@oscarpalmer/mora 0.33.0 → 0.35.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 +2 -2
- package/dist/helpers/proxy.d.mts +8 -8
- package/dist/helpers/proxy.mjs +32 -25
- package/dist/helpers/subscription.d.mts +3 -3
- package/dist/helpers/value.d.mts +9 -8
- package/dist/helpers/value.mjs +15 -11
- package/dist/index.d.mts +2 -2
- package/dist/models.d.mts +40 -37
- package/dist/mora.full.mjs +195 -167
- package/dist/value/array.mjs +53 -41
- package/dist/value/computed.d.mts +2 -2
- package/dist/value/computed.mjs +3 -5
- package/dist/value/readonly.d.mts +2 -2
- package/dist/value/readonly.mjs +16 -19
- package/dist/value/signal.mjs +13 -13
- package/dist/value/store.mjs +4 -6
- package/package.json +2 -2
- package/src/batch.ts +2 -2
- package/src/constants.ts +7 -2
- package/src/helpers/is.ts +1 -3
- package/src/helpers/proxy.ts +68 -57
- package/src/helpers/subscription.ts +7 -6
- package/src/helpers/value.ts +30 -20
- package/src/index.ts +1 -0
- package/src/models.ts +47 -43
- package/src/value/array.ts +81 -64
- package/src/value/computed.ts +12 -16
- package/src/value/readonly.ts +38 -29
- package/src/value/signal.ts +20 -20
- package/src/value/store.ts +4 -7
|
@@ -12,9 +12,10 @@ import {
|
|
|
12
12
|
SYMBOL_STATE,
|
|
13
13
|
} from '../constants';
|
|
14
14
|
import type {
|
|
15
|
-
|
|
15
|
+
InternalArray,
|
|
16
16
|
InternalReadonly,
|
|
17
|
-
|
|
17
|
+
InternalStateful,
|
|
18
|
+
InternalStore,
|
|
18
19
|
Subscriber,
|
|
19
20
|
SubscriptionType,
|
|
20
21
|
} from '../models';
|
|
@@ -24,20 +25,20 @@ import {getFrozenValue, peekSignalValue} from './value';
|
|
|
24
25
|
// #region Functions
|
|
25
26
|
|
|
26
27
|
export function subscribeToProxy(
|
|
27
|
-
this:
|
|
28
|
+
this: InternalArray | InternalStore,
|
|
28
29
|
first: Key | Subscriber<unknown>,
|
|
29
30
|
second?: Subscriber<unknown> | boolean,
|
|
30
31
|
third?: boolean,
|
|
31
32
|
): Subscription {
|
|
32
33
|
if (isKey(first)) {
|
|
33
|
-
return getReactiveValueInProxy(this
|
|
34
|
+
return getReactiveValueInProxy(this, first).subscribe(second as Subscriber<unknown>, third);
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
return subscribeToSignal.call(this, first, second);
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
function subscribeToReactive(
|
|
40
|
-
this:
|
|
41
|
+
this: InternalStateful,
|
|
41
42
|
type: SubscriptionType,
|
|
42
43
|
subscriber: Subscriber<unknown>,
|
|
43
44
|
): Subscription {
|
|
@@ -75,7 +76,7 @@ export function subscribeToReadonly(
|
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
export function subscribeToSignal(
|
|
78
|
-
this:
|
|
79
|
+
this: InternalStateful,
|
|
79
80
|
subscriber: Subscriber<unknown>,
|
|
80
81
|
copy?: unknown,
|
|
81
82
|
): Subscription {
|
package/src/helpers/value.ts
CHANGED
|
@@ -6,16 +6,16 @@ import {
|
|
|
6
6
|
ARRAY_PEEK,
|
|
7
7
|
ARRAY_THRESHOLD,
|
|
8
8
|
BATCH,
|
|
9
|
-
SUBSCRIPTION_TYPES_COPY,
|
|
10
9
|
SUBSCRIPTION_TYPE_FROZEN,
|
|
11
10
|
SUBSCRIPTION_TYPES,
|
|
11
|
+
SUBSCRIPTION_TYPES_COPY,
|
|
12
12
|
SYMBOL_STATE,
|
|
13
13
|
} from '../constants';
|
|
14
|
-
import type {
|
|
14
|
+
import type {InternalStateful} from '../models';
|
|
15
15
|
|
|
16
16
|
// #region Functions
|
|
17
17
|
|
|
18
|
-
export function emitValue(instance:
|
|
18
|
+
export function emitValue(instance: InternalStateful): void {
|
|
19
19
|
const state = instance[SYMBOL_STATE];
|
|
20
20
|
|
|
21
21
|
if (state.computeds != null && state.computeds.size > 0) {
|
|
@@ -51,14 +51,18 @@ export function emitValue(instance: InternalSignal): void {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
export function equalArrays(
|
|
54
|
+
export function equalArrays(
|
|
55
|
+
first: unknown[],
|
|
56
|
+
second: unknown[],
|
|
57
|
+
equal?: (first: unknown, second: unknown) => boolean,
|
|
58
|
+
): boolean {
|
|
55
59
|
const {length} = first;
|
|
56
60
|
|
|
57
61
|
if (length !== second.length) {
|
|
58
62
|
return false;
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
const eq =
|
|
65
|
+
const eq = equal ?? Object.is;
|
|
62
66
|
|
|
63
67
|
let offset = 0;
|
|
64
68
|
|
|
@@ -101,32 +105,38 @@ export function getFrozenValue(value: unknown): unknown {
|
|
|
101
105
|
return frozen;
|
|
102
106
|
}
|
|
103
107
|
|
|
104
|
-
export function
|
|
108
|
+
export function getJsonValue(this: InternalStateful): unknown {
|
|
109
|
+
return this[SYMBOL_STATE].value;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function getSignalValue(this: InternalStateful): unknown {
|
|
113
|
+
const state = this[SYMBOL_STATE];
|
|
114
|
+
|
|
105
115
|
if (ACTIVE.computed != null) {
|
|
106
|
-
|
|
116
|
+
state.computeds ??= new Set();
|
|
107
117
|
|
|
108
|
-
|
|
118
|
+
state.computeds.add(ACTIVE.computed);
|
|
109
119
|
}
|
|
110
120
|
|
|
111
121
|
if (ACTIVE.effect != null) {
|
|
112
|
-
|
|
122
|
+
state.effects ??= new Set();
|
|
113
123
|
|
|
114
|
-
|
|
124
|
+
state.effects.add(ACTIVE.effect);
|
|
115
125
|
}
|
|
116
126
|
|
|
117
|
-
return
|
|
127
|
+
return state.value;
|
|
118
128
|
}
|
|
119
129
|
|
|
120
|
-
export function getStringValue(this:
|
|
130
|
+
export function getStringValue(this: InternalStateful, json?: boolean): string {
|
|
121
131
|
return json === true
|
|
122
132
|
? JSON.stringify(this[SYMBOL_STATE].value)
|
|
123
133
|
: String(this[SYMBOL_STATE].value);
|
|
124
134
|
}
|
|
125
135
|
|
|
126
|
-
export function
|
|
127
|
-
instance:
|
|
136
|
+
export function handleSignal(
|
|
137
|
+
instance: InternalStateful,
|
|
128
138
|
origin: unknown,
|
|
129
|
-
setValue: (instance:
|
|
139
|
+
setValue: (instance: InternalStateful, value: unknown) => void,
|
|
130
140
|
onAfter?: () => void,
|
|
131
141
|
): void {
|
|
132
142
|
const state = instance[SYMBOL_STATE];
|
|
@@ -161,7 +171,7 @@ export function handleSignalValue(
|
|
|
161
171
|
}
|
|
162
172
|
|
|
163
173
|
export function peekSignalValue(
|
|
164
|
-
this:
|
|
174
|
+
this: InternalStateful | [InternalStateful, unknown],
|
|
165
175
|
copy?: boolean,
|
|
166
176
|
): unknown {
|
|
167
177
|
let peeked: unknown = Array.isArray(this) ? this[1] : this[SYMBOL_STATE].value;
|
|
@@ -179,16 +189,16 @@ export function peekSignalValue(
|
|
|
179
189
|
return peeked;
|
|
180
190
|
}
|
|
181
191
|
|
|
182
|
-
export function
|
|
183
|
-
instance:
|
|
192
|
+
export function updateSignal(
|
|
193
|
+
instance: InternalStateful,
|
|
184
194
|
callback: (value: unknown) => unknown,
|
|
185
|
-
setValue: (instance:
|
|
195
|
+
setValue: (instance: InternalStateful, value: unknown) => void,
|
|
186
196
|
): void {
|
|
187
197
|
if (typeof callback !== 'function') {
|
|
188
198
|
throw new TypeError('Callback must be a function');
|
|
189
199
|
}
|
|
190
200
|
|
|
191
|
-
|
|
201
|
+
handleSignal(instance, callback(instance[SYMBOL_STATE].value), setValue);
|
|
192
202
|
}
|
|
193
203
|
|
|
194
204
|
// #endregion
|
package/src/index.ts
CHANGED
package/src/models.ts
CHANGED
|
@@ -15,7 +15,7 @@ export type Batch = {
|
|
|
15
15
|
handlers: Map<EffectState | Subscription, EffectState | StoredSubscription>;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
export type Computed<Value> = Reactive<Value
|
|
18
|
+
export type Computed<Value> = Reactive<Value>;
|
|
19
19
|
|
|
20
20
|
export type ComputedEffect = {
|
|
21
21
|
dirty: boolean;
|
|
@@ -28,23 +28,46 @@ export type EffectState = {
|
|
|
28
28
|
callback: GenericCallback;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
+
export type InternalArray = {
|
|
32
|
+
[SYMBOL_STATE]: ReactiveProxyState;
|
|
33
|
+
} & ReactiveArray<unknown>;
|
|
34
|
+
|
|
31
35
|
export type InternalComputed = {
|
|
32
36
|
[SYMBOL_EFFECT]: ComputedEffect;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
export type InternalProxy = {
|
|
36
|
-
[SYMBOL_STATE]: ReactiveProxyState;
|
|
37
|
-
};
|
|
37
|
+
[SYMBOL_STATE]: SignalState;
|
|
38
|
+
} & Computed<unknown>;
|
|
38
39
|
|
|
39
40
|
export type InternalReadonly = {
|
|
40
41
|
frozen: boolean;
|
|
41
|
-
} &
|
|
42
|
+
} & InternalStateful &
|
|
43
|
+
ReadonlySignal<unknown>;
|
|
42
44
|
|
|
43
|
-
export type InternalSignal =
|
|
45
|
+
export type InternalSignal = InternalStateful & Signal<unknown>;
|
|
46
|
+
|
|
47
|
+
export type InternalStateful = {
|
|
44
48
|
[SYMBOL_STATE]: SignalState;
|
|
45
49
|
};
|
|
46
50
|
|
|
51
|
+
export type InternalStore = {
|
|
52
|
+
[SYMBOL_STATE]: ReactiveProxyState;
|
|
53
|
+
} & ReactiveStore<PlainObject>;
|
|
54
|
+
|
|
47
55
|
export type Reactive<Value> = {
|
|
56
|
+
/**
|
|
57
|
+
* Get the value
|
|
58
|
+
*
|
|
59
|
+
* @returns Current value
|
|
60
|
+
*/
|
|
61
|
+
get(): Value;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get the value _(without reactivity)_
|
|
65
|
+
*
|
|
66
|
+
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
67
|
+
* @returns Current value
|
|
68
|
+
*/
|
|
69
|
+
peek(copy?: boolean): Value;
|
|
70
|
+
|
|
48
71
|
/**
|
|
49
72
|
* _JSON_ representation of the value
|
|
50
73
|
*
|
|
@@ -59,6 +82,15 @@ export type Reactive<Value> = {
|
|
|
59
82
|
* @returns Value as string
|
|
60
83
|
*/
|
|
61
84
|
toString(json?: boolean): string;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Subscribe to changes
|
|
88
|
+
*
|
|
89
|
+
* @param subscriber Callback for changes
|
|
90
|
+
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
91
|
+
* @returns Subscription
|
|
92
|
+
*/
|
|
93
|
+
subscribe(subscriber: Subscriber<Value>, copy?: boolean): Subscription;
|
|
62
94
|
};
|
|
63
95
|
|
|
64
96
|
export type ReactiveArray<Item> = {
|
|
@@ -292,17 +324,17 @@ export type ReactiveOptions<Value> = {
|
|
|
292
324
|
export type ReactiveProxyState = {
|
|
293
325
|
isArray: boolean;
|
|
294
326
|
length?: Signal<number>;
|
|
295
|
-
mapped?: Map<string, [
|
|
327
|
+
mapped?: Map<string, [InternalComputed, ComputedEffect]>;
|
|
296
328
|
} & SignalState;
|
|
297
329
|
|
|
298
|
-
export type ReactiveState = {
|
|
330
|
+
export type ReactiveState<Value = unknown, Item = Value> = {
|
|
299
331
|
computeds?: Set<ComputedEffect>;
|
|
300
332
|
effects?: Set<EffectState>;
|
|
301
|
-
equal?: (first:
|
|
333
|
+
equal?: (first: Item, second: Item) => boolean;
|
|
302
334
|
promise?: Promise<unknown>;
|
|
303
335
|
promises?: Map<Key, Promise<never>>;
|
|
304
336
|
subscriptions?: Subscriptions<GenericCallback>;
|
|
305
|
-
value:
|
|
337
|
+
value: Value;
|
|
306
338
|
};
|
|
307
339
|
|
|
308
340
|
export type ReactiveStore<Store> = {
|
|
@@ -465,8 +497,7 @@ export type ReadonlySignal<Value> = {
|
|
|
465
497
|
* Is the signal frozen?
|
|
466
498
|
*/
|
|
467
499
|
get frozen(): boolean;
|
|
468
|
-
} & Reactive<Value
|
|
469
|
-
SimpleReactive<Value>;
|
|
500
|
+
} & Reactive<Value>;
|
|
470
501
|
|
|
471
502
|
export type ReadonlySignalValue<Value> = Value extends unknown[]
|
|
472
503
|
? Readonly<Value>
|
|
@@ -506,44 +537,17 @@ export type Signal<Value> = {
|
|
|
506
537
|
* @param callback Callback to update the value
|
|
507
538
|
*/
|
|
508
539
|
update(callback: (value: Value) => Value): void;
|
|
509
|
-
} & Reactive<Value
|
|
510
|
-
SimpleReactive<Value>;
|
|
540
|
+
} & Reactive<Value>;
|
|
511
541
|
|
|
512
542
|
export type SignalState = {
|
|
513
543
|
readonlies?: ReadonlyInstances<unknown>;
|
|
514
544
|
} & ReactiveState;
|
|
515
545
|
|
|
516
|
-
type SimpleReactive<Value> = {
|
|
517
|
-
/**
|
|
518
|
-
* Get the value
|
|
519
|
-
*
|
|
520
|
-
* @returns Current value
|
|
521
|
-
*/
|
|
522
|
-
get(): Value;
|
|
523
|
-
|
|
524
|
-
/**
|
|
525
|
-
* Get the value _(without reactivity)_
|
|
526
|
-
*
|
|
527
|
-
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
528
|
-
* @returns Current value
|
|
529
|
-
*/
|
|
530
|
-
peek(copy?: boolean): Value;
|
|
531
|
-
|
|
532
|
-
/**
|
|
533
|
-
* Subscribe to changes
|
|
534
|
-
*
|
|
535
|
-
* @param subscriber Callback for changes
|
|
536
|
-
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
537
|
-
* @returns Subscription
|
|
538
|
-
*/
|
|
539
|
-
subscribe(subscriber: Subscriber<Value>, copy?: boolean): Subscription;
|
|
540
|
-
};
|
|
541
|
-
|
|
542
546
|
export type StoredSubscription = {
|
|
543
547
|
callback: GenericCallback;
|
|
544
548
|
copy: boolean;
|
|
545
549
|
frozen: boolean;
|
|
546
|
-
instance:
|
|
550
|
+
instance: InternalStateful;
|
|
547
551
|
state: SignalState;
|
|
548
552
|
};
|
|
549
553
|
|
package/src/value/array.ts
CHANGED
|
@@ -18,10 +18,10 @@ import {
|
|
|
18
18
|
updateProxyValue,
|
|
19
19
|
} from '../helpers/proxy';
|
|
20
20
|
import {subscribeToProxy} from '../helpers/subscription';
|
|
21
|
-
import {emitValue, equalArrays, getStringValue} from '../helpers/value';
|
|
22
|
-
import type {
|
|
21
|
+
import {emitValue, equalArrays, getJsonValue, getStringValue} from '../helpers/value';
|
|
22
|
+
import type {Computed, InternalArray, ReactiveArray, ReactiveOptions} from '../models';
|
|
23
23
|
import {computed} from './computed';
|
|
24
|
-
import {
|
|
24
|
+
import {getReadonlySignal} from './readonly';
|
|
25
25
|
import {signal} from './signal';
|
|
26
26
|
|
|
27
27
|
// #region Instance
|
|
@@ -35,73 +35,43 @@ function ReactiveArray(this: any, value: unknown, options?: ReactiveOptions<unkn
|
|
|
35
35
|
|
|
36
36
|
this[SYMBOL_STATE].value = new Proxy([], {
|
|
37
37
|
get: (target, property) =>
|
|
38
|
-
METHODS_UPDATE.has(property
|
|
39
|
-
? updateArray(this, property
|
|
38
|
+
METHODS_UPDATE.has(property)
|
|
39
|
+
? updateArray(this, property, target)
|
|
40
40
|
: Reflect.get(target, property),
|
|
41
41
|
set: (target, property, value) => setValueInProxy(this, target, property, value),
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
Object.defineProperty(this, PROPERTY_LENGTH, {
|
|
45
|
-
enumerable: true,
|
|
46
|
-
get: () => this[SYMBOL_STATE].length.get(),
|
|
47
|
-
set: (value: number) => setArrayLength(this[SYMBOL_STATE], value),
|
|
48
|
-
});
|
|
49
|
-
|
|
50
44
|
setProxyValue.call(this, value);
|
|
51
45
|
}
|
|
52
46
|
|
|
53
47
|
ReactiveArray.prototype[NAME_MORA] = NAME_ARRAY;
|
|
54
48
|
|
|
55
|
-
ReactiveArray.prototype
|
|
49
|
+
Object.defineProperty(ReactiveArray.prototype, PROPERTY_LENGTH, {
|
|
50
|
+
enumerable: true,
|
|
51
|
+
get: getArrayLength,
|
|
52
|
+
set: setArrayLength,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
ReactiveArray.prototype.asReadonly = getReadonlySignal;
|
|
56
56
|
ReactiveArray.prototype.at = getArrayValues;
|
|
57
|
+
ReactiveArray.prototype.clear = clearArrayValues;
|
|
58
|
+
ReactiveArray.prototype.filter = filterArrayValues;
|
|
57
59
|
ReactiveArray.prototype.get = getArrayValues;
|
|
60
|
+
ReactiveArray.prototype.map = mapArrayValues;
|
|
58
61
|
ReactiveArray.prototype.notify = emitProxyValues;
|
|
59
62
|
ReactiveArray.prototype.peek = peekArrayValue;
|
|
63
|
+
ReactiveArray.prototype.pop = popArrayValue;
|
|
64
|
+
ReactiveArray.prototype.push = pushArrayValues;
|
|
65
|
+
ReactiveArray.prototype.select = selectArrayValues;
|
|
66
|
+
ReactiveArray.prototype.shift = shiftArrayValue;
|
|
60
67
|
ReactiveArray.prototype.set = setProxyValue;
|
|
68
|
+
ReactiveArray.prototype.splice = spliceArrayValues;
|
|
61
69
|
ReactiveArray.prototype.subscribe = subscribeToProxy;
|
|
62
70
|
ReactiveArray.prototype.toString = getStringValue;
|
|
71
|
+
ReactiveArray.prototype.toJSON = getJsonValue;
|
|
72
|
+
ReactiveArray.prototype.unshift = unshiftArrayValues;
|
|
63
73
|
ReactiveArray.prototype.update = updateProxyValue;
|
|
64
74
|
|
|
65
|
-
ReactiveArray.prototype.clear = function () {
|
|
66
|
-
this[SYMBOL_STATE].value.length = 0;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
ReactiveArray.prototype.filter = function (callback: never) {
|
|
70
|
-
return computed(() => filter(getArrayValues.call(this) as never, callback) as never);
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
ReactiveArray.prototype.map = function (callback: never) {
|
|
74
|
-
return computed(() => (getArrayValues.call(this) as unknown[]).map(callback));
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
ReactiveArray.prototype.pop = function () {
|
|
78
|
-
return this[SYMBOL_STATE].value.pop();
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
ReactiveArray.prototype.push = function (...items: unknown[]) {
|
|
82
|
-
return this[SYMBOL_STATE].value.push(...items);
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
ReactiveArray.prototype.select = function (filter: never, map: never) {
|
|
86
|
-
return computed(() => select(getArrayValues.call(this) as unknown[], filter, map));
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
ReactiveArray.prototype.shift = function () {
|
|
90
|
-
return this[SYMBOL_STATE].value.shift();
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
ReactiveArray.prototype.splice = function (from: never, to?: never, ...items: unknown[]) {
|
|
94
|
-
return this[SYMBOL_STATE].value.splice(from, to ?? this[SYMBOL_STATE].value.length, ...items);
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
ReactiveArray.prototype.toJSON = function () {
|
|
98
|
-
return this[SYMBOL_STATE].value;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
ReactiveArray.prototype.unshift = function (...items: unknown[]) {
|
|
102
|
-
return this[SYMBOL_STATE].value.unshift(...items);
|
|
103
|
-
};
|
|
104
|
-
|
|
105
75
|
// #endregion
|
|
106
76
|
|
|
107
77
|
// #region Functions
|
|
@@ -144,30 +114,75 @@ export function array(value: unknown, options?: ReactiveOptions<unknown>): React
|
|
|
144
114
|
return new ReactiveArray(value, options);
|
|
145
115
|
}
|
|
146
116
|
|
|
147
|
-
function
|
|
117
|
+
function clearArrayValues(this: InternalArray): void {
|
|
118
|
+
(this[SYMBOL_STATE].value as unknown[]).length = 0;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function filterArrayValues(this: InternalArray, callback: never): Computed<unknown[]> {
|
|
122
|
+
return computed(() => filter(getArrayValues.call(this) as never, callback) as never);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function getArrayLength(this: InternalArray): number {
|
|
126
|
+
return this[SYMBOL_STATE].length!.get();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function getArrayValues(this: InternalArray, value?: unknown): unknown {
|
|
148
130
|
return value === PROPERTY_LENGTH
|
|
149
131
|
? this[SYMBOL_STATE].length!.get()
|
|
150
132
|
: getValueInProxy.call(this, value);
|
|
151
133
|
}
|
|
152
134
|
|
|
153
|
-
function
|
|
135
|
+
function mapArrayValues(this: InternalArray, callback: never): Computed<unknown[]> {
|
|
136
|
+
return computed(() => (getArrayValues.call(this) as unknown[]).map(callback));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function peekArrayValue(this: InternalArray, first?: unknown, second?: boolean): unknown {
|
|
154
140
|
return first === PROPERTY_LENGTH
|
|
155
141
|
? this[SYMBOL_STATE].length!.peek()
|
|
156
142
|
: peekValueInProxy.call(this, first, second);
|
|
157
143
|
}
|
|
158
144
|
|
|
159
|
-
function
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
145
|
+
function popArrayValue(this: InternalArray): unknown {
|
|
146
|
+
return (this[SYMBOL_STATE].value as unknown[]).pop();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function pushArrayValues(this: InternalArray, ...items: unknown[]): number {
|
|
150
|
+
return (this[SYMBOL_STATE].value as unknown[]).push(...items);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function selectArrayValues(this: InternalArray, filter: never, map: never): Computed<unknown[]> {
|
|
154
|
+
return computed(() => select(getArrayValues.call(this) as unknown[], filter, map));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function setArrayLength(this: InternalArray, value: number): void {
|
|
158
|
+
const state = this[SYMBOL_STATE];
|
|
159
|
+
const values = state.value as unknown[];
|
|
160
|
+
|
|
161
|
+
if (typeof value === 'number' && !Number.isNaN(value) && value >= 0 && value !== values.length) {
|
|
162
|
+
values.length = value;
|
|
167
163
|
}
|
|
168
164
|
}
|
|
169
165
|
|
|
170
|
-
function
|
|
166
|
+
function shiftArrayValue(this: InternalArray): unknown {
|
|
167
|
+
return (this[SYMBOL_STATE].value as unknown[]).shift();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function spliceArrayValues(
|
|
171
|
+
this: InternalArray,
|
|
172
|
+
from: never,
|
|
173
|
+
to?: never,
|
|
174
|
+
...items: unknown[]
|
|
175
|
+
): unknown[] {
|
|
176
|
+
const values = this[SYMBOL_STATE].value as unknown[];
|
|
177
|
+
|
|
178
|
+
return values.splice(from, to ?? values.length, ...items);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function unshiftArrayValues(this: InternalArray, ...items: unknown[]): number {
|
|
182
|
+
return (this[SYMBOL_STATE].value as unknown[]).unshift(...items);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function updateArray(instance: InternalArray, type: string | symbol, array: unknown[]): unknown {
|
|
171
186
|
const state = instance[SYMBOL_STATE];
|
|
172
187
|
|
|
173
188
|
const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
|
|
@@ -178,7 +193,9 @@ function updateArray(instance: InternalProxy, type: string, array: unknown[]): u
|
|
|
178
193
|
const result = (array[type as never] as (...args: unknown[]) => unknown)(...args);
|
|
179
194
|
|
|
180
195
|
if (
|
|
181
|
-
affectsLength
|
|
196
|
+
affectsLength
|
|
197
|
+
? array.length !== previousLength
|
|
198
|
+
: !equalArrays(previousArray, array, state.equal)
|
|
182
199
|
) {
|
|
183
200
|
emitValue(instance);
|
|
184
201
|
|
package/src/value/computed.ts
CHANGED
|
@@ -14,20 +14,19 @@ import {
|
|
|
14
14
|
import {internalEffect, runEffect} from '../effect';
|
|
15
15
|
import {getState} from '../helpers/misc';
|
|
16
16
|
import {subscribeToSignal} from '../helpers/subscription';
|
|
17
|
-
import {getStringValue,
|
|
17
|
+
import {getJsonValue, getStringValue, handleSignal, peekSignalValue} from '../helpers/value';
|
|
18
18
|
import type {
|
|
19
19
|
Computed,
|
|
20
20
|
ComputedEffect,
|
|
21
|
-
ReactiveOptions,
|
|
22
21
|
InternalComputed,
|
|
23
|
-
|
|
22
|
+
InternalStateful,
|
|
23
|
+
ReactiveOptions,
|
|
24
24
|
} from '../models';
|
|
25
25
|
|
|
26
26
|
// #region Instance
|
|
27
27
|
|
|
28
28
|
function Computed(this: any, callback: GenericCallback, options?: ReactiveOptions<unknown>) {
|
|
29
29
|
this[SYMBOL_STATE] = getState(undefined, options);
|
|
30
|
-
|
|
31
30
|
this[SYMBOL_EFFECT] = getComputedEffect(this, callback);
|
|
32
31
|
}
|
|
33
32
|
|
|
@@ -36,12 +35,9 @@ Computed.prototype[NAME_MORA] = NAME_COMPUTED;
|
|
|
36
35
|
Computed.prototype.get = getComputedValue;
|
|
37
36
|
Computed.prototype.peek = peekSignalValue;
|
|
38
37
|
Computed.prototype.subscribe = subscribeToSignal;
|
|
38
|
+
Computed.prototype.toJSON = getJsonValue;
|
|
39
39
|
Computed.prototype.toString = getStringValue;
|
|
40
40
|
|
|
41
|
-
Computed.prototype.toJSON = function () {
|
|
42
|
-
return this[SYMBOL_STATE].value;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
41
|
// #endregion
|
|
46
42
|
|
|
47
43
|
// #region Functions
|
|
@@ -57,13 +53,13 @@ export function computed<Value>(
|
|
|
57
53
|
callback: () => Value | Promise<Value>,
|
|
58
54
|
options?: ReactiveOptions<Value>,
|
|
59
55
|
): Computed<Value> {
|
|
60
|
-
return getComputed(callback, options)[0]
|
|
56
|
+
return getComputed(callback, options)[0] as Computed<Value>;
|
|
61
57
|
}
|
|
62
58
|
|
|
63
59
|
function getComputed<Value>(
|
|
64
60
|
callback: GenericCallback,
|
|
65
61
|
options?: ReactiveOptions<Value>,
|
|
66
|
-
): [
|
|
62
|
+
): [InternalComputed, ComputedEffect] {
|
|
67
63
|
if (typeof callback !== 'function') {
|
|
68
64
|
throw new TypeError('Computed callback must be a function');
|
|
69
65
|
}
|
|
@@ -71,11 +67,11 @@ function getComputed<Value>(
|
|
|
71
67
|
// @ts-expect-error All good, no worries :-)
|
|
72
68
|
const instance = new Computed(callback, options);
|
|
73
69
|
|
|
74
|
-
return [instance
|
|
70
|
+
return [instance, instance[SYMBOL_EFFECT]];
|
|
75
71
|
}
|
|
76
72
|
|
|
77
73
|
function getComputedEffect(
|
|
78
|
-
instance:
|
|
74
|
+
instance: InternalStateful,
|
|
79
75
|
callback: GenericAsyncCallback,
|
|
80
76
|
): ComputedEffect {
|
|
81
77
|
const fx: ComputedEffect = {
|
|
@@ -89,7 +85,7 @@ function getComputedEffect(
|
|
|
89
85
|
|
|
90
86
|
ACTIVE.computed = fx;
|
|
91
87
|
|
|
92
|
-
|
|
88
|
+
handleSignal(instance, callback, setAndEmit, () => {
|
|
93
89
|
ACTIVE.computed = previousComputed;
|
|
94
90
|
});
|
|
95
91
|
|
|
@@ -126,14 +122,14 @@ function getComputedValue(this: InternalComputed): unknown {
|
|
|
126
122
|
export function internalComputed(
|
|
127
123
|
callback: GenericCallback,
|
|
128
124
|
options?: ReactiveOptions<unknown>,
|
|
129
|
-
): [
|
|
125
|
+
): [InternalComputed, ComputedEffect] {
|
|
130
126
|
return getComputed(callback, options);
|
|
131
127
|
}
|
|
132
128
|
|
|
133
|
-
function setAndEmit(instance:
|
|
129
|
+
function setAndEmit(instance: InternalStateful, value: unknown): void {
|
|
134
130
|
const state = instance[SYMBOL_STATE];
|
|
135
131
|
|
|
136
|
-
if ((state.equal ?? Object.is)(state.value
|
|
132
|
+
if ((state.equal ?? Object.is)(state.value, value)) {
|
|
137
133
|
return;
|
|
138
134
|
}
|
|
139
135
|
|