Repository navigation
Description
Motivation
An application already using PgliteKvStore should be able to adopt a feature that needs atomic multi-key state without constructing another backend-specific store. The shared contract is useful for general application state as well as delivery suspension and durable backlog. This issue makes the existing @fedify/pglite adapter a usable AtomicKvStore in its documented support scope.
Proposed API and use
Implement AtomicKvStore on PgliteKvStore. Keep its existing constructor and ordinary KV methods. Add the proposed signatures below, with the supporting entry types defined by the contract issue:
getMany<T = unknown>(keys: readonly KvKey[]): Promise<(T | undefined)[]>;
setMany(entries: readonly KvStoreSetEntry[]): Promise<void>;
deleteMany(keys: readonly KvKey[]): Promise<void>;
casMany(entries: readonly KvStoreCasEntry[]): Promise<boolean>;Keep cas() and make all five methods meet the shared contract. A proposed application use is:
import type { AtomicKvStore } from "@fedify/fedify";
import { PGlite } from "@electric-sql/pglite";
import { PgliteKvStore } from "@fedify/pglite";
const pg = new PGlite("./data/fedify");
const store: AtomicKvStore = new PgliteKvStore(pg);
const keys = [["example", "notice"], ["example", "budget"]] as const;
const [notice, budget] = await store.getMany(keys);
const committed = await store.casMany([
{ key: keys[0], expectedValue: notice, newValue: nextNotice },
{ key: keys[1], expectedValue: budget, newValue: nextBudget },
]);The application computes nextNotice and nextBudget from the snapshot and re-evaluates its rule when the result is false. Connection configuration and client shutdown remain the application's responsibility. These calls are proposed additions, not currently shipped methods.
Backend implementation and choices
Use PGlite's supported transaction path to evaluate expectations and commit the complete batch. Exercise concurrent requests against the supported shared database instance and preserve current table layout, initialization and logical time to live (TTL) behavior. Do not infer isolation merely from an awaited sequence of statements.
PGlite's data-directory and process-sharing limitations remain unchanged. Separate clients in the conformance suite may share the supported database instance; the test must not imply that unrelated processes can safely open one directory. Include batch rollback, missing-key races, codec/TTL and reopen tests within the supported environment.
Requiring a separate FEP-f799 store would discard the existing embedded KV abstraction. Implement the generic contract in PgliteKvStore; use backend-specific transaction code where needed rather than assuming the PostgreSQL client's API is interchangeable with PGlite's.
Shipping criteria
Run the shared Atomic KV conformance suite and the PGlite-specific concurrency/failure cases against a supported backend. Verify the package's declared Node, Deno and Bun support, its consumer declarations, and existing KV regression tests. Document unsupported batch scope and limits; do not silently weaken an atomic call or treat method presence as proof of durability.
Revise the PgliteKvStore support row and custom-adapter contract in docs/manual/kv.md, packages/pglite/README.md, public JSDoc, and relevant KV-selection skill guidance. Add the adapter's changelog fragment. Ship this adapter independently of other backend implementations and of delivery suspension.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Effort
Activity
AtomicKvStore#1363