@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
|
@@ -3,16 +3,30 @@
|
|
|
3
3
|
import { parseStepName, parseWorkflowName } from '@workflow/utils/parse-name';
|
|
4
4
|
import type { Event, WorkflowRun } from '@workflow/world';
|
|
5
5
|
import { Check, ChevronRight, Copy } from 'lucide-react';
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
KeyboardEvent as ReactKeyboardEvent,
|
|
8
|
+
MouseEvent as ReactMouseEvent,
|
|
9
|
+
ReactNode,
|
|
10
|
+
} from 'react';
|
|
7
11
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
8
12
|
import { Virtuoso, type VirtuosoHandle } from 'react-virtuoso';
|
|
13
|
+
import {
|
|
14
|
+
type ExactIdSearchResult,
|
|
15
|
+
type ExactWorkflowSearchIdKind,
|
|
16
|
+
looksLikeWorkflowIdSearchInput,
|
|
17
|
+
parseExactWorkflowSearchId,
|
|
18
|
+
} from '../lib/exact-event-search-id';
|
|
9
19
|
import { isEncryptedMarker } from '../lib/hydration';
|
|
10
|
-
import {
|
|
20
|
+
import { useToast } from '../lib/toast';
|
|
11
21
|
import { formatDuration } from '../lib/utils';
|
|
22
|
+
import { AttrSetEventBlock } from './sidebar/attributes-block';
|
|
23
|
+
import { ContextCardProvider } from './ui/context-card';
|
|
12
24
|
import { DataInspector, DecryptClickContext } from './ui/data-inspector';
|
|
25
|
+
import { DecryptButton } from './ui/decrypt-button';
|
|
13
26
|
import {
|
|
14
27
|
ErrorStackBlock,
|
|
15
|
-
|
|
28
|
+
isStructuredError,
|
|
29
|
+
type StructuredErrorRecord,
|
|
16
30
|
} from './ui/error-stack-block';
|
|
17
31
|
import { LoadMoreButton } from './ui/load-more-button';
|
|
18
32
|
import { MenuDropdown } from './ui/menu-dropdown';
|
|
@@ -55,6 +69,25 @@ function formatEventTime(date: Date): string {
|
|
|
55
69
|
);
|
|
56
70
|
}
|
|
57
71
|
|
|
72
|
+
function parseEventDate(value: unknown): Date | null {
|
|
73
|
+
if (value == null) return null;
|
|
74
|
+
|
|
75
|
+
const date = value instanceof Date ? value : new Date(String(value));
|
|
76
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function getEffectiveEventDate(
|
|
80
|
+
event: Pick<Event, 'createdAt' | 'occurredAt'>
|
|
81
|
+
): Date {
|
|
82
|
+
return parseEventDate(event.occurredAt) ?? new Date(event.createdAt);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function getEffectiveEventTime(
|
|
86
|
+
event: Pick<Event, 'createdAt' | 'occurredAt'>
|
|
87
|
+
): number {
|
|
88
|
+
return getEffectiveEventDate(event).getTime();
|
|
89
|
+
}
|
|
90
|
+
|
|
58
91
|
function formatEventType(eventType: Event['eventType']): string {
|
|
59
92
|
return eventType
|
|
60
93
|
.split('_')
|
|
@@ -84,6 +117,10 @@ function getStatusDotColor(eventType: string): string {
|
|
|
84
117
|
if (eventType === 'step_retrying') {
|
|
85
118
|
return 'var(--ds-amber-700)';
|
|
86
119
|
}
|
|
120
|
+
// Attribute changes → teal
|
|
121
|
+
if (eventType === 'attr_set') {
|
|
122
|
+
return 'var(--ds-teal-900)';
|
|
123
|
+
}
|
|
87
124
|
// Completed/succeeded → green
|
|
88
125
|
if (
|
|
89
126
|
eventType === 'step_completed' ||
|
|
@@ -142,7 +179,7 @@ function buildNameMaps(
|
|
|
142
179
|
return { correlationNameMap, workflowName };
|
|
143
180
|
}
|
|
144
181
|
|
|
145
|
-
interface DurationInfo {
|
|
182
|
+
export interface DurationInfo {
|
|
146
183
|
/** Time from created → started (ms) */
|
|
147
184
|
queued?: number;
|
|
148
185
|
/** Time from started → completed/failed/cancelled (ms) */
|
|
@@ -154,19 +191,30 @@ interface DurationInfo {
|
|
|
154
191
|
* created ↔ started (queued) and started ↔ completed/failed/cancelled (ran).
|
|
155
192
|
* Also computes run-level durations under the key '__run__'.
|
|
156
193
|
*/
|
|
157
|
-
function buildDurationMap(events: Event[]): Map<string, DurationInfo> {
|
|
194
|
+
export function buildDurationMap(events: Event[]): Map<string, DurationInfo> {
|
|
195
|
+
// Process events in chronological order so the result doesn't depend on
|
|
196
|
+
// the caller's sort direction. Retried steps emit multiple `step_started`
|
|
197
|
+
// events for the same correlationId; the queued duration must be measured
|
|
198
|
+
// against the first one, not the last.
|
|
199
|
+
const chronological = [...events].sort(
|
|
200
|
+
(a, b) => getEffectiveEventTime(a) - getEffectiveEventTime(b)
|
|
201
|
+
);
|
|
202
|
+
|
|
158
203
|
const createdTimes = new Map<string, number>();
|
|
204
|
+
const firstStartedTimes = new Map<string, number>();
|
|
159
205
|
const startedTimes = new Map<string, number>();
|
|
160
206
|
const durations = new Map<string, DurationInfo>();
|
|
161
207
|
|
|
162
|
-
for (const event of
|
|
163
|
-
const ts =
|
|
208
|
+
for (const event of chronological) {
|
|
209
|
+
const ts = getEffectiveEventTime(event);
|
|
164
210
|
const key = event.correlationId ?? '__run__';
|
|
165
211
|
const type: string = event.eventType;
|
|
166
212
|
|
|
167
213
|
// Track created times (first event for each correlation)
|
|
168
214
|
if (type === 'step_created' || type === 'run_created') {
|
|
169
|
-
createdTimes.
|
|
215
|
+
if (!createdTimes.has(key)) {
|
|
216
|
+
createdTimes.set(key, ts);
|
|
217
|
+
}
|
|
170
218
|
}
|
|
171
219
|
|
|
172
220
|
// Track started times & compute queued duration
|
|
@@ -176,16 +224,21 @@ function buildDurationMap(events: Event[]): Map<string, DurationInfo> {
|
|
|
176
224
|
type === 'workflow_started'
|
|
177
225
|
) {
|
|
178
226
|
startedTimes.set(key, ts);
|
|
179
|
-
//
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
227
|
+
// The queued duration is anchored on the first start event only —
|
|
228
|
+
// subsequent step_started events come from retries.
|
|
229
|
+
if (!firstStartedTimes.has(key)) {
|
|
230
|
+
firstStartedTimes.set(key, ts);
|
|
231
|
+
// If no explicit created event was seen, use the started time as created
|
|
232
|
+
if (!createdTimes.has(key)) {
|
|
233
|
+
createdTimes.set(key, ts);
|
|
234
|
+
}
|
|
235
|
+
const createdAt = createdTimes.get(key);
|
|
236
|
+
const info = durations.get(key) ?? {};
|
|
237
|
+
if (createdAt !== undefined) {
|
|
238
|
+
info.queued = ts - createdAt;
|
|
239
|
+
}
|
|
240
|
+
durations.set(key, info);
|
|
187
241
|
}
|
|
188
|
-
durations.set(key, info);
|
|
189
242
|
}
|
|
190
243
|
|
|
191
244
|
// Compute ran duration on terminal events
|
|
@@ -230,7 +283,10 @@ function isRunLevel(eventType: string): boolean {
|
|
|
230
283
|
eventType === 'run_cancelled' ||
|
|
231
284
|
eventType === 'workflow_started' ||
|
|
232
285
|
eventType === 'workflow_completed' ||
|
|
233
|
-
eventType === 'workflow_failed'
|
|
286
|
+
eventType === 'workflow_failed' ||
|
|
287
|
+
// attr_set carries a dedup correlationId rather than a child entity ID,
|
|
288
|
+
// so it groups and labels with the run itself.
|
|
289
|
+
eventType === 'attr_set'
|
|
234
290
|
);
|
|
235
291
|
}
|
|
236
292
|
|
|
@@ -492,20 +548,20 @@ function deepParseJson(value: unknown): unknown {
|
|
|
492
548
|
}
|
|
493
549
|
|
|
494
550
|
/**
|
|
495
|
-
* Extracts a structured error
|
|
551
|
+
* Extracts a structured error from event data, if present.
|
|
496
552
|
* Returns the error object to render with ErrorStackBlock, or null if not applicable.
|
|
497
553
|
*/
|
|
498
554
|
function extractStructuredError(
|
|
499
555
|
data: unknown,
|
|
500
556
|
eventType?: string
|
|
501
|
-
):
|
|
557
|
+
): StructuredErrorRecord | null {
|
|
502
558
|
if (!eventType || !ERROR_EVENT_TYPES.has(eventType)) return null;
|
|
503
559
|
if (data == null || typeof data !== 'object') return null;
|
|
504
560
|
const record = data as Record<string, unknown>;
|
|
505
561
|
// Check the nested `error` field first (the StructuredError)
|
|
506
|
-
if (
|
|
507
|
-
// Some error formats put the stack at the top level of eventData
|
|
508
|
-
if (
|
|
562
|
+
if (isStructuredError(record.error)) return record.error;
|
|
563
|
+
// Some error formats put the message/stack at the top level of eventData.
|
|
564
|
+
if (isStructuredError(record)) return record;
|
|
509
565
|
return null;
|
|
510
566
|
}
|
|
511
567
|
|
|
@@ -566,6 +622,33 @@ function PayloadBlock({
|
|
|
566
622
|
);
|
|
567
623
|
}
|
|
568
624
|
|
|
625
|
+
// Attribute changes — render the changed keys and the writer instead of
|
|
626
|
+
// the raw JSON payload.
|
|
627
|
+
if (eventType === 'attr_set') {
|
|
628
|
+
return <AttrSetEventBlock data={cleaned} />;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
// Cancellation reason — render the free-text reason as a readable line
|
|
632
|
+
// instead of a raw JSON payload (the only field run_cancelled carries).
|
|
633
|
+
if (eventType === 'run_cancelled') {
|
|
634
|
+
const cancelReason =
|
|
635
|
+
cleaned != null &&
|
|
636
|
+
typeof cleaned === 'object' &&
|
|
637
|
+
typeof (cleaned as Record<string, unknown>).cancelReason === 'string'
|
|
638
|
+
? ((cleaned as Record<string, unknown>).cancelReason as string)
|
|
639
|
+
: null;
|
|
640
|
+
if (cancelReason) {
|
|
641
|
+
return (
|
|
642
|
+
<div className="p-2 text-xs" style={{ color: 'var(--ds-gray-1000)' }}>
|
|
643
|
+
<span style={{ color: 'var(--ds-gray-900)' }}>Reason: </span>
|
|
644
|
+
<span className="whitespace-pre-wrap break-words">
|
|
645
|
+
{cancelReason}
|
|
646
|
+
</span>
|
|
647
|
+
</div>
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
569
652
|
return (
|
|
570
653
|
<div className="relative group/payload">
|
|
571
654
|
<div
|
|
@@ -609,7 +692,11 @@ const SORT_OPTIONS = [
|
|
|
609
692
|
{ value: 'asc' as const, label: 'Oldest' },
|
|
610
693
|
];
|
|
611
694
|
|
|
612
|
-
function RowsSkeleton(
|
|
695
|
+
function RowsSkeleton({
|
|
696
|
+
showSeparateEventOccurrenceTimestamps = false,
|
|
697
|
+
}: {
|
|
698
|
+
showSeparateEventOccurrenceTimestamps?: boolean;
|
|
699
|
+
}) {
|
|
613
700
|
return (
|
|
614
701
|
<div className="flex-1 overflow-hidden">
|
|
615
702
|
{Array.from({ length: 16 }, (_, i) => (
|
|
@@ -646,7 +733,12 @@ function RowsSkeleton() {
|
|
|
646
733
|
<div className="w-5 flex-shrink-0 flex items-center justify-center">
|
|
647
734
|
<Skeleton className="w-5 h-5" style={{ borderRadius: 4 }} />
|
|
648
735
|
</div>
|
|
649
|
-
{
|
|
736
|
+
{showSeparateEventOccurrenceTimestamps && (
|
|
737
|
+
<div className="min-w-0 px-4" style={{ flex: '2 1 0%' }}>
|
|
738
|
+
<Skeleton className="h-3" style={{ width: '70%' }} />
|
|
739
|
+
</div>
|
|
740
|
+
)}
|
|
741
|
+
{/* Created */}
|
|
650
742
|
<div className="min-w-0 px-4" style={{ flex: '2 1 0%' }}>
|
|
651
743
|
<Skeleton className="h-3" style={{ width: '70%' }} />
|
|
652
744
|
</div>
|
|
@@ -705,9 +797,17 @@ interface EventsListProps {
|
|
|
705
797
|
isDecrypting?: boolean;
|
|
706
798
|
/** Run-level hint: the run contains encrypted data (from probe). */
|
|
707
799
|
hasEncryptedData?: boolean;
|
|
800
|
+
/** Fetch events for an exact correlation or event ID. */
|
|
801
|
+
onExactIdSearch?: (
|
|
802
|
+
id: string,
|
|
803
|
+
kind: ExactWorkflowSearchIdKind,
|
|
804
|
+
signal?: AbortSignal
|
|
805
|
+
) => Promise<ExactIdSearchResult>;
|
|
806
|
+
/** Show occurredAt separately instead of folding it into the Created timestamp. */
|
|
807
|
+
showSeparateEventOccurrenceTimestamps?: boolean;
|
|
708
808
|
}
|
|
709
809
|
|
|
710
|
-
function EventRow({
|
|
810
|
+
export function EventRow({
|
|
711
811
|
event,
|
|
712
812
|
index,
|
|
713
813
|
isFirst,
|
|
@@ -727,6 +827,8 @@ function EventRow({
|
|
|
727
827
|
onCacheEventData,
|
|
728
828
|
encryptionKey,
|
|
729
829
|
onEncryptedDataDetected,
|
|
830
|
+
suppressGroupDimming = false,
|
|
831
|
+
showSeparateEventOccurrenceTimestamps = false,
|
|
730
832
|
}: {
|
|
731
833
|
event: Event;
|
|
732
834
|
index: number;
|
|
@@ -747,6 +849,10 @@ function EventRow({
|
|
|
747
849
|
onCacheEventData: (eventId: string, data: unknown) => void;
|
|
748
850
|
encryptionKey?: Uint8Array;
|
|
749
851
|
onEncryptedDataDetected?: () => void;
|
|
852
|
+
/** Exact-ID search results should not dim unrelated rows. */
|
|
853
|
+
suppressGroupDimming?: boolean;
|
|
854
|
+
/** Show occurredAt separately instead of folding it into the Created timestamp. */
|
|
855
|
+
showSeparateEventOccurrenceTimestamps?: boolean;
|
|
750
856
|
}) {
|
|
751
857
|
const [isLoading, setIsLoading] = useState(false);
|
|
752
858
|
const [loadedEventData, setLoadedEventData] = useState<unknown | null>(
|
|
@@ -775,6 +881,10 @@ function EventRow({
|
|
|
775
881
|
|
|
776
882
|
const statusDotColor = getStatusDotColor(event.eventType);
|
|
777
883
|
const createdAt = new Date(event.createdAt);
|
|
884
|
+
const occurredAt = parseEventDate(event.occurredAt);
|
|
885
|
+
const displayedCreatedAt = showSeparateEventOccurrenceTimestamps
|
|
886
|
+
? createdAt
|
|
887
|
+
: getEffectiveEventDate(event);
|
|
778
888
|
const hasExistingEventData = 'eventData' in event && event.eventData != null;
|
|
779
889
|
const isRun = isRunLevel(event.eventType);
|
|
780
890
|
const eventName = isRun
|
|
@@ -788,7 +898,7 @@ function EventRow({
|
|
|
788
898
|
|
|
789
899
|
const hasActive = activeGroupKey !== undefined;
|
|
790
900
|
const isRelated = rowGroupKey !== undefined && rowGroupKey === activeGroupKey;
|
|
791
|
-
const isDimmed = hasActive && !isRelated;
|
|
901
|
+
const isDimmed = hasActive && !isRelated && !suppressGroupDimming;
|
|
792
902
|
const isPulsing = hasActive && isRelated;
|
|
793
903
|
|
|
794
904
|
// Gutter state derived from selectedGroupRange
|
|
@@ -955,13 +1065,28 @@ function EventRow({
|
|
|
955
1065
|
/>
|
|
956
1066
|
</div>
|
|
957
1067
|
|
|
958
|
-
{
|
|
1068
|
+
{showSeparateEventOccurrenceTimestamps && (
|
|
1069
|
+
<div
|
|
1070
|
+
className="tabular-nums min-w-0 px-4"
|
|
1071
|
+
style={{ color: 'var(--ds-gray-900)', flex: '2 1 0%' }}
|
|
1072
|
+
>
|
|
1073
|
+
{occurredAt ? (
|
|
1074
|
+
<TimestampTooltip date={occurredAt}>
|
|
1075
|
+
<span>{formatEventTime(occurredAt)}</span>
|
|
1076
|
+
</TimestampTooltip>
|
|
1077
|
+
) : (
|
|
1078
|
+
'-'
|
|
1079
|
+
)}
|
|
1080
|
+
</div>
|
|
1081
|
+
)}
|
|
1082
|
+
|
|
1083
|
+
{/* Created */}
|
|
959
1084
|
<div
|
|
960
1085
|
className="tabular-nums min-w-0 px-4"
|
|
961
1086
|
style={{ color: 'var(--ds-gray-900)', flex: '2 1 0%' }}
|
|
962
1087
|
>
|
|
963
|
-
<TimestampTooltip date={
|
|
964
|
-
<span>{formatEventTime(
|
|
1088
|
+
<TimestampTooltip date={displayedCreatedAt}>
|
|
1089
|
+
<span>{formatEventTime(displayedCreatedAt)}</span>
|
|
965
1090
|
</TimestampTooltip>
|
|
966
1091
|
</div>
|
|
967
1092
|
|
|
@@ -1125,7 +1250,7 @@ function EventRow({
|
|
|
1125
1250
|
// Main component
|
|
1126
1251
|
// ──────────────────────────────────────────────────────────────────────────
|
|
1127
1252
|
|
|
1128
|
-
|
|
1253
|
+
function EventListViewInner({
|
|
1129
1254
|
events,
|
|
1130
1255
|
run,
|
|
1131
1256
|
onLoadEventData,
|
|
@@ -1139,7 +1264,10 @@ export function EventListView({
|
|
|
1139
1264
|
onDecrypt,
|
|
1140
1265
|
isDecrypting = false,
|
|
1141
1266
|
hasEncryptedData: hasEncryptedDataProp = false,
|
|
1267
|
+
onExactIdSearch,
|
|
1268
|
+
showSeparateEventOccurrenceTimestamps = false,
|
|
1142
1269
|
}: EventsListProps) {
|
|
1270
|
+
const toast = useToast();
|
|
1143
1271
|
const [internalSortOrder, setInternalSortOrder] = useState<'asc' | 'desc'>(
|
|
1144
1272
|
'asc'
|
|
1145
1273
|
);
|
|
@@ -1155,25 +1283,40 @@ export function EventListView({
|
|
|
1155
1283
|
[onSortOrderChange]
|
|
1156
1284
|
);
|
|
1157
1285
|
|
|
1286
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
1287
|
+
const [searchResults, setSearchResults] = useState<Event[] | null>(null);
|
|
1288
|
+
const [searchResultsTruncated, setSearchResultsTruncated] = useState(false);
|
|
1289
|
+
const [searchError, setSearchError] = useState<string | null>(null);
|
|
1290
|
+
const [searchLoading, setSearchLoading] = useState(false);
|
|
1291
|
+
const [searchNotFound, setSearchNotFound] = useState(false);
|
|
1292
|
+
const searchRequestRef = useRef(0);
|
|
1293
|
+
const virtuosoRef = useRef<VirtuosoHandle>(null);
|
|
1294
|
+
|
|
1295
|
+
const parsedSearchId = useMemo(
|
|
1296
|
+
() => parseExactWorkflowSearchId(searchQuery),
|
|
1297
|
+
[searchQuery]
|
|
1298
|
+
);
|
|
1299
|
+
const isExactSearchActive = searchResults !== null;
|
|
1300
|
+
|
|
1158
1301
|
const sortedEvents = useMemo(() => {
|
|
1159
|
-
|
|
1302
|
+
const sourceEvents = isExactSearchActive ? searchResults : (events ?? []);
|
|
1303
|
+
if (sourceEvents.length === 0) return [];
|
|
1160
1304
|
const dir = effectiveSortOrder === 'desc' ? -1 : 1;
|
|
1161
|
-
return [...
|
|
1162
|
-
(a, b) =>
|
|
1163
|
-
dir *
|
|
1164
|
-
(new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime())
|
|
1305
|
+
return [...sourceEvents].sort(
|
|
1306
|
+
(a, b) => dir * (getEffectiveEventTime(a) - getEffectiveEventTime(b))
|
|
1165
1307
|
);
|
|
1166
|
-
}, [events, effectiveSortOrder]);
|
|
1308
|
+
}, [events, effectiveSortOrder, isExactSearchActive, searchResults]);
|
|
1167
1309
|
|
|
1168
1310
|
// Detect encrypted fields across all loaded events (inline eventData).
|
|
1169
1311
|
const hasEncryptedInlineData = useMemo(() => {
|
|
1170
|
-
|
|
1171
|
-
|
|
1312
|
+
const sourceEvents = isExactSearchActive ? searchResults : events;
|
|
1313
|
+
if (!sourceEvents) return false;
|
|
1314
|
+
for (const event of sourceEvents) {
|
|
1172
1315
|
const ed = (event as Record<string, unknown>).eventData;
|
|
1173
1316
|
if (hasEncryptedValues(ed)) return true;
|
|
1174
1317
|
}
|
|
1175
1318
|
return false;
|
|
1176
|
-
}, [events]);
|
|
1319
|
+
}, [events, isExactSearchActive, searchResults]);
|
|
1177
1320
|
|
|
1178
1321
|
// Tracks whether any expanded row's lazy-loaded data contained encrypted markers.
|
|
1179
1322
|
// Set to true by EventRow via onEncryptedDataDetected; never reset (sticky).
|
|
@@ -1187,8 +1330,12 @@ export function EventListView({
|
|
|
1187
1330
|
hasEncryptedDataProp || hasEncryptedInlineData || foundEncryptedInLazyData;
|
|
1188
1331
|
|
|
1189
1332
|
const { correlationNameMap, workflowName } = useMemo(
|
|
1190
|
-
() =>
|
|
1191
|
-
|
|
1333
|
+
() =>
|
|
1334
|
+
buildNameMaps(
|
|
1335
|
+
isExactSearchActive ? searchResults : (events ?? null),
|
|
1336
|
+
run ?? null
|
|
1337
|
+
),
|
|
1338
|
+
[events, isExactSearchActive, run, searchResults]
|
|
1192
1339
|
);
|
|
1193
1340
|
|
|
1194
1341
|
const durationMap = useMemo(
|
|
@@ -1278,68 +1425,139 @@ export function EventListView({
|
|
|
1278
1425
|
return first >= 0 ? { first, last } : null;
|
|
1279
1426
|
}, [activeGroupKey, sortedEvents]);
|
|
1280
1427
|
|
|
1281
|
-
const [searchQuery, setSearchQuery] = useState('');
|
|
1282
|
-
const virtuosoRef = useRef<VirtuosoHandle>(null);
|
|
1283
|
-
|
|
1284
|
-
const searchIndex = useMemo(() => {
|
|
1285
|
-
const entries: {
|
|
1286
|
-
fields: string[];
|
|
1287
|
-
groupKey?: string;
|
|
1288
|
-
eventId: string;
|
|
1289
|
-
index: number;
|
|
1290
|
-
}[] = [];
|
|
1291
|
-
for (let i = 0; i < sortedEvents.length; i++) {
|
|
1292
|
-
const ev = sortedEvents[i];
|
|
1293
|
-
const isRun = isRunLevel(ev.eventType);
|
|
1294
|
-
const name = isRun
|
|
1295
|
-
? (workflowName ?? '')
|
|
1296
|
-
: ev.correlationId
|
|
1297
|
-
? (correlationNameMap.get(ev.correlationId) ?? '')
|
|
1298
|
-
: '';
|
|
1299
|
-
entries.push({
|
|
1300
|
-
fields: [
|
|
1301
|
-
ev.eventId,
|
|
1302
|
-
ev.correlationId ?? '',
|
|
1303
|
-
ev.eventType,
|
|
1304
|
-
formatEventType(ev.eventType),
|
|
1305
|
-
name,
|
|
1306
|
-
].map((f) => f.toLowerCase()),
|
|
1307
|
-
groupKey: ev.correlationId ?? (isRun ? '__run__' : undefined),
|
|
1308
|
-
eventId: ev.eventId,
|
|
1309
|
-
index: i,
|
|
1310
|
-
});
|
|
1311
|
-
}
|
|
1312
|
-
return entries;
|
|
1313
|
-
}, [sortedEvents, correlationNameMap, workflowName]);
|
|
1314
|
-
|
|
1315
1428
|
useEffect(() => {
|
|
1316
|
-
const
|
|
1317
|
-
if (!
|
|
1429
|
+
const trimmed = searchQuery.trim();
|
|
1430
|
+
if (!trimmed) {
|
|
1431
|
+
searchRequestRef.current += 1;
|
|
1432
|
+
setSearchResults(null);
|
|
1433
|
+
setSearchResultsTruncated(false);
|
|
1434
|
+
setSearchError(null);
|
|
1435
|
+
setSearchLoading(false);
|
|
1436
|
+
setSearchNotFound(false);
|
|
1318
1437
|
setSelectedGroupKey(undefined);
|
|
1319
1438
|
return;
|
|
1320
1439
|
}
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1440
|
+
|
|
1441
|
+
const parsed = parseExactWorkflowSearchId(trimmed);
|
|
1442
|
+
if (!parsed || !onExactIdSearch) {
|
|
1443
|
+
setSearchResults(null);
|
|
1444
|
+
setSearchLoading(false);
|
|
1445
|
+
setSearchNotFound(false);
|
|
1446
|
+
return;
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
const requestId = ++searchRequestRef.current;
|
|
1450
|
+
setSearchLoading(true);
|
|
1451
|
+
setSearchNotFound(false);
|
|
1452
|
+
setSearchError(null);
|
|
1453
|
+
|
|
1454
|
+
const abortController = new AbortController();
|
|
1455
|
+
|
|
1456
|
+
const timer = setTimeout(() => {
|
|
1457
|
+
void (async () => {
|
|
1458
|
+
try {
|
|
1459
|
+
const results = await onExactIdSearch(
|
|
1460
|
+
parsed.id,
|
|
1461
|
+
parsed.kind,
|
|
1462
|
+
abortController.signal
|
|
1463
|
+
);
|
|
1464
|
+
if (
|
|
1465
|
+
abortController.signal.aborted ||
|
|
1466
|
+
searchRequestRef.current !== requestId
|
|
1467
|
+
) {
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
if (results.status === 'error') {
|
|
1472
|
+
setSearchResults([]);
|
|
1473
|
+
setSearchResultsTruncated(false);
|
|
1474
|
+
setSearchNotFound(false);
|
|
1475
|
+
setSearchError(results.message);
|
|
1476
|
+
setSelectedGroupKey(undefined);
|
|
1477
|
+
return;
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
if (
|
|
1481
|
+
results.status === 'not_found' ||
|
|
1482
|
+
(results.status === 'ok' && results.events.length === 0)
|
|
1483
|
+
) {
|
|
1484
|
+
setSearchResults([]);
|
|
1485
|
+
setSearchResultsTruncated(false);
|
|
1486
|
+
setSearchNotFound(true);
|
|
1487
|
+
setSearchError(null);
|
|
1488
|
+
setSelectedGroupKey(undefined);
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
setSearchResults(results.events);
|
|
1493
|
+
setSearchResultsTruncated(Boolean(results.truncated));
|
|
1494
|
+
setSearchNotFound(false);
|
|
1495
|
+
setSearchError(null);
|
|
1496
|
+
setSelectedGroupKey(
|
|
1497
|
+
parsed.kind === 'event'
|
|
1498
|
+
? (() => {
|
|
1499
|
+
const first = results.events[0];
|
|
1500
|
+
if (!first) return undefined;
|
|
1501
|
+
return isRunLevel(first.eventType)
|
|
1502
|
+
? '__run__'
|
|
1503
|
+
: (first.correlationId ?? undefined);
|
|
1504
|
+
})()
|
|
1505
|
+
: parsed.id
|
|
1506
|
+
);
|
|
1507
|
+
virtuosoRef.current?.scrollToIndex({
|
|
1508
|
+
index: 0,
|
|
1509
|
+
align: 'start',
|
|
1510
|
+
behavior: 'smooth',
|
|
1511
|
+
});
|
|
1512
|
+
} catch {
|
|
1513
|
+
if (
|
|
1514
|
+
abortController.signal.aborted ||
|
|
1515
|
+
searchRequestRef.current !== requestId
|
|
1516
|
+
) {
|
|
1517
|
+
return;
|
|
1518
|
+
}
|
|
1519
|
+
setSearchResults([]);
|
|
1520
|
+
setSearchResultsTruncated(false);
|
|
1521
|
+
setSearchNotFound(false);
|
|
1522
|
+
setSearchError('Failed to search events. Try again.');
|
|
1523
|
+
setSelectedGroupKey(undefined);
|
|
1524
|
+
} finally {
|
|
1525
|
+
if (
|
|
1526
|
+
searchRequestRef.current === requestId &&
|
|
1527
|
+
!abortController.signal.aborted
|
|
1528
|
+
) {
|
|
1529
|
+
setSearchLoading(false);
|
|
1330
1530
|
}
|
|
1331
1531
|
}
|
|
1532
|
+
})();
|
|
1533
|
+
}, 300);
|
|
1534
|
+
|
|
1535
|
+
return () => {
|
|
1536
|
+
clearTimeout(timer);
|
|
1537
|
+
abortController.abort();
|
|
1538
|
+
};
|
|
1539
|
+
}, [searchQuery, onExactIdSearch]);
|
|
1540
|
+
|
|
1541
|
+
const handleSearchKeyDown = useCallback(
|
|
1542
|
+
(event: ReactKeyboardEvent<HTMLInputElement>) => {
|
|
1543
|
+
if (event.key !== 'Enter') {
|
|
1544
|
+
return;
|
|
1332
1545
|
}
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1546
|
+
|
|
1547
|
+
const trimmed = searchQuery.trim();
|
|
1548
|
+
if (
|
|
1549
|
+
!trimmed ||
|
|
1550
|
+
parseExactWorkflowSearchId(trimmed) ||
|
|
1551
|
+
!onExactIdSearch ||
|
|
1552
|
+
!looksLikeWorkflowIdSearchInput(trimmed)
|
|
1553
|
+
) {
|
|
1554
|
+
return;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
toast.info('Enter a full step ID, wait ID, hook ID, or event ID');
|
|
1558
|
+
},
|
|
1559
|
+
[searchQuery, onExactIdSearch, toast]
|
|
1560
|
+
);
|
|
1343
1561
|
|
|
1344
1562
|
// Track whether we've ever had events to distinguish initial load from refetch
|
|
1345
1563
|
const hasHadEventsRef = useRef(false);
|
|
@@ -1385,17 +1603,6 @@ export function EventListView({
|
|
|
1385
1603
|
);
|
|
1386
1604
|
}
|
|
1387
1605
|
|
|
1388
|
-
if (!isLoading && (!events || events.length === 0)) {
|
|
1389
|
-
return (
|
|
1390
|
-
<div
|
|
1391
|
-
className="flex items-center justify-center h-full text-sm"
|
|
1392
|
-
style={{ color: 'var(--ds-gray-700)' }}
|
|
1393
|
-
>
|
|
1394
|
-
No events found
|
|
1395
|
-
</div>
|
|
1396
|
-
);
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
1606
|
return (
|
|
1400
1607
|
<DecryptClickContext.Provider
|
|
1401
1608
|
value={onDecrypt ? { onDecrypt, isDecrypting } : undefined}
|
|
@@ -1460,9 +1667,16 @@ export function EventListView({
|
|
|
1460
1667
|
</div>
|
|
1461
1668
|
<input
|
|
1462
1669
|
type="search"
|
|
1463
|
-
placeholder="Search by
|
|
1670
|
+
placeholder="Search by step ID, wait ID, hook ID, or event ID…"
|
|
1464
1671
|
value={searchQuery}
|
|
1465
1672
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
1673
|
+
onKeyDown={handleSearchKeyDown}
|
|
1674
|
+
disabled={!onExactIdSearch}
|
|
1675
|
+
title={
|
|
1676
|
+
onExactIdSearch
|
|
1677
|
+
? undefined
|
|
1678
|
+
: 'Exact ID search is unavailable in this view.'
|
|
1679
|
+
}
|
|
1466
1680
|
style={{
|
|
1467
1681
|
marginLeft: -16,
|
|
1468
1682
|
paddingInline: 12,
|
|
@@ -1473,6 +1687,8 @@ export function EventListView({
|
|
|
1473
1687
|
outline: 'none',
|
|
1474
1688
|
height: 40,
|
|
1475
1689
|
width: '100%',
|
|
1690
|
+
opacity: onExactIdSearch ? 1 : 0.5,
|
|
1691
|
+
cursor: onExactIdSearch ? 'text' : 'not-allowed',
|
|
1476
1692
|
}}
|
|
1477
1693
|
/>
|
|
1478
1694
|
</label>
|
|
@@ -1501,8 +1717,13 @@ export function EventListView({
|
|
|
1501
1717
|
>
|
|
1502
1718
|
<div className="flex-shrink-0" style={{ width: GUTTER_WIDTH }} />
|
|
1503
1719
|
<div className="w-5 flex-shrink-0" />
|
|
1720
|
+
{showSeparateEventOccurrenceTimestamps && (
|
|
1721
|
+
<div className="min-w-0 px-4" style={{ flex: '2 1 0%' }}>
|
|
1722
|
+
Occurred
|
|
1723
|
+
</div>
|
|
1724
|
+
)}
|
|
1504
1725
|
<div className="min-w-0 px-4" style={{ flex: '2 1 0%' }}>
|
|
1505
|
-
|
|
1726
|
+
Created
|
|
1506
1727
|
</div>
|
|
1507
1728
|
<div className="min-w-0 px-4" style={{ flex: '2 1 0%' }}>
|
|
1508
1729
|
Event Type
|
|
@@ -1519,8 +1740,25 @@ export function EventListView({
|
|
|
1519
1740
|
</div>
|
|
1520
1741
|
|
|
1521
1742
|
{/* Virtualized event rows or refetching skeleton */}
|
|
1522
|
-
{isRefetching ? (
|
|
1523
|
-
<RowsSkeleton
|
|
1743
|
+
{isRefetching || searchLoading ? (
|
|
1744
|
+
<RowsSkeleton
|
|
1745
|
+
showSeparateEventOccurrenceTimestamps={
|
|
1746
|
+
showSeparateEventOccurrenceTimestamps
|
|
1747
|
+
}
|
|
1748
|
+
/>
|
|
1749
|
+
) : sortedEvents.length === 0 ? (
|
|
1750
|
+
<div
|
|
1751
|
+
className="flex flex-1 items-center justify-center px-6 text-center text-sm"
|
|
1752
|
+
style={{ color: 'var(--ds-gray-700)' }}
|
|
1753
|
+
>
|
|
1754
|
+
{searchNotFound && searchQuery.trim()
|
|
1755
|
+
? `No events found for ${searchQuery.trim()}`
|
|
1756
|
+
: searchError
|
|
1757
|
+
? searchError
|
|
1758
|
+
: parsedSearchId && searchQuery.trim() && !onExactIdSearch
|
|
1759
|
+
? 'Exact ID search is unavailable in this view.'
|
|
1760
|
+
: 'No events found'}
|
|
1761
|
+
</div>
|
|
1524
1762
|
) : (
|
|
1525
1763
|
<Virtuoso
|
|
1526
1764
|
ref={virtuosoRef}
|
|
@@ -1528,7 +1766,11 @@ export function EventListView({
|
|
|
1528
1766
|
overscan={20}
|
|
1529
1767
|
defaultItemHeight={40}
|
|
1530
1768
|
endReached={() => {
|
|
1531
|
-
if (
|
|
1769
|
+
if (
|
|
1770
|
+
isExactSearchActive ||
|
|
1771
|
+
!hasMoreEvents ||
|
|
1772
|
+
isLoadingMoreEvents
|
|
1773
|
+
) {
|
|
1532
1774
|
return;
|
|
1533
1775
|
}
|
|
1534
1776
|
void onLoadMoreEvents?.();
|
|
@@ -1558,6 +1800,10 @@ export function EventListView({
|
|
|
1558
1800
|
onCacheEventData={cacheEventData}
|
|
1559
1801
|
encryptionKey={encryptionKey}
|
|
1560
1802
|
onEncryptedDataDetected={handleEncryptedDataDetected}
|
|
1803
|
+
suppressGroupDimming={isExactSearchActive}
|
|
1804
|
+
showSeparateEventOccurrenceTimestamps={
|
|
1805
|
+
showSeparateEventOccurrenceTimestamps
|
|
1806
|
+
}
|
|
1561
1807
|
/>
|
|
1562
1808
|
);
|
|
1563
1809
|
}}
|
|
@@ -1575,10 +1821,15 @@ export function EventListView({
|
|
|
1575
1821
|
}}
|
|
1576
1822
|
>
|
|
1577
1823
|
<span>
|
|
1578
|
-
{
|
|
1579
|
-
|
|
1824
|
+
{isExactSearchActive
|
|
1825
|
+
? searchError
|
|
1826
|
+
? searchError
|
|
1827
|
+
: searchNotFound
|
|
1828
|
+
? `No events found for ${searchQuery.trim()}`
|
|
1829
|
+
: `${sortedEvents.length} event${sortedEvents.length !== 1 ? 's' : ''} for ${searchQuery.trim()}${searchResultsTruncated ? ' (results may be truncated)' : ''}`
|
|
1830
|
+
: `${sortedEvents.length} event${sortedEvents.length !== 1 ? 's' : ''} loaded`}
|
|
1580
1831
|
</span>
|
|
1581
|
-
{hasMoreEvents && (
|
|
1832
|
+
{!isExactSearchActive && hasMoreEvents && (
|
|
1582
1833
|
<div className="absolute inset-0 flex items-center justify-center pointer-events-none">
|
|
1583
1834
|
<div className="pointer-events-auto">
|
|
1584
1835
|
<LoadMoreButton
|
|
@@ -1593,3 +1844,11 @@ export function EventListView({
|
|
|
1593
1844
|
</DecryptClickContext.Provider>
|
|
1594
1845
|
);
|
|
1595
1846
|
}
|
|
1847
|
+
|
|
1848
|
+
export function EventListView(props: EventsListProps) {
|
|
1849
|
+
return (
|
|
1850
|
+
<ContextCardProvider>
|
|
1851
|
+
<EventListViewInner {...props} />
|
|
1852
|
+
</ContextCardProvider>
|
|
1853
|
+
);
|
|
1854
|
+
}
|