@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
package/dist/models.d.mts CHANGED
@@ -1,25 +1,26 @@
1
1
  import { PROPERTY_LENGTH } from "./constants.mjs";
2
- import { GenericCallback, Key } from "@oscarpalmer/atoms/models";
2
+ import { Subscription, Subscriptions } from "@oscarpalmer/atoms/subscription";
3
+ import { GenericCallback, Key, PlainObject } from "@oscarpalmer/atoms/models";
3
4
  //#region src/models.d.ts
4
- type Active = {
5
+ export type Active = {
5
6
  computed?: ComputedEffect;
6
7
  effect?: EffectState;
7
8
  };
8
- type Batch = {
9
+ export type Batch = {
9
10
  depth: number;
10
11
  flushing: boolean;
11
- handlers: Set<EffectState | Subscription>;
12
+ handlers: Map<EffectState | Subscription, EffectState | StoredSubscription>;
12
13
  };
13
- type Computed<Value> = Reactive<Value> & SimpleReactive<Value>;
14
- type ComputedEffect = {
14
+ export type Computed<Value> = Reactive<Value> & SimpleReactive<Value>;
15
+ export type ComputedEffect = {
15
16
  dirty: boolean;
16
17
  instance: EffectState;
17
18
  };
18
- type Effect = {};
19
- type EffectState = {
19
+ export type Effect = {};
20
+ export type EffectState = {
20
21
  callback: GenericCallback;
21
22
  };
22
- type Reactive<Value> = {
23
+ export type Reactive<Value> = {
23
24
  /**
24
25
  * JSON representation of the value
25
26
  *
@@ -33,7 +34,7 @@ type Reactive<Value> = {
33
34
  */
34
35
  toString(): string;
35
36
  };
36
- type ReactiveArray<Item> = {
37
+ export type ReactiveArray<Item> = {
37
38
  /**
38
39
  * The length of the array
39
40
  */
@@ -42,6 +43,20 @@ type ReactiveArray<Item> = {
42
43
  * Set the length of the array
43
44
  */
44
45
  set length(value: number);
46
+ /**
47
+ * Get a readonly version of the reactive array
48
+ *
49
+ * @param frozen Freeze the array? _(defaults to `false`)_
50
+ * @returns Readonly reactive array
51
+ */
52
+ asReadonly(frozen: true): ReadonlyFrozenSignal<Item[]>;
53
+ /**
54
+ * Get a readonly version of the reactive array
55
+ *
56
+ * @param frozen Freeze the array? _(defaults to `false`)_
57
+ * @returns Readonly reactive array
58
+ */
59
+ asReadonly(frozen?: boolean): typeof frozen extends true ? ReadonlyFrozenSignal<Item[]> : ReadonlySignal<Item[]>;
45
60
  /**
46
61
  * Get the value at an index
47
62
  *
@@ -96,16 +111,18 @@ type ReactiveArray<Item> = {
96
111
  /**
97
112
  * Get the array _(without reactivity)_
98
113
  *
114
+ * @param copy Copy the array? _(defaults to `false`)_
99
115
  * @returns Array of items
100
116
  */
101
- peek(): Item[];
117
+ peek(copy?: boolean): Item[];
102
118
  /**
103
119
  * Get the value at an index _(without reactivity)_
104
120
  *
105
121
  * @param index Index of item to get _(if negative, starts from the end)_
122
+ * @param copy If the item is an array or record, should it be copied? _(defaults to `false`)_
106
123
  * @returns Item at index, or `undefined` if it doesn't exist
107
124
  */
108
- peek(index: number): Item | undefined;
125
+ peek(index: number, copy?: boolean): Item | undefined;
109
126
  /**
110
127
  * Get the length of the array _(without reactivity)_
111
128
  *
@@ -171,36 +188,25 @@ type ReactiveArray<Item> = {
171
188
  * Subscribe to changes
172
189
  *
173
190
  * @param callback Callback for changes
174
- * @returns Unsubscribe callback
191
+ * @param copy Copy the array? _(defaults to `false`)_
192
+ * @returns Subscription
175
193
  */
176
- subscribe(callback: (value: Item[]) => void): Unsubscribe;
194
+ subscribe(callback: (value: Item[]) => void, copy?: boolean): Subscription;
177
195
  /**
178
196
  * Subscribe to changes at a specific index
179
197
  *
180
198
  * @param index Index of item to subscribe to
181
199
  * @param callback Callback for changes
182
- * @returns Unsubscribe callback
200
+ * @param copy If the item is an array or record, should it be copied? _(defaults to `false`)_
201
+ * @returns Subscription
183
202
  */
184
- subscribe(index: number, callback: (value: Item | undefined) => void): Unsubscribe;
203
+ subscribe(index: number, callback: (value: Item | undefined) => void, copy?: boolean): Subscription;
185
204
  /**
186
205
  * Add items to the beginning of the array
187
206
  * @param items Items to add
188
207
  * @returns New array length
189
208
  */
190
209
  unshift(...items: Item[]): number;
191
- /**
192
- * Unsubscribe from changes for a specific index
193
- *
194
- * @param index Index of the value to unsubscribe from
195
- * @param callback Callback to unsubscribe
196
- */
197
- unsubscribe(index: number, callback: (item: Item | undefined) => void): void;
198
- /**
199
- * Unsubscribe from changes
200
- *
201
- * @param callback Callback to unsubscribe
202
- */
203
- unsubscribe(callback: (array: Item[]) => void): void;
204
210
  /**
205
211
  * Update the value _(based on the current value)_
206
212
  *
@@ -208,7 +214,7 @@ type ReactiveArray<Item> = {
208
214
  */
209
215
  update(callback: (value: Item[]) => Item[]): void;
210
216
  } & Reactive<Item[]>;
211
- type ReactiveOptions<Value> = {
217
+ export type ReactiveOptions<Value> = {
212
218
  /**
213
219
  * Method for comparing values for equality
214
220
  * @param first First value
@@ -218,29 +224,43 @@ type ReactiveOptions<Value> = {
218
224
  */
219
225
  equal?: (first: Value, second: Value) => boolean;
220
226
  };
221
- type ReactiveState<Value, Equal> = {
227
+ export type ReactiveState<Value, Item = Value> = {
222
228
  computeds: Set<ComputedEffect>;
223
229
  effects: Set<EffectState>;
224
- equal: (first: Equal, second: Equal) => boolean;
230
+ equal: (first: Item, second: Item) => boolean;
225
231
  promise?: Promise<Value>;
226
232
  promises?: Map<Key, Promise<never>>;
227
- subscriptions: Map<GenericCallback, Subscription>;
233
+ subscriptions?: Subscriptions<GenericCallback>;
228
234
  value: Value;
229
235
  };
230
- type ReactiveStore<Value> = {
236
+ export type ReactiveStore<Store> = {
237
+ /**
238
+ * Get a readonly version of the reactive store
239
+ *
240
+ * @param frozen Freeze the store? _(defaults to `false`)_
241
+ * @returns Readonly reactive store
242
+ */
243
+ asReadonly(frozen: true): ReadonlyFrozenSignal<Store>;
244
+ /**
245
+ * Get a readonly version of the reactive store
246
+ *
247
+ * @param frozen Freeze the store? _(defaults to `false`)_
248
+ * @returns Readonly reactive store
249
+ */
250
+ asReadonly(frozen?: boolean): typeof frozen extends true ? ReadonlyFrozenSignal<Store> : ReadonlySignal<Store>;
231
251
  /**
232
252
  * Get the value
233
253
  *
234
254
  * @returns Current value
235
255
  */
236
- get(): Value;
256
+ get(): Store;
237
257
  /**
238
258
  * Get a value by key
239
259
  *
240
260
  * @param key Key of the value to get
241
261
  * @returns Value for the specified key, or `undefined` if it doesn't exist
242
262
  */
243
- get<Key extends keyof Value>(key: Key): Value[Key];
263
+ get<Key extends keyof Store>(key: Key): Store[Key];
244
264
  /**
245
265
  * Get a value by key
246
266
  *
@@ -258,36 +278,39 @@ type ReactiveStore<Value> = {
258
278
  /**
259
279
  * Get the value _(without reactivity)_
260
280
  *
281
+ * @param copy Copy the store? _(defaults to `false`)_
261
282
  * @returns Current value
262
283
  */
263
- peek(): Value;
284
+ peek(copy?: boolean): Store;
264
285
  /**
265
286
  * Get a value by key _(without reactivity)_
266
287
  *
267
288
  * @param key Key of the value to get
289
+ * @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
268
290
  * @returns Value for the specified key, or `undefined` if it doesn't exist
269
291
  */
270
- peek<Key extends keyof Value>(key: Key): Value[Key];
292
+ peek<Key extends keyof Store>(key: Key, copy?: boolean): Store[Key];
271
293
  /**
272
294
  * Get a value by key _(without reactivity)_
273
295
  *
274
296
  * @param key Key of the value to get
297
+ * @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
275
298
  * @returns Value for the specified key, or `undefined` if it doesn't exist
276
299
  */
277
- peek(key: Key): unknown;
300
+ peek(key: Key, copy?: boolean): unknown;
278
301
  /**
279
302
  * Set the value
280
303
  *
281
304
  * @param value New value _(defaults to an empty object)_
282
305
  */
283
- set(value?: Value | (() => null | undefined | Value | Promise<null | undefined | Value>) | Promise<null | undefined | Value>): void;
306
+ set(value?: Store | (() => null | undefined | Store | Promise<null | undefined | Store>) | Promise<null | undefined | Store>): void;
284
307
  /**
285
308
  * Set a value by key
286
309
  *
287
310
  * @param key Key of the value to set
288
311
  * @param value New value
289
312
  */
290
- set<Key extends keyof Value>(key: Key, value: Value[Key] | (() => Value[Key] | Promise<Value[Key]>) | Promise<Value[Key]>): void;
313
+ set<Key extends keyof Store>(key: Key, value: Store[Key] | (() => Store[Key] | Promise<Store[Key]>) | Promise<Store[Key]>): void;
291
314
  /**
292
315
  * Set a value by key
293
316
  *
@@ -299,54 +322,62 @@ type ReactiveStore<Value> = {
299
322
  * Subscribe to changes
300
323
  *
301
324
  * @param callback Callback for changes
302
- * @returns Unsubscribe callback
325
+ * @param copy Copy the store? _(defaults to `false`)_
326
+ * @returns Subscription
303
327
  */
304
- subscribe(callback: (value: Value) => void): Unsubscribe;
328
+ subscribe(callback: (value: Store) => void, copy?: boolean): Subscription;
305
329
  /**
306
330
  * Subscribe to changes for a specific key
307
331
  *
308
332
  * @param key Key of the value to subscribe to
309
333
  * @param callback Callback for changes
310
- * @returns Unsubscribe callback
334
+ * @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
335
+ * @returns Subscription
311
336
  */
312
- subscribe<Key extends keyof Value>(key: Key, callback: (value: Value[Key] | undefined) => void): Unsubscribe;
337
+ subscribe<Key extends keyof Store>(key: Key, callback: (value: Store[Key] | undefined) => void, copy?: boolean): Subscription;
313
338
  /**
314
339
  * Subscribe to changes for a specific key
315
340
  *
316
341
  * @param key Key of the value to subscribe to
317
342
  * @param callback Callback for changes
318
- * @returns Unsubscribe callback
343
+ * @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
344
+ * @returns Subscription
319
345
  */
320
- subscribe(key: Key, callback: (value: unknown) => void): Unsubscribe;
346
+ subscribe(key: Key, callback: (value: unknown) => void, copy?: boolean): Subscription;
321
347
  /**
322
- * Unsubscribe from changes for a specific key
348
+ * Update the value _(based on the current value)_
323
349
  *
324
- * @param key Key of the value to unsubscribe from
325
- * @param callback Callback to unsubscribe
350
+ * @param callback Callback to update the value
351
+ */
352
+ update(callback: (value: Store) => Store): void;
353
+ } & Reactive<Store>;
354
+ export type ReadonlyInstances<Value> = {
355
+ frozen?: ReadonlyFrozenSignal<Value>;
356
+ original?: ReadonlySignal<Value>;
357
+ };
358
+ export type ReadonlyFrozenSignal<Value> = ReadonlySignal<ReadonlySignalValue<Value>>;
359
+ export type ReadonlySignal<Value> = {
360
+ /**
361
+ * Is the signal frozen?
326
362
  */
327
- unsubscribe<Key extends keyof Value>(key: Key, callback: (value: Value[Key] | undefined) => void): void;
363
+ get frozen(): boolean;
364
+ } & Reactive<Value> & SimpleReactive<Value>;
365
+ export type ReadonlySignalValue<Value> = Value extends unknown[] ? Readonly<Value> : Value extends PlainObject ? Readonly<Value> : Value;
366
+ export type Signal<Value> = {
328
367
  /**
329
- * Unsubscribe from changes
368
+ * Get a readonly version of the signal
330
369
  *
331
- * @param callback Callback to unsubscribe
370
+ * @param frozen Freeze the signal? _(defaults to `false`)_
371
+ * @returns Readonly signal
332
372
  */
333
- unsubscribe(callback: (value: Value) => void): void;
373
+ asReadonly(frozen: true): ReadonlyFrozenSignal<Value>;
334
374
  /**
335
- * Update the value _(based on the current value)_
375
+ * Get a readonly version of the signal
336
376
  *
337
- * @param callback Callback to update the value
377
+ * @param frozen Freeze the signal? _(defaults to `false`)_
378
+ * @returns Readonly signal
338
379
  */
339
- update(callback: (value: Value) => Value): void;
340
- } & Reactive<Value>;
341
- type SetValueInProxyParameters<Value, Equal> = {
342
- target: Value;
343
- property: PropertyKey;
344
- value: unknown;
345
- state: ReactiveState<Value, Equal>;
346
- isArray: boolean;
347
- length?: Signal<number>;
348
- };
349
- type Signal<Value> = {
380
+ asReadonly(frozen?: boolean): typeof frozen extends true ? ReadonlyFrozenSignal<Value> : ReadonlySignal<Value>;
350
381
  /**
351
382
  * Set the value
352
383
  *
@@ -370,31 +401,24 @@ type SimpleReactive<Value> = {
370
401
  /**
371
402
  * Get the value _(without reactivity)_
372
403
  *
404
+ * @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
373
405
  * @returns Current value
374
406
  */
375
- peek(): Value;
407
+ peek(copy?: boolean): Value;
376
408
  /**
377
409
  * Subscribe to changes
378
410
  *
379
411
  * @param callback Callback for changes
380
- * @returns Unsubscribe callback
381
- */
382
- subscribe(callback: (value: Value) => void): Unsubscribe;
383
- /**
384
- * Unsubscribe from changes
385
- *
386
- * @param callback Callback to unsubscribe
412
+ * @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
413
+ * @returns Subscription
387
414
  */
388
- unsubscribe(callback: (value: Value) => void): void;
415
+ subscribe(callback: (value: Value) => void, copy?: boolean): Subscription;
389
416
  };
390
- type Subscription = {
417
+ export type StoredSubscription = {
391
418
  callback: GenericCallback;
419
+ copy: boolean;
420
+ frozen: boolean;
392
421
  state: ReactiveState<unknown, never>;
393
- destroy(): void;
394
422
  };
395
- /**
396
- * Unsubscribe from changes
397
- */
398
- type Unsubscribe = () => void;
399
- //#endregion
400
- export { Active, Batch, Computed, ComputedEffect, Effect, EffectState, Reactive, ReactiveArray, ReactiveOptions, ReactiveState, ReactiveStore, SetValueInProxyParameters, Signal, Subscription, Unsubscribe };
423
+ export type SubscriptionType = 'copy' | 'frozen' | 'original' | 'readonly';
424
+ //#endregion