// A SpaceStoragePort over plain rows, enough for core's space browser and // the readers the feature packages build over storage: a test names its // spaces, members and records as data and the port answers from them. import { cborEncodeDagCbor } from '../../packages/core/src/repo.js'; /** * @typedef {Object} FakeSpaceRecord * @property {string} collection * @property {string} rkey * @property {string} cid * @property {string} [indexedAt] * @property {unknown} value - plain, encoded to DAG-CBOR on read */ /** * @param {Object} [rows] * @param {Array & {uri: string}>} [rows.spaces] - SpaceRow-shaped; missing fields read as undefined * @param {Record} [rows.members] - by space URI * @param {Record} [rows.records] - by space URI, in storage order */ export function createFakeSpaceStorage({ spaces = [], members = {}, records = {}, } = {}) { /** @param {FakeSpaceRecord} record */ const row = (record) => ({ collection: record.collection, rkey: record.rkey, cid: record.cid, indexedAt: record.indexedAt ?? '2026-01-01T00:00:00.000Z', value: cborEncodeDagCbor(record.value), }); return /** @type {any} */ ({ async getSpace(/** @type {string} */ uri) { return spaces.find((space) => space.uri === uri) ?? null; }, async listSpaces(/** @type {{limit?: number}} */ { limit = 50 } = {}) { return { spaces: spaces.slice(0, limit), cursor: null }; }, async listMembers(/** @type {string} */ uri) { return { dids: members[uri] ?? [], cursor: null }; }, async listAllSpaceRecords(/** @type {string} */ uri) { return (records[uri] ?? []).map(({ collection, rkey, cid }) => ({ collection, rkey, cid, })); }, async listSpaceRecords( /** @type {string} */ uri, /** @type {{collection?: string|null, limit?: number, reverse?: boolean}} */ { collection = null, limit = 50, reverse = false, } = {}, ) { let rows = records[uri] ?? []; if (collection) rows = rows.filter((r) => r.collection === collection); if (reverse) rows = [...rows].reverse(); return { records: rows.slice(0, limit).map(row), cursor: null }; }, async getSpaceRecord( /** @type {string} */ uri, /** @type {string} */ collection, /** @type {string} */ rkey, ) { const found = (records[uri] ?? []).find( (r) => r.collection === collection && r.rkey === rkey, ); return found ? row(found) : null; }, }); }