@fictjs/runtime 0.0.10 → 0.0.12
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.cjs +315 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.dev.js +330 -48
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +315 -50
- package/dist/index.js.map +1 -1
- package/dist/slim.cjs +293 -40
- package/dist/slim.cjs.map +1 -1
- package/dist/slim.js +293 -40
- package/dist/slim.js.map +1 -1
- package/package.json +1 -1
- package/src/binding.ts +3 -1
- package/src/dev.d.ts +5 -0
- package/src/dom.ts +20 -2
- package/src/effect.ts +16 -5
- package/src/error-boundary.ts +11 -2
- package/src/lifecycle.ts +4 -1
- package/src/list-helpers.ts +243 -22
- package/src/props.ts +2 -4
- package/src/reconcile.ts +4 -0
- package/src/signal.ts +154 -25
- package/src/suspense.ts +24 -7
- package/src/transition.ts +4 -1
package/dist/slim.cjs
CHANGED
|
@@ -262,7 +262,7 @@ function handleError(err, info, startRoot) {
|
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
|
-
|
|
265
|
+
return false;
|
|
266
266
|
}
|
|
267
267
|
function handleSuspend(token, startRoot) {
|
|
268
268
|
let root = startRoot ?? currentRoot;
|
|
@@ -307,6 +307,11 @@ var lowPriorityQueue = [];
|
|
|
307
307
|
var enqueueMicrotask = typeof queueMicrotask === "function" ? queueMicrotask : (fn) => {
|
|
308
308
|
Promise.resolve().then(fn);
|
|
309
309
|
};
|
|
310
|
+
var inCleanup = false;
|
|
311
|
+
var SIGNAL_MARKER = Symbol.for("fict:signal");
|
|
312
|
+
var COMPUTED_MARKER = Symbol.for("fict:computed");
|
|
313
|
+
var EFFECT_MARKER = Symbol.for("fict:effect");
|
|
314
|
+
var EFFECT_SCOPE_MARKER = Symbol.for("fict:effectScope");
|
|
310
315
|
function link(dep, sub, version) {
|
|
311
316
|
const prevDep = sub.depsTail;
|
|
312
317
|
if (prevDep !== void 0 && prevDep.dep === dep) return;
|
|
@@ -430,13 +435,21 @@ function checkDirty(firstLink, sub) {
|
|
|
430
435
|
dirty = true;
|
|
431
436
|
}
|
|
432
437
|
} else if ((depFlags & MutablePending) === MutablePending) {
|
|
433
|
-
if (
|
|
434
|
-
|
|
438
|
+
if (!dep.deps) {
|
|
439
|
+
const nextDep = link2.nextDep;
|
|
440
|
+
if (nextDep !== void 0) {
|
|
441
|
+
link2 = nextDep;
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
444
|
+
} else {
|
|
445
|
+
if (link2.nextSub !== void 0 || link2.prevSub !== void 0) {
|
|
446
|
+
stack = { value: link2, prev: stack };
|
|
447
|
+
}
|
|
448
|
+
link2 = dep.deps;
|
|
449
|
+
sub = dep;
|
|
450
|
+
++checkDepth;
|
|
451
|
+
continue;
|
|
435
452
|
}
|
|
436
|
-
link2 = dep.deps;
|
|
437
|
-
sub = dep;
|
|
438
|
-
++checkDepth;
|
|
439
|
-
continue;
|
|
440
453
|
}
|
|
441
454
|
if (!dirty) {
|
|
442
455
|
const nextDep = link2.nextDep;
|
|
@@ -514,8 +527,12 @@ function disposeNode(node) {
|
|
|
514
527
|
node.depsTail = void 0;
|
|
515
528
|
node.flags = 0;
|
|
516
529
|
purgeDeps(node);
|
|
517
|
-
|
|
518
|
-
|
|
530
|
+
let sub = node.subs;
|
|
531
|
+
while (sub !== void 0) {
|
|
532
|
+
const next = sub.nextSub;
|
|
533
|
+
unlink(sub);
|
|
534
|
+
sub = next;
|
|
535
|
+
}
|
|
519
536
|
}
|
|
520
537
|
function updateSignal(s) {
|
|
521
538
|
s.flags = Mutable;
|
|
@@ -552,7 +569,15 @@ function updateComputed(c) {
|
|
|
552
569
|
}
|
|
553
570
|
function runEffect(e) {
|
|
554
571
|
const flags = e.flags;
|
|
555
|
-
if (flags & Dirty
|
|
572
|
+
if (flags & Dirty) {
|
|
573
|
+
if (e.runCleanup) {
|
|
574
|
+
inCleanup = true;
|
|
575
|
+
try {
|
|
576
|
+
e.runCleanup();
|
|
577
|
+
} finally {
|
|
578
|
+
inCleanup = false;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
556
581
|
++cycle;
|
|
557
582
|
effectRunDevtools(e);
|
|
558
583
|
e.depsTail = void 0;
|
|
@@ -569,6 +594,35 @@ function runEffect(e) {
|
|
|
569
594
|
e.flags = Watching;
|
|
570
595
|
throw err;
|
|
571
596
|
}
|
|
597
|
+
} else if (flags & Pending && e.deps) {
|
|
598
|
+
if (e.runCleanup) {
|
|
599
|
+
inCleanup = true;
|
|
600
|
+
try {
|
|
601
|
+
e.runCleanup();
|
|
602
|
+
} finally {
|
|
603
|
+
inCleanup = false;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
if (checkDirty(e.deps, e)) {
|
|
607
|
+
++cycle;
|
|
608
|
+
effectRunDevtools(e);
|
|
609
|
+
e.depsTail = void 0;
|
|
610
|
+
e.flags = WatchingRunning;
|
|
611
|
+
const prevSub = activeSub;
|
|
612
|
+
activeSub = e;
|
|
613
|
+
try {
|
|
614
|
+
e.fn();
|
|
615
|
+
activeSub = prevSub;
|
|
616
|
+
e.flags = Watching;
|
|
617
|
+
purgeDeps(e);
|
|
618
|
+
} catch (err) {
|
|
619
|
+
activeSub = prevSub;
|
|
620
|
+
e.flags = Watching;
|
|
621
|
+
throw err;
|
|
622
|
+
}
|
|
623
|
+
} else {
|
|
624
|
+
e.flags = Watching;
|
|
625
|
+
}
|
|
572
626
|
} else {
|
|
573
627
|
e.flags = Watching;
|
|
574
628
|
}
|
|
@@ -647,7 +701,9 @@ function signal(initialValue) {
|
|
|
647
701
|
__id: void 0
|
|
648
702
|
};
|
|
649
703
|
registerSignalDevtools(initialValue, s);
|
|
650
|
-
|
|
704
|
+
const accessor = signalOper.bind(s);
|
|
705
|
+
accessor[SIGNAL_MARKER] = true;
|
|
706
|
+
return accessor;
|
|
651
707
|
}
|
|
652
708
|
function signalOper(value) {
|
|
653
709
|
if (arguments.length > 0) {
|
|
@@ -664,7 +720,7 @@ function signalOper(value) {
|
|
|
664
720
|
return;
|
|
665
721
|
}
|
|
666
722
|
const flags = this.flags;
|
|
667
|
-
if (flags & Dirty) {
|
|
723
|
+
if (flags & Dirty && !inCleanup) {
|
|
668
724
|
if (updateSignal(this)) {
|
|
669
725
|
const subs = this.subs;
|
|
670
726
|
if (subs !== void 0) shallowPropagate(subs);
|
|
@@ -692,6 +748,7 @@ function computed(getter) {
|
|
|
692
748
|
getter
|
|
693
749
|
};
|
|
694
750
|
const bound = computedOper.bind(c);
|
|
751
|
+
bound[COMPUTED_MARKER] = true;
|
|
695
752
|
return bound;
|
|
696
753
|
}
|
|
697
754
|
function computedOper() {
|
|
@@ -744,7 +801,35 @@ function effect(fn) {
|
|
|
744
801
|
activeSub = prevSub;
|
|
745
802
|
e.flags &= ~Running;
|
|
746
803
|
}
|
|
747
|
-
|
|
804
|
+
const disposer = effectOper.bind(e);
|
|
805
|
+
disposer[EFFECT_MARKER] = true;
|
|
806
|
+
return disposer;
|
|
807
|
+
}
|
|
808
|
+
function effectWithCleanup(fn, cleanupRunner) {
|
|
809
|
+
const e = {
|
|
810
|
+
fn,
|
|
811
|
+
subs: void 0,
|
|
812
|
+
subsTail: void 0,
|
|
813
|
+
deps: void 0,
|
|
814
|
+
depsTail: void 0,
|
|
815
|
+
flags: WatchingRunning,
|
|
816
|
+
runCleanup: cleanupRunner,
|
|
817
|
+
__id: void 0
|
|
818
|
+
};
|
|
819
|
+
registerEffectDevtools(e);
|
|
820
|
+
const prevSub = activeSub;
|
|
821
|
+
if (prevSub !== void 0) link(e, prevSub, 0);
|
|
822
|
+
activeSub = e;
|
|
823
|
+
try {
|
|
824
|
+
effectRunDevtools(e);
|
|
825
|
+
fn();
|
|
826
|
+
} finally {
|
|
827
|
+
activeSub = prevSub;
|
|
828
|
+
e.flags &= ~Running;
|
|
829
|
+
}
|
|
830
|
+
const disposer = effectOper.bind(e);
|
|
831
|
+
disposer[EFFECT_MARKER] = true;
|
|
832
|
+
return disposer;
|
|
748
833
|
}
|
|
749
834
|
function effectOper() {
|
|
750
835
|
disposeNode(this);
|
|
@@ -759,7 +844,9 @@ function effectScope(fn) {
|
|
|
759
844
|
} finally {
|
|
760
845
|
activeSub = prevSub;
|
|
761
846
|
}
|
|
762
|
-
|
|
847
|
+
const disposer = effectScopeOper.bind(e);
|
|
848
|
+
disposer[EFFECT_SCOPE_MARKER] = true;
|
|
849
|
+
return disposer;
|
|
763
850
|
}
|
|
764
851
|
function effectScopeOper() {
|
|
765
852
|
disposeNode(this);
|
|
@@ -860,8 +947,11 @@ function createMemo(fn) {
|
|
|
860
947
|
function createEffect(fn) {
|
|
861
948
|
let cleanups = [];
|
|
862
949
|
const rootForError = getCurrentRoot();
|
|
863
|
-
const
|
|
950
|
+
const doCleanup = () => {
|
|
864
951
|
runCleanupList(cleanups);
|
|
952
|
+
cleanups = [];
|
|
953
|
+
};
|
|
954
|
+
const run = () => {
|
|
865
955
|
const bucket = [];
|
|
866
956
|
withEffectCleanups(bucket, () => {
|
|
867
957
|
try {
|
|
@@ -878,7 +968,7 @@ function createEffect(fn) {
|
|
|
878
968
|
});
|
|
879
969
|
cleanups = bucket;
|
|
880
970
|
};
|
|
881
|
-
const disposeEffect =
|
|
971
|
+
const disposeEffect = effectWithCleanup(run, doCleanup);
|
|
882
972
|
const teardown = () => {
|
|
883
973
|
runCleanupList(cleanups);
|
|
884
974
|
disposeEffect();
|
|
@@ -889,11 +979,13 @@ function createEffect(fn) {
|
|
|
889
979
|
function createRenderEffect(fn) {
|
|
890
980
|
let cleanup;
|
|
891
981
|
const rootForError = getCurrentRoot();
|
|
892
|
-
const
|
|
982
|
+
const doCleanup = () => {
|
|
893
983
|
if (cleanup) {
|
|
894
984
|
cleanup();
|
|
895
985
|
cleanup = void 0;
|
|
896
986
|
}
|
|
987
|
+
};
|
|
988
|
+
const run = () => {
|
|
897
989
|
try {
|
|
898
990
|
const maybeCleanup = fn();
|
|
899
991
|
if (typeof maybeCleanup === "function") {
|
|
@@ -907,7 +999,7 @@ function createRenderEffect(fn) {
|
|
|
907
999
|
throw err;
|
|
908
1000
|
}
|
|
909
1001
|
};
|
|
910
|
-
const disposeEffect =
|
|
1002
|
+
const disposeEffect = effectWithCleanup(run, doCleanup);
|
|
911
1003
|
const teardown = () => {
|
|
912
1004
|
if (cleanup) {
|
|
913
1005
|
cleanup();
|
|
@@ -1439,9 +1531,6 @@ function mergeProps(...sources) {
|
|
|
1439
1531
|
};
|
|
1440
1532
|
return new Proxy({}, {
|
|
1441
1533
|
get(_, prop) {
|
|
1442
|
-
if (typeof prop === "symbol") {
|
|
1443
|
-
return void 0;
|
|
1444
|
-
}
|
|
1445
1534
|
for (let i = validSources.length - 1; i >= 0; i--) {
|
|
1446
1535
|
const src = validSources[i];
|
|
1447
1536
|
const raw = resolveSource(src);
|
|
@@ -1722,7 +1811,8 @@ function applyRef(el, value) {
|
|
|
1722
1811
|
if (typeof value === "function") {
|
|
1723
1812
|
const refFn = value;
|
|
1724
1813
|
refFn(el);
|
|
1725
|
-
|
|
1814
|
+
const root = getCurrentRoot();
|
|
1815
|
+
if (root) {
|
|
1726
1816
|
registerRootCleanup(() => {
|
|
1727
1817
|
refFn(null);
|
|
1728
1818
|
});
|
|
@@ -1730,7 +1820,8 @@ function applyRef(el, value) {
|
|
|
1730
1820
|
} else if (value && typeof value === "object" && "current" in value) {
|
|
1731
1821
|
const refObj = value;
|
|
1732
1822
|
refObj.current = el;
|
|
1733
|
-
|
|
1823
|
+
const root = getCurrentRoot();
|
|
1824
|
+
if (root) {
|
|
1734
1825
|
registerRootCleanup(() => {
|
|
1735
1826
|
refObj.current = null;
|
|
1736
1827
|
});
|
|
@@ -2141,8 +2232,6 @@ function reconcileArrays(parentNode, a, b) {
|
|
|
2141
2232
|
}
|
|
2142
2233
|
}
|
|
2143
2234
|
}
|
|
2144
|
-
|
|
2145
|
-
// src/list-helpers.ts
|
|
2146
2235
|
function moveNodesBefore(parent, nodes, anchor) {
|
|
2147
2236
|
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
2148
2237
|
const node = nodes[i];
|
|
@@ -2204,6 +2293,7 @@ function removeBlockRange(block) {
|
|
|
2204
2293
|
cursor = next;
|
|
2205
2294
|
}
|
|
2206
2295
|
}
|
|
2296
|
+
var MAX_SAFE_VERSION = 9007199254740991;
|
|
2207
2297
|
function createVersionedSignalAccessor(initialValue) {
|
|
2208
2298
|
let current = initialValue;
|
|
2209
2299
|
let version = 0;
|
|
@@ -2214,7 +2304,7 @@ function createVersionedSignalAccessor(initialValue) {
|
|
|
2214
2304
|
return current;
|
|
2215
2305
|
}
|
|
2216
2306
|
current = value;
|
|
2217
|
-
version
|
|
2307
|
+
version = version >= MAX_SAFE_VERSION ? 1 : version + 1;
|
|
2218
2308
|
track(version);
|
|
2219
2309
|
}
|
|
2220
2310
|
return accessor;
|
|
@@ -2270,15 +2360,21 @@ function createKeyedBlock(key, item, index, render2, needsIndex = true, hostRoot
|
|
|
2270
2360
|
});
|
|
2271
2361
|
const root = createRootContext(hostRoot);
|
|
2272
2362
|
const prevRoot = pushRoot(root);
|
|
2273
|
-
const prevSub = setActiveSub(void 0);
|
|
2274
2363
|
let nodes = [];
|
|
2364
|
+
let scopeDispose;
|
|
2365
|
+
const prevSub = setActiveSub(void 0);
|
|
2275
2366
|
try {
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2367
|
+
scopeDispose = effectScope(() => {
|
|
2368
|
+
const rendered = render2(itemSig, indexSig, key);
|
|
2369
|
+
if (rendered instanceof Node || Array.isArray(rendered) && rendered.every((n) => n instanceof Node)) {
|
|
2370
|
+
nodes = toNodeArray(rendered);
|
|
2371
|
+
} else {
|
|
2372
|
+
const element = createElement(rendered);
|
|
2373
|
+
nodes = toNodeArray(element);
|
|
2374
|
+
}
|
|
2375
|
+
});
|
|
2376
|
+
if (scopeDispose) {
|
|
2377
|
+
root.cleanups.push(scopeDispose);
|
|
2282
2378
|
}
|
|
2283
2379
|
} finally {
|
|
2284
2380
|
setActiveSub(prevSub);
|
|
@@ -2297,6 +2393,86 @@ function createKeyedBlock(key, item, index, render2, needsIndex = true, hostRoot
|
|
|
2297
2393
|
function getFirstNodeAfter(marker) {
|
|
2298
2394
|
return marker.nextSibling;
|
|
2299
2395
|
}
|
|
2396
|
+
function reorderBySwap(parent, first, second) {
|
|
2397
|
+
if (first === second) return false;
|
|
2398
|
+
const firstNodes = first.nodes;
|
|
2399
|
+
const secondNodes = second.nodes;
|
|
2400
|
+
if (firstNodes.length === 0 || secondNodes.length === 0) return false;
|
|
2401
|
+
const lastFirst = firstNodes[firstNodes.length - 1];
|
|
2402
|
+
const lastSecond = secondNodes[secondNodes.length - 1];
|
|
2403
|
+
const afterFirst = lastFirst.nextSibling;
|
|
2404
|
+
const afterSecond = lastSecond.nextSibling;
|
|
2405
|
+
moveNodesBefore(parent, firstNodes, afterSecond);
|
|
2406
|
+
moveNodesBefore(parent, secondNodes, afterFirst);
|
|
2407
|
+
return true;
|
|
2408
|
+
}
|
|
2409
|
+
function getLISIndices(sequence) {
|
|
2410
|
+
const predecessors = new Array(sequence.length);
|
|
2411
|
+
const result = [];
|
|
2412
|
+
for (let i = 0; i < sequence.length; i++) {
|
|
2413
|
+
const value = sequence[i];
|
|
2414
|
+
if (value < 0) {
|
|
2415
|
+
predecessors[i] = -1;
|
|
2416
|
+
continue;
|
|
2417
|
+
}
|
|
2418
|
+
let low = 0;
|
|
2419
|
+
let high = result.length;
|
|
2420
|
+
while (low < high) {
|
|
2421
|
+
const mid = low + high >> 1;
|
|
2422
|
+
if (sequence[result[mid]] < value) {
|
|
2423
|
+
low = mid + 1;
|
|
2424
|
+
} else {
|
|
2425
|
+
high = mid;
|
|
2426
|
+
}
|
|
2427
|
+
}
|
|
2428
|
+
predecessors[i] = low > 0 ? result[low - 1] : -1;
|
|
2429
|
+
if (low === result.length) {
|
|
2430
|
+
result.push(i);
|
|
2431
|
+
} else {
|
|
2432
|
+
result[low] = i;
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
const lis = new Array(result.length);
|
|
2436
|
+
let k = result.length > 0 ? result[result.length - 1] : -1;
|
|
2437
|
+
for (let i = result.length - 1; i >= 0; i--) {
|
|
2438
|
+
lis[i] = k;
|
|
2439
|
+
k = predecessors[k];
|
|
2440
|
+
}
|
|
2441
|
+
return lis;
|
|
2442
|
+
}
|
|
2443
|
+
function reorderByLIS(parent, endMarker, prev, next) {
|
|
2444
|
+
const positions = /* @__PURE__ */ new Map();
|
|
2445
|
+
for (let i = 0; i < prev.length; i++) {
|
|
2446
|
+
positions.set(prev[i], i);
|
|
2447
|
+
}
|
|
2448
|
+
const sequence = new Array(next.length);
|
|
2449
|
+
for (let i = 0; i < next.length; i++) {
|
|
2450
|
+
const position = positions.get(next[i]);
|
|
2451
|
+
if (position === void 0) return false;
|
|
2452
|
+
sequence[i] = position;
|
|
2453
|
+
}
|
|
2454
|
+
const lisIndices = getLISIndices(sequence);
|
|
2455
|
+
if (lisIndices.length === sequence.length) return true;
|
|
2456
|
+
const inLIS = new Array(sequence.length).fill(false);
|
|
2457
|
+
for (let i = 0; i < lisIndices.length; i++) {
|
|
2458
|
+
inLIS[lisIndices[i]] = true;
|
|
2459
|
+
}
|
|
2460
|
+
let anchor = endMarker;
|
|
2461
|
+
let moved = false;
|
|
2462
|
+
for (let i = next.length - 1; i >= 0; i--) {
|
|
2463
|
+
const block = next[i];
|
|
2464
|
+
const nodes = block.nodes;
|
|
2465
|
+
if (nodes.length === 0) continue;
|
|
2466
|
+
if (inLIS[i]) {
|
|
2467
|
+
anchor = nodes[0];
|
|
2468
|
+
continue;
|
|
2469
|
+
}
|
|
2470
|
+
moveNodesBefore(parent, nodes, anchor);
|
|
2471
|
+
anchor = nodes[0];
|
|
2472
|
+
moved = true;
|
|
2473
|
+
}
|
|
2474
|
+
return moved;
|
|
2475
|
+
}
|
|
2300
2476
|
function createKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
2301
2477
|
const resolvedNeedsIndex = arguments.length >= 4 ? !!needsIndex : renderItem.length > 1;
|
|
2302
2478
|
return createFineGrainedKeyedList(getItems, keyFn, renderItem, resolvedNeedsIndex);
|
|
@@ -2329,10 +2505,6 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2329
2505
|
const prevOrderedBlocks = container.orderedBlocks;
|
|
2330
2506
|
const nextOrderedBlocks = container.nextOrderedBlocks;
|
|
2331
2507
|
const orderedIndexByKey = container.orderedIndexByKey;
|
|
2332
|
-
newBlocks.clear();
|
|
2333
|
-
nextOrderedBlocks.length = 0;
|
|
2334
|
-
orderedIndexByKey.clear();
|
|
2335
|
-
const createdBlocks = [];
|
|
2336
2508
|
const newItems = getItems();
|
|
2337
2509
|
if (newItems.length === 0) {
|
|
2338
2510
|
if (oldBlocks.size > 0) {
|
|
@@ -2355,8 +2527,44 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2355
2527
|
return;
|
|
2356
2528
|
}
|
|
2357
2529
|
const prevCount = prevOrderedBlocks.length;
|
|
2530
|
+
if (prevCount > 0 && newItems.length === prevCount && orderedIndexByKey.size === prevCount) {
|
|
2531
|
+
let stableOrder = true;
|
|
2532
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2533
|
+
for (let i = 0; i < prevCount; i++) {
|
|
2534
|
+
const item = newItems[i];
|
|
2535
|
+
const key = keyFn(item, i);
|
|
2536
|
+
if (seen.has(key) || prevOrderedBlocks[i].key !== key) {
|
|
2537
|
+
stableOrder = false;
|
|
2538
|
+
break;
|
|
2539
|
+
}
|
|
2540
|
+
seen.add(key);
|
|
2541
|
+
}
|
|
2542
|
+
if (stableOrder) {
|
|
2543
|
+
for (let i = 0; i < prevCount; i++) {
|
|
2544
|
+
const item = newItems[i];
|
|
2545
|
+
const block = prevOrderedBlocks[i];
|
|
2546
|
+
if (block.rawItem !== item) {
|
|
2547
|
+
block.rawItem = item;
|
|
2548
|
+
block.item(item);
|
|
2549
|
+
}
|
|
2550
|
+
if (needsIndex && block.rawIndex !== i) {
|
|
2551
|
+
block.rawIndex = i;
|
|
2552
|
+
block.index(i);
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
return;
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
newBlocks.clear();
|
|
2559
|
+
nextOrderedBlocks.length = 0;
|
|
2560
|
+
orderedIndexByKey.clear();
|
|
2561
|
+
const createdBlocks = [];
|
|
2358
2562
|
let appendCandidate = prevCount > 0 && newItems.length >= prevCount;
|
|
2359
2563
|
const appendedBlocks = [];
|
|
2564
|
+
let mismatchCount = 0;
|
|
2565
|
+
let mismatchFirst = -1;
|
|
2566
|
+
let mismatchSecond = -1;
|
|
2567
|
+
let hasDuplicateKey = false;
|
|
2360
2568
|
newItems.forEach((item, index) => {
|
|
2361
2569
|
const key = keyFn(item, index);
|
|
2362
2570
|
let block = oldBlocks.get(key);
|
|
@@ -2388,6 +2596,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2388
2596
|
const position = orderedIndexByKey.get(key);
|
|
2389
2597
|
if (position !== void 0) {
|
|
2390
2598
|
appendCandidate = false;
|
|
2599
|
+
hasDuplicateKey = true;
|
|
2391
2600
|
const prior = nextOrderedBlocks[position];
|
|
2392
2601
|
if (prior && prior !== resolvedBlock) {
|
|
2393
2602
|
destroyRoot(prior.root);
|
|
@@ -2404,8 +2613,17 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2404
2613
|
appendCandidate = false;
|
|
2405
2614
|
}
|
|
2406
2615
|
}
|
|
2407
|
-
|
|
2616
|
+
const nextIndex = nextOrderedBlocks.length;
|
|
2617
|
+
orderedIndexByKey.set(key, nextIndex);
|
|
2408
2618
|
nextOrderedBlocks.push(resolvedBlock);
|
|
2619
|
+
if (mismatchCount < 3 && (nextIndex >= prevCount || prevOrderedBlocks[nextIndex] !== resolvedBlock)) {
|
|
2620
|
+
if (mismatchCount === 0) {
|
|
2621
|
+
mismatchFirst = nextIndex;
|
|
2622
|
+
} else if (mismatchCount === 1) {
|
|
2623
|
+
mismatchSecond = nextIndex;
|
|
2624
|
+
}
|
|
2625
|
+
mismatchCount++;
|
|
2626
|
+
}
|
|
2409
2627
|
}
|
|
2410
2628
|
if (appendCandidate && index >= prevCount) {
|
|
2411
2629
|
appendedBlocks.push(resolvedBlock);
|
|
@@ -2446,7 +2664,26 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2446
2664
|
}
|
|
2447
2665
|
oldBlocks.clear();
|
|
2448
2666
|
}
|
|
2449
|
-
|
|
2667
|
+
const canReorderInPlace = createdBlocks.length === 0 && oldBlocks.size === 0 && nextOrderedBlocks.length === prevOrderedBlocks.length;
|
|
2668
|
+
let skipReconcile = false;
|
|
2669
|
+
let updateNodeBuffer = true;
|
|
2670
|
+
if (canReorderInPlace && nextOrderedBlocks.length > 0 && !hasDuplicateKey) {
|
|
2671
|
+
if (mismatchCount === 0) {
|
|
2672
|
+
skipReconcile = true;
|
|
2673
|
+
updateNodeBuffer = false;
|
|
2674
|
+
} else if (mismatchCount === 2 && prevOrderedBlocks[mismatchFirst] === nextOrderedBlocks[mismatchSecond] && prevOrderedBlocks[mismatchSecond] === nextOrderedBlocks[mismatchFirst]) {
|
|
2675
|
+
if (reorderBySwap(
|
|
2676
|
+
parent,
|
|
2677
|
+
prevOrderedBlocks[mismatchFirst],
|
|
2678
|
+
prevOrderedBlocks[mismatchSecond]
|
|
2679
|
+
)) {
|
|
2680
|
+
skipReconcile = true;
|
|
2681
|
+
}
|
|
2682
|
+
} else if (reorderByLIS(parent, container.endMarker, prevOrderedBlocks, nextOrderedBlocks)) {
|
|
2683
|
+
skipReconcile = true;
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
if (!skipReconcile && (newBlocks.size > 0 || container.currentNodes.length > 0)) {
|
|
2450
2687
|
const prevNodes = container.currentNodes;
|
|
2451
2688
|
const nextNodes = container.nextNodes;
|
|
2452
2689
|
nextNodes.length = 0;
|
|
@@ -2461,6 +2698,20 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2461
2698
|
reconcileArrays(parent, prevNodes, nextNodes);
|
|
2462
2699
|
container.currentNodes = nextNodes;
|
|
2463
2700
|
container.nextNodes = prevNodes;
|
|
2701
|
+
} else if (skipReconcile && updateNodeBuffer) {
|
|
2702
|
+
const prevNodes = container.currentNodes;
|
|
2703
|
+
const nextNodes = container.nextNodes;
|
|
2704
|
+
nextNodes.length = 0;
|
|
2705
|
+
nextNodes.push(container.startMarker);
|
|
2706
|
+
for (let i = 0; i < nextOrderedBlocks.length; i++) {
|
|
2707
|
+
const nodes = nextOrderedBlocks[i].nodes;
|
|
2708
|
+
for (let j = 0; j < nodes.length; j++) {
|
|
2709
|
+
nextNodes.push(nodes[j]);
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2712
|
+
nextNodes.push(container.endMarker);
|
|
2713
|
+
container.currentNodes = nextNodes;
|
|
2714
|
+
container.nextNodes = prevNodes;
|
|
2464
2715
|
}
|
|
2465
2716
|
container.blocks = newBlocks;
|
|
2466
2717
|
container.nextBlocks = oldBlocks;
|
|
@@ -3055,7 +3306,9 @@ function bindEvent(el, eventName, handler, options2) {
|
|
|
3055
3306
|
const fn = resolveHandler();
|
|
3056
3307
|
callEventHandler(fn, args[0], el);
|
|
3057
3308
|
} catch (err) {
|
|
3058
|
-
handleError(err, { source: "event", eventName }, rootRef)
|
|
3309
|
+
if (!handleError(err, { source: "event", eventName }, rootRef)) {
|
|
3310
|
+
throw err;
|
|
3311
|
+
}
|
|
3059
3312
|
}
|
|
3060
3313
|
};
|
|
3061
3314
|
return () => {
|