@demlik/tea 0.3.0 → 0.5.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 (117) hide show
  1. package/dist/agent/index.d.ts +5 -5
  2. package/dist/agent/index.js +10 -10
  3. package/dist/authed-call/index.d.ts +2 -2
  4. package/dist/authed-call/index.js +7 -7
  5. package/dist/await-terminal/index.d.ts +2 -2
  6. package/dist/await-terminal/index.js +2 -2
  7. package/dist/batch-window/index.d.ts +3 -3
  8. package/dist/batch-window/index.js +3 -3
  9. package/dist/cache/index.d.ts +2 -2
  10. package/dist/cache/index.js +4 -4
  11. package/dist/{chunk-S4O26D7B.js → chunk-362SZ6CS.js} +3 -3
  12. package/dist/{chunk-S4O26D7B.js.map → chunk-362SZ6CS.js.map} +1 -1
  13. package/dist/{chunk-JFFVBEDI.js → chunk-62QBHM3T.js} +3 -3
  14. package/dist/{chunk-JFFVBEDI.js.map → chunk-62QBHM3T.js.map} +1 -1
  15. package/dist/{chunk-TPGASTFF.js → chunk-7A74NSG4.js} +3 -3
  16. package/dist/{chunk-TPGASTFF.js.map → chunk-7A74NSG4.js.map} +1 -1
  17. package/dist/{chunk-2KNLKQVN.js → chunk-7UU5P2CX.js} +3 -3
  18. package/dist/{chunk-2KNLKQVN.js.map → chunk-7UU5P2CX.js.map} +1 -1
  19. package/dist/{chunk-NPERUUUE.js → chunk-CIDS43FH.js} +3 -3
  20. package/dist/{chunk-NPERUUUE.js.map → chunk-CIDS43FH.js.map} +1 -1
  21. package/dist/{chunk-PBDYW2TU.js → chunk-DBOJ2UC6.js} +14 -3
  22. package/dist/chunk-DBOJ2UC6.js.map +1 -0
  23. package/dist/{chunk-WGGAMW7Y.js → chunk-KEFMI24G.js} +7 -7
  24. package/dist/{chunk-WGGAMW7Y.js.map → chunk-KEFMI24G.js.map} +1 -1
  25. package/dist/{chunk-MVY5DAMF.js → chunk-KWPB6BM6.js} +4 -4
  26. package/dist/{chunk-MVY5DAMF.js.map → chunk-KWPB6BM6.js.map} +1 -1
  27. package/dist/{chunk-C6QC273X.js → chunk-LFW66IIV.js} +4 -4
  28. package/dist/{chunk-C6QC273X.js.map → chunk-LFW66IIV.js.map} +1 -1
  29. package/dist/{chunk-BP2R7TPP.js → chunk-PBAYOJJO.js} +150 -38
  30. package/dist/chunk-PBAYOJJO.js.map +1 -0
  31. package/dist/{chunk-SK5JGUY7.js → chunk-PUTHY7LR.js} +3 -3
  32. package/dist/{chunk-SK5JGUY7.js.map → chunk-PUTHY7LR.js.map} +1 -1
  33. package/dist/{chunk-LYLDCIPH.js → chunk-QKUWDC4P.js} +32 -25
  34. package/dist/chunk-QKUWDC4P.js.map +1 -0
  35. package/dist/{chunk-VBUCHVCV.js → chunk-T6HDAPMR.js} +3 -3
  36. package/dist/{chunk-VBUCHVCV.js.map → chunk-T6HDAPMR.js.map} +1 -1
  37. package/dist/{chunk-IXBKFQH5.js → chunk-W2S4HK7J.js} +6 -6
  38. package/dist/{chunk-IXBKFQH5.js.map → chunk-W2S4HK7J.js.map} +1 -1
  39. package/dist/{chunk-CAXMQJJ3.js → chunk-ZILCH3WS.js} +4 -4
  40. package/dist/{chunk-CAXMQJJ3.js.map → chunk-ZILCH3WS.js.map} +1 -1
  41. package/dist/{chunk-RMX4EOQK.js → chunk-ZT3MGQB7.js} +3 -3
  42. package/dist/{chunk-RMX4EOQK.js.map → chunk-ZT3MGQB7.js.map} +1 -1
  43. package/dist/{core-42kapW0n.d.ts → core-DPYOyOJv.d.ts} +8 -5
  44. package/dist/deadline/index.d.ts +2 -2
  45. package/dist/deadline/index.js +3 -3
  46. package/dist/do/index.d.ts +6 -6
  47. package/dist/do/index.js +10 -10
  48. package/dist/{durable-effects-CFRngTNA.d.ts → durable-effects-B0YpoCHg.d.ts} +1 -1
  49. package/dist/extension/index.d.ts +2 -2
  50. package/dist/extension/index.js +3 -3
  51. package/dist/extension/react.js +3 -3
  52. package/dist/extension/subs/index.d.ts +2 -2
  53. package/dist/fan-out/index.d.ts +2 -2
  54. package/dist/idempotent-intake/index.d.ts +2 -2
  55. package/dist/index.d.ts +18 -4
  56. package/dist/index.js +2 -2
  57. package/dist/llm-call/index.d.ts +2 -2
  58. package/dist/llm-call/index.js +7 -7
  59. package/dist/{machine-B_BF4jij.d.ts → machine-Q_Bsm7Vu.d.ts} +1 -1
  60. package/dist/machine-viz/index.d.ts +1 -1
  61. package/dist/machine-viz/index.js +2 -2
  62. package/dist/mem/index.d.ts +2 -2
  63. package/dist/monitored-run/index.d.ts +3 -3
  64. package/dist/monitored-run/index.js +5 -5
  65. package/dist/node/index.d.ts +2 -2
  66. package/dist/paginated-walk/index.d.ts +2 -2
  67. package/dist/paginated-walk/index.js +7 -7
  68. package/dist/parity/index.d.ts +2 -2
  69. package/dist/parity/index.js +3 -3
  70. package/dist/pbt/arbitraries/index.d.ts +1 -1
  71. package/dist/pbt/index.d.ts +1 -1
  72. package/dist/pbt/index.js +3 -3
  73. package/dist/pbt/runners/index.d.ts +1 -1
  74. package/dist/pbt/runners/index.js +3 -3
  75. package/dist/poller/index.d.ts +2 -2
  76. package/dist/poller/index.js +3 -3
  77. package/dist/prediction/index.d.ts +1 -1
  78. package/dist/prediction/index.js +2 -2
  79. package/dist/pure/index.d.ts +1 -1
  80. package/dist/pure/index.js +2 -2
  81. package/dist/react/index.d.ts +9 -3
  82. package/dist/react/index.js +2 -2
  83. package/dist/react/index.js.map +1 -1
  84. package/dist/reconciler/index.d.ts +2 -2
  85. package/dist/reconciler/index.js +7 -7
  86. package/dist/recorder/index.d.ts +2 -2
  87. package/dist/resilient-call/index.d.ts +2 -2
  88. package/dist/resilient-call/index.js +6 -6
  89. package/dist/{runtime-types-gsog27b6.d.ts → runtime-types-uBuVvZqa.d.ts} +117 -3
  90. package/dist/saga/index.d.ts +2 -2
  91. package/dist/snapshot/index.d.ts +1 -1
  92. package/dist/snapshot/index.js +3 -3
  93. package/dist/subs/index.d.ts +16 -9
  94. package/dist/subs/index.js +3 -3
  95. package/dist/testing/index.d.ts +2 -2
  96. package/dist/testing/index.js +2 -2
  97. package/dist/throttled-input/index.d.ts +2 -2
  98. package/dist/throttled-input/index.js +6 -6
  99. package/dist/token-refresh/index.d.ts +1 -1
  100. package/dist/token-refresh/index.js +3 -3
  101. package/dist/trace-replay/index.d.ts +2 -2
  102. package/dist/trace-replay/index.js +3 -3
  103. package/dist/{types-KbL3W1mj.d.ts → types-C6mXL9wA.d.ts} +1 -1
  104. package/dist/with-deadline/index.d.ts +1 -1
  105. package/dist/with-deadline/index.js +2 -2
  106. package/dist/with-resilience/index.d.ts +2 -2
  107. package/dist/with-resilience/index.js +6 -6
  108. package/dist/with-telemetry/index.d.ts +1 -1
  109. package/dist/with-telemetry/index.js +2 -2
  110. package/dist/work-queue/adapter.d.ts +2 -2
  111. package/dist/work-queue/index.d.ts +2 -2
  112. package/dist/work-queue/ops.d.ts +2 -2
  113. package/dist/workflow/index.d.ts +3 -3
  114. package/package.json +1 -1
  115. package/dist/chunk-BP2R7TPP.js.map +0 -1
  116. package/dist/chunk-LYLDCIPH.js.map +0 -1
  117. package/dist/chunk-PBDYW2TU.js.map +0 -1
@@ -1,14 +1,14 @@
1
- export { createResilientCall, liftResilience } from '../chunk-IXBKFQH5.js';
1
+ export { createResilientCall, liftResilience } from '../chunk-W2S4HK7J.js';
2
2
  import '../chunk-JELSZN25.js';
3
- export { deadlineSub, subscribeDeadline } from '../chunk-RMX4EOQK.js';
3
+ export { deadlineSub, subscribeDeadline } from '../chunk-ZT3MGQB7.js';
4
4
  import '../chunk-Q2UM7BXU.js';
5
5
  import '../chunk-S2EGRPCM.js';
6
6
  import '../chunk-UF4MZSLT.js';
7
- import '../chunk-2KNLKQVN.js';
8
- import '../chunk-LYLDCIPH.js';
7
+ import '../chunk-7UU5P2CX.js';
8
+ import '../chunk-QKUWDC4P.js';
9
9
  import '../chunk-2YFLOCWX.js';
10
10
  import '../chunk-ZJ5AOYBH.js';
11
- import '../chunk-BP2R7TPP.js';
12
- import '../chunk-PBDYW2TU.js';
11
+ import '../chunk-PBAYOJJO.js';
12
+ import '../chunk-DBOJ2UC6.js';
13
13
  //# sourceMappingURL=index.js.map
14
14
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import { P as Port, C as Cmd, S as Sub, M as Machine, T as Transitions, R as Reducer, I as InterpretDetached, b as PortEmitter } from './core-42kapW0n.js';
1
+ import { P as Port, C as Cmd, S as Sub, M as Machine, T as Transitions, R as Reducer, I as InterpretDetached, b as PortEmitter } from './core-DPYOyOJv.js';
2
2
 
3
3
  /**
4
4
  * @demlik/tea runtime interface surface + pure helpers — the public types,
@@ -68,6 +68,8 @@ declare function __resetPortRegistry(): void;
68
68
  *
69
69
  * - `"follow-up"` — a follow-up Msg an interpret handler returned rejected when
70
70
  * re-dispatched (the original dispatcher already resolved, so no caller).
71
+ * A rejection caused by `stop()`'s own teardown is NOT this phase — see
72
+ * `"discard"`.
71
73
  * - `"stop-save"` — the final `store.save(state)` inside `stop()` threw
72
74
  * (`stop()` resolves regardless, so without the sink this was silent loss).
73
75
  * - `"reduce"` — the pure `update` (reducer) threw synchronously; the configured
@@ -80,8 +82,25 @@ declare function __resetPortRegistry(): void;
80
82
  * - `"port-emit"` — a `subscribePort` listener threw during a port emission.
81
83
  * - `"sub-cleanup"` — a subscription's cleanup threw (reconcile-removal or
82
84
  * `stop()` teardown).
85
+ * - `"discard"` — work lost to a teardown the host asked for. Two witnesses,
86
+ * both carrying a `RuntimeDiscardNotice`: `stop()` was called while interpret
87
+ * handlers were still awaiting (`RuntimeDiscardedError`), and a Msg that
88
+ * arrived DURING `stop()`'s drain and so could not be delivered
89
+ * (`DispatchDiscardedError`), and teardown work that did not settle inside
90
+ * `disposeTimeoutMs` (`DisposeTimeoutNotice`). The one phase that is a
91
+ * LIFECYCLE report rather than a failure: legal, merely lossy.
92
+ * - `"identity-drop"` — the `Identity` filter dropped a message addressed to a
93
+ * different instance (`IdentityDropNotice`). Its own phase rather than
94
+ * `"discard"`: the loss is the FILTER WORKING, not a teardown, and a host
95
+ * routing it (a metric, a 409 back to the caller) wants it apart from
96
+ * unmount-time noise. Warn-only, like every `RuntimeDiscardNotice`.
97
+ *
98
+ * The phase never decides fatality — the ERROR CLASS does (`RuntimeDiscardNotice`
99
+ * warns, everything else rethrows). A phase is attached by the report site, so a
100
+ * consumer sink that throws while handling a `"discard"` report inherits that
101
+ * phase; keying the warn-only path on it would make the sink's own defect vanish.
83
102
  */
84
- type RuntimeErrorPhase = "follow-up" | "stop-save" | "reduce" | "listener" | "observer" | "event" | "boot" | "port-emit" | "sub-cleanup";
103
+ type RuntimeErrorPhase = "follow-up" | "stop-save" | "reduce" | "listener" | "observer" | "event" | "boot" | "port-emit" | "sub-cleanup" | "discard" | "identity-drop";
85
104
  /** Context handed to an `OnError` sink alongside the error itself. */
86
105
  interface RuntimeErrorContext {
87
106
  readonly phase: RuntimeErrorPhase;
@@ -133,6 +152,101 @@ declare class QuiescenceTimeoutError extends Error {
133
152
  readonly _tag: "QuiescenceTimeoutError";
134
153
  constructor(iterations: number);
135
154
  }
155
+ /**
156
+ * Base of the LOSSY-BUT-LEGAL teardown facts: work the host discarded by letting
157
+ * go of a runtime that still had something outstanding. Reported under
158
+ * `phase: "discard"`, never raised.
159
+ *
160
+ * It exists so "is this fatal?" has ONE definition — `error instanceof
161
+ * RuntimeDiscardNotice` — that the default sink can ask about any error from any
162
+ * site. The phase cannot answer it: a report site attaches the phase, so a
163
+ * consumer sink that throws while handling a `"discard"` report carries that
164
+ * phase into the sink-failure path, and a phase-keyed warn branch would swallow
165
+ * the sink's own defect. Sub-classing is how a new teardown fact opts into the
166
+ * warn-only treatment; nothing else can.
167
+ */
168
+ declare abstract class RuntimeDiscardNotice extends Error {
169
+ }
170
+ /**
171
+ * Reported to the `OnError` sink under `phase: "discard"` when `stop()` is
172
+ * called while `interpret` handlers are still awaiting. The host is dropping
173
+ * its only handle on that work: `stop()` drains the tail, but the listeners,
174
+ * observers and event handlers that would have consumed the resulting
175
+ * transitions are gone, so the Cmds' results reach nobody.
176
+ *
177
+ * The motivating shape is `@demlik/tea/react`'s `useMachine`, which memoizes on
178
+ * `[machine, ctx, store]` — a ctx re-derived mid-flight replaces the runtime,
179
+ * and the in-flight mutation's response arrives for a runtime the UI no longer
180
+ * renders, silently rewinding the visible state. Never a throw: tearing a
181
+ * runtime down mid-flight is legal (a navigation does it every time), so this
182
+ * is surfaced as data, not raised. Mechanizes invariant 6 (no silent failures)
183
+ * at the teardown seam, the role `QuiescenceTimeoutError` plays for `idle()`.
184
+ */
185
+ declare class RuntimeDiscardedError extends RuntimeDiscardNotice {
186
+ readonly pendingCmds: number;
187
+ readonly name = "RuntimeDiscardedError";
188
+ readonly _tag: "RuntimeDiscardedError";
189
+ constructor(pendingCmds: number);
190
+ }
191
+ /**
192
+ * Reported to the `OnError` sink under `phase: "identity-drop"` when the
193
+ * `Identity` filter drops a message addressed to a different instance.
194
+ *
195
+ * The drop itself is the feature — it is what lets a reducer stop repeating
196
+ * `if (msg.runId !== state.runId) return`. What was missing is that it was
197
+ * INVISIBLE: the dispatch resolved exactly like an applied one, so a reusable
198
+ * Durable Object serving run A and then run B lost every run-B message and
199
+ * reported success to each caller. The comment claiming "the one observable
200
+ * enforcement point" described this notice before it existed.
201
+ *
202
+ * Never fatal (`RuntimeDiscardNotice`): a mis-addressed message is a normal
203
+ * consequence of instance reuse, not a defect. A host that wants to act on it
204
+ * — a metric, a 409 to the caller, a re-route — reads `phase: "identity-drop"`
205
+ * in its own sink.
206
+ */
207
+ declare class IdentityDropNotice extends RuntimeDiscardNotice {
208
+ readonly msgType: string;
209
+ readonly name = "IdentityDropNotice";
210
+ readonly _tag: "IdentityDropNotice";
211
+ constructor(msgType: string);
212
+ }
213
+ /**
214
+ * Reported to the `OnError` sink under `phase: "discard"` when `stop()`'s wait
215
+ * for async teardown work hits `disposeTimeoutMs`.
216
+ *
217
+ * `stop()` awaits the disposals it started so `await runtime.stop()` can mean
218
+ * "safe to evict". A `release` that never settles must not turn that guarantee
219
+ * into a host that never shuts down, so the wait is bounded and expiry is
220
+ * REPORTED rather than silently tolerated — the resource is genuinely still
221
+ * open at that point, and only the host can decide what that costs.
222
+ */
223
+ declare class DisposeTimeoutNotice extends RuntimeDiscardNotice {
224
+ readonly pendingDisposals: number;
225
+ readonly timeoutMs: number;
226
+ readonly name = "DisposeTimeoutNotice";
227
+ readonly _tag: "DisposeTimeoutNotice";
228
+ constructor(pendingDisposals: number, timeoutMs: number);
229
+ }
230
+ /**
231
+ * The rejection of a dispatch that arrived DURING `stop()`'s drain — an in-flight
232
+ * interpret handler's follow-up Msg, a detached handler's terminal Msg, or a Sub
233
+ * that is still live because subs are torn down only after the drain. The stop
234
+ * barrier is absolute (the Msg is refused, never folded), so this names the loss.
235
+ *
236
+ * It is the SECOND witness of `RuntimeDiscardedError`'s fact, and it is why the
237
+ * drain window is a distinct runtime state rather than a plain `stopped` flag:
238
+ * a Msg refused inside the window was discarded BY the teardown, while the same
239
+ * refusal after `stop()` has returned is a consumer dispatching into a runtime it
240
+ * already retired — a real error, and still loud (`phase: "follow-up"`, or the
241
+ * caller's own rejection). The distinction is the state at refusal time, never
242
+ * the message text.
243
+ */
244
+ declare class DispatchDiscardedError extends RuntimeDiscardNotice {
245
+ readonly msgType: string;
246
+ readonly name = "DispatchDiscardedError";
247
+ readonly _tag: "DispatchDiscardedError";
248
+ constructor(msgType: string);
249
+ }
136
250
  /**
137
251
  * Define a typed port. `name` is metadata (devtools / debug logs); port identity
138
252
  * is by reference. Each definePort call must use a unique `name` — a second call
@@ -334,4 +448,4 @@ declare function wrapDetached<C extends Cmd, M extends {
334
448
  }, Allowed extends M, Ctx>(handler: InterpretDetached<C, Allowed, Ctx>): (cmd: C, ctx: Ctx & PortEmitter, dispatch?: (msg: M) => void) => Promise<void>;
335
449
  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>;
336
450
 
337
- export { type BootingRuntime as B, type CtxArg as C, type DispatchSettle as D, type OnError as O, PortNameCollisionError as P, QuiescenceTimeoutError as Q, type Runtime as R, type Store as S, __resetPortRegistry as _, type Supervision as a, type Branded as b, absurd as c, SubIdCollisionError as d, type RuntimeErrorPhase as e, type RuntimeErrorContext as f, type SupervisionStrategy as g, definePort as h, type Schema as i, type RuntimeRef as j, defineMachine as k, asReducer as l, noop as n, replay as r, schemaMigrate as s, tryInterpret as t, wrapDetached as w };
451
+ export { type BootingRuntime as B, type CtxArg as C, DisposeTimeoutNotice as D, IdentityDropNotice as I, type OnError as O, PortNameCollisionError as P, QuiescenceTimeoutError as Q, type Runtime as R, type Store as S, __resetPortRegistry as _, type Supervision as a, type Branded as b, absurd as c, SubIdCollisionError as d, type RuntimeErrorPhase as e, type RuntimeErrorContext as f, type SupervisionStrategy as g, RuntimeDiscardNotice as h, RuntimeDiscardedError as i, DispatchDiscardedError as j, definePort as k, type Schema as l, type DispatchSettle as m, noop as n, type RuntimeRef as o, defineMachine as p, asReducer as q, replay as r, schemaMigrate as s, tryInterpret as t, wrapDetached as w };
@@ -1,6 +1,6 @@
1
- import { C as Cmd } from '../core-42kapW0n.js';
1
+ import { C as Cmd } from '../core-DPYOyOJv.js';
2
2
  import { QueueItem } from '../work-queue/index.js';
3
- import '../runtime-types-gsog27b6.js';
3
+ import '../runtime-types-uBuVvZqa.js';
4
4
 
5
5
  /**
6
6
  * @packageDocumentation
@@ -1,4 +1,4 @@
1
- import { C as Cmd, c as Interpret } from '../core-42kapW0n.js';
1
+ import { C as Cmd, c as Interpret } from '../core-DPYOyOJv.js';
2
2
 
3
3
  /**
4
4
  * @demlik/tea/snapshot — periodic state checkpoint to a host store (R2/KV-shaped).
@@ -1,5 +1,5 @@
1
- export { createSnapshot, snapshotFailed, snapshotLoadFailed, snapshotLoaded, snapshotSaved } from '../chunk-MVY5DAMF.js';
2
- import '../chunk-BP2R7TPP.js';
3
- import '../chunk-PBDYW2TU.js';
1
+ export { createSnapshot, snapshotFailed, snapshotLoadFailed, snapshotLoaded, snapshotSaved } from '../chunk-KWPB6BM6.js';
2
+ import '../chunk-PBAYOJJO.js';
3
+ import '../chunk-DBOJ2UC6.js';
4
4
  //# sourceMappingURL=index.js.map
5
5
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
- import { S as Sub, P as Port, D as DepKeyedSub, a as SubId } from '../core-42kapW0n.js';
2
- import { S as SubscribeHandler } from '../types-KbL3W1mj.js';
3
- import { R as Runtime } from '../runtime-types-gsog27b6.js';
1
+ import { S as Sub, P as Port, e as Dispose, D as DepKeyedSub, a as SubId } from '../core-DPYOyOJv.js';
2
+ import { S as SubscribeHandler } from '../types-C6mXL9wA.js';
3
+ import { R as Runtime } from '../runtime-types-uBuVvZqa.js';
4
4
 
5
5
  /**
6
6
  * The imperative listener target, expressed as the `add`/`remove` pair the
@@ -177,7 +177,7 @@ interface GatedManagedResource<S, TKey, Ctx> {
177
177
  * `managed_resource` Sub to the entry whose `owns(sub)` is true, then calls
178
178
  * this.
179
179
  */
180
- readonly subscribe: (sub: ManagedResourceSub<TKey>, ctx: Ctx, dispatch: (msg: never) => void) => () => void;
180
+ readonly subscribe: (sub: ManagedResourceSub<TKey>, ctx: Ctx, dispatch: (msg: never) => void) => Dispose;
181
181
  /**
182
182
  * Does this entry own the given Sub? `sub.id === subIdFor(sub.key)` encodes
183
183
  * the battery `name`, so a match is unambiguous.
@@ -202,7 +202,7 @@ interface CombinedManagedResources<S, TKey, Ctx> {
202
202
  * id encodes the battery `name`). Throws loudly on an unrouted id — a wiring
203
203
  * bug, never a silent no-op resource.
204
204
  */
205
- readonly subscribe: (sub: ManagedResourceSub<TKey>, ctx: Ctx, dispatch: (msg: never) => void) => () => void;
205
+ readonly subscribe: (sub: ManagedResourceSub<TKey>, ctx: Ctx, dispatch: (msg: never) => void) => Dispose;
206
206
  }
207
207
  interface DefineManagedResourceOpts<TKey, Handle, Ctx> {
208
208
  /**
@@ -222,9 +222,16 @@ interface DefineManagedResourceOpts<TKey, Handle, Ctx> {
222
222
  /**
223
223
  * Tear the resource down. Runs when the Sub leaves the desired set (phase
224
224
  * exited) or when its key changes. MANDATORY — the guaranteed teardown is
225
- * the reason this battery exists. May be sync or async; the substrate's
226
- * cleanup is fire-and-forget (Rule 2), so a rejected teardown is logged at
227
- * the boundary, not surfaced as a Msg.
225
+ * the reason this battery exists.
226
+ *
227
+ * May be sync or async, and an async one is really awaited: the promise is
228
+ * returned to the substrate, which tracks it and drains it inside `stop()`
229
+ * (bounded by `run({ disposeTimeoutMs })`). So `await runtime.stop()` means
230
+ * the release finished — the reading a host evicting an isolate acts on.
231
+ * MID-RUN teardown (a phase exit, a key change) is still fire-and-forget
232
+ * (Rule 2): the reconcile pass is synchronous by construction, so it starts
233
+ * the release and moves on. A rejection is never a Msg — it reaches the
234
+ * runtime's `onError` sink under `phase: "sub-cleanup"`.
228
235
  */
229
236
  readonly release: (handle: Handle) => void | Promise<void>;
230
237
  }
@@ -283,7 +290,7 @@ interface ManagedResourceBattery<TKey, Handle, Ctx> {
283
290
  * Handle in the battery's handle table, and returns a cleanup that runs
284
291
  * `release` (and forgets the Handle) on reconcile-out.
285
292
  */
286
- readonly subscribe: (sub: ManagedResourceSub<TKey>, ctx: Ctx, dispatch: (msg: never) => void) => () => void;
293
+ readonly subscribe: (sub: ManagedResourceSub<TKey>, ctx: Ctx, dispatch: (msg: never) => void) => Dispose;
287
294
  /**
288
295
  * Accessor for the live Handle, keyed on `key`. Returns `undefined` when
289
296
  * the resource is not currently held (no active sub for that key) — the
@@ -1,7 +1,7 @@
1
- export { combineManagedResources, defineListener, defineManagedResource, fromBroadcastChannel, fromEventSource, fromEventTarget, fromInterval, fromPort, fromReconnectingWebSocket, fromTransport, fromWebSocket } from '../chunk-LYLDCIPH.js';
1
+ export { combineManagedResources, defineListener, defineManagedResource, fromBroadcastChannel, fromEventSource, fromEventTarget, fromInterval, fromPort, fromReconnectingWebSocket, fromTransport, fromWebSocket } from '../chunk-QKUWDC4P.js';
2
2
  export { fromTimeout } from '../chunk-2YFLOCWX.js';
3
3
  import '../chunk-ZJ5AOYBH.js';
4
- import '../chunk-BP2R7TPP.js';
5
- import '../chunk-PBDYW2TU.js';
4
+ import '../chunk-PBAYOJJO.js';
5
+ import '../chunk-DBOJ2UC6.js';
6
6
  //# sourceMappingURL=index.js.map
7
7
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
- import { C as Cmd, S as Sub, M as Machine } from '../core-42kapW0n.js';
2
- import { R as Runtime } from '../runtime-types-gsog27b6.js';
1
+ import { C as Cmd, S as Sub, M as Machine } from '../core-DPYOyOJv.js';
2
+ import { R as Runtime } from '../runtime-types-uBuVvZqa.js';
3
3
 
4
4
  /**
5
5
  * The composed Model shape every `withX` wrapper produces: the base machine's
@@ -1,5 +1,5 @@
1
- import { replay } from '../chunk-BP2R7TPP.js';
2
- import '../chunk-PBDYW2TU.js';
1
+ import { replay } from '../chunk-PBAYOJJO.js';
2
+ import '../chunk-DBOJ2UC6.js';
3
3
  import { expect, vi } from 'vitest';
4
4
 
5
5
  function assertWrapperFaithful(base, makeWrapped, opts) {
@@ -1,10 +1,10 @@
1
1
  import { TtlCache } from '../cache/index.js';
2
2
  import { DeadlineSub } from '../deadline/index.js';
3
3
  export { DeadlineExceeded as ThrottledInputSettled, subscribeDeadline as subscribeThrottledInput, deadlineExceeded as throttledInputSettled } from '../deadline/index.js';
4
- import { C as Cmd, S as Sub } from '../core-42kapW0n.js';
4
+ import { C as Cmd, S as Sub } from '../core-DPYOyOJv.js';
5
5
  export { Debounced, debounce } from '../debounce/index.js';
6
6
  export { Throttled, throttle } from '../throttle/index.js';
7
- import '../types-KbL3W1mj.js';
7
+ import '../types-C6mXL9wA.js';
8
8
 
9
9
  /**
10
10
  * @demlik/tea/throttled-input — gate a high-frequency input stream into a
@@ -1,13 +1,13 @@
1
1
  export { debounce } from '../chunk-J6527VRQ.js';
2
2
  export { throttle } from '../chunk-HCEVHFJ7.js';
3
- import { deadlineSub } from '../chunk-RMX4EOQK.js';
4
- export { subscribeDeadline as subscribeThrottledInput, deadlineExceeded as throttledInputSettled } from '../chunk-RMX4EOQK.js';
5
- import { initCache, get, set } from '../chunk-2KNLKQVN.js';
6
- import '../chunk-LYLDCIPH.js';
3
+ import { deadlineSub } from '../chunk-ZT3MGQB7.js';
4
+ export { subscribeDeadline as subscribeThrottledInput, deadlineExceeded as throttledInputSettled } from '../chunk-ZT3MGQB7.js';
5
+ import { initCache, get, set } from '../chunk-7UU5P2CX.js';
6
+ import '../chunk-QKUWDC4P.js';
7
7
  import '../chunk-2YFLOCWX.js';
8
8
  import '../chunk-ZJ5AOYBH.js';
9
- import '../chunk-BP2R7TPP.js';
10
- import '../chunk-PBDYW2TU.js';
9
+ import '../chunk-PBAYOJJO.js';
10
+ import '../chunk-DBOJ2UC6.js';
11
11
 
12
12
  // src/throttled-input/index.ts
13
13
  var DEFAULT_SUB_ID = "throttled-input:settle";
@@ -1,4 +1,4 @@
1
- import { C as Cmd, c as Interpret } from '../core-42kapW0n.js';
1
+ import { C as Cmd, c as Interpret } from '../core-DPYOyOJv.js';
2
2
  import { M as MsgType } from '../protocol-B5YmJr0d.js';
3
3
 
4
4
  /**
@@ -1,6 +1,6 @@
1
- export { createTokenRefresh, initTokenRefresh, refreshTokenCmd, tokenRefreshFailedMsg, tokenRefreshedMsg } from '../chunk-SK5JGUY7.js';
1
+ export { createTokenRefresh, initTokenRefresh, refreshTokenCmd, tokenRefreshFailedMsg, tokenRefreshedMsg } from '../chunk-PUTHY7LR.js';
2
2
  import '../chunk-JELSZN25.js';
3
- import '../chunk-BP2R7TPP.js';
4
- import '../chunk-PBDYW2TU.js';
3
+ import '../chunk-PBAYOJJO.js';
4
+ import '../chunk-DBOJ2UC6.js';
5
5
  //# sourceMappingURL=index.js.map
6
6
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
- import { C as Cmd, S as Sub, M as Machine } from '../core-42kapW0n.js';
1
+ import { C as Cmd, S as Sub, M as Machine } from '../core-DPYOyOJv.js';
2
2
  import { Trace } from '../recorder/index.js';
3
- import '../runtime-types-gsog27b6.js';
3
+ import '../runtime-types-uBuVvZqa.js';
4
4
 
5
5
  /**
6
6
  * The outcome of {@link replayTrace}.
@@ -1,6 +1,6 @@
1
- export { deepEqual, replayTrace } from '../chunk-S4O26D7B.js';
1
+ export { deepEqual, replayTrace } from '../chunk-362SZ6CS.js';
2
2
  import '../chunk-EWJP3YYP.js';
3
- import '../chunk-BP2R7TPP.js';
4
- import '../chunk-PBDYW2TU.js';
3
+ import '../chunk-PBAYOJJO.js';
4
+ import '../chunk-DBOJ2UC6.js';
5
5
  //# sourceMappingURL=index.js.map
6
6
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import { S as Sub } from './core-42kapW0n.js';
1
+ import { S as Sub } from './core-DPYOyOJv.js';
2
2
 
3
3
  type SubscribeHandler<S extends Sub, M, Ctx> = (sub: S, ctx: Ctx, dispatch: (msg: M) => void) => () => void;
4
4
 
@@ -1,4 +1,4 @@
1
- import { S as Sub, C as Cmd, M as Machine } from '../core-42kapW0n.js';
1
+ import { S as Sub, C as Cmd, M as Machine } from '../core-DPYOyOJv.js';
2
2
 
3
3
  /**
4
4
  * @demlik/tea/with-deadline — auto-fail a wrapped machine at T+N, re-arm on
@@ -1,6 +1,6 @@
1
1
  import { fromTimeout } from '../chunk-2YFLOCWX.js';
2
- import '../chunk-BP2R7TPP.js';
3
- import { msgKeysOf, applyCell, subId } from '../chunk-PBDYW2TU.js';
2
+ import '../chunk-PBAYOJJO.js';
3
+ import { msgKeysOf, applyCell, subId } from '../chunk-DBOJ2UC6.js';
4
4
 
5
5
  // src/with-deadline/index.ts
6
6
  function deadlineExceededMsg(seq) {
@@ -1,7 +1,7 @@
1
- import { C as Cmd, S as Sub, M as Machine } from '../core-42kapW0n.js';
1
+ import { C as Cmd, S as Sub, M as Machine } from '../core-DPYOyOJv.js';
2
2
  import { ResilientConfig, ResilientState } from '../resilient-call/index.js';
3
3
  import '../cache/index.js';
4
- import '../types-KbL3W1mj.js';
4
+ import '../types-C6mXL9wA.js';
5
5
  import '../circuit-breaker/index.js';
6
6
  import '../deadline/index.js';
7
7
  import '../protocol-B5YmJr0d.js';
@@ -1,15 +1,15 @@
1
- import { createResilientCall } from '../chunk-IXBKFQH5.js';
1
+ import { createResilientCall } from '../chunk-W2S4HK7J.js';
2
2
  import { MsgType } from '../chunk-JELSZN25.js';
3
- import { subscribeDeadline } from '../chunk-RMX4EOQK.js';
3
+ import { subscribeDeadline } from '../chunk-ZT3MGQB7.js';
4
4
  import '../chunk-Q2UM7BXU.js';
5
5
  import '../chunk-S2EGRPCM.js';
6
6
  import '../chunk-UF4MZSLT.js';
7
- import '../chunk-2KNLKQVN.js';
8
- import '../chunk-LYLDCIPH.js';
7
+ import '../chunk-7UU5P2CX.js';
8
+ import '../chunk-QKUWDC4P.js';
9
9
  import '../chunk-2YFLOCWX.js';
10
10
  import '../chunk-ZJ5AOYBH.js';
11
- import { tryInterpret } from '../chunk-BP2R7TPP.js';
12
- import { msgKeysOf, applyCell, subId, formOf } from '../chunk-PBDYW2TU.js';
11
+ import { tryInterpret } from '../chunk-PBAYOJJO.js';
12
+ import { msgKeysOf, applyCell, subId, formOf } from '../chunk-DBOJ2UC6.js';
13
13
 
14
14
  // src/with-resilience/index.ts
15
15
  var RC_RETRY_PREFIX = "resilient:retry:";
@@ -1,4 +1,4 @@
1
- import { C as Cmd, S as Sub, M as Machine } from '../core-42kapW0n.js';
1
+ import { C as Cmd, S as Sub, M as Machine } from '../core-DPYOyOJv.js';
2
2
 
3
3
  /**
4
4
  * @demlik/tea/with-telemetry — the pattern-setting wrapper of the wrapper tier.
@@ -1,5 +1,5 @@
1
- import '../chunk-BP2R7TPP.js';
2
- import { msgKeysOf, applyCell } from '../chunk-PBDYW2TU.js';
1
+ import '../chunk-PBAYOJJO.js';
2
+ import { msgKeysOf, applyCell } from '../chunk-DBOJ2UC6.js';
3
3
 
4
4
  // src/with-telemetry/index.ts
5
5
  function withTelemetry(base, config = {}) {
@@ -1,6 +1,6 @@
1
1
  import { QueueItem } from './index.js';
2
- import '../runtime-types-gsog27b6.js';
3
- import '../core-42kapW0n.js';
2
+ import '../runtime-types-uBuVvZqa.js';
3
+ import '../core-DPYOyOJv.js';
4
4
 
5
5
  /**
6
6
  * @demlik/tea/work-queue/adapter — the verb seam over the pure queue ops.
@@ -1,5 +1,5 @@
1
- import { S as Store } from '../runtime-types-gsog27b6.js';
2
- import '../core-42kapW0n.js';
1
+ import { S as Store } from '../runtime-types-uBuVvZqa.js';
2
+ import '../core-DPYOyOJv.js';
3
3
 
4
4
  /**
5
5
  * @packageDocumentation
@@ -1,6 +1,6 @@
1
1
  import { QueueItem } from './index.js';
2
- import '../runtime-types-gsog27b6.js';
3
- import '../core-42kapW0n.js';
2
+ import '../runtime-types-uBuVvZqa.js';
3
+ import '../core-DPYOyOJv.js';
4
4
 
5
5
  /**
6
6
  * Pure queue-lifecycle ops over `QueueItem<I>[]` — the BLESSED delegation
@@ -1,6 +1,6 @@
1
- import { D as DeliveryId, E as EffectLedgerEvent } from '../durable-effects-CFRngTNA.js';
2
- export { a as EffectConfirmed, b as EffectOwed, e as emptyLedger } from '../durable-effects-CFRngTNA.js';
3
- import { C as Cmd } from '../core-42kapW0n.js';
1
+ import { D as DeliveryId, E as EffectLedgerEvent } from '../durable-effects-B0YpoCHg.js';
2
+ export { a as EffectConfirmed, b as EffectOwed, e as emptyLedger } from '../durable-effects-B0YpoCHg.js';
3
+ import { C as Cmd } from '../core-DPYOyOJv.js';
4
4
 
5
5
  /**
6
6
  * @packageDocumentation
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@demlik/tea",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "TEA-faithful state machine substrate — one package, every host adapter. Core + subs + testing, plus React, Durable Object, Chrome extension, Node, in-memory, work-queue, devtools, and property-testing modules as subpaths.",
5
5
  "keywords": [
6
6
  "tea",