@oscarpalmer/mora 0.31.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 (54) hide show
  1. package/dist/batch.d.mts +4 -5
  2. package/dist/batch.mjs +4 -2
  3. package/dist/constants.d.mts +29 -19
  4. package/dist/constants.mjs +17 -2
  5. package/dist/effect.d.mts +4 -5
  6. package/dist/effect.mjs +2 -2
  7. package/dist/helpers/is.d.mts +14 -9
  8. package/dist/helpers/is.mjs +6 -0
  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 +3 -2
  16. package/dist/models.d.mts +45 -87
  17. package/dist/mora.full.mjs +461 -285
  18. package/dist/value/array.d.mts +4 -5
  19. package/dist/value/array.mjs +22 -69
  20. package/dist/value/computed.d.mts +3 -4
  21. package/dist/value/computed.mjs +14 -14
  22. package/dist/value/reactive.d.mts +2 -3
  23. package/dist/value/reactive.mjs +0 -1
  24. package/dist/value/readonly.d.mts +3 -5
  25. package/dist/value/readonly.mjs +15 -19
  26. package/dist/value/signal.d.mts +4 -5
  27. package/dist/value/signal.mjs +9 -22
  28. package/dist/value/store.d.mts +4 -5
  29. package/dist/value/store.mjs +16 -56
  30. package/package.json +6 -6
  31. package/src/batch.ts +15 -5
  32. package/src/constants.ts +32 -2
  33. package/src/effect.ts +6 -2
  34. package/src/helpers/is.ts +10 -0
  35. package/src/helpers/proxy.ts +99 -49
  36. package/src/helpers/subscription.ts +78 -0
  37. package/src/helpers/value.ts +69 -4
  38. package/src/index.ts +1 -1
  39. package/src/models.ts +38 -81
  40. package/src/value/array.ts +61 -150
  41. package/src/value/computed.ts +36 -13
  42. package/src/value/reactive.ts +8 -5
  43. package/src/value/readonly.ts +26 -25
  44. package/src/value/signal.ts +19 -22
  45. package/src/value/store.ts +35 -114
  46. package/types/constants.d.ts +1 -1
  47. package/types/index.d.ts +1 -1
  48. package/types/value/array.d.ts +1 -1
  49. package/types/value/computed.d.ts +0 -3
  50. package/types/value/signal.d.ts +1 -1
  51. package/types/value/store.d.ts +1 -1
  52. package/dist/subscription.d.mts +0 -7
  53. package/dist/subscription.mjs +0 -27
  54. 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",
@@ -26,6 +26,7 @@ const NAME_MORA = "$mora";
26
26
  const NAME_READONLY = "readonly";
27
27
  const NAME_SIGNAL = "signal";
28
28
  const NAME_STORE = "store";
29
+ const NAME_SUBSCRIPTION = "subscription";
29
30
  const NAME_ALL = /* @__PURE__ */ new Set([
30
31
  NAME_ARRAY,
31
32
  NAME_COMPUTED,
@@ -33,6 +34,20 @@ const NAME_ALL = /* @__PURE__ */ new Set([
33
34
  NAME_SIGNAL,
34
35
  NAME_STORE
35
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
+ ]);
36
51
  //#endregion
37
52
  //#region src/effect.ts
38
53
  /**
@@ -47,7 +62,7 @@ function effect(callback) {
47
62
  }
48
63
  function getEffect(callback) {
49
64
  const state = { callback };
50
- const instance = Object.freeze({ $mora: NAME_EFFECT });
65
+ const instance = Object.freeze({ [NAME_MORA]: NAME_EFFECT });
51
66
  runEffect(state);
52
67
  return [instance, state];
53
68
  }
@@ -64,6 +79,98 @@ function runEffect(state) {
64
79
  }
65
80
  }
66
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
67
174
  //#region src/batch.ts
68
175
  function flushHandlers() {
69
176
  if (BATCH.flushing) return;
@@ -74,8 +181,9 @@ function flushHandlers() {
74
181
  const { length } = handlers;
75
182
  BATCH.handlers.clear();
76
183
  for (let index = 0; index < length; index += 1) {
77
- const handler = handlers[index];
78
- 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));
79
187
  else runEffect(handler);
80
188
  }
81
189
  }
@@ -157,6 +265,12 @@ function isReactiveArray(value) {
157
265
  function isReactiveStore(value) {
158
266
  return isMora(value, NAME_STORE);
159
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
+ */
160
274
  function isReadonlySignal(value) {
161
275
  return isMora(value, NAME_READONLY);
162
276
  }
@@ -167,6 +281,7 @@ function getArrayCallback(value) {
167
281
  case "function": return value;
168
282
  case "number":
169
283
  case "string": return typeof value === "string" && value.includes(".") ? void 0 : (obj) => obj[value];
284
+ default: return;
170
285
  }
171
286
  }
172
287
  function getArrayCallbacks(bool, key, value) {
@@ -178,10 +293,18 @@ function getArrayCallbacks(bool, key, value) {
178
293
  }
179
294
  //#endregion
180
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
+ }
181
304
  function findValue(type, array, parameters, reversed) {
182
305
  const findIndex = type === FIND_VALUE_INDEX;
183
306
  if (!Array.isArray(array) || array.length === 0) return findIndex ? -1 : void 0;
184
- const { bool, key, value } = getFindParameters(parameters);
307
+ const { bool, key, value } = createFindParameters(parameters);
185
308
  const callbacks = getArrayCallbacks(bool, key);
186
309
  if (callbacks?.bool == null && callbacks?.keyed == null) {
187
310
  if (findIndex) return reversed ? array.lastIndexOf(value) : array.indexOf(value);
@@ -208,18 +331,22 @@ function findValues(type, array, parameters, mapper) {
208
331
  };
209
332
  if (!Array.isArray(array) || array.length === 0) return result;
210
333
  const { length } = array;
211
- const { bool, key, value } = getFindParameters(parameters);
334
+ const { bool, key, value } = createFindParameters(parameters);
212
335
  const callbacks = getArrayCallbacks(bool, key);
213
- if (type === "unique" && callbacks?.keyed == null && length >= UNIQUE_THRESHOLD) {
336
+ if (type === "unique" && callbacks?.keyed == null && length >= FIND_UNIQUE_THRESHOLD) {
214
337
  result.matched = [...new Set(array)];
215
338
  return result;
216
339
  }
217
- 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;
218
344
  if (callbacks?.bool != null || type === "all" && key == null) {
219
345
  const callback = callbacks?.bool ?? ((item) => Object.is(item, value));
220
346
  for (let index = 0; index < length; index += 1) {
221
347
  const item = array[index];
222
- 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);
223
350
  else result.notMatched.push(item);
224
351
  }
225
352
  return result;
@@ -227,71 +354,64 @@ function findValues(type, array, parameters, mapper) {
227
354
  const keys = /* @__PURE__ */ new Set();
228
355
  for (let index = 0; index < length; index += 1) {
229
356
  const item = array[index];
230
- 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
+ }
231
366
  if (type === "all" && Object.is(keyed, value) || type === "unique" && !keys.has(keyed)) {
232
367
  keys.add(keyed);
233
- result.matched.push(mapCallback?.(item, index, array) ?? item);
368
+ result.matched.push(mapAfter?.(item, index, array) ?? transformed);
234
369
  } else result.notMatched.push(item);
235
370
  }
236
371
  return result;
237
372
  }
238
- function getFindParameters(original) {
239
- const { length } = original;
240
- return {
241
- bool: length === 1 && typeof original[0] === "function" ? original[0] : void 0,
242
- key: length === 2 ? original[0] : void 0,
243
- value: length === 1 && typeof original[0] !== "function" ? original[0] : original[1]
244
- };
245
- }
246
373
  const FIND_VALUE_INDEX = "index";
247
374
  const FIND_VALUE_ITEM = "item";
248
- const UNIQUE_THRESHOLD = 100;
375
+ const FIND_UNIQUE_THRESHOLD = 100;
249
376
  //#endregion
250
377
  //#region node_modules/@oscarpalmer/atoms/dist/internal/array/index-of.mjs
251
378
  function indexOf(array, ...parameters) {
252
379
  return findValue(FIND_VALUE_INDEX, array, parameters, false);
253
380
  }
254
- indexOf.last = lastIndexOf;
255
381
  function lastIndexOf(array, ...parameters) {
256
382
  return findValue(FIND_VALUE_INDEX, array, parameters, true);
257
383
  }
258
- //#endregion
259
- //#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
260
- /**
261
- * Is the value a _Key_?
262
- *
263
- * @param value Value to check
264
- * @returns `true` if the value is a _Key_ _(`number` or `string`)_, otherwise `false`
265
- */
266
- function isKey(value) {
267
- return typeof value === "number" || typeof value === "string";
268
- }
269
- /**
270
- * Is the value a plain object?
271
- *
272
- * @param value Value to check
273
- * @returns `true` if the value is a plain object, otherwise `false`
274
- */
275
- function isPlainObject(value) {
276
- if (value === null || typeof value !== "object") return false;
277
- if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
278
- const prototype = Object.getPrototypeOf(value);
279
- return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
280
- }
384
+ indexOf.last = lastIndexOf;
385
+ Object.defineProperty(indexOf, "last", { value: lastIndexOf });
281
386
  //#endregion
282
387
  //#region node_modules/@oscarpalmer/atoms/dist/array/find.mjs
283
388
  function find(array, ...parameters) {
284
389
  return findValue(FIND_VALUE_ITEM, array, parameters, false);
285
390
  }
286
- find.last = findLast;
287
391
  function findLast(array, ...parameters) {
288
392
  return findValue(FIND_VALUE_ITEM, array, parameters, true);
289
393
  }
394
+ find.last = findLast;
395
+ Object.defineProperty(find, "last", { value: findLast });
290
396
  //#endregion
291
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
+ }
292
404
  function select(array, ...parameters) {
293
- return findValues("all", array, parameters, parameters.pop()).matched;
405
+ return selectValues(array, parameters);
294
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 });
295
415
  //#endregion
296
416
  //#region node_modules/@oscarpalmer/atoms/dist/array/filter.mjs
297
417
  function exclude(array, ...parameters) {
@@ -301,81 +421,221 @@ function filter(array, ...parameters) {
301
421
  return findValues("all", array, parameters).matched;
302
422
  }
303
423
  filter.remove = exclude;
424
+ Object.defineProperty(filter, "remove", { value: exclude });
304
425
  //#endregion
305
- //#region node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
306
- /**
307
- * A function that does nothing, which can be useful, I guess…
308
- */
309
- function noop$1() {}
310
- //#endregion
311
- //#region src/helpers/value.ts
312
- function emitValue(state) {
313
- for (const computed of state.computeds) computed.dirty = true;
314
- for (const effect of state.effects) BATCH.handlers.add(effect);
315
- for (const [, subscription] of state.subscriptions) BATCH.handlers.add(subscription);
316
- 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
+ };
317
435
  }
318
- function equalArrays(state, first, second) {
319
- let { length } = first;
320
- if (length !== second.length) return false;
321
- let offset = 0;
322
- if (length >= 100) {
323
- offset = Math.round(length / 10);
324
- offset = offset > 25 ? 25 : offset;
325
- 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;
326
448
  }
327
- length -= offset;
328
- for (let index = offset; index < length; index += 1) if (!state.equal(first[index], second[index])) return false;
329
- 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);
330
471
  }
331
- function getSimpleValue(state) {
332
- if (ACTIVE.computed != null) state.computeds.add(ACTIVE.computed);
333
- if (ACTIVE.effect != null) state.effects.add(ACTIVE.effect);
334
- 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();
335
475
  }
336
- function handleSimpleValue(state, origin, setValue, onAfter) {
337
- try {
338
- let actual = typeof origin === "function" ? origin() : origin;
339
- if (actual instanceof Promise) {
340
- state.promise = actual;
341
- actual.then((value) => {
342
- if (actual === state.promise) {
343
- state.promise = void 0;
344
- setValue(state, value);
345
- }
346
- }).catch(() => {
347
- if (actual === state.promise) state.promise = void 0;
348
- });
349
- } else setValue(state, actual);
350
- } catch {} finally {
351
- 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);
352
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];
353
501
  }
354
- //#endregion
355
- //#region src/subscription.ts
356
- function noop() {}
357
- function subscribe(state, callback) {
358
- if (typeof callback !== "function" || state.subscriptions.has(callback)) return noop;
359
- state.subscriptions.set(callback, subscription(state, callback));
360
- return () => {
361
- 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
362
515
  };
363
516
  }
364
- function subscription(state, callback) {
365
- const instance = {
366
- callback,
367
- state,
368
- destroy: () => {
369
- instance.callback = noop;
370
- 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
+ }
371
550
  }
372
551
  };
373
- callback(state.value);
374
- return instance;
375
552
  }
376
- function unsubscribe(state, callback) {
377
- state.subscriptions.get(callback)?.destroy();
378
- 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);
379
639
  }
380
640
  //#endregion
381
641
  //#region src/value/reactive.ts
@@ -384,7 +644,6 @@ function reactive(value, options) {
384
644
  computeds: /* @__PURE__ */ new Set(),
385
645
  effects: /* @__PURE__ */ new Set(),
386
646
  equal: typeof options === "object" && typeof options?.equal === "function" ? options.equal : Object.is,
387
- subscriptions: /* @__PURE__ */ new Map(),
388
647
  value
389
648
  };
390
649
  return [{
@@ -405,21 +664,16 @@ function computed(callback, options) {
405
664
  return getComputed(callback, options)[0];
406
665
  }
407
666
  function getComputed(callback, options) {
667
+ if (typeof callback !== "function") throw new TypeError("Computed callback must be a function");
408
668
  const [rx, state] = reactive(void 0, options);
409
669
  let fx;
410
670
  const instance = {
411
671
  ...rx,
412
672
  get: () => getValue(state, fx),
413
- peek: () => state.value,
414
- subscribe: (callback) => subscribe(state, callback),
415
- unsubscribe: (callback) => {
416
- state.subscriptions.delete(callback);
417
- }
673
+ peek: (copy) => peekSimpleValue(state.value, copy === true),
674
+ subscribe: (callback, copy) => subscribeToSignal(state, callback, copy === true)
418
675
  };
419
- Object.defineProperty(instance, NAME_MORA, {
420
- enumerable: false,
421
- value: NAME_COMPUTED
422
- });
676
+ Object.defineProperty(instance, NAME_MORA, { value: NAME_COMPUTED });
423
677
  fx = getComputedEffect(state, callback);
424
678
  return [Object.freeze(instance), fx];
425
679
  }
@@ -453,37 +707,56 @@ function setAndEmit$1(state, value) {
453
707
  if (state.equal(state.value, value)) return;
454
708
  state.value = value;
455
709
  for (const computed of state.computeds) computed.dirty = true;
456
- for (const effect of state.effects) BATCH.handlers.add(effect);
457
- 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
+ }
458
717
  flushHandlers();
459
718
  }
460
719
  //#endregion
461
720
  //#region src/helpers/proxy.ts
462
- function emityProxyValues(state, mapped) {
721
+ function emitProxyValues(state, mapped) {
463
722
  const values = [...mapped.values()];
464
723
  const { length } = values;
465
724
  for (let index = 0; index < length; index += 1) values[index][1].dirty = true;
466
725
  emitValue(state);
467
726
  }
468
727
  function getReactiveValueInProxy(reactive, mapped, key, isArray) {
469
- let item = mapped.get(key);
728
+ const mapKey = String(key);
729
+ let item = mapped.get(mapKey);
470
730
  if (item == null) {
471
731
  item = internalComputed(() => isArray ? reactive.get().at(key) : reactive.get()[key]);
472
- mapped.set(key, item);
732
+ mapped.set(mapKey, item);
473
733
  }
474
734
  return item[0];
475
735
  }
476
- function setProxyValue(array, state, isObject, isProperty, setObject, setProperty, first, second) {
477
- 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") {
478
751
  state.value.length = second;
479
752
  return;
480
753
  }
481
- if (isObject(first)) {
754
+ if (isProxyObject(isArray, first)) {
482
755
  setObject(state, first);
483
756
  return;
484
757
  }
485
- const property = isProperty(first);
486
- if (array && property && Number.isNaN(first)) return;
758
+ const property = isArray ? typeof first === "number" : isKey(first);
759
+ if (isArray && property && Number.isNaN(first)) return;
487
760
  let actual = property ? second : first;
488
761
  if (typeof actual === "function") try {
489
762
  actual = actual();
@@ -501,7 +774,7 @@ function setProxyValue(array, state, isObject, isProperty, setObject, setPropert
501
774
  setProperty(state, first, value);
502
775
  return;
503
776
  }
504
- if (!property && isObject(value) && state.promise === actual) {
777
+ if (!property && isProxyObject(isArray, value) && state.promise === actual) {
505
778
  state.promise = void 0;
506
779
  setObject(state, value);
507
780
  }
@@ -510,10 +783,9 @@ function setProxyValue(array, state, isObject, isProperty, setObject, setPropert
510
783
  else if (!property && state.promise === actual) state.promise = void 0;
511
784
  });
512
785
  } else if (property) setProperty(state, first, actual);
513
- else if (isObject(actual)) setObject(state, actual);
786
+ else if (isProxyObject(isArray, actual)) setObject(state, actual);
514
787
  }
515
- function setValueInProxy(parameters) {
516
- const { isArray, length, property, state, target, value } = parameters;
788
+ function setValueInProxy(isArray, state, target, property, value, length) {
517
789
  if (isArray) {
518
790
  if (!(!Number.isNaN(Number(property)) || property === "length")) return Reflect.set(target, property, value);
519
791
  }
@@ -525,24 +797,26 @@ function setValueInProxy(parameters) {
525
797
  }
526
798
  return true;
527
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
+ }
528
804
  //#endregion
529
805
  //#region src/value/readonly.ts
530
- function getReadonlyInstance(state, instances, handlers, frozen) {
806
+ function getReadonlyInstance(state, instances, frozen) {
531
807
  const key = frozen ? "frozen" : "original";
532
- instances[key] ??= getReadonlySignal(state, handlers, frozen);
808
+ instances[key] ??= getReadonlySignal(state, frozen);
533
809
  return instances[key];
534
810
  }
535
- function getReadonlySignal(state, handlers, frozen) {
811
+ function getReadonlySignal(state, frozen) {
812
+ const type = frozen ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_READONLY;
536
813
  const instance = {
537
- ...handlers,
538
814
  get: () => getReadonlyValue(state, false, frozen),
539
- peek: () => getReadonlyValue(state, true, frozen)
815
+ peek: (copy) => getReadonlyValue(state, true, frozen, copy),
816
+ subscribe: (callback) => subscribeToReactive(type, state, callback)
540
817
  };
541
818
  Object.defineProperties(instance, {
542
- [NAME_MORA]: {
543
- enumerable: false,
544
- value: NAME_READONLY
545
- },
819
+ [NAME_MORA]: { value: NAME_READONLY },
546
820
  frozen: {
547
821
  enumerable: true,
548
822
  value: frozen
@@ -550,13 +824,11 @@ function getReadonlySignal(state, handlers, frozen) {
550
824
  });
551
825
  return Object.freeze(instance);
552
826
  }
553
- function getReadonlyValue(state, peek, frozen) {
554
- let value = peek ? state.value : getSimpleValue(state);
555
- if (!frozen) return value;
556
- if (Array.isArray(state.value)) value = [...state.value];
557
- else if (isPlainObject(state.value)) value = { ...state.value };
558
- else value = state.value;
559
- return Object.freeze(value);
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;
560
832
  }
561
833
  //#endregion
562
834
  //#region src/value/signal.ts
@@ -569,29 +841,16 @@ function setAndEmit(state, value) {
569
841
  function signal(value, options) {
570
842
  const [rx, state] = reactive(void 0, options);
571
843
  const readonlies = {};
572
- const handlers = {
573
- ...rx,
574
- subscribe: (callback) => subscribe(state, callback),
575
- unsubscribe: (callback) => {
576
- state.subscriptions.delete(callback);
577
- }
578
- };
579
844
  const instance = {
580
- ...handlers,
581
- asReadonly: (frozen) => getReadonlyInstance(state, readonlies, handlers, frozen === true),
845
+ ...rx,
846
+ asReadonly: (frozen) => getReadonlyInstance(state, readonlies, frozen === true),
582
847
  get: () => getSimpleValue(state),
583
- peek: () => state.value,
584
- set: (value) => {
585
- handleSimpleValue(state, value, setAndEmit);
586
- },
587
- update: (callback) => {
588
- handleSimpleValue(state, callback(state.value), setAndEmit);
589
- }
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)
590
852
  };
591
- Object.defineProperty(instance, NAME_MORA, {
592
- enumerable: false,
593
- value: NAME_SIGNAL
594
- });
853
+ Object.defineProperty(instance, NAME_MORA, { value: NAME_SIGNAL });
595
854
  handleSimpleValue(state, value, setAndEmit);
596
855
  return Object.freeze(instance);
597
856
  }
@@ -599,68 +858,44 @@ function signal(value, options) {
599
858
  //#region src/value/array.ts
600
859
  function array(value, options) {
601
860
  const [rx, state] = reactive([], options);
602
- const indiced = /* @__PURE__ */ new Map();
861
+ const isArray = true;
603
862
  const length = signal(0);
863
+ const mapped = /* @__PURE__ */ new Map();
604
864
  const readonlies = {};
605
- let instance = {};
606
865
  state.value = new Proxy([], {
607
866
  get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(property, target, state, length) : Reflect.get(target, property),
608
- set: (target, property, value) => setValueInProxy({
609
- length,
610
- property,
611
- state,
612
- target,
613
- value,
614
- isArray: true
615
- })
867
+ set: (target, property, value) => setValueInProxy(isArray, state, target, property, value, length)
616
868
  });
617
869
  function get(value) {
618
- return getArrayValue(instance, indiced, state, length, value);
870
+ return value === "length" ? length.get() : getValueInProxy(isArray, instance, state, mapped, value);
619
871
  }
620
872
  function set(first, second) {
621
- setProxyValue(true, state, isArrayValue, isArrayIndex, setArray, setAtIndex, first, second);
873
+ setProxyValue(true, state, setArrayValue, setAtIndex, first, second);
622
874
  }
623
- const handlers = {
875
+ const instance = {
624
876
  ...rx,
625
- get: (value) => get(value),
626
- peek: (first, second) => peekArrayValue(state, length, first, second),
627
- subscribe: (first, second) => {
628
- if (typeof first === "number" && typeof second === "function") return getReactiveValueInProxy(instance, indiced, first, true).subscribe(second);
629
- return typeof first === "function" ? subscribe(state, first) : noop$1;
630
- },
631
- unsubscribe: (first, second) => {
632
- if (typeof first === "number" && typeof second === "function") getReactiveValueInProxy(instance, indiced, first, true)?.unsubscribe(second);
633
- else if (typeof first === "function") unsubscribe(state, first);
634
- }
635
- };
636
- instance = {
637
- ...handlers,
638
- asReadonly: (frozen) => getReadonlyInstance(state, readonlies, handlers, frozen === true),
877
+ asReadonly: (frozen) => getReadonlyInstance(state, readonlies, frozen === true),
639
878
  at: (index) => get(index),
640
879
  clear: () => {
641
880
  state.value.length = 0;
642
881
  },
643
882
  filter: (callback) => computed(() => filter(get(), callback)),
883
+ get: (value) => get(value),
644
884
  map: (callback) => computed(() => get().map(callback)),
645
- notify: () => {
646
- emityProxyValues(state, indiced);
647
- },
885
+ notify: () => emitProxyValues(state, mapped),
886
+ peek: (first, second) => peekArrayValue(state, length, first, second),
648
887
  pop: () => state.value.pop(),
649
888
  push: (...items) => state.value.push(...items),
650
889
  select: (filter, map) => computed(() => select(get(), filter, map)),
651
- set: (first, second) => {
652
- set(first, second);
653
- },
890
+ set: (first, second) => set(first, second),
654
891
  shift: () => state.value.shift(),
655
892
  splice: (from, to, ...items) => state.value.splice(from, to ?? state.value.length, ...items),
893
+ subscribe: (first, second, third) => subscribeToProxy(isArray, instance, state, mapped, first, second, third),
656
894
  unshift: (...items) => state.value.unshift(...items),
657
- update: (callback) => updateArrayValue(instance, state, callback)
895
+ update: (callback) => updateProxyValue(true, state, setArrayValue, setAtIndex, callback)
658
896
  };
659
897
  Object.defineProperties(instance, {
660
- [NAME_MORA]: {
661
- enumerable: false,
662
- value: NAME_ARRAY
663
- },
898
+ [NAME_MORA]: { value: NAME_ARRAY },
664
899
  length: {
665
900
  enumerable: true,
666
901
  get: () => length.get(),
@@ -670,31 +905,14 @@ function array(value, options) {
670
905
  set(value);
671
906
  return Object.freeze(instance);
672
907
  }
673
- function getArrayValue(instance, indiced, state, length, first) {
674
- if (typeof first === "number") return getReactiveValueInProxy(instance, indiced, first, true).get();
675
- return first === "length" ? length.get() : getSimpleValue(state);
676
- }
677
- function isArrayIndex(value) {
678
- return typeof value === "number";
679
- }
680
- function isArrayValue(value) {
681
- return value == null || Array.isArray(value);
682
- }
683
908
  function peekArrayValue(state, length, first, second) {
684
- if (first === "length") return length.peek();
685
- let value;
686
- if (typeof first === "number") value = state.value.at(first);
687
- else value = state.value;
688
- if (!(first === true || second === true)) return value;
689
- if (Array.isArray(value)) return value.slice();
690
- if (isPlainObject(value)) return { ...value };
691
- return value;
692
- }
693
- function setArray(state, value) {
694
- state.value.splice(0, state.value.length, ...value ?? []);
909
+ return first === "length" ? length.peek() : peekValueInProxy(true, state, first, second);
695
910
  }
696
911
  function setArrayLength(state, value) {
697
- if (typeof value === "number" && value >= 0 && value !== state.value.length) state.value.length = value;
912
+ if (typeof value === "number" && !Number.isNaN(value) && value >= 0 && value !== state.value.length) state.value.length = value;
913
+ }
914
+ function setArrayValue(state, value) {
915
+ state.value.splice(0, state.value.length, ...value ?? []);
698
916
  }
699
917
  function setAtIndex(state, index, value) {
700
918
  const actual = index < 0 ? state.value.length + index : index;
@@ -713,16 +931,12 @@ function updateArray(type, array, state, length) {
713
931
  return result;
714
932
  };
715
933
  }
716
- function updateArrayValue(instance, state, callback) {
717
- const updated = callback(state.value);
718
- if (updated == null || Array.isArray(updated)) instance.set(updated);
719
- }
720
934
  //#endregion
721
935
  //#region src/value/store.ts
722
- function isStoreObject(value) {
723
- return value == null || isPlainObject(value);
936
+ function setPropertyValue(state, key, value) {
937
+ state.value[key] = value;
724
938
  }
725
- function setObject(state, value) {
939
+ function setStoreValue(state, value) {
726
940
  startBatch();
727
941
  const actual = value ?? {};
728
942
  const proxy = state.value;
@@ -740,61 +954,23 @@ function setObject(state, value) {
740
954
  }
741
955
  stopBatch();
742
956
  }
743
- function peekStoreValue(state, first, second) {
744
- let value;
745
- if (isKey(first)) value = state.value[first];
746
- else value = state.value;
747
- if (!(first === true || second === true)) return value;
748
- if (Array.isArray(value)) return value.slice();
749
- if (isPlainObject(value)) return { ...value };
750
- return value;
751
- }
752
- function setProperty(state, key, value) {
753
- state.value[key] = value;
754
- }
755
957
  function store(value, options) {
756
958
  const [rx, state] = reactive(void 0, options);
959
+ const isArray = false;
757
960
  const keyed = /* @__PURE__ */ new Map();
758
961
  const readonlies = {};
759
- let instance = {};
760
- state.value = new Proxy({}, { set: (target, property, value) => setValueInProxy({
761
- target,
762
- property,
763
- state,
764
- value,
765
- isArray: false
766
- }) });
767
- const handlers = {
962
+ state.value = new Proxy({}, { set: (target, property, value) => setValueInProxy(isArray, state, target, property, value) });
963
+ const instance = {
768
964
  ...rx,
769
- get: (value) => isKey(value) ? getReactiveValueInProxy(instance, keyed, value, false).get() : getSimpleValue(state),
770
- peek: (first, second) => peekStoreValue(state, first, second),
771
- subscribe: (first, second) => {
772
- if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(instance, keyed, first, false).subscribe(second);
773
- return typeof first === "function" ? subscribe(state, first) : noop;
774
- },
775
- unsubscribe: (first, second) => {
776
- if (isKey(first) && typeof second === "function") getReactiveValueInProxy(instance, keyed, first, false)?.unsubscribe(second);
777
- else if (typeof first === "function") unsubscribe(state, first);
778
- }
779
- };
780
- instance = {
781
- ...handlers,
782
- asReadonly: (frozen) => getReadonlyInstance(state, readonlies, handlers, frozen === true),
783
- notify() {
784
- emityProxyValues(state, keyed);
785
- },
786
- set: (first, second) => {
787
- setProxyValue(false, state, isStoreObject, isKey, setObject, setProperty, first, second);
788
- },
789
- update: (callback) => {
790
- const updated = callback(state.value);
791
- if (updated == null || isPlainObject(updated)) setObject(state, updated);
792
- }
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)
793
972
  };
794
- Object.defineProperty(instance, NAME_MORA, {
795
- enumerable: false,
796
- value: NAME_STORE
797
- });
973
+ Object.defineProperty(instance, NAME_MORA, { value: NAME_STORE });
798
974
  instance.set(value);
799
975
  return Object.freeze(instance);
800
976
  }