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

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.
@@ -16010,7 +16010,7 @@ var init_runs2 = __esm({
16010
16010
  // Completed state - output can be v1 or v2 format
16011
16011
  WorkflowRunBaseSchema2.extend({
16012
16012
  status: external_exports2.literal("completed"),
16013
- output: SerializedDataSchema2,
16013
+ output: SerializedDataSchema2.optional(),
16014
16014
  error: external_exports2.undefined().optional(),
16015
16015
  completedAt: external_exports2.coerce.date()
16016
16016
  }),
@@ -16018,7 +16018,7 @@ var init_runs2 = __esm({
16018
16018
  WorkflowRunBaseSchema2.extend({
16019
16019
  status: external_exports2.literal("failed"),
16020
16020
  output: external_exports2.undefined().optional(),
16021
- error: SerializedDataSchema2,
16021
+ error: SerializedDataSchema2.optional(),
16022
16022
  completedAt: external_exports2.coerce.date()
16023
16023
  })
16024
16024
  ]);
@@ -16158,7 +16158,7 @@ var init_waits2 = __esm({
16158
16158
  });
16159
16159
 
16160
16160
  // ../world/dist/analytics.js
16161
- var NAIVE_DATETIME2, UTCDateSchema2, NullableDateSchema2, NullableStringSchema2, NullableBooleanSchema2, AnalyticsRunSchema2, AnalyticsStepSchema2, AnalyticsEventSchema2, AnalyticsHookSchema2, AnalyticsWaitSchema2, AnalyticsAttributeKeySchema2, ANALYTICS_EVENTS_GET_MANY_LIMIT;
16161
+ var NAIVE_DATETIME2, UTCDateSchema2, NullableDateSchema2, NullableStringSchema2, NullableBooleanSchema2, AnalyticsRunSchema2, AnalyticsStepSchema2, AnalyticsEventSchema2, AnalyticsHookSchema2, AnalyticsWaitSchema2, AnalyticsAttributeKeySchema2, ANALYTICS_EVENTS_GET_MANY_LIMIT, ANALYTICS_RUN_SCOPED_PAGE_LIMIT, ANALYTICS_PAGE_LIMIT, ANALYTICS_MAX_ATTRIBUTE_FILTERS;
16162
16162
  var init_analytics2 = __esm({
16163
16163
  "../world/dist/analytics.js"() {
16164
16164
  "use strict";
@@ -16261,10 +16261,13 @@ var init_analytics2 = __esm({
16261
16261
  AnalyticsAttributeKeySchema2 = external_exports2.object({
16262
16262
  key: external_exports2.string(),
16263
16263
  runCount: external_exports2.coerce.number(),
16264
- firstSeenAt: external_exports2.coerce.date(),
16265
- lastSeenAt: external_exports2.coerce.date()
16264
+ firstSeenAt: UTCDateSchema2,
16265
+ lastSeenAt: UTCDateSchema2
16266
16266
  });
16267
16267
  ANALYTICS_EVENTS_GET_MANY_LIMIT = 100;
16268
+ ANALYTICS_RUN_SCOPED_PAGE_LIMIT = 1e3;
16269
+ ANALYTICS_PAGE_LIMIT = 100;
16270
+ ANALYTICS_MAX_ATTRIBUTE_FILTERS = 8;
16268
16271
  }
16269
16272
  });
16270
16273
 
@@ -17080,6 +17083,9 @@ var init_ulid2 = __esm({
17080
17083
  var dist_exports = {};
17081
17084
  __export(dist_exports, {
17082
17085
  ANALYTICS_EVENTS_GET_MANY_LIMIT: () => ANALYTICS_EVENTS_GET_MANY_LIMIT,
17086
+ ANALYTICS_MAX_ATTRIBUTE_FILTERS: () => ANALYTICS_MAX_ATTRIBUTE_FILTERS,
17087
+ ANALYTICS_PAGE_LIMIT: () => ANALYTICS_PAGE_LIMIT,
17088
+ ANALYTICS_RUN_SCOPED_PAGE_LIMIT: () => ANALYTICS_RUN_SCOPED_PAGE_LIMIT,
17083
17089
  ATTRIBUTE_KEY_MAX_LENGTH: () => ATTRIBUTE_KEY_MAX_LENGTH2,
17084
17090
  ATTRIBUTE_MAX_PER_RUN: () => ATTRIBUTE_MAX_PER_RUN2,
17085
17091
  ATTRIBUTE_VALUE_MAX_BYTES: () => ATTRIBUTE_VALUE_MAX_BYTES2,
@@ -17244,6 +17250,8 @@ var init_error_codes2 = __esm({
17244
17250
  MAX_EVENTS_EXCEEDED: "MAX_EVENTS_EXCEEDED",
17245
17251
  /** Workflow replay exceeded the maximum allowed duration */
17246
17252
  REPLAY_TIMEOUT: "REPLAY_TIMEOUT",
17253
+ /** Workflow stream infrastructure failed while reading or writing data */
17254
+ STREAM_ERROR: "STREAM_ERROR",
17247
17255
  /** World response violated the SDK contract and cannot be retried safely */
17248
17256
  WORLD_CONTRACT_ERROR: "WORLD_CONTRACT_ERROR",
17249
17257
  /** Run was delivered to a deployment other than the one it is pinned to */
@@ -17279,12 +17287,13 @@ function buildFramedDetails2(hint3, slug) {
17279
17287
  out.push({ label: "docs", value: `${BASE_URL2}/${slug}` });
17280
17288
  return out;
17281
17289
  }
17282
- var BASE_URL2, ERROR_SLUGS2, WorkflowError2, WorkflowWorldError2, WorkflowRunFailedError2, WorkflowRunNotCompletedError2, WorkflowRuntimeError2, CorruptedEventLogError, ReplayDivergenceError, MaxEventsExceededError, RuntimeDecryptionError2, SerializationError2, StepNotRegisteredError2, WorkflowNotRegisteredError2, WorkflowDeploymentMismatchError, WorkflowRunNotFoundError2, HookConflictError2, HookNotFoundError2, EntityConflictError2, RunExpiredError2, StreamExpiredError2, TooEarlyError, ThrottleError2, PreconditionFailedError, WorkflowRunCancelledError2, RunNotSupportedError, FatalError2, RetryableError2, FATAL_ERROR_KEY2, RETRYABLE_ERROR_KEY2, HOOK_CONFLICT_ERROR_KEY2, RUNTIME_DECRYPTION_ERROR_KEY2;
17290
+ var BASE_URL2, ERROR_SLUGS2, WorkflowError2, WorkflowWorldError2, WorkflowRunFailedError2, WorkflowRunNotCompletedError2, WorkflowRuntimeError2, CorruptedEventLogError, ReplayDivergenceError, MaxEventsExceededError, RuntimeDecryptionError2, SerializationError2, StepNotRegisteredError2, WorkflowNotRegisteredError2, WorkflowDeploymentMismatchError, WorkflowRunNotFoundError2, HookConflictError2, HookNotFoundError2, EntityConflictError2, RunExpiredError2, StreamError2, StreamExpiredError2, TooEarlyError, ThrottleError2, PreconditionFailedError, WorkflowRunCancelledError2, RunNotSupportedError, FatalError2, RetryableError2, FATAL_ERROR_KEY2, RETRYABLE_ERROR_KEY2, HOOK_CONFLICT_ERROR_KEY2, RUNTIME_DECRYPTION_ERROR_KEY2, STREAM_ERROR_KEY2;
17283
17291
  var init_dist7 = __esm({
17284
17292
  "../errors/dist/index.js"() {
17285
17293
  "use strict";
17286
17294
  init_dist5();
17287
17295
  init_error_codes2();
17296
+ init_error_codes2();
17288
17297
  BASE_URL2 = "https://workflow-sdk.dev/err";
17289
17298
  __name(isError2, "isError");
17290
17299
  __name(appendFramedDetails2, "appendFramedDetails");
@@ -17334,6 +17343,12 @@ Caused by: ${options.cause.stack}`;
17334
17343
  url;
17335
17344
  /** Retry-After value in seconds, present on 429 and 425 responses */
17336
17345
  retryAfter;
17346
+ /**
17347
+ * The offending argument, present on client-side validation failures
17348
+ * (`code: 'INVALID_ARGUMENT'`). Lets a caller correct the specific
17349
+ * parameter without parsing the message.
17350
+ */
17351
+ field;
17337
17352
  constructor(message, options) {
17338
17353
  super(message, {
17339
17354
  cause: options?.cause
@@ -17343,6 +17358,7 @@ Caused by: ${options.cause.stack}`;
17343
17358
  this.code = options?.code;
17344
17359
  this.url = options?.url;
17345
17360
  this.retryAfter = options?.retryAfter;
17361
+ this.field = options?.field;
17346
17362
  }
17347
17363
  static is(value) {
17348
17364
  return isError2(value) && value.name === "WorkflowWorldError";
@@ -17622,6 +17638,23 @@ Caused by: ${options.cause.stack}`;
17622
17638
  return isError2(value) && value.name === "RunExpiredError";
17623
17639
  }
17624
17640
  };
17641
+ StreamError2 = class extends WorkflowWorldError2 {
17642
+ static {
17643
+ __name(this, "StreamError");
17644
+ }
17645
+ constructor(message, options) {
17646
+ super(message, {
17647
+ code: RUN_ERROR_CODES2.STREAM_ERROR,
17648
+ cause: options?.cause,
17649
+ url: options?.url,
17650
+ status: options?.status
17651
+ });
17652
+ this.name = "StreamError";
17653
+ }
17654
+ static is(value) {
17655
+ return isError2(value) && value.name === "StreamError";
17656
+ }
17657
+ };
17625
17658
  StreamExpiredError2 = class extends WorkflowWorldError2 {
17626
17659
  static {
17627
17660
  __name(this, "StreamExpiredError");
@@ -17752,6 +17785,7 @@ Caused by: ${options.cause.stack}`;
17752
17785
  RETRYABLE_ERROR_KEY2 = /* @__PURE__ */ Symbol.for("@workflow/errors//RetryableError");
17753
17786
  HOOK_CONFLICT_ERROR_KEY2 = /* @__PURE__ */ Symbol.for("@workflow/errors//HookConflictError");
17754
17787
  RUNTIME_DECRYPTION_ERROR_KEY2 = /* @__PURE__ */ Symbol.for("@workflow/errors//RuntimeDecryptionError");
17788
+ STREAM_ERROR_KEY2 = /* @__PURE__ */ Symbol.for("@workflow/errors//StreamError");
17755
17789
  if (typeof globalThis !== "undefined") {
17756
17790
  if (!Object.hasOwn(globalThis, FATAL_ERROR_KEY2)) {
17757
17791
  Object.defineProperty(globalThis, FATAL_ERROR_KEY2, {
@@ -17785,6 +17819,14 @@ Caused by: ${options.cause.stack}`;
17785
17819
  configurable: false
17786
17820
  });
17787
17821
  }
17822
+ if (!Object.hasOwn(globalThis, STREAM_ERROR_KEY2)) {
17823
+ Object.defineProperty(globalThis, STREAM_ERROR_KEY2, {
17824
+ value: StreamError2,
17825
+ writable: false,
17826
+ enumerable: false,
17827
+ configurable: false
17828
+ });
17829
+ }
17788
17830
  }
17789
17831
  }
17790
17832
  });
@@ -51455,12 +51497,24 @@ function createEventsStorage(basedir, tag) {
51455
51497
  };
51456
51498
  const storedConflict = await storeEvent(conflictEvent);
51457
51499
  const resolveData2 = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION;
51458
- return {
51500
+ const conflictDelta = typeof params?.sinceCursor === "string" ? await queryRunEvents(effectiveRunId, {
51501
+ sortOrder: "asc",
51502
+ cursor: params.sinceCursor
51503
+ }) : void 0;
51504
+ const conflictResult = {
51459
51505
  event: stripEventDataRefs(storedConflict, resolveData2),
51460
51506
  run: run3,
51461
51507
  step,
51462
51508
  hook: void 0
51463
51509
  };
51510
+ if (!conflictDelta)
51511
+ return conflictResult;
51512
+ return {
51513
+ ...conflictResult,
51514
+ events: resolveData2 === "none" ? conflictDelta.data.map((delta) => stripEventDataRefs(delta, resolveData2)) : conflictDelta.data,
51515
+ cursor: conflictDelta.cursor,
51516
+ hasMore: conflictDelta.hasMore
51517
+ };
51464
51518
  }
51465
51519
  const persistedHookData = event.eventData;
51466
51520
  hook = {
@@ -56155,7 +56209,7 @@ var version4;
56155
56209
  var init_version3 = __esm({
56156
56210
  "../world-vercel/dist/version.js"() {
56157
56211
  "use strict";
56158
- version4 = "5.0.0-beta.43";
56212
+ version4 = "5.0.0-beta.44";
56159
56213
  }
56160
56214
  });
56161
56215
 
@@ -56576,6 +56630,17 @@ var init_telemetry3 = __esm({
56576
56630
  });
56577
56631
 
56578
56632
  // ../world-vercel/dist/http-core.js
56633
+ function getTransientTransportCode(error95) {
56634
+ let current = error95;
56635
+ for (let depth = 0; current && depth < 8; depth++) {
56636
+ const code3 = current.code;
56637
+ if (typeof code3 === "string" && TRANSIENT_TRANSPORT_ERROR_CODES.has(code3)) {
56638
+ return code3;
56639
+ }
56640
+ current = current.cause;
56641
+ }
56642
+ return void 0;
56643
+ }
56579
56644
  function getVercelDiagnostics(headers) {
56580
56645
  return DIAGNOSTIC_HEADERS.flatMap((header) => {
56581
56646
  const value = headers.get(header);
@@ -56698,7 +56763,7 @@ function recordClientSpanStatus(span, status) {
56698
56763
  }
56699
56764
  }
56700
56765
  async function instrumentedFetch(opts) {
56701
- const { method, url: url3, headers, body, dispatcher, peerService, timeoutMs = getRequestTimeoutMs(), signal: callerSignal, injectTraceContext: injectTraceContext2 = true, cacheBust = true, logLabel, buildError, spanName, attributes, durationAttribute, onTransportOutcome } = opts;
56766
+ const { method, url: url3, headers, body, dispatcher, peerService, timeoutMs = getRequestTimeoutMs(), signal: callerSignal, injectTraceContext: injectTraceContext2 = true, cacheBust = true, logLabel, buildError, spanName, attributes, durationAttribute, onTransportOutcome, deferTransportSuccessUntilBody = false, transportErrorCode = "TRANSPORT" } = opts;
56702
56767
  const label = logLabel ?? url3;
56703
56768
  return withHttpClientSpan({ method, url: url3, peerService, spanName, attributes }, async (span) => {
56704
56769
  if (injectTraceContext2)
@@ -56738,15 +56803,36 @@ async function instrumentedFetch(opts) {
56738
56803
  const elapsed = Date.now() - start3;
56739
56804
  onTransportOutcome?.(error95);
56740
56805
  if (error95 instanceof Error && (error95.name === "TimeoutError" || error95.name === "AbortError")) {
56741
- const timeoutError = new WorkflowWorldError2(`${method} ${label} timed out after ${elapsed}ms`, { url: url3, cause: error95 });
56742
- span?.setAttributes({ ...ErrorType2("TIMEOUT") });
56806
+ const message = `${method} ${label} timed out after ${elapsed}ms`;
56807
+ const errorCode = transportErrorCode === "STREAM_ERROR" ? "STREAM_ERROR" : "TIMEOUT";
56808
+ const timeoutError = errorCode === "STREAM_ERROR" ? new StreamError2(message, { url: url3, cause: error95 }) : new WorkflowWorldError2(message, {
56809
+ url: url3,
56810
+ code: errorCode,
56811
+ cause: error95
56812
+ });
56813
+ span?.setAttributes({ ...ErrorType2(errorCode) });
56743
56814
  span?.recordException?.(timeoutError);
56744
56815
  throw timeoutError;
56745
56816
  }
56817
+ const transportCode = getTransientTransportCode(error95);
56818
+ if (transportCode) {
56819
+ const message = `${method} ${label} transport failure after ${elapsed}ms (${transportCode})`;
56820
+ const errorCode = transportErrorCode === "STREAM_ERROR" ? "STREAM_ERROR" : "TRANSPORT";
56821
+ const transportError2 = errorCode === "STREAM_ERROR" ? new StreamError2(message, { url: url3, cause: error95 }) : new WorkflowWorldError2(message, {
56822
+ url: url3,
56823
+ code: errorCode,
56824
+ cause: error95
56825
+ });
56826
+ span?.setAttributes({ ...ErrorType2(errorCode) });
56827
+ span?.recordException?.(transportError2);
56828
+ throw transportError2;
56829
+ }
56746
56830
  throw error95;
56747
56831
  }
56748
56832
  const ms3 = Date.now() - start3;
56749
- onTransportOutcome?.();
56833
+ if (response.ok && !deferTransportSuccessUntilBody) {
56834
+ onTransportOutcome?.(void 0, response);
56835
+ }
56750
56836
  httpLog(method, label, response, ms3);
56751
56837
  recordClientSpanStatus(span, response.status);
56752
56838
  if (durationAttribute)
@@ -56754,11 +56840,37 @@ async function instrumentedFetch(opts) {
56754
56840
  if (!response.ok) {
56755
56841
  logCurlRepro(method, url3, headers);
56756
56842
  if (buildError) {
56757
- const error96 = await buildError(response);
56843
+ let error96;
56844
+ try {
56845
+ error96 = await buildError(response);
56846
+ } catch (cause) {
56847
+ const transportCode = getTransientTransportCode(cause);
56848
+ if (transportCode) {
56849
+ onTransportOutcome?.(cause, response);
56850
+ const message = `${method} ${label} response body transport failure (${transportCode})`;
56851
+ const mappedError = transportErrorCode === "STREAM_ERROR" ? new StreamError2(message, { url: url3, cause }) : new WorkflowWorldError2(message, {
56852
+ url: url3,
56853
+ code: "TRANSPORT",
56854
+ cause
56855
+ });
56856
+ span?.setAttributes({ ...ErrorType2(transportErrorCode) });
56857
+ span?.recordException?.(mappedError);
56858
+ throw mappedError;
56859
+ }
56860
+ onTransportOutcome?.(void 0, response);
56861
+ throw cause;
56862
+ }
56863
+ onTransportOutcome?.(void 0, response);
56758
56864
  span?.recordException?.(error96);
56759
56865
  throw error96;
56760
56866
  }
56761
- const text = await response.text().catch(() => "");
56867
+ let text = "";
56868
+ try {
56869
+ text = await response.text();
56870
+ onTransportOutcome?.(void 0, response);
56871
+ } catch (cause) {
56872
+ onTransportOutcome?.(cause, response);
56873
+ }
56762
56874
  const error95 = errorForResponse(response.status, `${method} ${label} -> HTTP ${response.status}: ${response.statusText}${text ? ` ${text}` : ""}${formatVercelDiagnostics(response.headers)}`, {
56763
56875
  url: url3,
56764
56876
  retryAfter: parseRetryAfter(response.headers.get("Retry-After"))
@@ -56769,7 +56881,7 @@ async function instrumentedFetch(opts) {
56769
56881
  return response;
56770
56882
  });
56771
56883
  }
56772
- var import_oidc, REQUEST_TIMEOUT_MS, getRequestTimeoutMs, HTTP_DEBUG_ENABLED, DIAGNOSTIC_HEADERS;
56884
+ var import_oidc, REQUEST_TIMEOUT_MS, TRANSIENT_TRANSPORT_ERROR_CODES, getRequestTimeoutMs, HTTP_DEBUG_ENABLED, DIAGNOSTIC_HEADERS;
56773
56885
  var init_http_core = __esm({
56774
56886
  "../world-vercel/dist/http-core.js"() {
56775
56887
  "use strict";
@@ -56780,6 +56892,23 @@ var init_http_core = __esm({
56780
56892
  init_http_client();
56781
56893
  init_telemetry3();
56782
56894
  REQUEST_TIMEOUT_MS = 6e4;
56895
+ TRANSIENT_TRANSPORT_ERROR_CODES = /* @__PURE__ */ new Set([
56896
+ "UND_ERR_INFO",
56897
+ "UND_ERR_REQ_RETRY",
56898
+ "UND_ERR_SOCKET",
56899
+ "UND_ERR_CONNECT",
56900
+ "UND_ERR_CONNECT_TIMEOUT",
56901
+ "UND_ERR_HEADERS_TIMEOUT",
56902
+ "UND_ERR_BODY_TIMEOUT",
56903
+ "UND_ERR_CLOSED",
56904
+ "ECONNRESET",
56905
+ "ECONNREFUSED",
56906
+ "ENOTFOUND",
56907
+ "EAI_AGAIN",
56908
+ "EPIPE",
56909
+ "ETIMEDOUT"
56910
+ ]);
56911
+ __name(getTransientTransportCode, "getTransientTransportCode");
56783
56912
  getRequestTimeoutMs = /* @__PURE__ */ __name(() => envNumber2("WORKFLOW_REQUEST_TIMEOUT_MS", REQUEST_TIMEOUT_MS, {
56784
56913
  integer: true,
56785
56914
  min: 1e4,
@@ -56811,19 +56940,6 @@ var init_http_core = __esm({
56811
56940
  // ../world-vercel/dist/utils.js
56812
56941
  import os from "node:os";
56813
56942
  import { inspect } from "node:util";
56814
- function getTransientTransportCode(error95) {
56815
- let current = error95;
56816
- for (let depth = 0; current != null && depth < 5; depth++) {
56817
- if (typeof current === "object" && "code" in current) {
56818
- const code3 = current.code;
56819
- if (typeof code3 === "string" && TRANSIENT_TRANSPORT_ERROR_CODES.has(code3)) {
56820
- return code3;
56821
- }
56822
- }
56823
- current = current?.cause;
56824
- }
56825
- return void 0;
56826
- }
56827
56943
  function deserializeError(obj) {
56828
56944
  return obj;
56829
56945
  }
@@ -57009,7 +57125,7 @@ async function parseResponseBody(response) {
57009
57125
  getDebugContext: /* @__PURE__ */ __name(() => `Content-Type: ${contentType}, ${text.length} bytes, preview: ${createPreview(data)}`, "getDebugContext")
57010
57126
  };
57011
57127
  }
57012
- var import_oidc2, WORKFLOW_SERVER_URL_OVERRIDE, IDEMPOTENT_METHODS, MAX_BODY_PARSE_RETRIES, BODY_PARSE_RETRY_BASE_MS, TRANSIENT_TRANSPORT_ERROR_CODES, getWorkflowServerUrlOverride, TEST_LIMIT_OVERRIDES_HEADER, getTestLimitOverridesHeader, DEFAULT_RESOLVE_DATA_OPTION2, joinUserAgentProducts, getUserAgent, getHttpUrl, resolveClientEnvironment, getHeaders, MAX_PREVIEW_LENGTH;
57128
+ var import_oidc2, WORKFLOW_SERVER_URL_OVERRIDE, IDEMPOTENT_METHODS, MAX_BODY_PARSE_RETRIES, BODY_PARSE_RETRY_BASE_MS, getWorkflowServerUrlOverride, TEST_LIMIT_OVERRIDES_HEADER, getTestLimitOverridesHeader, DEFAULT_RESOLVE_DATA_OPTION2, joinUserAgentProducts, getUserAgent, getHttpUrl, resolveClientEnvironment, getHeaders, MAX_PREVIEW_LENGTH;
57013
57129
  var init_utils4 = __esm({
57014
57130
  "../world-vercel/dist/utils.js"() {
57015
57131
  "use strict";
@@ -57025,22 +57141,6 @@ var init_utils4 = __esm({
57025
57141
  IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
57026
57142
  MAX_BODY_PARSE_RETRIES = 2;
57027
57143
  BODY_PARSE_RETRY_BASE_MS = 100;
57028
- TRANSIENT_TRANSPORT_ERROR_CODES = /* @__PURE__ */ new Set([
57029
- "UND_ERR_REQ_RETRY",
57030
- "UND_ERR_SOCKET",
57031
- "UND_ERR_CONNECT",
57032
- "UND_ERR_CONNECT_TIMEOUT",
57033
- "UND_ERR_HEADERS_TIMEOUT",
57034
- "UND_ERR_BODY_TIMEOUT",
57035
- "UND_ERR_CLOSED",
57036
- "ECONNRESET",
57037
- "ECONNREFUSED",
57038
- "ENOTFOUND",
57039
- "EAI_AGAIN",
57040
- "EPIPE",
57041
- "ETIMEDOUT"
57042
- ]);
57043
- __name(getTransientTransportCode, "getTransientTransportCode");
57044
57144
  getWorkflowServerUrlOverride = /* @__PURE__ */ __name(() => WORKFLOW_SERVER_URL_OVERRIDE || process.env.VERCEL_WORKFLOW_SERVER_URL || "", "getWorkflowServerUrlOverride");
57045
57145
  TEST_LIMIT_OVERRIDES_HEADER = "x-workflow-test-limit-overrides";
57046
57146
  getTestLimitOverridesHeader = /* @__PURE__ */ __name(() => process.env.WORKFLOW_TEST_LIMIT_OVERRIDES?.trim() || "", "getTestLimitOverridesHeader");
@@ -57106,9 +57206,86 @@ var init_utils4 = __esm({
57106
57206
  });
57107
57207
 
57108
57208
  // ../world-vercel/dist/analytics.js
57109
- function appendPagination(params, pagination) {
57110
- if (pagination?.limit)
57209
+ function invalidArgument(method, field, detail) {
57210
+ return new WorkflowWorldError2(`${method}: ${field} ${detail}`, {
57211
+ code: INVALID_ARGUMENT,
57212
+ field
57213
+ });
57214
+ }
57215
+ function assertPageLimit(method, limit, maxLimit) {
57216
+ if (!Number.isInteger(limit) || limit < 1 || limit > maxLimit) {
57217
+ throw invalidArgument(method, "pagination.limit", `must be an integer between 1 and ${maxLimit} (received ${limit})`);
57218
+ }
57219
+ }
57220
+ function assertRunId(method, runId) {
57221
+ if (!RUN_ID_PATTERN.test(runId)) {
57222
+ throw invalidArgument(method, "runId", `must be a workflow run id ('wrun_' followed by a ULID), received ${JSON.stringify(runId)}`);
57223
+ }
57224
+ }
57225
+ function assertCorrelationId(method, correlationId) {
57226
+ if (!CORRELATION_ID_PATTERN.test(correlationId)) {
57227
+ throw invalidArgument(method, "correlationId", `must be a step, hook, wait, or attribute id, received ${JSON.stringify(correlationId)}`);
57228
+ }
57229
+ }
57230
+ function assertEventId(method, eventId) {
57231
+ if (!EVENT_ID_PATTERN.test(eventId)) {
57232
+ throw invalidArgument(method, "eventId", `must be an event id ('evnt_' followed by a ULID), received ${JSON.stringify(eventId)}`);
57233
+ }
57234
+ }
57235
+ function assertStepId(method, stepId) {
57236
+ if (!STEP_ID_PATTERN.test(stepId)) {
57237
+ throw invalidArgument(method, "stepId", `must be a step id ('step_' followed by a ULID), received ${JSON.stringify(stepId)}`);
57238
+ }
57239
+ }
57240
+ function assertHookId(method, hookId) {
57241
+ if (!HOOK_ID_PATTERN.test(hookId)) {
57242
+ throw invalidArgument(method, "hookId", `must be a hook id ('hook_' followed by a ULID), received ${JSON.stringify(hookId)}`);
57243
+ }
57244
+ }
57245
+ function assertWaitId(method, waitId) {
57246
+ if (!WAIT_ID_PATTERN.test(waitId)) {
57247
+ throw invalidArgument(method, "waitId", `must be a wait id ('wait_' followed by a ULID), received ${JSON.stringify(waitId)}`);
57248
+ }
57249
+ }
57250
+ function assertAttributeFilters(method, attributes) {
57251
+ const entries = Object.entries(attributes);
57252
+ if (entries.length > ANALYTICS_MAX_ATTRIBUTE_FILTERS) {
57253
+ throw invalidArgument(method, "attributes", `may filter by at most ${ANALYTICS_MAX_ATTRIBUTE_FILTERS} pairs (received ${entries.length})`);
57254
+ }
57255
+ for (const [key, value] of entries) {
57256
+ if (!AttributeKeySchema2.safeParse(key).success) {
57257
+ throw invalidArgument(method, "attributes", `key must be 1 to ${ATTRIBUTE_KEY_MAX_LENGTH2} characters, received ${key.length} in ${JSON.stringify(key)}`);
57258
+ }
57259
+ if (!AttributeValueSchema2.safeParse(value).success) {
57260
+ throw invalidArgument(method, "attributes", `value for ${JSON.stringify(key)} must be at most ${ATTRIBUTE_VALUE_MAX_BYTES2} UTF-8 bytes (received ${new TextEncoder().encode(value).length})`);
57261
+ }
57262
+ }
57263
+ }
57264
+ function assertDateWindow(method, startTime, endTime) {
57265
+ if (startTime === void 0 && endTime === void 0)
57266
+ return;
57267
+ if (startTime === void 0 || endTime === void 0) {
57268
+ const given = startTime === void 0 ? "endTime" : "startTime";
57269
+ const missing = startTime === void 0 ? "startTime" : "endTime";
57270
+ throw invalidArgument(method, missing, `is required when ${given} is provided; supply both or neither`);
57271
+ }
57272
+ const start3 = new Date(startTime).getTime();
57273
+ const end = new Date(endTime).getTime();
57274
+ if (!Number.isFinite(start3)) {
57275
+ throw invalidArgument(method, "startTime", `must be a parseable datetime, received ${JSON.stringify(startTime)}`);
57276
+ }
57277
+ if (!Number.isFinite(end)) {
57278
+ throw invalidArgument(method, "endTime", `must be a parseable datetime, received ${JSON.stringify(endTime)}`);
57279
+ }
57280
+ if (start3 > end) {
57281
+ throw invalidArgument(method, "startTime", `must be before or equal to endTime (received startTime=${JSON.stringify(startTime)}, endTime=${JSON.stringify(endTime)})`);
57282
+ }
57283
+ }
57284
+ function appendPagination(method, params, pagination, maxLimit) {
57285
+ if (pagination?.limit !== void 0) {
57286
+ assertPageLimit(method, pagination.limit, maxLimit);
57111
57287
  params.set("limit", pagination.limit.toString());
57288
+ }
57112
57289
  if (pagination?.cursor)
57113
57290
  params.set("cursor", pagination.cursor);
57114
57291
  if (pagination?.sortOrder)
@@ -57118,30 +57295,34 @@ function createQueryString(params) {
57118
57295
  const query = params.toString();
57119
57296
  return query ? `?${query}` : "";
57120
57297
  }
57121
- function normalizeEventIds(eventIds) {
57298
+ function normalizeEventIds(method, eventIds) {
57122
57299
  const uniqueEventIds = [...new Set(eventIds)];
57123
57300
  if (uniqueEventIds.length === 0) {
57124
- throw new RangeError("eventIds must contain at least one event ID");
57301
+ throw invalidArgument(method, "eventIds", "must contain at least one id");
57125
57302
  }
57126
57303
  if (uniqueEventIds.length > ANALYTICS_EVENTS_GET_MANY_LIMIT) {
57127
- throw new RangeError(`eventIds must contain at most ${ANALYTICS_EVENTS_GET_MANY_LIMIT} unique event IDs`);
57304
+ throw invalidArgument(method, "eventIds", `must contain at most ${ANALYTICS_EVENTS_GET_MANY_LIMIT} unique ids (received ${uniqueEventIds.length})`);
57128
57305
  }
57306
+ for (const eventId of uniqueEventIds)
57307
+ assertEventId(method, eventId);
57129
57308
  return uniqueEventIds;
57130
57309
  }
57131
- function appendAttributeListParams(searchParams, params) {
57132
- if (params.workflowName) {
57310
+ function appendAttributeListParams(method, searchParams, params) {
57311
+ assertDateWindow(method, params.startTime, params.endTime);
57312
+ if (params.workflowName !== void 0) {
57133
57313
  searchParams.set("workflowName", params.workflowName);
57134
57314
  }
57135
- if (params.startTime && params.endTime) {
57315
+ if (params.startTime !== void 0 && params.endTime !== void 0) {
57136
57316
  searchParams.set("startTime", params.startTime);
57137
57317
  searchParams.set("endTime", params.endTime);
57138
57318
  }
57139
- appendPagination(searchParams, params.pagination);
57319
+ appendPagination(method, searchParams, params.pagination, ANALYTICS_PAGE_LIMIT);
57140
57320
  }
57141
57321
  function createAnalytics(config4) {
57142
57322
  return {
57143
57323
  runs: {
57144
57324
  get(runId) {
57325
+ assertRunId("analytics.runs.get", runId);
57145
57326
  return makeRequest({
57146
57327
  endpoint: `/v2/analytics/runs/${encodeURIComponent(runId)}`,
57147
57328
  config: config4,
@@ -57149,21 +57330,23 @@ function createAnalytics(config4) {
57149
57330
  });
57150
57331
  },
57151
57332
  list(params = {}) {
57333
+ assertDateWindow("analytics.runs.list", params.startTime, params.endTime);
57152
57334
  const searchParams = new URLSearchParams();
57153
- if (params.workflowName) {
57335
+ if (params.workflowName !== void 0) {
57154
57336
  searchParams.set("workflowName", params.workflowName);
57155
57337
  }
57156
57338
  if (params.status) {
57157
57339
  searchParams.set("status", params.status);
57158
57340
  }
57159
- if (params.startTime && params.endTime) {
57341
+ if (params.startTime !== void 0 && params.endTime !== void 0) {
57160
57342
  searchParams.set("startTime", params.startTime);
57161
57343
  searchParams.set("endTime", params.endTime);
57162
57344
  }
57163
57345
  if (params.attributes && Object.keys(params.attributes).length > 0) {
57346
+ assertAttributeFilters("analytics.runs.list", params.attributes);
57164
57347
  searchParams.set("attributes", JSON.stringify(params.attributes));
57165
57348
  }
57166
- appendPagination(searchParams, params.pagination);
57349
+ appendPagination("analytics.runs.list", searchParams, params.pagination, ANALYTICS_PAGE_LIMIT);
57167
57350
  return makeRequest({
57168
57351
  endpoint: `/v2/analytics/runs${createQueryString(searchParams)}`,
57169
57352
  config: config4,
@@ -57174,7 +57357,7 @@ function createAnalytics(config4) {
57174
57357
  attributes: {
57175
57358
  list(params = {}) {
57176
57359
  const searchParams = new URLSearchParams();
57177
- appendAttributeListParams(searchParams, params);
57360
+ appendAttributeListParams("analytics.attributes.list", searchParams, params);
57178
57361
  return makeRequest({
57179
57362
  endpoint: `/v2/analytics/attributes${createQueryString(searchParams)}`,
57180
57363
  config: config4,
@@ -57184,6 +57367,8 @@ function createAnalytics(config4) {
57184
57367
  },
57185
57368
  steps: {
57186
57369
  get(runId, stepId) {
57370
+ assertRunId("analytics.steps.get", runId);
57371
+ assertStepId("analytics.steps.get", stepId);
57187
57372
  return makeRequest({
57188
57373
  endpoint: `/v2/analytics/runs/${encodeURIComponent(runId)}/steps/${encodeURIComponent(stepId)}`,
57189
57374
  config: config4,
@@ -57191,8 +57376,9 @@ function createAnalytics(config4) {
57191
57376
  });
57192
57377
  },
57193
57378
  list(params) {
57379
+ assertRunId("analytics.steps.list", params.runId);
57194
57380
  const searchParams = new URLSearchParams();
57195
- appendPagination(searchParams, params.pagination);
57381
+ appendPagination("analytics.steps.list", searchParams, params.pagination, ANALYTICS_RUN_SCOPED_PAGE_LIMIT);
57196
57382
  return makeRequest({
57197
57383
  endpoint: `/v2/analytics/runs/${encodeURIComponent(params.runId)}/steps${createQueryString(searchParams)}`,
57198
57384
  config: config4,
@@ -57202,6 +57388,8 @@ function createAnalytics(config4) {
57202
57388
  },
57203
57389
  events: {
57204
57390
  get(runId, eventId) {
57391
+ assertRunId("analytics.events.get", runId);
57392
+ assertEventId("analytics.events.get", eventId);
57205
57393
  return makeRequest({
57206
57394
  endpoint: `/v2/analytics/runs/${encodeURIComponent(runId)}/events/${encodeURIComponent(eventId)}`,
57207
57395
  config: config4,
@@ -57209,33 +57397,47 @@ function createAnalytics(config4) {
57209
57397
  });
57210
57398
  },
57211
57399
  getMany(runId, eventIds) {
57400
+ assertRunId("analytics.events.getMany", runId);
57212
57401
  return makeRequest({
57213
57402
  endpoint: `/v2/analytics/runs/${encodeURIComponent(runId)}/events/get-many`,
57214
57403
  options: { method: "POST" },
57215
- data: { eventIds: normalizeEventIds(eventIds) },
57404
+ data: {
57405
+ eventIds: normalizeEventIds("analytics.events.getMany", eventIds)
57406
+ },
57216
57407
  config: config4,
57217
57408
  schema: AnalyticsEventSchema2.array()
57218
57409
  });
57219
57410
  },
57220
57411
  list(params) {
57412
+ assertRunId("analytics.events.list", params.runId);
57221
57413
  const searchParams = new URLSearchParams();
57222
57414
  if (params.eventType) {
57223
57415
  searchParams.set("eventType", params.eventType);
57224
57416
  }
57225
- if (params.correlationId) {
57417
+ if (params.correlationId !== void 0) {
57418
+ assertCorrelationId("analytics.events.list", params.correlationId);
57226
57419
  searchParams.set("correlationId", params.correlationId);
57227
57420
  }
57228
- appendPagination(searchParams, params.pagination);
57421
+ appendPagination("analytics.events.list", searchParams, params.pagination, ANALYTICS_RUN_SCOPED_PAGE_LIMIT);
57229
57422
  return makeRequest({
57230
57423
  endpoint: `/v2/analytics/runs/${encodeURIComponent(params.runId)}/events${createQueryString(searchParams)}`,
57231
57424
  config: config4,
57232
57425
  schema: PaginatedResponseSchema(AnalyticsEventSchema2)
57233
57426
  });
57234
57427
  },
57428
+ /**
57429
+ * @deprecated Use `list({ runId, correlationId })`. Kept as its own
57430
+ * implementation rather than delegating: `list` treats
57431
+ * `correlationId` as optional and skips an empty one, where this
57432
+ * method requires it, so a delegation would turn an empty id into an
57433
+ * unfiltered listing of the run.
57434
+ */
57235
57435
  listByCorrelationId(params) {
57436
+ assertRunId("analytics.events.listByCorrelationId", params.runId);
57437
+ assertCorrelationId("analytics.events.listByCorrelationId", params.correlationId);
57236
57438
  const searchParams = new URLSearchParams();
57237
57439
  searchParams.set("correlationId", params.correlationId);
57238
- appendPagination(searchParams, params.pagination);
57440
+ appendPagination("analytics.events.listByCorrelationId", searchParams, params.pagination, ANALYTICS_RUN_SCOPED_PAGE_LIMIT);
57239
57441
  return makeRequest({
57240
57442
  endpoint: `/v2/analytics/runs/${encodeURIComponent(params.runId)}/events${createQueryString(searchParams)}`,
57241
57443
  config: config4,
@@ -57245,8 +57447,10 @@ function createAnalytics(config4) {
57245
57447
  },
57246
57448
  hooks: {
57247
57449
  get(hookId, params) {
57450
+ assertHookId("analytics.hooks.get", hookId);
57248
57451
  const searchParams = new URLSearchParams();
57249
- if (params?.runId) {
57452
+ if (params?.runId !== void 0) {
57453
+ assertRunId("analytics.hooks.get", params.runId);
57250
57454
  searchParams.set("runId", params.runId);
57251
57455
  }
57252
57456
  return makeRequest({
@@ -57256,9 +57460,10 @@ function createAnalytics(config4) {
57256
57460
  });
57257
57461
  },
57258
57462
  list(params) {
57463
+ assertRunId("analytics.hooks.list", params.runId);
57259
57464
  const searchParams = new URLSearchParams();
57260
57465
  searchParams.set("runId", params.runId);
57261
- appendPagination(searchParams, params.pagination);
57466
+ appendPagination("analytics.hooks.list", searchParams, params.pagination, ANALYTICS_PAGE_LIMIT);
57262
57467
  return makeRequest({
57263
57468
  endpoint: `/v2/analytics/hooks${createQueryString(searchParams)}`,
57264
57469
  config: config4,
@@ -57268,6 +57473,8 @@ function createAnalytics(config4) {
57268
57473
  },
57269
57474
  waits: {
57270
57475
  get(runId, waitId) {
57476
+ assertRunId("analytics.waits.get", runId);
57477
+ assertWaitId("analytics.waits.get", waitId);
57271
57478
  return makeRequest({
57272
57479
  endpoint: `/v2/analytics/runs/${encodeURIComponent(runId)}/waits/${encodeURIComponent(waitId)}`,
57273
57480
  config: config4,
@@ -57275,11 +57482,12 @@ function createAnalytics(config4) {
57275
57482
  });
57276
57483
  },
57277
57484
  list(params) {
57485
+ assertRunId("analytics.waits.list", params.runId);
57278
57486
  const searchParams = new URLSearchParams();
57279
57487
  if (params.status) {
57280
57488
  searchParams.set("status", params.status);
57281
57489
  }
57282
- appendPagination(searchParams, params.pagination);
57490
+ appendPagination("analytics.waits.list", searchParams, params.pagination, ANALYTICS_RUN_SCOPED_PAGE_LIMIT);
57283
57491
  return makeRequest({
57284
57492
  endpoint: `/v2/analytics/runs/${encodeURIComponent(params.runId)}/waits${createQueryString(searchParams)}`,
57285
57493
  config: config4,
@@ -57289,11 +57497,31 @@ function createAnalytics(config4) {
57289
57497
  }
57290
57498
  };
57291
57499
  }
57500
+ var INVALID_ARGUMENT, ULID_BODY, RUN_ID_PATTERN, CORRELATION_ID_PATTERN, EVENT_ID_PATTERN, STEP_ID_PATTERN, HOOK_ID_PATTERN, WAIT_ID_PATTERN;
57292
57501
  var init_analytics3 = __esm({
57293
57502
  "../world-vercel/dist/analytics.js"() {
57294
57503
  "use strict";
57504
+ init_dist7();
57295
57505
  init_dist6();
57296
57506
  init_utils4();
57507
+ INVALID_ARGUMENT = "INVALID_ARGUMENT";
57508
+ __name(invalidArgument, "invalidArgument");
57509
+ ULID_BODY = "[01234567][0123456789ABCDEFGHJKMNPQRSTVWXYZ]{25}";
57510
+ RUN_ID_PATTERN = new RegExp(`^wrun_${ULID_BODY}$`);
57511
+ CORRELATION_ID_PATTERN = new RegExp(`^(?:step|hook|wait|attr)_${ULID_BODY}$`);
57512
+ EVENT_ID_PATTERN = new RegExp(`^evnt_${ULID_BODY}$`);
57513
+ STEP_ID_PATTERN = new RegExp(`^step_${ULID_BODY}$`);
57514
+ HOOK_ID_PATTERN = new RegExp(`^hook_${ULID_BODY}$`);
57515
+ WAIT_ID_PATTERN = new RegExp(`^wait_${ULID_BODY}$`);
57516
+ __name(assertPageLimit, "assertPageLimit");
57517
+ __name(assertRunId, "assertRunId");
57518
+ __name(assertCorrelationId, "assertCorrelationId");
57519
+ __name(assertEventId, "assertEventId");
57520
+ __name(assertStepId, "assertStepId");
57521
+ __name(assertHookId, "assertHookId");
57522
+ __name(assertWaitId, "assertWaitId");
57523
+ __name(assertAttributeFilters, "assertAttributeFilters");
57524
+ __name(assertDateWindow, "assertDateWindow");
57297
57525
  __name(appendPagination, "appendPagination");
57298
57526
  __name(createQueryString, "createQueryString");
57299
57527
  __name(normalizeEventIds, "normalizeEventIds");
@@ -69227,7 +69455,7 @@ var init_steps3 = __esm({
69227
69455
  import assert4 from "node:assert/strict";
69228
69456
  async function fetchV4(url3, init, config4, opName, attributes) {
69229
69457
  const dispatcher = getEventsDispatcher(config4);
69230
- return instrumentedFetch({
69458
+ const response = await instrumentedFetch({
69231
69459
  method: init.method,
69232
69460
  url: url3,
69233
69461
  headers: init.headers,
@@ -69239,11 +69467,44 @@ async function fetchV4(url3, init, config4, opName, attributes) {
69239
69467
  // service indefinitely, so without this every request routed onto it fails
69240
69468
  // until the compute instance is recycled. See noteEventsTransportOutcome.
69241
69469
  onTransportOutcome: /* @__PURE__ */ __name((error95) => noteEventsTransportOutcome(dispatcher, error95), "onTransportOutcome"),
69470
+ deferTransportSuccessUntilBody: true,
69242
69471
  timeoutMs: null,
69472
+ transportErrorCode: "STREAM_ERROR",
69243
69473
  logLabel: opName,
69244
69474
  // Read the body as bytes, not text: a CBOR error body (the fence 412
69245
69475
  // carries event payloads back) does not survive a UTF-8 decode.
69246
- buildError: /* @__PURE__ */ __name(async (response) => errorFromV4Response(response.status, headersToRecord(response.headers), new Uint8Array(await response.arrayBuffer()), opName, url3), "buildError")
69476
+ buildError: /* @__PURE__ */ __name(async (response2) => errorFromV4Response(response2.status, headersToRecord(response2.headers), new Uint8Array(await response2.arrayBuffer()), opName, url3), "buildError")
69477
+ });
69478
+ if (!response.body) {
69479
+ noteEventsTransportOutcome(dispatcher);
69480
+ return response;
69481
+ }
69482
+ const reader = response.body.getReader();
69483
+ const body = new ReadableStream({
69484
+ async pull(controller) {
69485
+ try {
69486
+ const chunk = await reader.read();
69487
+ if (chunk.done) {
69488
+ noteEventsTransportOutcome(dispatcher);
69489
+ controller.close();
69490
+ } else {
69491
+ controller.enqueue(chunk.value);
69492
+ }
69493
+ } catch (cause) {
69494
+ noteEventsTransportOutcome(dispatcher, cause);
69495
+ const transportCode = getTransientTransportCode(cause);
69496
+ controller.error(transportCode ? new StreamError2(`v4 ${opName}: response stream transport failure (${transportCode})`, { cause, url: url3 }) : cause);
69497
+ }
69498
+ },
69499
+ cancel(reason) {
69500
+ noteEventsTransportOutcome(dispatcher);
69501
+ return reader.cancel(reason);
69502
+ }
69503
+ });
69504
+ return new Response(body, {
69505
+ status: response.status,
69506
+ statusText: response.statusText,
69507
+ headers: response.headers
69247
69508
  });
69248
69509
  }
69249
69510
  function eventsV4Url(baseUrl, runId, eventType) {
@@ -69495,6 +69756,8 @@ async function decodeCreateEventResponse(response, eventType) {
69495
69756
  try {
69496
69757
  bodyBytes = new Uint8Array(await response.arrayBuffer());
69497
69758
  } catch (cause) {
69759
+ if (StreamError2.is(cause))
69760
+ throw cause;
69498
69761
  throw new WorkflowWorldError2("v4 createEvent: failed to read response body", { code: "TRANSPORT", cause });
69499
69762
  }
69500
69763
  if (bodyBytes.byteLength === 0) {
@@ -69687,14 +69950,21 @@ async function getEventV4(runId, eventId, remoteRefBehavior, config4) {
69687
69950
  throw new Error(`v4 getEvent: expected ${V4_FRAME_CONTENT_TYPE}, got ${contentType ?? "(none)"}`);
69688
69951
  }
69689
69952
  const chunks = response.body;
69690
- for await (const frame3 of decodeFrames(chunks)) {
69691
- if (frame3.meta._error === 1) {
69692
- throw streamErrorFrameToError(frame3.meta, "getEvent");
69953
+ try {
69954
+ for await (const frame3 of decodeFrames(chunks)) {
69955
+ if (frame3.meta._error === 1) {
69956
+ throw streamErrorFrameToError(frame3.meta, "getEvent");
69957
+ }
69958
+ if (Object.keys(frame3.meta).some((key) => key.startsWith("_"))) {
69959
+ throw new Error("v4 getEvent: unexpected control frame");
69960
+ }
69961
+ return decodeEventFrame(frame3);
69693
69962
  }
69694
- if (Object.keys(frame3.meta).some((key) => key.startsWith("_"))) {
69695
- throw new Error("v4 getEvent: unexpected control frame");
69963
+ } catch (cause) {
69964
+ if (cause instanceof IncompleteFrameError && StreamError2.is(cause.cause)) {
69965
+ throw cause.cause;
69696
69966
  }
69697
- return decodeEventFrame(frame3);
69967
+ throw cause;
69698
69968
  }
69699
69969
  throw new Error(`v4 getEvent: empty frame stream for ${eventId}`);
69700
69970
  }
@@ -69762,6 +70032,9 @@ async function consumeEventFrameStream(response, opName, replayEventObserver) {
69762
70032
  if (cause instanceof ReplayEventObserverError || CorruptedEventLogError.is(cause) || WorkflowWorldError2.is(cause)) {
69763
70033
  throw cause;
69764
70034
  }
70035
+ if (cause instanceof IncompleteFrameError && StreamError2.is(cause.cause)) {
70036
+ return partialEventFrameStream(events, cause.cause);
70037
+ }
69765
70038
  if (!(cause instanceof IncompleteFrameError)) {
69766
70039
  throw new WorkflowWorldError2(`v4 ${opName}: invalid event frame stream`, {
69767
70040
  code: "SCHEMA_VALIDATION",
@@ -70752,21 +71025,28 @@ function streamSpanAttributes(args) {
70752
71025
  }
70753
71026
  async function createStreamReadError(response) {
70754
71027
  const fallback = `Failed to fetch stream: ${response.status}`;
70755
- if (response.status !== 410)
70756
- return new Error(fallback);
71028
+ if (response.status !== 410) {
71029
+ return new StreamError2(fallback, { status: response.status });
71030
+ }
70757
71031
  try {
70758
71032
  const body = await response.json();
70759
71033
  return errorForResponse(response.status, typeof body.message === "string" ? body.message : fallback, { code: body.error, details: body.details });
70760
71034
  } catch {
70761
- return new Error(fallback);
71035
+ return new StreamError2(fallback, { status: response.status });
71036
+ }
71037
+ }
71038
+ function toStreamError(message, cause) {
71039
+ if (WorkflowWorldError2.is(cause) || EntityConflictError2.is(cause) || RunExpiredError2.is(cause) || StreamError2.is(cause) || StreamExpiredError2.is(cause) || TooEarlyError.is(cause) || ThrottleError2.is(cause) || PreconditionFailedError.is(cause)) {
71040
+ return cause;
70762
71041
  }
71042
+ return new StreamError2(message, { cause });
70763
71043
  }
70764
71044
  function createStreamRequestError(operation, url3, response, text) {
70765
71045
  const context2 = [
70766
71046
  `PUT ${url3.origin}${url3.pathname}`,
70767
71047
  ...getVercelDiagnostics(response.headers)
70768
71048
  ];
70769
- return new Error(`Stream ${operation} failed: HTTP ${response.status} (${context2.join("; ")}): ${text}`);
71049
+ return new StreamError2(`Stream ${operation} failed: HTTP ${response.status} (${context2.join("; ")}): ${text}`, { url: url3.toString(), status: response.status });
70770
71050
  }
70771
71051
  function encodeMultiChunks(chunks) {
70772
71052
  const encoder4 = new TextEncoder();
@@ -70802,6 +71082,7 @@ function createStreamer2(config4) {
70802
71082
  headers: httpConfig.headers,
70803
71083
  dispatcher: getStreamDispatcher(config4),
70804
71084
  timeoutMs: null,
71085
+ transportErrorCode: "STREAM_ERROR",
70805
71086
  logLabel: url3.pathname,
70806
71087
  spanName: "workflow.stream.write",
70807
71088
  durationAttribute: "workflow.stream.write.chunk_rtt",
@@ -70832,6 +71113,7 @@ function createStreamer2(config4) {
70832
71113
  headers: httpConfig.headers,
70833
71114
  dispatcher: getStreamDispatcher(config4),
70834
71115
  timeoutMs: null,
71116
+ transportErrorCode: "STREAM_ERROR",
70835
71117
  logLabel: url3.pathname,
70836
71118
  spanName: "workflow.stream.write",
70837
71119
  durationAttribute: "workflow.stream.write.chunk_rtt",
@@ -70860,6 +71142,7 @@ function createStreamer2(config4) {
70860
71142
  // 503s with the stream left durably closing.
70861
71143
  dispatcher: getStreamCloseDispatcher(config4),
70862
71144
  timeoutMs: null,
71145
+ transportErrorCode: "STREAM_ERROR",
70863
71146
  logLabel: url3.pathname,
70864
71147
  spanName: "workflow.stream.write",
70865
71148
  durationAttribute: "workflow.stream.write.chunk_rtt",
@@ -70885,6 +71168,7 @@ function createStreamer2(config4) {
70885
71168
  headers: httpConfig.headers,
70886
71169
  dispatcher: void 0,
70887
71170
  timeoutMs: null,
71171
+ transportErrorCode: "STREAM_ERROR",
70888
71172
  logLabel: url3.pathname,
70889
71173
  spanName: "workflow.stream.read.connect",
70890
71174
  attributes: streamSpanAttributes({
@@ -70896,7 +71180,9 @@ function createStreamer2(config4) {
70896
71180
  buildError: createStreamReadError
70897
71181
  });
70898
71182
  if (!response.body) {
70899
- throw new Error("No response body for stream");
71183
+ throw new StreamError2("No response body for stream", {
71184
+ url: url3.toString()
71185
+ });
70900
71186
  }
70901
71187
  return response.body;
70902
71188
  },
@@ -70910,19 +71196,27 @@ function createStreamer2(config4) {
70910
71196
  }
70911
71197
  const qs = params.toString();
70912
71198
  const endpoint = `/v2/runs/${encodeURIComponent(runId)}/streams/${encodeURIComponent(name)}/chunks${qs ? `?${qs}` : ""}`;
70913
- return makeRequest({
70914
- endpoint,
70915
- config: config4,
70916
- schema: StreamChunksResponseSchema
70917
- });
71199
+ try {
71200
+ return await makeRequest({
71201
+ endpoint,
71202
+ config: config4,
71203
+ schema: StreamChunksResponseSchema
71204
+ });
71205
+ } catch (cause) {
71206
+ throw toStreamError(`Failed to read stream chunks for ${name}`, cause);
71207
+ }
70918
71208
  },
70919
71209
  async getInfo(runId, name) {
70920
71210
  const endpoint = `/v2/runs/${encodeURIComponent(runId)}/streams/${encodeURIComponent(name)}/info`;
70921
- return makeRequest({
70922
- endpoint,
70923
- config: config4,
70924
- schema: StreamInfoResponseSchema
70925
- });
71211
+ try {
71212
+ return await makeRequest({
71213
+ endpoint,
71214
+ config: config4,
71215
+ schema: StreamInfoResponseSchema
71216
+ });
71217
+ } catch (cause) {
71218
+ throw toStreamError(`Failed to read stream info for ${name}`, cause);
71219
+ }
70926
71220
  },
70927
71221
  async list(runId) {
70928
71222
  const httpConfig = await getHttpConfig(config4);
@@ -70933,10 +71227,18 @@ function createStreamer2(config4) {
70933
71227
  headers: httpConfig.headers,
70934
71228
  dispatcher: void 0,
70935
71229
  timeoutMs: null,
71230
+ transportErrorCode: "STREAM_ERROR",
70936
71231
  logLabel: url3.pathname,
70937
- buildError: /* @__PURE__ */ __name((res) => new Error(`Failed to list streams: ${res.status}`), "buildError")
71232
+ buildError: /* @__PURE__ */ __name((res) => new StreamError2(`Failed to list streams: ${res.status}`, {
71233
+ url: url3.toString(),
71234
+ status: res.status
71235
+ }), "buildError")
70938
71236
  });
70939
- return await response.json();
71237
+ try {
71238
+ return await response.json();
71239
+ } catch (cause) {
71240
+ throw toStreamError("Failed to parse stream list response", cause);
71241
+ }
70940
71242
  }
70941
71243
  }
70942
71244
  };
@@ -70945,6 +71247,7 @@ var MAX_CHUNKS_PER_REQUEST, getMaxChunksPerRequest, StreamInfoResponseSchema, St
70945
71247
  var init_streamer2 = __esm({
70946
71248
  "../world-vercel/dist/streamer.js"() {
70947
71249
  "use strict";
71250
+ init_dist7();
70948
71251
  init_dist6();
70949
71252
  init_zod2();
70950
71253
  init_http_client();
@@ -70960,6 +71263,7 @@ var init_streamer2 = __esm({
70960
71263
  __name(getStreamReadUrl, "getStreamReadUrl");
70961
71264
  __name(streamSpanAttributes, "streamSpanAttributes");
70962
71265
  __name(createStreamReadError, "createStreamReadError");
71266
+ __name(toStreamError, "toStreamError");
70963
71267
  __name(createStreamRequestError, "createStreamRequestError");
70964
71268
  __name(encodeMultiChunks, "encodeMultiChunks");
70965
71269
  StreamInfoResponseSchema = external_exports2.object({
@@ -71222,6 +71526,9 @@ function isRetryableWorldError2(err) {
71222
71526
  if (ThrottleError2.is(err)) {
71223
71527
  return true;
71224
71528
  }
71529
+ if (StreamError2.is(err)) {
71530
+ return err.status === void 0 || err.status >= 500;
71531
+ }
71225
71532
  if (!WorkflowWorldError2.is(err)) {
71226
71533
  return false;
71227
71534
  }
@@ -71243,6 +71550,9 @@ function classifyRunError(err) {
71243
71550
  if (WorkflowDeploymentMismatchError.is(err)) {
71244
71551
  return RUN_ERROR_CODES2.DEPLOYMENT_MISMATCH;
71245
71552
  }
71553
+ if (StreamError2.is(err)) {
71554
+ return RUN_ERROR_CODES2.STREAM_ERROR;
71555
+ }
71246
71556
  if (isWorldContractError(err) || isRetryableWorldError2(err)) {
71247
71557
  return RUN_ERROR_CODES2.WORLD_CONTRACT_ERROR;
71248
71558
  }
@@ -71263,7 +71573,11 @@ var init_classify_error = __esm({
71263
71573
  "SCHEMA_VALIDATION",
71264
71574
  RUN_ERROR_CODES2.WORLD_CONTRACT_ERROR
71265
71575
  ]);
71266
- RETRYABLE_WORLD_ERROR_CODES2 = /* @__PURE__ */ new Set(["TRANSPORT", "TIMEOUT"]);
71576
+ RETRYABLE_WORLD_ERROR_CODES2 = /* @__PURE__ */ new Set([
71577
+ "TRANSPORT",
71578
+ "TIMEOUT",
71579
+ RUN_ERROR_CODES2.STREAM_ERROR
71580
+ ]);
71267
71581
  RUNTIME_ERROR_CHECKS2 = [
71268
71582
  WorkflowRuntimeError2.is,
71269
71583
  StepNotRegisteredError2.is,
@@ -71646,6 +71960,13 @@ function describeError2(err, errorCode) {
71646
71960
  hint: CORRUPTED_EVENT_LOG_HINT
71647
71961
  };
71648
71962
  }
71963
+ if (effectiveCode === RUN_ERROR_CODES2.STREAM_ERROR) {
71964
+ return {
71965
+ attribution: "sdk",
71966
+ errorCode: effectiveCode,
71967
+ hint: STREAM_ERROR_HINT
71968
+ };
71969
+ }
71649
71970
  if (effectiveCode === RUN_ERROR_CODES2.WORLD_CONTRACT_ERROR) {
71650
71971
  return {
71651
71972
  attribution: "sdk",
@@ -71655,7 +71976,7 @@ function describeError2(err, errorCode) {
71655
71976
  }
71656
71977
  return { attribution: "user", errorCode: effectiveCode };
71657
71978
  }
71658
- var SERIALIZATION_ERROR_HINT, CONTEXT_ERROR_HINT, RUNTIME_ERROR_HINT, CORRUPTED_EVENT_LOG_HINT, REPLAY_TIMEOUT_HINT, MAX_DELIVERIES_HINT, MAX_EVENTS_HINT, WORLD_CONTRACT_HINT, DEPLOYMENT_MISMATCH_HINT;
71979
+ var SERIALIZATION_ERROR_HINT, CONTEXT_ERROR_HINT, RUNTIME_ERROR_HINT, CORRUPTED_EVENT_LOG_HINT, REPLAY_TIMEOUT_HINT, MAX_DELIVERIES_HINT, MAX_EVENTS_HINT, STREAM_ERROR_HINT, WORLD_CONTRACT_HINT, DEPLOYMENT_MISMATCH_HINT;
71659
71980
  var init_describe_error = __esm({
71660
71981
  "../core/dist/describe-error.js"() {
71661
71982
  "use strict";
@@ -71670,6 +71991,7 @@ var init_describe_error = __esm({
71670
71991
  REPLAY_TIMEOUT_HINT = 'The workflow replay between step boundaries took too long. This bounds workflow-VM and event-log replay time only \u2014 step bodies (`"use step"` functions) are excluded. This usually means the event log is unusually large or the workflow function is doing heavy synchronous work in workflow code outside of step bodies. Override the default budget via the WORKFLOW_REPLAY_TIMEOUT_MS env var if needed.';
71671
71992
  MAX_DELIVERIES_HINT = "The workflow queue exceeded its max-delivery budget. This usually indicates a persistent runtime failure \u2014 check the most recent stack traces for the underlying cause.";
71672
71993
  MAX_EVENTS_HINT = "The workflow exceeded the maximum number of events per run. This usually means unbounded work in the workflow function \u2014 e.g. a loop that keeps creating steps without terminating. Break long-running workflows into child workflows to stay under the limit.";
71994
+ STREAM_ERROR_HINT = "Workflow stream infrastructure failed while reading or writing data. This is an SDK or backend failure, not an error in your workflow code; please retry the run and report persistent failures with the runId.";
71673
71995
  WORLD_CONTRACT_HINT = "The workflow backend returned data that violated the SDK contract. This is not retryable; please report it with the stack trace and runId.";
71674
71996
  DEPLOYMENT_MISMATCH_HINT = "The run was delivered to a deployment other than the deployment it is pinned to, and was stopped to protect against code-skew errors after the runtime failed to re-route it there. Verify that the run's deployment is still available and that queue callbacks route to it.";
71675
71997
  __name(describeError2, "describeError");
@@ -74828,6 +75150,19 @@ function getCommonReducers2(_global2 = globalThis) {
74828
75150
  }
74829
75151
  return reduced;
74830
75152
  }, "RuntimeDecryptionError"),
75153
+ StreamError: /* @__PURE__ */ __name((value) => {
75154
+ const base = reduceNamedErrorSubclassBase2("StreamError", value);
75155
+ if (!base)
75156
+ return false;
75157
+ const reduced = { ...base };
75158
+ const status = readProperty2(value, "status");
75159
+ const url3 = readProperty2(value, "url");
75160
+ if (typeof status === "number")
75161
+ reduced.status = status;
75162
+ if (typeof url3 === "string")
75163
+ reduced.url = url3;
75164
+ return reduced;
75165
+ }, "StreamError"),
74831
75166
  SyntaxError: makeErrorSubclassReducer2("SyntaxError"),
74832
75167
  TypeError: makeErrorSubclassReducer2("TypeError"),
74833
75168
  URIError: makeErrorSubclassReducer2("URIError"),
@@ -74973,6 +75308,17 @@ function getCommonRevivers3(global2 = globalThis) {
74973
75308
  error95.stack = value.stack;
74974
75309
  return error95;
74975
75310
  }, "RuntimeDecryptionError"),
75311
+ StreamError: /* @__PURE__ */ __name((value) => {
75312
+ const Ctor = global2[/* @__PURE__ */ Symbol.for("@workflow/errors//StreamError")] ?? StreamError2;
75313
+ const error95 = new Ctor(value.message, {
75314
+ ..."cause" in value ? { cause: value.cause } : {},
75315
+ status: value.status,
75316
+ url: value.url
75317
+ });
75318
+ if (value.stack !== void 0)
75319
+ error95.stack = value.stack;
75320
+ return error95;
75321
+ }, "StreamError"),
74976
75322
  SyntaxError: makeErrorSubclassReviver2(global2, "SyntaxError"),
74977
75323
  TypeError: makeErrorSubclassReviver2(global2, "TypeError"),
74978
75324
  URIError: makeErrorSubclassReviver2(global2, "URIError"),
@@ -78545,7 +78891,7 @@ var version5;
78545
78891
  var init_version4 = __esm({
78546
78892
  "../core/dist/version.js"() {
78547
78893
  "use strict";
78548
- version5 = "5.0.0-beta.47";
78894
+ version5 = "5.0.0-beta.48";
78549
78895
  }
78550
78896
  });
78551
78897
 
@@ -78726,6 +79072,10 @@ async function loadWorkflowRunEvents(runId, afterCursor) {
78726
79072
  return { events: loadedEvents, cursor };
78727
79073
  });
78728
79074
  }
79075
+ function appendEventLog(log, appended) {
79076
+ appendUniqueEvents(log.events, appended.events);
79077
+ log.cursor = appended.cursor ?? log.cursor;
79078
+ }
78729
79079
  function isSlotGapCheckEnabled() {
78730
79080
  return process.env.WORKFLOW_SLOT_GAP_CHECK !== "0";
78731
79081
  }
@@ -78938,6 +79288,7 @@ var init_helpers3 = __esm({
78938
79288
  __name(assertEventPaginationProgress, "assertEventPaginationProgress");
78939
79289
  __name(shouldRetryWithoutEventCursor, "shouldRetryWithoutEventCursor");
78940
79290
  __name(loadWorkflowRunEvents, "loadWorkflowRunEvents");
79291
+ __name(appendEventLog, "appendEventLog");
78941
79292
  __name(isSlotGapCheckEnabled, "isSlotGapCheckEnabled");
78942
79293
  __name(mergeReportedEvents, "mergeReportedEvents");
78943
79294
  __name(absorbSkippedSlotReport, "absorbSkippedSlotReport");
@@ -79550,6 +79901,18 @@ function recordReadTimeToFirstChunk2(startEpochMs, runId, name, startIndex, conn
79550
79901
  });
79551
79902
  })();
79552
79903
  }
79904
+ function recordStreamReadKeyResolution2(startEpochMs, runId, name, succeeded) {
79905
+ void (async () => {
79906
+ await recordElapsedSpan2("workflow.stream.read.resolve_key", startEpochMs, {
79907
+ kind: await getSpanKind4("CLIENT"),
79908
+ attributes: {
79909
+ "workflow.run.id": runId,
79910
+ "workflow.stream.name": name,
79911
+ "workflow.stream.read.key_succeeded": succeeded
79912
+ }
79913
+ });
79914
+ })();
79915
+ }
79553
79916
  function recordStreamReadComplete2(startEpochMs, runId, name, chunkCount, byteCount, reconnects) {
79554
79917
  void (async () => {
79555
79918
  await recordElapsedSpan2("workflow.stream.read.complete", startEpochMs, {
@@ -79566,27 +79929,51 @@ function recordStreamReadComplete2(startEpochMs, runId, name, chunkCount, byteCo
79566
79929
  });
79567
79930
  })();
79568
79931
  }
79569
- function createReconnectingFramedStream2(runId, name, startIndex) {
79932
+ function createReconnectingFramedStream2(runId, name, startIndex, prefetchEncryptionKey = async () => void 0) {
79570
79933
  const reconnectSupported = startIndex === void 0 || startIndex >= 0;
79571
79934
  let currentStartIndex = startIndex ?? 0;
79572
79935
  let consumedFrames = 0;
79573
79936
  let reconnectCount = 0;
79574
79937
  let totalReconnectCount = 0;
79575
79938
  let reader;
79939
+ let canceled = false;
79940
+ let cancelReason;
79576
79941
  let buffer3 = new Uint8Array(0);
79577
79942
  let readStart;
79578
79943
  let connectMs;
79579
79944
  let firstChunkReported = false;
79580
79945
  let chunksDelivered = 0;
79581
79946
  let bytesDelivered = 0;
79947
+ let keyPrefetched = false;
79948
+ function prefetchKey() {
79949
+ if (keyPrefetched)
79950
+ return;
79951
+ keyPrefetched = true;
79952
+ const keyStart = Date.now();
79953
+ void prefetchEncryptionKey().then((key) => {
79954
+ if (key)
79955
+ recordStreamReadKeyResolution2(keyStart, runId, name, true);
79956
+ }, () => recordStreamReadKeyResolution2(keyStart, runId, name, false));
79957
+ }
79958
+ __name(prefetchKey, "prefetchKey");
79582
79959
  async function connect2() {
79960
+ if (canceled)
79961
+ return false;
79583
79962
  const world = await getWorldLazy2();
79963
+ if (canceled)
79964
+ return false;
79584
79965
  const effectiveStartIndex = reconnectSupported ? currentStartIndex + consumedFrames : startIndex;
79585
79966
  const connectStart = Date.now();
79586
79967
  const stream = await world.streams.get(runId, name, effectiveStartIndex);
79968
+ if (canceled) {
79969
+ await stream.cancel(cancelReason).catch(() => {
79970
+ });
79971
+ return false;
79972
+ }
79587
79973
  if (connectMs === void 0)
79588
79974
  connectMs = Date.now() - connectStart;
79589
79975
  reader = stream.getReader();
79976
+ return true;
79590
79977
  }
79591
79978
  __name(connect2, "connect");
79592
79979
  async function isVerifiedComplete() {
@@ -79600,11 +79987,15 @@ function createReconnectingFramedStream2(runId, name, startIndex) {
79600
79987
  }
79601
79988
  __name(isVerifiedComplete, "isVerifiedComplete");
79602
79989
  async function reconnect() {
79990
+ if (canceled)
79991
+ return false;
79603
79992
  if (reader) {
79604
79993
  await reader.cancel().catch(() => {
79605
79994
  });
79606
79995
  reader = void 0;
79607
79996
  }
79997
+ if (canceled)
79998
+ return false;
79608
79999
  currentStartIndex += consumedFrames;
79609
80000
  consumedFrames = 0;
79610
80001
  buffer3 = new Uint8Array(0);
@@ -79614,15 +80005,18 @@ function createReconnectingFramedStream2(runId, name, startIndex) {
79614
80005
  reconnectCount++;
79615
80006
  totalReconnectCount++;
79616
80007
  if (reconnectCount > maxReconnects) {
79617
- throw new Error(`Stream "${name}" exceeded maximum reconnection attempts (${maxReconnects})`);
80008
+ throw new StreamError2(`Stream "${name}" exceeded maximum reconnection attempts (${maxReconnects})`);
79618
80009
  }
79619
80010
  if (totalReconnectCount > maxTotalReconnects) {
79620
- throw new Error(`Stream "${name}" exceeded maximum total reconnection attempts (${maxTotalReconnects})`);
80011
+ throw new StreamError2(`Stream "${name}" exceeded maximum total reconnection attempts (${maxTotalReconnects})`);
79621
80012
  }
79622
80013
  try {
79623
- await connect2();
79624
- return;
80014
+ if (!await connect2())
80015
+ return false;
80016
+ return true;
79625
80017
  } catch (error95) {
80018
+ if (canceled)
80019
+ return false;
79626
80020
  if (StreamExpiredError2.is(error95))
79627
80021
  throw error95;
79628
80022
  }
@@ -79631,13 +80025,19 @@ function createReconnectingFramedStream2(runId, name, startIndex) {
79631
80025
  __name(reconnect, "reconnect");
79632
80026
  return new ReadableStream({
79633
80027
  pull: /* @__PURE__ */ __name(async (controller) => {
80028
+ if (canceled)
80029
+ return;
79634
80030
  if (readStart === void 0)
79635
80031
  readStart = Date.now();
80032
+ prefetchKey();
79636
80033
  for (; ; ) {
79637
80034
  if (!reader) {
79638
80035
  try {
79639
- await connect2();
80036
+ if (!await connect2())
80037
+ return;
79640
80038
  } catch (err) {
80039
+ if (canceled)
80040
+ return;
79641
80041
  controller.error(err);
79642
80042
  return;
79643
80043
  }
@@ -79646,23 +80046,32 @@ function createReconnectingFramedStream2(runId, name, startIndex) {
79646
80046
  try {
79647
80047
  result2 = await reader.read();
79648
80048
  } catch (err) {
80049
+ if (canceled)
80050
+ return;
79649
80051
  if (!reconnectSupported) {
79650
80052
  controller.error(err);
79651
80053
  return;
79652
80054
  }
79653
80055
  try {
79654
- await reconnect();
80056
+ if (!await reconnect())
80057
+ return;
79655
80058
  } catch (reconnectErr) {
79656
80059
  controller.error(reconnectErr);
79657
80060
  return;
79658
80061
  }
79659
80062
  continue;
79660
80063
  }
80064
+ if (canceled)
80065
+ return;
79661
80066
  if (result2.done || !result2.value) {
79662
80067
  reader = void 0;
79663
- if (reconnectSupported && !await isVerifiedComplete()) {
80068
+ const verifiedComplete = !reconnectSupported || await isVerifiedComplete();
80069
+ if (canceled)
80070
+ return;
80071
+ if (!verifiedComplete) {
79664
80072
  try {
79665
- await reconnect();
80073
+ if (!await reconnect())
80074
+ return;
79666
80075
  } catch (reconnectErr) {
79667
80076
  controller.error(reconnectErr);
79668
80077
  return;
@@ -79705,12 +80114,15 @@ function createReconnectingFramedStream2(runId, name, startIndex) {
79705
80114
  }
79706
80115
  }
79707
80116
  }, "pull"),
79708
- cancel: /* @__PURE__ */ __name(async () => {
79709
- if (reader) {
79710
- await reader.cancel().catch((err) => {
80117
+ cancel: /* @__PURE__ */ __name(async (reason) => {
80118
+ canceled = true;
80119
+ cancelReason = reason;
80120
+ const currentReader = reader;
80121
+ reader = void 0;
80122
+ if (currentReader) {
80123
+ await currentReader.cancel(reason).catch((err) => {
79711
80124
  console.warn("Error closing ReadableStream reader:", err);
79712
80125
  });
79713
- reader = void 0;
79714
80126
  }
79715
80127
  }, "cancel")
79716
80128
  });
@@ -80261,7 +80673,48 @@ async function getForwardedWritableEncryptionKey2(runId, deploymentId, encryptio
80261
80673
  const rawKey = deploymentId ? await world.getEncryptionKeyForRun(runId, { deploymentId }) : await world.getEncryptionKeyForRun(await world.runs.get(runId));
80262
80674
  return rawKey ? await importKey2(rawKey, ["encrypt"]) : void 0;
80263
80675
  }
80264
- function getExternalRevivers2(global2 = globalThis, ops, runId, cryptoKey) {
80676
+ function getRunReadableStream2(global2, ops, runId, name, startIndex, cryptoKey) {
80677
+ let reader;
80678
+ let lockState;
80679
+ let lockPollingStarted = false;
80680
+ let userReadable;
80681
+ userReadable = new ReadableStream(
80682
+ {
80683
+ async pull(controller) {
80684
+ try {
80685
+ if (!reader) {
80686
+ const stream = getExternalRevivers2(global2, ops, runId, cryptoKey, {
80687
+ onReadableState: /* @__PURE__ */ __name((state) => {
80688
+ lockState = state;
80689
+ }, "onReadableState")
80690
+ }).ReadableStream({ name, startIndex });
80691
+ reader = stream.getReader();
80692
+ if (lockState && !lockPollingStarted) {
80693
+ lockPollingStarted = true;
80694
+ pollReadableLock2(userReadable, lockState);
80695
+ }
80696
+ }
80697
+ const result2 = await reader.read();
80698
+ if (result2.done)
80699
+ controller.close();
80700
+ else
80701
+ controller.enqueue(result2.value);
80702
+ } catch (error95) {
80703
+ controller.error(error95);
80704
+ }
80705
+ },
80706
+ async cancel(reason) {
80707
+ await reader?.cancel(reason).catch(() => {
80708
+ });
80709
+ }
80710
+ },
80711
+ // A positive default high-water mark would run pull at construction to
80712
+ // fill the queue, turning an unread Run.getReadable() into I/O.
80713
+ { highWaterMark: 0 }
80714
+ );
80715
+ return userReadable;
80716
+ }
80717
+ function getExternalRevivers2(global2 = globalThis, ops, runId, cryptoKey, options) {
80265
80718
  return {
80266
80719
  ...getCommonRevivers4(global2),
80267
80720
  // StepFunction should not be returned from workflows to clients
@@ -80309,16 +80762,27 @@ function getExternalRevivers2(global2 = globalThis, ops, runId, cryptoKey) {
80309
80762
  const { readable: userReadable, writable } = value.framing === "framed-v1" ? getByteUnframingStream2() : new global2.TransformStream();
80310
80763
  flushablePipe2(readable, writable, state).catch(() => {
80311
80764
  });
80312
- pollReadableLock2(userReadable, state);
80765
+ if (options?.onReadableState)
80766
+ options.onReadableState(state);
80767
+ else
80768
+ pollReadableLock2(userReadable, state);
80313
80769
  return userReadable;
80314
80770
  } else {
80315
- const readable = createReconnectingFramedStream2(runId, value.name, value.startIndex);
80316
- const transform3 = getDeserializeStream2(getExternalRevivers2(global2, ops, runId, cryptoKey), cryptoKey);
80771
+ let keyPromise;
80772
+ const resolveKey = /* @__PURE__ */ __name(() => {
80773
+ keyPromise ??= resolveEncryptionKey2(cryptoKey);
80774
+ return keyPromise;
80775
+ }, "resolveKey");
80776
+ const readable = createReconnectingFramedStream2(runId, value.name, value.startIndex, resolveKey);
80777
+ const transform3 = getDeserializeStream2(getExternalRevivers2(global2, ops, runId, resolveKey), resolveKey);
80317
80778
  const state = createFlushableState2();
80318
80779
  ops.push(state.promise);
80319
80780
  flushablePipe2(readable, transform3.writable, state).catch(() => {
80320
80781
  });
80321
- pollReadableLock2(transform3.readable, state);
80782
+ if (options?.onReadableState)
80783
+ options.onReadableState(state);
80784
+ else
80785
+ pollReadableLock2(transform3.readable, state);
80322
80786
  return transform3.readable;
80323
80787
  }
80324
80788
  }, "ReadableStream"),
@@ -80892,6 +81356,7 @@ var init_serialization4 = __esm({
80892
81356
  __name(getByteFramingStream2, "getByteFramingStream");
80893
81357
  __name(getByteUnframingStream2, "getByteUnframingStream");
80894
81358
  __name(recordReadTimeToFirstChunk2, "recordReadTimeToFirstChunk");
81359
+ __name(recordStreamReadKeyResolution2, "recordStreamReadKeyResolution");
80895
81360
  __name(recordStreamReadComplete2, "recordStreamReadComplete");
80896
81361
  WorkflowServerReadableStream2 = class extends ReadableStream {
80897
81362
  static {
@@ -81206,6 +81671,7 @@ var init_serialization4 = __esm({
81206
81671
  __name(reviveAbortSignal2, "reviveAbortSignal");
81207
81672
  __name(getCommonRevivers4, "getCommonRevivers");
81208
81673
  __name(getForwardedWritableEncryptionKey2, "getForwardedWritableEncryptionKey");
81674
+ __name(getRunReadableStream2, "getRunReadableStream");
81209
81675
  __name(getExternalRevivers2, "getExternalRevivers");
81210
81676
  __name(getWorkflowRevivers, "getWorkflowRevivers");
81211
81677
  __name(getStepRevivers2, "getStepRevivers");
@@ -87866,6 +88332,30 @@ function createQuickJSSerde(vm, capturedRoot) {
87866
88332
  reduced.cause = shape.cause;
87867
88333
  return reduced;
87868
88334
  }, "RuntimeDecryptionError"),
88335
+ StreamError: /* @__PURE__ */ __name((value) => {
88336
+ if (!isHandle(value) || !value.isError)
88337
+ return false;
88338
+ if (chainedString(value, "name") !== "StreamError")
88339
+ return false;
88340
+ const shape = reduceErrorShape(value);
88341
+ const reduced = {
88342
+ message: shape.message,
88343
+ stack: shape.stack
88344
+ };
88345
+ if (Object.hasOwn(shape, "cause"))
88346
+ reduced.cause = shape.cause;
88347
+ const status = own(value, "status");
88348
+ if (status && !status.isUndefined)
88349
+ reduced.status = status;
88350
+ else
88351
+ status?.dispose();
88352
+ const url3 = own(value, "url");
88353
+ if (url3 && !url3.isUndefined)
88354
+ reduced.url = url3;
88355
+ else
88356
+ url3?.dispose();
88357
+ return reduced;
88358
+ }, "StreamError"),
87869
88359
  SyntaxError: namedErrorSubclassReducer("SyntaxError"),
87870
88360
  TypeError: namedErrorSubclassReducer("TypeError"),
87871
88361
  URIError: namedErrorSubclassReducer("URIError"),
@@ -88449,6 +88939,41 @@ function createQuickJSSerde(vm, capturedRoot) {
88449
88939
  }
88450
88940
  return error95;
88451
88941
  }, "RuntimeDecryptionError"),
88942
+ StreamError: /* @__PURE__ */ __name((value) => {
88943
+ const cls = registeredErrorClass("@workflow/errors//StreamError");
88944
+ let error95;
88945
+ if (cls) {
88946
+ const options = vm.newObject();
88947
+ for (const property of ["cause", "status", "url"]) {
88948
+ if (!guestHasOwn(value, property))
88949
+ continue;
88950
+ const propertyValue = own(value, property) ?? vm.undefined;
88951
+ options.setProp(property, propertyValue);
88952
+ if (propertyValue !== vm.undefined)
88953
+ propertyValue.dispose();
88954
+ }
88955
+ const message = own(value, "message") ?? vm.undefined;
88956
+ error95 = vm.construct(cls, message, options);
88957
+ if (message !== vm.undefined)
88958
+ message.dispose();
88959
+ options.dispose();
88960
+ const stack = own(value, "stack");
88961
+ if (stack && !stack.isUndefined)
88962
+ define2(error95, "stack", stack);
88963
+ stack?.dispose();
88964
+ cls.dispose();
88965
+ } else {
88966
+ error95 = buildError(i.Error, value, { name: "StreamError" });
88967
+ for (const property of ["status", "url"]) {
88968
+ const propertyValue = own(value, property);
88969
+ if (propertyValue && !propertyValue.isUndefined) {
88970
+ define2(error95, property, propertyValue);
88971
+ }
88972
+ propertyValue?.dispose();
88973
+ }
88974
+ }
88975
+ return error95;
88976
+ }, "StreamError"),
88452
88977
  SyntaxError: namedErrorSubclassReviver("SyntaxError"),
88453
88978
  TypeError: namedErrorSubclassReviver("TypeError"),
88454
88979
  URIError: namedErrorSubclassReviver("URIError"),
@@ -88941,7 +89466,8 @@ var init_quickjs_serde = __esm({
88941
89466
  "@workflow/errors//FatalError",
88942
89467
  "@workflow/errors//HookConflictError",
88943
89468
  "@workflow/errors//RetryableError",
88944
- "@workflow/errors//RuntimeDecryptionError"
89469
+ "@workflow/errors//RuntimeDecryptionError",
89470
+ "@workflow/errors//StreamError"
88945
89471
  ];
88946
89472
  CAPTURE_ROOT = `(() => ({
88947
89473
  intrinsics: ${CAPTURE_INTRINSICS},
@@ -92268,6 +92794,8 @@ var init_error_codes = __esm2({
92268
92794
  MAX_EVENTS_EXCEEDED: "MAX_EVENTS_EXCEEDED",
92269
92795
  /** Workflow replay exceeded the maximum allowed duration */
92270
92796
  REPLAY_TIMEOUT: "REPLAY_TIMEOUT",
92797
+ /** Workflow stream infrastructure failed while reading or writing data */
92798
+ STREAM_ERROR: "STREAM_ERROR",
92271
92799
  /** World response violated the SDK contract and cannot be retried safely */
92272
92800
  WORLD_CONTRACT_ERROR: "WORLD_CONTRACT_ERROR",
92273
92801
  /** Run was delivered to a deployment other than the one it is pinned to */
@@ -92325,6 +92853,7 @@ var HookConflictError;
92325
92853
  var HookNotFoundError;
92326
92854
  var EntityConflictError;
92327
92855
  var RunExpiredError;
92856
+ var StreamError;
92328
92857
  var StreamExpiredError;
92329
92858
  var ThrottleError;
92330
92859
  var WorkflowRunCancelledError;
@@ -92334,11 +92863,13 @@ var FATAL_ERROR_KEY;
92334
92863
  var RETRYABLE_ERROR_KEY;
92335
92864
  var HOOK_CONFLICT_ERROR_KEY;
92336
92865
  var RUNTIME_DECRYPTION_ERROR_KEY;
92866
+ var STREAM_ERROR_KEY;
92337
92867
  var init_dist2 = __esm2({
92338
92868
  "../errors/dist/index.js"() {
92339
92869
  "use strict";
92340
92870
  init_dist();
92341
92871
  init_error_codes();
92872
+ init_error_codes();
92342
92873
  BASE_URL = "https://workflow-sdk.dev/err";
92343
92874
  __name2(isError, "isError");
92344
92875
  __name2(appendFramedDetails, "appendFramedDetails");
@@ -92396,6 +92927,12 @@ Caused by: ${options.cause.stack}`;
92396
92927
  url;
92397
92928
  /** Retry-After value in seconds, present on 429 and 425 responses */
92398
92929
  retryAfter;
92930
+ /**
92931
+ * The offending argument, present on client-side validation failures
92932
+ * (`code: 'INVALID_ARGUMENT'`). Lets a caller correct the specific
92933
+ * parameter without parsing the message.
92934
+ */
92935
+ field;
92399
92936
  constructor(message, options) {
92400
92937
  super(message, {
92401
92938
  cause: options?.cause
@@ -92405,6 +92942,7 @@ Caused by: ${options.cause.stack}`;
92405
92942
  this.code = options?.code;
92406
92943
  this.url = options?.url;
92407
92944
  this.retryAfter = options?.retryAfter;
92945
+ this.field = options?.field;
92408
92946
  }
92409
92947
  static is(value) {
92410
92948
  return isError(value) && value.name === "WorkflowWorldError";
@@ -92651,6 +93189,26 @@ Caused by: ${options.cause.stack}`;
92651
93189
  return isError(value) && value.name === "RunExpiredError";
92652
93190
  }
92653
93191
  };
93192
+ StreamError = class extends WorkflowWorldError {
93193
+ static {
93194
+ __name(this, "StreamError");
93195
+ }
93196
+ static {
93197
+ __name2(this, "StreamError");
93198
+ }
93199
+ constructor(message, options) {
93200
+ super(message, {
93201
+ code: RUN_ERROR_CODES.STREAM_ERROR,
93202
+ cause: options?.cause,
93203
+ url: options?.url,
93204
+ status: options?.status
93205
+ });
93206
+ this.name = "StreamError";
93207
+ }
93208
+ static is(value) {
93209
+ return isError(value) && value.name === "StreamError";
93210
+ }
93211
+ };
92654
93212
  StreamExpiredError = class extends WorkflowWorldError {
92655
93213
  static {
92656
93214
  __name(this, "StreamExpiredError");
@@ -92755,6 +93313,7 @@ Caused by: ${options.cause.stack}`;
92755
93313
  RETRYABLE_ERROR_KEY = /* @__PURE__ */ Symbol.for("@workflow/errors//RetryableError");
92756
93314
  HOOK_CONFLICT_ERROR_KEY = /* @__PURE__ */ Symbol.for("@workflow/errors//HookConflictError");
92757
93315
  RUNTIME_DECRYPTION_ERROR_KEY = /* @__PURE__ */ Symbol.for("@workflow/errors//RuntimeDecryptionError");
93316
+ STREAM_ERROR_KEY = /* @__PURE__ */ Symbol.for("@workflow/errors//StreamError");
92758
93317
  if (typeof globalThis !== "undefined") {
92759
93318
  if (!Object.hasOwn(globalThis, FATAL_ERROR_KEY)) {
92760
93319
  Object.defineProperty(globalThis, FATAL_ERROR_KEY, {
@@ -92788,6 +93347,14 @@ Caused by: ${options.cause.stack}`;
92788
93347
  configurable: false
92789
93348
  });
92790
93349
  }
93350
+ if (!Object.hasOwn(globalThis, STREAM_ERROR_KEY)) {
93351
+ Object.defineProperty(globalThis, STREAM_ERROR_KEY, {
93352
+ value: StreamError,
93353
+ writable: false,
93354
+ enumerable: false,
93355
+ configurable: false
93356
+ });
93357
+ }
92791
93358
  }
92792
93359
  }
92793
93360
  });
@@ -111882,7 +112449,7 @@ var init_runs = __esm2({
111882
112449
  // Completed state - output can be v1 or v2 format
111883
112450
  WorkflowRunBaseSchema.extend({
111884
112451
  status: external_exports.literal("completed"),
111885
- output: SerializedDataSchema,
112452
+ output: SerializedDataSchema.optional(),
111886
112453
  error: external_exports.undefined().optional(),
111887
112454
  completedAt: external_exports.coerce.date()
111888
112455
  }),
@@ -111890,7 +112457,7 @@ var init_runs = __esm2({
111890
112457
  WorkflowRunBaseSchema.extend({
111891
112458
  status: external_exports.literal("failed"),
111892
112459
  output: external_exports.undefined().optional(),
111893
- error: SerializedDataSchema,
112460
+ error: SerializedDataSchema.optional(),
111894
112461
  completedAt: external_exports.coerce.date()
111895
112462
  })
111896
112463
  ]);
@@ -112154,8 +112721,8 @@ var init_analytics = __esm2({
112154
112721
  AnalyticsAttributeKeySchema = external_exports.object({
112155
112722
  key: external_exports.string(),
112156
112723
  runCount: external_exports.coerce.number(),
112157
- firstSeenAt: external_exports.coerce.date(),
112158
- lastSeenAt: external_exports.coerce.date()
112724
+ firstSeenAt: UTCDateSchema,
112725
+ lastSeenAt: UTCDateSchema
112159
112726
  });
112160
112727
  }
112161
112728
  });
@@ -113279,6 +113846,18 @@ function getCommonReducers(_global2 = globalThis) {
113279
113846
  }
113280
113847
  return reduced;
113281
113848
  }, "RuntimeDecryptionError"),
113849
+ StreamError: /* @__PURE__ */ __name2((value) => {
113850
+ const base = reduceNamedErrorSubclassBase("StreamError", value);
113851
+ if (!base) return false;
113852
+ const reduced = {
113853
+ ...base
113854
+ };
113855
+ const status = readProperty(value, "status");
113856
+ const url22 = readProperty(value, "url");
113857
+ if (typeof status === "number") reduced.status = status;
113858
+ if (typeof url22 === "string") reduced.url = url22;
113859
+ return reduced;
113860
+ }, "StreamError"),
113282
113861
  SyntaxError: makeErrorSubclassReducer("SyntaxError"),
113283
113862
  TypeError: makeErrorSubclassReducer("TypeError"),
113284
113863
  URIError: makeErrorSubclassReducer("URIError"),
@@ -113413,6 +113992,18 @@ function getCommonRevivers(global2 = globalThis) {
113413
113992
  if (value.stack !== void 0) error482.stack = value.stack;
113414
113993
  return error482;
113415
113994
  }, "RuntimeDecryptionError"),
113995
+ StreamError: /* @__PURE__ */ __name2((value) => {
113996
+ const Ctor = global2[/* @__PURE__ */ Symbol.for("@workflow/errors//StreamError")] ?? StreamError;
113997
+ const error482 = new Ctor(value.message, {
113998
+ ..."cause" in value ? {
113999
+ cause: value.cause
114000
+ } : {},
114001
+ status: value.status,
114002
+ url: value.url
114003
+ });
114004
+ if (value.stack !== void 0) error482.stack = value.stack;
114005
+ return error482;
114006
+ }, "StreamError"),
113416
114007
  SyntaxError: makeErrorSubclassReviver(global2, "SyntaxError"),
113417
114008
  TypeError: makeErrorSubclassReviver(global2, "TypeError"),
113418
114009
  URIError: makeErrorSubclassReviver(global2, "URIError"),
@@ -118938,7 +119529,7 @@ var version2;
118938
119529
  var init_version = __esm2({
118939
119530
  "../core/dist/version.js"() {
118940
119531
  "use strict";
118941
- version2 = "5.0.0-beta.47";
119532
+ version2 = "5.0.0-beta.48";
118942
119533
  }
118943
119534
  });
118944
119535
  function getWorkflowQueueName(workflowName, namespace) {
@@ -124730,6 +125321,19 @@ function recordReadTimeToFirstChunk(startEpochMs, runId, name, startIndex, conne
124730
125321
  })();
124731
125322
  }
124732
125323
  __name(recordReadTimeToFirstChunk, "recordReadTimeToFirstChunk");
125324
+ function recordStreamReadKeyResolution(startEpochMs, runId, name, succeeded) {
125325
+ void (async () => {
125326
+ await recordElapsedSpan("workflow.stream.read.resolve_key", startEpochMs, {
125327
+ kind: await getSpanKind("CLIENT"),
125328
+ attributes: {
125329
+ "workflow.run.id": runId,
125330
+ "workflow.stream.name": name,
125331
+ "workflow.stream.read.key_succeeded": succeeded
125332
+ }
125333
+ });
125334
+ })();
125335
+ }
125336
+ __name(recordStreamReadKeyResolution, "recordStreamReadKeyResolution");
124733
125337
  function recordStreamReadComplete(startEpochMs, runId, name, chunkCount, byteCount, reconnects) {
124734
125338
  void (async () => {
124735
125339
  await recordElapsedSpan("workflow.stream.read.complete", startEpochMs, {
@@ -124749,26 +125353,47 @@ function recordStreamReadComplete(startEpochMs, runId, name, chunkCount, byteCou
124749
125353
  })();
124750
125354
  }
124751
125355
  __name(recordStreamReadComplete, "recordStreamReadComplete");
124752
- function createReconnectingFramedStream(runId, name, startIndex) {
125356
+ function createReconnectingFramedStream(runId, name, startIndex, prefetchEncryptionKey = async () => void 0) {
124753
125357
  const reconnectSupported = startIndex === void 0 || startIndex >= 0;
124754
125358
  let currentStartIndex = startIndex ?? 0;
124755
125359
  let consumedFrames = 0;
124756
125360
  let reconnectCount = 0;
124757
125361
  let totalReconnectCount = 0;
124758
125362
  let reader;
125363
+ let canceled = false;
125364
+ let cancelReason;
124759
125365
  let buffer22 = new Uint8Array(0);
124760
125366
  let readStart;
124761
125367
  let connectMs;
124762
125368
  let firstChunkReported = false;
124763
125369
  let chunksDelivered = 0;
124764
125370
  let bytesDelivered = 0;
125371
+ let keyPrefetched = false;
125372
+ function prefetchKey() {
125373
+ if (keyPrefetched) return;
125374
+ keyPrefetched = true;
125375
+ const keyStart = Date.now();
125376
+ void prefetchEncryptionKey().then((key) => {
125377
+ if (key) recordStreamReadKeyResolution(keyStart, runId, name, true);
125378
+ }, () => recordStreamReadKeyResolution(keyStart, runId, name, false));
125379
+ }
125380
+ __name(prefetchKey, "prefetchKey");
125381
+ __name2(prefetchKey, "prefetchKey");
124765
125382
  async function connect2() {
125383
+ if (canceled) return false;
124766
125384
  const world = await getWorldLazy();
125385
+ if (canceled) return false;
124767
125386
  const effectiveStartIndex = reconnectSupported ? currentStartIndex + consumedFrames : startIndex;
124768
125387
  const connectStart = Date.now();
124769
125388
  const stream = await world.streams.get(runId, name, effectiveStartIndex);
125389
+ if (canceled) {
125390
+ await stream.cancel(cancelReason).catch(() => {
125391
+ });
125392
+ return false;
125393
+ }
124770
125394
  if (connectMs === void 0) connectMs = Date.now() - connectStart;
124771
125395
  reader = stream.getReader();
125396
+ return true;
124772
125397
  }
124773
125398
  __name(connect2, "connect");
124774
125399
  __name2(connect2, "connect");
@@ -124784,11 +125409,13 @@ function createReconnectingFramedStream(runId, name, startIndex) {
124784
125409
  __name(isVerifiedComplete, "isVerifiedComplete");
124785
125410
  __name2(isVerifiedComplete, "isVerifiedComplete");
124786
125411
  async function reconnect() {
125412
+ if (canceled) return false;
124787
125413
  if (reader) {
124788
125414
  await reader.cancel().catch(() => {
124789
125415
  });
124790
125416
  reader = void 0;
124791
125417
  }
125418
+ if (canceled) return false;
124792
125419
  currentStartIndex += consumedFrames;
124793
125420
  consumedFrames = 0;
124794
125421
  buffer22 = new Uint8Array(0);
@@ -124798,15 +125425,16 @@ function createReconnectingFramedStream(runId, name, startIndex) {
124798
125425
  reconnectCount++;
124799
125426
  totalReconnectCount++;
124800
125427
  if (reconnectCount > maxReconnects) {
124801
- throw new Error(`Stream "${name}" exceeded maximum reconnection attempts (${maxReconnects})`);
125428
+ throw new StreamError(`Stream "${name}" exceeded maximum reconnection attempts (${maxReconnects})`);
124802
125429
  }
124803
125430
  if (totalReconnectCount > maxTotalReconnects) {
124804
- throw new Error(`Stream "${name}" exceeded maximum total reconnection attempts (${maxTotalReconnects})`);
125431
+ throw new StreamError(`Stream "${name}" exceeded maximum total reconnection attempts (${maxTotalReconnects})`);
124805
125432
  }
124806
125433
  try {
124807
- await connect2();
124808
- return;
125434
+ if (!await connect2()) return false;
125435
+ return true;
124809
125436
  } catch (error482) {
125437
+ if (canceled) return false;
124810
125438
  if (StreamExpiredError.is(error482)) throw error482;
124811
125439
  }
124812
125440
  }
@@ -124815,12 +125443,15 @@ function createReconnectingFramedStream(runId, name, startIndex) {
124815
125443
  __name2(reconnect, "reconnect");
124816
125444
  return new ReadableStream({
124817
125445
  pull: /* @__PURE__ */ __name2(async (controller) => {
125446
+ if (canceled) return;
124818
125447
  if (readStart === void 0) readStart = Date.now();
125448
+ prefetchKey();
124819
125449
  for (; ; ) {
124820
125450
  if (!reader) {
124821
125451
  try {
124822
- await connect2();
125452
+ if (!await connect2()) return;
124823
125453
  } catch (err) {
125454
+ if (canceled) return;
124824
125455
  controller.error(err);
124825
125456
  return;
124826
125457
  }
@@ -124829,23 +125460,27 @@ function createReconnectingFramedStream(runId, name, startIndex) {
124829
125460
  try {
124830
125461
  result2 = await reader.read();
124831
125462
  } catch (err) {
125463
+ if (canceled) return;
124832
125464
  if (!reconnectSupported) {
124833
125465
  controller.error(err);
124834
125466
  return;
124835
125467
  }
124836
125468
  try {
124837
- await reconnect();
125469
+ if (!await reconnect()) return;
124838
125470
  } catch (reconnectErr) {
124839
125471
  controller.error(reconnectErr);
124840
125472
  return;
124841
125473
  }
124842
125474
  continue;
124843
125475
  }
125476
+ if (canceled) return;
124844
125477
  if (result2.done || !result2.value) {
124845
125478
  reader = void 0;
124846
- if (reconnectSupported && !await isVerifiedComplete()) {
125479
+ const verifiedComplete = !reconnectSupported || await isVerifiedComplete();
125480
+ if (canceled) return;
125481
+ if (!verifiedComplete) {
124847
125482
  try {
124848
- await reconnect();
125483
+ if (!await reconnect()) return;
124849
125484
  } catch (reconnectErr) {
124850
125485
  controller.error(reconnectErr);
124851
125486
  return;
@@ -124887,12 +125522,15 @@ function createReconnectingFramedStream(runId, name, startIndex) {
124887
125522
  }
124888
125523
  }
124889
125524
  }, "pull"),
124890
- cancel: /* @__PURE__ */ __name2(async () => {
124891
- if (reader) {
124892
- await reader.cancel().catch((err) => {
125525
+ cancel: /* @__PURE__ */ __name2(async (reason) => {
125526
+ canceled = true;
125527
+ cancelReason = reason;
125528
+ const currentReader = reader;
125529
+ reader = void 0;
125530
+ if (currentReader) {
125531
+ await currentReader.cancel(reason).catch((err) => {
124893
125532
  console.warn("Error closing ReadableStream reader:", err);
124894
125533
  });
124895
- reader = void 0;
124896
125534
  }
124897
125535
  }, "cancel")
124898
125536
  });
@@ -125415,7 +126053,52 @@ async function getForwardedWritableEncryptionKey(runId, deploymentId, encryption
125415
126053
  ]) : void 0;
125416
126054
  }
125417
126055
  __name(getForwardedWritableEncryptionKey, "getForwardedWritableEncryptionKey");
125418
- function getExternalRevivers(global2 = globalThis, ops, runId, cryptoKey) {
126056
+ function getRunReadableStream(global2, ops, runId, name, startIndex, cryptoKey) {
126057
+ let reader;
126058
+ let lockState;
126059
+ let lockPollingStarted = false;
126060
+ let userReadable;
126061
+ userReadable = new ReadableStream(
126062
+ {
126063
+ async pull(controller) {
126064
+ try {
126065
+ if (!reader) {
126066
+ const stream = getExternalRevivers(global2, ops, runId, cryptoKey, {
126067
+ onReadableState: /* @__PURE__ */ __name2((state) => {
126068
+ lockState = state;
126069
+ }, "onReadableState")
126070
+ }).ReadableStream({
126071
+ name,
126072
+ startIndex
126073
+ });
126074
+ reader = stream.getReader();
126075
+ if (lockState && !lockPollingStarted) {
126076
+ lockPollingStarted = true;
126077
+ pollReadableLock(userReadable, lockState);
126078
+ }
126079
+ }
126080
+ const result2 = await reader.read();
126081
+ if (result2.done) controller.close();
126082
+ else controller.enqueue(result2.value);
126083
+ } catch (error482) {
126084
+ controller.error(error482);
126085
+ }
126086
+ },
126087
+ async cancel(reason) {
126088
+ await reader?.cancel(reason).catch(() => {
126089
+ });
126090
+ }
126091
+ },
126092
+ // A positive default high-water mark would run pull at construction to
126093
+ // fill the queue, turning an unread Run.getReadable() into I/O.
126094
+ {
126095
+ highWaterMark: 0
126096
+ }
126097
+ );
126098
+ return userReadable;
126099
+ }
126100
+ __name(getRunReadableStream, "getRunReadableStream");
126101
+ function getExternalRevivers(global2 = globalThis, ops, runId, cryptoKey, options) {
125419
126102
  return {
125420
126103
  ...getCommonRevivers2(global2),
125421
126104
  // StepFunction should not be returned from workflows to clients
@@ -125463,16 +126146,23 @@ function getExternalRevivers(global2 = globalThis, ops, runId, cryptoKey) {
125463
126146
  const { readable: userReadable, writable } = value.framing === "framed-v1" ? getByteUnframingStream() : new global2.TransformStream();
125464
126147
  flushablePipe(readable, writable, state).catch(() => {
125465
126148
  });
125466
- pollReadableLock(userReadable, state);
126149
+ if (options?.onReadableState) options.onReadableState(state);
126150
+ else pollReadableLock(userReadable, state);
125467
126151
  return userReadable;
125468
126152
  } else {
125469
- const readable = createReconnectingFramedStream(runId, value.name, value.startIndex);
125470
- const transform22 = getDeserializeStream(getExternalRevivers(global2, ops, runId, cryptoKey), cryptoKey);
126153
+ let keyPromise;
126154
+ const resolveKey = /* @__PURE__ */ __name2(() => {
126155
+ keyPromise ??= resolveEncryptionKey(cryptoKey);
126156
+ return keyPromise;
126157
+ }, "resolveKey");
126158
+ const readable = createReconnectingFramedStream(runId, value.name, value.startIndex, resolveKey);
126159
+ const transform22 = getDeserializeStream(getExternalRevivers(global2, ops, runId, resolveKey), resolveKey);
125471
126160
  const state = createFlushableState();
125472
126161
  ops.push(state.promise);
125473
126162
  flushablePipe(readable, transform22.writable, state).catch(() => {
125474
126163
  });
125475
- pollReadableLock(transform22.readable, state);
126164
+ if (options?.onReadableState) options.onReadableState(state);
126165
+ else pollReadableLock(transform22.readable, state);
125476
126166
  return transform22.readable;
125477
126167
  }
125478
126168
  }, "ReadableStream"),
@@ -125889,6 +126579,7 @@ var init_serialization2 = __esm2({
125889
126579
  __name2(getByteFramingStream, "getByteFramingStream");
125890
126580
  __name2(getByteUnframingStream, "getByteUnframingStream");
125891
126581
  __name2(recordReadTimeToFirstChunk, "recordReadTimeToFirstChunk");
126582
+ __name2(recordStreamReadKeyResolution, "recordStreamReadKeyResolution");
125892
126583
  __name2(recordStreamReadComplete, "recordStreamReadComplete");
125893
126584
  WorkflowServerReadableStream = class extends ReadableStream {
125894
126585
  static {
@@ -126209,6 +126900,7 @@ var init_serialization2 = __esm2({
126209
126900
  __name2(reviveAbortSignal, "reviveAbortSignal");
126210
126901
  __name2(getCommonRevivers2, "getCommonRevivers");
126211
126902
  __name2(getForwardedWritableEncryptionKey, "getForwardedWritableEncryptionKey");
126903
+ __name2(getRunReadableStream, "getRunReadableStream");
126212
126904
  __name2(getExternalRevivers, "getExternalRevivers");
126213
126905
  __name2(getStepRevivers, "getStepRevivers");
126214
126906
  __name2(dehydrateWorkflowArguments, "dehydrateWorkflowArguments");
@@ -126379,7 +127071,8 @@ var WORLD_CONTRACT_ERROR_CODES = /* @__PURE__ */ new Set([
126379
127071
  ]);
126380
127072
  var RETRYABLE_WORLD_ERROR_CODES = /* @__PURE__ */ new Set([
126381
127073
  "TRANSPORT",
126382
- "TIMEOUT"
127074
+ "TIMEOUT",
127075
+ RUN_ERROR_CODES.STREAM_ERROR
126383
127076
  ]);
126384
127077
  var RUNTIME_ERROR_CHECKS = [
126385
127078
  WorkflowRuntimeError.is,
@@ -126395,6 +127088,9 @@ function isRetryableWorldError(err) {
126395
127088
  if (ThrottleError.is(err)) {
126396
127089
  return true;
126397
127090
  }
127091
+ if (StreamError.is(err)) {
127092
+ return err.status === void 0 || err.status >= 500;
127093
+ }
126398
127094
  if (!WorkflowWorldError.is(err)) {
126399
127095
  return false;
126400
127096
  }
@@ -126692,7 +127388,7 @@ __name2(start, "start");
126692
127388
  value: "start",
126693
127389
  configurable: true
126694
127390
  });
126695
- })(start, "step//@workflow/core/runtime/start@5.0.0-beta.47//start");
127391
+ })(start, "step//@workflow/core/runtime/start@5.0.0-beta.48//start");
126696
127392
  async function wakeUpRun(world, runId, options) {
126697
127393
  try {
126698
127394
  const run22 = await world.runs.get(runId, {
@@ -126880,9 +127576,9 @@ var Run = class _Run {
126880
127576
  return this.#encryptionKeyPromise;
126881
127577
  }
126882
127578
  /**
126883
- * Defer fetching the run and its encryption key until serialized stream data
126884
- * is actually read. An empty or metadata-only stream must not start an
126885
- * unobserved run lookup.
127579
+ * Defers fetching the run and its encryption key until a readable is first
127580
+ * consumed. The first pull prefetches it so an encrypted first frame can join
127581
+ * the lookup; this also applies to an empty consumed stream.
126886
127582
  * @internal
126887
127583
  */
126888
127584
  #getEncryptionKeyLazily() {
@@ -126993,10 +127689,7 @@ var Run = class _Run {
126993
127689
  const { ops = [], global: global2 = globalThis, startIndex, namespace } = options;
126994
127690
  const name = getWorkflowRunStreamId(this.runId, namespace);
126995
127691
  const encryptionKey = this.#getEncryptionKeyLazily();
126996
- const stream = getExternalRevivers(global2, ops, this.runId, encryptionKey).ReadableStream({
126997
- name,
126998
- startIndex
126999
- });
127692
+ const stream = getRunReadableStream(global2, ops, this.runId, name, startIndex, encryptionKey);
127000
127693
  const worldPromise = this.#lazyWorldPromise;
127001
127694
  const runId = this.runId;
127002
127695
  return Object.assign(stream, {
@@ -127095,7 +127788,7 @@ var Run = class _Run {
127095
127788
  value: "wakeUp",
127096
127789
  configurable: true
127097
127790
  });
127098
- })(Run.prototype["wakeUp"], "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#wakeUp");
127791
+ })(Run.prototype["wakeUp"], "step//@workflow/core/runtime/run@5.0.0-beta.48//Run#wakeUp");
127099
127792
  (function(__wf_fn, __wf_id) {
127100
127793
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
127101
127794
  __wf_reg.set(__wf_id, __wf_fn);
@@ -127104,7 +127797,7 @@ var Run = class _Run {
127104
127797
  value: "cancel",
127105
127798
  configurable: true
127106
127799
  });
127107
- })(Run.prototype["cancel"], "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#cancel");
127800
+ })(Run.prototype["cancel"], "step//@workflow/core/runtime/run@5.0.0-beta.48//Run#cancel");
127108
127801
  (function(__wf_fn, __wf_id) {
127109
127802
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
127110
127803
  __wf_reg.set(__wf_id, __wf_fn);
@@ -127113,7 +127806,7 @@ var Run = class _Run {
127113
127806
  value: "getReadable",
127114
127807
  configurable: true
127115
127808
  });
127116
- })(Run.prototype["getReadable"], "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#getReadable");
127809
+ })(Run.prototype["getReadable"], "step//@workflow/core/runtime/run@5.0.0-beta.48//Run#getReadable");
127117
127810
  (function(__wf_fn, __wf_id) {
127118
127811
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
127119
127812
  __wf_reg.set(__wf_id, __wf_fn);
@@ -127122,7 +127815,7 @@ var Run = class _Run {
127122
127815
  value: "exists",
127123
127816
  configurable: true
127124
127817
  });
127125
- })(Object.getOwnPropertyDescriptor(Run.prototype, "exists").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#exists");
127818
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "exists").get, "step//@workflow/core/runtime/run@5.0.0-beta.48//Run#exists");
127126
127819
  (function(__wf_fn, __wf_id) {
127127
127820
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
127128
127821
  __wf_reg.set(__wf_id, __wf_fn);
@@ -127131,7 +127824,7 @@ var Run = class _Run {
127131
127824
  value: "status",
127132
127825
  configurable: true
127133
127826
  });
127134
- })(Object.getOwnPropertyDescriptor(Run.prototype, "status").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#status");
127827
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "status").get, "step//@workflow/core/runtime/run@5.0.0-beta.48//Run#status");
127135
127828
  (function(__wf_fn, __wf_id) {
127136
127829
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
127137
127830
  __wf_reg.set(__wf_id, __wf_fn);
@@ -127140,7 +127833,7 @@ var Run = class _Run {
127140
127833
  value: "returnValue",
127141
127834
  configurable: true
127142
127835
  });
127143
- })(Object.getOwnPropertyDescriptor(Run.prototype, "returnValue").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#returnValue");
127836
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "returnValue").get, "step//@workflow/core/runtime/run@5.0.0-beta.48//Run#returnValue");
127144
127837
  (function(__wf_fn, __wf_id) {
127145
127838
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
127146
127839
  __wf_reg.set(__wf_id, __wf_fn);
@@ -127149,7 +127842,7 @@ var Run = class _Run {
127149
127842
  value: "workflowName",
127150
127843
  configurable: true
127151
127844
  });
127152
- })(Object.getOwnPropertyDescriptor(Run.prototype, "workflowName").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#workflowName");
127845
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "workflowName").get, "step//@workflow/core/runtime/run@5.0.0-beta.48//Run#workflowName");
127153
127846
  (function(__wf_fn, __wf_id) {
127154
127847
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
127155
127848
  __wf_reg.set(__wf_id, __wf_fn);
@@ -127158,7 +127851,7 @@ var Run = class _Run {
127158
127851
  value: "createdAt",
127159
127852
  configurable: true
127160
127853
  });
127161
- })(Object.getOwnPropertyDescriptor(Run.prototype, "createdAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#createdAt");
127854
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "createdAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.48//Run#createdAt");
127162
127855
  (function(__wf_fn, __wf_id) {
127163
127856
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
127164
127857
  __wf_reg.set(__wf_id, __wf_fn);
@@ -127167,7 +127860,7 @@ var Run = class _Run {
127167
127860
  value: "startedAt",
127168
127861
  configurable: true
127169
127862
  });
127170
- })(Object.getOwnPropertyDescriptor(Run.prototype, "startedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#startedAt");
127863
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "startedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.48//Run#startedAt");
127171
127864
  (function(__wf_fn, __wf_id) {
127172
127865
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
127173
127866
  __wf_reg.set(__wf_id, __wf_fn);
@@ -127176,7 +127869,7 @@ var Run = class _Run {
127176
127869
  value: "completedAt",
127177
127870
  configurable: true
127178
127871
  });
127179
- })(Object.getOwnPropertyDescriptor(Run.prototype, "completedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.47//Run#completedAt");
127872
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "completedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.48//Run#completedAt");
127180
127873
  (function(__wf_cls, __wf_id) {
127181
127874
  var __wf_sym = /* @__PURE__ */ Symbol.for("workflow-class-registry"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
127182
127875
  __wf_reg.set(__wf_id, __wf_cls);
@@ -127186,7 +127879,7 @@ var Run = class _Run {
127186
127879
  enumerable: false,
127187
127880
  configurable: false
127188
127881
  });
127189
- })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.47//Run");
127882
+ })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.48//Run");
127190
127883
  async function fetch2(...args) {
127191
127884
  return globalThis.fetch(...args);
127192
127885
  }
@@ -128089,10 +128782,11 @@ init_constants3();
128089
128782
  init_helpers3();
128090
128783
  init_replay_recovery_reporter();
128091
128784
  init_unserializable_step();
128092
- async function createHookEvent({ runId, hookEvent, queueItem, requestId, createEvent }) {
128785
+ async function createHookEvent({ runId, hookEvent, queueItem, requestId, sinceCursor, createEvent }) {
128093
128786
  try {
128094
128787
  const result2 = await createEvent(hookEvent, {
128095
- requestId
128788
+ requestId,
128789
+ ...sinceCursor === void 0 ? {} : { sinceCursor }
128096
128790
  });
128097
128791
  if (result2.event?.eventType === "hook_conflict") {
128098
128792
  return {
@@ -128153,7 +128847,10 @@ async function handleSuspension({ suspension, world, run: run3, span, requestId,
128153
128847
  const reporter = replayRecoveryReporter ?? ReplayRecoveryReporter.inert();
128154
128848
  const createEvent = /* @__PURE__ */ __name((data, params) => reporter.withEventCreate(params, (p) => world.events.create(runId, data, p)), "createEvent");
128155
128849
  let reportedEvents = 0;
128850
+ let guardedWrites = 0;
128851
+ let deltaAbsorbed = false;
128156
128852
  const createGuarded = /* @__PURE__ */ __name(async (data, params) => {
128853
+ guardedWrites++;
128157
128854
  if (!eventLog) {
128158
128855
  return createEvent(data, params);
128159
128856
  }
@@ -128162,6 +128859,13 @@ async function handleSuspension({ suspension, world, run: run3, span, requestId,
128162
128859
  ...params,
128163
128860
  ...slotSnapshotParams(log.events)
128164
128861
  });
128862
+ if (typeof params?.sinceCursor === "string") {
128863
+ if (log.cursor === params.sinceCursor && result2.events !== void 0 && result2.hasMore !== true) {
128864
+ appendEventLog(log, { events: result2.events, cursor: result2.cursor });
128865
+ deltaAbsorbed = true;
128866
+ }
128867
+ return result2;
128868
+ }
128165
128869
  const report = absorbSkippedSlotReport(log.events, result2);
128166
128870
  reportedEvents += report.added;
128167
128871
  if (report.truncated) {
@@ -128249,9 +128953,10 @@ async function handleSuspension({ suspension, world, run: run3, span, requestId,
128249
128953
  }
128250
128954
  }
128251
128955
  __name(disposeHook, "disposeHook");
128252
- let hasHookConflict = false;
128253
- let hasAwaitedHookCreation = false;
128956
+ const hookConflictCorrelationIds = [];
128957
+ const awaitedHookCorrelationIds = [];
128254
128958
  let hookCreationMs = 0;
128959
+ const hookDeltaCursor = hooksNeedingCreation.length === 1 && typeof eventLog?.cursor === "string" ? eventLog.cursor : void 0;
128255
128960
  if (hookItemsByToken.size > 0) {
128256
128961
  const hookPhaseStart = Date.now();
128257
128962
  await ensureRunReady();
@@ -128280,10 +128985,15 @@ async function handleSuspension({ suspension, world, run: run3, span, requestId,
128280
128985
  hookEvent,
128281
128986
  queueItem,
128282
128987
  requestId,
128988
+ sinceCursor: hookDeltaCursor,
128283
128989
  createEvent: createGuarded
128284
128990
  });
128285
- hasHookConflict ||= result2.hasHookConflict;
128286
- hasAwaitedHookCreation ||= result2.hasAwaitedHookCreation;
128991
+ if (result2.hasHookConflict) {
128992
+ hookConflictCorrelationIds.push(queueItem.correlationId);
128993
+ }
128994
+ if (result2.hasAwaitedHookCreation) {
128995
+ awaitedHookCorrelationIds.push(queueItem.correlationId);
128996
+ }
128287
128997
  creationConflicted = result2.hasHookConflict;
128288
128998
  }
128289
128999
  if (queueItem.disposed && !creationConflicted) {
@@ -128406,7 +129116,7 @@ async function handleSuspension({ suspension, world, run: run3, span, requestId,
128406
129116
  failedStepCorrelationIds.add(queueItem.correlationId);
128407
129117
  lazyInlineCorrelationIds.delete(queueItem.correlationId);
128408
129118
  }, "finalizeUnserializableStep");
128409
- const lazyInlineCorrelationIds = new Set(hasAwaitedHookCreation === false ? stepItems.filter((item) => stepsNeedingCreation.has(item.correlationId)).slice(0, getMaxInlineSteps()).map((item) => item.correlationId) : []);
129119
+ const lazyInlineCorrelationIds = new Set(awaitedHookCorrelationIds.length === 0 ? stepItems.filter((item) => stepsNeedingCreation.has(item.correlationId)).slice(0, getMaxInlineSteps()).map((item) => item.correlationId) : []);
128410
129120
  const lazyInlineByCorrelationId = /* @__PURE__ */ new Map();
128411
129121
  const ops = [];
128412
129122
  const queuedStepCorrelationIds = /* @__PURE__ */ new Set();
@@ -128903,11 +129613,18 @@ async function handleSuspension({ suspension, world, run: run3, span, requestId,
128903
129613
  inlineClaims,
128904
129614
  batchCommittedSlotCeiling,
128905
129615
  deferredBatchWork,
128906
- // On hook conflict the caller re-invokes immediately and never reads
128907
- // the wait timeout, so don't report one.
128908
- waitTimeout: hasHookConflict ? void 0 : soonestWait,
128909
- hasHookConflict,
128910
- hasAwaitedHookCreation,
129616
+ // On hook conflict the caller advances the workflow over the conflict
129617
+ // before scheduling anything and never reads the wait timeout, so don't
129618
+ // report one. The next pass, which sees the conflict settled, reports it.
129619
+ waitTimeout: hookConflictCorrelationIds.length > 0 ? void 0 : soonestWait,
129620
+ hasHookConflict: hookConflictCorrelationIds.length > 0,
129621
+ hookConflictCorrelationIds,
129622
+ hasAwaitedHookCreation: awaitedHookCorrelationIds.length > 0,
129623
+ awaitedHookCorrelationIds,
129624
+ // The delta accounts for the whole log only if the write that returned it
129625
+ // was this suspension's only one — anything written after it landed above
129626
+ // the delta and is missing from the caller's log.
129627
+ eventLogCarriedForward: deltaAbsorbed && guardedWrites === 1,
128911
129628
  hasAttributeEvents: attributeItems.length > 0,
128912
129629
  hasHookEvents: hooksNeedingCreation.length > 0,
128913
129630
  hookCreationMs,
@@ -130092,7 +130809,6 @@ __name(createCreateHook, "createCreateHook");
130092
130809
  init_dist7();
130093
130810
  init_dist5();
130094
130811
  init_events_consumer2();
130095
- init_global2();
130096
130812
  init_private2();
130097
130813
  function createSleep(ctx) {
130098
130814
  return /* @__PURE__ */ __name(async function sleepImpl(param) {
@@ -130107,9 +130823,7 @@ function createSleep(ctx) {
130107
130823
  ctx.invocationsQueue.set(correlationId, waitItem);
130108
130824
  ctx.eventsConsumer.subscribe((event) => {
130109
130825
  if (!event) {
130110
- scheduleWhenIdle(ctx, () => {
130111
- ctx.onWorkflowError(new WorkflowSuspension2(ctx.invocationsQueue, ctx.globalThis));
130112
- });
130826
+ scheduleWorkflowSuspension(ctx);
130113
130827
  return EventConsumerResult2.NotConsumed;
130114
130828
  }
130115
130829
  if (event.correlationId !== correlationId) {
@@ -131108,9 +131822,9 @@ var Run2 = class _Run2 {
131108
131822
  return this.#encryptionKeyPromise;
131109
131823
  }
131110
131824
  /**
131111
- * Defer fetching the run and its encryption key until serialized stream data
131112
- * is actually read. An empty or metadata-only stream must not start an
131113
- * unobserved run lookup.
131825
+ * Defers fetching the run and its encryption key until a readable is first
131826
+ * consumed. The first pull prefetches it so an encrypted first frame can join
131827
+ * the lookup; this also applies to an empty consumed stream.
131114
131828
  * @internal
131115
131829
  */
131116
131830
  #getEncryptionKeyLazily() {
@@ -131223,10 +131937,7 @@ var Run2 = class _Run2 {
131223
131937
  const { ops = [], global: global2 = globalThis, startIndex, namespace } = options;
131224
131938
  const name = getWorkflowRunStreamId2(this.runId, namespace);
131225
131939
  const encryptionKey = this.#getEncryptionKeyLazily();
131226
- const stream = getExternalRevivers2(global2, ops, this.runId, encryptionKey).ReadableStream({
131227
- name,
131228
- startIndex
131229
- });
131940
+ const stream = getRunReadableStream2(global2, ops, this.runId, name, startIndex, encryptionKey);
131230
131941
  const worldPromise = this.#lazyWorldPromise;
131231
131942
  const runId = this.runId;
131232
131943
  return Object.assign(stream, {
@@ -131463,7 +132174,7 @@ function openHookAndWaitState(events) {
131463
132174
  return { openHook: hooks.size > 0, openWait: waits.size > 0 };
131464
132175
  }
131465
132176
  __name(openHookAndWaitState, "openHookAndWaitState");
131466
- function getRetentionDecision({ suspension, serializationBlockerCount, hasOpenWait }) {
132177
+ function getRetentionDecision({ suspension, serializationBlockerCount, hookContinuation = false }) {
131467
132178
  if (!isVmRetentionEnabled()) {
131468
132179
  return { retain: false, reason: "disabled" };
131469
132180
  }
@@ -131473,27 +132184,12 @@ function getRetentionDecision({ suspension, serializationBlockerCount, hasOpenWa
131473
132184
  reason: "serialization_executed_workflow_code"
131474
132185
  };
131475
132186
  }
132187
+ if (hookContinuation) {
132188
+ return { retain: true };
132189
+ }
131476
132190
  if (suspension.stepCount === 0 && suspension.attributeCount === 0) {
131477
132191
  return { retain: false, reason: "no_replay_driver" };
131478
132192
  }
131479
- if (!suspension.items.every((item) => {
131480
- switch (item.type) {
131481
- case "step":
131482
- case "hook":
131483
- case "attribute":
131484
- return true;
131485
- case "wait":
131486
- return false;
131487
- default:
131488
- item;
131489
- throw new Error("Unknown workflow suspension item");
131490
- }
131491
- })) {
131492
- return { retain: false, reason: "unsupported_suspension_item" };
131493
- }
131494
- if (hasOpenWait()) {
131495
- return { retain: false, reason: "open_wait" };
131496
- }
131497
132193
  return { retain: true };
131498
132194
  }
131499
132195
  __name(getRetentionDecision, "getRetentionDecision");
@@ -131522,11 +132218,6 @@ function nextEventLogLoad(log) {
131522
132218
  };
131523
132219
  }
131524
132220
  __name(nextEventLogLoad, "nextEventLogLoad");
131525
- function appendEventLog(log, appended) {
131526
- appendUniqueEvents(log.events, appended.events);
131527
- log.cursor = appended.cursor ?? log.cursor;
131528
- }
131529
- __name(appendEventLog, "appendEventLog");
131530
132221
  async function getMaxInlineDurationMs(world, invocationStartTime) {
131531
132222
  const rawEnvOverride = process.env.WORKFLOW_V2_TIMEOUT_MS;
131532
132223
  if (rawEnvOverride !== void 0 && rawEnvOverride !== "") {
@@ -132398,6 +133089,7 @@ function workflowEntrypoint(workflowCode2, options) {
132398
133089
  }
132399
133090
  }
132400
133091
  let retainedSession = null;
133092
+ const continuedHookIds = /* @__PURE__ */ new Set();
132401
133093
  while (true) {
132402
133094
  loopIteration++;
132403
133095
  if (replayBudget.isExhausted()) {
@@ -132740,7 +133432,10 @@ function workflowEntrypoint(workflowCode2, options) {
132740
133432
  const retentionDecision = retainedSession ? getRetentionDecision({
132741
133433
  suspension: err,
132742
133434
  serializationBlockerCount: suspensionResult.serializationBlockerCount,
132743
- hasOpenWait: /* @__PURE__ */ __name(() => openHookWait.value.openWait, "hasOpenWait")
133435
+ // This suspension committed the event a hook's
133436
+ // own awaiter is parked on; the continuation
133437
+ // below drives the next iteration in-process.
133438
+ hookContinuation: suspensionResult.hasAwaitedHookCreation || suspensionResult.hasHookConflict
132744
133439
  }) : void 0;
132745
133440
  if (retentionDecision?.retain === false) {
132746
133441
  retainedSession = null;
@@ -132765,7 +133460,37 @@ function workflowEntrypoint(workflowCode2, options) {
132765
133460
  } : {},
132766
133461
  ...suspensionResult.serializationBlockerCount > 0 ? serializationBlockerLogMetadata(suspensionResult.serializationBlockers, suspensionResult.serializationBlockerCount) : {}
132767
133462
  });
133463
+ const continueOverHookWrite = /* @__PURE__ */ __name((hookIds, settles) => {
133464
+ if (!retainedSession)
133465
+ return false;
133466
+ const fresh = hookIds.filter((id) => !continuedHookIds.has(id));
133467
+ if (fresh.length === 0)
133468
+ return false;
133469
+ for (const id of fresh) {
133470
+ continuedHookIds.add(id);
133471
+ }
133472
+ const resumeWithoutRead = suspensionResult.eventLogCarriedForward && !openHookWait.value.openWait;
133473
+ if (!resumeWithoutRead) {
133474
+ assert6(eventLog.type === "ready");
133475
+ eventLog = nextEventLogLoad(eventLog);
133476
+ }
133477
+ runtimeLogger2.debug("Continuing over a hook write in-process", {
133478
+ workflowRunId: runId,
133479
+ loopIteration,
133480
+ settles,
133481
+ hookIds: fresh,
133482
+ carriedForward: suspensionResult.eventLogCarriedForward,
133483
+ readBeforeResume: !resumeWithoutRead
133484
+ });
133485
+ span?.setAttributes({
133486
+ "workflow.hook_write_continuations": continuedHookIds.size
133487
+ });
133488
+ return true;
133489
+ }, "continueOverHookWrite");
132768
133490
  if (suspensionResult.hasHookConflict) {
133491
+ if (continueOverHookWrite(suspensionResult.hookConflictCorrelationIds, "hook_conflict")) {
133492
+ continue;
133493
+ }
132769
133494
  return await reinvoke(0);
132770
133495
  }
132771
133496
  if (suspensionResult.hasAttributeEvents) {
@@ -132893,6 +133618,9 @@ function workflowEntrypoint(workflowCode2, options) {
132893
133618
  suspensionResult.deferredBatchWork
132894
133619
  ]);
132895
133620
  if (suspensionResult.hasAwaitedHookCreation) {
133621
+ if (continueOverHookWrite(suspensionResult.awaitedHookCorrelationIds, "hook_created")) {
133622
+ continue;
133623
+ }
132896
133624
  return await reinvoke(0);
132897
133625
  }
132898
133626
  return;
@@ -133753,6 +134481,30 @@ function parseDurationToDate(param) {
133753
134481
  }
133754
134482
  __name(parseDurationToDate, "parseDurationToDate");
133755
134483
 
134484
+ // ../errors/dist/error-codes.js
134485
+ var RUN_ERROR_CODES = {
134486
+ /** Error thrown in user workflow or step code */
134487
+ USER_ERROR: "USER_ERROR",
134488
+ /** Internal runtime error (missing timestamps, runtime invariant failures) */
134489
+ RUNTIME_ERROR: "RUNTIME_ERROR",
134490
+ /** Event log contains orphaned or mismatched events and cannot be replayed */
134491
+ CORRUPTED_EVENT_LOG: "CORRUPTED_EVENT_LOG",
134492
+ /** One replay could not consume the event log deterministically; retryable */
134493
+ REPLAY_DIVERGENCE: "REPLAY_DIVERGENCE",
134494
+ /** Run exceeded the maximum number of queue deliveries */
134495
+ MAX_DELIVERIES_EXCEEDED: "MAX_DELIVERIES_EXCEEDED",
134496
+ /** Run exceeded the maximum number of events per run */
134497
+ MAX_EVENTS_EXCEEDED: "MAX_EVENTS_EXCEEDED",
134498
+ /** Workflow replay exceeded the maximum allowed duration */
134499
+ REPLAY_TIMEOUT: "REPLAY_TIMEOUT",
134500
+ /** Workflow stream infrastructure failed while reading or writing data */
134501
+ STREAM_ERROR: "STREAM_ERROR",
134502
+ /** World response violated the SDK contract and cannot be retried safely */
134503
+ WORLD_CONTRACT_ERROR: "WORLD_CONTRACT_ERROR",
134504
+ /** Run was delivered to a deployment other than the one it is pinned to */
134505
+ DEPLOYMENT_MISMATCH: "DEPLOYMENT_MISMATCH"
134506
+ };
134507
+
133756
134508
  // ../errors/dist/index.js
133757
134509
  var BASE_URL = "https://workflow-sdk.dev/err";
133758
134510
  function isError(value) {
@@ -133827,6 +134579,36 @@ Caused by: \${options.cause.stack}\`;
133827
134579
  return isError(value) && value.name === "WorkflowError";
133828
134580
  }
133829
134581
  };
134582
+ var WorkflowWorldError = class extends WorkflowError {
134583
+ static {
134584
+ __name(this, "WorkflowWorldError");
134585
+ }
134586
+ status;
134587
+ code;
134588
+ url;
134589
+ /** Retry-After value in seconds, present on 429 and 425 responses */
134590
+ retryAfter;
134591
+ /**
134592
+ * The offending argument, present on client-side validation failures
134593
+ * (\`code: 'INVALID_ARGUMENT'\`). Lets a caller correct the specific
134594
+ * parameter without parsing the message.
134595
+ */
134596
+ field;
134597
+ constructor(message, options) {
134598
+ super(message, {
134599
+ cause: options?.cause
134600
+ });
134601
+ this.name = "WorkflowWorldError";
134602
+ this.status = options?.status;
134603
+ this.code = options?.code;
134604
+ this.url = options?.url;
134605
+ this.retryAfter = options?.retryAfter;
134606
+ this.field = options?.field;
134607
+ }
134608
+ static is(value) {
134609
+ return isError(value) && value.name === "WorkflowWorldError";
134610
+ }
134611
+ };
133830
134612
  var WorkflowRuntimeError = class extends WorkflowError {
133831
134613
  static {
133832
134614
  __name(this, "WorkflowRuntimeError");
@@ -133881,6 +134663,23 @@ var HookConflictError = class extends WorkflowError {
133881
134663
  return isError(value) && value.name === "HookConflictError";
133882
134664
  }
133883
134665
  };
134666
+ var StreamError = class extends WorkflowWorldError {
134667
+ static {
134668
+ __name(this, "StreamError");
134669
+ }
134670
+ constructor(message, options) {
134671
+ super(message, {
134672
+ code: RUN_ERROR_CODES.STREAM_ERROR,
134673
+ cause: options?.cause,
134674
+ url: options?.url,
134675
+ status: options?.status
134676
+ });
134677
+ this.name = "StreamError";
134678
+ }
134679
+ static is(value) {
134680
+ return isError(value) && value.name === "StreamError";
134681
+ }
134682
+ };
133884
134683
  var FatalError = class extends Error {
133885
134684
  static {
133886
134685
  __name(this, "FatalError");
@@ -133921,6 +134720,7 @@ var FATAL_ERROR_KEY = /* @__PURE__ */ Symbol.for("@workflow/errors//FatalError")
133921
134720
  var RETRYABLE_ERROR_KEY = /* @__PURE__ */ Symbol.for("@workflow/errors//RetryableError");
133922
134721
  var HOOK_CONFLICT_ERROR_KEY = /* @__PURE__ */ Symbol.for("@workflow/errors//HookConflictError");
133923
134722
  var RUNTIME_DECRYPTION_ERROR_KEY = /* @__PURE__ */ Symbol.for("@workflow/errors//RuntimeDecryptionError");
134723
+ var STREAM_ERROR_KEY = /* @__PURE__ */ Symbol.for("@workflow/errors//StreamError");
133924
134724
  if (typeof globalThis !== "undefined") {
133925
134725
  if (!Object.hasOwn(globalThis, FATAL_ERROR_KEY)) {
133926
134726
  Object.defineProperty(globalThis, FATAL_ERROR_KEY, {
@@ -133954,6 +134754,14 @@ if (typeof globalThis !== "undefined") {
133954
134754
  configurable: false
133955
134755
  });
133956
134756
  }
134757
+ if (!Object.hasOwn(globalThis, STREAM_ERROR_KEY)) {
134758
+ Object.defineProperty(globalThis, STREAM_ERROR_KEY, {
134759
+ value: StreamError,
134760
+ writable: false,
134761
+ enumerable: false,
134762
+ configurable: false
134763
+ });
134764
+ }
133957
134765
  }
133958
134766
 
133959
134767
  // ../core/dist/symbols.js
@@ -134038,10 +134846,10 @@ var Run = class _Run {
134038
134846
  return this.getReadable();
134039
134847
  }
134040
134848
  };
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");
134849
+ Run.prototype["wakeUp"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.48//Run#wakeUp");
134850
+ Run.prototype["cancel"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.48//Run#cancel");
134851
+ Run.prototype["getReadable"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.48//Run#getReadable");
134852
+ var __step_Run$exists = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.48//Run#exists");
134045
134853
  Object.defineProperty(Run.prototype, "exists", {
134046
134854
  get() {
134047
134855
  return __step_Run$exists.call(this);
@@ -134049,7 +134857,7 @@ Object.defineProperty(Run.prototype, "exists", {
134049
134857
  configurable: true,
134050
134858
  enumerable: false
134051
134859
  });
134052
- var __step_Run$status = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#status");
134860
+ var __step_Run$status = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.48//Run#status");
134053
134861
  Object.defineProperty(Run.prototype, "status", {
134054
134862
  get() {
134055
134863
  return __step_Run$status.call(this);
@@ -134057,7 +134865,7 @@ Object.defineProperty(Run.prototype, "status", {
134057
134865
  configurable: true,
134058
134866
  enumerable: false
134059
134867
  });
134060
- var __step_Run$returnValue = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#returnValue");
134868
+ var __step_Run$returnValue = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.48//Run#returnValue");
134061
134869
  Object.defineProperty(Run.prototype, "returnValue", {
134062
134870
  get() {
134063
134871
  return __step_Run$returnValue.call(this);
@@ -134065,7 +134873,7 @@ Object.defineProperty(Run.prototype, "returnValue", {
134065
134873
  configurable: true,
134066
134874
  enumerable: false
134067
134875
  });
134068
- var __step_Run$workflowName = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#workflowName");
134876
+ var __step_Run$workflowName = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.48//Run#workflowName");
134069
134877
  Object.defineProperty(Run.prototype, "workflowName", {
134070
134878
  get() {
134071
134879
  return __step_Run$workflowName.call(this);
@@ -134073,7 +134881,7 @@ Object.defineProperty(Run.prototype, "workflowName", {
134073
134881
  configurable: true,
134074
134882
  enumerable: false
134075
134883
  });
134076
- var __step_Run$createdAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#createdAt");
134884
+ var __step_Run$createdAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.48//Run#createdAt");
134077
134885
  Object.defineProperty(Run.prototype, "createdAt", {
134078
134886
  get() {
134079
134887
  return __step_Run$createdAt.call(this);
@@ -134081,7 +134889,7 @@ Object.defineProperty(Run.prototype, "createdAt", {
134081
134889
  configurable: true,
134082
134890
  enumerable: false
134083
134891
  });
134084
- var __step_Run$startedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#startedAt");
134892
+ var __step_Run$startedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.48//Run#startedAt");
134085
134893
  Object.defineProperty(Run.prototype, "startedAt", {
134086
134894
  get() {
134087
134895
  return __step_Run$startedAt.call(this);
@@ -134089,7 +134897,7 @@ Object.defineProperty(Run.prototype, "startedAt", {
134089
134897
  configurable: true,
134090
134898
  enumerable: false
134091
134899
  });
134092
- var __step_Run$completedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.47//Run#completedAt");
134900
+ var __step_Run$completedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.48//Run#completedAt");
134093
134901
  Object.defineProperty(Run.prototype, "completedAt", {
134094
134902
  get() {
134095
134903
  return __step_Run$completedAt.call(this);
@@ -134106,7 +134914,7 @@ Object.defineProperty(Run.prototype, "completedAt", {
134106
134914
  enumerable: false,
134107
134915
  configurable: false
134108
134916
  });
134109
- })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.47//Run");
134917
+ })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.48//Run");
134110
134918
 
134111
134919
  // ../core/dist/workflow/create-hook.js
134112
134920
  aliasSerializationClass(RUN_CLASS_ID, Run);
@@ -138736,7 +139544,7 @@ globalThis.__private_workflows.set("workflow//./workflows/inline-execution//hook
138736
139544
  var latestNoOpWarning = globalSingleton("@workflow/core//latestNoOpWarning", 1, () => ({
138737
139545
  warned: false
138738
139546
  }));
138739
- var start = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/start@5.0.0-beta.47//start");
139547
+ var start = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/start@5.0.0-beta.48//start");
138740
139548
 
138741
139549
  // workflows/lineage.ts
138742
139550
  var noop = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//./workflows/lineage//noop");