# PotentialStorage Layered TypeScript storage library: KV → Events → Documents. The design is in [DESIGN.md](./DESIGN.md); read it before changing anything and keep it up to date. ## Commands - `npm test`: `tsc --noEmit`, then all Vitest tests (including `test/types.test-d.ts`) - `npm run test:only -- `: Vitest only - `npm run test:browser`: `test/browser/` in headless Chromium (Vitest browser mode + Playwright) against a real server on another origin (`test/browser/global-setup.ts`) - `npm run typecheck`, `npm run build`, `npm run bench` - `npm run format` / `npm run format:check`: Prettier CI (`.gitea/workflows/ci.yml`, Gitea Actions) runs the format check, typecheck, tests and build on Node 22, 24 and 26, and the Chromium tests. On pushes it then publishes to the staging registry (`scripts/publish.mjs`: `main` → `latest`, `next` → `next`, others → `dev-`). ## Conventions - One abstract base class per layer (`src//base-*.ts`); implementations only provide the raw primitives, and the user-facing API lives in the base class. - Classes over loose functions; TS `private`, not `#`; no overloads (use `param?` or tuple-union rest params); don't override base methods in subclasses. - **Never reassign a field after construction.** `child()` nodes are frozen `Object.create(root)` views, so `this.x = ...` on a child throws. Keep mutable state in a `private readonly state` object or in Maps (see `KVStorageComposite`, `KVStorageHttp`). - No runtime dependencies; third-party code is vendored (`src/utils/sse-session/`, `event-emitter.ts`, `extended-json.ts`, with a header naming the source). Tests live only in `test/`, mirroring `src/`. - `README.md` examples are mirrored in `test/readme.test.ts`; change both together. - New KV/document implementations must pass `test/kv-storage/kv-storage.conformance.ts` / `test/document-storage/document-storage.suite.ts`. - Ask the owner before pushing.