@memlab/lens 2.0.2 → 2.0.3

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,3 +1,5 @@
1
+ /* @generated */
2
+ /* @nolint */
1
3
  /**
2
4
  * @license MemLab
3
5
  * MIT License
@@ -27,66 +29,40 @@
27
29
  /******/ "use strict";
28
30
  /******/ var __webpack_modules__ = ({
29
31
 
30
- /***/ 23
31
- (__unused_webpack_module, exports, __webpack_require__) {
32
+ /***/ 346
33
+ (__unused_webpack_module, exports) {
32
34
 
35
+ var __webpack_unused_export__;
33
36
 
34
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
35
- if (kind === "m") throw new TypeError("Private method is not writable");
36
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
37
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
38
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
37
+ /**
38
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
39
+ *
40
+ * This source code is licensed under the MIT license found in the
41
+ * LICENSE file in the root directory of this source tree.
42
+ *
43
+ * @format
44
+ * @oncall memory_lab
45
+ */
46
+ __webpack_unused_export__ = ({ value: true });
47
+ exports.config = exports.of = exports.lF = void 0;
48
+ // Performance Configuration
49
+ exports.lF = {
50
+ scanIntervalMs: 1000,
51
+ maxComponentStackDepth: 100,
52
+ memoryMeasurementIntervalMs: 5000,
39
53
  };
40
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
41
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
42
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
43
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
54
+ // Feature Flags
55
+ exports.of = {
56
+ enableMutationObserver: true,
57
+ enableMemoryTracking: true,
58
+ enableComponentStack: true,
59
+ enableConsoleLogs: window === null || window === void 0 ? void 0 : window.TEST_MEMORY_SCAN,
44
60
  };
45
- var __importDefault = (this && this.__importDefault) || function (mod) {
46
- return (mod && mod.__esModule) ? mod : { "default": mod };
61
+ // overall Config
62
+ exports.config = {
63
+ performance: exports.lF,
64
+ features: exports.of,
47
65
  };
48
- var _DOMVisualizationExtension_domVirtualizer;
49
- Object.defineProperty(exports, "__esModule", ({ value: true }));
50
- exports.DOMVisualizationExtension = void 0;
51
- const dom_element_visualizer_1 = __importDefault(__webpack_require__(150));
52
- const dom_element_visualizer_interactive_1 = __importDefault(__webpack_require__(271));
53
- const basic_extension_1 = __webpack_require__(860);
54
- const USE_INTERACTIVE_VISUALIZER = true;
55
- class DOMVisualizationExtension extends basic_extension_1.BasicExtension {
56
- constructor(scanner) {
57
- super(scanner);
58
- _DOMVisualizationExtension_domVirtualizer.set(this, void 0);
59
- if (USE_INTERACTIVE_VISUALIZER) {
60
- __classPrivateFieldSet(this, _DOMVisualizationExtension_domVirtualizer, new dom_element_visualizer_interactive_1.default(), "f");
61
- }
62
- else {
63
- __classPrivateFieldSet(this, _DOMVisualizationExtension_domVirtualizer, new dom_element_visualizer_1.default(), "f");
64
- }
65
- }
66
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
67
- afterScan(_analysisResult) {
68
- var _a;
69
- // const start = Date.now();
70
- const scanner = this.scanner;
71
- if (scanner.isDevMode()) {
72
- const detachedDOMInfo = scanner.getDetachedDOMInfo();
73
- (_a = __classPrivateFieldGet(this, _DOMVisualizationExtension_domVirtualizer, "f")) === null || _a === void 0 ? void 0 : _a.repaint(detachedDOMInfo);
74
- }
75
- // const end = Date.now();
76
- // console.log(`repaint took ${end - start}ms`);
77
- }
78
- cleanup() {
79
- // Clean up the visualizer to prevent memory leaks
80
- if (__classPrivateFieldGet(this, _DOMVisualizationExtension_domVirtualizer, "f") &&
81
- typeof __classPrivateFieldGet(this, _DOMVisualizationExtension_domVirtualizer, "f").cleanup === 'function') {
82
- __classPrivateFieldGet(this, _DOMVisualizationExtension_domVirtualizer, "f").cleanup();
83
- }
84
- // Clear the reference
85
- __classPrivateFieldSet(this, _DOMVisualizationExtension_domVirtualizer, null, "f");
86
- }
87
- }
88
- exports.DOMVisualizationExtension = DOMVisualizationExtension;
89
- _DOMVisualizationExtension_domVirtualizer = new WeakMap();
90
66
 
91
67
 
92
68
  /***/ },
@@ -286,7 +262,7 @@ _DOMObserver_elementCount = new WeakMap(), _DOMObserver_detachedElementCount = n
286
262
 
287
263
  /***/ },
288
264
 
289
- /***/ 150
265
+ /***/ 953
290
266
  (__unused_webpack_module, exports, __webpack_require__) {
291
267
 
292
268
 
@@ -301,122 +277,303 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
301
277
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
302
278
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
303
279
  };
304
- var _DOMElementVisualizer_instances, _DOMElementVisualizer_canvas, _DOMElementVisualizer_paint, _DOMElementVisualizer_cleanupExistingCanvas, _DOMElementVisualizer_tryToAttachCanvas, _DOMElementVisualizer_createAndAppendCanvas, _DOMElementVisualizer_paintKey, _DOMElementVisualizer_paintRectangles, _DOMElementVisualizer_cleanup;
280
+ var _EventListenerTracker_instances, _EventListenerTracker_listenerMap, _EventListenerTracker_detachedListeners, _EventListenerTracker_originalAddEventListener, _EventListenerTracker_originalRemoveEventListener, _EventListenerTracker_patchEventListeners, _EventListenerTracker_unpatchEventListeners;
305
281
  Object.defineProperty(exports, "__esModule", ({ value: true }));
306
- const visual_utils_1 = __webpack_require__(498);
307
- class DOMElementVisualizer {
282
+ exports.EventListenerTracker = void 0;
283
+ const react_fiber_utils_1 = __webpack_require__(737);
284
+ const weak_ref_utils_1 = __webpack_require__(313);
285
+ class EventListenerTracker {
308
286
  constructor() {
309
- _DOMElementVisualizer_instances.add(this);
310
- _DOMElementVisualizer_canvas.set(this, void 0);
311
- __classPrivateFieldSet(this, _DOMElementVisualizer_canvas, null, "f");
312
- }
313
- cleanup() {
314
- __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_cleanup).call(this);
287
+ _EventListenerTracker_instances.add(this);
288
+ _EventListenerTracker_listenerMap.set(this, void 0);
289
+ _EventListenerTracker_detachedListeners.set(this, void 0);
290
+ _EventListenerTracker_originalAddEventListener.set(this, void 0);
291
+ _EventListenerTracker_originalRemoveEventListener.set(this, void 0);
292
+ __classPrivateFieldSet(this, _EventListenerTracker_listenerMap, new weak_ref_utils_1.WeakMapPlus({ fallback: 'noop', cleanupMs: 100 }), "f");
293
+ __classPrivateFieldSet(this, _EventListenerTracker_detachedListeners, new Map(), "f");
294
+ __classPrivateFieldSet(this, _EventListenerTracker_originalAddEventListener, EventTarget.prototype.addEventListener, "f");
295
+ __classPrivateFieldSet(this, _EventListenerTracker_originalRemoveEventListener, EventTarget.prototype.removeEventListener, "f");
296
+ __classPrivateFieldGet(this, _EventListenerTracker_instances, "m", _EventListenerTracker_patchEventListeners).call(this);
315
297
  }
316
- repaint(domElementInfoList) {
317
- __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_cleanup).call(this);
318
- __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_paint).call(this, domElementInfoList);
298
+ static getInstance() {
299
+ if (!EventListenerTracker.instance) {
300
+ EventListenerTracker.instance = new EventListenerTracker();
301
+ }
302
+ return EventListenerTracker.instance;
319
303
  }
320
- }
321
- _DOMElementVisualizer_canvas = new WeakMap(), _DOMElementVisualizer_instances = new WeakSet(), _DOMElementVisualizer_paint = function _DOMElementVisualizer_paint(domElementInfoList) {
322
- if (!__classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f")) {
323
- const canvas = __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_createAndAppendCanvas).call(this);
324
- __classPrivateFieldSet(this, _DOMElementVisualizer_canvas, canvas, "f");
304
+ addListener(el, type, cb, options) {
305
+ el.addEventListener(type, cb, options);
325
306
  }
326
- __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_paintRectangles).call(this, domElementInfoList);
327
- }, _DOMElementVisualizer_cleanupExistingCanvas = function _DOMElementVisualizer_cleanupExistingCanvas() {
328
- // Clean up any existing canvas
329
- if (__classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f")) {
330
- const ctx = __classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f").getContext('2d');
331
- ctx === null || ctx === void 0 ? void 0 : ctx.clearRect(0, 0, __classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f").width, __classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f").height);
332
- __classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f").remove();
333
- __classPrivateFieldSet(this, _DOMElementVisualizer_canvas, null, "f");
307
+ removeListener(el, type, cb, options) {
308
+ el.removeEventListener(type, cb, options);
334
309
  }
335
- }, _DOMElementVisualizer_tryToAttachCanvas = function _DOMElementVisualizer_tryToAttachCanvas(canvas) {
336
- if (document.body) {
337
- document.body.appendChild(canvas);
310
+ scan(getComponentName) {
311
+ const detachedListeners = new Map();
312
+ for (const [el, listeners] of __classPrivateFieldGet(this, _EventListenerTracker_listenerMap, "f").entries()) {
313
+ if (el instanceof Element && !el.isConnected) {
314
+ for (const listener of listeners) {
315
+ // Skip if the callback has been garbage collected
316
+ if (!listener.cb.deref())
317
+ continue;
318
+ const componentName = getComponentName(new WeakRef(el));
319
+ if (!detachedListeners.has(componentName)) {
320
+ detachedListeners.set(componentName, []);
321
+ }
322
+ const groups = detachedListeners.get(componentName);
323
+ let group = groups === null || groups === void 0 ? void 0 : groups.find(g => g.type === listener.type);
324
+ if (!group) {
325
+ group = {
326
+ type: listener.type,
327
+ count: 0,
328
+ entries: [],
329
+ };
330
+ groups === null || groups === void 0 ? void 0 : groups.push(group);
331
+ }
332
+ group.count++;
333
+ group.entries.push(new WeakRef(listener));
334
+ }
335
+ }
336
+ }
337
+ __classPrivateFieldSet(this, _EventListenerTracker_detachedListeners, detachedListeners, "f");
338
+ return detachedListeners;
338
339
  }
339
- }, _DOMElementVisualizer_createAndAppendCanvas = function _DOMElementVisualizer_createAndAppendCanvas() {
340
- // Create and insert the canvas element
341
- const canvas = (0, visual_utils_1.createVisualizerElement)('canvas');
342
- canvas.id = 'overlayCanvas';
343
- __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_tryToAttachCanvas).call(this, canvas);
344
- // Style the canvas to cover the entire page
345
- canvas.style.position = 'absolute';
346
- canvas.style.top = '0';
347
- canvas.style.left = '0';
348
- canvas.style.width = '100%';
349
- canvas.style.height = '100%';
350
- canvas.style.pointerEvents = 'none';
351
- canvas.style.zIndex = '99999';
352
- // Set canvas dimensions to match the window dimensions
353
- canvas.width = window.innerWidth;
354
- canvas.height = window.innerHeight;
355
- return canvas;
356
- }, _DOMElementVisualizer_paintKey = function _DOMElementVisualizer_paintKey(info) {
357
- const { boundingRect } = info;
358
- return JSON.stringify({ boundingRect });
359
- }, _DOMElementVisualizer_paintRectangles = function _DOMElementVisualizer_paintRectangles(domElementInfoList) {
360
- const canvas = __classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f");
361
- if (!canvas) {
362
- return;
340
+ getDetachedListeners() {
341
+ return __classPrivateFieldGet(this, _EventListenerTracker_detachedListeners, "f");
363
342
  }
364
- // Get the 2D drawing context
365
- const ctx = canvas.getContext('2d');
366
- if (ctx == null) {
367
- return;
343
+ destroy() {
344
+ __classPrivateFieldGet(this, _EventListenerTracker_instances, "m", _EventListenerTracker_unpatchEventListeners).call(this);
345
+ __classPrivateFieldGet(this, _EventListenerTracker_listenerMap, "f").destroy();
346
+ __classPrivateFieldGet(this, _EventListenerTracker_detachedListeners, "f").clear();
347
+ EventListenerTracker.instance = null;
368
348
  }
369
- // Set rectangle styles
370
- ctx.strokeStyle = 'rgba(75, 192, 192, 0.8)';
371
- ctx.lineWidth = 2;
372
- ctx.fillStyle = 'rgba(75, 192, 192, 0.05)';
373
- ctx.font = '11px Inter, system-ui, -apple-system, sans-serif';
374
- const paintedInfo = new Set();
375
- // Draw the rectangles
376
- domElementInfoList.forEach((info) => {
349
+ }
350
+ exports.EventListenerTracker = EventListenerTracker;
351
+ _EventListenerTracker_listenerMap = new WeakMap(), _EventListenerTracker_detachedListeners = new WeakMap(), _EventListenerTracker_originalAddEventListener = new WeakMap(), _EventListenerTracker_originalRemoveEventListener = new WeakMap(), _EventListenerTracker_instances = new WeakSet(), _EventListenerTracker_patchEventListeners = function _EventListenerTracker_patchEventListeners() {
352
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
353
+ const self = this;
354
+ EventTarget.prototype.addEventListener = function (type, listener, options) {
377
355
  var _a;
378
- const rect = info.boundingRect;
379
- if (rect == null) {
380
- return;
356
+ __classPrivateFieldGet(self, _EventListenerTracker_originalAddEventListener, "f").call(this, type, listener, options);
357
+ if (this instanceof Element) {
358
+ const fiber = (0, react_fiber_utils_1.getFiberNodeFromElement)(this);
359
+ const entry = {
360
+ type,
361
+ cb: new WeakRef(listener),
362
+ options,
363
+ fiber: fiber ? new WeakRef(fiber) : undefined,
364
+ };
365
+ const listeners = (_a = __classPrivateFieldGet(self, _EventListenerTracker_listenerMap, "f").get(this)) !== null && _a !== void 0 ? _a : [];
366
+ listeners.push(entry);
367
+ __classPrivateFieldGet(self, _EventListenerTracker_listenerMap, "f").set(this, listeners);
381
368
  }
382
- const key = __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_paintKey).call(this, info);
383
- if (paintedInfo.has(key)) {
384
- return;
369
+ };
370
+ EventTarget.prototype.removeEventListener = function (type, listener, options) {
371
+ __classPrivateFieldGet(self, _EventListenerTracker_originalRemoveEventListener, "f").call(this, type, listener, options);
372
+ if (this instanceof Element) {
373
+ const listeners = __classPrivateFieldGet(self, _EventListenerTracker_listenerMap, "f").get(this);
374
+ if (listeners) {
375
+ const index = listeners.findIndex(entry => entry.type === type &&
376
+ entry.cb.deref() === listener &&
377
+ entry.options === options);
378
+ if (index !== -1) {
379
+ listeners.splice(index, 1);
380
+ }
381
+ if (listeners.length === 0) {
382
+ __classPrivateFieldGet(self, _EventListenerTracker_listenerMap, "f").delete(this);
383
+ }
384
+ else {
385
+ __classPrivateFieldGet(self, _EventListenerTracker_listenerMap, "f").set(this, listeners);
386
+ }
387
+ }
385
388
  }
386
- paintedInfo.add(key);
387
- ctx.fillRect(rect.left, rect.top, rect.width, rect.height);
388
- ctx.strokeRect(rect.left, rect.top, rect.width, rect.height);
389
- const component = (_a = info.componentStack) === null || _a === void 0 ? void 0 : _a[0];
390
- if (component) {
391
- // attach detached element id key so that it is easy to search in heap snapshot
392
- const element = info.element.deref();
393
- const elementId = element === null || element === void 0 ? void 0 : element.detachedElementId;
394
- const elementIdText = elementId ? ` (${elementId})` : '';
395
- const text = `${component}${elementIdText}`;
396
- ctx.fillStyle = 'rgba(74, 131, 224, 1)';
397
- ctx.fillText(text, rect.left + 5, rect.top + 15); // Draw the name
398
- ctx.fillStyle = 'rgba(75, 192, 192, 0.05)';
389
+ };
390
+ }, _EventListenerTracker_unpatchEventListeners = function _EventListenerTracker_unpatchEventListeners() {
391
+ EventTarget.prototype.addEventListener = __classPrivateFieldGet(this, _EventListenerTracker_originalAddEventListener, "f");
392
+ EventTarget.prototype.removeEventListener =
393
+ __classPrivateFieldGet(this, _EventListenerTracker_originalRemoveEventListener, "f");
394
+ };
395
+ EventListenerTracker.instance = null;
396
+
397
+
398
+ /***/ },
399
+
400
+ /***/ 302
401
+ (__unused_webpack_module, exports, __webpack_require__) {
402
+
403
+
404
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
405
+ if (k2 === undefined) k2 = k;
406
+ var desc = Object.getOwnPropertyDescriptor(m, k);
407
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
408
+ desc = { enumerable: true, get: function() { return m[k]; } };
409
+ }
410
+ Object.defineProperty(o, k2, desc);
411
+ }) : (function(o, m, k, k2) {
412
+ if (k2 === undefined) k2 = k;
413
+ o[k2] = m[k];
414
+ }));
415
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
416
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
417
+ }) : function(o, v) {
418
+ o["default"] = v;
419
+ });
420
+ var __importStar = (this && this.__importStar) || (function () {
421
+ var ownKeys = function(o) {
422
+ ownKeys = Object.getOwnPropertyNames || function (o) {
423
+ var ar = [];
424
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
425
+ return ar;
426
+ };
427
+ return ownKeys(o);
428
+ };
429
+ return function (mod) {
430
+ if (mod && mod.__esModule) return mod;
431
+ var result = {};
432
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
433
+ __setModuleDefault(result, mod);
434
+ return result;
435
+ };
436
+ })();
437
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
438
+ /**
439
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
440
+ *
441
+ * This source code is licensed under the MIT license found in the
442
+ * LICENSE file in the root directory of this source tree.
443
+ *
444
+ * @format
445
+ * @oncall memory_lab
446
+ */
447
+ const utils = __importStar(__webpack_require__(476));
448
+ const react_fiber_utils_1 = __webpack_require__(737);
449
+ const valid_component_name_1 = __webpack_require__(847);
450
+ class ReactFiberAnalyzer {
451
+ scan(elementWeakRefList, elementToComponentStack) {
452
+ var _a;
453
+ const visitedRootFibers = new Set();
454
+ const components = new Set();
455
+ const componentToFiberNodeCount = new Map();
456
+ const detachedComponentToFiberNodeCount = new Map();
457
+ const topDownVisited = new Set();
458
+ const analyzedFibers = new Set();
459
+ const fiberNodes = [];
460
+ let totalElements = 0;
461
+ let totalDetachedElements = 0;
462
+ function analyzeFiber(fiberNode) {
463
+ (0, react_fiber_utils_1.traverseFiber)(fiberNode, (fiberNode) => {
464
+ // skip if the fiber node has already been analyzed
465
+ if (analyzedFibers.has(fiberNode)) {
466
+ return true;
467
+ }
468
+ analyzedFibers.add(fiberNode);
469
+ // traverse the fiber tree up to find the component name
470
+ const displayName = (0, react_fiber_utils_1.getDisplayNameOfFiberNode)(fiberNode);
471
+ if (displayName != null && (0, valid_component_name_1.isValidComponentName)(displayName)) {
472
+ components.add(displayName);
473
+ utils.addCountbyKey(componentToFiberNodeCount, displayName, 1);
474
+ return true;
475
+ }
476
+ }, true);
399
477
  }
400
- });
401
- }, _DOMElementVisualizer_cleanup = function _DOMElementVisualizer_cleanup() {
402
- var _a;
403
- const canvas = __classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f");
404
- if (canvas) {
405
- const ctx = canvas.getContext('2d');
406
- ctx === null || ctx === void 0 ? void 0 : ctx.clearRect(0, 0, canvas.width, canvas.height);
407
- (_a = canvas.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(canvas);
478
+ for (const weakRef of elementWeakRefList) {
479
+ const elem = weakRef.deref();
480
+ if (elem == null) {
481
+ continue;
482
+ }
483
+ // elements stats
484
+ ++totalElements;
485
+ // TODO: simplify this logic
486
+ if (!elem.isConnected) {
487
+ if (elementToComponentStack.has(elem)) {
488
+ const componentStack = (_a = elementToComponentStack.get(elem)) !== null && _a !== void 0 ? _a : [];
489
+ // set component name
490
+ const component = componentStack[0];
491
+ elem.__component_name = component;
492
+ utils.addCountbyKey(detachedComponentToFiberNodeCount, component, 1);
493
+ }
494
+ ++totalDetachedElements;
495
+ }
496
+ // analyze fiber nodes
497
+ const fiberNode = (0, react_fiber_utils_1.getFiberNodeFromElement)(elem);
498
+ if (fiberNode == null) {
499
+ continue;
500
+ }
501
+ analyzeFiber(fiberNode);
502
+ // try to traverse each fiber node in the entire fiber tree
503
+ const rootFiber = (0, react_fiber_utils_1.getTopMostFiberWithChild)(fiberNode);
504
+ if (rootFiber == null) {
505
+ continue;
506
+ }
507
+ if (visitedRootFibers.has(rootFiber)) {
508
+ continue;
509
+ }
510
+ visitedRootFibers.add(rootFiber);
511
+ // start traversing fiber tree from the know root host
512
+ (0, react_fiber_utils_1.traverseFiber)(rootFiber, (node) => {
513
+ if (topDownVisited.has(node)) {
514
+ return true;
515
+ }
516
+ topDownVisited.add(node);
517
+ fiberNodes.push(new WeakRef(node));
518
+ analyzeFiber(node);
519
+ }, false);
520
+ }
521
+ topDownVisited.clear();
522
+ analyzedFibers.clear();
523
+ visitedRootFibers.clear();
524
+ return {
525
+ components,
526
+ componentToFiberNodeCount,
527
+ totalElements,
528
+ totalDetachedElements,
529
+ detachedComponentToFiberNodeCount,
530
+ fiberNodes,
531
+ leakedFibers: [],
532
+ };
408
533
  }
409
- __classPrivateFieldSet(this, _DOMElementVisualizer_canvas, null, "f");
410
- };
411
- exports["default"] = DOMElementVisualizer;
534
+ }
535
+ exports["default"] = ReactFiberAnalyzer;
412
536
 
413
537
 
414
538
  /***/ },
415
539
 
416
- /***/ 271
540
+ /***/ 282
417
541
  (__unused_webpack_module, exports, __webpack_require__) {
418
542
 
419
543
 
544
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
545
+ if (k2 === undefined) k2 = k;
546
+ var desc = Object.getOwnPropertyDescriptor(m, k);
547
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
548
+ desc = { enumerable: true, get: function() { return m[k]; } };
549
+ }
550
+ Object.defineProperty(o, k2, desc);
551
+ }) : (function(o, m, k, k2) {
552
+ if (k2 === undefined) k2 = k;
553
+ o[k2] = m[k];
554
+ }));
555
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
556
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
557
+ }) : function(o, v) {
558
+ o["default"] = v;
559
+ });
560
+ var __importStar = (this && this.__importStar) || (function () {
561
+ var ownKeys = function(o) {
562
+ ownKeys = Object.getOwnPropertyNames || function (o) {
563
+ var ar = [];
564
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
565
+ return ar;
566
+ };
567
+ return ownKeys(o);
568
+ };
569
+ return function (mod) {
570
+ if (mod && mod.__esModule) return mod;
571
+ var result = {};
572
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
573
+ __setModuleDefault(result, mod);
574
+ return result;
575
+ };
576
+ })();
420
577
  var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
421
578
  if (kind === "m") throw new TypeError("Private method is not writable");
422
579
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
@@ -428,627 +585,270 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
428
585
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
429
586
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
430
587
  };
588
+ var __rest = (this && this.__rest) || function (s, e) {
589
+ var t = {};
590
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
591
+ t[p] = s[p];
592
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
593
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
594
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
595
+ t[p[i]] = s[p[i]];
596
+ }
597
+ return t;
598
+ };
431
599
  var __importDefault = (this && this.__importDefault) || function (mod) {
432
600
  return (mod && mod.__esModule) ? mod : { "default": mod };
433
601
  };
434
- var _DOMElementVisualizerInteractive_instances, _DOMElementVisualizerInteractive_elementIdToRectangle, _DOMElementVisualizerInteractive_visualizationOverlayDiv, _DOMElementVisualizerInteractive_controlWidget, _DOMElementVisualizerInteractive_blockedElementIds, _DOMElementVisualizerInteractive_currentVisualData, _DOMElementVisualizerInteractive_hideAllRef, _DOMElementVisualizerInteractive_updateDataCallbacks, _DOMElementVisualizerInteractive_listenToKeyboardEvent, _DOMElementVisualizerInteractive_initVisualizerData, _DOMElementVisualizerInteractive_getOutlineElementByElementId, _DOMElementVisualizerInteractive_getElementIdSet, _DOMElementVisualizerInteractive_getComponentStackForElement, _DOMElementVisualizerInteractive_traverseUpOutlineElements, _DOMElementVisualizerInteractive_removeVisualizerElement, _DOMElementVisualizerInteractive_cleanup, _DOMElementVisualizerInteractive_getZIndex, _DOMElementVisualizerInteractive_paint, _DOMElementVisualizerInteractive_updateVisualizerData;
602
+ var _ReactMemoryScan_instances, _ReactMemoryScan_elementWeakRefs, _ReactMemoryScan_isActivated, _ReactMemoryScan_intervalId, _ReactMemoryScan_elementToBoundingRects, _ReactMemoryScan_elementToComponentStack, _ReactMemoryScan_knownFiberNodes, _ReactMemoryScan_fiberAnalyzer, _ReactMemoryScan_isDevMode, _ReactMemoryScan_subscribers, _ReactMemoryScan_extensions, _ReactMemoryScan_scanIntervalMs, _ReactMemoryScan_domObserver, _ReactMemoryScan_eventListenerTracker, _ReactMemoryScan_isDisposed, _ReactMemoryScan_log, _ReactMemoryScan_notifySubscribers, _ReactMemoryScan_notifyExtensionsBeforeScan, _ReactMemoryScan_notifyExtensionsAfterScan, _ReactMemoryScan_scanCycle, _ReactMemoryScan_updateElementToComponentInfo, _ReactMemoryScan_getTrackedDOMRefs, _ReactMemoryScan_runGC, _ReactMemoryScan_scanEventListenerLeaks;
435
603
  Object.defineProperty(exports, "__esModule", ({ value: true }));
436
- const dom_element_visualizer_1 = __importDefault(__webpack_require__(150));
437
- const visual_overlay_1 = __webpack_require__(368);
438
- const control_widget_1 = __webpack_require__(341);
439
- const overlay_rectangle_1 = __webpack_require__(701);
440
- const utils_1 = __webpack_require__(476);
441
- const visual_utils_1 = __webpack_require__(498);
442
- class DOMElementVisualizerInteractive extends dom_element_visualizer_1.default {
443
- constructor() {
444
- super();
445
- _DOMElementVisualizerInteractive_instances.add(this);
446
- _DOMElementVisualizerInteractive_elementIdToRectangle.set(this, void 0);
447
- _DOMElementVisualizerInteractive_visualizationOverlayDiv.set(this, void 0);
448
- _DOMElementVisualizerInteractive_controlWidget.set(this, void 0);
449
- _DOMElementVisualizerInteractive_blockedElementIds.set(this, void 0);
450
- _DOMElementVisualizerInteractive_currentVisualData.set(this, void 0);
451
- _DOMElementVisualizerInteractive_hideAllRef.set(this, void 0);
452
- _DOMElementVisualizerInteractive_updateDataCallbacks.set(this, []);
453
- __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_hideAllRef, { value: false }, "f");
454
- __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, (0, visual_overlay_1.createOverlayDiv)(), "f");
455
- (0, visual_utils_1.tryToAttachOverlay)(__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f"));
456
- __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_controlWidget, (0, control_widget_1.createControlWidget)(__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f"), __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_hideAllRef, "f"), cb => {
457
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_updateDataCallbacks, "f").push(cb);
458
- }), "f");
459
- (0, visual_utils_1.tryToAttachOverlay)(__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_controlWidget, "f"));
460
- __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, new Map(), "f");
461
- __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_currentVisualData, __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_initVisualizerData).call(this), "f");
462
- __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_blockedElementIds, new Set(), "f");
463
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_listenToKeyboardEvent).call(this);
464
- }
465
- repaint(domElementInfoList) {
466
- // this.#controlWidget.remove();
467
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f").remove();
468
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_cleanup).call(this, domElementInfoList);
469
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_paint).call(this, domElementInfoList);
470
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_updateVisualizerData).call(this);
471
- (0, visual_utils_1.tryToAttachOverlay)(__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f"));
472
- // tryToAttachOverlay(this.#controlWidget);
473
- }
474
- cleanup() {
475
- // Clean up the visualization overlay
476
- if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f")) {
477
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f").remove();
478
- }
479
- // Clean up the control widget
480
- if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_controlWidget, "f")) {
481
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_controlWidget, "f").remove();
482
- }
483
- // Clear all element references
484
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").clear();
485
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_blockedElementIds, "f").clear();
486
- __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_updateDataCallbacks, [], "f");
487
- // Call parent cleanup
488
- super.cleanup();
489
- }
490
- }
491
- _DOMElementVisualizerInteractive_elementIdToRectangle = new WeakMap(), _DOMElementVisualizerInteractive_visualizationOverlayDiv = new WeakMap(), _DOMElementVisualizerInteractive_controlWidget = new WeakMap(), _DOMElementVisualizerInteractive_blockedElementIds = new WeakMap(), _DOMElementVisualizerInteractive_currentVisualData = new WeakMap(), _DOMElementVisualizerInteractive_hideAllRef = new WeakMap(), _DOMElementVisualizerInteractive_updateDataCallbacks = new WeakMap(), _DOMElementVisualizerInteractive_instances = new WeakSet(), _DOMElementVisualizerInteractive_listenToKeyboardEvent = function _DOMElementVisualizerInteractive_listenToKeyboardEvent() {
492
- document.addEventListener('keydown', event => {
493
- if (event.key === 'd' || event.key === 'D') {
494
- if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").selectedElementId != null) {
495
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_blockedElementIds, "f").add(__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").selectedElementId);
496
- }
497
- }
498
- });
499
- }, _DOMElementVisualizerInteractive_initVisualizerData = function _DOMElementVisualizerInteractive_initVisualizerData() {
500
- const data = {
501
- detachedDOMElementsCount: 0,
502
- totalDOMElementsCount: (0, utils_1.getDOMElementCount)(),
503
- selectedElementId: null,
504
- selectedReactComponentStack: [],
505
- pinnedElementId: null,
506
- setPinnedElementId: (pinnedElementId) => {
507
- var _a, _b;
508
- if (data.pinnedElementId == pinnedElementId) {
509
- return;
510
- }
511
- // unpin the original pinned element
512
- const oldPin = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_getOutlineElementByElementId).call(this, data.pinnedElementId);
513
- (_a = oldPin === null || oldPin === void 0 ? void 0 : oldPin.__unpinned) === null || _a === void 0 ? void 0 : _a.call(oldPin);
514
- // pin the newly pinned element
515
- const newPin = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_getOutlineElementByElementId).call(this, pinnedElementId);
516
- (_b = newPin === null || newPin === void 0 ? void 0 : newPin.__pinned) === null || _b === void 0 ? void 0 : _b.call(newPin);
517
- data.pinnedElementId = pinnedElementId;
518
- },
519
- };
520
- return data;
521
- }, _DOMElementVisualizerInteractive_getOutlineElementByElementId = function _DOMElementVisualizerInteractive_getOutlineElementByElementId(elementId) {
522
- if (elementId == null) {
523
- return null;
524
- }
525
- const info = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get(elementId);
526
- if (info == null) {
527
- return null;
604
+ const utils = __importStar(__webpack_require__(476));
605
+ const react_fiber_analysis_1 = __importDefault(__webpack_require__(302));
606
+ const react_fiber_utils_1 = __webpack_require__(737);
607
+ const dom_observer_1 = __webpack_require__(54);
608
+ const config_1 = __webpack_require__(346);
609
+ const event_listener_tracker_1 = __webpack_require__(953);
610
+ class ReactMemoryScan {
611
+ constructor(options = {}) {
612
+ var _a, _b, _c, _d;
613
+ _ReactMemoryScan_instances.add(this);
614
+ _ReactMemoryScan_elementWeakRefs.set(this, void 0);
615
+ _ReactMemoryScan_isActivated.set(this, void 0);
616
+ _ReactMemoryScan_intervalId.set(this, void 0);
617
+ _ReactMemoryScan_elementToBoundingRects.set(this, void 0);
618
+ _ReactMemoryScan_elementToComponentStack.set(this, void 0);
619
+ _ReactMemoryScan_knownFiberNodes.set(this, void 0);
620
+ _ReactMemoryScan_fiberAnalyzer.set(this, void 0);
621
+ _ReactMemoryScan_isDevMode.set(this, void 0);
622
+ _ReactMemoryScan_subscribers.set(this, void 0);
623
+ _ReactMemoryScan_extensions.set(this, void 0);
624
+ _ReactMemoryScan_scanIntervalMs.set(this, void 0);
625
+ _ReactMemoryScan_domObserver.set(this, void 0);
626
+ _ReactMemoryScan_eventListenerTracker.set(this, void 0);
627
+ _ReactMemoryScan_isDisposed.set(this, void 0);
628
+ __classPrivateFieldSet(this, _ReactMemoryScan_elementWeakRefs, [], "f");
629
+ __classPrivateFieldSet(this, _ReactMemoryScan_isActivated, false, "f");
630
+ __classPrivateFieldSet(this, _ReactMemoryScan_elementToBoundingRects, new WeakMap(), "f");
631
+ __classPrivateFieldSet(this, _ReactMemoryScan_elementToComponentStack, new WeakMap(), "f");
632
+ __classPrivateFieldSet(this, _ReactMemoryScan_knownFiberNodes, [], "f");
633
+ __classPrivateFieldSet(this, _ReactMemoryScan_eventListenerTracker, options.trackEventListenerLeaks
634
+ ? event_listener_tracker_1.EventListenerTracker.getInstance()
635
+ : null, "f");
636
+ __classPrivateFieldSet(this, _ReactMemoryScan_intervalId, null, "f");
637
+ __classPrivateFieldSet(this, _ReactMemoryScan_isDisposed, false, "f");
638
+ __classPrivateFieldSet(this, _ReactMemoryScan_fiberAnalyzer, new react_fiber_analysis_1.default(), "f");
639
+ __classPrivateFieldSet(this, _ReactMemoryScan_isDevMode, (_a = options.isDevMode) !== null && _a !== void 0 ? _a : false, "f");
640
+ __classPrivateFieldSet(this, _ReactMemoryScan_subscribers, (_b = options.subscribers) !== null && _b !== void 0 ? _b : [], "f");
641
+ __classPrivateFieldSet(this, _ReactMemoryScan_extensions, (_c = options.extensions) !== null && _c !== void 0 ? _c : [], "f");
642
+ __classPrivateFieldSet(this, _ReactMemoryScan_scanIntervalMs, (_d = options.scanIntervalMs) !== null && _d !== void 0 ? _d : config_1.config.performance.scanIntervalMs, "f");
528
643
  }
529
- return info.visualizerElementRef.deref();
530
- }, _DOMElementVisualizerInteractive_getElementIdSet = function _DOMElementVisualizerInteractive_getElementIdSet(domElementInfoList) {
531
- const elementIdSet = new Set();
532
- for (const info of domElementInfoList) {
533
- const element = info.element.deref();
534
- if (element == null) {
535
- continue;
536
- }
537
- const elementId = element.detachedElementId;
538
- if (elementId == null) {
539
- continue;
540
- }
541
- elementIdSet.add(elementId);
644
+ subscribe(callback) {
645
+ __classPrivateFieldGet(this, _ReactMemoryScan_subscribers, "f").push(callback);
646
+ return () => this.unsubscribe(callback);
542
647
  }
543
- return elementIdSet;
544
- }, _DOMElementVisualizerInteractive_getComponentStackForElement = function _DOMElementVisualizerInteractive_getComponentStackForElement(elementId) {
545
- const ret = [];
546
- if (elementId == null) {
547
- return ret;
648
+ unsubscribe(callback) {
649
+ __classPrivateFieldSet(this, _ReactMemoryScan_subscribers, __classPrivateFieldGet(this, _ReactMemoryScan_subscribers, "f").filter(cb => cb !== callback), "f");
548
650
  }
549
- const visualizer = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get(elementId);
550
- if (visualizer == null) {
551
- return ret;
651
+ registerExtension(extension) {
652
+ __classPrivateFieldGet(this, _ReactMemoryScan_extensions, "f").push(extension);
653
+ return () => this.unregisterExtension(extension);
552
654
  }
553
- const element = visualizer.elementInfo.element.deref();
554
- if (element == null) {
555
- return ret;
655
+ unregisterExtension(extension) {
656
+ __classPrivateFieldSet(this, _ReactMemoryScan_extensions, __classPrivateFieldGet(this, _ReactMemoryScan_extensions, "f").filter(e => e !== extension), "f");
556
657
  }
557
- // traverse parent elements
558
- let currentElement = element;
559
- while (currentElement) {
560
- if (currentElement.isConnected) {
561
- break;
658
+ start() {
659
+ if (__classPrivateFieldGet(this, _ReactMemoryScan_isDisposed, "f")) {
660
+ console.warn('[Memory] ReactMemoryScan has been disposed and cannot be started again');
661
+ return;
562
662
  }
563
- const elementId = currentElement.detachedElementId;
564
- const info = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get(elementId);
565
- if (info == null) {
566
- break;
663
+ __classPrivateFieldSet(this, _ReactMemoryScan_isActivated, true, "f");
664
+ __classPrivateFieldSet(this, _ReactMemoryScan_intervalId, setInterval(__classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_scanCycle).bind(this), __classPrivateFieldGet(this, _ReactMemoryScan_scanIntervalMs, "f")), "f");
665
+ if (config_1.config.features.enableMutationObserver) {
666
+ if (__classPrivateFieldGet(this, _ReactMemoryScan_domObserver, "f") == null) {
667
+ __classPrivateFieldSet(this, _ReactMemoryScan_domObserver, new dom_observer_1.DOMObserver(), "f");
668
+ // NOTE: do not update the fiber or component information here
669
+ // with this.#domObserver.register as those elements in the delta
670
+ // list may be unmounted or just attached and their shape and
671
+ // component info is not correct or not set yet
672
+ }
673
+ __classPrivateFieldGet(this, _ReactMemoryScan_domObserver, "f").startMonitoring();
567
674
  }
568
- ret.push(info);
569
- currentElement = currentElement.parentElement;
675
+ console.log('[Memory] Tracking React and DOM memory...');
570
676
  }
571
- return ret;
572
- }, _DOMElementVisualizerInteractive_traverseUpOutlineElements = function _DOMElementVisualizerInteractive_traverseUpOutlineElements(elementId, callback) {
573
- const visualizer = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get(elementId);
574
- if (visualizer == null) {
575
- return;
677
+ pause() {
678
+ __classPrivateFieldSet(this, _ReactMemoryScan_isActivated, false, "f");
576
679
  }
577
- const visitedElementIds = new Set();
578
- let currentElement = visualizer.elementInfo.element.deref();
579
- while (currentElement) {
580
- if (currentElement.isConnected) {
581
- break;
582
- }
583
- const elementIdStr = currentElement.detachedElementId;
584
- const elementId = parseInt(elementIdStr, 10);
585
- if (visitedElementIds.has(elementId)) {
586
- break;
587
- }
588
- visitedElementIds.add(elementId);
589
- const visualizerInfo = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get(elementId);
590
- if (visualizerInfo == null) {
591
- break;
680
+ stop() {
681
+ __classPrivateFieldSet(this, _ReactMemoryScan_isActivated, false, "f");
682
+ // Clear the interval
683
+ if (__classPrivateFieldGet(this, _ReactMemoryScan_intervalId, "f") !== null) {
684
+ clearInterval(__classPrivateFieldGet(this, _ReactMemoryScan_intervalId, "f"));
685
+ __classPrivateFieldSet(this, _ReactMemoryScan_intervalId, null, "f");
592
686
  }
593
- const visualizerElement = visualizerInfo.visualizerElementRef.deref();
594
- if (visualizerElement == null) {
595
- break;
687
+ // Clear element references to allow garbage collection
688
+ __classPrivateFieldSet(this, _ReactMemoryScan_elementWeakRefs, [], "f");
689
+ __classPrivateFieldSet(this, _ReactMemoryScan_knownFiberNodes, [], "f");
690
+ // Stop DOM observer
691
+ if (__classPrivateFieldGet(this, _ReactMemoryScan_domObserver, "f")) {
692
+ __classPrivateFieldGet(this, _ReactMemoryScan_domObserver, "f").stopMonitoring();
693
+ __classPrivateFieldSet(this, _ReactMemoryScan_domObserver, null, "f");
596
694
  }
597
- callback(visualizerElement);
598
- currentElement = currentElement.parentElement;
599
- }
600
- }, _DOMElementVisualizerInteractive_removeVisualizerElement = function _DOMElementVisualizerInteractive_removeVisualizerElement(elementId) {
601
- var _a;
602
- const visualizer = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get(elementId);
603
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").delete(elementId);
604
- if (visualizer == null) {
605
- return;
606
- }
607
- const visualizerElement = visualizer.visualizerElementRef.deref();
608
- if (visualizerElement == null) {
609
- return;
695
+ // Clear WeakMaps to allow garbage collection
696
+ __classPrivateFieldSet(this, _ReactMemoryScan_elementToBoundingRects, new WeakMap(), "f");
697
+ __classPrivateFieldSet(this, _ReactMemoryScan_elementToComponentStack, new WeakMap(), "f");
698
+ console.log('[Memory] ReactMemoryScan stopped');
610
699
  }
611
- // invoke the overlay specific code to clean
612
- (_a = visualizerElement === null || visualizerElement === void 0 ? void 0 : visualizerElement.__cleanup) === null || _a === void 0 ? void 0 : _a.call(visualizerElement);
613
- visualizerElement.remove();
614
- }, _DOMElementVisualizerInteractive_cleanup = function _DOMElementVisualizerInteractive_cleanup(domElementInfoList) {
615
- // first pass remove all those painted visualizer for elements
616
- // that either 1) is GCed or 2) is connected to the DOM tree
617
- for (const [elementId, elementVistualizer,] of __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").entries()) {
618
- if (elementId == null) {
619
- continue;
700
+ dispose() {
701
+ // Stop all monitoring
702
+ this.stop();
703
+ // Clear all subscribers
704
+ __classPrivateFieldSet(this, _ReactMemoryScan_subscribers, [], "f");
705
+ // Clean up all extensions
706
+ for (const extension of __classPrivateFieldGet(this, _ReactMemoryScan_extensions, "f")) {
707
+ if (extension && typeof extension.cleanup === 'function') {
708
+ extension.cleanup();
709
+ }
620
710
  }
621
- const element = elementVistualizer.elementInfo.element.deref();
622
- if (element == null) {
623
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_removeVisualizerElement).call(this, elementId);
711
+ __classPrivateFieldSet(this, _ReactMemoryScan_extensions, [], "f");
712
+ // Dispose event listener tracker if it exists
713
+ if (__classPrivateFieldGet(this, _ReactMemoryScan_eventListenerTracker, "f")) {
714
+ __classPrivateFieldGet(this, _ReactMemoryScan_eventListenerTracker, "f").destroy();
715
+ __classPrivateFieldSet(this, _ReactMemoryScan_eventListenerTracker, null, "f");
624
716
  }
717
+ // Mark as disposed to prevent reuse
718
+ __classPrivateFieldSet(this, _ReactMemoryScan_isDisposed, true, "f");
719
+ console.log('[Memory] ReactMemoryScan disposed');
625
720
  }
626
- // second pass remove all those outlines that won't be painted later
627
- const willPaintElementIdSet = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_getElementIdSet).call(this, domElementInfoList);
628
- for (const [elementId] of __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").entries()) {
629
- if (elementId == null) {
630
- continue;
631
- }
632
- if (willPaintElementIdSet.has(elementId) &&
633
- !__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_blockedElementIds, "f").has(elementId)) {
634
- continue;
721
+ recordBoundingRectangles(elementRefs) {
722
+ for (const elemRef of elementRefs) {
723
+ const element = elemRef.deref();
724
+ if (element == null || __classPrivateFieldGet(this, _ReactMemoryScan_elementToBoundingRects, "f").has(element)) {
725
+ continue;
726
+ }
727
+ const rect = utils.getBoundingClientRect(element);
728
+ if (rect != null) {
729
+ __classPrivateFieldGet(this, _ReactMemoryScan_elementToBoundingRects, "f").set(element, rect);
730
+ }
635
731
  }
636
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_removeVisualizerElement).call(this, elementId);
637
732
  }
638
- }, _DOMElementVisualizerInteractive_getZIndex = function _DOMElementVisualizerInteractive_getZIndex(info) {
639
- var _a;
640
- const zIndexBase = 9999;
641
- const element = info.element.deref();
642
- if (element == null) {
643
- return 0;
644
- }
645
- const elementId = element.detachedElementId;
646
- if (elementId == null) {
647
- return 0;
733
+ getDetachedDOMInfo() {
734
+ var _a;
735
+ const detachedDOMElements = [];
736
+ for (const weakRef of __classPrivateFieldGet(this, _ReactMemoryScan_elementWeakRefs, "f")) {
737
+ const element = weakRef.deref();
738
+ if (element == null || element.isConnected) {
739
+ continue;
740
+ }
741
+ // add a unique id to that detach dom element
742
+ const elem = element;
743
+ if (elem.detachedElementId == null) {
744
+ const elementId = ReactMemoryScan.nextElementId++;
745
+ elem.detachedElementIdStr = `memory-id-${elementId}@`;
746
+ elem.detachedElementId = elementId;
747
+ }
748
+ const componentStack = (_a = __classPrivateFieldGet(this, _ReactMemoryScan_elementToComponentStack, "f").get(element)) !== null && _a !== void 0 ? _a : [];
749
+ detachedDOMElements.push({
750
+ element: weakRef,
751
+ boundingRect: __classPrivateFieldGet(this, _ReactMemoryScan_elementToBoundingRects, "f").get(element),
752
+ componentStack,
753
+ });
754
+ }
755
+ return detachedDOMElements;
648
756
  }
649
- const rectangle = (_a = info.boundingRect) !== null && _a !== void 0 ? _a : { width: 50, height: 50 };
650
- let ret = zIndexBase;
651
- // element with a higher element id (created later) has a higher z-index
652
- ret += parseInt(elementId, 10);
653
- // element with bigger area will have a lower z-index
654
- ret += Math.floor(10000000 / (rectangle.width * rectangle.height));
655
- return ret;
656
- }, _DOMElementVisualizerInteractive_paint = function _DOMElementVisualizerInteractive_paint(domElementInfoList) {
657
- for (const info of domElementInfoList) {
658
- const element = info.element.deref();
757
+ isDevMode() {
758
+ return __classPrivateFieldGet(this, _ReactMemoryScan_isDevMode, "f");
759
+ }
760
+ getCachedComponentName(elementRef) {
761
+ var _a;
762
+ const FALLBACK_NAME = '<Unknown>';
763
+ const element = elementRef.deref();
659
764
  if (element == null) {
660
- continue;
661
- }
662
- const elementId = element.detachedElementId;
663
- if (elementId == null) {
664
- continue;
665
- }
666
- if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_blockedElementIds, "f").has(elementId)) {
667
- continue;
765
+ return FALLBACK_NAME;
668
766
  }
669
- if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").has(elementId)) {
670
- continue;
767
+ const componentStack = __classPrivateFieldGet(this, _ReactMemoryScan_elementToComponentStack, "f").get(element);
768
+ if (componentStack == null) {
769
+ return FALLBACK_NAME;
671
770
  }
672
- if (element == null) {
673
- continue;
771
+ return (_a = componentStack[0]) !== null && _a !== void 0 ? _a : FALLBACK_NAME;
772
+ }
773
+ updateFiberNodes(fiberNodes) {
774
+ const knownFiberSet = new WeakSet();
775
+ for (const fiberNode of __classPrivateFieldGet(this, _ReactMemoryScan_knownFiberNodes, "f")) {
776
+ const fiber = fiberNode.deref();
777
+ if (fiber != null) {
778
+ knownFiberSet.add(fiber);
779
+ }
674
780
  }
675
- if (element.isConnected) {
676
- continue;
781
+ const newFiberSet = new WeakSet();
782
+ for (const fiberNode of fiberNodes) {
783
+ const fiber = fiberNode.deref();
784
+ if (fiber != null) {
785
+ newFiberSet.add(fiber);
786
+ }
677
787
  }
678
- const zIndex = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_getZIndex).call(this, info);
679
- const visualizerElementRef = (0, overlay_rectangle_1.createOverlayRectangle)(elementId, info, __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f"), (selectedId) => {
680
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").selectedElementId = selectedId;
681
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_updateVisualizerData).call(this);
682
- if (selectedId == null) {
683
- return;
788
+ const leakedFibers = [];
789
+ const newExistingFibers = [];
790
+ // clean up and compact the existing fiber node lists
791
+ for (const fiberRef of __classPrivateFieldGet(this, _ReactMemoryScan_knownFiberNodes, "f")) {
792
+ const fiber = fiberRef.deref();
793
+ if (fiber == null) {
794
+ continue;
684
795
  }
685
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_traverseUpOutlineElements).call(this, selectedId, element => {
686
- var _a;
687
- (_a = element === null || element === void 0 ? void 0 : element.__selected) === null || _a === void 0 ? void 0 : _a.call(element);
688
- });
689
- }, (unselectedId) => {
690
- if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").selectedElementId === unselectedId) {
691
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").selectedElementId = null;
692
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_updateVisualizerData).call(this);
796
+ if (!newFiberSet.has(fiber)) {
797
+ leakedFibers.push(fiberRef);
693
798
  }
694
- if (unselectedId == null) {
695
- return;
799
+ else {
800
+ newExistingFibers.push(fiberRef);
801
+ if (fiber.return == null) {
802
+ leakedFibers.push(fiberRef);
803
+ }
696
804
  }
697
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_traverseUpOutlineElements).call(this, unselectedId, element => {
698
- var _a;
699
- (_a = element === null || element === void 0 ? void 0 : element.__unselected) === null || _a === void 0 ? void 0 : _a.call(element);
700
- });
701
- }, (clickedId) => {
702
- if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").pinnedElementId === clickedId) {
703
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").setPinnedElementId(null);
805
+ }
806
+ // add new fibers to the existing list
807
+ for (const fiberRef of fiberNodes) {
808
+ const fiber = fiberRef.deref();
809
+ if (fiber == null) {
810
+ continue;
704
811
  }
705
- else {
706
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").setPinnedElementId(clickedId);
812
+ if (!knownFiberSet.has(fiber)) {
813
+ newExistingFibers.push(fiberRef);
707
814
  }
708
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_updateVisualizerData).call(this);
709
- }, zIndex);
710
- if (visualizerElementRef == null ||
711
- visualizerElementRef.deref() == null) {
712
- return null;
713
815
  }
714
- const visualizer = {
715
- elementInfo: info,
716
- visualizerElementRef,
717
- };
718
- __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").set(elementId, visualizer);
816
+ __classPrivateFieldSet(this, _ReactMemoryScan_knownFiberNodes, newExistingFibers, "f");
817
+ __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_log).call(this, 'known fibers: ', __classPrivateFieldGet(this, _ReactMemoryScan_knownFiberNodes, "f").length);
818
+ __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_log).call(this, 'leaked fibers: ', leakedFibers.length);
819
+ return leakedFibers;
719
820
  }
720
- }, _DOMElementVisualizerInteractive_updateVisualizerData = function _DOMElementVisualizerInteractive_updateVisualizerData() {
721
- var _a, _b, _c;
722
- const data = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f");
723
- if (data.pinnedElementId != null) {
724
- data.selectedElementId = data.pinnedElementId;
821
+ packLeakedFibers(leakedFibers) {
822
+ const ret = [];
823
+ for (const leakedFiber of leakedFibers) {
824
+ ret.push(new LeakedFiber(leakedFiber));
825
+ }
826
+ return ret;
725
827
  }
726
- data.detachedDOMElementsCount = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").size;
727
- data.totalDOMElementsCount = (0, utils_1.getDOMElementCount)();
728
- const selectedElementInfo = (_b = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get((_a = data.selectedElementId) !== null && _a !== void 0 ? _a : -1)) === null || _b === void 0 ? void 0 : _b.elementInfo;
729
- data.selectedReactComponentStack =
730
- (_c = selectedElementInfo === null || selectedElementInfo === void 0 ? void 0 : selectedElementInfo.componentStack) !== null && _c !== void 0 ? _c : [];
731
- for (const cb of __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_updateDataCallbacks, "f")) {
732
- cb(Object.assign({}, __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f")));
828
+ scan() {
829
+ const start = Date.now();
830
+ __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_runGC).call(this);
831
+ const weakRefList = __classPrivateFieldGet(this, _ReactMemoryScan_elementWeakRefs, "f");
832
+ // TODO: associate elements with URL and other metadata
833
+ const allElements = __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_getTrackedDOMRefs).call(this);
834
+ __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_updateElementToComponentInfo).call(this, allElements);
835
+ this.recordBoundingRectangles(allElements);
836
+ utils.updateWeakRefList(weakRefList, allElements);
837
+ const scanResult = __classPrivateFieldGet(this, _ReactMemoryScan_fiberAnalyzer, "f").scan(weakRefList, __classPrivateFieldGet(this, _ReactMemoryScan_elementToComponentStack, "f"));
838
+ const leakedFibers = this.updateFiberNodes(scanResult.fiberNodes);
839
+ scanResult.leakedFibers = leakedFibers;
840
+ // scan for event listener leaks
841
+ // TODO: show the results in the UI widget
842
+ scanResult.eventListenerLeaks = __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_scanEventListenerLeaks).call(this);
843
+ window.leakedFibers = this.packLeakedFibers(leakedFibers);
844
+ const end = Date.now();
845
+ __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_log).call(this, `scan took ${end - start}ms`);
846
+ return scanResult;
733
847
  }
734
- };
735
- exports["default"] = DOMElementVisualizerInteractive;
736
-
737
-
738
- /***/ },
739
-
740
- /***/ 282
741
- (__unused_webpack_module, exports, __webpack_require__) {
742
-
743
-
744
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
745
- if (k2 === undefined) k2 = k;
746
- var desc = Object.getOwnPropertyDescriptor(m, k);
747
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
748
- desc = { enumerable: true, get: function() { return m[k]; } };
749
- }
750
- Object.defineProperty(o, k2, desc);
751
- }) : (function(o, m, k, k2) {
752
- if (k2 === undefined) k2 = k;
753
- o[k2] = m[k];
754
- }));
755
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
756
- Object.defineProperty(o, "default", { enumerable: true, value: v });
757
- }) : function(o, v) {
758
- o["default"] = v;
759
- });
760
- var __importStar = (this && this.__importStar) || (function () {
761
- var ownKeys = function(o) {
762
- ownKeys = Object.getOwnPropertyNames || function (o) {
763
- var ar = [];
764
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
765
- return ar;
766
- };
767
- return ownKeys(o);
768
- };
769
- return function (mod) {
770
- if (mod && mod.__esModule) return mod;
771
- var result = {};
772
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
773
- __setModuleDefault(result, mod);
774
- return result;
775
- };
776
- })();
777
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
778
- if (kind === "m") throw new TypeError("Private method is not writable");
779
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
780
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
781
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
782
- };
783
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
784
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
785
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
786
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
787
- };
788
- var __rest = (this && this.__rest) || function (s, e) {
789
- var t = {};
790
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
791
- t[p] = s[p];
792
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
793
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
794
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
795
- t[p[i]] = s[p[i]];
796
- }
797
- return t;
798
- };
799
- var __importDefault = (this && this.__importDefault) || function (mod) {
800
- return (mod && mod.__esModule) ? mod : { "default": mod };
801
- };
802
- var _ReactMemoryScan_instances, _ReactMemoryScan_elementWeakRefs, _ReactMemoryScan_isActivated, _ReactMemoryScan_intervalId, _ReactMemoryScan_elementToBoundingRects, _ReactMemoryScan_elementToComponentStack, _ReactMemoryScan_knownFiberNodes, _ReactMemoryScan_fiberAnalyzer, _ReactMemoryScan_isDevMode, _ReactMemoryScan_subscribers, _ReactMemoryScan_extensions, _ReactMemoryScan_scanIntervalMs, _ReactMemoryScan_domObserver, _ReactMemoryScan_eventListenerTracker, _ReactMemoryScan_isDisposed, _ReactMemoryScan_log, _ReactMemoryScan_notifySubscribers, _ReactMemoryScan_notifyExtensionsBeforeScan, _ReactMemoryScan_notifyExtensionsAfterScan, _ReactMemoryScan_scanCycle, _ReactMemoryScan_updateElementToComponentInfo, _ReactMemoryScan_getTrackedDOMRefs, _ReactMemoryScan_runGC, _ReactMemoryScan_scanEventListenerLeaks;
803
- Object.defineProperty(exports, "__esModule", ({ value: true }));
804
- const utils = __importStar(__webpack_require__(476));
805
- const react_fiber_analysis_1 = __importDefault(__webpack_require__(302));
806
- const react_fiber_utils_1 = __webpack_require__(737);
807
- const dom_observer_1 = __webpack_require__(54);
808
- const config_1 = __webpack_require__(346);
809
- const event_listener_tracker_1 = __webpack_require__(953);
810
- class ReactMemoryScan {
811
- constructor(options = {}) {
812
- var _a, _b, _c, _d;
813
- _ReactMemoryScan_instances.add(this);
814
- _ReactMemoryScan_elementWeakRefs.set(this, void 0);
815
- _ReactMemoryScan_isActivated.set(this, void 0);
816
- _ReactMemoryScan_intervalId.set(this, void 0);
817
- _ReactMemoryScan_elementToBoundingRects.set(this, void 0);
818
- _ReactMemoryScan_elementToComponentStack.set(this, void 0);
819
- _ReactMemoryScan_knownFiberNodes.set(this, void 0);
820
- _ReactMemoryScan_fiberAnalyzer.set(this, void 0);
821
- _ReactMemoryScan_isDevMode.set(this, void 0);
822
- _ReactMemoryScan_subscribers.set(this, void 0);
823
- _ReactMemoryScan_extensions.set(this, void 0);
824
- _ReactMemoryScan_scanIntervalMs.set(this, void 0);
825
- _ReactMemoryScan_domObserver.set(this, void 0);
826
- _ReactMemoryScan_eventListenerTracker.set(this, void 0);
827
- _ReactMemoryScan_isDisposed.set(this, void 0);
828
- __classPrivateFieldSet(this, _ReactMemoryScan_elementWeakRefs, [], "f");
829
- __classPrivateFieldSet(this, _ReactMemoryScan_isActivated, false, "f");
830
- __classPrivateFieldSet(this, _ReactMemoryScan_elementToBoundingRects, new WeakMap(), "f");
831
- __classPrivateFieldSet(this, _ReactMemoryScan_elementToComponentStack, new WeakMap(), "f");
832
- __classPrivateFieldSet(this, _ReactMemoryScan_knownFiberNodes, [], "f");
833
- __classPrivateFieldSet(this, _ReactMemoryScan_eventListenerTracker, options.trackEventListenerLeaks
834
- ? event_listener_tracker_1.EventListenerTracker.getInstance()
835
- : null, "f");
836
- __classPrivateFieldSet(this, _ReactMemoryScan_intervalId, null, "f");
837
- __classPrivateFieldSet(this, _ReactMemoryScan_isDisposed, false, "f");
838
- __classPrivateFieldSet(this, _ReactMemoryScan_fiberAnalyzer, new react_fiber_analysis_1.default(), "f");
839
- __classPrivateFieldSet(this, _ReactMemoryScan_isDevMode, (_a = options.isDevMode) !== null && _a !== void 0 ? _a : false, "f");
840
- __classPrivateFieldSet(this, _ReactMemoryScan_subscribers, (_b = options.subscribers) !== null && _b !== void 0 ? _b : [], "f");
841
- __classPrivateFieldSet(this, _ReactMemoryScan_extensions, (_c = options.extensions) !== null && _c !== void 0 ? _c : [], "f");
842
- __classPrivateFieldSet(this, _ReactMemoryScan_scanIntervalMs, (_d = options.scanIntervalMs) !== null && _d !== void 0 ? _d : config_1.config.performance.scanIntervalMs, "f");
843
- }
844
- subscribe(callback) {
845
- __classPrivateFieldGet(this, _ReactMemoryScan_subscribers, "f").push(callback);
846
- return () => this.unsubscribe(callback);
847
- }
848
- unsubscribe(callback) {
849
- __classPrivateFieldSet(this, _ReactMemoryScan_subscribers, __classPrivateFieldGet(this, _ReactMemoryScan_subscribers, "f").filter(cb => cb !== callback), "f");
850
- }
851
- registerExtension(extension) {
852
- __classPrivateFieldGet(this, _ReactMemoryScan_extensions, "f").push(extension);
853
- return () => this.unregisterExtension(extension);
854
- }
855
- unregisterExtension(extension) {
856
- __classPrivateFieldSet(this, _ReactMemoryScan_extensions, __classPrivateFieldGet(this, _ReactMemoryScan_extensions, "f").filter(e => e !== extension), "f");
857
- }
858
- start() {
859
- if (__classPrivateFieldGet(this, _ReactMemoryScan_isDisposed, "f")) {
860
- console.warn('[Memory] ReactMemoryScan has been disposed and cannot be started again');
861
- return;
862
- }
863
- __classPrivateFieldSet(this, _ReactMemoryScan_isActivated, true, "f");
864
- __classPrivateFieldSet(this, _ReactMemoryScan_intervalId, setInterval(__classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_scanCycle).bind(this), __classPrivateFieldGet(this, _ReactMemoryScan_scanIntervalMs, "f")), "f");
865
- if (config_1.config.features.enableMutationObserver) {
866
- if (__classPrivateFieldGet(this, _ReactMemoryScan_domObserver, "f") == null) {
867
- __classPrivateFieldSet(this, _ReactMemoryScan_domObserver, new dom_observer_1.DOMObserver(), "f");
868
- // NOTE: do not update the fiber or component information here
869
- // with this.#domObserver.register as those elements in the delta
870
- // list may be unmounted or just attached and their shape and
871
- // component info is not correct or not set yet
872
- }
873
- __classPrivateFieldGet(this, _ReactMemoryScan_domObserver, "f").startMonitoring();
874
- }
875
- console.log('[Memory] Tracking React and DOM memory...');
876
- }
877
- pause() {
878
- __classPrivateFieldSet(this, _ReactMemoryScan_isActivated, false, "f");
879
- }
880
- stop() {
881
- __classPrivateFieldSet(this, _ReactMemoryScan_isActivated, false, "f");
882
- // Clear the interval
883
- if (__classPrivateFieldGet(this, _ReactMemoryScan_intervalId, "f") !== null) {
884
- clearInterval(__classPrivateFieldGet(this, _ReactMemoryScan_intervalId, "f"));
885
- __classPrivateFieldSet(this, _ReactMemoryScan_intervalId, null, "f");
886
- }
887
- // Clear element references to allow garbage collection
888
- __classPrivateFieldSet(this, _ReactMemoryScan_elementWeakRefs, [], "f");
889
- __classPrivateFieldSet(this, _ReactMemoryScan_knownFiberNodes, [], "f");
890
- // Stop DOM observer
891
- if (__classPrivateFieldGet(this, _ReactMemoryScan_domObserver, "f")) {
892
- __classPrivateFieldGet(this, _ReactMemoryScan_domObserver, "f").stopMonitoring();
893
- __classPrivateFieldSet(this, _ReactMemoryScan_domObserver, null, "f");
894
- }
895
- // Clear WeakMaps to allow garbage collection
896
- __classPrivateFieldSet(this, _ReactMemoryScan_elementToBoundingRects, new WeakMap(), "f");
897
- __classPrivateFieldSet(this, _ReactMemoryScan_elementToComponentStack, new WeakMap(), "f");
898
- console.log('[Memory] ReactMemoryScan stopped');
899
- }
900
- dispose() {
901
- // Stop all monitoring
902
- this.stop();
903
- // Clear all subscribers
904
- __classPrivateFieldSet(this, _ReactMemoryScan_subscribers, [], "f");
905
- // Clean up all extensions
906
- for (const extension of __classPrivateFieldGet(this, _ReactMemoryScan_extensions, "f")) {
907
- if (extension && typeof extension.cleanup === 'function') {
908
- extension.cleanup();
909
- }
910
- }
911
- __classPrivateFieldSet(this, _ReactMemoryScan_extensions, [], "f");
912
- // Dispose event listener tracker if it exists
913
- if (__classPrivateFieldGet(this, _ReactMemoryScan_eventListenerTracker, "f")) {
914
- __classPrivateFieldGet(this, _ReactMemoryScan_eventListenerTracker, "f").destroy();
915
- __classPrivateFieldSet(this, _ReactMemoryScan_eventListenerTracker, null, "f");
916
- }
917
- // Mark as disposed to prevent reuse
918
- __classPrivateFieldSet(this, _ReactMemoryScan_isDisposed, true, "f");
919
- console.log('[Memory] ReactMemoryScan disposed');
920
- }
921
- recordBoundingRectangles(elementRefs) {
922
- for (const elemRef of elementRefs) {
923
- const element = elemRef.deref();
924
- if (element == null || __classPrivateFieldGet(this, _ReactMemoryScan_elementToBoundingRects, "f").has(element)) {
925
- continue;
926
- }
927
- const rect = utils.getBoundingClientRect(element);
928
- if (rect != null) {
929
- __classPrivateFieldGet(this, _ReactMemoryScan_elementToBoundingRects, "f").set(element, rect);
930
- }
931
- }
932
- }
933
- getDetachedDOMInfo() {
934
- var _a;
935
- const detachedDOMElements = [];
936
- for (const weakRef of __classPrivateFieldGet(this, _ReactMemoryScan_elementWeakRefs, "f")) {
937
- const element = weakRef.deref();
938
- if (element == null || element.isConnected) {
939
- continue;
940
- }
941
- // add a unique id to that detach dom element
942
- const elem = element;
943
- if (elem.detachedElementId == null) {
944
- const elementId = ReactMemoryScan.nextElementId++;
945
- elem.detachedElementIdStr = `memory-id-${elementId}@`;
946
- elem.detachedElementId = elementId;
947
- }
948
- const componentStack = (_a = __classPrivateFieldGet(this, _ReactMemoryScan_elementToComponentStack, "f").get(element)) !== null && _a !== void 0 ? _a : [];
949
- detachedDOMElements.push({
950
- element: weakRef,
951
- boundingRect: __classPrivateFieldGet(this, _ReactMemoryScan_elementToBoundingRects, "f").get(element),
952
- componentStack,
953
- });
954
- }
955
- return detachedDOMElements;
956
- }
957
- isDevMode() {
958
- return __classPrivateFieldGet(this, _ReactMemoryScan_isDevMode, "f");
959
- }
960
- getCachedComponentName(elementRef) {
961
- var _a;
962
- const FALLBACK_NAME = '<Unknown>';
963
- const element = elementRef.deref();
964
- if (element == null) {
965
- return FALLBACK_NAME;
966
- }
967
- const componentStack = __classPrivateFieldGet(this, _ReactMemoryScan_elementToComponentStack, "f").get(element);
968
- if (componentStack == null) {
969
- return FALLBACK_NAME;
970
- }
971
- return (_a = componentStack[0]) !== null && _a !== void 0 ? _a : FALLBACK_NAME;
972
- }
973
- updateFiberNodes(fiberNodes) {
974
- const knownFiberSet = new WeakSet();
975
- for (const fiberNode of __classPrivateFieldGet(this, _ReactMemoryScan_knownFiberNodes, "f")) {
976
- const fiber = fiberNode.deref();
977
- if (fiber != null) {
978
- knownFiberSet.add(fiber);
979
- }
980
- }
981
- const newFiberSet = new WeakSet();
982
- for (const fiberNode of fiberNodes) {
983
- const fiber = fiberNode.deref();
984
- if (fiber != null) {
985
- newFiberSet.add(fiber);
986
- }
987
- }
988
- const leakedFibers = [];
989
- const newExistingFibers = [];
990
- // clean up and compact the existing fiber node lists
991
- for (const fiberRef of __classPrivateFieldGet(this, _ReactMemoryScan_knownFiberNodes, "f")) {
992
- const fiber = fiberRef.deref();
993
- if (fiber == null) {
994
- continue;
995
- }
996
- if (!newFiberSet.has(fiber)) {
997
- leakedFibers.push(fiberRef);
998
- }
999
- else {
1000
- newExistingFibers.push(fiberRef);
1001
- if (fiber.return == null) {
1002
- leakedFibers.push(fiberRef);
1003
- }
1004
- }
1005
- }
1006
- // add new fibers to the existing list
1007
- for (const fiberRef of fiberNodes) {
1008
- const fiber = fiberRef.deref();
1009
- if (fiber == null) {
1010
- continue;
1011
- }
1012
- if (!knownFiberSet.has(fiber)) {
1013
- newExistingFibers.push(fiberRef);
1014
- }
1015
- }
1016
- __classPrivateFieldSet(this, _ReactMemoryScan_knownFiberNodes, newExistingFibers, "f");
1017
- __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_log).call(this, 'known fibers: ', __classPrivateFieldGet(this, _ReactMemoryScan_knownFiberNodes, "f").length);
1018
- __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_log).call(this, 'leaked fibers: ', leakedFibers.length);
1019
- return leakedFibers;
1020
- }
1021
- packLeakedFibers(leakedFibers) {
1022
- const ret = [];
1023
- for (const leakedFiber of leakedFibers) {
1024
- ret.push(new LeakedFiber(leakedFiber));
1025
- }
1026
- return ret;
1027
- }
1028
- scan() {
1029
- const start = Date.now();
1030
- __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_runGC).call(this);
1031
- const weakRefList = __classPrivateFieldGet(this, _ReactMemoryScan_elementWeakRefs, "f");
1032
- // TODO: associate elements with URL and other metadata
1033
- const allElements = __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_getTrackedDOMRefs).call(this);
1034
- __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_updateElementToComponentInfo).call(this, allElements);
1035
- this.recordBoundingRectangles(allElements);
1036
- utils.updateWeakRefList(weakRefList, allElements);
1037
- const scanResult = __classPrivateFieldGet(this, _ReactMemoryScan_fiberAnalyzer, "f").scan(weakRefList, __classPrivateFieldGet(this, _ReactMemoryScan_elementToComponentStack, "f"));
1038
- const leakedFibers = this.updateFiberNodes(scanResult.fiberNodes);
1039
- scanResult.leakedFibers = leakedFibers;
1040
- // scan for event listener leaks
1041
- // TODO: show the results in the UI widget
1042
- scanResult.eventListenerLeaks = __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_scanEventListenerLeaks).call(this);
1043
- window.leakedFibers = this.packLeakedFibers(leakedFibers);
1044
- const end = Date.now();
1045
- __classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_log).call(this, `scan took ${end - start}ms`);
1046
- return scanResult;
1047
- }
1048
- }
1049
- _ReactMemoryScan_elementWeakRefs = new WeakMap(), _ReactMemoryScan_isActivated = new WeakMap(), _ReactMemoryScan_intervalId = new WeakMap(), _ReactMemoryScan_elementToBoundingRects = new WeakMap(), _ReactMemoryScan_elementToComponentStack = new WeakMap(), _ReactMemoryScan_knownFiberNodes = new WeakMap(), _ReactMemoryScan_fiberAnalyzer = new WeakMap(), _ReactMemoryScan_isDevMode = new WeakMap(), _ReactMemoryScan_subscribers = new WeakMap(), _ReactMemoryScan_extensions = new WeakMap(), _ReactMemoryScan_scanIntervalMs = new WeakMap(), _ReactMemoryScan_domObserver = new WeakMap(), _ReactMemoryScan_eventListenerTracker = new WeakMap(), _ReactMemoryScan_isDisposed = new WeakMap(), _ReactMemoryScan_instances = new WeakSet(), _ReactMemoryScan_log = function _ReactMemoryScan_log(...args) {
1050
- if (__classPrivateFieldGet(this, _ReactMemoryScan_isDevMode, "f") && config_1.config.features.enableConsoleLogs) {
1051
- utils.consoleLog(...args);
848
+ }
849
+ _ReactMemoryScan_elementWeakRefs = new WeakMap(), _ReactMemoryScan_isActivated = new WeakMap(), _ReactMemoryScan_intervalId = new WeakMap(), _ReactMemoryScan_elementToBoundingRects = new WeakMap(), _ReactMemoryScan_elementToComponentStack = new WeakMap(), _ReactMemoryScan_knownFiberNodes = new WeakMap(), _ReactMemoryScan_fiberAnalyzer = new WeakMap(), _ReactMemoryScan_isDevMode = new WeakMap(), _ReactMemoryScan_subscribers = new WeakMap(), _ReactMemoryScan_extensions = new WeakMap(), _ReactMemoryScan_scanIntervalMs = new WeakMap(), _ReactMemoryScan_domObserver = new WeakMap(), _ReactMemoryScan_eventListenerTracker = new WeakMap(), _ReactMemoryScan_isDisposed = new WeakMap(), _ReactMemoryScan_instances = new WeakSet(), _ReactMemoryScan_log = function _ReactMemoryScan_log(...args) {
850
+ if (__classPrivateFieldGet(this, _ReactMemoryScan_isDevMode, "f") && config_1.config.features.enableConsoleLogs) {
851
+ utils.consoleLog(...args);
1052
852
  }
1053
853
  }, _ReactMemoryScan_notifySubscribers = function _ReactMemoryScan_notifySubscribers(result) {
1054
854
  for (const subscriber of __classPrivateFieldGet(this, _ReactMemoryScan_subscribers, "f")) {
@@ -1136,44 +936,11 @@ class LeakedFiber {
1136
936
 
1137
937
  /***/ },
1138
938
 
1139
- /***/ 302
1140
- (__unused_webpack_module, exports, __webpack_require__) {
939
+ /***/ 847
940
+ (__unused_webpack_module, exports) {
1141
941
 
942
+ var __webpack_unused_export__;
1142
943
 
1143
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
1144
- if (k2 === undefined) k2 = k;
1145
- var desc = Object.getOwnPropertyDescriptor(m, k);
1146
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
1147
- desc = { enumerable: true, get: function() { return m[k]; } };
1148
- }
1149
- Object.defineProperty(o, k2, desc);
1150
- }) : (function(o, m, k, k2) {
1151
- if (k2 === undefined) k2 = k;
1152
- o[k2] = m[k];
1153
- }));
1154
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
1155
- Object.defineProperty(o, "default", { enumerable: true, value: v });
1156
- }) : function(o, v) {
1157
- o["default"] = v;
1158
- });
1159
- var __importStar = (this && this.__importStar) || (function () {
1160
- var ownKeys = function(o) {
1161
- ownKeys = Object.getOwnPropertyNames || function (o) {
1162
- var ar = [];
1163
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
1164
- return ar;
1165
- };
1166
- return ownKeys(o);
1167
- };
1168
- return function (mod) {
1169
- if (mod && mod.__esModule) return mod;
1170
- var result = {};
1171
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
1172
- __setModuleDefault(result, mod);
1173
- return result;
1174
- };
1175
- })();
1176
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1177
944
  /**
1178
945
  * Copyright (c) Meta Platforms, Inc. and affiliates.
1179
946
  *
@@ -1183,512 +950,401 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
1183
950
  * @format
1184
951
  * @oncall memory_lab
1185
952
  */
1186
- const utils = __importStar(__webpack_require__(476));
1187
- const react_fiber_utils_1 = __webpack_require__(737);
1188
- const valid_component_name_1 = __webpack_require__(847);
1189
- class ReactFiberAnalyzer {
1190
- scan(elementWeakRefList, elementToComponentStack) {
1191
- var _a;
1192
- const visitedRootFibers = new Set();
1193
- const components = new Set();
1194
- const componentToFiberNodeCount = new Map();
1195
- const detachedComponentToFiberNodeCount = new Map();
1196
- const topDownVisited = new Set();
1197
- const analyzedFibers = new Set();
1198
- const fiberNodes = [];
1199
- let totalElements = 0;
1200
- let totalDetachedElements = 0;
1201
- function analyzeFiber(fiberNode) {
1202
- (0, react_fiber_utils_1.traverseFiber)(fiberNode, (fiberNode) => {
1203
- // skip if the fiber node has already been analyzed
1204
- if (analyzedFibers.has(fiberNode)) {
1205
- return true;
1206
- }
1207
- analyzedFibers.add(fiberNode);
1208
- // traverse the fiber tree up to find the component name
1209
- const displayName = (0, react_fiber_utils_1.getDisplayNameOfFiberNode)(fiberNode);
1210
- if (displayName != null && (0, valid_component_name_1.isValidComponentName)(displayName)) {
1211
- components.add(displayName);
1212
- utils.addCountbyKey(componentToFiberNodeCount, displayName, 1);
1213
- return true;
1214
- }
1215
- }, true);
1216
- }
1217
- for (const weakRef of elementWeakRefList) {
1218
- const elem = weakRef.deref();
1219
- if (elem == null) {
1220
- continue;
1221
- }
1222
- // elements stats
1223
- ++totalElements;
1224
- // TODO: simplify this logic
1225
- if (!elem.isConnected) {
1226
- if (elementToComponentStack.has(elem)) {
1227
- const componentStack = (_a = elementToComponentStack.get(elem)) !== null && _a !== void 0 ? _a : [];
1228
- // set component name
1229
- const component = componentStack[0];
1230
- elem.__component_name = component;
1231
- utils.addCountbyKey(detachedComponentToFiberNodeCount, component, 1);
1232
- }
1233
- ++totalDetachedElements;
1234
- }
1235
- // analyze fiber nodes
1236
- const fiberNode = (0, react_fiber_utils_1.getFiberNodeFromElement)(elem);
1237
- if (fiberNode == null) {
1238
- continue;
1239
- }
1240
- analyzeFiber(fiberNode);
1241
- // try to traverse each fiber node in the entire fiber tree
1242
- const rootFiber = (0, react_fiber_utils_1.getTopMostFiberWithChild)(fiberNode);
1243
- if (rootFiber == null) {
1244
- continue;
1245
- }
1246
- if (visitedRootFibers.has(rootFiber)) {
1247
- continue;
1248
- }
1249
- visitedRootFibers.add(rootFiber);
1250
- // start traversing fiber tree from the know root host
1251
- (0, react_fiber_utils_1.traverseFiber)(rootFiber, (node) => {
1252
- if (topDownVisited.has(node)) {
1253
- return true;
1254
- }
1255
- topDownVisited.add(node);
1256
- fiberNodes.push(new WeakRef(node));
1257
- analyzeFiber(node);
1258
- }, false);
1259
- }
1260
- topDownVisited.clear();
1261
- analyzedFibers.clear();
1262
- visitedRootFibers.clear();
1263
- return {
1264
- components,
1265
- componentToFiberNodeCount,
1266
- totalElements,
1267
- totalDetachedElements,
1268
- detachedComponentToFiberNodeCount,
1269
- fiberNodes,
1270
- leakedFibers: [],
1271
- };
1272
- }
953
+ __webpack_unused_export__ = ({ value: true });
954
+ exports.isValidComponentName = isValidComponentName;
955
+ const displayNameBlockList = new Set();
956
+ function isValidComponentName(name) {
957
+ return name != null && !displayNameBlockList.has(name);
1273
958
  }
1274
- exports["default"] = ReactFiberAnalyzer;
1275
959
 
1276
960
 
1277
961
  /***/ },
1278
962
 
1279
- /***/ 313
963
+ /***/ 860
1280
964
  (__unused_webpack_module, exports) {
1281
965
 
966
+ var __webpack_unused_export__;
1282
967
 
968
+ __webpack_unused_export__ = ({ value: true });
969
+ exports.BasicExtension = void 0;
1283
970
  /**
1284
- * Copyright (c) Meta Platforms, Inc. and affiliates.
1285
- *
1286
- * This source code is licensed under the MIT license found in the
1287
- * LICENSE file in the root directory of this source tree.
1288
- *
1289
- * @format
1290
- * @oncall memory_lab
971
+ * Base class for React Memory Scanner extensions.
972
+ * Extensions can hook into the scanning process before and after analysis.
1291
973
  */
1292
- var _a, _b, _c;
1293
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1294
- exports.WeakMapPlus = exports.WeakMapNoOp = exports.WeakSetNoOp = exports.WeakRefNoOp = void 0;
1295
- exports.getNativeWeakMap = getNativeWeakMap;
1296
- exports.getNativeWeakMapOrFallback = getNativeWeakMapOrFallback;
1297
- exports.getNativeWeakSet = getNativeWeakSet;
1298
- exports.getNativeWeakSetOrFallback = getNativeWeakSetOrFallback;
1299
- exports.getNativeWeakRef = getNativeWeakRef;
1300
- exports.getNativeWeakRefOrFallback = getNativeWeakRefOrFallback;
1301
- exports.isWeakMapNative = isWeakMapNative;
1302
- exports.isWeakSetNative = isWeakSetNative;
1303
- exports.isWeakRefNative = isWeakRefNative;
1304
- exports.isWeakAPINative = isWeakAPINative;
1305
- const globalScope = typeof window !== 'undefined' ? window : self;
1306
- const _weakMap = (_a = globalScope.WeakMap) !== null && _a !== void 0 ? _a : null;
1307
- const _weakMapIsNative = isWeakMapNative();
1308
- const _weakSet = (_b = globalScope.WeakSet) !== null && _b !== void 0 ? _b : null;
1309
- const _weakSetIsNative = isWeakSetNative();
1310
- const _weakRef = (_c = globalScope.WeakRef) !== null && _c !== void 0 ? _c : null;
1311
- const _weakRefIsNative = isWeakRefNative();
1312
- const _weakAPIsAreNative = _weakMapIsNative && _weakSetIsNative && _weakRefIsNative;
1313
- class WeakRefNoOp {
1314
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1315
- constructor(_targetObject) {
1316
- // to be overridden
1317
- }
1318
- deref() {
1319
- return undefined;
974
+ class BasicExtension {
975
+ constructor(scanner) {
976
+ this.scanner = scanner;
1320
977
  }
1321
- }
1322
- exports.WeakRefNoOp = WeakRefNoOp;
1323
- class WeakSetNoOp {
1324
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1325
- constructor(_iterable) {
978
+ /**
979
+ * Hook that runs before the memory scan starts.
980
+ * Override this method to perform any setup or pre-scan operations.
981
+ */
982
+ beforeScan() {
1326
983
  // to be overridden
1327
984
  }
985
+ /**
986
+ * Hook that runs after the memory scan completes.
987
+ * Override this method to process or modify the analysis results.
988
+ * @param analysisResult - The results from the memory scan
989
+ */
1328
990
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
1329
- add(_value) {
1330
- return this;
1331
- }
1332
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1333
- delete(_value) {
1334
- return false;
1335
- }
1336
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1337
- has(_value) {
1338
- return false;
1339
- }
1340
- }
1341
- exports.WeakSetNoOp = WeakSetNoOp;
1342
- class WeakMapNoOp {
1343
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1344
- constructor(_iterable) {
991
+ afterScan(_analysisResult) {
1345
992
  // to be overridden
1346
993
  }
1347
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1348
- delete(_key) {
1349
- return false;
1350
- }
1351
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1352
- get(_key) {
1353
- return undefined;
994
+ }
995
+ exports.BasicExtension = BasicExtension;
996
+
997
+
998
+ /***/ },
999
+
1000
+ /***/ 23
1001
+ (__unused_webpack_module, exports, __webpack_require__) {
1002
+
1003
+
1004
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
1005
+ if (kind === "m") throw new TypeError("Private method is not writable");
1006
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
1007
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
1008
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
1009
+ };
1010
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
1011
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
1012
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
1013
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
1014
+ };
1015
+ var __importDefault = (this && this.__importDefault) || function (mod) {
1016
+ return (mod && mod.__esModule) ? mod : { "default": mod };
1017
+ };
1018
+ var _DOMVisualizationExtension_domVirtualizer;
1019
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1020
+ exports.DOMVisualizationExtension = void 0;
1021
+ const dom_element_visualizer_1 = __importDefault(__webpack_require__(150));
1022
+ const dom_element_visualizer_interactive_1 = __importDefault(__webpack_require__(271));
1023
+ const basic_extension_1 = __webpack_require__(860);
1024
+ const USE_INTERACTIVE_VISUALIZER = true;
1025
+ class DOMVisualizationExtension extends basic_extension_1.BasicExtension {
1026
+ constructor(scanner) {
1027
+ super(scanner);
1028
+ _DOMVisualizationExtension_domVirtualizer.set(this, void 0);
1029
+ if (USE_INTERACTIVE_VISUALIZER) {
1030
+ __classPrivateFieldSet(this, _DOMVisualizationExtension_domVirtualizer, new dom_element_visualizer_interactive_1.default(), "f");
1031
+ }
1032
+ else {
1033
+ __classPrivateFieldSet(this, _DOMVisualizationExtension_domVirtualizer, new dom_element_visualizer_1.default(), "f");
1034
+ }
1354
1035
  }
1355
1036
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
1356
- has(_key) {
1357
- return false;
1037
+ afterScan(_analysisResult) {
1038
+ var _a;
1039
+ // const start = Date.now();
1040
+ const scanner = this.scanner;
1041
+ if (scanner.isDevMode()) {
1042
+ const detachedDOMInfo = scanner.getDetachedDOMInfo();
1043
+ (_a = __classPrivateFieldGet(this, _DOMVisualizationExtension_domVirtualizer, "f")) === null || _a === void 0 ? void 0 : _a.repaint(detachedDOMInfo);
1044
+ }
1045
+ // const end = Date.now();
1046
+ // console.log(`repaint took ${end - start}ms`);
1358
1047
  }
1359
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1360
- set(_key, _value) {
1361
- return this;
1048
+ cleanup() {
1049
+ // Clean up the visualizer to prevent memory leaks
1050
+ if (__classPrivateFieldGet(this, _DOMVisualizationExtension_domVirtualizer, "f") &&
1051
+ typeof __classPrivateFieldGet(this, _DOMVisualizationExtension_domVirtualizer, "f").cleanup === 'function') {
1052
+ __classPrivateFieldGet(this, _DOMVisualizationExtension_domVirtualizer, "f").cleanup();
1053
+ }
1054
+ // Clear the reference
1055
+ __classPrivateFieldSet(this, _DOMVisualizationExtension_domVirtualizer, null, "f");
1362
1056
  }
1363
1057
  }
1364
- exports.WeakMapNoOp = WeakMapNoOp;
1365
- function getNativeWeakMap() {
1366
- return _weakMapIsNative ? _weakMap : null;
1367
- }
1368
- function getNativeWeakMapOrFallback() {
1369
- return _weakMapIsNative && _weakMap ? _weakMap : WeakMapNoOp;
1370
- }
1371
- function getNativeWeakSet() {
1372
- return _weakSetIsNative ? _weakSet : null;
1373
- }
1374
- function getNativeWeakSetOrFallback() {
1375
- return _weakSetIsNative && _weakSet ? _weakSet : WeakSetNoOp;
1376
- }
1377
- function getNativeWeakRef() {
1378
- return _weakRefIsNative ? _weakRef : null;
1379
- }
1380
- function getNativeWeakRefOrFallback() {
1381
- return _weakRefIsNative && _weakRef ? _weakRef : WeakRefNoOp;
1382
- }
1383
- function normalize(input) {
1384
- return typeof input.replace === 'function'
1385
- ? input.replace(/\n/g, ' ').replace(/\s+/g, ' ')
1386
- : null;
1387
- }
1388
- function isWeakMapNative() {
1389
- return (_weakMap !== null &&
1390
- typeof _weakMap.toString === 'function' &&
1391
- normalize(_weakMap.toString()) === 'function WeakMap() { [native code] }');
1392
- }
1393
- function isWeakSetNative() {
1394
- return (_weakSet !== null &&
1395
- typeof _weakSet.toString === 'function' &&
1396
- normalize(_weakSet.toString()) === 'function WeakSet() { [native code] }');
1397
- }
1398
- function isWeakRefNative() {
1399
- return (_weakRef !== null &&
1400
- typeof _weakRef.toString === 'function' &&
1401
- normalize(_weakRef.toString()) === 'function WeakRef() { [native code] }');
1402
- }
1403
- function isWeakAPINative() {
1404
- return _weakAPIsAreNative;
1058
+ exports.DOMVisualizationExtension = DOMVisualizationExtension;
1059
+ _DOMVisualizationExtension_domVirtualizer = new WeakMap();
1060
+
1061
+
1062
+ /***/ },
1063
+
1064
+ /***/ 933
1065
+ (__unused_webpack_module, exports, __webpack_require__) {
1066
+
1067
+
1068
+ var __importDefault = (this && this.__importDefault) || function (mod) {
1069
+ return (mod && mod.__esModule) ? mod : { "default": mod };
1070
+ };
1071
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
1072
+ /**
1073
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
1074
+ *
1075
+ * This source code is licensed under the MIT license found in the
1076
+ * LICENSE file in the root directory of this source tree.
1077
+ *
1078
+ * @format
1079
+ * @oncall memory_lab
1080
+ */
1081
+ const react_memory_scan_1 = __importDefault(__webpack_require__(282));
1082
+ const dom_visualization_extension_1 = __webpack_require__(23);
1083
+ const utils_1 = __webpack_require__(476);
1084
+ if (!(0, utils_1.hasRunInSession)()) {
1085
+ const memoryScan = new react_memory_scan_1.default({ isDevMode: true });
1086
+ const domVisualizer = new dom_visualization_extension_1.DOMVisualizationExtension(memoryScan);
1087
+ memoryScan.registerExtension(domVisualizer);
1088
+ memoryScan.start();
1089
+ (0, utils_1.setRunInSession)();
1405
1090
  }
1406
- class WeakMapPlus {
1407
- constructor(options = {}) {
1408
- this.strongMap = null;
1409
- this.noopMap = false;
1410
- this.entriesMap = new Map();
1411
- this.keyToId = new WeakMap();
1412
- const { fallback = 'strong', cleanupMs = 1000 } = options;
1413
- this.isWeak = _weakAPIsAreNative;
1414
- this.fallbackMode = fallback;
1415
- if (!this.isWeak) {
1416
- if (fallback === 'strong') {
1417
- this.strongMap = new Map();
1418
- }
1419
- else if (fallback === 'noop') {
1420
- this.noopMap = true;
1421
- }
1422
- this.cleanupInterval = -1;
1423
- }
1424
- else {
1425
- this.cleanupInterval = setInterval(() => this.cleanup(), cleanupMs);
1426
- }
1427
- }
1428
- getOrCreateId(key) {
1429
- let id = this.keyToId.get(key);
1430
- if (!id) {
1431
- id = Symbol();
1432
- this.keyToId.set(key, id);
1433
- }
1434
- return id;
1435
- }
1436
- set(key, value) {
1437
- var _a;
1438
- if (!this.isWeak) {
1439
- if (this.noopMap)
1440
- return this;
1441
- (_a = this.strongMap) === null || _a === void 0 ? void 0 : _a.set(key, value);
1442
- return this;
1443
- }
1444
- const id = this.getOrCreateId(key);
1445
- this.entriesMap.set(id, { ref: new WeakRef(key), value });
1446
- return this;
1447
- }
1448
- get(key) {
1449
- var _a, _b;
1450
- if (!this.isWeak) {
1451
- if (this.noopMap)
1452
- return undefined;
1453
- return (_a = this.strongMap) === null || _a === void 0 ? void 0 : _a.get(key);
1454
- }
1455
- const id = this.keyToId.get(key);
1456
- if (!id)
1457
- return undefined;
1458
- const entry = this.entriesMap.get(id);
1459
- const derefKey = (_b = entry === null || entry === void 0 ? void 0 : entry.ref) === null || _b === void 0 ? void 0 : _b.deref();
1460
- return derefKey ? entry === null || entry === void 0 ? void 0 : entry.value : undefined;
1461
- }
1462
- has(key) {
1463
- var _a, _b;
1464
- if (!this.isWeak) {
1465
- if (this.noopMap)
1466
- return false;
1467
- return (_b = (_a = this.strongMap) === null || _a === void 0 ? void 0 : _a.has(key)) !== null && _b !== void 0 ? _b : false;
1468
- }
1469
- const id = this.keyToId.get(key);
1470
- if (!id)
1471
- return false;
1472
- const entry = this.entriesMap.get(id);
1473
- return !!(entry && entry.ref.deref());
1474
- }
1475
- delete(key) {
1476
- var _a, _b;
1477
- if (!this.isWeak) {
1478
- if (this.noopMap)
1479
- return false;
1480
- return (_b = (_a = this.strongMap) === null || _a === void 0 ? void 0 : _a.delete(key)) !== null && _b !== void 0 ? _b : false;
1481
- }
1482
- const id = this.keyToId.get(key);
1483
- if (!id)
1484
- return false;
1485
- this.keyToId.delete(key);
1486
- return this.entriesMap.delete(id);
1487
- }
1488
- *liveEntries() {
1489
- for (const [, entry] of this.entriesMap) {
1490
- const key = entry.ref.deref();
1491
- if (key) {
1492
- yield [key, entry.value];
1493
- }
1494
- }
1495
- }
1496
- entries() {
1497
- var _a, _b;
1498
- if (!this.isWeak) {
1499
- if (this.noopMap)
1500
- return [][Symbol.iterator]();
1501
- return (_b = (_a = this.strongMap) === null || _a === void 0 ? void 0 : _a.entries()) !== null && _b !== void 0 ? _b : [][Symbol.iterator]();
1502
- }
1503
- return this.liveEntries();
1504
- }
1505
- keys() {
1506
- return (function* (self) {
1507
- for (const [key] of self.entries())
1508
- yield key;
1509
- })(this);
1510
- }
1511
- values() {
1512
- return (function* (self) {
1513
- for (const [, value] of self.entries())
1514
- yield value;
1515
- })(this);
1516
- }
1517
- [Symbol.iterator]() {
1518
- return this.entries();
1091
+
1092
+
1093
+ /***/ },
1094
+
1095
+ /***/ 979
1096
+ (__unused_webpack_module, exports) {
1097
+
1098
+ var __webpack_unused_export__;
1099
+
1100
+ __webpack_unused_export__ = ({ value: true });
1101
+ exports.IntersectionObserverManager = void 0;
1102
+ /**
1103
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
1104
+ *
1105
+ * This source code is licensed under the MIT license found in the
1106
+ * LICENSE file in the root directory of this source tree.
1107
+ *
1108
+ * @format
1109
+ * @oncall memory_lab
1110
+ */
1111
+ class IntersectionObserverManager {
1112
+ constructor() {
1113
+ this.observedElements = new Map();
1114
+ this.observer = new IntersectionObserver(entries => {
1115
+ entries.forEach((entry) => {
1116
+ const element = entry.target;
1117
+ const callback = this.observedElements.get(element);
1118
+ if (callback) {
1119
+ callback(entry);
1120
+ }
1121
+ });
1122
+ }, {
1123
+ // Only trigger when element is completely out of viewport
1124
+ threshold: 0,
1125
+ // Add some margin to trigger before element is completely out of view
1126
+ rootMargin: '50px',
1127
+ });
1519
1128
  }
1520
- get size() {
1521
- var _a, _b;
1522
- if (!this.isWeak) {
1523
- if (this.noopMap)
1524
- return 0;
1525
- return (_b = (_a = this.strongMap) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0;
1526
- }
1527
- let count = 0;
1528
- // eslint-disable-next-line
1529
- for (const _ of this.liveEntries()) {
1530
- count++;
1129
+ static getInstance() {
1130
+ if (!IntersectionObserverManager.instance) {
1131
+ IntersectionObserverManager.instance = new IntersectionObserverManager();
1531
1132
  }
1532
- return count;
1533
- }
1534
- getFallbackMode() {
1535
- return this.fallbackMode;
1133
+ return IntersectionObserverManager.instance;
1536
1134
  }
1537
- cleanup() {
1538
- if (!this.isWeak)
1135
+ observe(elementRef, callback) {
1136
+ const element = elementRef.deref();
1137
+ if (element == null) {
1539
1138
  return;
1540
- for (const [id, entry] of this.entriesMap) {
1541
- if (!entry.ref.deref()) {
1542
- this.entriesMap.delete(id);
1543
- }
1544
1139
  }
1140
+ this.observedElements.set(element, callback);
1141
+ this.observer.observe(element);
1545
1142
  }
1546
- destroy() {
1547
- if (this.isWeak) {
1548
- clearInterval(this.cleanupInterval);
1143
+ unobserve(elementRef) {
1144
+ const element = elementRef.deref();
1145
+ if (element == null) {
1146
+ return;
1549
1147
  }
1148
+ this.observedElements.delete(element);
1149
+ this.observer.unobserve(element);
1550
1150
  }
1551
1151
  }
1552
- exports.WeakMapPlus = WeakMapPlus;
1152
+ exports.IntersectionObserverManager = IntersectionObserverManager;
1553
1153
 
1554
1154
 
1555
1155
  /***/ },
1556
1156
 
1557
- /***/ 341
1157
+ /***/ 737
1558
1158
  (__unused_webpack_module, exports, __webpack_require__) {
1559
1159
 
1160
+ var __webpack_unused_export__;
1560
1161
 
1561
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1562
- exports.createControlWidget = createControlWidget;
1563
- const visual_utils_1 = __webpack_require__(498);
1564
- const status_text_1 = __webpack_require__(775);
1565
- const toggle_button_1 = __webpack_require__(946);
1566
- const component_stack_panel_1 = __webpack_require__(904);
1567
- function createControlWidget(overlayDiv, hideAllRef, registerDataUpdateCallback) {
1568
- const controlWidget = (0, visual_utils_1.createVisualizerElement)('div');
1569
- controlWidget.style.position = 'fixed';
1570
- controlWidget.style.top = '50px';
1571
- controlWidget.style.right = '50px';
1572
- controlWidget.style.width = '400px';
1573
- controlWidget.style.background = 'rgba(0, 0, 0, 0.7)';
1574
- controlWidget.style.border = 'none';
1575
- controlWidget.style.borderRadius = '8px';
1576
- controlWidget.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.3)';
1577
- controlWidget.style.zIndex = '999999999';
1578
- controlWidget.style.display = 'flex';
1579
- controlWidget.style.flexDirection = 'column';
1580
- controlWidget.style.textShadow = 'none';
1581
- controlWidget.style.boxSizing = 'border-box';
1582
- controlWidget.style.font = '9px Inter, system-ui, -apple-system, sans-serif';
1583
- controlWidget.id = 'memory-visualization-control-widget';
1584
- // Create header section
1585
- const header = (0, visual_utils_1.createVisualizerElement)('div');
1586
- header.style.display = 'flex';
1587
- header.style.alignItems = 'center';
1588
- header.style.justifyContent = 'flex-start';
1589
- header.style.padding = '0 8px';
1590
- header.style.height = '36px';
1591
- controlWidget.appendChild(header);
1592
- // Create component stack panel
1593
- const componentStackPanel = (0, component_stack_panel_1.createComponentStackPanel)(registerDataUpdateCallback);
1594
- controlWidget.appendChild(componentStackPanel);
1595
- supportDragging(controlWidget);
1596
- const toggleButton = (0, toggle_button_1.createToggleButton)(overlayDiv, hideAllRef);
1597
- header.appendChild(toggleButton);
1598
- const statusText = (0, status_text_1.createStatusText)(registerDataUpdateCallback);
1599
- header.appendChild(statusText);
1600
- return controlWidget;
1601
- }
1602
- function supportDragging(controlWidget) {
1603
- let isDragging = false;
1604
- let offsetX = 0;
1605
- let offsetY = 0;
1606
- controlWidget.addEventListener('mousedown', e => {
1607
- // Only allow dragging from the header
1608
- if (!e.target.closest('#memory-visualization-control-widget > div:first-child')) {
1609
- return;
1610
- }
1611
- isDragging = true;
1612
- offsetX = e.clientX - controlWidget.offsetLeft;
1613
- offsetY = e.clientY - controlWidget.offsetTop;
1614
- controlWidget.style.cursor = 'move';
1615
- });
1616
- document.addEventListener('mousemove', e => {
1617
- if (isDragging) {
1618
- controlWidget.style.left = `${e.clientX - offsetX}px`;
1619
- controlWidget.style.top = `${e.clientY - offsetY}px`;
1620
- controlWidget.style.right = '';
1621
- }
1622
- });
1623
- document.addEventListener('mouseup', () => {
1624
- isDragging = false;
1625
- controlWidget.style.cursor = 'default';
1626
- });
1627
- }
1628
-
1629
-
1630
- /***/ },
1631
-
1632
- /***/ 346
1633
- (__unused_webpack_module, exports) {
1634
-
1635
-
1162
+ __webpack_unused_export__ = ({ value: true });
1163
+ exports.traverseFiber = exports.getTopMostFiberWithChild = __webpack_unused_export__ = __webpack_unused_export__ = exports.dD = __webpack_unused_export__ = exports.bv = exports.Fm = __webpack_unused_export__ = exports.JA = exports.NT = __webpack_unused_export__ = exports.UT = exports.DQ = __webpack_unused_export__ = exports.W = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = exports.IZ = exports.i$ = exports.Wb = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = void 0;
1164
+ exports.getFiberNodeFromElement = getFiberNodeFromElement;
1165
+ exports.getReactComponentStack = getReactComponentStack;
1166
+ exports.getDisplayNameOfFiberNode = getDisplayNameOfFiberNode;
1167
+ __webpack_unused_export__ = isFunctionalComponent;
1168
+ __webpack_unused_export__ = extractReactComponentName;
1169
+ const utils_1 = __webpack_require__(476);
1170
+ const valid_component_name_1 = __webpack_require__(847);
1171
+ __webpack_unused_export__ = 1;
1172
+ __webpack_unused_export__ = 0;
1173
+ __webpack_unused_export__ = 9;
1174
+ __webpack_unused_export__ = 13;
1175
+ __webpack_unused_export__ = 22;
1176
+ __webpack_unused_export__ = 11;
1177
+ __webpack_unused_export__ = 14;
1178
+ __webpack_unused_export__ = 15;
1179
+ exports.Wb = 5;
1180
+ exports.i$ = 26;
1181
+ exports.IZ = 27;
1182
+ __webpack_unused_export__ = 18;
1183
+ __webpack_unused_export__ = 6;
1184
+ __webpack_unused_export__ = 7;
1185
+ __webpack_unused_export__ = 23;
1186
+ __webpack_unused_export__ = 22;
1187
+ __webpack_unused_export__ = 3;
1188
+ __webpack_unused_export__ = 0xeacf;
1189
+ __webpack_unused_export__ = 'Symbol(react.concurrent_mode)';
1190
+ __webpack_unused_export__ = 'Symbol(react.async_mode)';
1191
+ // https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberFlags.js
1192
+ __webpack_unused_export__ = 0b1;
1193
+ exports.W = 0b10;
1194
+ __webpack_unused_export__ = 0b10000000;
1195
+ exports.DQ = 0b1000000000000;
1196
+ exports.UT = 0b100;
1197
+ __webpack_unused_export__ = 0b1000;
1198
+ exports.NT = 0b10000;
1199
+ exports.JA = 0b100000;
1200
+ __webpack_unused_export__ = 0b1000000000;
1201
+ exports.Fm = 0b10000000000;
1202
+ exports.bv = 0b10000000000000;
1203
+ __webpack_unused_export__ = exports.W |
1204
+ exports.UT |
1205
+ exports.NT |
1206
+ exports.JA |
1207
+ exports.DQ |
1208
+ exports.bv |
1209
+ exports.Fm;
1636
1210
  /**
1637
- * Copyright (c) Meta Platforms, Inc. and affiliates.
1638
- *
1639
- * This source code is licensed under the MIT license found in the
1640
- * LICENSE file in the root directory of this source tree.
1641
- *
1642
- * @format
1643
- * @oncall memory_lab
1211
+ * @see https://reactnative.dev/architecture/glossary#host-view-tree-and-host-view
1644
1212
  */
1645
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1646
- exports.config = exports.featureFlags = exports.performanceConfig = void 0;
1647
- // Performance Configuration
1648
- exports.performanceConfig = {
1649
- scanIntervalMs: 1000,
1650
- maxComponentStackDepth: 100,
1651
- memoryMeasurementIntervalMs: 5000,
1213
+ const isHostFiber = (fiber) => fiber.tag === exports.Wb ||
1214
+ // @ts-expect-error: it exists
1215
+ fiber.tag === exports.i$ ||
1216
+ // @ts-expect-error: it exists
1217
+ fiber.tag === exports.IZ ||
1218
+ typeof fiber.type === 'string';
1219
+ exports.dD = isHostFiber;
1220
+ const getNearestHostFiber = (fiber) => {
1221
+ let hostFiber = (0, exports.traverseFiber)(fiber, exports.dD);
1222
+ if (!hostFiber) {
1223
+ hostFiber = (0, exports.traverseFiber)(fiber, exports.dD, true);
1224
+ }
1225
+ return hostFiber;
1652
1226
  };
1653
- // Feature Flags
1654
- exports.featureFlags = {
1655
- enableMutationObserver: true,
1656
- enableMemoryTracking: true,
1657
- enableComponentStack: true,
1658
- enableConsoleLogs: window === null || window === void 0 ? void 0 : window.TEST_MEMORY_SCAN,
1227
+ __webpack_unused_export__ = getNearestHostFiber;
1228
+ const getTopMostHostFiber = (fiber) => {
1229
+ let topMostHostFiber = null;
1230
+ function checkFiber(fiber) {
1231
+ if ((0, exports.dD)(fiber)) {
1232
+ topMostHostFiber = fiber;
1233
+ }
1234
+ }
1235
+ (0, exports.traverseFiber)(fiber, checkFiber, true);
1236
+ return topMostHostFiber;
1659
1237
  };
1660
- // overall Config
1661
- exports.config = {
1662
- performance: exports.performanceConfig,
1663
- features: exports.featureFlags,
1238
+ __webpack_unused_export__ = getTopMostHostFiber;
1239
+ const getTopMostFiberWithChild = (fiber) => {
1240
+ let topMostFiber = null;
1241
+ function checkFiber(fiber) {
1242
+ if (fiber.child != null) {
1243
+ topMostFiber = fiber;
1244
+ }
1245
+ }
1246
+ (0, exports.traverseFiber)(fiber, checkFiber, true);
1247
+ return topMostFiber;
1664
1248
  };
1665
-
1666
-
1667
- /***/ },
1668
-
1669
- /***/ 368
1670
- (__unused_webpack_module, exports, __webpack_require__) {
1671
-
1672
-
1673
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1674
- exports.createOverlayDiv = createOverlayDiv;
1675
- /**
1676
- * Copyright (c) Meta Platforms, Inc. and affiliates.
1677
- *
1678
- * This source code is licensed under the MIT license found in the
1679
- * LICENSE file in the root directory of this source tree.
1680
- *
1681
- * @format
1682
- * @oncall memory_lab
1683
- */
1684
- const visual_utils_1 = __webpack_require__(498);
1685
- function createOverlayDiv() {
1686
- const overlayDiv = (0, visual_utils_1.createVisualizerElement)('div');
1687
- overlayDiv.style.position = 'absolute';
1688
- overlayDiv.style.top = '0px';
1689
- overlayDiv.style.left = '0px';
1690
- overlayDiv.id = 'memory-visualization-overlay';
1691
- return overlayDiv;
1249
+ exports.getTopMostFiberWithChild = getTopMostFiberWithChild;
1250
+ const traverseFiber = (fiber, selector, ascending = false) => {
1251
+ if (!fiber) {
1252
+ return null;
1253
+ }
1254
+ if (selector(fiber) === true) {
1255
+ return fiber;
1256
+ }
1257
+ let next = ascending ? fiber.return : fiber.child;
1258
+ while (next) {
1259
+ const match = (0, exports.traverseFiber)(next, selector, ascending);
1260
+ if (match) {
1261
+ return match;
1262
+ }
1263
+ next = ascending ? null : next.sibling;
1264
+ }
1265
+ return null;
1266
+ };
1267
+ exports.traverseFiber = traverseFiber;
1268
+ // React internal property keys
1269
+ const internalKeys = [
1270
+ '__reactFiber$', // React 17+
1271
+ '__reactInternalInstance$', // React 16
1272
+ '_reactRootContainer', // React Root
1273
+ ];
1274
+ const getOwnPropertyNames = Object.getOwnPropertyNames.bind(Object);
1275
+ function getFiberNodeFromElement(element) {
1276
+ for (const prefix of internalKeys) {
1277
+ // Use Object.keys only as fallback since it's slower
1278
+ const key = getOwnPropertyNames(element).find(k => k.startsWith(prefix));
1279
+ if (key) {
1280
+ return element[key];
1281
+ }
1282
+ }
1283
+ return null;
1284
+ }
1285
+ function getReactComponentStack(node) {
1286
+ const stack = [];
1287
+ const visited = new Set();
1288
+ let fiber = node;
1289
+ while (fiber) {
1290
+ if (visited.has(fiber)) {
1291
+ break;
1292
+ }
1293
+ visited.add(fiber);
1294
+ const name = getDisplayNameOfFiberNode(fiber);
1295
+ if (name) {
1296
+ stack.push(name);
1297
+ }
1298
+ fiber = fiber.return;
1299
+ }
1300
+ return stack;
1301
+ }
1302
+ function getDisplayNameOfFiberNode(node) {
1303
+ var _a, _b, _c, _d;
1304
+ const elementType = (_a = node.type) !== null && _a !== void 0 ? _a : node.elementType;
1305
+ // Try to get name from displayName or name properties
1306
+ let displayName = (_b = elementType === null || elementType === void 0 ? void 0 : elementType.displayName) !== null && _b !== void 0 ? _b : elementType === null || elementType === void 0 ? void 0 : elementType.name;
1307
+ // Handle class components and forwardRef
1308
+ if (displayName == null) {
1309
+ if (elementType === null || elementType === void 0 ? void 0 : elementType.render) {
1310
+ // Class components
1311
+ const render = elementType === null || elementType === void 0 ? void 0 : elementType.render;
1312
+ displayName = (_c = render === null || render === void 0 ? void 0 : render.displayName) !== null && _c !== void 0 ? _c : render === null || render === void 0 ? void 0 : render.name;
1313
+ }
1314
+ else if (elementType === null || elementType === void 0 ? void 0 : elementType.type) {
1315
+ // ForwardRef components
1316
+ displayName = (_d = elementType.type.displayName) !== null && _d !== void 0 ? _d : elementType.type.name;
1317
+ }
1318
+ }
1319
+ // Handle anonymous functions
1320
+ if (!displayName && typeof elementType === 'function') {
1321
+ displayName = elementType.name;
1322
+ }
1323
+ const ret = (0, utils_1.getMeaningfulName)(extractReactComponentName(displayName));
1324
+ return (0, valid_component_name_1.isValidComponentName)(ret) ? ret : null;
1325
+ }
1326
+ function isFunctionalComponent(node) {
1327
+ const elementType = node === null || node === void 0 ? void 0 : node.elementType;
1328
+ return typeof elementType === 'function';
1329
+ }
1330
+ // dom-element [from component.react] --> component.react
1331
+ function extractReactComponentName(displayName) {
1332
+ if (typeof displayName !== 'string') {
1333
+ return null;
1334
+ }
1335
+ if (!displayName.includes('[') || !displayName.includes(']')) {
1336
+ return displayName;
1337
+ }
1338
+ const startIndex = displayName.indexOf('[');
1339
+ const endIndex = displayName.indexOf(']');
1340
+ if (startIndex > endIndex) {
1341
+ return displayName;
1342
+ }
1343
+ const name = displayName.substring(startIndex + 1, endIndex);
1344
+ if (name.startsWith('from ')) {
1345
+ return name.substring('from '.length);
1346
+ }
1347
+ return name;
1692
1348
  }
1693
1349
 
1694
1350
 
@@ -1877,69 +1533,425 @@ function setRunInSession() {
1877
1533
 
1878
1534
  /***/ },
1879
1535
 
1880
- /***/ 498
1536
+ /***/ 313
1881
1537
  (__unused_webpack_module, exports) {
1882
1538
 
1539
+ var __webpack_unused_export__;
1883
1540
 
1884
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1885
- exports.isVisualizerElement = isVisualizerElement;
1886
- exports.createVisualizerElement = createVisualizerElement;
1887
- exports.tryToAttachOverlay = tryToAttachOverlay;
1888
- exports.addTrackedListener = addTrackedListener;
1889
- exports.removeAllListeners = removeAllListeners;
1890
- exports.debounce = debounce;
1891
- const VISUALIZER_DATA_ATTR = 'data-visualizer';
1892
- function setVisualizerElement(element) {
1893
- element.setAttribute(VISUALIZER_DATA_ATTR, 'true');
1894
- element.setAttribute('data-visualcompletion', 'ignore');
1895
- }
1896
- function isVisualizerElement(element) {
1897
- return element.getAttribute(VISUALIZER_DATA_ATTR) === 'true';
1898
- }
1899
- function createVisualizerElement(tag) {
1900
- const element = document.createElement(tag);
1901
- setVisualizerElement(element);
1902
- return element;
1541
+ /**
1542
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
1543
+ *
1544
+ * This source code is licensed under the MIT license found in the
1545
+ * LICENSE file in the root directory of this source tree.
1546
+ *
1547
+ * @format
1548
+ * @oncall memory_lab
1549
+ */
1550
+ var _a, _b, _c;
1551
+ __webpack_unused_export__ = ({ value: true });
1552
+ exports.WeakMapPlus = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = void 0;
1553
+ __webpack_unused_export__ = getNativeWeakMap;
1554
+ __webpack_unused_export__ = getNativeWeakMapOrFallback;
1555
+ __webpack_unused_export__ = getNativeWeakSet;
1556
+ __webpack_unused_export__ = getNativeWeakSetOrFallback;
1557
+ __webpack_unused_export__ = getNativeWeakRef;
1558
+ __webpack_unused_export__ = getNativeWeakRefOrFallback;
1559
+ __webpack_unused_export__ = isWeakMapNative;
1560
+ __webpack_unused_export__ = isWeakSetNative;
1561
+ __webpack_unused_export__ = isWeakRefNative;
1562
+ exports.isWeakAPINative = isWeakAPINative;
1563
+ const globalScope = typeof window !== 'undefined' ? window : self;
1564
+ const _weakMap = (_a = globalScope.WeakMap) !== null && _a !== void 0 ? _a : null;
1565
+ const _weakMapIsNative = isWeakMapNative();
1566
+ const _weakSet = (_b = globalScope.WeakSet) !== null && _b !== void 0 ? _b : null;
1567
+ const _weakSetIsNative = isWeakSetNative();
1568
+ const _weakRef = (_c = globalScope.WeakRef) !== null && _c !== void 0 ? _c : null;
1569
+ const _weakRefIsNative = isWeakRefNative();
1570
+ const _weakAPIsAreNative = _weakMapIsNative && _weakSetIsNative && _weakRefIsNative;
1571
+ class WeakRefNoOp {
1572
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1573
+ constructor(_targetObject) {
1574
+ // to be overridden
1575
+ }
1576
+ deref() {
1577
+ return undefined;
1578
+ }
1903
1579
  }
1904
- function tryToAttachOverlay(overlayDiv) {
1905
- if (document.body) {
1906
- document.body.appendChild(overlayDiv);
1580
+ __webpack_unused_export__ = WeakRefNoOp;
1581
+ class WeakSetNoOp {
1582
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1583
+ constructor(_iterable) {
1584
+ // to be overridden
1585
+ }
1586
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1587
+ add(_value) {
1588
+ return this;
1589
+ }
1590
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1591
+ delete(_value) {
1592
+ return false;
1593
+ }
1594
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1595
+ has(_value) {
1596
+ return false;
1907
1597
  }
1908
1598
  }
1909
- const listenerMap = new WeakMap();
1910
- function addTrackedListener(elRef, type, cb, options) {
1911
- var _a;
1912
- const el = elRef.deref();
1913
- if (!el)
1914
- return;
1915
- el.addEventListener(type, cb, options);
1916
- if (!listenerMap.has(el)) {
1917
- listenerMap.set(el, []);
1599
+ __webpack_unused_export__ = WeakSetNoOp;
1600
+ class WeakMapNoOp {
1601
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1602
+ constructor(_iterable) {
1603
+ // to be overridden
1604
+ }
1605
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1606
+ delete(_key) {
1607
+ return false;
1608
+ }
1609
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1610
+ get(_key) {
1611
+ return undefined;
1612
+ }
1613
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1614
+ has(_key) {
1615
+ return false;
1616
+ }
1617
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1618
+ set(_key, _value) {
1619
+ return this;
1918
1620
  }
1919
- (_a = listenerMap.get(el)) === null || _a === void 0 ? void 0 : _a.push({ type, cb, options });
1920
1621
  }
1921
- function removeAllListeners(elRef) {
1922
- const el = elRef.deref();
1923
- if (!el)
1924
- return;
1925
- const listeners = listenerMap.get(el);
1926
- if (!listeners)
1927
- return;
1928
- for (const { type, cb, options } of listeners) {
1929
- el.removeEventListener(type, cb, options);
1622
+ __webpack_unused_export__ = WeakMapNoOp;
1623
+ function getNativeWeakMap() {
1624
+ return _weakMapIsNative ? _weakMap : null;
1625
+ }
1626
+ function getNativeWeakMapOrFallback() {
1627
+ return _weakMapIsNative && _weakMap ? _weakMap : WeakMapNoOp;
1628
+ }
1629
+ function getNativeWeakSet() {
1630
+ return _weakSetIsNative ? _weakSet : null;
1631
+ }
1632
+ function getNativeWeakSetOrFallback() {
1633
+ return _weakSetIsNative && _weakSet ? _weakSet : WeakSetNoOp;
1634
+ }
1635
+ function getNativeWeakRef() {
1636
+ return _weakRefIsNative ? _weakRef : null;
1637
+ }
1638
+ function getNativeWeakRefOrFallback() {
1639
+ return _weakRefIsNative && _weakRef ? _weakRef : WeakRefNoOp;
1640
+ }
1641
+ function normalize(input) {
1642
+ return typeof input.replace === 'function'
1643
+ ? input.replace(/\n/g, ' ').replace(/\s+/g, ' ')
1644
+ : null;
1645
+ }
1646
+ function isWeakMapNative() {
1647
+ return (_weakMap !== null &&
1648
+ typeof _weakMap.toString === 'function' &&
1649
+ normalize(_weakMap.toString()) === 'function WeakMap() { [native code] }');
1650
+ }
1651
+ function isWeakSetNative() {
1652
+ return (_weakSet !== null &&
1653
+ typeof _weakSet.toString === 'function' &&
1654
+ normalize(_weakSet.toString()) === 'function WeakSet() { [native code] }');
1655
+ }
1656
+ function isWeakRefNative() {
1657
+ return (_weakRef !== null &&
1658
+ typeof _weakRef.toString === 'function' &&
1659
+ normalize(_weakRef.toString()) === 'function WeakRef() { [native code] }');
1660
+ }
1661
+ function isWeakAPINative() {
1662
+ return _weakAPIsAreNative;
1663
+ }
1664
+ class WeakMapPlus {
1665
+ constructor(options = {}) {
1666
+ this.strongMap = null;
1667
+ this.noopMap = false;
1668
+ this.entriesMap = new Map();
1669
+ this.keyToId = new WeakMap();
1670
+ const { fallback = 'strong', cleanupMs = 1000 } = options;
1671
+ this.isWeak = _weakAPIsAreNative;
1672
+ this.fallbackMode = fallback;
1673
+ if (!this.isWeak) {
1674
+ if (fallback === 'strong') {
1675
+ this.strongMap = new Map();
1676
+ }
1677
+ else if (fallback === 'noop') {
1678
+ this.noopMap = true;
1679
+ }
1680
+ this.cleanupInterval = -1;
1681
+ }
1682
+ else {
1683
+ this.cleanupInterval = setInterval(() => this.cleanup(), cleanupMs);
1684
+ }
1685
+ }
1686
+ getOrCreateId(key) {
1687
+ let id = this.keyToId.get(key);
1688
+ if (!id) {
1689
+ id = Symbol();
1690
+ this.keyToId.set(key, id);
1691
+ }
1692
+ return id;
1693
+ }
1694
+ set(key, value) {
1695
+ var _a;
1696
+ if (!this.isWeak) {
1697
+ if (this.noopMap)
1698
+ return this;
1699
+ (_a = this.strongMap) === null || _a === void 0 ? void 0 : _a.set(key, value);
1700
+ return this;
1701
+ }
1702
+ const id = this.getOrCreateId(key);
1703
+ this.entriesMap.set(id, { ref: new WeakRef(key), value });
1704
+ return this;
1705
+ }
1706
+ get(key) {
1707
+ var _a, _b;
1708
+ if (!this.isWeak) {
1709
+ if (this.noopMap)
1710
+ return undefined;
1711
+ return (_a = this.strongMap) === null || _a === void 0 ? void 0 : _a.get(key);
1712
+ }
1713
+ const id = this.keyToId.get(key);
1714
+ if (!id)
1715
+ return undefined;
1716
+ const entry = this.entriesMap.get(id);
1717
+ const derefKey = (_b = entry === null || entry === void 0 ? void 0 : entry.ref) === null || _b === void 0 ? void 0 : _b.deref();
1718
+ return derefKey ? entry === null || entry === void 0 ? void 0 : entry.value : undefined;
1719
+ }
1720
+ has(key) {
1721
+ var _a, _b;
1722
+ if (!this.isWeak) {
1723
+ if (this.noopMap)
1724
+ return false;
1725
+ return (_b = (_a = this.strongMap) === null || _a === void 0 ? void 0 : _a.has(key)) !== null && _b !== void 0 ? _b : false;
1726
+ }
1727
+ const id = this.keyToId.get(key);
1728
+ if (!id)
1729
+ return false;
1730
+ const entry = this.entriesMap.get(id);
1731
+ return !!(entry && entry.ref.deref());
1732
+ }
1733
+ delete(key) {
1734
+ var _a, _b;
1735
+ if (!this.isWeak) {
1736
+ if (this.noopMap)
1737
+ return false;
1738
+ return (_b = (_a = this.strongMap) === null || _a === void 0 ? void 0 : _a.delete(key)) !== null && _b !== void 0 ? _b : false;
1739
+ }
1740
+ const id = this.keyToId.get(key);
1741
+ if (!id)
1742
+ return false;
1743
+ this.keyToId.delete(key);
1744
+ return this.entriesMap.delete(id);
1745
+ }
1746
+ *liveEntries() {
1747
+ for (const [, entry] of this.entriesMap) {
1748
+ const key = entry.ref.deref();
1749
+ if (key) {
1750
+ yield [key, entry.value];
1751
+ }
1752
+ }
1753
+ }
1754
+ entries() {
1755
+ var _a, _b;
1756
+ if (!this.isWeak) {
1757
+ if (this.noopMap)
1758
+ return [][Symbol.iterator]();
1759
+ return (_b = (_a = this.strongMap) === null || _a === void 0 ? void 0 : _a.entries()) !== null && _b !== void 0 ? _b : [][Symbol.iterator]();
1760
+ }
1761
+ return this.liveEntries();
1762
+ }
1763
+ keys() {
1764
+ return (function* (self) {
1765
+ for (const [key] of self.entries())
1766
+ yield key;
1767
+ })(this);
1768
+ }
1769
+ values() {
1770
+ return (function* (self) {
1771
+ for (const [, value] of self.entries())
1772
+ yield value;
1773
+ })(this);
1774
+ }
1775
+ [Symbol.iterator]() {
1776
+ return this.entries();
1777
+ }
1778
+ get size() {
1779
+ var _a, _b;
1780
+ if (!this.isWeak) {
1781
+ if (this.noopMap)
1782
+ return 0;
1783
+ return (_b = (_a = this.strongMap) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0;
1784
+ }
1785
+ let count = 0;
1786
+ // eslint-disable-next-line
1787
+ for (const _ of this.liveEntries()) {
1788
+ count++;
1789
+ }
1790
+ return count;
1791
+ }
1792
+ getFallbackMode() {
1793
+ return this.fallbackMode;
1794
+ }
1795
+ cleanup() {
1796
+ if (!this.isWeak)
1797
+ return;
1798
+ for (const [id, entry] of this.entriesMap) {
1799
+ if (!entry.ref.deref()) {
1800
+ this.entriesMap.delete(id);
1801
+ }
1802
+ }
1803
+ }
1804
+ destroy() {
1805
+ if (this.isWeak) {
1806
+ clearInterval(this.cleanupInterval);
1807
+ }
1930
1808
  }
1931
- listenerMap.delete(el);
1932
1809
  }
1933
- function debounce(callback, delay) {
1934
- let timer = null;
1935
- return (...args) => {
1936
- if (timer) {
1937
- clearTimeout(timer);
1810
+ exports.WeakMapPlus = WeakMapPlus;
1811
+
1812
+
1813
+ /***/ },
1814
+
1815
+ /***/ 904
1816
+ (__unused_webpack_module, exports, __webpack_require__) {
1817
+
1818
+ var __webpack_unused_export__;
1819
+
1820
+ __webpack_unused_export__ = ({ value: true });
1821
+ exports.createComponentStackPanel = createComponentStackPanel;
1822
+ const visual_utils_1 = __webpack_require__(498);
1823
+ function createComponentStackPanel(registerDataUpdateCallback) {
1824
+ const panel = (0, visual_utils_1.createVisualizerElement)('div');
1825
+ panel.style.width = '100%';
1826
+ // Ensure max height is at most 80% of viewport height
1827
+ panel.style.maxHeight = '80vh';
1828
+ panel.style.background = 'rgba(0, 0, 0, 0.5)';
1829
+ panel.style.borderTop = '1px solid rgba(255, 255, 255, 0.1)';
1830
+ panel.style.display = 'none';
1831
+ panel.style.flexDirection = 'column';
1832
+ panel.style.padding = '8px';
1833
+ panel.style.boxSizing = 'border-box';
1834
+ panel.style.borderRadius = '8px';
1835
+ panel.style.overflowY = 'scroll';
1836
+ panel.style.overflowX = 'hidden';
1837
+ panel.style.textShadow = 'none';
1838
+ panel.style.font = '9px Inter, system-ui, -apple-system, sans-serif';
1839
+ panel.style.color = 'white';
1840
+ panel.id = 'memory-visualization-component-stack-panel';
1841
+ let pinned = false;
1842
+ panel.addEventListener('mouseenter', () => {
1843
+ pinned = true;
1844
+ });
1845
+ panel.addEventListener('mouseleave', () => {
1846
+ pinned = false;
1847
+ });
1848
+ // Register data update callback to update component stack panel
1849
+ registerDataUpdateCallback((0, visual_utils_1.debounce)((data) => {
1850
+ var _a;
1851
+ if (pinned) {
1852
+ return;
1938
1853
  }
1939
- timer = setTimeout(() => {
1940
- callback(...args);
1941
- }, delay);
1942
- };
1854
+ panel.innerHTML = '';
1855
+ if (data.selectedElementId == null ||
1856
+ !((_a = data.selectedReactComponentStack) === null || _a === void 0 ? void 0 : _a.length)) {
1857
+ panel.style.display = 'none';
1858
+ return;
1859
+ }
1860
+ panel.style.display = 'flex';
1861
+ const title = (0, visual_utils_1.createVisualizerElement)('div');
1862
+ title.textContent = 'Component Stack:';
1863
+ title.style.fontWeight = 'bold';
1864
+ title.style.marginBottom = '8px';
1865
+ panel.appendChild(title);
1866
+ let actualComponentStackLength = 0;
1867
+ data.selectedReactComponentStack.forEach((component) => {
1868
+ const componentDiv = (0, visual_utils_1.createVisualizerElement)('div');
1869
+ componentDiv.style.marginBottom = '4px';
1870
+ componentDiv.textContent = component;
1871
+ panel.appendChild(componentDiv);
1872
+ ++actualComponentStackLength;
1873
+ });
1874
+ if (actualComponentStackLength === 0) {
1875
+ title.remove();
1876
+ }
1877
+ }, 1));
1878
+ return panel;
1879
+ }
1880
+
1881
+
1882
+ /***/ },
1883
+
1884
+ /***/ 341
1885
+ (__unused_webpack_module, exports, __webpack_require__) {
1886
+
1887
+ var __webpack_unused_export__;
1888
+
1889
+ __webpack_unused_export__ = ({ value: true });
1890
+ exports.createControlWidget = createControlWidget;
1891
+ const visual_utils_1 = __webpack_require__(498);
1892
+ const status_text_1 = __webpack_require__(775);
1893
+ const toggle_button_1 = __webpack_require__(946);
1894
+ const component_stack_panel_1 = __webpack_require__(904);
1895
+ function createControlWidget(overlayDiv, hideAllRef, registerDataUpdateCallback) {
1896
+ const controlWidget = (0, visual_utils_1.createVisualizerElement)('div');
1897
+ controlWidget.style.position = 'fixed';
1898
+ controlWidget.style.top = '50px';
1899
+ controlWidget.style.right = '50px';
1900
+ controlWidget.style.width = '400px';
1901
+ controlWidget.style.background = 'rgba(0, 0, 0, 0.7)';
1902
+ controlWidget.style.border = 'none';
1903
+ controlWidget.style.borderRadius = '8px';
1904
+ controlWidget.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.3)';
1905
+ controlWidget.style.zIndex = '999999999';
1906
+ controlWidget.style.display = 'flex';
1907
+ controlWidget.style.flexDirection = 'column';
1908
+ controlWidget.style.textShadow = 'none';
1909
+ controlWidget.style.boxSizing = 'border-box';
1910
+ controlWidget.style.font = '9px Inter, system-ui, -apple-system, sans-serif';
1911
+ controlWidget.id = 'memory-visualization-control-widget';
1912
+ // Create header section
1913
+ const header = (0, visual_utils_1.createVisualizerElement)('div');
1914
+ header.style.display = 'flex';
1915
+ header.style.alignItems = 'center';
1916
+ header.style.justifyContent = 'flex-start';
1917
+ header.style.padding = '0 8px';
1918
+ header.style.height = '36px';
1919
+ controlWidget.appendChild(header);
1920
+ // Create component stack panel
1921
+ const componentStackPanel = (0, component_stack_panel_1.createComponentStackPanel)(registerDataUpdateCallback);
1922
+ controlWidget.appendChild(componentStackPanel);
1923
+ supportDragging(controlWidget);
1924
+ const toggleButton = (0, toggle_button_1.createToggleButton)(overlayDiv, hideAllRef);
1925
+ header.appendChild(toggleButton);
1926
+ const statusText = (0, status_text_1.createStatusText)(registerDataUpdateCallback);
1927
+ header.appendChild(statusText);
1928
+ return controlWidget;
1929
+ }
1930
+ function supportDragging(controlWidget) {
1931
+ let isDragging = false;
1932
+ let offsetX = 0;
1933
+ let offsetY = 0;
1934
+ controlWidget.addEventListener('mousedown', e => {
1935
+ // Only allow dragging from the header
1936
+ if (!e.target.closest('#memory-visualization-control-widget > div:first-child')) {
1937
+ return;
1938
+ }
1939
+ isDragging = true;
1940
+ offsetX = e.clientX - controlWidget.offsetLeft;
1941
+ offsetY = e.clientY - controlWidget.offsetTop;
1942
+ controlWidget.style.cursor = 'move';
1943
+ });
1944
+ document.addEventListener('mousemove', e => {
1945
+ if (isDragging) {
1946
+ controlWidget.style.left = `${e.clientX - offsetX}px`;
1947
+ controlWidget.style.top = `${e.clientY - offsetY}px`;
1948
+ controlWidget.style.right = '';
1949
+ }
1950
+ });
1951
+ document.addEventListener('mouseup', () => {
1952
+ isDragging = false;
1953
+ controlWidget.style.cursor = 'default';
1954
+ });
1943
1955
  }
1944
1956
 
1945
1957
 
@@ -1948,8 +1960,9 @@ function debounce(callback, delay) {
1948
1960
  /***/ 701
1949
1961
  (__unused_webpack_module, exports, __webpack_require__) {
1950
1962
 
1963
+ var __webpack_unused_export__;
1951
1964
 
1952
- Object.defineProperty(exports, "__esModule", ({ value: true }));
1965
+ __webpack_unused_export__ = ({ value: true });
1953
1966
  exports.createOverlayRectangle = createOverlayRectangle;
1954
1967
  const intersection_observer_1 = __webpack_require__(979);
1955
1968
  const visual_utils_1 = __webpack_require__(498);
@@ -2065,477 +2078,479 @@ function styleOnInteraction(divRef, state) {
2065
2078
  div.style.background = 'rgba(75, 192, 192, 0.02)';
2066
2079
  }
2067
2080
  else {
2068
- div.style.border = '1px dotted rgba(75, 192, 192, 0.8)';
2069
- div.style.background = '';
2081
+ div.style.border = '1px dotted rgba(75, 192, 192, 0.8)';
2082
+ div.style.background = '';
2083
+ }
2084
+ }
2085
+ else {
2086
+ // pinned
2087
+ div.style.border = '1px solid rgba(255, 215, 0, 0.9)';
2088
+ div.style.background = 'rgba(255, 215, 0, 0.08)';
2089
+ }
2090
+ }
2091
+
2092
+
2093
+ /***/ },
2094
+
2095
+ /***/ 775
2096
+ (__unused_webpack_module, exports, __webpack_require__) {
2097
+
2098
+ var __webpack_unused_export__;
2099
+
2100
+ __webpack_unused_export__ = ({ value: true });
2101
+ exports.createStatusText = createStatusText;
2102
+ const visual_utils_1 = __webpack_require__(498);
2103
+ function formatBytes(bytes) {
2104
+ if (bytes === 0)
2105
+ return '0 B';
2106
+ const k = 1024;
2107
+ const sizes = ['B', 'KB', 'MB', 'GB'];
2108
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
2109
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
2110
+ }
2111
+ function createStatusText(registerDataUpdateCallback) {
2112
+ const statusWidget = (0, visual_utils_1.createVisualizerElement)('div');
2113
+ statusWidget.style.marginLeft = '10px';
2114
+ statusWidget.style.color = 'white';
2115
+ statusWidget.style.fontSize = '10px';
2116
+ statusWidget.style.fontFamily = 'Inter, system-ui, sans-serif';
2117
+ statusWidget.style.overflow = 'hidden';
2118
+ statusWidget.style.whiteSpace = 'nowrap';
2119
+ statusWidget.style.textOverflow = 'ellipsis';
2120
+ statusWidget.textContent = '';
2121
+ registerDataUpdateCallback((data) => {
2122
+ var _a, _b, _c, _d;
2123
+ const performance = window.performance;
2124
+ const memory = performance === null || performance === void 0 ? void 0 : performance.memory;
2125
+ const usedHeap = (_a = memory === null || memory === void 0 ? void 0 : memory.usedJSHeapSize) !== null && _a !== void 0 ? _a : 0;
2126
+ const totalHeap = (_b = memory === null || memory === void 0 ? void 0 : memory.totalJSHeapSize) !== null && _b !== void 0 ? _b : 0;
2127
+ const totalElements = (_c = data.totalDOMElementsCount) !== null && _c !== void 0 ? _c : 0;
2128
+ const detachedElements = (_d = data.detachedDOMElementsCount) !== null && _d !== void 0 ? _d : 0;
2129
+ statusWidget.textContent =
2130
+ `DOM: ${totalElements} total, ${detachedElements} detached | ` +
2131
+ `Heap: ${formatBytes(usedHeap)} / ${formatBytes(totalHeap)}`;
2132
+ });
2133
+ return statusWidget;
2134
+ }
2135
+
2136
+
2137
+ /***/ },
2138
+
2139
+ /***/ 946
2140
+ (__unused_webpack_module, exports, __webpack_require__) {
2141
+
2142
+ var __webpack_unused_export__;
2143
+
2144
+ __webpack_unused_export__ = ({ value: true });
2145
+ exports.createToggleButton = createToggleButton;
2146
+ /**
2147
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
2148
+ *
2149
+ * This source code is licensed under the MIT license found in the
2150
+ * LICENSE file in the root directory of this source tree.
2151
+ *
2152
+ * @format
2153
+ * @oncall memory_lab
2154
+ */
2155
+ const visual_utils_1 = __webpack_require__(498);
2156
+ function createToggleButton(overlayDiv, hideAllRef) {
2157
+ const toggleWrapper = (0, visual_utils_1.createVisualizerElement)('div');
2158
+ toggleWrapper.style.width = '40px';
2159
+ toggleWrapper.style.height = '24px';
2160
+ toggleWrapper.style.borderRadius = '9999px';
2161
+ toggleWrapper.style.backgroundColor = '#34C759'; // ON by default
2162
+ toggleWrapper.style.cursor = 'pointer';
2163
+ toggleWrapper.style.position = 'relative';
2164
+ toggleWrapper.style.transition = 'background-color 0.3s ease';
2165
+ const knob = (0, visual_utils_1.createVisualizerElement)('div');
2166
+ knob.style.width = '18px';
2167
+ knob.style.height = '18px';
2168
+ knob.style.backgroundColor = 'white';
2169
+ knob.style.borderRadius = '50%';
2170
+ knob.style.position = 'absolute';
2171
+ knob.style.top = '3px';
2172
+ knob.style.left = '3px'; // ON position
2173
+ knob.style.transition = 'left 0.25s ease';
2174
+ toggleWrapper.appendChild(knob);
2175
+ toggleWrapper.addEventListener('click', () => {
2176
+ hideAllRef.value = !hideAllRef.value;
2177
+ if (hideAllRef.value) {
2178
+ // OFF state
2179
+ overlayDiv.style.display = 'none';
2180
+ overlayDiv.style.pointerEvents = 'none';
2181
+ overlayDiv.style.userSelect = 'none';
2182
+ knob.style.left = '19px';
2183
+ toggleWrapper.style.backgroundColor = '#FF3B30'; // Apple red
2184
+ }
2185
+ else {
2186
+ // ON state
2187
+ overlayDiv.style.display = 'block';
2188
+ overlayDiv.style.pointerEvents = 'auto';
2189
+ overlayDiv.style.userSelect = 'auto';
2190
+ knob.style.left = '3px';
2191
+ toggleWrapper.style.backgroundColor = '#34C759'; // Apple green
2070
2192
  }
2071
- }
2072
- else {
2073
- // pinned
2074
- div.style.border = '1px solid rgba(255, 215, 0, 0.9)';
2075
- div.style.background = 'rgba(255, 215, 0, 0.08)';
2076
- }
2193
+ });
2194
+ return toggleWrapper;
2077
2195
  }
2078
2196
 
2079
2197
 
2080
2198
  /***/ },
2081
2199
 
2082
- /***/ 737
2200
+ /***/ 368
2083
2201
  (__unused_webpack_module, exports, __webpack_require__) {
2084
2202
 
2203
+ var __webpack_unused_export__;
2085
2204
 
2086
- Object.defineProperty(exports, "__esModule", ({ value: true }));
2087
- exports.traverseFiber = exports.getTopMostFiberWithChild = exports.getTopMostHostFiber = exports.getNearestHostFiber = exports.isHostFiber = exports.MutationMask = exports.Visibility = exports.Snapshot = exports.Ref = exports.ContentReset = exports.ChildDeletion = exports.Cloned = exports.Update = exports.Hydrating = exports.DidCapture = exports.Placement = exports.PerformedWork = exports.DEPRECATED_ASYNC_MODE_SYMBOL_STRING = exports.CONCURRENT_MODE_SYMBOL_STRING = exports.CONCURRENT_MODE_NUMBER = exports.HostRoot = exports.OffscreenComponent = exports.LegacyHiddenComponent = exports.Fragment = exports.HostText = exports.DehydratedSuspenseComponent = exports.HostSingletonTag = exports.HostHoistableTag = exports.HostComponentTag = exports.SimpleMemoComponentTag = exports.MemoComponentTag = exports.ForwardRefTag = exports.OffscreenComponentTag = exports.SuspenseComponentTag = exports.ContextConsumerTag = exports.FunctionComponentTag = exports.ClassComponentTag = void 0;
2088
- exports.getFiberNodeFromElement = getFiberNodeFromElement;
2089
- exports.getReactComponentStack = getReactComponentStack;
2090
- exports.getDisplayNameOfFiberNode = getDisplayNameOfFiberNode;
2091
- exports.isFunctionalComponent = isFunctionalComponent;
2092
- exports.extractReactComponentName = extractReactComponentName;
2093
- const utils_1 = __webpack_require__(476);
2094
- const valid_component_name_1 = __webpack_require__(847);
2095
- exports.ClassComponentTag = 1;
2096
- exports.FunctionComponentTag = 0;
2097
- exports.ContextConsumerTag = 9;
2098
- exports.SuspenseComponentTag = 13;
2099
- exports.OffscreenComponentTag = 22;
2100
- exports.ForwardRefTag = 11;
2101
- exports.MemoComponentTag = 14;
2102
- exports.SimpleMemoComponentTag = 15;
2103
- exports.HostComponentTag = 5;
2104
- exports.HostHoistableTag = 26;
2105
- exports.HostSingletonTag = 27;
2106
- exports.DehydratedSuspenseComponent = 18;
2107
- exports.HostText = 6;
2108
- exports.Fragment = 7;
2109
- exports.LegacyHiddenComponent = 23;
2110
- exports.OffscreenComponent = 22;
2111
- exports.HostRoot = 3;
2112
- exports.CONCURRENT_MODE_NUMBER = 0xeacf;
2113
- exports.CONCURRENT_MODE_SYMBOL_STRING = 'Symbol(react.concurrent_mode)';
2114
- exports.DEPRECATED_ASYNC_MODE_SYMBOL_STRING = 'Symbol(react.async_mode)';
2115
- // https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberFlags.js
2116
- exports.PerformedWork = 0b1;
2117
- exports.Placement = 0b10;
2118
- exports.DidCapture = 0b10000000;
2119
- exports.Hydrating = 0b1000000000000;
2120
- exports.Update = 0b100;
2121
- exports.Cloned = 0b1000;
2122
- exports.ChildDeletion = 0b10000;
2123
- exports.ContentReset = 0b100000;
2124
- exports.Ref = 0b1000000000;
2125
- exports.Snapshot = 0b10000000000;
2126
- exports.Visibility = 0b10000000000000;
2127
- exports.MutationMask = exports.Placement |
2128
- exports.Update |
2129
- exports.ChildDeletion |
2130
- exports.ContentReset |
2131
- exports.Hydrating |
2132
- exports.Visibility |
2133
- exports.Snapshot;
2205
+ __webpack_unused_export__ = ({ value: true });
2206
+ exports.createOverlayDiv = createOverlayDiv;
2134
2207
  /**
2135
- * @see https://reactnative.dev/architecture/glossary#host-view-tree-and-host-view
2208
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
2209
+ *
2210
+ * This source code is licensed under the MIT license found in the
2211
+ * LICENSE file in the root directory of this source tree.
2212
+ *
2213
+ * @format
2214
+ * @oncall memory_lab
2136
2215
  */
2137
- const isHostFiber = (fiber) => fiber.tag === exports.HostComponentTag ||
2138
- // @ts-expect-error: it exists
2139
- fiber.tag === exports.HostHoistableTag ||
2140
- // @ts-expect-error: it exists
2141
- fiber.tag === exports.HostSingletonTag ||
2142
- typeof fiber.type === 'string';
2143
- exports.isHostFiber = isHostFiber;
2144
- const getNearestHostFiber = (fiber) => {
2145
- let hostFiber = (0, exports.traverseFiber)(fiber, exports.isHostFiber);
2146
- if (!hostFiber) {
2147
- hostFiber = (0, exports.traverseFiber)(fiber, exports.isHostFiber, true);
2148
- }
2149
- return hostFiber;
2216
+ const visual_utils_1 = __webpack_require__(498);
2217
+ function createOverlayDiv() {
2218
+ const overlayDiv = (0, visual_utils_1.createVisualizerElement)('div');
2219
+ overlayDiv.style.position = 'absolute';
2220
+ overlayDiv.style.top = '0px';
2221
+ overlayDiv.style.left = '0px';
2222
+ overlayDiv.id = 'memory-visualization-overlay';
2223
+ return overlayDiv;
2224
+ }
2225
+
2226
+
2227
+ /***/ },
2228
+
2229
+ /***/ 271
2230
+ (__unused_webpack_module, exports, __webpack_require__) {
2231
+
2232
+
2233
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2234
+ if (kind === "m") throw new TypeError("Private method is not writable");
2235
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
2236
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
2237
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
2150
2238
  };
2151
- exports.getNearestHostFiber = getNearestHostFiber;
2152
- const getTopMostHostFiber = (fiber) => {
2153
- let topMostHostFiber = null;
2154
- function checkFiber(fiber) {
2155
- if ((0, exports.isHostFiber)(fiber)) {
2156
- topMostHostFiber = fiber;
2157
- }
2158
- }
2159
- (0, exports.traverseFiber)(fiber, checkFiber, true);
2160
- return topMostHostFiber;
2239
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2240
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
2241
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
2242
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
2161
2243
  };
2162
- exports.getTopMostHostFiber = getTopMostHostFiber;
2163
- const getTopMostFiberWithChild = (fiber) => {
2164
- let topMostFiber = null;
2165
- function checkFiber(fiber) {
2166
- if (fiber.child != null) {
2167
- topMostFiber = fiber;
2244
+ var __importDefault = (this && this.__importDefault) || function (mod) {
2245
+ return (mod && mod.__esModule) ? mod : { "default": mod };
2246
+ };
2247
+ var _DOMElementVisualizerInteractive_instances, _DOMElementVisualizerInteractive_elementIdToRectangle, _DOMElementVisualizerInteractive_visualizationOverlayDiv, _DOMElementVisualizerInteractive_controlWidget, _DOMElementVisualizerInteractive_blockedElementIds, _DOMElementVisualizerInteractive_currentVisualData, _DOMElementVisualizerInteractive_hideAllRef, _DOMElementVisualizerInteractive_updateDataCallbacks, _DOMElementVisualizerInteractive_listenToKeyboardEvent, _DOMElementVisualizerInteractive_initVisualizerData, _DOMElementVisualizerInteractive_getOutlineElementByElementId, _DOMElementVisualizerInteractive_getElementIdSet, _DOMElementVisualizerInteractive_getComponentStackForElement, _DOMElementVisualizerInteractive_traverseUpOutlineElements, _DOMElementVisualizerInteractive_removeVisualizerElement, _DOMElementVisualizerInteractive_cleanup, _DOMElementVisualizerInteractive_getZIndex, _DOMElementVisualizerInteractive_paint, _DOMElementVisualizerInteractive_updateVisualizerData;
2248
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
2249
+ const dom_element_visualizer_1 = __importDefault(__webpack_require__(150));
2250
+ const visual_overlay_1 = __webpack_require__(368);
2251
+ const control_widget_1 = __webpack_require__(341);
2252
+ const overlay_rectangle_1 = __webpack_require__(701);
2253
+ const utils_1 = __webpack_require__(476);
2254
+ const visual_utils_1 = __webpack_require__(498);
2255
+ class DOMElementVisualizerInteractive extends dom_element_visualizer_1.default {
2256
+ constructor() {
2257
+ super();
2258
+ _DOMElementVisualizerInteractive_instances.add(this);
2259
+ _DOMElementVisualizerInteractive_elementIdToRectangle.set(this, void 0);
2260
+ _DOMElementVisualizerInteractive_visualizationOverlayDiv.set(this, void 0);
2261
+ _DOMElementVisualizerInteractive_controlWidget.set(this, void 0);
2262
+ _DOMElementVisualizerInteractive_blockedElementIds.set(this, void 0);
2263
+ _DOMElementVisualizerInteractive_currentVisualData.set(this, void 0);
2264
+ _DOMElementVisualizerInteractive_hideAllRef.set(this, void 0);
2265
+ _DOMElementVisualizerInteractive_updateDataCallbacks.set(this, []);
2266
+ __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_hideAllRef, { value: false }, "f");
2267
+ __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, (0, visual_overlay_1.createOverlayDiv)(), "f");
2268
+ (0, visual_utils_1.tryToAttachOverlay)(__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f"));
2269
+ __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_controlWidget, (0, control_widget_1.createControlWidget)(__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f"), __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_hideAllRef, "f"), cb => {
2270
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_updateDataCallbacks, "f").push(cb);
2271
+ }), "f");
2272
+ (0, visual_utils_1.tryToAttachOverlay)(__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_controlWidget, "f"));
2273
+ __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, new Map(), "f");
2274
+ __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_currentVisualData, __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_initVisualizerData).call(this), "f");
2275
+ __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_blockedElementIds, new Set(), "f");
2276
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_listenToKeyboardEvent).call(this);
2277
+ }
2278
+ repaint(domElementInfoList) {
2279
+ // this.#controlWidget.remove();
2280
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f").remove();
2281
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_cleanup).call(this, domElementInfoList);
2282
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_paint).call(this, domElementInfoList);
2283
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_updateVisualizerData).call(this);
2284
+ (0, visual_utils_1.tryToAttachOverlay)(__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f"));
2285
+ // tryToAttachOverlay(this.#controlWidget);
2286
+ }
2287
+ cleanup() {
2288
+ // Clean up the visualization overlay
2289
+ if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f")) {
2290
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f").remove();
2291
+ }
2292
+ // Clean up the control widget
2293
+ if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_controlWidget, "f")) {
2294
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_controlWidget, "f").remove();
2168
2295
  }
2296
+ // Clear all element references
2297
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").clear();
2298
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_blockedElementIds, "f").clear();
2299
+ __classPrivateFieldSet(this, _DOMElementVisualizerInteractive_updateDataCallbacks, [], "f");
2300
+ // Call parent cleanup
2301
+ super.cleanup();
2169
2302
  }
2170
- (0, exports.traverseFiber)(fiber, checkFiber, true);
2171
- return topMostFiber;
2172
- };
2173
- exports.getTopMostFiberWithChild = getTopMostFiberWithChild;
2174
- const traverseFiber = (fiber, selector, ascending = false) => {
2175
- if (!fiber) {
2303
+ }
2304
+ _DOMElementVisualizerInteractive_elementIdToRectangle = new WeakMap(), _DOMElementVisualizerInteractive_visualizationOverlayDiv = new WeakMap(), _DOMElementVisualizerInteractive_controlWidget = new WeakMap(), _DOMElementVisualizerInteractive_blockedElementIds = new WeakMap(), _DOMElementVisualizerInteractive_currentVisualData = new WeakMap(), _DOMElementVisualizerInteractive_hideAllRef = new WeakMap(), _DOMElementVisualizerInteractive_updateDataCallbacks = new WeakMap(), _DOMElementVisualizerInteractive_instances = new WeakSet(), _DOMElementVisualizerInteractive_listenToKeyboardEvent = function _DOMElementVisualizerInteractive_listenToKeyboardEvent() {
2305
+ document.addEventListener('keydown', event => {
2306
+ if (event.key === 'd' || event.key === 'D') {
2307
+ if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").selectedElementId != null) {
2308
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_blockedElementIds, "f").add(__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").selectedElementId);
2309
+ }
2310
+ }
2311
+ });
2312
+ }, _DOMElementVisualizerInteractive_initVisualizerData = function _DOMElementVisualizerInteractive_initVisualizerData() {
2313
+ const data = {
2314
+ detachedDOMElementsCount: 0,
2315
+ totalDOMElementsCount: (0, utils_1.getDOMElementCount)(),
2316
+ selectedElementId: null,
2317
+ selectedReactComponentStack: [],
2318
+ pinnedElementId: null,
2319
+ setPinnedElementId: (pinnedElementId) => {
2320
+ var _a, _b;
2321
+ if (data.pinnedElementId == pinnedElementId) {
2322
+ return;
2323
+ }
2324
+ // unpin the original pinned element
2325
+ const oldPin = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_getOutlineElementByElementId).call(this, data.pinnedElementId);
2326
+ (_a = oldPin === null || oldPin === void 0 ? void 0 : oldPin.__unpinned) === null || _a === void 0 ? void 0 : _a.call(oldPin);
2327
+ // pin the newly pinned element
2328
+ const newPin = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_getOutlineElementByElementId).call(this, pinnedElementId);
2329
+ (_b = newPin === null || newPin === void 0 ? void 0 : newPin.__pinned) === null || _b === void 0 ? void 0 : _b.call(newPin);
2330
+ data.pinnedElementId = pinnedElementId;
2331
+ },
2332
+ };
2333
+ return data;
2334
+ }, _DOMElementVisualizerInteractive_getOutlineElementByElementId = function _DOMElementVisualizerInteractive_getOutlineElementByElementId(elementId) {
2335
+ if (elementId == null) {
2176
2336
  return null;
2177
2337
  }
2178
- if (selector(fiber) === true) {
2179
- return fiber;
2338
+ const info = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get(elementId);
2339
+ if (info == null) {
2340
+ return null;
2180
2341
  }
2181
- let next = ascending ? fiber.return : fiber.child;
2182
- while (next) {
2183
- const match = (0, exports.traverseFiber)(next, selector, ascending);
2184
- if (match) {
2185
- return match;
2342
+ return info.visualizerElementRef.deref();
2343
+ }, _DOMElementVisualizerInteractive_getElementIdSet = function _DOMElementVisualizerInteractive_getElementIdSet(domElementInfoList) {
2344
+ const elementIdSet = new Set();
2345
+ for (const info of domElementInfoList) {
2346
+ const element = info.element.deref();
2347
+ if (element == null) {
2348
+ continue;
2186
2349
  }
2187
- next = ascending ? null : next.sibling;
2350
+ const elementId = element.detachedElementId;
2351
+ if (elementId == null) {
2352
+ continue;
2353
+ }
2354
+ elementIdSet.add(elementId);
2188
2355
  }
2189
- return null;
2190
- };
2191
- exports.traverseFiber = traverseFiber;
2192
- // React internal property keys
2193
- const internalKeys = [
2194
- '__reactFiber$', // React 17+
2195
- '__reactInternalInstance$', // React 16
2196
- '_reactRootContainer', // React Root
2197
- ];
2198
- const getOwnPropertyNames = Object.getOwnPropertyNames.bind(Object);
2199
- function getFiberNodeFromElement(element) {
2200
- for (const prefix of internalKeys) {
2201
- // Use Object.keys only as fallback since it's slower
2202
- const key = getOwnPropertyNames(element).find(k => k.startsWith(prefix));
2203
- if (key) {
2204
- return element[key];
2356
+ return elementIdSet;
2357
+ }, _DOMElementVisualizerInteractive_getComponentStackForElement = function _DOMElementVisualizerInteractive_getComponentStackForElement(elementId) {
2358
+ const ret = [];
2359
+ if (elementId == null) {
2360
+ return ret;
2361
+ }
2362
+ const visualizer = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get(elementId);
2363
+ if (visualizer == null) {
2364
+ return ret;
2365
+ }
2366
+ const element = visualizer.elementInfo.element.deref();
2367
+ if (element == null) {
2368
+ return ret;
2369
+ }
2370
+ // traverse parent elements
2371
+ let currentElement = element;
2372
+ while (currentElement) {
2373
+ if (currentElement.isConnected) {
2374
+ break;
2375
+ }
2376
+ const elementId = currentElement.detachedElementId;
2377
+ const info = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get(elementId);
2378
+ if (info == null) {
2379
+ break;
2205
2380
  }
2381
+ ret.push(info);
2382
+ currentElement = currentElement.parentElement;
2206
2383
  }
2207
- return null;
2208
- }
2209
- function getReactComponentStack(node) {
2210
- const stack = [];
2211
- const visited = new Set();
2212
- let fiber = node;
2213
- while (fiber) {
2214
- if (visited.has(fiber)) {
2384
+ return ret;
2385
+ }, _DOMElementVisualizerInteractive_traverseUpOutlineElements = function _DOMElementVisualizerInteractive_traverseUpOutlineElements(elementId, callback) {
2386
+ const visualizer = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get(elementId);
2387
+ if (visualizer == null) {
2388
+ return;
2389
+ }
2390
+ const visitedElementIds = new Set();
2391
+ let currentElement = visualizer.elementInfo.element.deref();
2392
+ while (currentElement) {
2393
+ if (currentElement.isConnected) {
2215
2394
  break;
2216
2395
  }
2217
- visited.add(fiber);
2218
- const name = getDisplayNameOfFiberNode(fiber);
2219
- if (name) {
2220
- stack.push(name);
2396
+ const elementIdStr = currentElement.detachedElementId;
2397
+ const elementId = parseInt(elementIdStr, 10);
2398
+ if (visitedElementIds.has(elementId)) {
2399
+ break;
2221
2400
  }
2222
- fiber = fiber.return;
2223
- }
2224
- return stack;
2225
- }
2226
- function getDisplayNameOfFiberNode(node) {
2227
- var _a, _b, _c, _d;
2228
- const elementType = (_a = node.type) !== null && _a !== void 0 ? _a : node.elementType;
2229
- // Try to get name from displayName or name properties
2230
- let displayName = (_b = elementType === null || elementType === void 0 ? void 0 : elementType.displayName) !== null && _b !== void 0 ? _b : elementType === null || elementType === void 0 ? void 0 : elementType.name;
2231
- // Handle class components and forwardRef
2232
- if (displayName == null) {
2233
- if (elementType === null || elementType === void 0 ? void 0 : elementType.render) {
2234
- // Class components
2235
- const render = elementType === null || elementType === void 0 ? void 0 : elementType.render;
2236
- displayName = (_c = render === null || render === void 0 ? void 0 : render.displayName) !== null && _c !== void 0 ? _c : render === null || render === void 0 ? void 0 : render.name;
2401
+ visitedElementIds.add(elementId);
2402
+ const visualizerInfo = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get(elementId);
2403
+ if (visualizerInfo == null) {
2404
+ break;
2237
2405
  }
2238
- else if (elementType === null || elementType === void 0 ? void 0 : elementType.type) {
2239
- // ForwardRef components
2240
- displayName = (_d = elementType.type.displayName) !== null && _d !== void 0 ? _d : elementType.type.name;
2406
+ const visualizerElement = visualizerInfo.visualizerElementRef.deref();
2407
+ if (visualizerElement == null) {
2408
+ break;
2241
2409
  }
2410
+ callback(visualizerElement);
2411
+ currentElement = currentElement.parentElement;
2242
2412
  }
2243
- // Handle anonymous functions
2244
- if (!displayName && typeof elementType === 'function') {
2245
- displayName = elementType.name;
2246
- }
2247
- const ret = (0, utils_1.getMeaningfulName)(extractReactComponentName(displayName));
2248
- return (0, valid_component_name_1.isValidComponentName)(ret) ? ret : null;
2249
- }
2250
- function isFunctionalComponent(node) {
2251
- const elementType = node === null || node === void 0 ? void 0 : node.elementType;
2252
- return typeof elementType === 'function';
2253
- }
2254
- // dom-element [from component.react] --> component.react
2255
- function extractReactComponentName(displayName) {
2256
- if (typeof displayName !== 'string') {
2257
- return null;
2258
- }
2259
- if (!displayName.includes('[') || !displayName.includes(']')) {
2260
- return displayName;
2413
+ }, _DOMElementVisualizerInteractive_removeVisualizerElement = function _DOMElementVisualizerInteractive_removeVisualizerElement(elementId) {
2414
+ var _a;
2415
+ const visualizer = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get(elementId);
2416
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").delete(elementId);
2417
+ if (visualizer == null) {
2418
+ return;
2261
2419
  }
2262
- const startIndex = displayName.indexOf('[');
2263
- const endIndex = displayName.indexOf(']');
2264
- if (startIndex > endIndex) {
2265
- return displayName;
2420
+ const visualizerElement = visualizer.visualizerElementRef.deref();
2421
+ if (visualizerElement == null) {
2422
+ return;
2266
2423
  }
2267
- const name = displayName.substring(startIndex + 1, endIndex);
2268
- if (name.startsWith('from ')) {
2269
- return name.substring('from '.length);
2424
+ // invoke the overlay specific code to clean
2425
+ (_a = visualizerElement === null || visualizerElement === void 0 ? void 0 : visualizerElement.__cleanup) === null || _a === void 0 ? void 0 : _a.call(visualizerElement);
2426
+ visualizerElement.remove();
2427
+ }, _DOMElementVisualizerInteractive_cleanup = function _DOMElementVisualizerInteractive_cleanup(domElementInfoList) {
2428
+ // first pass remove all those painted visualizer for elements
2429
+ // that either 1) is GCed or 2) is connected to the DOM tree
2430
+ for (const [elementId, elementVistualizer,] of __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").entries()) {
2431
+ if (elementId == null) {
2432
+ continue;
2433
+ }
2434
+ const element = elementVistualizer.elementInfo.element.deref();
2435
+ if (element == null) {
2436
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_removeVisualizerElement).call(this, elementId);
2437
+ }
2270
2438
  }
2271
- return name;
2272
- }
2273
-
2274
-
2275
- /***/ },
2276
-
2277
- /***/ 775
2278
- (__unused_webpack_module, exports, __webpack_require__) {
2279
-
2280
-
2281
- Object.defineProperty(exports, "__esModule", ({ value: true }));
2282
- exports.createStatusText = createStatusText;
2283
- const visual_utils_1 = __webpack_require__(498);
2284
- function formatBytes(bytes) {
2285
- if (bytes === 0)
2286
- return '0 B';
2287
- const k = 1024;
2288
- const sizes = ['B', 'KB', 'MB', 'GB'];
2289
- const i = Math.floor(Math.log(bytes) / Math.log(k));
2290
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
2291
- }
2292
- function createStatusText(registerDataUpdateCallback) {
2293
- const statusWidget = (0, visual_utils_1.createVisualizerElement)('div');
2294
- statusWidget.style.marginLeft = '10px';
2295
- statusWidget.style.color = 'white';
2296
- statusWidget.style.fontSize = '10px';
2297
- statusWidget.style.fontFamily = 'Inter, system-ui, sans-serif';
2298
- statusWidget.style.overflow = 'hidden';
2299
- statusWidget.style.whiteSpace = 'nowrap';
2300
- statusWidget.style.textOverflow = 'ellipsis';
2301
- statusWidget.textContent = '';
2302
- registerDataUpdateCallback((data) => {
2303
- var _a, _b, _c, _d;
2304
- const performance = window.performance;
2305
- const memory = performance === null || performance === void 0 ? void 0 : performance.memory;
2306
- const usedHeap = (_a = memory === null || memory === void 0 ? void 0 : memory.usedJSHeapSize) !== null && _a !== void 0 ? _a : 0;
2307
- const totalHeap = (_b = memory === null || memory === void 0 ? void 0 : memory.totalJSHeapSize) !== null && _b !== void 0 ? _b : 0;
2308
- const totalElements = (_c = data.totalDOMElementsCount) !== null && _c !== void 0 ? _c : 0;
2309
- const detachedElements = (_d = data.detachedDOMElementsCount) !== null && _d !== void 0 ? _d : 0;
2310
- statusWidget.textContent =
2311
- `DOM: ${totalElements} total, ${detachedElements} detached | ` +
2312
- `Heap: ${formatBytes(usedHeap)} / ${formatBytes(totalHeap)}`;
2313
- });
2314
- return statusWidget;
2315
- }
2316
-
2317
-
2318
- /***/ },
2319
-
2320
- /***/ 847
2321
- (__unused_webpack_module, exports) {
2322
-
2323
-
2324
- /**
2325
- * Copyright (c) Meta Platforms, Inc. and affiliates.
2326
- *
2327
- * This source code is licensed under the MIT license found in the
2328
- * LICENSE file in the root directory of this source tree.
2329
- *
2330
- * @format
2331
- * @oncall memory_lab
2332
- */
2333
- Object.defineProperty(exports, "__esModule", ({ value: true }));
2334
- exports.isValidComponentName = isValidComponentName;
2335
- const displayNameBlockList = new Set();
2336
- function isValidComponentName(name) {
2337
- return name != null && !displayNameBlockList.has(name);
2338
- }
2339
-
2340
-
2341
- /***/ },
2342
-
2343
- /***/ 860
2344
- (__unused_webpack_module, exports) {
2345
-
2346
-
2347
- Object.defineProperty(exports, "__esModule", ({ value: true }));
2348
- exports.BasicExtension = void 0;
2349
- /**
2350
- * Base class for React Memory Scanner extensions.
2351
- * Extensions can hook into the scanning process before and after analysis.
2352
- */
2353
- class BasicExtension {
2354
- constructor(scanner) {
2355
- this.scanner = scanner;
2439
+ // second pass remove all those outlines that won't be painted later
2440
+ const willPaintElementIdSet = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_getElementIdSet).call(this, domElementInfoList);
2441
+ for (const [elementId] of __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").entries()) {
2442
+ if (elementId == null) {
2443
+ continue;
2444
+ }
2445
+ if (willPaintElementIdSet.has(elementId) &&
2446
+ !__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_blockedElementIds, "f").has(elementId)) {
2447
+ continue;
2448
+ }
2449
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_removeVisualizerElement).call(this, elementId);
2356
2450
  }
2357
- /**
2358
- * Hook that runs before the memory scan starts.
2359
- * Override this method to perform any setup or pre-scan operations.
2360
- */
2361
- beforeScan() {
2362
- // to be overridden
2451
+ }, _DOMElementVisualizerInteractive_getZIndex = function _DOMElementVisualizerInteractive_getZIndex(info) {
2452
+ var _a;
2453
+ const zIndexBase = 9999;
2454
+ const element = info.element.deref();
2455
+ if (element == null) {
2456
+ return 0;
2363
2457
  }
2364
- /**
2365
- * Hook that runs after the memory scan completes.
2366
- * Override this method to process or modify the analysis results.
2367
- * @param analysisResult - The results from the memory scan
2368
- */
2369
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
2370
- afterScan(_analysisResult) {
2371
- // to be overridden
2458
+ const elementId = element.detachedElementId;
2459
+ if (elementId == null) {
2460
+ return 0;
2372
2461
  }
2373
- }
2374
- exports.BasicExtension = BasicExtension;
2375
-
2376
-
2377
- /***/ },
2378
-
2379
- /***/ 904
2380
- (__unused_webpack_module, exports, __webpack_require__) {
2381
-
2382
-
2383
- Object.defineProperty(exports, "__esModule", ({ value: true }));
2384
- exports.createComponentStackPanel = createComponentStackPanel;
2385
- const visual_utils_1 = __webpack_require__(498);
2386
- function createComponentStackPanel(registerDataUpdateCallback) {
2387
- const panel = (0, visual_utils_1.createVisualizerElement)('div');
2388
- panel.style.width = '100%';
2389
- // Ensure max height is at most 80% of viewport height
2390
- panel.style.maxHeight = '80vh';
2391
- panel.style.background = 'rgba(0, 0, 0, 0.5)';
2392
- panel.style.borderTop = '1px solid rgba(255, 255, 255, 0.1)';
2393
- panel.style.display = 'none';
2394
- panel.style.flexDirection = 'column';
2395
- panel.style.padding = '8px';
2396
- panel.style.boxSizing = 'border-box';
2397
- panel.style.borderRadius = '8px';
2398
- panel.style.overflowY = 'scroll';
2399
- panel.style.overflowX = 'hidden';
2400
- panel.style.textShadow = 'none';
2401
- panel.style.font = '9px Inter, system-ui, -apple-system, sans-serif';
2402
- panel.style.color = 'white';
2403
- panel.id = 'memory-visualization-component-stack-panel';
2404
- let pinned = false;
2405
- panel.addEventListener('mouseenter', () => {
2406
- pinned = true;
2407
- });
2408
- panel.addEventListener('mouseleave', () => {
2409
- pinned = false;
2410
- });
2411
- // Register data update callback to update component stack panel
2412
- registerDataUpdateCallback((0, visual_utils_1.debounce)((data) => {
2413
- var _a;
2414
- if (pinned) {
2415
- return;
2462
+ const rectangle = (_a = info.boundingRect) !== null && _a !== void 0 ? _a : { width: 50, height: 50 };
2463
+ let ret = zIndexBase;
2464
+ // element with a higher element id (created later) has a higher z-index
2465
+ ret += parseInt(elementId, 10);
2466
+ // element with bigger area will have a lower z-index
2467
+ ret += Math.floor(10000000 / (rectangle.width * rectangle.height));
2468
+ return ret;
2469
+ }, _DOMElementVisualizerInteractive_paint = function _DOMElementVisualizerInteractive_paint(domElementInfoList) {
2470
+ for (const info of domElementInfoList) {
2471
+ const element = info.element.deref();
2472
+ if (element == null) {
2473
+ continue;
2416
2474
  }
2417
- panel.innerHTML = '';
2418
- if (data.selectedElementId == null ||
2419
- !((_a = data.selectedReactComponentStack) === null || _a === void 0 ? void 0 : _a.length)) {
2420
- panel.style.display = 'none';
2421
- return;
2475
+ const elementId = element.detachedElementId;
2476
+ if (elementId == null) {
2477
+ continue;
2422
2478
  }
2423
- panel.style.display = 'flex';
2424
- const title = (0, visual_utils_1.createVisualizerElement)('div');
2425
- title.textContent = 'Component Stack:';
2426
- title.style.fontWeight = 'bold';
2427
- title.style.marginBottom = '8px';
2428
- panel.appendChild(title);
2429
- let actualComponentStackLength = 0;
2430
- data.selectedReactComponentStack.forEach((component) => {
2431
- const componentDiv = (0, visual_utils_1.createVisualizerElement)('div');
2432
- componentDiv.style.marginBottom = '4px';
2433
- componentDiv.textContent = component;
2434
- panel.appendChild(componentDiv);
2435
- ++actualComponentStackLength;
2436
- });
2437
- if (actualComponentStackLength === 0) {
2438
- title.remove();
2479
+ if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_blockedElementIds, "f").has(elementId)) {
2480
+ continue;
2439
2481
  }
2440
- }, 1));
2441
- return panel;
2442
- }
2443
-
2444
-
2445
- /***/ },
2446
-
2447
- /***/ 933
2448
- (__unused_webpack_module, exports, __webpack_require__) {
2449
-
2450
-
2451
- var __importDefault = (this && this.__importDefault) || function (mod) {
2452
- return (mod && mod.__esModule) ? mod : { "default": mod };
2453
- };
2454
- Object.defineProperty(exports, "__esModule", ({ value: true }));
2455
- /**
2456
- * Copyright (c) Meta Platforms, Inc. and affiliates.
2457
- *
2458
- * This source code is licensed under the MIT license found in the
2459
- * LICENSE file in the root directory of this source tree.
2460
- *
2461
- * @format
2462
- * @oncall memory_lab
2463
- */
2464
- const react_memory_scan_1 = __importDefault(__webpack_require__(282));
2465
- const dom_visualization_extension_1 = __webpack_require__(23);
2466
- const utils_1 = __webpack_require__(476);
2467
- if (!(0, utils_1.hasRunInSession)()) {
2468
- const memoryScan = new react_memory_scan_1.default({ isDevMode: true });
2469
- const domVisualizer = new dom_visualization_extension_1.DOMVisualizationExtension(memoryScan);
2470
- memoryScan.registerExtension(domVisualizer);
2471
- memoryScan.start();
2472
- (0, utils_1.setRunInSession)();
2473
- }
2474
-
2475
-
2476
- /***/ },
2477
-
2478
- /***/ 946
2479
- (__unused_webpack_module, exports, __webpack_require__) {
2480
-
2481
-
2482
- Object.defineProperty(exports, "__esModule", ({ value: true }));
2483
- exports.createToggleButton = createToggleButton;
2484
- /**
2485
- * Copyright (c) Meta Platforms, Inc. and affiliates.
2486
- *
2487
- * This source code is licensed under the MIT license found in the
2488
- * LICENSE file in the root directory of this source tree.
2489
- *
2490
- * @format
2491
- * @oncall memory_lab
2492
- */
2493
- const visual_utils_1 = __webpack_require__(498);
2494
- function createToggleButton(overlayDiv, hideAllRef) {
2495
- const toggleWrapper = (0, visual_utils_1.createVisualizerElement)('div');
2496
- toggleWrapper.style.width = '40px';
2497
- toggleWrapper.style.height = '24px';
2498
- toggleWrapper.style.borderRadius = '9999px';
2499
- toggleWrapper.style.backgroundColor = '#34C759'; // ON by default
2500
- toggleWrapper.style.cursor = 'pointer';
2501
- toggleWrapper.style.position = 'relative';
2502
- toggleWrapper.style.transition = 'background-color 0.3s ease';
2503
- const knob = (0, visual_utils_1.createVisualizerElement)('div');
2504
- knob.style.width = '18px';
2505
- knob.style.height = '18px';
2506
- knob.style.backgroundColor = 'white';
2507
- knob.style.borderRadius = '50%';
2508
- knob.style.position = 'absolute';
2509
- knob.style.top = '3px';
2510
- knob.style.left = '3px'; // ON position
2511
- knob.style.transition = 'left 0.25s ease';
2512
- toggleWrapper.appendChild(knob);
2513
- toggleWrapper.addEventListener('click', () => {
2514
- hideAllRef.value = !hideAllRef.value;
2515
- if (hideAllRef.value) {
2516
- // OFF state
2517
- overlayDiv.style.display = 'none';
2518
- overlayDiv.style.pointerEvents = 'none';
2519
- overlayDiv.style.userSelect = 'none';
2520
- knob.style.left = '19px';
2521
- toggleWrapper.style.backgroundColor = '#FF3B30'; // Apple red
2482
+ if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").has(elementId)) {
2483
+ continue;
2522
2484
  }
2523
- else {
2524
- // ON state
2525
- overlayDiv.style.display = 'block';
2526
- overlayDiv.style.pointerEvents = 'auto';
2527
- overlayDiv.style.userSelect = 'auto';
2528
- knob.style.left = '3px';
2529
- toggleWrapper.style.backgroundColor = '#34C759'; // Apple green
2485
+ if (element == null) {
2486
+ continue;
2530
2487
  }
2531
- });
2532
- return toggleWrapper;
2533
- }
2488
+ if (element.isConnected) {
2489
+ continue;
2490
+ }
2491
+ const zIndex = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_getZIndex).call(this, info);
2492
+ const visualizerElementRef = (0, overlay_rectangle_1.createOverlayRectangle)(elementId, info, __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_visualizationOverlayDiv, "f"), (selectedId) => {
2493
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").selectedElementId = selectedId;
2494
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_updateVisualizerData).call(this);
2495
+ if (selectedId == null) {
2496
+ return;
2497
+ }
2498
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_traverseUpOutlineElements).call(this, selectedId, element => {
2499
+ var _a;
2500
+ (_a = element === null || element === void 0 ? void 0 : element.__selected) === null || _a === void 0 ? void 0 : _a.call(element);
2501
+ });
2502
+ }, (unselectedId) => {
2503
+ if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").selectedElementId === unselectedId) {
2504
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").selectedElementId = null;
2505
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_updateVisualizerData).call(this);
2506
+ }
2507
+ if (unselectedId == null) {
2508
+ return;
2509
+ }
2510
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_traverseUpOutlineElements).call(this, unselectedId, element => {
2511
+ var _a;
2512
+ (_a = element === null || element === void 0 ? void 0 : element.__unselected) === null || _a === void 0 ? void 0 : _a.call(element);
2513
+ });
2514
+ }, (clickedId) => {
2515
+ if (__classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").pinnedElementId === clickedId) {
2516
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").setPinnedElementId(null);
2517
+ }
2518
+ else {
2519
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f").setPinnedElementId(clickedId);
2520
+ }
2521
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_instances, "m", _DOMElementVisualizerInteractive_updateVisualizerData).call(this);
2522
+ }, zIndex);
2523
+ if (visualizerElementRef == null ||
2524
+ visualizerElementRef.deref() == null) {
2525
+ return null;
2526
+ }
2527
+ const visualizer = {
2528
+ elementInfo: info,
2529
+ visualizerElementRef,
2530
+ };
2531
+ __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").set(elementId, visualizer);
2532
+ }
2533
+ }, _DOMElementVisualizerInteractive_updateVisualizerData = function _DOMElementVisualizerInteractive_updateVisualizerData() {
2534
+ var _a, _b, _c;
2535
+ const data = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f");
2536
+ if (data.pinnedElementId != null) {
2537
+ data.selectedElementId = data.pinnedElementId;
2538
+ }
2539
+ data.detachedDOMElementsCount = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").size;
2540
+ data.totalDOMElementsCount = (0, utils_1.getDOMElementCount)();
2541
+ const selectedElementInfo = (_b = __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_elementIdToRectangle, "f").get((_a = data.selectedElementId) !== null && _a !== void 0 ? _a : -1)) === null || _b === void 0 ? void 0 : _b.elementInfo;
2542
+ data.selectedReactComponentStack =
2543
+ (_c = selectedElementInfo === null || selectedElementInfo === void 0 ? void 0 : selectedElementInfo.componentStack) !== null && _c !== void 0 ? _c : [];
2544
+ for (const cb of __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_updateDataCallbacks, "f")) {
2545
+ cb(Object.assign({}, __classPrivateFieldGet(this, _DOMElementVisualizerInteractive_currentVisualData, "f")));
2546
+ }
2547
+ };
2548
+ exports["default"] = DOMElementVisualizerInteractive;
2534
2549
 
2535
2550
 
2536
2551
  /***/ },
2537
2552
 
2538
- /***/ 953
2553
+ /***/ 150
2539
2554
  (__unused_webpack_module, exports, __webpack_require__) {
2540
2555
 
2541
2556
 
@@ -2547,186 +2562,186 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
2547
2562
  };
2548
2563
  var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2549
2564
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
2550
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
2551
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
2552
- };
2553
- var _EventListenerTracker_instances, _EventListenerTracker_listenerMap, _EventListenerTracker_detachedListeners, _EventListenerTracker_originalAddEventListener, _EventListenerTracker_originalRemoveEventListener, _EventListenerTracker_patchEventListeners, _EventListenerTracker_unpatchEventListeners;
2554
- Object.defineProperty(exports, "__esModule", ({ value: true }));
2555
- exports.EventListenerTracker = void 0;
2556
- const react_fiber_utils_1 = __webpack_require__(737);
2557
- const weak_ref_utils_1 = __webpack_require__(313);
2558
- class EventListenerTracker {
2559
- constructor() {
2560
- _EventListenerTracker_instances.add(this);
2561
- _EventListenerTracker_listenerMap.set(this, void 0);
2562
- _EventListenerTracker_detachedListeners.set(this, void 0);
2563
- _EventListenerTracker_originalAddEventListener.set(this, void 0);
2564
- _EventListenerTracker_originalRemoveEventListener.set(this, void 0);
2565
- __classPrivateFieldSet(this, _EventListenerTracker_listenerMap, new weak_ref_utils_1.WeakMapPlus({ fallback: 'noop', cleanupMs: 100 }), "f");
2566
- __classPrivateFieldSet(this, _EventListenerTracker_detachedListeners, new Map(), "f");
2567
- __classPrivateFieldSet(this, _EventListenerTracker_originalAddEventListener, EventTarget.prototype.addEventListener, "f");
2568
- __classPrivateFieldSet(this, _EventListenerTracker_originalRemoveEventListener, EventTarget.prototype.removeEventListener, "f");
2569
- __classPrivateFieldGet(this, _EventListenerTracker_instances, "m", _EventListenerTracker_patchEventListeners).call(this);
2570
- }
2571
- static getInstance() {
2572
- if (!EventListenerTracker.instance) {
2573
- EventListenerTracker.instance = new EventListenerTracker();
2574
- }
2575
- return EventListenerTracker.instance;
2576
- }
2577
- addListener(el, type, cb, options) {
2578
- el.addEventListener(type, cb, options);
2579
- }
2580
- removeListener(el, type, cb, options) {
2581
- el.removeEventListener(type, cb, options);
2582
- }
2583
- scan(getComponentName) {
2584
- const detachedListeners = new Map();
2585
- for (const [el, listeners] of __classPrivateFieldGet(this, _EventListenerTracker_listenerMap, "f").entries()) {
2586
- if (el instanceof Element && !el.isConnected) {
2587
- for (const listener of listeners) {
2588
- // Skip if the callback has been garbage collected
2589
- if (!listener.cb.deref())
2590
- continue;
2591
- const componentName = getComponentName(new WeakRef(el));
2592
- if (!detachedListeners.has(componentName)) {
2593
- detachedListeners.set(componentName, []);
2594
- }
2595
- const groups = detachedListeners.get(componentName);
2596
- let group = groups === null || groups === void 0 ? void 0 : groups.find(g => g.type === listener.type);
2597
- if (!group) {
2598
- group = {
2599
- type: listener.type,
2600
- count: 0,
2601
- entries: [],
2602
- };
2603
- groups === null || groups === void 0 ? void 0 : groups.push(group);
2604
- }
2605
- group.count++;
2606
- group.entries.push(new WeakRef(listener));
2607
- }
2608
- }
2609
- }
2610
- __classPrivateFieldSet(this, _EventListenerTracker_detachedListeners, detachedListeners, "f");
2611
- return detachedListeners;
2565
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
2566
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
2567
+ };
2568
+ var _DOMElementVisualizer_instances, _DOMElementVisualizer_canvas, _DOMElementVisualizer_paint, _DOMElementVisualizer_cleanupExistingCanvas, _DOMElementVisualizer_tryToAttachCanvas, _DOMElementVisualizer_createAndAppendCanvas, _DOMElementVisualizer_paintKey, _DOMElementVisualizer_paintRectangles, _DOMElementVisualizer_cleanup;
2569
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
2570
+ const visual_utils_1 = __webpack_require__(498);
2571
+ class DOMElementVisualizer {
2572
+ constructor() {
2573
+ _DOMElementVisualizer_instances.add(this);
2574
+ _DOMElementVisualizer_canvas.set(this, void 0);
2575
+ __classPrivateFieldSet(this, _DOMElementVisualizer_canvas, null, "f");
2612
2576
  }
2613
- getDetachedListeners() {
2614
- return __classPrivateFieldGet(this, _EventListenerTracker_detachedListeners, "f");
2577
+ cleanup() {
2578
+ __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_cleanup).call(this);
2615
2579
  }
2616
- destroy() {
2617
- __classPrivateFieldGet(this, _EventListenerTracker_instances, "m", _EventListenerTracker_unpatchEventListeners).call(this);
2618
- __classPrivateFieldGet(this, _EventListenerTracker_listenerMap, "f").destroy();
2619
- __classPrivateFieldGet(this, _EventListenerTracker_detachedListeners, "f").clear();
2620
- EventListenerTracker.instance = null;
2580
+ repaint(domElementInfoList) {
2581
+ __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_cleanup).call(this);
2582
+ __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_paint).call(this, domElementInfoList);
2621
2583
  }
2622
2584
  }
2623
- exports.EventListenerTracker = EventListenerTracker;
2624
- _EventListenerTracker_listenerMap = new WeakMap(), _EventListenerTracker_detachedListeners = new WeakMap(), _EventListenerTracker_originalAddEventListener = new WeakMap(), _EventListenerTracker_originalRemoveEventListener = new WeakMap(), _EventListenerTracker_instances = new WeakSet(), _EventListenerTracker_patchEventListeners = function _EventListenerTracker_patchEventListeners() {
2625
- // eslint-disable-next-line @typescript-eslint/no-this-alias
2626
- const self = this;
2627
- EventTarget.prototype.addEventListener = function (type, listener, options) {
2585
+ _DOMElementVisualizer_canvas = new WeakMap(), _DOMElementVisualizer_instances = new WeakSet(), _DOMElementVisualizer_paint = function _DOMElementVisualizer_paint(domElementInfoList) {
2586
+ if (!__classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f")) {
2587
+ const canvas = __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_createAndAppendCanvas).call(this);
2588
+ __classPrivateFieldSet(this, _DOMElementVisualizer_canvas, canvas, "f");
2589
+ }
2590
+ __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_paintRectangles).call(this, domElementInfoList);
2591
+ }, _DOMElementVisualizer_cleanupExistingCanvas = function _DOMElementVisualizer_cleanupExistingCanvas() {
2592
+ // Clean up any existing canvas
2593
+ if (__classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f")) {
2594
+ const ctx = __classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f").getContext('2d');
2595
+ ctx === null || ctx === void 0 ? void 0 : ctx.clearRect(0, 0, __classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f").width, __classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f").height);
2596
+ __classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f").remove();
2597
+ __classPrivateFieldSet(this, _DOMElementVisualizer_canvas, null, "f");
2598
+ }
2599
+ }, _DOMElementVisualizer_tryToAttachCanvas = function _DOMElementVisualizer_tryToAttachCanvas(canvas) {
2600
+ if (document.body) {
2601
+ document.body.appendChild(canvas);
2602
+ }
2603
+ }, _DOMElementVisualizer_createAndAppendCanvas = function _DOMElementVisualizer_createAndAppendCanvas() {
2604
+ // Create and insert the canvas element
2605
+ const canvas = (0, visual_utils_1.createVisualizerElement)('canvas');
2606
+ canvas.id = 'overlayCanvas';
2607
+ __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_tryToAttachCanvas).call(this, canvas);
2608
+ // Style the canvas to cover the entire page
2609
+ canvas.style.position = 'absolute';
2610
+ canvas.style.top = '0';
2611
+ canvas.style.left = '0';
2612
+ canvas.style.width = '100%';
2613
+ canvas.style.height = '100%';
2614
+ canvas.style.pointerEvents = 'none';
2615
+ canvas.style.zIndex = '99999';
2616
+ // Set canvas dimensions to match the window dimensions
2617
+ canvas.width = window.innerWidth;
2618
+ canvas.height = window.innerHeight;
2619
+ return canvas;
2620
+ }, _DOMElementVisualizer_paintKey = function _DOMElementVisualizer_paintKey(info) {
2621
+ const { boundingRect } = info;
2622
+ return JSON.stringify({ boundingRect });
2623
+ }, _DOMElementVisualizer_paintRectangles = function _DOMElementVisualizer_paintRectangles(domElementInfoList) {
2624
+ const canvas = __classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f");
2625
+ if (!canvas) {
2626
+ return;
2627
+ }
2628
+ // Get the 2D drawing context
2629
+ const ctx = canvas.getContext('2d');
2630
+ if (ctx == null) {
2631
+ return;
2632
+ }
2633
+ // Set rectangle styles
2634
+ ctx.strokeStyle = 'rgba(75, 192, 192, 0.8)';
2635
+ ctx.lineWidth = 2;
2636
+ ctx.fillStyle = 'rgba(75, 192, 192, 0.05)';
2637
+ ctx.font = '11px Inter, system-ui, -apple-system, sans-serif';
2638
+ const paintedInfo = new Set();
2639
+ // Draw the rectangles
2640
+ domElementInfoList.forEach((info) => {
2628
2641
  var _a;
2629
- __classPrivateFieldGet(self, _EventListenerTracker_originalAddEventListener, "f").call(this, type, listener, options);
2630
- if (this instanceof Element) {
2631
- const fiber = (0, react_fiber_utils_1.getFiberNodeFromElement)(this);
2632
- const entry = {
2633
- type,
2634
- cb: new WeakRef(listener),
2635
- options,
2636
- fiber: fiber ? new WeakRef(fiber) : undefined,
2637
- };
2638
- const listeners = (_a = __classPrivateFieldGet(self, _EventListenerTracker_listenerMap, "f").get(this)) !== null && _a !== void 0 ? _a : [];
2639
- listeners.push(entry);
2640
- __classPrivateFieldGet(self, _EventListenerTracker_listenerMap, "f").set(this, listeners);
2642
+ const rect = info.boundingRect;
2643
+ if (rect == null) {
2644
+ return;
2641
2645
  }
2642
- };
2643
- EventTarget.prototype.removeEventListener = function (type, listener, options) {
2644
- __classPrivateFieldGet(self, _EventListenerTracker_originalRemoveEventListener, "f").call(this, type, listener, options);
2645
- if (this instanceof Element) {
2646
- const listeners = __classPrivateFieldGet(self, _EventListenerTracker_listenerMap, "f").get(this);
2647
- if (listeners) {
2648
- const index = listeners.findIndex(entry => entry.type === type &&
2649
- entry.cb.deref() === listener &&
2650
- entry.options === options);
2651
- if (index !== -1) {
2652
- listeners.splice(index, 1);
2653
- }
2654
- if (listeners.length === 0) {
2655
- __classPrivateFieldGet(self, _EventListenerTracker_listenerMap, "f").delete(this);
2656
- }
2657
- else {
2658
- __classPrivateFieldGet(self, _EventListenerTracker_listenerMap, "f").set(this, listeners);
2659
- }
2660
- }
2646
+ const key = __classPrivateFieldGet(this, _DOMElementVisualizer_instances, "m", _DOMElementVisualizer_paintKey).call(this, info);
2647
+ if (paintedInfo.has(key)) {
2648
+ return;
2661
2649
  }
2662
- };
2663
- }, _EventListenerTracker_unpatchEventListeners = function _EventListenerTracker_unpatchEventListeners() {
2664
- EventTarget.prototype.addEventListener = __classPrivateFieldGet(this, _EventListenerTracker_originalAddEventListener, "f");
2665
- EventTarget.prototype.removeEventListener =
2666
- __classPrivateFieldGet(this, _EventListenerTracker_originalRemoveEventListener, "f");
2650
+ paintedInfo.add(key);
2651
+ ctx.fillRect(rect.left, rect.top, rect.width, rect.height);
2652
+ ctx.strokeRect(rect.left, rect.top, rect.width, rect.height);
2653
+ const component = (_a = info.componentStack) === null || _a === void 0 ? void 0 : _a[0];
2654
+ if (component) {
2655
+ // attach detached element id key so that it is easy to search in heap snapshot
2656
+ const element = info.element.deref();
2657
+ const elementId = element === null || element === void 0 ? void 0 : element.detachedElementId;
2658
+ const elementIdText = elementId ? ` (${elementId})` : '';
2659
+ const text = `${component}${elementIdText}`;
2660
+ ctx.fillStyle = 'rgba(74, 131, 224, 1)';
2661
+ ctx.fillText(text, rect.left + 5, rect.top + 15); // Draw the name
2662
+ ctx.fillStyle = 'rgba(75, 192, 192, 0.05)';
2663
+ }
2664
+ });
2665
+ }, _DOMElementVisualizer_cleanup = function _DOMElementVisualizer_cleanup() {
2666
+ var _a;
2667
+ const canvas = __classPrivateFieldGet(this, _DOMElementVisualizer_canvas, "f");
2668
+ if (canvas) {
2669
+ const ctx = canvas.getContext('2d');
2670
+ ctx === null || ctx === void 0 ? void 0 : ctx.clearRect(0, 0, canvas.width, canvas.height);
2671
+ (_a = canvas.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(canvas);
2672
+ }
2673
+ __classPrivateFieldSet(this, _DOMElementVisualizer_canvas, null, "f");
2667
2674
  };
2668
- EventListenerTracker.instance = null;
2675
+ exports["default"] = DOMElementVisualizer;
2669
2676
 
2670
2677
 
2671
2678
  /***/ },
2672
2679
 
2673
- /***/ 979
2680
+ /***/ 498
2674
2681
  (__unused_webpack_module, exports) {
2675
2682
 
2683
+ var __webpack_unused_export__;
2676
2684
 
2677
- Object.defineProperty(exports, "__esModule", ({ value: true }));
2678
- exports.IntersectionObserverManager = void 0;
2679
- /**
2680
- * Copyright (c) Meta Platforms, Inc. and affiliates.
2681
- *
2682
- * This source code is licensed under the MIT license found in the
2683
- * LICENSE file in the root directory of this source tree.
2684
- *
2685
- * @format
2686
- * @oncall memory_lab
2687
- */
2688
- class IntersectionObserverManager {
2689
- constructor() {
2690
- this.observedElements = new Map();
2691
- this.observer = new IntersectionObserver(entries => {
2692
- entries.forEach((entry) => {
2693
- const element = entry.target;
2694
- const callback = this.observedElements.get(element);
2695
- if (callback) {
2696
- callback(entry);
2697
- }
2698
- });
2699
- }, {
2700
- // Only trigger when element is completely out of viewport
2701
- threshold: 0,
2702
- // Add some margin to trigger before element is completely out of view
2703
- rootMargin: '50px',
2704
- });
2685
+ __webpack_unused_export__ = ({ value: true });
2686
+ exports.isVisualizerElement = isVisualizerElement;
2687
+ exports.createVisualizerElement = createVisualizerElement;
2688
+ exports.tryToAttachOverlay = tryToAttachOverlay;
2689
+ exports.addTrackedListener = addTrackedListener;
2690
+ exports.removeAllListeners = removeAllListeners;
2691
+ exports.debounce = debounce;
2692
+ const VISUALIZER_DATA_ATTR = 'data-visualizer';
2693
+ function setVisualizerElement(element) {
2694
+ element.setAttribute(VISUALIZER_DATA_ATTR, 'true');
2695
+ element.setAttribute('data-visualcompletion', 'ignore');
2696
+ }
2697
+ function isVisualizerElement(element) {
2698
+ return element.getAttribute(VISUALIZER_DATA_ATTR) === 'true';
2699
+ }
2700
+ function createVisualizerElement(tag) {
2701
+ const element = document.createElement(tag);
2702
+ setVisualizerElement(element);
2703
+ return element;
2704
+ }
2705
+ function tryToAttachOverlay(overlayDiv) {
2706
+ if (document.body) {
2707
+ document.body.appendChild(overlayDiv);
2705
2708
  }
2706
- static getInstance() {
2707
- if (!IntersectionObserverManager.instance) {
2708
- IntersectionObserverManager.instance = new IntersectionObserverManager();
2709
- }
2710
- return IntersectionObserverManager.instance;
2709
+ }
2710
+ const listenerMap = new WeakMap();
2711
+ function addTrackedListener(elRef, type, cb, options) {
2712
+ var _a;
2713
+ const el = elRef.deref();
2714
+ if (!el)
2715
+ return;
2716
+ el.addEventListener(type, cb, options);
2717
+ if (!listenerMap.has(el)) {
2718
+ listenerMap.set(el, []);
2711
2719
  }
2712
- observe(elementRef, callback) {
2713
- const element = elementRef.deref();
2714
- if (element == null) {
2715
- return;
2716
- }
2717
- this.observedElements.set(element, callback);
2718
- this.observer.observe(element);
2720
+ (_a = listenerMap.get(el)) === null || _a === void 0 ? void 0 : _a.push({ type, cb, options });
2721
+ }
2722
+ function removeAllListeners(elRef) {
2723
+ const el = elRef.deref();
2724
+ if (!el)
2725
+ return;
2726
+ const listeners = listenerMap.get(el);
2727
+ if (!listeners)
2728
+ return;
2729
+ for (const { type, cb, options } of listeners) {
2730
+ el.removeEventListener(type, cb, options);
2719
2731
  }
2720
- unobserve(elementRef) {
2721
- const element = elementRef.deref();
2722
- if (element == null) {
2723
- return;
2732
+ listenerMap.delete(el);
2733
+ }
2734
+ function debounce(callback, delay) {
2735
+ let timer = null;
2736
+ return (...args) => {
2737
+ if (timer) {
2738
+ clearTimeout(timer);
2724
2739
  }
2725
- this.observedElements.delete(element);
2726
- this.observer.unobserve(element);
2727
- }
2740
+ timer = setTimeout(() => {
2741
+ callback(...args);
2742
+ }, delay);
2743
+ };
2728
2744
  }
2729
- exports.IntersectionObserverManager = IntersectionObserverManager;
2730
2745
 
2731
2746
 
2732
2747
  /***/ }