footprintjs 4.16.0 → 4.17.2

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 (188) hide show
  1. package/AGENTS.md +567 -82
  2. package/CLAUDE.md +57 -0
  3. package/README.md +2 -0
  4. package/dist/advanced.js +4 -2
  5. package/dist/detach.js +78 -0
  6. package/dist/esm/advanced.js +2 -1
  7. package/dist/esm/detach.js +57 -0
  8. package/dist/esm/lib/builder/FlowChartBuilder.js +171 -61
  9. package/dist/esm/lib/contract/openapi.js +4 -5
  10. package/dist/esm/lib/contract/schema.js +115 -4
  11. package/dist/esm/lib/decide/decide.js +4 -5
  12. package/dist/esm/lib/decide/evidence.js +3 -2
  13. package/dist/esm/lib/detach/drivers/immediate.js +66 -0
  14. package/dist/esm/lib/detach/drivers/microtaskBatch.js +113 -0
  15. package/dist/esm/lib/detach/drivers/sendBeacon.js +78 -0
  16. package/dist/esm/lib/detach/drivers/setImmediate.js +81 -0
  17. package/dist/esm/lib/detach/drivers/setTimeout.js +69 -0
  18. package/dist/esm/lib/detach/drivers/workerThread.js +117 -0
  19. package/dist/esm/lib/detach/flush.js +91 -0
  20. package/dist/esm/lib/detach/handle.js +134 -0
  21. package/dist/esm/lib/detach/registry.js +97 -0
  22. package/dist/esm/lib/detach/runChild.js +40 -0
  23. package/dist/esm/lib/detach/spawn.js +86 -0
  24. package/dist/esm/lib/detach/types.js +37 -0
  25. package/dist/esm/lib/engine/errors/errorInfo.js +4 -4
  26. package/dist/esm/lib/engine/graph/StageNode.js +2 -2
  27. package/dist/esm/lib/engine/handlers/ChildrenExecutor.js +9 -8
  28. package/dist/esm/lib/engine/handlers/ContinuationResolver.js +12 -9
  29. package/dist/esm/lib/engine/handlers/DeciderHandler.js +7 -8
  30. package/dist/esm/lib/engine/handlers/ExtractorRunner.js +14 -8
  31. package/dist/esm/lib/engine/handlers/NodeResolver.js +5 -3
  32. package/dist/esm/lib/engine/handlers/RuntimeStructureManager.js +11 -14
  33. package/dist/esm/lib/engine/handlers/SelectorHandler.js +9 -9
  34. package/dist/esm/lib/engine/handlers/StageRunner.js +9 -11
  35. package/dist/esm/lib/engine/handlers/SubflowExecutor.js +13 -12
  36. package/dist/esm/lib/engine/handlers/SubflowInputMapper.js +4 -4
  37. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +85 -96
  38. package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.js +18 -36
  39. package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.js +6 -5
  40. package/dist/esm/lib/engine/narrative/recorders/AdaptiveNarrativeFlowRecorder.js +7 -6
  41. package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.js +10 -10
  42. package/dist/esm/lib/engine/narrative/recorders/MilestoneNarrativeFlowRecorder.js +5 -3
  43. package/dist/esm/lib/engine/narrative/recorders/ProgressiveNarrativeFlowRecorder.js +4 -3
  44. package/dist/esm/lib/engine/narrative/recorders/RLENarrativeFlowRecorder.js +4 -4
  45. package/dist/esm/lib/engine/narrative/recorders/SeparateNarrativeFlowRecorder.js +5 -6
  46. package/dist/esm/lib/engine/narrative/recorders/SilentNarrativeFlowRecorder.js +5 -6
  47. package/dist/esm/lib/engine/narrative/recorders/WindowedNarrativeFlowRecorder.js +5 -3
  48. package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +97 -71
  49. package/dist/esm/lib/memory/DiagnosticCollector.js +6 -8
  50. package/dist/esm/lib/memory/EventLog.js +5 -3
  51. package/dist/esm/lib/memory/SharedMemory.js +3 -2
  52. package/dist/esm/lib/memory/StageContext.js +44 -14
  53. package/dist/esm/lib/memory/TransactionBuffer.js +9 -8
  54. package/dist/esm/lib/memory/backtrack.js +3 -4
  55. package/dist/esm/lib/memory/commitLogUtils.js +2 -2
  56. package/dist/esm/lib/memory/utils.js +2 -3
  57. package/dist/esm/lib/pause/types.js +33 -14
  58. package/dist/esm/lib/reactive/createTypedScope.js +10 -8
  59. package/dist/esm/lib/reactive/types.js +3 -1
  60. package/dist/esm/lib/recorder/BoundaryStateTracker.js +263 -0
  61. package/dist/esm/lib/recorder/CompositeRecorder.js +3 -1
  62. package/dist/esm/lib/recorder/InOutRecorder.js +5 -6
  63. package/dist/esm/lib/recorder/KeyedRecorder.js +2 -4
  64. package/dist/esm/lib/recorder/QualityRecorder.js +15 -14
  65. package/dist/esm/lib/recorder/SequenceRecorder.js +11 -12
  66. package/dist/esm/lib/recorder/TopologyRecorder.js +36 -40
  67. package/dist/esm/lib/recorder/index.js +2 -1
  68. package/dist/esm/lib/recorder/qualityTrace.js +4 -5
  69. package/dist/esm/lib/runner/ExecutionRuntime.js +20 -4
  70. package/dist/esm/lib/runner/FlowChartExecutor.js +99 -55
  71. package/dist/esm/lib/runner/RunContext.js +5 -3
  72. package/dist/esm/lib/runner/RunnableChart.js +7 -9
  73. package/dist/esm/lib/runner/getSubtreeSnapshot.js +4 -5
  74. package/dist/esm/lib/schema/errors.js +4 -3
  75. package/dist/esm/lib/schema/validate.js +4 -5
  76. package/dist/esm/lib/scope/ScopeFacade.js +52 -35
  77. package/dist/esm/lib/scope/providers/baseStateCompatible.js +9 -9
  78. package/dist/esm/lib/scope/providers/guards.js +2 -2
  79. package/dist/esm/lib/scope/recorders/DebugRecorder.js +9 -7
  80. package/dist/esm/lib/scope/recorders/MetricRecorder.js +10 -8
  81. package/dist/esm/lib/scope/state/zod/defineScopeFromZod.js +2 -3
  82. package/dist/esm/lib/scope/state/zod/resolver.js +2 -3
  83. package/dist/esm/lib/scope/state/zod/scopeFactory.js +16 -20
  84. package/dist/esm/lib/scope/state/zod/utils/validateHelper.js +57 -14
  85. package/dist/esm/trace.js +4 -1
  86. package/dist/lib/builder/FlowChartBuilder.js +171 -61
  87. package/dist/lib/contract/openapi.js +4 -5
  88. package/dist/lib/contract/schema.js +115 -4
  89. package/dist/lib/decide/decide.js +4 -5
  90. package/dist/lib/decide/evidence.js +3 -2
  91. package/dist/lib/detach/drivers/immediate.js +70 -0
  92. package/dist/lib/detach/drivers/microtaskBatch.js +117 -0
  93. package/dist/lib/detach/drivers/sendBeacon.js +82 -0
  94. package/dist/lib/detach/drivers/setImmediate.js +85 -0
  95. package/dist/lib/detach/drivers/setTimeout.js +73 -0
  96. package/dist/lib/detach/drivers/workerThread.js +121 -0
  97. package/dist/lib/detach/flush.js +95 -0
  98. package/dist/lib/detach/handle.js +140 -0
  99. package/dist/lib/detach/registry.js +106 -0
  100. package/dist/lib/detach/runChild.js +67 -0
  101. package/dist/lib/detach/spawn.js +92 -0
  102. package/dist/lib/detach/types.js +38 -0
  103. package/dist/lib/engine/errors/errorInfo.js +4 -4
  104. package/dist/lib/engine/graph/StageNode.js +2 -2
  105. package/dist/lib/engine/handlers/ChildrenExecutor.js +9 -8
  106. package/dist/lib/engine/handlers/ContinuationResolver.js +12 -9
  107. package/dist/lib/engine/handlers/DeciderHandler.js +7 -8
  108. package/dist/lib/engine/handlers/ExtractorRunner.js +14 -8
  109. package/dist/lib/engine/handlers/NodeResolver.js +5 -3
  110. package/dist/lib/engine/handlers/RuntimeStructureManager.js +11 -14
  111. package/dist/lib/engine/handlers/SelectorHandler.js +9 -9
  112. package/dist/lib/engine/handlers/StageRunner.js +9 -11
  113. package/dist/lib/engine/handlers/SubflowExecutor.js +13 -12
  114. package/dist/lib/engine/handlers/SubflowInputMapper.js +4 -4
  115. package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +85 -96
  116. package/dist/lib/engine/narrative/FlowRecorderDispatcher.js +18 -36
  117. package/dist/lib/engine/narrative/NarrativeFlowRecorder.js +6 -5
  118. package/dist/lib/engine/narrative/recorders/AdaptiveNarrativeFlowRecorder.js +7 -6
  119. package/dist/lib/engine/narrative/recorders/ManifestFlowRecorder.js +10 -10
  120. package/dist/lib/engine/narrative/recorders/MilestoneNarrativeFlowRecorder.js +5 -3
  121. package/dist/lib/engine/narrative/recorders/ProgressiveNarrativeFlowRecorder.js +4 -3
  122. package/dist/lib/engine/narrative/recorders/RLENarrativeFlowRecorder.js +4 -4
  123. package/dist/lib/engine/narrative/recorders/SeparateNarrativeFlowRecorder.js +5 -6
  124. package/dist/lib/engine/narrative/recorders/SilentNarrativeFlowRecorder.js +5 -6
  125. package/dist/lib/engine/narrative/recorders/WindowedNarrativeFlowRecorder.js +5 -3
  126. package/dist/lib/engine/traversal/FlowchartTraverser.js +97 -71
  127. package/dist/lib/memory/DiagnosticCollector.js +6 -8
  128. package/dist/lib/memory/EventLog.js +5 -3
  129. package/dist/lib/memory/SharedMemory.js +3 -2
  130. package/dist/lib/memory/StageContext.js +44 -14
  131. package/dist/lib/memory/TransactionBuffer.js +9 -8
  132. package/dist/lib/memory/backtrack.js +3 -4
  133. package/dist/lib/memory/commitLogUtils.js +2 -2
  134. package/dist/lib/memory/utils.js +2 -3
  135. package/dist/lib/pause/types.js +33 -14
  136. package/dist/lib/reactive/createTypedScope.js +10 -8
  137. package/dist/lib/reactive/types.js +3 -1
  138. package/dist/lib/recorder/BoundaryStateTracker.js +267 -0
  139. package/dist/lib/recorder/CompositeRecorder.js +3 -1
  140. package/dist/lib/recorder/InOutRecorder.js +5 -6
  141. package/dist/lib/recorder/KeyedRecorder.js +2 -4
  142. package/dist/lib/recorder/QualityRecorder.js +15 -14
  143. package/dist/lib/recorder/SequenceRecorder.js +11 -12
  144. package/dist/lib/recorder/TopologyRecorder.js +36 -40
  145. package/dist/lib/recorder/index.js +4 -2
  146. package/dist/lib/recorder/qualityTrace.js +4 -5
  147. package/dist/lib/runner/ExecutionRuntime.js +20 -4
  148. package/dist/lib/runner/FlowChartExecutor.js +99 -55
  149. package/dist/lib/runner/RunContext.js +5 -3
  150. package/dist/lib/runner/RunnableChart.js +7 -9
  151. package/dist/lib/runner/getSubtreeSnapshot.js +4 -5
  152. package/dist/lib/schema/errors.js +4 -3
  153. package/dist/lib/schema/validate.js +4 -5
  154. package/dist/lib/scope/ScopeFacade.js +52 -35
  155. package/dist/lib/scope/providers/baseStateCompatible.js +9 -9
  156. package/dist/lib/scope/providers/guards.js +2 -2
  157. package/dist/lib/scope/recorders/DebugRecorder.js +9 -7
  158. package/dist/lib/scope/recorders/MetricRecorder.js +10 -8
  159. package/dist/lib/scope/state/zod/defineScopeFromZod.js +2 -3
  160. package/dist/lib/scope/state/zod/resolver.js +2 -3
  161. package/dist/lib/scope/state/zod/scopeFactory.js +16 -20
  162. package/dist/lib/scope/state/zod/utils/validateHelper.js +57 -14
  163. package/dist/trace.js +6 -2
  164. package/dist/types/advanced.d.ts +1 -0
  165. package/dist/types/detach.d.ts +59 -0
  166. package/dist/types/lib/builder/FlowChartBuilder.d.ts +81 -0
  167. package/dist/types/lib/detach/drivers/immediate.d.ts +39 -0
  168. package/dist/types/lib/detach/drivers/microtaskBatch.d.ts +57 -0
  169. package/dist/types/lib/detach/drivers/sendBeacon.d.ts +38 -0
  170. package/dist/types/lib/detach/drivers/setImmediate.d.ts +32 -0
  171. package/dist/types/lib/detach/drivers/setTimeout.d.ts +34 -0
  172. package/dist/types/lib/detach/drivers/workerThread.d.ts +50 -0
  173. package/dist/types/lib/detach/flush.d.ts +62 -0
  174. package/dist/types/lib/detach/handle.d.ts +83 -0
  175. package/dist/types/lib/detach/registry.d.ts +82 -0
  176. package/dist/types/lib/detach/runChild.d.ts +41 -0
  177. package/dist/types/lib/detach/spawn.d.ts +64 -0
  178. package/dist/types/lib/detach/types.d.ts +200 -0
  179. package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +0 -1
  180. package/dist/types/lib/engine/types.d.ts +0 -1
  181. package/dist/types/lib/reactive/types.d.ts +4 -0
  182. package/dist/types/lib/recorder/BoundaryStateTracker.d.ts +215 -0
  183. package/dist/types/lib/recorder/index.d.ts +1 -0
  184. package/dist/types/lib/runner/FlowChartExecutor.d.ts +28 -0
  185. package/dist/types/lib/scope/ScopeFacade.d.ts +4 -0
  186. package/dist/types/lib/scope/state/zod/utils/validateHelper.d.ts +13 -1
  187. package/dist/types/trace.d.ts +1 -0
  188. package/package.json +6 -1
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ /**
3
+ * detach/drivers/microtaskBatch.ts — Batch detached work into ONE microtask.
4
+ *
5
+ * Pattern: Producer-consumer with batched flush. Same shape as
6
+ * agentfootprint's `EventDispatcher` flush queue and the React
7
+ * reconciler's microtask scheduling — accumulate during the
8
+ * current sync slice, drain at the next microtask boundary.
9
+ * Role: Default driver for in-process detach. Cheapest scheduling
10
+ * primitive on V8/JSC: one `queueMicrotask` per batch
11
+ * regardless of how many work items, so the perf budget
12
+ * amortizes. Suitable for browser AND node AND edge runtimes
13
+ * (queueMicrotask is universal since 2018).
14
+ *
15
+ * Lifecycle:
16
+ *
17
+ * schedule(child, input, refId) ← driver entry
18
+ * └─ create handle (queued)
19
+ * └─ register in detachRegistry
20
+ * └─ push work item onto local queue
21
+ * └─ if no microtask scheduled yet → queueMicrotask(flush)
22
+ * └─ return handle (sync — passive recorder rule)
23
+ *
24
+ * flush() (microtask) ← deferred
25
+ * └─ swap out queue (drain races safely)
26
+ * └─ for each item: _markRunning, await runChild, _markDone/_markFailed
27
+ * └─ unregister handle from detachRegistry
28
+ *
29
+ * Why microtask (and not setImmediate / setTimeout):
30
+ * - Microtasks run BEFORE returning to the event loop — guarantees
31
+ * the work finishes within the current "tick" if the runtime allows
32
+ * - Lowest possible deferral cost (~50ns on modern V8)
33
+ * - Works in EVERY JS runtime (browser, node, deno, bun, edge)
34
+ * - Doesn't require any timer infrastructure → no GC pressure
35
+ *
36
+ * Re-entrancy:
37
+ * - If `runChild` calls `schedule()` for nested detach, the new item
38
+ * lands on the SAME queue. Because `scheduled` flips back to false
39
+ * at the start of `flush`, the new item triggers a fresh microtask.
40
+ * - Worst-case: O(n) microtasks for n nested levels. Acceptable —
41
+ * real-world detach trees are shallow.
42
+ */
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.microtaskBatchDriver = exports.createMicrotaskBatchDriver = void 0;
45
+ const handle_js_1 = require("../handle.js");
46
+ const registry_js_1 = require("../registry.js");
47
+ const runChild_js_1 = require("../runChild.js");
48
+ /**
49
+ * Build a microtask-batch driver wired to a custom child runner. Most
50
+ * consumers want the default singleton `microtaskBatchDriver` instead;
51
+ * this factory exists for tests and for advanced consumers who want to
52
+ * inject their own runner (e.g., a runner that wraps the child in a
53
+ * tracing context).
54
+ */
55
+ function createMicrotaskBatchDriver(runChild = runChild_js_1.defaultRunChild) {
56
+ // Per-driver-instance queue and flush guard. Closed over by `schedule`
57
+ // and `flush` so each call to `createMicrotaskBatchDriver` gets its
58
+ // own isolated batch (test isolation, multi-tenant scenarios).
59
+ const queue = [];
60
+ let scheduled = false;
61
+ function flush() {
62
+ // Reset BEFORE draining so re-entrant schedule()s during runChild
63
+ // queue a fresh microtask instead of joining the in-flight drain.
64
+ scheduled = false;
65
+ const items = queue.splice(0);
66
+ for (const item of items) {
67
+ // Each item runs concurrently — no awaits here, so the outer
68
+ // for-loop completes within this microtask. Errors inside
69
+ // `executeOne` are routed to the handle, not thrown. The promise
70
+ // is intentionally not awaited; ignore-promise-returned via the
71
+ // explicit no-op .then() pattern that the project's lint config
72
+ // accepts (vs `void`, which `no-void` rejects).
73
+ executeOne(item, runChild).then(undefined, undefined);
74
+ }
75
+ }
76
+ return {
77
+ name: 'microtask-batch',
78
+ capabilities: { browserSafe: true, nodeSafe: true, edgeSafe: true },
79
+ schedule(child, input, refId) {
80
+ const handle = (0, handle_js_1.createHandle)(refId);
81
+ (0, registry_js_1.register)(handle);
82
+ queue.push({ child, input, handle });
83
+ if (!scheduled) {
84
+ scheduled = true;
85
+ queueMicrotask(flush);
86
+ }
87
+ return handle;
88
+ },
89
+ };
90
+ }
91
+ exports.createMicrotaskBatchDriver = createMicrotaskBatchDriver;
92
+ /**
93
+ * Per-item execution. Marks the handle running, awaits the runner,
94
+ * routes outcome to the handle, cleans up the registry entry. Never
95
+ * throws — errors land on the handle (passive recorder rule).
96
+ */
97
+ async function executeOne(item, runChild) {
98
+ const impl = (0, handle_js_1.asImpl)(item.handle);
99
+ impl._markRunning();
100
+ try {
101
+ const result = await runChild(item.child, item.input);
102
+ impl._markDone(result);
103
+ }
104
+ catch (err) {
105
+ impl._markFailed(err instanceof Error ? err : new Error(String(err)));
106
+ }
107
+ finally {
108
+ (0, registry_js_1.unregister)(impl.id);
109
+ }
110
+ }
111
+ /**
112
+ * Default singleton. Most consumers import this and pass it to
113
+ * `executor.detachAndJoinLater(child, input, { driver: microtaskBatchDriver })`
114
+ * (or rely on it being the executor's default driver, set in T5b).
115
+ */
116
+ exports.microtaskBatchDriver = createMicrotaskBatchDriver();
117
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWljcm90YXNrQmF0Y2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2RldGFjaC9kcml2ZXJzL21pY3JvdGFza0JhdGNoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdDRzs7O0FBR0gsNENBQW9EO0FBQ3BELGdEQUFzRDtBQUN0RCxnREFBbUU7QUFTbkU7Ozs7OztHQU1HO0FBQ0gsU0FBZ0IsMEJBQTBCLENBQUMsV0FBd0IsNkJBQWU7SUFDaEYsdUVBQXVFO0lBQ3ZFLG9FQUFvRTtJQUNwRSwrREFBK0Q7SUFDL0QsTUFBTSxLQUFLLEdBQWUsRUFBRSxDQUFDO0lBQzdCLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQztJQUV0QixTQUFTLEtBQUs7UUFDWixrRUFBa0U7UUFDbEUsa0VBQWtFO1FBQ2xFLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDbEIsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5QixLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ3pCLDZEQUE2RDtZQUM3RCwwREFBMEQ7WUFDMUQsaUVBQWlFO1lBQ2pFLGdFQUFnRTtZQUNoRSxnRUFBZ0U7WUFDaEUsZ0RBQWdEO1lBQ2hELFVBQVUsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN4RCxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU87UUFDTCxJQUFJLEVBQUUsaUJBQWlCO1FBQ3ZCLFlBQVksRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFO1FBQ25FLFFBQVEsQ0FBQyxLQUFnQixFQUFFLEtBQWMsRUFBRSxLQUFhO1lBQ3RELE1BQU0sTUFBTSxHQUFHLElBQUEsd0JBQVksRUFBQyxLQUFLLENBQUMsQ0FBQztZQUNuQyxJQUFBLHNCQUFRLEVBQUMsTUFBTSxDQUFDLENBQUM7WUFDakIsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUNyQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ2YsU0FBUyxHQUFHLElBQUksQ0FBQztnQkFDakIsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3hCLENBQUM7WUFDRCxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUFyQ0QsZ0VBcUNDO0FBRUQ7Ozs7R0FJRztBQUNILEtBQUssVUFBVSxVQUFVLENBQUMsSUFBYyxFQUFFLFFBQXFCO0lBQzdELE1BQU0sSUFBSSxHQUFHLElBQUEsa0JBQU0sRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3BCLElBQUksQ0FBQztRQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDYixJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN4RSxDQUFDO1lBQVMsQ0FBQztRQUNULElBQUEsd0JBQVUsRUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDdEIsQ0FBQztBQUNILENBQUM7QUFFRDs7OztHQUlHO0FBQ1UsUUFBQSxvQkFBb0IsR0FBaUIsMEJBQTBCLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogZGV0YWNoL2RyaXZlcnMvbWljcm90YXNrQmF0Y2gudHMg4oCUIEJhdGNoIGRldGFjaGVkIHdvcmsgaW50byBPTkUgbWljcm90YXNrLlxuICpcbiAqIFBhdHRlcm46ICBQcm9kdWNlci1jb25zdW1lciB3aXRoIGJhdGNoZWQgZmx1c2guIFNhbWUgc2hhcGUgYXNcbiAqICAgICAgICAgICBhZ2VudGZvb3RwcmludCdzIGBFdmVudERpc3BhdGNoZXJgIGZsdXNoIHF1ZXVlIGFuZCB0aGUgUmVhY3RcbiAqICAgICAgICAgICByZWNvbmNpbGVyJ3MgbWljcm90YXNrIHNjaGVkdWxpbmcg4oCUIGFjY3VtdWxhdGUgZHVyaW5nIHRoZVxuICogICAgICAgICAgIGN1cnJlbnQgc3luYyBzbGljZSwgZHJhaW4gYXQgdGhlIG5leHQgbWljcm90YXNrIGJvdW5kYXJ5LlxuICogUm9sZTogICAgIERlZmF1bHQgZHJpdmVyIGZvciBpbi1wcm9jZXNzIGRldGFjaC4gQ2hlYXBlc3Qgc2NoZWR1bGluZ1xuICogICAgICAgICAgIHByaW1pdGl2ZSBvbiBWOC9KU0M6IG9uZSBgcXVldWVNaWNyb3Rhc2tgIHBlciBiYXRjaFxuICogICAgICAgICAgIHJlZ2FyZGxlc3Mgb2YgaG93IG1hbnkgd29yayBpdGVtcywgc28gdGhlIHBlcmYgYnVkZ2V0XG4gKiAgICAgICAgICAgYW1vcnRpemVzLiBTdWl0YWJsZSBmb3IgYnJvd3NlciBBTkQgbm9kZSBBTkQgZWRnZSBydW50aW1lc1xuICogICAgICAgICAgIChxdWV1ZU1pY3JvdGFzayBpcyB1bml2ZXJzYWwgc2luY2UgMjAxOCkuXG4gKlxuICogTGlmZWN5Y2xlOlxuICpcbiAqICAgc2NoZWR1bGUoY2hpbGQsIGlucHV0LCByZWZJZCkgICAgICAgICAgICDihpAgZHJpdmVyIGVudHJ5XG4gKiAgICAg4pSU4pSAIGNyZWF0ZSBoYW5kbGUgKHF1ZXVlZClcbiAqICAgICDilJTilIAgcmVnaXN0ZXIgaW4gZGV0YWNoUmVnaXN0cnlcbiAqICAgICDilJTilIAgcHVzaCB3b3JrIGl0ZW0gb250byBsb2NhbCBxdWV1ZVxuICogICAgIOKUlOKUgCBpZiBubyBtaWNyb3Rhc2sgc2NoZWR1bGVkIHlldCDihpIgcXVldWVNaWNyb3Rhc2soZmx1c2gpXG4gKiAgICAg4pSU4pSAIHJldHVybiBoYW5kbGUgKHN5bmMg4oCUIHBhc3NpdmUgcmVjb3JkZXIgcnVsZSlcbiAqXG4gKiAgIGZsdXNoKCkgKG1pY3JvdGFzaykgICAgICAgICAgICAgICAgICAgICAgIOKGkCBkZWZlcnJlZFxuICogICAgIOKUlOKUgCBzd2FwIG91dCBxdWV1ZSAoZHJhaW4gcmFjZXMgc2FmZWx5KVxuICogICAgIOKUlOKUgCBmb3IgZWFjaCBpdGVtOiBfbWFya1J1bm5pbmcsIGF3YWl0IHJ1bkNoaWxkLCBfbWFya0RvbmUvX21hcmtGYWlsZWRcbiAqICAgICDilJTilIAgdW5yZWdpc3RlciBoYW5kbGUgZnJvbSBkZXRhY2hSZWdpc3RyeVxuICpcbiAqIFdoeSBtaWNyb3Rhc2sgKGFuZCBub3Qgc2V0SW1tZWRpYXRlIC8gc2V0VGltZW91dCk6XG4gKiAgIC0gTWljcm90YXNrcyBydW4gQkVGT1JFIHJldHVybmluZyB0byB0aGUgZXZlbnQgbG9vcCDigJQgZ3VhcmFudGVlc1xuICogICAgIHRoZSB3b3JrIGZpbmlzaGVzIHdpdGhpbiB0aGUgY3VycmVudCBcInRpY2tcIiBpZiB0aGUgcnVudGltZSBhbGxvd3NcbiAqICAgLSBMb3dlc3QgcG9zc2libGUgZGVmZXJyYWwgY29zdCAofjUwbnMgb24gbW9kZXJuIFY4KVxuICogICAtIFdvcmtzIGluIEVWRVJZIEpTIHJ1bnRpbWUgKGJyb3dzZXIsIG5vZGUsIGRlbm8sIGJ1biwgZWRnZSlcbiAqICAgLSBEb2Vzbid0IHJlcXVpcmUgYW55IHRpbWVyIGluZnJhc3RydWN0dXJlIOKGkiBubyBHQyBwcmVzc3VyZVxuICpcbiAqIFJlLWVudHJhbmN5OlxuICogICAtIElmIGBydW5DaGlsZGAgY2FsbHMgYHNjaGVkdWxlKClgIGZvciBuZXN0ZWQgZGV0YWNoLCB0aGUgbmV3IGl0ZW1cbiAqICAgICBsYW5kcyBvbiB0aGUgU0FNRSBxdWV1ZS4gQmVjYXVzZSBgc2NoZWR1bGVkYCBmbGlwcyBiYWNrIHRvIGZhbHNlXG4gKiAgICAgYXQgdGhlIHN0YXJ0IG9mIGBmbHVzaGAsIHRoZSBuZXcgaXRlbSB0cmlnZ2VycyBhIGZyZXNoIG1pY3JvdGFzay5cbiAqICAgLSBXb3JzdC1jYXNlOiBPKG4pIG1pY3JvdGFza3MgZm9yIG4gbmVzdGVkIGxldmVscy4gQWNjZXB0YWJsZSDigJRcbiAqICAgICByZWFsLXdvcmxkIGRldGFjaCB0cmVlcyBhcmUgc2hhbGxvdy5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEZsb3dDaGFydCB9IGZyb20gJy4uLy4uL2J1aWxkZXIvdHlwZXMuanMnO1xuaW1wb3J0IHsgYXNJbXBsLCBjcmVhdGVIYW5kbGUgfSBmcm9tICcuLi9oYW5kbGUuanMnO1xuaW1wb3J0IHsgcmVnaXN0ZXIsIHVucmVnaXN0ZXIgfSBmcm9tICcuLi9yZWdpc3RyeS5qcyc7XG5pbXBvcnQgeyB0eXBlIENoaWxkUnVubmVyLCBkZWZhdWx0UnVuQ2hpbGQgfSBmcm9tICcuLi9ydW5DaGlsZC5qcyc7XG5pbXBvcnQgdHlwZSB7IERldGFjaERyaXZlciwgRGV0YWNoSGFuZGxlIH0gZnJvbSAnLi4vdHlwZXMuanMnO1xuXG5pbnRlcmZhY2UgV29ya0l0ZW0ge1xuICByZWFkb25seSBjaGlsZDogRmxvd0NoYXJ0O1xuICByZWFkb25seSBpbnB1dDogdW5rbm93bjtcbiAgcmVhZG9ubHkgaGFuZGxlOiBEZXRhY2hIYW5kbGU7XG59XG5cbi8qKlxuICogQnVpbGQgYSBtaWNyb3Rhc2stYmF0Y2ggZHJpdmVyIHdpcmVkIHRvIGEgY3VzdG9tIGNoaWxkIHJ1bm5lci4gTW9zdFxuICogY29uc3VtZXJzIHdhbnQgdGhlIGRlZmF1bHQgc2luZ2xldG9uIGBtaWNyb3Rhc2tCYXRjaERyaXZlcmAgaW5zdGVhZDtcbiAqIHRoaXMgZmFjdG9yeSBleGlzdHMgZm9yIHRlc3RzIGFuZCBmb3IgYWR2YW5jZWQgY29uc3VtZXJzIHdobyB3YW50IHRvXG4gKiBpbmplY3QgdGhlaXIgb3duIHJ1bm5lciAoZS5nLiwgYSBydW5uZXIgdGhhdCB3cmFwcyB0aGUgY2hpbGQgaW4gYVxuICogdHJhY2luZyBjb250ZXh0KS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1pY3JvdGFza0JhdGNoRHJpdmVyKHJ1bkNoaWxkOiBDaGlsZFJ1bm5lciA9IGRlZmF1bHRSdW5DaGlsZCk6IERldGFjaERyaXZlciB7XG4gIC8vIFBlci1kcml2ZXItaW5zdGFuY2UgcXVldWUgYW5kIGZsdXNoIGd1YXJkLiBDbG9zZWQgb3ZlciBieSBgc2NoZWR1bGVgXG4gIC8vIGFuZCBgZmx1c2hgIHNvIGVhY2ggY2FsbCB0byBgY3JlYXRlTWljcm90YXNrQmF0Y2hEcml2ZXJgIGdldHMgaXRzXG4gIC8vIG93biBpc29sYXRlZCBiYXRjaCAodGVzdCBpc29sYXRpb24sIG11bHRpLXRlbmFudCBzY2VuYXJpb3MpLlxuICBjb25zdCBxdWV1ZTogV29ya0l0ZW1bXSA9IFtdO1xuICBsZXQgc2NoZWR1bGVkID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gZmx1c2goKTogdm9pZCB7XG4gICAgLy8gUmVzZXQgQkVGT1JFIGRyYWluaW5nIHNvIHJlLWVudHJhbnQgc2NoZWR1bGUoKXMgZHVyaW5nIHJ1bkNoaWxkXG4gICAgLy8gcXVldWUgYSBmcmVzaCBtaWNyb3Rhc2sgaW5zdGVhZCBvZiBqb2luaW5nIHRoZSBpbi1mbGlnaHQgZHJhaW4uXG4gICAgc2NoZWR1bGVkID0gZmFsc2U7XG4gICAgY29uc3QgaXRlbXMgPSBxdWV1ZS5zcGxpY2UoMCk7XG4gICAgZm9yIChjb25zdCBpdGVtIG9mIGl0ZW1zKSB7XG4gICAgICAvLyBFYWNoIGl0ZW0gcnVucyBjb25jdXJyZW50bHkg4oCUIG5vIGF3YWl0cyBoZXJlLCBzbyB0aGUgb3V0ZXJcbiAgICAgIC8vIGZvci1sb29wIGNvbXBsZXRlcyB3aXRoaW4gdGhpcyBtaWNyb3Rhc2suIEVycm9ycyBpbnNpZGVcbiAgICAgIC8vIGBleGVjdXRlT25lYCBhcmUgcm91dGVkIHRvIHRoZSBoYW5kbGUsIG5vdCB0aHJvd24uIFRoZSBwcm9taXNlXG4gICAgICAvLyBpcyBpbnRlbnRpb25hbGx5IG5vdCBhd2FpdGVkOyBpZ25vcmUtcHJvbWlzZS1yZXR1cm5lZCB2aWEgdGhlXG4gICAgICAvLyBleHBsaWNpdCBuby1vcCAudGhlbigpIHBhdHRlcm4gdGhhdCB0aGUgcHJvamVjdCdzIGxpbnQgY29uZmlnXG4gICAgICAvLyBhY2NlcHRzICh2cyBgdm9pZGAsIHdoaWNoIGBuby12b2lkYCByZWplY3RzKS5cbiAgICAgIGV4ZWN1dGVPbmUoaXRlbSwgcnVuQ2hpbGQpLnRoZW4odW5kZWZpbmVkLCB1bmRlZmluZWQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ21pY3JvdGFzay1iYXRjaCcsXG4gICAgY2FwYWJpbGl0aWVzOiB7IGJyb3dzZXJTYWZlOiB0cnVlLCBub2RlU2FmZTogdHJ1ZSwgZWRnZVNhZmU6IHRydWUgfSxcbiAgICBzY2hlZHVsZShjaGlsZDogRmxvd0NoYXJ0LCBpbnB1dDogdW5rbm93biwgcmVmSWQ6IHN0cmluZyk6IERldGFjaEhhbmRsZSB7XG4gICAgICBjb25zdCBoYW5kbGUgPSBjcmVhdGVIYW5kbGUocmVmSWQpO1xuICAgICAgcmVnaXN0ZXIoaGFuZGxlKTtcbiAgICAgIHF1ZXVlLnB1c2goeyBjaGlsZCwgaW5wdXQsIGhhbmRsZSB9KTtcbiAgICAgIGlmICghc2NoZWR1bGVkKSB7XG4gICAgICAgIHNjaGVkdWxlZCA9IHRydWU7XG4gICAgICAgIHF1ZXVlTWljcm90YXNrKGZsdXNoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBQZXItaXRlbSBleGVjdXRpb24uIE1hcmtzIHRoZSBoYW5kbGUgcnVubmluZywgYXdhaXRzIHRoZSBydW5uZXIsXG4gKiByb3V0ZXMgb3V0Y29tZSB0byB0aGUgaGFuZGxlLCBjbGVhbnMgdXAgdGhlIHJlZ2lzdHJ5IGVudHJ5LiBOZXZlclxuICogdGhyb3dzIOKAlCBlcnJvcnMgbGFuZCBvbiB0aGUgaGFuZGxlIChwYXNzaXZlIHJlY29yZGVyIHJ1bGUpLlxuICovXG5hc3luYyBmdW5jdGlvbiBleGVjdXRlT25lKGl0ZW06IFdvcmtJdGVtLCBydW5DaGlsZDogQ2hpbGRSdW5uZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgaW1wbCA9IGFzSW1wbChpdGVtLmhhbmRsZSk7XG4gIGltcGwuX21hcmtSdW5uaW5nKCk7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcnVuQ2hpbGQoaXRlbS5jaGlsZCwgaXRlbS5pbnB1dCk7XG4gICAgaW1wbC5fbWFya0RvbmUocmVzdWx0KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgaW1wbC5fbWFya0ZhaWxlZChlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyKSkpO1xuICB9IGZpbmFsbHkge1xuICAgIHVucmVnaXN0ZXIoaW1wbC5pZCk7XG4gIH1cbn1cblxuLyoqXG4gKiBEZWZhdWx0IHNpbmdsZXRvbi4gTW9zdCBjb25zdW1lcnMgaW1wb3J0IHRoaXMgYW5kIHBhc3MgaXQgdG9cbiAqIGBleGVjdXRvci5kZXRhY2hBbmRKb2luTGF0ZXIoY2hpbGQsIGlucHV0LCB7IGRyaXZlcjogbWljcm90YXNrQmF0Y2hEcml2ZXIgfSlgXG4gKiAob3IgcmVseSBvbiBpdCBiZWluZyB0aGUgZXhlY3V0b3IncyBkZWZhdWx0IGRyaXZlciwgc2V0IGluIFQ1YikuXG4gKi9cbmV4cG9ydCBjb25zdCBtaWNyb3Rhc2tCYXRjaERyaXZlcjogRGV0YWNoRHJpdmVyID0gY3JlYXRlTWljcm90YXNrQmF0Y2hEcml2ZXIoKTtcbiJdfQ==
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ /**
3
+ * detach/drivers/sendBeacon.ts — Browser-only driver that ships work
4
+ * via `navigator.sendBeacon` so it
5
+ * survives page-unload.
6
+ *
7
+ * Pattern: Strategy / Adapter — translates the consumer's child
8
+ * flowchart into a sendBeacon POST. The "child" is expected
9
+ * to produce a JSON-serializable payload via its
10
+ * `inputMapper`; the URL endpoint is set at driver creation.
11
+ * Role: The narrow but high-value driver for analytics / error
12
+ * reporting / page-leave telemetry — the one case where
13
+ * "fire-and-forget" must really mean "ships even if the
14
+ * user closes the tab right after."
15
+ *
16
+ * `navigator.sendBeacon` semantics:
17
+ * - Browser queues the POST in the OS network stack BEFORE returning
18
+ * control. Survives page-unload, navigation, refresh.
19
+ * - Limited to ~64 KB per call (per HTML5 spec).
20
+ * - Fire-and-forget — no response observable.
21
+ *
22
+ * Caveats:
23
+ * - Browser-only (`browserSafe: true, survivesUnload: true`).
24
+ * `validate()` throws helpfully if `navigator.sendBeacon` isn't a
25
+ * function (e.g., when imported in Node).
26
+ * - The driver does NOT run the child flowchart through a
27
+ * `FlowChartExecutor` — it serializes the input and POSTs. This
28
+ * is an intentional simplification: sendBeacon's semantics
29
+ * wouldn't survive an executor's async stages anyway.
30
+ */
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ exports.createSendBeaconDriver = void 0;
33
+ const handle_js_1 = require("../handle.js");
34
+ const registry_js_1 = require("../registry.js");
35
+ function createSendBeaconDriver(opts) {
36
+ if (!opts.url) {
37
+ throw new TypeError('[detach] createSendBeaconDriver requires a `url` option.');
38
+ }
39
+ function serialize(input) {
40
+ if (opts.serialize)
41
+ return opts.serialize(input);
42
+ return new Blob([JSON.stringify(input ?? null)], { type: 'application/json' });
43
+ }
44
+ return {
45
+ name: 'send-beacon',
46
+ capabilities: {
47
+ browserSafe: true,
48
+ survivesUnload: true,
49
+ },
50
+ validate() {
51
+ if (typeof navigator === 'undefined' || typeof navigator.sendBeacon !== 'function') {
52
+ throw new Error('[detach] sendBeaconDriver requires a browser environment with `navigator.sendBeacon`. ' +
53
+ 'Use `microtaskBatchDriver` for in-process detach, or `setImmediateDriver` for Node.js.');
54
+ }
55
+ },
56
+ schedule(_child, input, refId) {
57
+ const handle = (0, handle_js_1.createHandle)(refId);
58
+ (0, registry_js_1.register)(handle);
59
+ const impl = (0, handle_js_1.asImpl)(handle);
60
+ impl._markRunning();
61
+ try {
62
+ const payload = serialize(input);
63
+ const accepted = navigator.sendBeacon(opts.url, payload);
64
+ if (accepted) {
65
+ impl._markDone({ accepted: true, url: opts.url });
66
+ }
67
+ else {
68
+ impl._markFailed(new Error('[detach] navigator.sendBeacon refused the payload (likely over the ~64 KB limit).'));
69
+ }
70
+ }
71
+ catch (err) {
72
+ impl._markFailed(err instanceof Error ? err : new Error(String(err)));
73
+ }
74
+ finally {
75
+ (0, registry_js_1.unregister)(impl.id);
76
+ }
77
+ return handle;
78
+ },
79
+ };
80
+ }
81
+ exports.createSendBeaconDriver = createSendBeaconDriver;
82
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZEJlYWNvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZGV0YWNoL2RyaXZlcnMvc2VuZEJlYWNvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E0Qkc7OztBQUdILDRDQUFvRDtBQUNwRCxnREFBc0Q7QUFXdEQsU0FBZ0Isc0JBQXNCLENBQUMsSUFBNkI7SUFDbEUsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNkLE1BQU0sSUFBSSxTQUFTLENBQUMsMERBQTBELENBQUMsQ0FBQztJQUNsRixDQUFDO0lBRUQsU0FBUyxTQUFTLENBQUMsS0FBYztRQUMvQixJQUFJLElBQUksQ0FBQyxTQUFTO1lBQUUsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pELE9BQU8sSUFBSSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLGtCQUFrQixFQUFFLENBQUMsQ0FBQztJQUNqRixDQUFDO0lBRUQsT0FBTztRQUNMLElBQUksRUFBRSxhQUFhO1FBQ25CLFlBQVksRUFBRTtZQUNaLFdBQVcsRUFBRSxJQUFJO1lBQ2pCLGNBQWMsRUFBRSxJQUFJO1NBQ3JCO1FBQ0QsUUFBUTtZQUNOLElBQUksT0FBTyxTQUFTLEtBQUssV0FBVyxJQUFJLE9BQU8sU0FBUyxDQUFDLFVBQVUsS0FBSyxVQUFVLEVBQUUsQ0FBQztnQkFDbkYsTUFBTSxJQUFJLEtBQUssQ0FDYix3RkFBd0Y7b0JBQ3RGLHdGQUF3RixDQUMzRixDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFDRCxRQUFRLENBQUMsTUFBaUIsRUFBRSxLQUFjLEVBQUUsS0FBYTtZQUN2RCxNQUFNLE1BQU0sR0FBRyxJQUFBLHdCQUFZLEVBQUMsS0FBSyxDQUFDLENBQUM7WUFDbkMsSUFBQSxzQkFBUSxFQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2pCLE1BQU0sSUFBSSxHQUFHLElBQUEsa0JBQU0sRUFBQyxNQUFNLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDcEIsSUFBSSxDQUFDO2dCQUNILE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDakMsTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLE9BQW1CLENBQUMsQ0FBQztnQkFDckUsSUFBSSxRQUFRLEVBQUUsQ0FBQztvQkFDYixJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7Z0JBQ3BELENBQUM7cUJBQU0sQ0FBQztvQkFDTixJQUFJLENBQUMsV0FBVyxDQUNkLElBQUksS0FBSyxDQUFDLG1GQUFtRixDQUFDLENBQy9GLENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hFLENBQUM7b0JBQVMsQ0FBQztnQkFDVCxJQUFBLHdCQUFVLEVBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3RCLENBQUM7WUFDRCxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUEvQ0Qsd0RBK0NDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBkZXRhY2gvZHJpdmVycy9zZW5kQmVhY29uLnRzIOKAlCBCcm93c2VyLW9ubHkgZHJpdmVyIHRoYXQgc2hpcHMgd29ya1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpYSBgbmF2aWdhdG9yLnNlbmRCZWFjb25gIHNvIGl0XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vydml2ZXMgcGFnZS11bmxvYWQuXG4gKlxuICogUGF0dGVybjogIFN0cmF0ZWd5IC8gQWRhcHRlciDigJQgdHJhbnNsYXRlcyB0aGUgY29uc3VtZXIncyBjaGlsZFxuICogICAgICAgICAgIGZsb3djaGFydCBpbnRvIGEgc2VuZEJlYWNvbiBQT1NULiBUaGUgXCJjaGlsZFwiIGlzIGV4cGVjdGVkXG4gKiAgICAgICAgICAgdG8gcHJvZHVjZSBhIEpTT04tc2VyaWFsaXphYmxlIHBheWxvYWQgdmlhIGl0c1xuICogICAgICAgICAgIGBpbnB1dE1hcHBlcmA7IHRoZSBVUkwgZW5kcG9pbnQgaXMgc2V0IGF0IGRyaXZlciBjcmVhdGlvbi5cbiAqIFJvbGU6ICAgICBUaGUgbmFycm93IGJ1dCBoaWdoLXZhbHVlIGRyaXZlciBmb3IgYW5hbHl0aWNzIC8gZXJyb3JcbiAqICAgICAgICAgICByZXBvcnRpbmcgLyBwYWdlLWxlYXZlIHRlbGVtZXRyeSDigJQgdGhlIG9uZSBjYXNlIHdoZXJlXG4gKiAgICAgICAgICAgXCJmaXJlLWFuZC1mb3JnZXRcIiBtdXN0IHJlYWxseSBtZWFuIFwic2hpcHMgZXZlbiBpZiB0aGVcbiAqICAgICAgICAgICB1c2VyIGNsb3NlcyB0aGUgdGFiIHJpZ2h0IGFmdGVyLlwiXG4gKlxuICogYG5hdmlnYXRvci5zZW5kQmVhY29uYCBzZW1hbnRpY3M6XG4gKiAgIC0gQnJvd3NlciBxdWV1ZXMgdGhlIFBPU1QgaW4gdGhlIE9TIG5ldHdvcmsgc3RhY2sgQkVGT1JFIHJldHVybmluZ1xuICogICAgIGNvbnRyb2wuIFN1cnZpdmVzIHBhZ2UtdW5sb2FkLCBuYXZpZ2F0aW9uLCByZWZyZXNoLlxuICogICAtIExpbWl0ZWQgdG8gfjY0IEtCIHBlciBjYWxsIChwZXIgSFRNTDUgc3BlYykuXG4gKiAgIC0gRmlyZS1hbmQtZm9yZ2V0IOKAlCBubyByZXNwb25zZSBvYnNlcnZhYmxlLlxuICpcbiAqIENhdmVhdHM6XG4gKiAgIC0gQnJvd3Nlci1vbmx5IChgYnJvd3NlclNhZmU6IHRydWUsIHN1cnZpdmVzVW5sb2FkOiB0cnVlYCkuXG4gKiAgICAgYHZhbGlkYXRlKClgIHRocm93cyBoZWxwZnVsbHkgaWYgYG5hdmlnYXRvci5zZW5kQmVhY29uYCBpc24ndCBhXG4gKiAgICAgZnVuY3Rpb24gKGUuZy4sIHdoZW4gaW1wb3J0ZWQgaW4gTm9kZSkuXG4gKiAgIC0gVGhlIGRyaXZlciBkb2VzIE5PVCBydW4gdGhlIGNoaWxkIGZsb3djaGFydCB0aHJvdWdoIGFcbiAqICAgICBgRmxvd0NoYXJ0RXhlY3V0b3JgIOKAlCBpdCBzZXJpYWxpemVzIHRoZSBpbnB1dCBhbmQgUE9TVHMuIFRoaXNcbiAqICAgICBpcyBhbiBpbnRlbnRpb25hbCBzaW1wbGlmaWNhdGlvbjogc2VuZEJlYWNvbidzIHNlbWFudGljc1xuICogICAgIHdvdWxkbid0IHN1cnZpdmUgYW4gZXhlY3V0b3IncyBhc3luYyBzdGFnZXMgYW55d2F5LlxuICovXG5cbmltcG9ydCB0eXBlIHsgRmxvd0NoYXJ0IH0gZnJvbSAnLi4vLi4vYnVpbGRlci90eXBlcy5qcyc7XG5pbXBvcnQgeyBhc0ltcGwsIGNyZWF0ZUhhbmRsZSB9IGZyb20gJy4uL2hhbmRsZS5qcyc7XG5pbXBvcnQgeyByZWdpc3RlciwgdW5yZWdpc3RlciB9IGZyb20gJy4uL3JlZ2lzdHJ5LmpzJztcbmltcG9ydCB0eXBlIHsgRGV0YWNoRHJpdmVyLCBEZXRhY2hIYW5kbGUgfSBmcm9tICcuLi90eXBlcy5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VuZEJlYWNvbkRyaXZlck9wdGlvbnMge1xuICAvKiogRW5kcG9pbnQgVVJMIOKAlCByZXF1aXJlZC4gZS5nLiwgYCdodHRwczovL3RlbGVtZXRyeS5leGFtcGxlLmNvbS9pbmdlc3QnYC4gKi9cbiAgcmVhZG9ubHkgdXJsOiBzdHJpbmc7XG4gIC8qKiBDdXN0b20gc2VyaWFsaXplci4gRGVmYXVsdHMgdG8gYEpTT04uc3RyaW5naWZ5KGlucHV0KWAgd2l0aFxuICAgKiAgYGFwcGxpY2F0aW9uL2pzb25gIGNvbnRlbnQgdHlwZS4gKi9cbiAgcmVhZG9ubHkgc2VyaWFsaXplPzogKGlucHV0OiB1bmtub3duKSA9PiBCbG9iIHwgc3RyaW5nIHwgRm9ybURhdGE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTZW5kQmVhY29uRHJpdmVyKG9wdHM6IFNlbmRCZWFjb25Ecml2ZXJPcHRpb25zKTogRGV0YWNoRHJpdmVyIHtcbiAgaWYgKCFvcHRzLnVybCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1tkZXRhY2hdIGNyZWF0ZVNlbmRCZWFjb25Ecml2ZXIgcmVxdWlyZXMgYSBgdXJsYCBvcHRpb24uJyk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXJpYWxpemUoaW5wdXQ6IHVua25vd24pOiBCbG9iIHwgc3RyaW5nIHwgRm9ybURhdGEge1xuICAgIGlmIChvcHRzLnNlcmlhbGl6ZSkgcmV0dXJuIG9wdHMuc2VyaWFsaXplKGlucHV0KTtcbiAgICByZXR1cm4gbmV3IEJsb2IoW0pTT04uc3RyaW5naWZ5KGlucHV0ID8/IG51bGwpXSwgeyB0eXBlOiAnYXBwbGljYXRpb24vanNvbicgfSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdzZW5kLWJlYWNvbicsXG4gICAgY2FwYWJpbGl0aWVzOiB7XG4gICAgICBicm93c2VyU2FmZTogdHJ1ZSxcbiAgICAgIHN1cnZpdmVzVW5sb2FkOiB0cnVlLFxuICAgIH0sXG4gICAgdmFsaWRhdGUoKTogdm9pZCB7XG4gICAgICBpZiAodHlwZW9mIG5hdmlnYXRvciA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIG5hdmlnYXRvci5zZW5kQmVhY29uICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAnW2RldGFjaF0gc2VuZEJlYWNvbkRyaXZlciByZXF1aXJlcyBhIGJyb3dzZXIgZW52aXJvbm1lbnQgd2l0aCBgbmF2aWdhdG9yLnNlbmRCZWFjb25gLiAnICtcbiAgICAgICAgICAgICdVc2UgYG1pY3JvdGFza0JhdGNoRHJpdmVyYCBmb3IgaW4tcHJvY2VzcyBkZXRhY2gsIG9yIGBzZXRJbW1lZGlhdGVEcml2ZXJgIGZvciBOb2RlLmpzLicsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSxcbiAgICBzY2hlZHVsZShfY2hpbGQ6IEZsb3dDaGFydCwgaW5wdXQ6IHVua25vd24sIHJlZklkOiBzdHJpbmcpOiBEZXRhY2hIYW5kbGUge1xuICAgICAgY29uc3QgaGFuZGxlID0gY3JlYXRlSGFuZGxlKHJlZklkKTtcbiAgICAgIHJlZ2lzdGVyKGhhbmRsZSk7XG4gICAgICBjb25zdCBpbXBsID0gYXNJbXBsKGhhbmRsZSk7XG4gICAgICBpbXBsLl9tYXJrUnVubmluZygpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHNlcmlhbGl6ZShpbnB1dCk7XG4gICAgICAgIGNvbnN0IGFjY2VwdGVkID0gbmF2aWdhdG9yLnNlbmRCZWFjb24ob3B0cy51cmwsIHBheWxvYWQgYXMgQm9keUluaXQpO1xuICAgICAgICBpZiAoYWNjZXB0ZWQpIHtcbiAgICAgICAgICBpbXBsLl9tYXJrRG9uZSh7IGFjY2VwdGVkOiB0cnVlLCB1cmw6IG9wdHMudXJsIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGltcGwuX21hcmtGYWlsZWQoXG4gICAgICAgICAgICBuZXcgRXJyb3IoJ1tkZXRhY2hdIG5hdmlnYXRvci5zZW5kQmVhY29uIHJlZnVzZWQgdGhlIHBheWxvYWQgKGxpa2VseSBvdmVyIHRoZSB+NjQgS0IgbGltaXQpLicpLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBpbXBsLl9tYXJrRmFpbGVkKGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyIDogbmV3IEVycm9yKFN0cmluZyhlcnIpKSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB1bnJlZ2lzdGVyKGltcGwuaWQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhbmRsZTtcbiAgICB9LFxuICB9O1xufVxuIl19
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ /**
3
+ * detach/drivers/setImmediate.ts — Defer detached work to a Node.js
4
+ * `setImmediate` boundary.
5
+ *
6
+ * Pattern: Same producer-consumer batch flush as `microtaskBatch`,
7
+ * but the deferral is `setImmediate` instead of
8
+ * `queueMicrotask`. Yields control back to the event loop
9
+ * BEFORE running — allows pending I/O callbacks to drain
10
+ * first, which microtasks would block.
11
+ * Role: Node-specific driver for "fire-and-forget after the
12
+ * current I/O tick." Use when the parent stage handles
13
+ * latency-sensitive work and you don't want detached work
14
+ * to compete for the synchronous slice.
15
+ *
16
+ * When to pick this over microtaskBatch:
17
+ * - You're shipping logs / metrics in a hot HTTP path and don't
18
+ * want them blocking the response from being flushed
19
+ * - The detached work itself is CPU-heavy enough that running it on
20
+ * the same microtask cycle would delay other microtasks
21
+ * - You explicitly want "next event-loop tick" semantics — useful
22
+ * when interacting with third-party libraries that expect at
23
+ * least one I/O tick between schedule and execution
24
+ *
25
+ * Capability:
26
+ * - `nodeSafe: true` — relies on Node's `setImmediate`, NOT
27
+ * available in browsers / Deno / Cloudflare Workers (use
28
+ * `setTimeoutDriver` for cross-runtime alternative)
29
+ */
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.setImmediateDriver = exports.createSetImmediateDriver = void 0;
32
+ const handle_js_1 = require("../handle.js");
33
+ const registry_js_1 = require("../registry.js");
34
+ const runChild_js_1 = require("../runChild.js");
35
+ function createSetImmediateDriver(runChild = runChild_js_1.defaultRunChild) {
36
+ const queue = [];
37
+ let scheduled = false;
38
+ function flush() {
39
+ scheduled = false;
40
+ const items = queue.splice(0);
41
+ for (const item of items) {
42
+ executeOne(item, runChild).then(undefined, undefined);
43
+ }
44
+ }
45
+ return {
46
+ name: 'set-immediate',
47
+ capabilities: { nodeSafe: true },
48
+ validate() {
49
+ if (typeof setImmediate !== 'function') {
50
+ throw new Error('[detach] setImmediateDriver requires Node.js — global `setImmediate` is not defined ' +
51
+ 'in this runtime. Use `microtaskBatchDriver` for cross-runtime use, or `setTimeoutDriver` ' +
52
+ 'for browser/edge environments.');
53
+ }
54
+ },
55
+ schedule(child, input, refId) {
56
+ const handle = (0, handle_js_1.createHandle)(refId);
57
+ (0, registry_js_1.register)(handle);
58
+ queue.push({ child, input, handle });
59
+ if (!scheduled) {
60
+ scheduled = true;
61
+ // `setImmediate` is non-undefined here in Node; runtime guard
62
+ // is in `validate()`. The `!` is a deliberate assertion.
63
+ setImmediate(flush);
64
+ }
65
+ return handle;
66
+ },
67
+ };
68
+ }
69
+ exports.createSetImmediateDriver = createSetImmediateDriver;
70
+ async function executeOne(item, runChild) {
71
+ const impl = (0, handle_js_1.asImpl)(item.handle);
72
+ impl._markRunning();
73
+ try {
74
+ const result = await runChild(item.child, item.input);
75
+ impl._markDone(result);
76
+ }
77
+ catch (err) {
78
+ impl._markFailed(err instanceof Error ? err : new Error(String(err)));
79
+ }
80
+ finally {
81
+ (0, registry_js_1.unregister)(impl.id);
82
+ }
83
+ }
84
+ exports.setImmediateDriver = createSetImmediateDriver();
85
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0SW1tZWRpYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9kZXRhY2gvZHJpdmVycy9zZXRJbW1lZGlhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EyQkc7OztBQUdILDRDQUFvRDtBQUNwRCxnREFBc0Q7QUFDdEQsZ0RBQW1FO0FBZW5FLFNBQWdCLHdCQUF3QixDQUFDLFdBQXdCLDZCQUFlO0lBQzlFLE1BQU0sS0FBSyxHQUFlLEVBQUUsQ0FBQztJQUM3QixJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFFdEIsU0FBUyxLQUFLO1FBQ1osU0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlCLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7WUFDekIsVUFBVSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3hELENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTztRQUNMLElBQUksRUFBRSxlQUFlO1FBQ3JCLFlBQVksRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7UUFDaEMsUUFBUTtZQUNOLElBQUksT0FBTyxZQUFZLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQ3ZDLE1BQU0sSUFBSSxLQUFLLENBQ2Isc0ZBQXNGO29CQUNwRiwyRkFBMkY7b0JBQzNGLGdDQUFnQyxDQUNuQyxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFDRCxRQUFRLENBQUMsS0FBZ0IsRUFBRSxLQUFjLEVBQUUsS0FBYTtZQUN0RCxNQUFNLE1BQU0sR0FBRyxJQUFBLHdCQUFZLEVBQUMsS0FBSyxDQUFDLENBQUM7WUFDbkMsSUFBQSxzQkFBUSxFQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2pCLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNmLFNBQVMsR0FBRyxJQUFJLENBQUM7Z0JBQ2pCLDhEQUE4RDtnQkFDOUQseURBQXlEO2dCQUN6RCxZQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkIsQ0FBQztZQUNELE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQztBQXJDRCw0REFxQ0M7QUFFRCxLQUFLLFVBQVUsVUFBVSxDQUFDLElBQWMsRUFBRSxRQUFxQjtJQUM3RCxNQUFNLElBQUksR0FBRyxJQUFBLGtCQUFNLEVBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2pDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUNwQixJQUFJLENBQUM7UUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDeEUsQ0FBQztZQUFTLENBQUM7UUFDVCxJQUFBLHdCQUFVLEVBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3RCLENBQUM7QUFDSCxDQUFDO0FBRVksUUFBQSxrQkFBa0IsR0FBaUIsd0JBQXdCLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogZGV0YWNoL2RyaXZlcnMvc2V0SW1tZWRpYXRlLnRzIOKAlCBEZWZlciBkZXRhY2hlZCB3b3JrIHRvIGEgTm9kZS5qc1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYHNldEltbWVkaWF0ZWAgYm91bmRhcnkuXG4gKlxuICogUGF0dGVybjogIFNhbWUgcHJvZHVjZXItY29uc3VtZXIgYmF0Y2ggZmx1c2ggYXMgYG1pY3JvdGFza0JhdGNoYCxcbiAqICAgICAgICAgICBidXQgdGhlIGRlZmVycmFsIGlzIGBzZXRJbW1lZGlhdGVgIGluc3RlYWQgb2ZcbiAqICAgICAgICAgICBgcXVldWVNaWNyb3Rhc2tgLiBZaWVsZHMgY29udHJvbCBiYWNrIHRvIHRoZSBldmVudCBsb29wXG4gKiAgICAgICAgICAgQkVGT1JFIHJ1bm5pbmcg4oCUIGFsbG93cyBwZW5kaW5nIEkvTyBjYWxsYmFja3MgdG8gZHJhaW5cbiAqICAgICAgICAgICBmaXJzdCwgd2hpY2ggbWljcm90YXNrcyB3b3VsZCBibG9jay5cbiAqIFJvbGU6ICAgICBOb2RlLXNwZWNpZmljIGRyaXZlciBmb3IgXCJmaXJlLWFuZC1mb3JnZXQgYWZ0ZXIgdGhlXG4gKiAgICAgICAgICAgY3VycmVudCBJL08gdGljay5cIiBVc2Ugd2hlbiB0aGUgcGFyZW50IHN0YWdlIGhhbmRsZXNcbiAqICAgICAgICAgICBsYXRlbmN5LXNlbnNpdGl2ZSB3b3JrIGFuZCB5b3UgZG9uJ3Qgd2FudCBkZXRhY2hlZCB3b3JrXG4gKiAgICAgICAgICAgdG8gY29tcGV0ZSBmb3IgdGhlIHN5bmNocm9ub3VzIHNsaWNlLlxuICpcbiAqIFdoZW4gdG8gcGljayB0aGlzIG92ZXIgbWljcm90YXNrQmF0Y2g6XG4gKiAgIC0gWW91J3JlIHNoaXBwaW5nIGxvZ3MgLyBtZXRyaWNzIGluIGEgaG90IEhUVFAgcGF0aCBhbmQgZG9uJ3RcbiAqICAgICB3YW50IHRoZW0gYmxvY2tpbmcgdGhlIHJlc3BvbnNlIGZyb20gYmVpbmcgZmx1c2hlZFxuICogICAtIFRoZSBkZXRhY2hlZCB3b3JrIGl0c2VsZiBpcyBDUFUtaGVhdnkgZW5vdWdoIHRoYXQgcnVubmluZyBpdCBvblxuICogICAgIHRoZSBzYW1lIG1pY3JvdGFzayBjeWNsZSB3b3VsZCBkZWxheSBvdGhlciBtaWNyb3Rhc2tzXG4gKiAgIC0gWW91IGV4cGxpY2l0bHkgd2FudCBcIm5leHQgZXZlbnQtbG9vcCB0aWNrXCIgc2VtYW50aWNzIOKAlCB1c2VmdWxcbiAqICAgICB3aGVuIGludGVyYWN0aW5nIHdpdGggdGhpcmQtcGFydHkgbGlicmFyaWVzIHRoYXQgZXhwZWN0IGF0XG4gKiAgICAgbGVhc3Qgb25lIEkvTyB0aWNrIGJldHdlZW4gc2NoZWR1bGUgYW5kIGV4ZWN1dGlvblxuICpcbiAqIENhcGFiaWxpdHk6XG4gKiAgIC0gYG5vZGVTYWZlOiB0cnVlYCDigJQgcmVsaWVzIG9uIE5vZGUncyBgc2V0SW1tZWRpYXRlYCwgTk9UXG4gKiAgICAgYXZhaWxhYmxlIGluIGJyb3dzZXJzIC8gRGVubyAvIENsb3VkZmxhcmUgV29ya2VycyAodXNlXG4gKiAgICAgYHNldFRpbWVvdXREcml2ZXJgIGZvciBjcm9zcy1ydW50aW1lIGFsdGVybmF0aXZlKVxuICovXG5cbmltcG9ydCB0eXBlIHsgRmxvd0NoYXJ0IH0gZnJvbSAnLi4vLi4vYnVpbGRlci90eXBlcy5qcyc7XG5pbXBvcnQgeyBhc0ltcGwsIGNyZWF0ZUhhbmRsZSB9IGZyb20gJy4uL2hhbmRsZS5qcyc7XG5pbXBvcnQgeyByZWdpc3RlciwgdW5yZWdpc3RlciB9IGZyb20gJy4uL3JlZ2lzdHJ5LmpzJztcbmltcG9ydCB7IHR5cGUgQ2hpbGRSdW5uZXIsIGRlZmF1bHRSdW5DaGlsZCB9IGZyb20gJy4uL3J1bkNoaWxkLmpzJztcbmltcG9ydCB0eXBlIHsgRGV0YWNoRHJpdmVyLCBEZXRhY2hIYW5kbGUgfSBmcm9tICcuLi90eXBlcy5qcyc7XG5cbi8vIE5vZGUtb25seSBnbG9iYWwuIFdlIGRvbid0IHNoaXAgQHR5cGVzL25vZGUsIHNvIGRlY2xhcmUgdGhlIG1pbmltYWxcbi8vIHNoYXBlIGhlcmUuIGBzZXRJbW1lZGlhdGVEcml2ZXJgIGFkdmVydGlzZXMgYG5vZGVTYWZlOiB0cnVlYCBhbmRcbi8vIGB2YWxpZGF0ZSgpYCB0aHJvd3MgaGVscGZ1bGx5IGlmIGBzZXRJbW1lZGlhdGVgIGlzIHVuZGVmaW5lZCBhdCB1c2Vcbi8vIHRpbWUgKGUuZy4sIGJyb3dzZXIgYnVuZGxlKS5cbmRlY2xhcmUgY29uc3Qgc2V0SW1tZWRpYXRlOiAoKGNiOiAoKSA9PiB2b2lkKSA9PiB1bmtub3duKSB8IHVuZGVmaW5lZDtcblxuaW50ZXJmYWNlIFdvcmtJdGVtIHtcbiAgcmVhZG9ubHkgY2hpbGQ6IEZsb3dDaGFydDtcbiAgcmVhZG9ubHkgaW5wdXQ6IHVua25vd247XG4gIHJlYWRvbmx5IGhhbmRsZTogRGV0YWNoSGFuZGxlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU2V0SW1tZWRpYXRlRHJpdmVyKHJ1bkNoaWxkOiBDaGlsZFJ1bm5lciA9IGRlZmF1bHRSdW5DaGlsZCk6IERldGFjaERyaXZlciB7XG4gIGNvbnN0IHF1ZXVlOiBXb3JrSXRlbVtdID0gW107XG4gIGxldCBzY2hlZHVsZWQgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBmbHVzaCgpOiB2b2lkIHtcbiAgICBzY2hlZHVsZWQgPSBmYWxzZTtcbiAgICBjb25zdCBpdGVtcyA9IHF1ZXVlLnNwbGljZSgwKTtcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgIGV4ZWN1dGVPbmUoaXRlbSwgcnVuQ2hpbGQpLnRoZW4odW5kZWZpbmVkLCB1bmRlZmluZWQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbmFtZTogJ3NldC1pbW1lZGlhdGUnLFxuICAgIGNhcGFiaWxpdGllczogeyBub2RlU2FmZTogdHJ1ZSB9LFxuICAgIHZhbGlkYXRlKCk6IHZvaWQge1xuICAgICAgaWYgKHR5cGVvZiBzZXRJbW1lZGlhdGUgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdbZGV0YWNoXSBzZXRJbW1lZGlhdGVEcml2ZXIgcmVxdWlyZXMgTm9kZS5qcyDigJQgZ2xvYmFsIGBzZXRJbW1lZGlhdGVgIGlzIG5vdCBkZWZpbmVkICcgK1xuICAgICAgICAgICAgJ2luIHRoaXMgcnVudGltZS4gVXNlIGBtaWNyb3Rhc2tCYXRjaERyaXZlcmAgZm9yIGNyb3NzLXJ1bnRpbWUgdXNlLCBvciBgc2V0VGltZW91dERyaXZlcmAgJyArXG4gICAgICAgICAgICAnZm9yIGJyb3dzZXIvZWRnZSBlbnZpcm9ubWVudHMuJyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIHNjaGVkdWxlKGNoaWxkOiBGbG93Q2hhcnQsIGlucHV0OiB1bmtub3duLCByZWZJZDogc3RyaW5nKTogRGV0YWNoSGFuZGxlIHtcbiAgICAgIGNvbnN0IGhhbmRsZSA9IGNyZWF0ZUhhbmRsZShyZWZJZCk7XG4gICAgICByZWdpc3RlcihoYW5kbGUpO1xuICAgICAgcXVldWUucHVzaCh7IGNoaWxkLCBpbnB1dCwgaGFuZGxlIH0pO1xuICAgICAgaWYgKCFzY2hlZHVsZWQpIHtcbiAgICAgICAgc2NoZWR1bGVkID0gdHJ1ZTtcbiAgICAgICAgLy8gYHNldEltbWVkaWF0ZWAgaXMgbm9uLXVuZGVmaW5lZCBoZXJlIGluIE5vZGU7IHJ1bnRpbWUgZ3VhcmRcbiAgICAgICAgLy8gaXMgaW4gYHZhbGlkYXRlKClgLiBUaGUgYCFgIGlzIGEgZGVsaWJlcmF0ZSBhc3NlcnRpb24uXG4gICAgICAgIHNldEltbWVkaWF0ZSEoZmx1c2gpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhbmRsZTtcbiAgICB9LFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBleGVjdXRlT25lKGl0ZW06IFdvcmtJdGVtLCBydW5DaGlsZDogQ2hpbGRSdW5uZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgaW1wbCA9IGFzSW1wbChpdGVtLmhhbmRsZSk7XG4gIGltcGwuX21hcmtSdW5uaW5nKCk7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcnVuQ2hpbGQoaXRlbS5jaGlsZCwgaXRlbS5pbnB1dCk7XG4gICAgaW1wbC5fbWFya0RvbmUocmVzdWx0KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgaW1wbC5fbWFya0ZhaWxlZChlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyKSkpO1xuICB9IGZpbmFsbHkge1xuICAgIHVucmVnaXN0ZXIoaW1wbC5pZCk7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNldEltbWVkaWF0ZURyaXZlcjogRGV0YWNoRHJpdmVyID0gY3JlYXRlU2V0SW1tZWRpYXRlRHJpdmVyKCk7XG4iXX0=
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ /**
3
+ * detach/drivers/setTimeout.ts — Defer detached work via `setTimeout(..., delayMs)`.
4
+ *
5
+ * Pattern: Producer-consumer batch flush; deferral mechanism is
6
+ * `setTimeout` with a configurable delay (default `0`).
7
+ * Role: Cross-runtime "next macrotask" driver. Works in browsers,
8
+ * Node.js, Deno, Cloudflare Workers, Bun, etc.
9
+ *
10
+ * When to pick this:
11
+ * - Consumer wants a SPECIFIC delay (e.g. "ship telemetry in 5
12
+ * seconds, batched") — pass `createSetTimeoutDriver({ delayMs: 5000 })`
13
+ * - Cross-runtime detach where `setImmediate` isn't available
14
+ * - Coalescing high-frequency events into a low-frequency flush
15
+ *
16
+ * Caveats:
17
+ * - Not for low-latency hot paths — minimum delay is ~4ms in
18
+ * browsers per the HTML5 spec, ~1ms in Node. Use
19
+ * `microtaskBatchDriver` for sub-ms scheduling.
20
+ * - Browser tab freezing / throttling can extend the delay
21
+ * significantly. Don't rely on precise timing.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.setTimeoutDriver = exports.createSetTimeoutDriver = void 0;
25
+ const handle_js_1 = require("../handle.js");
26
+ const registry_js_1 = require("../registry.js");
27
+ const runChild_js_1 = require("../runChild.js");
28
+ function createSetTimeoutDriver(opts = {}) {
29
+ const delayMs = opts.delayMs ?? 0;
30
+ const runChild = opts.runChild ?? runChild_js_1.defaultRunChild;
31
+ const queue = [];
32
+ let scheduled = false;
33
+ function flush() {
34
+ scheduled = false;
35
+ const items = queue.splice(0);
36
+ for (const item of items) {
37
+ executeOne(item, runChild).then(undefined, undefined);
38
+ }
39
+ }
40
+ return {
41
+ name: delayMs === 0 ? 'set-timeout' : `set-timeout-${delayMs}ms`,
42
+ capabilities: { browserSafe: true, nodeSafe: true, edgeSafe: true },
43
+ schedule(child, input, refId) {
44
+ const handle = (0, handle_js_1.createHandle)(refId);
45
+ (0, registry_js_1.register)(handle);
46
+ queue.push({ child, input, handle });
47
+ if (!scheduled) {
48
+ scheduled = true;
49
+ setTimeout(flush, delayMs);
50
+ }
51
+ return handle;
52
+ },
53
+ };
54
+ }
55
+ exports.createSetTimeoutDriver = createSetTimeoutDriver;
56
+ async function executeOne(item, runChild) {
57
+ const impl = (0, handle_js_1.asImpl)(item.handle);
58
+ impl._markRunning();
59
+ try {
60
+ const result = await runChild(item.child, item.input);
61
+ impl._markDone(result);
62
+ }
63
+ catch (err) {
64
+ impl._markFailed(err instanceof Error ? err : new Error(String(err)));
65
+ }
66
+ finally {
67
+ (0, registry_js_1.unregister)(impl.id);
68
+ }
69
+ }
70
+ /** Default singleton — zero-delay (next macrotask). For configurable
71
+ * delays, use `createSetTimeoutDriver({ delayMs })`. */
72
+ exports.setTimeoutDriver = createSetTimeoutDriver();
73
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0VGltZW91dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZGV0YWNoL2RyaXZlcnMvc2V0VGltZW91dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHOzs7QUFHSCw0Q0FBb0Q7QUFDcEQsZ0RBQXNEO0FBQ3RELGdEQUFtRTtBQWlCbkUsU0FBZ0Isc0JBQXNCLENBQUMsT0FBZ0MsRUFBRTtJQUN2RSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQztJQUNsQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLDZCQUFlLENBQUM7SUFDbEQsTUFBTSxLQUFLLEdBQWUsRUFBRSxDQUFDO0lBQzdCLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQztJQUV0QixTQUFTLEtBQUs7UUFDWixTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ2xCLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUIsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUN6QixVQUFVLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDeEQsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPO1FBQ0wsSUFBSSxFQUFFLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsZUFBZSxPQUFPLElBQUk7UUFDaEUsWUFBWSxFQUFFLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7UUFDbkUsUUFBUSxDQUFDLEtBQWdCLEVBQUUsS0FBYyxFQUFFLEtBQWE7WUFDdEQsTUFBTSxNQUFNLEdBQUcsSUFBQSx3QkFBWSxFQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ25DLElBQUEsc0JBQVEsRUFBQyxNQUFNLENBQUMsQ0FBQztZQUNqQixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDZixTQUFTLEdBQUcsSUFBSSxDQUFDO2dCQUNqQixVQUFVLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQzdCLENBQUM7WUFDRCxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUE1QkQsd0RBNEJDO0FBRUQsS0FBSyxVQUFVLFVBQVUsQ0FBQyxJQUFjLEVBQUUsUUFBcUI7SUFDN0QsTUFBTSxJQUFJLEdBQUcsSUFBQSxrQkFBTSxFQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNqQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDcEIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7WUFBUyxDQUFDO1FBQ1QsSUFBQSx3QkFBVSxFQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN0QixDQUFDO0FBQ0gsQ0FBQztBQUVEO3lEQUN5RDtBQUM1QyxRQUFBLGdCQUFnQixHQUFpQixzQkFBc0IsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBkZXRhY2gvZHJpdmVycy9zZXRUaW1lb3V0LnRzIOKAlCBEZWZlciBkZXRhY2hlZCB3b3JrIHZpYSBgc2V0VGltZW91dCguLi4sIGRlbGF5TXMpYC5cbiAqXG4gKiBQYXR0ZXJuOiAgUHJvZHVjZXItY29uc3VtZXIgYmF0Y2ggZmx1c2g7IGRlZmVycmFsIG1lY2hhbmlzbSBpc1xuICogICAgICAgICAgIGBzZXRUaW1lb3V0YCB3aXRoIGEgY29uZmlndXJhYmxlIGRlbGF5IChkZWZhdWx0IGAwYCkuXG4gKiBSb2xlOiAgICAgQ3Jvc3MtcnVudGltZSBcIm5leHQgbWFjcm90YXNrXCIgZHJpdmVyLiBXb3JrcyBpbiBicm93c2VycyxcbiAqICAgICAgICAgICBOb2RlLmpzLCBEZW5vLCBDbG91ZGZsYXJlIFdvcmtlcnMsIEJ1biwgZXRjLlxuICpcbiAqIFdoZW4gdG8gcGljayB0aGlzOlxuICogICAtIENvbnN1bWVyIHdhbnRzIGEgU1BFQ0lGSUMgZGVsYXkgKGUuZy4gXCJzaGlwIHRlbGVtZXRyeSBpbiA1XG4gKiAgICAgc2Vjb25kcywgYmF0Y2hlZFwiKSDigJQgcGFzcyBgY3JlYXRlU2V0VGltZW91dERyaXZlcih7IGRlbGF5TXM6IDUwMDAgfSlgXG4gKiAgIC0gQ3Jvc3MtcnVudGltZSBkZXRhY2ggd2hlcmUgYHNldEltbWVkaWF0ZWAgaXNuJ3QgYXZhaWxhYmxlXG4gKiAgIC0gQ29hbGVzY2luZyBoaWdoLWZyZXF1ZW5jeSBldmVudHMgaW50byBhIGxvdy1mcmVxdWVuY3kgZmx1c2hcbiAqXG4gKiBDYXZlYXRzOlxuICogICAtIE5vdCBmb3IgbG93LWxhdGVuY3kgaG90IHBhdGhzIOKAlCBtaW5pbXVtIGRlbGF5IGlzIH40bXMgaW5cbiAqICAgICBicm93c2VycyBwZXIgdGhlIEhUTUw1IHNwZWMsIH4xbXMgaW4gTm9kZS4gVXNlXG4gKiAgICAgYG1pY3JvdGFza0JhdGNoRHJpdmVyYCBmb3Igc3ViLW1zIHNjaGVkdWxpbmcuXG4gKiAgIC0gQnJvd3NlciB0YWIgZnJlZXppbmcgLyB0aHJvdHRsaW5nIGNhbiBleHRlbmQgdGhlIGRlbGF5XG4gKiAgICAgc2lnbmlmaWNhbnRseS4gRG9uJ3QgcmVseSBvbiBwcmVjaXNlIHRpbWluZy5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEZsb3dDaGFydCB9IGZyb20gJy4uLy4uL2J1aWxkZXIvdHlwZXMuanMnO1xuaW1wb3J0IHsgYXNJbXBsLCBjcmVhdGVIYW5kbGUgfSBmcm9tICcuLi9oYW5kbGUuanMnO1xuaW1wb3J0IHsgcmVnaXN0ZXIsIHVucmVnaXN0ZXIgfSBmcm9tICcuLi9yZWdpc3RyeS5qcyc7XG5pbXBvcnQgeyB0eXBlIENoaWxkUnVubmVyLCBkZWZhdWx0UnVuQ2hpbGQgfSBmcm9tICcuLi9ydW5DaGlsZC5qcyc7XG5pbXBvcnQgdHlwZSB7IERldGFjaERyaXZlciwgRGV0YWNoSGFuZGxlIH0gZnJvbSAnLi4vdHlwZXMuanMnO1xuXG5pbnRlcmZhY2UgV29ya0l0ZW0ge1xuICByZWFkb25seSBjaGlsZDogRmxvd0NoYXJ0O1xuICByZWFkb25seSBpbnB1dDogdW5rbm93bjtcbiAgcmVhZG9ubHkgaGFuZGxlOiBEZXRhY2hIYW5kbGU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2V0VGltZW91dERyaXZlck9wdGlvbnMge1xuICAvKiogTWlsbGlzZWNvbmRzIHRvIHdhaXQgYmVmb3JlIGZsdXNoaW5nIHRoZSBiYXRjaC4gRGVmYXVsdCAwXG4gICAqICAobmV4dCBtYWNyb3Rhc2spLiAqL1xuICByZWFkb25seSBkZWxheU1zPzogbnVtYmVyO1xuICAvKiogQ3VzdG9tIGBydW5DaGlsZGAuIERlZmF1bHRzIHRvIHNwYXduaW5nIGEgYEZsb3dDaGFydEV4ZWN1dG9yYC4gKi9cbiAgcmVhZG9ubHkgcnVuQ2hpbGQ/OiBDaGlsZFJ1bm5lcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNldFRpbWVvdXREcml2ZXIob3B0czogU2V0VGltZW91dERyaXZlck9wdGlvbnMgPSB7fSk6IERldGFjaERyaXZlciB7XG4gIGNvbnN0IGRlbGF5TXMgPSBvcHRzLmRlbGF5TXMgPz8gMDtcbiAgY29uc3QgcnVuQ2hpbGQgPSBvcHRzLnJ1bkNoaWxkID8/IGRlZmF1bHRSdW5DaGlsZDtcbiAgY29uc3QgcXVldWU6IFdvcmtJdGVtW10gPSBbXTtcbiAgbGV0IHNjaGVkdWxlZCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGZsdXNoKCk6IHZvaWQge1xuICAgIHNjaGVkdWxlZCA9IGZhbHNlO1xuICAgIGNvbnN0IGl0ZW1zID0gcXVldWUuc3BsaWNlKDApO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgZXhlY3V0ZU9uZShpdGVtLCBydW5DaGlsZCkudGhlbih1bmRlZmluZWQsIHVuZGVmaW5lZCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBkZWxheU1zID09PSAwID8gJ3NldC10aW1lb3V0JyA6IGBzZXQtdGltZW91dC0ke2RlbGF5TXN9bXNgLFxuICAgIGNhcGFiaWxpdGllczogeyBicm93c2VyU2FmZTogdHJ1ZSwgbm9kZVNhZmU6IHRydWUsIGVkZ2VTYWZlOiB0cnVlIH0sXG4gICAgc2NoZWR1bGUoY2hpbGQ6IEZsb3dDaGFydCwgaW5wdXQ6IHVua25vd24sIHJlZklkOiBzdHJpbmcpOiBEZXRhY2hIYW5kbGUge1xuICAgICAgY29uc3QgaGFuZGxlID0gY3JlYXRlSGFuZGxlKHJlZklkKTtcbiAgICAgIHJlZ2lzdGVyKGhhbmRsZSk7XG4gICAgICBxdWV1ZS5wdXNoKHsgY2hpbGQsIGlucHV0LCBoYW5kbGUgfSk7XG4gICAgICBpZiAoIXNjaGVkdWxlZCkge1xuICAgICAgICBzY2hlZHVsZWQgPSB0cnVlO1xuICAgICAgICBzZXRUaW1lb3V0KGZsdXNoLCBkZWxheU1zKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgfSxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZU9uZShpdGVtOiBXb3JrSXRlbSwgcnVuQ2hpbGQ6IENoaWxkUnVubmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGltcGwgPSBhc0ltcGwoaXRlbS5oYW5kbGUpO1xuICBpbXBsLl9tYXJrUnVubmluZygpO1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJ1bkNoaWxkKGl0ZW0uY2hpbGQsIGl0ZW0uaW5wdXQpO1xuICAgIGltcGwuX21hcmtEb25lKHJlc3VsdCk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGltcGwuX21hcmtGYWlsZWQoZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIgOiBuZXcgRXJyb3IoU3RyaW5nKGVycikpKTtcbiAgfSBmaW5hbGx5IHtcbiAgICB1bnJlZ2lzdGVyKGltcGwuaWQpO1xuICB9XG59XG5cbi8qKiBEZWZhdWx0IHNpbmdsZXRvbiDigJQgemVyby1kZWxheSAobmV4dCBtYWNyb3Rhc2spLiBGb3IgY29uZmlndXJhYmxlXG4gKiAgZGVsYXlzLCB1c2UgYGNyZWF0ZVNldFRpbWVvdXREcml2ZXIoeyBkZWxheU1zIH0pYC4gKi9cbmV4cG9ydCBjb25zdCBzZXRUaW1lb3V0RHJpdmVyOiBEZXRhY2hEcml2ZXIgPSBjcmVhdGVTZXRUaW1lb3V0RHJpdmVyKCk7XG4iXX0=
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ /**
3
+ * detach/drivers/workerThread.ts — Run detached work in a Node.js
4
+ * Worker Thread (or browser Web Worker).
5
+ *
6
+ * Pattern: Adapter — translates the consumer's child flowchart into
7
+ * a worker message + lifecycle handoff. The worker is owned
8
+ * by the driver instance; restarted on crash.
9
+ * Role: CPU-isolation driver — when detached work is genuinely
10
+ * expensive (heavy parsing, hashing, image processing) and
11
+ * you don't want it blocking the main thread's event loop
12
+ * even for a microtask burst.
13
+ *
14
+ * Caveats / IMPORTANT v1 limitations:
15
+ * - The worker entry point is a CONSUMER-PROVIDED file path / URL —
16
+ * this driver does NOT auto-spawn FlowChartExecutor in a worker.
17
+ * Workers can't `import('footprintjs')` portably without setup,
18
+ * and the worker file's lifecycle differs by runtime
19
+ * (Node Worker vs Web Worker vs Bun). Consumer writes the worker
20
+ * code; this driver just hands them a uniform `(input, handle)`
21
+ * API.
22
+ * - The "child flowchart" parameter is IGNORED in v1 (we only ship
23
+ * the input). The chart shape doesn't survive structuredClone +
24
+ * postMessage anyway. v2 may add a serialization protocol.
25
+ *
26
+ * Two ways to consume:
27
+ *
28
+ * 1. Node.js: pass a file path
29
+ * `createWorkerThreadDriver({ workerScript: '/path/to/worker.js' })`
30
+ *
31
+ * 2. Browser: pass a URL or pre-built Worker instance
32
+ * `createWorkerThreadDriver({ worker: new Worker(url) })`
33
+ */
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.createWorkerThreadDriver = void 0;
36
+ const handle_js_1 = require("../handle.js");
37
+ const registry_js_1 = require("../registry.js");
38
+ let nextMessageId = 0;
39
+ function createWorkerThreadDriver(opts) {
40
+ let worker;
41
+ const inFlight = new Map();
42
+ // If consumer provided a Worker at construction time, bind its
43
+ // 'message' handler eagerly so replies are routed back to handles.
44
+ // Lazy construction (via `workerScript`) defers binding to first use.
45
+ if (opts.worker) {
46
+ worker = opts.worker;
47
+ bindWorker(worker, inFlight);
48
+ }
49
+ function ensureWorker() {
50
+ if (worker)
51
+ return worker;
52
+ if (!opts.workerScript) {
53
+ throw new Error('[detach] workerThreadDriver: provide either `worker` (a constructed Worker) ' +
54
+ 'or `workerScript` (a path/URL) at driver creation.');
55
+ }
56
+ // Lazy-import Node's worker_threads — keeps browser bundles clean.
57
+ if (typeof require !== 'function') {
58
+ throw new Error('[detach] workerThreadDriver: `workerScript` requires Node.js (CommonJS `require`).');
59
+ }
60
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
61
+ const { Worker } = require('worker_threads');
62
+ worker = new Worker(opts.workerScript);
63
+ bindWorker(worker, inFlight);
64
+ return worker;
65
+ }
66
+ return {
67
+ name: 'worker-thread',
68
+ capabilities: { nodeSafe: true, cpuIsolated: true },
69
+ validate() {
70
+ if (!opts.worker && !opts.workerScript) {
71
+ throw new Error('[detach] workerThreadDriver requires either a pre-built `worker` or a `workerScript` path.');
72
+ }
73
+ },
74
+ schedule(_child, input, refId) {
75
+ const handle = (0, handle_js_1.createHandle)(refId);
76
+ (0, registry_js_1.register)(handle);
77
+ const impl = (0, handle_js_1.asImpl)(handle);
78
+ impl._markRunning();
79
+ const messageId = nextMessageId++;
80
+ inFlight.set(messageId, { handle });
81
+ try {
82
+ const w = ensureWorker();
83
+ w.postMessage({ messageId, refId, input });
84
+ }
85
+ catch (err) {
86
+ impl._markFailed(err instanceof Error ? err : new Error(String(err)));
87
+ (0, registry_js_1.unregister)(impl.id);
88
+ inFlight.delete(messageId);
89
+ }
90
+ return handle;
91
+ },
92
+ };
93
+ }
94
+ exports.createWorkerThreadDriver = createWorkerThreadDriver;
95
+ function bindWorker(worker, inFlight) {
96
+ const handler = (msg) => {
97
+ const m = msg;
98
+ if (!m || typeof m.messageId !== 'number')
99
+ return;
100
+ const slot = inFlight.get(m.messageId);
101
+ if (!slot)
102
+ return;
103
+ inFlight.delete(m.messageId);
104
+ const impl = (0, handle_js_1.asImpl)(slot.handle);
105
+ if (m.ok) {
106
+ impl._markDone(m.result);
107
+ }
108
+ else {
109
+ impl._markFailed(new Error(m.error ?? 'worker reported failure'));
110
+ }
111
+ (0, registry_js_1.unregister)(impl.id);
112
+ };
113
+ // Node Worker (worker_threads): EventEmitter-shape (`on('message', ...)`).
114
+ if (typeof worker.on === 'function')
115
+ worker.on('message', handler);
116
+ // Browser Worker / Web Worker: EventTarget-shape (`addEventListener`).
117
+ else if (typeof worker.addEventListener === 'function') {
118
+ worker.addEventListener('message', (evt) => handler(evt?.data));
119
+ }
120
+ }
121
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2VyVGhyZWFkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9kZXRhY2gvZHJpdmVycy93b3JrZXJUaHJlYWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBK0JHOzs7QUFHSCw0Q0FBb0Q7QUFDcEQsZ0RBQXNEO0FBNkJ0RCxJQUFJLGFBQWEsR0FBRyxDQUFDLENBQUM7QUFFdEIsU0FBZ0Isd0JBQXdCLENBQUMsSUFBK0I7SUFDdEUsSUFBSSxNQUE4QixDQUFDO0lBQ25DLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxFQUFvQixDQUFDO0lBRTdDLCtEQUErRDtJQUMvRCxtRUFBbUU7SUFDbkUsc0VBQXNFO0lBQ3RFLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2hCLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3JCLFVBQVUsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVELFNBQVMsWUFBWTtRQUNuQixJQUFJLE1BQU07WUFBRSxPQUFPLE1BQU0sQ0FBQztRQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQ2IsOEVBQThFO2dCQUM1RSxvREFBb0QsQ0FDdkQsQ0FBQztRQUNKLENBQUM7UUFDRCxtRUFBbUU7UUFDbkUsSUFBSSxPQUFPLE9BQU8sS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUNsQyxNQUFNLElBQUksS0FBSyxDQUFDLG9GQUFvRixDQUFDLENBQUM7UUFDeEcsQ0FBQztRQUNELGlFQUFpRTtRQUNqRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixDQUE4QyxDQUFDO1FBQzFGLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdkMsVUFBVSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUM3QixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQsT0FBTztRQUNMLElBQUksRUFBRSxlQUFlO1FBQ3JCLFlBQVksRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRTtRQUNuRCxRQUFRO1lBQ04sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3ZDLE1BQU0sSUFBSSxLQUFLLENBQUMsNEZBQTRGLENBQUMsQ0FBQztZQUNoSCxDQUFDO1FBQ0gsQ0FBQztRQUNELFFBQVEsQ0FBQyxNQUFpQixFQUFFLEtBQWMsRUFBRSxLQUFhO1lBQ3ZELE1BQU0sTUFBTSxHQUFHLElBQUEsd0JBQVksRUFBQyxLQUFLLENBQUMsQ0FBQztZQUNuQyxJQUFBLHNCQUFRLEVBQUMsTUFBTSxDQUFDLENBQUM7WUFDakIsTUFBTSxJQUFJLEdBQUcsSUFBQSxrQkFBTSxFQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzVCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUVwQixNQUFNLFNBQVMsR0FBRyxhQUFhLEVBQUUsQ0FBQztZQUNsQyxRQUFRLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFFcEMsSUFBSSxDQUFDO2dCQUNILE1BQU0sQ0FBQyxHQUFHLFlBQVksRUFBRSxDQUFDO2dCQUN6QixDQUFDLENBQUMsV0FBVyxDQUFDLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQzdDLENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN0RSxJQUFBLHdCQUFVLEVBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNwQixRQUFRLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzdCLENBQUM7WUFFRCxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUE1REQsNERBNERDO0FBRUQsU0FBUyxVQUFVLENBQUMsTUFBa0IsRUFBRSxRQUErQjtJQUNyRSxNQUFNLE9BQU8sR0FBRyxDQUFDLEdBQVksRUFBUSxFQUFFO1FBQ3JDLE1BQU0sQ0FBQyxHQUFHLEdBQXlGLENBQUM7UUFDcEcsSUFBSSxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxTQUFTLEtBQUssUUFBUTtZQUFFLE9BQU87UUFDbEQsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdkMsSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPO1FBQ2xCLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRTdCLE1BQU0sSUFBSSxHQUFHLElBQUEsa0JBQU0sRUFBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDVCxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMzQixDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSx5QkFBeUIsQ0FBQyxDQUFDLENBQUM7UUFDcEUsQ0FBQztRQUNELElBQUEsd0JBQVUsRUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDdEIsQ0FBQyxDQUFDO0lBRUYsMkVBQTJFO0lBQzNFLElBQUksT0FBTyxNQUFNLENBQUMsRUFBRSxLQUFLLFVBQVU7UUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNuRSx1RUFBdUU7U0FDbEUsSUFBSSxPQUFPLE1BQU0sQ0FBQyxnQkFBZ0IsS0FBSyxVQUFVLEVBQUUsQ0FBQztRQUN2RCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLENBQUMsR0FBWSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUUsR0FBMEIsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ25HLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBkZXRhY2gvZHJpdmVycy93b3JrZXJUaHJlYWQudHMg4oCUIFJ1biBkZXRhY2hlZCB3b3JrIGluIGEgTm9kZS5qc1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV29ya2VyIFRocmVhZCAob3IgYnJvd3NlciBXZWIgV29ya2VyKS5cbiAqXG4gKiBQYXR0ZXJuOiAgQWRhcHRlciDigJQgdHJhbnNsYXRlcyB0aGUgY29uc3VtZXIncyBjaGlsZCBmbG93Y2hhcnQgaW50b1xuICogICAgICAgICAgIGEgd29ya2VyIG1lc3NhZ2UgKyBsaWZlY3ljbGUgaGFuZG9mZi4gVGhlIHdvcmtlciBpcyBvd25lZFxuICogICAgICAgICAgIGJ5IHRoZSBkcml2ZXIgaW5zdGFuY2U7IHJlc3RhcnRlZCBvbiBjcmFzaC5cbiAqIFJvbGU6ICAgICBDUFUtaXNvbGF0aW9uIGRyaXZlciDigJQgd2hlbiBkZXRhY2hlZCB3b3JrIGlzIGdlbnVpbmVseVxuICogICAgICAgICAgIGV4cGVuc2l2ZSAoaGVhdnkgcGFyc2luZywgaGFzaGluZywgaW1hZ2UgcHJvY2Vzc2luZykgYW5kXG4gKiAgICAgICAgICAgeW91IGRvbid0IHdhbnQgaXQgYmxvY2tpbmcgdGhlIG1haW4gdGhyZWFkJ3MgZXZlbnQgbG9vcFxuICogICAgICAgICAgIGV2ZW4gZm9yIGEgbWljcm90YXNrIGJ1cnN0LlxuICpcbiAqIENhdmVhdHMgLyBJTVBPUlRBTlQgdjEgbGltaXRhdGlvbnM6XG4gKiAgIC0gVGhlIHdvcmtlciBlbnRyeSBwb2ludCBpcyBhIENPTlNVTUVSLVBST1ZJREVEIGZpbGUgcGF0aCAvIFVSTCDigJRcbiAqICAgICB0aGlzIGRyaXZlciBkb2VzIE5PVCBhdXRvLXNwYXduIEZsb3dDaGFydEV4ZWN1dG9yIGluIGEgd29ya2VyLlxuICogICAgIFdvcmtlcnMgY2FuJ3QgYGltcG9ydCgnZm9vdHByaW50anMnKWAgcG9ydGFibHkgd2l0aG91dCBzZXR1cCxcbiAqICAgICBhbmQgdGhlIHdvcmtlciBmaWxlJ3MgbGlmZWN5Y2xlIGRpZmZlcnMgYnkgcnVudGltZVxuICogICAgIChOb2RlIFdvcmtlciB2cyBXZWIgV29ya2VyIHZzIEJ1bikuIENvbnN1bWVyIHdyaXRlcyB0aGUgd29ya2VyXG4gKiAgICAgY29kZTsgdGhpcyBkcml2ZXIganVzdCBoYW5kcyB0aGVtIGEgdW5pZm9ybSBgKGlucHV0LCBoYW5kbGUpYFxuICogICAgIEFQSS5cbiAqICAgLSBUaGUgXCJjaGlsZCBmbG93Y2hhcnRcIiBwYXJhbWV0ZXIgaXMgSUdOT1JFRCBpbiB2MSAod2Ugb25seSBzaGlwXG4gKiAgICAgdGhlIGlucHV0KS4gVGhlIGNoYXJ0IHNoYXBlIGRvZXNuJ3Qgc3Vydml2ZSBzdHJ1Y3R1cmVkQ2xvbmUgK1xuICogICAgIHBvc3RNZXNzYWdlIGFueXdheS4gdjIgbWF5IGFkZCBhIHNlcmlhbGl6YXRpb24gcHJvdG9jb2wuXG4gKlxuICogVHdvIHdheXMgdG8gY29uc3VtZTpcbiAqXG4gKiAgIDEuIE5vZGUuanM6IHBhc3MgYSBmaWxlIHBhdGhcbiAqICAgICAgYGNyZWF0ZVdvcmtlclRocmVhZERyaXZlcih7IHdvcmtlclNjcmlwdDogJy9wYXRoL3RvL3dvcmtlci5qcycgfSlgXG4gKlxuICogICAyLiBCcm93c2VyOiBwYXNzIGEgVVJMIG9yIHByZS1idWlsdCBXb3JrZXIgaW5zdGFuY2VcbiAqICAgICAgYGNyZWF0ZVdvcmtlclRocmVhZERyaXZlcih7IHdvcmtlcjogbmV3IFdvcmtlcih1cmwpIH0pYFxuICovXG5cbmltcG9ydCB0eXBlIHsgRmxvd0NoYXJ0IH0gZnJvbSAnLi4vLi4vYnVpbGRlci90eXBlcy5qcyc7XG5pbXBvcnQgeyBhc0ltcGwsIGNyZWF0ZUhhbmRsZSB9IGZyb20gJy4uL2hhbmRsZS5qcyc7XG5pbXBvcnQgeyByZWdpc3RlciwgdW5yZWdpc3RlciB9IGZyb20gJy4uL3JlZ2lzdHJ5LmpzJztcbmltcG9ydCB0eXBlIHsgRGV0YWNoRHJpdmVyLCBEZXRhY2hIYW5kbGUgfSBmcm9tICcuLi90eXBlcy5qcyc7XG5cbi8vIE5vZGUtb25seSBDb21tb25KUyBgcmVxdWlyZWAuIFdlIGRvbid0IHNoaXAgQHR5cGVzL25vZGUsIHNvIGRlY2xhcmVcbi8vIHRoZSBtaW5pbWFsIHNoYXBlIGhlcmUuIFVzZWQgb25seSBpbiB0aGUgbGF6eSBgd29ya2VyU2NyaXB0YCBwYXRoO1xuLy8gYnJvd3NlciBjb25zdW1lcnMgcGFzcyBhIHByZS1jb25zdHJ1Y3RlZCBgV29ya2VyYCBhbmQgbmV2ZXIgaGl0IGl0LlxuZGVjbGFyZSBjb25zdCByZXF1aXJlOiAoKG1vZDogc3RyaW5nKSA9PiB1bmtub3duKSB8IHVuZGVmaW5lZDtcblxuaW50ZXJmYWNlIFdvcmtlckxpa2Uge1xuICBwb3N0TWVzc2FnZShtZXNzYWdlOiB1bmtub3duLCB0cmFuc2Zlcj86IFRyYW5zZmVyYWJsZVtdKTogdm9pZDtcbiAgdGVybWluYXRlPygpOiB1bmtub3duO1xuICBvbj8oZXZlbnQ6IHN0cmluZywgbGlzdGVuZXI6IChtc2c6IHVua25vd24pID0+IHZvaWQpOiB2b2lkO1xuICBhZGRFdmVudExpc3RlbmVyPyhldmVudDogc3RyaW5nLCBsaXN0ZW5lcjogKG1zZzogdW5rbm93bikgPT4gdm9pZCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgV29ya2VyVGhyZWFkRHJpdmVyT3B0aW9ucyB7XG4gIC8qKiBQcmUtY29uc3RydWN0ZWQgV29ya2VyIGluc3RhbmNlLiBQYXNzIGVpdGhlciB0aGlzIE9SXG4gICAqICBgd29ya2VyU2NyaXB0YCDigJQgbm90IGJvdGguICovXG4gIHJlYWRvbmx5IHdvcmtlcj86IFdvcmtlckxpa2U7XG4gIC8qKiBQYXRoIC8gVVJMIHRvIHRoZSB3b3JrZXIgc2NyaXB0LiBVc2VkIG9ubHkgd2hlbiBgd29ya2VyYCBpc1xuICAgKiAgbm90IHByb3ZpZGVkOyB0aGUgZHJpdmVyIGNvbnN0cnVjdHMgYSBXb3JrZXIgZnJvbSB0aGlzIG9uIGRlbWFuZFxuICAgKiAgKE5vZGUgYHdvcmtlcl90aHJlYWRzYCBBUEkpLiAqL1xuICByZWFkb25seSB3b3JrZXJTY3JpcHQ/OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBJbkZsaWdodCB7XG4gIHJlYWRvbmx5IGhhbmRsZTogRGV0YWNoSGFuZGxlO1xufVxuXG5sZXQgbmV4dE1lc3NhZ2VJZCA9IDA7XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVXb3JrZXJUaHJlYWREcml2ZXIob3B0czogV29ya2VyVGhyZWFkRHJpdmVyT3B0aW9ucyk6IERldGFjaERyaXZlciB7XG4gIGxldCB3b3JrZXI6IFdvcmtlckxpa2UgfCB1bmRlZmluZWQ7XG4gIGNvbnN0IGluRmxpZ2h0ID0gbmV3IE1hcDxudW1iZXIsIEluRmxpZ2h0PigpO1xuXG4gIC8vIElmIGNvbnN1bWVyIHByb3ZpZGVkIGEgV29ya2VyIGF0IGNvbnN0cnVjdGlvbiB0aW1lLCBiaW5kIGl0c1xuICAvLyAnbWVzc2FnZScgaGFuZGxlciBlYWdlcmx5IHNvIHJlcGxpZXMgYXJlIHJvdXRlZCBiYWNrIHRvIGhhbmRsZXMuXG4gIC8vIExhenkgY29uc3RydWN0aW9uICh2aWEgYHdvcmtlclNjcmlwdGApIGRlZmVycyBiaW5kaW5nIHRvIGZpcnN0IHVzZS5cbiAgaWYgKG9wdHMud29ya2VyKSB7XG4gICAgd29ya2VyID0gb3B0cy53b3JrZXI7XG4gICAgYmluZFdvcmtlcih3b3JrZXIsIGluRmxpZ2h0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVuc3VyZVdvcmtlcigpOiBXb3JrZXJMaWtlIHtcbiAgICBpZiAod29ya2VyKSByZXR1cm4gd29ya2VyO1xuICAgIGlmICghb3B0cy53b3JrZXJTY3JpcHQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1tkZXRhY2hdIHdvcmtlclRocmVhZERyaXZlcjogcHJvdmlkZSBlaXRoZXIgYHdvcmtlcmAgKGEgY29uc3RydWN0ZWQgV29ya2VyKSAnICtcbiAgICAgICAgICAnb3IgYHdvcmtlclNjcmlwdGAgKGEgcGF0aC9VUkwpIGF0IGRyaXZlciBjcmVhdGlvbi4nLFxuICAgICAgKTtcbiAgICB9XG4gICAgLy8gTGF6eS1pbXBvcnQgTm9kZSdzIHdvcmtlcl90aHJlYWRzIOKAlCBrZWVwcyBicm93c2VyIGJ1bmRsZXMgY2xlYW4uXG4gICAgaWYgKHR5cGVvZiByZXF1aXJlICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1tkZXRhY2hdIHdvcmtlclRocmVhZERyaXZlcjogYHdvcmtlclNjcmlwdGAgcmVxdWlyZXMgTm9kZS5qcyAoQ29tbW9uSlMgYHJlcXVpcmVgKS4nKTtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICBjb25zdCB7IFdvcmtlciB9ID0gcmVxdWlyZSgnd29ya2VyX3RocmVhZHMnKSBhcyB7IFdvcmtlcjogbmV3IChzOiBzdHJpbmcpID0+IFdvcmtlckxpa2UgfTtcbiAgICB3b3JrZXIgPSBuZXcgV29ya2VyKG9wdHMud29ya2VyU2NyaXB0KTtcbiAgICBiaW5kV29ya2VyKHdvcmtlciwgaW5GbGlnaHQpO1xuICAgIHJldHVybiB3b3JrZXI7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICd3b3JrZXItdGhyZWFkJyxcbiAgICBjYXBhYmlsaXRpZXM6IHsgbm9kZVNhZmU6IHRydWUsIGNwdUlzb2xhdGVkOiB0cnVlIH0sXG4gICAgdmFsaWRhdGUoKTogdm9pZCB7XG4gICAgICBpZiAoIW9wdHMud29ya2VyICYmICFvcHRzLndvcmtlclNjcmlwdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1tkZXRhY2hdIHdvcmtlclRocmVhZERyaXZlciByZXF1aXJlcyBlaXRoZXIgYSBwcmUtYnVpbHQgYHdvcmtlcmAgb3IgYSBgd29ya2VyU2NyaXB0YCBwYXRoLicpO1xuICAgICAgfVxuICAgIH0sXG4gICAgc2NoZWR1bGUoX2NoaWxkOiBGbG93Q2hhcnQsIGlucHV0OiB1bmtub3duLCByZWZJZDogc3RyaW5nKTogRGV0YWNoSGFuZGxlIHtcbiAgICAgIGNvbnN0IGhhbmRsZSA9IGNyZWF0ZUhhbmRsZShyZWZJZCk7XG4gICAgICByZWdpc3RlcihoYW5kbGUpO1xuICAgICAgY29uc3QgaW1wbCA9IGFzSW1wbChoYW5kbGUpO1xuICAgICAgaW1wbC5fbWFya1J1bm5pbmcoKTtcblxuICAgICAgY29uc3QgbWVzc2FnZUlkID0gbmV4dE1lc3NhZ2VJZCsrO1xuICAgICAgaW5GbGlnaHQuc2V0KG1lc3NhZ2VJZCwgeyBoYW5kbGUgfSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHcgPSBlbnN1cmVXb3JrZXIoKTtcbiAgICAgICAgdy5wb3N0TWVzc2FnZSh7IG1lc3NhZ2VJZCwgcmVmSWQsIGlucHV0IH0pO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGltcGwuX21hcmtGYWlsZWQoZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIgOiBuZXcgRXJyb3IoU3RyaW5nKGVycikpKTtcbiAgICAgICAgdW5yZWdpc3RlcihpbXBsLmlkKTtcbiAgICAgICAgaW5GbGlnaHQuZGVsZXRlKG1lc3NhZ2VJZCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gYmluZFdvcmtlcih3b3JrZXI6IFdvcmtlckxpa2UsIGluRmxpZ2h0OiBNYXA8bnVtYmVyLCBJbkZsaWdodD4pOiB2b2lkIHtcbiAgY29uc3QgaGFuZGxlciA9IChtc2c6IHVua25vd24pOiB2b2lkID0+IHtcbiAgICBjb25zdCBtID0gbXNnIGFzIHsgbWVzc2FnZUlkPzogbnVtYmVyOyBvaz86IGJvb2xlYW47IHJlc3VsdD86IHVua25vd247IGVycm9yPzogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XG4gICAgaWYgKCFtIHx8IHR5cGVvZiBtLm1lc3NhZ2VJZCAhPT0gJ251bWJlcicpIHJldHVybjtcbiAgICBjb25zdCBzbG90ID0gaW5GbGlnaHQuZ2V0KG0ubWVzc2FnZUlkKTtcbiAgICBpZiAoIXNsb3QpIHJldHVybjtcbiAgICBpbkZsaWdodC5kZWxldGUobS5tZXNzYWdlSWQpO1xuXG4gICAgY29uc3QgaW1wbCA9IGFzSW1wbChzbG90LmhhbmRsZSk7XG4gICAgaWYgKG0ub2spIHtcbiAgICAgIGltcGwuX21hcmtEb25lKG0ucmVzdWx0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW1wbC5fbWFya0ZhaWxlZChuZXcgRXJyb3IobS5lcnJvciA/PyAnd29ya2VyIHJlcG9ydGVkIGZhaWx1cmUnKSk7XG4gICAgfVxuICAgIHVucmVnaXN0ZXIoaW1wbC5pZCk7XG4gIH07XG5cbiAgLy8gTm9kZSBXb3JrZXIgKHdvcmtlcl90aHJlYWRzKTogRXZlbnRFbWl0dGVyLXNoYXBlIChgb24oJ21lc3NhZ2UnLCAuLi4pYCkuXG4gIGlmICh0eXBlb2Ygd29ya2VyLm9uID09PSAnZnVuY3Rpb24nKSB3b3JrZXIub24oJ21lc3NhZ2UnLCBoYW5kbGVyKTtcbiAgLy8gQnJvd3NlciBXb3JrZXIgLyBXZWIgV29ya2VyOiBFdmVudFRhcmdldC1zaGFwZSAoYGFkZEV2ZW50TGlzdGVuZXJgKS5cbiAgZWxzZSBpZiAodHlwZW9mIHdvcmtlci5hZGRFdmVudExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgd29ya2VyLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCAoZXZ0OiB1bmtub3duKSA9PiBoYW5kbGVyKChldnQgYXMgeyBkYXRhPzogdW5rbm93biB9KT8uZGF0YSkpO1xuICB9XG59XG4iXX0=