@memlab/lens 2.0.2 → 2.0.4

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