@ng-org/alien-deepsignals 0.1.2-alpha.2 → 0.1.2-alpha.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.
- package/dist/deepSignal.d.ts.map +1 -1
- package/dist/deepSignal.js +244 -100
- package/dist/hooks/react/useDeepSignal.d.ts +4 -4
- package/dist/hooks/react/useDeepSignal.d.ts.map +1 -1
- package/dist/hooks/react/useDeepSignal.js +22 -15
- package/dist/hooks/svelte/useDeepSignal.svelte.d.ts +3 -7
- package/dist/hooks/svelte/useDeepSignal.svelte.d.ts.map +1 -1
- package/dist/hooks/svelte/useDeepSignal.svelte.js +34 -18
- package/dist/hooks/vue/useDeepSignal.d.ts +4 -3
- package/dist/hooks/vue/useDeepSignal.d.ts.map +1 -1
- package/dist/hooks/vue/useDeepSignal.js +52 -24
- package/dist/test/frontend/astro-app/src/components/PerfSuiteClient.d.ts +4 -0
- package/dist/test/frontend/astro-app/src/components/PerfSuiteClient.d.ts.map +1 -0
- package/dist/test/frontend/astro-app/src/components/PerfSuiteClient.js +225 -0
- package/dist/test/frontend/astro-app/src/components/ReactPanel.d.ts +4 -0
- package/dist/test/frontend/astro-app/src/components/ReactPanel.d.ts.map +1 -0
- package/dist/test/frontend/astro-app/src/components/ReactPanel.js +227 -0
- package/dist/test/frontend/astro-app/src/components/perf/react/ReactPerfDeep.d.ts +4 -0
- package/dist/test/frontend/astro-app/src/components/perf/react/ReactPerfDeep.d.ts.map +1 -0
- package/dist/test/frontend/astro-app/src/components/perf/react/ReactPerfDeep.js +150 -0
- package/dist/test/frontend/astro-app/src/components/perf/react/ReactPerfNative.d.ts +4 -0
- package/dist/test/frontend/astro-app/src/components/perf/react/ReactPerfNative.d.ts.map +1 -0
- package/dist/test/frontend/astro-app/src/components/perf/react/ReactPerfNative.js +184 -0
- package/dist/test/frontend/playwright/crossFrameworkHooks.spec.d.ts +2 -0
- package/dist/test/frontend/playwright/crossFrameworkHooks.spec.d.ts.map +1 -0
- package/dist/test/frontend/playwright/crossFrameworkHooks.spec.js +171 -0
- package/dist/test/frontend/playwright/perfSuite.spec.d.ts +2 -0
- package/dist/test/frontend/playwright/perfSuite.spec.d.ts.map +1 -0
- package/dist/test/frontend/playwright/perfSuite.spec.js +128 -0
- package/dist/test/frontend/utils/mockData.d.ts +53 -0
- package/dist/test/frontend/utils/mockData.d.ts.map +1 -0
- package/dist/test/frontend/utils/mockData.js +78 -0
- package/dist/test/frontend/utils/paths.d.ts +4 -0
- package/dist/test/frontend/utils/paths.d.ts.map +1 -0
- package/dist/test/frontend/utils/paths.js +28 -0
- package/dist/test/frontend/utils/perfScenarios.d.ts +15 -0
- package/dist/test/frontend/utils/perfScenarios.d.ts.map +1 -0
- package/dist/test/frontend/utils/perfScenarios.js +287 -0
- package/dist/test/frontend/utils/renderMetrics.d.ts +13 -0
- package/dist/test/frontend/utils/renderMetrics.d.ts.map +1 -0
- package/dist/test/frontend/utils/renderMetrics.js +45 -0
- package/dist/test/frontend/utils/state.d.ts +57 -0
- package/dist/test/frontend/utils/state.d.ts.map +1 -0
- package/dist/test/frontend/utils/state.js +79 -0
- package/dist/test/lib/core.test.d.ts +2 -0
- package/dist/test/lib/core.test.d.ts.map +1 -0
- package/dist/test/lib/core.test.js +53 -0
- package/dist/test/lib/deepSignalOptions.test.d.ts +2 -0
- package/dist/test/lib/deepSignalOptions.test.d.ts.map +1 -0
- package/dist/test/lib/deepSignalOptions.test.js +230 -0
- package/dist/test/lib/index.test.d.ts +2 -0
- package/dist/test/lib/index.test.d.ts.map +1 -0
- package/dist/test/lib/index.test.js +807 -0
- package/dist/test/lib/misc.test.d.ts +2 -0
- package/dist/test/lib/misc.test.d.ts.map +1 -0
- package/dist/test/lib/misc.test.js +140 -0
- package/dist/test/lib/watch.test.d.ts +2 -0
- package/dist/test/lib/watch.test.d.ts.map +1 -0
- package/dist/test/lib/watch.test.js +1280 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +36 -19
- package/src/index.ts +5 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const react_1 = __importStar(require("react"));
|
|
40
|
+
const useDeepSignal_1 = __importDefault(require("../../../../../hooks/react/useDeepSignal"));
|
|
41
|
+
const state_1 = require("../../../utils/state");
|
|
42
|
+
const renderMetrics_1 = require("../../../utils/renderMetrics");
|
|
43
|
+
const ReactPanel = () => {
|
|
44
|
+
const state = (0, useDeepSignal_1.default)(state_1.sharedState);
|
|
45
|
+
const renderCount = (0, react_1.useRef)(0);
|
|
46
|
+
renderCount.current += 1;
|
|
47
|
+
(0, react_1.useEffect)(() => {
|
|
48
|
+
(0, renderMetrics_1.recordRender)("react", renderCount.current);
|
|
49
|
+
});
|
|
50
|
+
const objectEntries = Array.from(state.objectSet.values());
|
|
51
|
+
const ObjectRow = ({ entry }) => {
|
|
52
|
+
const rowRenderCount = (0, react_1.useRef)(0);
|
|
53
|
+
rowRenderCount.current += 1;
|
|
54
|
+
(0, react_1.useEffect)(() => {
|
|
55
|
+
(0, renderMetrics_1.recordObjectRender)("react", entry["@id"], rowRenderCount.current);
|
|
56
|
+
});
|
|
57
|
+
return (<div className="object-row" data-entry-id={entry["@id"]} data-render-count={rowRenderCount.current}>
|
|
58
|
+
<span className="object-id">{entry["@id"]}</span>
|
|
59
|
+
<input type="text" data-role="label" value={entry.label} onChange={(event) => {
|
|
60
|
+
entry.label = event.target.value;
|
|
61
|
+
}}/>
|
|
62
|
+
<input type="number" data-role="count-input" value={entry.count} onChange={(event) => {
|
|
63
|
+
entry.count = Number(event.target.value || 0);
|
|
64
|
+
}}/>
|
|
65
|
+
<span data-role="count">{entry.count}</span>
|
|
66
|
+
<button type="button" data-action="increment" onClick={() => {
|
|
67
|
+
entry.count += 1;
|
|
68
|
+
}}>
|
|
69
|
+
+1
|
|
70
|
+
</button>
|
|
71
|
+
</div>);
|
|
72
|
+
};
|
|
73
|
+
const renderPrimitiveField = (label, options) => {
|
|
74
|
+
if (options.type === "boolean") {
|
|
75
|
+
return (<fieldset className="field" data-field={label}>
|
|
76
|
+
<legend>{label}</legend>
|
|
77
|
+
<input type="checkbox" data-role="editor" checked={options.value} onChange={(event) => options.onChange(event.target.checked)}/>
|
|
78
|
+
<span data-role="value">{String(options.value)}</span>
|
|
79
|
+
</fieldset>);
|
|
80
|
+
}
|
|
81
|
+
if (options.type === "number") {
|
|
82
|
+
return (<fieldset className="field" data-field={label}>
|
|
83
|
+
<legend>{label}</legend>
|
|
84
|
+
<input type="number" data-role="editor" value={options.value} onChange={(event) => options.onChange(Number(event.target.value || 0))}/>
|
|
85
|
+
<span data-role="value">{options.value}</span>
|
|
86
|
+
</fieldset>);
|
|
87
|
+
}
|
|
88
|
+
return (<fieldset className="field" data-field={label}>
|
|
89
|
+
<legend>{label}</legend>
|
|
90
|
+
<input type="text" data-role="editor" value={options.value} onChange={(event) => options.onChange(event.target.value)}/>
|
|
91
|
+
<span data-role="value">{options.value}</span>
|
|
92
|
+
</fieldset>);
|
|
93
|
+
};
|
|
94
|
+
return (<section>
|
|
95
|
+
<h2 className="title">react</h2>
|
|
96
|
+
<div className="render-meta" data-render-count={renderCount.current}>
|
|
97
|
+
Render #{renderCount.current}
|
|
98
|
+
</div>
|
|
99
|
+
<div className="field-grid">
|
|
100
|
+
{renderPrimitiveField("type", {
|
|
101
|
+
type: "text",
|
|
102
|
+
value: state.type,
|
|
103
|
+
onChange: (next) => {
|
|
104
|
+
state.type = next;
|
|
105
|
+
},
|
|
106
|
+
})}
|
|
107
|
+
{renderPrimitiveField("stringValue", {
|
|
108
|
+
type: "text",
|
|
109
|
+
value: state.stringValue,
|
|
110
|
+
onChange: (next) => {
|
|
111
|
+
state.stringValue = next;
|
|
112
|
+
},
|
|
113
|
+
})}
|
|
114
|
+
{renderPrimitiveField("numValue", {
|
|
115
|
+
type: "number",
|
|
116
|
+
value: state.numValue,
|
|
117
|
+
onChange: (next) => {
|
|
118
|
+
state.numValue = next;
|
|
119
|
+
},
|
|
120
|
+
})}
|
|
121
|
+
{renderPrimitiveField("boolValue", {
|
|
122
|
+
type: "boolean",
|
|
123
|
+
value: state.boolValue,
|
|
124
|
+
onChange: (next) => {
|
|
125
|
+
state.boolValue = next;
|
|
126
|
+
},
|
|
127
|
+
})}
|
|
128
|
+
{renderPrimitiveField("objectValue.nestedString", {
|
|
129
|
+
type: "text",
|
|
130
|
+
value: state.objectValue.nestedString,
|
|
131
|
+
onChange: (next) => {
|
|
132
|
+
state.objectValue.nestedString = next;
|
|
133
|
+
},
|
|
134
|
+
})}
|
|
135
|
+
{renderPrimitiveField("objectValue.nestedNum", {
|
|
136
|
+
type: "number",
|
|
137
|
+
value: state.objectValue.nestedNum,
|
|
138
|
+
onChange: (next) => {
|
|
139
|
+
state.objectValue.nestedNum = next;
|
|
140
|
+
},
|
|
141
|
+
})}
|
|
142
|
+
</div>
|
|
143
|
+
|
|
144
|
+
<fieldset className="field" data-field="arrayValue">
|
|
145
|
+
<legend>arrayValue</legend>
|
|
146
|
+
<div className="stack">
|
|
147
|
+
<span data-role="array-length">
|
|
148
|
+
Length: {state.arrayValue.length}
|
|
149
|
+
</span>
|
|
150
|
+
<div>
|
|
151
|
+
<button type="button" data-action="push" onClick={() => {
|
|
152
|
+
state.arrayValue.push(state.arrayValue.length + 1);
|
|
153
|
+
}}>
|
|
154
|
+
Add item
|
|
155
|
+
</button>
|
|
156
|
+
<button type="button" data-action="pop" onClick={() => {
|
|
157
|
+
if (state.arrayValue.length)
|
|
158
|
+
state.arrayValue.pop();
|
|
159
|
+
}}>
|
|
160
|
+
Remove item
|
|
161
|
+
</button>
|
|
162
|
+
</div>
|
|
163
|
+
<ul className="value-list">
|
|
164
|
+
{state.arrayValue.map((value, index) => (<li key={`array-${index}`}>{value}</li>))}
|
|
165
|
+
</ul>
|
|
166
|
+
</div>
|
|
167
|
+
</fieldset>
|
|
168
|
+
|
|
169
|
+
<fieldset className="field" data-field="objectValue.nestedArray">
|
|
170
|
+
<legend>objectValue.nestedArray</legend>
|
|
171
|
+
<div className="stack">
|
|
172
|
+
<span data-role="array-length">
|
|
173
|
+
Length: {state.objectValue.nestedArray.length}
|
|
174
|
+
</span>
|
|
175
|
+
<div>
|
|
176
|
+
<button type="button" data-action="push" onClick={() => {
|
|
177
|
+
state.objectValue.nestedArray.push(state.objectValue.nestedArray.length + 10);
|
|
178
|
+
}}>
|
|
179
|
+
Add nested item
|
|
180
|
+
</button>
|
|
181
|
+
<button type="button" data-action="pop" onClick={() => {
|
|
182
|
+
if (state.objectValue.nestedArray.length) {
|
|
183
|
+
state.objectValue.nestedArray.pop();
|
|
184
|
+
}
|
|
185
|
+
}}>
|
|
186
|
+
Remove nested item
|
|
187
|
+
</button>
|
|
188
|
+
</div>
|
|
189
|
+
<ul className="value-list">
|
|
190
|
+
{state.objectValue.nestedArray.map((value, index) => (<li key={`nested-${index}`}>{value}</li>))}
|
|
191
|
+
</ul>
|
|
192
|
+
</div>
|
|
193
|
+
</fieldset>
|
|
194
|
+
|
|
195
|
+
<fieldset className="field" data-field="setValue">
|
|
196
|
+
<legend>setValue</legend>
|
|
197
|
+
<div className="stack">
|
|
198
|
+
<span data-role="set-size">
|
|
199
|
+
Size: {state.setValue.size}
|
|
200
|
+
</span>
|
|
201
|
+
<div>
|
|
202
|
+
<button type="button" data-action="add" onClick={() => {
|
|
203
|
+
state.setValue.add(`item${state.setValue.size + 1}`);
|
|
204
|
+
}}>
|
|
205
|
+
Add entry
|
|
206
|
+
</button>
|
|
207
|
+
<button type="button" data-action="remove" onClick={() => {
|
|
208
|
+
const last = Array.from(state.setValue.values()).pop();
|
|
209
|
+
if (last)
|
|
210
|
+
state.setValue.delete(last);
|
|
211
|
+
}}>
|
|
212
|
+
Remove entry
|
|
213
|
+
</button>
|
|
214
|
+
</div>
|
|
215
|
+
<ul className="value-list">
|
|
216
|
+
{Array.from(state.setValue.values()).map((entry) => (<li key={`set-${entry}`}>{entry}</li>))}
|
|
217
|
+
</ul>
|
|
218
|
+
</div>
|
|
219
|
+
</fieldset>
|
|
220
|
+
|
|
221
|
+
<fieldset className="field" data-field="objectSet">
|
|
222
|
+
<legend>objectSet entries</legend>
|
|
223
|
+
{objectEntries.map((entry) => (<ObjectRow entry={entry} key={entry["@id"]}/>))}
|
|
224
|
+
</fieldset>
|
|
225
|
+
</section>);
|
|
226
|
+
};
|
|
227
|
+
exports.default = ReactPanel;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactPerfDeep.d.ts","sourceRoot":"","sources":["../../../../../../../../src/test/frontend/astro-app/src/components/perf/react/ReactPerfDeep.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AA4D3D,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAwG1B,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const react_1 = __importStar(require("react"));
|
|
40
|
+
const useDeepSignal_1 = __importDefault(require("../../../../../../../hooks/react/useDeepSignal"));
|
|
41
|
+
const state_1 = require("../../../../../utils/state");
|
|
42
|
+
const renderMetrics_1 = require("../../../../../utils/renderMetrics");
|
|
43
|
+
const perfScenarios_1 = require("../../../../../utils/perfScenarios");
|
|
44
|
+
const alien_signals_1 = require("alien-signals");
|
|
45
|
+
const ObjectRow = ({ entry }) => {
|
|
46
|
+
const rowRenderCount = (0, react_1.useRef)(0);
|
|
47
|
+
rowRenderCount.current += 1;
|
|
48
|
+
(0, renderMetrics_1.recordObjectRender)("react", entry["@id"], rowRenderCount.current);
|
|
49
|
+
(0, useDeepSignal_1.default)(entry);
|
|
50
|
+
return (<div className="object-row" data-entry-id={entry["@id"]} data-render-count={rowRenderCount.current}>
|
|
51
|
+
<span className="object-id">{entry["@id"]}</span>
|
|
52
|
+
<input type="text" value={entry.label} data-role="label" onChange={(event) => (entry.label = event.target.value)}/>
|
|
53
|
+
<input type="number" value={entry.count} data-role="count-input" onChange={(event) => (entry.count = Number(event.target.value || 0))}/>
|
|
54
|
+
<span data-role="count">{entry.count}</span>
|
|
55
|
+
<button type="button" data-action="increment" onClick={() => {
|
|
56
|
+
entry.count += 1;
|
|
57
|
+
}}>
|
|
58
|
+
+1
|
|
59
|
+
</button>
|
|
60
|
+
</div>);
|
|
61
|
+
};
|
|
62
|
+
const ReactPerfDeep = () => {
|
|
63
|
+
const state = state_1.sharedState;
|
|
64
|
+
const [revision, bumpRevision] = (0, react_1.useState)(0);
|
|
65
|
+
(0, react_1.useEffect)(() => {
|
|
66
|
+
const stop = (0, alien_signals_1.effect)(() => {
|
|
67
|
+
const objectSet = state_1.sharedState.objectSet;
|
|
68
|
+
if (!objectSet)
|
|
69
|
+
return;
|
|
70
|
+
void objectSet.size;
|
|
71
|
+
bumpRevision((value) => value + 1);
|
|
72
|
+
});
|
|
73
|
+
return stop;
|
|
74
|
+
}, []);
|
|
75
|
+
const renderCount = (0, react_1.useRef)(0);
|
|
76
|
+
const [busy, setBusy] = (0, react_1.useState)(false);
|
|
77
|
+
renderCount.current += 1;
|
|
78
|
+
(0, react_1.useEffect)(() => {
|
|
79
|
+
const dispose = (0, perfScenarios_1.registerSharedStateAdapter)("react");
|
|
80
|
+
return () => dispose();
|
|
81
|
+
}, []);
|
|
82
|
+
(0, react_1.useEffect)(() => {
|
|
83
|
+
if (typeof window !== "undefined") {
|
|
84
|
+
window.__reactSharedIdentity = state === state_1.sharedState;
|
|
85
|
+
window.__reactSharedGlobal =
|
|
86
|
+
state === window.sharedState;
|
|
87
|
+
}
|
|
88
|
+
}, []);
|
|
89
|
+
(0, react_1.useEffect)(() => {
|
|
90
|
+
(0, renderMetrics_1.recordRender)("react", renderCount.current);
|
|
91
|
+
});
|
|
92
|
+
const handleAddEntry = () => {
|
|
93
|
+
const objectSet = state.objectSet;
|
|
94
|
+
if (!objectSet)
|
|
95
|
+
return;
|
|
96
|
+
const id = `react-deep-${Math.random().toString(36).slice(2, 8)}`;
|
|
97
|
+
objectSet.add({
|
|
98
|
+
"@id": id,
|
|
99
|
+
label: `react ${id}`,
|
|
100
|
+
count: 0,
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
const handleRemoveEntry = () => {
|
|
104
|
+
const objectSet = state.objectSet;
|
|
105
|
+
if (!objectSet)
|
|
106
|
+
return;
|
|
107
|
+
const last = Array.from(objectSet.values()).pop();
|
|
108
|
+
if (!last)
|
|
109
|
+
return;
|
|
110
|
+
objectSet.delete(last);
|
|
111
|
+
};
|
|
112
|
+
const handleRunScenario = async () => {
|
|
113
|
+
try {
|
|
114
|
+
setBusy(true);
|
|
115
|
+
await (0, perfScenarios_1.runScenarioImmediately)("react", "deep");
|
|
116
|
+
}
|
|
117
|
+
finally {
|
|
118
|
+
setBusy(false);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
const entries = Array.from(state.objectSet?.values?.() ?? []);
|
|
122
|
+
const objectSetSize = state.objectSet?.size ?? entries.length;
|
|
123
|
+
return (<section className="perf-panel react" data-field="objectSet">
|
|
124
|
+
<h2 className="title">react (deepSignal)</h2>
|
|
125
|
+
<div className="render-meta" data-render-count={renderCount.current}>
|
|
126
|
+
Render #{renderCount.current}
|
|
127
|
+
</div>
|
|
128
|
+
<div className="field" data-field="objectSet">
|
|
129
|
+
<legend>objectSet entries</legend>
|
|
130
|
+
<div className="set-controls">
|
|
131
|
+
<span data-role="set-size">Size: {objectSetSize}</span>
|
|
132
|
+
<div>
|
|
133
|
+
<button type="button" onClick={handleAddEntry}>
|
|
134
|
+
Add entry
|
|
135
|
+
</button>
|
|
136
|
+
<button type="button" onClick={handleRemoveEntry}>
|
|
137
|
+
Remove entry
|
|
138
|
+
</button>
|
|
139
|
+
<button type="button" data-action="run-scenario" onClick={handleRunScenario} disabled={busy}>
|
|
140
|
+
{busy ? "Running…" : "Run perf scenario"}
|
|
141
|
+
</button>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
<div className="object-set">
|
|
145
|
+
{entries.map((entry) => (<ObjectRow key={entry["@id"]} entry={entry}/>))}
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</section>);
|
|
149
|
+
};
|
|
150
|
+
exports.default = ReactPerfDeep;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactPerfNative.d.ts","sourceRoot":"","sources":["../../../../../../../../src/test/frontend/astro-app/src/components/perf/react/ReactPerfNative.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AA4Ef,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EA8I5B,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const react_1 = __importStar(require("react"));
|
|
37
|
+
const mockData_1 = require("../../../../../utils/mockData");
|
|
38
|
+
const renderMetrics_1 = require("../../../../../utils/renderMetrics");
|
|
39
|
+
const perfScenarios_1 = require("../../../../../utils/perfScenarios");
|
|
40
|
+
const ObjectRow = ({ entry, updateEntries }) => {
|
|
41
|
+
const rowRenderCount = (0, react_1.useRef)(0);
|
|
42
|
+
rowRenderCount.current += 1;
|
|
43
|
+
(0, renderMetrics_1.recordObjectRender)("react", entry["@id"], rowRenderCount.current);
|
|
44
|
+
return (<div className="object-row" data-entry-id={entry["@id"]} data-render-count={rowRenderCount.current}>
|
|
45
|
+
<span className="object-id">{entry["@id"]}</span>
|
|
46
|
+
<input type="text" data-role="label" value={entry.label} onChange={(event) => updateEntries((draft) => {
|
|
47
|
+
const target = draft.find((item) => item["@id"] === entry["@id"]);
|
|
48
|
+
if (target)
|
|
49
|
+
target.label = event.target.value;
|
|
50
|
+
})}/>
|
|
51
|
+
<input type="number" data-role="count-input" value={entry.count} onChange={(event) => updateEntries((draft) => {
|
|
52
|
+
const target = draft.find((item) => item["@id"] === entry["@id"]);
|
|
53
|
+
if (target)
|
|
54
|
+
target.count = Number(event.target.value || 0);
|
|
55
|
+
})}/>
|
|
56
|
+
<span data-role="count">{entry.count}</span>
|
|
57
|
+
<button type="button" data-action="increment" onClick={() => updateEntries((draft) => {
|
|
58
|
+
const target = draft.find((item) => item["@id"] === entry["@id"]);
|
|
59
|
+
if (target)
|
|
60
|
+
target.count += 1;
|
|
61
|
+
})}>
|
|
62
|
+
+1
|
|
63
|
+
</button>
|
|
64
|
+
</div>);
|
|
65
|
+
};
|
|
66
|
+
const cloneInitialEntries = () => (0, mockData_1.cloneDefaultObjectSet)();
|
|
67
|
+
const ReactPerfNative = () => {
|
|
68
|
+
const [objectSet, setObjectSet] = (0, react_1.useState)(() => new Set(cloneInitialEntries()));
|
|
69
|
+
const renderCount = (0, react_1.useRef)(0);
|
|
70
|
+
const counterRef = (0, react_1.useRef)(0);
|
|
71
|
+
const [busy, setBusy] = (0, react_1.useState)(false);
|
|
72
|
+
renderCount.current += 1;
|
|
73
|
+
(0, react_1.useEffect)(() => {
|
|
74
|
+
(0, renderMetrics_1.recordRender)("react", renderCount.current);
|
|
75
|
+
});
|
|
76
|
+
const entries = (0, react_1.useMemo)(() => Array.from(objectSet.values()), [objectSet]);
|
|
77
|
+
const updateEntries = (0, react_1.useCallback)((mutate) => {
|
|
78
|
+
setObjectSet((prev) => {
|
|
79
|
+
const draft = Array.from(prev.values()).map((entry) => ({
|
|
80
|
+
...entry,
|
|
81
|
+
}));
|
|
82
|
+
mutate(draft);
|
|
83
|
+
return new Set(draft);
|
|
84
|
+
});
|
|
85
|
+
}, []);
|
|
86
|
+
(0, react_1.useEffect)(() => {
|
|
87
|
+
const dispose = (0, perfScenarios_1.registerScenarioAdapter)("react", "native", {
|
|
88
|
+
reset: () => {
|
|
89
|
+
setObjectSet(new Set(cloneInitialEntries()));
|
|
90
|
+
},
|
|
91
|
+
mutateExisting: (iterations) => {
|
|
92
|
+
updateEntries((draft) => {
|
|
93
|
+
if (!draft.length)
|
|
94
|
+
return;
|
|
95
|
+
for (let cycle = 0; cycle < iterations; cycle += 1) {
|
|
96
|
+
draft.forEach((entry, index) => {
|
|
97
|
+
entry.label = `POJO ${entry["@id"]} #${cycle}-${index}`;
|
|
98
|
+
entry.count += 2;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
bulkMutate: (iterations) => {
|
|
104
|
+
updateEntries((draft) => {
|
|
105
|
+
if (!draft.length)
|
|
106
|
+
return;
|
|
107
|
+
for (let i = 0; i < iterations; i += 1) {
|
|
108
|
+
for (const entry of draft) {
|
|
109
|
+
entry.count += 2;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
batchAddRemove: (iterations) => {
|
|
115
|
+
const additions = [];
|
|
116
|
+
for (let i = 0; i < iterations; i += 1) {
|
|
117
|
+
counterRef.current += 1;
|
|
118
|
+
const id = `react-native-${counterRef.current}`;
|
|
119
|
+
additions.push({
|
|
120
|
+
"@id": id,
|
|
121
|
+
label: `Native ${id}`,
|
|
122
|
+
count: i,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
updateEntries((draft) => {
|
|
126
|
+
draft.push(...additions);
|
|
127
|
+
});
|
|
128
|
+
updateEntries((draft) => {
|
|
129
|
+
const start = Math.max(draft.length - additions.length, 0);
|
|
130
|
+
draft.splice(start, additions.length);
|
|
131
|
+
});
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
return () => dispose();
|
|
135
|
+
}, [updateEntries]);
|
|
136
|
+
const handleAddEntry = () => {
|
|
137
|
+
counterRef.current += 1;
|
|
138
|
+
const id = `react-native-${counterRef.current}`;
|
|
139
|
+
updateEntries((draft) => {
|
|
140
|
+
draft.push({ "@id": id, label: `Native ${id}`, count: 0 });
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
const handleRemoveEntry = () => {
|
|
144
|
+
updateEntries((draft) => {
|
|
145
|
+
draft.pop();
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
const handleRunScenario = async () => {
|
|
149
|
+
try {
|
|
150
|
+
setBusy(true);
|
|
151
|
+
await (0, perfScenarios_1.runScenarioImmediately)("react", "native");
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
setBusy(false);
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
return (<section className="perf-panel react" data-field="objectSet">
|
|
158
|
+
<h2 className="title">react (native state)</h2>
|
|
159
|
+
<div className="render-meta" data-render-count={renderCount.current}>
|
|
160
|
+
Render #{renderCount.current}
|
|
161
|
+
</div>
|
|
162
|
+
<div className="field" data-field="objectSet">
|
|
163
|
+
<legend>objectSet entries</legend>
|
|
164
|
+
<div className="set-controls">
|
|
165
|
+
<span data-role="set-size">Size: {objectSet.size}</span>
|
|
166
|
+
<div>
|
|
167
|
+
<button type="button" onClick={handleAddEntry}>
|
|
168
|
+
Add entry
|
|
169
|
+
</button>
|
|
170
|
+
<button type="button" onClick={handleRemoveEntry}>
|
|
171
|
+
Remove entry
|
|
172
|
+
</button>
|
|
173
|
+
<button type="button" data-action="run-scenario" onClick={handleRunScenario} disabled={busy}>
|
|
174
|
+
{busy ? "Running…" : "Run perf scenario"}
|
|
175
|
+
</button>
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
<div className="object-set">
|
|
179
|
+
{entries.map((entry) => (<ObjectRow key={entry["@id"]} entry={entry} updateEntries={updateEntries}/>))}
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
</section>);
|
|
183
|
+
};
|
|
184
|
+
exports.default = ReactPerfNative;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crossFrameworkHooks.spec.d.ts","sourceRoot":"","sources":["../../../../src/test/frontend/playwright/crossFrameworkHooks.spec.ts"],"names":[],"mappings":""}
|