@demlik/tea 0.3.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 (77) hide show
  1. package/dist/agent/index.d.ts +1 -1
  2. package/dist/agent/index.js +6 -6
  3. package/dist/authed-call/index.js +3 -3
  4. package/dist/await-terminal/index.d.ts +1 -1
  5. package/dist/await-terminal/index.js +1 -1
  6. package/dist/batch-window/index.d.ts +1 -1
  7. package/dist/batch-window/index.js +1 -1
  8. package/dist/cache/index.js +1 -1
  9. package/dist/{chunk-S4O26D7B.js → chunk-2AHAR7CX.js} +3 -3
  10. package/dist/{chunk-S4O26D7B.js.map → chunk-2AHAR7CX.js.map} +1 -1
  11. package/dist/{chunk-WGGAMW7Y.js → chunk-5W7CNAHB.js} +6 -6
  12. package/dist/{chunk-WGGAMW7Y.js.map → chunk-5W7CNAHB.js.map} +1 -1
  13. package/dist/{chunk-IXBKFQH5.js → chunk-B5RAZVXW.js} +3 -3
  14. package/dist/{chunk-IXBKFQH5.js.map → chunk-B5RAZVXW.js.map} +1 -1
  15. package/dist/{chunk-BP2R7TPP.js → chunk-D4NJBQAH.js} +63 -18
  16. package/dist/chunk-D4NJBQAH.js.map +1 -0
  17. package/dist/{chunk-NPERUUUE.js → chunk-ET6QQNSQ.js} +3 -3
  18. package/dist/{chunk-NPERUUUE.js.map → chunk-ET6QQNSQ.js.map} +1 -1
  19. package/dist/{chunk-VBUCHVCV.js → chunk-FCKP6N7Y.js} +3 -3
  20. package/dist/{chunk-VBUCHVCV.js.map → chunk-FCKP6N7Y.js.map} +1 -1
  21. package/dist/{chunk-TPGASTFF.js → chunk-JXYYRKD6.js} +3 -3
  22. package/dist/{chunk-TPGASTFF.js.map → chunk-JXYYRKD6.js.map} +1 -1
  23. package/dist/{chunk-CAXMQJJ3.js → chunk-LJJV6ZD5.js} +3 -3
  24. package/dist/{chunk-CAXMQJJ3.js.map → chunk-LJJV6ZD5.js.map} +1 -1
  25. package/dist/{chunk-MVY5DAMF.js → chunk-SPWVPIFQ.js} +3 -3
  26. package/dist/{chunk-MVY5DAMF.js.map → chunk-SPWVPIFQ.js.map} +1 -1
  27. package/dist/{chunk-C6QC273X.js → chunk-SSHDBOXF.js} +3 -3
  28. package/dist/{chunk-C6QC273X.js.map → chunk-SSHDBOXF.js.map} +1 -1
  29. package/dist/{chunk-SK5JGUY7.js → chunk-TWDHNIY6.js} +3 -3
  30. package/dist/{chunk-SK5JGUY7.js.map → chunk-TWDHNIY6.js.map} +1 -1
  31. package/dist/deadline/index.js +1 -1
  32. package/dist/do/index.d.ts +1 -1
  33. package/dist/do/index.js +6 -6
  34. package/dist/extension/index.d.ts +1 -1
  35. package/dist/extension/index.js +2 -2
  36. package/dist/extension/react.js +2 -2
  37. package/dist/fan-out/index.d.ts +1 -1
  38. package/dist/idempotent-intake/index.d.ts +1 -1
  39. package/dist/index.d.ts +2 -2
  40. package/dist/index.js +1 -1
  41. package/dist/llm-call/index.js +3 -3
  42. package/dist/machine-viz/index.js +1 -1
  43. package/dist/mem/index.d.ts +1 -1
  44. package/dist/monitored-run/index.d.ts +1 -1
  45. package/dist/monitored-run/index.js +3 -3
  46. package/dist/node/index.d.ts +1 -1
  47. package/dist/paginated-walk/index.js +3 -3
  48. package/dist/parity/index.d.ts +1 -1
  49. package/dist/parity/index.js +2 -2
  50. package/dist/pbt/index.js +2 -2
  51. package/dist/pbt/runners/index.js +2 -2
  52. package/dist/poller/index.js +1 -1
  53. package/dist/react/index.d.ts +8 -2
  54. package/dist/react/index.js +1 -1
  55. package/dist/react/index.js.map +1 -1
  56. package/dist/reconciler/index.js +3 -3
  57. package/dist/recorder/index.d.ts +1 -1
  58. package/dist/resilient-call/index.js +2 -2
  59. package/dist/{runtime-types-gsog27b6.d.ts → runtime-types-CukV8kMX.d.ts} +71 -2
  60. package/dist/saga/index.d.ts +1 -1
  61. package/dist/snapshot/index.js +2 -2
  62. package/dist/subs/index.d.ts +1 -1
  63. package/dist/subs/index.js +1 -1
  64. package/dist/testing/index.d.ts +1 -1
  65. package/dist/testing/index.js +1 -1
  66. package/dist/throttled-input/index.js +1 -1
  67. package/dist/token-refresh/index.js +2 -2
  68. package/dist/trace-replay/index.d.ts +1 -1
  69. package/dist/trace-replay/index.js +2 -2
  70. package/dist/with-deadline/index.js +1 -1
  71. package/dist/with-resilience/index.js +2 -2
  72. package/dist/with-telemetry/index.js +1 -1
  73. package/dist/work-queue/adapter.d.ts +1 -1
  74. package/dist/work-queue/index.d.ts +1 -1
  75. package/dist/work-queue/ops.d.ts +1 -1
  76. package/package.json +1 -1
  77. package/dist/chunk-BP2R7TPP.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { R as Runtime, S as Store } from '../runtime-types-gsog27b6.js';
1
+ import { R as Runtime, S as Store } from '../runtime-types-CukV8kMX.js';
2
2
  import '../core-42kapW0n.js';
3
3
 
4
4
  /**
@@ -1,6 +1,6 @@
1
- export { bridgeClient, bridgeRuntime, bridgeTabClient, passThroughMsg } from '../chunk-NPERUUUE.js';
1
+ export { bridgeClient, bridgeRuntime, bridgeTabClient, passThroughMsg } from '../chunk-ET6QQNSQ.js';
2
2
  import '../chunk-G5E74IJB.js';
3
- import '../chunk-BP2R7TPP.js';
3
+ import '../chunk-D4NJBQAH.js';
4
4
  import '../chunk-PBDYW2TU.js';
5
5
 
6
6
  // src/extension/index.ts
@@ -1,6 +1,6 @@
1
- import { bridgeClient, passThroughMsg } from '../chunk-NPERUUUE.js';
1
+ import { bridgeClient, passThroughMsg } from '../chunk-ET6QQNSQ.js';
2
2
  import '../chunk-G5E74IJB.js';
3
- import '../chunk-BP2R7TPP.js';
3
+ import '../chunk-D4NJBQAH.js';
4
4
  import '../chunk-PBDYW2TU.js';
5
5
  import { useRef, useSyncExternalStore, useEffect, useCallback, createContext, useMemo, useContext } from 'react';
6
6
  import { jsx } from 'react/jsx-runtime';
@@ -1,6 +1,6 @@
1
1
  import { C as Cmd, P as Port } from '../core-42kapW0n.js';
2
2
  import { QueueItem } from '../work-queue/index.js';
3
- import '../runtime-types-gsog27b6.js';
3
+ import '../runtime-types-CukV8kMX.js';
4
4
 
5
5
  /**
6
6
  * @demlik/tea/fan-out — scatter-gather over a bounded-concurrency work list.
@@ -1,7 +1,7 @@
1
1
  import { IdempotencyStore } from '../idempotency/index.js';
2
2
  import { C as Cmd } from '../core-42kapW0n.js';
3
3
  import { QueueItem } from '../work-queue/index.js';
4
- import '../runtime-types-gsog27b6.js';
4
+ import '../runtime-types-CukV8kMX.js';
5
5
 
6
6
  /**
7
7
  * @demlik/tea/idempotent-intake — receive-once intake for webhooks / queue
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
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';
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
3
  import { C as Cmd, S as Sub, M as Machine } from './core-42kapW0n.js';
4
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';
5
5
 
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { PortNameCollisionError, QuiescenceTimeoutError, SubIdCollisionError, __resetPortRegistry, absurd, asReducer, defineMachine, definePort, historyTracker, noop, replay, run, schemaMigrate, tryInterpret, wrapDetached } from './chunk-BP2R7TPP.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
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,5 +1,5 @@
1
- export { createLlmCall, liftLlmCall } from '../chunk-VBUCHVCV.js';
2
- import '../chunk-IXBKFQH5.js';
1
+ export { createLlmCall, liftLlmCall } from '../chunk-FCKP6N7Y.js';
2
+ import '../chunk-B5RAZVXW.js';
3
3
  import '../chunk-JELSZN25.js';
4
4
  export { deadlineSub, subscribeDeadline } from '../chunk-RMX4EOQK.js';
5
5
  import '../chunk-Q2UM7BXU.js';
@@ -10,7 +10,7 @@ import '../chunk-LYLDCIPH.js';
10
10
  import '../chunk-2YFLOCWX.js';
11
11
  import '../chunk-ZJ5AOYBH.js';
12
12
  import '../chunk-G5E74IJB.js';
13
- import '../chunk-BP2R7TPP.js';
13
+ import '../chunk-D4NJBQAH.js';
14
14
  import '../chunk-PBDYW2TU.js';
15
15
  //# sourceMappingURL=index.js.map
16
16
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import '../chunk-BP2R7TPP.js';
1
+ import '../chunk-D4NJBQAH.js';
2
2
  import { formOf } from '../chunk-PBDYW2TU.js';
3
3
 
4
4
  // src/machine-viz/index.ts
@@ -1,4 +1,4 @@
1
- import { S as Store } from '../runtime-types-gsog27b6.js';
1
+ import { S as Store } from '../runtime-types-CukV8kMX.js';
2
2
  import '../core-42kapW0n.js';
3
3
 
4
4
  /**
@@ -4,7 +4,7 @@ import { c as Interpret, C as Cmd } from '../core-42kapW0n.js';
4
4
  import { SnapshotState, SnapshotWriteCmd, SnapshotStore, SnapshotSavedMsg, SnapshotFailedMsg, SnapshotLoadedMsg, SnapshotLoadFailedMsg, SnapshotLoadCmd } from '../snapshot/index.js';
5
5
  import { QueueItem } from '../work-queue/index.js';
6
6
  import '../types-KbL3W1mj.js';
7
- import '../runtime-types-gsog27b6.js';
7
+ import '../runtime-types-CukV8kMX.js';
8
8
 
9
9
  /**
10
10
  * @demlik/tea/monitored-run — a long-running operation that is BOTH staged and
@@ -1,10 +1,10 @@
1
- export { createMonitoredRun, liftRun } from '../chunk-CAXMQJJ3.js';
2
- import '../chunk-MVY5DAMF.js';
1
+ export { createMonitoredRun, liftRun } from '../chunk-LJJV6ZD5.js';
2
+ import '../chunk-SPWVPIFQ.js';
3
3
  export { deadlineSub, subscribeDeadline } from '../chunk-RMX4EOQK.js';
4
4
  import '../chunk-MU6MCIAC.js';
5
5
  import '../chunk-FV3Z5MBE.js';
6
6
  import '../chunk-2YFLOCWX.js';
7
- import '../chunk-BP2R7TPP.js';
7
+ import '../chunk-D4NJBQAH.js';
8
8
  import '../chunk-PBDYW2TU.js';
9
9
  //# sourceMappingURL=index.js.map
10
10
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
1
  import WebSocket from 'ws';
2
- import { S as Store } from '../runtime-types-gsog27b6.js';
2
+ import { S as Store } from '../runtime-types-CukV8kMX.js';
3
3
  import { a as SubId, S as Sub } from '../core-42kapW0n.js';
4
4
 
5
5
  /**
@@ -1,6 +1,6 @@
1
- export { PAGE_KEY, createPaginatedWalk, liftWalk } from '../chunk-TPGASTFF.js';
1
+ export { PAGE_KEY, createPaginatedWalk, liftWalk } from '../chunk-JXYYRKD6.js';
2
2
  import '../chunk-SINXE47Y.js';
3
- import '../chunk-IXBKFQH5.js';
3
+ import '../chunk-B5RAZVXW.js';
4
4
  import '../chunk-JELSZN25.js';
5
5
  export { deadlineSub, subscribeDeadline } from '../chunk-RMX4EOQK.js';
6
6
  import '../chunk-Q2UM7BXU.js';
@@ -10,7 +10,7 @@ import '../chunk-2KNLKQVN.js';
10
10
  import '../chunk-LYLDCIPH.js';
11
11
  import '../chunk-2YFLOCWX.js';
12
12
  import '../chunk-ZJ5AOYBH.js';
13
- import '../chunk-BP2R7TPP.js';
13
+ import '../chunk-D4NJBQAH.js';
14
14
  import '../chunk-PBDYW2TU.js';
15
15
  //# sourceMappingURL=index.js.map
16
16
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import { B as BootingRuntime } from '../runtime-types-gsog27b6.js';
1
+ import { B as BootingRuntime } from '../runtime-types-CukV8kMX.js';
2
2
  import { C as Cmd, S as Sub, M as Machine } from '../core-42kapW0n.js';
3
3
  import { Trace, RecorderOptions } from '../recorder/index.js';
4
4
 
@@ -1,7 +1,7 @@
1
1
  import { recorder } from '../chunk-MUUROGIH.js';
2
- import { deepEqual } from '../chunk-S4O26D7B.js';
2
+ import { deepEqual } from '../chunk-2AHAR7CX.js';
3
3
  import '../chunk-EWJP3YYP.js';
4
- import { replay } from '../chunk-BP2R7TPP.js';
4
+ import { replay } from '../chunk-D4NJBQAH.js';
5
5
  import '../chunk-PBDYW2TU.js';
6
6
 
7
7
  // src/parity/index.ts
package/dist/pbt/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export { arbConstantMsg, arbGuidedSequence, arbMsg, arbMsgSequence, arbRecordMsg, stubCtxThrowingProxy } from '../chunk-7FYQGDMF.js';
2
- export { foldEvents, propertyInvariant, propertyTerminates, propertyTrace } from '../chunk-C6QC273X.js';
3
- import '../chunk-BP2R7TPP.js';
2
+ export { foldEvents, propertyInvariant, propertyTerminates, propertyTrace } from '../chunk-SSHDBOXF.js';
3
+ import '../chunk-D4NJBQAH.js';
4
4
  import { msgKeysOf } from '../chunk-PBDYW2TU.js';
5
5
 
6
6
  // src/pbt/util/msg-keys.ts
@@ -1,5 +1,5 @@
1
- export { foldEvents, propertyInvariant, propertyTerminates, propertyTrace } from '../../chunk-C6QC273X.js';
2
- import '../../chunk-BP2R7TPP.js';
1
+ export { foldEvents, propertyInvariant, propertyTerminates, propertyTrace } from '../../chunk-SSHDBOXF.js';
2
+ import '../../chunk-D4NJBQAH.js';
3
3
  import '../../chunk-PBDYW2TU.js';
4
4
  //# sourceMappingURL=index.js.map
5
5
  //# sourceMappingURL=index.js.map
@@ -3,7 +3,7 @@ import { asRng, defaultRetryPolicy, initRetry, recordFailure, shouldRetry, nextD
3
3
  import { idempotencyMemory } from '../chunk-BYQUGDD3.js';
4
4
  import '../chunk-K575PT4S.js';
5
5
  import '../chunk-2YFLOCWX.js';
6
- import '../chunk-BP2R7TPP.js';
6
+ import '../chunk-D4NJBQAH.js';
7
7
  import '../chunk-PBDYW2TU.js';
8
8
 
9
9
  // src/poller/index.ts
@@ -1,4 +1,4 @@
1
- import { S as Store, R as Runtime } from '../runtime-types-gsog27b6.js';
1
+ import { S as Store, R as Runtime } from '../runtime-types-CukV8kMX.js';
2
2
  import { C as Cmd, S as Sub, M as Machine } from '../core-42kapW0n.js';
3
3
 
4
4
  /**
@@ -32,6 +32,10 @@ import { C as Cmd, S as Sub, M as Machine } from '../core-42kapW0n.js';
32
32
  * **Identity matters.** The runtime is memoized on `[machine, opts.ctx,
33
33
  * opts.store]`. A new `ctx` reference rebuilds the runtime. Always `useMemo`
34
34
  * (or otherwise stabilize) the ctx at the call site. See README.
35
+ *
36
+ * Forgetting to is no longer silent: the replaced runtime's `stop()` reports
37
+ * `RuntimeDiscardedError` under `phase: "discard"` when Cmds were still in
38
+ * flight, which the substrate's default sink warns about (issue #365).
35
39
  */
36
40
  interface UseMachineOpts<S, Ctx> {
37
41
  ctx: Ctx;
@@ -47,7 +51,9 @@ interface UseMachineOpts<S, Ctx> {
47
51
  * runtime.getState)` — tearing-free under React 18 concurrent rendering.
48
52
  * - On unmount (or any dep change), `useEffect` cleanup calls
49
53
  * `runtime.stop()` — drains the queue, runs every active sub cleanup,
50
- * flushes state.
54
+ * flushes state, and — if Cmds were still in flight — reports
55
+ * `RuntimeDiscardedError` (`phase: "discard"`) rather than dropping them
56
+ * silently.
51
57
  *
52
58
  * Returns `[state, dispatch]` shaped like `useReducer`.
53
59
  */
@@ -1,4 +1,4 @@
1
- import { run } from '../chunk-BP2R7TPP.js';
1
+ import { run } from '../chunk-D4NJBQAH.js';
2
2
  import '../chunk-PBDYW2TU.js';
3
3
  import { useMemo, useRef, useReducer, useSyncExternalStore, useEffect } from 'react';
4
4
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/index.ts"],"names":[],"mappings":";;;;AAsEO,SAAS,UAAA,CAOd,SACA,IAAA,EACgC;AAMhC,EAAA,MAAM,MAAM,IAAA,CAAK,GAAA;AACjB,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AAMnB,EAAA,MAAM,OAAA,GAAU,OAAA;AAAA,IACd,MAAM,GAAA,CAAI,OAAA,EAAS,EAAE,GAAA,EAAK,OAAO,CAAA;AAAA,IACjC,CAAC,OAAA,EAAS,GAAA,EAAK,KAAK;AAAA,GACtB;AAeA,EAAA,MAAM,QAAA,GAAW,OAA6B,IAAI,CAAA;AAClD,EAAA,MAAM,GAAG,UAAU,CAAA,GAAI,WAAW,CAAC,IAAA,KAAiB,IAAA,GAAO,CAAA,EAAG,CAAC,CAAA;AAa/D,EAAA,MAAM,gBAAA,GAAmB,OAAA;AAAA,IACvB,MAAM,OAAA,CAAQ,IAAA,CAAK,IAAA,EAAM,GAAG,EAAE,CAAC,CAAA;AAAA,IAC/B,CAAC,SAAS,GAAG;AAAA,GACf;AAMA,EAAA,MAAM,WAAA,GAAc,MAClB,QAAA,CAAS,OAAA,KAAY,OAAO,QAAA,CAAS,OAAA,CAAQ,UAAS,GAAI,gBAAA;AAE5D,EAAA,MAAM,KAAA,GAAQ,oBAAA;AAAA,IACZ,OAAA,CAAQ,SAAA;AAAA,IACR,WAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,IAAA,GAAO,IAAA;AAMX,IAAA,OAAA,CAAQ,KAAA,CAAM,IAAA;AAAA,MACZ,CAAC,CAAA,KAAM;AACL,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,QAAA,CAAS,OAAA,GAAU,CAAA;AACnB,UAAA,UAAA,EAAW;AAAA,QACb;AAAA,MACF,CAAA;AAAA,MACA,MAAM;AAAA,MAAC;AAAA,KACT;AACA,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,GAAO,KAAA;AACP,MAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AAInB,MAAA,OAAA,CAAQ,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM;AAAA,MAAC,CAAC,CAAA;AAAA,IAC/B,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,OAAO,CAAC,KAAA,EAAO,OAAA,CAAQ,QAAQ,CAAA;AACjC;AAeO,SAAS,WACd,OAAA,EACgC;AAChC,EAAA,MAAM,KAAA,GAAQ,oBAAA;AAAA,IACZ,OAAA,CAAQ,SAAA;AAAA,IACR,OAAA,CAAQ,QAAA;AAAA,IACR,OAAA,CAAQ;AAAA,GACV;AACA,EAAA,OAAO,CAAC,KAAA,EAAO,OAAA,CAAQ,QAAQ,CAAA;AACjC","file":"index.js","sourcesContent":["/**\n * @packageDocumentation\n * @demlik/tea/react — React host adapter for `@demlik/tea`.\n *\n * The thinnest possible adapter that makes a tea machine consumable from a\n * React component. Three rules (PRD §\"React adapter\"):\n *\n * 1. The runtime is the source of truth, NOT React state. We subscribe via\n * `useSyncExternalStore(runtime.subscribe, runtime.getState,\n * runtime.getState)`. React renders are driven by runtime state changes;\n * React never owns the state.\n * 2. The runtime is memoized per component-mount, not per render. The deps\n * array is `[machine, opts.ctx, opts.store]` — IDENTITY, not value. See\n * `README.md` for the ctx-identity footgun + fix.\n * 3. Concurrent React is the design target. `useSyncExternalStore` is the\n * React-blessed primitive for tearing-free external state.\n *\n * Client-only in v1 — components that call `useMachine` MUST be `\"use client\"`.\n * Server Components consume data via Relay/RSC as today; tea machines own\n * client-side stateful flows. No RSC streaming, no server-side state\n * hydration. Crossing this boundary is a v2 concern.\n */\n\n\"use client\";\n\nimport {\n useEffect,\n useMemo,\n useReducer,\n useRef,\n useSyncExternalStore,\n} from \"react\";\nimport {\n type BootingRuntime,\n type Cmd,\n type Machine,\n type Runtime,\n run,\n type Store,\n type Sub,\n} from \"../index\";\n\n/**\n * Options passed to `useMachine`. The shape is intentionally minimal — `ctx`\n * is required (every machine has one), `store` is optional (omit it for\n * volatile-state machines).\n *\n * **Identity matters.** The runtime is memoized on `[machine, opts.ctx,\n * opts.store]`. A new `ctx` reference rebuilds the runtime. Always `useMemo`\n * (or otherwise stabilize) the ctx at the call site. See README.\n */\nexport interface UseMachineOpts<S, Ctx> {\n ctx: Ctx;\n store?: Store<S>;\n}\n\n/**\n * Build and own a `Runtime<S, M>` for the lifetime of the component mount.\n *\n * - Builds via `useMemo(() => run(machine, opts), [machine, opts.ctx,\n * opts.store])` — runtime is recreated when ANY of the three identities\n * change.\n * - Subscribes via `useSyncExternalStore(runtime.subscribe, runtime.getState,\n * runtime.getState)` — tearing-free under React 18 concurrent rendering.\n * - On unmount (or any dep change), `useEffect` cleanup calls\n * `runtime.stop()` — drains the queue, runs every active sub cleanup,\n * flushes state.\n *\n * Returns `[state, dispatch]` shaped like `useReducer`.\n */\nexport function useMachine<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n>(\n machine: Machine<S, M, C, U, Ctx>,\n opts: UseMachineOpts<S, Ctx>,\n): [S, (msg: M) => Promise<void>] {\n // Deps are literal: machine identity, ctx identity, store identity. NOT\n // `[opts]` (would rebuild every render — callers pass fresh objects).\n // We pass explicit fields to `run()` so the closure captures only the\n // deps in the array — keeps biome's `useExhaustiveDependencies` happy\n // without lying about what the memo actually depends on.\n const ctx = opts.ctx;\n const store = opts.store;\n // `run()` returns a `BootingRuntime<S, M>` SYNCHRONOUSLY (issue #45) — exactly\n // what `useMemo` needs. We never `await` here: awaiting would force an async\n // memo, a null first-commit state, and a resolved-flag dance. Instead we hold\n // the booting handle and capture the booted `Runtime` (the only thing with a\n // total `getState`) once `ready` resolves.\n const booting = useMemo<BootingRuntime<S, M>>(\n () => run(machine, { ctx, store }),\n [machine, ctx, store],\n );\n\n // Captures the booted `Runtime` once `ready` resolves. Until then it is\n // `null` and `getSnapshot` serves `preliminaryState`. Reset whenever the\n // booting handle identity changes (a new machine/ctx/store mount).\n //\n // The boot race the paired `bootedTick` bump exists for: the substrate's\n // boot fanout fires BEFORE `ready` resolves (fireListeners runs inside the\n // boot step; `ready` chains off the boot promise), so at notification time\n // this ref is still null and `getSnapshot` returns the same\n // `preliminaryState` reference — React sees an unchanged snapshot and\n // skips the re-render. Nothing re-notifies after the ref is set, so a\n // store-backed mount would stay stuck on the preliminary state until the\n // next unrelated transition. Bumping a reducer when we capture the booted\n // runtime forces the render that swaps preliminary → real state.\n const readyRef = useRef<Runtime<S, M> | null>(null);\n const [, markBooted] = useReducer((tick: number) => tick + 1, 0);\n\n // Preliminary state computed sync from `machine.init(null, ctx)`. This is\n // the snapshot React sees BEFORE the runtime finishes booting (matters\n // only when `opts.store` is present — without a store, the substrate\n // already sets state synchronously inside `run()`, so the boot fanout that\n // captures `readyRef` lands on the same microtask as the first commit).\n //\n // We deliberately recompute on each render but cache by `[machine,\n // opts.ctx]` — `init` is pure by convention, so cost is negligible. The\n // cached snapshot is also identity-stable across rerenders when the deps\n // don't change, which `useSyncExternalStore` rewards (no spurious\n // re-renders).\n const preliminaryState = useMemo<S>(\n () => machine.init(null, ctx)[0],\n [machine, ctx],\n );\n\n // `getSnapshot` reads the booted runtime if `ready` has resolved (the ref is\n // populated), else falls back to the preliminary state. No try/catch dance\n // anymore — pre-boot there is simply no booted `Runtime` to read from, so\n // the fallback is structural, not exception-driven.\n const getSnapshot = (): S =>\n readyRef.current !== null ? readyRef.current.getState() : preliminaryState;\n\n const state = useSyncExternalStore(\n booting.subscribe,\n getSnapshot,\n getSnapshot,\n );\n\n useEffect(() => {\n let live = true;\n // Capture the booted runtime when `ready` resolves, then force the\n // render that swaps preliminary → real state (see the boot-race note on\n // `readyRef` — the boot fanout fires too early to do it for us). Boot\n // rejections are swallowed: a failed boot surfaces on every `dispatch`,\n // which is where the consumer handles it.\n booting.ready.then(\n (r) => {\n if (live) {\n readyRef.current = r;\n markBooted();\n }\n },\n () => {},\n );\n return () => {\n live = false;\n readyRef.current = null;\n // Fire-and-forget — `stop()` is async but `useEffect` cleanup is sync.\n // The runtime swallows in-flight rejections internally, so this never\n // rejects in practice; we still attach `.catch` for safety.\n booting.stop().catch(() => {});\n };\n }, [booting]);\n\n return [state, booting.dispatch];\n}\n\n/**\n * Lower-level escape hatch: consume an externally-built `Runtime<S, M>`.\n *\n * Use this when the runtime is owned by something OTHER than the component —\n * a parent component, a test harness, a singleton. **The component does NOT\n * call `runtime.stop()` on unmount** — the caller owns the lifecycle.\n *\n * Primary use case in this repo: component tests. Build a runtime with\n * `@demlik/tea/mem` and pre-seed it via `replay`, then mount the component with\n * `useRuntime(testRuntime)` to render in any phase.\n *\n * Returns `[state, dispatch]` — same shape as `useMachine`.\n */\nexport function useRuntime<S, M extends { type: string }>(\n runtime: Runtime<S, M>,\n): [S, (msg: M) => Promise<void>] {\n const state = useSyncExternalStore(\n runtime.subscribe,\n runtime.getState,\n runtime.getState,\n );\n return [state, runtime.dispatch];\n}\n"]}
1
+ {"version":3,"sources":["../../src/react/index.ts"],"names":[],"mappings":";;;;AA4EO,SAAS,UAAA,CAOd,SACA,IAAA,EACgC;AAMhC,EAAA,MAAM,MAAM,IAAA,CAAK,GAAA;AACjB,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AAMnB,EAAA,MAAM,OAAA,GAAU,OAAA;AAAA,IACd,MAAM,GAAA,CAAI,OAAA,EAAS,EAAE,GAAA,EAAK,OAAO,CAAA;AAAA,IACjC,CAAC,OAAA,EAAS,GAAA,EAAK,KAAK;AAAA,GACtB;AAeA,EAAA,MAAM,QAAA,GAAW,OAA6B,IAAI,CAAA;AAClD,EAAA,MAAM,GAAG,UAAU,CAAA,GAAI,WAAW,CAAC,IAAA,KAAiB,IAAA,GAAO,CAAA,EAAG,CAAC,CAAA;AAa/D,EAAA,MAAM,gBAAA,GAAmB,OAAA;AAAA,IACvB,MAAM,OAAA,CAAQ,IAAA,CAAK,IAAA,EAAM,GAAG,EAAE,CAAC,CAAA;AAAA,IAC/B,CAAC,SAAS,GAAG;AAAA,GACf;AAMA,EAAA,MAAM,WAAA,GAAc,MAClB,QAAA,CAAS,OAAA,KAAY,OAAO,QAAA,CAAS,OAAA,CAAQ,UAAS,GAAI,gBAAA;AAE5D,EAAA,MAAM,KAAA,GAAQ,oBAAA;AAAA,IACZ,OAAA,CAAQ,SAAA;AAAA,IACR,WAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,IAAA,GAAO,IAAA;AAMX,IAAA,OAAA,CAAQ,KAAA,CAAM,IAAA;AAAA,MACZ,CAAC,CAAA,KAAM;AACL,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,QAAA,CAAS,OAAA,GAAU,CAAA;AACnB,UAAA,UAAA,EAAW;AAAA,QACb;AAAA,MACF,CAAA;AAAA,MACA,MAAM;AAAA,MAAC;AAAA,KACT;AACA,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,GAAO,KAAA;AACP,MAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AAInB,MAAA,OAAA,CAAQ,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM;AAAA,MAAC,CAAC,CAAA;AAAA,IAC/B,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,OAAO,CAAC,KAAA,EAAO,OAAA,CAAQ,QAAQ,CAAA;AACjC;AAeO,SAAS,WACd,OAAA,EACgC;AAChC,EAAA,MAAM,KAAA,GAAQ,oBAAA;AAAA,IACZ,OAAA,CAAQ,SAAA;AAAA,IACR,OAAA,CAAQ,QAAA;AAAA,IACR,OAAA,CAAQ;AAAA,GACV;AACA,EAAA,OAAO,CAAC,KAAA,EAAO,OAAA,CAAQ,QAAQ,CAAA;AACjC","file":"index.js","sourcesContent":["/**\n * @packageDocumentation\n * @demlik/tea/react — React host adapter for `@demlik/tea`.\n *\n * The thinnest possible adapter that makes a tea machine consumable from a\n * React component. Three rules (PRD §\"React adapter\"):\n *\n * 1. The runtime is the source of truth, NOT React state. We subscribe via\n * `useSyncExternalStore(runtime.subscribe, runtime.getState,\n * runtime.getState)`. React renders are driven by runtime state changes;\n * React never owns the state.\n * 2. The runtime is memoized per component-mount, not per render. The deps\n * array is `[machine, opts.ctx, opts.store]` — IDENTITY, not value. See\n * `README.md` for the ctx-identity footgun + fix.\n * 3. Concurrent React is the design target. `useSyncExternalStore` is the\n * React-blessed primitive for tearing-free external state.\n *\n * Client-only in v1 — components that call `useMachine` MUST be `\"use client\"`.\n * Server Components consume data via Relay/RSC as today; tea machines own\n * client-side stateful flows. No RSC streaming, no server-side state\n * hydration. Crossing this boundary is a v2 concern.\n */\n\n\"use client\";\n\nimport {\n useEffect,\n useMemo,\n useReducer,\n useRef,\n useSyncExternalStore,\n} from \"react\";\nimport {\n type BootingRuntime,\n type Cmd,\n type Machine,\n type Runtime,\n run,\n type Store,\n type Sub,\n} from \"../index\";\n\n/**\n * Options passed to `useMachine`. The shape is intentionally minimal — `ctx`\n * is required (every machine has one), `store` is optional (omit it for\n * volatile-state machines).\n *\n * **Identity matters.** The runtime is memoized on `[machine, opts.ctx,\n * opts.store]`. A new `ctx` reference rebuilds the runtime. Always `useMemo`\n * (or otherwise stabilize) the ctx at the call site. See README.\n *\n * Forgetting to is no longer silent: the replaced runtime's `stop()` reports\n * `RuntimeDiscardedError` under `phase: \"discard\"` when Cmds were still in\n * flight, which the substrate's default sink warns about (issue #365).\n */\nexport interface UseMachineOpts<S, Ctx> {\n ctx: Ctx;\n store?: Store<S>;\n}\n\n/**\n * Build and own a `Runtime<S, M>` for the lifetime of the component mount.\n *\n * - Builds via `useMemo(() => run(machine, opts), [machine, opts.ctx,\n * opts.store])` — runtime is recreated when ANY of the three identities\n * change.\n * - Subscribes via `useSyncExternalStore(runtime.subscribe, runtime.getState,\n * runtime.getState)` — tearing-free under React 18 concurrent rendering.\n * - On unmount (or any dep change), `useEffect` cleanup calls\n * `runtime.stop()` — drains the queue, runs every active sub cleanup,\n * flushes state, and — if Cmds were still in flight — reports\n * `RuntimeDiscardedError` (`phase: \"discard\"`) rather than dropping them\n * silently.\n *\n * Returns `[state, dispatch]` shaped like `useReducer`.\n */\nexport function useMachine<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n>(\n machine: Machine<S, M, C, U, Ctx>,\n opts: UseMachineOpts<S, Ctx>,\n): [S, (msg: M) => Promise<void>] {\n // Deps are literal: machine identity, ctx identity, store identity. NOT\n // `[opts]` (would rebuild every render — callers pass fresh objects).\n // We pass explicit fields to `run()` so the closure captures only the\n // deps in the array — keeps biome's `useExhaustiveDependencies` happy\n // without lying about what the memo actually depends on.\n const ctx = opts.ctx;\n const store = opts.store;\n // `run()` returns a `BootingRuntime<S, M>` SYNCHRONOUSLY (issue #45) — exactly\n // what `useMemo` needs. We never `await` here: awaiting would force an async\n // memo, a null first-commit state, and a resolved-flag dance. Instead we hold\n // the booting handle and capture the booted `Runtime` (the only thing with a\n // total `getState`) once `ready` resolves.\n const booting = useMemo<BootingRuntime<S, M>>(\n () => run(machine, { ctx, store }),\n [machine, ctx, store],\n );\n\n // Captures the booted `Runtime` once `ready` resolves. Until then it is\n // `null` and `getSnapshot` serves `preliminaryState`. Reset whenever the\n // booting handle identity changes (a new machine/ctx/store mount).\n //\n // The boot race the paired `bootedTick` bump exists for: the substrate's\n // boot fanout fires BEFORE `ready` resolves (fireListeners runs inside the\n // boot step; `ready` chains off the boot promise), so at notification time\n // this ref is still null and `getSnapshot` returns the same\n // `preliminaryState` reference — React sees an unchanged snapshot and\n // skips the re-render. Nothing re-notifies after the ref is set, so a\n // store-backed mount would stay stuck on the preliminary state until the\n // next unrelated transition. Bumping a reducer when we capture the booted\n // runtime forces the render that swaps preliminary → real state.\n const readyRef = useRef<Runtime<S, M> | null>(null);\n const [, markBooted] = useReducer((tick: number) => tick + 1, 0);\n\n // Preliminary state computed sync from `machine.init(null, ctx)`. This is\n // the snapshot React sees BEFORE the runtime finishes booting (matters\n // only when `opts.store` is present — without a store, the substrate\n // already sets state synchronously inside `run()`, so the boot fanout that\n // captures `readyRef` lands on the same microtask as the first commit).\n //\n // We deliberately recompute on each render but cache by `[machine,\n // opts.ctx]` — `init` is pure by convention, so cost is negligible. The\n // cached snapshot is also identity-stable across rerenders when the deps\n // don't change, which `useSyncExternalStore` rewards (no spurious\n // re-renders).\n const preliminaryState = useMemo<S>(\n () => machine.init(null, ctx)[0],\n [machine, ctx],\n );\n\n // `getSnapshot` reads the booted runtime if `ready` has resolved (the ref is\n // populated), else falls back to the preliminary state. No try/catch dance\n // anymore — pre-boot there is simply no booted `Runtime` to read from, so\n // the fallback is structural, not exception-driven.\n const getSnapshot = (): S =>\n readyRef.current !== null ? readyRef.current.getState() : preliminaryState;\n\n const state = useSyncExternalStore(\n booting.subscribe,\n getSnapshot,\n getSnapshot,\n );\n\n useEffect(() => {\n let live = true;\n // Capture the booted runtime when `ready` resolves, then force the\n // render that swaps preliminary → real state (see the boot-race note on\n // `readyRef` — the boot fanout fires too early to do it for us). Boot\n // rejections are swallowed: a failed boot surfaces on every `dispatch`,\n // which is where the consumer handles it.\n booting.ready.then(\n (r) => {\n if (live) {\n readyRef.current = r;\n markBooted();\n }\n },\n () => {},\n );\n return () => {\n live = false;\n readyRef.current = null;\n // Fire-and-forget — `stop()` is async but `useEffect` cleanup is sync.\n // The runtime swallows in-flight rejections internally, so this never\n // rejects in practice; we still attach `.catch` for safety.\n booting.stop().catch(() => {});\n };\n }, [booting]);\n\n return [state, booting.dispatch];\n}\n\n/**\n * Lower-level escape hatch: consume an externally-built `Runtime<S, M>`.\n *\n * Use this when the runtime is owned by something OTHER than the component —\n * a parent component, a test harness, a singleton. **The component does NOT\n * call `runtime.stop()` on unmount** — the caller owns the lifecycle.\n *\n * Primary use case in this repo: component tests. Build a runtime with\n * `@demlik/tea/mem` and pre-seed it via `replay`, then mount the component with\n * `useRuntime(testRuntime)` to render in any phase.\n *\n * Returns `[state, dispatch]` — same shape as `useMachine`.\n */\nexport function useRuntime<S, M extends { type: string }>(\n runtime: Runtime<S, M>,\n): [S, (msg: M) => Promise<void>] {\n const state = useSyncExternalStore(\n runtime.subscribe,\n runtime.getState,\n runtime.getState,\n );\n return [state, runtime.dispatch];\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { createPaginatedWalk, PAGE_KEY } from '../chunk-TPGASTFF.js';
1
+ import { createPaginatedWalk, PAGE_KEY } from '../chunk-JXYYRKD6.js';
2
2
  import '../chunk-SINXE47Y.js';
3
- import '../chunk-IXBKFQH5.js';
3
+ import '../chunk-B5RAZVXW.js';
4
4
  import '../chunk-JELSZN25.js';
5
5
  export { deadlineSub, subscribeDeadline } from '../chunk-RMX4EOQK.js';
6
6
  import '../chunk-Q2UM7BXU.js';
@@ -10,7 +10,7 @@ import { initCache, get, set } from '../chunk-2KNLKQVN.js';
10
10
  import '../chunk-LYLDCIPH.js';
11
11
  import '../chunk-2YFLOCWX.js';
12
12
  import '../chunk-ZJ5AOYBH.js';
13
- import '../chunk-BP2R7TPP.js';
13
+ import '../chunk-D4NJBQAH.js';
14
14
  import '../chunk-PBDYW2TU.js';
15
15
 
16
16
  // src/reconciler/index.ts
@@ -1,4 +1,4 @@
1
- import { B as BootingRuntime } from '../runtime-types-gsog27b6.js';
1
+ import { B as BootingRuntime } from '../runtime-types-CukV8kMX.js';
2
2
  import '../core-42kapW0n.js';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- export { createResilientCall, liftResilience } from '../chunk-IXBKFQH5.js';
1
+ export { createResilientCall, liftResilience } from '../chunk-B5RAZVXW.js';
2
2
  import '../chunk-JELSZN25.js';
3
3
  export { deadlineSub, subscribeDeadline } from '../chunk-RMX4EOQK.js';
4
4
  import '../chunk-Q2UM7BXU.js';
@@ -8,7 +8,7 @@ import '../chunk-2KNLKQVN.js';
8
8
  import '../chunk-LYLDCIPH.js';
9
9
  import '../chunk-2YFLOCWX.js';
10
10
  import '../chunk-ZJ5AOYBH.js';
11
- import '../chunk-BP2R7TPP.js';
11
+ import '../chunk-D4NJBQAH.js';
12
12
  import '../chunk-PBDYW2TU.js';
13
13
  //# sourceMappingURL=index.js.map
14
14
  //# sourceMappingURL=index.js.map
@@ -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,19 @@ 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`). The one phase that is a LIFECYCLE report rather
90
+ * than a failure: legal, merely lossy.
91
+ *
92
+ * The phase never decides fatality — the ERROR CLASS does (`RuntimeDiscardNotice`
93
+ * warns, everything else rethrows). A phase is attached by the report site, so a
94
+ * consumer sink that throws while handling a `"discard"` report inherits that
95
+ * phase; keying the warn-only path on it would make the sink's own defect vanish.
83
96
  */
84
- type RuntimeErrorPhase = "follow-up" | "stop-save" | "reduce" | "listener" | "observer" | "event" | "boot" | "port-emit" | "sub-cleanup";
97
+ type RuntimeErrorPhase = "follow-up" | "stop-save" | "reduce" | "listener" | "observer" | "event" | "boot" | "port-emit" | "sub-cleanup" | "discard";
85
98
  /** Context handed to an `OnError` sink alongside the error itself. */
86
99
  interface RuntimeErrorContext {
87
100
  readonly phase: RuntimeErrorPhase;
@@ -133,6 +146,62 @@ declare class QuiescenceTimeoutError extends Error {
133
146
  readonly _tag: "QuiescenceTimeoutError";
134
147
  constructor(iterations: number);
135
148
  }
149
+ /**
150
+ * Base of the LOSSY-BUT-LEGAL teardown facts: work the host discarded by letting
151
+ * go of a runtime that still had something outstanding. Reported under
152
+ * `phase: "discard"`, never raised.
153
+ *
154
+ * It exists so "is this fatal?" has ONE definition — `error instanceof
155
+ * RuntimeDiscardNotice` — that the default sink can ask about any error from any
156
+ * site. The phase cannot answer it: a report site attaches the phase, so a
157
+ * consumer sink that throws while handling a `"discard"` report carries that
158
+ * phase into the sink-failure path, and a phase-keyed warn branch would swallow
159
+ * the sink's own defect. Sub-classing is how a new teardown fact opts into the
160
+ * warn-only treatment; nothing else can.
161
+ */
162
+ declare abstract class RuntimeDiscardNotice extends Error {
163
+ }
164
+ /**
165
+ * Reported to the `OnError` sink under `phase: "discard"` when `stop()` is
166
+ * called while `interpret` handlers are still awaiting. The host is dropping
167
+ * its only handle on that work: `stop()` drains the tail, but the listeners,
168
+ * observers and event handlers that would have consumed the resulting
169
+ * transitions are gone, so the Cmds' results reach nobody.
170
+ *
171
+ * The motivating shape is `@demlik/tea/react`'s `useMachine`, which memoizes on
172
+ * `[machine, ctx, store]` — a ctx re-derived mid-flight replaces the runtime,
173
+ * and the in-flight mutation's response arrives for a runtime the UI no longer
174
+ * renders, silently rewinding the visible state. Never a throw: tearing a
175
+ * runtime down mid-flight is legal (a navigation does it every time), so this
176
+ * is surfaced as data, not raised. Mechanizes invariant 6 (no silent failures)
177
+ * at the teardown seam, the role `QuiescenceTimeoutError` plays for `idle()`.
178
+ */
179
+ declare class RuntimeDiscardedError extends RuntimeDiscardNotice {
180
+ readonly pendingCmds: number;
181
+ readonly name = "RuntimeDiscardedError";
182
+ readonly _tag: "RuntimeDiscardedError";
183
+ constructor(pendingCmds: number);
184
+ }
185
+ /**
186
+ * The rejection of a dispatch that arrived DURING `stop()`'s drain — an in-flight
187
+ * interpret handler's follow-up Msg, a detached handler's terminal Msg, or a Sub
188
+ * that is still live because subs are torn down only after the drain. The stop
189
+ * barrier is absolute (the Msg is refused, never folded), so this names the loss.
190
+ *
191
+ * It is the SECOND witness of `RuntimeDiscardedError`'s fact, and it is why the
192
+ * drain window is a distinct runtime state rather than a plain `stopped` flag:
193
+ * a Msg refused inside the window was discarded BY the teardown, while the same
194
+ * refusal after `stop()` has returned is a consumer dispatching into a runtime it
195
+ * already retired — a real error, and still loud (`phase: "follow-up"`, or the
196
+ * caller's own rejection). The distinction is the state at refusal time, never
197
+ * the message text.
198
+ */
199
+ declare class DispatchDiscardedError extends RuntimeDiscardNotice {
200
+ readonly msgType: string;
201
+ readonly name = "DispatchDiscardedError";
202
+ readonly _tag: "DispatchDiscardedError";
203
+ constructor(msgType: string);
204
+ }
136
205
  /**
137
206
  * Define a typed port. `name` is metadata (devtools / debug logs); port identity
138
207
  * is by reference. Each definePort call must use a unique `name` — a second call
@@ -334,4 +403,4 @@ declare function wrapDetached<C extends Cmd, M extends {
334
403
  }, Allowed extends M, Ctx>(handler: InterpretDetached<C, Allowed, Ctx>): (cmd: C, ctx: Ctx & PortEmitter, dispatch?: (msg: M) => void) => Promise<void>;
335
404
  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
405
 
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 };
406
+ export { type BootingRuntime as B, type CtxArg as C, DispatchDiscardedError 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, RuntimeDiscardNotice as h, RuntimeDiscardedError as i, definePort as j, type Schema as k, type DispatchSettle as l, type RuntimeRef as m, noop as n, defineMachine as o, asReducer as p, replay as r, schemaMigrate as s, tryInterpret as t, wrapDetached as w };
@@ -1,6 +1,6 @@
1
1
  import { C as Cmd } from '../core-42kapW0n.js';
2
2
  import { QueueItem } from '../work-queue/index.js';
3
- import '../runtime-types-gsog27b6.js';
3
+ import '../runtime-types-CukV8kMX.js';
4
4
 
5
5
  /**
6
6
  * @packageDocumentation
@@ -1,5 +1,5 @@
1
- export { createSnapshot, snapshotFailed, snapshotLoadFailed, snapshotLoaded, snapshotSaved } from '../chunk-MVY5DAMF.js';
2
- import '../chunk-BP2R7TPP.js';
1
+ export { createSnapshot, snapshotFailed, snapshotLoadFailed, snapshotLoaded, snapshotSaved } from '../chunk-SPWVPIFQ.js';
2
+ import '../chunk-D4NJBQAH.js';
3
3
  import '../chunk-PBDYW2TU.js';
4
4
  //# sourceMappingURL=index.js.map
5
5
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
1
  import { S as Sub, P as Port, D as DepKeyedSub, a as SubId } from '../core-42kapW0n.js';
2
2
  import { S as SubscribeHandler } from '../types-KbL3W1mj.js';
3
- import { R as Runtime } from '../runtime-types-gsog27b6.js';
3
+ import { R as Runtime } from '../runtime-types-CukV8kMX.js';
4
4
 
5
5
  /**
6
6
  * The imperative listener target, expressed as the `add`/`remove` pair the
@@ -1,7 +1,7 @@
1
1
  export { combineManagedResources, defineListener, defineManagedResource, fromBroadcastChannel, fromEventSource, fromEventTarget, fromInterval, fromPort, fromReconnectingWebSocket, fromTransport, fromWebSocket } from '../chunk-LYLDCIPH.js';
2
2
  export { fromTimeout } from '../chunk-2YFLOCWX.js';
3
3
  import '../chunk-ZJ5AOYBH.js';
4
- import '../chunk-BP2R7TPP.js';
4
+ import '../chunk-D4NJBQAH.js';
5
5
  import '../chunk-PBDYW2TU.js';
6
6
  //# sourceMappingURL=index.js.map
7
7
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
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';
2
+ import { R as Runtime } from '../runtime-types-CukV8kMX.js';
3
3
 
4
4
  /**
5
5
  * The composed Model shape every `withX` wrapper produces: the base machine's
@@ -1,4 +1,4 @@
1
- import { replay } from '../chunk-BP2R7TPP.js';
1
+ import { replay } from '../chunk-D4NJBQAH.js';
2
2
  import '../chunk-PBDYW2TU.js';
3
3
  import { expect, vi } from 'vitest';
4
4
 
@@ -6,7 +6,7 @@ import { initCache, get, set } from '../chunk-2KNLKQVN.js';
6
6
  import '../chunk-LYLDCIPH.js';
7
7
  import '../chunk-2YFLOCWX.js';
8
8
  import '../chunk-ZJ5AOYBH.js';
9
- import '../chunk-BP2R7TPP.js';
9
+ import '../chunk-D4NJBQAH.js';
10
10
  import '../chunk-PBDYW2TU.js';
11
11
 
12
12
  // src/throttled-input/index.ts
@@ -1,6 +1,6 @@
1
- export { createTokenRefresh, initTokenRefresh, refreshTokenCmd, tokenRefreshFailedMsg, tokenRefreshedMsg } from '../chunk-SK5JGUY7.js';
1
+ export { createTokenRefresh, initTokenRefresh, refreshTokenCmd, tokenRefreshFailedMsg, tokenRefreshedMsg } from '../chunk-TWDHNIY6.js';
2
2
  import '../chunk-JELSZN25.js';
3
- import '../chunk-BP2R7TPP.js';
3
+ import '../chunk-D4NJBQAH.js';
4
4
  import '../chunk-PBDYW2TU.js';
5
5
  //# sourceMappingURL=index.js.map
6
6
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
1
  import { C as Cmd, S as Sub, M as Machine } from '../core-42kapW0n.js';
2
2
  import { Trace } from '../recorder/index.js';
3
- import '../runtime-types-gsog27b6.js';
3
+ import '../runtime-types-CukV8kMX.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-2AHAR7CX.js';
2
2
  import '../chunk-EWJP3YYP.js';
3
- import '../chunk-BP2R7TPP.js';
3
+ import '../chunk-D4NJBQAH.js';
4
4
  import '../chunk-PBDYW2TU.js';
5
5
  //# sourceMappingURL=index.js.map
6
6
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
1
  import { fromTimeout } from '../chunk-2YFLOCWX.js';
2
- import '../chunk-BP2R7TPP.js';
2
+ import '../chunk-D4NJBQAH.js';
3
3
  import { msgKeysOf, applyCell, subId } from '../chunk-PBDYW2TU.js';
4
4
 
5
5
  // src/with-deadline/index.ts
@@ -1,4 +1,4 @@
1
- import { createResilientCall } from '../chunk-IXBKFQH5.js';
1
+ import { createResilientCall } from '../chunk-B5RAZVXW.js';
2
2
  import { MsgType } from '../chunk-JELSZN25.js';
3
3
  import { subscribeDeadline } from '../chunk-RMX4EOQK.js';
4
4
  import '../chunk-Q2UM7BXU.js';
@@ -8,7 +8,7 @@ import '../chunk-2KNLKQVN.js';
8
8
  import '../chunk-LYLDCIPH.js';
9
9
  import '../chunk-2YFLOCWX.js';
10
10
  import '../chunk-ZJ5AOYBH.js';
11
- import { tryInterpret } from '../chunk-BP2R7TPP.js';
11
+ import { tryInterpret } from '../chunk-D4NJBQAH.js';
12
12
  import { msgKeysOf, applyCell, subId, formOf } from '../chunk-PBDYW2TU.js';
13
13
 
14
14
  // src/with-resilience/index.ts
@@ -1,4 +1,4 @@
1
- import '../chunk-BP2R7TPP.js';
1
+ import '../chunk-D4NJBQAH.js';
2
2
  import { msgKeysOf, applyCell } from '../chunk-PBDYW2TU.js';
3
3
 
4
4
  // src/with-telemetry/index.ts
@@ -1,5 +1,5 @@
1
1
  import { QueueItem } from './index.js';
2
- import '../runtime-types-gsog27b6.js';
2
+ import '../runtime-types-CukV8kMX.js';
3
3
  import '../core-42kapW0n.js';
4
4
 
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { S as Store } from '../runtime-types-gsog27b6.js';
1
+ import { S as Store } from '../runtime-types-CukV8kMX.js';
2
2
  import '../core-42kapW0n.js';
3
3
 
4
4
  /**
@@ -1,5 +1,5 @@
1
1
  import { QueueItem } from './index.js';
2
- import '../runtime-types-gsog27b6.js';
2
+ import '../runtime-types-CukV8kMX.js';
3
3
  import '../core-42kapW0n.js';
4
4
 
5
5
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@demlik/tea",
3
- "version": "0.3.0",
3
+ "version": "0.4.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",