Files
suaveplan/packages/api-stack/api/api-plugin-example/src/domain/in-memory-store.md
2026-05-27 23:29:53 +01:00

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-N id allocator (nextId()).
  • Strict create: throws when the id already exists.
  • Get / list / setState / delete primitives.
  • Bulk clear() for the wasm-tier dispose() 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 — true when removed.
  • clear(): void — erases every entry and resets the counter.
  • setCounter(value): void — pin counter; next nextId() returns inv-${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.