{"version":3,"sources":["../db-component.ts","../db-component/db-kind-component-cache.ts","../db-component/DbKindComponentErrorBoundary.tsx","../db-component/kind-actions-through-surface.ts"],"sourcesContent":["\"use client\";\n\n/**\n * `@ai-matrx/content-ir/db-component` — rendering DB-authored kind\n * components (`content_ir.kind_component`, `source='db'`): the session compile\n * cache with its invalidation port, the kind prop contract, and the default\n * error boundary. The COMPILER itself stays a host injection (security-shaped\n * — see `db-component/db-kind-component-cache.ts`). Client-only; the entry is\n * stamped \"use client\".\n */\nexport * from \"./db-component/db-kind-component-cache\";\nexport * from \"./db-component/DbKindComponentErrorBoundary\";\nexport * from \"./db-component/kind-actions-through-surface\";\n","/**\n * The DB-component COMPILE CACHE — session-scoped, keyed per winning row\n * VERSION, with the loud-recovery policy built in.\n *\n * This was matrx-frontend's `dbKindComponentCache.ts` (316 lines of compile\n * caching + invalidation living in one host), absorbed per C22: cache\n * mechanics, key derivation, the scream-once latch, transform recovery, and\n * config narrowing are PACKAGE policy — every host was going to need exactly\n * these lines, bug for bug. What stays host-injected is exactly what is\n * host-shaped:\n *\n *  - THE COMPILER ({@link DbKindComponentCompiler}). Compiling or sandboxing\n *    user-authored component source is a security-shaped host decision — the\n *    package never bundles Babel or an allowlist scope. matrx-frontend\n *    injects its shared allowlist compiler (`compileSlotComponent`); a host\n *    with no sandbox simply never constructs a cache.\n *  - The default allowed-imports list (host scope registry).\n *  - Where screams land ({@link ContentIrErrorReporter}) and where durable\n *    incidents go ({@link DbKindComponentIncidentSink}).\n *  - Invalidation TRIGGERS ({@link DbKindComponentCachePorts.registerInvalidation}):\n *    the host wires its invalidation-registry keys (e.g.\n *    `@ai-matrx/kit/invalidation` fired by name when an agent edits a\n *    component row); the cache owns what invalidation MEANS.\n *\n * Contract (the db-row component contract, SHAPE_SYSTEM.md):\n *  - `component_source` compiles to a React component receiving\n *    `{ data, kind, config, runAction, itemState?, onResolve?, uiOptions? }`\n *    where `data` is the kind instance value and `itemState` what actions\n *    saved onto this item.\n *  - `props_transform` (optional) compiles to a `(data) => data` function\n *    applied to the value BEFORE it reaches the component. A throwing or\n *    non-compiling transform screams and the untransformed value is used\n *    (never a blank hole).\n *  - `config.allowed_imports` (string[]) narrows the compile scope; absent,\n *    the row gets the host's FULL registered allowlist.\n *\n * Cache key: (kind, platform, role, row.updated_at) — one compile per winning\n * row VERSION. A resolver refresh delivering an edited row (bumped\n * `updated_at`) re-keys and recompiles naturally; `invalidate` /\n * `invalidateAll` force-drop keys. Server edits never push to open clients —\n * the contract is refresh-on-view.\n */\n\nimport type * as React from \"react\";\n\nimport type { ContentIrErrorReporter } from \"../host/error-report\";\nimport type { ComponentResolution } from \"../resolver/component-resolution.types\";\n\n/**\n * Settings the MOUNTING UI dictates to a kind component — the standard,\n * growing arg list every component honors (Arman, 2026-07-23). `selectionMode`\n * is the first: it tells a component whether the surface wants the user to\n * pick one value, many, or none (pure display). A component reads what it\n * understands and ignores the rest; absent = its own default (usually display).\n */\nexport interface KindComponentUiOptions {\n  selectionMode?: \"single\" | \"multiple\" | \"none\";\n  [key: string]: unknown;\n}\n\n/**\n * The return channel: how a kind component hands a chosen value back to the\n * surface that mounted it (a Kind Request). The mirror of `runAction`\n * (surface → agent); this is component → surface. Undefined in normal render\n * (chat/notes) — the component simply doesn't offer selection there.\n */\nexport type ResolveKindValue = (value: unknown) => void;\n\n/** The envelope every kind action resolves to — a skip/failure is never a silent pass. */\nexport type DbKindActionResult =\n  | { ok: true; result: unknown }\n  | { ok: false; error: string };\n\n/**\n * The action seam a compiled component receives: `runAction(key, input)`\n * triggers a registered platform capability (e.g. \"trigger_agent\"). Always\n * resolves to an `{ ok }` envelope, never throws — safe to call from imperfect\n * component code. This is the ONLY side-effect channel a sandboxed component\n * gets; it reaches no data directly.\n */\nexport type RunDbKindAction = (\n  key: string,\n  input: unknown,\n) => Promise<DbKindActionResult>;\n\n/** Props every compiled DB kind component receives. */\nexport interface DbKindComponentRenderProps {\n  /** The kind instance value — post-`props_transform` when one exists. */\n  data: unknown;\n  /** The kind slug the value belongs to. */\n  kind: string;\n  /** The resolver row's `config` object, verbatim (narrowed — see {@link DbKindComponentCache.config}). */\n  config: Record<string, unknown>;\n  /** The action seam — see {@link RunDbKindAction}. */\n  runAction: RunDbKindAction;\n  /**\n   * Present only when the component is mounted inside a Kind Request. Call it\n   * with the user's chosen value to hand that value back to the requesting\n   * surface (which resolves its promise). Undefined in normal render.\n   */\n  onResolve?: ResolveKindValue;\n  /** Settings the mounting surface dictates (e.g. `{ selectionMode: \"single\" }`). */\n  uiOptions?: KindComponentUiOptions;\n  /**\n   * This item's durable state: what `save_item_state` / `run_shortcut` with\n   * `saveAs` wrote onto it (`{}` when nothing yet; survives reload). The host\n   * adds `src` to every saved image ref (`{ file_id, mime_type, width, height }`)\n   * so the component renders `<img src={itemState.key.src}>`.\n   */\n  itemState?: Record<string, unknown>;\n}\n\nexport interface CompiledDbKindComponent {\n  Component: React.ComponentType<DbKindComponentRenderProps>;\n  /** Compiled `props_transform`, or null when the row declares none. */\n  transform: ((data: unknown) => unknown) | null;\n}\n\nexport type DbKindCompileResult =\n  | { ok: true; compiled: CompiledDbKindComponent }\n  | { ok: false; error: string };\n\n/** The failure modes a browser can observe on a DB kind component. */\nexport type DbKindComponentIncidentType =\n  /** `component_source` did not compile (or produced no component). */\n  | \"compile_error\"\n  /** The compiled component threw during render (error boundary caught it). */\n  | \"render_throw\"\n  /** `props_transform` failed to compile or threw. */\n  | \"transform_error\";\n\n/**\n * One durable render incident — the payload for whoever can actually FIX the\n * component. A host sink typically files it on the kind's own incident queue\n * (matrx-frontend: `content_ir.kind_component_incident` via RPC); without a\n * sink, a broken component seen only by ordinary users is invisible to its\n * author forever. `data` is the kind instance value — a privacy-conscious sink\n * reduces it to keys + types before it leaves the browser.\n */\nexport interface DbKindComponentIncident {\n  kind: string;\n  errorType: DbKindComponentIncidentType;\n  message: string;\n  platform?: string;\n  role?: string;\n  componentKey?: string | null;\n  componentUpdatedAt?: string | null;\n  stack?: string | null;\n  data?: unknown;\n}\n\nexport type DbKindComponentIncidentSink = (\n  incident: DbKindComponentIncident,\n) => void;\n\n/**\n * THE COMPILER PORT. Matches matrx-frontend's shared allowlist compiler\n * (`compileSlotComponent`) structurally: source in, `{ Component | error }`\n * out, never throws. The compiled component is generically typed — the cache\n * performs the single deliberate narrowing where the generic compiler meets\n * the kind prop contract.\n */\nexport type DbKindComponentCompiler = (args: {\n  code: string;\n  allowedImports: string[];\n}) => {\n  Component: React.ComponentType<Record<string, unknown>> | null;\n  error: string | null;\n};\n\nexport interface DbKindComponentCachePorts {\n  /** The host's sandbox compiler — see {@link DbKindComponentCompiler}. */\n  compile: DbKindComponentCompiler;\n  /** The FULL registered allowlist a row without `config.allowed_imports` gets. */\n  defaultAllowedImports: () => string[];\n  /** Where screams land (every recovery path is loud). */\n  reportError: ContentIrErrorReporter;\n  /** Durable incident sink — optional, but a host without one blinds authors. */\n  reportIncident?: DbKindComponentIncidentSink;\n  /** Default `kind_component.platform` for this host (default \"web\"). */\n  platform?: string;\n  /**\n   * THE INVALIDATION REGISTRATION PORT. Called once at construction with the\n   * cache's `invalidateAll`; the host registers it under its own invalidation\n   * keys (e.g. `@ai-matrx/kit/invalidation`'s name-keyed registry, fired when\n   * an agent's component write completes). The cache owns the mechanics —\n   * what gets dropped, the scream-latch reset; the host owns only WHEN.\n   */\n  registerInvalidation?: (invalidateAll: () => void) => void;\n}\n\nexport interface DbKindComponentCache {\n  /**\n   * Compile (once per resolver key per row version) a db-source resolution's\n   * `component_source` + optional `props_transform`. Synchronous — the caller\n   * (a lazily-loaded Impl) already paid the compiler chunk.\n   */\n  getOrCompile(\n    kind: string,\n    resolution: ComponentResolution,\n    platform?: string,\n    role?: string,\n  ): DbKindCompileResult;\n  /**\n   * Apply the row's transform to the kind value. Loud on throw, never fatal —\n   * the untransformed value comes back so content is never hidden.\n   */\n  applyPropsTransform(\n    kind: string,\n    compiled: CompiledDbKindComponent,\n    value: unknown,\n  ): unknown;\n  /**\n   * THE CONFIG BOUNDARY. `ComponentResolution.config` is typed\n   * `Record<string, unknown>` — deliberately agnostic about a host's JSONB\n   * interior. This narrows at runtime (plain object → itself; anything else →\n   * scream + empty config) rather than asserting: a row whose `config` is not\n   * an object is a malformed `kind_component` row, and the component still\n   * renders rather than crashing.\n   */\n  config(config: unknown, kind: string): Record<string, unknown>;\n  /** Drop a (kind, platform, role) key family (authoring surfaces call after editing a row). */\n  invalidate(kind: string, platform?: string, role?: string): void;\n  /** Drop everything — the invalidation-port payload. */\n  invalidateAll(): void;\n}\n\n/**\n * A routed lazy warm row owns a real body, but the per-kind cold fetch has not\n * landed it yet. This is loading, not a compile failure.\n */\nexport function isDbKindComponentBodyPending(\n  resolution: ComponentResolution,\n): boolean {\n  return resolution.hasComponentSource && resolution.componentSource === null;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n  return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Build the session cache. One per host app — construct it in the wiring module. */\nexport function createDbKindComponentCache(\n  ports: DbKindComponentCachePorts,\n): DbKindComponentCache {\n  const cache = new Map<string, DbKindCompileResult>();\n  const screamedKeys = new Set<string>();\n  const defaultPlatform = ports.platform ?? \"web\";\n\n  function cacheKey(\n    kind: string,\n    platform: string,\n    role: string,\n    updatedAt: string | null,\n    rowIdentity: string,\n  ): string {\n    // `updatedAt` (the winning row's freshness) is part of the key: a refresh\n    // that delivers an edited row (bumped updated_at) recompiles automatically\n    // instead of serving the stale compile for the rest of the session.\n    // The ROW IDENTITY is too (shape layers): two rows of one key with equal\n    // `updated_at` — a layered row and the shared row, or rows from one\n    // seeding transaction — must never share a compiled body, and a viewer's\n    // layered body must never be served for a resolution of any other row.\n    // Appended AFTER the (kind, platform, role) prefix so `invalidate` still\n    // drops the whole family by prefix.\n    return `${kind}${platform}${role}${updatedAt ?? \"\"}${rowIdentity}`;\n  }\n\n  /** `layer:<id>` for an overlay answer, `row:<id>` for an identified db row, \"\" otherwise. */\n  function rowIdentityOf(resolution: ComponentResolution): string {\n    if (resolution.layer) return `layer:${resolution.layer.rowId}`;\n    return resolution.rowId ? `row:${resolution.rowId}` : \"\";\n  }\n\n  /**\n   * Loud recovery: one console scream per key + a structured report on every\n   * attempt + a durable incident for whoever can fix the component.\n   */\n  function screamCompileFailure(\n    key: string,\n    kind: string,\n    error: string,\n    resolution: ComponentResolution,\n    platform: string,\n    role: string,\n  ): void {\n    const message = `[content-ir] DB kind component for \"${kind}\" failed to compile — rendering the generic structured viewer instead: ${error}`;\n    if (!screamedKeys.has(key)) {\n      screamedKeys.add(key);\n      console.error(message);\n    }\n    ports.reportError({ source: \"content-ir\", message, raw: { kind, error } });\n    // A LAYERED body (someone's own / their organization's view) is never\n    // filed against the shared kind: its failure is not the kind owner's to\n    // fix, and must never open or close the shared kind's incident.\n    if (resolution.layer) return;\n    ports.reportIncident?.({\n      kind,\n      errorType: \"compile_error\",\n      message,\n      platform,\n      role,\n      componentKey: resolution.componentKey,\n      componentUpdatedAt: resolution.updatedAt,\n    });\n  }\n\n  function config(value: unknown, kind: string): Record<string, unknown> {\n    if (isPlainObject(value)) return value;\n    if (value === null || value === undefined) return {};\n    const message = `[content-ir] kind_component.config for \"${kind}\" is not a JSON object (${typeof value}) — rendering with an empty config.`;\n    console.error(message);\n    ports.reportError({ source: \"content-ir\", message, raw: { kind } });\n    return {};\n  }\n\n  function resolveAllowedImports(rowConfig: Record<string, unknown>): string[] {\n    const declared = rowConfig.allowed_imports;\n    if (\n      Array.isArray(declared) &&\n      declared.every((entry): entry is string => typeof entry === \"string\")\n    ) {\n      return declared;\n    }\n    return ports.defaultAllowedImports();\n  }\n\n  function getOrCompile(\n    kind: string,\n    resolution: ComponentResolution,\n    platform: string = defaultPlatform,\n    role = \"output\",\n  ): DbKindCompileResult {\n    const key = cacheKey(\n      kind,\n      platform,\n      role,\n      resolution.updatedAt,\n      rowIdentityOf(resolution),\n    );\n    const cached = cache.get(key);\n    if (cached) return cached;\n\n    const source = resolution.componentSource;\n    if (!source || !source.trim()) {\n      const result: DbKindCompileResult = {\n        ok: false,\n        error: \"db-source resolution has no component_source\",\n      };\n      screamCompileFailure(key, kind, result.error, resolution, platform, role);\n      cache.set(key, result);\n      return result;\n    }\n\n    const allowedImports = resolveAllowedImports(\n      config(resolution.config, kind),\n    );\n\n    const { Component, error } = ports.compile({ code: source, allowedImports });\n    if (!Component || error) {\n      const result: DbKindCompileResult = {\n        ok: false,\n        error: error ?? \"compile produced no component\",\n      };\n      screamCompileFailure(key, kind, result.error, resolution, platform, role);\n      cache.set(key, result);\n      return result;\n    }\n\n    // The optional props transform is its own tiny compile — a `(data) => data`\n    // function (mirroring tool_ui's header_subtitle_code pattern). A broken\n    // transform is LOUD but never fatal: the component still renders, fed the\n    // untransformed value.\n    let transform: ((data: unknown) => unknown) | null = null;\n    if (resolution.propsTransform && resolution.propsTransform.trim()) {\n      const { Component: transformFn, error: transformError } = ports.compile({\n        code: resolution.propsTransform,\n        allowedImports: [],\n      });\n      if (typeof transformFn === \"function\" && !transformError) {\n        transform = transformFn as unknown as (data: unknown) => unknown;\n      } else {\n        const message = `[content-ir] props_transform for kind \"${kind}\" failed to compile — value passes through untransformed: ${transformError ?? \"no function produced\"}`;\n        console.error(message);\n        ports.reportError({\n          source: \"content-ir\",\n          message,\n          raw: { kind, error: transformError },\n        });\n        if (!resolution.layer) ports.reportIncident?.({\n          kind,\n          errorType: \"transform_error\",\n          message,\n          platform,\n          role,\n          componentKey: resolution.componentKey,\n          componentUpdatedAt: resolution.updatedAt,\n        });\n      }\n    }\n\n    const result: DbKindCompileResult = {\n      ok: true,\n      compiled: {\n        // The injected compiler types components as\n        // ComponentType<Record<string, unknown>>; the callsite always passes\n        // DbKindComponentRenderProps — the single deliberate narrowing where\n        // the generic compiler meets the kind contract.\n        Component:\n          Component as unknown as React.ComponentType<DbKindComponentRenderProps>,\n        transform,\n      },\n    };\n    cache.set(key, result);\n    return result;\n  }\n\n  function applyPropsTransform(\n    kind: string,\n    compiled: CompiledDbKindComponent,\n    value: unknown,\n  ): unknown {\n    if (!compiled.transform) return value;\n    try {\n      return compiled.transform(value);\n    } catch (error) {\n      const message = `[content-ir] props_transform for kind \"${kind}\" threw — using the untransformed value: ${\n        error instanceof Error ? error.message : String(error)\n      }`;\n      console.error(message);\n      ports.reportError({ source: \"content-ir\", message, raw: { kind } });\n      ports.reportIncident?.({\n        kind,\n        errorType: \"transform_error\",\n        message,\n        stack: error instanceof Error ? (error.stack ?? null) : null,\n        data: value,\n      });\n      return value;\n    }\n  }\n\n  function invalidate(\n    kind: string,\n    platform: string = defaultPlatform,\n    role = \"output\",\n  ): void {\n    const prefix = `${kind}${platform}${role}`;\n    for (const key of [...cache.keys()]) {\n      if (key.startsWith(prefix)) cache.delete(key);\n    }\n    for (const key of [...screamedKeys]) {\n      if (key.startsWith(prefix)) screamedKeys.delete(key);\n    }\n  }\n\n  function invalidateAll(): void {\n    cache.clear();\n    screamedKeys.clear();\n  }\n\n  const api: DbKindComponentCache = {\n    getOrCompile,\n    applyPropsTransform,\n    config,\n    invalidate,\n    invalidateAll,\n  };\n\n  ports.registerInvalidation?.(() => invalidateAll());\n\n  return api;\n}\n","\"use client\";\n\n/**\n * DbKindComponentErrorBoundary — the DEFAULT error boundary around a compiled\n * DB kind component (absorbed from matrx-frontend per the C23 retrofit; the\n * package previously shipped \"no error capture by design\", which left every\n * host to rebuild this class).\n *\n * A user-authored component that throws during render must never crash the\n * surface (chat, notes, admin preview). The boundary catches, renders the\n * fallback (the kind's generic structured viewer — the R6 disposition, never\n * a blank hole), and SCREAMS: a recovery firing means a real bug got past\n * authoring.\n *\n * `resetSignal` (the component's `updated_at`) un-latches the boundary when a\n * NEW component version arrives: an author who fixes a throwing component must\n * see the fix on the next re-render, not stay stuck on the fallback until a\n * full unmount. Without this the error state is sticky for the whole session —\n * the \"broke, then magically fixed itself minutes later\" class. React error\n * boundaries never self-clear, so a version change is the only safe signal\n * (`hasError` alone can't tell a fixed version from the same broken one).\n *\n * `onCaught` is the scream seam: a host binds its structured render-error\n * capture + durable incident filing (matrx-frontend files a `render_throw`\n * incident so the component's author learns). Bound to nothing, the default is\n * an honest console scream — never silence.\n */\nimport * as React from \"react\";\n\nexport interface DbKindComponentErrorBoundaryProps {\n  kind: string;\n  /** The resolved component's `updated_at`; a change means a new version. */\n  resetSignal: string | null;\n  fallback: React.ReactNode;\n  children: React.ReactNode;\n  /**\n   * Where the catch lands. A host binds structured capture + incident filing\n   * here; the default screams to the console. NOTE for hosts whose console\n   * adapter persists `console.error`: bind this (which replaces the default)\n   * rather than mirroring the capture through the console twice.\n   */\n  onCaught?: (\n    error: Error,\n    info: { componentStack: string | null },\n  ) => void;\n}\n\ninterface State {\n  hasError: boolean;\n  /**\n   * The `resetSignal` seen on the LAST render — tracked every render (not just\n   * on error) so that at throw time it already holds the version that threw.\n   * `getDerivedStateFromError` cannot read props, so this is how the boundary\n   * knows which version to un-latch away from.\n   */\n  signalAtLastRender: string | null;\n}\n\nexport class DbKindComponentErrorBoundary extends React.Component<\n  DbKindComponentErrorBoundaryProps,\n  State\n> {\n  constructor(props: DbKindComponentErrorBoundaryProps) {\n    super(props);\n    this.state = { hasError: false, signalAtLastRender: props.resetSignal };\n  }\n\n  static getDerivedStateFromError(): Partial<State> {\n    return { hasError: true };\n  }\n\n  static getDerivedStateFromProps(\n    props: DbKindComponentErrorBoundaryProps,\n    state: State,\n  ): State | null {\n    if (props.resetSignal === state.signalAtLastRender) return null;\n    // The version changed. If we were latched on the old version, un-latch so\n    // the new (hopefully fixed) component gets a fresh render attempt; either\n    // way, record the new signal as the one now rendering.\n    return { hasError: false, signalAtLastRender: props.resetSignal };\n  }\n\n  override componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n    const info = { componentStack: errorInfo.componentStack ?? null };\n    if (this.props.onCaught) {\n      this.props.onCaught(error, info);\n      return;\n    }\n    // The honest default when a host binds nothing: never silent.\n    console.error(\n      `[content-ir] DB kind component for \"${this.props.kind}\" threw during render — showing the fallback:`,\n      error,\n    );\n  }\n\n  override render(): React.ReactNode {\n    if (this.state.hasError) return this.props.fallback;\n    return this.props.children;\n  }\n}\n","/**\n * Kind components call Actions (Applets CONTRACTS §6/§7).\n *\n * A compiled kind component's ONE side-effect channel is `runAction(key,\n * input)` (see {@link RunDbKindAction}). This binds that channel to a surface's\n * Actions — the one registry (`@ai-matrx/alchemy`'s `SurfacePort.runAction`,\n * whose runner applies each Action's policy and `triggeredBy`). A host mounts a\n * surface (an Applet frame mounts `applets/<id>`), then hands every kind it\n * renders `runKindActionsThroughSurface(port)`.\n *\n * Package policy, so every host gets it bug for bug:\n *  - NEVER throws: a refusal, an unknown Action, a port that rejects — all\n *    resolve `{ ok: false, error }` with the system's own sentence (and its\n *    remedy, when the refusal names one), so imperfect component code keeps\n *    rendering.\n *  - ONE run in flight per Action and target: a double-click or a re-render\n *    storm cannot run an agent, a write or a server action twice. The key is\n *    the Action name plus `input.target` / `input.id` when the input names one,\n *    so one slow Action never locks every other.\n *  - The caller is a PERSON by default: a kind component acts on a click in a\n *    person's page. A host that runs kinds on an agent's behalf passes `by`.\n *\n * Typed structurally over the port so this package does not depend on alchemy.\n */\nimport type { DbKindActionResult, RunDbKindAction } from \"./db-kind-component-cache\";\n\nexport type KindActionCaller = \"person\" | \"agent\" | \"applet\" | \"automation\";\n\n/** The one method of alchemy's `SurfacePort` this needs. */\nexport interface KindActionSurface {\n  runAction(\n    name: string,\n    input: unknown,\n    by: KindActionCaller,\n  ): Promise<{ ok: true; data: unknown } | { ok: false; error: { message: string; remedy?: string } }>;\n}\n\nexport interface KindActionsThroughSurfaceOptions {\n  /** Who is acting (default \"person\"). */\n  by?: KindActionCaller;\n}\n\nfunction inFlightKey(name: string, input: unknown): string {\n  if (input && typeof input === \"object\") {\n    const rec = input as { target?: unknown; id?: unknown };\n    if (typeof rec.target === \"string\" && rec.target) return `${name}::${rec.target}`;\n    if (typeof rec.id === \"string\" && rec.id) return `${name}::${rec.id}`;\n  }\n  return name;\n}\n\nexport function runKindActionsThroughSurface(\n  surface: KindActionSurface,\n  options: KindActionsThroughSurfaceOptions = {},\n): RunDbKindAction {\n  const by = options.by ?? \"person\";\n  const inFlight = new Set<string>();\n  return async (key: string, input: unknown): Promise<DbKindActionResult> => {\n    if (typeof key !== \"string\" || !key.trim()) {\n      return { ok: false, error: \"This component asked to run an Action without naming one.\" };\n    }\n    const flight = inFlightKey(key, input);\n    if (inFlight.has(flight)) {\n      return { ok: false, error: `\"${key}\" is already running. Wait for it to finish.` };\n    }\n    inFlight.add(flight);\n    try {\n      const result = await surface.runAction(key, input, by);\n      if (result.ok) return { ok: true, result: result.data };\n      const { message, remedy } = result.error;\n      return { ok: false, error: remedy ? `${message} ${remedy}` : message };\n    } catch (err) {\n      return {\n        ok: false,\n        error: `\"${key}\" could not run: ${err instanceof Error ? err.message : String(err)}`,\n      };\n    } finally {\n      inFlight.delete(flight);\n    }\n  };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACuOO,SAAS,6BACd,YACS;AACT,SAAO,WAAW,sBAAsB,WAAW,oBAAoB;AACzE;AAEA,SAAS,cAAc,OAAkD;AACvE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAGO,SAAS,2BACd,OACsB;AACtB,QAAM,QAAQ,oBAAI,IAAiC;AACnD,QAAM,eAAe,oBAAI,IAAY;AACrC,QAAM,kBAAkB,MAAM,YAAY;AAE1C,WAAS,SACP,MACA,UACA,MACA,WACA,aACQ;AAUR,WAAO,GAAG,IAAI,GAAG,QAAQ,GAAG,IAAI,GAAG,aAAa,EAAE,GAAG,WAAW;AAAA,EAClE;AAGA,WAAS,cAAc,YAAyC;AAC9D,QAAI,WAAW,MAAO,QAAO,SAAS,WAAW,MAAM,KAAK;AAC5D,WAAO,WAAW,QAAQ,OAAO,WAAW,KAAK,KAAK;AAAA,EACxD;AAMA,WAAS,qBACP,KACA,MACA,OACA,YACA,UACA,MACM;AACN,UAAM,UAAU,uCAAuC,IAAI,+EAA0E,KAAK;AAC1I,QAAI,CAAC,aAAa,IAAI,GAAG,GAAG;AAC1B,mBAAa,IAAI,GAAG;AACpB,cAAQ,MAAM,OAAO;AAAA,IACvB;AACA,UAAM,YAAY,EAAE,QAAQ,cAAc,SAAS,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC;AAIzE,QAAI,WAAW,MAAO;AACtB,UAAM,iBAAiB;AAAA,MACrB;AAAA,MACA,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc,WAAW;AAAA,MACzB,oBAAoB,WAAW;AAAA,IACjC,CAAC;AAAA,EACH;AAEA,WAAS,OAAO,OAAgB,MAAuC;AACrE,QAAI,cAAc,KAAK,EAAG,QAAO;AACjC,QAAI,UAAU,QAAQ,UAAU,OAAW,QAAO,CAAC;AACnD,UAAM,UAAU,2CAA2C,IAAI,2BAA2B,OAAO,KAAK;AACtG,YAAQ,MAAM,OAAO;AACrB,UAAM,YAAY,EAAE,QAAQ,cAAc,SAAS,KAAK,EAAE,KAAK,EAAE,CAAC;AAClE,WAAO,CAAC;AAAA,EACV;AAEA,WAAS,sBAAsB,WAA8C;AAC3E,UAAM,WAAW,UAAU;AAC3B,QACE,MAAM,QAAQ,QAAQ,KACtB,SAAS,MAAM,CAAC,UAA2B,OAAO,UAAU,QAAQ,GACpE;AACA,aAAO;AAAA,IACT;AACA,WAAO,MAAM,sBAAsB;AAAA,EACrC;AAEA,WAAS,aACP,MACA,YACA,WAAmB,iBACnB,OAAO,UACc;AACrB,UAAM,MAAM;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,cAAc,UAAU;AAAA,IAC1B;AACA,UAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,QAAI,OAAQ,QAAO;AAEnB,UAAM,SAAS,WAAW;AAC1B,QAAI,CAAC,UAAU,CAAC,OAAO,KAAK,GAAG;AAC7B,YAAMA,UAA8B;AAAA,QAClC,IAAI;AAAA,QACJ,OAAO;AAAA,MACT;AACA,2BAAqB,KAAK,MAAMA,QAAO,OAAO,YAAY,UAAU,IAAI;AACxE,YAAM,IAAI,KAAKA,OAAM;AACrB,aAAOA;AAAA,IACT;AAEA,UAAM,iBAAiB;AAAA,MACrB,OAAO,WAAW,QAAQ,IAAI;AAAA,IAChC;AAEA,UAAM,EAAE,WAAAC,YAAW,MAAM,IAAI,MAAM,QAAQ,EAAE,MAAM,QAAQ,eAAe,CAAC;AAC3E,QAAI,CAACA,cAAa,OAAO;AACvB,YAAMD,UAA8B;AAAA,QAClC,IAAI;AAAA,QACJ,OAAO,SAAS;AAAA,MAClB;AACA,2BAAqB,KAAK,MAAMA,QAAO,OAAO,YAAY,UAAU,IAAI;AACxE,YAAM,IAAI,KAAKA,OAAM;AACrB,aAAOA;AAAA,IACT;AAMA,QAAI,YAAiD;AACrD,QAAI,WAAW,kBAAkB,WAAW,eAAe,KAAK,GAAG;AACjE,YAAM,EAAE,WAAW,aAAa,OAAO,eAAe,IAAI,MAAM,QAAQ;AAAA,QACtE,MAAM,WAAW;AAAA,QACjB,gBAAgB,CAAC;AAAA,MACnB,CAAC;AACD,UAAI,OAAO,gBAAgB,cAAc,CAAC,gBAAgB;AACxD,oBAAY;AAAA,MACd,OAAO;AACL,cAAM,UAAU,0CAA0C,IAAI,kEAA6D,kBAAkB,sBAAsB;AACnK,gBAAQ,MAAM,OAAO;AACrB,cAAM,YAAY;AAAA,UAChB,QAAQ;AAAA,UACR;AAAA,UACA,KAAK,EAAE,MAAM,OAAO,eAAe;AAAA,QACrC,CAAC;AACD,YAAI,CAAC,WAAW,MAAO,OAAM,iBAAiB;AAAA,UAC5C;AAAA,UACA,WAAW;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA,cAAc,WAAW;AAAA,UACzB,oBAAoB,WAAW;AAAA,QACjC,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,SAA8B;AAAA,MAClC,IAAI;AAAA,MACJ,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,QAKR,WACEC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,IAAI,KAAK,MAAM;AACrB,WAAO;AAAA,EACT;AAEA,WAAS,oBACP,MACA,UACA,OACS;AACT,QAAI,CAAC,SAAS,UAAW,QAAO;AAChC,QAAI;AACF,aAAO,SAAS,UAAU,KAAK;AAAA,IACjC,SAAS,OAAO;AACd,YAAM,UAAU,0CAA0C,IAAI,iDAC5D,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;AACA,cAAQ,MAAM,OAAO;AACrB,YAAM,YAAY,EAAE,QAAQ,cAAc,SAAS,KAAK,EAAE,KAAK,EAAE,CAAC;AAClE,YAAM,iBAAiB;AAAA,QACrB;AAAA,QACA,WAAW;AAAA,QACX;AAAA,QACA,OAAO,iBAAiB,QAAS,MAAM,SAAS,OAAQ;AAAA,QACxD,MAAM;AAAA,MACR,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AAEA,WAAS,WACP,MACA,WAAmB,iBACnB,OAAO,UACD;AACN,UAAM,SAAS,GAAG,IAAI,GAAG,QAAQ,GAAG,IAAI;AACxC,eAAW,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG;AACnC,UAAI,IAAI,WAAW,MAAM,EAAG,OAAM,OAAO,GAAG;AAAA,IAC9C;AACA,eAAW,OAAO,CAAC,GAAG,YAAY,GAAG;AACnC,UAAI,IAAI,WAAW,MAAM,EAAG,cAAa,OAAO,GAAG;AAAA,IACrD;AAAA,EACF;AAEA,WAAS,gBAAsB;AAC7B,UAAM,MAAM;AACZ,iBAAa,MAAM;AAAA,EACrB;AAEA,QAAM,MAA4B;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,uBAAuB,MAAM,cAAc,CAAC;AAElD,SAAO;AACT;;;AC7bA,YAAuB;AA+BhB,IAAM,+BAAN,cAAiD,gBAGtD;AAAA,EACA,YAAY,OAA0C;AACpD,UAAM,KAAK;AACX,SAAK,QAAQ,EAAE,UAAU,OAAO,oBAAoB,MAAM,YAAY;AAAA,EACxE;AAAA,EAEA,OAAO,2BAA2C;AAChD,WAAO,EAAE,UAAU,KAAK;AAAA,EAC1B;AAAA,EAEA,OAAO,yBACL,OACA,OACc;AACd,QAAI,MAAM,gBAAgB,MAAM,mBAAoB,QAAO;AAI3D,WAAO,EAAE,UAAU,OAAO,oBAAoB,MAAM,YAAY;AAAA,EAClE;AAAA,EAES,kBAAkB,OAAc,WAAkC;AACzE,UAAM,OAAO,EAAE,gBAAgB,UAAU,kBAAkB,KAAK;AAChE,QAAI,KAAK,MAAM,UAAU;AACvB,WAAK,MAAM,SAAS,OAAO,IAAI;AAC/B;AAAA,IACF;AAEA,YAAQ;AAAA,MACN,uCAAuC,KAAK,MAAM,IAAI;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AAAA,EAES,SAA0B;AACjC,QAAI,KAAK,MAAM,SAAU,QAAO,KAAK,MAAM;AAC3C,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;;;ACzDA,SAAS,YAAY,MAAc,OAAwB;AACzD,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,MAAM;AACZ,QAAI,OAAO,IAAI,WAAW,YAAY,IAAI,OAAQ,QAAO,GAAG,IAAI,KAAK,IAAI,MAAM;AAC/E,QAAI,OAAO,IAAI,OAAO,YAAY,IAAI,GAAI,QAAO,GAAG,IAAI,KAAK,IAAI,EAAE;AAAA,EACrE;AACA,SAAO;AACT;AAEO,SAAS,6BACd,SACA,UAA4C,CAAC,GAC5B;AACjB,QAAM,KAAK,QAAQ,MAAM;AACzB,QAAM,WAAW,oBAAI,IAAY;AACjC,SAAO,OAAO,KAAa,UAAgD;AACzE,QAAI,OAAO,QAAQ,YAAY,CAAC,IAAI,KAAK,GAAG;AAC1C,aAAO,EAAE,IAAI,OAAO,OAAO,4DAA4D;AAAA,IACzF;AACA,UAAM,SAAS,YAAY,KAAK,KAAK;AACrC,QAAI,SAAS,IAAI,MAAM,GAAG;AACxB,aAAO,EAAE,IAAI,OAAO,OAAO,IAAI,GAAG,+CAA+C;AAAA,IACnF;AACA,aAAS,IAAI,MAAM;AACnB,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ,UAAU,KAAK,OAAO,EAAE;AACrD,UAAI,OAAO,GAAI,QAAO,EAAE,IAAI,MAAM,QAAQ,OAAO,KAAK;AACtD,YAAM,EAAE,SAAS,OAAO,IAAI,OAAO;AACnC,aAAO,EAAE,IAAI,OAAO,OAAO,SAAS,GAAG,OAAO,IAAI,MAAM,KAAK,QAAQ;AAAA,IACvE,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,OAAO,IAAI,GAAG,oBAAoB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MACpF;AAAA,IACF,UAAE;AACA,eAAS,OAAO,MAAM;AAAA,IACxB;AAAA,EACF;AACF;","names":["result","Component"]}