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