@workflow/web 5.0.0-beta.23 → 5.0.0-beta.25

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 (25) hide show
  1. package/build/client/assets/{highlighted-body-B3W2YXNL-pQbU-Oll.js → highlighted-body-B3W2YXNL-QrddlyZu.js} +1 -1
  2. package/build/client/assets/{home-Dz43xne_.js → home-BNApVOct.js} +2 -2
  3. package/build/client/assets/{manifest-608c3c54.js → manifest-379f050f.js} +1 -1
  4. package/build/client/assets/{mermaid-3ZIDBTTL-C_xy8SxZ.js → mermaid-3ZIDBTTL-Cg-Mp5Kj.js} +218 -100
  5. package/build/client/assets/{root-BlFmfRST.js → root-BsPxYsbK.js} +1 -1
  6. package/build/client/assets/root-F_dqJDC7.css +1 -0
  7. package/build/client/assets/{run-detail-C34zz02I.js → run-detail-sr7StYc6.js} +354 -331
  8. package/build/client/assets/server-build-DVBDkRDS.css +1 -0
  9. package/build/client/assets/{workflow-graph-viewer-BlDVZ5AU.js → workflow-graph-viewer-CcCwLmnF.js} +1 -1
  10. package/build/client/assets/{zstd-browser-decoder-Biv4GTD9.js → zstd-browser-decoder-OOeWOMJw.js} +1 -1
  11. package/build/server/assets/{app-BgELNM37.js → app-e2FYIgWU.js} +5 -1
  12. package/build/server/assets/{highlighted-body-B3W2YXNL-CP60Gm_l.js → highlighted-body-B3W2YXNL-B7xcG7gl.js} +6 -2
  13. package/build/server/assets/{index-D7poz6vJ.js → index-BELZxbAO.js} +7 -3
  14. package/build/server/assets/{index-C7C6cDW5.js → index-BafExO0s.js} +4 -0
  15. package/build/server/assets/{index-B8YoYr9f.js → index-DIXsjgfZ.js} +4 -0
  16. package/build/server/assets/{index-meg9qk8y.js → index-Dq5jTBN4.js} +4 -0
  17. package/build/server/assets/{mermaid-3ZIDBTTL-PK-HMOJq.js → mermaid-3ZIDBTTL-DQqBhQ9Y.js} +6 -2
  18. package/build/server/assets/{server-build-DAfWosK8.js → server-build-D7EgG_DH.js} +745 -510
  19. package/build/server/assets/{token-BCYgRbLT.js → token-guLCf66r.js} +6 -2
  20. package/build/server/assets/{token-util-M95T0pVo.js → token-util-CCeU4-vR.js} +6 -2
  21. package/build/server/assets/{zstd-browser-decoder-eXH_mKQG.js → zstd-browser-decoder-CcinVfMP.js} +7 -3
  22. package/build/server/index.js +5 -1
  23. package/package.json +5 -5
  24. package/build/client/assets/root-61NXpLSs.css +0 -1
  25. package/build/client/assets/server-build-B8TvrR_Z.css +0 -1
@@ -14,7 +14,11 @@ 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, _d, _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, getEncryptionKeyLazily_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-BgELNM37.js";
17
+ import { createRequire as __wkfCreateRequire } from "node:module";
18
+ if (typeof require === "undefined") {
19
+ globalThis.require = __wkfCreateRequire(import.meta.url);
20
+ }
21
+ 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-e2FYIgWU.js";
18
22
  import require$$0$4, { PassThrough } from "node:stream";
19
23
  import require$$0 from "util";
20
24
  import require$$1 from "crypto";
@@ -30043,6 +30047,54 @@ const getDefaultConfig = () => {
30043
30047
  orderSensitiveModifiers: ["*", "**", "after", "backdrop", "before", "details-content", "file", "first-letter", "first-line", "marker", "placeholder", "selection"]
30044
30048
  };
30045
30049
  };
30050
+ const mergeConfigs = (baseConfig, {
30051
+ cacheSize,
30052
+ prefix,
30053
+ experimentalParseClassName,
30054
+ extend: extend2 = {},
30055
+ override = {}
30056
+ }) => {
30057
+ overrideProperty(baseConfig, "cacheSize", cacheSize);
30058
+ overrideProperty(baseConfig, "prefix", prefix);
30059
+ overrideProperty(baseConfig, "experimentalParseClassName", experimentalParseClassName);
30060
+ overrideConfigProperties(baseConfig.theme, override.theme);
30061
+ overrideConfigProperties(baseConfig.classGroups, override.classGroups);
30062
+ overrideConfigProperties(baseConfig.conflictingClassGroups, override.conflictingClassGroups);
30063
+ overrideConfigProperties(baseConfig.conflictingClassGroupModifiers, override.conflictingClassGroupModifiers);
30064
+ overrideProperty(baseConfig, "orderSensitiveModifiers", override.orderSensitiveModifiers);
30065
+ mergeConfigProperties(baseConfig.theme, extend2.theme);
30066
+ mergeConfigProperties(baseConfig.classGroups, extend2.classGroups);
30067
+ mergeConfigProperties(baseConfig.conflictingClassGroups, extend2.conflictingClassGroups);
30068
+ mergeConfigProperties(baseConfig.conflictingClassGroupModifiers, extend2.conflictingClassGroupModifiers);
30069
+ mergeArrayProperties(baseConfig, extend2, "orderSensitiveModifiers");
30070
+ return baseConfig;
30071
+ };
30072
+ const overrideProperty = (baseObject, overrideKey, overrideValue) => {
30073
+ if (overrideValue !== void 0) {
30074
+ baseObject[overrideKey] = overrideValue;
30075
+ }
30076
+ };
30077
+ const overrideConfigProperties = (baseObject, overrideObject) => {
30078
+ if (overrideObject) {
30079
+ for (const key in overrideObject) {
30080
+ overrideProperty(baseObject, key, overrideObject[key]);
30081
+ }
30082
+ }
30083
+ };
30084
+ const mergeConfigProperties = (baseObject, mergeObject) => {
30085
+ if (mergeObject) {
30086
+ for (const key in mergeObject) {
30087
+ mergeArrayProperties(baseObject, mergeObject, key);
30088
+ }
30089
+ }
30090
+ };
30091
+ const mergeArrayProperties = (baseObject, mergeObject, key) => {
30092
+ const mergeValue = mergeObject[key];
30093
+ if (mergeValue !== void 0) {
30094
+ baseObject[key] = baseObject[key] ? baseObject[key].concat(mergeValue) : mergeValue;
30095
+ }
30096
+ };
30097
+ const extendTailwindMerge = (configExtension, ...createConfig) => typeof configExtension === "function" ? createTailwindMerge(getDefaultConfig, configExtension, ...createConfig) : createTailwindMerge(() => mergeConfigs(getDefaultConfig(), configExtension), ...createConfig);
30046
30098
  const twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
30047
30099
  function parseName(tag, name2) {
30048
30100
  if (typeof name2 !== "string") {
@@ -30707,102 +30759,78 @@ const __iconNode = [
30707
30759
  ["line", { x1: "8", x2: "14", y1: "11", y2: "11", key: "durymu" }]
30708
30760
  ];
30709
30761
  const ZoomOut = createLucideIcon("zoom-out", __iconNode);
30710
- function cn$4(...inputs) {
30711
- return twMerge(clsx(inputs));
30712
- }
30713
- const MS_IN_SECOND = 1e3;
30714
- const MS_IN_MINUTE = 60 * MS_IN_SECOND;
30715
- const MS_IN_HOUR = 60 * MS_IN_MINUTE;
30716
- const MS_IN_DAY = 24 * MS_IN_HOUR;
30717
- function formatDuration(ms2, compact = false) {
30718
- if (ms2 === 0) {
30719
- return "0s";
30720
- }
30721
- if (ms2 < MS_IN_SECOND) {
30722
- const roundedMs2 = Math.round(ms2);
30723
- return roundedMs2 < MS_IN_SECOND ? `${roundedMs2}ms` : "1s";
30724
- }
30725
- const roundedMs = Math.round(ms2 / MS_IN_SECOND) * MS_IN_SECOND;
30726
- if (roundedMs < MS_IN_MINUTE) {
30727
- return `${Math.floor(roundedMs / MS_IN_SECOND)}s`;
30728
- }
30729
- if (compact) {
30730
- if (roundedMs < MS_IN_HOUR) {
30731
- const m3 = Math.floor(roundedMs / MS_IN_MINUTE);
30732
- const s2 = Math.floor(roundedMs % MS_IN_MINUTE / MS_IN_SECOND);
30733
- return s2 > 0 ? `${m3}m ${s2}s` : `${m3}m`;
30734
- }
30735
- const h2 = Math.floor(roundedMs / MS_IN_HOUR);
30736
- const m2 = Math.floor(roundedMs % MS_IN_HOUR / MS_IN_MINUTE);
30737
- return m2 > 0 ? `${h2}h ${m2}m` : `${h2}h`;
30738
- }
30739
- const days = Math.floor(roundedMs / MS_IN_DAY);
30740
- const hours = Math.floor(roundedMs % MS_IN_DAY / MS_IN_HOUR);
30741
- const minutes = Math.floor(roundedMs % MS_IN_HOUR / MS_IN_MINUTE);
30742
- const seconds = Math.floor(roundedMs % MS_IN_MINUTE / MS_IN_SECOND);
30743
- const parts = [];
30744
- if (days > 0) {
30745
- parts.push(`${days}d`);
30746
- }
30747
- if (hours > 0) {
30748
- parts.push(`${hours}h`);
30749
- }
30750
- if (minutes > 0) {
30751
- parts.push(`${minutes}m`);
30752
- }
30753
- parts.push(`${seconds}s`);
30754
- return parts.join(" ");
30755
- }
30756
- const preciseSecondsFormatter = new Intl.NumberFormat(void 0, {
30757
- minimumFractionDigits: 2,
30758
- maximumFractionDigits: 2
30759
- });
30760
- function formatDurationPrecise(ms2) {
30761
- if (ms2 === 0) {
30762
- return "0s";
30763
- }
30764
- if (ms2 < MS_IN_SECOND) {
30765
- const roundedMs = Math.round(ms2);
30766
- if (roundedMs < MS_IN_SECOND) {
30767
- return `${roundedMs}ms`;
30762
+ const twMergeConfig = {
30763
+ extend: {
30764
+ classGroups: {
30765
+ "text-heading": [
30766
+ {
30767
+ "text-heading": [
30768
+ "72",
30769
+ "64",
30770
+ "56",
30771
+ "48",
30772
+ "40",
30773
+ "32",
30774
+ "24",
30775
+ "20",
30776
+ "16",
30777
+ "14"
30778
+ ]
30779
+ }
30780
+ ],
30781
+ "text-button": [
30782
+ {
30783
+ "text-button": ["16", "14", "12"]
30784
+ }
30785
+ ],
30786
+ "text-label": [
30787
+ {
30788
+ "text-label": [
30789
+ "20",
30790
+ "18",
30791
+ "16",
30792
+ "14",
30793
+ "14-mono",
30794
+ "13",
30795
+ "13-mono",
30796
+ "12",
30797
+ "12-mono"
30798
+ ]
30799
+ }
30800
+ ],
30801
+ "text-copy": [
30802
+ {
30803
+ "text-copy": ["24", "20", "18", "16", "14", "13", "13-mono"]
30804
+ }
30805
+ ],
30806
+ material: [
30807
+ {
30808
+ material: [
30809
+ "base",
30810
+ "small",
30811
+ "medium",
30812
+ "large",
30813
+ "tooltip",
30814
+ "menu",
30815
+ "modal",
30816
+ "fullscreen"
30817
+ ]
30818
+ }
30819
+ ]
30820
+ },
30821
+ // Make each category conflict with itself, so e.g. text-heading-32 overrides text-heading-24
30822
+ conflictingClassGroups: {
30823
+ "text-heading": ["text-heading"],
30824
+ "text-button": ["text-button"],
30825
+ "text-label": ["text-label"],
30826
+ "text-copy": ["text-copy"],
30827
+ material: ["material"]
30768
30828
  }
30769
30829
  }
30770
- const normalizedMs = Math.round(ms2 / 10) * 10;
30771
- if (normalizedMs < MS_IN_MINUTE) {
30772
- return `${preciseSecondsFormatter.format(normalizedMs / MS_IN_SECOND)}s`;
30773
- }
30774
- const days = Math.floor(normalizedMs / MS_IN_DAY);
30775
- const hours = Math.floor(normalizedMs % MS_IN_DAY / MS_IN_HOUR);
30776
- const minutes = Math.floor(normalizedMs % MS_IN_HOUR / MS_IN_MINUTE);
30777
- const seconds = normalizedMs % MS_IN_MINUTE / MS_IN_SECOND;
30778
- const parts = [];
30779
- if (days > 0) {
30780
- parts.push(`${days}d`);
30781
- }
30782
- if (hours > 0) {
30783
- parts.push(`${hours}h`);
30784
- }
30785
- if (minutes > 0) {
30786
- parts.push(`${minutes}m`);
30787
- }
30788
- parts.push(`${preciseSecondsFormatter.format(seconds)}s`);
30789
- return parts.join(" ");
30790
- }
30791
- function isDoStreamStep(stepName) {
30792
- return stepName.endsWith("//doStreamStep");
30793
- }
30794
- function extractConversation(stepInput) {
30795
- if (!Array.isArray(stepInput) || stepInput.length === 0) {
30796
- return null;
30797
- }
30798
- const firstArg = stepInput[0];
30799
- if (!Array.isArray(firstArg)) {
30800
- return null;
30801
- }
30802
- if (!firstArg.every((msg) => msg && typeof msg === "object" && "role" in msg)) {
30803
- return null;
30804
- }
30805
- return firstArg;
30830
+ };
30831
+ const customTwMerge = extendTailwindMerge(twMergeConfig);
30832
+ function cn$4(...classes) {
30833
+ return customTwMerge(clsx(...classes));
30806
30834
  }
30807
30835
  function ErrorCard({ title, className, details = "Unknown error" }) {
30808
30836
  const [isExpanded, setIsExpanded] = reactExports.useState(false);
@@ -49884,7 +49912,7 @@ function replaceEncryptedAndExpiredWithMarkers(resource) {
49884
49912
  async function hydrateResourceIOWithKey(resource, key) {
49885
49913
  const { hydrateDataWithKey: hydrateDataWithKey2 } = await Promise.resolve().then(() => serializationFormat);
49886
49914
  const { importKey: importKey2 } = await Promise.resolve().then(() => encryption);
49887
- const { ensureZstdDecoderRegistered } = await import("./zstd-browser-decoder-eXH_mKQG.js");
49915
+ const { ensureZstdDecoderRegistered } = await import("./zstd-browser-decoder-CcinVfMP.js");
49888
49916
  ensureZstdDecoderRegistered();
49889
49917
  const cryptoKey = await importKey2(key);
49890
49918
  const revivers = getRevivers();
@@ -51026,6 +51054,100 @@ const ToastContext = reactExports.createContext(defaultAdapter);
51026
51054
  function useToast() {
51027
51055
  return reactExports.useContext(ToastContext);
51028
51056
  }
51057
+ const MS_IN_SECOND = 1e3;
51058
+ const MS_IN_MINUTE = 60 * MS_IN_SECOND;
51059
+ const MS_IN_HOUR = 60 * MS_IN_MINUTE;
51060
+ const MS_IN_DAY = 24 * MS_IN_HOUR;
51061
+ function formatDuration(ms2, compact = false) {
51062
+ if (ms2 === 0) {
51063
+ return "0s";
51064
+ }
51065
+ if (ms2 < MS_IN_SECOND) {
51066
+ const roundedMs2 = Math.round(ms2);
51067
+ return roundedMs2 < MS_IN_SECOND ? `${roundedMs2}ms` : "1s";
51068
+ }
51069
+ const roundedMs = Math.round(ms2 / MS_IN_SECOND) * MS_IN_SECOND;
51070
+ if (roundedMs < MS_IN_MINUTE) {
51071
+ return `${Math.floor(roundedMs / MS_IN_SECOND)}s`;
51072
+ }
51073
+ if (compact) {
51074
+ if (roundedMs < MS_IN_HOUR) {
51075
+ const m3 = Math.floor(roundedMs / MS_IN_MINUTE);
51076
+ const s2 = Math.floor(roundedMs % MS_IN_MINUTE / MS_IN_SECOND);
51077
+ return s2 > 0 ? `${m3}m ${s2}s` : `${m3}m`;
51078
+ }
51079
+ const h2 = Math.floor(roundedMs / MS_IN_HOUR);
51080
+ const m2 = Math.floor(roundedMs % MS_IN_HOUR / MS_IN_MINUTE);
51081
+ return m2 > 0 ? `${h2}h ${m2}m` : `${h2}h`;
51082
+ }
51083
+ const days = Math.floor(roundedMs / MS_IN_DAY);
51084
+ const hours = Math.floor(roundedMs % MS_IN_DAY / MS_IN_HOUR);
51085
+ const minutes = Math.floor(roundedMs % MS_IN_HOUR / MS_IN_MINUTE);
51086
+ const seconds = Math.floor(roundedMs % MS_IN_MINUTE / MS_IN_SECOND);
51087
+ const parts = [];
51088
+ if (days > 0) {
51089
+ parts.push(`${days}d`);
51090
+ }
51091
+ if (hours > 0) {
51092
+ parts.push(`${hours}h`);
51093
+ }
51094
+ if (minutes > 0) {
51095
+ parts.push(`${minutes}m`);
51096
+ }
51097
+ parts.push(`${seconds}s`);
51098
+ return parts.join(" ");
51099
+ }
51100
+ const preciseSecondsFormatter = new Intl.NumberFormat(void 0, {
51101
+ minimumFractionDigits: 2,
51102
+ maximumFractionDigits: 2
51103
+ });
51104
+ function formatDurationPrecise(ms2) {
51105
+ if (ms2 === 0) {
51106
+ return "0s";
51107
+ }
51108
+ if (ms2 < MS_IN_SECOND) {
51109
+ const roundedMs = Math.round(ms2);
51110
+ if (roundedMs < MS_IN_SECOND) {
51111
+ return `${roundedMs}ms`;
51112
+ }
51113
+ }
51114
+ const normalizedMs = Math.round(ms2 / 10) * 10;
51115
+ if (normalizedMs < MS_IN_MINUTE) {
51116
+ return `${preciseSecondsFormatter.format(normalizedMs / MS_IN_SECOND)}s`;
51117
+ }
51118
+ const days = Math.floor(normalizedMs / MS_IN_DAY);
51119
+ const hours = Math.floor(normalizedMs % MS_IN_DAY / MS_IN_HOUR);
51120
+ const minutes = Math.floor(normalizedMs % MS_IN_HOUR / MS_IN_MINUTE);
51121
+ const seconds = normalizedMs % MS_IN_MINUTE / MS_IN_SECOND;
51122
+ const parts = [];
51123
+ if (days > 0) {
51124
+ parts.push(`${days}d`);
51125
+ }
51126
+ if (hours > 0) {
51127
+ parts.push(`${hours}h`);
51128
+ }
51129
+ if (minutes > 0) {
51130
+ parts.push(`${minutes}m`);
51131
+ }
51132
+ parts.push(`${preciseSecondsFormatter.format(seconds)}s`);
51133
+ return parts.join(" ");
51134
+ }
51135
+ function isDoStreamStep(stepName) {
51136
+ return stepName.endsWith("//doStreamStep");
51137
+ }
51138
+ function extractConversation(stepInput) {
51139
+ if (!Array.isArray(stepInput) || stepInput.length === 0) {
51140
+ return null;
51141
+ }
51142
+ const firstArg = stepInput[0];
51143
+ if (!Array.isArray(firstArg)) {
51144
+ return null;
51145
+ }
51146
+ if (!firstArg.every((msg) => msg && typeof msg === "object" && "role" in msg)) {
51147
+ return null;
51148
+ }
51149
+ return firstArg;
51150
+ }
51029
51151
  function CopyButton({ copyText, ariaLabel, className }) {
51030
51152
  const [copied, setCopied] = reactExports.useState(false);
51031
51153
  const timeoutRef = reactExports.useRef(null);
@@ -52777,6 +52899,18 @@ function formatEventTime(date2) {
52777
52899
  hour12: false
52778
52900
  }) + "." + date2.getMilliseconds().toString().padStart(3, "0");
52779
52901
  }
52902
+ function parseEventDate(value) {
52903
+ if (value == null)
52904
+ return null;
52905
+ const date2 = value instanceof Date ? value : new Date(String(value));
52906
+ return Number.isNaN(date2.getTime()) ? null : date2;
52907
+ }
52908
+ function getEffectiveEventDate$1(event) {
52909
+ return parseEventDate(event.occurredAt) ?? new Date(event.createdAt);
52910
+ }
52911
+ function getEffectiveEventTime(event) {
52912
+ return getEffectiveEventDate$1(event).getTime();
52913
+ }
52780
52914
  function formatEventType(eventType) {
52781
52915
  return eventType.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
52782
52916
  }
@@ -52817,13 +52951,13 @@ function buildNameMaps(events2, run2) {
52817
52951
  return { correlationNameMap, workflowName };
52818
52952
  }
52819
52953
  function buildDurationMap(events2) {
52820
- const chronological = [...events2].sort((a2, b2) => new Date(a2.createdAt).getTime() - new Date(b2.createdAt).getTime());
52954
+ const chronological = [...events2].sort((a2, b2) => getEffectiveEventTime(a2) - getEffectiveEventTime(b2));
52821
52955
  const createdTimes = /* @__PURE__ */ new Map();
52822
52956
  const firstStartedTimes = /* @__PURE__ */ new Map();
52823
52957
  const startedTimes = /* @__PURE__ */ new Map();
52824
52958
  const durations = /* @__PURE__ */ new Map();
52825
52959
  for (const event of chronological) {
52826
- const ts = new Date(event.createdAt).getTime();
52960
+ const ts = getEffectiveEventTime(event);
52827
52961
  const key = event.correlationId ?? "__run__";
52828
52962
  const type = event.eventType;
52829
52963
  if (type === "step_created" || type === "run_created") {
@@ -53046,7 +53180,7 @@ const SORT_OPTIONS = [
53046
53180
  { value: "desc", label: "Newest" },
53047
53181
  { value: "asc", label: "Oldest" }
53048
53182
  ];
53049
- function RowsSkeleton() {
53183
+ function RowsSkeleton({ showSeparateEventOccurrenceTimestamps = false }) {
53050
53184
  return jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-hidden", children: Array.from({ length: 16 }, (_2, i) => jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0", style: { height: 40 }, children: [jsxRuntimeExports.jsxs("div", { className: "relative flex-shrink-0 self-stretch flex items-center", style: { width: GUTTER_WIDTH }, children: [jsxRuntimeExports.jsx("div", { style: {
53051
53185
  position: "absolute",
53052
53186
  left: 8,
@@ -53058,9 +53192,9 @@ function RowsSkeleton() {
53058
53192
  height: i % 4 === 0 ? 8 : 6,
53059
53193
  borderRadius: "50%",
53060
53194
  marginLeft: i % 4 === 0 ? 5 : 6
53061
- } })] }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0 flex items-center justify-center", children: jsxRuntimeExports.jsx(Skeleton$2, { className: "w-5 h-5", style: { borderRadius: 4 } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "70%" } }) }), jsxRuntimeExports.jsxs("div", { className: "min-w-0 px-4 flex items-center gap-1.5", style: { flex: "2 1 0%" }, children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "flex-shrink-0", style: { width: 6, height: 6, borderRadius: "50%" } }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "60%" } })] }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "50%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "75%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "75%" } }) })] }, i)) });
53195
+ } })] }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0 flex items-center justify-center", children: jsxRuntimeExports.jsx(Skeleton$2, { className: "w-5 h-5", style: { borderRadius: 4 } }) }), showSeparateEventOccurrenceTimestamps && jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "70%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "70%" } }) }), jsxRuntimeExports.jsxs("div", { className: "min-w-0 px-4 flex items-center gap-1.5", style: { flex: "2 1 0%" }, children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "flex-shrink-0", style: { width: 6, height: 6, borderRadius: "50%" } }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "60%" } })] }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "50%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "75%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "75%" } }) })] }, i)) });
53062
53196
  }
53063
- function EventRow$1({ event, index: index2, isFirst, isLast, isExpanded, onToggleExpand, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData, onCacheEventData, encryptionKey, onEncryptedDataDetected, suppressGroupDimming = false }) {
53197
+ function EventRow$1({ event, index: index2, isFirst, isLast, isExpanded, onToggleExpand, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData, onCacheEventData, encryptionKey, onEncryptedDataDetected, suppressGroupDimming = false, showSeparateEventOccurrenceTimestamps = false }) {
53064
53198
  const [isLoading, setIsLoading] = reactExports.useState(false);
53065
53199
  const [loadedEventData, setLoadedEventData] = reactExports.useState(cachedEventData);
53066
53200
  const [loadError, setLoadError] = reactExports.useState(null);
@@ -53073,6 +53207,8 @@ function EventRow$1({ event, index: index2, isFirst, isLast, isExpanded, onToggl
53073
53207
  const rowGroupKey = isRunLevel(event.eventType) ? "__run__" : event.correlationId ?? void 0;
53074
53208
  const statusDotColor = getStatusDotColor(event.eventType);
53075
53209
  const createdAt = new Date(event.createdAt);
53210
+ const occurredAt = parseEventDate(event.occurredAt);
53211
+ const displayedCreatedAt = showSeparateEventOccurrenceTimestamps ? createdAt : getEffectiveEventDate$1(event);
53076
53212
  const hasExistingEventData = "eventData" in event && event.eventData != null;
53077
53213
  const isRun = isRunLevel(event.eventType);
53078
53214
  const eventName2 = isRun ? workflowName ?? "-" : event.correlationId ? correlationNameMap.get(event.correlationId) ?? "-" : "-";
@@ -53176,7 +53312,7 @@ function EventRow$1({ event, index: index2, isFirst, isLast, isExpanded, onToggl
53176
53312
  }, children: jsxRuntimeExports.jsx(ChevronRight, { className: "h-3 w-3 transition-transform", style: {
53177
53313
  color: "var(--ds-gray-900)",
53178
53314
  transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)"
53179
- } }) }), jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(TimestampTooltip, { date: createdAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(createdAt) }) }) }), jsxRuntimeExports.jsx("div", { className: "font-medium min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5", style: { color: "var(--ds-gray-900)" }, children: [jsxRuntimeExports.jsxs("span", { style: {
53315
+ } }) }), showSeparateEventOccurrenceTimestamps && jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: occurredAt ? jsxRuntimeExports.jsx(TimestampTooltip, { date: occurredAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(occurredAt) }) }) : "-" }), jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(TimestampTooltip, { date: displayedCreatedAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(displayedCreatedAt) }) }) }), jsxRuntimeExports.jsx("div", { className: "font-medium min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5", style: { color: "var(--ds-gray-900)" }, children: [jsxRuntimeExports.jsxs("span", { style: {
53180
53316
  position: "relative",
53181
53317
  display: "inline-flex",
53182
53318
  width: 6,
@@ -53205,7 +53341,7 @@ function EventRow$1({ event, index: index2, isFirst, isLast, isExpanded, onToggl
53205
53341
  color: "var(--ds-red-900)"
53206
53342
  }, children: loadError }) : isLoading || loadedEventData === null && !hasAttemptedLoad && event.correlationId ? jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 p-3", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "75%" } }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "50%" } }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3", style: { width: "60%" } })] }) : jsxRuntimeExports.jsx("div", { className: "p-2 text-xs", style: { color: "var(--ds-gray-900)" }, children: "No data" })] })] })] });
53207
53343
  }
53208
- function EventListViewInner({ events: events2, run: run2, onLoadEventData, hasMoreEvents = false, isLoadingMoreEvents = false, onLoadMoreEvents, encryptionKey, isLoading = false, sortOrder: sortOrderProp, onSortOrderChange, onDecrypt, isDecrypting = false, hasEncryptedData: hasEncryptedDataProp = false, onExactIdSearch }) {
53344
+ function EventListViewInner({ events: events2, run: run2, onLoadEventData, hasMoreEvents = false, isLoadingMoreEvents = false, onLoadMoreEvents, encryptionKey, isLoading = false, sortOrder: sortOrderProp, onSortOrderChange, onDecrypt, isDecrypting = false, hasEncryptedData: hasEncryptedDataProp = false, onExactIdSearch, showSeparateEventOccurrenceTimestamps = false }) {
53209
53345
  const toast2 = useToast();
53210
53346
  const [internalSortOrder, setInternalSortOrder] = reactExports.useState("asc");
53211
53347
  const effectiveSortOrder = sortOrderProp ?? internalSortOrder;
@@ -53231,7 +53367,7 @@ function EventListViewInner({ events: events2, run: run2, onLoadEventData, hasMo
53231
53367
  if (sourceEvents.length === 0)
53232
53368
  return [];
53233
53369
  const dir = effectiveSortOrder === "desc" ? -1 : 1;
53234
- return [...sourceEvents].sort((a2, b2) => dir * (new Date(a2.createdAt).getTime() - new Date(b2.createdAt).getTime()));
53370
+ return [...sourceEvents].sort((a2, b2) => dir * (getEffectiveEventTime(a2) - getEffectiveEventTime(b2)));
53235
53371
  }, [events2, effectiveSortOrder, isExactSearchActive, searchResults]);
53236
53372
  const hasEncryptedInlineData = reactExports.useMemo(() => {
53237
53373
  const sourceEvents = isExactSearchActive ? searchResults : events2;
@@ -53459,14 +53595,14 @@ function EventListViewInner({ events: events2, run: run2, onLoadEventData, hasMo
53459
53595
  borderColor: "var(--ds-gray-alpha-200)",
53460
53596
  color: "var(--ds-gray-900)",
53461
53597
  backgroundColor: "var(--ds-background-100)"
53462
- }, children: [jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", style: { width: GUTTER_WIDTH } }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Time" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Event Type" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Name" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: "Correlation ID" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: "Event ID" })] }), isRefetching || searchLoading ? jsxRuntimeExports.jsx(RowsSkeleton, {}) : sortedEvents2.length === 0 ? jsxRuntimeExports.jsx("div", { className: "flex flex-1 items-center justify-center px-6 text-center text-sm", style: { color: "var(--ds-gray-700)" }, children: searchNotFound && searchQuery.trim() ? `No events found for ${searchQuery.trim()}` : searchError ? searchError : parsedSearchId && searchQuery.trim() && !onExactIdSearch ? "Exact ID search is unavailable in this view." : "No events found" }) : jsxRuntimeExports.jsx(Yr, { ref: virtuosoRef, totalCount: sortedEvents2.length, overscan: 20, defaultItemHeight: 40, endReached: () => {
53598
+ }, children: [jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", style: { width: GUTTER_WIDTH } }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0" }), showSeparateEventOccurrenceTimestamps && jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Occurred" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Created" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Event Type" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Name" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: "Correlation ID" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: "Event ID" })] }), isRefetching || searchLoading ? jsxRuntimeExports.jsx(RowsSkeleton, { showSeparateEventOccurrenceTimestamps }) : sortedEvents2.length === 0 ? jsxRuntimeExports.jsx("div", { className: "flex flex-1 items-center justify-center px-6 text-center text-sm", style: { color: "var(--ds-gray-700)" }, children: searchNotFound && searchQuery.trim() ? `No events found for ${searchQuery.trim()}` : searchError ? searchError : parsedSearchId && searchQuery.trim() && !onExactIdSearch ? "Exact ID search is unavailable in this view." : "No events found" }) : jsxRuntimeExports.jsx(Yr, { ref: virtuosoRef, totalCount: sortedEvents2.length, overscan: 20, defaultItemHeight: 40, endReached: () => {
53463
53599
  if (isExactSearchActive || !hasMoreEvents || isLoadingMoreEvents) {
53464
53600
  return;
53465
53601
  }
53466
53602
  void (onLoadMoreEvents == null ? void 0 : onLoadMoreEvents());
53467
53603
  }, itemContent: (index2) => {
53468
53604
  const ev = sortedEvents2[index2];
53469
- return jsxRuntimeExports.jsx(EventRow$1, { event: ev, index: index2, isFirst: index2 === 0, isLast: index2 === sortedEvents2.length - 1, isExpanded: expandedEventIds.has(ev.eventId), onToggleExpand: toggleEventExpanded, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData: eventDataCacheRef.current.get(ev.eventId) ?? null, onCacheEventData: cacheEventData, encryptionKey, onEncryptedDataDetected: handleEncryptedDataDetected, suppressGroupDimming: isExactSearchActive });
53605
+ return jsxRuntimeExports.jsx(EventRow$1, { event: ev, index: index2, isFirst: index2 === 0, isLast: index2 === sortedEvents2.length - 1, isExpanded: expandedEventIds.has(ev.eventId), onToggleExpand: toggleEventExpanded, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData: eventDataCacheRef.current.get(ev.eventId) ?? null, onCacheEventData: cacheEventData, encryptionKey, onEncryptedDataDetected: handleEncryptedDataDetected, suppressGroupDimming: isExactSearchActive, showSeparateEventOccurrenceTimestamps });
53470
53606
  }, style: { flex: 1, minHeight: 0 } }), jsxRuntimeExports.jsxs("div", { className: "relative flex-shrink-0 flex items-center h-10 border-t px-4 text-xs", style: {
53471
53607
  borderColor: "var(--ds-gray-alpha-200)",
53472
53608
  color: "var(--ds-gray-900)",
@@ -53728,6 +53864,22 @@ function HookResolveModalWrapper({ hookActions }) {
53728
53864
  const { selectedHook, closeResolveModal, handleResolve, isResolving } = hookActions;
53729
53865
  return jsxRuntimeExports.jsx(ResolveHookModal, { isOpen: selectedHook !== null, onClose: closeResolveModal, onSubmit: handleResolve, isSubmitting: isResolving });
53730
53866
  }
53867
+ const COL_TEMPLATE = "340px 1px minmax(50px, 1fr)";
53868
+ const ROWS = [
53869
+ { id: "r0", name: 62, off: 0, bar: 72 },
53870
+ { id: "r1", name: 78, off: 6, bar: 48 },
53871
+ { id: "r2", name: 50, off: 10, bar: 55 },
53872
+ { id: "r3", name: 84, off: 18, bar: 30 },
53873
+ { id: "r4", name: 45, off: 18, bar: 42 },
53874
+ { id: "r5", name: 66, off: 34, bar: 38 },
53875
+ { id: "r6", name: 55, off: 41, bar: 25 },
53876
+ { id: "r7", name: 40, off: 50, bar: 30 }
53877
+ ];
53878
+ const HEADER_MARKERS = ["m0", "m1", "m2", "m3"];
53879
+ const HeaderDivider = () => jsxRuntimeExports.jsx("div", { className: "flex justify-center", children: jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }) });
53880
+ function TraceViewerSkeleton() {
53881
+ return jsxRuntimeExports.jsxs("output", { "aria-busy": "true", "aria-label": "Loading trace", className: "flex flex-col w-full h-full min-h-0 bg-background-100", children: [jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Loading trace…" }), jsxRuntimeExports.jsxs("div", { className: "shrink-0 grid", style: { gridTemplateColumns: COL_TEMPLATE }, children: [jsxRuntimeExports.jsxs("div", { className: "h-10 min-h-10 flex items-center border-b border-gray-alpha-400 pl-4 pr-2 gap-1.5", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "w-3.5 h-3.5 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3.5 w-40" })] }), jsxRuntimeExports.jsx(HeaderDivider, {}), jsxRuntimeExports.jsx("div", { className: "h-10 min-h-10 flex items-end border-b border-gray-alpha-400 px-4 pb-1 gap-2", children: jsxRuntimeExports.jsx("div", { className: "relative flex-1 flex items-end justify-between", children: HEADER_MARKERS.map((id2) => jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3.5 w-9" }, id2)) }) })] }), jsxRuntimeExports.jsxs("div", { className: "grid flex-1 min-h-0 overflow-hidden", style: { gridTemplateColumns: COL_TEMPLATE }, children: [jsxRuntimeExports.jsx("div", { className: "block overflow-visible", children: jsxRuntimeExports.jsx("ul", { className: "block divide-y divide-gray-alpha-400 border-b border-gray-alpha-400", children: ROWS.map((row) => jsxRuntimeExports.jsxs("li", { className: "h-10 flex items-center pl-4 pr-2", children: [jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "w-4 h-4 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3.5", style: { width: `${row.name}%` } })] }), jsxRuntimeExports.jsx(Skeleton$2, { className: "ml-2 h-3.5 w-10 shrink-0" })] }, row.id)) }) }), jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }), jsxRuntimeExports.jsx("div", { className: "relative min-h-0", children: ROWS.map((row) => jsxRuntimeExports.jsx("div", { className: "relative h-10", children: jsxRuntimeExports.jsx("div", { className: "absolute inset-x-4 inset-y-0", children: jsxRuntimeExports.jsx(Skeleton$2, { className: "absolute top-1/2 -translate-y-1/2 h-6 rounded-[0.25rem]", style: { left: `${row.off}%`, width: `${row.bar}%` } }) }) }, row.id)) })] })] });
53882
+ }
53731
53883
  function shouldShowVerticalLine(eventType) {
53732
53884
  if (eventType === "hook_created" || eventType === "hook_received" || eventType === "hook_disposed") {
53733
53885
  return true;
@@ -53783,10 +53935,17 @@ const MARKER_EVENT_TYPES = /* @__PURE__ */ new Set([
53783
53935
  "wait_completed",
53784
53936
  "attr_set"
53785
53937
  ]);
53786
- function convertEventsToSpanEvents(events2, filterTypes = true) {
53938
+ const getEventTimestamp = (event) => {
53939
+ const value = (event == null ? void 0 : event.occurredAt) ?? (event == null ? void 0 : event.createdAt);
53940
+ if (!value)
53941
+ return void 0;
53942
+ const date2 = value instanceof Date ? value : new Date(value);
53943
+ return Number.isNaN(date2.getTime()) ? void 0 : date2;
53944
+ };
53945
+ function convertEventsToSpanEvents(events2, filterTypes = true, options = {}) {
53787
53946
  return events2.filter((event) => filterTypes ? MARKER_EVENT_TYPES.has(event.eventType) : true).map((event) => ({
53788
53947
  name: event.eventType,
53789
- timestamp: dateToOtelTime(event.createdAt),
53948
+ timestamp: dateToOtelTime(options.preferOccurredAt ? getEventTimestamp(event) ?? event.createdAt : event.createdAt),
53790
53949
  attributes: {
53791
53950
  eventId: event.eventId,
53792
53951
  correlationId: event.correlationId,
@@ -53806,9 +53965,9 @@ const waitEventsToWaitEntity = (events2) => {
53806
53965
  return {
53807
53966
  waitId: startEvent.correlationId,
53808
53967
  runId: startEvent.runId,
53809
- createdAt: startEvent.createdAt,
53968
+ createdAt: getEventTimestamp(startEvent) ?? startEvent.createdAt,
53810
53969
  resumeAt: ((_a3 = startEvent.eventData) == null ? void 0 : _a3.resumeAt) ? new Date(startEvent.eventData.resumeAt) : void 0,
53811
- completedAt: completedEvent == null ? void 0 : completedEvent.createdAt
53970
+ completedAt: getEventTimestamp(completedEvent)
53812
53971
  };
53813
53972
  };
53814
53973
  function waitToSpan(events2, maxEndTime, fallbackEndTime = maxEndTime) {
@@ -53865,16 +54024,16 @@ const stepEventsToStepEntity = (events2) => {
53865
54024
  status = "running";
53866
54025
  attempt += 1;
53867
54026
  if (!startedAt)
53868
- startedAt = e.createdAt;
54027
+ startedAt = getEventTimestamp(e) ?? e.createdAt;
53869
54028
  completedAt = void 0;
53870
54029
  break;
53871
54030
  case "step_completed":
53872
54031
  status = "completed";
53873
- completedAt = e.createdAt;
54032
+ completedAt = getEventTimestamp(e) ?? e.createdAt;
53874
54033
  break;
53875
54034
  case "step_failed":
53876
54035
  status = "failed";
53877
- completedAt = e.createdAt;
54036
+ completedAt = getEventTimestamp(e) ?? e.createdAt;
53878
54037
  break;
53879
54038
  case "step_retrying":
53880
54039
  status = "pending";
@@ -53891,8 +54050,8 @@ const stepEventsToStepEntity = (events2) => {
53891
54050
  stepName: ((_a3 = createdEvent == null ? void 0 : createdEvent.eventData) == null ? void 0 : _a3.stepName) ?? "",
53892
54051
  status,
53893
54052
  attempt,
53894
- createdAt: anchorEvent.createdAt,
53895
- updatedAt: (lastEvent == null ? void 0 : lastEvent.createdAt) ?? anchorEvent.createdAt,
54053
+ createdAt: getEventTimestamp(anchorEvent) ?? anchorEvent.createdAt,
54054
+ updatedAt: getEventTimestamp(lastEvent) ?? (lastEvent == null ? void 0 : lastEvent.createdAt) ?? anchorEvent.createdAt,
53896
54055
  startedAt,
53897
54056
  completedAt,
53898
54057
  specVersion: anchorEvent.specVersion
@@ -53909,13 +54068,20 @@ function stepToSpan(stepEvents, maxEndTime) {
53909
54068
  data: step
53910
54069
  };
53911
54070
  const resource = "step";
53912
- const endTime = new Date(step.completedAt ?? maxEndTime);
53913
- const events2 = convertEventsToSpanEvents(stepEvents, false);
53914
- const spanStartTime = new Date(step.createdAt);
54071
+ const events2 = convertEventsToSpanEvents(stepEvents, false, {
54072
+ preferOccurredAt: true
54073
+ });
54074
+ const spanStartEvent = stepEvents.find((event) => event.eventType === "step_created") ?? stepEvents[0];
54075
+ const spanStartTime = getEventTimestamp(spanStartEvent) ?? new Date(step.createdAt);
53915
54076
  let activeStartTime = step.startedAt ? new Date(step.startedAt) : void 0;
53916
54077
  const firstStartEvent = stepEvents.find((event) => event.eventType === "step_started");
53917
54078
  if (firstStartEvent) {
53918
- activeStartTime = new Date(firstStartEvent.createdAt);
54079
+ activeStartTime = getEventTimestamp(firstStartEvent) ?? new Date(firstStartEvent.createdAt);
54080
+ }
54081
+ let endTime = new Date(maxEndTime);
54082
+ if (step.completedAt) {
54083
+ const completedEvent = stepEvents.slice().reverse().find((event) => event.eventType === "step_completed" || event.eventType === "step_failed");
54084
+ endTime = getEventTimestamp(completedEvent) ?? new Date(step.completedAt);
53919
54085
  }
53920
54086
  return {
53921
54087
  spanId: String(step.stepId),
@@ -53937,7 +54103,7 @@ function stepToSpan(stepEvents, maxEndTime) {
53937
54103
  };
53938
54104
  }
53939
54105
  const hookEventsToHookEntity = (events2) => {
53940
- var _a3, _b2;
54106
+ var _a3;
53941
54107
  const createdEvent = events2.find((event) => event.eventType === "hook_created");
53942
54108
  if (!createdEvent) {
53943
54109
  return null;
@@ -53949,10 +54115,10 @@ const hookEventsToHookEntity = (events2) => {
53949
54115
  hookId: createdEvent.correlationId,
53950
54116
  runId: createdEvent.runId,
53951
54117
  token: (_a3 = createdEvent.eventData) == null ? void 0 : _a3.token,
53952
- createdAt: createdEvent.createdAt,
54118
+ createdAt: getEventTimestamp(createdEvent) ?? createdEvent.createdAt,
53953
54119
  receivedCount: receivedEvents.length,
53954
- lastReceivedAt: (lastReceivedEvent == null ? void 0 : lastReceivedEvent.createdAt) || void 0,
53955
- disposedAt: ((_b2 = disposedEvents.at(-1)) == null ? void 0 : _b2.createdAt) || void 0
54120
+ lastReceivedAt: getEventTimestamp(lastReceivedEvent),
54121
+ disposedAt: getEventTimestamp(disposedEvents.at(-1))
53956
54122
  };
53957
54123
  };
53958
54124
  function hookToSpan(hookEvents, maxEndTime) {
@@ -53985,15 +54151,26 @@ function hookToSpan(hookEvents, maxEndTime) {
53985
54151
  function runToSpan(run2, runEvents, nowTime) {
53986
54152
  var _a3;
53987
54153
  const now2 = nowTime ?? /* @__PURE__ */ new Date();
54154
+ const runCreatedEvent = runEvents.find((event) => event.eventType === "run_created");
54155
+ const runStartedEvent = runEvents.find((event) => event.eventType === "run_started");
54156
+ const terminalEvent = runEvents.slice().reverse().find((event) => event.eventType === "run_completed" || event.eventType === "run_failed" || event.eventType === "run_cancelled");
54157
+ const spanStartTime = getEventTimestamp(runCreatedEvent) ?? new Date(run2.createdAt);
54158
+ const activeStartTime = getEventTimestamp(runStartedEvent) ?? (run2.startedAt ? new Date(run2.startedAt) : void 0);
54159
+ const completedAt = getEventTimestamp(terminalEvent) ?? run2.completedAt ?? void 0;
54160
+ const endTime = completedAt ?? now2;
53988
54161
  const { input: _i, output: _o2, error: _e2, ...runIdentity } = run2;
53989
54162
  const attributes = {
53990
54163
  resource: "run",
53991
- data: runIdentity
54164
+ data: {
54165
+ ...runIdentity,
54166
+ createdAt: spanStartTime,
54167
+ startedAt: activeStartTime,
54168
+ completedAt
54169
+ }
53992
54170
  };
53993
- const spanStartTime = new Date(run2.createdAt);
53994
- const activeStartTime = run2.startedAt ? new Date(run2.startedAt) : void 0;
53995
- const endTime = run2.completedAt ?? now2;
53996
- const events2 = convertEventsToSpanEvents(runEvents, false);
54171
+ const events2 = convertEventsToSpanEvents(runEvents, false, {
54172
+ preferOccurredAt: true
54173
+ });
53997
54174
  return {
53998
54175
  spanId: String(run2.runId),
53999
54176
  name: String(((_a3 = parseWorkflowName(run2.workflowName)) == null ? void 0 : _a3.shortName) ?? "?"),
@@ -54063,7 +54240,7 @@ function groupEventsByCorrelation(events2) {
54063
54240
  function computeLatestKnownTime(events2, run2) {
54064
54241
  let latest = new Date(run2.createdAt).getTime();
54065
54242
  for (const event of events2) {
54066
- const t = new Date(event.createdAt).getTime();
54243
+ const t = (getEventTimestamp(event) ?? new Date(event.createdAt)).getTime();
54067
54244
  if (t > latest)
54068
54245
  latest = t;
54069
54246
  }
@@ -82626,7 +82803,7 @@ var tn = f("block", "before:content-[counter(line)]", "before:inline-block", "be
82626
82803
  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 });
82627
82804
  var Se = reactExports.createContext({ code: "" }), de = () => reactExports.useContext(Se);
82628
82805
  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 }) });
82629
- var cn$1 = /\n+$/, dn = reactExports.lazy(() => import("./highlighted-body-B3W2YXNL-CP60Gm_l.js").then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
82806
+ var cn$1 = /\n+$/, dn = reactExports.lazy(() => import("./highlighted-body-B3W2YXNL-B7xcG7gl.js").then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
82630
82807
  let i = reactExports.useMemo(() => e.replace(cn$1, ""), [e]), c = reactExports.useMemo(() => ({ bg: "transparent", fg: "inherit", tokens: i.split(`
82631
82808
  `).map((a2) => [{ content: a2, color: "inherit", bgColor: "transparent", htmlStyle: {}, offset: 0 }]) }), [i]);
82632
82809
  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 }) })] }) });
@@ -82948,7 +83125,7 @@ var Dt = ({ children: e, className: t, onDownload: o, onError: n }) => {
82948
83125
  }, []), 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] });
82949
83126
  };
82950
83127
  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 }) })] });
82951
- var Jn = reactExports.lazy(() => import("./mermaid-3ZIDBTTL-PK-HMOJq.js").then((e) => ({ default: e.Mermaid }))), Kn = /language-([^\s]+)/;
83128
+ var Jn = reactExports.lazy(() => import("./mermaid-3ZIDBTTL-DQqBhQ9Y.js").then((e) => ({ default: e.Mermaid }))), Kn = /language-([^\s]+)/;
82952
83129
  function ke(e, t) {
82953
83130
  if (!(e != null && e.position || t != null && t.position)) return true;
82954
83131
  if (!(e != null && e.position && (t != null && t.position))) return false;
@@ -83647,7 +83824,7 @@ const getModuleSpecifierFromName = (value) => {
83647
83824
  }
83648
83825
  return raw2;
83649
83826
  };
83650
- const parseDateValue = (value) => {
83827
+ const parseDateValue$1 = (value) => {
83651
83828
  if (value == null) {
83652
83829
  return null;
83653
83830
  }
@@ -83662,14 +83839,14 @@ const parseDateValue = (value) => {
83662
83839
  };
83663
83840
  const formatLocalMillisecondTime = (date2) => format(date2, "MMM dd HH:mm:ss.SS OO").toUpperCase();
83664
83841
  const localMillisecondTimeOrNull = (value) => {
83665
- const date2 = parseDateValue(value);
83842
+ const date2 = parseDateValue$1(value);
83666
83843
  if (!date2) {
83667
83844
  return null;
83668
83845
  }
83669
83846
  return formatLocalMillisecondTime(date2);
83670
83847
  };
83671
83848
  const timestampWithTooltipOrNull = (value) => {
83672
- const date2 = parseDateValue(value);
83849
+ const date2 = parseDateValue$1(value);
83673
83850
  if (!date2)
83674
83851
  return null;
83675
83852
  return jsxRuntimeExports.jsx(TimestampTooltip, { date: date2, children: jsxRuntimeExports.jsx("span", { children: formatLocalMillisecondTime(date2) }) });
@@ -83876,8 +84053,8 @@ const AttributePanel = ({ data, moduleSpecifier, isLoading, error: error2, expir
83876
84053
  return present;
83877
84054
  if (resource === "sleep")
83878
84055
  return present;
83879
- const loadingDefaults = ["input", "output"];
83880
- for (const key of loadingDefaults) {
84056
+ const loadingPlaceholders = ["input", "output"];
84057
+ for (const key of loadingPlaceholders) {
83881
84058
  if (!present.includes(key)) {
83882
84059
  present.push(key);
83883
84060
  }
@@ -83942,7 +84119,23 @@ const DATA_EVENT_TYPES = /* @__PURE__ */ new Set([
83942
84119
  "wait_completed",
83943
84120
  "attr_set"
83944
84121
  ]);
83945
- function EventItem({ event, onLoadEventData, encryptionKey }) {
84122
+ const parseDateValue = (value) => {
84123
+ if (value == null)
84124
+ return null;
84125
+ const date2 = value instanceof Date ? value : new Date(String(value));
84126
+ return Number.isNaN(date2.getTime()) ? null : date2;
84127
+ };
84128
+ const getEffectiveEventDate = (event) => parseDateValue(event.occurredAt) ?? new Date(event.createdAt);
84129
+ const formatEventTimestamp = (date2) => date2.toLocaleString(void 0, {
84130
+ month: "short",
84131
+ day: "numeric",
84132
+ hour: "numeric",
84133
+ minute: "numeric",
84134
+ second: "numeric",
84135
+ fractionalSecondDigits: 3,
84136
+ timeZoneName: "short"
84137
+ });
84138
+ function EventItem({ event, onLoadEventData, encryptionKey, showSeparateEventOccurrenceTimestamps = false }) {
83946
84139
  const [loadedData, setLoadedData] = reactExports.useState(null);
83947
84140
  const [isLoading, setIsLoading] = reactExports.useState(false);
83948
84141
  const [loadError, setLoadError] = reactExports.useState(null);
@@ -83983,16 +84176,18 @@ function EventItem({ event, onLoadEventData, encryptionKey }) {
83983
84176
  void loadEventData({ force: true });
83984
84177
  }, [encryptionKey, loadEventData]);
83985
84178
  const createdAt = new Date(event.createdAt);
83986
- const createdAtTime = createdAt.toLocaleTimeString(void 0, {
84179
+ const occurredAt = parseDateValue(event.occurredAt);
84180
+ const displayedCreatedAt = showSeparateEventOccurrenceTimestamps ? createdAt : getEffectiveEventDate(event);
84181
+ const displayedCreatedAtTime = displayedCreatedAt.toLocaleTimeString(void 0, {
83987
84182
  hour: "numeric",
83988
84183
  minute: "numeric",
83989
84184
  second: "numeric"
83990
84185
  });
83991
84186
  const displayPayload = isLoading ? loadedData : mergedDisplay;
83992
- return jsxRuntimeExports.jsxs(DetailCard, { variant: "card", summaryClassName: "px-3 py-2", summary: jsxRuntimeExports.jsxs("div", { className: "flex w-full items-center justify-between gap-3", children: [jsxRuntimeExports.jsx("span", { className: "text-gray-1000 text-label-12 font-mono", children: event.eventType }), jsxRuntimeExports.jsx("span", { className: "shrink-0 text-label-13 text-gray-900", children: createdAtTime })] }), onToggle: canHaveData ? (open) => {
84187
+ return jsxRuntimeExports.jsxs(DetailCard, { variant: "card", summaryClassName: "px-3 py-2", summary: jsxRuntimeExports.jsxs("div", { className: "flex w-full items-center justify-between gap-3", children: [jsxRuntimeExports.jsx("span", { className: "text-gray-1000 text-label-12 font-mono", children: event.eventType }), jsxRuntimeExports.jsx("span", { className: "shrink-0 text-label-13 text-gray-900", children: displayedCreatedAtTime })] }), onToggle: canHaveData ? (open) => {
83993
84188
  if (open)
83994
84189
  handleExpand();
83995
- } : void 0, children: [jsxRuntimeExports.jsxs("div", { className: "flex flex-col bg-background-200 [&:has(+_*)]:border-b [&:has(+_*)]:border-gray-alpha-400", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Event ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.eventId })] }), event.correlationId && jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Correlation ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.correlationId })] })] }), isLoading && jsxRuntimeExports.jsxs("div", { className: "p-3", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "h-4 w-[35%]" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "mt-2 h-4 w-[90%]" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "mt-2 h-4 w-[75%]" })] }), loadError && jsxRuntimeExports.jsx(ErrorCard, { title: "Failed to load event data", details: loadError, className: "mt-2" }), displayPayload != null && jsxRuntimeExports.jsx("div", { className: "[&>div]:border-none [&>div]:rounded-none", children: jsxRuntimeExports.jsx(EventDataBlock, { eventType: event.eventType, data: displayPayload }) })] });
84190
+ } : void 0, children: [jsxRuntimeExports.jsxs("div", { className: "flex flex-col bg-background-200 [&:has(+_*)]:border-b [&:has(+_*)]:border-gray-alpha-400", children: [showSeparateEventOccurrenceTimestamps && occurredAt && jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Occurred" }), jsxRuntimeExports.jsx(TimestampTooltip, { date: occurredAt, children: jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: formatEventTimestamp(occurredAt) }) })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Event ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.eventId })] }), event.correlationId && jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Correlation ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.correlationId })] })] }), isLoading && jsxRuntimeExports.jsxs("div", { className: "p-3", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "h-4 w-[35%]" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "mt-2 h-4 w-[90%]" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "mt-2 h-4 w-[75%]" })] }), loadError && jsxRuntimeExports.jsx(ErrorCard, { title: "Failed to load event data", details: loadError, className: "mt-2" }), displayPayload != null && jsxRuntimeExports.jsx("div", { className: "[&>div]:border-none [&>div]:rounded-none", children: jsxRuntimeExports.jsx(EventDataBlock, { eventType: event.eventType, data: displayPayload }) })] });
83996
84191
  }
83997
84192
  function hasOnlyExpiredFields(data, eventType) {
83998
84193
  if (data === null || typeof data !== "object" || Array.isArray(data)) {
@@ -84028,13 +84223,13 @@ function EventDataBlock({ eventType, data }) {
84028
84223
  }
84029
84224
  return jsxRuntimeExports.jsx(CopyableDataBlock, { data });
84030
84225
  }
84031
- function EventsList({ events: events2, isLoading = false, error: error2, onLoadEventData, onStreamClick, onRunClick, encryptionKey }) {
84032
- const sortedEvents2 = reactExports.useMemo(() => [...events2].sort((a2, b2) => new Date(a2.createdAt).getTime() - new Date(b2.createdAt).getTime()), [events2]);
84226
+ function EventsList({ events: events2, isLoading = false, error: error2, onLoadEventData, onStreamClick, onRunClick, encryptionKey, showSeparateEventOccurrenceTimestamps = false }) {
84227
+ const sortedEvents2 = reactExports.useMemo(() => [...events2].sort((a2, b2) => getEffectiveEventDate(a2).getTime() - getEffectiveEventDate(b2).getTime()), [events2]);
84033
84228
  const hasEvents = sortedEvents2.length > 0 && !error2;
84034
84229
  if (!hasEvents && !isLoading) {
84035
84230
  return jsxRuntimeExports.jsx(DetailCard, { summary: "Events", disabled: true });
84036
84231
  }
84037
- return jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsx(DetailCard, { summary: "Events", contentClassName: "mb-0", defaultOpen: true, children: isLoading ? jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: [0, 1, 2].map((i) => jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-3 bg-background-200 px-4 py-2", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "h-4 w-32 rounded" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3 w-16 rounded" })] }, i)) }) : jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: sortedEvents2.map((event) => jsxRuntimeExports.jsx(EventItem, { event, onLoadEventData, encryptionKey }, event.eventId)) }) }) }) });
84232
+ return jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsx(DetailCard, { summary: "Events", contentClassName: "mb-0", defaultOpen: true, children: isLoading ? jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: [0, 1, 2].map((i) => jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-3 bg-background-200 px-4 py-2", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "h-4 w-32 rounded" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3 w-16 rounded" })] }, i)) }) : jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: sortedEvents2.map((event) => jsxRuntimeExports.jsx(EventItem, { event, onLoadEventData, encryptionKey, showSeparateEventOccurrenceTimestamps }, event.eventId)) }) }) }) });
84038
84233
  }
84039
84234
  const SidebarDataContext = reactExports.createContext(null);
84040
84235
  SidebarDataContext.displayName = "SidebarDataContext";
@@ -84052,6 +84247,43 @@ function useSidebarDataOptional() {
84052
84247
  return reactExports.useContext(SidebarDataContext);
84053
84248
  }
84054
84249
  const hasField = (value, key) => key in value;
84250
+ const RESOURCES_WITH_FETCHED_DETAIL = /* @__PURE__ */ new Set(["run", "step", "sleep"]);
84251
+ function resourceNeedsFetchedDetail(resource) {
84252
+ return resource !== void 0 && RESOURCES_WITH_FETCHED_DETAIL.has(resource);
84253
+ }
84254
+ function deriveSpanDetailView(args) {
84255
+ const { resource, resourceId, inlineData, fetchedDetail, fetchedError } = args;
84256
+ const matchedDetail = spanDetailMatchesSelection(fetchedDetail, resource, resourceId) ? fetchedDetail : null;
84257
+ const displayData = mergeSpanDetail(inlineData, matchedDetail);
84258
+ if (!resource || !resourceId) {
84259
+ return { status: "idle", displayData, detail: null, error: void 0 };
84260
+ }
84261
+ if (fetchedError) {
84262
+ return {
84263
+ status: "error",
84264
+ displayData,
84265
+ detail: matchedDetail,
84266
+ error: fetchedError
84267
+ };
84268
+ }
84269
+ if (!resourceNeedsFetchedDetail(resource)) {
84270
+ return {
84271
+ status: "ready",
84272
+ displayData,
84273
+ detail: matchedDetail,
84274
+ error: void 0
84275
+ };
84276
+ }
84277
+ if (matchedDetail !== null) {
84278
+ return {
84279
+ status: "ready",
84280
+ displayData,
84281
+ detail: matchedDetail,
84282
+ error: void 0
84283
+ };
84284
+ }
84285
+ return { status: "loading", displayData, detail: null, error: void 0 };
84286
+ }
84055
84287
  function spanDetailMatchesSelection(detail, resource, resourceId) {
84056
84288
  if (!detail || typeof detail !== "object" || !resource || !resourceId) {
84057
84289
  return false;
@@ -84084,16 +84316,88 @@ function mergeSpanDetail(spanData, detail) {
84084
84316
  }
84085
84317
  return merged;
84086
84318
  }
84087
- function isStep(data) {
84088
- return data !== null && typeof data === "object" && "stepId" in data;
84319
+ function deriveSpanSelection(selectedSpan) {
84320
+ if (!selectedSpan)
84321
+ return null;
84322
+ const { resource, data } = selectedSpan;
84323
+ if (resource === "step" && data && typeof data === "object" && "stepId" in data) {
84324
+ const step = data;
84325
+ return { resource: "step", resourceId: step.stepId, runId: step.runId };
84326
+ }
84327
+ if (resource === "run" && data && typeof data === "object" && "runId" in data) {
84328
+ return { resource: "run", resourceId: data.runId };
84329
+ }
84330
+ if (resource === "hook" && data && typeof data === "object" && "hookId" in data) {
84331
+ return { resource: "hook", resourceId: data.hookId };
84332
+ }
84333
+ if (resource === "sleep") {
84334
+ if (!selectedSpan.spanId)
84335
+ return null;
84336
+ const waitData = data;
84337
+ return {
84338
+ resource: "sleep",
84339
+ resourceId: selectedSpan.spanId,
84340
+ runId: waitData == null ? void 0 : waitData.runId
84341
+ };
84342
+ }
84343
+ return null;
84089
84344
  }
84090
- function isWorkflowRun(data) {
84091
- return data !== null && typeof data === "object" && "runId" in data;
84345
+ function useSelectedSpanDetail(selectedSpan, fetchSpanDetail) {
84346
+ const selection2 = reactExports.useMemo(() => deriveSpanSelection(selectedSpan), [selectedSpan]);
84347
+ const resource = selection2 == null ? void 0 : selection2.resource;
84348
+ const resourceId = selection2 == null ? void 0 : selection2.resourceId;
84349
+ const runId = selection2 == null ? void 0 : selection2.runId;
84350
+ const selectionKey = resource && resourceId ? `${resource}:${resourceId}` : null;
84351
+ const needsFetch = resourceNeedsFetchedDetail(resource);
84352
+ const [fetched, setFetched] = reactExports.useState({ detail: null, error: null, errorKey: null });
84353
+ const tokenRef = reactExports.useRef(0);
84354
+ const selectionRef = reactExports.useRef(selection2);
84355
+ selectionRef.current = selection2;
84356
+ reactExports.useEffect(() => {
84357
+ if (!selectionKey || !needsFetch) {
84358
+ return;
84359
+ }
84360
+ const activeSelection = selectionRef.current;
84361
+ if (!activeSelection) {
84362
+ return;
84363
+ }
84364
+ const token = ++tokenRef.current;
84365
+ fetchSpanDetail(activeSelection).then((detail) => {
84366
+ if (tokenRef.current !== token)
84367
+ return;
84368
+ setFetched({ detail, error: null, errorKey: null });
84369
+ }).catch((err) => {
84370
+ if (tokenRef.current !== token)
84371
+ return;
84372
+ setFetched({
84373
+ detail: null,
84374
+ error: err instanceof Error ? err : new Error(String(err)),
84375
+ errorKey: selectionKey
84376
+ });
84377
+ });
84378
+ }, [selectionKey, runId, needsFetch, fetchSpanDetail]);
84379
+ const scopedError = fetched.errorKey === selectionKey ? fetched.error : null;
84380
+ const view = reactExports.useMemo(() => deriveSpanDetailView({
84381
+ resource,
84382
+ resourceId,
84383
+ inlineData: selectedSpan == null ? void 0 : selectedSpan.data,
84384
+ fetchedDetail: fetched.detail,
84385
+ fetchedError: scopedError
84386
+ }), [resource, resourceId, selectedSpan == null ? void 0 : selectedSpan.data, fetched.detail, scopedError]);
84387
+ return {
84388
+ status: view.status,
84389
+ resource,
84390
+ resourceId,
84391
+ runId,
84392
+ displayData: view.displayData,
84393
+ detail: view.detail,
84394
+ error: view.error
84395
+ };
84092
84396
  }
84093
84397
  function isHook(data) {
84094
84398
  return data !== null && typeof data === "object" && "hookId" in data;
84095
84399
  }
84096
- function EntityDetailPanel({ run: run2, onStreamClick, onRunClick, spanDetailData, spanDetailError, spanDetailLoading, onSpanSelect, onWakeUpSleep, onLoadEventData, onResolveHook, encryptionKey, onDecrypt, isDecrypting = false, selectedSpan }) {
84400
+ function EntityDetailPanel({ run: run2, onStreamClick, onRunClick, fetchSpanDetail, onWakeUpSleep, onLoadEventData, onResolveHook, encryptionKey, onDecrypt, isDecrypting = false, selectedSpan, showSeparateEventOccurrenceTimestamps = false }) {
84097
84401
  const toast2 = useToast();
84098
84402
  const [stoppingSleep, setStoppingSleep] = reactExports.useState(false);
84099
84403
  const [showResolveHookModal, setShowResolveHookModal] = reactExports.useState(false);
@@ -84104,41 +84408,8 @@ function EntityDetailPanel({ run: run2, onStreamClick, onRunClick, spanDetailDat
84104
84408
  const data = selectedSpan == null ? void 0 : selectedSpan.data;
84105
84409
  const rawEvents = selectedSpan == null ? void 0 : selectedSpan.rawEvents;
84106
84410
  const rawEventsLength = (rawEvents == null ? void 0 : rawEvents.length) ?? 0;
84107
- const { resource, resourceId, runId } = reactExports.useMemo(() => {
84108
- if (!selectedSpan) {
84109
- return { resource: void 0, resourceId: void 0, runId: void 0 };
84110
- }
84111
- const res = selectedSpan.resource;
84112
- if (res === "step" && isStep(data)) {
84113
- return { resource: "step", resourceId: data.stepId, runId: data.runId };
84114
- }
84115
- if (res === "run" && isWorkflowRun(data)) {
84116
- return { resource: "run", resourceId: data.runId, runId: void 0 };
84117
- }
84118
- if (res === "hook" && isHook(data)) {
84119
- return { resource: "hook", resourceId: data.hookId, runId: void 0 };
84120
- }
84121
- if (res === "sleep") {
84122
- const waitData = data;
84123
- return {
84124
- resource: "sleep",
84125
- resourceId: selectedSpan.spanId,
84126
- runId: waitData == null ? void 0 : waitData.runId
84127
- };
84128
- }
84129
- return { resource: void 0, resourceId: void 0, runId: void 0 };
84130
- }, [selectedSpan, data]);
84131
- const onSpanSelectRef = reactExports.useRef(onSpanSelect);
84132
- onSpanSelectRef.current = onSpanSelect;
84133
- reactExports.useEffect(() => {
84134
- if (resource && resourceId && ["run", "step", "hook", "sleep"].includes(resource)) {
84135
- onSpanSelectRef.current({
84136
- resource,
84137
- resourceId,
84138
- runId
84139
- });
84140
- }
84141
- }, [resource, resourceId, runId]);
84411
+ const { status, resource, resourceId, displayData, detail: matchedSpanDetailData, error: error2 } = useSelectedSpanDetail(selectedSpan, fetchSpanDetail);
84412
+ const loading = status === "loading";
84142
84413
  const canWakeUp = reactExports.useMemo(() => {
84143
84414
  if (resource !== "sleep" || !rawEvents)
84144
84415
  return false;
@@ -84171,9 +84442,6 @@ function EntityDetailPanel({ run: run2, onStreamClick, onRunClick, spanDetailDat
84171
84442
  run2.status,
84172
84443
  resolvedHookIds
84173
84444
  ]);
84174
- const error2 = spanDetailError ?? void 0;
84175
- const loading = spanDetailLoading ?? false;
84176
- const matchedSpanDetailData = reactExports.useMemo(() => spanDetailMatchesSelection(spanDetailData, resource, resourceId) ? spanDetailData : null, [spanDetailData, resource, resourceId]);
84177
84445
  const hookToken = reactExports.useMemo(() => {
84178
84446
  if (resource !== "hook" || !resourceId)
84179
84447
  return void 0;
@@ -84258,7 +84526,6 @@ function EntityDetailPanel({ run: run2, onStreamClick, onRunClick, spanDetailDat
84258
84526
  setResolvingHook(false);
84259
84527
  }
84260
84528
  }, [onResolveHook, hookToken, resolvingHook, matchedSpanDetailData, data]);
84261
- const displayData = reactExports.useMemo(() => mergeSpanDetail(data, matchedSpanDetailData), [data, matchedSpanDetailData]);
84262
84529
  const moduleSpecifier = reactExports.useMemo(() => {
84263
84530
  const displayRecord = displayData;
84264
84531
  const displayStepName = displayRecord.stepName;
@@ -84287,7 +84554,7 @@ function EntityDetailPanel({ run: run2, onStreamClick, onRunClick, spanDetailDat
84287
84554
  }, children: [jsxRuntimeExports.jsx(Zap, { className: "h-4 w-4" }), stoppingSleep ? "Waking up..." : "Wake Up Sleep"] }), resource === "hook" && canResolveHook && jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => setShowResolveHookModal(true), disabled: resolvingHook, className: clsx("flex items-center justify-center gap-2 rounded-md px-3 py-2 text-sm font-medium", "disabled:opacity-50 disabled:cursor-not-allowed transition-colors", resolvingHook ? "opacity-50 cursor-not-allowed" : "cursor-pointer"), style: {
84288
84555
  background: "var(--ds-gray-1000)",
84289
84556
  color: "var(--ds-background-100)"
84290
- }, children: [jsxRuntimeExports.jsx(Send, { className: "h-4 w-4" }), "Resolve Hook"] })] })] }), jsxRuntimeExports.jsx(AttributePanel, { data: displayData, moduleSpecifier, expiredAt: run2.expiredAt, isLoading: loading, error: error2 ?? void 0, onStreamClick, onRunClick, onDecrypt, isDecrypting, resource }), rawEvents && jsxRuntimeExports.jsx(EventsList, { events: rawEvents, onLoadEventData, onStreamClick, onRunClick, encryptionKey })] }) }), jsxRuntimeExports.jsx(ResolveHookModal, { isOpen: showResolveHookModal, onClose: () => setShowResolveHookModal(false), onSubmit: handleResolveHook, isSubmitting: resolvingHook })] });
84557
+ }, children: [jsxRuntimeExports.jsx(Send, { className: "h-4 w-4" }), "Resolve Hook"] })] })] }), jsxRuntimeExports.jsx(AttributePanel, { data: displayData, moduleSpecifier, expiredAt: run2.expiredAt, isLoading: loading, error: error2 ?? void 0, onStreamClick, onRunClick, onDecrypt, isDecrypting, resource }), rawEvents && jsxRuntimeExports.jsx(EventsList, { events: rawEvents, onLoadEventData, onStreamClick, onRunClick, encryptionKey, showSeparateEventOccurrenceTimestamps })] }) }), jsxRuntimeExports.jsx(ResolveHookModal, { isOpen: showResolveHookModal, onClose: () => setShowResolveHookModal(false), onSubmit: handleResolveHook, isSubmitting: resolvingHook })] });
84291
84558
  }
84292
84559
  const MAP_HEIGHT = 56;
84293
84560
  const TIMELINE_PADDING = 8;
@@ -85554,6 +85821,41 @@ function StreamViewer({ streamId: _streamId, chunks, isLive, error: error2, isLo
85554
85821
  color: "var(--ds-gray-600)"
85555
85822
  }, 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 } }) })] });
85556
85823
  }
85824
+ function useIntersectionObserver(elementRef, { threshold = 0, rootRef, rootMargin = "0%", freezeOnceVisible = false } = {}) {
85825
+ const [entry2, setEntry] = reactExports.useState();
85826
+ const frozen = (entry2 == null ? void 0 : entry2.isIntersecting) && freezeOnceVisible;
85827
+ reactExports.useEffect(() => {
85828
+ const node2 = elementRef == null ? void 0 : elementRef.current;
85829
+ const hasIOSupport = !!window.IntersectionObserver;
85830
+ if (!hasIOSupport || frozen || !node2)
85831
+ return;
85832
+ const updateEntry = ([entry3]) => {
85833
+ setEntry(entry3);
85834
+ };
85835
+ const observer = new IntersectionObserver(updateEntry, {
85836
+ threshold,
85837
+ root: (rootRef == null ? void 0 : rootRef.current) ?? null,
85838
+ rootMargin
85839
+ });
85840
+ observer.observe(node2);
85841
+ return () => observer.disconnect();
85842
+ }, [elementRef, threshold, rootRef, rootMargin, frozen]);
85843
+ return entry2;
85844
+ }
85845
+ function useLoadMoreOnScroll(loadMore, { hasMore, isLoadingMore, rootRef, rootMargin = "400px" }) {
85846
+ const sentinelRef = reactExports.useRef(null);
85847
+ const entry2 = useIntersectionObserver(sentinelRef, { rootRef, rootMargin });
85848
+ const loadMoreRef = reactExports.useRef(loadMore);
85849
+ reactExports.useEffect(() => {
85850
+ loadMoreRef.current = loadMore;
85851
+ }, [loadMore]);
85852
+ reactExports.useEffect(() => {
85853
+ if ((entry2 == null ? void 0 : entry2.isIntersecting) && hasMore && !isLoadingMore) {
85854
+ loadMoreRef.current();
85855
+ }
85856
+ }, [entry2 == null ? void 0 : entry2.isIntersecting, hasMore, isLoadingMore]);
85857
+ return sentinelRef;
85858
+ }
85557
85859
  const iconButtonVariants = cva([
85558
85860
  "m-0 inline-flex shrink-0 appearance-none items-center justify-center border-0 bg-transparent p-0 align-baseline font-inherit no-underline [background:none] [-webkit-appearance:none] [-webkit-tap-highlight-color:transparent]",
85559
85861
  "transition-colors duration-150 ease-in-out",
@@ -85597,57 +85899,6 @@ const kbdVariants = cva("inline-flex items-center justify-center rounded px-1 te
85597
85899
  function Kbd({ children: children2, className, variant, size: size2, ...props }) {
85598
85900
  return jsxRuntimeExports.jsx("kbd", { className: cn$4(kbdVariants({ variant, size: size2, className })), ...props, children: children2 });
85599
85901
  }
85600
- const COL_TEMPLATE = "340px 1px minmax(50px, 1fr)";
85601
- const ROWS = [
85602
- { id: "r0", name: 62, off: 0, bar: 72 },
85603
- { id: "r1", name: 78, off: 6, bar: 48 },
85604
- { id: "r2", name: 50, off: 10, bar: 55 },
85605
- { id: "r3", name: 84, off: 18, bar: 30 },
85606
- { id: "r4", name: 45, off: 18, bar: 42 },
85607
- { id: "r5", name: 66, off: 34, bar: 38 },
85608
- { id: "r6", name: 55, off: 41, bar: 25 },
85609
- { id: "r7", name: 40, off: 50, bar: 30 }
85610
- ];
85611
- const HEADER_MARKERS = ["m0", "m1", "m2", "m3"];
85612
- const HeaderDivider = () => jsxRuntimeExports.jsx("div", { className: "flex justify-center", children: jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }) });
85613
- function TraceViewerSkeleton() {
85614
- return jsxRuntimeExports.jsxs("output", { "aria-busy": "true", "aria-label": "Loading trace", className: "flex flex-col w-full h-full min-h-0 bg-background-100", children: [jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Loading trace…" }), jsxRuntimeExports.jsxs("div", { className: "shrink-0 grid", style: { gridTemplateColumns: COL_TEMPLATE }, children: [jsxRuntimeExports.jsxs("div", { className: "h-10 min-h-10 flex items-center border-b border-gray-alpha-400 pl-4 pr-2 gap-1.5", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "w-3.5 h-3.5 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3.5 w-40" })] }), jsxRuntimeExports.jsx(HeaderDivider, {}), jsxRuntimeExports.jsx("div", { className: "h-10 min-h-10 flex items-end border-b border-gray-alpha-400 px-4 pb-1 gap-2", children: jsxRuntimeExports.jsx("div", { className: "relative flex-1 flex items-end justify-between", children: HEADER_MARKERS.map((id2) => jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3.5 w-9" }, id2)) }) })] }), jsxRuntimeExports.jsxs("div", { className: "grid flex-1 min-h-0 overflow-hidden", style: { gridTemplateColumns: COL_TEMPLATE }, children: [jsxRuntimeExports.jsx("div", { className: "block overflow-visible", children: jsxRuntimeExports.jsx("ul", { className: "block divide-y divide-gray-alpha-400 border-b border-gray-alpha-400", children: ROWS.map((row) => jsxRuntimeExports.jsxs("li", { className: "h-10 flex items-center pl-4 pr-2", children: [jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [jsxRuntimeExports.jsx(Skeleton$2, { className: "w-4 h-4 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton$2, { className: "h-3.5", style: { width: `${row.name}%` } })] }), jsxRuntimeExports.jsx(Skeleton$2, { className: "ml-2 h-3.5 w-10 shrink-0" })] }, row.id)) }) }), jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }), jsxRuntimeExports.jsx("div", { className: "relative min-h-0", children: ROWS.map((row) => jsxRuntimeExports.jsx("div", { className: "relative h-10", children: jsxRuntimeExports.jsx("div", { className: "absolute inset-x-4 inset-y-0", children: jsxRuntimeExports.jsx(Skeleton$2, { className: "absolute top-1/2 -translate-y-1/2 h-6 rounded-[0.25rem]", style: { left: `${row.off}%`, width: `${row.bar}%` } }) }) }, row.id)) })] })] });
85615
- }
85616
- function useIntersectionObserver(elementRef, { threshold = 0, rootRef, rootMargin = "0%", freezeOnceVisible = false } = {}) {
85617
- const [entry2, setEntry] = reactExports.useState();
85618
- const frozen = (entry2 == null ? void 0 : entry2.isIntersecting) && freezeOnceVisible;
85619
- reactExports.useEffect(() => {
85620
- const node2 = elementRef == null ? void 0 : elementRef.current;
85621
- const hasIOSupport = !!window.IntersectionObserver;
85622
- if (!hasIOSupport || frozen || !node2)
85623
- return;
85624
- const updateEntry = ([entry3]) => {
85625
- setEntry(entry3);
85626
- };
85627
- const observer = new IntersectionObserver(updateEntry, {
85628
- threshold,
85629
- root: (rootRef == null ? void 0 : rootRef.current) ?? null,
85630
- rootMargin
85631
- });
85632
- observer.observe(node2);
85633
- return () => observer.disconnect();
85634
- }, [elementRef, threshold, rootRef, rootMargin, frozen]);
85635
- return entry2;
85636
- }
85637
- function useLoadMoreOnScroll(loadMore, { hasMore, isLoadingMore, rootRef, rootMargin = "400px" }) {
85638
- const sentinelRef = reactExports.useRef(null);
85639
- const entry2 = useIntersectionObserver(sentinelRef, { rootRef, rootMargin });
85640
- const loadMoreRef = reactExports.useRef(loadMore);
85641
- reactExports.useEffect(() => {
85642
- loadMoreRef.current = loadMore;
85643
- }, [loadMore]);
85644
- reactExports.useEffect(() => {
85645
- if ((entry2 == null ? void 0 : entry2.isIntersecting) && hasMore && !isLoadingMore) {
85646
- loadMoreRef.current();
85647
- }
85648
- }, [entry2 == null ? void 0 : entry2.isIntersecting, hasMore, isLoadingMore]);
85649
- return sentinelRef;
85650
- }
85651
85902
  const TooltipProvider = Provider$2;
85652
85903
  const Tooltip$1 = Root3$1;
85653
85904
  const TooltipTrigger$1 = Trigger$4;
@@ -86233,57 +86484,6 @@ const EventList = ({ spans, activeSpanId, searchResult, onSelectSpan }) => {
86233
86484
  paddingBottom: (spans.length - end) * ROW_HEIGHT_PX
86234
86485
  }, children: spans.slice(start2, end).map((span) => jsxRuntimeExports.jsx(EventRow, { span, isSelected: span.spanId === activeSpanId, isDimmed: isSpanDimmedBySearch(span.spanId, searchResult), onSelectSpan }, span.spanId)) });
86235
86486
  };
86236
- const hint$1 = "_hint_1dmsq_3";
86237
- const styles$2 = {
86238
- hint: hint$1
86239
- };
86240
- const DISMISSALS_KEY = "workflow-step-shortcut-helper-dismissals";
86241
- const DISMISSAL_LIMIT = 3;
86242
- const HINT_ROTATION_MS = 8e3;
86243
- function getAltKeyLabel() {
86244
- if (typeof navigator === "undefined")
86245
- return "Alt";
86246
- return navigator.platform.toLowerCase().includes("mac") ? "Option" : "Alt";
86247
- }
86248
- function readDismissals() {
86249
- try {
86250
- const dismissals = Number.parseInt(window.localStorage.getItem(DISMISSALS_KEY) ?? "0", 10);
86251
- return Number.isNaN(dismissals) ? 0 : dismissals;
86252
- } catch {
86253
- return 0;
86254
- }
86255
- }
86256
- function AltHint() {
86257
- return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: ["Hold", jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "compact", className: "mx-1", children: getAltKeyLabel() }), "to see delta between spans"] });
86258
- }
86259
- function NavHint() {
86260
- return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: ["Use", jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "compact", className: "ml-1", children: "J" }), jsxRuntimeExports.jsx("span", { className: "mx-1", children: "/" }), jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "compact", className: "mr-1", children: "K" }), "to move between spans"] });
86261
- }
86262
- function TraceShortcutHelper({ hasMultipleSpans, reducedMotion }) {
86263
- const [visible, setVisible] = reactExports.useState(false);
86264
- const [index2, setIndex] = reactExports.useState(0);
86265
- reactExports.useEffect(() => {
86266
- setVisible(readDismissals() < DISMISSAL_LIMIT);
86267
- }, []);
86268
- reactExports.useEffect(() => {
86269
- if (reducedMotion)
86270
- return;
86271
- const id2 = setInterval(() => {
86272
- setIndex((i) => i === 0 ? 1 : 0);
86273
- }, HINT_ROTATION_MS);
86274
- return () => clearInterval(id2);
86275
- }, [reducedMotion]);
86276
- if (!visible || !hasMultipleSpans)
86277
- return null;
86278
- const dismiss = () => {
86279
- try {
86280
- window.localStorage.setItem(DISMISSALS_KEY, String(readDismissals() + 1));
86281
- } catch {
86282
- }
86283
- setVisible(false);
86284
- };
86285
- return jsxRuntimeExports.jsxs("div", { className: "group absolute bottom-3 left-1/2 z-10 hidden h-8 max-w-[calc(100%-2rem)] -translate-x-1/2 items-center gap-1 text-xs leading-none text-gray-900 md:inline-flex", children: [jsxRuntimeExports.jsx("span", { "aria-live": "polite", "aria-atomic": "true", className: "inline-flex items-center whitespace-nowrap", children: reducedMotion ? jsxRuntimeExports.jsx(AltHint, {}) : jsxRuntimeExports.jsx("span", { className: `inline-flex items-center ${styles$2.hint}`, children: index2 === 0 ? jsxRuntimeExports.jsx(AltHint, {}) : jsxRuntimeExports.jsx(NavHint, {}) }, index2) }), jsxRuntimeExports.jsx("button", { type: "button", className: "inline-flex h-5 w-5 items-center justify-center rounded text-muted-foreground opacity-0 transition-opacity hover:bg-accent hover:text-foreground group-hover:opacity-100 focus-visible:opacity-100 motion-reduce:transition-none", onClick: dismiss, "aria-label": "Dismiss trace shortcuts helper", children: jsxRuntimeExports.jsx(X$3, { className: "h-3 w-3" }) })] });
86286
- }
86287
86487
  const GUTTER_PX = 1;
86288
86488
  const MIN_PX = 50;
86289
86489
  const DEFAULT_START_PX = 340;
@@ -86424,11 +86624,11 @@ function OffscreenMarkerIndicator({ direction, count: count2, targetMs, onReveal
86424
86624
  return jsxRuntimeExports.jsx("button", { type: "button", "aria-label": label, title: label, onClick: (e) => {
86425
86625
  e.stopPropagation();
86426
86626
  onReveal == null ? void 0 : onReveal(targetMs);
86427
- }, className: cn$4("pointer-events-auto absolute top-1/2 z-20 flex h-6 -translate-y-1/2 cursor-pointer items-center rounded-[0.25rem] border border-gray-alpha-400 bg-background-100 shadow-sm hover:bg-gray-100", direction === "right" ? "right-0 pl-1.5" : "left-0 pr-1.5"), children: direction === "left" ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [chevron, tick] }) : jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [tick, chevron] }) });
86627
+ }, className: cn$4("pointer-events-auto absolute top-1/2 z-20 flex h-6 -translate-y-1/2 cursor-pointer items-center rounded-[0.25rem] border border-gray-alpha-400 bg-background-100 hover:bg-gray-100", direction === "right" ? "right-0 pl-1.5" : "left-0 pr-1.5"), children: direction === "left" ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [chevron, tick] }) : jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [tick, chevron] }) });
86428
86628
  }
86429
86629
  const runningStripes = "_runningStripes_1ii0z_1";
86430
86630
  const pendingStripes = "_pendingStripes_1ii0z_2";
86431
- const styles$1 = {
86631
+ const styles$2 = {
86432
86632
  runningStripes,
86433
86633
  pendingStripes
86434
86634
  };
@@ -86457,7 +86657,7 @@ const STRIPED_SEGMENT_STATUSES = /* @__PURE__ */ new Set([
86457
86657
  "received"
86458
86658
  ]);
86459
86659
  function AnimatedStripes({ status }) {
86460
- return jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: status === "pending" ? styles$1.pendingStripes : styles$1.runningStripes });
86660
+ return jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: status === "pending" ? styles$2.pendingStripes : styles$2.runningStripes });
86461
86661
  }
86462
86662
  function computeBarGeometry(startMs, endMs, viewStart, viewEnd, containerWidth) {
86463
86663
  const viewDuration = viewEnd - viewStart;
@@ -86621,6 +86821,57 @@ function Timeline({ spans, viewStart, viewEnd, markers: markers2, selectedId, se
86621
86821
  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}%` } }, String(marker2.value)) : null
86622
86822
  )) }), 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}%` } }) }), jsxRuntimeExports.jsx("div", { style: { transform: `translateY(${start2 * ROW_HEIGHT_PX}px)` }, children: spans.slice(start2, end).map((span) => jsxRuntimeExports.jsx(TimelineBar, { span, viewStart, viewDuration, containerWidth: timelineWidth, isSelected: selectedId === span.spanId, isDimmed: isSpanDimmedBySearch(span.spanId, searchResult), onSelect, onRevealTime }, 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)) })] });
86623
86823
  }
86824
+ const hint$1 = "_hint_1dmsq_3";
86825
+ const styles$1 = {
86826
+ hint: hint$1
86827
+ };
86828
+ const DISMISSALS_KEY = "workflow-step-shortcut-helper-dismissals";
86829
+ const DISMISSAL_LIMIT = 3;
86830
+ const HINT_ROTATION_MS = 8e3;
86831
+ function getAltKeyLabel() {
86832
+ if (typeof navigator === "undefined")
86833
+ return "Alt";
86834
+ return navigator.platform.toLowerCase().includes("mac") ? "Option" : "Alt";
86835
+ }
86836
+ function readDismissals() {
86837
+ try {
86838
+ const dismissals = Number.parseInt(window.localStorage.getItem(DISMISSALS_KEY) ?? "0", 10);
86839
+ return Number.isNaN(dismissals) ? 0 : dismissals;
86840
+ } catch {
86841
+ return 0;
86842
+ }
86843
+ }
86844
+ function AltHint() {
86845
+ return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: ["Hold", jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "compact", className: "mx-1", children: getAltKeyLabel() }), "to see delta between spans"] });
86846
+ }
86847
+ function NavHint() {
86848
+ return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: ["Use", jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "compact", className: "ml-1", children: "J" }), jsxRuntimeExports.jsx("span", { className: "mx-1", children: "/" }), jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "compact", className: "mr-1", children: "K" }), "to move between spans"] });
86849
+ }
86850
+ function TraceShortcutHelper({ hasMultipleSpans, reducedMotion }) {
86851
+ const [visible, setVisible] = reactExports.useState(false);
86852
+ const [index2, setIndex] = reactExports.useState(0);
86853
+ reactExports.useEffect(() => {
86854
+ setVisible(readDismissals() < DISMISSAL_LIMIT);
86855
+ }, []);
86856
+ reactExports.useEffect(() => {
86857
+ if (reducedMotion)
86858
+ return;
86859
+ const id2 = setInterval(() => {
86860
+ setIndex((i) => i === 0 ? 1 : 0);
86861
+ }, HINT_ROTATION_MS);
86862
+ return () => clearInterval(id2);
86863
+ }, [reducedMotion]);
86864
+ if (!visible || !hasMultipleSpans)
86865
+ return null;
86866
+ const dismiss = () => {
86867
+ try {
86868
+ window.localStorage.setItem(DISMISSALS_KEY, String(readDismissals() + 1));
86869
+ } catch {
86870
+ }
86871
+ setVisible(false);
86872
+ };
86873
+ return jsxRuntimeExports.jsxs("div", { className: "group absolute bottom-3 left-1/2 z-10 hidden h-8 max-w-[calc(100%-2rem)] -translate-x-1/2 items-center gap-1 text-xs leading-none text-gray-900 md:inline-flex", children: [jsxRuntimeExports.jsx("span", { "aria-live": "polite", "aria-atomic": "true", className: "inline-flex items-center whitespace-nowrap", children: reducedMotion ? jsxRuntimeExports.jsx(AltHint, {}) : jsxRuntimeExports.jsx("span", { className: `inline-flex items-center ${styles$1.hint}`, children: index2 === 0 ? jsxRuntimeExports.jsx(AltHint, {}) : jsxRuntimeExports.jsx(NavHint, {}) }, index2) }), jsxRuntimeExports.jsx("button", { type: "button", className: "inline-flex h-5 w-5 items-center justify-center rounded text-muted-foreground opacity-0 transition-opacity hover:bg-accent hover:text-foreground group-hover:opacity-100 focus-visible:opacity-100 motion-reduce:transition-none", onClick: dismiss, "aria-label": "Dismiss trace shortcuts helper", children: jsxRuntimeExports.jsx(X$3, { className: "h-3 w-3" }) })] });
86874
+ }
86624
86875
  const ActiveSpanContext = reactExports.createContext(null);
86625
86876
  ActiveSpanContext.displayName = "ActiveSpanContext";
86626
86877
  function ActiveSpanProvider({ spans, children: children2 }) {
@@ -87074,7 +87325,7 @@ function NewTraceViewerContent({ trace: trace2, onLoadMore, hasMore, isLoadingMo
87074
87325
  e.stopPropagation();
87075
87326
  setSearchQuery("");
87076
87327
  }
87077
- }, 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", "aria-label": "Clear search", onClick: () => setSearchQuery(""), className: "-mr-2 hidden h-full max-w-full shrink-0 cursor-pointer items-center rounded-r-md border-0 bg-transparent px-2.5 font-inherit text-base text-gray-900 no-underline transition-colors duration-150 ease-in hover:text-gray-1000 focus-visible:-outline-offset-1 focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--ds-focus-color)] min-[961px]:flex", children: jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "search", children: "Esc" }) })] }), endHeader: jsxRuntimeExports.jsx(TimelineHeader, { markers: timeMarkers, hoverInfo: hoverInfo2 }), children: [jsxRuntimeExports.jsxs("div", { className: "block overflow-visible", children: [jsxRuntimeExports.jsx(EventList, { spans: trace2.spans, activeSpanId, searchResult, onSelectSpan: handleSelectSpan }), jsxRuntimeExports.jsx("div", { ref: loadMoreSentinelRef, className: "flex justify-center", children: isLoadingMore ? jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-center gap-2 py-3 text-sm text-gray-800", children: [jsxRuntimeExports.jsx(Spinner, { size: 14 }), jsxRuntimeExports.jsx("span", { children: "Loading spans…" })] }) : null })] }), jsxRuntimeExports.jsx("div", { ref: timelineRef, className: "block min-h-0 overflow-visible relative", onDoubleClick: resetZoom, onMouseMove: handleTimelineMouseMove, onMouseLeave: handleTimelineMouseLeave, children: jsxRuntimeExports.jsx(Timeline, { spans: trace2.spans, viewStart: viewport.start, viewEnd: viewport.end, markers: timeMarkers, selectedId: activeSpanId, searchResult, onSelect: handleSelectSpan, onRevealTime: handleRevealTime, hoverFraction, altHeld }) })] }), jsxRuntimeExports.jsxs("div", { className: "absolute right-3 bottom-3 z-[5] flex items-center border border-gray-alpha-400 rounded-md bg-background-100 shadow-sm overflow-hidden divide-x divide-gray-alpha-400", children: [jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: zoomOut, "aria-label": "Zoom out", children: jsxRuntimeExports.jsx(ZoomOut, { className: "w-4 h-4" }) }), jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: resetZoom, "aria-label": "Reset zoom", children: jsxRuntimeExports.jsx(RotateCcw, { className: "w-3.5 h-3.5" }) }), jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: zoomIn, "aria-label": "Zoom in", children: jsxRuntimeExports.jsx(ZoomIn, { className: "w-4 h-4" }) })] })] }), activeSpan ? 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.jsxs("div", { className: "flex items-center justify-between gap-2 shrink-0 px-4 pt-3 pb-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-14 font-medium text-gray-1000 truncate block", children: selectedSpanName }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0.5 shrink-0", children: [jsxRuntimeExports.jsxs(Tooltip$1, { children: [jsxRuntimeExports.jsx(TooltipTrigger$1, { asChild: true, children: jsxRuntimeExports.jsx(IconButton, { "aria-label": "Navigate up", "aria-keyshortcuts": "K", onClick: handleSelectPrevSpan, disabled: !prevSpanId, children: jsxRuntimeExports.jsx(ChevronUp, { className: "w-4 h-4" }) }) }), prevSpanId ? jsxRuntimeExports.jsxs(TooltipContent$1, { children: ["Navigate up", jsxRuntimeExports.jsx(Kbd, { children: "K" })] }) : null] }), jsxRuntimeExports.jsxs(Tooltip$1, { children: [jsxRuntimeExports.jsx(TooltipTrigger$1, { asChild: true, children: jsxRuntimeExports.jsx(IconButton, { "aria-label": "Navigate down", "aria-keyshortcuts": "J", onClick: handleSelectNextSpan, disabled: !nextSpanId, children: jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4" }) }) }), nextSpanId ? jsxRuntimeExports.jsxs(TooltipContent$1, { children: ["Navigate down", jsxRuntimeExports.jsx(Kbd, { children: "J" })] }) : null] }), jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "w-px h-4 bg-gray-alpha-400 mx-1" }), jsxRuntimeExports.jsx(IconButton, { "aria-label": "Close span details", "aria-keyshortcuts": "Escape", onClick: handleClearActiveSpan, 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 }) }) })] }) : null, jsxRuntimeExports.jsx(TraceShortcutHelper, { hasMultipleSpans: trace2.spans.length > 1, reducedMotion })] });
87328
+ }, 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", "aria-label": "Clear search", onClick: () => setSearchQuery(""), className: "-mr-2 hidden h-full max-w-full shrink-0 cursor-pointer items-center rounded-r-md border-0 bg-transparent px-2.5 font-inherit text-base text-gray-900 no-underline transition-colors duration-150 ease-in hover:text-gray-1000 focus-visible:-outline-offset-1 focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--ds-focus-color)] min-[961px]:flex", children: jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "search", children: "Esc" }) })] }), endHeader: jsxRuntimeExports.jsx(TimelineHeader, { markers: timeMarkers, hoverInfo: hoverInfo2 }), children: [jsxRuntimeExports.jsxs("div", { className: "block overflow-visible", children: [jsxRuntimeExports.jsx(EventList, { spans: trace2.spans, activeSpanId, searchResult, onSelectSpan: handleSelectSpan }), jsxRuntimeExports.jsx("div", { ref: loadMoreSentinelRef, className: "flex justify-center", children: isLoadingMore ? jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-center gap-2 py-3 text-sm text-gray-800", children: [jsxRuntimeExports.jsx(Spinner, { size: 14 }), jsxRuntimeExports.jsx("span", { children: "Loading spans…" })] }) : null })] }), jsxRuntimeExports.jsx("div", { ref: timelineRef, className: "block min-h-0 overflow-visible relative", onDoubleClick: resetZoom, onMouseMove: handleTimelineMouseMove, onMouseLeave: handleTimelineMouseLeave, children: jsxRuntimeExports.jsx(Timeline, { spans: trace2.spans, viewStart: viewport.start, viewEnd: viewport.end, markers: timeMarkers, selectedId: activeSpanId, searchResult, onSelect: handleSelectSpan, onRevealTime: handleRevealTime, hoverFraction, altHeld }) })] }), jsxRuntimeExports.jsxs("div", { className: "absolute right-3 bottom-3 z-[5] flex items-center border border-gray-alpha-400 rounded-md bg-background-100 shadow-sm overflow-hidden divide-x divide-gray-alpha-400", children: [jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: zoomOut, "aria-label": "Zoom out", children: jsxRuntimeExports.jsx(ZoomOut, { className: "w-4 h-4" }) }), jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: resetZoom, "aria-label": "Reset zoom", children: jsxRuntimeExports.jsx(RotateCcw, { className: "w-3.5 h-3.5" }) }), jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: zoomIn, "aria-label": "Zoom in", children: jsxRuntimeExports.jsx(ZoomIn, { className: "w-4 h-4" }) })] })] }), activeSpan ? 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.jsxs("div", { className: "flex items-center justify-between gap-2 shrink-0 px-4 pt-3 pb-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-14 font-medium text-gray-1000 truncate block", children: selectedSpanName }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0.5 shrink-0", children: [jsxRuntimeExports.jsxs(Tooltip$1, { children: [jsxRuntimeExports.jsx(TooltipTrigger$1, { asChild: true, children: jsxRuntimeExports.jsx(IconButton, { "aria-label": "Navigate up", "aria-keyshortcuts": "K", onClick: handleSelectPrevSpan, disabled: !prevSpanId, children: jsxRuntimeExports.jsx(ChevronUp, { className: "w-4 h-4" }) }) }), prevSpanId ? jsxRuntimeExports.jsxs(TooltipContent$1, { children: ["Navigate up", jsxRuntimeExports.jsx(Kbd, { children: "K" })] }) : null] }), jsxRuntimeExports.jsxs(Tooltip$1, { children: [jsxRuntimeExports.jsx(TooltipTrigger$1, { asChild: true, children: jsxRuntimeExports.jsx(IconButton, { "aria-label": "Navigate down", "aria-keyshortcuts": "J", onClick: handleSelectNextSpan, disabled: !nextSpanId, children: jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4" }) }) }), nextSpanId ? jsxRuntimeExports.jsxs(TooltipContent$1, { children: ["Navigate down", jsxRuntimeExports.jsx(Kbd, { children: "J" })] }) : null] }), jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "w-px h-4 bg-gray-alpha-400 mx-1" }), jsxRuntimeExports.jsx(IconButton, { "aria-label": "Close span details", "aria-keyshortcuts": "Escape", onClick: handleClearActiveSpan, 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, fetchSpanDetail: sidebar.fetchSpanDetail, onWakeUpSleep: sidebar.onWakeUpSleep, onLoadEventData: sidebar.onLoadEventData, onResolveHook: sidebar.onResolveHook, encryptionKey: sidebar.encryptionKey, onDecrypt: sidebar.onDecrypt, isDecrypting: sidebar.isDecrypting, selectedSpan, showSeparateEventOccurrenceTimestamps: sidebar.showSeparateEventOccurrenceTimestamps }) }) })] }) : null, jsxRuntimeExports.jsx(TraceShortcutHelper, { hasMultipleSpans: trace2.spans.length > 1, reducedMotion })] });
87078
87329
  }
87079
87330
  const NewTraceViewer = ({ run: run2, events: events2, sidebarData, onLoadMore, hasMore, isLoadingMore, loading = false }) => {
87080
87331
  const trace2 = reactExports.useMemo(() => {
@@ -90771,7 +91022,7 @@ async function deserializeTraceCarrier(traceCarrier) {
90771
91022
  }
90772
91023
  const OtelApi = once$1(async () => {
90773
91024
  try {
90774
- return await import("./index-meg9qk8y.js");
91025
+ return await import("./index-Dq5jTBN4.js");
90775
91026
  } catch {
90776
91027
  runtimeLogger.info("OpenTelemetry not available, tracing will be disabled");
90777
91028
  return null;
@@ -90870,10 +91121,11 @@ function matchesDebugNamespace(namespace2, patternList) {
90870
91121
  }
90871
91122
  return enabled;
90872
91123
  }
90873
- function createLogger(namespace2) {
91124
+ function createLogger(namespace2, options = {}) {
90874
91125
  const build = (parentMetadata) => {
91126
+ const getDebugNamespace = (level) => options.debugNamespace ?? `workflow:${namespace2}:${level}`;
90875
91127
  const logger = (level) => {
90876
- const debugNamespace = `workflow:${namespace2}:${level}`;
91128
+ const debugNamespace = getDebugNamespace(level);
90877
91129
  return (message2, metadata) => {
90878
91130
  const hasParent = Object.keys(parentMetadata).length > 0;
90879
91131
  const hasCallSite = metadata && Object.keys(metadata).length > 0;
@@ -90908,7 +91160,14 @@ function createLogger(namespace2) {
90908
91160
  };
90909
91161
  return build({});
90910
91162
  }
91163
+ createLogger("step");
90911
91164
  const runtimeLogger = createLogger("runtime");
91165
+ createLogger("webhook");
91166
+ createLogger("events");
91167
+ createLogger("adapter");
91168
+ createLogger("build", {
91169
+ debugNamespace: "workflow:build"
91170
+ });
90912
91171
  const NONCE_LENGTH = 12;
90913
91172
  const TAG_LENGTH = 128;
90914
91173
  const KEY_LENGTH = 32;
@@ -90979,7 +91238,7 @@ const encryption = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePr
90979
91238
  encrypt: encrypt$1,
90980
91239
  importKey
90981
91240
  }, Symbol.toStringTag, { value: "Module" }));
90982
- const version$1 = "5.0.0-beta.23";
91241
+ const version$1 = "5.0.0-beta.25";
90983
91242
  const WorldCacheKey = Symbol.for("@workflow/world//cache");
90984
91243
  const WorldCachePromiseKey = Symbol.for("@workflow/world//cachePromise");
90985
91244
  const GetWorldFnKey$1 = Symbol.for("@workflow/world//getWorldFn");
@@ -92593,7 +92852,16 @@ function createReconnectingFramedStream(runId, name2, startIndex) {
92593
92852
  }
92594
92853
  const STREAM_FLUSH_INTERVAL_MS = 10;
92595
92854
  class WorkflowServerWritableStream extends WritableStream {
92596
- constructor(runId, name2) {
92855
+ /**
92856
+ * @param runReadyBarrier Turbo mode only: a promise that resolves once the
92857
+ * backgrounded `run_started` has landed. When the step body runs
92858
+ * optimistically (before `run_started` is durable), the first chunk write to
92859
+ * a brand-new stream would otherwise reach the World before the run exists
92860
+ * and be rejected as run-not-found. Awaiting this once before the first
92861
+ * flush/close orders the write after the run's creation. `undefined` outside
92862
+ * turbo and on the await path, where the run was already durable.
92863
+ */
92864
+ constructor(runId, name2, runReadyBarrier) {
92597
92865
  if (typeof runId !== "string") {
92598
92866
  throw new WorkflowRuntimeError(`"runId" must be a string, got "${typeof runId}"`);
92599
92867
  }
@@ -92601,6 +92869,16 @@ class WorkflowServerWritableStream extends WritableStream {
92601
92869
  throw new WorkflowRuntimeError(`"name" is required, got "${name2}"`);
92602
92870
  }
92603
92871
  const worldPromise = getWorldLazy();
92872
+ let pendingRunReady = runReadyBarrier;
92873
+ const ensureRunReady = async () => {
92874
+ if (pendingRunReady) {
92875
+ try {
92876
+ await pendingRunReady;
92877
+ } catch {
92878
+ }
92879
+ pendingRunReady = void 0;
92880
+ }
92881
+ };
92604
92882
  let buffer2 = [];
92605
92883
  let flushTimer = null;
92606
92884
  let flushPromise = null;
@@ -92612,6 +92890,7 @@ class WorkflowServerWritableStream extends WritableStream {
92612
92890
  }
92613
92891
  if (buffer2.length === 0)
92614
92892
  return;
92893
+ await ensureRunReady();
92615
92894
  const chunksToFlush = buffer2.slice();
92616
92895
  const world = await worldPromise;
92617
92896
  if (resolvedFlushIntervalMs === void 0) {
@@ -92661,6 +92940,7 @@ class WorkflowServerWritableStream extends WritableStream {
92661
92940
  flushPromise = null;
92662
92941
  }
92663
92942
  await flush();
92943
+ await ensureRunReady();
92664
92944
  const world = await worldPromise;
92665
92945
  await world.streams.close(runId, name2);
92666
92946
  },
@@ -92776,7 +93056,7 @@ function attachAbortListenerOnce(signal, streamName, runId, cryptoKey, ops) {
92776
93056
  })());
92777
93057
  }, { once: true });
92778
93058
  }
92779
- function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false) {
93059
+ function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier) {
92780
93060
  return {
92781
93061
  ...getAllBaseReducers(global2),
92782
93062
  ReadableStream: (value) => {
@@ -92790,7 +93070,7 @@ function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framed
92790
93070
  const streamId = (global2[STABLE_ULID] || defaultUlid)();
92791
93071
  const name2 = `strm_${streamId}`;
92792
93072
  const type = getStreamType(value);
92793
- const writable = new WorkflowServerWritableStream(runId, name2);
93073
+ const writable = new WorkflowServerWritableStream(runId, name2, runReadyBarrier);
92794
93074
  if (type === "bytes") {
92795
93075
  if (framedByteStreams) {
92796
93076
  ops.push(value.pipeThrough(getByteFramingStream()).pipeTo(writable));
@@ -92798,7 +93078,7 @@ function getExternalReducers(global2 = globalThis, ops, runId, cryptoKey, framed
92798
93078
  ops.push(value.pipeTo(writable));
92799
93079
  }
92800
93080
  } else {
92801
- ops.push(value.pipeThrough(getSerializeStream(getExternalReducers(global2, ops, runId, cryptoKey, framedByteStreams), cryptoKey)).pipeTo(writable));
93081
+ ops.push(value.pipeThrough(getSerializeStream(getExternalReducers(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier), cryptoKey)).pipeTo(writable));
92802
93082
  }
92803
93083
  const s2 = { name: name2 };
92804
93084
  if (type)
@@ -92908,7 +93188,7 @@ function getWorkflowReducers(global2 = globalThis) {
92908
93188
  }
92909
93189
  };
92910
93190
  }
92911
- function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false) {
93191
+ function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByteStreams = false, runReadyBarrier) {
92912
93192
  return {
92913
93193
  ...getAllBaseReducers(global2),
92914
93194
  ReadableStream: (value) => {
@@ -92927,7 +93207,7 @@ function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByte
92927
93207
  name2 = `strm_${streamId}`;
92928
93208
  type = getStreamType(value);
92929
93209
  framing = type === "bytes" && framedByteStreams ? "framed-v1" : framing;
92930
- const writable = new WorkflowServerWritableStream(runId, name2);
93210
+ const writable = new WorkflowServerWritableStream(runId, name2, runReadyBarrier);
92931
93211
  if (type === "bytes") {
92932
93212
  if (framing === "framed-v1") {
92933
93213
  ops.push(value.pipeThrough(getByteFramingStream()).pipeTo(writable));
@@ -92935,7 +93215,7 @@ function getStepReducers(global2 = globalThis, ops, runId, cryptoKey, framedByte
92935
93215
  ops.push(value.pipeTo(writable));
92936
93216
  }
92937
93217
  } else {
92938
- ops.push(value.pipeThrough(getSerializeStream(getStepReducers(global2, ops, runId, cryptoKey, framedByteStreams), cryptoKey)).pipeTo(writable));
93218
+ ops.push(value.pipeThrough(getSerializeStream(getStepReducers(global2, ops, runId, cryptoKey, framedByteStreams, runReadyBarrier), cryptoKey)).pipeTo(writable));
92939
93219
  }
92940
93220
  }
92941
93221
  const s2 = { name: name2 };
@@ -93541,16 +93821,16 @@ async function hydrateStepArguments(value, runId, key, ops = [], global2 = globa
93541
93821
  await recordCompression(compressionStats, "deserialize");
93542
93822
  return result;
93543
93823
  }
93544
- async function dehydrateStepReturnValue(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false, compression = false) {
93824
+ async function dehydrateStepReturnValue(value, runId, key, ops = [], global2 = globalThis, v1Compat = false, framedByteStreams = false, compression = false, runReadyBarrier) {
93545
93825
  if (v1Compat) {
93546
- const str = stringify$2(value, getStepReducers(global2, ops, runId, key, framedByteStreams));
93826
+ const str = stringify$2(value, getStepReducers(global2, ops, runId, key, framedByteStreams, runReadyBarrier));
93547
93827
  return revive(str);
93548
93828
  }
93549
93829
  try {
93550
93830
  const compressionStats = {};
93551
93831
  const result = await serialize(value, key, {
93552
93832
  global: global2,
93553
- extraReducers: getStreamAndRequestReducers(getStepReducers(global2, ops, runId, key, framedByteStreams)),
93833
+ extraReducers: getStreamAndRequestReducers(getStepReducers(global2, ops, runId, key, framedByteStreams, runReadyBarrier)),
93554
93834
  compression,
93555
93835
  compressionStats
93556
93836
  });
@@ -93909,6 +94189,9 @@ function stripTag(fileId) {
93909
94189
  function hasTag(fileId, tag) {
93910
94190
  return fileId.endsWith(`.${tag}`);
93911
94191
  }
94192
+ function isUntagged(fileId) {
94193
+ return !TAG_PATTERN.test(fileId);
94194
+ }
93912
94195
  function taggedPath(basedir, entityDir, fileId, tag) {
93913
94196
  assertSafeEntityId("fileId", fileId);
93914
94197
  if (tag !== void 0)
@@ -94335,7 +94618,7 @@ async function initDataDir(dataDir) {
94335
94618
  let otelApiPromise$1 = null;
94336
94619
  async function getOtelApi$1() {
94337
94620
  if (!otelApiPromise$1) {
94338
- otelApiPromise$1 = import("./index-meg9qk8y.js").catch(() => null);
94621
+ otelApiPromise$1 = import("./index-Dq5jTBN4.js").catch(() => null);
94339
94622
  }
94340
94623
  return otelApiPromise$1;
94341
94624
  }
@@ -120147,34 +120430,54 @@ function createQueue$2(config2) {
120147
120430
  await semaphore.acquire();
120148
120431
  }
120149
120432
  const MAX_LOCAL_SAFETY_LIMIT = 256;
120433
+ let delivery = 0;
120150
120434
  try {
120151
- for (let attempt = 0; attempt < MAX_LOCAL_SAFETY_LIMIT; attempt++) {
120435
+ for (let loop = 0; loop < MAX_LOCAL_SAFETY_LIMIT; loop++) {
120152
120436
  const headers2 = {
120153
120437
  ...opts == null ? void 0 : opts.headers,
120154
120438
  "content-type": "application/json",
120155
120439
  "x-vqs-queue-name": queueName,
120156
120440
  "x-vqs-message-id": messageId,
120157
- "x-vqs-message-attempt": String(attempt + 1)
120441
+ "x-vqs-message-attempt": String(delivery + 1)
120158
120442
  };
120159
120443
  const directHandler = directHandlers.get(prefix);
120160
120444
  let response2;
120161
- if (directHandler) {
120162
- const req = new Request(`http://localhost/.well-known/workflow/v1/${pathname}`, {
120163
- method: "POST",
120164
- headers: headers2,
120165
- body: body2
120166
- });
120167
- response2 = await directHandler(req);
120168
- } else {
120169
- const baseUrl = await resolveBaseUrl$1(config2);
120170
- response2 = await fetch(`${baseUrl}/.well-known/workflow/v1/${pathname}`, {
120171
- method: "POST",
120172
- duplex: "half",
120173
- dispatcher: httpAgent,
120174
- headers: headers2,
120175
- body: body2
120445
+ try {
120446
+ if (directHandler) {
120447
+ const req = new Request(`http://localhost/.well-known/workflow/v1/${pathname}`, {
120448
+ method: "POST",
120449
+ headers: headers2,
120450
+ body: body2
120451
+ });
120452
+ response2 = await directHandler(req);
120453
+ } else {
120454
+ const baseUrl = await resolveBaseUrl$1(config2);
120455
+ response2 = await fetch(`${baseUrl}/.well-known/workflow/v1/${pathname}`, {
120456
+ method: "POST",
120457
+ duplex: "half",
120458
+ dispatcher: httpAgent,
120459
+ headers: headers2,
120460
+ body: body2
120461
+ });
120462
+ }
120463
+ } catch (err) {
120464
+ const name2 = err == null ? void 0 : err.name;
120465
+ if (closeSignal.aborted || name2 === "AbortError" || name2 === "ResponseAborted") {
120466
+ return;
120467
+ }
120468
+ if (isDetachedArrayBufferQueueError(err))
120469
+ throw err;
120470
+ console.error(`[world-local] Queue delivery failed at the transport (loop ${loop + 1}), retrying`, {
120471
+ queueName,
120472
+ messageId,
120473
+ ...runId && { runId },
120474
+ ...stepId && { stepId },
120475
+ error: String(err)
120176
120476
  });
120477
+ await setTimeout$1(5e3, void 0, { signal: closeSignal });
120478
+ continue;
120177
120479
  }
120480
+ delivery++;
120178
120481
  const text2 = await response2.text();
120179
120482
  if (response2.ok) {
120180
120483
  try {
@@ -120192,7 +120495,7 @@ function createQueue$2(config2) {
120192
120495
  }
120193
120496
  return;
120194
120497
  }
120195
- console.error(`[world-local] Queue message failed (attempt ${attempt + 1}, HTTP ${response2.status})`, {
120498
+ console.error(`[world-local] Queue message failed (attempt ${delivery}, HTTP ${response2.status})`, {
120196
120499
  queueName,
120197
120500
  messageId,
120198
120501
  ...runId && { runId },
@@ -121903,13 +122206,14 @@ function createLocalWorld(args) {
121903
122206
  if (!recoverActiveRuns) {
121904
122207
  return;
121905
122208
  }
121906
- const recoveryRuns = tag ? {
122209
+ const fileIdFilter = tag ? (fileId) => hasTag(fileId, tag) : isUntagged;
122210
+ const recoveryRuns = {
121907
122211
  ...storage.runs,
121908
122212
  list: ((params) => storage.runs.list({
121909
122213
  ...params,
121910
- fileIdFilter: (fileId) => hasTag(fileId, tag)
122214
+ fileIdFilter
121911
122215
  }))
121912
- } : storage.runs;
122216
+ };
121913
122217
  await reenqueueActiveRuns(recoveryRuns, queue.queue, "world-local");
121914
122218
  },
121915
122219
  async close() {
@@ -121920,7 +122224,7 @@ function createLocalWorld(args) {
121920
122224
  const basedir = mergedConfig.dataDir;
121921
122225
  const hooksDir = path$3.join(basedir, "hooks");
121922
122226
  const taggedHookFiles = await listTaggedFiles(hooksDir, tag);
121923
- const { HookSchema: HookSchema2 } = await import("./index-D7poz6vJ.js");
122227
+ const { HookSchema: HookSchema2 } = await import("./index-BELZxbAO.js");
121924
122228
  await Promise.all(taggedHookFiles.map(async (hookFile) => {
121925
122229
  const hook = await readJSON(path$3.join(hooksDir, hookFile), HookSchema2);
121926
122230
  if (hook == null ? void 0 : hook.token) {
@@ -122073,8 +122377,8 @@ function requireGetVercelOidcToken() {
122073
122377
  }
122074
122378
  try {
122075
122379
  const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([
122076
- await import("./token-util-M95T0pVo.js").then((n) => n.t),
122077
- await import("./token-BCYgRbLT.js").then((n) => n.t)
122380
+ await import("./token-util-CCeU4-vR.js").then((n) => n.t),
122381
+ await import("./token-guLCf66r.js").then((n) => n.t)
122078
122382
  ]);
122079
122383
  if (!token || isExpired(getTokenPayload(token), options == null ? void 0 : options.expirationBufferMs)) {
122080
122384
  await refreshToken(options);
@@ -122638,32 +122942,63 @@ function requireDist() {
122638
122942
  }
122639
122943
  var distExports = requireDist();
122640
122944
  let _dispatcher;
122945
+ let _eventsDispatcher;
122946
+ let _streamDispatcher;
122947
+ const BASE_AGENT_OPTIONS = {
122948
+ connections: 8,
122949
+ keepAliveTimeout: 1e4,
122950
+ // HTTP/1.1 pipelining is disabled (pipelining: 1) because it causes
122951
+ // head-of-line blocking that deadlocks the webhook respondWith mechanism.
122952
+ pipelining: 1
122953
+ };
122954
+ const DEFAULT_AGENT_OPTIONS = {
122955
+ ...BASE_AGENT_OPTIONS,
122956
+ allowH2: false
122957
+ };
122958
+ const EVENTS_AGENT_OPTIONS = {
122959
+ ...BASE_AGENT_OPTIONS,
122960
+ allowH2: true
122961
+ };
122962
+ const RETRY_AGENT_OPTIONS = {
122963
+ // Observe Retry-After header if received
122964
+ retryAfter: true
122965
+ // By default, we observe re-try headers, and also separately
122966
+ // re-try on these status codes: 429 / 500 / 502 / 503 / 504.
122967
+ // TODO: We might want to let 429s pass through, so that we can do
122968
+ // runtime retry-after handling through the queue.
122969
+ };
122970
+ const STREAM_RETRY_OPTIONS = {
122971
+ retryAfter: true,
122972
+ methods: ["PUT"],
122973
+ statusCodes: [429]
122974
+ };
122641
122975
  function getDispatcher(config2) {
122642
122976
  return (config2 == null ? void 0 : config2.dispatcher) ?? getDefaultDispatcher();
122643
122977
  }
122978
+ function getEventsDispatcher(config2) {
122979
+ return (config2 == null ? void 0 : config2.dispatcher) ?? getDefaultEventsDispatcher();
122980
+ }
122981
+ function getStreamDispatcher(config2) {
122982
+ return (config2 == null ? void 0 : config2.dispatcher) ?? getDefaultStreamDispatcher();
122983
+ }
122644
122984
  function getDefaultDispatcher() {
122645
122985
  if (!_dispatcher) {
122646
- _dispatcher = new undiciExports.RetryAgent(new undiciExports.Agent({
122647
- connections: 8,
122648
- keepAliveTimeout: 1e4,
122649
- // H2 is specifically incompatible with SvelteKit on Vercel prod. Everything else
122650
- // runs fine.
122651
- // TODO: Investigate/fix the failure on SvelteKit so we can re-enable H2.
122652
- allowH2: false,
122653
- // HTTP/1.1 pipelining is disabled (pipelining: 1) because it causes
122654
- // head-of-line blocking that deadlocks the webhook respondWith mechanism.
122655
- pipelining: 1
122656
- }), {
122657
- // Observe Retry-After header if received
122658
- retryAfter: true
122659
- // By default, we observe re-try headers, and also separately
122660
- // re-try on these status codes: 429 / 500 / 502 / 503 / 504.
122661
- // TODO: We might want to let 429s pass through, so that we can do
122662
- // runtime retry-after handling through the queue.
122663
- });
122986
+ _dispatcher = new undiciExports.RetryAgent(new undiciExports.Agent(DEFAULT_AGENT_OPTIONS), RETRY_AGENT_OPTIONS);
122664
122987
  }
122665
122988
  return _dispatcher;
122666
122989
  }
122990
+ function getDefaultEventsDispatcher() {
122991
+ if (!_eventsDispatcher) {
122992
+ _eventsDispatcher = new undiciExports.RetryAgent(new undiciExports.Agent(EVENTS_AGENT_OPTIONS), RETRY_AGENT_OPTIONS);
122993
+ }
122994
+ return _eventsDispatcher;
122995
+ }
122996
+ function getDefaultStreamDispatcher() {
122997
+ if (!_streamDispatcher) {
122998
+ _streamDispatcher = new undiciExports.RetryAgent(new undiciExports.Agent(EVENTS_AGENT_OPTIONS), STREAM_RETRY_OPTIONS);
122999
+ }
123000
+ return _streamDispatcher;
123001
+ }
122667
123002
  const KEY_BYTES = 32;
122668
123003
  async function deriveRunKey(deploymentKey, projectId, runId) {
122669
123004
  if (deploymentKey.length !== KEY_BYTES) {
@@ -122760,7 +123095,7 @@ function createGetEncryptionKeyForRun(projectId, teamId, token, dispatcher2) {
122760
123095
  let otelApiPromise = null;
122761
123096
  async function getOtelApi() {
122762
123097
  if (!otelApiPromise) {
122763
- otelApiPromise = import("./index-meg9qk8y.js").catch(() => null);
123098
+ otelApiPromise = import("./index-Dq5jTBN4.js").catch(() => null);
122764
123099
  }
122765
123100
  return otelApiPromise;
122766
123101
  }
@@ -127423,7 +127758,7 @@ var QueueClient = class {
127423
127758
  setApi(this, new ApiClient({ ...options, region }));
127424
127759
  }
127425
127760
  };
127426
- const version = "5.0.0-beta.20";
127761
+ const version = "5.0.0-beta.21";
127427
127762
  const HTTP_DEBUG_ENABLED = typeof process !== "undefined" && typeof process.env.DEBUG === "string" && (process.env.DEBUG.includes("workflow:") || process.env.DEBUG === "*");
127428
127763
  function httpLog(method, endpoint, response2, ms2) {
127429
127764
  if (HTTP_DEBUG_ENABLED) {
@@ -128007,7 +128342,7 @@ async function fetchV4(url2, init2, config2) {
128007
128342
  headers: init2.headers,
128008
128343
  body: init2.body,
128009
128344
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- undici dispatcher type doesn't match @types/node's RequestInit
128010
- dispatcher: getDispatcher(config2)
128345
+ dispatcher: getEventsDispatcher(config2)
128011
128346
  });
128012
128347
  }
128013
128348
  function headersToRecord(headers2) {
@@ -128840,7 +129175,9 @@ function createStreamer(config2) {
128840
129175
  const response2 = await fetch(url2, {
128841
129176
  method: "PUT",
128842
129177
  body: chunk,
128843
- headers: httpConfig.headers
129178
+ headers: httpConfig.headers,
129179
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- undici dispatcher type doesn't match @types/node's RequestInit
129180
+ dispatcher: getStreamDispatcher(config2)
128844
129181
  });
128845
129182
  const text2 = await response2.text();
128846
129183
  if (!response2.ok) {
@@ -128860,7 +129197,9 @@ function createStreamer(config2) {
128860
129197
  const response2 = await fetch(url2, {
128861
129198
  method: "PUT",
128862
129199
  body: body2,
128863
- headers: httpConfig.headers
129200
+ headers: httpConfig.headers,
129201
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- undici dispatcher type doesn't match @types/node's RequestInit
129202
+ dispatcher: getStreamDispatcher(config2)
128864
129203
  });
128865
129204
  const text2 = await response2.text();
128866
129205
  if (!response2.ok) {
@@ -128875,7 +129214,9 @@ function createStreamer(config2) {
128875
129214
  const url2 = getStreamUrl(name2, resolvedRunId, httpConfig);
128876
129215
  const response2 = await fetch(url2, {
128877
129216
  method: "PUT",
128878
- headers: httpConfig.headers
129217
+ headers: httpConfig.headers,
129218
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- undici dispatcher type doesn't match @types/node's RequestInit
129219
+ dispatcher: getStreamDispatcher(config2)
128879
129220
  });
128880
129221
  const text2 = await response2.text();
128881
129222
  if (!response2.ok) {
@@ -129045,7 +129386,7 @@ const getWorld = async () => {
129045
129386
  const GetWorldFnKey = Symbol.for("@workflow/world//getWorldFn");
129046
129387
  globalThis[GetWorldFnKey] ?? (globalThis[GetWorldFnKey] = getWorld);
129047
129388
  function waitUntil(promise2) {
129048
- void import("./index-B8YoYr9f.js").then((n) => n.i).then(({ waitUntil: waitUntil2 }) => {
129389
+ void import("./index-DIXsjgfZ.js").then((n) => n.i).then(({ waitUntil: waitUntil2 }) => {
129049
129390
  waitUntil2(promise2);
129050
129391
  });
129051
129392
  }
@@ -137374,130 +137715,48 @@ async function fetchResourceWithCorrelationId(env2, resource, resourceId, option
137374
137715
  }
137375
137716
  return { data: resourceData, correlationId };
137376
137717
  }
137377
- function useWorkflowResourceData(env2, resource, resourceId, options = {}) {
137378
- const { refreshInterval = 0, runId, enabled = true, encryptionKey } = options;
137379
- const [data, setData] = reactExports.useState(
137380
- null
137381
- );
137382
- const [loading, setLoading] = reactExports.useState(enabled);
137383
- const [error2, setError] = reactExports.useState(null);
137384
- const hydrate = reactExports.useCallback(
137385
- async (resource2) => encryptionKey ? hydrateResourceIOWithKey(resource2, encryptionKey) : hydrateResourceIO(resource2),
137386
- [encryptionKey]
137387
- );
137388
- const prevSelectionRef = reactExports.useRef("");
137389
- const fetchData = reactExports.useCallback(async () => {
137390
- if (!enabled) {
137391
- setLoading(false);
137392
- return;
137393
- }
137394
- const selectionKey = `${resource}:${resourceId}`;
137395
- if (selectionKey !== prevSelectionRef.current) {
137396
- setData(null);
137397
- prevSelectionRef.current = selectionKey;
137398
- }
137399
- setError(null);
137400
- setLoading(true);
137401
- if (resource === "hook") {
137402
- try {
137403
- const { error: error22, result } = await unwrapServerActionResult(
137404
- fetchHook$1(env2, resourceId, "all")
137405
- );
137406
- if (error22) {
137407
- setError(error22);
137408
- return;
137409
- }
137410
- try {
137411
- setData(await hydrate(result));
137412
- } catch (hydrateError) {
137413
- setError(
137414
- hydrateError instanceof Error ? hydrateError : new Error(String(hydrateError))
137415
- );
137416
- }
137417
- } finally {
137418
- setLoading(false);
137419
- }
137420
- return;
137421
- }
137422
- if (resource === "sleep") {
137423
- try {
137424
- if (!runId) {
137425
- setError(new Error("runId is required for loading sleep details"));
137426
- return;
137427
- }
137428
- const { error: error22, result } = await unwrapServerActionResult(
137429
- fetchEvents$1(env2, runId, {
137430
- sortOrder: "asc",
137431
- limit: 1e3,
137432
- withData: true
137433
- })
137434
- );
137435
- if (error22) {
137436
- setError(error22);
137437
- return;
137438
- }
137439
- try {
137440
- const allEvents = result.data.map(
137441
- hydrateResourceIO
137442
- );
137443
- const waitEvents = await Promise.all(
137444
- allEvents.filter((e) => e.correlationId === resourceId).map(hydrate)
137445
- );
137446
- const data2 = waitEventsToWaitEntity(waitEvents);
137447
- if (data2 === null) {
137448
- setError(
137449
- new Error(
137450
- `Failed to load ${resource} details: missing required event data`
137451
- )
137452
- );
137453
- return;
137454
- }
137455
- setData(data2);
137456
- } catch (hydrateError) {
137457
- setError(
137458
- hydrateError instanceof Error ? hydrateError : new Error(String(hydrateError))
137459
- );
137460
- }
137461
- } finally {
137462
- setLoading(false);
137463
- }
137464
- return;
137718
+ async function fetchSpanDetailResource(env2, selection2, options = {}) {
137719
+ const { resource, resourceId, runId } = selection2;
137720
+ const { encryptionKey } = options;
137721
+ const hydrate = async (value) => encryptionKey ? hydrateResourceIOWithKey(value, encryptionKey) : hydrateResourceIO(value);
137722
+ if (resource === "hook") {
137723
+ const result = await unwrapOrThrow(fetchHook$1(env2, resourceId, "all"));
137724
+ return hydrate(result);
137725
+ }
137726
+ if (resource === "sleep") {
137727
+ if (!runId) {
137728
+ throw new WorkflowWebAPIError(
137729
+ "runId is required for loading sleep details",
137730
+ { layer: "client" }
137731
+ );
137465
137732
  }
137466
- try {
137467
- const { data: resourceData } = await fetchResourceWithCorrelationId(
137468
- env2,
137469
- resource,
137470
- resourceId,
137471
- { runId }
137733
+ const result = await unwrapOrThrow(
137734
+ fetchEvents$1(env2, runId, { sortOrder: "asc", limit: 1e3, withData: true })
137735
+ );
137736
+ const allEvents = result.data.map(
137737
+ hydrateResourceIO
137738
+ );
137739
+ const waitEvents = await Promise.all(
137740
+ allEvents.filter((e) => e.correlationId === resourceId).map(hydrate)
137741
+ );
137742
+ const data2 = waitEventsToWaitEntity(waitEvents);
137743
+ if (data2 === null) {
137744
+ throw new WorkflowWebAPIError(
137745
+ `Failed to load ${resource} details: missing required event data`,
137746
+ { layer: "client" }
137472
137747
  );
137473
- setData(await hydrate(resourceData));
137474
- } catch (error22) {
137475
- if (error22 instanceof Error) {
137476
- setError(error22);
137477
- } else {
137478
- setError(new Error(String(error22)));
137479
- }
137480
- return;
137481
- } finally {
137482
- setLoading(false);
137483
137748
  }
137484
- }, [env2, resource, resourceId, runId, enabled, hydrate]);
137485
- reactExports.useEffect(() => {
137486
- fetchData();
137487
- }, [fetchData]);
137488
- reactExports.useEffect(() => {
137489
- if (!refreshInterval || refreshInterval <= 0) {
137490
- return;
137749
+ return data2;
137750
+ }
137751
+ const { data } = await fetchResourceWithCorrelationId(
137752
+ env2,
137753
+ resource,
137754
+ resourceId,
137755
+ {
137756
+ runId
137491
137757
  }
137492
- const interval2 = setInterval(fetchData, refreshInterval);
137493
- return () => clearInterval(interval2);
137494
- }, [refreshInterval, fetchData]);
137495
- return {
137496
- data,
137497
- loading,
137498
- error: error2,
137499
- refresh: fetchData
137500
- };
137758
+ );
137759
+ return hydrate(data);
137501
137760
  }
137502
137761
  function mergeById(prev, next2, idKey) {
137503
137762
  const combined = [...prev, ...next2];
@@ -153539,30 +153798,15 @@ function RunDetailView({
153539
153798
  encryptionKey: encryptionKey ?? void 0,
153540
153799
  enabled: activeTab === "events"
153541
153800
  });
153542
- const [spanSelection, setSpanSelection] = reactExports.useState(
153543
- null
153544
- );
153545
- const {
153546
- data: spanDetailData,
153547
- loading: spanDetailLoading,
153548
- error: spanDetailError,
153549
- refresh: refreshSpanDetail
153550
- } = useWorkflowResourceData(
153551
- env2,
153552
- (spanSelection == null ? void 0 : spanSelection.resource) ?? "run",
153553
- (spanSelection == null ? void 0 : spanSelection.resourceId) ?? "",
153554
- {
153555
- runId: spanSelection == null ? void 0 : spanSelection.runId,
153556
- enabled: Boolean(
153557
- (spanSelection == null ? void 0 : spanSelection.resource) && (spanSelection == null ? void 0 : spanSelection.resourceId) && spanSelection.resource !== "hook"
153558
- ),
153801
+ const fetchSpanDetail = reactExports.useCallback(
153802
+ (selection2) => fetchSpanDetailResource(env2, selection2, {
153559
153803
  encryptionKey: encryptionKey ?? void 0
153560
- }
153804
+ }),
153805
+ [env2, encryptionKey]
153561
153806
  );
153562
153807
  const [isDecrypting, setIsDecrypting] = reactExports.useState(false);
153563
153808
  const handleDecrypt = reactExports.useCallback(async () => {
153564
153809
  if (encryptionKey) {
153565
- refreshSpanDetail();
153566
153810
  return;
153567
153811
  }
153568
153812
  setIsDecrypting(true);
@@ -153580,18 +153824,12 @@ function RunDetailView({
153580
153824
  } finally {
153581
153825
  setIsDecrypting(false);
153582
153826
  }
153583
- }, [encryptionKey, env2, runId, refreshSpanDetail]);
153584
- const handleSpanSelect = reactExports.useCallback((info) => {
153585
- setSpanSelection(info);
153586
- }, []);
153827
+ }, [encryptionKey, env2, runId]);
153587
153828
  const sidebarData = reactExports.useMemo(
153588
153829
  () => ({
153589
153830
  run: run2,
153590
153831
  events: allEvents ?? [],
153591
- spanDetailData: spanDetailData ?? null,
153592
- spanDetailError,
153593
- spanDetailLoading,
153594
- onSpanSelect: handleSpanSelect,
153832
+ fetchSpanDetail,
153595
153833
  onStreamClick: handleStreamClick,
153596
153834
  onRunClick: handleRunRefClick,
153597
153835
  onWakeUpSleep: handleWakeUpSleep,
@@ -153605,10 +153843,7 @@ function RunDetailView({
153605
153843
  [
153606
153844
  run2,
153607
153845
  allEvents,
153608
- spanDetailData,
153609
- spanDetailError,
153610
- spanDetailLoading,
153611
- handleSpanSelect,
153846
+ fetchSpanDetail,
153612
153847
  handleStreamClick,
153613
153848
  handleRunRefClick,
153614
153849
  handleWakeUpSleep,
@@ -154134,7 +154369,7 @@ const route4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProper
154134
154369
  __proto__: null,
154135
154370
  loader
154136
154371
  }, Symbol.toStringTag, { value: "Module" }));
154137
- const serverManifest = { "entry": { "module": "/assets/entry.client-DOJDY_4b.js", "imports": ["/assets/index-BXZSIDEp.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-BlFmfRST.js", "imports": ["/assets/index-BXZSIDEp.js", "/assets/mermaid-3ZIDBTTL-C_xy8SxZ.js"], "css": ["/assets/root-61NXpLSs.css", "/assets/mermaid-3ZIDBTTL-DDxQhcP4.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-Dz43xne_.js", "imports": ["/assets/index-BXZSIDEp.js", "/assets/workflow-graph-viewer-BlDVZ5AU.js", "/assets/mermaid-3ZIDBTTL-C_xy8SxZ.js", "/assets/index-B6-SzLmT.js"], "css": ["/assets/workflow-graph-viewer-DnlNuQQH.css", "/assets/mermaid-3ZIDBTTL-DDxQhcP4.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-C34zz02I.js", "imports": ["/assets/index-BXZSIDEp.js", "/assets/workflow-graph-viewer-BlDVZ5AU.js", "/assets/mermaid-3ZIDBTTL-C_xy8SxZ.js", "/assets/encryption-g14N5vQl.js", "/assets/index-B6-SzLmT.js"], "css": ["/assets/run-detail-CWoGxu_0.css", "/assets/workflow-graph-viewer-DnlNuQQH.css", "/assets/mermaid-3ZIDBTTL-DDxQhcP4.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-608c3c54.js", "version": "608c3c54", "sri": void 0 };
154372
+ const serverManifest = { "entry": { "module": "/assets/entry.client-DOJDY_4b.js", "imports": ["/assets/index-BXZSIDEp.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-BsPxYsbK.js", "imports": ["/assets/index-BXZSIDEp.js", "/assets/mermaid-3ZIDBTTL-Cg-Mp5Kj.js"], "css": ["/assets/root-F_dqJDC7.css", "/assets/mermaid-3ZIDBTTL-DDxQhcP4.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-BNApVOct.js", "imports": ["/assets/index-BXZSIDEp.js", "/assets/workflow-graph-viewer-CcCwLmnF.js", "/assets/mermaid-3ZIDBTTL-Cg-Mp5Kj.js", "/assets/index-B6-SzLmT.js"], "css": ["/assets/workflow-graph-viewer-DnlNuQQH.css", "/assets/mermaid-3ZIDBTTL-DDxQhcP4.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-sr7StYc6.js", "imports": ["/assets/index-BXZSIDEp.js", "/assets/workflow-graph-viewer-CcCwLmnF.js", "/assets/mermaid-3ZIDBTTL-Cg-Mp5Kj.js", "/assets/encryption-g14N5vQl.js", "/assets/index-B6-SzLmT.js"], "css": ["/assets/run-detail-CWoGxu_0.css", "/assets/workflow-graph-viewer-DnlNuQQH.css", "/assets/mermaid-3ZIDBTTL-DDxQhcP4.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-379f050f.js", "version": "379f050f", "sri": void 0 };
154138
154373
  const assetsBuildDirectory = "build/client";
154139
154374
  const basename = "/";
154140
154375
  const future = { "unstable_optimizeDeps": false, "unstable_subResourceIntegrity": false, "unstable_trailingSlashAwareDataRequests": false, "unstable_previewServerPrerendering": false, "v8_middleware": false, "v8_splitRouteModules": false, "v8_viteEnvironmentApi": false };