@oscarpalmer/mora 0.30.0 → 0.32.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 (55) hide show
  1. package/dist/batch.d.mts +4 -5
  2. package/dist/batch.mjs +4 -2
  3. package/dist/constants.d.mts +29 -18
  4. package/dist/constants.mjs +19 -2
  5. package/dist/effect.d.mts +4 -5
  6. package/dist/effect.mjs +2 -2
  7. package/dist/helpers/is.d.mts +21 -15
  8. package/dist/helpers/is.mjs +21 -12
  9. package/dist/helpers/proxy.d.mts +12 -10
  10. package/dist/helpers/proxy.mjs +32 -14
  11. package/dist/helpers/subscription.d.mts +8 -0
  12. package/dist/helpers/subscription.mjs +27 -0
  13. package/dist/helpers/value.d.mts +8 -6
  14. package/dist/helpers/value.mjs +30 -4
  15. package/dist/index.d.mts +4 -3
  16. package/dist/index.mjs +2 -2
  17. package/dist/models.d.mts +108 -84
  18. package/dist/mora.full.mjs +504 -247
  19. package/dist/value/array.d.mts +4 -5
  20. package/dist/value/array.mjs +25 -56
  21. package/dist/value/computed.d.mts +3 -4
  22. package/dist/value/computed.mjs +14 -14
  23. package/dist/value/reactive.d.mts +2 -3
  24. package/dist/value/reactive.mjs +0 -1
  25. package/dist/value/readonly.d.mts +5 -0
  26. package/dist/value/readonly.mjs +33 -0
  27. package/dist/value/signal.d.mts +4 -5
  28. package/dist/value/signal.mjs +10 -17
  29. package/dist/value/store.d.mts +4 -5
  30. package/dist/value/store.mjs +17 -41
  31. package/package.json +6 -6
  32. package/src/batch.ts +15 -5
  33. package/src/constants.ts +41 -3
  34. package/src/effect.ts +6 -2
  35. package/src/helpers/is.ts +37 -12
  36. package/src/helpers/proxy.ts +99 -49
  37. package/src/helpers/subscription.ts +78 -0
  38. package/src/helpers/value.ts +69 -4
  39. package/src/index.ts +18 -2
  40. package/src/models.ts +131 -86
  41. package/src/value/array.ts +67 -120
  42. package/src/value/computed.ts +36 -13
  43. package/src/value/reactive.ts +8 -5
  44. package/src/value/readonly.ts +72 -0
  45. package/src/value/signal.ts +22 -16
  46. package/src/value/store.ts +37 -70
  47. package/types/constants.d.ts +1 -1
  48. package/types/index.d.ts +1 -1
  49. package/types/value/array.d.ts +1 -1
  50. package/types/value/computed.d.ts +0 -3
  51. package/types/value/signal.d.ts +1 -1
  52. package/types/value/store.d.ts +1 -1
  53. package/dist/subscription.d.mts +0 -7
  54. package/dist/subscription.mjs +0 -27
  55. package/src/subscription.ts +0 -45
@@ -3,7 +3,7 @@ const ACTIVE = {};
3
3
  const BATCH = {
4
4
  depth: 0,
5
5
  flushing: false,
6
- handlers: /* @__PURE__ */ new Set()
6
+ handlers: /* @__PURE__ */ new Map()
7
7
  };
8
8
  const METHODS_AFFECTING_LENGTH = /* @__PURE__ */ new Set([
9
9
  "pop",
@@ -23,14 +23,31 @@ const NAME_ARRAY = "array";
23
23
  const NAME_COMPUTED = "computed";
24
24
  const NAME_EFFECT = "effect";
25
25
  const NAME_MORA = "$mora";
26
+ const NAME_READONLY = "readonly";
26
27
  const NAME_SIGNAL = "signal";
27
28
  const NAME_STORE = "store";
29
+ const NAME_SUBSCRIPTION = "subscription";
28
30
  const NAME_ALL = /* @__PURE__ */ new Set([
29
31
  NAME_ARRAY,
30
32
  NAME_COMPUTED,
33
+ NAME_READONLY,
31
34
  NAME_SIGNAL,
32
35
  NAME_STORE
33
36
  ]);
37
+ const SUBSCRIPTION_PROPERTY$1 = {
38
+ key: NAME_MORA,
39
+ value: NAME_SUBSCRIPTION
40
+ };
41
+ const SUBSCRIPTION_TYPE_COPY = "copy";
42
+ const SUBSCRIPTION_TYPE_FROZEN = "frozen";
43
+ const SUBSCRIPTION_TYPE_ORIGINAL = "original";
44
+ const SUBSCRIPTION_TYPE_READONLY = "readonly";
45
+ const SUBSCRIPTION_TYPES_COPY = /* @__PURE__ */ new Set([SUBSCRIPTION_TYPE_COPY, SUBSCRIPTION_TYPE_READONLY]);
46
+ const SUBSCRIPTION_TYPES = /* @__PURE__ */ new Set([
47
+ ...SUBSCRIPTION_TYPES_COPY,
48
+ SUBSCRIPTION_TYPE_FROZEN,
49
+ SUBSCRIPTION_TYPE_ORIGINAL
50
+ ]);
34
51
  //#endregion
35
52
  //#region src/effect.ts
36
53
  /**
@@ -45,7 +62,7 @@ function effect(callback) {
45
62
  }
46
63
  function getEffect(callback) {
47
64
  const state = { callback };
48
- const instance = Object.freeze({ $mora: NAME_EFFECT });
65
+ const instance = Object.freeze({ [NAME_MORA]: NAME_EFFECT });
49
66
  runEffect(state);
50
67
  return [instance, state];
51
68
  }
@@ -62,6 +79,98 @@ function runEffect(state) {
62
79
  }
63
80
  }
64
81
  //#endregion
82
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
83
+ /**
84
+ * Is the value a _Key_?
85
+ *
86
+ * @param value Value to check
87
+ * @returns `true` if the value is a _Key_ _(`number` or `string`)_, otherwise `false`
88
+ */
89
+ function isKey(value) {
90
+ return typeof value === "number" || typeof value === "string";
91
+ }
92
+ /**
93
+ * Is the value a plain object?
94
+ *
95
+ * @param value Value to check
96
+ * @returns `true` if the value is a plain object, otherwise `false`
97
+ */
98
+ function isPlainObject(value) {
99
+ if (value === null || typeof value !== "object") return false;
100
+ if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
101
+ const prototype = Object.getPrototypeOf(value);
102
+ return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
103
+ }
104
+ //#endregion
105
+ //#region src/helpers/value.ts
106
+ function emitValue(state) {
107
+ for (const computed of state.computeds) computed.dirty = true;
108
+ for (const effect of state.effects) BATCH.handlers.set(effect, effect);
109
+ for (const type of SUBSCRIPTION_TYPES) {
110
+ const subscriptions = state.subscriptions?.values.to.keyed?.get(type);
111
+ if (subscriptions != null) for (const [subscription, callback] of subscriptions) BATCH.handlers.set(subscription, {
112
+ callback,
113
+ state,
114
+ frozen: type === SUBSCRIPTION_TYPE_FROZEN,
115
+ copy: SUBSCRIPTION_TYPES_COPY.has(type)
116
+ });
117
+ }
118
+ if (BATCH.depth === 0) flushHandlers();
119
+ }
120
+ function equalArrays(state, first, second) {
121
+ let { length } = first;
122
+ if (length !== second.length) return false;
123
+ let offset = 0;
124
+ if (length >= 100) {
125
+ offset = Math.round(length / 10);
126
+ offset = offset > 25 ? 25 : offset;
127
+ for (let index = 0; index < offset; index += 1) if (!state.equal(first[index], second[index])) return false;
128
+ }
129
+ length -= offset;
130
+ for (let index = offset; index < length; index += 1) if (!state.equal(first[index], second[index])) return false;
131
+ return true;
132
+ }
133
+ function getFrozenValue(value) {
134
+ let frozen = value;
135
+ if (Array.isArray(frozen)) frozen = Object.freeze(frozen.slice());
136
+ else if (isPlainObject(frozen)) frozen = Object.freeze({ ...frozen });
137
+ return frozen;
138
+ }
139
+ function getSimpleValue(state) {
140
+ if (ACTIVE.computed != null) state.computeds.add(ACTIVE.computed);
141
+ if (ACTIVE.effect != null) state.effects.add(ACTIVE.effect);
142
+ return state.value;
143
+ }
144
+ function handleSimpleValue(state, origin, setValue, onAfter) {
145
+ try {
146
+ let actual = typeof origin === "function" ? origin() : origin;
147
+ if (actual instanceof Promise) {
148
+ state.promise = actual;
149
+ actual.then((value) => {
150
+ if (actual === state.promise) {
151
+ state.promise = void 0;
152
+ setValue(state, value);
153
+ }
154
+ }).catch(() => {
155
+ if (actual === state.promise) state.promise = void 0;
156
+ });
157
+ } else setValue(state, actual);
158
+ } catch {} finally {
159
+ onAfter?.();
160
+ }
161
+ }
162
+ function peekSimpleValue(value, copy) {
163
+ let peeked = value;
164
+ if (!copy) return peeked;
165
+ if (Array.isArray(peeked)) peeked = peeked.slice();
166
+ else if (isPlainObject(peeked)) peeked = { ...peeked };
167
+ return peeked;
168
+ }
169
+ function updateSimpleValue(state, callback, setValue) {
170
+ if (typeof callback !== "function") throw new TypeError("Callback must be a function");
171
+ handleSimpleValue(state, callback(state.value), setValue);
172
+ }
173
+ //#endregion
65
174
  //#region src/batch.ts
66
175
  function flushHandlers() {
67
176
  if (BATCH.flushing) return;
@@ -72,8 +181,9 @@ function flushHandlers() {
72
181
  const { length } = handlers;
73
182
  BATCH.handlers.clear();
74
183
  for (let index = 0; index < length; index += 1) {
75
- const handler = handlers[index];
76
- if (typeof handler.destroy === "function") handler.callback(handler.state.value);
184
+ const [, handler] = handlers[index];
185
+ const subscription = handler;
186
+ if (typeof subscription.frozen === "boolean") subscription.callback(subscription.frozen ? getFrozenValue(subscription.state.value) : peekSimpleValue(subscription.state.value, subscription.copy));
77
187
  else runEffect(handler);
78
188
  }
79
189
  }
@@ -99,15 +209,6 @@ function stopBatch() {
99
209
  //#endregion
100
210
  //#region src/helpers/is.ts
101
211
  /**
102
- * Is the value a reactive array?
103
- *
104
- * @param value Value to check
105
- * @returns True if value is a {@link ReactiveArray}
106
- */
107
- function isArray(value) {
108
- return isMora(value, NAME_ARRAY);
109
- }
110
- /**
111
212
  * Is the value a computed signal?
112
213
  *
113
214
  * @param value Value to check
@@ -146,6 +247,33 @@ function isReactive(value) {
146
247
  function isSignal(value) {
147
248
  return isMora(value, NAME_SIGNAL);
148
249
  }
250
+ /**
251
+ * Is the value a reactive array?
252
+ *
253
+ * @param value Value to check
254
+ * @returns True if value is a {@link ReactiveArray}
255
+ */
256
+ function isReactiveArray(value) {
257
+ return isMora(value, NAME_ARRAY);
258
+ }
259
+ /**
260
+ * Is the value a reactive store?
261
+ *
262
+ * @param value Value to check
263
+ * @returns True if value is a {@link Store}
264
+ */
265
+ function isReactiveStore(value) {
266
+ return isMora(value, NAME_STORE);
267
+ }
268
+ /**
269
+ * Is the value a readonly signal?
270
+ *
271
+ * @param value Value to check
272
+ * @returns True if value is a {@link ReadonlySignal}
273
+ */
274
+ function isReadonlySignal(value) {
275
+ return isMora(value, NAME_READONLY);
276
+ }
149
277
  //#endregion
150
278
  //#region node_modules/@oscarpalmer/atoms/dist/internal/array/callbacks.mjs
151
279
  function getArrayCallback(value) {
@@ -153,6 +281,7 @@ function getArrayCallback(value) {
153
281
  case "function": return value;
154
282
  case "number":
155
283
  case "string": return typeof value === "string" && value.includes(".") ? void 0 : (obj) => obj[value];
284
+ default: return;
156
285
  }
157
286
  }
158
287
  function getArrayCallbacks(bool, key, value) {
@@ -164,10 +293,18 @@ function getArrayCallbacks(bool, key, value) {
164
293
  }
165
294
  //#endregion
166
295
  //#region node_modules/@oscarpalmer/atoms/dist/internal/array/find.mjs
296
+ function createFindParameters(original) {
297
+ const { length } = original;
298
+ return {
299
+ bool: length === 1 && typeof original[0] === "function" ? original[0] : void 0,
300
+ key: length === 2 ? original[0] : void 0,
301
+ value: length === 1 && typeof original[0] !== "function" ? original[0] : original[1]
302
+ };
303
+ }
167
304
  function findValue(type, array, parameters, reversed) {
168
305
  const findIndex = type === FIND_VALUE_INDEX;
169
306
  if (!Array.isArray(array) || array.length === 0) return findIndex ? -1 : void 0;
170
- const { bool, key, value } = getFindParameters(parameters);
307
+ const { bool, key, value } = createFindParameters(parameters);
171
308
  const callbacks = getArrayCallbacks(bool, key);
172
309
  if (callbacks?.bool == null && callbacks?.keyed == null) {
173
310
  if (findIndex) return reversed ? array.lastIndexOf(value) : array.indexOf(value);
@@ -194,18 +331,22 @@ function findValues(type, array, parameters, mapper) {
194
331
  };
195
332
  if (!Array.isArray(array) || array.length === 0) return result;
196
333
  const { length } = array;
197
- const { bool, key, value } = getFindParameters(parameters);
334
+ const { bool, key, value } = createFindParameters(parameters);
198
335
  const callbacks = getArrayCallbacks(bool, key);
199
- if (type === "unique" && callbacks?.keyed == null && length >= UNIQUE_THRESHOLD) {
336
+ if (type === "unique" && callbacks?.keyed == null && length >= FIND_UNIQUE_THRESHOLD) {
200
337
  result.matched = [...new Set(array)];
201
338
  return result;
202
339
  }
203
- const mapCallback = getArrayCallback(mapper);
340
+ const mapCallback = getArrayCallback(mapper?.callback);
341
+ const mapReverse = mapper?.reverse ?? false;
342
+ const mapAfter = mapCallback == null ? void 0 : mapReverse ? void 0 : mapCallback;
343
+ const mapBefore = mapCallback == null ? void 0 : mapReverse ? mapCallback : void 0;
204
344
  if (callbacks?.bool != null || type === "all" && key == null) {
205
345
  const callback = callbacks?.bool ?? ((item) => Object.is(item, value));
206
346
  for (let index = 0; index < length; index += 1) {
207
347
  const item = array[index];
208
- if (callback(item, index, array)) result.matched.push(mapCallback?.(item, index, array) ?? item);
348
+ const transformed = mapBefore?.(item, index, array) ?? item;
349
+ if (callback(transformed, index, array)) result.matched.push(mapAfter?.(item, index, array) ?? transformed);
209
350
  else result.notMatched.push(item);
210
351
  }
211
352
  return result;
@@ -213,71 +354,64 @@ function findValues(type, array, parameters, mapper) {
213
354
  const keys = /* @__PURE__ */ new Set();
214
355
  for (let index = 0; index < length; index += 1) {
215
356
  const item = array[index];
216
- const keyed = callbacks?.keyed?.(item, index, array) ?? item;
357
+ let keyed;
358
+ let transformed;
359
+ if (mapBefore == null) {
360
+ keyed = callbacks?.keyed?.(item, index, array) ?? item;
361
+ transformed = item;
362
+ } else {
363
+ transformed = mapBefore(item, index, array);
364
+ keyed = callbacks?.keyed?.(transformed, index, array) ?? transformed;
365
+ }
217
366
  if (type === "all" && Object.is(keyed, value) || type === "unique" && !keys.has(keyed)) {
218
367
  keys.add(keyed);
219
- result.matched.push(mapCallback?.(item, index, array) ?? item);
368
+ result.matched.push(mapAfter?.(item, index, array) ?? transformed);
220
369
  } else result.notMatched.push(item);
221
370
  }
222
371
  return result;
223
372
  }
224
- function getFindParameters(original) {
225
- const { length } = original;
226
- return {
227
- bool: length === 1 && typeof original[0] === "function" ? original[0] : void 0,
228
- key: length === 2 ? original[0] : void 0,
229
- value: length === 1 && typeof original[0] !== "function" ? original[0] : original[1]
230
- };
231
- }
232
373
  const FIND_VALUE_INDEX = "index";
233
374
  const FIND_VALUE_ITEM = "item";
234
- const UNIQUE_THRESHOLD = 100;
375
+ const FIND_UNIQUE_THRESHOLD = 100;
235
376
  //#endregion
236
377
  //#region node_modules/@oscarpalmer/atoms/dist/internal/array/index-of.mjs
237
378
  function indexOf(array, ...parameters) {
238
379
  return findValue(FIND_VALUE_INDEX, array, parameters, false);
239
380
  }
240
- indexOf.last = lastIndexOf;
241
381
  function lastIndexOf(array, ...parameters) {
242
382
  return findValue(FIND_VALUE_INDEX, array, parameters, true);
243
383
  }
244
- //#endregion
245
- //#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
246
- /**
247
- * Is the value a _Key_?
248
- *
249
- * @param value Value to check
250
- * @returns `true` if the value is a _Key_ _(`number` or `string`)_, otherwise `false`
251
- */
252
- function isKey(value) {
253
- return typeof value === "number" || typeof value === "string";
254
- }
255
- /**
256
- * Is the value a plain object?
257
- *
258
- * @param value Value to check
259
- * @returns `true` if the value is a plain object, otherwise `false`
260
- */
261
- function isPlainObject(value) {
262
- if (value === null || typeof value !== "object") return false;
263
- if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
264
- const prototype = Object.getPrototypeOf(value);
265
- return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
266
- }
384
+ indexOf.last = lastIndexOf;
385
+ Object.defineProperty(indexOf, "last", { value: lastIndexOf });
267
386
  //#endregion
268
387
  //#region node_modules/@oscarpalmer/atoms/dist/array/find.mjs
269
388
  function find(array, ...parameters) {
270
389
  return findValue(FIND_VALUE_ITEM, array, parameters, false);
271
390
  }
272
- find.last = findLast;
273
391
  function findLast(array, ...parameters) {
274
392
  return findValue(FIND_VALUE_ITEM, array, parameters, true);
275
393
  }
394
+ find.last = findLast;
395
+ Object.defineProperty(find, "last", { value: findLast });
276
396
  //#endregion
277
397
  //#region node_modules/@oscarpalmer/atoms/dist/array/select.mjs
398
+ function reverseSelect(array, ...parameters) {
399
+ return findValues("all", array, parameters, {
400
+ callback: parameters.shift(),
401
+ reverse: true
402
+ }).matched;
403
+ }
278
404
  function select(array, ...parameters) {
279
- return findValues("all", array, parameters, parameters.pop()).matched;
405
+ return selectValues(array, parameters);
280
406
  }
407
+ function selectValues(array, parameters) {
408
+ return findValues("all", array, parameters, {
409
+ callback: parameters.pop(),
410
+ reverse: false
411
+ }).matched;
412
+ }
413
+ select.reverse = reverseSelect;
414
+ Object.defineProperty(select, "reverse", { value: reverseSelect });
281
415
  //#endregion
282
416
  //#region node_modules/@oscarpalmer/atoms/dist/array/filter.mjs
283
417
  function exclude(array, ...parameters) {
@@ -287,81 +421,221 @@ function filter(array, ...parameters) {
287
421
  return findValues("all", array, parameters).matched;
288
422
  }
289
423
  filter.remove = exclude;
424
+ Object.defineProperty(filter, "remove", { value: exclude });
290
425
  //#endregion
291
- //#region node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
292
- /**
293
- * A function that does nothing, which can be useful, I guess…
294
- */
295
- function noop$1() {}
296
- //#endregion
297
- //#region src/helpers/value.ts
298
- function emitValue(state) {
299
- for (const computed of state.computeds) computed.dirty = true;
300
- for (const effect of state.effects) BATCH.handlers.add(effect);
301
- for (const [, subscription] of state.subscriptions) BATCH.handlers.add(subscription);
302
- if (BATCH.depth === 0) flushHandlers();
426
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/abort.mjs
427
+ function createAborter(value, onAbort) {
428
+ if (!(value instanceof AbortSignal)) return;
429
+ value.addEventListener(ABORT_EVENT, onAbort, ABORT_OPTIONS);
430
+ return {
431
+ callback: onAbort,
432
+ signal: value,
433
+ cancel: () => value.removeEventListener(ABORT_EVENT, onAbort)
434
+ };
303
435
  }
304
- function equalArrays(state, first, second) {
305
- let { length } = first;
306
- if (length !== second.length) return false;
307
- let offset = 0;
308
- if (length >= 100) {
309
- offset = Math.round(length / 10);
310
- offset = offset > 25 ? 25 : offset;
311
- for (let index = 0; index < offset; index += 1) if (!state.equal(first[index], second[index])) return false;
436
+ const ABORT_EVENT = "abort";
437
+ const ABORT_OPTIONS = { once: true };
438
+ //#endregion
439
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/subscription.mjs
440
+ function addSubscription(subscriptions, subscription, state) {
441
+ const { items, values } = subscriptions;
442
+ const { key, value } = state.parameters;
443
+ if (!isKey(key)) {
444
+ items.any.add(subscription);
445
+ values.from.any.set(value, subscription);
446
+ values.to.any.set(subscription, value);
447
+ return;
312
448
  }
313
- length -= offset;
314
- for (let index = offset; index < length; index += 1) if (!state.equal(first[index], second[index])) return false;
315
- return true;
449
+ /* istanbul ignore if */
450
+ if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
451
+ // istanbul ignore next
452
+ return;
453
+ let keyedItems = items.keyed.get(key);
454
+ if (keyedItems == null) {
455
+ keyedItems = /* @__PURE__ */ new Set();
456
+ items.keyed.set(key, keyedItems);
457
+ }
458
+ keyedItems.add(subscription);
459
+ let keyedFrom = values.from.keyed.get(key);
460
+ if (keyedFrom == null) {
461
+ keyedFrom = /* @__PURE__ */ new Map();
462
+ values.from.keyed.set(key, keyedFrom);
463
+ }
464
+ keyedFrom.set(value, subscription);
465
+ let keyedTo = values.to.keyed.get(key);
466
+ if (keyedTo == null) {
467
+ keyedTo = /* @__PURE__ */ new Map();
468
+ values.to.keyed.set(key, keyedTo);
469
+ }
470
+ keyedTo.set(subscription, value);
316
471
  }
317
- function getSimpleValue(state) {
318
- if (ACTIVE.computed != null) state.computeds.add(ACTIVE.computed);
319
- if (ACTIVE.effect != null) state.effects.add(ACTIVE.effect);
320
- return state.value;
472
+ function clearSubscriptions(store) {
473
+ for (const susbcription of store.values.to.any.keys()) susbcription.unsubscribe();
474
+ if (store.values.to.keyed != null) for (const values of store.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
321
475
  }
322
- function handleSimpleValue(state, origin, setValue, onAfter) {
323
- try {
324
- let actual = typeof origin === "function" ? origin() : origin;
325
- if (actual instanceof Promise) {
326
- state.promise = actual;
327
- actual.then((value) => {
328
- if (actual === state.promise) {
329
- state.promise = void 0;
330
- setValue(state, value);
331
- }
332
- }).catch(() => {
333
- if (actual === state.promise) state.promise = void 0;
334
- });
335
- } else setValue(state, actual);
336
- } catch {} finally {
337
- onAfter?.();
476
+ function createSubscription(subscriptions, property, params) {
477
+ const parameters = createSubscriptionParameters(params);
478
+ if (parameters.signal?.aborted ?? false) throw new Error(parameters.signal?.reason);
479
+ const state = {
480
+ parameters,
481
+ active: true
482
+ };
483
+ const existing = getExistingSubscription(subscriptions, state);
484
+ if (existing != null) return [existing, true];
485
+ if (subscriptions.keys != null && isKey(parameters.key)) {
486
+ if (subscriptions.keys === false) throw new Error(SUBSCRIPTION_DISALLOWED_KEY);
487
+ else if (subscriptions.keys !== true && !subscriptions.keys.has(parameters.key)) throw new Error(SUBSCRIPTION_INVALID_KEY);
338
488
  }
489
+ state.aborter = createAborter(parameters.signal, () => unsubscribe(subscriptions, instance, state));
490
+ const instance = { unsubscribe: () => unsubscribe(subscriptions, instance, state) };
491
+ Object.defineProperties(instance, {
492
+ [SUBSCRIPTION_PROPERTY]: { value: SUBSCRIPTION_NAME },
493
+ [property.key]: { value: property.value },
494
+ active: {
495
+ enumerable: true,
496
+ get: () => (parameters.isActive?.() ?? true) && state.active
497
+ }
498
+ });
499
+ addSubscription(subscriptions, instance, state);
500
+ return [Object.freeze(instance), false];
339
501
  }
340
- //#endregion
341
- //#region src/subscription.ts
342
- function noop() {}
343
- function subscribe(state, callback) {
344
- if (typeof callback !== "function" || state.subscriptions.has(callback)) return noop;
345
- state.subscriptions.set(callback, subscription(state, callback));
346
- return () => {
347
- unsubscribe(state, callback);
502
+ function getExistingSubscription(subscriptions, state) {
503
+ const { values } = subscriptions;
504
+ const { parameters } = state;
505
+ return isKey(parameters.key) ? values.from.keyed?.get(parameters.key)?.get(parameters.value) : values.from.any.get(parameters.value);
506
+ }
507
+ function createSubscriptionParameters(input) {
508
+ const values = isPlainObject(input) ? input : {};
509
+ if (values.value == null) throw new Error(SUBSCRIPTION_INVALID_VALUE);
510
+ return {
511
+ isActive: typeof values.isActive === "function" ? values.isActive : void 0,
512
+ key: isKey(values.key) ? values.key : void 0,
513
+ signal: values.signal instanceof AbortSignal ? values.signal : void 0,
514
+ value: values.value
348
515
  };
349
516
  }
350
- function subscription(state, callback) {
351
- const instance = {
352
- callback,
353
- state,
354
- destroy: () => {
355
- instance.callback = noop;
356
- instance.state = void 0;
517
+ function createSubscriptionsParameters(input) {
518
+ const values = isPlainObject(input) ? input : {};
519
+ let keys;
520
+ if (values.keys instanceof Set) keys = values.keys;
521
+ else keys = typeof values.keys === "boolean" ? values.keys : false;
522
+ return {
523
+ keys,
524
+ property: createSubscriptionsProperty(values.property)
525
+ };
526
+ }
527
+ function createSubscriptionsProperty(input) {
528
+ const values = isPlainObject(input) ? input : {};
529
+ return {
530
+ key: typeof values.key === "string" ? values.key : SUBSCRIPTION_PROPERTY,
531
+ value: values.value == null ? SUBSCRIPTION_NAME : values.value
532
+ };
533
+ }
534
+ function createSubscriptionsState(keys) {
535
+ return {
536
+ keys,
537
+ items: {
538
+ any: /* @__PURE__ */ new Set(),
539
+ keyed: keys === false ? void 0 : /* @__PURE__ */ new Map()
540
+ },
541
+ values: {
542
+ from: {
543
+ any: /* @__PURE__ */ new Map(),
544
+ keyed: keys === false ? void 0 : /* @__PURE__ */ new Map()
545
+ },
546
+ to: {
547
+ any: /* @__PURE__ */ new Map(),
548
+ keyed: keys === false ? void 0 : /* @__PURE__ */ new Map()
549
+ }
357
550
  }
358
551
  };
359
- callback(state.value);
360
- return instance;
361
552
  }
362
- function unsubscribe(state, callback) {
363
- state.subscriptions.get(callback)?.destroy();
364
- state.subscriptions.delete(callback);
553
+ function removeFromStore(items, values, subscription, value, key) {
554
+ items.delete(subscription);
555
+ if (key == null) {
556
+ values.from.any.delete(value);
557
+ values.to.any.delete(subscription);
558
+ } else {
559
+ values.from.keyed?.get(key)?.delete(value);
560
+ values.to.keyed?.get(key)?.delete(subscription);
561
+ }
562
+ }
563
+ function removeSubscription(subscriptionsState, subscription, state) {
564
+ if (!state.active) return;
565
+ state.aborter = void 0;
566
+ state.active = false;
567
+ state.parameters.isActive = void 0;
568
+ state.parameters.signal = void 0;
569
+ const { items, values } = subscriptionsState;
570
+ const { key, value } = state.parameters;
571
+ if (!isKey(key)) {
572
+ removeFromStore(items.any, values, subscription, value);
573
+ return;
574
+ }
575
+ const keyed = items.keyed?.get(key);
576
+ /* istanbul ignore if */
577
+ if (items.keyed == null || keyed == null)
578
+ // istanbul ignore next
579
+ return;
580
+ removeFromStore(keyed, values, subscription, value, key);
581
+ if (keyed.size === 0) items.keyed.delete(key);
582
+ }
583
+ /**
584
+ * Create a subscription store
585
+ *
586
+ * @param parameters Store parameters
587
+ * @returns Subscription store
588
+ */
589
+ function subscriptions(parameters) {
590
+ const { keys, property } = createSubscriptionsParameters(parameters);
591
+ const state = createSubscriptionsState(keys);
592
+ const instance = {
593
+ clear: () => clearSubscriptions(state),
594
+ create: (parameters) => createSubscription(state, property, parameters)
595
+ };
596
+ Object.defineProperties(instance, {
597
+ [SUBSCRIPTION_PROPERTY]: { value: SUBSCRIPTION_STORE },
598
+ items: {
599
+ enumerable: true,
600
+ value: state.items
601
+ },
602
+ values: {
603
+ enumerable: true,
604
+ value: state.values
605
+ }
606
+ });
607
+ return Object.freeze(instance);
608
+ }
609
+ function unsubscribe(subscriptionsState, subscription, state) {
610
+ state.aborter?.cancel();
611
+ removeSubscription(subscriptionsState, subscription, state);
612
+ }
613
+ const SUBSCRIPTION_DISALLOWED_KEY = "Disallowed key for subscription";
614
+ const SUBSCRIPTION_INVALID_KEY = "Invalid key for subscription";
615
+ const SUBSCRIPTION_INVALID_VALUE = "A subscription requires a non-null value to identify it";
616
+ const SUBSCRIPTION_NAME = "subscription";
617
+ const SUBSCRIPTION_PROPERTY = "$subscriptions";
618
+ const SUBSCRIPTION_STORE = "subscriptions";
619
+ //#endregion
620
+ //#region src/helpers/subscription.ts
621
+ function subscribeToProxy(isArray, instance, state, mapped, first, second, third) {
622
+ if (isKey(first)) return getReactiveValueInProxy(instance, mapped, first, isArray).subscribe(second, third);
623
+ return subscribeToSignal(state, first, second === true);
624
+ }
625
+ function subscribeToReactive(type, state, callback) {
626
+ state.subscriptions ??= subscriptions({
627
+ keys: SUBSCRIPTION_TYPES,
628
+ property: SUBSCRIPTION_PROPERTY$1
629
+ });
630
+ const [subscription, existing] = state.subscriptions.create({
631
+ key: type,
632
+ value: callback
633
+ });
634
+ if (!existing) callback(type === "frozen" ? getFrozenValue(state.value) : peekSimpleValue(state.value, SUBSCRIPTION_TYPES_COPY.has(type)));
635
+ return subscription;
636
+ }
637
+ function subscribeToSignal(state, callback, copy) {
638
+ return subscribeToReactive(copy ? SUBSCRIPTION_TYPE_COPY : SUBSCRIPTION_TYPE_ORIGINAL, state, callback);
365
639
  }
366
640
  //#endregion
367
641
  //#region src/value/reactive.ts
@@ -370,7 +644,6 @@ function reactive(value, options) {
370
644
  computeds: /* @__PURE__ */ new Set(),
371
645
  effects: /* @__PURE__ */ new Set(),
372
646
  equal: typeof options === "object" && typeof options?.equal === "function" ? options.equal : Object.is,
373
- subscriptions: /* @__PURE__ */ new Map(),
374
647
  value
375
648
  };
376
649
  return [{
@@ -391,21 +664,16 @@ function computed(callback, options) {
391
664
  return getComputed(callback, options)[0];
392
665
  }
393
666
  function getComputed(callback, options) {
667
+ if (typeof callback !== "function") throw new TypeError("Computed callback must be a function");
394
668
  const [rx, state] = reactive(void 0, options);
395
669
  let fx;
396
670
  const instance = {
397
671
  ...rx,
398
672
  get: () => getValue(state, fx),
399
- peek: () => state.value,
400
- subscribe: (callback) => subscribe(state, callback),
401
- unsubscribe: (callback) => {
402
- state.subscriptions.delete(callback);
403
- }
673
+ peek: (copy) => peekSimpleValue(state.value, copy === true),
674
+ subscribe: (callback, copy) => subscribeToSignal(state, callback, copy === true)
404
675
  };
405
- Object.defineProperty(instance, NAME_MORA, {
406
- enumerable: false,
407
- value: NAME_COMPUTED
408
- });
676
+ Object.defineProperty(instance, NAME_MORA, { value: NAME_COMPUTED });
409
677
  fx = getComputedEffect(state, callback);
410
678
  return [Object.freeze(instance), fx];
411
679
  }
@@ -439,37 +707,56 @@ function setAndEmit$1(state, value) {
439
707
  if (state.equal(state.value, value)) return;
440
708
  state.value = value;
441
709
  for (const computed of state.computeds) computed.dirty = true;
442
- for (const effect of state.effects) BATCH.handlers.add(effect);
443
- for (const [, subscription] of state.subscriptions) subscription.callback(value);
710
+ for (const effect of state.effects) BATCH.handlers.set(effect, effect);
711
+ for (const type of SUBSCRIPTION_TYPES) {
712
+ if (type === "frozen") continue;
713
+ const copy = SUBSCRIPTION_TYPES_COPY.has(type);
714
+ const subscriptions = state.subscriptions?.values.to.keyed?.get(type);
715
+ if (subscriptions != null) for (const [, callback] of subscriptions) callback(peekSimpleValue(state.value, copy));
716
+ }
444
717
  flushHandlers();
445
718
  }
446
719
  //#endregion
447
720
  //#region src/helpers/proxy.ts
448
- function emityProxyValues(state, mapped) {
721
+ function emitProxyValues(state, mapped) {
449
722
  const values = [...mapped.values()];
450
723
  const { length } = values;
451
724
  for (let index = 0; index < length; index += 1) values[index][1].dirty = true;
452
725
  emitValue(state);
453
726
  }
454
727
  function getReactiveValueInProxy(reactive, mapped, key, isArray) {
455
- let item = mapped.get(key);
728
+ const mapKey = String(key);
729
+ let item = mapped.get(mapKey);
456
730
  if (item == null) {
457
731
  item = internalComputed(() => isArray ? reactive.get().at(key) : reactive.get()[key]);
458
- mapped.set(key, item);
732
+ mapped.set(mapKey, item);
459
733
  }
460
734
  return item[0];
461
735
  }
462
- function setProxyValue(array, state, isObject, isProperty, setObject, setProperty, first, second) {
463
- if (array && first === "length") {
736
+ function getValueInProxy(isArray, instance, state, mapped, first) {
737
+ if (isArray ? typeof first === "number" : isKey(first)) return getReactiveValueInProxy(instance, mapped, first, isArray).get();
738
+ return getSimpleValue(state);
739
+ }
740
+ function isProxyObject(isArray, value) {
741
+ return value == null || (isArray ? Array.isArray(value) : isPlainObject(value));
742
+ }
743
+ function peekValueInProxy(isArray, state, first, second) {
744
+ let value;
745
+ if (isArray ? typeof first === "number" : isKey(first)) value = isArray ? state.value.at(first) : state.value[first];
746
+ else value = state.value;
747
+ return peekSimpleValue(value, first === true || second === true);
748
+ }
749
+ function setProxyValue(isArray, state, setObject, setProperty, first, second) {
750
+ if (isArray && first === "length") {
464
751
  state.value.length = second;
465
752
  return;
466
753
  }
467
- if (isObject(first)) {
754
+ if (isProxyObject(isArray, first)) {
468
755
  setObject(state, first);
469
756
  return;
470
757
  }
471
- const property = isProperty(first);
472
- if (array && property && Number.isNaN(first)) return;
758
+ const property = isArray ? typeof first === "number" : isKey(first);
759
+ if (isArray && property && Number.isNaN(first)) return;
473
760
  let actual = property ? second : first;
474
761
  if (typeof actual === "function") try {
475
762
  actual = actual();
@@ -487,7 +774,7 @@ function setProxyValue(array, state, isObject, isProperty, setObject, setPropert
487
774
  setProperty(state, first, value);
488
775
  return;
489
776
  }
490
- if (!property && isObject(value) && state.promise === actual) {
777
+ if (!property && isProxyObject(isArray, value) && state.promise === actual) {
491
778
  state.promise = void 0;
492
779
  setObject(state, value);
493
780
  }
@@ -496,10 +783,9 @@ function setProxyValue(array, state, isObject, isProperty, setObject, setPropert
496
783
  else if (!property && state.promise === actual) state.promise = void 0;
497
784
  });
498
785
  } else if (property) setProperty(state, first, actual);
499
- else if (isObject(actual)) setObject(state, actual);
786
+ else if (isProxyObject(isArray, actual)) setObject(state, actual);
500
787
  }
501
- function setValueInProxy(parameters) {
502
- const { isArray, length, property, state, target, value } = parameters;
788
+ function setValueInProxy(isArray, state, target, property, value, length) {
503
789
  if (isArray) {
504
790
  if (!(!Number.isNaN(Number(property)) || property === "length")) return Reflect.set(target, property, value);
505
791
  }
@@ -511,6 +797,39 @@ function setValueInProxy(parameters) {
511
797
  }
512
798
  return true;
513
799
  }
800
+ function updateProxyValue(isArray, state, setObject, setProperty, callback) {
801
+ if (typeof callback !== "function") throw new TypeError("Callback must be a function");
802
+ setProxyValue(isArray, state, setObject, setProperty, callback(state.value));
803
+ }
804
+ //#endregion
805
+ //#region src/value/readonly.ts
806
+ function getReadonlyInstance(state, instances, frozen) {
807
+ const key = frozen ? "frozen" : "original";
808
+ instances[key] ??= getReadonlySignal(state, frozen);
809
+ return instances[key];
810
+ }
811
+ function getReadonlySignal(state, frozen) {
812
+ const type = frozen ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_READONLY;
813
+ const instance = {
814
+ get: () => getReadonlyValue(state, false, frozen),
815
+ peek: (copy) => getReadonlyValue(state, true, frozen, copy),
816
+ subscribe: (callback) => subscribeToReactive(type, state, callback)
817
+ };
818
+ Object.defineProperties(instance, {
819
+ [NAME_MORA]: { value: NAME_READONLY },
820
+ frozen: {
821
+ enumerable: true,
822
+ value: frozen
823
+ }
824
+ });
825
+ return Object.freeze(instance);
826
+ }
827
+ function getReadonlyValue(state, peek, frozen, copy) {
828
+ let value;
829
+ if (peek) value = peekSimpleValue(state.value, copy === true);
830
+ else value = getSimpleValue(state);
831
+ return frozen ? getFrozenValue(value) : value;
832
+ }
514
833
  //#endregion
515
834
  //#region src/value/signal.ts
516
835
  function setAndEmit(state, value) {
@@ -521,25 +840,17 @@ function setAndEmit(state, value) {
521
840
  }
522
841
  function signal(value, options) {
523
842
  const [rx, state] = reactive(void 0, options);
843
+ const readonlies = {};
524
844
  const instance = {
525
845
  ...rx,
846
+ asReadonly: (frozen) => getReadonlyInstance(state, readonlies, frozen === true),
526
847
  get: () => getSimpleValue(state),
527
- peek: () => state.value,
528
- set: (value) => {
529
- handleSimpleValue(state, value, setAndEmit);
530
- },
531
- update: (callback) => {
532
- handleSimpleValue(state, callback(state.value), setAndEmit);
533
- },
534
- subscribe: (callback) => subscribe(state, callback),
535
- unsubscribe: (callback) => {
536
- state.subscriptions.delete(callback);
537
- }
848
+ peek: (copy) => peekSimpleValue(state.value, copy === true),
849
+ set: (value) => handleSimpleValue(state, value, setAndEmit),
850
+ subscribe: (callback, copy) => subscribeToSignal(state, callback, copy === true),
851
+ update: (callback) => updateSimpleValue(state, callback, setAndEmit)
538
852
  };
539
- Object.defineProperty(instance, NAME_MORA, {
540
- enumerable: false,
541
- value: NAME_SIGNAL
542
- });
853
+ Object.defineProperty(instance, NAME_MORA, { value: NAME_SIGNAL });
543
854
  handleSimpleValue(state, value, setAndEmit);
544
855
  return Object.freeze(instance);
545
856
  }
@@ -547,25 +858,23 @@ function signal(value, options) {
547
858
  //#region src/value/array.ts
548
859
  function array(value, options) {
549
860
  const [rx, state] = reactive([], options);
550
- const indiced = /* @__PURE__ */ new Map();
861
+ const isArray = true;
551
862
  const length = signal(0);
863
+ const mapped = /* @__PURE__ */ new Map();
864
+ const readonlies = {};
552
865
  state.value = new Proxy([], {
553
866
  get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(property, target, state, length) : Reflect.get(target, property),
554
- set: (target, property, value) => setValueInProxy({
555
- length,
556
- property,
557
- state,
558
- target,
559
- value,
560
- isArray: true
561
- })
867
+ set: (target, property, value) => setValueInProxy(isArray, state, target, property, value, length)
562
868
  });
563
869
  function get(value) {
564
- return getArrayValue(instance, indiced, state, length, value);
870
+ return value === "length" ? length.get() : getValueInProxy(isArray, instance, state, mapped, value);
871
+ }
872
+ function set(first, second) {
873
+ setProxyValue(true, state, setArrayValue, setAtIndex, first, second);
565
874
  }
566
875
  const instance = {
567
876
  ...rx,
568
- length: state.value.length,
877
+ asReadonly: (frozen) => getReadonlyInstance(state, readonlies, frozen === true),
569
878
  at: (index) => get(index),
570
879
  clear: () => {
571
880
  state.value.length = 0;
@@ -573,63 +882,38 @@ function array(value, options) {
573
882
  filter: (callback) => computed(() => filter(get(), callback)),
574
883
  get: (value) => get(value),
575
884
  map: (callback) => computed(() => get().map(callback)),
576
- notify: () => {
577
- emityProxyValues(state, indiced);
578
- },
579
- peek: (value) => peekArrayValue(state, length, value),
885
+ notify: () => emitProxyValues(state, mapped),
886
+ peek: (first, second) => peekArrayValue(state, length, first, second),
580
887
  pop: () => state.value.pop(),
581
888
  push: (...items) => state.value.push(...items),
582
889
  select: (filter, map) => computed(() => select(get(), filter, map)),
583
- set: (first, second) => {
584
- setProxyValue(true, state, isArrayValue, isArrayIndex, setArray, setAtIndex, first, second);
585
- },
890
+ set: (first, second) => set(first, second),
586
891
  shift: () => state.value.shift(),
587
892
  splice: (from, to, ...items) => state.value.splice(from, to ?? state.value.length, ...items),
588
- subscribe: (first, second) => {
589
- if (typeof first === "number" && typeof second === "function") return getReactiveValueInProxy(instance, indiced, first, true).subscribe(second);
590
- return typeof first === "function" ? subscribe(state, first) : noop$1;
591
- },
893
+ subscribe: (first, second, third) => subscribeToProxy(isArray, instance, state, mapped, first, second, third),
592
894
  unshift: (...items) => state.value.unshift(...items),
593
- unsubscribe: (first, second) => {
594
- if (typeof first === "number" && typeof second === "function") getReactiveValueInProxy(instance, indiced, first, true)?.unsubscribe(second);
595
- else if (typeof first === "function") unsubscribe(state, first);
596
- },
597
- update: (callback) => updateArrayValue(instance, state, callback)
895
+ update: (callback) => updateProxyValue(true, state, setArrayValue, setAtIndex, callback)
598
896
  };
599
897
  Object.defineProperties(instance, {
600
- [NAME_MORA]: {
601
- enumerable: false,
602
- value: NAME_ARRAY
603
- },
898
+ [NAME_MORA]: { value: NAME_ARRAY },
604
899
  length: {
605
900
  enumerable: true,
606
901
  get: () => length.get(),
607
902
  set: (value) => setArrayLength(state, value)
608
903
  }
609
904
  });
610
- instance.set(value);
905
+ set(value);
611
906
  return Object.freeze(instance);
612
907
  }
613
- function getArrayValue(instance, indiced, state, length, first) {
614
- if (typeof first === "number") return getReactiveValueInProxy(instance, indiced, first, true).get();
615
- return first === "length" ? length.get() : getSimpleValue(state);
616
- }
617
- function isArrayIndex(value) {
618
- return typeof value === "number";
908
+ function peekArrayValue(state, length, first, second) {
909
+ return first === "length" ? length.peek() : peekValueInProxy(true, state, first, second);
619
910
  }
620
- function isArrayValue(value) {
621
- return value == null || Array.isArray(value);
622
- }
623
- function peekArrayValue(state, length, value) {
624
- if (value === "length") return length.peek();
625
- return typeof value === "number" ? state.value.at(value) : state.value.slice();
911
+ function setArrayLength(state, value) {
912
+ if (typeof value === "number" && !Number.isNaN(value) && value >= 0 && value !== state.value.length) state.value.length = value;
626
913
  }
627
- function setArray(state, value) {
914
+ function setArrayValue(state, value) {
628
915
  state.value.splice(0, state.value.length, ...value ?? []);
629
916
  }
630
- function setArrayLength(state, value) {
631
- if (typeof value === "number" && value >= 0 && value !== state.value.length) state.value.length = value;
632
- }
633
917
  function setAtIndex(state, index, value) {
634
918
  const actual = index < 0 ? state.value.length + index : index;
635
919
  if (actual > -1) state.value[actual] = value;
@@ -647,16 +931,12 @@ function updateArray(type, array, state, length) {
647
931
  return result;
648
932
  };
649
933
  }
650
- function updateArrayValue(instance, state, callback) {
651
- const updated = callback(state.value);
652
- if (updated == null || Array.isArray(updated)) instance.set(updated);
653
- }
654
934
  //#endregion
655
935
  //#region src/value/store.ts
656
- function isStoreObject(value) {
657
- return value == null || isPlainObject(value);
936
+ function setPropertyValue(state, key, value) {
937
+ state.value[key] = value;
658
938
  }
659
- function setObject(state, value) {
939
+ function setStoreValue(state, value) {
660
940
  startBatch();
661
941
  const actual = value ?? {};
662
942
  const proxy = state.value;
@@ -674,48 +954,25 @@ function setObject(state, value) {
674
954
  }
675
955
  stopBatch();
676
956
  }
677
- function setProperty(state, key, value) {
678
- state.value[key] = value;
679
- }
680
957
  function store(value, options) {
681
958
  const [rx, state] = reactive(void 0, options);
959
+ const isArray = false;
682
960
  const keyed = /* @__PURE__ */ new Map();
683
- state.value = new Proxy({}, { set: (target, property, value) => setValueInProxy({
684
- target,
685
- property,
686
- state,
687
- value,
688
- isArray: false
689
- }) });
961
+ const readonlies = {};
962
+ state.value = new Proxy({}, { set: (target, property, value) => setValueInProxy(isArray, state, target, property, value) });
690
963
  const instance = {
691
964
  ...rx,
692
- get: (value) => isKey(value) ? getReactiveValueInProxy(instance, keyed, value, false).get() : getSimpleValue(state),
693
- notify() {
694
- emityProxyValues(state, keyed);
695
- },
696
- peek: (value) => isKey(value) ? state.value[value] : { ...state.value },
697
- set: (first, second) => {
698
- setProxyValue(false, state, isStoreObject, isKey, setObject, setProperty, first, second);
699
- },
700
- subscribe: (first, second) => {
701
- if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(instance, keyed, first, false).subscribe(second);
702
- return typeof first === "function" ? subscribe(state, first) : noop;
703
- },
704
- unsubscribe: (first, second) => {
705
- if (isKey(first) && typeof second === "function") getReactiveValueInProxy(instance, keyed, first, false)?.unsubscribe(second);
706
- else if (typeof first === "function") unsubscribe(state, first);
707
- },
708
- update: (callback) => {
709
- const updated = callback(state.value);
710
- if (updated == null || isPlainObject(updated)) setObject(state, updated);
711
- }
965
+ asReadonly: (frozen) => getReadonlyInstance(state, readonlies, frozen === true),
966
+ get: (value) => getValueInProxy(isArray, instance, state, keyed, value),
967
+ notify: () => emitProxyValues(state, keyed),
968
+ peek: (first, second) => peekValueInProxy(isArray, state, first, second),
969
+ set: (first, second) => setProxyValue(isArray, state, setStoreValue, setPropertyValue, first, second),
970
+ subscribe: (first, second, third) => subscribeToProxy(isArray, instance, state, keyed, first, second, third),
971
+ update: (callback) => updateProxyValue(isArray, state, setStoreValue, setPropertyValue, callback)
712
972
  };
713
- Object.defineProperty(instance, NAME_MORA, {
714
- enumerable: false,
715
- value: NAME_STORE
716
- });
973
+ Object.defineProperty(instance, NAME_MORA, { value: NAME_STORE });
717
974
  instance.set(value);
718
975
  return Object.freeze(instance);
719
976
  }
720
977
  //#endregion
721
- export { array, computed, effect, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };
978
+ export { array, computed, effect, isComputed, isEffect, isReactive, isReactiveArray, isReactiveStore, isReadonlySignal, isSignal, signal, startBatch, stopBatch, store };