@mintjamsinc/ichigojs 0.1.82 → 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 +133 -10
- package/dist/ichigo.cjs.map +1 -1
- package/dist/ichigo.esm.js +133 -10
- package/dist/ichigo.esm.js.map +1 -1
- package/dist/ichigo.esm.min.js +1 -1
- package/dist/ichigo.esm.min.js.map +1 -0
- package/dist/ichigo.min.cjs +1 -1
- package/dist/ichigo.umd.js +133 -10
- package/dist/ichigo.umd.js.map +1 -1
- package/dist/ichigo.umd.min.js +1 -1
- package/dist/ichigo.umd.min.js.map +1 -0
- package/dist/types/ichigo/ExpressionEvaluator.d.ts +118 -0
- package/dist/types/ichigo/VComponent.d.ts +2 -0
- package/dist/types/ichigo/VComponentRegistry.d.ts +2 -0
- package/dist/types/ichigo/VNode.d.ts +1 -0
- package/dist/types/ichigo/VUpdateContext.d.ts +21 -0
- package/dist/types/ichigo/directives/VBindingsPreparer.d.ts +24 -0
- package/dist/types/ichigo/directives/VDOMUpdater.d.ts +17 -0
- package/dist/types/ichigo/util/BindingsUtils.d.ts +10 -0
- package/dist/types/ichigo/util/VLogLevel.d.ts +9 -0
- package/package.json +1 -1
package/dist/ichigo.cjs
CHANGED
|
@@ -10136,9 +10136,9 @@
|
|
|
10136
10136
|
*/
|
|
10137
10137
|
#fragmentRange;
|
|
10138
10138
|
/**
|
|
10139
|
-
* Set by {@link destroy}. A destroyed
|
|
10140
|
-
* list
|
|
10141
|
-
*
|
|
10139
|
+
* Set by {@link destroy}. A destroyed node also leaves its parent's child
|
|
10140
|
+
* list, but a walk that took its copy of the list before the node was
|
|
10141
|
+
* destroyed may still reach it, and must skip it.
|
|
10142
10142
|
*/
|
|
10143
10143
|
#destroyed = false;
|
|
10144
10144
|
/**
|
|
@@ -10308,7 +10308,8 @@
|
|
|
10308
10308
|
// walk runs once the subtree is in the document, which the outlet
|
|
10309
10309
|
// cannot know when it renders inside a detached v-if / v-for clone.
|
|
10310
10310
|
this.#directiveManager?.directives?.forEach(d => d.expandComponents?.());
|
|
10311
|
-
this
|
|
10311
|
+
// A copy: expanding can render and destroy clones under this node.
|
|
10312
|
+
this.#childVNodes?.slice().forEach(child => child.expandComponents());
|
|
10312
10313
|
}
|
|
10313
10314
|
/**
|
|
10314
10315
|
* The application instance associated with this virtual node.
|
|
@@ -10620,8 +10621,9 @@
|
|
|
10620
10621
|
updater.applyToDOM();
|
|
10621
10622
|
}
|
|
10622
10623
|
}
|
|
10623
|
-
// Recursively update child virtual nodes
|
|
10624
|
-
this
|
|
10624
|
+
// Recursively update child virtual nodes. A copy: an update can
|
|
10625
|
+
// destroy a v-if / v-for clone, which removes it from this list.
|
|
10626
|
+
this.#childVNodes?.slice().forEach(childVNode => {
|
|
10625
10627
|
childVNode.forceUpdate();
|
|
10626
10628
|
});
|
|
10627
10629
|
// If no directive requires template preservation, call onUpdated for directives that do not templatize
|
|
@@ -10633,7 +10635,7 @@
|
|
|
10633
10635
|
}
|
|
10634
10636
|
else if (this.#nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
|
|
10635
10637
|
// For document fragments, recursively force update child VNodes
|
|
10636
|
-
this.#childVNodes?.forEach(childVNode => {
|
|
10638
|
+
this.#childVNodes?.slice().forEach(childVNode => {
|
|
10637
10639
|
childVNode.forceUpdate();
|
|
10638
10640
|
});
|
|
10639
10641
|
}
|
|
@@ -10715,6 +10717,7 @@
|
|
|
10715
10717
|
* 4. Unregister dependencies
|
|
10716
10718
|
* 5. Clean up directive manager
|
|
10717
10719
|
* 6. Call onUnmounted lifecycle hooks
|
|
10720
|
+
* 7. Leave the parent's child list
|
|
10718
10721
|
*/
|
|
10719
10722
|
destroy() {
|
|
10720
10723
|
this.#destroyed = true;
|
|
@@ -10741,9 +10744,9 @@
|
|
|
10741
10744
|
}
|
|
10742
10745
|
this.#userData.clear();
|
|
10743
10746
|
}
|
|
10744
|
-
// Recursively destroy child nodes
|
|
10747
|
+
// Recursively destroy child nodes (a copy: each one leaves this list)
|
|
10745
10748
|
if (this.#childVNodes) {
|
|
10746
|
-
for (const childVNode of this.#childVNodes) {
|
|
10749
|
+
for (const childVNode of this.#childVNodes.slice()) {
|
|
10747
10750
|
try {
|
|
10748
10751
|
childVNode.destroy();
|
|
10749
10752
|
}
|
|
@@ -10771,6 +10774,15 @@
|
|
|
10771
10774
|
d.onUnmounted?.();
|
|
10772
10775
|
});
|
|
10773
10776
|
}
|
|
10777
|
+
// Leave the parent's child list. v-if and v-for render every new clone
|
|
10778
|
+
// under the same parent VNode, so a destroyed clone left in the list
|
|
10779
|
+
// would keep its whole subtree — VNodes, DOM nodes, bindings — alive
|
|
10780
|
+
// for as long as the parent, growing with each toggle or row change.
|
|
10781
|
+
const siblings = this.#parentVNode ? this.#parentVNode.#childVNodes : undefined;
|
|
10782
|
+
const index = siblings ? siblings.indexOf(this) : -1;
|
|
10783
|
+
if (index !== -1) {
|
|
10784
|
+
siblings.splice(index, 1);
|
|
10785
|
+
}
|
|
10774
10786
|
}
|
|
10775
10787
|
}
|
|
10776
10788
|
|
|
@@ -11307,6 +11319,25 @@
|
|
|
11307
11319
|
* Previous iterations to detect changes
|
|
11308
11320
|
*/
|
|
11309
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;
|
|
11310
11341
|
/**
|
|
11311
11342
|
* @param context The context for parsing the directive.
|
|
11312
11343
|
*/
|
|
@@ -11423,6 +11454,10 @@
|
|
|
11423
11454
|
* @inheritdoc
|
|
11424
11455
|
*/
|
|
11425
11456
|
destroy() {
|
|
11457
|
+
this.#destroyed = true;
|
|
11458
|
+
this.#unwatchSource?.();
|
|
11459
|
+
this.#unwatchSource = undefined;
|
|
11460
|
+
this.#watchedSource = undefined;
|
|
11426
11461
|
// Clean up all rendered items
|
|
11427
11462
|
// First destroy all VNodes (calls @unmount hooks), then remove from DOM
|
|
11428
11463
|
for (const { vNode } of this.#renderedItems) {
|
|
@@ -11454,6 +11489,10 @@
|
|
|
11454
11489
|
}
|
|
11455
11490
|
// Evaluate the source expression to get the data
|
|
11456
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;
|
|
11457
11496
|
// Get iterations from the source data
|
|
11458
11497
|
let iterations = this.#getIterations(sourceData);
|
|
11459
11498
|
// If we don't have a key evaluator yet, try to create it
|
|
@@ -11847,6 +11886,89 @@
|
|
|
11847
11886
|
}
|
|
11848
11887
|
vNode.update();
|
|
11849
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
|
+
}
|
|
11850
11972
|
/**
|
|
11851
11973
|
* Get iterations from various data types
|
|
11852
11974
|
* Supports: Arrays, Objects, Sets, Maps, Iterables, Numbers, Strings
|
|
@@ -11856,7 +11978,8 @@
|
|
|
11856
11978
|
return [];
|
|
11857
11979
|
// Array
|
|
11858
11980
|
if (Array.isArray(data)) {
|
|
11859
|
-
|
|
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) => ({
|
|
11860
11983
|
item,
|
|
11861
11984
|
index,
|
|
11862
11985
|
key: index
|