@workflow/web-shared 5.0.0-beta.2 → 5.0.0-beta.20
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/dist/components/error-boundary.js +1 -1
- package/dist/components/event-list-view.d.ts +16 -1
- package/dist/components/event-list-view.d.ts.map +1 -1
- package/dist/components/event-list-view.js +196 -85
- package/dist/components/hook-actions.js +1 -1
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +5 -1
- package/dist/components/new-trace-viewer/components/copy-button.d.ts +9 -0
- package/dist/components/new-trace-viewer/components/copy-button.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/copy-button.js +27 -0
- package/dist/components/new-trace-viewer/components/event-list.d.ts +10 -0
- package/dist/components/new-trace-viewer/components/event-list.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/event-list.js +46 -0
- 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/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 +15 -0
- package/dist/components/new-trace-viewer/components/split-pane.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/split-pane.js +105 -0
- package/dist/components/new-trace-viewer/components/timeline.d.ts +36 -0
- package/dist/components/new-trace-viewer/components/timeline.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/timeline.js +254 -0
- package/dist/components/new-trace-viewer/components/timeline.module.css +46 -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 +19 -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 +15 -0
- package/dist/components/new-trace-viewer/context.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/context.js +47 -0
- package/dist/components/new-trace-viewer/icons.d.ts +6 -0
- package/dist/components/new-trace-viewer/icons.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/icons.js +15 -0
- 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 +11 -0
- package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/trace-viewer.js +462 -0
- package/dist/components/new-trace-viewer/types.d.ts +3 -0
- package/dist/components/new-trace-viewer/types.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/types.js +2 -0
- package/dist/components/new-trace-viewer/utils.d.ts +61 -0
- package/dist/components/new-trace-viewer/utils.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/utils.js +345 -0
- package/dist/components/run-trace-view.js +1 -1
- package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
- package/dist/components/sidebar/attribute-panel.js +129 -102
- package/dist/components/sidebar/attributes-block.d.ts +28 -0
- package/dist/components/sidebar/attributes-block.d.ts.map +1 -0
- package/dist/components/sidebar/attributes-block.js +81 -0
- package/dist/components/sidebar/conversation-view.js +1 -1
- package/dist/components/sidebar/copyable-data-block.d.ts +1 -0
- package/dist/components/sidebar/copyable-data-block.d.ts.map +1 -1
- package/dist/components/sidebar/copyable-data-block.js +16 -15
- package/dist/components/sidebar/detail-card.d.ts +5 -6
- package/dist/components/sidebar/detail-card.d.ts.map +1 -1
- package/dist/components/sidebar/detail-card.js +32 -16
- package/dist/components/sidebar/entity-detail-panel.d.ts +1 -3
- package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -1
- package/dist/components/sidebar/entity-detail-panel.js +17 -35
- package/dist/components/sidebar/events-list.d.ts +3 -1
- package/dist/components/sidebar/events-list.d.ts.map +1 -1
- package/dist/components/sidebar/events-list.js +36 -22
- package/dist/components/sidebar/resolve-hook-modal.js +1 -1
- package/dist/components/sidebar/sidebar-data-context.d.ts +29 -0
- package/dist/components/sidebar/sidebar-data-context.d.ts.map +1 -0
- package/dist/components/sidebar/sidebar-data-context.js +19 -0
- package/dist/components/sidebar/span-detail-merge.d.ts +16 -0
- package/dist/components/sidebar/span-detail-merge.d.ts.map +1 -0
- package/dist/components/sidebar/span-detail-merge.js +53 -0
- package/dist/components/stream-viewer.d.ts +1 -1
- package/dist/components/stream-viewer.d.ts.map +1 -1
- package/dist/components/stream-viewer.js +3 -27
- 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.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 +14 -0
- package/dist/components/trace-viewer-new.d.ts.map +1 -0
- package/dist/components/trace-viewer-new.js +21 -0
- package/dist/components/ui/alert.js +1 -1
- 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 +1 -1
- 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 +22 -0
- package/dist/components/ui/data-inspector.d.ts.map +1 -1
- package/dist/components/ui/data-inspector.js +103 -13
- package/dist/components/ui/decrypt-button.js +1 -1
- package/dist/components/ui/error-card.js +1 -1
- 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/inspector-theme.d.ts +9 -10
- package/dist/components/ui/inspector-theme.d.ts.map +1 -1
- package/dist/components/ui/inspector-theme.js +39 -72
- package/dist/components/ui/kbd.d.ts +6 -0
- package/dist/components/ui/kbd.d.ts.map +1 -0
- package/dist/components/ui/kbd.js +6 -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 +1 -1
- 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 +1 -3
- package/dist/components/workflow-trace-view.d.ts.map +1 -1
- package/dist/components/workflow-trace-view.js +11 -13
- package/dist/components/workflow-traces/event-colors.d.ts +1 -0
- package/dist/components/workflow-traces/event-colors.d.ts.map +1 -1
- package/dist/components/workflow-traces/event-colors.js +12 -1
- package/dist/components/workflow-traces/trace-colors.js +1 -1
- package/dist/components/workflow-traces/trace-span-construction.d.ts +2 -2
- package/dist/components/workflow-traces/trace-span-construction.d.ts.map +1 -1
- package/dist/components/workflow-traces/trace-span-construction.js +19 -5
- 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 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/lib/event-analysis.js +1 -1
- package/dist/lib/event-materialization.js +1 -1
- 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 +6 -0
- package/dist/lib/hydration.d.ts.map +1 -1
- package/dist/lib/hydration.js +154 -2
- package/dist/lib/stream-display.d.ts +18 -0
- package/dist/lib/stream-display.d.ts.map +1 -0
- package/dist/lib/stream-display.js +30 -0
- package/dist/lib/toast.js +1 -1
- package/dist/lib/trace-builder.d.ts +15 -0
- package/dist/lib/trace-builder.d.ts.map +1 -1
- package/dist/lib/trace-builder.js +29 -3
- package/dist/lib/utils.d.ts +20 -9
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +74 -31
- 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 +484 -1
- package/package.json +10 -5
- package/src/components/event-list-view.tsx +279 -104
- package/src/components/index.ts +7 -0
- package/src/components/new-trace-viewer/components/copy-button.tsx +68 -0
- package/src/components/new-trace-viewer/components/event-list.tsx +136 -0
- 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/span-markers.tsx +173 -0
- package/src/components/new-trace-viewer/components/split-pane.tsx +198 -0
- package/src/components/new-trace-viewer/components/timeline.module.css +46 -0
- package/src/components/new-trace-viewer/components/timeline.tsx +744 -0
- package/src/components/new-trace-viewer/components/trace-viewer-skeleton.tsx +94 -0
- package/src/components/new-trace-viewer/components/use-row-window.ts +140 -0
- package/src/components/new-trace-viewer/context.tsx +90 -0
- package/src/components/new-trace-viewer/icons.tsx +79 -0
- package/src/components/new-trace-viewer/search.ts +178 -0
- package/src/components/new-trace-viewer/trace-viewer.tsx +843 -0
- package/src/components/new-trace-viewer/types.ts +2 -0
- package/src/components/new-trace-viewer/utils.test.ts +182 -0
- package/src/components/new-trace-viewer/utils.ts +519 -0
- package/src/components/sidebar/attribute-panel.tsx +194 -240
- package/src/components/sidebar/attributes-block.tsx +173 -0
- package/src/components/sidebar/copyable-data-block.tsx +49 -27
- package/src/components/sidebar/detail-card.tsx +119 -59
- package/src/components/sidebar/entity-detail-panel.tsx +55 -111
- package/src/components/sidebar/events-list.tsx +85 -96
- package/src/components/sidebar/sidebar-data-context.tsx +62 -0
- package/src/components/sidebar/span-detail-merge.ts +65 -0
- package/src/components/stream-viewer.tsx +18 -40
- 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 +55 -0
- package/src/components/ui/button.tsx +68 -0
- package/src/components/ui/context-card.tsx +784 -0
- package/src/components/ui/data-inspector.tsx +244 -22
- package/src/components/ui/error-stack-block.tsx +84 -55
- package/src/components/ui/icon-button.tsx +53 -0
- package/src/components/ui/inspector-theme.ts +39 -81
- package/src/components/ui/kbd.tsx +21 -0
- package/src/components/ui/timestamp-tooltip.tsx +132 -194
- package/src/components/ui/tooltip.tsx +47 -0
- package/src/components/workflow-trace-view.tsx +19 -15
- package/src/components/workflow-traces/event-colors.ts +12 -0
- package/src/components/workflow-traces/trace-span-construction.ts +24 -5
- 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/exact-event-search-id.ts +67 -0
- package/src/lib/hydration.ts +166 -1
- package/src/lib/stream-display.ts +48 -0
- package/src/lib/trace-builder.ts +34 -2
- package/src/lib/utils.ts +83 -31
- package/src/lib/zstd-browser-decoder.ts +42 -0
- package/src/styles.css +484 -1
- 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/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.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/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/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.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/toast.js.map +0 -1
- package/dist/lib/trace-builder.js.map +0 -1
- package/dist/lib/utils.js.map +0 -1
package/dist/lib/utils.js
CHANGED
|
@@ -3,9 +3,6 @@ import { twMerge } from 'tailwind-merge';
|
|
|
3
3
|
export function cn(...inputs) {
|
|
4
4
|
return twMerge(clsx(inputs));
|
|
5
5
|
}
|
|
6
|
-
const durationFormatter = new Intl.NumberFormat(undefined, {
|
|
7
|
-
maximumFractionDigits: 2,
|
|
8
|
-
});
|
|
9
6
|
const MS_IN_SECOND = 1000;
|
|
10
7
|
const MS_IN_MINUTE = 60 * MS_IN_SECOND;
|
|
11
8
|
const MS_IN_HOUR = 60 * MS_IN_MINUTE;
|
|
@@ -14,48 +11,48 @@ const MS_IN_DAY = 24 * MS_IN_HOUR;
|
|
|
14
11
|
* Formats a duration in milliseconds to a human-readable string.
|
|
15
12
|
*
|
|
16
13
|
* @param ms - Duration in milliseconds
|
|
17
|
-
* @param compact - If true, returns a
|
|
18
|
-
* If false (default), returns multi-part format (e.g., "
|
|
14
|
+
* @param compact - If true, returns a compact format (e.g., "380ms", "2m 30s").
|
|
15
|
+
* If false (default), returns multi-part format (e.g., "1m 13s", "2d 5h 3m 12s").
|
|
19
16
|
*
|
|
20
|
-
* Compact format:
|
|
21
|
-
* - < 1s: shows milliseconds (e.g., "
|
|
17
|
+
* Compact format (timeline markers):
|
|
18
|
+
* - < 1s: shows milliseconds (e.g., "380ms")
|
|
22
19
|
* - < 1m: shows seconds (e.g., "45s")
|
|
23
|
-
* - < 1h: shows minutes (e.g., "
|
|
24
|
-
* - >= 1h: shows hours (e.g., "
|
|
20
|
+
* - < 1h: shows minutes and seconds (e.g., "2m 30s")
|
|
21
|
+
* - >= 1h: shows hours and minutes (e.g., "2h 30m")
|
|
25
22
|
*
|
|
26
23
|
* Full format:
|
|
27
|
-
* - < 1s: shows milliseconds (e.g., "
|
|
28
|
-
* - < 1m: shows seconds (e.g., "
|
|
29
|
-
* - >= 1m: shows
|
|
24
|
+
* - < 1s: shows milliseconds (e.g., "380ms")
|
|
25
|
+
* - < 1m: shows seconds (e.g., "45s")
|
|
26
|
+
* - >= 1m: shows decomposed format with whole seconds (e.g., "1m 13s", "2m 13s")
|
|
30
27
|
*/
|
|
31
28
|
export function formatDuration(ms, compact = false) {
|
|
32
29
|
if (ms === 0) {
|
|
33
|
-
return '
|
|
30
|
+
return '0s';
|
|
34
31
|
}
|
|
35
|
-
// For durations less than 1 second, show milliseconds
|
|
36
32
|
if (ms < MS_IN_SECOND) {
|
|
37
|
-
|
|
33
|
+
const roundedMs = Math.round(ms);
|
|
34
|
+
return roundedMs < MS_IN_SECOND ? `${roundedMs}ms` : '1s';
|
|
38
35
|
}
|
|
39
|
-
|
|
40
|
-
if (
|
|
41
|
-
return `${
|
|
36
|
+
const roundedMs = Math.round(ms / MS_IN_SECOND) * MS_IN_SECOND;
|
|
37
|
+
if (roundedMs < MS_IN_MINUTE) {
|
|
38
|
+
return `${Math.floor(roundedMs / MS_IN_SECOND)}s`;
|
|
42
39
|
}
|
|
43
40
|
// Compact format: multi-unit without decimals (e.g. "8m 20s", "2h 30m")
|
|
44
41
|
if (compact) {
|
|
45
|
-
if (
|
|
46
|
-
const m = Math.floor(
|
|
47
|
-
const s = Math.floor((
|
|
42
|
+
if (roundedMs < MS_IN_HOUR) {
|
|
43
|
+
const m = Math.floor(roundedMs / MS_IN_MINUTE);
|
|
44
|
+
const s = Math.floor((roundedMs % MS_IN_MINUTE) / MS_IN_SECOND);
|
|
48
45
|
return s > 0 ? `${m}m ${s}s` : `${m}m`;
|
|
49
46
|
}
|
|
50
|
-
const h = Math.floor(
|
|
51
|
-
const m = Math.floor((
|
|
47
|
+
const h = Math.floor(roundedMs / MS_IN_HOUR);
|
|
48
|
+
const m = Math.floor((roundedMs % MS_IN_HOUR) / MS_IN_MINUTE);
|
|
52
49
|
return m > 0 ? `${h}h ${m}m` : `${h}h`;
|
|
53
50
|
}
|
|
54
|
-
// Full format:
|
|
55
|
-
const days = Math.floor(
|
|
56
|
-
const hours = Math.floor((
|
|
57
|
-
const minutes = Math.floor((
|
|
58
|
-
const seconds = Math.floor((
|
|
51
|
+
// Full format: decompose into larger units + whole seconds.
|
|
52
|
+
const days = Math.floor(roundedMs / MS_IN_DAY);
|
|
53
|
+
const hours = Math.floor((roundedMs % MS_IN_DAY) / MS_IN_HOUR);
|
|
54
|
+
const minutes = Math.floor((roundedMs % MS_IN_HOUR) / MS_IN_MINUTE);
|
|
55
|
+
const seconds = Math.floor((roundedMs % MS_IN_MINUTE) / MS_IN_SECOND);
|
|
59
56
|
const parts = [];
|
|
60
57
|
if (days > 0) {
|
|
61
58
|
parts.push(`${days}d`);
|
|
@@ -66,9 +63,55 @@ export function formatDuration(ms, compact = false) {
|
|
|
66
63
|
if (minutes > 0) {
|
|
67
64
|
parts.push(`${minutes}m`);
|
|
68
65
|
}
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
parts.push(`${seconds}s`);
|
|
67
|
+
return parts.join(' ');
|
|
68
|
+
}
|
|
69
|
+
// Locale-aware formatter that always renders exactly two fraction digits.
|
|
70
|
+
// Used for the seconds component of precise durations so values are never
|
|
71
|
+
// snapped to a whole second (and thousands separators stay correct).
|
|
72
|
+
const preciseSecondsFormatter = new Intl.NumberFormat(undefined, {
|
|
73
|
+
minimumFractionDigits: 2,
|
|
74
|
+
maximumFractionDigits: 2,
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* Formats a duration in milliseconds without snapping to whole seconds.
|
|
78
|
+
*
|
|
79
|
+
* Unlike {@link formatDuration}, this never rounds a sub-minute value up to
|
|
80
|
+
* the next whole second (e.g. 1626ms renders as "1.63s", not "2s").
|
|
81
|
+
*
|
|
82
|
+
* - < 1s: shows whole milliseconds (e.g. "626ms")
|
|
83
|
+
* - 1s – 1m: shows seconds with two decimals (e.g. "1.63s", "45.20s")
|
|
84
|
+
* - >= 1m: decomposes into d/h/m with two-decimal seconds (e.g. "1m 13.45s")
|
|
85
|
+
*/
|
|
86
|
+
export function formatDurationPrecise(ms) {
|
|
87
|
+
if (ms === 0) {
|
|
88
|
+
return '0s';
|
|
89
|
+
}
|
|
90
|
+
if (ms < MS_IN_SECOND) {
|
|
91
|
+
const roundedMs = Math.round(ms);
|
|
92
|
+
if (roundedMs < MS_IN_SECOND) {
|
|
93
|
+
return `${roundedMs}ms`;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const normalizedMs = Math.round(ms / 10) * 10;
|
|
97
|
+
if (normalizedMs < MS_IN_MINUTE) {
|
|
98
|
+
return `${preciseSecondsFormatter.format(normalizedMs / MS_IN_SECOND)}s`;
|
|
99
|
+
}
|
|
100
|
+
const days = Math.floor(normalizedMs / MS_IN_DAY);
|
|
101
|
+
const hours = Math.floor((normalizedMs % MS_IN_DAY) / MS_IN_HOUR);
|
|
102
|
+
const minutes = Math.floor((normalizedMs % MS_IN_HOUR) / MS_IN_MINUTE);
|
|
103
|
+
const seconds = (normalizedMs % MS_IN_MINUTE) / MS_IN_SECOND;
|
|
104
|
+
const parts = [];
|
|
105
|
+
if (days > 0) {
|
|
106
|
+
parts.push(`${days}d`);
|
|
107
|
+
}
|
|
108
|
+
if (hours > 0) {
|
|
109
|
+
parts.push(`${hours}h`);
|
|
110
|
+
}
|
|
111
|
+
if (minutes > 0) {
|
|
112
|
+
parts.push(`${minutes}m`);
|
|
71
113
|
}
|
|
114
|
+
parts.push(`${preciseSecondsFormatter.format(seconds)}s`);
|
|
72
115
|
return parts.join(' ');
|
|
73
116
|
}
|
|
74
117
|
/**
|
|
@@ -129,4 +172,4 @@ export function identifyStreamSteps(steps) {
|
|
|
129
172
|
};
|
|
130
173
|
});
|
|
131
174
|
}
|
|
132
|
-
//# sourceMappingURL=utils.js.map
|
|
175
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBbUIsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzdDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6QyxNQUFNLFVBQVUsRUFBRSxDQUFDLEdBQUcsTUFBb0I7SUFDeEMsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDL0IsQ0FBQztBQUVELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQztBQUMxQixNQUFNLFlBQVksR0FBRyxFQUFFLEdBQUcsWUFBWSxDQUFDO0FBQ3ZDLE1BQU0sVUFBVSxHQUFHLEVBQUUsR0FBRyxZQUFZLENBQUM7QUFDckMsTUFBTSxTQUFTLEdBQUcsRUFBRSxHQUFHLFVBQVUsQ0FBQztBQUVsQzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLEVBQVUsRUFBRSxPQUFPLEdBQUcsS0FBSztJQUN4RCxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNiLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELElBQUksRUFBRSxHQUFHLFlBQVksRUFBRSxDQUFDO1FBQ3RCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDakMsT0FBTyxTQUFTLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDNUQsQ0FBQztJQUVELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLFlBQVksQ0FBQyxHQUFHLFlBQVksQ0FBQztJQUUvRCxJQUFJLFNBQVMsR0FBRyxZQUFZLEVBQUUsQ0FBQztRQUM3QixPQUFPLEdBQUcsSUFB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QU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE9BQU8sUUFBMEIsQ0FBQztBQUNwQyxDQUFDO0FBWUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQUMsS0FBYTtJQUMvQyxPQUFPLEtBQUs7U0FDVCxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDL0MsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7UUFDWixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxTQUFTLENBQUM7UUFDbEUsTUFBTSxZQUFZLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUUzRCxPQUFPO1lBQ0wsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtZQUN2QixXQUFXLEVBQUUsWUFBWTtZQUN6QixZQUFZO1NBQ2IsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgU3RlcCB9IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgdHlwZSB7IE1vZGVsTWVzc2FnZSB9IGZyb20gJ2FpJztcbmltcG9ydCB7IHR5cGUgQ2xhc3NWYWx1ZSwgY2xzeCB9IGZyb20gJ2Nsc3gnO1xuaW1wb3J0IHsgdHdNZXJnZSB9IGZyb20gJ3RhaWx3aW5kLW1lcmdlJztcblxuZXhwb3J0IGZ1bmN0aW9uIGNuKC4uLmlucHV0czogQ2xhc3NWYWx1ZVtdKSB7XG4gIHJldHVybiB0d01lcmdlKGNsc3goaW5wdXRzKSk7XG59XG5cbmNvbnN0IE1TX0lOX1NFQ09ORCA9IDEwMDA7XG5jb25zdCBNU19JTl9NSU5VVEUgPSA2MCAqIE1TX0lOX1NFQ09ORDtcbmNvbnN0IE1TX0lOX0hPVVIgPSA2MCAqIE1TX0lOX01JTlVURTtcbmNvbnN0IE1TX0lOX0RBWSA9IDI0ICogTVNfSU5fSE9VUjtcblxuLyoqXG4gKiBGb3JtYXRzIGEgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzIHRvIGEgaHVtYW4tcmVhZGFibGUgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSBtcyAtIER1cmF0aW9uIGluIG1pbGxpc2Vjb25kc1xuICogQHBhcmFtIGNvbXBhY3QgLSBJZiB0cnVlLCByZXR1cm5zIGEgY29tcGFjdCBmb3JtYXQgKGUuZy4sIFwiMzgwbXNcIiwgXCIybSAzMHNcIikuXG4gKiAgICAgICAgICAgICAgICAgIElmIGZhbHNlIChkZWZhdWx0KSwgcmV0dXJucyBtdWx0aS1wYXJ0IGZvcm1hdCAoZS5nLiwgXCIxbSAxM3NcIiwgXCIyZCA1aCAzbSAxMnNcIikuXG4gKlxuICogQ29tcGFjdCBmb3JtYXQgKHRpbWVsaW5lIG1hcmtlcnMpOlxuICogLSA8IDFzOiBzaG93cyBtaWxsaXNlY29uZHMgKGUuZy4sIFwiMzgwbXNcIilcbiAqIC0gPCAxbTogc2hvd3Mgc2Vjb25kcyAoZS5nLiwgXCI0NXNcIilcbiAqIC0gPCAxaDogc2hvd3MgbWludXRlcyBhbmQgc2Vjb25kcyAoZS5nLiwgXCIybSAzMHNcIilcbiAqIC0gPj0gMWg6IHNob3dzIGhvdXJzIGFuZCBtaW51dGVzIChlLmcuLCBcIjJoIDMwbVwiKVxuICpcbiAqIEZ1bGwgZm9ybWF0OlxuICogLSA8IDFzOiBzaG93cyBtaWxsaXNlY29uZHMgKGUuZy4sIFwiMzgwbXNcIilcbiAqIC0gPCAxbTogc2hvd3Mgc2Vjb25kcyAoZS5nLiwgXCI0NXNcIilcbiAqIC0gPj0gMW06IHNob3dzIGRlY29tcG9zZWQgZm9ybWF0IHdpdGggd2hvbGUgc2Vjb25kcyAoZS5nLiwgXCIxbSAxM3NcIiwgXCIybSAxM3NcIilcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdER1cmF0aW9uKG1zOiBudW1iZXIsIGNvbXBhY3QgPSBmYWxzZSk6IHN0cmluZyB7XG4gIGlmIChtcyA9PT0gMCkge1xuICAgIHJldHVybiAnMHMnO1xuICB9XG5cbiAgaWYgKG1zIDwgTVNfSU5fU0VDT05EKSB7XG4gICAgY29uc3Qgcm91bmRlZE1zID0gTWF0aC5yb3VuZChtcyk7XG4gICAgcmV0dXJuIHJvdW5kZWRNcyA8IE1TX0lOX1NFQ09ORCA/IGAke3JvdW5kZWRNc31tc2AgOiAnMXMnO1xuICB9XG5cbiAgY29uc3Qgcm91bmRlZE1zID0gTWF0aC5yb3VuZChtcyAvIE1TX0lOX1NFQ09ORCkgKiBNU19JTl9TRUNPTkQ7XG5cbiAgaWYgKHJvdW5kZWRNcyA8IE1TX0lOX01JTlVURSkge1xuICAgIHJldHVybiBgJHtNYXRoLmZsb29yKHJvdW5kZWRNcyAvIE1TX0lOX1NFQ09ORCl9c2A7XG4gIH1cblxuICAvLyBDb21wYWN0IGZvcm1hdDogbXVsdGktdW5pdCB3aXRob3V0IGRlY2ltYWxzIChlLmcuIFwiOG0gMjBzXCIsIFwiMmggMzBtXCIpXG4gIGlmIChjb21wYWN0KSB7XG4gICAgaWYgKHJvdW5kZWRNcyA8IE1TX0lOX0hPVVIpIHtcbiAgICAgIGNvbnN0IG0gPSBNYXRoLmZsb29yKHJvdW5kZWRNcyAvIE1TX0lOX01JTlVURSk7XG4gICAgICBjb25zdCBzID0gTWF0aC5mbG9vcigocm91bmRlZE1zICUgTVNfSU5fTUlOVVRFKSAvIE1TX0lOX1NFQ09ORCk7XG4gICAgICByZXR1cm4gcyA+IDAgPyBgJHttfW0gJHtzfXNgIDogYCR7bX1tYDtcbiAgICB9XG4gICAgY29uc3QgaCA9IE1hdGguZmxvb3Iocm91bmRlZE1zIC8gTVNfSU5fSE9VUik7XG4gICAgY29uc3QgbSA9IE1hdGguZmxvb3IoKHJvdW5kZWRNcyAlIE1TX0lOX0hPVVIpIC8gTVNfSU5fTUlOVVRFKTtcbiAgICByZXR1cm4gbSA+IDAgPyBgJHtofWggJHttfW1gIDogYCR7aH1oYDtcbiAgfVxuXG4gIC8vIEZ1bGwgZm9ybWF0OiBkZWNvbXBvc2UgaW50byBsYXJnZXIgdW5pdHMgKyB3aG9sZSBzZWNvbmRzLlxuICBjb25zdCBkYXlzID0gTWF0aC5mbG9vcihyb3VuZGVkTXMgLyBNU19JTl9EQVkpO1xuICBjb25zdCBob3VycyA9IE1hdGguZmxvb3IoKHJvdW5kZWRNcyAlIE1TX0lOX0RBWSkgLyBNU19JTl9IT1VSKTtcbiAgY29uc3QgbWludXRlcyA9IE1hdGguZmxvb3IoKHJvdW5kZWRNcyAlIE1TX0lOX0hPVVIpIC8gTVNfSU5fTUlOVVRFKTtcbiAgY29uc3Qgc2Vjb25kcyA9IE1hdGguZmxvb3IoKHJvdW5kZWRNcyAlIE1TX0lOX01JTlVURSkgLyBNU19JTl9TRUNPTkQpO1xuXG4gIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGlmIChkYXlzID4gMCkge1xuICAgIHBhcnRzLnB1c2goYCR7ZGF5c31kYCk7XG4gIH1cbiAgaWYgKGhvdXJzID4gMCkge1xuICAgIHBhcnRzLnB1c2goYCR7aG91cnN9aGApO1xuICB9XG4gIGlmIChtaW51dGVzID4gMCkge1xuICAgIHBhcnRzLnB1c2goYCR7bWludXRlc31tYCk7XG4gIH1cbiAgcGFydHMucHVzaChgJHtzZWNvbmRzfXNgKTtcblxuICByZXR1cm4gcGFydHMuam9pbignICcpO1xufVxuXG4vLyBMb2NhbGUtYXdhcmUgZm9ybWF0dGVyIHRoYXQgYWx3YXlzIHJlbmRlcnMgZXhhY3RseSB0d28gZnJhY3Rpb24gZGlnaXRzLlxuLy8gVXNlZCBmb3IgdGhlIHNlY29uZHMgY29tcG9uZW50IG9mIHByZWNpc2UgZHVyYXRpb25zIHNvIHZhbHVlcyBhcmUgbmV2ZXJcbi8vIHNuYXBwZWQgdG8gYSB3aG9sZSBzZWNvbmQgKGFuZCB0aG91c2FuZHMgc2VwYXJhdG9ycyBzdGF5IGNvcnJlY3QpLlxuY29uc3QgcHJlY2lzZVNlY29uZHNGb3JtYXR0ZXIgPSBuZXcgSW50bC5OdW1iZXJGb3JtYXQodW5kZWZpbmVkLCB7XG4gIG1pbmltdW1GcmFjdGlvbkRpZ2l0czogMixcbiAgbWF4aW11bUZyYWN0aW9uRGlnaXRzOiAyLFxufSk7XG5cbi8qKlxuICogRm9ybWF0cyBhIGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcyB3aXRob3V0IHNuYXBwaW5nIHRvIHdob2xlIHNlY29uZHMuXG4gKlxuICogVW5saWtlIHtAbGluayBmb3JtYXREdXJhdGlvbn0sIHRoaXMgbmV2ZXIgcm91bmRzIGEgc3ViLW1pbnV0ZSB2YWx1ZSB1cCB0b1xuICogdGhlIG5leHQgd2hvbGUgc2Vjb25kIChlLmcuIDE2MjZtcyByZW5kZXJzIGFzIFwiMS42M3NcIiwgbm90IFwiMnNcIikuXG4gKlxuICogLSA8IDFzOiBzaG93cyB3aG9sZSBtaWxsaXNlY29uZHMgKGUuZy4gXCI2MjZtc1wiKVxuICogLSAxcyDigJMgMW06IHNob3dzIHNlY29uZHMgd2l0aCB0d28gZGVjaW1hbHMgKGUuZy4gXCIxLjYzc1wiLCBcIjQ1LjIwc1wiKVxuICogLSA+PSAxbTogZGVjb21wb3NlcyBpbnRvIGQvaC9tIHdpdGggdHdvLWRlY2ltYWwgc2Vjb25kcyAoZS5nLiBcIjFtIDEzLjQ1c1wiKVxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0RHVyYXRpb25QcmVjaXNlKG1zOiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAobXMgPT09IDApIHtcbiAgICByZXR1cm4gJzBzJztcbiAgfVxuXG4gIGlmIChtcyA8IE1TX0lOX1NFQ09ORCkge1xuICAgIGNvbnN0IHJvdW5kZWRNcyA9IE1hdGgucm91bmQobXMpO1xuICAgIGlmIChyb3VuZGVkTXMgPCBNU19JTl9TRUNPTkQpIHtcbiAgICAgIHJldHVybiBgJHtyb3VuZGVkTXN9bXNgO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG5vcm1hbGl6ZWRNcyA9IE1hdGgucm91bmQobXMgLyAxMCkgKiAxMDtcblxuICBpZiAobm9ybWFsaXplZE1zIDwgTVNfSU5fTUlOVVRFKSB7XG4gICAgcmV0dXJuIGAke3ByZWNpc2VTZWNvbmRzRm9ybWF0dGVyLmZvcm1hdChub3JtYWxpemVkTXMgLyBNU19JTl9TRUNPTkQpfXNgO1xuICB9XG5cbiAgY29uc3QgZGF5cyA9IE1hdGguZmxvb3Iobm9ybWFsaXplZE1zIC8gTVNfSU5fREFZKTtcbiAgY29uc3QgaG91cnMgPSBNYXRoLmZsb29yKChub3JtYWxpemVkTXMgJSBNU19JTl9EQVkpIC8gTVNfSU5fSE9VUik7XG4gIGNvbnN0IG1pbnV0ZXMgPSBNYXRoLmZsb29yKChub3JtYWxpemVkTXMgJSBNU19JTl9IT1VSKSAvIE1TX0lOX01JTlVURSk7XG4gIGNvbnN0IHNlY29uZHMgPSAobm9ybWFsaXplZE1zICUgTVNfSU5fTUlOVVRFKSAvIE1TX0lOX1NFQ09ORDtcblxuICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcblxuICBpZiAoZGF5cyA+IDApIHtcbiAgICBwYXJ0cy5wdXNoKGAke2RheXN9ZGApO1xuICB9XG4gIGlmIChob3VycyA+IDApIHtcbiAgICBwYXJ0cy5wdXNoKGAke2hvdXJzfWhgKTtcbiAgfVxuICBpZiAobWludXRlcyA+IDApIHtcbiAgICBwYXJ0cy5wdXNoKGAke21pbnV0ZXN9bWApO1xuICB9XG4gIHBhcnRzLnB1c2goYCR7cHJlY2lzZVNlY29uZHNGb3JtYXR0ZXIuZm9ybWF0KHNlY29uZHMpfXNgKTtcblxuICByZXR1cm4gcGFydHMuam9pbignICcpO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmb3JtYXR0ZWQgcGFnaW5hdGlvbiBkaXNwbGF5IHN0cmluZ1xuICogQHBhcmFtIGN1cnJlbnRQYWdlIC0gVGhlIGN1cnJlbnQgcGFnZSBudW1iZXJcbiAqIEBwYXJhbSB0b3RhbFBhZ2VzIC0gVGhlIHRvdGFsIG51bWJlciBvZiBwYWdlcyB2aXNpdGVkIHNvIGZhclxuICogQHBhcmFtIGhhc01vcmUgLSBXaGV0aGVyIHRoZXJlIGFyZSBtb3JlIHBhZ2VzIGF2YWlsYWJsZVxuICogQHJldHVybnMgRm9ybWF0dGVkIHN0cmluZyBsaWtlIFwiUGFnZSAxIG9mIDMrXCIgb3IgXCJQYWdlIDIgb2YgMlwiXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYWdpbmF0aW9uRGlzcGxheShcbiAgY3VycmVudFBhZ2U6IG51bWJlcixcbiAgdG90YWxQYWdlczogbnVtYmVyLFxuICBoYXNNb3JlOiBib29sZWFuXG4pOiBzdHJpbmcge1xuICBpZiAoaGFzTW9yZSkge1xuICAgIHJldHVybiBgUGFnZSAke2N1cnJlbnRQYWdlfSBvZiAke3RvdGFsUGFnZXN9K2A7XG4gIH1cbiAgcmV0dXJuIGBQYWdlICR7Y3VycmVudFBhZ2V9IG9mICR7dG90YWxQYWdlc31gO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBEdXJhYmxlIEFnZW50IFV0aWxpdGllc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIENoZWNrIGlmIGEgc3RlcCBpcyBhIGRvU3RyZWFtU3RlcCAoTExNIGNhbGwgd2l0aCBjb252ZXJzYXRpb24gaW5wdXQpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RvU3RyZWFtU3RlcChzdGVwTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBzdGVwTmFtZS5lbmRzV2l0aCgnLy9kb1N0cmVhbVN0ZXAnKTtcbn1cblxuLyoqXG4gKiBFeHRyYWN0IHRoZSBjb252ZXJzYXRpb24gZnJvbSBhIGh5ZHJhdGVkIGRvU3RyZWFtU3RlcCBpbnB1dC5cbiAqIGRvU3RyZWFtU3RlcCBzaWduYXR1cmU6IChjb252ZXJzYXRpb25Qcm9tcHQsIG1vZGVsLCB3cml0YWJsZSwgdG9vbHMsIG9wdGlvbnMpXG4gKiBTbyBpbnB1dFswXSBpcyB0aGUgY29udmVyc2F0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdENvbnZlcnNhdGlvbihzdGVwSW5wdXQ6IHVua25vd24pOiBNb2RlbE1lc3NhZ2VbXSB8IG51bGwge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoc3RlcElucHV0KSB8fCBzdGVwSW5wdXQubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBmaXJzdEFyZyA9IHN0ZXBJbnB1dFswXTtcblxuICBpZiAoIUFycmF5LmlzQXJyYXkoZmlyc3RBcmcpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBWYWxpZGF0ZSBpdCBsb29rcyBsaWtlIE1vZGVsTWVzc2FnZVtdXG4gIGlmIChcbiAgICAhZmlyc3RBcmcuZXZlcnkoKG1zZykgPT4gbXNnICYmIHR5cGVvZiBtc2cgPT09ICdvYmplY3QnICYmICdyb2xlJyBpbiBtc2cpXG4gICkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIGZpcnN0QXJnIGFzIE1vZGVsTWVzc2FnZVtdO1xufVxuXG4vKipcbiAqIEEgZG9TdHJlYW1TdGVwIHdpdGggaXRzIGNvbnZlcnNhdGlvbiBpbnB1dCBleHRyYWN0ZWRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdHJlYW1TdGVwIHtcbiAgc3RlcElkOiBzdHJpbmc7XG4gIHN0ZXBOYW1lOiBzdHJpbmc7XG4gIGRpc3BsYXlOYW1lOiBzdHJpbmc7XG4gIGNvbnZlcnNhdGlvbjogTW9kZWxNZXNzYWdlW107XG59XG5cbi8qKlxuICogSWRlbnRpZmllcyBhbGwgc3RyZWFtIHN0ZXBzIChkb1N0cmVhbVN0ZXApIGluIGEgcnVuIGFuZCBleHRyYWN0cyB0aGVpciBjb252ZXJzYXRpb25zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaWRlbnRpZnlTdHJlYW1TdGVwcyhzdGVwczogU3RlcFtdKTogU3RyZWFtU3RlcFtdIHtcbiAgcmV0dXJuIHN0ZXBzXG4gICAgLmZpbHRlcigoc3RlcCkgPT4gaXNEb1N0cmVhbVN0ZXAoc3RlcC5zdGVwTmFtZSkpXG4gICAgLm1hcCgoc3RlcCkgPT4ge1xuICAgICAgY29uc3QgZnVuY3Rpb25OYW1lID0gc3RlcC5zdGVwTmFtZS5zcGxpdCgnLy8nKS5wb3AoKSA/PyAndW5rbm93bic7XG4gICAgICBjb25zdCBjb252ZXJzYXRpb24gPSBleHRyYWN0Q29udmVyc2F0aW9uKHN0ZXAuaW5wdXQpID8/IFtdO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdGVwSWQ6IHN0ZXAuc3RlcElkLFxuICAgICAgICBzdGVwTmFtZTogc3RlcC5zdGVwTmFtZSxcbiAgICAgICAgZGlzcGxheU5hbWU6IGZ1bmN0aW9uTmFtZSxcbiAgICAgICAgY29udmVyc2F0aW9uLFxuICAgICAgfTtcbiAgICB9KTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register the browser zstd decoder with `@workflow/core` (idempotent).
|
|
3
|
+
* Call this before hydrating payloads that may be zstd-compressed; the
|
|
4
|
+
* actual WASM compile + decode happens lazily on first use.
|
|
5
|
+
*/
|
|
6
|
+
export declare function ensureZstdDecoderRegistered(): void;
|
|
7
|
+
//# sourceMappingURL=zstd-browser-decoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zstd-browser-decoder.d.ts","sourceRoot":"","sources":["../../src/lib/zstd-browser-decoder.ts"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAQlD"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser zstd decoder for the o11y read path.
|
|
3
|
+
*
|
|
4
|
+
* The Web `DecompressionStream` has no zstd support, so `@workflow/core`'s
|
|
5
|
+
* `hydrateDataWithKey` delegates zstd inflation to a decoder registered via
|
|
6
|
+
* `registerZstdDecoder`. This module supplies that decoder, backed by the
|
|
7
|
+
* `@tootallnate/zstd-wasm` single-file WASM decoder.
|
|
8
|
+
*
|
|
9
|
+
* The package leaves WASM sourcing to the caller; we resolve the shipped
|
|
10
|
+
* `zstd.wasm` as a bundler asset (`new URL(..., import.meta.url)`, the same
|
|
11
|
+
* pattern the trace-viewer Worker uses) and compile it once, lazily — the
|
|
12
|
+
* WASM is fetched only the first time a zstd payload is actually decoded.
|
|
13
|
+
*/
|
|
14
|
+
import { registerZstdDecoder } from '@workflow/core/serialization-format';
|
|
15
|
+
let registered = false;
|
|
16
|
+
let modulePromise;
|
|
17
|
+
function loadWasmModule() {
|
|
18
|
+
if (!modulePromise) {
|
|
19
|
+
const url = new URL('@tootallnate/zstd-wasm/zstd.wasm', import.meta.url);
|
|
20
|
+
modulePromise = fetch(url)
|
|
21
|
+
.then((res) => res.arrayBuffer())
|
|
22
|
+
.then((bytes) => WebAssembly.compile(bytes));
|
|
23
|
+
}
|
|
24
|
+
return modulePromise;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Register the browser zstd decoder with `@workflow/core` (idempotent).
|
|
28
|
+
* Call this before hydrating payloads that may be zstd-compressed; the
|
|
29
|
+
* actual WASM compile + decode happens lazily on first use.
|
|
30
|
+
*/
|
|
31
|
+
export function ensureZstdDecoderRegistered() {
|
|
32
|
+
if (registered)
|
|
33
|
+
return;
|
|
34
|
+
registered = true;
|
|
35
|
+
registerZstdDecoder(async (payload) => {
|
|
36
|
+
const { decompressBytes } = await import('@tootallnate/zstd-wasm');
|
|
37
|
+
const wasmModule = await loadWasmModule();
|
|
38
|
+
return decompressBytes(wasmModule, payload);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoienN0ZC1icm93c2VyLWRlY29kZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3pzdGQtYnJvd3Nlci1kZWNvZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBRTFFLElBQUksVUFBVSxHQUFHLEtBQUssQ0FBQztBQUN2QixJQUFJLGFBQXNELENBQUM7QUFFM0QsU0FBUyxjQUFjO0lBQ3JCLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNuQixNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxrQ0FBa0MsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pFLGFBQWEsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDO2FBQ3ZCLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDO2FBQ2hDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFDRCxPQUFPLGFBQWEsQ0FBQztBQUN2QixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSwyQkFBMkI7SUFDekMsSUFBSSxVQUFVO1FBQUUsT0FBTztJQUN2QixVQUFVLEdBQUcsSUFBSSxDQUFDO0lBQ2xCLG1CQUFtQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtRQUNwQyxNQUFNLEVBQUUsZUFBZSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsd0JBQXdCLENBQUMsQ0FBQztRQUNuRSxNQUFNLFVBQVUsR0FBRyxNQUFNLGNBQWMsRUFBRSxDQUFDO1FBQzFDLE9BQU8sZUFBZSxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUM5QyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEJyb3dzZXIgenN0ZCBkZWNvZGVyIGZvciB0aGUgbzExeSByZWFkIHBhdGguXG4gKlxuICogVGhlIFdlYiBgRGVjb21wcmVzc2lvblN0cmVhbWAgaGFzIG5vIHpzdGQgc3VwcG9ydCwgc28gYEB3b3JrZmxvdy9jb3JlYCdzXG4gKiBgaHlkcmF0ZURhdGFXaXRoS2V5YCBkZWxlZ2F0ZXMgenN0ZCBpbmZsYXRpb24gdG8gYSBkZWNvZGVyIHJlZ2lzdGVyZWQgdmlhXG4gKiBgcmVnaXN0ZXJac3RkRGVjb2RlcmAuIFRoaXMgbW9kdWxlIHN1cHBsaWVzIHRoYXQgZGVjb2RlciwgYmFja2VkIGJ5IHRoZVxuICogYEB0b290YWxsbmF0ZS96c3RkLXdhc21gIHNpbmdsZS1maWxlIFdBU00gZGVjb2Rlci5cbiAqXG4gKiBUaGUgcGFja2FnZSBsZWF2ZXMgV0FTTSBzb3VyY2luZyB0byB0aGUgY2FsbGVyOyB3ZSByZXNvbHZlIHRoZSBzaGlwcGVkXG4gKiBgenN0ZC53YXNtYCBhcyBhIGJ1bmRsZXIgYXNzZXQgKGBuZXcgVVJMKC4uLiwgaW1wb3J0Lm1ldGEudXJsKWAsIHRoZSBzYW1lXG4gKiBwYXR0ZXJuIHRoZSB0cmFjZS12aWV3ZXIgV29ya2VyIHVzZXMpIGFuZCBjb21waWxlIGl0IG9uY2UsIGxhemlseSDigJQgdGhlXG4gKiBXQVNNIGlzIGZldGNoZWQgb25seSB0aGUgZmlyc3QgdGltZSBhIHpzdGQgcGF5bG9hZCBpcyBhY3R1YWxseSBkZWNvZGVkLlxuICovXG5pbXBvcnQgeyByZWdpc3RlclpzdGREZWNvZGVyIH0gZnJvbSAnQHdvcmtmbG93L2NvcmUvc2VyaWFsaXphdGlvbi1mb3JtYXQnO1xuXG5sZXQgcmVnaXN0ZXJlZCA9IGZhbHNlO1xubGV0IG1vZHVsZVByb21pc2U6IFByb21pc2U8V2ViQXNzZW1ibHkuTW9kdWxlPiB8IHVuZGVmaW5lZDtcblxuZnVuY3Rpb24gbG9hZFdhc21Nb2R1bGUoKTogUHJvbWlzZTxXZWJBc3NlbWJseS5Nb2R1bGU+IHtcbiAgaWYgKCFtb2R1bGVQcm9taXNlKSB7XG4gICAgY29uc3QgdXJsID0gbmV3IFVSTCgnQHRvb3RhbGxuYXRlL3pzdGQtd2FzbS96c3RkLndhc20nLCBpbXBvcnQubWV0YS51cmwpO1xuICAgIG1vZHVsZVByb21pc2UgPSBmZXRjaCh1cmwpXG4gICAgICAudGhlbigocmVzKSA9PiByZXMuYXJyYXlCdWZmZXIoKSlcbiAgICAgIC50aGVuKChieXRlcykgPT4gV2ViQXNzZW1ibHkuY29tcGlsZShieXRlcykpO1xuICB9XG4gIHJldHVybiBtb2R1bGVQcm9taXNlO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVyIHRoZSBicm93c2VyIHpzdGQgZGVjb2RlciB3aXRoIGBAd29ya2Zsb3cvY29yZWAgKGlkZW1wb3RlbnQpLlxuICogQ2FsbCB0aGlzIGJlZm9yZSBoeWRyYXRpbmcgcGF5bG9hZHMgdGhhdCBtYXkgYmUgenN0ZC1jb21wcmVzc2VkOyB0aGVcbiAqIGFjdHVhbCBXQVNNIGNvbXBpbGUgKyBkZWNvZGUgaGFwcGVucyBsYXppbHkgb24gZmlyc3QgdXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5zdXJlWnN0ZERlY29kZXJSZWdpc3RlcmVkKCk6IHZvaWQge1xuICBpZiAocmVnaXN0ZXJlZCkgcmV0dXJuO1xuICByZWdpc3RlcmVkID0gdHJ1ZTtcbiAgcmVnaXN0ZXJac3RkRGVjb2Rlcihhc3luYyAocGF5bG9hZCkgPT4ge1xuICAgIGNvbnN0IHsgZGVjb21wcmVzc0J5dGVzIH0gPSBhd2FpdCBpbXBvcnQoJ0B0b290YWxsbmF0ZS96c3RkLXdhc20nKTtcbiAgICBjb25zdCB3YXNtTW9kdWxlID0gYXdhaXQgbG9hZFdhc21Nb2R1bGUoKTtcbiAgICByZXR1cm4gZGVjb21wcmVzc0J5dGVzKHdhc21Nb2R1bGUsIHBheWxvYWQpO1xuICB9KTtcbn1cbiJdfQ==
|