Personal website for Chris Parsons chrisparsons.dev
0

Configure Feed

Select the types of activity you want to include in your feed.

correct publication script to stop creating duplicates

Chris Parsons (Jun 10, 2026, 8:30 PM +0200) bbe6cd4d 3850a9bd

+21 -16
+17 -12
scripts/create-publication.ts
··· 11 11 process.exit(1); 12 12 } 13 13 14 + // 1. READ SYNC STATE FIRST 15 + const syncStatePath = ".atproto-sync.json"; 16 + let syncState: any = { posts: {} }; 17 + if (fs.existsSync(syncStatePath)) { 18 + syncState = JSON.parse(fs.readFileSync(syncStatePath, "utf-8")); 19 + } 20 + 14 21 const agent = createAgent(pdsUrl); 15 22 const session = await login(agent, handle, appPassword); 16 23 const did = session.did; 17 24 18 - const tid = TID.nextStr(); 19 - const result = await agent.com.atproto.repo.createRecord({ 25 + // 2. REUSE EXISTING RKEY OR MINT A NEW ONE 26 + const rkey = syncState.publication?.rkey || TID.nextStr(); 27 + 28 + // 3. USE PUTRECORD FOR IDEMPOTENT UPSERT 29 + const result = await agent.com.atproto.repo.putRecord({ 20 30 repo: did, 21 31 collection: "site.standard.publication", 22 - rkey: tid, 32 + rkey: rkey, 23 33 record: { 24 34 $type: "site.standard.publication", 25 35 name: "Chris Parsons", ··· 28 38 }, 29 39 }); 30 40 31 - const syncStatePath = ".atproto-sync.json"; 32 - let syncState: any = { posts: {} }; 33 - if (fs.existsSync(syncStatePath)) { 34 - syncState = JSON.parse(fs.readFileSync(syncStatePath, "utf-8")); 35 - } 36 - 41 + // 4. SAVE STATE BACK TO FILE 37 42 syncState.publication = { 38 43 uri: result.data.uri, 39 - rkey: tid, 44 + rkey: rkey, 40 45 }; 41 46 42 47 fs.writeFileSync(syncStatePath, JSON.stringify(syncState, null, 2)); 43 48 44 - console.log("Publication created!"); 49 + console.log("Publication processed successfully (upserted)!"); 45 50 console.log("AT-URI:", result.data.uri); 46 - console.log("Rkey:", tid); 51 + console.log("Rkey:", rkey);
+4 -4
scripts/sync-posts.ts
··· 15 15 process.exit(0); 16 16 } 17 17 18 - const agent = createAgent(pdsUrl); 19 - const session = await login(agent, handle, appPassword); 20 - const did = session.did; 21 - 22 18 const syncStatePath = ".atproto-sync.json"; 23 19 let syncState: any = { posts: {} }; 24 20 if (fs.existsSync(syncStatePath)) { ··· 29 25 console.error("No publication found. Run: bun run scripts/create-publication.ts"); 30 26 process.exit(1); 31 27 } 28 + 29 + const agent = createAgent(pdsUrl); 30 + const session = await login(agent, handle, appPassword); 31 + const did = session.did; 32 32 33 33 function getMarkdownFiles(dir: string): string[] { 34 34 const files: string[] = [];