import type { BlobRef, RemoteRecord, RemoteStore } from '../../src/habitat/index.js' /** * In-memory `RemoteStore` for tests (a Fake, not a mock): real Maps for records * (keyed `collection/rkey`, compare-and-swap via `expected`) and content-addressed * blobs. Two sync engines sharing one instance exercise real convergence. */ export class InMemoryRemoteStore implements RemoteStore { readonly records = new Map() readonly blobs = new Map() private recordSeq = 0 private blobSeq = 0 constructor(readonly did = 'did:plc:test') {} private uri(collection: string, rkey: string): string { return `at://${this.did}/${collection}/${rkey}` } async putRecord(input: { collection: string rkey: string record: unknown expected?: { absent: true } | { cid: string } }): Promise<{ uri: string; cid: string }> { const key = `${input.collection}/${input.rkey}` const existing = this.records.get(key) if (input.expected && 'absent' in input.expected && existing) { throw new Error(`record already exists: ${key}`) } if (input.expected && 'cid' in input.expected && existing?.cid !== input.expected.cid) { throw new Error(`cid mismatch for ${key}`) } const uri = this.uri(input.collection, input.rkey) const cid = `bafy-record-${this.recordSeq++}` this.records.set(key, { uri, cid, value: input.record }) return { uri, cid } } async getRecord(input: { collection: string; rkey: string }): Promise { return this.records.get(`${input.collection}/${input.rkey}`) } async listRecords(input: { collection: string }): Promise<{ records: RemoteRecord[]; cursor?: string }> { const records = [...this.records.entries()] .filter(([key]) => key.startsWith(`${input.collection}/`)) .map(([, record]) => record) return { records } } async getRepoOplog(): Promise<{ records: RemoteRecord[]; cursor?: string }> { return { records: [...this.records.values()] } } async deleteRecord(input: { collection: string; rkey: string }): Promise { this.records.delete(`${input.collection}/${input.rkey}`) } async uploadBlob(bytes: Uint8Array, mimeType: string): Promise { const link = `bafy-blob-${this.blobSeq++}` this.blobs.set(link, bytes.slice()) return { $type: 'blob', ref: { $link: link }, mimeType, size: bytes.byteLength } } async readBlob(ref: BlobRef): Promise { const bytes = this.blobs.get(ref.ref.$link) if (!bytes) throw new Error(`missing blob ${ref.ref.$link}`) return bytes } }