import * as React from 'react'; import { C as ComponentResolution } from './component-resolution.types-TrLiqXLk.js'; import { ContentIrErrorReporter } from './host.js'; /** * The DB-component COMPILE CACHE — session-scoped, keyed per winning row * VERSION, with the loud-recovery policy built in. * * This was matrx-frontend's `dbKindComponentCache.ts` (316 lines of compile * caching + invalidation living in one host), absorbed per C22: cache * mechanics, key derivation, the scream-once latch, transform recovery, and * config narrowing are PACKAGE policy — every host was going to need exactly * these lines, bug for bug. What stays host-injected is exactly what is * host-shaped: * * - THE COMPILER ({@link DbKindComponentCompiler}). Compiling or sandboxing * user-authored component source is a security-shaped host decision — the * package never bundles Babel or an allowlist scope. matrx-frontend * injects its shared allowlist compiler (`compileSlotComponent`); a host * with no sandbox simply never constructs a cache. * - The default allowed-imports list (host scope registry). * - Where screams land ({@link ContentIrErrorReporter}) and where durable * incidents go ({@link DbKindComponentIncidentSink}). * - Invalidation TRIGGERS ({@link DbKindComponentCachePorts.registerInvalidation}): * the host wires its invalidation-registry keys (e.g. * `@ai-matrx/kit/invalidation` fired by name when an agent edits a * component row); the cache owns what invalidation MEANS. * * Contract (the db-row component contract, SHAPE_SYSTEM.md): * - `component_source` compiles to a React component receiving * `{ data, kind, config, runAction, itemState?, onResolve?, uiOptions? }` * where `data` is the kind instance value and `itemState` what actions * saved onto this item. * - `props_transform` (optional) compiles to a `(data) => data` function * applied to the value BEFORE it reaches the component. A throwing or * non-compiling transform screams and the untransformed value is used * (never a blank hole). * - `config.allowed_imports` (string[]) narrows the compile scope; absent, * the row gets the host's FULL registered allowlist. * * Cache key: (kind, platform, role, row.updated_at) — one compile per winning * row VERSION. A resolver refresh delivering an edited row (bumped * `updated_at`) re-keys and recompiles naturally; `invalidate` / * `invalidateAll` force-drop keys. Server edits never push to open clients — * the contract is refresh-on-view. */ /** * Settings the MOUNTING UI dictates to a kind component — the standard, * growing arg list every component honors (Arman, 2026-07-23). `selectionMode` * is the first: it tells a component whether the surface wants the user to * pick one value, many, or none (pure display). A component reads what it * understands and ignores the rest; absent = its own default (usually display). */ interface KindComponentUiOptions { selectionMode?: "single" | "multiple" | "none"; [key: string]: unknown; } /** * The return channel: how a kind component hands a chosen value back to the * surface that mounted it (a Kind Request). The mirror of `runAction` * (surface → agent); this is component → surface. Undefined in normal render * (chat/notes) — the component simply doesn't offer selection there. */ type ResolveKindValue = (value: unknown) => void; /** The envelope every kind action resolves to — a skip/failure is never a silent pass. */ type DbKindActionResult = { ok: true; result: unknown; } | { ok: false; error: string; }; /** * The action seam a compiled component receives: `runAction(key, input)` * triggers a registered platform capability (e.g. "trigger_agent"). Always * resolves to an `{ ok }` envelope, never throws — safe to call from imperfect * component code. This is the ONLY side-effect channel a sandboxed component * gets; it reaches no data directly. */ type RunDbKindAction = (key: string, input: unknown) => Promise; /** Props every compiled DB kind component receives. */ interface DbKindComponentRenderProps { /** The kind instance value — post-`props_transform` when one exists. */ data: unknown; /** The kind slug the value belongs to. */ kind: string; /** The resolver row's `config` object, verbatim (narrowed — see {@link DbKindComponentCache.config}). */ config: Record; /** The action seam — see {@link RunDbKindAction}. */ runAction: RunDbKindAction; /** * Present only when the component is mounted inside a Kind Request. Call it * with the user's chosen value to hand that value back to the requesting * surface (which resolves its promise). Undefined in normal render. */ onResolve?: ResolveKindValue; /** Settings the mounting surface dictates (e.g. `{ selectionMode: "single" }`). */ uiOptions?: KindComponentUiOptions; /** * This item's durable state: what `save_item_state` / `run_shortcut` with * `saveAs` wrote onto it (`{}` when nothing yet; survives reload). The host * adds `src` to every saved image ref (`{ file_id, mime_type, width, height }`) * so the component renders ``. */ itemState?: Record; } interface CompiledDbKindComponent { Component: React.ComponentType; /** Compiled `props_transform`, or null when the row declares none. */ transform: ((data: unknown) => unknown) | null; } type DbKindCompileResult = { ok: true; compiled: CompiledDbKindComponent; } | { ok: false; error: string; }; /** The failure modes a browser can observe on a DB kind component. */ type DbKindComponentIncidentType = /** `component_source` did not compile (or produced no component). */ "compile_error" /** The compiled component threw during render (error boundary caught it). */ | "render_throw" /** `props_transform` failed to compile or threw. */ | "transform_error"; /** * One durable render incident — the payload for whoever can actually FIX the * component. A host sink typically files it on the kind's own incident queue * (matrx-frontend: `content_ir.kind_component_incident` via RPC); without a * sink, a broken component seen only by ordinary users is invisible to its * author forever. `data` is the kind instance value — a privacy-conscious sink * reduces it to keys + types before it leaves the browser. */ interface DbKindComponentIncident { kind: string; errorType: DbKindComponentIncidentType; message: string; platform?: string; role?: string; componentKey?: string | null; componentUpdatedAt?: string | null; stack?: string | null; data?: unknown; } type DbKindComponentIncidentSink = (incident: DbKindComponentIncident) => void; /** * THE COMPILER PORT. Matches matrx-frontend's shared allowlist compiler * (`compileSlotComponent`) structurally: source in, `{ Component | error }` * out, never throws. The compiled component is generically typed — the cache * performs the single deliberate narrowing where the generic compiler meets * the kind prop contract. */ type DbKindComponentCompiler = (args: { code: string; allowedImports: string[]; }) => { Component: React.ComponentType> | null; error: string | null; }; interface DbKindComponentCachePorts { /** The host's sandbox compiler — see {@link DbKindComponentCompiler}. */ compile: DbKindComponentCompiler; /** The FULL registered allowlist a row without `config.allowed_imports` gets. */ defaultAllowedImports: () => string[]; /** Where screams land (every recovery path is loud). */ reportError: ContentIrErrorReporter; /** Durable incident sink — optional, but a host without one blinds authors. */ reportIncident?: DbKindComponentIncidentSink; /** Default `kind_component.platform` for this host (default "web"). */ platform?: string; /** * THE INVALIDATION REGISTRATION PORT. Called once at construction with the * cache's `invalidateAll`; the host registers it under its own invalidation * keys (e.g. `@ai-matrx/kit/invalidation`'s name-keyed registry, fired when * an agent's component write completes). The cache owns the mechanics — * what gets dropped, the scream-latch reset; the host owns only WHEN. */ registerInvalidation?: (invalidateAll: () => void) => void; } interface DbKindComponentCache { /** * Compile (once per resolver key per row version) a db-source resolution's * `component_source` + optional `props_transform`. Synchronous — the caller * (a lazily-loaded Impl) already paid the compiler chunk. */ getOrCompile(kind: string, resolution: ComponentResolution, platform?: string, role?: string): DbKindCompileResult; /** * Apply the row's transform to the kind value. Loud on throw, never fatal — * the untransformed value comes back so content is never hidden. */ applyPropsTransform(kind: string, compiled: CompiledDbKindComponent, value: unknown): unknown; /** * THE CONFIG BOUNDARY. `ComponentResolution.config` is typed * `Record` — deliberately agnostic about a host's JSONB * interior. This narrows at runtime (plain object → itself; anything else → * scream + empty config) rather than asserting: a row whose `config` is not * an object is a malformed `kind_component` row, and the component still * renders rather than crashing. */ config(config: unknown, kind: string): Record; /** Drop a (kind, platform, role) key family (authoring surfaces call after editing a row). */ invalidate(kind: string, platform?: string, role?: string): void; /** Drop everything — the invalidation-port payload. */ invalidateAll(): void; } /** * A routed lazy warm row owns a real body, but the per-kind cold fetch has not * landed it yet. This is loading, not a compile failure. */ declare function isDbKindComponentBodyPending(resolution: ComponentResolution): boolean; /** Build the session cache. One per host app — construct it in the wiring module. */ declare function createDbKindComponentCache(ports: DbKindComponentCachePorts): DbKindComponentCache; /** * DbKindComponentErrorBoundary — the DEFAULT error boundary around a compiled * DB kind component (absorbed from matrx-frontend per the C23 retrofit; the * package previously shipped "no error capture by design", which left every * host to rebuild this class). * * A user-authored component that throws during render must never crash the * surface (chat, notes, admin preview). The boundary catches, renders the * fallback (the kind's generic structured viewer — the R6 disposition, never * a blank hole), and SCREAMS: a recovery firing means a real bug got past * authoring. * * `resetSignal` (the component's `updated_at`) un-latches the boundary when a * NEW component version arrives: an author who fixes a throwing component must * see the fix on the next re-render, not stay stuck on the fallback until a * full unmount. Without this the error state is sticky for the whole session — * the "broke, then magically fixed itself minutes later" class. React error * boundaries never self-clear, so a version change is the only safe signal * (`hasError` alone can't tell a fixed version from the same broken one). * * `onCaught` is the scream seam: a host binds its structured render-error * capture + durable incident filing (matrx-frontend files a `render_throw` * incident so the component's author learns). Bound to nothing, the default is * an honest console scream — never silence. */ interface DbKindComponentErrorBoundaryProps { kind: string; /** The resolved component's `updated_at`; a change means a new version. */ resetSignal: string | null; fallback: React.ReactNode; children: React.ReactNode; /** * Where the catch lands. A host binds structured capture + incident filing * here; the default screams to the console. NOTE for hosts whose console * adapter persists `console.error`: bind this (which replaces the default) * rather than mirroring the capture through the console twice. */ onCaught?: (error: Error, info: { componentStack: string | null; }) => void; } interface State { hasError: boolean; /** * The `resetSignal` seen on the LAST render — tracked every render (not just * on error) so that at throw time it already holds the version that threw. * `getDerivedStateFromError` cannot read props, so this is how the boundary * knows which version to un-latch away from. */ signalAtLastRender: string | null; } declare class DbKindComponentErrorBoundary extends React.Component { constructor(props: DbKindComponentErrorBoundaryProps); static getDerivedStateFromError(): Partial; static getDerivedStateFromProps(props: DbKindComponentErrorBoundaryProps, state: State): State | null; componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void; render(): React.ReactNode; } /** * Kind components call Actions (Applets CONTRACTS §6/§7). * * A compiled kind component's ONE side-effect channel is `runAction(key, * input)` (see {@link RunDbKindAction}). This binds that channel to a surface's * Actions — the one registry (`@ai-matrx/alchemy`'s `SurfacePort.runAction`, * whose runner applies each Action's policy and `triggeredBy`). A host mounts a * surface (an Applet frame mounts `applets/`), then hands every kind it * renders `runKindActionsThroughSurface(port)`. * * Package policy, so every host gets it bug for bug: * - NEVER throws: a refusal, an unknown Action, a port that rejects — all * resolve `{ ok: false, error }` with the system's own sentence (and its * remedy, when the refusal names one), so imperfect component code keeps * rendering. * - ONE run in flight per Action and target: a double-click or a re-render * storm cannot run an agent, a write or a server action twice. The key is * the Action name plus `input.target` / `input.id` when the input names one, * so one slow Action never locks every other. * - The caller is a PERSON by default: a kind component acts on a click in a * person's page. A host that runs kinds on an agent's behalf passes `by`. * * Typed structurally over the port so this package does not depend on alchemy. */ type KindActionCaller = "person" | "agent" | "applet" | "automation"; /** The one method of alchemy's `SurfacePort` this needs. */ interface KindActionSurface { runAction(name: string, input: unknown, by: KindActionCaller): Promise<{ ok: true; data: unknown; } | { ok: false; error: { message: string; remedy?: string; }; }>; } interface KindActionsThroughSurfaceOptions { /** Who is acting (default "person"). */ by?: KindActionCaller; } declare function runKindActionsThroughSurface(surface: KindActionSurface, options?: KindActionsThroughSurfaceOptions): RunDbKindAction; export { DbKindComponentErrorBoundary, createDbKindComponentCache, isDbKindComponentBodyPending, runKindActionsThroughSurface }; export type { CompiledDbKindComponent, DbKindActionResult, DbKindCompileResult, DbKindComponentCache, DbKindComponentCachePorts, DbKindComponentCompiler, DbKindComponentErrorBoundaryProps, DbKindComponentIncident, DbKindComponentIncidentSink, DbKindComponentIncidentType, DbKindComponentRenderProps, KindActionCaller, KindActionSurface, KindActionsThroughSurfaceOptions, KindComponentUiOptions, ResolveKindValue, RunDbKindAction };