@memlab/lens 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/LICENSE +21 -0
  2. package/dist/config/config.d.ts +22 -0
  3. package/dist/core/dom-observer.d.ts +10 -0
  4. package/dist/core/event-listener-tracker.d.ts +33 -0
  5. package/dist/core/react-fiber-analysis.d.ts +4 -0
  6. package/dist/core/react-memory-scan.d.ts +36 -0
  7. package/{src/core/types.ts → dist/core/types.d.ts} +56 -80
  8. package/{src/index.ts → dist/core/valid-component-name.d.ts} +2 -7
  9. package/dist/extensions/basic-extension.d.ts +30 -0
  10. package/dist/extensions/dom-visualization-extension.d.ts +17 -0
  11. package/dist/index.d.ts +1 -0
  12. package/dist/memlens.lib.bundle.js +1695 -0
  13. package/dist/memlens.lib.bundle.min.js +1 -0
  14. package/dist/memlens.lib.d.ts +12 -0
  15. package/dist/memlens.run.bundle.js +2673 -0
  16. package/dist/memlens.run.bundle.min.js +1 -0
  17. package/dist/memlens.run.d.ts +1 -0
  18. package/dist/tests/bundle/lib.bundle.test.d.ts +1 -0
  19. package/dist/tests/bundle/run.bundle.start.head.test.d.ts +1 -0
  20. package/dist/tests/bundle/run.bundle.start.test.d.ts +1 -0
  21. package/dist/tests/bundle/run.bundle.test.d.ts +1 -0
  22. package/dist/tests/fiber/dev.fiber.complex.dev.test.d.ts +1 -0
  23. package/dist/tests/fiber/dev.fiber.complex.list.dev.test.d.ts +1 -0
  24. package/dist/tests/fiber/dev.fiber.complex.prod.test.d.ts +1 -0
  25. package/dist/tests/fiber/dev.fiber.name.dev.test.d.ts +1 -0
  26. package/dist/tests/fiber/dev.fiber.name.prod.test.d.ts +1 -0
  27. package/dist/tests/utils/test-utils.d.ts +11 -0
  28. package/dist/utils/intersection-observer.d.ts +18 -0
  29. package/dist/utils/react-fiber-utils.d.ts +56 -0
  30. package/dist/utils/utils.d.ts +26 -0
  31. package/dist/utils/weak-ref-utils.d.ts +67 -0
  32. package/dist/visual/components/component-stack-panel.d.ts +11 -0
  33. package/dist/visual/components/control-widget.d.ts +13 -0
  34. package/dist/visual/components/overlay-rectangle.d.ts +11 -0
  35. package/dist/visual/components/status-text.d.ts +2 -0
  36. package/dist/visual/components/toggle-button.d.ts +3 -0
  37. package/dist/visual/components/visual-overlay.d.ts +1 -0
  38. package/dist/visual/dom-element-visualizer-interactive.d.ts +26 -0
  39. package/{src/core/valid-component-name.ts → dist/visual/dom-element-visualizer.d.ts} +5 -7
  40. package/dist/visual/visual-utils.d.ts +16 -0
  41. package/package.json +5 -1
  42. package/explainer.md +0 -54
  43. package/playwright.config.ts +0 -21
  44. package/src/config/config.ts +0 -32
  45. package/src/core/dom-observer.ts +0 -189
  46. package/src/core/event-listener-tracker.ts +0 -171
  47. package/src/core/react-fiber-analysis.ts +0 -123
  48. package/src/core/react-memory-scan.ts +0 -366
  49. package/src/extensions/basic-extension.ts +0 -41
  50. package/src/extensions/dom-visualization-extension.ts +0 -42
  51. package/src/memlens.lib.js.flow +0 -75
  52. package/src/memlens.lib.ts +0 -22
  53. package/src/memlens.run.ts +0 -21
  54. package/src/tests/bundle/lib.bundle.test.ts +0 -31
  55. package/src/tests/bundle/run.bundle.start.head.test.ts +0 -48
  56. package/src/tests/bundle/run.bundle.start.test.ts +0 -48
  57. package/src/tests/bundle/run.bundle.test.ts +0 -51
  58. package/src/tests/fiber/dev.fiber.complex.dev.test.ts +0 -92
  59. package/src/tests/fiber/dev.fiber.complex.list.dev.test.ts +0 -118
  60. package/src/tests/fiber/dev.fiber.complex.prod.test.ts +0 -92
  61. package/src/tests/fiber/dev.fiber.name.dev.test.ts +0 -77
  62. package/src/tests/fiber/dev.fiber.name.prod.test.ts +0 -79
  63. package/src/tests/lib/babel.prod.js +0 -4
  64. package/src/tests/lib/react-dom-v18.dev.js +0 -29926
  65. package/src/tests/lib/react-dom-v18.prod.js +0 -269
  66. package/src/tests/lib/react-v18.dev.js +0 -3345
  67. package/src/tests/lib/react-v18.prod.js +0 -33
  68. package/src/tests/manual/playwright-open-manual.js +0 -40
  69. package/src/tests/manual/todo-list/todo-with-run.bundle.html +0 -80
  70. package/src/tests/utils/test-utils.ts +0 -28
  71. package/src/utils/intersection-observer.ts +0 -65
  72. package/src/utils/react-fiber-utils.ts +0 -212
  73. package/src/utils/utils.ts +0 -201
  74. package/src/utils/weak-ref-utils.ts +0 -308
  75. package/src/visual/components/component-stack-panel.ts +0 -85
  76. package/src/visual/components/control-widget.ts +0 -96
  77. package/src/visual/components/overlay-rectangle.ts +0 -167
  78. package/src/visual/components/status-text.ts +0 -53
  79. package/src/visual/components/toggle-button.ts +0 -57
  80. package/src/visual/components/visual-overlay.ts +0 -19
  81. package/src/visual/dom-element-visualizer-interactive.ts +0 -358
  82. package/src/visual/dom-element-visualizer.ts +0 -130
  83. package/src/visual/visual-utils.ts +0 -89
  84. package/tsconfig.json +0 -18
  85. package/webpack.config.js +0 -105
@@ -1,51 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @format
8
- * @oncall memory_lab
9
- */
10
- import {test, expect} from '@playwright/test';
11
- import fs from 'fs';
12
- import {wait} from '../utils/test-utils';
13
- import {runBundleFilePath} from '../utils/test-utils';
14
-
15
- test.describe('run.bundle.js functionality', () => {
16
- test('should load and execute correctly', async ({page}) => {
17
- const bundleCode = fs.readFileSync(runBundleFilePath, 'utf8');
18
-
19
- let bundleLoaded = false;
20
- // Listen for console messages
21
- page.on('console', message => {
22
- // add console.log(message) if you would like to debug
23
- const msgText = message.text();
24
- if (msgText.includes('duration:')) {
25
- bundleLoaded = true;
26
- }
27
- });
28
-
29
- await page.setContent(`
30
- <!DOCTYPE html>
31
- <html>
32
- <head>
33
- <script>
34
- window.TEST_MEMORY_SCAN = true;
35
- </script>
36
- </head>
37
- <body>
38
- <div id="test-container"></div>
39
- <script>
40
- ${bundleCode}
41
- </script>
42
- </body>
43
- </html>
44
- `);
45
-
46
- await wait(2000);
47
-
48
- // check if the bundle loaded successfully
49
- expect(bundleLoaded).toBe(true);
50
- });
51
- });
@@ -1,92 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @format
8
- * @oncall memory_lab
9
- */
10
- import type {AnyValue} from '../../core/types';
11
-
12
- import {test, expect} from '@playwright/test';
13
- import path from 'path';
14
- import fs from 'fs';
15
- import {srcPath} from '../utils/test-utils';
16
- import {libBundleFilePath} from '../utils/test-utils';
17
-
18
- test('scan should identify react components in a complex fiber tree (React 18 Dev)', async ({
19
- page,
20
- }) => {
21
- const bundleCode = fs.readFileSync(libBundleFilePath, 'utf8');
22
-
23
- const reactDevPath = path.join(srcPath, 'tests', 'lib', 'react-v18.dev.js');
24
- const reactDevCode = fs.readFileSync(reactDevPath, 'utf8');
25
-
26
- const reactDOMDevPath = path.join(
27
- srcPath,
28
- 'tests',
29
- 'lib',
30
- 'react-dom-v18.dev.js',
31
- );
32
- const reactDOMDevCode = fs.readFileSync(reactDOMDevPath, 'utf8');
33
-
34
- // Create a simple test page with React and a custom component
35
- await page.setContent(`
36
- <html>
37
- <body>
38
- <div id="root"></div>
39
- <script>${reactDevCode}</script>
40
- <script>${reactDOMDevCode}</script>
41
- <script>${bundleCode}</script>
42
- <script>
43
- function TopContainer() {
44
- return React.createElement(
45
- 'div',
46
- null,
47
- React.createElement(TestContainer),
48
- React.createElement(TestContainer),
49
- React.createElement(TestContainer),
50
- );
51
- }
52
- function TestContainer() {
53
- return React.createElement(
54
- 'div',
55
- null,
56
- React.createElement(TestComponent),
57
- React.createElement(TestComponent)
58
- );
59
- }
60
-
61
- function TestComponent() {
62
- return React.createElement('div', null, 'Test Component');
63
- }
64
-
65
- ReactDOM.render(
66
- React.createElement(TopContainer),
67
- document.getElementById('root')
68
- );
69
- </script>
70
- </body>
71
- </html>
72
- `);
73
-
74
- // Now the global `MemLens` should be available in the page
75
- const componentIdentified = await page.evaluate(() => {
76
- const createReactMemoryScan = (window as AnyValue).MemLens
77
- .createReactMemoryScan;
78
- const instance = createReactMemoryScan();
79
- const analysisResult = instance.scan();
80
- const componentCountCorrect =
81
- analysisResult.componentToFiberNodeCount.get('TestComponent') === 6;
82
- const containerCountCorrect =
83
- analysisResult.componentToFiberNodeCount.get('TestContainer') === 3;
84
- const topContainerCountCorrect =
85
- analysisResult.componentToFiberNodeCount.get('TopContainer') === 1;
86
- return (
87
- componentCountCorrect && containerCountCorrect && topContainerCountCorrect
88
- );
89
- });
90
-
91
- expect(componentIdentified).toBe(true);
92
- });
@@ -1,118 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @format
8
- * @oncall memory_lab
9
- */
10
- import {AnyValue} from '../../core/types';
11
- import {test, expect} from '@playwright/test';
12
- import path from 'path';
13
- import fs from 'fs';
14
- import {srcPath} from '../utils/test-utils';
15
- import {libBundleFilePath} from '../utils/test-utils';
16
-
17
- test('scan should identify react components in a complex list fiber tree (React 18 Dev)', async ({
18
- page,
19
- }) => {
20
- const bundleCode = fs.readFileSync(libBundleFilePath, 'utf8');
21
-
22
- const reactDevPath = path.join(srcPath, 'tests', 'lib', 'react-v18.dev.js');
23
- const reactDevCode = fs.readFileSync(reactDevPath, 'utf8');
24
-
25
- const reactDOMDevPath = path.join(
26
- srcPath,
27
- 'tests',
28
- 'lib',
29
- 'react-dom-v18.dev.js',
30
- );
31
- const reactDOMDevCode = fs.readFileSync(reactDOMDevPath, 'utf8');
32
-
33
- // Create a test page with React and some list components
34
- await page.setContent(`
35
- <html>
36
- <body>
37
- <div id="root"></div>
38
- <script>${reactDevCode}</script>
39
- <script>${reactDOMDevCode}</script>
40
- <script>${bundleCode}</script>
41
- <script>
42
- function ListItem({ text, count }) {
43
- return React.createElement('li', null, \`$\{text} ($\{count})\`);
44
- }
45
-
46
- function List({ items }) {
47
- return React.createElement(
48
- 'ul',
49
- { className: 'list-container' },
50
- items.map((item, index) =>
51
- React.createElement(ListItem, {
52
- key: index,
53
- text: item.text,
54
- count: item.count
55
- })
56
- )
57
- );
58
- }
59
-
60
- function Counter({ initialCount }) {
61
- const [count, setCount] = React.useState(initialCount);
62
-
63
- return React.createElement(
64
- 'div',
65
- { className: 'counter' },
66
- React.createElement('span', null, \`Count: $\{count}\`),
67
- React.createElement(
68
- 'button',
69
- { onClick: () => setCount(count + 1) },
70
- 'Increment'
71
- )
72
- );
73
- }
74
-
75
- function TestContainer() {
76
- const listSetup = [];
77
- for (let i = 0; i < 1000; ++i) {
78
- listSetup.push({ text: 'Item ' + i, count: i });
79
- }
80
- const [items] = React.useState(listSetup);
81
-
82
- return React.createElement(
83
- 'div',
84
- { className: 'container' },
85
- React.createElement('h1', null, 'Test Application'),
86
- React.createElement(Counter, { initialCount: 0 }),
87
- React.createElement(Counter, { initialCount: 10 }),
88
- React.createElement(List, { items: items }),
89
- React.createElement(List, { items: items.slice(0, 500) })
90
- );
91
- }
92
-
93
- ReactDOM.render(
94
- React.createElement(TestContainer),
95
- document.getElementById('root')
96
- );
97
- </script>
98
- </body>
99
- </html>
100
- `);
101
-
102
- // Now the global `MemLens` should be available in the page
103
- const componentIdentified = await page.evaluate(() => {
104
- const createReactMemoryScan = (window as AnyValue).MemLens
105
- .createReactMemoryScan;
106
- const instance = createReactMemoryScan();
107
- const analysisResult = instance.scan();
108
- const counterCorrect =
109
- analysisResult.componentToFiberNodeCount.get('Counter') === 2;
110
- const listCorrect =
111
- analysisResult.componentToFiberNodeCount.get('List') === 2;
112
- const listItemCorrect =
113
- analysisResult.componentToFiberNodeCount.get('ListItem') === 1500;
114
- return counterCorrect && listCorrect && listItemCorrect;
115
- });
116
-
117
- expect(componentIdentified).toBe(true);
118
- });
@@ -1,92 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @format
8
- * @oncall memory_lab
9
- */
10
- import type {AnyValue} from '../../core/types';
11
-
12
- import {test, expect} from '@playwright/test';
13
- import path from 'path';
14
- import fs from 'fs';
15
- import {srcPath} from '../utils/test-utils';
16
- import {libBundleFilePath} from '../utils/test-utils';
17
-
18
- test('scan should identify react components in a complex fiber tree (React 18 Prod)', async ({
19
- page,
20
- }) => {
21
- const bundleCode = fs.readFileSync(libBundleFilePath, 'utf8');
22
-
23
- const reactDevPath = path.join(srcPath, 'tests', 'lib', 'react-v18.prod.js');
24
- const reactDevCode = fs.readFileSync(reactDevPath, 'utf8');
25
-
26
- const reactDOMDevPath = path.join(
27
- srcPath,
28
- 'tests',
29
- 'lib',
30
- 'react-dom-v18.prod.js',
31
- );
32
- const reactDOMDevCode = fs.readFileSync(reactDOMDevPath, 'utf8');
33
-
34
- // Create a simple test page with React and a custom component
35
- await page.setContent(`
36
- <html>
37
- <body>
38
- <div id="root"></div>
39
- <script>${reactDevCode}</script>
40
- <script>${reactDOMDevCode}</script>
41
- <script>${bundleCode}</script>
42
- <script>
43
- function TopContainer() {
44
- return React.createElement(
45
- 'div',
46
- null,
47
- React.createElement(TestContainer),
48
- React.createElement(TestContainer),
49
- React.createElement(TestContainer),
50
- );
51
- }
52
- function TestContainer() {
53
- return React.createElement(
54
- 'div',
55
- null,
56
- React.createElement(TestComponent),
57
- React.createElement(TestComponent)
58
- );
59
- }
60
-
61
- function TestComponent() {
62
- return React.createElement('div', null, 'Test Component');
63
- }
64
-
65
- ReactDOM.render(
66
- React.createElement(TopContainer),
67
- document.getElementById('root')
68
- );
69
- </script>
70
- </body>
71
- </html>
72
- `);
73
-
74
- // Now the global `MemLens` should be available in the page
75
- const componentIdentified = await page.evaluate(() => {
76
- const createReactMemoryScan = (window as AnyValue).MemLens
77
- .createReactMemoryScan;
78
- const instance = createReactMemoryScan();
79
- const analysisResult = instance.scan();
80
- const componentCountCorrect =
81
- analysisResult.componentToFiberNodeCount.get('TestComponent') === 6;
82
- const containerCountCorrect =
83
- analysisResult.componentToFiberNodeCount.get('TestContainer') === 3;
84
- const topContainerCountCorrect =
85
- analysisResult.componentToFiberNodeCount.get('TopContainer') === 1;
86
- return (
87
- componentCountCorrect && containerCountCorrect && topContainerCountCorrect
88
- );
89
- });
90
-
91
- expect(componentIdentified).toBe(true);
92
- });
@@ -1,77 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @format
8
- * @oncall memory_lab
9
- */
10
- import type {AnyValue} from '../../core/types';
11
-
12
- import {test, expect} from '@playwright/test';
13
- import path from 'path';
14
- import fs from 'fs';
15
- import {srcPath} from '../utils/test-utils';
16
- import {libBundleFilePath} from '../utils/test-utils';
17
-
18
- test('scan should identify react components (React 18 Dev)', async ({page}) => {
19
- const bundleCode = fs.readFileSync(libBundleFilePath, 'utf8');
20
-
21
- const reactDevPath = path.join(srcPath, 'tests', 'lib', 'react-v18.dev.js');
22
- const reactDevCode = fs.readFileSync(reactDevPath, 'utf8');
23
-
24
- const reactDOMDevPath = path.join(
25
- srcPath,
26
- 'tests',
27
- 'lib',
28
- 'react-dom-v18.dev.js',
29
- );
30
- const reactDOMDevCode = fs.readFileSync(reactDOMDevPath, 'utf8');
31
-
32
- // Create a simple test page with React and a custom component
33
- await page.setContent(`
34
- <html>
35
- <body>
36
- <div id="root"></div>
37
- <script>${reactDevCode}</script>
38
- <script>${reactDOMDevCode}</script>
39
- <script>${bundleCode}</script>
40
- <script>
41
- function TestContainer() {
42
- return React.createElement(
43
- 'div',
44
- null,
45
- React.createElement(TestComponent),
46
- React.createElement(TestComponent)
47
- );
48
- }
49
-
50
- function TestComponent() {
51
- return React.createElement('div', null, 'Test Component');
52
- }
53
-
54
- ReactDOM.render(
55
- React.createElement(TestContainer),
56
- document.getElementById('root')
57
- );
58
- </script>
59
- </body>
60
- </html>
61
- `);
62
-
63
- // Now the global `MemLens` should be available in the page
64
- const componentIdentified = await page.evaluate(() => {
65
- const createReactMemoryScan = (window as AnyValue).MemLens
66
- .createReactMemoryScan;
67
- const instance = createReactMemoryScan();
68
- const analysisResult = instance.scan();
69
- const componentCountCorrect =
70
- analysisResult.componentToFiberNodeCount.get('TestComponent') === 2;
71
- const containerCountCorrect =
72
- analysisResult.componentToFiberNodeCount.get('TestContainer') === 1;
73
- return componentCountCorrect && containerCountCorrect;
74
- });
75
-
76
- expect(componentIdentified).toBe(true);
77
- });
@@ -1,79 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @format
8
- * @oncall memory_lab
9
- */
10
- import type {AnyValue} from '../../core/types';
11
-
12
- import {test, expect} from '@playwright/test';
13
- import path from 'path';
14
- import fs from 'fs';
15
- import {srcPath} from '../utils/test-utils';
16
- import {libBundleFilePath} from '../utils/test-utils';
17
-
18
- test('scan should identify react components (React 18 Prod)', async ({
19
- page,
20
- }) => {
21
- const bundleCode = fs.readFileSync(libBundleFilePath, 'utf8');
22
-
23
- const reactDevPath = path.join(srcPath, 'tests', 'lib', 'react-v18.prod.js');
24
- const reactDevCode = fs.readFileSync(reactDevPath, 'utf8');
25
-
26
- const reactDOMDevPath = path.join(
27
- srcPath,
28
- 'tests',
29
- 'lib',
30
- 'react-dom-v18.prod.js',
31
- );
32
- const reactDOMDevCode = fs.readFileSync(reactDOMDevPath, 'utf8');
33
-
34
- // Create a simple test page with React and a custom component
35
- await page.setContent(`
36
- <html>
37
- <body>
38
- <div id="root"></div>
39
- <script>${reactDevCode}</script>
40
- <script>${reactDOMDevCode}</script>
41
- <script>${bundleCode}</script>
42
- <script>
43
- function TestContainer() {
44
- return React.createElement(
45
- 'div',
46
- null,
47
- React.createElement(TestComponent),
48
- React.createElement(TestComponent)
49
- );
50
- }
51
-
52
- function TestComponent() {
53
- return React.createElement('div', null, 'Test Component');
54
- }
55
-
56
- ReactDOM.render(
57
- React.createElement(TestContainer),
58
- document.getElementById('root')
59
- );
60
- </script>
61
- </body>
62
- </html>
63
- `);
64
-
65
- // Now the global `MemLens` should be available in the page
66
- const componentIdentified = await page.evaluate(() => {
67
- const createReactMemoryScan = (window as AnyValue).MemLens
68
- .createReactMemoryScan;
69
- const instance = createReactMemoryScan();
70
- const analysisResult = instance.scan();
71
- const componentCountCorrect =
72
- analysisResult.componentToFiberNodeCount.get('TestComponent') === 2;
73
- const containerCountCorrect =
74
- analysisResult.componentToFiberNodeCount.get('TestContainer') === 1;
75
- return componentCountCorrect && containerCountCorrect;
76
- });
77
-
78
- expect(componentIdentified).toBe(true);
79
- });