@workflow/web-shared 5.0.0-beta.6 → 5.0.0-beta.8

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 (200) hide show
  1. package/dist/components/error-boundary.js +1 -1
  2. package/dist/components/event-list-view.d.ts +12 -0
  3. package/dist/components/event-list-view.d.ts.map +1 -1
  4. package/dist/components/event-list-view.js +26 -13
  5. package/dist/components/hook-actions.js +1 -1
  6. package/dist/components/index.js +1 -1
  7. package/dist/components/new-trace-viewer/components/copy-button.js +2 -2
  8. package/dist/components/new-trace-viewer/components/event-list.js +3 -3
  9. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js +1 -1
  10. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js +1 -1
  11. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js +1 -1
  12. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js +1 -1
  13. package/dist/components/new-trace-viewer/components/split-pane.js +1 -1
  14. package/dist/components/new-trace-viewer/components/timeline.d.ts +1 -1
  15. package/dist/components/new-trace-viewer/components/timeline.d.ts.map +1 -1
  16. package/dist/components/new-trace-viewer/components/timeline.js +187 -103
  17. package/dist/components/new-trace-viewer/context.js +1 -1
  18. package/dist/components/new-trace-viewer/detail-panel.js +2 -2
  19. package/dist/components/new-trace-viewer/icons.js +1 -1
  20. package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +1 -1
  21. package/dist/components/new-trace-viewer/trace-viewer.js +53 -26
  22. package/dist/components/new-trace-viewer/types.js +1 -1
  23. package/dist/components/new-trace-viewer/util/constants.js +1 -1
  24. package/dist/components/new-trace-viewer/utils.d.ts +8 -4
  25. package/dist/components/new-trace-viewer/utils.d.ts.map +1 -1
  26. package/dist/components/new-trace-viewer/utils.js +31 -6
  27. package/dist/components/run-trace-view.js +1 -1
  28. package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
  29. package/dist/components/sidebar/attribute-panel.js +99 -73
  30. package/dist/components/sidebar/conversation-view.js +1 -1
  31. package/dist/components/sidebar/copyable-data-block.d.ts +1 -0
  32. package/dist/components/sidebar/copyable-data-block.d.ts.map +1 -1
  33. package/dist/components/sidebar/copyable-data-block.js +16 -15
  34. package/dist/components/sidebar/detail-card.d.ts +5 -6
  35. package/dist/components/sidebar/detail-card.d.ts.map +1 -1
  36. package/dist/components/sidebar/detail-card.js +32 -16
  37. package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -1
  38. package/dist/components/sidebar/entity-detail-panel.js +6 -3
  39. package/dist/components/sidebar/events-list.d.ts.map +1 -1
  40. package/dist/components/sidebar/events-list.js +21 -15
  41. package/dist/components/sidebar/resolve-hook-modal.js +1 -1
  42. package/dist/components/sidebar/sidebar-data-context.js +1 -1
  43. package/dist/components/stream-viewer.js +1 -1
  44. package/dist/components/trace-viewer/components/map.js +1 -1
  45. package/dist/components/trace-viewer/components/markers.js +1 -1
  46. package/dist/components/trace-viewer/components/node.js +1 -1
  47. package/dist/components/trace-viewer/components/search-input.js +1 -1
  48. package/dist/components/trace-viewer/components/search.js +1 -1
  49. package/dist/components/trace-viewer/components/span-content.js +1 -1
  50. package/dist/components/trace-viewer/components/span-detail-panel.js +1 -1
  51. package/dist/components/trace-viewer/components/span-segments.js +1 -1
  52. package/dist/components/trace-viewer/components/span-strategies.js +1 -1
  53. package/dist/components/trace-viewer/components/ui.js +1 -1
  54. package/dist/components/trace-viewer/components/zoom-button.js +1 -1
  55. package/dist/components/trace-viewer/components/zoom-icons.js +1 -1
  56. package/dist/components/trace-viewer/context.js +1 -1
  57. package/dist/components/trace-viewer/index.js +1 -1
  58. package/dist/components/trace-viewer/trace-viewer.js +1 -1
  59. package/dist/components/trace-viewer/types.js +1 -1
  60. package/dist/components/trace-viewer/util/constants.js +1 -1
  61. package/dist/components/trace-viewer/util/scrollbar-width.js +1 -1
  62. package/dist/components/trace-viewer/util/timing.js +1 -1
  63. package/dist/components/trace-viewer/util/tree.js +1 -1
  64. package/dist/components/trace-viewer/util/use-immediate-style.js +1 -1
  65. package/dist/components/trace-viewer/util/use-streaming-spans.js +1 -1
  66. package/dist/components/trace-viewer/util/use-trackpad-zoom.js +1 -1
  67. package/dist/components/trace-viewer/worker.js +1 -1
  68. package/dist/components/trace-viewer-new.js +1 -1
  69. package/dist/components/ui/alert.js +1 -1
  70. package/dist/components/ui/button.d.ts +10 -0
  71. package/dist/components/ui/button.d.ts.map +1 -0
  72. package/dist/components/ui/button.js +39 -0
  73. package/dist/components/ui/card.js +1 -1
  74. package/dist/components/ui/data-inspector.d.ts +1 -0
  75. package/dist/components/ui/data-inspector.d.ts.map +1 -1
  76. package/dist/components/ui/data-inspector.js +4 -9
  77. package/dist/components/ui/decrypt-button.js +1 -1
  78. package/dist/components/ui/error-card.js +1 -1
  79. package/dist/components/ui/error-stack-block.d.ts.map +1 -1
  80. package/dist/components/ui/error-stack-block.js +4 -18
  81. package/dist/components/ui/inspector-theme.js +1 -1
  82. package/dist/components/ui/load-more-button.js +1 -1
  83. package/dist/components/ui/menu-dropdown.js +1 -1
  84. package/dist/components/ui/skeleton.js +1 -1
  85. package/dist/components/ui/spinner.js +1 -1
  86. package/dist/components/ui/timestamp-tooltip.js +1 -1
  87. package/dist/components/workflow-trace-view.js +1 -1
  88. package/dist/components/workflow-traces/event-colors.js +1 -1
  89. package/dist/components/workflow-traces/trace-colors.js +1 -1
  90. package/dist/components/workflow-traces/trace-span-construction.js +1 -1
  91. package/dist/components/workflow-traces/trace-time-utils.js +1 -1
  92. package/dist/hooks/use-dark-mode.js +1 -1
  93. package/dist/hooks/use-reduced-motion.d.ts +10 -0
  94. package/dist/hooks/use-reduced-motion.d.ts.map +1 -0
  95. package/dist/hooks/use-reduced-motion.js +29 -0
  96. package/dist/index.js +1 -1
  97. package/dist/lib/event-analysis.js +1 -1
  98. package/dist/lib/event-materialization.js +1 -1
  99. package/dist/lib/hydration.js +1 -1
  100. package/dist/lib/stream-display.js +1 -1
  101. package/dist/lib/toast.js +1 -1
  102. package/dist/lib/trace-builder.js +1 -1
  103. package/dist/lib/utils.js +1 -1
  104. package/package.json +5 -5
  105. package/src/components/event-list-view.tsx +29 -13
  106. package/src/components/new-trace-viewer/components/copy-button.tsx +1 -1
  107. package/src/components/new-trace-viewer/components/event-list.tsx +2 -2
  108. package/src/components/new-trace-viewer/components/timeline.tsx +353 -192
  109. package/src/components/new-trace-viewer/detail-panel.tsx +1 -1
  110. package/src/components/new-trace-viewer/trace-viewer.tsx +93 -59
  111. package/src/components/new-trace-viewer/utils.ts +40 -8
  112. package/src/components/sidebar/attribute-panel.tsx +212 -235
  113. package/src/components/sidebar/copyable-data-block.tsx +49 -27
  114. package/src/components/sidebar/detail-card.tsx +119 -41
  115. package/src/components/sidebar/entity-detail-panel.tsx +28 -28
  116. package/src/components/sidebar/events-list.tsx +51 -79
  117. package/src/components/ui/button.tsx +61 -0
  118. package/src/components/ui/data-inspector.tsx +9 -18
  119. package/src/components/ui/error-stack-block.tsx +7 -26
  120. package/src/hooks/use-reduced-motion.ts +34 -0
  121. package/dist/components/error-boundary.js.map +0 -1
  122. package/dist/components/event-list-view.js.map +0 -1
  123. package/dist/components/hook-actions.js.map +0 -1
  124. package/dist/components/index.js.map +0 -1
  125. package/dist/components/new-trace-viewer/components/copy-button.js.map +0 -1
  126. package/dist/components/new-trace-viewer/components/event-list.js.map +0 -1
  127. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js.map +0 -1
  128. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js.map +0 -1
  129. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js.map +0 -1
  130. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js.map +0 -1
  131. package/dist/components/new-trace-viewer/components/split-pane.js.map +0 -1
  132. package/dist/components/new-trace-viewer/components/timeline.js.map +0 -1
  133. package/dist/components/new-trace-viewer/context.js.map +0 -1
  134. package/dist/components/new-trace-viewer/detail-panel.js.map +0 -1
  135. package/dist/components/new-trace-viewer/icons.js.map +0 -1
  136. package/dist/components/new-trace-viewer/trace-viewer.js.map +0 -1
  137. package/dist/components/new-trace-viewer/types.js.map +0 -1
  138. package/dist/components/new-trace-viewer/util/constants.js.map +0 -1
  139. package/dist/components/new-trace-viewer/utils.js.map +0 -1
  140. package/dist/components/run-trace-view.js.map +0 -1
  141. package/dist/components/sidebar/attribute-panel.js.map +0 -1
  142. package/dist/components/sidebar/conversation-view.js.map +0 -1
  143. package/dist/components/sidebar/copyable-data-block.js.map +0 -1
  144. package/dist/components/sidebar/detail-card.js.map +0 -1
  145. package/dist/components/sidebar/entity-detail-panel.js.map +0 -1
  146. package/dist/components/sidebar/events-list.js.map +0 -1
  147. package/dist/components/sidebar/resolve-hook-modal.js.map +0 -1
  148. package/dist/components/sidebar/sidebar-data-context.js.map +0 -1
  149. package/dist/components/stream-viewer.js.map +0 -1
  150. package/dist/components/trace-viewer/components/map.js.map +0 -1
  151. package/dist/components/trace-viewer/components/markers.js.map +0 -1
  152. package/dist/components/trace-viewer/components/node.js.map +0 -1
  153. package/dist/components/trace-viewer/components/search-input.js.map +0 -1
  154. package/dist/components/trace-viewer/components/search.js.map +0 -1
  155. package/dist/components/trace-viewer/components/span-content.js.map +0 -1
  156. package/dist/components/trace-viewer/components/span-detail-panel.js.map +0 -1
  157. package/dist/components/trace-viewer/components/span-segments.js.map +0 -1
  158. package/dist/components/trace-viewer/components/span-strategies.js.map +0 -1
  159. package/dist/components/trace-viewer/components/ui.js.map +0 -1
  160. package/dist/components/trace-viewer/components/zoom-button.js.map +0 -1
  161. package/dist/components/trace-viewer/components/zoom-icons.js.map +0 -1
  162. package/dist/components/trace-viewer/context.js.map +0 -1
  163. package/dist/components/trace-viewer/index.js.map +0 -1
  164. package/dist/components/trace-viewer/trace-viewer.js.map +0 -1
  165. package/dist/components/trace-viewer/types.js.map +0 -1
  166. package/dist/components/trace-viewer/util/constants.js.map +0 -1
  167. package/dist/components/trace-viewer/util/scrollbar-width.js.map +0 -1
  168. package/dist/components/trace-viewer/util/timing.js.map +0 -1
  169. package/dist/components/trace-viewer/util/tree.js.map +0 -1
  170. package/dist/components/trace-viewer/util/use-immediate-style.js.map +0 -1
  171. package/dist/components/trace-viewer/util/use-streaming-spans.js.map +0 -1
  172. package/dist/components/trace-viewer/util/use-trackpad-zoom.js.map +0 -1
  173. package/dist/components/trace-viewer/worker.js.map +0 -1
  174. package/dist/components/trace-viewer-new.js.map +0 -1
  175. package/dist/components/ui/alert.js.map +0 -1
  176. package/dist/components/ui/card.js.map +0 -1
  177. package/dist/components/ui/data-inspector.js.map +0 -1
  178. package/dist/components/ui/decrypt-button.js.map +0 -1
  179. package/dist/components/ui/error-card.js.map +0 -1
  180. package/dist/components/ui/error-stack-block.js.map +0 -1
  181. package/dist/components/ui/inspector-theme.js.map +0 -1
  182. package/dist/components/ui/load-more-button.js.map +0 -1
  183. package/dist/components/ui/menu-dropdown.js.map +0 -1
  184. package/dist/components/ui/skeleton.js.map +0 -1
  185. package/dist/components/ui/spinner.js.map +0 -1
  186. package/dist/components/ui/timestamp-tooltip.js.map +0 -1
  187. package/dist/components/workflow-trace-view.js.map +0 -1
  188. package/dist/components/workflow-traces/event-colors.js.map +0 -1
  189. package/dist/components/workflow-traces/trace-colors.js.map +0 -1
  190. package/dist/components/workflow-traces/trace-span-construction.js.map +0 -1
  191. package/dist/components/workflow-traces/trace-time-utils.js.map +0 -1
  192. package/dist/hooks/use-dark-mode.js.map +0 -1
  193. package/dist/index.js.map +0 -1
  194. package/dist/lib/event-analysis.js.map +0 -1
  195. package/dist/lib/event-materialization.js.map +0 -1
  196. package/dist/lib/hydration.js.map +0 -1
  197. package/dist/lib/stream-display.js.map +0 -1
  198. package/dist/lib/toast.js.map +0 -1
  199. package/dist/lib/trace-builder.js.map +0 -1
  200. package/dist/lib/utils.js.map +0 -1
@@ -38,6 +38,7 @@ import {
38
38
  inspectorThemeExtendedLight,
39
39
  inspectorThemeLight,
40
40
  } from './inspector-theme';
41
+ import { Button } from './button';
41
42
  import { Spinner } from './spinner';
42
43
 
43
44
  // ---------------------------------------------------------------------------
@@ -138,6 +139,7 @@ export const StreamClickContext = createContext<
138
139
  export type DecryptClickContextValue = {
139
140
  onDecrypt: () => void;
140
141
  isDecrypting: boolean;
142
+ hasEncryptedData?: boolean;
141
143
  };
142
144
 
143
145
  export const DecryptClickContext = createContext<
@@ -152,33 +154,22 @@ function EncryptedInlineLabel() {
152
154
  const ctx = useContext(DecryptClickContext);
153
155
  if (ctx) {
154
156
  return (
155
- <button
156
- type="button"
157
- className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] cursor-pointer"
158
- style={{
159
- backgroundColor: 'var(--ds-gray-100)',
160
- color: 'var(--ds-gray-700)',
161
- border: '1px solid var(--ds-gray-400)',
162
- fontStyle: 'italic',
163
- opacity: ctx.isDecrypting ? 0.6 : 1,
164
- }}
157
+ <Button
158
+ size="xs"
159
+ className="align-baseline gap-x-1"
165
160
  disabled={ctx.isDecrypting}
166
161
  onClick={(e) => {
167
162
  e.stopPropagation();
168
163
  ctx.onDecrypt();
169
164
  }}
170
- title="Click to decrypt"
171
165
  >
172
166
  {ctx.isDecrypting ? (
173
- <Spinner size={12} />
167
+ <Spinner size={10} />
174
168
  ) : (
175
- <Lock
176
- className="h-3 w-3"
177
- style={{ display: 'inline', flexShrink: 0 }}
178
- />
169
+ <Lock className="h-3 w-3" />
179
170
  )}
180
- <span>{ctx.isDecrypting ? 'Decrypting…' : 'Decrypt'}</span>
181
- </button>
171
+ <span>Decrypt</span>
172
+ </Button>
182
173
  );
183
174
  }
184
175
  return (
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
- import { AlertCircle, Copy } from 'lucide-react';
4
- import { useToast } from '../../lib/toast';
3
+ import { AlertCircle } from 'lucide-react';
4
+ import { CopyButton } from '../new-trace-viewer/components/copy-button';
5
5
 
6
6
  /**
7
7
  * Check whether `value` looks like a structured error object with a `stack`
@@ -43,7 +43,6 @@ export function ErrorStackBlock({
43
43
  }: {
44
44
  value: Record<string, unknown> & { stack: string };
45
45
  }) {
46
- const toast = useToast();
47
46
  const stack = value.stack;
48
47
  const message = typeof value.message === 'string' ? value.message : undefined;
49
48
  // V8's `Error.stack` already starts with `Name: message`, so when the
@@ -60,29 +59,11 @@ export function ErrorStackBlock({
60
59
  background: 'var(--ds-red-100)',
61
60
  }}
62
61
  >
63
- <button
64
- type="button"
65
- aria-label="Copy error"
66
- title="Copy"
67
- className="!absolute !right-2 !top-2 !flex !h-6 !w-6 !items-center !justify-center !rounded-md !border transition-transform transition-colors duration-100 hover:!bg-[var(--ds-red-200)] active:!scale-95"
68
- style={{
69
- borderColor: 'var(--ds-red-400)',
70
- background: 'var(--ds-red-100)',
71
- color: 'var(--ds-red-900)',
72
- }}
73
- onClick={() => {
74
- navigator.clipboard
75
- .writeText(copyText)
76
- .then(() => {
77
- toast.success('Copied to clipboard');
78
- })
79
- .catch(() => {
80
- toast.error('Failed to copy');
81
- });
82
- }}
83
- >
84
- <Copy size={12} />
85
- </button>
62
+ <CopyButton
63
+ copyText={copyText}
64
+ ariaLabel="Copy error"
65
+ className="absolute right-2 top-2 flex h-6 w-6 items-center justify-center rounded-md border border-red-400 bg-red-100 p-0 text-red-900 transition-transform transition-colors duration-100 hover:bg-red-200 active:scale-95"
66
+ />
86
67
 
87
68
  {title && (
88
69
  <div
@@ -0,0 +1,34 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+
5
+ const QUERY = '(prefers-reduced-motion: reduce)';
6
+
7
+ /**
8
+ * Hook that detects whether the user has requested reduced motion and reacts
9
+ * to changes. Mirrors the `prefers-reduced-motion: reduce` media query so
10
+ * components can skip or shorten animations for users with motion
11
+ * sensitivities (e.g. vestibular disorders).
12
+ *
13
+ * @returns `true` if the user prefers reduced motion, `false` otherwise
14
+ */
15
+ export const useReducedMotion = (): boolean => {
16
+ const [reduced, setReduced] = useState(() => {
17
+ if (typeof window === 'undefined' || !window.matchMedia) return false;
18
+ return window.matchMedia(QUERY).matches;
19
+ });
20
+
21
+ useEffect(() => {
22
+ if (typeof window === 'undefined' || !window.matchMedia) return;
23
+
24
+ const media = window.matchMedia(QUERY);
25
+ const onChange = (): void => setReduced(media.matches);
26
+
27
+ media.addEventListener('change', onChange);
28
+ onChange();
29
+
30
+ return () => media.removeEventListener('change', onChange);
31
+ }, []);
32
+
33
+ return reduced;
34
+ };
@@ -1 +0,0 @@
1
- {"version":3,"file":"error-boundary.js","sourceRoot":"","sources":["../../src/components/error-boundary.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAiB5C,MAAM,OAAO,aAAc,SAAQ,SAGlC;IACC,YAAY,KAAyB;QACnC,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,KAAK,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAChD,CAAC;IAED,MAAM,CAAC,wBAAwB,CAAC,KAAc;QAC5C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACnC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,SAAkB;QAClD,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;YAC3C,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,MAAM;QACJ,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YACxB,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACxB,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC7B,CAAC;YAED,mBAAmB;YACnB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;YACxE,MAAM,YAAY,GAAG,GAAG,EAAE,KAAK;gBAC7B,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,OAAO,GAAG,CAAC,KAAK,EAAE;gBAClC,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,IAAI,eAAe,CAAC,CAAC;YAEtC,OAAO,CACL,KAAC,SAAS,IACR,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,mBAAmB,EAC9C,OAAO,EAAE,YAAY,GACrB,CACH,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC7B,CAAC;CACF","sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport { Component } from 'react';\nimport { ErrorCard } from './ui/error-card';\n\nexport interface ErrorBoundaryProps {\n children: ReactNode;\n /** Optional fallback UI to render on error. When omitted, a default ErrorCard is shown. */\n fallback?: ReactNode;\n /** Optional title for the default error card (used when no fallback is provided) */\n title?: string;\n /** Optional callback when an error is caught */\n onCatch?: (error: unknown, retry: () => void) => void;\n}\n\nexport interface ErrorBoundaryState {\n hasError: boolean;\n error: unknown;\n}\n\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: unknown): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n retry(): void {\n this.setState({ hasError: false, error: null });\n }\n\n componentDidCatch(error: unknown, errorInfo: unknown): void {\n if (process.env.NODE_ENV === 'development') {\n console.error(error, errorInfo);\n }\n this.props.onCatch?.(error, () => this.retry());\n }\n\n render(): ReactNode {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n // Default error UI\n const err = this.state.error instanceof Error ? this.state.error : null;\n const errorDetails = err?.stack\n ? `${err.message}\\n\\n${err.stack}`\n : (err?.message ?? 'Unknown error');\n\n return (\n <ErrorCard\n title={this.props.title || 'An error occurred'}\n details={errorDetails}\n />\n );\n }\n\n return this.props.children;\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-list-view.js","sourceRoot":"","sources":["../../src/components/event-list-view.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { parseStepName, parseWorkflowName } from '@workflow/utils/parse-name';\nimport type { Event, WorkflowRun } from '@workflow/world';\nimport { Check, ChevronRight, Copy } from 'lucide-react';\nimport type { MouseEvent as ReactMouseEvent, ReactNode } from 'react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { Virtuoso, type VirtuosoHandle } from 'react-virtuoso';\nimport { isEncryptedMarker } from '../lib/hydration';\nimport { DecryptButton } from './ui/decrypt-button';\nimport { formatDuration } from '../lib/utils';\nimport { DataInspector, DecryptClickContext } from './ui/data-inspector';\nimport {\n ErrorStackBlock,\n isStructuredErrorWithStack,\n} from './ui/error-stack-block';\nimport { LoadMoreButton } from './ui/load-more-button';\nimport { MenuDropdown } from './ui/menu-dropdown';\nimport { Skeleton } from './ui/skeleton';\nimport { TimestampTooltip } from './ui/timestamp-tooltip';\n\n/**\n * Event types whose eventData contains an error field with a StructuredError.\n */\nconst ERROR_EVENT_TYPES = new Set([\n 'step_failed',\n 'step_retrying',\n 'run_failed',\n 'workflow_failed',\n]);\n\nconst BUTTON_RESET_STYLE: React.CSSProperties = {\n appearance: 'none',\n WebkitAppearance: 'none',\n border: 'none',\n background: 'transparent',\n};\nconst DOT_PULSE_ANIMATION =\n 'workflow-dot-pulse 1.25s cubic-bezier(0, 0, 0.2, 1) infinite';\n\n// ──────────────────────────────────────────────────────────────────────────\n// Helpers\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction formatEventTime(date: Date): string {\n return (\n date.toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false,\n }) +\n '.' +\n date.getMilliseconds().toString().padStart(3, '0')\n );\n}\n\nfunction formatEventType(eventType: Event['eventType']): string {\n return eventType\n .split('_')\n .map((word: string) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Event type → status color (small dot only)\n// ──────────────────────────────────────────────────────────────────────────\n\n/** Returns a CSS color using Geist design tokens for the status dot. */\nfunction getStatusDotColor(eventType: string): string {\n // Failed → red\n if (\n eventType === 'step_failed' ||\n eventType === 'run_failed' ||\n eventType === 'workflow_failed'\n ) {\n return 'var(--ds-red-700)';\n }\n // Cancelled → amber\n if (eventType === 'run_cancelled') {\n return 'var(--ds-amber-700)';\n }\n // Retrying → amber\n if (eventType === 'step_retrying') {\n return 'var(--ds-amber-700)';\n }\n // Completed/succeeded → green\n if (\n eventType === 'step_completed' ||\n eventType === 'run_completed' ||\n eventType === 'workflow_completed' ||\n eventType === 'hook_disposed' ||\n eventType === 'wait_completed'\n ) {\n return 'var(--ds-green-700)';\n }\n // Started/running → blue\n if (\n eventType === 'step_started' ||\n eventType === 'run_started' ||\n eventType === 'workflow_started' ||\n eventType === 'hook_received'\n ) {\n return 'var(--ds-blue-700)';\n }\n // Created/pending → gray\n return 'var(--ds-gray-600)';\n}\n\n/**\n * Build a map from correlationId (stepId) → display name using step_created\n * events, and parse the workflow name from the run.\n */\nfunction buildNameMaps(\n events: Event[] | null,\n run: WorkflowRun | null\n): {\n correlationNameMap: Map<string, string>;\n workflowName: string | null;\n} {\n const correlationNameMap = new Map<string, string>();\n\n // Map step correlationId (= stepId) → parsed step name from step_created events\n if (events) {\n for (const event of events) {\n if (event.eventType === 'step_created' && event.correlationId) {\n const stepName = event.eventData?.stepName ?? '';\n const parsed = parseStepName(String(stepName));\n correlationNameMap.set(\n event.correlationId,\n parsed?.shortName ?? stepName\n );\n }\n }\n }\n\n // Parse workflow name from run\n const workflowName = run?.workflowName\n ? (parseWorkflowName(run.workflowName)?.shortName ?? run.workflowName)\n : null;\n\n return { correlationNameMap, workflowName };\n}\n\ninterface DurationInfo {\n /** Time from created → started (ms) */\n queued?: number;\n /** Time from started → completed/failed/cancelled (ms) */\n ran?: number;\n}\n\n/**\n * Build a map from correlationId → duration info by diffing\n * created ↔ started (queued) and started ↔ completed/failed/cancelled (ran).\n * Also computes run-level durations under the key '__run__'.\n */\nfunction buildDurationMap(events: Event[]): Map<string, DurationInfo> {\n const createdTimes = new Map<string, number>();\n const startedTimes = new Map<string, number>();\n const durations = new Map<string, DurationInfo>();\n\n for (const event of events) {\n const ts = new Date(event.createdAt).getTime();\n const key = event.correlationId ?? '__run__';\n const type: string = event.eventType;\n\n // Track created times (first event for each correlation)\n if (type === 'step_created' || type === 'run_created') {\n createdTimes.set(key, ts);\n }\n\n // Track started times & compute queued duration\n if (\n type === 'step_started' ||\n type === 'run_started' ||\n type === 'workflow_started'\n ) {\n startedTimes.set(key, ts);\n // If no explicit created event was seen, use the started time as created\n if (!createdTimes.has(key)) {\n createdTimes.set(key, ts);\n }\n const createdAt = createdTimes.get(key);\n const info = durations.get(key) ?? {};\n if (createdAt !== undefined) {\n info.queued = ts - createdAt;\n }\n durations.set(key, info);\n }\n\n // Compute ran duration on terminal events\n if (\n type === 'step_completed' ||\n type === 'step_failed' ||\n type === 'run_completed' ||\n type === 'run_failed' ||\n type === 'run_cancelled' ||\n type === 'workflow_completed' ||\n type === 'workflow_failed' ||\n type === 'wait_completed' ||\n type === 'hook_disposed'\n ) {\n const startedAt = startedTimes.get(key);\n const info = durations.get(key) ?? {};\n if (startedAt !== undefined) {\n info.ran = ts - startedAt;\n }\n durations.set(key, info);\n }\n }\n\n return durations;\n}\n\n/** Check if a loaded eventData object contains any encrypted marker values. */\nfunction hasEncryptedValues(data: unknown): boolean {\n if (!data || typeof data !== 'object') return false;\n for (const val of Object.values(data as Record<string, unknown>)) {\n if (isEncryptedMarker(val)) return true;\n }\n return false;\n}\n\nfunction isRunLevel(eventType: string): boolean {\n return (\n eventType === 'run_created' ||\n eventType === 'run_started' ||\n eventType === 'run_completed' ||\n eventType === 'run_failed' ||\n eventType === 'run_cancelled' ||\n eventType === 'workflow_started' ||\n eventType === 'workflow_completed' ||\n eventType === 'workflow_failed'\n );\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Tree gutter — fixed-width, shows branch lines only for the selected group\n// ──────────────────────────────────────────────────────────────────────────\n\n/** Fixed gutter width: 20px root area + 16px for one branch lane */\nconst GUTTER_WIDTH = 36;\n/** X position of the single branch lane line */\nconst LANE_X = 20;\nconst ROOT_LINE_COLOR = 'var(--ds-gray-500)';\n\nfunction TreeGutter({\n isFirst,\n isLast,\n isRunLevel: isRun,\n statusDotColor,\n pulse = false,\n hasSelection,\n showBranch,\n showLaneLine,\n isLaneStart,\n isLaneEnd,\n continuationOnly = false,\n}: {\n isFirst: boolean;\n isLast: boolean;\n isRunLevel: boolean;\n statusDotColor?: string;\n pulse?: boolean;\n /** Whether any group is currently active (selected or hovered) */\n hasSelection: boolean;\n /** Whether to show a horizontal branch line for this row (event belongs to active group) */\n showBranch: boolean;\n /** Whether the vertical lane line passes through this row */\n showLaneLine: boolean;\n /** Whether the vertical lane line starts at this row (top clipped to 50%) */\n isLaneStart: boolean;\n /** Whether the vertical lane line ends at this row (bottom clipped to 50%) */\n isLaneEnd: boolean;\n continuationOnly?: boolean;\n}) {\n const dotSize = isRun ? 8 : 6;\n const dotLeft = isRun ? 5 : 6;\n const dotOpacity = hasSelection && !showBranch && !isRun ? 0.3 : 1;\n\n return (\n <div\n className=\"relative flex-shrink-0 self-stretch\"\n style={{\n width: GUTTER_WIDTH,\n minHeight: continuationOnly ? 0 : undefined,\n }}\n >\n {/* Root vertical line (leftmost, always visible) */}\n <div\n style={{\n position: 'absolute',\n left: 8,\n top: continuationOnly ? 0 : isFirst ? '50%' : 0,\n bottom: continuationOnly ? 0 : isLast ? '50%' : 0,\n width: 2,\n backgroundColor: ROOT_LINE_COLOR,\n zIndex: 0,\n }}\n />\n\n {!continuationOnly && (\n <>\n {/* Status dot on the root line for every event */}\n <div\n style={{\n position: 'absolute',\n left: dotLeft,\n top: '50%',\n transform: 'translateY(-50%)',\n width: dotSize,\n height: dotSize,\n zIndex: 2,\n }}\n >\n {/* Opaque backdrop ensures gutter lines never visually cut through dots */}\n <div\n style={{\n position: 'absolute',\n inset: 0,\n borderRadius: '50%',\n backgroundColor: 'var(--ds-background-100)',\n zIndex: 0,\n }}\n />\n {pulse && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n borderRadius: '50%',\n backgroundColor: statusDotColor,\n opacity: 0.75 * dotOpacity,\n animation: DOT_PULSE_ANIMATION,\n zIndex: 1,\n }}\n />\n )}\n <div\n style={{\n position: 'relative',\n width: '100%',\n height: '100%',\n borderRadius: '50%',\n backgroundColor: statusDotColor,\n opacity: dotOpacity,\n transition: 'opacity 150ms',\n zIndex: 2,\n }}\n />\n </div>\n\n {/* Horizontal branch from root to gutter edge (selected group events only) */}\n {showBranch && (\n <div\n style={{\n position: 'absolute',\n left: 9,\n top: '50%',\n width: GUTTER_WIDTH - 9,\n height: 2,\n backgroundColor: ROOT_LINE_COLOR,\n zIndex: 0,\n }}\n />\n )}\n </>\n )}\n\n {/* Vertical lane line connecting the selected group's events */}\n {showLaneLine && (\n <div\n style={{\n position: 'absolute',\n left: LANE_X,\n top: continuationOnly ? 0 : isLaneStart ? '50%' : 0,\n bottom: continuationOnly ? 0 : isLaneEnd ? '50%' : 0,\n width: 2,\n backgroundColor: ROOT_LINE_COLOR,\n zIndex: 0,\n }}\n />\n )}\n </div>\n );\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Copyable cell — shows a copy button on hover\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction CopyableCell({\n value,\n className,\n style: styleProp,\n}: {\n value: string;\n className?: string;\n style?: React.CSSProperties;\n}): ReactNode {\n const [copied, setCopied] = useState(false);\n const resetCopiedTimeoutRef = useRef<number | null>(null);\n\n useEffect(() => {\n return () => {\n if (resetCopiedTimeoutRef.current !== null) {\n window.clearTimeout(resetCopiedTimeoutRef.current);\n }\n };\n }, []);\n\n const handleCopy = useCallback(\n (e: ReactMouseEvent) => {\n e.stopPropagation();\n navigator.clipboard.writeText(value).then(() => {\n setCopied(true);\n if (resetCopiedTimeoutRef.current !== null) {\n window.clearTimeout(resetCopiedTimeoutRef.current);\n }\n resetCopiedTimeoutRef.current = window.setTimeout(() => {\n setCopied(false);\n resetCopiedTimeoutRef.current = null;\n }, 1500);\n });\n },\n [value]\n );\n\n return (\n <div\n className={`group/copy flex items-center gap-1 min-w-0 px-4 ${className ?? ''}`}\n style={styleProp}\n >\n <span className=\"overflow-hidden text-ellipsis whitespace-nowrap\">\n {value || '-'}\n </span>\n {value ? (\n <button\n type=\"button\"\n onClick={handleCopy}\n className=\"flex-shrink-0 opacity-0 group-hover/copy:opacity-100 transition-opacity p-0.5 rounded hover:bg-[var(--ds-gray-alpha-200)]\"\n style={BUTTON_RESET_STYLE}\n aria-label={`Copy ${value}`}\n >\n {copied ? (\n <Check\n className=\"h-3 w-3\"\n style={{ color: 'var(--ds-green-700)' }}\n />\n ) : (\n <Copy className=\"h-3 w-3\" style={{ color: 'var(--ds-gray-700)' }} />\n )}\n </button>\n ) : null}\n </div>\n );\n}\n\n/** Recursively parse stringified JSON values so escaped slashes / quotes are cleaned up */\nfunction deepParseJson(value: unknown): unknown {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']')) ||\n (trimmed.startsWith('\"') && trimmed.endsWith('\"'))\n ) {\n try {\n return deepParseJson(JSON.parse(trimmed));\n } catch {\n return value;\n }\n }\n return value;\n }\n if (Array.isArray(value)) {\n return value.map(deepParseJson);\n }\n if (value !== null && typeof value === 'object') {\n // Preserve objects with custom constructors (e.g., encrypted markers,\n // class instance refs) — don't destructure them into plain objects\n if (value.constructor !== Object) {\n return value;\n }\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = deepParseJson(v);\n }\n return result;\n }\n return value;\n}\n\n/**\n * Extracts a structured error with a stack trace from event data, if present.\n * Returns the error object to render with ErrorStackBlock, or null if not applicable.\n */\nfunction extractStructuredError(\n data: unknown,\n eventType?: string\n): (Record<string, unknown> & { stack: string }) | null {\n if (!eventType || !ERROR_EVENT_TYPES.has(eventType)) return null;\n if (data == null || typeof data !== 'object') return null;\n const record = data as Record<string, unknown>;\n // Check the nested `error` field first (the StructuredError)\n if (isStructuredErrorWithStack(record.error)) return record.error;\n // Some error formats put the stack at the top level of eventData\n if (isStructuredErrorWithStack(record)) return record;\n return null;\n}\n\nfunction PayloadBlock({\n data,\n eventType,\n}: {\n data: unknown;\n eventType?: string;\n}): ReactNode {\n const structuredError = useMemo(\n () => extractStructuredError(data, eventType),\n [data, eventType]\n );\n\n const [copied, setCopied] = useState(false);\n const resetCopiedTimeoutRef = useRef<number | null>(null);\n const cleaned = useMemo(() => deepParseJson(data), [data]);\n\n useEffect(() => {\n return () => {\n if (resetCopiedTimeoutRef.current !== null) {\n window.clearTimeout(resetCopiedTimeoutRef.current);\n }\n };\n }, []);\n\n const formatted = useMemo(() => {\n try {\n return JSON.stringify(cleaned, null, 2);\n } catch {\n return String(cleaned);\n }\n }, [cleaned]);\n\n const handleCopy = useCallback(\n (e: ReactMouseEvent) => {\n e.stopPropagation();\n navigator.clipboard.writeText(formatted).then(() => {\n setCopied(true);\n if (resetCopiedTimeoutRef.current !== null) {\n window.clearTimeout(resetCopiedTimeoutRef.current);\n }\n resetCopiedTimeoutRef.current = window.setTimeout(() => {\n setCopied(false);\n resetCopiedTimeoutRef.current = null;\n }, 1500);\n });\n },\n [formatted]\n );\n\n if (structuredError) {\n return (\n <div className=\"p-2\">\n <ErrorStackBlock value={structuredError} />\n </div>\n );\n }\n\n return (\n <div className=\"relative group/payload\">\n <div\n className=\"overflow-x-auto p-2 text-[11px]\"\n style={{ color: 'var(--ds-gray-1000)' }}\n >\n <DataInspector data={cleaned} expandLevel={2} />\n </div>\n <button\n type=\"button\"\n onClick={handleCopy}\n className=\"absolute bottom-2 right-2 opacity-0 group-hover/payload:opacity-100 transition-opacity flex items-center gap-1 px-2 py-1 rounded-md text-xs hover:bg-[var(--ds-gray-alpha-200)]\"\n style={{ ...BUTTON_RESET_STYLE, color: 'var(--ds-gray-700)' }}\n aria-label=\"Copy payload\"\n >\n {copied ? (\n <>\n <Check\n className=\"h-3 w-3\"\n style={{ color: 'var(--ds-green-700)' }}\n />\n <span style={{ color: 'var(--ds-green-700)' }}>Copied</span>\n </>\n ) : (\n <>\n <Copy className=\"h-3 w-3\" />\n <span>Copy</span>\n </>\n )}\n </button>\n </div>\n );\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Sort options for the events list\n// ──────────────────────────────────────────────────────────────────────────\n\nconst SORT_OPTIONS = [\n { value: 'desc' as const, label: 'Newest' },\n { value: 'asc' as const, label: 'Oldest' },\n];\n\nfunction RowsSkeleton() {\n return (\n <div className=\"flex-1 overflow-hidden\">\n {Array.from({ length: 16 }, (_, i) => (\n <div key={i} className=\"flex items-center gap-0\" style={{ height: 40 }}>\n {/* Gutter area */}\n <div\n className=\"relative flex-shrink-0 self-stretch flex items-center\"\n style={{ width: GUTTER_WIDTH }}\n >\n {/* Vertical line skeleton */}\n <div\n style={{\n position: 'absolute',\n left: 8,\n top: i === 0 ? '50%' : 0,\n bottom: 0,\n width: 2,\n }}\n >\n <Skeleton className=\"w-full h-full\" style={{ borderRadius: 1 }} />\n </div>\n {/* Dot skeleton */}\n <Skeleton\n className=\"flex-shrink-0\"\n style={{\n width: i % 4 === 0 ? 8 : 6,\n height: i % 4 === 0 ? 8 : 6,\n borderRadius: '50%',\n marginLeft: i % 4 === 0 ? 5 : 6,\n }}\n />\n </div>\n {/* Chevron placeholder */}\n <div className=\"w-5 flex-shrink-0 flex items-center justify-center\">\n <Skeleton className=\"w-5 h-5\" style={{ borderRadius: 4 }} />\n </div>\n {/* Time */}\n <div className=\"min-w-0 px-4\" style={{ flex: '2 1 0%' }}>\n <Skeleton className=\"h-3\" style={{ width: '70%' }} />\n </div>\n {/* Event Type */}\n <div\n className=\"min-w-0 px-4 flex items-center gap-1.5\"\n style={{ flex: '2 1 0%' }}\n >\n <Skeleton\n className=\"flex-shrink-0\"\n style={{ width: 6, height: 6, borderRadius: '50%' }}\n />\n <Skeleton className=\"h-3\" style={{ width: '60%' }} />\n </div>\n {/* Name */}\n <div className=\"min-w-0 px-4\" style={{ flex: '2 1 0%' }}>\n <Skeleton className=\"h-3\" style={{ width: '50%' }} />\n </div>\n {/* Correlation ID */}\n <div className=\"min-w-0 px-4\" style={{ flex: '3 1 0%' }}>\n <Skeleton className=\"h-3\" style={{ width: '75%' }} />\n </div>\n {/* Event ID */}\n <div className=\"min-w-0 px-4\" style={{ flex: '3 1 0%' }}>\n <Skeleton className=\"h-3\" style={{ width: '75%' }} />\n </div>\n </div>\n ))}\n </div>\n );\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Event row\n// ──────────────────────────────────────────────────────────────────────────\n\ninterface EventsListProps {\n events: Event[] | null;\n run?: WorkflowRun | null;\n onLoadEventData?: (event: Event) => Promise<unknown | null>;\n hasMoreEvents?: boolean;\n isLoadingMoreEvents?: boolean;\n onLoadMoreEvents?: () => Promise<void> | void;\n /** When provided, signals that decryption is active (triggers re-load of expanded events) */\n encryptionKey?: Uint8Array;\n /** When true, shows a loading state instead of \"No events found\" for empty lists */\n isLoading?: boolean;\n /** Sort order for events. Defaults to 'asc'. */\n sortOrder?: 'asc' | 'desc';\n /** Called when the user changes sort order. When provided, the sort dropdown is shown\n * and the parent is expected to refetch from the API with the new order. */\n onSortOrderChange?: (order: 'asc' | 'desc') => void;\n /** Called when the user clicks the Decrypt button. */\n onDecrypt?: () => void;\n /** Whether the encryption key is currently being fetched. */\n isDecrypting?: boolean;\n /** Run-level hint: the run contains encrypted data (from probe). */\n hasEncryptedData?: boolean;\n}\n\nfunction EventRow({\n event,\n index,\n isFirst,\n isLast,\n isExpanded,\n onToggleExpand,\n activeGroupKey,\n selectedGroupKey,\n selectedGroupRange,\n correlationNameMap,\n workflowName,\n durationMap,\n onSelectGroup,\n onHoverGroup,\n onLoadEventData,\n cachedEventData,\n onCacheEventData,\n encryptionKey,\n onEncryptedDataDetected,\n}: {\n event: Event;\n index: number;\n isFirst: boolean;\n isLast: boolean;\n isExpanded: boolean;\n onToggleExpand: (eventId: string) => void;\n activeGroupKey?: string;\n selectedGroupKey?: string;\n selectedGroupRange: { first: number; last: number } | null;\n correlationNameMap: Map<string, string>;\n workflowName: string | null;\n durationMap: Map<string, DurationInfo>;\n onSelectGroup: (groupKey: string | undefined) => void;\n onHoverGroup: (groupKey: string | undefined) => void;\n onLoadEventData?: (event: Event) => Promise<unknown | null>;\n cachedEventData: unknown | null;\n onCacheEventData: (eventId: string, data: unknown) => void;\n encryptionKey?: Uint8Array;\n onEncryptedDataDetected?: () => void;\n}) {\n const [isLoading, setIsLoading] = useState(false);\n const [loadedEventData, setLoadedEventData] = useState<unknown | null>(\n cachedEventData\n );\n const [loadError, setLoadError] = useState<string | null>(null);\n const [hasAttemptedLoad, setHasAttemptedLoad] = useState(\n cachedEventData !== null\n );\n\n // Notify parent if cached data has encrypted markers on mount\n useEffect(() => {\n if (\n cachedEventData !== null &&\n !encryptionKey &&\n hasEncryptedValues(cachedEventData)\n ) {\n onEncryptedDataDetected?.();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const rowGroupKey = isRunLevel(event.eventType)\n ? '__run__'\n : (event.correlationId ?? undefined);\n\n const statusDotColor = getStatusDotColor(event.eventType);\n const createdAt = new Date(event.createdAt);\n const hasExistingEventData = 'eventData' in event && event.eventData != null;\n const isRun = isRunLevel(event.eventType);\n const eventName = isRun\n ? (workflowName ?? '-')\n : event.correlationId\n ? (correlationNameMap.get(event.correlationId) ?? '-')\n : '-';\n\n const durationKey = event.correlationId ?? (isRun ? '__run__' : '');\n const durationInfo = durationKey ? durationMap.get(durationKey) : undefined;\n\n const hasActive = activeGroupKey !== undefined;\n const isRelated = rowGroupKey !== undefined && rowGroupKey === activeGroupKey;\n const isDimmed = hasActive && !isRelated;\n const isPulsing = hasActive && isRelated;\n\n // Gutter state derived from selectedGroupRange\n const showBranch = hasActive && isRelated && !isRun;\n const showLaneLine =\n selectedGroupRange !== null &&\n index >= selectedGroupRange.first &&\n index <= selectedGroupRange.last;\n const isLaneStart =\n selectedGroupRange !== null && index === selectedGroupRange.first;\n const isLaneEnd =\n selectedGroupRange !== null && index === selectedGroupRange.last;\n\n const loadEventDetails = useCallback(async () => {\n if (loadedEventData !== null) {\n return;\n }\n if (cachedEventData !== null) {\n setLoadedEventData(cachedEventData);\n setHasAttemptedLoad(true);\n return;\n }\n if (isLoading) {\n return;\n }\n setIsLoading(true);\n setLoadError(null);\n try {\n if (!onLoadEventData) {\n setLoadError('Event details unavailable');\n return;\n }\n const data = await onLoadEventData(event);\n if (data !== null && data !== undefined) {\n setLoadedEventData(data);\n onCacheEventData(event.eventId, data);\n if (!encryptionKey && hasEncryptedValues(data)) {\n onEncryptedDataDetected?.();\n }\n }\n } catch (err) {\n setLoadError(\n err instanceof Error ? err.message : 'Failed to load event details'\n );\n } finally {\n setIsLoading(false);\n setHasAttemptedLoad(true);\n }\n }, [\n event,\n loadedEventData,\n isLoading,\n onLoadEventData,\n onCacheEventData,\n encryptionKey,\n onEncryptedDataDetected,\n cachedEventData,\n ]);\n\n // Auto-load event data when remounting in expanded state without cached data\n useEffect(() => {\n if (!isExpanded || isLoading) {\n return;\n }\n void loadEventDetails();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // When encryption key changes and this event was previously loaded,\n // re-load to get decrypted data\n useEffect(() => {\n if (encryptionKey && hasAttemptedLoad && onLoadEventData) {\n setLoadedEventData(null);\n setHasAttemptedLoad(false);\n onLoadEventData(event)\n .then((data) => {\n if (data !== null && data !== undefined) {\n setLoadedEventData(data);\n onCacheEventData(event.eventId, data);\n }\n setHasAttemptedLoad(true);\n })\n .catch(() => {\n setHasAttemptedLoad(true);\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [encryptionKey]);\n\n const handleRowClick = useCallback(() => {\n onSelectGroup(rowGroupKey === selectedGroupKey ? undefined : rowGroupKey);\n onToggleExpand(event.eventId);\n if (!isExpanded) {\n void loadEventDetails();\n }\n }, [\n selectedGroupKey,\n rowGroupKey,\n onSelectGroup,\n onToggleExpand,\n event.eventId,\n isExpanded,\n loadEventDetails,\n ]);\n\n const mergedEventData =\n loadedEventData ??\n (hasExistingEventData\n ? (event as Event & { eventData: unknown }).eventData\n : null);\n\n const displayPayload = isLoading ? loadedEventData : mergedEventData;\n\n const contentOpacity = isDimmed ? 0.3 : 1;\n\n return (\n <div\n data-event-id={event.eventId}\n onMouseEnter={() => onHoverGroup(rowGroupKey)}\n onMouseLeave={() => onHoverGroup(undefined)}\n >\n {/* Row */}\n <div\n role=\"button\"\n tabIndex={0}\n onClick={handleRowClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleRowClick();\n }}\n className=\"w-full text-left flex items-center gap-0 text-[13px] hover:bg-[var(--ds-gray-alpha-100)] transition-colors cursor-pointer\"\n style={{ minHeight: 40 }}\n >\n <TreeGutter\n isFirst={isFirst}\n isLast={isLast && !isExpanded}\n isRunLevel={isRun}\n statusDotColor={statusDotColor}\n pulse={isPulsing}\n hasSelection={hasActive}\n showBranch={showBranch}\n showLaneLine={showLaneLine}\n isLaneStart={isLaneStart}\n isLaneEnd={isLaneEnd}\n />\n\n {/* Content area — dims when unrelated */}\n <div\n className=\"flex items-center flex-1 min-w-0\"\n style={{ opacity: contentOpacity, transition: 'opacity 150ms' }}\n >\n {/* Expand chevron indicator */}\n <div\n className=\"flex items-center justify-center w-5 h-5 flex-shrink-0 rounded\"\n style={{\n border: '1px solid var(--ds-gray-400)',\n }}\n >\n <ChevronRight\n className=\"h-3 w-3 transition-transform\"\n style={{\n color: 'var(--ds-gray-900)',\n transform: isExpanded ? 'rotate(90deg)' : 'rotate(0deg)',\n }}\n />\n </div>\n\n {/* Time */}\n <div\n className=\"tabular-nums min-w-0 px-4\"\n style={{ color: 'var(--ds-gray-900)', flex: '2 1 0%' }}\n >\n <TimestampTooltip date={createdAt}>\n <span>{formatEventTime(createdAt)}</span>\n </TimestampTooltip>\n </div>\n\n {/* Event Type */}\n <div className=\"font-medium min-w-0 px-4\" style={{ flex: '2 1 0%' }}>\n <span\n className=\"inline-flex items-center gap-1.5\"\n style={{ color: 'var(--ds-gray-900)' }}\n >\n <span\n style={{\n position: 'relative',\n display: 'inline-flex',\n width: 6,\n height: 6,\n flexShrink: 0,\n }}\n >\n {isPulsing && (\n <span\n style={{\n position: 'absolute',\n inset: 0,\n borderRadius: '50%',\n backgroundColor: statusDotColor,\n opacity: 0.75,\n animation: DOT_PULSE_ANIMATION,\n }}\n />\n )}\n <span\n style={{\n position: 'relative',\n width: 6,\n height: 6,\n borderRadius: '50%',\n backgroundColor: statusDotColor,\n }}\n />\n </span>\n {formatEventType(event.eventType)}\n </span>\n </div>\n\n {/* Name */}\n <div\n className=\"min-w-0 px-4 overflow-hidden text-ellipsis whitespace-nowrap\"\n style={{ flex: '2 1 0%' }}\n title={eventName !== '-' ? eventName : undefined}\n >\n {eventName}\n </div>\n\n {/* Correlation ID */}\n <CopyableCell\n value={event.correlationId || ''}\n className=\"font-mono\"\n style={{ flex: '3 1 0%' }}\n />\n\n {/* Event ID */}\n <CopyableCell\n value={event.eventId}\n className=\"font-mono\"\n style={{ flex: '3 1 0%' }}\n />\n </div>\n </div>\n\n {/* Expanded details — tree lines continue through this area */}\n {isExpanded && (\n <div className=\"flex\">\n {/* Continuation gutter — lane line continues if not at lane end */}\n <TreeGutter\n isFirst={false}\n isLast={isLast}\n isRunLevel={isRun}\n hasSelection={hasActive}\n showBranch={false}\n showLaneLine={showLaneLine && !isLaneEnd}\n isLaneStart={false}\n isLaneEnd={false}\n continuationOnly\n />\n {/* Spacer for chevron column */}\n <div className=\"w-5 flex-shrink-0\" />\n <div\n className=\"flex-1 my-1.5 mr-3 ml-2 py-2 rounded-md border overflow-hidden\"\n style={{\n borderColor: 'var(--ds-gray-alpha-200)',\n opacity: contentOpacity,\n transition: 'opacity 150ms',\n }}\n >\n {/* Duration info */}\n {(durationInfo?.queued !== undefined ||\n durationInfo?.ran !== undefined) && (\n <div\n className=\"px-2 pb-1.5 text-xs flex gap-3\"\n style={{ color: 'var(--ds-gray-900)' }}\n >\n {durationInfo.queued !== undefined &&\n durationInfo.queued > 0 && (\n <span>\n Queued for{' '}\n <span className=\"font-mono tabular-nums\">\n {formatDuration(durationInfo.queued)}\n </span>\n </span>\n )}\n {durationInfo.ran !== undefined && (\n <span>\n Ran for{' '}\n <span className=\"font-mono tabular-nums\">\n {formatDuration(durationInfo.ran)}\n </span>\n </span>\n )}\n </div>\n )}\n\n {/* Payload */}\n {displayPayload != null ? (\n <PayloadBlock data={displayPayload} eventType={event.eventType} />\n ) : loadError ? (\n <div\n className=\"rounded-md border p-3 text-xs\"\n style={{\n borderColor: 'var(--ds-red-400)',\n backgroundColor: 'var(--ds-red-100)',\n color: 'var(--ds-red-900)',\n }}\n >\n {loadError}\n </div>\n ) : isLoading ||\n (loadedEventData === null &&\n !hasAttemptedLoad &&\n event.correlationId) ? (\n <div className=\"flex flex-col gap-2 p-3\">\n <Skeleton className=\"h-3\" style={{ width: '75%' }} />\n <Skeleton className=\"h-3\" style={{ width: '50%' }} />\n <Skeleton className=\"h-3\" style={{ width: '60%' }} />\n </div>\n ) : (\n <div\n className=\"p-2 text-xs\"\n style={{ color: 'var(--ds-gray-900)' }}\n >\n No data\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Main component\n// ──────────────────────────────────────────────────────────────────────────\n\nexport function EventListView({\n events,\n run,\n onLoadEventData,\n hasMoreEvents = false,\n isLoadingMoreEvents = false,\n onLoadMoreEvents,\n encryptionKey,\n isLoading = false,\n sortOrder: sortOrderProp,\n onSortOrderChange,\n onDecrypt,\n isDecrypting = false,\n hasEncryptedData: hasEncryptedDataProp = false,\n}: EventsListProps) {\n const [internalSortOrder, setInternalSortOrder] = useState<'asc' | 'desc'>(\n 'asc'\n );\n const effectiveSortOrder = sortOrderProp ?? internalSortOrder;\n const handleSortOrderChange = useCallback(\n (order: 'asc' | 'desc') => {\n if (onSortOrderChange) {\n onSortOrderChange(order);\n } else {\n setInternalSortOrder(order);\n }\n },\n [onSortOrderChange]\n );\n\n const sortedEvents = useMemo(() => {\n if (!events || events.length === 0) return [];\n const dir = effectiveSortOrder === 'desc' ? -1 : 1;\n return [...events].sort(\n (a, b) =>\n dir *\n (new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime())\n );\n }, [events, effectiveSortOrder]);\n\n // Detect encrypted fields across all loaded events (inline eventData).\n const hasEncryptedInlineData = useMemo(() => {\n if (!events) return false;\n for (const event of events) {\n const ed = (event as Record<string, unknown>).eventData;\n if (hasEncryptedValues(ed)) return true;\n }\n return false;\n }, [events]);\n\n // Tracks whether any expanded row's lazy-loaded data contained encrypted markers.\n // Set to true by EventRow via onEncryptedDataDetected; never reset (sticky).\n const [foundEncryptedInLazyData, setFoundEncryptedInLazyData] =\n useState(false);\n const handleEncryptedDataDetected = useCallback(() => {\n setFoundEncryptedInLazyData(true);\n }, []);\n\n const hasEncryptedData =\n hasEncryptedDataProp || hasEncryptedInlineData || foundEncryptedInLazyData;\n\n const { correlationNameMap, workflowName } = useMemo(\n () => buildNameMaps(events ?? null, run ?? null),\n [events, run]\n );\n\n const durationMap = useMemo(\n () => buildDurationMap(sortedEvents),\n [sortedEvents]\n );\n\n const [selectedGroupKey, setSelectedGroupKey] = useState<string | undefined>(\n undefined\n );\n const [hoveredGroupKey, setHoveredGroupKey] = useState<string | undefined>(\n undefined\n );\n const onSelectGroup = useCallback((groupKey: string | undefined) => {\n setSelectedGroupKey(groupKey);\n }, []);\n const onHoverGroup = useCallback((groupKey: string | undefined) => {\n setHoveredGroupKey(groupKey);\n }, []);\n\n const activeGroupKey = selectedGroupKey ?? hoveredGroupKey;\n\n // Expanded state lifted out of EventRow so it survives virtualization\n const [expandedEventIds, setExpandedEventIds] = useState<Set<string>>(\n () => new Set()\n );\n const toggleEventExpanded = useCallback((eventId: string) => {\n setExpandedEventIds((prev) => {\n const next = new Set(prev);\n if (next.has(eventId)) {\n next.delete(eventId);\n } else {\n next.add(eventId);\n }\n return next;\n });\n }, []);\n\n // Event data cache — ref avoids re-renders when cache updates\n const eventDataCacheRef = useRef<Map<string, unknown>>(new Map());\n const cacheEventData = useCallback((eventId: string, data: unknown) => {\n eventDataCacheRef.current.set(eventId, data);\n }, []);\n\n // Lookup from eventId → groupKey for efficient collapse filtering\n const eventGroupKeyMap = useMemo(() => {\n const map = new Map<string, string>();\n for (const ev of sortedEvents) {\n const gk = isRunLevel(ev.eventType)\n ? '__run__'\n : (ev.correlationId ?? '');\n if (gk) map.set(ev.eventId, gk);\n }\n return map;\n }, [sortedEvents]);\n\n // Collapse expanded events that don't belong to the newly selected group\n useEffect(() => {\n if (selectedGroupKey === undefined) return;\n setExpandedEventIds((prev) => {\n if (prev.size === 0) return prev;\n let changed = false;\n const next = new Set<string>();\n for (const eventId of prev) {\n if (eventGroupKeyMap.get(eventId) === selectedGroupKey) {\n next.add(eventId);\n } else {\n changed = true;\n }\n }\n return changed ? next : prev;\n });\n }, [selectedGroupKey, eventGroupKeyMap]);\n\n // Compute the row-index range for the active group's connecting lane line.\n // Only applies to non-run groups (step/hook/wait correlations).\n const selectedGroupRange = useMemo(() => {\n if (!activeGroupKey || activeGroupKey === '__run__') return null;\n let first = -1;\n let last = -1;\n for (let i = 0; i < sortedEvents.length; i++) {\n if (sortedEvents[i].correlationId === activeGroupKey) {\n if (first === -1) first = i;\n last = i;\n }\n }\n return first >= 0 ? { first, last } : null;\n }, [activeGroupKey, sortedEvents]);\n\n const [searchQuery, setSearchQuery] = useState('');\n const virtuosoRef = useRef<VirtuosoHandle>(null);\n\n const searchIndex = useMemo(() => {\n const entries: {\n fields: string[];\n groupKey?: string;\n eventId: string;\n index: number;\n }[] = [];\n for (let i = 0; i < sortedEvents.length; i++) {\n const ev = sortedEvents[i];\n const isRun = isRunLevel(ev.eventType);\n const name = isRun\n ? (workflowName ?? '')\n : ev.correlationId\n ? (correlationNameMap.get(ev.correlationId) ?? '')\n : '';\n entries.push({\n fields: [\n ev.eventId,\n ev.correlationId ?? '',\n ev.eventType,\n formatEventType(ev.eventType),\n name,\n ].map((f) => f.toLowerCase()),\n groupKey: ev.correlationId ?? (isRun ? '__run__' : undefined),\n eventId: ev.eventId,\n index: i,\n });\n }\n return entries;\n }, [sortedEvents, correlationNameMap, workflowName]);\n\n useEffect(() => {\n const q = searchQuery.trim().toLowerCase();\n if (!q) {\n setSelectedGroupKey(undefined);\n return;\n }\n let bestMatch: (typeof searchIndex)[number] | null = null;\n let bestScore = 0;\n for (const entry of searchIndex) {\n for (const field of entry.fields) {\n if (field && field.includes(q)) {\n const score = q.length / field.length;\n if (score > bestScore) {\n bestScore = score;\n bestMatch = entry;\n }\n }\n }\n }\n if (bestMatch) {\n setSelectedGroupKey(bestMatch.groupKey);\n virtuosoRef.current?.scrollToIndex({\n index: bestMatch.index,\n align: 'center',\n behavior: 'smooth',\n });\n }\n }, [searchQuery, searchIndex]);\n\n // Track whether we've ever had events to distinguish initial load from refetch\n const hasHadEventsRef = useRef(false);\n if (sortedEvents.length > 0) {\n hasHadEventsRef.current = true;\n }\n const isInitialLoad = isLoading && !hasHadEventsRef.current;\n const isRefetching =\n isLoading && hasHadEventsRef.current && sortedEvents.length === 0;\n\n if (isInitialLoad) {\n return (\n <div className=\"h-full flex flex-col overflow-hidden\">\n {/* Skeleton search bar */}\n <div style={{ padding: 6 }}>\n <Skeleton style={{ height: 40, borderRadius: 6 }} />\n </div>\n {/* Skeleton header */}\n <div\n className=\"flex items-center gap-0 h-10 border-b flex-shrink-0\"\n style={{ borderColor: 'var(--ds-gray-alpha-200)' }}\n >\n <div className=\"flex-shrink-0\" style={{ width: GUTTER_WIDTH }} />\n <div className=\"w-5 flex-shrink-0\" />\n <div className=\"min-w-0 px-4\" style={{ flex: '2 1 0%' }}>\n <Skeleton className=\"h-3\" style={{ width: 40 }} />\n </div>\n <div className=\"min-w-0 px-4\" style={{ flex: '2 1 0%' }}>\n <Skeleton className=\"h-3\" style={{ width: 72 }} />\n </div>\n <div className=\"min-w-0 px-4\" style={{ flex: '2 1 0%' }}>\n <Skeleton className=\"h-3\" style={{ width: 44 }} />\n </div>\n <div className=\"min-w-0 px-4\" style={{ flex: '3 1 0%' }}>\n <Skeleton className=\"h-3\" style={{ width: 92 }} />\n </div>\n <div className=\"min-w-0 px-4\" style={{ flex: '3 1 0%' }}>\n <Skeleton className=\"h-3\" style={{ width: 60 }} />\n </div>\n </div>\n <RowsSkeleton />\n </div>\n );\n }\n\n if (!isLoading && (!events || events.length === 0)) {\n return (\n <div\n className=\"flex items-center justify-center h-full text-sm\"\n style={{ color: 'var(--ds-gray-700)' }}\n >\n No events found\n </div>\n );\n }\n\n return (\n <DecryptClickContext.Provider\n value={onDecrypt ? { onDecrypt, isDecrypting } : undefined}\n >\n <div className=\"h-full flex flex-col overflow-hidden\">\n <style>{`@keyframes workflow-dot-pulse{0%{transform:scale(1);opacity:.7}70%,100%{transform:scale(2.2);opacity:0}}`}</style>\n {/* Search bar + sort */}\n <div\n style={{\n padding: 6,\n backgroundColor: 'var(--ds-background-100)',\n display: 'flex',\n gap: 6,\n }}\n >\n <label\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 6,\n boxShadow: '0 0 0 1px var(--ds-gray-alpha-400)',\n background: 'var(--ds-background-100)',\n height: 40,\n flex: 1,\n minWidth: 0,\n }}\n >\n <div\n style={{\n width: 40,\n height: 40,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: 'var(--ds-gray-800)',\n flexShrink: 0,\n }}\n >\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle\n cx=\"7\"\n cy=\"7\"\n r=\"4.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M11.5 11.5L14 14\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n </div>\n <input\n type=\"search\"\n placeholder=\"Search by name, event type, or ID…\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n style={{\n marginLeft: -16,\n paddingInline: 12,\n fontFamily: 'inherit',\n fontSize: 14,\n background: 'transparent',\n border: 'none',\n outline: 'none',\n height: 40,\n width: '100%',\n }}\n />\n </label>\n <MenuDropdown\n options={SORT_OPTIONS}\n value={effectiveSortOrder}\n onChange={handleSortOrderChange}\n />\n {(hasEncryptedData || encryptionKey) && onDecrypt && (\n <DecryptButton\n decrypted={!!encryptionKey}\n loading={isDecrypting}\n onClick={onDecrypt}\n />\n )}\n </div>\n\n {/* Header */}\n <div\n className=\"flex items-center gap-0 text-[13px] font-medium h-10 border-b flex-shrink-0\"\n style={{\n borderColor: 'var(--ds-gray-alpha-200)',\n color: 'var(--ds-gray-900)',\n backgroundColor: 'var(--ds-background-100)',\n }}\n >\n <div className=\"flex-shrink-0\" style={{ width: GUTTER_WIDTH }} />\n <div className=\"w-5 flex-shrink-0\" />\n <div className=\"min-w-0 px-4\" style={{ flex: '2 1 0%' }}>\n Time\n </div>\n <div className=\"min-w-0 px-4\" style={{ flex: '2 1 0%' }}>\n Event Type\n </div>\n <div className=\"min-w-0 px-4\" style={{ flex: '2 1 0%' }}>\n Name\n </div>\n <div className=\"min-w-0 px-4\" style={{ flex: '3 1 0%' }}>\n Correlation ID\n </div>\n <div className=\"min-w-0 px-4\" style={{ flex: '3 1 0%' }}>\n Event ID\n </div>\n </div>\n\n {/* Virtualized event rows or refetching skeleton */}\n {isRefetching ? (\n <RowsSkeleton />\n ) : (\n <Virtuoso\n ref={virtuosoRef}\n totalCount={sortedEvents.length}\n overscan={20}\n defaultItemHeight={40}\n endReached={() => {\n if (!hasMoreEvents || isLoadingMoreEvents) {\n return;\n }\n void onLoadMoreEvents?.();\n }}\n itemContent={(index: number) => {\n const ev = sortedEvents[index];\n return (\n <EventRow\n event={ev}\n index={index}\n isFirst={index === 0}\n isLast={index === sortedEvents.length - 1}\n isExpanded={expandedEventIds.has(ev.eventId)}\n onToggleExpand={toggleEventExpanded}\n activeGroupKey={activeGroupKey}\n selectedGroupKey={selectedGroupKey}\n selectedGroupRange={selectedGroupRange}\n correlationNameMap={correlationNameMap}\n workflowName={workflowName}\n durationMap={durationMap}\n onSelectGroup={onSelectGroup}\n onHoverGroup={onHoverGroup}\n onLoadEventData={onLoadEventData}\n cachedEventData={\n eventDataCacheRef.current.get(ev.eventId) ?? null\n }\n onCacheEventData={cacheEventData}\n encryptionKey={encryptionKey}\n onEncryptedDataDetected={handleEncryptedDataDetected}\n />\n );\n }}\n style={{ flex: 1, minHeight: 0 }}\n />\n )}\n\n {/* Fixed footer — count + load more */}\n <div\n className=\"relative flex-shrink-0 flex items-center h-10 border-t px-4 text-xs\"\n style={{\n borderColor: 'var(--ds-gray-alpha-200)',\n color: 'var(--ds-gray-900)',\n backgroundColor: 'var(--ds-background-100)',\n }}\n >\n <span>\n {sortedEvents.length} event\n {sortedEvents.length !== 1 ? 's' : ''} loaded\n </span>\n {hasMoreEvents && (\n <div className=\"absolute inset-0 flex items-center justify-center pointer-events-none\">\n <div className=\"pointer-events-auto\">\n <LoadMoreButton\n loading={isLoadingMoreEvents}\n onClick={() => void onLoadMoreEvents?.()}\n />\n </div>\n </div>\n )}\n </div>\n </div>\n </DecryptClickContext.Provider>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"hook-actions.js","sourceRoot":"","sources":["../../src/components/hook-actions.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport type { Hook, WorkflowRunStatus } from '@workflow/world';\nimport { Send } from 'lucide-react';\nimport { useCallback, useState } from 'react';\nimport { useToast } from '../lib/toast';\nimport { ResolveHookModal } from './sidebar/resolve-hook-modal';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface HookActionCallbacks {\n /** Called after a successful action */\n onSuccess?: () => void;\n}\n\nexport interface UseHookActionsOptions {\n onResolve: (hook: Hook, payload: unknown) => Promise<void>;\n callbacks?: HookActionCallbacks;\n}\n\nexport interface UseHookActionsReturn {\n /** Whether the hook is currently being resolved */\n isResolving: boolean;\n /** The hook currently selected for resolution (null if none) */\n selectedHook: Hook | null;\n /** Open the resolve modal for a specific hook */\n openResolveModal: (hook: Hook) => void;\n /** Close the resolve modal */\n closeResolveModal: () => void;\n /** Handle submitting the resolve payload */\n handleResolve: (payload: unknown) => Promise<void>;\n}\n\n// ============================================================================\n// Hook for managing hook actions state\n// ============================================================================\n\n/**\n * React hook for managing hook action state.\n * Use this to coordinate the resolve modal across components.\n */\nexport function useHookActions({\n onResolve,\n callbacks,\n}: UseHookActionsOptions): UseHookActionsReturn {\n const toast = useToast();\n const [isResolving, setIsResolving] = useState(false);\n const [selectedHook, setSelectedHook] = useState<Hook | null>(null);\n\n const openResolveModal = useCallback((hook: Hook) => {\n setSelectedHook(hook);\n }, []);\n\n const closeResolveModal = useCallback(() => {\n setSelectedHook(null);\n }, []);\n\n const handleResolve = useCallback(\n async (payload: unknown) => {\n if (isResolving || !selectedHook) return;\n\n try {\n setIsResolving(true);\n await onResolve(selectedHook, payload);\n toast.success('Hook resolved', {\n description: 'The payload has been sent and the hook resolved.',\n });\n setSelectedHook(null);\n callbacks?.onSuccess?.();\n } catch (err) {\n console.error('Failed to resolve hook:', err);\n toast.error('Failed to resolve hook', {\n description:\n err instanceof Error ? err.message : 'An unknown error occurred',\n });\n } finally {\n setIsResolving(false);\n }\n },\n [onResolve, selectedHook, isResolving, callbacks]\n );\n\n return {\n isResolving,\n selectedHook,\n openResolveModal,\n closeResolveModal,\n handleResolve,\n };\n}\n\n// ============================================================================\n// Dropdown Menu Item Component\n// ============================================================================\n\nexport interface HookActionsDropdownItemProps {\n /** The hook to act on */\n hook: Hook;\n /** The current run status (used to determine if actions are available) */\n runStatus?: WorkflowRunStatus;\n /** Stop click event propagation (useful in table rows) */\n stopPropagation?: boolean;\n /** Called when the resolve action is triggered */\n onResolveClick: (hook: Hook) => void;\n /** Custom DropdownMenuItem component (allows using the consumer's UI library) */\n DropdownMenuItem: React.ComponentType<{\n onClick?: (e: React.MouseEvent) => void;\n disabled?: boolean;\n children: React.ReactNode;\n }>;\n}\n\n/**\n * Dropdown menu item for resolving a hook.\n * This is a single menu item component that can be composed into dropdown menus.\n */\nexport function ResolveHookDropdownItem({\n hook,\n stopPropagation = false,\n onResolveClick,\n DropdownMenuItem,\n}: HookActionsDropdownItemProps): React.JSX.Element {\n const handleClick = (e: React.MouseEvent) => {\n if (stopPropagation) e.stopPropagation();\n onResolveClick(hook);\n };\n\n return (\n <DropdownMenuItem onClick={handleClick}>\n <Send className=\"h-4 w-4 mr-2\" />\n Resolve Hook\n </DropdownMenuItem>\n );\n}\n\n// ============================================================================\n// Modal wrapper for convenience\n// ============================================================================\n\nexport interface HookResolveModalProps {\n /** The hook actions state from useHookActions */\n hookActions: UseHookActionsReturn;\n}\n\n/**\n * Convenience wrapper that renders the ResolveHookModal using useHookActions state.\n * Place this at the top level of your component (outside any iteration).\n */\nexport function HookResolveModalWrapper({\n hookActions,\n}: HookResolveModalProps): React.JSX.Element | null {\n const { selectedHook, closeResolveModal, handleResolve, isResolving } =\n hookActions;\n\n return (\n <ResolveHookModal\n isOpen={selectedHook !== null}\n onClose={closeResolveModal}\n onSubmit={handleResolve}\n isSubmitting={isResolving}\n />\n );\n}\n\n// Re-export the modal for direct use\nexport { ResolveHookModal } from './sidebar/resolve-hook-modal';\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAQlD,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,gBAAgB,EAChB,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EACL,mBAAmB,GAEpB,MAAM,gCAAgC,CAAC;AAKxC,OAAO,EAAoB,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEjE,OAAO,EACL,aAAa,EAEb,mBAAmB,GAEpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAA2B,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export { ErrorBoundary } from './error-boundary';\nexport { EventListView } from './event-list-view';\nexport type {\n HookActionCallbacks,\n HookActionsDropdownItemProps,\n HookResolveModalProps,\n UseHookActionsOptions,\n UseHookActionsReturn,\n} from './hook-actions';\nexport {\n HookResolveModalWrapper,\n ResolveHookDropdownItem,\n ResolveHookModal,\n useHookActions,\n} from './hook-actions';\nexport { RunTraceView } from './run-trace-view';\nexport { ConversationView } from './sidebar/conversation-view';\nexport {\n SidebarDataProvider,\n type SidebarDataContextValue,\n} from './sidebar/sidebar-data-context';\nexport type {\n SelectedSpanInfo,\n SpanSelectionInfo,\n} from './sidebar/entity-detail-panel';\nexport { type StreamChunk, StreamViewer } from './stream-viewer';\nexport type { Span, SpanEvent } from './trace-viewer/types';\nexport {\n DataInspector,\n type DataInspectorProps,\n DecryptClickContext,\n type DecryptClickContextValue,\n} from './ui/data-inspector';\nexport { DecryptButton } from './ui/decrypt-button';\nexport { LoadMoreButton } from './ui/load-more-button';\nexport { MenuDropdown, type MenuDropdownOption } from './ui/menu-dropdown';\nexport { Spinner } from './ui/spinner';\nexport { WorkflowTraceViewer } from './workflow-trace-view';\nexport { NewTraceViewer } from './trace-viewer-new';\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"copy-button.js","sourceRoot":"","sources":["../../../../src/components/new-trace-viewer/components/copy-button.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAY,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAQxC,MAAM,UAAU,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,SAAS,GACO;IAChB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,MAAM,CAAuC,IAAI,CAAC,CAAC;IAEtE,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,GAAG,EAAE;YACV,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;gBACvB,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,iBACE,IAAI,EAAC,QAAQ,gBACD,SAAS,EACrB,SAAS,EAAE,EAAE,CACX,sFAAsF,EACtF,SAAS,CACV,EACD,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;YACb,CAAC,CAAC,eAAe,EAAE,CAAC;YACpB,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;gBACvB,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC;YACD,KAAK,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;gBACrD,SAAS,CAAC,IAAI,CAAC,CAAC;gBAChB,UAAU,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;QACL,CAAC,YAED,eAAK,SAAS,EAAC,kBAAkB,aAC/B,cACE,SAAS,EAAE,EAAE,CACX,wFAAwF,EACxF,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,mBAAmB,CACvD,YAED,KAAC,KAAK,IAAC,SAAS,EAAC,SAAS,GAAG,GACzB,EACN,cACE,SAAS,EAAE,EAAE,CACX,wFAAwF,EACxF,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,uBAAuB,CACvD,YAED,KAAC,IAAI,IAAC,SAAS,EAAC,SAAS,GAAG,GACxB,IACF,GACC,CACV,CAAC;AACJ,CAAC","sourcesContent":["'use client';\n\nimport { Check, Copy } from 'lucide-react';\nimport { type JSX, useEffect, useRef, useState } from 'react';\nimport { cn } from '../../../lib/utils';\n\ninterface CopyButtonProps {\n copyText: string;\n ariaLabel: string;\n className?: string;\n}\n\nexport function CopyButton({\n copyText,\n ariaLabel,\n className,\n}: CopyButtonProps): JSX.Element {\n const [copied, setCopied] = useState(false);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n return (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n className={cn(\n 'cursor-pointer text-gray-800 hover:text-gray-1000 bg-transparent border-none p-1 m-0',\n className\n )}\n onClick={(e) => {\n e.stopPropagation();\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n void navigator.clipboard.writeText(copyText).then(() => {\n setCopied(true);\n timeoutRef.current = setTimeout(() => setCopied(false), 1000);\n });\n }}\n >\n <div className=\"relative w-3 h-3\">\n <div\n className={cn(\n 'absolute inset-0 flex items-center justify-center transition-all duration-150 ease-out',\n copied ? 'scale-100 opacity-100' : 'scale-0 opacity-0'\n )}\n >\n <Check className=\"w-3 h-3\" />\n </div>\n <div\n className={cn(\n 'absolute inset-0 flex items-center justify-center transition-all duration-150 ease-out',\n copied ? 'scale-0 opacity-0' : 'scale-100 opacity-100'\n )}\n >\n <Copy className=\"w-3 h-3\" />\n </div>\n </div>\n </button>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-list.js","sourceRoot":"","sources":["../../../../src/components/new-trace-viewer/components/event-list.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Circle } from 'lucide-react';\nimport { cn } from '../../../lib/utils';\nimport type { Span } from '../../trace-viewer/types';\nimport { formatDuration } from '../../trace-viewer/util/timing';\nimport {\n WorkflowIcon,\n WebhookIcon,\n SleepIcon,\n StepForwardIcon,\n} from '../icons';\nimport { getSpanDurationMs } from '../utils';\nimport { MiddleTruncate } from './middle-truncate/middle-truncate';\n\ninterface EventStyle {\n icon: React.ComponentType<{ className?: string }>;\n className: string;\n}\n\nconst eventStyles: Record<string, EventStyle> = {\n run: { icon: WorkflowIcon, className: 'text-blue-900' },\n step: { icon: StepForwardIcon, className: 'text-green-900' },\n hook: { icon: WebhookIcon, className: 'text-yellow-900' },\n sleep: { icon: SleepIcon, className: 'text-gray-900' },\n};\n\nconst defaultStyle: EventStyle = {\n icon: Circle,\n className: 'text-gray-900',\n};\n\nconst ROW_HEIGHT_CLASS = 'h-10';\n\nfunction getEventStyle(resource: string, isErrored: boolean): EventStyle {\n const style = eventStyles[resource] ?? defaultStyle;\n return {\n icon: style.icon,\n className: cn(isErrored ? 'text-red-900' : style.className),\n };\n}\n\nconst EventRow = ({\n span,\n isSelected,\n onSelectSpan,\n}: {\n span: Span;\n isSelected: boolean;\n onSelectSpan: (spanId: string) => void;\n}) => {\n const durationMs = getSpanDurationMs(span);\n const isErrored =\n (span.attributes.data as Record<string, unknown>).status === 'failed';\n const { icon: Icon, className: tagClassName } = getEventStyle(\n span.resource,\n isErrored\n );\n\n return (\n <li\n className={cn(\n 'relative overflow-clip group after:absolute after:inset-x-0 after:bottom-0 after:h-px after:bg-gray-alpha-400',\n ROW_HEIGHT_CLASS\n )}\n role=\"treeitem\"\n aria-selected={isSelected}\n aria-expanded={isSelected}\n aria-level={1}\n onClick={() => onSelectSpan(span.spanId)}\n >\n <div className=\"h-full hover:bg-gray-100 group-aria-selected:bg-gray-100 group-aria-selected:hover:bg-gray-200\">\n <div className=\"flex h-full min-w-0 items-center px-2\">\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n <span className={cn('shrink-0', tagClassName)}>\n <Icon className=\"w-4 h-4\" />\n </span>\n <span className=\"min-w-0 text-label-14\">\n <MiddleTruncate value={span.name} />\n </span>\n </div>\n <div className=\"ml-2 shrink-0\">\n <span className=\"text-label-14 text-gray-900 tabular-nums\">\n {formatDuration(durationMs)}\n </span>\n </div>\n </div>\n </div>\n </li>\n );\n};\n\nconst EventList = ({\n spans,\n activeSpanId,\n onSelectSpan,\n}: {\n spans: Span[];\n activeSpanId: string | null;\n onSelectSpan: (spanId: string) => void;\n}) => {\n return (\n <ul id=\"event-list\" role=\"tree\" className=\"block min-h-0 overflow-visible\">\n {spans.map((span) => {\n return (\n <EventRow\n key={span.spanId}\n span={span}\n isSelected={span.spanId === activeSpanId}\n onSelectSpan={onSelectSpan}\n />\n );\n })}\n </ul>\n );\n};\n\nexport default EventList;\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"copy-selection.js","sourceRoot":"","sources":["../../../../../src/components/new-trace-viewer/components/middle-truncate/copy-selection.ts"],"names":[],"mappings":"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","sourcesContent":["import { ELLIPSIS, toGraphemes } from './truncate';\n\ninterface GetMiddleTruncateCopyTextOptions {\n prefixText: string;\n selectionEnd: number;\n selectionStart: number;\n suffixText: string;\n value: string;\n}\n\ninterface GetMiddleTruncateCopyTextFromSelectionTextOptions {\n prefixText: string;\n selectionText: string;\n suffixText: string;\n value: string;\n}\n\nfunction getMiddleTruncateCopyText({\n prefixText,\n selectionEnd,\n selectionStart,\n suffixText,\n value,\n}: GetMiddleTruncateCopyTextOptions): string | null {\n const visibleText = prefixText + ELLIPSIS + suffixText;\n\n if (\n selectionStart < 0 ||\n selectionEnd > visibleText.length ||\n selectionStart >= selectionEnd\n ) {\n return null;\n }\n\n if (selectionStart === 0 && selectionEnd === visibleText.length) {\n return value;\n }\n\n const ellipsisStart = prefixText.length;\n const ellipsisEnd = ellipsisStart + ELLIPSIS.length;\n\n if (selectionStart > ellipsisStart || selectionEnd < ellipsisEnd) {\n return null;\n }\n\n const originalGraphemes = toGraphemes(value);\n const selectedPrefixGraphemeCount = toGraphemes(\n visibleText.slice(0, selectionStart)\n ).length;\n const selectedSuffixGraphemeCount = toGraphemes(\n visibleText.slice(ellipsisEnd, selectionEnd)\n ).length;\n const suffixStart = originalGraphemes.length - toGraphemes(suffixText).length;\n\n return originalGraphemes\n .slice(\n selectedPrefixGraphemeCount,\n suffixStart + selectedSuffixGraphemeCount\n )\n .join('');\n}\n\nfunction getMiddleTruncateCopyTextFromSelectionText({\n prefixText,\n selectionText,\n suffixText,\n value,\n}: GetMiddleTruncateCopyTextFromSelectionTextOptions): string | null {\n const visibleText = prefixText + ELLIPSIS + suffixText;\n const trimmedSelectionText = selectionText.trim();\n\n if (!trimmedSelectionText) {\n return null;\n }\n\n const leading = selectionText.slice(\n 0,\n selectionText.length - selectionText.trimStart().length\n );\n const trailing = selectionText.slice(selectionText.trimEnd().length);\n\n if (trimmedSelectionText === visibleText) {\n return leading + value + trailing;\n }\n\n if (!trimmedSelectionText.includes(ELLIPSIS)) {\n return null;\n }\n\n const selectionStart = visibleText.indexOf(trimmedSelectionText);\n if (selectionStart === -1) {\n return null;\n }\n\n const selectionEnd = selectionStart + trimmedSelectionText.length;\n const mappedText = getMiddleTruncateCopyText({\n prefixText,\n selectionEnd,\n selectionStart,\n suffixText,\n value,\n });\n\n return mappedText === null ? null : leading + mappedText + trailing;\n}\n\nexport {\n getMiddleTruncateCopyText,\n getMiddleTruncateCopyTextFromSelectionText,\n};\nexport type {\n GetMiddleTruncateCopyTextFromSelectionTextOptions,\n GetMiddleTruncateCopyTextOptions,\n};\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"middle-truncate.js","sourceRoot":"","sources":["../../../../../src/components/new-trace-viewer/components/middle-truncate/middle-truncate.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { useCallback, useRef } from 'react';\nimport type { ClipboardEvent, ComponentPropsWithoutRef, JSX } from 'react';\nimport { cn } from '../../../../lib/utils';\nimport {\n getMiddleTruncateCopyText,\n getMiddleTruncateCopyTextFromSelectionText,\n} from './copy-selection';\nimport { ELLIPSIS } from './truncate';\nimport { useMiddleTruncate } from './use-middle-truncate';\n\n/** Props for the {@link MiddleTruncate} component. */\ninterface MiddleTruncateProps\n extends Omit<ComponentPropsWithoutRef<'span'>, 'children'> {\n /** The full text string to display, truncated from the middle when it overflows. */\n value: string;\n}\n\nfunction getRangeOffsets(\n container: HTMLElement,\n range: Range\n): { end: number; start: number } | null {\n if (\n !container.contains(range.startContainer) ||\n !container.contains(range.endContainer)\n ) {\n return null;\n }\n\n const startRange = document.createRange();\n startRange.selectNodeContents(container);\n startRange.setEnd(range.startContainer, range.startOffset);\n\n const endRange = document.createRange();\n endRange.selectNodeContents(container);\n endRange.setEnd(range.endContainer, range.endOffset);\n\n return {\n end: endRange.toString().length,\n start: startRange.toString().length,\n };\n}\n\n/**\n * @gdoc\n *\n * Truncates text from the middle with an ellipsis when it overflows, preserving the beginning and end (e.g. file paths, URLs). Copy behavior restores the full untruncated text to the clipboard.\n * Renders a `<span>` element.\n *\n * Documentation: [Geist Middle Truncate](https://vercel.com/geist/middle-truncate)\n *\n * @param value - Full text string to display.\n */\nfunction MiddleTruncate({\n value,\n className,\n onCopy: onCopyProp,\n ...props\n}: MiddleTruncateProps): JSX.Element {\n const { ref, measureRef, displayText, isTruncated, prefixText, suffixText } =\n useMiddleTruncate(value);\n const visibleRef = useRef<HTMLSpanElement | null>(null);\n\n const handleCopy = useCallback(\n (e: ClipboardEvent<HTMLSpanElement>) => {\n onCopyProp?.(e);\n if (e.defaultPrevented || !isTruncated) return;\n\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return;\n const selectionText = selection.toString();\n if (!selectionText) return;\n\n // Only intercept when the selection is fully within this element.\n // If the user selected across elements (e.g. a table row), let\n // the browser's default behavior preserve surrounding context.\n const range = selection.getRangeAt(0);\n const visibleEl = visibleRef.current;\n let copyText: string | null = null;\n\n if (\n e.currentTarget.contains(range.startContainer) &&\n e.currentTarget.contains(range.endContainer) &&\n visibleEl\n ) {\n const offsets = getRangeOffsets(visibleEl, range);\n if (offsets) {\n copyText = getMiddleTruncateCopyText({\n prefixText,\n selectionEnd: offsets.end,\n selectionStart: offsets.start,\n suffixText,\n value,\n });\n }\n }\n\n copyText ??= getMiddleTruncateCopyTextFromSelectionText({\n prefixText,\n selectionText,\n suffixText,\n value,\n });\n\n if (copyText === null) return;\n\n e.preventDefault();\n e.clipboardData.setData('text/plain', copyText);\n },\n [onCopyProp, isTruncated, prefixText, suffixText, value]\n );\n\n return (\n <span\n title={isTruncated ? value : undefined}\n {...props}\n ref={ref}\n className={cn(\n 'relative inline-grid min-w-0 max-w-full overflow-hidden whitespace-nowrap',\n className\n )}\n onCopy={handleCopy}\n >\n {isTruncated && <span className=\"sr-only select-none\">{value}</span>}\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none col-start-1 row-start-1 invisible select-none whitespace-nowrap\"\n >\n {value}\n </span>\n <span\n aria-hidden={isTruncated || undefined}\n className=\"col-start-1 row-start-1 min-w-0 overflow-hidden\"\n ref={visibleRef}\n >\n {isTruncated ? (\n <>\n <span>{prefixText}</span>\n <span>{ELLIPSIS}</span>\n <span>{suffixText}</span>\n </>\n ) : (\n displayText\n )}\n </span>\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-0 top-0 inline-block invisible select-none whitespace-nowrap\"\n ref={measureRef}\n />\n </span>\n );\n}\n\nexport { MiddleTruncate };\nexport type { MiddleTruncateProps };\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"truncate.js","sourceRoot":"","sources":["../../../../../src/components/new-trace-viewer/components/middle-truncate/truncate.ts"],"names":[],"mappings":"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","sourcesContent":["const ELLIPSIS = '...';\nconst MIN_START = 3;\nconst MIN_END = 3;\nconst MIN_KEPT = MIN_START + MIN_END;\nconst graphemeSegmenter =\n typeof Intl !== 'undefined' && 'Segmenter' in Intl\n ? new Intl.Segmenter(undefined, { granularity: 'grapheme' })\n : null;\n\ntype MeasureFn = (text: string) => number;\n\n/**\n * Splits a string into grapheme clusters using Intl.Segmenter.\n * Falls back to Array.from for environments without Intl.Segmenter.\n */\nfunction toGraphemes(text: string): string[] {\n if (graphemeSegmenter) {\n return [...graphemeSegmenter.segment(text)].map((s) => s.segment);\n }\n return Array.from(text);\n}\n\ninterface TruncateResult {\n prefixText: string;\n prefixGraphemeCount: number;\n suffixText: string;\n suffixGraphemeCount: number;\n text: string;\n truncated: boolean;\n}\n\nfunction buildCandidate(graphemes: string[], kept: number): TruncateResult {\n if (kept <= 0) {\n return {\n prefixText: '',\n prefixGraphemeCount: 0,\n suffixText: '',\n suffixGraphemeCount: 0,\n text: ELLIPSIS,\n truncated: true,\n };\n }\n\n const suffixGraphemeCount =\n kept >= MIN_KEPT\n ? Math.max(MIN_END, Math.floor(kept / 2))\n : Math.floor(kept / 2);\n const prefixGraphemeCount = kept - suffixGraphemeCount;\n const prefixText = graphemes.slice(0, prefixGraphemeCount).join('');\n const suffixText =\n suffixGraphemeCount > 0\n ? graphemes.slice(-suffixGraphemeCount).join('')\n : '';\n\n return {\n prefixText,\n prefixGraphemeCount,\n suffixText,\n suffixGraphemeCount,\n text: prefixText + ELLIPSIS + suffixText,\n truncated: true,\n };\n}\n\n/**\n * Middle-truncates a string so `prefix...suffix` fits within `availableWidth`.\n * Uses binary search over grapheme clusters with an injectable measure function.\n */\nfunction middleTruncate(\n graphemes: string[],\n availableWidth: number,\n measure: MeasureFn,\n fullWidth?: number\n): TruncateResult {\n const fullText = graphemes.join('');\n const resolvedFullWidth = fullWidth ?? measure(fullText);\n\n if (availableWidth <= 0 || graphemes.length === 0) {\n return {\n prefixText: fullText,\n prefixGraphemeCount: graphemes.length,\n suffixText: '',\n suffixGraphemeCount: 0,\n text: fullText,\n truncated: false,\n };\n }\n\n if (resolvedFullWidth <= availableWidth) {\n return {\n prefixText: fullText,\n prefixGraphemeCount: graphemes.length,\n suffixText: '',\n suffixGraphemeCount: 0,\n text: fullText,\n truncated: false,\n };\n }\n\n // Binary search for the maximum number of kept graphemes\n let lo = 0;\n let hi = graphemes.length - 1;\n let best = -1;\n\n while (lo <= hi) {\n const mid = (lo + hi) >>> 1;\n const candidate = buildCandidate(graphemes, mid);\n\n if (measure(candidate.text) <= availableWidth) {\n best = mid;\n lo = mid + 1;\n } else {\n hi = mid - 1;\n }\n }\n\n if (best === -1) {\n return {\n prefixText: '',\n prefixGraphemeCount: 0,\n suffixText: '',\n suffixGraphemeCount: 0,\n text: '',\n truncated: true,\n };\n }\n\n return buildCandidate(graphemes, best);\n}\n\nexport { middleTruncate, toGraphemes, ELLIPSIS, MIN_START, MIN_END };\nexport type { MeasureFn, TruncateResult };\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-middle-truncate.js","sourceRoot":"","sources":["../../../../../src/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { middleTruncate, toGraphemes } from './truncate';\n\nconst useIsomorphicLayoutEffect =\n typeof window === 'undefined' ? useEffect : useLayoutEffect;\n\ninterface MiddleTruncateState {\n displayText: string;\n isTruncated: boolean;\n prefixGraphemeCount: number;\n prefixText: string;\n suffixGraphemeCount: number;\n suffixText: string;\n}\n\nfunction createFullState(\n value: string,\n graphemes: string[]\n): MiddleTruncateState {\n return {\n displayText: value,\n isTruncated: false,\n prefixGraphemeCount: graphemes.length,\n prefixText: value,\n suffixGraphemeCount: 0,\n suffixText: '',\n };\n}\n\n/**\n * Middle-truncation logic. Returns refs to attach to the container and measurement elements, plus the truncated display text. Recalculates on resize, font loading, and value changes.\n * Powers the `<MiddleTruncate>` (`<span>`) component.\n *\n * Documentation: [Geist Middle Truncate](https://vercel.com/geist/middle-truncate)\n *\n * @param value - Full text string to truncate.\n */\nfunction useMiddleTruncate(value: string): {\n ref: React.RefObject<HTMLSpanElement | null>;\n measureRef: React.RefObject<HTMLSpanElement | null>;\n displayText: string;\n isTruncated: boolean;\n prefixGraphemeCount: number;\n prefixText: string;\n suffixGraphemeCount: number;\n suffixText: string;\n} {\n const graphemes = useMemo(() => toGraphemes(value), [value]);\n const fullState = useMemo(\n () => createFullState(value, graphemes),\n [graphemes, value]\n );\n const ref = useRef<HTMLSpanElement | null>(null);\n const measureRef = useRef<HTMLSpanElement | null>(null);\n const [state, setState] = useState<MiddleTruncateState>(() => fullState);\n const rafRef = useRef<number>(0);\n\n const updateState = useCallback((nextState: MiddleTruncateState) => {\n setState((currentState) => {\n if (\n currentState.displayText === nextState.displayText &&\n currentState.isTruncated === nextState.isTruncated &&\n currentState.prefixText === nextState.prefixText &&\n currentState.prefixGraphemeCount === nextState.prefixGraphemeCount &&\n currentState.suffixText === nextState.suffixText &&\n currentState.suffixGraphemeCount === nextState.suffixGraphemeCount\n ) {\n return currentState;\n }\n\n return nextState;\n });\n }, []);\n\n const recalculate = useCallback(() => {\n const el = ref.current;\n const measureEl = measureRef.current;\n if (!el || !measureEl) return;\n\n const available = el.clientWidth;\n\n if (available <= 0) {\n updateState(fullState);\n return;\n }\n\n const measure = (text: string): number => {\n measureEl.textContent = text;\n return measureEl.scrollWidth;\n };\n\n const fullWidth = measure(value);\n\n if (fullWidth <= available) {\n updateState(fullState);\n return;\n }\n\n const result = middleTruncate(graphemes, available, measure, fullWidth);\n updateState({\n displayText: result.text,\n isTruncated: result.truncated,\n prefixGraphemeCount: result.prefixGraphemeCount,\n prefixText: result.prefixText,\n suffixGraphemeCount: result.suffixGraphemeCount,\n suffixText: result.suffixText,\n });\n }, [fullState, graphemes, updateState, value]);\n\n // Measure on mount and when value changes - before paint\n useIsomorphicLayoutEffect(() => {\n recalculate();\n }, [recalculate]);\n\n // ResizeObserver + font loading for ongoing responsiveness\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n const debouncedRecalc = (): void => {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(recalculate);\n };\n\n const ro =\n typeof ResizeObserver !== 'undefined'\n ? new ResizeObserver(debouncedRecalc)\n : null;\n ro?.observe(el);\n window.addEventListener('resize', debouncedRecalc);\n\n const onFontsLoaded = (): void => {\n debouncedRecalc();\n };\n const fontSet = 'fonts' in document ? document.fonts : null;\n fontSet?.addEventListener?.('loadingdone', onFontsLoaded);\n\n return () => {\n ro?.disconnect();\n window.removeEventListener('resize', debouncedRecalc);\n cancelAnimationFrame(rafRef.current);\n fontSet?.removeEventListener?.('loadingdone', onFontsLoaded);\n };\n }, [recalculate]);\n\n return {\n ref,\n measureRef,\n displayText: state.displayText,\n isTruncated: state.isTruncated,\n prefixGraphemeCount: state.prefixGraphemeCount,\n prefixText: state.prefixText,\n suffixGraphemeCount: state.suffixGraphemeCount,\n suffixText: state.suffixText,\n };\n}\n\nexport { useMiddleTruncate };\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"split-pane.js","sourceRoot":"","sources":["../../../../src/components/new-trace-viewer/components/split-pane.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport {\n Children,\n type ReactNode,\n type PointerEvent as ReactPointerEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../../../lib/utils';\n\nconst GUTTER_PX = 1;\nconst MIN_PX = 50;\nconst DEFAULT_START_PX = 340;\n\nexport function Divider() {\n return <div aria-hidden className=\"h-full w-px shrink-0 bg-gray-alpha-400\" />;\n}\n\nexport interface SplitPaneProps {\n children: ReactNode;\n className?: string;\n /** Fixed pixel width for the start (left) pane. Default 220. */\n defaultStartWidth?: number;\n /** Fixed (non-scrolling) header rendered above the start pane. */\n startHeader?: ReactNode;\n /** Fixed (non-scrolling) header rendered above the end pane. */\n endHeader?: ReactNode;\n}\n\nexport function SplitPane({\n children,\n className,\n defaultStartWidth = DEFAULT_START_PX,\n startHeader,\n endHeader,\n}: SplitPaneProps) {\n const parts = Children.toArray(children);\n if (parts.length !== 2) {\n throw new Error('SplitPane expects exactly two children');\n }\n const [start, end] = parts;\n\n const [startPx, setStartPx] = useState(defaultStartWidth);\n const [isDragging, setIsDragging] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const gutterRef = useRef<HTMLDivElement>(null);\n const rafRef = useRef<number | null>(null);\n const pendingPx = useRef(defaultStartWidth);\n const pointerIdRef = useRef<number | null>(null);\n\n useEffect(() => {\n return () => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n };\n }, []);\n\n const clampPx = useCallback((px: number) => {\n const el = containerRef.current;\n if (!el) return px;\n const maxPx = el.getBoundingClientRect().width - MIN_PX - GUTTER_PX;\n return Math.min(maxPx, Math.max(MIN_PX, px));\n }, []);\n\n useEffect(() => {\n if (!isDragging) return;\n\n const onPointerMove = (e: globalThis.PointerEvent) => {\n if (e.pointerId !== pointerIdRef.current) return;\n const container = containerRef.current;\n if (!container) return;\n const rect = container.getBoundingClientRect();\n pendingPx.current = clampPx(e.clientX - rect.left);\n if (!rafRef.current) {\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = null;\n setStartPx(pendingPx.current);\n });\n }\n };\n\n const onPointerUp = (e: globalThis.PointerEvent) => {\n if (e.pointerId !== pointerIdRef.current) return;\n const gutter = gutterRef.current;\n if (gutter?.hasPointerCapture(e.pointerId)) {\n gutter.releasePointerCapture(e.pointerId);\n }\n if (rafRef.current) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n pointerIdRef.current = null;\n setIsDragging(false);\n };\n\n document.addEventListener('pointermove', onPointerMove);\n document.addEventListener('pointerup', onPointerUp);\n document.addEventListener('pointercancel', onPointerUp);\n\n return () => {\n document.removeEventListener('pointermove', onPointerMove);\n document.removeEventListener('pointerup', onPointerUp);\n document.removeEventListener('pointercancel', onPointerUp);\n };\n }, [isDragging, clampPx]);\n\n const handlePointerDown = (e: ReactPointerEvent<HTMLDivElement>) => {\n e.currentTarget.setPointerCapture(e.pointerId);\n pointerIdRef.current = e.pointerId;\n setIsDragging(true);\n };\n\n const handleLostPointerCapture = () => {\n pointerIdRef.current = null;\n setIsDragging(false);\n if (rafRef.current) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n\n const colTemplate = `${startPx}px ${GUTTER_PX}px minmax(${MIN_PX}px, 1fr)`;\n const hasHeaders = startHeader != null || endHeader != null;\n\n const gutter = (\n <div\n ref={gutterRef}\n className=\"relative z-20 isolate flex shrink-0 cursor-col-resize justify-center\"\n onPointerDown={handlePointerDown}\n onLostPointerCapture={handleLostPointerCapture}\n >\n <span\n className=\"pointer-events-none relative z-10 h-full w-px shrink-0 bg-gray-alpha-400\"\n aria-hidden\n />\n </div>\n );\n\n if (hasHeaders) {\n return (\n <div className={cn('flex flex-col h-full min-h-0', className)}>\n <div\n className=\"shrink-0 grid\"\n style={{ gridTemplateColumns: colTemplate }}\n >\n <div>{startHeader}</div>\n <div className=\"flex justify-center\">\n <span className=\"h-full w-px bg-gray-alpha-400\" aria-hidden />\n </div>\n <div>{endHeader}</div>\n </div>\n <div\n ref={containerRef}\n className={cn(\n 'grid flex-1 min-h-0 overflow-x-hidden overflow-y-auto',\n isDragging && 'select-none'\n )}\n style={{ gridTemplateColumns: colTemplate }}\n >\n {start}\n {gutter}\n {end}\n </div>\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n className={cn(\n 'grid h-full min-h-0 content-start overflow-x-hidden overflow-y-auto',\n isDragging && 'select-none',\n className\n )}\n style={{ gridTemplateColumns: colTemplate, height: '100%' }}\n >\n {start}\n {gutter}\n {end}\n </div>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../../../src/components/new-trace-viewer/components/timeline.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { ArrowLeft, ArrowRight } from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport { memo, useEffect, useMemo, useRef, useState } from 'react';\nimport { cn } from '../../../lib/utils';\nimport type { Span } from '../../trace-viewer/types';\nimport { formatDuration, getHighResInMs } from '../../trace-viewer/util/timing';\nimport type { SegmentStatus, TimeMarker } from '../utils';\nimport {\n computeSpanGaps,\n computeSpanSegments,\n getSpanDurationMs,\n getResourceColor,\n} from '../utils';\n\nconst SEGMENT_CONFIG: Record<\n SegmentStatus,\n { className?: string; style?: React.CSSProperties }\n> = {\n queued: { className: 'bg-gray-500' },\n retrying: {\n className: 'box-border bg-gray-500',\n },\n waiting: { className: 'bg-gray-500' },\n running: { className: 'bg-blue-700' },\n failed: { className: 'bg-red-700' },\n succeeded: { className: 'bg-green-700' },\n sleeping: { className: 'bg-gray-500' },\n received: { className: 'bg-blue-700' },\n};\n\nconst BAR_HEIGHT_PX = 24;\nconst TINY_BAR_BOX_SIZE_PX = 24;\nconst TINY_BAR_WIDTH_PX = 4;\nconst SEGMENT_GAP_PX = 1;\n// Keep this in sync with the rendered row height in the timeline/event list.\nconst ROW_HEIGHT = 40;\nconst CONTAINER_PAD_Y = 8;\nconst END_CAP_HEIGHT = 8;\nexport const TIMELINE_PADDING_PX = 16;\nconst ORIGIN_MARKER_EPSILON = 0.000001;\n\nconst DeltaIndicator = memo(function DeltaIndicator({\n leftFrac,\n rightFrac,\n label,\n rowIndex,\n}: {\n leftFrac: number;\n rightFrac: number;\n label: string;\n rowIndex: number;\n}) {\n const centerY = CONTAINER_PAD_Y + (rowIndex + 1) * ROW_HEIGHT;\n\n return (\n <div\n className=\"absolute pointer-events-none\"\n style={{\n left: `${leftFrac * 100}%`,\n width: `${(rightFrac - leftFrac) * 100}%`,\n top: centerY - END_CAP_HEIGHT / 2,\n height: END_CAP_HEIGHT,\n }}\n >\n <div className=\"absolute left-0 top-0 w-px h-full bg-amber-800\" />\n <div className=\"absolute left-0 right-0 top-1/2 h-px bg-amber-800\" />\n <div className=\"absolute right-0 top-0 w-px h-full bg-amber-800\" />\n <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\">\n {label}\n </span>\n </div>\n );\n});\n\nconst TimelineBar = memo(function TimelineBar({\n span,\n viewStart,\n viewDuration,\n containerWidth,\n isSelected,\n onClick,\n}: {\n span: Span;\n viewStart: number;\n viewDuration: number;\n containerWidth: number;\n isSelected: boolean;\n onClick: () => void;\n}): ReactNode {\n const startTime = getHighResInMs(span.startTime);\n const endTime = getHighResInMs(span.endTime);\n const totalDurationMs = getSpanDurationMs(span);\n\n const leftFracRaw =\n viewDuration > 0 ? (startTime - viewStart) / viewDuration : 0;\n const rightFracRaw =\n viewDuration > 0 ? (endTime - viewStart) / viewDuration : 0;\n const widthFrac = rightFracRaw - leftFracRaw;\n\n const leftPct = leftFracRaw * 100;\n const widthPct = widthFrac * 100;\n\n const pixelWidth = widthFrac * containerWidth;\n const visibleLeftFrac = Math.max(0, Math.min(1, leftFracRaw));\n const visibleRightFrac = Math.max(0, Math.min(1, rightFracRaw));\n const visiblePixelWidth =\n Math.max(0, visibleRightFrac - visibleLeftFrac) * containerWidth;\n const isTinyBar =\n containerWidth > 0 && visiblePixelWidth < TINY_BAR_BOX_SIZE_PX;\n const [isRowHovered, setIsRowHovered] = useState(false);\n\n const segments = useMemo(() => computeSpanSegments(span), [span]);\n\n const workflowStatus = (span.attributes.data as Record<string, unknown>)\n ?.status as string | undefined;\n const isErrored = span.status.code === 2 || workflowStatus === 'failed';\n const colors = getResourceColor(span.resource);\n const fallbackColor = isErrored\n ? (colors.errorBar ?? 'var(--ds-red-700)')\n : colors.bar;\n const renderDurationLabel = (label: string) => (\n <span\n 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\"\n style={{ textShadow: '0 1px 1px rgba(0, 0, 0, 0.45)' }}\n >\n {label}\n </span>\n );\n const getMinDurationLabelWidthPx = (label: string) =>\n Math.max(40, label.length * 6 + 12);\n const totalDurationLabel = formatDuration(totalDurationMs);\n const showBarDurationLabel =\n isRowHovered &&\n pixelWidth >= getMinDurationLabelWidthPx(totalDurationLabel);\n\n const showBoundaryArrow = isTinyBar && (leftFracRaw < 0 || rightFracRaw > 1);\n const BoundaryArrow = leftFracRaw < 0.5 ? ArrowLeft : ArrowRight;\n const barContent = showBoundaryArrow ? (\n <div className=\"flex h-6 w-6 items-center justify-center rounded-[0.25rem]\">\n <BoundaryArrow className=\"size-3 text-gray-900\" />\n </div>\n ) : isTinyBar ? (\n <div\n className=\"h-6 rounded-[0.25rem]\"\n style={{ background: fallbackColor }}\n />\n ) : segments.length > 0 ? (\n <div className=\"relative h-6 w-full\">\n {segments.map((seg, i) => {\n const segPixelWidth =\n (seg.endFraction - seg.startFraction) * pixelWidth;\n const segDurationLabel = formatDuration(\n (seg.endFraction - seg.startFraction) * totalDurationMs\n );\n const showSegmentDurationLabel =\n isRowHovered &&\n segPixelWidth >= getMinDurationLabelWidthPx(segDurationLabel);\n const segStyle =\n seg.status === 'queued' && segPixelWidth < 20\n ? { background: 'var(--ds-gray-500)' }\n : SEGMENT_CONFIG[seg.status].style;\n\n return (\n <div\n key={`${seg.status}-${i}`}\n className={cn(\n 'absolute h-full rounded-[0.25rem]',\n SEGMENT_CONFIG[seg.status].className\n )}\n style={{\n left: `calc(${seg.startFraction * 100}% + ${SEGMENT_GAP_PX / 2}px)`,\n width: `calc(${(seg.endFraction - seg.startFraction) * 100}% - ${SEGMENT_GAP_PX}px)`,\n minWidth: 1,\n ...segStyle,\n }}\n >\n {showSegmentDurationLabel\n ? renderDurationLabel(segDurationLabel)\n : null}\n </div>\n );\n })}\n </div>\n ) : (\n <div\n className=\"relative h-6 rounded-[0.25rem]\"\n style={{\n width: '100%',\n minWidth: 4,\n background: fallbackColor,\n }}\n >\n {showBarDurationLabel ? renderDurationLabel(totalDurationLabel) : null}\n </div>\n );\n\n return (\n <div\n role=\"treeitem\"\n aria-selected={isSelected}\n aria-expanded={isSelected}\n aria-level={1}\n className={cn(\n 'h-10 relative flex items-center hover:bg-gray-100 aria-selected:bg-gray-100 aria-selected:hover:bg-gray-200'\n )}\n onMouseEnter={() => setIsRowHovered(true)}\n onMouseLeave={() => setIsRowHovered(false)}\n onClick={onClick}\n >\n <div\n className=\"absolute inset-y-0\"\n style={{\n left: TIMELINE_PADDING_PX,\n right: TIMELINE_PADDING_PX,\n }}\n >\n <div\n className=\"absolute top-1/2 -translate-y-1/2\"\n style={{\n left: showBoundaryArrow\n ? `min(max(${leftPct}%, 0px), calc(100% - ${TINY_BAR_BOX_SIZE_PX}px))`\n : isTinyBar\n ? `min(${leftPct}%, calc(100% - ${TINY_BAR_WIDTH_PX}px))`\n : `${leftPct}%`,\n width: showBoundaryArrow\n ? `${TINY_BAR_BOX_SIZE_PX}px`\n : isTinyBar\n ? `${TINY_BAR_WIDTH_PX}px`\n : `max(${widthPct}%, 4px)`,\n height: BAR_HEIGHT_PX,\n }}\n >\n {barContent}\n </div>\n </div>\n </div>\n );\n});\n\nexport { TimelineBar };\n\nexport function TimelineHeader({\n markers,\n hoverInfo,\n}: {\n markers: TimeMarker[];\n hoverInfo?: { fraction: number; label: string } | null;\n}): ReactNode {\n return (\n <div className=\"relative bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-end px-4 pb-1\">\n <div className=\"relative h-full flex-1\">\n {markers.map((m) => (\n <span\n key={`${m.position}-${m.label}`}\n className=\"absolute bottom-1 font-mono text-xs font-normal leading-4 text-gray-900 whitespace-nowrap\"\n style={{ left: `${m.position * 100}%` }}\n >\n {m.label}\n </span>\n ))}\n {hoverInfo && (\n <span\n 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\"\n style={{ left: `${hoverInfo.fraction * 100}%` }}\n >\n {hoverInfo.label}\n </span>\n )}\n </div>\n </div>\n );\n}\n\nexport function Timeline({\n spans,\n viewStart,\n viewEnd,\n markers,\n selectedId,\n onSelect,\n hoverFraction,\n altHeld = false,\n}: {\n spans: Span[];\n viewStart: number;\n viewEnd: number;\n markers: TimeMarker[];\n selectedId: string | null;\n onSelect: (spanId: string) => void;\n hoverFraction?: number | null;\n altHeld?: boolean;\n}): ReactNode {\n const containerRef = useRef<HTMLDivElement>(null);\n const [containerWidth, setContainerWidth] = useState(0);\n const viewDuration = viewEnd - viewStart;\n const timelineWidth = Math.max(0, containerWidth - TIMELINE_PADDING_PX * 2);\n\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n const ro = new ResizeObserver(([entry]) => {\n setContainerWidth(entry.contentRect.width);\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n\n const gaps = useMemo(\n () => computeSpanGaps(spans, viewStart, viewEnd),\n [spans, viewStart, viewEnd]\n );\n\n return (\n <div ref={containerRef} className=\"relative h-full overflow-hidden\">\n <div\n aria-hidden\n className=\"absolute inset-y-0 pointer-events-none\"\n style={{\n left: TIMELINE_PADDING_PX,\n right: TIMELINE_PADDING_PX,\n }}\n >\n {markers.map((marker) =>\n Math.abs(marker.value) > ORIGIN_MARKER_EPSILON ? (\n <div\n key={`${marker.position}-${marker.label}`}\n className=\"absolute top-0 bottom-0 w-px bg-gray-alpha-300\"\n style={{ left: `${marker.position * 100}%` }}\n />\n ) : null\n )}\n </div>\n {hoverFraction != null && (\n <div\n className=\"absolute inset-y-0 pointer-events-none z-10\"\n style={{\n left: TIMELINE_PADDING_PX,\n right: TIMELINE_PADDING_PX,\n }}\n >\n <div\n className=\"absolute top-0 bottom-0 w-px bg-gray-alpha-400\"\n style={{ left: `${hoverFraction * 100}%` }}\n />\n </div>\n )}\n {spans.map((span) => (\n <TimelineBar\n key={span.spanId}\n span={span}\n viewStart={viewStart}\n viewDuration={viewDuration}\n containerWidth={timelineWidth}\n isSelected={selectedId === span.spanId}\n onClick={() => onSelect(span.spanId)}\n />\n ))}\n {altHeld && (\n <div\n aria-hidden\n className=\"absolute inset-y-0 pointer-events-none\"\n style={{\n left: TIMELINE_PADDING_PX,\n right: TIMELINE_PADDING_PX,\n }}\n >\n {gaps.map((gap) => (\n <DeltaIndicator\n key={gap.rowIndex}\n leftFrac={gap.leftFrac}\n rightFrac={gap.rightFrac}\n label={formatDuration(gap.gapMs, true)}\n rowIndex={gap.rowIndex}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n"]}