Bluesky app fork with some witchin' additions 馃挮
at linkat-integration 70 lines 1.7 kB view raw
1import { 2 type $Typed, 3 type AppBskyGraphFollow, 4 type AppBskyGraphGetFollows, 5 type BskyAgent, 6 type ComAtprotoRepoApplyWrites, 7} from '@atproto/api' 8import {TID} from '@atproto/common-web' 9import chunk from 'lodash.chunk' 10 11import {until} from '#/lib/async/until' 12 13export async function bulkWriteFollows(agent: BskyAgent, dids: string[]) { 14 const session = agent.session 15 16 if (!session) { 17 throw new Error(`bulkWriteFollows failed: no session`) 18 } 19 20 const followRecords: $Typed<AppBskyGraphFollow.Record>[] = dids.map(did => { 21 return { 22 $type: 'app.bsky.graph.follow', 23 subject: did, 24 createdAt: new Date().toISOString(), 25 } 26 }) 27 28 const followWrites: $Typed<ComAtprotoRepoApplyWrites.Create>[] = 29 followRecords.map(r => ({ 30 $type: 'com.atproto.repo.applyWrites#create', 31 collection: 'app.bsky.graph.follow', 32 rkey: TID.nextStr(), 33 value: r, 34 })) 35 36 const chunks = chunk(followWrites, 50) 37 for (const chunk of chunks) { 38 await agent.com.atproto.repo.applyWrites({ 39 repo: session.did, 40 writes: chunk, 41 }) 42 } 43 await whenFollowsIndexed(agent, session.did, res => !!res.data.follows.length) 44 45 const followUris = new Map<string, string>() 46 for (const r of followWrites) { 47 followUris.set( 48 r.value.subject as string, 49 `at://${session.did}/app.bsky.graph.follow/${r.rkey}`, 50 ) 51 } 52 return followUris 53} 54 55async function whenFollowsIndexed( 56 agent: BskyAgent, 57 actor: string, 58 fn: (res: AppBskyGraphGetFollows.Response) => boolean, 59) { 60 await until( 61 5, // 5 tries 62 1e3, // 1s delay between tries 63 fn, 64 () => 65 agent.app.bsky.graph.getFollows({ 66 actor, 67 limit: 1, 68 }), 69 ) 70}