Initial Commit
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
<!-- markdownlint-disable MD024 -->
|
||||
|
||||
# Capability Spec Delta: api-db-worker-proxy (api-db-worker-proxy)
|
||||
|
||||
**Package**: `@suaveplan/api-db-worker-proxy`
|
||||
**Status**: PROPOSED
|
||||
|
||||
> Every requirement below carries a `**Verified by:**` line at authoring time.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Admin and tenant-scoped surfaces are type-distinct proxy clients
|
||||
|
||||
The package SHALL expose `createDbProxyClient(port, { surface })` whose return type is `WorkerProxyOf<AdminDatabaseLike>` when `surface === "admin"` and `WorkerProxyOf<TenantScopedDatabaseLike>` when `surface === "tenant-scoped"`. The two return types MUST NOT be mutually assignable: a tenant-scoped proxy MUST NOT satisfy an admin parameter and vice versa.
|
||||
|
||||
#### Scenario: surfaces are not mutually assignable
|
||||
|
||||
- **WHEN** `expectTypeOf<Admin>().not.toEqualTypeOf<TenantScoped>()` is checked
|
||||
- **THEN** TypeScript flags the surfaces as distinct
|
||||
|
||||
**Verified by:** `src/client/client.spec-conformance.test.ts::"admin and tenant-scoped surfaces are distinct"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Cursors stream results without buffering
|
||||
|
||||
The package SHALL marshal DB cursors as `ReadableStream<Row>` via `api-worker-rpc`'s streaming primitive. `for await (const row of cursor)` MUST yield rows incrementally; the main-side cursor MUST NOT be drained eagerly. Consumer cancellation MUST propagate so the main-side cursor closes.
|
||||
|
||||
#### Scenario: 10k-row cursor yields incrementally
|
||||
|
||||
- **WHEN** a worker iterates a 10k-row cursor
|
||||
- **THEN** the first row is observed BEFORE the last row has been produced main-side (verified via timing)
|
||||
|
||||
#### Scenario: cursor break propagates close
|
||||
|
||||
- **WHEN** the worker breaks out of `for await` early
|
||||
- **THEN** the main-side cursor is closed AND no further rows are produced
|
||||
|
||||
**Verified by:** `src/cursor/cursor.test.ts::"cursor yields incrementally"` AND `src/cursor/cursor.test.ts::"break propagates cursor close"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Transaction handle is scoped to callback lifetime
|
||||
|
||||
The package SHALL provide `client.transaction(async (tx) => { ... })` where `tx` is only valid inside the callback. A call on `tx` after the callback resolves or rejects MUST throw `DB_PROXY_TX_OUT_OF_SCOPE`. The transaction MUST be carried by a transaction-scoped sub-port so the main side can correlate every call to the same connection.
|
||||
|
||||
#### Scenario: out-of-scope tx call throws
|
||||
|
||||
- **WHEN** the callback captures `tx` AND a method is called on it after the callback returns
|
||||
- **THEN** `DB_PROXY_TX_OUT_OF_SCOPE` is thrown
|
||||
|
||||
#### Scenario: nested tx is rejected
|
||||
|
||||
- **WHEN** `tx.transaction(...)` is invoked inside the callback
|
||||
- **THEN** `DB_PROXY_TX_OUT_OF_SCOPE` is thrown (savepoints are out of scope for Stage 3)
|
||||
|
||||
**Verified by:** `src/transaction/transaction.test.ts::"out-of-scope tx call throws"` AND `src/transaction/transaction.test.ts::"nested tx is rejected"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Conformance suite passes against this proxy
|
||||
|
||||
The package SHALL be runnable as a surface argument to `runDbAdapterConformance` from `@suaveplan/api-db/testing`. Every conformance scenario (CRUD, transactions, cursors, schema introspection) MUST pass identically to a direct in-process adapter. This is the Stage-4-precondition gate: every Stage-4 DB adapter (`api-db-adapter`, `api-db-sqlite-memory`) MUST pass conformance under BOTH the direct surface AND this worker-proxy surface before Stage 4 can be declared complete.
|
||||
|
||||
#### Scenario: runDbAdapterConformance passes
|
||||
|
||||
- **WHEN** `runDbAdapterConformance("worker-proxy", makeFactory)` runs against this proxy + stub server
|
||||
- **THEN** every conformance scenario passes
|
||||
|
||||
**Verified by:** `tests/conformance/run-db-adapter-conformance.test.ts::"runDbAdapterConformance passes against proxy"`
|
||||
Reference in New Issue
Block a user