eve 0.31.1 → 0.31.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/src/compiled/.vendor-stamp.json +6 -6
  3. package/dist/src/compiled/@workflow/core/_quickjs-wasi.d.ts +8 -0
  4. package/dist/src/compiled/@workflow/core/correlation-id.d.ts +109 -0
  5. package/dist/src/compiled/@workflow/core/events-consumer.d.ts +1 -0
  6. package/dist/src/compiled/@workflow/core/index.js +2 -2
  7. package/dist/src/compiled/@workflow/core/private.d.ts +17 -1
  8. package/dist/src/compiled/@workflow/core/private.js +1 -1
  9. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +19 -0
  10. package/dist/src/compiled/@workflow/core/runtime/deployment-guard.d.ts +99 -0
  11. package/dist/src/compiled/@workflow/core/runtime/quickjs-assets.generated.d.ts +14 -0
  12. package/dist/src/compiled/@workflow/core/runtime/quickjs-entrypoint.d.ts +124 -0
  13. package/dist/src/compiled/@workflow/core/runtime/quickjs-runtime.d.ts +193 -0
  14. package/dist/src/compiled/@workflow/core/runtime/run.d.ts +2 -0
  15. package/dist/src/compiled/@workflow/core/runtime/runs.d.ts +18 -1
  16. package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +7 -0
  17. package/dist/src/compiled/@workflow/core/runtime/vm-mode.d.ts +44 -0
  18. package/dist/src/compiled/@workflow/core/runtime/vm-serde-bundle.generated.d.ts +14 -0
  19. package/dist/src/compiled/@workflow/core/runtime.d.ts +1 -1
  20. package/dist/src/compiled/@workflow/core/runtime.js +3 -3
  21. package/dist/src/compiled/@workflow/core/serialization/codec-devalue-vm.d.ts +9 -0
  22. package/dist/src/compiled/@workflow/core/serialization/reducers/class-vm.d.ts +20 -0
  23. package/dist/src/compiled/@workflow/core/serialization/reducers/common-vm.d.ts +15 -0
  24. package/dist/src/compiled/@workflow/core/serialization/reducers/step-function-vm.d.ts +44 -0
  25. package/dist/src/compiled/@workflow/core/serialization/vm-bundle-entry.d.ts +12 -0
  26. package/dist/src/compiled/@workflow/core/serialization/workflow-vm.d.ts +24 -0
  27. package/dist/src/compiled/@workflow/core/serialization.d.ts +2 -1
  28. package/dist/src/compiled/@workflow/core/source-map.d.ts +20 -0
  29. package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +78 -0
  30. package/dist/src/compiled/@workflow/core/telemetry.d.ts +5 -0
  31. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  32. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  33. package/dist/src/compiled/@workflow/errors/error-codes.d.ts +2 -0
  34. package/dist/src/compiled/@workflow/errors/index.d.ts +24 -0
  35. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  36. package/dist/src/compiled/@workflow/world/analytics.d.ts +2 -0
  37. package/dist/src/compiled/@workflow/world/events.d.ts +51 -1
  38. package/dist/src/compiled/@workflow/world/hooks.d.ts +1 -0
  39. package/dist/src/compiled/@workflow/world/index.d.ts +1 -1
  40. package/dist/src/compiled/@workflow/world/interfaces.d.ts +28 -1
  41. package/dist/src/compiled/@workflow/world/queue.d.ts +8 -0
  42. package/dist/src/compiled/@workflow/world/runs.d.ts +83 -0
  43. package/dist/src/compiled/@workflow/world-local/index.js +5 -4
  44. package/dist/src/compiled/@workflow/world-vercel/index.js +15 -15
  45. package/dist/src/compiled/_chunks/workflow/_eve-core-quickjs-entrypoint-stub-qIV0OaFz.js +1 -0
  46. package/dist/src/compiled/_chunks/workflow/{attribute-changes-DROfGk6l.js → attribute-changes-Du5ztewf.js} +2 -2
  47. package/dist/src/compiled/_chunks/workflow/{dist-D5bR13zs.js → dist-CNXUKQCp.js} +1 -1
  48. package/dist/src/compiled/_chunks/workflow/dist-CRTn4Sg8.js +3 -0
  49. package/dist/src/compiled/_chunks/workflow/dist-tJoQXAF6.js +1 -0
  50. package/dist/src/compiled/_chunks/workflow/functions-ClJbpZhR.js +1 -0
  51. package/dist/src/compiled/_chunks/workflow/{private-BcwCGTV5.js → private-CiWVdS5v.js} +1 -1
  52. package/dist/src/compiled/_chunks/workflow/resume-hook-CT0keOww.js +1 -0
  53. package/dist/src/compiled/_chunks/workflow/run-DBheaFhH.js +1 -0
  54. package/dist/src/compiled/_chunks/workflow/signal-exit-C8vsI6zj.js +1 -0
  55. package/dist/src/compiled/_chunks/workflow/sleep-BeH4B0Cd.js +1 -0
  56. package/dist/src/compiled/_chunks/workflow/{token-hiUWkDKe.js → token-DtCUEpJs.js} +1 -1
  57. package/dist/src/compiled/_chunks/workflow/{token-util-DURSL1l8.js → token-util-DNwIAn_u.js} +9 -9
  58. package/dist/src/compiled/_chunks/workflow/undici-CUIybhQ2.js +95 -0
  59. package/dist/src/compiled/_chunks/workflow/wait-until-CMX5LUWJ.js +15 -0
  60. package/dist/src/internal/application/package.js +1 -1
  61. package/dist/src/setup/scaffold/create/project.js +1 -1
  62. package/package.json +6 -6
  63. package/dist/src/compiled/_chunks/workflow/dist-B-vbuNqP.js +0 -1
  64. package/dist/src/compiled/_chunks/workflow/dist-dNxTT6nO.js +0 -3
  65. package/dist/src/compiled/_chunks/workflow/functions-CiVUVDNB.js +0 -1
  66. package/dist/src/compiled/_chunks/workflow/resume-hook-bc-OQVI0.js +0 -1
  67. package/dist/src/compiled/_chunks/workflow/run-DM3ouA3U.js +0 -1
  68. package/dist/src/compiled/_chunks/workflow/sleep-D5iWly6-.js +0 -1
  69. package/dist/src/compiled/_chunks/workflow/undici-DWL_MYmT.js +0 -95
  70. package/dist/src/compiled/_chunks/workflow/wait-until-DoW76jdb.js +0 -15
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # eve
2
2
 
3
+ ## 0.31.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 69244fe: Update eve's bundled Workflow SDK packages to the latest 5.0.0 beta releases, keeping the core runtime and workflow worlds aligned.
8
+
3
9
  ## 0.31.1
4
10
 
5
11
  ### Patch Changes
@@ -34,14 +34,14 @@
34
34
  "@vercel/oidc": "3.8.0",
35
35
  "@vercel/otel": "2.1.3",
36
36
  "@vercel/sandbox": "2.8.0",
37
- "@workflow/core": "5.0.0-beta.39",
38
- "@workflow/errors": "5.0.0-beta.15",
37
+ "@workflow/core": "5.0.0-beta.40",
38
+ "@workflow/errors": "5.0.0-beta.16",
39
39
  "@workflow/serde": "5.0.0-beta.2",
40
- "@workflow/world": "5.0.0-beta.24",
41
- "@workflow/world-local": "5.0.0-beta.33",
42
- "@workflow/world-vercel": "5.0.0-beta.35",
40
+ "@workflow/world": "5.0.0-beta.25",
41
+ "@workflow/world-local": "5.0.0-beta.34",
42
+ "@workflow/world-vercel": "5.0.0-beta.36",
43
43
  "zod": "4.4.3",
44
44
  "zod-validation-error": "5.0.0"
45
45
  },
46
- "scriptHash": "640455d5c2660cbd8a88133eca72ee3218cfd8053d63f21b93f857e4b0d96732"
46
+ "scriptHash": "e20714a41a19b69ca8599dc01467ae8cce225eaa106301f1ec2e9adc5d2adcca"
47
47
  }
@@ -0,0 +1,8 @@
1
+ // Auto-generated stub for `quickjs-wasi` types referenced by a vendored .d.ts.
2
+ // Emitted by createDeclarationCopier > buildOpaqueTypesStub.
3
+ //
4
+ // Names are aliased to `unknown` so consumers don't have to install
5
+ // upstream @types just to typecheck against eve. If real types are
6
+ // needed in user code, install the upstream @types and use them directly.
7
+
8
+ export type ExtensionDescriptor = unknown;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Correlation-id generation for the entity families a replay can create.
3
+ *
4
+ * Correlation ids are minted by the workflow VM and are the server's identity
5
+ * gate: a conditional create on the id is what makes a duplicate write from a
6
+ * second live replay idempotent instead of additive. That only works if two
7
+ * replays of the same run mint the same id for the same entity.
8
+ *
9
+ * Historically every id was the Nth draw of *one* monotonic ULID sequence per
10
+ * run, shared by steps, waits, hooks, attribute writes, abort controllers and
11
+ * stream ids alike. Every id was therefore an ordinal over the whole run, and a
12
+ * single extra draw of any kind renumbered every entity of every kind after it.
13
+ * Two replays that agreed about every step but disagreed about one `sleep()`
14
+ * would mint different ids for all subsequent steps, so their writes appended
15
+ * side by side instead of colliding, and the settled log ended up holding two
16
+ * names for one logical step. Only one of them can be consumed on the next
17
+ * replay; the other is fatal (`onUnconsumedEvent`).
18
+ *
19
+ * Per-kind sources narrow that coupling to one kind at a time: each family
20
+ * draws from its own independent incrementing sequence, so a disagreement about
21
+ * how many hooks or sleeps were created no longer renames steps.
22
+ *
23
+ * Ids stay syntactically valid ULIDs (10 Crockford characters of
24
+ * `fixedTimestamp` plus 16 of body), because correlation ids are validated as
25
+ * prefixed 26-char ULIDs by the backend, and they stay monotonic *within* a
26
+ * kind, because `hooks.list` is ordered by hook id.
27
+ *
28
+ * Monotonicity is per kind, and two kinds mint `hook_` ids (`hook` and
29
+ * `abortHook`), so listing order is only creation order *within* each of them.
30
+ * No world filters system hooks out of a listing, so a run that constructs an
31
+ * abort controller and also creates its own hooks lists that system hook at a
32
+ * position decided by its kind's hash rather than at its creation position.
33
+ * Order among the user's own hooks is unaffected.
34
+ *
35
+ * This does not make ids independent of *ordinal position within their own
36
+ * kind*: two replays that disagree about how many steps ran still mint
37
+ * different ids for the next step. That is a narrower failure than the shared
38
+ * sequence's, not an eliminated one.
39
+ */
40
+ /** Entity families that draw correlation ids, each from its own sequence. */
41
+ export type CorrelationIdKind =
42
+ /** `step_` ids, one per step invocation. */
43
+ 'step'
44
+ /** `wait_` ids, one per `sleep()`. */
45
+ | 'wait'
46
+ /** `hook_` ids for hooks created by workflow code. */
47
+ | 'hook'
48
+ /** `attr_` ids, one per attribute write. */
49
+ | 'attr'
50
+ /**
51
+ * The abort controller's own id, which becomes its stream name and hook
52
+ * token. Separate from `hook` so constructing an abort controller does not
53
+ * renumber later user hooks.
54
+ */
55
+ | 'abort'
56
+ /** `hook_` ids for the internal system hook backing an abort controller. */
57
+ | 'abortHook'
58
+ /**
59
+ * Ids minted during serialization (`STABLE_ULID`): stream names, and an abort
60
+ * holder's stream name and `abrt_` hook token when it reaches serialization
61
+ * without an identity yet (`reduceAbortWithListener`), which is why `abort`
62
+ * above is not the only mint path for an abort identity. Not correlation ids,
63
+ * but they drew from the same shared sequence, so a workflow that serialized
64
+ * a stream renumbered every entity created after it.
65
+ */
66
+ | 'stream';
67
+ /** Mints the ULID body of a correlation id for one entity family. */
68
+ export type CorrelationIdGenerator = (kind: CorrelationIdKind) => string;
69
+ /**
70
+ * Builds a replay's correlation-id generator.
71
+ *
72
+ * `perKind: false` returns the run's single shared monotonic sequence and
73
+ * ignores the kind entirely, so both schemes go through one call path and the
74
+ * flag is the only difference between them.
75
+ */
76
+ export declare function createCorrelationIdGenerator(options: {
77
+ /**
78
+ * The run's replay-stable seed. Must not vary between replays of one run, and
79
+ * must differ between runs, or two runs would mint identical ids.
80
+ */
81
+ seed: string;
82
+ fixedTimestamp: number;
83
+ /** The run's shared monotonic sequence, used as-is when `perKind` is false. */
84
+ positional: () => string;
85
+ perKind: boolean;
86
+ }): CorrelationIdGenerator;
87
+ /** Length of a ULID, exported so tests need not restate it. */
88
+ export declare const CORRELATION_ID_LENGTH: number;
89
+ /**
90
+ * Whether each entity family draws correlation ids from its own sequence rather
91
+ * than from one sequence shared by the whole run. Off unless opted in, so an SDK
92
+ * upgrade alone never moves a run between schemes.
93
+ *
94
+ * The invariant either way: a run must replay under the scheme that minted its
95
+ * ids. A replay under the other scheme mints ids its own earlier events do not
96
+ * carry, so it can consume none of them and fails the run. Two things can break
97
+ * it, and both are about turning the flag on rather than about upgrading:
98
+ *
99
+ * - Enabling it while runs are in flight. On Vercel, skew protection keeps a run
100
+ * on the deployment that started it, so a run only ever sees the value baked
101
+ * into its own deployment. Elsewhere (world-postgres, world-local, a
102
+ * self-hosted process) nothing pins a run to the code that started it, so
103
+ * enable it during a quiet window.
104
+ * - A rolling deploy that leaves both values live, which puts two schemes on one
105
+ * run concurrently — the side-by-side append this whole mechanism exists to
106
+ * avoid. Roll the value out to the whole fleet at once.
107
+ */
108
+ export declare function isPerKindCorrelationIdsEnabled(): boolean;
109
+ //# sourceMappingURL=correlation-id.d.ts.map
@@ -55,6 +55,7 @@ export declare class EventsConsumer {
55
55
  private pendingUnconsumedTimeout;
56
56
  private unconsumedCheckVersion;
57
57
  constructor(events: Event[], options: EventsConsumerOptions);
58
+ append(events: Event[]): void;
58
59
  /**
59
60
  * Registers a callback function to be called after an event has been consumed
60
61
  * by a different callback. The callback can return:
@@ -1,2 +1,2 @@
1
- import{A as e,Bn as t,Fn as n,Hn as r,In as i,K as a,M as o,Mn as s,Pn as c,S as l,Vn as u,bn as d,kn as f,q as p,zn as m}from"../../_chunks/workflow/wait-until-DoW76jdb.js";import{i as h,u as g}from"../../_chunks/workflow/dist-dNxTT6nO.js";import{a as _,i as v,r as y,t as b}from"../../_chunks/workflow/attribute-changes-DROfGk6l.js";import"../../_chunks/workflow/dist-D5bR13zs.js";import{n as x}from"../../_chunks/workflow/resume-hook-bc-OQVI0.js";import{t as S}from"../../_chunks/workflow/sleep-D5iWly6-.js";function C(e){v(`createHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-hook`,C)}function w(e){v(`createWebhook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-webhook`,w)}function T({schema:e}={}){function t(e){v(`defineHook().create()`,`https://workflow-sdk.dev/docs/api-reference/workflow/define-hook`,t)}return{create:t,async resume(t,n){if(!e?.[`~standard`])return await x(t,n);let r=e[`~standard`].validate(n);if(r instanceof Promise&&(r=await r),r.issues){let e=r.issues.map(e=>{let t=e.path?.map(e=>String(typeof e==`object`&&e?e.key:e)).join(`.`);return t?` at "${t}": ${e.message}`:` ${e.message}`});throw Error(`Hook payload did not match the defined schema:\n${e.join(`
2
- `)}`)}return await x(t,r.value)}}}async function E(e,t={}){let n=p.getStore(),r=n?.workflowMetadata?.workflowRunId;if(!r)throw new h(`setAttributes() must be called from a 'use workflow' or 'use step' function. Calling it from plain host code is not supported.`);let i=b(e,t);if(i.length!==0){if(n.runReadyBarrier)try{await n.runReadyBarrier}catch{}await(await s()).events.create(r,{eventType:`attr_set`,specVersion:5,eventData:{changes:i,writer:{type:`step`,stepId:n.stepMetadata.stepId,attempt:n.stepMetadata.attempt},...t.allowReservedAttributes===!0?{allowReservedAttributes:!0}:{}}})}}function D(){let e=p.getStore();return e||y(`getStepMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-step-metadata`,D),e.stepMetadata}function O(){let e=p.getStore();return e||_(`getWorkflowMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-workflow-metadata`,O),e.workflowMetadata}function k(s={}){let h=p.getStore();h||_(`getWritable()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-writable`,k);let{namespace:g}=s,v=h.workflowMetadata.workflowRunId,y=a(v,g);h.writables??=new Map;let b=h.writables,x=b.get(y);if(x)return x.writable;let S=o(e(globalThis,h.ops,v,h.encryptionKey,!0,h.runReadyBarrier),h.encryptionKey),C=new l(v,y,h.runReadyBarrier),w=c();return h.ops.push(w.promise),n(S.readable,C,w).catch(()=>{}),i(S.writable,w),Object.defineProperty(S.writable,m,{value:y,writable:!1}),Object.defineProperty(S.writable,r,{value:v,writable:!1}),h.workflowDeploymentId&&Object.defineProperty(S.writable,t,{value:h.workflowDeploymentId,writable:!1}),d(h.encryptionKey)&&Object.defineProperty(S.writable,u,{value:f(h.encryptionKey.keyPair.publicKey),writable:!1}),b.set(y,{writable:S.writable,state:w}),S.writable}export{h as FatalError,g as RetryableError,C as createHook,w as createWebhook,T as defineHook,D as getStepMetadata,O as getWorkflowMetadata,k as getWritable,E as setAttributes,S as sleep};
1
+ import{A as e,Bn as t,En as n,Fn as r,Gn as i,Hn as a,Jn as o,K as s,Kn as c,M as l,Rn as u,S as d,Vn as f,q as p,qn as m}from"../../_chunks/workflow/wait-until-CMX5LUWJ.js";import{i as h,u as g}from"../../_chunks/workflow/dist-CRTn4Sg8.js";import{a as _,i as v,r as y,t as b}from"../../_chunks/workflow/attribute-changes-Du5ztewf.js";import"../../_chunks/workflow/dist-CNXUKQCp.js";import{n as x}from"../../_chunks/workflow/resume-hook-CT0keOww.js";import{t as S}from"../../_chunks/workflow/sleep-BeH4B0Cd.js";function C(e){v(`createHook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-hook`,C)}function w(e){v(`createWebhook()`,`https://workflow-sdk.dev/docs/api-reference/workflow/create-webhook`,w)}function T({schema:e}={}){function t(e){v(`defineHook().create()`,`https://workflow-sdk.dev/docs/api-reference/workflow/define-hook`,t)}return{create:t,async resume(t,n){if(!e?.[`~standard`])return await x(t,n);let r=e[`~standard`].validate(n);if(r instanceof Promise&&(r=await r),r.issues){let e=r.issues.map(e=>{let t=e.path?.map(e=>String(typeof e==`object`&&e?e.key:e)).join(`.`);return t?` at "${t}": ${e.message}`:` ${e.message}`});throw Error(`Hook payload did not match the defined schema:\n${e.join(`
2
+ `)}`)}return await x(t,r.value)}}}async function E(e,t={}){let n=p.getStore(),r=n?.workflowMetadata?.workflowRunId;if(!r)throw new h(`setAttributes() must be called from a 'use workflow' or 'use step' function. Calling it from plain host code is not supported.`);let i=b(e,t);if(i.length!==0){if(n.runReadyBarrier)try{await n.runReadyBarrier}catch{}await(await u()).events.create(r,{eventType:`attr_set`,specVersion:5,eventData:{changes:i,writer:{type:`step`,stepId:n.stepMetadata.stepId,attempt:n.stepMetadata.attempt},...t.allowReservedAttributes===!0?{allowReservedAttributes:!0}:{}}})}}function D(){let e=p.getStore();return e||y(`getStepMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-step-metadata`,D),e.stepMetadata}function O(){let e=p.getStore();return e||_(`getWorkflowMetadata()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-workflow-metadata`,O),e.workflowMetadata}function k(u={}){let h=p.getStore();h||_(`getWritable()`,`https://workflow-sdk.dev/docs/api-reference/workflow/get-writable`,k);let{namespace:g}=u,v=h.workflowMetadata.workflowRunId,y=s(v,g);h.writables??=new Map;let b=h.writables,x=b.get(y);if(x)return x.writable;let S=l(e(globalThis,h.ops,v,h.encryptionKey,!0,h.runReadyBarrier),h.encryptionKey),C=new d(v,y,h.runReadyBarrier),w=t();return h.ops.push(w.promise),f(S.readable,C,w).catch(()=>{}),a(S.writable,w),Object.defineProperty(S.writable,i,{value:y,writable:!1}),Object.defineProperty(S.writable,o,{value:v,writable:!1}),h.workflowDeploymentId&&Object.defineProperty(S.writable,c,{value:h.workflowDeploymentId,writable:!1}),n(h.encryptionKey)&&Object.defineProperty(S.writable,m,{value:r(h.encryptionKey.keyPair.publicKey),writable:!1}),b.set(y,{writable:S.writable,state:w}),S.writable}export{h as FatalError,g as RetryableError,C as createHook,w as createWebhook,T as defineHook,D as getStepMetadata,O as getWorkflowMetadata,k as getWritable,E as setAttributes,S as sleep};
@@ -2,6 +2,7 @@
2
2
  * Utils used by the bundler when transforming code
3
3
  */
4
4
  import type { WorldCapabilities } from '#compiled/@workflow/world/index.js';
5
+ import type { CorrelationIdGenerator } from './correlation-id.js';
5
6
  import type { EventsConsumer } from './events-consumer.js';
6
7
  import type { QueueItem } from './global.js';
7
8
  import type { ReplayPayloadCache } from './replay-payload-cache.js';
@@ -30,6 +31,16 @@ export interface WorkflowOrchestratorContext {
30
31
  encryptionKey: PayloadKey | undefined;
31
32
  worldCapabilities?: WorldCapabilities;
32
33
  globalThis: typeof globalThis;
34
+ /**
35
+ * Increments when a suspension is accepted and on every retained-session
36
+ * resume. STEP suspension signals capture it when scheduled and no-op if
37
+ * it moved (see step.ts) — this drops same-boundary sibling signals and
38
+ * timers queued at boundary N that would fire after the session resumed
39
+ * into boundary N+1. Sleep/hook/attribute signals are intentionally
40
+ * unguarded: their presence makes the boundary unretainable, so a late
41
+ * signal correctly demotes the session (workflow.ts `onWorkflowError`).
42
+ */
43
+ suspensionGeneration: number;
33
44
  eventsConsumer: EventsConsumer;
34
45
  /**
35
46
  * Map of pending invocations keyed by correlationId.
@@ -37,7 +48,12 @@ export interface WorkflowOrchestratorContext {
37
48
  */
38
49
  invocationsQueue: Map<string, QueueItem>;
39
50
  onWorkflowError: (error: Error) => void;
40
- generateUlid: () => string;
51
+ /**
52
+ * Mints a correlation id body for one entity family. Every entity a replay
53
+ * creates draws from here, and the family is what keeps a disagreement about
54
+ * one family's count from renumbering another's.
55
+ */
56
+ generateCorrelationId: CorrelationIdGenerator;
41
57
  generateNanoid: () => string;
42
58
  /**
43
59
  * Sequential promise queue that ensures all event-driven promise resolutions
@@ -1 +1 @@
1
- import{a as e,i as t,n,r,t as i}from"../../_chunks/workflow/private-BcwCGTV5.js";export{i as awaitEarlierDeliveries,n as getStepFunction,r as registerDeliveryBarrier,t as registerStepFunction,e as scheduleWhenIdle};
1
+ import{a as e,i as t,n,r,t as i}from"../../_chunks/workflow/private-CiWVdS5v.js";export{i as awaitEarlierDeliveries,n as getStepFunction,r as registerDeliveryBarrier,t as registerStepFunction,e as scheduleWhenIdle};
@@ -141,6 +141,18 @@ export declare function isOptimisticInlineStartExplicitlyDisabled(): boolean;
141
141
  * explicit `'0'` / `'false'` (case-insensitive).
142
142
  */
143
143
  export declare function isTurboEnabled(): boolean;
144
+ /**
145
+ * Whether the inline loop retains a suspended workflow VM across inline steps
146
+ * within one invocation (default ON). When on, a step-only suspension keeps
147
+ * the live VM, event consumer, and hydrated state alive, and the next loop
148
+ * iteration appends only the newly durable events instead of rebuilding the
149
+ * `vm.Context` and replaying the whole event log. Non-step suspensions and
150
+ * replay divergence always fall back to the ordinary durable replay path.
151
+ *
152
+ * `WORKFLOW_RETAINED_VM=0` (or `false`) is the kill switch: every iteration
153
+ * replays from scratch in a fresh VM, matching the pre-retention behavior.
154
+ */
155
+ export declare function isVmRetentionEnabled(): boolean;
144
156
  /**
145
157
  * Whether inline step ownership is enabled (default ON). When on, the lazy
146
158
  * `step_started` that creates an inline step records the owning queue
@@ -219,4 +231,11 @@ export declare const PRECONDITION_REINVOKE_DELAY_SECONDS = 2;
219
231
  * `WORKFLOW_PRECONDITION_REINVOKE_DELAY_SECONDS`.
220
232
  */
221
233
  export declare function getPreconditionReinvokeDelaySeconds(): number;
234
+ export declare const DEPLOYMENT_MISMATCH_MAX_RETRIES = 3;
235
+ /**
236
+ * Effective deployment-mismatch re-route budget. Override via
237
+ * `WORKFLOW_DEPLOYMENT_MISMATCH_MAX_RETRIES`; `0` fails the run on the first
238
+ * misrouted delivery instead of attempting recovery.
239
+ */
240
+ export declare function getDeploymentMismatchMaxRetries(): number;
222
241
  //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1,99 @@
1
+ import { type WorkflowRun, type World } from '#compiled/@workflow/world/index.js';
2
+ /**
3
+ * How the guard resolved a delivery. Both non-`continue` outcomes mean the
4
+ * caller must ack the message and return without executing anything.
5
+ */
6
+ export type DeploymentAffinityOutcome =
7
+ /** The run belongs here (or this world has no deployment affinity). */
8
+ 'continue'
9
+ /** Misrouted; re-enqueued at the run's own deployment. */
10
+ | 'rerouted'
11
+ /** Misrouted and out of budget (or unroutable); `run_failed` recorded. */
12
+ | 'failed';
13
+ /**
14
+ * `spanAttributes` is present only on a misrouted delivery — mismatches are
15
+ * rare, so the presence of `workflow.deployment.pinned_id` on a span *is* the
16
+ * signal that one happened, and `recovered` separates the ones a re-route fixed
17
+ * from the ones that kept misrouting.
18
+ */
19
+ export interface DeploymentAffinityResult {
20
+ outcome: DeploymentAffinityOutcome;
21
+ spanAttributes?: Record<string, string | number | boolean>;
22
+ }
23
+ /**
24
+ * Arguments handed to a call site's re-enqueue closure. The guard owns the
25
+ * policy — counting, backoff, logging, telemetry, escalation — and the call
26
+ * site owns only the shape of the message it needs to put back on the queue.
27
+ */
28
+ export interface ReenqueueArgs {
29
+ /** The deployment to target: the one the run is pinned to. */
30
+ deploymentId: string;
31
+ /**
32
+ * The run's spec version, so the world picks the right queue transport
33
+ * (CBOR vs JSON). Undefined on legacy runs that predate the field; worlds
34
+ * then fall back to their current default.
35
+ */
36
+ specVersion: number | undefined;
37
+ deploymentMismatchRetryCount: number;
38
+ /** Backoff before the re-routed message becomes visible. */
39
+ delaySeconds: number;
40
+ }
41
+ /**
42
+ * Guards deployment affinity: a run may only execute on the deployment it is
43
+ * pinned to.
44
+ *
45
+ * A run's `deploymentId` is fixed when it starts — the deployment that called
46
+ * `start()`, or whatever `start({ deploymentId })` resolved to (an explicit id
47
+ * or `'latest'`) — and no replay or step execution may happen anywhere else:
48
+ * the bundles here may not match the run's persisted history, and any step
49
+ * dispatched from here derives the per-run encryption key from the wrong
50
+ * deployment's master key, which surfaces as a `RuntimeDecryptionError` the
51
+ * queue retry callback swallows into a blank "exceeded max retries".
52
+ *
53
+ * A misrouted delivery is not treated as permanent. Rather than failing
54
+ * immediately, re-enqueue the message *explicitly targeted* at the run's own
55
+ * deployment; that send is strictly better-addressed than the one that
56
+ * misrouted, which inherited the producing deployment's ambient id. Fail only
57
+ * once the budget (`WORKFLOW_DEPLOYMENT_MISMATCH_MAX_RETRIES`, default 3) is
58
+ * spent, mirroring how a replay divergence gets bounded recovery replays before
59
+ * being recorded as a corrupted event log.
60
+ *
61
+ * Callers must pass a run entity they already have in hand — every call site
62
+ * loads the run for other reasons — so the guard costs no extra round trip.
63
+ * (`world.getDeploymentId()` reads the ambient deployment id, e.g.
64
+ * `VERCEL_DEPLOYMENT_ID`, and does not call the backend either.)
65
+ *
66
+ * The failure is recorded **without resolving the run's encryption key**: the
67
+ * key is fetched from the pinned deployment's API, often unavailable once that
68
+ * deployment is past its retention window, so depending on it would throw here
69
+ * instead of recording the failure. The payload is written unencrypted (it
70
+ * holds only deployment ids, nothing sensitive), and the plaintext `errorCode`
71
+ * is the signal observability and the UI key off.
72
+ */
73
+ export declare function guardDeploymentAffinity({ world, run, requestId, retryCount, reenqueue, isDeploymentUnavailableError, beforeStop, }: {
74
+ world: World;
75
+ run: Pick<WorkflowRun, 'runId' | 'deploymentId' | 'specVersion'>;
76
+ requestId?: string;
77
+ /** `deploymentMismatchRetryCount` from the incoming message, if any. */
78
+ retryCount?: number;
79
+ /**
80
+ * Puts this delivery's message back on the queue, targeted at the run's own
81
+ * deployment. Omitted by callers that cannot reconstruct their message, which
82
+ * makes the guard fail-fast.
83
+ */
84
+ reenqueue?: (args: ReenqueueArgs) => Promise<void>;
85
+ /**
86
+ * Classifies a re-enqueue failure as definitive proof that the pinned
87
+ * deployment cannot receive the message. Unclassified failures are retried
88
+ * by rejecting the handler and leaving the current queue message unacked.
89
+ */
90
+ isDeploymentUnavailableError?: (error: unknown) => boolean;
91
+ /**
92
+ * Ordering barrier awaited once a mismatch is confirmed, before either
93
+ * stopping action. Under turbo the `run_started` write is backgrounded, and
94
+ * both outcomes hand the run off (to a `run_failed` here, or to the pinned
95
+ * deployment's own `run_started`) — so that write must have landed first.
96
+ */
97
+ beforeStop?: () => Promise<void>;
98
+ }): Promise<DeploymentAffinityResult>;
99
+ //# sourceMappingURL=deployment-guard.d.ts.map
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Auto-generated by scripts/build-quickjs-assets.js
3
+ * Do not edit manually.
4
+ *
5
+ * Contains base64-encoded quickjs-wasi WASM binary and native C extension
6
+ * .so files. Decoded at import time so they can be passed directly to
7
+ * QuickJS.create() and QuickJS.restore() without any filesystem access,
8
+ * import.meta.url resolution, or require.resolve calls.
9
+ */
10
+ import type { ExtensionDescriptor } from '../_quickjs-wasi.js';
11
+ declare const quickjsWasm: Uint8Array<ArrayBufferLike>;
12
+ export { quickjsWasm };
13
+ export declare const quickjsExtensions: ExtensionDescriptor[];
14
+ //# sourceMappingURL=quickjs-assets.generated.d.ts.map
@@ -0,0 +1,124 @@
1
+ /**
2
+ * QuickJS VM integration with the Workflow DevKit.
3
+ *
4
+ * This module provides the entry point for running workflows in the
5
+ * QuickJS WASM VM engine instead of the `node:vm` engine. Both engines
6
+ * implement the same event-replay execution model — every invocation:
7
+ *
8
+ * 1. Loads the full event log for the run
9
+ * 2. Runs the workflow function from the top in a fresh QuickJS VM,
10
+ * replaying the event log to resolve awaited primitives
11
+ * 3. On suspension: creates events + queues steps for new pending ops
12
+ * 4. On completion: creates run_completed
13
+ * 5. On failure: creates run_failed
14
+ */
15
+ import type { Span } from '#compiled/@opentelemetry/api/index.js';
16
+ import { type Event, type RunInput, type WorkflowRun } from '#compiled/@workflow/world/index.js';
17
+ /**
18
+ * Returns true when the supplied preloaded events indicate this is the
19
+ * first workflow handler invocation for the run — i.e. the log contains
20
+ * nothing beyond `run_created` / `run_started`. In that case the
21
+ * preloaded events ARE the complete event log and the `events.list`
22
+ * round-trips can be skipped entirely.
23
+ *
24
+ * Crucially, if the world backfilled a missing `run_created` via the
25
+ * resilient start path, `preloadedEvents` contains it even when a fresh
26
+ * `events.list` might not (eventual consistency), so preferring the
27
+ * preloaded events on first invocation is also the more correct choice.
28
+ *
29
+ * Returns false when `preloadedEvents` is missing/empty so the caller
30
+ * falls back to the normal fetch path.
31
+ *
32
+ * Exported for unit testing.
33
+ */
34
+ export declare function isFirstInvocation(preloadedEvents: readonly Event[] | undefined): boolean;
35
+ /**
36
+ * Run a workflow using the QuickJS WASM VM engine.
37
+ *
38
+ * This replaces the `node:vm` replay path (runWorkflow + EventsConsumer)
39
+ * with a QuickJS VM invocation that performs the same full event replay.
40
+ *
41
+ * KNOWN GAP — precondition guard: unlike the node:vm path, no event write
42
+ * in this file participates in the optimistic-concurrency precondition
43
+ * guard (`withPreconditionRetry` + `stateUpdatedAtForCreate`), which
44
+ * protects a writer holding a stale event-log snapshot from clobbering a
45
+ * concurrent one. The engine currently relies on per-(runId,
46
+ * correlationId) event uniqueness (EntityConflictError dedup) alone. This
47
+ * is a deliberate simplification while the engine is experimental — wiring
48
+ * the guard is tracked follow-up work; anyone adding new write paths here
49
+ * should not assume parity with the node engine on this axis.
50
+ */
51
+ export declare function runWorkflowWithQuickJS(params: {
52
+ workflowCode: string;
53
+ workflowName: string;
54
+ workflowRun: WorkflowRun;
55
+ /**
56
+ * Events returned inline by `events.create('run_started', ...)` or by
57
+ * the lazy hook fast path's `hook_received` preload. When they indicate
58
+ * a first invocation — or when `preloadedEventsComplete` attests they
59
+ * are the complete log — they are used as the event log instead of
60
+ * fetching via `events.list`, matching the node:vm engine's fast path.
61
+ */
62
+ preloadedEvents?: Event[];
63
+ /**
64
+ * True when the caller has validated that `preloadedEvents` is the run's
65
+ * COMPLETE event log (e.g. the lazy hook fast path's hasMore-false
66
+ * replay preload). The first-invocation heuristic below only recognizes
67
+ * run_created/run_started-only preloads, so without this attestation a
68
+ * hook-resume preload would be discarded and refetched.
69
+ */
70
+ preloadedEventsComplete?: boolean;
71
+ /**
72
+ * Run input carried through the queue message on first delivery. Used
73
+ * as a last-resort fallback for `run_created.eventData.input` when
74
+ * the event log is incomplete.
75
+ */
76
+ runInput?: RunInput;
77
+ /**
78
+ * The parent OTel span (the outer `WORKFLOW {workflowName}` span from
79
+ * `runtime.ts`). When supplied, VM lifecycle attributes are attached
80
+ * to it for end-to-end visibility.
81
+ */
82
+ parentSpan?: Span;
83
+ /**
84
+ * Server-supplied per-run event ceiling from the run_started response
85
+ * (undefined ⇒ no enforcement). Mirrors the node:vm engine's guard:
86
+ * a runaway run is failed once its log reaches the ceiling. The throw
87
+ * propagates to the replay loop's catch in runtime.ts (the QuickJS
88
+ * dispatch runs inside that loop's try), which classifies it and
89
+ * records run_failed with MAX_EVENTS_EXCEEDED.
90
+ */
91
+ maxEventsLimit?: number;
92
+ /**
93
+ * Queue delivery attempt of the message driving this invocation (from
94
+ * the queue handler's metadata; 1 = first delivery). Surfaced in
95
+ * diagnostics; crash recovery itself is driven by the ownership-lease
96
+ * decision table in the loop, not by the attempt count.
97
+ */
98
+ deliveryAttempt?: number;
99
+ /**
100
+ * Queue message ID of the delivery driving this invocation, stamped as
101
+ * `ownerMessageId` on inline lazy step claims so wake replays defer to
102
+ * the in-flight body instead of requeueing the step.
103
+ */
104
+ ownerMessageId?: string;
105
+ /**
106
+ * Queue namespace resolved at route registration (runtime.ts). Must be
107
+ * threaded into every message publish: the builders bake the namespace
108
+ * into generated routes, so consumers listen on `__<ns>_wkf_workflow_*`
109
+ * — a publish without it lands on `__wkf_workflow_*` and is never
110
+ * picked up.
111
+ */
112
+ namespace?: string;
113
+ /**
114
+ * Run-origin trace carrier accessor from runtime.ts
115
+ * (getNextTraceCarrier). In the default `linked` trace mode every
116
+ * invocation must link back to the run's origin (workflow.start) in a
117
+ * star; capturing the current invocation context instead would chain
118
+ * invocations to each other and fragment the run view on async queues.
119
+ */
120
+ nextTraceCarrier?: () => Promise<Record<string, string>>;
121
+ }): Promise<{
122
+ timeoutSeconds?: number;
123
+ } | void>;
124
+ //# sourceMappingURL=quickjs-entrypoint.d.ts.map