@@ -2,10 +2,9 @@ import process from 'node:process'
22import { createHash } from 'node:crypto'
33import { defineNuxtModule , useNuxt , createResolver } from 'nuxt/kit'
44import { safeParse } from 'valibot'
5- import { BlogPostSchema , type BlogPostFrontmatter } from '../ shared/schemas/blog'
6- import { NPMX_SITE } from '../ shared/utils/constants'
5+ import { BlogPostSchema , type BlogPostFrontmatter } from '# shared/schemas/blog'
6+ import { NPMX_DEV_DID , NPMX_SITE } from '# shared/utils/constants'
77import { read } from 'gray-matter'
8- import { TID } from '@atproto/common'
98import { PasswordSession } from '@atproto/lex-password-session'
109import {
1110 Client ,
@@ -15,11 +14,9 @@ import {
1514} from '@atproto/lex'
1615import * as com from '../shared/types/lexicons/com'
1716import * as site from '../shared/types/lexicons/site'
17+ import { generateBlogTID , npmxPublicationRkey } from '#shared/utils/atproto'
1818
1919const syncedDocuments = new Map < string , string > ( )
20- const CLOCK_ID_THREE = 3
21- const MS_TO_MICROSECONDS = 1000
22- const ONE_DAY_MILLISECONDS = 86400000
2320
2421type BlogPostDocument = Pick <
2522 BlogPostFrontmatter ,
@@ -89,6 +86,8 @@ export default defineNuxtModule({
8986 rkey : possiblePublication . tid ,
9087 } ,
9188 )
89+ // Wait for the firehose and indexers to catch up if we create a publication
90+ await new Promise ( sleepResolve => setTimeout ( sleepResolve , 2_000 ) )
9291 }
9392 if ( documentsToSync . length > 0 ) {
9493 await syncsiteStandardDocuments ( authenticatedClient , documentsToSync )
@@ -153,23 +152,6 @@ async function syncsiteStandardDocuments(client: Client, documentsToSync: Docume
153152 console . log ( '[standard-site-sync] synced all new publications' )
154153}
155154
156- // Parse date from frontmatter, add file-path entropy for same-date collision resolution
157- function generateTID ( dateString : string , filePath : string ) : string {
158- let timestamp = new Date ( dateString ) . getTime ( )
159-
160- // If date has no time component (exact midnight), add file-based entropy
161- // This ensures unique TIDs when multiple posts share the same date
162- if ( timestamp % ONE_DAY_MILLISECONDS === 0 ) {
163- // Hash the file path to generate deterministic microseconds offset
164- const pathHash = createHash ( 'md5' ) . update ( filePath ) . digest ( 'hex' )
165- const offset = parseInt ( pathHash . slice ( 0 , 8 ) , 16 ) % 1000000 // 0-999999 microseconds
166- timestamp += offset
167- }
168-
169- // Clock id(3) needs to be the same everytime to get the same TID from a timestamp
170- return TID . fromTime ( timestamp * MS_TO_MICROSECONDS , CLOCK_ID_THREE ) . str
171- }
172-
173155// Schema expects 'path' & frontmatter provides 'slug'
174156function normalizeBlogFrontmatter ( frontmatter : Record < string , unknown > ) : Record < string , unknown > {
175157 return {
@@ -187,12 +169,13 @@ function createContentHash(data: unknown): string {
187169
188170function buildATProtoDocument ( siteUrl : string , data : BlogPostDocument ) {
189171 return site . standard . document . $build ( {
190- site : siteUrl as `${ string } :${ string } `,
172+ site : `at:// ${ NPMX_DEV_DID } /site.standard.publication/ ${ npmxPublicationRkey ( ) } `,
191173 path : data . path ,
192174 title : data . title ,
193175 description : data . description ?? data . excerpt ,
194176 tags : data . tags ,
195- publishedAt : new Date ( data . date ) . toISOString ( ) ,
177+ // Publish on the record with the current date
178+ publishedAt : new Date ( ) . toISOString ( ) ,
196179 } )
197180}
198181
@@ -242,7 +225,7 @@ const syncFile = async (
242225 return
243226 }
244227
245- const tid = generateTID ( data . date , filePath )
228+ const tid = generateBlogTID ( data . date , data . slug )
246229
247230 let checkForBlogResult = await pdsPublicClient . xrpcSafe ( com . atproto . repo . getRecord , {
248231 params : {
@@ -275,11 +258,7 @@ const syncFile = async (
275258 * @returns
276259 */
277260const checkPublication = async ( identifier : AtIdentifierString , pdsPublicClient : Client ) => {
278- // Using our release date as the tid for the publication
279- const publicationTid = TID . fromTime (
280- new Date ( '2026-03-03' ) . getTime ( ) * MS_TO_MICROSECONDS ,
281- CLOCK_ID_THREE ,
282- ) . str
261+ const publicationTid = npmxPublicationRkey ( )
283262
284263 //Check to see if we have a publication yet
285264 const publicationCheck = await pdsPublicClient . xrpcSafe ( com . atproto . repo . getRecord , {
@@ -302,8 +281,11 @@ const checkPublication = async (identifier: AtIdentifierString, pdsPublicClient:
302281 tid : publicationTid ,
303282 record : site . standard . publication . $build ( {
304283 name : 'npmx.dev' ,
305- url : 'https://npmx.dev/blog ' ,
284+ url : 'https://npmx.dev' ,
306285 description : 'a fast, modern browser for the npm registry' ,
286+ preferences : {
287+ showInDiscover : true ,
288+ } ,
307289 } ) ,
308290 }
309291 }
0 commit comments