@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,67 @@
1
+ import type { Event } from '@workflow/world';
2
+
3
+ const WORKFLOW_ULID_BODY = '[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}';
4
+
5
+ const STEP_ID_PATTERN = new RegExp(`^step_(${WORKFLOW_ULID_BODY})$`, 'i');
6
+ const WAIT_ID_PATTERN = new RegExp(`^wait_(${WORKFLOW_ULID_BODY})$`, 'i');
7
+ const HOOK_ID_PATTERN = new RegExp(`^hook_(${WORKFLOW_ULID_BODY})$`, 'i');
8
+ const EVENT_ID_PATTERN = new RegExp(`^evnt_(${WORKFLOW_ULID_BODY})$`, 'i');
9
+
10
+ const WORKFLOW_ID_PREFIX_PATTERN = /^(step_|wait_|hook_|evnt_|wrun_)/i;
11
+
12
+ export type ExactWorkflowSearchIdKind = 'step' | 'wait' | 'hook' | 'event';
13
+
14
+ export type ExactWorkflowSearchId = {
15
+ kind: ExactWorkflowSearchIdKind;
16
+ id: string;
17
+ };
18
+
19
+ export type ExactIdSearchResult =
20
+ | { status: 'ok'; events: Event[]; truncated?: boolean }
21
+ | { status: 'not_found' }
22
+ | { status: 'error'; message: string };
23
+
24
+ function matchPrefixedId(
25
+ pattern: RegExp,
26
+ prefix: 'step' | 'wait' | 'hook' | 'evnt',
27
+ kind: ExactWorkflowSearchIdKind,
28
+ query: string
29
+ ): ExactWorkflowSearchId | null {
30
+ const match = query.match(pattern);
31
+ if (!match) {
32
+ return null;
33
+ }
34
+ return { kind, id: `${prefix}_${match[1].toUpperCase()}` };
35
+ }
36
+
37
+ /**
38
+ * Returns a parsed workflow ID when `query` is a full step, wait, hook, or event ID.
39
+ * Partial IDs and run IDs (`wrun_`) are ignored. ULID bodies are matched case-insensitively
40
+ * and normalized to uppercase in the returned ID.
41
+ */
42
+ export function parseExactWorkflowSearchId(
43
+ query: string
44
+ ): ExactWorkflowSearchId | null {
45
+ const trimmed = query.trim();
46
+ if (!trimmed) {
47
+ return null;
48
+ }
49
+
50
+ return (
51
+ matchPrefixedId(STEP_ID_PATTERN, 'step', 'step', trimmed) ??
52
+ matchPrefixedId(WAIT_ID_PATTERN, 'wait', 'wait', trimmed) ??
53
+ matchPrefixedId(HOOK_ID_PATTERN, 'hook', 'hook', trimmed) ??
54
+ matchPrefixedId(EVENT_ID_PATTERN, 'evnt', 'event', trimmed)
55
+ );
56
+ }
57
+
58
+ /** True when input looks like the user is attempting an ID search (including partial). */
59
+ export function looksLikeWorkflowIdSearchInput(query: string): boolean {
60
+ const trimmed = query.trim();
61
+ if (!WORKFLOW_ID_PREFIX_PATTERN.test(trimmed)) {
62
+ return false;
63
+ }
64
+ // Distinguish IDs (contain digits) from event-type strings like step_started.
65
+ // Assumes workflow event types do not include digits in their names.
66
+ return /\d/.test(trimmed);
67
+ }
@@ -16,7 +16,7 @@ import {
16
16
  type Revivers,
17
17
  serializedInstanceToRef,
18
18
  } from '@workflow/core/serialization-format';
19
- import { EVENT_DATA_REF_FIELDS } from '@workflow/world';
19
+ import { getEventDataRefFields } from '@workflow/world';
20
20
 
21
21
  // Re-export types and utilities that consumers need
22
22
  export {
@@ -58,12 +58,60 @@ function base64ToArrayBuffer(base64: string): ArrayBuffer {
58
58
  // Web revivers (browser-safe, no Buffer dependency)
59
59
  // ---------------------------------------------------------------------------
60
60
 
61
+ /**
62
+ * Build a reviver for one of the built-in `Error` subclasses (e.g.
63
+ * `TypeError`, `RangeError`). The constructor for the named subclass is
64
+ * resolved off `globalThis` at call time so the produced instance has the
65
+ * correct prototype chain in the consumer realm. Falls back to a generic
66
+ * `Error` (with `name` set) if the global isn't available, which keeps the
67
+ * o11y UI rendering even on exotic browsers.
68
+ *
69
+ * `cause` is passed through `ErrorOptions` to the constructor when present,
70
+ * matching `getCommonRevivers` in `@workflow/core` so the resulting `cause`
71
+ * property has the same semantics (non-enumerable, set by the engine) as a
72
+ * freshly thrown Error in the consumer realm. The `'cause' in value` check
73
+ * preserves the distinction between "no cause" and "cause is undefined".
74
+ */
75
+ function makeWebErrorSubclassReviver(
76
+ name:
77
+ | 'EvalError'
78
+ | 'RangeError'
79
+ | 'ReferenceError'
80
+ | 'SyntaxError'
81
+ | 'TypeError'
82
+ | 'URIError'
83
+ ) {
84
+ return (value: { message: string; stack?: string; cause?: unknown }) => {
85
+ const opts = 'cause' in value ? { cause: value.cause } : undefined;
86
+ const Ctor = (globalThis as Record<string, any>)[name] as
87
+ | ErrorConstructor
88
+ | undefined;
89
+ let error: Error;
90
+ if (typeof Ctor === 'function') {
91
+ error = new Ctor(value.message, opts);
92
+ } else {
93
+ // Fallback path: no built-in subclass available (exotic env). Construct
94
+ // a plain Error with the right `name` and copy `cause` manually since
95
+ // the base Error constructor is what we actually called.
96
+ error = Object.assign(new Error(value.message, opts), { name });
97
+ }
98
+ if (value.stack !== undefined) error.stack = value.stack;
99
+ return error;
100
+ };
101
+ }
102
+
61
103
  /**
62
104
  * Get the web-specific revivers for hydrating serialized data.
63
105
  *
64
106
  * Uses `atob()` for base64 decoding (no Node.js Buffer dependency).
65
107
  * All types are revived as real instances (Date, Map, Set, URL,
66
108
  * URLSearchParams, Headers, Error, etc.).
109
+ *
110
+ * NOTE: this set must mirror the keys in `SerializableSpecial` (see
111
+ * `@workflow/core/serialization/types`). Any reducer key added on the
112
+ * serialization side that isn't covered here will cause `devalue.unflatten`
113
+ * to throw `Unknown type X`, which `hydrateResourceIO` swallows and
114
+ * surfaces as a "Failed to load resource details" banner in the o11y UI.
67
115
  */
68
116
  export function getWebRevivers(): Revivers {
69
117
  function reviveArrayBuffer(value: string): ArrayBuffer {
@@ -83,10 +131,120 @@ export function getWebRevivers(): Revivers {
83
131
  BigUint64Array: (value: string) =>
84
132
  new BigUint64Array(reviveArrayBuffer(value)),
85
133
  Date: (value) => new Date(value),
134
+
135
+ // Error family. The reducer side (see
136
+ // `packages/core/src/serialization/reducers/common.ts`) emits a tagged
137
+ // entry for each built-in Error subclass plus the workflow-specific
138
+ // `FatalError` / `RetryableError` / `HookConflictError` /
139
+ // `RuntimeDecryptionError` and `AggregateError`. Without
140
+ // matching revivers here, `devalue.unflatten` throws "Unknown type X"
141
+ // — which surfaces in the web o11y UI as "Failed to load resource
142
+ // details: Unknown type FatalError".
86
143
  Error: (value) => {
144
+ const opts = 'cause' in value ? { cause: value.cause } : undefined;
145
+ const error = new Error(value.message, opts);
146
+ error.name = value.name;
147
+ if (value.stack !== undefined) error.stack = value.stack;
148
+ return error;
149
+ },
150
+ EvalError: makeWebErrorSubclassReviver('EvalError'),
151
+ RangeError: makeWebErrorSubclassReviver('RangeError'),
152
+ ReferenceError: makeWebErrorSubclassReviver('ReferenceError'),
153
+ SyntaxError: makeWebErrorSubclassReviver('SyntaxError'),
154
+ TypeError: makeWebErrorSubclassReviver('TypeError'),
155
+ URIError: makeWebErrorSubclassReviver('URIError'),
156
+ AggregateError: (value) => {
157
+ const opts = 'cause' in value ? { cause: value.cause } : undefined;
158
+ const Ctor = (
159
+ globalThis as { AggregateError?: AggregateErrorConstructor }
160
+ ).AggregateError;
161
+ const error =
162
+ typeof Ctor === 'function'
163
+ ? new Ctor(value.errors, value.message, opts)
164
+ : Object.assign(new Error(value.message, opts), {
165
+ name: 'AggregateError',
166
+ errors: value.errors,
167
+ });
168
+ if (value.stack !== undefined) error.stack = value.stack;
169
+ return error;
170
+ },
171
+ // `FatalError` and `RetryableError` are not built-in browser globals,
172
+ // so we can't resolve a constructor from globalThis. The web o11y UI
173
+ // doesn't need `instanceof FatalError` to pass (no user code runs
174
+ // here) — it just needs `name`, `message`, `stack`, and any extra
175
+ // enumerable fields to render. Construct a plain `Error` with `name`
176
+ // set; ObjectInspector reads `constructor.name` for the displayed
177
+ // class label, but we don't have the real class, so we emit a tagged
178
+ // Error whose `name` field carries the class identity. This matches
179
+ // how the existing base `Error` reviver presents unknown subclasses.
180
+ FatalError: (value) => {
181
+ const opts = 'cause' in value ? { cause: value.cause } : undefined;
182
+ const error = new Error(value.message, opts);
183
+ error.name = 'FatalError';
184
+ if (value.stack !== undefined) error.stack = value.stack;
185
+ return error;
186
+ },
187
+ HookConflictError: (value) => {
188
+ const opts = 'cause' in value ? { cause: value.cause } : undefined;
189
+ const error = new Error(value.message, opts) as Error & {
190
+ token?: string;
191
+ conflictingRunId?: string;
192
+ };
193
+ error.name = 'HookConflictError';
194
+ error.token = value.token;
195
+ if (value.conflictingRunId !== undefined) {
196
+ error.conflictingRunId = value.conflictingRunId;
197
+ }
198
+ if (value.stack !== undefined) error.stack = value.stack;
199
+ return error;
200
+ },
201
+ RetryableError: (value) => {
202
+ const opts = 'cause' in value ? { cause: value.cause } : undefined;
203
+ const error = new Error(value.message, opts) as Error & {
204
+ retryAfter?: Date;
205
+ };
206
+ error.name = 'RetryableError';
207
+ if (value.stack !== undefined) error.stack = value.stack;
208
+ // `retryAfter` is serialized as an epoch ms number (see the runtime
209
+ // RetryableError reducer for the rationale around realm-safety).
210
+ // Rehydrate as a Date so o11y consumers can render it directly.
211
+ // Guard against payloads from older runtime versions that predate
212
+ // the field — without this check, `new Date(undefined)` would
213
+ // produce an Invalid Date rather than omitting the property.
214
+ if (value.retryAfter != null) {
215
+ error.retryAfter = new Date(value.retryAfter);
216
+ }
217
+ return error;
218
+ },
219
+ RuntimeDecryptionError: (value) => {
220
+ const opts = 'cause' in value ? { cause: value.cause } : undefined;
221
+ const error = new Error(value.message, opts) as Error & {
222
+ context?: unknown;
223
+ };
224
+ error.name = 'RuntimeDecryptionError';
225
+ if (value.context !== undefined) {
226
+ error.context = value.context;
227
+ }
228
+ if (value.stack !== undefined) error.stack = value.stack;
229
+ return error;
230
+ },
231
+ DOMException: (value) => {
232
+ // Modern browsers and Node 18+ expose `DOMException` on globalThis.
233
+ // `AbortController.abort()` with no argument synthesizes one as the
234
+ // signal's reason, so this is a common payload for any aborted step.
235
+ const G = globalThis as { DOMException?: typeof DOMException };
236
+ if (typeof G.DOMException === 'function') {
237
+ const e = new G.DOMException(value.message, value.name);
238
+ if (value.stack !== undefined) e.stack = value.stack;
239
+ if ('cause' in value) (e as { cause?: unknown }).cause = value.cause;
240
+ return e;
241
+ }
87
242
  const error = new Error(value.message);
88
243
  error.name = value.name;
89
- error.stack = value.stack;
244
+ if (value.stack !== undefined) error.stack = value.stack;
245
+ if ('cause' in value) {
246
+ (error as Error & { cause?: unknown }).cause = value.cause;
247
+ }
90
248
  return error;
91
249
  },
92
250
  Float32Array: (value: string) => new Float32Array(reviveArrayBuffer(value)),
@@ -140,7 +298,7 @@ export function getWebRevivers(): Revivers {
140
298
 
141
299
  // Web-specific overrides for class instances.
142
300
  // Create objects with a dynamically-named constructor so that
143
- // react-inspector shows the class name (it reads constructor.name).
301
+ // the data inspector shows the class name (it reads constructor.name).
144
302
  Class: (value) => `<class:${extractClassName(value.classId)}>`,
145
303
  Instance: (value) => {
146
304
  // Run instances are rendered as clickable RunRef badges
@@ -153,7 +311,7 @@ export function getWebRevivers(): Revivers {
153
311
  const props =
154
312
  data && typeof data === 'object' ? { ...data } : { value: data };
155
313
  // Create a constructor with the right name using computed property
156
- // so react-inspector's `object.constructor.name` shows the class name.
314
+ // so the data inspector's `object.constructor.name` shows the class name.
157
315
  // Must use `function` (not arrow) because arrow functions have no .prototype.
158
316
  // biome-ignore lint/complexity/useArrowFunction: arrow functions have no .prototype
159
317
  const ctor = { [className]: function () {} }[className]!;
@@ -288,7 +446,7 @@ function replaceEncryptedAndExpiredWithMarkers<T>(resource: T): T {
288
446
  if (result.eventData && typeof result.eventData === 'object') {
289
447
  const eventType =
290
448
  typeof result.eventType === 'string' ? result.eventType : '';
291
- const refKeys = EVENT_DATA_REF_FIELDS[eventType] ?? [];
449
+ const refKeys = getEventDataRefFields(eventType);
292
450
  const ed = { ...(result.eventData as Record<string, unknown>) };
293
451
  for (const key of refKeys) {
294
452
  if (key in ed) {
@@ -307,36 +465,62 @@ function replaceEncryptedAndExpiredWithMarkers<T>(resource: T): T {
307
465
  * When a key is provided, encrypted fields are decrypted before hydration.
308
466
  * This is the async version used when the user clicks "Decrypt" in the web UI.
309
467
  *
310
- * Handles both top-level fields (input, output, metadata) and nested
311
- * eventData subfields per `EVENT_DATA_REF_FIELDS` from `@workflow/world` for that event type.
468
+ * Handles both top-level fields (input, output, metadata) and nested eventData
469
+ * payload fields for that event type.
312
470
  */
313
471
  export async function hydrateResourceIOWithKey<T>(
314
472
  resource: T,
315
473
  key: Uint8Array
316
474
  ): Promise<T> {
317
- const { hydrateDataWithKey } = await import(
475
+ return hydrateResourceIOAsync(resource, key);
476
+ }
477
+
478
+ /**
479
+ * Async hydration for web display.
480
+ *
481
+ * This follows the same resource-field mapping as {@link hydrateResourceIO},
482
+ * but can also inflate compressed browser payloads through the registered
483
+ * zstd WASM decoder. When a key is provided, encrypted fields are decrypted
484
+ * first and then inflated/hydrated.
485
+ */
486
+ export async function hydrateResourceIOAsync<T>(
487
+ resource: T,
488
+ key?: Uint8Array
489
+ ): Promise<T> {
490
+ const { hydrateDataWithKey, deriveRunPayloadKeys } = await import(
318
491
  '@workflow/core/serialization-format'
319
492
  );
320
- const { importKey } = await import('@workflow/core/encryption');
321
- const cryptoKey = await importKey(key);
493
+ // Payloads may be zstd-compressed (the Web DecompressionStream has no zstd);
494
+ // register the WASM-backed browser decoder before hydrating. Idempotent and
495
+ // lazy — the WASM is only compiled when a zstd payload is actually decoded.
496
+ const { ensureZstdDecoderRegistered } = await import(
497
+ './zstd-browser-decoder.js'
498
+ );
499
+ ensureZstdDecoderRegistered();
500
+ // Resolve the *full* key capability, not just the symmetric key: a run's
501
+ // event log can contain sealed ('encp') payloads that another run wrote to
502
+ // it (a cross-deployment hook resumption, say), and opening those needs the
503
+ // run's X25519 scalar in addition to its AES key. Both are derived from the
504
+ // same 32 bytes the key-retrieval endpoint returns.
505
+ // Resolve the *full* key capability, not just the symmetric key: a run's
506
+ // event log can contain sealed ('encp') payloads that another run wrote to
507
+ // it (a cross-deployment hook resumption, say), and opening those needs the
508
+ // run's X25519 scalar in addition to its AES key. Both derive from the same
509
+ // 32 bytes the key-retrieval endpoint returns.
510
+ const cryptoKey = key ? await deriveRunPayloadKeys(key) : undefined;
322
511
  const revivers = getRevivers();
323
512
 
324
- /** Extract original encrypted bytes from a marker or raw Uint8Array, then decrypt + hydrate */
325
- async function decryptField(
326
- value: unknown,
327
- rev: Revivers,
328
- k: Awaited<ReturnType<typeof importKey>>
329
- ): Promise<unknown> {
513
+ async function hydrateField(value: unknown): Promise<unknown> {
330
514
  // Already-hydrated: encrypted marker with stored bytes
331
515
  if (isEncryptedMarker(value)) {
332
516
  const raw = (value as any).__encryptedData as Uint8Array;
333
- return hydrateDataWithKey(raw, rev, k);
517
+ return cryptoKey ? hydrateDataWithKey(raw, revivers, cryptoKey) : value;
334
518
  }
335
- // Raw encrypted Uint8Array (not yet hydrated)
519
+ // Raw Uint8Array: may be encrypted, compressed, or plain devalue.
336
520
  if (value instanceof Uint8Array) {
337
- return hydrateDataWithKey(value, rev, k);
521
+ return hydrateDataWithKey(value, revivers, cryptoKey);
338
522
  }
339
- // Not encrypted — return as-is
523
+ // Not serialized — return as-is.
340
524
  return value;
341
525
  }
342
526
 
@@ -346,29 +530,25 @@ export async function hydrateResourceIOWithKey<T>(
346
530
  // Decrypt + hydrate top-level serialized fields (runs, steps, hooks)
347
531
  for (const field of ['input', 'output', 'metadata', 'error']) {
348
532
  if (field in result) {
349
- result[field] = await decryptField(result[field], revivers, cryptoKey);
533
+ result[field] = await hydrateField(result[field]);
350
534
  }
351
535
  }
352
536
 
353
- // Decrypt + hydrate eventData subfields (events)
537
+ // Hydrate eventData subfields (events)
354
538
  if (result.eventData && typeof result.eventData === 'object') {
355
539
  const eventType =
356
540
  typeof result.eventType === 'string' ? result.eventType : '';
357
- const refKeys = EVENT_DATA_REF_FIELDS[eventType] ?? [];
541
+ const refKeys = getEventDataRefFields(eventType);
358
542
  const eventData = { ...(result.eventData as Record<string, unknown>) };
359
543
  for (const field of refKeys) {
360
544
  if (field in eventData) {
361
- eventData[field] = await decryptField(
362
- eventData[field],
363
- revivers,
364
- cryptoKey
365
- );
545
+ eventData[field] = await hydrateField(eventData[field]);
366
546
  }
367
547
  }
368
548
  result.eventData = eventData;
369
549
  }
370
550
 
371
- return result as T;
551
+ return replaceEncryptedAndExpiredWithMarkers(result as T);
372
552
  }
373
553
 
374
554
  /**
@@ -387,7 +567,7 @@ export function hasEncryptedFields(resource: unknown): boolean {
387
567
 
388
568
  if (r.eventData && typeof r.eventData === 'object') {
389
569
  const eventType = typeof r.eventType === 'string' ? r.eventType : '';
390
- const refKeys = EVENT_DATA_REF_FIELDS[eventType] ?? [];
570
+ const refKeys = getEventDataRefFields(eventType);
391
571
  const ed = r.eventData as Record<string, unknown>;
392
572
  for (const key of refKeys) {
393
573
  if (key in ed && isEncryptedMarker(ed[key])) return true;
@@ -6,30 +6,54 @@
6
6
  * a fully-formed Trace ready for the trace viewer.
7
7
  */
8
8
 
9
- import type { Event, WorkflowRun } from '@workflow/world';
10
- import type { Span } from '../components/trace-viewer/types';
11
9
  import {
10
+ type Event,
11
+ isHookLifecycleEventType,
12
+ isStepEventType,
13
+ isWaitEventType,
14
+ type WorkflowRun,
15
+ } from '@workflow/world';
16
+ import {
17
+ getEventTimestamp,
12
18
  hookToSpan,
13
19
  runToSpan,
14
20
  stepToSpan,
15
- waitToSpan,
16
21
  WORKFLOW_LIBRARY,
22
+ waitToSpan,
17
23
  } from '../components/workflow-traces/trace-span-construction';
18
24
  import { otelTimeToMs } from '../components/workflow-traces/trace-time-utils';
25
+ import type { Span } from './trace-types';
19
26
 
20
- // ---------------------------------------------------------------------------
21
- // Event type classifiers
22
- // ---------------------------------------------------------------------------
23
-
24
- export const isStepEvent = (eventType: string) => eventType.startsWith('step_');
25
-
26
- export const isTimerEvent = (eventType: string) =>
27
- eventType === 'wait_created' || eventType === 'wait_completed';
27
+ /**
28
+ * Events that belong to the run root span rather than a child entity span.
29
+ * Mirrors the fallthrough logic in {@link groupEventsByCorrelation}: events
30
+ * without a correlationId (run lifecycle) plus correlated events that aren't
31
+ * step/timer/hook events (e.g. `attr_set`, whose correlationId is a dedup
32
+ * token rather than a child entity ID).
33
+ */
34
+ export const isRunLevelEvent = (event: Event): boolean =>
35
+ !event.correlationId ||
36
+ (!isWaitEventType(event.eventType) &&
37
+ !isHookLifecycleEventType(event.eventType) &&
38
+ !isStepEventType(event.eventType));
28
39
 
29
- export const isHookLifecycleEvent = (eventType: string) =>
30
- eventType === 'hook_received' ||
31
- eventType === 'hook_created' ||
32
- eventType === 'hook_disposed';
40
+ /**
41
+ * Filter the raw event list down to the events for a selected span.
42
+ * For the run root span this returns run-level events (see
43
+ * {@link isRunLevelEvent}); for child spans it returns the events
44
+ * correlated to that span's ID.
45
+ */
46
+ export function filterSpanRawEvents(
47
+ events: Event[],
48
+ resource: string | undefined,
49
+ spanId: string | undefined
50
+ ): Event[] {
51
+ if (resource === 'run') {
52
+ return events.filter(isRunLevelEvent);
53
+ }
54
+ if (!spanId) return [];
55
+ return events.filter((e) => e.correlationId === spanId);
56
+ }
33
57
 
34
58
  // ---------------------------------------------------------------------------
35
59
  // Event grouping
@@ -68,17 +92,17 @@ export function groupEventsByCorrelation(events: Event[]): GroupedEvents {
68
92
  continue;
69
93
  }
70
94
 
71
- if (isTimerEvent(event.eventType)) {
95
+ if (isWaitEventType(event.eventType)) {
72
96
  pushEvent(timerEvents, correlationId, event);
73
97
  continue;
74
98
  }
75
99
 
76
- if (isHookLifecycleEvent(event.eventType)) {
100
+ if (isHookLifecycleEventType(event.eventType)) {
77
101
  pushEvent(hookEvents, correlationId, event);
78
102
  continue;
79
103
  }
80
104
 
81
- if (isStepEvent(event.eventType)) {
105
+ if (isStepEventType(event.eventType)) {
82
106
  pushEvent(eventsByStepId, correlationId, event);
83
107
  continue;
84
108
  }
@@ -101,7 +125,7 @@ export function groupEventsByCorrelation(events: Event[]): GroupedEvents {
101
125
  function computeLatestKnownTime(events: Event[], run: WorkflowRun): Date {
102
126
  let latest = new Date(run.createdAt).getTime();
103
127
  for (const event of events) {
104
- const t = new Date(event.createdAt).getTime();
128
+ const t = (getEventTimestamp(event) ?? new Date(event.createdAt)).getTime();
105
129
  if (t > latest) latest = t;
106
130
  }
107
131
  return new Date(latest);
@@ -0,0 +1,56 @@
1
+ export interface Span {
2
+ name: string;
3
+ kind: number;
4
+ resource: string;
5
+ library: {
6
+ name: string;
7
+ version?: string;
8
+ };
9
+ spanId: string;
10
+ parentSpanId?: string;
11
+ status: {
12
+ code: number;
13
+ };
14
+ traceFlags: number;
15
+ attributes: Record<string, unknown>;
16
+ links: Record<string, unknown>[];
17
+ events: SpanEvent[];
18
+ startTime: [number, number];
19
+ endTime: [number, number];
20
+ duration: [number, number];
21
+ /**
22
+ * The time when the span became active/started executing (optional).
23
+ * If provided and different from startTime, the portion between startTime
24
+ * and activeStartTime will be rendered as a "queued" period with different styling.
25
+ */
26
+ activeStartTime?: [number, number];
27
+ }
28
+
29
+ export interface SpanEvent {
30
+ name: string;
31
+ timestamp: [number, number];
32
+ attributes: Record<string, unknown>;
33
+ /**
34
+ * Optional custom color for this event marker (workflow-specific feature).
35
+ * If provided, this color will be used for the event marker line/diamond.
36
+ */
37
+ color?: string;
38
+ /**
39
+ * Whether to show a vertical line for this event in the timeline (workflow-specific feature).
40
+ * If false, only the diamond marker on the span will be shown.
41
+ * Defaults to true if not specified.
42
+ */
43
+ showVerticalLine?: boolean;
44
+ }
45
+
46
+ export interface Resource {
47
+ name: string;
48
+ attributes: Record<string, string>;
49
+ }
50
+
51
+ export interface Trace {
52
+ traceId: string;
53
+ resources?: Resource[];
54
+ spans: Span[];
55
+ rootSpanId?: string;
56
+ }
@@ -0,0 +1,33 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { formatDurationPrecise } from './utils';
3
+
4
+ describe('formatDurationPrecise', () => {
5
+ it('shows whole milliseconds below 1s', () => {
6
+ expect(formatDurationPrecise(0)).toBe('0s');
7
+ expect(formatDurationPrecise(626)).toBe('626ms');
8
+ });
9
+
10
+ it('keeps sub-second precision instead of rounding up to a whole second', () => {
11
+ // The bug this guards: 1626ms must not read as "2s".
12
+ expect(formatDurationPrecise(1626)).toBe('1.63s');
13
+ });
14
+
15
+ it('trims trailing zeros so whole/half seconds read cleanly', () => {
16
+ expect(formatDurationPrecise(2000)).toBe('2s');
17
+ expect(formatDurationPrecise(1500)).toBe('1.5s');
18
+ expect(formatDurationPrecise(1600)).toBe('1.6s');
19
+ expect(formatDurationPrecise(45_000)).toBe('45s');
20
+ });
21
+
22
+ it('honors a custom fraction-digit count (used by the timeline ruler)', () => {
23
+ // Fewer digits also coarsen the rounding: 1 digit rounds to 100ms.
24
+ expect(formatDurationPrecise(1500, 1)).toBe('1.5s');
25
+ expect(formatDurationPrecise(1620, 1)).toBe('1.6s');
26
+ expect(formatDurationPrecise(2000, 1)).toBe('2s');
27
+ });
28
+
29
+ it('decomposes durations of a minute or more', () => {
30
+ expect(formatDurationPrecise(65_000)).toBe('1m 5s');
31
+ expect(formatDurationPrecise(63_450)).toBe('1m 3.45s');
32
+ });
33
+ });
package/src/lib/utils.ts CHANGED
@@ -1,11 +1,5 @@
1
1
  import type { Step } from '@workflow/world';
2
2
  import type { ModelMessage } from 'ai';
3
- import { type ClassValue, clsx } from 'clsx';
4
- import { twMerge } from 'tailwind-merge';
5
-
6
- export function cn(...inputs: ClassValue[]) {
7
- return twMerge(clsx(inputs));
8
- }
9
3
 
10
4
  const MS_IN_SECOND = 1000;
11
5
  const MS_IN_MINUTE = 60 * MS_IN_SECOND;
@@ -80,6 +74,59 @@ export function formatDuration(ms: number, compact = false): string {
80
74
  return parts.join(' ');
81
75
  }
82
76
 
77
+ /**
78
+ * Formats a duration in milliseconds without snapping to whole seconds.
79
+ *
80
+ * Unlike {@link formatDuration}, this keeps sub-second detail, so 1626ms
81
+ * renders as "1.63s" rather than "2s". `fractionDigits` sets both the number of
82
+ * decimals on the seconds component (trailing zeros trimmed, so 2000ms is "2s"
83
+ * and 1500ms is "1.5s") and the rounding granularity — the default of 2 rounds
84
+ * to 10ms; the timeline ruler passes fewer digits to match its tick step.
85
+ *
86
+ * - < 1s: shows whole milliseconds (e.g. "626ms")
87
+ * - 1s – 1m: shows seconds with trimmed decimals (e.g. "1.63s", "1.5s", "45s")
88
+ * - >= 1m: decomposes into d/h/m with trimmed-decimal seconds (e.g. "1m 13.45s")
89
+ */
90
+ export function formatDurationPrecise(ms: number, fractionDigits = 2): string {
91
+ if (ms === 0) {
92
+ return '0s';
93
+ }
94
+
95
+ if (ms < MS_IN_SECOND) {
96
+ const roundedMs = Math.round(ms);
97
+ if (roundedMs < MS_IN_SECOND) {
98
+ return `${roundedMs}ms`;
99
+ }
100
+ }
101
+
102
+ const granularityMs = MS_IN_SECOND / 10 ** fractionDigits;
103
+ const normalizedMs = Math.round(ms / granularityMs) * granularityMs;
104
+
105
+ if (normalizedMs < MS_IN_MINUTE) {
106
+ return `${Number((normalizedMs / MS_IN_SECOND).toFixed(fractionDigits))}s`;
107
+ }
108
+
109
+ const days = Math.floor(normalizedMs / MS_IN_DAY);
110
+ const hours = Math.floor((normalizedMs % MS_IN_DAY) / MS_IN_HOUR);
111
+ const minutes = Math.floor((normalizedMs % MS_IN_HOUR) / MS_IN_MINUTE);
112
+ const seconds = (normalizedMs % MS_IN_MINUTE) / MS_IN_SECOND;
113
+
114
+ const parts: string[] = [];
115
+
116
+ if (days > 0) {
117
+ parts.push(`${days}d`);
118
+ }
119
+ if (hours > 0) {
120
+ parts.push(`${hours}h`);
121
+ }
122
+ if (minutes > 0) {
123
+ parts.push(`${minutes}m`);
124
+ }
125
+ parts.push(`${Number(seconds.toFixed(fractionDigits))}s`);
126
+
127
+ return parts.join(' ');
128
+ }
129
+
83
130
  /**
84
131
  * Returns a formatted pagination display string
85
132
  * @param currentPage - The current page number