@mintjamsinc/ichigojs 0.1.83 → 0.1.84
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/ichigo.cjs +112 -1
- package/dist/ichigo.cjs.map +1 -1
- package/dist/ichigo.esm.js +112 -1
- package/dist/ichigo.esm.js.map +1 -1
- package/dist/ichigo.esm.min.js +1 -1
- package/dist/ichigo.min.cjs +1 -1
- package/dist/ichigo.umd.js +112 -1
- package/dist/ichigo.umd.js.map +1 -1
- package/dist/ichigo.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/ichigo.umd.js
CHANGED
|
@@ -11319,6 +11319,25 @@
|
|
|
11319
11319
|
* Previous iterations to detect changes
|
|
11320
11320
|
*/
|
|
11321
11321
|
#previousIterations = [];
|
|
11322
|
+
/**
|
|
11323
|
+
* The source array watched for writes made directly to it, and the function
|
|
11324
|
+
* that stops watching it.
|
|
11325
|
+
*
|
|
11326
|
+
* A write such as `items[1] = x` is reported as a change of "items[1]", which
|
|
11327
|
+
* does not match this directive's dependency on "items", and the row's loop
|
|
11328
|
+
* variable holds the value it was rendered with. The directive therefore
|
|
11329
|
+
* watches the array itself and refreshes the rows that were written.
|
|
11330
|
+
*/
|
|
11331
|
+
#watchedSource;
|
|
11332
|
+
#unwatchSource;
|
|
11333
|
+
/**
|
|
11334
|
+
* Positions written since the last refresh, and whether a write (such as one
|
|
11335
|
+
* to `length`) needs the whole list rendered again.
|
|
11336
|
+
*/
|
|
11337
|
+
#writtenIndexes = new Set();
|
|
11338
|
+
#writtenWhole = false;
|
|
11339
|
+
#refreshScheduled = false;
|
|
11340
|
+
#destroyed = false;
|
|
11322
11341
|
/**
|
|
11323
11342
|
* @param context The context for parsing the directive.
|
|
11324
11343
|
*/
|
|
@@ -11435,6 +11454,10 @@
|
|
|
11435
11454
|
* @inheritdoc
|
|
11436
11455
|
*/
|
|
11437
11456
|
destroy() {
|
|
11457
|
+
this.#destroyed = true;
|
|
11458
|
+
this.#unwatchSource?.();
|
|
11459
|
+
this.#unwatchSource = undefined;
|
|
11460
|
+
this.#watchedSource = undefined;
|
|
11438
11461
|
// Clean up all rendered items
|
|
11439
11462
|
// First destroy all VNodes (calls @unmount hooks), then remove from DOM
|
|
11440
11463
|
for (const { vNode } of this.#renderedItems) {
|
|
@@ -11466,6 +11489,10 @@
|
|
|
11466
11489
|
}
|
|
11467
11490
|
// Evaluate the source expression to get the data
|
|
11468
11491
|
const sourceData = this.#sourceEvaluator.evaluate();
|
|
11492
|
+
// Every row is rendered from the source below, including those written in place
|
|
11493
|
+
this.#watchSource(sourceData);
|
|
11494
|
+
this.#writtenIndexes.clear();
|
|
11495
|
+
this.#writtenWhole = false;
|
|
11469
11496
|
// Get iterations from the source data
|
|
11470
11497
|
let iterations = this.#getIterations(sourceData);
|
|
11471
11498
|
// If we don't have a key evaluator yet, try to create it
|
|
@@ -11859,6 +11886,89 @@
|
|
|
11859
11886
|
}
|
|
11860
11887
|
vNode.update();
|
|
11861
11888
|
}
|
|
11889
|
+
/**
|
|
11890
|
+
* Watches the source for writes made directly to its elements. Only a
|
|
11891
|
+
* reactive array can be written that way; anything else is not watched.
|
|
11892
|
+
*/
|
|
11893
|
+
#watchSource(source) {
|
|
11894
|
+
if (source === this.#watchedSource) {
|
|
11895
|
+
return;
|
|
11896
|
+
}
|
|
11897
|
+
this.#unwatchSource?.();
|
|
11898
|
+
this.#unwatchSource = undefined;
|
|
11899
|
+
this.#watchedSource = source;
|
|
11900
|
+
const path = Array.isArray(source) ? ReactiveProxy.getPath(source) : undefined;
|
|
11901
|
+
if (!path) {
|
|
11902
|
+
return;
|
|
11903
|
+
}
|
|
11904
|
+
this.#unwatchSource = ReactiveProxy.subscribe(source, (changedPath) => {
|
|
11905
|
+
this.#onSourceWritten(path, changedPath);
|
|
11906
|
+
});
|
|
11907
|
+
}
|
|
11908
|
+
/**
|
|
11909
|
+
* Notes a write made directly to the source array. A change below an
|
|
11910
|
+
* element (e.g. "items[1].name") is followed by the row's own bindings, and
|
|
11911
|
+
* a change of the whole array (e.g. by splice) by the usual dependency on it.
|
|
11912
|
+
*/
|
|
11913
|
+
#onSourceWritten(path, changedPath) {
|
|
11914
|
+
if (!changedPath || !changedPath.startsWith(path + '[') || !changedPath.endsWith(']')) {
|
|
11915
|
+
return;
|
|
11916
|
+
}
|
|
11917
|
+
const property = changedPath.substring(path.length + 1, changedPath.length - 1);
|
|
11918
|
+
if (property.includes(']')) {
|
|
11919
|
+
return;
|
|
11920
|
+
}
|
|
11921
|
+
if (/^\d+$/.test(property)) {
|
|
11922
|
+
this.#writtenIndexes.add(Number(property));
|
|
11923
|
+
}
|
|
11924
|
+
else {
|
|
11925
|
+
// e.g. `items.length = 0`
|
|
11926
|
+
this.#writtenWhole = true;
|
|
11927
|
+
}
|
|
11928
|
+
// Writes made together are refreshed together, after the application's update
|
|
11929
|
+
if (!this.#refreshScheduled) {
|
|
11930
|
+
this.#refreshScheduled = true;
|
|
11931
|
+
queueMicrotask(() => {
|
|
11932
|
+
this.#refreshScheduled = false;
|
|
11933
|
+
this.#refreshWritten();
|
|
11934
|
+
});
|
|
11935
|
+
}
|
|
11936
|
+
}
|
|
11937
|
+
/**
|
|
11938
|
+
* Shows the elements written since the last refresh. A row whose position or
|
|
11939
|
+
* key no longer holds is not patched; the whole list is rendered again.
|
|
11940
|
+
*/
|
|
11941
|
+
#refreshWritten() {
|
|
11942
|
+
if (this.#destroyed || (!this.#writtenWhole && this.#writtenIndexes.size === 0)) {
|
|
11943
|
+
return;
|
|
11944
|
+
}
|
|
11945
|
+
const indexes = [...this.#writtenIndexes];
|
|
11946
|
+
const whole = this.#writtenWhole;
|
|
11947
|
+
this.#writtenIndexes.clear();
|
|
11948
|
+
this.#writtenWhole = false;
|
|
11949
|
+
const source = this.#sourceEvaluator?.evaluate();
|
|
11950
|
+
if (whole || source !== this.#watchedSource || !Array.isArray(source) || source.length !== this.#renderedItems.length) {
|
|
11951
|
+
this.#render();
|
|
11952
|
+
return;
|
|
11953
|
+
}
|
|
11954
|
+
for (const index of indexes) {
|
|
11955
|
+
const rendered = this.#renderedItems[index];
|
|
11956
|
+
let context = { key: index, item: source[index], index };
|
|
11957
|
+
if (this.#evaluateKey && (this.#itemName || this.#itemDestructure)) {
|
|
11958
|
+
const itemBindings = new VBindings({
|
|
11959
|
+
parent: this.#vNode.bindings
|
|
11960
|
+
});
|
|
11961
|
+
this.#setItemBindings(itemBindings, context);
|
|
11962
|
+
context = { ...context, key: this.#evaluateKey(itemBindings) };
|
|
11963
|
+
}
|
|
11964
|
+
if (!rendered || context.key !== rendered.key) {
|
|
11965
|
+
this.#render();
|
|
11966
|
+
return;
|
|
11967
|
+
}
|
|
11968
|
+
this.#updateItemBindings(rendered.vNode, context);
|
|
11969
|
+
this.#previousIterations[index] = context;
|
|
11970
|
+
}
|
|
11971
|
+
}
|
|
11862
11972
|
/**
|
|
11863
11973
|
* Get iterations from various data types
|
|
11864
11974
|
* Supports: Arrays, Objects, Sets, Maps, Iterables, Numbers, Strings
|
|
@@ -11868,7 +11978,8 @@
|
|
|
11868
11978
|
return [];
|
|
11869
11979
|
// Array
|
|
11870
11980
|
if (Array.isArray(data)) {
|
|
11871
|
-
|
|
11981
|
+
// Array.from rather than map: a hole (e.g. after `items[5] = x` past the end) is a row of undefined
|
|
11982
|
+
return Array.from(data, (item, index) => ({
|
|
11872
11983
|
item,
|
|
11873
11984
|
index,
|
|
11874
11985
|
key: index
|