@creact-labs/creact 0.2.6 → 0.2.8
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/primitives/instance.js +57 -11
- package/package.json +1 -1
|
@@ -4,6 +4,26 @@
|
|
|
4
4
|
import { createSignal } from '../reactive/signal';
|
|
5
5
|
import { batch } from '../reactive/tracking';
|
|
6
6
|
import { getCurrentFiber, getCurrentResourcePath, pushResourcePath } from '../runtime/render';
|
|
7
|
+
/**
|
|
8
|
+
* Shallow equality check for output deduplication
|
|
9
|
+
*/
|
|
10
|
+
function shallowEqual(a, b) {
|
|
11
|
+
if (a === b)
|
|
12
|
+
return true;
|
|
13
|
+
if (a == null || b == null)
|
|
14
|
+
return false;
|
|
15
|
+
if (typeof a !== 'object' || typeof b !== 'object')
|
|
16
|
+
return false;
|
|
17
|
+
const keysA = Object.keys(a);
|
|
18
|
+
const keysB = Object.keys(b);
|
|
19
|
+
if (keysA.length !== keysB.length)
|
|
20
|
+
return false;
|
|
21
|
+
for (const key of keysA) {
|
|
22
|
+
if (a[key] !== b[key])
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
7
27
|
// Registry of all instance nodes by ID
|
|
8
28
|
const nodeRegistry = new Map();
|
|
9
29
|
// Track which fiber owns each nodeId (to detect duplicate siblings)
|
|
@@ -101,9 +121,23 @@ export function useInstance(construct, props) {
|
|
|
101
121
|
outputSignals: new Map(),
|
|
102
122
|
children: [],
|
|
103
123
|
setOutputs(outputs) {
|
|
104
|
-
//
|
|
105
|
-
|
|
106
|
-
|
|
124
|
+
// First check if any values actually changed
|
|
125
|
+
let hasChanges = false;
|
|
126
|
+
for (const [key, value] of Object.entries(outputs)) {
|
|
127
|
+
if (!this.outputSignals.has(key)) {
|
|
128
|
+
hasChanges = true;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
const [read] = this.outputSignals.get(key);
|
|
132
|
+
if (!shallowEqual(read(), value)) {
|
|
133
|
+
hasChanges = true;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Early exit if nothing changed - no re-render needed
|
|
138
|
+
if (!hasChanges)
|
|
139
|
+
return;
|
|
140
|
+
// Only clear ownership and batch if there are actual changes
|
|
107
141
|
nodeOwnership.clear();
|
|
108
142
|
batch(() => {
|
|
109
143
|
for (const [key, value] of Object.entries(outputs)) {
|
|
@@ -112,8 +146,7 @@ export function useInstance(construct, props) {
|
|
|
112
146
|
}
|
|
113
147
|
else {
|
|
114
148
|
const [read, write] = this.outputSignals.get(key);
|
|
115
|
-
|
|
116
|
-
if (read() !== value) {
|
|
149
|
+
if (!shallowEqual(read(), value)) {
|
|
117
150
|
write(value);
|
|
118
151
|
}
|
|
119
152
|
}
|
|
@@ -139,7 +172,7 @@ export function useInstance(construct, props) {
|
|
|
139
172
|
else {
|
|
140
173
|
const [read, write] = node.outputSignals.get(key);
|
|
141
174
|
// Only update if value actually changed
|
|
142
|
-
if (read()
|
|
175
|
+
if (!shallowEqual(read(), value)) {
|
|
143
176
|
write(value);
|
|
144
177
|
}
|
|
145
178
|
}
|
|
@@ -194,16 +227,29 @@ export function fillInstanceOutputs(nodeId, outputs) {
|
|
|
194
227
|
const node = nodeRegistry.get(nodeId);
|
|
195
228
|
if (!node)
|
|
196
229
|
return;
|
|
197
|
-
//
|
|
198
|
-
|
|
199
|
-
|
|
230
|
+
// First check if any values actually changed
|
|
231
|
+
let hasChanges = false;
|
|
232
|
+
for (const [key, value] of Object.entries(outputs)) {
|
|
233
|
+
if (!node.outputSignals.has(key)) {
|
|
234
|
+
hasChanges = true;
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
const [read] = node.outputSignals.get(key);
|
|
238
|
+
if (!shallowEqual(read(), value)) {
|
|
239
|
+
hasChanges = true;
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Early exit if nothing changed - no re-render needed
|
|
244
|
+
if (!hasChanges)
|
|
245
|
+
return;
|
|
246
|
+
// Only clear ownership and batch if there are actual changes
|
|
200
247
|
nodeOwnership.clear();
|
|
201
248
|
batch(() => {
|
|
202
249
|
for (const [key, value] of Object.entries(outputs)) {
|
|
203
250
|
if (node.outputSignals.has(key)) {
|
|
204
251
|
const [read, write] = node.outputSignals.get(key);
|
|
205
|
-
|
|
206
|
-
if (read() !== value) {
|
|
252
|
+
if (!shallowEqual(read(), value)) {
|
|
207
253
|
write(value);
|
|
208
254
|
}
|
|
209
255
|
}
|