@oscarpalmer/mora 0.38.0 → 0.39.0

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.
Files changed (57) hide show
  1. package/dist/batch.d.mts +1 -3
  2. package/dist/batch.mjs +3 -4
  3. package/dist/constants.d.mts +16 -10
  4. package/dist/constants.mjs +12 -6
  5. package/dist/effect.d.mts +2 -3
  6. package/dist/effect.mjs +27 -8
  7. package/dist/helpers/is.d.mts +1 -3
  8. package/dist/helpers/is.mjs +8 -5
  9. package/dist/helpers/misc.d.mts +8 -4
  10. package/dist/helpers/misc.mjs +66 -4
  11. package/dist/helpers/proxy.d.mts +3 -4
  12. package/dist/helpers/proxy.mjs +26 -11
  13. package/dist/helpers/subscription.d.mts +1 -3
  14. package/dist/helpers/subscription.mjs +15 -7
  15. package/dist/helpers/value.d.mts +4 -5
  16. package/dist/helpers/value.mjs +18 -13
  17. package/dist/models.d.mts +38 -5
  18. package/dist/mora.full.mjs +555 -276
  19. package/dist/value/array.d.mts +1 -3
  20. package/dist/value/array.mjs +46 -22
  21. package/dist/value/computed.d.mts +1 -3
  22. package/dist/value/computed.mjs +17 -11
  23. package/dist/value/readonly.d.mts +2 -5
  24. package/dist/value/readonly.mjs +24 -16
  25. package/dist/value/signal.d.mts +1 -3
  26. package/dist/value/signal.mjs +9 -6
  27. package/dist/value/store.d.mts +1 -3
  28. package/dist/value/store.mjs +9 -6
  29. package/package.json +5 -12
  30. package/src/batch.ts +8 -4
  31. package/src/constants.ts +26 -16
  32. package/src/effect.ts +37 -7
  33. package/src/helpers/is.ts +18 -8
  34. package/src/helpers/misc.ts +121 -2
  35. package/src/helpers/proxy.ts +59 -9
  36. package/src/helpers/subscription.ts +34 -4
  37. package/src/helpers/value.ts +48 -15
  38. package/src/models.ts +42 -3
  39. package/src/value/array.ts +100 -21
  40. package/src/value/computed.ts +29 -10
  41. package/src/value/readonly.ts +38 -33
  42. package/src/value/signal.ts +11 -5
  43. package/src/value/store.ts +11 -5
  44. package/types/batch.d.ts +0 -11
  45. package/types/constants.d.ts +0 -16
  46. package/types/effect.d.ts +0 -13
  47. package/types/helpers/is.d.ts +0 -43
  48. package/types/helpers/proxy.d.ts +0 -11
  49. package/types/helpers/value.d.ts +0 -4
  50. package/types/index.d.ts +0 -9
  51. package/types/models.d.ts +0 -56
  52. package/types/subscription.d.ts +0 -11
  53. package/types/value/array.d.ts +0 -137
  54. package/types/value/computed.d.ts +0 -14
  55. package/types/value/reactive.d.ts +0 -36
  56. package/types/value/signal.d.ts +0 -26
  57. package/types/value/store.d.ts +0 -94
@@ -1,92 +1,18 @@
1
- //#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
2
- /**
3
- * Is the value a _Key_?
4
- *
5
- * @param value Value to check
6
- * @returns `true` if the value is a _Key_ _(`number` or `string`)_, otherwise `false`
7
- */
8
- function isKey(value) {
9
- return typeof value === "number" || typeof value === "string";
10
- }
11
- /**
12
- * Is the value a plain object?
13
- *
14
- * @param value Value to check
15
- * @returns `true` if the value is a plain object, otherwise `false`
16
- */
17
- function isPlainObject(value) {
18
- if (value === null || typeof value !== "object") return false;
19
- if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
20
- const prototype = Object.getPrototypeOf(value);
21
- return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
22
- }
23
- //#endregion
24
- //#region node_modules/@oscarpalmer/atoms/dist/internal/result/misc.mjs
25
- function error(value, original) {
26
- return getError(value, original);
27
- }
28
- function getError(value, original) {
29
- const errorResult = {
30
- error: value,
31
- ok: false
32
- };
33
- if (original instanceof Error) errorResult.original = original;
34
- return errorResult;
35
- }
36
- function isError(value, extended) {
37
- return isResultValue(value, false) && (extended === true ? value.original instanceof Error : true);
38
- }
39
- function isOk(value) {
40
- return isResultValue(value, true);
41
- }
42
- function isResultValue(value, okValue) {
43
- return isPlainObject(value) && value.ok === okValue && (okValue ? RESULT_PROPERTY_VALUE : RESULT_PROPERTY_ERROR) in value;
44
- }
45
- /**
46
- * Creates an ok result
47
- *
48
- * @param value Value
49
- * @returns Ok result
50
- */
51
- function ok(value) {
52
- return {
53
- ok: true,
54
- value
55
- };
56
- }
57
- const RESULT_PROPERTY_ERROR = "error";
58
- const RESULT_PROPERTY_VALUE = "value";
59
- error.is = isError;
60
- ok.is = isOk;
61
- //#endregion
62
- //#region node_modules/@oscarpalmer/atoms/dist/result/index.mjs
63
- async function asyncAttempt(value, err) {
64
- try {
65
- let result;
66
- if (typeof value === "function") result = value();
67
- else result = value;
68
- if (result instanceof Promise) result = await result;
69
- return ok(result);
70
- } catch (thrown) {
71
- return getError(err ?? thrown, err == null ? void 0 : thrown);
72
- }
73
- }
74
- function attempt(callback, err) {
75
- try {
76
- return ok(callback());
77
- } catch (thrown) {
78
- return getError(err ?? thrown, err == null ? void 0 : thrown);
79
- }
80
- }
81
- attempt.async = asyncAttempt;
82
- //#endregion
83
- //#region src/constants.ts
1
+ // src/constants.ts
84
2
  const ACTIVE = {};
85
3
  const BATCH = {
86
4
  depth: 0,
87
5
  flushing: false,
88
6
  handlers: /* @__PURE__ */ new Map()
89
7
  };
8
+ const MESSAGE_COMPUTED_CALLBACK = "Computed callback must be a function";
9
+ const MESSAGE_DEACTIVATED_ARRAY_FILTER = "Cannot filter an inactive reactive array";
10
+ const MESSAGE_DEACTIVATED_ARRAY_MAP = "Cannot map an inactive reactive array";
11
+ const MESSAGE_DEACTIVATED_ARRAY_SELECT = "Cannot select from an inactive reactive array";
12
+ const MESSAGE_DEACTIVATED_READONLY = "Cannot create readonly variant of inactive signal";
13
+ const MESSAGE_DEACTIVATED_SUBSCRIPTION = "Cannot subscribe to inactive signal";
14
+ const MESSAGE_EFFECT_CALLBACK = "Effect callback must be a function";
15
+ const MESSAGE_UPDATE_CALLBACK = "Update callback must be a function";
90
16
  const METHODS_AFFECTING_LENGTH = /* @__PURE__ */ new Set([
91
17
  "pop",
92
18
  "push",
@@ -104,7 +30,6 @@ const METHODS_UPDATE = /* @__PURE__ */ new Set([
104
30
  const NAME_ARRAY = "array";
105
31
  const NAME_COMPUTED = "computed";
106
32
  const NAME_EFFECT = "effect";
107
- const NAME_MORA = "$mora";
108
33
  const NAME_READONLY = "readonly";
109
34
  const NAME_SIGNAL = "signal";
110
35
  const NAME_STORE = "store";
@@ -112,15 +37,15 @@ const NAME_SUBSCRIPTION = "subscription";
112
37
  const NAME_ALL = /* @__PURE__ */ new Set([
113
38
  NAME_ARRAY,
114
39
  NAME_COMPUTED,
115
- NAME_READONLY,
116
40
  NAME_SIGNAL,
117
41
  NAME_STORE
118
42
  ]);
119
43
  const PROPERTY_LENGTH = "length";
120
44
  const SYMBOL_EFFECT = Symbol("effect");
45
+ const SYMBOL_READONLY = Symbol("readonly");
121
46
  const SYMBOL_STATE = Symbol("state");
122
47
  const SUBSCRIPTION_PROPERTY$1 = {
123
- key: NAME_MORA,
48
+ key: "$mora",
124
49
  value: NAME_SUBSCRIPTION
125
50
  };
126
51
  const SUBSCRIPTION_TYPE_COPY = "copy";
@@ -133,13 +58,70 @@ const SUBSCRIPTION_TYPES = /* @__PURE__ */ new Set([
133
58
  SUBSCRIPTION_TYPE_FROZEN,
134
59
  SUBSCRIPTION_TYPE_ORIGINAL
135
60
  ]);
136
- //#endregion
137
- //#region src/effect.ts
61
+ // node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
62
+ /**
63
+ * Is the value a _Key_?
64
+ *
65
+ * @param value Value to check
66
+ * @returns `true` if the value is a _Key_ _(`number` or `string`)_, otherwise `false`
67
+ */
68
+ function isKey(value) {
69
+ return typeof value === "number" || typeof value === "string";
70
+ }
71
+ /**
72
+ * Is the value not a number?
73
+ *
74
+ * @param value Value to check
75
+ * @returns `true` if the value is not a `number`, otherwise `false`
76
+ */
77
+ function isNonNumber(value) {
78
+ return !isNumber(value);
79
+ }
80
+ /**
81
+ * Is the value a number?
82
+ *
83
+ * @param value Value to check
84
+ * @returns `true` if the value is a `number`, otherwise `false`
85
+ */
86
+ function isNumber(value) {
87
+ return typeof value === "number" && !Number.isNaN(value);
88
+ }
89
+ /**
90
+ * Is the value a plain object?
91
+ *
92
+ * @param value Value to check
93
+ * @returns `true` if the value is a plain object, otherwise `false`
94
+ */
95
+ function isPlainObject(value) {
96
+ if (value === null || typeof value !== "object") return false;
97
+ if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
98
+ const prototype = Object.getPrototypeOf(value);
99
+ return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
100
+ }
101
+ // node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
102
+ /**
103
+ * A function that does nothing, which can be useful, I guess…
104
+ */
105
+ function noop() {}
106
+ // src/effect.ts
138
107
  function Effect(callback) {
139
- this[SYMBOL_STATE] = { callback };
108
+ this[SYMBOL_STATE] = {
109
+ callback,
110
+ active: true,
111
+ name: NAME_EFFECT
112
+ };
140
113
  runEffect(this[SYMBOL_STATE]);
141
114
  }
142
- Effect.prototype[NAME_MORA] = NAME_EFFECT;
115
+ Effect.prototype.stop = stopEffect;
116
+ Object.defineProperties(Effect.prototype, { active: {
117
+ enumerable: true,
118
+ get: getActive
119
+ } });
120
+ function deactivateEffect(state) {
121
+ state.active = false;
122
+ state.callback = noop;
123
+ BATCH.handlers.delete(state);
124
+ }
143
125
  /**
144
126
  * Create an effect
145
127
  *
@@ -147,9 +129,12 @@ Effect.prototype[NAME_MORA] = NAME_EFFECT;
147
129
  * @returns Effect
148
130
  */
149
131
  function effect(callback) {
150
- if (typeof callback !== "function") throw new TypeError("Effect callback must be a function");
132
+ if (typeof callback !== "function") throw new TypeError(MESSAGE_EFFECT_CALLBACK);
151
133
  return getEffect(callback)[0];
152
134
  }
135
+ function getActive() {
136
+ return this[SYMBOL_STATE].active;
137
+ }
153
138
  function getEffect(callback) {
154
139
  const instance = new Effect(callback);
155
140
  return [instance, instance[SYMBOL_STATE]];
@@ -166,6 +151,91 @@ function runEffect(state) {
166
151
  ACTIVE.effect = previousEffect;
167
152
  }
168
153
  }
154
+ function stopEffect() {
155
+ const state = this[SYMBOL_STATE];
156
+ if (state.active) deactivateEffect(state);
157
+ }
158
+ // node_modules/@oscarpalmer/atoms/dist/internal/string/misc.mjs
159
+ /**
160
+ * Get the string value from any value
161
+ *
162
+ * @param value Original value
163
+ * @returns String representation of the value
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * getString(null) // => ''
168
+ * getString('foo') // => 'foo'
169
+ * getString(123) // => '123'
170
+ * getString(true) // => 'true'
171
+ * getString([1, 2, 3]) // => '1,2,3'
172
+ * getString({a: 1}) // => '{"a":1}'
173
+ * getString(() => 123) // => '123'
174
+ * ```
175
+ */
176
+ function getString(value) {
177
+ if (typeof value === "string") return value;
178
+ if (value == null) return "";
179
+ if (typeof value === "function") return getString(value());
180
+ if (typeof value !== "object") return String(value);
181
+ const asString = String(value.valueOf?.() ?? value);
182
+ return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
183
+ }
184
+ // node_modules/@oscarpalmer/atoms/dist/models/misc.model.mjs
185
+ const EXPRESSION_NUMBER_BINARY = /^0b[01]+$/i;
186
+ const EXPRESSION_NUMBER_OCTAL = /^0o[0-7]+$/i;
187
+ const EXPRESSION_NUMBER_ZEROISH = /^\s*0+\s*$/;
188
+ // node_modules/@oscarpalmer/atoms/dist/internal/math/misc.mjs
189
+ /**
190
+ * Round a number
191
+ *
192
+ * @param value Number to round
193
+ * @param decimals Number of decimal places to round to _(defaults to `0`)_
194
+ * @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
195
+ *
196
+ * @example
197
+ * ```typescript
198
+ * round(10.567, 2); // => 10.57
199
+ * round(10.567); // => 11
200
+ * round('abc'); // => Number.NaN
201
+ * ```
202
+ */
203
+ function round(value, decimals) {
204
+ return roundNumber(Math.round, value, decimals);
205
+ }
206
+ function roundNumber(callback, value, decimals) {
207
+ if (typeof value !== "number") return NaN;
208
+ if (typeof decimals !== "number" || decimals < 1) return callback(value);
209
+ const mod = 10 ** decimals;
210
+ return callback((value + Number.EPSILON) * mod) / mod;
211
+ }
212
+ // node_modules/@oscarpalmer/atoms/dist/internal/math/aggregate.mjs
213
+ function aggregate(type, array, key, first) {
214
+ const length = Array.isArray(array) ? array.length : 0;
215
+ const aggregation = {
216
+ array: false,
217
+ count: 0,
218
+ first: first === true,
219
+ value: NaN
220
+ };
221
+ if (length === 0) return aggregation;
222
+ const aggregator = aggregators[type];
223
+ const callback = getAggregateCallback(key);
224
+ aggregation.array = callback != null && (type === "max" || type === "min");
225
+ let notNumber = true;
226
+ for (let index = 0; index < length; index += 1) {
227
+ const item = array[index];
228
+ const value = callback == null ? item : callback(item, index, array);
229
+ if (isNonNumber(value)) continue;
230
+ aggregation.value = aggregator(aggregation, value, notNumber, item);
231
+ aggregation.count += 1;
232
+ notNumber = false;
233
+ }
234
+ return aggregation;
235
+ }
236
+ function calculateSum(aggregation, value, notNumber) {
237
+ return notNumber ? value : aggregation.value + value;
238
+ }
169
239
  function getAbsoluteValue(condition, aggregation, value, notNumber, item) {
170
240
  if (notNumber || condition(aggregation, value)) {
171
241
  if (aggregation.array) {
@@ -177,42 +247,49 @@ function getAbsoluteValue(condition, aggregation, value, notNumber, item) {
177
247
  }
178
248
  return aggregation.value;
179
249
  }
250
+ function getAggregateCallback(key) {
251
+ if (key == null) return;
252
+ return typeof key === "function" ? key : (item) => item[key];
253
+ }
254
+ function getAggregated(type, array, key, first) {
255
+ const aggregation = aggregate(type, array, key, first);
256
+ if (aggregation.count === 0) {
257
+ if (aggregation.array) return aggregation.first ? void 0 : [];
258
+ return NaN;
259
+ }
260
+ if (aggregation.array) {
261
+ const array = aggregation.items[aggregation.value];
262
+ return aggregation.first ? array[0] : array;
263
+ }
264
+ return aggregation.value;
265
+ }
180
266
  function isMaxValue(aggregation, value) {
181
267
  return aggregation.array ? value >= aggregation.value : value > aggregation.value;
182
268
  }
183
269
  function isMinValue(aggregation, value) {
184
270
  return aggregation.array ? value <= aggregation.value : value < aggregation.value;
185
271
  }
186
- getAbsoluteValue.bind(void 0, isMaxValue), getAbsoluteValue.bind(void 0, isMinValue);
187
- //#endregion
188
- //#region node_modules/@oscarpalmer/atoms/dist/internal/math/misc.mjs
189
- /**
190
- * Round a number
191
- *
192
- * @param value Number to round
193
- * @param decimals Number of decimal places to round to _(defaults to `0`)_
194
- * @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
195
- */
196
- function round(value, decimals) {
197
- return roundNumber(Math.round, value, decimals);
198
- }
199
- function roundNumber(callback, value, decimals) {
200
- if (typeof value !== "number") return NaN;
201
- if (typeof decimals !== "number" || decimals < 1) return callback(value);
202
- const mod = 10 ** decimals;
203
- return callback((value + Number.EPSILON) * mod) / mod;
272
+ function min(array, key, first) {
273
+ return getAggregated("min", array, key, first);
204
274
  }
205
- //#endregion
206
- //#region src/helpers/value.ts
275
+ const aggregators = {
276
+ average: calculateSum,
277
+ max: getAbsoluteValue.bind(void 0, isMaxValue),
278
+ min: getAbsoluteValue.bind(void 0, isMinValue),
279
+ sum: calculateSum
280
+ };
281
+ // src/helpers/value.ts
207
282
  function emitValue(instance, notify) {
208
283
  const state = instance[SYMBOL_STATE];
209
- if (state.computeds != null && state.computeds.size > 0) for (const computed of state.computeds) computed.dirty = true;
210
- if (state.effects != null && state.effects.size > 0) for (const effect of state.effects) BATCH.handlers.set(effect, effect);
284
+ if (state.computeds != null && state.computeds.size > 0) for (const computed of state.computeds) if (computed.instance.active) computed.dirty = true;
285
+ else state.computeds.delete(computed);
286
+ if (state.effects != null && state.effects.size > 0) for (const effect of state.effects) if (effect.active) BATCH.handlers.set(effect, effect);
287
+ else state.effects.delete(effect);
211
288
  if (notify ?? false) {
212
289
  const mapped = instance[SYMBOL_STATE].mapped;
213
290
  for (const [, item] of mapped) {
214
- const fx = item[SYMBOL_EFFECT];
215
- BATCH.handlers.set(fx.instance, fx.instance);
291
+ const { instance } = item[SYMBOL_EFFECT];
292
+ BATCH.handlers.set(instance, instance);
216
293
  }
217
294
  }
218
295
  for (const type of SUBSCRIPTION_TYPES) {
@@ -234,7 +311,7 @@ function equalArrays(first, second, equal) {
234
311
  let offset = 0;
235
312
  if (length >= 100) {
236
313
  offset = round(length / 10);
237
- offset = offset > 25 ? 25 : offset;
314
+ offset = min([offset, 25]);
238
315
  for (let index = 0; index < offset; index += 1) if (!(eq(first[index], second[index]) && eq(first[length - index - 1], second[length - index - 1]))) return false;
239
316
  }
240
317
  const end = length - offset;
@@ -248,10 +325,12 @@ function getFrozenValue(value) {
248
325
  return frozen;
249
326
  }
250
327
  function getJsonValue() {
328
+ if (SYMBOL_READONLY in this && !this[SYMBOL_READONLY].active) return this[SYMBOL_READONLY].value;
251
329
  return this[SYMBOL_STATE].value;
252
330
  }
253
331
  function getSignalValue() {
254
332
  const state = this[SYMBOL_STATE];
333
+ if (!state.active) return state.value;
255
334
  if (ACTIVE.computed != null) {
256
335
  state.computeds ??= /* @__PURE__ */ new Set();
257
336
  state.computeds.add(ACTIVE.computed);
@@ -263,10 +342,13 @@ function getSignalValue() {
263
342
  return state.value;
264
343
  }
265
344
  function getStringValue(json) {
266
- return json === true ? JSON.stringify(this[SYMBOL_STATE].value) : String(this[SYMBOL_STATE].value);
345
+ let { value } = this[SYMBOL_STATE];
346
+ if (SYMBOL_READONLY in this && !this[SYMBOL_READONLY].active) value = this[SYMBOL_READONLY].value;
347
+ return json === true ? JSON.stringify(value) : String(value);
267
348
  }
268
349
  function handleSignal(instance, origin, setValue, onAfter, notify) {
269
350
  const state = instance[SYMBOL_STATE];
351
+ if (!state.active) return;
270
352
  try {
271
353
  let actual = typeof origin === "function" ? origin() : origin;
272
354
  if (actual instanceof Promise) {
@@ -292,11 +374,10 @@ function peekSignalValue(copy) {
292
374
  return peeked;
293
375
  }
294
376
  function updateSignal(instance, callback, setValue) {
295
- if (typeof callback !== "function") throw new TypeError("Callback must be a function");
296
- handleSignal(instance, callback(instance[SYMBOL_STATE].value), setValue);
377
+ if (typeof callback !== "function") throw new TypeError(MESSAGE_UPDATE_CALLBACK);
378
+ if (instance[SYMBOL_STATE].active) handleSignal(instance, callback(instance[SYMBOL_STATE].value), setValue);
297
379
  }
298
- //#endregion
299
- //#region src/batch.ts
380
+ // src/batch.ts
300
381
  function flushHandlers() {
301
382
  if (BATCH.flushing) return;
302
383
  BATCH.flushing = true;
@@ -306,7 +387,8 @@ function flushHandlers() {
306
387
  const { length } = handlers;
307
388
  BATCH.handlers.clear();
308
389
  for (let index = 0; index < length; index += 1) {
309
- const [, handler] = handlers[index];
390
+ const [owner, handler] = handlers[index];
391
+ if (!owner.active) continue;
310
392
  const subscription = handler;
311
393
  if (typeof subscription.frozen === "boolean") subscription.callback(subscription.frozen ? getFrozenValue(subscription.state.value) : peekSignalValue.call(subscription.instance, subscription.copy));
312
394
  else runEffect(handler);
@@ -331,8 +413,7 @@ function stopBatch() {
331
413
  if (BATCH.depth > 0) BATCH.depth -= 1;
332
414
  flushHandlers();
333
415
  }
334
- //#endregion
335
- //#region src/helpers/is.ts
416
+ // src/helpers/is.ts
336
417
  /**
337
418
  * Is the value a computed signal?
338
419
  *
@@ -351,8 +432,12 @@ function isComputed(value) {
351
432
  function isEffect(value) {
352
433
  return isMora(value, NAME_EFFECT);
353
434
  }
354
- function isMora(value, name) {
355
- return typeof value === "object" && value != null && "$mora" in value && (typeof name === "string" ? value["$mora"] === name : name.has(value["$mora"]));
435
+ function isMora(input, value) {
436
+ if (typeof input !== "object" || input === null) return false;
437
+ if (value === "readonly") return SYMBOL_READONLY in input;
438
+ if (!(SYMBOL_STATE in input)) return false;
439
+ const state = input[SYMBOL_STATE];
440
+ return typeof value === "string" ? state.name === value : value.has(state.name);
356
441
  }
357
442
  /**
358
443
  * Is the value reactive?
@@ -399,13 +484,12 @@ function isReactiveStore(value) {
399
484
  function isReadonlySignal(value) {
400
485
  return isMora(value, NAME_READONLY);
401
486
  }
402
- //#endregion
403
- //#region node_modules/@oscarpalmer/atoms/dist/internal/array/callbacks.mjs
487
+ // node_modules/@oscarpalmer/atoms/dist/internal/array/callbacks.mjs
404
488
  function getArrayCallback(value) {
405
489
  switch (typeof value) {
406
490
  case "function": return value;
407
491
  case "number":
408
- case "string": return typeof value === "string" && value.includes(".") ? void 0 : (obj) => obj[value];
492
+ case "string": return (obj) => obj?.[value];
409
493
  default: return;
410
494
  }
411
495
  }
@@ -416,8 +500,16 @@ function getArrayCallbacks(bool, key, value) {
416
500
  value: getArrayCallback(value)
417
501
  };
418
502
  }
419
- //#endregion
420
- //#region node_modules/@oscarpalmer/atoms/dist/internal/array/find.mjs
503
+ // node_modules/@oscarpalmer/atoms/dist/internal/array/find.mjs
504
+ function addResult(result, mapped, flat) {
505
+ if (!flat) {
506
+ result.matched.push(mapped);
507
+ return;
508
+ }
509
+ const array = Array.isArray(mapped) ? mapped : [mapped];
510
+ const { length } = array;
511
+ for (let index = 0; index < length; index += 1) result.matched.push(array[index]);
512
+ }
421
513
  function createFindParameters(original) {
422
514
  const { length } = original;
423
515
  return {
@@ -426,55 +518,84 @@ function createFindParameters(original) {
426
518
  value: length === 1 && typeof original[0] !== "function" ? original[0] : original[1]
427
519
  };
428
520
  }
429
- function findValues(type, array, parameters, mapper) {
521
+ function findComplexValues(parameters) {
522
+ const { array, arrayLength, callback, limit, result, type, value } = parameters;
523
+ const keys = /* @__PURE__ */ new Set();
524
+ for (let arrayIndex = 0; arrayIndex < arrayLength; arrayIndex += 1) {
525
+ const arrayItem = array[arrayIndex];
526
+ const keyed = callback == null ? arrayItem : callback(arrayItem, arrayIndex, array);
527
+ const mapped = arrayItem;
528
+ if (type === "all" && Object.is(keyed, value) || type === "unique" && !keys.has(keyed)) {
529
+ keys.add(keyed);
530
+ result.matched.push(mapped);
531
+ if (result.matched.length >= limit) return result;
532
+ } else result.notMatched.push(arrayItem);
533
+ }
534
+ return result;
535
+ }
536
+ function findSimpleValues(parameters) {
537
+ const { array, arrayLength, callback, flat, limit, map, result, value } = parameters;
538
+ const { after, before } = map ?? {};
539
+ const handler = callback ?? ((item) => Object.is(item, value));
540
+ for (let arrayIndex = 0; arrayIndex < arrayLength; arrayIndex += 1) {
541
+ const arrayItem = array[arrayIndex];
542
+ let mapped = before == null ? arrayItem : before(arrayItem, arrayIndex, array);
543
+ if (!flat || after != null) {
544
+ if (handler(mapped, arrayIndex, array)) {
545
+ mapped = after == null ? mapped : after(arrayItem, arrayIndex, array);
546
+ addResult(result, mapped, flat);
547
+ if (result.matched.length >= limit) return result;
548
+ } else result.notMatched.push(arrayItem);
549
+ continue;
550
+ }
551
+ const flatItems = Array.isArray(mapped) ? mapped : [mapped];
552
+ const flatLength = flatItems.length;
553
+ for (let flatIndex = 0; flatIndex < flatLength; flatIndex += 1) {
554
+ const flatItem = flatItems[flatIndex];
555
+ if (handler(flatItem, arrayIndex, array)) result.matched.push(flatItem);
556
+ else result.notMatched.push(flatItem);
557
+ }
558
+ }
559
+ return result;
560
+ }
561
+ function findValues(type, array, parameters, options) {
430
562
  const result = {
431
563
  matched: [],
432
564
  notMatched: []
433
565
  };
434
- if (!Array.isArray(array) || array.length === 0) return result;
435
- const { length } = array;
566
+ if (!Array.isArray(array)) return result;
567
+ const arrayLength = array.length;
568
+ if (arrayLength === 0) return result;
436
569
  const { bool, key, value } = createFindParameters(parameters);
437
570
  const callbacks = getArrayCallbacks(bool, key);
438
- if (type === "unique" && callbacks?.keyed == null && length >= FIND_UNIQUE_THRESHOLD) {
571
+ if (type === "unique" && callbacks?.keyed == null && arrayLength >= 100) {
439
572
  result.matched = [...new Set(array)];
440
573
  return result;
441
574
  }
442
- const mapCallback = getArrayCallback(mapper?.callback);
443
- const mapReverse = mapper?.reverse ?? false;
444
- const mapAfter = mapCallback == null ? void 0 : mapReverse ? void 0 : mapCallback;
445
- const mapBefore = mapCallback == null ? void 0 : mapReverse ? mapCallback : void 0;
446
- if (callbacks?.bool != null || type === "all" && key == null) {
447
- const callback = callbacks?.bool ?? ((item) => Object.is(item, value));
448
- for (let index = 0; index < length; index += 1) {
449
- const item = array[index];
450
- const transformed = mapBefore?.(item, index, array) ?? item;
451
- if (callback(transformed, index, array)) result.matched.push(mapAfter?.(item, index, array) ?? transformed);
452
- else result.notMatched.push(item);
453
- }
454
- return result;
455
- }
456
- const keys = /* @__PURE__ */ new Set();
457
- for (let index = 0; index < length; index += 1) {
458
- const item = array[index];
459
- let keyed;
460
- let transformed;
461
- if (mapBefore == null) {
462
- keyed = callbacks?.keyed?.(item, index, array) ?? item;
463
- transformed = item;
464
- } else {
465
- transformed = mapBefore(item, index, array);
466
- keyed = callbacks?.keyed?.(transformed, index, array) ?? transformed;
467
- }
468
- if (type === "all" && Object.is(keyed, value) || type === "unique" && !keys.has(keyed)) {
469
- keys.add(keyed);
470
- result.matched.push(mapAfter?.(item, index, array) ?? transformed);
471
- } else result.notMatched.push(item);
472
- }
473
- return result;
575
+ const limit = options?.limit ?? Number.POSITIVE_INFINITY;
576
+ const flat = options?.map?.flat ?? false;
577
+ const mapCallback = getArrayCallback(options?.map?.callback);
578
+ const mapReverse = options?.map?.reverse ?? false;
579
+ let map;
580
+ if (mapCallback != null) map = {
581
+ before: mapReverse ? mapCallback : void 0,
582
+ after: mapReverse ? void 0 : mapCallback
583
+ };
584
+ const simple = callbacks?.bool != null || type === "all" && key == null;
585
+ const findParameters = {
586
+ array,
587
+ arrayLength,
588
+ flat,
589
+ limit,
590
+ map,
591
+ result,
592
+ type,
593
+ value,
594
+ callback: simple ? callbacks?.bool : callbacks?.keyed
595
+ };
596
+ return simple ? findSimpleValues(findParameters) : findComplexValues(findParameters);
474
597
  }
475
- const FIND_UNIQUE_THRESHOLD = 100;
476
- //#endregion
477
- //#region node_modules/@oscarpalmer/atoms/dist/array/filter.mjs
598
+ // node_modules/@oscarpalmer/atoms/dist/array/filter.mjs
478
599
  function exclude(array, ...parameters) {
479
600
  return findValues("all", array, parameters).notMatched;
480
601
  }
@@ -482,50 +603,152 @@ function filter(array, ...parameters) {
482
603
  return findValues("all", array, parameters).matched;
483
604
  }
484
605
  filter.remove = exclude;
485
- //#endregion
486
- //#region node_modules/@oscarpalmer/atoms/dist/array/select.mjs
487
- function filterAndMap(array, ...parameters) {
488
- return selectValues(array, parameters);
489
- }
490
- function mapAndFilter(array, ...parameters) {
491
- return findValues("all", array, parameters, {
492
- callback: parameters.shift(),
493
- reverse: true
494
- }).matched;
495
- }
496
- function selectValues(array, parameters) {
497
- return findValues("all", array, parameters, {
498
- callback: parameters.pop(),
499
- reverse: false
500
- }).matched;
606
+ // node_modules/@oscarpalmer/atoms/dist/array/select.mjs
607
+ function filterAndFlatMap(array, filter, mapper) {
608
+ return selectValues(array, filter, mapper, true, false);
609
+ }
610
+ function filterAndMap(array, filter, mapper) {
611
+ return selectValues(array, filter, mapper, false, false);
501
612
  }
613
+ function flatMapAndFilter(array, mapper, filter) {
614
+ return selectValues(array, filter, mapper, true, true);
615
+ }
616
+ function mapAndFilter(array, mapper, filter) {
617
+ return selectValues(array, filter, mapper, false, true);
618
+ }
619
+ function selectValues(array, filter, mapper, flat, reverse) {
620
+ return findValues("all", array, [filter], { map: {
621
+ flat,
622
+ reverse,
623
+ callback: mapper
624
+ } }).matched;
625
+ }
626
+ filterAndMap.flat = filterAndFlatMap;
502
627
  filterAndMap.reverse = mapAndFilter;
503
- //#endregion
504
- //#region src/helpers/misc.ts
505
- function getState(value, options) {
628
+ mapAndFilter.flat = flatMapAndFilter;
629
+ // src/helpers/misc.ts
630
+ function deactivateComputed() {
631
+ if (!this[SYMBOL_STATE].active) return;
632
+ deactivateEffect(this[SYMBOL_EFFECT].instance);
633
+ deactivateReactive.call(this);
634
+ }
635
+ function deactivateProxy() {
636
+ const state = this[SYMBOL_STATE];
637
+ if (!state.active) return;
638
+ if (state.derived != null) {
639
+ for (const computed of state.derived) computed.deactivate();
640
+ state.derived.clear();
641
+ state.derived = void 0;
642
+ }
643
+ if (state.mapped != null) {
644
+ for (const [, computed] of state.mapped) computed.deactivate();
645
+ state.mapped.clear();
646
+ state.mapped = void 0;
647
+ }
648
+ deactivateReactive.call(this);
649
+ }
650
+ function deactivateReactive() {
651
+ const state = this[SYMBOL_STATE];
652
+ if (!state.active) return;
653
+ state.active = false;
654
+ state.computeds?.clear();
655
+ state.effects?.clear();
656
+ state.promises?.clear();
657
+ state.readonlies?.frozen?.deactivate();
658
+ state.readonlies?.original?.deactivate();
659
+ state.subscriptions?.clear();
660
+ state.equal = noop;
661
+ state.promise = void 0;
662
+ state.computeds = void 0;
663
+ state.effects = void 0;
664
+ state.promises = void 0;
665
+ state.readonlies = void 0;
666
+ state.subscriptions = void 0;
667
+ }
668
+ function deactivateReadonly() {
669
+ const readonly = this[SYMBOL_READONLY];
670
+ const signal = this[SYMBOL_STATE];
671
+ if (!readonly.active) return;
672
+ signal.readonlies[readonly.name] = void 0;
673
+ if (readonly.subscriptions != null) {
674
+ for (const subscription of readonly.subscriptions) subscription.unsubscribe();
675
+ readonly.subscriptions.clear();
676
+ readonly.subscriptions = void 0;
677
+ }
678
+ readonly.active = false;
679
+ readonly.value = peekSignalValue.call(this, true);
680
+ }
681
+ function getReactiveActive() {
682
+ return this[SYMBOL_STATE].active;
683
+ }
684
+ function getReadonlyActive() {
685
+ return this[SYMBOL_READONLY].active;
686
+ }
687
+ function getState(name, value, options) {
506
688
  return {
689
+ name,
507
690
  value,
691
+ active: true,
508
692
  equal: typeof options === "object" && typeof options?.equal === "function" ? options.equal : void 0
509
693
  };
510
694
  }
511
- //#endregion
512
- //#region node_modules/@oscarpalmer/atoms/dist/internal/aborter.mjs
695
+ // node_modules/@oscarpalmer/atoms/dist/internal/number.mjs
696
+ /**
697
+ * Get the number value from an unknown value
698
+ *
699
+ * _(Based on Lodash)_
700
+ *
701
+ * @param value Original value
702
+ * @returns Original value as a number, or `Number.NaN` if the value is unable to be parsed
703
+ *
704
+ * @example
705
+ * ```typescript
706
+ * getNumber(null) // => Number.NaN
707
+ * getNumber('foo') // => Number.NaN
708
+ * getNumber('123') // => 123
709
+ * getNumber(true) // => 1
710
+ * getNumber([1, 2, 3]) // => Number.NaN
711
+ * getNumber({a: 1}) // => Number.NaN
712
+ * getNumber(() => 123) // => 123
713
+ * ```
714
+ */
715
+ function getNumber(value) {
716
+ if (typeof value === "number") return value;
717
+ if (typeof value === "bigint" || typeof value === "boolean") return Number(value);
718
+ if (value == null || typeof value === "symbol") return NaN;
719
+ if (typeof value === "function") return getNumber(value());
720
+ let parsed = value.valueOf();
721
+ if (typeof parsed === "object") parsed = parsed.toString();
722
+ if (typeof parsed !== "string") return getNumber(parsed);
723
+ const trimmed = parsed.trim();
724
+ if (trimmed.length === 0) return NaN;
725
+ if (EXPRESSION_NUMBER_ZEROISH.test(parsed)) return 0;
726
+ const isBinary = EXPRESSION_NUMBER_BINARY.test(trimmed);
727
+ if (isBinary || EXPRESSION_NUMBER_OCTAL.test(trimmed)) return Number.parseInt(trimmed.slice(2), isBinary ? 2 : 8);
728
+ return Number(trimmed);
729
+ }
730
+ // node_modules/@oscarpalmer/atoms/dist/models/subscription.model.mjs
731
+ const SUBSCRIPTION_DISALLOWED_KEY = "Disallowed key for subscription";
732
+ const SUBSCRIPTION_INVALID_KEY = "Invalid key for subscription";
733
+ const SUBSCRIPTION_INVALID_VALUE = "A subscription requires a non-null value to identify it";
734
+ const SUBSCRIPTION_NAME = "subscription";
735
+ const SUBSCRIPTION_PROPERTY = "$subscription";
736
+ const SUBSCRIPTION_STORE = "subscriptions";
737
+ const SUBSCRIPTION_SYMBOL = Symbol(SUBSCRIPTION_PROPERTY);
738
+ // node_modules/@oscarpalmer/atoms/dist/models/aborter.model.mjs
739
+ const ABORTER_EVENT = "abort";
740
+ const ABORTER_OPTIONS = { once: true };
741
+ // node_modules/@oscarpalmer/atoms/dist/internal/aborter.mjs
513
742
  function createAborter(value, onAbort) {
514
743
  if (!(value instanceof AbortSignal)) return;
515
- value.addEventListener(ABORT_EVENT, onAbort, ABORT_OPTIONS);
744
+ value.addEventListener(ABORTER_EVENT, onAbort, ABORTER_OPTIONS);
516
745
  return {
517
746
  callback: onAbort,
518
747
  signal: value,
519
- cancel: () => value.removeEventListener(ABORT_EVENT, onAbort)
748
+ cancel: () => value.removeEventListener(ABORTER_EVENT, onAbort)
520
749
  };
521
750
  }
522
- const ABORT_EVENT = "abort";
523
- const ABORT_OPTIONS = { once: true };
524
- //#endregion
525
- //#region node_modules/@oscarpalmer/atoms/dist/internal/subscription.mjs
526
- const SUBSCRIPTION_NAME = "subscription";
527
- const SUBSCRIPTION_PROPERTY = "$subscription";
528
- const SUBSCRIPTION_STORE = "subscriptions";
751
+ // node_modules/@oscarpalmer/atoms/dist/internal/subscription.mjs
529
752
  function Subscription(state, property, parameters) {
530
753
  this[SUBSCRIPTION_SYMBOL] = state;
531
754
  this[property.key] = property.value;
@@ -566,9 +789,7 @@ function addSubscription(instance) {
566
789
  return;
567
790
  }
568
791
  /* istanbul ignore if */
569
- if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
570
- // istanbul ignore next
571
- return;
792
+ if (items.keyed == null || values.from.keyed == null || values.to.keyed == null) return;
572
793
  let keyedItems = items.keyed.get(key);
573
794
  if (keyedItems == null) {
574
795
  keyedItems = /* @__PURE__ */ new Set();
@@ -649,7 +870,7 @@ function createSubscriptionsProperty(input) {
649
870
  const values = isPlainObject(input) ? input : {};
650
871
  return {
651
872
  key: typeof values.key === "string" ? values.key : SUBSCRIPTION_PROPERTY,
652
- value: values.value == null ? SUBSCRIPTION_NAME : values.value
873
+ value: values.value ?? "subscription"
653
874
  };
654
875
  }
655
876
  function createSubscriptionsState(property, keys) {
@@ -697,9 +918,7 @@ function removeSubscription() {
697
918
  }
698
919
  const keyed = items.keyed?.get(key);
699
920
  /* istanbul ignore if */
700
- if (items.keyed == null || keyed == null)
701
- // istanbul ignore next
702
- return;
921
+ if (items.keyed == null || keyed == null) return;
703
922
  removeFromStore(keyed, values, this, value, key);
704
923
  if (keyed.size === 0) items.keyed.delete(key);
705
924
  }
@@ -712,46 +931,53 @@ function removeSubscription() {
712
931
  function subscriptions(parameters) {
713
932
  return new Subscriptions(parameters);
714
933
  }
715
- const SUBSCRIPTION_DISALLOWED_KEY = "Disallowed key for subscription";
716
- const SUBSCRIPTION_INVALID_KEY = "Invalid key for subscription";
717
- const SUBSCRIPTION_INVALID_VALUE = "A subscription requires a non-null value to identify it";
718
- const SUBSCRIPTION_SYMBOL = Symbol(SUBSCRIPTION_PROPERTY);
719
- //#endregion
720
- //#region src/helpers/subscription.ts
934
+ // src/helpers/subscription.ts
721
935
  function subscribeToProxy(first, second, third) {
936
+ if (!this[SYMBOL_STATE].active) throw new Error(MESSAGE_DEACTIVATED_SUBSCRIPTION);
722
937
  if (isKey(first)) return getReactiveValueInProxy(this, first).subscribe(second, third);
723
938
  return subscribeToSignal.call(this, first, second);
724
939
  }
725
940
  function subscribeToReactive(type, subscriber) {
726
- this[SYMBOL_STATE].subscriptions ??= subscriptions({
941
+ const state = this[SYMBOL_STATE];
942
+ if (!state.active) throw new Error(MESSAGE_DEACTIVATED_SUBSCRIPTION);
943
+ state.subscriptions ??= subscriptions({
727
944
  keys: SUBSCRIPTION_TYPES,
728
945
  property: SUBSCRIPTION_PROPERTY$1
729
946
  });
730
- const [subscription, existing] = this[SYMBOL_STATE].subscriptions.create({
947
+ const [subscription, existing] = state.subscriptions.create({
731
948
  key: type,
732
949
  value: subscriber
733
950
  });
734
- if (!existing) subscriber(type === "frozen" ? getFrozenValue(this[SYMBOL_STATE].value) : peekSignalValue.call(this, SUBSCRIPTION_TYPES_COPY.has(type)), subscription);
951
+ if (!existing) subscriber(type === "frozen" ? getFrozenValue(state.value) : peekSignalValue.call(this, SUBSCRIPTION_TYPES_COPY.has(type)), subscription);
735
952
  return subscription;
736
953
  }
737
954
  function subscribeToReadonly(subscriber) {
738
- return subscribeToReactive.call(this, this.frozen ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_READONLY, subscriber);
955
+ const state = this[SYMBOL_READONLY];
956
+ if (!state.active) throw new Error(MESSAGE_DEACTIVATED_SUBSCRIPTION);
957
+ const subscription = subscribeToReactive.call(this, this.frozen ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_READONLY, subscriber);
958
+ state.subscriptions ??= /* @__PURE__ */ new Set();
959
+ for (const existing of state.subscriptions) if (!existing.active) state.subscriptions.delete(existing);
960
+ state.subscriptions.add(subscription);
961
+ return subscription;
739
962
  }
740
963
  function subscribeToSignal(subscriber, copy) {
741
964
  return subscribeToReactive.call(this, copy === true ? SUBSCRIPTION_TYPE_COPY : SUBSCRIPTION_TYPE_ORIGINAL, subscriber);
742
965
  }
743
- //#endregion
744
- //#region src/value/computed.ts
966
+ // src/value/computed.ts
745
967
  function Computed(callback, options) {
746
- this[SYMBOL_STATE] = getState(void 0, options);
968
+ this[SYMBOL_STATE] = getState(NAME_COMPUTED, void 0, options);
747
969
  this[SYMBOL_EFFECT] = getComputedEffect(this, callback);
748
970
  }
749
- Computed.prototype[NAME_MORA] = NAME_COMPUTED;
971
+ Computed.prototype.deactivate = deactivateComputed;
750
972
  Computed.prototype.get = getComputedValue;
751
973
  Computed.prototype.peek = peekSignalValue;
752
974
  Computed.prototype.subscribe = subscribeToSignal;
753
975
  Computed.prototype.toJSON = getJsonValue;
754
976
  Computed.prototype.toString = getStringValue;
977
+ Object.defineProperties(Computed.prototype, { active: {
978
+ enumerable: true,
979
+ get: getReactiveActive
980
+ } });
755
981
  /**
756
982
  * Create a computed value
757
983
  *
@@ -763,7 +989,7 @@ function computed(callback, options) {
763
989
  return getComputed(callback, options);
764
990
  }
765
991
  function getComputed(callback, options) {
766
- if (typeof callback !== "function") throw new TypeError("Computed callback must be a function");
992
+ if (typeof callback !== "function") throw new TypeError(MESSAGE_COMPUTED_CALLBACK);
767
993
  return new Computed(callback, options);
768
994
  }
769
995
  function getComputedEffect(instance, callback) {
@@ -786,8 +1012,9 @@ function getComputedEffect(instance, callback) {
786
1012
  return fx;
787
1013
  }
788
1014
  function getComputedValue() {
789
- const fx = this[SYMBOL_EFFECT];
790
1015
  const state = this[SYMBOL_STATE];
1016
+ if (!state.active) return state.value;
1017
+ const fx = this[SYMBOL_EFFECT];
791
1018
  if (ACTIVE.computed != null && fx !== ACTIVE.computed) {
792
1019
  state.computeds ??= /* @__PURE__ */ new Set();
793
1020
  state.computeds.add(ACTIVE.computed);
@@ -804,10 +1031,12 @@ function internalComputed(callback, options) {
804
1031
  }
805
1032
  function setAndEmit$1(instance, value, notify) {
806
1033
  const state = instance[SYMBOL_STATE];
807
- if (!notify && (state.equal ?? Object.is)(state.value, value)) return;
1034
+ if (!state.active || !notify && (state.equal ?? Object.is)(state.value, value)) return;
808
1035
  state.value = value;
809
- if (state.computeds != null && state.computeds.size > 0) for (const computed of state.computeds) computed.dirty = true;
810
- if (state.effects != null && state.effects.size > 0) for (const effect of state.effects) BATCH.handlers.set(effect, effect);
1036
+ if (state.computeds != null && state.computeds.size > 0) for (const computed of state.computeds) if (computed.instance.active) computed.dirty = true;
1037
+ else state.computeds.delete(computed);
1038
+ if (state.effects != null && state.effects.size > 0) for (const effect of state.effects) if (effect.active) BATCH.handlers.set(effect, effect);
1039
+ else state.effects.delete(effect);
811
1040
  for (const type of SUBSCRIPTION_TYPES) {
812
1041
  if (type === "frozen") continue;
813
1042
  const subscriptions = state.subscriptions?.values.to.keyed?.get(type);
@@ -818,12 +1047,11 @@ function setAndEmit$1(instance, value, notify) {
818
1047
  }
819
1048
  flushHandlers();
820
1049
  }
821
- //#endregion
822
- //#region src/helpers/proxy.ts
1050
+ // src/helpers/proxy.ts
823
1051
  function getReactiveValueInProxy(instance, key) {
824
1052
  const state = instance[SYMBOL_STATE];
825
1053
  state.mapped ??= /* @__PURE__ */ new Map();
826
- const mapKey = String(key);
1054
+ const mapKey = getString(key);
827
1055
  let item = state.mapped.get(mapKey);
828
1056
  if (item == null) {
829
1057
  item = internalComputed(() => state.isArray ? instance.get().at(key) : instance.get()[key]);
@@ -832,18 +1060,21 @@ function getReactiveValueInProxy(instance, key) {
832
1060
  return item;
833
1061
  }
834
1062
  function getValueInProxy(first) {
1063
+ const state = this[SYMBOL_STATE];
1064
+ if (!state.active) return peekValueInProxy.call(this, first);
835
1065
  let signal;
836
- if (this[SYMBOL_STATE].isArray ? typeof first === "number" : isKey(first)) signal = getReactiveValueInProxy(this, first);
1066
+ if (state.isArray ? typeof first === "number" : isKey(first)) signal = getReactiveValueInProxy(this, first);
837
1067
  return getSignalValue.call(signal ?? this);
838
1068
  }
839
1069
  function isProxyKey(isArray, value) {
840
- return isArray ? typeof value === "number" : isKey(value);
1070
+ return isArray && typeof value === "number" || isKey(value);
841
1071
  }
842
1072
  function isProxyObject(isArray, value) {
843
1073
  return value == null || (isArray ? Array.isArray(value) : isPlainObject(value));
844
1074
  }
845
1075
  function notifyProxyValue() {
846
1076
  const state = this[SYMBOL_STATE];
1077
+ if (!state.active) return;
847
1078
  state.mapped ??= /* @__PURE__ */ new Map();
848
1079
  const values = [...state.mapped.values()];
849
1080
  const { length } = values;
@@ -895,6 +1126,7 @@ function setProxyProperty(state, property, value) {
895
1126
  }
896
1127
  function setProxyValue(first, second) {
897
1128
  const state = this[SYMBOL_STATE];
1129
+ if (!state.active) return;
898
1130
  if (state.isArray && first === "length") {
899
1131
  state.value.length = second;
900
1132
  return;
@@ -935,8 +1167,9 @@ function setProxyValue(first, second) {
935
1167
  }
936
1168
  function setValueInProxy(instance, target, property, value) {
937
1169
  const state = instance[SYMBOL_STATE];
1170
+ if (!state.active) return true;
938
1171
  if (state.isArray) {
939
- if (!(!Number.isNaN(Number(property)) || property === "length")) return Reflect.set(target, property, value);
1172
+ if (!(!Number.isNaN(getNumber(property)) || property === "length")) return Reflect.set(target, property, value);
940
1173
  }
941
1174
  const previous = Reflect.get(target, property);
942
1175
  if (!(state.equal ?? Object.is)(previous, value)) {
@@ -946,51 +1179,67 @@ function setValueInProxy(instance, target, property, value) {
946
1179
  }
947
1180
  return true;
948
1181
  }
1182
+ function updateProxyDerivations(instance, value) {
1183
+ const state = instance[SYMBOL_STATE];
1184
+ if (state.derived == null) {
1185
+ state.derived = /* @__PURE__ */ new Set([value]);
1186
+ return value;
1187
+ }
1188
+ for (const computed of state.derived) if (!computed.active) state.derived.delete(computed);
1189
+ state.derived.add(value);
1190
+ return value;
1191
+ }
949
1192
  function updateProxyValue(callback) {
950
- if (typeof callback !== "function") throw new TypeError("Callback must be a function");
951
- setProxyValue.call(this, callback(this[SYMBOL_STATE].value));
1193
+ if (typeof callback !== "function") throw new TypeError(MESSAGE_UPDATE_CALLBACK);
1194
+ if (this[SYMBOL_STATE].active) setProxyValue.call(this, callback(this[SYMBOL_STATE].value));
952
1195
  }
953
- //#endregion
954
- //#region src/value/readonly.ts
1196
+ // src/value/readonly.ts
955
1197
  function Readonly(state, frozen) {
956
- this[SUBSCRIPTION_TYPE_FROZEN] = frozen;
957
1198
  this[SYMBOL_STATE] = state;
1199
+ this[SYMBOL_READONLY] = {
1200
+ active: true,
1201
+ name: frozen ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_ORIGINAL
1202
+ };
1203
+ Object.defineProperty(this, SUBSCRIPTION_TYPE_FROZEN, { value: frozen });
958
1204
  }
959
- Readonly.prototype[NAME_MORA] = NAME_READONLY;
1205
+ Readonly.prototype.deactivate = deactivateReadonly;
960
1206
  Readonly.prototype.get = getReadonlyValue;
961
1207
  Readonly.prototype.peek = peekReadonlyValue;
962
1208
  Readonly.prototype.subscribe = subscribeToReadonly;
963
1209
  Readonly.prototype.toJSON = getJsonValue;
964
1210
  Readonly.prototype.toString = getStringValue;
965
- function getReadonlyInstance(state, frozen) {
966
- return new Readonly(state, frozen);
967
- }
1211
+ Object.defineProperties(Readonly.prototype, { active: {
1212
+ enumerable: true,
1213
+ get: getReadonlyActive
1214
+ } });
968
1215
  function getReadonlySignal(frozen) {
1216
+ const state = this[SYMBOL_STATE];
1217
+ if (!state.active) throw new Error(MESSAGE_DEACTIVATED_READONLY);
969
1218
  const key = frozen === true ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_ORIGINAL;
970
- this[SYMBOL_STATE].readonlies ??= {};
971
- this[SYMBOL_STATE].readonlies[key] ??= getReadonlyInstance(this[SYMBOL_STATE], frozen === true);
972
- return this[SYMBOL_STATE].readonlies[key];
1219
+ state.readonlies ??= {};
1220
+ state.readonlies[key] ??= new Readonly(state, frozen === true);
1221
+ return state.readonlies[key];
973
1222
  }
974
1223
  function getReadonlyValue() {
975
- return handleReadonlyValue(this, false, this[SUBSCRIPTION_TYPE_FROZEN]);
1224
+ return handleReadonlyValue(this, false, this.frozen);
976
1225
  }
977
1226
  function handleReadonlyValue(instance, peek, frozen, copy) {
1227
+ const state = instance[SYMBOL_READONLY];
978
1228
  let value;
979
- if (peek) value = peekSignalValue.call(instance, copy === true);
980
- else value = getSignalValue.call(instance);
1229
+ if (peek) value = peekSignalValue.call(state.active ? instance : [instance, state.value], copy === true);
1230
+ else value = state.active ? getSignalValue.call(instance) : state.value;
981
1231
  return frozen ? getFrozenValue(value) : value;
982
1232
  }
983
1233
  function peekReadonlyValue(copy) {
984
- return handleReadonlyValue(this, true, this[SUBSCRIPTION_TYPE_FROZEN], copy);
1234
+ return handleReadonlyValue(this, true, this.frozen, copy);
985
1235
  }
986
- //#endregion
987
- //#region src/value/signal.ts
1236
+ // src/value/signal.ts
988
1237
  function Signal(value, options) {
989
- this[SYMBOL_STATE] = getState(void 0, options);
1238
+ this[SYMBOL_STATE] = getState(NAME_SIGNAL, void 0, options);
990
1239
  handleSignal(this, value, setAndEmit);
991
1240
  }
992
- Signal.prototype[NAME_MORA] = NAME_SIGNAL;
993
1241
  Signal.prototype.asReadonly = getReadonlySignal;
1242
+ Signal.prototype.deactivate = deactivateReactive;
994
1243
  Signal.prototype.get = getSignalValue;
995
1244
  Signal.prototype.peek = peekSignalValue;
996
1245
  Signal.prototype.set = setSignalValue;
@@ -998,6 +1247,10 @@ Signal.prototype.subscribe = subscribeToSignal;
998
1247
  Signal.prototype.toString = getStringValue;
999
1248
  Signal.prototype.toJSON = getJsonValue;
1000
1249
  Signal.prototype.update = updateSignalValue;
1250
+ Object.defineProperties(Signal.prototype, { active: {
1251
+ enumerable: true,
1252
+ get: getReactiveActive
1253
+ } });
1001
1254
  function setAndEmit(instance, value) {
1002
1255
  const state = instance[SYMBOL_STATE];
1003
1256
  if (!(state.equal ?? Object.is)(state.value, value)) {
@@ -1014,11 +1267,10 @@ function signal(value, options) {
1014
1267
  function updateSignalValue(callback) {
1015
1268
  updateSignal(this, callback, setAndEmit);
1016
1269
  }
1017
- //#endregion
1018
- //#region src/value/array.ts
1270
+ // src/value/array.ts
1019
1271
  function ReactiveArray(value, options) {
1020
1272
  this[SYMBOL_STATE] = {
1021
- ...getState(void 0, options),
1273
+ ...getState(NAME_ARRAY, void 0, options),
1022
1274
  isArray: true,
1023
1275
  length: signal(0)
1024
1276
  };
@@ -1028,15 +1280,10 @@ function ReactiveArray(value, options) {
1028
1280
  });
1029
1281
  setProxyValue.call(this, value);
1030
1282
  }
1031
- ReactiveArray.prototype[NAME_MORA] = NAME_ARRAY;
1032
- Object.defineProperty(ReactiveArray.prototype, PROPERTY_LENGTH, {
1033
- enumerable: true,
1034
- get: getArrayLength,
1035
- set: setArrayLength
1036
- });
1037
1283
  ReactiveArray.prototype.asReadonly = getReadonlySignal;
1038
1284
  ReactiveArray.prototype.at = getArrayValues;
1039
1285
  ReactiveArray.prototype.clear = clearArrayValues;
1286
+ ReactiveArray.prototype.deactivate = deactivateArray;
1040
1287
  ReactiveArray.prototype.filter = filterArrayValues;
1041
1288
  ReactiveArray.prototype.get = getArrayValues;
1042
1289
  ReactiveArray.prototype.map = mapArrayValues;
@@ -1053,14 +1300,33 @@ ReactiveArray.prototype.toString = getStringValue;
1053
1300
  ReactiveArray.prototype.toJSON = getJsonValue;
1054
1301
  ReactiveArray.prototype.unshift = unshiftArrayValues;
1055
1302
  ReactiveArray.prototype.update = updateProxyValue;
1303
+ Object.defineProperties(ReactiveArray.prototype, {
1304
+ [PROPERTY_LENGTH]: {
1305
+ enumerable: true,
1306
+ get: getArrayLength,
1307
+ set: setArrayLength
1308
+ },
1309
+ active: {
1310
+ enumerable: true,
1311
+ get: getReactiveActive
1312
+ }
1313
+ });
1056
1314
  function array(value, options) {
1057
1315
  return new ReactiveArray(value, options);
1058
1316
  }
1059
1317
  function clearArrayValues() {
1060
- this[SYMBOL_STATE].value.length = 0;
1318
+ const state = this[SYMBOL_STATE];
1319
+ if (state.active) state.value.length = 0;
1320
+ }
1321
+ function deactivateArray() {
1322
+ const state = this[SYMBOL_STATE];
1323
+ if (!state.active) return;
1324
+ state.length?.deactivate?.();
1325
+ deactivateProxy.call(this);
1061
1326
  }
1062
1327
  function filterArrayValues(callback) {
1063
- return computed(() => filter(getArrayValues.call(this), callback));
1328
+ if (!this[SYMBOL_STATE].active) throw new Error(MESSAGE_DEACTIVATED_ARRAY_FILTER);
1329
+ return updateProxyDerivations(this, computed(() => filter(getArrayValues.call(this), callback)));
1064
1330
  }
1065
1331
  function getArrayLength() {
1066
1332
  return this[SYMBOL_STATE].length.get();
@@ -1069,36 +1335,47 @@ function getArrayValues(value) {
1069
1335
  return value === "length" ? this[SYMBOL_STATE].length.get() : getValueInProxy.call(this, value);
1070
1336
  }
1071
1337
  function mapArrayValues(callback) {
1072
- return computed(() => getArrayValues.call(this).map(callback));
1338
+ if (!this[SYMBOL_STATE].active) throw new Error(MESSAGE_DEACTIVATED_ARRAY_MAP);
1339
+ return updateProxyDerivations(this, computed(() => getArrayValues.call(this).map((item, index, array) => callback(item, index, array))));
1073
1340
  }
1074
1341
  function peekArrayValue(first, second) {
1075
1342
  return first === "length" ? this[SYMBOL_STATE].length.peek() : peekValueInProxy.call(this, first, second);
1076
1343
  }
1077
1344
  function popArrayValue() {
1078
- return this[SYMBOL_STATE].value.pop();
1345
+ const state = this[SYMBOL_STATE];
1346
+ return state.active ? state.value.pop() : void 0;
1079
1347
  }
1080
1348
  function pushArrayValues(...items) {
1081
- return this[SYMBOL_STATE].value.push(...items);
1349
+ const state = this[SYMBOL_STATE];
1350
+ return state.active ? state.value.push(...items) : state.value.length;
1082
1351
  }
1083
1352
  function selectArrayValues(filter, map) {
1084
- return computed(() => filterAndMap(getArrayValues.call(this), filter, map));
1353
+ if (!this[SYMBOL_STATE].active) throw new Error(MESSAGE_DEACTIVATED_ARRAY_SELECT);
1354
+ return updateProxyDerivations(this, computed(() => filterAndMap(getArrayValues.call(this), filter, map)));
1085
1355
  }
1086
1356
  function setArrayLength(value) {
1087
- const values = this[SYMBOL_STATE].value;
1357
+ const state = this[SYMBOL_STATE];
1358
+ if (!state.active) return;
1359
+ const values = state.value;
1088
1360
  if (typeof value === "number" && !Number.isNaN(value) && value >= 0 && value !== values.length) values.length = value;
1089
1361
  }
1090
1362
  function shiftArrayValue() {
1091
- return this[SYMBOL_STATE].value.shift();
1363
+ const state = this[SYMBOL_STATE];
1364
+ return state.active ? state.value.shift() : void 0;
1092
1365
  }
1093
1366
  function spliceArrayValues(from, to, ...items) {
1094
- const values = this[SYMBOL_STATE].value;
1367
+ const state = this[SYMBOL_STATE];
1368
+ if (!state.active) return [];
1369
+ const values = state.value;
1095
1370
  return values.splice(from, to ?? values.length, ...items);
1096
1371
  }
1097
1372
  function unshiftArrayValues(...items) {
1098
- return this[SYMBOL_STATE].value.unshift(...items);
1373
+ const state = this[SYMBOL_STATE];
1374
+ return state.active ? state.value.unshift(...items) : state.value.length;
1099
1375
  }
1100
1376
  function updateArray(instance, type, array) {
1101
1377
  const state = instance[SYMBOL_STATE];
1378
+ if (!state.active) return () => void 0;
1102
1379
  const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
1103
1380
  const previousArray = affectsLength ? [] : array.slice();
1104
1381
  const previousLength = array.length;
@@ -1111,18 +1388,17 @@ function updateArray(instance, type, array) {
1111
1388
  return result;
1112
1389
  };
1113
1390
  }
1114
- //#endregion
1115
- //#region src/value/store.ts
1391
+ // src/value/store.ts
1116
1392
  function ReactiveStore(value, options) {
1117
1393
  this[SYMBOL_STATE] = {
1118
- ...getState(void 0, options),
1394
+ ...getState(NAME_STORE, void 0, options),
1119
1395
  isArray: false
1120
1396
  };
1121
1397
  this[SYMBOL_STATE].value = new Proxy({}, { set: (target, property, value) => setValueInProxy(this, target, property, value) });
1122
1398
  setProxyValue.call(this, value);
1123
1399
  }
1124
- ReactiveStore.prototype[NAME_MORA] = NAME_STORE;
1125
1400
  ReactiveStore.prototype.asReadonly = getReadonlySignal;
1401
+ ReactiveStore.prototype.deactivate = deactivateProxy;
1126
1402
  ReactiveStore.prototype.get = getValueInProxy;
1127
1403
  ReactiveStore.prototype.notify = notifyProxyValue;
1128
1404
  ReactiveStore.prototype.peek = peekValueInProxy;
@@ -1131,8 +1407,11 @@ ReactiveStore.prototype.subscribe = subscribeToProxy;
1131
1407
  ReactiveStore.prototype.toJSON = getJsonValue;
1132
1408
  ReactiveStore.prototype.toString = getStringValue;
1133
1409
  ReactiveStore.prototype.update = updateProxyValue;
1410
+ Object.defineProperties(ReactiveStore.prototype, { active: {
1411
+ enumerable: true,
1412
+ get: getReactiveActive
1413
+ } });
1134
1414
  function store(value, options) {
1135
1415
  return new ReactiveStore(value, options);
1136
1416
  }
1137
- //#endregion
1138
1417
  export { array, computed, effect, isComputed, isEffect, isReactive, isReactiveArray, isReactiveStore, isReadonlySignal, isSignal, signal, startBatch, stopBatch, store };