Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# `proxy/create-db-adapter-worker-proxy` — worker-side adapter factory
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`createDbAdapterWorkerProxy` is the worker-side counterpart to
|
||||
`createDbAdapter`. Inside an `api-worker-host` worker, plugin code receives a
|
||||
proxy that looks identical to the direct surface but marshals every call
|
||||
across an `@suaveplan/api-db-worker-proxy` `MessagePort`. The host side
|
||||
still owns the real engine connection and the tenant-scope rewriter; this
|
||||
package is the worker-side facade.
|
||||
|
||||
Cursor results survive the boundary as `ReadableStream` (transferable per
|
||||
the worker-rpc layer), so a 10_000-row query streams row-by-row without
|
||||
buffering. The tenant-scoped facade is structurally identical to the
|
||||
direct-surface one because the host's `wrapTenantScoped` already maps
|
||||
`AdminDatabaseLike` onto `TenantScopedDatabaseLike` without further SQL
|
||||
rewriting (rewriting happens main-side).
|
||||
|
||||
## Features
|
||||
|
||||
- Identical public shape to `DbAdapter` for parity: `admin`, `scoped()`,
|
||||
`close()`.
|
||||
- Built on `createDbProxyClient` from `api-db-worker-proxy/worker-side`,
|
||||
which manages RPC framing, cursor streaming, and stream cancellation.
|
||||
- Engine identity is supplied synchronously at construction (it would
|
||||
require a round-trip otherwise).
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { createDbAdapterWorkerProxy } from "@suaveplan/api-db-adapter/proxy";
|
||||
|
||||
const proxy = createDbAdapterWorkerProxy({
|
||||
port: workerPort,
|
||||
engine: "sqlite",
|
||||
});
|
||||
|
||||
const rows = await proxy.scoped("acme" as TenantId).query("SELECT * FROM users");
|
||||
proxy.close();
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { createDbProxyHarness } from "@suaveplan/api-db-worker-proxy/testing";
|
||||
import { createDbAdapterWorkerProxy } from "@suaveplan/api-db-adapter/proxy";
|
||||
|
||||
const harness = createDbProxyHarness({ seed: [["a", { v: 1 }]] });
|
||||
try {
|
||||
const proxy = createDbAdapterWorkerProxy({
|
||||
port: harness.ports.clientPort,
|
||||
engine: harness.db.engine,
|
||||
});
|
||||
const rows = await proxy.admin.query("SELECT *");
|
||||
proxy.close();
|
||||
} finally {
|
||||
harness.close();
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `createDbAdapterWorkerProxy(options): DbAdapterWorkerProxy`.
|
||||
- `DbAdapterWorkerProxyOptions` — `{ port, engine, clientOptions? }`.
|
||||
- `DbAdapterWorkerProxy.admin: DbProxyClient` (admin + `cursor()`).
|
||||
- `DbAdapterWorkerProxy.scoped(tenantId): TenantScopedDatabaseLike`.
|
||||
- `DbAdapterWorkerProxy.close(): void`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The proxy intentionally exposes the underlying `DbProxyClient` (extends
|
||||
`AdminDatabaseLike`) as `admin` so cursor streaming is reachable to
|
||||
consumers that need it. Tenant-scope rewriting is the main side's job; this
|
||||
facade only injects the `tenantId` brand into the worker-side type so route
|
||||
handlers cannot accidentally pass an admin reference where a scoped one is
|
||||
expected. `close()` calls `client.dispose()` which rejects in-flight calls
|
||||
with `DB_PROXY.PROXY_DISPOSED`.
|
||||
Reference in New Issue
Block a user