@oscarpalmer/mora 0.37.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 -3
  3. package/dist/constants.d.mts +16 -12
  4. package/dist/constants.mjs +12 -6
  5. package/dist/effect.d.mts +2 -4
  6. package/dist/effect.mjs +27 -7
  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 -10
  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 +19 -12
  17. package/dist/models.d.mts +39 -7
  18. package/dist/mora.full.mjs +565 -234
  19. package/dist/value/array.d.mts +1 -4
  20. package/dist/value/array.mjs +47 -23
  21. package/dist/value/computed.d.mts +1 -4
  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 -4
  26. package/dist/value/signal.mjs +9 -6
  27. package/dist/value/store.d.mts +1 -4
  28. package/dist/value/store.mjs +9 -6
  29. package/package.json +7 -10
  30. package/src/batch.ts +8 -3
  31. package/src/constants.ts +31 -20
  32. package/src/effect.ts +37 -6
  33. package/src/helpers/is.ts +18 -8
  34. package/src/helpers/misc.ts +121 -2
  35. package/src/helpers/proxy.ts +59 -8
  36. package/src/helpers/subscription.ts +34 -4
  37. package/src/helpers/value.ts +49 -14
  38. package/src/models.ts +43 -4
  39. package/src/value/array.ts +103 -24
  40. package/src/value/computed.ts +30 -11
  41. package/src/value/readonly.ts +38 -33
  42. package/src/value/signal.ts +12 -6
  43. package/src/value/store.ts +13 -7
  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,10 +1,18 @@
1
- //#region src/constants.ts
1
+ // src/constants.ts
2
2
  const ACTIVE = {};
3
3
  const BATCH = {
4
4
  depth: 0,
5
5
  flushing: false,
6
6
  handlers: /* @__PURE__ */ new Map()
7
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";
8
16
  const METHODS_AFFECTING_LENGTH = /* @__PURE__ */ new Set([
9
17
  "pop",
10
18
  "push",
@@ -22,7 +30,6 @@ const METHODS_UPDATE = /* @__PURE__ */ new Set([
22
30
  const NAME_ARRAY = "array";
23
31
  const NAME_COMPUTED = "computed";
24
32
  const NAME_EFFECT = "effect";
25
- const NAME_MORA = "$mora";
26
33
  const NAME_READONLY = "readonly";
27
34
  const NAME_SIGNAL = "signal";
28
35
  const NAME_STORE = "store";
@@ -30,15 +37,15 @@ const NAME_SUBSCRIPTION = "subscription";
30
37
  const NAME_ALL = /* @__PURE__ */ new Set([
31
38
  NAME_ARRAY,
32
39
  NAME_COMPUTED,
33
- NAME_READONLY,
34
40
  NAME_SIGNAL,
35
41
  NAME_STORE
36
42
  ]);
37
43
  const PROPERTY_LENGTH = "length";
38
44
  const SYMBOL_EFFECT = Symbol("effect");
45
+ const SYMBOL_READONLY = Symbol("readonly");
39
46
  const SYMBOL_STATE = Symbol("state");
40
47
  const SUBSCRIPTION_PROPERTY$1 = {
41
- key: NAME_MORA,
48
+ key: "$mora",
42
49
  value: NAME_SUBSCRIPTION
43
50
  };
44
51
  const SUBSCRIPTION_TYPE_COPY = "copy";
@@ -51,13 +58,70 @@ const SUBSCRIPTION_TYPES = /* @__PURE__ */ new Set([
51
58
  SUBSCRIPTION_TYPE_FROZEN,
52
59
  SUBSCRIPTION_TYPE_ORIGINAL
53
60
  ]);
54
- //#endregion
55
- //#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
56
107
  function Effect(callback) {
57
- this[SYMBOL_STATE] = { callback };
108
+ this[SYMBOL_STATE] = {
109
+ callback,
110
+ active: true,
111
+ name: NAME_EFFECT
112
+ };
58
113
  runEffect(this[SYMBOL_STATE]);
59
114
  }
60
- 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
+ }
61
125
  /**
62
126
  * Create an effect
63
127
  *
@@ -65,9 +129,12 @@ Effect.prototype[NAME_MORA] = NAME_EFFECT;
65
129
  * @returns Effect
66
130
  */
67
131
  function effect(callback) {
68
- if (typeof callback !== "function") throw new TypeError("Effect callback must be a function");
132
+ if (typeof callback !== "function") throw new TypeError(MESSAGE_EFFECT_CALLBACK);
69
133
  return getEffect(callback)[0];
70
134
  }
135
+ function getActive() {
136
+ return this[SYMBOL_STATE].active;
137
+ }
71
138
  function getEffect(callback) {
72
139
  const instance = new Effect(callback);
73
140
  return [instance, instance[SYMBOL_STATE]];
@@ -84,40 +151,145 @@ function runEffect(state) {
84
151
  ACTIVE.effect = previousEffect;
85
152
  }
86
153
  }
87
- //#endregion
88
- //#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
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
89
159
  /**
90
- * Is the value a _Key_?
160
+ * Get the string value from any value
91
161
  *
92
- * @param value Value to check
93
- * @returns `true` if the value is a _Key_ _(`number` or `string`)_, otherwise `false`
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
+ * ```
94
175
  */
95
- function isKey(value) {
96
- return typeof value === "number" || typeof value === "string";
97
- }
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
98
189
  /**
99
- * Is the value a plain object?
190
+ * Round a number
100
191
  *
101
- * @param value Value to check
102
- * @returns `true` if the value is a plain object, otherwise `false`
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
+ * ```
103
202
  */
104
- function isPlainObject(value) {
105
- if (value === null || typeof value !== "object") return false;
106
- if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
107
- const prototype = Object.getPrototypeOf(value);
108
- return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
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
+ }
239
+ function getAbsoluteValue(condition, aggregation, value, notNumber, item) {
240
+ if (notNumber || condition(aggregation, value)) {
241
+ if (aggregation.array) {
242
+ aggregation.items ??= {};
243
+ aggregation.items[value] ??= [];
244
+ aggregation.items[value].push(item);
245
+ }
246
+ return value;
247
+ }
248
+ return aggregation.value;
249
+ }
250
+ function getAggregateCallback(key) {
251
+ if (key == null) return;
252
+ return typeof key === "function" ? key : (item) => item[key];
109
253
  }
110
- //#endregion
111
- //#region src/helpers/value.ts
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
+ }
266
+ function isMaxValue(aggregation, value) {
267
+ return aggregation.array ? value >= aggregation.value : value > aggregation.value;
268
+ }
269
+ function isMinValue(aggregation, value) {
270
+ return aggregation.array ? value <= aggregation.value : value < aggregation.value;
271
+ }
272
+ function min(array, key, first) {
273
+ return getAggregated("min", array, key, first);
274
+ }
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
112
282
  function emitValue(instance, notify) {
113
283
  const state = instance[SYMBOL_STATE];
114
- if (state.computeds != null && state.computeds.size > 0) for (const computed of state.computeds) computed.dirty = true;
115
- 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);
116
288
  if (notify ?? false) {
117
289
  const mapped = instance[SYMBOL_STATE].mapped;
118
290
  for (const [, item] of mapped) {
119
- const fx = item[SYMBOL_EFFECT];
120
- BATCH.handlers.set(fx.instance, fx.instance);
291
+ const { instance } = item[SYMBOL_EFFECT];
292
+ BATCH.handlers.set(instance, instance);
121
293
  }
122
294
  }
123
295
  for (const type of SUBSCRIPTION_TYPES) {
@@ -138,8 +310,8 @@ function equalArrays(first, second, equal) {
138
310
  const eq = equal ?? Object.is;
139
311
  let offset = 0;
140
312
  if (length >= 100) {
141
- offset = Math.round(length / 10);
142
- offset = offset > 25 ? 25 : offset;
313
+ offset = round(length / 10);
314
+ offset = min([offset, 25]);
143
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;
144
316
  }
145
317
  const end = length - offset;
@@ -153,10 +325,12 @@ function getFrozenValue(value) {
153
325
  return frozen;
154
326
  }
155
327
  function getJsonValue() {
328
+ if (SYMBOL_READONLY in this && !this[SYMBOL_READONLY].active) return this[SYMBOL_READONLY].value;
156
329
  return this[SYMBOL_STATE].value;
157
330
  }
158
331
  function getSignalValue() {
159
332
  const state = this[SYMBOL_STATE];
333
+ if (!state.active) return state.value;
160
334
  if (ACTIVE.computed != null) {
161
335
  state.computeds ??= /* @__PURE__ */ new Set();
162
336
  state.computeds.add(ACTIVE.computed);
@@ -168,10 +342,13 @@ function getSignalValue() {
168
342
  return state.value;
169
343
  }
170
344
  function getStringValue(json) {
171
- 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);
172
348
  }
173
349
  function handleSignal(instance, origin, setValue, onAfter, notify) {
174
350
  const state = instance[SYMBOL_STATE];
351
+ if (!state.active) return;
175
352
  try {
176
353
  let actual = typeof origin === "function" ? origin() : origin;
177
354
  if (actual instanceof Promise) {
@@ -197,11 +374,10 @@ function peekSignalValue(copy) {
197
374
  return peeked;
198
375
  }
199
376
  function updateSignal(instance, callback, setValue) {
200
- if (typeof callback !== "function") throw new TypeError("Callback must be a function");
201
- 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);
202
379
  }
203
- //#endregion
204
- //#region src/batch.ts
380
+ // src/batch.ts
205
381
  function flushHandlers() {
206
382
  if (BATCH.flushing) return;
207
383
  BATCH.flushing = true;
@@ -211,7 +387,8 @@ function flushHandlers() {
211
387
  const { length } = handlers;
212
388
  BATCH.handlers.clear();
213
389
  for (let index = 0; index < length; index += 1) {
214
- const [, handler] = handlers[index];
390
+ const [owner, handler] = handlers[index];
391
+ if (!owner.active) continue;
215
392
  const subscription = handler;
216
393
  if (typeof subscription.frozen === "boolean") subscription.callback(subscription.frozen ? getFrozenValue(subscription.state.value) : peekSignalValue.call(subscription.instance, subscription.copy));
217
394
  else runEffect(handler);
@@ -236,8 +413,7 @@ function stopBatch() {
236
413
  if (BATCH.depth > 0) BATCH.depth -= 1;
237
414
  flushHandlers();
238
415
  }
239
- //#endregion
240
- //#region src/helpers/is.ts
416
+ // src/helpers/is.ts
241
417
  /**
242
418
  * Is the value a computed signal?
243
419
  *
@@ -256,8 +432,12 @@ function isComputed(value) {
256
432
  function isEffect(value) {
257
433
  return isMora(value, NAME_EFFECT);
258
434
  }
259
- function isMora(value, name) {
260
- 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);
261
441
  }
262
442
  /**
263
443
  * Is the value reactive?
@@ -304,13 +484,12 @@ function isReactiveStore(value) {
304
484
  function isReadonlySignal(value) {
305
485
  return isMora(value, NAME_READONLY);
306
486
  }
307
- //#endregion
308
- //#region node_modules/@oscarpalmer/atoms/dist/internal/array/callbacks.mjs
487
+ // node_modules/@oscarpalmer/atoms/dist/internal/array/callbacks.mjs
309
488
  function getArrayCallback(value) {
310
489
  switch (typeof value) {
311
490
  case "function": return value;
312
491
  case "number":
313
- case "string": return typeof value === "string" && value.includes(".") ? void 0 : (obj) => obj[value];
492
+ case "string": return (obj) => obj?.[value];
314
493
  default: return;
315
494
  }
316
495
  }
@@ -321,8 +500,16 @@ function getArrayCallbacks(bool, key, value) {
321
500
  value: getArrayCallback(value)
322
501
  };
323
502
  }
324
- //#endregion
325
- //#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
+ }
326
513
  function createFindParameters(original) {
327
514
  const { length } = original;
328
515
  return {
@@ -331,116 +518,84 @@ function createFindParameters(original) {
331
518
  value: length === 1 && typeof original[0] !== "function" ? original[0] : original[1]
332
519
  };
333
520
  }
334
- function findValue(type, array, parameters, reversed) {
335
- const findIndex = type === FIND_VALUE_INDEX;
336
- if (!Array.isArray(array) || array.length === 0) return findIndex ? -1 : void 0;
337
- const { bool, key, value } = createFindParameters(parameters);
338
- const callbacks = getArrayCallbacks(bool, key);
339
- if (callbacks?.bool == null && callbacks?.keyed == null) {
340
- if (findIndex) return reversed ? array.lastIndexOf(value) : array.indexOf(value);
341
- return reversed ? array.findLast((item) => Object.is(item, value)) : array.find((item) => Object.is(item, value));
342
- }
343
- if (callbacks.bool != null) {
344
- const index = reversed ? array.findLastIndex(callbacks.bool) : array.findIndex(callbacks.bool);
345
- return findIndex ? index : array[index];
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);
346
533
  }
347
- return findValueInArray(array, callbacks.keyed, value, findIndex, reversed);
534
+ return result;
348
535
  }
349
- function findValueInArray(array, callback, value, findIndex, reversed) {
350
- const { length } = array;
351
- for (let index = 0; index < length; index += 1) {
352
- const item = reversed ? array.at(-(index + 1)) : array[index];
353
- if (Object.is(callback?.(item, index, array), value)) return findIndex ? index : item;
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
+ }
354
558
  }
355
- return findIndex ? -1 : void 0;
559
+ return result;
356
560
  }
357
- function findValues(type, array, parameters, mapper) {
561
+ function findValues(type, array, parameters, options) {
358
562
  const result = {
359
563
  matched: [],
360
564
  notMatched: []
361
565
  };
362
- if (!Array.isArray(array) || array.length === 0) return result;
363
- const { length } = array;
566
+ if (!Array.isArray(array)) return result;
567
+ const arrayLength = array.length;
568
+ if (arrayLength === 0) return result;
364
569
  const { bool, key, value } = createFindParameters(parameters);
365
570
  const callbacks = getArrayCallbacks(bool, key);
366
- if (type === "unique" && callbacks?.keyed == null && length >= FIND_UNIQUE_THRESHOLD) {
571
+ if (type === "unique" && callbacks?.keyed == null && arrayLength >= 100) {
367
572
  result.matched = [...new Set(array)];
368
573
  return result;
369
574
  }
370
- const mapCallback = getArrayCallback(mapper?.callback);
371
- const mapReverse = mapper?.reverse ?? false;
372
- const mapAfter = mapCallback == null ? void 0 : mapReverse ? void 0 : mapCallback;
373
- const mapBefore = mapCallback == null ? void 0 : mapReverse ? mapCallback : void 0;
374
- if (callbacks?.bool != null || type === "all" && key == null) {
375
- const callback = callbacks?.bool ?? ((item) => Object.is(item, value));
376
- for (let index = 0; index < length; index += 1) {
377
- const item = array[index];
378
- const transformed = mapBefore?.(item, index, array) ?? item;
379
- if (callback(transformed, index, array)) result.matched.push(mapAfter?.(item, index, array) ?? transformed);
380
- else result.notMatched.push(item);
381
- }
382
- return result;
383
- }
384
- const keys = /* @__PURE__ */ new Set();
385
- for (let index = 0; index < length; index += 1) {
386
- const item = array[index];
387
- let keyed;
388
- let transformed;
389
- if (mapBefore == null) {
390
- keyed = callbacks?.keyed?.(item, index, array) ?? item;
391
- transformed = item;
392
- } else {
393
- transformed = mapBefore(item, index, array);
394
- keyed = callbacks?.keyed?.(transformed, index, array) ?? transformed;
395
- }
396
- if (type === "all" && Object.is(keyed, value) || type === "unique" && !keys.has(keyed)) {
397
- keys.add(keyed);
398
- result.matched.push(mapAfter?.(item, index, array) ?? transformed);
399
- } else result.notMatched.push(item);
400
- }
401
- 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);
402
597
  }
403
- const FIND_VALUE_INDEX = "index";
404
- const FIND_VALUE_ITEM = "item";
405
- const FIND_UNIQUE_THRESHOLD = 100;
406
- //#endregion
407
- //#region node_modules/@oscarpalmer/atoms/dist/internal/array/index-of.mjs
408
- function indexOf(array, ...parameters) {
409
- return findValue(FIND_VALUE_INDEX, array, parameters, false);
410
- }
411
- function lastIndexOf(array, ...parameters) {
412
- return findValue(FIND_VALUE_INDEX, array, parameters, true);
413
- }
414
- indexOf.last = lastIndexOf;
415
- //#endregion
416
- //#region node_modules/@oscarpalmer/atoms/dist/array/find.mjs
417
- function find(array, ...parameters) {
418
- return findValue(FIND_VALUE_ITEM, array, parameters, false);
419
- }
420
- function findLast(array, ...parameters) {
421
- return findValue(FIND_VALUE_ITEM, array, parameters, true);
422
- }
423
- find.last = findLast;
424
- //#endregion
425
- //#region node_modules/@oscarpalmer/atoms/dist/array/select.mjs
426
- function reverseSelect(array, ...parameters) {
427
- return findValues("all", array, parameters, {
428
- callback: parameters.shift(),
429
- reverse: true
430
- }).matched;
431
- }
432
- function select(array, ...parameters) {
433
- return selectValues(array, parameters);
434
- }
435
- function selectValues(array, parameters) {
436
- return findValues("all", array, parameters, {
437
- callback: parameters.pop(),
438
- reverse: false
439
- }).matched;
440
- }
441
- select.reverse = reverseSelect;
442
- //#endregion
443
- //#region node_modules/@oscarpalmer/atoms/dist/array/filter.mjs
598
+ // node_modules/@oscarpalmer/atoms/dist/array/filter.mjs
444
599
  function exclude(array, ...parameters) {
445
600
  return findValues("all", array, parameters).notMatched;
446
601
  }
@@ -448,32 +603,152 @@ function filter(array, ...parameters) {
448
603
  return findValues("all", array, parameters).matched;
449
604
  }
450
605
  filter.remove = exclude;
451
- //#endregion
452
- //#region src/helpers/misc.ts
453
- function getState(value, options) {
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);
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;
627
+ filterAndMap.reverse = mapAndFilter;
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) {
454
688
  return {
689
+ name,
455
690
  value,
691
+ active: true,
456
692
  equal: typeof options === "object" && typeof options?.equal === "function" ? options.equal : void 0
457
693
  };
458
694
  }
459
- //#endregion
460
- //#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
461
742
  function createAborter(value, onAbort) {
462
743
  if (!(value instanceof AbortSignal)) return;
463
- value.addEventListener(ABORT_EVENT, onAbort, ABORT_OPTIONS);
744
+ value.addEventListener(ABORTER_EVENT, onAbort, ABORTER_OPTIONS);
464
745
  return {
465
746
  callback: onAbort,
466
747
  signal: value,
467
- cancel: () => value.removeEventListener(ABORT_EVENT, onAbort)
748
+ cancel: () => value.removeEventListener(ABORTER_EVENT, onAbort)
468
749
  };
469
750
  }
470
- const ABORT_EVENT = "abort";
471
- const ABORT_OPTIONS = { once: true };
472
- //#endregion
473
- //#region node_modules/@oscarpalmer/atoms/dist/internal/subscription.mjs
474
- const SUBSCRIPTION_NAME = "subscription";
475
- const SUBSCRIPTION_PROPERTY = "$subscription";
476
- const SUBSCRIPTION_STORE = "subscriptions";
751
+ // node_modules/@oscarpalmer/atoms/dist/internal/subscription.mjs
477
752
  function Subscription(state, property, parameters) {
478
753
  this[SUBSCRIPTION_SYMBOL] = state;
479
754
  this[property.key] = property.value;
@@ -514,9 +789,7 @@ function addSubscription(instance) {
514
789
  return;
515
790
  }
516
791
  /* istanbul ignore if */
517
- if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
518
- // istanbul ignore next
519
- return;
792
+ if (items.keyed == null || values.from.keyed == null || values.to.keyed == null) return;
520
793
  let keyedItems = items.keyed.get(key);
521
794
  if (keyedItems == null) {
522
795
  keyedItems = /* @__PURE__ */ new Set();
@@ -597,7 +870,7 @@ function createSubscriptionsProperty(input) {
597
870
  const values = isPlainObject(input) ? input : {};
598
871
  return {
599
872
  key: typeof values.key === "string" ? values.key : SUBSCRIPTION_PROPERTY,
600
- value: values.value == null ? SUBSCRIPTION_NAME : values.value
873
+ value: values.value ?? "subscription"
601
874
  };
602
875
  }
603
876
  function createSubscriptionsState(property, keys) {
@@ -645,9 +918,7 @@ function removeSubscription() {
645
918
  }
646
919
  const keyed = items.keyed?.get(key);
647
920
  /* istanbul ignore if */
648
- if (items.keyed == null || keyed == null)
649
- // istanbul ignore next
650
- return;
921
+ if (items.keyed == null || keyed == null) return;
651
922
  removeFromStore(keyed, values, this, value, key);
652
923
  if (keyed.size === 0) items.keyed.delete(key);
653
924
  }
@@ -660,46 +931,53 @@ function removeSubscription() {
660
931
  function subscriptions(parameters) {
661
932
  return new Subscriptions(parameters);
662
933
  }
663
- const SUBSCRIPTION_DISALLOWED_KEY = "Disallowed key for subscription";
664
- const SUBSCRIPTION_INVALID_KEY = "Invalid key for subscription";
665
- const SUBSCRIPTION_INVALID_VALUE = "A subscription requires a non-null value to identify it";
666
- const SUBSCRIPTION_SYMBOL = Symbol(SUBSCRIPTION_PROPERTY);
667
- //#endregion
668
- //#region src/helpers/subscription.ts
934
+ // src/helpers/subscription.ts
669
935
  function subscribeToProxy(first, second, third) {
936
+ if (!this[SYMBOL_STATE].active) throw new Error(MESSAGE_DEACTIVATED_SUBSCRIPTION);
670
937
  if (isKey(first)) return getReactiveValueInProxy(this, first).subscribe(second, third);
671
938
  return subscribeToSignal.call(this, first, second);
672
939
  }
673
940
  function subscribeToReactive(type, subscriber) {
674
- 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({
675
944
  keys: SUBSCRIPTION_TYPES,
676
945
  property: SUBSCRIPTION_PROPERTY$1
677
946
  });
678
- const [subscription, existing] = this[SYMBOL_STATE].subscriptions.create({
947
+ const [subscription, existing] = state.subscriptions.create({
679
948
  key: type,
680
949
  value: subscriber
681
950
  });
682
- 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);
683
952
  return subscription;
684
953
  }
685
954
  function subscribeToReadonly(subscriber) {
686
- 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;
687
962
  }
688
963
  function subscribeToSignal(subscriber, copy) {
689
964
  return subscribeToReactive.call(this, copy === true ? SUBSCRIPTION_TYPE_COPY : SUBSCRIPTION_TYPE_ORIGINAL, subscriber);
690
965
  }
691
- //#endregion
692
- //#region src/value/computed.ts
966
+ // src/value/computed.ts
693
967
  function Computed(callback, options) {
694
- this[SYMBOL_STATE] = getState(void 0, options);
968
+ this[SYMBOL_STATE] = getState(NAME_COMPUTED, void 0, options);
695
969
  this[SYMBOL_EFFECT] = getComputedEffect(this, callback);
696
970
  }
697
- Computed.prototype[NAME_MORA] = NAME_COMPUTED;
971
+ Computed.prototype.deactivate = deactivateComputed;
698
972
  Computed.prototype.get = getComputedValue;
699
973
  Computed.prototype.peek = peekSignalValue;
700
974
  Computed.prototype.subscribe = subscribeToSignal;
701
975
  Computed.prototype.toJSON = getJsonValue;
702
976
  Computed.prototype.toString = getStringValue;
977
+ Object.defineProperties(Computed.prototype, { active: {
978
+ enumerable: true,
979
+ get: getReactiveActive
980
+ } });
703
981
  /**
704
982
  * Create a computed value
705
983
  *
@@ -711,7 +989,7 @@ function computed(callback, options) {
711
989
  return getComputed(callback, options);
712
990
  }
713
991
  function getComputed(callback, options) {
714
- if (typeof callback !== "function") throw new TypeError("Computed callback must be a function");
992
+ if (typeof callback !== "function") throw new TypeError(MESSAGE_COMPUTED_CALLBACK);
715
993
  return new Computed(callback, options);
716
994
  }
717
995
  function getComputedEffect(instance, callback) {
@@ -734,8 +1012,9 @@ function getComputedEffect(instance, callback) {
734
1012
  return fx;
735
1013
  }
736
1014
  function getComputedValue() {
737
- const fx = this[SYMBOL_EFFECT];
738
1015
  const state = this[SYMBOL_STATE];
1016
+ if (!state.active) return state.value;
1017
+ const fx = this[SYMBOL_EFFECT];
739
1018
  if (ACTIVE.computed != null && fx !== ACTIVE.computed) {
740
1019
  state.computeds ??= /* @__PURE__ */ new Set();
741
1020
  state.computeds.add(ACTIVE.computed);
@@ -752,10 +1031,12 @@ function internalComputed(callback, options) {
752
1031
  }
753
1032
  function setAndEmit$1(instance, value, notify) {
754
1033
  const state = instance[SYMBOL_STATE];
755
- if (!notify && (state.equal ?? Object.is)(state.value, value)) return;
1034
+ if (!state.active || !notify && (state.equal ?? Object.is)(state.value, value)) return;
756
1035
  state.value = value;
757
- if (state.computeds != null && state.computeds.size > 0) for (const computed of state.computeds) computed.dirty = true;
758
- 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);
759
1040
  for (const type of SUBSCRIPTION_TYPES) {
760
1041
  if (type === "frozen") continue;
761
1042
  const subscriptions = state.subscriptions?.values.to.keyed?.get(type);
@@ -766,12 +1047,11 @@ function setAndEmit$1(instance, value, notify) {
766
1047
  }
767
1048
  flushHandlers();
768
1049
  }
769
- //#endregion
770
- //#region src/helpers/proxy.ts
1050
+ // src/helpers/proxy.ts
771
1051
  function getReactiveValueInProxy(instance, key) {
772
1052
  const state = instance[SYMBOL_STATE];
773
1053
  state.mapped ??= /* @__PURE__ */ new Map();
774
- const mapKey = String(key);
1054
+ const mapKey = getString(key);
775
1055
  let item = state.mapped.get(mapKey);
776
1056
  if (item == null) {
777
1057
  item = internalComputed(() => state.isArray ? instance.get().at(key) : instance.get()[key]);
@@ -780,18 +1060,21 @@ function getReactiveValueInProxy(instance, key) {
780
1060
  return item;
781
1061
  }
782
1062
  function getValueInProxy(first) {
1063
+ const state = this[SYMBOL_STATE];
1064
+ if (!state.active) return peekValueInProxy.call(this, first);
783
1065
  let signal;
784
- 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);
785
1067
  return getSignalValue.call(signal ?? this);
786
1068
  }
787
1069
  function isProxyKey(isArray, value) {
788
- return isArray ? typeof value === "number" : isKey(value);
1070
+ return isArray && typeof value === "number" || isKey(value);
789
1071
  }
790
1072
  function isProxyObject(isArray, value) {
791
1073
  return value == null || (isArray ? Array.isArray(value) : isPlainObject(value));
792
1074
  }
793
1075
  function notifyProxyValue() {
794
1076
  const state = this[SYMBOL_STATE];
1077
+ if (!state.active) return;
795
1078
  state.mapped ??= /* @__PURE__ */ new Map();
796
1079
  const values = [...state.mapped.values()];
797
1080
  const { length } = values;
@@ -843,6 +1126,7 @@ function setProxyProperty(state, property, value) {
843
1126
  }
844
1127
  function setProxyValue(first, second) {
845
1128
  const state = this[SYMBOL_STATE];
1129
+ if (!state.active) return;
846
1130
  if (state.isArray && first === "length") {
847
1131
  state.value.length = second;
848
1132
  return;
@@ -883,8 +1167,9 @@ function setProxyValue(first, second) {
883
1167
  }
884
1168
  function setValueInProxy(instance, target, property, value) {
885
1169
  const state = instance[SYMBOL_STATE];
1170
+ if (!state.active) return true;
886
1171
  if (state.isArray) {
887
- 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);
888
1173
  }
889
1174
  const previous = Reflect.get(target, property);
890
1175
  if (!(state.equal ?? Object.is)(previous, value)) {
@@ -894,51 +1179,67 @@ function setValueInProxy(instance, target, property, value) {
894
1179
  }
895
1180
  return true;
896
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
+ }
897
1192
  function updateProxyValue(callback) {
898
- if (typeof callback !== "function") throw new TypeError("Callback must be a function");
899
- 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));
900
1195
  }
901
- //#endregion
902
- //#region src/value/readonly.ts
1196
+ // src/value/readonly.ts
903
1197
  function Readonly(state, frozen) {
904
- this[SUBSCRIPTION_TYPE_FROZEN] = frozen;
905
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 });
906
1204
  }
907
- Readonly.prototype[NAME_MORA] = NAME_READONLY;
1205
+ Readonly.prototype.deactivate = deactivateReadonly;
908
1206
  Readonly.prototype.get = getReadonlyValue;
909
1207
  Readonly.prototype.peek = peekReadonlyValue;
910
1208
  Readonly.prototype.subscribe = subscribeToReadonly;
911
1209
  Readonly.prototype.toJSON = getJsonValue;
912
1210
  Readonly.prototype.toString = getStringValue;
913
- function getReadonlyInstance(state, frozen) {
914
- return new Readonly(state, frozen);
915
- }
1211
+ Object.defineProperties(Readonly.prototype, { active: {
1212
+ enumerable: true,
1213
+ get: getReadonlyActive
1214
+ } });
916
1215
  function getReadonlySignal(frozen) {
1216
+ const state = this[SYMBOL_STATE];
1217
+ if (!state.active) throw new Error(MESSAGE_DEACTIVATED_READONLY);
917
1218
  const key = frozen === true ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_ORIGINAL;
918
- this[SYMBOL_STATE].readonlies ??= {};
919
- this[SYMBOL_STATE].readonlies[key] ??= getReadonlyInstance(this[SYMBOL_STATE], frozen === true);
920
- return this[SYMBOL_STATE].readonlies[key];
1219
+ state.readonlies ??= {};
1220
+ state.readonlies[key] ??= new Readonly(state, frozen === true);
1221
+ return state.readonlies[key];
921
1222
  }
922
1223
  function getReadonlyValue() {
923
- return handleReadonlyValue(this, false, this[SUBSCRIPTION_TYPE_FROZEN]);
1224
+ return handleReadonlyValue(this, false, this.frozen);
924
1225
  }
925
1226
  function handleReadonlyValue(instance, peek, frozen, copy) {
1227
+ const state = instance[SYMBOL_READONLY];
926
1228
  let value;
927
- if (peek) value = peekSignalValue.call(instance, copy === true);
928
- 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;
929
1231
  return frozen ? getFrozenValue(value) : value;
930
1232
  }
931
1233
  function peekReadonlyValue(copy) {
932
- return handleReadonlyValue(this, true, this[SUBSCRIPTION_TYPE_FROZEN], copy);
1234
+ return handleReadonlyValue(this, true, this.frozen, copy);
933
1235
  }
934
- //#endregion
935
- //#region src/value/signal.ts
1236
+ // src/value/signal.ts
936
1237
  function Signal(value, options) {
937
- this[SYMBOL_STATE] = getState(void 0, options);
1238
+ this[SYMBOL_STATE] = getState(NAME_SIGNAL, void 0, options);
938
1239
  handleSignal(this, value, setAndEmit);
939
1240
  }
940
- Signal.prototype[NAME_MORA] = NAME_SIGNAL;
941
1241
  Signal.prototype.asReadonly = getReadonlySignal;
1242
+ Signal.prototype.deactivate = deactivateReactive;
942
1243
  Signal.prototype.get = getSignalValue;
943
1244
  Signal.prototype.peek = peekSignalValue;
944
1245
  Signal.prototype.set = setSignalValue;
@@ -946,6 +1247,10 @@ Signal.prototype.subscribe = subscribeToSignal;
946
1247
  Signal.prototype.toString = getStringValue;
947
1248
  Signal.prototype.toJSON = getJsonValue;
948
1249
  Signal.prototype.update = updateSignalValue;
1250
+ Object.defineProperties(Signal.prototype, { active: {
1251
+ enumerable: true,
1252
+ get: getReactiveActive
1253
+ } });
949
1254
  function setAndEmit(instance, value) {
950
1255
  const state = instance[SYMBOL_STATE];
951
1256
  if (!(state.equal ?? Object.is)(state.value, value)) {
@@ -962,11 +1267,10 @@ function signal(value, options) {
962
1267
  function updateSignalValue(callback) {
963
1268
  updateSignal(this, callback, setAndEmit);
964
1269
  }
965
- //#endregion
966
- //#region src/value/array.ts
1270
+ // src/value/array.ts
967
1271
  function ReactiveArray(value, options) {
968
1272
  this[SYMBOL_STATE] = {
969
- ...getState(void 0, options),
1273
+ ...getState(NAME_ARRAY, void 0, options),
970
1274
  isArray: true,
971
1275
  length: signal(0)
972
1276
  };
@@ -976,15 +1280,10 @@ function ReactiveArray(value, options) {
976
1280
  });
977
1281
  setProxyValue.call(this, value);
978
1282
  }
979
- ReactiveArray.prototype[NAME_MORA] = NAME_ARRAY;
980
- Object.defineProperty(ReactiveArray.prototype, PROPERTY_LENGTH, {
981
- enumerable: true,
982
- get: getArrayLength,
983
- set: setArrayLength
984
- });
985
1283
  ReactiveArray.prototype.asReadonly = getReadonlySignal;
986
1284
  ReactiveArray.prototype.at = getArrayValues;
987
1285
  ReactiveArray.prototype.clear = clearArrayValues;
1286
+ ReactiveArray.prototype.deactivate = deactivateArray;
988
1287
  ReactiveArray.prototype.filter = filterArrayValues;
989
1288
  ReactiveArray.prototype.get = getArrayValues;
990
1289
  ReactiveArray.prototype.map = mapArrayValues;
@@ -1001,14 +1300,33 @@ ReactiveArray.prototype.toString = getStringValue;
1001
1300
  ReactiveArray.prototype.toJSON = getJsonValue;
1002
1301
  ReactiveArray.prototype.unshift = unshiftArrayValues;
1003
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
+ });
1004
1314
  function array(value, options) {
1005
1315
  return new ReactiveArray(value, options);
1006
1316
  }
1007
1317
  function clearArrayValues() {
1008
- 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);
1009
1326
  }
1010
1327
  function filterArrayValues(callback) {
1011
- 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)));
1012
1330
  }
1013
1331
  function getArrayLength() {
1014
1332
  return this[SYMBOL_STATE].length.get();
@@ -1017,36 +1335,47 @@ function getArrayValues(value) {
1017
1335
  return value === "length" ? this[SYMBOL_STATE].length.get() : getValueInProxy.call(this, value);
1018
1336
  }
1019
1337
  function mapArrayValues(callback) {
1020
- 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))));
1021
1340
  }
1022
1341
  function peekArrayValue(first, second) {
1023
1342
  return first === "length" ? this[SYMBOL_STATE].length.peek() : peekValueInProxy.call(this, first, second);
1024
1343
  }
1025
1344
  function popArrayValue() {
1026
- return this[SYMBOL_STATE].value.pop();
1345
+ const state = this[SYMBOL_STATE];
1346
+ return state.active ? state.value.pop() : void 0;
1027
1347
  }
1028
1348
  function pushArrayValues(...items) {
1029
- return this[SYMBOL_STATE].value.push(...items);
1349
+ const state = this[SYMBOL_STATE];
1350
+ return state.active ? state.value.push(...items) : state.value.length;
1030
1351
  }
1031
1352
  function selectArrayValues(filter, map) {
1032
- return computed(() => select(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)));
1033
1355
  }
1034
1356
  function setArrayLength(value) {
1035
- const values = this[SYMBOL_STATE].value;
1357
+ const state = this[SYMBOL_STATE];
1358
+ if (!state.active) return;
1359
+ const values = state.value;
1036
1360
  if (typeof value === "number" && !Number.isNaN(value) && value >= 0 && value !== values.length) values.length = value;
1037
1361
  }
1038
1362
  function shiftArrayValue() {
1039
- return this[SYMBOL_STATE].value.shift();
1363
+ const state = this[SYMBOL_STATE];
1364
+ return state.active ? state.value.shift() : void 0;
1040
1365
  }
1041
1366
  function spliceArrayValues(from, to, ...items) {
1042
- const values = this[SYMBOL_STATE].value;
1367
+ const state = this[SYMBOL_STATE];
1368
+ if (!state.active) return [];
1369
+ const values = state.value;
1043
1370
  return values.splice(from, to ?? values.length, ...items);
1044
1371
  }
1045
1372
  function unshiftArrayValues(...items) {
1046
- return this[SYMBOL_STATE].value.unshift(...items);
1373
+ const state = this[SYMBOL_STATE];
1374
+ return state.active ? state.value.unshift(...items) : state.value.length;
1047
1375
  }
1048
1376
  function updateArray(instance, type, array) {
1049
1377
  const state = instance[SYMBOL_STATE];
1378
+ if (!state.active) return () => void 0;
1050
1379
  const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
1051
1380
  const previousArray = affectsLength ? [] : array.slice();
1052
1381
  const previousLength = array.length;
@@ -1059,18 +1388,17 @@ function updateArray(instance, type, array) {
1059
1388
  return result;
1060
1389
  };
1061
1390
  }
1062
- //#endregion
1063
- //#region src/value/store.ts
1391
+ // src/value/store.ts
1064
1392
  function ReactiveStore(value, options) {
1065
1393
  this[SYMBOL_STATE] = {
1066
- ...getState(void 0, options),
1394
+ ...getState(NAME_STORE, void 0, options),
1067
1395
  isArray: false
1068
1396
  };
1069
1397
  this[SYMBOL_STATE].value = new Proxy({}, { set: (target, property, value) => setValueInProxy(this, target, property, value) });
1070
1398
  setProxyValue.call(this, value);
1071
1399
  }
1072
- ReactiveStore.prototype[NAME_MORA] = NAME_STORE;
1073
1400
  ReactiveStore.prototype.asReadonly = getReadonlySignal;
1401
+ ReactiveStore.prototype.deactivate = deactivateProxy;
1074
1402
  ReactiveStore.prototype.get = getValueInProxy;
1075
1403
  ReactiveStore.prototype.notify = notifyProxyValue;
1076
1404
  ReactiveStore.prototype.peek = peekValueInProxy;
@@ -1079,8 +1407,11 @@ ReactiveStore.prototype.subscribe = subscribeToProxy;
1079
1407
  ReactiveStore.prototype.toJSON = getJsonValue;
1080
1408
  ReactiveStore.prototype.toString = getStringValue;
1081
1409
  ReactiveStore.prototype.update = updateProxyValue;
1410
+ Object.defineProperties(ReactiveStore.prototype, { active: {
1411
+ enumerable: true,
1412
+ get: getReactiveActive
1413
+ } });
1082
1414
  function store(value, options) {
1083
1415
  return new ReactiveStore(value, options);
1084
1416
  }
1085
- //#endregion
1086
1417
  export { array, computed, effect, isComputed, isEffect, isReactive, isReactiveArray, isReactiveStore, isReadonlySignal, isSignal, signal, startBatch, stopBatch, store };