@demlik/tea 0.1.0 → 0.1.1
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.
- package/LICENSE +21 -0
- package/dist/agent/index.d.ts +907 -0
- package/dist/agent/index.js +20 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/authed-call/index.d.ts +119 -0
- package/dist/authed-call/index.js +148 -0
- package/dist/authed-call/index.js.map +1 -0
- package/dist/await-terminal/index.d.ts +99 -0
- package/dist/await-terminal/index.js +75 -0
- package/dist/await-terminal/index.js.map +1 -0
- package/dist/batch-window/index.d.ts +259 -0
- package/dist/batch-window/index.js +43 -0
- package/dist/batch-window/index.js.map +1 -0
- package/dist/cache/index.d.ts +2 -2
- package/dist/cache/index.js +2 -50
- package/dist/cache/index.js.map +1 -1
- package/dist/{chunk-CMG2KMWX.js → chunk-2WZHS4P2.js} +220 -177
- package/dist/chunk-2WZHS4P2.js.map +1 -0
- package/dist/chunk-2YOE5PIS.js +45 -0
- package/dist/chunk-2YOE5PIS.js.map +1 -0
- package/dist/chunk-3545BOYL.js +65 -0
- package/dist/chunk-3545BOYL.js.map +1 -0
- package/dist/chunk-5VNWZADP.js +49 -0
- package/dist/chunk-5VNWZADP.js.map +1 -0
- package/dist/{chunk-ZRUST6BK.js → chunk-7FYQGDMF.js} +2 -2
- package/dist/chunk-7FYQGDMF.js.map +1 -0
- package/dist/chunk-7VEG4KHB.js +202 -0
- package/dist/chunk-7VEG4KHB.js.map +1 -0
- package/dist/{chunk-PYBQREFU.js → chunk-A56GNPI7.js} +20 -6
- package/dist/chunk-A56GNPI7.js.map +1 -0
- package/dist/chunk-BNJYE4AU.js +157 -0
- package/dist/chunk-BNJYE4AU.js.map +1 -0
- package/dist/chunk-BYQUGDD3.js +16 -0
- package/dist/chunk-BYQUGDD3.js.map +1 -0
- package/dist/chunk-D5EQDLDV.js +186 -0
- package/dist/chunk-D5EQDLDV.js.map +1 -0
- package/dist/chunk-EDGDR5XX.js +60 -0
- package/dist/chunk-EDGDR5XX.js.map +1 -0
- package/dist/chunk-EIZJTYKR.js +93 -0
- package/dist/chunk-EIZJTYKR.js.map +1 -0
- package/dist/chunk-EQRUAP2A.js +56 -0
- package/dist/chunk-EQRUAP2A.js.map +1 -0
- package/dist/chunk-FH5RUIIL.js +61 -0
- package/dist/chunk-FH5RUIIL.js.map +1 -0
- package/dist/chunk-HJO6VNQI.js +15 -0
- package/dist/chunk-HJO6VNQI.js.map +1 -0
- package/dist/chunk-IFBQJYGI.js +132 -0
- package/dist/chunk-IFBQJYGI.js.map +1 -0
- package/dist/chunk-IN33Q4VJ.js +52 -0
- package/dist/chunk-IN33Q4VJ.js.map +1 -0
- package/dist/chunk-JELSZN25.js +47 -0
- package/dist/chunk-JELSZN25.js.map +1 -0
- package/dist/chunk-K575PT4S.js +58 -0
- package/dist/chunk-K575PT4S.js.map +1 -0
- package/dist/chunk-LEC4U6CX.js +91 -0
- package/dist/chunk-LEC4U6CX.js.map +1 -0
- package/dist/{chunk-Y5JM3UUH.js → chunk-NSDFA6M6.js} +75 -3
- package/dist/chunk-NSDFA6M6.js.map +1 -0
- package/dist/chunk-QGZW4W3E.js +20 -0
- package/dist/chunk-QGZW4W3E.js.map +1 -0
- package/dist/{chunk-PYOCUBQJ.js → chunk-RGTPPF4U.js} +22 -15
- package/dist/chunk-RGTPPF4U.js.map +1 -0
- package/dist/chunk-RVJFGRGK.js +222 -0
- package/dist/chunk-RVJFGRGK.js.map +1 -0
- package/dist/chunk-RVU3RBE6.js +31 -0
- package/dist/chunk-RVU3RBE6.js.map +1 -0
- package/dist/chunk-SC3FAFZN.js +53 -0
- package/dist/chunk-SC3FAFZN.js.map +1 -0
- package/dist/chunk-SINXE47Y.js +55 -0
- package/dist/chunk-SINXE47Y.js.map +1 -0
- package/dist/chunk-TAO4YOLO.js +87 -0
- package/dist/chunk-TAO4YOLO.js.map +1 -0
- package/dist/chunk-TC4HWABA.js +506 -0
- package/dist/chunk-TC4HWABA.js.map +1 -0
- package/dist/chunk-TGG26XMK.js +52 -0
- package/dist/chunk-TGG26XMK.js.map +1 -0
- package/dist/chunk-UV6UWGEO.js +147 -0
- package/dist/chunk-UV6UWGEO.js.map +1 -0
- package/dist/chunk-UYWUVEP6.js +158 -0
- package/dist/chunk-UYWUVEP6.js.map +1 -0
- package/dist/chunk-WUV3PSCZ.js +54 -0
- package/dist/chunk-WUV3PSCZ.js.map +1 -0
- package/dist/chunk-XRXKH7KA.js +268 -0
- package/dist/chunk-XRXKH7KA.js.map +1 -0
- package/dist/circuit-breaker/index.js +1 -51
- package/dist/circuit-breaker/index.js.map +1 -1
- package/dist/core-CymXZCeY.d.ts +178 -0
- package/dist/deadline/index.d.ts +24 -5
- package/dist/deadline/index.js +4 -18
- package/dist/deadline/index.js.map +1 -1
- package/dist/debounce/index.js +1 -54
- package/dist/debounce/index.js.map +1 -1
- package/dist/devtools/index.d.ts +1 -1
- package/dist/devtools/index.js +18 -6
- package/dist/devtools/index.js.map +1 -1
- package/dist/do/index.d.ts +1732 -92
- package/dist/do/index.js +677 -31
- package/dist/do/index.js.map +1 -1
- package/dist/durable-effects-2MDxDs45.d.ts +180 -0
- package/dist/extension/index.d.ts +31 -13
- package/dist/extension/index.js +5 -3
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/react.js +8 -3
- package/dist/extension/react.js.map +1 -1
- package/dist/extension/subs/index.d.ts +2 -2
- package/dist/extension/subs/index.js.map +1 -1
- package/dist/extension/test-utils.js +11 -3
- package/dist/extension/test-utils.js.map +1 -1
- package/dist/fan-out/index.d.ts +239 -0
- package/dist/fan-out/index.js +5 -0
- package/dist/fan-out/index.js.map +1 -0
- package/dist/idempotency/adapter.d.ts +62 -0
- package/dist/idempotency/adapter.js +4 -0
- package/dist/idempotency/adapter.js.map +1 -0
- package/dist/idempotency/index.js +1 -56
- package/dist/idempotency/index.js.map +1 -1
- package/dist/idempotent-intake/index.d.ts +186 -0
- package/dist/idempotent-intake/index.js +7 -0
- package/dist/idempotent-intake/index.js.map +1 -0
- package/dist/index.d.ts +341 -191
- package/dist/index.js +2 -1
- package/dist/llm-call/index.d.ts +309 -0
- package/dist/llm-call/index.js +14 -0
- package/dist/llm-call/index.js.map +1 -0
- package/dist/machine-viz/index.d.ts +1 -1
- package/dist/machine-viz/index.js +1 -1
- package/dist/machine-viz/index.js.map +1 -1
- package/dist/mem/index.d.ts +1 -0
- package/dist/monitored-run/index.d.ts +253 -0
- package/dist/monitored-run/index.js +10 -0
- package/dist/monitored-run/index.js.map +1 -0
- package/dist/node/index.d.ts +5 -5
- package/dist/node/index.js.map +1 -1
- package/dist/paginated-walk/index.d.ts +234 -0
- package/dist/paginated-walk/index.js +15 -0
- package/dist/paginated-walk/index.js.map +1 -0
- package/dist/paginator/index.d.ts +271 -0
- package/dist/paginator/index.js +3 -0
- package/dist/paginator/index.js.map +1 -0
- package/dist/parity/index.d.ts +86 -0
- package/dist/parity/index.js +77 -0
- package/dist/parity/index.js.map +1 -0
- package/dist/pbt/arbitraries/index.d.ts +1 -1
- package/dist/pbt/arbitraries/index.js +1 -1
- package/dist/pbt/index.d.ts +1 -1
- package/dist/pbt/index.js +5 -4
- package/dist/pbt/index.js.map +1 -1
- package/dist/pbt/runners/index.d.ts +1 -1
- package/dist/pbt/runners/index.js +3 -2
- package/dist/poller/index.d.ts +288 -0
- package/dist/poller/index.js +79 -0
- package/dist/poller/index.js.map +1 -0
- package/dist/prediction/index.d.ts +109 -0
- package/dist/prediction/index.js +4 -0
- package/dist/prediction/index.js.map +1 -0
- package/dist/protocol-B5YmJr0d.d.ts +45 -0
- package/dist/pure/index.d.ts +2 -0
- package/dist/pure/index.js +4 -0
- package/dist/pure/index.js.map +1 -0
- package/dist/raft/demo.d.ts +105 -0
- package/dist/raft/demo.js +172 -0
- package/dist/raft/demo.js.map +1 -0
- package/dist/raft/index.d.ts +548 -0
- package/dist/raft/index.js +7 -0
- package/dist/raft/index.js.map +1 -0
- package/dist/raft/sim.d.ts +222 -0
- package/dist/raft/sim.js +8 -0
- package/dist/raft/sim.js.map +1 -0
- package/dist/raft/timeline.d.ts +46 -0
- package/dist/raft/timeline.js +62 -0
- package/dist/raft/timeline.js.map +1 -0
- package/dist/rate-limit/index.js +1 -43
- package/dist/rate-limit/index.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.js +39 -20
- package/dist/react/index.js.map +1 -1
- package/dist/reconciler/index.d.ts +192 -0
- package/dist/reconciler/index.js +166 -0
- package/dist/reconciler/index.js.map +1 -0
- package/dist/recorder/index.d.ts +7 -3
- package/dist/recorder/index.js +1 -155
- package/dist/recorder/index.js.map +1 -1
- package/dist/resilient-call/index.d.ts +251 -0
- package/dist/resilient-call/index.js +13 -0
- package/dist/resilient-call/index.js.map +1 -0
- package/dist/retry-backoff/index.d.ts +42 -5
- package/dist/retry-backoff/index.js +1 -35
- package/dist/retry-backoff/index.js.map +1 -1
- package/dist/saga/index.d.ts +225 -0
- package/dist/saga/index.js +150 -0
- package/dist/saga/index.js.map +1 -0
- package/dist/snapshot/index.d.ts +334 -0
- package/dist/snapshot/index.js +5 -0
- package/dist/snapshot/index.js.map +1 -0
- package/dist/subs/index.d.ts +48 -10
- package/dist/subs/index.js +1 -1
- package/dist/testing/index.d.ts +107 -2
- package/dist/testing/index.js +204 -6
- package/dist/testing/index.js.map +1 -1
- package/dist/throttle/index.js +1 -52
- package/dist/throttle/index.js.map +1 -1
- package/dist/throttled-input/index.d.ts +372 -0
- package/dist/throttled-input/index.js +88 -0
- package/dist/throttled-input/index.js.map +1 -0
- package/dist/token-refresh/index.d.ts +215 -0
- package/dist/token-refresh/index.js +6 -0
- package/dist/token-refresh/index.js.map +1 -0
- package/dist/trace-replay/index.d.ts +11 -2
- package/dist/trace-replay/index.js +3 -55
- package/dist/trace-replay/index.js.map +1 -1
- package/dist/{types-CwBC5wMn.d.ts → types-N9LZbdnr.d.ts} +1 -1
- package/dist/with-deadline/index.d.ts +196 -0
- package/dist/with-deadline/index.js +130 -0
- package/dist/with-deadline/index.js.map +1 -0
- package/dist/with-resilience/index.d.ts +205 -0
- package/dist/with-resilience/index.js +274 -0
- package/dist/with-resilience/index.js.map +1 -0
- package/dist/with-telemetry/index.d.ts +149 -0
- package/dist/with-telemetry/index.js +95 -0
- package/dist/with-telemetry/index.js.map +1 -0
- package/dist/work-queue/adapter.d.ts +82 -0
- package/dist/work-queue/adapter.js +4 -0
- package/dist/work-queue/adapter.js.map +1 -0
- package/dist/work-queue/index.d.ts +25 -11
- package/dist/work-queue/index.js +1 -46
- package/dist/work-queue/index.js.map +1 -1
- package/dist/work-queue/ops.d.ts +69 -0
- package/dist/work-queue/ops.js +3 -0
- package/dist/work-queue/ops.js.map +1 -0
- package/dist/workflow/index.d.ts +444 -0
- package/dist/workflow/index.js +225 -0
- package/dist/workflow/index.js.map +1 -0
- package/package.json +162 -25
- package/dist/chunk-CMG2KMWX.js.map +0 -1
- package/dist/chunk-PYBQREFU.js.map +0 -1
- package/dist/chunk-PYOCUBQJ.js.map +0 -1
- package/dist/chunk-Y5JM3UUH.js.map +0 -1
- package/dist/chunk-ZRUST6BK.js.map +0 -1
|
@@ -1,126 +1,10 @@
|
|
|
1
|
+
import { detectUpdateForm, formOf, foldUpdates, __DEV__, deepFreeze, assertPureResult } from './chunk-BNJYE4AU.js';
|
|
1
2
|
import { Result } from 'better-result';
|
|
2
3
|
|
|
3
|
-
// src/index.ts
|
|
4
|
-
var __DEV__ = (() => {
|
|
5
|
-
try {
|
|
6
|
-
const meta = import.meta;
|
|
7
|
-
if (meta.env?.DEV !== void 0) {
|
|
8
|
-
return meta.env.DEV;
|
|
9
|
-
}
|
|
10
|
-
} catch {
|
|
11
|
-
}
|
|
12
|
-
try {
|
|
13
|
-
return typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
|
|
14
|
-
} catch {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
})();
|
|
18
|
-
function deepFreeze(obj, seen) {
|
|
19
|
-
if (obj === null || typeof obj !== "object") return obj;
|
|
20
|
-
const proto = Object.getPrototypeOf(obj);
|
|
21
|
-
if (proto !== Object.prototype && proto !== Array.prototype && proto !== null) return obj;
|
|
22
|
-
const visited = seen ?? /* @__PURE__ */ new WeakSet();
|
|
23
|
-
if (visited.has(obj)) return obj;
|
|
24
|
-
visited.add(obj);
|
|
25
|
-
Object.freeze(obj);
|
|
26
|
-
for (const v of Object.values(obj)) deepFreeze(v, visited);
|
|
27
|
-
return obj;
|
|
28
|
-
}
|
|
29
|
-
function hasFunctionValues(obj) {
|
|
30
|
-
if (obj === null || typeof obj !== "object") return null;
|
|
31
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
32
|
-
if (typeof value === "function") return key;
|
|
33
|
-
}
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
function assertPureResult(result, msgType) {
|
|
37
|
-
if (result && typeof result.then === "function") {
|
|
38
|
-
throw new Error(
|
|
39
|
-
`@demlik/tea: update cell "${msgType}" returned a Promise. update must be synchronous. Move async work to interpret.`
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
if (!Array.isArray(result) || result.length < 2 || !Array.isArray(result[1])) {
|
|
43
|
-
throw new Error(
|
|
44
|
-
`@demlik/tea: update cell "${msgType}" returned a non-tuple. Expected [State, Cmd[]], got ${typeof result}.`
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
const cmds = result[1];
|
|
48
|
-
for (const cmd of cmds) {
|
|
49
|
-
const fnField = hasFunctionValues(cmd);
|
|
50
|
-
if (fnField !== null) {
|
|
51
|
-
throw new Error(
|
|
52
|
-
`@demlik/tea: Cmd "${cmd.type}" has function field "${fnField}". Cmds must be plain data, not closures.`
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
4
|
function absurd(x) {
|
|
58
5
|
throw new Error(`unreachable: ${JSON.stringify(x)}`);
|
|
59
6
|
}
|
|
60
|
-
var noop = (state, _msg) => [
|
|
61
|
-
state,
|
|
62
|
-
[]
|
|
63
|
-
];
|
|
64
|
-
var Cmd = {
|
|
65
|
-
/**
|
|
66
|
-
* The empty Cmd array. Typed `readonly never[]` so it's assignable to any
|
|
67
|
-
* `readonly C[]` for any `C extends Cmd`. Use in `init` returns and
|
|
68
|
-
* Transitions cells that emit zero effects:
|
|
69
|
-
*
|
|
70
|
-
* init: (loaded) => [loaded ?? initial, Cmd.none],
|
|
71
|
-
* tick: (state) => [state, Cmd.none],
|
|
72
|
-
*
|
|
73
|
-
* Elm's `Cmd.none` analogue. Cultural signal alongside the runtime help:
|
|
74
|
-
* `[state, Cmd.none]` reads as intent ("this transition emits nothing"),
|
|
75
|
-
* `[state, []]` reads as "empty array of what".
|
|
76
|
-
*
|
|
77
|
-
* Frozen at runtime so a downstream consumer can't `.push()` into the
|
|
78
|
-
* shared reference.
|
|
79
|
-
*/
|
|
80
|
-
none: Object.freeze([]),
|
|
81
|
-
/**
|
|
82
|
-
* Flat concat of cmd arrays. Use when a cell composes effects from
|
|
83
|
-
* multiple conditional sources:
|
|
84
|
-
*
|
|
85
|
-
* return [next, Cmd.batch(
|
|
86
|
-
* Cmd.whenDefined(state.queueItemId, (id) => ({ type: "complete", id })),
|
|
87
|
-
* Cmd.when(state.windowId !== undefined, { type: "close_window", windowId }),
|
|
88
|
-
* [{ type: "detach_debugger", tabId: state.tabId }],
|
|
89
|
-
* )];
|
|
90
|
-
*
|
|
91
|
-
* `<const C>` keeps inline cmd literals' discriminants narrow (same
|
|
92
|
-
* rationale as `when` / `whenDefined` above).
|
|
93
|
-
*/
|
|
94
|
-
batch: (...arrs) => {
|
|
95
|
-
const out = [];
|
|
96
|
-
for (const arr of arrs) out.push(...arr);
|
|
97
|
-
return out;
|
|
98
|
-
},
|
|
99
|
-
/**
|
|
100
|
-
* Emit `cmd` wrapped in a single-element array iff `cond` is true.
|
|
101
|
-
* Otherwise return the empty array. Spreads cleanly into the cmds array
|
|
102
|
-
* returned by a Transitions cell.
|
|
103
|
-
*
|
|
104
|
-
* `const C` (TypeScript 5.0+) keeps the inferred `type:` discriminator
|
|
105
|
-
* literal narrow when called with an object literal — so `Cmd.when(b,
|
|
106
|
-
* { type: "x", ... })` infers as `{ type: "x", ... }`, not `{ type:
|
|
107
|
-
* string, ... }`, and stays assignable to a discriminated-union arm
|
|
108
|
-
* without `as const` at the call site.
|
|
109
|
-
*/
|
|
110
|
-
when: (cond, cmd) => cond ? [cmd] : [],
|
|
111
|
-
/**
|
|
112
|
-
* If `value` is defined, call `build(value)` and emit the resulting cmd
|
|
113
|
-
* wrapped in a single-element array. If `value` is `undefined`, return
|
|
114
|
-
* the empty array. `value` is narrowed to `T` inside `build`.
|
|
115
|
-
*
|
|
116
|
-
* `const C` on the return type keeps the callback's object-literal
|
|
117
|
-
* `type:` field narrow (see `when` above for the full rationale).
|
|
118
|
-
*/
|
|
119
|
-
whenDefined: (value, build) => value !== void 0 ? [build(value)] : []
|
|
120
|
-
};
|
|
121
|
-
function subId(s) {
|
|
122
|
-
return s;
|
|
123
|
-
}
|
|
7
|
+
var noop = (state, _msg) => [state, []];
|
|
124
8
|
var definedPortNames = /* @__PURE__ */ new Set();
|
|
125
9
|
var PortNameCollisionError = class extends Error {
|
|
126
10
|
name = "PortNameCollisionError";
|
|
@@ -133,6 +17,25 @@ var PortNameCollisionError = class extends Error {
|
|
|
133
17
|
function __resetPortRegistry() {
|
|
134
18
|
definedPortNames.clear();
|
|
135
19
|
}
|
|
20
|
+
function defaultOnError(error, _context) {
|
|
21
|
+
setTimeout(() => {
|
|
22
|
+
throw error;
|
|
23
|
+
}, 0);
|
|
24
|
+
}
|
|
25
|
+
function normalizeSupervision(supervision) {
|
|
26
|
+
if (supervision === void 0) return { strategy: "stop" };
|
|
27
|
+
if (typeof supervision === "string") return { strategy: supervision };
|
|
28
|
+
return supervision;
|
|
29
|
+
}
|
|
30
|
+
var QuiescenceTimeoutError = class extends Error {
|
|
31
|
+
constructor(iterations) {
|
|
32
|
+
super(
|
|
33
|
+
`@demlik/tea: idle() did not reach quiescence after ${iterations} iterations \u2014 the dispatch tail kept advancing. The machine is likely livelocking (an interpret handler enqueues a follow-up Msg that enqueues another, without end). Bound the follow-up chain in the reducer, or stop the runtime.`
|
|
34
|
+
);
|
|
35
|
+
this.iterations = iterations;
|
|
36
|
+
}
|
|
37
|
+
name = "QuiescenceTimeoutError";
|
|
38
|
+
};
|
|
136
39
|
function definePort(name) {
|
|
137
40
|
let isHmr = false;
|
|
138
41
|
try {
|
|
@@ -148,16 +51,44 @@ function definePort(name) {
|
|
|
148
51
|
return { __brand: "port", name };
|
|
149
52
|
}
|
|
150
53
|
function defineMachine(m) {
|
|
54
|
+
if (m.__form === void 0) {
|
|
55
|
+
Object.defineProperty(m, "__form", {
|
|
56
|
+
value: detectUpdateForm(m.update),
|
|
57
|
+
enumerable: false,
|
|
58
|
+
writable: false,
|
|
59
|
+
configurable: true
|
|
60
|
+
});
|
|
61
|
+
}
|
|
151
62
|
return m;
|
|
152
63
|
}
|
|
64
|
+
function asReducer(reducer) {
|
|
65
|
+
return reducer;
|
|
66
|
+
}
|
|
153
67
|
function run(machine, opts) {
|
|
154
|
-
const {
|
|
68
|
+
const { store } = opts;
|
|
69
|
+
const ctx = opts.ctx ?? {};
|
|
70
|
+
const idleCap = opts.__idleCap ?? 1e5;
|
|
71
|
+
const projectEvents = opts.events ?? (() => []);
|
|
72
|
+
const isTerminal = opts.terminal ?? (() => false);
|
|
73
|
+
const onError = opts.onError ?? defaultOnError;
|
|
74
|
+
const reportError = (error, context) => {
|
|
75
|
+
try {
|
|
76
|
+
onError(error, context);
|
|
77
|
+
} catch (sinkError) {
|
|
78
|
+
defaultOnError(sinkError);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const supervision = normalizeSupervision(opts.supervision);
|
|
155
82
|
let state;
|
|
156
83
|
let bootError = null;
|
|
157
84
|
let stopped = false;
|
|
158
85
|
const subRegistry = /* @__PURE__ */ new Map();
|
|
159
86
|
const listeners = /* @__PURE__ */ new Set();
|
|
160
87
|
const observers = /* @__PURE__ */ new Set();
|
|
88
|
+
const bootHandlers = /* @__PURE__ */ new Set();
|
|
89
|
+
let booted = false;
|
|
90
|
+
const eventHandlers = /* @__PURE__ */ new Map();
|
|
91
|
+
const doneWaiters = /* @__PURE__ */ new Set();
|
|
161
92
|
const portRegistry = /* @__PURE__ */ new Map();
|
|
162
93
|
function portEmit(port, value) {
|
|
163
94
|
const subscribers = portRegistry.get(port);
|
|
@@ -172,14 +103,7 @@ function run(machine, opts) {
|
|
|
172
103
|
}
|
|
173
104
|
const augmentedCtx = { ...ctx, emit: portEmit };
|
|
174
105
|
const updateForm = machine.update;
|
|
175
|
-
const updateMode = (
|
|
176
|
-
const firstKey = Object.keys(updateForm)[0];
|
|
177
|
-
if (firstKey === void 0) {
|
|
178
|
-
return "reducer";
|
|
179
|
-
}
|
|
180
|
-
const firstValue = updateForm[firstKey];
|
|
181
|
-
return typeof firstValue === "function" ? "reducer" : "transitions";
|
|
182
|
-
})();
|
|
106
|
+
const updateMode = formOf(machine);
|
|
183
107
|
function applyUpdate(state2, msg) {
|
|
184
108
|
if (__DEV__) deepFreeze(state2);
|
|
185
109
|
let result;
|
|
@@ -230,7 +154,11 @@ function run(machine, opts) {
|
|
|
230
154
|
continue;
|
|
231
155
|
}
|
|
232
156
|
try {
|
|
233
|
-
const cleanup = handler(
|
|
157
|
+
const cleanup = handler(
|
|
158
|
+
sub,
|
|
159
|
+
ctx,
|
|
160
|
+
enqueueDispatch
|
|
161
|
+
);
|
|
234
162
|
subRegistry.set(sub.id, cleanup);
|
|
235
163
|
} catch (err) {
|
|
236
164
|
if (firstStartError === null) firstStartError = err;
|
|
@@ -243,9 +171,13 @@ function run(machine, opts) {
|
|
|
243
171
|
for (const cmd of cmds) {
|
|
244
172
|
const handler = interpretMap[cmd.type];
|
|
245
173
|
if (!handler) continue;
|
|
246
|
-
const follow = await handler(
|
|
174
|
+
const follow = await handler(
|
|
175
|
+
cmd,
|
|
176
|
+
augmentedCtx
|
|
177
|
+
);
|
|
247
178
|
if (follow !== void 0 && follow !== null) {
|
|
248
|
-
enqueueDispatch(follow).catch(() => {
|
|
179
|
+
enqueueDispatch(follow).catch((error) => {
|
|
180
|
+
reportError(error, { phase: "follow-up" });
|
|
249
181
|
});
|
|
250
182
|
}
|
|
251
183
|
}
|
|
@@ -270,17 +202,83 @@ function run(machine, opts) {
|
|
|
270
202
|
}
|
|
271
203
|
}
|
|
272
204
|
}
|
|
205
|
+
function fireEvents(msg) {
|
|
206
|
+
if (eventHandlers.size === 0 || state === void 0) return;
|
|
207
|
+
let events;
|
|
208
|
+
try {
|
|
209
|
+
events = projectEvents(msg, state);
|
|
210
|
+
} catch (err) {
|
|
211
|
+
console.error(err);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
for (const event of events) {
|
|
215
|
+
const bucket = eventHandlers.get(event.type);
|
|
216
|
+
if (bucket === void 0) continue;
|
|
217
|
+
for (const handler of bucket) {
|
|
218
|
+
try {
|
|
219
|
+
handler(event);
|
|
220
|
+
} catch (err) {
|
|
221
|
+
console.error(err);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
function fireBoot() {
|
|
227
|
+
booted = true;
|
|
228
|
+
if (bootHandlers.size === 0 || state === void 0) return;
|
|
229
|
+
const snapshot = state;
|
|
230
|
+
for (const handler of bootHandlers) {
|
|
231
|
+
try {
|
|
232
|
+
handler(snapshot);
|
|
233
|
+
} catch (err) {
|
|
234
|
+
console.error(err);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
function settleDoneWaiters() {
|
|
239
|
+
if (doneWaiters.size === 0 || state === void 0) return;
|
|
240
|
+
if (!isTerminal(state)) return;
|
|
241
|
+
const snapshot = state;
|
|
242
|
+
const parked = [...doneWaiters];
|
|
243
|
+
doneWaiters.clear();
|
|
244
|
+
for (const resolve of parked) resolve(snapshot);
|
|
245
|
+
}
|
|
273
246
|
async function stepDispatch(msg) {
|
|
274
247
|
if (state === void 0) {
|
|
275
248
|
throw new Error("@demlik/tea: runtime not booted");
|
|
276
249
|
}
|
|
277
|
-
|
|
250
|
+
let next;
|
|
251
|
+
let cmds;
|
|
252
|
+
try {
|
|
253
|
+
[next, cmds] = applyUpdate(state, msg);
|
|
254
|
+
} catch (reduceError) {
|
|
255
|
+
reportError(reduceError, { phase: "reduce" });
|
|
256
|
+
switch (supervision.strategy) {
|
|
257
|
+
case "restart": {
|
|
258
|
+
state = supervision.rehydrate(state, msg, reduceError);
|
|
259
|
+
if (store) await store.save(state);
|
|
260
|
+
reconcileSubs();
|
|
261
|
+
fireListeners();
|
|
262
|
+
fireObservers(msg);
|
|
263
|
+
fireEvents(msg);
|
|
264
|
+
settleDoneWaiters();
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
case "escalate":
|
|
268
|
+
throw reduceError;
|
|
269
|
+
default:
|
|
270
|
+
stopped = true;
|
|
271
|
+
throw reduceError;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
278
274
|
state = next;
|
|
279
275
|
if (store) await store.save(state);
|
|
280
276
|
reconcileSubs();
|
|
281
277
|
await runInterpret(cmds);
|
|
282
278
|
fireListeners();
|
|
283
279
|
fireObservers(msg);
|
|
280
|
+
fireEvents(msg);
|
|
281
|
+
settleDoneWaiters();
|
|
284
282
|
}
|
|
285
283
|
let pendingInitCmds = [];
|
|
286
284
|
if (!store) {
|
|
@@ -300,10 +298,12 @@ function run(machine, opts) {
|
|
|
300
298
|
reconcileSubs();
|
|
301
299
|
await runInterpret(pendingInitCmds);
|
|
302
300
|
fireListeners();
|
|
303
|
-
|
|
301
|
+
fireBoot();
|
|
302
|
+
settleDoneWaiters();
|
|
304
303
|
}
|
|
305
304
|
function enqueueDispatch(msg) {
|
|
306
|
-
if (stopped)
|
|
305
|
+
if (stopped)
|
|
306
|
+
return Promise.reject(new Error("@demlik/tea: runtime stopped"));
|
|
307
307
|
const next = tail.then(() => {
|
|
308
308
|
if (bootError !== null) throw bootError;
|
|
309
309
|
return stepDispatch(msg);
|
|
@@ -312,17 +312,30 @@ function run(machine, opts) {
|
|
|
312
312
|
});
|
|
313
313
|
return next;
|
|
314
314
|
}
|
|
315
|
+
async function drainToQuiescence() {
|
|
316
|
+
for (let i = 0; i < idleCap; i++) {
|
|
317
|
+
const observed = tail;
|
|
318
|
+
await observed;
|
|
319
|
+
if (tail === observed) return;
|
|
320
|
+
}
|
|
321
|
+
throw new QuiescenceTimeoutError(idleCap);
|
|
322
|
+
}
|
|
323
|
+
async function dispatchToQuiescence(msg, opts2) {
|
|
324
|
+
await enqueueDispatch(msg);
|
|
325
|
+
if (opts2?.settle === "once") return;
|
|
326
|
+
await drainToQuiescence();
|
|
327
|
+
}
|
|
315
328
|
const bootPromise = stepBootEffects();
|
|
316
329
|
tail = bootPromise.catch((err) => {
|
|
317
330
|
bootError = err;
|
|
318
331
|
});
|
|
332
|
+
const readyPromise = bootPromise.then(
|
|
333
|
+
() => runtime
|
|
334
|
+
);
|
|
319
335
|
const runtime = {
|
|
320
|
-
dispatch:
|
|
336
|
+
dispatch: dispatchToQuiescence,
|
|
337
|
+
dispatchOnce: enqueueDispatch,
|
|
321
338
|
getState() {
|
|
322
|
-
if (bootError !== null) throw bootError;
|
|
323
|
-
if (state === void 0) {
|
|
324
|
-
throw new Error("@demlik/tea: getState() called before runtime booted");
|
|
325
|
-
}
|
|
326
339
|
return state;
|
|
327
340
|
},
|
|
328
341
|
subscribe(listener) {
|
|
@@ -337,6 +350,36 @@ function run(machine, opts) {
|
|
|
337
350
|
observers.delete(observer);
|
|
338
351
|
};
|
|
339
352
|
},
|
|
353
|
+
onBoot(handler) {
|
|
354
|
+
if (booted && state !== void 0) {
|
|
355
|
+
try {
|
|
356
|
+
handler(state);
|
|
357
|
+
} catch (err) {
|
|
358
|
+
console.error(err);
|
|
359
|
+
}
|
|
360
|
+
return () => {
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
bootHandlers.add(handler);
|
|
364
|
+
return () => {
|
|
365
|
+
bootHandlers.delete(handler);
|
|
366
|
+
};
|
|
367
|
+
},
|
|
368
|
+
on(type, handler) {
|
|
369
|
+
let bucket = eventHandlers.get(type);
|
|
370
|
+
if (bucket === void 0) {
|
|
371
|
+
bucket = /* @__PURE__ */ new Set();
|
|
372
|
+
eventHandlers.set(type, bucket);
|
|
373
|
+
}
|
|
374
|
+
const erased = handler;
|
|
375
|
+
bucket.add(erased);
|
|
376
|
+
return () => {
|
|
377
|
+
const set = eventHandlers.get(type);
|
|
378
|
+
if (set === void 0) return;
|
|
379
|
+
set.delete(erased);
|
|
380
|
+
if (set.size === 0) eventHandlers.delete(type);
|
|
381
|
+
};
|
|
382
|
+
},
|
|
340
383
|
subscribePort(port, listener) {
|
|
341
384
|
const key = port;
|
|
342
385
|
let bucket = portRegistry.get(key);
|
|
@@ -356,11 +399,24 @@ function run(machine, opts) {
|
|
|
356
399
|
emitPort(port, value) {
|
|
357
400
|
portEmit(port, value);
|
|
358
401
|
},
|
|
359
|
-
// `ready` is
|
|
360
|
-
//
|
|
361
|
-
//
|
|
362
|
-
|
|
363
|
-
|
|
402
|
+
// `ready` is assigned just below (it must resolve to `runtime` itself,
|
|
403
|
+
// which can't be referenced inside its own object literal). See the
|
|
404
|
+
// assignment + rationale after this block.
|
|
405
|
+
ready: readyPromise,
|
|
406
|
+
idle() {
|
|
407
|
+
return drainToQuiescence();
|
|
408
|
+
},
|
|
409
|
+
result() {
|
|
410
|
+
const current = state;
|
|
411
|
+
return isTerminal(current) ? current : void 0;
|
|
412
|
+
},
|
|
413
|
+
done() {
|
|
414
|
+
const current = state;
|
|
415
|
+
if (isTerminal(current)) return Promise.resolve(current);
|
|
416
|
+
return new Promise((resolve) => {
|
|
417
|
+
doneWaiters.add(resolve);
|
|
418
|
+
});
|
|
419
|
+
},
|
|
364
420
|
async stop() {
|
|
365
421
|
stopped = true;
|
|
366
422
|
await tail;
|
|
@@ -375,8 +431,8 @@ function run(machine, opts) {
|
|
|
375
431
|
if (store && state !== void 0 && bootError === null) {
|
|
376
432
|
try {
|
|
377
433
|
await store.save(state);
|
|
378
|
-
} catch (
|
|
379
|
-
|
|
434
|
+
} catch (error) {
|
|
435
|
+
reportError(error, { phase: "stop-save" });
|
|
380
436
|
}
|
|
381
437
|
}
|
|
382
438
|
}
|
|
@@ -386,10 +442,17 @@ function run(machine, opts) {
|
|
|
386
442
|
function historyTracker(runtime, size) {
|
|
387
443
|
const buffer = [];
|
|
388
444
|
let stopped = false;
|
|
445
|
+
const push = (entry) => {
|
|
446
|
+
buffer.push(entry);
|
|
447
|
+
if (buffer.length > size) buffer.shift();
|
|
448
|
+
};
|
|
389
449
|
const unobserve = size <= 0 ? () => {
|
|
390
450
|
} : runtime.observe((msg, state) => {
|
|
391
|
-
|
|
392
|
-
|
|
451
|
+
push({ msg, state });
|
|
452
|
+
});
|
|
453
|
+
const unboot = size <= 0 ? () => {
|
|
454
|
+
} : runtime.onBoot((state) => {
|
|
455
|
+
push({ msg: null, state });
|
|
393
456
|
});
|
|
394
457
|
return {
|
|
395
458
|
snapshot() {
|
|
@@ -399,6 +462,7 @@ function historyTracker(runtime, size) {
|
|
|
399
462
|
if (stopped) return;
|
|
400
463
|
stopped = true;
|
|
401
464
|
unobserve();
|
|
465
|
+
unboot();
|
|
402
466
|
}
|
|
403
467
|
};
|
|
404
468
|
}
|
|
@@ -410,33 +474,12 @@ function replay(machine, opts) {
|
|
|
410
474
|
"TEA contract violation: machine.init must return [state, []] (no Cmds) when `loaded` is non-null. Init's rehydrate branch is a pure state passthrough \u2014 the migration/parse boundary, not the boot-effect hook.\n\nRoutes for boot effects:\n - Stateless infrastructure (e.g. chrome.alarms ensure) \u2192 host module top level, outside TEA.\n - State-conditional resume (e.g. re-attach a session) \u2192 a `boot` Msg dispatched once from the host after `run(...)` returns, handled in update.\n\nSee .patterns/tea/tea-invariants.md (Invariant 2)."
|
|
411
475
|
);
|
|
412
476
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
const firstValue = updateForm[firstKey];
|
|
420
|
-
return typeof firstValue === "function" ? "reducer" : "transitions";
|
|
421
|
-
})();
|
|
422
|
-
for (const msg of opts.msgs) {
|
|
423
|
-
if (__DEV__) deepFreeze(state);
|
|
424
|
-
let result;
|
|
425
|
-
if (updateMode === "reducer") {
|
|
426
|
-
result = updateForm[msg.type](
|
|
427
|
-
state,
|
|
428
|
-
msg
|
|
429
|
-
);
|
|
430
|
-
} else {
|
|
431
|
-
const table = updateForm;
|
|
432
|
-
const stateKey = state.type;
|
|
433
|
-
result = table[stateKey][msg.type](state, msg);
|
|
434
|
-
}
|
|
435
|
-
if (__DEV__) assertPureResult(result, msg.type);
|
|
436
|
-
const [next, emitted] = result;
|
|
437
|
-
state = next;
|
|
438
|
-
cmds.push(...emitted);
|
|
439
|
-
}
|
|
477
|
+
const { state, cmds: foldedCmds } = foldUpdates(
|
|
478
|
+
machine,
|
|
479
|
+
initialState,
|
|
480
|
+
opts.msgs
|
|
481
|
+
);
|
|
482
|
+
const cmds = [...initCmds, ...foldedCmds];
|
|
440
483
|
const subs = machine.subscriptions ? [...machine.subscriptions(state)] : [];
|
|
441
484
|
return { state, cmds, subs };
|
|
442
485
|
}
|
|
@@ -453,6 +496,6 @@ function tryInterpret(work, onOk, onErr) {
|
|
|
453
496
|
};
|
|
454
497
|
}
|
|
455
498
|
|
|
456
|
-
export {
|
|
457
|
-
//# sourceMappingURL=chunk-
|
|
458
|
-
//# sourceMappingURL=chunk-
|
|
499
|
+
export { PortNameCollisionError, QuiescenceTimeoutError, __resetPortRegistry, absurd, asReducer, defineMachine, definePort, historyTracker, noop, replay, run, tryInterpret };
|
|
500
|
+
//# sourceMappingURL=chunk-2WZHS4P2.js.map
|
|
501
|
+
//# sourceMappingURL=chunk-2WZHS4P2.js.map
|