@demlik/tea 0.11.0 → 0.13.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 (163) hide show
  1. package/dist/agent/index.d.ts +6 -5
  2. package/dist/agent/index.js +11 -11
  3. package/dist/authed-call/index.d.ts +3 -2
  4. package/dist/authed-call/index.js +7 -7
  5. package/dist/await-terminal/index.d.ts +3 -2
  6. package/dist/await-terminal/index.js +2 -2
  7. package/dist/batch-window/index.d.ts +4 -3
  8. package/dist/batch-window/index.js +3 -3
  9. package/dist/cache/index.d.ts +3 -2
  10. package/dist/cache/index.js +4 -4
  11. package/dist/chart/index.d.ts +4 -3
  12. package/dist/chart/index.js +2 -2
  13. package/dist/chart/inspect/index.d.ts +5 -4
  14. package/dist/chart/inspect/index.js +3 -3
  15. package/dist/chart/inspect/react.d.ts +6 -5
  16. package/dist/chart/inspect/react.js +5 -5
  17. package/dist/chart/lane/index.d.ts +7 -6
  18. package/dist/chart/lane/index.js +6 -6
  19. package/dist/chart/lane/react.d.ts +6 -5
  20. package/dist/chart/lane/react.js +7 -7
  21. package/dist/chart/lane/viewer/assets/{chunk-5RXB4S5H-IPzIfiJ6.js → chunk-5RXB4S5H-CcNtpUd7.js} +1 -1
  22. package/dist/chart/lane/viewer/assets/{classDiagram-v2-OCEON4UE-DnUXz1Pv.js → classDiagram-v2-OCEON4UE-D4uAiFr8.js} +1 -1
  23. package/dist/chart/lane/viewer/assets/{dagre-VZM6K2ZE-Og2UIoWg.js → dagre-VZM6K2ZE-831qZcA8.js} +1 -1
  24. package/dist/chart/lane/viewer/assets/{index-sP-6AD57.css → index-9SkH5NA3.css} +1 -1
  25. package/dist/chart/lane/viewer/assets/{index-Obj05Jex.js → index-Bgt4sXpW.js} +4 -4
  26. package/dist/chart/lane/viewer/assets/{kanban-definition-27J2QSJJ-CxkCxJUN.js → kanban-definition-27J2QSJJ-G7PaPzy-.js} +1 -1
  27. package/dist/chart/lane/viewer/assets/{mindmap-definition-FAOFIHXS-DvgvXZhp.js → mindmap-definition-FAOFIHXS-CGj9nrVk.js} +1 -1
  28. package/dist/chart/lane/viewer/assets/{stateDiagram-OKZ733FA-CIZQWK5X.js → stateDiagram-OKZ733FA-B_88AzBS.js} +1 -1
  29. package/dist/chart/lane/viewer/assets/{stateDiagram-v2-UEYNNEHI-Sm6p0NoR.js → stateDiagram-v2-UEYNNEHI-CR5gcgq6.js} +1 -1
  30. package/dist/chart/lane/viewer/assets/{timeline-definition-Z64GVDOM-CV3KwSb-.js → timeline-definition-Z64GVDOM-CCv52MfY.js} +1 -1
  31. package/dist/chart/lane/viewer/index.html +2 -2
  32. package/dist/chart/report/index.d.ts +5 -4
  33. package/dist/chart/report/index.js +4 -4
  34. package/dist/{chunk-ZF6WDK2D.js → chunk-3I52QZZ5.js} +7 -7
  35. package/dist/{chunk-ZF6WDK2D.js.map → chunk-3I52QZZ5.js.map} +1 -1
  36. package/dist/{chunk-ZD6PNZBK.js → chunk-3ZAFFRRB.js} +3 -3
  37. package/dist/{chunk-ZD6PNZBK.js.map → chunk-3ZAFFRRB.js.map} +1 -1
  38. package/dist/{chunk-4KTWLPL5.js → chunk-4EQZ76JC.js} +3 -3
  39. package/dist/{chunk-4KTWLPL5.js.map → chunk-4EQZ76JC.js.map} +1 -1
  40. package/dist/{chunk-EUF7XOEE.js → chunk-4KLG43GY.js} +6 -6
  41. package/dist/{chunk-EUF7XOEE.js.map → chunk-4KLG43GY.js.map} +1 -1
  42. package/dist/{chunk-JER5O7PQ.js → chunk-7FRZ2CT2.js} +15 -7
  43. package/dist/chunk-7FRZ2CT2.js.map +1 -0
  44. package/dist/{chunk-ZCL7SCBK.js → chunk-CIQG5L42.js} +5 -5
  45. package/dist/{chunk-ZCL7SCBK.js.map → chunk-CIQG5L42.js.map} +1 -1
  46. package/dist/{chunk-TP5UPGLY.js → chunk-CLM6ERNO.js} +3 -3
  47. package/dist/{chunk-TP5UPGLY.js.map → chunk-CLM6ERNO.js.map} +1 -1
  48. package/dist/{chunk-ND3DH6KM.js → chunk-COS5MSTO.js} +3 -3
  49. package/dist/{chunk-ND3DH6KM.js.map → chunk-COS5MSTO.js.map} +1 -1
  50. package/dist/{chunk-JP5D6GSL.js → chunk-CRPZJVD2.js} +4 -4
  51. package/dist/{chunk-JP5D6GSL.js.map → chunk-CRPZJVD2.js.map} +1 -1
  52. package/dist/{chunk-SUST46KO.js → chunk-D62FDQKE.js} +3 -3
  53. package/dist/{chunk-SUST46KO.js.map → chunk-D62FDQKE.js.map} +1 -1
  54. package/dist/{chunk-JGVL3WPL.js → chunk-DGE4PV4A.js} +3 -3
  55. package/dist/{chunk-JGVL3WPL.js.map → chunk-DGE4PV4A.js.map} +1 -1
  56. package/dist/{chunk-WLGO64WC.js → chunk-DMYGQB4O.js} +4 -4
  57. package/dist/{chunk-WLGO64WC.js.map → chunk-DMYGQB4O.js.map} +1 -1
  58. package/dist/{chunk-A56OR5RF.js → chunk-L57ZOT5K.js} +3 -3
  59. package/dist/{chunk-A56OR5RF.js.map → chunk-L57ZOT5K.js.map} +1 -1
  60. package/dist/{chunk-5KJKJOFC.js → chunk-NR7BU22N.js} +3 -3
  61. package/dist/{chunk-5KJKJOFC.js.map → chunk-NR7BU22N.js.map} +1 -1
  62. package/dist/{chunk-7V4EVLZA.js → chunk-O4MVQTEJ.js} +4 -4
  63. package/dist/{chunk-7V4EVLZA.js.map → chunk-O4MVQTEJ.js.map} +1 -1
  64. package/dist/{chunk-B5VXOFMZ.js → chunk-OOYD44JI.js} +54 -3
  65. package/dist/chunk-OOYD44JI.js.map +1 -0
  66. package/dist/{chunk-7SVIRMC6.js → chunk-RH5EFRVJ.js} +3 -3
  67. package/dist/{chunk-7SVIRMC6.js.map → chunk-RH5EFRVJ.js.map} +1 -1
  68. package/dist/{chunk-3JU6657S.js → chunk-VYFAZN3F.js} +3 -3
  69. package/dist/{chunk-3JU6657S.js.map → chunk-VYFAZN3F.js.map} +1 -1
  70. package/dist/chunk-XGELA764.js +163 -0
  71. package/dist/chunk-XGELA764.js.map +1 -0
  72. package/dist/{chunk-I5OV65MS.js → chunk-YUXP55T2.js} +3 -3
  73. package/dist/{chunk-I5OV65MS.js.map → chunk-YUXP55T2.js.map} +1 -1
  74. package/dist/{chunk-E6GEDSF4.js → chunk-YWIKDKHY.js} +3 -3
  75. package/dist/{chunk-E6GEDSF4.js.map → chunk-YWIKDKHY.js.map} +1 -1
  76. package/dist/{chunk-5EHLEUTL.js → chunk-ZSUUOEPL.js} +51 -6
  77. package/dist/chunk-ZSUUOEPL.js.map +1 -0
  78. package/dist/{core-Bjc0bS8j.d.ts → core-Co0LWkIA.d.ts} +190 -3
  79. package/dist/deadline/index.d.ts +3 -2
  80. package/dist/deadline/index.js +3 -3
  81. package/dist/do/index.d.ts +12 -8
  82. package/dist/do/index.js +11 -11
  83. package/dist/do/index.js.map +1 -1
  84. package/dist/{durable-effects-D8SqU_if.d.ts → durable-effects-C6uwzjb5.d.ts} +1 -1
  85. package/dist/extension/index.d.ts +3 -2
  86. package/dist/extension/index.js +3 -3
  87. package/dist/extension/react.js +3 -3
  88. package/dist/extension/subs/index.d.ts +3 -2
  89. package/dist/fan-out/index.d.ts +3 -2
  90. package/dist/{fold-Blbhru48.d.ts → fold-BJPdjc9w.d.ts} +1 -1
  91. package/dist/{graph-CcjWZVrd.d.ts → graph-B3L5e0N1.d.ts} +1 -1
  92. package/dist/idempotent-intake/index.d.ts +3 -2
  93. package/dist/index.d.ts +14 -6
  94. package/dist/index.js +2 -2
  95. package/dist/journal/index.d.ts +373 -0
  96. package/dist/journal/index.js +3 -0
  97. package/dist/journal/index.js.map +1 -0
  98. package/dist/llm-call/index.d.ts +3 -2
  99. package/dist/llm-call/index.js +8 -8
  100. package/dist/{machine-0OmPvsy_.d.ts → machine-BtFWQmmq.d.ts} +1 -1
  101. package/dist/machine-viz/index.d.ts +2 -1
  102. package/dist/machine-viz/index.js +2 -2
  103. package/dist/mem/index.d.ts +3 -2
  104. package/dist/monitored-run/index.d.ts +4 -3
  105. package/dist/monitored-run/index.js +5 -5
  106. package/dist/node/index.d.ts +31 -3
  107. package/dist/node/index.js +92 -3
  108. package/dist/node/index.js.map +1 -1
  109. package/dist/paginated-walk/index.d.ts +3 -2
  110. package/dist/paginated-walk/index.js +7 -7
  111. package/dist/parity/index.d.ts +3 -2
  112. package/dist/parity/index.js +3 -3
  113. package/dist/pbt/arbitraries/index.d.ts +2 -1
  114. package/dist/pbt/index.d.ts +2 -1
  115. package/dist/pbt/index.js +3 -3
  116. package/dist/pbt/runners/index.d.ts +2 -1
  117. package/dist/pbt/runners/index.js +3 -3
  118. package/dist/poller/index.d.ts +3 -2
  119. package/dist/poller/index.js +3 -3
  120. package/dist/prediction/index.d.ts +2 -1
  121. package/dist/prediction/index.js +2 -2
  122. package/dist/pure/index.d.ts +2 -1
  123. package/dist/pure/index.js +2 -2
  124. package/dist/react/index.d.ts +4 -3
  125. package/dist/react/index.js +2 -2
  126. package/dist/react/index.js.map +1 -1
  127. package/dist/reconciler/index.d.ts +3 -2
  128. package/dist/reconciler/index.js +7 -7
  129. package/dist/recorder/index.d.ts +3 -2
  130. package/dist/{reducer-BqyoVyBG.d.ts → reducer-4GNR6b8B.d.ts} +2 -2
  131. package/dist/resilient-call/index.d.ts +3 -2
  132. package/dist/resilient-call/index.js +6 -6
  133. package/dist/{run-BVeqJDBF.d.ts → run-pAcmBpah.d.ts} +3 -3
  134. package/dist/{runtime-types-Bxc637bp.d.ts → runtime-types-CNLmhWif.d.ts} +17 -2
  135. package/dist/saga/index.d.ts +3 -2
  136. package/dist/{samples-DCt6nF8H.d.ts → samples-B3My5oh2.d.ts} +1 -1
  137. package/dist/snapshot/index.d.ts +2 -1
  138. package/dist/snapshot/index.js +3 -3
  139. package/dist/subs/index.d.ts +4 -3
  140. package/dist/subs/index.js +3 -3
  141. package/dist/testing/index.d.ts +3 -2
  142. package/dist/testing/index.js +2 -2
  143. package/dist/throttled-input/index.d.ts +3 -2
  144. package/dist/throttled-input/index.js +6 -6
  145. package/dist/token-refresh/index.d.ts +2 -1
  146. package/dist/token-refresh/index.js +3 -3
  147. package/dist/trace-replay/index.d.ts +3 -2
  148. package/dist/trace-replay/index.js +3 -3
  149. package/dist/{types-D7u9DkH7.d.ts → types-XS_miRnB.d.ts} +1 -1
  150. package/dist/with-deadline/index.d.ts +2 -1
  151. package/dist/with-deadline/index.js +2 -2
  152. package/dist/with-resilience/index.d.ts +3 -2
  153. package/dist/with-resilience/index.js +6 -6
  154. package/dist/with-telemetry/index.d.ts +2 -1
  155. package/dist/with-telemetry/index.js +2 -2
  156. package/dist/work-queue/adapter.d.ts +3 -2
  157. package/dist/work-queue/index.d.ts +3 -2
  158. package/dist/work-queue/ops.d.ts +3 -2
  159. package/dist/workflow/index.d.ts +4 -3
  160. package/package.json +11 -4
  161. package/dist/chunk-5EHLEUTL.js.map +0 -1
  162. package/dist/chunk-B5VXOFMZ.js.map +0 -1
  163. package/dist/chunk-JER5O7PQ.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/resilient-call/index.ts"],"names":[],"mappings":"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","file":"chunk-EUF7XOEE.js","sourcesContent":["/**\n * @packageDocumentation\n *\n * @deprecated `@demlik/tea/resilient-call` is deprecated in favor of\n * `@demlik/tea/with-resilience` — the higher-order `withResilience(base,\n * config)` wrapper (TEA-idiomatic: it wraps any existing machine instead of\n * forcing a bespoke embedded slice; epic consolidation verdict, survivor\n * `with-resilience`). The APIs are NOT drop-in; migration map:\n *\n * - `createResilientCall(config, rng)` + hand-wiring `init` / the verbs /\n * `subs` / `handlers` into your machine → `withResilience(base, { target,\n * ...bricks }, rng)`. Nothing is wired by hand anymore: the wrapper\n * intercepts the `target` base Cmd and routes it through the gate.\n * - `ResilientConfig` bricks (`retry` / `circuit` / `rateLimit` / `cache` /\n * `deadline`) → unchanged; `ResilienceConfig` extends the same knob and\n * adds `target` (required), `keyOf?` (per-call key — was `attempt`'s `key`\n * argument), and `at?` (time-as-data reader — REQUIRED with any\n * time-sensitive brick; `withResilience` throws at construction without it).\n * - The slice at your chosen Model field + `liftResilience` → the wrapper\n * owns `model.$resilience`; there is nothing to lift.\n * - Verbs `attempt` / `succeed` / `fail` / `onTimer` → internal to the\n * wrapper; results route as `$resilience:ok` / `$resilience:err` /\n * `$resilience:timer` Msgs through the merged `update` (the old\n * `resilient_run` / `resilient_ok` / `resilient_err` vocabulary is renamed\n * into the `$resilience:` namespace).\n * - `settleFailed` → NO equivalent. It exists for embedded-slice consumers\n * (`authed-call`, `paginated-walk`) that settle a call without touching the\n * breaker; the wrapper exposes no caller-facing settle verb.\n * - `handlers(ports)` / `subs(state)` / the `subscribeDeadline` re-export →\n * handled by the wrapper; run the returned machine like any other.\n *\n * Removal window (\"deprecate, don't delete\"): the `./resilient-call` subpath\n * export survives one minor release after this deprecation ships, then is\n * removed. Internal sibling modules (`with-resilience` itself, `agent`,\n * `llm-call`, `authed-call`, `reconciler`, `paginated-walk`) intentionally keep\n * importing `../resilient-call` — the deprecation targets the PUBLISHED export,\n * not the module's internal role.\n *\n * @demlik/tea/resilient-call — the ROOT composition: a single resilience knob\n * that bundles cache → circuit-breaker → rate-limit → exponential-backoff retry\n * (with a deadline-driven retry timer) around any fallible `(input) => Promise`\n * port.\n *\n * This is `examples/resilient-fetch.ts`'s hand-wired `attempt()` generalized:\n *\n * - It is **keyed**. The example tracked one URL at a time; this tracks N\n * concurrent logical calls, each under a string `key`. The cache, the\n * waiting-retry bookkeeping, and the retry timers are all per-key, while the\n * circuit breaker and token bucket are shared (one downstream target, one\n * breaker / one bucket — the example's implicit single-target assumption\n * made explicit).\n * - It is **config-driven**, not hand-wired. You hand `createResilientCall`\n * a `ResilientConfig` and get back the uniform knob contract every L2\n * composition exposes: `init()`, the four verbs (`attempt` / `succeed` /\n * `fail` / `onTimer`), `subs(state)`, and `handlers(ports)`.\n * - Every brick is **optional**. Omit `cache` and the cache gate disappears\n * (`get` is never consulted); omit `circuit` and every call passes the\n * breaker; omit `rateLimit` and the bucket never throttles; omit `retry`\n * and a failure is terminal (no backoff, no timer); omit `deadline` and no\n * overall wall-clock cap is armed. \"Omit a brick → omit its gate\" is the\n * whole config story — there are no other modes.\n *\n * Four later compositions (`llm-call`, `paginated-walk`, `authed-call`,\n * `reconciler`) inherit THIS slice + verb shape, so the contract here is\n * load-bearing: the slice is a flat record of brick states, every verb returns\n * `readonly [State, Cmd[]]`, time is always an `at` / `now` parameter, and the\n * RNG used for jitter is injected on the config (never read inside a verb).\n *\n * ## The two non-negotiables (canon)\n *\n * - **Durable** — the slice is a plain-data Model field (brick states are all\n * JSON-serializable), so it survives DO eviction / reload.\n * - **Replayable** — every transition is a verb returning new state + Cmds;\n * `replay` reconstructs it exactly. Nothing here closes over time or RNG.\n *\n * ## Where the clock / RNG live\n *\n * Inside the verbs: nowhere. Time arrives as `at` on `attempt` / `onTimer` and\n * is carried on the result / timer Msgs the consumer dispatches. Jitter RNG is\n * injected once at `createResilientCall(config, rng)` and threaded into\n * `nextDelayMs` at the verb boundary — deterministic in tests, `Math.random`\n * by default. The ONLY clock read is `Date.now()` inside the `handlers` port\n * (the effect boundary), exactly as `resilient-fetch.ts` stamps its result Msgs.\n *\n * That same `at` is what makes a DURATION-bounded retry budget reachable here:\n * `recordFailure` / `shouldRetry` are fed the failure's observation instant,\n * so `config.retry` accepts any `AnyRetryPolicy` — a count, a wall-clock outage\n * budget (`maxElapsedMs`), or explicit `unbounded: true` — with no new argument\n * on any verb and no clock read inside one.\n *\n * ## Typical wiring\n *\n * const rc = createResilientCall<string, Result>({\n * cache: { ttlMs: 60_000 },\n * circuit: { threshold: 5, cooldownMs: 30_000 },\n * rateLimit: { capacity: 10, refillPerSec: 5 },\n * retry: defaultRetryPolicy,\n * deadline: { ms: 5_000 },\n * });\n *\n * // in the machine:\n * init: () => [{ resilience: rc.init() }, []],\n * update: {\n * fetch: (s, m) => lift(s, rc.attempt(s.resilience, m.key, m.input, m.at)),\n * call_ok: (s, m) => lift(s, rc.succeed(s.resilience, m.key, m)),\n * call_err:(s, m) => lift(s, rc.fail(s.resilience, m.key, m)),\n * retry_due:(s, m) => lift(s, rc.onTimer(s.resilience, m)),\n * },\n * subscriptions: (s) => rc.subs(s.resilience),\n * subscribe: { deadline: subscribeDeadline },\n * interpret: rc.handlers({ run: ctx.call }),\n */\n\nimport {\n get as cacheGet,\n set as cacheSet,\n initCache,\n type TtlCache,\n} from \"../cache\";\nimport {\n type CircuitState,\n canPass,\n initCircuit,\n onFailure,\n onSuccess,\n} from \"../circuit-breaker\";\nimport {\n type DeadlineExceeded,\n type DeadlineSub,\n deadlineSub,\n subscribeDeadline,\n} from \"../deadline\";\nimport { type Cmd, type NoCtx, tryInterpret } from \"../index\";\nimport { MsgType } from \"../protocol\";\nimport { without } from \"../pure/core\";\nimport { initBucket, type TokenBucket, tryConsume } from \"../rate-limit\";\nimport {\n type AnyRetryPolicy,\n asRng,\n initRetry,\n nextDelayMs,\n type RetryState,\n recordFailure,\n shouldRetry,\n} from \"../retry-backoff\";\n\n// ===========================================================================\n// Config — the knob. Every brick optional; omit a brick → omit its gate.\n// ===========================================================================\n\n/** Circuit-breaker knob — only the two numbers a consumer ever tunes. */\nexport interface CircuitConfig {\n /** Consecutive failures that trip the breaker open. */\n readonly threshold: number;\n /** How long the breaker stays open before admitting a probe, in ms. */\n readonly cooldownMs: number;\n /**\n * Probes admitted in `half_open` before fast-failing the rest of the round.\n * Defaults to 1 (a single probe decides recovery) — matches the circuit-\n * breaker module's `defaultCircuitPolicy`.\n */\n readonly halfOpenMaxProbes?: number;\n}\n\n/** Token-bucket rate-limit knob. */\nexport interface RateLimitConfig {\n /** Burst size — the bucket starts full at `capacity`. */\n readonly capacity: number;\n /** Steady-state refill rate, tokens per second. */\n readonly refillPerSec: number;\n}\n\n/** Per-entry TTL cache knob. */\nexport interface CacheConfig {\n /** How long a cached success stays fresh, in ms. */\n readonly ttlMs: number;\n}\n\n/** Overall wall-clock deadline knob — an absolute cap per in-flight call. */\nexport interface DeadlineConfig {\n /** Budget from the moment a call starts, in ms. */\n readonly ms: number;\n}\n\n/**\n * The resilience knob. EVERY field is optional: omit a brick and its gate is\n * skipped entirely (the slice still carries a default brick state so the shape\n * stays uniform across configs, but the gate is never consulted). An empty\n * config `{}` is a valid pass-through — a bare effect with no resilience at all.\n */\nexport interface ResilientConfig {\n /**\n * The backoff brick. Omit and a failure is terminal (no backoff, no timer).\n *\n * Any bound the `../retry-backoff` union admits: a count (`RetryPolicy`), a\n * wall-clock outage budget (`DurationRetryPolicy`), or explicit\n * `unbounded: true`. A duration bound needs no extra wiring: every path that\n * records a failure already holds the instant it was observed as DATA —\n * `fail`'s `msg.at` (stamped at the interpret boundary) and `gate`'s `at`\n * (the caller's `attempt` / the retry timer's `atMs`) — so the streak clock\n * is fed from a Msg, never from a `Date.now()` inside a verb (invariant 2).\n */\n readonly retry?: AnyRetryPolicy;\n readonly circuit?: CircuitConfig;\n readonly rateLimit?: RateLimitConfig;\n readonly cache?: CacheConfig;\n readonly deadline?: DeadlineConfig;\n}\n\n// ===========================================================================\n// Slice — the Model field this knob owns. A flat record of brick states.\n// ===========================================================================\n\n/**\n * Per-key call phase. `key` indexes a logical call; several can be in flight at\n * once (the generalization of the example's single `url`). Discriminated on\n * `phase` so each phase carries only its own data (pattern 11):\n *\n * - `idle` — never attempted, or fully settled and forgotten.\n * - `running` — the effect Cmd is out; awaiting `succeed` / `fail`.\n * Carries `deadlineAtMs` (absolute cap, `0` if no deadline\n * brick) and the last `input` so a retry can re-issue it.\n * - `waiting_retry` — a transient failure backed off; the retry timer is armed\n * for `retryAtMs`. Carries `input` for the re-attempt.\n * - `circuit_open` — the breaker fast-failed this attempt. Terminal for this\n * call until the consumer re-attempts after cooldown.\n * - `succeeded` — settled OK. `result` is the value the port produced.\n * - `failed` — settled Err (out of retries, or no retry brick). `error`\n * carries the last failure.\n */\nexport type CallPhase<I, R> =\n | { readonly phase: \"idle\" }\n | {\n readonly phase: \"running\";\n readonly input: I;\n readonly deadlineAtMs: number;\n }\n | {\n readonly phase: \"waiting_retry\";\n readonly input: I;\n readonly retryAtMs: number;\n readonly deadlineAtMs: number;\n }\n | { readonly phase: \"circuit_open\" }\n | { readonly phase: \"succeeded\"; readonly result: R }\n | { readonly phase: \"failed\"; readonly error: unknown };\n\n/**\n * The slice. `circuit` / `bucket` are SHARED across keys (one downstream target\n * → one breaker, one bucket). `retry` and `cache` are PER KEY (each logical call\n * has its own backoff count + cached result), as is the per-call `CallPhase`.\n * Every field is plain data → the whole slice serializes into a `Store<S>`.\n *\n * `retry` / `cache` keep a default brick value even when the corresponding\n * config brick is omitted, so the slice shape is identical regardless of which\n * bricks the consumer enabled — the verbs simply never consult the unused brick.\n */\nexport interface ResilientState<I, R> {\n readonly circuit: CircuitState;\n readonly bucket: TokenBucket;\n /**\n * Per-key backoff counter. Entries minted by `backoff` are `TimedRetryState`s\n * (they carry the streak's `firstFailureAtMs`, since every failure path holds\n * the observation instant); the field is typed at the `RetryState` supertype\n * because a key that has never failed has no streak, and a slice persisted\n * before the origin existed rehydrates without one. Still plain data.\n */\n readonly retry: Readonly<Record<string, RetryState>>;\n readonly cache: TtlCache<R>;\n readonly calls: Readonly<Record<string, CallPhase<I, R>>>;\n}\n\n// ===========================================================================\n// Cmds + Msgs the knob speaks. Generic over the port input `I`.\n// ===========================================================================\n\n/**\n * The one effect this knob emits: \"run the port for `key` with `input`\". The\n * consumer's `handlers(ports)` interprets it; it carries no closure — `input`\n * is plain data (invariant 3).\n */\nexport type RunCmd<I> = Cmd<typeof MsgType.ResilientRun> & {\n readonly key: string;\n readonly input: I;\n};\n\n/** Settle Msgs the `handlers` port dispatches back. `at` is stamped at the boundary. */\nexport type SucceedMsg<R> = {\n readonly type: typeof MsgType.ResilientOk;\n readonly key: string;\n readonly result: R;\n readonly at: number;\n};\nexport type FailMsg = {\n readonly type: typeof MsgType.ResilientErr;\n readonly key: string;\n readonly error: unknown;\n readonly at: number;\n};\n\n/** The retry / deadline timer Msg — `DeadlineExceeded`, keyed by the call `key`. */\nexport type ResilientTimerMsg = DeadlineExceeded;\n\n/**\n * The plain-data error a deadline-failed call settles with. A `{_tag, ...}`\n * sentinel — NEVER a `new Error(...)` — so the slice stays JSON-serializable\n * (Error objects round-trip to `{}` and carry a stack trace, both of which break\n * the slice's durability invariant). `id` / `atMs` echo the timer that fired so\n * a consumer can attribute the failure to its deadline.\n */\nexport type DeadlineExceededError = {\n readonly _tag: \"deadline_exceeded\";\n readonly id: string;\n readonly atMs: number;\n};\n\n/** Ports the consumer supplies to `handlers`. */\nexport interface ResilientPorts<I, R> {\n /** The fallible work this knob wraps. Throws on failure → routed to `fail`. */\n readonly run: (input: I, key: string) => Promise<R>;\n}\n\n// ===========================================================================\n// Internal brick-policy derivation — config → the L1 policy shapes.\n// ===========================================================================\n\n// A circuit policy is only built when the brick is configured; absence is\n// represented as `null` so the gate can short-circuit to \"always pass\".\nfunction circuitPolicy(config: ResilientConfig) {\n if (config.circuit === undefined) return null;\n return {\n failureThreshold: config.circuit.threshold,\n cooldownMs: config.circuit.cooldownMs,\n halfOpenMaxProbes: config.circuit.halfOpenMaxProbes ?? 1,\n };\n}\n\n// Sub-id families. Each call's retry timer is a deadline keyed by `key`, so a\n// machine running many concurrent calls reconciles each independently.\nfunction retryTimerId(key: string): string {\n return `resilient:retry:${key}`;\n}\nfunction deadlineTimerId(key: string): string {\n return `resilient:deadline:${key}`;\n}\n\n// ===========================================================================\n// The knob factory.\n// ===========================================================================\n\n/**\n * Build a resilient-call knob from `config`. `rng` is injected for retry\n * jitter — pass a fixed `() => 0.5` in tests to pin backoff; defaults to\n * `Math.random` (read at the verb boundary, never inside a brick op). It is\n * curried onto the factory rather than threaded through every verb so callers\n * spell the determinism choice once.\n *\n * Returns the uniform L2 knob contract. `I` is the port input type, `R` the\n * port result type.\n *\n * @deprecated Use `withResilience` from `@demlik/tea/with-resilience` — not\n * drop-in; see the migration map at the top of this module.\n */\nexport function createResilientCall<I, R>(\n config: ResilientConfig,\n rng: () => number = Math.random,\n) {\n const cPolicy = circuitPolicy(config);\n // Re-affirm the `[0, 1)` contract at the seam where the injected generator\n // feeds the backoff math (brand from `../retry-backoff`). The factory's\n // public param stays a plain `() => number` so transitive callers are\n // unchanged; `asRng` is the single point it's branded for `nextDelayMs`.\n const rngBranded = asRng(rng);\n\n /** The starting slice. Bricks not in `config` still get a default value. */\n function init(): ResilientState<I, R> {\n return {\n circuit: initCircuit(),\n // The bucket carries a default value even without the rateLimit brick so\n // the slice shape is uniform, but the rate-limit GATE is skipped entirely\n // when the brick is absent (see `gate`) — the bucket is simply never\n // consulted. A `0/0` placeholder bucket would be touched by `tryConsume`;\n // a `1-cap` default is harmless because the gate never calls it.\n bucket: config.rateLimit\n ? initBucket(\n config.rateLimit.capacity,\n config.rateLimit.refillPerSec,\n 0,\n )\n : initBucket(1, 1, 0),\n retry: {},\n cache: initCache<R>(),\n calls: {},\n };\n }\n\n /** Read this key's retry state, defaulting to a fresh one. */\n function retryOf(s: ResilientState<I, R>, key: string): RetryState {\n return s.retry[key] ?? initRetry();\n }\n\n /** Compute the absolute deadline for a call starting at `at` (0 = no cap). */\n function deadlineAt(at: number): number {\n return config.deadline ? at + config.deadline.ms : 0;\n }\n\n /**\n * The shared decision: cache → rate-limit → circuit gate, then either emit\n * the effect or schedule a retry. `deadlineAtMs` is threaded so a re-attempt\n * (from `onTimer`) keeps the ORIGINAL overall deadline rather than restarting\n * it. PURE — `at` is the only clock; `rng` is the injected jitter source.\n *\n * Used by both `attempt` (fresh call) and `onTimer` (retry timer fired) so\n * the gate logic lives in exactly one place — the example's shared `attempt`\n * helper, lifted to a keyed knob.\n *\n * ## Why rate-limit is gated BEFORE the circuit probe\n *\n * The circuit-breaker's `canPass` is not a passive read: in `half_open` it\n * *consumes* a probe slot (advancing `probes`), and the consumed slot is only\n * released when a probe RESOLVES via `onSuccess` / `onFailure`. So a probe\n * slot may only be taken when this attempt is actually going to reach the\n * backend (i.e. emit the `resilient_run` Cmd). The rate-limit gate can reject\n * an attempt and return a backoff WITHOUT any Cmd — no backend call, so no\n * settle Msg ever comes back. If the circuit probe were consumed first, that\n * rate-limited attempt would burn the half-open probe budget on a call that\n * never happened, wedging the breaker `half_open` at its probe cap forever\n * (nothing moves it out of `half_open` but a resolved probe). Running the\n * rate-limit gate first means the circuit probe is consumed ONLY on the path\n * that emits the effect.\n */\n function gate(\n s: ResilientState<I, R>,\n key: string,\n input: I,\n at: number,\n deadlineAtMs: number,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n // 1) Serve from cache if fresh — no effect at all. Skipped when no cache brick.\n if (config.cache !== undefined) {\n const cached = cacheGet(s.cache, key, at);\n if (cached !== undefined) {\n return [setCall(s, key, { phase: \"succeeded\", result: cached }), []];\n }\n }\n\n // 2) Rate-limit gate FIRST — it may reject with no Cmd, so it must run\n // before any circuit probe is consumed (see header note). Skipped entirely\n // when no rateLimit brick — the bucket is never consulted, so the default\n // placeholder bucket stays untouched.\n let bucket = s.bucket;\n if (config.rateLimit !== undefined) {\n const [next, hasToken] = tryConsume(bucket, at);\n bucket = next;\n if (!hasToken) {\n // Rate-limited: treat as a transient failure and back off via retry.\n // The circuit is untouched — no probe is spent on a call that never ran.\n return backoff(\n { ...s, bucket },\n key,\n input,\n \"rate_limited\",\n at,\n deadlineAtMs,\n );\n }\n }\n\n // 3) Circuit-breaker gate. `null` policy → no breaker → always pass. Reached\n // only once a token is secured, so a half-open probe is consumed exclusively\n // on the path that emits the effect below.\n let circuit = s.circuit;\n if (cPolicy !== null) {\n const [next, ok] = canPass(circuit, cPolicy, at);\n circuit = next;\n if (!ok) {\n return [\n { ...setCall(s, key, { phase: \"circuit_open\" }), bucket, circuit },\n [],\n ];\n }\n }\n\n // 4) All gates passed — emit the effect as data.\n return [\n {\n ...setCall(s, key, { phase: \"running\", input, deadlineAtMs }),\n circuit,\n bucket,\n },\n [{ type: MsgType.ResilientRun, key, input }],\n ];\n }\n\n /**\n * Back off after a transient failure: record it, and if `retry` permits\n * another attempt, enter `waiting_retry` with the retry timer armed; else\n * settle `failed`. When no `retry` brick is configured the call fails on the\n * first failure (no backoff, no timer). PURE.\n *\n * `at` is both the backoff anchor AND the streak clock: it is passed to\n * `recordFailure` (which starts `firstFailureAtMs` on the streak's first\n * failure and preserves it on every later one) and to `shouldRetry`, so a\n * `DurationRetryPolicy` on `config.retry` is honoured with no extra wiring.\n * A success drops `retry[key]` entirely, which drops the origin with it —\n * only an unbroken run of failures grows toward a duration budget.\n */\n function backoff(\n s: ResilientState<I, R>,\n key: string,\n input: I,\n error: unknown,\n at: number,\n deadlineAtMs: number,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n if (config.retry === undefined) {\n return [setCall(s, key, { phase: \"failed\", error }), []];\n }\n const retry = recordFailure(retryOf(s, key), error, at);\n const withRetry = { ...s, retry: { ...s.retry, [key]: retry } };\n if (!shouldRetry(retry, config.retry, at)) {\n return [setCall(withRetry, key, { phase: \"failed\", error }), []];\n }\n const retryAtMs = at + nextDelayMs(retry, config.retry, rngBranded);\n return [\n setCall(withRetry, key, {\n phase: \"waiting_retry\",\n input,\n retryAtMs,\n deadlineAtMs,\n }),\n [],\n ];\n }\n\n // Set the phase for one key, leaving every other field untouched.\n function setCall(\n s: ResilientState<I, R>,\n key: string,\n phase: CallPhase<I, R>,\n ): ResilientState<I, R> {\n return { ...s, calls: { ...s.calls, [key]: phase } };\n }\n\n // === Verb: attempt =======================================================\n\n /**\n * Start (or restart) the call for `key` with `input` at time `at`. Runs the\n * cache → circuit → rate-limit gate and either emits the `resilient_run`\n * effect, schedules a retry, fast-fails (circuit open), or serves the cache.\n * PURE.\n */\n function attempt(\n s: ResilientState<I, R>,\n key: string,\n input: I,\n at: number,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n return gate(s, key, input, at, deadlineAt(at));\n }\n\n // === Verb: succeed =======================================================\n\n /**\n * Record a success for `key`: close the breaker, fill the cache (if a cache\n * brick exists), reset this key's retry count, and settle `succeeded`. PURE —\n * `msg.at` is the cache write clock.\n */\n function succeed(\n s: ResilientState<I, R>,\n key: string,\n msg: SucceedMsg<R>,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n const circuit =\n cPolicy !== null ? onSuccess(s.circuit, cPolicy) : s.circuit;\n const cache =\n config.cache !== undefined\n ? cacheSet(s.cache, key, msg.result, msg.at, config.cache.ttlMs)\n : s.cache;\n // Drop this key's retry counter — a success ends the retry run.\n const retry = without(s.retry, key);\n return [\n {\n ...setCall(s, key, { phase: \"succeeded\", result: msg.result }),\n circuit,\n cache,\n retry,\n },\n [],\n ];\n }\n\n // === Verb: fail ==========================================================\n\n /**\n * Record a failure for `key`: trip the breaker (it may open), then back off —\n * schedule a retry if `retry` permits, else settle `failed`. PURE — `msg.at`\n * stamps the breaker trip + the retry delay base. Re-issues from the call's\n * remembered `input` and preserves the original overall `deadlineAtMs`.\n */\n function fail(\n s: ResilientState<I, R>,\n key: string,\n msg: FailMsg,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n const circuit =\n cPolicy !== null ? onFailure(s.circuit, cPolicy, msg.at) : s.circuit;\n const withCircuit = { ...s, circuit };\n const call = s.calls[key];\n const input = call?.phase === \"running\" ? call.input : undefined;\n const deadlineAtMs =\n call?.phase === \"running\" ? call.deadlineAtMs : deadlineAt(msg.at);\n // No remembered input (e.g. a stray fail for a key not running) → just\n // settle failed after tripping the breaker; nothing to re-issue.\n if (input === undefined) {\n return [\n setCall(withCircuit, key, { phase: \"failed\", error: msg.error }),\n [],\n ];\n }\n return backoff(withCircuit, key, input, msg.error, msg.at, deadlineAtMs);\n }\n\n // === Verb: settleFailed ==================================================\n\n /**\n * Settle `key` to terminal `failed` with `error` WITHOUT touching the circuit\n * breaker or this key's retry counter. PURE.\n *\n * This is the verb for a failure that is NOT a downstream-health signal: the\n * call must end now, but the breaker must not trip and the backoff run must\n * not advance. `fail` is the opposite — it records the failure against the\n * breaker (it may open) and feeds the retry policy (it may back off). Use\n * `settleFailed` when the *reason* the call cannot proceed has nothing to do\n * with downstream health:\n *\n * - `authed-call` settles a 401 it cannot fix (e.g. the refresh budget is\n * spent): a bad token is the caller's problem, not the backend's —\n * tripping the breaker on it would punish a healthy target, and backing\n * off would just retry a request that will 401 again.\n * - `paginated-walk` settles a terminal walk error (e.g. a malformed page\n * the consumer rejects) that should stop the walk without poisoning the\n * shared breaker the next page fetch passes through.\n *\n * Because it leaves `circuit` and `retry[key]` untouched, the breaker keeps\n * its health view of the actual backend and a later `attempt` for this key\n * starts a fresh retry run. Both sibling knobs previously hand-rolled this by\n * splicing `calls` directly; this verb gives them one named, tested entry\n * point so the slice's settle invariants live in exactly one place.\n */\n function settleFailed(\n s: ResilientState<I, R>,\n key: string,\n error: unknown,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n return [setCall(s, key, { phase: \"failed\", error }), []];\n }\n\n // === Verb: onTimer =======================================================\n\n /**\n * A timer fired for some key. Two kinds, disambiguated by the Sub id:\n *\n * - retry timer → re-run the gate for that key's remembered input,\n * re-checking the circuit + bucket at THIS time.\n * - deadline timer → the overall budget elapsed → settle `failed` with a\n * deadline error, no matter the current phase.\n *\n * A timer for a key no longer `waiting_retry` (retry) / no longer in flight\n * (deadline) is a no-op — the reconcile pass races the result; the verb must\n * tolerate a stale fire. PURE.\n */\n function onTimer(\n s: ResilientState<I, R>,\n msg: ResilientTimerMsg,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n for (const [key, call] of Object.entries(s.calls)) {\n if (msg.id === retryTimerId(key)) {\n if (call.phase !== \"waiting_retry\") return [s, []];\n return gate(s, key, call.input, msg.atMs, call.deadlineAtMs);\n }\n if (msg.id === deadlineTimerId(key)) {\n // Deadline only fires for a still-active call. A settled call has no\n // armed deadline Sub, but tolerate a stale fire defensively.\n if (call.phase !== \"running\" && call.phase !== \"waiting_retry\")\n return [s, []];\n // Plain-data sentinel, NOT a `new Error(...)`: an Error object is not\n // JSON-serializable (it round-trips to `{}`) and captures a stack trace,\n // both of which break the slice's durability invariant once it is\n // persisted into a `Store<S>` and reloaded. A `{_tag, ...}` record keeps\n // the slice round-trip-equal under JSON.parse(JSON.stringify(...)).\n return [\n setCall(s, key, {\n phase: \"failed\",\n error: {\n _tag: \"deadline_exceeded\",\n id: msg.id,\n atMs: msg.atMs,\n } satisfies DeadlineExceededError,\n }),\n [],\n ];\n }\n }\n return [s, []];\n }\n\n // === Subs ================================================================\n\n /**\n * Pre-wired subscriptions: a retry timer for every `waiting_retry` call, and\n * (when the `deadline` brick is configured) an overall deadline timer for\n * every still-active call. Both are `DeadlineSub`s reconciled by id, so a\n * phase change cancels the matching timer automatically — no manual\n * `clearTimeout`. Wire `subscribe: { deadline: subscribeDeadline }`.\n */\n function subs(s: ResilientState<I, R>): readonly DeadlineSub[] {\n const out: DeadlineSub[] = [];\n for (const [key, call] of Object.entries(s.calls)) {\n if (call.phase === \"waiting_retry\") {\n out.push(deadlineSub(retryTimerId(key), call.retryAtMs));\n }\n if (\n config.deadline !== undefined &&\n (call.phase === \"running\" || call.phase === \"waiting_retry\") &&\n call.deadlineAtMs > 0\n ) {\n out.push(deadlineSub(deadlineTimerId(key), call.deadlineAtMs));\n }\n }\n return out;\n }\n\n // === Handlers ============================================================\n\n /**\n * Pre-wired interpret handler for `resilient_run`. Wraps the consumer's\n * `run` port via `tryInterpret` (Railway): success → `resilient_ok`, failure\n * → `resilient_err`, each stamped with `Date.now()` at the effect boundary —\n * the ONE permitted clock read (interpret is impure; the reducer never reads\n * the clock). Assign to the machine's `interpret`:\n *\n * interpret: rc.handlers({ run: (input, key) => ctx.callBackend(input) })\n */\n function handlers(ports: ResilientPorts<I, R>) {\n return {\n resilient_run: tryInterpret<\n RunCmd<I>,\n R,\n SucceedMsg<R> | FailMsg,\n // The work fn reads nothing from ctx — it forwards `cmd.input` to the\n // consumer-supplied `run` port. `NoCtx` (not `unknown`) marks this as a\n // DELIBERATE context-free seam, so callers see intent, not looseness.\n NoCtx\n >(\n (cmd) => ports.run(cmd.input, cmd.key),\n (result, cmd): SucceedMsg<R> => ({\n type: MsgType.ResilientOk,\n key: cmd.key,\n result,\n at: Date.now(),\n }),\n (error, cmd): FailMsg => ({\n type: MsgType.ResilientErr,\n key: cmd.key,\n error,\n at: Date.now(),\n }),\n ),\n };\n }\n\n return {\n init,\n attempt,\n succeed,\n fail,\n settleFailed,\n onTimer,\n subs,\n handlers,\n };\n}\n\n/**\n * Lift a knob result `[slice, cmds]` into a host `[State, cmds]` where the\n * slice lives at `state.resilience`. A convenience for the common single-slice\n * host; consumers with a differently-named field spread by hand. Pure — a thin\n * record rebuild, no clock / RNG.\n *\n * @deprecated Use `withResilience` from `@demlik/tea/with-resilience` — the\n * wrapper owns `model.$resilience`, so there is nothing to lift; see the\n * migration map at the top of this module.\n */\nexport function liftResilience<\n S extends { resilience: ResilientState<I, R> },\n I,\n R,\n C extends Cmd,\n>(\n state: S,\n [slice, cmds]: readonly [ResilientState<I, R>, readonly C[]],\n): readonly [S, readonly C[]] {\n return [{ ...state, resilience: slice }, cmds];\n}\n\n/**\n * Re-export the deadline Sub primitives so consumers (and tests) wire one\n * import: `subscribeDeadline` is the `subscribe` cell, `deadlineSub` builds the\n * Sub literal this knob's `subs` emits.\n */\nexport { subscribeDeadline, deadlineSub };\nexport type { DeadlineSub, DeadlineExceeded };\n"]}
1
+ {"version":3,"sources":["../src/resilient-call/index.ts"],"names":[],"mappings":"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","file":"chunk-4KLG43GY.js","sourcesContent":["/**\n * @packageDocumentation\n *\n * @deprecated `@demlik/tea/resilient-call` is deprecated in favor of\n * `@demlik/tea/with-resilience` — the higher-order `withResilience(base,\n * config)` wrapper (TEA-idiomatic: it wraps any existing machine instead of\n * forcing a bespoke embedded slice; epic consolidation verdict, survivor\n * `with-resilience`). The APIs are NOT drop-in; migration map:\n *\n * - `createResilientCall(config, rng)` + hand-wiring `init` / the verbs /\n * `subs` / `handlers` into your machine → `withResilience(base, { target,\n * ...bricks }, rng)`. Nothing is wired by hand anymore: the wrapper\n * intercepts the `target` base Cmd and routes it through the gate.\n * - `ResilientConfig` bricks (`retry` / `circuit` / `rateLimit` / `cache` /\n * `deadline`) → unchanged; `ResilienceConfig` extends the same knob and\n * adds `target` (required), `keyOf?` (per-call key — was `attempt`'s `key`\n * argument), and `at?` (time-as-data reader — REQUIRED with any\n * time-sensitive brick; `withResilience` throws at construction without it).\n * - The slice at your chosen Model field + `liftResilience` → the wrapper\n * owns `model.$resilience`; there is nothing to lift.\n * - Verbs `attempt` / `succeed` / `fail` / `onTimer` → internal to the\n * wrapper; results route as `$resilience:ok` / `$resilience:err` /\n * `$resilience:timer` Msgs through the merged `update` (the old\n * `resilient_run` / `resilient_ok` / `resilient_err` vocabulary is renamed\n * into the `$resilience:` namespace).\n * - `settleFailed` → NO equivalent. It exists for embedded-slice consumers\n * (`authed-call`, `paginated-walk`) that settle a call without touching the\n * breaker; the wrapper exposes no caller-facing settle verb.\n * - `handlers(ports)` / `subs(state)` / the `subscribeDeadline` re-export →\n * handled by the wrapper; run the returned machine like any other.\n *\n * Removal window (\"deprecate, don't delete\"): the `./resilient-call` subpath\n * export survives one minor release after this deprecation ships, then is\n * removed. Internal sibling modules (`with-resilience` itself, `agent`,\n * `llm-call`, `authed-call`, `reconciler`, `paginated-walk`) intentionally keep\n * importing `../resilient-call` — the deprecation targets the PUBLISHED export,\n * not the module's internal role.\n *\n * @demlik/tea/resilient-call — the ROOT composition: a single resilience knob\n * that bundles cache → circuit-breaker → rate-limit → exponential-backoff retry\n * (with a deadline-driven retry timer) around any fallible `(input) => Promise`\n * port.\n *\n * This is `examples/resilient-fetch.ts`'s hand-wired `attempt()` generalized:\n *\n * - It is **keyed**. The example tracked one URL at a time; this tracks N\n * concurrent logical calls, each under a string `key`. The cache, the\n * waiting-retry bookkeeping, and the retry timers are all per-key, while the\n * circuit breaker and token bucket are shared (one downstream target, one\n * breaker / one bucket — the example's implicit single-target assumption\n * made explicit).\n * - It is **config-driven**, not hand-wired. You hand `createResilientCall`\n * a `ResilientConfig` and get back the uniform knob contract every L2\n * composition exposes: `init()`, the four verbs (`attempt` / `succeed` /\n * `fail` / `onTimer`), `subs(state)`, and `handlers(ports)`.\n * - Every brick is **optional**. Omit `cache` and the cache gate disappears\n * (`get` is never consulted); omit `circuit` and every call passes the\n * breaker; omit `rateLimit` and the bucket never throttles; omit `retry`\n * and a failure is terminal (no backoff, no timer); omit `deadline` and no\n * overall wall-clock cap is armed. \"Omit a brick → omit its gate\" is the\n * whole config story — there are no other modes.\n *\n * Four later compositions (`llm-call`, `paginated-walk`, `authed-call`,\n * `reconciler`) inherit THIS slice + verb shape, so the contract here is\n * load-bearing: the slice is a flat record of brick states, every verb returns\n * `readonly [State, Cmd[]]`, time is always an `at` / `now` parameter, and the\n * RNG used for jitter is injected on the config (never read inside a verb).\n *\n * ## The two non-negotiables (canon)\n *\n * - **Durable** — the slice is a plain-data Model field (brick states are all\n * JSON-serializable), so it survives DO eviction / reload.\n * - **Replayable** — every transition is a verb returning new state + Cmds;\n * `replay` reconstructs it exactly. Nothing here closes over time or RNG.\n *\n * ## Where the clock / RNG live\n *\n * Inside the verbs: nowhere. Time arrives as `at` on `attempt` / `onTimer` and\n * is carried on the result / timer Msgs the consumer dispatches. Jitter RNG is\n * injected once at `createResilientCall(config, rng)` and threaded into\n * `nextDelayMs` at the verb boundary — deterministic in tests, `Math.random`\n * by default. The ONLY clock read is `Date.now()` inside the `handlers` port\n * (the effect boundary), exactly as `resilient-fetch.ts` stamps its result Msgs.\n *\n * That same `at` is what makes a DURATION-bounded retry budget reachable here:\n * `recordFailure` / `shouldRetry` are fed the failure's observation instant,\n * so `config.retry` accepts any `AnyRetryPolicy` — a count, a wall-clock outage\n * budget (`maxElapsedMs`), or explicit `unbounded: true` — with no new argument\n * on any verb and no clock read inside one.\n *\n * ## Typical wiring\n *\n * const rc = createResilientCall<string, Result>({\n * cache: { ttlMs: 60_000 },\n * circuit: { threshold: 5, cooldownMs: 30_000 },\n * rateLimit: { capacity: 10, refillPerSec: 5 },\n * retry: defaultRetryPolicy,\n * deadline: { ms: 5_000 },\n * });\n *\n * // in the machine:\n * init: () => [{ resilience: rc.init() }, []],\n * update: {\n * fetch: (s, m) => lift(s, rc.attempt(s.resilience, m.key, m.input, m.at)),\n * call_ok: (s, m) => lift(s, rc.succeed(s.resilience, m.key, m)),\n * call_err:(s, m) => lift(s, rc.fail(s.resilience, m.key, m)),\n * retry_due:(s, m) => lift(s, rc.onTimer(s.resilience, m)),\n * },\n * subscriptions: (s) => rc.subs(s.resilience),\n * subscribe: { deadline: subscribeDeadline },\n * interpret: rc.handlers({ run: ctx.call }),\n */\n\nimport {\n get as cacheGet,\n set as cacheSet,\n initCache,\n type TtlCache,\n} from \"../cache\";\nimport {\n type CircuitState,\n canPass,\n initCircuit,\n onFailure,\n onSuccess,\n} from \"../circuit-breaker\";\nimport {\n type DeadlineExceeded,\n type DeadlineSub,\n deadlineSub,\n subscribeDeadline,\n} from \"../deadline\";\nimport { type Cmd, type NoCtx, tryInterpret } from \"../index\";\nimport { MsgType } from \"../protocol\";\nimport { without } from \"../pure/core\";\nimport { initBucket, type TokenBucket, tryConsume } from \"../rate-limit\";\nimport {\n type AnyRetryPolicy,\n asRng,\n initRetry,\n nextDelayMs,\n type RetryState,\n recordFailure,\n shouldRetry,\n} from \"../retry-backoff\";\n\n// ===========================================================================\n// Config — the knob. Every brick optional; omit a brick → omit its gate.\n// ===========================================================================\n\n/** Circuit-breaker knob — only the two numbers a consumer ever tunes. */\nexport interface CircuitConfig {\n /** Consecutive failures that trip the breaker open. */\n readonly threshold: number;\n /** How long the breaker stays open before admitting a probe, in ms. */\n readonly cooldownMs: number;\n /**\n * Probes admitted in `half_open` before fast-failing the rest of the round.\n * Defaults to 1 (a single probe decides recovery) — matches the circuit-\n * breaker module's `defaultCircuitPolicy`.\n */\n readonly halfOpenMaxProbes?: number;\n}\n\n/** Token-bucket rate-limit knob. */\nexport interface RateLimitConfig {\n /** Burst size — the bucket starts full at `capacity`. */\n readonly capacity: number;\n /** Steady-state refill rate, tokens per second. */\n readonly refillPerSec: number;\n}\n\n/** Per-entry TTL cache knob. */\nexport interface CacheConfig {\n /** How long a cached success stays fresh, in ms. */\n readonly ttlMs: number;\n}\n\n/** Overall wall-clock deadline knob — an absolute cap per in-flight call. */\nexport interface DeadlineConfig {\n /** Budget from the moment a call starts, in ms. */\n readonly ms: number;\n}\n\n/**\n * The resilience knob. EVERY field is optional: omit a brick and its gate is\n * skipped entirely (the slice still carries a default brick state so the shape\n * stays uniform across configs, but the gate is never consulted). An empty\n * config `{}` is a valid pass-through — a bare effect with no resilience at all.\n */\nexport interface ResilientConfig {\n /**\n * The backoff brick. Omit and a failure is terminal (no backoff, no timer).\n *\n * Any bound the `../retry-backoff` union admits: a count (`RetryPolicy`), a\n * wall-clock outage budget (`DurationRetryPolicy`), or explicit\n * `unbounded: true`. A duration bound needs no extra wiring: every path that\n * records a failure already holds the instant it was observed as DATA —\n * `fail`'s `msg.at` (stamped at the interpret boundary) and `gate`'s `at`\n * (the caller's `attempt` / the retry timer's `atMs`) — so the streak clock\n * is fed from a Msg, never from a `Date.now()` inside a verb (invariant 2).\n */\n readonly retry?: AnyRetryPolicy;\n readonly circuit?: CircuitConfig;\n readonly rateLimit?: RateLimitConfig;\n readonly cache?: CacheConfig;\n readonly deadline?: DeadlineConfig;\n}\n\n// ===========================================================================\n// Slice — the Model field this knob owns. A flat record of brick states.\n// ===========================================================================\n\n/**\n * Per-key call phase. `key` indexes a logical call; several can be in flight at\n * once (the generalization of the example's single `url`). Discriminated on\n * `phase` so each phase carries only its own data (pattern 11):\n *\n * - `idle` — never attempted, or fully settled and forgotten.\n * - `running` — the effect Cmd is out; awaiting `succeed` / `fail`.\n * Carries `deadlineAtMs` (absolute cap, `0` if no deadline\n * brick) and the last `input` so a retry can re-issue it.\n * - `waiting_retry` — a transient failure backed off; the retry timer is armed\n * for `retryAtMs`. Carries `input` for the re-attempt.\n * - `circuit_open` — the breaker fast-failed this attempt. Terminal for this\n * call until the consumer re-attempts after cooldown.\n * - `succeeded` — settled OK. `result` is the value the port produced.\n * - `failed` — settled Err (out of retries, or no retry brick). `error`\n * carries the last failure.\n */\nexport type CallPhase<I, R> =\n | { readonly phase: \"idle\" }\n | {\n readonly phase: \"running\";\n readonly input: I;\n readonly deadlineAtMs: number;\n }\n | {\n readonly phase: \"waiting_retry\";\n readonly input: I;\n readonly retryAtMs: number;\n readonly deadlineAtMs: number;\n }\n | { readonly phase: \"circuit_open\" }\n | { readonly phase: \"succeeded\"; readonly result: R }\n | { readonly phase: \"failed\"; readonly error: unknown };\n\n/**\n * The slice. `circuit` / `bucket` are SHARED across keys (one downstream target\n * → one breaker, one bucket). `retry` and `cache` are PER KEY (each logical call\n * has its own backoff count + cached result), as is the per-call `CallPhase`.\n * Every field is plain data → the whole slice serializes into a `Store<S>`.\n *\n * `retry` / `cache` keep a default brick value even when the corresponding\n * config brick is omitted, so the slice shape is identical regardless of which\n * bricks the consumer enabled — the verbs simply never consult the unused brick.\n */\nexport interface ResilientState<I, R> {\n readonly circuit: CircuitState;\n readonly bucket: TokenBucket;\n /**\n * Per-key backoff counter. Entries minted by `backoff` are `TimedRetryState`s\n * (they carry the streak's `firstFailureAtMs`, since every failure path holds\n * the observation instant); the field is typed at the `RetryState` supertype\n * because a key that has never failed has no streak, and a slice persisted\n * before the origin existed rehydrates without one. Still plain data.\n */\n readonly retry: Readonly<Record<string, RetryState>>;\n readonly cache: TtlCache<R>;\n readonly calls: Readonly<Record<string, CallPhase<I, R>>>;\n}\n\n// ===========================================================================\n// Cmds + Msgs the knob speaks. Generic over the port input `I`.\n// ===========================================================================\n\n/**\n * The one effect this knob emits: \"run the port for `key` with `input`\". The\n * consumer's `handlers(ports)` interprets it; it carries no closure — `input`\n * is plain data (invariant 3).\n */\nexport type RunCmd<I> = Cmd<typeof MsgType.ResilientRun> & {\n readonly key: string;\n readonly input: I;\n};\n\n/** Settle Msgs the `handlers` port dispatches back. `at` is stamped at the boundary. */\nexport type SucceedMsg<R> = {\n readonly type: typeof MsgType.ResilientOk;\n readonly key: string;\n readonly result: R;\n readonly at: number;\n};\nexport type FailMsg = {\n readonly type: typeof MsgType.ResilientErr;\n readonly key: string;\n readonly error: unknown;\n readonly at: number;\n};\n\n/** The retry / deadline timer Msg — `DeadlineExceeded`, keyed by the call `key`. */\nexport type ResilientTimerMsg = DeadlineExceeded;\n\n/**\n * The plain-data error a deadline-failed call settles with. A `{_tag, ...}`\n * sentinel — NEVER a `new Error(...)` — so the slice stays JSON-serializable\n * (Error objects round-trip to `{}` and carry a stack trace, both of which break\n * the slice's durability invariant). `id` / `atMs` echo the timer that fired so\n * a consumer can attribute the failure to its deadline.\n */\nexport type DeadlineExceededError = {\n readonly _tag: \"deadline_exceeded\";\n readonly id: string;\n readonly atMs: number;\n};\n\n/** Ports the consumer supplies to `handlers`. */\nexport interface ResilientPorts<I, R> {\n /** The fallible work this knob wraps. Throws on failure → routed to `fail`. */\n readonly run: (input: I, key: string) => Promise<R>;\n}\n\n// ===========================================================================\n// Internal brick-policy derivation — config → the L1 policy shapes.\n// ===========================================================================\n\n// A circuit policy is only built when the brick is configured; absence is\n// represented as `null` so the gate can short-circuit to \"always pass\".\nfunction circuitPolicy(config: ResilientConfig) {\n if (config.circuit === undefined) return null;\n return {\n failureThreshold: config.circuit.threshold,\n cooldownMs: config.circuit.cooldownMs,\n halfOpenMaxProbes: config.circuit.halfOpenMaxProbes ?? 1,\n };\n}\n\n// Sub-id families. Each call's retry timer is a deadline keyed by `key`, so a\n// machine running many concurrent calls reconciles each independently.\nfunction retryTimerId(key: string): string {\n return `resilient:retry:${key}`;\n}\nfunction deadlineTimerId(key: string): string {\n return `resilient:deadline:${key}`;\n}\n\n// ===========================================================================\n// The knob factory.\n// ===========================================================================\n\n/**\n * Build a resilient-call knob from `config`. `rng` is injected for retry\n * jitter — pass a fixed `() => 0.5` in tests to pin backoff; defaults to\n * `Math.random` (read at the verb boundary, never inside a brick op). It is\n * curried onto the factory rather than threaded through every verb so callers\n * spell the determinism choice once.\n *\n * Returns the uniform L2 knob contract. `I` is the port input type, `R` the\n * port result type.\n *\n * @deprecated Use `withResilience` from `@demlik/tea/with-resilience` — not\n * drop-in; see the migration map at the top of this module.\n */\nexport function createResilientCall<I, R>(\n config: ResilientConfig,\n rng: () => number = Math.random,\n) {\n const cPolicy = circuitPolicy(config);\n // Re-affirm the `[0, 1)` contract at the seam where the injected generator\n // feeds the backoff math (brand from `../retry-backoff`). The factory's\n // public param stays a plain `() => number` so transitive callers are\n // unchanged; `asRng` is the single point it's branded for `nextDelayMs`.\n const rngBranded = asRng(rng);\n\n /** The starting slice. Bricks not in `config` still get a default value. */\n function init(): ResilientState<I, R> {\n return {\n circuit: initCircuit(),\n // The bucket carries a default value even without the rateLimit brick so\n // the slice shape is uniform, but the rate-limit GATE is skipped entirely\n // when the brick is absent (see `gate`) — the bucket is simply never\n // consulted. A `0/0` placeholder bucket would be touched by `tryConsume`;\n // a `1-cap` default is harmless because the gate never calls it.\n bucket: config.rateLimit\n ? initBucket(\n config.rateLimit.capacity,\n config.rateLimit.refillPerSec,\n 0,\n )\n : initBucket(1, 1, 0),\n retry: {},\n cache: initCache<R>(),\n calls: {},\n };\n }\n\n /** Read this key's retry state, defaulting to a fresh one. */\n function retryOf(s: ResilientState<I, R>, key: string): RetryState {\n return s.retry[key] ?? initRetry();\n }\n\n /** Compute the absolute deadline for a call starting at `at` (0 = no cap). */\n function deadlineAt(at: number): number {\n return config.deadline ? at + config.deadline.ms : 0;\n }\n\n /**\n * The shared decision: cache → rate-limit → circuit gate, then either emit\n * the effect or schedule a retry. `deadlineAtMs` is threaded so a re-attempt\n * (from `onTimer`) keeps the ORIGINAL overall deadline rather than restarting\n * it. PURE — `at` is the only clock; `rng` is the injected jitter source.\n *\n * Used by both `attempt` (fresh call) and `onTimer` (retry timer fired) so\n * the gate logic lives in exactly one place — the example's shared `attempt`\n * helper, lifted to a keyed knob.\n *\n * ## Why rate-limit is gated BEFORE the circuit probe\n *\n * The circuit-breaker's `canPass` is not a passive read: in `half_open` it\n * *consumes* a probe slot (advancing `probes`), and the consumed slot is only\n * released when a probe RESOLVES via `onSuccess` / `onFailure`. So a probe\n * slot may only be taken when this attempt is actually going to reach the\n * backend (i.e. emit the `resilient_run` Cmd). The rate-limit gate can reject\n * an attempt and return a backoff WITHOUT any Cmd — no backend call, so no\n * settle Msg ever comes back. If the circuit probe were consumed first, that\n * rate-limited attempt would burn the half-open probe budget on a call that\n * never happened, wedging the breaker `half_open` at its probe cap forever\n * (nothing moves it out of `half_open` but a resolved probe). Running the\n * rate-limit gate first means the circuit probe is consumed ONLY on the path\n * that emits the effect.\n */\n function gate(\n s: ResilientState<I, R>,\n key: string,\n input: I,\n at: number,\n deadlineAtMs: number,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n // 1) Serve from cache if fresh — no effect at all. Skipped when no cache brick.\n if (config.cache !== undefined) {\n const cached = cacheGet(s.cache, key, at);\n if (cached !== undefined) {\n return [setCall(s, key, { phase: \"succeeded\", result: cached }), []];\n }\n }\n\n // 2) Rate-limit gate FIRST — it may reject with no Cmd, so it must run\n // before any circuit probe is consumed (see header note). Skipped entirely\n // when no rateLimit brick — the bucket is never consulted, so the default\n // placeholder bucket stays untouched.\n let bucket = s.bucket;\n if (config.rateLimit !== undefined) {\n const [next, hasToken] = tryConsume(bucket, at);\n bucket = next;\n if (!hasToken) {\n // Rate-limited: treat as a transient failure and back off via retry.\n // The circuit is untouched — no probe is spent on a call that never ran.\n return backoff(\n { ...s, bucket },\n key,\n input,\n \"rate_limited\",\n at,\n deadlineAtMs,\n );\n }\n }\n\n // 3) Circuit-breaker gate. `null` policy → no breaker → always pass. Reached\n // only once a token is secured, so a half-open probe is consumed exclusively\n // on the path that emits the effect below.\n let circuit = s.circuit;\n if (cPolicy !== null) {\n const [next, ok] = canPass(circuit, cPolicy, at);\n circuit = next;\n if (!ok) {\n return [\n { ...setCall(s, key, { phase: \"circuit_open\" }), bucket, circuit },\n [],\n ];\n }\n }\n\n // 4) All gates passed — emit the effect as data.\n return [\n {\n ...setCall(s, key, { phase: \"running\", input, deadlineAtMs }),\n circuit,\n bucket,\n },\n [{ type: MsgType.ResilientRun, key, input }],\n ];\n }\n\n /**\n * Back off after a transient failure: record it, and if `retry` permits\n * another attempt, enter `waiting_retry` with the retry timer armed; else\n * settle `failed`. When no `retry` brick is configured the call fails on the\n * first failure (no backoff, no timer). PURE.\n *\n * `at` is both the backoff anchor AND the streak clock: it is passed to\n * `recordFailure` (which starts `firstFailureAtMs` on the streak's first\n * failure and preserves it on every later one) and to `shouldRetry`, so a\n * `DurationRetryPolicy` on `config.retry` is honoured with no extra wiring.\n * A success drops `retry[key]` entirely, which drops the origin with it —\n * only an unbroken run of failures grows toward a duration budget.\n */\n function backoff(\n s: ResilientState<I, R>,\n key: string,\n input: I,\n error: unknown,\n at: number,\n deadlineAtMs: number,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n if (config.retry === undefined) {\n return [setCall(s, key, { phase: \"failed\", error }), []];\n }\n const retry = recordFailure(retryOf(s, key), error, at);\n const withRetry = { ...s, retry: { ...s.retry, [key]: retry } };\n if (!shouldRetry(retry, config.retry, at)) {\n return [setCall(withRetry, key, { phase: \"failed\", error }), []];\n }\n const retryAtMs = at + nextDelayMs(retry, config.retry, rngBranded);\n return [\n setCall(withRetry, key, {\n phase: \"waiting_retry\",\n input,\n retryAtMs,\n deadlineAtMs,\n }),\n [],\n ];\n }\n\n // Set the phase for one key, leaving every other field untouched.\n function setCall(\n s: ResilientState<I, R>,\n key: string,\n phase: CallPhase<I, R>,\n ): ResilientState<I, R> {\n return { ...s, calls: { ...s.calls, [key]: phase } };\n }\n\n // === Verb: attempt =======================================================\n\n /**\n * Start (or restart) the call for `key` with `input` at time `at`. Runs the\n * cache → circuit → rate-limit gate and either emits the `resilient_run`\n * effect, schedules a retry, fast-fails (circuit open), or serves the cache.\n * PURE.\n */\n function attempt(\n s: ResilientState<I, R>,\n key: string,\n input: I,\n at: number,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n return gate(s, key, input, at, deadlineAt(at));\n }\n\n // === Verb: succeed =======================================================\n\n /**\n * Record a success for `key`: close the breaker, fill the cache (if a cache\n * brick exists), reset this key's retry count, and settle `succeeded`. PURE —\n * `msg.at` is the cache write clock.\n */\n function succeed(\n s: ResilientState<I, R>,\n key: string,\n msg: SucceedMsg<R>,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n const circuit =\n cPolicy !== null ? onSuccess(s.circuit, cPolicy) : s.circuit;\n const cache =\n config.cache !== undefined\n ? cacheSet(s.cache, key, msg.result, msg.at, config.cache.ttlMs)\n : s.cache;\n // Drop this key's retry counter — a success ends the retry run.\n const retry = without(s.retry, key);\n return [\n {\n ...setCall(s, key, { phase: \"succeeded\", result: msg.result }),\n circuit,\n cache,\n retry,\n },\n [],\n ];\n }\n\n // === Verb: fail ==========================================================\n\n /**\n * Record a failure for `key`: trip the breaker (it may open), then back off —\n * schedule a retry if `retry` permits, else settle `failed`. PURE — `msg.at`\n * stamps the breaker trip + the retry delay base. Re-issues from the call's\n * remembered `input` and preserves the original overall `deadlineAtMs`.\n */\n function fail(\n s: ResilientState<I, R>,\n key: string,\n msg: FailMsg,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n const circuit =\n cPolicy !== null ? onFailure(s.circuit, cPolicy, msg.at) : s.circuit;\n const withCircuit = { ...s, circuit };\n const call = s.calls[key];\n const input = call?.phase === \"running\" ? call.input : undefined;\n const deadlineAtMs =\n call?.phase === \"running\" ? call.deadlineAtMs : deadlineAt(msg.at);\n // No remembered input (e.g. a stray fail for a key not running) → just\n // settle failed after tripping the breaker; nothing to re-issue.\n if (input === undefined) {\n return [\n setCall(withCircuit, key, { phase: \"failed\", error: msg.error }),\n [],\n ];\n }\n return backoff(withCircuit, key, input, msg.error, msg.at, deadlineAtMs);\n }\n\n // === Verb: settleFailed ==================================================\n\n /**\n * Settle `key` to terminal `failed` with `error` WITHOUT touching the circuit\n * breaker or this key's retry counter. PURE.\n *\n * This is the verb for a failure that is NOT a downstream-health signal: the\n * call must end now, but the breaker must not trip and the backoff run must\n * not advance. `fail` is the opposite — it records the failure against the\n * breaker (it may open) and feeds the retry policy (it may back off). Use\n * `settleFailed` when the *reason* the call cannot proceed has nothing to do\n * with downstream health:\n *\n * - `authed-call` settles a 401 it cannot fix (e.g. the refresh budget is\n * spent): a bad token is the caller's problem, not the backend's —\n * tripping the breaker on it would punish a healthy target, and backing\n * off would just retry a request that will 401 again.\n * - `paginated-walk` settles a terminal walk error (e.g. a malformed page\n * the consumer rejects) that should stop the walk without poisoning the\n * shared breaker the next page fetch passes through.\n *\n * Because it leaves `circuit` and `retry[key]` untouched, the breaker keeps\n * its health view of the actual backend and a later `attempt` for this key\n * starts a fresh retry run. Both sibling knobs previously hand-rolled this by\n * splicing `calls` directly; this verb gives them one named, tested entry\n * point so the slice's settle invariants live in exactly one place.\n */\n function settleFailed(\n s: ResilientState<I, R>,\n key: string,\n error: unknown,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n return [setCall(s, key, { phase: \"failed\", error }), []];\n }\n\n // === Verb: onTimer =======================================================\n\n /**\n * A timer fired for some key. Two kinds, disambiguated by the Sub id:\n *\n * - retry timer → re-run the gate for that key's remembered input,\n * re-checking the circuit + bucket at THIS time.\n * - deadline timer → the overall budget elapsed → settle `failed` with a\n * deadline error, no matter the current phase.\n *\n * A timer for a key no longer `waiting_retry` (retry) / no longer in flight\n * (deadline) is a no-op — the reconcile pass races the result; the verb must\n * tolerate a stale fire. PURE.\n */\n function onTimer(\n s: ResilientState<I, R>,\n msg: ResilientTimerMsg,\n ): readonly [ResilientState<I, R>, readonly RunCmd<I>[]] {\n for (const [key, call] of Object.entries(s.calls)) {\n if (msg.id === retryTimerId(key)) {\n if (call.phase !== \"waiting_retry\") return [s, []];\n return gate(s, key, call.input, msg.atMs, call.deadlineAtMs);\n }\n if (msg.id === deadlineTimerId(key)) {\n // Deadline only fires for a still-active call. A settled call has no\n // armed deadline Sub, but tolerate a stale fire defensively.\n if (call.phase !== \"running\" && call.phase !== \"waiting_retry\")\n return [s, []];\n // Plain-data sentinel, NOT a `new Error(...)`: an Error object is not\n // JSON-serializable (it round-trips to `{}`) and captures a stack trace,\n // both of which break the slice's durability invariant once it is\n // persisted into a `Store<S>` and reloaded. A `{_tag, ...}` record keeps\n // the slice round-trip-equal under JSON.parse(JSON.stringify(...)).\n return [\n setCall(s, key, {\n phase: \"failed\",\n error: {\n _tag: \"deadline_exceeded\",\n id: msg.id,\n atMs: msg.atMs,\n } satisfies DeadlineExceededError,\n }),\n [],\n ];\n }\n }\n return [s, []];\n }\n\n // === Subs ================================================================\n\n /**\n * Pre-wired subscriptions: a retry timer for every `waiting_retry` call, and\n * (when the `deadline` brick is configured) an overall deadline timer for\n * every still-active call. Both are `DeadlineSub`s reconciled by id, so a\n * phase change cancels the matching timer automatically — no manual\n * `clearTimeout`. Wire `subscribe: { deadline: subscribeDeadline }`.\n */\n function subs(s: ResilientState<I, R>): readonly DeadlineSub[] {\n const out: DeadlineSub[] = [];\n for (const [key, call] of Object.entries(s.calls)) {\n if (call.phase === \"waiting_retry\") {\n out.push(deadlineSub(retryTimerId(key), call.retryAtMs));\n }\n if (\n config.deadline !== undefined &&\n (call.phase === \"running\" || call.phase === \"waiting_retry\") &&\n call.deadlineAtMs > 0\n ) {\n out.push(deadlineSub(deadlineTimerId(key), call.deadlineAtMs));\n }\n }\n return out;\n }\n\n // === Handlers ============================================================\n\n /**\n * Pre-wired interpret handler for `resilient_run`. Wraps the consumer's\n * `run` port via `tryInterpret` (Railway): success → `resilient_ok`, failure\n * → `resilient_err`, each stamped with `Date.now()` at the effect boundary —\n * the ONE permitted clock read (interpret is impure; the reducer never reads\n * the clock). Assign to the machine's `interpret`:\n *\n * interpret: rc.handlers({ run: (input, key) => ctx.callBackend(input) })\n */\n function handlers(ports: ResilientPorts<I, R>) {\n return {\n resilient_run: tryInterpret<\n RunCmd<I>,\n R,\n SucceedMsg<R> | FailMsg,\n // The work fn reads nothing from ctx — it forwards `cmd.input` to the\n // consumer-supplied `run` port. `NoCtx` (not `unknown`) marks this as a\n // DELIBERATE context-free seam, so callers see intent, not looseness.\n NoCtx\n >(\n (cmd) => ports.run(cmd.input, cmd.key),\n (result, cmd): SucceedMsg<R> => ({\n type: MsgType.ResilientOk,\n key: cmd.key,\n result,\n at: Date.now(),\n }),\n (error, cmd): FailMsg => ({\n type: MsgType.ResilientErr,\n key: cmd.key,\n error,\n at: Date.now(),\n }),\n ),\n };\n }\n\n return {\n init,\n attempt,\n succeed,\n fail,\n settleFailed,\n onTimer,\n subs,\n handlers,\n };\n}\n\n/**\n * Lift a knob result `[slice, cmds]` into a host `[State, cmds]` where the\n * slice lives at `state.resilience`. A convenience for the common single-slice\n * host; consumers with a differently-named field spread by hand. Pure — a thin\n * record rebuild, no clock / RNG.\n *\n * @deprecated Use `withResilience` from `@demlik/tea/with-resilience` — the\n * wrapper owns `model.$resilience`, so there is nothing to lift; see the\n * migration map at the top of this module.\n */\nexport function liftResilience<\n S extends { resilience: ResilientState<I, R> },\n I,\n R,\n C extends Cmd,\n>(\n state: S,\n [slice, cmds]: readonly [ResilientState<I, R>, readonly C[]],\n): readonly [S, readonly C[]] {\n return [{ ...state, resilience: slice }, cmds];\n}\n\n/**\n * Re-export the deadline Sub primitives so consumers (and tests) wire one\n * import: `subscribeDeadline` is the `subscribe` cell, `deadlineSub` builds the\n * Sub literal this knob's `subs` emits.\n */\nexport { subscribeDeadline, deadlineSub };\nexport type { DeadlineSub, DeadlineExceeded };\n"]}
@@ -1,8 +1,8 @@
1
- import { describeChart, describeReducerChart, inspectState, inspectReducerState, captureCmds } from './chunk-ZD6PNZBK.js';
2
- import { compile, initFrom, compileReducer, reducerInitFrom, chartMermaid, reducerMermaid } from './chunk-E6GEDSF4.js';
1
+ import { describeChart, describeReducerChart, inspectState, inspectReducerState, captureCmds } from './chunk-3ZAFFRRB.js';
2
+ import { compile, initFrom, compileReducer, reducerInitFrom, chartMermaid, reducerMermaid } from './chunk-YWIKDKHY.js';
3
3
  import { recorder } from './chunk-MUUROGIH.js';
4
+ import { run, replay } from './chunk-ZSUUOEPL.js';
4
5
  import { useMsgHistory, StateInspector, StateDiff, MsgLog } from './chunk-WRAA7GVZ.js';
5
- import { run, replay } from './chunk-5EHLEUTL.js';
6
6
  import { useMemo, useState, useEffect, useReducer, useRef } from 'react';
7
7
  import { jsx, jsxs } from 'react/jsx-runtime';
8
8
 
@@ -45,7 +45,11 @@ function ChartInspector(props) {
45
45
  }),
46
46
  [chart, parts, boot]
47
47
  );
48
- const { rt, rec } = useInspectorRuntime(machine, ctx, epoch);
48
+ const { rt, rec } = useInspectorRuntime(
49
+ machine,
50
+ ctx,
51
+ epoch
52
+ );
49
53
  const desc = useMemo(() => describeChart(chart), [chart]);
50
54
  const view = useMemo(
51
55
  () => gridView(desc, chart, parts, props.title, props.direction),
@@ -82,7 +86,11 @@ function ReducerChartInspector(props) {
82
86
  }),
83
87
  [chart, parts, boot]
84
88
  );
85
- const { rt, rec } = useInspectorRuntime(machine, ctx, epoch);
89
+ const { rt, rec } = useInspectorRuntime(
90
+ machine,
91
+ ctx,
92
+ epoch
93
+ );
86
94
  const desc = useMemo(() => describeReducerChart(chart), [chart]);
87
95
  const view = useMemo(
88
96
  () => reducerView(desc, chart, parts),
@@ -412,5 +420,5 @@ function replayPrefix(machine, trace, ctx, n, live) {
412
420
  }
413
421
 
414
422
  export { ChartInspector, ReducerChartInspector, useInspectorRuntime };
415
- //# sourceMappingURL=chunk-JER5O7PQ.js.map
416
- //# sourceMappingURL=chunk-JER5O7PQ.js.map
423
+ //# sourceMappingURL=chunk-7FRZ2CT2.js.map
424
+ //# sourceMappingURL=chunk-7FRZ2CT2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chart/inspect/react.tsx"],"names":[],"mappings":";;;;;;;;AA8LO,SAAS,mBAAA,CAMd,OAAA,EAEA,GAAA,EACA,KAAA,EACqE;AAMrE,EAAA,MAAM,OAAA,GAAU,OAAA;AAAA,IACd,MAAM,GAAA,CAAI,OAAA,EAAS,EAAE,KAAK,CAAA;AAAA,IAC1B,CAAC,OAAA,EAAS,GAAA,EAAK,KAAK;AAAA,GACtB;AACA,EAAA,MAAM,GAAA,GAAM,QAAwB,MAAM,QAAA,CAAS,OAAO,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAKtE,EAAA,MAAM,CAAC,EAAA,EAAI,KAAK,CAAA,GAAI,SAA+B,IAAI,CAAA;AACvD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,IAAA,GAAO,IAAA;AACX,IAAA,KAAA,CAAM,IAAI,CAAA;AACV,IAAA,OAAA,CAAQ,KAAA,CAAM,IAAA;AAAA,MACZ,CAAC,CAAA,KAAM;AACL,QAAA,IAAI,IAAA,QAAY,CAAC,CAAA;AAAA,MACnB,CAAA;AAAA,MACA,MAAM;AAAA,MAAC;AAAA,KACT;AACA,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,GAAO,KAAA;AACP,MAAA,GAAA,CAAI,IAAA,EAAK;AACT,MAAA,OAAA,CAAQ,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM;AAAA,MAAC,CAAC,CAAA;AAAA,IAC/B,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,GAAG,CAAC,CAAA;AAEjB,EAAA,OAAO,EAAE,IAAI,GAAA,EAAI;AACnB;AAOO,SAAS,eAMd,KAAA,EAA0C;AAC1C,EAAA,MAAM,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,EAAM,KAAI,GAAI,KAAA;AAIpC,EAAA,MAAM,CAAC,OAAO,KAAK,CAAA,GAAI,WAAW,CAAC,CAAA,KAAc,CAAA,GAAI,CAAA,EAAG,CAAC,CAAA;AAEzD,EAAA,MAAM,OAAA,GAAU,OAAA;AAAA,IACd,OACG;AAAA,MACC,IAAA,EAAM,QAAA,CAAkB,KAAA,EAAO,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA,MAInC,MAAA,EAAQ,OAAA,CAAQ,KAAA,EAAO,KAAK;AAAA,KAC9B,CAAA;AAAA,IACF,CAAC,KAAA,EAAO,KAAA,EAAO,IAAI;AAAA,GACrB;AACA,EAAA,MAAM,EAAE,EAAA,EAAI,GAAA,EAAI,GAAI,mBAAA;AAAA,IAClB,OAAA;AAAA,IACA,GAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,IAAA,GAAO,QAAQ,MAAM,aAAA,CAAc,KAAK,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AACxD,EAAA,MAAM,IAAA,GAAO,OAAA;AAAA,IACX,MAAM,SAAS,IAAA,EAAM,KAAA,EAAO,OAAO,KAAA,CAAM,KAAA,EAAO,MAAM,SAAS,CAAA;AAAA,IAC/D,CAAC,IAAA,EAAM,KAAA,EAAO,OAAO,KAAA,CAAM,KAAA,EAAO,MAAM,SAAS;AAAA,GACnD;AAEA,EAAA,IAAI,OAAO,IAAA,EAAM;AACf,IAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,cAAA,CAAe,KAAA,CAAM,SAAS,CAAA,EAC5C,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EAAc,QAAA,EAAA,eAAA,EAAQ,CAAA,EACvC,CAAA;AAAA,EAEJ;AACA,EAAA,uBACE,GAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MAEC,IAAA;AAAA,MACA,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,OAAA,EAAS,EAAA;AAAA,MACT,GAAA;AAAA,MACA,OAAA;AAAA,MACA,GAAA;AAAA,MACA,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,OAAA,EAAS;AAAA,KAAA;AAAA,IATJ;AAAA,GAUP;AAEJ;AAYO,SAAS,sBAMd,KAAA,EAAiD;AACjD,EAAA,MAAM,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,EAAM,KAAI,GAAI,KAAA;AACpC,EAAA,MAAM,CAAC,OAAO,KAAK,CAAA,GAAI,WAAW,CAAC,CAAA,KAAc,CAAA,GAAI,CAAA,EAAG,CAAC,CAAA;AAEzD,EAAA,MAAM,OAAA,GAAU,OAAA;AAAA,IACd,OACG;AAAA,MACC,IAAA,EAAM,eAAA,CAAyB,KAAA,EAAO,IAAI,CAAA;AAAA;AAAA;AAAA,MAG1C,MAAA,EAAQ,cAAA,CAAe,KAAA,EAAO,KAAK;AAAA,KACrC,CAAA;AAAA,IACF,CAAC,KAAA,EAAO,KAAA,EAAO,IAAI;AAAA,GACrB;AACA,EAAA,MAAM,EAAE,EAAA,EAAI,GAAA,EAAI,GAAI,mBAAA;AAAA,IAClB,OAAA;AAAA,IACA,GAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,IAAA,GAAO,QAAQ,MAAM,oBAAA,CAAqB,KAAK,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAC/D,EAAA,MAAM,IAAA,GAAO,OAAA;AAAA,IACX,MAAM,WAAA,CAAY,IAAA,EAAM,KAAA,EAAO,KAAK,CAAA;AAAA,IACpC,CAAC,IAAA,EAAM,KAAA,EAAO,KAAK;AAAA,GACrB;AAEA,EAAA,IAAI,OAAO,IAAA,EAAM;AACf,IAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,cAAA,CAAe,KAAA,CAAM,SAAS,CAAA,EAC5C,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EAAc,QAAA,EAAA,eAAA,EAAQ,CAAA,EACvC,CAAA;AAAA,EAEJ;AACA,EAAA,uBACE,GAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MAEC,IAAA;AAAA,MACA,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,OAAA,EAAS,EAAA;AAAA,MACT,GAAA;AAAA,MACA,OAAA;AAAA,MACA,GAAA;AAAA,MACA,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,WAAW,KAAA,CAAM,SAAA;AAAA,MACjB,OAAA,EAAS;AAAA,KAAA;AAAA,IATJ;AAAA,GAUP;AAEJ;AAEA,SAAS,eAAe,KAAA,EAAmC;AACzD,EAAA,OAAO,CAAA,MAAA,EAAS,KAAA,GAAQ,CAAA,CAAA,EAAI,KAAK,KAAK,EAAE,CAAA,CAAA;AAC1C;AAgDA,SAAS,QAAA,CACP,IAAA,EACA,KAAA,EACA,KAAA,EACA,OACA,SAAA,EACa;AACb,EAAA,OAAO;AAAA,IACL,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,QAAA,EAAU,CAAC,KAAA,EAAO,OAAA,KAChB,YAAA,CAAa,IAAA,EAAM,KAAA,EAAO,EAAE,KAAA,EAAuB,OAAA,EAAS,CAAA,CAAE,GAAA;AAAA,MAC5D;AAAA,KACF;AAAA,IACF,OAAA,EAAS,CAAC,KAAA,KACR,YAAA,CAAa,KAAA,EAAgB;AAAA,MAC3B,WAAW,KAAA,CAAM,IAAA;AAAA,MACjB,MAAA,EAAQ,IAAA;AAAA,MACR,SAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,IACH,MAAA,EAAQ,CAAC,KAAA,KAAU;AACjB,MAAA,MAAM,IAAA,GAAO,KAAK,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,KAAA,CAAM,IAAI,CAAA;AAC1D,MAAA,OAAO;AAAA,QACL,GAAI,SAAS,MAAA,GAAY,KAAK,EAAE,KAAA,EAAO,KAAK,KAAA,EAAM;AAAA,QAClD,IAAA,EAAM;AAAA,UACJ,GAAI,IAAA,EAAM,GAAA,KAAQ,OAAO,CAAC,KAAK,IAAI,EAAC;AAAA,UACpC,GAAI,IAAA,EAAM,OAAA,KAAY,OAAO,CAAC,SAAS,IAAI;AAAC;AAC9C,OACF;AAAA,IACF,CAAA;AAAA,IACA,OAAO;AAAC,GACV;AACF;AAEA,SAAS,WAAA,CACP,IAAA,EACA,KAAA,EACA,KAAA,EACa;AACb,EAAA,OAAO;AAAA,IACL,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,UAAU,CAAC,KAAA,EAAO,OAAA,KAChB,mBAAA,CAAoB,MAAM,KAAA,EAAO;AAAA,MAC/B,KAAA;AAAA,MACA;AAAA,KACD,CAAA,CAAE,GAAA,CAAI,cAAc,CAAA;AAAA;AAAA;AAAA,IAGvB,OAAA,EAAS,MAAM,cAAA,CAAe,KAAc,CAAA;AAAA;AAAA,IAE5C,MAAA,EAAQ,OAAO,EAAE,IAAA,EAAM,EAAC,EAAE,CAAA;AAAA,IAC1B,OAAO,CAAC,IAAA,CAAK,QAAQ,IAAA,CAAK,QAAA,EAAU,KAAK,KAAK;AAAA,GAChD;AACF;AAGA,SAAS,YAAY,CAAA,EAA+B;AAClD,EAAA,MAAM,OAAA,GAAU,EAAE,MAAA,KAAW,SAAA;AAC7B,EAAA,OAAO;AAAA,IACL,OAAO,CAAA,CAAE,KAAA;AAAA,IACT,IAAA,EAAM,OAAA,GAAW,CAAA,CAAE,MAAA,EAAQ,QAAQ,YAAA,GAAgB,OAAA;AAAA,IACnD,OAAA;AAAA,IACA,GAAI,EAAE,GAAA,KAAQ,MAAA,GAAY,EAAC,GAAI,EAAE,GAAA,EAAK,CAAA,CAAE,GAAA,EAAI;AAAA,IAC5C,OAAA,EAAS,gBAAgB,CAAC,CAAA;AAAA,IAC1B,GAAI,EAAE,GAAA,KAAQ,MAAA,GAAY,EAAC,GAAI,EAAE,GAAA,EAAK,CAAA,CAAE,GAAA;AAAI,GAC9C;AACF;AAIA,SAAS,eAAe,CAAA,EAAsC;AAC5D,EAAA,OAAO;AAAA,IACL,OAAO,CAAA,CAAE,KAAA;AAAA,IACT,IAAA,EAAM,OAAA;AAAA,IACN,OAAA,EAAS,KAAA;AAAA,IACT,OAAA,EAAS,gBAAgB,CAAC,CAAA;AAAA,IAC1B,GAAI,EAAE,GAAA,KAAQ,MAAA,GAAY,EAAC,GAAI,EAAE,GAAA,EAAK,CAAA,CAAE,GAAA;AAAI,GAC9C;AACF;AAsBA,SAAS,aAAA,CAMP;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAA+B;AAG7B,EAAA,MAAM,CAAC,MAAM,IAAI,CAAA,GAAI,WAAW,CAAC,CAAA,KAAc,CAAA,GAAI,CAAA,EAAG,CAAC,CAAA;AACvD,EAAA,SAAA,CAAU,MAAM,OAAA,CAAQ,SAAA,CAAU,IAAI,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAClD,EAAA,MAAM,SAAA,GAAY,QAAQ,QAAA,EAAS;AAInC,EAAA,MAAM,CAAC,OAAA,EAAS,IAAI,CAAA,GAAI,aAAA,CAAiB,QAAQ,QAAQ,CAAA;AAIzD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,QAAA;AAAA,IAA2C,MACrE,UAAA,CAAW,IAAA,CAAK,MAAA,EAAQ,OAAO;AAAA,GACjC;AACA,EAAA,MAAM,SAAA,GAAY,QAAQ,MAAM,WAAA,CAAY,MAAM,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAI7D,EAAA,MAAM,CAAC,EAAA,EAAI,KAAK,CAAA,GAAI,SAAwB,IAAI,CAAA;AAChD,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,EAAK,SAAS,CAAA;AACrC,EAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,MAAA;AACzB,EAAA,MAAM,SAAS,EAAA,KAAO,IAAA,GAAO,QAAQ,IAAA,CAAK,GAAA,CAAI,IAAI,KAAK,CAAA;AACvD,EAAA,MAAM,QAAA,GAAW,EAAA,KAAO,IAAA,IAAQ,MAAA,GAAS,KAAA;AAEzC,EAAA,MAAM,QAAQ,YAAA,CAAa,OAAA,EAAS,KAAA,EAAO,GAAA,EAAK,QAAQ,SAAS,CAAA;AACjE,EAAA,MAAM,QAAA,GAAW,YAAA;AAAA,IACf,OAAA;AAAA,IACA,KAAA;AAAA,IACA,GAAA;AAAA,IACA,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAA,GAAS,CAAC,CAAA;AAAA,IACtB;AAAA,GACF;AAEA,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,CAAS,KAAA,EAAO,SAAS,CAAA;AAC/C,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA;AAS9B,EAAA,MAAM,IAAA,GAAO,OAAO,KAAK,CAAA;AACzB,EAAA,IAAA,CAAK,OAAA,GAAU,KAAA;AAEf,EAAA,MAAM,OAAA,GAAU,OAAA;AAAA,IACd,MACE,YAAY,OAAA,EAAS;AAAA,MACnB,IAAA,EAAM,KAAK,OAAA,CAAQ,IAAA;AAAA,MACnB,GAAA;AAAA,MACA,MAAA,EAAQ,KAAK,OAAA,CAAQ;AAAA,KACtB,CAAA;AAAA,IACH,CAAC,OAAA,EAAS,GAAA,EAAK,KAAK;AAAA,GACtB;AAEA,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,cAAA,CAAe,SAAS,CAAA,EACtC,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,QAAA,EAAA,EAAO,WAAU,aAAA,EAChB,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,cAAA,EAAgB,QAAA,EAAA,KAAA,IAAS,iBAAA,EAAkB,CAAA;AAAA,sBAC3D,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,YAAA,EACb,QAAA,EAAA;AAAA,QAAA,IAAA,CAAK,KAAA,KAAU,SAAY,IAAA,mBAC1B,GAAA,CAAC,UAAK,SAAA,EAAU,cAAA,EAAgB,eAAK,KAAA,EAAM,CAAA;AAAA,wBAE7C,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,cAAA,EAAgB,gBAAM,IAAA,EAAK,CAAA;AAAA,QAC1C,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,qBACd,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,YAAA,EACb,QAAA,EAAA,CAAA,EAAA,EAD+B,CAElC,CACD;AAAA,OAAA,EACH,CAAA;AAAA,MACC,QAAA,mBACC,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,aAAA,EAAc,QAAA,EAAA;AAAA,QAAA,8BAAA;AAAA,QACJ,MAAA;AAAA,QAAO,MAAA;AAAA,QAAK;AAAA,OAAA,EACtC,CAAA,GACE;AAAA,KAAA,EACN,CAAA;AAAA,wBAIC,SAAA,EAAA,EAAQ,SAAA,EAAU,8BAChB,QAAA,EAAA,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,qBACb,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QAEC,OAAA,EAAS,CAAA;AAAA,QACT,QAAA,EAAU,QAAA;AAAA,QACV,KAAA,EAAO,MAAA,CAAO,CAAA,CAAE,KAAK,CAAA;AAAA,QACrB,OAAA,EAAS,CAAC,IAAA,KAAS,SAAA,CAAU,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,CAAC,CAAA,CAAE,KAAK,GAAG,MAAK,CAAE,CAAA;AAAA,QAC/D,QAAQ,MAAM;AACZ,UAAA,KAAA,CAAM,IAAI,CAAA;AACV,UAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,MAAA,EAAW,IAAA,CAAK,EAAE,GAAmB,CAAA;AAAA,QACrD;AAAA,OAAA;AAAA,MARK,CAAA,CAAE;AAAA,KAUV,CAAA,EACH,CAAA;AAAA,oBAEA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,aAAA,EAEb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,SAAA,EAAA,EAAQ,WAAU,cAAA,EACjB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,UAAA,EAAW,QAAA,EAAA,OAAA,EAAK,CAAA;AAAA,4BAC7B,cAAA,EAAA,EAAe,KAAA,EAAO,KAAA,EAAO,QAAA,EAAU,SAAS,IAAA,EAAM,CAAA;AAAA,wBACvD,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,UAAA,EAAW,QAAA,EAAA,uBAAA,EAAqB,CAAA;AAAA,wBAC9C,GAAA,CAAC,SAAA,EAAA,EAAU,QAAA,EAAU,QAAA,EAAU,QAAQ,KAAA,EAAO;AAAA,OAAA,EAChD,CAAA;AAAA,sBAMA,IAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAU,cAAA,EACjB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,UAAA,EAAW,QAAA,EAAA,SAAA,EAAO,CAAA;AAAA,wBAKhC,GAAA,CAAC,KAAA,EAAA,EAA8B,SAAA,EAAU,wBAAA,EACtC,QAAA,EAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,CAAA,EAAA,EADX,IAAA,CAAK,OAAA,CAAQ,KAAK,CAE5B;AAAA,OAAA,EACF;AAAA,KAAA,EACF,CAAA;AAAA,oBAMA,IAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAU,2BAAA,EACjB,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,UAAA,EAAW,QAAA,EAAA,YAAA,EAAU,CAAA;AAAA,sBACnC,GAAA,CAAC,QAAG,SAAA,EAAU,gBAAA,EACX,kBAAQ,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,qBAClB,IAAA;AAAA,QAAC,IAAA;AAAA,QAAA;AAAA,UAEC,WAAW,CAAA,WAAA,EAAc,CAAA,CAAE,IAAA,KAAS,MAAA,GAAS,qBAAqB,EAAE,CAAA,CAAA;AAAA,UACpE,aAAW,CAAA,CAAE,IAAA;AAAA,UACb,YAAA,EAAY,EAAE,IAAA,CAAK,MAAA;AAAA,UAEnB,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,UAAK,SAAA,EAAU,gBAAA,EAAkB,QAAA,EAAA,CAAA,CAAE,EAAA,EAAI,QAAQ,MAAA,EAAO,CAAA;AAAA,gCACtD,MAAA,EAAA,EAAK,SAAA,EAAU,oBACb,QAAA,EAAA,CAAA,CAAE,IAAA,CAAK,WAAW,CAAA,GACf,QAAA,GACA,EAAE,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,EACzC;AAAA;AAAA,SAAA;AAAA,QAVK,CAAA,CAAE;AAAA,OAYV,CAAA,EACH,CAAA;AAAA,MACC,QAAQ,SAAA,KAAc,MAAA,GAAY,uBACjC,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,YAAA,EAAa,QAAA,EAAA;AAAA,QAAA,0BAAA;AAAA,QACF,QAAQ,SAAA,CAAU,IAAA;AAAA,QAAK,GAAA;AAAA,QAAE,GAAA;AAAA,QACjD,QAAQ,SAAA,CAAU;AAAA,OAAA,EACrB;AAAA,KAAA,EAEJ,CAAA;AAAA,IAIC,IAAA,CAAK,MAAM,MAAA,KAAW,CAAA,GAAI,uBACzB,IAAA,CAAC,SAAA,EAAA,EAAQ,WAAU,2BAAA,EACjB,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,UAAA,EAAW,QAAA,EAAA,4BAAA,EAA0B,CAAA;AAAA,sBACnD,GAAA,CAAC,IAAA,EAAA,EACE,QAAA,EAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,qBACf,IAAA,CAAC,IAAA,EAAA,EAAoB,cAAA,EAAc,CAAA,CAAE,QAAA,EACnC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,GAAA,EAAA,EAAG,YAAE,QAAA,EAAS,CAAA;AAAA,QAAI,UAAA;AAAA,QAAI,CAAA,CAAE;AAAA,OAAA,EAAA,EADlB,CAAA,CAAE,QAEX,CACD,CAAA,EACH;AAAA,KAAA,EACF,CAAA;AAAA,oBAIF,IAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAU,4BAAA,EACjB,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,UAAA,EAAW,QAAA,EAAA,aAAA,EAAW,CAAA;AAAA,sBACpC,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,cAAA,EACb,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,OAAA;AAAA,YACL,GAAA,EAAK,CAAA;AAAA,YACL,GAAA,EAAK,KAAA;AAAA,YACL,KAAA,EAAO,MAAA;AAAA,YACP,YAAA,EAAW,YAAA;AAAA,YACX,QAAA,EAAU,CAAC,CAAA,KAAM,KAAA,CAAM,OAAO,CAAA,CAAE,MAAA,CAAO,KAAK,CAAC;AAAA;AAAA,SAC/C;AAAA,wBACA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,aAAA,EACb,QAAA,EAAA;AAAA,UAAA,MAAA;AAAA,UAAO,KAAA;AAAA,UAAI,KAAA;AAAA,UACX,MAAA,GAAS,CAAA,GAAI,CAAA,MAAA,EAAM,MAAA,CAAO,KAAA,CAAM,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA,EAAG,IAAI,CAAC,CAAA,CAAA,GAAK;AAAA,SAAA,EAC/D,CAAA;AAAA,wBACA,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,KAAA,CAAM,IAAI,CAAA;AAAA,YACzB,UAAU,CAAC,QAAA;AAAA,YACZ,QAAA,EAAA;AAAA;AAAA,SAED;AAAA,4BACC,QAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,OAAA,EAAS,SAAS,QAAA,EAAA,OAAA,EAExC;AAAA,OAAA,EACF,CAAA;AAAA,sBACA,GAAA,CAAC,UAAO,OAAA,EAAkB;AAAA,KAAA,EAC5B;AAAA,GAAA,EACF,CAAA;AAEJ;AAIA,SAAS,YAAA,CAAa;AAAA,EACpB,OAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,EAMG;AACD,EAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAS,MAAM,GAAA,EAAK,OAAA,EAAS,KAAI,GAAI,OAAA;AACpD,EAAA,MAAM,OAAA,GAAU,OAAA,IAAW,QAAA,IAAY,GAAA,KAAQ,MAAA;AAC/C,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,uBAAuB,IAAI,CAAA,CAAA;AAAA,MACtC,YAAA,EAAY,KAAA;AAAA,MACZ,aAAA,EAAa,UAAU,SAAA,GAAY,OAAA;AAAA,MAEnC,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,SAAA,EAAU,YAAA;AAAA,YACV,QAAA,EAAU,OAAA;AAAA,YACV,OAAO,GAAA,IAAO,OAAA;AAAA,YACd,OAAA,EAAS,MAAA;AAAA,YAER,QAAA,EAAA;AAAA;AAAA,SACH;AAAA,QACC,OAAA,mBACC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,YAAA,EAAc,QAAA,EAAA,GAAA,EAAI,CAAA,mBAElC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAA,EAAa,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,QAEtC,KAAA,KAAU,SAAY,IAAA,mBACrB,GAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,eAAA;AAAA,YACV,YAAA,EAAY,GAAG,KAAK,CAAA,QAAA,CAAA;AAAA,YACpB,IAAA,EAAM,CAAA;AAAA,YACN,KAAA,EAAO,KAAA;AAAA,YACP,UAAU,CAAC,CAAA,KAAM,OAAA,CAAQ,CAAA,CAAE,OAAO,KAAK;AAAA;AAAA,SACzC;AAAA,QAED,GAAA,KAAQ,UAAa,CAAC,OAAA,uBACpB,MAAA,EAAA,EAAK,SAAA,EAAU,YAAA,EAAa,QAAA,EAAA,kCAAA,EAA2B,CAAA,GACtD;AAAA;AAAA;AAAA,GACN;AAEJ;AASA,SAAS,gBAAgB,CAAA,EAKd;AACT,EAAA,MAAM,IAAA,GAAO,CAAA,CAAE,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,CAAA,GAAA,EAAM,CAAA,CAAE,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GAAK,EAAA;AAC7D,EAAA,IAAI,CAAA,CAAE,UAAU,MAAA,EAAW;AACzB,IAAA,OAAO,CAAA,CAAE,KAAA,CAAM,MAAA,KAAW,SAAA,GACtB,GAAG,CAAA,CAAE,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAC,CAAA,QAAA,EAAM,CAAA,CAAE,KAAA,CAAM,KAAK,MAAM,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CAAA,CAAA,GAC5D,UAAK,CAAA,CAAE,KAAA,CAAM,MAAM,CAAA,EAAA,EAAK,EAAE,KAAA,CAAM,MAAA,KAAW,MAAA,GAAS,EAAA,GAAK,GAAG,CAAA,EAAG,CAAA,CAAE,KAAA,CAAM,KAAK,IAAI,IAAI,CAAA,CAAA;AAAA,EAC1F;AACA,EAAA,IAAI,CAAA,CAAE,aAAa,MAAA,EAAW,OAAO,UAAK,CAAA,CAAE,QAAQ,GAAG,IAAI,CAAA,CAAA;AAC3D,EAAA,OAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,KAAK,KAAK,CAAC,GAAG,IAAI,CAAA,CAAA;AACxC;AAKA,SAAS,UAAA,CACP,QACA,OAAA,EACwB;AACxB,EAAA,MAAM,GAAA,GAAO,WAAW,EAAC;AACzB,EAAA,MAAM,MAA8B,EAAC;AACrC,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,IAAI,CAAC,EAAE,UAAA,EAAY;AACnB,IAAA,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,GAAI,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,CAAE,IAAI,CAAA,IAAK,EAAE,CAAA;AAAA,EAChD;AACA,EAAA,OAAO,GAAA;AACT;AAOA,SAAS,YACP,MAAA,EACoC;AACpC,EAAA,MAAM,MAA0C,EAAC;AACjD,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,IAAI,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC9C,IAAA,IAAI;AACF,MAAA,MAAM,CAAA,GAAa,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAClC,MAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,MAAM,IAAA,EAAM,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,IACpD,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAOA,SAAS,QAAA,CACP,KACA,IAAA,EACa;AACb,EAAA,IAAI;AACF,IAAA,OAAO,IAAI,IAAA,EAAK;AAAA,EAClB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,MAAM,EAAC,EAAG,YAAY,IAAA,EAAK;AAAA,EACpD;AACF;AAUA,SAAS,YAAA,CAMP,OAAA,EACA,KAAA,EACA,GAAA,EACA,GACA,IAAA,EACG;AACH,EAAA,IAAI;AACF,IAAA,OAAO,OAAO,OAAA,EAAS;AAAA,MACrB,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA;AAAA,MAC3B,GAAA;AAAA,MACA,QAAQ,KAAA,CAAM;AAAA,KACf,CAAA,CAAE,KAAA;AAAA,EACL,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF","file":"chunk-7FRZ2CT2.js","sourcesContent":["/**\n * @packageDocumentation\n * @demlik/tea/chart/inspect/react — the chart inspector, as one component.\n *\n * ```tsx\n * <ChartInspector chart={lane} parts={{ assign, guards }} samples={samples}\n * boot={() => ({ retries: 0, maxRetries: 3 })} />\n * ```\n *\n * That is the whole page: a button per message, a live state panel, a state\n * diagram with the current node lit, and a time-travel scrubber over every\n * transition. None of it is configured. The message list, the state names, the\n * phases, which control is legal right now and why the others are refused are\n * all READ OFF THE CHART by `../inspect`'s headless core — which is the point:\n * a hand-built debugger page encodes those four facts a second time, and this\n * one cannot, because it never learns them from anywhere but the chart.\n *\n * WHAT THE AUTHOR STILL SUPPLIES, and why none of it is derivable:\n *\n * - `parts` — the code the chart deliberately does not own (payload builders,\n * guard bodies, cells). It is the same bag `compile` demands; the inspector\n * compiles the machine itself rather than asking for one, so the diagram and\n * the runtime provably come from the same chart.\n * - `boot` — the initial state's DATA. The chart says which state is the entry\n * (`initial: true`); it cannot say what `maxRetries` is.\n * - `samples` — one payload per event that declares one. `ty<T>()` is `{}` at\n * runtime, so no derivation recovers the shape. Typed by the chart all the\n * same (see `Samples<C>`), and rendered as EDITABLE JSON so the operator can\n * vary a payload and watch a guard's branch flip.\n * - `ctx` — the runtime environment, which is not a property of the machine.\n *\n * WHAT WOULD FIRE, AND WHAT DID. The button row shows the cmds an edge\n * DECLARES — the before question, and empty by declaration on a `{ to, cell }`\n * edge, because the cell builds its cmds in its body. The \"cmds fired\" panel\n * shows what the recorded run ACTUALLY emitted, per step, tagged with the msg\n * that caused it. Two panels, because they answer two questions; the second is\n * the only place a cell-built effect is visible at all.\n *\n * THE REDUCER FORM has its own component, `<ReducerChartInspector>`, over the\n * same view. It renders the panels that apply and NAMES the ones that do not:\n * no phase on the header, no refusal on any control, no highlighted node in the\n * drawing — each listed in a \"not available in this form\" panel with the reason,\n * rather than quietly missing.\n *\n * TIME TRAVEL IS PURE. The runtime is recorded with `@demlik/tea/recorder`, and\n * scrubbing re-folds a PREFIX of the recorded msgs through `replay` — init +\n * update only, never `interpret`, never a Store, never a live subscription. So\n * dragging the scrubber backwards cannot re-fire an effect, which is the one\n * thing a naive time-travel implementation gets wrong.\n *\n * Styling follows `@demlik/tea/devtools`: one stylesheet, every class prefixed\n * (`tea-ci-*`), wired to the consumer's design tokens, no framework and no new\n * dependency. Import `@demlik/tea/chart/inspect/styles.css` (and devtools'\n * stylesheet, since the state/log/diff panels are devtools components).\n */\n\n\"use client\";\n\nimport { useEffect, useMemo, useReducer, useRef, useState } from \"react\";\nimport {\n MsgLog,\n StateDiff,\n StateInspector,\n useMsgHistory,\n} from \"../../devtools\";\nimport {\n type BootingRuntime,\n type Cmd,\n type Machine,\n type Runtime,\n replay,\n run,\n type Sub,\n} from \"../../index\";\nimport type { Reducer, RequiredCtx, Transitions } from \"../../pure/core\";\nimport { type Recorder, recorder, type Trace } from \"../../recorder\";\nimport {\n chartMermaid,\n compile,\n compileReducer,\n initFrom,\n type Parts,\n type RParts,\n reducerInitFrom,\n reducerMermaid,\n} from \"../compile\";\nimport type {\n Chart,\n CmdOf,\n InitialData,\n MsgOf,\n ReducerChart,\n RStateOf,\n StateOf,\n} from \"../graph\";\nimport {\n type ChartDescription,\n type CmdCapture,\n captureCmds,\n describeChart,\n describeReducerChart,\n type EventPreview,\n inspectReducerState,\n inspectState,\n type ReducerChartDescription,\n type ReducerEventPreview,\n type RtSamples,\n type Samples,\n} from \"./index\";\n\n// ── props ─────────────────────────────────────────────────────────────────\n\n/**\n * Everything `<ChartInspector>` needs. Four fields, and every one of them is a\n * fact the chart genuinely does not carry — see the module doc. Anything the\n * chart DOES carry (events, states, phases, guards, cmds, refusals) has no prop\n * here by design: a prop that restated one would be the fact said twice.\n */\nexport interface ChartInspectorProps<\n C,\n S extends { type: string },\n M extends { type: string },\n Ctx,\n> {\n /** The chart. Everything the UI draws is read off this value. */\n readonly chart: C;\n /** The parts bag `compile` demands — assign, plus guards/cmds/cells if used. */\n readonly parts: Parts<C, S, M>;\n /** The entry state's data. The chart names the state; you supply its ctx. */\n readonly boot: () => InitialData<C, S>;\n /** One payload per event that declares one. Typed by the chart. */\n readonly samples?: Samples<C>;\n /** The runtime ctx. Omit for a machine that reads nothing from one. */\n readonly ctx?: Ctx;\n /** Diagram title. Cosmetic — defaults to no title. */\n readonly title?: string;\n /** Diagram direction. Default `\"TB\"`. */\n readonly direction?: \"TB\" | \"LR\";\n /** Appended to the container's class list. */\n readonly className?: string;\n}\n\n/**\n * Everything `<ReducerChartInspector>` needs — the same four undecidable facts,\n * over the form that has no phase dimension.\n *\n * There is no `direction` prop, and its absence is the honest kind: the reducer\n * drawing has one `any` node with every edge leaving it (that is what having no\n * phase dimension MEANS), so a layout knob would be a knob over nothing.\n */\nexport interface ReducerChartInspectorProps<\n C,\n S extends { type: string },\n M extends { type: string },\n Ctx,\n> {\n /** The reducer chart. Everything the UI draws is read off this value. */\n readonly chart: C;\n /** The parts bag `compileReducer` demands. */\n readonly parts: RParts<C, S, M>;\n /** The entry state's data — for this form, the whole state minus its tag. */\n readonly boot: () => Omit<RStateOf<C>, \"type\">;\n /** One payload per event that declares one. Typed by the chart. */\n readonly samples?: Samples<C>;\n /** The runtime ctx. Omit for a machine that reads nothing from one. */\n readonly ctx?: Ctx;\n /** Panel title. Cosmetic — defaults to no title. */\n readonly title?: string;\n /** Appended to the container's class list. */\n readonly className?: string;\n}\n\n// ── the runtime lifecycle, shared by both forms ───────────────────────────\n\n/**\n * Own a runtime for the component's lifetime (built with `run`, stopped on\n * unmount or reset) so the recorder has something to attach to — `useMachine`\n * hides the runtime, and the recorder needs it. The booted `Runtime` is\n * consumed with `useRuntime`'s contract: the component that owns the lifecycle\n * stops it.\n *\n * Shared by both chart forms because none of it is form-specific: a compiled\n * `Transitions` and a compiled `Reducer` are both just a `Machine[\"update\"]`.\n *\n * EXPORTED for the one other component with the same lifecycle to own:\n * `@demlik/tea/chart/lane/react`'s live lane, whose `update` is `runLane`'s.\n * A lane is not a chart form, but \"own a runtime for the component's lifetime,\n * record it, and stop it on unmount\" is not a fact about charts either — and a\n * second copy of it is a second place for the recorder's stop to be forgotten.\n */\nexport function useInspectorRuntime<\n S,\n M extends { type: string },\n K extends Cmd,\n Ctx,\n>(\n machine: Machine<S, M, K, Sub<never>, Ctx>,\n // What `run` demands: the machine's ctx plus every typed Cmd's `R`.\n ctx: Ctx & RequiredCtx<K>,\n epoch: number,\n): { readonly rt: Runtime<S, M> | null; readonly rec: Recorder<S, M> } {\n // `epoch` is not read inside the memo, and it is still a real dependency: it\n // IS the reset lever. Bumping it is how \"start over\" rebuilds the runtime, so\n // re-booting the machine from `init` rather than pretending some message\n // means \"go back to the beginning\" — no chart has one.\n // biome-ignore lint/correctness/useExhaustiveDependencies: `epoch` is the reset lever — the memo must re-run when it bumps, which is the whole point of the value\n const booting = useMemo<BootingRuntime<S, M>>(\n () => run(machine, { ctx }),\n [machine, ctx, epoch],\n );\n const rec = useMemo<Recorder<S, M>>(() => recorder(booting), [booting]);\n\n // The booted handle. Until `ready` resolves there is no total `getState`, so\n // there is nothing honest to render — one frame of \"booting\" beats inventing\n // a state the machine has not produced.\n const [rt, setRt] = useState<Runtime<S, M> | null>(null);\n useEffect(() => {\n let live = true;\n setRt(null);\n booting.ready.then(\n (r) => {\n if (live) setRt(r);\n },\n () => {},\n );\n return () => {\n live = false;\n rec.stop();\n booting.stop().catch(() => {});\n };\n }, [booting, rec]);\n\n return { rt, rec };\n}\n\n// ── the components ────────────────────────────────────────────────────────\n\n/**\n * The self-building debugger for any GRID-form chart.\n */\nexport function ChartInspector<\n const C extends Chart<C>,\n S extends { type: string } = StateOf<C>,\n M extends { type: string } = MsgOf<C>,\n K extends Cmd = CmdOf<C>,\n Ctx = Record<never, never>,\n>(props: ChartInspectorProps<C, S, M, Ctx>) {\n const { chart, parts, boot, ctx } = props;\n // The reset lever: a fresh epoch rebuilds the runtime, which re-boots the\n // machine from `init`. Resetting by dispatching would be a lie — there is no\n // \"go back to the start\" message in any chart.\n const [epoch, reset] = useReducer((n: number) => n + 1, 0);\n\n const machine = useMemo(\n () =>\n ({\n init: initFrom<C, S, K>(chart, boot),\n // The one cast, at the construction boundary: `compile` returns a\n // `Transitions` over the chart's OWN derivations, and `S`/`M`/`K` are\n // the caller's names for exactly those.\n update: compile(chart, parts) as unknown as Transitions<S, M, K>,\n }) as unknown as Machine<S, M, K, Sub<never>, Ctx>,\n [chart, parts, boot],\n );\n const { rt, rec } = useInspectorRuntime(\n machine,\n ctx as Ctx & RequiredCtx<K>,\n epoch,\n );\n\n const desc = useMemo(() => describeChart(chart), [chart]);\n const view = useMemo<FormView<S>>(\n () => gridView(desc, chart, parts, props.title, props.direction),\n [desc, chart, parts, props.title, props.direction],\n );\n\n if (rt === null) {\n return (\n <div className={containerClass(props.className)}>\n <div className=\"tea-ci-boot\">booting…</div>\n </div>\n );\n }\n return (\n <InspectorView\n key={epoch}\n view={view}\n samples={props.samples}\n runtime={rt}\n rec={rec}\n machine={machine}\n ctx={ctx as Ctx}\n title={props.title}\n className={props.className}\n onReset={reset}\n />\n );\n}\n\n/**\n * The same debugger for a REDUCER-form chart — the panels that apply, and the\n * ones that do not left out with the reason on screen.\n *\n * What is missing here is missing because the form does not have it: no phase\n * on the header, no refusal on any control (this form cannot refuse an event),\n * and no highlighted node in the drawing (every edge leaves the one `any`\n * node). The \"not available in this form\" panel names each one, so the\n * omission reads as a property of the chart rather than a hole in the tool.\n */\nexport function ReducerChartInspector<\n const C extends ReducerChart<C>,\n S extends { type: string } = RStateOf<C>,\n M extends { type: string } = MsgOf<C>,\n K extends Cmd = CmdOf<C>,\n Ctx = Record<never, never>,\n>(props: ReducerChartInspectorProps<C, S, M, Ctx>) {\n const { chart, parts, boot, ctx } = props;\n const [epoch, reset] = useReducer((n: number) => n + 1, 0);\n\n const machine = useMemo(\n () =>\n ({\n init: reducerInitFrom<C, S, K>(chart, boot),\n // The one cast, for the same reason as the grid form's: `compileReducer`\n // returns a `Reducer` over the chart's OWN derivations.\n update: compileReducer(chart, parts) as unknown as Reducer<S, M, K>,\n }) as unknown as Machine<S, M, K, Sub<never>, Ctx>,\n [chart, parts, boot],\n );\n const { rt, rec } = useInspectorRuntime(\n machine,\n ctx as Ctx & RequiredCtx<K>,\n epoch,\n );\n\n const desc = useMemo(() => describeReducerChart(chart), [chart]);\n const view = useMemo<FormView<S>>(\n () => reducerView(desc, chart, parts),\n [desc, chart, parts],\n );\n\n if (rt === null) {\n return (\n <div className={containerClass(props.className)}>\n <div className=\"tea-ci-boot\">booting…</div>\n </div>\n );\n }\n return (\n <InspectorView\n key={epoch}\n view={view}\n samples={props.samples}\n runtime={rt}\n rec={rec}\n machine={machine}\n ctx={ctx as Ctx}\n title={props.title}\n className={props.className}\n onReset={reset}\n />\n );\n}\n\nfunction containerClass(extra: string | undefined): string {\n return `tea-ci${extra ? ` ${extra}` : \"\"}`;\n}\n\n// ── the form seam ─────────────────────────────────────────────────────────\n\n/** One event control, normalized so the two chart forms render through one row. */\ninterface ControlModel {\n readonly event: string;\n /** `\"legal\"` or the refusal's kind — the class suffix, and the CSS hook. */\n readonly kind: string;\n readonly refused: boolean;\n /** The refusal's one-line explanation. Present iff refused. */\n readonly why?: string;\n /** \"where would this go, and what would it fire\" — the DECLARED answer. */\n readonly outcome: string;\n /** The msg a click would dispatch, or `undefined` when no sample was given. */\n readonly msg?: { readonly type: string };\n}\n\n/**\n * The three things that differ between the chart forms, and nothing else.\n *\n * Everything below this line — the runtime, the recorder, time travel, the\n * drafts, the captured cmds — is identical for a grid chart and a reducer\n * chart, because none of it depends on there being a phase dimension. So the\n * view takes the difference as data rather than branching on it: `header`\n * returns no phase where there is no phase, `controls` returns rows that cannot\n * be refused where nothing can refuse them, and `omits` names each panel the\n * form cannot honestly fill.\n */\ninterface FormView<S extends { type: string }> {\n /** The alphabet, for seeding one payload draft per event that declares one. */\n readonly events: readonly {\n readonly name: string;\n readonly hasPayload: boolean;\n }[];\n readonly controls: (state: S, samples: RtSamples) => readonly ControlModel[];\n readonly mermaid: (state: S) => string;\n readonly header: (state: S) => {\n readonly phase?: string;\n readonly tags: readonly string[];\n };\n /** The questions this form cannot answer, each with the reason. */\n readonly omits: readonly {\n readonly question: string;\n readonly why: string;\n }[];\n}\n\nfunction gridView<C, S extends { type: string }, M extends { type: string }>(\n desc: ChartDescription,\n chart: C,\n parts: Parts<C, S, M>,\n title: string | undefined,\n direction: \"TB\" | \"LR\" | undefined,\n): FormView<S> {\n return {\n events: desc.events,\n controls: (state, samples) =>\n inspectState(desc, state, { parts: parts as never, samples }).map(\n gridControl,\n ),\n mermaid: (state) =>\n chartMermaid(chart as never, {\n highlight: state.type,\n phases: true,\n direction,\n title,\n }),\n header: (state) => {\n const here = desc.states.find((s) => s.name === state.type);\n return {\n ...(here === undefined ? {} : { phase: here.phase }),\n tags: [\n ...(here?.end === true ? [\"end\"] : []),\n ...(here?.parking === true ? [\"parking\"] : []),\n ],\n };\n },\n omits: [],\n };\n}\n\nfunction reducerView<C, S extends { type: string }, M extends { type: string }>(\n desc: ReducerChartDescription,\n chart: C,\n parts: RParts<C, S, M>,\n): FormView<S> {\n return {\n events: desc.events,\n controls: (state, samples) =>\n inspectReducerState(desc, state, {\n parts: parts as never,\n samples,\n }).map(reducerControl),\n // No `highlight`: every edge leaves the one `any` node, so there is no\n // node that IS the current state to light up.\n mermaid: () => reducerMermaid(chart as never),\n // No phase, no `end`, no `parking` — this form declares none of the three.\n header: () => ({ tags: [] }),\n omits: [desc.phases, desc.refusals, desc.scope],\n };\n}\n\n/** An `EventPreview` as a row: legality is a real question in the grid form. */\nfunction gridControl(v: EventPreview): ControlModel {\n const refused = v.status === \"refused\";\n return {\n event: v.event,\n kind: refused ? (v.reason?.kind ?? \"undeclared\") : \"legal\",\n refused,\n ...(v.why === undefined ? {} : { why: v.why }),\n outcome: describeOutcome(v),\n ...(v.msg === undefined ? {} : { msg: v.msg }),\n };\n}\n\n/** A `ReducerEventPreview` as a row. It can never be refused — there is no\n * mechanism in this form with which to refuse it. */\nfunction reducerControl(v: ReducerEventPreview): ControlModel {\n return {\n event: v.event,\n kind: \"legal\",\n refused: false,\n outcome: describeOutcome(v),\n ...(v.msg === undefined ? {} : { msg: v.msg }),\n };\n}\n\n// ── the view ──────────────────────────────────────────────────────────────\n\ninterface ViewProps<\n C,\n S extends { type: string },\n M extends { type: string },\n K extends Cmd,\n Ctx,\n> {\n readonly view: FormView<S>;\n readonly samples: Samples<C> | undefined;\n readonly runtime: Runtime<S, M>;\n readonly rec: Recorder<S, M>;\n readonly machine: Machine<S, M, K, Sub<never>, Ctx>;\n readonly ctx: Ctx;\n readonly title: string | undefined;\n readonly className: string | undefined;\n readonly onReset: () => void;\n}\n\nfunction InspectorView<\n C,\n S extends { type: string },\n M extends { type: string },\n K extends Cmd,\n Ctx,\n>({\n view,\n samples,\n runtime,\n rec,\n machine,\n ctx,\n title,\n className,\n onReset,\n}: ViewProps<C, S, M, K, Ctx>) {\n // The live state, straight off the runtime (`useRuntime`'s subscription,\n // inlined here because this component also needs the recorder's view).\n const [tick, bump] = useReducer((n: number) => n + 1, 0);\n useEffect(() => runtime.subscribe(bump), [runtime]);\n const liveState = runtime.getState();\n\n // Every dispatch goes through `useMsgHistory`, so the MsgLog rows and the\n // recorder's replay tape are fed by the same action.\n const [history, send] = useMsgHistory<M>(runtime.dispatch);\n\n // The editable payloads. Seeded from `samples`, then owned by the operator —\n // varying one is what makes the guard preview interactive.\n const [drafts, setDrafts] = useState<Readonly<Record<string, string>>>(() =>\n seedDrafts(view.events, samples),\n );\n const effective = useMemo(() => parseDrafts(drafts), [drafts]);\n\n // Time travel. `at === null` is live; otherwise it is a msg-prefix length,\n // and the displayed state is that prefix re-folded through `replay`.\n const [at, setAt] = useState<number | null>(null);\n const trace = safeDump(rec, liveState);\n const total = trace.msgs.length;\n const cursor = at === null ? total : Math.min(at, total);\n const scrubbed = at !== null && cursor < total;\n\n const shown = replayPrefix(machine, trace, ctx, cursor, liveState);\n const previous = replayPrefix(\n machine,\n trace,\n ctx,\n Math.max(0, cursor - 1),\n liveState,\n );\n\n const verdicts = view.controls(shown, effective);\n const here = view.header(shown);\n\n // WHAT ACTUALLY FIRED, per step — the after question, folded from the same\n // recorded prefix the scrubber is already folding. `cursor` indexes both, so\n // the highlighted row is the transition on screen.\n // `rec.dump()` allocates a fresh tape every render, so the msgs ARRAY has a\n // new identity each time and keying the memo on it would re-fold the whole run\n // on every keystroke in a payload box. The tape only ever grows, so its LENGTH\n // is the honest key, and the tape itself is read through a ref.\n const tape = useRef(trace);\n tape.current = trace;\n // biome-ignore lint/correctness/useExhaustiveDependencies: `total` is not read in the body and is the whole point of the memo — it is the tape's length, the one thing that changes what the capture returns\n const capture = useMemo<CmdCapture<M, K>>(\n () =>\n captureCmds(machine, {\n msgs: tape.current.msgs,\n ctx,\n loaded: tape.current.loaded,\n }),\n [machine, ctx, total],\n );\n\n return (\n <div className={containerClass(className)}>\n <header className=\"tea-ci-head\">\n <span className=\"tea-ci-title\">{title ?? \"chart inspector\"}</span>\n <span className=\"tea-ci-now\">\n {here.phase === undefined ? null : (\n <span className=\"tea-ci-phase\">{here.phase}</span>\n )}\n <span className=\"tea-ci-state\">{shown.type}</span>\n {here.tags.map((t) => (\n <span className=\"tea-ci-tag\" key={t}>\n {t}\n </span>\n ))}\n </span>\n {scrubbed ? (\n <span className=\"tea-ci-warn\">\n time-travelling — step {cursor} of {total}\n </span>\n ) : null}\n </header>\n\n {/* 1 — the button row. One control per DECLARED event; a refused one is\n drawn as refused, with the reason, never omitted. */}\n <section className=\"tea-ci-panel tea-ci-events\">\n {verdicts.map((v) => (\n <EventControl\n key={v.event}\n control={v}\n disabled={scrubbed}\n draft={drafts[v.event]}\n onDraft={(text) => setDrafts((d) => ({ ...d, [v.event]: text }))}\n onSend={() => {\n setAt(null);\n if (v.msg !== undefined) send(v.msg as unknown as M);\n }}\n />\n ))}\n </section>\n\n <div className=\"tea-ci-cols\">\n {/* 2 — the live state, and what the last step changed. */}\n <section className=\"tea-ci-panel\">\n <h3 className=\"tea-ci-h\">state</h3>\n <StateInspector state={shown} flashKey={cursor + tick} />\n <h3 className=\"tea-ci-h\">diff vs previous step</h3>\n <StateDiff expected={previous} actual={shown} />\n </section>\n\n {/* 3 — the diagram, with the current node lit where the form has one.\n `<pre class=\"mermaid\">` is the shape a mermaid host renders in\n place; the text is readable either way, so the panel is useful with\n no renderer at all. */}\n <section className=\"tea-ci-panel\">\n <h3 className=\"tea-ci-h\">diagram</h3>\n {/* Keyed by the diagram, for the reason `chart/lane/react.tsx` records:\n a mermaid host marks rendered nodes and skips them, React rewrites\n only the text, and the picture silently stops updating after the\n first frame. The key forces a genuinely new node. */}\n <pre key={view.mermaid(shown)} className=\"mermaid tea-ci-mermaid\">\n {view.mermaid(shown)}\n </pre>\n </section>\n </div>\n\n {/* 4 — WHAT ACTUALLY FIRED. The button row above says what an edge\n DECLARES it would fire; this says what the recorded run did fire, per\n step, tagged with the msg that caused it — the only place a cmd built\n inside a cell body is visible at all. */}\n <section className=\"tea-ci-panel tea-ci-fired\">\n <h3 className=\"tea-ci-h\">cmds fired</h3>\n <ol className=\"tea-ci-firelog\">\n {capture.steps.map((s) => (\n <li\n key={s.step}\n className={`tea-ci-fire${s.step === cursor ? \" tea-ci-fire-now\" : \"\"}`}\n data-step={s.step}\n data-fired={s.cmds.length}\n >\n <span className=\"tea-ci-fire-by\">{s.by?.type ?? \"init\"}</span>\n <span className=\"tea-ci-fire-cmds\">\n {s.cmds.length === 0\n ? \"—\"\n : s.cmds.map((c) => c.type).join(\", \")}\n </span>\n </li>\n ))}\n </ol>\n {capture.stoppedAt === undefined ? null : (\n <span className=\"tea-ci-why\">\n capture stopped at step {capture.stoppedAt.step}:{\" \"}\n {capture.stoppedAt.error}\n </span>\n )}\n </section>\n\n {/* 5 — the questions this chart form cannot answer, named rather than\n silently missing. Empty for a grid chart, which answers all three. */}\n {view.omits.length === 0 ? null : (\n <section className=\"tea-ci-panel tea-ci-omits\">\n <h3 className=\"tea-ci-h\">not available in this form</h3>\n <ul>\n {view.omits.map((o) => (\n <li key={o.question} data-omitted={o.question}>\n <b>{o.question}</b> — {o.why}\n </li>\n ))}\n </ul>\n </section>\n )}\n\n {/* 6 — time travel over every recorded transition. */}\n <section className=\"tea-ci-panel tea-ci-travel\">\n <h3 className=\"tea-ci-h\">time travel</h3>\n <div className=\"tea-ci-scrub\">\n <input\n type=\"range\"\n min={0}\n max={total}\n value={cursor}\n aria-label=\"transition\"\n onChange={(e) => setAt(Number(e.target.value))}\n />\n <span className=\"tea-ci-step\">\n {cursor} / {total}\n {cursor > 0 ? ` · ${String(trace.msgs[cursor - 1]?.type)}` : \"\"}\n </span>\n <button\n type=\"button\"\n onClick={() => setAt(null)}\n disabled={!scrubbed}\n >\n live\n </button>\n <button type=\"button\" onClick={onReset}>\n reset\n </button>\n </div>\n <MsgLog history={history} />\n </section>\n </div>\n );\n}\n\n// ── one event control ─────────────────────────────────────────────────────\n\nfunction EventControl({\n control,\n disabled,\n draft,\n onDraft,\n onSend,\n}: {\n readonly control: ControlModel;\n readonly disabled: boolean;\n readonly draft: string | undefined;\n readonly onDraft: (text: string) => void;\n readonly onSend: () => void;\n}) {\n const { event, refused, kind, why, outcome, msg } = control;\n const blocked = refused || disabled || msg === undefined;\n return (\n <div\n className={`tea-ci-ev tea-ci-ev-${kind}`}\n data-event={event}\n data-status={refused ? \"refused\" : \"legal\"}\n >\n <button\n type=\"button\"\n className=\"tea-ci-btn\"\n disabled={blocked}\n title={why ?? outcome}\n onClick={onSend}\n >\n {event}\n </button>\n {refused ? (\n <span className=\"tea-ci-why\">{why}</span>\n ) : (\n <span className=\"tea-ci-to\">{outcome}</span>\n )}\n {draft === undefined ? null : (\n <textarea\n className=\"tea-ci-sample\"\n aria-label={`${event} payload`}\n rows={1}\n value={draft}\n onChange={(e) => onDraft(e.target.value)}\n />\n )}\n {msg === undefined && !refused ? (\n <span className=\"tea-ci-why\">no sample — cannot dispatch</span>\n ) : null}\n </div>\n );\n}\n\n/**\n * The one-line \"where would this go, and what would it DECLARE it fires\".\n *\n * Structural in its parameter, because a grid preview and a reducer preview\n * agree on exactly the four fields it reads — and disagree only about the\n * refusal, which never reaches here.\n */\nfunction describeOutcome(v: {\n readonly guard?: EventPreview[\"guard\"];\n readonly cmds: readonly string[];\n readonly targets: readonly string[];\n readonly resolved?: string;\n}): string {\n const cmds = v.cmds.length > 0 ? ` / ${v.cmds.join(\", \")}` : \"\";\n if (v.guard !== undefined) {\n return v.guard.branch === \"unknown\"\n ? `${v.targets.join(\" | \")} — ${v.guard.guard}? (${v.guard.why})`\n : `→ ${v.guard.target} [${v.guard.branch === \"then\" ? \"\" : \"!\"}${v.guard.guard}]${cmds}`;\n }\n if (v.resolved !== undefined) return `→ ${v.resolved}${cmds}`;\n return `${v.targets.join(\" | \")}${cmds}`;\n}\n\n// ── helpers ───────────────────────────────────────────────────────────────\n\n/** One JSON draft per event that declares a payload. */\nfunction seedDrafts(\n events: readonly { readonly name: string; readonly hasPayload: boolean }[],\n samples: unknown,\n): Record<string, string> {\n const bag = (samples ?? {}) as Record<string, unknown>;\n const out: Record<string, string> = {};\n for (const e of events) {\n if (!e.hasPayload) continue;\n out[e.name] = JSON.stringify(bag[e.name] ?? {});\n }\n return out;\n}\n\n/**\n * Parse the drafts back into a samples bag. An unparseable draft contributes\n * NOTHING rather than a stale value — which surfaces as the honest \"no sample\"\n * degradation in the guard preview instead of a silently ignored edit.\n */\nfunction parseDrafts(\n drafts: Readonly<Record<string, string>>,\n): Record<string, object | undefined> {\n const out: Record<string, object | undefined> = {};\n for (const [k, text] of Object.entries(drafts)) {\n try {\n const v: unknown = JSON.parse(text);\n if (typeof v === \"object\" && v !== null) out[k] = v;\n } catch {\n // left absent on purpose — see the doc above.\n }\n }\n return out;\n}\n\n/**\n * The recorder's tape. `dump()` throws before the boot observe has fired; the\n * view only renders post-boot, so the fallback is a formality — and a formality\n * beats a blank screen.\n */\nfunction safeDump<S, M extends { type: string }>(\n rec: Recorder<S, M>,\n live: S,\n): Trace<S, M> {\n try {\n return rec.dump();\n } catch {\n return { loaded: null, msgs: [], finalState: live };\n }\n}\n\n/**\n * The state after the first `n` recorded msgs, by PURE replay.\n *\n * `replay` runs `init` + `update` only. No `interpret`, no Store, no live\n * subscription — so scrubbing backwards re-derives history rather than\n * re-performing it, which is the whole difference between time travel and\n * re-running the app.\n */\nfunction replayPrefix<\n S extends { type: string },\n M extends { type: string },\n K extends Cmd,\n Ctx,\n>(\n machine: Machine<S, M, K, Sub<never>, Ctx>,\n trace: Trace<S, M>,\n ctx: Ctx,\n n: number,\n live: S,\n): S {\n try {\n return replay(machine, {\n msgs: trace.msgs.slice(0, n),\n ctx,\n loaded: trace.loaded,\n }).state;\n } catch {\n return live;\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { inspectState, describeChart } from './chunk-ZD6PNZBK.js';
2
- import { foldLane, phaseStandings, trippedTasks, statesOf, RETRY_BUDGET, timeline, walkedEdgeKey, walkedEdges, initialOf, waitingOn, endPolarityOf, laneTerminalReached, bareEvent, drawTask, originOf } from './chunk-5KJKJOFC.js';
3
- import { compileTable } from './chunk-E6GEDSF4.js';
1
+ import { inspectState, describeChart } from './chunk-3ZAFFRRB.js';
2
+ import { foldLane, phaseStandings, trippedTasks, statesOf, RETRY_BUDGET, timeline, walkedEdgeKey, walkedEdges, initialOf, waitingOn, endPolarityOf, laneTerminalReached, bareEvent, drawTask, originOf } from './chunk-NR7BU22N.js';
3
+ import { compileTable } from './chunk-YWIKDKHY.js';
4
4
 
5
5
  // src/chart/lane/inspect.ts
6
6
  var describe = (chart) => describeChart(chart);
@@ -681,5 +681,5 @@ function outcomeOf(v) {
681
681
  }
682
682
 
683
683
  export { LaneShapeError, defineLane, inspectLane, inspectLaneStates, laneShape, laneView, liveFeed, replayFeed, runLane };
684
- //# sourceMappingURL=chunk-ZCL7SCBK.js.map
685
- //# sourceMappingURL=chunk-ZCL7SCBK.js.map
684
+ //# sourceMappingURL=chunk-CIQG5L42.js.map
685
+ //# sourceMappingURL=chunk-CIQG5L42.js.map