@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.js
CHANGED
|
@@ -260,7 +260,7 @@ function handleError(err, info, startRoot) {
|
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
|
-
|
|
263
|
+
return false;
|
|
264
264
|
}
|
|
265
265
|
function handleSuspend(token, startRoot) {
|
|
266
266
|
let root = startRoot ?? currentRoot;
|
|
@@ -305,6 +305,11 @@ var lowPriorityQueue = [];
|
|
|
305
305
|
var enqueueMicrotask = typeof queueMicrotask === "function" ? queueMicrotask : (fn) => {
|
|
306
306
|
Promise.resolve().then(fn);
|
|
307
307
|
};
|
|
308
|
+
var inCleanup = false;
|
|
309
|
+
var SIGNAL_MARKER = Symbol.for("fict:signal");
|
|
310
|
+
var COMPUTED_MARKER = Symbol.for("fict:computed");
|
|
311
|
+
var EFFECT_MARKER = Symbol.for("fict:effect");
|
|
312
|
+
var EFFECT_SCOPE_MARKER = Symbol.for("fict:effectScope");
|
|
308
313
|
function link(dep, sub, version) {
|
|
309
314
|
const prevDep = sub.depsTail;
|
|
310
315
|
if (prevDep !== void 0 && prevDep.dep === dep) return;
|
|
@@ -428,13 +433,21 @@ function checkDirty(firstLink, sub) {
|
|
|
428
433
|
dirty = true;
|
|
429
434
|
}
|
|
430
435
|
} else if ((depFlags & MutablePending) === MutablePending) {
|
|
431
|
-
if (
|
|
432
|
-
|
|
436
|
+
if (!dep.deps) {
|
|
437
|
+
const nextDep = link2.nextDep;
|
|
438
|
+
if (nextDep !== void 0) {
|
|
439
|
+
link2 = nextDep;
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
} else {
|
|
443
|
+
if (link2.nextSub !== void 0 || link2.prevSub !== void 0) {
|
|
444
|
+
stack = { value: link2, prev: stack };
|
|
445
|
+
}
|
|
446
|
+
link2 = dep.deps;
|
|
447
|
+
sub = dep;
|
|
448
|
+
++checkDepth;
|
|
449
|
+
continue;
|
|
433
450
|
}
|
|
434
|
-
link2 = dep.deps;
|
|
435
|
-
sub = dep;
|
|
436
|
-
++checkDepth;
|
|
437
|
-
continue;
|
|
438
451
|
}
|
|
439
452
|
if (!dirty) {
|
|
440
453
|
const nextDep = link2.nextDep;
|
|
@@ -512,8 +525,12 @@ function disposeNode(node) {
|
|
|
512
525
|
node.depsTail = void 0;
|
|
513
526
|
node.flags = 0;
|
|
514
527
|
purgeDeps(node);
|
|
515
|
-
|
|
516
|
-
|
|
528
|
+
let sub = node.subs;
|
|
529
|
+
while (sub !== void 0) {
|
|
530
|
+
const next = sub.nextSub;
|
|
531
|
+
unlink(sub);
|
|
532
|
+
sub = next;
|
|
533
|
+
}
|
|
517
534
|
}
|
|
518
535
|
function updateSignal(s) {
|
|
519
536
|
s.flags = Mutable;
|
|
@@ -550,7 +567,15 @@ function updateComputed(c) {
|
|
|
550
567
|
}
|
|
551
568
|
function runEffect(e) {
|
|
552
569
|
const flags = e.flags;
|
|
553
|
-
if (flags & Dirty
|
|
570
|
+
if (flags & Dirty) {
|
|
571
|
+
if (e.runCleanup) {
|
|
572
|
+
inCleanup = true;
|
|
573
|
+
try {
|
|
574
|
+
e.runCleanup();
|
|
575
|
+
} finally {
|
|
576
|
+
inCleanup = false;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
554
579
|
++cycle;
|
|
555
580
|
effectRunDevtools(e);
|
|
556
581
|
e.depsTail = void 0;
|
|
@@ -567,6 +592,35 @@ function runEffect(e) {
|
|
|
567
592
|
e.flags = Watching;
|
|
568
593
|
throw err;
|
|
569
594
|
}
|
|
595
|
+
} else if (flags & Pending && e.deps) {
|
|
596
|
+
if (e.runCleanup) {
|
|
597
|
+
inCleanup = true;
|
|
598
|
+
try {
|
|
599
|
+
e.runCleanup();
|
|
600
|
+
} finally {
|
|
601
|
+
inCleanup = false;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
if (checkDirty(e.deps, e)) {
|
|
605
|
+
++cycle;
|
|
606
|
+
effectRunDevtools(e);
|
|
607
|
+
e.depsTail = void 0;
|
|
608
|
+
e.flags = WatchingRunning;
|
|
609
|
+
const prevSub = activeSub;
|
|
610
|
+
activeSub = e;
|
|
611
|
+
try {
|
|
612
|
+
e.fn();
|
|
613
|
+
activeSub = prevSub;
|
|
614
|
+
e.flags = Watching;
|
|
615
|
+
purgeDeps(e);
|
|
616
|
+
} catch (err) {
|
|
617
|
+
activeSub = prevSub;
|
|
618
|
+
e.flags = Watching;
|
|
619
|
+
throw err;
|
|
620
|
+
}
|
|
621
|
+
} else {
|
|
622
|
+
e.flags = Watching;
|
|
623
|
+
}
|
|
570
624
|
} else {
|
|
571
625
|
e.flags = Watching;
|
|
572
626
|
}
|
|
@@ -645,7 +699,9 @@ function signal(initialValue) {
|
|
|
645
699
|
__id: void 0
|
|
646
700
|
};
|
|
647
701
|
registerSignalDevtools(initialValue, s);
|
|
648
|
-
|
|
702
|
+
const accessor = signalOper.bind(s);
|
|
703
|
+
accessor[SIGNAL_MARKER] = true;
|
|
704
|
+
return accessor;
|
|
649
705
|
}
|
|
650
706
|
function signalOper(value) {
|
|
651
707
|
if (arguments.length > 0) {
|
|
@@ -662,7 +718,7 @@ function signalOper(value) {
|
|
|
662
718
|
return;
|
|
663
719
|
}
|
|
664
720
|
const flags = this.flags;
|
|
665
|
-
if (flags & Dirty) {
|
|
721
|
+
if (flags & Dirty && !inCleanup) {
|
|
666
722
|
if (updateSignal(this)) {
|
|
667
723
|
const subs = this.subs;
|
|
668
724
|
if (subs !== void 0) shallowPropagate(subs);
|
|
@@ -690,6 +746,7 @@ function computed(getter) {
|
|
|
690
746
|
getter
|
|
691
747
|
};
|
|
692
748
|
const bound = computedOper.bind(c);
|
|
749
|
+
bound[COMPUTED_MARKER] = true;
|
|
693
750
|
return bound;
|
|
694
751
|
}
|
|
695
752
|
function computedOper() {
|
|
@@ -742,7 +799,35 @@ function effect(fn) {
|
|
|
742
799
|
activeSub = prevSub;
|
|
743
800
|
e.flags &= ~Running;
|
|
744
801
|
}
|
|
745
|
-
|
|
802
|
+
const disposer = effectOper.bind(e);
|
|
803
|
+
disposer[EFFECT_MARKER] = true;
|
|
804
|
+
return disposer;
|
|
805
|
+
}
|
|
806
|
+
function effectWithCleanup(fn, cleanupRunner) {
|
|
807
|
+
const e = {
|
|
808
|
+
fn,
|
|
809
|
+
subs: void 0,
|
|
810
|
+
subsTail: void 0,
|
|
811
|
+
deps: void 0,
|
|
812
|
+
depsTail: void 0,
|
|
813
|
+
flags: WatchingRunning,
|
|
814
|
+
runCleanup: cleanupRunner,
|
|
815
|
+
__id: void 0
|
|
816
|
+
};
|
|
817
|
+
registerEffectDevtools(e);
|
|
818
|
+
const prevSub = activeSub;
|
|
819
|
+
if (prevSub !== void 0) link(e, prevSub, 0);
|
|
820
|
+
activeSub = e;
|
|
821
|
+
try {
|
|
822
|
+
effectRunDevtools(e);
|
|
823
|
+
fn();
|
|
824
|
+
} finally {
|
|
825
|
+
activeSub = prevSub;
|
|
826
|
+
e.flags &= ~Running;
|
|
827
|
+
}
|
|
828
|
+
const disposer = effectOper.bind(e);
|
|
829
|
+
disposer[EFFECT_MARKER] = true;
|
|
830
|
+
return disposer;
|
|
746
831
|
}
|
|
747
832
|
function effectOper() {
|
|
748
833
|
disposeNode(this);
|
|
@@ -757,7 +842,9 @@ function effectScope(fn) {
|
|
|
757
842
|
} finally {
|
|
758
843
|
activeSub = prevSub;
|
|
759
844
|
}
|
|
760
|
-
|
|
845
|
+
const disposer = effectScopeOper.bind(e);
|
|
846
|
+
disposer[EFFECT_SCOPE_MARKER] = true;
|
|
847
|
+
return disposer;
|
|
761
848
|
}
|
|
762
849
|
function effectScopeOper() {
|
|
763
850
|
disposeNode(this);
|
|
@@ -858,8 +945,11 @@ function createMemo(fn) {
|
|
|
858
945
|
function createEffect(fn) {
|
|
859
946
|
let cleanups = [];
|
|
860
947
|
const rootForError = getCurrentRoot();
|
|
861
|
-
const
|
|
948
|
+
const doCleanup = () => {
|
|
862
949
|
runCleanupList(cleanups);
|
|
950
|
+
cleanups = [];
|
|
951
|
+
};
|
|
952
|
+
const run = () => {
|
|
863
953
|
const bucket = [];
|
|
864
954
|
withEffectCleanups(bucket, () => {
|
|
865
955
|
try {
|
|
@@ -876,7 +966,7 @@ function createEffect(fn) {
|
|
|
876
966
|
});
|
|
877
967
|
cleanups = bucket;
|
|
878
968
|
};
|
|
879
|
-
const disposeEffect =
|
|
969
|
+
const disposeEffect = effectWithCleanup(run, doCleanup);
|
|
880
970
|
const teardown = () => {
|
|
881
971
|
runCleanupList(cleanups);
|
|
882
972
|
disposeEffect();
|
|
@@ -887,11 +977,13 @@ function createEffect(fn) {
|
|
|
887
977
|
function createRenderEffect(fn) {
|
|
888
978
|
let cleanup;
|
|
889
979
|
const rootForError = getCurrentRoot();
|
|
890
|
-
const
|
|
980
|
+
const doCleanup = () => {
|
|
891
981
|
if (cleanup) {
|
|
892
982
|
cleanup();
|
|
893
983
|
cleanup = void 0;
|
|
894
984
|
}
|
|
985
|
+
};
|
|
986
|
+
const run = () => {
|
|
895
987
|
try {
|
|
896
988
|
const maybeCleanup = fn();
|
|
897
989
|
if (typeof maybeCleanup === "function") {
|
|
@@ -905,7 +997,7 @@ function createRenderEffect(fn) {
|
|
|
905
997
|
throw err;
|
|
906
998
|
}
|
|
907
999
|
};
|
|
908
|
-
const disposeEffect =
|
|
1000
|
+
const disposeEffect = effectWithCleanup(run, doCleanup);
|
|
909
1001
|
const teardown = () => {
|
|
910
1002
|
if (cleanup) {
|
|
911
1003
|
cleanup();
|
|
@@ -1437,9 +1529,6 @@ function mergeProps(...sources) {
|
|
|
1437
1529
|
};
|
|
1438
1530
|
return new Proxy({}, {
|
|
1439
1531
|
get(_, prop) {
|
|
1440
|
-
if (typeof prop === "symbol") {
|
|
1441
|
-
return void 0;
|
|
1442
|
-
}
|
|
1443
1532
|
for (let i = validSources.length - 1; i >= 0; i--) {
|
|
1444
1533
|
const src = validSources[i];
|
|
1445
1534
|
const raw = resolveSource(src);
|
|
@@ -1720,7 +1809,8 @@ function applyRef(el, value) {
|
|
|
1720
1809
|
if (typeof value === "function") {
|
|
1721
1810
|
const refFn = value;
|
|
1722
1811
|
refFn(el);
|
|
1723
|
-
|
|
1812
|
+
const root = getCurrentRoot();
|
|
1813
|
+
if (root) {
|
|
1724
1814
|
registerRootCleanup(() => {
|
|
1725
1815
|
refFn(null);
|
|
1726
1816
|
});
|
|
@@ -1728,7 +1818,8 @@ function applyRef(el, value) {
|
|
|
1728
1818
|
} else if (value && typeof value === "object" && "current" in value) {
|
|
1729
1819
|
const refObj = value;
|
|
1730
1820
|
refObj.current = el;
|
|
1731
|
-
|
|
1821
|
+
const root = getCurrentRoot();
|
|
1822
|
+
if (root) {
|
|
1732
1823
|
registerRootCleanup(() => {
|
|
1733
1824
|
refObj.current = null;
|
|
1734
1825
|
});
|
|
@@ -2139,8 +2230,6 @@ function reconcileArrays(parentNode, a, b) {
|
|
|
2139
2230
|
}
|
|
2140
2231
|
}
|
|
2141
2232
|
}
|
|
2142
|
-
|
|
2143
|
-
// src/list-helpers.ts
|
|
2144
2233
|
function moveNodesBefore(parent, nodes, anchor) {
|
|
2145
2234
|
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
2146
2235
|
const node = nodes[i];
|
|
@@ -2202,6 +2291,7 @@ function removeBlockRange(block) {
|
|
|
2202
2291
|
cursor = next;
|
|
2203
2292
|
}
|
|
2204
2293
|
}
|
|
2294
|
+
var MAX_SAFE_VERSION = 9007199254740991;
|
|
2205
2295
|
function createVersionedSignalAccessor(initialValue) {
|
|
2206
2296
|
let current = initialValue;
|
|
2207
2297
|
let version = 0;
|
|
@@ -2212,7 +2302,7 @@ function createVersionedSignalAccessor(initialValue) {
|
|
|
2212
2302
|
return current;
|
|
2213
2303
|
}
|
|
2214
2304
|
current = value;
|
|
2215
|
-
version
|
|
2305
|
+
version = version >= MAX_SAFE_VERSION ? 1 : version + 1;
|
|
2216
2306
|
track(version);
|
|
2217
2307
|
}
|
|
2218
2308
|
return accessor;
|
|
@@ -2268,15 +2358,21 @@ function createKeyedBlock(key, item, index, render2, needsIndex = true, hostRoot
|
|
|
2268
2358
|
});
|
|
2269
2359
|
const root = createRootContext(hostRoot);
|
|
2270
2360
|
const prevRoot = pushRoot(root);
|
|
2271
|
-
const prevSub = setActiveSub(void 0);
|
|
2272
2361
|
let nodes = [];
|
|
2362
|
+
let scopeDispose;
|
|
2363
|
+
const prevSub = setActiveSub(void 0);
|
|
2273
2364
|
try {
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2365
|
+
scopeDispose = effectScope(() => {
|
|
2366
|
+
const rendered = render2(itemSig, indexSig, key);
|
|
2367
|
+
if (rendered instanceof Node || Array.isArray(rendered) && rendered.every((n) => n instanceof Node)) {
|
|
2368
|
+
nodes = toNodeArray(rendered);
|
|
2369
|
+
} else {
|
|
2370
|
+
const element = createElement(rendered);
|
|
2371
|
+
nodes = toNodeArray(element);
|
|
2372
|
+
}
|
|
2373
|
+
});
|
|
2374
|
+
if (scopeDispose) {
|
|
2375
|
+
root.cleanups.push(scopeDispose);
|
|
2280
2376
|
}
|
|
2281
2377
|
} finally {
|
|
2282
2378
|
setActiveSub(prevSub);
|
|
@@ -2295,6 +2391,86 @@ function createKeyedBlock(key, item, index, render2, needsIndex = true, hostRoot
|
|
|
2295
2391
|
function getFirstNodeAfter(marker) {
|
|
2296
2392
|
return marker.nextSibling;
|
|
2297
2393
|
}
|
|
2394
|
+
function reorderBySwap(parent, first, second) {
|
|
2395
|
+
if (first === second) return false;
|
|
2396
|
+
const firstNodes = first.nodes;
|
|
2397
|
+
const secondNodes = second.nodes;
|
|
2398
|
+
if (firstNodes.length === 0 || secondNodes.length === 0) return false;
|
|
2399
|
+
const lastFirst = firstNodes[firstNodes.length - 1];
|
|
2400
|
+
const lastSecond = secondNodes[secondNodes.length - 1];
|
|
2401
|
+
const afterFirst = lastFirst.nextSibling;
|
|
2402
|
+
const afterSecond = lastSecond.nextSibling;
|
|
2403
|
+
moveNodesBefore(parent, firstNodes, afterSecond);
|
|
2404
|
+
moveNodesBefore(parent, secondNodes, afterFirst);
|
|
2405
|
+
return true;
|
|
2406
|
+
}
|
|
2407
|
+
function getLISIndices(sequence) {
|
|
2408
|
+
const predecessors = new Array(sequence.length);
|
|
2409
|
+
const result = [];
|
|
2410
|
+
for (let i = 0; i < sequence.length; i++) {
|
|
2411
|
+
const value = sequence[i];
|
|
2412
|
+
if (value < 0) {
|
|
2413
|
+
predecessors[i] = -1;
|
|
2414
|
+
continue;
|
|
2415
|
+
}
|
|
2416
|
+
let low = 0;
|
|
2417
|
+
let high = result.length;
|
|
2418
|
+
while (low < high) {
|
|
2419
|
+
const mid = low + high >> 1;
|
|
2420
|
+
if (sequence[result[mid]] < value) {
|
|
2421
|
+
low = mid + 1;
|
|
2422
|
+
} else {
|
|
2423
|
+
high = mid;
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
predecessors[i] = low > 0 ? result[low - 1] : -1;
|
|
2427
|
+
if (low === result.length) {
|
|
2428
|
+
result.push(i);
|
|
2429
|
+
} else {
|
|
2430
|
+
result[low] = i;
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
const lis = new Array(result.length);
|
|
2434
|
+
let k = result.length > 0 ? result[result.length - 1] : -1;
|
|
2435
|
+
for (let i = result.length - 1; i >= 0; i--) {
|
|
2436
|
+
lis[i] = k;
|
|
2437
|
+
k = predecessors[k];
|
|
2438
|
+
}
|
|
2439
|
+
return lis;
|
|
2440
|
+
}
|
|
2441
|
+
function reorderByLIS(parent, endMarker, prev, next) {
|
|
2442
|
+
const positions = /* @__PURE__ */ new Map();
|
|
2443
|
+
for (let i = 0; i < prev.length; i++) {
|
|
2444
|
+
positions.set(prev[i], i);
|
|
2445
|
+
}
|
|
2446
|
+
const sequence = new Array(next.length);
|
|
2447
|
+
for (let i = 0; i < next.length; i++) {
|
|
2448
|
+
const position = positions.get(next[i]);
|
|
2449
|
+
if (position === void 0) return false;
|
|
2450
|
+
sequence[i] = position;
|
|
2451
|
+
}
|
|
2452
|
+
const lisIndices = getLISIndices(sequence);
|
|
2453
|
+
if (lisIndices.length === sequence.length) return true;
|
|
2454
|
+
const inLIS = new Array(sequence.length).fill(false);
|
|
2455
|
+
for (let i = 0; i < lisIndices.length; i++) {
|
|
2456
|
+
inLIS[lisIndices[i]] = true;
|
|
2457
|
+
}
|
|
2458
|
+
let anchor = endMarker;
|
|
2459
|
+
let moved = false;
|
|
2460
|
+
for (let i = next.length - 1; i >= 0; i--) {
|
|
2461
|
+
const block = next[i];
|
|
2462
|
+
const nodes = block.nodes;
|
|
2463
|
+
if (nodes.length === 0) continue;
|
|
2464
|
+
if (inLIS[i]) {
|
|
2465
|
+
anchor = nodes[0];
|
|
2466
|
+
continue;
|
|
2467
|
+
}
|
|
2468
|
+
moveNodesBefore(parent, nodes, anchor);
|
|
2469
|
+
anchor = nodes[0];
|
|
2470
|
+
moved = true;
|
|
2471
|
+
}
|
|
2472
|
+
return moved;
|
|
2473
|
+
}
|
|
2298
2474
|
function createKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
2299
2475
|
const resolvedNeedsIndex = arguments.length >= 4 ? !!needsIndex : renderItem.length > 1;
|
|
2300
2476
|
return createFineGrainedKeyedList(getItems, keyFn, renderItem, resolvedNeedsIndex);
|
|
@@ -2327,10 +2503,6 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2327
2503
|
const prevOrderedBlocks = container.orderedBlocks;
|
|
2328
2504
|
const nextOrderedBlocks = container.nextOrderedBlocks;
|
|
2329
2505
|
const orderedIndexByKey = container.orderedIndexByKey;
|
|
2330
|
-
newBlocks.clear();
|
|
2331
|
-
nextOrderedBlocks.length = 0;
|
|
2332
|
-
orderedIndexByKey.clear();
|
|
2333
|
-
const createdBlocks = [];
|
|
2334
2506
|
const newItems = getItems();
|
|
2335
2507
|
if (newItems.length === 0) {
|
|
2336
2508
|
if (oldBlocks.size > 0) {
|
|
@@ -2353,8 +2525,44 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2353
2525
|
return;
|
|
2354
2526
|
}
|
|
2355
2527
|
const prevCount = prevOrderedBlocks.length;
|
|
2528
|
+
if (prevCount > 0 && newItems.length === prevCount && orderedIndexByKey.size === prevCount) {
|
|
2529
|
+
let stableOrder = true;
|
|
2530
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2531
|
+
for (let i = 0; i < prevCount; i++) {
|
|
2532
|
+
const item = newItems[i];
|
|
2533
|
+
const key = keyFn(item, i);
|
|
2534
|
+
if (seen.has(key) || prevOrderedBlocks[i].key !== key) {
|
|
2535
|
+
stableOrder = false;
|
|
2536
|
+
break;
|
|
2537
|
+
}
|
|
2538
|
+
seen.add(key);
|
|
2539
|
+
}
|
|
2540
|
+
if (stableOrder) {
|
|
2541
|
+
for (let i = 0; i < prevCount; i++) {
|
|
2542
|
+
const item = newItems[i];
|
|
2543
|
+
const block = prevOrderedBlocks[i];
|
|
2544
|
+
if (block.rawItem !== item) {
|
|
2545
|
+
block.rawItem = item;
|
|
2546
|
+
block.item(item);
|
|
2547
|
+
}
|
|
2548
|
+
if (needsIndex && block.rawIndex !== i) {
|
|
2549
|
+
block.rawIndex = i;
|
|
2550
|
+
block.index(i);
|
|
2551
|
+
}
|
|
2552
|
+
}
|
|
2553
|
+
return;
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
newBlocks.clear();
|
|
2557
|
+
nextOrderedBlocks.length = 0;
|
|
2558
|
+
orderedIndexByKey.clear();
|
|
2559
|
+
const createdBlocks = [];
|
|
2356
2560
|
let appendCandidate = prevCount > 0 && newItems.length >= prevCount;
|
|
2357
2561
|
const appendedBlocks = [];
|
|
2562
|
+
let mismatchCount = 0;
|
|
2563
|
+
let mismatchFirst = -1;
|
|
2564
|
+
let mismatchSecond = -1;
|
|
2565
|
+
let hasDuplicateKey = false;
|
|
2358
2566
|
newItems.forEach((item, index) => {
|
|
2359
2567
|
const key = keyFn(item, index);
|
|
2360
2568
|
let block = oldBlocks.get(key);
|
|
@@ -2386,6 +2594,7 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2386
2594
|
const position = orderedIndexByKey.get(key);
|
|
2387
2595
|
if (position !== void 0) {
|
|
2388
2596
|
appendCandidate = false;
|
|
2597
|
+
hasDuplicateKey = true;
|
|
2389
2598
|
const prior = nextOrderedBlocks[position];
|
|
2390
2599
|
if (prior && prior !== resolvedBlock) {
|
|
2391
2600
|
destroyRoot(prior.root);
|
|
@@ -2402,8 +2611,17 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2402
2611
|
appendCandidate = false;
|
|
2403
2612
|
}
|
|
2404
2613
|
}
|
|
2405
|
-
|
|
2614
|
+
const nextIndex = nextOrderedBlocks.length;
|
|
2615
|
+
orderedIndexByKey.set(key, nextIndex);
|
|
2406
2616
|
nextOrderedBlocks.push(resolvedBlock);
|
|
2617
|
+
if (mismatchCount < 3 && (nextIndex >= prevCount || prevOrderedBlocks[nextIndex] !== resolvedBlock)) {
|
|
2618
|
+
if (mismatchCount === 0) {
|
|
2619
|
+
mismatchFirst = nextIndex;
|
|
2620
|
+
} else if (mismatchCount === 1) {
|
|
2621
|
+
mismatchSecond = nextIndex;
|
|
2622
|
+
}
|
|
2623
|
+
mismatchCount++;
|
|
2624
|
+
}
|
|
2407
2625
|
}
|
|
2408
2626
|
if (appendCandidate && index >= prevCount) {
|
|
2409
2627
|
appendedBlocks.push(resolvedBlock);
|
|
@@ -2444,7 +2662,26 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2444
2662
|
}
|
|
2445
2663
|
oldBlocks.clear();
|
|
2446
2664
|
}
|
|
2447
|
-
|
|
2665
|
+
const canReorderInPlace = createdBlocks.length === 0 && oldBlocks.size === 0 && nextOrderedBlocks.length === prevOrderedBlocks.length;
|
|
2666
|
+
let skipReconcile = false;
|
|
2667
|
+
let updateNodeBuffer = true;
|
|
2668
|
+
if (canReorderInPlace && nextOrderedBlocks.length > 0 && !hasDuplicateKey) {
|
|
2669
|
+
if (mismatchCount === 0) {
|
|
2670
|
+
skipReconcile = true;
|
|
2671
|
+
updateNodeBuffer = false;
|
|
2672
|
+
} else if (mismatchCount === 2 && prevOrderedBlocks[mismatchFirst] === nextOrderedBlocks[mismatchSecond] && prevOrderedBlocks[mismatchSecond] === nextOrderedBlocks[mismatchFirst]) {
|
|
2673
|
+
if (reorderBySwap(
|
|
2674
|
+
parent,
|
|
2675
|
+
prevOrderedBlocks[mismatchFirst],
|
|
2676
|
+
prevOrderedBlocks[mismatchSecond]
|
|
2677
|
+
)) {
|
|
2678
|
+
skipReconcile = true;
|
|
2679
|
+
}
|
|
2680
|
+
} else if (reorderByLIS(parent, container.endMarker, prevOrderedBlocks, nextOrderedBlocks)) {
|
|
2681
|
+
skipReconcile = true;
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2684
|
+
if (!skipReconcile && (newBlocks.size > 0 || container.currentNodes.length > 0)) {
|
|
2448
2685
|
const prevNodes = container.currentNodes;
|
|
2449
2686
|
const nextNodes = container.nextNodes;
|
|
2450
2687
|
nextNodes.length = 0;
|
|
@@ -2459,6 +2696,20 @@ function createFineGrainedKeyedList(getItems, keyFn, renderItem, needsIndex) {
|
|
|
2459
2696
|
reconcileArrays(parent, prevNodes, nextNodes);
|
|
2460
2697
|
container.currentNodes = nextNodes;
|
|
2461
2698
|
container.nextNodes = prevNodes;
|
|
2699
|
+
} else if (skipReconcile && updateNodeBuffer) {
|
|
2700
|
+
const prevNodes = container.currentNodes;
|
|
2701
|
+
const nextNodes = container.nextNodes;
|
|
2702
|
+
nextNodes.length = 0;
|
|
2703
|
+
nextNodes.push(container.startMarker);
|
|
2704
|
+
for (let i = 0; i < nextOrderedBlocks.length; i++) {
|
|
2705
|
+
const nodes = nextOrderedBlocks[i].nodes;
|
|
2706
|
+
for (let j = 0; j < nodes.length; j++) {
|
|
2707
|
+
nextNodes.push(nodes[j]);
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
nextNodes.push(container.endMarker);
|
|
2711
|
+
container.currentNodes = nextNodes;
|
|
2712
|
+
container.nextNodes = prevNodes;
|
|
2462
2713
|
}
|
|
2463
2714
|
container.blocks = newBlocks;
|
|
2464
2715
|
container.nextBlocks = oldBlocks;
|
|
@@ -3053,7 +3304,9 @@ function bindEvent(el, eventName, handler, options2) {
|
|
|
3053
3304
|
const fn = resolveHandler();
|
|
3054
3305
|
callEventHandler(fn, args[0], el);
|
|
3055
3306
|
} catch (err) {
|
|
3056
|
-
handleError(err, { source: "event", eventName }, rootRef)
|
|
3307
|
+
if (!handleError(err, { source: "event", eventName }, rootRef)) {
|
|
3308
|
+
throw err;
|
|
3309
|
+
}
|
|
3057
3310
|
}
|
|
3058
3311
|
};
|
|
3059
3312
|
return () => {
|