// Makes the repository knotless-serve's archive tests read: a few dozen // records, the MST made by @atproto/repo, as atproto's reference makes it, // written as a CAR and as STAR-lite version 0 (microcosm's, as hubble // serves it), with the DID and the key that signed its commit. // // node harness/star-fixture.mjs crates/knotless-serve/fixtures // // STAR-lite: `*l\0`, the MST root's CID (36 bytes), the commit without its // `data` (a varint length, then DRISL), then each record in key order as a // varint key length, the key, a varint record length and the record. // https://tangled.org/microcosm.blue/star/tree/main/v0-star/star-lite import { writeFileSync } from 'node:fs' import { join } from 'node:path' import { encode } from '@atproto/lex-cbor' import { Secp256k1Keypair } from '@atproto/crypto' import { MemoryBlockstore, Repo, WriteOpAction, blocksToCarFile } from '@atproto/repo' const out = process.argv[2] if (!out) throw new Error('usage: node harness/star-fixture.mjs ') // A fixed key, so the fixture's DID stays the same each time it is made. const keypair = await Secp256k1Keypair.import( '9085d2bef69286a6cbb51623c8fa258629945cd55ca705cc4e66700396894e0c', ) const did = 'did:plc:archivefixture00000000000' const writes = [] for (let i = 0; i < 30; i++) { const rkey = `3l${String(i).padStart(11, 'a')}` writes.push({ action: WriteOpAction.Create, collection: 'dev.knotless.repo', rkey, record: { $type: 'dev.knotless.repo', name: `r${i}`, key: `k${i}`, createdAt: '2026-11-01T00:00:00.000Z', }, }) writes.push({ action: WriteOpAction.Create, collection: 'app.bsky.feed.post', rkey, record: { $type: 'app.bsky.feed.post', text: `post ${i}`, createdAt: '2026-11-01T00:00:00.000Z', }, }) } const storage = new MemoryBlockstore() const repo = await Repo.create(storage, did, keypair, writes) const car = await blocksToCarFile(repo.cid, storage.blocks) const varint = (n) => { const bytes = [] while (n >= 0x80) { bytes.push((n & 0x7f) | 0x80) n >>>= 7 } bytes.push(n) return Buffer.from(bytes) } const { data, ...partial } = repo.commit const commit = Buffer.from(encode(partial)) const parts = [ Buffer.from([0x2a, 0x6c, 0x00]), Buffer.from(data.bytes), varint(commit.length), commit, ] for (const leaf of await repo.data.list()) { const record = Buffer.from(await storage.getBytes(leaf.value)) const key = Buffer.from(leaf.key, 'ascii') parts.push(varint(key.length), key, varint(record.length), record) } const star = Buffer.concat(parts) writeFileSync(join(out, 'repo.car'), car) writeFileSync(join(out, 'repo.star'), star) writeFileSync( join(out, 'repo.json'), `${JSON.stringify({ did, key: keypair.did(), rev: repo.commit.rev, records: writes.length }, null, 2)}\n`, ) console.log(`${writes.length} records, CAR ${car.length} bytes, STAR-lite ${star.length} bytes`)