@kylincloud/flamegraph 0.35.29 → 0.36.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../src/shims/Table.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../src/shims/Table.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"createFlamegraphRenderWorker.d.ts","sourceRoot":"","sources":["../../src/workers/createFlamegraphRenderWorker.ts"],"names":[],"mappings":"AAAA,wBAAgB,4BAA4B,IAAI,MAAM,CAMrD"}
1
+ {"version":3,"file":"createFlamegraphRenderWorker.d.ts","sourceRoot":"","sources":["../../src/workers/createFlamegraphRenderWorker.ts"],"names":[],"mappings":"AAAA,wBAAgB,4BAA4B,IAAI,MAAM,CAsBrD"}
@@ -1 +1 @@
1
- {"version":3,"file":"profilerTableWorker.d.ts","sourceRoot":"","sources":["../../src/workers/profilerTableWorker.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,sBAAsB,GAC9B;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEN,MAAM,MAAM,0BAA0B,GAClC;IACE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE;QACP,WAAW,EAAE;YACX,KAAK,EAAE,MAAM,EAAE,CAAC;YAChB,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;YACnB,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAC;YAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB,UAAU,CAAC,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE,KAAK,GAAG,MAAM,CAAC;QAChC,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE,KAAK,GAAG,MAAM,CAAC;QAChC,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAEN,MAAM,MAAM,2BAA2B,GACnC;IACE,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE;QACP,IAAI,EAAE,sBAAsB,EAAE,CAAC;QAC/B,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE;QACP,IAAI,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;QACtC,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAEN,wBAAgB,yBAAyB,IAAI,MAAM,CA+RlD"}
1
+ {"version":3,"file":"profilerTableWorker.d.ts","sourceRoot":"","sources":["../../src/workers/profilerTableWorker.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,sBAAsB,GAC9B;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEN,MAAM,MAAM,0BAA0B,GAClC;IACE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE;QACP,WAAW,EAAE;YACX,KAAK,EAAE,MAAM,EAAE,CAAC;YAChB,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;YACnB,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAC;YAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB,UAAU,CAAC,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE,KAAK,GAAG,MAAM,CAAC;QAChC,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE,KAAK,GAAG,MAAM,CAAC;QAChC,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAEN,MAAM,MAAM,2BAA2B,GACnC;IACE,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE;QACP,IAAI,EAAE,sBAAsB,EAAE,CAAC;QAC/B,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE;QACP,IAAI,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;QACtC,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAEN,wBAAgB,yBAAyB,IAAI,MAAM,CAqQlD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kylincloud/flamegraph",
3
- "version": "0.35.29",
3
+ "version": "0.36.1",
4
4
  "description": "KylinCloud flamegraph renderer (Pyroscope-based)",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.node.cjs.js",
@@ -1,10 +1,46 @@
1
1
  // a dummy class is required
2
2
  // so that the component can import this class
3
3
  // and therefore the library style (index.css above) is imported
4
- .dummy {
4
+ .menu {
5
5
  display: block;
6
6
 
7
7
  svg {
8
8
  margin-right: 10px;
9
9
  }
10
+
11
+ :global(.szh-menu) {
12
+ background-color: var(--ps-dropdown-background, #fff);
13
+ border: 1px solid var(--ps-ui-border, #d9d9d9);
14
+ border-radius: 6px;
15
+ box-shadow:
16
+ 0 6px 16px 0 rgba(0, 0, 0, 0.08),
17
+ 0 3px 6px -4px rgba(0, 0, 0, 0.12),
18
+ 0 9px 28px 8px rgba(0, 0, 0, 0.05);
19
+ padding: 4px 0;
20
+ min-width: 180px;
21
+ font-size: 13px;
22
+ color: var(--ps-ui-foreground-text, #000);
23
+ }
24
+
25
+ :global(.szh-menu__item) {
26
+ display: flex;
27
+ align-items: center;
28
+ gap: 8px;
29
+ padding: 6px 12px;
30
+ height: 32px;
31
+ cursor: pointer;
32
+ color: inherit;
33
+ transition: background-color 0.15s;
34
+
35
+ &:hover {
36
+ background-color: var(--ps-ui-element-bg-highlight, #f5f5f5);
37
+ }
38
+
39
+ svg {
40
+ width: 14px;
41
+ height: 14px;
42
+ flex-shrink: 0;
43
+ margin-right: 0;
44
+ }
45
+ }
10
46
  }
@@ -76,7 +76,7 @@ export default function ContextMenu(props: ContextMenuProps) {
76
76
  return (
77
77
  <ControlledMenu
78
78
  {...menuProps}
79
- className={styles.dummy}
79
+ className={styles.menu}
80
80
  anchorPoint={anchorPoint}
81
81
  onClose={onClose}
82
82
  >
@@ -80,7 +80,6 @@ export default function FlameGraphComponent(props: FlamegraphProps) {
80
80
  const textCanvasRef = React.useRef<HTMLCanvasElement>(null);
81
81
  const flamegraph = useRef<Flamegraph>();
82
82
  const flamegraphText = useRef<Flamegraph>();
83
- const renderSeq = useRef(0);
84
83
  const renderWorkerRef = useRef<Worker | null>(null);
85
84
  const rectOffscreenRef = useRef<OffscreenCanvas | null>(null);
86
85
  const textOffscreenRef = useRef<OffscreenCanvas | null>(null);
@@ -159,8 +158,6 @@ export default function FlameGraphComponent(props: FlamegraphProps) {
159
158
  }
160
159
  const worker = createFlamegraphRenderWorker();
161
160
  renderWorkerRef.current = worker;
162
- // eslint-disable-next-line no-console
163
- console.debug('[flamegraph] render worker created');
164
161
  setTimeout(() => {
165
162
  renderRectCanvas();
166
163
  renderTextCanvas();
@@ -171,8 +168,6 @@ export default function FlameGraphComponent(props: FlamegraphProps) {
171
168
  rectOffscreenRef.current = null;
172
169
  textOffscreenRef.current = null;
173
170
  workerReadyRef.current = { rect: false, text: false };
174
- // eslint-disable-next-line no-console
175
- console.debug('[flamegraph] render worker terminated');
176
171
  };
177
172
  }, [useRenderWorker]);
178
173
 
@@ -375,10 +370,6 @@ export default function FlameGraphComponent(props: FlamegraphProps) {
375
370
  );
376
371
 
377
372
  const constructCanvas = () => {
378
- const seq = renderSeq.current + 1;
379
- renderSeq.current = seq;
380
- // eslint-disable-next-line no-console
381
- console.time(`[flamegraph] constructCanvas #${seq}`);
382
373
  if (canvasRef.current) {
383
374
  const f = new Flamegraph(
384
375
  flamebearer,
@@ -406,8 +397,6 @@ export default function FlameGraphComponent(props: FlamegraphProps) {
406
397
  );
407
398
  flamegraphText.current = f;
408
399
  }
409
- // eslint-disable-next-line no-console
410
- console.timeEnd(`[flamegraph] constructCanvas #${seq}`);
411
400
  };
412
401
 
413
402
  const ensureRenderWorkerCanvases = useCallback(() => {
@@ -426,8 +415,6 @@ export default function FlameGraphComponent(props: FlamegraphProps) {
426
415
  );
427
416
  workerReadyRef.current.rect = true;
428
417
  } catch (err) {
429
- // eslint-disable-next-line no-console
430
- console.debug('[flamegraph] rect transfer failed', err);
431
418
  }
432
419
  }
433
420
 
@@ -441,8 +428,6 @@ export default function FlameGraphComponent(props: FlamegraphProps) {
441
428
  );
442
429
  workerReadyRef.current.text = true;
443
430
  } catch (err) {
444
- // eslint-disable-next-line no-console
445
- console.debug('[flamegraph] text transfer failed', err);
446
431
  }
447
432
  }
448
433
 
@@ -482,8 +467,6 @@ export default function FlameGraphComponent(props: FlamegraphProps) {
482
467
  return false;
483
468
  }
484
469
  if (!renderWorkerRef.current) {
485
- // eslint-disable-next-line no-console
486
- console.debug('[flamegraph] worker not ready yet');
487
470
  return true;
488
471
  }
489
472
  if (!ensureRenderWorkerCanvases()) {
@@ -512,35 +495,21 @@ export default function FlameGraphComponent(props: FlamegraphProps) {
512
495
  };
513
496
 
514
497
  const renderRectCanvas = () => {
515
- const seq = renderSeq.current;
516
498
  if (postWorkerRender('rect', { renderText: false })) {
517
- // eslint-disable-next-line no-console
518
- console.debug(`[flamegraph] renderRects via worker #${seq}`);
519
499
  return;
520
500
  }
521
- // eslint-disable-next-line no-console
522
- console.time(`[flamegraph] renderRects #${seq}`);
523
501
  canvasRef?.current?.setAttribute('data-state', 'rendering');
524
502
  flamegraph?.current?.render({ renderText: false });
525
503
  canvasRef?.current?.setAttribute('data-state', 'rendered');
526
- // eslint-disable-next-line no-console
527
- console.timeEnd(`[flamegraph] renderRects #${seq}`);
528
504
  };
529
505
 
530
506
  const renderTextCanvas = () => {
531
- const seq = renderSeq.current;
532
507
  if (postWorkerRender('text', { renderRects: false })) {
533
- // eslint-disable-next-line no-console
534
- console.debug(`[flamegraph] renderText via worker #${seq}`);
535
508
  return;
536
509
  }
537
- // eslint-disable-next-line no-console
538
- console.time(`[flamegraph] renderText #${seq}`);
539
510
  textCanvasRef?.current?.setAttribute('data-state', 'rendering');
540
511
  flamegraphText?.current?.render({ renderRects: false });
541
512
  textCanvasRef?.current?.setAttribute('data-state', 'rendered');
542
- // eslint-disable-next-line no-console
543
- console.timeEnd(`[flamegraph] renderText #${seq}`);
544
513
  };
545
514
 
546
515
  const dataUnavailable =
@@ -5,7 +5,7 @@
5
5
  .fitModeItem svg,
6
6
  .sandwichItem svg {
7
7
  width: 1em;
8
- margin-right: 10px;
8
+ margin-right: 0;
9
9
  }
10
10
  }
11
11
 
@@ -3,27 +3,32 @@
3
3
  .tableContextMenu {
4
4
  // 继承 react-menu 的基础样式
5
5
  :global(.szh-menu) {
6
- background-color: var(--ps-ui-background, #fff);
7
- border: 1px solid var(--ps-ui-border, #ccc);
8
- border-radius: 4px;
9
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
6
+ background-color: var(--ps-dropdown-background, #fff);
7
+ border: 1px solid var(--ps-ui-border, #d9d9d9);
8
+ border-radius: 6px;
9
+ box-shadow:
10
+ 0 6px 16px 0 rgba(0, 0, 0, 0.08),
11
+ 0 3px 6px -4px rgba(0, 0, 0, 0.12),
12
+ 0 9px 28px 8px rgba(0, 0, 0, 0.05);
10
13
  padding: 4px 0;
11
14
  min-width: 180px;
12
- z-index: 1000;
15
+ font-size: 13px;
16
+ z-index: 3000;
13
17
  }
14
18
 
15
19
  :global(.szh-menu__item) {
16
20
  display: flex;
17
21
  align-items: center;
18
22
  gap: 8px;
19
- padding: 8px 12px;
23
+ padding: 6px 12px;
24
+ height: 32px;
20
25
  cursor: pointer;
21
- color: var(--ps-ui-foreground-text, #333);
22
- font-size: 13px;
26
+ color: var(--ps-ui-foreground-text, #000);
27
+ font-size: inherit;
23
28
  transition: background-color 0.15s;
24
29
 
25
30
  &:hover {
26
- background-color: var(--ps-ui-element-bg-highlight, #f0f0f0);
31
+ background-color: var(--ps-ui-element-bg-highlight, #f5f5f5);
27
32
  }
28
33
 
29
34
  svg {
@@ -501,12 +501,14 @@ function Table({
501
501
  virtualizeRowHeight,
502
502
  virtualizeOverscan,
503
503
  scrollRef,
504
+ menuPortalTarget,
504
505
  }: ProfilerTableProps & {
505
506
  isDoubles: boolean;
506
507
  virtualize?: boolean;
507
508
  virtualizeRowHeight?: number;
508
509
  virtualizeOverscan?: number;
509
510
  scrollRef?: RefObject<HTMLElement>;
511
+ menuPortalTarget?: HTMLElement | null;
510
512
  }) {
511
513
  const i18n = useFlamegraphI18n();
512
514
  const [menuProps, toggleMenu] = useMenuState({ transition: true });
@@ -540,8 +542,6 @@ function Table({
540
542
  const worker = createProfilerTableWorker();
541
543
  workerRef.current = worker;
542
544
  setWorkerInstance((prev) => prev + 1);
543
- // eslint-disable-next-line no-console
544
- console.debug('[profiler-table] worker created');
545
545
 
546
546
  const handleMessage = (event: MessageEvent<ProfilerTableWorkerResponse>) => {
547
547
  const msg = event.data;
@@ -553,10 +553,6 @@ function Table({
553
553
  setRowCount(msg.payload.rowCount);
554
554
  setWorkerReady(true);
555
555
  setDataVersion((prev) => prev + 1);
556
- // eslint-disable-next-line no-console
557
- console.debug('[profiler-table] worker ready', {
558
- rowCount: msg.payload.rowCount,
559
- });
560
556
  break;
561
557
  }
562
558
  case 'range': {
@@ -565,12 +561,6 @@ function Table({
565
561
  }
566
562
  setVisibleRowData(msg.payload.rows);
567
563
  setVirtualRange({ start: msg.payload.start, end: msg.payload.end });
568
- // eslint-disable-next-line no-console
569
- console.debug('[profiler-table] range received', {
570
- start: msg.payload.start,
571
- end: msg.payload.end,
572
- rows: msg.payload.rows.length,
573
- });
574
564
  break;
575
565
  }
576
566
  case 'findNode': {
@@ -579,10 +569,6 @@ function Table({
579
569
  pendingFocusRef.current.delete(msg.payload.requestId);
580
570
  resolver(msg.payload.node);
581
571
  }
582
- // eslint-disable-next-line no-console
583
- console.debug('[profiler-table] findNode response', {
584
- found: !!msg.payload.node,
585
- });
586
572
  break;
587
573
  }
588
574
  default:
@@ -596,8 +582,6 @@ function Table({
596
582
  worker.terminate();
597
583
  workerRef.current = null;
598
584
  pendingFocusRef.current.clear();
599
- // eslint-disable-next-line no-console
600
- console.debug('[profiler-table] worker terminated');
601
585
  };
602
586
  }, [useWorker]);
603
587
 
@@ -607,8 +591,6 @@ function Table({
607
591
  return Promise.resolve(findNodeByName(flamebearer, name));
608
592
  }
609
593
  const requestId = ++focusRequestIdRef.current;
610
- // eslint-disable-next-line no-console
611
- console.debug('[profiler-table] findNode request', { name, requestId });
612
594
  return new Promise<{ i: number; j: number } | null>((resolve) => {
613
595
  pendingFocusRef.current.set(requestId, resolve);
614
596
  workerRef.current?.postMessage({
@@ -637,19 +619,11 @@ function Table({
637
619
  (name: string) => {
638
620
  // 先确保该项被高亮(如果未高亮则高亮,如果已高亮则保持)
639
621
  if (!selectedItem.isJust || selectedItem.value !== name) {
640
- // eslint-disable-next-line no-console
641
- console.time(`[profiler-table] dblclick highlight ${name}`);
642
622
  handleTableItemClick({ name });
643
- // eslint-disable-next-line no-console
644
- console.timeEnd(`[profiler-table] dblclick highlight ${name}`);
645
623
  }
646
624
 
647
625
  // 然后聚焦到火焰图
648
- // eslint-disable-next-line no-console
649
- console.time(`[profiler-table] dblclick focus ${name}`);
650
626
  focusByName(name);
651
- // eslint-disable-next-line no-console
652
- console.timeEnd(`[profiler-table] dblclick focus ${name}`);
653
627
  },
654
628
  [focusByName, selectedItem, handleTableItemClick]
655
629
  );
@@ -673,11 +647,7 @@ function Table({
673
647
  // 菜单项:聚焦到此函数
674
648
  const handleFocusClick = useCallback(() => {
675
649
  if (!contextMenuTarget) return;
676
- // eslint-disable-next-line no-console
677
- console.time(`[profiler-table] menu focus ${contextMenuTarget}`);
678
650
  focusByName(contextMenuTarget);
679
- // eslint-disable-next-line no-console
680
- console.timeEnd(`[profiler-table] menu focus ${contextMenuTarget}`);
681
651
  handleMenuClose();
682
652
  }, [contextMenuTarget, focusByName, handleMenuClose]);
683
653
 
@@ -793,8 +763,6 @@ function Table({
793
763
  ]);
794
764
 
795
765
  const handleRangeChange = useCallback((start: number, end: number) => {
796
- // eslint-disable-next-line no-console
797
- console.debug('[profiler-table] range requested', { start, end });
798
766
  setRequestedRange((prev) => {
799
767
  if (prev && prev.start === start && prev.end === end) {
800
768
  return prev;
@@ -847,11 +815,7 @@ function Table({
847
815
  'data-row': `single;${x.name};${x.self};${x.total}`,
848
816
  isRowSelected: isRowSelected(x.name),
849
817
  onClick: () => {
850
- // eslint-disable-next-line no-console
851
- console.time(`[profiler-table] click ${x.name}`);
852
818
  handleTableItemClick({ name: x.name });
853
- // eslint-disable-next-line no-console
854
- console.timeEnd(`[profiler-table] click ${x.name}`);
855
819
  },
856
820
  onContextMenu: (e: React.MouseEvent) => handleContextMenu(e, x.name),
857
821
  onDoubleClick: () => handleDoubleClick(x.name),
@@ -921,11 +885,7 @@ function Table({
921
885
  'data-row': `double;${x.name};${x.totalLeft};${x.leftTicks};${x.totalRght};${x.rightTicks}`,
922
886
  isRowSelected: isRowSelected(x.name),
923
887
  onClick: () => {
924
- // eslint-disable-next-line no-console
925
- console.time(`[profiler-table] click ${x.name}`);
926
888
  handleTableItemClick({ name: x.name });
927
- // eslint-disable-next-line no-console
928
- console.timeEnd(`[profiler-table] click ${x.name}`);
929
889
  },
930
890
  onContextMenu: (e: React.MouseEvent) => handleContextMenu(e, x.name),
931
891
  onDoubleClick: () => handleDoubleClick(x.name),
@@ -1055,6 +1015,7 @@ function Table({
1055
1015
  anchorPoint={anchorPoint}
1056
1016
  onClose={handleMenuClose}
1057
1017
  className={styles.tableContextMenu}
1018
+ portal={menuPortalTarget ? { target: menuPortalTarget } : true}
1058
1019
  >
1059
1020
  {onFocusOnNode && (
1060
1021
  <MenuItem onClick={handleFocusClick}>
@@ -1096,6 +1057,9 @@ const ProfilerTable = React.memo(function ProfilerTable({
1096
1057
  const wrapperRef = useRef<HTMLDivElement>(null);
1097
1058
  const scrollRef = useRef<HTMLDivElement>(null);
1098
1059
  const [scrollbarSize, setScrollbarSize] = useState(0);
1060
+ const [menuPortalTarget, setMenuPortalTarget] = useState<HTMLElement | null>(
1061
+ null
1062
+ );
1099
1063
  const isDoubles = flamebearer.format === 'double';
1100
1064
  const shouldVirtualize = true;
1101
1065
 
@@ -1108,6 +1072,26 @@ const ProfilerTable = React.memo(function ProfilerTable({
1108
1072
  }
1109
1073
  }, [tableBodyRef.current, isDoubles, scrollbarSize]);
1110
1074
 
1075
+ useEffect(() => {
1076
+ const host = wrapperRef.current;
1077
+ if (!host || typeof document === 'undefined') return;
1078
+
1079
+ const themeHost = host.closest(
1080
+ "[data-theme], [data-flamegraph-color-mode]"
1081
+ ) as HTMLElement | null;
1082
+ const targetParent = themeHost || host;
1083
+ const portalTarget = document.createElement('div');
1084
+ portalTarget.className = 'flamegraph-menu-portal';
1085
+ targetParent.appendChild(portalTarget);
1086
+ setMenuPortalTarget(portalTarget);
1087
+
1088
+ return () => {
1089
+ if (portalTarget.parentElement) {
1090
+ portalTarget.parentElement.removeChild(portalTarget);
1091
+ }
1092
+ };
1093
+ }, []);
1094
+
1111
1095
  return (
1112
1096
  <div
1113
1097
  data-testid="table-view"
@@ -1138,9 +1122,9 @@ const ProfilerTable = React.memo(function ProfilerTable({
1138
1122
  updateView={updateView}
1139
1123
  enableSandwichView={enableSandwichView}
1140
1124
  virtualize={shouldVirtualize}
1141
- virtualizeRowHeight={26}
1142
1125
  virtualizeOverscan={8}
1143
1126
  scrollRef={scrollRef}
1127
+ menuPortalTarget={menuPortalTarget}
1144
1128
  />
1145
1129
  </div>
1146
1130
 
@@ -177,6 +177,7 @@ function Table({
177
177
  const [measuredRowHeight, setMeasuredRowHeight] = useState<number | null>(null);
178
178
  const [scrollEl, setScrollEl] = useState<HTMLElement | null>(null);
179
179
  const rafRef = useRef<number | null>(null);
180
+ const lastVirtualRowsRef = useRef<BodyRow[] | null>(null);
180
181
 
181
182
  useLayoutEffect(() => {
182
183
  if (scrollRef?.current && scrollRef.current !== scrollEl) {
@@ -231,7 +232,8 @@ function Table({
231
232
  ? bodyRows.length
232
233
  : 0;
233
234
 
234
- const rowHeight = virtualizeRowHeight || measuredRowHeight || 0;
235
+ // Fallback row height prevents empty render when no measurement yet.
236
+ const rowHeight = virtualizeRowHeight || measuredRowHeight || 26;
235
237
  const canVirtualize =
236
238
  !!virtualize &&
237
239
  !!scrollEl &&
@@ -296,13 +298,22 @@ function Table({
296
298
  }))
297
299
  : [];
298
300
 
299
- const renderVirtualRows =
301
+ const shouldUseFreshRows =
300
302
  table.type === 'virtual' &&
301
303
  virtualState &&
302
304
  table.range &&
303
305
  table.range.start === virtualState.startIndex &&
304
- table.range.end === virtualState.endIndex
305
- ? table.rows
306
+ table.range.end === virtualState.endIndex;
307
+
308
+ if (table.type === 'virtual' && shouldUseFreshRows) {
309
+ lastVirtualRowsRef.current = table.rows;
310
+ }
311
+
312
+ const renderVirtualRows =
313
+ table.type === 'virtual'
314
+ ? (shouldUseFreshRows
315
+ ? table.rows
316
+ : lastVirtualRowsRef.current || placeholderRows)
306
317
  : placeholderRows;
307
318
 
308
319
  return isLoading ? (
@@ -1,7 +1,23 @@
1
1
  export function createFlamegraphRenderWorker(): Worker {
2
- const fromSrc = import.meta.url.includes('/src/');
3
- const workerUrl = fromSrc
4
- ? new URL('./flamegraphRenderWorker.ts', import.meta.url)
5
- : new URL('./flamegraphRenderWorker.js', import.meta.url);
2
+ const metaUrl = new URL(import.meta.url);
3
+ const pathname = metaUrl.pathname;
4
+ const isFromSrc = pathname.includes('/src/');
5
+ const isFromDist = pathname.includes('/dist/');
6
+ const isFromViteDeps = pathname.includes('/node_modules/.vite/deps/');
7
+
8
+ if (isFromViteDeps) {
9
+ // Vite prebundle path -> hop back to node_modules/@kylincloud/flamegraph/dist
10
+ const viteDepsWorkerUrl = new URL(
11
+ '../../@kylincloud/flamegraph/dist/flamegraphRenderWorker.js',
12
+ metaUrl
13
+ );
14
+ return new Worker(viteDepsWorkerUrl, { type: 'module' });
15
+ }
16
+
17
+ const workerUrl = isFromSrc
18
+ ? new URL('./flamegraphRenderWorker.ts', metaUrl)
19
+ : isFromDist
20
+ ? new URL('./flamegraphRenderWorker.js', metaUrl)
21
+ : new URL('./flamegraphRenderWorker.js', metaUrl);
6
22
  return new Worker(workerUrl, { type: 'module' });
7
23
  }
@@ -107,8 +107,6 @@ const runChunk = (kind: 'rect' | 'text', token: number) => {
107
107
  }
108
108
  const canvas = kind === 'rect' ? state.rectCanvas : state.textCanvas;
109
109
  if (!canvas) {
110
- // eslint-disable-next-line no-console
111
- console.debug('[flamegraph-worker] missing canvas for', kind);
112
110
  renderState.running = false;
113
111
  return;
114
112
  }
@@ -155,8 +153,6 @@ const renderFlamegraph = (payload: FlamegraphRenderRequest['payload']) => {
155
153
  const canvas =
156
154
  payload.kind === 'rect' ? state.rectCanvas : state.textCanvas;
157
155
  if (!canvas) {
158
- // eslint-disable-next-line no-console
159
- console.debug('[flamegraph-worker] missing canvas for', payload.kind);
160
156
  return;
161
157
  }
162
158
 
@@ -188,8 +184,6 @@ self.onmessage = (event: MessageEvent<FlamegraphWorkerMessage>) => {
188
184
  } else {
189
185
  state.textCanvas = msg.payload.canvas;
190
186
  }
191
- // eslint-disable-next-line no-console
192
- console.debug('[flamegraph-worker] init', msg.payload.kind);
193
187
  return;
194
188
  }
195
189
  if (msg.type === 'render') {
@@ -275,13 +275,6 @@ export function createProfilerTableWorker(): Worker {
275
275
  state.sortByDirection = payload.sortByDirection;
276
276
  state.highlightQuery = payload.highlightQuery || '';
277
277
  applyFilterAndSort();
278
- // eslint-disable-next-line no-console
279
- console.debug('[profiler-table-worker] init ready', {
280
- rowCount: state.rows.length,
281
- sortBy: state.sortBy,
282
- sortByDirection: state.sortByDirection,
283
- highlightQuery: state.highlightQuery,
284
- });
285
278
  self.postMessage({
286
279
  type: 'ready',
287
280
  payload: { rowCount: state.rows.length },
@@ -293,13 +286,6 @@ export function createProfilerTableWorker(): Worker {
293
286
  state.sortByDirection = payload.sortByDirection;
294
287
  state.highlightQuery = payload.highlightQuery || '';
295
288
  applyFilterAndSort();
296
- // eslint-disable-next-line no-console
297
- console.debug('[profiler-table-worker] update ready', {
298
- rowCount: state.rows.length,
299
- sortBy: state.sortBy,
300
- sortByDirection: state.sortByDirection,
301
- highlightQuery: state.highlightQuery,
302
- });
303
289
  self.postMessage({
304
290
  type: 'ready',
305
291
  payload: { rowCount: state.rows.length },
@@ -311,12 +297,6 @@ export function createProfilerTableWorker(): Worker {
311
297
  const safeStart = Math.max(0, start);
312
298
  const safeEnd = Math.min(state.rows.length, end);
313
299
  const rows = state.rows.slice(safeStart, safeEnd);
314
- // eslint-disable-next-line no-console
315
- console.debug('[profiler-table-worker] range', {
316
- start: safeStart,
317
- end: safeEnd,
318
- requestId,
319
- });
320
300
  self.postMessage({
321
301
  type: 'range',
322
302
  payload: { rows, start: safeStart, end: safeEnd, requestId },
@@ -326,12 +306,6 @@ export function createProfilerTableWorker(): Worker {
326
306
  const handleFindNode = (payload) => {
327
307
  const { name, requestId } = payload;
328
308
  const best = state.bestNodeByName.get(name);
329
- // eslint-disable-next-line no-console
330
- console.debug('[profiler-table-worker] findNode', {
331
- name,
332
- found: !!best,
333
- requestId,
334
- });
335
309
  self.postMessage({
336
310
  type: 'findNode',
337
311
  payload: { node: best ? { i: best.i, j: best.j } : null, requestId },