@workflow/web-shared 5.0.0-beta.3 → 5.0.0-beta.30
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.
- package/README.md +2 -10
- package/dist/components/error-boundary.js +1 -1
- package/dist/components/event-list-view.d.ts +46 -1
- package/dist/components/event-list-view.d.ts.map +1 -1
- package/dist/components/event-list-view.js +228 -90
- package/dist/components/hook-actions.js +1 -1
- package/dist/components/index.d.ts +6 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +5 -2
- package/dist/components/new-trace-viewer/components/copy-button.js +3 -3
- package/dist/components/new-trace-viewer/components/detail-panel-width.d.ts +34 -0
- package/dist/components/new-trace-viewer/components/detail-panel-width.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/detail-panel-width.js +67 -0
- package/dist/components/new-trace-viewer/components/detail-panel.d.ts +14 -0
- package/dist/components/new-trace-viewer/components/detail-panel.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/detail-panel.js +122 -0
- package/dist/components/new-trace-viewer/components/draggable-border.d.ts +31 -0
- package/dist/components/new-trace-viewer/components/draggable-border.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/draggable-border.js +140 -0
- package/dist/components/new-trace-viewer/components/event-list.d.ts +4 -2
- package/dist/components/new-trace-viewer/components/event-list.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/components/event-list.js +22 -13
- package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.d.ts +18 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js +54 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.d.ts +20 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js +81 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts +25 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js +101 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.d.ts +20 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js +114 -0
- package/dist/components/new-trace-viewer/components/minimap.d.ts +14 -0
- package/dist/components/new-trace-viewer/components/minimap.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/minimap.js +337 -0
- package/dist/components/new-trace-viewer/components/pane-constants.d.ts +14 -0
- package/dist/components/new-trace-viewer/components/pane-constants.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/pane-constants.js +16 -0
- package/dist/components/new-trace-viewer/components/span-markers.d.ts +46 -0
- package/dist/components/new-trace-viewer/components/span-markers.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/span-markers.js +85 -0
- package/dist/components/new-trace-viewer/components/split-pane.d.ts +3 -7
- package/dist/components/new-trace-viewer/components/split-pane.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/components/split-pane.js +25 -84
- package/dist/components/new-trace-viewer/components/timeline.d.ts +19 -15
- package/dist/components/new-trace-viewer/components/timeline.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/components/timeline.js +229 -111
- package/dist/components/new-trace-viewer/components/timeline.module.css +46 -0
- package/dist/components/new-trace-viewer/components/trace-shortcut-helper.d.ts +5 -0
- package/dist/components/new-trace-viewer/components/trace-shortcut-helper.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/trace-shortcut-helper.js +55 -0
- package/dist/components/new-trace-viewer/components/trace-shortcut-helper.module.css +20 -0
- package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.d.ts +2 -0
- package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.js +26 -0
- package/dist/components/new-trace-viewer/components/use-element-width.d.ts +8 -0
- package/dist/components/new-trace-viewer/components/use-element-width.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/use-element-width.js +25 -0
- package/dist/components/new-trace-viewer/components/use-row-window.d.ts +34 -0
- package/dist/components/new-trace-viewer/components/use-row-window.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/use-row-window.js +107 -0
- package/dist/components/new-trace-viewer/context.d.ts +3 -1
- package/dist/components/new-trace-viewer/context.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/context.js +9 -10
- package/dist/components/new-trace-viewer/icons.js +3 -3
- package/dist/components/new-trace-viewer/search.d.ts +19 -0
- package/dist/components/new-trace-viewer/search.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/search.js +134 -0
- package/dist/components/new-trace-viewer/trace-viewer.d.ts +6 -3
- package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/trace-viewer.js +167 -162
- package/dist/components/new-trace-viewer/types.d.ts +2 -0
- package/dist/components/new-trace-viewer/types.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/types.js +2 -2
- package/dist/components/new-trace-viewer/utils.d.ts +48 -13
- package/dist/components/new-trace-viewer/utils.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/utils.js +135 -107
- package/dist/components/run-trace-view.d.ts +5 -7
- package/dist/components/run-trace-view.d.ts.map +1 -1
- package/dist/components/run-trace-view.js +3 -3
- package/dist/components/sidebar/attribute-panel.d.ts +4 -1
- package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
- package/dist/components/sidebar/attribute-panel.js +133 -113
- package/dist/components/sidebar/attributes-block.d.ts +40 -0
- package/dist/components/sidebar/attributes-block.d.ts.map +1 -0
- package/dist/components/sidebar/attributes-block.js +140 -0
- package/dist/components/sidebar/conversation-view.js +1 -1
- package/dist/components/sidebar/copyable-data-block.d.ts +2 -0
- package/dist/components/sidebar/copyable-data-block.d.ts.map +1 -1
- package/dist/components/sidebar/copyable-data-block.js +17 -16
- package/dist/components/sidebar/entity-detail-panel.d.ts +11 -11
- package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -1
- package/dist/components/sidebar/entity-detail-panel.js +35 -69
- package/dist/components/sidebar/events-list.d.ts +6 -2
- package/dist/components/sidebar/events-list.d.ts.map +1 -1
- package/dist/components/sidebar/events-list.js +76 -62
- package/dist/components/sidebar/resolve-hook-modal.js +1 -1
- package/dist/components/sidebar/sidebar-data-context.d.ts +10 -7
- package/dist/components/sidebar/sidebar-data-context.d.ts.map +1 -1
- package/dist/components/sidebar/sidebar-data-context.js +1 -1
- package/dist/components/sidebar/span-detail-merge.d.ts +31 -0
- package/dist/components/sidebar/span-detail-merge.d.ts.map +1 -0
- package/dist/components/sidebar/span-detail-merge.js +92 -0
- package/dist/components/sidebar/use-selected-span-detail.d.ts +16 -0
- package/dist/components/sidebar/use-selected-span-detail.d.ts.map +1 -0
- package/dist/components/sidebar/use-selected-span-detail.js +93 -0
- package/dist/components/stream-viewer.js +1 -1
- package/dist/components/trace-viewer/components/map.d.ts +2 -2
- package/dist/components/trace-viewer/components/map.d.ts.map +1 -1
- package/dist/components/trace-viewer/components/map.js +1 -1
- package/dist/components/trace-viewer/components/markers.js +1 -1
- package/dist/components/trace-viewer/components/node.d.ts +7 -7
- package/dist/components/trace-viewer/components/node.d.ts.map +1 -1
- package/dist/components/trace-viewer/components/node.js +2 -1
- package/dist/components/trace-viewer/components/search-input.js +1 -1
- package/dist/components/trace-viewer/components/search.js +1 -1
- package/dist/components/trace-viewer/components/span-content.js +1 -1
- package/dist/components/trace-viewer/components/span-detail-panel.js +1 -1
- package/dist/components/trace-viewer/components/span-segments.js +1 -1
- package/dist/components/trace-viewer/components/span-strategies.js +1 -1
- package/dist/components/trace-viewer/components/ui.js +1 -1
- package/dist/components/trace-viewer/components/zoom-button.js +1 -1
- package/dist/components/trace-viewer/components/zoom-icons.js +1 -1
- package/dist/components/trace-viewer/context.js +1 -1
- package/dist/components/trace-viewer/index.js +1 -1
- package/dist/components/trace-viewer/trace-viewer.js +1 -1
- package/dist/components/trace-viewer/trace-viewer.module.css +4 -4
- package/dist/components/trace-viewer/types.js +1 -1
- package/dist/components/trace-viewer/util/constants.js +1 -1
- package/dist/components/trace-viewer/util/scrollbar-width.js +1 -1
- package/dist/components/trace-viewer/util/timing.d.ts +3 -3
- package/dist/components/trace-viewer/util/timing.d.ts.map +1 -1
- package/dist/components/trace-viewer/util/timing.js +8 -11
- package/dist/components/trace-viewer/util/tree.js +1 -1
- package/dist/components/trace-viewer/util/use-immediate-style.js +1 -1
- package/dist/components/trace-viewer/util/use-streaming-spans.js +1 -1
- package/dist/components/trace-viewer/util/use-trackpad-zoom.js +1 -1
- package/dist/components/trace-viewer/worker.js +1 -1
- package/dist/components/trace-viewer-new.d.ts +5 -1
- package/dist/components/trace-viewer-new.d.ts.map +1 -1
- package/dist/components/trace-viewer-new.js +8 -10
- package/dist/components/ui/alert.js +2 -2
- package/dist/components/ui/button.d.ts +10 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +46 -0
- package/dist/components/ui/card.js +2 -2
- package/dist/components/ui/collapsible.d.ts +46 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/collapsible.js +66 -0
- package/dist/components/ui/context-card.d.ts +47 -0
- package/dist/components/ui/context-card.d.ts.map +1 -0
- package/dist/components/ui/context-card.js +471 -0
- package/dist/components/ui/data-inspector.d.ts +7 -6
- package/dist/components/ui/data-inspector.d.ts.map +1 -1
- package/dist/components/ui/data-inspector.js +232 -99
- package/dist/components/ui/data-inspector.styles.d.ts +29 -0
- package/dist/components/ui/data-inspector.styles.d.ts.map +1 -0
- package/dist/components/ui/data-inspector.styles.js +95 -0
- package/dist/components/ui/decrypt-button.js +1 -1
- package/dist/components/ui/error-card.js +2 -2
- package/dist/components/ui/error-stack-block.d.ts +17 -10
- package/dist/components/ui/error-stack-block.d.ts.map +1 -1
- package/dist/components/ui/error-stack-block.js +49 -30
- package/dist/components/ui/icon-button.d.ts +19 -0
- package/dist/components/ui/icon-button.d.ts.map +1 -0
- package/dist/components/ui/icon-button.js +29 -0
- package/dist/components/ui/kbd.d.ts +10 -0
- package/dist/components/ui/kbd.d.ts.map +1 -0
- package/dist/components/ui/kbd.js +25 -0
- package/dist/components/ui/load-more-button.js +1 -1
- package/dist/components/ui/menu-dropdown.js +1 -1
- package/dist/components/ui/skeleton.js +2 -2
- package/dist/components/ui/spinner.js +1 -1
- package/dist/components/ui/timestamp-tooltip.d.ts +34 -1
- package/dist/components/ui/timestamp-tooltip.d.ts.map +1 -1
- package/dist/components/ui/timestamp-tooltip.js +80 -132
- package/dist/components/ui/tooltip.d.ts +10 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/tooltip.js +12 -0
- package/dist/components/workflow-trace-view.d.ts +7 -8
- package/dist/components/workflow-trace-view.d.ts.map +1 -1
- package/dist/components/workflow-trace-view.js +11 -16
- package/dist/components/workflow-traces/event-colors.d.ts +2 -1
- package/dist/components/workflow-traces/event-colors.d.ts.map +1 -1
- package/dist/components/workflow-traces/event-colors.js +15 -7
- package/dist/components/workflow-traces/trace-colors.d.ts.map +1 -1
- package/dist/components/workflow-traces/trace-colors.js +3 -4
- package/dist/components/workflow-traces/trace-span-construction.d.ts +7 -4
- package/dist/components/workflow-traces/trace-span-construction.d.ts.map +1 -1
- package/dist/components/workflow-traces/trace-span-construction.js +87 -33
- package/dist/components/workflow-traces/trace-time-utils.js +1 -1
- package/dist/hooks/use-dark-mode.js +1 -1
- package/dist/hooks/use-intersection-observer.d.ts +17 -0
- package/dist/hooks/use-intersection-observer.d.ts.map +1 -0
- package/dist/hooks/use-intersection-observer.js +29 -0
- package/dist/hooks/use-load-more-on-scroll.d.ts +21 -0
- package/dist/hooks/use-load-more-on-scroll.d.ts.map +1 -0
- package/dist/hooks/use-load-more-on-scroll.js +28 -0
- package/dist/hooks/use-reduced-motion.d.ts +10 -0
- package/dist/hooks/use-reduced-motion.d.ts.map +1 -0
- package/dist/hooks/use-reduced-motion.js +29 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/lib/cn.d.ts +10 -0
- package/dist/lib/cn.d.ts.map +1 -0
- package/dist/lib/cn.js +83 -0
- package/dist/lib/event-analysis.d.ts +1 -1
- package/dist/lib/event-analysis.d.ts.map +1 -1
- package/dist/lib/event-analysis.js +3 -2
- package/dist/lib/event-materialization.d.ts +1 -1
- package/dist/lib/event-materialization.d.ts.map +1 -1
- package/dist/lib/event-materialization.js +29 -21
- package/dist/lib/exact-event-search-id.d.ts +25 -0
- package/dist/lib/exact-event-search-id.d.ts.map +1 -0
- package/dist/lib/exact-event-search-id.js +39 -0
- package/dist/lib/hydration.d.ts +17 -2
- package/dist/lib/hydration.d.ts.map +1 -1
- package/dist/lib/hydration.js +185 -22
- package/dist/lib/stream-display.js +1 -1
- package/dist/lib/toast.js +1 -1
- package/dist/lib/trace-builder.d.ts +16 -4
- package/dist/lib/trace-builder.d.ts.map +1 -1
- package/dist/lib/trace-builder.js +34 -15
- package/dist/lib/utils.d.ts +23 -9
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +73 -33
- package/dist/lib/zstd-browser-decoder.d.ts +7 -0
- package/dist/lib/zstd-browser-decoder.d.ts.map +1 -0
- package/dist/lib/zstd-browser-decoder.js +41 -0
- package/dist/styles.css +14 -0
- package/package.json +10 -7
- package/src/components/event-list-view.tsx +375 -116
- package/src/components/index.ts +12 -5
- package/src/components/new-trace-viewer/components/copy-button.tsx +2 -2
- package/src/components/new-trace-viewer/components/detail-panel-width.test.ts +123 -0
- package/src/components/new-trace-viewer/components/detail-panel-width.ts +76 -0
- package/src/components/new-trace-viewer/components/detail-panel.tsx +273 -0
- package/src/components/new-trace-viewer/components/draggable-border.tsx +216 -0
- package/src/components/new-trace-viewer/components/event-list.tsx +57 -32
- package/src/components/new-trace-viewer/components/middle-truncate/copy-selection.ts +114 -0
- package/src/components/new-trace-viewer/components/middle-truncate/middle-truncate.tsx +157 -0
- package/src/components/new-trace-viewer/components/middle-truncate/truncate.ts +132 -0
- package/src/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.ts +167 -0
- package/src/components/new-trace-viewer/components/minimap.tsx +559 -0
- package/src/components/new-trace-viewer/components/pane-constants.ts +19 -0
- package/src/components/new-trace-viewer/components/span-markers.tsx +173 -0
- package/src/components/new-trace-viewer/components/split-pane.tsx +80 -135
- package/src/components/new-trace-viewer/components/timeline.module.css +46 -0
- package/src/components/new-trace-viewer/components/timeline.tsx +603 -239
- package/src/components/new-trace-viewer/components/trace-shortcut-helper.module.css +20 -0
- package/src/components/new-trace-viewer/components/trace-shortcut-helper.tsx +116 -0
- package/src/components/new-trace-viewer/components/trace-viewer-skeleton.tsx +114 -0
- package/src/components/new-trace-viewer/components/use-element-width.ts +29 -0
- package/src/components/new-trace-viewer/components/use-row-window.ts +140 -0
- package/src/components/new-trace-viewer/context.tsx +13 -14
- package/src/components/new-trace-viewer/icons.tsx +2 -2
- package/src/components/new-trace-viewer/search.ts +178 -0
- package/src/components/new-trace-viewer/trace-viewer.tsx +336 -293
- package/src/components/new-trace-viewer/types.ts +2 -0
- package/src/components/new-trace-viewer/utils.test.ts +247 -0
- package/src/components/new-trace-viewer/utils.ts +203 -134
- package/src/components/run-trace-view.tsx +10 -14
- package/src/components/sidebar/attribute-panel.tsx +276 -275
- package/src/components/sidebar/attributes-block.tsx +326 -0
- package/src/components/sidebar/copyable-data-block.tsx +50 -28
- package/src/components/sidebar/entity-detail-panel.tsx +89 -123
- package/src/components/sidebar/events-list.tsx +196 -178
- package/src/components/sidebar/sidebar-data-context.tsx +11 -11
- package/src/components/sidebar/span-detail-merge.ts +134 -0
- package/src/components/sidebar/use-selected-span-detail.ts +146 -0
- package/src/components/trace-viewer/components/node.tsx +3 -2
- package/src/components/trace-viewer/trace-viewer.module.css +4 -4
- package/src/components/trace-viewer/util/timing.ts +7 -11
- package/src/components/trace-viewer-new.tsx +21 -15
- package/src/components/ui/alert.tsx +1 -1
- package/src/components/ui/button.tsx +68 -0
- package/src/components/ui/card.tsx +1 -1
- package/src/components/ui/collapsible.tsx +219 -0
- package/src/components/ui/context-card.tsx +784 -0
- package/src/components/ui/data-inspector.styles.ts +96 -0
- package/src/components/ui/data-inspector.tsx +501 -204
- package/src/components/ui/error-card.tsx +1 -1
- package/src/components/ui/error-stack-block.tsx +84 -55
- package/src/components/ui/icon-button.tsx +53 -0
- package/src/components/ui/kbd.tsx +43 -0
- package/src/components/ui/skeleton.tsx +1 -1
- package/src/components/ui/timestamp-tooltip.tsx +132 -194
- package/src/components/ui/tooltip.tsx +47 -0
- package/src/components/workflow-trace-view.tsx +31 -36
- package/src/components/workflow-traces/event-colors.ts +15 -11
- package/src/components/workflow-traces/trace-colors.ts +6 -6
- package/src/components/workflow-traces/trace-span-construction.test.ts +85 -0
- package/src/components/workflow-traces/trace-span-construction.ts +118 -35
- package/src/hooks/use-intersection-observer.ts +57 -0
- package/src/hooks/use-load-more-on-scroll.ts +49 -0
- package/src/hooks/use-reduced-motion.ts +34 -0
- package/src/index.ts +9 -0
- package/src/lib/cn.ts +93 -0
- package/src/lib/event-analysis.ts +6 -4
- package/src/lib/event-materialization.ts +35 -21
- package/src/lib/exact-event-search-id.ts +67 -0
- package/src/lib/hydration.ts +203 -29
- package/src/lib/trace-builder.ts +44 -19
- package/src/lib/utils.test.ts +33 -0
- package/src/lib/utils.ts +82 -35
- package/src/lib/zstd-browser-decoder.ts +42 -0
- package/src/styles.css +14 -0
- package/dist/components/error-boundary.js.map +0 -1
- package/dist/components/event-list-view.js.map +0 -1
- package/dist/components/hook-actions.js.map +0 -1
- package/dist/components/index.js.map +0 -1
- package/dist/components/new-trace-viewer/components/copy-button.js.map +0 -1
- package/dist/components/new-trace-viewer/components/event-list.js.map +0 -1
- package/dist/components/new-trace-viewer/components/split-pane.js.map +0 -1
- package/dist/components/new-trace-viewer/components/timeline.js.map +0 -1
- package/dist/components/new-trace-viewer/context.js.map +0 -1
- package/dist/components/new-trace-viewer/detail-panel.d.ts +0 -10
- package/dist/components/new-trace-viewer/detail-panel.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/detail-panel.js +0 -11
- package/dist/components/new-trace-viewer/detail-panel.js.map +0 -1
- package/dist/components/new-trace-viewer/icons.js.map +0 -1
- package/dist/components/new-trace-viewer/trace-viewer.js.map +0 -1
- package/dist/components/new-trace-viewer/types.js.map +0 -1
- package/dist/components/new-trace-viewer/util/constants.d.ts +0 -1
- package/dist/components/new-trace-viewer/util/constants.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/util/constants.js +0 -2
- package/dist/components/new-trace-viewer/util/constants.js.map +0 -1
- package/dist/components/new-trace-viewer/utils.js.map +0 -1
- package/dist/components/run-trace-view.js.map +0 -1
- package/dist/components/sidebar/attribute-panel.js.map +0 -1
- package/dist/components/sidebar/conversation-view.js.map +0 -1
- package/dist/components/sidebar/copyable-data-block.js.map +0 -1
- package/dist/components/sidebar/detail-card.d.ts +0 -14
- package/dist/components/sidebar/detail-card.d.ts.map +0 -1
- package/dist/components/sidebar/detail-card.js +0 -20
- package/dist/components/sidebar/detail-card.js.map +0 -1
- package/dist/components/sidebar/entity-detail-panel.js.map +0 -1
- package/dist/components/sidebar/events-list.js.map +0 -1
- package/dist/components/sidebar/resolve-hook-modal.js.map +0 -1
- package/dist/components/sidebar/sidebar-data-context.js.map +0 -1
- package/dist/components/stream-viewer.js.map +0 -1
- package/dist/components/trace-viewer/components/map.js.map +0 -1
- package/dist/components/trace-viewer/components/markers.js.map +0 -1
- package/dist/components/trace-viewer/components/node.js.map +0 -1
- package/dist/components/trace-viewer/components/search-input.js.map +0 -1
- package/dist/components/trace-viewer/components/search.js.map +0 -1
- package/dist/components/trace-viewer/components/span-content.js.map +0 -1
- package/dist/components/trace-viewer/components/span-detail-panel.js.map +0 -1
- package/dist/components/trace-viewer/components/span-segments.js.map +0 -1
- package/dist/components/trace-viewer/components/span-strategies.js.map +0 -1
- package/dist/components/trace-viewer/components/ui.js.map +0 -1
- package/dist/components/trace-viewer/components/zoom-button.js.map +0 -1
- package/dist/components/trace-viewer/components/zoom-icons.js.map +0 -1
- package/dist/components/trace-viewer/context.js.map +0 -1
- package/dist/components/trace-viewer/index.js.map +0 -1
- package/dist/components/trace-viewer/trace-viewer.js.map +0 -1
- package/dist/components/trace-viewer/types.js.map +0 -1
- package/dist/components/trace-viewer/util/constants.js.map +0 -1
- package/dist/components/trace-viewer/util/scrollbar-width.js.map +0 -1
- package/dist/components/trace-viewer/util/timing.js.map +0 -1
- package/dist/components/trace-viewer/util/tree.js.map +0 -1
- package/dist/components/trace-viewer/util/use-immediate-style.js.map +0 -1
- package/dist/components/trace-viewer/util/use-streaming-spans.js.map +0 -1
- package/dist/components/trace-viewer/util/use-trackpad-zoom.js.map +0 -1
- package/dist/components/trace-viewer/worker.js.map +0 -1
- package/dist/components/trace-viewer-new.js.map +0 -1
- package/dist/components/ui/alert.js.map +0 -1
- package/dist/components/ui/card.js.map +0 -1
- package/dist/components/ui/data-inspector.js.map +0 -1
- package/dist/components/ui/decrypt-button.js.map +0 -1
- package/dist/components/ui/error-card.js.map +0 -1
- package/dist/components/ui/error-stack-block.js.map +0 -1
- package/dist/components/ui/inspector-theme.d.ts +0 -95
- package/dist/components/ui/inspector-theme.d.ts.map +0 -1
- package/dist/components/ui/inspector-theme.js +0 -82
- package/dist/components/ui/inspector-theme.js.map +0 -1
- package/dist/components/ui/load-more-button.js.map +0 -1
- package/dist/components/ui/menu-dropdown.js.map +0 -1
- package/dist/components/ui/skeleton.js.map +0 -1
- package/dist/components/ui/spinner.js.map +0 -1
- package/dist/components/ui/timestamp-tooltip.js.map +0 -1
- package/dist/components/workflow-trace-view.js.map +0 -1
- package/dist/components/workflow-traces/event-colors.js.map +0 -1
- package/dist/components/workflow-traces/trace-colors.js.map +0 -1
- package/dist/components/workflow-traces/trace-span-construction.js.map +0 -1
- package/dist/components/workflow-traces/trace-time-utils.js.map +0 -1
- package/dist/hooks/use-dark-mode.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/event-analysis.js.map +0 -1
- package/dist/lib/event-materialization.js.map +0 -1
- package/dist/lib/hydration.js.map +0 -1
- package/dist/lib/stream-display.js.map +0 -1
- package/dist/lib/toast.js.map +0 -1
- package/dist/lib/trace-builder.js.map +0 -1
- package/dist/lib/utils.js.map +0 -1
- package/src/components/new-trace-viewer/detail-panel.tsx +0 -57
- package/src/components/new-trace-viewer/util/constants.ts +0 -0
- package/src/components/sidebar/detail-card.tsx +0 -65
- package/src/components/ui/inspector-theme.ts +0 -110
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
* Color utilities for workflow traces
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import {
|
|
6
|
+
isHookLifecycleEventType,
|
|
7
|
+
type Step,
|
|
8
|
+
type WorkflowRun,
|
|
9
|
+
} from '@workflow/world';
|
|
6
10
|
import styles from '../trace-viewer/trace-viewer.module.css';
|
|
7
11
|
import type { SpanNode, SpanNodeEvent } from '../trace-viewer/types';
|
|
8
12
|
|
|
@@ -99,11 +103,7 @@ export const getCustomSpanEventClassName = (
|
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
// Webhook-related events - Purple
|
|
102
|
-
if (
|
|
103
|
-
eventName === 'hook_created' ||
|
|
104
|
-
eventName === 'hook_received' ||
|
|
105
|
-
eventName === 'hook_disposed'
|
|
106
|
-
) {
|
|
106
|
+
if (isHookLifecycleEventType(eventName)) {
|
|
107
107
|
return styles.eventHook;
|
|
108
108
|
}
|
|
109
109
|
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { Event, WorkflowRun } from '@workflow/world';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { runToSpan } from './trace-span-construction';
|
|
4
|
+
import { otelTimeToMs } from './trace-time-utils';
|
|
5
|
+
|
|
6
|
+
const date = (ms: number) => new Date(ms);
|
|
7
|
+
|
|
8
|
+
function run(overrides: Partial<WorkflowRun> = {}): WorkflowRun {
|
|
9
|
+
return {
|
|
10
|
+
runId: 'run_1',
|
|
11
|
+
status: 'completed',
|
|
12
|
+
deploymentId: 'dpl_1',
|
|
13
|
+
workflowName: 'workflow//./workflow//testWorkflow',
|
|
14
|
+
specVersion: 2,
|
|
15
|
+
attributes: {},
|
|
16
|
+
createdAt: date(1_000),
|
|
17
|
+
updatedAt: date(6_000),
|
|
18
|
+
startedAt: date(2_000),
|
|
19
|
+
completedAt: date(6_000),
|
|
20
|
+
output: null,
|
|
21
|
+
...overrides,
|
|
22
|
+
} as WorkflowRun;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function event(overrides: Partial<Event>): Event {
|
|
26
|
+
return {
|
|
27
|
+
runId: 'run_1',
|
|
28
|
+
eventId: `evt_${overrides.eventType ?? 'unknown'}`,
|
|
29
|
+
eventType: 'run_created',
|
|
30
|
+
createdAt: date(1_000),
|
|
31
|
+
specVersion: 2,
|
|
32
|
+
eventData: {
|
|
33
|
+
deploymentId: 'dpl_1',
|
|
34
|
+
workflowName: 'workflow//./workflow//testWorkflow',
|
|
35
|
+
input: null,
|
|
36
|
+
},
|
|
37
|
+
...overrides,
|
|
38
|
+
} as Event;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
describe('runToSpan', () => {
|
|
42
|
+
it('prefers occurredAt for run span timing when available', () => {
|
|
43
|
+
const span = runToSpan(
|
|
44
|
+
run(),
|
|
45
|
+
[
|
|
46
|
+
event({
|
|
47
|
+
eventType: 'run_created',
|
|
48
|
+
createdAt: date(1_000),
|
|
49
|
+
occurredAt: date(100),
|
|
50
|
+
}),
|
|
51
|
+
event({
|
|
52
|
+
eventType: 'run_started',
|
|
53
|
+
createdAt: date(2_000),
|
|
54
|
+
occurredAt: date(200),
|
|
55
|
+
}),
|
|
56
|
+
event({
|
|
57
|
+
eventType: 'run_completed',
|
|
58
|
+
createdAt: date(6_000),
|
|
59
|
+
occurredAt: date(500),
|
|
60
|
+
}),
|
|
61
|
+
],
|
|
62
|
+
date(10_000)
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
expect(otelTimeToMs(span.startTime)).toBe(100);
|
|
66
|
+
expect(
|
|
67
|
+
span.activeStartTime ? otelTimeToMs(span.activeStartTime) : undefined
|
|
68
|
+
).toBe(200);
|
|
69
|
+
expect(otelTimeToMs(span.endTime)).toBe(500);
|
|
70
|
+
expect(
|
|
71
|
+
span.events.find((e) => e.name === 'run_created')?.timestamp
|
|
72
|
+
).toEqual([0, 100_000_000]);
|
|
73
|
+
|
|
74
|
+
const data = span.attributes.data as {
|
|
75
|
+
createdAt: Date;
|
|
76
|
+
startedAt?: Date;
|
|
77
|
+
completedAt?: Date;
|
|
78
|
+
occurredAt?: Date;
|
|
79
|
+
};
|
|
80
|
+
expect(data.createdAt).toEqual(date(100));
|
|
81
|
+
expect(data.startedAt).toEqual(date(200));
|
|
82
|
+
expect(data.completedAt).toEqual(date(500));
|
|
83
|
+
expect(data).not.toHaveProperty('occurredAt');
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { parseStepName, parseWorkflowName } from '@workflow/utils/parse-name';
|
|
6
|
-
import
|
|
6
|
+
import {
|
|
7
|
+
type Event,
|
|
8
|
+
isTerminalStepEventType,
|
|
9
|
+
type WorkflowRun,
|
|
10
|
+
} from '@workflow/world';
|
|
7
11
|
import type { Span, SpanEvent } from '../trace-viewer/types';
|
|
8
12
|
import { shouldShowVerticalLine } from './event-colors';
|
|
9
13
|
import { calculateDuration, dateToOtelTime } from './trace-time-utils';
|
|
@@ -26,15 +30,27 @@ const MARKER_EVENT_TYPES: Set<Event['eventType']> = new Set([
|
|
|
26
30
|
'run_failed',
|
|
27
31
|
'wait_created',
|
|
28
32
|
'wait_completed',
|
|
33
|
+
'attr_set',
|
|
29
34
|
]);
|
|
30
35
|
|
|
36
|
+
export const getEventTimestamp = (
|
|
37
|
+
event: Event | undefined
|
|
38
|
+
): Date | undefined => {
|
|
39
|
+
const value = event?.occurredAt ?? event?.createdAt;
|
|
40
|
+
if (!value) return undefined;
|
|
41
|
+
|
|
42
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
43
|
+
return Number.isNaN(date.getTime()) ? undefined : date;
|
|
44
|
+
};
|
|
45
|
+
|
|
31
46
|
/**
|
|
32
47
|
* Convert workflow events to span events
|
|
33
48
|
* Only includes events that should be displayed as markers
|
|
34
49
|
*/
|
|
35
50
|
export function convertEventsToSpanEvents(
|
|
36
51
|
events: Event[],
|
|
37
|
-
filterTypes = true
|
|
52
|
+
filterTypes = true,
|
|
53
|
+
options: { preferOccurredAt?: boolean } = {}
|
|
38
54
|
): SpanEvent[] {
|
|
39
55
|
return events
|
|
40
56
|
.filter((event) =>
|
|
@@ -42,7 +58,11 @@ export function convertEventsToSpanEvents(
|
|
|
42
58
|
)
|
|
43
59
|
.map((event) => ({
|
|
44
60
|
name: event.eventType,
|
|
45
|
-
timestamp: dateToOtelTime(
|
|
61
|
+
timestamp: dateToOtelTime(
|
|
62
|
+
options.preferOccurredAt
|
|
63
|
+
? (getEventTimestamp(event) ?? event.createdAt)
|
|
64
|
+
: event.createdAt
|
|
65
|
+
),
|
|
46
66
|
attributes: {
|
|
47
67
|
eventId: event.eventId,
|
|
48
68
|
correlationId: event.correlationId,
|
|
@@ -59,7 +79,7 @@ export const waitEventsToWaitEntity = (
|
|
|
59
79
|
waitId: string;
|
|
60
80
|
runId: string;
|
|
61
81
|
createdAt: Date;
|
|
62
|
-
resumeAt
|
|
82
|
+
resumeAt?: Date;
|
|
63
83
|
completedAt?: Date;
|
|
64
84
|
} | null => {
|
|
65
85
|
const startEvent = events.find((event) => event.eventType === 'wait_created');
|
|
@@ -72,22 +92,40 @@ export const waitEventsToWaitEntity = (
|
|
|
72
92
|
return {
|
|
73
93
|
waitId: startEvent.correlationId,
|
|
74
94
|
runId: startEvent.runId,
|
|
75
|
-
createdAt: startEvent.createdAt,
|
|
76
|
-
resumeAt: startEvent.eventData?.resumeAt
|
|
77
|
-
|
|
95
|
+
createdAt: getEventTimestamp(startEvent) ?? startEvent.createdAt,
|
|
96
|
+
resumeAt: startEvent.eventData?.resumeAt
|
|
97
|
+
? new Date(startEvent.eventData.resumeAt)
|
|
98
|
+
: undefined,
|
|
99
|
+
completedAt: getEventTimestamp(completedEvent),
|
|
78
100
|
};
|
|
79
101
|
};
|
|
80
102
|
|
|
81
103
|
/**
|
|
82
104
|
* Converts a workflow Wait to an OpenTelemetry Span
|
|
83
105
|
*/
|
|
84
|
-
export function waitToSpan(
|
|
106
|
+
export function waitToSpan(
|
|
107
|
+
events: Event[],
|
|
108
|
+
maxEndTime: Date,
|
|
109
|
+
fallbackEndTime = maxEndTime
|
|
110
|
+
): Span | null {
|
|
85
111
|
const wait = waitEventsToWaitEntity(events);
|
|
86
112
|
if (!wait) {
|
|
87
113
|
return null;
|
|
88
114
|
}
|
|
89
115
|
const startTime = wait.createdAt;
|
|
90
|
-
const
|
|
116
|
+
const startMs = startTime.getTime();
|
|
117
|
+
let endTime = wait.completedAt;
|
|
118
|
+
if (!endTime) {
|
|
119
|
+
const fallbackCap =
|
|
120
|
+
wait.resumeAt && wait.resumeAt.getTime() < fallbackEndTime.getTime()
|
|
121
|
+
? wait.resumeAt
|
|
122
|
+
: fallbackEndTime;
|
|
123
|
+
endTime =
|
|
124
|
+
maxEndTime.getTime() > startMs &&
|
|
125
|
+
maxEndTime.getTime() < fallbackCap.getTime()
|
|
126
|
+
? maxEndTime
|
|
127
|
+
: fallbackCap;
|
|
128
|
+
}
|
|
91
129
|
const start = dateToOtelTime(startTime);
|
|
92
130
|
const end = dateToOtelTime(endTime);
|
|
93
131
|
const duration = calculateDuration(startTime, endTime);
|
|
@@ -150,16 +188,16 @@ export const stepEventsToStepEntity = (
|
|
|
150
188
|
case 'step_started':
|
|
151
189
|
status = 'running';
|
|
152
190
|
attempt += 1;
|
|
153
|
-
if (!startedAt) startedAt = e.createdAt;
|
|
191
|
+
if (!startedAt) startedAt = getEventTimestamp(e) ?? e.createdAt;
|
|
154
192
|
completedAt = undefined;
|
|
155
193
|
break;
|
|
156
194
|
case 'step_completed':
|
|
157
195
|
status = 'completed';
|
|
158
|
-
completedAt = e.createdAt;
|
|
196
|
+
completedAt = getEventTimestamp(e) ?? e.createdAt;
|
|
159
197
|
break;
|
|
160
198
|
case 'step_failed':
|
|
161
199
|
status = 'failed';
|
|
162
|
-
completedAt = e.createdAt;
|
|
200
|
+
completedAt = getEventTimestamp(e) ?? e.createdAt;
|
|
163
201
|
break;
|
|
164
202
|
case 'step_retrying':
|
|
165
203
|
status = 'pending';
|
|
@@ -172,14 +210,18 @@ export const stepEventsToStepEntity = (
|
|
|
172
210
|
if (attempt === 0) attempt = 1;
|
|
173
211
|
|
|
174
212
|
const lastEvent = events[events.length - 1];
|
|
213
|
+
|
|
175
214
|
return {
|
|
176
215
|
stepId: anchorEvent.correlationId ?? '',
|
|
177
216
|
runId: anchorEvent.runId,
|
|
178
217
|
stepName: createdEvent?.eventData?.stepName ?? '',
|
|
179
218
|
status,
|
|
180
219
|
attempt,
|
|
181
|
-
createdAt: anchorEvent.createdAt,
|
|
182
|
-
updatedAt:
|
|
220
|
+
createdAt: getEventTimestamp(anchorEvent) ?? anchorEvent.createdAt,
|
|
221
|
+
updatedAt:
|
|
222
|
+
getEventTimestamp(lastEvent) ??
|
|
223
|
+
lastEvent?.createdAt ??
|
|
224
|
+
anchorEvent.createdAt,
|
|
183
225
|
startedAt,
|
|
184
226
|
completedAt,
|
|
185
227
|
specVersion: anchorEvent.specVersion,
|
|
@@ -202,25 +244,37 @@ export function stepToSpan(stepEvents: Event[], maxEndTime: Date): Span | null {
|
|
|
202
244
|
};
|
|
203
245
|
|
|
204
246
|
const resource = 'step';
|
|
205
|
-
const endTime = new Date(step.completedAt ?? maxEndTime);
|
|
206
247
|
|
|
207
248
|
// Include ALL correlated events on the span so the sidebar detail view
|
|
208
249
|
// can display them. The timeline uses the `showVerticalLine` flag to
|
|
209
250
|
// determine which events appear as markers.
|
|
210
|
-
const events = convertEventsToSpanEvents(stepEvents, false
|
|
251
|
+
const events = convertEventsToSpanEvents(stepEvents, false, {
|
|
252
|
+
preferOccurredAt: true,
|
|
253
|
+
});
|
|
211
254
|
|
|
212
|
-
// Use
|
|
213
|
-
//
|
|
214
|
-
const
|
|
255
|
+
// Use the event occurrence timestamp for step spans when it is available,
|
|
256
|
+
// falling back to the ingest timestamp used by older event streams.
|
|
257
|
+
const spanStartEvent =
|
|
258
|
+
stepEvents.find((event) => event.eventType === 'step_created') ??
|
|
259
|
+
stepEvents[0];
|
|
260
|
+
const spanStartTime =
|
|
261
|
+
getEventTimestamp(spanStartEvent) ?? new Date(step.createdAt);
|
|
215
262
|
let activeStartTime = step.startedAt ? new Date(step.startedAt) : undefined;
|
|
216
263
|
const firstStartEvent = stepEvents.find(
|
|
217
264
|
(event) => event.eventType === 'step_started'
|
|
218
265
|
);
|
|
219
266
|
if (firstStartEvent) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
267
|
+
activeStartTime =
|
|
268
|
+
getEventTimestamp(firstStartEvent) ?? new Date(firstStartEvent.createdAt);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
let endTime = new Date(maxEndTime);
|
|
272
|
+
if (step.completedAt) {
|
|
273
|
+
const completedEvent = stepEvents
|
|
274
|
+
.slice()
|
|
275
|
+
.reverse()
|
|
276
|
+
.find((event) => isTerminalStepEventType(event.eventType));
|
|
277
|
+
endTime = getEventTimestamp(completedEvent) ?? new Date(step.completedAt);
|
|
224
278
|
}
|
|
225
279
|
|
|
226
280
|
return {
|
|
@@ -273,10 +327,10 @@ export const hookEventsToHookEntity = (
|
|
|
273
327
|
hookId: createdEvent.correlationId,
|
|
274
328
|
runId: createdEvent.runId,
|
|
275
329
|
token: createdEvent.eventData?.token,
|
|
276
|
-
createdAt: createdEvent.createdAt,
|
|
330
|
+
createdAt: getEventTimestamp(createdEvent) ?? createdEvent.createdAt,
|
|
277
331
|
receivedCount: receivedEvents.length,
|
|
278
|
-
lastReceivedAt: lastReceivedEvent
|
|
279
|
-
disposedAt: disposedEvents.at(-1)
|
|
332
|
+
lastReceivedAt: getEventTimestamp(lastReceivedEvent),
|
|
333
|
+
disposedAt: getEventTimestamp(disposedEvents.at(-1)),
|
|
280
334
|
};
|
|
281
335
|
};
|
|
282
336
|
|
|
@@ -296,7 +350,7 @@ export function hookToSpan(hookEvents: Event[], maxEndTime: Date): Span | null {
|
|
|
296
350
|
|
|
297
351
|
return {
|
|
298
352
|
spanId: String(hook.hookId),
|
|
299
|
-
name: String(hook.hookId),
|
|
353
|
+
name: hook.token ?? String(hook.hookId),
|
|
300
354
|
kind: 1, // INTERNAL span kind
|
|
301
355
|
resource: 'hook',
|
|
302
356
|
library: WORKFLOW_LIBRARY,
|
|
@@ -324,21 +378,50 @@ export function runToSpan(
|
|
|
324
378
|
): Span {
|
|
325
379
|
const now = nowTime ?? new Date();
|
|
326
380
|
|
|
381
|
+
// Prefer the event occurrence timestamp when available so the root span
|
|
382
|
+
// lines up with child spans that already use event occurrence time.
|
|
383
|
+
const runCreatedEvent = runEvents.find(
|
|
384
|
+
(event) => event.eventType === 'run_created'
|
|
385
|
+
);
|
|
386
|
+
const runStartedEvent = runEvents.find(
|
|
387
|
+
(event) => event.eventType === 'run_started'
|
|
388
|
+
);
|
|
389
|
+
const terminalEvent = runEvents
|
|
390
|
+
.slice()
|
|
391
|
+
.reverse()
|
|
392
|
+
.find(
|
|
393
|
+
(event) =>
|
|
394
|
+
event.eventType === 'run_completed' ||
|
|
395
|
+
event.eventType === 'run_failed' ||
|
|
396
|
+
event.eventType === 'run_cancelled'
|
|
397
|
+
);
|
|
398
|
+
const spanStartTime =
|
|
399
|
+
getEventTimestamp(runCreatedEvent) ?? new Date(run.createdAt);
|
|
400
|
+
const activeStartTime =
|
|
401
|
+
getEventTimestamp(runStartedEvent) ??
|
|
402
|
+
(run.startedAt ? new Date(run.startedAt) : undefined);
|
|
403
|
+
const completedAt =
|
|
404
|
+
getEventTimestamp(terminalEvent) ?? run.completedAt ?? undefined;
|
|
405
|
+
const endTime = completedAt ?? now;
|
|
406
|
+
|
|
327
407
|
// Only embed identification fields — not the full object with
|
|
328
|
-
// input/output/error which may contain non-cloneable types.
|
|
408
|
+
// input/output/error which may contain non-cloneable types. Lifecycle
|
|
409
|
+
// timestamps are event-derived so detail rows align with the span timeline.
|
|
329
410
|
const { input: _i, output: _o, error: _e, ...runIdentity } = run;
|
|
330
411
|
const attributes = {
|
|
331
412
|
resource: 'run' as const,
|
|
332
|
-
data:
|
|
413
|
+
data: {
|
|
414
|
+
...runIdentity,
|
|
415
|
+
createdAt: spanStartTime,
|
|
416
|
+
startedAt: activeStartTime,
|
|
417
|
+
completedAt,
|
|
418
|
+
},
|
|
333
419
|
};
|
|
334
420
|
|
|
335
|
-
// Use createdAt as span start time, with activeStartTime for when execution began
|
|
336
|
-
const spanStartTime = new Date(run.createdAt);
|
|
337
|
-
const activeStartTime = run.startedAt ? new Date(run.startedAt) : undefined;
|
|
338
|
-
const endTime = run.completedAt ?? now;
|
|
339
|
-
|
|
340
421
|
// Convert run-level events to span events
|
|
341
|
-
const events = convertEventsToSpanEvents(runEvents, false
|
|
422
|
+
const events = convertEventsToSpanEvents(runEvents, false, {
|
|
423
|
+
preferOccurredAt: true,
|
|
424
|
+
});
|
|
342
425
|
|
|
343
426
|
return {
|
|
344
427
|
spanId: String(run.runId),
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { RefObject } from 'react';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
|
|
6
|
+
interface UseIntersectionObserverArgs
|
|
7
|
+
extends Omit<IntersectionObserverInit, 'root'> {
|
|
8
|
+
/**
|
|
9
|
+
* Scroll container the target is observed within. Defaults to the viewport.
|
|
10
|
+
* Passed as a ref so it resolves after commit (when the node exists).
|
|
11
|
+
*/
|
|
12
|
+
rootRef?: RefObject<Element | null>;
|
|
13
|
+
freezeOnceVisible?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Returns the latest IntersectionObserverEntry for `elementRef`.
|
|
18
|
+
* Ported from vercel/front's `@vercel/hooks` `useIntersectionObserver`, with
|
|
19
|
+
* `root` threaded as a ref so we can observe inside a custom scroll container.
|
|
20
|
+
*/
|
|
21
|
+
export function useIntersectionObserver(
|
|
22
|
+
elementRef: RefObject<Element | null>,
|
|
23
|
+
{
|
|
24
|
+
threshold = 0,
|
|
25
|
+
rootRef,
|
|
26
|
+
rootMargin = '0%',
|
|
27
|
+
freezeOnceVisible = false,
|
|
28
|
+
}: UseIntersectionObserverArgs = {}
|
|
29
|
+
): IntersectionObserverEntry | undefined {
|
|
30
|
+
const [entry, setEntry] = useState<IntersectionObserverEntry>();
|
|
31
|
+
|
|
32
|
+
const frozen = entry?.isIntersecting && freezeOnceVisible;
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
const node = elementRef?.current;
|
|
36
|
+
|
|
37
|
+
const hasIOSupport = !!window.IntersectionObserver;
|
|
38
|
+
|
|
39
|
+
if (!hasIOSupport || frozen || !node) return;
|
|
40
|
+
|
|
41
|
+
const updateEntry = ([entry]: IntersectionObserverEntry[]): void => {
|
|
42
|
+
setEntry(entry);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const observer = new IntersectionObserver(updateEntry, {
|
|
46
|
+
threshold,
|
|
47
|
+
root: rootRef?.current ?? null,
|
|
48
|
+
rootMargin,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
observer.observe(node);
|
|
52
|
+
|
|
53
|
+
return () => observer.disconnect();
|
|
54
|
+
}, [elementRef, threshold, rootRef, rootMargin, frozen]);
|
|
55
|
+
|
|
56
|
+
return entry;
|
|
57
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { RefObject } from 'react';
|
|
4
|
+
import { useEffect, useRef } from 'react';
|
|
5
|
+
import { useIntersectionObserver } from './use-intersection-observer';
|
|
6
|
+
|
|
7
|
+
interface UseLoadMoreOnScrollOptions {
|
|
8
|
+
hasMore: boolean;
|
|
9
|
+
isLoadingMore: boolean;
|
|
10
|
+
/** Scroll container the sentinel lives in. Defaults to the viewport. */
|
|
11
|
+
rootRef?: RefObject<Element | null>;
|
|
12
|
+
rootMargin?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Triggers `loadMore` when a sentinel element scrolls into view.
|
|
17
|
+
* Returns a ref to attach to an invisible sentinel `<div>` placed after the
|
|
18
|
+
* list content. Ported from vercel/front's `@vercel/hooks`
|
|
19
|
+
* `useLoadMoreOnScroll`.
|
|
20
|
+
*
|
|
21
|
+
* Because it keys off `isIntersecting`/`isLoadingMore`, it self-continues:
|
|
22
|
+
* if the sentinel is still in view once a page finishes loading, the next
|
|
23
|
+
* page is requested automatically.
|
|
24
|
+
*/
|
|
25
|
+
export function useLoadMoreOnScroll(
|
|
26
|
+
loadMore: () => void,
|
|
27
|
+
{
|
|
28
|
+
hasMore,
|
|
29
|
+
isLoadingMore,
|
|
30
|
+
rootRef,
|
|
31
|
+
rootMargin = '400px',
|
|
32
|
+
}: UseLoadMoreOnScrollOptions
|
|
33
|
+
) {
|
|
34
|
+
const sentinelRef = useRef<HTMLDivElement>(null);
|
|
35
|
+
const entry = useIntersectionObserver(sentinelRef, { rootRef, rootMargin });
|
|
36
|
+
|
|
37
|
+
const loadMoreRef = useRef(loadMore);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
loadMoreRef.current = loadMore;
|
|
40
|
+
}, [loadMore]);
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (entry?.isIntersecting && hasMore && !isLoadingMore) {
|
|
44
|
+
loadMoreRef.current();
|
|
45
|
+
}
|
|
46
|
+
}, [entry?.isIntersecting, hasMore, isLoadingMore]);
|
|
47
|
+
|
|
48
|
+
return sentinelRef;
|
|
49
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
const QUERY = '(prefers-reduced-motion: reduce)';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Hook that detects whether the user has requested reduced motion and reacts
|
|
9
|
+
* to changes. Mirrors the `prefers-reduced-motion: reduce` media query so
|
|
10
|
+
* components can skip or shorten animations for users with motion
|
|
11
|
+
* sensitivities (e.g. vestibular disorders).
|
|
12
|
+
*
|
|
13
|
+
* @returns `true` if the user prefers reduced motion, `false` otherwise
|
|
14
|
+
*/
|
|
15
|
+
export const useReducedMotion = (): boolean => {
|
|
16
|
+
const [reduced, setReduced] = useState(() => {
|
|
17
|
+
if (typeof window === 'undefined' || !window.matchMedia) return false;
|
|
18
|
+
return window.matchMedia(QUERY).matches;
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (typeof window === 'undefined' || !window.matchMedia) return;
|
|
23
|
+
|
|
24
|
+
const media = window.matchMedia(QUERY);
|
|
25
|
+
const onChange = (): void => setReduced(media.matches);
|
|
26
|
+
|
|
27
|
+
media.addEventListener('change', onChange);
|
|
28
|
+
onChange();
|
|
29
|
+
|
|
30
|
+
return () => media.removeEventListener('change', onChange);
|
|
31
|
+
}, []);
|
|
32
|
+
|
|
33
|
+
return reduced;
|
|
34
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -33,6 +33,13 @@ export {
|
|
|
33
33
|
materializeSteps,
|
|
34
34
|
materializeWaits,
|
|
35
35
|
} from './lib/event-materialization';
|
|
36
|
+
export {
|
|
37
|
+
type ExactIdSearchResult,
|
|
38
|
+
type ExactWorkflowSearchId,
|
|
39
|
+
type ExactWorkflowSearchIdKind,
|
|
40
|
+
looksLikeWorkflowIdSearchInput,
|
|
41
|
+
parseExactWorkflowSearchId,
|
|
42
|
+
} from './lib/exact-event-search-id';
|
|
36
43
|
export type { Revivers, StreamRef } from './lib/hydration';
|
|
37
44
|
export {
|
|
38
45
|
CLASS_INSTANCE_REF_TYPE,
|
|
@@ -42,6 +49,7 @@ export {
|
|
|
42
49
|
getWebRevivers,
|
|
43
50
|
hasEncryptedFields,
|
|
44
51
|
hydrateResourceIO,
|
|
52
|
+
hydrateResourceIOAsync,
|
|
45
53
|
hydrateResourceIOWithKey,
|
|
46
54
|
isClassInstanceRef,
|
|
47
55
|
isEncryptedMarker,
|
|
@@ -57,6 +65,7 @@ export type { StreamStep } from './lib/utils';
|
|
|
57
65
|
export {
|
|
58
66
|
extractConversation,
|
|
59
67
|
formatDuration,
|
|
68
|
+
formatDurationPrecise,
|
|
60
69
|
identifyStreamSteps,
|
|
61
70
|
isDoStreamStep,
|
|
62
71
|
} from './lib/utils';
|
package/src/lib/cn.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { type ClassValue, clsx } from 'clsx';
|
|
2
|
+
import { extendTailwindMerge } from 'tailwind-merge';
|
|
3
|
+
|
|
4
|
+
const twMergeConfig = {
|
|
5
|
+
extend: {
|
|
6
|
+
classGroups: {
|
|
7
|
+
'text-heading': [
|
|
8
|
+
{
|
|
9
|
+
'text-heading': [
|
|
10
|
+
'72',
|
|
11
|
+
'64',
|
|
12
|
+
'56',
|
|
13
|
+
'48',
|
|
14
|
+
'40',
|
|
15
|
+
'32',
|
|
16
|
+
'24',
|
|
17
|
+
'20',
|
|
18
|
+
'16',
|
|
19
|
+
'14',
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
'text-button': [
|
|
24
|
+
{
|
|
25
|
+
'text-button': ['16', '14', '12'],
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
'text-label': [
|
|
29
|
+
{
|
|
30
|
+
'text-label': [
|
|
31
|
+
'20',
|
|
32
|
+
'18',
|
|
33
|
+
'16',
|
|
34
|
+
'14',
|
|
35
|
+
'14-mono',
|
|
36
|
+
'13',
|
|
37
|
+
'13-mono',
|
|
38
|
+
'12',
|
|
39
|
+
'12-mono',
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
'text-copy': [
|
|
44
|
+
{
|
|
45
|
+
'text-copy': ['24', '20', '18', '16', '14', '13', '13-mono'],
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
material: [
|
|
49
|
+
{
|
|
50
|
+
material: [
|
|
51
|
+
'base',
|
|
52
|
+
'small',
|
|
53
|
+
'medium',
|
|
54
|
+
'large',
|
|
55
|
+
'tooltip',
|
|
56
|
+
'menu',
|
|
57
|
+
'modal',
|
|
58
|
+
'fullscreen',
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
// Make each category conflict with itself, so e.g. text-heading-32 overrides text-heading-24
|
|
64
|
+
conflictingClassGroups: {
|
|
65
|
+
'text-heading': ['text-heading'],
|
|
66
|
+
'text-button': ['text-button'],
|
|
67
|
+
'text-label': ['text-label'],
|
|
68
|
+
'text-copy': ['text-copy'],
|
|
69
|
+
material: ['material'],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
} as const;
|
|
73
|
+
|
|
74
|
+
type CustomClassGroupIds =
|
|
75
|
+
| 'text-heading'
|
|
76
|
+
| 'text-button'
|
|
77
|
+
| 'text-label'
|
|
78
|
+
| 'text-copy'
|
|
79
|
+
| 'material';
|
|
80
|
+
|
|
81
|
+
const customTwMerge = extendTailwindMerge<CustomClassGroupIds>(twMergeConfig);
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Merges Tailwind class names and resolves any conflicts using `clsx` with `tailwind-merge`.
|
|
85
|
+
*
|
|
86
|
+
* @param inputs - An array of class names to merge.
|
|
87
|
+
* @returns A string of merged and optimized class names.
|
|
88
|
+
*/
|
|
89
|
+
function cn(...classes: ClassValue[]) {
|
|
90
|
+
return customTwMerge(clsx(...classes));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { cn };
|
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
* Used by run-actions and trace viewer components.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import {
|
|
7
|
+
type Event,
|
|
8
|
+
isTerminalWorkflowRunStatus,
|
|
9
|
+
type WorkflowRunStatus,
|
|
10
|
+
} from '@workflow/world';
|
|
7
11
|
|
|
8
12
|
// Time thresholds for Re-enqueue button visibility
|
|
9
13
|
const STEP_ACTIVITY_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
|
|
@@ -140,9 +144,7 @@ export function analyzeEvents(events: Event[] | undefined): EventAnalysis {
|
|
|
140
144
|
export function isTerminalStatus(
|
|
141
145
|
status: WorkflowRunStatus | undefined
|
|
142
146
|
): boolean {
|
|
143
|
-
return (
|
|
144
|
-
status === 'completed' || status === 'failed' || status === 'cancelled'
|
|
145
|
-
);
|
|
147
|
+
return status ? isTerminalWorkflowRunStatus(status) : false;
|
|
146
148
|
}
|
|
147
149
|
|
|
148
150
|
/**
|