@workflow/core 5.0.0-beta.27 → 5.0.0-beta.29

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 (50) hide show
  1. package/dist/create-hook.d.ts +2 -2
  2. package/dist/create-hook.js +1 -1
  3. package/dist/runtime/get-world-lazy.d.ts +3 -12
  4. package/dist/runtime/get-world-lazy.d.ts.map +1 -1
  5. package/dist/runtime/get-world-lazy.js +7 -24
  6. package/dist/runtime/run.d.ts +6 -2
  7. package/dist/runtime/run.d.ts.map +1 -1
  8. package/dist/runtime/run.js +9 -2
  9. package/dist/runtime/runs.d.ts +11 -1
  10. package/dist/runtime/runs.d.ts.map +1 -1
  11. package/dist/runtime/runs.js +10 -4
  12. package/dist/runtime/step-executor.d.ts +10 -0
  13. package/dist/runtime/step-executor.d.ts.map +1 -1
  14. package/dist/runtime/step-executor.js +92 -34
  15. package/dist/runtime/step-handler.d.ts.map +1 -1
  16. package/dist/runtime/step-handler.js +8 -7
  17. package/dist/runtime/step-latency.d.ts +125 -0
  18. package/dist/runtime/step-latency.d.ts.map +1 -0
  19. package/dist/runtime/step-latency.js +135 -0
  20. package/dist/runtime/suspension-handler.d.ts +7 -0
  21. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  22. package/dist/runtime/suspension-handler.js +98 -72
  23. package/dist/runtime/wait-continuation.d.ts +2 -2
  24. package/dist/runtime/wait-continuation.js +3 -3
  25. package/dist/runtime/world-init.d.ts +16 -41
  26. package/dist/runtime/world-init.d.ts.map +1 -1
  27. package/dist/runtime/world-init.js +17 -42
  28. package/dist/runtime/world-target.d.ts +11 -0
  29. package/dist/runtime/world-target.d.ts.map +1 -0
  30. package/dist/runtime/world-target.js +15 -0
  31. package/dist/runtime/world.d.ts +21 -9
  32. package/dist/runtime/world.d.ts.map +1 -1
  33. package/dist/runtime/world.js +40 -122
  34. package/dist/runtime.d.ts +3 -2
  35. package/dist/runtime.d.ts.map +1 -1
  36. package/dist/runtime.js +94 -16
  37. package/dist/serialization.d.ts.map +1 -1
  38. package/dist/serialization.js +24 -3
  39. package/dist/telemetry/semantic-conventions.d.ts +24 -0
  40. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  41. package/dist/telemetry/semantic-conventions.js +19 -1
  42. package/dist/version.d.ts +1 -1
  43. package/dist/version.js +2 -2
  44. package/dist/workflow/create-hook.d.ts.map +1 -1
  45. package/dist/workflow/create-hook.js +4 -3
  46. package/dist/workflow/world-init-stub.d.ts +2 -2
  47. package/dist/workflow/world-init-stub.js +3 -3
  48. package/dist/workflow.d.ts.map +1 -1
  49. package/dist/workflow.js +6 -9
  50. package/package.json +11 -6
@@ -0,0 +1,125 @@
1
+ import type { Event } from '@workflow/world';
2
+ /**
3
+ * Client-side latency measurement (TTFS / STSO) threaded from the
4
+ * orchestrator's inline execution path into `executeStep`.
5
+ *
6
+ * TTFS (time-to-first-step) measures run creation → the first step's body
7
+ * beginning to execute. STSO (step-to-step overhead) measures the previous
8
+ * step's terminal event → the next step's body beginning to execute. Both are
9
+ * attached to the step's terminal event so a backend can emit latency metrics
10
+ * from the event write alone, without extra event-log queries.
11
+ *
12
+ * Eligibility is decided by the orchestrator (which owns the event log) via
13
+ * {@link computeStepLatencyTracking}; the final values are computed by
14
+ * `executeStep` right before user code runs via
15
+ * {@link computeStepLatencyEventData}.
16
+ */
17
+ export interface StepLatencyTracking {
18
+ /**
19
+ * Epoch ms of run creation (from the run-id ULID, falling back to the run
20
+ * snapshot's `createdAt`). Present only when the step qualifies for TTFS.
21
+ */
22
+ ttfsAnchorMs?: number;
23
+ /**
24
+ * Wall-clock ms this invocation spent committing `hook_created` events
25
+ * before the first step (fire-and-forget `createHook()` ahead of the first
26
+ * step commits in the same suspension batch). Subtracted from TTFS so the
27
+ * metric reflects runtime overhead rather than the user's hook writes.
28
+ */
29
+ preStepBlockingMs?: number;
30
+ /**
31
+ * Epoch ms the first pre-step `attr_set` write began (its client-stamped
32
+ * `occurredAt`, falling back to `createdAt`). When present, the TTFS
33
+ * measurement ENDS here instead of at the step's code start: a
34
+ * workflow-body `experimental_setAttributes` before the first step
35
+ * resolves through an extra replay (see the `hasAttributeEvents` branch in
36
+ * runtime.ts), so everything from this write until the step body runs is
37
+ * the duration of the setAttributes call — which is subtracted by ending
38
+ * the measurement at the point where the step would otherwise have been
39
+ * scheduled.
40
+ */
41
+ preStepAttrStartMs?: number;
42
+ /**
43
+ * Epoch ms the previous step's terminal event was recorded (its
44
+ * client-stamped `occurredAt`, falling back to `createdAt`). Present only
45
+ * when the step qualifies for STSO.
46
+ */
47
+ prevStepEndMs?: number;
48
+ /** Whether turbo mode is active for this invocation. */
49
+ turbo: boolean;
50
+ }
51
+ /** Latency telemetry attached to a step's terminal event's `eventData`. */
52
+ export interface StepLatencyEventData {
53
+ ttfs?: number;
54
+ stso?: number;
55
+ optimizations?: string[];
56
+ }
57
+ /**
58
+ * Decide, from the orchestrator's view of the event log, whether the inline
59
+ * step batch about to execute qualifies for TTFS and/or STSO measurement.
60
+ * Returns undefined when neither applies. Called once per batch; the result
61
+ * is passed to the batch's first step only, so a parallel first batch emits a
62
+ * single sample rather than one per sibling.
63
+ */
64
+ export declare function computeStepLatencyTracking(params: {
65
+ /** The orchestrator's current in-memory event log (ascending order). */
66
+ events: Event[];
67
+ /**
68
+ * Whether this invocation's initial event load contained nothing beyond
69
+ * run_created/run_started/attr_set. Pre-existing hook events were written
70
+ * by an earlier invocation, so the time they added (including the queue
71
+ * hop back to this invocation) is unmeasurable and disqualifies TTFS.
72
+ * attr_set is permitted: a redelivery can land after a committed pre-step
73
+ * attr_set, and the detour it marks is subtracted via `preStepAttrStartMs`
74
+ * regardless of which invocation wrote it.
75
+ */
76
+ invocationStartedClean: boolean;
77
+ /** Epoch ms of run creation, if recoverable. Absent disqualifies TTFS. */
78
+ runCreatedAtMs: number | undefined;
79
+ /** See {@link StepLatencyTracking.preStepBlockingMs}. */
80
+ preStepBlockingMs: number;
81
+ /**
82
+ * The accumulator's value as of the suspension that wrote the run's first
83
+ * attr_set (its hook phase runs before its attr writes). When the
84
+ * measurement ends at the attr write, only hook time from before that
85
+ * point may be subtracted — later hook writes fall outside the measured
86
+ * window. Undefined when no attr suspension happened in this invocation
87
+ * (e.g. the attr_set was loaded from a redelivery's snapshot, where no
88
+ * same-invocation hook time precedes it).
89
+ */
90
+ preStepBlockingBeforeAttrMs: number | undefined;
91
+ /**
92
+ * Whether the suspension that scheduled this batch also created waits.
93
+ * Those `wait_created` writes are not in `events` yet (they were committed
94
+ * by this very suspension pass), so they must be reported separately. A
95
+ * wait disqualifies both measurements.
96
+ */
97
+ suspensionHasWaits: boolean;
98
+ /**
99
+ * Whether the suspension that scheduled this batch also created hooks
100
+ * (also not in `events` yet). Hooks keep TTFS eligible — their measured
101
+ * write time is subtracted via `preStepBlockingMs` — but disqualify STSO,
102
+ * which is only meaningful for a pure back-to-back step gap.
103
+ */
104
+ suspensionCreatedHooks: boolean;
105
+ /** Whether turbo mode is active for this invocation. */
106
+ turbo: boolean;
107
+ }): StepLatencyTracking | undefined;
108
+ /**
109
+ * Compute the latency telemetry to attach to the step's terminal event.
110
+ * Called by `executeStep` with the wall-clock timestamp taken immediately
111
+ * before user step code runs. Returns undefined when there is nothing to
112
+ * report (no tracking, or a retry attempt — retries measure neither TTFS nor
113
+ * STSO).
114
+ */
115
+ export declare function computeStepLatencyEventData(params: {
116
+ tracking: StepLatencyTracking | undefined;
117
+ /** `Date.now()` taken immediately before user step code began executing. */
118
+ stepCodeStartedAtMs: number;
119
+ attempt: number;
120
+ /** Whether this step was started lazily (no separate step_created write). */
121
+ lazyStepStart: boolean;
122
+ /** Whether the body ran optimistically, without awaiting step_started. */
123
+ optimisticStart: boolean;
124
+ }): StepLatencyEventData | undefined;
125
+ //# sourceMappingURL=step-latency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-latency.d.ts","sourceRoot":"","sources":["../../src/runtime/step-latency.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,2EAA2E;AAC3E,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAkCD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,wEAAwE;IACxE,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB;;;;;;;;OAQG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC,0EAA0E;IAC1E,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,yDAAyD;IACzD,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;;;;;;OAQG;IACH,2BAA2B,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD;;;;;OAKG;IACH,kBAAkB,EAAE,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC,wDAAwD;IACxD,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,mBAAmB,GAAG,SAAS,CA4DlC;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,QAAQ,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC1C,4EAA4E;IAC5E,mBAAmB,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,aAAa,EAAE,OAAO,CAAC;IACvB,0EAA0E;IAC1E,eAAe,EAAE,OAAO,CAAC;CAC1B,GAAG,oBAAoB,GAAG,SAAS,CA2CnC"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Event types that disqualify TTFS when present in the event log at the time
3
+ * the run's first step batch is scheduled:
4
+ *
5
+ * - Any step event means this is not the run's first step execution.
6
+ * - `hook_received` / `wait_created` / `wait_completed` mean the run's path to
7
+ * the first step depended on user-driven timing (a webhook arriving, a
8
+ * sleep elapsing), so the measurement would not reflect runtime overhead.
9
+ *
10
+ * Deliberately absent, with their cost subtracted instead:
11
+ *
12
+ * - `hook_created`: a fire-and-forget `createHook()` before the first step
13
+ * commits in the same invocation, whose measured duration is subtracted via
14
+ * {@link StepLatencyTracking.preStepBlockingMs}.
15
+ * - `attr_set` (workflow-body `experimental_setAttributes`): resolves through
16
+ * an extra replay before steps run. Subtracted by ending the measurement at
17
+ * the first attr write's timestamp instead — see
18
+ * {@link StepLatencyTracking.preStepAttrStartMs}.
19
+ */
20
+ const TTFS_DISQUALIFYING_EVENT_TYPES = new Set([
21
+ 'step_created',
22
+ 'step_started',
23
+ 'step_completed',
24
+ 'step_failed',
25
+ 'step_retrying',
26
+ 'hook_received',
27
+ 'wait_created',
28
+ 'wait_completed',
29
+ ]);
30
+ /**
31
+ * Decide, from the orchestrator's view of the event log, whether the inline
32
+ * step batch about to execute qualifies for TTFS and/or STSO measurement.
33
+ * Returns undefined when neither applies. Called once per batch; the result
34
+ * is passed to the batch's first step only, so a parallel first batch emits a
35
+ * single sample rather than one per sibling.
36
+ */
37
+ export function computeStepLatencyTracking(params) {
38
+ const { events } = params;
39
+ let ttfsEligible = params.invocationStartedClean &&
40
+ params.runCreatedAtMs !== undefined &&
41
+ !params.suspensionHasWaits;
42
+ let preStepAttrStartMs;
43
+ if (ttfsEligible) {
44
+ for (const event of events) {
45
+ if (TTFS_DISQUALIFYING_EVENT_TYPES.has(event.eventType)) {
46
+ ttfsEligible = false;
47
+ break;
48
+ }
49
+ if (event.eventType === 'attr_set') {
50
+ const attrStartMs = +(event.occurredAt ?? event.createdAt);
51
+ preStepAttrStartMs =
52
+ preStepAttrStartMs === undefined
53
+ ? attrStartMs
54
+ : Math.min(preStepAttrStartMs, attrStartMs);
55
+ }
56
+ }
57
+ }
58
+ // STSO: the two steps ran back-to-back — the newest known event is the
59
+ // previous step's terminal event, with nothing (hook_received, waits,
60
+ // attr_set, ...) in between and this suspension scheduling nothing but
61
+ // steps.
62
+ let prevStepEndMs;
63
+ const lastEvent = events[events.length - 1];
64
+ if (!params.suspensionHasWaits &&
65
+ !params.suspensionCreatedHooks &&
66
+ lastEvent &&
67
+ (lastEvent.eventType === 'step_completed' ||
68
+ lastEvent.eventType === 'step_failed')) {
69
+ prevStepEndMs = +(lastEvent.occurredAt ?? lastEvent.createdAt);
70
+ }
71
+ if (!ttfsEligible && prevStepEndMs === undefined) {
72
+ return undefined;
73
+ }
74
+ return {
75
+ ...(ttfsEligible
76
+ ? {
77
+ ttfsAnchorMs: params.runCreatedAtMs,
78
+ // When the measurement ends at the first attr write, only hook
79
+ // time from before that point is inside the measured window.
80
+ preStepBlockingMs: preStepAttrStartMs !== undefined
81
+ ? (params.preStepBlockingBeforeAttrMs ?? 0)
82
+ : params.preStepBlockingMs,
83
+ ...(preStepAttrStartMs !== undefined ? { preStepAttrStartMs } : {}),
84
+ }
85
+ : {}),
86
+ ...(prevStepEndMs !== undefined ? { prevStepEndMs } : {}),
87
+ turbo: params.turbo,
88
+ };
89
+ }
90
+ /**
91
+ * Compute the latency telemetry to attach to the step's terminal event.
92
+ * Called by `executeStep` with the wall-clock timestamp taken immediately
93
+ * before user step code runs. Returns undefined when there is nothing to
94
+ * report (no tracking, or a retry attempt — retries measure neither TTFS nor
95
+ * STSO).
96
+ */
97
+ export function computeStepLatencyEventData(params) {
98
+ const { tracking } = params;
99
+ if (!tracking || params.attempt !== 1) {
100
+ return undefined;
101
+ }
102
+ // Clamp at 0: cross-invocation timestamps can come from another machine's
103
+ // clock, so small skews must not produce negative durations.
104
+ //
105
+ // A pre-step setAttributes detour ends the measurement at the first attr
106
+ // write instead of the step's code start — the remainder is the duration
107
+ // of the setAttributes call (resolved via an extra replay), which is
108
+ // subtracted rather than disqualifying the sample. In that case
109
+ // `tracking.preStepBlockingMs` already holds only the hook time from
110
+ // BEFORE the attr write — hook writes after the window closed are excluded
111
+ // by computeStepLatencyTracking (see preStepBlockingBeforeAttrMs).
112
+ const ttfsEndMs = tracking.preStepAttrStartMs ?? params.stepCodeStartedAtMs;
113
+ const ttfs = tracking.ttfsAnchorMs !== undefined
114
+ ? Math.max(0, ttfsEndMs - tracking.ttfsAnchorMs - (tracking.preStepBlockingMs ?? 0))
115
+ : undefined;
116
+ const stso = tracking.prevStepEndMs !== undefined
117
+ ? Math.max(0, params.stepCodeStartedAtMs - tracking.prevStepEndMs)
118
+ : undefined;
119
+ if (ttfs === undefined && stso === undefined) {
120
+ return undefined;
121
+ }
122
+ const optimizations = [];
123
+ if (tracking.turbo)
124
+ optimizations.push('turbo');
125
+ if (params.lazyStepStart)
126
+ optimizations.push('lazyStepStart');
127
+ if (params.optimisticStart)
128
+ optimizations.push('optimisticStart');
129
+ return {
130
+ ...(ttfs !== undefined ? { ttfs } : {}),
131
+ ...(stso !== undefined ? { stso } : {}),
132
+ optimizations,
133
+ };
134
+ }
135
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcC1sYXRlbmN5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvc3RlcC1sYXRlbmN5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQTJEQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBQ0gsTUFBTSw4QkFBOEIsR0FBb0MsSUFBSSxHQUFHLENBQzdFO0lBQ0UsY0FBYztJQUNkLGNBQWM7SUFDZCxnQkFBZ0I7SUFDaEIsYUFBYTtJQUNiLGVBQWU7SUFDZixlQUFlO0lBQ2YsY0FBYztJQUNkLGdCQUFnQjtDQUNqQixDQUNGLENBQUM7QUFFRjs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsMEJBQTBCLENBQUMsTUEyQzFDO0lBQ0MsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQztJQUUxQixJQUFJLFlBQVksR0FDZCxNQUFNLENBQUMsc0JBQXNCO1FBQzdCLE1BQU0sQ0FBQyxjQUFjLEtBQUssU0FBUztRQUNuQyxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQztJQUM3QixJQUFJLGtCQUFzQyxDQUFDO0lBQzNDLElBQUksWUFBWSxFQUFFLENBQUM7UUFDakIsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUMzQixJQUFJLDhCQUE4QixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFDeEQsWUFBWSxHQUFHLEtBQUssQ0FBQztnQkFDckIsTUFBTTtZQUNSLENBQUM7WUFDRCxJQUFJLEtBQUssQ0FBQyxTQUFTLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQ25DLE1BQU0sV0FBVyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBVSxJQUFJLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDM0Qsa0JBQWtCO29CQUNoQixrQkFBa0IsS0FBSyxTQUFTO3dCQUM5QixDQUFDLENBQUMsV0FBVzt3QkFDYixDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcs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QUFDO0lBQ25CLENBQUM7SUFFRCxNQUFNLGFBQWEsR0FBYSxFQUFFLENBQUM7SUFDbkMsSUFBSSxRQUFRLENBQUMsS0FBSztRQUFFLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDaEQsSUFBSSxNQUFNLENBQUMsYUFBYTtRQUFFLGFBQWEsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDOUQsSUFBSSxNQUFNLENBQUMsZUFBZTtRQUFFLGFBQWEsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUVsRSxPQUFPO1FBQ0wsR0FBRyxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN2QyxHQUFHLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3ZDLGFBQWE7S0FDZCxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRXZlbnQgfSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuXG4vKipcbiAqIENsaWVudC1zaWRlIGxhdGVuY3kgbWVhc3VyZW1lbnQgKFRURlMgLyBTVFNPKSB0aHJlYWRlZCBmcm9tIHRoZVxuICogb3JjaGVzdHJhdG9yJ3MgaW5saW5lIGV4ZWN1dGlvbiBwYXRoIGludG8gYGV4ZWN1dGVTdGVwYC5cbiAqXG4gKiBUVEZTICh0aW1lLXRvLWZpcnN0LXN0ZXApIG1lYXN1cmVzIHJ1biBjcmVhdGlvbiDihpIgdGhlIGZpcnN0IHN0ZXAncyBib2R5XG4gKiBiZWdpbm5pbmcgdG8gZXhlY3V0ZS4gU1RTTyAoc3RlcC10by1zdGVwIG92ZXJoZWFkKSBtZWFzdXJlcyB0aGUgcHJldmlvdXNcbiAqIHN0ZXAncyB0ZXJtaW5hbCBldmVudCDihpIgdGhlIG5leHQgc3RlcCdzIGJvZHkgYmVnaW5uaW5nIHRvIGV4ZWN1dGUuIEJvdGggYXJlXG4gKiBhdHRhY2hlZCB0byB0aGUgc3RlcCdzIHRlcm1pbmFsIGV2ZW50IHNvIGEgYmFja2VuZCBjYW4gZW1pdCBsYXRlbmN5IG1ldHJpY3NcbiAqIGZyb20gdGhlIGV2ZW50IHdyaXRlIGFsb25lLCB3aXRob3V0IGV4dHJhIGV2ZW50LWxvZyBxdWVyaWVzLlxuICpcbiAqIEVsaWdpYmlsaXR5IGlzIGRlY2lkZWQgYnkgdGhlIG9yY2hlc3RyYXRvciAod2hpY2ggb3ducyB0aGUgZXZlbnQgbG9nKSB2aWFcbiAqIHtAbGluayBjb21wdXRlU3RlcExhdGVuY3lUcmFja2luZ307IHRoZSBmaW5hbCB2YWx1ZXMgYXJlIGNvbXB1dGVkIGJ5XG4gKiBgZXhlY3V0ZVN0ZXBgIHJpZ2h0IGJlZm9yZSB1c2VyIGNvZGUgcnVucyB2aWFcbiAqIHtAbGluayBjb21wdXRlU3RlcExhdGVuY3lFdmVudERhdGF9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0ZXBMYXRlbmN5VHJhY2tpbmcge1xuICAvKipcbiAgICogRXBvY2ggbXMgb2YgcnVuIGNyZWF0aW9uIChmcm9tIHRoZSBydW4taWQgVUxJRCwgZmFsbGluZyBiYWNrIHRvIHRoZSBydW5cbiAgICogc25hcHNob3QncyBgY3JlYXRlZEF0YCkuIFByZXNlbnQgb25seSB3aGVuIHRoZSBzdGVwIHF1YWxpZmllcyBmb3IgVFRGUy5cbiAgICovXG4gIHR0ZnNBbmNob3JNcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFdhbGwtY2xvY2sgbXMgdGhpcyBpbnZvY2F0aW9uIHNwZW50IGNvbW1pdHRpbmcgYGhvb2tfY3JlYXRlZGAgZXZlbnRzXG4gICAqIGJlZm9yZSB0aGUgZmlyc3Qgc3RlcCAoZmlyZS1hbmQtZm9yZ2V0IGBjcmVhdGVIb29rKClgIGFoZWFkIG9mIHRoZSBmaXJzdFxuICAgKiBzdGVwIGNvbW1pdHMgaW4gdGhlIHNhbWUgc3VzcGVuc2lvbiBiYXRjaCkuIFN1YnRyYWN0ZWQgZnJvbSBUVEZTIHNvIHRoZVxuICAgKiBtZXRyaWMgcmVmbGVjdHMgcnVudGltZSBvdmVyaGVhZCByYXRoZXIgdGhhbiB0aGUgdXNlcidzIGhvb2sgd3JpdGVzLlxuICAgKi9cbiAgcHJlU3RlcEJsb2NraW5nTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBFcG9jaCBtcyB0aGUgZmlyc3QgcHJlLXN0ZXAgYGF0dHJfc2V0YCB3cml0ZSBiZWdhbiAoaXRzIGNsaWVudC1zdGFtcGVkXG4gICAqIGBvY2N1cnJlZEF0YCwgZmFsbGluZyBiYWNrIHRvIGBjcmVhdGVkQXRgKS4gV2hlbiBwcmVzZW50LCB0aGUgVFRGU1xuICAgKiBtZWFzdXJlbWVudCBFTkRTIGhlcmUgaW5zdGVhZCBvZiBhdCB0aGUgc3RlcCdzIGNvZGUgc3RhcnQ6IGFcbiAgICogd29ya2Zsb3ctYm9keSBgZXhwZXJpbWVudGFsX3NldEF0dHJpYnV0ZXNgIGJlZm9yZSB0aGUgZmlyc3Qgc3RlcFxuICAgKiByZXNvbHZlcyB0aHJvdWdoIGFuIGV4dHJhIHJlcGxheSAoc2VlIHRoZSBgaGFzQXR0cmlidXRlRXZlbnRzYCBicmFuY2ggaW5cbiAgICogcnVudGltZS50cyksIHNvIGV2ZXJ5dGhpbmcgZnJvbSB0aGlzIHdyaXRlIHVudGlsIHRoZSBzdGVwIGJvZHkgcnVucyBpc1xuICAgKiB0aGUgZHVyYXRpb24gb2YgdGhlIHNldEF0dHJpYnV0ZXMgY2FsbCDigJQgd2hpY2ggaXMgc3VidHJhY3RlZCBieSBlbmRpbmdcbiAgICogdGhlIG1lYXN1cmVtZW50IGF0IHRoZSBwb2ludCB3aGVyZSB0aGUgc3RlcCB3b3VsZCBvdGhlcndpc2UgaGF2ZSBiZWVuXG4gICAqIHNjaGVkdWxlZC5cbiAgICovXG4gIHByZVN0ZXBBdHRyU3RhcnRNcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIEVwb2NoIG1zIHRoZSBwcmV2aW91cyBzdGVwJ3MgdGVybWluYWwgZXZlbnQgd2FzIHJlY29yZGVkIChpdHNcbiAgICogY2xpZW50LXN0YW1wZWQgYG9jY3VycmVkQXRgLCBmYWxsaW5nIGJhY2sgdG8gYGNyZWF0ZWRBdGApLiBQcmVzZW50IG9ubHlcbiAgICogd2hlbiB0aGUgc3RlcCBxdWFsaWZpZXMgZm9yIFNUU08uXG4gICAqL1xuICBwcmV2U3RlcEVuZE1zPzogbnVtYmVyO1xuICAvKiogV2hldGhlciB0dXJibyBtb2RlIGlzIGFjdGl2ZSBmb3IgdGhpcyBpbnZvY2F0aW9uLiAqL1xuICB0dXJibzogYm9vbGVhbjtcbn1cblxuLyoqIExhdGVuY3kgdGVsZW1ldHJ5IGF0dGFjaGVkIHRvIGEgc3RlcCdzIHRlcm1pbmFsIGV2ZW50J3MgYGV2ZW50RGF0YWAuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0ZXBMYXRlbmN5RXZlbnREYXRhIHtcbiAgdHRmcz86IG51bWJlcjtcbiAgc3Rzbz86IG51bWJlcjtcbiAgb3B0aW1pemF0aW9ucz86IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIEV2ZW50IHR5cGVzIHRoYXQgZGlzcXVhbGlmeSBUVEZTIHdoZW4gcHJlc2VudCBpbiB0aGUgZXZlbnQgbG9nIGF0IHRoZSB0aW1lXG4gKiB0aGUgcnVuJ3MgZmlyc3Qgc3RlcCBiYXRjaCBpcyBzY2hlZHVsZWQ6XG4gKlxuICogLSBBbnkgc3RlcCBldmVudCBtZWFucyB0aGlzIGlzIG5vdCB0aGUgcnVuJ3MgZmlyc3Qgc3RlcCBleGVjdXRpb24uXG4gKiAtIGBob29rX3JlY2VpdmVkYCAvIGB3YWl0X2NyZWF0ZWRgIC8gYHdhaXRfY29tcGxldGVkYCBtZWFuIHRoZSBydW4ncyBwYXRoIHRvXG4gKiAgIHRoZSBmaXJzdCBzdGVwIGRlcGVuZGVkIG9uIHVzZXItZHJpdmVuIHRpbWluZyAoYSB3ZWJob29rIGFycml2aW5nLCBhXG4gKiAgIHNsZWVwIGVsYXBzaW5nKSwgc28gdGhlIG1lYXN1cmVtZW50IHdvdWxkIG5vdCByZWZsZWN0IHJ1bnRpbWUgb3ZlcmhlYWQuXG4gKlxuICogRGVsaWJlcmF0ZWx5IGFic2VudCwgd2l0aCB0aGVpciBjb3N0IHN1YnRyYWN0ZWQgaW5zdGVhZDpcbiAqXG4gKiAtIGBob29rX2NyZWF0ZWRgOiBhIGZpcmUtYW5kLWZvcmdldCBgY3JlYXRlSG9vaygpYCBiZWZvcmUgdGhlIGZpcnN0IHN0ZXBcbiAqICAgY29tbWl0cyBpbiB0aGUgc2FtZSBpbnZvY2F0aW9uLCB3aG9zZSBtZWFzdXJlZCBkdXJhdGlvbiBpcyBzdWJ0cmFjdGVkIHZpYVxuICogICB7QGxpbmsgU3RlcExhdGVuY3lUcmFja2luZy5wcmVTdGVwQmxvY2tpbmdNc30uXG4gKiAtIGBhdHRyX3NldGAgKHdvcmtmbG93LWJvZHkgYGV4cGVyaW1lbnRhbF9zZXRBdHRyaWJ1dGVzYCk6IHJlc29sdmVzIHRocm91Z2hcbiAqICAgYW4gZXh0cmEgcmVwbGF5IGJlZm9yZSBzdGVwcyBydW4uIFN1YnRyYWN0ZWQgYnkgZW5kaW5nIHRoZSBtZWFzdXJlbWVudCBhdFxuICogICB0aGUgZmlyc3QgYXR0ciB3cml0ZSdzIHRpbWVzdGFtcCBpbnN0ZWFkIOKAlCBzZWVcbiAqICAge0BsaW5rIFN0ZXBMYXRlbmN5VHJhY2tpbmcucHJlU3RlcEF0dHJTdGFydE1zfS5cbiAqL1xuY29uc3QgVFRGU19ESVNRVUFMSUZZSU5HX0VWRU5UX1RZUEVTOiBSZWFkb25seVNldDxFdmVudFsnZXZlbnRUeXBlJ10+ID0gbmV3IFNldChcbiAgW1xuICAgICdzdGVwX2NyZWF0ZWQnLFxuICAgICdzdGVwX3N0YXJ0ZWQnLFxuICAgICdzdGVwX2NvbXBsZXRlZCcsXG4gICAgJ3N0ZXBfZmFpbGVkJyxcbiAgICAnc3RlcF9yZXRyeWluZycsXG4gICAgJ2hvb2tfcmVjZWl2ZWQnLFxuICAgICd3YWl0X2NyZWF0ZWQnLFxuICAgICd3YWl0X2NvbXBsZXRlZCcsXG4gIF1cbik7XG5cbi8qKlxuICogRGVjaWRlLCBmcm9tIHRoZSBvcmNoZXN0cmF0b3IncyB2aWV3IG9mIHRoZSBldmVudCBsb2csIHdoZXRoZXIgdGhlIGlubGluZVxuICogc3RlcCBiYXRjaCBhYm91dCB0byBleGVjdXRlIHF1YWxpZmllcyBmb3IgVFRGUyBhbmQvb3IgU1RTTyBtZWFzdXJlbWVudC5cbiAqIFJldHVybnMgdW5kZWZpbmVkIHdoZW4gbmVpdGhlciBhcHBsaWVzLiBDYWxsZWQgb25jZSBwZXIgYmF0Y2g7IHRoZSByZXN1bHRcbiAqIGlzIHBhc3NlZCB0byB0aGUgYmF0Y2gncyBmaXJzdCBzdGVwIG9ubHksIHNvIGEgcGFyYWxsZWwgZmlyc3QgYmF0Y2ggZW1pdHMgYVxuICogc2luZ2xlIHNhbXBsZSByYXRoZXIgdGhhbiBvbmUgcGVyIHNpYmxpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlU3RlcExhdGVuY3lUcmFja2luZyhwYXJhbXM6IHtcbiAgLyoqIFRoZSBvcmNoZXN0cmF0b3IncyBjdXJyZW50IGluLW1lbW9yeSBldmVudCBsb2cgKGFzY2VuZGluZyBvcmRlcikuICovXG4gIGV2ZW50czogRXZlbnRbXTtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhpcyBpbnZvY2F0aW9uJ3MgaW5pdGlhbCBldmVudCBsb2FkIGNvbnRhaW5lZCBub3RoaW5nIGJleW9uZFxuICAgKiBydW5fY3JlYXRlZC9ydW5fc3RhcnRlZC9hdHRyX3NldC4gUHJlLWV4aXN0aW5nIGhvb2sgZXZlbnRzIHdlcmUgd3JpdHRlblxuICAgKiBieSBhbiBlYXJsaWVyIGludm9jYXRpb24sIHNvIHRoZSB0aW1lIHRoZXkgYWRkZWQgKGluY2x1ZGluZyB0aGUgcXVldWVcbiAgICogaG9wIGJhY2sgdG8gdGhpcyBpbnZvY2F0aW9uKSBpcyB1bm1lYXN1cmFibGUgYW5kIGRpc3F1YWxpZmllcyBUVEZTLlxuICAgKiBhdHRyX3NldCBpcyBwZXJtaXR0ZWQ6IGEgcmVkZWxpdmVyeSBjYW4gbGFuZCBhZnRlciBhIGNvbW1pdHRlZCBwcmUtc3RlcFxuICAgKiBhdHRyX3NldCwgYW5kIHRoZSBkZXRvdXIgaXQgbWFya3MgaXMgc3VidHJhY3RlZCB2aWEgYHByZVN0ZXBBdHRyU3RhcnRNc2BcbiAgICogcmVnYXJkbGVzcyBvZiB3aGljaCBpbnZvY2F0aW9uIHdyb3RlIGl0LlxuICAgKi9cbiAgaW52b2NhdGlvblN0YXJ0ZWRDbGVhbjogYm9vbGVhbjtcbiAgLyoqIEVwb2NoIG1zIG9mIHJ1biBjcmVhdGlvbiwgaWYgcmVjb3ZlcmFibGUuIEFic2VudCBkaXNxdWFsaWZpZXMgVFRGUy4gKi9cbiAgcnVuQ3JlYXRlZEF0TXM6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgLyoqIFNlZSB7QGxpbmsgU3RlcExhdGVuY3lUcmFja2luZy5wcmVTdGVwQmxvY2tpbmdNc30uICovXG4gIHByZVN0ZXBCbG9ja2luZ01zOiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgYWNjdW11bGF0b3IncyB2YWx1ZSBhcyBvZiB0aGUgc3VzcGVuc2lvbiB0aGF0IHdyb3RlIHRoZSBydW4ncyBmaXJzdFxuICAgKiBhdHRyX3NldCAoaXRzIGhvb2sgcGhhc2UgcnVucyBiZWZvcmUgaXRzIGF0dHIgd3JpdGVzKS4gV2hlbiB0aGVcbiAgICogbWVhc3VyZW1lbnQgZW5kcyBhdCB0aGUgYXR0ciB3cml0ZSwgb25seSBob29rIHRpbWUgZnJvbSBiZWZvcmUgdGhhdFxuICAgKiBwb2ludCBtYXkgYmUgc3VidHJhY3RlZCDigJQgbGF0ZXIgaG9vayB3cml0ZXMgZmFsbCBvdXRzaWRlIHRoZSBtZWFzdXJlZFxuICAgKiB3aW5kb3cuIFVuZGVmaW5lZCB3aGVuIG5vIGF0dHIgc3VzcGVuc2lvbiBoYXBwZW5lZCBpbiB0aGlzIGludm9jYXRpb25cbiAgICogKGUuZy4gdGhlIGF0dHJfc2V0IHdhcyBsb2FkZWQgZnJvbSBhIHJlZGVsaXZlcnkncyBzbmFwc2hvdCwgd2hlcmUgbm9cbiAgICogc2FtZS1pbnZvY2F0aW9uIGhvb2sgdGltZSBwcmVjZWRlcyBpdCkuXG4gICAqL1xuICBwcmVTdGVwQmxvY2tpbmdCZWZvcmVBdHRyTXM6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHN1c3BlbnNpb24gdGhhdCBzY2hlZHVsZWQgdGhpcyBiYXRjaCBhbHNvIGNyZWF0ZWQgd2FpdHMuXG4gICAqIFRob3NlIGB3YWl0X2NyZWF0ZWRgIHdyaXRlcyBhcmUgbm90IGluIGBldmVudHNgIHlldCAodGhleSB3ZXJlIGNvbW1pdHRlZFxuICAgKiBieSB0aGlzIHZlcnkgc3VzcGVuc2lvbiBwYXNzKSwgc28gdGhleSBtdXN0IGJlIHJlcG9ydGVkIHNlcGFyYXRlbHkuIEFcbiAgICogd2FpdCBkaXNxdWFsaWZpZXMgYm90aCBtZWFzdXJlbWVudHMuXG4gICAqL1xuICBzdXNwZW5zaW9uSGFzV2FpdHM6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBzdXNwZW5zaW9uIHRoYXQgc2NoZWR1bGVkIHRoaXMgYmF0Y2ggYWxzbyBjcmVhdGVkIGhvb2tzXG4gICAqIChhbHNvIG5vdCBpbiBgZXZlbnRzYCB5ZXQpLiBIb29rcyBrZWVwIFRURlMgZWxpZ2libGUg4oCUIHRoZWlyIG1lYXN1cmVkXG4gICAqIHdyaXRlIHRpbWUgaXMgc3VidHJhY3RlZCB2aWEgYHByZVN0ZXBCbG9ja2luZ01zYCDigJQgYnV0IGRpc3F1YWxpZnkgU1RTTyxcbiAgICogd2hpY2ggaXMgb25seSBtZWFuaW5nZnVsIGZvciBhIHB1cmUgYmFjay10by1iYWNrIHN0ZXAgZ2FwLlxuICAgKi9cbiAgc3VzcGVuc2lvbkNyZWF0ZWRIb29rczogYm9vbGVhbjtcbiAgLyoqIFdoZXRoZXIgdHVyYm8gbW9kZSBpcyBhY3RpdmUgZm9yIHRoaXMgaW52b2NhdGlvbi4gKi9cbiAgdHVyYm86IGJvb2xlYW47XG59KTogU3RlcExhdGVuY3lUcmFja2luZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHsgZXZlbnRzIH0gPSBwYXJhbXM7XG5cbiAgbGV0IHR0ZnNFbGlnaWJsZSA9XG4gICAgcGFyYW1zLmludm9jYXRpb25TdGFydGVkQ2xlYW4gJiZcbiAgICBwYXJhbXMucnVuQ3JlYXRlZEF0TXMgIT09IHVuZGVmaW5lZCAmJlxuICAgICFwYXJhbXMuc3VzcGVuc2lvbkhhc1dhaXRzO1xuICBsZXQgcHJlU3RlcEF0dHJTdGFydE1zOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIGlmICh0dGZzRWxpZ2libGUpIHtcbiAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIGV2ZW50cykge1xuICAgICAgaWYgKFRURlNfRElTUVVBTElGWUlOR19FVkVOVF9UWVBFUy5oYXMoZXZlbnQuZXZlbnRUeXBlKSkge1xuICAgICAgICB0dGZzRWxpZ2libGUgPSBmYWxzZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQuZXZlbnRUeXBlID09PSAnYXR0cl9zZXQnKSB7XG4gICAgICAgIGNvbnN0IGF0dHJTdGFydE1zID0gKyhldmVudC5vY2N1cnJlZEF0ID8/IGV2ZW50LmNyZWF0ZWRBdCk7XG4gICAgICAgIHByZVN0ZXBBdHRyU3RhcnRNcyA9XG4gICAgICAgICAgcHJlU3RlcEF0dHJTdGFydE1zID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgID8gYXR0clN0YXJ0TXNcbiAgICAgICAgICAgIDogTWF0aC5taW4ocHJlU3RlcEF0dHJTdGFydE1zLCBhdHRyU3RhcnRNcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gU1RTTzogdGhlIHR3byBzdGVwcyByYW4gYmFjay10by1iYWNrIOKAlCB0aGUgbmV3ZXN0IGtub3duIGV2ZW50IGlzIHRoZVxuICAvLyBwcmV2aW91cyBzdGVwJ3MgdGVybWluYWwgZXZlbnQsIHdpdGggbm90aGluZyAoaG9va19yZWNlaXZlZCwgd2FpdHMsXG4gIC8vIGF0dHJfc2V0LCAuLi4pIGluIGJldHdlZW4gYW5kIHRoaXMgc3VzcGVuc2lvbiBzY2hlZHVsaW5nIG5vdGhpbmcgYnV0XG4gIC8vIHN0ZXBzLlxuICBsZXQgcHJldlN0ZXBFbmRNczogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICBjb25zdCBsYXN0RXZlbnQgPSBldmVudHNbZXZlbnRzLmxlbmd0aCAtIDFdO1xuICBpZiAoXG4gICAgIXBhcmFtcy5zdXNwZW5zaW9uSGFzV2FpdHMgJiZcbiAgICAhcGFyYW1zLnN1c3BlbnNpb25DcmVhdGVkSG9va3MgJiZcbiAgICBsYXN0RXZlbnQgJiZcbiAgICAobGFzdEV2ZW50LmV2ZW50VHlwZSA9PT0gJ3N0ZXBfY29tcGxldGVkJyB8fFxuICAgICAgbGFzdEV2ZW50LmV2ZW50VHlwZSA9PT0gJ3N0ZXBfZmFpbGVkJylcbiAgKSB7XG4gICAgcHJldlN0ZXBFbmRNcyA9ICsobGFzdEV2ZW50Lm9jY3VycmVkQXQgPz8gbGFzdEV2ZW50LmNyZWF0ZWRBdCk7XG4gIH1cblxuICBpZiAoIXR0ZnNFbGlnaWJsZSAmJiBwcmV2U3RlcEVuZE1zID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi4odHRmc0VsaWdpYmxlXG4gICAgICA/IHtcbiAgICAgICAgICB0dGZzQW5jaG9yTXM6IHBhcmFtcy5ydW5DcmVhdGVkQXRNcyxcbiAgICAgICAgICAvLyBXaGVuIHRoZSBtZWFzdXJlbWVudCBlbmRzIGF0IHRoZSBmaXJzdCBhdHRyIHdyaXRlLCBvbmx5IGhvb2tcbiAgICAgICAgICAvLyB0aW1lIGZyb20gYmVmb3JlIHRoYXQgcG9pbnQgaXMgaW5zaWRlIHRoZSBtZWFzdXJlZCB3aW5kb3cuXG4gICAgICAgICAgcHJlU3RlcEJsb2NraW5nTXM6XG4gICAgICAgICAgICBwcmVTdGVwQXR0clN0YXJ0TXMgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICA/IChwYXJhbXMucHJlU3RlcEJsb2NraW5nQmVmb3JlQXR0ck1zID8/IDApXG4gICAgICAgICAgICAgIDogcGFyYW1zLnByZVN0ZXBCbG9ja2luZ01zLFxuICAgICAgICAgIC4uLihwcmVTdGVwQXR0clN0YXJ0TXMgIT09IHVuZGVmaW5lZCA/IHsgcHJlU3RlcEF0dHJTdGFydE1zIH0gOiB7fSksXG4gICAgICAgIH1cbiAgICAgIDoge30pLFxuICAgIC4uLihwcmV2U3RlcEVuZE1zICE9PSB1bmRlZmluZWQgPyB7IHByZXZTdGVwRW5kTXMgfSA6IHt9KSxcbiAgICB0dXJibzogcGFyYW1zLnR1cmJvLFxuICB9O1xufVxuXG4vKipcbiAqIENvbXB1dGUgdGhlIGxhdGVuY3kgdGVsZW1ldHJ5IHRvIGF0dGFjaCB0byB0aGUgc3RlcCdzIHRlcm1pbmFsIGV2ZW50LlxuICogQ2FsbGVkIGJ5IGBleGVjdXRlU3RlcGAgd2l0aCB0aGUgd2FsbC1jbG9jayB0aW1lc3RhbXAgdGFrZW4gaW1tZWRpYXRlbHlcbiAqIGJlZm9yZSB1c2VyIHN0ZXAgY29kZSBydW5zLiBSZXR1cm5zIHVuZGVmaW5lZCB3aGVuIHRoZXJlIGlzIG5vdGhpbmcgdG9cbiAqIHJlcG9ydCAobm8gdHJhY2tpbmcsIG9yIGEgcmV0cnkgYXR0ZW1wdCDigJQgcmV0cmllcyBtZWFzdXJlIG5laXRoZXIgVFRGUyBub3JcbiAqIFNUU08pLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29tcHV0ZVN0ZXBMYXRlbmN5RXZlbnREYXRhKHBhcmFtczoge1xuICB0cmFja2luZzogU3RlcExhdGVuY3lUcmFja2luZyB8IHVuZGVmaW5lZDtcbiAgLyoqIGBEYXRlLm5vdygpYCB0YWtlbiBpbW1lZGlhdGVseSBiZWZvcmUgdXNlciBzdGVwIGNvZGUgYmVnYW4gZXhlY3V0aW5nLiAqL1xuICBzdGVwQ29kZVN0YXJ0ZWRBdE1zOiBudW1iZXI7XG4gIGF0dGVtcHQ6IG51bWJlcjtcbiAgLyoqIFdoZXRoZXIgdGhpcyBzdGVwIHdhcyBzdGFydGVkIGxhemlseSAobm8gc2VwYXJhdGUgc3RlcF9jcmVhdGVkIHdyaXRlKS4gKi9cbiAgbGF6eVN0ZXBTdGFydDogYm9vbGVhbjtcbiAgLyoqIFdoZXRoZXIgdGhlIGJvZHkgcmFuIG9wdGltaXN0aWNhbGx5LCB3aXRob3V0IGF3YWl0aW5nIHN0ZXBfc3RhcnRlZC4gKi9cbiAgb3B0aW1pc3RpY1N0YXJ0OiBib29sZWFuO1xufSk6IFN0ZXBMYXRlbmN5RXZlbnREYXRhIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgeyB0cmFja2luZyB9ID0gcGFyYW1zO1xuICBpZiAoIXRyYWNraW5nIHx8IHBhcmFtcy5hdHRlbXB0ICE9PSAxKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIENsYW1wIGF0IDA6IGNyb3NzLWludm9jYXRpb24gdGltZXN0YW1wcyBjYW4gY29tZSBmcm9tIGFub3RoZXIgbWFjaGluZSdzXG4gIC8vIGNsb2NrLCBzbyBzbWFsbCBza2V3cyBtdXN0IG5vdCBwcm9kdWNlIG5lZ2F0aXZlIGR1cmF0aW9ucy5cbiAgLy9cbiAgLy8gQSBwcmUtc3RlcCBzZXRBdHRyaWJ1dGVzIGRldG91ciBlbmRzIHRoZSBtZWFzdXJlbWVudCBhdCB0aGUgZmlyc3QgYXR0clxuICAvLyB3cml0ZSBpbnN0ZWFkIG9mIHRoZSBzdGVwJ3MgY29kZSBzdGFydCDigJQgdGhlIHJlbWFpbmRlciBpcyB0aGUgZHVyYXRpb25cbiAgLy8gb2YgdGhlIHNldEF0dHJpYnV0ZXMgY2FsbCAocmVzb2x2ZWQgdmlhIGFuIGV4dHJhIHJlcGxheSksIHdoaWNoIGlzXG4gIC8vIHN1YnRyYWN0ZWQgcmF0aGVyIHRoYW4gZGlzcXVhbGlmeWluZyB0aGUgc2FtcGxlLiBJbiB0aGF0IGNhc2VcbiAgLy8gYHRyYWNraW5nLnByZVN0ZXBCbG9ja2luZ01zYCBhbHJlYWR5IGhvbGRzIG9ubHkgdGhlIGhvb2sgdGltZSBmcm9tXG4gIC8vIEJFRk9SRSB0aGUgYXR0ciB3cml0ZSDigJQgaG9vayB3cml0ZXMgYWZ0ZXIgdGhlIHdpbmRvdyBjbG9zZWQgYXJlIGV4Y2x1ZGVkXG4gIC8vIGJ5IGNvbXB1dGVTdGVwTGF0ZW5jeVRyYWNraW5nIChzZWUgcHJlU3RlcEJsb2NraW5nQmVmb3JlQXR0ck1zKS5cbiAgY29uc3QgdHRmc0VuZE1zID0gdHJhY2tpbmcucHJlU3RlcEF0dHJTdGFydE1zID8/IHBhcmFtcy5zdGVwQ29kZVN0YXJ0ZWRBdE1zO1xuICBjb25zdCB0dGZzID1cbiAgICB0cmFja2luZy50dGZzQW5jaG9yTXMgIT09IHVuZGVmaW5lZFxuICAgICAgPyBNYXRoLm1heChcbiAgICAgICAgICAwLFxuICAgICAgICAgIHR0ZnNFbmRNcyAtIHRyYWNraW5nLnR0ZnNBbmNob3JNcyAtICh0cmFja2luZy5wcmVTdGVwQmxvY2tpbmdNcyA/PyAwKVxuICAgICAgICApXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgY29uc3Qgc3RzbyA9XG4gICAgdHJhY2tpbmcucHJldlN0ZXBFbmRNcyAhPT0gdW5kZWZpbmVkXG4gICAgICA/IE1hdGgubWF4KDAsIHBhcmFtcy5zdGVwQ29kZVN0YXJ0ZWRBdE1zIC0gdHJhY2tpbmcucHJldlN0ZXBFbmRNcylcbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gIGlmICh0dGZzID09PSB1bmRlZmluZWQgJiYgc3RzbyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IG9wdGltaXphdGlvbnM6IHN0cmluZ1tdID0gW107XG4gIGlmICh0cmFja2luZy50dXJibykgb3B0aW1pemF0aW9ucy5wdXNoKCd0dXJibycpO1xuICBpZiAocGFyYW1zLmxhenlTdGVwU3RhcnQpIG9wdGltaXphdGlvbnMucHVzaCgnbGF6eVN0ZXBTdGFydCcpO1xuICBpZiAocGFyYW1zLm9wdGltaXN0aWNTdGFydCkgb3B0aW1pemF0aW9ucy5wdXNoKCdvcHRpbWlzdGljU3RhcnQnKTtcblxuICByZXR1cm4ge1xuICAgIC4uLih0dGZzICE9PSB1bmRlZmluZWQgPyB7IHR0ZnMgfSA6IHt9KSxcbiAgICAuLi4oc3RzbyAhPT0gdW5kZWZpbmVkID8geyBzdHNvIH0gOiB7fSksXG4gICAgb3B0aW1pemF0aW9ucyxcbiAgfTtcbn1cbiJdfQ==
@@ -77,6 +77,13 @@ export interface SuspensionHandlerResult {
77
77
  * inline start (a hook introduces later resume invocations that could race).
78
78
  */
79
79
  hasHookEvents: boolean;
80
+ /**
81
+ * Wall-clock ms spent committing this suspension's `hook_created` events
82
+ * (0 when it created none). The caller accumulates this across iterations
83
+ * and subtracts it from the TTFS latency measurement, so time spent
84
+ * durably creating the user's hooks doesn't count as runtime overhead.
85
+ */
86
+ hookCreationMs: number;
80
87
  }
81
88
  /**
82
89
  * Handles a workflow suspension by processing all pending operations (hooks, steps, waits).
@@ -1 +1 @@
1
- {"version":3,"file":"suspension-handler.d.ts","sourceRoot":"","sources":["../../src/runtime/suspension-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAQ/C,OAAO,EAGL,KAAK,cAAc,EAGnB,KAAK,WAAW,EAChB,KAAK,KAAK,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAGV,uBAAuB,EAEvB,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAOtB,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,4DAA4D;IAC5D,YAAY,EAAE,uBAAuB,EAAE,CAAC;IACxC;;;;;;;OAOG;IACH,yBAAyB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC;;;;;;;;;;;;OAYG;IACH,eAAe,EAAE,KAAK,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,cAAc,CAAC;KACjC,CAAC,CAAC;IACH;;;;;;OAMG;IACH,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,0EAA0E;IAC1E,eAAe,EAAE,OAAO,CAAC;IACzB,wFAAwF;IACxF,sBAAsB,EAAE,OAAO,CAAC;IAChC,wEAAwE;IACxE,kBAAkB,EAAE,OAAO,CAAC;IAC5B;;;;;;OAMG;IACH,aAAa,EAAE,OAAO,CAAC;CACxB;AAgED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,UAAU,EACV,KAAK,EACL,GAAG,EACH,IAAI,EACJ,SAAS,EACT,eAAe,GAChB,EAAE,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAyd5D"}
1
+ {"version":3,"file":"suspension-handler.d.ts","sourceRoot":"","sources":["../../src/runtime/suspension-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAQ/C,OAAO,EAGL,KAAK,cAAc,EAGnB,KAAK,WAAW,EAChB,KAAK,KAAK,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAGV,uBAAuB,EAEvB,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAOtB,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,4DAA4D;IAC5D,YAAY,EAAE,uBAAuB,EAAE,CAAC;IACxC;;;;;;;OAOG;IACH,yBAAyB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC;;;;;;;;;;;;OAYG;IACH,eAAe,EAAE,KAAK,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,cAAc,CAAC;KACjC,CAAC,CAAC;IACH;;;;;;OAMG;IACH,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,0EAA0E;IAC1E,eAAe,EAAE,OAAO,CAAC;IACzB,wFAAwF;IACxF,sBAAsB,EAAE,OAAO,CAAC;IAChC,wEAAwE;IACxE,kBAAkB,EAAE,OAAO,CAAC;IAC5B;;;;;;OAMG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB;AAgED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,UAAU,EACV,KAAK,EACL,GAAG,EACH,IAAI,EACJ,SAAS,EACT,eAAe,GAChB,EAAE,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA8e5D"}