@workflow/web 5.0.0-beta.6 → 5.0.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. package/build/client/assets/{encryption-DU49MAQV.js → encryption-C69WMRfh.js} +11 -5
  2. package/build/client/assets/{highlighted-body-B3W2YXNL-BZLzBNxn.js → highlighted-body-B3W2YXNL-Cq4feDhL.js} +1 -1
  3. package/build/client/assets/{home-DmK2qlF4.js → home-B-DWbULo.js} +2 -2
  4. package/build/client/assets/{manifest-f8f46e3c.js → manifest-21016363.js} +1 -1
  5. package/build/client/assets/{mermaid-3ZIDBTTL-D3hhpLut.js → mermaid-3ZIDBTTL-PK-k2mDG.js} +188 -102
  6. package/build/client/assets/root-B527kgKt.css +1 -0
  7. package/build/client/assets/{root-DCSDR-Tx.js → root-DDT0W3fG.js} +1 -1
  8. package/build/client/assets/{run-detail-qu2t8u4x.js → run-detail-COyTZwjr.js} +30 -6
  9. package/build/client/assets/server-build-BUmla00D.css +1 -0
  10. package/build/client/assets/{workflow-graph-viewer-Bl8eU-PY.js → workflow-graph-viewer-CVUKAMV1.js} +1 -1
  11. package/build/server/assets/{app-C_Lhht8k.js → app-CASBD2Jz.js} +1 -1
  12. package/build/server/assets/{highlighted-body-B3W2YXNL-DOOlKIMb.js → highlighted-body-B3W2YXNL-DtYGrm0G.js} +2 -2
  13. package/build/server/assets/{index-CRYPN_tt.js → index-B_Gtun0B.js} +3 -3
  14. package/build/server/assets/{mermaid-3ZIDBTTL-CglyhPap.js → mermaid-3ZIDBTTL-D37Y2lwn.js} +2 -2
  15. package/build/server/assets/{server-build-CeQwCbX_.js → server-build-BZS28Q46.js} +1165 -973
  16. package/build/server/assets/{token-CZpVopko.js → token-98GkKm4t.js} +2 -2
  17. package/build/server/assets/{token-util-DUvMx9Gj.js → token-util-CHxt50WW.js} +2 -2
  18. package/build/server/index.js +1 -1
  19. package/package.json +6 -6
  20. package/build/client/assets/root-5XHFuftH.css +0 -1
  21. package/build/client/assets/server-build-olrGumlh.css +0 -1
@@ -14,7 +14,7 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
14
14
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
15
15
  var __superGet = (cls, obj, key) => __reflectGet(__getProtoOf(cls), key, obj);
16
16
  var _a2, _b, _c, _listeners, _onabort, _reader, _root, _hasMagic, _uflag, _parts, _parent, _parentIndex, _negs, _filledNegs, _options, _toString, _emptyExt, _AST_instances, fillNegs_fn, _AST_static, parseAST_fn, canAdoptWithSpace_fn, canAdopt_fn, canAdoptType_fn, adoptWithSpace_fn, adopt_fn, canUsurpType_fn, canUsurp_fn, usurp_fn, flatten_fn, partsToRegExp_fn, parseGlob_fn, _Minimatch_instances, matchGlobstar_fn, matchGlobStarBodySections_fn, matchOne_fn, _worldPromise, _Run_instances, lazyWorldPromise_get, _encryptionKeyPromise, _resilientStart, getEncryptionKey_fn, pollReturnValue_fn;
17
- import { a as requireReact, S as ServerRouter, c as createReadableStreamFromReadable, r as reactExports, g as getDefaultExportFromCjs, R as React, b as ReactExports, w as withComponentProps, d as withErrorBoundaryProps, M as Meta, L as Links, e as ScrollRestoration, f as Scripts, O as Outlet, u as useNavigate, h as useSearchParams, i as Link$1, j as useRouteError, k as isRouteErrorResponse, l as useLocation, m as useParams } from "./app-C_Lhht8k.js";
17
+ import { a as requireReact, S as ServerRouter, c as createReadableStreamFromReadable, r as reactExports, g as getDefaultExportFromCjs, R as React, b as ReactExports, w as withComponentProps, d as withErrorBoundaryProps, M as Meta, L as Links, e as ScrollRestoration, f as Scripts, O as Outlet, u as useNavigate, h as useSearchParams, i as Link$1, j as useRouteError, k as isRouteErrorResponse, l as useLocation, m as useParams } from "./app-CASBD2Jz.js";
18
18
  import require$$0$3, { PassThrough } from "node:stream";
19
19
  import require$$0 from "util";
20
20
  import require$$1 from "crypto";
@@ -48635,6 +48635,7 @@ const StepCompletedEventSchema = BaseEventSchema.extend({
48635
48635
  eventType: literal("step_completed"),
48636
48636
  correlationId: string$3(),
48637
48637
  eventData: object$1({
48638
+ stepName: string$3().optional(),
48638
48639
  result: SerializedDataSchema
48639
48640
  })
48640
48641
  });
@@ -48642,6 +48643,7 @@ const StepFailedEventSchema = BaseEventSchema.extend({
48642
48643
  eventType: literal("step_failed"),
48643
48644
  correlationId: string$3(),
48644
48645
  eventData: object$1({
48646
+ stepName: string$3().optional(),
48645
48647
  // The thrown value, serialized via the workflow serialization pipeline.
48646
48648
  // Can be any JavaScript value (string, number, object, Error, etc.)
48647
48649
  error: SerializedDataSchema
@@ -48651,6 +48653,7 @@ const StepRetryingEventSchema = BaseEventSchema.extend({
48651
48653
  eventType: literal("step_retrying"),
48652
48654
  correlationId: string$3(),
48653
48655
  eventData: object$1({
48656
+ stepName: string$3().optional(),
48654
48657
  // The thrown value, serialized via the workflow serialization pipeline.
48655
48658
  // Can be any JavaScript value (string, number, object, Error, etc.)
48656
48659
  error: SerializedDataSchema,
@@ -48661,6 +48664,7 @@ const StepStartedEventSchema = BaseEventSchema.extend({
48661
48664
  eventType: literal("step_started"),
48662
48665
  correlationId: string$3(),
48663
48666
  eventData: object$1({
48667
+ stepName: string$3().optional(),
48664
48668
  attempt: number$3().optional()
48665
48669
  }).optional()
48666
48670
  });
@@ -48686,12 +48690,16 @@ const HookReceivedEventSchema = BaseEventSchema.extend({
48686
48690
  eventType: literal("hook_received"),
48687
48691
  correlationId: string$3(),
48688
48692
  eventData: object$1({
48693
+ token: string$3().optional(),
48689
48694
  payload: SerializedDataSchema
48690
48695
  })
48691
48696
  });
48692
48697
  const HookDisposedEventSchema = BaseEventSchema.extend({
48693
48698
  eventType: literal("hook_disposed"),
48694
- correlationId: string$3()
48699
+ correlationId: string$3(),
48700
+ eventData: object$1({
48701
+ token: string$3().optional()
48702
+ }).optional()
48695
48703
  });
48696
48704
  const HookConflictEventSchema = BaseEventSchema.extend({
48697
48705
  eventType: literal("hook_conflict"),
@@ -48712,7 +48720,10 @@ const WaitCreatedEventSchema = BaseEventSchema.extend({
48712
48720
  });
48713
48721
  const WaitCompletedEventSchema = BaseEventSchema.extend({
48714
48722
  eventType: literal("wait_completed"),
48715
- correlationId: string$3()
48723
+ correlationId: string$3(),
48724
+ eventData: object$1({
48725
+ resumeAt: date$2().optional()
48726
+ }).optional()
48716
48727
  });
48717
48728
  const RunCreatedEventSchema = BaseEventSchema.extend({
48718
48729
  eventType: literal("run_created"),
@@ -48997,7 +49008,7 @@ object$1({
48997
49008
  message: string$3(),
48998
49009
  stack: string$3().optional(),
48999
49010
  code: string$3().optional()
49000
- // Populated with RunErrorCode values (USER_ERROR, RUNTIME_ERROR) for run_failed events
49011
+ // Populated with RunErrorCode values (USER_ERROR, RUNTIME_ERROR, etc.) for run_failed events
49001
49012
  });
49002
49013
  const SPEC_VERSION_LEGACY = 1;
49003
49014
  const SPEC_VERSION_SUPPORTS_EVENT_SOURCING = 2;
@@ -80051,7 +80062,7 @@ var tn = f("block", "before:content-[counter(line)]", "before:inline-block", "be
80051
80062
  var et = ({ className: e, language: t, style: o, isIncomplete: n, ...s2 }) => jsxRuntimeExports.jsx("div", { className: f("my-4 flex w-full flex-col gap-2 rounded-xl border border-border bg-sidebar p-2", e), "data-incomplete": n || void 0, "data-language": t, "data-streamdown": "code-block", style: { contentVisibility: "auto", containIntrinsicSize: "auto 200px", ...o }, ...s2 });
80052
80063
  var Se = reactExports.createContext({ code: "" }), de = () => reactExports.useContext(Se);
80053
80064
  var ot = ({ language: e }) => jsxRuntimeExports.jsx("div", { className: "flex h-8 items-center text-muted-foreground text-xs", "data-language": e, "data-streamdown": "code-block-header", children: jsxRuntimeExports.jsx("span", { className: "ml-1 font-mono lowercase", children: e }) });
80054
- var cn$1 = /\n+$/, dn = reactExports.lazy(() => import("./highlighted-body-B3W2YXNL-DOOlKIMb.js").then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
80065
+ var cn$1 = /\n+$/, dn = reactExports.lazy(() => import("./highlighted-body-B3W2YXNL-DtYGrm0G.js").then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
80055
80066
  let i = reactExports.useMemo(() => e.replace(cn$1, ""), [e]), c = reactExports.useMemo(() => ({ bg: "transparent", fg: "inherit", tokens: i.split(`
80056
80067
  `).map((a2) => [{ content: a2, color: "inherit", bgColor: "transparent", htmlStyle: {}, offset: 0 }]) }), [i]);
80057
80068
  return jsxRuntimeExports.jsx(Se.Provider, { value: { code: e }, children: jsxRuntimeExports.jsxs(et, { isIncomplete: s2, language: t, children: [jsxRuntimeExports.jsx(ot, { language: t }), n ? jsxRuntimeExports.jsx("div", { className: "pointer-events-none sticky top-2 z-10 -mt-10 flex h-8 items-center justify-end", children: jsxRuntimeExports.jsx("div", { className: "pointer-events-auto flex shrink-0 items-center gap-2 rounded-md border border-sidebar bg-sidebar/80 px-1.5 py-1 supports-[backdrop-filter]:bg-sidebar/70 supports-[backdrop-filter]:backdrop-blur", "data-streamdown": "code-block-actions", children: n }) }) : null, jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: jsxRuntimeExports.jsx(Qe, { className: o, language: t, result: c, ...r2 }), children: jsxRuntimeExports.jsx(dn, { className: o, code: i, language: t, raw: c, ...r2 }) })] }) });
@@ -80373,7 +80384,7 @@ var Dt = ({ children: e, className: t, onDownload: o, onError: n }) => {
80373
80384
  }, []), jsxRuntimeExports.jsxs("div", { className: "relative", ref: i, children: [jsxRuntimeExports.jsx("button", { className: f("cursor-pointer p-1 text-muted-foreground transition-all hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50", t), disabled: c, onClick: () => r2(!s2), title: "Download table", type: "button", children: e != null ? e : jsxRuntimeExports.jsx(Z, { size: 14 }) }), s2 ? jsxRuntimeExports.jsxs("div", { className: "absolute top-full right-0 z-10 mt-1 min-w-[120px] overflow-hidden rounded-md border border-border bg-background shadow-lg", children: [jsxRuntimeExports.jsx("button", { className: "w-full px-3 py-2 text-left text-sm transition-colors hover:bg-muted/40", onClick: () => a2("csv"), title: "Download table as CSV", type: "button", children: "CSV" }), jsxRuntimeExports.jsx("button", { className: "w-full px-3 py-2 text-left text-sm transition-colors hover:bg-muted/40", onClick: () => a2("markdown"), title: "Download table as Markdown", type: "button", children: "Markdown" })] }) : null] });
80374
80385
  };
80375
80386
  var Vt = ({ children: e, className: t, showControls: o, ...n }) => jsxRuntimeExports.jsxs("div", { className: "my-4 flex flex-col gap-2 rounded-lg border border-border bg-sidebar p-2", "data-streamdown": "table-wrapper", children: [o ? jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-1", children: [jsxRuntimeExports.jsx(Ht, {}), jsxRuntimeExports.jsx(Dt, {})] }) : null, jsxRuntimeExports.jsx("div", { className: "border-collapse overflow-x-auto overscroll-y-auto rounded-md border border-border bg-background", children: jsxRuntimeExports.jsx("table", { className: f("w-full divide-y divide-border", t), "data-streamdown": "table", ...n, children: e }) })] });
80376
- var Jn = reactExports.lazy(() => import("./mermaid-3ZIDBTTL-CglyhPap.js").then((e) => ({ default: e.Mermaid }))), Kn = /language-([^\s]+)/;
80387
+ var Jn = reactExports.lazy(() => import("./mermaid-3ZIDBTTL-D37Y2lwn.js").then((e) => ({ default: e.Mermaid }))), Kn = /language-([^\s]+)/;
80377
80388
  function ke(e, t) {
80378
80389
  if (!(e != null && e.position || t != null && t.position)) return true;
80379
80390
  if (!(e != null && e.position && (t != null && t.position))) return false;
@@ -81696,7 +81707,7 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
81696
81707
  const MAP_HEIGHT = 56;
81697
81708
  const TIMELINE_PADDING = 8;
81698
81709
  const ROW_PADDING = 2;
81699
- const ROW_HEIGHT$1 = 24;
81710
+ const ROW_HEIGHT = 24;
81700
81711
  const MARKER_HEIGHT = 24;
81701
81712
  const initialState = {
81702
81713
  root: {
@@ -82432,17 +82443,17 @@ function computeIsNearRightSide(node2, root2, scrollSnapshotRef, isHovered) {
82432
82443
  }
82433
82444
  function computeDefaultLayout(node2, root2, scale, scrollSnapshotRef) {
82434
82445
  const left = (node2.startTime - root2.startTime) * scale;
82435
- let top = MARKER_HEIGHT + (ROW_HEIGHT$1 + ROW_PADDING) * node2.row;
82446
+ let top = MARKER_HEIGHT + (ROW_HEIGHT + ROW_PADDING) * node2.row;
82436
82447
  const actualWidth = node2.duration * scale;
82437
82448
  const width = Math.max(actualWidth, MIN_SPAN_WIDTH);
82438
- let height = ROW_HEIGHT$1;
82449
+ let height = ROW_HEIGHT;
82439
82450
  const isHuge = computeIsHuge(actualWidth);
82440
82451
  const isSmall = computeIsSmall(actualWidth);
82441
82452
  const isHovered = computeIsHovered(node2, isHuge);
82442
82453
  const isExpanded = isHovered || Boolean(node2.isSelected);
82443
82454
  if (isSmall && !isExpanded) {
82444
82455
  height *= 0.4;
82445
- top += (ROW_HEIGHT$1 - height) * 0.5;
82456
+ top += (ROW_HEIGHT - height) * 0.5;
82446
82457
  }
82447
82458
  const isNearRightSide = computeIsNearRightSide(node2, root2, scrollSnapshotRef, isExpanded);
82448
82459
  return {
@@ -82608,8 +82619,8 @@ const SpanComponent = reactExports.memo(function SpanComponent2({ node: node2, r
82608
82619
  layout.isSmall = liveActualWidth < 64;
82609
82620
  layout.isHuge = liveActualWidth >= 500;
82610
82621
  if (!layout.isSmall) {
82611
- layout.height = ROW_HEIGHT$1;
82612
- layout.top = MARKER_HEIGHT + (ROW_HEIGHT$1 + ROW_PADDING) * segmentNode.row;
82622
+ layout.height = ROW_HEIGHT;
82623
+ layout.top = MARKER_HEIGHT + (ROW_HEIGHT + ROW_PADDING) * segmentNode.row;
82613
82624
  }
82614
82625
  }
82615
82626
  reactExports.useEffect(() => {
@@ -82684,7 +82695,7 @@ const SpanEventComponent = reactExports.memo(function SpanEventComponent2({ even
82684
82695
  }
82685
82696
  }
82686
82697
  const left = (event.timestamp - root2.startTime) * scale;
82687
- const top = MARKER_HEIGHT + (ROW_HEIGHT$1 + ROW_PADDING) * node2.row;
82698
+ const top = MARKER_HEIGHT + (ROW_HEIGHT + ROW_PADDING) * node2.row;
82688
82699
  const isLeftAligned = node2.duration <= 0 || (event.timestamp - node2.startTime) / node2.duration < 0.5;
82689
82700
  const customClassName = customSpanEventClassNameFunc ? customSpanEventClassNameFunc(event) : "";
82690
82701
  return jsxRuntimeExports.jsxs("div", { title: phaseDuration ? `${displayLabel} ${timestamp}
@@ -82965,6 +82976,24 @@ function StreamViewer({ streamId: _streamId, chunks, isLive, error: error2, isLo
82965
82976
  color: "var(--ds-gray-600)"
82966
82977
  }, children: isLive ? "Waiting for stream data..." : "Stream is empty" }) : jsxRuntimeExports.jsx(Yr, { ref: virtuosoRef, totalCount: chunks.length, overscan: 10, endReached: () => onScrollEnd == null ? void 0 : onScrollEnd(), itemContent: (index2) => jsxRuntimeExports.jsx("div", { style: { paddingBottom: 8 }, children: jsxRuntimeExports.jsx(ChunkRow, { chunk: chunks[index2], index: index2 }) }), style: { flex: 1, minHeight: 0 } }) })] });
82967
82978
  }
82979
+ const QUERY = "(prefers-reduced-motion: reduce)";
82980
+ const useReducedMotion = () => {
82981
+ const [reduced, setReduced] = reactExports.useState(() => {
82982
+ if (typeof window === "undefined" || !window.matchMedia)
82983
+ return false;
82984
+ return window.matchMedia(QUERY).matches;
82985
+ });
82986
+ reactExports.useEffect(() => {
82987
+ if (typeof window === "undefined" || !window.matchMedia)
82988
+ return;
82989
+ const media = window.matchMedia(QUERY);
82990
+ const onChange = () => setReduced(media.matches);
82991
+ media.addEventListener("change", onChange);
82992
+ onChange();
82993
+ return () => media.removeEventListener("change", onChange);
82994
+ }, []);
82995
+ return reduced;
82996
+ };
82968
82997
  function CopyButton({ copyText, ariaLabel, className }) {
82969
82998
  const [copied, setCopied] = reactExports.useState(false);
82970
82999
  const timeoutRef = reactExports.useRef(null);
@@ -83099,11 +83128,36 @@ function computeSpanGaps(spans, viewStart, viewEnd) {
83099
83128
  return gaps;
83100
83129
  }
83101
83130
  const RESOURCE_COLORS = {
83102
- run: { bar: "var(--ds-blue-700)", errorBar: "var(--ds-red-700)" },
83103
- step: { bar: "var(--ds-green-700)", errorBar: "var(--ds-red-700)" },
83104
- hook: { bar: "var(--ds-amber-700)", errorBar: "var(--ds-red-700)" },
83105
- sleep: { bar: "var(--ds-purple-700)", errorBar: "var(--ds-red-700)" },
83106
- default: { bar: "var(--ds-gray-500)", errorBar: "var(--ds-red-700)" }
83131
+ run: {
83132
+ bg: "var(--ds-blue-200)",
83133
+ border: "var(--ds-blue-500)",
83134
+ errorBg: "var(--ds-red-200)",
83135
+ errorBorder: "var(--ds-red-500)"
83136
+ },
83137
+ step: {
83138
+ bg: "var(--ds-green-200)",
83139
+ border: "var(--ds-green-500)",
83140
+ errorBg: "var(--ds-red-200)",
83141
+ errorBorder: "var(--ds-red-500)"
83142
+ },
83143
+ hook: {
83144
+ bg: "var(--ds-amber-200)",
83145
+ border: "var(--ds-amber-500)",
83146
+ errorBg: "var(--ds-red-200)",
83147
+ errorBorder: "var(--ds-red-500)"
83148
+ },
83149
+ sleep: {
83150
+ bg: "var(--ds-purple-200)",
83151
+ border: "var(--ds-purple-500)",
83152
+ errorBg: "var(--ds-red-200)",
83153
+ errorBorder: "var(--ds-red-500)"
83154
+ },
83155
+ default: {
83156
+ bg: "var(--ds-gray-200)",
83157
+ border: "var(--ds-gray-500)",
83158
+ errorBg: "var(--ds-red-200)",
83159
+ errorBorder: "var(--ds-red-500)"
83160
+ }
83107
83161
  };
83108
83162
  function getResourceColor(resource) {
83109
83163
  return RESOURCE_COLORS[resource] ?? RESOURCE_COLORS.default;
@@ -83579,7 +83633,7 @@ function MiddleTruncate({ value, className, onCopy: onCopyProp, ...props }) {
83579
83633
  const eventStyles = {
83580
83634
  run: { icon: WorkflowIcon, className: "text-blue-900" },
83581
83635
  step: { icon: StepForwardIcon, className: "text-green-900" },
83582
- hook: { icon: WebhookIcon, className: "text-yellow-900" },
83636
+ hook: { icon: WebhookIcon, className: "text-gray-900" },
83583
83637
  sleep: { icon: SleepIcon, className: "text-gray-900" }
83584
83638
  };
83585
83639
  const defaultStyle = {
@@ -83696,87 +83750,143 @@ function SplitPane({ children: children2, className, defaultStartWidth = DEFAULT
83696
83750
  }
83697
83751
  return jsxRuntimeExports.jsxs("div", { ref: containerRef, className: cn$4("grid h-full min-h-0 content-start overflow-x-hidden overflow-y-auto", isDragging && "select-none", className), style: { gridTemplateColumns: colTemplate, height: "100%" }, children: [start2, gutter, end] });
83698
83752
  }
83699
- const SEGMENT_CONFIG = {
83700
- queued: { className: "bg-gray-500" },
83701
- retrying: {
83702
- className: "box-border bg-gray-500"
83703
- },
83704
- waiting: { className: "bg-gray-500" },
83705
- running: { className: "bg-blue-700" },
83706
- failed: { className: "bg-red-700" },
83707
- succeeded: { className: "bg-green-700" },
83708
- sleeping: { className: "bg-gray-500" },
83709
- received: { className: "bg-blue-700" }
83710
- };
83711
- const BAR_HEIGHT_PX = 24;
83712
83753
  const TINY_BAR_BOX_SIZE_PX = 24;
83713
83754
  const TINY_BAR_WIDTH_PX = 4;
83714
- const SEGMENT_GAP_PX = 1;
83715
- const ROW_HEIGHT = 40;
83716
- const CONTAINER_PAD_Y = 8;
83717
- const END_CAP_HEIGHT = 8;
83718
83755
  const TIMELINE_PADDING_PX = 16;
83719
- const ORIGIN_MARKER_EPSILON = 1e-6;
83720
- const DeltaIndicator = reactExports.memo(function DeltaIndicator2({ leftFrac, rightFrac, label, rowIndex }) {
83721
- const centerY = CONTAINER_PAD_Y + (rowIndex + 1) * ROW_HEIGHT;
83722
- return jsxRuntimeExports.jsxs("div", { className: "absolute pointer-events-none", style: {
83723
- left: `${leftFrac * 100}%`,
83724
- width: `${(rightFrac - leftFrac) * 100}%`,
83725
- top: centerY - END_CAP_HEIGHT / 2,
83726
- height: END_CAP_HEIGHT
83727
- }, children: [jsxRuntimeExports.jsx("div", { className: "absolute left-0 top-0 w-px h-full bg-amber-800" }), jsxRuntimeExports.jsx("div", { className: "absolute left-0 right-0 top-1/2 h-px bg-amber-800" }), jsxRuntimeExports.jsx("div", { className: "absolute right-0 top-0 w-px h-full bg-amber-800" }), jsxRuntimeExports.jsx("span", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-label-12 leading-none whitespace-nowrap rounded-xs px-1 py-0.5 text-gray-100 bg-amber-800", children: label })] });
83728
- });
83729
- const TimelineBar = reactExports.memo(function TimelineBar2({ span, viewStart, viewDuration, containerWidth, isSelected, onClick }) {
83756
+ const SEGMENT_CLASSES = {
83757
+ queued: "bg-gray-400 border border-gray-500",
83758
+ retrying: "bg-gray-400 border border-gray-500",
83759
+ waiting: "bg-gray-400 border border-gray-500",
83760
+ running: "bg-blue-200 border border-blue-500",
83761
+ failed: "bg-red-200 border border-red-500",
83762
+ succeeded: "bg-green-200 border border-green-500",
83763
+ sleeping: "bg-gray-400 border border-gray-500",
83764
+ received: "bg-blue-200 border border-blue-500"
83765
+ };
83766
+ const TIMELINE_INSET_STYLE = {
83767
+ left: TIMELINE_PADDING_PX,
83768
+ right: TIMELINE_PADDING_PX
83769
+ };
83770
+ function computeBarGeometry(startMs, endMs, viewStart, viewEnd, containerWidth) {
83771
+ const viewDuration = viewEnd - viewStart;
83772
+ const visibleStartMs = Math.max(startMs, viewStart);
83773
+ const visibleEndMs = Math.min(endMs, viewEnd);
83774
+ const visibleDurationMs = Math.max(0, visibleEndMs - visibleStartMs);
83775
+ const widthFrac = viewDuration > 0 ? visibleDurationMs / viewDuration : 0;
83776
+ const visiblePixelWidth = widthFrac * containerWidth;
83777
+ const isTiny = containerWidth > 0 && visiblePixelWidth < TINY_BAR_BOX_SIZE_PX;
83778
+ const extendsOffLeft = startMs < viewStart;
83779
+ const extendsOffRight = endMs > viewEnd;
83780
+ const mode = isTiny && (extendsOffLeft || extendsOffRight) ? { kind: "arrow", direction: extendsOffRight ? "right" : "left" } : isTiny ? { kind: "tiny" } : { kind: "full" };
83781
+ return {
83782
+ mode,
83783
+ leftPct: viewDuration > 0 ? (visibleStartMs - viewStart) / viewDuration * 100 : 0,
83784
+ widthPct: widthFrac * 100,
83785
+ visibleStartMs,
83786
+ visibleEndMs,
83787
+ visiblePixelWidth
83788
+ };
83789
+ }
83790
+ function getBarPositionStyle(geometry) {
83791
+ switch (geometry.mode.kind) {
83792
+ case "arrow":
83793
+ return {
83794
+ left: geometry.mode.direction === "right" ? `calc(100% - ${TINY_BAR_BOX_SIZE_PX}px)` : "0px",
83795
+ width: `${TINY_BAR_BOX_SIZE_PX}px`
83796
+ };
83797
+ case "tiny":
83798
+ return {
83799
+ left: `min(${geometry.leftPct}%, calc(100% - ${TINY_BAR_WIDTH_PX}px))`,
83800
+ width: `${TINY_BAR_WIDTH_PX}px`
83801
+ };
83802
+ case "full":
83803
+ return {
83804
+ left: `${geometry.leftPct}%`,
83805
+ width: `max(${geometry.widthPct}%, 4px)`
83806
+ };
83807
+ }
83808
+ }
83809
+ function projectSegments(segments, spanStartMs, spanDurationMs, geometry) {
83810
+ const visibleDurationMs = geometry.visibleEndMs - geometry.visibleStartMs;
83811
+ if (visibleDurationMs <= 0)
83812
+ return [];
83813
+ return segments.flatMap((seg) => {
83814
+ const segStartMs = spanStartMs + seg.startFraction * spanDurationMs;
83815
+ const segEndMs = spanStartMs + seg.endFraction * spanDurationMs;
83816
+ const startMs = Math.max(segStartMs, geometry.visibleStartMs);
83817
+ const endMs = Math.min(segEndMs, geometry.visibleEndMs);
83818
+ if (endMs <= startMs)
83819
+ return [];
83820
+ const widthFrac = (endMs - startMs) / visibleDurationMs;
83821
+ return [
83822
+ {
83823
+ status: seg.status,
83824
+ leftPct: (startMs - geometry.visibleStartMs) / visibleDurationMs * 100,
83825
+ widthPct: widthFrac * 100,
83826
+ pixelWidth: widthFrac * geometry.visiblePixelWidth,
83827
+ fullDurationMs: (seg.endFraction - seg.startFraction) * spanDurationMs
83828
+ }
83829
+ ];
83830
+ });
83831
+ }
83832
+ function DurationLabel({ label }) {
83833
+ return jsxRuntimeExports.jsx("span", { className: "pointer-events-none absolute inset-0 flex items-center justify-start overflow-hidden px-1 text-[10px] font-mono font-medium leading-none whitespace-nowrap text-left text-gray-1000 tabular-nums opacity-0 group-hover/timeline-row:opacity-100", children: label });
83834
+ }
83835
+ function BoundaryArrow({ direction }) {
83836
+ const Icon2 = direction === "right" ? ArrowRight : ArrowLeft;
83837
+ return jsxRuntimeExports.jsx("div", { className: "flex h-6 w-6 items-center justify-center rounded-[0.25rem]", children: jsxRuntimeExports.jsx(Icon2, { className: "size-3 text-gray-900" }) });
83838
+ }
83839
+ function PlainBar({ bg: bg2, border, label }) {
83840
+ return jsxRuntimeExports.jsx("div", { className: "relative h-6 w-full min-w-1 rounded-[0.25rem] border", style: { background: bg2, borderColor: border }, children: label ? jsxRuntimeExports.jsx(DurationLabel, { label }) : null });
83841
+ }
83842
+ function SegmentBar({ segments }) {
83843
+ return jsxRuntimeExports.jsx("div", { className: "relative h-6 w-full", children: segments.map((seg, i) => {
83844
+ const label = formatDuration(seg.fullDurationMs);
83845
+ const showLabel = seg.pixelWidth >= Math.max(40, label.length * 6 + 12);
83846
+ const isNarrowQueued = seg.status === "queued" && seg.pixelWidth < 20;
83847
+ const overrideBg = isNarrowQueued ? "var(--ds-gray-400)" : void 0;
83848
+ const overrideBorder = isNarrowQueued ? "var(--ds-gray-500)" : void 0;
83849
+ return jsxRuntimeExports.jsx("div", { className: cn$4("absolute h-full rounded-[0.25rem]", SEGMENT_CLASSES[seg.status]), style: {
83850
+ // 1px gap between adjacent segments, distributed equally.
83851
+ left: `calc(${seg.leftPct}% + 0.5px)`,
83852
+ width: `calc(${seg.widthPct}% - 1px)`,
83853
+ minWidth: 1,
83854
+ background: overrideBg,
83855
+ borderColor: overrideBorder
83856
+ }, children: showLabel ? jsxRuntimeExports.jsx(DurationLabel, { label }) : null }, `${seg.status}-${i}`);
83857
+ }) });
83858
+ }
83859
+ const TimelineBar = reactExports.memo(function TimelineBar2({ span, viewStart, viewDuration, containerWidth, isSelected, onSelect }) {
83730
83860
  var _a3;
83731
- const startTime = getHighResInMs(span.startTime);
83732
- const endTime = getHighResInMs(span.endTime);
83861
+ const startMs = getHighResInMs(span.startTime);
83862
+ const endMs = getHighResInMs(span.endTime);
83733
83863
  const totalDurationMs = getSpanDurationMs(span);
83734
- const leftFracRaw = viewDuration > 0 ? (startTime - viewStart) / viewDuration : 0;
83735
- const rightFracRaw = viewDuration > 0 ? (endTime - viewStart) / viewDuration : 0;
83736
- const widthFrac = rightFracRaw - leftFracRaw;
83737
- const leftPct = leftFracRaw * 100;
83738
- const widthPct = widthFrac * 100;
83739
- const pixelWidth = widthFrac * containerWidth;
83740
- const visibleLeftFrac = Math.max(0, Math.min(1, leftFracRaw));
83741
- const visibleRightFrac = Math.max(0, Math.min(1, rightFracRaw));
83742
- const visiblePixelWidth = Math.max(0, visibleRightFrac - visibleLeftFrac) * containerWidth;
83743
- const isTinyBar = containerWidth > 0 && visiblePixelWidth < TINY_BAR_BOX_SIZE_PX;
83744
- const [isRowHovered, setIsRowHovered] = reactExports.useState(false);
83745
- const segments = reactExports.useMemo(() => computeSpanSegments(span), [span]);
83864
+ const geometry = reactExports.useMemo(() => computeBarGeometry(startMs, endMs, viewStart, viewStart + viewDuration, containerWidth), [startMs, endMs, viewStart, viewDuration, containerWidth]);
83865
+ const baseSegments = reactExports.useMemo(() => computeSpanSegments(span), [span]);
83866
+ const segments = reactExports.useMemo(() => geometry.mode.kind === "full" ? projectSegments(baseSegments, startMs, totalDurationMs, geometry) : [], [geometry, baseSegments, startMs, totalDurationMs]);
83746
83867
  const workflowStatus = (_a3 = span.attributes.data) == null ? void 0 : _a3.status;
83747
83868
  const isErrored = span.status.code === 2 || workflowStatus === "failed";
83748
83869
  const colors = getResourceColor(span.resource);
83749
- const fallbackColor = isErrored ? colors.errorBar ?? "var(--ds-red-700)" : colors.bar;
83750
- const renderDurationLabel = (label) => jsxRuntimeExports.jsx("span", { className: "pointer-events-none absolute inset-0 flex items-center justify-start overflow-hidden px-1 text-[10px] font-mono font-medium leading-none whitespace-nowrap text-left text-white tabular-nums", style: { textShadow: "0 1px 1px rgba(0, 0, 0, 0.45)" }, children: label });
83751
- const getMinDurationLabelWidthPx = (label) => Math.max(40, label.length * 6 + 12);
83752
- const totalDurationLabel = formatDuration(totalDurationMs);
83753
- const showBarDurationLabel = isRowHovered && pixelWidth >= getMinDurationLabelWidthPx(totalDurationLabel);
83754
- const showBoundaryArrow = isTinyBar && (leftFracRaw < 0 || rightFracRaw > 1);
83755
- const BoundaryArrow = leftFracRaw < 0.5 ? ArrowLeft : ArrowRight;
83756
- const barContent = showBoundaryArrow ? jsxRuntimeExports.jsx("div", { className: "flex h-6 w-6 items-center justify-center rounded-[0.25rem]", children: jsxRuntimeExports.jsx(BoundaryArrow, { className: "size-3 text-gray-900" }) }) : isTinyBar ? jsxRuntimeExports.jsx("div", { className: "h-6 rounded-[0.25rem]", style: { background: fallbackColor } }) : segments.length > 0 ? jsxRuntimeExports.jsx("div", { className: "relative h-6 w-full", children: segments.map((seg, i) => {
83757
- const segPixelWidth = (seg.endFraction - seg.startFraction) * pixelWidth;
83758
- const segDurationLabel = formatDuration((seg.endFraction - seg.startFraction) * totalDurationMs);
83759
- const showSegmentDurationLabel = isRowHovered && segPixelWidth >= getMinDurationLabelWidthPx(segDurationLabel);
83760
- const segStyle = seg.status === "queued" && segPixelWidth < 20 ? { background: "var(--ds-gray-500)" } : SEGMENT_CONFIG[seg.status].style;
83761
- return jsxRuntimeExports.jsx("div", { className: cn$4("absolute h-full rounded-[0.25rem]", SEGMENT_CONFIG[seg.status].className), style: {
83762
- left: `calc(${seg.startFraction * 100}% + ${SEGMENT_GAP_PX / 2}px)`,
83763
- width: `calc(${(seg.endFraction - seg.startFraction) * 100}% - ${SEGMENT_GAP_PX}px)`,
83764
- minWidth: 1,
83765
- ...segStyle
83766
- }, children: showSegmentDurationLabel ? renderDurationLabel(segDurationLabel) : null }, `${seg.status}-${i}`);
83767
- }) }) : jsxRuntimeExports.jsx("div", { className: "relative h-6 rounded-[0.25rem]", style: {
83768
- width: "100%",
83769
- minWidth: 4,
83770
- background: fallbackColor
83771
- }, children: showBarDurationLabel ? renderDurationLabel(totalDurationLabel) : null });
83772
- return jsxRuntimeExports.jsx("div", { role: "treeitem", "aria-selected": isSelected, "aria-expanded": isSelected, "aria-level": 1, className: cn$4("h-10 relative flex items-center hover:bg-gray-100 aria-selected:bg-gray-100 aria-selected:hover:bg-gray-200"), onMouseEnter: () => setIsRowHovered(true), onMouseLeave: () => setIsRowHovered(false), onClick, children: jsxRuntimeExports.jsx("div", { className: "absolute inset-y-0", style: {
83773
- left: TIMELINE_PADDING_PX,
83774
- right: TIMELINE_PADDING_PX
83775
- }, children: jsxRuntimeExports.jsx("div", { className: "absolute top-1/2 -translate-y-1/2", style: {
83776
- left: showBoundaryArrow ? `min(max(${leftPct}%, 0px), calc(100% - ${TINY_BAR_BOX_SIZE_PX}px))` : isTinyBar ? `min(${leftPct}%, calc(100% - ${TINY_BAR_WIDTH_PX}px))` : `${leftPct}%`,
83777
- width: showBoundaryArrow ? `${TINY_BAR_BOX_SIZE_PX}px` : isTinyBar ? `${TINY_BAR_WIDTH_PX}px` : `max(${widthPct}%, 4px)`,
83778
- height: BAR_HEIGHT_PX
83779
- }, children: barContent }) }) });
83870
+ const fallbackBg = isErrored ? colors.errorBg ?? "var(--ds-red-200)" : colors.bg;
83871
+ const fallbackBorder = isErrored ? colors.errorBorder ?? "var(--ds-red-500)" : colors.border;
83872
+ const totalLabel = formatDuration(totalDurationMs);
83873
+ const showTotalLabel = geometry.visiblePixelWidth >= Math.max(40, totalLabel.length * 6 + 12);
83874
+ const handleClick = reactExports.useCallback(() => {
83875
+ onSelect(span.spanId);
83876
+ }, [onSelect, span.spanId]);
83877
+ return jsxRuntimeExports.jsx("div", { role: "treeitem", "aria-selected": isSelected, "aria-expanded": isSelected, "aria-level": 1, className: "group/timeline-row h-10 relative flex items-center hover:bg-gray-100 aria-selected:bg-gray-100 aria-selected:hover:bg-gray-200", onClick: handleClick, children: jsxRuntimeExports.jsx("div", { className: "absolute inset-y-0", style: TIMELINE_INSET_STYLE, children: jsxRuntimeExports.jsx("div", { className: "absolute top-1/2 h-6 -translate-y-1/2", style: getBarPositionStyle(geometry), children: geometry.mode.kind === "arrow" ? jsxRuntimeExports.jsx(BoundaryArrow, { direction: geometry.mode.direction }) : geometry.mode.kind === "tiny" ? jsxRuntimeExports.jsx("div", { className: "h-6 rounded-[0.25rem] border", style: { background: fallbackBg, borderColor: fallbackBorder } }) : segments.length > 0 ? jsxRuntimeExports.jsx(SegmentBar, { segments }) : jsxRuntimeExports.jsx(PlainBar, { bg: fallbackBg, border: fallbackBorder, label: showTotalLabel ? totalLabel : null }) }) }) });
83878
+ });
83879
+ const DELTA_ROW_HEIGHT_PX = 40;
83880
+ const DELTA_CAP_HEIGHT_PX = 8;
83881
+ const DELTA_ROW_OFFSET_PX = 8;
83882
+ const DeltaIndicator = reactExports.memo(function DeltaIndicator2({ leftFrac, rightFrac, label, rowIndex }) {
83883
+ const centerY = DELTA_ROW_OFFSET_PX + (rowIndex + 1) * DELTA_ROW_HEIGHT_PX;
83884
+ return jsxRuntimeExports.jsxs("div", { className: "absolute pointer-events-none", style: {
83885
+ left: `${leftFrac * 100}%`,
83886
+ width: `${(rightFrac - leftFrac) * 100}%`,
83887
+ top: centerY - DELTA_CAP_HEIGHT_PX / 2,
83888
+ height: DELTA_CAP_HEIGHT_PX
83889
+ }, children: [jsxRuntimeExports.jsx("div", { className: "absolute left-0 top-0 w-px h-full bg-amber-800" }), jsxRuntimeExports.jsx("div", { className: "absolute left-0 right-0 top-1/2 h-px bg-amber-800" }), jsxRuntimeExports.jsx("div", { className: "absolute right-0 top-0 w-px h-full bg-amber-800" }), jsxRuntimeExports.jsx("span", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-label-12 leading-none whitespace-nowrap rounded-xs px-1 py-0.5 text-gray-100 bg-amber-800", children: label })] });
83780
83890
  });
83781
83891
  function TimelineHeader({ markers: markers2, hoverInfo: hoverInfo2 }) {
83782
83892
  return jsxRuntimeExports.jsx("div", { className: "relative bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-end px-4 pb-1", children: jsxRuntimeExports.jsxs("div", { className: "relative h-full flex-1", children: [markers2.map((m2) => jsxRuntimeExports.jsx("span", { className: "absolute bottom-1 font-mono text-xs font-normal leading-4 text-gray-900 whitespace-nowrap", style: { left: `${m2.position * 100}%` }, children: m2.label }, `${m2.position}-${m2.label}`)), hoverInfo2 && jsxRuntimeExports.jsx("span", { className: "absolute top-1 pointer-events-none z-10 font-mono text-[11px] leading-4 text-gray-1000 whitespace-nowrap bg-background-100 border border-gray-alpha-400 rounded px-1 -translate-x-1/2", style: { left: `${hoverInfo2.fraction * 100}%` }, children: hoverInfo2.label })] }) });
@@ -83797,16 +83907,10 @@ function Timeline({ spans, viewStart, viewEnd, markers: markers2, selectedId, on
83797
83907
  return () => ro2.disconnect();
83798
83908
  }, []);
83799
83909
  const gaps = reactExports.useMemo(() => computeSpanGaps(spans, viewStart, viewEnd), [spans, viewStart, viewEnd]);
83800
- return jsxRuntimeExports.jsxs("div", { ref: containerRef, className: "relative h-full overflow-hidden", children: [jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "absolute inset-y-0 pointer-events-none", style: {
83801
- left: TIMELINE_PADDING_PX,
83802
- right: TIMELINE_PADDING_PX
83803
- }, children: markers2.map((marker2) => Math.abs(marker2.value) > ORIGIN_MARKER_EPSILON ? jsxRuntimeExports.jsx("div", { className: "absolute top-0 bottom-0 w-px bg-gray-alpha-300", style: { left: `${marker2.position * 100}%` } }, `${marker2.position}-${marker2.label}`) : null) }), hoverFraction != null && jsxRuntimeExports.jsx("div", { className: "absolute inset-y-0 pointer-events-none z-10", style: {
83804
- left: TIMELINE_PADDING_PX,
83805
- right: TIMELINE_PADDING_PX
83806
- }, children: jsxRuntimeExports.jsx("div", { className: "absolute top-0 bottom-0 w-px bg-gray-alpha-400", style: { left: `${hoverFraction * 100}%` } }) }), spans.map((span) => jsxRuntimeExports.jsx(TimelineBar, { span, viewStart, viewDuration, containerWidth: timelineWidth, isSelected: selectedId === span.spanId, onClick: () => onSelect(span.spanId) }, span.spanId)), altHeld && jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "absolute inset-y-0 pointer-events-none", style: {
83807
- left: TIMELINE_PADDING_PX,
83808
- right: TIMELINE_PADDING_PX
83809
- }, children: gaps.map((gap) => jsxRuntimeExports.jsx(DeltaIndicator, { leftFrac: gap.leftFrac, rightFrac: gap.rightFrac, label: formatDuration(gap.gapMs, true), rowIndex: gap.rowIndex }, gap.rowIndex)) })] });
83910
+ return jsxRuntimeExports.jsxs("div", { ref: containerRef, className: "relative h-full overflow-hidden", children: [jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "absolute inset-y-0 pointer-events-none", style: TIMELINE_INSET_STYLE, children: markers2.map((marker2) => (
83911
+ // Skip the "0s" origin marker since the left edge already implies it.
83912
+ Math.abs(marker2.value) > 1e-6 ? jsxRuntimeExports.jsx("div", { className: "absolute top-0 bottom-0 w-px bg-gray-alpha-300", style: { left: `${marker2.position * 100}%` } }, `${marker2.position}-${marker2.label}`) : null
83913
+ )) }), hoverFraction != null && jsxRuntimeExports.jsx("div", { className: "absolute inset-y-0 pointer-events-none z-10", style: TIMELINE_INSET_STYLE, children: jsxRuntimeExports.jsx("div", { className: "absolute top-0 bottom-0 w-px bg-gray-alpha-500", style: { left: `${hoverFraction * 100}%` } }) }), spans.map((span) => jsxRuntimeExports.jsx(TimelineBar, { span, viewStart, viewDuration, containerWidth: timelineWidth, isSelected: selectedId === span.spanId, onSelect }, span.spanId)), altHeld && jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "absolute inset-y-0 pointer-events-none", style: TIMELINE_INSET_STYLE, children: gaps.map((gap) => jsxRuntimeExports.jsx(DeltaIndicator, { leftFrac: gap.leftFrac, rightFrac: gap.rightFrac, label: formatDuration(gap.gapMs, true), rowIndex: gap.rowIndex }, gap.rowIndex)) })] });
83810
83914
  }
83811
83915
  const ActiveSpanContext = reactExports.createContext(null);
83812
83916
  ActiveSpanContext.displayName = "ActiveSpanContext";
@@ -83864,6 +83968,7 @@ function useAnimatedViewport(initial) {
83864
83968
  const animRef = reactExports.useRef(null);
83865
83969
  const currentRef = reactExports.useRef(initial);
83866
83970
  currentRef.current = viewport;
83971
+ const reducedMotion = useReducedMotion();
83867
83972
  const cancel = reactExports.useCallback(() => {
83868
83973
  if (animRef.current) {
83869
83974
  cancelAnimationFrame(animRef.current.raf);
@@ -83872,6 +83977,11 @@ function useAnimatedViewport(initial) {
83872
83977
  }, []);
83873
83978
  const animateTo = reactExports.useCallback((target2) => {
83874
83979
  cancel();
83980
+ if (reducedMotion) {
83981
+ currentRef.current = target2;
83982
+ setViewportState(target2);
83983
+ return;
83984
+ }
83875
83985
  const from = currentRef.current;
83876
83986
  const anim = { raf: 0, from, to: target2, start: performance.now() };
83877
83987
  const tick = () => {
@@ -83888,7 +83998,7 @@ function useAnimatedViewport(initial) {
83888
83998
  };
83889
83999
  animRef.current = anim;
83890
84000
  anim.raf = requestAnimationFrame(tick);
83891
- }, [cancel]);
84001
+ }, [cancel, reducedMotion]);
83892
84002
  const setViewport = reactExports.useCallback((update) => {
83893
84003
  cancel();
83894
84004
  if (typeof update === "function") {
@@ -84169,7 +84279,7 @@ function NewTraceViewerContent({ trace: trace2 }) {
84169
84279
  }
84170
84280
  return data.stepId ?? data.runId ?? data.hookId ?? selectedSpan.spanId;
84171
84281
  }, [selectedSpan == null ? void 0 : selectedSpan.data, selectedSpan == null ? void 0 : selectedSpan.resource, selectedSpan == null ? void 0 : selectedSpan.spanId]);
84172
- return jsxRuntimeExports.jsxs("div", { "data-pane": "pane-root", "data-has-detail": activeSpan ? "" : void 0, className: "grid w-full h-full max-h-full grid-cols-[minmax(100px,1fr)] data-[has-detail]:grid-cols-[minmax(100px,1fr)_clamp(280px,420px,100%)]", children: [jsxRuntimeExports.jsxs("div", { id: "trace-parent", className: "grid grid-rows-[1fr] h-full min-h-0 overflow-hidden relative bg-background-100", children: [jsxRuntimeExports.jsxs(SplitPane, { startHeader: jsxRuntimeExports.jsxs("div", { className: "bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-center px-2 gap-1.5", children: [jsxRuntimeExports.jsx(Search, { className: "w-3.5 h-3.5 shrink-0 text-gray-800" }), jsxRuntimeExports.jsx("input", { id: "trace-viewer-search", name: "trace-viewer-search", type: "text", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: "Search spans...", "aria-label": "Search spans", className: "flex-1 min-w-0 bg-transparent text-sm text-gray-1000 placeholder:text-gray-800 outline-none" }), searchQuery && jsxRuntimeExports.jsx("button", { type: "button", onClick: () => setSearchQuery(""), className: "shrink-0 p-0.5 rounded-sm text-gray-800 hover:text-gray-1000 hover:bg-gray-200 transition-colors", children: jsxRuntimeExports.jsx(X$3, { className: "w-3 h-3" }) })] }), endHeader: jsxRuntimeExports.jsx(TimelineHeader, { markers: timeMarkers, hoverInfo: hoverInfo2 }), children: [jsxRuntimeExports.jsx("div", { className: "block overflow-visible", children: jsxRuntimeExports.jsx(EventList, { spans: filteredSpans, activeSpanId, onSelectSpan: handleSelectSpan }) }), jsxRuntimeExports.jsx("div", { ref: timelineRef, className: "block min-h-0 overflow-visible relative", onDoubleClick: resetZoom, onMouseMove: handleTimelineMouseMove, onMouseLeave: handleTimelineMouseLeave, children: jsxRuntimeExports.jsx(Timeline, { spans: filteredSpans, viewStart: viewport.start, viewEnd: viewport.end, markers: timeMarkers, selectedId: activeSpanId, onSelect: handleSelectSpan, hoverFraction, altHeld }) })] }), jsxRuntimeExports.jsxs("div", { className: "absolute right-3 bottom-3 z-[5] flex items-center border border-gray-alpha-400 rounded-lg bg-background-100 shadow-sm overflow-hidden divide-x divide-gray-alpha-400", children: [jsxRuntimeExports.jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[time:120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100", onClick: zoomOut, "aria-label": "Zoom out", children: jsxRuntimeExports.jsx(ZoomOut, { className: "w-4 h-4" }) }), jsxRuntimeExports.jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[time:120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100", onClick: resetZoom, "aria-label": "Reset zoom", children: jsxRuntimeExports.jsx(RotateCcw, { className: "w-3.5 h-3.5" }) }), jsxRuntimeExports.jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[time:120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100", onClick: zoomIn, "aria-label": "Zoom in", children: jsxRuntimeExports.jsx(ZoomIn, { className: "w-4 h-4" }) })] })] }), activeSpan && sidebar ? jsxRuntimeExports.jsxs("aside", { className: "flex flex-col h-full max-h-full bg-background-100 border-l border-gray-alpha-400 overflow-auto", children: [jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 px-4 pt-4 pb-3", children: jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1", children: [jsxRuntimeExports.jsx("span", { className: "text-[15px] font-semibold text-gray-1000 truncate block", children: selectedSpanName }), selectedResourceId && jsxRuntimeExports.jsxs("div", { className: "mt-1 flex items-center gap-2", children: [selectedResource && jsxRuntimeExports.jsx("span", { className: `inline-flex items-center rounded-md px-1.5 py-0.5 text-[11px] font-medium leading-none shrink-0 ${selectedResource === "step" ? "bg-green-200 text-green-900" : selectedResource === "run" ? "bg-blue-200 text-blue-900" : selectedResource === "hook" ? "bg-yellow-200 text-yellow-900" : "bg-gray-200 text-gray-900"}`, children: selectedResource.charAt(0).toUpperCase() + selectedResource.slice(1) }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-[13px] font-mono text-gray-700 min-w-0", title: selectedResourceId, children: [jsxRuntimeExports.jsx("span", { className: "truncate", children: selectedResourceId }), jsxRuntimeExports.jsx(CopyButton, { copyText: selectedResourceId, ariaLabel: "Copy ID", className: "shrink-0" })] })] })] }), jsxRuntimeExports.jsx("button", { type: "button", className: "p-1 rounded-md text-gray-900 hover:text-gray-1000 hover:bg-gray-alpha-200 transition-colors shrink-0", onClick: clearActiveSpan, children: jsxRuntimeExports.jsx(X$3, { className: "w-4 h-4" }) })] }) }), jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto", children: jsxRuntimeExports.jsx(ErrorBoundary$1, { children: jsxRuntimeExports.jsx(EntityDetailPanel, { run: sidebar.run, onStreamClick: sidebar.onStreamClick, onRunClick: sidebar.onRunClick, spanDetailData: sidebar.spanDetailData, spanDetailError: sidebar.spanDetailError, spanDetailLoading: sidebar.spanDetailLoading, onSpanSelect: sidebar.onSpanSelect, onWakeUpSleep: sidebar.onWakeUpSleep, onLoadEventData: sidebar.onLoadEventData, onResolveHook: sidebar.onResolveHook, encryptionKey: sidebar.encryptionKey, onDecrypt: sidebar.onDecrypt, isDecrypting: sidebar.isDecrypting, selectedSpan }) }) })] }) : activeSpan ? jsxRuntimeExports.jsx(DetailPanel, { span: activeSpan, rootStart: root2.startTime, onClose: clearActiveSpan }) : null] });
84282
+ return jsxRuntimeExports.jsxs("div", { "data-pane": "pane-root", "data-has-detail": activeSpan ? "" : void 0, className: "grid w-full h-full max-h-full grid-cols-[minmax(100px,1fr)] data-[has-detail]:grid-cols-[minmax(100px,1fr)_clamp(280px,420px,100%)]", children: [jsxRuntimeExports.jsxs("div", { id: "trace-parent", className: "grid grid-rows-[1fr] h-full min-h-0 overflow-hidden relative bg-background-100", children: [jsxRuntimeExports.jsxs(SplitPane, { startHeader: jsxRuntimeExports.jsxs("div", { className: "bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-center px-2 gap-1.5", children: [jsxRuntimeExports.jsx(Search, { className: "w-3.5 h-3.5 shrink-0 text-gray-800" }), jsxRuntimeExports.jsx("input", { id: "trace-viewer-search", name: "trace-viewer-search", type: "text", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: "Search spans...", "aria-label": "Search spans", className: "flex-1 min-w-0 bg-transparent text-sm text-gray-1000 placeholder:text-gray-800 outline-none" }), searchQuery && jsxRuntimeExports.jsx("button", { type: "button", onClick: () => setSearchQuery(""), className: "shrink-0 p-0.5 rounded-sm text-gray-800 hover:text-gray-1000 hover:bg-gray-200 transition-colors", children: jsxRuntimeExports.jsx(X$3, { className: "w-3 h-3" }) })] }), endHeader: jsxRuntimeExports.jsx(TimelineHeader, { markers: timeMarkers, hoverInfo: hoverInfo2 }), children: [jsxRuntimeExports.jsx("div", { className: "block overflow-visible", children: jsxRuntimeExports.jsx(EventList, { spans: filteredSpans, activeSpanId, onSelectSpan: handleSelectSpan }) }), jsxRuntimeExports.jsx("div", { ref: timelineRef, className: "block min-h-0 overflow-visible relative", onDoubleClick: resetZoom, onMouseMove: handleTimelineMouseMove, onMouseLeave: handleTimelineMouseLeave, children: jsxRuntimeExports.jsx(Timeline, { spans: filteredSpans, viewStart: viewport.start, viewEnd: viewport.end, markers: timeMarkers, selectedId: activeSpanId, onSelect: handleSelectSpan, hoverFraction, altHeld }) })] }), jsxRuntimeExports.jsxs("div", { className: "absolute right-3 bottom-3 z-[5] flex items-center border border-gray-alpha-400 rounded-lg bg-background-100 shadow-sm overflow-hidden divide-x divide-gray-alpha-400", children: [jsxRuntimeExports.jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[time:120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100", onClick: zoomOut, "aria-label": "Zoom out", children: jsxRuntimeExports.jsx(ZoomOut, { className: "w-4 h-4" }) }), jsxRuntimeExports.jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[time:120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100", onClick: resetZoom, "aria-label": "Reset zoom", children: jsxRuntimeExports.jsx(RotateCcw, { className: "w-3.5 h-3.5" }) }), jsxRuntimeExports.jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[time:120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100", onClick: zoomIn, "aria-label": "Zoom in", children: jsxRuntimeExports.jsx(ZoomIn, { className: "w-4 h-4" }) })] })] }), activeSpan && sidebar ? jsxRuntimeExports.jsxs("aside", { className: "flex flex-col h-full max-h-full bg-background-100 border-l border-gray-alpha-400 overflow-auto", children: [jsxRuntimeExports.jsx("div", { className: "flex-shrink-0 px-4 pt-4 pb-3", children: jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [jsxRuntimeExports.jsxs("div", { className: "min-w-0 flex-1", children: [jsxRuntimeExports.jsx("span", { className: "text-[15px] font-semibold text-gray-1000 truncate block", children: selectedSpanName }), selectedResourceId && jsxRuntimeExports.jsxs("div", { className: "mt-1 flex items-center gap-2", children: [selectedResource && jsxRuntimeExports.jsx("span", { className: `inline-flex items-center rounded-md px-1.5 py-0.5 text-[11px] font-medium leading-none shrink-0 ${selectedResource === "step" ? "bg-green-200 text-green-900" : selectedResource === "run" ? "bg-blue-200 text-blue-900" : "bg-gray-200 text-gray-900"}`, children: selectedResource.charAt(0).toUpperCase() + selectedResource.slice(1) }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-[13px] font-mono text-gray-700 min-w-0", title: selectedResourceId, children: [jsxRuntimeExports.jsx("span", { className: "truncate", children: selectedResourceId }), jsxRuntimeExports.jsx(CopyButton, { copyText: selectedResourceId, ariaLabel: "Copy ID", className: "shrink-0" })] })] })] }), jsxRuntimeExports.jsx("button", { type: "button", className: "p-1 rounded-md text-gray-900 hover:text-gray-1000 hover:bg-gray-alpha-200 transition-colors shrink-0", onClick: clearActiveSpan, children: jsxRuntimeExports.jsx(X$3, { className: "w-4 h-4" }) })] }) }), jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto", children: jsxRuntimeExports.jsx(ErrorBoundary$1, { children: jsxRuntimeExports.jsx(EntityDetailPanel, { run: sidebar.run, onStreamClick: sidebar.onStreamClick, onRunClick: sidebar.onRunClick, spanDetailData: sidebar.spanDetailData, spanDetailError: sidebar.spanDetailError, spanDetailLoading: sidebar.spanDetailLoading, onSpanSelect: sidebar.onSpanSelect, onWakeUpSleep: sidebar.onWakeUpSleep, onLoadEventData: sidebar.onLoadEventData, onResolveHook: sidebar.onResolveHook, encryptionKey: sidebar.encryptionKey, onDecrypt: sidebar.onDecrypt, isDecrypting: sidebar.isDecrypting, selectedSpan }) }) })] }) : activeSpan ? jsxRuntimeExports.jsx(DetailPanel, { span: activeSpan, rootStart: root2.startTime, onClose: clearActiveSpan }) : null] });
84173
84283
  }
84174
84284
  const NewTraceViewer = ({ run, events: events2, sidebarData }) => {
84175
84285
  const traceWithMeta = reactExports.useMemo(() => {
@@ -88094,14 +88204,20 @@ const runtimeLogger = createLogger("runtime");
88094
88204
  const NONCE_LENGTH = 12;
88095
88205
  const TAG_LENGTH = 128;
88096
88206
  const KEY_LENGTH = 32;
88097
- async function importKey(raw2) {
88207
+ async function importKey(raw2, usages = ["encrypt", "decrypt"]) {
88098
88208
  if (raw2.byteLength !== KEY_LENGTH) {
88099
88209
  throw new WorkflowRuntimeError(`Encryption key must be exactly ${KEY_LENGTH} bytes, got ${raw2.byteLength}`);
88100
88210
  }
88101
- return globalThis.crypto.subtle.importKey("raw", raw2, "AES-GCM", false, [
88102
- "encrypt",
88103
- "decrypt"
88104
- ]);
88211
+ return globalThis.crypto.subtle.importKey(
88212
+ "raw",
88213
+ raw2,
88214
+ "AES-GCM",
88215
+ false,
88216
+ // `KeyUsage` is a DOM-lib type that's not in scope under `es2022`.
88217
+ // The `ReadonlyArray<'encrypt' | 'decrypt'>` parameter type matches
88218
+ // a strict subset of `KeyUsage[]`, so this cast is sound.
88219
+ usages
88220
+ );
88105
88221
  }
88106
88222
  async function encrypt$1(key, data) {
88107
88223
  const nonce = globalThis.crypto.getRandomValues(new Uint8Array(NONCE_LENGTH));
@@ -88127,7 +88243,7 @@ const encryption = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
88127
88243
  encrypt: encrypt$1,
88128
88244
  importKey
88129
88245
  }, Symbol.toStringTag, { value: "Module" }));
88130
- const version$1 = "5.0.0-beta.6";
88246
+ const version$1 = "5.0.0-beta.7";
88131
88247
  const WorldCacheKey = Symbol.for("@workflow/world//cache");
88132
88248
  const WorldCachePromiseKey = Symbol.for("@workflow/world//cachePromise");
88133
88249
  const GetWorldFnKey$1 = Symbol.for("@workflow/world//getWorldFn");
@@ -88261,6 +88377,849 @@ async function healthCheck(world, endpoint, options) {
88261
88377
  };
88262
88378
  }
88263
88379
  }
88380
+ const LOCK_POLL_INTERVAL_MS = 10;
88381
+ function createFlushableState() {
88382
+ return {
88383
+ ...withResolvers$1(),
88384
+ pendingOps: 0,
88385
+ doneResolved: false,
88386
+ streamEnded: false
88387
+ };
88388
+ }
88389
+ function isWritableUnlockedNotClosed(writable) {
88390
+ if (writable.locked)
88391
+ return false;
88392
+ let writer;
88393
+ try {
88394
+ writer = writable.getWriter();
88395
+ } catch {
88396
+ return false;
88397
+ }
88398
+ try {
88399
+ writer.releaseLock();
88400
+ } catch {
88401
+ return false;
88402
+ }
88403
+ return true;
88404
+ }
88405
+ function isReadableUnlockedNotClosed(readable2) {
88406
+ if (readable2.locked)
88407
+ return false;
88408
+ let reader;
88409
+ try {
88410
+ reader = readable2.getReader();
88411
+ } catch {
88412
+ return false;
88413
+ }
88414
+ try {
88415
+ reader.releaseLock();
88416
+ } catch {
88417
+ return false;
88418
+ }
88419
+ return true;
88420
+ }
88421
+ function pollWritableLock(writable, state) {
88422
+ if (state.writablePollingInterval !== void 0) {
88423
+ return;
88424
+ }
88425
+ const intervalId = setInterval(() => {
88426
+ if (state.doneResolved || state.streamEnded) {
88427
+ clearInterval(intervalId);
88428
+ state.writablePollingInterval = void 0;
88429
+ return;
88430
+ }
88431
+ if (isWritableUnlockedNotClosed(writable) && state.pendingOps === 0) {
88432
+ state.doneResolved = true;
88433
+ state.resolve();
88434
+ clearInterval(intervalId);
88435
+ state.writablePollingInterval = void 0;
88436
+ }
88437
+ }, LOCK_POLL_INTERVAL_MS);
88438
+ state.writablePollingInterval = intervalId;
88439
+ }
88440
+ function pollReadableLock(readable2, state) {
88441
+ if (state.readablePollingInterval !== void 0) {
88442
+ return;
88443
+ }
88444
+ const intervalId = setInterval(() => {
88445
+ if (state.doneResolved || state.streamEnded) {
88446
+ clearInterval(intervalId);
88447
+ state.readablePollingInterval = void 0;
88448
+ return;
88449
+ }
88450
+ if (isReadableUnlockedNotClosed(readable2) && state.pendingOps === 0) {
88451
+ state.doneResolved = true;
88452
+ state.resolve();
88453
+ clearInterval(intervalId);
88454
+ state.readablePollingInterval = void 0;
88455
+ }
88456
+ }, LOCK_POLL_INTERVAL_MS);
88457
+ state.readablePollingInterval = intervalId;
88458
+ }
88459
+ async function flushablePipe(source, sink, state) {
88460
+ const reader = source.getReader();
88461
+ const writer = sink.getWriter();
88462
+ let cancelReason;
88463
+ try {
88464
+ while (true) {
88465
+ if (state.streamEnded) {
88466
+ return;
88467
+ }
88468
+ const readResult = await Promise.race([
88469
+ reader.read(),
88470
+ writer.closed.then(() => {
88471
+ throw new WorkflowRuntimeError("Writable stream closed prematurely");
88472
+ })
88473
+ ]);
88474
+ if (state.streamEnded) {
88475
+ return;
88476
+ }
88477
+ if (readResult.done) {
88478
+ state.streamEnded = true;
88479
+ await writer.close();
88480
+ if (!state.doneResolved) {
88481
+ state.doneResolved = true;
88482
+ state.resolve();
88483
+ }
88484
+ return;
88485
+ }
88486
+ state.pendingOps++;
88487
+ try {
88488
+ await writer.write(readResult.value);
88489
+ } finally {
88490
+ state.pendingOps--;
88491
+ }
88492
+ }
88493
+ } catch (err) {
88494
+ state.streamEnded = true;
88495
+ cancelReason = err;
88496
+ if (!state.doneResolved) {
88497
+ state.doneResolved = true;
88498
+ state.reject(err);
88499
+ }
88500
+ throw err;
88501
+ } finally {
88502
+ reader.cancel(cancelReason).catch(() => {
88503
+ });
88504
+ reader.releaseLock();
88505
+ writer.releaseLock();
88506
+ }
88507
+ }
88508
+ const RegisteredStepsKey = Symbol.for("@workflow/core//registeredSteps");
88509
+ const globalSymbols$1 = globalThis;
88510
+ const registeredSteps = globalSymbols$1[RegisteredStepsKey] ?? (globalSymbols$1[RegisteredStepsKey] = /* @__PURE__ */ new Map());
88511
+ const BUILTIN_RESPONSE_STEP_NAMES = /* @__PURE__ */ new Set([
88512
+ "__builtin_response_array_buffer",
88513
+ "__builtin_response_json",
88514
+ "__builtin_response_text"
88515
+ ]);
88516
+ function getStepIdAliasCandidates(stepId) {
88517
+ const parts = stepId.split("//");
88518
+ if (parts.length !== 3 || parts[0] !== "step") {
88519
+ return [];
88520
+ }
88521
+ const modulePath = parts[1];
88522
+ const fnName = parts[2];
88523
+ const modulePathAliases = /* @__PURE__ */ new Set();
88524
+ const addAlias = (aliasModulePath) => {
88525
+ if (aliasModulePath !== modulePath) {
88526
+ modulePathAliases.add(aliasModulePath);
88527
+ }
88528
+ };
88529
+ if (modulePath.startsWith("./workflows/")) {
88530
+ const workflowRelativePath = modulePath.slice("./".length);
88531
+ addAlias(`./example/${workflowRelativePath}`);
88532
+ addAlias(`./src/${workflowRelativePath}`);
88533
+ } else if (modulePath.startsWith("./example/workflows/")) {
88534
+ const workflowRelativePath = modulePath.slice("./example/".length);
88535
+ addAlias(`./${workflowRelativePath}`);
88536
+ addAlias(`./src/${workflowRelativePath}`);
88537
+ } else if (modulePath.startsWith("./src/workflows/")) {
88538
+ const workflowRelativePath = modulePath.slice("./src/".length);
88539
+ addAlias(`./${workflowRelativePath}`);
88540
+ addAlias(`./example/${workflowRelativePath}`);
88541
+ }
88542
+ return Array.from(modulePathAliases, (aliasModulePath) => `step//${aliasModulePath}//${fnName}`);
88543
+ }
88544
+ function getBuiltinResponseStepAlias(stepId) {
88545
+ if (!BUILTIN_RESPONSE_STEP_NAMES.has(stepId)) {
88546
+ return void 0;
88547
+ }
88548
+ for (const [registeredStepId, stepFn] of registeredSteps.entries()) {
88549
+ if (registeredStepId.endsWith(`//${stepId}`)) {
88550
+ return stepFn;
88551
+ }
88552
+ }
88553
+ return void 0;
88554
+ }
88555
+ function getStepFunction(stepId) {
88556
+ const directMatch = registeredSteps.get(stepId);
88557
+ if (directMatch) {
88558
+ return directMatch;
88559
+ }
88560
+ for (const aliasStepId of getStepIdAliasCandidates(stepId)) {
88561
+ const aliasMatch = registeredSteps.get(aliasStepId);
88562
+ if (aliasMatch) {
88563
+ return aliasMatch;
88564
+ }
88565
+ }
88566
+ const builtinAliasMatch = getBuiltinResponseStepAlias(stepId);
88567
+ if (builtinAliasMatch) {
88568
+ return builtinAliasMatch;
88569
+ }
88570
+ return void 0;
88571
+ }
88572
+ const WORKFLOW_SERIALIZE = Symbol.for("workflow-serialize");
88573
+ const WORKFLOW_DESERIALIZE = Symbol.for("workflow-deserialize");
88574
+ const STABLE_ULID = Symbol.for("WORKFLOW_STABLE_ULID");
88575
+ const STREAM_NAME_SYMBOL = Symbol.for("WORKFLOW_STREAM_NAME");
88576
+ const STREAM_TYPE_SYMBOL = Symbol.for("WORKFLOW_STREAM_TYPE");
88577
+ const STREAM_SERVER_RUN_ID_SYMBOL = Symbol.for("WORKFLOW_STREAM_SERVER_RUN_ID");
88578
+ const BODY_INIT_SYMBOL = Symbol.for("BODY_INIT");
88579
+ const WEBHOOK_RESPONSE_WRITABLE = Symbol.for("WEBHOOK_RESPONSE_WRITABLE");
88580
+ const WORKFLOW_CLASS_REGISTRY = Symbol.for("workflow-class-registry");
88581
+ const ABORT_STREAM_NAME = Symbol.for("WORKFLOW_ABORT_STREAM_NAME");
88582
+ const ABORT_HOOK_TOKEN = Symbol.for("WORKFLOW_ABORT_HOOK_TOKEN");
88583
+ const ABORT_LISTENER_ATTACHED = Symbol.for("WORKFLOW_ABORT_LISTENER_ATTACHED");
88584
+ const ABORT_READER_CANCEL = Symbol.for("WORKFLOW_ABORT_READER_CANCEL");
88585
+ function getRegistry(global2 = globalThis) {
88586
+ const g2 = global2;
88587
+ let registry2 = g2[WORKFLOW_CLASS_REGISTRY];
88588
+ if (!registry2) {
88589
+ registry2 = /* @__PURE__ */ new Map();
88590
+ g2[WORKFLOW_CLASS_REGISTRY] = registry2;
88591
+ }
88592
+ return registry2;
88593
+ }
88594
+ function getSerializationClass(classId, global2) {
88595
+ return getRegistry(global2).get(classId);
88596
+ }
88597
+ function getClassReducers() {
88598
+ return {
88599
+ // Class and Instance are intentionally placed before Error so that
88600
+ // custom Error subclasses with WORKFLOW_SERIALIZE take precedence
88601
+ // over the generic Error serialization (devalue uses first-match-wins).
88602
+ Class: (value) => {
88603
+ if (typeof value !== "function")
88604
+ return false;
88605
+ const classId = value.classId;
88606
+ if (typeof classId !== "string")
88607
+ return false;
88608
+ return { classId };
88609
+ },
88610
+ Instance: (value) => {
88611
+ if (value === null || typeof value !== "object")
88612
+ return false;
88613
+ const cls = value.constructor;
88614
+ if (!cls || typeof cls !== "function")
88615
+ return false;
88616
+ const serialize2 = cls[WORKFLOW_SERIALIZE];
88617
+ if (typeof serialize2 !== "function")
88618
+ return false;
88619
+ const classId = cls.classId;
88620
+ if (typeof classId !== "string") {
88621
+ throw new Error(`Class "${cls.name}" with ${String(WORKFLOW_SERIALIZE)} must have a static "classId" property.`);
88622
+ }
88623
+ const data = serialize2.call(cls, value);
88624
+ return { classId, data };
88625
+ }
88626
+ };
88627
+ }
88628
+ function getClassRevivers(global2 = globalThis) {
88629
+ return {
88630
+ Class: (value) => {
88631
+ const classId = value.classId;
88632
+ const cls = getSerializationClass(classId, global2);
88633
+ if (!cls) {
88634
+ throw new Error(`Class "${classId}" not found. Make sure the class is registered with registerSerializationClass.`);
88635
+ }
88636
+ return cls;
88637
+ },
88638
+ Instance: (value) => {
88639
+ const classId = value.classId;
88640
+ const data = value.data;
88641
+ const cls = getSerializationClass(classId, global2);
88642
+ if (!cls) {
88643
+ throw new Error(`Class "${classId}" not found. Make sure the class is registered with registerSerializationClass.`);
88644
+ }
88645
+ const deserialize2 = cls[WORKFLOW_DESERIALIZE];
88646
+ if (typeof deserialize2 !== "function") {
88647
+ throw new Error(`Class "${classId}" does not have a static ${String(WORKFLOW_DESERIALIZE)} method.`);
88648
+ }
88649
+ return deserialize2.call(cls, data);
88650
+ }
88651
+ };
88652
+ }
88653
+ function arrayBufferToBase64(value, offset2, length) {
88654
+ if (length === 0)
88655
+ return ".";
88656
+ const uint8 = new Uint8Array(value, offset2, length);
88657
+ return Buffer.from(uint8).toString("base64");
88658
+ }
88659
+ function viewToBase64(value) {
88660
+ return arrayBufferToBase64(value.buffer, value.byteOffset, value.byteLength);
88661
+ }
88662
+ function reviveArrayBuffer(value, global2) {
88663
+ const base642 = value === "." ? "" : value;
88664
+ const buffer = Buffer.from(base642, "base64");
88665
+ const arrayBuffer = new global2.ArrayBuffer(buffer.length);
88666
+ const uint8Array = new global2.Uint8Array(arrayBuffer);
88667
+ uint8Array.set(buffer);
88668
+ return arrayBuffer;
88669
+ }
88670
+ function revive(str) {
88671
+ return JSON.parse(str);
88672
+ }
88673
+ function reduceErrorBase(value) {
88674
+ if (!types$3.isNativeError(value))
88675
+ return false;
88676
+ const reduced = {
88677
+ message: value.message,
88678
+ stack: value.stack
88679
+ };
88680
+ if ("cause" in value)
88681
+ reduced.cause = value.cause;
88682
+ return reduced;
88683
+ }
88684
+ function reduceNamedErrorSubclassBase(subclassName, value) {
88685
+ if (!types$3.isNativeError(value))
88686
+ return false;
88687
+ if (value.name !== subclassName)
88688
+ return false;
88689
+ return reduceErrorBase(value);
88690
+ }
88691
+ function makeErrorSubclassReducer(subclassName) {
88692
+ return (value) => {
88693
+ const base = reduceNamedErrorSubclassBase(subclassName, value);
88694
+ if (!base)
88695
+ return false;
88696
+ return base;
88697
+ };
88698
+ }
88699
+ function makeErrorSubclassReviver(global2, ctorName) {
88700
+ return (value) => {
88701
+ const v2 = value;
88702
+ const opts = "cause" in v2 ? { cause: v2.cause } : void 0;
88703
+ const Ctor = global2[ctorName];
88704
+ const error2 = new Ctor(v2.message, opts);
88705
+ if (v2.stack !== void 0)
88706
+ error2.stack = v2.stack;
88707
+ return error2;
88708
+ };
88709
+ }
88710
+ function getCommonReducers(global2 = globalThis) {
88711
+ return {
88712
+ ArrayBuffer: (value) => value instanceof global2.ArrayBuffer && arrayBufferToBase64(value, 0, value.byteLength),
88713
+ BigInt: (value) => typeof value === "bigint" && value.toString(),
88714
+ BigInt64Array: (value) => value instanceof global2.BigInt64Array && viewToBase64(value),
88715
+ BigUint64Array: (value) => value instanceof global2.BigUint64Array && viewToBase64(value),
88716
+ Date: (value) => {
88717
+ if (!(value instanceof global2.Date))
88718
+ return false;
88719
+ const valid2 = !Number.isNaN(value.getDate());
88720
+ return valid2 ? value.toISOString() : ".";
88721
+ },
88722
+ // DOMException is a special case: it `instanceof Error` is true in Node,
88723
+ // but `types.isNativeError()` returns FALSE for it, so the generic Error
88724
+ // reducer (which gates on isNativeError) won't match. Check it explicitly
88725
+ // by constructor name + Error inheritance so we catch DOMExceptions from
88726
+ // any realm (cross-VM safety: instanceof global.DOMException would fail
88727
+ // for instances minted in another context).
88728
+ DOMException: (value) => {
88729
+ var _a3;
88730
+ if (value === null || typeof value !== "object")
88731
+ return false;
88732
+ if (((_a3 = value.constructor) == null ? void 0 : _a3.name) !== "DOMException")
88733
+ return false;
88734
+ const e = value;
88735
+ const reduced = {
88736
+ message: e.message,
88737
+ name: e.name,
88738
+ stack: e.stack
88739
+ };
88740
+ if ("cause" in e)
88741
+ reduced.cause = e.cause;
88742
+ return reduced;
88743
+ },
88744
+ // Error subclass reducers are intentionally placed before the base Error
88745
+ // reducer because devalue uses first-match-wins. Subclass-specific reducers
88746
+ // must be checked first so that e.g. a TypeError is serialized as "TypeError"
88747
+ // rather than falling through to the generic "Error" reducer.
88748
+ // See `makeErrorSubclassReducer` for implementation details.
88749
+ EvalError: makeErrorSubclassReducer("EvalError"),
88750
+ FatalError: makeErrorSubclassReducer("FatalError"),
88751
+ HookConflictError: (value) => {
88752
+ const base = reduceNamedErrorSubclassBase("HookConflictError", value);
88753
+ if (!base)
88754
+ return false;
88755
+ const error2 = value;
88756
+ const reduced = {
88757
+ ...base,
88758
+ token: error2.token
88759
+ };
88760
+ if (error2.conflictingRunId !== void 0) {
88761
+ reduced.conflictingRunId = error2.conflictingRunId;
88762
+ }
88763
+ return reduced;
88764
+ },
88765
+ RangeError: makeErrorSubclassReducer("RangeError"),
88766
+ ReferenceError: makeErrorSubclassReducer("ReferenceError"),
88767
+ // RetryableError carries an extra `retryAfter` Date that we serialize as
88768
+ // a numeric epoch timestamp. The Date reducer uses `instanceof global.Date`,
88769
+ // which fails for Dates from a different VM realm; serializing as a
88770
+ // number sidesteps that issue.
88771
+ RetryableError: (value) => {
88772
+ const base = reduceNamedErrorSubclassBase("RetryableError", value);
88773
+ if (!base)
88774
+ return false;
88775
+ const retryAfterRaw = value.retryAfter;
88776
+ let retryAfter;
88777
+ if (retryAfterRaw && typeof retryAfterRaw === "object" && typeof retryAfterRaw.getTime === "function") {
88778
+ const t = retryAfterRaw.getTime();
88779
+ retryAfter = Number.isNaN(t) ? Date.now() + 1e3 : t;
88780
+ } else if (typeof retryAfterRaw === "string" || typeof retryAfterRaw === "number") {
88781
+ const t = new Date(retryAfterRaw).getTime();
88782
+ retryAfter = Number.isNaN(t) ? Date.now() + 1e3 : t;
88783
+ } else {
88784
+ retryAfter = Date.now() + 1e3;
88785
+ }
88786
+ return {
88787
+ ...base,
88788
+ retryAfter
88789
+ };
88790
+ },
88791
+ SyntaxError: makeErrorSubclassReducer("SyntaxError"),
88792
+ TypeError: makeErrorSubclassReducer("TypeError"),
88793
+ URIError: makeErrorSubclassReducer("URIError"),
88794
+ // AggregateError is similar to other subclasses but also preserves the
88795
+ // `errors` array. We extend the base helper's output here.
88796
+ AggregateError: (value) => {
88797
+ const base = reduceNamedErrorSubclassBase("AggregateError", value);
88798
+ if (!base)
88799
+ return false;
88800
+ return {
88801
+ ...base,
88802
+ errors: value.errors
88803
+ };
88804
+ },
88805
+ // Base Error reducer — catch-all for any Error instance not matched by a
88806
+ // specific subclass reducer above (including user Error subclasses without
88807
+ // WORKFLOW_SERIALIZE). Preserves `name` so the error's identity is retained
88808
+ // even though the exact class cannot be reconstructed.
88809
+ Error: (value) => {
88810
+ if (!types$3.isNativeError(value))
88811
+ return false;
88812
+ const reduced = {
88813
+ name: value.name,
88814
+ message: value.message,
88815
+ stack: value.stack
88816
+ };
88817
+ if ("cause" in value)
88818
+ reduced.cause = value.cause;
88819
+ return reduced;
88820
+ },
88821
+ Float32Array: (value) => value instanceof global2.Float32Array && viewToBase64(value),
88822
+ Float64Array: (value) => value instanceof global2.Float64Array && viewToBase64(value),
88823
+ Headers: (value) => value instanceof global2.Headers && Array.from(value),
88824
+ Int8Array: (value) => value instanceof global2.Int8Array && viewToBase64(value),
88825
+ Int16Array: (value) => value instanceof global2.Int16Array && viewToBase64(value),
88826
+ Int32Array: (value) => value instanceof global2.Int32Array && viewToBase64(value),
88827
+ Map: (value) => value instanceof global2.Map && Array.from(value),
88828
+ RegExp: (value) => value instanceof global2.RegExp && {
88829
+ source: value.source,
88830
+ flags: value.flags
88831
+ },
88832
+ // Request and Response are intentionally NOT in common reducers.
88833
+ // They require mode-specific revivers (stream handling, etc.) and
88834
+ // including them here without matching revivers would cause them
88835
+ // to deserialize as plain objects.
88836
+ Set: (value) => value instanceof global2.Set && Array.from(value),
88837
+ URL: (value) => value instanceof global2.URL && value.href,
88838
+ WorkflowFunction: (value) => {
88839
+ if (typeof value !== "function")
88840
+ return false;
88841
+ const workflowId = value.workflowId;
88842
+ if (typeof workflowId !== "string")
88843
+ return false;
88844
+ return { workflowId };
88845
+ },
88846
+ URLSearchParams: (value) => {
88847
+ if (!(value instanceof global2.URLSearchParams))
88848
+ return false;
88849
+ if (value.size === 0)
88850
+ return ".";
88851
+ return String(value);
88852
+ },
88853
+ Uint8Array: (value) => value instanceof global2.Uint8Array && viewToBase64(value),
88854
+ Uint8ClampedArray: (value) => value instanceof global2.Uint8ClampedArray && viewToBase64(value),
88855
+ Uint16Array: (value) => value instanceof global2.Uint16Array && viewToBase64(value),
88856
+ Uint32Array: (value) => value instanceof global2.Uint32Array && viewToBase64(value)
88857
+ };
88858
+ }
88859
+ function getCommonRevivers$1(global2 = globalThis) {
88860
+ return {
88861
+ ArrayBuffer: (value) => reviveArrayBuffer(value, global2),
88862
+ BigInt: (value) => global2.BigInt(value),
88863
+ BigInt64Array: (value) => new global2.BigInt64Array(reviveArrayBuffer(value, global2)),
88864
+ BigUint64Array: (value) => new global2.BigUint64Array(reviveArrayBuffer(value, global2)),
88865
+ Date: (value) => new global2.Date(value),
88866
+ DOMException: (value) => {
88867
+ const error2 = new global2.DOMException(value.message, value.name);
88868
+ if (value.stack !== void 0)
88869
+ error2.stack = value.stack;
88870
+ if ("cause" in value)
88871
+ error2.cause = value.cause;
88872
+ return error2;
88873
+ },
88874
+ // Error subclass revivers reconstruct the correct built-in Error type.
88875
+ // See `makeErrorSubclassReviver` for implementation details.
88876
+ EvalError: makeErrorSubclassReviver(global2, "EvalError"),
88877
+ // `FatalError` and `RetryableError` are not built-ins, so we resolve them
88878
+ // from the consumer's `globalThis` via a `Symbol.for(...)` key registered
88879
+ // by `@workflow/errors` on load. This makes `instanceof FatalError` work
88880
+ // in user code that lives in a different realm than this reducer module
88881
+ // (e.g. when the host hydrates a value destined for a workflow VM
88882
+ // context). See the registration block at the bottom of
88883
+ // `packages/errors/src/index.ts` for details. Falls back to the imported
88884
+ // class for environments where no bundled `@workflow/errors` has loaded
88885
+ // in the consumer realm.
88886
+ FatalError: (value) => {
88887
+ const Ctor = global2[Symbol.for("@workflow/errors//FatalError")] ?? FatalError;
88888
+ const error2 = new Ctor(value.message);
88889
+ if (value.stack !== void 0)
88890
+ error2.stack = value.stack;
88891
+ if ("cause" in value)
88892
+ error2.cause = value.cause;
88893
+ return error2;
88894
+ },
88895
+ HookConflictError: (value) => {
88896
+ const Ctor = global2[Symbol.for("@workflow/errors//HookConflictError")] ?? HookConflictError;
88897
+ const error2 = new Ctor(value.token, value.conflictingRunId);
88898
+ if (value.stack !== void 0)
88899
+ error2.stack = value.stack;
88900
+ if ("cause" in value) {
88901
+ error2.cause = value.cause;
88902
+ }
88903
+ return error2;
88904
+ },
88905
+ RangeError: makeErrorSubclassReviver(global2, "RangeError"),
88906
+ ReferenceError: makeErrorSubclassReviver(global2, "ReferenceError"),
88907
+ RetryableError: (value) => {
88908
+ const Ctor = global2[Symbol.for("@workflow/errors//RetryableError")] ?? RetryableError;
88909
+ const error2 = new Ctor(value.message, {
88910
+ retryAfter: new global2.Date(value.retryAfter)
88911
+ });
88912
+ if (value.stack !== void 0)
88913
+ error2.stack = value.stack;
88914
+ if ("cause" in value)
88915
+ error2.cause = value.cause;
88916
+ return error2;
88917
+ },
88918
+ SyntaxError: makeErrorSubclassReviver(global2, "SyntaxError"),
88919
+ TypeError: makeErrorSubclassReviver(global2, "TypeError"),
88920
+ URIError: makeErrorSubclassReviver(global2, "URIError"),
88921
+ AggregateError: (value) => {
88922
+ const opts = "cause" in value ? { cause: value.cause } : void 0;
88923
+ const error2 = new global2.AggregateError(value.errors, value.message, opts);
88924
+ if (value.stack !== void 0)
88925
+ error2.stack = value.stack;
88926
+ return error2;
88927
+ },
88928
+ // Base Error reviver — used for plain Error instances and unrecognized
88929
+ // Error subclasses. Preserves `name` so the error's identity is retained.
88930
+ Error: (value) => {
88931
+ const opts = "cause" in value ? { cause: value.cause } : void 0;
88932
+ const error2 = new global2.Error(value.message, opts);
88933
+ error2.name = value.name;
88934
+ if (value.stack !== void 0)
88935
+ error2.stack = value.stack;
88936
+ return error2;
88937
+ },
88938
+ Float32Array: (value) => new global2.Float32Array(reviveArrayBuffer(value, global2)),
88939
+ Float64Array: (value) => new global2.Float64Array(reviveArrayBuffer(value, global2)),
88940
+ Headers: (value) => new global2.Headers(value),
88941
+ Int8Array: (value) => new global2.Int8Array(reviveArrayBuffer(value, global2)),
88942
+ Int16Array: (value) => new global2.Int16Array(reviveArrayBuffer(value, global2)),
88943
+ Int32Array: (value) => new global2.Int32Array(reviveArrayBuffer(value, global2)),
88944
+ Map: (value) => new global2.Map(value),
88945
+ RegExp: (value) => new global2.RegExp(value.source, value.flags),
88946
+ Set: (value) => new global2.Set(value),
88947
+ URL: (value) => new global2.URL(value),
88948
+ WorkflowFunction: (value) => Object.assign(() => {
88949
+ throw new Error("Workflow functions cannot be called directly. Use start() to invoke them.");
88950
+ }, { workflowId: value.workflowId }),
88951
+ URLSearchParams: (value) => new global2.URLSearchParams(value === "." ? "" : value),
88952
+ Uint8Array: (value) => new global2.Uint8Array(reviveArrayBuffer(value, global2)),
88953
+ Uint8ClampedArray: (value) => new global2.Uint8ClampedArray(reviveArrayBuffer(value, global2)),
88954
+ Uint16Array: (value) => new global2.Uint16Array(reviveArrayBuffer(value, global2)),
88955
+ Uint32Array: (value) => new global2.Uint32Array(reviveArrayBuffer(value, global2))
88956
+ };
88957
+ }
88958
+ function getStepFunctionReducer() {
88959
+ return {
88960
+ StepFunction: (value) => {
88961
+ if (typeof value !== "function")
88962
+ return false;
88963
+ const stepId = value.stepId;
88964
+ if (typeof stepId !== "string")
88965
+ return false;
88966
+ const closureVarsFn = value.__closureVarsFn;
88967
+ const closureVars = closureVarsFn && typeof closureVarsFn === "function" ? closureVarsFn() : void 0;
88968
+ const hasBoundThis = "__boundThis" in value;
88969
+ const boundThis = hasBoundThis ? value.__boundThis : void 0;
88970
+ const boundArgs = value.__boundArgs;
88971
+ const payload = { stepId };
88972
+ if (closureVars !== void 0)
88973
+ payload.closureVars = closureVars;
88974
+ if (hasBoundThis)
88975
+ payload.boundThis = boundThis;
88976
+ if (Array.isArray(boundArgs) && boundArgs.length > 0) {
88977
+ payload.boundArgs = boundArgs;
88978
+ }
88979
+ return payload;
88980
+ }
88981
+ };
88982
+ }
88983
+ function getStepFunctionReviver(global2 = globalThis) {
88984
+ const useStep = global2[Symbol.for("WORKFLOW_USE_STEP")];
88985
+ return {
88986
+ StepFunction: (value) => {
88987
+ const stepId = value.stepId;
88988
+ const closureVars = value.closureVars;
88989
+ if (!useStep) {
88990
+ throw new Error("WORKFLOW_USE_STEP not found on global object. Step functions cannot be deserialized outside workflow context.");
88991
+ }
88992
+ const proxy = closureVars ? useStep(stepId, () => closureVars) : useStep(stepId);
88993
+ if ("boundThis" in value) {
88994
+ const boundArgs = Array.isArray(value.boundArgs) ? value.boundArgs : [];
88995
+ return proxy.bind(value.boundThis, ...boundArgs);
88996
+ }
88997
+ return proxy;
88998
+ }
88999
+ };
89000
+ }
89001
+ function isFormatPrefix(value) {
89002
+ return value.length === 4 && /^[a-z0-9]{4}$/.test(value);
89003
+ }
89004
+ const SerializationFormat = {
89005
+ /** devalue stringify/parse with TextEncoder/TextDecoder */
89006
+ DEVALUE_V1: "devl",
89007
+ /** Encrypted payload (inner payload has its own format prefix) */
89008
+ ENCRYPTED: "encr"
89009
+ };
89010
+ const encoder = new TextEncoder();
89011
+ const decoder = new TextDecoder();
89012
+ function getReducersForMode(mode, global2 = globalThis, extraReducers) {
89013
+ let base;
89014
+ switch (mode) {
89015
+ case "workflow":
89016
+ base = {
89017
+ ...getClassReducers(),
89018
+ ...getStepFunctionReducer(),
89019
+ ...getCommonReducers(global2)
89020
+ };
89021
+ break;
89022
+ case "step":
89023
+ base = {
89024
+ ...getClassReducers(),
89025
+ ...getCommonReducers(global2)
89026
+ };
89027
+ break;
89028
+ case "client":
89029
+ base = {
89030
+ ...getClassReducers(),
89031
+ ...getCommonReducers(global2)
89032
+ };
89033
+ break;
89034
+ }
89035
+ if (extraReducers) {
89036
+ return { ...base, ...extraReducers };
89037
+ }
89038
+ return base;
89039
+ }
89040
+ function getReviversForMode(mode, global2 = globalThis, extraRevivers) {
89041
+ let base;
89042
+ switch (mode) {
89043
+ case "workflow":
89044
+ base = {
89045
+ ...getClassRevivers(global2),
89046
+ ...getStepFunctionReviver(global2),
89047
+ ...getCommonRevivers$1(global2)
89048
+ };
89049
+ break;
89050
+ case "step":
89051
+ base = {
89052
+ ...getClassRevivers(global2),
89053
+ ...getCommonRevivers$1(global2)
89054
+ };
89055
+ break;
89056
+ case "client":
89057
+ base = {
89058
+ ...getClassRevivers(global2),
89059
+ ...getCommonRevivers$1(global2),
89060
+ StepFunction: () => {
89061
+ throw new Error("Step functions cannot be deserialized in client context.");
89062
+ }
89063
+ };
89064
+ break;
89065
+ }
89066
+ if (extraRevivers) {
89067
+ return { ...base, ...extraRevivers };
89068
+ }
89069
+ return base;
89070
+ }
89071
+ const devalueCodec = {
89072
+ formatPrefix: SerializationFormat.DEVALUE_V1,
89073
+ serialize(value, mode, options) {
89074
+ const reducers = getReducersForMode(mode, options == null ? void 0 : options.global, options == null ? void 0 : options.extraReducers);
89075
+ const str = stringify$2(value, reducers);
89076
+ return encoder.encode(str);
89077
+ },
89078
+ deserialize(data, mode, options) {
89079
+ const revivers = getReviversForMode(mode, options == null ? void 0 : options.global, options == null ? void 0 : options.extraRevivers);
89080
+ const str = decoder.decode(data);
89081
+ return parse$7(str, revivers);
89082
+ },
89083
+ deserializeLegacy(data, mode, options) {
89084
+ const revivers = getReviversForMode(mode, options == null ? void 0 : options.global, options == null ? void 0 : options.extraRevivers);
89085
+ return unflatten(data, revivers);
89086
+ }
89087
+ };
89088
+ const FORMAT_PREFIX_LENGTH = 4;
89089
+ const formatEncoder = new TextEncoder();
89090
+ const formatDecoder = new TextDecoder();
89091
+ function encodeWithFormatPrefix(format2, payload) {
89092
+ if (!(payload instanceof Uint8Array)) {
89093
+ return payload;
89094
+ }
89095
+ const prefixBytes = formatEncoder.encode(format2);
89096
+ const result = new Uint8Array(FORMAT_PREFIX_LENGTH + payload.length);
89097
+ result.set(prefixBytes, 0);
89098
+ result.set(payload, FORMAT_PREFIX_LENGTH);
89099
+ return result;
89100
+ }
89101
+ function peekFormatPrefix(data) {
89102
+ if (!(data instanceof Uint8Array) || data.length < FORMAT_PREFIX_LENGTH) {
89103
+ return null;
89104
+ }
89105
+ const prefixBytes = data.subarray(0, FORMAT_PREFIX_LENGTH);
89106
+ const str = formatDecoder.decode(prefixBytes);
89107
+ return isFormatPrefix(str) ? str : null;
89108
+ }
89109
+ function decodeFormatPrefix(data) {
89110
+ if (!(data instanceof Uint8Array)) {
89111
+ return {
89112
+ format: SerializationFormat.DEVALUE_V1,
89113
+ payload: new TextEncoder().encode(JSON.stringify(data))
89114
+ };
89115
+ }
89116
+ if (data.length < FORMAT_PREFIX_LENGTH) {
89117
+ throw new Error(`Data too short to contain format prefix: expected at least ${FORMAT_PREFIX_LENGTH} bytes, got ${data.length}`);
89118
+ }
89119
+ const prefixBytes = data.subarray(0, FORMAT_PREFIX_LENGTH);
89120
+ const str = formatDecoder.decode(prefixBytes);
89121
+ if (!isFormatPrefix(str)) {
89122
+ throw new Error(`Invalid format prefix: "${str}". Must be 4 characters of [a-z0-9].`);
89123
+ }
89124
+ const payload = data.subarray(FORMAT_PREFIX_LENGTH);
89125
+ return { format: str, payload };
89126
+ }
89127
+ async function encrypt(data, key) {
89128
+ if (!key || !(data instanceof Uint8Array))
89129
+ return data;
89130
+ const encrypted = await encrypt$1(key, data);
89131
+ return encodeWithFormatPrefix(SerializationFormat.ENCRYPTED, encrypted);
89132
+ }
89133
+ async function decrypt(data, key) {
89134
+ if (!(data instanceof Uint8Array))
89135
+ return data;
89136
+ const format2 = peekFormatPrefix(data);
89137
+ if (format2 === SerializationFormat.ENCRYPTED && !key) {
89138
+ throw new WorkflowRuntimeError("Encrypted data encountered but no encryption key is available. Encryption is not configured or no key was provided for this run.");
89139
+ }
89140
+ if (format2 !== SerializationFormat.ENCRYPTED)
89141
+ return data;
89142
+ const { payload } = decodeFormatPrefix(data);
89143
+ return decrypt$1(key, payload);
89144
+ }
89145
+ function formatSerializationError(context, error2) {
89146
+ const verb = context.includes("return value") ? "returning" : "passing";
89147
+ let message2 = `Failed to serialize ${context}`;
89148
+ if (error2 instanceof DevalueError && error2.path) {
89149
+ message2 += ` at path "${error2.path}"`;
89150
+ }
89151
+ const hint2 = `Ensure you're ${verb} workflow serializable types. Check the serialization docs to see what's serializable: https://workflow-sdk.dev/docs/foundations/serialization`;
89152
+ if (error2 instanceof DevalueError && error2.value !== void 0) {
89153
+ runtimeLogger.error("Serialization failed", {
89154
+ context,
89155
+ problematicValue: error2.value
89156
+ });
89157
+ }
89158
+ return { message: message2, hint: hint2 };
89159
+ }
89160
+ async function serialize$1(value, encryptionKey, options) {
89161
+ try {
89162
+ const payload = devalueCodec.serialize(value, "client", options);
89163
+ const prefixed = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
89164
+ return encrypt(prefixed, encryptionKey);
89165
+ } catch (error2) {
89166
+ const { message: message2, hint: hint2 } = formatSerializationError("client value", error2);
89167
+ throw new SerializationError(message2, { hint: hint2, cause: error2 });
89168
+ }
89169
+ }
89170
+ async function deserialize$2(data, encryptionKey, options) {
89171
+ const decrypted = await decrypt(data, encryptionKey);
89172
+ if (!(decrypted instanceof Uint8Array)) {
89173
+ if (devalueCodec.deserializeLegacy) {
89174
+ return devalueCodec.deserializeLegacy(decrypted, "client", options);
89175
+ }
89176
+ throw new Error("Cannot deserialize non-binary data without legacy support");
89177
+ }
89178
+ const { format: format2, payload } = decodeFormatPrefix(decrypted);
89179
+ if (format2 === SerializationFormat.DEVALUE_V1) {
89180
+ return devalueCodec.deserialize(payload, "client", options);
89181
+ }
89182
+ throw new Error(`Unsupported serialization format: ${format2}`);
89183
+ }
89184
+ async function serialize(value, encryptionKey, options) {
89185
+ try {
89186
+ const payload = devalueCodec.serialize(value, "step", options);
89187
+ const prefixed = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
89188
+ return encrypt(prefixed, encryptionKey);
89189
+ } catch (error2) {
89190
+ const { message: message2, hint: hint2 } = formatSerializationError("step value", error2);
89191
+ throw new SerializationError(message2, { hint: hint2, cause: error2 });
89192
+ }
89193
+ }
89194
+ async function deserialize$1(data, encryptionKey, options) {
89195
+ const decrypted = await decrypt(data, encryptionKey);
89196
+ if (!(decrypted instanceof Uint8Array)) {
89197
+ if (devalueCodec.deserializeLegacy) {
89198
+ return devalueCodec.deserializeLegacy(decrypted, "step", options);
89199
+ }
89200
+ throw new Error("Cannot deserialize non-binary data without legacy support");
89201
+ }
89202
+ const { format: format2, payload } = decodeFormatPrefix(decrypted);
89203
+ if (format2 === SerializationFormat.DEVALUE_V1) {
89204
+ return devalueCodec.deserialize(payload, "step", options);
89205
+ }
89206
+ throw new Error(`Unsupported serialization format: ${format2}`);
89207
+ }
89208
+ function deserialize(data, options) {
89209
+ if (!(data instanceof Uint8Array)) {
89210
+ if (devalueCodec.deserializeLegacy) {
89211
+ return devalueCodec.deserializeLegacy(data, "workflow", options);
89212
+ }
89213
+ throw new Error("Cannot deserialize non-binary data without legacy support");
89214
+ }
89215
+ const { format: format2, payload } = decodeFormatPrefix(data);
89216
+ if (format2 === SerializationFormat.DEVALUE_V1) {
89217
+ return devalueCodec.deserialize(payload, "workflow", options);
89218
+ }
89219
+ throw new Error(`Unsupported serialization format: ${format2}`);
89220
+ }
89221
+ const CONTEXT_STORAGE_SYMBOL = Symbol.for("WORKFLOW_STEP_CONTEXT_STORAGE");
89222
+ const contextStorage = globalThis[CONTEXT_STORAGE_SYMBOL] ?? (globalThis[CONTEXT_STORAGE_SYMBOL] = new AsyncLocalStorage());
88264
89223
  var headers$1;
88265
89224
  var hasRequiredHeaders$1;
88266
89225
  function requireHeaders$1() {
@@ -89353,848 +90312,6 @@ function requireFunctions() {
89353
90312
  return functions;
89354
90313
  }
89355
90314
  var functionsExports = requireFunctions();
89356
- const RegisteredStepsKey = Symbol.for("@workflow/core//registeredSteps");
89357
- const globalSymbols$1 = globalThis;
89358
- const registeredSteps = globalSymbols$1[RegisteredStepsKey] ?? (globalSymbols$1[RegisteredStepsKey] = /* @__PURE__ */ new Map());
89359
- const BUILTIN_RESPONSE_STEP_NAMES = /* @__PURE__ */ new Set([
89360
- "__builtin_response_array_buffer",
89361
- "__builtin_response_json",
89362
- "__builtin_response_text"
89363
- ]);
89364
- function getStepIdAliasCandidates(stepId) {
89365
- const parts = stepId.split("//");
89366
- if (parts.length !== 3 || parts[0] !== "step") {
89367
- return [];
89368
- }
89369
- const modulePath = parts[1];
89370
- const fnName = parts[2];
89371
- const modulePathAliases = /* @__PURE__ */ new Set();
89372
- const addAlias = (aliasModulePath) => {
89373
- if (aliasModulePath !== modulePath) {
89374
- modulePathAliases.add(aliasModulePath);
89375
- }
89376
- };
89377
- if (modulePath.startsWith("./workflows/")) {
89378
- const workflowRelativePath = modulePath.slice("./".length);
89379
- addAlias(`./example/${workflowRelativePath}`);
89380
- addAlias(`./src/${workflowRelativePath}`);
89381
- } else if (modulePath.startsWith("./example/workflows/")) {
89382
- const workflowRelativePath = modulePath.slice("./example/".length);
89383
- addAlias(`./${workflowRelativePath}`);
89384
- addAlias(`./src/${workflowRelativePath}`);
89385
- } else if (modulePath.startsWith("./src/workflows/")) {
89386
- const workflowRelativePath = modulePath.slice("./src/".length);
89387
- addAlias(`./${workflowRelativePath}`);
89388
- addAlias(`./example/${workflowRelativePath}`);
89389
- }
89390
- return Array.from(modulePathAliases, (aliasModulePath) => `step//${aliasModulePath}//${fnName}`);
89391
- }
89392
- function getBuiltinResponseStepAlias(stepId) {
89393
- if (!BUILTIN_RESPONSE_STEP_NAMES.has(stepId)) {
89394
- return void 0;
89395
- }
89396
- for (const [registeredStepId, stepFn] of registeredSteps.entries()) {
89397
- if (registeredStepId.endsWith(`//${stepId}`)) {
89398
- return stepFn;
89399
- }
89400
- }
89401
- return void 0;
89402
- }
89403
- function getStepFunction(stepId) {
89404
- const directMatch = registeredSteps.get(stepId);
89405
- if (directMatch) {
89406
- return directMatch;
89407
- }
89408
- for (const aliasStepId of getStepIdAliasCandidates(stepId)) {
89409
- const aliasMatch = registeredSteps.get(aliasStepId);
89410
- if (aliasMatch) {
89411
- return aliasMatch;
89412
- }
89413
- }
89414
- const builtinAliasMatch = getBuiltinResponseStepAlias(stepId);
89415
- if (builtinAliasMatch) {
89416
- return builtinAliasMatch;
89417
- }
89418
- return void 0;
89419
- }
89420
- const LOCK_POLL_INTERVAL_MS = 10;
89421
- function createFlushableState() {
89422
- return {
89423
- ...withResolvers$1(),
89424
- pendingOps: 0,
89425
- doneResolved: false,
89426
- streamEnded: false
89427
- };
89428
- }
89429
- function isWritableUnlockedNotClosed(writable) {
89430
- if (writable.locked)
89431
- return false;
89432
- let writer;
89433
- try {
89434
- writer = writable.getWriter();
89435
- } catch {
89436
- return false;
89437
- }
89438
- try {
89439
- writer.releaseLock();
89440
- } catch {
89441
- return false;
89442
- }
89443
- return true;
89444
- }
89445
- function isReadableUnlockedNotClosed(readable2) {
89446
- if (readable2.locked)
89447
- return false;
89448
- let reader;
89449
- try {
89450
- reader = readable2.getReader();
89451
- } catch {
89452
- return false;
89453
- }
89454
- try {
89455
- reader.releaseLock();
89456
- } catch {
89457
- return false;
89458
- }
89459
- return true;
89460
- }
89461
- function pollWritableLock(writable, state) {
89462
- if (state.writablePollingInterval !== void 0) {
89463
- return;
89464
- }
89465
- const intervalId = setInterval(() => {
89466
- if (state.doneResolved || state.streamEnded) {
89467
- clearInterval(intervalId);
89468
- state.writablePollingInterval = void 0;
89469
- return;
89470
- }
89471
- if (isWritableUnlockedNotClosed(writable) && state.pendingOps === 0) {
89472
- state.doneResolved = true;
89473
- state.resolve();
89474
- clearInterval(intervalId);
89475
- state.writablePollingInterval = void 0;
89476
- }
89477
- }, LOCK_POLL_INTERVAL_MS);
89478
- state.writablePollingInterval = intervalId;
89479
- }
89480
- function pollReadableLock(readable2, state) {
89481
- if (state.readablePollingInterval !== void 0) {
89482
- return;
89483
- }
89484
- const intervalId = setInterval(() => {
89485
- if (state.doneResolved || state.streamEnded) {
89486
- clearInterval(intervalId);
89487
- state.readablePollingInterval = void 0;
89488
- return;
89489
- }
89490
- if (isReadableUnlockedNotClosed(readable2) && state.pendingOps === 0) {
89491
- state.doneResolved = true;
89492
- state.resolve();
89493
- clearInterval(intervalId);
89494
- state.readablePollingInterval = void 0;
89495
- }
89496
- }, LOCK_POLL_INTERVAL_MS);
89497
- state.readablePollingInterval = intervalId;
89498
- }
89499
- async function flushablePipe(source, sink, state) {
89500
- const reader = source.getReader();
89501
- const writer = sink.getWriter();
89502
- let cancelReason;
89503
- try {
89504
- while (true) {
89505
- if (state.streamEnded) {
89506
- return;
89507
- }
89508
- const readResult = await Promise.race([
89509
- reader.read(),
89510
- writer.closed.then(() => {
89511
- throw new WorkflowRuntimeError("Writable stream closed prematurely");
89512
- })
89513
- ]);
89514
- if (state.streamEnded) {
89515
- return;
89516
- }
89517
- if (readResult.done) {
89518
- state.streamEnded = true;
89519
- await writer.close();
89520
- if (!state.doneResolved) {
89521
- state.doneResolved = true;
89522
- state.resolve();
89523
- }
89524
- return;
89525
- }
89526
- state.pendingOps++;
89527
- try {
89528
- await writer.write(readResult.value);
89529
- } finally {
89530
- state.pendingOps--;
89531
- }
89532
- }
89533
- } catch (err) {
89534
- state.streamEnded = true;
89535
- cancelReason = err;
89536
- if (!state.doneResolved) {
89537
- state.doneResolved = true;
89538
- state.reject(err);
89539
- }
89540
- throw err;
89541
- } finally {
89542
- reader.cancel(cancelReason).catch(() => {
89543
- });
89544
- reader.releaseLock();
89545
- writer.releaseLock();
89546
- }
89547
- }
89548
- const WORKFLOW_SERIALIZE = Symbol.for("workflow-serialize");
89549
- const WORKFLOW_DESERIALIZE = Symbol.for("workflow-deserialize");
89550
- const STABLE_ULID = Symbol.for("WORKFLOW_STABLE_ULID");
89551
- const STREAM_NAME_SYMBOL = Symbol.for("WORKFLOW_STREAM_NAME");
89552
- const STREAM_TYPE_SYMBOL = Symbol.for("WORKFLOW_STREAM_TYPE");
89553
- const BODY_INIT_SYMBOL = Symbol.for("BODY_INIT");
89554
- const WEBHOOK_RESPONSE_WRITABLE = Symbol.for("WEBHOOK_RESPONSE_WRITABLE");
89555
- const WORKFLOW_CLASS_REGISTRY = Symbol.for("workflow-class-registry");
89556
- const ABORT_STREAM_NAME = Symbol.for("WORKFLOW_ABORT_STREAM_NAME");
89557
- const ABORT_HOOK_TOKEN = Symbol.for("WORKFLOW_ABORT_HOOK_TOKEN");
89558
- const ABORT_LISTENER_ATTACHED = Symbol.for("WORKFLOW_ABORT_LISTENER_ATTACHED");
89559
- const ABORT_READER_CANCEL = Symbol.for("WORKFLOW_ABORT_READER_CANCEL");
89560
- function getRegistry(global2 = globalThis) {
89561
- const g2 = global2;
89562
- let registry2 = g2[WORKFLOW_CLASS_REGISTRY];
89563
- if (!registry2) {
89564
- registry2 = /* @__PURE__ */ new Map();
89565
- g2[WORKFLOW_CLASS_REGISTRY] = registry2;
89566
- }
89567
- return registry2;
89568
- }
89569
- function getSerializationClass(classId, global2) {
89570
- return getRegistry(global2).get(classId);
89571
- }
89572
- function getClassReducers() {
89573
- return {
89574
- // Class and Instance are intentionally placed before Error so that
89575
- // custom Error subclasses with WORKFLOW_SERIALIZE take precedence
89576
- // over the generic Error serialization (devalue uses first-match-wins).
89577
- Class: (value) => {
89578
- if (typeof value !== "function")
89579
- return false;
89580
- const classId = value.classId;
89581
- if (typeof classId !== "string")
89582
- return false;
89583
- return { classId };
89584
- },
89585
- Instance: (value) => {
89586
- if (value === null || typeof value !== "object")
89587
- return false;
89588
- const cls = value.constructor;
89589
- if (!cls || typeof cls !== "function")
89590
- return false;
89591
- const serialize2 = cls[WORKFLOW_SERIALIZE];
89592
- if (typeof serialize2 !== "function")
89593
- return false;
89594
- const classId = cls.classId;
89595
- if (typeof classId !== "string") {
89596
- throw new Error(`Class "${cls.name}" with ${String(WORKFLOW_SERIALIZE)} must have a static "classId" property.`);
89597
- }
89598
- const data = serialize2.call(cls, value);
89599
- return { classId, data };
89600
- }
89601
- };
89602
- }
89603
- function getClassRevivers(global2 = globalThis) {
89604
- return {
89605
- Class: (value) => {
89606
- const classId = value.classId;
89607
- const cls = getSerializationClass(classId, global2);
89608
- if (!cls) {
89609
- throw new Error(`Class "${classId}" not found. Make sure the class is registered with registerSerializationClass.`);
89610
- }
89611
- return cls;
89612
- },
89613
- Instance: (value) => {
89614
- const classId = value.classId;
89615
- const data = value.data;
89616
- const cls = getSerializationClass(classId, global2);
89617
- if (!cls) {
89618
- throw new Error(`Class "${classId}" not found. Make sure the class is registered with registerSerializationClass.`);
89619
- }
89620
- const deserialize2 = cls[WORKFLOW_DESERIALIZE];
89621
- if (typeof deserialize2 !== "function") {
89622
- throw new Error(`Class "${classId}" does not have a static ${String(WORKFLOW_DESERIALIZE)} method.`);
89623
- }
89624
- return deserialize2.call(cls, data);
89625
- }
89626
- };
89627
- }
89628
- function arrayBufferToBase64(value, offset2, length) {
89629
- if (length === 0)
89630
- return ".";
89631
- const uint8 = new Uint8Array(value, offset2, length);
89632
- return Buffer.from(uint8).toString("base64");
89633
- }
89634
- function viewToBase64(value) {
89635
- return arrayBufferToBase64(value.buffer, value.byteOffset, value.byteLength);
89636
- }
89637
- function reviveArrayBuffer(value, global2) {
89638
- const base642 = value === "." ? "" : value;
89639
- const buffer = Buffer.from(base642, "base64");
89640
- const arrayBuffer = new global2.ArrayBuffer(buffer.length);
89641
- const uint8Array = new global2.Uint8Array(arrayBuffer);
89642
- uint8Array.set(buffer);
89643
- return arrayBuffer;
89644
- }
89645
- function revive(str) {
89646
- return JSON.parse(str);
89647
- }
89648
- function reduceErrorBase(value) {
89649
- if (!types$3.isNativeError(value))
89650
- return false;
89651
- const reduced = {
89652
- message: value.message,
89653
- stack: value.stack
89654
- };
89655
- if ("cause" in value)
89656
- reduced.cause = value.cause;
89657
- return reduced;
89658
- }
89659
- function reduceNamedErrorSubclassBase(subclassName, value) {
89660
- if (!types$3.isNativeError(value))
89661
- return false;
89662
- if (value.name !== subclassName)
89663
- return false;
89664
- return reduceErrorBase(value);
89665
- }
89666
- function makeErrorSubclassReducer(subclassName) {
89667
- return (value) => {
89668
- const base = reduceNamedErrorSubclassBase(subclassName, value);
89669
- if (!base)
89670
- return false;
89671
- return base;
89672
- };
89673
- }
89674
- function makeErrorSubclassReviver(global2, ctorName) {
89675
- return (value) => {
89676
- const v2 = value;
89677
- const opts = "cause" in v2 ? { cause: v2.cause } : void 0;
89678
- const Ctor = global2[ctorName];
89679
- const error2 = new Ctor(v2.message, opts);
89680
- if (v2.stack !== void 0)
89681
- error2.stack = v2.stack;
89682
- return error2;
89683
- };
89684
- }
89685
- function getCommonReducers(global2 = globalThis) {
89686
- return {
89687
- ArrayBuffer: (value) => value instanceof global2.ArrayBuffer && arrayBufferToBase64(value, 0, value.byteLength),
89688
- BigInt: (value) => typeof value === "bigint" && value.toString(),
89689
- BigInt64Array: (value) => value instanceof global2.BigInt64Array && viewToBase64(value),
89690
- BigUint64Array: (value) => value instanceof global2.BigUint64Array && viewToBase64(value),
89691
- Date: (value) => {
89692
- if (!(value instanceof global2.Date))
89693
- return false;
89694
- const valid2 = !Number.isNaN(value.getDate());
89695
- return valid2 ? value.toISOString() : ".";
89696
- },
89697
- // DOMException is a special case: it `instanceof Error` is true in Node,
89698
- // but `types.isNativeError()` returns FALSE for it, so the generic Error
89699
- // reducer (which gates on isNativeError) won't match. Check it explicitly
89700
- // by constructor name + Error inheritance so we catch DOMExceptions from
89701
- // any realm (cross-VM safety: instanceof global.DOMException would fail
89702
- // for instances minted in another context).
89703
- DOMException: (value) => {
89704
- var _a3;
89705
- if (value === null || typeof value !== "object")
89706
- return false;
89707
- if (((_a3 = value.constructor) == null ? void 0 : _a3.name) !== "DOMException")
89708
- return false;
89709
- const e = value;
89710
- const reduced = {
89711
- message: e.message,
89712
- name: e.name,
89713
- stack: e.stack
89714
- };
89715
- if ("cause" in e)
89716
- reduced.cause = e.cause;
89717
- return reduced;
89718
- },
89719
- // Error subclass reducers are intentionally placed before the base Error
89720
- // reducer because devalue uses first-match-wins. Subclass-specific reducers
89721
- // must be checked first so that e.g. a TypeError is serialized as "TypeError"
89722
- // rather than falling through to the generic "Error" reducer.
89723
- // See `makeErrorSubclassReducer` for implementation details.
89724
- EvalError: makeErrorSubclassReducer("EvalError"),
89725
- FatalError: makeErrorSubclassReducer("FatalError"),
89726
- HookConflictError: (value) => {
89727
- const base = reduceNamedErrorSubclassBase("HookConflictError", value);
89728
- if (!base)
89729
- return false;
89730
- const error2 = value;
89731
- const reduced = {
89732
- ...base,
89733
- token: error2.token
89734
- };
89735
- if (error2.conflictingRunId !== void 0) {
89736
- reduced.conflictingRunId = error2.conflictingRunId;
89737
- }
89738
- return reduced;
89739
- },
89740
- RangeError: makeErrorSubclassReducer("RangeError"),
89741
- ReferenceError: makeErrorSubclassReducer("ReferenceError"),
89742
- // RetryableError carries an extra `retryAfter` Date that we serialize as
89743
- // a numeric epoch timestamp. The Date reducer uses `instanceof global.Date`,
89744
- // which fails for Dates from a different VM realm; serializing as a
89745
- // number sidesteps that issue.
89746
- RetryableError: (value) => {
89747
- const base = reduceNamedErrorSubclassBase("RetryableError", value);
89748
- if (!base)
89749
- return false;
89750
- const retryAfterRaw = value.retryAfter;
89751
- let retryAfter;
89752
- if (retryAfterRaw && typeof retryAfterRaw === "object" && typeof retryAfterRaw.getTime === "function") {
89753
- const t = retryAfterRaw.getTime();
89754
- retryAfter = Number.isNaN(t) ? Date.now() + 1e3 : t;
89755
- } else if (typeof retryAfterRaw === "string" || typeof retryAfterRaw === "number") {
89756
- const t = new Date(retryAfterRaw).getTime();
89757
- retryAfter = Number.isNaN(t) ? Date.now() + 1e3 : t;
89758
- } else {
89759
- retryAfter = Date.now() + 1e3;
89760
- }
89761
- return {
89762
- ...base,
89763
- retryAfter
89764
- };
89765
- },
89766
- SyntaxError: makeErrorSubclassReducer("SyntaxError"),
89767
- TypeError: makeErrorSubclassReducer("TypeError"),
89768
- URIError: makeErrorSubclassReducer("URIError"),
89769
- // AggregateError is similar to other subclasses but also preserves the
89770
- // `errors` array. We extend the base helper's output here.
89771
- AggregateError: (value) => {
89772
- const base = reduceNamedErrorSubclassBase("AggregateError", value);
89773
- if (!base)
89774
- return false;
89775
- return {
89776
- ...base,
89777
- errors: value.errors
89778
- };
89779
- },
89780
- // Base Error reducer — catch-all for any Error instance not matched by a
89781
- // specific subclass reducer above (including user Error subclasses without
89782
- // WORKFLOW_SERIALIZE). Preserves `name` so the error's identity is retained
89783
- // even though the exact class cannot be reconstructed.
89784
- Error: (value) => {
89785
- if (!types$3.isNativeError(value))
89786
- return false;
89787
- const reduced = {
89788
- name: value.name,
89789
- message: value.message,
89790
- stack: value.stack
89791
- };
89792
- if ("cause" in value)
89793
- reduced.cause = value.cause;
89794
- return reduced;
89795
- },
89796
- Float32Array: (value) => value instanceof global2.Float32Array && viewToBase64(value),
89797
- Float64Array: (value) => value instanceof global2.Float64Array && viewToBase64(value),
89798
- Headers: (value) => value instanceof global2.Headers && Array.from(value),
89799
- Int8Array: (value) => value instanceof global2.Int8Array && viewToBase64(value),
89800
- Int16Array: (value) => value instanceof global2.Int16Array && viewToBase64(value),
89801
- Int32Array: (value) => value instanceof global2.Int32Array && viewToBase64(value),
89802
- Map: (value) => value instanceof global2.Map && Array.from(value),
89803
- RegExp: (value) => value instanceof global2.RegExp && {
89804
- source: value.source,
89805
- flags: value.flags
89806
- },
89807
- // Request and Response are intentionally NOT in common reducers.
89808
- // They require mode-specific revivers (stream handling, etc.) and
89809
- // including them here without matching revivers would cause them
89810
- // to deserialize as plain objects.
89811
- Set: (value) => value instanceof global2.Set && Array.from(value),
89812
- URL: (value) => value instanceof global2.URL && value.href,
89813
- WorkflowFunction: (value) => {
89814
- if (typeof value !== "function")
89815
- return false;
89816
- const workflowId = value.workflowId;
89817
- if (typeof workflowId !== "string")
89818
- return false;
89819
- return { workflowId };
89820
- },
89821
- URLSearchParams: (value) => {
89822
- if (!(value instanceof global2.URLSearchParams))
89823
- return false;
89824
- if (value.size === 0)
89825
- return ".";
89826
- return String(value);
89827
- },
89828
- Uint8Array: (value) => value instanceof global2.Uint8Array && viewToBase64(value),
89829
- Uint8ClampedArray: (value) => value instanceof global2.Uint8ClampedArray && viewToBase64(value),
89830
- Uint16Array: (value) => value instanceof global2.Uint16Array && viewToBase64(value),
89831
- Uint32Array: (value) => value instanceof global2.Uint32Array && viewToBase64(value)
89832
- };
89833
- }
89834
- function getCommonRevivers$1(global2 = globalThis) {
89835
- return {
89836
- ArrayBuffer: (value) => reviveArrayBuffer(value, global2),
89837
- BigInt: (value) => global2.BigInt(value),
89838
- BigInt64Array: (value) => new global2.BigInt64Array(reviveArrayBuffer(value, global2)),
89839
- BigUint64Array: (value) => new global2.BigUint64Array(reviveArrayBuffer(value, global2)),
89840
- Date: (value) => new global2.Date(value),
89841
- DOMException: (value) => {
89842
- const error2 = new global2.DOMException(value.message, value.name);
89843
- if (value.stack !== void 0)
89844
- error2.stack = value.stack;
89845
- if ("cause" in value)
89846
- error2.cause = value.cause;
89847
- return error2;
89848
- },
89849
- // Error subclass revivers reconstruct the correct built-in Error type.
89850
- // See `makeErrorSubclassReviver` for implementation details.
89851
- EvalError: makeErrorSubclassReviver(global2, "EvalError"),
89852
- // `FatalError` and `RetryableError` are not built-ins, so we resolve them
89853
- // from the consumer's `globalThis` via a `Symbol.for(...)` key registered
89854
- // by `@workflow/errors` on load. This makes `instanceof FatalError` work
89855
- // in user code that lives in a different realm than this reducer module
89856
- // (e.g. when the host hydrates a value destined for a workflow VM
89857
- // context). See the registration block at the bottom of
89858
- // `packages/errors/src/index.ts` for details. Falls back to the imported
89859
- // class for environments where no bundled `@workflow/errors` has loaded
89860
- // in the consumer realm.
89861
- FatalError: (value) => {
89862
- const Ctor = global2[Symbol.for("@workflow/errors//FatalError")] ?? FatalError;
89863
- const error2 = new Ctor(value.message);
89864
- if (value.stack !== void 0)
89865
- error2.stack = value.stack;
89866
- if ("cause" in value)
89867
- error2.cause = value.cause;
89868
- return error2;
89869
- },
89870
- HookConflictError: (value) => {
89871
- const Ctor = global2[Symbol.for("@workflow/errors//HookConflictError")] ?? HookConflictError;
89872
- const error2 = new Ctor(value.token, value.conflictingRunId);
89873
- if (value.stack !== void 0)
89874
- error2.stack = value.stack;
89875
- if ("cause" in value) {
89876
- error2.cause = value.cause;
89877
- }
89878
- return error2;
89879
- },
89880
- RangeError: makeErrorSubclassReviver(global2, "RangeError"),
89881
- ReferenceError: makeErrorSubclassReviver(global2, "ReferenceError"),
89882
- RetryableError: (value) => {
89883
- const Ctor = global2[Symbol.for("@workflow/errors//RetryableError")] ?? RetryableError;
89884
- const error2 = new Ctor(value.message, {
89885
- retryAfter: new global2.Date(value.retryAfter)
89886
- });
89887
- if (value.stack !== void 0)
89888
- error2.stack = value.stack;
89889
- if ("cause" in value)
89890
- error2.cause = value.cause;
89891
- return error2;
89892
- },
89893
- SyntaxError: makeErrorSubclassReviver(global2, "SyntaxError"),
89894
- TypeError: makeErrorSubclassReviver(global2, "TypeError"),
89895
- URIError: makeErrorSubclassReviver(global2, "URIError"),
89896
- AggregateError: (value) => {
89897
- const opts = "cause" in value ? { cause: value.cause } : void 0;
89898
- const error2 = new global2.AggregateError(value.errors, value.message, opts);
89899
- if (value.stack !== void 0)
89900
- error2.stack = value.stack;
89901
- return error2;
89902
- },
89903
- // Base Error reviver — used for plain Error instances and unrecognized
89904
- // Error subclasses. Preserves `name` so the error's identity is retained.
89905
- Error: (value) => {
89906
- const opts = "cause" in value ? { cause: value.cause } : void 0;
89907
- const error2 = new global2.Error(value.message, opts);
89908
- error2.name = value.name;
89909
- if (value.stack !== void 0)
89910
- error2.stack = value.stack;
89911
- return error2;
89912
- },
89913
- Float32Array: (value) => new global2.Float32Array(reviveArrayBuffer(value, global2)),
89914
- Float64Array: (value) => new global2.Float64Array(reviveArrayBuffer(value, global2)),
89915
- Headers: (value) => new global2.Headers(value),
89916
- Int8Array: (value) => new global2.Int8Array(reviveArrayBuffer(value, global2)),
89917
- Int16Array: (value) => new global2.Int16Array(reviveArrayBuffer(value, global2)),
89918
- Int32Array: (value) => new global2.Int32Array(reviveArrayBuffer(value, global2)),
89919
- Map: (value) => new global2.Map(value),
89920
- RegExp: (value) => new global2.RegExp(value.source, value.flags),
89921
- Set: (value) => new global2.Set(value),
89922
- URL: (value) => new global2.URL(value),
89923
- WorkflowFunction: (value) => Object.assign(() => {
89924
- throw new Error("Workflow functions cannot be called directly. Use start() to invoke them.");
89925
- }, { workflowId: value.workflowId }),
89926
- URLSearchParams: (value) => new global2.URLSearchParams(value === "." ? "" : value),
89927
- Uint8Array: (value) => new global2.Uint8Array(reviveArrayBuffer(value, global2)),
89928
- Uint8ClampedArray: (value) => new global2.Uint8ClampedArray(reviveArrayBuffer(value, global2)),
89929
- Uint16Array: (value) => new global2.Uint16Array(reviveArrayBuffer(value, global2)),
89930
- Uint32Array: (value) => new global2.Uint32Array(reviveArrayBuffer(value, global2))
89931
- };
89932
- }
89933
- function getStepFunctionReducer() {
89934
- return {
89935
- StepFunction: (value) => {
89936
- if (typeof value !== "function")
89937
- return false;
89938
- const stepId = value.stepId;
89939
- if (typeof stepId !== "string")
89940
- return false;
89941
- const closureVarsFn = value.__closureVarsFn;
89942
- const closureVars = closureVarsFn && typeof closureVarsFn === "function" ? closureVarsFn() : void 0;
89943
- const hasBoundThis = "__boundThis" in value;
89944
- const boundThis = hasBoundThis ? value.__boundThis : void 0;
89945
- const boundArgs = value.__boundArgs;
89946
- const payload = { stepId };
89947
- if (closureVars !== void 0)
89948
- payload.closureVars = closureVars;
89949
- if (hasBoundThis)
89950
- payload.boundThis = boundThis;
89951
- if (Array.isArray(boundArgs) && boundArgs.length > 0) {
89952
- payload.boundArgs = boundArgs;
89953
- }
89954
- return payload;
89955
- }
89956
- };
89957
- }
89958
- function getStepFunctionReviver(global2 = globalThis) {
89959
- const useStep = global2[Symbol.for("WORKFLOW_USE_STEP")];
89960
- return {
89961
- StepFunction: (value) => {
89962
- const stepId = value.stepId;
89963
- const closureVars = value.closureVars;
89964
- if (!useStep) {
89965
- throw new Error("WORKFLOW_USE_STEP not found on global object. Step functions cannot be deserialized outside workflow context.");
89966
- }
89967
- const proxy = closureVars ? useStep(stepId, () => closureVars) : useStep(stepId);
89968
- if ("boundThis" in value) {
89969
- const boundArgs = Array.isArray(value.boundArgs) ? value.boundArgs : [];
89970
- return proxy.bind(value.boundThis, ...boundArgs);
89971
- }
89972
- return proxy;
89973
- }
89974
- };
89975
- }
89976
- function isFormatPrefix(value) {
89977
- return value.length === 4 && /^[a-z0-9]{4}$/.test(value);
89978
- }
89979
- const SerializationFormat = {
89980
- /** devalue stringify/parse with TextEncoder/TextDecoder */
89981
- DEVALUE_V1: "devl",
89982
- /** Encrypted payload (inner payload has its own format prefix) */
89983
- ENCRYPTED: "encr"
89984
- };
89985
- const encoder = new TextEncoder();
89986
- const decoder = new TextDecoder();
89987
- function getReducersForMode(mode, global2 = globalThis, extraReducers) {
89988
- let base;
89989
- switch (mode) {
89990
- case "workflow":
89991
- base = {
89992
- ...getClassReducers(),
89993
- ...getStepFunctionReducer(),
89994
- ...getCommonReducers(global2)
89995
- };
89996
- break;
89997
- case "step":
89998
- base = {
89999
- ...getClassReducers(),
90000
- ...getCommonReducers(global2)
90001
- };
90002
- break;
90003
- case "client":
90004
- base = {
90005
- ...getClassReducers(),
90006
- ...getCommonReducers(global2)
90007
- };
90008
- break;
90009
- }
90010
- if (extraReducers) {
90011
- return { ...base, ...extraReducers };
90012
- }
90013
- return base;
90014
- }
90015
- function getReviversForMode(mode, global2 = globalThis, extraRevivers) {
90016
- let base;
90017
- switch (mode) {
90018
- case "workflow":
90019
- base = {
90020
- ...getClassRevivers(global2),
90021
- ...getStepFunctionReviver(global2),
90022
- ...getCommonRevivers$1(global2)
90023
- };
90024
- break;
90025
- case "step":
90026
- base = {
90027
- ...getClassRevivers(global2),
90028
- ...getCommonRevivers$1(global2)
90029
- };
90030
- break;
90031
- case "client":
90032
- base = {
90033
- ...getClassRevivers(global2),
90034
- ...getCommonRevivers$1(global2),
90035
- StepFunction: () => {
90036
- throw new Error("Step functions cannot be deserialized in client context.");
90037
- }
90038
- };
90039
- break;
90040
- }
90041
- if (extraRevivers) {
90042
- return { ...base, ...extraRevivers };
90043
- }
90044
- return base;
90045
- }
90046
- const devalueCodec = {
90047
- formatPrefix: SerializationFormat.DEVALUE_V1,
90048
- serialize(value, mode, options) {
90049
- const reducers = getReducersForMode(mode, options == null ? void 0 : options.global, options == null ? void 0 : options.extraReducers);
90050
- const str = stringify$2(value, reducers);
90051
- return encoder.encode(str);
90052
- },
90053
- deserialize(data, mode, options) {
90054
- const revivers = getReviversForMode(mode, options == null ? void 0 : options.global, options == null ? void 0 : options.extraRevivers);
90055
- const str = decoder.decode(data);
90056
- return parse$7(str, revivers);
90057
- },
90058
- deserializeLegacy(data, mode, options) {
90059
- const revivers = getReviversForMode(mode, options == null ? void 0 : options.global, options == null ? void 0 : options.extraRevivers);
90060
- return unflatten(data, revivers);
90061
- }
90062
- };
90063
- const FORMAT_PREFIX_LENGTH = 4;
90064
- const formatEncoder = new TextEncoder();
90065
- const formatDecoder = new TextDecoder();
90066
- function encodeWithFormatPrefix(format2, payload) {
90067
- if (!(payload instanceof Uint8Array)) {
90068
- return payload;
90069
- }
90070
- const prefixBytes = formatEncoder.encode(format2);
90071
- const result = new Uint8Array(FORMAT_PREFIX_LENGTH + payload.length);
90072
- result.set(prefixBytes, 0);
90073
- result.set(payload, FORMAT_PREFIX_LENGTH);
90074
- return result;
90075
- }
90076
- function peekFormatPrefix(data) {
90077
- if (!(data instanceof Uint8Array) || data.length < FORMAT_PREFIX_LENGTH) {
90078
- return null;
90079
- }
90080
- const prefixBytes = data.subarray(0, FORMAT_PREFIX_LENGTH);
90081
- const str = formatDecoder.decode(prefixBytes);
90082
- return isFormatPrefix(str) ? str : null;
90083
- }
90084
- function decodeFormatPrefix(data) {
90085
- if (!(data instanceof Uint8Array)) {
90086
- return {
90087
- format: SerializationFormat.DEVALUE_V1,
90088
- payload: new TextEncoder().encode(JSON.stringify(data))
90089
- };
90090
- }
90091
- if (data.length < FORMAT_PREFIX_LENGTH) {
90092
- throw new Error(`Data too short to contain format prefix: expected at least ${FORMAT_PREFIX_LENGTH} bytes, got ${data.length}`);
90093
- }
90094
- const prefixBytes = data.subarray(0, FORMAT_PREFIX_LENGTH);
90095
- const str = formatDecoder.decode(prefixBytes);
90096
- if (!isFormatPrefix(str)) {
90097
- throw new Error(`Invalid format prefix: "${str}". Must be 4 characters of [a-z0-9].`);
90098
- }
90099
- const payload = data.subarray(FORMAT_PREFIX_LENGTH);
90100
- return { format: str, payload };
90101
- }
90102
- async function encrypt(data, key) {
90103
- if (!key || !(data instanceof Uint8Array))
90104
- return data;
90105
- const encrypted = await encrypt$1(key, data);
90106
- return encodeWithFormatPrefix(SerializationFormat.ENCRYPTED, encrypted);
90107
- }
90108
- async function decrypt(data, key) {
90109
- if (!(data instanceof Uint8Array))
90110
- return data;
90111
- const format2 = peekFormatPrefix(data);
90112
- if (format2 === SerializationFormat.ENCRYPTED && !key) {
90113
- throw new WorkflowRuntimeError("Encrypted data encountered but no encryption key is available. Encryption is not configured or no key was provided for this run.");
90114
- }
90115
- if (format2 !== SerializationFormat.ENCRYPTED)
90116
- return data;
90117
- const { payload } = decodeFormatPrefix(data);
90118
- return decrypt$1(key, payload);
90119
- }
90120
- function formatSerializationError(context, error2) {
90121
- const verb = context.includes("return value") ? "returning" : "passing";
90122
- let message2 = `Failed to serialize ${context}`;
90123
- if (error2 instanceof DevalueError && error2.path) {
90124
- message2 += ` at path "${error2.path}"`;
90125
- }
90126
- const hint2 = `Ensure you're ${verb} workflow serializable types. Check the serialization docs to see what's serializable: https://workflow-sdk.dev/docs/foundations/serialization`;
90127
- if (error2 instanceof DevalueError && error2.value !== void 0) {
90128
- runtimeLogger.error("Serialization failed", {
90129
- context,
90130
- problematicValue: error2.value
90131
- });
90132
- }
90133
- return { message: message2, hint: hint2 };
90134
- }
90135
- async function serialize$1(value, encryptionKey, options) {
90136
- try {
90137
- const payload = devalueCodec.serialize(value, "client", options);
90138
- const prefixed = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
90139
- return encrypt(prefixed, encryptionKey);
90140
- } catch (error2) {
90141
- const { message: message2, hint: hint2 } = formatSerializationError("client value", error2);
90142
- throw new SerializationError(message2, { hint: hint2, cause: error2 });
90143
- }
90144
- }
90145
- async function deserialize$2(data, encryptionKey, options) {
90146
- const decrypted = await decrypt(data, encryptionKey);
90147
- if (!(decrypted instanceof Uint8Array)) {
90148
- if (devalueCodec.deserializeLegacy) {
90149
- return devalueCodec.deserializeLegacy(decrypted, "client", options);
90150
- }
90151
- throw new Error("Cannot deserialize non-binary data without legacy support");
90152
- }
90153
- const { format: format2, payload } = decodeFormatPrefix(decrypted);
90154
- if (format2 === SerializationFormat.DEVALUE_V1) {
90155
- return devalueCodec.deserialize(payload, "client", options);
90156
- }
90157
- throw new Error(`Unsupported serialization format: ${format2}`);
90158
- }
90159
- async function serialize(value, encryptionKey, options) {
90160
- try {
90161
- const payload = devalueCodec.serialize(value, "step", options);
90162
- const prefixed = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
90163
- return encrypt(prefixed, encryptionKey);
90164
- } catch (error2) {
90165
- const { message: message2, hint: hint2 } = formatSerializationError("step value", error2);
90166
- throw new SerializationError(message2, { hint: hint2, cause: error2 });
90167
- }
90168
- }
90169
- async function deserialize$1(data, encryptionKey, options) {
90170
- const decrypted = await decrypt(data, encryptionKey);
90171
- if (!(decrypted instanceof Uint8Array)) {
90172
- if (devalueCodec.deserializeLegacy) {
90173
- return devalueCodec.deserializeLegacy(decrypted, "step", options);
90174
- }
90175
- throw new Error("Cannot deserialize non-binary data without legacy support");
90176
- }
90177
- const { format: format2, payload } = decodeFormatPrefix(decrypted);
90178
- if (format2 === SerializationFormat.DEVALUE_V1) {
90179
- return devalueCodec.deserialize(payload, "step", options);
90180
- }
90181
- throw new Error(`Unsupported serialization format: ${format2}`);
90182
- }
90183
- function deserialize(data, options) {
90184
- if (!(data instanceof Uint8Array)) {
90185
- if (devalueCodec.deserializeLegacy) {
90186
- return devalueCodec.deserializeLegacy(data, "workflow", options);
90187
- }
90188
- throw new Error("Cannot deserialize non-binary data without legacy support");
90189
- }
90190
- const { format: format2, payload } = decodeFormatPrefix(data);
90191
- if (format2 === SerializationFormat.DEVALUE_V1) {
90192
- return devalueCodec.deserialize(payload, "workflow", options);
90193
- }
90194
- throw new Error(`Unsupported serialization format: ${format2}`);
90195
- }
90196
- const CONTEXT_STORAGE_SYMBOL = Symbol.for("WORKFLOW_STEP_CONTEXT_STORAGE");
90197
- const contextStorage = globalThis[CONTEXT_STORAGE_SYMBOL] ?? (globalThis[CONTEXT_STORAGE_SYMBOL] = new AsyncLocalStorage());
90198
90315
  function getWorkflowRunStreamId(runId, namespace2) {
90199
90316
  const streamId = `${runId.replace("wrun_", "strm_")}_user`;
90200
90317
  if (!namespace2) {
@@ -90646,6 +90763,11 @@ function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey) {
90646
90763
  WritableStream: (value) => {
90647
90764
  if (!(value instanceof global2.WritableStream))
90648
90765
  return false;
90766
+ const existingName = value[STREAM_NAME_SYMBOL];
90767
+ const existingRunId = value[STREAM_SERVER_RUN_ID_SYMBOL];
90768
+ if (typeof existingName === "string" && typeof existingRunId === "string") {
90769
+ return { name: existingName, runId: existingRunId };
90770
+ }
90649
90771
  const streamId = (global2[STABLE_ULID] || defaultUlid)();
90650
90772
  const name2 = `strm_${streamId}`;
90651
90773
  const readable2 = new WorkflowServerReadableStream(runId, name2);
@@ -90693,7 +90815,11 @@ function getWorkflowReducers(global2 = globalThis) {
90693
90815
  if (!name2) {
90694
90816
  throw new WorkflowRuntimeError("WritableStream `name` is not set");
90695
90817
  }
90696
- return { name: name2 };
90818
+ const s2 = { name: name2 };
90819
+ const foreignRunId = value[STREAM_SERVER_RUN_ID_SYMBOL];
90820
+ if (typeof foreignRunId === "string")
90821
+ s2.runId = foreignRunId;
90822
+ return s2;
90697
90823
  },
90698
90824
  // AbortController/AbortSignal in workflow context — just read symbols (handles).
90699
90825
  // In the workflow VM, global.AbortController is a class but global.AbortSignal
@@ -90753,12 +90879,16 @@ function getStepReducers(global2 = globalThis, ops, runId, cryptoKey) {
90753
90879
  if (!(value instanceof global2.WritableStream))
90754
90880
  return false;
90755
90881
  let name2 = value[STREAM_NAME_SYMBOL];
90882
+ const foreignRunId = value[STREAM_SERVER_RUN_ID_SYMBOL];
90756
90883
  if (!name2) {
90757
90884
  const streamId = (global2[STABLE_ULID] || defaultUlid)();
90758
90885
  name2 = `strm_${streamId}`;
90759
90886
  ops.push(new WorkflowServerReadableStream(runId, name2).pipeThrough(getDeserializeStream(getStepRevivers(global2, ops, runId, cryptoKey), cryptoKey)).pipeTo(value));
90760
90887
  }
90761
- return { name: name2 };
90888
+ const s2 = { name: name2 };
90889
+ if (typeof foreignRunId === "string")
90890
+ s2.runId = foreignRunId;
90891
+ return s2;
90762
90892
  },
90763
90893
  AbortController: (value) => {
90764
90894
  if (!global2.AbortController || typeof global2.AbortController !== "function" || !(value instanceof global2.AbortController))
@@ -90952,13 +91082,28 @@ function getExternalRevivers(global2 = globalThis, ops, runId, cryptoKey) {
90952
91082
  }
90953
91083
  },
90954
91084
  WritableStream: (value) => {
90955
- const serialize2 = getSerializeStream(getExternalReducers(global2, ops, runId, cryptoKey), cryptoKey);
90956
- const serverWritable = new WorkflowServerWritableStream(runId, value.name);
91085
+ const targetRunId = typeof value.runId === "string" ? value.runId : runId;
91086
+ const targetKey = targetRunId === runId ? cryptoKey : (async () => {
91087
+ var _a3;
91088
+ const world = await getWorldLazy();
91089
+ const rawKey = await ((_a3 = world.getEncryptionKeyForRun) == null ? void 0 : _a3.call(world, targetRunId));
91090
+ return rawKey ? await importKey(rawKey, ["encrypt"]) : void 0;
91091
+ })();
91092
+ const serialize2 = getSerializeStream(getExternalReducers(global2, ops, targetRunId, targetKey), targetKey);
91093
+ const serverWritable = new WorkflowServerWritableStream(targetRunId, value.name);
90957
91094
  const state = createFlushableState();
90958
91095
  ops.push(state.promise);
90959
91096
  flushablePipe(serialize2.readable, serverWritable, state).catch(() => {
90960
91097
  });
90961
91098
  pollWritableLock(serialize2.writable, state);
91099
+ Object.defineProperty(serialize2.writable, STREAM_NAME_SYMBOL, {
91100
+ value: value.name,
91101
+ writable: false
91102
+ });
91103
+ Object.defineProperty(serialize2.writable, STREAM_SERVER_RUN_ID_SYMBOL, {
91104
+ value: targetRunId,
91105
+ writable: false
91106
+ });
90962
91107
  return serialize2.writable;
90963
91108
  },
90964
91109
  AbortController: (value) => reviveAbortController(value, ops, runId),
@@ -91017,12 +91162,19 @@ function getWorkflowRevivers(global2 = globalThis) {
91017
91162
  });
91018
91163
  },
91019
91164
  WritableStream: (value) => {
91020
- return Object.create(global2.WritableStream.prototype, {
91165
+ const descriptor = {
91021
91166
  [STREAM_NAME_SYMBOL]: {
91022
91167
  value: value.name,
91023
91168
  writable: false
91024
91169
  }
91025
- });
91170
+ };
91171
+ if (typeof value.runId === "string") {
91172
+ descriptor[STREAM_SERVER_RUN_ID_SYMBOL] = {
91173
+ value: value.runId,
91174
+ writable: false
91175
+ };
91176
+ }
91177
+ return Object.create(global2.WritableStream.prototype, descriptor);
91026
91178
  },
91027
91179
  // AbortController/AbortSignal revived inside the workflow VM. Use the
91028
91180
  // real WorkflowAbortSignal class so addEventListener('abort', fn) actually
@@ -91177,13 +91329,28 @@ function getStepRevivers(global2 = globalThis, ops, runId, cryptoKey) {
91177
91329
  }
91178
91330
  },
91179
91331
  WritableStream: (value) => {
91180
- const serialize2 = getSerializeStream(getStepReducers(global2, ops, runId, cryptoKey), cryptoKey);
91181
- const serverWritable = new WorkflowServerWritableStream(runId, value.name);
91332
+ const targetRunId = typeof value.runId === "string" ? value.runId : runId;
91333
+ const targetKey = targetRunId === runId ? cryptoKey : (async () => {
91334
+ var _a3;
91335
+ const world = await getWorldLazy();
91336
+ const rawKey = await ((_a3 = world.getEncryptionKeyForRun) == null ? void 0 : _a3.call(world, targetRunId));
91337
+ return rawKey ? await importKey(rawKey, ["encrypt"]) : void 0;
91338
+ })();
91339
+ const serialize2 = getSerializeStream(getStepReducers(global2, ops, targetRunId, targetKey), targetKey);
91340
+ const serverWritable = new WorkflowServerWritableStream(targetRunId, value.name);
91182
91341
  const state = createFlushableState();
91183
91342
  ops.push(state.promise);
91184
91343
  flushablePipe(serialize2.readable, serverWritable, state).catch(() => {
91185
91344
  });
91186
91345
  pollWritableLock(serialize2.writable, state);
91346
+ Object.defineProperty(serialize2.writable, STREAM_NAME_SYMBOL, {
91347
+ value: value.name,
91348
+ writable: false
91349
+ });
91350
+ Object.defineProperty(serialize2.writable, STREAM_SERVER_RUN_ID_SYMBOL, {
91351
+ value: targetRunId,
91352
+ writable: false
91353
+ });
91187
91354
  return serialize2.writable;
91188
91355
  },
91189
91356
  AbortController: (value) => reviveAbortController(value, ops, runId),
@@ -117246,16 +117413,21 @@ function createEventsStorage(basedir, tag) {
117246
117413
  const resolveData = (params == null ? void 0 : params.resolveData) ?? DEFAULT_RESOLVE_DATA_OPTION$1;
117247
117414
  const filteredEvent = stripEventDataRefs(event, resolveData);
117248
117415
  let events2;
117416
+ let cursor;
117417
+ let hasMore;
117249
117418
  if (data.eventType === "run_started" && run) {
117250
117419
  const allEvents = await paginatedFileSystemQuery({
117251
117420
  directory: path$3.join(basedir, "events"),
117252
117421
  schema: EventSchema,
117253
117422
  filePrefix: `${effectiveRunId}-`,
117254
117423
  sortOrder: "asc",
117424
+ limit: 1e3,
117255
117425
  getCreatedAt: getObjectCreatedAt("evnt"),
117256
117426
  getId: (e) => e.eventId
117257
117427
  });
117258
117428
  events2 = allEvents.data;
117429
+ cursor = allEvents.cursor;
117430
+ hasMore = allEvents.hasMore;
117259
117431
  }
117260
117432
  return {
117261
117433
  event: filteredEvent,
@@ -117263,7 +117435,9 @@ function createEventsStorage(basedir, tag) {
117263
117435
  step,
117264
117436
  hook,
117265
117437
  wait,
117266
- events: events2
117438
+ events: events2,
117439
+ cursor,
117440
+ hasMore
117267
117441
  };
117268
117442
  }
117269
117443
  },
@@ -117835,7 +118009,7 @@ function createLocalWorld(args) {
117835
118009
  const basedir = mergedConfig.dataDir;
117836
118010
  const hooksDir = path$3.join(basedir, "hooks");
117837
118011
  const taggedHookFiles = await listTaggedFiles(hooksDir, tag);
117838
- const { HookSchema: HookSchema2 } = await import("./index-CRYPN_tt.js");
118012
+ const { HookSchema: HookSchema2 } = await import("./index-B_Gtun0B.js");
117839
118013
  await Promise.all(taggedHookFiles.map(async (hookFile) => {
117840
118014
  const hook = await readJSON(path$3.join(hooksDir, hookFile), HookSchema2);
117841
118015
  if (hook == null ? void 0 : hook.token) {
@@ -117987,8 +118161,8 @@ function requireGetVercelOidcToken() {
117987
118161
  }
117988
118162
  try {
117989
118163
  const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([
117990
- await import("./token-util-DUvMx9Gj.js").then((n) => n.t),
117991
- await import("./token-CZpVopko.js").then((n) => n.t)
118164
+ await import("./token-util-CHxt50WW.js").then((n) => n.t),
118165
+ await import("./token-98GkKm4t.js").then((n) => n.t)
117992
118166
  ]);
117993
118167
  if (!token || isExpired(getTokenPayload(token), options == null ? void 0 : options.expirationBufferMs)) {
117994
118168
  await refreshToken(options);
@@ -123159,7 +123333,7 @@ var QueueClient = class {
123159
123333
  setApi(this, new ApiClient({ ...options, region }));
123160
123334
  }
123161
123335
  };
123162
- const version = "5.0.0-beta.5";
123336
+ const version = "5.0.0-beta.6";
123163
123337
  const HTTP_DEBUG_ENABLED = typeof process !== "undefined" && typeof process.env.DEBUG === "string" && (process.env.DEBUG.includes("workflow:") || process.env.DEBUG === "*");
123164
123338
  function httpLog(method, endpoint, status, ms2) {
123165
123339
  if (HTTP_DEBUG_ENABLED) {
@@ -123350,7 +123524,7 @@ curl -X ${request2.method} ${stringifiedHeaders} "${url2}"`);
123350
123524
  const contentType = response2.headers.get("Content-Type") || "unknown";
123351
123525
  throw new WorkflowWorldError(`Failed to parse response body for ${request2.method} ${endpoint} (Content-Type: ${contentType}):
123352
123526
 
123353
- ${error2}`, { url: url2, cause: error2 });
123527
+ ${error2}`, { url: url2, code: "PARSE_ERROR", cause: error2 });
123354
123528
  }
123355
123529
  const result = await trace("world.validate", async () => {
123356
123530
  const validationResult = schema.safeParse(parseResult.data);
@@ -123360,7 +123534,7 @@ ${error2}`, { url: url2, cause: error2 });
123360
123534
 
123361
123535
  Response context: ${parseResult.getDebugContext()}` : "";
123362
123536
  throw new WorkflowWorldError(`Schema validation failed for ${method} ${endpoint}:
123363
- ${issues}${debugContext}`, { url: url2, cause: validationResult.error });
123537
+ ${issues}${debugContext}`, { url: url2, code: "SCHEMA_VALIDATION", cause: validationResult.error });
123364
123538
  }
123365
123539
  return validationResult.data;
123366
123540
  });
@@ -123916,14 +124090,18 @@ const EventResultResolveWireSchema = z$2.object({
123916
124090
  run: WorkflowRunSchema.optional(),
123917
124091
  step: StepWireSchema.optional(),
123918
124092
  hook: HookSchema.optional(),
123919
- events: z$2.array(EventSchema).optional()
124093
+ events: z$2.array(EventSchema).optional(),
124094
+ cursor: z$2.string().nullable().optional(),
124095
+ hasMore: z$2.boolean().optional()
123920
124096
  });
123921
124097
  const EventResultLazyWireSchema = z$2.object({
123922
124098
  event: EventSchema.optional(),
123923
124099
  run: WorkflowRunWireBaseSchema.optional(),
123924
124100
  step: StepWireSchema.optional(),
123925
124101
  hook: HookSchema.optional(),
123926
- events: z$2.array(EventSchema).optional()
124102
+ events: z$2.array(EventSchema).optional(),
124103
+ cursor: z$2.string().nullable().optional(),
124104
+ hasMore: z$2.boolean().optional()
123927
124105
  });
123928
124106
  const EventWithRefsSchema = z$2.object({
123929
124107
  eventId: z$2.string(),
@@ -124166,7 +124344,9 @@ async function createWorkflowRunEventInner(id2, data, params, config2) {
124166
124344
  run: wireResult2.run,
124167
124345
  step: wireResult2.step ? deserializeStep(wireResult2.step) : void 0,
124168
124346
  hook: wireResult2.hook,
124169
- events: wireResult2.events
124347
+ events: wireResult2.events,
124348
+ cursor: wireResult2.cursor,
124349
+ hasMore: wireResult2.hasMore
124170
124350
  };
124171
124351
  }
124172
124352
  const wireResult = await makeRequest({
@@ -124185,7 +124365,9 @@ async function createWorkflowRunEventInner(id2, data, params, config2) {
124185
124365
  run: wireResult.run ? deserializeError(wireResult.run) : void 0,
124186
124366
  step: wireResult.step ? deserializeStep(wireResult.step) : void 0,
124187
124367
  hook: wireResult.hook,
124188
- events: wireResult.events
124368
+ events: wireResult.events,
124369
+ cursor: wireResult.cursor,
124370
+ hasMore: wireResult.hasMore
124189
124371
  };
124190
124372
  }
124191
124373
  function filterHookData(hook, resolveData) {
@@ -124430,6 +124612,12 @@ function createVercelWorld(config2) {
124430
124612
  const projectId = ((_a3 = config2 == null ? void 0 : config2.projectConfig) == null ? void 0 : _a3.projectId) || process.env.VERCEL_PROJECT_ID;
124431
124613
  return {
124432
124614
  specVersion: SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT,
124615
+ // On Vercel the platform fails the function invocation when the
124616
+ // process exits non-zero, and VQS redelivers the queue message via a
124617
+ // fresh invocation. The core runtime uses this to decide whether
124618
+ // `process.exit(1)` is an acceptable response to an exhausted replay
124619
+ // budget.
124620
+ processExitTriggersQueueRedelivery: true,
124433
124621
  ...createQueue$1(config2),
124434
124622
  ...createStorage(config2),
124435
124623
  ...instrumentObject("world.streams", createStreamer(config2)),
@@ -127221,6 +127409,7 @@ async function resumeHook$2(tokenOrHook, payload, encryptionKeyOverride) {
127221
127409
  specVersion: SPEC_VERSION_CURRENT,
127222
127410
  correlationId: hook.hookId,
127223
127411
  eventData: {
127412
+ ...v1Compat ? {} : { token: hook.token },
127224
127413
  payload: dehydratedPayload
127225
127414
  }
127226
127415
  }, { v1Compat });
@@ -127496,7 +127685,10 @@ async function wakeUpRun$2(world, runId, options) {
127496
127685
  } : {
127497
127686
  eventType: "wait_completed",
127498
127687
  correlationId: waitEvent.correlationId,
127499
- specVersion: run.specVersion
127688
+ specVersion: run.specVersion,
127689
+ eventData: {
127690
+ resumeAt: waitEvent.eventData.resumeAt
127691
+ }
127500
127692
  };
127501
127693
  try {
127502
127694
  await world.events.create(runId, eventData, { v1Compat: compatMode });
@@ -150996,7 +151188,7 @@ const route4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
150996
151188
  __proto__: null,
150997
151189
  loader
150998
151190
  }, Symbol.toStringTag, { value: "Module" }));
150999
- const serverManifest = { "entry": { "module": "/assets/entry.client-DtOpLtMQ.js", "imports": ["/assets/index-BsV8i_Jn.js"], "css": [] }, "routes": { "root": { "id": "root", "parentId": void 0, "path": "", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/root-DCSDR-Tx.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/mermaid-3ZIDBTTL-D3hhpLut.js"], "css": ["/assets/root-5XHFuftH.css", "/assets/mermaid-3ZIDBTTL-DKxHcEOp.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/home": { "id": "routes/home", "parentId": "root", "path": void 0, "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": false, "module": "/assets/home-DmK2qlF4.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/workflow-graph-viewer-Bl8eU-PY.js", "/assets/mermaid-3ZIDBTTL-D3hhpLut.js", "/assets/index-Byi8AWfe.js"], "css": ["/assets/workflow-graph-viewer-DnlNuQQH.css", "/assets/mermaid-3ZIDBTTL-DKxHcEOp.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/run-detail": { "id": "routes/run-detail", "parentId": "root", "path": "run/:runId", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": false, "module": "/assets/run-detail-qu2t8u4x.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/workflow-graph-viewer-Bl8eU-PY.js", "/assets/mermaid-3ZIDBTTL-D3hhpLut.js", "/assets/encryption-DU49MAQV.js", "/assets/index-Byi8AWfe.js"], "css": ["/assets/workflow-graph-viewer-DnlNuQQH.css", "/assets/mermaid-3ZIDBTTL-DKxHcEOp.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/api.rpc": { "id": "routes/api.rpc", "parentId": "root", "path": "api/rpc", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": false, "hasErrorBoundary": false, "module": "/assets/api.rpc-l0sNRNKZ.js", "imports": [], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/api.stream.$streamId": { "id": "routes/api.stream.$streamId", "parentId": "root", "path": "api/stream/:streamId", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": false, "hasErrorBoundary": false, "module": "/assets/api.stream._streamId-l0sNRNKZ.js", "imports": [], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 } }, "url": "/assets/manifest-f8f46e3c.js", "version": "f8f46e3c", "sri": void 0 };
151191
+ const serverManifest = { "entry": { "module": "/assets/entry.client-DtOpLtMQ.js", "imports": ["/assets/index-BsV8i_Jn.js"], "css": [] }, "routes": { "root": { "id": "root", "parentId": void 0, "path": "", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": true, "module": "/assets/root-DDT0W3fG.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/mermaid-3ZIDBTTL-PK-k2mDG.js"], "css": ["/assets/root-B527kgKt.css", "/assets/mermaid-3ZIDBTTL-DKxHcEOp.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/home": { "id": "routes/home", "parentId": "root", "path": void 0, "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": false, "module": "/assets/home-B-DWbULo.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/workflow-graph-viewer-CVUKAMV1.js", "/assets/mermaid-3ZIDBTTL-PK-k2mDG.js", "/assets/index-Byi8AWfe.js"], "css": ["/assets/workflow-graph-viewer-DnlNuQQH.css", "/assets/mermaid-3ZIDBTTL-DKxHcEOp.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/run-detail": { "id": "routes/run-detail", "parentId": "root", "path": "run/:runId", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": true, "hasErrorBoundary": false, "module": "/assets/run-detail-COyTZwjr.js", "imports": ["/assets/index-BsV8i_Jn.js", "/assets/workflow-graph-viewer-CVUKAMV1.js", "/assets/mermaid-3ZIDBTTL-PK-k2mDG.js", "/assets/encryption-C69WMRfh.js", "/assets/index-Byi8AWfe.js"], "css": ["/assets/workflow-graph-viewer-DnlNuQQH.css", "/assets/mermaid-3ZIDBTTL-DKxHcEOp.css"], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/api.rpc": { "id": "routes/api.rpc", "parentId": "root", "path": "api/rpc", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": false, "hasErrorBoundary": false, "module": "/assets/api.rpc-l0sNRNKZ.js", "imports": [], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 }, "routes/api.stream.$streamId": { "id": "routes/api.stream.$streamId", "parentId": "root", "path": "api/stream/:streamId", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasClientMiddleware": false, "hasDefaultExport": false, "hasErrorBoundary": false, "module": "/assets/api.stream._streamId-l0sNRNKZ.js", "imports": [], "css": [], "clientActionModule": void 0, "clientLoaderModule": void 0, "clientMiddlewareModule": void 0, "hydrateFallbackModule": void 0 } }, "url": "/assets/manifest-21016363.js", "version": "21016363", "sri": void 0 };
151000
151192
  const assetsBuildDirectory = "build/client";
151001
151193
  const basename = "/";
151002
151194
  const future = { "unstable_optimizeDeps": false, "unstable_subResourceIntegrity": false, "unstable_trailingSlashAwareDataRequests": false, "unstable_previewServerPrerendering": false, "v8_middleware": false, "v8_splitRouteModules": false, "v8_viteEnvironmentApi": false };