@estjs/signals 0.0.15-beta.9 → 0.0.16-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.
@@ -3,8 +3,6 @@
3
3
  var shared = require('@estjs/shared');
4
4
 
5
5
  var __defProp = Object.defineProperty;
6
- var __defProps = Object.defineProperties;
7
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
8
6
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
10
8
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
@@ -20,7 +18,6 @@ var __spreadValues = (a, b) => {
20
18
  }
21
19
  return a;
22
20
  };
23
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
21
 
25
22
  // src/constants.ts
26
23
  var TriggerOpTypes = {
@@ -29,58 +26,62 @@ var TriggerOpTypes = {
29
26
  DELETE: "DELETE",
30
27
  CLEAR: "CLEAR"
31
28
  };
32
- var SIGNAL_KEY = /* @__PURE__ */ Symbol("Signal_Key" );
33
29
  var ARRAY_KEY = /* @__PURE__ */ Symbol("Array_Key" );
34
30
  var COLLECTION_KEY = /* @__PURE__ */ Symbol("Collection_Key" );
35
31
  var WEAK_COLLECTION_KEY = /* @__PURE__ */ Symbol("WeakCollection_Key" );
32
+ var ITERATE_KEY = /* @__PURE__ */ Symbol("Iterate_Key" );
36
33
  var ARRAY_ITERATE_KEY = /* @__PURE__ */ Symbol("Array_Iterate_Key" );
37
34
 
38
35
  // src/propagation.ts
36
+ function enqueueEffect(effect2) {
37
+ var _a5;
38
+ (_a5 = effect2 == null ? void 0 : effect2.notify) == null ? void 0 : _a5.call(effect2);
39
+ }
39
40
  function propagate(link) {
40
41
  let next = link.nextSubLink;
41
42
  let stack;
42
43
  top: do {
43
44
  const sub = link.subNode;
44
- const queueBit = sub.flag & 64 /* QUEUED */;
45
45
  const watcherBit = sub.flag & 2 /* WATCHING */;
46
- let flags = sub.flag & -65 /* QUEUED */;
46
+ let flags = sub.flag;
47
47
  if (!(flags & (16 /* DIRTY */ | 32 /* PENDING */ | 8 /* RECURSED */ | 4 /* RECURSED_CHECK */))) {
48
- sub.flag = queueBit | watcherBit | flags | 32 /* PENDING */;
49
- } else if (flags & (16 /* DIRTY */ | 32 /* PENDING */)) ; else if (!(flags & (8 /* RECURSED */ | 4 /* RECURSED_CHECK */))) {
48
+ sub.flag = flags | 32 /* PENDING */;
49
+ if (watcherBit) {
50
+ enqueueEffect(sub);
51
+ }
52
+ } else if (!(flags & (8 /* RECURSED */ | 4 /* RECURSED_CHECK */))) {
50
53
  flags = 0 /* NONE */;
51
- sub.flag = queueBit | watcherBit;
52
54
  } else if (!(flags & 4 /* RECURSED_CHECK */)) {
53
- sub.flag = queueBit | watcherBit | (flags & -9 /* RECURSED */ | 32 /* PENDING */);
55
+ sub.flag = flags & -9 /* RECURSED */ | 32 /* PENDING */;
54
56
  } else if (!(flags & (16 /* DIRTY */ | 32 /* PENDING */)) && isValidLink(link, sub)) {
55
- sub.flag = queueBit | watcherBit | (flags | 8 /* RECURSED */ | 32 /* PENDING */);
57
+ sub.flag = flags | (8 /* RECURSED */ | 32 /* PENDING */);
58
+ if (watcherBit) {
59
+ enqueueEffect(sub);
60
+ }
56
61
  flags &= 1 /* MUTABLE */;
57
62
  } else {
58
63
  flags = 0 /* NONE */;
59
- sub.flag = queueBit | watcherBit;
60
- }
61
- if (sub.flag & 2 /* WATCHING */) {
62
- enqueueEffect(sub);
63
64
  }
64
65
  if (flags & 1 /* MUTABLE */) {
65
66
  const subSubs = sub.subLink;
66
- if (subSubs) {
67
- const nextSub = (link = subSubs).nextSubLink;
68
- if (nextSub) {
67
+ if (subSubs !== void 0) {
68
+ const nextSub = subSubs.nextSubLink;
69
+ if (nextSub !== void 0) {
69
70
  stack = { value: next, prev: stack };
70
71
  next = nextSub;
71
72
  }
73
+ link = subSubs;
72
74
  continue;
73
75
  }
74
76
  }
75
- if (next) {
76
- link = next;
77
+ if ((link = next) !== void 0) {
77
78
  next = link.nextSubLink;
78
79
  continue;
79
80
  }
80
- while (stack) {
81
+ while (stack !== void 0) {
81
82
  link = stack.value;
82
83
  stack = stack.prev;
83
- if (link) {
84
+ if (link !== void 0) {
84
85
  next = link.nextSubLink;
85
86
  continue top;
86
87
  }
@@ -91,32 +92,38 @@ function propagate(link) {
91
92
  function shallowPropagate(link) {
92
93
  while (link) {
93
94
  const sub = link.subNode;
94
- const queueBit = sub.flag & 64 /* QUEUED */;
95
- const flags = sub.flag & -65 /* QUEUED */;
96
- if (!(flags & 16 /* DIRTY */) && flags & (1 /* MUTABLE */ | 32 /* PENDING */)) {
97
- const newFlags = queueBit | flags & -33 /* PENDING */ | 16 /* DIRTY */;
98
- sub.flag = newFlags;
99
- if (newFlags & 2 /* WATCHING */) {
95
+ const flags = sub.flag;
96
+ if ((flags & (32 /* PENDING */ | 16 /* DIRTY */)) === 32 /* PENDING */) {
97
+ sub.flag = flags | 16 /* DIRTY */;
98
+ if ((flags & (2 /* WATCHING */ | 4 /* RECURSED_CHECK */)) === 2 /* WATCHING */) {
100
99
  enqueueEffect(sub);
101
100
  }
102
- if (flags & 1 /* MUTABLE */ && sub.subLink) {
103
- shallowPropagate(sub.subLink);
104
- }
105
101
  }
106
102
  link = link.nextSubLink;
107
103
  }
108
104
  }
109
- function enqueueEffect(effect2) {
110
- if (!effect2.active) {
111
- return;
112
- }
113
- effect2.notify();
114
- }
115
105
 
116
106
  // src/link.ts
117
107
  var currentLinkVersion = 0;
118
108
  var activeSub;
119
109
  var isUntracking = false;
110
+ var Dep = class {
111
+ constructor(map, key) {
112
+ this.map = map;
113
+ this.key = key;
114
+ this.isDep = true;
115
+ this.flag = 0 /* NONE */;
116
+ }
117
+ get subLink() {
118
+ return this._subLink;
119
+ }
120
+ set subLink(value) {
121
+ this._subLink = value;
122
+ if (value === void 0) {
123
+ this.map.delete(this.key);
124
+ }
125
+ }
126
+ };
120
127
  function linkReactiveNode(depNode, subNode) {
121
128
  if (isUntracking) {
122
129
  return void 0;
@@ -205,7 +212,9 @@ function unlinkReactiveNode(linkNode, subNode = linkNode.subNode) {
205
212
  toRemove = unlinkReactiveNode(toRemove, depNode);
206
213
  }
207
214
  depNode.depLinkTail = void 0;
208
- depNode.flag |= 16 /* DIRTY */;
215
+ if (!depNode.isDep) {
216
+ depNode.flag |= 16 /* DIRTY */;
217
+ }
209
218
  {
210
219
  if (depNode.depLink) {
211
220
  shared.error(
@@ -215,67 +224,76 @@ function unlinkReactiveNode(linkNode, subNode = linkNode.subNode) {
215
224
  }
216
225
  }
217
226
  }
218
- linkNode.depNode = void 0;
219
- linkNode.subNode = void 0;
220
- linkNode.prevSubLink = void 0;
221
- linkNode.nextSubLink = void 0;
222
- linkNode.prevDepLink = void 0;
223
- linkNode.nextDepLink = void 0;
224
227
  return nextDep;
225
228
  }
226
229
  function checkDirty(link, sub) {
227
- const stack = [{ link, owner: sub }];
228
- const pendingNodes = [];
229
- while (stack.length > 0) {
230
- const frame = stack.pop();
231
- let current = frame.link;
232
- const owner = frame.owner;
233
- while (current) {
234
- const dep = current.depNode;
230
+ let stack;
231
+ let checkDepth = 0;
232
+ let dirty = false;
233
+ top: do {
234
+ let currentDirty = false;
235
+ if (sub.flag & 16 /* DIRTY */) {
236
+ currentDirty = true;
237
+ } else {
238
+ const dep = link.depNode;
235
239
  const depFlags = dep.flag;
236
- if (owner.flag & 16 /* DIRTY */) {
237
- return true;
238
- }
239
240
  if ((depFlags & (1 /* MUTABLE */ | 16 /* DIRTY */)) === (1 /* MUTABLE */ | 16 /* DIRTY */)) {
240
241
  const subs = dep.subLink;
241
242
  if (subs && subs.nextSubLink) {
242
243
  shallowPropagate2(subs);
243
244
  }
244
- for (const node of pendingNodes) {
245
- if (node.flag & 32 /* PENDING */) {
246
- node.flag = node.flag & -33 /* PENDING */ | 16 /* DIRTY */;
247
- }
248
- }
249
- return true;
250
- }
251
- if ((depFlags & (1 /* MUTABLE */ | 32 /* PENDING */)) === (1 /* MUTABLE */ | 32 /* PENDING */)) {
245
+ currentDirty = true;
246
+ } else if ((depFlags & (1 /* MUTABLE */ | 32 /* PENDING */)) === (1 /* MUTABLE */ | 32 /* PENDING */)) {
252
247
  if (dep.depLink) {
253
- pendingNodes.push(dep);
254
- stack.push({ link: dep.depLink, owner: dep });
248
+ stack = { link, prev: stack };
249
+ link = dep.depLink;
250
+ sub = dep;
251
+ ++checkDepth;
252
+ continue top;
255
253
  } else {
256
254
  dep.flag &= -33 /* PENDING */;
257
255
  }
258
256
  } else if (depFlags & 32 /* PENDING */) {
259
257
  dep.flag &= -33 /* PENDING */;
260
258
  }
261
- current = current.nextDepLink;
262
259
  }
263
- }
264
- for (const node of pendingNodes) {
265
- node.flag &= -33 /* PENDING */;
266
- }
267
- if (sub.flag & 32 /* PENDING */) {
268
- sub.flag &= -33 /* PENDING */;
269
- }
270
- return false;
260
+ if (!currentDirty && link.nextDepLink !== void 0) {
261
+ link = link.nextDepLink;
262
+ continue top;
263
+ }
264
+ dirty = currentDirty;
265
+ while (checkDepth--) {
266
+ link = stack.link;
267
+ stack = stack.prev;
268
+ sub = link.subNode;
269
+ const checkedDep = link.depNode;
270
+ if (dirty) {
271
+ checkedDep.flag = checkedDep.flag & -33 /* PENDING */ | 16 /* DIRTY */;
272
+ } else {
273
+ checkedDep.flag &= -33 /* PENDING */;
274
+ }
275
+ if (checkedDep.flag & 16 /* DIRTY */) {
276
+ dirty = true;
277
+ }
278
+ if (!dirty && link.nextDepLink !== void 0) {
279
+ link = link.nextDepLink;
280
+ continue top;
281
+ }
282
+ }
283
+ if (dirty) {
284
+ sub.flag = sub.flag & -33 /* PENDING */ | 16 /* DIRTY */;
285
+ } else {
286
+ sub.flag &= -33 /* PENDING */;
287
+ }
288
+ return dirty;
289
+ } while (true);
271
290
  }
272
291
  function shallowPropagate2(link) {
273
292
  while (link) {
274
293
  const sub = link.subNode;
275
- const queueBit = sub.flag & 64 /* QUEUED */;
276
- const flags = sub.flag & -65 /* QUEUED */;
294
+ const flags = sub.flag;
277
295
  if ((flags & (32 /* PENDING */ | 16 /* DIRTY */)) === 32 /* PENDING */) {
278
- sub.flag = queueBit | flags | 16 /* DIRTY */;
296
+ sub.flag = flags | 16 /* DIRTY */;
279
297
  }
280
298
  link = link.nextSubLink;
281
299
  }
@@ -322,6 +340,20 @@ function isValidLink(checkLink, sub) {
322
340
  return false;
323
341
  }
324
342
  var targetMap = /* @__PURE__ */ new WeakMap();
343
+ var triggerVersion = 0;
344
+ function collectTriggeredEffects(dep, effects, version) {
345
+ if (!dep) {
346
+ return;
347
+ }
348
+ for (let link = dep.subLink; link; link = link.nextSubLink) {
349
+ const effect2 = link.subNode;
350
+ if (effect2._triggerVersion === version) {
351
+ continue;
352
+ }
353
+ effect2._triggerVersion = version;
354
+ effects.push(effect2);
355
+ }
356
+ }
325
357
  function track(target, key) {
326
358
  if (!activeSub || isUntracking) {
327
359
  return;
@@ -333,53 +365,33 @@ function track(target, key) {
333
365
  }
334
366
  let dep = depsMap.get(key);
335
367
  if (!dep) {
336
- dep = /* @__PURE__ */ new Set();
368
+ dep = new Dep(depsMap, key);
337
369
  depsMap.set(key, dep);
338
370
  }
339
- if (!dep.has(activeSub)) {
340
- dep.add(activeSub);
341
- if (shared.isFunction(activeSub.onTrack)) {
342
- activeSub.onTrack({
343
- effect: activeSub,
344
- target,
345
- type: "get",
346
- key
347
- });
348
- }
349
- }
371
+ linkReactiveNode(dep, activeSub);
350
372
  }
351
373
  function trigger(target, type, key, newValue) {
374
+ var _a5;
352
375
  const depsMap = targetMap.get(target);
353
376
  if (!depsMap) {
354
377
  return;
355
378
  }
356
- const effects = /* @__PURE__ */ new Set();
379
+ const effects = [];
380
+ const version = ++triggerVersion;
357
381
  if (key !== void 0) {
358
382
  if (Array.isArray(key)) {
359
- key.forEach((k) => {
360
- const dep = depsMap.get(k);
361
- if (dep) {
362
- dep.forEach((effect2) => effects.add(effect2));
363
- }
364
- });
365
- } else {
366
- const dep = depsMap.get(key);
367
- if (dep) {
368
- dep.forEach((effect2) => effects.add(effect2));
383
+ for (const element of key) {
384
+ collectTriggeredEffects(depsMap.get(element), effects, version);
369
385
  }
386
+ } else {
387
+ collectTriggeredEffects(depsMap.get(key), effects, version);
370
388
  }
371
389
  }
372
390
  if (type === "ADD" || type === "DELETE" || type === "CLEAR") {
373
- const ITERATE_KEY = /* @__PURE__ */ Symbol("iterate");
374
- const ARRAY_ITERATE_KEY2 = /* @__PURE__ */ Symbol("arrayIterate");
375
- const iterationKey = Array.isArray(target) ? ARRAY_ITERATE_KEY2 : ITERATE_KEY;
376
- const iterationDep = depsMap.get(iterationKey);
377
- if (iterationDep) {
378
- iterationDep.forEach((effect2) => effects.add(effect2));
379
- }
391
+ const iterationKey = Array.isArray(target) ? ARRAY_ITERATE_KEY : ITERATE_KEY;
392
+ collectTriggeredEffects(depsMap.get(iterationKey), effects, version);
380
393
  }
381
- effects.forEach((effect2) => {
382
- var _a5;
394
+ for (const effect2 of effects) {
383
395
  if (shared.isFunction(effect2.onTrigger)) {
384
396
  effect2.onTrigger({
385
397
  effect: effect2,
@@ -397,7 +409,7 @@ function trigger(target, type, key, newValue) {
397
409
  propagate(effect2.subLink);
398
410
  }
399
411
  }
400
- });
412
+ }
401
413
  }
402
414
  var reactiveCaches = /* @__PURE__ */ new WeakMap();
403
415
  function toRaw(value) {
@@ -445,8 +457,7 @@ function createArrayInstrumentations() {
445
457
  instrumentations[key] = function(...args) {
446
458
  const arr = toRaw(this);
447
459
  const res = Array.prototype[key].apply(arr, args);
448
- trigger(arr, TriggerOpTypes.SET, ARRAY_KEY);
449
- trigger(arr, TriggerOpTypes.SET, ARRAY_ITERATE_KEY);
460
+ trigger(arr, TriggerOpTypes.SET, [ARRAY_KEY, ARRAY_ITERATE_KEY]);
450
461
  return res;
451
462
  };
452
463
  }
@@ -472,8 +483,7 @@ function createArrayInstrumentations() {
472
483
  instrumentations[key] = function(...args) {
473
484
  const arr = toRaw(this);
474
485
  track(arr, ARRAY_ITERATE_KEY);
475
- const res = Array.prototype[key].apply(arr, args);
476
- return res;
486
+ return Array.prototype[key].apply(this, args);
477
487
  };
478
488
  });
479
489
  ["join", "toString", "toLocaleString"].forEach((key) => {
@@ -490,6 +500,9 @@ function createArrayInstrumentations() {
490
500
  track(arr, ARRAY_KEY);
491
501
  const rawIterator = key === Symbol.iterator ? arr[Symbol.iterator]() : arr[key]();
492
502
  return {
503
+ /**
504
+ * Returns the next iterator result.
505
+ */
493
506
  next() {
494
507
  const { value, done } = rawIterator.next();
495
508
  if (done) {
@@ -506,6 +519,9 @@ function createArrayInstrumentations() {
506
519
  done
507
520
  };
508
521
  },
522
+ /**
523
+ * Returns an iterator for the current collection.
524
+ */
509
525
  [Symbol.iterator]() {
510
526
  return this;
511
527
  }
@@ -554,6 +570,9 @@ var arrayHandlers = (shallow) => ({
554
570
  var shallowArrayHandlers = arrayHandlers(true);
555
571
  var deepArrayHandlers = arrayHandlers(false);
556
572
  var collectionHandlers = {
573
+ /**
574
+ * Exposes collection proxy flags and instrumented methods.
575
+ */
557
576
  get(target, key) {
558
577
  if (key === "_IS_REACTIVE" /* IS_REACTIVE */) {
559
578
  return true;
@@ -569,6 +588,9 @@ var collectionHandlers = {
569
588
  }
570
589
  };
571
590
  var weakCollectionHandlers = {
591
+ /**
592
+ * Exposes weak-collection proxy flags and instrumented methods.
593
+ */
572
594
  get(target, key) {
573
595
  if (key === "_IS_REACTIVE" /* IS_REACTIVE */) {
574
596
  return true;
@@ -584,6 +606,9 @@ var weakCollectionHandlers = {
584
606
  }
585
607
  };
586
608
  var collectionInstrumentations = {
609
+ /**
610
+ * Reads a Map entry with dependency tracking.
611
+ */
587
612
  get(key) {
588
613
  const target = toRaw(this);
589
614
  track(target, COLLECTION_KEY);
@@ -593,6 +618,9 @@ var collectionInstrumentations = {
593
618
  }
594
619
  return value;
595
620
  },
621
+ /**
622
+ * Sets the requested value.
623
+ */
596
624
  set(key, value) {
597
625
  const target = toRaw(this);
598
626
  const hadKey = target.has(key);
@@ -604,6 +632,9 @@ var collectionInstrumentations = {
604
632
  }
605
633
  return this;
606
634
  },
635
+ /**
636
+ * Adds the requested value.
637
+ */
607
638
  add(value) {
608
639
  const target = toRaw(this);
609
640
  const rawValue = toRaw(value);
@@ -611,11 +642,12 @@ var collectionInstrumentations = {
611
642
  target.add(rawValue);
612
643
  if (!hadValue) {
613
644
  trigger(target, TriggerOpTypes.ADD, COLLECTION_KEY);
614
- } else {
615
- trigger(target, TriggerOpTypes.SET, COLLECTION_KEY);
616
645
  }
617
646
  return this;
618
647
  },
648
+ /**
649
+ * Returns whether the requested value exists.
650
+ */
619
651
  has(key) {
620
652
  const target = toRaw(this);
621
653
  track(target, COLLECTION_KEY);
@@ -625,6 +657,9 @@ var collectionInstrumentations = {
625
657
  }
626
658
  return hasKey;
627
659
  },
660
+ /**
661
+ * Deletes the requested value.
662
+ */
628
663
  delete(key) {
629
664
  const target = toRaw(this);
630
665
  const hadKey = target.has(key);
@@ -637,6 +672,9 @@ var collectionInstrumentations = {
637
672
  }
638
673
  return result;
639
674
  },
675
+ /**
676
+ * Clears the current collection.
677
+ */
640
678
  clear() {
641
679
  const target = toRaw(this);
642
680
  const hadItems = target.size > 0;
@@ -646,6 +684,9 @@ var collectionInstrumentations = {
646
684
  }
647
685
  return result;
648
686
  },
687
+ /**
688
+ * Iterates over each collection entry.
689
+ */
649
690
  forEach(callback, thisArg) {
650
691
  const target = toRaw(this);
651
692
  const isShallowMode = isShallow(this);
@@ -656,12 +697,18 @@ var collectionInstrumentations = {
656
697
  callback.call(thisArg, wrappedValue, wrappedKey, this);
657
698
  });
658
699
  },
700
+ /**
701
+ * Returns an iterator for the current collection.
702
+ */
659
703
  [Symbol.iterator]() {
660
704
  const target = toRaw(this);
661
705
  const isShallowMode = isShallow(this);
662
706
  track(target, COLLECTION_KEY);
663
707
  const rawIterator = target[Symbol.iterator]();
664
708
  return {
709
+ /**
710
+ * Returns the next iterator result.
711
+ */
665
712
  next() {
666
713
  const { value, done } = rawIterator.next();
667
714
  if (done) {
@@ -681,22 +728,34 @@ var collectionInstrumentations = {
681
728
  done
682
729
  };
683
730
  },
731
+ /**
732
+ * Returns an iterator for the current collection.
733
+ */
684
734
  [Symbol.iterator]() {
685
735
  return this;
686
736
  }
687
737
  };
688
738
  },
739
+ /**
740
+ * Returns the current collection size.
741
+ */
689
742
  get size() {
690
743
  const target = toRaw(this);
691
744
  track(target, COLLECTION_KEY);
692
745
  return target.size;
693
746
  },
747
+ /**
748
+ * Returns an iterator over the current keys.
749
+ */
694
750
  keys() {
695
751
  const target = toRaw(this);
696
752
  const isShallowMode = isShallow(this);
697
753
  track(target, COLLECTION_KEY);
698
754
  const rawIterator = target.keys();
699
755
  return {
756
+ /**
757
+ * Returns the next iterator result.
758
+ */
700
759
  next() {
701
760
  const { value, done } = rawIterator.next();
702
761
  if (done) {
@@ -707,17 +766,26 @@ var collectionInstrumentations = {
707
766
  done
708
767
  };
709
768
  },
769
+ /**
770
+ * Returns an iterator for the current collection.
771
+ */
710
772
  [Symbol.iterator]() {
711
773
  return this;
712
774
  }
713
775
  };
714
776
  },
777
+ /**
778
+ * Returns an iterator over the current values.
779
+ */
715
780
  values() {
716
781
  const target = toRaw(this);
717
782
  const isShallowMode = isShallow(this);
718
783
  track(target, COLLECTION_KEY);
719
784
  const rawIterator = target.values();
720
785
  return {
786
+ /**
787
+ * Returns the next iterator result.
788
+ */
721
789
  next() {
722
790
  const { value, done } = rawIterator.next();
723
791
  if (done) {
@@ -728,17 +796,26 @@ var collectionInstrumentations = {
728
796
  done
729
797
  };
730
798
  },
799
+ /**
800
+ * Returns an iterator for the current collection.
801
+ */
731
802
  [Symbol.iterator]() {
732
803
  return this;
733
804
  }
734
805
  };
735
806
  },
807
+ /**
808
+ * Returns an iterator over the current entries.
809
+ */
736
810
  entries() {
737
811
  const target = toRaw(this);
738
812
  const isShallowMode = isShallow(this);
739
813
  track(target, COLLECTION_KEY);
740
814
  const rawIterator = target.entries();
741
815
  return {
816
+ /**
817
+ * Returns the next iterator result.
818
+ */
742
819
  next() {
743
820
  const { value, done } = rawIterator.next();
744
821
  if (done) {
@@ -752,6 +829,9 @@ var collectionInstrumentations = {
752
829
  done
753
830
  };
754
831
  },
832
+ /**
833
+ * Returns an iterator for the current collection.
834
+ */
755
835
  [Symbol.iterator]() {
756
836
  return this;
757
837
  }
@@ -759,6 +839,9 @@ var collectionInstrumentations = {
759
839
  }
760
840
  };
761
841
  var weakInstrumentations = {
842
+ /**
843
+ * Reads a WeakMap entry with dependency tracking.
844
+ */
762
845
  get(key) {
763
846
  const target = toRaw(this);
764
847
  track(target, WEAK_COLLECTION_KEY);
@@ -771,6 +854,9 @@ var weakInstrumentations = {
771
854
  }
772
855
  return value;
773
856
  },
857
+ /**
858
+ * Sets the requested value.
859
+ */
774
860
  set(key, value) {
775
861
  const target = toRaw(this);
776
862
  const rawKey = toRaw(key);
@@ -783,6 +869,9 @@ var weakInstrumentations = {
783
869
  }
784
870
  return this;
785
871
  },
872
+ /**
873
+ * Adds the requested value.
874
+ */
786
875
  add(value) {
787
876
  const target = toRaw(this);
788
877
  const rawValue = toRaw(value);
@@ -793,6 +882,9 @@ var weakInstrumentations = {
793
882
  }
794
883
  return this;
795
884
  },
885
+ /**
886
+ * Returns whether the requested value exists.
887
+ */
796
888
  has(key) {
797
889
  const target = toRaw(this);
798
890
  track(target, WEAK_COLLECTION_KEY);
@@ -802,6 +894,9 @@ var weakInstrumentations = {
802
894
  }
803
895
  return hasKey;
804
896
  },
897
+ /**
898
+ * Deletes the requested value.
899
+ */
805
900
  delete(key) {
806
901
  const target = toRaw(this);
807
902
  const rawKey = toRaw(key);
@@ -814,6 +909,9 @@ var weakInstrumentations = {
814
909
  }
815
910
  };
816
911
  var objectHandlers = (shallow) => ({
912
+ /**
913
+ * Reads an object property, unwraps signals, and tracks the access.
914
+ */
817
915
  get(target, key, receiver) {
818
916
  if (key === "_RAW" /* RAW */) {
819
917
  return target;
@@ -849,6 +947,8 @@ var objectHandlers = (shallow) => ({
849
947
  return result;
850
948
  }
851
949
  });
950
+ var shallowObjectHandlers = objectHandlers(true);
951
+ var deepObjectHandlers = objectHandlers(false);
852
952
  function reactiveImpl(target, shallow = false) {
853
953
  if (!shared.isObject(target)) {
854
954
  return target;
@@ -868,7 +968,7 @@ function reactiveImpl(target, shallow = false) {
868
968
  } else if (shared.isWeakMap(target) || shared.isWeakSet(target)) {
869
969
  handler = weakCollectionHandlers;
870
970
  } else {
871
- handler = objectHandlers(shallow);
971
+ handler = shallow ? shallowObjectHandlers : deepObjectHandlers;
872
972
  }
873
973
  const proxy = new Proxy(target, handler);
874
974
  reactiveCaches.set(target, proxy);
@@ -916,18 +1016,32 @@ var SignalImpl = class {
916
1016
  // Mark whether it's shallow reactive
917
1017
  // @ts-ignore
918
1018
  this[_a] = true;
919
- this._rawValue = value;
920
- if (shallow) {
921
- this._value = shared.isObject(value) ? shallowReactive(value) : value;
1019
+ const unwrapped = toRaw(value);
1020
+ this._rawValue = unwrapped;
1021
+ this["_IS_SHALLOW" /* IS_SHALLOW */] = shallow;
1022
+ if (!shouldWrapReactiveValue(unwrapped)) {
1023
+ this._value = unwrapped;
922
1024
  } else {
923
- this._value = shared.isObject(value) ? reactive(value) : value;
1025
+ if (isReactive(value)) {
1026
+ this._value = value;
1027
+ } else {
1028
+ this._value = shallow ? shallowReactive(unwrapped) : reactive(unwrapped);
1029
+ }
924
1030
  }
925
- this["_IS_SHALLOW" /* IS_SHALLOW */] = shallow;
926
1031
  }
927
- // dep getter, returns itself for dependency collection
1032
+ /**
1033
+ * Returns the dependency node used for tracking.
1034
+ *
1035
+ * @returns {this} The dependency node.
1036
+ */
928
1037
  get dep() {
929
1038
  return this;
930
1039
  }
1040
+ /**
1041
+ * Returns the current value.
1042
+ *
1043
+ * @returns {T} The current value.
1044
+ */
931
1045
  get value() {
932
1046
  const sub = activeSub;
933
1047
  if (sub) {
@@ -942,38 +1056,46 @@ var SignalImpl = class {
942
1056
  }
943
1057
  return this._value;
944
1058
  }
945
- // value setter, triggers update when value changes
946
- set value(value) {
947
- if (isSignal(value)) {
1059
+ /**
1060
+ * Updates the current value.
1061
+ *
1062
+ * @param newValue - The new value to set.
1063
+ */
1064
+ set value(newValue) {
1065
+ if (isSignal(newValue)) {
948
1066
  {
949
1067
  shared.warn(
950
1068
  "Setting a signal value to another signal is not recommended. The value will be unwrapped automatically."
951
1069
  );
952
1070
  }
953
- value = value.peek();
1071
+ newValue = newValue.peek();
954
1072
  }
955
- value = toRaw(value);
956
- if (!shared.hasChanged(this._rawValue, value)) {
1073
+ const originalValue = newValue;
1074
+ const rawValue = toRaw(newValue);
1075
+ if (!shared.hasChanged(this._rawValue, rawValue)) {
957
1076
  return;
958
1077
  }
959
- if (!("_oldValue" in this)) {
960
- this._oldValue = this._rawValue;
961
- }
962
- const flags = this.flag;
963
- this.flag = flags | 16 /* DIRTY */;
964
- this._rawValue = value;
965
- const shallow = this["_IS_SHALLOW" /* IS_SHALLOW */];
966
- if (shallow) {
967
- this._value = shared.isObject(value) ? shallowReactive(value) : value;
1078
+ this._oldValue = this._rawValue;
1079
+ this._rawValue = rawValue;
1080
+ this.flag |= 16 /* DIRTY */;
1081
+ if (!shouldWrapReactiveValue(rawValue)) {
1082
+ this._value = rawValue;
1083
+ } else if (isReactive(originalValue)) {
1084
+ this._value = originalValue;
968
1085
  } else {
969
- this._value = shared.isObject(value) ? reactive(value) : value;
1086
+ const shallow = this["_IS_SHALLOW" /* IS_SHALLOW */];
1087
+ this._value = shallow ? shallowReactive(rawValue) : reactive(rawValue);
970
1088
  }
971
1089
  const subs = this.subLink;
972
1090
  if (subs) {
973
1091
  propagate(subs);
974
1092
  }
975
1093
  }
976
- // Check if the value should be update
1094
+ /**
1095
+ * Check if the value should be updated.
1096
+ *
1097
+ * @returns {boolean} True if the value should be updated.
1098
+ */
977
1099
  shouldUpdate() {
978
1100
  this.flag &= -17 /* DIRTY */;
979
1101
  if (!("_oldValue" in this)) {
@@ -983,15 +1105,29 @@ var SignalImpl = class {
983
1105
  this._oldValue = this._rawValue;
984
1106
  return changed;
985
1107
  }
986
- // Get current value without triggering dependency tracking
1108
+ /**
1109
+ * Get current value without triggering dependency tracking.
1110
+ *
1111
+ * @returns {T} The current value.
1112
+ */
987
1113
  peek() {
988
1114
  return this._value;
989
1115
  }
990
- // set method is an alias for the value setter
1116
+ /**
1117
+ * Sets the requested value.
1118
+ *
1119
+ * @param value - The new value to set.
1120
+ * @returns {void}
1121
+ */
991
1122
  set(value) {
992
1123
  this.value = value;
993
1124
  }
994
- // Update value using an updater function
1125
+ /**
1126
+ * Update value using an updater function.
1127
+ *
1128
+ * @param updater - A function that receives the current value and returns the new value.
1129
+ * @returns {void}
1130
+ */
995
1131
  update(updater) {
996
1132
  const nextValue = updater(this.peek());
997
1133
  if (isSignal(nextValue)) {
@@ -1006,6 +1142,10 @@ var SignalImpl = class {
1006
1142
  }
1007
1143
  }
1008
1144
  };
1145
+ function shouldWrapReactiveValue(value) {
1146
+ if (!shared.isObject(value)) return false;
1147
+ return shared.isArray(value) || shared.isMap(value) || shared.isSet(value) || shared.isWeakMap(value) || shared.isWeakSet(value) || shared.isPlainObject(value);
1148
+ }
1009
1149
  function signal(value) {
1010
1150
  if (isSignal(value)) {
1011
1151
  {
@@ -1031,19 +1171,7 @@ var activePreFlushCbs = /* @__PURE__ */ new Set();
1031
1171
  var p = Promise.resolve();
1032
1172
  var isFlushPending = false;
1033
1173
  function nextTick(fn) {
1034
- if (fn) {
1035
- return new Promise((resolve, reject) => {
1036
- queueMicrotask(() => {
1037
- try {
1038
- fn();
1039
- resolve();
1040
- } catch (error5) {
1041
- reject(error5);
1042
- }
1043
- });
1044
- });
1045
- }
1046
- return p;
1174
+ return fn ? p.then(fn) : p;
1047
1175
  }
1048
1176
  function queueJob(job) {
1049
1177
  queue.add(job);
@@ -1063,9 +1191,7 @@ function flushJobs() {
1063
1191
  isFlushPending = false;
1064
1192
  flushPreFlushCbs();
1065
1193
  while (queue.size > 0) {
1066
- const jobs = Array.from(queue);
1067
- queue.clear();
1068
- for (const job of jobs) {
1194
+ for (const job of queue) {
1069
1195
  try {
1070
1196
  job();
1071
1197
  } catch (_error) {
@@ -1074,6 +1200,7 @@ function flushJobs() {
1074
1200
  }
1075
1201
  }
1076
1202
  }
1203
+ queue.clear();
1077
1204
  }
1078
1205
  }
1079
1206
  function flushPreFlushCbs() {
@@ -1142,10 +1269,10 @@ var _a2;
1142
1269
  _a2 = "_IS_EFFECT" /* IS_EFFECT */;
1143
1270
  var EffectImpl = class {
1144
1271
  /**
1145
- * Create an Effect instance
1272
+ * Create an Effect instance.
1146
1273
  *
1147
- * @param fn - The effect function
1148
- * @param options - Configuration options
1274
+ * @param fn - The effect function.
1275
+ * @param options - Configuration options.
1149
1276
  */
1150
1277
  constructor(fn, options) {
1151
1278
  this.flag = 2 /* WATCHING */ | 16 /* DIRTY */;
@@ -1155,22 +1282,30 @@ var EffectImpl = class {
1155
1282
  this._active = true;
1156
1283
  this.fn = fn;
1157
1284
  if (options) {
1158
- this.scheduler = options.flush || options.scheduler;
1159
- this.onStop = options.onStop;
1160
- this.onTrack = options.onTrack;
1161
- this.onTrigger = options.onTrigger;
1285
+ this.options = options;
1286
+ const scheduler = options.flush || options.scheduler;
1287
+ if (scheduler && !shared.isFunction(scheduler)) {
1288
+ this._flushScheduler = createScheduler(() => this.run(), scheduler);
1289
+ }
1290
+ {
1291
+ if (options.onTrack) this.onTrack = options.onTrack;
1292
+ if (options.onTrigger) this.onTrigger = options.onTrigger;
1293
+ }
1162
1294
  }
1163
1295
  }
1164
1296
  /**
1165
- * Check if the Effect is active
1297
+ * Check if the Effect is active.
1298
+ *
1299
+ * @returns {boolean} True if the effect is active.
1166
1300
  */
1167
1301
  get active() {
1168
1302
  return this._active;
1169
1303
  }
1170
1304
  /**
1171
- * Check if the Effect is dirty (needs re-execution)
1172
-
1173
- */
1305
+ * Check if the Effect is dirty (needs re-execution).
1306
+ *
1307
+ * @returns {boolean} True if the effect is dirty.
1308
+ */
1174
1309
  get dirty() {
1175
1310
  const flags = this.flag;
1176
1311
  if (flags & 16 /* DIRTY */) {
@@ -1186,57 +1321,39 @@ var EffectImpl = class {
1186
1321
  return false;
1187
1322
  }
1188
1323
  /**
1189
- * Pause Effect execution
1324
+ * Pause Effect execution.
1190
1325
  *
1191
1326
  * When an effect is paused:
1192
- * - It stops responding to dependency changes
1193
- * - Notifications are ignored (see notify method)
1194
- * - DIRTY and PENDING flags are still set when dependencies change
1195
- * - The effect remains active and maintains its dependency links
1327
+ * - It stops responding to dependency changes.
1328
+ * - Notifications are ignored (see notify method).
1329
+ * - DIRTY and PENDING flags are still set when dependencies change.
1330
+ * - The effect remains active and maintains its dependency links.
1196
1331
  *
1197
1332
  * Use cases:
1198
- * - Temporarily disable effects during bulk updates
1199
- * - Prevent effects from running during initialization
1200
- * - Control when side effects should execute
1201
- *
1202
- * @example
1203
- * ```typescript
1204
- * const count = signal(0);
1205
- * const runner = effect(() => console.log(count.value));
1333
+ * - Temporarily disable effects during bulk updates.
1334
+ * - Prevent effects from running during initialization.
1335
+ * - Control when side effects should execute.
1206
1336
  *
1207
- * runner.effect.pause();
1208
- * count.value = 1; // Effect won't run
1209
- * count.value = 2; // Effect won't run
1210
- * runner.effect.resume(); // Effect runs once with latest value
1211
- * ```
1337
+ * @returns {void}
1212
1338
  */
1213
1339
  pause() {
1214
1340
  this.flag |= 256 /* PAUSED */;
1215
1341
  }
1216
1342
  /**
1217
- * Resume Effect execution
1343
+ * Resume Effect execution.
1218
1344
  *
1219
1345
  * When an effect is resumed:
1220
- * - The PAUSED flag is cleared
1346
+ * - The PAUSED flag is cleared.
1221
1347
  * - If dependencies changed during pause (DIRTY or PENDING flags set),
1222
- * the effect executes immediately via notify()
1223
- * - If no changes occurred, the effect simply becomes active again
1348
+ * the effect executes immediately via notify().
1349
+ * - If no changes occurred, the effect simply becomes active again.
1224
1350
  *
1225
1351
  * State management:
1226
- * - Clears PAUSED flag atomically
1227
- * - Checks for accumulated DIRTY/PENDING flags
1228
- * - Triggers execution if needed
1352
+ * - Clears PAUSED flag atomically.
1353
+ * - Checks for accumulated DIRTY/PENDING flags.
1354
+ * - Triggers execution if needed.
1229
1355
  *
1230
- * @example
1231
- * ```typescript
1232
- * const count = signal(0);
1233
- * const runner = effect(() => console.log(count.value));
1234
- *
1235
- * runner.effect.pause();
1236
- * count.value = 1; // Queued
1237
- * count.value = 2; // Queued
1238
- * runner.effect.resume(); // Executes once with count.value = 2
1239
- * ```
1356
+ * @returns {void}
1240
1357
  */
1241
1358
  resume() {
1242
1359
  const flags = this.flag;
@@ -1249,23 +1366,23 @@ var EffectImpl = class {
1249
1366
  }
1250
1367
  }
1251
1368
  /**
1252
- * Execute the Effect function
1253
- *
1254
- * Core execution flow:
1255
- * 1. Check if active
1256
- * 2. Clear dirty flag
1257
- * 3. Start tracking dependencies
1258
- * 4. Execute user function
1259
- * 5. End tracking, clean up stale dependencies
1260
-
1261
- * @returns The return value of the effect function
1262
- */
1369
+ * Execute the Effect function.
1370
+ *
1371
+ * Core execution flow:
1372
+ * 1. Check if active
1373
+ * 2. Clear dirty flag
1374
+ * 3. Start tracking dependencies
1375
+ * 4. Execute user function
1376
+ * 5. End tracking, clean up stale dependencies
1377
+ *
1378
+ * @returns {T} The return value of the effect function.
1379
+ */
1263
1380
  run() {
1264
1381
  if (!this._active) {
1265
1382
  return this.fn();
1266
1383
  }
1267
1384
  const flags = this.flag;
1268
- this.flag = flags & -17 /* DIRTY */ | 1024 /* STOP */;
1385
+ this.flag = flags & -49 | 512 /* RUNNING */;
1269
1386
  const prevSub = startTracking(this);
1270
1387
  try {
1271
1388
  return this.fn();
@@ -1273,12 +1390,14 @@ var EffectImpl = class {
1273
1390
  this.flag |= 16 /* DIRTY */;
1274
1391
  throw error5;
1275
1392
  } finally {
1276
- this.flag &= -1025 /* STOP */;
1393
+ this.flag &= -513 /* RUNNING */;
1277
1394
  endTracking(this, prevSub);
1278
1395
  }
1279
1396
  }
1280
1397
  /**
1281
- * Get or create the job function for this effect
1398
+ * Get or create the job function for this effect.
1399
+ *
1400
+ * @returns {() => void} The job function.
1282
1401
  */
1283
1402
  getJob() {
1284
1403
  if (!this._job) {
@@ -1287,30 +1406,33 @@ var EffectImpl = class {
1287
1406
  return this._job;
1288
1407
  }
1289
1408
  /**
1290
- * Notify that the Effect needs to execute
1409
+ * Notify that the Effect needs to execute.
1291
1410
  *
1292
1411
  * Called by dependent reactive values.
1293
1412
  * Decides whether to execute immediately or defer based on scheduling strategy.
1413
+ *
1414
+ * @returns {void}
1294
1415
  */
1295
1416
  notify() {
1417
+ var _a5, _b2, _c, _d;
1296
1418
  const flags = this.flag;
1297
- if (!this._active || flags & (256 /* PAUSED */ | 1024 /* STOP */ | 16 /* DIRTY */)) {
1419
+ if (!this._active || flags & (256 /* PAUSED */ | 512 /* RUNNING */ | 16 /* DIRTY */)) {
1298
1420
  return;
1299
1421
  }
1300
1422
  this.flag = flags | 16 /* DIRTY */;
1301
- if (this.onTrigger) {
1302
- this.onTrigger({
1423
+ if ((_a5 = this.options) == null ? void 0 : _a5.onTrigger) {
1424
+ this.options.onTrigger({
1303
1425
  effect: this,
1304
1426
  target: {},
1305
1427
  type: "set"
1306
1428
  });
1307
1429
  }
1308
- if (this.scheduler) {
1309
- if (shared.isFunction(this.scheduler)) {
1310
- this.scheduler(this);
1430
+ const scheduler = ((_b2 = this.options) == null ? void 0 : _b2.flush) || ((_c = this.options) == null ? void 0 : _c.scheduler);
1431
+ if (scheduler) {
1432
+ if (shared.isFunction(scheduler)) {
1433
+ scheduler(this);
1311
1434
  } else {
1312
- const schedulerFn = createScheduler(() => this.run(), this.scheduler);
1313
- schedulerFn();
1435
+ (_d = this._flushScheduler) == null ? void 0 : _d.call(this);
1314
1436
  }
1315
1437
  } else if (isBatching()) {
1316
1438
  queueJob(this.getJob());
@@ -1319,16 +1441,19 @@ var EffectImpl = class {
1319
1441
  }
1320
1442
  }
1321
1443
  /**
1322
- * Stop the Effect
1444
+ * Stop the Effect.
1323
1445
  *
1324
1446
  * After stopping:
1325
- * - No longer responds to dependency changes
1326
- * - Disconnects all dependency links
1327
- * - Clears cached job function
1328
- * - Calls onStop callback
1329
- * - Verifies complete cleanup in development mode
1447
+ * - No longer responds to dependency changes.
1448
+ * - Disconnects all dependency links.
1449
+ * - Clears cached job function.
1450
+ * - Calls onStop callback.
1451
+ * - Verifies complete cleanup in development mode.
1452
+ *
1453
+ * @returns {void}
1330
1454
  */
1331
1455
  stop() {
1456
+ var _a5;
1332
1457
  if (!this._active) {
1333
1458
  {
1334
1459
  shared.warn("[Effect] Attempting to stop an already stopped effect.");
@@ -1345,6 +1470,7 @@ var EffectImpl = class {
1345
1470
  sub = unlinkReactiveNode(sub);
1346
1471
  }
1347
1472
  this._job = void 0;
1473
+ this._flushScheduler = void 0;
1348
1474
  this.depLinkTail = void 0;
1349
1475
  this.subLinkTail = void 0;
1350
1476
  {
@@ -1359,8 +1485,8 @@ var EffectImpl = class {
1359
1485
  );
1360
1486
  }
1361
1487
  }
1362
- if (this.onStop) {
1363
- this.onStop();
1488
+ if ((_a5 = this.options) == null ? void 0 : _a5.onStop) {
1489
+ this.options.onStop();
1364
1490
  }
1365
1491
  }
1366
1492
  };
@@ -1402,12 +1528,12 @@ var _a3;
1402
1528
  _a3 = "_IS_COMPUTED" /* IS_COMPUTED */;
1403
1529
  var ComputedImpl = class {
1404
1530
  /**
1405
- * Create a Computed instance
1531
+ * Create a Computed instance.
1406
1532
  *
1407
- * @param getter - The computation function
1408
- * @param setter - Optional setter function
1409
- * @param onTrack - Optional debug callback for dependency tracking
1410
- * @param onTrigger - Optional debug callback for triggers
1533
+ * @param getter - The computation function.
1534
+ * @param setter - Optional setter function.
1535
+ * @param onTrack - Optional debug callback for dependency tracking.
1536
+ * @param onTrigger - Optional debug callback for triggers.
1411
1537
  */
1412
1538
  constructor(getter, setter, onTrack, onTrigger) {
1413
1539
  this.flag = 1 /* MUTABLE */ | 16 /* DIRTY */;
@@ -1422,6 +1548,11 @@ var ComputedImpl = class {
1422
1548
  this.onTrigger = onTrigger;
1423
1549
  this.flag |= 16 /* DIRTY */;
1424
1550
  }
1551
+ /**
1552
+ * Returns the current value.
1553
+ *
1554
+ * @returns {T} The current value.
1555
+ */
1425
1556
  get value() {
1426
1557
  if (activeSub) {
1427
1558
  linkReactiveNode(this, activeSub);
@@ -1445,9 +1576,9 @@ var ComputedImpl = class {
1445
1576
  return this._value;
1446
1577
  }
1447
1578
  /**
1448
- * Set value (only effective when setter is provided)
1579
+ * Set value (only effective when setter is provided).
1449
1580
  *
1450
- * @param newValue - The new value
1581
+ * @param newValue - The new value.
1451
1582
  */
1452
1583
  set value(newValue) {
1453
1584
  if (this.setter) {
@@ -1459,9 +1590,9 @@ var ComputedImpl = class {
1459
1590
  }
1460
1591
  }
1461
1592
  /**
1462
- * Read value without tracking dependencies
1593
+ * Read value without tracking dependencies.
1463
1594
  *
1464
- * @returns Current value
1595
+ * @returns {T} The current value.
1465
1596
  */
1466
1597
  peek() {
1467
1598
  if (this._value === NO_VALUE) {
@@ -1511,7 +1642,7 @@ var ComputedImpl = class {
1511
1642
  } catch (_error) {
1512
1643
  const clearMask = -49;
1513
1644
  this.flag &= clearMask;
1514
- this.flag |= 16 /* DIRTY */;
1645
+ this._value = NO_VALUE;
1515
1646
  {
1516
1647
  shared.error(
1517
1648
  "[Computed] Error occurred while computing value.\nThe computed will retry on next access.\nCommon causes:\n - Accessing undefined properties\n - Circular dependencies\n - Exceptions in getter function\nCheck your getter function for errors.",
@@ -1524,11 +1655,11 @@ var ComputedImpl = class {
1524
1655
  }
1525
1656
  }
1526
1657
  /**
1527
- * Check if update is needed
1658
+ * Check if update is needed.
1528
1659
  *
1529
1660
  * Internal use, called by reactive system.
1530
1661
  *
1531
- * @returns true if value changed
1662
+ * @returns {boolean} True if value changed.
1532
1663
  */
1533
1664
  shouldUpdate() {
1534
1665
  const hadValue = this._value !== NO_VALUE;
@@ -1595,6 +1726,9 @@ function createOptionsStore(options) {
1595
1726
  actionCallbacks.forEach((callback) => callback(state2));
1596
1727
  };
1597
1728
  const defaultActions = {
1729
+ /**
1730
+ * Applies a partial patch to the reactive store state.
1731
+ */
1598
1732
  patch$(payload) {
1599
1733
  if (!payload) {
1600
1734
  shared.warn("Patch payload is required");
@@ -1605,6 +1739,9 @@ function createOptionsStore(options) {
1605
1739
  });
1606
1740
  notifySubscribers(reactiveState);
1607
1741
  },
1742
+ /**
1743
+ * Registers a store subscriber callback.
1744
+ */
1608
1745
  subscribe$(callback) {
1609
1746
  if (!callback) {
1610
1747
  shared.warn("Subscribe callback is required");
@@ -1612,9 +1749,15 @@ function createOptionsStore(options) {
1612
1749
  }
1613
1750
  subscriptions.add(callback);
1614
1751
  },
1752
+ /**
1753
+ * Removes a previously registered store subscriber.
1754
+ */
1615
1755
  unsubscribe$(callback) {
1616
1756
  subscriptions.delete(callback);
1617
1757
  },
1758
+ /**
1759
+ * Registers a callback for store action notifications.
1760
+ */
1618
1761
  onAction$(callback) {
1619
1762
  if (!callback) {
1620
1763
  shared.warn("Action callback is required");
@@ -1622,6 +1765,15 @@ function createOptionsStore(options) {
1622
1765
  }
1623
1766
  actionCallbacks.add(callback);
1624
1767
  },
1768
+ /**
1769
+ * Removes a previously registered action callback.
1770
+ */
1771
+ offAction$(callback) {
1772
+ actionCallbacks.delete(callback);
1773
+ },
1774
+ /**
1775
+ * Resets the reactive state back to its initial snapshot.
1776
+ */
1625
1777
  reset$() {
1626
1778
  batch(() => {
1627
1779
  Object.assign(reactiveState, initState);
@@ -1629,34 +1781,34 @@ function createOptionsStore(options) {
1629
1781
  notifySubscribers(reactiveState);
1630
1782
  }
1631
1783
  };
1632
- const store = __spreadValues(__spreadProps(__spreadValues({}, reactiveState), {
1633
- state: reactiveState
1634
- }), defaultActions);
1784
+ const store = {};
1785
+ for (const key of Object.keys(initState)) {
1786
+ Object.defineProperty(store, key, {
1787
+ get: () => reactiveState[key],
1788
+ set: (value) => {
1789
+ reactiveState[key] = value;
1790
+ },
1791
+ enumerable: true,
1792
+ configurable: true
1793
+ });
1794
+ }
1795
+ Object.defineProperty(store, "state", {
1796
+ value: reactiveState,
1797
+ enumerable: true,
1798
+ configurable: true,
1799
+ writable: true
1800
+ });
1801
+ Object.assign(store, defaultActions);
1635
1802
  if (getters) {
1636
1803
  for (const key in getters) {
1637
1804
  const getter = getters[key];
1638
- if (getter) {
1639
- let accessCount = 0;
1640
- let lastWarnTime = 0;
1641
- Object.defineProperty(store, key, {
1642
- get() {
1643
- {
1644
- accessCount++;
1645
- const now = Date.now();
1646
- if (accessCount > 100 && now - lastWarnTime > 1e3) {
1647
- shared.warn(
1648
- `Getter '${key}' has been accessed ${accessCount} times. Consider caching the result if the value is used frequently. Note: Getters are computed properties that recalculate on every access.`
1649
- );
1650
- lastWarnTime = now;
1651
- accessCount = 0;
1652
- }
1653
- }
1654
- return computed(() => getter.call(store, reactiveState)).value;
1655
- },
1656
- enumerable: true,
1657
- configurable: true
1658
- });
1659
- }
1805
+ if (!getter) continue;
1806
+ const getterValue = computed(() => getter.call(store, reactiveState));
1807
+ Object.defineProperty(store, key, {
1808
+ get: () => getterValue.value,
1809
+ enumerable: true,
1810
+ configurable: true
1811
+ });
1660
1812
  }
1661
1813
  }
1662
1814
  if (actions) {
@@ -1664,7 +1816,7 @@ function createOptionsStore(options) {
1664
1816
  const action = actions[key];
1665
1817
  if (action) {
1666
1818
  store[key] = (...args) => {
1667
- const result = action.apply(reactiveState, args);
1819
+ const result = action.apply(store, args);
1668
1820
  actionCallbacks.forEach((callback) => callback(reactiveState));
1669
1821
  return result;
1670
1822
  };
@@ -1684,11 +1836,11 @@ function createClassStore(StoreClass) {
1684
1836
  Object.getOwnPropertyNames(StoreClass.prototype).forEach((key) => {
1685
1837
  const descriptor = Object.getOwnPropertyDescriptor(StoreClass.prototype, key);
1686
1838
  if (descriptor) {
1687
- if (typeof descriptor.get === "function") {
1839
+ if (shared.isFunction(descriptor.get)) {
1688
1840
  getters[key] = function() {
1689
1841
  return descriptor.get.call(this);
1690
1842
  };
1691
- } else if (typeof descriptor.value === "function" && key !== "constructor") {
1843
+ } else if (shared.isFunction(descriptor.value) && key !== "constructor") {
1692
1844
  actions[key] = function(...args) {
1693
1845
  return descriptor.value.apply(this, args);
1694
1846
  };
@@ -1708,18 +1860,12 @@ function createStore(storeDefinition) {
1708
1860
  }
1709
1861
  return () => {
1710
1862
  let options;
1711
- if (typeof storeDefinition === "function") {
1863
+ if (shared.isFunction(storeDefinition)) {
1712
1864
  options = createClassStore(storeDefinition);
1713
1865
  } else {
1714
1866
  options = storeDefinition;
1715
1867
  }
1716
- const store = createOptionsStore(options);
1717
- if (typeof storeDefinition === "function") {
1718
- Object.keys(options.actions || {}).forEach((key) => {
1719
- store[key] = options.actions[key].bind(store);
1720
- });
1721
- }
1722
- return store;
1868
+ return createOptionsStore(options);
1723
1869
  };
1724
1870
  }
1725
1871
  var _a4, _b;
@@ -1734,23 +1880,37 @@ var RefImpl = class extends (_b = SignalImpl, _a4 = "_IS_REF" /* IS_REF */, _b)
1734
1880
  // @ts-ignore
1735
1881
  this[_a4] = true;
1736
1882
  }
1883
+ /**
1884
+ * Returns the current value.
1885
+ *
1886
+ * @returns {T} The current value.
1887
+ */
1737
1888
  get value() {
1738
- track(this, SIGNAL_KEY);
1889
+ const sub = activeSub;
1890
+ if (sub) {
1891
+ linkReactiveNode(this, sub);
1892
+ }
1739
1893
  return this._value;
1740
1894
  }
1895
+ /**
1896
+ * Updates the current value.
1897
+ *
1898
+ * @param newValue - The new value.
1899
+ */
1741
1900
  set value(newValue) {
1742
1901
  if (isSignal(newValue)) {
1743
- newValue = newValue.value;
1902
+ newValue = newValue.peek();
1744
1903
  }
1745
1904
  if (isRef(newValue)) {
1746
1905
  newValue = newValue.value;
1747
1906
  }
1748
1907
  if (shared.hasChanged(this._value, newValue)) {
1908
+ this._rawValue = newValue;
1749
1909
  this._value = newValue;
1910
+ this.flag |= 16 /* DIRTY */;
1750
1911
  if (this.subLink) {
1751
- shallowPropagate2(this.subLink);
1912
+ propagate(this.subLink);
1752
1913
  }
1753
- trigger(this, "SET", SIGNAL_KEY);
1754
1914
  }
1755
1915
  }
1756
1916
  };
@@ -1767,8 +1927,12 @@ function isRef(value) {
1767
1927
  return !!value && !!value["_IS_REF" /* IS_REF */];
1768
1928
  }
1769
1929
  var INITIAL_WATCHER_VALUE = {};
1770
- var cleanupMap = /* @__PURE__ */ new WeakMap();
1771
- function traverse(value, seen = /* @__PURE__ */ new Set()) {
1930
+ var _traverseSeen = /* @__PURE__ */ new Set();
1931
+ function traverse(value, seen) {
1932
+ if (!seen) {
1933
+ _traverseSeen.clear();
1934
+ seen = _traverseSeen;
1935
+ }
1772
1936
  if (!shared.isObject(value) || seen.has(value)) {
1773
1937
  return value;
1774
1938
  }
@@ -1799,54 +1963,13 @@ function traverse(value, seen = /* @__PURE__ */ new Set()) {
1799
1963
  return value;
1800
1964
  }
1801
1965
  function cloneValue(value) {
1802
- if (!shared.isObject(value)) {
1803
- return value;
1804
- }
1805
- if (Array.isArray(value)) {
1806
- return value.map((item) => cloneValue(item));
1807
- }
1808
- if (shared.isMap(value)) {
1809
- const cloned2 = /* @__PURE__ */ new Map();
1810
- value.forEach((v, k) => {
1811
- cloned2.set(k, cloneValue(v));
1812
- });
1813
- return cloned2;
1814
- }
1815
- if (shared.isSet(value)) {
1816
- const cloned2 = /* @__PURE__ */ new Set();
1817
- value.forEach((v) => {
1818
- cloned2.add(cloneValue(v));
1819
- });
1820
- return cloned2;
1821
- }
1822
- const cloned = {};
1823
- for (const key of Object.keys(value)) {
1824
- cloned[key] = cloneValue(value[key]);
1825
- }
1826
- return cloned;
1966
+ return value;
1827
1967
  }
1828
- function resolveSource(source) {
1829
- if (Array.isArray(source)) {
1830
- return () => source.map((s) => {
1831
- if (isSignal(s) || isComputed(s)) {
1832
- return s.value;
1833
- }
1834
- if (isReactive(s)) {
1835
- return traverse(s);
1836
- }
1837
- if (shared.isFunction(s)) {
1838
- return s();
1839
- }
1840
- return s;
1841
- });
1842
- }
1968
+ function resolveSingleSource(source) {
1843
1969
  if (shared.isFunction(source)) {
1844
1970
  return source;
1845
1971
  }
1846
- if (isSignal(source)) {
1847
- return () => source.value;
1848
- }
1849
- if (shared.isObject(source) && "value" in source) {
1972
+ if (isSignal(source) || isComputed(source)) {
1850
1973
  return () => source.value;
1851
1974
  }
1852
1975
  if (isReactive(source)) {
@@ -1854,6 +1977,13 @@ function resolveSource(source) {
1854
1977
  }
1855
1978
  return () => source;
1856
1979
  }
1980
+ function resolveSource(source) {
1981
+ if (Array.isArray(source)) {
1982
+ const getters = source.map((s) => resolveSingleSource(s));
1983
+ return () => getters.map((g) => g());
1984
+ }
1985
+ return resolveSingleSource(source);
1986
+ }
1857
1987
  function watch(source, callback, options = {}) {
1858
1988
  const { immediate = false, deep = false } = options;
1859
1989
  let oldValue = INITIAL_WATCHER_VALUE;
@@ -1864,7 +1994,7 @@ function watch(source, callback, options = {}) {
1864
1994
  return;
1865
1995
  }
1866
1996
  const newValue = currentEffect.run();
1867
- if (shared.hasChanged(newValue, oldValue)) {
1997
+ if (deep || shared.isObject(newValue) || shared.hasChanged(newValue, oldValue)) {
1868
1998
  callback(newValue, oldValue === INITIAL_WATCHER_VALUE ? void 0 : oldValue);
1869
1999
  oldValue = cloneValue(newValue);
1870
2000
  }
@@ -1889,11 +2019,6 @@ function watch(source, callback, options = {}) {
1889
2019
  }
1890
2020
  return () => {
1891
2021
  runner.stop();
1892
- const cleanups = cleanupMap.get(runner.effect);
1893
- if (cleanups) {
1894
- cleanups.forEach((fn) => fn());
1895
- cleanupMap.delete(runner.effect);
1896
- }
1897
2022
  };
1898
2023
  }
1899
2024