2.4 KiB
in-memory-store
Purpose
Deterministic Map-backed invoice store consumed by every business
rule in invoice-rules.ts. The store performs zero IO and runs
identically on Node, Bun, and Javy/QuickJS — both the trusted-tier
route handlers and the wasm-tier handleRequest hold one of these as
their single source of truth for invoice persistence.
The store exposes the minimal vocabulary the rules need: monotonic id
allocation, create/get/list/setState/delete, plus clear() for
disposal and setCounter() for test pinning. Keeping the surface small
makes the shape-conformance test trivial — both tiers issue the same
sequence of store operations for the same input.
Features
- Monotonic
inv-Nid allocator (nextId()). - Strict create: throws when the id already exists.
- Get / list / setState / delete primitives.
- Bulk
clear()for the wasm-tierdispose()hook. setCounter(n)for deterministic id pinning in tests.
Usage: Basic
import { createInMemoryStore } from "@suaveplan/api-plugin-example/domain";
const store = createInMemoryStore();
const inv = store.create({ id: store.nextId(), status: "open", amountCents: 1500, currency: "USD" });
console.log(store.list()); // [inv]
Usage: Advanced
import { createInMemoryStore } from "@suaveplan/api-plugin-example/domain";
const store = createInMemoryStore();
store.setCounter(99); // next id will be inv-100
const seeded = store.create({ id: store.nextId(), status: "open", amountCents: 1, currency: "USD" });
store.setState(seeded.id, "paid");
store.delete(seeded.id);
store.clear();
API Reference
createInMemoryStore(): InMemoryStore— factory.nextId(): string—inv-1,inv-2, ...create(invoice): Invoice— inserts, throws on duplicate id.get(id): Invoice | undefined.list(): readonly Invoice[]— insertion-ordered snapshot.setState(id, state): Invoice— throws when id absent.delete(id): boolean—truewhen removed.clear(): void— erases every entry and resets the counter.setCounter(value): void— pin counter; nextnextId()returnsinv-${value+1}.
Implementation Notes
The store is a closure over a private Map and a private counter — no
prototype methods, no this binding, no shared global state. Tests
instantiate a fresh store per test for isolation; the wasm-tier holds
a module-singleton instance because the WASI-stdio surface has no
request-scoped context to thread one through.