diff --git a/src/blockstore/store.ts b/src/blockstore/store.ts index 99e30eaf6..6217d6e14 100644 --- a/src/blockstore/store.ts +++ b/src/blockstore/store.ts @@ -21,7 +21,7 @@ import type { DbMetaEventBlock, CarClockLink, } from "./types.js"; -import { Falsy, StoreType, SuperThis, throwFalsy } from "../types.js"; +import { Falsy, StoreType, SuperThis, throwFalsy, CRDTEntry } from "../types.js"; import { Gateway } from "./gateway.js"; import { ensureLogger, isNotFoundError } from "../utils.js"; import { carLogIncludesGroup } from "./loader.js"; @@ -176,8 +176,7 @@ export class MetaStoreImpl extends BaseStoreImpl implements MetaStore { return event as EventBlock<{ dbMeta: Uint8Array }>; } - async decodeMetaBlock(bytes: Uint8Array): Promise<{ eventCid: CarClockLink; dbMeta: DbMeta; parents: string[] }> { - const crdtEntry = JSON.parse(this.sthis.txt.decode(bytes)) as { data: string; parents: string[]; cid: string }; + async decodeMetaBlock(crdtEntry: CRDTEntry): Promise<{ eventCid: CarClockLink; dbMeta: DbMeta; parents: string[] }> { const eventBytes = decodeFromBase64(crdtEntry.data); const eventBlock = await this.decodeEventBlock(eventBytes); return { @@ -187,9 +186,10 @@ export class MetaStoreImpl extends BaseStoreImpl implements MetaStore { }; } - async handleByteHeads(byteHeads: Uint8Array[]) { + async handleByteHeads(byteHeads: Uint8Array) { + const crdtEntries = JSON.parse(this.sthis.txt.decode(byteHeads)) as CRDTEntry[]; try { - const dbMetas = await Promise.all(byteHeads.map((bytes) => this.decodeMetaBlock(bytes))); + const dbMetas = await Promise.all(crdtEntries.map((entry) => this.decodeMetaBlock(entry))); return dbMetas; } catch (e) { throw this.logger.Error().Err(e).Msg("parseHeader").AsError(); @@ -197,7 +197,8 @@ export class MetaStoreImpl extends BaseStoreImpl implements MetaStore { } async handleEventByteHead(byteHead: Uint8Array) { - const { eventCid, dbMeta, parents } = await this.decodeMetaBlock(byteHead); + const crdtEntry = JSON.parse(this.sthis.txt.decode(byteHead)) as CRDTEntry; + const { eventCid, dbMeta, parents } = await this.decodeMetaBlock(crdtEntry); this.loader?.taskManager?.handleEvent(eventCid, parents, dbMeta); } @@ -215,7 +216,7 @@ export class MetaStoreImpl extends BaseStoreImpl implements MetaStore { } throw this.logger.Error().Url(url.Ok()).Result("bytes:", bytes).Msg("gateway get").AsError(); } - const dbMetas = await this.handleByteHeads([bytes.Ok()]); + const dbMetas = await this.handleByteHeads(bytes.Ok()); await this.loader?.handleDbMetasFromStore(dbMetas.map((m) => m.dbMeta)); // the old one didn't await const cids = dbMetas.map((m) => m.eventCid); const uniqueParentsMap = new Map([...this.parents, ...cids].map((p) => [p.toString(), p])); @@ -230,7 +231,7 @@ export class MetaStoreImpl extends BaseStoreImpl implements MetaStore { data: base64String, parents: this.parents.map((p) => p.toString()), }; - return this.sthis.txt.encode(JSON.stringify(crdtEntry)); + return this.sthis.txt.encode(JSON.stringify([crdtEntry])); } async save(meta: DbMeta, branch?: string): Promise> { diff --git a/src/blockstore/types.ts b/src/blockstore/types.ts index e59047abd..dd2deee0c 100644 --- a/src/blockstore/types.ts +++ b/src/blockstore/types.ts @@ -250,7 +250,7 @@ export interface MetaStore extends BaseStore { load(branch?: string): Promise; // branch is defaulted to "main" save(meta: DbMeta, branch?: string): Promise>; - handleByteHeads(byteHeads: Uint8Array[], branch?: string): Promise<{ eventCid: CarClockLink; dbMeta: DbMeta }[]>; + handleByteHeads(byteHeads: Uint8Array, branch?: string): Promise<{ eventCid: CarClockLink; dbMeta: DbMeta }[]>; } export interface DataSaveOpts { diff --git a/src/types.ts b/src/types.ts index d937f6e49..a0c3d0799 100644 --- a/src/types.ts +++ b/src/types.ts @@ -262,3 +262,9 @@ export interface DocResponse { export type UpdateListenerFn = (docs: DocWithId[]) => Promise | void; export type NoUpdateListenerFn = () => Promise | void; export type ListenerFn = UpdateListenerFn | NoUpdateListenerFn; + +export interface CRDTEntry { + data: string; + parents: string[]; + cid: string; +} diff --git a/tests/blockstore/store.test.ts b/tests/blockstore/store.test.ts index aeb17a049..7a4c37945 100644 --- a/tests/blockstore/store.test.ts +++ b/tests/blockstore/store.test.ts @@ -124,7 +124,7 @@ describe("MetaStore", function () { }; await store.save(h); const file = await raw.get(store.url(), "main"); - const [blockMeta] = await store.handleByteHeads([file]); + const [blockMeta] = await store.handleByteHeads(file); const decodedHeader = blockMeta.dbMeta; expect(decodedHeader).toBeTruthy(); expect(decodedHeader.cars).toBeTruthy(); @@ -156,10 +156,10 @@ describe("MetaStore with a saved header", function () { const bytes = await raw.get(store.url(), "main"); const data = decoder.decode(bytes); expect(data).toMatch(/parents/); - const header = JSON.parse(data); + const header = JSON.parse(data)[0]; expect(header).toBeDefined(); expect(header.parents).toBeDefined(); - const [blockMeta] = await store.handleByteHeads([bytes]); + const [blockMeta] = await store.handleByteHeads(bytes); const decodedHeader = blockMeta.dbMeta; expect(decodedHeader).toBeDefined(); expect(decodedHeader.cars).toBeDefined();