essor 0.0.17-beta.7 → 0.0.18-beta.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.
@@ -1,12 +1,12 @@
1
1
  /**
2
- * essor v0.0.17-beta.7
3
- * build time 2026-06-27T06:24:37.846Z
2
+ * essor v0.0.18-beta.1
3
+ * build time 2026-07-08T09:46:23.036Z
4
4
  * (c) 2023-Present jiangxd <jiangxd2016@gmail.com>
5
5
  * @license MIT
6
6
  **/
7
7
 
8
8
  // src/version.ts
9
- var __version = "0.0.17-beta.7";
9
+ var __version = "0.0.18-beta.1";
10
10
 
11
11
  // ../shared/dist/shared.dev.js
12
12
  var isObject = (val) => val !== null && typeof val === "object";
@@ -20,6 +20,9 @@ function isString(val) {
20
20
  function isNumber(val) {
21
21
  return typeof val === "number";
22
22
  }
23
+ function isNull(val) {
24
+ return val === null;
25
+ }
23
26
  function isSymbol(val) {
24
27
  return typeof val === "symbol";
25
28
  }
@@ -36,7 +39,11 @@ function isMap(val) {
36
39
  return _toString.call(val) === "[object Map]";
37
40
  }
38
41
  var isFunction = (val) => typeof val === "function";
39
- var isPlainObject = (val) => _toString.call(val) === "[object Object]";
42
+ var isPlainObject = (val) => {
43
+ if (_toString.call(val) !== "[object Object]") return false;
44
+ const proto = Object.getPrototypeOf(val);
45
+ return proto === null || proto === Object.prototype;
46
+ };
40
47
  function isStringNumber(val) {
41
48
  if (!isString(val) || val === "") {
42
49
  return false;
@@ -46,6 +53,12 @@ function isStringNumber(val) {
46
53
  function isUndefined(val) {
47
54
  return typeof val === "undefined";
48
55
  }
56
+ function isDate(val) {
57
+ return _toString.call(val) === "[object Date]";
58
+ }
59
+ function isRegExp(val) {
60
+ return _toString.call(val) === "[object RegExp]";
61
+ }
49
62
  var _toString = Object.prototype.toString;
50
63
  var hasOwnProperty = Object.prototype.hasOwnProperty;
51
64
  var hasOwn = (val, key) => hasOwnProperty.call(val, key);
@@ -432,6 +445,17 @@ function isValidLink(checkLink, sub) {
432
445
  }
433
446
  var targetMap = /* @__PURE__ */ new WeakMap();
434
447
  var triggerVersion = 0;
448
+ var triggerEffects = [];
449
+ var triggerDepth = 0;
450
+ function startTriggerEffects() {
451
+ const effects = triggerDepth === 0 ? triggerEffects : [];
452
+ triggerDepth++;
453
+ return effects;
454
+ }
455
+ function endTriggerEffects(effects) {
456
+ effects.length = 0;
457
+ triggerDepth--;
458
+ }
435
459
  function collectTriggeredEffects(dep, effects, version) {
436
460
  if (!dep) {
437
461
  return;
@@ -462,46 +486,127 @@ function track(target, key) {
462
486
  linkReactiveNode(dep, activeSub);
463
487
  }
464
488
  function trigger(target, type, key, newValue) {
465
- var _a52;
489
+ var _a62;
466
490
  const depsMap = targetMap.get(target);
467
491
  if (!depsMap) {
468
492
  return;
469
493
  }
470
- const effects = [];
494
+ const effects = startTriggerEffects();
471
495
  const version = ++triggerVersion;
472
- if (key !== void 0) {
473
- if (Array.isArray(key)) {
474
- for (const element of key) {
475
- collectTriggeredEffects(depsMap.get(element), effects, version);
496
+ try {
497
+ if (key !== void 0) {
498
+ if (isArray(key)) {
499
+ for (const element of key) {
500
+ collectTriggeredEffects(depsMap.get(element), effects, version);
501
+ }
502
+ } else {
503
+ collectTriggeredEffects(depsMap.get(key), effects, version);
476
504
  }
477
- } else {
478
- collectTriggeredEffects(depsMap.get(key), effects, version);
479
505
  }
506
+ if (type === "ADD" || type === "DELETE" || type === "CLEAR") {
507
+ const iterationKey = isArray(target) ? ARRAY_ITERATE_KEY : ITERATE_KEY;
508
+ collectTriggeredEffects(depsMap.get(iterationKey), effects, version);
509
+ }
510
+ for (const effect2 of effects) {
511
+ if (isFunction(effect2.onTrigger)) {
512
+ effect2.onTrigger({
513
+ effect: effect2,
514
+ target,
515
+ type,
516
+ key,
517
+ newValue
518
+ });
519
+ }
520
+ if (effect2.flag & 2) {
521
+ (_a62 = effect2.notify) == null ? void 0 : _a62.call(effect2);
522
+ } else if (effect2.flag & 1) {
523
+ effect2.flag |= 16;
524
+ if (effect2.subLink) {
525
+ propagate(effect2.subLink);
526
+ }
527
+ }
528
+ }
529
+ } finally {
530
+ endTriggerEffects(effects);
480
531
  }
481
- if (type === "ADD" || type === "DELETE" || type === "CLEAR") {
482
- const iterationKey = Array.isArray(target) ? ARRAY_ITERATE_KEY : ITERATE_KEY;
483
- collectTriggeredEffects(depsMap.get(iterationKey), effects, version);
484
- }
485
- for (const effect2 of effects) {
486
- if (isFunction(effect2.onTrigger)) {
487
- effect2.onTrigger({
488
- effect: effect2,
489
- target,
490
- type,
491
- key,
492
- newValue
493
- });
532
+ }
533
+ function trackNode(node) {
534
+ if (!activeSub || isUntracking) return;
535
+ linkReactiveNode(node, activeSub);
536
+ }
537
+ function triggerNode(node) {
538
+ var _a62;
539
+ const link = node.subLink;
540
+ if (!link) return;
541
+ const effects = startTriggerEffects();
542
+ const version = ++triggerVersion;
543
+ try {
544
+ for (let current = link; current; current = current.nextSubLink) {
545
+ const effect2 = current.subNode;
546
+ if (effect2._triggerVersion === version) {
547
+ continue;
548
+ }
549
+ effect2._triggerVersion = version;
550
+ effects.push(effect2);
494
551
  }
495
- if (effect2.flag & 2) {
496
- (_a52 = effect2.notify) == null ? void 0 : _a52.call(effect2);
497
- } else if (effect2.flag & 1) {
498
- effect2.flag |= 16;
499
- if (effect2.subLink) {
500
- propagate(effect2.subLink);
552
+ for (const effect2 of effects) {
553
+ if (effect2.flag & 2) {
554
+ (_a62 = effect2.notify) == null ? void 0 : _a62.call(effect2);
555
+ } else if (effect2.flag & 1) {
556
+ effect2.flag |= 16;
557
+ if (effect2.subLink) {
558
+ propagate(effect2.subLink);
559
+ }
501
560
  }
502
561
  }
562
+ } finally {
563
+ endTriggerEffects(effects);
503
564
  }
504
565
  }
566
+ var ReactiveProperty = class {
567
+ constructor(_target, _key) {
568
+ this._target = _target;
569
+ this._key = _key;
570
+ this.flag = 1;
571
+ }
572
+ /**
573
+ * Read the property value and track the dependency.
574
+ *
575
+ * Uses trackNode(this) — bypasses targetMap/Dep. The ReactiveProperty itself
576
+ * IS the depNode, so linkReactiveNode connects the active subscriber directly
577
+ * to this node's subLink chain.
578
+ *
579
+ * Nested proxy wrapping and signal auto-unwrapping are handled by the caller
580
+ * (the reactive proxy get trap), keeping this method self-contained and free
581
+ * of a circular dependency on the rest of reactive.ts.
582
+ */
583
+ getValue() {
584
+ trackNode(this);
585
+ return this._target[this._key];
586
+ }
587
+ /**
588
+ * Update the property value and notify subscribers.
589
+ *
590
+ * Uses triggerNode(this) — directly walks the subLink chain, bypassing
591
+ * targetMap + collectTriggeredEffects.
592
+ *
593
+ * @param rawValue - The new (already unrawed) value.
594
+ * @param oldValue - The previous value, read BEFORE Reflect.set.
595
+ */
596
+ setValue(rawValue, oldValue) {
597
+ if (Object.is(oldValue, rawValue)) {
598
+ return;
599
+ }
600
+ triggerNode(this);
601
+ }
602
+ /**
603
+ * Invalidate this property (called on delete).
604
+ * Notifies subscribers that the value is gone.
605
+ */
606
+ invalidate() {
607
+ triggerNode(this);
608
+ }
609
+ };
505
610
  var reactiveCaches = /* @__PURE__ */ new WeakMap();
506
611
  var shallowReactiveCaches = /* @__PURE__ */ new WeakMap();
507
612
  function toRaw(value) {
@@ -563,7 +668,7 @@ function createArrayInstrumentations() {
563
668
  const isShallowMode = isShallow(this);
564
669
  track(arr, ARRAY_ITERATE_KEY);
565
670
  const res = Array.prototype[key].apply(arr, args);
566
- if (!Array.isArray(res)) {
671
+ if (!isArray(res)) {
567
672
  return res;
568
673
  }
569
674
  return res.map((item) => isObject(item) ? reactiveImpl(item, isShallowMode) : item);
@@ -598,7 +703,7 @@ function createArrayInstrumentations() {
598
703
  if (done) {
599
704
  return { value, done };
600
705
  }
601
- if (Array.isArray(value)) {
706
+ if (isArray(value)) {
602
707
  return {
603
708
  value: value.map((v) => isObject(v) ? reactiveImpl(v, isShallowMode) : v),
604
709
  done
@@ -660,6 +765,32 @@ var arrayHandlers = (shallow) => ({
660
765
  }
661
766
  }
662
767
  return result;
768
+ },
769
+ has: (target, key) => {
770
+ const result = Reflect.has(target, key);
771
+ if (typeof key !== "symbol") {
772
+ if (isStringNumber(key)) {
773
+ track(target, key);
774
+ }
775
+ track(target, ARRAY_KEY);
776
+ }
777
+ return result;
778
+ },
779
+ deleteProperty: (target, key) => {
780
+ const hadKey = hasOwn(target, key);
781
+ const result = Reflect.deleteProperty(target, key);
782
+ if (hadKey && result) {
783
+ if (isStringNumber(key)) {
784
+ trigger(target, TriggerOpTypes.DELETE, [key, ARRAY_ITERATE_KEY, ARRAY_KEY]);
785
+ } else {
786
+ trigger(target, TriggerOpTypes.DELETE, key);
787
+ }
788
+ }
789
+ return result;
790
+ },
791
+ ownKeys: (target) => {
792
+ track(target, ARRAY_ITERATE_KEY);
793
+ return Reflect.ownKeys(target);
663
794
  }
664
795
  });
665
796
  var shallowArrayHandlers = arrayHandlers(true);
@@ -826,7 +957,7 @@ var collectionInstrumentations = {
826
957
  if (isShallowMode) {
827
958
  return { value, done };
828
959
  }
829
- if (Array.isArray(value)) {
960
+ if (isArray(value)) {
830
961
  return {
831
962
  value: value.map((v) => isObject(v) ? reactiveImpl(v) : v),
832
963
  done
@@ -1017,9 +1148,46 @@ var weakInstrumentations = {
1017
1148
  return result;
1018
1149
  }
1019
1150
  };
1151
+ var targetPropertyMaps = /* @__PURE__ */ new WeakMap();
1152
+ function getTargetDepSize(target, key) {
1153
+ var _a62, _b2;
1154
+ const rawTarget = (_a62 = target[
1155
+ "_RAW"
1156
+ /* RAW */
1157
+ ]) != null ? _a62 : target;
1158
+ const prop = (_b2 = targetPropertyMaps.get(rawTarget)) == null ? void 0 : _b2.get(key);
1159
+ if (!(prop == null ? void 0 : prop.subLink)) return 0;
1160
+ let size = 0;
1161
+ for (let link = prop.subLink; link; link = link.nextSubLink) size++;
1162
+ return size;
1163
+ }
1164
+ function getPropertyMap(target) {
1165
+ let map = targetPropertyMaps.get(target);
1166
+ if (!map) {
1167
+ map = /* @__PURE__ */ new Map();
1168
+ targetPropertyMaps.set(target, map);
1169
+ }
1170
+ return map;
1171
+ }
1172
+ function trackProperty(target, key) {
1173
+ if (!activeSub) {
1174
+ return target[key];
1175
+ }
1176
+ const pm = getPropertyMap(target);
1177
+ let prop = pm.get(key);
1178
+ if (!prop) {
1179
+ prop = new ReactiveProperty(target, key);
1180
+ pm.set(key, prop);
1181
+ }
1182
+ return prop.getValue();
1183
+ }
1020
1184
  var objectHandlers = (shallow) => ({
1021
1185
  /**
1022
1186
  * Reads an object property, unwraps signals, and tracks the access.
1187
+ *
1188
+ * Own properties use the per-property signal fast path (trackNode),
1189
+ * which bypasses the targetMap → Map → Dep indirection.
1190
+ * Prototype-chain properties fall back to the standard track() path.
1023
1191
  */
1024
1192
  get(target, key, receiver) {
1025
1193
  if (key === "_RAW") {
@@ -1031,6 +1199,14 @@ var objectHandlers = (shallow) => ({
1031
1199
  if (key === "_IS_SHALLOW") {
1032
1200
  return shallow;
1033
1201
  }
1202
+ if (activeSub && hasOwn(target, key)) {
1203
+ const result = trackProperty(target, key);
1204
+ const unwrapped = isSignal(result) ? result.value : result;
1205
+ if (isObject(unwrapped) && !shallow) {
1206
+ return reactiveImpl(unwrapped);
1207
+ }
1208
+ return unwrapped;
1209
+ }
1034
1210
  const value = Reflect.get(target, key, receiver);
1035
1211
  const valueUnwrapped = isSignal(value) ? value.value : value;
1036
1212
  track(target, key);
@@ -1044,6 +1220,14 @@ var objectHandlers = (shallow) => ({
1044
1220
  const oldValue = Reflect.get(target, key, receiver);
1045
1221
  const rawValue = toRaw(value);
1046
1222
  const result = Reflect.set(target, key, rawValue, receiver);
1223
+ if (hadKey) {
1224
+ const pm = targetPropertyMaps.get(target);
1225
+ const prop = pm == null ? void 0 : pm.get(key);
1226
+ if (prop) {
1227
+ prop.setValue(rawValue, oldValue);
1228
+ return result;
1229
+ }
1230
+ }
1047
1231
  if (hasStoredValueChanged(rawValue, oldValue)) {
1048
1232
  trigger(target, hadKey ? TriggerOpTypes.SET : TriggerOpTypes.ADD, key, rawValue);
1049
1233
  }
@@ -1053,6 +1237,12 @@ var objectHandlers = (shallow) => ({
1053
1237
  const hadKey = hasOwn(target, key);
1054
1238
  const result = Reflect.deleteProperty(target, key);
1055
1239
  if (hadKey && result) {
1240
+ const pm = targetPropertyMaps.get(target);
1241
+ const prop = pm == null ? void 0 : pm.get(key);
1242
+ if (prop) {
1243
+ pm.delete(key);
1244
+ prop.invalidate();
1245
+ }
1056
1246
  trigger(target, TriggerOpTypes.DELETE, key, void 0);
1057
1247
  }
1058
1248
  return result;
@@ -1295,6 +1485,7 @@ function isSignal(value) {
1295
1485
  }
1296
1486
  var queue = /* @__PURE__ */ new Set();
1297
1487
  var activePreFlushCbs = /* @__PURE__ */ new Set();
1488
+ var activePostFlushCbs = /* @__PURE__ */ new Set();
1298
1489
  var p = Promise.resolve();
1299
1490
  var isFlushPending = false;
1300
1491
  var RECURSION_LIMIT = 100;
@@ -1315,6 +1506,10 @@ function queuePreFlushCb(cb) {
1315
1506
  activePreFlushCbs.add(cb);
1316
1507
  queueFlush();
1317
1508
  }
1509
+ function queuePostFlushJob(cb) {
1510
+ activePostFlushCbs.add(cb);
1511
+ queueFlush();
1512
+ }
1318
1513
  function flushJobs() {
1319
1514
  isFlushPending = false;
1320
1515
  flushPreFlushCbs();
@@ -1327,7 +1522,7 @@ function flushJobs() {
1327
1522
  `[Scheduler] Maximum recursive flush count (${RECURSION_LIMIT}) exceeded. This usually means an effect or watch callback is mutating a reactive dependency it also reads, causing an infinite update loop. The remaining queued jobs have been dropped to keep the app responsive.`
1328
1523
  );
1329
1524
  }
1330
- return;
1525
+ break;
1331
1526
  }
1332
1527
  const jobs = [...queue];
1333
1528
  queue.clear();
@@ -1341,6 +1536,7 @@ function flushJobs() {
1341
1536
  }
1342
1537
  }
1343
1538
  }
1539
+ flushPostFlushCbs();
1344
1540
  }
1345
1541
  function flushPreFlushCbs() {
1346
1542
  const callbacks = Array.from(activePreFlushCbs);
@@ -1355,6 +1551,20 @@ function flushPreFlushCbs() {
1355
1551
  }
1356
1552
  }
1357
1553
  }
1554
+ function flushPostFlushCbs() {
1555
+ if (activePostFlushCbs.size === 0) return;
1556
+ const callbacks = Array.from(activePostFlushCbs);
1557
+ activePostFlushCbs.clear();
1558
+ for (const callback of callbacks) {
1559
+ try {
1560
+ callback();
1561
+ } catch (_error) {
1562
+ {
1563
+ error("Error executing post-flush callback:", _error);
1564
+ }
1565
+ }
1566
+ }
1567
+ }
1358
1568
  function createScheduler(effect2, flush) {
1359
1569
  switch (flush) {
1360
1570
  case "sync":
@@ -1405,7 +1615,7 @@ var EffectScope = class {
1405
1615
  constructor(detached = false, parent = void 0) {
1406
1616
  this.detached = detached;
1407
1617
  this.parent = parent;
1408
- this._active = true;
1618
+ this._state = 0;
1409
1619
  this.effects = /* @__PURE__ */ new Set();
1410
1620
  this.scopes = /* @__PURE__ */ new Set();
1411
1621
  this.cleanups = [];
@@ -1415,36 +1625,46 @@ var EffectScope = class {
1415
1625
  }
1416
1626
  }
1417
1627
  get active() {
1418
- return this._active;
1628
+ return this._state !== 2;
1629
+ }
1630
+ /** Whether the scope is paused. */
1631
+ get isPaused() {
1632
+ return this._state === 1;
1633
+ }
1634
+ /** Whether the scope has been stopped / disposed. */
1635
+ get isDisposed() {
1636
+ return this._state === 2;
1419
1637
  }
1420
1638
  pause() {
1421
- var _a52;
1422
- if (!this._active) {
1639
+ var _a62;
1640
+ if (this._state !== 0) {
1423
1641
  return;
1424
1642
  }
1643
+ this._state = 1;
1425
1644
  for (const scope of this.scopes) {
1426
1645
  scope.pause();
1427
1646
  }
1428
1647
  for (const effect2 of this.effects) {
1429
- (_a52 = effect2.pause) == null ? void 0 : _a52.call(effect2);
1648
+ (_a62 = effect2.pause) == null ? void 0 : _a62.call(effect2);
1430
1649
  }
1431
1650
  }
1432
1651
  resume() {
1433
- var _a52;
1434
- if (!this._active) {
1652
+ var _a62;
1653
+ if (this._state !== 1) {
1435
1654
  return;
1436
1655
  }
1656
+ this._state = 0;
1437
1657
  for (const scope of this.scopes) {
1438
1658
  scope.resume();
1439
1659
  }
1440
1660
  for (const effect2 of this.effects) {
1441
- (_a52 = effect2.resume) == null ? void 0 : _a52.call(effect2);
1661
+ (_a62 = effect2.resume) == null ? void 0 : _a62.call(effect2);
1442
1662
  }
1443
1663
  }
1444
1664
  run(fn) {
1445
- if (!this._active) {
1665
+ if (this._state === 2) {
1446
1666
  {
1447
- warn("cannot run an inactive effect scope.");
1667
+ warn("cannot run a disposed effect scope.");
1448
1668
  }
1449
1669
  return;
1450
1670
  }
@@ -1457,27 +1677,42 @@ var EffectScope = class {
1457
1677
  }
1458
1678
  }
1459
1679
  stop(fromParent = false) {
1460
- if (!this._active) {
1680
+ if (this._state === 2) {
1461
1681
  return;
1462
1682
  }
1463
- this._active = false;
1464
- for (const scope of this.scopes) {
1465
- scope.stop(true);
1466
- }
1467
- this.scopes.clear();
1468
- const effects = Array.from(this.effects);
1469
- this.effects.clear();
1470
- for (const effect2 of effects) {
1471
- effect2.stop();
1472
- }
1473
- for (let i = 0; i < this.cleanups.length; i++) {
1474
- this.cleanups[i]();
1475
- }
1476
- this.cleanups.length = 0;
1477
- if (!fromParent && this.parent) {
1478
- this.parent.scopes.delete(this);
1683
+ this._state = 2;
1684
+ try {
1685
+ for (const scope of this.scopes) {
1686
+ try {
1687
+ scope.stop(true);
1688
+ } catch (error_) {
1689
+ if (true) error("[EffectScope] child scope disposal threw:", error_);
1690
+ }
1691
+ }
1692
+ this.scopes.clear();
1693
+ const effects = Array.from(this.effects);
1694
+ this.effects.clear();
1695
+ for (const effect2 of effects) {
1696
+ try {
1697
+ effect2.stop();
1698
+ } catch (error_) {
1699
+ if (true) error("[EffectScope] effect disposal threw:", error_);
1700
+ }
1701
+ }
1702
+ for (let i = 0; i < this.cleanups.length; i++) {
1703
+ try {
1704
+ this.cleanups[i]();
1705
+ } catch (error_) {
1706
+ if (true) error("[EffectScope] cleanup threw:", error_);
1707
+ }
1708
+ }
1709
+ this.cleanups.length = 0;
1710
+ } finally {
1711
+ if (!fromParent && this.parent) {
1712
+ this.parent.scopes.delete(this);
1713
+ }
1714
+ this.parent = void 0;
1479
1715
  }
1480
- this.parent = void 0;
1481
1716
  }
1482
1717
  _record(effect2) {
1483
1718
  this.effects.add(effect2);
@@ -1641,9 +1876,9 @@ var EffectImpl = class {
1641
1876
  const prevSub = startTracking(this);
1642
1877
  try {
1643
1878
  return this.fn();
1644
- } catch (error5) {
1879
+ } catch (error6) {
1645
1880
  this.flag |= 16;
1646
- throw error5;
1881
+ throw error6;
1647
1882
  } finally {
1648
1883
  this.flag &= -513;
1649
1884
  endTracking(this, prevSub);
@@ -1669,13 +1904,13 @@ var EffectImpl = class {
1669
1904
  * @returns {void}
1670
1905
  */
1671
1906
  notify() {
1672
- var _a52, _b2, _c, _d;
1907
+ var _a62, _b2, _c, _d;
1673
1908
  const flags = this.flag;
1674
1909
  if (!this._active || flags & (256 | 512 | 16)) {
1675
1910
  return;
1676
1911
  }
1677
1912
  this.flag = flags | 16;
1678
- if ((_a52 = this.options) == null ? void 0 : _a52.onTrigger) {
1913
+ if ((_a62 = this.options) == null ? void 0 : _a62.onTrigger) {
1679
1914
  this.options.onTrigger({
1680
1915
  effect: this,
1681
1916
  target: {},
@@ -1708,7 +1943,7 @@ var EffectImpl = class {
1708
1943
  * @returns {void}
1709
1944
  */
1710
1945
  stop() {
1711
- var _a52;
1946
+ var _a62;
1712
1947
  if (!this._active) {
1713
1948
  return;
1714
1949
  }
@@ -1738,7 +1973,7 @@ var EffectImpl = class {
1738
1973
  );
1739
1974
  }
1740
1975
  }
1741
- if ((_a52 = this.options) == null ? void 0 : _a52.onStop) {
1976
+ if ((_a62 = this.options) == null ? void 0 : _a62.onStop) {
1742
1977
  this.options.onStop();
1743
1978
  }
1744
1979
  }
@@ -1885,7 +2120,7 @@ var ComputedImpl = class {
1885
2120
  const hadValue = oldValue !== NO_VALUE;
1886
2121
  const prevSub = startTracking(this);
1887
2122
  try {
1888
- const newValue = this.getter();
2123
+ const newValue = this.getter(hadValue ? oldValue : void 0);
1889
2124
  const flags = this.flag;
1890
2125
  const subs = this.subLink;
1891
2126
  const clearMask = ~(16 | 32);
@@ -2008,13 +2243,13 @@ function cloneInitialState(value, seen = /* @__PURE__ */ new WeakMap()) {
2008
2243
  if (seen.has(value)) {
2009
2244
  return seen.get(value);
2010
2245
  }
2011
- if (value instanceof Date) {
2246
+ if (isDate(value)) {
2012
2247
  return new Date(value.getTime());
2013
2248
  }
2014
- if (value instanceof RegExp) {
2249
+ if (isRegExp(value)) {
2015
2250
  return new RegExp(value.source, value.flags);
2016
2251
  }
2017
- if (value instanceof Map) {
2252
+ if (isMap(value)) {
2018
2253
  const clone2 = /* @__PURE__ */ new Map();
2019
2254
  seen.set(value, clone2);
2020
2255
  value.forEach((mapValue, mapKey) => {
@@ -2022,7 +2257,7 @@ function cloneInitialState(value, seen = /* @__PURE__ */ new WeakMap()) {
2022
2257
  });
2023
2258
  return clone2;
2024
2259
  }
2025
- if (value instanceof Set) {
2260
+ if (isSet(value)) {
2026
2261
  const clone2 = /* @__PURE__ */ new Set();
2027
2262
  seen.set(value, clone2);
2028
2263
  value.forEach((setValue) => {
@@ -2030,7 +2265,7 @@ function cloneInitialState(value, seen = /* @__PURE__ */ new WeakMap()) {
2030
2265
  });
2031
2266
  return clone2;
2032
2267
  }
2033
- if (Array.isArray(value)) {
2268
+ if (isArray(value)) {
2034
2269
  const clone2 = [];
2035
2270
  seen.set(value, clone2);
2036
2271
  value.forEach((item, index) => {
@@ -2039,7 +2274,7 @@ function cloneInitialState(value, seen = /* @__PURE__ */ new WeakMap()) {
2039
2274
  return clone2;
2040
2275
  }
2041
2276
  const prototype = Object.getPrototypeOf(value);
2042
- if (prototype !== Object.prototype && prototype !== null) {
2277
+ if (prototype !== Object.prototype && !isNull(prototype)) {
2043
2278
  return value;
2044
2279
  }
2045
2280
  const clone = Object.create(prototype);
@@ -2070,11 +2305,58 @@ function createOptionsStore(options) {
2070
2305
  };
2071
2306
  }
2072
2307
  set.add(callback);
2073
- return () => set.delete(callback);
2308
+ const unsubscribe = () => set.delete(callback);
2309
+ onScopeDispose(
2310
+ unsubscribe,
2311
+ /* failSilently */
2312
+ true
2313
+ );
2314
+ return unsubscribe;
2315
+ };
2316
+ let activeTransaction = null;
2317
+ const flushTransaction = (transaction) => {
2318
+ if (transaction.depth === 0 && transaction.pending === 0 && !transaction.notified) {
2319
+ transaction.notified = true;
2320
+ notify(reactiveState);
2321
+ }
2074
2322
  };
2075
2323
  const commit = (mutate) => {
2076
- batch(mutate);
2077
- notify(reactiveState);
2324
+ const transaction = activeTransaction != null ? activeTransaction : {
2325
+ depth: 0,
2326
+ pending: 0,
2327
+ notified: false
2328
+ };
2329
+ const previousTransaction = activeTransaction;
2330
+ transaction.depth++;
2331
+ let result;
2332
+ try {
2333
+ activeTransaction = transaction;
2334
+ result = batch(mutate);
2335
+ } catch (error6) {
2336
+ transaction.depth--;
2337
+ activeTransaction = previousTransaction;
2338
+ throw error6;
2339
+ }
2340
+ activeTransaction = previousTransaction;
2341
+ if (isPromise(result)) {
2342
+ transaction.pending++;
2343
+ transaction.depth--;
2344
+ return result.then(
2345
+ (value) => {
2346
+ transaction.pending--;
2347
+ flushTransaction(transaction);
2348
+ return value;
2349
+ },
2350
+ (error6) => {
2351
+ transaction.pending--;
2352
+ flushTransaction(transaction);
2353
+ throw error6;
2354
+ }
2355
+ );
2356
+ }
2357
+ transaction.depth--;
2358
+ flushTransaction(transaction);
2359
+ return result;
2078
2360
  };
2079
2361
  const defaultActions = {
2080
2362
  $patch(payload) {
@@ -2097,7 +2379,15 @@ function createOptionsStore(options) {
2097
2379
  actionCallbacks.delete(callback);
2098
2380
  },
2099
2381
  $reset() {
2100
- commit(() => Object.assign(reactiveState, initState));
2382
+ commit(() => {
2383
+ const fresh = cloneInitialState(initState);
2384
+ for (const key of Object.keys(reactiveState)) {
2385
+ if (!Object.prototype.hasOwnProperty.call(fresh, key)) {
2386
+ delete reactiveState[key];
2387
+ }
2388
+ }
2389
+ Object.assign(reactiveState, fresh);
2390
+ });
2101
2391
  }
2102
2392
  };
2103
2393
  const store = {};
@@ -2115,7 +2405,7 @@ function createOptionsStore(options) {
2115
2405
  value: reactiveState,
2116
2406
  enumerable: true,
2117
2407
  configurable: true,
2118
- writable: true
2408
+ writable: false
2119
2409
  });
2120
2410
  Object.assign(store, defaultActions);
2121
2411
  if (getters) {
@@ -2135,9 +2425,7 @@ function createOptionsStore(options) {
2135
2425
  const action = actions[key];
2136
2426
  if (action) {
2137
2427
  store[key] = (...args) => {
2138
- const result = action.apply(store, args);
2139
- actionCallbacks.forEach((callback) => callback(reactiveState));
2140
- return result;
2428
+ return commit(() => action.apply(store, args));
2141
2429
  };
2142
2430
  }
2143
2431
  }
@@ -2209,6 +2497,12 @@ var RefImpl = class extends (_b = SignalImpl, _a4 = "_IS_REF", _b) {
2209
2497
  if (sub) {
2210
2498
  linkReactiveNode(this, sub);
2211
2499
  }
2500
+ if (this.flag & 16 && this.shouldUpdate()) {
2501
+ const subs = this.subLink;
2502
+ if (subs) {
2503
+ shallowPropagate(subs);
2504
+ }
2505
+ }
2212
2506
  return this._value;
2213
2507
  }
2214
2508
  /**
@@ -2224,6 +2518,7 @@ var RefImpl = class extends (_b = SignalImpl, _a4 = "_IS_REF", _b) {
2224
2518
  newValue = newValue.value;
2225
2519
  }
2226
2520
  if (hasChanged(this._value, newValue)) {
2521
+ this._oldValue = this._rawValue;
2227
2522
  this._rawValue = newValue;
2228
2523
  this._value = newValue;
2229
2524
  this.flag |= 16;
@@ -2248,6 +2543,45 @@ function isRef(value) {
2248
2543
  /* IS_REF */
2249
2544
  ];
2250
2545
  }
2546
+ var _a5;
2547
+ _a5 = "_IS_COMPUTED";
2548
+ var ObjectPropertyRef = class {
2549
+ constructor(obj, key, defaultValue) {
2550
+ this.obj = obj;
2551
+ this.key = key;
2552
+ this.defaultValue = defaultValue;
2553
+ this[_a5] = true;
2554
+ }
2555
+ get value() {
2556
+ const value = this.obj[this.key];
2557
+ return value !== void 0 ? value : this.defaultValue;
2558
+ }
2559
+ set value(value) {
2560
+ this.obj[this.key] = value;
2561
+ }
2562
+ peek() {
2563
+ return untrack(() => this.value);
2564
+ }
2565
+ };
2566
+ function unref(value) {
2567
+ if (isSignal(value) || isRef(value) || isComputed(value)) {
2568
+ return value.value;
2569
+ }
2570
+ if (isFunction(value)) {
2571
+ return value();
2572
+ }
2573
+ return value;
2574
+ }
2575
+ function toRef(obj, key, defaultValue) {
2576
+ return new ObjectPropertyRef(obj, key, defaultValue);
2577
+ }
2578
+ function toRefs(obj) {
2579
+ const result = {};
2580
+ for (const key of Object.keys(obj)) {
2581
+ result[key] = toRef(obj, key);
2582
+ }
2583
+ return result;
2584
+ }
2251
2585
  var INITIAL_WATCHER_VALUE = {};
2252
2586
  var _traverseSeen = /* @__PURE__ */ new Set();
2253
2587
  var _traverseBusy = false;
@@ -2258,7 +2592,7 @@ function traverseValue(value, seen) {
2258
2592
  seen.add(value);
2259
2593
  if (isSignal(value) || isComputed(value)) {
2260
2594
  traverseValue(value.value, seen);
2261
- } else if (Array.isArray(value)) {
2595
+ } else if (isArray(value)) {
2262
2596
  for (const element of value) {
2263
2597
  traverseValue(element, seen);
2264
2598
  }
@@ -2308,7 +2642,7 @@ function resolveSingleSource(source) {
2308
2642
  return () => source;
2309
2643
  }
2310
2644
  function resolveSource(source) {
2311
- if (Array.isArray(source)) {
2645
+ if (isArray(source)) {
2312
2646
  const getters = source.map((s) => resolveSingleSource(s));
2313
2647
  return () => getters.map((g) => g());
2314
2648
  }
@@ -2319,7 +2653,7 @@ function watch(source, callback, options = {}) {
2319
2653
  let oldValue = INITIAL_WATCHER_VALUE;
2320
2654
  let lastValue;
2321
2655
  let active = true;
2322
- const isSingleReactive = !Array.isArray(source) && isReactive(source);
2656
+ const isSingleReactive = !isArray(source) && isReactive(source);
2323
2657
  const needTraverse = deep && !isSingleReactive;
2324
2658
  const getter = resolveSource(source);
2325
2659
  let cleanup;
@@ -2328,8 +2662,8 @@ function watch(source, callback, options = {}) {
2328
2662
  cleanup = void 0;
2329
2663
  try {
2330
2664
  fn();
2331
- } catch (error5) {
2332
- warn("[watch] cleanup handler threw:", error5);
2665
+ } catch (error6) {
2666
+ warn("[watch] cleanup handler threw:", error6);
2333
2667
  }
2334
2668
  };
2335
2669
  };
@@ -2462,12 +2796,12 @@ function runWithScope(scope, fn) {
2462
2796
  }
2463
2797
  }
2464
2798
  function disposeScope(scope) {
2465
- var _a6;
2799
+ var _a7;
2466
2800
  if (!scope || scope.isDestroyed) {
2467
2801
  return;
2468
2802
  }
2469
2803
  scope.isDestroyed = true;
2470
- if ((_a6 = scope.parent) == null ? void 0 : _a6.children) {
2804
+ if ((_a7 = scope.parent) == null ? void 0 : _a7.children) {
2471
2805
  scope.parent.children.delete(scope);
2472
2806
  }
2473
2807
  scope.parent = null;
@@ -2539,6 +2873,24 @@ var FOR_COMPONENT = /* @__PURE__ */ Symbol("For Component");
2539
2873
  var TRANSITION_COMPONENT = /* @__PURE__ */ Symbol("Transition Component");
2540
2874
  var TRANSITION_GROUP_COMPONENT = /* @__PURE__ */ Symbol("TransitionGroup Component");
2541
2875
  var DANGEROUS_DATA_MIME_RE = /^data:\s*(?:text\/html|text\/xml|application\/xhtml\+xml|image\/svg\+xml|application\/xml)/;
2876
+ var BOOLEAN_PROPERTY_ALIASES = {
2877
+ allowfullscreen: "allowFullscreen",
2878
+ formnovalidate: "formNoValidate",
2879
+ ismap: "isMap",
2880
+ nomodule: "noModule",
2881
+ novalidate: "noValidate",
2882
+ readonly: "readOnly"
2883
+ };
2884
+ function syncBooleanProperty(el, key, value) {
2885
+ var _a22;
2886
+ if (el.namespaceURI === SVG_NAMESPACE) return;
2887
+ const prop = (_a22 = BOOLEAN_PROPERTY_ALIASES[key.toLowerCase()]) != null ? _a22 : key;
2888
+ if (!(prop in el) || typeof el[prop] !== "boolean") return;
2889
+ try {
2890
+ el[prop] = value;
2891
+ } catch (e) {
2892
+ }
2893
+ }
2542
2894
  function isUnsafeUrl(value) {
2543
2895
  const v = value.replaceAll(/[\u0000-\u0020]+/g, "").toLowerCase();
2544
2896
  if (startsWith(v, "javascript:") || startsWith(v, "vbscript:")) {
@@ -2615,14 +2967,19 @@ function patchAttr(el, key, prev, next2) {
2615
2967
  } else {
2616
2968
  el.removeAttribute(key);
2617
2969
  }
2970
+ if (isBoolean || lowerKey === "indeterminate") {
2971
+ syncBooleanProperty(el, key, false);
2972
+ }
2618
2973
  return;
2619
2974
  }
2620
2975
  if (isBoolean) {
2621
- if (includeBooleanAttr(next2)) {
2976
+ const included = includeBooleanAttr(next2);
2977
+ if (included) {
2622
2978
  el.setAttribute(key, "");
2623
2979
  } else {
2624
2980
  el.removeAttribute(key);
2625
2981
  }
2982
+ syncBooleanProperty(el, key, included);
2626
2983
  return;
2627
2984
  }
2628
2985
  const attrValue = isSymbol(next2) ? String(next2) : next2;
@@ -2849,19 +3206,31 @@ function endHydration() {
2849
3206
  _teleportTargetStarts.clear();
2850
3207
  }
2851
3208
  function claimHydratedNodes(parent, expected, before) {
2852
- var _a22, _b2;
3209
+ var _a22, _b2, _c;
2853
3210
  if (!_isHydrating || before && before.parentNode !== parent) return null;
2854
3211
  if (expected.length === 0) return [];
2855
3212
  const claimed = new Array(expected.length);
2856
3213
  let cursor = before ? before.previousSibling : parent.lastChild;
2857
3214
  for (let i = expected.length - 1; i >= 0; i--) {
2858
- if (!cursor) return null;
2859
3215
  const expectedNode = expected[i];
2860
3216
  const expectedType = expectedNode.nodeType;
2861
3217
  if (expectedType === Node.TEXT_NODE) {
2862
3218
  const expectedText = (_a22 = expectedNode.textContent) != null ? _a22 : "";
2863
- if (!expectedText || cursor.nodeType !== Node.TEXT_NODE) return null;
2864
- const existingText = (_b2 = cursor.textContent) != null ? _b2 : "";
3219
+ if (expectedText === "") {
3220
+ if ((cursor == null ? void 0 : cursor.nodeType) === Node.TEXT_NODE && ((_b2 = cursor.textContent) != null ? _b2 : "") === "") {
3221
+ claimed[i] = cursor;
3222
+ cursor = cursor.previousSibling;
3223
+ } else {
3224
+ const emptyNode = document.createTextNode("");
3225
+ const anchor = i + 1 < expected.length ? claimed[i + 1] : before != null ? before : null;
3226
+ parent.insertBefore(emptyNode, anchor);
3227
+ claimed[i] = emptyNode;
3228
+ }
3229
+ continue;
3230
+ }
3231
+ if (!cursor) return null;
3232
+ if (cursor.nodeType !== Node.TEXT_NODE) return null;
3233
+ const existingText = (_c = cursor.textContent) != null ? _c : "";
2865
3234
  if (existingText === expectedText) {
2866
3235
  claimed[i] = cursor;
2867
3236
  cursor = cursor.previousSibling;
@@ -2877,6 +3246,7 @@ function claimHydratedNodes(parent, expected, before) {
2877
3246
  cursor = prefixNode;
2878
3247
  continue;
2879
3248
  }
3249
+ if (!cursor) return null;
2880
3250
  if (cursor.nodeType !== expectedType) return null;
2881
3251
  if (expectedType === Node.ELEMENT_NODE) {
2882
3252
  if (cursor.tagName !== expectedNode.tagName) return null;
@@ -3180,6 +3550,8 @@ function insert(parent, nodeFactory, before) {
3180
3550
  const effectRunner = effect(() => {
3181
3551
  const executeUpdate = () => {
3182
3552
  const rawNodes = isFunction(nodeFactory) ? nodeFactory() : nodeFactory;
3553
+ const rawType = typeof rawNodes;
3554
+ const canPatchText = rawNodes == null || rawType === "string" || rawType === "number" || rawType === "boolean" || rawType === "symbol";
3183
3555
  const nodes = resolveNodes(rawNodes);
3184
3556
  if (isFirstRun && isHydrating() && nodes.every((node) => node instanceof Node && node.parentNode === parent)) {
3185
3557
  renderedNodes = nodes;
@@ -3194,6 +3566,13 @@ function insert(parent, nodeFactory, before) {
3194
3566
  return;
3195
3567
  }
3196
3568
  }
3569
+ if (canPatchText && renderedNodes.length === 1 && nodes.length === 1 && renderedNodes[0].nodeType === Node.TEXT_NODE && nodes[0].nodeType === Node.TEXT_NODE) {
3570
+ const current = renderedNodes[0];
3571
+ const nextText = nodes[0].textContent;
3572
+ if (current.textContent !== nextText) current.textContent = nextText;
3573
+ isFirstRun = false;
3574
+ return;
3575
+ }
3197
3576
  renderedNodes = reconcileArrays(parent, renderedNodes, nodes, before);
3198
3577
  isFirstRun = false;
3199
3578
  };
@@ -3238,7 +3617,7 @@ function addEvent(el, event, handler, options) {
3238
3617
  const selector = options.delegate;
3239
3618
  const wrappedHandler = (e) => {
3240
3619
  const target = e.target;
3241
- if (target.matches(selector) || target.closest(selector)) {
3620
+ if (target.closest(selector)) {
3242
3621
  handler.call(el, e);
3243
3622
  }
3244
3623
  };
@@ -3352,13 +3731,13 @@ function readDescriptorValue(source, key) {
3352
3731
  const descriptor = Object.getOwnPropertyDescriptor(source, key);
3353
3732
  return descriptor.get ? descriptor.get.call(source) : descriptor.value;
3354
3733
  }
3355
- var _a5;
3356
- _a5 = "normal";
3734
+ var _a6;
3735
+ _a6 = "normal";
3357
3736
  var Component = class {
3358
3737
  constructor(component, props = {}) {
3359
3738
  this.component = component;
3360
3739
  this.props = props;
3361
- this[_a5] = true;
3740
+ this[_a6] = true;
3362
3741
  this.scope = null;
3363
3742
  this.state = 0;
3364
3743
  this.beforeNode = void 0;
@@ -3469,28 +3848,34 @@ var Component = class {
3469
3848
  */
3470
3849
  syncSpecialProps(props) {
3471
3850
  if (!props) return;
3472
- const root = this.firstChild;
3473
- if (!root || !(root instanceof Element)) return;
3851
+ const roots = this.getRootElements();
3852
+ if (roots.length === 0) return;
3853
+ const refRoot = roots[0];
3474
3854
  this.releaseSpecialProps();
3475
3855
  for (const key of Reflect.ownKeys(props)) {
3476
3856
  if (!isString(key)) continue;
3477
3857
  if (key === REF_KEY) {
3478
3858
  const value = readDescriptorValue(props, key);
3479
- this.rootRefCleanup = this.bindRootRef(value, root);
3859
+ this.rootRefCleanup = this.bindRootRef(value, refRoot);
3480
3860
  continue;
3481
3861
  }
3482
3862
  if (isOn(key)) {
3483
3863
  const value = readDescriptorValue(props, key);
3484
3864
  if (!isFunction(value)) continue;
3485
3865
  const eventName = key.slice(2).toLowerCase();
3486
- this.bindRootEvent(
3487
- root,
3488
- eventName,
3489
- value
3490
- );
3866
+ for (const root of roots) {
3867
+ this.bindRootEvent(root, eventName, value);
3868
+ }
3491
3869
  }
3492
3870
  }
3493
3871
  }
3872
+ getRootElements() {
3873
+ const roots = [];
3874
+ for (const node of this.renderedNodes) {
3875
+ if (node instanceof Element) roots.push(node);
3876
+ }
3877
+ return roots;
3878
+ }
3494
3879
  bindRootEvent(target, eventName, handler) {
3495
3880
  const slot = `_$${eventName}`;
3496
3881
  const prev = target[slot];
@@ -3699,7 +4084,9 @@ function eventHandler(e) {
3699
4084
  return true;
3700
4085
  };
3701
4086
  const walkUpTree = () => {
3702
- while (handleNode() && (node = node._$host || node.parentNode || node.host)) ;
4087
+ while (handleNode() && (node = node._$host || node.parentNode || node.host)) {
4088
+ if (node === oriCurrentTarget) break;
4089
+ }
3703
4090
  };
3704
4091
  Object.defineProperty(e, "currentTarget", {
3705
4092
  configurable: true,
@@ -3710,23 +4097,26 @@ function eventHandler(e) {
3710
4097
  return node || document;
3711
4098
  }
3712
4099
  });
3713
- if (e.composedPath) {
3714
- const path = e.composedPath();
3715
- reTargetEvent(e, path[0]);
3716
- for (let i = 0; i < path.length - 2; i++) {
3717
- node = path[i];
3718
- if (!handleNode()) break;
3719
- if (node._$host) {
3720
- node = node._$host;
3721
- walkUpTree();
3722
- break;
3723
- }
3724
- if (node.parentNode === oriCurrentTarget) {
3725
- break;
4100
+ try {
4101
+ if (e.composedPath) {
4102
+ const path = e.composedPath();
4103
+ reTargetEvent(e, path[0]);
4104
+ for (let i = 0; i < path.length - 2; i++) {
4105
+ node = path[i];
4106
+ if (!handleNode()) break;
4107
+ if (node._$host) {
4108
+ node = node._$host;
4109
+ walkUpTree();
4110
+ break;
4111
+ }
4112
+ if (node.parentNode === oriCurrentTarget) {
4113
+ break;
4114
+ }
3726
4115
  }
3727
- }
3728
- } else walkUpTree();
3729
- reTargetEvent(e, oriTarget);
4116
+ } else walkUpTree();
4117
+ } finally {
4118
+ reTargetEvent(e, oriTarget);
4119
+ }
3730
4120
  }
3731
4121
  var $EVENTS = /* @__PURE__ */ Symbol("_$EVENTS");
3732
4122
  function delegateEvents(eventNames, document2 = globalThis.document) {
@@ -3762,6 +4152,7 @@ var EMPTY_FILES = (() => {
3762
4152
  if (typeof DataTransfer !== "undefined") return new DataTransfer().files;
3763
4153
  return [];
3764
4154
  })();
4155
+ var checkboxArraySnapshots = /* @__PURE__ */ new WeakMap();
3765
4156
  function writeValue(el, v) {
3766
4157
  const target = el;
3767
4158
  const next2 = v == null ? "" : String(v);
@@ -3878,11 +4269,16 @@ function bindElement(node, prop, getter, setter, modifiers = {}) {
3878
4269
  const getModel = isFunction(getter) ? getter : () => getter;
3879
4270
  const cast = shouldCast ? (v) => applyModifiers(v, trim, toNum) : IDENTITY;
3880
4271
  const computeNext = checkboxArray ? (raw) => {
4272
+ var _a22;
3881
4273
  const current = getModel();
3882
- if (!isArray(current)) return cast(raw);
4274
+ if (!isArray(current)) {
4275
+ return cast(raw);
4276
+ }
3883
4277
  const own = node.value;
3884
- const next2 = current.filter((item) => String(item) !== own);
4278
+ const source = (_a22 = checkboxArraySnapshots.get(current)) != null ? _a22 : current;
4279
+ const next2 = source.filter((item) => String(item) !== own);
3885
4280
  if (raw) next2.push(own);
4281
+ checkboxArraySnapshots.set(current, next2);
3886
4282
  return next2;
3887
4283
  } : cast;
3888
4284
  let composing = false;
@@ -3909,6 +4305,9 @@ function bindElement(node, prop, getter, setter, modifiers = {}) {
3909
4305
  }
3910
4306
  const runner = effect(() => {
3911
4307
  const value = getModel();
4308
+ if (checkboxArray) {
4309
+ if (isArray(value)) checkboxArraySnapshots.set(value, [...value]);
4310
+ }
3912
4311
  if (ime && composing) return;
3913
4312
  if (ime && !lazy && isFocused(node) && Object.is(cast(read(node)), value)) return;
3914
4313
  write(node, value);
@@ -3919,7 +4318,7 @@ function bindElement(node, prop, getter, setter, modifiers = {}) {
3919
4318
  }
3920
4319
  function unwrapSlotValue(raw) {
3921
4320
  let v = raw;
3922
- if (Array.isArray(v) && v.length === 1) v = v[0];
4321
+ if (isArray(v) && v.length === 1) v = v[0];
3923
4322
  return isFunction(v) ? v() : v;
3924
4323
  }
3925
4324
  function useChildren(props) {
@@ -4000,7 +4399,9 @@ function Portal(props) {
4000
4399
  if (children == null) return placeholder;
4001
4400
  const parentScope = getActiveScope();
4002
4401
  let innerScope = null;
4402
+ let disposed = false;
4003
4403
  const mountAt = (parent, before) => {
4404
+ if (disposed || (parentScope == null ? void 0 : parentScope.isDestroyed)) return;
4004
4405
  innerScope = createScope(parentScope);
4005
4406
  runWithScope(innerScope, () => {
4006
4407
  insert(parent, () => children, before);
@@ -4013,6 +4414,7 @@ function Portal(props) {
4013
4414
  }
4014
4415
  };
4015
4416
  const apply = (disabled, target) => {
4417
+ if (disposed) return;
4016
4418
  teardown();
4017
4419
  if (disabled) {
4018
4420
  const parent = placeholder.parentNode;
@@ -4045,11 +4447,13 @@ function Portal(props) {
4045
4447
  return;
4046
4448
  }
4047
4449
  queueMicrotask(() => {
4450
+ if (disposed) return;
4048
4451
  if (!placeholder.parentNode) return;
4049
4452
  apply(evalDisabled(props), resolveTarget(props));
4050
4453
  });
4051
4454
  });
4052
4455
  onCleanup(() => {
4456
+ disposed = true;
4053
4457
  effectRunner.stop();
4054
4458
  teardown();
4055
4459
  });
@@ -4095,12 +4499,15 @@ function resolveNodeValue(value) {
4095
4499
  if (isSignal(current) || isComputed(current)) {
4096
4500
  return resolveNodeValue(current.value);
4097
4501
  }
4098
- if (Array.isArray(current)) {
4502
+ if (isArray(current)) {
4099
4503
  return current.map((item) => resolveNodeValue(item));
4100
4504
  }
4101
4505
  return current;
4102
4506
  }
4103
4507
  var SuspenseContext = /* @__PURE__ */ Symbol("SuspenseContext");
4508
+ function isAbortError(error4) {
4509
+ return !!error4 && typeof error4 === "object" && error4.name === "AbortError";
4510
+ }
4104
4511
  function Suspense(props) {
4105
4512
  var _a22;
4106
4513
  if (!isBrowser()) {
@@ -4114,10 +4521,14 @@ function Suspense(props) {
4114
4521
  let mounted = true;
4115
4522
  let pending = 0;
4116
4523
  let mounting = false;
4524
+ let boundaryVersion = 0;
4525
+ let currentChildren = null;
4117
4526
  let contentScope = null;
4118
4527
  let parked = null;
4119
4528
  let fallbackScope = null;
4120
4529
  let resolved = null;
4530
+ let hasResolved = false;
4531
+ let manualReleases = [];
4121
4532
  const parkContent = () => {
4122
4533
  const off = document.createDocumentFragment();
4123
4534
  while (end.previousSibling && end.previousSibling !== start) {
@@ -4147,14 +4558,35 @@ function Suspense(props) {
4147
4558
  disposeScope(fallbackScope);
4148
4559
  fallbackScope = null;
4149
4560
  };
4150
- const mountContent = (children2) => {
4561
+ const disposeContent = () => {
4562
+ if (contentScope) {
4563
+ disposeScope(contentScope);
4564
+ contentScope = null;
4565
+ }
4566
+ if (parked) {
4567
+ while (parked.firstChild) parked.firstChild.remove();
4568
+ parked = null;
4569
+ }
4570
+ };
4571
+ const mountContent = (children) => {
4572
+ const scope = createScope(owner);
4151
4573
  mounting = true;
4152
- contentScope = createScope(owner);
4153
- runWithScope(contentScope, () => {
4154
- var _a32;
4155
- insert((_a32 = end.parentNode) != null ? _a32 : frag, () => resolveNodeValue(children2), end);
4156
- });
4157
- mounting = false;
4574
+ contentScope = scope;
4575
+ try {
4576
+ runWithScope(scope, () => {
4577
+ var _a32;
4578
+ insert((_a32 = end.parentNode) != null ? _a32 : frag, () => resolveNodeValue(children), end);
4579
+ });
4580
+ } catch (error4) {
4581
+ if (contentScope === scope) contentScope = null;
4582
+ disposeScope(scope);
4583
+ pending = 0;
4584
+ manualReleases = [];
4585
+ boundaryVersion++;
4586
+ throw error4;
4587
+ } finally {
4588
+ mounting = false;
4589
+ }
4158
4590
  if (pending && !parked) {
4159
4591
  parkContent();
4160
4592
  mountFallback();
@@ -4168,53 +4600,89 @@ function Suspense(props) {
4168
4600
  };
4169
4601
  const showContent = () => {
4170
4602
  if (!parked) return;
4171
- const hasSyncChildren = props.children != null && !isPromise(props.children);
4172
- if (contentScope == null && resolved == null && !hasSyncChildren) return;
4603
+ const hasSyncChildren = currentChildren != null && !isPromise(currentChildren);
4604
+ if (contentScope == null && !hasResolved && !hasSyncChildren) return;
4173
4605
  disposeFallback();
4174
4606
  restoreContent();
4175
4607
  if (!contentScope) {
4176
- if (resolved) {
4608
+ if (hasResolved) {
4177
4609
  mountContent(resolved);
4178
4610
  } else if (hasSyncChildren) {
4179
- mountContent(props.children);
4611
+ mountContent(currentChildren);
4180
4612
  }
4181
4613
  }
4182
4614
  };
4183
- const settle = () => {
4615
+ const addPending = (version = boundaryVersion) => {
4616
+ pending++;
4617
+ showFallback();
4618
+ const release = (() => {
4619
+ if (!release.active) return;
4620
+ release.active = false;
4621
+ if (!mounted || version !== boundaryVersion) return;
4622
+ if (--pending === 0) showContent();
4623
+ });
4624
+ release.active = true;
4625
+ return release;
4626
+ };
4627
+ const settle = (release) => {
4184
4628
  if (!mounted) return;
4185
- if (--pending === 0) showContent();
4629
+ release();
4630
+ };
4631
+ const dequeueManualRelease = () => {
4632
+ while (manualReleases.length > 0) {
4633
+ const release = manualReleases.shift();
4634
+ if (release.active) return release;
4635
+ }
4636
+ return void 0;
4186
4637
  };
4187
4638
  const ctx = {
4188
4639
  register: (promise) => {
4189
- pending++;
4190
- showFallback();
4191
- promise.then(settle).catch((error4) => {
4192
- warn("[Suspense] Resource failed:", error4);
4193
- settle();
4194
- });
4640
+ const release = addPending();
4641
+ promise.then(
4642
+ () => settle(release),
4643
+ (error4) => {
4644
+ if (!isAbortError(error4)) warn("[Suspense] Resource failed:", error4);
4645
+ settle(release);
4646
+ }
4647
+ );
4648
+ return release;
4195
4649
  },
4196
4650
  increment: () => {
4197
- pending++;
4198
- showFallback();
4651
+ const release = addPending();
4652
+ manualReleases.push(release);
4653
+ return release;
4199
4654
  },
4200
4655
  decrement: () => {
4201
- pending = Math.max(0, pending - 1);
4202
- if (pending === 0) showContent();
4656
+ const release = dequeueManualRelease();
4657
+ if (release) settle(release);
4203
4658
  }
4204
4659
  };
4205
4660
  provide(SuspenseContext, ctx);
4206
- const children = props.children;
4207
- if (isPromise(children)) {
4208
- children.then((value) => {
4209
- resolved = value;
4210
- }).catch(() => {
4211
- });
4212
- ctx.register(children);
4213
- } else if (children != null) {
4214
- mountContent(children);
4215
- } else if (props.fallback != null) {
4216
- showFallback();
4217
- }
4661
+ const renderChildren = (children) => {
4662
+ const version = ++boundaryVersion;
4663
+ currentChildren = children != null ? children : null;
4664
+ pending = 0;
4665
+ resolved = null;
4666
+ hasResolved = false;
4667
+ manualReleases = [];
4668
+ disposeContent();
4669
+ disposeFallback();
4670
+ if (isPromise(children)) {
4671
+ children.then((value) => {
4672
+ if (!mounted || version !== boundaryVersion) return;
4673
+ resolved = value;
4674
+ hasResolved = true;
4675
+ }).catch(() => {
4676
+ });
4677
+ ctx.register(children);
4678
+ } else if (children != null) {
4679
+ mountContent(children);
4680
+ } else if (props.fallback != null) {
4681
+ showFallback();
4682
+ }
4683
+ };
4684
+ renderChildren(props.children);
4685
+ onUpdate(() => renderChildren(props.children));
4218
4686
  onCleanup(() => {
4219
4687
  mounted = false;
4220
4688
  pending = 0;
@@ -4232,6 +4700,9 @@ Suspense[SUSPENSE_COMPONENT] = true;
4232
4700
  function isSuspense(node) {
4233
4701
  return !!node && !!node[SUSPENSE_COMPONENT];
4234
4702
  }
4703
+ function isAbortError2(error4) {
4704
+ return !!error4 && typeof error4 === "object" && error4.name === "AbortError";
4705
+ }
4235
4706
  function createResource(fetcher, options) {
4236
4707
  const value = signal(options == null ? void 0 : options.initialValue);
4237
4708
  const loading = signal(true);
@@ -4266,7 +4737,7 @@ function createResource(fetcher, options) {
4266
4737
  }
4267
4738
  } catch (error_) {
4268
4739
  if (id !== fetchId) return;
4269
- if (error_ instanceof DOMException && error_.name === "AbortError") {
4740
+ if (isAbortError2(error_)) {
4270
4741
  loading.value = false;
4271
4742
  return;
4272
4743
  }
@@ -4321,17 +4792,26 @@ function defineServerAsyncComponent(loader, ssr) {
4321
4792
  function defineClientAsyncComponent(loader, options) {
4322
4793
  const { loading, error: errorComp, delay = 200, timeout, onError } = options;
4323
4794
  let component = null;
4324
- let error4 = null;
4795
+ let loadError = null;
4325
4796
  let status = "pending";
4326
4797
  let loadPromise = null;
4327
- const load = () => loadPromise != null ? loadPromise : loadPromise = loader().then((mod) => {
4328
- component = resolveModule(mod);
4329
- status = "resolved";
4330
- }).catch((error_) => {
4331
- error4 = error_ instanceof Error ? error_ : new Error(String(error_));
4332
- status = "errored";
4333
- loadPromise = null;
4334
- });
4798
+ let loadId = 0;
4799
+ const currentLoad = (id) => id !== loadId ? loadPromise != null ? loadPromise : void 0 : void 0;
4800
+ const load = (forceId) => {
4801
+ if (loadPromise && forceId === void 0) return loadPromise;
4802
+ const id = forceId != null ? forceId : ++loadId;
4803
+ loadPromise = loader().then((mod) => {
4804
+ if (id !== loadId) return currentLoad(id);
4805
+ component = resolveModule(mod);
4806
+ status = "resolved";
4807
+ }).catch((error_) => {
4808
+ if (id !== loadId) return currentLoad(id);
4809
+ loadError = error_ instanceof Error ? error_ : new Error(String(error_));
4810
+ status = "errored";
4811
+ loadPromise = null;
4812
+ });
4813
+ return loadPromise;
4814
+ };
4335
4815
  load();
4336
4816
  function AsyncWrapper(props) {
4337
4817
  var _a22;
@@ -4343,6 +4823,7 @@ function defineClientAsyncComponent(loader, options) {
4343
4823
  let viewScope = null;
4344
4824
  let delayTimer = null;
4345
4825
  let timeoutTimer = null;
4826
+ let instanceRetryId = 0;
4346
4827
  const clearTimers = () => {
4347
4828
  if (delayTimer != null) clearTimeout(delayTimer);
4348
4829
  if (timeoutTimer != null) clearTimeout(timeoutTimer);
@@ -4372,28 +4853,34 @@ function defineClientAsyncComponent(loader, options) {
4372
4853
  end.remove();
4373
4854
  });
4374
4855
  const retryWith = (retryProps) => () => {
4856
+ if (!alive) return;
4857
+ const retryLoadId = ++loadId;
4375
4858
  loadPromise = null;
4376
4859
  status = "pending";
4377
- error4 = null;
4860
+ loadError = null;
4861
+ instanceRetryId++;
4862
+ const capturedRetry = instanceRetryId;
4378
4863
  if (loading) render(loading);
4379
- load().then(() => settle(retryProps));
4864
+ load(retryLoadId).then(() => {
4865
+ if (alive && capturedRetry === instanceRetryId) settle(retryProps);
4866
+ });
4380
4867
  };
4381
4868
  const settle = (renderProps) => {
4382
4869
  if (!alive) return;
4383
4870
  clearTimers();
4384
4871
  if (status === "resolved" && component) {
4385
4872
  render(component, renderProps);
4386
- } else if (status === "errored" && error4) {
4387
- if (errorComp) render(errorComp, { error: error4, retry: retryWith(renderProps) });
4388
- if (onError) onError(error4, retryWith(renderProps));
4873
+ } else if (status === "errored" && loadError) {
4874
+ if (errorComp) render(errorComp, { error: loadError, retry: retryWith(renderProps) });
4875
+ if (onError) onError(loadError, retryWith(renderProps));
4389
4876
  }
4390
4877
  };
4391
4878
  if (status === "resolved" && component) {
4392
4879
  render(component, props);
4393
4880
  return frag;
4394
4881
  }
4395
- if (status === "errored" && error4) {
4396
- if (errorComp) render(errorComp, { error: error4, retry: retryWith(props) });
4882
+ if (status === "errored" && loadError) {
4883
+ if (errorComp) render(errorComp, { error: loadError, retry: retryWith(props) });
4397
4884
  return frag;
4398
4885
  }
4399
4886
  const pending = load().then(() => settle(props));
@@ -4408,10 +4895,9 @@ function defineClientAsyncComponent(loader, options) {
4408
4895
  if (timeout != null) {
4409
4896
  timeoutTimer = setTimeout(() => {
4410
4897
  if (!alive || status !== "pending") return;
4411
- error4 = new Error(`[defineAsyncComponent] Timeout after ${timeout}ms`);
4412
- status = "errored";
4413
- if (errorComp) render(errorComp, { error: error4, retry: retryWith(props) });
4414
- if (onError) onError(error4, retryWith(props));
4898
+ const err = new Error(`[defineAsyncComponent] Timeout after ${timeout}ms`);
4899
+ if (errorComp) render(errorComp, { error: err, retry: retryWith(props) });
4900
+ if (onError) onError(err, retryWith(props));
4415
4901
  }, timeout);
4416
4902
  }
4417
4903
  return frag;
@@ -4430,9 +4916,11 @@ function For(props) {
4430
4916
  fragment.appendChild(marker);
4431
4917
  let entries = [];
4432
4918
  let fallbackNodes = [];
4919
+ let fallbackScope = null;
4920
+ const ownerScope = getActiveScope();
4433
4921
  const keyFn = props.key;
4434
4922
  const raw = props.children;
4435
- const renderFn = Array.isArray(raw) && raw.length === 1 && isFunction(raw[0]) ? raw[0] : props.children;
4923
+ const renderFn = isArray(raw) && raw.length === 1 && isFunction(raw[0]) ? raw[0] : props.children;
4436
4924
  if (!isFunction(renderFn)) {
4437
4925
  throw new TypeError("<For> requires `children` to be a function (item, index) => Node");
4438
4926
  }
@@ -4444,9 +4932,31 @@ function For(props) {
4444
4932
  return input != null ? input : [];
4445
4933
  };
4446
4934
  const getKey = (item, index) => keyFn ? keyFn(item, index) : item;
4935
+ const formatKeyForWarning = (key) => {
4936
+ if (typeof key === "string") return JSON.stringify(key);
4937
+ return String(key);
4938
+ };
4939
+ const getKeys = (items) => {
4940
+ const keys = new Array(items.length);
4941
+ {
4942
+ const seen = /* @__PURE__ */ new Set();
4943
+ for (const [i, item] of items.entries()) {
4944
+ const key = getKey(item, i);
4945
+ keys[i] = key;
4946
+ if (seen.has(key)) {
4947
+ warn(
4948
+ `[For] duplicate key ${formatKeyForWarning(key)} detected. Duplicate keys may cause rows to remount or lose state.`
4949
+ );
4950
+ } else {
4951
+ seen.add(key);
4952
+ }
4953
+ }
4954
+ return keys;
4955
+ }
4956
+ };
4447
4957
  const mountValue = (value, parent, before) => {
4448
4958
  if (value == null || value === false) return [];
4449
- if (Array.isArray(value)) {
4959
+ if (isArray(value)) {
4450
4960
  const nodes = [];
4451
4961
  for (const child2 of value) nodes.push(...mountValue(child2, parent, before));
4452
4962
  return nodes;
@@ -4460,17 +4970,30 @@ function For(props) {
4460
4970
  return [node];
4461
4971
  };
4462
4972
  const mountFallback = (parent, before) => {
4973
+ var _a22;
4463
4974
  if (!props.fallback) return;
4464
- const nodes = mountValue(props.fallback(), parent, before);
4465
- fallbackNodes = nodes;
4975
+ fallbackScope = createScope((_a22 = getActiveScope()) != null ? _a22 : ownerScope);
4976
+ try {
4977
+ runWithScope(fallbackScope, () => {
4978
+ fallbackNodes = mountValue(props.fallback(), parent, before);
4979
+ });
4980
+ } catch (error4) {
4981
+ disposeScope(fallbackScope);
4982
+ fallbackScope = null;
4983
+ fallbackNodes = [];
4984
+ throw error4;
4985
+ }
4466
4986
  };
4467
4987
  const clearFallback = () => {
4988
+ if (fallbackScope) {
4989
+ disposeScope(fallbackScope);
4990
+ fallbackScope = null;
4991
+ }
4468
4992
  for (const node of fallbackNodes) {
4469
4993
  removeNode(node);
4470
4994
  }
4471
4995
  fallbackNodes = [];
4472
4996
  };
4473
- const ownerScope = getActiveScope();
4474
4997
  const renderItem = (item, index, parent, before, key = getKey(item, index)) => {
4475
4998
  var _a22;
4476
4999
  const parentScope = (_a22 = getActiveScope()) != null ? _a22 : ownerScope;
@@ -4502,10 +5025,9 @@ function For(props) {
4502
5025
  mountFallback(fragment, marker);
4503
5026
  } else {
4504
5027
  entries = new Array(newItems.length);
4505
- let idx = 0;
4506
- for (const newItem of newItems) {
4507
- entries[idx] = renderItem(newItem, idx, fragment, marker);
4508
- idx++;
5028
+ const newKeys = getKeys(newItems);
5029
+ for (const [i, newItem] of newItems.entries()) {
5030
+ entries[i] = renderItem(newItem, i, fragment, marker, newKeys[i]);
4509
5031
  }
4510
5032
  }
4511
5033
  return;
@@ -4531,10 +5053,13 @@ function For(props) {
4531
5053
  }
4532
5054
  entries = new Array(newLen);
4533
5055
  const batchFragment2 = document.createDocumentFragment();
5056
+ const newKeys2 = getKeys(newItems);
4534
5057
  for (let i = 0; i < newLen; i++) {
4535
- entries[i] = renderItem(newItems[i], i, batchFragment2, null);
5058
+ entries[i] = renderItem(newItems[i], i, batchFragment2, null, newKeys2[i]);
4536
5059
  }
4537
- parent.insertBefore(batchFragment2, marker);
5060
+ untrack(() => {
5061
+ parent.insertBefore(batchFragment2, marker);
5062
+ });
4538
5063
  return;
4539
5064
  }
4540
5065
  const oldKeyMap = /* @__PURE__ */ new Map();
@@ -4551,10 +5076,7 @@ function For(props) {
4551
5076
  const newIndexToOldIndex = new Int32Array(newLen);
4552
5077
  let moved = false;
4553
5078
  let maxOldSeen = 0;
4554
- const newKeys = new Array(newLen);
4555
- for (let i = 0; i < newLen; i++) {
4556
- newKeys[i] = getKey(newItems[i], i);
4557
- }
5079
+ const newKeys = getKeys(newItems);
4558
5080
  for (let i = 0; i < newLen; i++) {
4559
5081
  const item = newItems[i];
4560
5082
  const key = newKeys[i];
@@ -4569,7 +5091,7 @@ function For(props) {
4569
5091
  else maxOldSeen = oldIndex;
4570
5092
  } else {
4571
5093
  if (!batchFragment) batchFragment = document.createDocumentFragment();
4572
- disposeItem(reused);
5094
+ untrack(() => disposeItem(reused));
4573
5095
  newEntries[i] = renderItem(item, i, batchFragment, null, key);
4574
5096
  }
4575
5097
  } else {
@@ -4580,28 +5102,30 @@ function For(props) {
4580
5102
  for (const list of oldKeyMap.values()) {
4581
5103
  for (const [entry] of list) toRemove.push(entry);
4582
5104
  }
4583
- for (const entry of toRemove) disposeItem(entry);
4584
- const lis = moved ? getSequence(newIndexToOldIndex) : [];
4585
- let lisCursor = lis.length - 1;
4586
- let nextNode = marker;
4587
- for (let i = newLen - 1; i >= 0; i--) {
4588
- const entry = newEntries[i];
4589
- const nodes = entry.nodes;
4590
- const isFresh = newIndexToOldIndex[i] === 0;
4591
- const inLis = !isFresh && moved && lisCursor >= 0 && i === lis[lisCursor];
4592
- if (inLis) {
4593
- lisCursor--;
4594
- for (let j = nodes.length - 1; j >= 0; j--) nextNode = nodes[j];
4595
- continue;
4596
- }
4597
- for (let j = nodes.length - 1; j >= 0; j--) {
4598
- const node = nodes[j];
4599
- if (node.nextSibling !== nextNode) {
4600
- parent.insertBefore(node, nextNode);
5105
+ for (const entry of toRemove) untrack(() => disposeItem(entry));
5106
+ untrack(() => {
5107
+ const lis = moved ? getSequence(newIndexToOldIndex) : [];
5108
+ let lisCursor = lis.length - 1;
5109
+ let nextNode = marker;
5110
+ for (let i = newLen - 1; i >= 0; i--) {
5111
+ const entry = newEntries[i];
5112
+ const nodes = entry.nodes;
5113
+ const isFresh = newIndexToOldIndex[i] === 0;
5114
+ const inLis = !isFresh && moved && lisCursor >= 0 && i === lis[lisCursor];
5115
+ if (inLis) {
5116
+ lisCursor--;
5117
+ for (let j = nodes.length - 1; j >= 0; j--) nextNode = nodes[j];
5118
+ continue;
5119
+ }
5120
+ for (let j = nodes.length - 1; j >= 0; j--) {
5121
+ const node = nodes[j];
5122
+ if (node.nextSibling !== nextNode) {
5123
+ parent.insertBefore(node, nextNode);
5124
+ }
5125
+ nextNode = node;
4601
5126
  }
4602
- nextNode = node;
4603
5127
  }
4604
- }
5128
+ });
4605
5129
  entries = newEntries;
4606
5130
  }
4607
5131
  onCleanup(() => {
@@ -4664,21 +5188,40 @@ function addClass(el, cls) {
4664
5188
  function removeClass(el, cls) {
4665
5189
  for (const c of cls.split(/\s+/)) if (c) el.classList.remove(c);
4666
5190
  }
4667
- function nextFrame(cb) {
4668
- requestAnimationFrame(() => requestAnimationFrame(cb));
5191
+ function nextFrameCancellable(cb) {
5192
+ let cancelled = false;
5193
+ let innerId = null;
5194
+ const outerId = requestAnimationFrame(() => {
5195
+ if (cancelled) return;
5196
+ innerId = requestAnimationFrame(cb);
5197
+ });
5198
+ return () => {
5199
+ cancelled = true;
5200
+ cancelAnimationFrame(outerId);
5201
+ if (innerId != null) cancelAnimationFrame(innerId);
5202
+ };
4669
5203
  }
4670
5204
  function forceReflow(el) {
4671
5205
  void el.offsetHeight;
4672
5206
  }
4673
5207
  function whenTransitionEnds(el, type, explicit, resolve2) {
4674
5208
  if (explicit != null) {
4675
- setTimeout(resolve2, explicit);
4676
- return;
5209
+ let done2 = false;
5210
+ const timer2 = setTimeout(() => {
5211
+ if (done2) return;
5212
+ done2 = true;
5213
+ resolve2();
5214
+ }, explicit);
5215
+ return () => {
5216
+ done2 = true;
5217
+ clearTimeout(timer2);
5218
+ };
4677
5219
  }
4678
5220
  const info = getTransitionInfo(el, type);
4679
5221
  if (!info) {
4680
5222
  resolve2();
4681
- return;
5223
+ return () => {
5224
+ };
4682
5225
  }
4683
5226
  let done = false;
4684
5227
  const finish = () => {
@@ -4688,9 +5231,18 @@ function whenTransitionEnds(el, type, explicit, resolve2) {
4688
5231
  el.removeEventListener(info.event, onEnd);
4689
5232
  resolve2();
4690
5233
  };
4691
- const onEnd = () => finish();
5234
+ const onEnd = (event) => {
5235
+ if (event.target !== el) return;
5236
+ finish();
5237
+ };
4692
5238
  el.addEventListener(info.event, onEnd);
4693
5239
  const timer = setTimeout(finish, info.timeout + 1);
5240
+ return () => {
5241
+ if (done) return;
5242
+ done = true;
5243
+ clearTimeout(timer);
5244
+ el.removeEventListener(info.event, onEnd);
5245
+ };
4694
5246
  }
4695
5247
  function resolveDuration(d, dir) {
4696
5248
  if (d == null) return null;
@@ -4699,7 +5251,7 @@ function resolveDuration(d, dir) {
4699
5251
  }
4700
5252
  function validateSlot(value) {
4701
5253
  if (value == null || value === false) return null;
4702
- if (Array.isArray(value)) {
5254
+ if (isArray(value)) {
4703
5255
  {
4704
5256
  throw new Error(
4705
5257
  "[essor] <Transition> expects a single root child. Use <TransitionGroup> for multiple children."
@@ -4745,8 +5297,26 @@ function Transition(props) {
4745
5297
  let hasPending = false;
4746
5298
  let scheduled = false;
4747
5299
  let disposed = false;
5300
+ let cancelEnterWait = null;
5301
+ let cancelLeaveWait = null;
5302
+ const stopEnterWait = () => {
5303
+ cancelEnterWait == null ? void 0 : cancelEnterWait();
5304
+ cancelEnterWait = null;
5305
+ };
5306
+ const stopLeaveWait = () => {
5307
+ cancelLeaveWait == null ? void 0 : cancelLeaveWait();
5308
+ cancelLeaveWait = null;
5309
+ };
4748
5310
  const enter = (el, phase) => {
4749
5311
  var _a22;
5312
+ stopEnterWait();
5313
+ let cancelWait = null;
5314
+ const stopWait = () => {
5315
+ cancelWait == null ? void 0 : cancelWait();
5316
+ cancelWait = null;
5317
+ if (cancelEnterWait === stopWait) cancelEnterWait = null;
5318
+ };
5319
+ cancelEnterWait = stopWait;
4750
5320
  const prevLeave = el[LEAVE_CB];
4751
5321
  if (prevLeave) prevLeave(true);
4752
5322
  state = "entering";
@@ -4763,6 +5333,7 @@ function Transition(props) {
4763
5333
  var _a32, _b2;
4764
5334
  if (called) return;
4765
5335
  called = true;
5336
+ stopWait();
4766
5337
  el[ENTER_CB] = void 0;
4767
5338
  if (useCss) {
4768
5339
  removeClass(el, fromCls);
@@ -4777,7 +5348,8 @@ function Transition(props) {
4777
5348
  }
4778
5349
  };
4779
5350
  el[ENTER_CB] = done;
4780
- nextFrame(() => {
5351
+ cancelWait = nextFrameCancellable(() => {
5352
+ cancelWait = null;
4781
5353
  if (called) return;
4782
5354
  if (useCss) {
4783
5355
  removeClass(el, fromCls);
@@ -4787,7 +5359,10 @@ function Transition(props) {
4787
5359
  props.onEnter(el, () => done(false));
4788
5360
  } else if (useCss) {
4789
5361
  const explicit = resolveDuration(props.duration, "enter");
4790
- whenTransitionEnds(el, props.type, explicit, () => done(false));
5362
+ cancelWait = whenTransitionEnds(el, props.type, explicit, () => {
5363
+ cancelWait = null;
5364
+ done(false);
5365
+ });
4791
5366
  } else {
4792
5367
  done(false);
4793
5368
  }
@@ -4795,6 +5370,14 @@ function Transition(props) {
4795
5370
  };
4796
5371
  const leave = (el, after) => {
4797
5372
  var _a22;
5373
+ stopLeaveWait();
5374
+ let cancelWait = null;
5375
+ const stopWait = () => {
5376
+ cancelWait == null ? void 0 : cancelWait();
5377
+ cancelWait = null;
5378
+ if (cancelLeaveWait === stopWait) cancelLeaveWait = null;
5379
+ };
5380
+ cancelLeaveWait = stopWait;
4798
5381
  const prevEnter = el[ENTER_CB];
4799
5382
  if (prevEnter) {
4800
5383
  prevEnter(true);
@@ -4811,6 +5394,7 @@ function Transition(props) {
4811
5394
  var _a32, _b2;
4812
5395
  if (called) return;
4813
5396
  called = true;
5397
+ stopWait();
4814
5398
  el[LEAVE_CB] = void 0;
4815
5399
  if (useCss) {
4816
5400
  removeClass(el, classes.leaveFrom);
@@ -4832,7 +5416,8 @@ function Transition(props) {
4832
5416
  done(false);
4833
5417
  return;
4834
5418
  }
4835
- nextFrame(() => {
5419
+ cancelWait = nextFrameCancellable(() => {
5420
+ cancelWait = null;
4836
5421
  if (called) return;
4837
5422
  if (useCss) {
4838
5423
  removeClass(el, classes.leaveFrom);
@@ -4841,7 +5426,10 @@ function Transition(props) {
4841
5426
  if (props.onLeave) {
4842
5427
  props.onLeave(el, () => done(false));
4843
5428
  } else if (useCss) {
4844
- whenTransitionEnds(el, props.type, explicit, () => done(false));
5429
+ cancelWait = whenTransitionEnds(el, props.type, explicit, () => {
5430
+ cancelWait = null;
5431
+ done(false);
5432
+ });
4845
5433
  } else {
4846
5434
  done(false);
4847
5435
  }
@@ -4916,6 +5504,8 @@ function Transition(props) {
4916
5504
  });
4917
5505
  onCleanup(() => {
4918
5506
  disposed = true;
5507
+ stopEnterWait();
5508
+ stopLeaveWait();
4919
5509
  effectRunner.stop();
4920
5510
  for (const el of [currentEl, leavingEl]) {
4921
5511
  if (!el) continue;
@@ -4937,7 +5527,7 @@ function isTransition(node) {
4937
5527
  }
4938
5528
  function resolveItemElement(raw, parent) {
4939
5529
  if (raw == null || raw === false) return { el: null, comp: null };
4940
- if (Array.isArray(raw) && raw.length === 1) {
5530
+ if (isArray(raw) && raw.length === 1) {
4941
5531
  return resolveItemElement(raw[0], parent);
4942
5532
  }
4943
5533
  if (isFunction(raw)) {
@@ -4992,7 +5582,7 @@ function TransitionGroup(props) {
4992
5582
  const moveClass = (_c = props.moveClass) != null ? _c : `${(_b2 = props.name) != null ? _b2 : "v"}-move`;
4993
5583
  const keyFn = props.key;
4994
5584
  const rawChildren = props.children;
4995
- const childrenFn = Array.isArray(rawChildren) && rawChildren.length === 1 && isFunction(rawChildren[0]) ? rawChildren[0] : props.children;
5585
+ const childrenFn = isArray(rawChildren) && rawChildren.length === 1 && isFunction(rawChildren[0]) ? rawChildren[0] : props.children;
4996
5586
  if (!isFunction(childrenFn) || !isFunction(keyFn)) {
4997
5587
  throw new TypeError(
4998
5588
  "<TransitionGroup> requires `children: (item, index) => Node` and `key: (item, index) => unknown`"
@@ -5043,9 +5633,12 @@ function TransitionGroup(props) {
5043
5633
  if (entry.el.parentNode === wrapper) wrapper.removeChild(entry.el);
5044
5634
  };
5045
5635
  const disposeEntry = (entry) => {
5046
- var _a32, _b22;
5636
+ var _a32, _b22, _c2, _d, _e;
5047
5637
  (_a32 = entry.cancelEnter) == null ? void 0 : _a32.call(entry, true);
5048
5638
  (_b22 = entry.cancelLeave) == null ? void 0 : _b22.call(entry, true);
5639
+ (_c2 = entry.cancelEnterWait) == null ? void 0 : _c2.call(entry);
5640
+ (_d = entry.cancelLeaveWait) == null ? void 0 : _d.call(entry);
5641
+ (_e = entry.cancelMoveWait) == null ? void 0 : _e.call(entry);
5049
5642
  if (entry.comp) entry.comp.destroy();
5050
5643
  detachEntryDom(entry);
5051
5644
  disposeScope(entry.scope);
@@ -5064,23 +5657,26 @@ function TransitionGroup(props) {
5064
5657
  addClass(el, classes.enterActive);
5065
5658
  let called = false;
5066
5659
  const done = (cancelled) => {
5067
- var _a42, _b3;
5660
+ var _a42, _b3, _c3;
5068
5661
  if (called) return;
5069
5662
  called = true;
5070
5663
  entry.cancelEnter = void 0;
5664
+ (_a42 = entry.cancelEnterWait) == null ? void 0 : _a42.call(entry);
5665
+ entry.cancelEnterWait = void 0;
5071
5666
  removeClass(el, classes.enterFrom);
5072
5667
  removeClass(el, classes.enterActive);
5073
5668
  removeClass(el, classes.enterTo);
5074
5669
  if (cancelled) {
5075
- (_a42 = props.onEnterCancelled) == null ? void 0 : _a42.call(props, el);
5670
+ (_b3 = props.onEnterCancelled) == null ? void 0 : _b3.call(props, el);
5076
5671
  } else {
5077
5672
  entry.state = "present";
5078
- (_b3 = props.onAfterEnter) == null ? void 0 : _b3.call(props, el);
5673
+ (_c3 = props.onAfterEnter) == null ? void 0 : _c3.call(props, el);
5079
5674
  }
5080
5675
  };
5081
5676
  entry.cancelEnter = done;
5082
5677
  entry.state = "entering";
5083
- nextFrame(() => {
5678
+ entry.cancelEnterWait = nextFrameCancellable(() => {
5679
+ entry.cancelEnterWait = void 0;
5084
5680
  if (called) return;
5085
5681
  removeClass(el, classes.enterFrom);
5086
5682
  addClass(el, classes.enterTo);
@@ -5088,7 +5684,10 @@ function TransitionGroup(props) {
5088
5684
  props.onEnter(el, () => done(false));
5089
5685
  } else {
5090
5686
  const explicit = resolveDuration(props.duration, "enter");
5091
- whenTransitionEnds(el, props.type, explicit, () => done(false));
5687
+ entry.cancelEnterWait = whenTransitionEnds(el, props.type, explicit, () => {
5688
+ entry.cancelEnterWait = void 0;
5689
+ done(false);
5690
+ });
5092
5691
  }
5093
5692
  });
5094
5693
  };
@@ -5120,17 +5719,19 @@ function TransitionGroup(props) {
5120
5719
  addClass(el, classes.leaveActive);
5121
5720
  let called = false;
5122
5721
  const done = (cancelled) => {
5123
- var _a42, _b3;
5722
+ var _a42, _b3, _c2;
5124
5723
  if (called) return;
5125
5724
  called = true;
5126
5725
  entry.cancelLeave = void 0;
5726
+ (_a42 = entry.cancelLeaveWait) == null ? void 0 : _a42.call(entry);
5727
+ entry.cancelLeaveWait = void 0;
5127
5728
  removeClass(el, classes.leaveFrom);
5128
5729
  removeClass(el, classes.leaveActive);
5129
5730
  removeClass(el, classes.leaveTo);
5130
5731
  if (cancelled) {
5131
5732
  if (entry.savedStyles) restoreStyles(el, entry.savedStyles);
5132
5733
  entry.savedStyles = void 0;
5133
- (_a42 = props.onLeaveCancelled) == null ? void 0 : _a42.call(props, el);
5734
+ (_b3 = props.onLeaveCancelled) == null ? void 0 : _b3.call(props, el);
5134
5735
  return;
5135
5736
  }
5136
5737
  if (entry.savedStyles) restoreStyles(el, entry.savedStyles);
@@ -5138,10 +5739,11 @@ function TransitionGroup(props) {
5138
5739
  detachEntryDom(entry);
5139
5740
  disposeScope(entry.scope);
5140
5741
  if (entry.comp) entry.comp.destroy();
5141
- (_b3 = props.onAfterLeave) == null ? void 0 : _b3.call(props, el);
5742
+ (_c2 = props.onAfterLeave) == null ? void 0 : _c2.call(props, el);
5142
5743
  };
5143
5744
  entry.cancelLeave = done;
5144
- nextFrame(() => {
5745
+ entry.cancelLeaveWait = nextFrameCancellable(() => {
5746
+ entry.cancelLeaveWait = void 0;
5145
5747
  if (called) return;
5146
5748
  removeClass(el, classes.leaveFrom);
5147
5749
  addClass(el, classes.leaveTo);
@@ -5149,11 +5751,15 @@ function TransitionGroup(props) {
5149
5751
  props.onLeave(el, () => done(false));
5150
5752
  } else {
5151
5753
  const explicit = resolveDuration(props.duration, "leave");
5152
- whenTransitionEnds(el, props.type, explicit, () => done(false));
5754
+ entry.cancelLeaveWait = whenTransitionEnds(el, props.type, explicit, () => {
5755
+ entry.cancelLeaveWait = void 0;
5756
+ done(false);
5757
+ });
5153
5758
  }
5154
5759
  });
5155
5760
  };
5156
5761
  const runMove = (entry, prevRect) => {
5762
+ var _a32;
5157
5763
  if (!useCss || entry.state !== "present") return;
5158
5764
  const el = entry.el;
5159
5765
  const newRect = el.getBoundingClientRect();
@@ -5169,7 +5775,9 @@ function TransitionGroup(props) {
5169
5775
  el.style.transform = savedTransform;
5170
5776
  el.style.transitionDuration = savedTransition;
5171
5777
  const explicit = resolveDuration(props.duration, "enter");
5172
- whenTransitionEnds(el, props.type, explicit, () => {
5778
+ (_a32 = entry.cancelMoveWait) == null ? void 0 : _a32.call(entry);
5779
+ entry.cancelMoveWait = whenTransitionEnds(el, props.type, explicit, () => {
5780
+ entry.cancelMoveWait = void 0;
5173
5781
  removeClass(el, moveClass);
5174
5782
  });
5175
5783
  };
@@ -5278,6 +5886,6 @@ if (globalThis) {
5278
5886
  globalThis.__essor_version__ = __version;
5279
5887
  }
5280
5888
 
5281
- export { Component, EffectScope, For, Fragment, Portal, Suspense, Transition, TransitionGroup, TriggerOpTypes, __version, addEvent, addEventListener, batch, beginHydration, bindElement, child, clearDelegatedEvents, computed, consumeTeleportAnchor, consumeTeleportBlock, createApp, createComponent, createResource, createStore, defineAsyncComponent, delegateEvents, effect, effectScope, endBatch, endHydration, getBatchDepth, getCurrentScope, getHydrationKey, getRenderedElement, hydrate, hydrationAnchor, hydrationMarker, inject, insert, isBatching, isComponent, isComputed, isEffect, isFragment, isHydrating, isPortal, isReactive, isRef, isShallow, isSignal, isSuspense, isTransition, isTransitionGroup, memoEffect, next, nextTick, normalizeClass, nthChild, omitProps, onDestroy, onMount, onScopeDispose, onUpdate, patchAttr, patchAttrHydrate, patchClass, patchClassHydrate, patchStyle, patchStyleHydrate, provide, queueJob, queuePreFlushCb, reactive, ref, resetHydrationKey, setCurrentScope, setStyle, shallowReactive, shallowSignal, signal, startBatch, stop, template, toRaw, toReactive, trigger, untrack, watch };
5889
+ export { Component, EffectScope, For, Fragment, Portal, Suspense, Transition, TransitionGroup, TriggerOpTypes, __version, addEvent, addEventListener, batch, beginHydration, bindElement, child, clearDelegatedEvents, computed, consumeTeleportAnchor, consumeTeleportBlock, createApp, createComponent, createResource, createStore, defineAsyncComponent, delegateEvents, effect, effectScope, endBatch, endHydration, getBatchDepth, getCurrentScope, getHydrationKey, getRenderedElement, getTargetDepSize, hydrate, hydrationAnchor, hydrationMarker, inject, insert, isBatching, isComponent, isComputed, isEffect, isFragment, isHydrating, isPortal, isReactive, isRef, isShallow, isSignal, isSuspense, isTransition, isTransitionGroup, memoEffect, next, nextTick, normalizeClass, nthChild, omitProps, onDestroy, onMount, onScopeDispose, onUpdate, patchAttr, patchAttrHydrate, patchClass, patchClassHydrate, patchStyle, patchStyleHydrate, provide, queueJob, queuePostFlushJob, queuePreFlushCb, reactive, ref, resetHydrationKey, setCurrentScope, setStyle, shallowReactive, shallowSignal, signal, startBatch, stop, template, toRaw, toReactive, toRef, toRefs, trigger, unref, untrack, watch };
5282
5890
  //# sourceMappingURL=essor.browser.dev.js.map
5283
5891
  //# sourceMappingURL=essor.browser.dev.js.map