@workflow/world-testing 5.0.0-beta.46 → 5.0.0-beta.47

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.
@@ -1,7 +1,11 @@
1
1
  // biome-ignore-all lint: generated file
2
2
  /* eslint-disable */
3
3
  import { createRequire as __createRequire } from "node:module";
4
+ import { fileURLToPath as __fileURLToPath } from "node:url";
5
+ import { dirname as __pathDirname } from "node:path";
4
6
  var require = __createRequire(import.meta.url);
7
+ var __filename = __fileURLToPath(import.meta.url);
8
+ var __dirname = __pathDirname(__filename);
5
9
 
6
10
  var __create = Object.create;
7
11
  var __defProp = Object.defineProperty;
@@ -52,6 +56,26 @@ var __toESM = (mod, isNodeMode, target2) => (target2 = mod != null ? __create(__
52
56
  mod
53
57
  ));
54
58
 
59
+ // ../utils/dist/debug-log.js
60
+ function isWorkflowDebugEnabled() {
61
+ const debug = typeof process !== "undefined" ? process.env.DEBUG : void 0;
62
+ if (typeof debug !== "string")
63
+ return false;
64
+ return debug.includes("workflow:") || debug === "*";
65
+ }
66
+ function debugLog(...args) {
67
+ if (!isWorkflowDebugEnabled())
68
+ return;
69
+ console.debug(...args);
70
+ }
71
+ var init_debug_log = __esm({
72
+ "../utils/dist/debug-log.js"() {
73
+ "use strict";
74
+ __name(isWorkflowDebugEnabled, "isWorkflowDebugEnabled");
75
+ __name(debugLog, "debugLog");
76
+ }
77
+ });
78
+
55
79
  // ../utils/dist/global-singleton.js
56
80
  function globalSingleton2(name, shapeVersion, create) {
57
81
  const key = /* @__PURE__ */ Symbol.for(`${name}/v${shapeVersion}`);
@@ -409,6 +433,7 @@ var init_world_target = __esm({
409
433
  var init_dist5 = __esm({
410
434
  "../utils/dist/index.js"() {
411
435
  "use strict";
436
+ init_debug_log();
412
437
  init_global_singleton2();
413
438
  init_parse_name2();
414
439
  init_pluralize2();
@@ -15315,19 +15340,30 @@ function isSealedNoopEvent(event) {
15315
15340
  function entityEventClass(eventType) {
15316
15341
  return getOwnProperty(ENTITY_EVENT_CLASS_BY_TYPE, eventType);
15317
15342
  }
15343
+ function classifyEntityEvent(event) {
15344
+ const eventClass = entityEventClass(event.eventType);
15345
+ if (eventClass === void 0) {
15346
+ return void 0;
15347
+ }
15348
+ if (eventClass === "run_started") {
15349
+ return { eventClass, entity: RUN_ENTITY_KEY };
15350
+ }
15351
+ return event.correlationId ? { eventClass, entity: event.correlationId } : void 0;
15352
+ }
15318
15353
  function getEventDataRefFields(eventType) {
15319
15354
  return getOwnProperty(EVENT_DATA_REF_FIELDS_BY_EVENT_TYPE, eventType) ?? NO_EVENT_DATA_REF_FIELDS;
15320
15355
  }
15321
15356
  function getEventDataPayloadField(eventType) {
15322
15357
  return getEventDataRefFields(eventType)[0];
15323
15358
  }
15324
- var ENTITY_EVENT_CLASS_BY_TYPE, EVENT_DATA_REF_FIELDS_BY_EVENT_TYPE, NO_EVENT_DATA_REF_FIELDS;
15359
+ var ENTITY_EVENT_CLASS_BY_TYPE, RUN_ENTITY_KEY, TERMINAL_EVENT_CLASSES, EVENT_DATA_REF_FIELDS_BY_EVENT_TYPE, NO_EVENT_DATA_REF_FIELDS;
15325
15360
  var init_event_metadata2 = __esm({
15326
15361
  "../world/dist/event-metadata.js"() {
15327
15362
  "use strict";
15328
15363
  __name(getOwnProperty, "getOwnProperty");
15329
15364
  __name(isSealedNoopEvent, "isSealedNoopEvent");
15330
15365
  ENTITY_EVENT_CLASS_BY_TYPE = {
15366
+ attr_set: "attr_set",
15331
15367
  step_created: "step_created",
15332
15368
  step_started: "step_started",
15333
15369
  step_retrying: "step_retrying",
@@ -15340,6 +15376,14 @@ var init_event_metadata2 = __esm({
15340
15376
  run_started: "run_started"
15341
15377
  };
15342
15378
  __name(entityEventClass, "entityEventClass");
15379
+ RUN_ENTITY_KEY = "";
15380
+ TERMINAL_EVENT_CLASSES = /* @__PURE__ */ new Set([
15381
+ "attr_set",
15382
+ "step_terminal",
15383
+ "wait_completed",
15384
+ "hook_disposed"
15385
+ ]);
15386
+ __name(classifyEntityEvent, "classifyEntityEvent");
15343
15387
  EVENT_DATA_REF_FIELDS_BY_EVENT_TYPE = {
15344
15388
  run_created: ["input"],
15345
15389
  run_started: ["input"],
@@ -16426,8 +16470,9 @@ var init_queue2 = __esm({
16426
16470
  /** Epoch ms immediately before the queue publish was requested. */
16427
16471
  queuePublishRequestedAtMs: external_exports2.number(),
16428
16472
  /**
16429
- * Which `resumeHook()` dispatch path ran: `lazy` or `sequential` (`parallel`
16430
- * from producers predating lazy-only resume).
16473
+ * Which `resumeHook()` dispatch path ran. Current producers always report
16474
+ * `sequential` (durable write, then wake); older producers may report
16475
+ * `lazy` or `parallel`.
16431
16476
  */
16432
16477
  strategy: external_exports2.string().optional(),
16433
16478
  /** Epoch ms the final consumer's queue handler was entered. */
@@ -16499,9 +16544,9 @@ var init_queue2 = __esm({
16499
16544
  /** Run creation data, only present on the first queue delivery from start() */
16500
16545
  runInput: RunInputSchema2.optional(),
16501
16546
  /**
16502
- * Lazy hook resume data, only present when `resumeHook()` takes the parallel
16503
- * fast path. A consumer that understands this field idempotently ensures the
16504
- * `hook_received` event exists (keyed by `resumeId`) before replaying.
16547
+ * Legacy lazy hook resume data. A consumer that understands this field
16548
+ * idempotently ensures the `hook_received` event exists (keyed by `resumeId`)
16549
+ * before replaying.
16505
16550
  */
16506
16551
  hookInput: HookResumeInputSchema2.optional(),
16507
16552
  /**
@@ -16513,7 +16558,7 @@ var init_queue2 = __esm({
16513
16558
  stepInput: StepDispatchInputSchema2.optional(),
16514
16559
  /**
16515
16560
  * Hook-resume TTR timing. Present on both `resumeHook()` dispatch paths
16516
- * (unlike `hookInput`, which only rides the lazy path), and
16561
+ * (unlike legacy `hookInput`), and
16517
16562
  * forwarded onto a dispatched step message when the resuming invocation
16518
16563
  * hands the next durable step to another invocation. Purely observational.
16519
16564
  * See {@link HookResumeTimingSchema}.
@@ -16571,12 +16616,14 @@ var init_hooks2 = __esm({
16571
16616
  encryptionPublicKey: external_exports2.string().optional(),
16572
16617
  // Feature marker: the version of the lazy-hook-resume consumer protocol the
16573
16618
  // run's creating deployment supports. Present (>= 1) means that deployment's
16574
- // `@workflow/core` re-ensures the `hook_received` event from the queue
16575
- // message's `hookInput` on replay, so `resumeHook()`'s lazy path is safe to
16576
- // use. Because a run is pinned to its creating deployment, this
16577
- // marker is a reliable per-run attestation, unlike inferring support from a
16578
- // version compare against a predicted release cutoff. Absent on runs created
16579
- // before the marker existed (fall back to the sequential path).
16619
+ // `@workflow/core` re-ensures the `hook_received` event from a queue
16620
+ // message's `hookInput` on replay. Current producers no longer send
16621
+ // `hookInput` (the durable write happens before the wake is published), so
16622
+ // they never read this marker; it remains stamped so OLDER producers, which
16623
+ // still gate their lazy path on it, keep working against new runs. Because a
16624
+ // run is pinned to its creating deployment, this marker is a reliable
16625
+ // per-run attestation, unlike inferring support from a version compare
16626
+ // against a predicted release cutoff.
16580
16627
  hookResumeInputVersion: external_exports2.number().optional()
16581
16628
  });
16582
16629
  HOOK_RESUME_INPUT_VERSION2 = 1;
@@ -16661,15 +16708,22 @@ async function reenqueueActiveRuns(runs, enqueue, label, namespace) {
16661
16708
  cursor = page.cursor ?? void 0;
16662
16709
  }
16663
16710
  }
16664
- if (reenqueued > 0) {
16665
- console.log(`[${label}] Re-enqueued ${reenqueued} active run(s) on startup`);
16711
+ if (reenqueued > 0 && isDebugEnabled()) {
16712
+ console.debug(`[${label}] Re-enqueued ${reenqueued} active run(s) on startup`);
16666
16713
  }
16667
16714
  }
16715
+ function isDebugEnabled() {
16716
+ const debug = typeof process !== "undefined" ? process.env.DEBUG : void 0;
16717
+ if (typeof debug !== "string")
16718
+ return false;
16719
+ return debug.includes("workflow:") || debug === "*";
16720
+ }
16668
16721
  var init_recovery2 = __esm({
16669
16722
  "../world/dist/recovery.js"() {
16670
16723
  "use strict";
16671
16724
  init_queue2();
16672
16725
  __name(reenqueueActiveRuns, "reenqueueActiveRuns");
16726
+ __name(isDebugEnabled, "isDebugEnabled");
16673
16727
  }
16674
16728
  });
16675
16729
 
@@ -17074,6 +17128,7 @@ __export(dist_exports, {
17074
17128
  QueuePrefix: () => QueuePrefix2,
17075
17129
  RESERVED_ATTRIBUTE_KEY_PREFIX: () => RESERVED_ATTRIBUTE_KEY_PREFIX2,
17076
17130
  ROOT_RUN_ID_ATTRIBUTE: () => ROOT_RUN_ID_ATTRIBUTE2,
17131
+ RUN_ENTITY_KEY: () => RUN_ENTITY_KEY,
17077
17132
  RUN_EVENT_TYPES: () => RUN_EVENT_TYPES2,
17078
17133
  RunInputSchema: () => RunInputSchema2,
17079
17134
  SEALED_LOG_ENV_VAR: () => SEALED_LOG_ENV_VAR,
@@ -17091,6 +17146,7 @@ __export(dist_exports, {
17091
17146
  StepSchema: () => StepSchema2,
17092
17147
  StepStatusSchema: () => StepStatusSchema2,
17093
17148
  StructuredErrorSchema: () => StructuredErrorSchema2,
17149
+ TERMINAL_EVENT_CLASSES: () => TERMINAL_EVENT_CLASSES,
17094
17150
  TERMINAL_RUN_EVENT_TYPES: () => TERMINAL_RUN_EVENT_TYPES2,
17095
17151
  TERMINAL_STEP_EVENT_TYPES: () => TERMINAL_STEP_EVENT_TYPES2,
17096
17152
  TERMINAL_STEP_STATUSES: () => TERMINAL_STEP_STATUSES2,
@@ -17108,6 +17164,7 @@ __export(dist_exports, {
17108
17164
  WorkflowRunStatusSchema: () => WorkflowRunStatusSchema2,
17109
17165
  _resetEnvWarnCacheForTests: () => _resetEnvWarnCacheForTests,
17110
17166
  applyAttributeChanges: () => applyAttributeChanges,
17167
+ classifyEntityEvent: () => classifyEntityEvent,
17111
17168
  entityEventClass: () => entityEventClass,
17112
17169
  envFlag: () => envFlag,
17113
17170
  envNumber: () => envNumber2,
@@ -17956,9 +18013,7 @@ async function getAllPorts() {
17956
18013
  return [];
17957
18014
  }
17958
18015
  } catch (error95) {
17959
- if (process.env.NODE_ENV === "development") {
17960
- console.debug("[getAllPorts] Detection failed:", error95);
17961
- }
18016
+ debugLog("[getAllPorts] Detection failed:", error95);
17962
18017
  return [];
17963
18018
  }
17964
18019
  }
@@ -17994,15 +18049,14 @@ async function getWorkflowPort(options) {
17994
18049
  if (workflowPort) {
17995
18050
  return workflowPort.port;
17996
18051
  }
17997
- if (process.env.NODE_ENV === "development") {
17998
- console.debug("[getWorkflowPort] Probing failed, falling back to first port:", ports[0]);
17999
- }
18052
+ debugLog("[getWorkflowPort] Probing failed, falling back to first port:", ports[0]);
18000
18053
  return ports[0];
18001
18054
  }
18002
18055
  var execFileAsync, join, PROC_ROOT, PROBE_TIMEOUT_MS, PROBE_ENDPOINT;
18003
18056
  var init_get_port = __esm({
18004
18057
  "../utils/dist/get-port.js"() {
18005
18058
  "use strict";
18059
+ init_debug_log();
18006
18060
  init_get_port_internals();
18007
18061
  init_workflow_routes();
18008
18062
  execFileAsync = promisify(execFile);
@@ -23078,7 +23132,7 @@ var require_diagnostics = __commonJS({
23078
23132
  proxyConnected: diagnosticsChannel.channel("undici:proxy:connected")
23079
23133
  };
23080
23134
  var isTrackingClientEvents = false;
23081
- function trackClientEvents(debugLog = undiciDebugLog) {
23135
+ function trackClientEvents(debugLog2 = undiciDebugLog) {
23082
23136
  if (isTrackingClientEvents) {
23083
23137
  return;
23084
23138
  }
@@ -23093,7 +23147,7 @@ var require_diagnostics = __commonJS({
23093
23147
  const {
23094
23148
  connectParams: { version: version6, protocol, port, host }
23095
23149
  } = evt;
23096
- debugLog(
23150
+ debugLog2(
23097
23151
  "connecting to %s%s using %s%s",
23098
23152
  host,
23099
23153
  port ? `:${port}` : "",
@@ -23108,7 +23162,7 @@ var require_diagnostics = __commonJS({
23108
23162
  const {
23109
23163
  connectParams: { version: version6, protocol, port, host }
23110
23164
  } = evt;
23111
- debugLog(
23165
+ debugLog2(
23112
23166
  "connected to %s%s using %s%s",
23113
23167
  host,
23114
23168
  port ? `:${port}` : "",
@@ -23124,7 +23178,7 @@ var require_diagnostics = __commonJS({
23124
23178
  connectParams: { version: version6, protocol, port, host },
23125
23179
  error: error95
23126
23180
  } = evt;
23127
- debugLog(
23181
+ debugLog2(
23128
23182
  "connection to %s%s using %s%s errored - %s",
23129
23183
  host,
23130
23184
  port ? `:${port}` : "",
@@ -23140,13 +23194,13 @@ var require_diagnostics = __commonJS({
23140
23194
  const {
23141
23195
  request: { method, path: path14, origin }
23142
23196
  } = evt;
23143
- debugLog("sending request to %s %s%s", method, origin, path14);
23197
+ debugLog2("sending request to %s %s%s", method, origin, path14);
23144
23198
  }
23145
23199
  );
23146
23200
  }
23147
23201
  __name(trackClientEvents, "trackClientEvents");
23148
23202
  var isTrackingRequestEvents = false;
23149
- function trackRequestEvents(debugLog = undiciDebugLog) {
23203
+ function trackRequestEvents(debugLog2 = undiciDebugLog) {
23150
23204
  if (isTrackingRequestEvents) {
23151
23205
  return;
23152
23206
  }
@@ -23162,7 +23216,7 @@ var require_diagnostics = __commonJS({
23162
23216
  request: { method, path: path14, origin },
23163
23217
  response: { statusCode }
23164
23218
  } = evt;
23165
- debugLog(
23219
+ debugLog2(
23166
23220
  "received response to %s %s%s - HTTP %d",
23167
23221
  method,
23168
23222
  origin,
@@ -23177,7 +23231,7 @@ var require_diagnostics = __commonJS({
23177
23231
  const {
23178
23232
  request: { method, path: path14, origin }
23179
23233
  } = evt;
23180
- debugLog("trailers received from %s %s%s", method, origin, path14);
23234
+ debugLog2("trailers received from %s %s%s", method, origin, path14);
23181
23235
  }
23182
23236
  );
23183
23237
  diagnosticsChannel.subscribe(
@@ -23187,7 +23241,7 @@ var require_diagnostics = __commonJS({
23187
23241
  request: { method, path: path14, origin },
23188
23242
  error: error95
23189
23243
  } = evt;
23190
- debugLog(
23244
+ debugLog2(
23191
23245
  "request to %s %s%s errored - %s",
23192
23246
  method,
23193
23247
  origin,
@@ -23199,7 +23253,7 @@ var require_diagnostics = __commonJS({
23199
23253
  }
23200
23254
  __name(trackRequestEvents, "trackRequestEvents");
23201
23255
  var isTrackingWebSocketEvents = false;
23202
- function trackWebSocketEvents(debugLog = websocketDebuglog) {
23256
+ function trackWebSocketEvents(debugLog2 = websocketDebuglog) {
23203
23257
  if (isTrackingWebSocketEvents) {
23204
23258
  return;
23205
23259
  }
@@ -23213,9 +23267,9 @@ var require_diagnostics = __commonJS({
23213
23267
  (evt) => {
23214
23268
  if (evt.address != null) {
23215
23269
  const { address, port } = evt.address;
23216
- debugLog("connection opened %s%s", address, port ? `:${port}` : "");
23270
+ debugLog2("connection opened %s%s", address, port ? `:${port}` : "");
23217
23271
  } else {
23218
- debugLog("connection opened");
23272
+ debugLog2("connection opened");
23219
23273
  }
23220
23274
  }
23221
23275
  );
@@ -23223,7 +23277,7 @@ var require_diagnostics = __commonJS({
23223
23277
  "undici:websocket:close",
23224
23278
  (evt) => {
23225
23279
  const { websocket, code: code3, reason } = evt;
23226
- debugLog(
23280
+ debugLog2(
23227
23281
  "closed connection to %s - %s %s",
23228
23282
  websocket.url,
23229
23283
  code3,
@@ -23234,19 +23288,19 @@ var require_diagnostics = __commonJS({
23234
23288
  diagnosticsChannel.subscribe(
23235
23289
  "undici:websocket:socket_error",
23236
23290
  (err) => {
23237
- debugLog("connection errored - %s", err.message);
23291
+ debugLog2("connection errored - %s", err.message);
23238
23292
  }
23239
23293
  );
23240
23294
  diagnosticsChannel.subscribe(
23241
23295
  "undici:websocket:ping",
23242
23296
  (evt) => {
23243
- debugLog("ping received");
23297
+ debugLog2("ping received");
23244
23298
  }
23245
23299
  );
23246
23300
  diagnosticsChannel.subscribe(
23247
23301
  "undici:websocket:pong",
23248
23302
  (evt) => {
23249
- debugLog("pong received");
23303
+ debugLog2("pong received");
23250
23304
  }
23251
23305
  );
23252
23306
  }
@@ -47490,7 +47544,7 @@ function createQueue(config4) {
47490
47544
  }
47491
47545
  const token = semaphore.tryAcquire();
47492
47546
  if (!token) {
47493
- console.warn(`[world-local]: concurrency limit (${WORKFLOW_LOCAL_QUEUE_CONCURRENCY}) reached, waiting for queue to free up`);
47547
+ debugLog(`[world-local]: concurrency limit (${WORKFLOW_LOCAL_QUEUE_CONCURRENCY}) reached, waiting for queue to free up`);
47494
47548
  await semaphore.acquire();
47495
47549
  }
47496
47550
  const MAX_LOCAL_SAFETY_LIMIT = 256;
@@ -47521,6 +47575,7 @@ function createQueue(config4) {
47521
47575
  headers: new Headers(headers),
47522
47576
  body,
47523
47577
  agents: nodeHttpAgents,
47578
+ signal: closeSignal,
47524
47579
  headersTimeoutMs: agentOptions.headersTimeout,
47525
47580
  bodyTimeoutMs: agentOptions.bodyTimeout
47526
47581
  }) : (
@@ -47530,7 +47585,8 @@ function createQueue(config4) {
47530
47585
  duplex: "half",
47531
47586
  dispatcher: httpAgent,
47532
47587
  headers,
47533
- body
47588
+ body,
47589
+ signal: closeSignal
47534
47590
  })
47535
47591
  );
47536
47592
  }
@@ -52817,7 +52873,7 @@ var require_token_util = __commonJS({
52817
52873
  findProjectInfo: /* @__PURE__ */ __name(() => findProjectInfo, "findProjectInfo"),
52818
52874
  getTokenPayload: /* @__PURE__ */ __name(() => getTokenPayload, "getTokenPayload"),
52819
52875
  getVercelDataDir: /* @__PURE__ */ __name(() => getVercelDataDir, "getVercelDataDir"),
52820
- getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken6, "getVercelOidcToken"),
52876
+ getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken7, "getVercelOidcToken"),
52821
52877
  getVercelToken: /* @__PURE__ */ __name(() => getVercelToken2, "getVercelToken"),
52822
52878
  isExpired: /* @__PURE__ */ __name(() => isExpired, "isExpired"),
52823
52879
  loadToken: /* @__PURE__ */ __name(() => loadToken, "loadToken"),
@@ -52879,7 +52935,7 @@ var require_token_util = __commonJS({
52879
52935
  }
52880
52936
  }
52881
52937
  __name(getVercelToken2, "getVercelToken");
52882
- async function getVercelOidcToken6(authToken, projectId, teamId) {
52938
+ async function getVercelOidcToken7(authToken, projectId, teamId) {
52883
52939
  const url3 = `https://api.vercel.com/v1/projects/${projectId}/token?source=vercel-oidc-refresh${teamId ? `&teamId=${teamId}` : ""}`;
52884
52940
  const res = await fetch(url3, {
52885
52941
  method: "POST",
@@ -52896,7 +52952,7 @@ var require_token_util = __commonJS({
52896
52952
  assertVercelOidcTokenResponse(tokenRes);
52897
52953
  return tokenRes;
52898
52954
  }
52899
- __name(getVercelOidcToken6, "getVercelOidcToken");
52955
+ __name(getVercelOidcToken7, "getVercelOidcToken");
52900
52956
  function assertVercelOidcTokenResponse(res) {
52901
52957
  if (!res || typeof res !== "object") {
52902
52958
  throw new TypeError(
@@ -53071,13 +53127,13 @@ var require_get_vercel_oidc_token = __commonJS({
53071
53127
  var __toCommonJS = /* @__PURE__ */ __name((mod) => __copyProps3(__defProp3({}, "__esModule", { value: true }), mod), "__toCommonJS");
53072
53128
  var get_vercel_oidc_token_exports = {};
53073
53129
  __export3(get_vercel_oidc_token_exports, {
53074
- getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken6, "getVercelOidcToken"),
53130
+ getVercelOidcToken: /* @__PURE__ */ __name(() => getVercelOidcToken7, "getVercelOidcToken"),
53075
53131
  getVercelOidcTokenSync: /* @__PURE__ */ __name(() => getVercelOidcTokenSync2, "getVercelOidcTokenSync")
53076
53132
  });
53077
53133
  module.exports = __toCommonJS(get_vercel_oidc_token_exports);
53078
53134
  var import_get_context = require_get_context2();
53079
53135
  var import_token_error = require_token_error();
53080
- async function getVercelOidcToken6(options) {
53136
+ async function getVercelOidcToken7(options) {
53081
53137
  let token = "";
53082
53138
  let err;
53083
53139
  try {
@@ -53107,7 +53163,7 @@ ${error95.message}`;
53107
53163
  }
53108
53164
  return token;
53109
53165
  }
53110
- __name(getVercelOidcToken6, "getVercelOidcToken");
53166
+ __name(getVercelOidcToken7, "getVercelOidcToken");
53111
53167
  function getVercelOidcTokenSync2() {
53112
53168
  const token = (0, import_get_context.getContext)().headers?.["x-vercel-oidc-token"] ?? process.env.VERCEL_OIDC_TOKEN;
53113
53169
  if (!token) {
@@ -56099,7 +56155,7 @@ var version4;
56099
56155
  var init_version3 = __esm({
56100
56156
  "../world-vercel/dist/version.js"() {
56101
56157
  "use strict";
56102
- version4 = "5.0.0-beta.42";
56158
+ version4 = "5.0.0-beta.43";
56103
56159
  }
56104
56160
  });
56105
56161
 
@@ -66213,7 +66269,7 @@ function headersToCarrier(headers) {
66213
66269
  }
66214
66270
  return carrier;
66215
66271
  }
66216
- function isDebugEnabled() {
66272
+ function isDebugEnabled2() {
66217
66273
  return process.env.VERCEL_QUEUE_DEBUG === "1" || process.env.VERCEL_QUEUE_DEBUG === "true";
66218
66274
  }
66219
66275
  async function consumeStream(stream) {
@@ -66987,7 +67043,7 @@ var init_dist10 = __esm({
66987
67043
  __name(withConsumerSpan, "withConsumerSpan");
66988
67044
  __name(extractProducerLink, "extractProducerLink");
66989
67045
  __name(headersToCarrier, "headersToCarrier");
66990
- __name(isDebugEnabled, "isDebugEnabled");
67046
+ __name(isDebugEnabled2, "isDebugEnabled");
66991
67047
  __name(consumeStream, "consumeStream");
66992
67048
  __name(parseRetryAfterSeconds, "parseRetryAfterSeconds");
66993
67049
  __name(throwCommonHttpError, "throwCommonHttpError");
@@ -67113,7 +67169,7 @@ Cause: ${cause}`
67113
67169
  }
67114
67170
  async fetch(url3, init) {
67115
67171
  const method = init.method || "GET";
67116
- if (isDebugEnabled()) {
67172
+ if (isDebugEnabled2()) {
67117
67173
  const logData = {
67118
67174
  method,
67119
67175
  url: url3,
@@ -67137,7 +67193,7 @@ Cause: ${cause}`
67137
67193
  init.headers.set("Vqs-Client-Ts", (/* @__PURE__ */ new Date()).toISOString());
67138
67194
  const fetchInit = this.dispatcher ? { ...init, dispatcher: this.dispatcher } : init;
67139
67195
  const response = await fetch(url3, fetchInit);
67140
- if (isDebugEnabled()) {
67196
+ if (isDebugEnabled2()) {
67141
67197
  const logData = {
67142
67198
  method,
67143
67199
  url: url3,
@@ -67713,7 +67769,14 @@ async function* decodeFrames(source) {
67713
67769
  const parts = [buffer3];
67714
67770
  let byteLength = buffer3.byteLength;
67715
67771
  while (byteLength < needed) {
67716
- const chunk = await chunks.next();
67772
+ let chunk;
67773
+ try {
67774
+ chunk = await chunks.next();
67775
+ } catch (cause) {
67776
+ throw new IncompleteFrameError("decodeFrames: source stream failed", {
67777
+ cause
67778
+ });
67779
+ }
67717
67780
  if (chunk.done)
67718
67781
  return false;
67719
67782
  if (chunk.value.byteLength === 0)
@@ -67741,16 +67804,16 @@ async function* decodeFrames(source) {
67741
67804
  const metaLen = new DataView(buffer3.buffer, buffer3.byteOffset, 4).getUint32(0, false);
67742
67805
  take(4);
67743
67806
  if (!await refill(metaLen)) {
67744
- throw new Error("decodeFrames: truncated meta block");
67807
+ throw new IncompleteFrameError("decodeFrames: truncated meta block");
67745
67808
  }
67746
67809
  const meta5 = CborObjectSchema.parse(decode5(take(metaLen)));
67747
67810
  if (!await refill(4)) {
67748
- throw new Error("decodeFrames: truncated body length");
67811
+ throw new IncompleteFrameError("decodeFrames: truncated body length");
67749
67812
  }
67750
67813
  const bodyLen = new DataView(buffer3.buffer, buffer3.byteOffset, 4).getUint32(0, false);
67751
67814
  take(4);
67752
67815
  if (bodyLen > 0 && !await refill(bodyLen)) {
67753
- throw new Error("decodeFrames: truncated body bytes");
67816
+ throw new IncompleteFrameError("decodeFrames: truncated body bytes");
67754
67817
  }
67755
67818
  yield { meta: meta5, body: buffer3.slice(0, bodyLen) };
67756
67819
  take(bodyLen);
@@ -67781,13 +67844,18 @@ async function* readerToIterator(reader) {
67781
67844
  closeQuietly(() => reader.cancel());
67782
67845
  }
67783
67846
  }
67784
- var V4_FRAME_CONTENT_TYPE, CborObjectSchema;
67847
+ var V4_FRAME_CONTENT_TYPE, IncompleteFrameError, CborObjectSchema;
67785
67848
  var init_frames = __esm({
67786
67849
  "../world-vercel/dist/frames.js"() {
67787
67850
  "use strict";
67788
67851
  init_node_index();
67789
67852
  init_zod2();
67790
67853
  V4_FRAME_CONTENT_TYPE = "application/vnd.workflow.v4-frames";
67854
+ IncompleteFrameError = class extends Error {
67855
+ static {
67856
+ __name(this, "IncompleteFrameError");
67857
+ }
67858
+ };
67791
67859
  CborObjectSchema = external_exports2.record(external_exports2.string(), external_exports2.unknown());
67792
67860
  __name(encodeFrame, "encodeFrame");
67793
67861
  __name(decodeFrames, "decodeFrames");
@@ -67867,7 +67935,7 @@ function openWsChannel(runId, config4) {
67867
67935
  return void 0;
67868
67936
  if (!wsState.loggedWsInUse) {
67869
67937
  wsState.loggedWsInUse = true;
67870
- console.log(`world-vercel: using ws events transport (${resolved}).`);
67938
+ debugLog(`world-vercel: using ws events transport (${resolved}).`);
67871
67939
  }
67872
67940
  const transport = getWsEventsTransport(resolved, async ({ forceRefresh }) => {
67873
67941
  if (forceRefresh)
@@ -67897,7 +67965,7 @@ function resolveChannelUrl(runId, config4) {
67897
67965
  if (usingProxy) {
67898
67966
  if (!wsState.loggedWsProxyFallback) {
67899
67967
  wsState.loggedWsProxyFallback = true;
67900
- console.warn(`world-vercel: ws events transport requested but a World with projectConfig (api-workflow proxy, resolved baseUrl: ${baseUrl}) is active \u2014 falling back.`);
67968
+ debugLog(`world-vercel: ws events transport unavailable for a World with projectConfig (api-workflow proxy, resolved baseUrl: ${baseUrl}) \u2014 falling back to HTTP.`);
67901
67969
  }
67902
67970
  return null;
67903
67971
  }
@@ -68250,7 +68318,7 @@ var init_ws_transport = __esm({
68250
68318
  if (decoded.meta.type === "drain") {
68251
68319
  const reason = decoded.meta.reason === "auth_expiry" ? "auth_expiry" : "max_duration";
68252
68320
  this.lastDrainReason = reason;
68253
- console.log(`world-vercel: ws events transport received a drain notice (reason: ${reason}, graceMs: ${decoded.meta.graceMs ?? "unspecified"}); connection will close soon.`);
68321
+ debugLog(`world-vercel: ws events transport received a drain notice (reason: ${reason}, graceMs: ${decoded.meta.graceMs ?? "unspecified"}); connection will close soon.`);
68254
68322
  return;
68255
68323
  }
68256
68324
  const reqId = decoded.meta.reqId;
@@ -68670,17 +68738,29 @@ var init_queue4 = __esm({
68670
68738
  });
68671
68739
 
68672
68740
  // ../world-vercel/dist/resolve-latest-deployment.js
68741
+ async function resolveDeploymentIdentityToken(config4) {
68742
+ if (config4?.token)
68743
+ return config4.token;
68744
+ if (process.env.VERCEL === "1") {
68745
+ const oidcToken = await (0, import_oidc5.getVercelOidcToken)().catch(() => null);
68746
+ if (oidcToken)
68747
+ return oidcToken;
68748
+ }
68749
+ return resolveVercelApiToken(config4);
68750
+ }
68673
68751
  function createResolveLatestDeploymentId(config4) {
68674
68752
  return /* @__PURE__ */ __name(async function resolveLatestDeploymentId() {
68675
68753
  const currentDeploymentId = process.env.VERCEL_DEPLOYMENT_ID;
68676
68754
  if (!currentDeploymentId) {
68677
68755
  throw new Error(missingDeploymentIdMessage("Resolving the latest deployment for deploymentId: 'latest'"));
68678
68756
  }
68679
- const token = await resolveVercelApiToken(config4);
68757
+ const token = await resolveDeploymentIdentityToken(config4);
68680
68758
  if (!token) {
68681
68759
  throw new Error("Cannot resolve latest deployment: no OIDC token or VERCEL_TOKEN available");
68682
68760
  }
68683
- const url3 = `https://api.vercel.com/v1/workflow/resolve-latest-deployment/${encodeURIComponent(currentDeploymentId)}`;
68761
+ const teamId = config4?.projectConfig?.teamId;
68762
+ const query = teamId ? `?${new URLSearchParams({ teamId })}` : "";
68763
+ const url3 = `https://api.vercel.com/v1/workflow/resolve-latest-deployment/${encodeURIComponent(currentDeploymentId)}${query}`;
68684
68764
  const response = await instrumentedFetch({
68685
68765
  method: "GET",
68686
68766
  url: url3,
@@ -68697,7 +68777,8 @@ function createResolveLatestDeploymentId(config4) {
68697
68777
  } catch {
68698
68778
  body = "<unable to read response body>";
68699
68779
  }
68700
- return new Error(`Failed to resolve latest deployment for ${currentDeploymentId}: HTTP ${res.status} ${res.statusText}${body ? ` \u2014 ${body}` : ""}`);
68780
+ const hint3 = res.status === 404 ? ". The deployment exists but was not visible to the identity this request authenticated as, which means the request resolved to a different team. Set the World's `projectConfig.teamId` to scope it explicitly." : "";
68781
+ return new Error(`Failed to resolve latest deployment for ${currentDeploymentId}: HTTP ${res.status} ${res.statusText}${body ? ` \u2014 ${body}` : ""}${hint3}`);
68701
68782
  }, "buildError")
68702
68783
  });
68703
68784
  const data = await response.json();
@@ -68708,10 +68789,11 @@ function createResolveLatestDeploymentId(config4) {
68708
68789
  return result2.data.id;
68709
68790
  }, "resolveLatestDeploymentId");
68710
68791
  }
68711
- var ResolveLatestDeploymentResponseSchema;
68792
+ var import_oidc5, ResolveLatestDeploymentResponseSchema;
68712
68793
  var init_resolve_latest_deployment = __esm({
68713
68794
  "../world-vercel/dist/resolve-latest-deployment.js"() {
68714
68795
  "use strict";
68796
+ import_oidc5 = __toESM(require_dist(), 1);
68715
68797
  init_zod2();
68716
68798
  init_deployment_id();
68717
68799
  init_http_client();
@@ -68719,6 +68801,7 @@ var init_resolve_latest_deployment = __esm({
68719
68801
  ResolveLatestDeploymentResponseSchema = object2({
68720
68802
  id: string5()
68721
68803
  });
68804
+ __name(resolveDeploymentIdentityToken, "resolveDeploymentIdentityToken");
68722
68805
  __name(createResolveLatestDeploymentId, "createResolveLatestDeploymentId");
68723
68806
  }
68724
68807
  });
@@ -68738,6 +68821,8 @@ function collectErrorMarkers(err, depth = 0) {
68738
68821
  return markers;
68739
68822
  }
68740
68823
  function isRetryableEventPostError(err) {
68824
+ if (err instanceof ReplayEventObserverError)
68825
+ return false;
68741
68826
  if (EntityConflictError2.is(err) || RunExpiredError2.is(err) || TooEarlyError.is(err) || ThrottleError2.is(err)) {
68742
68827
  return false;
68743
68828
  }
@@ -68821,11 +68906,22 @@ async function withEventPostRetry(fn, eventType, options) {
68821
68906
  }
68822
68907
  }
68823
68908
  }
68824
- var EVENT_RETRY_ELIGIBILITY, MAX_EVENT_POST_RETRIES, THROTTLE_RETRY_BUDGET_MS, DEFAULT_THROTTLE_RETRY_AFTER_SECONDS, EVENT_POST_RETRY_BASE_MS, EVENT_POST_RETRY_JITTER_MS, TRANSIENT_CODES, sleep, RETRY_DEBUG_ENABLED;
68909
+ var ReplayEventObserverError, EVENT_RETRY_ELIGIBILITY, MAX_EVENT_POST_RETRIES, THROTTLE_RETRY_BUDGET_MS, DEFAULT_THROTTLE_RETRY_AFTER_SECONDS, EVENT_POST_RETRY_BASE_MS, EVENT_POST_RETRY_JITTER_MS, TRANSIENT_CODES, sleep, RETRY_DEBUG_ENABLED;
68825
68910
  var init_event_retry = __esm({
68826
68911
  "../world-vercel/dist/event-retry.js"() {
68827
68912
  "use strict";
68828
68913
  init_dist7();
68914
+ ReplayEventObserverError = class extends Error {
68915
+ static {
68916
+ __name(this, "ReplayEventObserverError");
68917
+ }
68918
+ error;
68919
+ constructor(error95) {
68920
+ super("Replay event observer failed", { cause: error95 });
68921
+ this.error = error95;
68922
+ this.name = "ReplayEventObserverError";
68923
+ }
68924
+ };
68829
68925
  EVENT_RETRY_ELIGIBILITY = {
68830
68926
  // Creates: conditional create → 409 EntityConflictError if it already exists.
68831
68927
  run_created: {
@@ -69388,17 +69484,35 @@ async function createWorkflowRunEventV4(input, config4) {
69388
69484
  const response = await postWorkflowRunEventV4(input, "materialized", config4);
69389
69485
  const contentType = response.headers.get("content-type");
69390
69486
  if (contentType?.startsWith(V4_FRAME_CONTENT_TYPE)) {
69391
- throw new Error("v4 createEvent: unexpected event page");
69487
+ throw new WorkflowWorldError2("v4 createEvent: unexpected event page", {
69488
+ code: "SCHEMA_VALIDATION"
69489
+ });
69392
69490
  }
69393
69491
  return decodeCreateEventResponse(response, input.eventType);
69394
69492
  }
69395
69493
  async function decodeCreateEventResponse(response, eventType) {
69396
- const bodyBytes = new Uint8Array(await response.arrayBuffer());
69494
+ let bodyBytes;
69495
+ try {
69496
+ bodyBytes = new Uint8Array(await response.arrayBuffer());
69497
+ } catch (cause) {
69498
+ throw new WorkflowWorldError2("v4 createEvent: failed to read response body", { code: "TRANSPORT", cause });
69499
+ }
69397
69500
  if (bodyBytes.byteLength === 0) {
69398
- throw new Error("v4 createEvent: empty response body");
69501
+ throw new WorkflowWorldError2("v4 createEvent: empty response body", {
69502
+ code: "PARSE_ERROR"
69503
+ });
69399
69504
  }
69400
69505
  const schema = CreateEventV4BodySchemas[eventType].refine(({ event }) => event.eventType === eventType || eventType === "hook_created" && event.eventType === "hook_conflict", { path: ["event", "eventType"] });
69401
- const parsedBody = schema.safeParse(decode5(bodyBytes));
69506
+ let decoded;
69507
+ try {
69508
+ decoded = decode5(bodyBytes);
69509
+ } catch (cause) {
69510
+ throw new WorkflowWorldError2("v4 createEvent: invalid CBOR response body", {
69511
+ code: "PARSE_ERROR",
69512
+ cause
69513
+ });
69514
+ }
69515
+ const parsedBody = schema.safeParse(decoded);
69402
69516
  if (!parsedBody.success) {
69403
69517
  throw new WorkflowWorldError2("v4 createEvent: invalid response body", {
69404
69518
  code: "SCHEMA_VALIDATION",
@@ -69407,11 +69521,12 @@ async function decodeCreateEventResponse(response, eventType) {
69407
69521
  }
69408
69522
  return parsedBody.data;
69409
69523
  }
69410
- async function createWorkflowRunStartedEventV4(input, config4) {
69524
+ async function createWorkflowRunStartedEventV4(input, config4, replayEventObserver) {
69411
69525
  const response = await postWorkflowRunEventV4({ ...input, eventType: "run_started" }, "event-stream", config4);
69412
- const events = [];
69413
- const page = await consumeEventFrameStream(response, "createEvent", events);
69414
- assert4(page.cursor, "v4 createEvent: event stream missing cursor");
69526
+ const page = await consumeReplayLogResponse(response, input.runId, config4, replayEventObserver);
69527
+ if (!page.cursor) {
69528
+ throw new WorkflowWorldError2("v4 createEvent: event stream missing cursor", { code: "SCHEMA_VALIDATION" });
69529
+ }
69415
69530
  const maxEvents = MaxEventsHeaderSchema.safeParse(response.headers.get(MAX_EVENTS_HEADER));
69416
69531
  if (!maxEvents.success) {
69417
69532
  throw new WorkflowWorldError2("v4 createEvent: invalid max-events header", {
@@ -69419,7 +69534,7 @@ async function createWorkflowRunStartedEventV4(input, config4) {
69419
69534
  cause: maxEvents.error
69420
69535
  });
69421
69536
  }
69422
- return { events, ...page, maxEvents: maxEvents.data };
69537
+ return { ...page, maxEvents: maxEvents.data };
69423
69538
  }
69424
69539
  async function createWorkflowRunEventsBatchV4(input, config4) {
69425
69540
  assert4(input.events.length > 0, "v4 createEventBatch: empty batch");
@@ -69537,7 +69652,7 @@ async function postEventFrameOverWs(input, config4) {
69537
69652
  };
69538
69653
  });
69539
69654
  }
69540
- async function createHookReceivedPreloadEventV4(input, config4) {
69655
+ async function createHookReceivedPreloadEventV4(input, config4, replayEventObserver) {
69541
69656
  const response = await postWorkflowRunEventV4({ ...input, eventType: "hook_received" }, "event-stream", config4);
69542
69657
  const contentType = response.headers.get("content-type");
69543
69658
  if (!contentType?.startsWith(V4_FRAME_CONTENT_TYPE)) {
@@ -69546,12 +69661,10 @@ async function createHookReceivedPreloadEventV4(input, config4) {
69546
69661
  result: await decodeCreateEventResponse(response, "hook_received")
69547
69662
  };
69548
69663
  }
69549
- const events = [];
69550
- const page = await consumeEventFrameStream(response, "createEvent", events);
69664
+ const page = await consumeReplayLogResponse(response, input.runId, config4, replayEventObserver);
69551
69665
  const maxEvents = MaxEventsHeaderSchema.safeParse(response.headers.get(MAX_EVENTS_HEADER));
69552
69666
  return {
69553
69667
  kind: "stream",
69554
- events,
69555
69668
  ...page,
69556
69669
  canonicalEventId: response.headers.get(EVENT_ID_HEADER) ?? void 0,
69557
69670
  maxEvents: maxEvents.success ? maxEvents.data : void 0
@@ -69575,31 +69688,115 @@ async function getEventV4(runId, eventId, remoteRefBehavior, config4) {
69575
69688
  }
69576
69689
  const chunks = response.body;
69577
69690
  for await (const frame3 of decodeFrames(chunks)) {
69691
+ if (frame3.meta._error === 1) {
69692
+ throw streamErrorFrameToError(frame3.meta, "getEvent");
69693
+ }
69694
+ if (Object.keys(frame3.meta).some((key) => key.startsWith("_"))) {
69695
+ throw new Error("v4 getEvent: unexpected control frame");
69696
+ }
69578
69697
  return decodeEventFrame(frame3);
69579
69698
  }
69580
69699
  throw new Error(`v4 getEvent: empty frame stream for ${eventId}`);
69581
69700
  }
69582
- async function consumeEventFrameStream(response, opName, events) {
69701
+ function streamErrorFrameToError(meta5, opName) {
69702
+ const parsed = EventStreamErrorSchema.safeParse(meta5);
69703
+ if (!parsed.success) {
69704
+ return new WorkflowWorldError2(`v4 ${opName}: malformed terminal error frame`, { code: "SCHEMA_VALIDATION", cause: parsed.error });
69705
+ }
69706
+ const { code: code3, message } = parsed.data;
69707
+ const detail = message ?? "(no detail)";
69708
+ if (code3 === PAYLOAD_MISSING_ERROR_CODE) {
69709
+ return new CorruptedEventLogError(`the event log references a payload that no longer exists in storage: ${detail}`);
69710
+ }
69711
+ return new WorkflowWorldError2(`v4 ${opName}: stream ended with terminal error "${code3}": ${detail}`, { code: "WORLD_CONTRACT_ERROR" });
69712
+ }
69713
+ function partialEventFrameStream(events, error95) {
69714
+ const eventId = events.at(-1)?.eventId;
69715
+ if (!eventId)
69716
+ throw error95;
69717
+ return {
69718
+ kind: "partial",
69719
+ events,
69720
+ cursor: `eid:${eventId}`,
69721
+ hasMore: true,
69722
+ error: error95
69723
+ };
69724
+ }
69725
+ async function consumeEventFrameStream(response, opName, replayEventObserver) {
69583
69726
  const contentType = response.headers.get("content-type");
69584
69727
  if (!contentType?.startsWith(V4_FRAME_CONTENT_TYPE)) {
69585
- throw new Error(`v4 ${opName}: expected ${V4_FRAME_CONTENT_TYPE}, got ${contentType ?? "(none)"}`);
69728
+ throw new WorkflowWorldError2(`v4 ${opName}: expected ${V4_FRAME_CONTENT_TYPE}, got ${contentType ?? "(none)"}`, { code: "SCHEMA_VALIDATION" });
69586
69729
  }
69587
- const chunks = response.body;
69588
- for await (const frame3 of decodeFrames(chunks)) {
69589
- if (frame3.meta._end === 1) {
69590
- const end = EventStreamEndSchema.parse(frame3.meta);
69591
- return { cursor: end.next ?? null, hasMore: end.hasMore };
69730
+ if (!response.body) {
69731
+ throw new WorkflowWorldError2(`v4 ${opName}: response body is missing`, {
69732
+ code: "TRANSPORT"
69733
+ });
69734
+ }
69735
+ const events = [];
69736
+ try {
69737
+ for await (const frame3 of decodeFrames(response.body)) {
69738
+ if (frame3.meta._end === 1) {
69739
+ const end = EventStreamEndSchema.parse(frame3.meta);
69740
+ return {
69741
+ kind: "complete",
69742
+ events,
69743
+ cursor: end.next ?? null,
69744
+ hasMore: end.hasMore
69745
+ };
69746
+ }
69747
+ if (frame3.meta._error === 1) {
69748
+ throw streamErrorFrameToError(frame3.meta, opName);
69749
+ }
69750
+ if (Object.keys(frame3.meta).some((key) => key.startsWith("_"))) {
69751
+ throw new Error(`v4 ${opName}: unexpected control frame`);
69752
+ }
69753
+ const event = decodeEventFrame(frame3);
69754
+ events.push(event);
69755
+ try {
69756
+ replayEventObserver?.(event);
69757
+ } catch (error95) {
69758
+ throw new ReplayEventObserverError(error95);
69759
+ }
69592
69760
  }
69593
- if (Object.keys(frame3.meta).some((key) => key.startsWith("_"))) {
69594
- throw new Error(`v4 ${opName}: unexpected control frame`);
69761
+ } catch (cause) {
69762
+ if (cause instanceof ReplayEventObserverError || CorruptedEventLogError.is(cause) || WorkflowWorldError2.is(cause)) {
69763
+ throw cause;
69595
69764
  }
69596
- events.push(decodeEventFrame(frame3));
69765
+ if (!(cause instanceof IncompleteFrameError)) {
69766
+ throw new WorkflowWorldError2(`v4 ${opName}: invalid event frame stream`, {
69767
+ code: "SCHEMA_VALIDATION",
69768
+ cause
69769
+ });
69770
+ }
69771
+ return partialEventFrameStream(events, new WorkflowWorldError2(`v4 ${opName}: incomplete event frame stream`, {
69772
+ code: "TRANSPORT",
69773
+ cause
69774
+ }));
69775
+ }
69776
+ return partialEventFrameStream(events, new WorkflowWorldError2(`v4 ${opName}: frame stream ended without the end-of-stream sentinel (${events.length} events read)`, { code: "TRANSPORT" }));
69777
+ }
69778
+ async function consumeReplayLogResponse(response, runId, config4, replayEventObserver) {
69779
+ const page = await consumeEventFrameStream(response, "createEvent", replayEventObserver);
69780
+ if (!page.hasMore) {
69781
+ return {
69782
+ events: page.events,
69783
+ cursor: page.cursor,
69784
+ hasMore: false
69785
+ };
69597
69786
  }
69598
- throw new Error(`v4 ${opName}: frame stream ended without the end-of-stream sentinel (${events.length} events read) \u2014 truncated response?`);
69787
+ if (!page.cursor) {
69788
+ throw new WorkflowWorldError2("v4 createEvent: partial event stream missing cursor", { code: "SCHEMA_VALIDATION" });
69789
+ }
69790
+ const suffix = await getWorkflowRunEventsV4(runId, { cursor: page.cursor, remoteRefBehavior: "resolve" }, config4, replayEventObserver);
69791
+ return {
69792
+ events: [...page.events, ...suffix.events],
69793
+ cursor: suffix.cursor ?? page.cursor,
69794
+ hasMore: suffix.hasMore
69795
+ };
69599
69796
  }
69600
- async function consumeListFrameStream(url3, headers, config4, opName, events) {
69797
+ async function consumeListFrameStream(url3, headers, config4, opName, replayEventObserver) {
69601
69798
  const response = await fetchV4(url3, { method: "GET", headers }, config4, opName);
69602
- return consumeEventFrameStream(response, opName, events);
69799
+ return consumeEventFrameStream(response, opName, replayEventObserver);
69603
69800
  }
69604
69801
  function appendListParams(sp, params) {
69605
69802
  if (params.cursor)
@@ -69619,23 +69816,34 @@ function paginationToQuery(params) {
69619
69816
  appendListParams(sp, params);
69620
69817
  return `?${sp.toString()}`;
69621
69818
  }
69622
- async function getWorkflowRunEventsV4(runId, params = {}, config4) {
69819
+ async function getWorkflowRunEventsV4(runId, params = {}, config4, replayEventObserver) {
69623
69820
  const { baseUrl, headers } = await getHttpConfig(config4);
69624
69821
  const events = [];
69625
- let cursor = params.cursor;
69626
- while (true) {
69627
- const url3 = `${baseUrl}/v4/runs/${encodeURIComponent(runId)}/events` + paginationToQuery({ ...params, cursor });
69628
- try {
69629
- const page = await consumeListFrameStream(url3, headers, config4, "listEvents", events);
69630
- return { events, ...page };
69631
- } catch (error95) {
69632
- const lastEvent = events.at(-1);
69633
- if (params.limit !== void 0 || !lastEvent || `eid:${lastEvent.eventId}` === cursor) {
69634
- throw error95;
69635
- }
69636
- cursor = `eid:${lastEvent.eventId}`;
69637
- }
69638
- }
69822
+ let cursor = params.cursor ?? null;
69823
+ let partialStreamRetries = 0;
69824
+ let consumed;
69825
+ do {
69826
+ const url3 = `${baseUrl}/v4/runs/${encodeURIComponent(runId)}/events` + paginationToQuery({ ...params, cursor: cursor ?? void 0 });
69827
+ consumed = await consumeListFrameStream(url3, headers, config4, "listEvents", replayEventObserver);
69828
+ const cursorAdvanced = !!consumed.cursor && consumed.cursor !== cursor;
69829
+ if (consumed.kind === "partial") {
69830
+ if (params.limit !== void 0 || !cursorAdvanced || partialStreamRetries === MAX_PARTIAL_STREAM_RETRIES) {
69831
+ throw consumed.error;
69832
+ }
69833
+ partialStreamRetries++;
69834
+ cursor = consumed.cursor;
69835
+ } else if (!cursorAdvanced && (consumed.events.length > 0 || consumed.hasMore)) {
69836
+ throw new WorkflowWorldError2("v4 listEvents: response did not advance cursor", { code: "SCHEMA_VALIDATION" });
69837
+ }
69838
+ for (const event of consumed.events) {
69839
+ events.push(event);
69840
+ }
69841
+ } while (consumed.kind === "partial");
69842
+ return {
69843
+ events,
69844
+ cursor: consumed.cursor || (partialStreamRetries > 0 ? cursor : null),
69845
+ hasMore: consumed.hasMore
69846
+ };
69639
69847
  }
69640
69848
  async function getEventsByCorrelationIdV4(correlationId, runId, params = {}, config4) {
69641
69849
  const { baseUrl, headers } = await getHttpConfig(config4);
@@ -69644,11 +69852,16 @@ async function getEventsByCorrelationIdV4(correlationId, runId, params = {}, con
69644
69852
  sp.set("runId", runId);
69645
69853
  appendListParams(sp, params);
69646
69854
  const url3 = `${baseUrl}/v4/events?${sp.toString()}`;
69647
- const events = [];
69648
- const page = await consumeListFrameStream(url3, headers, config4, "listEventsByCorrelationId", events);
69649
- return { events, ...page };
69855
+ const consumed = await consumeListFrameStream(url3, headers, config4, "listEventsByCorrelationId");
69856
+ if (consumed.kind === "partial")
69857
+ throw consumed.error;
69858
+ return {
69859
+ events: consumed.events,
69860
+ cursor: consumed.cursor,
69861
+ hasMore: consumed.hasMore
69862
+ };
69650
69863
  }
69651
- var EVENT_ID_HEADER, MAX_EVENTS_HEADER, CreateEventV4BodyBaseSchema, CreateEventV4PageSchema, CreateEventV4BodySchema, CreateEventV4BodySchemas, MaxEventsHeaderSchema, EventStreamEndSchema, legacyStructuredErrorEventTypes, STRICT_WS_EVENT_TYPES, BatchItemFailureSchema;
69864
+ var EVENT_ID_HEADER, MAX_EVENTS_HEADER, CreateEventV4BodyBaseSchema, CreateEventV4PageSchema, CreateEventV4BodySchema, CreateEventV4BodySchemas, MaxEventsHeaderSchema, EventStreamEndSchema, EventStreamErrorSchema, PAYLOAD_MISSING_ERROR_CODE, legacyStructuredErrorEventTypes, STRICT_WS_EVENT_TYPES, BatchItemFailureSchema, MAX_PARTIAL_STREAM_RETRIES;
69652
69865
  var init_events_v4 = __esm({
69653
69866
  "../world-vercel/dist/events-v4.js"() {
69654
69867
  "use strict";
@@ -69656,6 +69869,7 @@ var init_events_v4 = __esm({
69656
69869
  init_dist6();
69657
69870
  init_node_index();
69658
69871
  init_zod2();
69872
+ init_event_retry();
69659
69873
  init_frames();
69660
69874
  init_http_client();
69661
69875
  init_http_core();
@@ -69730,6 +69944,12 @@ var init_events_v4 = __esm({
69730
69944
  next: external_exports2.string().optional(),
69731
69945
  hasMore: external_exports2.boolean()
69732
69946
  });
69947
+ EventStreamErrorSchema = external_exports2.object({
69948
+ _error: external_exports2.literal(1),
69949
+ code: external_exports2.string(),
69950
+ message: external_exports2.string().optional()
69951
+ });
69952
+ PAYLOAD_MISSING_ERROR_CODE = "payload-missing";
69733
69953
  legacyStructuredErrorEventTypes = /* @__PURE__ */ new Set([
69734
69954
  "run_failed",
69735
69955
  "step_failed",
@@ -69760,7 +69980,11 @@ var init_events_v4 = __esm({
69760
69980
  __name(createHookReceivedPreloadEventV4, "createHookReceivedPreloadEventV4");
69761
69981
  __name(readHeader, "readHeader");
69762
69982
  __name(getEventV4, "getEventV4");
69983
+ __name(streamErrorFrameToError, "streamErrorFrameToError");
69984
+ MAX_PARTIAL_STREAM_RETRIES = 2;
69985
+ __name(partialEventFrameStream, "partialEventFrameStream");
69763
69986
  __name(consumeEventFrameStream, "consumeEventFrameStream");
69987
+ __name(consumeReplayLogResponse, "consumeReplayLogResponse");
69764
69988
  __name(consumeListFrameStream, "consumeListFrameStream");
69765
69989
  __name(appendListParams, "appendListParams");
69766
69990
  __name(paginationToQuery, "paginationToQuery");
@@ -70211,6 +70435,8 @@ async function createWorkflowRunEvent(id, data, params, config4) {
70211
70435
  }
70212
70436
  return result2;
70213
70437
  } catch (err) {
70438
+ if (err instanceof ReplayEventObserverError)
70439
+ throw err.error;
70214
70440
  if (isHookEventRequiringExistence(data.eventType) && WorkflowWorldError2.is(err) && err.status === 404 && data.correlationId) {
70215
70441
  throw new HookNotFoundError2(data.correlationId);
70216
70442
  }
@@ -70282,39 +70508,14 @@ async function createWorkflowRunEventInner(id, data, params, config4) {
70282
70508
  ...meta5
70283
70509
  };
70284
70510
  if (data.eventType === "run_started" && !params?.skipPreload) {
70285
- const result2 = await createWorkflowRunStartedEventV4(input, config4);
70286
- const runCreated = result2.events.find((event) => event.eventType === "run_created");
70287
- const runStarted = result2.events.find((event) => event.eventType === "run_started");
70288
- if (!runCreated) {
70289
- throw new Error("v4 createEvent: run_started stream is missing run_created");
70290
- }
70291
- if (!runStarted) {
70292
- throw new Error("v4 createEvent: run_started stream is missing run_started");
70293
- }
70294
- let attributes = runCreated.eventData.attributes ?? {};
70295
- let updatedAt = runStarted.createdAt;
70296
- for (const event of result2.events) {
70297
- if (event.eventType === "attr_set") {
70298
- attributes = applyAttributeChanges(attributes, event.eventData.changes);
70299
- updatedAt = event.createdAt;
70300
- }
70511
+ const result2 = await createWorkflowRunStartedEventV4(input, config4, params?.replayEventObserver);
70512
+ const replayRun = reconstructRunFromReplayEvents(result2.events);
70513
+ if (!replayRun) {
70514
+ throw new WorkflowWorldError2("v4 createEvent: run_started stream is missing lifecycle events", { code: "SCHEMA_VALIDATION" });
70301
70515
  }
70302
70516
  return {
70303
- event: runStarted,
70304
- run: {
70305
- runId: runCreated.runId,
70306
- status: "running",
70307
- deploymentId: runCreated.eventData.deploymentId,
70308
- workflowName: runCreated.eventData.workflowName,
70309
- specVersion: runCreated.specVersion,
70310
- executionContext: runCreated.eventData.executionContext,
70311
- input: runCreated.eventData.input,
70312
- attributes,
70313
- encryptionPublicKey: runCreated.eventData.encryptionPublicKey,
70314
- startedAt: runStarted.createdAt,
70315
- createdAt: runCreated.createdAt,
70316
- updatedAt
70317
- },
70517
+ event: replayRun.event,
70518
+ run: replayRun.run,
70318
70519
  events: result2.events,
70319
70520
  cursor: result2.cursor,
70320
70521
  hasMore: result2.hasMore,
@@ -70322,16 +70523,16 @@ async function createWorkflowRunEventInner(id, data, params, config4) {
70322
70523
  };
70323
70524
  }
70324
70525
  if (data.eventType === "hook_received" && params?.preloadEvents === true && params.resumeId !== void 0 && params.resumePayloadDigest !== void 0) {
70325
- const outcome = await createHookReceivedPreloadEventV4({ ...input, remoteRefBehavior: "lazy" }, config4);
70526
+ const outcome = await createHookReceivedPreloadEventV4({ ...input, remoteRefBehavior: "lazy" }, config4, params.replayEventObserver);
70326
70527
  if (outcome.kind === "materialized") {
70327
70528
  return outcome.result;
70328
70529
  }
70329
70530
  const { canonicalEventId, maxEvents, events, cursor, hasMore } = outcome;
70330
70531
  const canonicalEvent = events.find((event) => event.eventId === canonicalEventId);
70331
- const run3 = reconstructRunFromReplayEvents(events);
70532
+ const replayRun = reconstructRunFromReplayEvents(events);
70332
70533
  return {
70333
70534
  ...canonicalEvent ? { event: canonicalEvent } : {},
70334
- ...run3 ? { run: run3 } : {},
70535
+ ...replayRun ? { run: replayRun.run } : {},
70335
70536
  events,
70336
70537
  cursor,
70337
70538
  hasMore,
@@ -70343,9 +70544,8 @@ async function createWorkflowRunEventInner(id, data, params, config4) {
70343
70544
  function reconstructRunFromReplayEvents(events) {
70344
70545
  const runCreated = events.find((event) => event.eventType === "run_created");
70345
70546
  const runStarted = events.find((event) => event.eventType === "run_started");
70346
- if (!runCreated || !runStarted) {
70347
- return void 0;
70348
- }
70547
+ if (!runCreated || !runStarted)
70548
+ return;
70349
70549
  let attributes = runCreated.eventData.attributes ?? {};
70350
70550
  let updatedAt = runStarted.createdAt;
70351
70551
  for (const event of events) {
@@ -70355,18 +70555,21 @@ function reconstructRunFromReplayEvents(events) {
70355
70555
  }
70356
70556
  }
70357
70557
  return {
70358
- runId: runCreated.runId,
70359
- status: "running",
70360
- deploymentId: runCreated.eventData.deploymentId,
70361
- workflowName: runCreated.eventData.workflowName,
70362
- specVersion: runCreated.specVersion,
70363
- executionContext: runCreated.eventData.executionContext,
70364
- input: runCreated.eventData.input,
70365
- attributes,
70366
- encryptionPublicKey: runCreated.eventData.encryptionPublicKey,
70367
- startedAt: runStarted.createdAt,
70368
- createdAt: runCreated.createdAt,
70369
- updatedAt
70558
+ event: runStarted,
70559
+ run: {
70560
+ runId: runCreated.runId,
70561
+ status: "running",
70562
+ deploymentId: runCreated.eventData.deploymentId,
70563
+ workflowName: runCreated.eventData.workflowName,
70564
+ specVersion: runCreated.specVersion,
70565
+ executionContext: runCreated.eventData.executionContext,
70566
+ input: runCreated.eventData.input,
70567
+ attributes,
70568
+ encryptionPublicKey: runCreated.eventData.encryptionPublicKey,
70569
+ startedAt: runStarted.createdAt,
70570
+ createdAt: runCreated.createdAt,
70571
+ updatedAt
70572
+ }
70370
70573
  };
70371
70574
  }
70372
70575
  var eventsNeedingResolve;
@@ -71757,7 +71960,7 @@ var init_log_format2 = __esm({
71757
71960
  function SemanticConvention4(...names) {
71758
71961
  return (value) => Object.fromEntries(names.map((name) => [name, value]));
71759
71962
  }
71760
- var WorkflowName2, WorkflowOperation2, WorkflowRunId4, WorkflowRunStatus2, WorkflowStartedAt2, WorkflowEventsCount2, WorkflowExecutionMode2, WorkflowParkedEventsCount2, WorkflowParkedEventId2, WorkflowParkedEventType2, WorkflowArgumentsCount2, WorkflowResultType2, WorkflowTracePropagated2, WorkflowVm2, QuickJSOutcome2, QuickJSEventsPreloaded2, QuickJSEventsFetchedCount2, QuickJSEventsFetchedPages2, QuickJSPendingOpsCount2, QuickJSInlineSteps2, WorkflowTraceMode2, WorkflowTurbo2, WorkflowErrorName2, WorkflowErrorMessage2, WorkflowErrorCode2, WorkflowStepsCreated2, WorkflowHooksCreated2, WorkflowWaitsCreated2, WorkflowStepsFailedSerialization2, WorkflowOwnedRecoverySteps2, WorkflowBackstopWakesArmed2, WorkflowRouteType2, WorkflowRouteHandlerCached2, WorkflowRouteInvocationCount2, WorkflowRouteEntrypointAgeMs2, WorkflowRouteModuleBodyInitMs2, FaasInstance2, StepName2, StepId4, StepAttempt2, StepStatus2, StepMaxRetries2, StepTracePropagated2, StepTtfsMs2, StepStsoMs3, StepRsfsMs2, StepFinalSchedulingReplayMs2, StepLatencyOptimizations3, StepSkipped2, StepSkipReason2, StepArgumentsCount2, StepResultType2, StepErrorName2, StepErrorMessage2, StepFatalError2, StepRetryExhausted2, StepRetryTimeoutSeconds2, StepRetryWillRetry2, MessagingSystem2, MessagingDestinationName2, MessagingMessageId2, MessagingOperationType2, QueueOverheadMs2, DeploymentId2, WorkflowRunPinnedDeploymentId2, WorkflowDeploymentMismatchRetryCount2, WorkflowDeploymentMismatchRecovered2, HookToken2, HookId2, HookFound2, HookResilientResume2, HookResilientResumeMaterialized2, HookResumeSetupSource2, StepResilientDispatchRecovered2, StepResilientDispatchMaterialized2, ResumeTotalMs2, ResumeProducerPrepMs2, ResumeQueueDeliveryMs2, ResumeSetupMs2, ResumeReplayMs2, ResumeStepDispatchMs2, ResumeStepClaimMs2, ResumeStepPrepareMs2, ResumeTrigger2, ResumeStrategy2, ResumeSetupSource2, ResumeStepExecution2, WebhookHandlersTriggered2, WorkflowSuspensionState2, WorkflowSuspensionHookCount2, WorkflowSuspensionStepCount2, WorkflowSuspensionWaitCount2, HttpRequestMethod3, HttpRoute2, UrlFull3, ServerAddress3, ServerPort3, HttpResponseStatusCode3, ErrorType3, WorldParseFormat3, WorkflowEventsPagesLoaded2, QueueDeserializeTimeMs2, QueueExecutionTimeMs2, QueueSerializeTimeMs2, SerializationOperation2, SerializationCompressed2, SerializationCodec2, SerializationUncompressedBytes2, SerializationStoredBytes2, SerializationCompressionRatio2, SerializationGuestCodeExecutions2, SerializationGuestCodeDetails2, PeerService4, RpcSystem4, RpcService4, RpcMethod4, ErrorRetryable2, ErrorCategory2;
71963
+ var WorkflowName2, WorkflowOperation2, WorkflowRunId4, WorkflowRunStatus2, WorkflowStartedAt2, WorkflowEventsCount2, WorkflowExecutionMode2, WorkflowBundleCompileCacheHit2, WorkflowReplayLoadSource2, WorkflowParkedEventsCount2, WorkflowParkedEventId2, WorkflowParkedEventType2, WorkflowArgumentsCount2, WorkflowResultType2, WorkflowTracePropagated2, WorkflowVm2, QuickJSOutcome2, QuickJSEventsPreloaded2, QuickJSEventsFetchedCount2, QuickJSEventsFetchedPages2, QuickJSPendingOpsCount2, QuickJSInlineSteps2, WorkflowTraceMode2, WorkflowTurbo2, WorkflowErrorName2, WorkflowErrorMessage2, WorkflowErrorCode2, WorkflowStepsCreated2, WorkflowHooksCreated2, WorkflowWaitsCreated2, WorkflowStepsFailedSerialization2, WorkflowOwnedRecoverySteps2, WorkflowBackstopWakesArmed2, WorkflowRouteType2, WorkflowRouteHandlerCached2, WorkflowRouteInvocationCount2, WorkflowRouteEntrypointAgeMs2, WorkflowRouteModuleBodyInitMs2, FaasInstance2, StepName2, StepId4, StepAttempt2, StepStatus2, StepMaxRetries2, StepTracePropagated2, StepTtfsMs2, StepStsoMs3, StepRsfsMs2, StepFinalSchedulingReplayMs2, StepLatencyOptimizations3, StepSkipped2, StepSkipReason2, StepArgumentsCount2, StepResultType2, StepErrorName2, StepErrorMessage2, StepFatalError2, StepRetryExhausted2, StepRetryTimeoutSeconds2, StepRetryWillRetry2, MessagingSystem2, MessagingDestinationName2, MessagingMessageId2, MessagingOperationType2, QueueOverheadMs2, DeploymentId2, WorkflowRunPinnedDeploymentId2, WorkflowDeploymentMismatchRetryCount2, WorkflowDeploymentMismatchRecovered2, HookToken2, HookId2, HookFound2, HookResilientResume2, HookResumeCommitted2, HookWakePublished2, HookResilientResumeMaterialized2, HookResumeSetupSource2, StepResilientDispatchRecovered2, StepResilientDispatchMaterialized2, ResumeTotalMs2, ResumeProducerPrepMs2, ResumeQueueDeliveryMs2, ResumeSetupMs2, ResumeReplayMs2, ResumeStepDispatchMs2, ResumeStepClaimMs2, ResumeStepPrepareMs2, ResumeTrigger2, ResumeStrategy2, ResumeSetupSource2, ResumeStepExecution2, WebhookHandlersTriggered2, WorkflowSuspensionState2, WorkflowSuspensionHookCount2, WorkflowSuspensionStepCount2, WorkflowSuspensionWaitCount2, HttpRequestMethod3, HttpRoute2, UrlFull3, ServerAddress3, ServerPort3, HttpResponseStatusCode3, ErrorType3, WorldParseFormat3, WorkflowEventsPagesLoaded2, QueueDeserializeTimeMs2, QueueExecutionTimeMs2, QueueSerializeTimeMs2, SerializationOperation2, SerializationCompressed2, SerializationCodec2, SerializationUncompressedBytes2, SerializationStoredBytes2, SerializationCompressionRatio2, SerializationGuestCodeExecutions2, SerializationGuestCodeDetails2, PeerService4, RpcSystem4, RpcService4, RpcMethod4, ErrorRetryable2, ErrorCategory2;
71761
71964
  var init_semantic_conventions2 = __esm({
71762
71965
  "../core/dist/telemetry/semantic-conventions.js"() {
71763
71966
  "use strict";
@@ -71769,6 +71972,8 @@ var init_semantic_conventions2 = __esm({
71769
71972
  WorkflowStartedAt2 = SemanticConvention4("workflow.started_at");
71770
71973
  WorkflowEventsCount2 = SemanticConvention4("workflow.events.count");
71771
71974
  WorkflowExecutionMode2 = SemanticConvention4("workflow.execution.mode");
71975
+ WorkflowBundleCompileCacheHit2 = SemanticConvention4("workflow.bundle.compile.cache_hit");
71976
+ WorkflowReplayLoadSource2 = SemanticConvention4("workflow.replay.load.source");
71772
71977
  WorkflowParkedEventsCount2 = SemanticConvention4("workflow.events.parked.count");
71773
71978
  WorkflowParkedEventId2 = SemanticConvention4("workflow.events.parked.event_id");
71774
71979
  WorkflowParkedEventType2 = SemanticConvention4("workflow.events.parked.event_type");
@@ -71833,6 +72038,8 @@ var init_semantic_conventions2 = __esm({
71833
72038
  HookId2 = SemanticConvention4("workflow.hook.id");
71834
72039
  HookFound2 = SemanticConvention4("workflow.hook.found");
71835
72040
  HookResilientResume2 = SemanticConvention4("workflow.hook.resilient_resume");
72041
+ HookResumeCommitted2 = SemanticConvention4("workflow.hook.resume_committed");
72042
+ HookWakePublished2 = SemanticConvention4("workflow.hook.wake_published");
71836
72043
  HookResilientResumeMaterialized2 = SemanticConvention4("workflow.hook.resilient_resume_materialized");
71837
72044
  HookResumeSetupSource2 = SemanticConvention4("workflow.resume_setup_source");
71838
72045
  StepResilientDispatchRecovered2 = SemanticConvention4("workflow.step.resilient_dispatch_recovered");
@@ -71933,6 +72140,16 @@ async function withTraceContext(traceCarrier, fn) {
71933
72140
  }
71934
72141
  return otel3.context.with(extractedContext, async () => await fn());
71935
72142
  }
72143
+ function describeThrownValue2(value) {
72144
+ try {
72145
+ if (typeof value === "object" && value !== null && "message" in value && typeof value.message === "string") {
72146
+ return value.message;
72147
+ }
72148
+ return String(value);
72149
+ } catch {
72150
+ return "Unknown error";
72151
+ }
72152
+ }
71936
72153
  function logOtelDiagnosticOnce3(otel3, tracer) {
71937
72154
  const debugEnabled = typeof process !== "undefined" && typeof process.env.DEBUG === "string" && (process.env.DEBUG.includes("workflow:") || process.env.DEBUG === "*");
71938
72155
  if (otelDiagLogged3 || !debugEnabled)
@@ -71976,7 +72193,7 @@ async function trace5(spanName, ...args) {
71976
72193
  } else {
71977
72194
  span.setStatus({
71978
72195
  code: otel3.SpanStatusCode.ERROR,
71979
- message: e.message
72196
+ message: describeThrownValue2(e)
71980
72197
  });
71981
72198
  }
71982
72199
  throw e;
@@ -71985,6 +72202,52 @@ async function trace5(spanName, ...args) {
71985
72202
  }
71986
72203
  });
71987
72204
  }
72205
+ async function startTraceSpan(spanName) {
72206
+ const [tracer, otel3] = await Promise.all([Tracer2.value, OtelApi2.value]);
72207
+ if (!tracer || !otel3)
72208
+ return { end() {
72209
+ }, fail() {
72210
+ } };
72211
+ const span = tracer.startSpan(spanName);
72212
+ let ended = false;
72213
+ const finish = /* @__PURE__ */ __name((status) => {
72214
+ if (ended)
72215
+ return;
72216
+ ended = true;
72217
+ span.setStatus(status);
72218
+ span.end();
72219
+ }, "finish");
72220
+ return {
72221
+ end: /* @__PURE__ */ __name(() => finish({ code: otel3.SpanStatusCode.OK }), "end"),
72222
+ fail: /* @__PURE__ */ __name((error95) => finish({
72223
+ code: otel3.SpanStatusCode.ERROR,
72224
+ message: describeThrownValue2(error95)
72225
+ }), "fail")
72226
+ };
72227
+ }
72228
+ async function bindActiveTraceContext(fn) {
72229
+ const otel3 = await OtelApi2.value;
72230
+ return otel3 ? otel3.context.bind(otel3.context.active(), fn) : fn;
72231
+ }
72232
+ async function createRefreshableTraceContext() {
72233
+ const otel3 = await OtelApi2.value;
72234
+ if (!otel3) {
72235
+ return { refresh() {
72236
+ }, run: /* @__PURE__ */ __name((fn) => fn(), "run") };
72237
+ }
72238
+ let current = otel3.context.active();
72239
+ const context2 = {
72240
+ getValue: /* @__PURE__ */ __name((key) => current.getValue(key), "getValue"),
72241
+ setValue: /* @__PURE__ */ __name((key, value) => current.setValue(key, value), "setValue"),
72242
+ deleteValue: /* @__PURE__ */ __name((key) => current.deleteValue(key), "deleteValue")
72243
+ };
72244
+ return {
72245
+ refresh: /* @__PURE__ */ __name(() => {
72246
+ current = otel3.context.active();
72247
+ }, "refresh"),
72248
+ run: /* @__PURE__ */ __name((fn) => otel3.context.with(context2, fn), "run")
72249
+ };
72250
+ }
71988
72251
  async function recordElapsedSpan2(spanName, startEpochMs, opts) {
71989
72252
  const tracer = await Tracer2.value;
71990
72253
  if (!tracer)
@@ -72098,8 +72361,12 @@ var init_telemetry4 = __esm({
72098
72361
  });
72099
72362
  });
72100
72363
  otelDiagLogged3 = false;
72364
+ __name(describeThrownValue2, "describeThrownValue");
72101
72365
  __name(logOtelDiagnosticOnce3, "logOtelDiagnosticOnce");
72102
72366
  __name(trace5, "trace");
72367
+ __name(startTraceSpan, "startTraceSpan");
72368
+ __name(bindActiveTraceContext, "bindActiveTraceContext");
72369
+ __name(createRefreshableTraceContext, "createRefreshableTraceContext");
72103
72370
  __name(recordElapsedSpan2, "recordElapsedSpan");
72104
72371
  __name(recordStepExecutionDuration, "recordStepExecutionDuration");
72105
72372
  __name(applyWorkflowSuspensionToSpan2, "applyWorkflowSuspensionToSpan");
@@ -72317,7 +72584,7 @@ async function awaitEarlierDeliveries(ctx, eventIndex, kind) {
72317
72584
  if (!gatesOn(kind, eventIndex, index, entry)) {
72318
72585
  continue;
72319
72586
  }
72320
- earlier.push(entry.delivered);
72587
+ earlier.push(entry.released);
72321
72588
  }
72322
72589
  if (earlier.length > 0) {
72323
72590
  await Promise.all(earlier);
@@ -72337,29 +72604,52 @@ function registerDeliveryBarrier(ctx, eventIndex, kind, options = {}) {
72337
72604
  }, "markDelivered"), arm: /* @__PURE__ */ __name(() => {
72338
72605
  }, "arm") };
72339
72606
  }
72340
- let done = false;
72341
- const { promise: promise3, resolve: resolve3 } = withResolvers2();
72342
- const finish = /* @__PURE__ */ __name(() => {
72343
- if (done) {
72344
- return;
72345
- }
72346
- done = true;
72347
- if (barriers.get(eventIndex) === entry) {
72348
- barriers.delete(eventIndex);
72607
+ const install = /* @__PURE__ */ __name((armed) => {
72608
+ if (barriers.has(eventIndex)) {
72609
+ throw new WorkflowRuntimeError2(`Delivery barrier already registered at event index ${eventIndex}`);
72349
72610
  }
72350
- resolve3();
72351
- }, "finish");
72352
- const entry = {
72353
- kind,
72354
- delivered: promise3,
72355
- armed: options.armed ?? true,
72356
- retire: finish
72357
- };
72358
- barriers.set(eventIndex, entry);
72359
- ensureBarrierSafetyNet(ctx);
72611
+ const { promise: promise3, resolve: resolve3 } = withResolvers2();
72612
+ const entry2 = {
72613
+ kind,
72614
+ released: promise3,
72615
+ armed,
72616
+ retired: false,
72617
+ retire: /* @__PURE__ */ __name(() => {
72618
+ if (entry2.retired) {
72619
+ return;
72620
+ }
72621
+ entry2.retired = true;
72622
+ if (barriers.get(eventIndex) === entry2) {
72623
+ barriers.delete(eventIndex);
72624
+ }
72625
+ resolve3();
72626
+ }, "retire")
72627
+ };
72628
+ barriers.set(eventIndex, entry2);
72629
+ ensureBarrierSafetyNet(ctx);
72630
+ return entry2;
72631
+ }, "install");
72632
+ let entry = install(options.armed ?? true);
72633
+ let deliveredToWorkflow = false;
72360
72634
  return {
72361
- markDelivered: finish,
72635
+ markDelivered: /* @__PURE__ */ __name(() => {
72636
+ if (deliveredToWorkflow) {
72637
+ return;
72638
+ }
72639
+ deliveredToWorkflow = true;
72640
+ entry.retire();
72641
+ }, "markDelivered"),
72362
72642
  arm: /* @__PURE__ */ __name(() => {
72643
+ if (deliveredToWorkflow) {
72644
+ return;
72645
+ }
72646
+ if (entry.retired) {
72647
+ entry = install(true);
72648
+ return;
72649
+ }
72650
+ if (barriers.get(eventIndex) !== entry) {
72651
+ throw new WorkflowRuntimeError2(`Delivery barrier lost ownership of event index ${eventIndex}`);
72652
+ }
72363
72653
  entry.armed = true;
72364
72654
  }, "arm")
72365
72655
  };
@@ -72443,6 +72733,7 @@ var RegisteredStepsKey2, globalSymbols3, registeredSteps2, BUILTIN_RESPONSE_STEP
72443
72733
  var init_private2 = __esm({
72444
72734
  "../core/dist/private.js"() {
72445
72735
  "use strict";
72736
+ init_dist7();
72446
72737
  init_dist5();
72447
72738
  init_global2();
72448
72739
  RegisteredStepsKey2 = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps");
@@ -75697,6 +75988,7 @@ var init_events_consumer2 = __esm({
75697
75988
  let progressed = this.parked.length > 0;
75698
75989
  while (progressed) {
75699
75990
  progressed = false;
75991
+ this.dropParkedDuplicates();
75700
75992
  for (let i = 0; i < this.parked.length; i++) {
75701
75993
  const entry = this.parked[i];
75702
75994
  const walkIndex = this.eventIndex;
@@ -75715,6 +76007,49 @@ var init_events_consumer2 = __esm({
75715
76007
  }
75716
76008
  }
75717
76009
  }
76010
+ /**
76011
+ * Release anything parked whose class a consumption has since recorded for
76012
+ * the same entity, on the same terms as {@link skipDuplicateEvent}.
76013
+ *
76014
+ * The ordered walk decides a straggler at the event, but only for one of the
76015
+ * two orders the copies can arrive in. When neither copy has a consumer yet,
76016
+ * both park — the walk steps over the first and re-enters immediately, so
76017
+ * the second is offered in the same tick, with no class recorded because
76018
+ * nothing has been *consumed*. The drain then claims the first and the
76019
+ * second is left held by a consumer list that will never grow the callback
76020
+ * it needs, which the workflow function returning reports through
76021
+ * {@link strandedEvent} as a replay divergence.
76022
+ *
76023
+ * Run before each offer pass rather than once, because the consumption that
76024
+ * records the class happens inside the drain itself.
76025
+ *
76026
+ * Not specific to `attr_set`: `wait_completed` reaches the same state, and
76027
+ * {@link ONE_SHOT_EVENT_TYPES} only covers it in the order where the
76028
+ * consumption came first.
76029
+ */
76030
+ dropParkedDuplicates() {
76031
+ for (let i = this.parked.length - 1; i >= 0; i--) {
76032
+ const event = this.parked[i].event;
76033
+ const firstType = this.firstEventTypeOfClass(event);
76034
+ if (firstType === void 0) {
76035
+ continue;
76036
+ }
76037
+ this.parked.splice(i, 1);
76038
+ eventsLogger2.debug("Releasing a parked event that repeats a class already in the log", {
76039
+ eventId: event.eventId,
76040
+ eventType: event.eventType,
76041
+ firstEventType: firstType,
76042
+ correlationId: event.correlationId
76043
+ });
76044
+ try {
76045
+ this.onDuplicateEvent?.(event, firstType);
76046
+ } catch (error95) {
76047
+ eventsLogger2.error("onDuplicateEvent callback threw an error", {
76048
+ error: error95
76049
+ });
76050
+ }
76051
+ }
76052
+ }
75718
76053
  /**
75719
76054
  * Step the ordered walk over an event nobody claimed, holding on to it for a
75720
76055
  * later consumer. Returns false when the event's type makes its position a
@@ -75739,16 +76074,17 @@ var init_events_consumer2 = __esm({
75739
76074
  return true;
75740
76075
  }
75741
76076
  /**
75742
- * The key `event`'s class is tracked under, or `undefined` for the event
75743
- * types that belong to no class (`hook_received`, `hook_conflict`,
75744
- * `attr_set`, `run_created`) and are therefore never skipped.
76077
+ * The key `event`'s class is tracked under, or `undefined` for the events
76078
+ * that belong to no class and are therefore never skipped: the types with no
76079
+ * entry at all (`hook_received`, `hook_conflict`, `run_created`), and a
76080
+ * classed type carrying no entity to track it under.
75745
76081
  *
75746
- * Run events carry no correlation id. They are classes of the run itself, so
75747
- * they all key off the same bucket.
76082
+ * {@link classifyEntityEvent} owns that rule, because the observability UI
76083
+ * decides the same question about the same log and the two must not drift.
75748
76084
  */
75749
76085
  eventClassKey(event) {
75750
- const eventClass = entityEventClass(event.eventType);
75751
- return eventClass === void 0 ? void 0 : `${eventClass}:${event.correlationId}`;
76086
+ const classification = classifyEntityEvent(event);
76087
+ return classification === void 0 ? void 0 : `${classification.eventClass}:${classification.entity}`;
75752
76088
  }
75753
76089
  /**
75754
76090
  * Remembers that `event`'s class is now decided for its entity, if the type
@@ -75893,7 +76229,8 @@ var init_events_consumer2 = __esm({
75893
76229
  * recorded while the check was in flight can only have been recorded by a
75894
76230
  * consumption inside {@link consume}, whose next pass re-offers this event
75895
76231
  * and steps over it there, leaving the identity guard above to drop the
75896
- * in-flight check.
76232
+ * in-flight check. One that parks before any consumption records its class
76233
+ * is released later by {@link dropParkedDuplicates} instead.
75897
76234
  */
75898
76235
  resolveUnconsumedEvent(currentEvent, mayPark) {
75899
76236
  if (mayPark) {
@@ -78188,12 +78525,13 @@ var init_capabilities2 = __esm({
78188
78525
  // consumers that cannot unframe them (silent corruption); too-high merely
78189
78526
  // delays the optimization (safe).
78190
78527
  { capability: "framedByteStreams", minVersion: "5.0.0-beta.15" }
78191
- // NOTE: lazy hook resume ("does the consumer re-ensure `hook_received` from
78192
- // the queue message's `hookInput`?") is intentionally NOT gated here. A
78193
- // version-compare against a predicted release cutoff is a guess; instead the
78194
- // run's creating deployment stamps an explicit `hookResumeInputVersion`
78195
- // marker into its execution context, which the server mirrors onto the hook's
78196
- // resumeContext. `resumeHook()` gates the lazy path on that marker.
78528
+ // NOTE: the hook-resume consumer protocol ("does the consumer re-ensure
78529
+ // `hook_received` from the queue message's `hookInput`?") is intentionally
78530
+ // NOT gated here. A version-compare against a predicted release cutoff is a
78531
+ // guess; instead the run's creating deployment stamps an explicit
78532
+ // `hookResumeInputVersion` marker into its execution context, which the
78533
+ // server mirrors onto the hook's resumeContext. Older producers gate their
78534
+ // lazy path on that marker.
78197
78535
  ];
78198
78536
  BASELINE_FORMATS2 = /* @__PURE__ */ new Set([
78199
78537
  SerializationFormat2.DEVALUE_V1
@@ -78207,7 +78545,7 @@ var version5;
78207
78545
  var init_version4 = __esm({
78208
78546
  "../core/dist/version.js"() {
78209
78547
  "use strict";
78210
- version5 = "5.0.0-beta.46";
78548
+ version5 = "5.0.0-beta.47";
78211
78549
  }
78212
78550
  });
78213
78551
 
@@ -78320,9 +78658,10 @@ function shouldRetryWithoutEventCursor(error95, cursor, alreadyRetried) {
78320
78658
  }
78321
78659
  async function loadWorkflowRunEvents(runId, afterCursor) {
78322
78660
  const incremental = afterCursor !== void 0;
78323
- return trace5(incremental ? "workflow.loadNewEvents" : "workflow.loadEvents", async (span) => {
78661
+ return trace5("workflow.replay.load", async (span) => {
78324
78662
  span?.setAttributes({
78325
- ...WorkflowRunId4(runId)
78663
+ ...WorkflowRunId4(runId),
78664
+ ...WorkflowReplayLoadSource2(incremental ? "events_list_incremental" : "events_list")
78326
78665
  });
78327
78666
  const loadedEvents = [];
78328
78667
  const loadedEventIds = /* @__PURE__ */ new Set();
@@ -78558,14 +78897,15 @@ function getQueueOverhead(message) {
78558
78897
  return;
78559
78898
  }
78560
78899
  }
78900
+ async function resolveRunEncryptionKey(world, runOrId, context2) {
78901
+ const rawKey = typeof runOrId === "string" ? await world.getEncryptionKeyForRun?.(runOrId, context2) : await world.getEncryptionKeyForRun?.(runOrId);
78902
+ return rawKey ? await deriveRunPayloadKeys2(rawKey) : void 0;
78903
+ }
78561
78904
  function memoizeEncryptionKey(world, runOrId) {
78562
78905
  let cached3;
78563
78906
  return () => {
78564
78907
  if (!cached3) {
78565
- cached3 = (async () => {
78566
- const rawKey = typeof runOrId === "string" ? await world.getEncryptionKeyForRun?.(runOrId) : await world.getEncryptionKeyForRun?.(runOrId);
78567
- return rawKey ? await deriveRunPayloadKeys2(rawKey) : void 0;
78568
- })();
78908
+ cached3 = resolveRunEncryptionKey(world, runOrId);
78569
78909
  }
78570
78910
  return cached3;
78571
78911
  };
@@ -78618,6 +78958,7 @@ var init_helpers3 = __esm({
78618
78958
  __name(stepDispatchIdempotencyKey, "stepDispatchIdempotencyKey");
78619
78959
  __name(queueMessage, "queueMessage");
78620
78960
  __name(getQueueOverhead, "getQueueOverhead");
78961
+ __name(resolveRunEncryptionKey, "resolveRunEncryptionKey");
78621
78962
  __name(memoizeEncryptionKey, "memoizeEncryptionKey");
78622
78963
  }
78623
78964
  });
@@ -78659,7 +79000,6 @@ var resume_hook_exports2 = {};
78659
79000
  __export(resume_hook_exports2, {
78660
79001
  getHookByToken: () => getHookByToken3,
78661
79002
  resumeHook: () => resumeHook2,
78662
- resumeHookDurable: () => resumeHookDurable2,
78663
79003
  resumeWebhook: () => resumeWebhook2
78664
79004
  });
78665
79005
  async function computeResumePayloadDigest2(bytes) {
@@ -78671,6 +79011,38 @@ async function computeResumePayloadDigest2(bytes) {
78671
79011
  }
78672
79012
  return hex5;
78673
79013
  }
79014
+ function isRetryableWakeError2(error95, isDeploymentUnavailableError) {
79015
+ if (isDeploymentUnavailableError?.(error95))
79016
+ return false;
79017
+ const status = error95 ?? {};
79018
+ const code3 = status.status ?? status.statusCode;
79019
+ if (typeof code3 === "number") {
79020
+ return code3 >= 500 || code3 === 408 || code3 === 429;
79021
+ }
79022
+ const name = error95?.name;
79023
+ return name !== "BadRequestError" && name !== "UnauthorizedError" && name !== "ForbiddenError";
79024
+ }
79025
+ async function publishHookWakeWithRetry2(publish, isDeploymentUnavailableError) {
79026
+ let lastError;
79027
+ for (let attempt = 0; attempt <= HOOK_WAKE_RETRY_DELAYS_MS2.length; attempt++) {
79028
+ try {
79029
+ await publish();
79030
+ return;
79031
+ } catch (error95) {
79032
+ lastError = error95;
79033
+ if (!isRetryableWakeError2(error95, isDeploymentUnavailableError))
79034
+ break;
79035
+ const delayMs = HOOK_WAKE_RETRY_DELAYS_MS2[attempt];
79036
+ if (delayMs !== void 0) {
79037
+ await new Promise((resolve3) => setTimeout(resolve3, delayMs));
79038
+ }
79039
+ }
79040
+ }
79041
+ if (HookNotFoundError2.is(lastError)) {
79042
+ throw new WorkflowRuntimeError2("The hook resume was committed, but its workflow wake could not be published", { cause: lastError });
79043
+ }
79044
+ throw lastError;
79045
+ }
78674
79046
  function resumeContextFromRun2(run3) {
78675
79047
  const coreVersion = run3.executionContext?.workflowCoreVersion;
78676
79048
  const traceCarrier = run3.executionContext?.traceCarrier;
@@ -78722,12 +79094,9 @@ async function getHookByToken3(token) {
78722
79094
  return hook;
78723
79095
  }
78724
79096
  async function resumeHook2(tokenOrHook, payload, encryptionKeyOverride) {
78725
- return resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, false, Date.now(), false);
78726
- }
78727
- async function resumeHookDurable2(tokenOrHook, payload, encryptionKeyOverride) {
78728
- return resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, false, Date.now(), true);
79097
+ return resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, false, Date.now());
78729
79098
  }
78730
- async function resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, hookFreshlyLookedUp, resumeRequestedAtMs, requireDurableWrite) {
79099
+ async function resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, hookFreshlyLookedUp, resumeRequestedAtMs) {
78731
79100
  return await waitedUntil2(() => {
78732
79101
  return trace5("hook.resume", async (span) => {
78733
79102
  const world = await getWorldLazy2();
@@ -78765,12 +79134,17 @@ async function resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, hook
78765
79134
  }
78766
79135
  const compression = (resumeContext.runSpecVersion ?? 0) >= SPEC_VERSION_SUPPORTS_COMPRESSION2 && capabilities.supportedFormats.has(SerializationFormat2.GZIP);
78767
79136
  const ops = [];
79137
+ const readbackOps = [];
78768
79138
  const v1Compat = isLegacySpecVersion2(hook.specVersion);
78769
- const dehydratedPayload = await dehydrateStepReturnValue2(payload, hook.runId, payloadKey, ops, globalThis, v1Compat, capabilities.framedByteStreams, compression);
78770
- safeWaitUntil2(Promise.all(ops), (err) => {
79139
+ const dehydratedPayload = await dehydrateStepReturnValue2(payload, hook.runId, payloadKey, ops, globalThis, v1Compat, capabilities.framedByteStreams, compression, void 0, readbackOps);
79140
+ await Promise.all(ops.map((op) => op.catch((error95) => {
79141
+ if (error95 !== void 0)
79142
+ throw error95;
79143
+ })));
79144
+ safeWaitUntil2(Promise.all(readbackOps), (err) => {
78771
79145
  if (err === void 0)
78772
79146
  return;
78773
- runtimeLogger2.warn("Background flush of hook payload ops failed", {
79147
+ runtimeLogger2.warn("Background readback of hook payload failed", {
78774
79148
  workflowRunId: hook.runId,
78775
79149
  hookId: hook.hookId,
78776
79150
  error: err instanceof Error ? err.message : String(err)
@@ -78788,74 +79162,57 @@ async function resumeHookImpl2(tokenOrHook, payload, encryptionKeyOverride, hook
78788
79162
  deploymentId: resumeContext.deploymentId,
78789
79163
  specVersion: resumeContext.runSpecVersion ?? SPEC_VERSION_LEGACY2
78790
79164
  };
78791
- const lazyResumeDisabled = process.env.WORKFLOW_DISABLE_LAZY_HOOK_RESUME === "1";
78792
79165
  const backendDedupSupported = (hookResumeCapabilitiesAreFresh ? hook.resumeCapabilities?.hookResumeDedupVersion ?? 0 : 0) >= HOOK_RESUME_DEDUP_VERSION2 || world.capabilities?.hookResumeDedup === true;
78793
- const fallbackReason = requireDurableWrite ? (
78794
- // An internal caller needs the event committed before this
78795
- // resolves (an ordering barrier), which only the eager write
78796
- // provides. Checked first so the span names the real reason
78797
- // rather than whichever gate happens to fail alongside it.
78798
- "durable_required"
78799
- ) : lazyResumeDisabled ? "disabled" : !backendDedupSupported ? "backend_unsupported" : (resumeContext.hookResumeInputVersion ?? 0) < HOOK_RESUME_INPUT_VERSION2 ? "consumer_unsupported" : v1Compat ? "legacy" : (resumeContext.runSpecVersion ?? 0) < SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT2 ? "non_cbor_transport" : !(dehydratedPayload instanceof Uint8Array) ? "non_bytes" : dehydratedPayload.byteLength > MAX_INLINE_RESUME_PAYLOAD_BYTES2 ? "oversized" : null;
78800
- const useLazyResume = fallbackReason === null;
79166
+ const canClaimResume = backendDedupSupported && !v1Compat && dehydratedPayload instanceof Uint8Array;
78801
79167
  span?.setAttributes({
78802
- "workflow.hook.resume_strategy": useLazyResume ? "lazy" : "sequential",
78803
- ...fallbackReason ? { "workflow.hook.resume_fallback_reason": fallbackReason } : {}
79168
+ "workflow.hook.resume_strategy": "sequential"
78804
79169
  });
78805
- if (!useLazyResume) {
78806
- const isHookGoneError = /* @__PURE__ */ __name((err) => HookNotFoundError2.is(err) || EntityConflictError2.is(err) || RunExpiredError2.is(err), "isHookGoneError");
78807
- try {
78808
- await world.events.create(hook.runId, {
78809
- eventType: "hook_received",
78810
- specVersion: SPEC_VERSION_CURRENT2,
78811
- correlationId: hook.hookId,
78812
- eventData: {
78813
- ...v1Compat ? {} : { token: hook.token },
78814
- payload: dehydratedPayload
78815
- }
78816
- }, { v1Compat });
78817
- } catch (err) {
78818
- if (isHookGoneError(err)) {
78819
- throw new HookNotFoundError2(hook.token);
79170
+ const resumeId = canClaimResume ? generateResumeId2() : void 0;
79171
+ const payloadDigest = canClaimResume ? await computeResumePayloadDigest2(dehydratedPayload) : void 0;
79172
+ if (resumeId) {
79173
+ span?.setAttributes({ "workflow.hook.resume_id": resumeId });
79174
+ }
79175
+ const isHookGoneError = /* @__PURE__ */ __name((err) => HookNotFoundError2.is(err) || RunExpiredError2.is(err), "isHookGoneError");
79176
+ try {
79177
+ await world.events.create(hook.runId, {
79178
+ eventType: "hook_received",
79179
+ specVersion: SPEC_VERSION_CURRENT2,
79180
+ correlationId: hook.hookId,
79181
+ eventData: {
79182
+ ...v1Compat ? {} : { token: hook.token },
79183
+ payload: dehydratedPayload
78820
79184
  }
78821
- throw err;
79185
+ }, {
79186
+ v1Compat,
79187
+ ...resumeId && payloadDigest ? { resumeId, resumePayloadDigest: payloadDigest } : {}
79188
+ });
79189
+ } catch (err) {
79190
+ if (isHookGoneError(err)) {
79191
+ throw new HookNotFoundError2(hook.token);
78822
79192
  }
78823
- const queuePublishRequestedAtMs2 = Date.now();
78824
- await world.queue(queueName, {
78825
- runId: hook.runId,
78826
- traceCarrier: resumeContext.traceCarrier ?? void 0,
78827
- hookResumeTiming: {
78828
- resumeRequestedAtMs,
78829
- queuePublishRequestedAtMs: queuePublishRequestedAtMs2,
78830
- strategy: "sequential"
78831
- }
78832
- }, queueOptions);
78833
- return hook;
78834
- }
78835
- const resumeId = generateResumeId2();
78836
- const payloadDigest = await computeResumePayloadDigest2(dehydratedPayload);
78837
- span?.setAttributes({ "workflow.hook.resume_id": resumeId });
79193
+ throw err;
79194
+ }
79195
+ span?.setAttributes(HookResumeCommitted2(true));
78838
79196
  const queuePublishRequestedAtMs = Date.now();
78839
- await world.queue(queueName, {
79197
+ await publishHookWakeWithRetry2(() => world.queue(queueName, {
78840
79198
  runId: hook.runId,
78841
79199
  traceCarrier: resumeContext.traceCarrier ?? void 0,
78842
- hookInput: {
78843
- resumeId,
78844
- hookId: hook.hookId,
78845
- token: hook.token,
78846
- payload: dehydratedPayload,
78847
- payloadDigest,
78848
- // Deployment affinity for the consumer's cheap pre-write
78849
- // check: lets a misrouted delivery re-route before its
78850
- // hoisted hook_received write instead of after.
78851
- deploymentId: resumeContext.deploymentId
78852
- },
78853
79200
  hookResumeTiming: {
78854
79201
  resumeRequestedAtMs,
78855
79202
  queuePublishRequestedAtMs,
78856
- strategy: "lazy"
79203
+ strategy: "sequential"
78857
79204
  }
78858
- }, queueOptions);
79205
+ }, {
79206
+ ...queueOptions,
79207
+ // Dedup retried publishes whose response was lost: a
79208
+ // duplicate wake is harmless for correctness (deterministic
79209
+ // replay) but costs a full replay of the run, and the queue
79210
+ // accepts a repeated idempotency key by delivering only one
79211
+ // of the messages. Claim-less writes have no resumeId and
79212
+ // keep the previous behavior.
79213
+ ...resumeId ? { idempotencyKey: `hook-${resumeId}` } : {}
79214
+ }), world.isDeploymentUnavailableError?.bind(world));
79215
+ span?.setAttributes(HookWakePublished2(true));
78859
79216
  return hook;
78860
79217
  } catch (err) {
78861
79218
  span?.setAttributes({
@@ -78888,7 +79245,7 @@ async function resumeWebhook2(token, request) {
78888
79245
  } else {
78889
79246
  response = new Response(null, { status: 202 });
78890
79247
  }
78891
- await resumeHookImpl2(hook, request, encryptionKey, true, resumeRequestedAtMs, false);
79248
+ await resumeHookImpl2(hook, request, encryptionKey, true, resumeRequestedAtMs);
78892
79249
  if (responseReadable) {
78893
79250
  const reader = responseReadable.getReader();
78894
79251
  const chunk = await reader.read();
@@ -78904,7 +79261,7 @@ async function resumeWebhook2(token, request) {
78904
79261
  }
78905
79262
  return response;
78906
79263
  }
78907
- var generateResumeId2, MAX_INLINE_RESUME_PAYLOAD_BYTES2;
79264
+ var generateResumeId2, HOOK_WAKE_RETRY_DELAYS_MS2;
78908
79265
  var init_resume_hook2 = __esm({
78909
79266
  "../core/dist/runtime/resume-hook.js"() {
78910
79267
  "use strict";
@@ -78924,15 +79281,16 @@ var init_resume_hook2 = __esm({
78924
79281
  init_helpers3();
78925
79282
  init_wait_until2();
78926
79283
  generateResumeId2 = monotonicFactory2();
78927
- MAX_INLINE_RESUME_PAYLOAD_BYTES2 = 128 * 1024;
78928
79284
  __name(computeResumePayloadDigest2, "computeResumePayloadDigest");
79285
+ HOOK_WAKE_RETRY_DELAYS_MS2 = [25, 100];
79286
+ __name(isRetryableWakeError2, "isRetryableWakeError");
79287
+ __name(publishHookWakeWithRetry2, "publishHookWakeWithRetry");
78929
79288
  __name(resumeContextFromRun2, "resumeContextFromRun");
78930
79289
  __name(resolveHookResumeInfo2, "resolveHookResumeInfo");
78931
79290
  __name(resolveHookEncryptionKey2, "resolveHookEncryptionKey");
78932
79291
  __name(getHookByTokenWithKey2, "getHookByTokenWithKey");
78933
79292
  __name(getHookByToken3, "getHookByToken");
78934
79293
  __name(resumeHook2, "resumeHook");
78935
- __name(resumeHookDurable2, "resumeHookDurable");
78936
79294
  __name(resumeHookImpl2, "resumeHookImpl");
78937
79295
  __name(resumeWebhook2, "resumeWebhook");
78938
79296
  }
@@ -79488,7 +79846,7 @@ function attachAbortListenerOnce2(signal, streamName, runId, cryptoKey, ops) {
79488
79846
  })());
79489
79847
  }, { once: true });
79490
79848
  }
79491
- function getExternalReducers2(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier) {
79849
+ function getExternalReducers2(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier, readbackOps = ops) {
79492
79850
  return {
79493
79851
  ...getAllBaseReducers2(global2),
79494
79852
  ReadableStream: /* @__PURE__ */ __name((value) => {
@@ -79510,7 +79868,7 @@ function getExternalReducers2(global2 = globalThis, ops, runId, cryptoKey, frame
79510
79868
  ops.push(value.pipeTo(writable));
79511
79869
  }
79512
79870
  } else {
79513
- ops.push(value.pipeThrough(getSerializeStream2(getExternalReducers2(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier), cryptoKey)).pipeTo(writable));
79871
+ ops.push(value.pipeThrough(getSerializeStream2(getExternalReducers2(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier, readbackOps), cryptoKey)).pipeTo(writable));
79514
79872
  }
79515
79873
  const s = { name };
79516
79874
  if (type)
@@ -79542,7 +79900,7 @@ function getExternalReducers2(global2 = globalThis, ops, runId, cryptoKey, frame
79542
79900
  const streamId = (global2[STABLE_ULID2] || defaultUlid2)();
79543
79901
  const name = `strm_${streamId}`;
79544
79902
  const readable = new WorkflowServerReadableStream2(runId, name);
79545
- ops.push(readable.pipeTo(value));
79903
+ readbackOps.push(readable.pipeTo(value));
79546
79904
  return { name };
79547
79905
  }, "WritableStream"),
79548
79906
  AbortController: /* @__PURE__ */ __name((value) => {
@@ -79645,7 +80003,7 @@ function getWorkflowReducers2(global2 = globalThis) {
79645
80003
  }, "AbortSignal")
79646
80004
  };
79647
80005
  }
79648
- function getStepReducers2(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier) {
80006
+ function getStepReducers2(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier, readbackOps = ops) {
79649
80007
  return {
79650
80008
  ...getAllBaseReducers2(global2),
79651
80009
  ReadableStream: /* @__PURE__ */ __name((value) => {
@@ -79672,7 +80030,7 @@ function getStepReducers2(global2 = globalThis, ops, runId, cryptoKey, framedByt
79672
80030
  ops.push(value.pipeTo(writable));
79673
80031
  }
79674
80032
  } else {
79675
- ops.push(value.pipeThrough(getSerializeStream2(getStepReducers2(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier), cryptoKey)).pipeTo(writable));
80033
+ ops.push(value.pipeThrough(getSerializeStream2(getStepReducers2(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier, readbackOps), cryptoKey)).pipeTo(writable));
79676
80034
  }
79677
80035
  }
79678
80036
  const s = { name };
@@ -79690,7 +80048,7 @@ function getStepReducers2(global2 = globalThis, ops, runId, cryptoKey, framedByt
79690
80048
  if (!name) {
79691
80049
  const streamId = (global2[STABLE_ULID2] || defaultUlid2)();
79692
80050
  name = `strm_${streamId}`;
79693
- ops.push(new WorkflowServerReadableStream2(runId, name).pipeThrough(getDeserializeStream2(getStepRevivers2(global2, ops, runId, cryptoKey), cryptoKey)).pipeTo(value));
80051
+ readbackOps.push(new WorkflowServerReadableStream2(runId, name).pipeThrough(getDeserializeStream2(getStepRevivers2(global2, readbackOps, runId, cryptoKey), cryptoKey)).pipeTo(value));
79694
80052
  }
79695
80053
  const s = { name };
79696
80054
  if (typeof foreignRunId === "string")
@@ -79860,8 +80218,8 @@ function reviveAbortController2(value, ops, runId) {
79860
80218
  if (value.hookToken) {
79861
80219
  const hookResume = (async () => {
79862
80220
  try {
79863
- const { resumeHookDurable: resumeHookDurable3 } = await Promise.resolve().then(() => (init_resume_hook2(), resume_hook_exports2));
79864
- await resumeHookDurable3(value.hookToken, {
80221
+ const { resumeHook: resumeHook3 } = await Promise.resolve().then(() => (init_resume_hook2(), resume_hook_exports2));
80222
+ await resumeHook3(value.hookToken, {
79865
80223
  aborted: true,
79866
80224
  reason
79867
80225
  });
@@ -80393,16 +80751,16 @@ async function hydrateStepArguments2(value, runId, key, ops = [], global2 = glob
80393
80751
  await recordCompression2(compressionStats, "deserialize");
80394
80752
  return result2;
80395
80753
  }
80396
- async function dehydrateStepReturnValue2(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false, compression = false, runReadyBarrier) {
80754
+ async function dehydrateStepReturnValue2(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false, compression = false, runReadyBarrier, readbackOps = ops) {
80397
80755
  if (v1Compat) {
80398
- const str = stringify2(value, getStepReducers2(global2, ops, runId, key, framedByteStreams, runReadyBarrier));
80756
+ const str = stringify2(value, getStepReducers2(global2, ops, runId, key, framedByteStreams, runReadyBarrier, readbackOps));
80399
80757
  return revive2(str);
80400
80758
  }
80401
80759
  try {
80402
80760
  const compressionStats = {};
80403
80761
  const result2 = await serialize3(value, key, {
80404
80762
  global: global2,
80405
- extraReducers: getStreamAndRequestReducers2(getStepReducers2(global2, ops, runId, key, framedByteStreams, runReadyBarrier)),
80763
+ extraReducers: getStreamAndRequestReducers2(getStepReducers2(global2, ops, runId, key, framedByteStreams, runReadyBarrier, readbackOps)),
80406
80764
  compression,
80407
80765
  compressionStats
80408
80766
  });
@@ -94550,6 +94908,7 @@ var BUILTIN_RESPONSE_STEP_NAMES;
94550
94908
  var init_private = __esm2({
94551
94909
  "../core/dist/private.js"() {
94552
94910
  "use strict";
94911
+ init_dist2();
94553
94912
  init_global();
94554
94913
  RegisteredStepsKey = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps");
94555
94914
  globalSymbols = globalThis;
@@ -111939,8 +112298,9 @@ var init_queue = __esm2({
111939
112298
  /** Epoch ms immediately before the queue publish was requested. */
111940
112299
  queuePublishRequestedAtMs: external_exports.number(),
111941
112300
  /**
111942
- * Which `resumeHook()` dispatch path ran: `lazy` or `sequential` (`parallel`
111943
- * from producers predating lazy-only resume).
112301
+ * Which `resumeHook()` dispatch path ran. Current producers always report
112302
+ * `sequential` (durable write, then wake); older producers may report
112303
+ * `lazy` or `parallel`.
111944
112304
  */
111945
112305
  strategy: external_exports.string().optional(),
111946
112306
  /** Epoch ms the final consumer's queue handler was entered. */
@@ -112012,9 +112372,9 @@ var init_queue = __esm2({
112012
112372
  /** Run creation data, only present on the first queue delivery from start() */
112013
112373
  runInput: RunInputSchema.optional(),
112014
112374
  /**
112015
- * Lazy hook resume data, only present when `resumeHook()` takes the parallel
112016
- * fast path. A consumer that understands this field idempotently ensures the
112017
- * `hook_received` event exists (keyed by `resumeId`) before replaying.
112375
+ * Legacy lazy hook resume data. A consumer that understands this field
112376
+ * idempotently ensures the `hook_received` event exists (keyed by `resumeId`)
112377
+ * before replaying.
112018
112378
  */
112019
112379
  hookInput: HookResumeInputSchema.optional(),
112020
112380
  /**
@@ -112026,7 +112386,7 @@ var init_queue = __esm2({
112026
112386
  stepInput: StepDispatchInputSchema.optional(),
112027
112387
  /**
112028
112388
  * Hook-resume TTR timing. Present on both `resumeHook()` dispatch paths
112029
- * (unlike `hookInput`, which only rides the lazy path), and
112389
+ * (unlike legacy `hookInput`), and
112030
112390
  * forwarded onto a dispatched step message when the resuming invocation
112031
112391
  * hands the next durable step to another invocation. Purely observational.
112032
112392
  * See {@link HookResumeTimingSchema}.
@@ -112086,12 +112446,14 @@ var init_hooks = __esm2({
112086
112446
  encryptionPublicKey: external_exports.string().optional(),
112087
112447
  // Feature marker: the version of the lazy-hook-resume consumer protocol the
112088
112448
  // run's creating deployment supports. Present (>= 1) means that deployment's
112089
- // `@workflow/core` re-ensures the `hook_received` event from the queue
112090
- // message's `hookInput` on replay, so `resumeHook()`'s lazy path is safe to
112091
- // use. Because a run is pinned to its creating deployment, this
112092
- // marker is a reliable per-run attestation, unlike inferring support from a
112093
- // version compare against a predicted release cutoff. Absent on runs created
112094
- // before the marker existed (fall back to the sequential path).
112449
+ // `@workflow/core` re-ensures the `hook_received` event from a queue
112450
+ // message's `hookInput` on replay. Current producers no longer send
112451
+ // `hookInput` (the durable write happens before the wake is published), so
112452
+ // they never read this marker; it remains stamped so OLDER producers, which
112453
+ // still gate their lazy path on it, keep working against new runs. Because a
112454
+ // run is pinned to its creating deployment, this marker is a reliable
112455
+ // per-run attestation, unlike inferring support from a version compare
112456
+ // against a predicted release cutoff.
112095
112457
  hookResumeInputVersion: external_exports.number().optional()
112096
112458
  });
112097
112459
  HOOK_RESUME_INPUT_VERSION = 1;
@@ -113745,6 +114107,8 @@ var WorkflowRunStatus;
113745
114107
  var WorkflowStartedAt;
113746
114108
  var WorkflowEventsCount;
113747
114109
  var WorkflowExecutionMode;
114110
+ var WorkflowBundleCompileCacheHit;
114111
+ var WorkflowReplayLoadSource;
113748
114112
  var WorkflowParkedEventsCount;
113749
114113
  var WorkflowParkedEventId;
113750
114114
  var WorkflowParkedEventType;
@@ -113809,6 +114173,8 @@ var HookToken;
113809
114173
  var HookId;
113810
114174
  var HookFound;
113811
114175
  var HookResilientResume;
114176
+ var HookResumeCommitted;
114177
+ var HookWakePublished;
113812
114178
  var HookResilientResumeMaterialized;
113813
114179
  var HookResumeSetupSource;
113814
114180
  var StepResilientDispatchRecovered;
@@ -113867,6 +114233,8 @@ var init_semantic_conventions = __esm2({
113867
114233
  WorkflowStartedAt = SemanticConvention("workflow.started_at");
113868
114234
  WorkflowEventsCount = SemanticConvention("workflow.events.count");
113869
114235
  WorkflowExecutionMode = SemanticConvention("workflow.execution.mode");
114236
+ WorkflowBundleCompileCacheHit = SemanticConvention("workflow.bundle.compile.cache_hit");
114237
+ WorkflowReplayLoadSource = SemanticConvention("workflow.replay.load.source");
113870
114238
  WorkflowParkedEventsCount = SemanticConvention("workflow.events.parked.count");
113871
114239
  WorkflowParkedEventId = SemanticConvention("workflow.events.parked.event_id");
113872
114240
  WorkflowParkedEventType = SemanticConvention("workflow.events.parked.event_type");
@@ -113931,6 +114299,8 @@ var init_semantic_conventions = __esm2({
113931
114299
  HookId = SemanticConvention("workflow.hook.id");
113932
114300
  HookFound = SemanticConvention("workflow.hook.found");
113933
114301
  HookResilientResume = SemanticConvention("workflow.hook.resilient_resume");
114302
+ HookResumeCommitted = SemanticConvention("workflow.hook.resume_committed");
114303
+ HookWakePublished = SemanticConvention("workflow.hook.wake_published");
113934
114304
  HookResilientResumeMaterialized = SemanticConvention("workflow.hook.resilient_resume_materialized");
113935
114305
  HookResumeSetupSource = SemanticConvention("workflow.resume_setup_source");
113936
114306
  StepResilientDispatchRecovered = SemanticConvention("workflow.step.resilient_dispatch_recovered");
@@ -116063,6 +116433,17 @@ async function deserializeTraceCarrier(traceCarrier) {
116063
116433
  return otel3.propagation.extract(otel3.context.active(), traceCarrier);
116064
116434
  }
116065
116435
  __name(deserializeTraceCarrier, "deserializeTraceCarrier");
116436
+ function describeThrownValue(value) {
116437
+ try {
116438
+ if (typeof value === "object" && value !== null && "message" in value && typeof value.message === "string") {
116439
+ return value.message;
116440
+ }
116441
+ return String(value);
116442
+ } catch {
116443
+ return "Unknown error";
116444
+ }
116445
+ }
116446
+ __name(describeThrownValue, "describeThrownValue");
116066
116447
  function logOtelDiagnosticOnce(otel3, tracer) {
116067
116448
  const debugEnabled = typeof process !== "undefined" && typeof process.env.DEBUG === "string" && (process.env.DEBUG.includes("workflow:") || process.env.DEBUG === "*");
116068
116449
  if (otelDiagLogged || !debugEnabled) return;
@@ -116118,7 +116499,7 @@ async function trace(spanName, ...args) {
116118
116499
  } else {
116119
116500
  span.setStatus({
116120
116501
  code: otel3.SpanStatusCode.ERROR,
116121
- message: e.message
116502
+ message: describeThrownValue(e)
116122
116503
  });
116123
116504
  }
116124
116505
  throw e;
@@ -116223,6 +116604,7 @@ var init_telemetry = __esm2({
116223
116604
  });
116224
116605
  });
116225
116606
  otelDiagLogged = false;
116607
+ __name2(describeThrownValue, "describeThrownValue");
116226
116608
  __name2(logOtelDiagnosticOnce, "logOtelDiagnosticOnce");
116227
116609
  __name2(trace, "trace");
116228
116610
  __name2(recordElapsedSpan, "recordElapsedSpan");
@@ -118556,7 +118938,7 @@ var version2;
118556
118938
  var init_version = __esm2({
118557
118939
  "../core/dist/version.js"() {
118558
118940
  "use strict";
118559
- version2 = "5.0.0-beta.46";
118941
+ version2 = "5.0.0-beta.47";
118560
118942
  }
118561
118943
  });
118562
118944
  function getWorkflowQueueName(workflowName, namespace) {
@@ -123749,7 +124131,6 @@ var resume_hook_exports = {};
123749
124131
  __export2(resume_hook_exports, {
123750
124132
  getHookByToken: /* @__PURE__ */ __name(() => getHookByToken, "getHookByToken"),
123751
124133
  resumeHook: /* @__PURE__ */ __name(() => resumeHook, "resumeHook"),
123752
- resumeHookDurable: /* @__PURE__ */ __name(() => resumeHookDurable, "resumeHookDurable"),
123753
124134
  resumeWebhook: /* @__PURE__ */ __name(() => resumeWebhook, "resumeWebhook")
123754
124135
  });
123755
124136
  async function computeResumePayloadDigest(bytes) {
@@ -123762,6 +124143,40 @@ async function computeResumePayloadDigest(bytes) {
123762
124143
  return hex32;
123763
124144
  }
123764
124145
  __name(computeResumePayloadDigest, "computeResumePayloadDigest");
124146
+ function isRetryableWakeError(error482, isDeploymentUnavailableError) {
124147
+ if (isDeploymentUnavailableError?.(error482)) return false;
124148
+ const status = error482 ?? {};
124149
+ const code22 = status.status ?? status.statusCode;
124150
+ if (typeof code22 === "number") {
124151
+ return code22 >= 500 || code22 === 408 || code22 === 429;
124152
+ }
124153
+ const name = error482?.name;
124154
+ return name !== "BadRequestError" && name !== "UnauthorizedError" && name !== "ForbiddenError";
124155
+ }
124156
+ __name(isRetryableWakeError, "isRetryableWakeError");
124157
+ async function publishHookWakeWithRetry(publish, isDeploymentUnavailableError) {
124158
+ let lastError;
124159
+ for (let attempt = 0; attempt <= HOOK_WAKE_RETRY_DELAYS_MS.length; attempt++) {
124160
+ try {
124161
+ await publish();
124162
+ return;
124163
+ } catch (error482) {
124164
+ lastError = error482;
124165
+ if (!isRetryableWakeError(error482, isDeploymentUnavailableError)) break;
124166
+ const delayMs = HOOK_WAKE_RETRY_DELAYS_MS[attempt];
124167
+ if (delayMs !== void 0) {
124168
+ await new Promise((resolve3) => setTimeout(resolve3, delayMs));
124169
+ }
124170
+ }
124171
+ }
124172
+ if (HookNotFoundError.is(lastError)) {
124173
+ throw new WorkflowRuntimeError("The hook resume was committed, but its workflow wake could not be published", {
124174
+ cause: lastError
124175
+ });
124176
+ }
124177
+ throw lastError;
124178
+ }
124179
+ __name(publishHookWakeWithRetry, "publishHookWakeWithRetry");
123765
124180
  function resumeContextFromRun(run22) {
123766
124181
  const coreVersion = run22.executionContext?.workflowCoreVersion;
123767
124182
  const traceCarrier = run22.executionContext?.traceCarrier;
@@ -123824,14 +124239,10 @@ async function getHookByToken(token) {
123824
124239
  }
123825
124240
  __name(getHookByToken, "getHookByToken");
123826
124241
  async function resumeHook(tokenOrHook, payload, encryptionKeyOverride) {
123827
- return resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, false, Date.now(), false);
124242
+ return resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, false, Date.now());
123828
124243
  }
123829
124244
  __name(resumeHook, "resumeHook");
123830
- async function resumeHookDurable(tokenOrHook, payload, encryptionKeyOverride) {
123831
- return resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, false, Date.now(), true);
123832
- }
123833
- __name(resumeHookDurable, "resumeHookDurable");
123834
- async function resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, hookFreshlyLookedUp, resumeRequestedAtMs, requireDurableWrite) {
124245
+ async function resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, hookFreshlyLookedUp, resumeRequestedAtMs) {
123835
124246
  return await waitedUntil(() => {
123836
124247
  return trace("hook.resume", async (span) => {
123837
124248
  const world = await getWorldLazy();
@@ -123868,11 +124279,15 @@ async function resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, hookF
123868
124279
  }
123869
124280
  const compression = (resumeContext.runSpecVersion ?? 0) >= SPEC_VERSION_SUPPORTS_COMPRESSION && capabilities.supportedFormats.has(SerializationFormat.GZIP);
123870
124281
  const ops = [];
124282
+ const readbackOps = [];
123871
124283
  const v1Compat = isLegacySpecVersion(hook.specVersion);
123872
- const dehydratedPayload = await dehydrateStepReturnValue(payload, hook.runId, payloadKey, ops, globalThis, v1Compat, capabilities.framedByteStreams, compression);
123873
- safeWaitUntil(Promise.all(ops), (err) => {
124284
+ const dehydratedPayload = await dehydrateStepReturnValue(payload, hook.runId, payloadKey, ops, globalThis, v1Compat, capabilities.framedByteStreams, compression, void 0, readbackOps);
124285
+ await Promise.all(ops.map((op) => op.catch((error482) => {
124286
+ if (error482 !== void 0) throw error482;
124287
+ })));
124288
+ safeWaitUntil(Promise.all(readbackOps), (err) => {
123874
124289
  if (err === void 0) return;
123875
- runtimeLogger.warn("Background flush of hook payload ops failed", {
124290
+ runtimeLogger.warn("Background readback of hook payload failed", {
123876
124291
  workflowRunId: hook.runId,
123877
124292
  hookId: hook.hookId,
123878
124293
  error: err instanceof Error ? err.message : String(err)
@@ -123890,81 +124305,66 @@ async function resumeHookImpl(tokenOrHook, payload, encryptionKeyOverride, hookF
123890
124305
  deploymentId: resumeContext.deploymentId,
123891
124306
  specVersion: resumeContext.runSpecVersion ?? SPEC_VERSION_LEGACY
123892
124307
  };
123893
- const lazyResumeDisabled = process.env.WORKFLOW_DISABLE_LAZY_HOOK_RESUME === "1";
123894
124308
  const backendDedupSupported = (hookResumeCapabilitiesAreFresh ? hook.resumeCapabilities?.hookResumeDedupVersion ?? 0 : 0) >= HOOK_RESUME_DEDUP_VERSION || world.capabilities?.hookResumeDedup === true;
123895
- const fallbackReason = requireDurableWrite ? (
123896
- // resolves (an ordering barrier), which only the eager write
123897
- // provides. Checked first so the span names the real reason
123898
- // rather than whichever gate happens to fail alongside it.
123899
- "durable_required"
123900
- ) : lazyResumeDisabled ? "disabled" : !backendDedupSupported ? "backend_unsupported" : (resumeContext.hookResumeInputVersion ?? 0) < HOOK_RESUME_INPUT_VERSION ? "consumer_unsupported" : v1Compat ? "legacy" : (resumeContext.runSpecVersion ?? 0) < SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT ? "non_cbor_transport" : !(dehydratedPayload instanceof Uint8Array) ? "non_bytes" : dehydratedPayload.byteLength > MAX_INLINE_RESUME_PAYLOAD_BYTES ? "oversized" : null;
123901
- const useLazyResume = fallbackReason === null;
124309
+ const canClaimResume = backendDedupSupported && !v1Compat && dehydratedPayload instanceof Uint8Array;
123902
124310
  span?.setAttributes({
123903
- "workflow.hook.resume_strategy": useLazyResume ? "lazy" : "sequential",
123904
- ...fallbackReason ? {
123905
- "workflow.hook.resume_fallback_reason": fallbackReason
123906
- } : {}
124311
+ "workflow.hook.resume_strategy": "sequential"
123907
124312
  });
123908
- if (!useLazyResume) {
123909
- const isHookGoneError = /* @__PURE__ */ __name2((err) => HookNotFoundError.is(err) || EntityConflictError.is(err) || RunExpiredError.is(err), "isHookGoneError");
123910
- try {
123911
- await world.events.create(hook.runId, {
123912
- eventType: "hook_received",
123913
- specVersion: SPEC_VERSION_CURRENT,
123914
- correlationId: hook.hookId,
123915
- eventData: {
123916
- ...v1Compat ? {} : {
123917
- token: hook.token
123918
- },
123919
- payload: dehydratedPayload
123920
- }
123921
- }, {
123922
- v1Compat
123923
- });
123924
- } catch (err) {
123925
- if (isHookGoneError(err)) {
123926
- throw new HookNotFoundError(hook.token);
124313
+ const resumeId = canClaimResume ? generateResumeId() : void 0;
124314
+ const payloadDigest = canClaimResume ? await computeResumePayloadDigest(dehydratedPayload) : void 0;
124315
+ if (resumeId) {
124316
+ span?.setAttributes({
124317
+ "workflow.hook.resume_id": resumeId
124318
+ });
124319
+ }
124320
+ const isHookGoneError = /* @__PURE__ */ __name2((err) => HookNotFoundError.is(err) || RunExpiredError.is(err), "isHookGoneError");
124321
+ try {
124322
+ await world.events.create(hook.runId, {
124323
+ eventType: "hook_received",
124324
+ specVersion: SPEC_VERSION_CURRENT,
124325
+ correlationId: hook.hookId,
124326
+ eventData: {
124327
+ ...v1Compat ? {} : {
124328
+ token: hook.token
124329
+ },
124330
+ payload: dehydratedPayload
123927
124331
  }
123928
- throw err;
124332
+ }, {
124333
+ v1Compat,
124334
+ ...resumeId && payloadDigest ? {
124335
+ resumeId,
124336
+ resumePayloadDigest: payloadDigest
124337
+ } : {}
124338
+ });
124339
+ } catch (err) {
124340
+ if (isHookGoneError(err)) {
124341
+ throw new HookNotFoundError(hook.token);
123929
124342
  }
123930
- const queuePublishRequestedAtMs2 = Date.now();
123931
- await world.queue(queueName, {
123932
- runId: hook.runId,
123933
- traceCarrier: resumeContext.traceCarrier ?? void 0,
123934
- hookResumeTiming: {
123935
- resumeRequestedAtMs,
123936
- queuePublishRequestedAtMs: queuePublishRequestedAtMs2,
123937
- strategy: "sequential"
123938
- }
123939
- }, queueOptions);
123940
- return hook;
124343
+ throw err;
123941
124344
  }
123942
- const resumeId = generateResumeId();
123943
- const payloadDigest = await computeResumePayloadDigest(dehydratedPayload);
123944
- span?.setAttributes({
123945
- "workflow.hook.resume_id": resumeId
123946
- });
124345
+ span?.setAttributes(HookResumeCommitted(true));
123947
124346
  const queuePublishRequestedAtMs = Date.now();
123948
- await world.queue(queueName, {
124347
+ await publishHookWakeWithRetry(() => world.queue(queueName, {
123949
124348
  runId: hook.runId,
123950
124349
  traceCarrier: resumeContext.traceCarrier ?? void 0,
123951
- hookInput: {
123952
- resumeId,
123953
- hookId: hook.hookId,
123954
- token: hook.token,
123955
- payload: dehydratedPayload,
123956
- payloadDigest,
123957
- // Deployment affinity for the consumer's cheap pre-write
123958
- // check: lets a misrouted delivery re-route before its
123959
- // hoisted hook_received write instead of after.
123960
- deploymentId: resumeContext.deploymentId
123961
- },
123962
124350
  hookResumeTiming: {
123963
124351
  resumeRequestedAtMs,
123964
124352
  queuePublishRequestedAtMs,
123965
- strategy: "lazy"
124353
+ strategy: "sequential"
123966
124354
  }
123967
- }, queueOptions);
124355
+ }, {
124356
+ ...queueOptions,
124357
+ // Dedup retried publishes whose response was lost: a
124358
+ // duplicate wake is harmless for correctness (deterministic
124359
+ // replay) but costs a full replay of the run, and the queue
124360
+ // accepts a repeated idempotency key by delivering only one
124361
+ // of the messages. Claim-less writes have no resumeId and
124362
+ // keep the previous behavior.
124363
+ ...resumeId ? {
124364
+ idempotencyKey: `hook-${resumeId}`
124365
+ } : {}
124366
+ }), world.isDeploymentUnavailableError?.bind(world));
124367
+ span?.setAttributes(HookWakePublished(true));
123968
124368
  return hook;
123969
124369
  } catch (err) {
123970
124370
  span?.setAttributes({
@@ -124002,7 +124402,7 @@ async function resumeWebhook(token, request) {
124002
124402
  status: 202
124003
124403
  });
124004
124404
  }
124005
- await resumeHookImpl(hook, request, encryptionKey, true, resumeRequestedAtMs, false);
124405
+ await resumeHookImpl(hook, request, encryptionKey, true, resumeRequestedAtMs);
124006
124406
  if (responseReadable) {
124007
124407
  const reader = responseReadable.getReader();
124008
124408
  const chunk = await reader.read();
@@ -124020,7 +124420,7 @@ async function resumeWebhook(token, request) {
124020
124420
  }
124021
124421
  __name(resumeWebhook, "resumeWebhook");
124022
124422
  var generateResumeId;
124023
- var MAX_INLINE_RESUME_PAYLOAD_BYTES;
124423
+ var HOOK_WAKE_RETRY_DELAYS_MS;
124024
124424
  var init_resume_hook = __esm2({
124025
124425
  "../core/dist/runtime/resume-hook.js"() {
124026
124426
  "use strict";
@@ -124040,15 +124440,19 @@ var init_resume_hook = __esm2({
124040
124440
  init_helpers();
124041
124441
  init_wait_until();
124042
124442
  generateResumeId = monotonicFactory();
124043
- MAX_INLINE_RESUME_PAYLOAD_BYTES = 128 * 1024;
124044
124443
  __name2(computeResumePayloadDigest, "computeResumePayloadDigest");
124444
+ HOOK_WAKE_RETRY_DELAYS_MS = [
124445
+ 25,
124446
+ 100
124447
+ ];
124448
+ __name2(isRetryableWakeError, "isRetryableWakeError");
124449
+ __name2(publishHookWakeWithRetry, "publishHookWakeWithRetry");
124045
124450
  __name2(resumeContextFromRun, "resumeContextFromRun");
124046
124451
  __name2(resolveHookResumeInfo, "resolveHookResumeInfo");
124047
124452
  __name2(resolveHookEncryptionKey, "resolveHookEncryptionKey");
124048
124453
  __name2(getHookByTokenWithKey, "getHookByTokenWithKey");
124049
124454
  __name2(getHookByToken, "getHookByToken");
124050
124455
  __name2(resumeHook, "resumeHook");
124051
- __name2(resumeHookDurable, "resumeHookDurable");
124052
124456
  __name2(resumeHookImpl, "resumeHookImpl");
124053
124457
  __name2(resumeWebhook, "resumeWebhook");
124054
124458
  }
@@ -124632,7 +125036,7 @@ function attachAbortListenerOnce(signal, streamName, runId, cryptoKey, ops) {
124632
125036
  });
124633
125037
  }
124634
125038
  __name(attachAbortListenerOnce, "attachAbortListenerOnce");
124635
- function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier) {
125039
+ function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier, readbackOps = ops) {
124636
125040
  return {
124637
125041
  ...getAllBaseReducers(global2),
124638
125042
  ReadableStream: /* @__PURE__ */ __name2((value) => {
@@ -124653,7 +125057,7 @@ function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framed
124653
125057
  ops.push(value.pipeTo(writable));
124654
125058
  }
124655
125059
  } else {
124656
- ops.push(value.pipeThrough(getSerializeStream(getExternalReducers(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier), cryptoKey)).pipeTo(writable));
125060
+ ops.push(value.pipeThrough(getSerializeStream(getExternalReducers(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier, readbackOps), cryptoKey)).pipeTo(writable));
124657
125061
  }
124658
125062
  const s = {
124659
125063
  name
@@ -124684,7 +125088,7 @@ function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framed
124684
125088
  const streamId = (global2[STABLE_ULID] || defaultUlid)();
124685
125089
  const name = `strm_${streamId}`;
124686
125090
  const readable = new WorkflowServerReadableStream(runId, name);
124687
- ops.push(readable.pipeTo(value));
125091
+ readbackOps.push(readable.pipeTo(value));
124688
125092
  return {
124689
125093
  name
124690
125094
  };
@@ -124786,7 +125190,7 @@ function getWorkflowReducers(global2 = globalThis) {
124786
125190
  };
124787
125191
  }
124788
125192
  __name(getWorkflowReducers, "getWorkflowReducers");
124789
- function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier) {
125193
+ function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier, readbackOps = ops) {
124790
125194
  return {
124791
125195
  ...getAllBaseReducers(global2),
124792
125196
  ReadableStream: /* @__PURE__ */ __name2((value) => {
@@ -124812,7 +125216,7 @@ function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByte
124812
125216
  ops.push(value.pipeTo(writable));
124813
125217
  }
124814
125218
  } else {
124815
- ops.push(value.pipeThrough(getSerializeStream(getStepReducers(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier), cryptoKey)).pipeTo(writable));
125219
+ ops.push(value.pipeThrough(getSerializeStream(getStepReducers(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier, readbackOps), cryptoKey)).pipeTo(writable));
124816
125220
  }
124817
125221
  }
124818
125222
  const s = {
@@ -124829,7 +125233,7 @@ function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByte
124829
125233
  if (!name) {
124830
125234
  const streamId = (global2[STABLE_ULID] || defaultUlid)();
124831
125235
  name = `strm_${streamId}`;
124832
- ops.push(new WorkflowServerReadableStream(runId, name).pipeThrough(getDeserializeStream(getStepRevivers(global2, ops, runId, cryptoKey), cryptoKey)).pipeTo(value));
125236
+ readbackOps.push(new WorkflowServerReadableStream(runId, name).pipeThrough(getDeserializeStream(getStepRevivers(global2, readbackOps, runId, cryptoKey), cryptoKey)).pipeTo(value));
124833
125237
  }
124834
125238
  const s = {
124835
125239
  name
@@ -124962,8 +125366,8 @@ function reviveAbortController(value, ops, runId) {
124962
125366
  if (value.hookToken) {
124963
125367
  const hookResume = (async () => {
124964
125368
  try {
124965
- const { resumeHookDurable: resumeHookDurable22 } = await Promise.resolve().then(() => (init_resume_hook(), resume_hook_exports));
124966
- await resumeHookDurable22(value.hookToken, {
125369
+ const { resumeHook: resumeHook22 } = await Promise.resolve().then(() => (init_resume_hook(), resume_hook_exports));
125370
+ await resumeHook22(value.hookToken, {
124967
125371
  aborted: true,
124968
125372
  reason
124969
125373
  });
@@ -125281,16 +125685,16 @@ function getStepRevivers(global2 = globalThis, ops, runId, cryptoKey, deployment
125281
125685
  };
125282
125686
  }
125283
125687
  __name(getStepRevivers, "getStepRevivers");
125284
- async function dehydrateWorkflowArguments(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false, compression = false) {
125688
+ async function dehydrateWorkflowArguments(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false, compression = false, readbackOps = ops) {
125285
125689
  if (v1Compat) {
125286
- const str = stringify(value, getExternalReducers(global2, ops, runId, key, framedByteStreams));
125690
+ const str = stringify(value, getExternalReducers(global2, ops, runId, key, framedByteStreams, void 0, readbackOps));
125287
125691
  return revive(str);
125288
125692
  }
125289
125693
  try {
125290
125694
  const compressionStats = {};
125291
125695
  const result2 = await serialize(value, key, {
125292
125696
  global: global2,
125293
- extraReducers: getStreamAndRequestReducers(getExternalReducers(global2, ops, runId, key, framedByteStreams)),
125697
+ extraReducers: getStreamAndRequestReducers(getExternalReducers(global2, ops, runId, key, framedByteStreams, void 0, readbackOps)),
125294
125698
  compression,
125295
125699
  compressionStats
125296
125700
  });
@@ -125364,16 +125768,16 @@ async function hydrateStepArguments(value, runId, key, ops = [], global2 = globa
125364
125768
  return result2;
125365
125769
  }
125366
125770
  __name(hydrateStepArguments, "hydrateStepArguments");
125367
- async function dehydrateStepReturnValue(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false, compression = false, runReadyBarrier) {
125771
+ async function dehydrateStepReturnValue(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false, compression = false, runReadyBarrier, readbackOps = ops) {
125368
125772
  if (v1Compat) {
125369
- const str = stringify(value, getStepReducers(global2, ops, runId, key, framedByteStreams, runReadyBarrier));
125773
+ const str = stringify(value, getStepReducers(global2, ops, runId, key, framedByteStreams, runReadyBarrier, readbackOps));
125370
125774
  return revive(str);
125371
125775
  }
125372
125776
  try {
125373
125777
  const compressionStats = {};
125374
125778
  const result2 = await serialize2(value, key, {
125375
125779
  global: global2,
125376
- extraReducers: getStreamAndRequestReducers(getStepReducers(global2, ops, runId, key, framedByteStreams, runReadyBarrier)),
125780
+ extraReducers: getStreamAndRequestReducers(getStepReducers(global2, ops, runId, key, framedByteStreams, runReadyBarrier, readbackOps)),
125377
125781
  compression,
125378
125782
  compressionStats
125379
125783
  });
@@ -126174,9 +126578,9 @@ async function start(workflow, argsOrOptions, options) {
126174
126578
  },
126175
126579
  // Attest that the *consumer* deployment's runtime re-ensures a
126176
126580
  // `hook_received` event from a queue message's `hookInput` on replay.
126177
- // A resume of this run reads the marker (mirrored onto the hook's
126178
- // resumeContext by the server) to decide whether the parallel fast
126179
- // path is safe. For a cross-deployment start the consumer is the
126581
+ // An OLDER producer resuming this run reads the marker (mirrored onto
126582
+ // the hook's resumeContext by the server) to decide whether its lazy
126583
+ // fast path is safe. For a cross-deployment start the consumer is the
126180
126584
  // target deployment, so we stamp the *target's* value carried back on
126181
126585
  // the health-check probe, never the caller's. Omitted when we could
126182
126586
  // not attest the target (older target, timeout, or no probe channel),
@@ -126288,7 +126692,7 @@ __name2(start, "start");
126288
126692
  value: "start",
126289
126693
  configurable: true
126290
126694
  });
126291
- })(start, "step//@workflow/core/runtime/start@5.0.0-beta.46//start");
126695
+ })(start, "step//@workflow/core/runtime/start@5.0.0-beta.47//start");
126292
126696
  async function wakeUpRun(world, runId, options) {
126293
126697
  try {
126294
126698
  const run22 = await world.runs.get(runId, {
@@ -126691,7 +127095,7 @@ var Run = class _Run {
126691
127095
  value: "wakeUp",
126692
127096
  configurable: true
126693
127097
  });
126694
- })(Run.prototype["wakeUp"], "step//@workflow/core/runtime/run@5.0.0-beta.46//Run#wakeUp");
127098
+ })(Run.prototype["wakeUp"], "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#wakeUp");
126695
127099
  (function(__wf_fn, __wf_id) {
126696
127100
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
126697
127101
  __wf_reg.set(__wf_id, __wf_fn);
@@ -126700,7 +127104,7 @@ var Run = class _Run {
126700
127104
  value: "cancel",
126701
127105
  configurable: true
126702
127106
  });
126703
- })(Run.prototype["cancel"], "step//@workflow/core/runtime/run@5.0.0-beta.46//Run#cancel");
127107
+ })(Run.prototype["cancel"], "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#cancel");
126704
127108
  (function(__wf_fn, __wf_id) {
126705
127109
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
126706
127110
  __wf_reg.set(__wf_id, __wf_fn);
@@ -126709,7 +127113,7 @@ var Run = class _Run {
126709
127113
  value: "getReadable",
126710
127114
  configurable: true
126711
127115
  });
126712
- })(Run.prototype["getReadable"], "step//@workflow/core/runtime/run@5.0.0-beta.46//Run#getReadable");
127116
+ })(Run.prototype["getReadable"], "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#getReadable");
126713
127117
  (function(__wf_fn, __wf_id) {
126714
127118
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
126715
127119
  __wf_reg.set(__wf_id, __wf_fn);
@@ -126718,7 +127122,7 @@ var Run = class _Run {
126718
127122
  value: "exists",
126719
127123
  configurable: true
126720
127124
  });
126721
- })(Object.getOwnPropertyDescriptor(Run.prototype, "exists").get, "step//@workflow/core/runtime/run@5.0.0-beta.46//Run#exists");
127125
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "exists").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#exists");
126722
127126
  (function(__wf_fn, __wf_id) {
126723
127127
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
126724
127128
  __wf_reg.set(__wf_id, __wf_fn);
@@ -126727,7 +127131,7 @@ var Run = class _Run {
126727
127131
  value: "status",
126728
127132
  configurable: true
126729
127133
  });
126730
- })(Object.getOwnPropertyDescriptor(Run.prototype, "status").get, "step//@workflow/core/runtime/run@5.0.0-beta.46//Run#status");
127134
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "status").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#status");
126731
127135
  (function(__wf_fn, __wf_id) {
126732
127136
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
126733
127137
  __wf_reg.set(__wf_id, __wf_fn);
@@ -126736,7 +127140,7 @@ var Run = class _Run {
126736
127140
  value: "returnValue",
126737
127141
  configurable: true
126738
127142
  });
126739
- })(Object.getOwnPropertyDescriptor(Run.prototype, "returnValue").get, "step//@workflow/core/runtime/run@5.0.0-beta.46//Run#returnValue");
127143
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "returnValue").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#returnValue");
126740
127144
  (function(__wf_fn, __wf_id) {
126741
127145
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
126742
127146
  __wf_reg.set(__wf_id, __wf_fn);
@@ -126745,7 +127149,7 @@ var Run = class _Run {
126745
127149
  value: "workflowName",
126746
127150
  configurable: true
126747
127151
  });
126748
- })(Object.getOwnPropertyDescriptor(Run.prototype, "workflowName").get, "step//@workflow/core/runtime/run@5.0.0-beta.46//Run#workflowName");
127152
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "workflowName").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#workflowName");
126749
127153
  (function(__wf_fn, __wf_id) {
126750
127154
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
126751
127155
  __wf_reg.set(__wf_id, __wf_fn);
@@ -126754,7 +127158,7 @@ var Run = class _Run {
126754
127158
  value: "createdAt",
126755
127159
  configurable: true
126756
127160
  });
126757
- })(Object.getOwnPropertyDescriptor(Run.prototype, "createdAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.46//Run#createdAt");
127161
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "createdAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#createdAt");
126758
127162
  (function(__wf_fn, __wf_id) {
126759
127163
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
126760
127164
  __wf_reg.set(__wf_id, __wf_fn);
@@ -126763,7 +127167,7 @@ var Run = class _Run {
126763
127167
  value: "startedAt",
126764
127168
  configurable: true
126765
127169
  });
126766
- })(Object.getOwnPropertyDescriptor(Run.prototype, "startedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.46//Run#startedAt");
127170
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "startedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#startedAt");
126767
127171
  (function(__wf_fn, __wf_id) {
126768
127172
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
126769
127173
  __wf_reg.set(__wf_id, __wf_fn);
@@ -126772,7 +127176,7 @@ var Run = class _Run {
126772
127176
  value: "completedAt",
126773
127177
  configurable: true
126774
127178
  });
126775
- })(Object.getOwnPropertyDescriptor(Run.prototype, "completedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.46//Run#completedAt");
127179
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "completedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#completedAt");
126776
127180
  (function(__wf_cls, __wf_id) {
126777
127181
  var __wf_sym = /* @__PURE__ */ Symbol.for("workflow-class-registry"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
126778
127182
  __wf_reg.set(__wf_id, __wf_cls);
@@ -126782,7 +127186,7 @@ var Run = class _Run {
126782
127186
  enumerable: false,
126783
127187
  configurable: false
126784
127188
  });
126785
- })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.46//Run");
127189
+ })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.47//Run");
126786
127190
  async function fetch2(...args) {
126787
127191
  return globalThis.fetch(...args);
126788
127192
  }
@@ -127342,19 +127746,12 @@ import { types as types9 } from "node:util";
127342
127746
 
127343
127747
  // ../core/dist/replay-payload-cache.js
127344
127748
  init_serialization4();
127345
- var MAX_MEMOIZED_PRIMITIVE_LENGTH = 4096;
127346
127749
  function isMemoizablePrimitive(value) {
127347
127750
  if (value === null)
127348
127751
  return true;
127349
127752
  const type = typeof value;
127350
127753
  if (type === "object" || type === "function")
127351
127754
  return false;
127352
- if (type === "string") {
127353
- return value.length <= MAX_MEMOIZED_PRIMITIVE_LENGTH;
127354
- }
127355
- if (type === "bigint") {
127356
- return value.toString().length <= MAX_MEMOIZED_PRIMITIVE_LENGTH;
127357
- }
127358
127755
  return true;
127359
127756
  }
127360
127757
  __name(isMemoizablePrimitive, "isMemoizablePrimitive");
@@ -127362,14 +127759,20 @@ var ReplayPayloadCache = class {
127362
127759
  static {
127363
127760
  __name(this, "ReplayPayloadCache");
127364
127761
  }
127365
- encryptionKey;
127366
127762
  preparer;
127367
127763
  preparedPayloads = /* @__PURE__ */ new Map();
127368
127764
  primitiveStepResults = /* @__PURE__ */ new Map();
127765
+ encryptionKey;
127369
127766
  nextUnscannedEventIndex = 0;
127370
127767
  constructor(encryptionKey, preparer = prepareReplayPayload) {
127371
- this.encryptionKey = encryptionKey;
127372
127768
  this.preparer = preparer;
127769
+ this.encryptionKey = Promise.resolve(encryptionKey);
127770
+ }
127771
+ /** Start preparing an event payload as soon as its frame is decoded. */
127772
+ prepareEvent(event) {
127773
+ const preparation = this.prepareEventIfMissing(event);
127774
+ void preparation?.catch(() => {
127775
+ });
127373
127776
  }
127374
127777
  /**
127375
127778
  * Start every missing binary preparation before workflow execution. Failures
@@ -127378,41 +127781,19 @@ var ReplayPayloadCache = class {
127378
127781
  */
127379
127782
  async prewarm(workflowRun, events) {
127380
127783
  const preparations = [];
127381
- const start3 = /* @__PURE__ */ __name((cacheKey, value) => {
127382
- if (!(value instanceof Uint8Array))
127383
- return;
127384
- if (this.preparedPayloads.has(cacheKey))
127385
- return;
127386
- preparations.push(this.ensurePreparation(cacheKey, value));
127387
- }, "start");
127388
- start3(this.workflowInputKey(workflowRun.runId), workflowRun.input);
127784
+ const workflowInput = this.startPreparation(this.workflowInputKey(workflowRun.runId), workflowRun.input);
127785
+ if (workflowInput)
127786
+ preparations.push(workflowInput);
127389
127787
  for (let index = this.nextUnscannedEventIndex; index < events.length; index++) {
127390
127788
  const event = events[index];
127391
- switch (event.eventType) {
127392
- case "step_completed":
127393
- start3(this.eventPayloadKey(event.eventId, "result"), event.eventData?.result);
127394
- break;
127395
- case "step_failed":
127396
- start3(this.eventPayloadKey(event.eventId, "error"), event.eventData?.error);
127397
- break;
127398
- case "hook_received":
127399
- start3(this.eventPayloadKey(event.eventId, "payload"), event.eventData?.payload);
127400
- break;
127401
- }
127789
+ const preparation = this.prepareEventIfMissing(event);
127790
+ if (preparation)
127791
+ preparations.push(preparation);
127402
127792
  }
127403
127793
  this.nextUnscannedEventIndex = events.length;
127404
127794
  await Promise.allSettled(preparations);
127405
127795
  }
127406
- /**
127407
- * Forget how much of the event log has been scanned, so the next
127408
- * {@link prewarm} walks it from the start again.
127409
- *
127410
- * Required before a replay whose event log was reloaded rather than extended:
127411
- * a corrected log inserts the events the previous load was missing, which
127412
- * shifts every later position, so a positional resume would skip exactly the
127413
- * events the reload was for. Already-prepared payloads are kept: they are
127414
- * keyed by event id, so re-scanning re-observes them for free.
127415
- */
127796
+ /** Rescan the next event log after an authoritative replacement. */
127416
127797
  resetScan() {
127417
127798
  this.nextUnscannedEventIndex = 0;
127418
127799
  }
@@ -127430,8 +127811,8 @@ var ReplayPayloadCache = class {
127430
127811
  }
127431
127812
  /**
127432
127813
  * Reuse final step values only when sharing them across VMs is unobservable.
127433
- * Objects and large strings/bigints always run `hydrate` again, producing a
127434
- * fresh VM-specific value from the separately cached prepared payload.
127814
+ * Objects always run `hydrate` again to produce a fresh VM-specific value;
127815
+ * every primitive is safe to reuse directly.
127435
127816
  */
127436
127817
  async getStepResult(eventId, hydrate) {
127437
127818
  if (this.primitiveStepResults.has(eventId)) {
@@ -127469,7 +127850,39 @@ var ReplayPayloadCache = class {
127469
127850
  }
127470
127851
  /** Normalize synchronous and asynchronous preparers to one promise contract. */
127471
127852
  async runPreparation(value) {
127472
- return this.preparer(value, this.encryptionKey);
127853
+ return this.preparer(value, await this.encryptionKey);
127854
+ }
127855
+ /** Start one event's binary payload unless another path already did. */
127856
+ prepareEventIfMissing(event) {
127857
+ let field;
127858
+ let value;
127859
+ switch (event.eventType) {
127860
+ case "run_created":
127861
+ return this.startPreparation(this.workflowInputKey(event.runId), event.eventData.input);
127862
+ case "run_started":
127863
+ return this.startPreparation(this.workflowInputKey(event.runId), event.eventData?.input);
127864
+ case "step_completed":
127865
+ field = "result";
127866
+ value = event.eventData?.result;
127867
+ break;
127868
+ case "step_failed":
127869
+ field = "error";
127870
+ value = event.eventData?.error;
127871
+ break;
127872
+ case "hook_received":
127873
+ field = "payload";
127874
+ value = event.eventData?.payload;
127875
+ break;
127876
+ default:
127877
+ return void 0;
127878
+ }
127879
+ return this.startPreparation(this.eventPayloadKey(event.eventId, field), value);
127880
+ }
127881
+ startPreparation(cacheKey, value) {
127882
+ if (!(value instanceof Uint8Array) || this.preparedPayloads.has(cacheKey)) {
127883
+ return void 0;
127884
+ }
127885
+ return this.ensurePreparation(cacheKey, value);
127473
127886
  }
127474
127887
  workflowInputKey(runId) {
127475
127888
  return `run:${runId}:input`;
@@ -129304,8 +129717,8 @@ import { Script } from "node:vm";
129304
129717
  var scripts = globalSingleton2("@workflow/core//vmScriptCache", 1, () => ({
129305
129718
  byCode: /* @__PURE__ */ new Map()
129306
129719
  }));
129307
- var MAX_BUNDLES = 8;
129308
- function touchBundle(code3) {
129720
+ var MAX_SCRIPT_SOURCES = 8;
129721
+ function touchScriptSource(code3) {
129309
129722
  const byFilename = scripts.byCode.get(code3);
129310
129723
  if (byFilename === void 0) {
129311
129724
  return void 0;
@@ -129314,13 +129727,13 @@ function touchBundle(code3) {
129314
129727
  scripts.byCode.set(code3, byFilename);
129315
129728
  return byFilename;
129316
129729
  }
129317
- __name(touchBundle, "touchBundle");
129730
+ __name(touchScriptSource, "touchScriptSource");
129318
129731
  function getCachedWorkflowScript(code3, filename) {
129319
- let byFilename = touchBundle(code3);
129732
+ let byFilename = touchScriptSource(code3);
129320
129733
  if (byFilename === void 0) {
129321
129734
  byFilename = /* @__PURE__ */ new Map();
129322
129735
  scripts.byCode.set(code3, byFilename);
129323
- while (scripts.byCode.size > MAX_BUNDLES) {
129736
+ while (scripts.byCode.size > MAX_SCRIPT_SOURCES) {
129324
129737
  const oldest = scripts.byCode.keys().next().value;
129325
129738
  if (oldest === void 0) {
129326
129739
  break;
@@ -129329,17 +129742,14 @@ function getCachedWorkflowScript(code3, filename) {
129329
129742
  }
129330
129743
  }
129331
129744
  let script = byFilename.get(filename);
129745
+ const cacheHit = script !== void 0;
129332
129746
  if (script === void 0) {
129333
129747
  script = new Script(code3, { filename });
129334
129748
  byFilename.set(filename, script);
129335
129749
  }
129336
- return script;
129750
+ return { script, cacheHit };
129337
129751
  }
129338
129752
  __name(getCachedWorkflowScript, "getCachedWorkflowScript");
129339
- function runCachedWorkflowScript(code3, filename, context2) {
129340
- return getCachedWorkflowScript(code3, filename).runInContext(context2);
129341
- }
129342
- __name(runCachedWorkflowScript, "runCachedWorkflowScript");
129343
129753
 
129344
129754
  // ../core/dist/workflow.js
129345
129755
  init_abort_controller2();
@@ -129776,6 +130186,26 @@ async function drainPendingQueueItems(runId, pendingQueue, vmGlobalThis, workflo
129776
130186
  }
129777
130187
  }
129778
130188
  __name(drainPendingQueueItems, "drainPendingQueueItems");
130189
+ function compileWorkflowBundle(workflowCode2, workflowName) {
130190
+ const parsedName = parseWorkflowName2(workflowName);
130191
+ const filename = parsedName?.moduleSpecifier || workflowName;
130192
+ const workflowLookupCode = `globalThis.__private_workflows?.get(${JSON.stringify(workflowName)})`;
130193
+ return trace5("workflow.bundle.compile", async (span) => {
130194
+ const bundle = getCachedWorkflowScript(workflowCode2, filename);
130195
+ const lookup = getCachedWorkflowScript(workflowLookupCode, filename);
130196
+ span?.setAttributes({
130197
+ // This attribute intentionally describes the workflow bundle. The tiny
130198
+ // lookup script may miss when another workflow from the same source file
130199
+ // runs, but that does not mean V8 recompiled the application bundle.
130200
+ ...WorkflowBundleCompileCacheHit2(bundle.cacheHit)
130201
+ });
130202
+ return {
130203
+ bundleScript: bundle.script,
130204
+ workflowLookupScript: lookup.script
130205
+ };
130206
+ });
130207
+ }
130208
+ __name(compileWorkflowBundle, "compileWorkflowBundle");
129779
130209
  function replayWorkflow(options) {
129780
130210
  return traceExecution("replay", options.workflowRun, options.events, async (span) => {
129781
130211
  const { session, execution } = await createWorkflowSession(options);
@@ -129827,7 +130257,15 @@ function recordResult(result2, span) {
129827
130257
  return result2;
129828
130258
  }
129829
130259
  __name(recordResult, "recordResult");
129830
- async function createWorkflowSession({ workflowCode: workflowCode2, workflowRun, events, encryptionKey, replayPayloadCache, runReadyBarrier, worldCapabilities }) {
130260
+ async function createWorkflowSession(options) {
130261
+ const vmTrace = await startTraceSpan("workflow.vm.create_context");
130262
+ return createWorkflowSessionInner(options, vmTrace.end).catch((error95) => {
130263
+ vmTrace.fail(error95);
130264
+ throw error95;
130265
+ });
130266
+ }
130267
+ __name(createWorkflowSession, "createWorkflowSession");
130268
+ async function createWorkflowSessionInner({ workflowCode: workflowCode2, workflowRun, events, encryptionKey, replayPayloadCache, compiledWorkflowScripts, runReadyBarrier, worldCapabilities }, endVmTrace) {
129831
130269
  const startedAt = workflowRun.startedAt;
129832
130270
  if (!startedAt) {
129833
130271
  throw new WorkflowRuntimeError2(`Workflow run "${workflowRun.runId}" has no "startedAt" timestamp (should not happen)`);
@@ -130355,22 +130793,23 @@ Learn more: https://workflow-sdk.dev/err/${ERROR_SLUGS2.FETCH_IN_WORKFLOW_FUNCTI
130355
130793
  vmGlobalThis.console = globalThis.console;
130356
130794
  const SYMBOL_FOR_REQ_CONTEXT = /* @__PURE__ */ Symbol.for("@vercel/request-context");
130357
130795
  vmGlobalThis[SYMBOL_FOR_REQ_CONTEXT] = globalThis[SYMBOL_FOR_REQ_CONTEXT];
130358
- const parsedName = parseWorkflowName2(workflowRun.workflowName);
130359
- const filename = parsedName?.moduleSpecifier || workflowRun.workflowName;
130360
- runCachedWorkflowScript(workflowCode2, filename, context2);
130361
- const workflowFn = runCachedWorkflowScript(`globalThis.__private_workflows?.get(${JSON.stringify(workflowRun.workflowName)})`, filename, context2);
130796
+ endVmTrace();
130797
+ const { bundleScript, workflowLookupScript } = compiledWorkflowScripts ?? await compileWorkflowBundle(workflowCode2, workflowRun.workflowName);
130798
+ const workflowFn = await trace5("workflow.bundle.evaluate", async () => {
130799
+ bundleScript.runInContext(context2);
130800
+ return workflowLookupScript.runInContext(context2);
130801
+ });
130362
130802
  if (typeof workflowFn !== "function") {
130363
130803
  throw new WorkflowNotRegisteredError2(workflowRun.workflowName);
130364
130804
  }
130365
130805
  let args = [];
130366
130806
  workflowContext.promiseQueue = workflowContext.promiseQueue.then(async () => {
130367
- const prepared = await replayPayloadCache.prepareWorkflowInput(workflowRun);
130368
- args = await hydrateWorkflowArguments(workflowRun.input, workflowRun.runId, encryptionKey, vmGlobalThis, {}, prepared);
130807
+ args = await trace5("workflow.input.hydrate", async () => {
130808
+ const prepared = await replayPayloadCache.prepareWorkflowInput(workflowRun);
130809
+ return hydrateWorkflowArguments(workflowRun.input, workflowRun.runId, encryptionKey, vmGlobalThis, {}, prepared);
130810
+ });
130369
130811
  });
130370
130812
  await workflowContext.promiseQueue;
130371
- const workflowBody = (async () => {
130372
- return await workflowFn(...args);
130373
- })();
130374
130813
  const failWorkflow = /* @__PURE__ */ __name(async (error95) => {
130375
130814
  if (WorkflowSuspension2.is(error95) || ReplayDivergenceError.is(error95)) {
130376
130815
  if (state.type === "running")
@@ -130381,10 +130820,10 @@ Learn more: https://workflow-sdk.dev/err/${ERROR_SLUGS2.FETCH_IN_WORKFLOW_FUNCTI
130381
130820
  await drainPendingQueueItems(workflowRun.runId, workflowContext.invocationsQueue, vmGlobalThis, workflowRun, "failed", runReadyBarrier);
130382
130821
  throw error95;
130383
130822
  }, "failWorkflow");
130384
- const waitForExecution = /* @__PURE__ */ __name(async (interruption) => {
130823
+ const waitForExecution = /* @__PURE__ */ __name(async (workflowBody2, interruption) => {
130385
130824
  let result2;
130386
130825
  try {
130387
- result2 = await Promise.race([workflowBody, interruption.promise]);
130826
+ result2 = await Promise.race([workflowBody2, interruption.promise]);
130388
130827
  } catch (error95) {
130389
130828
  if (state.type === "suspended" && error95 === state.suspension) {
130390
130829
  return {
@@ -130421,6 +130860,9 @@ Learn more: https://workflow-sdk.dev/err/${ERROR_SLUGS2.FETCH_IN_WORKFLOW_FUNCTI
130421
130860
  return failWorkflow(error95);
130422
130861
  }
130423
130862
  }, "waitForExecution");
130863
+ const workflowTraceContext = await createRefreshableTraceContext();
130864
+ const replayTrace = await startTraceSpan("workflow.replay.execute");
130865
+ const workflowBody = workflowTraceContext.run(async () => workflowFn(...args));
130424
130866
  const session = {
130425
130867
  workflowRun,
130426
130868
  argumentCount: args.length,
@@ -130436,8 +130878,9 @@ Learn more: https://workflow-sdk.dev/err/${ERROR_SLUGS2.FETCH_IN_WORKFLOW_FUNCTI
130436
130878
  const interruption = withResolvers2();
130437
130879
  state = { type: "running", interruption };
130438
130880
  workflowContext.suspensionGeneration++;
130881
+ workflowTraceContext.refresh();
130439
130882
  eventsConsumer.append(nextEvents.slice(knownEvents.length));
130440
- return waitForExecution(interruption);
130883
+ return waitForExecution(workflowBody, interruption);
130441
130884
  }
130442
130885
  case "replay":
130443
130886
  return { type: "replay" };
@@ -130448,12 +130891,14 @@ Learn more: https://workflow-sdk.dev/err/${ERROR_SLUGS2.FETCH_IN_WORKFLOW_FUNCTI
130448
130891
  state;
130449
130892
  }
130450
130893
  };
130894
+ const execution = waitForExecution(workflowBody, initialInterruption);
130895
+ void execution.then(replayTrace.end, replayTrace.fail);
130451
130896
  return {
130452
130897
  session,
130453
- execution: waitForExecution(initialInterruption)
130898
+ execution
130454
130899
  };
130455
130900
  }
130456
- __name(createWorkflowSession, "createWorkflowSession");
130901
+ __name(createWorkflowSessionInner, "createWorkflowSessionInner");
130457
130902
 
130458
130903
  // ../core/dist/runtime.js
130459
130904
  init_global2();
@@ -130966,8 +131411,12 @@ async function recordFatalRunError({ world, workflowRun, runId, requestId, err,
130966
131411
  }
130967
131412
  }
130968
131413
  __name(recordFatalRunError, "recordFatalRunError");
131414
+ function findRecordedTerminalRunEvent(events, runId) {
131415
+ return events.find((e) => e.runId === runId && (e.eventType === "run_completed" || e.eventType === "run_failed" || e.eventType === "run_cancelled"));
131416
+ }
131417
+ __name(findRecordedTerminalRunEvent, "findRecordedTerminalRunEvent");
130969
131418
  function hasRecordedTerminalRunEvent(events, runId) {
130970
- const terminalRunEvent = events.find((e) => e.runId === runId && (e.eventType === "run_completed" || e.eventType === "run_failed" || e.eventType === "run_cancelled"));
131419
+ const terminalRunEvent = findRecordedTerminalRunEvent(events, runId);
130971
131420
  if (!terminalRunEvent) {
130972
131421
  return false;
130973
131422
  }
@@ -131198,6 +131647,41 @@ function workflowEntrypoint(workflowCode2, options) {
131198
131647
  const noInlineReplayAfterMs = await getMaxInlineDurationMs(world, invocationStartTime);
131199
131648
  let loopIteration = 0;
131200
131649
  const replayRecoveryReporter = replayDivergence ? new ReplayRecoveryReporter(replayDivergence.count) : ReplayRecoveryReporter.inert();
131650
+ let compiledWorkflowScripts;
131651
+ let compiledWorkflowName;
131652
+ const startWorkflowCompile = await bindActiveTraceContext((workflow) => {
131653
+ if (!workflow || useQuickJSVm(workflow))
131654
+ return;
131655
+ if (compiledWorkflowName !== workflow.workflowName) {
131656
+ compiledWorkflowName = workflow.workflowName;
131657
+ compiledWorkflowScripts = compileWorkflowBundle(workflowCode2, workflow.workflowName);
131658
+ void compiledWorkflowScripts.catch(() => {
131659
+ });
131660
+ }
131661
+ return compiledWorkflowScripts;
131662
+ });
131663
+ const encryptionKey = once2(() => {
131664
+ const result2 = resolveRunEncryptionKey(world, runId);
131665
+ void result2.catch(() => {
131666
+ });
131667
+ return result2;
131668
+ });
131669
+ let replayPayloadCache;
131670
+ const startReplayPayloadCache = /* @__PURE__ */ __name((workflow) => {
131671
+ if (!workflow || useQuickJSVm(workflow))
131672
+ return;
131673
+ if (!replayPayloadCache) {
131674
+ replayPayloadCache = new ReplayPayloadCache(encryptionKey.value);
131675
+ }
131676
+ return replayPayloadCache;
131677
+ }, "startReplayPayloadCache");
131678
+ const prepareReplayEvent = /* @__PURE__ */ __name((event) => {
131679
+ if (event.eventType === "run_created") {
131680
+ startReplayPayloadCache(event.eventData);
131681
+ startWorkflowCompile(event.eventData);
131682
+ }
131683
+ replayPayloadCache?.prepareEvent(event);
131684
+ }, "prepareReplayEvent");
131201
131685
  const createEvent = /* @__PURE__ */ __name(async (data, params) => {
131202
131686
  const sinceCursor = deltaRequestCursor(data, params);
131203
131687
  const withSnapshot = { ...slotSnapshot(), ...params };
@@ -131207,6 +131691,23 @@ function workflowEntrypoint(workflowCode2, options) {
131207
131691
  }
131208
131692
  return result2;
131209
131693
  }, "createEvent");
131694
+ const traceReplayLoad = /* @__PURE__ */ __name((source, load) => trace5("workflow.replay.load", async (loadSpan) => {
131695
+ let eventsCount = 0;
131696
+ loadSpan?.setAttributes({
131697
+ ...WorkflowRunId4(runId),
131698
+ ...WorkflowReplayLoadSource2(source)
131699
+ });
131700
+ try {
131701
+ const result2 = await load((event) => {
131702
+ eventsCount++;
131703
+ prepareReplayEvent(event);
131704
+ });
131705
+ eventsCount = result2.events?.length ?? eventsCount;
131706
+ return result2;
131707
+ } finally {
131708
+ loadSpan?.setAttributes(WorkflowEventsCount2(eventsCount));
131709
+ }
131710
+ }), "traceReplayLoad");
131210
131711
  const slotSnapshot = /* @__PURE__ */ __name(() => eventLog.type === "loadAll" ? {} : slotSnapshotParams(eventLog.events), "slotSnapshot");
131211
131712
  const deltaRequestCursor = /* @__PURE__ */ __name((data, params) => {
131212
131713
  if (turbo || eventLog.type !== "ready" || params?.sinceCursor !== void 0 || params?.preloadEvents === true || isTerminalRunEventType(data.eventType)) {
@@ -131242,6 +131743,21 @@ function workflowEntrypoint(workflowCode2, options) {
131242
131743
  }
131243
131744
  }
131244
131745
  }, "awaitRunReady");
131746
+ const recordWorkflowSetupFailure = /* @__PURE__ */ __name(async (err) => {
131747
+ const errorCode = getWorkflowSetupErrorCode(err);
131748
+ if (!errorCode)
131749
+ return false;
131750
+ await recordFatalRunError({
131751
+ world,
131752
+ workflowRun,
131753
+ runId,
131754
+ requestId,
131755
+ err,
131756
+ errorCode,
131757
+ logMessage: "Fatal runtime error during workflow setup"
131758
+ });
131759
+ return true;
131760
+ }, "recordWorkflowSetupFailure");
131245
131761
  const inFlightOwnedSteps = /* @__PURE__ */ new Set();
131246
131762
  const assertNoInFlightOwnedSteps = /* @__PURE__ */ __name((ackPath) => {
131247
131763
  if (inFlightOwnedSteps.size > 0) {
@@ -131307,7 +131823,7 @@ function workflowEntrypoint(workflowCode2, options) {
131307
131823
  eventLog = { ...eventLog, type: "ready" };
131308
131824
  } else {
131309
131825
  eventLog = { type: "loadAll" };
131310
- replayPayloadCache.resetScan();
131826
+ replayPayloadCache?.resetScan();
131311
131827
  }
131312
131828
  runtimeLogger2.warn("Event creation rejected as stale; restarting replay in-process", {
131313
131829
  workflowRunId: runId,
@@ -131518,6 +132034,7 @@ function workflowEntrypoint(workflowCode2, options) {
131518
132034
  return;
131519
132035
  }
131520
132036
  }
132037
+ startWorkflowCompile(bgRun);
131521
132038
  runtimeLogger2.debug("All parallel steps done, replaying inline after background step", { workflowRunId: runId });
131522
132039
  const runCreatedEvent = loaded.events.find((event) => event.eventType === "run_created");
131523
132040
  let replayInput;
@@ -131606,7 +132123,7 @@ function workflowEntrypoint(workflowCode2, options) {
131606
132123
  span?.addEvent("workflow.hook_received.create.start", {
131607
132124
  "workflow.hook_received.preload_events": true
131608
132125
  });
131609
- const result2 = await createEvent({
132126
+ const replayLoad = traceReplayLoad("hook_preload", (replayEventObserver) => createEvent({
131610
132127
  eventType: "hook_received",
131611
132128
  specVersion: SPEC_VERSION_CURRENT2,
131612
132129
  correlationId: hookResumeInput.hookId,
@@ -131619,8 +132136,10 @@ function workflowEntrypoint(workflowCode2, options) {
131619
132136
  occurredAt,
131620
132137
  resumeId: hookResumeInput.resumeId,
131621
132138
  resumePayloadDigest: hookResumeInput.payloadDigest,
131622
- preloadEvents: true
131623
- });
132139
+ preloadEvents: true,
132140
+ replayEventObserver
132141
+ }));
132142
+ const result2 = await replayLoad;
131624
132143
  hookEnsured = true;
131625
132144
  const usableReplayPreload = result2.run !== void 0 && result2.run.startedAt !== void 0 && result2.event !== void 0 && result2.events !== void 0 && result2.events.length > 0 && result2.cursor != null && result2.hasMore === false && typeof result2.maxEvents === "number" && result2.events.some((e) => e.eventType === "run_created") && result2.events.some((e) => e.eventType === "run_started") && result2.events.some((e) => e.eventType === "hook_received" && e.resumeId === hookResumeInput.resumeId);
131626
132145
  if (usableReplayPreload && result2.run?.startedAt && result2.events) {
@@ -131637,6 +132156,7 @@ function workflowEntrypoint(workflowCode2, options) {
131637
132156
  return;
131638
132157
  }
131639
132158
  workflowRun = result2.run;
132159
+ startWorkflowCompile(workflowRun);
131640
132160
  maxEventsLimit = clampMaxEvents(result2.maxEvents);
131641
132161
  runStartedReceivedAtMs = Date.now();
131642
132162
  if (resumeTracking) {
@@ -131661,6 +132181,8 @@ function workflowEntrypoint(workflowCode2, options) {
131661
132181
  runtimeLogger2.info("Run already finished during lazy hook setup, skipping", { workflowRunId: runId, message: err.message });
131662
132182
  return;
131663
132183
  }
132184
+ if (await recordWorkflowSetupFailure(err))
132185
+ return;
131664
132186
  throw err;
131665
132187
  }
131666
132188
  }
@@ -131701,6 +132223,16 @@ function workflowEntrypoint(workflowCode2, options) {
131701
132223
  { requestId, skipPreload: true }
131702
132224
  );
131703
132225
  runReadyBarrier = startedPromise;
132226
+ try {
132227
+ startWorkflowCompile(runInput);
132228
+ startReplayPayloadCache(runInput);
132229
+ } catch (err) {
132230
+ await awaitRunReady();
132231
+ if (!await recordWorkflowSetupFailure(err)) {
132232
+ throw err;
132233
+ }
132234
+ return;
132235
+ }
131704
132236
  void startedPromise.then((r) => {
131705
132237
  const limit = clampMaxEvents(r.maxEvents);
131706
132238
  if (limit !== void 0)
@@ -131749,9 +132281,21 @@ function workflowEntrypoint(workflowCode2, options) {
131749
132281
  span?.addEvent("workflow.run_started.create.start", {
131750
132282
  "workflow.run_started.skip_preload": false
131751
132283
  });
131752
- const result2 = await createEvent(runStartedEvent, {
131753
- requestId
131754
- });
132284
+ const replayLoad = traceReplayLoad("run_started", (replayEventObserver) => createEvent(runStartedEvent, {
132285
+ requestId,
132286
+ replayEventObserver
132287
+ }));
132288
+ try {
132289
+ startWorkflowCompile(runInput);
132290
+ startReplayPayloadCache(runInput);
132291
+ } catch (setupError) {
132292
+ try {
132293
+ await replayLoad;
132294
+ } catch {
132295
+ }
132296
+ throw setupError;
132297
+ }
132298
+ const result2 = await replayLoad;
131755
132299
  workflowRun = result2.run;
131756
132300
  maxEventsLimit = clampMaxEvents(result2.maxEvents);
131757
132301
  runStartedReceivedAtMs = Date.now();
@@ -131777,24 +132321,15 @@ function workflowEntrypoint(workflowCode2, options) {
131777
132321
  });
131778
132322
  return;
131779
132323
  }
132324
+ startWorkflowCompile(workflowRun);
131780
132325
  } catch (err) {
131781
132326
  if (EntityConflictError2.is(err) || RunExpiredError2.is(err)) {
131782
132327
  runtimeLogger2.info("Run already finished during setup, skipping", { workflowRunId: runId, message: err.message });
131783
132328
  return;
131784
132329
  } else {
131785
- const errorCode = getWorkflowSetupErrorCode(err);
131786
- if (!errorCode) {
132330
+ if (!await recordWorkflowSetupFailure(err)) {
131787
132331
  throw err;
131788
132332
  }
131789
- await recordFatalRunError({
131790
- world,
131791
- workflowRun,
131792
- runId,
131793
- requestId,
131794
- err,
131795
- errorCode,
131796
- logMessage: "Fatal runtime error during workflow setup"
131797
- });
131798
132333
  return;
131799
132334
  }
131800
132335
  }
@@ -131856,14 +132391,12 @@ function workflowEntrypoint(workflowCode2, options) {
131856
132391
  }
131857
132392
  if (eventLog.type !== "loadAll" && ensuredEvent) {
131858
132393
  insertEventByEventId(eventLog.events, ensuredEvent);
132394
+ prepareReplayEvent(ensuredEvent);
131859
132395
  } else {
131860
132396
  eventLog = { type: "loadAll" };
131861
132397
  }
131862
132398
  }
131863
132399
  }
131864
- const getEncryptionKey = memoizeEncryptionKey(world, workflowRun);
131865
- const encryptionKey = await getEncryptionKey();
131866
- const replayPayloadCache = new ReplayPayloadCache(encryptionKey);
131867
132400
  let retainedSession = null;
131868
132401
  while (true) {
131869
132402
  loopIteration++;
@@ -131944,7 +132477,10 @@ function workflowEntrypoint(workflowCode2, options) {
131944
132477
  appendEventLog(eventLog, page);
131945
132478
  eventLog = { ...eventLog, type: "ready" };
131946
132479
  } else {
131947
- eventLog = { ...page, type: "ready" };
132480
+ eventLog = {
132481
+ ...page,
132482
+ type: "ready"
132483
+ };
131948
132484
  }
131949
132485
  }
131950
132486
  assert6(eventLog.type === "ready");
@@ -132007,7 +132543,10 @@ function workflowEntrypoint(workflowCode2, options) {
132007
132543
  events: eventLog.events,
132008
132544
  cursor: eventLog.cursor
132009
132545
  });
132010
- eventLog = { ...settled.log, type: "ready" };
132546
+ eventLog = {
132547
+ ...settled.log,
132548
+ type: "ready"
132549
+ };
132011
132550
  if (settled.gap !== void 0) {
132012
132551
  throw new CorruptedEventLogError(`Event log for run ${runId} has a hole at slot ${settled.gap.firstMissingSlot}: ${settled.gap.missingCount} of the ${settled.gap.maxSlot} slots up to the log's maximum hold no event.`);
132013
132552
  }
@@ -132032,17 +132571,22 @@ function workflowEntrypoint(workflowCode2, options) {
132032
132571
  if (resumeTracking) {
132033
132572
  resumeTracking.replayStartedAtMs ??= replayStart;
132034
132573
  }
132035
- const payloadPrewarm = replayPayloadCache.prewarm(workflowRun, eventLog.events);
132574
+ const replayPayloadCache2 = startReplayPayloadCache(workflowRun);
132575
+ assert6(replayPayloadCache2, "Node workflow replay requires payload preparation");
132576
+ const payloadPrewarm = replayPayloadCache2.prewarm(workflowRun, eventLog.events);
132036
132577
  let workflowResult = retainedSession ? await resumeWorkflow(retainedSession, eventLog.events) : { type: "replay" };
132037
132578
  servedByRetainedSession = retainedSession !== null && workflowResult.type !== "replay";
132038
132579
  if (workflowResult.type === "replay") {
132039
132580
  retainedSession = null;
132581
+ const compiled = startWorkflowCompile(workflowRun);
132582
+ assert6(compiled, "Node workflow replay requires compiled scripts");
132040
132583
  workflowResult = await replayWorkflow({
132041
132584
  workflowCode: workflowCode2,
132042
132585
  workflowRun,
132043
132586
  events: eventLog.events,
132044
- encryptionKey,
132045
- replayPayloadCache,
132587
+ encryptionKey: await encryptionKey.value,
132588
+ replayPayloadCache: replayPayloadCache2,
132589
+ compiledWorkflowScripts: await compiled,
132046
132590
  // Turbo: the end-of-run drain inside workflow
132047
132591
  // execution commits fire-and-forget `*_created`
132048
132592
  // events before the terminal `awaitRunReady()` below.
@@ -132166,7 +132710,7 @@ function workflowEntrypoint(workflowCode2, options) {
132166
132710
  eventType: "run_failed",
132167
132711
  specVersion: SPEC_VERSION_CURRENT2,
132168
132712
  eventData: {
132169
- error: await dehydrateRunError(suspensionError, runId, encryptionKey, globalThis, (workflowRun?.specVersion ?? 0) >= SPEC_VERSION_SUPPORTS_COMPRESSION2),
132713
+ error: await dehydrateRunError(suspensionError, runId, await encryptionKey.value, globalThis, (workflowRun?.specVersion ?? 0) >= SPEC_VERSION_SUPPORTS_COMPRESSION2),
132170
132714
  errorCode
132171
132715
  }
132172
132716
  }, { requestId });
@@ -132189,9 +132733,6 @@ function workflowEntrypoint(workflowCode2, options) {
132189
132733
  });
132190
132734
  return;
132191
132735
  }
132192
- if (suspensionResult.reportedEventCount > 0) {
132193
- replayPayloadCache.resetScan();
132194
- }
132195
132736
  const openHookWait = once2(() => {
132196
132737
  assert6(eventLog.type === "ready");
132197
132738
  return openHookAndWaitState(eventLog.events);
@@ -132653,7 +133194,7 @@ function workflowEntrypoint(workflowCode2, options) {
132653
133194
  eventType: "run_failed",
132654
133195
  specVersion: SPEC_VERSION_CURRENT2,
132655
133196
  eventData: {
132656
- error: await dehydrateRunError(terminalError, runId, encryptionKey, globalThis, (workflowRun?.specVersion ?? 0) >= SPEC_VERSION_SUPPORTS_COMPRESSION2),
133197
+ error: await dehydrateRunError(terminalError, runId, await encryptionKey.value, globalThis, (workflowRun?.specVersion ?? 0) >= SPEC_VERSION_SUPPORTS_COMPRESSION2),
132657
133198
  errorCode
132658
133199
  }
132659
133200
  }, {
@@ -133497,10 +134038,10 @@ var Run = class _Run {
133497
134038
  return this.getReadable();
133498
134039
  }
133499
134040
  };
133500
- Run.prototype["wakeUp"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.46//Run#wakeUp");
133501
- Run.prototype["cancel"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.46//Run#cancel");
133502
- Run.prototype["getReadable"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.46//Run#getReadable");
133503
- var __step_Run$exists = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.46//Run#exists");
134041
+ Run.prototype["wakeUp"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#wakeUp");
134042
+ Run.prototype["cancel"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#cancel");
134043
+ Run.prototype["getReadable"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#getReadable");
134044
+ var __step_Run$exists = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#exists");
133504
134045
  Object.defineProperty(Run.prototype, "exists", {
133505
134046
  get() {
133506
134047
  return __step_Run$exists.call(this);
@@ -133508,7 +134049,7 @@ Object.defineProperty(Run.prototype, "exists", {
133508
134049
  configurable: true,
133509
134050
  enumerable: false
133510
134051
  });
133511
- var __step_Run$status = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.46//Run#status");
134052
+ var __step_Run$status = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#status");
133512
134053
  Object.defineProperty(Run.prototype, "status", {
133513
134054
  get() {
133514
134055
  return __step_Run$status.call(this);
@@ -133516,7 +134057,7 @@ Object.defineProperty(Run.prototype, "status", {
133516
134057
  configurable: true,
133517
134058
  enumerable: false
133518
134059
  });
133519
- var __step_Run$returnValue = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.46//Run#returnValue");
134060
+ var __step_Run$returnValue = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#returnValue");
133520
134061
  Object.defineProperty(Run.prototype, "returnValue", {
133521
134062
  get() {
133522
134063
  return __step_Run$returnValue.call(this);
@@ -133524,7 +134065,7 @@ Object.defineProperty(Run.prototype, "returnValue", {
133524
134065
  configurable: true,
133525
134066
  enumerable: false
133526
134067
  });
133527
- var __step_Run$workflowName = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.46//Run#workflowName");
134068
+ var __step_Run$workflowName = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#workflowName");
133528
134069
  Object.defineProperty(Run.prototype, "workflowName", {
133529
134070
  get() {
133530
134071
  return __step_Run$workflowName.call(this);
@@ -133532,7 +134073,7 @@ Object.defineProperty(Run.prototype, "workflowName", {
133532
134073
  configurable: true,
133533
134074
  enumerable: false
133534
134075
  });
133535
- var __step_Run$createdAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.46//Run#createdAt");
134076
+ var __step_Run$createdAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#createdAt");
133536
134077
  Object.defineProperty(Run.prototype, "createdAt", {
133537
134078
  get() {
133538
134079
  return __step_Run$createdAt.call(this);
@@ -133540,7 +134081,7 @@ Object.defineProperty(Run.prototype, "createdAt", {
133540
134081
  configurable: true,
133541
134082
  enumerable: false
133542
134083
  });
133543
- var __step_Run$startedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.46//Run#startedAt");
134084
+ var __step_Run$startedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#startedAt");
133544
134085
  Object.defineProperty(Run.prototype, "startedAt", {
133545
134086
  get() {
133546
134087
  return __step_Run$startedAt.call(this);
@@ -133548,7 +134089,7 @@ Object.defineProperty(Run.prototype, "startedAt", {
133548
134089
  configurable: true,
133549
134090
  enumerable: false
133550
134091
  });
133551
- var __step_Run$completedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.46//Run#completedAt");
134092
+ var __step_Run$completedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#completedAt");
133552
134093
  Object.defineProperty(Run.prototype, "completedAt", {
133553
134094
  get() {
133554
134095
  return __step_Run$completedAt.call(this);
@@ -133565,7 +134106,7 @@ Object.defineProperty(Run.prototype, "completedAt", {
133565
134106
  enumerable: false,
133566
134107
  configurable: false
133567
134108
  });
133568
- })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.46//Run");
134109
+ })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.47//Run");
133569
134110
 
133570
134111
  // ../core/dist/workflow/create-hook.js
133571
134112
  aliasSerializationClass(RUN_CLASS_ID, Run);
@@ -138195,7 +138736,7 @@ globalThis.__private_workflows.set("workflow//./workflows/inline-execution//hook
138195
138736
  var latestNoOpWarning = globalSingleton("@workflow/core//latestNoOpWarning", 1, () => ({
138196
138737
  warned: false
138197
138738
  }));
138198
- var start = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/start@5.0.0-beta.46//start");
138739
+ var start = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/start@5.0.0-beta.47//start");
138199
138740
 
138200
138741
  // workflows/lineage.ts
138201
138742
  var noop = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//./workflows/lineage//noop");