@workflow/web-shared 5.0.0-beta.13 → 5.0.0-beta.15
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/new-trace-viewer/components/event-list.js +3 -3
- package/dist/components/new-trace-viewer/components/timeline.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/components/timeline.js +26 -14
- package/dist/components/new-trace-viewer/components/timeline.module.css +31 -0
- package/dist/components/new-trace-viewer/utils.d.ts +1 -1
- package/dist/components/new-trace-viewer/utils.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/utils.js +12 -5
- package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
- package/dist/components/sidebar/attribute-panel.js +8 -4
- package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -1
- package/dist/components/sidebar/entity-detail-panel.js +12 -11
- 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 +4 -3
- 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/trace-viewer/util/timing.d.ts +2 -2
- package/dist/components/trace-viewer/util/timing.d.ts.map +1 -1
- package/dist/components/trace-viewer/util/timing.js +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/lib/utils.d.ts +11 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +49 -1
- package/package.json +4 -4
- package/src/components/new-trace-viewer/components/event-list.tsx +2 -2
- package/src/components/new-trace-viewer/components/timeline.module.css +31 -0
- package/src/components/new-trace-viewer/components/timeline.tsx +60 -12
- package/src/components/new-trace-viewer/utils.ts +12 -4
- package/src/components/sidebar/attribute-panel.tsx +7 -3
- package/src/components/sidebar/entity-detail-panel.tsx +28 -13
- package/src/components/sidebar/events-list.tsx +34 -25
- package/src/components/sidebar/span-detail-merge.ts +65 -0
- package/src/components/trace-viewer/util/timing.ts +2 -2
- package/src/index.ts +1 -0
- package/src/lib/utils.ts +57 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const hasField = (
|
|
2
|
+
value: object,
|
|
3
|
+
key: string
|
|
4
|
+
): value is Record<string, unknown> => key in value;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Returns true when the fetched `detail` belongs to the current selection.
|
|
8
|
+
* The fetch lags selection, so it can briefly hold a previously selected span
|
|
9
|
+
* (even a different resource type); reject it before merging or its fields
|
|
10
|
+
* union into the wrong panel. Steps/hooks/waits carry their parent `runId`, so
|
|
11
|
+
* a `run` selection excludes objects identifiable as a child resource.
|
|
12
|
+
*/
|
|
13
|
+
export function spanDetailMatchesSelection(
|
|
14
|
+
detail: unknown,
|
|
15
|
+
resource: string | undefined,
|
|
16
|
+
resourceId: string | undefined
|
|
17
|
+
): boolean {
|
|
18
|
+
if (!detail || typeof detail !== 'object' || !resource || !resourceId) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
switch (resource) {
|
|
22
|
+
case 'step':
|
|
23
|
+
return hasField(detail, 'stepId') && detail.stepId === resourceId;
|
|
24
|
+
case 'hook':
|
|
25
|
+
return hasField(detail, 'hookId') && detail.hookId === resourceId;
|
|
26
|
+
case 'sleep':
|
|
27
|
+
return hasField(detail, 'waitId') && detail.waitId === resourceId;
|
|
28
|
+
case 'run':
|
|
29
|
+
return (
|
|
30
|
+
hasField(detail, 'runId') &&
|
|
31
|
+
!('stepId' in detail) &&
|
|
32
|
+
!('hookId' in detail) &&
|
|
33
|
+
!('waitId' in detail) &&
|
|
34
|
+
detail.runId === resourceId
|
|
35
|
+
);
|
|
36
|
+
default:
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Merges fetched `detail` over the span's own data. The detail supplies the
|
|
43
|
+
* heavy fields the trace strips (input/output/error/metadata, sleep resumeAt);
|
|
44
|
+
* the span's identity, status, and event-derived timestamps stay authoritative
|
|
45
|
+
* so they don't flicker to the backend row's millisecond-different values.
|
|
46
|
+
*/
|
|
47
|
+
export function mergeSpanDetail(spanData: unknown, detail: unknown): unknown {
|
|
48
|
+
if (!detail || typeof detail !== 'object') {
|
|
49
|
+
return spanData;
|
|
50
|
+
}
|
|
51
|
+
if (!spanData || typeof spanData !== 'object') {
|
|
52
|
+
return detail;
|
|
53
|
+
}
|
|
54
|
+
// Skip `undefined` span fields so they don't clobber a value the detail
|
|
55
|
+
// legitimately provides (e.g. a step's optional startedAt).
|
|
56
|
+
const merged: Record<string, unknown> = { ...detail };
|
|
57
|
+
for (const [key, value] of Object.entries(
|
|
58
|
+
spanData as Record<string, unknown>
|
|
59
|
+
)) {
|
|
60
|
+
if (value !== undefined) {
|
|
61
|
+
merged[key] = value;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return merged;
|
|
65
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { formatDuration } from '../../../lib/utils';
|
|
1
|
+
import { formatDuration, formatDurationPrecise } from '../../../lib/utils';
|
|
2
2
|
|
|
3
|
-
export { formatDuration };
|
|
3
|
+
export { formatDuration, formatDurationPrecise };
|
|
4
4
|
|
|
5
5
|
export function getHighResInMs([seconds, nanoseconds]: [
|
|
6
6
|
number,
|
package/src/index.ts
CHANGED
package/src/lib/utils.ts
CHANGED
|
@@ -80,6 +80,63 @@ export function formatDuration(ms: number, compact = false): string {
|
|
|
80
80
|
return parts.join(' ');
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
// Locale-aware formatter that always renders exactly two fraction digits.
|
|
84
|
+
// Used for the seconds component of precise durations so values are never
|
|
85
|
+
// snapped to a whole second (and thousands separators stay correct).
|
|
86
|
+
const preciseSecondsFormatter = new Intl.NumberFormat(undefined, {
|
|
87
|
+
minimumFractionDigits: 2,
|
|
88
|
+
maximumFractionDigits: 2,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Formats a duration in milliseconds without snapping to whole seconds.
|
|
93
|
+
*
|
|
94
|
+
* Unlike {@link formatDuration}, this never rounds a sub-minute value up to
|
|
95
|
+
* the next whole second (e.g. 1626ms renders as "1.63s", not "2s").
|
|
96
|
+
*
|
|
97
|
+
* - < 1s: shows whole milliseconds (e.g. "626ms")
|
|
98
|
+
* - 1s – 1m: shows seconds with two decimals (e.g. "1.63s", "45.20s")
|
|
99
|
+
* - >= 1m: decomposes into d/h/m with two-decimal seconds (e.g. "1m 13.45s")
|
|
100
|
+
*/
|
|
101
|
+
export function formatDurationPrecise(ms: number): string {
|
|
102
|
+
if (ms === 0) {
|
|
103
|
+
return '0s';
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (ms < MS_IN_SECOND) {
|
|
107
|
+
const roundedMs = Math.round(ms);
|
|
108
|
+
if (roundedMs < MS_IN_SECOND) {
|
|
109
|
+
return `${roundedMs}ms`;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const normalizedMs = Math.round(ms / 10) * 10;
|
|
114
|
+
|
|
115
|
+
if (normalizedMs < MS_IN_MINUTE) {
|
|
116
|
+
return `${preciseSecondsFormatter.format(normalizedMs / MS_IN_SECOND)}s`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const days = Math.floor(normalizedMs / MS_IN_DAY);
|
|
120
|
+
const hours = Math.floor((normalizedMs % MS_IN_DAY) / MS_IN_HOUR);
|
|
121
|
+
const minutes = Math.floor((normalizedMs % MS_IN_HOUR) / MS_IN_MINUTE);
|
|
122
|
+
const seconds = (normalizedMs % MS_IN_MINUTE) / MS_IN_SECOND;
|
|
123
|
+
|
|
124
|
+
const parts: string[] = [];
|
|
125
|
+
|
|
126
|
+
if (days > 0) {
|
|
127
|
+
parts.push(`${days}d`);
|
|
128
|
+
}
|
|
129
|
+
if (hours > 0) {
|
|
130
|
+
parts.push(`${hours}h`);
|
|
131
|
+
}
|
|
132
|
+
if (minutes > 0) {
|
|
133
|
+
parts.push(`${minutes}m`);
|
|
134
|
+
}
|
|
135
|
+
parts.push(`${preciseSecondsFormatter.format(seconds)}s`);
|
|
136
|
+
|
|
137
|
+
return parts.join(' ');
|
|
138
|
+
}
|
|
139
|
+
|
|
83
140
|
/**
|
|
84
141
|
* Returns a formatted pagination display string
|
|
85
142
|
* @param currentPage - The current page number
|