@demlik/tea 0.6.0 → 0.8.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 (158) hide show
  1. package/dist/agent/index.d.ts +6 -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 +3 -2
  6. package/dist/await-terminal/index.js +2 -2
  7. package/dist/batch-window/index.d.ts +4 -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/chart/index.d.ts +217 -0
  12. package/dist/chart/index.js +16 -0
  13. package/dist/chart/index.js.map +1 -0
  14. package/dist/chart/inspect/index.d.ts +85 -0
  15. package/dist/chart/inspect/index.js +5 -0
  16. package/dist/chart/inspect/index.js.map +1 -0
  17. package/dist/chart/inspect/react.d.ts +112 -0
  18. package/dist/chart/inspect/react.js +11 -0
  19. package/dist/chart/inspect/react.js.map +1 -0
  20. package/dist/chart/inspect/styles.css +286 -0
  21. package/dist/chart/lane/index.d.ts +361 -0
  22. package/dist/chart/lane/index.js +9 -0
  23. package/dist/chart/lane/index.js.map +1 -0
  24. package/dist/chart/lane/react.d.ts +83 -0
  25. package/dist/chart/lane/react.js +559 -0
  26. package/dist/chart/lane/react.js.map +1 -0
  27. package/dist/chart/lane/styles.css +498 -0
  28. package/dist/chart/report/index.d.ts +116 -0
  29. package/dist/chart/report/index.js +32 -0
  30. package/dist/chart/report/index.js.map +1 -0
  31. package/dist/{chunk-2UGTDYOK.js → chunk-3JU6657S.js} +3 -3
  32. package/dist/{chunk-2UGTDYOK.js.map → chunk-3JU6657S.js.map} +1 -1
  33. package/dist/{chunk-AZ3NHUPD.js → chunk-4KTWLPL5.js} +3 -3
  34. package/dist/{chunk-AZ3NHUPD.js.map → chunk-4KTWLPL5.js.map} +1 -1
  35. package/dist/{chunk-ZH454CR5.js → chunk-5EHLEUTL.js} +24 -4
  36. package/dist/chunk-5EHLEUTL.js.map +1 -0
  37. package/dist/chunk-5KJKJOFC.js +758 -0
  38. package/dist/chunk-5KJKJOFC.js.map +1 -0
  39. package/dist/{chunk-WF46FABO.js → chunk-7SVIRMC6.js} +3 -3
  40. package/dist/{chunk-WF46FABO.js.map → chunk-7SVIRMC6.js.map} +1 -1
  41. package/dist/{chunk-XMHZ44QC.js → chunk-7V4EVLZA.js} +4 -4
  42. package/dist/{chunk-XMHZ44QC.js.map → chunk-7V4EVLZA.js.map} +1 -1
  43. package/dist/{chunk-IVHQCVFX.js → chunk-A56OR5RF.js} +3 -3
  44. package/dist/{chunk-IVHQCVFX.js.map → chunk-A56OR5RF.js.map} +1 -1
  45. package/dist/{chunk-O7ED34JH.js → chunk-B5VXOFMZ.js} +47 -15
  46. package/dist/chunk-B5VXOFMZ.js.map +1 -0
  47. package/dist/chunk-E6GEDSF4.js +307 -0
  48. package/dist/chunk-E6GEDSF4.js.map +1 -0
  49. package/dist/{chunk-EC6FO42Q.js → chunk-EUF7XOEE.js} +6 -6
  50. package/dist/{chunk-EC6FO42Q.js.map → chunk-EUF7XOEE.js.map} +1 -1
  51. package/dist/{chunk-XOAP3LOT.js → chunk-I5OV65MS.js} +3 -3
  52. package/dist/{chunk-XOAP3LOT.js.map → chunk-I5OV65MS.js.map} +1 -1
  53. package/dist/chunk-JER5O7PQ.js +416 -0
  54. package/dist/chunk-JER5O7PQ.js.map +1 -0
  55. package/dist/{chunk-ASX7PL2K.js → chunk-JGVL3WPL.js} +3 -3
  56. package/dist/{chunk-ASX7PL2K.js.map → chunk-JGVL3WPL.js.map} +1 -1
  57. package/dist/{chunk-S6Y3RNX4.js → chunk-JP5D6GSL.js} +4 -4
  58. package/dist/{chunk-S6Y3RNX4.js.map → chunk-JP5D6GSL.js.map} +1 -1
  59. package/dist/{chunk-ERYY5P6W.js → chunk-ND3DH6KM.js} +3 -3
  60. package/dist/{chunk-ERYY5P6W.js.map → chunk-ND3DH6KM.js.map} +1 -1
  61. package/dist/{chunk-A7USKARI.js → chunk-SUST46KO.js} +3 -3
  62. package/dist/{chunk-A7USKARI.js.map → chunk-SUST46KO.js.map} +1 -1
  63. package/dist/{chunk-2KBEIGYP.js → chunk-TP5UPGLY.js} +3 -3
  64. package/dist/{chunk-2KBEIGYP.js.map → chunk-TP5UPGLY.js.map} +1 -1
  65. package/dist/chunk-UOC2PL46.js +13 -0
  66. package/dist/chunk-UOC2PL46.js.map +1 -0
  67. package/dist/{chunk-66S2KEQQ.js → chunk-WLGO64WC.js} +4 -4
  68. package/dist/{chunk-66S2KEQQ.js.map → chunk-WLGO64WC.js.map} +1 -1
  69. package/dist/chunk-WRAA7GVZ.js +209 -0
  70. package/dist/chunk-WRAA7GVZ.js.map +1 -0
  71. package/dist/chunk-ZCL7SCBK.js +685 -0
  72. package/dist/chunk-ZCL7SCBK.js.map +1 -0
  73. package/dist/chunk-ZD6PNZBK.js +457 -0
  74. package/dist/chunk-ZD6PNZBK.js.map +1 -0
  75. package/dist/{chunk-UV7VCTNC.js → chunk-ZF6WDK2D.js} +7 -7
  76. package/dist/{chunk-UV7VCTNC.js.map → chunk-ZF6WDK2D.js.map} +1 -1
  77. package/dist/{core-CUN5HDKL.d.ts → core-Bjc0bS8j.d.ts} +22 -1
  78. package/dist/deadline/index.d.ts +2 -2
  79. package/dist/deadline/index.js +3 -3
  80. package/dist/devtools/index.js +2 -207
  81. package/dist/devtools/index.js.map +1 -1
  82. package/dist/do/index.d.ts +7 -6
  83. package/dist/do/index.js +10 -10
  84. package/dist/{durable-effects-CXMOi-sp.d.ts → durable-effects-D8SqU_if.d.ts} +1 -1
  85. package/dist/extension/index.d.ts +3 -2
  86. package/dist/extension/index.js +3 -3
  87. package/dist/extension/react.js +3 -3
  88. package/dist/extension/subs/index.d.ts +2 -2
  89. package/dist/fan-out/index.d.ts +3 -2
  90. package/dist/fold-Blbhru48.d.ts +435 -0
  91. package/dist/graph-CcjWZVrd.d.ts +923 -0
  92. package/dist/idempotent-intake/index.d.ts +3 -2
  93. package/dist/index.d.ts +5 -4
  94. package/dist/index.js +2 -2
  95. package/dist/llm-call/index.d.ts +2 -2
  96. package/dist/llm-call/index.js +7 -7
  97. package/dist/{machine-CoWpvp8x.d.ts → machine-0OmPvsy_.d.ts} +1 -1
  98. package/dist/machine-viz/index.d.ts +19 -2
  99. package/dist/machine-viz/index.js +4 -10
  100. package/dist/machine-viz/index.js.map +1 -1
  101. package/dist/mem/index.d.ts +3 -2
  102. package/dist/monitored-run/index.d.ts +4 -3
  103. package/dist/monitored-run/index.js +5 -5
  104. package/dist/node/index.d.ts +3 -2
  105. package/dist/paginated-walk/index.d.ts +2 -2
  106. package/dist/paginated-walk/index.js +7 -7
  107. package/dist/parity/index.d.ts +3 -2
  108. package/dist/parity/index.js +3 -3
  109. package/dist/pbt/arbitraries/index.d.ts +1 -1
  110. package/dist/pbt/index.d.ts +1 -1
  111. package/dist/pbt/index.js +3 -3
  112. package/dist/pbt/runners/index.d.ts +1 -1
  113. package/dist/pbt/runners/index.js +3 -3
  114. package/dist/poller/index.d.ts +28 -7
  115. package/dist/poller/index.js +3 -3
  116. package/dist/poller/index.js.map +1 -1
  117. package/dist/prediction/index.d.ts +1 -1
  118. package/dist/prediction/index.js +2 -2
  119. package/dist/pure/index.d.ts +1 -1
  120. package/dist/pure/index.js +2 -2
  121. package/dist/react/index.d.ts +3 -2
  122. package/dist/react/index.js +2 -2
  123. package/dist/reconciler/index.d.ts +2 -2
  124. package/dist/reconciler/index.js +7 -7
  125. package/dist/recorder/index.d.ts +3 -2
  126. package/dist/reducer-BqyoVyBG.d.ts +447 -0
  127. package/dist/resilient-call/index.d.ts +2 -2
  128. package/dist/resilient-call/index.js +6 -6
  129. package/dist/run-BVeqJDBF.d.ts +713 -0
  130. package/dist/{runtime-types-BD3ZFfdw.d.ts → runtime-types-Bxc637bp.d.ts} +53 -2
  131. package/dist/saga/index.d.ts +3 -2
  132. package/dist/samples-DCt6nF8H.d.ts +59 -0
  133. package/dist/snapshot/index.d.ts +1 -1
  134. package/dist/snapshot/index.js +3 -3
  135. package/dist/subs/index.d.ts +4 -3
  136. package/dist/subs/index.js +3 -3
  137. package/dist/testing/index.d.ts +3 -2
  138. package/dist/testing/index.js +2 -2
  139. package/dist/throttled-input/index.d.ts +2 -2
  140. package/dist/throttled-input/index.js +6 -6
  141. package/dist/token-refresh/index.d.ts +1 -1
  142. package/dist/token-refresh/index.js +3 -3
  143. package/dist/trace-replay/index.d.ts +3 -2
  144. package/dist/trace-replay/index.js +3 -3
  145. package/dist/{types-CjAkI83U.d.ts → types-D7u9DkH7.d.ts} +1 -1
  146. package/dist/with-deadline/index.d.ts +1 -1
  147. package/dist/with-deadline/index.js +2 -2
  148. package/dist/with-resilience/index.d.ts +2 -2
  149. package/dist/with-resilience/index.js +6 -6
  150. package/dist/with-telemetry/index.d.ts +1 -1
  151. package/dist/with-telemetry/index.js +2 -2
  152. package/dist/work-queue/adapter.d.ts +3 -2
  153. package/dist/work-queue/index.d.ts +3 -2
  154. package/dist/work-queue/ops.d.ts +3 -2
  155. package/dist/workflow/index.d.ts +3 -3
  156. package/package.json +31 -1
  157. package/dist/chunk-O7ED34JH.js.map +0 -1
  158. package/dist/chunk-ZH454CR5.js.map +0 -1
@@ -0,0 +1,559 @@
1
+ import { useInspectorRuntime } from '../../chunk-JER5O7PQ.js';
2
+ import { replayFeed, runLane, liveFeed, laneView } from '../../chunk-ZCL7SCBK.js';
3
+ import '../../chunk-ZD6PNZBK.js';
4
+ import '../../chunk-5KJKJOFC.js';
5
+ import '../../chunk-E6GEDSF4.js';
6
+ import '../../chunk-UOC2PL46.js';
7
+ import '../../chunk-MUUROGIH.js';
8
+ import '../../chunk-WRAA7GVZ.js';
9
+ import '../../chunk-EWJP3YYP.js';
10
+ import { replay } from '../../chunk-5EHLEUTL.js';
11
+ import '../../chunk-B5VXOFMZ.js';
12
+ import { useMemo, useReducer, useEffect, useRef, useState } from 'react';
13
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
14
+
15
+ function LaneView(props) {
16
+ const feed = useMemo(
17
+ () => replayFeed(props.lane, props.log),
18
+ [props.lane, props.log]
19
+ );
20
+ return /* @__PURE__ */ jsx(
21
+ LanePanels,
22
+ {
23
+ feed,
24
+ title: props.title,
25
+ className: props.className,
26
+ send: null
27
+ }
28
+ );
29
+ }
30
+ function LiveLaneView(props) {
31
+ const { lane, hands, ctx } = props;
32
+ const [epoch, reset] = useReducer((n) => n + 1, 0);
33
+ const machine = useMemo(
34
+ () => (
35
+ // The one cast, at the construction boundary — `runLane` returns exactly
36
+ // the `init` and `update` a `Machine` is made of, over the lane's own
37
+ // derivations, and `Machine` wants them under the caller's names.
38
+ { ...runLane(lane, hands) }
39
+ ),
40
+ [lane, hands]
41
+ );
42
+ const { rt, rec } = useInspectorRuntime(machine, ctx, epoch);
43
+ if (rt === null) {
44
+ return /* @__PURE__ */ jsx("div", { className: containerClass(props.className), children: /* @__PURE__ */ jsx("div", { className: "tea-lv-boot", children: "booting\u2026" }) });
45
+ }
46
+ return /* @__PURE__ */ jsx(
47
+ LiveLanePanels,
48
+ {
49
+ lane,
50
+ hands,
51
+ samples: props.samples,
52
+ machine,
53
+ runtime: rt,
54
+ rec,
55
+ ctx,
56
+ title: props.title,
57
+ className: props.className,
58
+ onReset: reset
59
+ },
60
+ epoch
61
+ );
62
+ }
63
+ function LiveLanePanels({
64
+ lane,
65
+ hands,
66
+ samples,
67
+ machine,
68
+ runtime,
69
+ rec,
70
+ ctx,
71
+ title,
72
+ className,
73
+ onReset
74
+ }) {
75
+ const [, bump] = useReducer((n) => n + 1, 0);
76
+ useEffect(() => runtime.subscribe(bump), [runtime]);
77
+ const live = runtime.getState();
78
+ const trace = safeDump(rec, live);
79
+ const tape = useRef(trace);
80
+ tape.current = trace;
81
+ const now = useRef(live);
82
+ now.current = live;
83
+ const total = trace.msgs.length;
84
+ const feed = useMemo(
85
+ () => liveFeed(lane, {
86
+ regionsAt: (n) => regionsOf(
87
+ replayPrefix(machine, tape.current, ctx, n, now.current),
88
+ // a fold that threw leaves the live regions as the honest answer
89
+ regionsOf(now.current, {})
90
+ ),
91
+ msgs: tape.current.msgs,
92
+ optsFor: (task) => ({
93
+ ...hands[task]?.parts === void 0 ? {} : { parts: hands[task]?.parts },
94
+ ...samples?.[task] === void 0 ? {} : { samples: samples[task] }
95
+ })
96
+ }),
97
+ [lane, hands, samples, machine, ctx, total]
98
+ );
99
+ return /* @__PURE__ */ jsx(
100
+ LanePanels,
101
+ {
102
+ feed,
103
+ title,
104
+ className,
105
+ send: (msg) => runtime.dispatch(msg),
106
+ onReset
107
+ }
108
+ );
109
+ }
110
+ function containerClass(extra) {
111
+ return `tea-lv${extra ? ` ${extra}` : ""}`;
112
+ }
113
+ var Sep = () => /* @__PURE__ */ jsx("span", { className: "tea-lv-sep", children: " \xB7 " });
114
+ var NO_SEND = "this view was given no way to dispatch";
115
+ function endingWord(view) {
116
+ if (view.terminal === null) return "still running";
117
+ return view.tripped.length > 0 ? "stopped here" : "finished";
118
+ }
119
+ function LanePanels({
120
+ feed,
121
+ title,
122
+ className,
123
+ send,
124
+ onReset
125
+ }) {
126
+ const [at, setAt] = useState(null);
127
+ const cursor = at === null ? feed.total : Math.min(at, feed.total);
128
+ const view = laneView(feed, cursor, title);
129
+ const blocked = view.scrubbed ? `you are looking at step ${view.cursor} of ${view.total}. A button dispatches into the lane as it is NOW \u2014 press \u201Cnow\u201D to get them back.` : view.noDispatch?.why;
130
+ const page = {
131
+ dispatch: send !== null && blocked === void 0 ? { send } : { blocked: blocked ?? NO_SEND },
132
+ foldControls: view.noDispatch !== void 0,
133
+ ended: view.terminal !== null
134
+ };
135
+ return /* @__PURE__ */ jsxs("div", { className: containerClass(className), "data-source": view.source, children: [
136
+ /* @__PURE__ */ jsxs("header", { className: "tea-lv-head", children: [
137
+ /* @__PURE__ */ jsx("span", { className: "tea-lv-title", children: view.title }),
138
+ /* @__PURE__ */ jsx(Sep, {}),
139
+ /* @__PURE__ */ jsx("span", { className: "tea-lv-src", "data-source": view.source, children: view.source }),
140
+ /* @__PURE__ */ jsx(Sep, {}),
141
+ /* @__PURE__ */ jsxs("span", { className: "tea-lv-now", "data-lane-status": view.status, children: [
142
+ view.terminal === null ? /* @__PURE__ */ jsx("span", { className: "tea-lv-phase", children: view.activePhase ?? "\u2014" }) : /* @__PURE__ */ jsx("span", { className: "tea-lv-terminal", children: view.terminal }),
143
+ /* @__PURE__ */ jsx(Sep, {}),
144
+ /* @__PURE__ */ jsx("span", { className: "tea-lv-status", children: endingWord(view) })
145
+ ] }),
146
+ view.scrubbed ? /* @__PURE__ */ jsxs(Fragment, { children: [
147
+ /* @__PURE__ */ jsx(Sep, {}),
148
+ /* @__PURE__ */ jsxs("span", { className: "tea-lv-warn", children: [
149
+ "time-travelling \u2014 step ",
150
+ view.cursor,
151
+ " of ",
152
+ view.total
153
+ ] })
154
+ ] }) : null
155
+ ] }),
156
+ /* @__PURE__ */ jsxs("p", { className: "tea-lv-lede", children: [
157
+ view.phases.length === 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
158
+ "A ",
159
+ /* @__PURE__ */ jsx("b", { children: "lane" }),
160
+ " is a run of phases \u2014 this one has a single phase."
161
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
162
+ "A ",
163
+ /* @__PURE__ */ jsx("b", { children: "lane" }),
164
+ " is ",
165
+ view.phases.length,
166
+ " phases that run one after another."
167
+ ] }),
168
+ " ",
169
+ "Each phase holds tasks that run ",
170
+ /* @__PURE__ */ jsx("i", { children: "at the same time" }),
171
+ ", and every task is one state machine \u2014 the diagram below it is that machine, with the state it is in right now lit up. A phase finishes when all of its tasks finish;",
172
+ " ",
173
+ view.terminal === null ? /* @__PURE__ */ jsxs(Fragment, { children: [
174
+ "right now ",
175
+ /* @__PURE__ */ jsx("b", { children: view.activePhase }),
176
+ " is the one running."
177
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
178
+ "this lane has ended, on ",
179
+ /* @__PURE__ */ jsx("b", { children: view.terminal }),
180
+ "."
181
+ ] })
182
+ ] }),
183
+ "blocked" in page.dispatch ? /* @__PURE__ */ jsx("p", { className: "tea-lv-unavailable", "data-unavailable": "dispatch", children: page.dispatch.blocked }) : null,
184
+ /* @__PURE__ */ jsx(StuckPanel, { view }),
185
+ view.phases.map((phase) => /* @__PURE__ */ jsx(PhasePanel, { phase, page }, phase.name)),
186
+ /* @__PURE__ */ jsx(
187
+ TimelinePanel,
188
+ {
189
+ view,
190
+ onScrub: setAt,
191
+ onLive: () => setAt(null),
192
+ onReset
193
+ }
194
+ )
195
+ ] });
196
+ }
197
+ function StuckPanel({ view }) {
198
+ return /* @__PURE__ */ jsxs("section", { className: "tea-lv-panel tea-lv-stuck", children: [
199
+ /* @__PURE__ */ jsxs("h3", { className: "tea-lv-h", children: [
200
+ "1 \xB7 is anything blocked?",
201
+ /* @__PURE__ */ jsx(Sep, {}),
202
+ /* @__PURE__ */ jsx("span", { className: "tea-lv-hint", children: "a task nothing can move until someone acts" })
203
+ ] }),
204
+ view.stuck.length === 0 ? (
205
+ // Said, never left blank: "nothing is stuck" is an answer, and an empty
206
+ // panel is the reader wondering whether the question was asked.
207
+ /* @__PURE__ */ jsx("p", { className: "tea-lv-none", children: "nothing is stuck \u2014 every task can still move" })
208
+ ) : /* @__PURE__ */ jsx("ul", { className: "tea-lv-stucklist", children: view.stuck.map((s) => /* @__PURE__ */ jsxs("li", { "data-stuck": s.reason.kind, "data-task": s.task, children: [
209
+ /* @__PURE__ */ jsx("b", { children: s.task }),
210
+ " ",
211
+ /* @__PURE__ */ jsxs("span", { className: "tea-lv-muted", children: [
212
+ "(",
213
+ s.phase,
214
+ ")"
215
+ ] }),
216
+ " ",
217
+ "\u2014 ",
218
+ stuckLine(s.reason)
219
+ ] }, s.task)) }),
220
+ view.tripped.length === 0 ? null : /* @__PURE__ */ jsxs("p", { className: "tea-lv-tripped", children: [
221
+ "tripped: ",
222
+ view.tripped.join(", ")
223
+ ] })
224
+ ] });
225
+ }
226
+ function stuckLine(reason) {
227
+ if (reason === null) return "";
228
+ switch (reason.kind) {
229
+ case "tripped":
230
+ return `landed on the error final \`${reason.state}\` \u2014 as finished as a shipped task, and lost`;
231
+ case "dead-end":
232
+ return `\`${reason.state}\` routes no event and is not a final \u2014 nobody can move it`;
233
+ case "budget-spent":
234
+ return `\`${reason.state}\` has spent its retry budget \u2014 the next \`${reason.event}\` is \`${reason.landsOn}\`, not a retry`;
235
+ case "awaiting-world":
236
+ return `\`${reason.state}\` moves only when ${reason.roles.join(" or ")} sends ${reason.events.map((e) => `\`${e}\``).join(" or ")} \u2014 no cmd or sub can arrive here`;
237
+ }
238
+ }
239
+ function phaseCount(phase) {
240
+ const n = phase.tasks.length;
241
+ const tasks = `${n} task${n === 1 ? "" : "s"}`;
242
+ switch (phase.standing) {
243
+ case "active":
244
+ return n === 1 ? `${tasks}, running` : `${tasks}, running together`;
245
+ case "complete":
246
+ return `${tasks}, all finished`;
247
+ case "tripped":
248
+ return n === 1 ? `${tasks}, stopped on an error` : `${tasks} \u2014 ${phase.tripped.length} stopped on an error`;
249
+ case "waiting":
250
+ return `${tasks}, not started`;
251
+ }
252
+ }
253
+ function PhasePanel({
254
+ phase,
255
+ page
256
+ }) {
257
+ const count = phaseCount(phase);
258
+ return /* @__PURE__ */ jsxs(
259
+ "section",
260
+ {
261
+ className: `tea-lv-panel tea-lv-phase-${phase.standing}`,
262
+ "data-phase": phase.name,
263
+ "data-standing": phase.standing,
264
+ children: [
265
+ /* @__PURE__ */ jsxs("h3", { className: "tea-lv-h", children: [
266
+ phase.index === 0 ? "2 \xB7 " : "",
267
+ phase.name,
268
+ " ",
269
+ /* @__PURE__ */ jsx("span", { className: "tea-lv-standing", children: phase.standing }),
270
+ /* @__PURE__ */ jsx(Sep, {}),
271
+ /* @__PURE__ */ jsx("span", { className: "tea-lv-muted", children: count })
272
+ ] }),
273
+ /* @__PURE__ */ jsx("ul", { className: "tea-lv-chips", children: phase.tasks.map((task) => /* @__PURE__ */ jsxs(
274
+ "li",
275
+ {
276
+ className: "tea-lv-chip",
277
+ "data-task": task.task,
278
+ "data-state": task.state,
279
+ "data-end": String(task.endPolarity),
280
+ children: [
281
+ /* @__PURE__ */ jsx("b", { children: task.task }),
282
+ " = ",
283
+ task.state,
284
+ task.endPolarity === "error" ? " (tripped)" : ""
285
+ ]
286
+ },
287
+ task.task
288
+ )) }),
289
+ phase.tasks.map((task) => /* @__PURE__ */ jsx(
290
+ TaskPanel,
291
+ {
292
+ task,
293
+ expanded: phase.expanded.includes(task.task),
294
+ alone: phase.tasks.length === 1,
295
+ page
296
+ },
297
+ task.task
298
+ ))
299
+ ]
300
+ }
301
+ );
302
+ }
303
+ function waitingLine(task, alone, ended) {
304
+ if (task.waitingOn !== null) return task.waitingOn;
305
+ if (task.endPolarity !== "error") return "nothing \u2014 this task is final";
306
+ const landed = `nothing \u2014 this task landed on the error final \`${task.state}\``;
307
+ if (ended) return `${landed}, which is what stopped the lane`;
308
+ if (alone) return `${landed}, and that trips \`${task.phase}\``;
309
+ return `${landed}, and \`${task.phase}\` will trip the lane once its siblings finish`;
310
+ }
311
+ function TaskPanel({
312
+ task,
313
+ expanded,
314
+ alone,
315
+ page
316
+ }) {
317
+ const [opened, setOpened] = useState(false);
318
+ const showDiagram = expanded || opened;
319
+ const waiting = waitingLine(task, alone, page.ended);
320
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
321
+ /* @__PURE__ */ jsxs("p", { className: "tea-lv-waiting", children: [
322
+ "waiting on: ",
323
+ waiting
324
+ ] }),
325
+ /* @__PURE__ */ jsx(Budget, { task }),
326
+ page.foldControls ? /* @__PURE__ */ jsxs("details", { className: "tea-lv-accepts", children: [
327
+ /* @__PURE__ */ jsxs("summary", { children: [
328
+ "which events this state accepts (",
329
+ task.controls.filter((c) => !c.refused).length,
330
+ " of",
331
+ " ",
332
+ task.controls.length,
333
+ ")"
334
+ ] }),
335
+ /* @__PURE__ */ jsx("div", { className: "tea-lv-controls", children: task.controls.map((control) => /* @__PURE__ */ jsx(
336
+ Control,
337
+ {
338
+ control,
339
+ dispatch: page.dispatch
340
+ },
341
+ control.event
342
+ )) })
343
+ ] }) : /* @__PURE__ */ jsx("div", { className: "tea-lv-controls", children: task.controls.map((control) => /* @__PURE__ */ jsx(
344
+ Control,
345
+ {
346
+ control,
347
+ dispatch: page.dispatch
348
+ },
349
+ control.event
350
+ )) }),
351
+ showDiagram ? /* @__PURE__ */ jsx("pre", { className: "mermaid tea-lv-mermaid", children: task.diagram }, task.diagram) : null
352
+ ] });
353
+ if (!expanded) {
354
+ return (
355
+ /* The chip row above already says `task = state` for every task in the
356
+ phase. A collapsed disclosure that repeats it lists each task twice,
357
+ adjacent — which reads as a bug and was one, found by rendering a real
358
+ eight-task phase rather than by any assertion. So the summary says what
359
+ the chip cannot: that there is more here, and whether it has begun. */
360
+ /* @__PURE__ */ jsxs(
361
+ "details",
362
+ {
363
+ className: "tea-lv-task tea-lv-collapsed",
364
+ "data-task": task.task,
365
+ onToggle: (e) => setOpened(e.currentTarget.open),
366
+ children: [
367
+ /* @__PURE__ */ jsxs("summary", { children: [
368
+ /* @__PURE__ */ jsx("b", { children: task.task }),
369
+ /* @__PURE__ */ jsx(Sep, {}),
370
+ /* @__PURE__ */ jsx("span", { className: "tea-lv-muted", children: task.moved ? "details" : `still at ${task.state}` })
371
+ ] }),
372
+ body
373
+ ]
374
+ }
375
+ )
376
+ );
377
+ }
378
+ return /* @__PURE__ */ jsxs("div", { className: "tea-lv-task", "data-task": task.task, "data-expanded": "true", children: [
379
+ /* @__PURE__ */ jsxs("h4", { className: "tea-lv-taskh", children: [
380
+ /* @__PURE__ */ jsx("b", { children: task.task }),
381
+ " \u2014 ",
382
+ /* @__PURE__ */ jsx("span", { className: "tea-lv-state", children: task.state }),
383
+ task.endPolarity === "error" ? /* @__PURE__ */ jsxs(Fragment, { children: [
384
+ " ",
385
+ /* @__PURE__ */ jsx("span", { className: "tea-lv-badge", children: "tripped" })
386
+ ] }) : null,
387
+ task.was === void 0 ? null : /* @__PURE__ */ jsxs("span", { className: "tea-lv-muted", children: [
388
+ " \xB7 resumes to ",
389
+ task.was
390
+ ] })
391
+ ] }),
392
+ body
393
+ ] });
394
+ }
395
+ function Budget({ task }) {
396
+ if ("answerable" in task.budget) {
397
+ return /* @__PURE__ */ jsxs(
398
+ "p",
399
+ {
400
+ className: "tea-lv-unavailable",
401
+ "data-unavailable": task.budget.question,
402
+ title: task.budget.why,
403
+ children: [
404
+ "retries: not available \u2014 ",
405
+ task.budget.why
406
+ ]
407
+ }
408
+ );
409
+ }
410
+ if (task.budget.retries === 0) return null;
411
+ return /* @__PURE__ */ jsxs("p", { className: "tea-lv-retries", "data-retries": task.budget.retries, children: [
412
+ "retries: ",
413
+ task.budget.retries,
414
+ "/",
415
+ task.budget.maxRetries,
416
+ task.budget.retries >= task.budget.maxRetries ? " \u2014 spent" : ""
417
+ ] });
418
+ }
419
+ function Control({
420
+ control,
421
+ dispatch
422
+ }) {
423
+ const unsendable = "answerable" in control.send;
424
+ const msg = unsendable ? void 0 : control.send;
425
+ const why = unsendable ? control.send.why : void 0;
426
+ const blocked = "blocked" in dispatch ? dispatch.blocked : void 0;
427
+ const sendable = msg !== void 0 && blocked === void 0;
428
+ return /* @__PURE__ */ jsxs(
429
+ "div",
430
+ {
431
+ className: `tea-lv-ev tea-lv-ev-${control.kind}`,
432
+ "data-event": control.event,
433
+ "data-task": control.task,
434
+ "data-status": control.refused ? "refused" : "legal",
435
+ "data-sendable": String(sendable),
436
+ children: [
437
+ /* @__PURE__ */ jsx(
438
+ "button",
439
+ {
440
+ type: "button",
441
+ className: "tea-lv-btn",
442
+ disabled: !sendable,
443
+ title: control.why ?? why ?? blocked ?? control.outcome,
444
+ onClick: () => {
445
+ if (msg !== void 0 && "send" in dispatch) dispatch.send(msg);
446
+ },
447
+ children: control.event
448
+ }
449
+ ),
450
+ /* @__PURE__ */ jsx("span", { className: "tea-lv-to", children: control.refused ? control.why : control.outcome })
451
+ ]
452
+ }
453
+ );
454
+ }
455
+ function TimelinePanel({
456
+ view,
457
+ onScrub,
458
+ onLive,
459
+ onReset
460
+ }) {
461
+ const clockless = "answerable" in view.clock;
462
+ return /* @__PURE__ */ jsxs("section", { className: "tea-lv-panel tea-lv-travel", children: [
463
+ /* @__PURE__ */ jsxs("h3", { className: "tea-lv-h", children: [
464
+ "3 \xB7 what happened, step by step",
465
+ /* @__PURE__ */ jsx(Sep, {}),
466
+ /* @__PURE__ */ jsx("span", { className: "tea-lv-hint", children: "drag to rewind \u2014 everything above moves with it" })
467
+ ] }),
468
+ /* @__PURE__ */ jsxs("div", { className: "tea-lv-scrub", children: [
469
+ /* @__PURE__ */ jsx(
470
+ "input",
471
+ {
472
+ type: "range",
473
+ min: 0,
474
+ max: view.total,
475
+ value: view.cursor,
476
+ "aria-label": "step",
477
+ onChange: (e) => onScrub(Number(e.target.value))
478
+ }
479
+ ),
480
+ /* @__PURE__ */ jsxs("span", { className: "tea-lv-step", children: [
481
+ view.cursor,
482
+ " / ",
483
+ view.total
484
+ ] }),
485
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: onLive, disabled: !view.scrubbed, children: "now" }),
486
+ onReset === void 0 ? null : /* @__PURE__ */ jsx("button", { type: "button", onClick: onReset, children: "reset" })
487
+ ] }),
488
+ clockless ? /* @__PURE__ */ jsxs(
489
+ "p",
490
+ {
491
+ className: "tea-lv-unavailable",
492
+ "data-unavailable": "clock",
493
+ title: view.clock.why,
494
+ children: [
495
+ "when: not available \u2014 ",
496
+ view.clock.why
497
+ ]
498
+ }
499
+ ) : null,
500
+ view.steps.length === 0 ? /* @__PURE__ */ jsx("p", { className: "tea-lv-none", children: "no steps yet \u2014 every task is where it booted" }) : /* @__PURE__ */ jsxs("table", { className: "tea-lv-steps", children: [
501
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
502
+ /* @__PURE__ */ jsx("th", { children: "#" }),
503
+ clockless ? null : /* @__PURE__ */ jsx("th", { children: "at" }),
504
+ /* @__PURE__ */ jsx("th", { children: "task" }),
505
+ /* @__PURE__ */ jsx("th", { children: "event" }),
506
+ /* @__PURE__ */ jsx("th", { children: "from \u2192 to" })
507
+ ] }) }),
508
+ /* @__PURE__ */ jsx("tbody", { children: view.steps.map((step) => /* @__PURE__ */ jsxs(
509
+ "tr",
510
+ {
511
+ "data-step": step.index,
512
+ "data-refused": step.refused ? "true" : void 0,
513
+ children: [
514
+ /* @__PURE__ */ jsx("td", { children: step.index + 1 }),
515
+ clockless ? null : /* @__PURE__ */ jsx("td", { children: view.clock[step.index] }),
516
+ /* @__PURE__ */ jsx("td", { children: step.task }),
517
+ /* @__PURE__ */ jsx("td", { children: step.event }),
518
+ /* @__PURE__ */ jsx("td", { children: step.refused ? /* @__PURE__ */ jsxs(Fragment, { children: [
519
+ step.from,
520
+ " \u2014 refused, nothing moved"
521
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
522
+ step.from,
523
+ " \u2192 ",
524
+ step.to
525
+ ] }) })
526
+ ]
527
+ },
528
+ step.index
529
+ )) })
530
+ ] })
531
+ ] });
532
+ }
533
+ function regionsOf(state, fallback) {
534
+ if (typeof state !== "object" || state === null) return fallback;
535
+ const regions = state.regions;
536
+ return typeof regions === "object" && regions !== null ? regions : fallback;
537
+ }
538
+ function safeDump(rec, live) {
539
+ try {
540
+ return rec.dump();
541
+ } catch {
542
+ return { loaded: null, msgs: [], finalState: live };
543
+ }
544
+ }
545
+ function replayPrefix(machine, trace, ctx, n, live) {
546
+ try {
547
+ return replay(machine, {
548
+ msgs: trace.msgs.slice(0, n),
549
+ ctx,
550
+ loaded: trace.loaded
551
+ }).state;
552
+ } catch {
553
+ return live;
554
+ }
555
+ }
556
+
557
+ export { LaneView, LiveLaneView };
558
+ //# sourceMappingURL=react.js.map
559
+ //# sourceMappingURL=react.js.map