// hydrate (load) all posts found in a user's repo and find what is missing (posts removed/blacklisted by moderation) import { iterateAtpRepo } from "@atcute/car"; // user's did and pds to get repo from var did = "did:plc:462k2onbtwlhcphxjdev7spp"; var pds = "https://agaric.us-west.host.bsky.network"; // appview to test against var appview = "https://public.api.bsky.app"; async function fetch(url, options) { console.log("fetch", url); var res = await global.fetch(url, options); if (res.status == 429) { console.log(429); await new Promise(r => setTimeout(r, 5000)); return await fetch(url, options); } if (!res.ok) throw new Error(`HTTP ${res.status} ${res.statusText} ${await res.text()}`); console.log(res.status); return res; } var repo = await fetch(`${pds}/xrpc/com.atproto.sync.getRepo?did=${did}`).then(res => res.arrayBuffer()); repo = new Uint8Array(repo); var posts = []; for (let {collection, rkey, record} of iterateAtpRepo(repo)) { if (collection == "app.bsky.feed.post") { posts.push([rkey,record]); } } console.log(`${posts.length} posts in repository`); var repo_post_uris = posts.map(([rkey]) => `at://${did}/app.bsky.feed.post/${rkey}`); var missing_uris = []; for (let i = 0; i < repo_post_uris.length; i += 25) { let dry_uris = repo_post_uris.slice(i, i + 25); let q = dry_uris.map(u => `uris=${encodeURIComponent(u)}`).join('&'); let res = await fetch(`${appview}/xrpc/app.bsky.feed.getPosts?${q}`); let j = await res.json(); let hydrated_uris = j.posts.map(post => post.uri); for (let uri of dry_uris) { if (!hydrated_uris.includes(uri)) { missing_uris.push(uri); } } } console.log(`${missing_uris.length} posts in the repo didn't load in appview`); console.log(missing_uris);