@estjs/signals 0.0.15-beta.8 → 0.0.15

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.
@@ -2,11 +2,6 @@
2
2
 
3
3
  var shared = require('@estjs/shared');
4
4
 
5
- /**
6
- * @estjs/signals v0.0.15-beta.8
7
- * (c) 2023-Present jiangxd <jiangxd2016@gmail.com>
8
- * @license MIT
9
- **/
10
5
  var __defProp = Object.defineProperty;
11
6
  var __defProps = Object.defineProperties;
12
7
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
@@ -34,58 +29,62 @@ var TriggerOpTypes = {
34
29
  DELETE: "DELETE",
35
30
  CLEAR: "CLEAR"
36
31
  };
37
- var SIGNAL_KEY = Symbol("Signal_Key" );
38
- var ARRAY_KEY = Symbol("Array_Key" );
39
- var COLLECTION_KEY = Symbol("Collection_Key" );
40
- var WEAK_COLLECTION_KEY = Symbol("WeakCollection_Key" );
41
- var ARRAY_ITERATE_KEY = Symbol("Array_Iterate_Key" );
32
+ var ARRAY_KEY = /* @__PURE__ */ Symbol("Array_Key" );
33
+ var COLLECTION_KEY = /* @__PURE__ */ Symbol("Collection_Key" );
34
+ var WEAK_COLLECTION_KEY = /* @__PURE__ */ Symbol("WeakCollection_Key" );
35
+ var ITERATE_KEY = /* @__PURE__ */ Symbol("Iterate_Key" );
36
+ var ARRAY_ITERATE_KEY = /* @__PURE__ */ Symbol("Array_Iterate_Key" );
42
37
 
43
38
  // src/propagation.ts
39
+ function enqueueEffect(effect2) {
40
+ var _a5;
41
+ (_a5 = effect2 == null ? void 0 : effect2.notify) == null ? void 0 : _a5.call(effect2);
42
+ }
44
43
  function propagate(link) {
45
44
  let next = link.nextSubLink;
46
45
  let stack;
47
46
  top: do {
48
47
  const sub = link.subNode;
49
- const queueBit = sub.flag & 64 /* QUEUED */;
50
48
  const watcherBit = sub.flag & 2 /* WATCHING */;
51
- let flags = sub.flag & -65 /* QUEUED */;
49
+ let flags = sub.flag;
52
50
  if (!(flags & (16 /* DIRTY */ | 32 /* PENDING */ | 8 /* RECURSED */ | 4 /* RECURSED_CHECK */))) {
53
- sub.flag = queueBit | watcherBit | flags | 32 /* PENDING */;
54
- } else if (flags & (16 /* DIRTY */ | 32 /* PENDING */)) ; else if (!(flags & (8 /* RECURSED */ | 4 /* RECURSED_CHECK */))) {
51
+ sub.flag = flags | 32 /* PENDING */;
52
+ if (watcherBit) {
53
+ enqueueEffect(sub);
54
+ }
55
+ } else if (!(flags & (8 /* RECURSED */ | 4 /* RECURSED_CHECK */))) {
55
56
  flags = 0 /* NONE */;
56
- sub.flag = queueBit | watcherBit;
57
57
  } else if (!(flags & 4 /* RECURSED_CHECK */)) {
58
- sub.flag = queueBit | watcherBit | (flags & -9 /* RECURSED */ | 32 /* PENDING */);
58
+ sub.flag = flags & -9 /* RECURSED */ | 32 /* PENDING */;
59
59
  } else if (!(flags & (16 /* DIRTY */ | 32 /* PENDING */)) && isValidLink(link, sub)) {
60
- sub.flag = queueBit | watcherBit | (flags | 8 /* RECURSED */ | 32 /* PENDING */);
60
+ sub.flag = flags | (8 /* RECURSED */ | 32 /* PENDING */);
61
+ if (watcherBit) {
62
+ enqueueEffect(sub);
63
+ }
61
64
  flags &= 1 /* MUTABLE */;
62
65
  } else {
63
66
  flags = 0 /* NONE */;
64
- sub.flag = queueBit | watcherBit;
65
- }
66
- if (sub.flag & 2 /* WATCHING */) {
67
- enqueueEffect(sub);
68
67
  }
69
68
  if (flags & 1 /* MUTABLE */) {
70
69
  const subSubs = sub.subLink;
71
- if (subSubs) {
72
- const nextSub = (link = subSubs).nextSubLink;
73
- if (nextSub) {
70
+ if (subSubs !== void 0) {
71
+ const nextSub = subSubs.nextSubLink;
72
+ if (nextSub !== void 0) {
74
73
  stack = { value: next, prev: stack };
75
74
  next = nextSub;
76
75
  }
76
+ link = subSubs;
77
77
  continue;
78
78
  }
79
79
  }
80
- if (next) {
81
- link = next;
80
+ if ((link = next) !== void 0) {
82
81
  next = link.nextSubLink;
83
82
  continue;
84
83
  }
85
- while (stack) {
84
+ while (stack !== void 0) {
86
85
  link = stack.value;
87
86
  stack = stack.prev;
88
- if (link) {
87
+ if (link !== void 0) {
89
88
  next = link.nextSubLink;
90
89
  continue top;
91
90
  }
@@ -96,27 +95,16 @@ function propagate(link) {
96
95
  function shallowPropagate(link) {
97
96
  while (link) {
98
97
  const sub = link.subNode;
99
- const queueBit = sub.flag & 64 /* QUEUED */;
100
- const flags = sub.flag & -65 /* QUEUED */;
101
- if (!(flags & 16 /* DIRTY */) && flags & (1 /* MUTABLE */ | 32 /* PENDING */)) {
102
- const newFlags = queueBit | flags & -33 /* PENDING */ | 16 /* DIRTY */;
103
- sub.flag = newFlags;
104
- if (newFlags & 2 /* WATCHING */) {
98
+ const flags = sub.flag;
99
+ if ((flags & (32 /* PENDING */ | 16 /* DIRTY */)) === 32 /* PENDING */) {
100
+ sub.flag = flags | 16 /* DIRTY */;
101
+ if ((flags & (2 /* WATCHING */ | 4 /* RECURSED_CHECK */)) === 2 /* WATCHING */) {
105
102
  enqueueEffect(sub);
106
103
  }
107
- if (flags & 1 /* MUTABLE */ && sub.subLink) {
108
- shallowPropagate(sub.subLink);
109
- }
110
104
  }
111
105
  link = link.nextSubLink;
112
106
  }
113
107
  }
114
- function enqueueEffect(effect2) {
115
- if (!effect2.active) {
116
- return;
117
- }
118
- effect2.notify();
119
- }
120
108
 
121
109
  // src/link.ts
122
110
  var currentLinkVersion = 0;
@@ -220,67 +208,76 @@ function unlinkReactiveNode(linkNode, subNode = linkNode.subNode) {
220
208
  }
221
209
  }
222
210
  }
223
- linkNode.depNode = void 0;
224
- linkNode.subNode = void 0;
225
- linkNode.prevSubLink = void 0;
226
- linkNode.nextSubLink = void 0;
227
- linkNode.prevDepLink = void 0;
228
- linkNode.nextDepLink = void 0;
229
211
  return nextDep;
230
212
  }
231
213
  function checkDirty(link, sub) {
232
- const stack = [{ link, owner: sub }];
233
- const pendingNodes = [];
234
- while (stack.length > 0) {
235
- const frame = stack.pop();
236
- let current = frame.link;
237
- const owner = frame.owner;
238
- while (current) {
239
- const dep = current.depNode;
214
+ let stack;
215
+ let checkDepth = 0;
216
+ let dirty = false;
217
+ top: do {
218
+ let currentDirty = false;
219
+ if (sub.flag & 16 /* DIRTY */) {
220
+ currentDirty = true;
221
+ } else {
222
+ const dep = link.depNode;
240
223
  const depFlags = dep.flag;
241
- if (owner.flag & 16 /* DIRTY */) {
242
- return true;
243
- }
244
224
  if ((depFlags & (1 /* MUTABLE */ | 16 /* DIRTY */)) === (1 /* MUTABLE */ | 16 /* DIRTY */)) {
245
225
  const subs = dep.subLink;
246
226
  if (subs && subs.nextSubLink) {
247
227
  shallowPropagate2(subs);
248
228
  }
249
- for (const node of pendingNodes) {
250
- if (node.flag & 32 /* PENDING */) {
251
- node.flag = node.flag & -33 /* PENDING */ | 16 /* DIRTY */;
252
- }
253
- }
254
- return true;
255
- }
256
- if ((depFlags & (1 /* MUTABLE */ | 32 /* PENDING */)) === (1 /* MUTABLE */ | 32 /* PENDING */)) {
229
+ currentDirty = true;
230
+ } else if ((depFlags & (1 /* MUTABLE */ | 32 /* PENDING */)) === (1 /* MUTABLE */ | 32 /* PENDING */)) {
257
231
  if (dep.depLink) {
258
- pendingNodes.push(dep);
259
- stack.push({ link: dep.depLink, owner: dep });
232
+ stack = { link, prev: stack };
233
+ link = dep.depLink;
234
+ sub = dep;
235
+ ++checkDepth;
236
+ continue top;
260
237
  } else {
261
238
  dep.flag &= -33 /* PENDING */;
262
239
  }
263
240
  } else if (depFlags & 32 /* PENDING */) {
264
241
  dep.flag &= -33 /* PENDING */;
265
242
  }
266
- current = current.nextDepLink;
267
243
  }
268
- }
269
- for (const node of pendingNodes) {
270
- node.flag &= -33 /* PENDING */;
271
- }
272
- if (sub.flag & 32 /* PENDING */) {
273
- sub.flag &= -33 /* PENDING */;
274
- }
275
- return false;
244
+ if (!currentDirty && link.nextDepLink !== void 0) {
245
+ link = link.nextDepLink;
246
+ continue top;
247
+ }
248
+ dirty = currentDirty;
249
+ while (checkDepth--) {
250
+ link = stack.link;
251
+ stack = stack.prev;
252
+ sub = link.subNode;
253
+ const checkedDep = link.depNode;
254
+ if (dirty) {
255
+ checkedDep.flag = checkedDep.flag & -33 /* PENDING */ | 16 /* DIRTY */;
256
+ } else {
257
+ checkedDep.flag &= -33 /* PENDING */;
258
+ }
259
+ if (checkedDep.flag & 16 /* DIRTY */) {
260
+ dirty = true;
261
+ }
262
+ if (!dirty && link.nextDepLink !== void 0) {
263
+ link = link.nextDepLink;
264
+ continue top;
265
+ }
266
+ }
267
+ if (dirty) {
268
+ sub.flag = sub.flag & -33 /* PENDING */ | 16 /* DIRTY */;
269
+ } else {
270
+ sub.flag &= -33 /* PENDING */;
271
+ }
272
+ return dirty;
273
+ } while (true);
276
274
  }
277
275
  function shallowPropagate2(link) {
278
276
  while (link) {
279
277
  const sub = link.subNode;
280
- const queueBit = sub.flag & 64 /* QUEUED */;
281
- const flags = sub.flag & -65 /* QUEUED */;
278
+ const flags = sub.flag;
282
279
  if ((flags & (32 /* PENDING */ | 16 /* DIRTY */)) === 32 /* PENDING */) {
283
- sub.flag = queueBit | flags | 16 /* DIRTY */;
280
+ sub.flag = flags | 16 /* DIRTY */;
284
281
  }
285
282
  link = link.nextSubLink;
286
283
  }
@@ -327,6 +324,23 @@ function isValidLink(checkLink, sub) {
327
324
  return false;
328
325
  }
329
326
  var targetMap = /* @__PURE__ */ new WeakMap();
327
+ var triggerVersion = 0;
328
+ function collectTriggeredEffects(dep, effects, version) {
329
+ if (!dep) {
330
+ return;
331
+ }
332
+ dep.forEach((effect2) => {
333
+ if (effect2.flag & 2 /* WATCHING */ && !effect2._active) {
334
+ dep.delete(effect2);
335
+ return;
336
+ }
337
+ if (effect2._triggerVersion === version) {
338
+ return;
339
+ }
340
+ effect2._triggerVersion = version;
341
+ effects.push(effect2);
342
+ });
343
+ }
330
344
  function track(target, key) {
331
345
  if (!activeSub || isUntracking) {
332
346
  return;
@@ -341,50 +355,39 @@ function track(target, key) {
341
355
  dep = /* @__PURE__ */ new Set();
342
356
  depsMap.set(key, dep);
343
357
  }
344
- if (!dep.has(activeSub)) {
345
- dep.add(activeSub);
346
- if (shared.isFunction(activeSub.onTrack)) {
347
- activeSub.onTrack({
348
- effect: activeSub,
349
- target,
350
- type: "get",
351
- key
352
- });
353
- }
358
+ const sizeBefore = dep.size ;
359
+ dep.add(activeSub);
360
+ if (dep.size !== sizeBefore && shared.isFunction(activeSub.onTrack)) {
361
+ activeSub.onTrack({
362
+ effect: activeSub,
363
+ target,
364
+ type: "get",
365
+ key
366
+ });
354
367
  }
355
368
  }
356
369
  function trigger(target, type, key, newValue) {
370
+ var _a5;
357
371
  const depsMap = targetMap.get(target);
358
372
  if (!depsMap) {
359
373
  return;
360
374
  }
361
- const effects = /* @__PURE__ */ new Set();
375
+ const effects = [];
376
+ const version = ++triggerVersion;
362
377
  if (key !== void 0) {
363
378
  if (Array.isArray(key)) {
364
- key.forEach((k) => {
365
- const dep = depsMap.get(k);
366
- if (dep) {
367
- dep.forEach((effect2) => effects.add(effect2));
368
- }
369
- });
370
- } else {
371
- const dep = depsMap.get(key);
372
- if (dep) {
373
- dep.forEach((effect2) => effects.add(effect2));
379
+ for (const element of key) {
380
+ collectTriggeredEffects(depsMap.get(element), effects, version);
374
381
  }
382
+ } else {
383
+ collectTriggeredEffects(depsMap.get(key), effects, version);
375
384
  }
376
385
  }
377
386
  if (type === "ADD" || type === "DELETE" || type === "CLEAR") {
378
- const ITERATE_KEY2 = Symbol("iterate");
379
- const ARRAY_ITERATE_KEY2 = Symbol("arrayIterate");
380
- const iterationKey = Array.isArray(target) ? ARRAY_ITERATE_KEY2 : ITERATE_KEY2;
381
- const iterationDep = depsMap.get(iterationKey);
382
- if (iterationDep) {
383
- iterationDep.forEach((effect2) => effects.add(effect2));
384
- }
387
+ const iterationKey = Array.isArray(target) ? ARRAY_ITERATE_KEY : ITERATE_KEY;
388
+ collectTriggeredEffects(depsMap.get(iterationKey), effects, version);
385
389
  }
386
- effects.forEach((effect2) => {
387
- var _a5;
390
+ for (const effect2 of effects) {
388
391
  if (shared.isFunction(effect2.onTrigger)) {
389
392
  effect2.onTrigger({
390
393
  effect: effect2,
@@ -402,7 +405,7 @@ function trigger(target, type, key, newValue) {
402
405
  propagate(effect2.subLink);
403
406
  }
404
407
  }
405
- });
408
+ }
406
409
  }
407
410
  var reactiveCaches = /* @__PURE__ */ new WeakMap();
408
411
  function toRaw(value) {
@@ -450,8 +453,7 @@ function createArrayInstrumentations() {
450
453
  instrumentations[key] = function(...args) {
451
454
  const arr = toRaw(this);
452
455
  const res = Array.prototype[key].apply(arr, args);
453
- trigger(arr, TriggerOpTypes.SET, ARRAY_KEY);
454
- trigger(arr, TriggerOpTypes.SET, ARRAY_ITERATE_KEY);
456
+ trigger(arr, TriggerOpTypes.SET, [ARRAY_KEY, ARRAY_ITERATE_KEY]);
455
457
  return res;
456
458
  };
457
459
  }
@@ -854,6 +856,8 @@ var objectHandlers = (shallow) => ({
854
856
  return result;
855
857
  }
856
858
  });
859
+ var shallowObjectHandlers = objectHandlers(true);
860
+ var deepObjectHandlers = objectHandlers(false);
857
861
  function reactiveImpl(target, shallow = false) {
858
862
  if (!shared.isObject(target)) {
859
863
  return target;
@@ -873,7 +877,7 @@ function reactiveImpl(target, shallow = false) {
873
877
  } else if (shared.isWeakMap(target) || shared.isWeakSet(target)) {
874
878
  handler = weakCollectionHandlers;
875
879
  } else {
876
- handler = objectHandlers(shallow);
880
+ handler = shallow ? shallowObjectHandlers : deepObjectHandlers;
877
881
  }
878
882
  const proxy = new Proxy(target, handler);
879
883
  reactiveCaches.set(target, proxy);
@@ -884,44 +888,18 @@ function isReactive(target) {
884
888
  }
885
889
  function reactive(target) {
886
890
  if (isReactive(target)) {
887
- {
888
- shared.warn(
889
- "[Reactive] Target is already reactive. Returning existing reactive proxy to avoid double wrapping."
890
- );
891
- }
892
891
  return target;
893
892
  }
894
893
  if (isSignal(target)) {
895
- {
896
- shared.warn(
897
- "[Reactive] Creating a reactive proxy from a signal is not recommended. Use the signal directly or access its value property."
898
- );
899
- }
900
894
  return target;
901
895
  }
902
896
  return reactiveImpl(target);
903
897
  }
904
898
  function shallowReactive(target) {
905
899
  if (isReactive(target)) {
906
- {
907
- if (isShallow(target)) {
908
- shared.warn(
909
- "[ShallowReactive] Target is already a shallow reactive proxy. Returning existing proxy to avoid double wrapping."
910
- );
911
- } else {
912
- shared.warn(
913
- "[ShallowReactive] Target is already a deep reactive proxy. Cannot convert deep reactive to shallow reactive. Returning existing proxy."
914
- );
915
- }
916
- }
917
900
  return target;
918
901
  }
919
902
  if (isSignal(target)) {
920
- {
921
- shared.warn(
922
- "[ShallowReactive] Creating a reactive proxy from a signal is not recommended. Use the signal directly or access its value property."
923
- );
924
- }
925
903
  return target;
926
904
  }
927
905
  return reactiveImpl(target, true);
@@ -935,7 +913,6 @@ var toReactive = (value) => shared.isObject(value) ? reactive(value) : value;
935
913
  var _a;
936
914
  _a = "_IS_SIGNAL" /* IS_SIGNAL */;
937
915
  var SignalImpl = class {
938
- // Mark as Signal
939
916
  /**
940
917
  * Create a new Signal with the given initial value.
941
918
  *
@@ -945,15 +922,20 @@ var SignalImpl = class {
945
922
  constructor(value, shallow = false) {
946
923
  this.flag = 1 /* MUTABLE */;
947
924
  // Mark whether it's shallow reactive
948
- // @ts-ignore
925
+ // @ts-ignore: used internally by isSignal typeguard
949
926
  this[_a] = true;
950
- this._rawValue = value;
951
- if (shallow) {
952
- this._value = shared.isObject(value) ? shallowReactive(value) : value;
927
+ const unwrapped = toRaw(value);
928
+ this._rawValue = unwrapped;
929
+ this["_IS_SHALLOW" /* IS_SHALLOW */] = shallow;
930
+ if (!shared.isObject(unwrapped)) {
931
+ this._value = unwrapped;
953
932
  } else {
954
- this._value = shared.isObject(value) ? reactive(value) : value;
933
+ if (isReactive(value)) {
934
+ this._value = value;
935
+ } else {
936
+ this._value = shallow ? shallowReactive(unwrapped) : reactive(unwrapped);
937
+ }
955
938
  }
956
- this["_IS_SHALLOW" /* IS_SHALLOW */] = shallow;
957
939
  }
958
940
  // dep getter, returns itself for dependency collection
959
941
  get dep() {
@@ -974,37 +956,37 @@ var SignalImpl = class {
974
956
  return this._value;
975
957
  }
976
958
  // value setter, triggers update when value changes
977
- set value(value) {
978
- if (isSignal(value)) {
959
+ set value(newValue) {
960
+ if (isSignal(newValue)) {
979
961
  {
980
962
  shared.warn(
981
963
  "Setting a signal value to another signal is not recommended. The value will be unwrapped automatically."
982
964
  );
983
965
  }
984
- value = value.peek();
966
+ newValue = newValue.peek();
985
967
  }
986
- value = toRaw(value);
987
- if (!shared.hasChanged(this._rawValue, value)) {
968
+ const originalValue = newValue;
969
+ const rawValue = toRaw(newValue);
970
+ if (!shared.hasChanged(this._rawValue, rawValue)) {
988
971
  return;
989
972
  }
990
- if (!("_oldValue" in this)) {
991
- this._oldValue = this._rawValue;
992
- }
993
- const flags = this.flag;
994
- this.flag = flags | 16 /* DIRTY */;
995
- this._rawValue = value;
996
- const shallow = this["_IS_SHALLOW" /* IS_SHALLOW */];
997
- if (shallow) {
998
- this._value = shared.isObject(value) ? shallowReactive(value) : value;
973
+ this._oldValue = this._rawValue;
974
+ this._rawValue = rawValue;
975
+ this.flag |= 16 /* DIRTY */;
976
+ if (!shared.isObject(rawValue)) {
977
+ this._value = rawValue;
978
+ } else if (isReactive(originalValue)) {
979
+ this._value = originalValue;
999
980
  } else {
1000
- this._value = shared.isObject(value) ? reactive(value) : value;
981
+ const shallow = this["_IS_SHALLOW" /* IS_SHALLOW */];
982
+ this._value = shallow ? shallowReactive(rawValue) : reactive(rawValue);
1001
983
  }
1002
984
  const subs = this.subLink;
1003
985
  if (subs) {
1004
986
  propagate(subs);
1005
987
  }
1006
988
  }
1007
- // Check if the value should be update
989
+ // Check if the value should be updated
1008
990
  shouldUpdate() {
1009
991
  this.flag &= -17 /* DIRTY */;
1010
992
  if (!("_oldValue" in this)) {
@@ -1050,11 +1032,6 @@ function signal(value) {
1050
1032
  }
1051
1033
  function shallowSignal(value) {
1052
1034
  if (isSignal(value)) {
1053
- {
1054
- shared.warn(
1055
- "Creating a shallow signal with another signal is not recommended. The value will be unwrapped."
1056
- );
1057
- }
1058
1035
  value = value.peek();
1059
1036
  }
1060
1037
  return new SignalImpl(value, true);
@@ -1067,19 +1044,7 @@ var activePreFlushCbs = /* @__PURE__ */ new Set();
1067
1044
  var p = Promise.resolve();
1068
1045
  var isFlushPending = false;
1069
1046
  function nextTick(fn) {
1070
- if (fn) {
1071
- return new Promise((resolve, reject) => {
1072
- queueMicrotask(() => {
1073
- try {
1074
- fn();
1075
- resolve();
1076
- } catch (error5) {
1077
- reject(error5);
1078
- }
1079
- });
1080
- });
1081
- }
1082
- return p;
1047
+ return fn ? p.then(fn) : p;
1083
1048
  }
1084
1049
  function queueJob(job) {
1085
1050
  queue.add(job);
@@ -1099,9 +1064,7 @@ function flushJobs() {
1099
1064
  isFlushPending = false;
1100
1065
  flushPreFlushCbs();
1101
1066
  while (queue.size > 0) {
1102
- const jobs = Array.from(queue);
1103
- queue.clear();
1104
- for (const job of jobs) {
1067
+ for (const job of queue) {
1105
1068
  try {
1106
1069
  job();
1107
1070
  } catch (_error) {
@@ -1110,6 +1073,7 @@ function flushJobs() {
1110
1073
  }
1111
1074
  }
1112
1075
  }
1076
+ queue.clear();
1113
1077
  }
1114
1078
  }
1115
1079
  function flushPreFlushCbs() {
@@ -1185,16 +1149,22 @@ var EffectImpl = class {
1185
1149
  */
1186
1150
  constructor(fn, options) {
1187
1151
  this.flag = 2 /* WATCHING */ | 16 /* DIRTY */;
1188
- // @ts-ignore
1152
+ // @ts-ignore: used internally by isEffect typeguard
1189
1153
  this[_a2] = true;
1190
- // ===== State management =====
1154
+ // State management
1191
1155
  this._active = true;
1156
+ var _a5;
1192
1157
  this.fn = fn;
1193
1158
  if (options) {
1194
- this.scheduler = options.flush || options.scheduler;
1195
- this.onStop = options.onStop;
1196
- this.onTrack = options.onTrack;
1197
- this.onTrigger = options.onTrigger;
1159
+ const scheduler = (_a5 = options.scheduler) != null ? _a5 : options.flush;
1160
+ if (scheduler) {
1161
+ this._flushScheduler = shared.isFunction(scheduler) ? () => scheduler(this) : createScheduler(() => this.run(), scheduler);
1162
+ }
1163
+ if (options.onStop) this.onStop = options.onStop;
1164
+ {
1165
+ if (options.onTrack) this.onTrack = options.onTrack;
1166
+ if (options.onTrigger) this.onTrigger = options.onTrigger;
1167
+ }
1198
1168
  }
1199
1169
  }
1200
1170
  /**
@@ -1204,9 +1174,8 @@ var EffectImpl = class {
1204
1174
  return this._active;
1205
1175
  }
1206
1176
  /**
1207
- * Check if the Effect is dirty (needs re-execution)
1208
-
1209
- */
1177
+ * Check if the Effect is dirty (needs re-execution)
1178
+ */
1210
1179
  get dirty() {
1211
1180
  const flags = this.flag;
1212
1181
  if (flags & 16 /* DIRTY */) {
@@ -1301,7 +1270,7 @@ var EffectImpl = class {
1301
1270
  return this.fn();
1302
1271
  }
1303
1272
  const flags = this.flag;
1304
- this.flag = flags & -17 /* DIRTY */ | 1024 /* STOP */;
1273
+ this.flag = flags & -49 | 512 /* RUNNING */;
1305
1274
  const prevSub = startTracking(this);
1306
1275
  try {
1307
1276
  return this.fn();
@@ -1309,7 +1278,7 @@ var EffectImpl = class {
1309
1278
  this.flag |= 16 /* DIRTY */;
1310
1279
  throw error5;
1311
1280
  } finally {
1312
- this.flag &= -1025 /* STOP */;
1281
+ this.flag &= -513 /* RUNNING */;
1313
1282
  endTracking(this, prevSub);
1314
1283
  }
1315
1284
  }
@@ -1329,25 +1298,21 @@ var EffectImpl = class {
1329
1298
  * Decides whether to execute immediately or defer based on scheduling strategy.
1330
1299
  */
1331
1300
  notify() {
1301
+ var _a5;
1332
1302
  const flags = this.flag;
1333
- if (!this._active || flags & (256 /* PAUSED */ | 1024 /* STOP */ | 16 /* DIRTY */)) {
1303
+ if (!this._active || flags & (256 /* PAUSED */ | 512 /* RUNNING */ | 16 /* DIRTY */)) {
1334
1304
  return;
1335
1305
  }
1336
1306
  this.flag = flags | 16 /* DIRTY */;
1337
- if (this.onTrigger) {
1307
+ if (this == null ? void 0 : this.onTrigger) {
1338
1308
  this.onTrigger({
1339
1309
  effect: this,
1340
1310
  target: {},
1341
1311
  type: "set"
1342
1312
  });
1343
1313
  }
1344
- if (this.scheduler) {
1345
- if (shared.isFunction(this.scheduler)) {
1346
- this.scheduler(this);
1347
- } else {
1348
- const schedulerFn = createScheduler(() => this.run(), this.scheduler);
1349
- schedulerFn();
1350
- }
1314
+ if (this._flushScheduler) {
1315
+ (_a5 = this._flushScheduler) == null ? void 0 : _a5.call(this);
1351
1316
  } else if (isBatching()) {
1352
1317
  queueJob(this.getJob());
1353
1318
  } else {
@@ -1381,6 +1346,7 @@ var EffectImpl = class {
1381
1346
  sub = unlinkReactiveNode(sub);
1382
1347
  }
1383
1348
  this._job = void 0;
1349
+ this._flushScheduler = void 0;
1384
1350
  this.depLinkTail = void 0;
1385
1351
  this.subLinkTail = void 0;
1386
1352
  {
@@ -1395,7 +1361,7 @@ var EffectImpl = class {
1395
1361
  );
1396
1362
  }
1397
1363
  }
1398
- if (this.onStop) {
1364
+ if (this == null ? void 0 : this.onStop) {
1399
1365
  this.onStop();
1400
1366
  }
1401
1367
  }
@@ -1433,7 +1399,7 @@ function memoEffect(fn, initialState, options) {
1433
1399
  };
1434
1400
  return effect(effectFn, options);
1435
1401
  }
1436
- var NO_VALUE = Symbol("computed-no-value");
1402
+ var NO_VALUE = /* @__PURE__ */ Symbol("computed-no-value");
1437
1403
  var _a3;
1438
1404
  _a3 = "_IS_COMPUTED" /* IS_COMPUTED */;
1439
1405
  var ComputedImpl = class {
@@ -1447,9 +1413,9 @@ var ComputedImpl = class {
1447
1413
  */
1448
1414
  constructor(getter, setter, onTrack, onTrigger) {
1449
1415
  this.flag = 1 /* MUTABLE */ | 16 /* DIRTY */;
1450
- //@ts-ignore
1416
+ // @ts-ignore: used internally by isComputed typeguard
1451
1417
  this[_a3] = true;
1452
- // ===== Cache =====
1418
+ // Cache
1453
1419
  // Use symbol sentinel to distinguish "no value" from undefined/null values
1454
1420
  this._value = NO_VALUE;
1455
1421
  this.getter = getter;
@@ -1508,7 +1474,7 @@ var ComputedImpl = class {
1508
1474
  /**
1509
1475
  * Recompute the value
1510
1476
  *
1511
- * computation logic:
1477
+ * computation logic:
1512
1478
  * 1. Start tracking dependencies
1513
1479
  * 2. Execute getter function
1514
1480
  * 3. Check if value changed using optimized comparison
@@ -1547,7 +1513,7 @@ var ComputedImpl = class {
1547
1513
  } catch (_error) {
1548
1514
  const clearMask = -49;
1549
1515
  this.flag &= clearMask;
1550
- this.flag |= 16 /* DIRTY */;
1516
+ this._value = NO_VALUE;
1551
1517
  {
1552
1518
  shared.error(
1553
1519
  "[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.",
@@ -1671,39 +1637,23 @@ function createOptionsStore(options) {
1671
1637
  if (getters) {
1672
1638
  for (const key in getters) {
1673
1639
  const getter = getters[key];
1674
- if (getter) {
1675
- let accessCount = 0;
1676
- let lastWarnTime = 0;
1677
- Object.defineProperty(store, key, {
1678
- get() {
1679
- {
1680
- accessCount++;
1681
- const now = Date.now();
1682
- if (accessCount > 100 && now - lastWarnTime > 1e3) {
1683
- shared.warn(
1684
- `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.`
1685
- );
1686
- lastWarnTime = now;
1687
- accessCount = 0;
1688
- }
1689
- }
1690
- return computed(() => getter.call(store, reactiveState)).value;
1691
- },
1692
- enumerable: true,
1693
- configurable: true
1694
- });
1695
- }
1640
+ if (!getter) continue;
1641
+ Object.defineProperty(store, key, {
1642
+ get: () => computed(() => getter.call(store, reactiveState)).value,
1643
+ enumerable: true,
1644
+ configurable: true
1645
+ });
1696
1646
  }
1697
1647
  }
1698
1648
  if (actions) {
1699
1649
  for (const key in actions) {
1700
1650
  const action = actions[key];
1701
1651
  if (action) {
1702
- store[key] = (...args) => {
1652
+ Reflect.set(store, key, (...args) => {
1703
1653
  const result = action.apply(reactiveState, args);
1704
1654
  actionCallbacks.forEach((callback) => callback(reactiveState));
1705
1655
  return result;
1706
- };
1656
+ });
1707
1657
  }
1708
1658
  }
1709
1659
  }
@@ -1744,15 +1694,15 @@ function createStore(storeDefinition) {
1744
1694
  }
1745
1695
  return () => {
1746
1696
  let options;
1747
- if (typeof storeDefinition === "function") {
1697
+ if (shared.isFunction(storeDefinition)) {
1748
1698
  options = createClassStore(storeDefinition);
1749
1699
  } else {
1750
1700
  options = storeDefinition;
1751
1701
  }
1752
1702
  const store = createOptionsStore(options);
1753
- if (typeof storeDefinition === "function") {
1754
- Object.keys(options.actions || {}).forEach((key) => {
1755
- store[key] = options.actions[key].bind(store);
1703
+ if (shared.isFunction(storeDefinition) && options.actions) {
1704
+ Object.keys(options.actions).forEach((key) => {
1705
+ Reflect.set(store, key, options.actions[key].bind(store));
1756
1706
  });
1757
1707
  }
1758
1708
  return store;
@@ -1767,40 +1717,38 @@ var RefImpl = class extends (_b = SignalImpl, _a4 = "_IS_REF" /* IS_REF */, _b)
1767
1717
  */
1768
1718
  constructor(value) {
1769
1719
  super(value, true);
1770
- // @ts-ignore
1720
+ // @ts-ignore: used internally by isRef typeguard
1771
1721
  this[_a4] = true;
1772
1722
  }
1773
1723
  get value() {
1774
- track(this, SIGNAL_KEY);
1724
+ const sub = activeSub;
1725
+ if (sub) {
1726
+ linkReactiveNode(this, sub);
1727
+ }
1775
1728
  return this._value;
1776
1729
  }
1777
1730
  set value(newValue) {
1778
1731
  if (isSignal(newValue)) {
1779
- newValue = newValue.value;
1732
+ newValue = newValue.peek();
1780
1733
  }
1781
1734
  if (isRef(newValue)) {
1782
1735
  newValue = newValue.value;
1783
1736
  }
1784
1737
  if (shared.hasChanged(this._value, newValue)) {
1738
+ this._rawValue = newValue;
1785
1739
  this._value = newValue;
1740
+ this.flag |= 16 /* DIRTY */;
1786
1741
  if (this.subLink) {
1787
- shallowPropagate2(this.subLink);
1742
+ propagate(this.subLink);
1788
1743
  }
1789
- trigger(this, "SET", SIGNAL_KEY);
1790
1744
  }
1791
1745
  }
1792
1746
  };
1793
1747
  function ref(value = void 0) {
1794
1748
  if (isRef(value)) {
1795
- {
1796
- shared.info("Creating a ref with another ref is not recommended. The value will be unwrapped.");
1797
- }
1798
1749
  return value;
1799
1750
  }
1800
1751
  if (isSignal(value)) {
1801
- {
1802
- shared.info("Creating a ref with a signal is not recommended. The value will be unwrapped.");
1803
- }
1804
1752
  return new RefImpl(value.peek());
1805
1753
  }
1806
1754
  return new RefImpl(value);