Initial Commit
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# 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
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```ts
|
||||
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.
|
||||
Reference in New Issue
Block a user