@workflow/web-shared 5.0.0-beta.10 → 5.0.0-beta.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/components/index.d.ts +1 -0
  2. package/dist/components/index.d.ts.map +1 -1
  3. package/dist/components/index.js +2 -1
  4. package/dist/components/new-trace-viewer/components/event-list.d.ts.map +1 -1
  5. package/dist/components/new-trace-viewer/components/event-list.js +9 -4
  6. package/dist/components/new-trace-viewer/components/split-pane.d.ts +3 -2
  7. package/dist/components/new-trace-viewer/components/split-pane.d.ts.map +1 -1
  8. package/dist/components/new-trace-viewer/components/split-pane.js +10 -4
  9. package/dist/components/new-trace-viewer/components/timeline.d.ts +1 -1
  10. package/dist/components/new-trace-viewer/components/timeline.d.ts.map +1 -1
  11. package/dist/components/new-trace-viewer/components/timeline.js +6 -8
  12. package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.d.ts +2 -0
  13. package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.d.ts.map +1 -0
  14. package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.js +19 -0
  15. package/dist/components/new-trace-viewer/components/use-row-window.d.ts +20 -0
  16. package/dist/components/new-trace-viewer/components/use-row-window.d.ts.map +1 -0
  17. package/dist/components/new-trace-viewer/components/use-row-window.js +69 -0
  18. package/dist/components/new-trace-viewer/context.d.ts.map +1 -1
  19. package/dist/components/new-trace-viewer/context.js +2 -2
  20. package/dist/components/new-trace-viewer/trace-viewer.d.ts +4 -1
  21. package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +1 -1
  22. package/dist/components/new-trace-viewer/trace-viewer.js +19 -6
  23. package/dist/components/trace-viewer-new.d.ts +5 -1
  24. package/dist/components/trace-viewer-new.d.ts.map +1 -1
  25. package/dist/components/trace-viewer-new.js +7 -8
  26. package/dist/components/ui/icon-button.d.ts +8 -2
  27. package/dist/components/ui/icon-button.d.ts.map +1 -1
  28. package/dist/components/ui/icon-button.js +4 -4
  29. package/dist/components/ui/kbd.d.ts +6 -0
  30. package/dist/components/ui/kbd.d.ts.map +1 -0
  31. package/dist/components/ui/kbd.js +6 -0
  32. package/dist/components/ui/tooltip.d.ts +10 -0
  33. package/dist/components/ui/tooltip.d.ts.map +1 -0
  34. package/dist/components/ui/tooltip.js +12 -0
  35. package/dist/hooks/use-intersection-observer.d.ts +17 -0
  36. package/dist/hooks/use-intersection-observer.d.ts.map +1 -0
  37. package/dist/hooks/use-intersection-observer.js +29 -0
  38. package/dist/hooks/use-load-more-on-scroll.d.ts +21 -0
  39. package/dist/hooks/use-load-more-on-scroll.d.ts.map +1 -0
  40. package/dist/hooks/use-load-more-on-scroll.js +28 -0
  41. package/dist/lib/hydration.d.ts.map +1 -1
  42. package/dist/lib/hydration.js +26 -2
  43. package/package.json +4 -4
  44. package/src/components/index.ts +1 -0
  45. package/src/components/new-trace-viewer/components/event-list.tsx +19 -11
  46. package/src/components/new-trace-viewer/components/split-pane.tsx +15 -2
  47. package/src/components/new-trace-viewer/components/timeline.tsx +27 -19
  48. package/src/components/new-trace-viewer/components/trace-viewer-skeleton.tsx +94 -0
  49. package/src/components/new-trace-viewer/components/use-row-window.ts +93 -0
  50. package/src/components/new-trace-viewer/context.tsx +1 -3
  51. package/src/components/new-trace-viewer/trace-viewer.tsx +90 -22
  52. package/src/components/trace-viewer-new.tsx +20 -12
  53. package/src/components/ui/icon-button.tsx +7 -11
  54. package/src/components/ui/kbd.tsx +21 -0
  55. package/src/components/ui/tooltip.tsx +47 -0
  56. package/src/hooks/use-intersection-observer.ts +57 -0
  57. package/src/hooks/use-load-more-on-scroll.ts +49 -0
  58. package/src/lib/hydration.ts +28 -1
@@ -0,0 +1,47 @@
1
+ 'use client';
2
+
3
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
4
+ import * as React from 'react';
5
+ import { cn } from '../../lib/utils';
6
+
7
+ const TooltipProvider = TooltipPrimitive.Provider;
8
+
9
+ const Tooltip = TooltipPrimitive.Root;
10
+
11
+ const TooltipTrigger = TooltipPrimitive.Trigger;
12
+
13
+ const TooltipContent = React.forwardRef<
14
+ React.ElementRef<typeof TooltipPrimitive.Content>,
15
+ React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> & {
16
+ showArrow?: boolean;
17
+ }
18
+ >(
19
+ (
20
+ { className, sideOffset = 8, showArrow = true, children, ...props },
21
+ ref
22
+ ) => (
23
+ <TooltipPrimitive.Portal>
24
+ <TooltipPrimitive.Content
25
+ ref={ref}
26
+ sideOffset={sideOffset}
27
+ className={cn(
28
+ 'z-[99999] flex items-center gap-1 rounded-[10px] bg-gray-1000 px-2 py-1.5 !text-label-13 text-background-100 shadow-md select-none',
29
+ className
30
+ )}
31
+ {...props}
32
+ >
33
+ {children}
34
+ {showArrow ? (
35
+ <TooltipPrimitive.Arrow
36
+ width={11}
37
+ height={5}
38
+ className="fill-gray-1000"
39
+ />
40
+ ) : null}
41
+ </TooltipPrimitive.Content>
42
+ </TooltipPrimitive.Portal>
43
+ )
44
+ );
45
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
46
+
47
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
@@ -0,0 +1,57 @@
1
+ 'use client';
2
+
3
+ import type { RefObject } from 'react';
4
+ import { useEffect, useState } from 'react';
5
+
6
+ interface UseIntersectionObserverArgs
7
+ extends Omit<IntersectionObserverInit, 'root'> {
8
+ /**
9
+ * Scroll container the target is observed within. Defaults to the viewport.
10
+ * Passed as a ref so it resolves after commit (when the node exists).
11
+ */
12
+ rootRef?: RefObject<Element | null>;
13
+ freezeOnceVisible?: boolean;
14
+ }
15
+
16
+ /**
17
+ * Returns the latest IntersectionObserverEntry for `elementRef`.
18
+ * Ported from vercel/front's `@vercel/hooks` `useIntersectionObserver`, with
19
+ * `root` threaded as a ref so we can observe inside a custom scroll container.
20
+ */
21
+ export function useIntersectionObserver(
22
+ elementRef: RefObject<Element | null>,
23
+ {
24
+ threshold = 0,
25
+ rootRef,
26
+ rootMargin = '0%',
27
+ freezeOnceVisible = false,
28
+ }: UseIntersectionObserverArgs = {}
29
+ ): IntersectionObserverEntry | undefined {
30
+ const [entry, setEntry] = useState<IntersectionObserverEntry>();
31
+
32
+ const frozen = entry?.isIntersecting && freezeOnceVisible;
33
+
34
+ useEffect(() => {
35
+ const node = elementRef?.current;
36
+
37
+ const hasIOSupport = !!window.IntersectionObserver;
38
+
39
+ if (!hasIOSupport || frozen || !node) return;
40
+
41
+ const updateEntry = ([entry]: IntersectionObserverEntry[]): void => {
42
+ setEntry(entry);
43
+ };
44
+
45
+ const observer = new IntersectionObserver(updateEntry, {
46
+ threshold,
47
+ root: rootRef?.current ?? null,
48
+ rootMargin,
49
+ });
50
+
51
+ observer.observe(node);
52
+
53
+ return () => observer.disconnect();
54
+ }, [elementRef, threshold, rootRef, rootMargin, frozen]);
55
+
56
+ return entry;
57
+ }
@@ -0,0 +1,49 @@
1
+ 'use client';
2
+
3
+ import type { RefObject } from 'react';
4
+ import { useEffect, useRef } from 'react';
5
+ import { useIntersectionObserver } from './use-intersection-observer';
6
+
7
+ interface UseLoadMoreOnScrollOptions {
8
+ hasMore: boolean;
9
+ isLoadingMore: boolean;
10
+ /** Scroll container the sentinel lives in. Defaults to the viewport. */
11
+ rootRef?: RefObject<Element | null>;
12
+ rootMargin?: string;
13
+ }
14
+
15
+ /**
16
+ * Triggers `loadMore` when a sentinel element scrolls into view.
17
+ * Returns a ref to attach to an invisible sentinel `<div>` placed after the
18
+ * list content. Ported from vercel/front's `@vercel/hooks`
19
+ * `useLoadMoreOnScroll`.
20
+ *
21
+ * Because it keys off `isIntersecting`/`isLoadingMore`, it self-continues:
22
+ * if the sentinel is still in view once a page finishes loading, the next
23
+ * page is requested automatically.
24
+ */
25
+ export function useLoadMoreOnScroll(
26
+ loadMore: () => void,
27
+ {
28
+ hasMore,
29
+ isLoadingMore,
30
+ rootRef,
31
+ rootMargin = '400px',
32
+ }: UseLoadMoreOnScrollOptions
33
+ ) {
34
+ const sentinelRef = useRef<HTMLDivElement>(null);
35
+ const entry = useIntersectionObserver(sentinelRef, { rootRef, rootMargin });
36
+
37
+ const loadMoreRef = useRef(loadMore);
38
+ useEffect(() => {
39
+ loadMoreRef.current = loadMore;
40
+ }, [loadMore]);
41
+
42
+ useEffect(() => {
43
+ if (entry?.isIntersecting && hasMore && !isLoadingMore) {
44
+ loadMoreRef.current();
45
+ }
46
+ }, [entry?.isIntersecting, hasMore, isLoadingMore]);
47
+
48
+ return sentinelRef;
49
+ }
@@ -135,7 +135,8 @@ export function getWebRevivers(): Revivers {
135
135
  // Error family. The reducer side (see
136
136
  // `packages/core/src/serialization/reducers/common.ts`) emits a tagged
137
137
  // entry for each built-in Error subclass plus the workflow-specific
138
- // `FatalError` / `RetryableError` and `AggregateError`. Without
138
+ // `FatalError` / `RetryableError` / `HookConflictError` /
139
+ // `RuntimeDecryptionError` and `AggregateError`. Without
139
140
  // matching revivers here, `devalue.unflatten` throws "Unknown type X"
140
141
  // — which surfaces in the web o11y UI as "Failed to load resource
141
142
  // details: Unknown type FatalError".
@@ -183,6 +184,20 @@ export function getWebRevivers(): Revivers {
183
184
  if (value.stack !== undefined) error.stack = value.stack;
184
185
  return error;
185
186
  },
187
+ HookConflictError: (value) => {
188
+ const opts = 'cause' in value ? { cause: value.cause } : undefined;
189
+ const error = new Error(value.message, opts) as Error & {
190
+ token?: string;
191
+ conflictingRunId?: string;
192
+ };
193
+ error.name = 'HookConflictError';
194
+ error.token = value.token;
195
+ if (value.conflictingRunId !== undefined) {
196
+ error.conflictingRunId = value.conflictingRunId;
197
+ }
198
+ if (value.stack !== undefined) error.stack = value.stack;
199
+ return error;
200
+ },
186
201
  RetryableError: (value) => {
187
202
  const opts = 'cause' in value ? { cause: value.cause } : undefined;
188
203
  const error = new Error(value.message, opts) as Error & {
@@ -201,6 +216,18 @@ export function getWebRevivers(): Revivers {
201
216
  }
202
217
  return error;
203
218
  },
219
+ RuntimeDecryptionError: (value) => {
220
+ const opts = 'cause' in value ? { cause: value.cause } : undefined;
221
+ const error = new Error(value.message, opts) as Error & {
222
+ context?: unknown;
223
+ };
224
+ error.name = 'RuntimeDecryptionError';
225
+ if (value.context !== undefined) {
226
+ error.context = value.context;
227
+ }
228
+ if (value.stack !== undefined) error.stack = value.stack;
229
+ return error;
230
+ },
204
231
  DOMException: (value) => {
205
232
  // Modern browsers and Node 18+ expose `DOMException` on globalThis.
206
233
  // `AbortController.abort()` with no argument synthesizes one as the