@estjs/signals 0.0.15-beta.13 → 0.0.15-beta.17

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