@workflow/web-shared 5.0.0-beta.7 → 5.0.0-beta.9

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 (211) 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.d.ts +1 -0
  7. package/dist/components/index.d.ts.map +1 -1
  8. package/dist/components/index.js +2 -1
  9. package/dist/components/new-trace-viewer/components/copy-button.js +2 -2
  10. package/dist/components/new-trace-viewer/components/event-list.d.ts +3 -1
  11. package/dist/components/new-trace-viewer/components/event-list.d.ts.map +1 -1
  12. package/dist/components/new-trace-viewer/components/event-list.js +8 -7
  13. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js +1 -1
  14. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js +1 -1
  15. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js +1 -1
  16. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js +1 -1
  17. package/dist/components/new-trace-viewer/components/split-pane.js +1 -1
  18. package/dist/components/new-trace-viewer/components/timeline.d.ts +4 -1
  19. package/dist/components/new-trace-viewer/components/timeline.d.ts.map +1 -1
  20. package/dist/components/new-trace-viewer/components/timeline.js +6 -5
  21. package/dist/components/new-trace-viewer/context.js +1 -1
  22. package/dist/components/new-trace-viewer/detail-panel.d.ts.map +1 -1
  23. package/dist/components/new-trace-viewer/detail-panel.js +3 -2
  24. package/dist/components/new-trace-viewer/icons.js +1 -1
  25. package/dist/components/new-trace-viewer/search.d.ts +19 -0
  26. package/dist/components/new-trace-viewer/search.d.ts.map +1 -0
  27. package/dist/components/new-trace-viewer/search.js +134 -0
  28. package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +1 -1
  29. package/dist/components/new-trace-viewer/trace-viewer.js +62 -35
  30. package/dist/components/new-trace-viewer/types.js +1 -1
  31. package/dist/components/new-trace-viewer/util/constants.js +1 -1
  32. package/dist/components/new-trace-viewer/utils.js +1 -1
  33. package/dist/components/run-trace-view.js +1 -1
  34. package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
  35. package/dist/components/sidebar/attribute-panel.js +99 -73
  36. package/dist/components/sidebar/conversation-view.js +1 -1
  37. package/dist/components/sidebar/copyable-data-block.d.ts +1 -0
  38. package/dist/components/sidebar/copyable-data-block.d.ts.map +1 -1
  39. package/dist/components/sidebar/copyable-data-block.js +16 -15
  40. package/dist/components/sidebar/detail-card.d.ts +5 -6
  41. package/dist/components/sidebar/detail-card.d.ts.map +1 -1
  42. package/dist/components/sidebar/detail-card.js +32 -16
  43. package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -1
  44. package/dist/components/sidebar/entity-detail-panel.js +6 -3
  45. package/dist/components/sidebar/events-list.d.ts.map +1 -1
  46. package/dist/components/sidebar/events-list.js +21 -15
  47. package/dist/components/sidebar/resolve-hook-modal.js +1 -1
  48. package/dist/components/sidebar/sidebar-data-context.js +1 -1
  49. package/dist/components/stream-viewer.js +1 -1
  50. package/dist/components/trace-viewer/components/map.js +1 -1
  51. package/dist/components/trace-viewer/components/markers.js +1 -1
  52. package/dist/components/trace-viewer/components/node.js +1 -1
  53. package/dist/components/trace-viewer/components/search-input.js +1 -1
  54. package/dist/components/trace-viewer/components/search.js +1 -1
  55. package/dist/components/trace-viewer/components/span-content.js +1 -1
  56. package/dist/components/trace-viewer/components/span-detail-panel.js +1 -1
  57. package/dist/components/trace-viewer/components/span-segments.js +1 -1
  58. package/dist/components/trace-viewer/components/span-strategies.js +1 -1
  59. package/dist/components/trace-viewer/components/ui.js +1 -1
  60. package/dist/components/trace-viewer/components/zoom-button.js +1 -1
  61. package/dist/components/trace-viewer/components/zoom-icons.js +1 -1
  62. package/dist/components/trace-viewer/context.js +1 -1
  63. package/dist/components/trace-viewer/index.js +1 -1
  64. package/dist/components/trace-viewer/trace-viewer.js +1 -1
  65. package/dist/components/trace-viewer/types.js +1 -1
  66. package/dist/components/trace-viewer/util/constants.js +1 -1
  67. package/dist/components/trace-viewer/util/scrollbar-width.js +1 -1
  68. package/dist/components/trace-viewer/util/timing.js +1 -1
  69. package/dist/components/trace-viewer/util/tree.js +1 -1
  70. package/dist/components/trace-viewer/util/use-immediate-style.js +1 -1
  71. package/dist/components/trace-viewer/util/use-streaming-spans.js +1 -1
  72. package/dist/components/trace-viewer/util/use-trackpad-zoom.js +1 -1
  73. package/dist/components/trace-viewer/worker.js +1 -1
  74. package/dist/components/trace-viewer-new.js +1 -1
  75. package/dist/components/ui/alert.js +1 -1
  76. package/dist/components/ui/button.d.ts +10 -0
  77. package/dist/components/ui/button.d.ts.map +1 -0
  78. package/dist/components/ui/button.js +46 -0
  79. package/dist/components/ui/card.js +1 -1
  80. package/dist/components/ui/data-inspector.d.ts +1 -0
  81. package/dist/components/ui/data-inspector.d.ts.map +1 -1
  82. package/dist/components/ui/data-inspector.js +4 -9
  83. package/dist/components/ui/decrypt-button.js +1 -1
  84. package/dist/components/ui/error-card.js +1 -1
  85. package/dist/components/ui/error-stack-block.d.ts.map +1 -1
  86. package/dist/components/ui/error-stack-block.js +4 -18
  87. package/dist/components/ui/icon-button.d.ts +13 -0
  88. package/dist/components/ui/icon-button.d.ts.map +1 -0
  89. package/dist/components/ui/icon-button.js +29 -0
  90. package/dist/components/ui/inspector-theme.js +1 -1
  91. package/dist/components/ui/load-more-button.js +1 -1
  92. package/dist/components/ui/menu-dropdown.js +1 -1
  93. package/dist/components/ui/skeleton.js +1 -1
  94. package/dist/components/ui/spinner.js +1 -1
  95. package/dist/components/ui/timestamp-tooltip.js +1 -1
  96. package/dist/components/workflow-trace-view.js +1 -1
  97. package/dist/components/workflow-traces/event-colors.js +1 -1
  98. package/dist/components/workflow-traces/trace-colors.js +1 -1
  99. package/dist/components/workflow-traces/trace-span-construction.js +1 -1
  100. package/dist/components/workflow-traces/trace-time-utils.js +1 -1
  101. package/dist/hooks/use-dark-mode.js +1 -1
  102. package/dist/hooks/use-reduced-motion.js +1 -1
  103. package/dist/index.js +1 -1
  104. package/dist/lib/event-analysis.js +1 -1
  105. package/dist/lib/event-materialization.js +1 -1
  106. package/dist/lib/hydration.js +1 -1
  107. package/dist/lib/stream-display.js +1 -1
  108. package/dist/lib/toast.js +1 -1
  109. package/dist/lib/trace-builder.js +1 -1
  110. package/dist/lib/utils.js +1 -1
  111. package/dist/styles.css +5 -0
  112. package/package.json +5 -5
  113. package/src/components/event-list-view.tsx +29 -13
  114. package/src/components/index.ts +1 -0
  115. package/src/components/new-trace-viewer/components/copy-button.tsx +1 -1
  116. package/src/components/new-trace-viewer/components/event-list.tsx +17 -6
  117. package/src/components/new-trace-viewer/components/timeline.tsx +11 -2
  118. package/src/components/new-trace-viewer/detail-panel.tsx +3 -6
  119. package/src/components/new-trace-viewer/search.ts +178 -0
  120. package/src/components/new-trace-viewer/trace-viewer.tsx +123 -89
  121. package/src/components/sidebar/attribute-panel.tsx +212 -235
  122. package/src/components/sidebar/copyable-data-block.tsx +49 -27
  123. package/src/components/sidebar/detail-card.tsx +119 -41
  124. package/src/components/sidebar/entity-detail-panel.tsx +28 -28
  125. package/src/components/sidebar/events-list.tsx +51 -79
  126. package/src/components/ui/button.tsx +68 -0
  127. package/src/components/ui/data-inspector.tsx +9 -18
  128. package/src/components/ui/error-stack-block.tsx +7 -26
  129. package/src/components/ui/icon-button.tsx +57 -0
  130. package/src/styles.css +5 -0
  131. package/dist/components/error-boundary.js.map +0 -1
  132. package/dist/components/event-list-view.js.map +0 -1
  133. package/dist/components/hook-actions.js.map +0 -1
  134. package/dist/components/index.js.map +0 -1
  135. package/dist/components/new-trace-viewer/components/copy-button.js.map +0 -1
  136. package/dist/components/new-trace-viewer/components/event-list.js.map +0 -1
  137. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js.map +0 -1
  138. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js.map +0 -1
  139. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js.map +0 -1
  140. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js.map +0 -1
  141. package/dist/components/new-trace-viewer/components/split-pane.js.map +0 -1
  142. package/dist/components/new-trace-viewer/components/timeline.js.map +0 -1
  143. package/dist/components/new-trace-viewer/context.js.map +0 -1
  144. package/dist/components/new-trace-viewer/detail-panel.js.map +0 -1
  145. package/dist/components/new-trace-viewer/icons.js.map +0 -1
  146. package/dist/components/new-trace-viewer/trace-viewer.js.map +0 -1
  147. package/dist/components/new-trace-viewer/types.js.map +0 -1
  148. package/dist/components/new-trace-viewer/util/constants.js.map +0 -1
  149. package/dist/components/new-trace-viewer/utils.js.map +0 -1
  150. package/dist/components/run-trace-view.js.map +0 -1
  151. package/dist/components/sidebar/attribute-panel.js.map +0 -1
  152. package/dist/components/sidebar/conversation-view.js.map +0 -1
  153. package/dist/components/sidebar/copyable-data-block.js.map +0 -1
  154. package/dist/components/sidebar/detail-card.js.map +0 -1
  155. package/dist/components/sidebar/entity-detail-panel.js.map +0 -1
  156. package/dist/components/sidebar/events-list.js.map +0 -1
  157. package/dist/components/sidebar/resolve-hook-modal.js.map +0 -1
  158. package/dist/components/sidebar/sidebar-data-context.js.map +0 -1
  159. package/dist/components/stream-viewer.js.map +0 -1
  160. package/dist/components/trace-viewer/components/map.js.map +0 -1
  161. package/dist/components/trace-viewer/components/markers.js.map +0 -1
  162. package/dist/components/trace-viewer/components/node.js.map +0 -1
  163. package/dist/components/trace-viewer/components/search-input.js.map +0 -1
  164. package/dist/components/trace-viewer/components/search.js.map +0 -1
  165. package/dist/components/trace-viewer/components/span-content.js.map +0 -1
  166. package/dist/components/trace-viewer/components/span-detail-panel.js.map +0 -1
  167. package/dist/components/trace-viewer/components/span-segments.js.map +0 -1
  168. package/dist/components/trace-viewer/components/span-strategies.js.map +0 -1
  169. package/dist/components/trace-viewer/components/ui.js.map +0 -1
  170. package/dist/components/trace-viewer/components/zoom-button.js.map +0 -1
  171. package/dist/components/trace-viewer/components/zoom-icons.js.map +0 -1
  172. package/dist/components/trace-viewer/context.js.map +0 -1
  173. package/dist/components/trace-viewer/index.js.map +0 -1
  174. package/dist/components/trace-viewer/trace-viewer.js.map +0 -1
  175. package/dist/components/trace-viewer/types.js.map +0 -1
  176. package/dist/components/trace-viewer/util/constants.js.map +0 -1
  177. package/dist/components/trace-viewer/util/scrollbar-width.js.map +0 -1
  178. package/dist/components/trace-viewer/util/timing.js.map +0 -1
  179. package/dist/components/trace-viewer/util/tree.js.map +0 -1
  180. package/dist/components/trace-viewer/util/use-immediate-style.js.map +0 -1
  181. package/dist/components/trace-viewer/util/use-streaming-spans.js.map +0 -1
  182. package/dist/components/trace-viewer/util/use-trackpad-zoom.js.map +0 -1
  183. package/dist/components/trace-viewer/worker.js.map +0 -1
  184. package/dist/components/trace-viewer-new.js.map +0 -1
  185. package/dist/components/ui/alert.js.map +0 -1
  186. package/dist/components/ui/card.js.map +0 -1
  187. package/dist/components/ui/data-inspector.js.map +0 -1
  188. package/dist/components/ui/decrypt-button.js.map +0 -1
  189. package/dist/components/ui/error-card.js.map +0 -1
  190. package/dist/components/ui/error-stack-block.js.map +0 -1
  191. package/dist/components/ui/inspector-theme.js.map +0 -1
  192. package/dist/components/ui/load-more-button.js.map +0 -1
  193. package/dist/components/ui/menu-dropdown.js.map +0 -1
  194. package/dist/components/ui/skeleton.js.map +0 -1
  195. package/dist/components/ui/spinner.js.map +0 -1
  196. package/dist/components/ui/timestamp-tooltip.js.map +0 -1
  197. package/dist/components/workflow-trace-view.js.map +0 -1
  198. package/dist/components/workflow-traces/event-colors.js.map +0 -1
  199. package/dist/components/workflow-traces/trace-colors.js.map +0 -1
  200. package/dist/components/workflow-traces/trace-span-construction.js.map +0 -1
  201. package/dist/components/workflow-traces/trace-time-utils.js.map +0 -1
  202. package/dist/hooks/use-dark-mode.js.map +0 -1
  203. package/dist/hooks/use-reduced-motion.js.map +0 -1
  204. package/dist/index.js.map +0 -1
  205. package/dist/lib/event-analysis.js.map +0 -1
  206. package/dist/lib/event-materialization.js.map +0 -1
  207. package/dist/lib/hydration.js.map +0 -1
  208. package/dist/lib/stream-display.js.map +0 -1
  209. package/dist/lib/toast.js.map +0 -1
  210. package/dist/lib/trace-builder.js.map +0 -1
  211. package/dist/lib/utils.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"events-list.js","sourceRoot":"","sources":["../../../src/components/sidebar/events-list.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { EVENT_DATA_REF_FIELDS, type Event } from '@workflow/world';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { isExpiredMarker } from '../../lib/hydration';\nimport { ErrorCard } from '../ui/error-card';\nimport {\n ErrorStackBlock,\n isStructuredErrorWithStack,\n} from '../ui/error-stack-block';\nimport { Skeleton } from '../ui/skeleton';\nimport { localMillisecondTime } from './attribute-panel';\nimport { CopyableDataBlock } from './copyable-data-block';\nimport { DetailCard } from './detail-card';\n\n/**\n * Event types whose eventData contains an error field with a StructuredError.\n */\nconst ERROR_EVENT_TYPES = new Set(['step_failed', 'step_retrying']);\n\n/**\n * Event types that carry user-serialized data in their eventData field.\n */\nconst DATA_EVENT_TYPES = new Set([\n 'step_created',\n 'step_completed',\n 'step_failed',\n 'step_retrying',\n 'hook_created',\n 'hook_received',\n 'run_created',\n 'run_completed',\n 'run_failed',\n 'wait_created',\n 'wait_completed',\n]);\n\n/**\n * A single event row that can lazy-load its eventData when expanded.\n */\nfunction EventItem({\n event,\n onLoadEventData,\n encryptionKey,\n}: {\n event: Event;\n onLoadEventData?: (\n correlationId: string,\n eventId: string\n ) => Promise<unknown | null>;\n /** When this changes (e.g., Decrypt was clicked), invalidate cached data */\n encryptionKey?: Uint8Array;\n}) {\n const [loadedData, setLoadedData] = useState<unknown | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [loadError, setLoadError] = useState<string | null>(null);\n const wasExpandedRef = useRef(false);\n /** Mirrors whether we have a fetched payload; avoids stale `loadedData` in load closure. */\n const loadedDataRef = useRef<unknown | null>(null);\n\n // Check if the event already has eventData from the store\n const existingData =\n 'eventData' in event && event.eventData != null ? event.eventData : null;\n const mergedDisplay = loadedData ?? existingData;\n const canHaveData = DATA_EVENT_TYPES.has(event.eventType);\n\n const loadEventData = useCallback(\n async (options?: { force?: boolean }) => {\n if (!onLoadEventData || !event.correlationId || !event.eventId) return;\n if (!options?.force && loadedDataRef.current !== null) {\n return;\n }\n\n try {\n setIsLoading(true);\n setLoadError(null);\n const data = await onLoadEventData(event.correlationId, event.eventId);\n loadedDataRef.current = data;\n setLoadedData(data);\n } catch (err) {\n setLoadError(err instanceof Error ? err.message : String(err));\n } finally {\n setIsLoading(false);\n }\n },\n [onLoadEventData, event.correlationId, event.eventId]\n );\n\n const handleExpand = useCallback(async () => {\n if (isLoading) return;\n wasExpandedRef.current = true;\n await loadEventData();\n }, [isLoading, loadEventData]);\n\n // When the encryption key changes and this event was previously expanded,\n // re-load the data so it gets decrypted\n useEffect(() => {\n if (!encryptionKey || !wasExpandedRef.current) return;\n loadedDataRef.current = null;\n setLoadedData(null);\n void loadEventData({ force: true });\n }, [encryptionKey, loadEventData]);\n\n const createdAt = new Date(event.createdAt);\n\n const displayPayload = isLoading ? loadedData : mergedDisplay;\n\n return (\n <DetailCard\n summaryClassName=\"text-base py-2\"\n summary={\n <>\n <span\n className=\"font-medium\"\n style={{ color: 'var(--ds-gray-1000)' }}\n >\n {event.eventType}\n </span>{' '}\n -{' '}\n <span style={{ color: 'var(--ds-gray-700)' }}>\n {localMillisecondTime(createdAt.getTime())}\n </span>\n </>\n }\n onToggle={\n canHaveData\n ? (open) => {\n if (open) handleExpand();\n }\n : undefined\n }\n >\n {/* Event attributes */}\n <div\n className=\"flex flex-col divide-y rounded-md border overflow-hidden\"\n style={{\n borderColor: 'var(--ds-gray-300)',\n backgroundColor: 'var(--ds-gray-100)',\n }}\n >\n <div\n className=\"flex min-h-[32px] items-center justify-between gap-4 px-2.5 py-1.5\"\n style={{ borderColor: 'var(--ds-gray-300)' }}\n >\n <span\n className=\"text-[13px] font-medium\"\n style={{ color: 'var(--ds-gray-700)' }}\n >\n Event ID\n </span>\n <span\n className=\"max-w-[70%] truncate text-right text-[13px] font-mono\"\n style={{ color: 'var(--ds-gray-1000)' }}\n title={event.eventId}\n >\n {event.eventId}\n </span>\n </div>\n {event.correlationId && (\n <div\n className=\"flex min-h-[32px] items-center justify-between gap-4 px-2.5 py-1.5\"\n style={{ borderColor: 'var(--ds-gray-300)' }}\n >\n <span\n className=\"text-[13px] font-medium\"\n style={{ color: 'var(--ds-gray-700)' }}\n >\n Correlation ID\n </span>\n <span\n className=\"max-w-[70%] truncate text-right text-[13px] font-mono\"\n style={{ color: 'var(--ds-gray-1000)' }}\n title={event.correlationId}\n >\n {event.correlationId}\n </span>\n </div>\n )}\n </div>\n\n {/* Loading state */}\n {isLoading && (\n <div\n className=\"mt-2 rounded-md border p-3\"\n style={{\n borderColor: 'var(--ds-gray-300)',\n }}\n >\n <Skeleton className=\"h-4 w-[35%]\" />\n <Skeleton className=\"mt-2 h-4 w-[90%]\" />\n <Skeleton className=\"mt-2 h-4 w-[75%]\" />\n </div>\n )}\n\n {/* Error state */}\n {loadError && (\n <ErrorCard\n title=\"Failed to load event data\"\n details={loadError}\n className=\"mt-2\"\n />\n )}\n\n {/* Event data */}\n {displayPayload != null && (\n <div className=\"mt-2\">\n <EventDataBlock eventType={event.eventType} data={displayPayload} />\n </div>\n )}\n </DetailCard>\n );\n}\n\n/**\n * Check if an eventData object has only expired marker values in ref/payload\n * fields for this event type (see {@link EVENT_DATA_REF_FIELDS}). Other keys\n * (e.g. `resumeAt`, `stepName`) are ignored.\n */\nfunction hasOnlyExpiredFields(data: unknown, eventType: string): boolean {\n if (data === null || typeof data !== 'object' || Array.isArray(data)) {\n return false;\n }\n const record = data as Record<string, unknown>;\n const refKeys = EVENT_DATA_REF_FIELDS[eventType] ?? [];\n const presentKeys = refKeys.filter((k) => k in record);\n return (\n presentKeys.length > 0 &&\n presentKeys.every((k) => isExpiredMarker(record[k]))\n );\n}\n\n/**\n * Renders event data, using ErrorStackBlock for error events that contain\n * a structured error with a stack trace, and CopyableDataBlock otherwise.\n */\nfunction EventDataBlock({\n eventType,\n data,\n}: {\n eventType: string;\n data: unknown;\n}) {\n // Expired data — show a simple message instead of the raw stub.\n // Check both the top-level eventData and nested sub-fields (result, input, etc.)\n // since the server stubs each ref field independently.\n if (isExpiredMarker(data) || hasOnlyExpiredFields(data, eventType)) {\n return (\n <div\n className=\"flex items-center gap-1.5 rounded-md border px-3 py-2 text-xs\"\n style={{\n borderColor: 'var(--ds-gray-300)',\n backgroundColor: 'var(--ds-gray-100)',\n color: 'var(--ds-gray-700)',\n }}\n >\n <span className=\"font-medium\">Data expired</span>\n </div>\n );\n }\n\n // For error events (step_failed, step_retrying), the eventData has the shape\n // { error: StructuredError, stack?: string, ... }. Check both the top-level\n // value and the nested `error` field for a stack trace.\n if (\n ERROR_EVENT_TYPES.has(eventType) &&\n data != null &&\n typeof data === 'object'\n ) {\n const record = data as Record<string, unknown>;\n\n // Check the nested `error` field first (the StructuredError)\n if (isStructuredErrorWithStack(record.error)) {\n return <ErrorStackBlock value={record.error} />;\n }\n\n // Some error formats put the stack at the top level of eventData\n if (isStructuredErrorWithStack(record)) {\n return <ErrorStackBlock value={record} />;\n }\n }\n\n // For non-error events or errors without a stack, fall back to the\n // generic JSON viewer.\n return <CopyableDataBlock data={data} />;\n}\n\nexport function EventsList({\n events,\n isLoading = false,\n error,\n onLoadEventData,\n encryptionKey,\n}: {\n events: Event[];\n isLoading?: boolean;\n error?: Error | null;\n onLoadEventData?: (\n correlationId: string,\n eventId: string\n ) => Promise<unknown | null>;\n /** When provided, signals that decryption is active (triggers re-load of expanded events) */\n encryptionKey?: Uint8Array;\n}) {\n // Sort by createdAt\n const sortedEvents = useMemo(\n () =>\n [...events].sort(\n (a, b) =>\n new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()\n ),\n [events]\n );\n\n return (\n <div className=\"mt-2\" style={{ color: 'var(--ds-gray-1000)' }}>\n <h3\n className=\"text-label-14 font-medium mt-4 mb-2\"\n style={{ color: 'var(--ds-gray-1000)' }}\n >\n Events\n </h3>\n {isLoading ? (\n <div className=\"flex flex-col gap-4\">\n <Skeleton className=\"h-9 w-full rounded-md\" />\n <Skeleton className=\"h-9 w-full rounded-md\" />\n <Skeleton className=\"h-9 w-full rounded-md\" />\n </div>\n ) : null}\n {!isLoading && !error && sortedEvents.length === 0 && (\n <div className=\"text-sm\">No events found</div>\n )}\n {sortedEvents.length > 0 && !error ? (\n <div className=\"flex flex-col gap-4\">\n {sortedEvents.map((event) => (\n <EventItem\n key={event.eventId}\n event={event}\n onLoadEventData={onLoadEventData}\n encryptionKey={encryptionKey}\n />\n ))}\n </div>\n ) : null}\n </div>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolve-hook-modal.js","sourceRoot":"","sources":["../../../src/components/sidebar/resolve-hook-modal.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { Send, X } from 'lucide-react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\ninterface ResolveHookModalProps {\n /** Whether the modal is open */\n isOpen: boolean;\n /** Callback when the modal should be closed */\n onClose: () => void;\n /** Callback when the form is submitted with the parsed JSON payload */\n onSubmit: (payload: unknown) => Promise<void>;\n /** Whether the submission is in progress */\n isSubmitting?: boolean;\n}\n\n/**\n * Modal component for resolving a hook by entering a JSON payload.\n *\n * Styled to match the Geist design-system dialog component used in the\n * Vercel dashboard so it looks native when rendered inside `front`.\n */\nexport function ResolveHookModal({\n isOpen,\n onClose,\n onSubmit,\n isSubmitting = false,\n}: ResolveHookModalProps): React.JSX.Element | null {\n const [jsonInput, setJsonInput] = useState('');\n const [parseError, setParseError] = useState<string | null>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n // Focus the textarea when the modal opens\n useEffect(() => {\n if (isOpen && textareaRef.current) {\n textareaRef.current.focus();\n }\n }, [isOpen]);\n\n // Reset state when modal closes\n useEffect(() => {\n if (!isOpen) {\n setJsonInput('');\n setParseError(null);\n }\n }, [isOpen]);\n\n // Handle escape key to close\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && isOpen && !isSubmitting) {\n onClose();\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isOpen, isSubmitting, onClose]);\n\n const submitPayload = useCallback(async () => {\n setParseError(null);\n\n // Parse the JSON input\n let payload: unknown;\n try {\n // Allow empty string as null payload\n if (jsonInput.trim() === '') {\n payload = null;\n } else {\n payload = JSON.parse(jsonInput);\n }\n } catch {\n setParseError('Invalid JSON. Please check your input.');\n return;\n }\n\n await onSubmit(payload);\n }, [jsonInput, onSubmit]);\n\n const handleSubmit = useCallback(\n (e: React.FormEvent) => {\n e.preventDefault();\n void submitPayload();\n },\n [submitPayload]\n );\n\n const isMacPlatform =\n typeof navigator !== 'undefined' &&\n (\n (navigator as Navigator & { userAgentData?: { platform?: string } })\n .userAgentData?.platform ?? navigator.userAgent\n )\n .toLowerCase()\n .includes('mac');\n\n // Handle Cmd/Ctrl + Enter to submit\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter' && !isSubmitting) {\n e.preventDefault();\n handleSubmit(e as unknown as React.FormEvent);\n }\n },\n [handleSubmit, isSubmitting]\n );\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 50,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"resolve-hook-modal-title\"\n >\n {/* Backdrop — matches Geist dialog ::backdrop */}\n <div\n style={{\n position: 'absolute',\n inset: 0,\n background: 'rgba(0, 0, 0, 0.7)',\n }}\n onClick={isSubmitting ? undefined : onClose}\n />\n\n {/* Modal card — matches Geist dialog.geist-dialog */}\n <div\n style={{\n position: 'relative',\n zIndex: 10,\n width: 480,\n maxWidth: 'calc(100% - 32px)',\n borderRadius: 12,\n border: 'none',\n boxShadow: 'var(--ds-shadow-menu)',\n background: 'var(--ds-background-100)',\n color: 'var(--ds-gray-1000)',\n overflow: 'hidden',\n }}\n >\n {/* Header */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 24px',\n }}\n >\n <h2\n id=\"resolve-hook-modal-title\"\n style={{\n margin: 0,\n fontSize: 16,\n fontWeight: 600,\n color: 'var(--ds-gray-1000)',\n }}\n >\n Resolve Hook\n </h2>\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isSubmitting}\n aria-label=\"Close modal\"\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 4,\n borderRadius: 6,\n border: 'none',\n background: 'transparent',\n color: 'var(--ds-gray-900)',\n cursor: isSubmitting ? 'not-allowed' : 'pointer',\n opacity: isSubmitting ? 0.5 : 1,\n transition: 'background 0.15s',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = 'var(--ds-gray-alpha-200)';\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = 'transparent';\n }}\n >\n <X style={{ width: 16, height: 16 }} />\n </button>\n </div>\n\n {/* Body */}\n <form onSubmit={handleSubmit}>\n <div style={{ padding: '0 24px 16px' }}>\n <label\n htmlFor=\"json-payload\"\n style={{\n display: 'block',\n fontSize: 14,\n fontWeight: 500,\n marginBottom: 6,\n color: 'var(--ds-gray-1000)',\n }}\n >\n JSON Payload\n </label>\n <p\n style={{\n fontSize: 13,\n marginBottom: 12,\n marginTop: 0,\n color: 'var(--ds-gray-900)',\n lineHeight: 1.5,\n }}\n >\n Enter a JSON value to send to the hook. Leave empty to send{' '}\n <code\n style={{\n padding: '2px 6px',\n borderRadius: 4,\n fontSize: 12,\n fontFamily:\n 'var(--font-mono, ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, monospace)',\n background: 'var(--ds-gray-alpha-200)',\n color: 'var(--ds-gray-1000)',\n }}\n >\n null\n </code>\n .\n </p>\n <textarea\n ref={textareaRef}\n id=\"json-payload\"\n value={jsonInput}\n onChange={(e) => {\n setJsonInput(e.target.value);\n setParseError(null);\n }}\n onKeyDown={handleKeyDown}\n disabled={isSubmitting}\n placeholder='{\"key\": \"value\"}'\n style={{\n width: '100%',\n height: 160,\n padding: '8px 12px',\n fontFamily:\n 'var(--font-mono, ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, monospace)',\n fontSize: 13,\n lineHeight: 1.5,\n borderRadius: 8,\n border: `1px solid ${parseError ? 'var(--ds-red-700)' : 'var(--ds-gray-alpha-400)'}`,\n color: 'var(--ds-gray-1000)',\n background: 'var(--ds-background-100)',\n outline: 'none',\n resize: 'none',\n opacity: isSubmitting ? 0.5 : 1,\n cursor: isSubmitting ? 'not-allowed' : 'text',\n boxSizing: 'border-box',\n }}\n />\n {parseError && (\n <p\n style={{\n marginTop: 8,\n fontSize: 13,\n color: 'var(--ds-red-900)',\n margin: '8px 0 0',\n }}\n >\n {parseError}\n </p>\n )}\n <p\n style={{\n marginTop: 8,\n fontSize: 12,\n color: 'var(--ds-gray-800)',\n margin: '8px 0 0',\n }}\n >\n Press{' '}\n <kbd\n style={{\n padding: '2px 5px',\n borderRadius: 4,\n fontSize: 11,\n fontFamily:\n 'var(--font-mono, ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, monospace)',\n background: 'var(--ds-gray-alpha-200)',\n border: '1px solid var(--ds-gray-alpha-400)',\n }}\n >\n {isMacPlatform ? '⌘' : 'Ctrl'}\n +Enter\n </kbd>{' '}\n to submit\n </p>\n </div>\n\n {/* Footer */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: 8,\n padding: '12px 24px',\n borderTop: '1px solid var(--ds-gray-alpha-400)',\n }}\n >\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isSubmitting}\n style={{\n padding: '8px 16px',\n fontSize: 14,\n fontWeight: 500,\n borderRadius: 8,\n border: '1px solid var(--ds-gray-alpha-400)',\n background: 'var(--ds-background-100)',\n color: 'var(--ds-gray-1000)',\n cursor: isSubmitting ? 'not-allowed' : 'pointer',\n opacity: isSubmitting ? 0.5 : 1,\n transition: 'background 0.15s',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = 'var(--ds-gray-alpha-100)';\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = 'var(--ds-background-100)';\n }}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() => void submitPayload()}\n disabled={isSubmitting}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '8px 16px',\n fontSize: 14,\n fontWeight: 500,\n borderRadius: 8,\n border: 'none',\n background: 'var(--ds-gray-1000)',\n color: 'var(--ds-background-100)',\n cursor: isSubmitting ? 'not-allowed' : 'pointer',\n opacity: isSubmitting ? 0.5 : 1,\n transition: 'opacity 0.15s',\n }}\n onMouseEnter={(e) => {\n if (!isSubmitting) e.currentTarget.style.opacity = '0.9';\n }}\n onMouseLeave={(e) => {\n if (!isSubmitting) e.currentTarget.style.opacity = '1';\n }}\n >\n <Send style={{ width: 14, height: 14 }} />\n {isSubmitting ? 'Sending...' : 'Send Payload'}\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sidebar-data-context.js","sourceRoot":"","sources":["../../../src/components/sidebar/sidebar-data-context.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,aAAa,EAAE,UAAU,EAAkB,MAAM,OAAO,CAAC;AAgClE,MAAM,kBAAkB,GAAG,aAAa,CAAiC,IAAI,CAAC,CAAC;AAC/E,kBAAkB,CAAC,WAAW,GAAG,oBAAoB,CAAC;AAEtD,MAAM,UAAU,mBAAmB,CAAC,EAClC,KAAK,EACL,QAAQ,GAIT;IACC,OAAO,CACL,KAAC,kBAAkB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACtC,QAAQ,GACmB,CAC/B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,MAAM,GAAG,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC3C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,UAAU,CAAC,kBAAkB,CAAC,CAAC;AACxC,CAAC","sourcesContent":["'use client';\n\nimport { createContext, useContext, type ReactNode } from 'react';\nimport type { Event, Hook, Step, WorkflowRun } from '@workflow/world';\nimport type { SpanSelectionInfo } from './entity-detail-panel';\n\nexport interface SidebarDataContextValue {\n run: WorkflowRun;\n events: Event[];\n spanDetailData: WorkflowRun | Step | Hook | Event | null;\n spanDetailError?: Error | null;\n spanDetailLoading?: boolean;\n onSpanSelect: (info: SpanSelectionInfo) => void;\n onStreamClick?: (streamId: string) => void;\n onRunClick?: (runId: string) => void;\n onWakeUpSleep?: (\n runId: string,\n correlationId: string\n ) => Promise<{ stoppedCount: number }>;\n onLoadEventData?: (\n correlationId: string,\n eventId: string\n ) => Promise<unknown | null>;\n onResolveHook?: (\n hookToken: string,\n payload: unknown,\n hook?: Hook\n ) => Promise<void>;\n encryptionKey?: Uint8Array;\n onDecrypt?: () => void;\n isDecrypting?: boolean;\n hasEncryptedData?: boolean;\n}\n\nconst SidebarDataContext = createContext<SidebarDataContextValue | null>(null);\nSidebarDataContext.displayName = 'SidebarDataContext';\n\nexport function SidebarDataProvider({\n value,\n children,\n}: {\n value: SidebarDataContextValue;\n children: ReactNode;\n}) {\n return (\n <SidebarDataContext.Provider value={value}>\n {children}\n </SidebarDataContext.Provider>\n );\n}\n\nexport function useSidebarData(): SidebarDataContextValue {\n const ctx = useContext(SidebarDataContext);\n if (!ctx) {\n throw new Error('useSidebarData must be used within a SidebarDataProvider');\n }\n return ctx;\n}\n\nexport function useSidebarDataOptional(): SidebarDataContextValue | null {\n return useContext(SidebarDataContext);\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"stream-viewer.js","sourceRoot":"","sources":["../../src/components/stream-viewer.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport React, { useEffect, useRef } from 'react';\nimport { Virtuoso, type VirtuosoHandle } from 'react-virtuoso';\nimport { DataInspector } from './ui/data-inspector';\nimport { Skeleton } from './ui/skeleton';\n\n// ──────────────────────────────────────────────────────────────────────────\n// Types\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface StreamChunk {\n id: number;\n value: unknown;\n}\n\ntype Chunk = StreamChunk;\n\ninterface StreamViewerProps {\n streamId: string;\n chunks: Chunk[];\n isLive: boolean;\n error?: string | null;\n /** True while the initial stream connection is being established */\n isLoading?: boolean;\n /** Called when the user scrolls near the bottom, for triggering pagination */\n onScrollEnd?: () => void;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Chunk row — memoized to prevent remounts during polling\n// ──────────────────────────────────────────────────────────────────────────\n\nconst ChunkRow = React.memo(function ChunkRow({\n chunk,\n index,\n}: {\n chunk: Chunk;\n index: number;\n}) {\n return (\n <div\n className=\"text-[11px] rounded-md border p-3\"\n style={{\n borderColor: 'var(--ds-gray-300)',\n backgroundColor: 'var(--ds-gray-100)',\n }}\n >\n <div className=\"flex items-start gap-2\">\n <span\n className=\"select-none pt-px\"\n style={{ color: 'var(--ds-gray-500)' }}\n >\n [{index}]\n </span>\n <div className=\"min-w-0 flex-1\">\n {typeof chunk.value === 'string' ? (\n <span\n className=\"whitespace-pre-wrap break-words\"\n style={{ color: 'var(--ds-gray-1000)' }}\n >\n {chunk.value}\n </span>\n ) : (\n <DataInspector data={chunk.value} expandLevel={1} />\n )}\n </div>\n </div>\n </div>\n );\n});\n\n// ──────────────────────────────────────────────────────────────────────────\n// Skeleton loading\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction StreamSkeleton() {\n return (\n <div className=\"flex flex-col gap-3 animate-in fade-in\">\n <Skeleton style={{ width: 120, height: 16, borderRadius: 4 }} />\n {[1, 2, 3, 4].map((i) => (\n <Skeleton key={i} style={{ height: 56, borderRadius: 6 }} />\n ))}\n </div>\n );\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Main component\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * StreamViewer component that displays real-time stream data.\n * Each chunk is rendered with DataInspector for proper display\n * of complex types (Map, Set, Date, custom classes, etc.).\n */\nexport function StreamViewer({\n streamId: _streamId,\n chunks,\n isLive,\n error,\n isLoading,\n onScrollEnd,\n}: StreamViewerProps) {\n const virtuosoRef = useRef<VirtuosoHandle>(null);\n const prevChunkCountRef = useRef(0);\n\n // Auto-scroll to bottom when new chunks arrive (live streaming)\n useEffect(() => {\n if (chunks.length > prevChunkCountRef.current && chunks.length > 0) {\n virtuosoRef.current?.scrollToIndex({\n index: chunks.length - 1,\n align: 'end',\n });\n }\n prevChunkCountRef.current = chunks.length;\n }, [chunks.length]);\n\n // Show skeleton when loading and no chunks have arrived yet\n if (isLoading && chunks.length === 0) {\n return (\n <div className=\"flex flex-col h-full\">\n <StreamSkeleton />\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Live indicator */}\n {isLive && (\n <div className=\"flex items-center gap-1.5 mb-2 px-1\">\n <span\n className=\"inline-block w-2 h-2 rounded-full\"\n style={{ backgroundColor: 'var(--ds-green-600)' }}\n />\n <span className=\"text-xs\" style={{ color: 'var(--ds-green-700)' }}>\n Live\n </span>\n </div>\n )}\n\n {/* Header */}\n {chunks.length > 0 && (\n <div className=\"flex items-center gap-2 mb-2 px-1\">\n <span\n className=\"text-[13px] font-medium\"\n style={{ color: 'var(--ds-gray-900)' }}\n >\n Stream Chunks\n </span>\n <span\n className=\"text-xs tabular-nums\"\n style={{ color: 'var(--ds-gray-600)' }}\n >\n ({chunks.length})\n </span>\n </div>\n )}\n\n {/* Content */}\n <div className=\"flex-1 min-h-0\">\n {error ? (\n <div\n className=\"text-[11px] rounded-md border p-3\"\n style={{\n borderColor: 'var(--ds-red-300)',\n backgroundColor: 'var(--ds-red-100)',\n color: 'var(--ds-red-700)',\n }}\n >\n <div>Error reading stream:</div>\n <div>{error}</div>\n </div>\n ) : chunks.length === 0 ? (\n <div\n className=\"text-[11px] rounded-md border p-3\"\n style={{\n borderColor: 'var(--ds-gray-300)',\n backgroundColor: 'var(--ds-gray-100)',\n color: 'var(--ds-gray-600)',\n }}\n >\n {isLive ? 'Waiting for stream data...' : 'Stream is empty'}\n </div>\n ) : (\n <Virtuoso\n ref={virtuosoRef}\n totalCount={chunks.length}\n overscan={10}\n endReached={() => onScrollEnd?.()}\n itemContent={(index) => (\n <div style={{ paddingBottom: 8 }}>\n <ChunkRow chunk={chunks[index]} index={index} />\n </div>\n )}\n style={{ flex: 1, minHeight: 0 }}\n />\n )}\n </div>\n </div>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"map.js","sourceRoot":"","sources":["../../../../src/components/trace-viewer/components/map.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n type MutableRefObject,\n memo,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { useTraceViewer } from '../context';\nimport styles from '../trace-viewer.module.css';\nimport type { VisibleSpan } from '../types';\nimport { MAP_HEIGHT, TIMELINE_PADDING } from '../util/constants';\nimport { useImmediateStyle } from '../util/use-immediate-style';\n\nconst getDpi = (): number => {\n if ('devicePixelRatio' in globalThis) {\n return globalThis.devicePixelRatio || 1;\n }\n return 1;\n};\n\nconst useDpi = (): number => {\n const [dpi, setDpi] = useState(1);\n useLayoutEffect(() => {\n const onChange = (): void => setDpi(getDpi());\n const media = matchMedia(`(resolution: ${dpi}dppx)`);\n media.addEventListener('change', onChange);\n onChange();\n\n return () => {\n media.removeEventListener('change', onChange);\n };\n }, [dpi]);\n return dpi;\n};\n\nconst padding = TIMELINE_PADDING;\n\nexport const MiniMap = memo(function MiniMap({\n timelineRef,\n rows,\n scale,\n}: {\n timelineRef: MutableRefObject<HTMLDivElement | null>;\n rows: VisibleSpan[][];\n scale: number;\n}) {\n const {\n state: { root, baseScale, timelineWidth, width: fullWidth, scrollbarWidth },\n } = useTraceViewer();\n const mapWidth = fullWidth + TIMELINE_PADDING * 2;\n const dpi = useDpi();\n const containerRef = useRef<HTMLDivElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const thumbRatio =\n (fullWidth / (fullWidth - scrollbarWidth)) *\n Math.min(fullWidth / timelineWidth, baseScale / scale);\n const thumbWidth = Math.min(\n fullWidth,\n (timelineWidth - scrollbarWidth) * thumbRatio\n );\n useEffect(() => {\n let isHeld = false;\n let clientX = 0;\n let rect: DOMRect | undefined;\n\n const isValidEventTarget = (target: EventTarget | null): boolean => {\n return Boolean(containerRef.current?.contains(target as HTMLElement));\n };\n\n let nextFrame = 0;\n const onFrame = (): void => {\n if (!isHeld || !rect) return;\n const $timeline = timelineRef.current;\n if (!$timeline) return;\n\n const x = clientX - thumbWidth * 0.5 - rect.left;\n $timeline.scrollLeft = x / thumbRatio;\n };\n\n const onPointerMove = (event: PointerEvent): void => {\n ({ clientX } = event);\n cancelAnimationFrame(nextFrame);\n nextFrame = requestAnimationFrame(onFrame);\n };\n\n const onPointerDown = (event: PointerEvent): void => {\n if (!isValidEventTarget(event.target)) return;\n isHeld = true;\n rect = containerRef.current?.getBoundingClientRect();\n onPointerMove(event);\n };\n\n const onPointerUp = (): void => {\n isHeld = false;\n rect = undefined;\n };\n\n const onTouchStart = (event: TouchEvent): void => {\n if (!isValidEventTarget(event.target)) return;\n if (event.cancelable) {\n event.preventDefault();\n }\n };\n const onTouchMove = (event: TouchEvent): void => {\n if (!isHeld) return;\n if (event.cancelable) {\n event.preventDefault();\n }\n };\n\n window.addEventListener('pointerdown', onPointerDown);\n window.addEventListener('pointermove', onPointerMove);\n window.addEventListener('pointerup', onPointerUp);\n window.addEventListener('blur', onPointerUp);\n window.addEventListener('touchstart', onTouchStart, { passive: false });\n window.addEventListener('touchmove', onTouchMove, { passive: false });\n\n return () => {\n window.removeEventListener('pointerdown', onPointerDown);\n window.removeEventListener('pointermove', onPointerMove);\n window.removeEventListener('pointerup', onPointerUp);\n window.removeEventListener('blur', onPointerUp);\n window.removeEventListener('touchstart', onTouchStart);\n window.removeEventListener('touchmove', onTouchMove);\n cancelAnimationFrame(nextFrame);\n };\n }, [timelineRef, thumbRatio, thumbWidth]);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n const ctx = canvas?.getContext('2d');\n if (!canvas || !ctx) return;\n\n const render = (): void => {\n ctx.resetTransform();\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.scale(dpi, dpi);\n\n const gap = 1;\n const height = 3;\n const ratio = (mapWidth - padding * 2) / root.duration;\n\n // TODO: fill spans based on depth\n ctx.fillStyle = '#ccc';\n ctx.beginPath();\n for (const row of rows) {\n for (const span of row) {\n const y = padding - gap + (gap + height) * span.row;\n if (y >= MAP_HEIGHT - height - padding) break;\n\n const x = padding + (span.startTime - root.startTime) * ratio;\n const width = span.duration * ratio;\n\n ctx.roundRect(x, y, width, height, height);\n }\n }\n ctx.fill();\n };\n\n const nextFrame = requestAnimationFrame(render);\n\n return () => cancelAnimationFrame(nextFrame);\n }, [dpi, root, mapWidth, rows]);\n\n const thumbRef = useRef<HTMLDivElement>(null);\n const { style: thumbStyle, setStyle: setThumbStyle } =\n useImmediateStyle(thumbRef);\n useLayoutEffect(() => {\n const $timeline = timelineRef.current;\n if (!$timeline) return;\n\n let nextFrame = 0;\n const onFrame = (): void => {\n setThumbStyle(\n 'transform',\n `translateX(${padding + $timeline.scrollLeft * thumbRatio}px)`\n );\n };\n onFrame();\n\n const onScroll = (): void => {\n cancelAnimationFrame(nextFrame);\n nextFrame = requestAnimationFrame(onFrame);\n };\n $timeline.addEventListener('scroll', onScroll);\n\n return () => {\n cancelAnimationFrame(nextFrame);\n $timeline.removeEventListener('scroll', onScroll);\n };\n }, [timelineRef, thumbRatio, setThumbStyle]);\n\n return (\n <div\n className={styles.mapContainer}\n ref={containerRef}\n style={{\n width: thumbWidth > 0 ? mapWidth : '100%',\n height: MAP_HEIGHT,\n }}\n >\n <canvas\n className={styles.mapCanvas}\n height={MAP_HEIGHT * dpi}\n ref={canvasRef}\n style={{ width: mapWidth, height: MAP_HEIGHT }}\n width={mapWidth * dpi}\n />\n <div\n className={styles.mapThumb}\n ref={thumbRef}\n style={{\n transform: thumbStyle.transform,\n width:\n thumbWidth > 0\n ? thumbWidth\n : `calc(100% - ${TIMELINE_PADDING * 2}px)`,\n top: 2,\n height: MAP_HEIGHT - 4,\n }}\n />\n </div>\n );\n});\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"markers.js","sourceRoot":"","sources":["../../../../src/components/trace-viewer/components/markers.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { clsx } from 'clsx';\nimport type {\n CSSProperties,\n Dispatch,\n MutableRefObject,\n ReactNode,\n} from 'react';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { type TraceViewerAction, useTraceViewer } from '../context';\nimport styles from '../trace-viewer.module.css';\nimport type {\n MemoCache,\n RootNode,\n ScrollSnapshot,\n VisibleSpan,\n VisibleSpanEvent,\n} from '../types';\nimport {\n MARKER_HEIGHT,\n ROW_HEIGHT,\n ROW_PADDING,\n TIMELINE_PADDING,\n} from '../util/constants';\nimport {\n formatDurationForTimeline,\n formatTimeSelection,\n formatWallClockTime,\n} from '../util/timing';\nimport { useImmediateStyle } from '../util/use-immediate-style';\nimport { useTrackpadZoom } from '../util/use-trackpad-zoom';\n\n/**\n * Snap a raw duration to the nearest \"nice\" number in the 1-2-5 × 10^n\n * sequence (e.g. …, 0.5, 1, 2, 5, 10, 20, 50, 100, …).\n */\nfunction snapToNice(raw: number): number {\n if (raw <= 0) return 1;\n const log10 = Math.floor(Math.log10(raw));\n const pow = 10 ** log10;\n const normalized = raw / pow;\n\n if (normalized <= 1.5) return pow;\n if (normalized <= 3.5) return 2 * pow;\n if (normalized <= 7.5) return 5 * pow;\n return 10 * pow;\n}\n\nexport function Markers({\n scale,\n isLive = false,\n}: {\n scale: number;\n isLive?: boolean;\n}): ReactNode {\n const {\n state: { root },\n } = useTraceViewer();\n // Force a re-render every second when live to pick up new tick marks.\n // The markers container width is grown at 60fps by useLiveTick;\n // this interval only ensures the marker *labels* stay current.\n const [, forceMarkerUpdate] = useState(0);\n useEffect(() => {\n if (!isLive) return;\n const id = setInterval(() => forceMarkerUpdate((v) => v + 1), 1000);\n return () => clearInterval(id);\n }, [isLive]);\n\n const fullDuration = root.duration;\n\n // Calculate a marker interval that gives reasonable spacing at any zoom level.\n // We target ~50px per notch mark; labels appear on every Nth notch via labelSpacing.\n // When scale is <= 0 (e.g. the initial -1 sentinel), fall back to a safe default\n // to avoid generating an absurd number of markers.\n const effectiveScale =\n scale > 0 ? scale : fullDuration > 0 ? 1 / fullDuration : 1;\n const targetNotchPx = 50;\n let markerDuration = snapToNice(targetNotchPx / effectiveScale);\n markerDuration = Math.max(1, markerDuration);\n let markerWidth = markerDuration * effectiveScale;\n\n // Cap marker count to avoid creating too many DOM elements at extreme zoom\n // on very long traces. Only the visible portion is shown on screen anyway.\n const MAX_MARKERS = 1000;\n if (fullDuration / markerDuration > MAX_MARKERS) {\n markerDuration = snapToNice(fullDuration / MAX_MARKERS);\n markerWidth = markerDuration * effectiveScale;\n }\n const markerCount = Math.ceil(fullDuration / markerDuration);\n\n // How often labels should appear for markers, e.g. 3 === one label for every third marker\n const labelSpacing = Math.ceil(100 / markerWidth) || 1;\n\n return (\n <div className={styles.markersContainer}>\n <div\n aria-hidden\n className={styles.markers}\n style={\n {\n width: Math.floor(root.duration * scale + 15),\n visibility: scale !== -1 ? 'visible' : 'hidden',\n '--marker-width': `${markerWidth}px`,\n } as CSSProperties\n }\n >\n {new Array(markerCount).fill(null).map((_, i) => {\n const hasLabel = i % labelSpacing === 0;\n return (\n <span\n className={clsx(styles.marker, !hasLabel && styles.notch)}\n key={String(i)}\n >\n {hasLabel ? (\n <span className={styles.markerLabel}>\n {formatDurationForTimeline(markerDuration * i)}\n <span className={styles.markerClockTime}>\n {formatWallClockTime(root.startTime + markerDuration * i)}\n </span>\n </span>\n ) : null}\n </span>\n );\n })}\n </div>\n </div>\n );\n}\n\nexport function EventMarkers({\n events,\n root,\n scale,\n}: {\n events: VisibleSpanEvent[];\n root: RootNode;\n scale: number;\n}): ReactNode {\n // Filter out events that should not show vertical lines (workflow-specific feature)\n const eventsWithVerticalLines = useMemo(\n () => events.filter((x) => x.event.showVerticalLine !== false),\n [events]\n );\n\n return (\n <div className={styles.eventMarkersContainer}>\n <div\n aria-hidden\n className={styles.eventMarkers}\n style={\n {\n width: Math.floor(root.duration * scale),\n } as CSSProperties\n }\n >\n {eventsWithVerticalLines.map((x) => {\n return (\n <span\n className={clsx(styles.eventMarker)}\n key={x.key}\n style={{\n left: Math.floor((x.timestamp - root.startTime) * scale),\n ...(x.event.color && { borderLeftColor: x.event.color }),\n }}\n />\n );\n })}\n </div>\n </div>\n );\n}\n\nconst HOVER_OVERSCAN = 2;\n\ninterface TrackpadZoom {\n anchorX: number;\n anchorT: number;\n}\n\nexport function CursorMarker({\n memoCacheRef,\n timelineRef,\n root,\n spans,\n events,\n scale,\n dispatch,\n scrollSnapshotRef,\n}: {\n memoCacheRef: MutableRefObject<MemoCache>;\n timelineRef: MutableRefObject<HTMLDivElement | null>;\n root: RootNode;\n spans: VisibleSpan[];\n events: VisibleSpanEvent[];\n scale: number;\n dispatch: Dispatch<TraceViewerAction>;\n scrollSnapshotRef: MutableRefObject<ScrollSnapshot | undefined>;\n}): ReactNode {\n const hasEnteredRef = useRef(false);\n const spansRef = useRef(spans);\n spansRef.current = spans;\n const eventsRef = useRef(events);\n eventsRef.current = events;\n const labelRef = useRef<HTMLDivElement>(null);\n const { style: labelStyle, setStyle: setLabelStyle } =\n useImmediateStyle(labelRef);\n const labelTextRef = useRef<HTMLDivElement>(null);\n\n const ref = useRef<HTMLDivElement>(null);\n const { style, setStyle } = useImmediateStyle(ref);\n const rectRef = useRef<DOMRect>(undefined);\n\n const selectionRef = useRef<HTMLDivElement>(null);\n const { style: selectionStyle, setStyle: setSelectionStyle } =\n useImmediateStyle(selectionRef);\n\n const xRef = useRef(0);\n useEffect(() => {\n const $timeline = timelineRef.current;\n if (!$timeline) return;\n\n let x = xRef.current;\n let xStart = 0;\n let isDragging = false;\n let isExternalDrag = false;\n let hasMoved = false;\n let isRightClick = false;\n let scrollX = 0;\n let scrollY = 0;\n const hoverStartT = Date.now() + 500;\n const updateRect = (): void => {\n if (rectRef.current) return;\n rectRef.current = $timeline.getBoundingClientRect();\n };\n\n const getRowFromY = (y: number): number => {\n if (!rectRef.current) return 0;\n return (\n (y - MARKER_HEIGHT - TIMELINE_PADDING) / (ROW_HEIGHT + ROW_PADDING)\n );\n };\n\n const removeHover = (): void => {\n const cache = memoCacheRef.current;\n // Remove hover styling from any elements that have it\n for (const span of spansRef.current) {\n if (!span.isHovered) continue;\n span.isHovered = false;\n cache.set(span.span.spanId, {});\n }\n dispatch({\n type: 'forceRender',\n });\n };\n\n let nextFrame = 0;\n const onFrame = (): void => {\n if (!hasEnteredRef.current) return;\n if (!rectRef.current) updateRect();\n const rect = rectRef.current;\n if (!rect) return;\n\n const { scrollLeft, scrollTop } = $timeline;\n\n const left = Math.max(\n 0,\n Math.min(\n x + scrollLeft - rect.left - TIMELINE_PADDING,\n root.duration * scale\n )\n );\n const leftStyle = `${left - scrollLeft + TIMELINE_PADDING}px`;\n setStyle('left', leftStyle);\n setLabelStyle('left', leftStyle);\n\n const t = root.startTime + left / scale;\n const labelT = t - root.startTime;\n if (labelT < 0 || labelT > root.duration) {\n labelTextRef.current?.removeAttribute('data-text');\n } else {\n labelTextRef.current?.setAttribute(\n 'data-text',\n formatTimeSelection(labelT)\n );\n }\n\n if (isDragging) {\n const xDelta = x - xStart;\n const width = Math.abs(xDelta);\n if (!hasMoved) {\n if (width < 4) return;\n hasMoved = true;\n setSelectionStyle('display', 'flex');\n removeHover();\n }\n\n if (xDelta > 0) {\n setSelectionStyle('left', '');\n setSelectionStyle('right', '0');\n } else {\n setSelectionStyle('left', '0');\n setSelectionStyle('right', '');\n }\n setSelectionStyle('width', `${width}px`);\n\n const leftStart = Math.max(\n 0,\n Math.min(\n xStart + scrollLeft - rect.left - TIMELINE_PADDING,\n root.duration * scale\n )\n );\n const labelTStart = leftStart / scale;\n let t1: number;\n let t2: number;\n if (labelTStart < labelT) {\n t1 = labelTStart;\n t2 = labelT;\n } else {\n t1 = labelT;\n t2 = labelTStart;\n }\n selectionRef.current?.setAttribute(\n 'data-range',\n `${formatTimeSelection(t1)} — ${formatTimeSelection(t2)}`\n );\n selectionRef.current?.setAttribute(\n 'data-duration',\n `${formatTimeSelection(t2 - t1)} selected`\n );\n }\n\n if (Date.now() < hoverStartT) {\n nextFrame = requestAnimationFrame(onFrame);\n return;\n }\n\n if (scrollLeft !== scrollX || scrollTop !== scrollY) {\n scrollX = scrollLeft;\n scrollY = scrollTop;\n nextFrame = requestAnimationFrame(onFrame);\n return;\n }\n\n if (x - rect.left < 128) {\n labelTextRef.current?.setAttribute('data-align', 'left');\n } else if (x - rect.left > rect.width - 128) {\n labelTextRef.current?.setAttribute('data-align', 'right');\n } else {\n labelTextRef.current?.removeAttribute('data-align');\n }\n\n if (!hasMoved && !isExternalDrag) {\n const cache = memoCacheRef.current;\n\n // Span Hover\n const rowMin = getRowFromY(scrollTop) - HOVER_OVERSCAN;\n const rowMax = getRowFromY(scrollTop + rect.height) + HOVER_OVERSCAN;\n for (const span of spansRef.current) {\n const isHovered =\n span.row >= rowMin &&\n span.row <= rowMax &&\n t >= span.startTime &&\n t <= span.endTime;\n if (span.isHovered === isHovered) continue;\n span.isHovered = isHovered;\n cache.set(span.span.spanId, {});\n }\n\n // Event Hover — only show the nearest event when multiple overlap\n const eventSpreadPx = 12;\n const eventSpreadMs = eventSpreadPx / scale;\n let closestEvent: (typeof eventsRef.current)[number] | null = null;\n let closestDist = Infinity;\n for (const event of eventsRef.current) {\n const dist = Math.abs(event.timestamp - t);\n if (dist <= eventSpreadMs && dist < closestDist) {\n closestDist = dist;\n closestEvent = event;\n }\n }\n for (const event of eventsRef.current) {\n const isHovered = event === closestEvent;\n if (event.isHovered === isHovered) continue;\n event.isHovered = isHovered;\n const $event = event.ref?.current;\n if (!$event) continue;\n $event.setAttribute('data-hovered', String(isHovered));\n }\n\n dispatch({\n type: 'forceRender',\n });\n }\n };\n nextFrame = requestAnimationFrame(onFrame);\n\n const onPointerEnter = (event: PointerEvent): void => {\n if (event.pointerType !== 'mouse') return;\n hasEnteredRef.current = true;\n };\n const onPointerLeave = (): void => {\n if (!hasEnteredRef.current) return;\n hasEnteredRef.current = false;\n removeHover();\n };\n\n const onMouseMove = ({ clientX }: MouseEvent): void => {\n x = clientX;\n xRef.current = x;\n cancelAnimationFrame(nextFrame);\n nextFrame = requestAnimationFrame(onFrame);\n };\n\n const onContextMenu = (event: MouseEvent): void => {\n event.preventDefault();\n };\n const onMouseDown = (event: MouseEvent): void => {\n if (event.button === 2) {\n isRightClick = true;\n event.preventDefault();\n } else if (event.button !== 0) {\n return;\n } else {\n isRightClick = false;\n }\n if (timelineRef.current?.contains(event.target as HTMLElement)) {\n xStart = x;\n isDragging = true;\n } else {\n isExternalDrag = true;\n requestAnimationFrame(removeHover);\n }\n };\n const onMouseUp = (event: Event): void => {\n isExternalDrag = false;\n\n if (!isDragging) return;\n isDragging = false;\n\n if (!hasMoved) return;\n hasMoved = false;\n setSelectionStyle('display', '');\n setSelectionStyle('left', '');\n setSelectionStyle('right', '');\n setSelectionStyle('width', '');\n\n event.preventDefault();\n event.stopImmediatePropagation();\n\n if (isRightClick) {\n isRightClick = false;\n return;\n }\n\n if (!rectRef.current) updateRect();\n const rect = rectRef.current;\n if (!rect) return;\n\n const { scrollLeft } = $timeline;\n\n const start = Math.max(\n 0,\n Math.min(\n (xStart + scrollLeft - rect.left - TIMELINE_PADDING) / scale,\n root.duration\n )\n );\n const end = Math.max(\n 0,\n Math.min(\n (x + scrollLeft - rect.left - TIMELINE_PADDING) / scale,\n root.duration\n )\n );\n\n dispatch({\n type: 'scaleToRange',\n t1: start + root.startTime,\n t2: end + root.startTime,\n });\n };\n\n const onKeyDown = (event: KeyboardEvent): void => {\n if (!isDragging) return;\n if (event.key !== 'Escape') return;\n\n isRightClick = true;\n onMouseUp(event);\n };\n\n const onWindowScroll = (): void => {\n rectRef.current = undefined;\n trackpadZoomRef.current = undefined;\n cancelAnimationFrame(nextFrame);\n nextFrame = requestAnimationFrame(onFrame);\n };\n\n const onScroll = (): void => {\n cancelAnimationFrame(nextFrame);\n nextFrame = requestAnimationFrame(onFrame);\n };\n\n const observer = new ResizeObserver(() => {\n // NOTE: I tried to use the entry from this to immediately set the rect,\n // but for some reason it has different dimensions than the one from\n // .getBoundingClientRect()\n rectRef.current = undefined;\n });\n observer.observe($timeline);\n\n window.addEventListener('mousemove', onMouseMove);\n $timeline.addEventListener('contextmenu', onContextMenu);\n window.addEventListener('mousedown', onMouseDown);\n window.addEventListener('mouseup', onMouseUp);\n window.addEventListener('blur', onMouseUp);\n window.addEventListener('keydown', onKeyDown, true);\n window.addEventListener('scroll', onWindowScroll);\n $timeline.addEventListener('scroll', onScroll);\n $timeline.addEventListener('pointerenter', onPointerEnter);\n $timeline.addEventListener('pointerleave', onPointerLeave);\n\n return () => {\n observer.disconnect();\n window.removeEventListener('mousemove', onMouseMove);\n $timeline.removeEventListener('contextmenu', onContextMenu);\n window.removeEventListener('mousedown', onMouseDown);\n window.removeEventListener('mouseup', onMouseUp);\n window.removeEventListener('blur', onMouseUp);\n window.removeEventListener('keydown', onKeyDown, true);\n window.removeEventListener('scroll', onWindowScroll);\n $timeline.removeEventListener('scroll', onScroll);\n $timeline.removeEventListener('pointerenter', onPointerEnter);\n $timeline.removeEventListener('pointerleave', onPointerLeave);\n cancelAnimationFrame(nextFrame);\n xRef.current = x;\n removeHover();\n };\n }, [\n dispatch,\n root,\n scale,\n setStyle,\n setLabelStyle,\n setSelectionStyle,\n memoCacheRef,\n timelineRef,\n scrollSnapshotRef,\n ]);\n\n const trackpadZoomRef = useRef<TrackpadZoom>(undefined);\n useTrackpadZoom((delta) => {\n const $timeline = timelineRef.current;\n if (!$timeline) return;\n\n rectRef.current ??= $timeline.getBoundingClientRect();\n const rect = rectRef.current;\n const anchorX = Math.max(\n 0,\n Math.min(\n xRef.current - rect.left - TIMELINE_PADDING,\n rect.width - 2 * TIMELINE_PADDING\n )\n );\n\n let anchorT = 0;\n let existing = trackpadZoomRef.current;\n if (existing?.anchorX === anchorX) {\n anchorT = existing.anchorT;\n } else {\n anchorT = ($timeline.scrollLeft + anchorX) / scale;\n existing = {\n anchorT,\n anchorX,\n };\n trackpadZoomRef.current = existing;\n }\n\n dispatch({\n type: 'trackpadScale',\n delta: delta / 64,\n anchorT,\n anchorX,\n });\n });\n\n return (\n <>\n <div className={styles.cursorMarkerStickyParent}>\n <div\n className={styles.cursorMarkerLabelContainer}\n ref={labelRef}\n style={labelStyle}\n >\n <div className={styles.cursorMarkerLabel} ref={labelTextRef} />\n </div>\n </div>\n <div className={styles.cursorMarkerStickyParent}>\n <div className={styles.cursorMarkerContainer} ref={ref} style={style}>\n <div className={styles.cursorMarker}>\n <div\n className={styles.cursorSelection}\n ref={selectionRef}\n style={selectionStyle}\n />\n </div>\n </div>\n </div>\n </>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../../../../src/components/trace-viewer/components/node.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { clsx } from 'clsx';\nimport type { CSSProperties, MutableRefObject, ReactNode } from 'react';\nimport { memo, useEffect, useRef, useState } from 'react';\nimport styles from '../trace-viewer.module.css';\nimport type {\n MemoCache,\n MemoCacheKey,\n RootNode,\n ScrollSnapshot,\n SpanNode,\n VisibleSpan,\n VisibleSpanEvent,\n} from '../types';\nimport { MARKER_HEIGHT, ROW_HEIGHT, ROW_PADDING } from '../util/constants';\nimport { formatDuration, getHighResInMs } from '../util/timing';\nimport { SpanContent } from './span-content';\nimport { computeSegments } from './span-segments';\nimport {\n type ResourceType,\n type SpanLayout,\n getResourceType,\n getSpanLayout,\n} from './span-strategies';\n\nexport const getSpanColorClassName = (node: SpanNode): string => {\n if (node.isVercel) return String(styles.colorVercel);\n return String(styles[`color${node.resourceIndex % 5}` as 'color0']);\n};\n\nfunction getTerminalTimestamp(\n resourceType: ResourceType,\n node: VisibleSpan\n): number | undefined {\n const events = node.events;\n if (!events?.length) return undefined;\n\n switch (resourceType) {\n case 'hook':\n for (let i = events.length; i--; ) {\n if (events[i].event.name === 'hook_disposed') {\n return events[i].timestamp;\n }\n }\n return undefined;\n case 'sleep':\n for (let i = events.length; i--; ) {\n if (events[i].event.name === 'wait_completed') {\n return events[i].timestamp;\n }\n }\n return undefined;\n case 'run':\n for (let i = events.length; i--; ) {\n const name = events[i].event.name;\n if (\n name === 'run_completed' ||\n name === 'run_failed' ||\n name === 'run_cancelled'\n ) {\n return events[i].timestamp;\n }\n }\n return undefined;\n case 'step':\n for (let i = events.length; i--; ) {\n const name = events[i].event.name;\n if (name === 'step_completed' || name === 'step_failed') {\n return events[i].timestamp;\n }\n if (name === 'step_started' || name === 'step_retrying') {\n return undefined;\n }\n }\n return undefined;\n default:\n return undefined;\n }\n}\n\nexport const SpanNodes = memo(function SpanNodes({\n root,\n scale,\n spans,\n isLive = false,\n scrollSnapshotRef,\n cache,\n customSpanClassNameFunc,\n customSpanEventClassNameFunc,\n}: {\n root: RootNode;\n scale: number;\n spans: VisibleSpan[];\n isLive?: boolean;\n scrollSnapshotRef: MutableRefObject<ScrollSnapshot | undefined>;\n /** Not used in the body — exists solely to bust React.memo when the global memo cache changes. */\n cacheKey?: MemoCacheKey;\n cache: MemoCache;\n customSpanClassNameFunc?: (span: SpanNode) => string;\n customSpanEventClassNameFunc?: (event: VisibleSpanEvent) => string;\n}) {\n return spans.map((x) => (\n <SpanComponent\n cacheKey={cache.get(x.span.spanId)}\n customSpanEventClassNameFunc={customSpanEventClassNameFunc}\n customSpanClassNameFunc={customSpanClassNameFunc}\n key={x.span.spanId}\n node={x}\n root={root}\n scale={scale}\n traceIsLive={isLive}\n scrollSnapshotRef={scrollSnapshotRef}\n />\n ));\n});\n\n// ──────────────────────────────────────────────────────────────────────────\n// Compute inline styles from a SpanLayout\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction getSpanStyle(\n layout: SpanLayout,\n node: VisibleSpan,\n root: RootNode,\n scale: number\n): CSSProperties {\n // Use isExpanded (hovered or selected) for width expansion so that\n // selected small spans stay expanded and show their name.\n const expanded = layout.isExpanded;\n return {\n // Use actualWidth for CSS variable so hover expansion is accurate\n '--span-width': `${Math.max(layout.actualWidth, 1)}px`,\n minWidth: expanded ? layout.width : undefined,\n width: expanded ? undefined : layout.width,\n height: layout.height,\n maxWidth:\n expanded && !layout.isNearRightSide\n ? (root.endTime - node.startTime) * scale\n : undefined,\n containIntrinsicWidth: expanded ? undefined : layout.width,\n containIntrinsicHeight: layout.height,\n left: layout.isNearRightSide ? undefined : layout.left,\n right: layout.isNearRightSide\n ? (root.endTime - node.endTime) * scale\n : undefined,\n top: layout.top,\n } as CSSProperties;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// SpanComponent\n// ──────────────────────────────────────────────────────────────────────────\n\nexport const SpanComponent = memo(function SpanComponent({\n node,\n root,\n scale,\n traceIsLive = false,\n scrollSnapshotRef,\n customSpanClassNameFunc,\n customSpanEventClassNameFunc,\n}: {\n node: VisibleSpan;\n root: RootNode;\n scale: number;\n traceIsLive?: boolean;\n scrollSnapshotRef: MutableRefObject<ScrollSnapshot | undefined>;\n /** Not used in the body — exists solely to bust React.memo for this span. */\n cacheKey?: MemoCacheKey;\n customSpanClassNameFunc?: (span: SpanNode) => string;\n customSpanEventClassNameFunc?: (event: VisibleSpanEvent) => string;\n}): ReactNode {\n const ref = useRef<HTMLButtonElement>(null);\n\n useEffect(() => {\n node.ref = ref;\n return () => {\n node.ref = undefined;\n };\n }, [node]);\n\n const { span } = node;\n const resourceType = getResourceType(node);\n const [liveNow, setLiveNow] = useState(0);\n\n // Get custom class name from callback if provided\n const customClassName = customSpanClassNameFunc\n ? customSpanClassNameFunc(node)\n : '';\n\n // Workflow span types use colored segments + boundary line markers\n // Generic OTEL spans use diamond event markers\n const isWorkflowSpan = resourceType !== 'default';\n\n // Determine if this span is still active (live). We require the parent run\n // to be explicitly live to avoid completed/cancelled traces continuing to\n // grow due to timing heuristics.\n const data = span.attributes?.data as Record<string, unknown> | undefined;\n const terminalTimestamp = getTerminalTimestamp(resourceType, node);\n const hasTerminalEvent = terminalTimestamp != null;\n const isCompletedByData =\n resourceType === 'hook'\n ? Boolean(data?.disposedAt)\n : Boolean(data?.completedAt);\n const isCompleted = isCompletedByData || hasTerminalEvent;\n const isLive = traceIsLive && isWorkflowSpan && !isCompleted;\n\n useEffect(() => {\n if (!isLive) return;\n setLiveNow(Date.now());\n const interval = setInterval(() => {\n setLiveNow(Date.now());\n }, 250);\n return () => clearInterval(interval);\n }, [isLive]);\n\n const canonicalStartTime = getHighResInMs(span.startTime);\n const canonicalEndTime = getHighResInMs(span.endTime);\n const canonicalDuration = getHighResInMs(span.duration);\n const canonicalActiveStartTime = span.activeStartTime\n ? getHighResInMs(span.activeStartTime)\n : undefined;\n\n const durationMs =\n terminalTimestamp != null\n ? Math.max(0, terminalTimestamp - canonicalStartTime)\n : isLive\n ? Math.max(0, (liveNow || Date.now()) - canonicalStartTime)\n : canonicalDuration;\n const duration = node.isInstrumentationHint\n ? 'Get Started'\n : formatDuration(durationMs);\n const baseNode = {\n ...node,\n startTime: canonicalStartTime,\n endTime: canonicalEndTime,\n duration: canonicalDuration,\n activeStartTime: canonicalActiveStartTime,\n } as VisibleSpan;\n const segmentNode = isLive\n ? ({\n ...baseNode,\n duration: durationMs,\n endTime: canonicalStartTime + durationMs,\n } as VisibleSpan)\n : baseNode;\n const hasSegments =\n isWorkflowSpan &&\n computeSegments(resourceType, segmentNode).segments.length > 0;\n const layout = getSpanLayout(\n resourceType,\n segmentNode,\n root,\n scale,\n scrollSnapshotRef\n );\n\n // For live spans the data-level `node.duration` can be stale (from the last\n // fetch) while the visual width is growing via rAF. Recompute from real\n // elapsed time so that:\n // - height/isSmall classification stays correct (not shrunken to 40%)\n // - React-rendered width matches the rAF-driven width, preventing a brief\n // shrink→expand flash on re-render that breaks cursor hit-testing\n if (isLive) {\n const elapsed = durationMs;\n const liveActualWidth = elapsed * scale;\n const liveWidth = Math.max(liveActualWidth, 4);\n layout.actualWidth = liveActualWidth;\n layout.width = liveWidth;\n layout.isSmall = liveActualWidth < 64;\n layout.isHuge = liveActualWidth >= 500;\n if (!layout.isSmall) {\n layout.height = ROW_HEIGHT;\n layout.top = MARKER_HEIGHT + (ROW_HEIGHT + ROW_PADDING) * segmentNode.row;\n }\n }\n\n // Smoothly grow active span width at 60fps using wall clock time\n useEffect(() => {\n if (!isLive || !ref.current) return;\n\n let rafId = 0;\n const tick = (): void => {\n const $el = ref.current;\n if (!$el) return;\n const elapsed = Date.now() - canonicalStartTime;\n const w = Math.max(elapsed * scale, 2);\n $el.style.width = `${w}px`;\n $el.style.setProperty('--span-width', `${w}px`);\n rafId = requestAnimationFrame(tick);\n };\n rafId = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(rafId);\n }, [isLive, canonicalStartTime, scale]);\n\n const renderNode = segmentNode;\n\n return (\n <>\n <button\n aria-label={`${span.name} - ${duration}`}\n className={clsx(\n styles.spanNode,\n layout.isHuge && styles.huge,\n layout.isSmall && styles.small,\n layout.isExpanded && styles.xHover,\n node.isHighlighted\n ? styles.colorHighlight\n : getSpanColorClassName(node),\n node.isHighlighted === false && styles.unlit,\n customClassName,\n hasSegments && styles.hasSegments\n )}\n data-span-id={span.spanId}\n data-start-time={segmentNode.startTime - root.startTime}\n data-right-side={layout.isNearRightSide}\n data-selected={node.isSelected ? '' : undefined}\n ref={ref}\n style={getSpanStyle(layout, segmentNode, root, scale)}\n type=\"button\"\n >\n <SpanContent\n durationMs={durationMs}\n resourceType={resourceType}\n node={renderNode}\n layout={layout}\n />\n </button>\n {segmentNode.events && !layout.isSmall\n ? segmentNode.events.map((x) => (\n <SpanEventComponent\n customSpanEventClassNameFunc={customSpanEventClassNameFunc}\n event={x}\n key={x.key}\n node={segmentNode}\n root={root}\n scale={scale}\n asBoundary={isWorkflowSpan}\n />\n ))\n : null}\n </>\n );\n});\n\n// ──────────────────────────────────────────────────────────────────────────\n// SpanEventComponent\n// ──────────────────────────────────────────────────────────────────────────\n\n/** Human-readable labels for workflow event types */\nconst BOUNDARY_LABELS: Record<string, string> = {\n step_started: 'Started',\n step_retrying: 'Retrying',\n step_failed: 'Failed',\n hook_created: 'Created',\n hook_received: 'Received',\n hook_disposed: 'Resolved',\n wait_created: 'Sleep started',\n wait_completed: 'Sleep completed',\n run_started: 'Started',\n run_completed: 'Completed',\n run_failed: 'Run failed',\n step_completed: 'Completed',\n};\n\nexport const SpanEventComponent = memo(function SpanEventComponent({\n event,\n node,\n root,\n scale,\n customSpanEventClassNameFunc,\n asBoundary = false,\n}: {\n event: VisibleSpanEvent;\n node: VisibleSpan;\n root: RootNode;\n scale: number;\n customSpanEventClassNameFunc?: (event: VisibleSpanEvent) => string;\n asBoundary?: boolean;\n}): ReactNode {\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n event.ref = ref;\n return () => {\n event.ref = undefined;\n };\n }, [event]);\n\n const {\n event: { name },\n } = event;\n const timestamp = formatDuration(event.timestamp - root.startTime);\n const displayLabel = asBoundary ? (BOUNDARY_LABELS[name] ?? name) : name;\n\n // For boundary events, compute the duration of the phase.\n // \"Forward\" events (started, retrying) measure until the next event.\n // \"Terminal\" events (completed) measure from the previous started event.\n const isForwardEvent =\n asBoundary &&\n (name === 'step_started' ||\n name === 'run_started' ||\n name === 'step_retrying');\n const isTerminalEvent =\n asBoundary && (name === 'step_completed' || name === 'run_completed');\n\n let phaseDuration: string | null = null;\n let phaseLabel: string | null = null;\n if ((isForwardEvent || isTerminalEvent) && node.events) {\n const sortedNodeEvents = [...node.events].sort(\n (a, b) => a.timestamp - b.timestamp\n );\n const currentIdx = sortedNodeEvents.findIndex((e) => e.key === event.key);\n\n if (isTerminalEvent) {\n // Look backward to find the last step_started\n let prevStartTime: number | null = null;\n for (let i = currentIdx - 1; i >= 0; i--) {\n if (sortedNodeEvents[i].event.name === 'step_started') {\n prevStartTime = sortedNodeEvents[i].timestamp;\n break;\n }\n }\n if (prevStartTime !== null) {\n phaseDuration = formatDuration(event.timestamp - prevStartTime);\n phaseLabel = 'Executed';\n }\n } else {\n // Look forward to the next event\n const nextEvent = sortedNodeEvents[currentIdx + 1];\n const endTime = nextEvent ? nextEvent.timestamp : node.endTime;\n phaseDuration = formatDuration(endTime - event.timestamp);\n phaseLabel = name === 'step_retrying' ? 'Waited' : 'Executed';\n }\n }\n\n const left = (event.timestamp - root.startTime) * scale;\n const top = MARKER_HEIGHT + (ROW_HEIGHT + ROW_PADDING) * node.row;\n const isLeftAligned =\n node.duration <= 0 ||\n (event.timestamp - node.startTime) / node.duration < 0.5;\n\n // Get custom class name from callback if provided\n const customClassName = customSpanEventClassNameFunc\n ? customSpanEventClassNameFunc(event)\n : '';\n\n return (\n <div\n title={\n phaseDuration\n ? `${displayLabel} ${timestamp}\\n${phaseLabel} ${phaseDuration}`\n : `${displayLabel} ${timestamp}`\n }\n className={clsx(\n styles.spanNodeEvent,\n customClassName,\n asBoundary && styles.boundaryMarker,\n node.isHighlighted\n ? styles.colorHighlight\n : getSpanColorClassName(node),\n node.isHighlighted === false && styles.unlit\n )}\n data-hovered={event.isHovered}\n ref={ref}\n style={\n {\n left,\n top,\n } as CSSProperties\n }\n >\n <div\n className={clsx(\n styles.hoverInfo,\n isLeftAligned ? styles.alignStart : styles.alignEnd\n )}\n >\n {asBoundary ? (\n <>\n <span className={styles.eventName}>{displayLabel}</span>\n <span className={styles.eventTimestamp}>{timestamp}</span>\n {phaseDuration ? (\n <>\n <span className={styles.eventName}>{phaseLabel}</span>\n <span className={styles.eventTimestamp}>{phaseDuration}</span>\n </>\n ) : null}\n </>\n ) : (\n <>\n <span className={styles.eventName}>{name}</span>\n <span className={styles.eventTimestamp}>{timestamp}</span>\n </>\n )}\n </div>\n {asBoundary ? (\n <div className={styles.boundaryLine} />\n ) : (\n <div className={styles.eventDiamond} />\n )}\n </div>\n );\n});\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-input.js","sourceRoot":"","sources":["../../../../src/components/trace-viewer/components/search-input.tsx"],"names":[],"mappings":";AACA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAEhD,MAAM,UAAU,WAAW,CAAC,EAC1B,MAAM,EACN,KAAK,EACL,KAAK,EACL,WAAW,EACX,QAAQ,GAOT;IACC,OAAO,CACL,iBAAO,SAAS,EAAE,MAAM,CAAC,gBAAgB,aACvC,cAAK,SAAS,EAAE,MAAM,CAAC,iBAAiB,YACtC,KAAC,mBAAmB,KAAG,GACnB,EACN,gBACE,IAAI,EAAC,QAAQ,EACb,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GACxB,IACI,CACT,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB;IAC1B,OAAO,CACL,eACE,KAAK,EAAE,EAAE,EACT,MAAM,EAAE,EAAE,EACV,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,iBACC,MAAM,EAClB,SAAS,EAAC,OAAO,aAEjB,iBAAQ,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,CAAC,EAAC,KAAK,EAAC,MAAM,EAAC,cAAc,EAAC,WAAW,EAAC,KAAK,GAAG,EACxE,eACE,CAAC,EAAC,kBAAkB,EACpB,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,KAAK,EACjB,aAAa,EAAC,OAAO,GACrB,IACE,CACP,CAAC;AACJ,CAAC","sourcesContent":["import type { ChangeEventHandler, ReactNode } from 'react';\nimport styles from '../trace-viewer.module.css';\n\nexport function SearchInput({\n height,\n width,\n value,\n placeholder,\n onChange,\n}: {\n height: number | string;\n width?: number | string;\n value: string;\n placeholder?: string;\n onChange: ChangeEventHandler<HTMLInputElement>;\n}): ReactNode {\n return (\n <label className={styles.searchInputLabel}>\n <div className={styles.searchInputPrefix}>\n <MagnifyingGlassIcon />\n </div>\n <input\n type=\"search\"\n value={value}\n placeholder={placeholder}\n onChange={onChange}\n style={{ height, width }}\n />\n </label>\n );\n}\n\nfunction MagnifyingGlassIcon(): ReactNode {\n return (\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 cx=\"7\" cy=\"7\" r=\"4.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path\n d=\"M11.5 11.5L14 14\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../src/components/trace-viewer/components/search.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAkB,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,UAAU,SAAS;IACvB,OAAO,CACL,cAAK,SAAS,EAAE,MAAM,CAAC,SAAS,YAC9B,KAAC,kBAAkB,KAAG,GAClB,CACP,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB;IACzB,MAAM,EAAE,QAAQ,EAAE,GAAG,cAAc,EAAE,CAAC;IACtC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEvC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,OAAO,GAAG,UAAU,CACxB,GAAG,EAAE,CACH,QAAQ,CAAC;YACP,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,KAAK;SACd,CAAC,EACJ,GAAG,CACJ,CAAC;QAEF,OAAO,GAAG,EAAE;YACV,YAAY,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;IAEtB,OAAO,CACL,cAAK,SAAS,EAAE,MAAM,CAAC,WAAW,YAChC,KAAC,WAAW,IACV,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACzC,WAAW,EAAC,oBAAe,EAC3B,KAAK,EAAE,KAAK,EACZ,KAAK,EAAC,MAAM,GACZ,GACE,CACP,CAAC;AACJ,CAAC","sourcesContent":["'use client';\n\nimport { type ReactNode, useEffect, useState } from 'react';\nimport { useTraceViewer } from '../context';\nimport styles from '../trace-viewer.module.css';\nimport { SEARCH_HEIGHT } from '../util/constants';\nimport { SearchInput } from './search-input';\n\nexport function SearchBar(): ReactNode {\n return (\n <nav className={styles.searchBar}>\n <SearchInputWrapper />\n </nav>\n );\n}\n\nfunction SearchInputWrapper(): ReactNode {\n const { dispatch } = useTraceViewer();\n const [value, setValue] = useState('');\n\n useEffect(() => {\n const timeout = setTimeout(\n () =>\n dispatch({\n type: 'setFilter',\n filter: value,\n }),\n 100\n );\n\n return () => {\n clearTimeout(timeout);\n };\n }, [dispatch, value]);\n\n return (\n <div className={styles.searchInput}>\n <SearchInput\n height={SEARCH_HEIGHT}\n onChange={(e) => setValue(e.target.value)}\n placeholder=\"Search spans…\"\n value={value}\n width=\"100%\"\n />\n </div>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"span-content.js","sourceRoot":"","sources":["../../../../src/components/trace-viewer/components/span-content.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport type { CSSProperties, ReactNode } from 'react';\nimport styles from '../trace-viewer.module.css';\nimport type { SpanNode } from '../types';\nimport { formatDuration } from '../util/timing';\nimport {\n type Segment,\n type SegmentStatus,\n SEGMENT_CLASS_MAP,\n computeSegments,\n} from './span-segments';\nimport type { ResourceType, SpanLayout } from './span-strategies';\n\n// ──────────────────────────────────────────────────────────────────────────\n// Shared helpers\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction getDuration(node: SpanNode): string {\n if (node.isInstrumentationHint) {\n return 'Get Started';\n }\n return formatDuration(node.duration);\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Segment rendering (shared across all workflow span types)\n// ──────────────────────────────────────────────────────────────────────────\n\nconst SEGMENT_LABELS: Record<SegmentStatus, string> = {\n queued: 'Queued',\n running: '',\n failed: 'Failed',\n retrying: 'Retry wait',\n succeeded: 'Executed',\n waiting: 'Waiting',\n sleeping: 'Sleeping',\n received: 'Received',\n};\n\nfunction SegmentLayer({\n segments,\n spanDuration,\n}: {\n segments: Segment[];\n spanDuration: number;\n}): ReactNode {\n if (segments.length === 0) return null;\n\n return (\n <div className={styles.segmentLayer}>\n {segments.map((seg, i) => {\n const className =\n styles[SEGMENT_CLASS_MAP[seg.status] as keyof typeof styles];\n const segDuration =\n (seg.endFraction - seg.startFraction) * spanDuration;\n const label = SEGMENT_LABELS[seg.status];\n const style: CSSProperties = {\n left: `${seg.startFraction * 100}%`,\n width: `${(seg.endFraction - seg.startFraction) * 100}%`,\n };\n\n return (\n <div\n key={`seg-${seg.status}-${String(i)}`}\n className={`${styles.segment} ${String(className)}`}\n style={style}\n title={\n label\n ? `${label} ${formatDuration(segDuration)}`\n : formatDuration(segDuration)\n }\n />\n );\n })}\n </div>\n );\n}\n\n/** Build inline segment tags to render next to the span name. */\nfunction getSegmentTags(\n segments: Segment[],\n spanDuration: number\n): { label: string; duration: string }[] {\n const tags: { label: string; duration: string }[] = [];\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i];\n const label = SEGMENT_LABELS[seg.status];\n if (!label) continue; // skip \"running\" which has no label\n let segDuration = (seg.endFraction - seg.startFraction) * spanDuration;\n\n // For terminal segments (succeeded/failed) with ~0 duration,\n // use the preceding running segment's duration instead.\n if (\n segDuration < 1 &&\n (seg.status === 'succeeded' || seg.status === 'failed') &&\n i > 0\n ) {\n const prev = segments[i - 1];\n if (prev.status === 'running') {\n segDuration = (prev.endFraction - prev.startFraction) * spanDuration;\n }\n }\n\n // Skip tags that still have no meaningful duration\n if (segDuration < 1) continue;\n\n tags.push({ label, duration: formatDuration(segDuration) });\n }\n return tags;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Text content (shared label + duration rendering)\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction TextContent({\n node,\n layout,\n durationMs,\n segmentTags,\n}: SpanContentProps & {\n segmentTags?: { label: string; duration: string }[];\n}): ReactNode {\n const duration = node.isInstrumentationHint\n ? getDuration(node)\n : formatDuration(durationMs ?? node.duration);\n\n if (layout.isSmall && !layout.isHovered) {\n return null;\n }\n\n const showTags =\n segmentTags &&\n segmentTags.length > 0 &&\n (layout.isHovered || layout.width > 200);\n\n return (\n <>\n <span className={styles.spanName}>\n {node.label || node.span.name}\n {showTags\n ? segmentTags.map((tag, i) => (\n <span key={i} className={styles.segmentTag}>\n {' · '}\n {tag.label} {tag.duration}\n </span>\n ))\n : null}\n </span>\n {layout.isHuge ? <span className={styles.spanSpacer} /> : null}\n {layout.isHovered || layout.width > 128 ? (\n <span className={styles.spanDuration}>{duration}</span>\n ) : null}\n </>\n );\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Content props\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface SpanContentProps {\n node: SpanNode;\n layout: SpanLayout;\n durationMs?: number;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Default content (generic OTEL spans — no segments)\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction DefaultContent({ node, layout }: SpanContentProps): ReactNode {\n return <TextContent node={node} layout={layout} />;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Workflow content (segments + text for workflow span types)\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction WorkflowContent({\n resourceType,\n node,\n layout,\n durationMs,\n}: SpanContentProps & { resourceType: ResourceType }): ReactNode {\n const spanDuration = durationMs ?? node.duration;\n const { segments } = computeSegments(resourceType, node);\n const segmentTags = getSegmentTags(segments, spanDuration);\n\n return (\n <>\n <SegmentLayer segments={segments} spanDuration={spanDuration} />\n <TextContent\n durationMs={spanDuration}\n node={node}\n layout={layout}\n segmentTags={segmentTags}\n />\n </>\n );\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Per-type content components\n// ──────────────────────────────────────────────────────────────────────────\n\nexport function RunContent(props: SpanContentProps): ReactNode {\n return <WorkflowContent resourceType=\"run\" {...props} />;\n}\n\nexport function StepContent(props: SpanContentProps): ReactNode {\n return <WorkflowContent resourceType=\"step\" {...props} />;\n}\n\nexport function HookContent(props: SpanContentProps): ReactNode {\n return <WorkflowContent resourceType=\"hook\" {...props} />;\n}\n\nexport function SleepContent(props: SpanContentProps): ReactNode {\n return <WorkflowContent resourceType=\"sleep\" {...props} />;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Dispatcher\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Returns the inner content for a span based on its resource type.\n */\nexport function SpanContent({\n resourceType,\n ...props\n}: SpanContentProps & { resourceType: ResourceType }): ReactNode {\n switch (resourceType) {\n case 'run':\n return <RunContent {...props} />;\n case 'step':\n return <StepContent {...props} />;\n case 'hook':\n return <HookContent {...props} />;\n case 'sleep':\n return <SleepContent {...props} />;\n default:\n return <DefaultContent {...props} />;\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"span-detail-panel.js","sourceRoot":"","sources":["../../../../src/components/trace-viewer/components/span-detail-panel.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { clsx } from 'clsx';\nimport type { PointerEventHandler, ReactNode } from 'react';\nimport {\n Fragment,\n memo,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n initialState,\n useCustomPanelComponent,\n useTraceViewer,\n} from '../context';\nimport styles from '../trace-viewer.module.css';\nimport type {\n GetQuickLinks,\n QuickLinkValue,\n RootNode,\n Span,\n SpanNode,\n TraceNode,\n} from '../types';\nimport { formatDuration } from '../util/timing';\nimport { getSpanColorClassName } from './node';\nimport {\n ButtonLink,\n IconChevronDown,\n IconCross,\n IconExternalSmall,\n Link,\n Note,\n Skeleton,\n} from './ui';\n\nconst percentage = (n: number): string => `${(100 * n).toFixed(3)}%`;\n\ninterface GroupedAttribute {\n prefix: string;\n attributes: Attribute[];\n}\n\ninterface Attribute {\n suffix: string;\n key: string;\n value: string;\n}\n\nconst sortWord = (a: string, b: string): number => {\n if (a < b) {\n return -1;\n } else if (a > b) {\n return 1;\n }\n return 0;\n};\n\nconst getGroupedAttributes = (\n attributes: Span['attributes']\n): GroupedAttribute[] => {\n // Build groups of items with the same prefix\n const groups: Record<string, GroupedAttribute> = {};\n for (const [key, value] of Object.entries(attributes)) {\n const dotIndex = key.indexOf('.');\n let prefix = '';\n let suffix = '';\n if (dotIndex !== -1) {\n prefix = key.substring(0, dotIndex);\n suffix = key.substring(dotIndex + 1);\n } else {\n suffix = key;\n }\n\n let group = groups[prefix];\n if (!group) {\n group = {\n prefix,\n attributes: [],\n };\n groups[prefix] = group;\n }\n group.attributes.push({\n key,\n suffix,\n value: String(value),\n });\n }\n\n // List and sort everything\n const result = Array.from(Object.values(groups)).sort((a, b) =>\n sortWord(a.prefix, b.prefix)\n );\n for (const group of result) {\n group.attributes.sort((a, b) => sortWord(a.suffix, b.suffix));\n }\n return result;\n};\n\n// biome-ignore lint/correctness/noUnusedFunctionParameters: ignored using `--suppress`\nconst getAncestors = (_root: RootNode, start: SpanNode | null): SpanNode[] => {\n const result: SpanNode[] = [];\n\n if (!start) return result;\n\n for (let node: TraceNode = start; 'parent' in node; node = node.parent) {\n result.unshift(node);\n }\n\n return result;\n};\n\nexport const SpanDetailPanelBody = () => {\n const {\n state: { root, selected, resourceMap, getQuickLinks },\n dispatch,\n } = useTraceViewer();\n\n const ancestors = useMemo(\n () => getAncestors(root, selected),\n [root, selected]\n );\n\n const attributeGroups = useMemo(\n () => getGroupedAttributes(selected?.span.attributes ?? {}),\n [selected]\n );\n\n const resourceAttributeGroups = useMemo(() => {\n const resourceName = selected?.span.resource;\n if (!resourceName) return [];\n const resourceAttributes = resourceMap[resourceName];\n if (!resourceAttributes) return [];\n return getGroupedAttributes(resourceAttributes);\n }, [resourceMap, selected]);\n\n if (!selected) return null;\n\n const { span } = selected;\n\n const isEntrySpan = detectIsEntrySpan(selected);\n\n return (\n <>\n {selected.isVercel ? <InfraSpanDescription node={selected} /> : null}\n {selected.isInstrumentationHint ? <InstrumentationHint /> : null}\n {!selected.isInstrumentationHint && ancestors.length ? (\n <DetailGroup className={styles.ancestorGroup} name=\"Location\">\n {ancestors.map((node) => (\n <button\n className={styles.ancestorNode}\n key={`${selected.span.spanId}.${node.span.spanId}`}\n onClick={() =>\n dispatch({\n type: 'select',\n id: node.span.spanId,\n })\n }\n type=\"button\"\n >\n <div className={styles.ancestorText}>\n <span className={styles.ancestorName}>\n {node.label || node.span.name}\n </span>\n <span className={styles.ancestorDuration}>\n {formatDuration(node.duration)}\n </span>\n </div>\n <span aria-hidden className={styles.ancestorLineContainer}>\n <span\n className={clsx(\n styles.ancestorLine,\n getSpanColorClassName(node)\n )}\n style={{\n left: percentage(\n (node.startTime - root.startTime) / root.duration\n ),\n width: percentage(node.duration / root.duration),\n }}\n />\n </span>\n </button>\n ))}\n </DetailGroup>\n ) : null}\n {isEntrySpan ? (\n <EntrySpanLinks getQuickLinks={getQuickLinks} span={selected.span} />\n ) : null}\n {selected.events?.length ? (\n <DetailGroup name=\"Events\">\n {selected.events.map((event) => (\n <Fragment key={event.key}>\n <dl className={styles.spanDetailPanelAttribute}>\n <dt className={styles.spanDetailPanelAttributeKey}>\n {event.event.name}\n </dt>\n <dd className={styles.spanDetailPanelAttributeValue}>\n {formatDuration(event.timestamp - root.startTime)}\n </dd>\n </dl>\n {Object.entries(event.event.attributes).map(([key, value]) => (\n <DetailLine\n key={key}\n name={`${event.event.name}.${key}`}\n value={value}\n />\n ))}\n </Fragment>\n ))}\n </DetailGroup>\n ) : null}\n {attributeGroups.length ? (\n <DetailGroup name=\"Attributes\">\n {attributeGroups.map((group) => (\n <Fragment key={group.prefix}>\n {group.attributes.map(({ key, value }) => (\n <DetailLine key={key} name={key} value={value} />\n ))}\n </Fragment>\n ))}\n </DetailGroup>\n ) : null}\n {resourceAttributeGroups.length ? (\n <DetailGroup name=\"Resource\">\n {resourceAttributeGroups.map((group) => (\n <Fragment key={group.prefix}>\n {group.attributes.map(({ key, value }) => (\n <DetailLine key={key} name={key} value={value} />\n ))}\n </Fragment>\n ))}\n </DetailGroup>\n ) : null}\n {selected.isInstrumentationHint ? null : (\n <DetailGroup name=\"Library\">\n <DetailLine name=\"name\" value={span.library.name} />\n {span.library.version ? (\n <DetailLine name=\"version\" value={span.library.version} />\n ) : null}\n </DetailGroup>\n )}\n </>\n );\n};\n\nexport function SpanDetailPanel({\n attached = false,\n}: {\n attached?: boolean;\n}): ReactNode {\n const {\n state: { selected, isMobile },\n dispatch,\n } = useTraceViewer();\n const customPanelComponent = useCustomPanelComponent();\n\n if (!selected) return null;\n\n const { span } = selected;\n\n return (\n <div className={clsx(styles.spanDetailPanel, isMobile && styles.mobile)}>\n {attached && !isMobile ? <PanelResizer /> : null}\n <div className={styles.spanDetailPanelTop}>\n <div className={styles.spanDetailPanelTopInfo}>\n {/* Name/ID first */}\n <span className={styles.spanDetailPanelName} title={span.name}>\n {span.name}\n </span>\n {/* Right side: duration badge, separator, close */}\n <div className={styles.spanDetailPanelCorner}>\n {selected.isInstrumentationHint ? null : (\n <span className={styles.spanDetailPanelDuration}>\n {formatDuration(selected.duration)}\n </span>\n )}\n <div className={styles.spanDetailPanelCloseVerticalRule} />\n <button\n aria-label=\"Close Span Details\"\n className={styles.spanDetailPanelClose}\n onClick={() =>\n dispatch({\n type: 'deselect',\n })\n }\n type=\"button\"\n >\n <IconCross color=\"gray-700\" size={20} />\n </button>\n </div>\n </div>\n </div>\n <div className={clsx('flex gap-3', styles.spanDetailPanelBody)}>\n {customPanelComponent || <SpanDetailPanelBody />}\n </div>\n </div>\n );\n}\n\nconst EXPANDED_STORAGE_KEY_PREFIX = 'vc-trace-span-exp:';\n\nfunction DetailGroup({\n name,\n className = '',\n children,\n}: {\n name: string;\n className?: string;\n children: ReactNode;\n}): ReactNode {\n const [isExpanded, setIsExpanded] = useState(() => {\n if (!('localStorage' in globalThis)) return true;\n return (\n localStorage.getItem(`${EXPANDED_STORAGE_KEY_PREFIX}${name}`) !== '0'\n );\n });\n\n const toggleExpanded = useCallback(() => {\n setIsExpanded((x) => {\n const willBeExpanded = !x;\n localStorage.setItem(\n `${EXPANDED_STORAGE_KEY_PREFIX}${name}`,\n String(Number(willBeExpanded))\n );\n return willBeExpanded;\n });\n }, [name]);\n\n return (\n <div\n className={clsx(\n styles.detailGroup,\n isExpanded ? styles.expanded : styles.collapsed,\n className\n )}\n >\n <button\n className={styles.detailHeading}\n onClick={toggleExpanded}\n type=\"button\"\n >\n <span>{name}</span>\n <IconChevronDown />\n </button>\n {isExpanded ? children : null}\n </div>\n );\n}\n\nconst CommonHttpVerbs = new Set([\n 'OPTIONS',\n 'HEAD',\n 'GET',\n 'PUT',\n 'POST',\n 'DELETE',\n]);\nconst KnownSpans: Record<string, string> = {\n 'Resolve Deployment': `How long it took Vercel's routing layer to retrieve details for the deployment.`,\n 'Resolve Cache': `How long it took Vercel's routing layer to check for a cached function invocation.`,\n 'Resolve Route': `How long it took Vercel's routing layer to resolve routing rules, including redirects and rewrites.`,\n 'Invoke Middleware': `How long it took this middleware to start and run user code.`,\n 'Invoke Function': `How long it took this Vercel Function to start and run user code.`,\n waitUntil: `How long it took to run user code inside of waitUntil.`,\n 'Start VM': `How long it took to start the Virtual Machine which contains the Vercel Function.`,\n 'Spawn Node.js': `How long it took the Virtual Machine to start the Node.js runtime.`,\n 'Spawn Python': `How long it took the Virtual Machine to start the Python runtime.`,\n 'Init User Code': `How long it took to import the user code and run any globally-scoped code.`,\n};\n\nconst ColdStartSpanNames = new Set([\n 'Start VM',\n 'Spawn Node.js',\n 'Spawn Python',\n 'Init User Code',\n]);\n\nconst getRegion = (\n node: SpanNode | RootNode | null | undefined\n): string | null => {\n if (!node || !('span' in node)) {\n return null;\n }\n\n const attr = node.span.attributes;\n const region = attr['vercel.region'] || attr['vercel.function.region'];\n if (region) return String(region);\n return null;\n};\n\nconst getNote = (node: SpanNode): ReactNode => {\n const { name } = node.span;\n const region = getRegion(node);\n const parentRegion = getRegion(node.parent);\n\n if (node.span.attributes['vercel.middleware.internal'] === 'true') {\n return 'The Vercel Toolbar created this middleware.';\n } else if (\n ColdStartSpanNames.has(name) ||\n (name === 'Invoke Function' &&\n node.children.some((x) => ColdStartSpanNames.has(x.span.name)))\n ) {\n return 'This function encountered a cold start.';\n } else if (region && parentRegion && region !== parentRegion) {\n return 'This request was routed across regions.';\n }\n\n return null;\n};\n\nconst detectIsEntrySpan = (node: SpanNode): boolean => {\n if (!node.isVercel) return false;\n const { name } = node.span;\n const spaceIndex = name.indexOf(' ');\n if (spaceIndex === -1) return false;\n const firstWord = name.substring(0, spaceIndex);\n return CommonHttpVerbs.has(firstWord);\n};\n\nfunction InfraSpanDescription({ node }: { node: SpanNode }): ReactNode {\n const { name } = node.span;\n let description = KnownSpans[name];\n\n if (!description && detectIsEntrySpan(node)) {\n description = `How long it took for Vercel to process the request and send the response.`;\n }\n\n if (!description) return null;\n\n const note = getNote(node);\n\n return (\n <DetailGroup name=\"What is this?\">\n <div className={styles.infraSpanDescription}>\n <span>{description}</span>\n {note ? <Note>{note}</Note> : note}\n </div>\n </DetailGroup>\n );\n}\n\nconst EntrySpanLinks = memo(function EntrySpanLinks({\n getQuickLinks,\n span,\n}: {\n getQuickLinks: GetQuickLinks;\n span: Span;\n}): ReactNode {\n const links = getQuickLinks(span);\n\n if (!links.length) return null;\n\n return (\n <DetailGroup name=\"Links\">\n {links.map(({ key, value }) => (\n <EntrySpanLink key={key} link={value} name={key} />\n ))}\n </DetailGroup>\n );\n});\n\ninterface ResolvablePromise<T> extends Promise<T> {\n __resolvedValue?: T;\n __rejectedValue?: unknown;\n}\n\nfunction usePromise<T>(promise: ResolvablePromise<T>): T | undefined {\n const [_, setLatest] = useState({});\n const fulfilled =\n promise.__resolvedValue !== undefined ||\n promise.__rejectedValue !== undefined;\n useEffect(() => {\n if (fulfilled) return;\n\n promise\n .then((value) => {\n promise.__resolvedValue = value;\n })\n .catch((err) => {\n promise.__rejectedValue = err;\n })\n .finally(() => setLatest({}));\n }, [promise, fulfilled]);\n\n return promise.__resolvedValue;\n}\n\nfunction EntrySpanLink({\n name,\n link: linkPromise,\n}: {\n name: string;\n link: Promise<QuickLinkValue>;\n}): ReactNode {\n const link = usePromise(linkPromise);\n\n return (\n <Link\n as={link ? undefined : 'span'}\n className={clsx(\n styles.spanDetailPanelAttribute,\n styles.spanDetailPanelQuickLink\n )}\n href={link?.href || ''}\n >\n <span className={styles.spanDetailPanelAttributeKey}>{name}</span>\n <span\n className={clsx(\n styles.spanDetailPanelAttributeValue,\n styles.spanDetailPanelQuickLinkLabel\n )}\n >\n {link ? (\n <>\n {link.label}\n {link.icon || <IconExternalSmall color=\"gray-900\" />}\n </>\n ) : (\n <>\n <Skeleton height={18} width={32 + name.length * 8} />\n <Skeleton height={18} rounded width={18} />\n </>\n )}\n </span>\n </Link>\n );\n}\n\nfunction InstrumentationHint(): ReactNode {\n return (\n <DetailGroup name=\"What is this?\">\n <div className={styles.infraSpanDescription}>\n <span>{`You can visualize your application's spans alongside Vercel's spans in this viewer.`}</span>\n <ButtonLink\n href=\"https://vercel.com/docs/session-tracing#adding-custom-spans\"\n size=\"small\"\n target=\"_blank\"\n >\n Get Started\n </ButtonLink>\n </div>\n </DetailGroup>\n );\n}\n\nfunction DetailLine({\n name,\n value,\n}: {\n name: string;\n value: unknown;\n}): ReactNode {\n return (\n <dl className={styles.spanDetailPanelAttribute}>\n <dt className={styles.spanDetailPanelAttributeKey}>{name}</dt>\n <dd\n className={styles.spanDetailPanelAttributeValue}\n title={String(value)}\n >\n {String(value)}\n </dd>\n </dl>\n );\n}\n\ninterface ResizeGestureRef {\n start: {\n x: number;\n width: number;\n };\n x: number;\n width: number;\n isHeld: boolean;\n}\n\n/**\n * Resizer component for the trace viewer panel.\n */\nexport function PanelResizer(): ReactNode {\n const {\n state: { panelWidth },\n dispatch,\n } = useTraceViewer();\n const gestureRef = useRef<ResizeGestureRef>({\n start: {\n x: 0,\n width: panelWidth,\n },\n x: 0,\n width: panelWidth,\n isHeld: false,\n });\n gestureRef.current.width = panelWidth;\n\n const onPointerDown = useCallback<PointerEventHandler>((event) => {\n if (event.pointerType !== 'mouse') return;\n event.preventDefault();\n const g = gestureRef.current;\n g.start.x = event.clientX;\n g.x = event.clientX;\n g.start.width = g.width;\n g.isHeld = true;\n }, []);\n\n const onDoubleClick = useCallback(() => {\n dispatch({\n type: 'setPanelWidth',\n width: initialState.panelWidth,\n });\n }, [dispatch]);\n\n useEffect(() => {\n let nextFrame = 0;\n const onFrame = (): void => {\n const g = gestureRef.current;\n const width = g.start.width + g.start.x - g.x;\n dispatch({\n type: 'setPanelWidth',\n width,\n });\n };\n\n const onPointerMove = (event: PointerEvent): void => {\n if (!gestureRef.current.isHeld) return;\n event.preventDefault();\n gestureRef.current.x = event.clientX;\n cancelAnimationFrame(nextFrame);\n nextFrame = requestAnimationFrame(onFrame);\n };\n const onPointerUp = (): void => {\n gestureRef.current.isHeld = false;\n };\n\n window.addEventListener('pointermove', onPointerMove);\n window.addEventListener('pointerup', onPointerUp);\n\n return () => {\n window.removeEventListener('pointermove', onPointerMove);\n window.removeEventListener('pointerup', onPointerUp);\n };\n }, [dispatch]);\n\n return (\n <div\n aria-hidden\n className={styles.spanDetailPanelResizer}\n onDoubleClick={onDoubleClick}\n onPointerDown={onPointerDown}\n />\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"span-segments.js","sourceRoot":"","sources":["../../../../src/components/trace-viewer/components/span-segments.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SpanNode, SpanNodeEvent } from '../types';\nimport type { ResourceType } from './span-strategies';\n\n// ──────────────────────────────────────────────────────────────────────────\n// Segment types\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Visual status of a segment within a span bar.\n *\n * - queued: Waiting to start (hatched pattern)\n * - running: Actively executing (solid blue)\n * - failed: Attempt that ended in failure (soft red)\n * - retrying: Waiting between retry attempts (hatched pattern)\n * - succeeded: Final successful attempt (soft green)\n * - waiting: Passive waiting, e.g. hook waiting for payload (hatched pattern)\n * - sleeping: Sleep in progress (soft amber)\n * - received: Hook received a payload (soft blue)\n */\nexport type SegmentStatus =\n | 'queued'\n | 'running'\n | 'failed'\n | 'retrying'\n | 'succeeded'\n | 'waiting'\n | 'sleeping'\n | 'received';\n\nexport interface Segment {\n /** Fraction of span width where this segment starts (0–1) */\n startFraction: number;\n /** Fraction of span width where this segment ends (0–1) */\n endFraction: number;\n /** Visual status controlling color/pattern */\n status: SegmentStatus;\n}\n\n/**\n * A boundary between two segments, representing an event that caused\n * a transition. Rendered as a hoverable divider with a tooltip.\n */\nexport interface SegmentBoundary {\n /** Fractional position along the span (0–1) */\n fraction: number;\n /** Display label for the tooltip (e.g. \"step_started\") */\n label: string;\n /** Formatted timestamp relative to span start */\n offsetMs: number;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// CSS class mapping (segment status → module CSS class name)\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Maps a SegmentStatus to the CSS module class name to use.\n * These class names must exist in trace-viewer.module.css.\n */\nexport const SEGMENT_CLASS_MAP: Record<SegmentStatus, string> = {\n queued: 'segQueued',\n running: 'segRunning',\n failed: 'segFailed',\n retrying: 'segRetrying',\n succeeded: 'segSucceeded',\n waiting: 'segWaiting',\n sleeping: 'segSleeping',\n received: 'segReceived',\n};\n\n// ──────────────────────────────────────────────────────────────────────────\n// Helpers\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction clampFraction(value: number): number {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction timeToFraction(\n time: number,\n spanStart: number,\n spanDuration: number\n): number {\n if (spanDuration <= 0) return 0;\n return clampFraction((time - spanStart) / spanDuration);\n}\n\n/**\n * Sort events by timestamp ascending.\n */\nfunction sortedEvents(events: SpanNodeEvent[]): SpanNodeEvent[] {\n return [...events].sort((a, b) => a.timestamp - b.timestamp);\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Step segments\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Compute segments for a step span.\n *\n * Timeline: [queued] → [attempt₁ (fail)] → [retry wait] → [attempt₂ (fail)] → ... → [attemptₙ (success)]\n *\n * Events used: step_started, step_retrying, step_failed, step_completed\n * The final segment is 'succeeded' if no trailing step_retrying/step_failed.\n */\nfunction computeStepSegments(node: SpanNode): Segment[] {\n const events = node.events ? sortedEvents(node.events) : [];\n const { startTime, duration } = node;\n const segments: Segment[] = [];\n\n if (duration <= 0) return segments;\n\n // Build a timeline of event boundaries\n interface EventMark {\n time: number;\n type: string;\n }\n const marks: EventMark[] = events\n .filter((e) =>\n [\n 'step_started',\n 'step_retrying',\n 'step_failed',\n 'step_completed',\n ].includes(e.event.name)\n )\n .map((e) => ({ time: e.timestamp, type: e.event.name }));\n\n if (marks.length === 0) {\n // No events — show entire span as running\n segments.push({ startFraction: 0, endFraction: 1, status: 'running' });\n return segments;\n }\n\n // Queued period: from span start to first event\n const firstMark = marks[0];\n const firstFraction = timeToFraction(firstMark.time, startTime, duration);\n if (firstFraction > 0.001) {\n segments.push({\n startFraction: 0,\n endFraction: firstFraction,\n status: 'queued',\n });\n }\n\n // Walk through events to build attempt/retry segments\n for (let i = 0; i < marks.length; i++) {\n const mark = marks[i];\n const markFraction = timeToFraction(mark.time, startTime, duration);\n const nextMark = marks[i + 1];\n const nextFraction = nextMark\n ? timeToFraction(nextMark.time, startTime, duration)\n : 1;\n\n if (mark.type === 'step_started') {\n // This is the start of an execution attempt.\n // It runs until the next event (step_retrying or step_failed) or end of span.\n const isLastMark = i === marks.length - 1;\n if (isLastMark) {\n // Last event is step_started — this attempt is either still running or succeeded\n segments.push({\n startFraction: markFraction,\n endFraction: 1,\n status: 'succeeded',\n });\n } else {\n // Attempt runs until the next event\n const nextType = nextMark.type;\n const attemptStatus: SegmentStatus =\n nextType === 'step_retrying' || nextType === 'step_failed'\n ? 'failed'\n : nextType === 'step_completed'\n ? 'succeeded'\n : 'running';\n segments.push({\n startFraction: markFraction,\n endFraction: nextFraction,\n status: attemptStatus,\n });\n }\n } else if (mark.type === 'step_retrying') {\n // Retry wait: from this event to the next step_started (or end)\n segments.push({\n startFraction: markFraction,\n endFraction: nextFraction,\n status: 'retrying',\n });\n } else if (mark.type === 'step_failed') {\n // Terminal failure: from this event to the end\n if (markFraction < 0.999) {\n segments.push({\n startFraction: markFraction,\n endFraction: 1,\n status: 'failed',\n });\n }\n } else if (mark.type === 'step_completed') {\n // Terminal success: do nothing here since the preceding step_started\n // segment already terminates at this marker.\n }\n }\n\n return segments;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Hook segments\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Compute segments for a hook span.\n *\n * Timeline: [waiting] → [received] → [disposed]\n */\nfunction computeHookSegments(node: SpanNode): Segment[] {\n const events = node.events ? sortedEvents(node.events) : [];\n const { startTime, duration } = node;\n const segments: Segment[] = [];\n\n if (duration <= 0) return segments;\n\n const receivedEvent = events.find((e) => e.event.name === 'hook_received');\n const disposedEvent = events.find((e) => e.event.name === 'hook_disposed');\n\n if (!receivedEvent && !disposedEvent) {\n // Still waiting\n segments.push({ startFraction: 0, endFraction: 1, status: 'waiting' });\n return segments;\n }\n\n const receivedFraction = receivedEvent\n ? timeToFraction(receivedEvent.timestamp, startTime, duration)\n : null;\n const disposedFraction = disposedEvent\n ? timeToFraction(disposedEvent.timestamp, startTime, duration)\n : null;\n\n // Waiting period (before received)\n if (receivedFraction !== null && receivedFraction > 0.001) {\n segments.push({\n startFraction: 0,\n endFraction: receivedFraction,\n status: 'waiting',\n });\n } else if (receivedFraction === null && disposedFraction !== null) {\n // Disposed without receiving — waiting the whole time\n segments.push({\n startFraction: 0,\n endFraction: disposedFraction,\n status: 'waiting',\n });\n }\n\n // Received period\n if (receivedFraction !== null) {\n const end = disposedFraction ?? 1;\n segments.push({\n startFraction: receivedFraction,\n endFraction: end,\n status: 'received',\n });\n }\n\n // Post-disposed (if there's remaining span after disposal)\n if (disposedFraction !== null && disposedFraction < 0.999) {\n segments.push({\n startFraction: disposedFraction,\n endFraction: 1,\n status: 'succeeded',\n });\n }\n\n return segments;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Sleep segments\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Compute segments for a sleep span.\n *\n * Timeline: [sleeping] → [completed]\n */\nfunction computeSleepSegments(node: SpanNode): Segment[] {\n const events = node.events ? sortedEvents(node.events) : [];\n const { startTime, duration } = node;\n const segments: Segment[] = [];\n\n if (duration <= 0) return segments;\n\n const completedEvent = events.find((e) => e.event.name === 'wait_completed');\n\n if (!completedEvent) {\n // Still sleeping\n segments.push({ startFraction: 0, endFraction: 1, status: 'sleeping' });\n return segments;\n }\n\n const completedFraction = timeToFraction(\n completedEvent.timestamp,\n startTime,\n duration\n );\n\n if (completedFraction > 0.001) {\n segments.push({\n startFraction: 0,\n endFraction: completedFraction,\n status: 'sleeping',\n });\n }\n\n segments.push({\n startFraction: completedFraction,\n endFraction: 1,\n status: 'succeeded',\n });\n\n return segments;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Run segments\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Compute segments for a run span.\n *\n * Timeline: [queued] → [running] → [completed/failed]\n *\n * The queued period is derived from activeStartTime (run.startedAt).\n * A synthetic run_started event is injected at that timestamp so\n * the boundary is hoverable in the trace viewer.\n */\nfunction computeRunSegments(node: SpanNode): Segment[] {\n const events = node.events ? sortedEvents(node.events) : [];\n const { startTime, duration, activeStartTime } = node;\n const segments: Segment[] = [];\n\n if (duration <= 0) return segments;\n\n // V1 runs (specVersion 1) don't emit run lifecycle events (run_created,\n // run_started, run_completed). Detect this by checking for the absence of\n // run_created — it's always the first event for v2 runs and is always\n // loaded in the first page, so its absence reliably signals a v1 run.\n // For v1, fall back to the run entity's status from span.attributes.data.\n const hasRunCreated = events.some((e) => e.event.name === 'run_created');\n\n if (!hasRunCreated) {\n const runData = node.span.attributes?.data as\n | Record<string, unknown>\n | undefined;\n const runStatus = runData?.status as string | undefined;\n return computeV1RunSegments(\n startTime,\n duration,\n activeStartTime,\n runStatus\n );\n }\n\n const failedEvent = events.find((e) => e.event.name === 'run_failed');\n const completedEvent = events.find((e) => e.event.name === 'run_completed');\n\n // Queued period (from span start to activeStartTime)\n let cursor = 0;\n if (activeStartTime && activeStartTime > startTime) {\n const queuedFraction = timeToFraction(activeStartTime, startTime, duration);\n if (queuedFraction > 0.001) {\n segments.push({\n startFraction: 0,\n endFraction: queuedFraction,\n status: 'queued',\n });\n cursor = queuedFraction;\n }\n }\n\n if (failedEvent) {\n const failedFraction = timeToFraction(\n failedEvent.timestamp,\n startTime,\n duration\n );\n // Running until failure\n if (failedFraction > cursor + 0.001) {\n segments.push({\n startFraction: cursor,\n endFraction: failedFraction,\n status: 'running',\n });\n }\n segments.push({\n startFraction: failedFraction,\n endFraction: 1,\n status: 'failed',\n });\n } else if (completedEvent) {\n const completedFraction = timeToFraction(\n completedEvent.timestamp,\n startTime,\n duration\n );\n if (completedFraction > cursor + 0.001) {\n segments.push({\n startFraction: cursor,\n endFraction: completedFraction,\n status: 'running',\n });\n }\n segments.push({\n startFraction: completedFraction,\n endFraction: 1,\n status: 'succeeded',\n });\n } else {\n // Running to completion (or terminal events haven't loaded yet)\n segments.push({\n startFraction: cursor,\n endFraction: 1,\n status: 'running',\n });\n }\n\n return segments;\n}\n\n/**\n * Compute segments for a v1 run using only the run entity's status and\n * activeStartTime (derived from run.startedAt). V1 runs have no run\n * lifecycle events, so we infer the visual segments from entity fields.\n */\nfunction computeV1RunSegments(\n startTime: number,\n duration: number,\n activeStartTime: number | undefined,\n runStatus: string | undefined\n): Segment[] {\n const segments: Segment[] = [];\n\n let cursor = 0;\n if (activeStartTime && activeStartTime > startTime) {\n const queuedFraction = timeToFraction(activeStartTime, startTime, duration);\n if (queuedFraction > 0.001) {\n segments.push({\n startFraction: 0,\n endFraction: queuedFraction,\n status: 'queued',\n });\n cursor = queuedFraction;\n }\n }\n\n if (runStatus === 'failed') {\n segments.push({\n startFraction: cursor,\n endFraction: 1,\n status: 'failed',\n });\n } else if (runStatus === 'completed' || runStatus === 'cancelled') {\n segments.push({\n startFraction: cursor,\n endFraction: 1,\n status: 'succeeded',\n });\n } else {\n segments.push({\n startFraction: cursor,\n endFraction: 1,\n status: 'running',\n });\n }\n\n return segments;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Dispatcher\n// ──────────────────────────────────────────────────────────────────────────\n\nexport interface SegmentResult {\n segments: Segment[];\n boundaries: SegmentBoundary[];\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Boundary computation\n// ──────────────────────────────────────────────────────────────────────────\n\n/** Event names to human-readable labels */\nconst EVENT_LABELS: Record<string, string> = {\n step_started: 'Started',\n step_retrying: 'Retrying',\n step_failed: 'Failed',\n hook_created: 'Created',\n hook_received: 'Received',\n hook_disposed: 'Resolved',\n wait_created: 'Sleep started',\n wait_completed: 'Sleep completed',\n run_completed: 'Completed',\n run_failed: 'Run failed',\n step_completed: 'Completed',\n};\n\n/**\n * Extract boundaries from a span's events. Each boundary sits at the\n * fractional position of a relevant event within the span duration.\n * Only includes events that are used as segment boundaries (not at the\n * very start or very end of the span, to avoid edge clutter).\n */\nfunction computeBoundaries(\n node: SpanNode,\n relevantEventNames: string[]\n): SegmentBoundary[] {\n const events = node.events ? sortedEvents(node.events) : [];\n const { startTime, duration } = node;\n\n if (duration <= 0) return [];\n\n const boundaries: SegmentBoundary[] = [];\n for (const e of events) {\n if (!relevantEventNames.includes(e.event.name)) continue;\n\n const fraction = timeToFraction(e.timestamp, startTime, duration);\n // Skip boundaries at the very edges (< 1% or > 99%) to avoid clutter\n if (fraction < 0.01 || fraction > 0.99) continue;\n\n boundaries.push({\n fraction,\n label: EVENT_LABELS[e.event.name] ?? e.event.name,\n offsetMs: e.timestamp - startTime,\n });\n }\n\n return boundaries;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Dispatcher\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Compute the event-based segments and boundaries for a span based on its resource type.\n * Returns empty arrays for 'default' (generic OTEL) spans.\n */\nexport function computeSegments(\n resourceType: ResourceType,\n node: SpanNode\n): SegmentResult {\n switch (resourceType) {\n case 'step':\n return {\n segments: computeStepSegments(node),\n boundaries: computeBoundaries(node, [\n 'step_started',\n 'step_retrying',\n 'step_failed',\n 'step_completed',\n ]),\n };\n case 'hook':\n return {\n segments: computeHookSegments(node),\n boundaries: computeBoundaries(node, [\n 'hook_created',\n 'hook_received',\n 'hook_disposed',\n ]),\n };\n case 'sleep':\n return {\n segments: computeSleepSegments(node),\n boundaries: computeBoundaries(node, ['wait_created', 'wait_completed']),\n };\n case 'run':\n return {\n segments: computeRunSegments(node),\n boundaries: computeBoundaries(node, ['run_completed', 'run_failed']),\n };\n default:\n return { segments: [], boundaries: [] };\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"span-strategies.js","sourceRoot":"","sources":["../../../../src/components/trace-viewer/components/span-strategies.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQ3E,oEAAoE;AACpE,MAAM,cAAc,GAAG,CAAC,CAAC;AA6BzB;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAiB;IAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC;IAChD,IACE,QAAQ,KAAK,KAAK;QAClB,QAAQ,KAAK,MAAM;QACnB,QAAQ,KAAK,MAAM;QACnB,QAAQ,KAAK,OAAO,EACpB,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,6EAA6E;AAC7E,iBAAiB;AACjB,6EAA6E;AAE7E,SAAS,cAAc,CAAC,WAAmB;IACzC,OAAO,WAAW,GAAG,EAAE,CAAC;AAC1B,CAAC;AAED,SAAS,aAAa,CAAC,WAAmB;IACxC,OAAO,WAAW,IAAI,GAAG,CAAC;AAC5B,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAiB,EAAE,MAAe;IAC1D,OAAO,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,aAAa,KAAK,KAAK,CAAC;AACnE,CAAC;AAED,SAAS,sBAAsB,CAC7B,IAAiB,EACjB,IAAc,EACd,iBAAwD,EACxD,SAAkB;IAElB,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAE7B,IAAI,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC;IACpC,IAAI,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC;IAClC,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC;IAC3C,IAAI,QAAQ,EAAE,CAAC;QACb,eAAe,GAAG,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC;QACxD,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC;IACpC,CAAC;IACD,OAAO,cAAc,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,eAAe,CAAC;AAClE,CAAC;AAED,6EAA6E;AAC7E,gFAAgF;AAChF,6EAA6E;AAE7E,SAAS,oBAAoB,CAC3B,IAAiB,EACjB,IAAc,EACd,KAAa,EACb,iBAAwD;IAExD,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC;IACvD,IAAI,GAAG,GAAG,aAAa,GAAG,CAAC,UAAU,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC;IAChE,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IACpD,IAAI,MAAM,GAAG,UAAU,CAAC;IAExB,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAEzD,IAAI,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,CAAC;QACd,GAAG,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC;IACrC,CAAC;IAED,MAAM,eAAe,GAAG,sBAAsB,CAC5C,IAAI,EACJ,IAAI,EACJ,iBAAiB,EACjB,UAAU,CACX,CAAC;IAEF,OAAO;QACL,KAAK;QACL,WAAW;QACX,MAAM;QACN,GAAG;QACH,IAAI;QACJ,OAAO;QACP,MAAM;QACN,SAAS;QACT,UAAU;QACV,eAAe;KAChB,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,4BAA4B;AAC5B,2EAA2E;AAC3E,6EAA6E;AAE7E,MAAM,UAAU,YAAY,CAC1B,IAAiB,EACjB,IAAc,EACd,KAAa,EACb,iBAAwD;IAExD,OAAO,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,IAAiB,EACjB,IAAc,EACd,KAAa,EACb,iBAAwD;IAExD,OAAO,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,IAAiB,EACjB,IAAc,EACd,KAAa,EACb,iBAAwD;IAExD,OAAO,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,IAAiB,EACjB,IAAc,EACd,KAAa,EACb,iBAAwD;IAExD,OAAO,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;AACpE,CAAC;AAED,6EAA6E;AAC7E,aAAa;AACb,6EAA6E;AAE7E;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,YAA0B,EAC1B,IAAiB,EACjB,IAAc,EACd,KAAa,EACb,iBAAwD;IAExD,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,KAAK;YACR,OAAO,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;QAC5D,KAAK,MAAM;YACT,OAAO,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;QAC7D,KAAK,MAAM;YACT,OAAO,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;QAC7D,KAAK,OAAO;YACV,OAAO,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;QAC9D;YACE,OAAO,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;IACtE,CAAC;AACH,CAAC","sourcesContent":["import type { RefObject } from 'react';\nimport type { RootNode, ScrollSnapshot, VisibleSpan } from '../types';\nimport { MARKER_HEIGHT, ROW_HEIGHT, ROW_PADDING } from '../util/constants';\n\n/**\n * The resource type of a workflow span, read from span.attributes.resource.\n * Falls back to 'default' for non-workflow (generic OTEL) spans.\n */\nexport type ResourceType = 'run' | 'step' | 'hook' | 'sleep' | 'default';\n\n/** Minimum rendered width so very short spans are always visible */\nconst MIN_SPAN_WIDTH = 4;\n\n/**\n * Layout result computed by a span strategy. Controls how the span\n * is sized and positioned in the timeline.\n */\nexport interface SpanLayout {\n /** The rendered width in pixels */\n width: number;\n /** The actual duration-based width (before min-width clamping) */\n actualWidth: number;\n /** The rendered height in pixels */\n height: number;\n /** The y position in pixels */\n top: number;\n /** The x position in pixels (from left) */\n left: number;\n /** Whether the span is considered \"small\" (< 64px actual width) */\n isSmall: boolean;\n /** Whether the span is considered \"huge\" (>= 500px actual width) */\n isHuge: boolean;\n /** Whether the span is currently hovered (with hover eligibility) */\n isHovered: boolean;\n /** Whether the span is expanded (hovered or selected) — controls sizing */\n isExpanded: boolean;\n /** Whether the span is near the right side of the visible area */\n isNearRightSide: boolean;\n}\n\n/**\n * Reads the resource type from a span's attributes.\n */\nexport function getResourceType(node: VisibleSpan): ResourceType {\n const resource = node.span.attributes?.resource;\n if (\n resource === 'run' ||\n resource === 'step' ||\n resource === 'hook' ||\n resource === 'sleep'\n ) {\n return resource;\n }\n return 'default';\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Shared helpers\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction computeIsSmall(actualWidth: number): boolean {\n return actualWidth < 64;\n}\n\nfunction computeIsHuge(actualWidth: number): boolean {\n return actualWidth >= 500;\n}\n\nfunction computeIsHovered(node: VisibleSpan, isHuge: boolean): boolean {\n return node.isHovered && !isHuge && node.isHighlighted !== false;\n}\n\nfunction computeIsNearRightSide(\n node: VisibleSpan,\n root: RootNode,\n scrollSnapshotRef: RefObject<ScrollSnapshot | undefined>,\n isHovered: boolean\n): boolean {\n if (!isHovered) return false;\n\n let visibleDuration = root.duration;\n let visibleEndTime = root.endTime;\n const snapshot = scrollSnapshotRef.current;\n if (snapshot) {\n visibleDuration = snapshot.endTime - snapshot.startTime;\n visibleEndTime = snapshot.endTime;\n }\n return visibleEndTime - node.startTime < 0.25 * visibleDuration;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Default layout (used by step, hook, run, default — all behave the same today)\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction computeDefaultLayout(\n node: VisibleSpan,\n root: RootNode,\n scale: number,\n scrollSnapshotRef: RefObject<ScrollSnapshot | undefined>\n): SpanLayout {\n const left = (node.startTime - root.startTime) * scale;\n let top = MARKER_HEIGHT + (ROW_HEIGHT + ROW_PADDING) * node.row;\n const actualWidth = node.duration * scale;\n const width = Math.max(actualWidth, MIN_SPAN_WIDTH);\n let height = ROW_HEIGHT;\n\n const isHuge = computeIsHuge(actualWidth);\n const isSmall = computeIsSmall(actualWidth);\n const isHovered = computeIsHovered(node, isHuge);\n const isExpanded = isHovered || Boolean(node.isSelected);\n\n if (isSmall && !isExpanded) {\n height *= 0.4;\n top += (ROW_HEIGHT - height) * 0.5;\n }\n\n const isNearRightSide = computeIsNearRightSide(\n node,\n root,\n scrollSnapshotRef,\n isExpanded\n );\n\n return {\n width,\n actualWidth,\n height,\n top,\n left,\n isSmall,\n isHuge,\n isHovered,\n isExpanded,\n isNearRightSide,\n };\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Per-type layout functions\n// Each returns the same result today but provides a clear extension point.\n// ──────────────────────────────────────────────────────────────────────────\n\nexport function getRunLayout(\n node: VisibleSpan,\n root: RootNode,\n scale: number,\n scrollSnapshotRef: RefObject<ScrollSnapshot | undefined>\n): SpanLayout {\n return computeDefaultLayout(node, root, scale, scrollSnapshotRef);\n}\n\nexport function getStepLayout(\n node: VisibleSpan,\n root: RootNode,\n scale: number,\n scrollSnapshotRef: RefObject<ScrollSnapshot | undefined>\n): SpanLayout {\n return computeDefaultLayout(node, root, scale, scrollSnapshotRef);\n}\n\nexport function getHookLayout(\n node: VisibleSpan,\n root: RootNode,\n scale: number,\n scrollSnapshotRef: RefObject<ScrollSnapshot | undefined>\n): SpanLayout {\n return computeDefaultLayout(node, root, scale, scrollSnapshotRef);\n}\n\nexport function getSleepLayout(\n node: VisibleSpan,\n root: RootNode,\n scale: number,\n scrollSnapshotRef: RefObject<ScrollSnapshot | undefined>\n): SpanLayout {\n return computeDefaultLayout(node, root, scale, scrollSnapshotRef);\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Dispatcher\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Computes the layout for a span based on its resource type.\n */\nexport function getSpanLayout(\n resourceType: ResourceType,\n node: VisibleSpan,\n root: RootNode,\n scale: number,\n scrollSnapshotRef: RefObject<ScrollSnapshot | undefined>\n): SpanLayout {\n switch (resourceType) {\n case 'run':\n return getRunLayout(node, root, scale, scrollSnapshotRef);\n case 'step':\n return getStepLayout(node, root, scale, scrollSnapshotRef);\n case 'hook':\n return getHookLayout(node, root, scale, scrollSnapshotRef);\n case 'sleep':\n return getSleepLayout(node, root, scale, scrollSnapshotRef);\n default:\n return computeDefaultLayout(node, root, scale, scrollSnapshotRef);\n }\n}\n"]}