veles 1.1.2 → 1.1.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/{_utils-BnAXelPu.js → _utils-B1lbF1Al.js} +58 -32
- package/dist/{_utils-DbrPydEE.cjs → _utils-CXVRQTuz.cjs} +63 -31
- package/dist/{fragment-C16zCm8L.d.cts → fragment-COsp_SDE.d.cts} +3 -1
- package/dist/{fragment-yC0-T2O-.d.ts → fragment-CPcYB5D5.d.ts} +3 -1
- package/dist/index.cjs +221 -105
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +221 -105
- package/dist/jsx-runtime.cjs +1 -1
- package/dist/jsx-runtime.d.cts +1 -1
- package/dist/jsx-runtime.d.ts +1 -1
- package/dist/jsx-runtime.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require__utils = require("./_utils-
|
|
2
|
+
const require__utils = require("./_utils-CXVRQTuz.cjs");
|
|
3
3
|
//#region src/attach-component.ts
|
|
4
4
|
/**
|
|
5
5
|
* Attach Veles component tree to a regular HTML node.
|
|
@@ -66,69 +66,42 @@ function updateUseValueSelector({ value, selectorTrackingElement, newTrackingSel
|
|
|
66
66
|
newVelesElementNode.parentVelesElement = parentVelesElementRendered;
|
|
67
67
|
if ("executedVelesNode" in newVelesElementNode && newVelesElementNode.phantom) {
|
|
68
68
|
const insertAllPhantomChildren = (adjacentNode) => {
|
|
69
|
+
const adjacentSourceNode = require__utils.getExecutedVelesNodeSourceNode(adjacentNode);
|
|
69
70
|
newVelesElementNode.childComponents.forEach((childComponentofPhantom) => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
} else {
|
|
74
|
-
const velesElementNode = require__utils.getExecutedComponentVelesNode(childComponentofPhantom);
|
|
75
|
-
if (!velesElementNode) console.error("can't find HTML tree in a component chain");
|
|
76
|
-
else {
|
|
77
|
-
adjacentNode.html.before(velesElementNode.html);
|
|
78
|
-
velesElementNode.parentVelesElement = adjacentNode.parentVelesElement;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
71
|
+
const childNode = "executedVelesComponent" in childComponentofPhantom ? require__utils.getExecutedComponentVelesNode(childComponentofPhantom) : childComponentofPhantom;
|
|
72
|
+
adjacentSourceNode.before(require__utils.getExecutedVelesNodeSourceNode(childNode));
|
|
73
|
+
childNode.parentVelesElement = adjacentNode.parentVelesElement;
|
|
81
74
|
});
|
|
82
75
|
};
|
|
83
76
|
if ("executedVelesNode" in oldVelesElementNode && oldVelesElementNode.phantom) {
|
|
84
77
|
let isInserted = false;
|
|
85
78
|
oldVelesElementNode.childComponents.forEach((childComponentofPhantom) => {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
childComponentofPhantom.html.remove();
|
|
92
|
-
} else {
|
|
93
|
-
const velesElementNode = require__utils.getExecutedComponentVelesNode(childComponentofPhantom);
|
|
94
|
-
if (!velesElementNode) console.error("can't find HTML tree in a component chain");
|
|
95
|
-
else {
|
|
96
|
-
if (!isInserted) {
|
|
97
|
-
insertAllPhantomChildren(velesElementNode);
|
|
98
|
-
isInserted = true;
|
|
99
|
-
}
|
|
100
|
-
velesElementNode.html.remove();
|
|
101
|
-
}
|
|
79
|
+
const childNode = "executedVelesComponent" in childComponentofPhantom ? require__utils.getExecutedComponentVelesNode(childComponentofPhantom) : childComponentofPhantom;
|
|
80
|
+
if (!isInserted) {
|
|
81
|
+
insertAllPhantomChildren(childNode);
|
|
82
|
+
isInserted = true;
|
|
102
83
|
}
|
|
84
|
+
require__utils.getExecutedVelesNodeSourceNode(childNode).remove();
|
|
103
85
|
});
|
|
104
86
|
} else {
|
|
105
87
|
insertAllPhantomChildren(oldVelesElementNode);
|
|
106
|
-
oldVelesElementNode.
|
|
88
|
+
require__utils.getExecutedVelesNodeSourceNode(oldVelesElementNode).remove();
|
|
107
89
|
}
|
|
108
90
|
} else if ("executedVelesNode" in oldVelesElementNode && oldVelesElementNode.phantom) {
|
|
109
91
|
let isInserted = false;
|
|
110
92
|
oldVelesElementNode.childComponents.forEach((childComponentofPhantom) => {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
childComponentofPhantom.html.remove();
|
|
117
|
-
} else {
|
|
118
|
-
const velesElementNode = require__utils.getExecutedComponentVelesNode(childComponentofPhantom);
|
|
119
|
-
if (!velesElementNode) console.error("can't find HTML tree in a component chain");
|
|
120
|
-
else {
|
|
121
|
-
if (!isInserted) {
|
|
122
|
-
velesElementNode.html.before(newVelesElementNode.html);
|
|
123
|
-
isInserted = true;
|
|
124
|
-
}
|
|
125
|
-
velesElementNode.html.remove();
|
|
126
|
-
}
|
|
93
|
+
const childSourceNode = require__utils.getExecutedVelesNodeSourceNode("executedVelesComponent" in childComponentofPhantom ? require__utils.getExecutedComponentVelesNode(childComponentofPhantom) : childComponentofPhantom);
|
|
94
|
+
if (!isInserted) {
|
|
95
|
+
childSourceNode.before(require__utils.getExecutedVelesNodeSourceNode(newVelesElementNode));
|
|
96
|
+
isInserted = true;
|
|
127
97
|
}
|
|
98
|
+
childSourceNode.remove();
|
|
128
99
|
});
|
|
129
100
|
} else try {
|
|
130
|
-
|
|
131
|
-
|
|
101
|
+
const newSourceNode = require__utils.getExecutedVelesNodeSourceNode(newVelesElementNode);
|
|
102
|
+
const oldSourceNode = require__utils.getExecutedVelesNodeSourceNode(oldVelesElementNode);
|
|
103
|
+
if (parentVelesElementRendered.portal) parentVelesElementRendered.portal.replaceChild(newSourceNode, oldSourceNode);
|
|
104
|
+
else parentVelesElementRendered.html.replaceChild(newSourceNode, oldSourceNode);
|
|
132
105
|
} catch (e) {
|
|
133
106
|
console.error("failed to update in renderSelected", e);
|
|
134
107
|
}
|
|
@@ -205,7 +178,7 @@ function updateUseAttributeValue({ element, value }) {
|
|
|
205
178
|
//#endregion
|
|
206
179
|
//#region src/create-state/update-render-each-value.ts
|
|
207
180
|
function updateUseValueIteratorValue({ value, trackingIterator, createState }) {
|
|
208
|
-
const { cb, key, renderedElements, elementsByKey, wrapperComponent, selector, savedContext } = trackingIterator;
|
|
181
|
+
const { anchor, cb, key, renderedElements, elementsByKey, wrapperComponent, selector, savedContext } = trackingIterator;
|
|
209
182
|
if (!wrapperComponent) {
|
|
210
183
|
console.error("there is no wrapper component for the iterator");
|
|
211
184
|
return;
|
|
@@ -219,19 +192,19 @@ function updateUseValueIteratorValue({ value, trackingIterator, createState }) {
|
|
|
219
192
|
const elements = selector ? selector(value) : value;
|
|
220
193
|
if (Array.isArray(elements)) {
|
|
221
194
|
const newRenderedElements = [];
|
|
222
|
-
const newElementsByKey =
|
|
223
|
-
const renderedExistingElements =
|
|
195
|
+
const newElementsByKey = /* @__PURE__ */ new Map();
|
|
196
|
+
const renderedExistingElements = /* @__PURE__ */ new Set();
|
|
224
197
|
elements.forEach((element, index) => {
|
|
225
|
-
let calculatedKey =
|
|
198
|
+
let calculatedKey = null;
|
|
226
199
|
if (typeof key === "string" && typeof element === "object" && element !== null && key in element) calculatedKey = element[key];
|
|
227
200
|
else if (typeof key === "function") calculatedKey = key({
|
|
228
201
|
element,
|
|
229
202
|
index
|
|
230
203
|
});
|
|
231
|
-
if (
|
|
232
|
-
const existingElement = elementsByKey
|
|
204
|
+
if (calculatedKey == null) return;
|
|
205
|
+
const existingElement = elementsByKey.get(calculatedKey);
|
|
233
206
|
if (existingElement) {
|
|
234
|
-
renderedExistingElements
|
|
207
|
+
renderedExistingElements.add(calculatedKey);
|
|
235
208
|
if (existingElement.elementState.get() !== element) existingElement.elementState.set(element);
|
|
236
209
|
if (existingElement.indexState.get() !== index) existingElement.indexState.set(index);
|
|
237
210
|
newRenderedElements.push([
|
|
@@ -239,12 +212,12 @@ function updateUseValueIteratorValue({ value, trackingIterator, createState }) {
|
|
|
239
212
|
calculatedKey,
|
|
240
213
|
existingElement.elementState
|
|
241
214
|
]);
|
|
242
|
-
newElementsByKey
|
|
215
|
+
newElementsByKey.set(calculatedKey, {
|
|
243
216
|
elementState: existingElement.elementState,
|
|
244
217
|
indexState: existingElement.indexState,
|
|
245
218
|
indexValue: index,
|
|
246
219
|
node: existingElement.node
|
|
247
|
-
};
|
|
220
|
+
});
|
|
248
221
|
} else {
|
|
249
222
|
const elementState = createState(element);
|
|
250
223
|
const indexState = createState(index);
|
|
@@ -260,12 +233,12 @@ function updateUseValueIteratorValue({ value, trackingIterator, createState }) {
|
|
|
260
233
|
calculatedKey,
|
|
261
234
|
elementState
|
|
262
235
|
]);
|
|
263
|
-
newElementsByKey
|
|
236
|
+
newElementsByKey.set(calculatedKey, {
|
|
264
237
|
elementState,
|
|
265
238
|
indexState,
|
|
266
239
|
indexValue: index,
|
|
267
240
|
node
|
|
268
|
-
};
|
|
241
|
+
});
|
|
269
242
|
}
|
|
270
243
|
});
|
|
271
244
|
const newChildRenderedComponents = [];
|
|
@@ -279,61 +252,65 @@ function updateUseValueIteratorValue({ value, trackingIterator, createState }) {
|
|
|
279
252
|
newChildComponents.push(newRenderedElement[0]);
|
|
280
253
|
if (positioningOffset[index]) offset = offset + positioningOffset[index];
|
|
281
254
|
const [newNode, calculatedKey, _newState] = newRenderedElement;
|
|
282
|
-
const existingElement = elementsByKey
|
|
255
|
+
const existingElement = elementsByKey.get(calculatedKey);
|
|
283
256
|
if (existingElement) {
|
|
284
|
-
const
|
|
257
|
+
const existingElementSourceNode = require__utils.getExecutedVelesNodeSourceNode(require__utils.getExecutedComponentVelesNode(require__utils.getMountedNodeExecutedVersion(existingElement.node, "Existing iterator node is expected to be mounted")));
|
|
285
258
|
if (existingElement.indexValue + offset === index) {
|
|
286
|
-
currentElement =
|
|
259
|
+
currentElement = existingElementSourceNode;
|
|
287
260
|
return;
|
|
288
261
|
}
|
|
289
262
|
if (existingElement.indexValue + offset > index) {
|
|
290
263
|
if (currentElement) {
|
|
291
|
-
currentElement.after(
|
|
264
|
+
currentElement.after(existingElementSourceNode);
|
|
292
265
|
positioningOffset[existingElement.indexValue + 1] = -1;
|
|
293
266
|
} else {
|
|
294
267
|
const firstRenderedElement = renderedElements[0]?.[0];
|
|
295
|
-
if (firstRenderedElement?.executedVersion) require__utils.getExecutedComponentVelesNode(firstRenderedElement.executedVersion).
|
|
268
|
+
if (firstRenderedElement?.executedVersion) require__utils.getExecutedVelesNodeSourceNode(require__utils.getExecutedComponentVelesNode(firstRenderedElement.executedVersion)).before(existingElementSourceNode);
|
|
296
269
|
}
|
|
297
|
-
currentElement =
|
|
270
|
+
currentElement = existingElementSourceNode;
|
|
298
271
|
offset = offset + 1;
|
|
299
272
|
} else {
|
|
300
273
|
if (currentElement) {
|
|
301
|
-
currentElement.after(
|
|
274
|
+
currentElement.after(existingElementSourceNode);
|
|
302
275
|
positioningOffset[existingElement.indexValue + 1] = 1;
|
|
303
276
|
} else {
|
|
304
277
|
const firstRenderedElement = renderedElements[0]?.[0];
|
|
305
|
-
if (firstRenderedElement?.executedVersion) require__utils.getExecutedComponentVelesNode(firstRenderedElement.executedVersion).
|
|
278
|
+
if (firstRenderedElement?.executedVersion) require__utils.getExecutedVelesNodeSourceNode(require__utils.getExecutedComponentVelesNode(firstRenderedElement.executedVersion)).before(existingElementSourceNode);
|
|
306
279
|
}
|
|
307
|
-
currentElement =
|
|
280
|
+
currentElement = existingElementSourceNode;
|
|
308
281
|
offset = offset - 1;
|
|
309
282
|
}
|
|
310
283
|
} else {
|
|
311
284
|
const newNodeExecutedVersion = require__utils.getMountedNodeExecutedVersion(newNode, "New iterator node is expected to be mounted");
|
|
312
285
|
const newNodeVelesElement = require__utils.getExecutedComponentVelesNode(newNodeExecutedVersion);
|
|
286
|
+
const newNodeSourceNode = require__utils.getExecutedVelesNodeSourceNode(newNodeVelesElement);
|
|
313
287
|
newNodeVelesElement.parentVelesElement = parentVelesElement;
|
|
314
|
-
if (currentElement) currentElement.after(
|
|
288
|
+
if (currentElement) currentElement.after(newNodeSourceNode);
|
|
315
289
|
else {
|
|
316
290
|
const firstRenderedElement = renderedElements[0]?.[0];
|
|
317
|
-
if (firstRenderedElement?.executedVersion) require__utils.getExecutedComponentVelesNode(firstRenderedElement.executedVersion).
|
|
318
|
-
else
|
|
291
|
+
if (firstRenderedElement?.executedVersion) require__utils.getExecutedVelesNodeSourceNode(require__utils.getExecutedComponentVelesNode(firstRenderedElement.executedVersion)).before(newNodeSourceNode);
|
|
292
|
+
else anchor.html.before(newNodeSourceNode);
|
|
319
293
|
}
|
|
320
294
|
offset = offset + 1;
|
|
321
|
-
currentElement =
|
|
295
|
+
currentElement = newNodeSourceNode;
|
|
322
296
|
newElementsCount = newElementsCount + 1;
|
|
323
297
|
require__utils.callMountHandlers(newNodeExecutedVersion);
|
|
324
298
|
}
|
|
325
299
|
});
|
|
326
300
|
if (renderedElements.length === newRenderedElements.length + newElementsCount) {} else renderedElements.forEach(([oldNode, calculatedKey]) => {
|
|
327
|
-
if (renderedExistingElements
|
|
301
|
+
if (renderedExistingElements.has(calculatedKey)) return;
|
|
328
302
|
else {
|
|
329
303
|
const oldNodeExecutedVersion = require__utils.getMountedNodeExecutedVersion(oldNode, "Removed iterator node is expected to be mounted");
|
|
330
|
-
require__utils.getExecutedComponentVelesNode(oldNodeExecutedVersion).
|
|
304
|
+
require__utils.getExecutedVelesNodeSourceNode(require__utils.getExecutedComponentVelesNode(oldNodeExecutedVersion)).remove();
|
|
331
305
|
require__utils.callUnmountHandlers(oldNodeExecutedVersion);
|
|
332
306
|
if ("executedVelesNode" in wrapperVelesElementNode) wrapperVelesElementNode.childComponents = wrapperVelesElementNode.childComponents.filter((childComponent) => childComponent !== oldNodeExecutedVersion);
|
|
333
307
|
else throw new Error("Wrapper iterator element is a string");
|
|
334
308
|
if ("velesNode" in wrapperComponent) wrapperComponent.childComponents = wrapperComponent.childComponents.filter((childComponent) => childComponent !== oldNode);
|
|
335
309
|
}
|
|
336
310
|
});
|
|
311
|
+
if (!anchor.executedVersion) throw new Error("Iterator anchor is expected to be mounted");
|
|
312
|
+
newChildRenderedComponents.push(anchor.executedVersion);
|
|
313
|
+
newChildComponents.push(anchor);
|
|
337
314
|
if ("executedVelesNode" in wrapperVelesElementNode) wrapperVelesElementNode.childComponents = newChildRenderedComponents;
|
|
338
315
|
if ("velesNode" in wrapperComponent) wrapperComponent.childComponents = newChildComponents;
|
|
339
316
|
trackingIterator.renderedElements = newRenderedElements;
|
|
@@ -370,6 +347,113 @@ function triggerUpdates({ value, createState, trackers, get }) {
|
|
|
370
347
|
});
|
|
371
348
|
}
|
|
372
349
|
//#endregion
|
|
350
|
+
//#region src/create-state/min-heap.ts
|
|
351
|
+
/**
|
|
352
|
+
* A stable min-heap. Values with the same priority are returned in
|
|
353
|
+
* insertion order.
|
|
354
|
+
*/
|
|
355
|
+
var MinHeap = class {
|
|
356
|
+
constructor(compareValues) {
|
|
357
|
+
this._entries = [];
|
|
358
|
+
this._insertionOrder = 0;
|
|
359
|
+
this._compareValues = compareValues;
|
|
360
|
+
}
|
|
361
|
+
get size() {
|
|
362
|
+
return this._entries.length;
|
|
363
|
+
}
|
|
364
|
+
push(value) {
|
|
365
|
+
const entry = {
|
|
366
|
+
value,
|
|
367
|
+
insertionOrder: this._insertionOrder++
|
|
368
|
+
};
|
|
369
|
+
let index = this._entries.length;
|
|
370
|
+
this._entries.push(entry);
|
|
371
|
+
while (index > 0) {
|
|
372
|
+
const parentIndex = Math.floor((index - 1) / 2);
|
|
373
|
+
const parentEntry = this._entries[parentIndex];
|
|
374
|
+
if (this.compareEntries(parentEntry, entry) <= 0) break;
|
|
375
|
+
this._entries[index] = parentEntry;
|
|
376
|
+
index = parentIndex;
|
|
377
|
+
}
|
|
378
|
+
this._entries[index] = entry;
|
|
379
|
+
}
|
|
380
|
+
pop() {
|
|
381
|
+
const firstEntry = this._entries[0];
|
|
382
|
+
const lastEntry = this._entries.pop();
|
|
383
|
+
if (!firstEntry || !lastEntry) return void 0;
|
|
384
|
+
if (this._entries.length === 0) return firstEntry.value;
|
|
385
|
+
let index = 0;
|
|
386
|
+
while (true) {
|
|
387
|
+
const leftChildIndex = index * 2 + 1;
|
|
388
|
+
const rightChildIndex = leftChildIndex + 1;
|
|
389
|
+
let smallestIndex = index;
|
|
390
|
+
if (leftChildIndex < this._entries.length && this.compareEntries(this._entries[leftChildIndex], lastEntry) < 0) smallestIndex = leftChildIndex;
|
|
391
|
+
if (rightChildIndex < this._entries.length && this.compareEntries(this._entries[rightChildIndex], smallestIndex === index ? lastEntry : this._entries[leftChildIndex]) < 0) smallestIndex = rightChildIndex;
|
|
392
|
+
if (smallestIndex === index) break;
|
|
393
|
+
this._entries[index] = this._entries[smallestIndex];
|
|
394
|
+
index = smallestIndex;
|
|
395
|
+
}
|
|
396
|
+
this._entries[index] = lastEntry;
|
|
397
|
+
return firstEntry.value;
|
|
398
|
+
}
|
|
399
|
+
compareEntries(entry1, entry2) {
|
|
400
|
+
const valueComparison = this._compareValues(entry1.value, entry2.value);
|
|
401
|
+
return valueComparison === 0 ? entry1.insertionOrder - entry2.insertionOrder : valueComparison;
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
//#endregion
|
|
405
|
+
//#region src/create-state/state-scheduler.ts
|
|
406
|
+
/**
|
|
407
|
+
* Coordinates notifications produced by one synchronous state transaction.
|
|
408
|
+
*
|
|
409
|
+
* A subscriber can synchronously update another state. That nested update adds
|
|
410
|
+
* its notifications to this same scheduler, allowing an older notification for
|
|
411
|
+
* the same state to be replaced before it is delivered.
|
|
412
|
+
*/
|
|
413
|
+
var StateScheduler = class {
|
|
414
|
+
constructor() {
|
|
415
|
+
this._notifications = new MinHeap((notification1, notification2) => notification1.rank - notification2.rank);
|
|
416
|
+
this._notificationsByKey = /* @__PURE__ */ new Map();
|
|
417
|
+
}
|
|
418
|
+
scheduleNotification(notification) {
|
|
419
|
+
const existingNotification = this._notificationsByKey.get(notification.key);
|
|
420
|
+
if (existingNotification) {
|
|
421
|
+
existingNotification.value = notification.value;
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
this._notificationsByKey.set(notification.key, notification);
|
|
425
|
+
this._notifications.push(notification);
|
|
426
|
+
}
|
|
427
|
+
deliverNotifications() {
|
|
428
|
+
while (this._notifications.size > 0) {
|
|
429
|
+
const notification = this._notifications.pop();
|
|
430
|
+
if (this._notificationsByKey.get(notification.key) !== notification) continue;
|
|
431
|
+
this._notificationsByKey.delete(notification.key);
|
|
432
|
+
notification.notify(notification.value, notification.previousValue);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
let activeScheduler;
|
|
437
|
+
/**
|
|
438
|
+
* Top-level state updates own the scheduler and synchronously drain it. Updates
|
|
439
|
+
* made by subscribers reuse the active scheduler, so they cannot deliver a
|
|
440
|
+
* nested notification batch ahead of notifications already waiting to run.
|
|
441
|
+
*/
|
|
442
|
+
function runWithStateScheduler(runUpdate) {
|
|
443
|
+
if (activeScheduler) {
|
|
444
|
+
runUpdate(activeScheduler);
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
const scheduler = new StateScheduler();
|
|
448
|
+
activeScheduler = scheduler;
|
|
449
|
+
try {
|
|
450
|
+
runUpdate(scheduler);
|
|
451
|
+
scheduler.deliverNotifications();
|
|
452
|
+
} finally {
|
|
453
|
+
activeScheduler = void 0;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
//#endregion
|
|
373
457
|
//#region src/create-state/state-core.ts
|
|
374
458
|
const emptyValue = Symbol("veles-state-core-empty");
|
|
375
459
|
const defaultEquality = (value1, value2) => value1 === value2;
|
|
@@ -380,8 +464,10 @@ var StateCore = class StateCore {
|
|
|
380
464
|
this._dirty = false;
|
|
381
465
|
this._children = /* @__PURE__ */ new Set();
|
|
382
466
|
this._value = initialValue;
|
|
383
|
-
|
|
467
|
+
const parents = options.parents || [];
|
|
468
|
+
this._parents = new Set(parents);
|
|
384
469
|
this._compute = options.compute;
|
|
470
|
+
this._rank = parents.reduce((rank, parent) => Math.max(rank, parent._rank + 1), 0);
|
|
385
471
|
this._dirty = Boolean(options.dirty);
|
|
386
472
|
this._equality = options.equality || defaultEquality;
|
|
387
473
|
}
|
|
@@ -400,14 +486,16 @@ var StateCore = class StateCore {
|
|
|
400
486
|
}
|
|
401
487
|
set(newValue) {
|
|
402
488
|
if (this._equality(this._value, newValue)) return;
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
child
|
|
489
|
+
runWithStateScheduler((scheduler) => {
|
|
490
|
+
const prevValue = this._value;
|
|
491
|
+
this._prevValue = prevValue;
|
|
492
|
+
this._value = newValue;
|
|
493
|
+
this.scheduleNotification(scheduler, newValue, prevValue);
|
|
494
|
+
this._children.forEach((child) => {
|
|
495
|
+
child._dirty = true;
|
|
496
|
+
});
|
|
497
|
+
this.flush(scheduler);
|
|
409
498
|
});
|
|
410
|
-
this.flush();
|
|
411
499
|
}
|
|
412
500
|
update(fn) {
|
|
413
501
|
const newValue = fn(this._value);
|
|
@@ -494,37 +582,62 @@ var StateCore = class StateCore {
|
|
|
494
582
|
this._dirty = false;
|
|
495
583
|
return { changed };
|
|
496
584
|
}
|
|
497
|
-
flush() {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
585
|
+
flush(scheduler) {
|
|
586
|
+
/**
|
|
587
|
+
* We utilize a min-heap to ensure that we don't trigger notifications
|
|
588
|
+
* before all the previous necessary work is done. Otherwise it can
|
|
589
|
+
* happen too early, and we'd need to recursively check that every parent
|
|
590
|
+
* is not dirty and schedule it again.
|
|
591
|
+
*
|
|
592
|
+
* Here we achieve this by assinging a rank to each core state, which is
|
|
593
|
+
* determined by the highest rank of any of the parent + 1.
|
|
594
|
+
*
|
|
595
|
+
* After that, we process them at the same rank, ensuring that "short" branches
|
|
596
|
+
* are not executed before all their parents are done with their recomputation.
|
|
597
|
+
*/
|
|
598
|
+
const queue = new MinHeap((node1, node2) => node1._rank - node2._rank);
|
|
599
|
+
const queued = /* @__PURE__ */ new Set();
|
|
600
|
+
const enqueue = (node) => {
|
|
601
|
+
if (queued.has(node)) return;
|
|
602
|
+
queue.push(node);
|
|
603
|
+
queued.add(node);
|
|
604
|
+
};
|
|
605
|
+
this._children.forEach(enqueue);
|
|
606
|
+
while (queue.size > 0) {
|
|
607
|
+
const child = queue.pop();
|
|
502
608
|
queued.delete(child);
|
|
503
609
|
if (!child._dirty) continue;
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
610
|
+
let shouldRescheduleChild = false;
|
|
611
|
+
child._parents.forEach((parentNode) => {
|
|
612
|
+
if (parentNode._dirty) {
|
|
613
|
+
enqueue(parentNode);
|
|
614
|
+
shouldRescheduleChild = true;
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
if (shouldRescheduleChild) {
|
|
618
|
+
enqueue(child);
|
|
507
619
|
continue;
|
|
508
620
|
}
|
|
509
621
|
const { changed } = child.recompute();
|
|
510
622
|
const value = child._value;
|
|
511
623
|
if (!changed) continue;
|
|
512
|
-
child.
|
|
624
|
+
child.scheduleNotification(scheduler, value, child._prevValue);
|
|
513
625
|
child._children.forEach((grandchild) => {
|
|
514
626
|
grandchild._dirty = true;
|
|
515
|
-
|
|
516
|
-
queue.push(grandchild);
|
|
517
|
-
queued.add(grandchild);
|
|
518
|
-
}
|
|
627
|
+
enqueue(grandchild);
|
|
519
628
|
});
|
|
520
629
|
}
|
|
521
630
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
631
|
+
scheduleNotification(scheduler, value, previousValue) {
|
|
632
|
+
scheduler.scheduleNotification({
|
|
633
|
+
key: this,
|
|
634
|
+
rank: this._rank,
|
|
635
|
+
value,
|
|
636
|
+
previousValue,
|
|
637
|
+
notify: (notificationValue, notificationPreviousValue) => {
|
|
638
|
+
this.notifySubscribers(notificationValue, notificationPreviousValue);
|
|
639
|
+
}
|
|
526
640
|
});
|
|
527
|
-
return hasDirtyParent;
|
|
528
641
|
}
|
|
529
642
|
notifySubscribers(value, prevValue) {
|
|
530
643
|
if (value === emptyValue) return;
|
|
@@ -645,7 +758,10 @@ function createStateFromCore(core, subscribeCallback) {
|
|
|
645
758
|
trackingParams.savedContext = currentContext;
|
|
646
759
|
const wrapperComponent = require__utils.createElement((_props, componentAPI) => {
|
|
647
760
|
const children = [];
|
|
648
|
-
const
|
|
761
|
+
const anchor = require__utils.createTextElement("");
|
|
762
|
+
anchor.needExecutedVersion = true;
|
|
763
|
+
trackingParams.anchor = anchor;
|
|
764
|
+
const elementsByKey = /* @__PURE__ */ new Map();
|
|
649
765
|
const stateValue = core.get();
|
|
650
766
|
const elements = options.selector ? options.selector(stateValue) : stateValue;
|
|
651
767
|
if (!Array.isArray(elements)) {
|
|
@@ -653,7 +769,7 @@ function createStateFromCore(core, subscribeCallback) {
|
|
|
653
769
|
return null;
|
|
654
770
|
}
|
|
655
771
|
elements.forEach((element, index) => {
|
|
656
|
-
let calculatedKey =
|
|
772
|
+
let calculatedKey = null;
|
|
657
773
|
if (typeof options.key === "string" && typeof element === "object" && element !== null && options.key in element) calculatedKey = element[options.key];
|
|
658
774
|
else if (typeof options.key === "function") calculatedKey = options.key({
|
|
659
775
|
element,
|
|
@@ -661,18 +777,18 @@ function createStateFromCore(core, subscribeCallback) {
|
|
|
661
777
|
});
|
|
662
778
|
const elementState = createState(element);
|
|
663
779
|
const indexState = createState(index);
|
|
664
|
-
if (
|
|
780
|
+
if (calculatedKey == null) return;
|
|
665
781
|
let node = cb({
|
|
666
782
|
elementState,
|
|
667
783
|
indexState
|
|
668
784
|
});
|
|
669
785
|
node.needExecutedVersion = true;
|
|
670
|
-
elementsByKey
|
|
786
|
+
elementsByKey.set(calculatedKey, {
|
|
671
787
|
node,
|
|
672
788
|
indexState,
|
|
673
789
|
indexValue: index,
|
|
674
790
|
elementState
|
|
675
|
-
};
|
|
791
|
+
});
|
|
676
792
|
children.push([
|
|
677
793
|
node,
|
|
678
794
|
calculatedKey,
|
|
@@ -689,7 +805,7 @@ function createStateFromCore(core, subscribeCallback) {
|
|
|
689
805
|
});
|
|
690
806
|
return require__utils.createElement("div", {
|
|
691
807
|
phantom: true,
|
|
692
|
-
children: children.map((child) => child[0])
|
|
808
|
+
children: [...children.map((child) => child[0]), anchor]
|
|
693
809
|
});
|
|
694
810
|
});
|
|
695
811
|
wrapperComponent.needExecutedVersion = true;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as VelesComponentObject, i as VelesChildren, n as createElement, o as VelesElement, r as AttributeHelper, s as VelesStringElement, t as Fragment } from "./fragment-
|
|
1
|
+
import { a as VelesComponentObject, i as VelesChildren, n as createElement, o as VelesElement, r as AttributeHelper, s as VelesStringElement, t as Fragment } from "./fragment-COsp_SDE.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/attach-component.d.ts
|
|
4
4
|
/**
|
|
@@ -24,6 +24,7 @@ declare function onUnmount(cb: Function): void;
|
|
|
24
24
|
type StateEquality<ValueType> = (value1: ValueType, value2: ValueType) => boolean;
|
|
25
25
|
type StateLike<ValueType> = State<ValueType>;
|
|
26
26
|
type ArrayElement<T> = T extends ReadonlyArray<infer Element> ? Element : never;
|
|
27
|
+
type IteratorKey = string | number;
|
|
27
28
|
type State<ValueType> = {
|
|
28
29
|
track(cb: (value: ValueType) => void | Function, options?: {
|
|
29
30
|
callOnMount?: boolean;
|
|
@@ -45,7 +46,7 @@ type State<ValueType> = {
|
|
|
45
46
|
key: string | ((options: {
|
|
46
47
|
element: Element;
|
|
47
48
|
index: number;
|
|
48
|
-
}) =>
|
|
49
|
+
}) => IteratorKey);
|
|
49
50
|
selector?: undefined;
|
|
50
51
|
} : never, cb: (props: {
|
|
51
52
|
elementState: State<Element>;
|
|
@@ -55,7 +56,7 @@ type State<ValueType> = {
|
|
|
55
56
|
key: string | ((options: {
|
|
56
57
|
element: Element;
|
|
57
58
|
index: number;
|
|
58
|
-
}) =>
|
|
59
|
+
}) => IteratorKey);
|
|
59
60
|
selector: (value: ValueType) => SelectorValueType;
|
|
60
61
|
}, cb: (props: {
|
|
61
62
|
elementState: State<Element>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as VelesComponentObject, i as VelesChildren, n as createElement, o as VelesElement, r as AttributeHelper, s as VelesStringElement, t as Fragment } from "./fragment-
|
|
1
|
+
import { a as VelesComponentObject, i as VelesChildren, n as createElement, o as VelesElement, r as AttributeHelper, s as VelesStringElement, t as Fragment } from "./fragment-CPcYB5D5.js";
|
|
2
2
|
|
|
3
3
|
//#region src/attach-component.d.ts
|
|
4
4
|
/**
|
|
@@ -24,6 +24,7 @@ declare function onUnmount(cb: Function): void;
|
|
|
24
24
|
type StateEquality<ValueType> = (value1: ValueType, value2: ValueType) => boolean;
|
|
25
25
|
type StateLike<ValueType> = State<ValueType>;
|
|
26
26
|
type ArrayElement<T> = T extends ReadonlyArray<infer Element> ? Element : never;
|
|
27
|
+
type IteratorKey = string | number;
|
|
27
28
|
type State<ValueType> = {
|
|
28
29
|
track(cb: (value: ValueType) => void | Function, options?: {
|
|
29
30
|
callOnMount?: boolean;
|
|
@@ -45,7 +46,7 @@ type State<ValueType> = {
|
|
|
45
46
|
key: string | ((options: {
|
|
46
47
|
element: Element;
|
|
47
48
|
index: number;
|
|
48
|
-
}) =>
|
|
49
|
+
}) => IteratorKey);
|
|
49
50
|
selector?: undefined;
|
|
50
51
|
} : never, cb: (props: {
|
|
51
52
|
elementState: State<Element>;
|
|
@@ -55,7 +56,7 @@ type State<ValueType> = {
|
|
|
55
56
|
key: string | ((options: {
|
|
56
57
|
element: Element;
|
|
57
58
|
index: number;
|
|
58
|
-
}) =>
|
|
59
|
+
}) => IteratorKey);
|
|
59
60
|
selector: (value: ValueType) => SelectorValueType;
|
|
60
61
|
}, cb: (props: {
|
|
61
62
|
elementState: State<Element>;
|