docs: generate each subsystem's cordis surface into its own page; delete the flat catalogs
Rebuild of the region machinery (PR3) on the post-#904 Typert projection: renderPageRegion/renderInheritedPage live in dsh-typert-generator beside the projection; scripts/gen-cordis-catalog.ts owns the curated SERVICE_PAGE / EVENT_SCOPE_PAGE / SERVICE_WALK_EXEMPTIONS / LINK_MAP partition (fail-loud in both directions, with the independent Context-merge scan backstopping the projection's blind spot), spliceRegion, and the guarded pair auto-record. docs/cordis-catalog/ is deleted: the flat events/services catalogs dissolve into per-page regions and docs/cordis-catalog/core moves to docs/cordis-api/ with the inherited tier as its own generated page. The partition absorbs the post-regrouping surface: ctx.typert → invariants.md, ctx.directoryPicker → workspace.md, skills/* events → skills.md, and the four launcher-provided tui accessor values join the named exemptions.
This commit is contained in:
@@ -8,7 +8,7 @@ Source: [`packages/storage/storage/src/backend.ts`](../../packages/storage/stora
|
||||
|
||||
## The hub: `ctx.storage`
|
||||
|
||||
`Storage` ([signatures](../cordis-catalog/services.md#ctxstorage--storage)) is a meeting point, not a store. `ctx.storage.backend` is a name → backend table: multiple backends stay mounted side by side, and which backend serves which consumer is that consumer's configuration (the domain layer's route table), never a hub-global choice. `register(name, backend)` returns the disposer; duplicate names and unknown lookups throw `StorageError`. Disposal only unregisters the name — the owning plugin closes the backend after unregistering. Each backend plugin also publishes a lifecycle-only service key (`storageBackendServiceKey(name)`), which form providers inject so their activation cannot race backend registration.
|
||||
`Storage` ([signatures](#ctxstorage--storage)) is a meeting point, not a store. `ctx.storage.backend` is a name → backend table: multiple backends stay mounted side by side, and which backend serves which consumer is that consumer's configuration (the domain layer's route table), never a hub-global choice. `register(name, backend)` returns the disposer; duplicate names and unknown lookups throw `StorageError`. Disposal only unregisters the name — the owning plugin closes the backend after unregistering. Each backend plugin also publishes a lifecycle-only service key (`storageBackendServiceKey(name)`), which form providers inject so their activation cannot race backend registration.
|
||||
|
||||
Data forms mount on the hub under a merge-extensible key map:
|
||||
|
||||
@@ -99,11 +99,11 @@ Reads are synchronous from authoritative in-memory state: `KvTable` exposes `get
|
||||
|
||||
## The domain facility: `ctx.storageDomain`
|
||||
|
||||
`DomainFacility` ([signatures](../cordis-catalog/services.md#ctxstoragedomain--domainfacility)) opens declared domains over routed backends. Routing is the domain plugin's configuration, never the hub's: `backend` names the required default route and `routes` overrides it per domain name. `open(spec)` runs a strict sequence, each step failing the whole call: it rejects a name already open or still closing (`already-open`), resolves the route (`backend-not-found`), requires the backend's `kv` facet (`facet-unsupported`), opens the unit (backend `version-mismatch`/`malformed-medium` pass through), and validates every stored record and global against the spec's zod schemas (`invalid-record` with the offending table and key). The caller owns the returned handle and releases it with `Domain.close()`; domains still open when the plugin unmounts are closed by the facility, and a closed domain's name frees for reopening only after teardown fully completes. `get(name)` is an untyped diagnostic lookup onto the package-private `DomainImpl` runtime behind every typed handle; `closeAll()` is the unmount path.
|
||||
`DomainFacility` ([signatures](#ctxstoragedomain--domainfacility)) opens declared domains over routed backends. Routing is the domain plugin's configuration, never the hub's: `backend` names the required default route and `routes` overrides it per domain name. `open(spec)` runs a strict sequence, each step failing the whole call: it rejects a name already open or still closing (`already-open`), resolves the route (`backend-not-found`), requires the backend's `kv` facet (`facet-unsupported`), opens the unit (backend `version-mismatch`/`malformed-medium` pass through), and validates every stored record and global against the spec's zod schemas (`invalid-record` with the offending table and key). The caller owns the returned handle and releases it with `Domain.close()`; domains still open when the plugin unmounts are closed by the facility, and a closed domain's name frees for reopening only after teardown fully completes. `get(name)` is an untyped diagnostic lookup onto the package-private `DomainImpl` runtime behind every typed handle; `closeAll()` is the unmount path.
|
||||
|
||||
## The change event: `domain/changed`
|
||||
|
||||
Every durable write emits one event strictly after the backend acknowledged durability, in the domain's write-chain order ([event entry](../cordis-catalog/events.md#domainchanged--emit)):
|
||||
Every durable write emits one event strictly after the backend acknowledged durability, in the domain's write-chain order ([event entry](#domainchanged--emit)):
|
||||
|
||||
```ts type-equiv
|
||||
/** Shared location fields of one durable domain change. */
|
||||
@@ -123,3 +123,107 @@ type DomainChanged = DomainChangedPut | DomainChangedDeleted
|
||||
```
|
||||
|
||||
`put` (inserts, overwrites, and global writes) carries the new snapshot in `value` — never the old value; a diffing consumer keeps its own previous snapshot. `deleted` is a tombstone with no value. The event is a notification, not a transaction participant: the commit point has passed at emission, so a synchronously throwing listener is contained with a logged warning rather than rejecting the already-durable write, and emitted values equal the in-memory state at emission. The event is in-process only; cross-process change push is deferred work recorded in the [package README](../../packages/storage/storage-domain/README.md).
|
||||
|
||||
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
||||
|
||||
<a id="cordis-surface"></a>
|
||||
|
||||
## Cordis surface
|
||||
|
||||
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` surface lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
||||
|
||||
<a id="ctxstorage--storage"></a>
|
||||
|
||||
### `ctx.storage` — `Storage`
|
||||
|
||||
The storage hub service. Backends register under `backend`; data forms mount under their `StorageForms` key and are reached as `ctx.storage.<form>`.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Mount a data-form facility on the hub. Mounting is an effect: the
|
||||
* returned disposer unmounts the form.
|
||||
* @param form - Form key declared in {@link StorageForms}.
|
||||
* @param facility - The facility instance to expose.
|
||||
* @returns the disposer that unmounts the form.
|
||||
*/
|
||||
mount<K extends keyof StorageForms>(form: K, facility: StorageForms[K]): () => void
|
||||
|
||||
/**
|
||||
* Resolve a mounted data form.
|
||||
* @param form - Form key declared in {@link StorageForms}.
|
||||
* @returns the mounted facility.
|
||||
*/
|
||||
form<K extends keyof StorageForms>(form: K): StorageForms[K]
|
||||
```
|
||||
|
||||
Source: [`packages/storage/storage/src/index.ts:47`](../../packages/storage/storage/src/index.ts)
|
||||
|
||||
<a id="ctxstoragedomain--domainfacility"></a>
|
||||
|
||||
### `ctx.storageDomain` — `DomainFacility`
|
||||
|
||||
The mounted domain facility. Opens declared domains over routed backends; one facility instance owns the open-domain table and enforces single-open per domain name.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Open one declared domain. Steps, each failing the whole call: reject a
|
||||
* name that is already open (`already-open`); resolve the backend route
|
||||
* (`backend-not-found` passes through from the hub); require its `kv` facet
|
||||
* (`facet-unsupported`); open the unit projected from the spec (backend
|
||||
* `version-mismatch`/`malformed-medium` pass through); load and validate
|
||||
* every stored record against the spec's zod schemas (`invalid-record`
|
||||
* with the offending table and key); construct the domain.
|
||||
*
|
||||
* Lifecycle: the CALLER owns the returned handle and closes it via
|
||||
* `Domain.close()` (typically as its own `ctx.effect` disposer) — the
|
||||
* facility does not tie the domain to any consumer fiber. Domains still
|
||||
* open when the facility unmounts are closed by the plugin disposer.
|
||||
* @param spec - The domain declaration, typically from `defineDomain`.
|
||||
* @returns the opened domain handle, typed by the spec.
|
||||
*/
|
||||
async open<S extends DomainSpec>(spec: S): Promise<Domain<S>>
|
||||
|
||||
/**
|
||||
* Look up an open domain by name, untyped. Diagnostic surface (the package
|
||||
* invariant cross-checks change events against live domain state); typed
|
||||
* consumers hold the handle returned by {@link open}.
|
||||
* @param name - Domain name.
|
||||
* @returns the open domain runtime, or `undefined` when not open.
|
||||
*/
|
||||
get(name: string): DomainImpl | undefined
|
||||
|
||||
/**
|
||||
* Close every domain still open on this facility. The unmount path for
|
||||
* consumers that never called `Domain.close()` themselves; closing is
|
||||
* idempotent, so double-closing an already-closed domain is harmless.
|
||||
* @returns resolution after every unit is released.
|
||||
*/
|
||||
async closeAll(): Promise<void>
|
||||
```
|
||||
|
||||
Source: [`packages/storage/storage-domain/src/index.ts:69`](../../packages/storage/storage-domain/src/index.ts)
|
||||
|
||||
<a id="domain-events"></a>
|
||||
|
||||
### `domain/*` events
|
||||
|
||||
<a id="domainchanged--emit"></a>
|
||||
|
||||
#### `domain/changed` — emit
|
||||
|
||||
A domain record or the global singleton changed, emitted once per write strictly after the backend acknowledged durability. Events of one domain arrive in its write-chain order.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* A domain record or the global singleton changed, emitted once per write
|
||||
* strictly after the backend acknowledged durability. Events of one
|
||||
* domain arrive in its write-chain order.
|
||||
* @param change - domain, table (`''` for global), key (`''` for global),
|
||||
* operation discriminant, and on `put` the new snapshot.
|
||||
* @mode emit
|
||||
*/
|
||||
'domain/changed'(change: DomainChanged): void
|
||||
```
|
||||
|
||||
Source: [`packages/storage/storage-domain/src/events.ts:46`](../../packages/storage/storage-domain/src/events.ts)
|
||||
<!-- END GENERATED cordis-surface -->
|
||||
|
||||
Reference in New Issue
Block a user