diff --git a/packages/cultcache-ts/src/single-file-messagepack-backing-store.ts b/packages/cultcache-ts/src/single-file-messagepack-backing-store.ts index b4984913..4fdb2fb6 100644 --- a/packages/cultcache-ts/src/single-file-messagepack-backing-store.ts +++ b/packages/cultcache-ts/src/single-file-messagepack-backing-store.ts @@ -103,7 +103,8 @@ export class SingleFileMessagePackBackingStore implements CacheBackingStore { } requireOneTypePerKey(this.filePath, entries, []); - await this.#writeAll(entries, []); + // A key is held once: of same-type entries sharing a key in one batch, the last is kept. + await this.#writeAll([...new Map(entries.map((entry) => [entry.key, entry])).values()], []); }); } diff --git a/packages/cultcache-ts/test/store-file.test.ts b/packages/cultcache-ts/test/store-file.test.ts index 1ff23320..eb41b77b 100644 --- a/packages/cultcache-ts/test/store-file.test.ts +++ b/packages/cultcache-ts/test/store-file.test.ts @@ -623,6 +623,17 @@ test("a pushAll batch that carries one key under two types is refused and writes } }); +test("a pushAll batch that carries one key twice under one type keeps the last and the file reads back with one record", async () => { + const directory = await scratch(); + try { + const path = join(directory, "store.cc"); + await new SingleFileMessagePackBackingStore(path).pushAll([entryOf("k", "t", 1), entryOf("a", "t", 3), entryOf("k", "t", 2)]); + assert.deepEqual(await snapshotOf(new SingleFileMessagePackBackingStore(path)), ["t/a:3", "t/k:2"]); + } finally { + await rm(directory, { recursive: true, force: true }); + } +}); + test("a legacy envelope array that holds a key under two types is refused on open, as a v1 store is", async () => { const directory = await scratch(); try {