@ai-matrx/content-ir-react 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/dist/component-resolution.types-BS1ySIg-.d.cts +104 -0
  3. package/dist/component-resolution.types-BS1ySIg-.d.ts +104 -0
  4. package/dist/component-resolution.types-fvR92hW7.d.cts +142 -0
  5. package/dist/component-resolution.types-fvR92hW7.d.ts +142 -0
  6. package/dist/db-component.cjs +226 -0
  7. package/dist/db-component.cjs.map +1 -0
  8. package/dist/db-component.d.cts +267 -0
  9. package/dist/db-component.d.ts +267 -0
  10. package/dist/db-component.js +194 -0
  11. package/dist/db-component.js.map +1 -0
  12. package/dist/host-types-CZ_Bkp4R.d.ts +131 -0
  13. package/dist/host-types-DvGv8s9L.d.cts +131 -0
  14. package/dist/host.cjs +74 -0
  15. package/dist/host.cjs.map +1 -0
  16. package/dist/host.d.cts +24 -0
  17. package/dist/host.d.ts +24 -0
  18. package/dist/host.js +52 -0
  19. package/dist/host.js.map +1 -0
  20. package/dist/index.cjs +356 -90
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +280 -672
  23. package/dist/index.d.ts +280 -672
  24. package/dist/index.js +316 -31
  25. package/dist/index.js.map +1 -1
  26. package/dist/react.cjs +361 -0
  27. package/dist/react.cjs.map +1 -0
  28. package/dist/react.d.cts +195 -0
  29. package/dist/react.d.ts +195 -0
  30. package/dist/react.js +344 -0
  31. package/dist/react.js.map +1 -0
  32. package/dist/resolver.cjs +327 -0
  33. package/dist/resolver.cjs.map +1 -0
  34. package/dist/resolver.d.cts +133 -0
  35. package/dist/resolver.d.ts +133 -0
  36. package/dist/resolver.js +304 -0
  37. package/dist/resolver.js.map +1 -0
  38. package/dist/route-C1XNcubB.d.ts +433 -0
  39. package/dist/route-C55jsF4B.d.cts +433 -0
  40. package/dist/route.cjs +259 -0
  41. package/dist/route.cjs.map +1 -0
  42. package/dist/route.d.cts +4 -0
  43. package/dist/route.d.ts +4 -0
  44. package/dist/route.js +247 -0
  45. package/dist/route.js.map +1 -0
  46. package/package.json +75 -2
package/dist/index.d.cts CHANGED
@@ -1,279 +1,17 @@
1
- import * as react from 'react';
2
- import react__default, { ReactNode } from 'react';
3
- import { KindDefinition, CanonicalBlockIR, PartialKindEvent } from '@ai-matrx/content-ir';
4
-
5
- /**
6
- * THE SCREAM SEAM.
7
- *
8
- * Every recovery path in this package is loud: a defective component row, a
9
- * failed resolver load, a kind whose component throws on a provisional value.
10
- * The package refuses to own where those screams land — matrx-frontend routes
11
- * them to the Error Inspector, the dashboard to its own log, the extension to
12
- * its background page. Each host binds one function.
13
- *
14
- * A host that binds a no-op has chosen silence, which is a defect in itself;
15
- * {@link consoleErrorReporter} is the honest default.
16
- */
17
- interface ContentIrErrorReport {
18
- /** Always `"content-ir"` — hosts key their capture stores on it. */
19
- source: "content-ir";
20
- message: string;
21
- name?: string;
22
- stack?: string;
23
- /** Free-form grouping key (the host's `relation`), e.g. `"partial-kind"`. */
24
- relation?: string;
25
- raw?: unknown;
26
- }
27
- type ContentIrErrorReporter = (report: ContentIrErrorReport) => void;
28
- /** The default when a host binds nothing: never silent. */
29
- declare const consoleErrorReporter: ContentIrErrorReporter;
30
-
31
- /**
32
- * The (kind, platform, role) → component vocabulary — the Shape System's
33
- * resolver contract (rulings R1 + R6), stated once for every UI.
34
- *
35
- * Cross-repo system-of-record:
36
- * `common-docs/systems/content-ir-twin/FEATURE.md` (package boundary) and
37
- * `matrx-frontend/features/content-ir/docs/SHAPE_SYSTEM.md` (the semantics).
38
- *
39
- * Nothing here knows where a row comes from. A host supplies rows from
40
- * `content_ir.kind_component` (Supabase, a REST call, a fixture); the resolver
41
- * only knows the shape.
42
- */
43
- /** JSON object, restated locally so this package depends on no host type. */
44
- type JsonObject = Record<string, unknown>;
45
- /**
46
- * Which face of the shape a component draws.
47
- *
48
- * - `output` — the shape's finished value, the component a reader sees.
49
- * - `input` — the authoring form for a value of this shape.
50
- * - `loading` — the shape's LOADING face: what renders from the instant the
51
- * kind is identified until its output component has a renderable frame.
52
- * Authored per kind like any other component and fed the region's partial
53
- * value each frame, so it can PERFORM the arrival (surface real text as it
54
- * lands) instead of drawing a shapeless skeleton. Optional: a kind with no
55
- * `loading` component falls back to the host's loading library.
56
- */
57
- type ComponentRole = "output" | "input" | "loading";
58
- /**
59
- * One `content_ir.kind_component` row, projected to exactly what rendering
60
- * needs. Hosts map their own query result onto this.
61
- */
62
- interface KindComponentRow {
63
- kind: string;
64
- platform: string;
65
- role: ComponentRole;
66
- componentKey: string;
67
- /** `source` column vocabulary: "bundled" | "db" (db = web sandbox only). */
68
- source: string;
69
- config: JsonObject;
70
- isActive: boolean;
71
- componentSource: string | null;
72
- propsTransform: string | null;
73
- /**
74
- * Whether the row carries a real `component_source` body — supplied by the
75
- * host when its warm list is BODY-LESS (the lazy design: metadata travels
76
- * on the list, the body arrives per kind via the cold fetch). Omitted →
77
- * derived from `componentSource` itself, so eager hosts change nothing.
78
- */
79
- hasComponentSource?: boolean;
80
- pinnedKindVersion: number | null;
81
- updatedAt: string | null;
82
- createdBy: string | null;
83
- }
84
- /**
85
- * One COMPILED bootstrap entry — the trusted-at-boot floor a host ships in its
86
- * bundle, available synchronously from the first streamed byte.
87
- */
88
- interface SystemComponentEntry {
89
- kind: string;
90
- platform: string;
91
- role: ComponentRole;
92
- componentKey: string;
93
- source: string;
94
- config: JsonObject;
95
- }
96
- /** The resolver's answer for one (kind, platform, role). */
97
- interface ComponentResolution {
98
- /** The component key the renderer routes on (e.g. "flashcards"). */
99
- componentKey: string;
100
- source: string;
101
- config: JsonObject;
102
- /**
103
- * Render-trust verdict (R6). Compiled entries are always active (trusted at
104
- * bootstrap); DB rows carry their own `is_active`.
105
- */
106
- isActive: boolean;
107
- /** Which tier produced this answer — the verification hook's `by`. */
108
- resolvedBy: "compiled" | "db";
109
- componentSource: string | null;
110
- propsTransform: string | null;
111
- /**
112
- * TRUE when the row owns a real component body — even if `componentSource`
113
- * is null because the host's warm list is body-less and the cold fetch has
114
- * not landed it yet. THE routing gate: `routeToDbComponent` re-types on
115
- * this flag, never on body presence, so a body-less row still routes and
116
- * the renderer fetches/compiles the body lazily.
117
- */
118
- hasComponentSource: boolean;
119
- pinnedKindVersion: number | null;
120
- /** The db row's `updated_at` — the compile-cache staleness key. */
121
- updatedAt: string | null;
122
- createdBy: string | null;
123
- }
124
- /**
125
- * The read side of a component resolver, as the render layer consumes it.
126
- * The package ships {@link ComponentResolver}; a host with its own resolver
127
- * only has to satisfy this.
128
- */
129
- interface ComponentResolutionSource {
130
- /** Synchronous — the render seam's per-block call. */
131
- resolve(kind: string, platform: string, role: ComponentRole): ComponentResolution | null;
132
- /** Eager targeted fetch for one kind; fire-and-forget, never awaited on the hot path. */
133
- requestComponent(kind: string, platform: string, role: ComponentRole): void;
134
- /** One list fetch per session. */
135
- ensureWarm(): Promise<void>;
136
- /** Refresh-on-view; rate-limited and deduped by the implementation. */
137
- refresh(maxAgeMs?: number): Promise<void>;
138
- /** Monotonic tier version — has anything at all changed? */
139
- getVersion(): number;
140
- /** Monotonic per-kind version (+ wholesale epoch) — the granular repaint key. */
141
- getKindVersion(kind: string): number;
142
- subscribe(listener: () => void): () => void;
143
- subscribeKind(kind: string, listener: () => void): () => void;
144
- }
145
-
146
- /**
147
- * THE HOST CONTRACT — everything this package refuses to decide.
148
- *
149
- * The kernel (`@ai-matrx/content-ir`) proved the shape: extract the portable
150
- * part, let host capability enter through explicit named seams. The render
151
- * layer needs four things it must never own:
152
- *
153
- * 1. WHERE KIND DEFINITIONS COME FROM (a bundled table, `content_ir`, a REST
154
- * call). The route only asks "is this kind registered, and does it carry a
155
- * legacy bridge / a partial-ready opt-in".
156
- * 2. WHERE COMPONENT ROWS COME FROM — {@link ComponentResolutionSource}. The
157
- * package ships `ComponentResolver`, which any host can construct with its
158
- * own loaders; a host with its own resolver only has to satisfy the type.
159
- * 3. HOW A ROUTED BLOCK ACTUALLY DRAWS. `applyIrKindRoute` decides a block's
160
- * TYPE; turning that type into pixels is the host's dispatch table
161
- * (matrx-frontend's `BlockRenderer`, the dashboard's small map). The
162
- * package never imports a component library.
163
- * 4. WHERE SCREAMS LAND — {@link ContentIrErrorReporter}.
164
- *
165
- * No Next.js, no Redux, no Supabase, no router, no host error capture. If a
166
- * seam is missing, ADD A SEAM — never an import.
167
- */
168
-
169
- /**
170
- * The minimum a render block must expose for the kind route to work. Hosts
171
- * pass their own richer block type through; the route is generic over `T` and
172
- * preserves every extra field.
173
- */
174
- interface IrRoutableBlock {
175
- type: string;
176
- serverData?: Record<string, unknown>;
177
- metadata?: Record<string, unknown>;
178
- }
179
- /** A routable block that also carries its source text (the raw region). */
180
- interface IrRenderBlock extends IrRoutableBlock {
181
- content: string;
182
- language?: string;
183
- }
184
- /**
185
- * Where registered kinds come from. `getDefinition` is the only method the
186
- * pure route needs; the rest drive the granular repaint and the warm-up tick
187
- * that keeps a cold registry from being mistaken for "this kind has no
188
- * component".
189
- */
190
- interface KindDefinitionSource {
191
- getDefinition(kind: string): KindDefinition | undefined;
192
- /** Monotonic per-kind version — the repaint snapshot key. */
193
- getKindVersion(kind: string): number;
194
- subscribeKind(kind: string, listener: () => void): () => void;
195
- /** One definition load per app session. */
196
- ensureWarm(): Promise<void>;
197
- }
198
- /**
199
- * The rendering seams. Everything here returns host UI; the package supplies
200
- * the DECISIONS and the chrome-free structure around them.
201
- */
202
- interface ContentIrRenderSeams {
203
- /**
204
- * Draw a block the kind route has already typed. This is the host's dispatch
205
- * table — the single place a component key becomes a component.
206
- */
207
- renderBlock(block: IrRenderBlock): ReactNode;
208
- /**
209
- * THE FLOOR: render ANY JSON value as a human document. Reached when a kind
210
- * has no render-trusted component, when the value is not an object at all,
211
- * and by the generic structured view.
212
- *
213
- * This is deliberately a seam and not a bundled component. Rendering a value
214
- * WELL means prose through the host's markdown renderer, media through the
215
- * host's file handler, and uniform arrays through the host's data table —
216
- * all of which are host property. A host that has none of those can pass a
217
- * `<pre>`; it will be honest, just plain.
218
- */
219
- renderValue(props: StructuredValueRenderProps): ReactNode;
220
- /**
221
- * The "still arriving" indicator used by the provisional frame. Optional —
222
- * hosts without a shimmer get plain text.
223
- */
224
- renderShimmer?(text: string): ReactNode;
225
- /**
226
- * The honest "this shape has no custom component yet" notice. Optional: the
227
- * package draws a plain amber line when a host supplies nothing, and a host
228
- * with an icon set or its own callout component supplies that instead. It is
229
- * a seam and not a bundled component because this package depends on no icon
230
- * library.
231
- */
232
- renderNotice?(text: string): ReactNode;
233
- }
234
- interface StructuredValueRenderProps {
235
- value: unknown;
236
- /** The kind slug this value claims, when known. Honesty line only — never a renderer choice. */
237
- kind?: string;
238
- /** Why this shape has no custom view, in human words. */
239
- note?: string;
240
- /** Show the "what this is / raw data" footer. Default true. */
241
- footer?: boolean;
242
- }
243
- /**
244
- * One host, wired once, read by every component in this package through
245
- * {@link ContentIrRenderProvider}.
246
- */
247
- interface ContentIrHost extends ContentIrRenderSeams {
248
- kinds: KindDefinitionSource;
249
- components: ComponentResolutionSource;
250
- reportError: ContentIrErrorReporter;
251
- /**
252
- * The `kind_component.platform` this host resolves as. "web" for every
253
- * browser UI; the column already models "react-native" and friends, and a
254
- * host that lies here renders the wrong component everywhere.
255
- */
256
- platform: string;
257
- }
258
- /**
259
- * The pure route's dependencies — a strict subset of {@link ContentIrHost},
260
- * because `applyIrKindRoute` is called OUTSIDE React (reducers, stream
261
- * accumulators, tests) where there is no provider to read.
262
- */
263
- interface KindRouteEnv {
264
- kinds: Pick<KindDefinitionSource, "getDefinition">;
265
- components: Pick<ComponentResolutionSource, "resolve">;
266
- reportError: ContentIrErrorReporter;
267
- platform: string;
268
- }
269
- /** Narrow a host (or anything host-shaped) to what the pure route needs. */
270
- declare function routeEnvOf(host: ContentIrHost): KindRouteEnv;
1
+ import { C as ComponentResolutionSource, a as ComponentResolution, b as ContentIrErrorReporter } from './component-resolution.types-fvR92hW7.cjs';
2
+ export { c as ComponentRole, d as ContentIrErrorReport, J as JsonObject, K as KindComponentRow, S as SystemComponentEntry, e as consoleErrorReporter } from './component-resolution.types-fvR92hW7.cjs';
3
+ import { C as ContentIrHost, K as KindRouteEnv, a as KindDefinitionSource } from './route-C55jsF4B.cjs';
4
+ export { b as ContentIrRenderSeams, D as DB_KIND_COMPONENT_KEY, G as GENERIC_STRUCTURED_COMPONENT_KEY, c as GenericFallbackReason, I as IR_PROVISIONAL_KEY, d as IR_ROUTE_KEY, e as IrRenderBlock, f as IrRoutableBlock, g as IrRouteMarker, h as KindRouteBinding, i as KindRouteOptions, P as PartialRenderOptions, j as ProvisionalKindRender, S as StructuredValueRenderProps, k as applyIrKindRoute, l as createKindRouteBinding, m as envelopeFromPartialKind, n as isPartialReadyKind, o as isProvisionalBlock, p as kindServerDataFromStoredValue, q as markKindPartialUnsafe, r as readIrRouteMarker, s as resetPartialUnsafeKinds, t as resetSourcelessDbRowReports, u as resolveAnnouncedKindLoading, v as resolveProvisionalKindRender, w as routeEnvOf } from './route-C55jsF4B.cjs';
5
+ import * as React from 'react';
6
+ import React__default, { ReactNode } from 'react';
7
+ export { ComponentResolver, ComponentResolverOptions } from './resolver.cjs';
8
+ import '@ai-matrx/content-ir';
271
9
 
272
10
  interface ContentIrRenderProviderProps {
273
11
  host: ContentIrHost;
274
12
  children: ReactNode;
275
13
  }
276
- declare function ContentIrRenderProvider({ host, children, }: ContentIrRenderProviderProps): react.JSX.Element;
14
+ declare function ContentIrRenderProvider({ host, children, }: ContentIrRenderProviderProps): React.JSX.Element;
277
15
  /**
278
16
  * The wired host, or null. For the rare consumer that can legitimately run
279
17
  * without a provider because it was handed its sources explicitly (see
@@ -285,399 +23,6 @@ declare function useContentIrHost(): ContentIrHost;
285
23
  /** The wired host narrowed to what the pure route functions take. */
286
24
  declare function useKindRouteEnv(): KindRouteEnv;
287
25
 
288
- /**
289
- * The Shape System component RESOLVER (rulings R1 + R6): (kind, platform,
290
- * role) → component, with two tiers:
291
- *
292
- * - eager: a COMPILED bootstrap the host ships in its bundle — the
293
- * trusted-at-boot floor, available at import so the render seam can gate
294
- * synchronously from the first streamed byte.
295
- * - warm: one `content_ir.kind_component` list fetch per app session
296
- * (`ensureWarm`). A DB row for a (kind, platform, role) OVERRIDES the
297
- * compiled entry once warm; the compiled floor keeps answering until then
298
- * (and forever, on DB failure).
299
- *
300
- * Resolution is SYNCHRONOUS (the render seam calls it per block); the only
301
- * async work is the loading, off the render path.
302
- *
303
- * WHAT MOVED AND WHY. This class was matrx-frontend's `ComponentRegistry`. It
304
- * is a large part of why a second UI could not render a kind: every tier rule,
305
- * every repaint counter, every dedupe latch lived in one app. Nothing about it
306
- * is Next.js, Redux, or Supabase — the only host-specific parts were the two
307
- * loaders and the error sink, which are now constructor arguments.
308
- */
309
-
310
- interface ComponentResolverOptions {
311
- /**
312
- * The compiled bootstrap, as a THUNK resolved on first use: a host's system
313
- * component table is often mid-initialization when this module evaluates
314
- * (matrx-frontend's registry cluster has a deliberate import cycle).
315
- */
316
- compiledEntries?: () => SystemComponentEntry[];
317
- /** The warm/refresh list load — every `kind_component` row the user may see. */
318
- loadAll?: () => Promise<KindComponentRow[]>;
319
- /** The eager single-kind load fired the moment a kind is identified mid-stream. */
320
- loadForKind?: (kind: string, platform: string) => Promise<KindComponentRow[]>;
321
- /** Where recovery screams land. Defaults to `console.error`, never silence. */
322
- reportError?: ContentIrErrorReporter;
323
- /** Clock seam — the refresh rate limiter. Defaults to `Date.now`. */
324
- now?: () => number;
325
- }
326
- declare class ComponentResolver implements ComponentResolutionSource {
327
- private compiled;
328
- private readonly db;
329
- private warmPromise;
330
- private warmFailureLogged;
331
- /**
332
- * When the last successful wholesale refresh landed, or null for "never".
333
- * Explicitly nullable rather than 0: with a host-supplied clock that starts
334
- * near zero, a `0` sentinel makes the FIRST refresh look rate-limited and
335
- * silently skip.
336
- */
337
- private lastRefreshAt;
338
- private refreshPromise;
339
- private readonly listeners;
340
- /**
341
- * Cold single-kind fetch dedupe (streaming eager path). In-flight is keyed
342
- * by (kind, platform) — the fetch unit; misses are keyed by (kind, platform,
343
- * role) so a miss on web/output never suppresses other roles, and CLEARED on
344
- * every wholesale refresh (a component created mid-session becomes eagerly
345
- * fetchable again — misses are cheap to re-verify).
346
- */
347
- private readonly coldInFlight;
348
- private readonly coldMisses;
349
- /** Monotonic db-tier version — the repaint hook's snapshot key. */
350
- private version;
351
- /** Per-kind versions + listeners (granular repaint) + wholesale epoch. */
352
- private readonly kindVersions;
353
- private readonly kindListeners;
354
- private epoch;
355
- private readonly reportError;
356
- private readonly now;
357
- private readonly options;
358
- constructor(options?: ComponentResolverOptions);
359
- private compiledMap;
360
- /**
361
- * Synchronous resolve — the render seam's per-block call. DB override first
362
- * (once warm), compiled floor second, null for unknown.
363
- */
364
- resolve(kind: string, platform: string, role: ComponentRole): ComponentResolution | null;
365
- /** R6 floor check: compiled-bootstrap membership = always render-trusted. */
366
- hasCompiled(kind: string, platform: string, role: ComponentRole): boolean;
367
- /**
368
- * Pure ingest — the warm landing point and the unit-test seam. First row per
369
- * key wins: rows arrive is_default-first / sort_order-asc from the source.
370
- */
371
- ingestDbRows(rows: readonly KindComponentRow[]): void;
372
- /**
373
- * Refresh landing point: REPLACE the db tier wholesale (same
374
- * first-row-per-key contract as {@link ingestDbRows}) so edits, deletions,
375
- * and is_active flips all take effect. Always notifies.
376
- */
377
- replaceDbRows(rows: readonly KindComponentRow[]): void;
378
- getVersion(): number;
379
- getKindVersion(kind: string): number;
380
- subscribeKind(kind: string, listener: () => void): () => void;
381
- subscribe(listener: () => void): () => void;
382
- private bumpKind;
383
- private notifyChanged;
384
- /**
385
- * A warm metadata shell is resolved enough for routing, but not for the
386
- * host's db-component renderer. Its body must still come from the cold
387
- * single-kind loader.
388
- */
389
- private needsColdFetch;
390
- /**
391
- * Cold rows are the authoritative heavy form of warm metadata shells. Keep
392
- * the same first-row-per-key winner contract, but replace an existing shell
393
- * so `componentSource` / `propsTransform` can land and repaint the kind.
394
- */
395
- private ingestColdRows;
396
- /**
397
- * The eager lightweight single-kind fetch (streaming path): the moment a
398
- * cloud kind is identified mid-stream, pull ONLY that kind's resolver rows
399
- * and ingest them so {@link resolve} can answer before — or shortly after —
400
- * the region completes. Deduped in-flight and by known-miss. Fire-and-forget;
401
- * failures are loud (the warm list remains the backstop).
402
- */
403
- requestComponent(kind: string, platform: string, role: ComponentRole): void;
404
- /**
405
- * Refresh-on-view: re-fetch the warm list and REPLACE the db tier, so an
406
- * edited `source='db'` component (its `updated_at` bump re-keys the host's
407
- * compile cache) renders fresh on the next view. Deduped in-flight and
408
- * rate-limited by `maxAgeMs` (default 10s) — mounting several previews costs
409
- * one fetch. Server-side edits do NOT push to open clients; the contract is
410
- * refresh-on-view via this call.
411
- */
412
- refresh(maxAgeMs?: number): Promise<void>;
413
- /** One list fetch per app session; failed loads retry on the next call. */
414
- ensureWarm(): Promise<void>;
415
- }
416
-
417
- /**
418
- * THE KIND ROUTE — the render flip, as a pure block transform.
419
- *
420
- * A block whose `metadata.__ir` envelope resolved a REGISTERED kind is routed
421
- * to that kind's component: via the legacy-bridge facet (`legacyBlockType` +
422
- * `toLegacyServerData`) when the kind has one, so the block enters the host's
423
- * existing renderer as its real type with envelope-derived serverData;
424
- * otherwise via the component resolver. Blocks with no envelope, an
425
- * unregistered kind, or no bridge facet pass through UNTOUCHED — the strangler
426
- * seam.
427
- *
428
- * This is where a bare/fenced JSON flashcard_set — which a text detector could
429
- * only ever call "code" — becomes real flashcards, live while streaming.
430
- *
431
- * PORTABILITY. This function was matrx-frontend's `react/kind-route.ts` and is
432
- * the single most-copied thing in the system: every UI that renders a kind has
433
- * to make exactly these decisions in exactly this order, and a second
434
- * implementation of them is a guaranteed divergence. It takes its registries,
435
- * its platform, and its error sink as an {@link KindRouteEnv} argument rather
436
- * than importing them, so it is callable from a reducer, a stream accumulator,
437
- * a test, or a React render — in any app.
438
- *
439
- * Semantics: `matrx-frontend/features/content-ir/docs/SHAPE_SYSTEM.md`
440
- * (registry, dual gate, `kind_component` resolution, rulings R1 + R6).
441
- */
442
-
443
- /**
444
- * Runtime routing marker (the Shape System's verification hook): stamped on
445
- * `metadata.__ir_route` whenever a block routes AND the component resolver
446
- * produced the decision. `by` says which resolver tier answered ("compiled"
447
- * floor vs a warm `content_ir.kind_component` row) — the live proof of
448
- * registry-resolution vs hard-coded fallback. Metadata-only, non-breaking.
449
- */
450
- declare const IR_ROUTE_KEY: "__ir_route";
451
- /**
452
- * The component key the R6 generic fallback routes to — the official renderer
453
- * for a KNOWN shape that nothing render-trusted claims. Hosts map this key to
454
- * their generic structured view (the package ships one: `GenericStructuredView`).
455
- */
456
- declare const GENERIC_STRUCTURED_COMPONENT_KEY: "generic_structured";
457
- /**
458
- * The block type a DB-sourced (user-authored) kind component renders as.
459
- * FE-synthesized: produced ONLY here, never emitted upstream. A host that has
460
- * no sandbox for user components simply does not map this key — the block then
461
- * falls to that host's unknown-type handling, which is honest.
462
- */
463
- declare const DB_KIND_COMPONENT_KEY: "db_kind_component";
464
- /** Test-only reset of the once-per-kind console latch. */
465
- declare function resetSourcelessDbRowReports(): void;
466
- /** Why a block landed on the generic viewer instead of a real renderer. */
467
- type GenericFallbackReason =
468
- /** No compiled bridge and no `content_ir.kind_component` row at all. */
469
- "no-component"
470
- /** A component row exists but is held `is_active = false`. */
471
- | "inactive"
472
- /**
473
- * An ACTIVE component row exists and names `generic_structured` — i.e. the
474
- * fallback, registered under a component's name. This reads as coverage to
475
- * every count-the-rows check on the platform and is not: the reader still
476
- * gets a key/value dump. Kept as its own reason because the repair differs
477
- * (author a component AND retire the decoy row), and because a page that
478
- * silently marked itself `by: "bundled"` here is how 226 of 428 active
479
- * kinds came to be certified as renderable while rendering generically
480
- * (found 2026-08-23).
481
- */
482
- | "generic-row"
483
- /**
484
- * The envelope carries a kind-preserved RAW: the payload identified a
485
- * registered kind and its value FAILED a check — a schema violation, an
486
- * array-item kind mismatch, a duplicate key, a contradicted speculation.
487
- * The instance is BROKEN, not component-less — the repair is fixing the
488
- * payload or the schema, and the generic floor must acknowledge the kind and
489
- * surface the recorded problems.
490
- *
491
- * NOT this: a kind whose schema was never available (`kindState:
492
- * "unverified"`). Nothing checked that value, so calling it broken is a
493
- * false accusation — it routes to its component. The two were one state
494
- * until 2026-08-29 and conflating them was a platform-wide outage.
495
- */
496
- | "broken-instance"
497
- /**
498
- * The slug is not in the registry at all (typo, foreign emitter, a shape
499
- * not yet created). Routed anyway — Arman's 2026-08-29 ruling: a root
500
- * `__kind` key means the kind system owns the render, no exceptions. The
501
- * repair is creating/registering the shape (or fixing the slug).
502
- */
503
- | "unregistered";
504
- interface IrRouteMarker {
505
- by: ComponentResolution["resolvedBy"] | "generic";
506
- key: string;
507
- /**
508
- * Only on the generic fallback: the shape is NOT render-trusted, so the
509
- * viewer must say so out loud (R6 — never an error, never hidden content).
510
- */
511
- unverified?: true;
512
- reason?: GenericFallbackReason;
513
- }
514
- /** Read the routing marker a block picked up at the seam (or null). */
515
- declare function readIrRouteMarker(metadata: Record<string, unknown> | null | undefined): IrRouteMarker | null;
516
- interface KindRouteOptions {
517
- /**
518
- * Block types this host OWNS and the route must never re-type, however good
519
- * the envelope on them looks.
520
- *
521
- * matrx-frontend passes `["artifact"]`: an artifact block has an identity, a
522
- * version, and a Canvas to open in, and since 2026-08-18 it carries
523
- * `metadata.__ir` so SELECTORS can read the envelope. That envelope is DATA
524
- * there, not a route — re-typing it to the bare kind component would strip
525
- * the artifact chrome and lose the door to the Canvas.
526
- */
527
- ownedTypes?: readonly string[];
528
- }
529
- declare function applyIrKindRoute<T extends IrRoutableBlock>(block: T, env: KindRouteEnv, options?: KindRouteOptions): T;
530
- /**
531
- * Rehydration route for STRUCTURED persisted artifacts.
532
- *
533
- * A materialized kind artifact stores its zero-loss value object (carrying
534
- * `__kind`) alongside its row. Given that stored value, derive the registered
535
- * kind's legacy `serverData` WITHOUT re-parsing any text: the value wraps into
536
- * a complete envelope and runs through the same `toLegacyServerData` bridge the
537
- * live stream uses. Returns null for non-objects, unregistered kinds, or kinds
538
- * without a legacy bridge — callers fall back to their string-payload path.
539
- */
540
- declare function kindServerDataFromStoredValue(value: unknown, env: Pick<KindRouteEnv, "kinds">): Record<string, unknown> | null;
541
-
542
- /**
543
- * Routing the PROVISIONAL half of the streaming partial-kinds contract.
544
- *
545
- * Cross-repo system-of-record (read it before changing anything here):
546
- * `common-docs/systems/content-ir-system/STREAMING_PARTIAL_KINDS.md` §8.
547
- * The reader/validator half lives in `@ai-matrx/content-ir` (`wire/partial-kind`);
548
- * the wire gate runs in each host's stream ingest.
549
- *
550
- * WHAT THIS DOES
551
- * --------------
552
- * While a structured region streams, the server announces what it thinks the
553
- * region IS and what has arrived so far (`metadata.__ir_partial`). This module
554
- * turns that provisional event into a routed block that renders through the
555
- * EXACT SAME component the final value renders in — which is the entire point:
556
- * a bespoke skeleton renderer would be a second render path and is banned.
557
- *
558
- * HOW, without touching the verified channel
559
- * ------------------------------------------
560
- * `root` is deliberately `IrStructuredNode`-shaped, so the event wraps into a
561
- * `CanonicalBlockIR` and every existing reader — the compiled bridge, the
562
- * component resolver, the db-component flip, the generic viewer — works
563
- * unchanged. That provisional envelope is placed on a RENDER-LOCAL COPY of the
564
- * block's metadata under `__ir`, never on the wire and never in host state. The
565
- * block also carries `__ir_provisional: true` so any downstream reader can tell
566
- * a provisional render from a verified one.
567
- *
568
- * THE POSTURE: WITHHOLD BY DEFAULT, OPT IN PER KIND
569
- * -------------------------------------------------
570
- * A provisional value MAY be missing required fields — that is what the
571
- * `partial_unvalidated` notice declares — and §8 of the contract requires that
572
- * a component which throws on an absent field is not routed one. Rather than
573
- * audit every component, the default is WITHHOLD: nothing changes and the block
574
- * keeps its loading skeleton. A kind opts in with `partialReady: true` on its
575
- * registry definition. If an opted-in component throws anyway,
576
- * `ProvisionalKindBoundary` screams and calls `markKindPartialUnsafe`, which
577
- * drops that kind back to withhold for the rest of the session — loud recovery,
578
- * never a broken surface.
579
- *
580
- * TERMINALS
581
- * ---------
582
- * `superseded` and `retracted` produce NO provisional render, so the swap to
583
- * the final value happens in the same frame the terminal arrives — never a
584
- * flicker through an empty state. Both are explicit EVENTS: the terminal is
585
- * never inferred from the arrival of `__ir`, because a completed block often
586
- * has no `__ir` at all (unregistered kind, schema drift, cold catalog) and
587
- * inferring it would leave the skeleton up forever in exactly those cases.
588
- */
589
-
590
- /**
591
- * Marker stamped on a render-local block whose `__ir` is PROVISIONAL. Never
592
- * emitted by a producer, never persisted, never on the wire.
593
- */
594
- declare const IR_PROVISIONAL_KEY: "__ir_provisional";
595
- /** True when this block's metadata carries a provisional (not verified) envelope. */
596
- declare function isProvisionalBlock(metadata: Record<string, unknown> | null | undefined): boolean;
597
- /** Wrap a validated `partial` event into the envelope shape every IR reader consumes. */
598
- declare function envelopeFromPartialKind(event: PartialKindEvent): CanonicalBlockIR;
599
- /** Loud recovery hook — called by ProvisionalKindBoundary when a render throws. */
600
- declare function markKindPartialUnsafe(kind: string): void;
601
- /** Test-only reset of the session latch. */
602
- declare function resetPartialUnsafeKinds(): void;
603
- /**
604
- * Has this kind opted in to being handed a provisional value? Withhold is the
605
- * default; see the module doc.
606
- */
607
- declare function isPartialReadyKind(kind: string, env: Pick<KindRouteEnv, "kinds">): boolean;
608
- interface PartialRenderOptions extends KindRouteOptions {
609
- /**
610
- * Is the STREAM still running? Message-wide, deliberately — not this block's
611
- * own completion.
612
- *
613
- * 🚨 THE ANTI-STUCK-SKELETON BACKSTOP. Law 1 of the contract says every
614
- * partial ends in exactly one terminal, and that law is the ONLY thing
615
- * standing between a user and a "Still arriving" skeleton that never
616
- * resolves. It is a producer guarantee with at least three ways to not fire:
617
- * the drain skips a block missing from the final block list, the emitter
618
- * early-returns once the stream ended or was cancelled (so a client abort
619
- * drops every retraction), and a flush failure is swallowed so it never kills
620
- * a run.
621
- *
622
- * Once the stream is over, no terminal can ever arrive, so a still-open
623
- * provisional is stuck by definition — drop it and let the block's own
624
- * content and `__ir` be the truth. Correct to be message-wide: a terminal for
625
- * THIS block may still be in flight while the block itself looks finished.
626
- *
627
- * `undefined` reads as active, so a caller that does not thread stream state
628
- * keeps live rendering rather than silently losing it.
629
- */
630
- streamActive?: boolean;
631
- }
632
- /**
633
- * The ANNOUNCED-but-not-yet-renderable state: the server has said what this
634
- * region is, and the region cannot render its real component yet.
635
- *
636
- * WHY THIS EXISTS SEPARATELY FROM THE VERIFIED CHANNEL. On a chat stream the
637
- * host's own accumulator fills `__ir` in as it parses. A WORKFLOW run's lane
638
- * does not: when the server opens the block scope it marks the text channel
639
- * `block_shadowed` and the lane stops feeding its accumulator, precisely so one
640
- * region is never rendered twice under two sets of block ids
641
- * (STREAMING_PARTIAL_KINDS.md §7b rule 4). So on a run page there is NO
642
- * streaming `__ir` — the ONLY thing that knows what the region is, is the
643
- * partial channel. Without this, a workflow node's structured answer fell
644
- * through to the raw-text renderer: a generic loader, then raw JSON
645
- * accumulating, then a swap at the end.
646
- *
647
- * Returns the provisional envelope to feed the kind's loading component, or
648
- * null when there is nothing announced (no event, a terminal, a dead stream).
649
- * Deliberately independent of `partialReady`: withholding a VALUE from a
650
- * component that might throw on it is a real decision, but withholding the
651
- * kind's own loading state is not — a skeleton cannot throw, and the reader
652
- * seeing what is coming is the whole point.
653
- */
654
- declare function resolveAnnouncedKindLoading(block: {
655
- metadata?: Record<string, unknown>;
656
- }, options?: Pick<PartialRenderOptions, "streamActive">): {
657
- kind: string;
658
- envelope: CanonicalBlockIR;
659
- } | null;
660
- interface ProvisionalKindRender<T> {
661
- /** The routed block — same type/serverData shape the final value produces. */
662
- block: T;
663
- /** The announced (speculative) kind. */
664
- kind: string;
665
- /** Per-block ordering key, for diagnostics. */
666
- seq: number;
667
- /** The provisional envelope — feeds the loading skeleton used as the throw fallback. */
668
- envelope: CanonicalBlockIR;
669
- }
670
- /**
671
- * Resolve a block's provisional render, or null when there is nothing to show
672
- * provisionally (no event, a terminal event, a withheld kind, a kind nothing
673
- * can route, or a verified envelope that already won).
674
- *
675
- * Pure: no React, no host state, no side effects beyond the registry reads.
676
- */
677
- declare function resolveProvisionalKindRender<T extends IrRoutableBlock & {
678
- metadata?: Record<string, unknown>;
679
- }>(block: T, env: KindRouteEnv, options?: PartialRenderOptions): ProvisionalKindRender<T> | null;
680
-
681
26
  /**
682
27
  * The two registries this hook watches. Passed explicitly by a host whose
683
28
  * render path sits BELOW no provider — matrx-frontend's block renderer runs
@@ -755,7 +100,7 @@ interface KindInstanceRenderProps {
755
100
  variant?: "card" | "bare";
756
101
  className?: string;
757
102
  }
758
- declare function KindInstanceRender({ kind, value, showRoutingNote, unroutableFallback, variant, className, }: KindInstanceRenderProps): react.JSX.Element;
103
+ declare function KindInstanceRender({ kind, value, showRoutingNote, unroutableFallback, variant, className, }: KindInstanceRenderProps): React.JSX.Element;
759
104
 
760
105
  /**
761
106
  * The safety net + the "still arriving" affordance for a provisional kind
@@ -789,7 +134,7 @@ interface ProvisionalKindBoundaryOwnProps {
789
134
  fallback: ReactNode;
790
135
  children: ReactNode;
791
136
  }
792
- declare function ProvisionalKindBoundary(props: ProvisionalKindBoundaryOwnProps): react__default.JSX.Element;
137
+ declare function ProvisionalKindBoundary(props: ProvisionalKindBoundaryOwnProps): React__default.JSX.Element;
793
138
  /**
794
139
  * The "still arriving" frame. `aria-busy` carries the same fact to assistive
795
140
  * tech that the chip carries visually. The chip's own rendering is a host seam
@@ -798,7 +143,7 @@ declare function ProvisionalKindBoundary(props: ProvisionalKindBoundaryOwnProps)
798
143
  */
799
144
  declare function ProvisionalKindFrame({ children }: {
800
145
  children: ReactNode;
801
- }): react__default.JSX.Element;
146
+ }): React__default.JSX.Element;
802
147
 
803
148
  interface GenericStructuredViewProps {
804
149
  /** The raw region source — the zero-loss floor when no envelope survived. */
@@ -812,7 +157,7 @@ interface GenericStructuredViewProps {
812
157
  streamingIndicator?: ReactNode;
813
158
  className?: string;
814
159
  }
815
- declare function GenericStructuredView({ content, metadata, streamingIndicator, className, }: GenericStructuredViewProps): react.JSX.Element;
160
+ declare function GenericStructuredView({ content, metadata, streamingIndicator, className, }: GenericStructuredViewProps): React.JSX.Element;
816
161
 
817
162
  interface DelegatedOutputProps {
818
163
  output: unknown;
@@ -840,14 +185,14 @@ interface DelegatedOutputProps {
840
185
  * holding, so it is what routes. With no kind at all there is nothing to route
841
186
  * to, and the host's fallback (or the floor) shows what the step produced.
842
187
  */
843
- declare function DelegatedOutput({ output, declaredKind, fallback, emptyLabel, }: DelegatedOutputProps): react.JSX.Element;
188
+ declare function DelegatedOutput({ output, declaredKind, fallback, emptyLabel, }: DelegatedOutputProps): React.JSX.Element;
844
189
  interface NodeOutcomeViewProps {
845
190
  serverData?: unknown;
846
191
  /** Passed through to {@link DelegatedOutput}. */
847
192
  fallback?: (output: unknown) => ReactNode;
848
193
  }
849
194
  /** THE renderer for the `node_outcome` runtime wrapper kind. */
850
- declare function NodeOutcomeView({ serverData, fallback }: NodeOutcomeViewProps): react.JSX.Element | null;
195
+ declare function NodeOutcomeView({ serverData, fallback }: NodeOutcomeViewProps): React.JSX.Element | null;
851
196
  interface RunResultViewProps {
852
197
  serverData?: unknown;
853
198
  fallback?: (output: unknown) => ReactNode;
@@ -864,6 +209,269 @@ interface RunResultViewProps {
864
209
  * outcomes — otherwise it is the same content the outcomes already carry, and
865
210
  * showing both is the duplication the wrapper exists to prevent.
866
211
  */
867
- declare function RunResultView({ serverData, fallback }: RunResultViewProps): react.JSX.Element | null;
212
+ declare function RunResultView({ serverData, fallback }: RunResultViewProps): React.JSX.Element | null;
213
+
214
+ /**
215
+ * The DB-component COMPILE CACHE — session-scoped, keyed per winning row
216
+ * VERSION, with the loud-recovery policy built in.
217
+ *
218
+ * This was matrx-frontend's `dbKindComponentCache.ts` (316 lines of compile
219
+ * caching + invalidation living in one host), absorbed per C22: cache
220
+ * mechanics, key derivation, the scream-once latch, transform recovery, and
221
+ * config narrowing are PACKAGE policy — every host was going to need exactly
222
+ * these lines, bug for bug. What stays host-injected is exactly what is
223
+ * host-shaped:
224
+ *
225
+ * - THE COMPILER ({@link DbKindComponentCompiler}). Compiling or sandboxing
226
+ * user-authored component source is a security-shaped host decision — the
227
+ * package never bundles Babel or an allowlist scope. matrx-frontend
228
+ * injects its shared allowlist compiler (`compileSlotComponent`); a host
229
+ * with no sandbox simply never constructs a cache.
230
+ * - The default allowed-imports list (host scope registry).
231
+ * - Where screams land ({@link ContentIrErrorReporter}) and where durable
232
+ * incidents go ({@link DbKindComponentIncidentSink}).
233
+ * - Invalidation TRIGGERS ({@link DbKindComponentCachePorts.registerInvalidation}):
234
+ * the host wires its invalidation-registry keys (e.g.
235
+ * `@ai-matrx/kit/invalidation` fired by name when an agent edits a
236
+ * component row); the cache owns what invalidation MEANS.
237
+ *
238
+ * Contract (the db-row component contract, SHAPE_SYSTEM.md):
239
+ * - `component_source` compiles to a React component receiving
240
+ * `{ data, kind, config, runAction, onResolve?, uiOptions? }` where `data`
241
+ * is the kind instance value.
242
+ * - `props_transform` (optional) compiles to a `(data) => data` function
243
+ * applied to the value BEFORE it reaches the component. A throwing or
244
+ * non-compiling transform screams and the untransformed value is used
245
+ * (never a blank hole).
246
+ * - `config.allowed_imports` (string[]) narrows the compile scope; absent,
247
+ * the row gets the host's FULL registered allowlist.
248
+ *
249
+ * Cache key: (kind, platform, role, row.updated_at) — one compile per winning
250
+ * row VERSION. A resolver refresh delivering an edited row (bumped
251
+ * `updated_at`) re-keys and recompiles naturally; `invalidate` /
252
+ * `invalidateAll` force-drop keys. Server edits never push to open clients —
253
+ * the contract is refresh-on-view.
254
+ */
255
+
256
+ /**
257
+ * Settings the MOUNTING UI dictates to a kind component — the standard,
258
+ * growing arg list every component honors (Arman, 2026-07-23). `selectionMode`
259
+ * is the first: it tells a component whether the surface wants the user to
260
+ * pick one value, many, or none (pure display). A component reads what it
261
+ * understands and ignores the rest; absent = its own default (usually display).
262
+ */
263
+ interface KindComponentUiOptions {
264
+ selectionMode?: "single" | "multiple" | "none";
265
+ [key: string]: unknown;
266
+ }
267
+ /**
268
+ * The return channel: how a kind component hands a chosen value back to the
269
+ * surface that mounted it (a Kind Request). The mirror of `runAction`
270
+ * (surface → agent); this is component → surface. Undefined in normal render
271
+ * (chat/notes) — the component simply doesn't offer selection there.
272
+ */
273
+ type ResolveKindValue = (value: unknown) => void;
274
+ /** The envelope every kind action resolves to — a skip/failure is never a silent pass. */
275
+ type DbKindActionResult = {
276
+ ok: true;
277
+ result: unknown;
278
+ } | {
279
+ ok: false;
280
+ error: string;
281
+ };
282
+ /**
283
+ * The action seam a compiled component receives: `runAction(key, input)`
284
+ * triggers a registered platform capability (e.g. "trigger_agent"). Always
285
+ * resolves to an `{ ok }` envelope, never throws — safe to call from imperfect
286
+ * component code. This is the ONLY side-effect channel a sandboxed component
287
+ * gets; it reaches no data directly.
288
+ */
289
+ type RunDbKindAction = (key: string, input: unknown) => Promise<DbKindActionResult>;
290
+ /** Props every compiled DB kind component receives. */
291
+ interface DbKindComponentRenderProps {
292
+ /** The kind instance value — post-`props_transform` when one exists. */
293
+ data: unknown;
294
+ /** The kind slug the value belongs to. */
295
+ kind: string;
296
+ /** The resolver row's `config` object, verbatim (narrowed — see {@link DbKindComponentCache.config}). */
297
+ config: Record<string, unknown>;
298
+ /** The action seam — see {@link RunDbKindAction}. */
299
+ runAction: RunDbKindAction;
300
+ /**
301
+ * Present only when the component is mounted inside a Kind Request. Call it
302
+ * with the user's chosen value to hand that value back to the requesting
303
+ * surface (which resolves its promise). Undefined in normal render.
304
+ */
305
+ onResolve?: ResolveKindValue;
306
+ /** Settings the mounting surface dictates (e.g. `{ selectionMode: "single" }`). */
307
+ uiOptions?: KindComponentUiOptions;
308
+ }
309
+ interface CompiledDbKindComponent {
310
+ Component: React.ComponentType<DbKindComponentRenderProps>;
311
+ /** Compiled `props_transform`, or null when the row declares none. */
312
+ transform: ((data: unknown) => unknown) | null;
313
+ }
314
+ type DbKindCompileResult = {
315
+ ok: true;
316
+ compiled: CompiledDbKindComponent;
317
+ } | {
318
+ ok: false;
319
+ error: string;
320
+ };
321
+ /** The failure modes a browser can observe on a DB kind component. */
322
+ type DbKindComponentIncidentType =
323
+ /** `component_source` did not compile (or produced no component). */
324
+ "compile_error"
325
+ /** The compiled component threw during render (error boundary caught it). */
326
+ | "render_throw"
327
+ /** `props_transform` failed to compile or threw. */
328
+ | "transform_error";
329
+ /**
330
+ * One durable render incident — the payload for whoever can actually FIX the
331
+ * component. A host sink typically files it on the kind's own incident queue
332
+ * (matrx-frontend: `content_ir.kind_component_incident` via RPC); without a
333
+ * sink, a broken component seen only by ordinary users is invisible to its
334
+ * author forever. `data` is the kind instance value — a privacy-conscious sink
335
+ * reduces it to keys + types before it leaves the browser.
336
+ */
337
+ interface DbKindComponentIncident {
338
+ kind: string;
339
+ errorType: DbKindComponentIncidentType;
340
+ message: string;
341
+ platform?: string;
342
+ role?: string;
343
+ componentKey?: string | null;
344
+ componentUpdatedAt?: string | null;
345
+ stack?: string | null;
346
+ data?: unknown;
347
+ }
348
+ type DbKindComponentIncidentSink = (incident: DbKindComponentIncident) => void;
349
+ /**
350
+ * THE COMPILER PORT. Matches matrx-frontend's shared allowlist compiler
351
+ * (`compileSlotComponent`) structurally: source in, `{ Component | error }`
352
+ * out, never throws. The compiled component is generically typed — the cache
353
+ * performs the single deliberate narrowing where the generic compiler meets
354
+ * the kind prop contract.
355
+ */
356
+ type DbKindComponentCompiler = (args: {
357
+ code: string;
358
+ allowedImports: string[];
359
+ }) => {
360
+ Component: React.ComponentType<Record<string, unknown>> | null;
361
+ error: string | null;
362
+ };
363
+ interface DbKindComponentCachePorts {
364
+ /** The host's sandbox compiler — see {@link DbKindComponentCompiler}. */
365
+ compile: DbKindComponentCompiler;
366
+ /** The FULL registered allowlist a row without `config.allowed_imports` gets. */
367
+ defaultAllowedImports: () => string[];
368
+ /** Where screams land (every recovery path is loud). */
369
+ reportError: ContentIrErrorReporter;
370
+ /** Durable incident sink — optional, but a host without one blinds authors. */
371
+ reportIncident?: DbKindComponentIncidentSink;
372
+ /** Default `kind_component.platform` for this host (default "web"). */
373
+ platform?: string;
374
+ /**
375
+ * THE INVALIDATION REGISTRATION PORT. Called once at construction with the
376
+ * cache's `invalidateAll`; the host registers it under its own invalidation
377
+ * keys (e.g. `@ai-matrx/kit/invalidation`'s name-keyed registry, fired when
378
+ * an agent's component write completes). The cache owns the mechanics —
379
+ * what gets dropped, the scream-latch reset; the host owns only WHEN.
380
+ */
381
+ registerInvalidation?: (invalidateAll: () => void) => void;
382
+ }
383
+ interface DbKindComponentCache {
384
+ /**
385
+ * Compile (once per resolver key per row version) a db-source resolution's
386
+ * `component_source` + optional `props_transform`. Synchronous — the caller
387
+ * (a lazily-loaded Impl) already paid the compiler chunk.
388
+ */
389
+ getOrCompile(kind: string, resolution: ComponentResolution, platform?: string, role?: string): DbKindCompileResult;
390
+ /**
391
+ * Apply the row's transform to the kind value. Loud on throw, never fatal —
392
+ * the untransformed value comes back so content is never hidden.
393
+ */
394
+ applyPropsTransform(kind: string, compiled: CompiledDbKindComponent, value: unknown): unknown;
395
+ /**
396
+ * THE CONFIG BOUNDARY. `ComponentResolution.config` is typed
397
+ * `Record<string, unknown>` — deliberately agnostic about a host's JSONB
398
+ * interior. This narrows at runtime (plain object → itself; anything else →
399
+ * scream + empty config) rather than asserting: a row whose `config` is not
400
+ * an object is a malformed `kind_component` row, and the component still
401
+ * renders rather than crashing.
402
+ */
403
+ config(config: unknown, kind: string): Record<string, unknown>;
404
+ /** Drop a (kind, platform, role) key family (authoring surfaces call after editing a row). */
405
+ invalidate(kind: string, platform?: string, role?: string): void;
406
+ /** Drop everything — the invalidation-port payload. */
407
+ invalidateAll(): void;
408
+ }
409
+ /**
410
+ * A routed lazy warm row owns a real body, but the per-kind cold fetch has not
411
+ * landed it yet. This is loading, not a compile failure.
412
+ */
413
+ declare function isDbKindComponentBodyPending(resolution: ComponentResolution): boolean;
414
+ /** Build the session cache. One per host app — construct it in the wiring module. */
415
+ declare function createDbKindComponentCache(ports: DbKindComponentCachePorts): DbKindComponentCache;
416
+
417
+ /**
418
+ * DbKindComponentErrorBoundary — the DEFAULT error boundary around a compiled
419
+ * DB kind component (absorbed from matrx-frontend per the C23 retrofit; the
420
+ * package previously shipped "no error capture by design", which left every
421
+ * host to rebuild this class).
422
+ *
423
+ * A user-authored component that throws during render must never crash the
424
+ * surface (chat, notes, admin preview). The boundary catches, renders the
425
+ * fallback (the kind's generic structured viewer — the R6 disposition, never
426
+ * a blank hole), and SCREAMS: a recovery firing means a real bug got past
427
+ * authoring.
428
+ *
429
+ * `resetSignal` (the component's `updated_at`) un-latches the boundary when a
430
+ * NEW component version arrives: an author who fixes a throwing component must
431
+ * see the fix on the next re-render, not stay stuck on the fallback until a
432
+ * full unmount. Without this the error state is sticky for the whole session —
433
+ * the "broke, then magically fixed itself minutes later" class. React error
434
+ * boundaries never self-clear, so a version change is the only safe signal
435
+ * (`hasError` alone can't tell a fixed version from the same broken one).
436
+ *
437
+ * `onCaught` is the scream seam: a host binds its structured render-error
438
+ * capture + durable incident filing (matrx-frontend files a `render_throw`
439
+ * incident so the component's author learns). Bound to nothing, the default is
440
+ * an honest console scream — never silence.
441
+ */
442
+
443
+ interface DbKindComponentErrorBoundaryProps {
444
+ kind: string;
445
+ /** The resolved component's `updated_at`; a change means a new version. */
446
+ resetSignal: string | null;
447
+ fallback: React.ReactNode;
448
+ children: React.ReactNode;
449
+ /**
450
+ * Where the catch lands. A host binds structured capture + incident filing
451
+ * here; the default screams to the console. NOTE for hosts whose console
452
+ * adapter persists `console.error`: bind this (which replaces the default)
453
+ * rather than mirroring the capture through the console twice.
454
+ */
455
+ onCaught?: (error: Error, info: {
456
+ componentStack: string | null;
457
+ }) => void;
458
+ }
459
+ interface State {
460
+ hasError: boolean;
461
+ /**
462
+ * The `resetSignal` seen on the LAST render — tracked every render (not just
463
+ * on error) so that at throw time it already holds the version that threw.
464
+ * `getDerivedStateFromError` cannot read props, so this is how the boundary
465
+ * knows which version to un-latch away from.
466
+ */
467
+ signalAtLastRender: string | null;
468
+ }
469
+ declare class DbKindComponentErrorBoundary extends React.Component<DbKindComponentErrorBoundaryProps, State> {
470
+ constructor(props: DbKindComponentErrorBoundaryProps);
471
+ static getDerivedStateFromError(): Partial<State>;
472
+ static getDerivedStateFromProps(props: DbKindComponentErrorBoundaryProps, state: State): State | null;
473
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;
474
+ render(): React.ReactNode;
475
+ }
868
476
 
869
- export { type ComponentResolution, type ComponentResolutionSource, ComponentResolver, type ComponentResolverOptions, type ComponentRole, type ContentIrErrorReport, type ContentIrErrorReporter, type ContentIrHost, ContentIrRenderProvider, type ContentIrRenderProviderProps, type ContentIrRenderSeams, DB_KIND_COMPONENT_KEY, DelegatedOutput, type DelegatedOutputProps, GENERIC_STRUCTURED_COMPONENT_KEY, type GenericFallbackReason, GenericStructuredView, type GenericStructuredViewProps, IR_PROVISIONAL_KEY, IR_ROUTE_KEY, type IrRenderBlock, type IrRoutableBlock, type IrRouteMarker, type JsonObject, type KindComponentRow, type KindDefinitionSource, KindInstanceRender, type KindInstanceRenderProps, type KindRouteEnv, type KindRouteOptions, type KindVersionSources, NodeOutcomeView, type NodeOutcomeViewProps, type PartialRenderOptions, ProvisionalKindBoundary, ProvisionalKindFrame, type ProvisionalKindRender, RunResultView, type RunResultViewProps, type StructuredValueRenderProps, type SystemComponentEntry, applyIrKindRoute, consoleErrorReporter, envelopeFromPartialKind, isPartialReadyKind, isProvisionalBlock, isRecordValue, kindIsRoutable, kindServerDataFromStoredValue, markKindPartialUnsafe, readIrRouteMarker, resetPartialUnsafeKinds, resetSourcelessDbRowReports, resolveAnnouncedKindLoading, resolveProvisionalKindRender, routeEnvOf, useContentIrHost, useContentIrHostOrNull, useContentIrKindVersion, useKindRouteEnv };
477
+ export { type CompiledDbKindComponent, ComponentResolution, ComponentResolutionSource, ContentIrErrorReporter, ContentIrHost, ContentIrRenderProvider, type ContentIrRenderProviderProps, type DbKindActionResult, type DbKindCompileResult, type DbKindComponentCache, type DbKindComponentCachePorts, type DbKindComponentCompiler, DbKindComponentErrorBoundary, type DbKindComponentErrorBoundaryProps, type DbKindComponentIncident, type DbKindComponentIncidentSink, type DbKindComponentIncidentType, type DbKindComponentRenderProps, DelegatedOutput, type DelegatedOutputProps, GenericStructuredView, type GenericStructuredViewProps, type KindComponentUiOptions, KindDefinitionSource, KindInstanceRender, type KindInstanceRenderProps, KindRouteEnv, type KindVersionSources, NodeOutcomeView, type NodeOutcomeViewProps, ProvisionalKindBoundary, ProvisionalKindFrame, type ResolveKindValue, type RunDbKindAction, RunResultView, type RunResultViewProps, createDbKindComponentCache, isDbKindComponentBodyPending, isRecordValue, kindIsRoutable, useContentIrHost, useContentIrHostOrNull, useContentIrKindVersion, useKindRouteEnv };