@ng-org/alien-deepsignals 0.1.2-alpha.3 → 0.1.2-alpha.5
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 +168 -16
- 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/package.json +1 -2
|
@@ -0,0 +1,225 @@
|
|
|
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 perfScenarios_1 = require("../../../utils/perfScenarios");
|
|
38
|
+
const MAX_RESULTS = 12;
|
|
39
|
+
const sortResults = (results) => [...results].sort((a, b) => (b.completedAt ?? 0) - (a.completedAt ?? 0));
|
|
40
|
+
const resultSignature = (result) => [
|
|
41
|
+
result.framework,
|
|
42
|
+
result.variant,
|
|
43
|
+
result.completedAt ?? result.totalDuration,
|
|
44
|
+
result.runCount,
|
|
45
|
+
].join(":");
|
|
46
|
+
const attachEntryId = (result) => ({
|
|
47
|
+
...result,
|
|
48
|
+
entryId: `${result.framework}-${result.variant}-${result.completedAt ?? Date.now()}-${Math.random()
|
|
49
|
+
.toString(36)
|
|
50
|
+
.slice(2, 8)}`,
|
|
51
|
+
});
|
|
52
|
+
const seedResults = () => {
|
|
53
|
+
if (typeof window === "undefined")
|
|
54
|
+
return [];
|
|
55
|
+
const latest = window.perfSuite?.latestResults;
|
|
56
|
+
if (!latest)
|
|
57
|
+
return [];
|
|
58
|
+
const flattened = Object.values(latest).flatMap((variants) => Object.values(variants));
|
|
59
|
+
return sortResults(flattened.map(attachEntryId));
|
|
60
|
+
};
|
|
61
|
+
const formatDuration = (value) => `${value.toFixed(2)}ms`;
|
|
62
|
+
const formatSubRenderCount = (block, framework) => {
|
|
63
|
+
const entries = block.objectRenderCounts?.[framework];
|
|
64
|
+
if (!entries)
|
|
65
|
+
return 0;
|
|
66
|
+
return Object.values(entries).reduce((sum, count) => sum + count, 0);
|
|
67
|
+
};
|
|
68
|
+
const PerfSuiteClient = () => {
|
|
69
|
+
const [results, setResults] = (0, react_1.useState)(seedResults);
|
|
70
|
+
(0, react_1.useEffect)(() => {
|
|
71
|
+
if ((0, perfScenarios_1.registerPerfRunners)()) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const timer = window.setInterval(() => {
|
|
75
|
+
if ((0, perfScenarios_1.registerPerfRunners)()) {
|
|
76
|
+
window.clearInterval(timer);
|
|
77
|
+
}
|
|
78
|
+
}, 50);
|
|
79
|
+
return () => {
|
|
80
|
+
window.clearInterval(timer);
|
|
81
|
+
};
|
|
82
|
+
}, []);
|
|
83
|
+
(0, react_1.useEffect)(() => {
|
|
84
|
+
if (typeof window === "undefined")
|
|
85
|
+
return;
|
|
86
|
+
const suite = window.perfSuite;
|
|
87
|
+
if (!suite?.subscribe)
|
|
88
|
+
return;
|
|
89
|
+
const unsubscribe = suite.subscribe((result) => {
|
|
90
|
+
setResults((current) => {
|
|
91
|
+
if (current.some((entry) => resultSignature(entry) === resultSignature(result))) {
|
|
92
|
+
return current;
|
|
93
|
+
}
|
|
94
|
+
const augmented = attachEntryId(result);
|
|
95
|
+
const next = sortResults([augmented, ...current]);
|
|
96
|
+
return next.slice(0, MAX_RESULTS);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
return unsubscribe;
|
|
100
|
+
}, []);
|
|
101
|
+
const renderedList = (0, react_1.useMemo)(() => {
|
|
102
|
+
if (!results.length) {
|
|
103
|
+
return (<p className="perf-suite-results__empty">
|
|
104
|
+
Awaiting perf runner output…
|
|
105
|
+
</p>);
|
|
106
|
+
}
|
|
107
|
+
return results.map((result) => (<li key={result.entryId} className="perf-suite-results__item">
|
|
108
|
+
<header>
|
|
109
|
+
<strong>
|
|
110
|
+
{result.framework}/{result.variant}
|
|
111
|
+
</strong>
|
|
112
|
+
<span>{formatDuration(result.totalDuration)}</span>
|
|
113
|
+
</header>
|
|
114
|
+
<div className="perf-suite-results__meta">
|
|
115
|
+
<span>
|
|
116
|
+
runs {result.runCount}
|
|
117
|
+
{result.warmupCount
|
|
118
|
+
? ` (+${result.warmupCount} warmup)`
|
|
119
|
+
: ""}
|
|
120
|
+
</span>
|
|
121
|
+
{result.completedAt ? (<time>
|
|
122
|
+
{new Date(result.completedAt).toLocaleTimeString()}
|
|
123
|
+
</time>) : null}
|
|
124
|
+
</div>
|
|
125
|
+
<dl>
|
|
126
|
+
{Object.entries(result.blocks).map(([name, block]) => (<react_1.default.Fragment key={name}>
|
|
127
|
+
<div className="perf-suite-results__block">
|
|
128
|
+
<dt>{name}</dt>
|
|
129
|
+
<dd>{formatDuration(block.duration)}</dd>
|
|
130
|
+
</div>
|
|
131
|
+
<div className="perf-suite-results__block perf-suite-results__block--subrenders">
|
|
132
|
+
<dt>Subcomponent renders</dt>
|
|
133
|
+
<dd>
|
|
134
|
+
{formatSubRenderCount(block, result.framework)}
|
|
135
|
+
</dd>
|
|
136
|
+
</div>
|
|
137
|
+
</react_1.default.Fragment>))}
|
|
138
|
+
</dl>
|
|
139
|
+
</li>));
|
|
140
|
+
}, [results]);
|
|
141
|
+
return (<div className="perf-suite-results">
|
|
142
|
+
<div className="perf-suite-results__header">
|
|
143
|
+
<h3>Latest Perf Runs</h3>
|
|
144
|
+
<p>Playwright tests stream into this dashboard.</p>
|
|
145
|
+
</div>
|
|
146
|
+
<ul>{renderedList}</ul>
|
|
147
|
+
<style>
|
|
148
|
+
{`
|
|
149
|
+
.perf-suite-results {
|
|
150
|
+
border: 1px solid var(--astro-color-border, rgba(120, 120, 120, 0.4));
|
|
151
|
+
border-radius: 0.75rem;
|
|
152
|
+
padding: 1rem;
|
|
153
|
+
margin-top: 1.5rem;
|
|
154
|
+
max-width: 720px;
|
|
155
|
+
}
|
|
156
|
+
.perf-suite-results__header {
|
|
157
|
+
display: flex;
|
|
158
|
+
flex-direction: column;
|
|
159
|
+
gap: 0.25rem;
|
|
160
|
+
margin-bottom: 0.5rem;
|
|
161
|
+
}
|
|
162
|
+
.perf-suite-results__header h3 {
|
|
163
|
+
margin: 0;
|
|
164
|
+
font-size: 1.1rem;
|
|
165
|
+
}
|
|
166
|
+
.perf-suite-results__header p {
|
|
167
|
+
margin: 0;
|
|
168
|
+
opacity: 0.8;
|
|
169
|
+
font-size: 0.9rem;
|
|
170
|
+
}
|
|
171
|
+
.perf-suite-results ul {
|
|
172
|
+
list-style: none;
|
|
173
|
+
padding: 0;
|
|
174
|
+
margin: 0;
|
|
175
|
+
display: flex;
|
|
176
|
+
flex-direction: column;
|
|
177
|
+
gap: 0.75rem;
|
|
178
|
+
}
|
|
179
|
+
.perf-suite-results__item {
|
|
180
|
+
background: rgba(120, 120, 120, 0.08);
|
|
181
|
+
border: 1px solid rgba(120, 120, 120, 0.3);
|
|
182
|
+
border-radius: 0.5rem;
|
|
183
|
+
padding: 0.75rem;
|
|
184
|
+
display: flex;
|
|
185
|
+
flex-direction: column;
|
|
186
|
+
gap: 0.35rem;
|
|
187
|
+
}
|
|
188
|
+
.perf-suite-results__item header {
|
|
189
|
+
display: flex;
|
|
190
|
+
justify-content: space-between;
|
|
191
|
+
font-size: 0.95rem;
|
|
192
|
+
}
|
|
193
|
+
.perf-suite-results__item header strong {
|
|
194
|
+
text-transform: capitalize;
|
|
195
|
+
}
|
|
196
|
+
.perf-suite-results__meta {
|
|
197
|
+
display: flex;
|
|
198
|
+
justify-content: space-between;
|
|
199
|
+
font-size: 0.8rem;
|
|
200
|
+
opacity: 0.8;
|
|
201
|
+
}
|
|
202
|
+
.perf-suite-results__block {
|
|
203
|
+
display: flex;
|
|
204
|
+
justify-content: space-between;
|
|
205
|
+
font-size: 0.85rem;
|
|
206
|
+
}
|
|
207
|
+
.perf-suite-results__block--subrenders {
|
|
208
|
+
opacity: 0.85;
|
|
209
|
+
}
|
|
210
|
+
.perf-suite-results__block dt {
|
|
211
|
+
margin: 0;
|
|
212
|
+
text-transform: capitalize;
|
|
213
|
+
}
|
|
214
|
+
.perf-suite-results__block dd {
|
|
215
|
+
margin: 0;
|
|
216
|
+
}
|
|
217
|
+
.perf-suite-results__empty {
|
|
218
|
+
font-style: italic;
|
|
219
|
+
opacity: 0.8;
|
|
220
|
+
}
|
|
221
|
+
`}
|
|
222
|
+
</style>
|
|
223
|
+
</div>);
|
|
224
|
+
};
|
|
225
|
+
exports.default = PerfSuiteClient;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactPanel.d.ts","sourceRoot":"","sources":["../../../../../../src/test/frontend/astro-app/src/components/ReactPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAMjD,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAqSvB,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -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"}
|