@workflow/core 5.0.0-beta.5 → 5.0.0-beta.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/attribute-changes.d.ts +5 -0
- package/dist/attribute-changes.d.ts.map +1 -0
- package/dist/attribute-changes.js +25 -0
- package/dist/capabilities.d.ts +35 -2
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +74 -5
- package/dist/capture-stack.d.ts +1 -1
- package/dist/capture-stack.js +2 -2
- package/dist/class-serialization.d.ts +32 -0
- package/dist/class-serialization.d.ts.map +1 -1
- package/dist/class-serialization.js +37 -1
- package/dist/classify-error.d.ts +19 -3
- package/dist/classify-error.d.ts.map +1 -1
- package/dist/classify-error.js +98 -6
- package/dist/context-violation-error.d.ts +5 -5
- package/dist/context-violation-error.d.ts.map +1 -1
- package/dist/context-violation-error.js +8 -6
- package/dist/create-hook.d.ts +72 -7
- package/dist/create-hook.d.ts.map +1 -1
- package/dist/create-hook.js +1 -1
- package/dist/define-hook.js +2 -2
- package/dist/describe-error.d.ts +7 -7
- package/dist/describe-error.d.ts.map +1 -1
- package/dist/describe-error.js +97 -12
- package/dist/encryption.d.ts +38 -4
- package/dist/encryption.d.ts.map +1 -1
- package/dist/encryption.js +96 -14
- package/dist/events-consumer.d.ts +297 -0
- package/dist/events-consumer.d.ts.map +1 -1
- package/dist/events-consumer.js +673 -42
- package/dist/flushable-stream.d.ts +97 -1
- package/dist/flushable-stream.d.ts.map +1 -1
- package/dist/flushable-stream.js +291 -11
- package/dist/global.d.ts +36 -2
- package/dist/global.d.ts.map +1 -1
- package/dist/global.js +21 -6
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/log-format.d.ts +2 -2
- package/dist/log-format.js +19 -12
- package/dist/logger.d.ts +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +10 -6
- package/dist/private.d.ts +226 -9
- package/dist/private.d.ts.map +1 -1
- package/dist/private.js +626 -7
- package/dist/replay-divergence.d.ts +25 -0
- package/dist/replay-divergence.d.ts.map +1 -0
- package/dist/replay-divergence.js +61 -0
- package/dist/replay-payload-cache.d.ts +64 -0
- package/dist/replay-payload-cache.d.ts.map +1 -0
- package/dist/replay-payload-cache.js +158 -0
- package/dist/runtime/compute-instance.d.ts +13 -0
- package/dist/runtime/compute-instance.d.ts.map +1 -0
- package/dist/runtime/compute-instance.js +14 -0
- package/dist/runtime/constants.d.ts +315 -0
- package/dist/runtime/constants.d.ts.map +1 -1
- package/dist/runtime/constants.js +502 -16
- package/dist/runtime/count-step-started-events.d.ts +52 -0
- package/dist/runtime/count-step-started-events.d.ts.map +1 -0
- package/dist/runtime/count-step-started-events.js +72 -0
- package/dist/runtime/deployment-guard.d.ts +99 -0
- package/dist/runtime/deployment-guard.d.ts.map +1 -0
- package/dist/runtime/deployment-guard.js +154 -0
- package/dist/runtime/get-port-lazy.d.ts +15 -0
- package/dist/runtime/get-port-lazy.d.ts.map +1 -1
- package/dist/runtime/get-port-lazy.js +75 -6
- package/dist/runtime/get-world-lazy.d.ts +5 -14
- package/dist/runtime/get-world-lazy.d.ts.map +1 -1
- package/dist/runtime/get-world-lazy.js +19 -29
- package/dist/runtime/helpers.d.ts +415 -29
- package/dist/runtime/helpers.d.ts.map +1 -1
- package/dist/runtime/helpers.js +686 -57
- package/dist/runtime/quickjs-assets.generated.d.ts +14 -0
- package/dist/runtime/quickjs-assets.generated.d.ts.map +1 -0
- package/dist/runtime/quickjs-assets.generated.js +30 -0
- package/dist/runtime/quickjs-entrypoint.d.ts +158 -0
- package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -0
- package/dist/runtime/quickjs-entrypoint.js +1863 -0
- package/dist/runtime/quickjs-log-view.d.ts +129 -0
- package/dist/runtime/quickjs-log-view.d.ts.map +1 -0
- package/dist/runtime/quickjs-log-view.js +229 -0
- package/dist/runtime/quickjs-runtime.d.ts +244 -0
- package/dist/runtime/quickjs-runtime.d.ts.map +1 -0
- package/dist/runtime/quickjs-runtime.js +2427 -0
- package/dist/runtime/quickjs-serde.d.ts +107 -0
- package/dist/runtime/quickjs-serde.d.ts.map +1 -0
- package/dist/runtime/quickjs-serde.js +2159 -0
- package/dist/runtime/replay-budget.d.ts +97 -0
- package/dist/runtime/replay-budget.d.ts.map +1 -0
- package/dist/runtime/replay-budget.js +139 -0
- package/dist/runtime/replay-recovery-reporter.d.ts +36 -0
- package/dist/runtime/replay-recovery-reporter.d.ts.map +1 -0
- package/dist/runtime/replay-recovery-reporter.js +64 -0
- package/dist/runtime/resume-hook.d.ts +91 -8
- package/dist/runtime/resume-hook.d.ts.map +1 -1
- package/dist/runtime/resume-hook.js +512 -89
- package/dist/runtime/resume-latency.d.ts +150 -0
- package/dist/runtime/resume-latency.d.ts.map +1 -0
- package/dist/runtime/resume-latency.js +155 -0
- package/dist/runtime/run-id-time.d.ts +19 -0
- package/dist/runtime/run-id-time.d.ts.map +1 -0
- package/dist/runtime/run-id-time.js +42 -0
- package/dist/runtime/run.d.ts +72 -7
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js +280 -53
- package/dist/runtime/runs.d.ts +54 -3
- package/dist/runtime/runs.d.ts.map +1 -1
- package/dist/runtime/runs.js +126 -16
- package/dist/runtime/start.d.ts +101 -2
- package/dist/runtime/start.d.ts.map +1 -1
- package/dist/runtime/start.js +352 -61
- package/dist/runtime/step-executor.d.ts +186 -5
- package/dist/runtime/step-executor.d.ts.map +1 -1
- package/dist/runtime/step-executor.js +768 -130
- package/dist/runtime/step-latency.d.ts +220 -0
- package/dist/runtime/step-latency.d.ts.map +1 -0
- package/dist/runtime/step-latency.js +215 -0
- package/dist/runtime/step-ownership.d.ts +72 -0
- package/dist/runtime/step-ownership.d.ts.map +1 -0
- package/dist/runtime/step-ownership.js +114 -0
- package/dist/runtime/step-single-flight.d.ts +12 -0
- package/dist/runtime/step-single-flight.d.ts.map +1 -0
- package/dist/runtime/step-single-flight.js +75 -0
- package/dist/runtime/suspension-handler.d.ts +247 -7
- package/dist/runtime/suspension-handler.d.ts.map +1 -1
- package/dist/runtime/suspension-handler.js +1304 -125
- package/dist/runtime/unserializable-step.d.ts +34 -0
- package/dist/runtime/unserializable-step.d.ts.map +1 -0
- package/dist/runtime/unserializable-step.js +52 -0
- package/dist/runtime/vm-mode.d.ts +44 -0
- package/dist/runtime/vm-mode.d.ts.map +1 -0
- package/dist/runtime/vm-mode.js +62 -0
- package/dist/runtime/vm-serde-bundle.generated.d.ts +14 -0
- package/dist/runtime/vm-serde-bundle.generated.d.ts.map +1 -0
- package/dist/runtime/vm-serde-bundle.generated.js +16 -0
- package/dist/runtime/wait-continuation.d.ts +106 -0
- package/dist/runtime/wait-continuation.d.ts.map +1 -0
- package/dist/runtime/wait-continuation.js +136 -0
- package/dist/runtime/wait-until.d.ts +18 -0
- package/dist/runtime/wait-until.d.ts.map +1 -0
- package/dist/runtime/wait-until.js +42 -0
- package/dist/runtime/world-compatibility.d.ts +32 -0
- package/dist/runtime/world-compatibility.d.ts.map +1 -0
- package/dist/runtime/world-compatibility.js +44 -0
- package/dist/runtime/world-init.d.ts +17 -42
- package/dist/runtime/world-init.d.ts.map +1 -1
- package/dist/runtime/world-init.js +18 -43
- package/dist/runtime/world.d.ts +14 -2
- package/dist/runtime/world.d.ts.map +1 -1
- package/dist/runtime/world.js +75 -19
- package/dist/runtime.d.ts +10 -6
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +3911 -489
- package/dist/sealed-box.d.ts +167 -0
- package/dist/sealed-box.d.ts.map +1 -0
- package/dist/sealed-box.js +571 -0
- package/dist/serialization/client.d.ts +3 -3
- package/dist/serialization/client.d.ts.map +1 -1
- package/dist/serialization/client.js +8 -4
- package/dist/serialization/codec-devalue-vm.d.ts +16 -0
- package/dist/serialization/codec-devalue-vm.d.ts.map +1 -0
- package/dist/serialization/codec-devalue-vm.js +148 -0
- package/dist/serialization/codec-devalue.d.ts +1 -1
- package/dist/serialization/codec-devalue.d.ts.map +1 -1
- package/dist/serialization/codec-devalue.js +24 -6
- package/dist/serialization/codec.d.ts +37 -2
- package/dist/serialization/codec.d.ts.map +1 -1
- package/dist/serialization/codec.js +2 -2
- package/dist/serialization/compression.d.ts +105 -0
- package/dist/serialization/compression.d.ts.map +1 -0
- package/dist/serialization/compression.js +261 -0
- package/dist/serialization/encryption.d.ts +119 -17
- package/dist/serialization/encryption.d.ts.map +1 -1
- package/dist/serialization/encryption.js +152 -17
- package/dist/serialization/errors.d.ts +13 -0
- package/dist/serialization/errors.d.ts.map +1 -1
- package/dist/serialization/errors.js +20 -2
- package/dist/serialization/format.d.ts +6 -6
- package/dist/serialization/format.js +7 -7
- package/dist/serialization/hardened.d.ts +156 -0
- package/dist/serialization/hardened.d.ts.map +1 -0
- package/dist/serialization/hardened.js +538 -0
- package/dist/serialization/index.d.ts +10 -8
- package/dist/serialization/index.d.ts.map +1 -1
- package/dist/serialization/index.js +10 -8
- package/dist/serialization/reducers/class-vm.d.ts +20 -0
- package/dist/serialization/reducers/class-vm.d.ts.map +1 -0
- package/dist/serialization/reducers/class-vm.js +77 -0
- package/dist/serialization/reducers/class.d.ts.map +1 -1
- package/dist/serialization/reducers/class.js +11 -6
- package/dist/serialization/reducers/common-vm.d.ts +15 -0
- package/dist/serialization/reducers/common-vm.d.ts.map +1 -0
- package/dist/serialization/reducers/common-vm.js +616 -0
- package/dist/serialization/reducers/common.d.ts +1 -1
- package/dist/serialization/reducers/common.d.ts.map +1 -1
- package/dist/serialization/reducers/common.js +202 -62
- package/dist/serialization/reducers/step-function-vm.d.ts +44 -0
- package/dist/serialization/reducers/step-function-vm.d.ts.map +1 -0
- package/dist/serialization/reducers/step-function-vm.js +97 -0
- package/dist/serialization/reducers/step-function.d.ts.map +1 -1
- package/dist/serialization/reducers/step-function.js +25 -9
- package/dist/serialization/step.d.ts +4 -4
- package/dist/serialization/step.d.ts.map +1 -1
- package/dist/serialization/step.js +9 -5
- package/dist/serialization/types.d.ts +80 -1
- package/dist/serialization/types.d.ts.map +1 -1
- package/dist/serialization/types.js +15 -1
- package/dist/serialization/workflow-vm.d.ts +29 -0
- package/dist/serialization/workflow-vm.d.ts.map +1 -0
- package/dist/serialization/workflow-vm.js +74 -0
- package/dist/serialization-format.d.ts +64 -8
- package/dist/serialization-format.d.ts.map +1 -1
- package/dist/serialization-format.js +225 -73
- package/dist/serialization.d.ts +262 -34
- package/dist/serialization.d.ts.map +1 -1
- package/dist/serialization.js +1885 -277
- package/dist/set-attributes.d.ts +13 -0
- package/dist/set-attributes.d.ts.map +1 -0
- package/dist/set-attributes.js +60 -0
- package/dist/source-map.d.ts +25 -0
- package/dist/source-map.d.ts.map +1 -1
- package/dist/source-map.js +154 -10
- package/dist/step/context-storage.d.ts +63 -2
- package/dist/step/context-storage.d.ts.map +1 -1
- package/dist/step/context-storage.js +7 -5
- package/dist/step/writable-stream.d.ts +3 -3
- package/dist/step/writable-stream.d.ts.map +1 -1
- package/dist/step/writable-stream.js +80 -13
- package/dist/step.d.ts.map +1 -1
- package/dist/step.js +148 -27
- package/dist/symbols.d.ts +50 -0
- package/dist/symbols.d.ts.map +1 -1
- package/dist/symbols.js +51 -1
- package/dist/telemetry/semantic-conventions.d.ts +433 -2
- package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
- package/dist/telemetry/semantic-conventions.js +319 -3
- package/dist/telemetry.d.ts +91 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +244 -17
- package/dist/test-support/orchestrator-context.d.ts +25 -0
- package/dist/test-support/orchestrator-context.d.ts.map +1 -0
- package/dist/test-support/orchestrator-context.js +107 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +23 -1
- package/dist/util.d.ts +0 -5
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +1 -15
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +2 -2
- package/dist/vm/index.d.ts.map +1 -1
- package/dist/vm/index.js +84 -14
- package/dist/vm/script-cache.d.ts +26 -0
- package/dist/vm/script-cache.d.ts.map +1 -0
- package/dist/vm/script-cache.js +131 -0
- package/dist/vm/uint8array-base64.js +1 -1
- package/dist/workflow/abort-controller.d.ts +2 -2
- package/dist/workflow/abort-controller.d.ts.map +1 -1
- package/dist/workflow/abort-controller.js +88 -21
- package/dist/workflow/attribute-dispatcher.d.ts +6 -0
- package/dist/workflow/attribute-dispatcher.d.ts.map +1 -0
- package/dist/workflow/attribute-dispatcher.js +45 -0
- package/dist/workflow/create-hook.d.ts.map +1 -1
- package/dist/workflow/create-hook.js +24 -3
- package/dist/workflow/get-workflow-metadata.js +2 -2
- package/dist/workflow/hook.d.ts.map +1 -1
- package/dist/workflow/hook.js +304 -47
- package/dist/workflow/index.d.ts +1 -0
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +2 -1
- package/dist/workflow/set-attributes.d.ts +68 -0
- package/dist/workflow/set-attributes.d.ts.map +1 -0
- package/dist/workflow/set-attributes.js +60 -0
- package/dist/workflow/sleep.d.ts.map +1 -1
- package/dist/workflow/sleep.js +58 -12
- package/dist/workflow/world-init-stub.d.ts +3 -3
- package/dist/workflow/world-init-stub.js +4 -4
- package/dist/workflow.d.ts +95 -3
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +900 -561
- package/docs/api-reference/create-hook.mdx +89 -10
- package/docs/api-reference/create-webhook.mdx +16 -15
- package/docs/api-reference/define-hook.mdx +35 -33
- package/docs/api-reference/fatal-error.mdx +30 -8
- package/docs/api-reference/fetch.mdx +14 -10
- package/docs/api-reference/get-step-metadata.mdx +2 -2
- package/docs/api-reference/get-workflow-metadata.mdx +3 -3
- package/docs/api-reference/get-writable.mdx +7 -7
- package/docs/api-reference/index.mdx +4 -1
- package/docs/api-reference/retryable-error.mdx +1 -1
- package/docs/api-reference/set-attributes.mdx +61 -0
- package/docs/api-reference/sleep.mdx +4 -4
- package/docs/foundations/cancellation.mdx +31 -32
- package/docs/foundations/errors-and-retries.mdx +42 -11
- package/docs/foundations/hooks.mdx +64 -35
- package/docs/foundations/idempotency.mdx +244 -12
- package/docs/foundations/index.mdx +1 -23
- package/docs/foundations/meta.json +2 -1
- package/docs/foundations/serialization.mdx +21 -22
- package/docs/foundations/starting-workflows.mdx +106 -30
- package/docs/foundations/streaming.mdx +108 -60
- package/docs/foundations/versioning.mdx +263 -0
- package/docs/foundations/workflows-and-steps.mdx +9 -9
- package/docs/how-it-works/cancellation.mdx +63 -63
- package/docs/how-it-works/code-transform.mdx +83 -67
- package/docs/how-it-works/encryption.mdx +30 -26
- package/docs/how-it-works/event-sourcing.mdx +125 -34
- package/docs/how-it-works/framework-integrations.mdx +96 -337
- package/docs/how-it-works/understanding-directives.mdx +22 -22
- package/package.json +24 -15
- package/dist/runtime/step-handler.d.ts +0 -2
- package/dist/runtime/step-handler.d.ts.map +0 -1
- package/dist/runtime/step-handler.js +0 -776
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { type Event } from '@workflow/world';
|
|
2
|
+
/**
|
|
3
|
+
* The QuickJS engine's bookkeeping for the run's event log, giving that engine
|
|
4
|
+
* the same relationship to a World's write responses that the node:vm replay
|
|
5
|
+
* loop has.
|
|
6
|
+
*
|
|
7
|
+
* The node engine holds the log as an array it replays from, so a page a World
|
|
8
|
+
* hands back on a write (a skipped-slot report against `eventCount`, or an
|
|
9
|
+
* inline delta against `sinceCursor`; see `CreateEventParams` in
|
|
10
|
+
* `@workflow/world`) is merged into that array and the next replay reads it
|
|
11
|
+
* there. The QuickJS engine holds a LIVE VM instead: events are delivered to it
|
|
12
|
+
* incrementally through `continueWithEvents`, in log order, exactly once. So
|
|
13
|
+
* for this engine a returned page is not merged into a log; it is queued to be
|
|
14
|
+
* delivered. This class owns that queue and the three numbers around it:
|
|
15
|
+
*
|
|
16
|
+
* - `knownMaxSlot`, the highest position this invocation has seen anywhere
|
|
17
|
+
* (fed, buffered, or its own write). Reported as `eventCount` on every write
|
|
18
|
+
* this invocation makes from its view of the log, so the World can hand
|
|
19
|
+
* back what landed above it.
|
|
20
|
+
* - `fedMaxSlot`, the highest position delivered to the VM. Delivery is
|
|
21
|
+
* strictly in position order with no gaps, because the VM consumes events
|
|
22
|
+
* as they arrive and a later replay will read the log in position order;
|
|
23
|
+
* feeding position 13 before 12 exists would let the two disagree.
|
|
24
|
+
* - `cursor`, the read position for `events.list`, advanced by list pages and
|
|
25
|
+
* by a complete inline delta.
|
|
26
|
+
*
|
|
27
|
+
* Only PAGES are queued for delivery, never the created event a write returns
|
|
28
|
+
* on its own. A World reads a report or a delta the way it reads a listing,
|
|
29
|
+
* with payload refs resolved, so those events are what a listing would have
|
|
30
|
+
* delivered. The created event on a create response is not: a World may hand
|
|
31
|
+
* it back with its payload still a ref descriptor and telemetry fields
|
|
32
|
+
* stripped (the Vercel World does, for every type whose entity the runtime
|
|
33
|
+
* does not read off the response), and a VM given that copy of a `step_failed`
|
|
34
|
+
* sees a step that failed with no error in it. The created event still counts
|
|
35
|
+
* toward the position the next write names; it is delivered by the page that
|
|
36
|
+
* covers it or by the next listing. `deliverEvent` opts a write in when its
|
|
37
|
+
* event carries nothing a VM reads (`wait_completed`).
|
|
38
|
+
*
|
|
39
|
+
* Positions come from slot-numbered event ids. A log whose ids are not slots
|
|
40
|
+
* (a World on the old id scheme, or a mocked World) turns tracking off for the
|
|
41
|
+
* rest of the invocation: no `eventCount` is sent, nothing is buffered, and the
|
|
42
|
+
* engine reads the log back the way it did before any of this existed.
|
|
43
|
+
*/
|
|
44
|
+
export declare class QuickJSLogView {
|
|
45
|
+
private slotTracking;
|
|
46
|
+
private knownMaxSlot;
|
|
47
|
+
private fedMaxSlot;
|
|
48
|
+
/** Events handed back by a World that the VM has not been given yet. */
|
|
49
|
+
private readonly unfed;
|
|
50
|
+
private cursor;
|
|
51
|
+
constructor(fedEvents: readonly Event[], cursor: string | null);
|
|
52
|
+
/** Read position for the next `events.list`, or `null` for the start. */
|
|
53
|
+
get logCursor(): string | null;
|
|
54
|
+
/** How many events are queued for delivery to the VM. */
|
|
55
|
+
get bufferedCount(): number;
|
|
56
|
+
/** Whether positions are being tracked (see class doc). */
|
|
57
|
+
get tracking(): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* The `eventCount` to attach to a write made from this view. Empty while no
|
|
60
|
+
* position is known (an empty log) or once tracking has been turned off.
|
|
61
|
+
*/
|
|
62
|
+
snapshotParams(): {
|
|
63
|
+
eventCount?: number;
|
|
64
|
+
};
|
|
65
|
+
/** A page of `events.list` was read to `cursor`. */
|
|
66
|
+
advanceCursor(cursor: string | null): void;
|
|
67
|
+
/**
|
|
68
|
+
* Events delivered to the VM by the caller (the initial load, or an
|
|
69
|
+
* `events.list` page). Removes them from the delivery queue if a write
|
|
70
|
+
* response had already handed them back.
|
|
71
|
+
*/
|
|
72
|
+
markFed(events: readonly Event[]): void;
|
|
73
|
+
/**
|
|
74
|
+
* Absorb a write's response: note the committed event's position, and
|
|
75
|
+
* queue the skipped-slot report a World attached to it.
|
|
76
|
+
*
|
|
77
|
+
* A truncated page (`hasMore`) is dropped whole, the same policy as
|
|
78
|
+
* `absorbSkippedSlotReport` in the node engine: it covers a span of
|
|
79
|
+
* positions but carries only some of them, and queuing part of a span
|
|
80
|
+
* would have this view claim, on its next write, to have seen positions it
|
|
81
|
+
* never received. The committed event is queued only under `deliverEvent`
|
|
82
|
+
* (see the class doc for why not by default); its position always counts.
|
|
83
|
+
*/
|
|
84
|
+
absorb(result: {
|
|
85
|
+
event?: Event;
|
|
86
|
+
events?: readonly Event[];
|
|
87
|
+
hasMore?: boolean;
|
|
88
|
+
}, options?: {
|
|
89
|
+
deliverEvent?: boolean;
|
|
90
|
+
}): {
|
|
91
|
+
queued: number;
|
|
92
|
+
truncated: boolean;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Absorb the inline delta a step-terminal write returned for
|
|
96
|
+
* `sinceCursor`, and advance the read cursor past it when that is safe.
|
|
97
|
+
*
|
|
98
|
+
* The delta is everything after `sentCursor`, so it may be taken only if
|
|
99
|
+
* the view still stands at that cursor (a list in between would have moved
|
|
100
|
+
* it, and appending a delta computed from an older position could deliver
|
|
101
|
+
* events behind ones already fed). The cursor advances only when the queue
|
|
102
|
+
* then holds every position between what the VM has and the delta's end:
|
|
103
|
+
* with a hole in between, a later `events.list` from the advanced cursor
|
|
104
|
+
* would never return the missing event and the VM would stall on it.
|
|
105
|
+
*
|
|
106
|
+
* @returns whether the cursor was advanced.
|
|
107
|
+
*/
|
|
108
|
+
absorbDelta(sentCursor: string, delta: {
|
|
109
|
+
events: readonly Event[];
|
|
110
|
+
cursor: string | null;
|
|
111
|
+
hasMore: boolean;
|
|
112
|
+
}): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Drain the events that can be delivered to the VM now: the queued run of
|
|
115
|
+
* consecutive positions directly above the highest one already fed. A queued
|
|
116
|
+
* event above a position nothing has filled yet stays queued until a list
|
|
117
|
+
* fills the gap.
|
|
118
|
+
*/
|
|
119
|
+
takeContiguous(): Event[];
|
|
120
|
+
private queueIsDense;
|
|
121
|
+
/** Queue one event for delivery unless the VM already has it. */
|
|
122
|
+
private queue;
|
|
123
|
+
/**
|
|
124
|
+
* The event's position, bumping `knownMaxSlot`. `undefined` once an id
|
|
125
|
+
* turns out not to be a slot, which turns tracking off for good.
|
|
126
|
+
*/
|
|
127
|
+
private slotOf;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=quickjs-log-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quickjs-log-view.d.ts","sourceRoot":"","sources":["../../src/runtime/quickjs-log-view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAmC,MAAM,iBAAiB,CAAC;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,UAAU,CAAqB;IACvC,wEAAwE;IACxE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA4B;IAClD,OAAO,CAAC,MAAM,CAAgB;gBAElB,SAAS,EAAE,SAAS,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAK9D,yEAAyE;IACzE,IAAI,SAAS,IAAI,MAAM,GAAG,IAAI,CAE7B;IAED,yDAAyD;IACzD,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,2DAA2D;IAC3D,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;OAGG;IACH,cAAc,IAAI;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;IAMzC,oDAAoD;IACpD,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAM1C;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,IAAI;IAWvC;;;;;;;;;;OAUG;IACH,MAAM,CACJ,MAAM,EAAE;QACN,KAAK,CAAC,EAAE,KAAK,CAAC;QACd,MAAM,CAAC,EAAE,SAAS,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,EACD,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAO,GACvC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE;IAsBzC;;;;;;;;;;;;;OAaG;IACH,WAAW,CACT,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE;QAAE,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,GAC3E,OAAO;IAiBV;;;;;OAKG;IACH,cAAc,IAAI,KAAK,EAAE;IAqBzB,OAAO,CAAC,YAAY;IAQpB,iEAAiE;IACjE,OAAO,CAAC,KAAK;IAWb;;;OAGG;IACH,OAAO,CAAC,MAAM;CAef"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { eventIdToSlot, FIRST_EVENT_SLOT } from '@workflow/world';
|
|
2
|
+
/**
|
|
3
|
+
* The QuickJS engine's bookkeeping for the run's event log, giving that engine
|
|
4
|
+
* the same relationship to a World's write responses that the node:vm replay
|
|
5
|
+
* loop has.
|
|
6
|
+
*
|
|
7
|
+
* The node engine holds the log as an array it replays from, so a page a World
|
|
8
|
+
* hands back on a write (a skipped-slot report against `eventCount`, or an
|
|
9
|
+
* inline delta against `sinceCursor`; see `CreateEventParams` in
|
|
10
|
+
* `@workflow/world`) is merged into that array and the next replay reads it
|
|
11
|
+
* there. The QuickJS engine holds a LIVE VM instead: events are delivered to it
|
|
12
|
+
* incrementally through `continueWithEvents`, in log order, exactly once. So
|
|
13
|
+
* for this engine a returned page is not merged into a log; it is queued to be
|
|
14
|
+
* delivered. This class owns that queue and the three numbers around it:
|
|
15
|
+
*
|
|
16
|
+
* - `knownMaxSlot`, the highest position this invocation has seen anywhere
|
|
17
|
+
* (fed, buffered, or its own write). Reported as `eventCount` on every write
|
|
18
|
+
* this invocation makes from its view of the log, so the World can hand
|
|
19
|
+
* back what landed above it.
|
|
20
|
+
* - `fedMaxSlot`, the highest position delivered to the VM. Delivery is
|
|
21
|
+
* strictly in position order with no gaps, because the VM consumes events
|
|
22
|
+
* as they arrive and a later replay will read the log in position order;
|
|
23
|
+
* feeding position 13 before 12 exists would let the two disagree.
|
|
24
|
+
* - `cursor`, the read position for `events.list`, advanced by list pages and
|
|
25
|
+
* by a complete inline delta.
|
|
26
|
+
*
|
|
27
|
+
* Only PAGES are queued for delivery, never the created event a write returns
|
|
28
|
+
* on its own. A World reads a report or a delta the way it reads a listing,
|
|
29
|
+
* with payload refs resolved, so those events are what a listing would have
|
|
30
|
+
* delivered. The created event on a create response is not: a World may hand
|
|
31
|
+
* it back with its payload still a ref descriptor and telemetry fields
|
|
32
|
+
* stripped (the Vercel World does, for every type whose entity the runtime
|
|
33
|
+
* does not read off the response), and a VM given that copy of a `step_failed`
|
|
34
|
+
* sees a step that failed with no error in it. The created event still counts
|
|
35
|
+
* toward the position the next write names; it is delivered by the page that
|
|
36
|
+
* covers it or by the next listing. `deliverEvent` opts a write in when its
|
|
37
|
+
* event carries nothing a VM reads (`wait_completed`).
|
|
38
|
+
*
|
|
39
|
+
* Positions come from slot-numbered event ids. A log whose ids are not slots
|
|
40
|
+
* (a World on the old id scheme, or a mocked World) turns tracking off for the
|
|
41
|
+
* rest of the invocation: no `eventCount` is sent, nothing is buffered, and the
|
|
42
|
+
* engine reads the log back the way it did before any of this existed.
|
|
43
|
+
*/
|
|
44
|
+
export class QuickJSLogView {
|
|
45
|
+
slotTracking = true;
|
|
46
|
+
knownMaxSlot;
|
|
47
|
+
fedMaxSlot;
|
|
48
|
+
/** Events handed back by a World that the VM has not been given yet. */
|
|
49
|
+
unfed = new Map();
|
|
50
|
+
cursor;
|
|
51
|
+
constructor(fedEvents, cursor) {
|
|
52
|
+
this.cursor = cursor;
|
|
53
|
+
this.markFed(fedEvents);
|
|
54
|
+
}
|
|
55
|
+
/** Read position for the next `events.list`, or `null` for the start. */
|
|
56
|
+
get logCursor() {
|
|
57
|
+
return this.cursor;
|
|
58
|
+
}
|
|
59
|
+
/** How many events are queued for delivery to the VM. */
|
|
60
|
+
get bufferedCount() {
|
|
61
|
+
return this.unfed.size;
|
|
62
|
+
}
|
|
63
|
+
/** Whether positions are being tracked (see class doc). */
|
|
64
|
+
get tracking() {
|
|
65
|
+
return this.slotTracking;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The `eventCount` to attach to a write made from this view. Empty while no
|
|
69
|
+
* position is known (an empty log) or once tracking has been turned off.
|
|
70
|
+
*/
|
|
71
|
+
snapshotParams() {
|
|
72
|
+
return this.slotTracking && this.knownMaxSlot !== undefined
|
|
73
|
+
? { eventCount: this.knownMaxSlot }
|
|
74
|
+
: {};
|
|
75
|
+
}
|
|
76
|
+
/** A page of `events.list` was read to `cursor`. */
|
|
77
|
+
advanceCursor(cursor) {
|
|
78
|
+
if (cursor !== null) {
|
|
79
|
+
this.cursor = cursor;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Events delivered to the VM by the caller (the initial load, or an
|
|
84
|
+
* `events.list` page). Removes them from the delivery queue if a write
|
|
85
|
+
* response had already handed them back.
|
|
86
|
+
*/
|
|
87
|
+
markFed(events) {
|
|
88
|
+
for (const event of events) {
|
|
89
|
+
const slot = this.slotOf(event);
|
|
90
|
+
if (slot === undefined)
|
|
91
|
+
continue;
|
|
92
|
+
this.unfed.delete(slot);
|
|
93
|
+
if (this.fedMaxSlot === undefined || slot > this.fedMaxSlot) {
|
|
94
|
+
this.fedMaxSlot = slot;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Absorb a write's response: note the committed event's position, and
|
|
100
|
+
* queue the skipped-slot report a World attached to it.
|
|
101
|
+
*
|
|
102
|
+
* A truncated page (`hasMore`) is dropped whole, the same policy as
|
|
103
|
+
* `absorbSkippedSlotReport` in the node engine: it covers a span of
|
|
104
|
+
* positions but carries only some of them, and queuing part of a span
|
|
105
|
+
* would have this view claim, on its next write, to have seen positions it
|
|
106
|
+
* never received. The committed event is queued only under `deliverEvent`
|
|
107
|
+
* (see the class doc for why not by default); its position always counts.
|
|
108
|
+
*/
|
|
109
|
+
absorb(result, options = {}) {
|
|
110
|
+
let queued = 0;
|
|
111
|
+
if (result.event) {
|
|
112
|
+
if (options.deliverEvent === true) {
|
|
113
|
+
if (this.queue(result.event))
|
|
114
|
+
queued++;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
this.slotOf(result.event);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const page = result.events ?? [];
|
|
121
|
+
if (page.length === 0) {
|
|
122
|
+
return { queued, truncated: false };
|
|
123
|
+
}
|
|
124
|
+
if (result.hasMore === true) {
|
|
125
|
+
return { queued, truncated: true };
|
|
126
|
+
}
|
|
127
|
+
for (const event of page) {
|
|
128
|
+
if (this.queue(event))
|
|
129
|
+
queued++;
|
|
130
|
+
}
|
|
131
|
+
return { queued, truncated: false };
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Absorb the inline delta a step-terminal write returned for
|
|
135
|
+
* `sinceCursor`, and advance the read cursor past it when that is safe.
|
|
136
|
+
*
|
|
137
|
+
* The delta is everything after `sentCursor`, so it may be taken only if
|
|
138
|
+
* the view still stands at that cursor (a list in between would have moved
|
|
139
|
+
* it, and appending a delta computed from an older position could deliver
|
|
140
|
+
* events behind ones already fed). The cursor advances only when the queue
|
|
141
|
+
* then holds every position between what the VM has and the delta's end:
|
|
142
|
+
* with a hole in between, a later `events.list` from the advanced cursor
|
|
143
|
+
* would never return the missing event and the VM would stall on it.
|
|
144
|
+
*
|
|
145
|
+
* @returns whether the cursor was advanced.
|
|
146
|
+
*/
|
|
147
|
+
absorbDelta(sentCursor, delta) {
|
|
148
|
+
if (!this.slotTracking || this.cursor !== sentCursor) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
if (delta.hasMore) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
for (const event of delta.events) {
|
|
155
|
+
this.queue(event);
|
|
156
|
+
}
|
|
157
|
+
if (!this.queueIsDense()) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
this.advanceCursor(delta.cursor);
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Drain the events that can be delivered to the VM now: the queued run of
|
|
165
|
+
* consecutive positions directly above the highest one already fed. A queued
|
|
166
|
+
* event above a position nothing has filled yet stays queued until a list
|
|
167
|
+
* fills the gap.
|
|
168
|
+
*/
|
|
169
|
+
takeContiguous() {
|
|
170
|
+
if (!this.slotTracking) {
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
const out = [];
|
|
174
|
+
// A VM started on an empty log is waiting for the first position.
|
|
175
|
+
let next = this.fedMaxSlot === undefined ? FIRST_EVENT_SLOT : this.fedMaxSlot + 1;
|
|
176
|
+
for (;;) {
|
|
177
|
+
const event = this.unfed.get(next);
|
|
178
|
+
if (event === undefined)
|
|
179
|
+
break;
|
|
180
|
+
this.unfed.delete(next);
|
|
181
|
+
out.push(event);
|
|
182
|
+
next++;
|
|
183
|
+
}
|
|
184
|
+
if (out.length > 0) {
|
|
185
|
+
this.fedMaxSlot = next - 1;
|
|
186
|
+
}
|
|
187
|
+
return out;
|
|
188
|
+
}
|
|
189
|
+
queueIsDense() {
|
|
190
|
+
if (this.knownMaxSlot === undefined) {
|
|
191
|
+
return this.unfed.size === 0;
|
|
192
|
+
}
|
|
193
|
+
const fed = this.fedMaxSlot ?? FIRST_EVENT_SLOT - 1;
|
|
194
|
+
return this.unfed.size === this.knownMaxSlot - fed;
|
|
195
|
+
}
|
|
196
|
+
/** Queue one event for delivery unless the VM already has it. */
|
|
197
|
+
queue(event) {
|
|
198
|
+
const slot = this.slotOf(event);
|
|
199
|
+
if (slot === undefined)
|
|
200
|
+
return false;
|
|
201
|
+
if (this.fedMaxSlot !== undefined && slot <= this.fedMaxSlot) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
if (this.unfed.has(slot))
|
|
205
|
+
return false;
|
|
206
|
+
this.unfed.set(slot, event);
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* The event's position, bumping `knownMaxSlot`. `undefined` once an id
|
|
211
|
+
* turns out not to be a slot, which turns tracking off for good.
|
|
212
|
+
*/
|
|
213
|
+
slotOf(event) {
|
|
214
|
+
if (!this.slotTracking)
|
|
215
|
+
return undefined;
|
|
216
|
+
const slot = typeof event.eventId === 'string' ? eventIdToSlot(event.eventId) : null;
|
|
217
|
+
if (slot === null) {
|
|
218
|
+
this.slotTracking = false;
|
|
219
|
+
this.knownMaxSlot = undefined;
|
|
220
|
+
this.unfed.clear();
|
|
221
|
+
return undefined;
|
|
222
|
+
}
|
|
223
|
+
if (this.knownMaxSlot === undefined || slot > this.knownMaxSlot) {
|
|
224
|
+
this.knownMaxSlot = slot;
|
|
225
|
+
}
|
|
226
|
+
return slot;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVpY2tqcy1sb2ctdmlldy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW50aW1lL3F1aWNranMtbG9nLXZpZXcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFjLGFBQWEsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRTlFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlDRztBQUNILE1BQU0sT0FBTyxjQUFjO0lBQ2pCLFlBQVksR0FBRyxJQUFJLENBQUM7SUFDcEIsWUFBWSxDQUFxQjtJQUNqQyxVQUFVLENBQXFCO0lBQ3ZDLHdFQUF3RTtJQUN2RCxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQWlCLENBQUM7SUFDMUMsTUFBTSxDQUFnQjtJQUU5QixZQUFZLFNBQTJCLEVBQUUsTUFBcUI7UUFDNUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBRUQseUVBQXlFO0lBQ3pFLElBQUksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNyQixDQUFDO0lBRUQseURBQXlEO0lBQ3pELElBQUksYUFBYTtRQUNmLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUM7SUFDekIsQ0FBQztJQUVELDJEQUEyRDtJQUMzRCxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUM7SUFDM0IsQ0FBQztJQUVEOzs7T0FHRztJQUNILGNBQWM7UUFDWixPQUFPLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLFlBQVksS0FBSyxTQUFTO1lBQ3pELENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFO1lBQ25DLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDVCxDQUFDO0lBRUQsb0RBQW9EO0lBQ3BE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IGV2ZW50SWRUb1Nsb3QsIEZJUlNUX0VWRU5UX1NMT1QgfSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuXG4vKipcbiAqIFRoZSBRdWlja0pTIGVuZ2luZSdzIGJvb2trZWVwaW5nIGZvciB0aGUgcnVuJ3MgZXZlbnQgbG9nLCBnaXZpbmcgdGhhdCBlbmdpbmVcbiAqIHRoZSBzYW1lIHJlbGF0aW9uc2hpcCB0byBhIFdvcmxkJ3Mgd3JpdGUgcmVzcG9uc2VzIHRoYXQgdGhlIG5vZGU6dm0gcmVwbGF5XG4gKiBsb29wIGhhcy5cbiAqXG4gKiBUaGUgbm9kZSBlbmdpbmUgaG9sZHMgdGhlIGxvZyBhcyBhbiBhcnJheSBpdCByZXBsYXlzIGZyb20sIHNvIGEgcGFnZSBhIFdvcmxkXG4gKiBoYW5kcyBiYWNrIG9uIGEgd3JpdGUgKGEgc2tpcHBlZC1zbG90IHJlcG9ydCBhZ2FpbnN0IGBldmVudENvdW50YCwgb3IgYW5cbiAqIGlubGluZSBkZWx0YSBhZ2FpbnN0IGBzaW5jZUN1cnNvcmA7IHNlZSBgQ3JlYXRlRXZlbnRQYXJhbXNgIGluXG4gKiBgQHdvcmtmbG93L3dvcmxkYCkgaXMgbWVyZ2VkIGludG8gdGhhdCBhcnJheSBhbmQgdGhlIG5leHQgcmVwbGF5IHJlYWRzIGl0XG4gKiB0aGVyZS4gVGhlIFF1aWNrSlMgZW5naW5lIGhvbGRzIGEgTElWRSBWTSBpbnN0ZWFkOiBldmVudHMgYXJlIGRlbGl2ZXJlZCB0byBpdFxuICogaW5jcmVtZW50YWxseSB0aHJvdWdoIGBjb250aW51ZVdpdGhFdmVudHNgLCBpbiBsb2cgb3JkZXIsIGV4YWN0bHkgb25jZS4gU29cbiAqIGZvciB0aGlzIGVuZ2luZSBhIHJldHVybmVkIHBhZ2UgaXMgbm90IG1lcmdlZCBpbnRvIGEgbG9nOyBpdCBpcyBxdWV1ZWQgdG8gYmVcbiAqIGRlbGl2ZXJlZC4gVGhpcyBjbGFzcyBvd25zIHRoYXQgcXVldWUgYW5kIHRoZSB0aHJlZSBudW1iZXJzIGFyb3VuZCBpdDpcbiAqXG4gKiAtIGBrbm93bk1heFNsb3RgLCB0aGUgaGlnaGVzdCBwb3NpdGlvbiB0aGlzIGludm9jYXRpb24gaGFzIHNlZW4gYW55d2hlcmVcbiAqICAgKGZlZCwgYnVmZmVyZWQsIG9yIGl0cyBvd24gd3JpdGUpLiBSZXBvcnRlZCBhcyBgZXZlbnRDb3VudGAgb24gZXZlcnkgd3JpdGVcbiAqICAgdGhpcyBpbnZvY2F0aW9uIG1ha2VzIGZyb20gaXRzIHZpZXcgb2YgdGhlIGxvZywgc28gdGhlIFdvcmxkIGNhbiBoYW5kXG4gKiAgIGJhY2sgd2hhdCBsYW5kZWQgYWJvdmUgaXQuXG4gKiAtIGBmZWRNYXhTbG90YCwgdGhlIGhpZ2hlc3QgcG9zaXRpb24gZGVsaXZlcmVkIHRvIHRoZSBWTS4gRGVsaXZlcnkgaXNcbiAqICAgc3RyaWN0bHkgaW4gcG9zaXRpb24gb3JkZXIgd2l0aCBubyBnYXBzLCBiZWNhdXNlIHRoZSBWTSBjb25zdW1lcyBldmVudHNcbiAqICAgYXMgdGhleSBhcnJpdmUgYW5kIGEgbGF0ZXIgcmVwbGF5IHdpbGwgcmVhZCB0aGUgbG9nIGluIHBvc2l0aW9uIG9yZGVyO1xuICogICBmZWVkaW5nIHBvc2l0aW9uIDEzIGJlZm9yZSAxMiBleGlzdHMgd291bGQgbGV0IHRoZSB0d28gZGlzYWdyZWUuXG4gKiAtIGBjdXJzb3JgLCB0aGUgcmVhZCBwb3NpdGlvbiBmb3IgYGV2ZW50cy5saXN0YCwgYWR2YW5jZWQgYnkgbGlzdCBwYWdlcyBhbmRcbiAqICAgYnkgYSBjb21wbGV0ZSBpbmxpbmUgZGVsdGEuXG4gKlxuICogT25seSBQQUdFUyBhcmUgcXVldWVkIGZvciBkZWxpdmVyeSwgbmV2ZXIgdGhlIGNyZWF0ZWQgZXZlbnQgYSB3cml0ZSByZXR1cm5zXG4gKiBvbiBpdHMgb3duLiBBIFdvcmxkIHJlYWRzIGEgcmVwb3J0IG9yIGEgZGVsdGEgdGhlIHdheSBpdCByZWFkcyBhIGxpc3RpbmcsXG4gKiB3aXRoIHBheWxvYWQgcmVmcyByZXNvbHZlZCwgc28gdGhvc2UgZXZlbnRzIGFyZSB3aGF0IGEgbGlzdGluZyB3b3VsZCBoYXZlXG4gKiBkZWxpdmVyZWQuIFRoZSBjcmVhdGVkIGV2ZW50IG9uIGEgY3JlYXRlIHJlc3BvbnNlIGlzIG5vdDogYSBXb3JsZCBtYXkgaGFuZFxuICogaXQgYmFjayB3aXRoIGl0cyBwYXlsb2FkIHN0aWxsIGEgcmVmIGRlc2NyaXB0b3IgYW5kIHRlbGVtZXRyeSBmaWVsZHNcbiAqIHN0cmlwcGVkICh0aGUgVmVyY2VsIFdvcmxkIGRvZXMsIGZvciBldmVyeSB0eXBlIHdob3NlIGVudGl0eSB0aGUgcnVudGltZVxuICogZG9lcyBub3QgcmVhZCBvZmYgdGhlIHJlc3BvbnNlKSwgYW5kIGEgVk0gZ2l2ZW4gdGhhdCBjb3B5IG9mIGEgYHN0ZXBfZmFpbGVkYFxuICogc2VlcyBhIHN0ZXAgdGhhdCBmYWlsZWQgd2l0aCBubyBlcnJvciBpbiBpdC4gVGhlIGNyZWF0ZWQgZXZlbnQgc3RpbGwgY291bnRzXG4gKiB0b3dhcmQgdGhlIHBvc2l0aW9uIHRoZSBuZXh0IHdyaXRlIG5hbWVzOyBpdCBpcyBkZWxpdmVyZWQgYnkgdGhlIHBhZ2UgdGhhdFxuICogY292ZXJzIGl0IG9yIGJ5IHRoZSBuZXh0IGxpc3RpbmcuIGBkZWxpdmVyRXZlbnRgIG9wdHMgYSB3cml0ZSBpbiB3aGVuIGl0c1xuICogZXZlbnQgY2FycmllcyBub3RoaW5nIGEgVk0gcmVhZHMgKGB3YWl0X2NvbXBsZXRlZGApLlxuICpcbiAqIFBvc2l0aW9ucyBjb21lIGZyb20gc2xvdC1udW1iZXJlZCBldmVudCBpZHMuIEEgbG9nIHdob3NlIGlkcyBhcmUgbm90IHNsb3RzXG4gKiAoYSBXb3JsZCBvbiB0aGUgb2xkIGlkIHNjaGVtZSwgb3IgYSBtb2NrZWQgV29ybGQpIHR1cm5zIHRyYWNraW5nIG9mZiBmb3IgdGhlXG4gKiByZXN0IG9mIHRoZSBpbnZvY2F0aW9uOiBubyBgZXZlbnRDb3VudGAgaXMgc2VudCwgbm90aGluZyBpcyBidWZmZXJlZCwgYW5kIHRoZVxuICogZW5naW5lIHJlYWRzIHRoZSBsb2cgYmFjayB0aGUgd2F5IGl0IGRpZCBiZWZvcmUgYW55IG9mIHRoaXMgZXhpc3RlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIFF1aWNrSlNMb2dWaWV3IHtcbiAgcHJpdmF0ZSBzbG90VHJhY2tpbmcgPSB0cnVlO1xuICBwcml2YXRlIGtub3duTWF4U2xvdDogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIGZlZE1heFNsb3Q6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgLyoqIEV2ZW50cyBoYW5kZWQgYmFjayBieSBhIFdvcmxkIHRoYXQgdGhlIFZNIGhhcyBub3QgYmVlbiBnaXZlbiB5ZXQuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgdW5mZWQgPSBuZXcgTWFwPG51bWJlciwgRXZlbnQ+KCk7XG4gIHByaXZhdGUgY3Vyc29yOiBzdHJpbmcgfCBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKGZlZEV2ZW50czogcmVhZG9ubHkgRXZlbnRbXSwgY3Vyc29yOiBzdHJpbmcgfCBudWxsKSB7XG4gICAgdGhpcy5jdXJzb3IgPSBjdXJzb3I7XG4gICAgdGhpcy5tYXJrRmVkKGZlZEV2ZW50cyk7XG4gIH1cblxuICAvKiogUmVhZCBwb3NpdGlvbiBmb3IgdGhlIG5leHQgYGV2ZW50cy5saXN0YCwgb3IgYG51bGxgIGZvciB0aGUgc3RhcnQuICovXG4gIGdldCBsb2dDdXJzb3IoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuY3Vyc29yO1xuICB9XG5cbiAgLyoqIEhvdyBtYW55IGV2ZW50cyBhcmUgcXVldWVkIGZvciBkZWxpdmVyeSB0byB0aGUgVk0uICovXG4gIGdldCBidWZmZXJlZENvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudW5mZWQuc2l6ZTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHBvc2l0aW9ucyBhcmUgYmVpbmcgdHJhY2tlZCAoc2VlIGNsYXNzIGRvYykuICovXG4gIGdldCB0cmFja2luZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zbG90VHJhY2tpbmc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGBldmVudENvdW50YCB0byBhdHRhY2ggdG8gYSB3cml0ZSBtYWRlIGZyb20gdGhpcyB2aWV3LiBFbXB0eSB3aGlsZSBub1xuICAgKiBwb3NpdGlvbiBpcyBrbm93biAoYW4gZW1wdHkgbG9nKSBvciBvbmNlIHRyYWNraW5nIGhhcyBiZWVuIHR1cm5lZCBvZmYuXG4gICAqL1xuICBzbmFwc2hvdFBhcmFtcygpOiB7IGV2ZW50Q291bnQ/OiBudW1iZXIgfSB7XG4gICAgcmV0dXJuIHRoaXMuc2xvdFRyYWNraW5nICYmIHRoaXMua25vd25NYXhTbG90ICE9PSB1bmRlZmluZWRcbiAgICAgID8geyBldmVudENvdW50OiB0aGlzLmtub3duTWF4U2xvdCB9XG4gICAgICA6IHt9O1xuICB9XG5cbiAgLyoqIEEgcGFnZSBvZiBgZXZlbnRzLmxpc3RgIHdhcyByZWFkIHRvIGBjdXJzb3JgLiAqL1xuICBhZHZhbmNlQ3Vyc29yKGN1cnNvcjogc3RyaW5nIHwgbnVsbCk6IHZvaWQge1xuICAgIGlmIChjdXJzb3IgIT09IG51bGwpIHtcbiAgICAgIHRoaXMuY3Vyc29yID0gY3Vyc29yO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFdmVudHMgZGVsaXZlcmVkIHRvIHRoZSBWTSBieSB0aGUgY2FsbGVyICh0aGUgaW5pdGlhbCBsb2FkLCBvciBhblxuICAgKiBgZXZlbnRzLmxpc3RgIHBhZ2UpLiBSZW1vdmVzIHRoZW0gZnJvbSB0aGUgZGVsaXZlcnkgcXVldWUgaWYgYSB3cml0ZVxuICAgKiByZXNwb25zZSBoYWQgYWxyZWFkeSBoYW5kZWQgdGhlbSBiYWNrLlxuICAgKi9cbiAgbWFya0ZlZChldmVudHM6IHJlYWRvbmx5IEV2ZW50W10pOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIGV2ZW50cykge1xuICAgICAgY29uc3Qgc2xvdCA9IHRoaXMuc2xvdE9mKGV2ZW50KTtcbiAgICAgIGlmIChzbG90ID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgdGhpcy51bmZlZC5kZWxldGUoc2xvdCk7XG4gICAgICBpZiAodGhpcy5mZWRNYXhTbG90ID09PSB1bmRlZmluZWQgfHwgc2xvdCA+IHRoaXMuZmVkTWF4U2xvdCkge1xuICAgICAgICB0aGlzLmZlZE1heFNsb3QgPSBzbG90O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBYnNvcmIgYSB3cml0ZSdzIHJlc3BvbnNlOiBub3RlIHRoZSBjb21taXR0ZWQgZXZlbnQncyBwb3NpdGlvbiwgYW5kXG4gICAqIHF1ZXVlIHRoZSBza2lwcGVkLXNsb3QgcmVwb3J0IGEgV29ybGQgYXR0YWNoZWQgdG8gaXQuXG4gICAqXG4gICAqIEEgdHJ1bmNhdGVkIHBhZ2UgKGBoYXNNb3JlYCkgaXMgZHJvcHBlZCB3aG9sZSwgdGhlIHNhbWUgcG9saWN5IGFzXG4gICAqIGBhYnNvcmJTa2lwcGVkU2xvdFJlcG9ydGAgaW4gdGhlIG5vZGUgZW5naW5lOiBpdCBjb3ZlcnMgYSBzcGFuIG9mXG4gICAqIHBvc2l0aW9ucyBidXQgY2FycmllcyBvbmx5IHNvbWUgb2YgdGhlbSwgYW5kIHF1ZXVpbmcgcGFydCBvZiBhIHNwYW5cbiAgICogd291bGQgaGF2ZSB0aGlzIHZpZXcgY2xhaW0sIG9uIGl0cyBuZXh0IHdyaXRlLCB0byBoYXZlIHNlZW4gcG9zaXRpb25zIGl0XG4gICAqIG5ldmVyIHJlY2VpdmVkLiBUaGUgY29tbWl0dGVkIGV2ZW50IGlzIHF1ZXVlZCBvbmx5IHVuZGVyIGBkZWxpdmVyRXZlbnRgXG4gICAqIChzZWUgdGhlIGNsYXNzIGRvYyBmb3Igd2h5IG5vdCBieSBkZWZhdWx0KTsgaXRzIHBvc2l0aW9uIGFsd2F5cyBjb3VudHMuXG4gICAqL1xuICBhYnNvcmIoXG4gICAgcmVzdWx0OiB7XG4gICAgICBldmVudD86IEV2ZW50O1xuICAgICAgZXZlbnRzPzogcmVhZG9ubHkgRXZlbnRbXTtcbiAgICAgIGhhc01vcmU/OiBib29sZWFuO1xuICAgIH0sXG4gICAgb3B0aW9uczogeyBkZWxpdmVyRXZlbnQ/OiBib29sZWFuIH0gPSB7fVxuICApOiB7IHF1ZXVlZDogbnVtYmVyOyB0cnVuY2F0ZWQ6IGJvb2xlYW4gfSB7XG4gICAgbGV0IHF1ZXVlZCA9IDA7XG4gICAgaWYgKHJlc3VsdC5ldmVudCkge1xuICAgICAgaWYgKG9wdGlvbnMuZGVsaXZlckV2ZW50ID09PSB0cnVlKSB7XG4gICAgICAgIGlmICh0aGlzLnF1ZXVlKHJlc3VsdC5ldmVudCkpIHF1ZXVlZCsrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zbG90T2YocmVzdWx0LmV2ZW50KTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgcGFnZSA9IHJlc3VsdC5ldmVudHMgPz8gW107XG4gICAgaWYgKHBhZ2UubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4geyBxdWV1ZWQsIHRydW5jYXRlZDogZmFsc2UgfTtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC5oYXNNb3JlID09PSB0cnVlKSB7XG4gICAgICByZXR1cm4geyBxdWV1ZWQsIHRydW5jYXRlZDogdHJ1ZSB9O1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIHBhZ2UpIHtcbiAgICAgIGlmICh0aGlzLnF1ZXVlKGV2ZW50KSkgcXVldWVkKys7XG4gICAgfVxuICAgIHJldHVybiB7IHF1ZXVlZCwgdHJ1bmNhdGVkOiBmYWxzZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFic29yYiB0aGUgaW5saW5lIGRlbHRhIGEgc3RlcC10ZXJtaW5hbCB3cml0ZSByZXR1cm5lZCBmb3JcbiAgICogYHNpbmNlQ3Vyc29yYCwgYW5kIGFkdmFuY2UgdGhlIHJlYWQgY3Vyc29yIHBhc3QgaXQgd2hlbiB0aGF0IGlzIHNhZmUuXG4gICAqXG4gICAqIFRoZSBkZWx0YSBpcyBldmVyeXRoaW5nIGFmdGVyIGBzZW50Q3Vyc29yYCwgc28gaXQgbWF5IGJlIHRha2VuIG9ubHkgaWZcbiAgICogdGhlIHZpZXcgc3RpbGwgc3RhbmRzIGF0IHRoYXQgY3Vyc29yIChhIGxpc3QgaW4gYmV0d2VlbiB3b3VsZCBoYXZlIG1vdmVkXG4gICAqIGl0LCBhbmQgYXBwZW5kaW5nIGEgZGVsdGEgY29tcHV0ZWQgZnJvbSBhbiBvbGRlciBwb3NpdGlvbiBjb3VsZCBkZWxpdmVyXG4gICAqIGV2ZW50cyBiZWhpbmQgb25lcyBhbHJlYWR5IGZlZCkuIFRoZSBjdXJzb3IgYWR2YW5jZXMgb25seSB3aGVuIHRoZSBxdWV1ZVxuICAgKiB0aGVuIGhvbGRzIGV2ZXJ5IHBvc2l0aW9uIGJldHdlZW4gd2hhdCB0aGUgVk0gaGFzIGFuZCB0aGUgZGVsdGEncyBlbmQ6XG4gICAqIHdpdGggYSBob2xlIGluIGJldHdlZW4sIGEgbGF0ZXIgYGV2ZW50cy5saXN0YCBmcm9tIHRoZSBhZHZhbmNlZCBjdXJzb3JcbiAgICogd291bGQgbmV2ZXIgcmV0dXJuIHRoZSBtaXNzaW5nIGV2ZW50IGFuZCB0aGUgVk0gd291bGQgc3RhbGwgb24gaXQuXG4gICAqXG4gICAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGN1cnNvciB3YXMgYWR2YW5jZWQuXG4gICAqL1xuICBhYnNvcmJEZWx0YShcbiAgICBzZW50Q3Vyc29yOiBzdHJpbmcsXG4gICAgZGVsdGE6IHsgZXZlbnRzOiByZWFkb25seSBFdmVudFtdOyBjdXJzb3I6IHN0cmluZyB8IG51bGw7IGhhc01vcmU6IGJvb2xlYW4gfVxuICApOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMuc2xvdFRyYWNraW5nIHx8IHRoaXMuY3Vyc29yICE9PSBzZW50Q3Vyc29yKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChkZWx0YS5oYXNNb3JlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZGVsdGEuZXZlbnRzKSB7XG4gICAgICB0aGlzLnF1ZXVlKGV2ZW50KTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnF1ZXVlSXNEZW5zZSgpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMuYWR2YW5jZUN1cnNvcihkZWx0YS5jdXJzb3IpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIERyYWluIHRoZSBldmVudHMgdGhhdCBjYW4gYmUgZGVsaXZlcmVkIHRvIHRoZSBWTSBub3c6IHRoZSBxdWV1ZWQgcnVuIG9mXG4gICAqIGNvbnNlY3V0aXZlIHBvc2l0aW9ucyBkaXJlY3RseSBhYm92ZSB0aGUgaGlnaGVzdCBvbmUgYWxyZWFkeSBmZWQuIEEgcXVldWVkXG4gICAqIGV2ZW50IGFib3ZlIGEgcG9zaXRpb24gbm90aGluZyBoYXMgZmlsbGVkIHlldCBzdGF5cyBxdWV1ZWQgdW50aWwgYSBsaXN0XG4gICAqIGZpbGxzIHRoZSBnYXAuXG4gICAqL1xuICB0YWtlQ29udGlndW91cygpOiBFdmVudFtdIHtcbiAgICBpZiAoIXRoaXMuc2xvdFRyYWNraW5nKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IG91dDogRXZlbnRbXSA9IFtdO1xuICAgIC8vIEEgVk0gc3RhcnRlZCBvbiBhbiBlbXB0eSBsb2cgaXMgd2FpdGluZyBmb3IgdGhlIGZpcnN0IHBvc2l0aW9uLlxuICAgIGxldCBuZXh0ID1cbiAgICAgIHRoaXMuZmVkTWF4U2xvdCA9PT0gdW5kZWZpbmVkID8gRklSU1RfRVZFTlRfU0xPVCA6IHRoaXMuZmVkTWF4U2xvdCArIDE7XG4gICAgZm9yICg7Oykge1xuICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLnVuZmVkLmdldChuZXh0KTtcbiAgICAgIGlmIChldmVudCA9PT0gdW5kZWZpbmVkKSBicmVhaztcbiAgICAgIHRoaXMudW5mZWQuZGVsZXRlKG5leHQpO1xuICAgICAgb3V0LnB1c2goZXZlbnQpO1xuICAgICAgbmV4dCsrO1xuICAgIH1cbiAgICBpZiAob3V0Lmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuZmVkTWF4U2xvdCA9IG5leHQgLSAxO1xuICAgIH1cbiAgICByZXR1cm4gb3V0O1xuICB9XG5cbiAgcHJpdmF0ZSBxdWV1ZUlzRGVuc2UoKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMua25vd25NYXhTbG90ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnVuZmVkLnNpemUgPT09IDA7XG4gICAgfVxuICAgIGNvbnN0IGZlZCA9IHRoaXMuZmVkTWF4U2xvdCA/PyBGSVJTVF9FVkVOVF9TTE9UIC0gMTtcbiAgICByZXR1cm4gdGhpcy51bmZlZC5zaXplID09PSB0aGlzLmtub3duTWF4U2xvdCAtIGZlZDtcbiAgfVxuXG4gIC8qKiBRdWV1ZSBvbmUgZXZlbnQgZm9yIGRlbGl2ZXJ5IHVubGVzcyB0aGUgVk0gYWxyZWFkeSBoYXMgaXQuICovXG4gIHByaXZhdGUgcXVldWUoZXZlbnQ6IEV2ZW50KTogYm9vbGVhbiB7XG4gICAgY29uc3Qgc2xvdCA9IHRoaXMuc2xvdE9mKGV2ZW50KTtcbiAgICBpZiAoc2xvdCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHRoaXMuZmVkTWF4U2xvdCAhPT0gdW5kZWZpbmVkICYmIHNsb3QgPD0gdGhpcy5mZWRNYXhTbG90KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0aGlzLnVuZmVkLmhhcyhzbG90KSkgcmV0dXJuIGZhbHNlO1xuICAgIHRoaXMudW5mZWQuc2V0KHNsb3QsIGV2ZW50KTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgZXZlbnQncyBwb3NpdGlvbiwgYnVtcGluZyBga25vd25NYXhTbG90YC4gYHVuZGVmaW5lZGAgb25jZSBhbiBpZFxuICAgKiB0dXJucyBvdXQgbm90IHRvIGJlIGEgc2xvdCwgd2hpY2ggdHVybnMgdHJhY2tpbmcgb2ZmIGZvciBnb29kLlxuICAgKi9cbiAgcHJpdmF0ZSBzbG90T2YoZXZlbnQ6IEV2ZW50KTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIXRoaXMuc2xvdFRyYWNraW5nKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGNvbnN0IHNsb3QgPVxuICAgICAgdHlwZW9mIGV2ZW50LmV2ZW50SWQgPT09ICdzdHJpbmcnID8gZXZlbnRJZFRvU2xvdChldmVudC5ldmVudElkKSA6IG51bGw7XG4gICAgaWYgKHNsb3QgPT09IG51bGwpIHtcbiAgICAgIHRoaXMuc2xvdFRyYWNraW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmtub3duTWF4U2xvdCA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMudW5mZWQuY2xlYXIoKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmICh0aGlzLmtub3duTWF4U2xvdCA9PT0gdW5kZWZpbmVkIHx8IHNsb3QgPiB0aGlzLmtub3duTWF4U2xvdCkge1xuICAgICAgdGhpcy5rbm93bk1heFNsb3QgPSBzbG90O1xuICAgIH1cbiAgICByZXR1cm4gc2xvdDtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QuickJS WebAssembly (WASM) workflow VM.
|
|
3
|
+
*
|
|
4
|
+
* An alternative engine for the event-replay execution model: the workflow
|
|
5
|
+
* code runs inside a QuickJS WASM VM (via quickjs-wasi) instead of a
|
|
6
|
+
* `node:vm` context. Every invocation creates a fresh VM, re-executes the
|
|
7
|
+
* workflow function from the top, and replays the recorded event log to
|
|
8
|
+
* resolve awaited primitives: the same replay semantics as the `node:vm`
|
|
9
|
+
* engine.
|
|
10
|
+
*
|
|
11
|
+
* The workflow primitives (useStep, sleep, createHook) are implemented as
|
|
12
|
+
* JavaScript code running inside the QuickJS VM. The host communicates with
|
|
13
|
+
* the VM by evaluating small JS snippets to read pending operations and
|
|
14
|
+
* resolve/reject promises.
|
|
15
|
+
*
|
|
16
|
+
* The VM bootstrap is deliberately split into two phases:
|
|
17
|
+
* 1. Static initialization (`initWorkflowVM`): run-independent setup:
|
|
18
|
+
* VM creation and the workflow primitives. (Serialization lives on
|
|
19
|
+
* the host (see quickjs-serde.ts) so no serde code is evaluated
|
|
20
|
+
* in the VM.)
|
|
21
|
+
* 2. Per-run initialization (inline in `runQuickJSWorkflow`): seeded
|
|
22
|
+
* PRNG/ULID host functions, workflow bundle evaluation, run metadata,
|
|
23
|
+
* workflow input, and start.
|
|
24
|
+
* Keeping the phases separate is groundwork for VM-memory snapshotting:
|
|
25
|
+
* a follow-up can persist/restore the VM at the phase boundary (e.g. a
|
|
26
|
+
* build-time initial snapshot) without restructuring this module. Note
|
|
27
|
+
* that bundle evaluation currently sits in the per-run phase so that
|
|
28
|
+
* module-scope user code observes the seeded `Math.random`, matching the
|
|
29
|
+
* `node:vm` engine's replay determinism.
|
|
30
|
+
*/
|
|
31
|
+
import { SerializationError } from '@workflow/errors';
|
|
32
|
+
import { type Event, type RunInput, type WorkflowRun, type WorldCapabilities } from '@workflow/world';
|
|
33
|
+
import { type Snapshot } from 'quickjs-wasi';
|
|
34
|
+
import type { DecryptionKey } from '../serialization/encryption.js';
|
|
35
|
+
export interface PendingStep {
|
|
36
|
+
type: 'step';
|
|
37
|
+
correlationId: string;
|
|
38
|
+
stepId: string;
|
|
39
|
+
/**
|
|
40
|
+
* Format-prefixed devalue-serialized step input (args + closureVars).
|
|
41
|
+
* Absent when {@link serializationError} is set: the input is precisely
|
|
42
|
+
* what refused to serialize.
|
|
43
|
+
*/
|
|
44
|
+
input?: Uint8Array;
|
|
45
|
+
/** Whether a step_created event already exists for this step */
|
|
46
|
+
hasCreatedEvent: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Set when host-side serialization of the step's raw input failed while
|
|
49
|
+
* dumping the VM's pending ops (see `dumpPendingOps`). The failure is
|
|
50
|
+
* deterministic (replaying re-derives the same unserializable value), so
|
|
51
|
+
* instead of failing the whole collection the op is surfaced with the
|
|
52
|
+
* reframed error and no `input`; the entrypoint finalizes the step as
|
|
53
|
+
* `step_created` (placeholder input) + `step_failed`, mirroring the
|
|
54
|
+
* node:vm engine's `finalizeUnserializableStep`, so a try/catch around
|
|
55
|
+
* the step call observes the SerializationError.
|
|
56
|
+
*/
|
|
57
|
+
serializationError?: SerializationError;
|
|
58
|
+
}
|
|
59
|
+
export interface PendingWait {
|
|
60
|
+
type: 'wait';
|
|
61
|
+
correlationId: string;
|
|
62
|
+
/** ISO string of when to resume */
|
|
63
|
+
resumeAt: string;
|
|
64
|
+
/** Whether a wait_created event already exists for this wait */
|
|
65
|
+
hasCreatedEvent: boolean;
|
|
66
|
+
}
|
|
67
|
+
export interface PendingHook {
|
|
68
|
+
type: 'hook';
|
|
69
|
+
correlationId: string;
|
|
70
|
+
token: string;
|
|
71
|
+
/** Earliest token reuse time, as milliseconds since the Unix epoch. */
|
|
72
|
+
tokenRetentionUntil?: number;
|
|
73
|
+
isWebhook: boolean;
|
|
74
|
+
metadata?: unknown;
|
|
75
|
+
hasCreatedEvent: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* True for internal system hooks (e.g. AbortController's hook), which
|
|
78
|
+
* are exempt from user-hook token namespace conflict checks.
|
|
79
|
+
*/
|
|
80
|
+
isSystem?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Set when the workflow called AbortController.abort() during this
|
|
83
|
+
* invocation. The host must record the abort: create a hook_received
|
|
84
|
+
* event carrying `abortPayload` and write/close the abort stream.
|
|
85
|
+
*/
|
|
86
|
+
abortRequested?: boolean;
|
|
87
|
+
/** VM-serialized `{ aborted: true, reason }` payload for the abort. */
|
|
88
|
+
abortPayload?: Uint8Array;
|
|
89
|
+
/** Set by the completion drain when a system hook is implicitly disposed. */
|
|
90
|
+
disposed?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* True when the workflow is awaiting hook.getConflict() for this hook.
|
|
93
|
+
* The entrypoint re-invokes the workflow right after writing
|
|
94
|
+
* hook_created so replay can confirm creation and resolve the awaiter.
|
|
95
|
+
*/
|
|
96
|
+
hasGetConflictAwaiter?: boolean;
|
|
97
|
+
}
|
|
98
|
+
export interface PendingAttribute {
|
|
99
|
+
type: 'attribute';
|
|
100
|
+
correlationId: string;
|
|
101
|
+
/** Normalized attribute changes (plain JSON-able objects) */
|
|
102
|
+
changes: unknown[];
|
|
103
|
+
allowReservedAttributes?: boolean;
|
|
104
|
+
/** Whether an attr_set event already exists for this write */
|
|
105
|
+
hasCreatedEvent: boolean;
|
|
106
|
+
}
|
|
107
|
+
export interface PendingHookDispose {
|
|
108
|
+
type: 'hook_dispose';
|
|
109
|
+
correlationId: string;
|
|
110
|
+
/**
|
|
111
|
+
* Token of the hook being disposed. Used by the entrypoint to order
|
|
112
|
+
* same-token hook operations sequentially in code order.
|
|
113
|
+
*/
|
|
114
|
+
token?: string;
|
|
115
|
+
hasCreatedEvent: boolean;
|
|
116
|
+
}
|
|
117
|
+
export type PendingOperation = PendingStep | PendingWait | PendingHook | PendingAttribute | PendingHookDispose;
|
|
118
|
+
export interface QuickJSRuntimeResult {
|
|
119
|
+
/** The workflow completed: result is format-prefixed devalue bytes */
|
|
120
|
+
completed?: {
|
|
121
|
+
result: Uint8Array;
|
|
122
|
+
/**
|
|
123
|
+
* Leftover pending operations that still need durable side effects at
|
|
124
|
+
* completion: abort recordings, system-hook disposals, fire-and-forget
|
|
125
|
+
* attribute/hook/step events. Mirrors the node:vm engine's
|
|
126
|
+
* drainPendingQueueItems. The entrypoint dispatches these WITHOUT
|
|
127
|
+
* queueing steps or requeuing the run.
|
|
128
|
+
*/
|
|
129
|
+
drainOperations?: PendingOperation[];
|
|
130
|
+
};
|
|
131
|
+
/** The workflow suspended with pending operations */
|
|
132
|
+
suspended?: {
|
|
133
|
+
pendingOperations: PendingOperation[];
|
|
134
|
+
};
|
|
135
|
+
/** The workflow failed */
|
|
136
|
+
failed?: {
|
|
137
|
+
message: string;
|
|
138
|
+
stack?: string;
|
|
139
|
+
name?: string;
|
|
140
|
+
/** See completed.drainOperations: same semantics on failure. */
|
|
141
|
+
drainOperations?: PendingOperation[];
|
|
142
|
+
/**
|
|
143
|
+
* Format-prefixed devalue bytes of the original thrown value
|
|
144
|
+
* (Error subclass with cause chain, plain object, primitive, etc.).
|
|
145
|
+
* Set when the VM-side rejection handler successfully serializes
|
|
146
|
+
* the thrown value. The host uses these bytes to reconstruct the
|
|
147
|
+
* original value through the standard error hydration pipeline,
|
|
148
|
+
* preserving type identity (TypeError, FatalError) and non-Error
|
|
149
|
+
* throws verbatim. Falls back to the message/stack/name fields
|
|
150
|
+
* when this is undefined (e.g. extractError pseudo-failures).
|
|
151
|
+
*/
|
|
152
|
+
valueBytes?: Uint8Array;
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
export interface QuickJSRuntimeOptions {
|
|
156
|
+
/** The compiled workflow bundle code (workflow mode output from SWC) */
|
|
157
|
+
workflowCode: string;
|
|
158
|
+
/** The workflow ID (e.g. "workflow//./workflows/1_simple//simple") */
|
|
159
|
+
workflowId: string;
|
|
160
|
+
/** The workflow run entity */
|
|
161
|
+
workflowRun: WorkflowRun;
|
|
162
|
+
/** Features supported by the World executing this workflow. */
|
|
163
|
+
worldCapabilities?: WorldCapabilities;
|
|
164
|
+
/**
|
|
165
|
+
* The full event log for the run. Every invocation replays the complete
|
|
166
|
+
* log from the start (same replay semantics as the `node:vm` engine).
|
|
167
|
+
*/
|
|
168
|
+
events: Event[];
|
|
169
|
+
/** Encryption key for decrypting event payloads (undefined if unencrypted) */
|
|
170
|
+
encryptionKey?: DecryptionKey;
|
|
171
|
+
/**
|
|
172
|
+
* The local port the workflow server is listening on, used to populate
|
|
173
|
+
* `workflowMetadata.url`. Resolved at call time on the host side so the
|
|
174
|
+
* VM doesn't have to probe the filesystem. Ignored on Vercel, where
|
|
175
|
+
* VERCEL_URL takes precedence.
|
|
176
|
+
*/
|
|
177
|
+
port?: number;
|
|
178
|
+
/**
|
|
179
|
+
* Fallback workflow input from the queue message's resilient-start
|
|
180
|
+
* payload. Used when the fetched event log lacks a `run_created` event
|
|
181
|
+
* (eventually-consistent read after the parent's start() wrote it).
|
|
182
|
+
*/
|
|
183
|
+
runInput?: RunInput;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Eval filename used when hydrating the baseline VM. The baseline is
|
|
187
|
+
* shared by EVERY workflow in the bundle, so the filename baked into
|
|
188
|
+
* its compiled code (and therefore into snapshot-path stack frames)
|
|
189
|
+
* must be workflow-independent: hydrating under the first caller's
|
|
190
|
+
* workflowId would break `remapErrorStack`'s filename matching for
|
|
191
|
+
* every other workflow in the bundle. Remap call sites match this
|
|
192
|
+
* constant IN ADDITION to the run's module specifier (which covers
|
|
193
|
+
* fresh-path frames).
|
|
194
|
+
*/
|
|
195
|
+
export declare const BASELINE_BUNDLE_FILENAME = "workflow-bundle.js";
|
|
196
|
+
type BaselineEntry = {
|
|
197
|
+
state: 'ready';
|
|
198
|
+
snapshot: Snapshot;
|
|
199
|
+
/**
|
|
200
|
+
* Raw box pointer of the serde capture root created BEFORE the
|
|
201
|
+
* bundle evaluated (see captureSerdeRoot). The box lives in the
|
|
202
|
+
* snapshot's memory image at this offset; every restored VM
|
|
203
|
+
* re-adopts it so serde initialization executes no guest code
|
|
204
|
+
* after user code has run: capture-before-user-code semantics,
|
|
205
|
+
* identical to the fresh path.
|
|
206
|
+
*/
|
|
207
|
+
serdeRootPtr: number;
|
|
208
|
+
} | {
|
|
209
|
+
state: 'ineligible';
|
|
210
|
+
reason: string;
|
|
211
|
+
};
|
|
212
|
+
/** Test-only: reset the baseline cache between test cases. */
|
|
213
|
+
export declare function __clearBaselineSnapshotCacheForTests(): void;
|
|
214
|
+
/** Test-only: observe how a bundle was classified. */
|
|
215
|
+
export declare function __peekBaselineEntryForTests(workflowCode: string): Promise<BaselineEntry | undefined>;
|
|
216
|
+
/**
|
|
217
|
+
* A live QuickJS workflow invocation. When the initial `result` is
|
|
218
|
+
* `suspended`, the VM is kept alive so the caller can feed newly recorded
|
|
219
|
+
* events (e.g. terminal events of inline-executed steps) into the SAME VM
|
|
220
|
+
* via `continueWithEvents`, resuming execution exactly where it left off
|
|
221
|
+
* without a fresh-VM re-replay. Terminal results dispose the VM
|
|
222
|
+
* automatically; `dispose()` must be called when abandoning a suspended
|
|
223
|
+
* session (idempotent).
|
|
224
|
+
*/
|
|
225
|
+
export interface QuickJSWorkflowSession {
|
|
226
|
+
result: QuickJSRuntimeResult;
|
|
227
|
+
/**
|
|
228
|
+
* Process newly recorded events in the live VM and re-evaluate the
|
|
229
|
+
* workflow state. Only valid while the last result was `suspended`.
|
|
230
|
+
* Resets the VM's interrupt budget for the new execution burst.
|
|
231
|
+
*/
|
|
232
|
+
continueWithEvents(newEvents: Event[]): Promise<QuickJSRuntimeResult>;
|
|
233
|
+
/** Dispose the VM if it is still alive. Safe to call multiple times. */
|
|
234
|
+
dispose(): void;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Run a workflow invocation to its first settled state and dispose the
|
|
238
|
+
* VM. Convenience wrapper over {@link startQuickJSWorkflow} for callers
|
|
239
|
+
* (and tests) that don't use live-VM continuation.
|
|
240
|
+
*/
|
|
241
|
+
export declare function runQuickJSWorkflow(options: QuickJSRuntimeOptions): Promise<QuickJSRuntimeResult>;
|
|
242
|
+
export declare function startQuickJSWorkflow(options: QuickJSRuntimeOptions): Promise<QuickJSWorkflowSession>;
|
|
243
|
+
export {};
|
|
244
|
+
//# sourceMappingURL=quickjs-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quickjs-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/quickjs-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EACL,KAAK,KAAK,EAEV,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAIL,KAAK,QAAQ,EAEd,MAAM,cAAc,CAAC;AAKtB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAwCpE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,gEAAgE;IAChE,eAAe,EAAE,OAAO,CAAC;IACzB;;;;;;;;;OASG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uEAAuE;IACvE,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,WAAW,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,8DAA8D;IAC9D,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,cAAc,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,MAAM,gBAAgB,GACxB,WAAW,GACX,WAAW,GACX,WAAW,GACX,gBAAgB,GAChB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,oBAAoB;IACnC,sEAAsE;IACtE,SAAS,CAAC,EAAE;QACV,MAAM,EAAE,UAAU,CAAC;QACnB;;;;;;WAMG;QACH,eAAe,CAAC,EAAE,gBAAgB,EAAE,CAAC;KACtC,CAAC;IACF,qDAAqD;IACrD,SAAS,CAAC,EAAE;QACV,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;KACvC,CAAC;IACF,0BAA0B;IAC1B,MAAM,CAAC,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,gEAAgE;QAChE,eAAe,CAAC,EAAE,gBAAgB,EAAE,CAAC;QACrC;;;;;;;;;WASG;QACH,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,wEAAwE;IACxE,YAAY,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,WAAW,EAAE,WAAW,CAAC;IACzB,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;;OAGG;IACH,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AA44BD;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D,KAAK,aAAa,GACd;IACE,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;IACnB;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,CAAC;CACtB,GACD;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAc5C,8DAA8D;AAC9D,wBAAgB,oCAAoC,IAAI,IAAI,CAE3D;AAED,sDAAsD;AACtD,wBAAsB,2BAA2B,CAC/C,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAEpC;AAwID;;;;;;;;GAQG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,oBAAoB,CAAC;IAC7B;;;;OAIG;IACH,kBAAkB,CAAC,SAAS,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtE,wEAAwE;IACxE,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAI/B;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,sBAAsB,CAAC,CAyWjC"}
|