@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.
- package/dist/batch.d.mts +4 -5
- package/dist/batch.mjs +4 -2
- package/dist/constants.d.mts +29 -18
- package/dist/constants.mjs +19 -2
- package/dist/effect.d.mts +4 -5
- package/dist/effect.mjs +2 -2
- package/dist/helpers/is.d.mts +21 -15
- package/dist/helpers/is.mjs +21 -12
- package/dist/helpers/proxy.d.mts +12 -10
- package/dist/helpers/proxy.mjs +32 -14
- package/dist/helpers/subscription.d.mts +8 -0
- package/dist/helpers/subscription.mjs +27 -0
- package/dist/helpers/value.d.mts +8 -6
- package/dist/helpers/value.mjs +30 -4
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +2 -2
- package/dist/models.d.mts +108 -84
- package/dist/mora.full.mjs +504 -247
- package/dist/value/array.d.mts +4 -5
- package/dist/value/array.mjs +25 -56
- package/dist/value/computed.d.mts +3 -4
- package/dist/value/computed.mjs +14 -14
- package/dist/value/reactive.d.mts +2 -3
- package/dist/value/reactive.mjs +0 -1
- package/dist/value/readonly.d.mts +5 -0
- package/dist/value/readonly.mjs +33 -0
- package/dist/value/signal.d.mts +4 -5
- package/dist/value/signal.mjs +10 -17
- package/dist/value/store.d.mts +4 -5
- package/dist/value/store.mjs +17 -41
- package/package.json +6 -6
- package/src/batch.ts +15 -5
- package/src/constants.ts +41 -3
- package/src/effect.ts +6 -2
- package/src/helpers/is.ts +37 -12
- package/src/helpers/proxy.ts +99 -49
- package/src/helpers/subscription.ts +78 -0
- package/src/helpers/value.ts +69 -4
- package/src/index.ts +18 -2
- package/src/models.ts +131 -86
- package/src/value/array.ts +67 -120
- package/src/value/computed.ts +36 -13
- package/src/value/reactive.ts +8 -5
- package/src/value/readonly.ts +72 -0
- package/src/value/signal.ts +22 -16
- package/src/value/store.ts +37 -70
- package/types/constants.d.ts +1 -1
- package/types/index.d.ts +1 -1
- package/types/value/array.d.ts +1 -1
- package/types/value/computed.d.ts +0 -3
- package/types/value/signal.d.ts +1 -1
- package/types/value/store.d.ts +1 -1
- package/dist/subscription.d.mts +0 -7
- package/dist/subscription.mjs +0 -27
- package/src/subscription.ts +0 -45
package/src/models.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type {GenericCallback, Key} from '@oscarpalmer/atoms/models';
|
|
1
|
+
import type {GenericCallback, Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
+
import type {Subscription, Subscriptions} from '@oscarpalmer/atoms/subscription';
|
|
2
3
|
import type {PROPERTY_LENGTH} from './constants';
|
|
3
4
|
|
|
5
|
+
// #region Types
|
|
6
|
+
|
|
4
7
|
export type Active = {
|
|
5
8
|
computed?: ComputedEffect;
|
|
6
9
|
effect?: EffectState;
|
|
@@ -9,7 +12,7 @@ export type Active = {
|
|
|
9
12
|
export type Batch = {
|
|
10
13
|
depth: number;
|
|
11
14
|
flushing: boolean;
|
|
12
|
-
handlers:
|
|
15
|
+
handlers: Map<EffectState | Subscription, EffectState | StoredSubscription>;
|
|
13
16
|
};
|
|
14
17
|
|
|
15
18
|
export type Computed<Value> = Reactive<Value> & SimpleReactive<Value>;
|
|
@@ -52,6 +55,24 @@ export type ReactiveArray<Item> = {
|
|
|
52
55
|
*/
|
|
53
56
|
set length(value: number);
|
|
54
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Get a readonly version of the reactive array
|
|
60
|
+
*
|
|
61
|
+
* @param frozen Freeze the array? _(defaults to `false`)_
|
|
62
|
+
* @returns Readonly reactive array
|
|
63
|
+
*/
|
|
64
|
+
asReadonly(frozen: true): ReadonlyFrozenSignal<Item[]>;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get a readonly version of the reactive array
|
|
68
|
+
*
|
|
69
|
+
* @param frozen Freeze the array? _(defaults to `false`)_
|
|
70
|
+
* @returns Readonly reactive array
|
|
71
|
+
*/
|
|
72
|
+
asReadonly(
|
|
73
|
+
frozen?: boolean,
|
|
74
|
+
): typeof frozen extends true ? ReadonlyFrozenSignal<Item[]> : ReadonlySignal<Item[]>;
|
|
75
|
+
|
|
55
76
|
/**
|
|
56
77
|
* Get the value at an index
|
|
57
78
|
*
|
|
@@ -114,17 +135,19 @@ export type ReactiveArray<Item> = {
|
|
|
114
135
|
/**
|
|
115
136
|
* Get the array _(without reactivity)_
|
|
116
137
|
*
|
|
138
|
+
* @param copy Copy the array? _(defaults to `false`)_
|
|
117
139
|
* @returns Array of items
|
|
118
140
|
*/
|
|
119
|
-
peek(): Item[];
|
|
141
|
+
peek(copy?: boolean): Item[];
|
|
120
142
|
|
|
121
143
|
/**
|
|
122
144
|
* Get the value at an index _(without reactivity)_
|
|
123
145
|
*
|
|
124
146
|
* @param index Index of item to get _(if negative, starts from the end)_
|
|
147
|
+
* @param copy If the item is an array or record, should it be copied? _(defaults to `false`)_
|
|
125
148
|
* @returns Item at index, or `undefined` if it doesn't exist
|
|
126
149
|
*/
|
|
127
|
-
peek(index: number): Item | undefined;
|
|
150
|
+
peek(index: number, copy?: boolean): Item | undefined;
|
|
128
151
|
|
|
129
152
|
/**
|
|
130
153
|
* Get the length of the array _(without reactivity)_
|
|
@@ -208,18 +231,24 @@ export type ReactiveArray<Item> = {
|
|
|
208
231
|
* Subscribe to changes
|
|
209
232
|
*
|
|
210
233
|
* @param callback Callback for changes
|
|
211
|
-
* @
|
|
234
|
+
* @param copy Copy the array? _(defaults to `false`)_
|
|
235
|
+
* @returns Subscription
|
|
212
236
|
*/
|
|
213
|
-
subscribe(callback: (value: Item[]) => void):
|
|
237
|
+
subscribe(callback: (value: Item[]) => void, copy?: boolean): Subscription;
|
|
214
238
|
|
|
215
239
|
/**
|
|
216
240
|
* Subscribe to changes at a specific index
|
|
217
241
|
*
|
|
218
242
|
* @param index Index of item to subscribe to
|
|
219
243
|
* @param callback Callback for changes
|
|
220
|
-
* @
|
|
244
|
+
* @param copy If the item is an array or record, should it be copied? _(defaults to `false`)_
|
|
245
|
+
* @returns Subscription
|
|
221
246
|
*/
|
|
222
|
-
subscribe(
|
|
247
|
+
subscribe(
|
|
248
|
+
index: number,
|
|
249
|
+
callback: (value: Item | undefined) => void,
|
|
250
|
+
copy?: boolean,
|
|
251
|
+
): Subscription;
|
|
223
252
|
|
|
224
253
|
/**
|
|
225
254
|
* Add items to the beginning of the array
|
|
@@ -228,21 +257,6 @@ export type ReactiveArray<Item> = {
|
|
|
228
257
|
*/
|
|
229
258
|
unshift(...items: Item[]): number;
|
|
230
259
|
|
|
231
|
-
/**
|
|
232
|
-
* Unsubscribe from changes for a specific index
|
|
233
|
-
*
|
|
234
|
-
* @param index Index of the value to unsubscribe from
|
|
235
|
-
* @param callback Callback to unsubscribe
|
|
236
|
-
*/
|
|
237
|
-
unsubscribe(index: number, callback: (item: Item | undefined) => void): void;
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Unsubscribe from changes
|
|
241
|
-
*
|
|
242
|
-
* @param callback Callback to unsubscribe
|
|
243
|
-
*/
|
|
244
|
-
unsubscribe(callback: (array: Item[]) => void): void;
|
|
245
|
-
|
|
246
260
|
/**
|
|
247
261
|
* Update the value _(based on the current value)_
|
|
248
262
|
*
|
|
@@ -262,23 +276,41 @@ export type ReactiveOptions<Value> = {
|
|
|
262
276
|
equal?: (first: Value, second: Value) => boolean;
|
|
263
277
|
};
|
|
264
278
|
|
|
265
|
-
export type ReactiveState<Value,
|
|
279
|
+
export type ReactiveState<Value, Item = Value> = {
|
|
266
280
|
computeds: Set<ComputedEffect>;
|
|
267
281
|
effects: Set<EffectState>;
|
|
268
|
-
equal: (first:
|
|
282
|
+
equal: (first: Item, second: Item) => boolean;
|
|
269
283
|
promise?: Promise<Value>;
|
|
270
284
|
promises?: Map<Key, Promise<never>>;
|
|
271
|
-
subscriptions
|
|
285
|
+
subscriptions?: Subscriptions<GenericCallback>;
|
|
272
286
|
value: Value;
|
|
273
287
|
};
|
|
274
288
|
|
|
275
|
-
export type ReactiveStore<
|
|
289
|
+
export type ReactiveStore<Store> = {
|
|
290
|
+
/**
|
|
291
|
+
* Get a readonly version of the reactive store
|
|
292
|
+
*
|
|
293
|
+
* @param frozen Freeze the store? _(defaults to `false`)_
|
|
294
|
+
* @returns Readonly reactive store
|
|
295
|
+
*/
|
|
296
|
+
asReadonly(frozen: true): ReadonlyFrozenSignal<Store>;
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Get a readonly version of the reactive store
|
|
300
|
+
*
|
|
301
|
+
* @param frozen Freeze the store? _(defaults to `false`)_
|
|
302
|
+
* @returns Readonly reactive store
|
|
303
|
+
*/
|
|
304
|
+
asReadonly(
|
|
305
|
+
frozen?: boolean,
|
|
306
|
+
): typeof frozen extends true ? ReadonlyFrozenSignal<Store> : ReadonlySignal<Store>;
|
|
307
|
+
|
|
276
308
|
/**
|
|
277
309
|
* Get the value
|
|
278
310
|
*
|
|
279
311
|
* @returns Current value
|
|
280
312
|
*/
|
|
281
|
-
get():
|
|
313
|
+
get(): Store;
|
|
282
314
|
|
|
283
315
|
/**
|
|
284
316
|
* Get a value by key
|
|
@@ -286,7 +318,7 @@ export type ReactiveStore<Value> = {
|
|
|
286
318
|
* @param key Key of the value to get
|
|
287
319
|
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
288
320
|
*/
|
|
289
|
-
get<Key extends keyof
|
|
321
|
+
get<Key extends keyof Store>(key: Key): Store[Key];
|
|
290
322
|
|
|
291
323
|
/**
|
|
292
324
|
* Get a value by key
|
|
@@ -307,25 +339,28 @@ export type ReactiveStore<Value> = {
|
|
|
307
339
|
/**
|
|
308
340
|
* Get the value _(without reactivity)_
|
|
309
341
|
*
|
|
342
|
+
* @param copy Copy the store? _(defaults to `false`)_
|
|
310
343
|
* @returns Current value
|
|
311
344
|
*/
|
|
312
|
-
peek():
|
|
345
|
+
peek(copy?: boolean): Store;
|
|
313
346
|
|
|
314
347
|
/**
|
|
315
348
|
* Get a value by key _(without reactivity)_
|
|
316
349
|
*
|
|
317
350
|
* @param key Key of the value to get
|
|
351
|
+
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
318
352
|
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
319
353
|
*/
|
|
320
|
-
peek<Key extends keyof
|
|
354
|
+
peek<Key extends keyof Store>(key: Key, copy?: boolean): Store[Key];
|
|
321
355
|
|
|
322
356
|
/**
|
|
323
357
|
* Get a value by key _(without reactivity)_
|
|
324
358
|
*
|
|
325
359
|
* @param key Key of the value to get
|
|
360
|
+
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
326
361
|
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
327
362
|
*/
|
|
328
|
-
peek(key: Key): unknown;
|
|
363
|
+
peek(key: Key, copy?: boolean): unknown;
|
|
329
364
|
|
|
330
365
|
/**
|
|
331
366
|
* Set the value
|
|
@@ -334,9 +369,9 @@ export type ReactiveStore<Value> = {
|
|
|
334
369
|
*/
|
|
335
370
|
set(
|
|
336
371
|
value?:
|
|
337
|
-
|
|
|
338
|
-
| (() => null | undefined |
|
|
339
|
-
| Promise<null | undefined |
|
|
372
|
+
| Store
|
|
373
|
+
| (() => null | undefined | Store | Promise<null | undefined | Store>)
|
|
374
|
+
| Promise<null | undefined | Store>,
|
|
340
375
|
): void;
|
|
341
376
|
|
|
342
377
|
/**
|
|
@@ -345,9 +380,9 @@ export type ReactiveStore<Value> = {
|
|
|
345
380
|
* @param key Key of the value to set
|
|
346
381
|
* @param value New value
|
|
347
382
|
*/
|
|
348
|
-
set<Key extends keyof
|
|
383
|
+
set<Key extends keyof Store>(
|
|
349
384
|
key: Key,
|
|
350
|
-
value:
|
|
385
|
+
value: Store[Key] | (() => Store[Key] | Promise<Store[Key]>) | Promise<Store[Key]>,
|
|
351
386
|
): void;
|
|
352
387
|
|
|
353
388
|
/**
|
|
@@ -362,67 +397,83 @@ export type ReactiveStore<Value> = {
|
|
|
362
397
|
* Subscribe to changes
|
|
363
398
|
*
|
|
364
399
|
* @param callback Callback for changes
|
|
365
|
-
* @
|
|
400
|
+
* @param copy Copy the store? _(defaults to `false`)_
|
|
401
|
+
* @returns Subscription
|
|
366
402
|
*/
|
|
367
|
-
subscribe(callback: (value:
|
|
403
|
+
subscribe(callback: (value: Store) => void, copy?: boolean): Subscription;
|
|
368
404
|
|
|
369
405
|
/**
|
|
370
406
|
* Subscribe to changes for a specific key
|
|
371
407
|
*
|
|
372
408
|
* @param key Key of the value to subscribe to
|
|
373
409
|
* @param callback Callback for changes
|
|
374
|
-
* @
|
|
410
|
+
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
411
|
+
* @returns Subscription
|
|
375
412
|
*/
|
|
376
|
-
subscribe<Key extends keyof
|
|
413
|
+
subscribe<Key extends keyof Store>(
|
|
377
414
|
key: Key,
|
|
378
|
-
callback: (value:
|
|
379
|
-
|
|
415
|
+
callback: (value: Store[Key] | undefined) => void,
|
|
416
|
+
copy?: boolean,
|
|
417
|
+
): Subscription;
|
|
380
418
|
|
|
381
419
|
/**
|
|
382
420
|
* Subscribe to changes for a specific key
|
|
383
421
|
*
|
|
384
422
|
* @param key Key of the value to subscribe to
|
|
385
423
|
* @param callback Callback for changes
|
|
386
|
-
* @
|
|
424
|
+
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
425
|
+
* @returns Subscription
|
|
387
426
|
*/
|
|
388
|
-
subscribe(key: Key, callback: (value: unknown) => void):
|
|
427
|
+
subscribe(key: Key, callback: (value: unknown) => void, copy?: boolean): Subscription;
|
|
389
428
|
|
|
390
429
|
/**
|
|
391
|
-
*
|
|
430
|
+
* Update the value _(based on the current value)_
|
|
392
431
|
*
|
|
393
|
-
* @param
|
|
394
|
-
* @param callback Callback to unsubscribe
|
|
432
|
+
* @param callback Callback to update the value
|
|
395
433
|
*/
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
434
|
+
update(callback: (value: Store) => Store): void;
|
|
435
|
+
} & Reactive<Store>;
|
|
436
|
+
|
|
437
|
+
export type ReadonlyInstances<Value> = {
|
|
438
|
+
frozen?: ReadonlyFrozenSignal<Value>;
|
|
439
|
+
original?: ReadonlySignal<Value>;
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
export type ReadonlyFrozenSignal<Value> = ReadonlySignal<ReadonlySignalValue<Value>>;
|
|
400
443
|
|
|
444
|
+
export type ReadonlySignal<Value> = {
|
|
401
445
|
/**
|
|
402
|
-
*
|
|
446
|
+
* Is the signal frozen?
|
|
447
|
+
*/
|
|
448
|
+
get frozen(): boolean;
|
|
449
|
+
} & Reactive<Value> &
|
|
450
|
+
SimpleReactive<Value>;
|
|
451
|
+
|
|
452
|
+
export type ReadonlySignalValue<Value> = Value extends unknown[]
|
|
453
|
+
? Readonly<Value>
|
|
454
|
+
: Value extends PlainObject
|
|
455
|
+
? Readonly<Value>
|
|
456
|
+
: Value;
|
|
457
|
+
|
|
458
|
+
export type Signal<Value> = {
|
|
459
|
+
/**
|
|
460
|
+
* Get a readonly version of the signal
|
|
403
461
|
*
|
|
404
|
-
* @param
|
|
462
|
+
* @param frozen Freeze the signal? _(defaults to `false`)_
|
|
463
|
+
* @returns Readonly signal
|
|
405
464
|
*/
|
|
406
|
-
|
|
465
|
+
asReadonly(frozen: true): ReadonlyFrozenSignal<Value>;
|
|
407
466
|
|
|
408
467
|
/**
|
|
409
|
-
*
|
|
468
|
+
* Get a readonly version of the signal
|
|
410
469
|
*
|
|
411
|
-
* @param
|
|
470
|
+
* @param frozen Freeze the signal? _(defaults to `false`)_
|
|
471
|
+
* @returns Readonly signal
|
|
412
472
|
*/
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
export type SetValueInProxyParameters<Value, Equal> = {
|
|
417
|
-
target: Value;
|
|
418
|
-
property: PropertyKey;
|
|
419
|
-
value: unknown;
|
|
420
|
-
state: ReactiveState<Value, Equal>;
|
|
421
|
-
isArray: boolean;
|
|
422
|
-
length?: Signal<number>;
|
|
423
|
-
};
|
|
473
|
+
asReadonly(
|
|
474
|
+
frozen?: boolean,
|
|
475
|
+
): typeof frozen extends true ? ReadonlyFrozenSignal<Value> : ReadonlySignal<Value>;
|
|
424
476
|
|
|
425
|
-
export type Signal<Value> = {
|
|
426
477
|
/**
|
|
427
478
|
* Set the value
|
|
428
479
|
*
|
|
@@ -450,34 +501,28 @@ type SimpleReactive<Value> = {
|
|
|
450
501
|
/**
|
|
451
502
|
* Get the value _(without reactivity)_
|
|
452
503
|
*
|
|
504
|
+
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
453
505
|
* @returns Current value
|
|
454
506
|
*/
|
|
455
|
-
peek(): Value;
|
|
507
|
+
peek(copy?: boolean): Value;
|
|
456
508
|
|
|
457
509
|
/**
|
|
458
510
|
* Subscribe to changes
|
|
459
511
|
*
|
|
460
512
|
* @param callback Callback for changes
|
|
461
|
-
* @
|
|
513
|
+
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
514
|
+
* @returns Subscription
|
|
462
515
|
*/
|
|
463
|
-
subscribe(callback: (value: Value) => void):
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
* Unsubscribe from changes
|
|
467
|
-
*
|
|
468
|
-
* @param callback Callback to unsubscribe
|
|
469
|
-
*/
|
|
470
|
-
unsubscribe(callback: (value: Value) => void): void;
|
|
516
|
+
subscribe(callback: (value: Value) => void, copy?: boolean): Subscription;
|
|
471
517
|
};
|
|
472
518
|
|
|
473
|
-
export type
|
|
519
|
+
export type StoredSubscription = {
|
|
474
520
|
callback: GenericCallback;
|
|
521
|
+
copy: boolean;
|
|
522
|
+
frozen: boolean;
|
|
475
523
|
state: ReactiveState<unknown, never>;
|
|
476
|
-
|
|
477
|
-
destroy(): void;
|
|
478
524
|
};
|
|
479
525
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
export type Unsubscribe = () => void;
|
|
526
|
+
export type SubscriptionType = 'copy' | 'frozen' | 'original' | 'readonly';
|
|
527
|
+
|
|
528
|
+
// #endregion
|
package/src/value/array.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import {select} from '@oscarpalmer/atoms/array';
|
|
2
2
|
import {filter} from '@oscarpalmer/atoms/array/filter';
|
|
3
|
-
import {noop} from '@oscarpalmer/atoms/function';
|
|
4
|
-
import type {GenericCallback} from '@oscarpalmer/atoms/models';
|
|
5
3
|
import {
|
|
6
4
|
METHODS_AFFECTING_LENGTH,
|
|
7
5
|
METHODS_UPDATE,
|
|
@@ -10,25 +8,31 @@ import {
|
|
|
10
8
|
PROPERTY_LENGTH,
|
|
11
9
|
} from '../constants';
|
|
12
10
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
emitProxyValues,
|
|
12
|
+
getValueInProxy,
|
|
13
|
+
peekValueInProxy,
|
|
15
14
|
setProxyValue,
|
|
16
15
|
setValueInProxy,
|
|
16
|
+
updateProxyValue,
|
|
17
17
|
} from '../helpers/proxy';
|
|
18
|
-
import {
|
|
18
|
+
import {subscribeToProxy} from '../helpers/subscription';
|
|
19
|
+
import {emitValue, equalArrays} from '../helpers/value';
|
|
19
20
|
import type {
|
|
20
21
|
Computed,
|
|
21
22
|
ComputedEffect,
|
|
22
23
|
ReactiveArray,
|
|
23
24
|
ReactiveOptions,
|
|
24
25
|
ReactiveState,
|
|
26
|
+
ReadonlyInstances,
|
|
25
27
|
Signal,
|
|
26
28
|
} from '../models';
|
|
27
|
-
import {subscribe, unsubscribe} from '../subscription';
|
|
28
29
|
import {computed} from './computed';
|
|
29
30
|
import {reactive} from './reactive';
|
|
31
|
+
import {getReadonlyInstance} from './readonly';
|
|
30
32
|
import {signal} from './signal';
|
|
31
33
|
|
|
34
|
+
// #region Functions
|
|
35
|
+
|
|
32
36
|
/**
|
|
33
37
|
* Create a reactive array from a function result
|
|
34
38
|
*
|
|
@@ -68,8 +72,10 @@ export function array<Item>(
|
|
|
68
72
|
): ReactiveArray<Item> {
|
|
69
73
|
const [rx, state] = reactive<Item[], Item>([], options);
|
|
70
74
|
|
|
71
|
-
const
|
|
75
|
+
const isArray = true;
|
|
72
76
|
const length = signal(0);
|
|
77
|
+
const mapped = new Map<number, [Computed<unknown>, ComputedEffect]>();
|
|
78
|
+
const readonlies: ReadonlyInstances<Item[]> = {};
|
|
73
79
|
|
|
74
80
|
state.value = new Proxy([], {
|
|
75
81
|
get: (target: Item[], property: PropertyKey) =>
|
|
@@ -77,14 +83,7 @@ export function array<Item>(
|
|
|
77
83
|
? updateArray(property as string, target, state, length)
|
|
78
84
|
: Reflect.get(target, property),
|
|
79
85
|
set: (target: Item[], property: PropertyKey, value: Item) =>
|
|
80
|
-
setValueInProxy(
|
|
81
|
-
length,
|
|
82
|
-
property,
|
|
83
|
-
state,
|
|
84
|
-
target,
|
|
85
|
-
value,
|
|
86
|
-
isArray: true,
|
|
87
|
-
}),
|
|
86
|
+
setValueInProxy(isArray, state, target, property, value, length),
|
|
88
87
|
});
|
|
89
88
|
|
|
90
89
|
function get(): Item[];
|
|
@@ -92,76 +91,43 @@ export function array<Item>(
|
|
|
92
91
|
function get(property: typeof PROPERTY_LENGTH): number;
|
|
93
92
|
function get(value?: unknown): number | Item | Item[] | undefined;
|
|
94
93
|
|
|
95
|
-
function get(value?: unknown):
|
|
96
|
-
return
|
|
94
|
+
function get(value?: unknown): unknown {
|
|
95
|
+
return value === PROPERTY_LENGTH
|
|
96
|
+
? length.get()
|
|
97
|
+
: getValueInProxy(isArray, instance as never, state, mapped, value);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function set(first?: never, second?: never): void {
|
|
101
|
+
setProxyValue<Item[], Item>(true, state, setArrayValue, setAtIndex, first, second);
|
|
97
102
|
}
|
|
98
103
|
|
|
99
104
|
const instance = {
|
|
100
105
|
...rx,
|
|
101
|
-
|
|
102
|
-
at: (index:
|
|
106
|
+
asReadonly: (frozen?: never) => getReadonlyInstance(state, readonlies, frozen === true),
|
|
107
|
+
at: (index: never) => get(index),
|
|
103
108
|
clear: () => {
|
|
104
109
|
state.value.length = 0;
|
|
105
110
|
},
|
|
106
|
-
filter: (callback:
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
notify: () => {
|
|
112
|
-
emityProxyValues(state, indiced);
|
|
113
|
-
},
|
|
114
|
-
peek: (value?: unknown) => peekArrayValue(state, length, value),
|
|
111
|
+
filter: (callback: never) => computed(() => filter(get(), callback)),
|
|
112
|
+
get: (value?: never) => get(value),
|
|
113
|
+
map: (callback: never) => computed(() => get().map(callback)),
|
|
114
|
+
notify: () => emitProxyValues(state, mapped),
|
|
115
|
+
peek: (first?: never, second?: never) => peekArrayValue(state, length, first, second),
|
|
115
116
|
pop: () => state.value.pop(),
|
|
116
117
|
push: (...items: Item[]) => state.value.push(...items),
|
|
117
|
-
select:
|
|
118
|
-
|
|
119
|
-
map: (item: Item, index: number, array: Item[]) => Mapped,
|
|
120
|
-
) => computed(() => select(get() as Item[], filter, map)),
|
|
121
|
-
set: (first?: unknown, second?: unknown) => {
|
|
122
|
-
setProxyValue<Item[], Item>(
|
|
123
|
-
true,
|
|
124
|
-
state,
|
|
125
|
-
isArrayValue,
|
|
126
|
-
isArrayIndex,
|
|
127
|
-
setArray,
|
|
128
|
-
setAtIndex,
|
|
129
|
-
first,
|
|
130
|
-
second,
|
|
131
|
-
);
|
|
132
|
-
},
|
|
118
|
+
select: (filter: never, map: never) => computed(() => select(get(), filter, map)),
|
|
119
|
+
set: (first?: never, second?: never) => set(first, second),
|
|
133
120
|
shift: () => state.value.shift(),
|
|
134
|
-
splice: (from:
|
|
121
|
+
splice: (from: never, to?: never, ...items: Item[]) =>
|
|
135
122
|
state.value.splice(from, to ?? state.value.length, ...items),
|
|
136
|
-
subscribe: (first:
|
|
137
|
-
|
|
138
|
-
return getReactiveValueInProxy(
|
|
139
|
-
instance as ReactiveArray<Item>,
|
|
140
|
-
indiced,
|
|
141
|
-
first,
|
|
142
|
-
true,
|
|
143
|
-
).subscribe(second);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return typeof first === 'function' ? subscribe(state, first) : noop;
|
|
147
|
-
},
|
|
123
|
+
subscribe: (first: never, second?: never, third?: never) =>
|
|
124
|
+
subscribeToProxy(isArray, instance as never, state, mapped, first, second, third),
|
|
148
125
|
unshift: (...items: Item[]) => state.value.unshift(...items),
|
|
149
|
-
|
|
150
|
-
if (typeof first === 'number' && typeof second === 'function') {
|
|
151
|
-
getReactiveValueInProxy(instance as ReactiveArray<Item>, indiced, first, true)?.unsubscribe(
|
|
152
|
-
second,
|
|
153
|
-
);
|
|
154
|
-
} else if (typeof first === 'function') {
|
|
155
|
-
unsubscribe(state, first);
|
|
156
|
-
}
|
|
157
|
-
},
|
|
158
|
-
update: (callback: (value: Item[]) => Item[]) =>
|
|
159
|
-
updateArrayValue(instance as ReactiveArray<Item>, state, callback),
|
|
126
|
+
update: (callback: never) => updateProxyValue(true, state, setArrayValue, setAtIndex, callback),
|
|
160
127
|
};
|
|
161
128
|
|
|
162
129
|
Object.defineProperties(instance, {
|
|
163
130
|
[NAME_MORA]: {
|
|
164
|
-
enumerable: false,
|
|
165
131
|
value: NAME_ARRAY,
|
|
166
132
|
},
|
|
167
133
|
length: {
|
|
@@ -171,60 +137,51 @@ export function array<Item>(
|
|
|
171
137
|
},
|
|
172
138
|
});
|
|
173
139
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return Object.freeze(instance) as ReactiveArray<Item>;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function getArrayValue<Item>(
|
|
180
|
-
instance: ReactiveArray<Item>,
|
|
181
|
-
indiced: Map<number, [Computed<unknown>, ComputedEffect]>,
|
|
182
|
-
state: ReactiveState<Item[], Item>,
|
|
183
|
-
length: Signal<number>,
|
|
184
|
-
first?: unknown,
|
|
185
|
-
): number | Item | Item[] | undefined {
|
|
186
|
-
if (typeof first === 'number') {
|
|
187
|
-
return getReactiveValueInProxy(instance, indiced, first, true).get();
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return first === PROPERTY_LENGTH ? length.get() : getSimpleValue(state);
|
|
191
|
-
}
|
|
140
|
+
set(value as never);
|
|
192
141
|
|
|
193
|
-
|
|
194
|
-
return typeof value === 'number';
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function isArrayValue<Item>(value: unknown): value is Item[] | undefined {
|
|
198
|
-
return value == null || Array.isArray(value);
|
|
142
|
+
return Object.freeze(instance) as never;
|
|
199
143
|
}
|
|
200
144
|
|
|
201
145
|
function peekArrayValue<Item>(
|
|
202
146
|
state: ReactiveState<Item[], Item>,
|
|
203
147
|
length: Signal<number>,
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return typeof value === 'number' ? state.value.at(value) : state.value.slice();
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
function setArray<Item>(state: ReactiveState<Item[], Item>, value: Item[] | undefined): void {
|
|
214
|
-
state.value.splice(0, state.value.length, ...(value ?? []));
|
|
148
|
+
first?: unknown,
|
|
149
|
+
second?: boolean,
|
|
150
|
+
): unknown {
|
|
151
|
+
return first === PROPERTY_LENGTH ? length.peek() : peekValueInProxy(true, state, first, second);
|
|
215
152
|
}
|
|
216
153
|
|
|
217
154
|
function setArrayLength<Item>(state: ReactiveState<Item[], Item>, value: number): void {
|
|
218
|
-
if (
|
|
155
|
+
if (
|
|
156
|
+
typeof value === 'number' &&
|
|
157
|
+
!Number.isNaN(value) &&
|
|
158
|
+
value >= 0 &&
|
|
159
|
+
value !== state.value.length
|
|
160
|
+
) {
|
|
219
161
|
state.value.length = value;
|
|
220
162
|
}
|
|
221
163
|
}
|
|
222
164
|
|
|
223
|
-
function
|
|
224
|
-
|
|
165
|
+
function setArrayValue<Value, Item = Value>(state: ReactiveState<Value, Item>, value: Value): void {
|
|
166
|
+
(state.value as unknown[]).splice(
|
|
167
|
+
0,
|
|
168
|
+
(state.value as unknown[]).length,
|
|
169
|
+
...((value as unknown[]) ?? []),
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function setAtIndex<Value, Item = Value>(
|
|
174
|
+
state: ReactiveState<Value, Item>,
|
|
175
|
+
index: unknown,
|
|
176
|
+
value: Item,
|
|
177
|
+
): void {
|
|
178
|
+
const actual =
|
|
179
|
+
(index as number) < 0
|
|
180
|
+
? (state.value as unknown[]).length + (index as number)
|
|
181
|
+
: (index as number);
|
|
225
182
|
|
|
226
183
|
if (actual > -1) {
|
|
227
|
-
state.value[actual] = value;
|
|
184
|
+
(state.value as unknown[])[actual] = value;
|
|
228
185
|
}
|
|
229
186
|
}
|
|
230
187
|
|
|
@@ -238,7 +195,7 @@ function updateArray<Item>(
|
|
|
238
195
|
const previousArray = affectsLength ? [] : array.slice();
|
|
239
196
|
const previousLength = array.length;
|
|
240
197
|
|
|
241
|
-
return (...args: unknown[])
|
|
198
|
+
return (...args: unknown[]) => {
|
|
242
199
|
const result = (array[type as never] as (...args: unknown[]) => unknown)(...args);
|
|
243
200
|
|
|
244
201
|
if (
|
|
@@ -253,14 +210,4 @@ function updateArray<Item>(
|
|
|
253
210
|
};
|
|
254
211
|
}
|
|
255
212
|
|
|
256
|
-
|
|
257
|
-
instance: ReactiveArray<Item>,
|
|
258
|
-
state: ReactiveState<Item[], Item>,
|
|
259
|
-
callback: (value: Item[]) => Item[],
|
|
260
|
-
): void {
|
|
261
|
-
const updated = callback(state.value);
|
|
262
|
-
|
|
263
|
-
if (updated == null || Array.isArray(updated)) {
|
|
264
|
-
instance.set(updated);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
213
|
+
// #endregion
|