@gemx-dev/heatmap-react 3.5.92-dev.11 → 3.5.92-dev.14

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.
@@ -11,6 +11,7 @@ interface HeatmapLayoutProps {
11
11
  controls: IHeatmapControl;
12
12
  isLoading?: boolean;
13
13
  isLoadingCanvas?: boolean;
14
+ excludeClassNames?: string[];
14
15
  }
15
16
  export declare const HeatmapLayout: React.FC<HeatmapLayoutProps>;
16
17
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"HeatmapLayout.d.ts","sourceRoot":"","sources":["../../../src/components/Layout/HeatmapLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACnH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAS3D,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,cAAc,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAClC,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AACD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA2DtD,CAAC"}
1
+ {"version":3,"file":"HeatmapLayout.d.ts","sourceRoot":"","sources":["../../../src/components/Layout/HeatmapLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACnH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAS3D,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,cAAc,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAClC,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AACD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA4DtD,CAAC"}
@@ -1,6 +1,7 @@
1
- export declare const useRegisterConfig: ({ shopId, isLoading, isLoadingCanvas, }: {
1
+ export declare const useRegisterConfig: ({ shopId, isLoading, isLoadingCanvas, excludeClassNames, }: {
2
2
  shopId?: string;
3
3
  isLoading?: boolean;
4
4
  isLoadingCanvas?: boolean;
5
+ excludeClassNames?: string[];
5
6
  }) => void;
6
7
  //# sourceMappingURL=useRegisterConfig.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useRegisterConfig.d.ts","sourceRoot":"","sources":["../../../src/hooks/register/useRegisterConfig.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,iBAAiB,GAAI,yCAI/B;IACD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,SA+BA,CAAC"}
1
+ {"version":3,"file":"useRegisterConfig.d.ts","sourceRoot":"","sources":["../../../src/hooks/register/useRegisterConfig.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,iBAAiB,GAAI,4DAK/B;IACD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B,SAoCA,CAAC"}
@@ -1,6 +1,5 @@
1
- interface IUseHeatmapRenderResult {
1
+ export interface IUseHeatmapRenderResult {
2
2
  iframeRef: React.RefObject<HTMLIFrameElement | null>;
3
3
  }
4
4
  export declare const useHeatmapRender: () => IUseHeatmapRenderResult;
5
- export {};
6
5
  //# sourceMappingURL=useHeatmapRender.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useHeatmapRender.d.ts","sourceRoot":"","sources":["../../../src/hooks/viz-render/useHeatmapRender.ts"],"names":[],"mappings":"AAiCA,UAAU,uBAAuB;IAC/B,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;CACtD;AAcD,eAAO,MAAM,gBAAgB,QAAO,uBAiFnC,CAAC"}
1
+ {"version":3,"file":"useHeatmapRender.d.ts","sourceRoot":"","sources":["../../../src/hooks/viz-render/useHeatmapRender.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;CACtD;AAYD,eAAO,MAAM,gBAAgB,QAAO,uBAsGnC,CAAC"}
package/dist/esm/index.js CHANGED
@@ -321,10 +321,12 @@ const useHeatmapConfigStore = create()((set) => {
321
321
  mode: EHeatmapMode.Single,
322
322
  sidebarWidth: DEFAULT_SIDEBAR_WIDTH,
323
323
  shopId: undefined,
324
+ excludeClassNames: [],
324
325
  setMode: (mode) => set({ mode }),
325
326
  resetMode: () => set({ mode: EHeatmapMode.Single }),
326
327
  setSidebarWidth: (sidebarWidth) => set({ sidebarWidth }),
327
328
  setShopId: (shopId) => set({ shopId }),
329
+ setExcludeClassNames: (excludeClassNames) => set({ excludeClassNames }),
328
330
  };
329
331
  });
330
332
 
@@ -1543,7 +1545,7 @@ const useHeatmapWidthByDevice = () => {
1543
1545
  }
1544
1546
  };
1545
1547
 
1546
- const useRegisterConfig = ({ shopId, isLoading, isLoadingCanvas, }) => {
1548
+ const useRegisterConfig = ({ shopId, isLoading, isLoadingCanvas, excludeClassNames, }) => {
1547
1549
  const mode = useHeatmapConfigStore((state) => state.mode);
1548
1550
  const shopIdStore = useHeatmapConfigStore((state) => state.shopId);
1549
1551
  const deviceType = useHeatmapSettingContext((state) => state.deviceType);
@@ -1552,11 +1554,15 @@ const useRegisterConfig = ({ shopId, isLoading, isLoadingCanvas, }) => {
1552
1554
  const setIsLoadingDom = useHeatmapSettingContext((state) => state.setIsLoadingDom);
1553
1555
  const setIsLoadingCanvas = useHeatmapSettingContext((state) => state.setIsLoadingCanvas);
1554
1556
  const setShopId = useHeatmapConfigStore((state) => state.setShopId);
1557
+ const setExcludeClassNames = useHeatmapConfigStore((state) => state.setExcludeClassNames);
1555
1558
  useEffect(() => {
1556
1559
  if (!shopId || !!shopIdStore || shopIdStore === shopId)
1557
1560
  return;
1558
1561
  setShopId(shopId);
1559
1562
  }, [shopId, setShopId, shopIdStore]);
1563
+ useEffect(() => {
1564
+ setExcludeClassNames(excludeClassNames || []);
1565
+ }, [excludeClassNames, setExcludeClassNames]);
1560
1566
  useEffect(() => {
1561
1567
  setIsRendering(true);
1562
1568
  setTimeout(() => {
@@ -4142,7 +4148,7 @@ function flush() {
4142
4148
  window.__gemxPerf = getReport();
4143
4149
  }
4144
4150
  // ── Global singleton export ───────────────────────────────────────────────────
4145
- const perf = {
4151
+ const perf$1 = {
4146
4152
  startSession,
4147
4153
  endSession,
4148
4154
  mark: globalMark,
@@ -4152,6 +4158,39 @@ const perf = {
4152
4158
  enable: enableGlobal,
4153
4159
  disable: disableGlobal,
4154
4160
  };
4161
+ // ── createPerfTimer factory ───────────────────────────────────────────────────
4162
+ function createPerfTimer(config) {
4163
+ let cfg = typeof config === 'string' ? { prefix: config, enabled: true } : { enabled: true, ...config };
4164
+ function log(icon, label, extra) {
4165
+ if (!cfg.enabled)
4166
+ return;
4167
+ const suffix = extra ? ` — ${extra}` : '';
4168
+ console.log(`[${cfg.prefix}] ${icon} ${label}${suffix}`);
4169
+ }
4170
+ return {
4171
+ configure(next) {
4172
+ cfg = { ...cfg, ...next };
4173
+ },
4174
+ mark(label) {
4175
+ const t = globalMark(`[${cfg.prefix}] ${label}`);
4176
+ log('⏱', label);
4177
+ return t;
4178
+ },
4179
+ measure(label, from) {
4180
+ globalMeasure(`[${cfg.prefix}] ${label}`, from);
4181
+ const ms = (performance.now() - from).toFixed(1);
4182
+ log('✅', label, `${ms}ms`);
4183
+ },
4184
+ async wrap(label, fn) {
4185
+ const t = globalMark(`[${cfg.prefix}] ${label}`);
4186
+ log('⏱', label);
4187
+ const result = await fn();
4188
+ const duration = globalMeasure(`[${cfg.prefix}] ${label}`, t);
4189
+ log('✅', label, `${duration.toFixed(1)}ms`);
4190
+ return result;
4191
+ },
4192
+ };
4193
+ }
4155
4194
 
4156
4195
  /**
4157
4196
  * DOM observation setup — ResizeObserver + MutationObserver.
@@ -5345,52 +5384,52 @@ function configure(debug) {
5345
5384
  }
5346
5385
  async function run$1(ctx, activeGlobal, shopFix) {
5347
5386
  // ── Phase 1: beforeProcess ────────────────────────────────────────────────
5348
- const t1 = perf.mark('phase1.beforeProcess');
5387
+ const t1 = perf$1.mark('phase1.beforeProcess');
5349
5388
  for (const fix of activeGlobal) {
5350
5389
  if (fix.beforeProcess) {
5351
5390
  logger.log(`[beforeProcess] ${fix.name}`);
5352
- const t = perf.mark(`phase1.${fix.name}.beforeProcess`);
5391
+ const t = perf$1.mark(`phase1.${fix.name}.beforeProcess`);
5353
5392
  await fix.beforeProcess(ctx);
5354
- perf.measure(`phase1.${fix.name}.beforeProcess`, t);
5393
+ perf$1.measure(`phase1.${fix.name}.beforeProcess`, t);
5355
5394
  }
5356
5395
  }
5357
5396
  if (shopFix?.beforeProcess) {
5358
5397
  logger.log('[beforeProcess] shop');
5359
- const t = perf.mark('phase1.shop.beforeProcess');
5398
+ const t = perf$1.mark('phase1.shop.beforeProcess');
5360
5399
  await shopFix.beforeProcess(ctx);
5361
- perf.measure('phase1.shop.beforeProcess', t);
5400
+ perf$1.measure('phase1.shop.beforeProcess', t);
5362
5401
  }
5363
- perf.measure('phase1.beforeProcess', t1);
5402
+ perf$1.measure('phase1.beforeProcess', t1);
5364
5403
  // ── Phase 2: process ──────────────────────────────────────────────────────
5365
- const t2 = perf.mark('phase2.process');
5404
+ const t2 = perf$1.mark('phase2.process');
5366
5405
  for (const fix of activeGlobal) {
5367
5406
  if (fix.process) {
5368
5407
  logger.log(`[process] ${fix.name}`);
5369
- const t = perf.mark(`phase2.${fix.name}.process`);
5408
+ const t = perf$1.mark(`phase2.${fix.name}.process`);
5370
5409
  await fix.process(ctx);
5371
- perf.measure(`phase2.${fix.name}.process`, t);
5410
+ perf$1.measure(`phase2.${fix.name}.process`, t);
5372
5411
  }
5373
5412
  }
5374
- perf.measure('phase2.process', t2);
5413
+ perf$1.measure('phase2.process', t2);
5375
5414
  // ── Phase 3: afterProcess ─────────────────────────────────────────────────
5376
- const t3 = perf.mark('phase3.afterProcess');
5415
+ const t3 = perf$1.mark('phase3.afterProcess');
5377
5416
  if (shopFix?.afterProcess) {
5378
5417
  logger.log('[afterProcess] shop');
5379
- const t = perf.mark('phase3.shop.afterProcess');
5418
+ const t = perf$1.mark('phase3.shop.afterProcess');
5380
5419
  await shopFix.afterProcess(ctx);
5381
- perf.measure('phase3.shop.afterProcess', t);
5420
+ perf$1.measure('phase3.shop.afterProcess', t);
5382
5421
  }
5383
5422
  for (const fix of activeGlobal) {
5384
5423
  if (fix.afterProcess) {
5385
5424
  logger.log(`[afterProcess] ${fix.name}`);
5386
- const t = perf.mark(`phase3.${fix.name}.afterProcess`);
5425
+ const t = perf$1.mark(`phase3.${fix.name}.afterProcess`);
5387
5426
  await fix.afterProcess(ctx);
5388
- perf.measure(`phase3.${fix.name}.afterProcess`, t);
5427
+ perf$1.measure(`phase3.${fix.name}.afterProcess`, t);
5389
5428
  }
5390
5429
  }
5391
- perf.measure('phase3.afterProcess', t3);
5430
+ perf$1.measure('phase3.afterProcess', t3);
5392
5431
  // ── Phase 4: getDimensions ────────────────────────────────────────────────
5393
- const t4 = perf.mark('phase4.getDimensions');
5432
+ const t4 = perf$1.mark('phase4.getDimensions');
5394
5433
  return new Promise((resolve) => {
5395
5434
  requestAnimationFrame(() => {
5396
5435
  let dimensions = null;
@@ -5415,7 +5454,7 @@ async function run$1(ctx, activeGlobal, shopFix) {
5415
5454
  dimensions = { height: getFinalHeight(ctx.doc, ctx.win), width: getFinalWidth(ctx.doc) };
5416
5455
  }
5417
5456
  logger.log('Final dimensions:', dimensions);
5418
- perf.measure('phase4.getDimensions', t4);
5457
+ perf$1.measure('phase4.getDimensions', t4);
5419
5458
  resolve(dimensions);
5420
5459
  });
5421
5460
  });
@@ -5543,14 +5582,14 @@ async function run(s) {
5543
5582
  const activeGlobal = getActiveFixes(ctx);
5544
5583
  if (activeGlobal.length > 0)
5545
5584
  s.logger.log(`Active global fixes: ${activeGlobal.map((f) => f.name).join(', ')}`);
5546
- const tRun = perf.mark('viewport.run');
5585
+ const tRun = perf$1.mark('viewport.run');
5547
5586
  try {
5548
5587
  const result = await run$1(ctx, activeGlobal, s.shopFix);
5549
- perf.measure('viewport.run', tRun);
5588
+ perf$1.measure('viewport.run', tRun);
5550
5589
  return result;
5551
5590
  }
5552
5591
  catch (err) {
5553
- perf.measure('viewport.run', tRun);
5592
+ perf$1.measure('viewport.run', tRun);
5554
5593
  s.logger.error('Critical error:', err);
5555
5594
  return { height: s.doc.body?.scrollHeight || 1000, width: s.doc.body?.scrollWidth || 1000 };
5556
5595
  }
@@ -5600,22 +5639,22 @@ async function process(s) {
5600
5639
  return;
5601
5640
  }
5602
5641
  const sessionId = `render-${Date.now()}`;
5603
- perf.startSession(sessionId);
5604
- const t0 = perf.mark('orchestrator.process');
5642
+ perf$1.startSession(sessionId);
5643
+ const t0 = perf$1.mark('orchestrator.process');
5605
5644
  try {
5606
5645
  s.logger.log('Processing viewport units...');
5607
5646
  s.viewportReplacer.start(s.iframe, s.config);
5608
5647
  s.navigationBlocker.start(s.iframe, { debug: s.config.debug });
5609
5648
  const result = await s.viewportReplacer.run();
5610
- perf.measure('orchestrator.process', t0);
5611
- perf.endSession();
5649
+ perf$1.measure('orchestrator.process', t0);
5650
+ perf$1.endSession();
5612
5651
  s.logger.log('Process completed:', result);
5613
5652
  s.config.onSuccess?.(result);
5614
5653
  dispatchDimensionsEvent(result);
5615
5654
  }
5616
5655
  catch (error) {
5617
- perf.measure('orchestrator.process', t0);
5618
- perf.endSession();
5656
+ perf$1.measure('orchestrator.process', t0);
5657
+ perf$1.endSession();
5619
5658
  s.logger.error('Failed to process:', error);
5620
5659
  s.config.onError?.(error);
5621
5660
  }
@@ -6077,20 +6116,15 @@ class GXVisualizer extends Visualizer {
6077
6116
  constructor() {
6078
6117
  super();
6079
6118
  this.attentionMap = new AttentionMapRenderer(null);
6080
- // Save references to base implementations before overriding
6081
6119
  this.originalSetup = this.setup;
6082
6120
  this.originalClearmap = this.clearmap;
6083
6121
  this.clearmap = this.clearmapOverride;
6084
6122
  this.setup = this.setupOverride;
6085
6123
  }
6086
6124
  setupOverride = async (target, options) => {
6087
- // Clear existing custom renderers before re-initializing (null-safe)
6088
6125
  this.attentionMap?.clear();
6089
- // Initialize base Visualizer (sets this.state, this.heatmap, this.layout, etc.)
6090
6126
  await this.originalSetup(target, options);
6091
- // Re-create custom renderers with the newly initialized PlaybackState
6092
- const state = this.state;
6093
- this.attentionMap = new AttentionMapRenderer(state);
6127
+ this.attentionMap = new AttentionMapRenderer(this.state);
6094
6128
  return this;
6095
6129
  };
6096
6130
  clearmapOverride = () => {
@@ -6109,21 +6143,12 @@ class GXVisualizer extends Visualizer {
6109
6143
  };
6110
6144
  }
6111
6145
 
6112
- // ── Performance timing ────────────────────────────────────────────────────────
6113
- function mark(label) {
6114
- const t = performance.now();
6115
- console.log(`[Render] ⏱ ${label}`);
6116
- return t;
6117
- }
6118
- function measure(label, startMs) {
6119
- const ms = (performance.now() - startMs).toFixed(1);
6120
- console.log(`[Render] ✅ ${label} — ${ms}ms`);
6121
- }
6122
- // ── Hook ──────────────────────────────────────────────────────────────────────
6146
+ const perf = createPerfTimer('Render');
6123
6147
  const useHeatmapRender = () => {
6124
6148
  const viewId = useViewIdContext();
6125
6149
  const data = useHeatmapDataContext((s) => s.data);
6126
6150
  const shopId = useHeatmapConfigStore((s) => s.shopId);
6151
+ const excludeClassNames = useHeatmapConfigStore((s) => s.excludeClassNames);
6127
6152
  const vizRef = useHeatmapVizRectContext((s) => s.vizRef);
6128
6153
  const setVizRef = useHeatmapVizRectContext((s) => s.setVizRef);
6129
6154
  const setIframeHeight = useHeatmapVizRectContext((s) => s.setIframeHeight);
@@ -6134,35 +6159,41 @@ const useHeatmapRender = () => {
6134
6159
  const iframeRef = useRef(null);
6135
6160
  const helperRef = useRef(null);
6136
6161
  const abortRef = useRef(null);
6162
+ const pendingDataRef = useRef(null);
6163
+ const wrapperHeightRef = useRef(wrapperHeight);
6164
+ wrapperHeightRef.current = wrapperHeight;
6165
+ const contentWidthRef = useRef(contentWidth);
6166
+ contentWidthRef.current = contentWidth;
6137
6167
  const renderHeatmap = useCallback(async (payloads) => {
6138
- if (contentWidth === 0 || wrapperHeight === 0)
6168
+ if (contentWidthRef.current === 0 || wrapperHeightRef.current === 0) {
6169
+ pendingDataRef.current = payloads;
6139
6170
  return;
6171
+ }
6172
+ pendingDataRef.current = null;
6140
6173
  if (!payloads || payloads.length === 0)
6141
6174
  return;
6142
- // Cancel any in-flight render before starting a new one
6175
+ const iframe = iframeRef.current;
6176
+ if (!iframe?.contentWindow)
6177
+ return;
6143
6178
  abortRef.current?.abort();
6144
6179
  const abort = new AbortController();
6145
6180
  abortRef.current = abort;
6146
- const t0 = mark('renderHeatmap start');
6181
+ const t0 = perf.mark('renderHeatmap start');
6147
6182
  const visualizer = vizRef ?? new GXVisualizer();
6148
6183
  if (!vizRef)
6149
6184
  setVizRef(visualizer);
6185
+ visualizer.configure({ excludeClassNames });
6150
6186
  setIsRenderedViz(false);
6151
- const iframe = iframeRef.current;
6152
- if (!iframe?.contentWindow)
6153
- return;
6154
- const tHtml = mark('visualizer.html start');
6155
- await visualizer.html(payloads, iframe.contentWindow, viewId);
6156
- measure('visualizer.html', tHtml);
6157
- // Bail out if data changed or component unmounted while we were awaiting
6187
+ await perf.wrap('visualizer.html', () => visualizer.html(payloads, iframe.contentWindow, viewId));
6158
6188
  if (abort.signal.aborted)
6159
6189
  return;
6190
+ const size = { width: contentWidthRef.current, height: wrapperHeightRef.current };
6160
6191
  startIframe({
6161
6192
  helperRef,
6162
6193
  iframe,
6163
6194
  shopId,
6164
6195
  deviceType,
6165
- size: { width: contentWidth, height: wrapperHeight },
6196
+ size,
6166
6197
  t0,
6167
6198
  onSuccess: (height) => {
6168
6199
  if (abort.signal.aborted)
@@ -6172,27 +6203,33 @@ const useHeatmapRender = () => {
6172
6203
  setIsRenderedViz(true);
6173
6204
  },
6174
6205
  });
6175
- }, [wrapperHeight, contentWidth, deviceType]);
6206
+ }, [deviceType]);
6176
6207
  useEffect(() => {
6177
6208
  if (!data || data.length === 0)
6178
6209
  return;
6179
6210
  const decoded = decodeArrayClarity(data);
6180
6211
  renderHeatmap(decoded);
6181
- return () => {
6182
- setVizRef(null);
6183
- };
6184
- }, [data, renderHeatmap, setVizRef]);
6185
- // Abort render + stop helper when the component unmounts
6212
+ return () => { };
6213
+ }, [data, renderHeatmap]);
6214
+ // Retry pending render when dimensions become available
6215
+ useEffect(() => {
6216
+ if (contentWidth === 0 || wrapperHeight === 0)
6217
+ return;
6218
+ if (!pendingDataRef.current)
6219
+ return;
6220
+ const pending = pendingDataRef.current;
6221
+ pendingDataRef.current = null;
6222
+ renderHeatmap(pending);
6223
+ }, [contentWidth, wrapperHeight, renderHeatmap]);
6186
6224
  useEffect(() => {
6187
6225
  return () => {
6226
+ setVizRef(null);
6188
6227
  abortRef.current?.abort();
6189
6228
  helperRef.current?.stop();
6190
6229
  helperRef.current = null;
6191
6230
  };
6192
- }, []);
6193
- return {
6194
- iframeRef,
6195
- };
6231
+ }, [setVizRef]);
6232
+ return { iframeRef };
6196
6233
  };
6197
6234
  // ── Helpers ───────────────────────────────────────────────────────────────────
6198
6235
  function startIframe({ helperRef, iframe, shopId, deviceType = EDeviceType.Desktop, size, t0, onSuccess, }) {
@@ -6201,7 +6238,7 @@ function startIframe({ helperRef, iframe, shopId, deviceType = EDeviceType.Deskt
6201
6238
  if (docHeight === 0)
6202
6239
  return;
6203
6240
  helperRef.current?.stop();
6204
- const tHelper = mark('IframeHelper.start');
6241
+ const tHelper = perf.mark('IframeHelper.start');
6205
6242
  const helper = createIframeHelper();
6206
6243
  helperRef.current = helper;
6207
6244
  helper.start({
@@ -6212,8 +6249,8 @@ function startIframe({ helperRef, iframe, shopId, deviceType = EDeviceType.Deskt
6212
6249
  debug: true,
6213
6250
  shopId,
6214
6251
  onSuccess: (data) => {
6215
- measure('IframeHelper processing', tHelper);
6216
- measure('Total render', t0);
6252
+ perf.measure('IframeHelper processing', tHelper);
6253
+ perf.measure('Total render', t0);
6217
6254
  iframe.style.height = `${data.height}px`;
6218
6255
  onSuccess(data.height);
6219
6256
  },
@@ -8482,11 +8519,11 @@ const ContentTopBar = () => {
8482
8519
  }, children: CompTopBar && jsx(CompTopBar, {}) }));
8483
8520
  };
8484
8521
 
8485
- const HeatmapLayout = ({ shopId, data, clickmap, clickAreas, scrollmap, attentionMap, controls, dataInfo, isLoading, isLoadingCanvas, }) => {
8522
+ const HeatmapLayout = ({ shopId, data, clickmap, clickAreas, scrollmap, attentionMap, controls, dataInfo, isLoading, isLoadingCanvas, excludeClassNames, }) => {
8486
8523
  useRegisterControl(controls);
8487
8524
  useRegisterData(data, dataInfo);
8488
8525
  useRegisterHeatmap({ clickmap, scrollmap, clickAreas, attentionMap });
8489
- useRegisterConfig({ isLoading, isLoadingCanvas, shopId });
8526
+ useRegisterConfig({ isLoading, isLoadingCanvas, shopId, excludeClassNames });
8490
8527
  // performanceLogger.configure({
8491
8528
  // enabled: true,
8492
8529
  // logToConsole: false,