@oscarpalmer/mora 0.27.0 → 0.29.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/constants.d.mts +19 -1
- package/dist/effect.d.mts +26 -1
- package/dist/helpers/is.d.mts +4 -2
- package/dist/helpers/proxy.d.mts +3 -2
- package/dist/helpers/proxy.mjs +36 -14
- package/dist/helpers/value.d.mts +1 -1
- package/dist/helpers/value.mjs +2 -1
- package/dist/index.d.mts +5 -2
- package/dist/models.d.mts +61 -1
- package/dist/mora.full.mjs +187 -84
- package/dist/subscription.d.mts +14 -1
- package/dist/value/array.d.mts +20 -4
- package/dist/value/array.mjs +19 -16
- package/dist/value/computed.d.mts +20 -1
- package/dist/value/computed.mjs +32 -11
- package/dist/value/reactive.d.mts +50 -1
- package/dist/value/reactive.mjs +5 -0
- package/dist/value/signal.d.mts +43 -1
- package/dist/value/signal.mjs +27 -11
- package/dist/value/store.d.mts +18 -3
- package/dist/value/store.mjs +31 -11
- package/package.json +6 -5
- package/src/effect.ts +10 -0
- package/src/helpers/proxy.ts +64 -17
- package/src/helpers/value.ts +2 -1
- package/src/models.ts +3 -1
- package/src/value/array.ts +74 -18
- package/src/value/computed.ts +65 -30
- package/src/value/reactive.ts +13 -0
- package/src/value/signal.ts +77 -9
- package/src/value/store.ts +100 -11
- 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/constants-Cy6_M9Vk.d.mts +0 -20
- package/dist/effect-BkupB1p9.d.mts +0 -17
- package/dist/models-QwNga87R.d.mts +0 -148
package/src/value/array.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type {GenericCallback} from '@oscarpalmer/atoms/models';
|
|
2
2
|
import {METHODS_AFFECTING_LENGTH, METHODS_UPDATE, NAME_ARRAY, PROPERTY_LENGTH} from '../constants';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
emityProxyValues,
|
|
5
|
+
getReactiveValueInProxy,
|
|
6
|
+
setProxyValue,
|
|
7
|
+
setValueInProxy,
|
|
8
|
+
} from '../helpers/proxy';
|
|
4
9
|
import {emitValue, equalArrays, getValue} from '../helpers/value';
|
|
5
10
|
import type {ReactiveOptions, ReactiveState, Unsubscribe} from '../models';
|
|
6
11
|
import {noop, subscribe} from '../subscription';
|
|
@@ -137,7 +142,7 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
|
|
|
137
142
|
return this.#size.peek();
|
|
138
143
|
}
|
|
139
144
|
|
|
140
|
-
return typeof value === 'number' ? this.state.value.at(value) :
|
|
145
|
+
return typeof value === 'number' ? this.state.value.at(value) : this.state.value.slice();
|
|
141
146
|
}
|
|
142
147
|
|
|
143
148
|
/**
|
|
@@ -161,14 +166,19 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
|
|
|
161
166
|
* Set the value
|
|
162
167
|
* @param value New array of items _(defaults to an empty array)_
|
|
163
168
|
*/
|
|
164
|
-
set(
|
|
169
|
+
set(
|
|
170
|
+
value?:
|
|
171
|
+
| Item[]
|
|
172
|
+
| (() => null | undefined | Item[] | Promise<null | undefined | Item[]>)
|
|
173
|
+
| Promise<null | undefined | Item[]>,
|
|
174
|
+
): void;
|
|
165
175
|
|
|
166
176
|
/**
|
|
167
177
|
* Set the value at an index
|
|
168
178
|
* @param index Index of item to set __(if negative, starts from the end)_
|
|
169
179
|
* @param value New item
|
|
170
180
|
*/
|
|
171
|
-
set(index: number, value: Item): void;
|
|
181
|
+
set(index: number, value: Item | (() => Item | Promise<Item>) | Promise<Item>): void;
|
|
172
182
|
|
|
173
183
|
/**
|
|
174
184
|
* Set the length of the array
|
|
@@ -176,14 +186,17 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
|
|
|
176
186
|
*/
|
|
177
187
|
set(property: typeof PROPERTY_LENGTH, value: number): void;
|
|
178
188
|
|
|
179
|
-
set(first?:
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
189
|
+
set(first?: unknown, second?: unknown): void {
|
|
190
|
+
setProxyValue<Item[], Item>(
|
|
191
|
+
true,
|
|
192
|
+
this.state,
|
|
193
|
+
isArrayValue,
|
|
194
|
+
isArrayIndex,
|
|
195
|
+
setArray,
|
|
196
|
+
setAtIndex,
|
|
197
|
+
first,
|
|
198
|
+
second,
|
|
199
|
+
);
|
|
187
200
|
}
|
|
188
201
|
|
|
189
202
|
/**
|
|
@@ -248,14 +261,53 @@ export class ReactiveArray<Item> extends Reactive<Item[], Item> {
|
|
|
248
261
|
}
|
|
249
262
|
}
|
|
250
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Create a reactive array from a function result
|
|
266
|
+
* @param value Initial array of items
|
|
267
|
+
* @param options Reactivity options
|
|
268
|
+
* @returns Reactive array
|
|
269
|
+
*/
|
|
270
|
+
export function array<Item>(
|
|
271
|
+
value: () => Item[] | Promise<Item[]>,
|
|
272
|
+
options?: ReactiveOptions<Item>,
|
|
273
|
+
): ReactiveArray<Item>;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Create a reactive array from a promise
|
|
277
|
+
* @param value Initial array of items
|
|
278
|
+
* @param options Reactivity options
|
|
279
|
+
* @returns Reactive array
|
|
280
|
+
*/
|
|
281
|
+
export function array<Item>(
|
|
282
|
+
value: Promise<Item[]>,
|
|
283
|
+
options?: ReactiveOptions<Item>,
|
|
284
|
+
): ReactiveArray<Item>;
|
|
285
|
+
|
|
251
286
|
/**
|
|
252
287
|
* Create a reactive array
|
|
253
288
|
* @param value Initial array of items
|
|
254
289
|
* @param options Reactivity options
|
|
255
290
|
* @returns Reactive array
|
|
256
291
|
*/
|
|
257
|
-
export function array<Item>(value: Item[], options?: ReactiveOptions<Item>): ReactiveArray<Item
|
|
258
|
-
|
|
292
|
+
export function array<Item>(value: Item[], options?: ReactiveOptions<Item>): ReactiveArray<Item>;
|
|
293
|
+
|
|
294
|
+
export function array<Item>(
|
|
295
|
+
value: Item[] | (() => Item[] | Promise<Item[]>) | Promise<Item[]>,
|
|
296
|
+
options?: ReactiveOptions<Item>,
|
|
297
|
+
): ReactiveArray<Item> {
|
|
298
|
+
const instance = new ReactiveArray([], options);
|
|
299
|
+
|
|
300
|
+
instance.set(value);
|
|
301
|
+
|
|
302
|
+
return instance;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function isArrayIndex(value: unknown): boolean {
|
|
306
|
+
return typeof value === 'number';
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function isArrayValue<Item>(value: unknown): value is Item[] | undefined {
|
|
310
|
+
return value == null || Array.isArray(value);
|
|
259
311
|
}
|
|
260
312
|
|
|
261
313
|
function updateArray<Item>(
|
|
@@ -265,7 +317,7 @@ function updateArray<Item>(
|
|
|
265
317
|
length: Signal<number>,
|
|
266
318
|
): unknown {
|
|
267
319
|
const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
|
|
268
|
-
const previousArray = affectsLength ? [] :
|
|
320
|
+
const previousArray = affectsLength ? [] : array.slice();
|
|
269
321
|
const previousLength = array.length;
|
|
270
322
|
|
|
271
323
|
return (...args: unknown[]): unknown => {
|
|
@@ -283,10 +335,14 @@ function updateArray<Item>(
|
|
|
283
335
|
};
|
|
284
336
|
}
|
|
285
337
|
|
|
286
|
-
function
|
|
287
|
-
|
|
338
|
+
function setArray<Item>(state: ReactiveState<Item[], Item>, value: Item[] | undefined): void {
|
|
339
|
+
state.value.splice(0, state.value.length, ...(value ?? []));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function setAtIndex<Item>(state: ReactiveState<Item[], Item>, index: unknown, value: Item): void {
|
|
343
|
+
const actual = (index as number) < 0 ? state.value.length + (index as number) : (index as number);
|
|
288
344
|
|
|
289
345
|
if (actual > -1) {
|
|
290
|
-
|
|
346
|
+
state.value[actual] = value;
|
|
291
347
|
}
|
|
292
348
|
}
|
package/src/value/computed.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import {flushHandlers} from '../batch';
|
|
1
2
|
import {ACTIVE, BATCH, NAME_COMPUTED} from '../constants';
|
|
2
3
|
import {effect, runEffect} from '../effect';
|
|
3
|
-
import type {ComputedEffect, ReactiveOptions} from '../models';
|
|
4
|
+
import type {ComputedEffect, InternalComputed, ReactiveOptions, ReactiveState} from '../models';
|
|
4
5
|
import {Reactive} from './reactive';
|
|
5
6
|
|
|
6
7
|
export class Computed<Value> extends Reactive<Value> {
|
|
@@ -9,39 +10,15 @@ export class Computed<Value> extends Reactive<Value> {
|
|
|
9
10
|
instance: undefined as never,
|
|
10
11
|
};
|
|
11
12
|
|
|
12
|
-
constructor(callback: () => Value
|
|
13
|
+
constructor(callback: () => Value | Promise<Value>, options?: ReactiveOptions<Value>) {
|
|
13
14
|
super(NAME_COMPUTED, undefined as never, options);
|
|
14
15
|
|
|
15
16
|
this.effect.instance = effect(() => {
|
|
16
|
-
if (
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const previousComputed = ACTIVE.computed;
|
|
21
|
-
|
|
22
|
-
ACTIVE.computed = this as never;
|
|
23
|
-
|
|
24
|
-
const value = callback();
|
|
25
|
-
|
|
26
|
-
ACTIVE.computed = previousComputed;
|
|
27
|
-
|
|
28
|
-
if (!this.state.equal(this.state.value, value)) {
|
|
29
|
-
this.state.value = value;
|
|
17
|
+
if (this.effect.dirty) {
|
|
18
|
+
setValue(this, this.state, callback);
|
|
30
19
|
|
|
31
|
-
|
|
32
|
-
computed.effect.dirty = true;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
for (const effect of this.state.effects) {
|
|
36
|
-
BATCH.handlers.add(effect);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
for (const [, subscription] of this.state.subscriptions) {
|
|
40
|
-
subscription.callback(value);
|
|
41
|
-
}
|
|
20
|
+
this.effect.dirty = false;
|
|
42
21
|
}
|
|
43
|
-
|
|
44
|
-
this.effect.dirty = false;
|
|
45
22
|
});
|
|
46
23
|
}
|
|
47
24
|
|
|
@@ -72,8 +49,66 @@ export class Computed<Value> extends Reactive<Value> {
|
|
|
72
49
|
* @returns Computed value
|
|
73
50
|
*/
|
|
74
51
|
export function computed<Value>(
|
|
75
|
-
callback: () => Value
|
|
52
|
+
callback: () => Value | Promise<Value>,
|
|
76
53
|
options?: ReactiveOptions<Value>,
|
|
77
54
|
): Computed<Value> {
|
|
78
55
|
return new Computed(callback, options);
|
|
79
56
|
}
|
|
57
|
+
|
|
58
|
+
function setAndEmit<Value>(state: ReactiveState<Value, Value>, value: Value): void {
|
|
59
|
+
if (state.equal(state.value, value)) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
state.value = value;
|
|
64
|
+
|
|
65
|
+
for (const computed of state.computeds) {
|
|
66
|
+
(computed as unknown as InternalComputed).effect.dirty = true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for (const effect of state.effects) {
|
|
70
|
+
BATCH.handlers.add(effect);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
for (const [, subscription] of state.subscriptions) {
|
|
74
|
+
subscription.callback(value);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
flushHandlers();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function setValue<Value>(
|
|
81
|
+
instance: Computed<Value>,
|
|
82
|
+
state: ReactiveState<Value, Value>,
|
|
83
|
+
callback: () => Value | Promise<Value>,
|
|
84
|
+
): void {
|
|
85
|
+
const previousComputed = ACTIVE.computed;
|
|
86
|
+
|
|
87
|
+
ACTIVE.computed = instance as never;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const value = callback();
|
|
91
|
+
|
|
92
|
+
if (value instanceof Promise) {
|
|
93
|
+
state.promise = value;
|
|
94
|
+
|
|
95
|
+
value
|
|
96
|
+
.then(resolvedValue => {
|
|
97
|
+
if (state.promise === value) {
|
|
98
|
+
state.promise = undefined;
|
|
99
|
+
|
|
100
|
+
setAndEmit(state, resolvedValue);
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
.catch(() => {
|
|
104
|
+
if (state.promise === value) {
|
|
105
|
+
state.promise = undefined;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
} else {
|
|
109
|
+
setAndEmit(state, value);
|
|
110
|
+
}
|
|
111
|
+
} finally {
|
|
112
|
+
ACTIVE.computed = previousComputed;
|
|
113
|
+
}
|
|
114
|
+
}
|
package/src/value/reactive.ts
CHANGED
|
@@ -3,6 +3,18 @@ import type {ReactiveOptions, ReactiveState, Unsubscribe} from '../models';
|
|
|
3
3
|
import {subscribe, unsubscribe} from '../subscription';
|
|
4
4
|
|
|
5
5
|
export abstract class Reactive<Value, Equal = Value> {
|
|
6
|
+
/**
|
|
7
|
+
* Internal name of the reactive value
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
declare protected readonly $mora: string;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Internal state of the reactive value
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
6
18
|
protected readonly state: ReactiveState<Value, Equal> = {
|
|
7
19
|
computeds: new Set(),
|
|
8
20
|
effects: new Set(),
|
|
@@ -59,6 +71,7 @@ export abstract class Reactive<Value, Equal = Value> {
|
|
|
59
71
|
* @return Value as string
|
|
60
72
|
*/
|
|
61
73
|
toString(): string {
|
|
74
|
+
// oxlint-disable-next-line @oscarpalmer/atoms/string.getString: base toString is expected; allow custom toString in options?
|
|
62
75
|
return String(this.get());
|
|
63
76
|
}
|
|
64
77
|
|
package/src/value/signal.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {NAME_SIGNAL} from '../constants';
|
|
2
2
|
import {emitValue, getValue} from '../helpers/value';
|
|
3
|
-
import type {ReactiveOptions} from '../models';
|
|
3
|
+
import type {ReactiveOptions, ReactiveState} from '../models';
|
|
4
4
|
import {Reactive} from './reactive';
|
|
5
5
|
|
|
6
6
|
export class Signal<Value> extends Reactive<Value> {
|
|
@@ -19,12 +19,8 @@ export class Signal<Value> extends Reactive<Value> {
|
|
|
19
19
|
* Set the value
|
|
20
20
|
* @param value New value
|
|
21
21
|
*/
|
|
22
|
-
set(value: Value): void {
|
|
23
|
-
|
|
24
|
-
this.state.value = value;
|
|
25
|
-
|
|
26
|
-
emitValue(this.state);
|
|
27
|
-
}
|
|
22
|
+
set(value: Value | (() => Value | Promise<Value>) | Promise<Value>): void {
|
|
23
|
+
setValue<Value>(this.state, value);
|
|
28
24
|
}
|
|
29
25
|
|
|
30
26
|
/**
|
|
@@ -36,12 +32,84 @@ export class Signal<Value> extends Reactive<Value> {
|
|
|
36
32
|
}
|
|
37
33
|
}
|
|
38
34
|
|
|
35
|
+
function setAndEmit<Value>(state: ReactiveState<Value, Value>, value: Value): void {
|
|
36
|
+
if (!state.equal(state.value, value)) {
|
|
37
|
+
state.value = value;
|
|
38
|
+
|
|
39
|
+
emitValue(state);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function setValue<Value>(
|
|
44
|
+
state: ReactiveState<Value, Value>,
|
|
45
|
+
value: Value | (() => Value | Promise<Value>) | Promise<Value>,
|
|
46
|
+
): void {
|
|
47
|
+
try {
|
|
48
|
+
let actual = value;
|
|
49
|
+
|
|
50
|
+
if (typeof value === 'function') {
|
|
51
|
+
actual = (value as () => Value | Promise<Value>)() as Value | Promise<Value>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (actual instanceof Promise) {
|
|
55
|
+
state.promise = actual;
|
|
56
|
+
|
|
57
|
+
void actual
|
|
58
|
+
.then(value => {
|
|
59
|
+
if (actual === state.promise) {
|
|
60
|
+
state.promise = undefined;
|
|
61
|
+
|
|
62
|
+
setAndEmit(state, value);
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
.catch(() => {
|
|
66
|
+
if (actual === state.promise) {
|
|
67
|
+
state.promise = undefined;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
} else {
|
|
71
|
+
setAndEmit(state, actual as Value);
|
|
72
|
+
}
|
|
73
|
+
} catch {}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Create a reactive value from a function result
|
|
78
|
+
* @param value Initial value
|
|
79
|
+
* @param options Reactivity options
|
|
80
|
+
* @returns Reactive value
|
|
81
|
+
*/
|
|
82
|
+
export function signal<Value>(
|
|
83
|
+
value: () => Value | Promise<Value>,
|
|
84
|
+
options?: ReactiveOptions<Value>,
|
|
85
|
+
): Signal<Value>;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Create a reactive value from a promise
|
|
89
|
+
* @param value Initial value
|
|
90
|
+
* @param options Reactivity options
|
|
91
|
+
* @returns Reactive value
|
|
92
|
+
*/
|
|
93
|
+
export function signal<Value>(
|
|
94
|
+
value: Promise<Value>,
|
|
95
|
+
options?: ReactiveOptions<Value>,
|
|
96
|
+
): Signal<Value>;
|
|
97
|
+
|
|
39
98
|
/**
|
|
40
99
|
* Create a reactive value
|
|
41
100
|
* @param value Initial value
|
|
42
101
|
* @param options Reactivity options
|
|
43
102
|
* @returns Reactive value
|
|
44
103
|
*/
|
|
45
|
-
export function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value
|
|
46
|
-
|
|
104
|
+
export function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value>;
|
|
105
|
+
|
|
106
|
+
export function signal<Value>(
|
|
107
|
+
value: Value | (() => Value | Promise<Value>) | Promise<Value>,
|
|
108
|
+
options?: ReactiveOptions<Value>,
|
|
109
|
+
): Signal<Value> {
|
|
110
|
+
const instance = new Signal<Value>(undefined as unknown as Value, options);
|
|
111
|
+
|
|
112
|
+
instance.set(value);
|
|
113
|
+
|
|
114
|
+
return instance;
|
|
47
115
|
}
|
package/src/value/store.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {isKey, isPlainObject} from '@oscarpalmer/atoms/is';
|
|
2
2
|
import type {GenericCallback, Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
3
|
+
import {startBatch, stopBatch} from '../batch';
|
|
3
4
|
import {NAME_STORE} from '../constants';
|
|
4
5
|
import {
|
|
5
6
|
emityProxyValues,
|
|
@@ -8,7 +9,7 @@ import {
|
|
|
8
9
|
setValueInProxy,
|
|
9
10
|
} from '../helpers/proxy';
|
|
10
11
|
import {getValue} from '../helpers/value';
|
|
11
|
-
import type {ReactiveOptions, Unsubscribe} from '../models';
|
|
12
|
+
import type {ReactiveOptions, ReactiveState, Unsubscribe} from '../models';
|
|
12
13
|
import {noop, subscribe} from '../subscription';
|
|
13
14
|
import type {Computed} from './computed';
|
|
14
15
|
import {Reactive} from './reactive';
|
|
@@ -96,14 +97,22 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
|
|
|
96
97
|
* Set the value
|
|
97
98
|
* @param value New value _(defaults to an empty object)_
|
|
98
99
|
*/
|
|
99
|
-
set(
|
|
100
|
+
set(
|
|
101
|
+
value?:
|
|
102
|
+
| Value
|
|
103
|
+
| (() => null | undefined | Value | Promise<null | undefined | Value>)
|
|
104
|
+
| Promise<null | undefined | Value>,
|
|
105
|
+
): void;
|
|
100
106
|
|
|
101
107
|
/**
|
|
102
108
|
* Set a value by key
|
|
103
109
|
* @param key Key of the value to set
|
|
104
110
|
* @param value New value
|
|
105
111
|
*/
|
|
106
|
-
set<Key extends keyof Value>(
|
|
112
|
+
set<Key extends keyof Value>(
|
|
113
|
+
key: Key,
|
|
114
|
+
value: Value[Key] | (() => Value[Key] | Promise<Value[Key]>) | Promise<Value[Key]>,
|
|
115
|
+
): void;
|
|
107
116
|
|
|
108
117
|
/**
|
|
109
118
|
* Set a value by key
|
|
@@ -113,11 +122,16 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
|
|
|
113
122
|
set(key: Key, value: unknown): void;
|
|
114
123
|
|
|
115
124
|
set(first?: unknown, second?: unknown): void {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
125
|
+
setProxyValue<Value>(
|
|
126
|
+
false,
|
|
127
|
+
this.state,
|
|
128
|
+
isStoreObject,
|
|
129
|
+
isKey,
|
|
130
|
+
setObject,
|
|
131
|
+
setProperty,
|
|
132
|
+
first,
|
|
133
|
+
second,
|
|
134
|
+
);
|
|
121
135
|
}
|
|
122
136
|
|
|
123
137
|
/**
|
|
@@ -157,14 +171,80 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
|
|
|
157
171
|
* @param callback Callback to update the value
|
|
158
172
|
*/
|
|
159
173
|
update(callback: (value: Value) => Value): void {
|
|
160
|
-
const updated = callback(
|
|
174
|
+
const updated = callback(this.state.value);
|
|
161
175
|
|
|
162
176
|
if (updated == null || isPlainObject(updated)) {
|
|
163
|
-
|
|
177
|
+
setObject(this.state, updated);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function isStoreObject<Value extends PlainObject>(value: unknown): value is Value | undefined {
|
|
183
|
+
return value == null || isPlainObject(value);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function setObject(state: ReactiveState<PlainObject, never>, value: PlainObject | undefined): void {
|
|
187
|
+
startBatch();
|
|
188
|
+
|
|
189
|
+
const actual = value ?? {};
|
|
190
|
+
const proxy = state.value as PlainObject;
|
|
191
|
+
|
|
192
|
+
const proxyKeys = Object.keys(proxy);
|
|
193
|
+
const actualKeys = Object.keys(actual);
|
|
194
|
+
|
|
195
|
+
let {length} = proxyKeys;
|
|
196
|
+
|
|
197
|
+
for (let index = 0; index < length; index += 1) {
|
|
198
|
+
const key = proxyKeys[index];
|
|
199
|
+
|
|
200
|
+
proxy[key] = actualKeys.includes(key) ? actual[key] : undefined;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
length = actualKeys.length;
|
|
204
|
+
|
|
205
|
+
for (let index = 0; index < length; index += 1) {
|
|
206
|
+
const key = actualKeys[index];
|
|
207
|
+
|
|
208
|
+
if (!proxyKeys.includes(key)) {
|
|
209
|
+
const keyedValue = actual[key];
|
|
210
|
+
|
|
211
|
+
proxy[key] = keyedValue;
|
|
164
212
|
}
|
|
165
213
|
}
|
|
214
|
+
|
|
215
|
+
stopBatch();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function setProperty<Value extends PlainObject>(
|
|
219
|
+
state: ReactiveState<Value, Value>,
|
|
220
|
+
key: unknown,
|
|
221
|
+
value: unknown,
|
|
222
|
+
): void {
|
|
223
|
+
(state.value as PlainObject)[key as Key] = value;
|
|
166
224
|
}
|
|
167
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Create a reactive store from a function result
|
|
228
|
+
* @param value Initial object value
|
|
229
|
+
* @param options Reactivity options
|
|
230
|
+
* @returns Reactive store
|
|
231
|
+
*/
|
|
232
|
+
export function store<Value extends PlainObject>(
|
|
233
|
+
value: () => Value | Promise<Value>,
|
|
234
|
+
options?: ReactiveOptions<Value>,
|
|
235
|
+
): Store<Value>;
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Create a reactive store from a promise
|
|
239
|
+
* @param value Initial object value
|
|
240
|
+
* @param options Reactivity options
|
|
241
|
+
* @returns Reactive store
|
|
242
|
+
*/
|
|
243
|
+
export function store<Value extends PlainObject>(
|
|
244
|
+
value: Promise<Value>,
|
|
245
|
+
options?: ReactiveOptions<Value>,
|
|
246
|
+
): Store<Value>;
|
|
247
|
+
|
|
168
248
|
/**
|
|
169
249
|
* Create a reactive store
|
|
170
250
|
* @param value Initial object value
|
|
@@ -174,6 +254,15 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
|
|
|
174
254
|
export function store<Value extends PlainObject>(
|
|
175
255
|
value: Value,
|
|
176
256
|
options?: ReactiveOptions<Value>,
|
|
257
|
+
): Store<Value>;
|
|
258
|
+
|
|
259
|
+
export function store<Value extends PlainObject>(
|
|
260
|
+
value: Value | (() => Value | Promise<Value>) | Promise<Value>,
|
|
261
|
+
options?: ReactiveOptions<Value>,
|
|
177
262
|
): Store<Value> {
|
|
178
|
-
|
|
263
|
+
const instance = new Store({} as unknown as Value, options);
|
|
264
|
+
|
|
265
|
+
instance.set(value);
|
|
266
|
+
|
|
267
|
+
return instance;
|
|
179
268
|
}
|
package/types/constants.d.ts
CHANGED
|
@@ -12,5 +12,5 @@ export declare const NAME_EFFECT = "effect";
|
|
|
12
12
|
export declare const NAME_MORA = "$mora";
|
|
13
13
|
export declare const NAME_SIGNAL = "signal";
|
|
14
14
|
export declare const NAME_STORE = "store";
|
|
15
|
-
export declare const
|
|
15
|
+
export declare const NAMES: Set<string>;
|
|
16
16
|
export declare const PROPERTY_LENGTH = "length";
|
package/types/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { startBatch, stopBatch } from './batch';
|
|
2
2
|
export { effect, type Effect } from './effect';
|
|
3
|
-
export { isArray, isComputed, isEffect, isReactive, isSignal } from './helpers/is';
|
|
3
|
+
export { isArray, isComputed, isEffect, isReactive, isSignal, } from './helpers/is';
|
|
4
4
|
export type { Unsubscribe } from './models';
|
|
5
5
|
export { array, type ReactiveArray } from './value/array';
|
|
6
6
|
export { computed, type Computed } from './value/computed';
|
package/types/value/array.d.ts
CHANGED
|
@@ -131,7 +131,7 @@ export declare class ReactiveArray<Item> extends Reactive<Item[], Item> {
|
|
|
131
131
|
/**
|
|
132
132
|
* Create a reactive array
|
|
133
133
|
* @param value Initial array of items
|
|
134
|
-
* @param options
|
|
134
|
+
* @param options Optional reactivity options
|
|
135
135
|
* @returns Reactive array
|
|
136
136
|
*/
|
|
137
137
|
export declare function array<Item>(value: Item[], options?: ReactiveOptions<Item>): ReactiveArray<Item>;
|
|
@@ -10,8 +10,5 @@ export declare class Computed<Value> extends Reactive<Value> {
|
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* Create a computed value
|
|
13
|
-
* @param callback Callback to compute the value
|
|
14
|
-
* @param options Reactivity options
|
|
15
|
-
* @returns Computed value
|
|
16
13
|
*/
|
|
17
14
|
export declare function computed<Value>(callback: () => Value, options?: ReactiveOptions<Value>): Computed<Value>;
|
package/types/value/signal.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export declare class Signal<Value> extends Reactive<Value> {
|
|
|
20
20
|
/**
|
|
21
21
|
* Create a reactive value
|
|
22
22
|
* @param value Initial value
|
|
23
|
-
* @param options
|
|
23
|
+
* @param options Optional reactivity options
|
|
24
24
|
* @returns Reactive value
|
|
25
25
|
*/
|
|
26
26
|
export declare function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value>;
|
package/types/value/store.d.ts
CHANGED
|
@@ -88,7 +88,7 @@ export declare class Store<Value extends PlainObject> extends Reactive<Value, Va
|
|
|
88
88
|
/**
|
|
89
89
|
* Create a reactive store
|
|
90
90
|
* @param value Initial object value
|
|
91
|
-
* @param options
|
|
91
|
+
* @param options Optional reactivity options
|
|
92
92
|
* @returns Reactive store
|
|
93
93
|
*/
|
|
94
94
|
export declare function store<Value extends PlainObject>(value: Value, options?: ReactiveOptions<Value>): Store<Value>;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { n as Batch, t as Active } from "./models-QwNga87R.mjs";
|
|
2
|
-
|
|
3
|
-
//#region src/constants.d.ts
|
|
4
|
-
declare const ACTIVE: Active;
|
|
5
|
-
declare const ARRAY_THRESHOLD = 100;
|
|
6
|
-
declare const ARRAY_OFFSET = 25;
|
|
7
|
-
declare const ARRAY_PEEK = 10;
|
|
8
|
-
declare const BATCH: Batch;
|
|
9
|
-
declare const METHODS_AFFECTING_LENGTH: Set<string>;
|
|
10
|
-
declare const METHODS_UPDATE: Set<string>;
|
|
11
|
-
declare const NAME_ARRAY = "array";
|
|
12
|
-
declare const NAME_COMPUTED = "computed";
|
|
13
|
-
declare const NAME_EFFECT = "effect";
|
|
14
|
-
declare const NAME_MORA = "$mora";
|
|
15
|
-
declare const NAME_SIGNAL = "signal";
|
|
16
|
-
declare const NAME_STORE = "store";
|
|
17
|
-
declare const NAME_ALL: Set<string>;
|
|
18
|
-
declare const PROPERTY_LENGTH = "length";
|
|
19
|
-
//#endregion
|
|
20
|
-
export { BATCH as a, NAME_ALL as c, NAME_EFFECT as d, NAME_MORA as f, PROPERTY_LENGTH as h, ARRAY_THRESHOLD as i, NAME_ARRAY as l, NAME_STORE as m, ARRAY_OFFSET as n, METHODS_AFFECTING_LENGTH as o, NAME_SIGNAL as p, ARRAY_PEEK as r, METHODS_UPDATE as s, ACTIVE as t, NAME_COMPUTED as u };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { GenericCallback } from "@oscarpalmer/atoms/models";
|
|
2
|
-
|
|
3
|
-
//#region src/effect.d.ts
|
|
4
|
-
declare class Effect {
|
|
5
|
-
private readonly $mora;
|
|
6
|
-
private readonly state;
|
|
7
|
-
constructor(callback: GenericCallback);
|
|
8
|
-
}
|
|
9
|
-
declare function runEffect(effect: Effect): void;
|
|
10
|
-
/**
|
|
11
|
-
* Create an effect
|
|
12
|
-
* @param callback Callback for handling signal effects
|
|
13
|
-
* @returns Effect
|
|
14
|
-
*/
|
|
15
|
-
declare function effect(callback: GenericCallback): Effect;
|
|
16
|
-
//#endregion
|
|
17
|
-
export { effect as n, runEffect as r, Effect as t };
|