@memlab/lens 1.0.2 → 2.0.0
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.
- package/README.md +136 -38
- package/dist/core/react-memory-scan.d.ts +1 -0
- package/dist/extensions/dom-visualization-extension.d.ts +1 -0
- package/dist/index.js +10 -10
- package/dist/memlens.lib.bundle.js +104 -39
- package/dist/memlens.lib.bundle.min.js +26 -1
- package/dist/memlens.run.bundle.js +169 -74
- package/dist/memlens.run.bundle.min.js +26 -1
- package/dist/visual/dom-element-visualizer-interactive.d.ts +1 -0
- package/dist/visual/dom-element-visualizer.d.ts +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,63 +1,161 @@
|
|
|
1
1
|
# MemLens
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
MemLens is a lightweight, in-browser lens for spotting memory issues in React apps. It detects and visualizes:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- Detached DOM elements still retained in memory
|
|
6
|
+
- Unmounted React Fiber nodes that may indicate leaks
|
|
7
|
+
- Event listener leaks (optional)
|
|
8
|
+
- High-level DOM and heap usage stats (overlay header)
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
- Unmounted React Fiber nodes that haven't been properly cleaned up
|
|
9
|
-
- Memory usage patterns and growth over time
|
|
10
|
+
It can run as a one-line console snippet or as a small library you embed in dev builds.
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
### Key features
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
- **Visual overlay**: Highlights detached DOM elements; interactive panel shows counts and the React component stack for the selected element
|
|
15
|
+
- **React Fiber analysis**: Scans the fiber tree to attribute elements to components
|
|
16
|
+
- **Event listener leak scan (opt-in)**: Groups leaked listeners by component and type
|
|
17
|
+
- **Non-intrusive**: Uses a transparent overlay and avoids tracking its own UI
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
- Components that aren't properly cleaned up
|
|
19
|
+
### Browser support
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
- Requires browsers with WeakRef/FinalizationRegistry support (e.g. modern Chrome, Edge, Safari, Firefox). In older browsers the tool may not function.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
### Quick start
|
|
26
|
+
|
|
27
|
+
#### Option A: Run from the browser console (CDN)
|
|
28
|
+
|
|
29
|
+
Paste this in your app page:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
(() => {
|
|
33
|
+
const s = document.createElement('script');
|
|
34
|
+
s.src = 'https://unpkg.com/@memlab/lens/dist/memlens.run.bundle.min.js';
|
|
35
|
+
s.crossOrigin = 'anonymous';
|
|
36
|
+
document.head.appendChild(s);
|
|
37
|
+
})();
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This injects and starts MemLens with the interactive overlay.
|
|
41
|
+
|
|
42
|
+
#### Option B: Run from the browser console (local build)
|
|
43
|
+
|
|
44
|
+
Copy the contents of `packages/lens/dist/memlens.run.bundle.min.js` (or `packages/lens/dist/memlens.run.bundle.js`) and paste into the browser's web console. The overlay starts immediately.
|
|
45
|
+
|
|
46
|
+
#### Option C: Programmatic scanner (UMD global)
|
|
47
|
+
|
|
48
|
+
Load the library bundle and use the `MemLens` global:
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<script src="https://unpkg.com/@memlab/lens/dist/memlens.lib.bundle.min.js"></script>
|
|
52
|
+
<script>
|
|
53
|
+
// Create a scanner (no overlay by default; use the run bundle for overlay)
|
|
54
|
+
const scan = MemLens.createReactMemoryScan({
|
|
55
|
+
isDevMode: true,
|
|
56
|
+
scanIntervalMs: 1000,
|
|
57
|
+
trackEventListenerLeaks: true, // optional
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const unsubscribe = scan.subscribe((result) => {
|
|
61
|
+
console.log('[MemLens]', {
|
|
62
|
+
totalElements: result.totalElements,
|
|
63
|
+
detached: result.totalDetachedElements,
|
|
64
|
+
eventListenerLeaks: result.eventListenerLeaks,
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
scan.start();
|
|
69
|
+
|
|
70
|
+
// Later: scan.stop(); unsubscribe(); scan.dispose();
|
|
71
|
+
</script>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Note: The visualization overlay is provided by the self-starting "run" bundle (Option A/B/D). The library bundle focuses on scanning APIs.
|
|
75
|
+
|
|
76
|
+
#### Option D: Node/Puppeteer injection
|
|
77
|
+
|
|
78
|
+
`@memlab/lens` exposes a helper to retrieve the self-starting bundle as a string for script injection:
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
// Node
|
|
82
|
+
const {getBundleContent} = require('@memlab/lens');
|
|
83
|
+
|
|
84
|
+
// Puppeteer example
|
|
85
|
+
await page.addScriptTag({content: getBundleContent()});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### Overlay controls and interactions
|
|
91
|
+
|
|
92
|
+
- **Toggle switch**: Show/hide all overlay rectangles
|
|
93
|
+
- **Select/pin**: Click a rectangle to pin/unpin the current selection
|
|
94
|
+
- **Hover**: Reveal the selection chain of related detached elements
|
|
95
|
+
- **Component stack panel**: Shows the React component stack of the selected element
|
|
96
|
+
- **Keyboard**: Press `D` to temporarily ignore the currently selected element in the overlay
|
|
97
|
+
- **Widget**: The control widget is draggable
|
|
98
|
+
|
|
99
|
+
Notes:
|
|
100
|
+
- The overlay ignores its own UI elements and won’t count them as part of the page.
|
|
101
|
+
- In dev mode, MemLens logs basic timing and scan stats to the console.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### Configuration (CreateOptions)
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
type CreateOptions = {
|
|
109
|
+
isDevMode?: boolean; // enable console logs and dev-only behaviors
|
|
110
|
+
subscribers?: Array<(r) => void>; // observers of each scan result
|
|
111
|
+
extensions?: Array<BasicExtension>; // e.g., DOMVisualizationExtension
|
|
112
|
+
scanIntervalMs?: number; // default ~1000ms
|
|
113
|
+
trackEventListenerLeaks?: boolean; // enable listener leak scanning
|
|
114
|
+
};
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Core API (`ReactMemoryScan`):
|
|
118
|
+
- `start()`, `pause()`, `stop()`, `dispose()`
|
|
119
|
+
- `subscribe(cb) => () => void`
|
|
120
|
+
- `registerExtension(ext) => () => void`
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### Build
|
|
21
125
|
|
|
22
126
|
```bash
|
|
127
|
+
# from packages/lens
|
|
128
|
+
npm run build
|
|
129
|
+
# or
|
|
23
130
|
webpack
|
|
24
131
|
```
|
|
25
132
|
|
|
26
|
-
|
|
133
|
+
### Test
|
|
27
134
|
|
|
28
|
-
1
|
|
135
|
+
1) Install Playwright dependencies (first time):
|
|
29
136
|
|
|
30
137
|
```bash
|
|
31
138
|
npx playwright install
|
|
32
139
|
npx playwright install-deps
|
|
33
140
|
```
|
|
34
141
|
|
|
35
|
-
2
|
|
142
|
+
2) Run tests:
|
|
36
143
|
|
|
37
144
|
```bash
|
|
38
145
|
npm run test:e2e
|
|
39
146
|
```
|
|
40
147
|
|
|
41
|
-
3
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
* DOM visualizer is leaking canvas DOM elements after each scan
|
|
56
|
-
* Monitor event listener leaks?
|
|
57
|
-
* Real-time memory usage graphs
|
|
58
|
-
* Real-time component count and other react memory scan obtained stats graphs
|
|
59
|
-
* Component re-render heat maps
|
|
60
|
-
* Interactive component tree navigation
|
|
61
|
-
* Browser extension integration
|
|
62
|
-
* centralized config file
|
|
63
|
-
* centralized exception handling
|
|
148
|
+
3) Manual test: open `src/tests/manual/todo-list/todo-with-run.bundle.html` in a browser, or copy/paste `dist/memlens.run.bundle.js` to the DevTools console on any React page.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
### Learn more
|
|
153
|
+
|
|
154
|
+
Please check out this
|
|
155
|
+
[tutorial page](https://facebook.github.io/memlab/docs/guides/visually-debug-memory-leaks-with-memlens)
|
|
156
|
+
on how to use MemLens (a debugging utility) to visualize memory leaks in the
|
|
157
|
+
browser for easier memory debugging.
|
|
158
|
+
|
|
159
|
+
### License
|
|
160
|
+
|
|
161
|
+
MIT © Meta Platforms, Inc.
|
package/dist/index.js
CHANGED
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
/******/ "use strict";
|
|
3
3
|
/******/ var __webpack_modules__ = ({
|
|
4
4
|
|
|
5
|
-
/***/ 3
|
|
6
|
-
|
|
5
|
+
/***/ 3
|
|
6
|
+
(module) {
|
|
7
7
|
|
|
8
8
|
module.exports = require("path");
|
|
9
9
|
|
|
10
|
-
/***/ }
|
|
10
|
+
/***/ },
|
|
11
11
|
|
|
12
|
-
/***/ 383
|
|
13
|
-
|
|
12
|
+
/***/ 383
|
|
13
|
+
(module) {
|
|
14
14
|
|
|
15
15
|
module.exports = require("fs");
|
|
16
16
|
|
|
17
|
-
/***/ }
|
|
17
|
+
/***/ },
|
|
18
18
|
|
|
19
|
-
/***/ 783
|
|
20
|
-
|
|
19
|
+
/***/ 783
|
|
20
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -68,11 +68,11 @@ const fs = __importStar(__webpack_require__(383));
|
|
|
68
68
|
const path = __importStar(__webpack_require__(3));
|
|
69
69
|
function getBundleContent() {
|
|
70
70
|
const bundlePath = path.join(__dirname, 'memlens.run.bundle.min.js');
|
|
71
|
-
return fs.readFileSync(bundlePath, '
|
|
71
|
+
return fs.readFileSync(bundlePath, { encoding: 'utf8' });
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
/***/ }
|
|
75
|
+
/***/ }
|
|
76
76
|
|
|
77
77
|
/******/ });
|
|
78
78
|
/************************************************************************/
|
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license MemLab
|
|
3
|
+
* MIT License
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
6
|
+
*
|
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
* furnished to do so, subject to the following conditions:
|
|
13
|
+
*
|
|
14
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
* copies or substantial portions of the Software.
|
|
16
|
+
*
|
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
* SOFTWARE.
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
1
26
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
2
27
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
3
28
|
module.exports = factory();
|
|
@@ -12,8 +37,8 @@ return /******/ (() => { // webpackBootstrap
|
|
|
12
37
|
/******/ "use strict";
|
|
13
38
|
/******/ var __webpack_modules__ = ({
|
|
14
39
|
|
|
15
|
-
/***/ 54
|
|
16
|
-
|
|
40
|
+
/***/ 54
|
|
41
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
17
42
|
|
|
18
43
|
|
|
19
44
|
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
@@ -205,10 +230,10 @@ _DOMObserver_elementCount = new WeakMap(), _DOMObserver_detachedElementCount = n
|
|
|
205
230
|
};
|
|
206
231
|
|
|
207
232
|
|
|
208
|
-
/***/ }
|
|
233
|
+
/***/ },
|
|
209
234
|
|
|
210
|
-
/***/ 235
|
|
211
|
-
|
|
235
|
+
/***/ 235
|
|
236
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
212
237
|
|
|
213
238
|
|
|
214
239
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
@@ -236,10 +261,10 @@ function createReactMemoryScan(options = {}) {
|
|
|
236
261
|
}
|
|
237
262
|
|
|
238
263
|
|
|
239
|
-
/***/ }
|
|
264
|
+
/***/ },
|
|
240
265
|
|
|
241
|
-
/***/ 282
|
|
242
|
-
|
|
266
|
+
/***/ 282
|
|
267
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
243
268
|
|
|
244
269
|
|
|
245
270
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -300,7 +325,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
300
325
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
301
326
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
302
327
|
};
|
|
303
|
-
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_log, _ReactMemoryScan_notifySubscribers, _ReactMemoryScan_notifyExtensionsBeforeScan, _ReactMemoryScan_notifyExtensionsAfterScan, _ReactMemoryScan_scanCycle, _ReactMemoryScan_updateElementToComponentInfo, _ReactMemoryScan_getTrackedDOMRefs, _ReactMemoryScan_runGC, _ReactMemoryScan_scanEventListenerLeaks;
|
|
328
|
+
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;
|
|
304
329
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
305
330
|
const utils = __importStar(__webpack_require__(476));
|
|
306
331
|
const react_fiber_analysis_1 = __importDefault(__webpack_require__(302));
|
|
@@ -325,6 +350,7 @@ class ReactMemoryScan {
|
|
|
325
350
|
_ReactMemoryScan_scanIntervalMs.set(this, void 0);
|
|
326
351
|
_ReactMemoryScan_domObserver.set(this, void 0);
|
|
327
352
|
_ReactMemoryScan_eventListenerTracker.set(this, void 0);
|
|
353
|
+
_ReactMemoryScan_isDisposed.set(this, void 0);
|
|
328
354
|
__classPrivateFieldSet(this, _ReactMemoryScan_elementWeakRefs, [], "f");
|
|
329
355
|
__classPrivateFieldSet(this, _ReactMemoryScan_isActivated, false, "f");
|
|
330
356
|
__classPrivateFieldSet(this, _ReactMemoryScan_elementToBoundingRects, new WeakMap(), "f");
|
|
@@ -333,8 +359,9 @@ class ReactMemoryScan {
|
|
|
333
359
|
__classPrivateFieldSet(this, _ReactMemoryScan_eventListenerTracker, options.trackEventListenerLeaks
|
|
334
360
|
? event_listener_tracker_1.EventListenerTracker.getInstance()
|
|
335
361
|
: null, "f");
|
|
362
|
+
__classPrivateFieldSet(this, _ReactMemoryScan_intervalId, null, "f");
|
|
363
|
+
__classPrivateFieldSet(this, _ReactMemoryScan_isDisposed, false, "f");
|
|
336
364
|
__classPrivateFieldSet(this, _ReactMemoryScan_fiberAnalyzer, new react_fiber_analysis_1.default(), "f");
|
|
337
|
-
__classPrivateFieldSet(this, _ReactMemoryScan_intervalId, 0, "f");
|
|
338
365
|
__classPrivateFieldSet(this, _ReactMemoryScan_isDevMode, (_a = options.isDevMode) !== null && _a !== void 0 ? _a : false, "f");
|
|
339
366
|
__classPrivateFieldSet(this, _ReactMemoryScan_subscribers, (_b = options.subscribers) !== null && _b !== void 0 ? _b : [], "f");
|
|
340
367
|
__classPrivateFieldSet(this, _ReactMemoryScan_extensions, (_c = options.extensions) !== null && _c !== void 0 ? _c : [], "f");
|
|
@@ -355,6 +382,10 @@ class ReactMemoryScan {
|
|
|
355
382
|
__classPrivateFieldSet(this, _ReactMemoryScan_extensions, __classPrivateFieldGet(this, _ReactMemoryScan_extensions, "f").filter(e => e !== extension), "f");
|
|
356
383
|
}
|
|
357
384
|
start() {
|
|
385
|
+
if (__classPrivateFieldGet(this, _ReactMemoryScan_isDisposed, "f")) {
|
|
386
|
+
console.warn('[Memory] ReactMemoryScan has been disposed and cannot be started again');
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
358
389
|
__classPrivateFieldSet(this, _ReactMemoryScan_isActivated, true, "f");
|
|
359
390
|
__classPrivateFieldSet(this, _ReactMemoryScan_intervalId, setInterval(__classPrivateFieldGet(this, _ReactMemoryScan_instances, "m", _ReactMemoryScan_scanCycle).bind(this), __classPrivateFieldGet(this, _ReactMemoryScan_scanIntervalMs, "f")), "f");
|
|
360
391
|
if (config_1.config.features.enableMutationObserver) {
|
|
@@ -373,11 +404,45 @@ class ReactMemoryScan {
|
|
|
373
404
|
__classPrivateFieldSet(this, _ReactMemoryScan_isActivated, false, "f");
|
|
374
405
|
}
|
|
375
406
|
stop() {
|
|
376
|
-
var _a;
|
|
377
407
|
__classPrivateFieldSet(this, _ReactMemoryScan_isActivated, false, "f");
|
|
378
|
-
|
|
408
|
+
// Clear the interval
|
|
409
|
+
if (__classPrivateFieldGet(this, _ReactMemoryScan_intervalId, "f") !== null) {
|
|
410
|
+
clearInterval(__classPrivateFieldGet(this, _ReactMemoryScan_intervalId, "f"));
|
|
411
|
+
__classPrivateFieldSet(this, _ReactMemoryScan_intervalId, null, "f");
|
|
412
|
+
}
|
|
413
|
+
// Clear element references to allow garbage collection
|
|
379
414
|
__classPrivateFieldSet(this, _ReactMemoryScan_elementWeakRefs, [], "f");
|
|
380
|
-
(
|
|
415
|
+
__classPrivateFieldSet(this, _ReactMemoryScan_knownFiberNodes, [], "f");
|
|
416
|
+
// Stop DOM observer
|
|
417
|
+
if (__classPrivateFieldGet(this, _ReactMemoryScan_domObserver, "f")) {
|
|
418
|
+
__classPrivateFieldGet(this, _ReactMemoryScan_domObserver, "f").stopMonitoring();
|
|
419
|
+
__classPrivateFieldSet(this, _ReactMemoryScan_domObserver, null, "f");
|
|
420
|
+
}
|
|
421
|
+
// Clear WeakMaps to allow garbage collection
|
|
422
|
+
__classPrivateFieldSet(this, _ReactMemoryScan_elementToBoundingRects, new WeakMap(), "f");
|
|
423
|
+
__classPrivateFieldSet(this, _ReactMemoryScan_elementToComponentStack, new WeakMap(), "f");
|
|
424
|
+
console.log('[Memory] ReactMemoryScan stopped');
|
|
425
|
+
}
|
|
426
|
+
dispose() {
|
|
427
|
+
// Stop all monitoring
|
|
428
|
+
this.stop();
|
|
429
|
+
// Clear all subscribers
|
|
430
|
+
__classPrivateFieldSet(this, _ReactMemoryScan_subscribers, [], "f");
|
|
431
|
+
// Clean up all extensions
|
|
432
|
+
for (const extension of __classPrivateFieldGet(this, _ReactMemoryScan_extensions, "f")) {
|
|
433
|
+
if (extension && typeof extension.cleanup === 'function') {
|
|
434
|
+
extension.cleanup();
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
__classPrivateFieldSet(this, _ReactMemoryScan_extensions, [], "f");
|
|
438
|
+
// Dispose event listener tracker if it exists
|
|
439
|
+
if (__classPrivateFieldGet(this, _ReactMemoryScan_eventListenerTracker, "f")) {
|
|
440
|
+
__classPrivateFieldGet(this, _ReactMemoryScan_eventListenerTracker, "f").destroy();
|
|
441
|
+
__classPrivateFieldSet(this, _ReactMemoryScan_eventListenerTracker, null, "f");
|
|
442
|
+
}
|
|
443
|
+
// Mark as disposed to prevent reuse
|
|
444
|
+
__classPrivateFieldSet(this, _ReactMemoryScan_isDisposed, true, "f");
|
|
445
|
+
console.log('[Memory] ReactMemoryScan disposed');
|
|
381
446
|
}
|
|
382
447
|
recordBoundingRectangles(elementRefs) {
|
|
383
448
|
for (const elemRef of elementRefs) {
|
|
@@ -507,7 +572,7 @@ class ReactMemoryScan {
|
|
|
507
572
|
return scanResult;
|
|
508
573
|
}
|
|
509
574
|
}
|
|
510
|
-
_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_instances = new WeakSet(), _ReactMemoryScan_log = function _ReactMemoryScan_log(...args) {
|
|
575
|
+
_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) {
|
|
511
576
|
if (__classPrivateFieldGet(this, _ReactMemoryScan_isDevMode, "f") && config_1.config.features.enableConsoleLogs) {
|
|
512
577
|
utils.consoleLog(...args);
|
|
513
578
|
}
|
|
@@ -595,10 +660,10 @@ class LeakedFiber {
|
|
|
595
660
|
}
|
|
596
661
|
|
|
597
662
|
|
|
598
|
-
/***/ }
|
|
663
|
+
/***/ },
|
|
599
664
|
|
|
600
|
-
/***/ 302
|
|
601
|
-
|
|
665
|
+
/***/ 302
|
|
666
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
602
667
|
|
|
603
668
|
|
|
604
669
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -735,10 +800,10 @@ class ReactFiberAnalyzer {
|
|
|
735
800
|
exports["default"] = ReactFiberAnalyzer;
|
|
736
801
|
|
|
737
802
|
|
|
738
|
-
/***/ }
|
|
803
|
+
/***/ },
|
|
739
804
|
|
|
740
|
-
/***/ 313
|
|
741
|
-
|
|
805
|
+
/***/ 313
|
|
806
|
+
(__unused_webpack_module, exports) {
|
|
742
807
|
|
|
743
808
|
|
|
744
809
|
/**
|
|
@@ -1013,10 +1078,10 @@ class WeakMapPlus {
|
|
|
1013
1078
|
exports.WeakMapPlus = WeakMapPlus;
|
|
1014
1079
|
|
|
1015
1080
|
|
|
1016
|
-
/***/ }
|
|
1081
|
+
/***/ },
|
|
1017
1082
|
|
|
1018
|
-
/***/ 346
|
|
1019
|
-
|
|
1083
|
+
/***/ 346
|
|
1084
|
+
(__unused_webpack_module, exports) {
|
|
1020
1085
|
|
|
1021
1086
|
|
|
1022
1087
|
/**
|
|
@@ -1050,10 +1115,10 @@ exports.config = {
|
|
|
1050
1115
|
};
|
|
1051
1116
|
|
|
1052
1117
|
|
|
1053
|
-
/***/ }
|
|
1118
|
+
/***/ },
|
|
1054
1119
|
|
|
1055
|
-
/***/ 476
|
|
1056
|
-
|
|
1120
|
+
/***/ 476
|
|
1121
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
1057
1122
|
|
|
1058
1123
|
|
|
1059
1124
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
@@ -1233,10 +1298,10 @@ function setRunInSession() {
|
|
|
1233
1298
|
}
|
|
1234
1299
|
|
|
1235
1300
|
|
|
1236
|
-
/***/ }
|
|
1301
|
+
/***/ },
|
|
1237
1302
|
|
|
1238
|
-
/***/ 498
|
|
1239
|
-
|
|
1303
|
+
/***/ 498
|
|
1304
|
+
(__unused_webpack_module, exports) {
|
|
1240
1305
|
|
|
1241
1306
|
|
|
1242
1307
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
@@ -1301,10 +1366,10 @@ function debounce(callback, delay) {
|
|
|
1301
1366
|
}
|
|
1302
1367
|
|
|
1303
1368
|
|
|
1304
|
-
/***/ }
|
|
1369
|
+
/***/ },
|
|
1305
1370
|
|
|
1306
|
-
/***/ 737
|
|
1307
|
-
|
|
1371
|
+
/***/ 737
|
|
1372
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
1308
1373
|
|
|
1309
1374
|
|
|
1310
1375
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
@@ -1496,10 +1561,10 @@ function extractReactComponentName(displayName) {
|
|
|
1496
1561
|
}
|
|
1497
1562
|
|
|
1498
1563
|
|
|
1499
|
-
/***/ }
|
|
1564
|
+
/***/ },
|
|
1500
1565
|
|
|
1501
|
-
/***/ 847
|
|
1502
|
-
|
|
1566
|
+
/***/ 847
|
|
1567
|
+
(__unused_webpack_module, exports) {
|
|
1503
1568
|
|
|
1504
1569
|
|
|
1505
1570
|
/**
|
|
@@ -1519,10 +1584,10 @@ function isValidComponentName(name) {
|
|
|
1519
1584
|
}
|
|
1520
1585
|
|
|
1521
1586
|
|
|
1522
|
-
/***/ }
|
|
1587
|
+
/***/ },
|
|
1523
1588
|
|
|
1524
|
-
/***/ 953
|
|
1525
|
-
|
|
1589
|
+
/***/ 953
|
|
1590
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
1526
1591
|
|
|
1527
1592
|
|
|
1528
1593
|
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
@@ -1654,7 +1719,7 @@ _EventListenerTracker_listenerMap = new WeakMap(), _EventListenerTracker_detache
|
|
|
1654
1719
|
EventListenerTracker.instance = null;
|
|
1655
1720
|
|
|
1656
1721
|
|
|
1657
|
-
/***/ }
|
|
1722
|
+
/***/ }
|
|
1658
1723
|
|
|
1659
1724
|
/******/ });
|
|
1660
1725
|
/************************************************************************/
|