@demlik/tea 0.1.2 → 0.3.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 (212) hide show
  1. package/README.md +49 -0
  2. package/dist/agent/index.d.ts +16 -770
  3. package/dist/agent/index.js +18 -16
  4. package/dist/authed-call/index.d.ts +3 -3
  5. package/dist/authed-call/index.js +22 -36
  6. package/dist/authed-call/index.js.map +1 -1
  7. package/dist/await-terminal/index.d.ts +2 -2
  8. package/dist/await-terminal/index.js +2 -2
  9. package/dist/batch-window/index.d.ts +3 -3
  10. package/dist/batch-window/index.js +3 -3
  11. package/dist/cache/index.d.ts +2 -2
  12. package/dist/cache/index.js +5 -2
  13. package/dist/{chunk-3545BOYL.js → chunk-25LBDCBC.js} +6 -5
  14. package/dist/chunk-25LBDCBC.js.map +1 -0
  15. package/dist/{chunk-IN33Q4VJ.js → chunk-2KNLKQVN.js} +3 -3
  16. package/dist/{chunk-IN33Q4VJ.js.map → chunk-2KNLKQVN.js.map} +1 -1
  17. package/dist/{chunk-MMH7CW5K.js → chunk-BP2R7TPP.js} +216 -157
  18. package/dist/chunk-BP2R7TPP.js.map +1 -0
  19. package/dist/chunk-C6QC273X.js +71 -0
  20. package/dist/chunk-C6QC273X.js.map +1 -0
  21. package/dist/{chunk-7W4LMPUW.js → chunk-CAXMQJJ3.js} +17 -24
  22. package/dist/chunk-CAXMQJJ3.js.map +1 -0
  23. package/dist/{chunk-UV6UWGEO.js → chunk-D736QUGF.js} +6 -5
  24. package/dist/chunk-D736QUGF.js.map +1 -0
  25. package/dist/chunk-EWJP3YYP.js +21 -0
  26. package/dist/chunk-EWJP3YYP.js.map +1 -0
  27. package/dist/{chunk-TGG26XMK.js → chunk-FV3Z5MBE.js} +10 -5
  28. package/dist/chunk-FV3Z5MBE.js.map +1 -0
  29. package/dist/chunk-G5E74IJB.js +8 -0
  30. package/dist/chunk-G5E74IJB.js.map +1 -0
  31. package/dist/{chunk-27N2SPTN.js → chunk-IXBKFQH5.js} +12 -11
  32. package/dist/chunk-IXBKFQH5.js.map +1 -0
  33. package/dist/{chunk-SQTCS44W.js → chunk-JFFVBEDI.js} +3 -3
  34. package/dist/{chunk-SQTCS44W.js.map → chunk-JFFVBEDI.js.map} +1 -1
  35. package/dist/chunk-LYLDCIPH.js +365 -0
  36. package/dist/chunk-LYLDCIPH.js.map +1 -0
  37. package/dist/{chunk-HJO6VNQI.js → chunk-MU6MCIAC.js} +3 -3
  38. package/dist/{chunk-HJO6VNQI.js.map → chunk-MU6MCIAC.js.map} +1 -1
  39. package/dist/{chunk-UYWUVEP6.js → chunk-MUUROGIH.js} +2 -2
  40. package/dist/chunk-MUUROGIH.js.map +1 -0
  41. package/dist/{chunk-EHIX7NYZ.js → chunk-MVY5DAMF.js} +4 -4
  42. package/dist/{chunk-EHIX7NYZ.js.map → chunk-MVY5DAMF.js.map} +1 -1
  43. package/dist/{chunk-LP7VQBRG.js → chunk-NPERUUUE.js} +76 -95
  44. package/dist/chunk-NPERUUUE.js.map +1 -0
  45. package/dist/{chunk-QLA76GIT.js → chunk-PBDYW2TU.js} +68 -9
  46. package/dist/chunk-PBDYW2TU.js.map +1 -0
  47. package/dist/{chunk-5VNWZADP.js → chunk-Q2UM7BXU.js} +18 -7
  48. package/dist/chunk-Q2UM7BXU.js.map +1 -0
  49. package/dist/chunk-RMX4EOQK.js +26 -0
  50. package/dist/chunk-RMX4EOQK.js.map +1 -0
  51. package/dist/{chunk-2YOE5PIS.js → chunk-S2EGRPCM.js} +8 -6
  52. package/dist/chunk-S2EGRPCM.js.map +1 -0
  53. package/dist/{chunk-ON24RKSE.js → chunk-S4O26D7B.js} +7 -14
  54. package/dist/chunk-S4O26D7B.js.map +1 -0
  55. package/dist/{chunk-3XJWC7VW.js → chunk-SK5JGUY7.js} +3 -3
  56. package/dist/{chunk-3XJWC7VW.js.map → chunk-SK5JGUY7.js.map} +1 -1
  57. package/dist/{chunk-5DEQ5I3U.js → chunk-TPGASTFF.js} +8 -10
  58. package/dist/chunk-TPGASTFF.js.map +1 -0
  59. package/dist/{chunk-SC3FAFZN.js → chunk-UF4MZSLT.js} +2 -2
  60. package/dist/chunk-UF4MZSLT.js.map +1 -0
  61. package/dist/{chunk-PS23H6KQ.js → chunk-VBUCHVCV.js} +6 -5
  62. package/dist/chunk-VBUCHVCV.js.map +1 -0
  63. package/dist/{chunk-S3FQN4SL.js → chunk-WGGAMW7Y.js} +191 -178
  64. package/dist/chunk-WGGAMW7Y.js.map +1 -0
  65. package/dist/chunk-ZJ5AOYBH.js +8 -0
  66. package/dist/chunk-ZJ5AOYBH.js.map +1 -0
  67. package/dist/{chunk-LEC4U6CX.js → chunk-ZVJZ72HY.js} +3 -3
  68. package/dist/{chunk-LEC4U6CX.js.map → chunk-ZVJZ72HY.js.map} +1 -1
  69. package/dist/circuit-breaker/index.d.ts +1 -0
  70. package/dist/circuit-breaker/index.js +1 -1
  71. package/dist/{core-BoB6t7dB.d.ts → core-42kapW0n.d.ts} +105 -6
  72. package/dist/deadline/index.d.ts +77 -11
  73. package/dist/deadline/index.js +3 -3
  74. package/dist/devtools/index.js +8 -28
  75. package/dist/devtools/index.js.map +1 -1
  76. package/dist/do/index.d.ts +483 -339
  77. package/dist/do/index.js +244 -214
  78. package/dist/do/index.js.map +1 -1
  79. package/dist/{durable-effects-CO9Uh971.d.ts → durable-effects-CFRngTNA.d.ts} +3 -3
  80. package/dist/extension/index.d.ts +25 -7
  81. package/dist/extension/index.js +4 -3
  82. package/dist/extension/index.js.map +1 -1
  83. package/dist/extension/react.js +4 -3
  84. package/dist/extension/react.js.map +1 -1
  85. package/dist/extension/subs/index.d.ts +2 -2
  86. package/dist/extension/subs/index.js +7 -10
  87. package/dist/extension/subs/index.js.map +1 -1
  88. package/dist/fan-out/index.d.ts +10 -10
  89. package/dist/fan-out/index.js +3 -3
  90. package/dist/idempotent-intake/index.d.ts +2 -2
  91. package/dist/idempotent-intake/index.js +3 -3
  92. package/dist/index.d.ts +50 -472
  93. package/dist/index.js +2 -2
  94. package/dist/llm-call/index.d.ts +3 -2
  95. package/dist/llm-call/index.js +12 -10
  96. package/dist/machine-B_BF4jij.d.ts +804 -0
  97. package/dist/machine-viz/index.d.ts +1 -1
  98. package/dist/machine-viz/index.js +2 -2
  99. package/dist/mem/index.d.ts +3 -2
  100. package/dist/mem/index.js.map +1 -1
  101. package/dist/monitored-run/index.d.ts +54 -30
  102. package/dist/monitored-run/index.js +7 -7
  103. package/dist/node/index.d.ts +3 -2
  104. package/dist/node/index.js +2 -3
  105. package/dist/node/index.js.map +1 -1
  106. package/dist/paginated-walk/index.d.ts +2 -2
  107. package/dist/paginated-walk/index.js +11 -10
  108. package/dist/parity/index.d.ts +6 -5
  109. package/dist/parity/index.js +5 -4
  110. package/dist/parity/index.js.map +1 -1
  111. package/dist/pbt/arbitraries/index.d.ts +1 -1
  112. package/dist/pbt/index.d.ts +1 -1
  113. package/dist/pbt/index.js +3 -3
  114. package/dist/pbt/index.js.map +1 -1
  115. package/dist/pbt/runners/index.d.ts +1 -1
  116. package/dist/pbt/runners/index.js +3 -3
  117. package/dist/poller/index.d.ts +59 -17
  118. package/dist/poller/index.js +56 -20
  119. package/dist/poller/index.js.map +1 -1
  120. package/dist/prediction/index.d.ts +1 -1
  121. package/dist/prediction/index.js +2 -2
  122. package/dist/pure/index.d.ts +1 -1
  123. package/dist/pure/index.js +2 -2
  124. package/dist/rate-limit/index.d.ts +2 -2
  125. package/dist/rate-limit/index.js +1 -1
  126. package/dist/react/index.d.ts +3 -2
  127. package/dist/react/index.js +2 -2
  128. package/dist/react/index.js.map +1 -1
  129. package/dist/reconciler/index.d.ts +2 -2
  130. package/dist/reconciler/index.js +13 -15
  131. package/dist/reconciler/index.js.map +1 -1
  132. package/dist/recorder/index.d.ts +20 -20
  133. package/dist/recorder/index.js +1 -1
  134. package/dist/resilient-call/index.d.ts +31 -6
  135. package/dist/resilient-call/index.js +10 -9
  136. package/dist/retry-backoff/index.d.ts +191 -14
  137. package/dist/retry-backoff/index.js +1 -1
  138. package/dist/retry-to-success/index.js +1 -1
  139. package/dist/runtime-types-gsog27b6.d.ts +337 -0
  140. package/dist/saga/index.d.ts +3 -2
  141. package/dist/saga/index.js +2 -2
  142. package/dist/saga/index.js.map +1 -1
  143. package/dist/snapshot/index.d.ts +1 -1
  144. package/dist/snapshot/index.js +3 -3
  145. package/dist/subs/index.d.ts +372 -4
  146. package/dist/subs/index.js +4 -1
  147. package/dist/testing/index.d.ts +2 -2
  148. package/dist/testing/index.js +2 -2
  149. package/dist/throttled-input/index.d.ts +2 -2
  150. package/dist/throttled-input/index.js +14 -13
  151. package/dist/throttled-input/index.js.map +1 -1
  152. package/dist/token-refresh/index.d.ts +1 -1
  153. package/dist/token-refresh/index.js +3 -3
  154. package/dist/trace-replay/index.d.ts +12 -7
  155. package/dist/trace-replay/index.js +4 -3
  156. package/dist/{types-B-8bcAp8.d.ts → types-KbL3W1mj.d.ts} +1 -1
  157. package/dist/with-deadline/index.d.ts +1 -1
  158. package/dist/with-deadline/index.js +2 -2
  159. package/dist/with-resilience/index.d.ts +21 -2
  160. package/dist/with-resilience/index.js +12 -23
  161. package/dist/with-resilience/index.js.map +1 -1
  162. package/dist/with-telemetry/index.d.ts +1 -1
  163. package/dist/with-telemetry/index.js +2 -2
  164. package/dist/work-queue/adapter.d.ts +2 -2
  165. package/dist/work-queue/adapter.js +2 -2
  166. package/dist/work-queue/index.d.ts +3 -2
  167. package/dist/work-queue/index.js +1 -1
  168. package/dist/work-queue/index.js.map +1 -1
  169. package/dist/work-queue/ops.d.ts +2 -2
  170. package/dist/work-queue/ops.js +1 -1
  171. package/dist/workflow/index.d.ts +51 -19
  172. package/dist/workflow/index.js +71 -52
  173. package/dist/workflow/index.js.map +1 -1
  174. package/package.json +4 -19
  175. package/dist/chunk-27N2SPTN.js.map +0 -1
  176. package/dist/chunk-2YOE5PIS.js.map +0 -1
  177. package/dist/chunk-3545BOYL.js.map +0 -1
  178. package/dist/chunk-5DEQ5I3U.js.map +0 -1
  179. package/dist/chunk-5VNWZADP.js.map +0 -1
  180. package/dist/chunk-6RGBKODV.js +0 -268
  181. package/dist/chunk-6RGBKODV.js.map +0 -1
  182. package/dist/chunk-7W4LMPUW.js.map +0 -1
  183. package/dist/chunk-DILMKOZ7.js +0 -91
  184. package/dist/chunk-DILMKOZ7.js.map +0 -1
  185. package/dist/chunk-K7Q23EQ4.js +0 -20
  186. package/dist/chunk-K7Q23EQ4.js.map +0 -1
  187. package/dist/chunk-LP7VQBRG.js.map +0 -1
  188. package/dist/chunk-MMH7CW5K.js.map +0 -1
  189. package/dist/chunk-NSDFA6M6.js +0 -198
  190. package/dist/chunk-NSDFA6M6.js.map +0 -1
  191. package/dist/chunk-ON24RKSE.js.map +0 -1
  192. package/dist/chunk-PS23H6KQ.js.map +0 -1
  193. package/dist/chunk-QLA76GIT.js.map +0 -1
  194. package/dist/chunk-S3FQN4SL.js.map +0 -1
  195. package/dist/chunk-SC3FAFZN.js.map +0 -1
  196. package/dist/chunk-TGG26XMK.js.map +0 -1
  197. package/dist/chunk-UV6UWGEO.js.map +0 -1
  198. package/dist/chunk-UYWUVEP6.js.map +0 -1
  199. package/dist/chunk-VLGARN6H.js +0 -202
  200. package/dist/chunk-VLGARN6H.js.map +0 -1
  201. package/dist/raft/demo.d.ts +0 -105
  202. package/dist/raft/demo.js +0 -172
  203. package/dist/raft/demo.js.map +0 -1
  204. package/dist/raft/index.d.ts +0 -548
  205. package/dist/raft/index.js +0 -7
  206. package/dist/raft/index.js.map +0 -1
  207. package/dist/raft/sim.d.ts +0 -222
  208. package/dist/raft/sim.js +0 -8
  209. package/dist/raft/sim.js.map +0 -1
  210. package/dist/raft/timeline.d.ts +0 -46
  211. package/dist/raft/timeline.js +0 -62
  212. package/dist/raft/timeline.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,459 +1,15 @@
1
- import { C as Cmd, P as Port, S as Sub, M as Machine, T as Transitions, R as Reducer } from './core-BoB6t7dB.js';
2
- export { b as ContextFree, I as Interpret, N as NoCtx, c as PortEmitter, a as SubId, d as Subscribe, e as SyncReturn, U as UpdateForm, f as applyCell, g as detectUpdateForm, h as foldMsgs, i as formOf, m as msgKeysOf, s as subId } from './core-BoB6t7dB.js';
1
+ import { B as BootingRuntime, C as CtxArg, S as Store, O as OnError, a as Supervision } from './runtime-types-gsog27b6.js';
2
+ export { b as Branded, D as DispatchSettle, P as PortNameCollisionError, Q as QuiescenceTimeoutError, R as Runtime, f as RuntimeErrorContext, e as RuntimeErrorPhase, j as RuntimeRef, i as Schema, d as SubIdCollisionError, g as SupervisionStrategy, _ as __resetPortRegistry, c as absurd, l as asReducer, k as defineMachine, h as definePort, n as noop, r as replay, s as schemaMigrate, t as tryInterpret, w as wrapDetached } from './runtime-types-gsog27b6.js';
3
+ import { C as Cmd, S as Sub, M as Machine } from './core-42kapW0n.js';
4
+ export { d as ContextFree, D as DepKeyedSub, e as Dispose, f as Identity, c as Interpret, I as InterpretDetached, n as NoCellError, N as NoCtx, P as Port, b as PortEmitter, R as Reducer, a as SubId, g as Subscribe, h as SyncReturn, T as Transitions, U as UpdateForm, i as applyCell, j as detectUpdateForm, k as foldMsgs, l as formOf, m as msgKeysOf, s as structuralHash, o as subId } from './core-42kapW0n.js';
3
5
 
4
- /**
5
- * @demlik/tea — TEA-faithful state machine substrate.
6
- *
7
- * This module exposes the full Locked API Surface from the PRD as types and
8
- * implements `defineMachine` (identity, task 1), `run` (task 2), and
9
- * `replay` + `tryInterpret` (task 3).
10
- *
11
- * `replay` is the pure unit-test tool: it composes `init` + `update` only,
12
- * never touches `Store`, never calls `interpret`, never starts subscriptions.
13
- *
14
- * `tryInterpret` is Railway sugar — wraps a fallible async function and routes
15
- * Ok/Err to two Msg constructors via better-result.
16
- */
17
-
18
- declare const ReducerBrand: unique symbol;
19
- type Branded<T> = T & {
20
- readonly [ReducerBrand]: true;
21
- };
22
- /**
23
- * Compile-time exhaustiveness assertion. Use in default branches of
24
- * switches over discriminated unions where every case should be handled
25
- * explicitly — TS narrows the type to `never` only if every variant has
26
- * been covered. Strengthens invariant 7 (identity is explicit).
27
- *
28
- * @example
29
- * switch (msg.type) {
30
- * case "a": return ...;
31
- * case "b": return ...;
32
- * default: return absurd(msg); // compile error if a "c" is added
33
- * }
34
- */
35
- declare function absurd(x: never): never;
36
- declare const noop: <S, M, C extends Cmd>(state: S, _msg: M) => readonly [S, readonly C[]];
37
- /**
38
- * Thrown by `definePort` when a name has already been registered in the
39
- * current process. Symmetric with the `Sub.id` collision assert in
40
- * `reconcileSubs` — both mechanize invariant 7 (identity is explicit) at the
41
- * runtime layer the type system cannot reach (string names compared at
42
- * runtime, not at compile time).
43
- */
44
- declare class PortNameCollisionError extends Error {
45
- readonly name = "PortNameCollisionError";
46
- constructor(portName: string);
47
- }
48
- /**
49
- * Test-only escape hatch — clears the module-level port-name registry so the
50
- * collision assert in `definePort` doesn't false-positive across vitest's
51
- * non-isolated runs. Production code MUST NOT call this; the registry is the
52
- * invariant-7 witness for the process lifetime.
53
- *
54
- * @internal test-only
55
- */
56
- declare function __resetPortRegistry(): void;
57
- /**
58
- * Which otherwise-unattributable runtime path produced an error.
59
- *
60
- * - `"follow-up"` — a follow-up Msg an interpret handler returned rejected
61
- * when re-dispatched. The original dispatcher already resolved, so this
62
- * rejection has no caller; without the sink it was swallowed.
63
- * - `"stop-save"` — the final `store.save(state)` inside `stop()` threw.
64
- * `stop()` resolves regardless (its contract), so without the sink this was
65
- * silent loss of the last write.
66
- * - `"reduce"` — the pure `update` (reducer) threw synchronously while folding
67
- * a Msg. #71's reentrancy brand makes a reducer provably synchronous, so this
68
- * throw is catchable in the dispatch loop; the configured `Supervision`
69
- * strategy decides what the runtime does next (`stop` / `escalate` /
70
- * `restart`), but the failure is ALWAYS surfaced here as data first.
71
- */
72
- type RuntimeErrorPhase = "follow-up" | "stop-save" | "reduce";
73
- /** Context handed to an `OnError` sink alongside the error itself. */
74
- interface RuntimeErrorContext {
75
- readonly phase: RuntimeErrorPhase;
76
- }
77
- /**
78
- * Sink for runtime failures that have no caller to reject at. Configured via
79
- * `run(machine, { onError })`. Should be total — a throw inside the sink is
80
- * itself surfaced via `defaultOnError`, so the sink can never re-introduce a
81
- * silent failure.
82
- */
83
- type OnError = (error: unknown, context: RuntimeErrorContext) => void;
84
- /** The three declared reducer-throw supervision strategies. */
85
- type SupervisionStrategy = "stop" | "escalate" | "restart";
86
- /**
87
- * Declared supervision policy for a reducer (`update`) throw, configured at
88
- * `run(machine, { supervision })`.
89
- *
90
- * - `{ strategy: "stop" }` — halt + surface (the safe default; also the bare
91
- * shorthand `"stop"`).
92
- * - `{ strategy: "escalate" }` — surface + propagate, runtime stays live (also
93
- * the bare shorthand `"escalate"`).
94
- * - `{ strategy: "restart", rehydrate }` — surface, then re-init from the
95
- * host-supplied last-known-good `S` and keep folding. `rehydrate` receives
96
- * the failing `(state, msg, error)` so the host can log / pick a snapshot;
97
- * it MUST return a valid `S` synchronously (the reducer is synchronous, so
98
- * recovery is too — no suspension across the single-writer slot).
99
- *
100
- * The bare-string shorthands (`"stop"` / `"escalate"`) are accepted for the two
101
- * strategies that need no host data; `restart` MUST be the object form because
102
- * it carries the `rehydrate` callback.
103
- */
104
- type Supervision<S, M extends {
105
- type: string;
106
- }> = "stop" | "escalate" | {
107
- readonly strategy: "stop";
108
- } | {
109
- readonly strategy: "escalate";
110
- } | {
111
- readonly strategy: "restart";
112
- /**
113
- * Host-provided rehydration to last-known-good state. Invoked by the core
114
- * when the reducer throws; its return value becomes the new state and the
115
- * transition continues from there. Receives the pre-throw `state`, the
116
- * `msg` that triggered the throw, and the thrown `error` so the host can
117
- * route by cause.
118
- */
119
- readonly rehydrate: (state: S, msg: M, error: unknown) => S;
120
- };
121
- /**
122
- * Raised by `idle()` when the quiescence wait hits its iteration cap without
123
- * the dispatch tail stabilizing. Replaces the old silent fall-through-resolve
124
- * (which made "the loop quiesced" indistinguishable from "we gave up"):
125
- * `idle()` now REJECTS with this so a livelocking machine surfaces instead of
126
- * masquerading as quiescent.
127
- *
128
- * Mechanizes invariant 6 (no silent failures) at the runtime layer — the same
129
- * role `PortNameCollisionError` plays for invariant 7.
130
- */
131
- declare class QuiescenceTimeoutError extends Error {
132
- readonly iterations: number;
133
- readonly name = "QuiescenceTimeoutError";
134
- constructor(iterations: number);
135
- }
136
- /**
137
- * Define a typed port. `name` is metadata (shown in devtools / debug logs);
138
- * port identity is by reference. Each definePort call must use a unique
139
- * `name` — a second call with the same name throws
140
- * `PortNameCollisionError`. If two modules need the same port, export it
141
- * from one module and import it from the other.
142
- *
143
- * Use ports for "data leaving the runtime selectively" — e.g. cursor
144
- * announcements, DOM-mutation broadcasts, telemetry events that should NOT be
145
- * folded into State and should NOT be observed by every transition listener.
146
- *
147
- * Strengthens invariant 7 (identity is explicit) — the runtime assert is the
148
- * Port-side counterpart of `SubId`'s id collision check in `reconcileSubs`.
149
- */
150
- declare function definePort<T>(name: string): Port<T>;
151
- interface Store<S> {
152
- load(): Promise<unknown>;
153
- save(state: S): Promise<void>;
154
- migrate(raw: unknown): S | null;
155
- }
156
- type DispatchSettle = "quiescent" | "once";
157
- interface RuntimeRef<M extends {
158
- type: string;
159
- }> {
160
- /**
161
- * Put a Msg in the runtime's inbox and resolve once it has been processed.
162
- *
163
- * Runs to QUIESCENCE by default (issue #50): the returned promise settles
164
- * only after the dispatched Msg AND every follow-up Msg its `interpret`
165
- * handlers (transitively) returned have drained off the serial tail. This is
166
- * the safe default — `await dispatch(msg)` means "the consequences have run",
167
- * not "one transition fired and the rest are racing". Pass
168
- * `{ settle: "once" }` (or call `dispatchOnce`) for the rare single-step
169
- * case where the caller will await the tail itself.
170
- *
171
- * Rejection ordering: the ONE dispatched transition's own failure (a reducer
172
- * / save / sub-start / interpret throw) surfaces first, on this promise. If
173
- * that transition succeeds but the follow-up chain never stabilizes, the
174
- * quiescent drain rejects with `QuiescenceTimeoutError` (same cap and same
175
- * no-silent-give-up contract as `idle()` — issue #51). Follow-up Msg
176
- * rejections themselves route to the `onError` sink, never here.
177
- */
178
- dispatch(msg: M, opts?: {
179
- readonly settle?: DispatchSettle;
180
- }): Promise<void>;
181
- /**
182
- * Dispatch `msg` and resolve after exactly ONE transition's effects settle,
183
- * WITHOUT draining the follow-up chain. Equivalent to
184
- * `dispatch(msg, { settle: "once" })`.
185
- *
186
- * This is the old (pre-#50) `dispatch` behavior, kept as an explicit escape
187
- * hatch: a caller that wants to interleave its own work between the first
188
- * transition and its follow-ups, then `await runtime.idle()` itself. Prefer
189
- * plain `dispatch` (run-to-quiescence) unless you specifically need the
190
- * single step — the un-awaited follow-up chain is exactly the footgun #50
191
- * removed from the default.
192
- */
193
- dispatchOnce(msg: M): Promise<void>;
194
- }
195
- interface BootingRuntime<S, M extends {
196
- type: string;
197
- }, E extends {
198
- type: string;
199
- } = never> extends RuntimeRef<M> {
200
- dispatch(msg: M, opts?: {
201
- readonly settle?: DispatchSettle;
202
- }): Promise<void>;
203
- dispatchOnce(msg: M): Promise<void>;
204
- subscribe(listener: () => void): () => void;
205
- observe(observer: (msg: M, state: S) => void): () => void;
206
- /**
207
- * Subscribe to the INITIAL State — the boot transition the old `observe`
208
- * `msg === null` arm carried (#47). Fires exactly once: immediately if boot
209
- * has already completed when `onBoot` is called (so a late subscriber never
210
- * misses it), otherwise on the boot fanout. Returns a cleanup that detaches
211
- * the handler (a no-op once it has fired).
212
- *
213
- * This is where the boot case the `observe` firehose used to fold in went
214
- * once `observe`'s `msg` became total: a consumer that needs to seed a view
215
- * from the initial State wires `onBoot`; a consumer that only folds events
216
- * (the common case) wires `observe` (or `on`) and is no longer handed a boot
217
- * arm to skip.
218
- */
219
- onBoot(handler: (state: S) => void): () => void;
220
- /**
221
- * Subscribe to a SEMANTIC event of `type` (#47). Typed narrowing: the handler
222
- * receives exactly the `E` member whose `type` matches `K`, so a consumer
223
- * built on `on("TurnSettled", …)` never touches another event's shape and —
224
- * critically — never references the machine's PRIVATE Msg names. Returns a
225
- * cleanup that detaches the handler. Multiple handlers per type are
226
- * supported; fanout is synchronous and throw-isolated (same discipline as
227
- * `observe`). Fires only when the machine's `events` projector (wired on
228
- * `run`) emits an event of that type for a transition.
229
- */
230
- on<K extends E["type"]>(type: K, handler: (event: Extract<E, {
231
- type: K;
232
- }>) => void): () => void;
233
- /**
234
- * Subscribe to a typed Port. Returns a cleanup function that removes the
235
- * listener. Multiple listeners per port are supported; fanout is synchronous
236
- * (same shape as `observe`) and isolated — one listener throw does not strand
237
- * the others.
238
- *
239
- * Ports are for "data leaving the runtime selectively" — see `definePort`.
240
- * Distinct from `observe` (every transition) and from State (the world).
241
- */
242
- subscribePort<T>(port: Port<T>, listener: (value: T) => void): () => void;
243
- /**
244
- * Emit a value on a Port from OUTSIDE an interpret handler. Same synchronous
245
- * fanout discipline as `ctx.emit` inside interpret — every subscriber
246
- * receives the value immediately; emitting to a port with no subscribers is
247
- * a no-op; listener throws are isolated.
248
- *
249
- * Use this for `observe`-driven Port emission: the canonical case is one
250
- * runtime publishing a state-derived signal (e.g. "am I idle?") that
251
- * another runtime subscribes to via `subscribePort`. Without
252
- * `runtime.emitPort`, the only way to emit a Port is from inside an
253
- * `interpret` handler — which forces the reducer to spawn a "tell the
254
- * outside world" Cmd on every transition that should signal. With it,
255
- * `runtime.observe((msg, state) => runtime.emitPort(port, derive(state)))`
256
- * keeps the reducer free of Port-plumbing Cmds and matches the "every
257
- * transition is observable" contract this invariant set already commits to.
258
- *
259
- * Strengthens invariant 6 (runtime is small and inspectable — Port emission
260
- * is no longer privileged to interpret handlers; `observe`-driven emission
261
- * is structurally supported).
262
- */
263
- emitPort<T>(port: Port<T>, value: T): void;
264
- /**
265
- * Resolves to the booted `Runtime<S, M>` after boot completes — i.e. after
266
- * `store.load()` (if any), `init`, `store.save()` of the initial state,
267
- * `reconcileSubs`, `interpret` of any init-emitted cmds, and the initial
268
- * listener / observer fanout. Rejects with the boot error if boot fails (the
269
- * same error every subsequent `dispatch` call rejects with).
270
- *
271
- * This is the ONLY way to obtain a `Runtime<S, M>` — and a `Runtime` is the
272
- * only handle whose `getState()` is total. Awaiting `ready` is therefore the
273
- * single gate between "boot in flight" and "State exists":
274
- *
275
- * ```ts
276
- * const runtime = await run(machine, opts).ready;
277
- * runtime.getState(); // total — never throws-before-boot
278
- * ```
279
- *
280
- * Idempotent — subsequent reads return the same settled promise. The runtime
281
- * holds exactly one `ready` promise per `run()` call; it resolves to the same
282
- * `Runtime` object every time.
283
- *
284
- * Closes issue #45 (the `getState()` lie) and the v1 boot-await gap once
285
- * documented in `stepBootEffects`: components that need synchronous initial
286
- * state under a store (e.g. `useSyncExternalStore` consumers) await `ready`
287
- * for the booted runtime instead of dispatching a no-op Msg.
288
- *
289
- * Expresses canon §2.3 (the `init` contract — boot is a named, awaitable
290
- * moment). Strengthens invariant 6 (runtime is small and inspectable).
291
- */
292
- ready: Promise<Runtime<S, M, E>>;
293
- stop(): Promise<void>;
294
- }
295
- interface Runtime<S, M extends {
296
- type: string;
297
- }, E extends {
298
- type: string;
299
- } = never> extends BootingRuntime<S, M, E> {
300
- /**
301
- * The current State. TOTAL — never throws. Obtaining a `Runtime` requires
302
- * awaiting `ready`, which only resolves AFTER boot has run `init` and set the
303
- * initial State; a `Runtime` therefore always has a State to return. (Before
304
- * #45 this was declared on the synchronously-returned handle and threw under
305
- * a store until boot finished — the type lied. It no longer does.)
306
- */
307
- getState(): S;
308
- /**
309
- * Resolves to this same `Runtime` once boot completes. Idempotent.
310
- */
311
- ready: Promise<Runtime<S, M, E>>;
312
- /**
313
- * Resolves once the runtime has reached QUIESCENCE — every dispatched Msg AND
314
- * every follow-up Msg an interpret handler returned has been processed, with
315
- * no further step pending on the serial tail.
316
- *
317
- * Since #50, plain `dispatch(msg)` already runs to quiescence (it awaits this
318
- * same drain after its own transition), so a caller rarely needs `idle()`
319
- * directly. `idle()` is still the right tool to (a) settle follow-ups left in
320
- * flight by a `dispatchOnce` / `dispatch(msg, { settle: "once" })` single
321
- * step, or (b) wait out a follow-up chain kicked off by a Sub or by boot
322
- * `init` cmds where there was no `dispatch` call to await. It chains onto the
323
- * current tail and re-checks until the tail stops advancing, draining the
324
- * entire transitive follow-up chain.
325
- *
326
- * Idempotent and re-entrant-safe: each call reads the live tail; a tail that
327
- * advanced during the await (a follow-up landed) is awaited again until
328
- * stable. Tail rejections are NOT surfaced here — a failing dispatch
329
- * surfaces on its OWN returned promise (and follow-up rejections route to
330
- * the `onError` sink). The ONE rejection `idle()` itself produces is a
331
- * `QuiescenceTimeoutError` when the wait hits its iteration cap without the
332
- * tail stabilizing: that replaces the old silent fall-through-resolve so a
333
- * livelocking machine is distinguishable from a genuinely quiesced one
334
- * (invariant 6 — no silent failures).
335
- *
336
- * Use `idle()` for runtime-internal follow-ups; a poll is still correct when
337
- * waiting on an EXTERNAL event (a WS reply) the runtime cannot enqueue itself.
338
- *
339
- * Strengthens invariant 6 (runtime is small and inspectable — quiescence is a
340
- * first-class awaitable moment, not a poll the consumer re-derives).
341
- */
342
- idle(): Promise<void>;
343
- /**
344
- * The terminal State of the run, or `undefined` while it is still in flight.
345
- * A run is "terminal" exactly when the `terminal` predicate passed to `run()`
346
- * returns `true` for the current State; with no predicate supplied a run is
347
- * never terminal and this always returns `undefined`.
348
- *
349
- * This is the FIRST-CLASS result read (issue #46): the outcome of running the
350
- * thing, off the State the machine already owns — NOT scraped off the
351
- * `observe` firehose by matching an internal Msg name (`resilient_ok`) and
352
- * racing a state-clear. The consumer reads the run's product (e.g. an agent's
353
- * `state.output`) off the returned `S`, with no coupling to the machine's
354
- * private retry / loop vocabulary.
355
- *
356
- * Total — never throws (a `Runtime` always has a State; see `getState`).
357
- */
358
- result(): S | undefined;
359
- /**
360
- * Resolves with the terminal State the first time the run reaches a terminal
361
- * State (per the `terminal` predicate passed to `run()`). If the run is
362
- * ALREADY terminal when `done()` is called, resolves immediately with the
363
- * current State; otherwise resolves on the transition that first makes
364
- * `terminal` hold.
365
- *
366
- * The awaitable companion to `result()` — "wait for the run to finish, then
367
- * hand me what it produced" in one call, instead of polling `result()` or
368
- * hand-rolling an `observe` loop that watches for a private terminal Msg.
369
- * With no `terminal` predicate supplied the run is never terminal, so this
370
- * promise never resolves (a non-terminating machine has no result to await).
371
- *
372
- * Idempotent and multi-caller safe: every call observes the live State, so a
373
- * call made after the run already terminated resolves at once, and concurrent
374
- * callers all settle on the same terminal transition.
375
- */
376
- done(): Promise<S>;
377
- }
378
- declare function defineMachine<S, M extends {
379
- type: string;
380
- }, C extends Cmd, U extends Sub, Ctx>(m: Omit<Machine<S, M, C, U, Ctx>, "update"> & {
381
- update: [S] extends [{
382
- type: string;
383
- }] ? Transitions<S, M, C> : never;
384
- }): Machine<S, M, C, U, Ctx>;
385
- declare function defineMachine<S, M extends {
386
- type: string;
387
- }, C extends Cmd, U extends Sub, Ctx>(m: Omit<Machine<S, M, C, U, Ctx>, "update"> & {
388
- update: Reducer<S, M, C>;
389
- }): Machine<S, M, C, U, Ctx>;
390
- declare function asReducer<S, M extends {
391
- type: string;
392
- }, C extends Cmd>(reducer: Reducer<S, M, C>): Branded<Reducer<S, M, C>>;
393
- type CtxArg<Ctx> = [Record<never, never>] extends [Ctx] ? {
394
- ctx?: Ctx;
395
- } : {
396
- ctx: Ctx;
397
- };
398
- declare function run<S, M extends {
399
- type: string;
400
- }, C extends Cmd, U extends Sub, Ctx, E extends {
401
- type: string;
402
- } = never>(machine: Machine<S, M, C, U, Ctx>, opts: CtxArg<Ctx> & {
403
- store?: Store<S>;
404
- onError?: OnError;
405
- /**
406
- * The SEMANTIC event projector (#47). Maps one APPLIED transition `(msg,
407
- * state)` to zero-or-more public events of the machine-level union `E`.
408
- * Returning `[]` skips the transition (it produced no event the consumer's
409
- * `on(type, …)` cares about). This is where a machine maps its PRIVATE Msg
410
- * vocabulary (a retry plumbing's `resilient_ok`, a tool loop's
411
- * `agent_tool_ok`) to NAMED events — the private names live only inside this
412
- * closure and never reach `on`'s `E` surface. Omit → the run has no event
413
- * surface (`E = never`) and `on` is uncallable.
414
- *
415
- * PURE — called inside the dispatch loop on the freshly-folded `(msg,
416
- * state)`; it must not read the clock, mutate, or throw (a throw is
417
- * isolated like an observer throw, never stranding the transition).
418
- */
419
- events?: (msg: M, state: S) => readonly E[];
420
- /**
421
- * Declared policy for when the pure `update` (reducer) throws. The reducer
422
- * throw is always surfaced via `onError` (`phase: "reduce"`); the strategy
423
- * decides what the runtime does next. Defaults to `"stop"` — the explicit,
424
- * safe choice (surface + halt, never a silent resume). See `Supervision`.
425
- */
426
- supervision?: Supervision<S, M>;
427
- /**
428
- * The run-terminality predicate — what makes the run's outcome first-class
429
- * (issue #46). Returns `true` for a State the run has finished in (e.g. an
430
- * agent's `state.run.phase === "done"`). The runtime feeds it to
431
- * `Runtime.result()` (the terminal State, or `undefined` in flight) and
432
- * `Runtime.done()` (resolves with the terminal State when it first holds).
433
- *
434
- * PURE — the runtime calls it inside the dispatch loop on the freshly-folded
435
- * State; it must not read the clock, mutate, or throw. Omit → the run is
436
- * never terminal: `result()` always returns `undefined` and `done()` never
437
- * resolves (the right behavior for a machine with no natural completion).
438
- */
439
- terminal?: (state: S) => boolean;
440
- /**
441
- * Iteration cap for `idle()`'s quiescence wait. Defaults to 100_000. Test
442
- * seam only — lets a livelock test trip the `QuiescenceTimeoutError` reject
443
- * path in a handful of iterations instead of 100k. Production code must not
444
- * set it.
445
- *
446
- * @internal test-only
447
- */
448
- __idleCap?: number;
449
- }): BootingRuntime<S, M, E>;
450
6
  interface HistoryTracker<S, M extends {
451
7
  type: string;
452
8
  }> {
453
9
  /**
454
10
  * Snapshot of recorded transitions, oldest first. Each entry is
455
- * `{ msg, state }` exactly as the underlying `observe` callback received
456
- * it — `msg` is `null` for the boot transition, a Msg for every other.
11
+ * `{ msg, state }`: `msg` is `null` for the boot transition (recorded via
12
+ * `onBoot`) and the applied Msg for every other (recorded via `observe`).
457
13
  *
458
14
  * Returns a shallow copy: the array is fresh on every call (callers may
459
15
  * iterate, slice, or replay without affecting the tracker's buffer).
@@ -477,9 +33,9 @@ interface HistoryTracker<S, M extends {
477
33
  stop(): void;
478
34
  }
479
35
  /**
480
- * Create a bounded history tracker over a Runtime. The tracker subscribes
481
- * to the runtime via `observe(...)` and retains the last `size` `(msg,
482
- * state)` transitions in a FIFO ring buffer.
36
+ * Create a bounded history tracker over a Runtime. The tracker subscribes to
37
+ * the runtime via `observe(...)` and retains the last `size` `(msg, state)`
38
+ * transitions in a FIFO ring buffer.
483
39
  *
484
40
  * @param runtime Any `BootingRuntime<S, M>` (a full `Runtime` satisfies it).
485
41
  * The tracker uses only `observe`, which is total before boot —
@@ -487,28 +43,50 @@ interface HistoryTracker<S, M extends {
487
43
  * boot transition.
488
44
  * @param size Buffer cap. `size <= 0` produces an inert no-op tracker:
489
45
  * no observer is attached to the runtime, `snapshot()` is
490
- * always `[]`, and `stop()` is a no-op. (Prefer skipping the
491
- * tracker entirely in that case — this arm just makes a
492
- * non-positive `size` harmless rather than an error.)
493
- *
494
- * Memory cost: O(size × avg(msg + state size)). For audit-extension's
495
- * inspector use case (size 100, audit state ~5KB), ~500KB max — held
496
- * in-memory only, no persistence.
46
+ * always `[]`, and `stop()` is a no-op.
497
47
  */
498
48
  declare function historyTracker<S, M extends {
499
49
  type: string;
500
50
  }>(runtime: BootingRuntime<S, M>, size: number): HistoryTracker<S, M>;
501
- declare function replay<S, M extends {
51
+
52
+ /**
53
+ * @demlik/tea runtime — `run`: boot + the serial dispatch loop. The pure helpers
54
+ * that compose against a machine without running it (`replay`, `tryInterpret`)
55
+ * live in `./runtime-types`.
56
+ */
57
+
58
+ declare function run<S, M extends {
59
+ type: string;
60
+ }, C extends Cmd, U extends Sub, Ctx, E extends {
502
61
  type: string;
503
- }, C extends Cmd, U extends Sub, Ctx>(machine: Machine<S, M, C, U, Ctx>, opts: {
504
- msgs: readonly M[];
505
- ctx: Ctx;
506
- loaded?: S | null;
507
- }): {
508
- state: S;
509
- cmds: C[];
510
- subs: U[];
511
- };
512
- declare function tryInterpret<C extends Cmd, Ok, M, Ctx>(work: (cmd: C, ctx: Ctx) => Promise<Ok>, onOk: (value: Ok, cmd: C) => M, onErr: (error: unknown, cmd: C) => M): (cmd: C, ctx: Ctx) => Promise<M>;
62
+ } = never>(machine: Machine<S, M, C, U, Ctx>, opts: CtxArg<Ctx> & {
63
+ store?: Store<S>;
64
+ onError?: OnError;
65
+ /**
66
+ * The SEMANTIC event projector. Maps one APPLIED transition `(msg, state)`
67
+ * to zero-or-more public events of `E`; `[]` skips the transition. Maps the
68
+ * machine's PRIVATE Msg vocabulary to NAMED events — the private names never
69
+ * reach `on`'s `E` surface. Omit → `E = never` and `on` is uncallable. PURE.
70
+ */
71
+ events?: (msg: M, state: S) => readonly E[];
72
+ /**
73
+ * Declared policy for a reducer (`update`) throw. Always surfaced via
74
+ * `onError` (`phase: "reduce"`); the strategy decides what the runtime does
75
+ * next. Defaults to `"stop"`. See `Supervision`.
76
+ */
77
+ supervision?: Supervision<S, M>;
78
+ /**
79
+ * The run-terminality predicate — makes the run's outcome first-class. Fed to
80
+ * `Runtime.result()` and `Runtime.done()`. PURE. Omit → never terminal.
81
+ */
82
+ terminal?: (state: S) => boolean;
83
+ /**
84
+ * Iteration cap for `idle()`'s quiescence wait. Defaults to 100_000. Test
85
+ * seam only. Production code must not set it.
86
+ *
87
+ * @internal test-only
88
+ */
89
+ __idleCap?: number;
90
+ }): BootingRuntime<S, M, E>;
513
91
 
514
- export { type BootingRuntime, type Branded, Cmd, type CtxArg, type DispatchSettle, type HistoryTracker, Machine, type OnError, Port, PortNameCollisionError, QuiescenceTimeoutError, Reducer, type Runtime, type RuntimeErrorContext, type RuntimeErrorPhase, type RuntimeRef, type Store, Sub, type Supervision, type SupervisionStrategy, Transitions, __resetPortRegistry, absurd, asReducer, defineMachine, definePort, historyTracker, noop, replay, run, tryInterpret };
92
+ export { BootingRuntime, Cmd, CtxArg, type HistoryTracker, Machine, OnError, Store, Sub, Supervision, historyTracker, run };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { PortNameCollisionError, QuiescenceTimeoutError, __resetPortRegistry, absurd, asReducer, defineMachine, definePort, historyTracker, noop, replay, run, tryInterpret } from './chunk-MMH7CW5K.js';
2
- export { Cmd, applyCell, detectUpdateForm, foldMsgs, formOf, msgKeysOf, subId } from './chunk-QLA76GIT.js';
1
+ export { PortNameCollisionError, QuiescenceTimeoutError, SubIdCollisionError, __resetPortRegistry, absurd, asReducer, defineMachine, definePort, historyTracker, noop, replay, run, schemaMigrate, tryInterpret, wrapDetached } from './chunk-BP2R7TPP.js';
2
+ export { Cmd, NoCellError, applyCell, detectUpdateForm, foldMsgs, formOf, msgKeysOf, structuralHash, subId } from './chunk-PBDYW2TU.js';
3
3
  //# sourceMappingURL=index.js.map
4
4
  //# sourceMappingURL=index.js.map
@@ -1,15 +1,16 @@
1
- import { C as Cmd } from '../core-BoB6t7dB.js';
1
+ import { C as Cmd } from '../core-42kapW0n.js';
2
2
  import { SucceedMsg, FailMsg, RunCmd, ResilientState } from '../resilient-call/index.js';
3
3
  import { RetryPolicy } from '../retry-backoff/index.js';
4
4
  import { DeadlineExceeded, DeadlineSub } from '../deadline/index.js';
5
5
  export { deadlineSub, subscribeDeadline } from '../deadline/index.js';
6
6
  import '../cache/index.js';
7
- import '../types-B-8bcAp8.js';
7
+ import '../types-KbL3W1mj.js';
8
8
  import '../circuit-breaker/index.js';
9
9
  import '../protocol-B5YmJr0d.js';
10
10
  import '../rate-limit/index.js';
11
11
 
12
12
  /**
13
+ * @packageDocumentation
13
14
  * @demlik/tea/llm-call — `resilient-call` + structured-output parse + a typed
14
15
  * failure variant, around a purpose-discriminated LLM invocation.
15
16
  *
@@ -1,14 +1,16 @@
1
- export { createLlmCall, liftLlmCall } from '../chunk-PS23H6KQ.js';
2
- import '../chunk-27N2SPTN.js';
1
+ export { createLlmCall, liftLlmCall } from '../chunk-VBUCHVCV.js';
2
+ import '../chunk-IXBKFQH5.js';
3
3
  import '../chunk-JELSZN25.js';
4
- export { deadlineSub, subscribeDeadline } from '../chunk-K7Q23EQ4.js';
5
- import '../chunk-5VNWZADP.js';
6
- import '../chunk-2YOE5PIS.js';
7
- import '../chunk-SC3FAFZN.js';
8
- import '../chunk-IN33Q4VJ.js';
9
- import '../chunk-NSDFA6M6.js';
4
+ export { deadlineSub, subscribeDeadline } from '../chunk-RMX4EOQK.js';
5
+ import '../chunk-Q2UM7BXU.js';
6
+ import '../chunk-S2EGRPCM.js';
7
+ import '../chunk-UF4MZSLT.js';
8
+ import '../chunk-2KNLKQVN.js';
9
+ import '../chunk-LYLDCIPH.js';
10
10
  import '../chunk-2YFLOCWX.js';
11
- import '../chunk-MMH7CW5K.js';
12
- import '../chunk-QLA76GIT.js';
11
+ import '../chunk-ZJ5AOYBH.js';
12
+ import '../chunk-G5E74IJB.js';
13
+ import '../chunk-BP2R7TPP.js';
14
+ import '../chunk-PBDYW2TU.js';
13
15
  //# sourceMappingURL=index.js.map
14
16
  //# sourceMappingURL=index.js.map