@workflow/web-shared 5.0.0-beta.4 → 5.0.0-beta.40

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 (517) hide show
  1. package/README.md +5 -13
  2. package/dist/components/error-boundary.js +1 -1
  3. package/dist/components/event-list-view.d.ts +46 -1
  4. package/dist/components/event-list-view.d.ts.map +1 -1
  5. package/dist/components/event-list-view.js +235 -97
  6. package/dist/components/hook-actions.js +1 -1
  7. package/dist/components/index.d.ts +8 -5
  8. package/dist/components/index.d.ts.map +1 -1
  9. package/dist/components/index.js +6 -4
  10. package/dist/components/sidebar/attribute-panel.d.ts +4 -1
  11. package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
  12. package/dist/components/sidebar/attribute-panel.js +173 -119
  13. package/dist/components/sidebar/attributes-block.d.ts +40 -0
  14. package/dist/components/sidebar/attributes-block.d.ts.map +1 -0
  15. package/dist/components/sidebar/attributes-block.js +140 -0
  16. package/dist/components/sidebar/conversation-view.js +1 -1
  17. package/dist/components/sidebar/copyable-data-block.d.ts +2 -0
  18. package/dist/components/sidebar/copyable-data-block.d.ts.map +1 -1
  19. package/dist/components/sidebar/copyable-data-block.js +17 -16
  20. package/dist/components/sidebar/entity-detail-panel.d.ts +11 -11
  21. package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -1
  22. package/dist/components/sidebar/entity-detail-panel.js +37 -71
  23. package/dist/components/sidebar/events-list.d.ts +6 -2
  24. package/dist/components/sidebar/events-list.d.ts.map +1 -1
  25. package/dist/components/sidebar/events-list.js +77 -63
  26. package/dist/components/sidebar/resolve-hook-modal.js +1 -1
  27. package/dist/components/sidebar/sidebar-data-context.d.ts +10 -7
  28. package/dist/components/sidebar/sidebar-data-context.d.ts.map +1 -1
  29. package/dist/components/sidebar/sidebar-data-context.js +1 -1
  30. package/dist/components/sidebar/span-detail-merge.d.ts +31 -0
  31. package/dist/components/sidebar/span-detail-merge.d.ts.map +1 -0
  32. package/dist/components/sidebar/span-detail-merge.js +92 -0
  33. package/dist/components/sidebar/use-selected-span-detail.d.ts +16 -0
  34. package/dist/components/sidebar/use-selected-span-detail.d.ts.map +1 -0
  35. package/dist/components/sidebar/use-selected-span-detail.js +93 -0
  36. package/dist/components/stream-viewer-skeleton.d.ts +2 -0
  37. package/dist/components/stream-viewer-skeleton.d.ts.map +1 -0
  38. package/dist/components/stream-viewer-skeleton.js +12 -0
  39. package/dist/components/stream-viewer.d.ts +1 -1
  40. package/dist/components/stream-viewer.d.ts.map +1 -1
  41. package/dist/components/stream-viewer.js +9 -26
  42. package/dist/components/trace-viewer/components/copy-button.d.ts.map +1 -0
  43. package/dist/components/trace-viewer/components/copy-button.js +27 -0
  44. package/dist/components/trace-viewer/components/detail-panel-width.d.ts +34 -0
  45. package/dist/components/trace-viewer/components/detail-panel-width.d.ts.map +1 -0
  46. package/dist/components/trace-viewer/components/detail-panel-width.js +67 -0
  47. package/dist/components/trace-viewer/components/detail-panel.d.ts +14 -0
  48. package/dist/components/trace-viewer/components/detail-panel.d.ts.map +1 -0
  49. package/dist/components/trace-viewer/components/detail-panel.js +122 -0
  50. package/dist/components/trace-viewer/components/draggable-border.d.ts +31 -0
  51. package/dist/components/trace-viewer/components/draggable-border.d.ts.map +1 -0
  52. package/dist/components/trace-viewer/components/draggable-border.js +140 -0
  53. package/dist/components/trace-viewer/components/event-list.d.ts +10 -0
  54. package/dist/components/trace-viewer/components/event-list.d.ts.map +1 -0
  55. package/dist/components/trace-viewer/components/event-list.js +47 -0
  56. package/dist/components/trace-viewer/components/middle-truncate/copy-selection.d.ts.map +1 -0
  57. package/dist/components/trace-viewer/components/middle-truncate/copy-selection.js +54 -0
  58. package/dist/components/trace-viewer/components/middle-truncate/middle-truncate.d.ts.map +1 -0
  59. package/dist/components/trace-viewer/components/middle-truncate/middle-truncate.js +81 -0
  60. package/dist/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/truncate.d.ts +1 -1
  61. package/dist/components/trace-viewer/components/middle-truncate/truncate.d.ts.map +1 -0
  62. package/dist/components/trace-viewer/components/middle-truncate/truncate.js +101 -0
  63. package/dist/components/trace-viewer/components/middle-truncate/use-middle-truncate.d.ts.map +1 -0
  64. package/dist/components/trace-viewer/components/middle-truncate/use-middle-truncate.js +114 -0
  65. package/dist/components/trace-viewer/components/minimap.d.ts +14 -0
  66. package/dist/components/trace-viewer/components/minimap.d.ts.map +1 -0
  67. package/dist/components/trace-viewer/components/minimap.js +337 -0
  68. package/dist/components/trace-viewer/components/pane-constants.d.ts +14 -0
  69. package/dist/components/trace-viewer/components/pane-constants.d.ts.map +1 -0
  70. package/dist/components/trace-viewer/components/pane-constants.js +16 -0
  71. package/dist/components/trace-viewer/components/span-markers.d.ts +46 -0
  72. package/dist/components/trace-viewer/components/span-markers.d.ts.map +1 -0
  73. package/dist/components/trace-viewer/components/span-markers.js +85 -0
  74. package/dist/components/trace-viewer/components/split-pane.d.ts +10 -0
  75. package/dist/components/trace-viewer/components/split-pane.d.ts.map +1 -0
  76. package/dist/components/trace-viewer/components/split-pane.js +41 -0
  77. package/dist/components/trace-viewer/components/timeline.d.ts +42 -0
  78. package/dist/components/trace-viewer/components/timeline.d.ts.map +1 -0
  79. package/dist/components/trace-viewer/components/timeline.js +321 -0
  80. package/dist/components/trace-viewer/components/timeline.module.css +46 -0
  81. package/dist/components/trace-viewer/components/trace-shortcut-helper.d.ts +5 -0
  82. package/dist/components/trace-viewer/components/trace-shortcut-helper.d.ts.map +1 -0
  83. package/dist/components/trace-viewer/components/trace-shortcut-helper.js +55 -0
  84. package/dist/components/trace-viewer/components/trace-shortcut-helper.module.css +20 -0
  85. package/dist/components/trace-viewer/components/trace-viewer-skeleton.d.ts +2 -0
  86. package/dist/components/trace-viewer/components/trace-viewer-skeleton.d.ts.map +1 -0
  87. package/dist/components/trace-viewer/components/trace-viewer-skeleton.js +26 -0
  88. package/dist/components/trace-viewer/components/use-element-width.d.ts +8 -0
  89. package/dist/components/trace-viewer/components/use-element-width.d.ts.map +1 -0
  90. package/dist/components/trace-viewer/components/use-element-width.js +25 -0
  91. package/dist/components/trace-viewer/components/use-row-window.d.ts +34 -0
  92. package/dist/components/trace-viewer/components/use-row-window.d.ts.map +1 -0
  93. package/dist/components/trace-viewer/components/use-row-window.js +107 -0
  94. package/dist/components/trace-viewer/context.d.ts +14 -182
  95. package/dist/components/trace-viewer/context.d.ts.map +1 -1
  96. package/dist/components/trace-viewer/context.js +44 -351
  97. package/dist/components/trace-viewer/icons.d.ts.map +1 -0
  98. package/dist/components/trace-viewer/icons.js +15 -0
  99. package/dist/components/trace-viewer/search.d.ts +19 -0
  100. package/dist/components/trace-viewer/search.d.ts.map +1 -0
  101. package/dist/components/trace-viewer/search.js +134 -0
  102. package/dist/components/trace-viewer/trace-viewer.d.ts +7 -28
  103. package/dist/components/trace-viewer/trace-viewer.d.ts.map +1 -1
  104. package/dist/components/trace-viewer/trace-viewer.js +306 -356
  105. package/dist/components/trace-viewer/types.d.ts +2 -211
  106. package/dist/components/trace-viewer/types.d.ts.map +1 -1
  107. package/dist/components/trace-viewer/types.js +1 -1
  108. package/dist/components/trace-viewer/util/timing.d.ts +2 -2
  109. package/dist/components/trace-viewer/util/timing.d.ts.map +1 -1
  110. package/dist/components/trace-viewer/util/timing.js +3 -3
  111. package/dist/components/trace-viewer/utils.d.ts +111 -0
  112. package/dist/components/trace-viewer/utils.d.ts.map +1 -0
  113. package/dist/components/trace-viewer/utils.js +430 -0
  114. package/dist/components/{trace-viewer-new.d.ts → trace-viewer.d.ts} +7 -3
  115. package/dist/components/trace-viewer.d.ts.map +1 -0
  116. package/dist/components/trace-viewer.js +21 -0
  117. package/dist/components/ui/alert.js +3 -3
  118. package/dist/components/ui/button.d.ts +10 -0
  119. package/dist/components/ui/button.d.ts.map +1 -0
  120. package/dist/components/ui/button.js +46 -0
  121. package/dist/components/ui/card.d.ts.map +1 -1
  122. package/dist/components/ui/card.js +4 -4
  123. package/dist/components/ui/collapsible.d.ts +46 -0
  124. package/dist/components/ui/collapsible.d.ts.map +1 -0
  125. package/dist/components/ui/collapsible.js +66 -0
  126. package/dist/components/ui/context-card.d.ts +47 -0
  127. package/dist/components/ui/context-card.d.ts.map +1 -0
  128. package/dist/components/ui/context-card.js +471 -0
  129. package/dist/components/ui/data-inspector.d.ts +7 -6
  130. package/dist/components/ui/data-inspector.d.ts.map +1 -1
  131. package/dist/components/ui/data-inspector.js +232 -99
  132. package/dist/components/ui/data-inspector.styles.d.ts +29 -0
  133. package/dist/components/ui/data-inspector.styles.d.ts.map +1 -0
  134. package/dist/components/ui/data-inspector.styles.js +95 -0
  135. package/dist/components/ui/decrypt-button.js +1 -1
  136. package/dist/components/ui/error-card.js +3 -3
  137. package/dist/components/ui/error-stack-block.d.ts +17 -10
  138. package/dist/components/ui/error-stack-block.d.ts.map +1 -1
  139. package/dist/components/ui/error-stack-block.js +49 -30
  140. package/dist/components/ui/icon-button.d.ts +19 -0
  141. package/dist/components/ui/icon-button.d.ts.map +1 -0
  142. package/dist/components/ui/icon-button.js +29 -0
  143. package/dist/components/ui/kbd.d.ts +10 -0
  144. package/dist/components/ui/kbd.d.ts.map +1 -0
  145. package/dist/components/ui/kbd.js +25 -0
  146. package/dist/components/ui/load-more-button.js +1 -1
  147. package/dist/components/ui/menu-dropdown.js +1 -1
  148. package/dist/components/ui/skeleton.js +2 -2
  149. package/dist/components/ui/spinner.js +1 -1
  150. package/dist/components/ui/timestamp-tooltip.d.ts +34 -1
  151. package/dist/components/ui/timestamp-tooltip.d.ts.map +1 -1
  152. package/dist/components/ui/timestamp-tooltip.js +80 -132
  153. package/dist/components/ui/tooltip.d.ts +10 -0
  154. package/dist/components/ui/tooltip.d.ts.map +1 -0
  155. package/dist/components/ui/tooltip.js +12 -0
  156. package/dist/components/workflow-traces/event-colors.d.ts +2 -1
  157. package/dist/components/workflow-traces/event-colors.d.ts.map +1 -1
  158. package/dist/components/workflow-traces/event-colors.js +15 -7
  159. package/dist/components/workflow-traces/trace-span-construction.d.ts +6 -3
  160. package/dist/components/workflow-traces/trace-span-construction.d.ts.map +1 -1
  161. package/dist/components/workflow-traces/trace-span-construction.js +71 -30
  162. package/dist/components/workflow-traces/trace-time-utils.js +1 -1
  163. package/dist/hooks/use-dark-mode.js +1 -1
  164. package/dist/hooks/use-intersection-observer.d.ts +17 -0
  165. package/dist/hooks/use-intersection-observer.d.ts.map +1 -0
  166. package/dist/hooks/use-intersection-observer.js +29 -0
  167. package/dist/hooks/use-load-more-on-scroll.d.ts +21 -0
  168. package/dist/hooks/use-load-more-on-scroll.d.ts.map +1 -0
  169. package/dist/hooks/use-load-more-on-scroll.js +28 -0
  170. package/dist/hooks/use-reduced-motion.d.ts +10 -0
  171. package/dist/hooks/use-reduced-motion.d.ts.map +1 -0
  172. package/dist/hooks/use-reduced-motion.js +29 -0
  173. package/dist/index.d.ts +4 -3
  174. package/dist/index.d.ts.map +1 -1
  175. package/dist/index.js +4 -3
  176. package/dist/lib/cn.d.ts +10 -0
  177. package/dist/lib/cn.d.ts.map +1 -0
  178. package/dist/lib/cn.js +83 -0
  179. package/dist/lib/event-analysis.d.ts +1 -1
  180. package/dist/lib/event-analysis.d.ts.map +1 -1
  181. package/dist/lib/event-analysis.js +3 -2
  182. package/dist/lib/event-materialization.d.ts +1 -1
  183. package/dist/lib/event-materialization.d.ts.map +1 -1
  184. package/dist/lib/event-materialization.js +29 -21
  185. package/dist/lib/exact-event-search-id.d.ts +25 -0
  186. package/dist/lib/exact-event-search-id.d.ts.map +1 -0
  187. package/dist/lib/exact-event-search-id.js +39 -0
  188. package/dist/lib/hydration.d.ts +17 -2
  189. package/dist/lib/hydration.d.ts.map +1 -1
  190. package/dist/lib/hydration.js +194 -23
  191. package/dist/lib/stream-display.js +1 -1
  192. package/dist/lib/toast.js +1 -1
  193. package/dist/lib/trace-builder.d.ts +17 -5
  194. package/dist/lib/trace-builder.d.ts.map +1 -1
  195. package/dist/lib/trace-builder.js +32 -14
  196. package/dist/lib/trace-types.d.ts +54 -0
  197. package/dist/lib/trace-types.d.ts.map +1 -0
  198. package/dist/lib/trace-types.js +2 -0
  199. package/dist/lib/utils.d.ts +14 -2
  200. package/dist/lib/utils.d.ts.map +1 -1
  201. package/dist/lib/utils.js +46 -6
  202. package/dist/lib/zstd-browser-decoder.d.ts +7 -0
  203. package/dist/lib/zstd-browser-decoder.d.ts.map +1 -0
  204. package/dist/lib/zstd-browser-decoder.js +41 -0
  205. package/dist/styles.css +210 -139
  206. package/package.json +11 -8
  207. package/src/components/event-list-view.tsx +385 -123
  208. package/src/components/index.ts +14 -8
  209. package/src/components/sidebar/attribute-panel.tsx +331 -282
  210. package/src/components/sidebar/attributes-block.tsx +326 -0
  211. package/src/components/sidebar/copyable-data-block.tsx +50 -28
  212. package/src/components/sidebar/entity-detail-panel.tsx +92 -126
  213. package/src/components/sidebar/events-list.tsx +197 -179
  214. package/src/components/sidebar/sidebar-data-context.tsx +11 -11
  215. package/src/components/sidebar/span-detail-merge.ts +134 -0
  216. package/src/components/sidebar/use-selected-span-detail.ts +146 -0
  217. package/src/components/stream-viewer-skeleton.tsx +34 -0
  218. package/src/components/stream-viewer.tsx +34 -106
  219. package/src/components/{new-trace-viewer → trace-viewer}/components/copy-button.tsx +2 -2
  220. package/src/components/trace-viewer/components/detail-panel-width.test.ts +123 -0
  221. package/src/components/trace-viewer/components/detail-panel-width.ts +76 -0
  222. package/src/components/trace-viewer/components/detail-panel.tsx +273 -0
  223. package/src/components/trace-viewer/components/draggable-border.tsx +216 -0
  224. package/src/components/trace-viewer/components/event-list.tsx +144 -0
  225. package/src/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/middle-truncate.tsx +8 -8
  226. package/src/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/truncate.ts +1 -1
  227. package/src/components/trace-viewer/components/minimap.tsx +556 -0
  228. package/src/components/trace-viewer/components/pane-constants.ts +19 -0
  229. package/src/components/trace-viewer/components/span-markers.tsx +173 -0
  230. package/src/components/trace-viewer/components/split-pane.tsx +141 -0
  231. package/src/components/trace-viewer/components/timeline.module.css +46 -0
  232. package/src/components/trace-viewer/components/timeline.tsx +850 -0
  233. package/src/components/trace-viewer/components/trace-shortcut-helper.module.css +20 -0
  234. package/src/components/trace-viewer/components/trace-shortcut-helper.tsx +116 -0
  235. package/src/components/trace-viewer/components/trace-viewer-skeleton.tsx +114 -0
  236. package/src/components/trace-viewer/components/use-element-width.ts +29 -0
  237. package/src/components/trace-viewer/components/use-row-window.ts +140 -0
  238. package/src/components/trace-viewer/context.tsx +63 -656
  239. package/src/components/{new-trace-viewer → trace-viewer}/icons.tsx +2 -2
  240. package/src/components/trace-viewer/search.ts +178 -0
  241. package/src/components/trace-viewer/trace-viewer.tsx +563 -531
  242. package/src/components/trace-viewer/types.ts +2 -234
  243. package/src/components/trace-viewer/util/timing.ts +2 -2
  244. package/src/components/trace-viewer/utils.test.ts +458 -0
  245. package/src/components/{new-trace-viewer → trace-viewer}/utils.ts +271 -50
  246. package/src/components/{trace-viewer-new.tsx → trace-viewer.tsx} +24 -18
  247. package/src/components/ui/alert.tsx +2 -2
  248. package/src/components/ui/button.tsx +68 -0
  249. package/src/components/ui/card.tsx +3 -10
  250. package/src/components/ui/collapsible.tsx +219 -0
  251. package/src/components/ui/context-card.tsx +784 -0
  252. package/src/components/ui/data-inspector.styles.ts +96 -0
  253. package/src/components/ui/data-inspector.tsx +501 -204
  254. package/src/components/ui/error-card.tsx +4 -4
  255. package/src/components/ui/error-stack-block.tsx +84 -55
  256. package/src/components/ui/icon-button.tsx +53 -0
  257. package/src/components/ui/kbd.tsx +43 -0
  258. package/src/components/ui/skeleton.tsx +1 -1
  259. package/src/components/ui/timestamp-tooltip.tsx +132 -194
  260. package/src/components/ui/tooltip.tsx +47 -0
  261. package/src/components/workflow-traces/event-colors.ts +15 -11
  262. package/src/components/workflow-traces/trace-span-construction.test.ts +85 -0
  263. package/src/components/workflow-traces/trace-span-construction.ts +97 -32
  264. package/src/hooks/use-intersection-observer.ts +57 -0
  265. package/src/hooks/use-load-more-on-scroll.ts +49 -0
  266. package/src/hooks/use-reduced-motion.ts +34 -0
  267. package/src/index.ts +10 -4
  268. package/src/lib/cn.ts +93 -0
  269. package/src/lib/event-analysis.ts +6 -4
  270. package/src/lib/event-materialization.ts +35 -21
  271. package/src/lib/exact-event-search-id.ts +67 -0
  272. package/src/lib/hydration.ts +210 -30
  273. package/src/lib/trace-builder.ts +43 -19
  274. package/src/lib/trace-types.ts +56 -0
  275. package/src/lib/utils.test.ts +33 -0
  276. package/src/lib/utils.ts +53 -6
  277. package/src/lib/zstd-browser-decoder.ts +42 -0
  278. package/src/styles.css +210 -139
  279. package/dist/components/error-boundary.js.map +0 -1
  280. package/dist/components/event-list-view.js.map +0 -1
  281. package/dist/components/hook-actions.js.map +0 -1
  282. package/dist/components/index.js.map +0 -1
  283. package/dist/components/new-trace-viewer/components/copy-button.d.ts.map +0 -1
  284. package/dist/components/new-trace-viewer/components/copy-button.js +0 -27
  285. package/dist/components/new-trace-viewer/components/copy-button.js.map +0 -1
  286. package/dist/components/new-trace-viewer/components/event-list.d.ts +0 -8
  287. package/dist/components/new-trace-viewer/components/event-list.d.ts.map +0 -1
  288. package/dist/components/new-trace-viewer/components/event-list.js +0 -38
  289. package/dist/components/new-trace-viewer/components/event-list.js.map +0 -1
  290. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.d.ts.map +0 -1
  291. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js +0 -54
  292. package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js.map +0 -1
  293. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.d.ts.map +0 -1
  294. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js +0 -81
  295. package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js.map +0 -1
  296. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts.map +0 -1
  297. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js +0 -101
  298. package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js.map +0 -1
  299. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.d.ts.map +0 -1
  300. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js +0 -114
  301. package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js.map +0 -1
  302. package/dist/components/new-trace-viewer/components/split-pane.d.ts +0 -14
  303. package/dist/components/new-trace-viewer/components/split-pane.d.ts.map +0 -1
  304. package/dist/components/new-trace-viewer/components/split-pane.js +0 -99
  305. package/dist/components/new-trace-viewer/components/split-pane.js.map +0 -1
  306. package/dist/components/new-trace-viewer/components/timeline.d.ts +0 -31
  307. package/dist/components/new-trace-viewer/components/timeline.d.ts.map +0 -1
  308. package/dist/components/new-trace-viewer/components/timeline.js +0 -138
  309. package/dist/components/new-trace-viewer/components/timeline.js.map +0 -1
  310. package/dist/components/new-trace-viewer/context.d.ts +0 -15
  311. package/dist/components/new-trace-viewer/context.d.ts.map +0 -1
  312. package/dist/components/new-trace-viewer/context.js +0 -47
  313. package/dist/components/new-trace-viewer/context.js.map +0 -1
  314. package/dist/components/new-trace-viewer/detail-panel.d.ts +0 -10
  315. package/dist/components/new-trace-viewer/detail-panel.d.ts.map +0 -1
  316. package/dist/components/new-trace-viewer/detail-panel.js +0 -12
  317. package/dist/components/new-trace-viewer/detail-panel.js.map +0 -1
  318. package/dist/components/new-trace-viewer/icons.d.ts.map +0 -1
  319. package/dist/components/new-trace-viewer/icons.js +0 -15
  320. package/dist/components/new-trace-viewer/icons.js.map +0 -1
  321. package/dist/components/new-trace-viewer/trace-viewer.d.ts +0 -8
  322. package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +0 -1
  323. package/dist/components/new-trace-viewer/trace-viewer.js +0 -349
  324. package/dist/components/new-trace-viewer/trace-viewer.js.map +0 -1
  325. package/dist/components/new-trace-viewer/types.d.ts +0 -1
  326. package/dist/components/new-trace-viewer/types.d.ts.map +0 -1
  327. package/dist/components/new-trace-viewer/types.js +0 -2
  328. package/dist/components/new-trace-viewer/types.js.map +0 -1
  329. package/dist/components/new-trace-viewer/util/constants.d.ts +0 -1
  330. package/dist/components/new-trace-viewer/util/constants.d.ts.map +0 -1
  331. package/dist/components/new-trace-viewer/util/constants.js +0 -2
  332. package/dist/components/new-trace-viewer/util/constants.js.map +0 -1
  333. package/dist/components/new-trace-viewer/utils.d.ts +0 -42
  334. package/dist/components/new-trace-viewer/utils.d.ts.map +0 -1
  335. package/dist/components/new-trace-viewer/utils.js +0 -305
  336. package/dist/components/new-trace-viewer/utils.js.map +0 -1
  337. package/dist/components/run-trace-view.d.ts +0 -25
  338. package/dist/components/run-trace-view.d.ts.map +0 -1
  339. package/dist/components/run-trace-view.js +0 -11
  340. package/dist/components/run-trace-view.js.map +0 -1
  341. package/dist/components/sidebar/attribute-panel.js.map +0 -1
  342. package/dist/components/sidebar/conversation-view.js.map +0 -1
  343. package/dist/components/sidebar/copyable-data-block.js.map +0 -1
  344. package/dist/components/sidebar/detail-card.d.ts +0 -14
  345. package/dist/components/sidebar/detail-card.d.ts.map +0 -1
  346. package/dist/components/sidebar/detail-card.js +0 -20
  347. package/dist/components/sidebar/detail-card.js.map +0 -1
  348. package/dist/components/sidebar/entity-detail-panel.js.map +0 -1
  349. package/dist/components/sidebar/events-list.js.map +0 -1
  350. package/dist/components/sidebar/resolve-hook-modal.js.map +0 -1
  351. package/dist/components/sidebar/sidebar-data-context.js.map +0 -1
  352. package/dist/components/stream-viewer.js.map +0 -1
  353. package/dist/components/trace-viewer/components/map.d.ts +0 -8
  354. package/dist/components/trace-viewer/components/map.d.ts.map +0 -1
  355. package/dist/components/trace-viewer/components/map.js +0 -162
  356. package/dist/components/trace-viewer/components/map.js.map +0 -1
  357. package/dist/components/trace-viewer/components/markers.d.ts +0 -23
  358. package/dist/components/trace-viewer/components/markers.d.ts.map +0 -1
  359. package/dist/components/trace-viewer/components/markers.js +0 -416
  360. package/dist/components/trace-viewer/components/markers.js.map +0 -1
  361. package/dist/components/trace-viewer/components/node.d.ts +0 -35
  362. package/dist/components/trace-viewer/components/node.d.ts.map +0 -1
  363. package/dist/components/trace-viewer/components/node.js +0 -285
  364. package/dist/components/trace-viewer/components/node.js.map +0 -1
  365. package/dist/components/trace-viewer/components/search-input.d.ts +0 -9
  366. package/dist/components/trace-viewer/components/search-input.d.ts.map +0 -1
  367. package/dist/components/trace-viewer/components/search-input.js +0 -9
  368. package/dist/components/trace-viewer/components/search-input.js.map +0 -1
  369. package/dist/components/trace-viewer/components/search.d.ts +0 -3
  370. package/dist/components/trace-viewer/components/search.d.ts.map +0 -1
  371. package/dist/components/trace-viewer/components/search.js +0 -25
  372. package/dist/components/trace-viewer/components/search.js.map +0 -1
  373. package/dist/components/trace-viewer/components/span-content.d.ts +0 -19
  374. package/dist/components/trace-viewer/components/span-content.d.ts.map +0 -1
  375. package/dist/components/trace-viewer/components/span-content.js +0 -137
  376. package/dist/components/trace-viewer/components/span-content.js.map +0 -1
  377. package/dist/components/trace-viewer/components/span-detail-panel.d.ts +0 -10
  378. package/dist/components/trace-viewer/components/span-detail-panel.d.ts.map +0 -1
  379. package/dist/components/trace-viewer/components/span-detail-panel.js +0 -285
  380. package/dist/components/trace-viewer/components/span-detail-panel.js.map +0 -1
  381. package/dist/components/trace-viewer/components/span-segments.d.ts +0 -50
  382. package/dist/components/trace-viewer/components/span-segments.d.ts.map +0 -1
  383. package/dist/components/trace-viewer/components/span-segments.js +0 -445
  384. package/dist/components/trace-viewer/components/span-segments.js.map +0 -1
  385. package/dist/components/trace-viewer/components/span-strategies.d.ts +0 -46
  386. package/dist/components/trace-viewer/components/span-strategies.d.ts.map +0 -1
  387. package/dist/components/trace-viewer/components/span-strategies.js +0 -108
  388. package/dist/components/trace-viewer/components/span-strategies.js.map +0 -1
  389. package/dist/components/trace-viewer/components/ui.d.ts +0 -28
  390. package/dist/components/trace-viewer/components/ui.d.ts.map +0 -1
  391. package/dist/components/trace-viewer/components/ui.js +0 -39
  392. package/dist/components/trace-viewer/components/ui.js.map +0 -1
  393. package/dist/components/trace-viewer/components/zoom-button.d.ts +0 -3
  394. package/dist/components/trace-viewer/components/zoom-button.d.ts.map +0 -1
  395. package/dist/components/trace-viewer/components/zoom-button.js +0 -29
  396. package/dist/components/trace-viewer/components/zoom-button.js.map +0 -1
  397. package/dist/components/trace-viewer/components/zoom-icons.d.ts +0 -11
  398. package/dist/components/trace-viewer/components/zoom-icons.d.ts.map +0 -1
  399. package/dist/components/trace-viewer/components/zoom-icons.js +0 -11
  400. package/dist/components/trace-viewer/components/zoom-icons.js.map +0 -1
  401. package/dist/components/trace-viewer/context.js.map +0 -1
  402. package/dist/components/trace-viewer/index.d.ts +0 -5
  403. package/dist/components/trace-viewer/index.d.ts.map +0 -1
  404. package/dist/components/trace-viewer/index.js +0 -4
  405. package/dist/components/trace-viewer/index.js.map +0 -1
  406. package/dist/components/trace-viewer/trace-viewer.js.map +0 -1
  407. package/dist/components/trace-viewer/trace-viewer.module.css +0 -1465
  408. package/dist/components/trace-viewer/types.js.map +0 -1
  409. package/dist/components/trace-viewer/util/constants.d.ts +0 -9
  410. package/dist/components/trace-viewer/util/constants.d.ts.map +0 -1
  411. package/dist/components/trace-viewer/util/constants.js +0 -9
  412. package/dist/components/trace-viewer/util/constants.js.map +0 -1
  413. package/dist/components/trace-viewer/util/scrollbar-width.d.ts +0 -2
  414. package/dist/components/trace-viewer/util/scrollbar-width.d.ts.map +0 -1
  415. package/dist/components/trace-viewer/util/scrollbar-width.js +0 -14
  416. package/dist/components/trace-viewer/util/scrollbar-width.js.map +0 -1
  417. package/dist/components/trace-viewer/util/timing.js.map +0 -1
  418. package/dist/components/trace-viewer/util/tree.d.ts +0 -13
  419. package/dist/components/trace-viewer/util/tree.d.ts.map +0 -1
  420. package/dist/components/trace-viewer/util/tree.js +0 -227
  421. package/dist/components/trace-viewer/util/tree.js.map +0 -1
  422. package/dist/components/trace-viewer/util/use-immediate-style.d.ts +0 -15
  423. package/dist/components/trace-viewer/util/use-immediate-style.d.ts.map +0 -1
  424. package/dist/components/trace-viewer/util/use-immediate-style.js +0 -23
  425. package/dist/components/trace-viewer/util/use-immediate-style.js.map +0 -1
  426. package/dist/components/trace-viewer/util/use-streaming-spans.d.ts +0 -8
  427. package/dist/components/trace-viewer/util/use-streaming-spans.d.ts.map +0 -1
  428. package/dist/components/trace-viewer/util/use-streaming-spans.js +0 -345
  429. package/dist/components/trace-viewer/util/use-streaming-spans.js.map +0 -1
  430. package/dist/components/trace-viewer/util/use-trackpad-zoom.d.ts +0 -6
  431. package/dist/components/trace-viewer/util/use-trackpad-zoom.d.ts.map +0 -1
  432. package/dist/components/trace-viewer/util/use-trackpad-zoom.js +0 -39
  433. package/dist/components/trace-viewer/util/use-trackpad-zoom.js.map +0 -1
  434. package/dist/components/trace-viewer/worker.d.ts +0 -2
  435. package/dist/components/trace-viewer/worker.d.ts.map +0 -1
  436. package/dist/components/trace-viewer/worker.js +0 -109
  437. package/dist/components/trace-viewer/worker.js.map +0 -1
  438. package/dist/components/trace-viewer-new.d.ts.map +0 -1
  439. package/dist/components/trace-viewer-new.js +0 -23
  440. package/dist/components/trace-viewer-new.js.map +0 -1
  441. package/dist/components/ui/alert.js.map +0 -1
  442. package/dist/components/ui/card.js.map +0 -1
  443. package/dist/components/ui/data-inspector.js.map +0 -1
  444. package/dist/components/ui/decrypt-button.js.map +0 -1
  445. package/dist/components/ui/error-card.js.map +0 -1
  446. package/dist/components/ui/error-stack-block.js.map +0 -1
  447. package/dist/components/ui/inspector-theme.d.ts +0 -95
  448. package/dist/components/ui/inspector-theme.d.ts.map +0 -1
  449. package/dist/components/ui/inspector-theme.js +0 -82
  450. package/dist/components/ui/inspector-theme.js.map +0 -1
  451. package/dist/components/ui/load-more-button.js.map +0 -1
  452. package/dist/components/ui/menu-dropdown.js.map +0 -1
  453. package/dist/components/ui/skeleton.js.map +0 -1
  454. package/dist/components/ui/spinner.js.map +0 -1
  455. package/dist/components/ui/timestamp-tooltip.js.map +0 -1
  456. package/dist/components/workflow-trace-view.d.ts +0 -40
  457. package/dist/components/workflow-trace-view.d.ts.map +0 -1
  458. package/dist/components/workflow-trace-view.js +0 -695
  459. package/dist/components/workflow-trace-view.js.map +0 -1
  460. package/dist/components/workflow-traces/event-colors.js.map +0 -1
  461. package/dist/components/workflow-traces/trace-colors.d.ts +0 -15
  462. package/dist/components/workflow-traces/trace-colors.d.ts.map +0 -1
  463. package/dist/components/workflow-traces/trace-colors.js +0 -87
  464. package/dist/components/workflow-traces/trace-colors.js.map +0 -1
  465. package/dist/components/workflow-traces/trace-span-construction.js.map +0 -1
  466. package/dist/components/workflow-traces/trace-time-utils.js.map +0 -1
  467. package/dist/hooks/use-dark-mode.js.map +0 -1
  468. package/dist/index.js.map +0 -1
  469. package/dist/lib/event-analysis.js.map +0 -1
  470. package/dist/lib/event-materialization.js.map +0 -1
  471. package/dist/lib/hydration.js.map +0 -1
  472. package/dist/lib/stream-display.js.map +0 -1
  473. package/dist/lib/toast.js.map +0 -1
  474. package/dist/lib/trace-builder.js.map +0 -1
  475. package/dist/lib/utils.js.map +0 -1
  476. package/src/components/new-trace-viewer/components/event-list.tsx +0 -116
  477. package/src/components/new-trace-viewer/components/split-pane.tsx +0 -185
  478. package/src/components/new-trace-viewer/components/timeline.tsx +0 -382
  479. package/src/components/new-trace-viewer/context.tsx +0 -92
  480. package/src/components/new-trace-viewer/detail-panel.tsx +0 -58
  481. package/src/components/new-trace-viewer/trace-viewer.tsx +0 -645
  482. package/src/components/new-trace-viewer/types.ts +0 -0
  483. package/src/components/new-trace-viewer/util/constants.ts +0 -0
  484. package/src/components/run-trace-view.tsx +0 -84
  485. package/src/components/sidebar/detail-card.tsx +0 -65
  486. package/src/components/trace-viewer/components/map.tsx +0 -226
  487. package/src/components/trace-viewer/components/markers.tsx +0 -612
  488. package/src/components/trace-viewer/components/node.tsx +0 -505
  489. package/src/components/trace-viewer/components/search-input.tsx +0 -52
  490. package/src/components/trace-viewer/components/search.tsx +0 -47
  491. package/src/components/trace-viewer/components/span-content.tsx +0 -247
  492. package/src/components/trace-viewer/components/span-detail-panel.tsx +0 -655
  493. package/src/components/trace-viewer/components/span-segments.ts +0 -585
  494. package/src/components/trace-viewer/components/span-strategies.ts +0 -205
  495. package/src/components/trace-viewer/components/ui.tsx +0 -156
  496. package/src/components/trace-viewer/components/zoom-button.tsx +0 -61
  497. package/src/components/trace-viewer/components/zoom-icons.tsx +0 -65
  498. package/src/components/trace-viewer/index.tsx +0 -4
  499. package/src/components/trace-viewer/trace-viewer.module.css +0 -1465
  500. package/src/components/trace-viewer/util/constants.ts +0 -8
  501. package/src/components/trace-viewer/util/scrollbar-width.ts +0 -13
  502. package/src/components/trace-viewer/util/tree.ts +0 -277
  503. package/src/components/trace-viewer/util/use-immediate-style.ts +0 -38
  504. package/src/components/trace-viewer/util/use-streaming-spans.ts +0 -426
  505. package/src/components/trace-viewer/util/use-trackpad-zoom.tsx +0 -51
  506. package/src/components/trace-viewer/worker.ts +0 -131
  507. package/src/components/ui/inspector-theme.ts +0 -110
  508. package/src/components/workflow-trace-view.tsx +0 -1171
  509. package/src/components/workflow-traces/trace-colors.ts +0 -112
  510. /package/dist/components/{new-trace-viewer → trace-viewer}/components/copy-button.d.ts +0 -0
  511. /package/dist/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/copy-selection.d.ts +0 -0
  512. /package/dist/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/middle-truncate.d.ts +0 -0
  513. /package/dist/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/use-middle-truncate.d.ts +0 -0
  514. /package/dist/components/{new-trace-viewer → trace-viewer}/icons.d.ts +0 -0
  515. /package/src/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/copy-selection.ts +0 -0
  516. /package/src/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/use-middle-truncate.ts +0 -0
  517. /package/src/{components/trace-viewer/modules.d.ts → modules.d.ts} +0 -0
@@ -0,0 +1,134 @@
1
+ const hasField = (
2
+ value: object,
3
+ key: string
4
+ ): value is Record<string, unknown> => key in value;
5
+
6
+ const RESOURCES_WITH_FETCHED_DETAIL = new Set(['run', 'step', 'sleep']);
7
+
8
+ export function resourceNeedsFetchedDetail(
9
+ resource: string | undefined
10
+ ): boolean {
11
+ return resource !== undefined && RESOURCES_WITH_FETCHED_DETAIL.has(resource);
12
+ }
13
+
14
+ export type SpanDetailStatus = 'idle' | 'loading' | 'ready' | 'error';
15
+
16
+ export interface SpanDetailView {
17
+ status: SpanDetailStatus;
18
+ displayData: Record<string, unknown>;
19
+ detail: unknown;
20
+ error: Error | undefined;
21
+ }
22
+
23
+ export function deriveSpanDetailView(args: {
24
+ resource: string | undefined;
25
+ resourceId: string | undefined;
26
+ inlineData: unknown;
27
+ fetchedDetail: unknown;
28
+ fetchedError: Error | null;
29
+ }): SpanDetailView {
30
+ const { resource, resourceId, inlineData, fetchedDetail, fetchedError } =
31
+ args;
32
+
33
+ const matchedDetail = spanDetailMatchesSelection(
34
+ fetchedDetail,
35
+ resource,
36
+ resourceId
37
+ )
38
+ ? fetchedDetail
39
+ : null;
40
+ const displayData = mergeSpanDetail(inlineData, matchedDetail) as Record<
41
+ string,
42
+ unknown
43
+ >;
44
+
45
+ if (!resource || !resourceId) {
46
+ return { status: 'idle', displayData, detail: null, error: undefined };
47
+ }
48
+ if (fetchedError) {
49
+ return {
50
+ status: 'error',
51
+ displayData,
52
+ detail: matchedDetail,
53
+ error: fetchedError,
54
+ };
55
+ }
56
+ if (!resourceNeedsFetchedDetail(resource)) {
57
+ return {
58
+ status: 'ready',
59
+ displayData,
60
+ detail: matchedDetail,
61
+ error: undefined,
62
+ };
63
+ }
64
+ if (matchedDetail !== null) {
65
+ return {
66
+ status: 'ready',
67
+ displayData,
68
+ detail: matchedDetail,
69
+ error: undefined,
70
+ };
71
+ }
72
+ return { status: 'loading', displayData, detail: null, error: undefined };
73
+ }
74
+
75
+ /**
76
+ * Returns true when the fetched `detail` belongs to the current selection.
77
+ * The fetch lags selection, so it can briefly hold a previously selected span
78
+ * (even a different resource type); reject it before merging or its fields
79
+ * union into the wrong panel. Steps/hooks/waits carry their parent `runId`, so
80
+ * a `run` selection excludes objects identifiable as a child resource.
81
+ */
82
+ export function spanDetailMatchesSelection(
83
+ detail: unknown,
84
+ resource: string | undefined,
85
+ resourceId: string | undefined
86
+ ): boolean {
87
+ if (!detail || typeof detail !== 'object' || !resource || !resourceId) {
88
+ return false;
89
+ }
90
+ switch (resource) {
91
+ case 'step':
92
+ return hasField(detail, 'stepId') && detail.stepId === resourceId;
93
+ case 'hook':
94
+ return hasField(detail, 'hookId') && detail.hookId === resourceId;
95
+ case 'sleep':
96
+ return hasField(detail, 'waitId') && detail.waitId === resourceId;
97
+ case 'run':
98
+ return (
99
+ hasField(detail, 'runId') &&
100
+ !('stepId' in detail) &&
101
+ !('hookId' in detail) &&
102
+ !('waitId' in detail) &&
103
+ detail.runId === resourceId
104
+ );
105
+ default:
106
+ return false;
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Merges fetched `detail` over the span's own data. The detail supplies the
112
+ * heavy fields the trace strips (input/output/error/metadata, sleep resumeAt);
113
+ * the span's identity, status, and event-derived timestamps stay authoritative
114
+ * so they don't flicker to the backend row's millisecond-different values.
115
+ */
116
+ export function mergeSpanDetail(spanData: unknown, detail: unknown): unknown {
117
+ if (!detail || typeof detail !== 'object') {
118
+ return spanData;
119
+ }
120
+ if (!spanData || typeof spanData !== 'object') {
121
+ return detail;
122
+ }
123
+ // Skip `undefined` span fields so they don't clobber a value the detail
124
+ // legitimately provides (e.g. a step's optional startedAt).
125
+ const merged: Record<string, unknown> = { ...detail };
126
+ for (const [key, value] of Object.entries(
127
+ spanData as Record<string, unknown>
128
+ )) {
129
+ if (value !== undefined) {
130
+ merged[key] = value;
131
+ }
132
+ }
133
+ return merged;
134
+ }
@@ -0,0 +1,146 @@
1
+ 'use client';
2
+
3
+ import type { Event, Hook, Step, WorkflowRun } from '@workflow/world';
4
+ import { useEffect, useMemo, useRef, useState } from 'react';
5
+ import type {
6
+ SelectedSpanInfo,
7
+ SpanSelectionInfo,
8
+ } from './entity-detail-panel';
9
+ import {
10
+ deriveSpanDetailView,
11
+ resourceNeedsFetchedDetail,
12
+ type SpanDetailStatus,
13
+ } from './span-detail-merge';
14
+
15
+ export type DetailResource = WorkflowRun | Step | Hook | Event;
16
+
17
+ export type FetchSpanDetail = (
18
+ selection: SpanSelectionInfo
19
+ ) => Promise<DetailResource>;
20
+
21
+ function deriveSpanSelection(
22
+ selectedSpan: SelectedSpanInfo | null
23
+ ): SpanSelectionInfo | null {
24
+ if (!selectedSpan) return null;
25
+ const { resource, data } = selectedSpan;
26
+
27
+ if (
28
+ resource === 'step' &&
29
+ data &&
30
+ typeof data === 'object' &&
31
+ 'stepId' in data
32
+ ) {
33
+ const step = data as Step;
34
+ return { resource: 'step', resourceId: step.stepId, runId: step.runId };
35
+ }
36
+ if (
37
+ resource === 'run' &&
38
+ data &&
39
+ typeof data === 'object' &&
40
+ 'runId' in data
41
+ ) {
42
+ return { resource: 'run', resourceId: (data as WorkflowRun).runId };
43
+ }
44
+ if (
45
+ resource === 'hook' &&
46
+ data &&
47
+ typeof data === 'object' &&
48
+ 'hookId' in data
49
+ ) {
50
+ return { resource: 'hook', resourceId: (data as Hook).hookId };
51
+ }
52
+ if (resource === 'sleep') {
53
+ if (!selectedSpan.spanId) return null;
54
+ const waitData = data as { runId?: string } | undefined;
55
+ return {
56
+ resource: 'sleep',
57
+ resourceId: selectedSpan.spanId,
58
+ runId: waitData?.runId,
59
+ };
60
+ }
61
+ return null;
62
+ }
63
+
64
+ export interface SelectedSpanDetailResult {
65
+ status: SpanDetailStatus;
66
+ resource: SpanSelectionInfo['resource'] | undefined;
67
+ resourceId: string | undefined;
68
+ runId: string | undefined;
69
+ displayData: Record<string, unknown>;
70
+ detail: DetailResource | null;
71
+ error: Error | undefined;
72
+ }
73
+
74
+ export function useSelectedSpanDetail(
75
+ selectedSpan: SelectedSpanInfo | null,
76
+ fetchSpanDetail: FetchSpanDetail
77
+ ): SelectedSpanDetailResult {
78
+ const selection = useMemo(
79
+ () => deriveSpanSelection(selectedSpan),
80
+ [selectedSpan]
81
+ );
82
+ const resource = selection?.resource;
83
+ const resourceId = selection?.resourceId;
84
+ const runId = selection?.runId;
85
+ const selectionKey =
86
+ resource && resourceId ? `${resource}:${resourceId}` : null;
87
+ const needsFetch = resourceNeedsFetchedDetail(resource);
88
+
89
+ const [fetched, setFetched] = useState<{
90
+ detail: DetailResource | null;
91
+ error: Error | null;
92
+ errorKey: string | null;
93
+ }>({ detail: null, error: null, errorKey: null });
94
+
95
+ const tokenRef = useRef(0);
96
+ const selectionRef = useRef(selection);
97
+ selectionRef.current = selection;
98
+
99
+ useEffect(() => {
100
+ if (!selectionKey || !needsFetch) {
101
+ return;
102
+ }
103
+ const activeSelection = selectionRef.current;
104
+ if (!activeSelection) {
105
+ return;
106
+ }
107
+ const token = ++tokenRef.current;
108
+ fetchSpanDetail(activeSelection)
109
+ .then((detail) => {
110
+ if (tokenRef.current !== token) return;
111
+ setFetched({ detail, error: null, errorKey: null });
112
+ })
113
+ .catch((err: unknown) => {
114
+ if (tokenRef.current !== token) return;
115
+ setFetched({
116
+ detail: null,
117
+ error: err instanceof Error ? err : new Error(String(err)),
118
+ errorKey: selectionKey,
119
+ });
120
+ });
121
+ }, [selectionKey, runId, needsFetch, fetchSpanDetail]);
122
+
123
+ const scopedError = fetched.errorKey === selectionKey ? fetched.error : null;
124
+
125
+ const view = useMemo(
126
+ () =>
127
+ deriveSpanDetailView({
128
+ resource,
129
+ resourceId,
130
+ inlineData: selectedSpan?.data,
131
+ fetchedDetail: fetched.detail,
132
+ fetchedError: scopedError,
133
+ }),
134
+ [resource, resourceId, selectedSpan?.data, fetched.detail, scopedError]
135
+ );
136
+
137
+ return {
138
+ status: view.status,
139
+ resource,
140
+ resourceId,
141
+ runId,
142
+ displayData: view.displayData,
143
+ detail: view.detail as DetailResource | null,
144
+ error: view.error,
145
+ };
146
+ }
@@ -0,0 +1,34 @@
1
+ import { Skeleton } from './ui/skeleton';
2
+
3
+ const STREAM_SKELETON_ROWS = [
4
+ { id: 'stream-skeleton-row-1', width: '72%' },
5
+ { id: 'stream-skeleton-row-2', width: '58%' },
6
+ { id: 'stream-skeleton-row-3', width: '80%' },
7
+ { id: 'stream-skeleton-row-4', width: '64%' },
8
+ ];
9
+
10
+ export function StreamViewerSkeleton() {
11
+ return (
12
+ <output
13
+ aria-busy="true"
14
+ aria-label="Loading stream"
15
+ className="flex h-full min-h-0 w-full flex-col overflow-hidden bg-background-100"
16
+ >
17
+ <span className="sr-only">Loading stream…</span>
18
+ <div className="flex h-10 min-h-10 items-center border-b border-gray-alpha-400 px-3">
19
+ <Skeleton className="h-3 w-10" />
20
+ </div>
21
+ <div className="flex flex-col">
22
+ {STREAM_SKELETON_ROWS.map((row) => (
23
+ <div
24
+ key={row.id}
25
+ className="flex h-10 items-center gap-2 border-b border-gray-alpha-400 px-3"
26
+ >
27
+ <Skeleton className="h-3" style={{ width: row.width }} />
28
+ <Skeleton className="h-4 w-4 shrink-0 rounded-sm" />
29
+ </div>
30
+ ))}
31
+ </div>
32
+ </output>
33
+ );
34
+ }
@@ -2,8 +2,10 @@
2
2
 
3
3
  import React, { useEffect, useRef } from 'react';
4
4
  import { Virtuoso, type VirtuosoHandle } from 'react-virtuoso';
5
+ import { serializeForClipboard } from './sidebar/copyable-data-block';
6
+ import { StreamViewerSkeleton } from './stream-viewer-skeleton';
7
+ import { CopyButton } from './trace-viewer/components/copy-button';
5
8
  import { DataInspector } from './ui/data-inspector';
6
- import { Skeleton } from './ui/skeleton';
7
9
 
8
10
  // ──────────────────────────────────────────────────────────────────────────
9
11
  // Types
@@ -23,7 +25,7 @@ interface StreamViewerProps {
23
25
  error?: string | null;
24
26
  /** True while the initial stream connection is being established */
25
27
  isLoading?: boolean;
26
- /** Called when the user scrolls near the bottom, for triggering pagination */
28
+ /** Called when the user scrolls near the rendered end. */
27
29
  onScrollEnd?: () => void;
28
30
  }
29
31
 
@@ -31,60 +33,27 @@ interface StreamViewerProps {
31
33
  // Chunk row — memoized to prevent remounts during polling
32
34
  // ──────────────────────────────────────────────────────────────────────────
33
35
 
34
- const ChunkRow = React.memo(function ChunkRow({
35
- chunk,
36
- index,
37
- }: {
38
- chunk: Chunk;
39
- index: number;
40
- }) {
36
+ const ChunkRow = React.memo(function ChunkRow({ chunk }: { chunk: Chunk }) {
41
37
  return (
42
- <div
43
- className="text-[11px] rounded-md border p-3"
44
- style={{
45
- borderColor: 'var(--ds-gray-300)',
46
- backgroundColor: 'var(--ds-gray-100)',
47
- }}
48
- >
49
- <div className="flex items-start gap-2">
50
- <span
51
- className="select-none pt-px"
52
- style={{ color: 'var(--ds-gray-500)' }}
53
- >
54
- [{index}]
55
- </span>
56
- <div className="min-w-0 flex-1">
57
- {typeof chunk.value === 'string' ? (
58
- <span
59
- className="whitespace-pre-wrap break-words"
60
- style={{ color: 'var(--ds-gray-1000)' }}
61
- >
62
- {chunk.value}
63
- </span>
64
- ) : (
65
- <DataInspector data={chunk.value} expandLevel={1} />
66
- )}
67
- </div>
38
+ <div className="flex w-full items-start gap-1 border-b border-gray-alpha-400 px-3 py-2">
39
+ <div className="min-w-0 flex-1">
40
+ {typeof chunk.value === 'string' ? (
41
+ <span className="whitespace-pre-wrap break-words text-label-12 font-mono text-gray-1000">
42
+ {chunk.value}
43
+ </span>
44
+ ) : (
45
+ <DataInspector data={chunk.value} expandLevel={1} />
46
+ )}
68
47
  </div>
48
+ <CopyButton
49
+ copyText={serializeForClipboard(chunk.value)}
50
+ ariaLabel="Copy chunk"
51
+ className="shrink-0 -mr-1 [&>div]:h-4 [&>div]:w-4 [&_svg]:h-4 [&_svg]:w-4"
52
+ />
69
53
  </div>
70
54
  );
71
55
  });
72
56
 
73
- // ──────────────────────────────────────────────────────────────────────────
74
- // Skeleton loading
75
- // ──────────────────────────────────────────────────────────────────────────
76
-
77
- function StreamSkeleton() {
78
- return (
79
- <div className="flex flex-col gap-3 animate-in fade-in">
80
- <Skeleton style={{ width: 120, height: 16, borderRadius: 4 }} />
81
- {[1, 2, 3, 4].map((i) => (
82
- <Skeleton key={i} style={{ height: 56, borderRadius: 6 }} />
83
- ))}
84
- </div>
85
- );
86
- }
87
-
88
57
  // ──────────────────────────────────────────────────────────────────────────
89
58
  // Main component
90
59
  // ──────────────────────────────────────────────────────────────────────────
@@ -105,7 +74,6 @@ export function StreamViewer({
105
74
  const virtuosoRef = useRef<VirtuosoHandle>(null);
106
75
  const prevChunkCountRef = useRef(0);
107
76
 
108
- // Auto-scroll to bottom when new chunks arrive (live streaming)
109
77
  useEffect(() => {
110
78
  if (chunks.length > prevChunkCountRef.current && chunks.length > 0) {
111
79
  virtuosoRef.current?.scrollToIndex({
@@ -116,71 +84,31 @@ export function StreamViewer({
116
84
  prevChunkCountRef.current = chunks.length;
117
85
  }, [chunks.length]);
118
86
 
119
- // Show skeleton when loading and no chunks have arrived yet
120
87
  if (isLoading && chunks.length === 0) {
121
- return (
122
- <div className="flex flex-col h-full">
123
- <StreamSkeleton />
124
- </div>
125
- );
88
+ return <StreamViewerSkeleton />;
126
89
  }
127
90
 
128
91
  return (
129
- <div className="flex flex-col h-full">
130
- {/* Live indicator */}
131
- {isLive && (
132
- <div className="flex items-center gap-1.5 mb-2 px-1">
133
- <span
134
- className="inline-block w-2 h-2 rounded-full"
135
- style={{ backgroundColor: 'var(--ds-green-600)' }}
136
- />
137
- <span className="text-xs" style={{ color: 'var(--ds-green-700)' }}>
138
- Live
139
- </span>
140
- </div>
141
- )}
142
-
143
- {/* Header */}
144
- {chunks.length > 0 && (
145
- <div className="flex items-center gap-2 mb-2 px-1">
146
- <span
147
- className="text-[13px] font-medium"
148
- style={{ color: 'var(--ds-gray-900)' }}
149
- >
150
- Stream Chunks
151
- </span>
152
- <span
153
- className="text-xs tabular-nums"
154
- style={{ color: 'var(--ds-gray-600)' }}
155
- >
156
- ({chunks.length})
157
- </span>
158
- </div>
159
- )}
92
+ <div className="flex h-full w-full flex-col overflow-hidden bg-background-100">
93
+ {/* Status header */}
94
+ <div className="flex h-10 min-h-10 items-center gap-1.5 border-b border-gray-alpha-400 px-3">
95
+ {isLive && (
96
+ <>
97
+ <span className="inline-block h-2 w-2 rounded-full bg-green-600" />
98
+ <span className="text-label-12 text-green-700">Live</span>
99
+ </>
100
+ )}
101
+ </div>
160
102
 
161
103
  {/* Content */}
162
104
  <div className="flex-1 min-h-0">
163
105
  {error ? (
164
- <div
165
- className="text-[11px] rounded-md border p-3"
166
- style={{
167
- borderColor: 'var(--ds-red-300)',
168
- backgroundColor: 'var(--ds-red-100)',
169
- color: 'var(--ds-red-700)',
170
- }}
171
- >
106
+ <div className="border-b border-red-400 bg-red-100 px-3 py-2 text-label-12 text-red-900">
172
107
  <div>Error reading stream:</div>
173
108
  <div>{error}</div>
174
109
  </div>
175
110
  ) : chunks.length === 0 ? (
176
- <div
177
- className="text-[11px] rounded-md border p-3"
178
- style={{
179
- borderColor: 'var(--ds-gray-300)',
180
- backgroundColor: 'var(--ds-gray-100)',
181
- color: 'var(--ds-gray-600)',
182
- }}
183
- >
111
+ <div className="flex h-10 items-center border-b border-gray-alpha-400 bg-background-200 px-3 text-label-12 text-gray-900">
184
112
  {isLive ? 'Waiting for stream data...' : 'Stream is empty'}
185
113
  </div>
186
114
  ) : (
@@ -190,8 +118,8 @@ export function StreamViewer({
190
118
  overscan={10}
191
119
  endReached={() => onScrollEnd?.()}
192
120
  itemContent={(index) => (
193
- <div style={{ paddingBottom: 8 }}>
194
- <ChunkRow chunk={chunks[index]} index={index} />
121
+ <div className="w-full">
122
+ <ChunkRow chunk={chunks[index]} />
195
123
  </div>
196
124
  )}
197
125
  style={{ flex: 1, minHeight: 0 }}
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { Check, Copy } from 'lucide-react';
4
4
  import { type JSX, useEffect, useRef, useState } from 'react';
5
- import { cn } from '../../../lib/utils';
5
+ import { cn } from '../../../lib/cn';
6
6
 
7
7
  interface CopyButtonProps {
8
8
  copyText: string;
@@ -31,7 +31,7 @@ export function CopyButton({
31
31
  type="button"
32
32
  aria-label={ariaLabel}
33
33
  className={cn(
34
- 'cursor-pointer text-gray-800 hover:text-gray-1000 bg-transparent border-none p-1 m-0',
34
+ 'cursor-pointer text-gray-800 hover:text-gray-1000 bg-transparent border-0 p-1 m-0',
35
35
  className
36
36
  )}
37
37
  onClick={(e) => {
@@ -0,0 +1,123 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest';
2
+ import {
3
+ clampPanelWidth,
4
+ computeMaxPanelWidth,
5
+ MAIN_MIN_WIDTH,
6
+ PANEL_DEFAULT_WIDTH,
7
+ PANEL_HARD_MAX_WIDTH,
8
+ PANEL_MIN_WIDTH,
9
+ PANEL_WIDTH_STORAGE_KEY,
10
+ readStoredPanelWidth,
11
+ writeStoredPanelWidth,
12
+ } from './detail-panel-width';
13
+
14
+ function stubLocalStorage(overrides: Partial<Storage> = {}) {
15
+ const storage = {
16
+ getItem: vi.fn().mockReturnValue(null),
17
+ setItem: vi.fn(),
18
+ ...overrides,
19
+ };
20
+ vi.stubGlobal('window', { localStorage: storage });
21
+ return storage;
22
+ }
23
+
24
+ afterEach(() => {
25
+ vi.unstubAllGlobals();
26
+ });
27
+
28
+ describe('computeMaxPanelWidth', () => {
29
+ it('falls back to the hard max when the container is unmeasured', () => {
30
+ expect(computeMaxPanelWidth(0)).toBe(PANEL_HARD_MAX_WIDTH);
31
+ expect(computeMaxPanelWidth(-5)).toBe(PANEL_HARD_MAX_WIDTH);
32
+ });
33
+
34
+ it('reserves the main-area minimum', () => {
35
+ expect(computeMaxPanelWidth(1000)).toBe(1000 - MAIN_MIN_WIDTH);
36
+ });
37
+
38
+ it('caps at the hard max on very wide containers', () => {
39
+ expect(computeMaxPanelWidth(5000)).toBe(PANEL_HARD_MAX_WIDTH);
40
+ });
41
+
42
+ it('bottoms out at 0 when the container is smaller than the main minimum', () => {
43
+ expect(computeMaxPanelWidth(MAIN_MIN_WIDTH - 50)).toBe(0);
44
+ });
45
+ });
46
+
47
+ describe('clampPanelWidth', () => {
48
+ it('passes through widths within bounds', () => {
49
+ expect(clampPanelWidth(360, 1000)).toBe(360);
50
+ });
51
+
52
+ it('clamps to the panel minimum', () => {
53
+ expect(clampPanelWidth(100, 1000)).toBe(PANEL_MIN_WIDTH);
54
+ });
55
+
56
+ it('clamps to the container-relative maximum', () => {
57
+ expect(clampPanelWidth(900, 1000)).toBe(1000 - MAIN_MIN_WIDTH);
58
+ });
59
+
60
+ it('lets the max win below the crossover so the panel gives way, not the main area', () => {
61
+ // Container too small for both floors: panel compresses below its own min.
62
+ const available = PANEL_MIN_WIDTH + MAIN_MIN_WIDTH - 100;
63
+ expect(clampPanelWidth(360, available)).toBe(available - MAIN_MIN_WIDTH);
64
+ });
65
+ });
66
+
67
+ describe('readStoredPanelWidth', () => {
68
+ it('returns the default when window is unavailable (SSR)', () => {
69
+ expect(readStoredPanelWidth()).toBe(PANEL_DEFAULT_WIDTH);
70
+ });
71
+
72
+ it('returns the stored value when valid', () => {
73
+ stubLocalStorage({ getItem: vi.fn().mockReturnValue('512') });
74
+ expect(readStoredPanelWidth()).toBe(512);
75
+ });
76
+
77
+ it('returns the default for missing or unparseable values', () => {
78
+ stubLocalStorage({ getItem: vi.fn().mockReturnValue(null) });
79
+ expect(readStoredPanelWidth()).toBe(PANEL_DEFAULT_WIDTH);
80
+ stubLocalStorage({ getItem: vi.fn().mockReturnValue('not-a-number') });
81
+ expect(readStoredPanelWidth()).toBe(PANEL_DEFAULT_WIDTH);
82
+ });
83
+
84
+ it('clamps stored values to absolute bounds only', () => {
85
+ stubLocalStorage({ getItem: vi.fn().mockReturnValue('-20') });
86
+ expect(readStoredPanelWidth()).toBe(PANEL_MIN_WIDTH);
87
+ stubLocalStorage({ getItem: vi.fn().mockReturnValue('99999') });
88
+ expect(readStoredPanelWidth()).toBe(PANEL_HARD_MAX_WIDTH);
89
+ });
90
+
91
+ it('returns the default when storage access throws', () => {
92
+ stubLocalStorage({
93
+ getItem: vi.fn().mockImplementation(() => {
94
+ throw new Error('denied');
95
+ }),
96
+ });
97
+ expect(readStoredPanelWidth()).toBe(PANEL_DEFAULT_WIDTH);
98
+ });
99
+ });
100
+
101
+ describe('writeStoredPanelWidth', () => {
102
+ it('is a no-op when window is unavailable (SSR)', () => {
103
+ expect(() => writeStoredPanelWidth(400)).not.toThrow();
104
+ });
105
+
106
+ it('rounds and writes the value', () => {
107
+ const storage = stubLocalStorage();
108
+ writeStoredPanelWidth(412.6);
109
+ expect(storage.setItem).toHaveBeenCalledWith(
110
+ PANEL_WIDTH_STORAGE_KEY,
111
+ '413'
112
+ );
113
+ });
114
+
115
+ it('swallows storage errors (private mode, quota)', () => {
116
+ stubLocalStorage({
117
+ setItem: vi.fn().mockImplementation(() => {
118
+ throw new Error('quota');
119
+ }),
120
+ });
121
+ expect(() => writeStoredPanelWidth(400)).not.toThrow();
122
+ });
123
+ });