@workflow/web 5.0.0-beta.2 → 5.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. package/build/client/assets/{highlighted-body-B3W2YXNL-DPWdt39H.js → highlighted-body-B3W2YXNL-Be0uLJd8.js} +1 -1
  2. package/build/client/assets/{home-OcN-ARTU.js → home-Ce97yLJ7.js} +16 -8
  3. package/build/client/assets/{manifest-62352cd9.js → manifest-923d96a0.js} +1 -1
  4. package/build/client/assets/{mermaid-3ZIDBTTL-B9v3aKRl.js → mermaid-3ZIDBTTL-BSJR0c5A.js} +712 -736
  5. package/build/client/assets/root-DXDFWibD.css +1 -0
  6. package/build/client/assets/{root-ClRrWHkX.js → root-DdOfCnSG.js} +1 -1
  7. package/build/client/assets/{run-detail-BdYMODbi.js → run-detail-JQ32aJru.js} +1737 -3257
  8. package/build/client/assets/server-build-pZ5ucXET.css +1 -0
  9. package/build/client/assets/{workflow-graph-viewer-BdFIMYrh.js → workflow-graph-viewer-DYhMo9jl.js} +42 -51
  10. package/build/client/assets/{workflow-graph-viewer-yls6qlc0.css → workflow-graph-viewer-DnlNuQQH.css} +1 -1
  11. package/build/server/assets/{app-coxrYAYu.js → app-Bh_7yjpl.js} +1 -1
  12. package/build/server/assets/{highlighted-body-B3W2YXNL-DhGWas67.js → highlighted-body-B3W2YXNL-Cdb-ypB4.js} +3 -3
  13. package/build/server/assets/{index-DJ8Yt9MV.js → index-CNvEtg5c.js} +4 -4
  14. package/build/server/assets/{mermaid-3ZIDBTTL-DJkW_cc4.js → mermaid-3ZIDBTTL-CE8Volk5.js} +3 -3
  15. package/build/server/assets/{server-build-dCNkWo2d.js → server-build-DztRAoMd.js} +2191 -3649
  16. package/build/server/assets/{token-Bi1ru9oe.js → token-DMEdoEUo.js} +2 -2
  17. package/build/server/assets/{token-util-Bwj_Mj31.js → token-util-DsMisyo3.js} +2 -2
  18. package/build/server/index.js +1 -1
  19. package/package.json +5 -5
  20. package/build/client/assets/root-BrnNveEi.css +0 -1
  21. package/build/client/assets/server-build-DKWv59Tp.css +0 -1
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/highlighted-body-B3W2YXNL-DPWdt39H.js","assets/index-DQa-BExo.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/highlighted-body-B3W2YXNL-Be0uLJd8.js","assets/index-DQa-BExo.js"])))=>i.map(i=>d[i]);
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -6695,7 +6695,8 @@ const Lock = createLucideIcon("lock", __iconNode);
6695
6695
  function cn$4(...inputs) {
6696
6696
  return twMerge(clsx(inputs));
6697
6697
  }
6698
- const durationFormatter = new Intl.NumberFormat(void 0, {
6698
+ const secondsFormatter = new Intl.NumberFormat(void 0, {
6699
+ minimumFractionDigits: 2,
6699
6700
  maximumFractionDigits: 2
6700
6701
  });
6701
6702
  const MS_IN_SECOND = 1e3;
@@ -6704,13 +6705,10 @@ const MS_IN_HOUR = 60 * MS_IN_MINUTE;
6704
6705
  const MS_IN_DAY = 24 * MS_IN_HOUR;
6705
6706
  function formatDuration(ms, compact = false) {
6706
6707
  if (ms === 0) {
6707
- return "0";
6708
- }
6709
- if (ms < MS_IN_SECOND) {
6710
- return `${durationFormatter.format(ms)}ms`;
6708
+ return "0s";
6711
6709
  }
6712
6710
  if (ms < MS_IN_MINUTE) {
6713
- return `${durationFormatter.format(ms / MS_IN_SECOND)}s`;
6711
+ return `${secondsFormatter.format(ms / MS_IN_SECOND)}s`;
6714
6712
  }
6715
6713
  if (compact) {
6716
6714
  if (ms < MS_IN_HOUR) {
@@ -6725,7 +6723,7 @@ function formatDuration(ms, compact = false) {
6725
6723
  const days = Math.floor(ms / MS_IN_DAY);
6726
6724
  const hours = Math.floor(ms % MS_IN_DAY / MS_IN_HOUR);
6727
6725
  const minutes = Math.floor(ms % MS_IN_HOUR / MS_IN_MINUTE);
6728
- const seconds = Math.floor(ms % MS_IN_MINUTE / MS_IN_SECOND);
6726
+ const seconds = ms % MS_IN_MINUTE / MS_IN_SECOND;
6729
6727
  const parts = [];
6730
6728
  if (days > 0) {
6731
6729
  parts.push(`${days}d`);
@@ -6736,9 +6734,7 @@ function formatDuration(ms, compact = false) {
6736
6734
  if (minutes > 0) {
6737
6735
  parts.push(`${minutes}m`);
6738
6736
  }
6739
- if (hours <= 1 && (seconds > 0 || parts.length === 0)) {
6740
- parts.push(`${seconds}s`);
6741
- }
6737
+ parts.push(`${secondsFormatter.format(seconds)}s`);
6742
6738
  return parts.join(" ");
6743
6739
  }
6744
6740
  function isDoStreamStep(stepName) {
@@ -16707,13 +16703,33 @@ const useDarkMode = () => {
16707
16703
  }, []);
16708
16704
  return isDark;
16709
16705
  };
16706
+ function summarizeArrayBufferView(value) {
16707
+ const ta = value;
16708
+ const name2 = ta.constructor.name;
16709
+ const preview = Array.from({ length: Math.min(ta.length, 8) }, (_2, i) => ta[i]);
16710
+ const suffix = ta.length > 8 ? ", …" : "";
16711
+ return `${name2}(${ta.length}) [${preview.join(", ")}${suffix}]`;
16712
+ }
16713
+ function formatArrayBufferViewForDisplay(value) {
16714
+ try {
16715
+ const text2 = new TextDecoder("utf-8", { fatal: true }).decode(value);
16716
+ return {
16717
+ text: text2,
16718
+ decodedFrom: {
16719
+ type: value.constructor.name,
16720
+ encoding: "utf-8",
16721
+ rawSummary: summarizeArrayBufferView(value)
16722
+ }
16723
+ };
16724
+ } catch {
16725
+ return { text: summarizeArrayBufferView(value) };
16726
+ }
16727
+ }
16710
16728
  const inspectorThemeExtendedLight = {
16711
- OBJECT_VALUE_DATE_COLOR: "#a21caf"
16712
- // fuchsia-700
16729
+ OBJECT_VALUE_DATE_COLOR: "var(--ds-pink-900)"
16713
16730
  };
16714
16731
  const inspectorThemeExtendedDark = {
16715
- OBJECT_VALUE_DATE_COLOR: "#e879f9"
16716
- // fuchsia-400
16732
+ OBJECT_VALUE_DATE_COLOR: "var(--ds-pink-900)"
16717
16733
  };
16718
16734
  const shared = {
16719
16735
  BASE_FONT_SIZE: "11px",
@@ -16731,85 +16747,64 @@ const shared = {
16731
16747
  TABLE_DATA_BACKGROUND_IMAGE: "none",
16732
16748
  TABLE_DATA_BACKGROUND_SIZE: "0"
16733
16749
  };
16734
- const inspectorThemeLight = {
16750
+ const geistTheme = {
16735
16751
  ...shared,
16736
16752
  // Base text
16737
16753
  BASE_COLOR: "var(--ds-gray-1000)",
16738
- // Property names — unstyled, same as base foreground (Node: no style)
16739
- OBJECT_NAME_COLOR: "var(--ds-gray-900)",
16740
- // Strings & symbols — green (Node: 'green')
16741
- OBJECT_VALUE_STRING_COLOR: "#16a34a",
16742
- // green-600
16743
- OBJECT_VALUE_SYMBOL_COLOR: "#16a34a",
16744
- // Numbers & booleans — yellow/amber (Node: 'yellow')
16745
- OBJECT_VALUE_NUMBER_COLOR: "#b45309",
16746
- // amber-700 (readable on white)
16747
- OBJECT_VALUE_BOOLEAN_COLOR: "#b45309",
16748
- // null — bold foreground (Node: 'bold')
16754
+ // Property names — default foreground (matches JSON key color in Geist Shiki)
16755
+ OBJECT_NAME_COLOR: "var(--ds-gray-1000)",
16756
+ // Strings & symbols — green
16757
+ OBJECT_VALUE_STRING_COLOR: "var(--ds-green-900)",
16758
+ OBJECT_VALUE_SYMBOL_COLOR: "var(--ds-green-900)",
16759
+ // Numbers & booleans — green (Geist JSON tokens)
16760
+ OBJECT_VALUE_NUMBER_COLOR: "var(--ds-green-900)",
16761
+ OBJECT_VALUE_BOOLEAN_COLOR: "var(--ds-green-900)",
16762
+ // null muted foreground
16749
16763
  OBJECT_VALUE_NULL_COLOR: "var(--ds-gray-900)",
16750
- // undefined — grey (Node: 'grey')
16751
- OBJECT_VALUE_UNDEFINED_COLOR: "var(--ds-gray-500)",
16752
- // RegExp — red (Node regexp base uses green/red/yellow palette)
16753
- OBJECT_VALUE_REGEXP_COLOR: "#dc2626",
16754
- // red-600
16755
- // Functions — cyan (Node: 'special' → 'cyan')
16756
- OBJECT_VALUE_FUNCTION_PREFIX_COLOR: "#0891b2",
16757
- // cyan-600
16758
- // HTML (less relevant for data inspection, but reasonable defaults)
16759
- HTML_TAG_COLOR: "var(--ds-gray-500)",
16760
- HTML_TAGNAME_COLOR: "#0891b2",
16761
- HTML_ATTRIBUTE_NAME_COLOR: "#b45309",
16762
- HTML_ATTRIBUTE_VALUE_COLOR: "#16a34a",
16763
- HTML_COMMENT_COLOR: "var(--ds-gray-400)",
16764
- HTML_DOCTYPE_COLOR: "var(--ds-gray-400)",
16764
+ // undefined — muted foreground
16765
+ OBJECT_VALUE_UNDEFINED_COLOR: "var(--ds-gray-900)",
16766
+ // RegExp — purple
16767
+ OBJECT_VALUE_REGEXP_COLOR: "var(--ds-purple-900)",
16768
+ // Functions — purple
16769
+ OBJECT_VALUE_FUNCTION_PREFIX_COLOR: "var(--ds-purple-900)",
16770
+ // HTML (rarely used here, kept consistent with the palette)
16771
+ HTML_TAG_COLOR: "var(--ds-gray-900)",
16772
+ HTML_TAGNAME_COLOR: "var(--ds-blue-900)",
16773
+ HTML_ATTRIBUTE_NAME_COLOR: "var(--ds-amber-900)",
16774
+ HTML_ATTRIBUTE_VALUE_COLOR: "var(--ds-green-900)",
16775
+ HTML_COMMENT_COLOR: "var(--ds-gray-700)",
16776
+ HTML_DOCTYPE_COLOR: "var(--ds-gray-700)",
16765
16777
  // Structural
16766
- ARROW_COLOR: "var(--ds-gray-500)",
16778
+ ARROW_COLOR: "var(--ds-gray-700)",
16767
16779
  TABLE_BORDER_COLOR: "var(--ds-gray-300)",
16768
16780
  TABLE_TH_BACKGROUND_COLOR: "var(--ds-gray-100)",
16769
16781
  TABLE_TH_HOVER_COLOR: "var(--ds-gray-200)",
16770
- TABLE_SORT_ICON_COLOR: "var(--ds-gray-500)"
16771
- };
16772
- const inspectorThemeDark = {
16773
- ...shared,
16774
- // Base text
16775
- BASE_COLOR: "var(--ds-gray-1000)",
16776
- // Property names — white/light foreground (Node: unstyled = white in dark terminal)
16777
- OBJECT_NAME_COLOR: "var(--ds-gray-900)",
16778
- // Strings & symbols — green (Node: 'green')
16779
- OBJECT_VALUE_STRING_COLOR: "#4ade80",
16780
- // green-400
16781
- OBJECT_VALUE_SYMBOL_COLOR: "#4ade80",
16782
- // Numbers & booleans — yellow (Node: 'yellow')
16783
- OBJECT_VALUE_NUMBER_COLOR: "#facc15",
16784
- // yellow-400
16785
- OBJECT_VALUE_BOOLEAN_COLOR: "#facc15",
16786
- // null — bold foreground / white (Node: 'bold')
16787
- OBJECT_VALUE_NULL_COLOR: "var(--ds-gray-1000)",
16788
- // undefined — grey (Node: 'grey')
16789
- OBJECT_VALUE_UNDEFINED_COLOR: "var(--ds-gray-500)",
16790
- // RegExp — red (Node regexp palette)
16791
- OBJECT_VALUE_REGEXP_COLOR: "#f87171",
16792
- // red-400
16793
- // Functions — cyan (Node: 'special' → 'cyan')
16794
- OBJECT_VALUE_FUNCTION_PREFIX_COLOR: "#22d3ee",
16795
- // cyan-400
16796
- // HTML
16797
- HTML_TAG_COLOR: "var(--ds-gray-500)",
16798
- HTML_TAGNAME_COLOR: "#22d3ee",
16799
- HTML_ATTRIBUTE_NAME_COLOR: "#facc15",
16800
- HTML_ATTRIBUTE_VALUE_COLOR: "#4ade80",
16801
- HTML_COMMENT_COLOR: "var(--ds-gray-500)",
16802
- HTML_DOCTYPE_COLOR: "var(--ds-gray-500)",
16803
- // Structural
16804
- ARROW_COLOR: "var(--ds-gray-500)",
16805
- TABLE_BORDER_COLOR: "var(--ds-gray-300)",
16806
- TABLE_TH_BACKGROUND_COLOR: "var(--ds-gray-100)",
16807
- TABLE_TH_HOVER_COLOR: "var(--ds-gray-200)",
16808
- TABLE_SORT_ICON_COLOR: "var(--ds-gray-500)"
16782
+ TABLE_SORT_ICON_COLOR: "var(--ds-gray-700)"
16809
16783
  };
16784
+ const inspectorThemeLight = geistTheme;
16785
+ const inspectorThemeDark = geistTheme;
16810
16786
  const STREAM_REF_TYPE = "__workflow_stream_ref__";
16811
16787
  const CLASS_INSTANCE_REF_TYPE = "__workflow_class_instance_ref__";
16812
16788
  const RUN_REF_TYPE = "__workflow_run_ref__";
16789
+ const BYTES_DISPLAY_TYPE = "__workflow_bytes_display__";
16790
+ function deserializeChunkText(text2) {
16791
+ try {
16792
+ const parsed = JSON.parse(text2);
16793
+ if (typeof parsed === "string") {
16794
+ return parsed;
16795
+ }
16796
+ return JSON.stringify(parsed, null, 2);
16797
+ } catch {
16798
+ return text2;
16799
+ }
16800
+ }
16801
+ function parseChunkData(text2) {
16802
+ try {
16803
+ return JSON.parse(text2);
16804
+ } catch {
16805
+ return text2;
16806
+ }
16807
+ }
16813
16808
  function isStreamRef(value) {
16814
16809
  if (value === null || typeof value !== "object")
16815
16810
  return false;
@@ -16822,6 +16817,12 @@ function isRunRef(value) {
16822
16817
  const desc = Object.getOwnPropertyDescriptor(value, "__type");
16823
16818
  return (desc == null ? void 0 : desc.value) === RUN_REF_TYPE;
16824
16819
  }
16820
+ function isBytesDisplay(value) {
16821
+ if (value === null || typeof value !== "object")
16822
+ return false;
16823
+ const desc = Object.getOwnPropertyDescriptor(value, "__type");
16824
+ return (desc == null ? void 0 : desc.value) === BYTES_DISPLAY_TYPE;
16825
+ }
16825
16826
  function isClassInstanceRef(value) {
16826
16827
  return value !== null && typeof value === "object" && "__type" in value && value.__type === CLASS_INSTANCE_REF_TYPE;
16827
16828
  }
@@ -16874,9 +16875,31 @@ function RunRefInline({ runRef }) {
16874
16875
  }, title: `View run: ${runRef.runId}`, children: jsxRuntimeExports.jsx("span", { children: runRef.runId }) });
16875
16876
  }
16876
16877
  const ExtendedThemeContext = reactExports.createContext(inspectorThemeExtendedLight);
16878
+ function DecodedBytesChunk({ decodedText, source }) {
16879
+ const [selectedView, setSelectedView] = reactExports.useState("decoded");
16880
+ const parsed = parseChunkData(decodedText);
16881
+ return jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [selectedView === "decoded" ? jsxRuntimeExports.jsx("div", { className: "min-w-0", children: typeof parsed === "string" ? jsxRuntimeExports.jsx("span", { className: "whitespace-pre-wrap break-words", style: { color: "var(--ds-gray-1000)" }, children: deserializeChunkText(parsed) }) : jsxRuntimeExports.jsx(DataInspector, { data: parsed, expandLevel: 1 }) }) : jsxRuntimeExports.jsx(DecodedBytesInspector, { decodedText, source }), jsxRuntimeExports.jsx("div", { className: "mt-2 flex", children: jsxRuntimeExports.jsxs("div", { className: "inline-flex overflow-hidden rounded border", style: { borderColor: "var(--ds-gray-400)" }, title: `${source.type} decoded as ${source.encoding.toUpperCase()} text. Switch to Bytes to inspect the summarized raw value.`, children: [jsxRuntimeExports.jsx("button", { type: "button", className: "h-5 px-1.5 text-[10px] font-medium", style: {
16882
+ backgroundColor: selectedView === "decoded" ? "var(--ds-gray-200)" : "var(--ds-gray-100)",
16883
+ color: "var(--ds-gray-900)"
16884
+ }, onClick: () => setSelectedView("decoded"), "aria-pressed": selectedView === "decoded", "aria-label": "Show decoded text", children: "Decoded" }), jsxRuntimeExports.jsx("button", { type: "button", className: "h-5 border-l px-1.5 text-[10px] font-medium", style: {
16885
+ borderColor: "var(--ds-gray-400)",
16886
+ backgroundColor: selectedView === "bytes" ? "var(--ds-gray-200)" : "var(--ds-gray-100)",
16887
+ color: "var(--ds-gray-900)"
16888
+ }, onClick: () => setSelectedView("bytes"), "aria-pressed": selectedView === "bytes", "aria-label": "Show raw bytes summary", children: "Bytes" })] }) })] });
16889
+ }
16890
+ function DecodedBytesInspector({ decodedText, source }) {
16891
+ const [expanded2, setExpanded] = reactExports.useState(false);
16892
+ return jsxRuntimeExports.jsxs("div", { className: "font-mono", children: [jsxRuntimeExports.jsxs("button", { type: "button", className: "flex max-w-full items-start gap-1 text-left", style: { color: "var(--ds-gray-1000)" }, onClick: () => setExpanded((value) => !value), title: `${source.type} decoded as ${source.encoding.toUpperCase()} text`, children: [jsxRuntimeExports.jsx("span", { className: "select-none", style: { color: "var(--ds-gray-700)" }, children: expanded2 ? "▼" : "▶" }), jsxRuntimeExports.jsx("span", { className: "min-w-0 break-words", children: source.rawSummary })] }), expanded2 && jsxRuntimeExports.jsxs("div", { className: "mt-1 pl-5", children: [jsxRuntimeExports.jsx("span", { style: { color: "var(--ds-gray-700)" }, children: "decoded: " }), jsxRuntimeExports.jsx("span", { className: "whitespace-pre-wrap break-words", style: { color: "var(--ds-green-900)" }, children: JSON.stringify(decodedText) })] })] });
16893
+ }
16894
+ function BytesDisplayLabel({ name: name2, display }) {
16895
+ return jsxRuntimeExports.jsxs("div", { className: "inline-block min-w-0 align-top", children: [name2 != null && jsxRuntimeExports.jsx(ObjectName, { name: name2 }), name2 != null && jsxRuntimeExports.jsx("span", { children: ": " }), display.decodedFrom ? jsxRuntimeExports.jsx(DecodedBytesChunk, { decodedText: display.text, source: display.decodedFrom }) : jsxRuntimeExports.jsx("span", { className: "whitespace-pre-wrap break-words", style: { color: "var(--ds-gray-1000)" }, children: display.text })] });
16896
+ }
16877
16897
  function NodeRenderer({ depth, name: name2, data, isNonenumerable }) {
16878
16898
  var _a3;
16879
16899
  const extendedTheme = reactExports.useContext(ExtendedThemeContext);
16900
+ if (isBytesDisplay(data)) {
16901
+ return jsxRuntimeExports.jsx(BytesDisplayLabel, { name: name2, display: data });
16902
+ }
16880
16903
  if (data !== null && typeof data === "object" && ((_a3 = data.constructor) == null ? void 0 : _a3.name) === ENCRYPTED_DISPLAY_NAME) {
16881
16904
  const label = jsxRuntimeExports.jsx(EncryptedInlineLabel, {});
16882
16905
  if (depth === 0) {
@@ -16915,13 +16938,41 @@ function makeOpaqueRef(ref) {
16915
16938
  }
16916
16939
  return opaque;
16917
16940
  }
16941
+ function makeBytesDisplay(display) {
16942
+ const opaque = /* @__PURE__ */ Object.create(null);
16943
+ Object.defineProperty(opaque, "__type", {
16944
+ value: BYTES_DISPLAY_TYPE,
16945
+ enumerable: false
16946
+ });
16947
+ Object.defineProperty(opaque, "text", {
16948
+ value: display.text,
16949
+ enumerable: false
16950
+ });
16951
+ Object.defineProperty(opaque, "decodedFrom", {
16952
+ value: display.decodedFrom,
16953
+ enumerable: false
16954
+ });
16955
+ return opaque;
16956
+ }
16918
16957
  function collapseRefs(data) {
16919
16958
  if (data === null || typeof data !== "object")
16920
16959
  return data;
16960
+ if (ArrayBuffer.isView(data) && !(data instanceof DataView)) {
16961
+ return makeBytesDisplay(formatArrayBufferViewForDisplay(data));
16962
+ }
16921
16963
  if (isRunRef(data) || isStreamRef(data))
16922
16964
  return makeOpaqueRef(data);
16923
16965
  if (Array.isArray(data))
16924
16966
  return data.map(collapseRefs);
16967
+ if (data instanceof Map) {
16968
+ return new Map(Array.from(data.entries(), ([key, value]) => [
16969
+ collapseRefs(key),
16970
+ collapseRefs(value)
16971
+ ]));
16972
+ }
16973
+ if (data instanceof Set) {
16974
+ return new Set(Array.from(data.values(), collapseRefs));
16975
+ }
16925
16976
  const proto2 = Object.getPrototypeOf(data);
16926
16977
  if (proto2 !== Object.prototype && proto2 !== null)
16927
16978
  return data;
@@ -16971,9 +17022,16 @@ function useStableInspectorData(next2) {
16971
17022
  function isObjectLike(value) {
16972
17023
  return typeof value === "object" && value !== null;
16973
17024
  }
17025
+ function isSameBytesDisplay(a2, b2) {
17026
+ var _a3, _b, _c, _d, _e2, _f;
17027
+ return a2.text === b2.text && ((_a3 = a2.decodedFrom) == null ? void 0 : _a3.type) === ((_b = b2.decodedFrom) == null ? void 0 : _b.type) && ((_c = a2.decodedFrom) == null ? void 0 : _c.encoding) === ((_d = b2.decodedFrom) == null ? void 0 : _d.encoding) && ((_e2 = a2.decodedFrom) == null ? void 0 : _e2.rawSummary) === ((_f = b2.decodedFrom) == null ? void 0 : _f.rawSummary);
17028
+ }
16974
17029
  function isDeepEqual(a2, b2, seen2 = /* @__PURE__ */ new WeakMap()) {
16975
17030
  if (Object.is(a2, b2))
16976
17031
  return true;
17032
+ if (isBytesDisplay(a2) || isBytesDisplay(b2)) {
17033
+ return isBytesDisplay(a2) && isBytesDisplay(b2) && isSameBytesDisplay(a2, b2);
17034
+ }
16977
17035
  if (a2 instanceof Date && b2 instanceof Date) {
16978
17036
  return a2.getTime() === b2.getTime();
16979
17037
  }
@@ -42883,7 +42941,7 @@ var tn = f("block", "before:content-[counter(line)]", "before:inline-block", "be
42883
42941
  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 });
42884
42942
  var Se = reactExports.createContext({ code: "" }), de = () => reactExports.useContext(Se);
42885
42943
  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 }) });
42886
- var cn$1 = /\n+$/, dn = reactExports.lazy(() => __vitePreload(() => import("./highlighted-body-B3W2YXNL-DPWdt39H.js"), true ? __vite__mapDeps([0,1]) : void 0).then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
42944
+ var cn$1 = /\n+$/, dn = reactExports.lazy(() => __vitePreload(() => import("./highlighted-body-B3W2YXNL-Be0uLJd8.js"), true ? __vite__mapDeps([0,1]) : void 0).then((e) => ({ default: e.HighlightedCodeBlockBody }))), rt = ({ code: e, language: t, className: o, children: n, isIncomplete: s2 = false, ...r2 }) => {
42887
42945
  let i = reactExports.useMemo(() => e.replace(cn$1, ""), [e]), c = reactExports.useMemo(() => ({ bg: "transparent", fg: "inherit", tokens: i.split(`
42888
42946
  `).map((a2) => [{ content: a2, color: "inherit", bgColor: "transparent", htmlStyle: {}, offset: 0 }]) }), [i]);
42889
42947
  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 }) })] }) });
@@ -43647,27 +43705,11 @@ var Nt = ({ chart: e, className: t, config: o, fullscreen: n = false, showContro
43647
43705
  let T2 = l || d2;
43648
43706
  return jsxRuntimeExports.jsx("div", { className: f("size-full", t), "data-streamdown": "mermaid", ref: w2, children: jsxRuntimeExports.jsx(So, { className: f(n ? "size-full overflow-hidden" : "overflow-hidden", t), fullscreen: n, maxZoom: 3, minZoom: 0.5, showControls: s2, zoomStep: 0.1, children: jsxRuntimeExports.jsx("div", { "aria-label": "Mermaid chart", className: f("flex justify-center", n ? "size-full items-center" : null), dangerouslySetInnerHTML: { __html: T2 }, role: "img" }) }) });
43649
43707
  };
43650
- const SEARCH_HEIGHT = 40;
43651
- const SEARCH_GAP = 8;
43652
43708
  const MAP_HEIGHT = 56;
43653
43709
  const TIMELINE_PADDING = 8;
43654
43710
  const ROW_PADDING = 2;
43655
- const ROW_HEIGHT = 24;
43711
+ const ROW_HEIGHT$1 = 24;
43656
43712
  const MARKER_HEIGHT = 24;
43657
- const MARKER_NOTCH_HEIGHT = 8;
43658
- const detectScrollbarWidth = () => {
43659
- if (!("document" in globalThis))
43660
- return 0;
43661
- const size2 = 400;
43662
- const container = document.createElement("div");
43663
- container.style.width = `${size2}px`;
43664
- container.style.height = `${size2}px`;
43665
- container.style.overflow = "scroll";
43666
- document.body.appendChild(container);
43667
- const scrollbarWidth = size2 - container.scrollWidth;
43668
- container.remove();
43669
- return scrollbarWidth;
43670
- };
43671
43713
  const initialState = {
43672
43714
  root: {
43673
43715
  startTime: 0,
@@ -43697,301 +43739,14 @@ const initialState = {
43697
43739
  withPanel: false,
43698
43740
  isMobile: false
43699
43741
  };
43700
- const getMinScale = (state) => {
43701
- return (state.timelineWidth - state.scrollbarWidth) / state.root.duration;
43702
- };
43703
43742
  const TraceViewerContext = reactExports.createContext({
43704
43743
  state: initialState,
43705
43744
  dispatch: () => {
43706
43745
  }
43707
43746
  });
43708
43747
  TraceViewerContext.displayName = "TraceViewerContext";
43709
- const reducer = (state, action) => {
43710
- var _a3;
43711
- switch (action.type) {
43712
- case "setRoot":
43713
- state.scrollSnapshotRef.current = void 0;
43714
- state.memoCacheRef.current.clear();
43715
- return reducer({
43716
- ...state,
43717
- root: action.root,
43718
- spanMap: action.spanMap,
43719
- resourceMap: Object.fromEntries(action.resources.map(({ name: name2, attributes }) => [name2, attributes]))
43720
- }, {
43721
- type: "detectBaseScale"
43722
- });
43723
- case "setSize": {
43724
- const lowerHeight = action.height - MAP_HEIGHT - SEARCH_HEIGHT - 3 * SEARCH_GAP;
43725
- const isMobile = state.withPanel && action.width <= 768;
43726
- let newState = {
43727
- ...state,
43728
- width: action.width,
43729
- height: action.height,
43730
- timelineWidth: action.width - Number(Boolean(state.selected && state.withPanel && !isMobile)) * state.panelWidth,
43731
- timelineHeight: lowerHeight,
43732
- panelHeight: lowerHeight,
43733
- isMobile
43734
- };
43735
- if (newState.width !== state.width) {
43736
- newState = reducer(newState, {
43737
- type: "detectBaseScale"
43738
- });
43739
- }
43740
- return newState;
43741
- }
43742
- case "setPanelWidth": {
43743
- const panelWidth = Math.max(240, Math.min(action.width, state.width - 240));
43744
- const timelineWidth = state.withPanel && state.selected && !state.isMobile ? state.width - panelWidth : state.width;
43745
- return reducer({
43746
- ...state,
43747
- timelineWidth,
43748
- panelWidth
43749
- }, {
43750
- type: "detectBaseScale"
43751
- });
43752
- }
43753
- case "setFilter":
43754
- return {
43755
- ...state,
43756
- filter: action.filter
43757
- };
43758
- case "deselect":
43759
- return reducer({
43760
- ...state,
43761
- selected: null,
43762
- timelineWidth: state.width
43763
- }, {
43764
- type: "detectBaseScale"
43765
- });
43766
- case "select": {
43767
- const node2 = state.spanMap[action.id];
43768
- if (!node2) {
43769
- return state;
43770
- }
43771
- return reducer({
43772
- ...state,
43773
- selected: node2,
43774
- timelineWidth: state.width - (state.withPanel && !state.isMobile ? state.panelWidth : 0)
43775
- }, {
43776
- type: "detectBaseScale"
43777
- });
43778
- }
43779
- case "escape": {
43780
- if (state.selected) {
43781
- return reducer(state, {
43782
- type: "deselect"
43783
- });
43784
- }
43785
- return reducer(state, {
43786
- type: "resetScale"
43787
- });
43788
- }
43789
- case "toggleSelection": {
43790
- let newState = state;
43791
- if (state.selected) {
43792
- newState = reducer(newState, {
43793
- type: "deselect"
43794
- });
43795
- }
43796
- if (((_a3 = state.selected) == null ? void 0 : _a3.span.spanId) === action.id) {
43797
- return newState;
43798
- }
43799
- return reducer(newState, {
43800
- type: "select",
43801
- id: action.id
43802
- });
43803
- }
43804
- case "detectBaseScale": {
43805
- const baseScale = (state.timelineWidth - state.scrollbarWidth) / state.root.duration;
43806
- return reducer({
43807
- ...state,
43808
- baseScale,
43809
- scale: baseScale * state.scaleRatio
43810
- }, {
43811
- type: "minScale"
43812
- });
43813
- }
43814
- case "setScale":
43815
- return {
43816
- ...state,
43817
- scaleRatio: action.scale,
43818
- scale: state.baseScale * action.scale
43819
- };
43820
- case "resetScale":
43821
- return reducer(state, {
43822
- type: "scaleToRange",
43823
- t1: state.root.startTime,
43824
- t2: state.root.endTime
43825
- });
43826
- case "scaleToNode": {
43827
- const node2 = state.spanMap[action.id];
43828
- if (!node2) {
43829
- return state;
43830
- }
43831
- return reducer(reducer(state, {
43832
- type: "setScale",
43833
- scale: (state.width - state.scrollbarWidth - (state.withPanel && !state.isMobile ? state.panelWidth : 0)) / node2.duration / state.baseScale
43834
- }), {
43835
- type: "setScrollSnapshot",
43836
- anchorT: node2.startTime - state.root.startTime,
43837
- anchorX: 0
43838
- });
43839
- }
43840
- case "scaleToRange": {
43841
- const duration2 = Math.abs(action.t1 - action.t2);
43842
- return reducer(reducer(state, {
43843
- type: "setScale",
43844
- scale: (state.width - state.scrollbarWidth - (state.selected && state.withPanel ? state.panelWidth : 0)) / duration2 / state.baseScale
43845
- }), {
43846
- type: "setScrollSnapshot",
43847
- anchorT: Math.min(action.t1, action.t2) - state.root.startTime,
43848
- anchorX: 0
43849
- });
43850
- }
43851
- case "adjustScaleRatio": {
43852
- let { scaleRatio } = state;
43853
- switch (action.direction) {
43854
- case -1:
43855
- scaleRatio *= 0.8;
43856
- break;
43857
- case 1:
43858
- scaleRatio *= 1.25;
43859
- break;
43860
- default:
43861
- scaleRatio = 1;
43862
- break;
43863
- }
43864
- const $timeline = state.timelineRef.current;
43865
- if (!$timeline) {
43866
- console.warn("timelineRef is null");
43867
- return state;
43868
- }
43869
- const { clientWidth, scrollLeft } = $timeline;
43870
- return reducer(reducer({
43871
- ...state,
43872
- scaleRatio,
43873
- scale: state.baseScale * scaleRatio
43874
- }, {
43875
- type: "minScale"
43876
- }), {
43877
- type: "setScrollSnapshot",
43878
- anchorT: (scrollLeft + clientWidth * 0.5) / state.scale,
43879
- anchorX: clientWidth * 0.5
43880
- });
43881
- }
43882
- case "trackpadScale": {
43883
- const minScaleRatio = getMinScale(state) / state.baseScale;
43884
- const scaleRatio = Math.max(minScaleRatio, state.scaleRatio * (1 + 0.2 * Math.sign(action.delta) * Math.sqrt(Math.abs(action.delta))));
43885
- return reducer({
43886
- ...state,
43887
- scaleRatio,
43888
- scale: state.baseScale * scaleRatio
43889
- }, {
43890
- type: "setScrollSnapshot",
43891
- anchorT: action.anchorT,
43892
- anchorX: action.anchorX
43893
- });
43894
- }
43895
- case "minScale": {
43896
- const minScale = getMinScale(state);
43897
- if (state.scale >= minScale)
43898
- return state;
43899
- return {
43900
- ...state,
43901
- scale: minScale,
43902
- scaleRatio: minScale / state.baseScale
43903
- };
43904
- }
43905
- case "setScrollSnapshot": {
43906
- const $timeline = state.timelineRef.current;
43907
- if (!$timeline)
43908
- return state;
43909
- const { anchorT, anchorX } = action;
43910
- const scrollLeft = anchorT * state.scale - anchorX;
43911
- const { scrollTop } = $timeline;
43912
- const startRow = (scrollTop - MARKER_HEIGHT - TIMELINE_PADDING) / (ROW_HEIGHT + ROW_PADDING);
43913
- const endRow = startRow + Math.ceil(state.timelineHeight / (ROW_HEIGHT + ROW_PADDING));
43914
- state.scrollSnapshotRef.current = {
43915
- anchorT,
43916
- anchorX,
43917
- scrollLeft,
43918
- scrollTop,
43919
- startTime: state.root.startTime + scrollLeft / state.scale,
43920
- endTime: state.root.startTime + (scrollLeft + state.timelineWidth) / state.scale,
43921
- startRow,
43922
- endRow,
43923
- scale: state.scale
43924
- };
43925
- return state;
43926
- }
43927
- case "setWithPanel": {
43928
- if (state.withPanel === action.withPanel)
43929
- return state;
43930
- const timelineWidth = action.withPanel && state.selected && !state.isMobile ? state.width - state.panelWidth : state.width;
43931
- return reducer({
43932
- ...state,
43933
- withPanel: action.withPanel,
43934
- timelineWidth
43935
- }, {
43936
- type: "detectBaseScale"
43937
- });
43938
- }
43939
- case "forceRender":
43940
- state.memoCacheRef.current.set("", {});
43941
- return {
43942
- ...state
43943
- };
43944
- case "updateRoot":
43945
- state.memoCacheRef.current.set("", {});
43946
- return reducer({
43947
- ...state,
43948
- root: action.root,
43949
- spanMap: action.spanMap,
43950
- resourceMap: Object.fromEntries(action.resources.map(({ name: name2, attributes }) => [name2, attributes]))
43951
- }, {
43952
- type: "detectBaseScale"
43953
- });
43954
- }
43955
- };
43956
- function TraceViewerContextProvider({ getQuickLinks, withPanel = false, children: children2, customSpanClassNameFunc, customSpanEventClassNameFunc, customPanelComponent = null }) {
43957
- const timelineRef = reactExports.useRef(null);
43958
- const scrollSnapshotRef = reactExports.useRef(void 0);
43959
- const getQuickLinksRef = reactExports.useRef(getQuickLinks);
43960
- getQuickLinksRef.current = getQuickLinks;
43961
- const memoCacheRef = reactExports.useRef(/* @__PURE__ */ new Map());
43962
- const quickLinksCache = reactExports.useRef(/* @__PURE__ */ new Map());
43963
- const [state, dispatch] = reactExports.useReducer(reducer, initialState, (initial) => {
43964
- return {
43965
- ...initial,
43966
- scrollbarWidth: detectScrollbarWidth(),
43967
- timelineRef,
43968
- scrollSnapshotRef,
43969
- customSpanClassNameFunc,
43970
- customSpanEventClassNameFunc,
43971
- memoCacheRef,
43972
- withPanel,
43973
- getQuickLinks: (span) => {
43974
- var _a3;
43975
- const cacheKey = span.spanId;
43976
- const existing = quickLinksCache.current.get(cacheKey);
43977
- if (existing)
43978
- return existing;
43979
- const value2 = ((_a3 = getQuickLinksRef.current) == null ? void 0 : _a3.call(getQuickLinksRef, span)) || [];
43980
- quickLinksCache.current.set(cacheKey, value2);
43981
- return value2;
43982
- }
43983
- };
43984
- });
43985
- reactExports.useEffect(() => dispatch({
43986
- type: "setWithPanel",
43987
- withPanel
43988
- }), [withPanel]);
43989
- const value = reactExports.useMemo(() => ({ state, dispatch }), [state, dispatch]);
43990
- return jsxRuntimeExports.jsx(CustomPanelContext.Provider, { value: customPanelComponent, children: jsxRuntimeExports.jsx(TraceViewerContext.Provider, { value, children: children2 }) });
43991
- }
43992
43748
  const useTraceViewer = () => reactExports.useContext(TraceViewerContext);
43993
- const CustomPanelContext = reactExports.createContext(null);
43994
- const useCustomPanelComponent = () => reactExports.useContext(CustomPanelContext);
43749
+ reactExports.createContext(null);
43995
43750
  const traceNode = "_traceNode_1fmf2_1";
43996
43751
  const childRow = "_childRow_1fmf2_5";
43997
43752
  const spanNode = "_spanNode_1fmf2_11";
@@ -44241,27 +43996,6 @@ const styles = {
44241
43996
  function getHighResInMs([seconds, nanoseconds]) {
44242
43997
  return seconds * 1e3 + nanoseconds / 1e6;
44243
43998
  }
44244
- function getMsInHighRes(ms) {
44245
- return [Math.floor(ms / 1e3), ms % 1e3 * 1e3];
44246
- }
44247
- const formatDurationForTimeline = (ms) => formatDuration(ms, true);
44248
- const timeSelectionFormatter = new Intl.NumberFormat(void 0, {
44249
- minimumFractionDigits: 2,
44250
- maximumFractionDigits: 2
44251
- });
44252
- function formatTimeSelection(ms) {
44253
- if (ms >= 1e3) {
44254
- return `${timeSelectionFormatter.format(ms / 1e3)}s`;
44255
- }
44256
- return `${timeSelectionFormatter.format(ms)}ms`;
44257
- }
44258
- function formatWallClockTime(epochMs) {
44259
- const d2 = new Date(epochMs);
44260
- const h2 = String(d2.getHours()).padStart(2, "0");
44261
- const m2 = String(d2.getMinutes()).padStart(2, "0");
44262
- const s2 = String(d2.getSeconds()).padStart(2, "0");
44263
- return `${h2}:${m2}:${s2}`;
44264
- }
44265
43999
  const SEGMENT_CLASS_MAP = {
44266
44000
  queued: "segQueued",
44267
44001
  running: "segRunning",
@@ -44272,13 +44006,13 @@ const SEGMENT_CLASS_MAP = {
44272
44006
  sleeping: "segSleeping",
44273
44007
  received: "segReceived"
44274
44008
  };
44275
- function clampFraction(value) {
44009
+ function clampFraction$1(value) {
44276
44010
  return Math.max(0, Math.min(1, value));
44277
44011
  }
44278
- function timeToFraction(time2, spanStart, spanDuration2) {
44012
+ function timeToFraction$1(time2, spanStart, spanDuration2) {
44279
44013
  if (spanDuration2 <= 0)
44280
44014
  return 0;
44281
- return clampFraction((time2 - spanStart) / spanDuration2);
44015
+ return clampFraction$1((time2 - spanStart) / spanDuration2);
44282
44016
  }
44283
44017
  function sortedEvents(events) {
44284
44018
  return [...events].sort((a2, b2) => a2.timestamp - b2.timestamp);
@@ -44300,7 +44034,7 @@ function computeStepSegments(node2) {
44300
44034
  return segments;
44301
44035
  }
44302
44036
  const firstMark = marks[0];
44303
- const firstFraction = timeToFraction(firstMark.time, startTime, duration2);
44037
+ const firstFraction = timeToFraction$1(firstMark.time, startTime, duration2);
44304
44038
  if (firstFraction > 1e-3) {
44305
44039
  segments.push({
44306
44040
  startFraction: 0,
@@ -44310,9 +44044,9 @@ function computeStepSegments(node2) {
44310
44044
  }
44311
44045
  for (let i = 0; i < marks.length; i++) {
44312
44046
  const mark2 = marks[i];
44313
- const markFraction = timeToFraction(mark2.time, startTime, duration2);
44047
+ const markFraction = timeToFraction$1(mark2.time, startTime, duration2);
44314
44048
  const nextMark = marks[i + 1];
44315
- const nextFraction = nextMark ? timeToFraction(nextMark.time, startTime, duration2) : 1;
44049
+ const nextFraction = nextMark ? timeToFraction$1(nextMark.time, startTime, duration2) : 1;
44316
44050
  if (mark2.type === "step_started") {
44317
44051
  const isLastMark = i === marks.length - 1;
44318
44052
  if (isLastMark) {
@@ -44360,8 +44094,8 @@ function computeHookSegments(node2) {
44360
44094
  segments.push({ startFraction: 0, endFraction: 1, status: "waiting" });
44361
44095
  return segments;
44362
44096
  }
44363
- const receivedFraction = receivedEvent ? timeToFraction(receivedEvent.timestamp, startTime, duration2) : null;
44364
- const disposedFraction = disposedEvent ? timeToFraction(disposedEvent.timestamp, startTime, duration2) : null;
44097
+ const receivedFraction = receivedEvent ? timeToFraction$1(receivedEvent.timestamp, startTime, duration2) : null;
44098
+ const disposedFraction = disposedEvent ? timeToFraction$1(disposedEvent.timestamp, startTime, duration2) : null;
44365
44099
  if (receivedFraction !== null && receivedFraction > 1e-3) {
44366
44100
  segments.push({
44367
44101
  startFraction: 0,
@@ -44403,7 +44137,7 @@ function computeSleepSegments(node2) {
44403
44137
  segments.push({ startFraction: 0, endFraction: 1, status: "sleeping" });
44404
44138
  return segments;
44405
44139
  }
44406
- const completedFraction = timeToFraction(completedEvent.timestamp, startTime, duration2);
44140
+ const completedFraction = timeToFraction$1(completedEvent.timestamp, startTime, duration2);
44407
44141
  if (completedFraction > 1e-3) {
44408
44142
  segments.push({
44409
44143
  startFraction: 0,
@@ -44429,13 +44163,13 @@ function computeRunSegments(node2) {
44429
44163
  if (!hasRunCreated) {
44430
44164
  const runData = (_a3 = node2.span.attributes) == null ? void 0 : _a3.data;
44431
44165
  const runStatus = runData == null ? void 0 : runData.status;
44432
- return computeV1RunSegments(startTime, duration2, activeStartTime, runStatus);
44166
+ return computeV1RunSegments$1(startTime, duration2, activeStartTime, runStatus);
44433
44167
  }
44434
44168
  const failedEvent = events.find((e) => e.event.name === "run_failed");
44435
44169
  const completedEvent = events.find((e) => e.event.name === "run_completed");
44436
44170
  let cursor = 0;
44437
44171
  if (activeStartTime && activeStartTime > startTime) {
44438
- const queuedFraction = timeToFraction(activeStartTime, startTime, duration2);
44172
+ const queuedFraction = timeToFraction$1(activeStartTime, startTime, duration2);
44439
44173
  if (queuedFraction > 1e-3) {
44440
44174
  segments.push({
44441
44175
  startFraction: 0,
@@ -44446,7 +44180,7 @@ function computeRunSegments(node2) {
44446
44180
  }
44447
44181
  }
44448
44182
  if (failedEvent) {
44449
- const failedFraction = timeToFraction(failedEvent.timestamp, startTime, duration2);
44183
+ const failedFraction = timeToFraction$1(failedEvent.timestamp, startTime, duration2);
44450
44184
  if (failedFraction > cursor + 1e-3) {
44451
44185
  segments.push({
44452
44186
  startFraction: cursor,
@@ -44460,7 +44194,7 @@ function computeRunSegments(node2) {
44460
44194
  status: "failed"
44461
44195
  });
44462
44196
  } else if (completedEvent) {
44463
- const completedFraction = timeToFraction(completedEvent.timestamp, startTime, duration2);
44197
+ const completedFraction = timeToFraction$1(completedEvent.timestamp, startTime, duration2);
44464
44198
  if (completedFraction > cursor + 1e-3) {
44465
44199
  segments.push({
44466
44200
  startFraction: cursor,
@@ -44482,11 +44216,11 @@ function computeRunSegments(node2) {
44482
44216
  }
44483
44217
  return segments;
44484
44218
  }
44485
- function computeV1RunSegments(startTime, duration2, activeStartTime, runStatus) {
44219
+ function computeV1RunSegments$1(startTime, duration2, activeStartTime, runStatus) {
44486
44220
  const segments = [];
44487
44221
  let cursor = 0;
44488
44222
  if (activeStartTime && activeStartTime > startTime) {
44489
- const queuedFraction = timeToFraction(activeStartTime, startTime, duration2);
44223
+ const queuedFraction = timeToFraction$1(activeStartTime, startTime, duration2);
44490
44224
  if (queuedFraction > 1e-3) {
44491
44225
  segments.push({
44492
44226
  startFraction: 0,
@@ -44539,7 +44273,7 @@ function computeBoundaries(node2, relevantEventNames) {
44539
44273
  for (const e of events) {
44540
44274
  if (!relevantEventNames.includes(e.event.name))
44541
44275
  continue;
44542
- const fraction = timeToFraction(e.timestamp, startTime, duration2);
44276
+ const fraction = timeToFraction$1(e.timestamp, startTime, duration2);
44543
44277
  if (fraction < 0.01 || fraction > 0.99)
44544
44278
  continue;
44545
44279
  boundaries.push({
@@ -44710,17 +44444,17 @@ function computeIsNearRightSide(node2, root2, scrollSnapshotRef, isHovered) {
44710
44444
  }
44711
44445
  function computeDefaultLayout(node2, root2, scale, scrollSnapshotRef) {
44712
44446
  const left = (node2.startTime - root2.startTime) * scale;
44713
- let top = MARKER_HEIGHT + (ROW_HEIGHT + ROW_PADDING) * node2.row;
44447
+ let top = MARKER_HEIGHT + (ROW_HEIGHT$1 + ROW_PADDING) * node2.row;
44714
44448
  const actualWidth = node2.duration * scale;
44715
44449
  const width = Math.max(actualWidth, MIN_SPAN_WIDTH);
44716
- let height = ROW_HEIGHT;
44450
+ let height = ROW_HEIGHT$1;
44717
44451
  const isHuge = computeIsHuge(actualWidth);
44718
44452
  const isSmall = computeIsSmall(actualWidth);
44719
44453
  const isHovered = computeIsHovered(node2, isHuge);
44720
44454
  const isExpanded = isHovered || Boolean(node2.isSelected);
44721
44455
  if (isSmall && !isExpanded) {
44722
44456
  height *= 0.4;
44723
- top += (ROW_HEIGHT - height) * 0.5;
44457
+ top += (ROW_HEIGHT$1 - height) * 0.5;
44724
44458
  }
44725
44459
  const isNearRightSide = computeIsNearRightSide(node2, root2, scrollSnapshotRef, isExpanded);
44726
44460
  return {
@@ -44809,7 +44543,7 @@ function getTerminalTimestamp(resourceType, node2) {
44809
44543
  return void 0;
44810
44544
  }
44811
44545
  }
44812
- const SpanNodes = reactExports.memo(function SpanNodes2({ root: root2, scale, spans, isLive = false, scrollSnapshotRef, cache, customSpanClassNameFunc, customSpanEventClassNameFunc }) {
44546
+ reactExports.memo(function SpanNodes({ root: root2, scale, spans, isLive = false, scrollSnapshotRef, cache, customSpanClassNameFunc, customSpanEventClassNameFunc }) {
44813
44547
  return spans.map((x2) => jsxRuntimeExports.jsx(SpanComponent, { cacheKey: cache.get(x2.span.spanId), customSpanEventClassNameFunc, customSpanClassNameFunc, node: x2, root: root2, scale, traceIsLive: isLive, scrollSnapshotRef }, x2.span.spanId));
44814
44548
  });
44815
44549
  function getSpanStyle(layout, node2, root2, scale) {
@@ -44886,8 +44620,8 @@ const SpanComponent = reactExports.memo(function SpanComponent2({ node: node2, r
44886
44620
  layout.isSmall = liveActualWidth < 64;
44887
44621
  layout.isHuge = liveActualWidth >= 500;
44888
44622
  if (!layout.isSmall) {
44889
- layout.height = ROW_HEIGHT;
44890
- layout.top = MARKER_HEIGHT + (ROW_HEIGHT + ROW_PADDING) * segmentNode.row;
44623
+ layout.height = ROW_HEIGHT$1;
44624
+ layout.top = MARKER_HEIGHT + (ROW_HEIGHT$1 + ROW_PADDING) * segmentNode.row;
44891
44625
  }
44892
44626
  }
44893
44627
  reactExports.useEffect(() => {
@@ -44962,7 +44696,7 @@ const SpanEventComponent = reactExports.memo(function SpanEventComponent2({ even
44962
44696
  }
44963
44697
  }
44964
44698
  const left = (event.timestamp - root2.startTime) * scale;
44965
- const top = MARKER_HEIGHT + (ROW_HEIGHT + ROW_PADDING) * node2.row;
44699
+ const top = MARKER_HEIGHT + (ROW_HEIGHT$1 + ROW_PADDING) * node2.row;
44966
44700
  const isLeftAligned = node2.duration <= 0 || (event.timestamp - node2.startTime) / node2.duration < 0.5;
44967
44701
  const customClassName = customSpanEventClassNameFunc ? customSpanEventClassNameFunc(event) : "";
44968
44702
  return jsxRuntimeExports.jsxs("div", { title: phaseDuration ? `${displayLabel} ${timestamp}
@@ -44975,10 +44709,6 @@ const colorTokenMap = {
44975
44709
  "gray-700": "var(--ds-gray-700)",
44976
44710
  "gray-900": "var(--ds-gray-900)"
44977
44711
  };
44978
- function IconCross({ size: size2 = 16, color: color5 = "gray-700" }) {
44979
- const style2 = { color: colorTokenMap[color5] || color5 };
44980
- return jsxRuntimeExports.jsxs("svg", { width: size2, height: size2, viewBox: "0 0 24 24", fill: "none", style: style2, "aria-hidden": true, children: [jsxRuntimeExports.jsx("title", { children: "Cross" }), jsxRuntimeExports.jsx("path", { d: "M6 6l12 12M18 6L6 18", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })] });
44981
- }
44982
44712
  function IconChevronDown({ size: size2 = 16 }) {
44983
44713
  return jsxRuntimeExports.jsxs("svg", { width: size2, height: size2, viewBox: "0 0 24 24", fill: "none", "aria-hidden": true, className: styles.detailHeadingIcon, children: [jsxRuntimeExports.jsx("title", { children: "Chevron Down" }), jsxRuntimeExports.jsx("path", { d: "M6 9l6 6 6-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })] });
44984
44714
  }
@@ -44994,102 +44724,9 @@ function Link(props) {
44994
44724
  }
44995
44725
  return jsxRuntimeExports.jsx("a", { className, href, ...rest, children: children2 });
44996
44726
  }
44997
- function ButtonLink(props) {
44998
- const { className, children: children2, size: _size, ...rest } = props;
44999
- return jsxRuntimeExports.jsx("a", { ...rest, className: clsx(styles.buttonLink, className), children: children2 });
45000
- }
45001
- function Note({ children: children2, className }) {
45002
- return jsxRuntimeExports.jsx("div", { className: clsx(styles.note, className), children: children2 });
45003
- }
45004
44727
  function Skeleton({ width, height, rounded }) {
45005
44728
  return jsxRuntimeExports.jsx("span", { className: clsx(styles.skeleton, rounded && styles.skeletonRounded), style: { width, height }, "aria-hidden": true });
45006
44729
  }
45007
- const percentage = (n) => `${(100 * n).toFixed(3)}%`;
45008
- const sortWord = (a2, b2) => {
45009
- if (a2 < b2) {
45010
- return -1;
45011
- } else if (a2 > b2) {
45012
- return 1;
45013
- }
45014
- return 0;
45015
- };
45016
- const getGroupedAttributes = (attributes) => {
45017
- const groups = {};
45018
- for (const [key, value] of Object.entries(attributes)) {
45019
- const dotIndex = key.indexOf(".");
45020
- let prefix = "";
45021
- let suffix = "";
45022
- if (dotIndex !== -1) {
45023
- prefix = key.substring(0, dotIndex);
45024
- suffix = key.substring(dotIndex + 1);
45025
- } else {
45026
- suffix = key;
45027
- }
45028
- let group = groups[prefix];
45029
- if (!group) {
45030
- group = {
45031
- prefix,
45032
- attributes: []
45033
- };
45034
- groups[prefix] = group;
45035
- }
45036
- group.attributes.push({
45037
- key,
45038
- suffix,
45039
- value: String(value)
45040
- });
45041
- }
45042
- const result = Array.from(Object.values(groups)).sort((a2, b2) => sortWord(a2.prefix, b2.prefix));
45043
- for (const group of result) {
45044
- group.attributes.sort((a2, b2) => sortWord(a2.suffix, b2.suffix));
45045
- }
45046
- return result;
45047
- };
45048
- const getAncestors = (_root, start) => {
45049
- const result = [];
45050
- if (!start)
45051
- return result;
45052
- for (let node2 = start; "parent" in node2; node2 = node2.parent) {
45053
- result.unshift(node2);
45054
- }
45055
- return result;
45056
- };
45057
- const SpanDetailPanelBody = () => {
45058
- var _a3;
45059
- const { state: { root: root2, selected, resourceMap, getQuickLinks }, dispatch } = useTraceViewer();
45060
- const ancestors = reactExports.useMemo(() => getAncestors(root2, selected), [root2, selected]);
45061
- const attributeGroups = reactExports.useMemo(() => getGroupedAttributes((selected == null ? void 0 : selected.span.attributes) ?? {}), [selected]);
45062
- const resourceAttributeGroups = reactExports.useMemo(() => {
45063
- const resourceName = selected == null ? void 0 : selected.span.resource;
45064
- if (!resourceName)
45065
- return [];
45066
- const resourceAttributes = resourceMap[resourceName];
45067
- if (!resourceAttributes)
45068
- return [];
45069
- return getGroupedAttributes(resourceAttributes);
45070
- }, [resourceMap, selected]);
45071
- if (!selected)
45072
- return null;
45073
- const { span } = selected;
45074
- const isEntrySpan = detectIsEntrySpan(selected);
45075
- return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [selected.isVercel ? jsxRuntimeExports.jsx(InfraSpanDescription, { node: selected }) : null, selected.isInstrumentationHint ? jsxRuntimeExports.jsx(InstrumentationHint, {}) : null, !selected.isInstrumentationHint && ancestors.length ? jsxRuntimeExports.jsx(DetailGroup, { className: styles.ancestorGroup, name: "Location", children: ancestors.map((node2) => jsxRuntimeExports.jsxs("button", { className: styles.ancestorNode, onClick: () => dispatch({
45076
- type: "select",
45077
- id: node2.span.spanId
45078
- }), type: "button", children: [jsxRuntimeExports.jsxs("div", { className: styles.ancestorText, children: [jsxRuntimeExports.jsx("span", { className: styles.ancestorName, children: node2.label || node2.span.name }), jsxRuntimeExports.jsx("span", { className: styles.ancestorDuration, children: formatDuration(node2.duration) })] }), jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: styles.ancestorLineContainer, children: jsxRuntimeExports.jsx("span", { className: clsx(styles.ancestorLine, getSpanColorClassName(node2)), style: {
45079
- left: percentage((node2.startTime - root2.startTime) / root2.duration),
45080
- width: percentage(node2.duration / root2.duration)
45081
- } }) })] }, `${selected.span.spanId}.${node2.span.spanId}`)) }) : null, isEntrySpan ? jsxRuntimeExports.jsx(EntrySpanLinks, { getQuickLinks, span: selected.span }) : null, ((_a3 = selected.events) == null ? void 0 : _a3.length) ? jsxRuntimeExports.jsx(DetailGroup, { name: "Events", children: selected.events.map((event) => jsxRuntimeExports.jsxs(reactExports.Fragment, { children: [jsxRuntimeExports.jsxs("dl", { className: styles.spanDetailPanelAttribute, children: [jsxRuntimeExports.jsx("dt", { className: styles.spanDetailPanelAttributeKey, children: event.event.name }), jsxRuntimeExports.jsx("dd", { className: styles.spanDetailPanelAttributeValue, children: formatDuration(event.timestamp - root2.startTime) })] }), Object.entries(event.event.attributes).map(([key, value]) => jsxRuntimeExports.jsx(DetailLine, { name: `${event.event.name}.${key}`, value }, key))] }, event.key)) }) : null, attributeGroups.length ? jsxRuntimeExports.jsx(DetailGroup, { name: "Attributes", children: attributeGroups.map((group) => jsxRuntimeExports.jsx(reactExports.Fragment, { children: group.attributes.map(({ key, value }) => jsxRuntimeExports.jsx(DetailLine, { name: key, value }, key)) }, group.prefix)) }) : null, resourceAttributeGroups.length ? jsxRuntimeExports.jsx(DetailGroup, { name: "Resource", children: resourceAttributeGroups.map((group) => jsxRuntimeExports.jsx(reactExports.Fragment, { children: group.attributes.map(({ key, value }) => jsxRuntimeExports.jsx(DetailLine, { name: key, value }, key)) }, group.prefix)) }) : null, selected.isInstrumentationHint ? null : jsxRuntimeExports.jsxs(DetailGroup, { name: "Library", children: [jsxRuntimeExports.jsx(DetailLine, { name: "name", value: span.library.name }), span.library.version ? jsxRuntimeExports.jsx(DetailLine, { name: "version", value: span.library.version }) : null] })] });
45082
- };
45083
- function SpanDetailPanel({ attached = false }) {
45084
- const { state: { selected, isMobile }, dispatch } = useTraceViewer();
45085
- const customPanelComponent = useCustomPanelComponent();
45086
- if (!selected)
45087
- return null;
45088
- const { span } = selected;
45089
- return jsxRuntimeExports.jsxs("div", { className: clsx(styles.spanDetailPanel, isMobile && styles.mobile), children: [attached && !isMobile ? jsxRuntimeExports.jsx(PanelResizer, {}) : null, jsxRuntimeExports.jsx("div", { className: styles.spanDetailPanelTop, children: jsxRuntimeExports.jsxs("div", { className: styles.spanDetailPanelTopInfo, children: [jsxRuntimeExports.jsx("span", { className: styles.spanDetailPanelName, title: span.name, children: span.name }), jsxRuntimeExports.jsxs("div", { className: styles.spanDetailPanelCorner, children: [selected.isInstrumentationHint ? null : jsxRuntimeExports.jsx("span", { className: styles.spanDetailPanelDuration, children: formatDuration(selected.duration) }), jsxRuntimeExports.jsx("div", { className: styles.spanDetailPanelCloseVerticalRule }), jsxRuntimeExports.jsx("button", { "aria-label": "Close Span Details", className: styles.spanDetailPanelClose, onClick: () => dispatch({
45090
- type: "deselect"
45091
- }), type: "button", children: jsxRuntimeExports.jsx(IconCross, { color: "gray-700", size: 20 }) })] })] }) }), jsxRuntimeExports.jsx("div", { className: clsx("flex gap-3", styles.spanDetailPanelBody), children: customPanelComponent || jsxRuntimeExports.jsx(SpanDetailPanelBody, {}) })] });
45092
- }
45093
44730
  const EXPANDED_STORAGE_KEY_PREFIX = "vc-trace-span-exp:";
45094
44731
  function DetailGroup({ name: name2, className = "", children: children2 }) {
45095
44732
  const [isExpanded, setIsExpanded] = reactExports.useState(() => {
@@ -45106,77 +44743,7 @@ function DetailGroup({ name: name2, className = "", children: children2 }) {
45106
44743
  }, [name2]);
45107
44744
  return jsxRuntimeExports.jsxs("div", { className: clsx(styles.detailGroup, isExpanded ? styles.expanded : styles.collapsed, className), children: [jsxRuntimeExports.jsxs("button", { className: styles.detailHeading, onClick: toggleExpanded, type: "button", children: [jsxRuntimeExports.jsx("span", { children: name2 }), jsxRuntimeExports.jsx(IconChevronDown, {})] }), isExpanded ? children2 : null] });
45108
44745
  }
45109
- const CommonHttpVerbs = /* @__PURE__ */ new Set([
45110
- "OPTIONS",
45111
- "HEAD",
45112
- "GET",
45113
- "PUT",
45114
- "POST",
45115
- "DELETE"
45116
- ]);
45117
- const KnownSpans = {
45118
- "Resolve Deployment": `How long it took Vercel's routing layer to retrieve details for the deployment.`,
45119
- "Resolve Cache": `How long it took Vercel's routing layer to check for a cached function invocation.`,
45120
- "Resolve Route": `How long it took Vercel's routing layer to resolve routing rules, including redirects and rewrites.`,
45121
- "Invoke Middleware": `How long it took this middleware to start and run user code.`,
45122
- "Invoke Function": `How long it took this Vercel Function to start and run user code.`,
45123
- waitUntil: `How long it took to run user code inside of waitUntil.`,
45124
- "Start VM": `How long it took to start the Virtual Machine which contains the Vercel Function.`,
45125
- "Spawn Node.js": `How long it took the Virtual Machine to start the Node.js runtime.`,
45126
- "Spawn Python": `How long it took the Virtual Machine to start the Python runtime.`,
45127
- "Init User Code": `How long it took to import the user code and run any globally-scoped code.`
45128
- };
45129
- const ColdStartSpanNames = /* @__PURE__ */ new Set([
45130
- "Start VM",
45131
- "Spawn Node.js",
45132
- "Spawn Python",
45133
- "Init User Code"
45134
- ]);
45135
- const getRegion = (node2) => {
45136
- if (!node2 || !("span" in node2)) {
45137
- return null;
45138
- }
45139
- const attr = node2.span.attributes;
45140
- const region = attr["vercel.region"] || attr["vercel.function.region"];
45141
- if (region)
45142
- return String(region);
45143
- return null;
45144
- };
45145
- const getNote = (node2) => {
45146
- const { name: name2 } = node2.span;
45147
- const region = getRegion(node2);
45148
- const parentRegion = getRegion(node2.parent);
45149
- if (node2.span.attributes["vercel.middleware.internal"] === "true") {
45150
- return "The Vercel Toolbar created this middleware.";
45151
- } else if (ColdStartSpanNames.has(name2) || name2 === "Invoke Function" && node2.children.some((x2) => ColdStartSpanNames.has(x2.span.name))) {
45152
- return "This function encountered a cold start.";
45153
- } else if (region && parentRegion && region !== parentRegion) {
45154
- return "This request was routed across regions.";
45155
- }
45156
- return null;
45157
- };
45158
- const detectIsEntrySpan = (node2) => {
45159
- if (!node2.isVercel)
45160
- return false;
45161
- const { name: name2 } = node2.span;
45162
- const spaceIndex = name2.indexOf(" ");
45163
- if (spaceIndex === -1)
45164
- return false;
45165
- const firstWord = name2.substring(0, spaceIndex);
45166
- return CommonHttpVerbs.has(firstWord);
45167
- };
45168
- function InfraSpanDescription({ node: node2 }) {
45169
- const { name: name2 } = node2.span;
45170
- let description = KnownSpans[name2];
45171
- if (!description && detectIsEntrySpan(node2)) {
45172
- description = `How long it took for Vercel to process the request and send the response.`;
45173
- }
45174
- if (!description)
45175
- return null;
45176
- const note2 = getNote(node2);
45177
- return jsxRuntimeExports.jsx(DetailGroup, { name: "What is this?", children: jsxRuntimeExports.jsxs("div", { className: styles.infraSpanDescription, children: [jsxRuntimeExports.jsx("span", { children: description }), note2 ? jsxRuntimeExports.jsx(Note, { children: note2 }) : note2] }) });
45178
- }
45179
- const EntrySpanLinks = reactExports.memo(function EntrySpanLinks2({ getQuickLinks, span }) {
44746
+ reactExports.memo(function EntrySpanLinks({ getQuickLinks, span }) {
45180
44747
  const links = getQuickLinks(span);
45181
44748
  if (!links.length)
45182
44749
  return null;
@@ -45200,70 +44767,6 @@ function EntrySpanLink({ name: name2, link: linkPromise }) {
45200
44767
  const link2 = usePromise(linkPromise);
45201
44768
  return jsxRuntimeExports.jsxs(Link, { as: link2 ? void 0 : "span", className: clsx(styles.spanDetailPanelAttribute, styles.spanDetailPanelQuickLink), href: (link2 == null ? void 0 : link2.href) || "", children: [jsxRuntimeExports.jsx("span", { className: styles.spanDetailPanelAttributeKey, children: name2 }), jsxRuntimeExports.jsx("span", { className: clsx(styles.spanDetailPanelAttributeValue, styles.spanDetailPanelQuickLinkLabel), children: link2 ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [link2.label, link2.icon || jsxRuntimeExports.jsx(IconExternalSmall, { color: "gray-900" })] }) : jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Skeleton, { height: 18, width: 32 + name2.length * 8 }), jsxRuntimeExports.jsx(Skeleton, { height: 18, rounded: true, width: 18 })] }) })] });
45202
44769
  }
45203
- function InstrumentationHint() {
45204
- return jsxRuntimeExports.jsx(DetailGroup, { name: "What is this?", children: jsxRuntimeExports.jsxs("div", { className: styles.infraSpanDescription, children: [jsxRuntimeExports.jsx("span", { children: `You can visualize your application's spans alongside Vercel's spans in this viewer.` }), jsxRuntimeExports.jsx(ButtonLink, { href: "https://vercel.com/docs/session-tracing#adding-custom-spans", size: "small", target: "_blank", children: "Get Started" })] }) });
45205
- }
45206
- function DetailLine({ name: name2, value }) {
45207
- return jsxRuntimeExports.jsxs("dl", { className: styles.spanDetailPanelAttribute, children: [jsxRuntimeExports.jsx("dt", { className: styles.spanDetailPanelAttributeKey, children: name2 }), jsxRuntimeExports.jsx("dd", { className: styles.spanDetailPanelAttributeValue, title: String(value), children: String(value) })] });
45208
- }
45209
- function PanelResizer() {
45210
- const { state: { panelWidth }, dispatch } = useTraceViewer();
45211
- const gestureRef = reactExports.useRef({
45212
- start: {
45213
- x: 0,
45214
- width: panelWidth
45215
- },
45216
- x: 0,
45217
- width: panelWidth,
45218
- isHeld: false
45219
- });
45220
- gestureRef.current.width = panelWidth;
45221
- const onPointerDown = reactExports.useCallback((event) => {
45222
- if (event.pointerType !== "mouse")
45223
- return;
45224
- event.preventDefault();
45225
- const g2 = gestureRef.current;
45226
- g2.start.x = event.clientX;
45227
- g2.x = event.clientX;
45228
- g2.start.width = g2.width;
45229
- g2.isHeld = true;
45230
- }, []);
45231
- const onDoubleClick = reactExports.useCallback(() => {
45232
- dispatch({
45233
- type: "setPanelWidth",
45234
- width: initialState.panelWidth
45235
- });
45236
- }, [dispatch]);
45237
- reactExports.useEffect(() => {
45238
- let nextFrame = 0;
45239
- const onFrame = () => {
45240
- const g2 = gestureRef.current;
45241
- const width = g2.start.width + g2.start.x - g2.x;
45242
- dispatch({
45243
- type: "setPanelWidth",
45244
- width
45245
- });
45246
- };
45247
- const onPointerMove = (event) => {
45248
- if (!gestureRef.current.isHeld)
45249
- return;
45250
- event.preventDefault();
45251
- gestureRef.current.x = event.clientX;
45252
- cancelAnimationFrame(nextFrame);
45253
- nextFrame = requestAnimationFrame(onFrame);
45254
- };
45255
- const onPointerUp = () => {
45256
- gestureRef.current.isHeld = false;
45257
- };
45258
- window.addEventListener("pointermove", onPointerMove);
45259
- window.addEventListener("pointerup", onPointerUp);
45260
- return () => {
45261
- window.removeEventListener("pointermove", onPointerMove);
45262
- window.removeEventListener("pointerup", onPointerUp);
45263
- };
45264
- }, [dispatch]);
45265
- return jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: styles.spanDetailPanelResizer, onDoubleClick, onPointerDown });
45266
- }
45267
44770
  function useImmediateStyle(ref) {
45268
44771
  const styleRef = reactExports.useRef({});
45269
44772
  const setStyle = reactExports.useCallback((propertyName, value) => {
@@ -45298,7 +44801,7 @@ const useDpi = () => {
45298
44801
  return dpi;
45299
44802
  };
45300
44803
  const padding = TIMELINE_PADDING;
45301
- const MiniMap = reactExports.memo(function MiniMap2({ timelineRef, rows, scale }) {
44804
+ reactExports.memo(function MiniMap({ timelineRef, rows, scale }) {
45302
44805
  const { state: { root: root2, baseScale, timelineWidth, width: fullWidth, scrollbarWidth } } = useTraceViewer();
45303
44806
  const mapWidth = fullWidth + TIMELINE_PADDING * 2;
45304
44807
  const dpi = useDpi();
@@ -45431,30 +44934,19 @@ const MiniMap = reactExports.memo(function MiniMap2({ timelineRef, rows, scale }
45431
44934
  height: MAP_HEIGHT - 4
45432
44935
  } })] });
45433
44936
  });
45434
- function deserializeChunkText(text2) {
45435
- try {
45436
- const parsed = JSON.parse(text2);
45437
- if (typeof parsed === "string") {
45438
- return parsed;
45439
- }
45440
- return JSON.stringify(parsed, null, 2);
45441
- } catch {
45442
- return text2;
45443
- }
44937
+ const SidebarDataContext = reactExports.createContext(null);
44938
+ SidebarDataContext.displayName = "SidebarDataContext";
44939
+ function SidebarDataProvider({ value, children: children2 }) {
44940
+ return jsxRuntimeExports.jsx(SidebarDataContext.Provider, { value, children: children2 });
45444
44941
  }
45445
- function parseChunkData(text2) {
45446
- try {
45447
- return JSON.parse(text2);
45448
- } catch {
45449
- return text2;
45450
- }
44942
+ function useSidebarDataOptional() {
44943
+ return reactExports.useContext(SidebarDataContext);
45451
44944
  }
45452
44945
  const ChunkRow = ReactExports.memo(function ChunkRow2({ chunk, index: index2 }) {
45453
- const parsed = parseChunkData(chunk.text);
45454
- return jsxRuntimeExports.jsxs("div", { className: "text-[11px] rounded-md border p-3", style: {
44946
+ return jsxRuntimeExports.jsx("div", { className: "text-[11px] rounded-md border p-3", style: {
45455
44947
  borderColor: "var(--ds-gray-300)",
45456
44948
  backgroundColor: "var(--ds-gray-100)"
45457
- }, children: [jsxRuntimeExports.jsxs("span", { className: "select-none mr-2", style: { color: "var(--ds-gray-500)" }, children: ["[", index2, "]"] }), typeof parsed === "string" ? jsxRuntimeExports.jsx("span", { className: "whitespace-pre-wrap break-words", style: { color: "var(--ds-gray-1000)" }, children: deserializeChunkText(parsed) }) : jsxRuntimeExports.jsx(DataInspector, { data: parsed, expandLevel: 1 })] });
44949
+ }, children: jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2", children: [jsxRuntimeExports.jsxs("span", { className: "select-none pt-px", style: { color: "var(--ds-gray-500)" }, children: ["[", index2, "]"] }), jsxRuntimeExports.jsx("div", { className: "min-w-0 flex-1", children: typeof chunk.value === "string" ? jsxRuntimeExports.jsx("span", { className: "whitespace-pre-wrap break-words", style: { color: "var(--ds-gray-1000)" }, children: chunk.value }) : jsxRuntimeExports.jsx(DataInspector, { data: chunk.value, expandLevel: 1 }) })] }) });
45458
44950
  });
45459
44951
  function StreamSkeleton() {
45460
44952
  return jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3 animate-in fade-in", children: [jsxRuntimeExports.jsx(Skeleton$1, { style: { width: 120, height: 16, borderRadius: 4 } }), [1, 2, 3, 4].map((i) => jsxRuntimeExports.jsx(Skeleton$1, { style: { height: 56, borderRadius: 6 } }, i))] });
@@ -45485,6 +44977,501 @@ function StreamViewer({ streamId: _streamId, chunks, isLive, error, isLoading, o
45485
44977
  color: "var(--ds-gray-600)"
45486
44978
  }, 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 } }) })] });
45487
44979
  }
44980
+ function computeRootBounds(spans) {
44981
+ let minStart = Number.POSITIVE_INFINITY;
44982
+ let maxEnd = Number.NEGATIVE_INFINITY;
44983
+ for (const span of spans) {
44984
+ const s2 = getHighResInMs(span.startTime);
44985
+ const e = getHighResInMs(span.endTime);
44986
+ if (s2 < minStart)
44987
+ minStart = s2;
44988
+ if (e > maxEnd)
44989
+ maxEnd = e;
44990
+ }
44991
+ if (!Number.isFinite(minStart) || !Number.isFinite(maxEnd)) {
44992
+ return { startTime: 0, endTime: 1, duration: 1 };
44993
+ }
44994
+ const duration2 = Math.max(maxEnd - minStart, 1);
44995
+ return { startTime: minStart, endTime: maxEnd, duration: duration2 };
44996
+ }
44997
+ function buildTimeCompression(_spans, viewStart, viewEnd) {
44998
+ const range = viewEnd - viewStart;
44999
+ return {
45000
+ isCompressed: false,
45001
+ toVisual(time2) {
45002
+ if (range <= 0)
45003
+ return 0;
45004
+ return Math.min(Math.max((time2 - viewStart) / range, 0), 1);
45005
+ },
45006
+ fromVisual(fraction) {
45007
+ return viewStart + fraction * range;
45008
+ }
45009
+ };
45010
+ }
45011
+ const NICE_INTERVALS = [
45012
+ 1,
45013
+ 2,
45014
+ 5,
45015
+ 10,
45016
+ 20,
45017
+ 50,
45018
+ 100,
45019
+ 200,
45020
+ 500,
45021
+ 1e3,
45022
+ 2e3,
45023
+ 5e3,
45024
+ 1e4,
45025
+ 2e4,
45026
+ 5e4,
45027
+ 1e5,
45028
+ 2e5,
45029
+ 5e5,
45030
+ 1e6,
45031
+ 2e6,
45032
+ 5e6,
45033
+ 1e7,
45034
+ 2e7,
45035
+ 5e7,
45036
+ 1e8,
45037
+ 2e8,
45038
+ 5e8,
45039
+ 1e9,
45040
+ 2e9,
45041
+ 5e9
45042
+ ];
45043
+ const MAX_MARKERS = 8;
45044
+ function pickInterval(viewDuration, maxTicks) {
45045
+ for (const interval of NICE_INTERVALS) {
45046
+ if (viewDuration / interval <= maxTicks)
45047
+ return interval;
45048
+ }
45049
+ return NICE_INTERVALS[NICE_INTERVALS.length - 1];
45050
+ }
45051
+ function computeTimeMarkers(viewDuration, offset2) {
45052
+ if (viewDuration <= 0)
45053
+ return [];
45054
+ const maxTicks = 6;
45055
+ const interval = pickInterval(viewDuration, maxTicks);
45056
+ const firstTick = Math.ceil(offset2 / interval) * interval;
45057
+ const markers2 = [];
45058
+ for (let t = firstTick; t <= offset2 + viewDuration; t += interval) {
45059
+ const position2 = (t - offset2) / viewDuration;
45060
+ if (position2 < -0.01 || position2 > 1.01)
45061
+ continue;
45062
+ markers2.push({
45063
+ position: Math.min(Math.max(position2, 0), 1),
45064
+ label: formatDuration(Math.abs(t), true)
45065
+ });
45066
+ if (markers2.length >= MAX_MARKERS)
45067
+ break;
45068
+ }
45069
+ return markers2;
45070
+ }
45071
+ function computeCompressedTimeMarkers(compression, viewStart, viewEnd, rootStart) {
45072
+ const viewDuration = viewEnd - viewStart;
45073
+ if (viewDuration <= 0)
45074
+ return [];
45075
+ const maxTicks = 6;
45076
+ const interval = pickInterval(viewDuration, maxTicks);
45077
+ const offset2 = viewStart - rootStart;
45078
+ const firstTick = Math.ceil(offset2 / interval) * interval;
45079
+ const markers2 = [];
45080
+ for (let t = firstTick; t <= offset2 + viewDuration; t += interval) {
45081
+ const absTime = rootStart + t;
45082
+ const position2 = compression.toVisual(absTime);
45083
+ if (position2 < -0.01 || position2 > 1.01)
45084
+ continue;
45085
+ markers2.push({
45086
+ position: Math.min(Math.max(position2, 0), 1),
45087
+ label: formatDuration(Math.abs(t), true)
45088
+ });
45089
+ if (markers2.length >= MAX_MARKERS)
45090
+ break;
45091
+ }
45092
+ return markers2;
45093
+ }
45094
+ function computeSpanGaps(spans, compression) {
45095
+ const gaps = [];
45096
+ for (let i = 0; i < spans.length - 1; i++) {
45097
+ const endTime = getHighResInMs(spans[i].endTime);
45098
+ const startTime = getHighResInMs(spans[i + 1].startTime);
45099
+ const gapMs = startTime - endTime;
45100
+ if (gapMs <= 0)
45101
+ continue;
45102
+ const leftFrac = compression.toVisual(endTime);
45103
+ const rightFrac = compression.toVisual(startTime);
45104
+ if (rightFrac - leftFrac < 1e-3)
45105
+ continue;
45106
+ gaps.push({ gapMs, leftFrac, rightFrac, rowIndex: i });
45107
+ }
45108
+ return gaps;
45109
+ }
45110
+ const RESOURCE_COLORS = {
45111
+ run: { bar: "var(--ds-blue-700)", errorBar: "var(--ds-red-700)" },
45112
+ step: { bar: "var(--ds-green-700)", errorBar: "var(--ds-red-700)" },
45113
+ hook: { bar: "var(--ds-amber-700)", errorBar: "var(--ds-red-700)" },
45114
+ sleep: { bar: "var(--ds-purple-700)", errorBar: "var(--ds-red-700)" },
45115
+ default: { bar: "var(--ds-gray-500)", errorBar: "var(--ds-red-700)" }
45116
+ };
45117
+ function getResourceColor(resource) {
45118
+ return RESOURCE_COLORS[resource] ?? RESOURCE_COLORS.default;
45119
+ }
45120
+ function clampFraction(value) {
45121
+ return Math.max(0, Math.min(1, value));
45122
+ }
45123
+ function timeToFraction(time2, spanStart, spanDuration2) {
45124
+ if (spanDuration2 <= 0)
45125
+ return 0;
45126
+ return clampFraction((time2 - spanStart) / spanDuration2);
45127
+ }
45128
+ function sortedEventMarks(events, relevantNames) {
45129
+ return events.filter((e) => relevantNames.includes(e.name)).map((e) => ({ time: getHighResInMs(e.timestamp), type: e.name })).sort((a2, b2) => a2.time - b2.time);
45130
+ }
45131
+ function computeStepSegmentsFromSpan(startMs, duration2, events) {
45132
+ const segments = [];
45133
+ if (duration2 <= 0)
45134
+ return segments;
45135
+ const marks = sortedEventMarks(events, [
45136
+ "step_started",
45137
+ "step_retrying",
45138
+ "step_failed",
45139
+ "step_completed"
45140
+ ]);
45141
+ if (marks.length === 0) {
45142
+ segments.push({ startFraction: 0, endFraction: 1, status: "running" });
45143
+ return segments;
45144
+ }
45145
+ const firstFraction = timeToFraction(marks[0].time, startMs, duration2);
45146
+ if (firstFraction > 1e-3) {
45147
+ segments.push({
45148
+ startFraction: 0,
45149
+ endFraction: firstFraction,
45150
+ status: "queued"
45151
+ });
45152
+ }
45153
+ for (let i = 0; i < marks.length; i++) {
45154
+ const mark2 = marks[i];
45155
+ const markFrac = timeToFraction(mark2.time, startMs, duration2);
45156
+ const nextMark = marks[i + 1];
45157
+ const nextFrac = nextMark ? timeToFraction(nextMark.time, startMs, duration2) : 1;
45158
+ if (mark2.type === "step_started") {
45159
+ if (i === marks.length - 1) {
45160
+ segments.push({
45161
+ startFraction: markFrac,
45162
+ endFraction: 1,
45163
+ status: "succeeded"
45164
+ });
45165
+ } else {
45166
+ const nextType = nextMark.type;
45167
+ const attemptStatus = nextType === "step_retrying" || nextType === "step_failed" ? "failed" : nextType === "step_completed" ? "succeeded" : "running";
45168
+ segments.push({
45169
+ startFraction: markFrac,
45170
+ endFraction: nextFrac,
45171
+ status: attemptStatus
45172
+ });
45173
+ }
45174
+ } else if (mark2.type === "step_retrying") {
45175
+ segments.push({
45176
+ startFraction: markFrac,
45177
+ endFraction: nextFrac,
45178
+ status: "retrying"
45179
+ });
45180
+ } else if (mark2.type === "step_failed") {
45181
+ if (markFrac < 0.999) {
45182
+ segments.push({
45183
+ startFraction: markFrac,
45184
+ endFraction: 1,
45185
+ status: "failed"
45186
+ });
45187
+ }
45188
+ }
45189
+ }
45190
+ return segments;
45191
+ }
45192
+ function computeHookSegmentsFromSpan(startMs, duration2, events) {
45193
+ const segments = [];
45194
+ if (duration2 <= 0)
45195
+ return segments;
45196
+ const sorted = [...events].map((e) => ({ name: e.name, time: getHighResInMs(e.timestamp) })).sort((a2, b2) => a2.time - b2.time);
45197
+ const received = sorted.find((e) => e.name === "hook_received");
45198
+ const disposed = sorted.find((e) => e.name === "hook_disposed");
45199
+ if (!received && !disposed) {
45200
+ segments.push({ startFraction: 0, endFraction: 1, status: "waiting" });
45201
+ return segments;
45202
+ }
45203
+ const receivedFrac = received ? timeToFraction(received.time, startMs, duration2) : null;
45204
+ const disposedFrac = disposed ? timeToFraction(disposed.time, startMs, duration2) : null;
45205
+ if (receivedFrac !== null && receivedFrac > 1e-3) {
45206
+ segments.push({
45207
+ startFraction: 0,
45208
+ endFraction: receivedFrac,
45209
+ status: "waiting"
45210
+ });
45211
+ } else if (receivedFrac === null && disposedFrac !== null) {
45212
+ segments.push({
45213
+ startFraction: 0,
45214
+ endFraction: disposedFrac,
45215
+ status: "waiting"
45216
+ });
45217
+ }
45218
+ if (receivedFrac !== null) {
45219
+ segments.push({
45220
+ startFraction: receivedFrac,
45221
+ endFraction: disposedFrac ?? 1,
45222
+ status: "received"
45223
+ });
45224
+ }
45225
+ if (disposedFrac !== null && disposedFrac < 0.999) {
45226
+ segments.push({
45227
+ startFraction: disposedFrac,
45228
+ endFraction: 1,
45229
+ status: "succeeded"
45230
+ });
45231
+ }
45232
+ return segments;
45233
+ }
45234
+ function computeSleepSegmentsFromSpan(startMs, duration2, events) {
45235
+ const segments = [];
45236
+ if (duration2 <= 0)
45237
+ return segments;
45238
+ const completedTime = events.filter((e) => e.name === "wait_completed").map((e) => getHighResInMs(e.timestamp)).sort((a2, b2) => a2 - b2)[0];
45239
+ if (completedTime === void 0) {
45240
+ segments.push({ startFraction: 0, endFraction: 1, status: "sleeping" });
45241
+ return segments;
45242
+ }
45243
+ const completedFrac = timeToFraction(completedTime, startMs, duration2);
45244
+ if (completedFrac > 1e-3) {
45245
+ segments.push({
45246
+ startFraction: 0,
45247
+ endFraction: completedFrac,
45248
+ status: "sleeping"
45249
+ });
45250
+ }
45251
+ segments.push({
45252
+ startFraction: completedFrac,
45253
+ endFraction: 1,
45254
+ status: "succeeded"
45255
+ });
45256
+ return segments;
45257
+ }
45258
+ function computeRunSegmentsFromSpan(startMs, duration2, activeStartMs, events, attributes) {
45259
+ const segments = [];
45260
+ if (duration2 <= 0)
45261
+ return segments;
45262
+ const sorted = [...events].map((e) => ({ name: e.name, time: getHighResInMs(e.timestamp) })).sort((a2, b2) => a2.time - b2.time);
45263
+ const hasRunCreated = sorted.some((e) => e.name === "run_created");
45264
+ if (!hasRunCreated) {
45265
+ const runData = attributes == null ? void 0 : attributes.data;
45266
+ const runStatus = runData == null ? void 0 : runData.status;
45267
+ return computeV1RunSegments(startMs, duration2, activeStartMs, runStatus);
45268
+ }
45269
+ const failedEvent = sorted.find((e) => e.name === "run_failed");
45270
+ let cursor = 0;
45271
+ if (activeStartMs !== void 0 && activeStartMs > startMs) {
45272
+ const queuedFrac = timeToFraction(activeStartMs, startMs, duration2);
45273
+ if (queuedFrac > 1e-3) {
45274
+ segments.push({
45275
+ startFraction: 0,
45276
+ endFraction: queuedFrac,
45277
+ status: "queued"
45278
+ });
45279
+ cursor = queuedFrac;
45280
+ }
45281
+ }
45282
+ segments.push({
45283
+ startFraction: cursor,
45284
+ endFraction: 1,
45285
+ status: failedEvent ? "failed" : "running"
45286
+ });
45287
+ return segments;
45288
+ }
45289
+ function computeV1RunSegments(startMs, duration2, activeStartMs, runStatus) {
45290
+ const segments = [];
45291
+ let cursor = 0;
45292
+ if (activeStartMs !== void 0 && activeStartMs > startMs) {
45293
+ const queuedFrac = timeToFraction(activeStartMs, startMs, duration2);
45294
+ if (queuedFrac > 1e-3) {
45295
+ segments.push({
45296
+ startFraction: 0,
45297
+ endFraction: queuedFrac,
45298
+ status: "queued"
45299
+ });
45300
+ cursor = queuedFrac;
45301
+ }
45302
+ }
45303
+ segments.push({
45304
+ startFraction: cursor,
45305
+ endFraction: 1,
45306
+ status: runStatus === "failed" ? "failed" : "running"
45307
+ });
45308
+ return segments;
45309
+ }
45310
+ function computeSpanSegments(span) {
45311
+ const startMs = getHighResInMs(span.startTime);
45312
+ const endMs = getHighResInMs(span.endTime);
45313
+ const duration2 = endMs - startMs;
45314
+ const activeStartMs = span.activeStartTime ? getHighResInMs(span.activeStartTime) : void 0;
45315
+ switch (span.resource) {
45316
+ case "step":
45317
+ return computeStepSegmentsFromSpan(startMs, duration2, span.events);
45318
+ case "hook":
45319
+ return computeHookSegmentsFromSpan(startMs, duration2, span.events);
45320
+ case "sleep":
45321
+ return computeSleepSegmentsFromSpan(startMs, duration2, span.events);
45322
+ case "run":
45323
+ return computeRunSegmentsFromSpan(startMs, duration2, activeStartMs, span.events, span.attributes);
45324
+ default:
45325
+ return [];
45326
+ }
45327
+ }
45328
+ const QUEUED_BACKGROUND = "radial-gradient(circle, var(--ds-gray-400) 2px, transparent 2px) center / 20px 20px space no-repeat, var(--ds-gray-500)";
45329
+ const HATCHED_BACKGROUND = "repeating-linear-gradient(-45deg, var(--ds-gray-400) 0px, var(--ds-gray-400) 3px, var(--ds-gray-500) 3px, var(--ds-gray-500) 6px)";
45330
+ const SEGMENT_CONFIG = {
45331
+ queued: { style: { background: QUEUED_BACKGROUND } },
45332
+ retrying: {
45333
+ className: "box-border bg-gray-500"
45334
+ },
45335
+ waiting: { style: { background: HATCHED_BACKGROUND } },
45336
+ running: { className: "bg-blue-700" },
45337
+ failed: { className: "bg-red-700" },
45338
+ succeeded: { className: "bg-green-700" },
45339
+ sleeping: { className: "bg-amber-700" },
45340
+ received: { className: "bg-blue-700" }
45341
+ };
45342
+ const FIXED_BAR_WIDTH_PX = 4;
45343
+ const SEGMENT_GAP_PX = 1;
45344
+ const ROW_HEIGHT = 34;
45345
+ const CONTAINER_PAD_Y = 8;
45346
+ const END_CAP_HEIGHT = 8;
45347
+ const DeltaIndicator = reactExports.memo(function DeltaIndicator2({ leftFrac, rightFrac, label, rowIndex }) {
45348
+ const centerY = CONTAINER_PAD_Y + (rowIndex + 1) * ROW_HEIGHT;
45349
+ return jsxRuntimeExports.jsxs("div", { className: "absolute pointer-events-none", style: {
45350
+ left: `${leftFrac * 100}%`,
45351
+ width: `${(rightFrac - leftFrac) * 100}%`,
45352
+ top: centerY - END_CAP_HEIGHT / 2,
45353
+ height: END_CAP_HEIGHT
45354
+ }, children: [jsxRuntimeExports.jsx("div", { className: "absolute left-0 top-0 w-px h-full bg-amber-800" }), jsxRuntimeExports.jsx("div", { className: "absolute left-0 right-0 top-1/2 h-px bg-amber-800" }), jsxRuntimeExports.jsx("div", { className: "absolute right-0 top-0 w-px h-full bg-amber-800" }), jsxRuntimeExports.jsx("span", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-label-12 leading-none whitespace-nowrap rounded-xs px-1 py-0.5 text-gray-100 bg-amber-800", children: label })] });
45355
+ });
45356
+ const TimelineBar = reactExports.memo(function TimelineBar2({ span, compression, containerWidth, isSelected, onClick }) {
45357
+ var _a3;
45358
+ const startTime = getHighResInMs(span.startTime);
45359
+ const endTime = getHighResInMs(span.endTime);
45360
+ const totalDurationMs = endTime - startTime;
45361
+ const leftFrac = compression.toVisual(startTime);
45362
+ const rightFrac = compression.toVisual(endTime);
45363
+ const widthFrac = rightFrac - leftFrac;
45364
+ const leftPct = leftFrac * 100;
45365
+ const widthPct = widthFrac * 100;
45366
+ const pixelWidth = widthFrac * containerWidth;
45367
+ const isCompressed = containerWidth > 0 && pixelWidth < FIXED_BAR_WIDTH_PX;
45368
+ const [isRowHovered, setIsRowHovered] = reactExports.useState(false);
45369
+ const segments = reactExports.useMemo(() => computeSpanSegments(span), [span]);
45370
+ const finalSegment = segments[segments.length - 1];
45371
+ const workflowStatus = (_a3 = span.attributes.data) == null ? void 0 : _a3.status;
45372
+ const isErrored = span.status.code === 2 || workflowStatus === "failed";
45373
+ const colors = getResourceColor(span.resource);
45374
+ const fallbackColor = isErrored ? colors.errorBar ?? "var(--ds-red-700)" : colors.bar;
45375
+ const compressedSegmentStatus = isErrored ? "failed" : span.resource === "hook" ? "received" : finalSegment == null ? void 0 : finalSegment.status;
45376
+ const compressedSegmentStyle = compressedSegmentStatus === "queued" ? { background: "var(--ds-gray-500)" } : compressedSegmentStatus ? SEGMENT_CONFIG[compressedSegmentStatus].style : void 0;
45377
+ const compressedSegmentClassName = compressedSegmentStatus ? SEGMENT_CONFIG[compressedSegmentStatus].className : void 0;
45378
+ const hasCompressedStatus = Boolean(compressedSegmentClassName || compressedSegmentStyle);
45379
+ const renderDurationLabel = (label) => jsxRuntimeExports.jsx("span", { className: "pointer-events-none absolute inset-0 flex items-center justify-start overflow-hidden px-1 text-[10px] font-mono font-medium leading-none whitespace-nowrap text-left text-white tabular-nums", style: { textShadow: "0 1px 1px rgba(0, 0, 0, 0.45)" }, children: label });
45380
+ const getMinDurationLabelWidthPx = (label) => Math.max(40, label.length * 6 + 12);
45381
+ const totalDurationLabel = formatDuration(totalDurationMs);
45382
+ const showBarDurationLabel = isRowHovered && pixelWidth >= getMinDurationLabelWidthPx(totalDurationLabel);
45383
+ const barContent = isCompressed ? jsxRuntimeExports.jsx("div", { className: cn$4("relative h-4 rounded-[0.25rem] top-[3px]", compressedSegmentClassName), style: {
45384
+ width: "100%",
45385
+ background: hasCompressedStatus ? void 0 : fallbackColor,
45386
+ ...compressedSegmentStyle
45387
+ }, children: showBarDurationLabel ? renderDurationLabel(totalDurationLabel) : null }) : segments.length > 0 ? jsxRuntimeExports.jsx("div", { className: "relative w-full h-4 top-[3px]", children: segments.map((seg, i) => {
45388
+ const segPixelWidth = (seg.endFraction - seg.startFraction) * pixelWidth;
45389
+ const segDurationLabel = formatDuration((seg.endFraction - seg.startFraction) * totalDurationMs);
45390
+ const showSegmentDurationLabel = isRowHovered && segPixelWidth >= getMinDurationLabelWidthPx(segDurationLabel);
45391
+ const segStyle = seg.status === "queued" && segPixelWidth < 20 ? { background: "var(--ds-gray-500)" } : SEGMENT_CONFIG[seg.status].style;
45392
+ return jsxRuntimeExports.jsx("div", { className: cn$4("absolute h-full rounded-[0.25rem]", SEGMENT_CONFIG[seg.status].className), style: {
45393
+ left: `calc(${seg.startFraction * 100}% + ${SEGMENT_GAP_PX / 2}px)`,
45394
+ width: `calc(${(seg.endFraction - seg.startFraction) * 100}% - ${SEGMENT_GAP_PX}px)`,
45395
+ minWidth: 1,
45396
+ ...segStyle
45397
+ }, children: showSegmentDurationLabel ? renderDurationLabel(segDurationLabel) : null }, `${seg.status}-${i}`);
45398
+ }) }) : jsxRuntimeExports.jsx("div", { className: "relative h-4 rounded-[0.25rem] top-[3px]", style: {
45399
+ width: "100%",
45400
+ minWidth: 4,
45401
+ background: fallbackColor
45402
+ }, children: showBarDurationLabel ? renderDurationLabel(totalDurationLabel) : null });
45403
+ return jsxRuntimeExports.jsx("div", { role: "treeitem", "aria-selected": isSelected, "aria-expanded": isSelected, "aria-level": 1, className: cn$4("h-[34px] relative flex items-center hover:bg-gray-100 aria-selected:bg-gray-100 rounded-sm aria-selected:hover:bg-gray-200"), onMouseEnter: () => setIsRowHovered(true), onMouseLeave: () => setIsRowHovered(false), onClick, children: jsxRuntimeExports.jsx("div", { className: "absolute top-1.5 h-[22px] rounded-sm", style: {
45404
+ left: isCompressed ? `min(${leftPct}%, calc(100% - ${FIXED_BAR_WIDTH_PX}px))` : `${leftPct}%`,
45405
+ width: isCompressed ? `${FIXED_BAR_WIDTH_PX}px` : `max(${widthPct}%, 4px)`
45406
+ }, children: barContent }) });
45407
+ });
45408
+ function TimelineHeader({ viewStart, viewDuration, rootStart, compression, isZoomed, onResetZoom, hoverInfo: hoverInfo2 }) {
45409
+ const viewEnd = viewStart + viewDuration;
45410
+ const markers2 = reactExports.useMemo(() => compression.isCompressed ? computeCompressedTimeMarkers(compression, viewStart, viewEnd, rootStart) : computeTimeMarkers(viewDuration, viewStart - rootStart), [compression, viewStart, viewEnd, viewDuration, rootStart]);
45411
+ return jsxRuntimeExports.jsxs("div", { className: "relative bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-end px-2 pb-1", children: [jsxRuntimeExports.jsxs("div", { className: "relative h-full flex-1", children: [markers2.map((m2, i) => jsxRuntimeExports.jsx("span", { className: "absolute bottom-1 font-mono text-xs font-normal leading-4 text-gray-900 whitespace-nowrap", style: { left: `${m2.position * 100}%` }, children: m2.label }, i)), hoverInfo2 && jsxRuntimeExports.jsx("span", { className: "absolute top-1 pointer-events-none z-10 font-mono text-[11px] leading-4 text-gray-1000 whitespace-nowrap bg-background-100 border border-gray-alpha-400 rounded px-1 -translate-x-1/2", style: { left: `${hoverInfo2.fraction * 100}%` }, children: hoverInfo2.label })] }), isZoomed && jsxRuntimeExports.jsx("button", { type: "button", className: "absolute right-2 top-1/2 -translate-y-1/2 z-[5] flex items-center py-0.5 px-2 border border-gray-alpha-400 rounded-md bg-background-100 font-sans text-[11px] font-medium text-gray-900 cursor-pointer whitespace-nowrap transition-[color,border-color] duration-[120ms] ease-in-out hover:text-gray-1000 hover:border-gray-600", onClick: onResetZoom, children: "Reset zoom" })] });
45412
+ }
45413
+ function Timeline({ spans, compression, selectedId, onSelect, hoverFraction, altHeld = false }) {
45414
+ const containerRef = reactExports.useRef(null);
45415
+ const [containerWidth, setContainerWidth] = reactExports.useState(0);
45416
+ reactExports.useEffect(() => {
45417
+ const el = containerRef.current;
45418
+ if (!el)
45419
+ return;
45420
+ const ro2 = new ResizeObserver(([entry]) => {
45421
+ setContainerWidth(entry.contentRect.width);
45422
+ });
45423
+ ro2.observe(el);
45424
+ return () => ro2.disconnect();
45425
+ }, []);
45426
+ const gaps = reactExports.useMemo(() => computeSpanGaps(spans, compression), [spans, compression]);
45427
+ return jsxRuntimeExports.jsxs("div", { ref: containerRef, className: "relative py-2", children: [hoverFraction != null && jsxRuntimeExports.jsx("div", { className: "absolute top-0 bottom-0 w-px bg-gray-alpha-400 pointer-events-none z-10", style: { left: `${hoverFraction * 100}%` } }), spans.map((span) => jsxRuntimeExports.jsx(TimelineBar, { span, compression, containerWidth, isSelected: selectedId === span.spanId, onClick: () => onSelect(span.spanId) }, span.spanId)), altHeld && jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "absolute inset-0 pointer-events-none", children: gaps.map((gap) => jsxRuntimeExports.jsx(DeltaIndicator, { leftFrac: gap.leftFrac, rightFrac: gap.rightFrac, label: formatDuration(gap.gapMs, true), rowIndex: gap.rowIndex }, gap.rowIndex)) })] });
45428
+ }
45429
+ const ActiveSpanContext = reactExports.createContext(null);
45430
+ ActiveSpanContext.displayName = "ActiveSpanContext";
45431
+ function ActiveSpanProvider({ spans, children: children2 }) {
45432
+ var _a3;
45433
+ const [activeSpanId, setActiveSpanId] = reactExports.useState(((_a3 = spans[0]) == null ? void 0 : _a3.spanId) ?? null);
45434
+ reactExports.useEffect(() => {
45435
+ setActiveSpanId((currentSpanId) => {
45436
+ if (spans.length === 0) {
45437
+ return null;
45438
+ }
45439
+ if (currentSpanId) {
45440
+ const hasCurrentSpan = spans.some((span) => span.spanId === currentSpanId);
45441
+ if (hasCurrentSpan) {
45442
+ return currentSpanId;
45443
+ }
45444
+ }
45445
+ return spans[0].spanId;
45446
+ });
45447
+ }, [spans]);
45448
+ const activeSpan = reactExports.useMemo(() => {
45449
+ if (!activeSpanId) {
45450
+ return null;
45451
+ }
45452
+ return spans.find((span) => span.spanId === activeSpanId) ?? null;
45453
+ }, [activeSpanId, spans]);
45454
+ const setActiveSpan = reactExports.useCallback((spanId) => {
45455
+ setActiveSpanId(spanId);
45456
+ }, []);
45457
+ const clearActiveSpan = reactExports.useCallback(() => {
45458
+ setActiveSpanId(null);
45459
+ }, []);
45460
+ const value = reactExports.useMemo(() => ({
45461
+ activeSpanId,
45462
+ activeSpan,
45463
+ setActiveSpan,
45464
+ clearActiveSpan
45465
+ }), [activeSpanId, activeSpan, setActiveSpan, clearActiveSpan]);
45466
+ return jsxRuntimeExports.jsx(ActiveSpanContext.Provider, { value, children: children2 });
45467
+ }
45468
+ const useActiveSpan = () => {
45469
+ const context = reactExports.useContext(ActiveSpanContext);
45470
+ if (!context) {
45471
+ throw new Error("useActiveSpan must be used within ActiveSpanProvider");
45472
+ }
45473
+ return context;
45474
+ };
45488
45475
  const DEFAULT_PAGE_SIZE = 10;
45489
45476
  function cn(...inputs) {
45490
45477
  return twMerge(clsx(inputs));
@@ -48061,58 +48048,47 @@ export {
48061
48048
  Lock as a3,
48062
48049
  EVENT_DATA_REF_FIELDS as a4,
48063
48050
  clsx as a5,
48064
- useTraceViewer as a6,
48065
- styles as a7,
48066
- formatDurationForTimeline as a8,
48067
- formatWallClockTime as a9,
48068
- hydrateData as aA,
48069
- getWebRevivers as aB,
48070
- LIVE_UPDATE_INTERVAL_MS as aC,
48071
- fetchEvent as aD,
48072
- getEncryptionKeyForRun as aE,
48073
- StreamViewer as aF,
48074
- cn$4 as aG,
48075
- composeRefs as aH,
48076
- useFloating as aI,
48077
- offset as aJ,
48078
- shift as aK,
48079
- limitShift as aL,
48080
- flip as aM,
48081
- size as aN,
48082
- arrow as aO,
48083
- hide as aP,
48084
- autoUpdate as aQ,
48085
- cancelRun as aR,
48086
- reenqueueRun as aS,
48087
- wakeUpRun as aT,
48088
- resumeHook as aU,
48089
- recreateRun as aV,
48090
- useImmediateStyle as aa,
48091
- TIMELINE_PADDING as ab,
48092
- formatTimeSelection as ac,
48093
- MARKER_HEIGHT as ad,
48094
- ROW_HEIGHT as ae,
48095
- ROW_PADDING as af,
48096
- SEARCH_HEIGHT as ag,
48097
- getHighResInMs as ah,
48098
- getMsInHighRes as ai,
48099
- MARKER_NOTCH_HEIGHT as aj,
48100
- MAP_HEIGHT as ak,
48101
- SEARCH_GAP as al,
48102
- MiniMap as am,
48103
- SpanNodes as an,
48104
- SpanDetailPanel as ao,
48105
- TraceViewerContextProvider as ap,
48106
- hydrateResourceIOWithKey as aq,
48107
- hydrateResourceIO as ar,
48108
- fetchHook as as,
48109
- fetchStep as at,
48110
- hasEncryptedFields as au,
48111
- fetchStreams as av,
48112
- Slot as aw,
48113
- Slottable as ax,
48114
- buttonVariants as ay,
48115
- isEncryptedData as az,
48051
+ cn$4 as a6,
48052
+ getHighResInMs as a7,
48053
+ ActiveSpanProvider as a8,
48054
+ useActiveSpan as a9,
48055
+ limitShift as aA,
48056
+ flip as aB,
48057
+ size as aC,
48058
+ arrow as aD,
48059
+ hide as aE,
48060
+ autoUpdate as aF,
48061
+ cancelRun as aG,
48062
+ reenqueueRun as aH,
48063
+ wakeUpRun as aI,
48064
+ resumeHook as aJ,
48065
+ recreateRun as aK,
48066
+ useSidebarDataOptional as aa,
48067
+ computeRootBounds as ab,
48068
+ buildTimeCompression as ac,
48069
+ Timeline as ad,
48070
+ TimelineHeader as ae,
48071
+ SidebarDataProvider as af,
48072
+ hydrateResourceIOWithKey as ag,
48073
+ hydrateResourceIO as ah,
48074
+ fetchHook as ai,
48075
+ fetchStep as aj,
48076
+ hasEncryptedFields as ak,
48077
+ fetchStreams as al,
48078
+ Slot as am,
48079
+ Slottable as an,
48080
+ buttonVariants as ao,
48081
+ isEncryptedData as ap,
48082
+ hydrateData as aq,
48083
+ getWebRevivers as ar,
48084
+ LIVE_UPDATE_INTERVAL_MS as as,
48085
+ fetchEvent as at,
48086
+ getEncryptionKeyForRun as au,
48087
+ StreamViewer as av,
48088
+ composeRefs as aw,
48089
+ useFloating as ax,
48090
+ offset as ay,
48091
+ shift as az,
48116
48092
  TooltipContent as b,
48117
48093
  createLucideIcon as c,
48118
48094
  cn as d,