@wcstack/state 1.19.0 → 1.19.1
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/index.esm.js +69 -27
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
let _inSsrCache = null;
|
|
2
1
|
function inSsr() {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
// キャッシュしない: SSR モードはプロセスの属性ではなく「現在の document」の
|
|
3
|
+
// 属性。@wcstack/server はグローバル document を差し替えてサーバーレンダリング
|
|
4
|
+
// した後、同一プロセスでクライアント側ハイドレーションが走る(SSR→hydrate の
|
|
5
|
+
// e2e が該当)。サーバーフェーズの判定をキャッシュするとクライアントフェーズが
|
|
6
|
+
// SSR モード扱いになり、hydrateBindings の代わりに buildBindings が選ばれて
|
|
7
|
+
// connectedCallbackPromise が永久に未解決になる。
|
|
8
|
+
const html = document.documentElement;
|
|
9
|
+
return html ? html.hasAttribute('data-wcs-server') : false;
|
|
8
10
|
}
|
|
9
11
|
const _config = {
|
|
10
12
|
bindAttributeName: 'data-wcs',
|
|
@@ -63,7 +65,7 @@ function setConfig(partialConfig) {
|
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
67
|
|
|
66
|
-
var version$1 = "1.19.
|
|
68
|
+
var version$1 = "1.19.1";
|
|
67
69
|
var pkg = {
|
|
68
70
|
version: version$1};
|
|
69
71
|
|
|
@@ -2788,6 +2790,20 @@ function isSameList(oldList, newList) {
|
|
|
2788
2790
|
}
|
|
2789
2791
|
return true;
|
|
2790
2792
|
}
|
|
2793
|
+
/**
|
|
2794
|
+
* Aligns each list index's .index with its position in the new list.
|
|
2795
|
+
* A diff only becomes the rendered state once the updater applies it: an
|
|
2796
|
+
* earlier diff in the same batch (two replacements in one microtask) may have
|
|
2797
|
+
* moved shared indexes toward a list that never got applied, and a cache hit
|
|
2798
|
+
* skips recomputation entirely — so every createListDiff return re-aligns.
|
|
2799
|
+
*/
|
|
2800
|
+
function syncListIndexes(newIndexes) {
|
|
2801
|
+
for (let i = 0; i < newIndexes.length; i++) {
|
|
2802
|
+
if (newIndexes[i].index !== i) {
|
|
2803
|
+
newIndexes[i].index = i;
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2791
2807
|
/**
|
|
2792
2808
|
* Creates or updates list indexes by comparing old and new lists.
|
|
2793
2809
|
* Optimizes by reusing existing list indexes when values match.
|
|
@@ -2798,6 +2814,11 @@ function isSameList(oldList, newList) {
|
|
|
2798
2814
|
* @returns Array of list indexes for the new list
|
|
2799
2815
|
*/
|
|
2800
2816
|
function createListDiff(parentListIndex, rawOldList, rawNewList) {
|
|
2817
|
+
const diff = computeListDiff(parentListIndex, rawOldList, rawNewList);
|
|
2818
|
+
syncListIndexes(diff.newIndexes);
|
|
2819
|
+
return diff;
|
|
2820
|
+
}
|
|
2821
|
+
function computeListDiff(parentListIndex, rawOldList, rawNewList) {
|
|
2801
2822
|
// Normalize inputs to arrays (handles null/undefined)
|
|
2802
2823
|
const oldList = (Array.isArray(rawOldList) && rawOldList.length > 0) ? rawOldList : EMPTY_LIST;
|
|
2803
2824
|
const newList = (Array.isArray(rawNewList) && rawNewList.length > 0) ? rawNewList : EMPTY_LIST;
|
|
@@ -2846,6 +2867,10 @@ function createListDiff(parentListIndex, rawOldList, rawNewList) {
|
|
|
2846
2867
|
addIndexSet: EMPTY_SET$1,
|
|
2847
2868
|
};
|
|
2848
2869
|
}
|
|
2870
|
+
if (newIndexes !== null) {
|
|
2871
|
+
return calcDiffIndexes(oldIndexes, newIndexes);
|
|
2872
|
+
}
|
|
2873
|
+
newIndexes = [];
|
|
2849
2874
|
// Use index-based map for efficiency
|
|
2850
2875
|
// Supports duplicate values by storing array of indexes
|
|
2851
2876
|
const indexByValue = new Map();
|
|
@@ -2858,10 +2883,6 @@ function createListDiff(parentListIndex, rawOldList, rawNewList) {
|
|
|
2858
2883
|
}
|
|
2859
2884
|
indexes.push(i);
|
|
2860
2885
|
}
|
|
2861
|
-
if (newIndexes !== null) {
|
|
2862
|
-
return calcDiffIndexes(oldList, newList, oldIndexes, newIndexes, indexByValue);
|
|
2863
|
-
}
|
|
2864
|
-
newIndexes = [];
|
|
2865
2886
|
// Build new indexes array by matching values with old list
|
|
2866
2887
|
const changeIndexSet = new Set();
|
|
2867
2888
|
const addIndexSet = new Set();
|
|
@@ -2878,9 +2899,11 @@ function createListDiff(parentListIndex, rawOldList, rawNewList) {
|
|
|
2878
2899
|
else {
|
|
2879
2900
|
// Reuse existing element
|
|
2880
2901
|
const existingListIndex = oldIndexes[oldIndex];
|
|
2881
|
-
//
|
|
2882
|
-
|
|
2883
|
-
|
|
2902
|
+
// Judge position change against the old list's order (oldIndexes array
|
|
2903
|
+
// order), not the mutable .index — an earlier diff in the same batch
|
|
2904
|
+
// may have already moved .index toward a list that was never applied.
|
|
2905
|
+
// The .index itself is re-aligned by syncListIndexes on return.
|
|
2906
|
+
if (oldIndex !== i) {
|
|
2884
2907
|
changeIndexSet.add(existingListIndex);
|
|
2885
2908
|
}
|
|
2886
2909
|
newIndexes.push(existingListIndex);
|
|
@@ -2902,22 +2925,35 @@ function createListDiff(parentListIndex, rawOldList, rawNewList) {
|
|
|
2902
2925
|
}
|
|
2903
2926
|
}
|
|
2904
2927
|
}
|
|
2905
|
-
|
|
2928
|
+
/**
|
|
2929
|
+
* Diff between two lists whose listIndex ledgers both already exist.
|
|
2930
|
+
* Rows are joined by listIndex identity — the same key applyChangeToFor and
|
|
2931
|
+
* walkDependency consume the result sets with. A value-based join could mark
|
|
2932
|
+
* oldIndexes-side objects that are absent from newIndexes (ledgers built along
|
|
2933
|
+
* unconnected diff chains hold different objects for the same value); such
|
|
2934
|
+
* orphan markers never match the consumers' has() lookups and only pollute
|
|
2935
|
+
* the dirty set. Rows without shared identity are represented as add+delete.
|
|
2936
|
+
*/
|
|
2937
|
+
function calcDiffIndexes(oldIndexes, newIndexes) {
|
|
2906
2938
|
const newIndexSet = new Set(newIndexes);
|
|
2907
2939
|
const oldIndexSet = new Set(oldIndexes);
|
|
2908
2940
|
const changeIndexSet = new Set();
|
|
2909
2941
|
const addIndexSet = newIndexSet.difference(oldIndexSet);
|
|
2910
2942
|
const deleteIndexSet = oldIndexSet.difference(newIndexSet);
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2943
|
+
// Old positions come from the oldIndexes array order (.index may have been
|
|
2944
|
+
// mutated by an unapplied diff in the same batch).
|
|
2945
|
+
const oldPosByIndex = new Map();
|
|
2946
|
+
for (let i = 0; i < oldIndexes.length; i++) {
|
|
2947
|
+
oldPosByIndex.set(oldIndexes[i], i);
|
|
2948
|
+
}
|
|
2949
|
+
for (let i = 0; i < newIndexes.length; i++) {
|
|
2950
|
+
const index = newIndexes[i];
|
|
2951
|
+
if (addIndexSet.has(index)) {
|
|
2952
|
+
continue;
|
|
2953
|
+
}
|
|
2954
|
+
if (oldPosByIndex.get(index) !== i) {
|
|
2955
|
+
// 位置が違うことだけを記録
|
|
2956
|
+
changeIndexSet.add(index);
|
|
2921
2957
|
}
|
|
2922
2958
|
}
|
|
2923
2959
|
return {
|
|
@@ -5666,8 +5702,14 @@ class LoopContextStack {
|
|
|
5666
5702
|
}
|
|
5667
5703
|
}
|
|
5668
5704
|
else {
|
|
5669
|
-
|
|
5670
|
-
|
|
5705
|
+
// With no active loop context the address must be self-contained: the
|
|
5706
|
+
// listIndex chain supplies one index per wildcard. Top-level lists
|
|
5707
|
+
// (wildcardCount 1) always satisfy this. A nested list re-rendered
|
|
5708
|
+
// directly (e.g. replaced via $resolve from outside the loop) also
|
|
5709
|
+
// satisfies it — the for binding's listIndex carries the full ancestor
|
|
5710
|
+
// chain.
|
|
5711
|
+
if (loopContext.listIndex.length !== loopContext.pathInfo.wildcardCount) {
|
|
5712
|
+
raiseError(`Cannot push loop context when there is no active loop context: the list index chain (length ${loopContext.listIndex.length}) does not cover the wildcard path (wildcard count ${loopContext.pathInfo.wildcardCount}).`);
|
|
5671
5713
|
}
|
|
5672
5714
|
}
|
|
5673
5715
|
this._loopContextStack[this._length] = loopContext;
|