@oscarpalmer/mora 0.32.0 → 0.33.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 +2 -2
- package/dist/constants.d.mts +2 -0
- package/dist/constants.mjs +3 -1
- package/dist/effect.d.mts +1 -0
- package/dist/effect.mjs +8 -5
- package/dist/helpers/is.d.mts +6 -6
- package/dist/helpers/misc.d.mts +4 -0
- package/dist/helpers/misc.mjs +9 -0
- package/dist/helpers/proxy.d.mts +8 -10
- package/dist/helpers/proxy.mjs +71 -33
- package/dist/helpers/subscription.d.mts +4 -4
- package/dist/helpers/subscription.mjs +16 -13
- package/dist/helpers/value.d.mts +8 -7
- package/dist/helpers/value.mjs +35 -22
- package/dist/models.d.mts +47 -24
- package/dist/models.mjs +1 -0
- package/dist/mora.full.mjs +307 -236
- package/dist/value/array.d.mts +1 -0
- package/dist/value/array.mjs +69 -61
- package/dist/value/computed.d.mts +3 -1
- package/dist/value/computed.mjs +39 -25
- package/dist/value/readonly.d.mts +3 -3
- package/dist/value/readonly.mjs +31 -24
- package/dist/value/signal.d.mts +1 -0
- package/dist/value/signal.mjs +27 -20
- package/dist/value/store.d.mts +1 -0
- package/dist/value/store.mjs +23 -41
- package/package.json +1 -1
- package/src/batch.ts +2 -2
- package/src/constants.ts +4 -0
- package/src/effect.ts +16 -11
- package/src/helpers/is.ts +6 -6
- package/src/helpers/misc.ts +15 -0
- package/src/helpers/proxy.ts +116 -89
- package/src/helpers/subscription.ts +46 -35
- package/src/helpers/value.ts +61 -35
- package/src/models.ts +54 -28
- package/src/value/array.ts +103 -124
- package/src/value/computed.ts +70 -40
- package/src/value/readonly.ts +54 -41
- package/src/value/signal.ts +46 -35
- package/src/value/store.ts +36 -83
- package/dist/value/reactive.d.mts +0 -4
- package/dist/value/reactive.mjs +0 -15
- package/src/value/reactive.ts +0 -27
package/src/helpers/proxy.ts
CHANGED
|
@@ -1,131 +1,164 @@
|
|
|
1
1
|
import {isKey, isPlainObject} from '@oscarpalmer/atoms/is';
|
|
2
2
|
import type {ArrayOrPlainObject, Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
3
|
-
import {
|
|
3
|
+
import {startBatch, stopBatch} from '../batch';
|
|
4
|
+
import {PROPERTY_LENGTH, SYMBOL_STATE} from '../constants';
|
|
4
5
|
import type {
|
|
5
6
|
Computed,
|
|
6
|
-
ComputedEffect,
|
|
7
7
|
ReactiveArray,
|
|
8
|
-
|
|
8
|
+
ReactiveProxyState,
|
|
9
9
|
ReactiveStore,
|
|
10
|
-
|
|
10
|
+
InternalProxy,
|
|
11
11
|
} from '../models';
|
|
12
12
|
import {internalComputed} from '../value/computed';
|
|
13
|
-
import {emitValue,
|
|
13
|
+
import {emitValue, getSignalValue, peekSignalValue} from './value';
|
|
14
14
|
|
|
15
|
-
// #region
|
|
16
|
-
|
|
17
|
-
type SetObjectCallback<Value, Item> = (
|
|
18
|
-
state: ReactiveState<Value, Item>,
|
|
19
|
-
value: Value | undefined,
|
|
20
|
-
) => void;
|
|
15
|
+
// #region Functions
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
state
|
|
24
|
-
property: unknown,
|
|
25
|
-
value: Item,
|
|
26
|
-
) => void;
|
|
17
|
+
export function emitProxyValues(this: InternalProxy): void {
|
|
18
|
+
const state = this[SYMBOL_STATE];
|
|
27
19
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// #region Functions
|
|
20
|
+
state.mapped ??= new Map();
|
|
31
21
|
|
|
32
|
-
|
|
33
|
-
state: ReactiveState<Value, Item>,
|
|
34
|
-
mapped: Map<Key, [Computed<unknown>, ComputedEffect]>,
|
|
35
|
-
): void {
|
|
36
|
-
const values = [...mapped.values()];
|
|
22
|
+
const values = [...state.mapped.values()];
|
|
37
23
|
const {length} = values;
|
|
38
24
|
|
|
39
25
|
for (let index = 0; index < length; index += 1) {
|
|
40
26
|
values[index][1].dirty = true;
|
|
41
27
|
}
|
|
42
28
|
|
|
43
|
-
emitValue(
|
|
29
|
+
emitValue(this);
|
|
44
30
|
}
|
|
45
31
|
|
|
46
|
-
export function getReactiveValueInProxy
|
|
47
|
-
|
|
48
|
-
mapped: Map<Key, [Computed<unknown>, ComputedEffect]>,
|
|
32
|
+
export function getReactiveValueInProxy(
|
|
33
|
+
instance: ReactiveArray<unknown> | ReactiveStore<unknown>,
|
|
49
34
|
key: Key,
|
|
50
|
-
isArray: boolean,
|
|
51
35
|
): Computed<unknown> {
|
|
36
|
+
const state = (instance as unknown as InternalProxy)[SYMBOL_STATE];
|
|
37
|
+
|
|
38
|
+
state.mapped ??= new Map();
|
|
39
|
+
|
|
52
40
|
const mapKey = String(key);
|
|
53
41
|
|
|
54
|
-
let item = mapped.get(mapKey);
|
|
42
|
+
let item = state.mapped.get(mapKey);
|
|
55
43
|
|
|
56
44
|
if (item == null) {
|
|
57
45
|
item = internalComputed(() =>
|
|
58
|
-
isArray
|
|
59
|
-
? (
|
|
60
|
-
: (
|
|
46
|
+
state.isArray
|
|
47
|
+
? (instance.get() as unknown[]).at(key as number)
|
|
48
|
+
: (instance.get() as PlainObject)[key],
|
|
61
49
|
);
|
|
62
50
|
|
|
63
|
-
mapped.set(mapKey, item);
|
|
51
|
+
state.mapped.set(mapKey, item);
|
|
64
52
|
}
|
|
65
53
|
|
|
66
54
|
return item[0];
|
|
67
55
|
}
|
|
68
56
|
|
|
69
|
-
export function getValueInProxy
|
|
70
|
-
isArray:
|
|
71
|
-
|
|
72
|
-
state: ReactiveState<Value, Item>,
|
|
73
|
-
mapped: Map<Key, [Computed<unknown>, ComputedEffect]>,
|
|
74
|
-
first?: unknown,
|
|
75
|
-
): unknown {
|
|
76
|
-
if (isArray ? typeof first === 'number' : isKey(first)) {
|
|
77
|
-
return getReactiveValueInProxy(instance, mapped, first as Key, isArray).get();
|
|
57
|
+
export function getValueInProxy(this: InternalProxy, first?: unknown): unknown {
|
|
58
|
+
if (this[SYMBOL_STATE].isArray ? typeof first === 'number' : isKey(first)) {
|
|
59
|
+
return getReactiveValueInProxy(this as never, first as Key).get();
|
|
78
60
|
}
|
|
79
61
|
|
|
80
|
-
return
|
|
62
|
+
return getSignalValue.call(this);
|
|
81
63
|
}
|
|
82
64
|
|
|
83
65
|
function isProxyObject(isArray: boolean, value: unknown): value is ArrayOrPlainObject {
|
|
84
66
|
return value == null || (isArray ? Array.isArray(value) : isPlainObject(value));
|
|
85
67
|
}
|
|
86
68
|
|
|
87
|
-
export function peekValueInProxy
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
first?: unknown,
|
|
91
|
-
second?: boolean,
|
|
92
|
-
): unknown {
|
|
69
|
+
export function peekValueInProxy(this: InternalProxy, first?: unknown, second?: boolean): unknown {
|
|
70
|
+
const state = this[SYMBOL_STATE];
|
|
71
|
+
|
|
93
72
|
let value: unknown;
|
|
94
73
|
|
|
95
|
-
if (isArray ? typeof first === 'number' : isKey(first)) {
|
|
96
|
-
value = isArray
|
|
74
|
+
if (state.isArray ? typeof first === 'number' : isKey(first)) {
|
|
75
|
+
value = state.isArray
|
|
97
76
|
? (state.value as unknown[]).at(first as number)
|
|
98
77
|
: (state.value as PlainObject)[first as Key];
|
|
99
78
|
} else {
|
|
100
79
|
value = state.value;
|
|
101
80
|
}
|
|
102
81
|
|
|
103
|
-
return
|
|
82
|
+
return peekSignalValue.call([this, value], first === true || second === true);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function setProxyObject(state: ReactiveProxyState, value: unknown): void {
|
|
86
|
+
if (state.isArray) {
|
|
87
|
+
(state.value as unknown[]).splice(
|
|
88
|
+
0,
|
|
89
|
+
(state.value as unknown[]).length,
|
|
90
|
+
...((value ?? []) as unknown[]),
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
startBatch();
|
|
97
|
+
|
|
98
|
+
const actual = (value as Record<string, unknown>) ?? {};
|
|
99
|
+
const proxy = state.value as PlainObject;
|
|
100
|
+
|
|
101
|
+
const proxyKeys = Object.keys(proxy);
|
|
102
|
+
const actualKeys = Object.keys(actual);
|
|
103
|
+
|
|
104
|
+
let {length} = proxyKeys;
|
|
105
|
+
|
|
106
|
+
for (let index = 0; index < length; index += 1) {
|
|
107
|
+
const key = proxyKeys[index];
|
|
108
|
+
|
|
109
|
+
proxy[key] = actualKeys.includes(key) ? actual[key] : undefined;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
length = actualKeys.length;
|
|
113
|
+
|
|
114
|
+
for (let index = 0; index < length; index += 1) {
|
|
115
|
+
const key = actualKeys[index];
|
|
116
|
+
|
|
117
|
+
if (!proxyKeys.includes(key)) {
|
|
118
|
+
const keyedValue = actual[key];
|
|
119
|
+
|
|
120
|
+
proxy[key] = keyedValue;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
stopBatch();
|
|
104
125
|
}
|
|
105
126
|
|
|
106
|
-
|
|
107
|
-
isArray
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
127
|
+
function setProxyProperty(state: ReactiveProxyState, property: unknown, value: unknown): void {
|
|
128
|
+
if (!state.isArray) {
|
|
129
|
+
(state.value as PlainObject)[property as Key] = value;
|
|
130
|
+
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const actual =
|
|
135
|
+
(property as number) < 0
|
|
136
|
+
? (state.value as unknown[]).length + (property as number)
|
|
137
|
+
: (property as number);
|
|
138
|
+
|
|
139
|
+
if (actual > -1) {
|
|
140
|
+
(state.value as unknown[])[actual] = value;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function setProxyValue(this: InternalProxy, first?: unknown, second?: unknown): void {
|
|
145
|
+
const state = this[SYMBOL_STATE] as ReactiveProxyState;
|
|
146
|
+
|
|
147
|
+
if (state.isArray && first === PROPERTY_LENGTH) {
|
|
115
148
|
(state.value as unknown[]).length = second as number;
|
|
116
149
|
|
|
117
150
|
return;
|
|
118
151
|
}
|
|
119
152
|
|
|
120
|
-
if (isProxyObject(isArray, first)) {
|
|
121
|
-
|
|
153
|
+
if (isProxyObject(state.isArray, first)) {
|
|
154
|
+
setProxyObject(state, first);
|
|
122
155
|
|
|
123
156
|
return;
|
|
124
157
|
}
|
|
125
158
|
|
|
126
|
-
const property = isArray ? typeof first === 'number' : isKey(first);
|
|
159
|
+
const property = state.isArray ? typeof first === 'number' : isKey(first);
|
|
127
160
|
|
|
128
|
-
if (isArray && property && Number.isNaN(first)) {
|
|
161
|
+
if (state.isArray && property && Number.isNaN(first)) {
|
|
129
162
|
return;
|
|
130
163
|
}
|
|
131
164
|
|
|
@@ -153,15 +186,15 @@ export function setProxyValue<Value, Item = Value>(
|
|
|
153
186
|
if (property && state.promises!.get(first as Key) === actual) {
|
|
154
187
|
state.promises!.delete(first as Key);
|
|
155
188
|
|
|
156
|
-
|
|
189
|
+
setProxyProperty(state, first, value);
|
|
157
190
|
|
|
158
191
|
return;
|
|
159
192
|
}
|
|
160
193
|
|
|
161
|
-
if (!property && isProxyObject(isArray, value) && state.promise === actual) {
|
|
194
|
+
if (!property && isProxyObject(state.isArray, value) && state.promise === actual) {
|
|
162
195
|
state.promise = undefined;
|
|
163
196
|
|
|
164
|
-
|
|
197
|
+
setProxyObject(state, value);
|
|
165
198
|
}
|
|
166
199
|
})
|
|
167
200
|
.catch(() => {
|
|
@@ -172,21 +205,21 @@ export function setProxyValue<Value, Item = Value>(
|
|
|
172
205
|
}
|
|
173
206
|
});
|
|
174
207
|
} else if (property) {
|
|
175
|
-
|
|
176
|
-
} else if (isProxyObject(isArray, actual)) {
|
|
177
|
-
|
|
208
|
+
setProxyProperty(state, first, actual);
|
|
209
|
+
} else if (isProxyObject(state.isArray, actual)) {
|
|
210
|
+
setProxyObject(state, actual);
|
|
178
211
|
}
|
|
179
212
|
}
|
|
180
213
|
|
|
181
|
-
export function setValueInProxy
|
|
182
|
-
|
|
183
|
-
state: ReactiveState<Value, Item>,
|
|
214
|
+
export function setValueInProxy(
|
|
215
|
+
instance: InternalProxy,
|
|
184
216
|
target: object,
|
|
185
217
|
property: PropertyKey,
|
|
186
218
|
value: unknown,
|
|
187
|
-
length?: Signal<number>,
|
|
188
219
|
): boolean {
|
|
189
|
-
|
|
220
|
+
const state = instance[SYMBOL_STATE];
|
|
221
|
+
|
|
222
|
+
if (state.isArray) {
|
|
190
223
|
const isIndex = !Number.isNaN(Number(property));
|
|
191
224
|
const isLength = property === PROPERTY_LENGTH;
|
|
192
225
|
|
|
@@ -197,31 +230,25 @@ export function setValueInProxy<Value, Item = Value>(
|
|
|
197
230
|
|
|
198
231
|
const previous = Reflect.get(target as object, property);
|
|
199
232
|
|
|
200
|
-
if (!state.equal(previous as never, value as never)) {
|
|
233
|
+
if (!(state.equal ?? Object.is)(previous as never, value as never)) {
|
|
201
234
|
Reflect.set(target, property, value);
|
|
202
235
|
|
|
203
|
-
emitValue(
|
|
236
|
+
emitValue(instance);
|
|
204
237
|
|
|
205
|
-
if (isArray) {
|
|
206
|
-
length?.set((target as unknown[]).length);
|
|
238
|
+
if (state.isArray) {
|
|
239
|
+
state.length?.set((target as unknown[]).length);
|
|
207
240
|
}
|
|
208
241
|
}
|
|
209
242
|
|
|
210
243
|
return true;
|
|
211
244
|
}
|
|
212
245
|
|
|
213
|
-
export function updateProxyValue
|
|
214
|
-
isArray: boolean,
|
|
215
|
-
state: ReactiveState<Value, Item>,
|
|
216
|
-
setObject: SetObjectCallback<Value, Item>,
|
|
217
|
-
setProperty: SetPropertyCallback<Value, Item>,
|
|
218
|
-
callback: unknown,
|
|
219
|
-
): void {
|
|
246
|
+
export function updateProxyValue(this: InternalProxy, callback: unknown): void {
|
|
220
247
|
if (typeof callback !== 'function') {
|
|
221
248
|
throw new TypeError('Callback must be a function');
|
|
222
249
|
}
|
|
223
250
|
|
|
224
|
-
setProxyValue(
|
|
251
|
+
setProxyValue.call(this, callback(this[SYMBOL_STATE].value));
|
|
225
252
|
}
|
|
226
253
|
|
|
227
254
|
// #endregion
|
|
@@ -6,73 +6,84 @@ import {
|
|
|
6
6
|
SUBSCRIPTION_TYPE_COPY,
|
|
7
7
|
SUBSCRIPTION_TYPE_FROZEN,
|
|
8
8
|
SUBSCRIPTION_TYPE_ORIGINAL,
|
|
9
|
+
SUBSCRIPTION_TYPE_READONLY,
|
|
9
10
|
SUBSCRIPTION_TYPES,
|
|
10
11
|
SUBSCRIPTION_TYPES_COPY,
|
|
12
|
+
SYMBOL_STATE,
|
|
11
13
|
} from '../constants';
|
|
12
14
|
import type {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
ReactiveStore,
|
|
15
|
+
InternalProxy,
|
|
16
|
+
InternalReadonly,
|
|
17
|
+
InternalSignal,
|
|
18
|
+
Subscriber,
|
|
18
19
|
SubscriptionType,
|
|
19
20
|
} from '../models';
|
|
20
21
|
import {getReactiveValueInProxy} from './proxy';
|
|
21
|
-
import {getFrozenValue,
|
|
22
|
+
import {getFrozenValue, peekSignalValue} from './value';
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
second?: ((value: unknown) => unknown) | boolean,
|
|
24
|
+
// #region Functions
|
|
25
|
+
|
|
26
|
+
export function subscribeToProxy(
|
|
27
|
+
this: InternalProxy,
|
|
28
|
+
first: Key | Subscriber<unknown>,
|
|
29
|
+
second?: Subscriber<unknown> | boolean,
|
|
30
30
|
third?: boolean,
|
|
31
31
|
): Subscription {
|
|
32
32
|
if (isKey(first)) {
|
|
33
|
-
return getReactiveValueInProxy(
|
|
34
|
-
second as never,
|
|
35
|
-
third as never,
|
|
36
|
-
);
|
|
33
|
+
return getReactiveValueInProxy(this as never, first).subscribe(second as never, third as never);
|
|
37
34
|
}
|
|
38
35
|
|
|
39
|
-
return subscribeToSignal(
|
|
36
|
+
return subscribeToSignal.call(this, first, second);
|
|
40
37
|
}
|
|
41
38
|
|
|
42
|
-
|
|
39
|
+
function subscribeToReactive(
|
|
40
|
+
this: InternalSignal,
|
|
43
41
|
type: SubscriptionType,
|
|
44
|
-
|
|
45
|
-
callback: (value: unknown) => unknown,
|
|
42
|
+
subscriber: Subscriber<unknown>,
|
|
46
43
|
): Subscription {
|
|
47
|
-
|
|
44
|
+
this[SYMBOL_STATE].subscriptions ??= subscriptions({
|
|
48
45
|
keys: SUBSCRIPTION_TYPES,
|
|
49
46
|
property: SUBSCRIPTION_PROPERTY,
|
|
50
47
|
});
|
|
51
48
|
|
|
52
|
-
const [subscription, existing] =
|
|
49
|
+
const [subscription, existing] = this[SYMBOL_STATE].subscriptions.create({
|
|
53
50
|
key: type,
|
|
54
|
-
value:
|
|
51
|
+
value: subscriber,
|
|
55
52
|
});
|
|
56
53
|
|
|
57
54
|
if (!existing) {
|
|
58
|
-
|
|
55
|
+
subscriber(
|
|
59
56
|
type === SUBSCRIPTION_TYPE_FROZEN
|
|
60
|
-
? getFrozenValue(
|
|
61
|
-
:
|
|
57
|
+
? getFrozenValue(this[SYMBOL_STATE].value)
|
|
58
|
+
: peekSignalValue.call(this, SUBSCRIPTION_TYPES_COPY.has(type)),
|
|
59
|
+
subscription,
|
|
62
60
|
);
|
|
63
61
|
}
|
|
64
62
|
|
|
65
63
|
return subscription;
|
|
66
64
|
}
|
|
67
65
|
|
|
68
|
-
export function
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
copy: boolean,
|
|
66
|
+
export function subscribeToReadonly(
|
|
67
|
+
this: InternalReadonly,
|
|
68
|
+
subscriber: Subscriber<unknown>,
|
|
72
69
|
): Subscription {
|
|
73
|
-
return subscribeToReactive(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
return subscribeToReactive.call(
|
|
71
|
+
this,
|
|
72
|
+
this.frozen ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_READONLY,
|
|
73
|
+
subscriber,
|
|
77
74
|
);
|
|
78
75
|
}
|
|
76
|
+
|
|
77
|
+
export function subscribeToSignal(
|
|
78
|
+
this: InternalSignal,
|
|
79
|
+
subscriber: Subscriber<unknown>,
|
|
80
|
+
copy?: unknown,
|
|
81
|
+
): Subscription {
|
|
82
|
+
return subscribeToReactive.call(
|
|
83
|
+
this,
|
|
84
|
+
copy === true ? SUBSCRIPTION_TYPE_COPY : SUBSCRIPTION_TYPE_ORIGINAL,
|
|
85
|
+
subscriber,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// #endregion
|
package/src/helpers/value.ts
CHANGED
|
@@ -9,27 +9,35 @@ import {
|
|
|
9
9
|
SUBSCRIPTION_TYPES_COPY,
|
|
10
10
|
SUBSCRIPTION_TYPE_FROZEN,
|
|
11
11
|
SUBSCRIPTION_TYPES,
|
|
12
|
+
SYMBOL_STATE,
|
|
12
13
|
} from '../constants';
|
|
13
|
-
import type {ReactiveState} from '../models';
|
|
14
|
+
import type {ReactiveState, InternalSignal} from '../models';
|
|
14
15
|
|
|
15
16
|
// #region Functions
|
|
16
17
|
|
|
17
|
-
export function emitValue
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
export function emitValue(instance: InternalSignal): void {
|
|
19
|
+
const state = instance[SYMBOL_STATE];
|
|
20
|
+
|
|
21
|
+
if (state.computeds != null && state.computeds.size > 0) {
|
|
22
|
+
for (const computed of state.computeds) {
|
|
23
|
+
computed.dirty = true;
|
|
24
|
+
}
|
|
20
25
|
}
|
|
21
26
|
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
if (state.effects != null && state.effects.size > 0) {
|
|
28
|
+
for (const effect of state.effects) {
|
|
29
|
+
BATCH.handlers.set(effect, effect);
|
|
30
|
+
}
|
|
24
31
|
}
|
|
25
32
|
|
|
26
33
|
for (const type of SUBSCRIPTION_TYPES) {
|
|
27
34
|
const subscriptions = state.subscriptions?.values.to.keyed?.get(type);
|
|
28
35
|
|
|
29
|
-
if (subscriptions != null) {
|
|
36
|
+
if (subscriptions != null && subscriptions.size > 0) {
|
|
30
37
|
for (const [subscription, callback] of subscriptions) {
|
|
31
38
|
BATCH.handlers.set(subscription, {
|
|
32
39
|
callback,
|
|
40
|
+
instance,
|
|
33
41
|
state,
|
|
34
42
|
frozen: type === SUBSCRIPTION_TYPE_FROZEN,
|
|
35
43
|
copy: SUBSCRIPTION_TYPES_COPY.has(type),
|
|
@@ -43,17 +51,15 @@ export function emitValue<Value>(state: ReactiveState<Value, never>): void {
|
|
|
43
51
|
}
|
|
44
52
|
}
|
|
45
53
|
|
|
46
|
-
export function equalArrays
|
|
47
|
-
|
|
48
|
-
first: Value[],
|
|
49
|
-
second: Value[],
|
|
50
|
-
): boolean {
|
|
51
|
-
let {length} = first;
|
|
54
|
+
export function equalArrays(state: ReactiveState, first: unknown[], second: unknown[]): boolean {
|
|
55
|
+
const {length} = first;
|
|
52
56
|
|
|
53
57
|
if (length !== second.length) {
|
|
54
58
|
return false;
|
|
55
59
|
}
|
|
56
60
|
|
|
61
|
+
const eq = state.equal ?? Object.is;
|
|
62
|
+
|
|
57
63
|
let offset = 0;
|
|
58
64
|
|
|
59
65
|
if (length >= ARRAY_THRESHOLD) {
|
|
@@ -61,16 +67,21 @@ export function equalArrays<Value>(
|
|
|
61
67
|
offset = offset > ARRAY_OFFSET ? ARRAY_OFFSET : offset;
|
|
62
68
|
|
|
63
69
|
for (let index = 0; index < offset; index += 1) {
|
|
64
|
-
if (
|
|
70
|
+
if (
|
|
71
|
+
!(
|
|
72
|
+
eq(first[index], second[index]) &&
|
|
73
|
+
eq(first[length - index - 1], second[length - index - 1])
|
|
74
|
+
)
|
|
75
|
+
) {
|
|
65
76
|
return false;
|
|
66
77
|
}
|
|
67
78
|
}
|
|
68
79
|
}
|
|
69
80
|
|
|
70
|
-
length
|
|
81
|
+
const end = length - offset;
|
|
71
82
|
|
|
72
|
-
for (let index = offset; index <
|
|
73
|
-
if (!
|
|
83
|
+
for (let index = offset; index < end; index += 1) {
|
|
84
|
+
if (!eq(first[index], second[index])) {
|
|
74
85
|
return false;
|
|
75
86
|
}
|
|
76
87
|
}
|
|
@@ -90,24 +101,36 @@ export function getFrozenValue(value: unknown): unknown {
|
|
|
90
101
|
return frozen;
|
|
91
102
|
}
|
|
92
103
|
|
|
93
|
-
export function
|
|
104
|
+
export function getSignalValue(this: InternalSignal): unknown {
|
|
94
105
|
if (ACTIVE.computed != null) {
|
|
95
|
-
|
|
106
|
+
this[SYMBOL_STATE].computeds ??= new Set();
|
|
107
|
+
|
|
108
|
+
this[SYMBOL_STATE].computeds.add(ACTIVE.computed);
|
|
96
109
|
}
|
|
97
110
|
|
|
98
111
|
if (ACTIVE.effect != null) {
|
|
99
|
-
|
|
112
|
+
this[SYMBOL_STATE].effects ??= new Set();
|
|
113
|
+
|
|
114
|
+
this[SYMBOL_STATE].effects.add(ACTIVE.effect);
|
|
100
115
|
}
|
|
101
116
|
|
|
102
|
-
return
|
|
117
|
+
return this[SYMBOL_STATE].value;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function getStringValue(this: InternalSignal, json?: boolean): string {
|
|
121
|
+
return json === true
|
|
122
|
+
? JSON.stringify(this[SYMBOL_STATE].value)
|
|
123
|
+
: String(this[SYMBOL_STATE].value);
|
|
103
124
|
}
|
|
104
125
|
|
|
105
|
-
export function
|
|
106
|
-
|
|
107
|
-
origin:
|
|
108
|
-
setValue: (
|
|
126
|
+
export function handleSignalValue(
|
|
127
|
+
instance: InternalSignal,
|
|
128
|
+
origin: unknown,
|
|
129
|
+
setValue: (instance: InternalSignal, value: unknown) => void,
|
|
109
130
|
onAfter?: () => void,
|
|
110
131
|
): void {
|
|
132
|
+
const state = instance[SYMBOL_STATE];
|
|
133
|
+
|
|
111
134
|
try {
|
|
112
135
|
let actual = typeof origin === 'function' ? (origin as () => unknown)() : origin;
|
|
113
136
|
|
|
@@ -119,7 +142,7 @@ export function handleSimpleValue<Value>(
|
|
|
119
142
|
if (actual === state.promise) {
|
|
120
143
|
state.promise = undefined;
|
|
121
144
|
|
|
122
|
-
setValue(
|
|
145
|
+
setValue(instance, value);
|
|
123
146
|
}
|
|
124
147
|
})
|
|
125
148
|
.catch(() => {
|
|
@@ -128,7 +151,7 @@ export function handleSimpleValue<Value>(
|
|
|
128
151
|
}
|
|
129
152
|
});
|
|
130
153
|
} else {
|
|
131
|
-
setValue(
|
|
154
|
+
setValue(instance, actual);
|
|
132
155
|
}
|
|
133
156
|
} catch {
|
|
134
157
|
// ?
|
|
@@ -137,10 +160,13 @@ export function handleSimpleValue<Value>(
|
|
|
137
160
|
}
|
|
138
161
|
}
|
|
139
162
|
|
|
140
|
-
export function
|
|
141
|
-
|
|
163
|
+
export function peekSignalValue(
|
|
164
|
+
this: InternalSignal | [InternalSignal, unknown],
|
|
165
|
+
copy?: boolean,
|
|
166
|
+
): unknown {
|
|
167
|
+
let peeked: unknown = Array.isArray(this) ? this[1] : this[SYMBOL_STATE].value;
|
|
142
168
|
|
|
143
|
-
if (
|
|
169
|
+
if (copy !== true) {
|
|
144
170
|
return peeked;
|
|
145
171
|
}
|
|
146
172
|
|
|
@@ -153,16 +179,16 @@ export function peekSimpleValue(value: unknown, copy: boolean): unknown {
|
|
|
153
179
|
return peeked;
|
|
154
180
|
}
|
|
155
181
|
|
|
156
|
-
export function
|
|
157
|
-
|
|
158
|
-
callback: (value:
|
|
159
|
-
setValue: (
|
|
182
|
+
export function updateSignalValue(
|
|
183
|
+
instance: InternalSignal,
|
|
184
|
+
callback: (value: unknown) => unknown,
|
|
185
|
+
setValue: (instance: InternalSignal, value: unknown) => void,
|
|
160
186
|
): void {
|
|
161
187
|
if (typeof callback !== 'function') {
|
|
162
188
|
throw new TypeError('Callback must be a function');
|
|
163
189
|
}
|
|
164
190
|
|
|
165
|
-
|
|
191
|
+
handleSignalValue(instance, callback(instance[SYMBOL_STATE].value), setValue);
|
|
166
192
|
}
|
|
167
193
|
|
|
168
194
|
// #endregion
|