@oscarpalmer/mora 0.29.0 → 0.31.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.mjs +15 -6
- package/dist/constants.d.mts +2 -2
- package/dist/constants.mjs +7 -4
- package/dist/effect.d.mts +5 -18
- package/dist/effect.mjs +23 -19
- package/dist/helpers/is.d.mts +17 -16
- package/dist/helpers/is.mjs +20 -11
- package/dist/helpers/proxy.d.mts +5 -9
- package/dist/helpers/proxy.mjs +4 -4
- package/dist/helpers/value.d.mts +3 -3
- package/dist/helpers/value.mjs +22 -5
- package/dist/index.d.mts +8 -9
- package/dist/index.mjs +2 -2
- package/dist/models.d.mts +423 -19
- package/dist/mora.full.mjs +532 -424
- package/dist/subscription.d.mts +1 -9
- package/dist/subscription.mjs +14 -15
- package/dist/value/array.d.mts +5 -133
- package/dist/value/array.mjs +108 -138
- package/dist/value/computed.d.mts +4 -12
- package/dist/value/computed.mjs +54 -50
- package/dist/value/reactive.d.mts +3 -49
- package/dist/value/reactive.mjs +10 -54
- package/dist/value/readonly.d.mts +7 -0
- package/dist/value/readonly.mjs +37 -0
- package/dist/value/signal.d.mts +5 -21
- package/dist/value/signal.mjs +33 -49
- package/dist/value/store.d.mts +9 -92
- package/dist/value/store.mjs +58 -49
- package/package.json +7 -8
- package/src/batch.ts +22 -9
- package/src/constants.ts +12 -5
- package/src/effect.ts +35 -40
- package/src/helpers/is.ts +36 -20
- package/src/helpers/proxy.ts +23 -18
- package/src/helpers/value.ts +39 -5
- package/src/index.ts +23 -8
- package/src/models.ts +520 -17
- package/src/subscription.ts +20 -20
- package/src/value/array.ts +220 -266
- package/src/value/computed.ts +80 -74
- package/src/value/reactive.ts +16 -77
- package/src/value/readonly.ts +71 -0
- package/src/value/signal.ts +43 -71
- package/src/value/store.ts +130 -177
- 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 +3 -0
- package/types/value/signal.d.ts +1 -1
- package/types/value/store.d.ts +1 -1
package/src/models.ts
CHANGED
|
@@ -1,37 +1,276 @@
|
|
|
1
|
-
import type {GenericCallback, Key} from '@oscarpalmer/atoms/models';
|
|
2
|
-
import type {
|
|
3
|
-
import type {Subscription} from './subscription';
|
|
4
|
-
import type {Computed} from './value/computed';
|
|
5
|
-
import type {Signal} from './value/signal';
|
|
1
|
+
import type {GenericCallback, Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
+
import type {PROPERTY_LENGTH} from './constants';
|
|
6
3
|
|
|
7
4
|
export type Active = {
|
|
8
|
-
computed?:
|
|
9
|
-
effect?:
|
|
5
|
+
computed?: ComputedEffect;
|
|
6
|
+
effect?: EffectState;
|
|
10
7
|
};
|
|
11
8
|
|
|
12
9
|
export type Batch = {
|
|
13
10
|
depth: number;
|
|
14
|
-
|
|
11
|
+
flushing: boolean;
|
|
12
|
+
handlers: Set<EffectState | Subscription>;
|
|
15
13
|
};
|
|
16
14
|
|
|
15
|
+
export type Computed<Value> = Reactive<Value> & SimpleReactive<Value>;
|
|
16
|
+
|
|
17
17
|
export type ComputedEffect = {
|
|
18
18
|
dirty: boolean;
|
|
19
|
-
instance:
|
|
19
|
+
instance: EffectState;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
+
export type Effect = {};
|
|
23
|
+
|
|
22
24
|
export type EffectState = {
|
|
23
25
|
callback: GenericCallback;
|
|
24
26
|
};
|
|
25
27
|
|
|
26
|
-
export type
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
export type Reactive<Value> = {
|
|
29
|
+
/**
|
|
30
|
+
* JSON representation of the value
|
|
31
|
+
*
|
|
32
|
+
* @returns JSON value
|
|
33
|
+
*/
|
|
34
|
+
toJSON(): Value;
|
|
30
35
|
|
|
31
|
-
|
|
32
|
-
|
|
36
|
+
/**
|
|
37
|
+
* String representation of the value
|
|
38
|
+
*
|
|
39
|
+
* @returns Value as string
|
|
40
|
+
*/
|
|
41
|
+
toString(): string;
|
|
33
42
|
};
|
|
34
43
|
|
|
44
|
+
export type ReactiveArray<Item> = {
|
|
45
|
+
/**
|
|
46
|
+
* The length of the array
|
|
47
|
+
*/
|
|
48
|
+
get length(): number;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Set the length of the array
|
|
52
|
+
*/
|
|
53
|
+
set length(value: number);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get a readonly version of the reactive array
|
|
57
|
+
*
|
|
58
|
+
* @param frozen Freeze the array? _(defaults to `false`)_
|
|
59
|
+
* @returns Readonly reactive array
|
|
60
|
+
*/
|
|
61
|
+
asReadonly(frozen: true): ReadonlyFrozenSignal<Item[]>;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get a readonly version of the reactive array
|
|
65
|
+
*
|
|
66
|
+
* @param frozen Freeze the array? _(defaults to `false`)_
|
|
67
|
+
* @returns Readonly reactive array
|
|
68
|
+
*/
|
|
69
|
+
asReadonly(
|
|
70
|
+
frozen?: boolean,
|
|
71
|
+
): typeof frozen extends true ? ReadonlyFrozenSignal<Item[]> : ReadonlySignal<Item[]>;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get the value at an index
|
|
75
|
+
*
|
|
76
|
+
* @param index Index of item to get _(if negative, starts from the end)_
|
|
77
|
+
* @returns Item at index, or `undefined` if it doesn't exist
|
|
78
|
+
*/
|
|
79
|
+
at(index: number): Item | undefined;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Clear the array
|
|
83
|
+
*/
|
|
84
|
+
clear(): void;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Create a computed, filtered array
|
|
88
|
+
*
|
|
89
|
+
* @param callback Callback to evaluate each item
|
|
90
|
+
* @returns Computed array of filtered items
|
|
91
|
+
*/
|
|
92
|
+
filter(callback: (item: Item, index: number, array: Item[]) => boolean): Computed<Item[]>;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Get the array
|
|
96
|
+
*
|
|
97
|
+
* @returns Array of items
|
|
98
|
+
*/
|
|
99
|
+
get(): Item[];
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Get the value at an index
|
|
103
|
+
*
|
|
104
|
+
* @param index Index of item to get _(if negative, starts from the end)_
|
|
105
|
+
* @returns Item at index, or `undefined` if it doesn't exist
|
|
106
|
+
*/
|
|
107
|
+
get(index: number): Item | undefined;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Get the length of the array
|
|
111
|
+
*
|
|
112
|
+
* @returns Length of the array
|
|
113
|
+
*/
|
|
114
|
+
get(property: typeof PROPERTY_LENGTH): number;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Create a computed, mapped array
|
|
118
|
+
*
|
|
119
|
+
* @param callback Callback to transform each item
|
|
120
|
+
* @returns Computed array of mapped items
|
|
121
|
+
*/
|
|
122
|
+
map<Mapped>(callback: (item: Item, index: number, array: Item[]) => Mapped): Computed<Mapped[]>;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Notify dependents of changes
|
|
126
|
+
*
|
|
127
|
+
* _This bypasses equality checks and will immediately notify dependents.
|
|
128
|
+
* Use this only if you're modifying nested data that would be ignored by equality checks._
|
|
129
|
+
*/
|
|
130
|
+
notify(): void;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Get the array _(without reactivity)_
|
|
134
|
+
*
|
|
135
|
+
* @param copy Copy the array? _(defaults to `false`)_
|
|
136
|
+
* @returns Array of items
|
|
137
|
+
*/
|
|
138
|
+
peek(copy?: boolean): Item[];
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get the value at an index _(without reactivity)_
|
|
142
|
+
*
|
|
143
|
+
* @param index Index of item to get _(if negative, starts from the end)_
|
|
144
|
+
* @param copy If the item is an array or record, should it be copied? _(defaults to `false`)_
|
|
145
|
+
* @returns Item at index, or `undefined` if it doesn't exist
|
|
146
|
+
*/
|
|
147
|
+
peek(index: number, copy?: boolean): Item | undefined;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Get the length of the array _(without reactivity)_
|
|
151
|
+
*
|
|
152
|
+
* @returns Length of the array
|
|
153
|
+
*/
|
|
154
|
+
peek(property: typeof PROPERTY_LENGTH): number;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Remove and return the last item of the array
|
|
158
|
+
*
|
|
159
|
+
* @returns Removed item, or `undefined` if the array is empty
|
|
160
|
+
*/
|
|
161
|
+
pop(): Item | undefined;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Add items to the end of the array
|
|
165
|
+
*
|
|
166
|
+
* @param items Items to add
|
|
167
|
+
* @returns New array length
|
|
168
|
+
*/
|
|
169
|
+
push(...items: Item[]): number;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Create a computed, filtered, and mapped array
|
|
173
|
+
*
|
|
174
|
+
* @param filter Callback to evaluate each item
|
|
175
|
+
* @param map Callback to transform each item
|
|
176
|
+
* @returns Computed array of mapped items
|
|
177
|
+
*/
|
|
178
|
+
select<Mapped>(
|
|
179
|
+
filter: (item: Item, index: number, array: Item[]) => boolean,
|
|
180
|
+
map: (item: Item, index: number, array: Item[]) => Mapped,
|
|
181
|
+
): Computed<Mapped[]>;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Set the value
|
|
185
|
+
*
|
|
186
|
+
* @param value New array of items _(defaults to an empty array)_
|
|
187
|
+
*/
|
|
188
|
+
set(
|
|
189
|
+
value?:
|
|
190
|
+
| Item[]
|
|
191
|
+
| (() => null | undefined | Item[] | Promise<null | undefined | Item[]>)
|
|
192
|
+
| Promise<null | undefined | Item[]>,
|
|
193
|
+
): void;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Set the value at an index
|
|
197
|
+
*
|
|
198
|
+
* @param index Index of item to set _(if negative, starts from the end)_
|
|
199
|
+
* @param value New item
|
|
200
|
+
*/
|
|
201
|
+
set(index: number, value: Item | (() => Item | Promise<Item>) | Promise<Item>): void;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Set the length of the array
|
|
205
|
+
*
|
|
206
|
+
* @param value New array length
|
|
207
|
+
*/
|
|
208
|
+
set(property: typeof PROPERTY_LENGTH, value: number): void;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Remove and return the first item of the array
|
|
212
|
+
*
|
|
213
|
+
* @returns Removed item, or `undefined` if the array is empty
|
|
214
|
+
*/
|
|
215
|
+
shift(): Item | undefined;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Remove and return items from the array _(and optionally add new items)_
|
|
219
|
+
*
|
|
220
|
+
* @param from Index to start removing items from
|
|
221
|
+
* @param to Index to stop removing items at _(defaults to the end of the array)_
|
|
222
|
+
* @param items Optional items to add
|
|
223
|
+
* @returns Removed items
|
|
224
|
+
*/
|
|
225
|
+
splice(from: number, to?: number, ...items: Item[]): Item[];
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Subscribe to changes
|
|
229
|
+
*
|
|
230
|
+
* @param callback Callback for changes
|
|
231
|
+
* @returns Unsubscribe callback
|
|
232
|
+
*/
|
|
233
|
+
subscribe(callback: (value: Item[]) => void): Unsubscribe;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Subscribe to changes at a specific index
|
|
237
|
+
*
|
|
238
|
+
* @param index Index of item to subscribe to
|
|
239
|
+
* @param callback Callback for changes
|
|
240
|
+
* @returns Unsubscribe callback
|
|
241
|
+
*/
|
|
242
|
+
subscribe(index: number, callback: (value: Item | undefined) => void): Unsubscribe;
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Add items to the beginning of the array
|
|
246
|
+
* @param items Items to add
|
|
247
|
+
* @returns New array length
|
|
248
|
+
*/
|
|
249
|
+
unshift(...items: Item[]): number;
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Unsubscribe from changes for a specific index
|
|
253
|
+
*
|
|
254
|
+
* @param index Index of the value to unsubscribe from
|
|
255
|
+
* @param callback Callback to unsubscribe
|
|
256
|
+
*/
|
|
257
|
+
unsubscribe(index: number, callback: (item: Item | undefined) => void): void;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Unsubscribe from changes
|
|
261
|
+
*
|
|
262
|
+
* @param callback Callback to unsubscribe
|
|
263
|
+
*/
|
|
264
|
+
unsubscribe(callback: (array: Item[]) => void): void;
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Update the value _(based on the current value)_
|
|
268
|
+
*
|
|
269
|
+
* @param callback Callback to update the value
|
|
270
|
+
*/
|
|
271
|
+
update(callback: (value: Item[]) => Item[]): void;
|
|
272
|
+
} & Reactive<Item[]>;
|
|
273
|
+
|
|
35
274
|
export type ReactiveOptions<Value> = {
|
|
36
275
|
/**
|
|
37
276
|
* Method for comparing values for equality
|
|
@@ -44,8 +283,8 @@ export type ReactiveOptions<Value> = {
|
|
|
44
283
|
};
|
|
45
284
|
|
|
46
285
|
export type ReactiveState<Value, Equal> = {
|
|
47
|
-
computeds: Set<
|
|
48
|
-
effects: Set<
|
|
286
|
+
computeds: Set<ComputedEffect>;
|
|
287
|
+
effects: Set<EffectState>;
|
|
49
288
|
equal: (first: Equal, second: Equal) => boolean;
|
|
50
289
|
promise?: Promise<Value>;
|
|
51
290
|
promises?: Map<Key, Promise<never>>;
|
|
@@ -53,6 +292,197 @@ export type ReactiveState<Value, Equal> = {
|
|
|
53
292
|
value: Value;
|
|
54
293
|
};
|
|
55
294
|
|
|
295
|
+
export type ReactiveStore<Store> = {
|
|
296
|
+
/**
|
|
297
|
+
* Get a readonly version of the reactive store
|
|
298
|
+
*
|
|
299
|
+
* @param frozen Freeze the store? _(defaults to `false`)_
|
|
300
|
+
* @returns Readonly reactive store
|
|
301
|
+
*/
|
|
302
|
+
asReadonly(frozen: true): ReadonlyFrozenSignal<Store>;
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Get a readonly version of the reactive store
|
|
306
|
+
*
|
|
307
|
+
* @param frozen Freeze the store? _(defaults to `false`)_
|
|
308
|
+
* @returns Readonly reactive store
|
|
309
|
+
*/
|
|
310
|
+
asReadonly(
|
|
311
|
+
frozen?: boolean,
|
|
312
|
+
): typeof frozen extends true ? ReadonlyFrozenSignal<Store> : ReadonlySignal<Store>;
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Get the value
|
|
316
|
+
*
|
|
317
|
+
* @returns Current value
|
|
318
|
+
*/
|
|
319
|
+
get(): Store;
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Get a value by key
|
|
323
|
+
*
|
|
324
|
+
* @param key Key of the value to get
|
|
325
|
+
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
326
|
+
*/
|
|
327
|
+
get<Key extends keyof Store>(key: Key): Store[Key];
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Get a value by key
|
|
331
|
+
*
|
|
332
|
+
* @param key Key of the value to get
|
|
333
|
+
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
334
|
+
*/
|
|
335
|
+
get(key: Key): unknown;
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Notify dependents of changes
|
|
339
|
+
*
|
|
340
|
+
* _This bypasses equality checks and will immediately notify dependents.
|
|
341
|
+
* Use this only if you're modifying nested data that would be ignored by equality checks._
|
|
342
|
+
*/
|
|
343
|
+
notify(): void;
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Get the value _(without reactivity)_
|
|
347
|
+
*
|
|
348
|
+
* @param copy Copy the store? _(defaults to `false`)_
|
|
349
|
+
* @returns Current value
|
|
350
|
+
*/
|
|
351
|
+
peek(copy?: boolean): Store;
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Get a value by key _(without reactivity)_
|
|
355
|
+
*
|
|
356
|
+
* @param key Key of the value to get
|
|
357
|
+
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
358
|
+
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
359
|
+
*/
|
|
360
|
+
peek<Key extends keyof Store>(key: Key, copy?: boolean): Store[Key];
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Get a value by key _(without reactivity)_
|
|
364
|
+
*
|
|
365
|
+
* @param key Key of the value to get
|
|
366
|
+
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
367
|
+
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
368
|
+
*/
|
|
369
|
+
peek(key: Key, copy?: boolean): unknown;
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Set the value
|
|
373
|
+
*
|
|
374
|
+
* @param value New value _(defaults to an empty object)_
|
|
375
|
+
*/
|
|
376
|
+
set(
|
|
377
|
+
value?:
|
|
378
|
+
| Store
|
|
379
|
+
| (() => null | undefined | Store | Promise<null | undefined | Store>)
|
|
380
|
+
| Promise<null | undefined | Store>,
|
|
381
|
+
): void;
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Set a value by key
|
|
385
|
+
*
|
|
386
|
+
* @param key Key of the value to set
|
|
387
|
+
* @param value New value
|
|
388
|
+
*/
|
|
389
|
+
set<Key extends keyof Store>(
|
|
390
|
+
key: Key,
|
|
391
|
+
value: Store[Key] | (() => Store[Key] | Promise<Store[Key]>) | Promise<Store[Key]>,
|
|
392
|
+
): void;
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Set a value by key
|
|
396
|
+
*
|
|
397
|
+
* @param key Key of the value to set
|
|
398
|
+
* @param value New value
|
|
399
|
+
*/
|
|
400
|
+
set(key: Key, value: unknown): void;
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Subscribe to changes
|
|
404
|
+
*
|
|
405
|
+
* @param callback Callback for changes
|
|
406
|
+
* @returns Unsubscribe callback
|
|
407
|
+
*/
|
|
408
|
+
subscribe(callback: (value: Store) => void): Unsubscribe;
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Subscribe to changes for a specific key
|
|
412
|
+
*
|
|
413
|
+
* @param key Key of the value to subscribe to
|
|
414
|
+
* @param callback Callback for changes
|
|
415
|
+
* @returns Unsubscribe callback
|
|
416
|
+
*/
|
|
417
|
+
subscribe<Key extends keyof Store>(
|
|
418
|
+
key: Key,
|
|
419
|
+
callback: (value: Store[Key] | undefined) => void,
|
|
420
|
+
): Unsubscribe;
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Subscribe to changes for a specific key
|
|
424
|
+
*
|
|
425
|
+
* @param key Key of the value to subscribe to
|
|
426
|
+
* @param callback Callback for changes
|
|
427
|
+
* @returns Unsubscribe callback
|
|
428
|
+
*/
|
|
429
|
+
subscribe(key: Key, callback: (value: unknown) => void): Unsubscribe;
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Unsubscribe from changes for a specific key
|
|
433
|
+
*
|
|
434
|
+
* @param key Key of the value to unsubscribe from
|
|
435
|
+
* @param callback Callback to unsubscribe
|
|
436
|
+
*/
|
|
437
|
+
unsubscribe<Key extends keyof Store>(
|
|
438
|
+
key: Key,
|
|
439
|
+
callback: (value: Store[Key] | undefined) => void,
|
|
440
|
+
): void;
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Unsubscribe from changes for a specific key
|
|
444
|
+
*
|
|
445
|
+
* @param key Key of the value to unsubscribe from
|
|
446
|
+
* @param callback Callback to unsubscribe
|
|
447
|
+
*/
|
|
448
|
+
unsubscribe(key: Key, callback: (value: unknown | undefined) => void): void;
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Unsubscribe from changes
|
|
452
|
+
*
|
|
453
|
+
* @param callback Callback to unsubscribe
|
|
454
|
+
*/
|
|
455
|
+
unsubscribe(callback: (value: Store) => void): void;
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Update the value _(based on the current value)_
|
|
459
|
+
*
|
|
460
|
+
* @param callback Callback to update the value
|
|
461
|
+
*/
|
|
462
|
+
update(callback: (value: Store) => Store): void;
|
|
463
|
+
} & Reactive<Store>;
|
|
464
|
+
|
|
465
|
+
export type ReadonlyInstances<Value> = {
|
|
466
|
+
frozen?: ReadonlyFrozenSignal<Value>;
|
|
467
|
+
original?: ReadonlySignal<Value>;
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
export type ReadonlyFrozenSignal<Value> = ReadonlySignal<ReadonlySignalValue<Value>>;
|
|
471
|
+
|
|
472
|
+
export type ReadonlySignal<Value> = {
|
|
473
|
+
/**
|
|
474
|
+
* Is the signal frozen?
|
|
475
|
+
*/
|
|
476
|
+
get frozen(): boolean;
|
|
477
|
+
} & Reactive<Value> &
|
|
478
|
+
SimpleReactive<Value>;
|
|
479
|
+
|
|
480
|
+
export type ReadonlySignalValue<Value> = Value extends unknown[]
|
|
481
|
+
? Readonly<Value>
|
|
482
|
+
: Value extends PlainObject
|
|
483
|
+
? Readonly<Value>
|
|
484
|
+
: Value;
|
|
485
|
+
|
|
56
486
|
export type SetValueInProxyParameters<Value, Equal> = {
|
|
57
487
|
target: Value;
|
|
58
488
|
property: PropertyKey;
|
|
@@ -62,6 +492,79 @@ export type SetValueInProxyParameters<Value, Equal> = {
|
|
|
62
492
|
length?: Signal<number>;
|
|
63
493
|
};
|
|
64
494
|
|
|
495
|
+
export type Signal<Value> = {
|
|
496
|
+
/**
|
|
497
|
+
* Get a readonly version of the signal
|
|
498
|
+
*
|
|
499
|
+
* @param frozen Freeze the signal? _(defaults to `false`)_
|
|
500
|
+
* @returns Readonly signal
|
|
501
|
+
*/
|
|
502
|
+
asReadonly(frozen: true): ReadonlyFrozenSignal<Value>;
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Get a readonly version of the signal
|
|
506
|
+
*
|
|
507
|
+
* @param frozen Freeze the signal? _(defaults to `false`)_
|
|
508
|
+
* @returns Readonly signal
|
|
509
|
+
*/
|
|
510
|
+
asReadonly(
|
|
511
|
+
frozen?: boolean,
|
|
512
|
+
): typeof frozen extends true ? ReadonlyFrozenSignal<Value> : ReadonlySignal<Value>;
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Set the value
|
|
516
|
+
*
|
|
517
|
+
* @param value New value
|
|
518
|
+
*/
|
|
519
|
+
set(value: Value | (() => Value | Promise<Value>) | Promise<Value>): void;
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Update the value _(based on the current value)_
|
|
523
|
+
*
|
|
524
|
+
* @param callback Callback to update the value
|
|
525
|
+
*/
|
|
526
|
+
update(callback: (value: Value) => Value): void;
|
|
527
|
+
} & Reactive<Value> &
|
|
528
|
+
SimpleReactive<Value>;
|
|
529
|
+
|
|
530
|
+
type SimpleReactive<Value> = {
|
|
531
|
+
/**
|
|
532
|
+
* Get the value
|
|
533
|
+
*
|
|
534
|
+
* @returns Current value
|
|
535
|
+
*/
|
|
536
|
+
get(): Value;
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Get the value _(without reactivity)_
|
|
540
|
+
*
|
|
541
|
+
* @returns Current value
|
|
542
|
+
*/
|
|
543
|
+
peek(): Value;
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Subscribe to changes
|
|
547
|
+
*
|
|
548
|
+
* @param callback Callback for changes
|
|
549
|
+
* @returns Unsubscribe callback
|
|
550
|
+
*/
|
|
551
|
+
subscribe(callback: (value: Value) => void): Unsubscribe;
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Unsubscribe from changes
|
|
555
|
+
*
|
|
556
|
+
* @param callback Callback to unsubscribe
|
|
557
|
+
*/
|
|
558
|
+
unsubscribe(callback: (value: Value) => void): void;
|
|
559
|
+
};
|
|
560
|
+
|
|
561
|
+
export type Subscription = {
|
|
562
|
+
callback: GenericCallback;
|
|
563
|
+
state: ReactiveState<unknown, never>;
|
|
564
|
+
|
|
565
|
+
destroy(): void;
|
|
566
|
+
};
|
|
567
|
+
|
|
65
568
|
/**
|
|
66
569
|
* Unsubscribe from changes
|
|
67
570
|
*/
|
package/src/subscription.ts
CHANGED
|
@@ -1,22 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {ReactiveState, Unsubscribe} from './models';
|
|
3
|
-
|
|
4
|
-
export class Subscription {
|
|
5
|
-
callback: GenericCallback;
|
|
6
|
-
state: ReactiveState<unknown, never>;
|
|
7
|
-
|
|
8
|
-
constructor(state: ReactiveState<unknown, never>, callback: GenericCallback) {
|
|
9
|
-
this.state = state;
|
|
10
|
-
this.callback = callback;
|
|
11
|
-
|
|
12
|
-
callback(state.value);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
destroy(): void {
|
|
16
|
-
this.callback = noop;
|
|
17
|
-
this.state = undefined as never;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
1
|
+
import type {ReactiveState, Subscription, Unsubscribe} from './models';
|
|
20
2
|
|
|
21
3
|
export function noop(): void {}
|
|
22
4
|
|
|
@@ -28,13 +10,31 @@ export function subscribe<Value>(
|
|
|
28
10
|
return noop;
|
|
29
11
|
}
|
|
30
12
|
|
|
31
|
-
state.subscriptions.set(callback,
|
|
13
|
+
state.subscriptions.set(callback, subscription(state, callback));
|
|
32
14
|
|
|
33
15
|
return () => {
|
|
34
16
|
unsubscribe(state, callback);
|
|
35
17
|
};
|
|
36
18
|
}
|
|
37
19
|
|
|
20
|
+
function subscription<Value>(
|
|
21
|
+
state: ReactiveState<Value, never>,
|
|
22
|
+
callback: (value: Value) => void,
|
|
23
|
+
): Subscription {
|
|
24
|
+
const instance: Subscription = {
|
|
25
|
+
callback,
|
|
26
|
+
state,
|
|
27
|
+
destroy: () => {
|
|
28
|
+
instance.callback = noop;
|
|
29
|
+
instance.state = undefined as never;
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
callback(state.value);
|
|
34
|
+
|
|
35
|
+
return instance;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
38
|
export function unsubscribe<Value>(
|
|
39
39
|
state: ReactiveState<Value, never>,
|
|
40
40
|
callback: (value: Value) => void,
|