@oscarpalmer/mora 0.31.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.d.mts +4 -5
- package/dist/batch.mjs +4 -2
- package/dist/constants.d.mts +31 -19
- package/dist/constants.mjs +19 -2
- package/dist/effect.d.mts +5 -5
- package/dist/effect.mjs +8 -5
- package/dist/helpers/is.d.mts +14 -9
- package/dist/helpers/is.mjs +6 -0
- package/dist/helpers/misc.d.mts +4 -0
- package/dist/helpers/misc.mjs +9 -0
- package/dist/helpers/proxy.d.mts +10 -10
- package/dist/helpers/proxy.mjs +83 -27
- package/dist/helpers/subscription.d.mts +8 -0
- package/dist/helpers/subscription.mjs +30 -0
- package/dist/helpers/value.d.mts +10 -7
- package/dist/helpers/value.mjs +56 -17
- package/dist/index.d.mts +3 -2
- package/dist/models.d.mts +82 -101
- package/dist/models.mjs +1 -0
- package/dist/mora.full.mjs +659 -412
- package/dist/value/array.d.mts +5 -5
- package/dist/value/array.mjs +70 -109
- package/dist/value/computed.d.mts +5 -4
- package/dist/value/computed.mjs +45 -31
- package/dist/value/readonly.d.mts +4 -6
- package/dist/value/readonly.mjs +34 -31
- package/dist/value/signal.d.mts +5 -5
- package/dist/value/signal.mjs +28 -34
- package/dist/value/store.d.mts +5 -5
- package/dist/value/store.mjs +25 -83
- package/package.json +6 -6
- package/src/batch.ts +15 -5
- package/src/constants.ts +36 -2
- package/src/effect.ts +20 -11
- package/src/helpers/is.ts +16 -6
- package/src/helpers/misc.ts +15 -0
- package/src/helpers/proxy.ts +151 -74
- package/src/helpers/subscription.ts +89 -0
- package/src/helpers/value.ts +121 -30
- package/src/index.ts +1 -1
- package/src/models.ts +81 -98
- package/src/value/array.ts +116 -226
- package/src/value/computed.ts +96 -43
- package/src/value/readonly.ts +68 -54
- package/src/value/signal.ts +54 -46
- package/src/value/store.ts +42 -168
- package/types/constants.d.ts +1 -1
- package/types/index.d.ts +1 -1
- package/types/value/array.d.ts +1 -1
- package/types/value/computed.d.ts +0 -3
- package/types/value/signal.d.ts +1 -1
- package/types/value/store.d.ts +1 -1
- package/dist/subscription.d.mts +0 -7
- package/dist/subscription.mjs +0 -27
- package/dist/value/reactive.d.mts +0 -5
- package/dist/value/reactive.mjs +0 -16
- package/src/subscription.ts +0 -45
- package/src/value/reactive.ts +0 -24
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {isKey} from '@oscarpalmer/atoms/is';
|
|
2
|
+
import type {Key} from '@oscarpalmer/atoms/models';
|
|
3
|
+
import {subscriptions, type Subscription} from '@oscarpalmer/atoms/subscription';
|
|
4
|
+
import {
|
|
5
|
+
SUBSCRIPTION_PROPERTY,
|
|
6
|
+
SUBSCRIPTION_TYPE_COPY,
|
|
7
|
+
SUBSCRIPTION_TYPE_FROZEN,
|
|
8
|
+
SUBSCRIPTION_TYPE_ORIGINAL,
|
|
9
|
+
SUBSCRIPTION_TYPE_READONLY,
|
|
10
|
+
SUBSCRIPTION_TYPES,
|
|
11
|
+
SUBSCRIPTION_TYPES_COPY,
|
|
12
|
+
SYMBOL_STATE,
|
|
13
|
+
} from '../constants';
|
|
14
|
+
import type {
|
|
15
|
+
InternalProxy,
|
|
16
|
+
InternalReadonly,
|
|
17
|
+
InternalSignal,
|
|
18
|
+
Subscriber,
|
|
19
|
+
SubscriptionType,
|
|
20
|
+
} from '../models';
|
|
21
|
+
import {getReactiveValueInProxy} from './proxy';
|
|
22
|
+
import {getFrozenValue, peekSignalValue} from './value';
|
|
23
|
+
|
|
24
|
+
// #region Functions
|
|
25
|
+
|
|
26
|
+
export function subscribeToProxy(
|
|
27
|
+
this: InternalProxy,
|
|
28
|
+
first: Key | Subscriber<unknown>,
|
|
29
|
+
second?: Subscriber<unknown> | boolean,
|
|
30
|
+
third?: boolean,
|
|
31
|
+
): Subscription {
|
|
32
|
+
if (isKey(first)) {
|
|
33
|
+
return getReactiveValueInProxy(this as never, first).subscribe(second as never, third as never);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return subscribeToSignal.call(this, first, second);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function subscribeToReactive(
|
|
40
|
+
this: InternalSignal,
|
|
41
|
+
type: SubscriptionType,
|
|
42
|
+
subscriber: Subscriber<unknown>,
|
|
43
|
+
): Subscription {
|
|
44
|
+
this[SYMBOL_STATE].subscriptions ??= subscriptions({
|
|
45
|
+
keys: SUBSCRIPTION_TYPES,
|
|
46
|
+
property: SUBSCRIPTION_PROPERTY,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const [subscription, existing] = this[SYMBOL_STATE].subscriptions.create({
|
|
50
|
+
key: type,
|
|
51
|
+
value: subscriber,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
if (!existing) {
|
|
55
|
+
subscriber(
|
|
56
|
+
type === SUBSCRIPTION_TYPE_FROZEN
|
|
57
|
+
? getFrozenValue(this[SYMBOL_STATE].value)
|
|
58
|
+
: peekSignalValue.call(this, SUBSCRIPTION_TYPES_COPY.has(type)),
|
|
59
|
+
subscription,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return subscription;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function subscribeToReadonly(
|
|
67
|
+
this: InternalReadonly,
|
|
68
|
+
subscriber: Subscriber<unknown>,
|
|
69
|
+
): Subscription {
|
|
70
|
+
return subscribeToReactive.call(
|
|
71
|
+
this,
|
|
72
|
+
this.frozen ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_READONLY,
|
|
73
|
+
subscriber,
|
|
74
|
+
);
|
|
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
|
@@ -1,18 +1,49 @@
|
|
|
1
|
+
import {isPlainObject} from '@oscarpalmer/atoms/is';
|
|
1
2
|
import {flushHandlers} from '../batch';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import {
|
|
4
|
+
ACTIVE,
|
|
5
|
+
ARRAY_OFFSET,
|
|
6
|
+
ARRAY_PEEK,
|
|
7
|
+
ARRAY_THRESHOLD,
|
|
8
|
+
BATCH,
|
|
9
|
+
SUBSCRIPTION_TYPES_COPY,
|
|
10
|
+
SUBSCRIPTION_TYPE_FROZEN,
|
|
11
|
+
SUBSCRIPTION_TYPES,
|
|
12
|
+
SYMBOL_STATE,
|
|
13
|
+
} from '../constants';
|
|
14
|
+
import type {ReactiveState, InternalSignal} from '../models';
|
|
15
|
+
|
|
16
|
+
// #region Functions
|
|
17
|
+
|
|
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
|
+
}
|
|
8
25
|
}
|
|
9
26
|
|
|
10
|
-
|
|
11
|
-
|
|
27
|
+
if (state.effects != null && state.effects.size > 0) {
|
|
28
|
+
for (const effect of state.effects) {
|
|
29
|
+
BATCH.handlers.set(effect, effect);
|
|
30
|
+
}
|
|
12
31
|
}
|
|
13
32
|
|
|
14
|
-
for (const
|
|
15
|
-
|
|
33
|
+
for (const type of SUBSCRIPTION_TYPES) {
|
|
34
|
+
const subscriptions = state.subscriptions?.values.to.keyed?.get(type);
|
|
35
|
+
|
|
36
|
+
if (subscriptions != null && subscriptions.size > 0) {
|
|
37
|
+
for (const [subscription, callback] of subscriptions) {
|
|
38
|
+
BATCH.handlers.set(subscription, {
|
|
39
|
+
callback,
|
|
40
|
+
instance,
|
|
41
|
+
state,
|
|
42
|
+
frozen: type === SUBSCRIPTION_TYPE_FROZEN,
|
|
43
|
+
copy: SUBSCRIPTION_TYPES_COPY.has(type),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
16
47
|
}
|
|
17
48
|
|
|
18
49
|
if (BATCH.depth === 0) {
|
|
@@ -20,17 +51,15 @@ export function emitValue<Value>(state: ReactiveState<Value, never>): void {
|
|
|
20
51
|
}
|
|
21
52
|
}
|
|
22
53
|
|
|
23
|
-
export function equalArrays
|
|
24
|
-
|
|
25
|
-
first: Value[],
|
|
26
|
-
second: Value[],
|
|
27
|
-
): boolean {
|
|
28
|
-
let {length} = first;
|
|
54
|
+
export function equalArrays(state: ReactiveState, first: unknown[], second: unknown[]): boolean {
|
|
55
|
+
const {length} = first;
|
|
29
56
|
|
|
30
57
|
if (length !== second.length) {
|
|
31
58
|
return false;
|
|
32
59
|
}
|
|
33
60
|
|
|
61
|
+
const eq = state.equal ?? Object.is;
|
|
62
|
+
|
|
34
63
|
let offset = 0;
|
|
35
64
|
|
|
36
65
|
if (length >= ARRAY_THRESHOLD) {
|
|
@@ -38,16 +67,21 @@ export function equalArrays<Value>(
|
|
|
38
67
|
offset = offset > ARRAY_OFFSET ? ARRAY_OFFSET : offset;
|
|
39
68
|
|
|
40
69
|
for (let index = 0; index < offset; index += 1) {
|
|
41
|
-
if (
|
|
70
|
+
if (
|
|
71
|
+
!(
|
|
72
|
+
eq(first[index], second[index]) &&
|
|
73
|
+
eq(first[length - index - 1], second[length - index - 1])
|
|
74
|
+
)
|
|
75
|
+
) {
|
|
42
76
|
return false;
|
|
43
77
|
}
|
|
44
78
|
}
|
|
45
79
|
}
|
|
46
80
|
|
|
47
|
-
length
|
|
81
|
+
const end = length - offset;
|
|
48
82
|
|
|
49
|
-
for (let index = offset; index <
|
|
50
|
-
if (!
|
|
83
|
+
for (let index = offset; index < end; index += 1) {
|
|
84
|
+
if (!eq(first[index], second[index])) {
|
|
51
85
|
return false;
|
|
52
86
|
}
|
|
53
87
|
}
|
|
@@ -55,24 +89,48 @@ export function equalArrays<Value>(
|
|
|
55
89
|
return true;
|
|
56
90
|
}
|
|
57
91
|
|
|
58
|
-
export function
|
|
92
|
+
export function getFrozenValue(value: unknown): unknown {
|
|
93
|
+
let frozen = value;
|
|
94
|
+
|
|
95
|
+
if (Array.isArray(frozen)) {
|
|
96
|
+
frozen = Object.freeze(frozen.slice());
|
|
97
|
+
} else if (isPlainObject(frozen)) {
|
|
98
|
+
frozen = Object.freeze({...frozen});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return frozen;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function getSignalValue(this: InternalSignal): unknown {
|
|
59
105
|
if (ACTIVE.computed != null) {
|
|
60
|
-
|
|
106
|
+
this[SYMBOL_STATE].computeds ??= new Set();
|
|
107
|
+
|
|
108
|
+
this[SYMBOL_STATE].computeds.add(ACTIVE.computed);
|
|
61
109
|
}
|
|
62
110
|
|
|
63
111
|
if (ACTIVE.effect != null) {
|
|
64
|
-
|
|
112
|
+
this[SYMBOL_STATE].effects ??= new Set();
|
|
113
|
+
|
|
114
|
+
this[SYMBOL_STATE].effects.add(ACTIVE.effect);
|
|
65
115
|
}
|
|
66
116
|
|
|
67
|
-
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);
|
|
68
124
|
}
|
|
69
125
|
|
|
70
|
-
export function
|
|
71
|
-
|
|
72
|
-
origin:
|
|
73
|
-
setValue: (
|
|
126
|
+
export function handleSignalValue(
|
|
127
|
+
instance: InternalSignal,
|
|
128
|
+
origin: unknown,
|
|
129
|
+
setValue: (instance: InternalSignal, value: unknown) => void,
|
|
74
130
|
onAfter?: () => void,
|
|
75
131
|
): void {
|
|
132
|
+
const state = instance[SYMBOL_STATE];
|
|
133
|
+
|
|
76
134
|
try {
|
|
77
135
|
let actual = typeof origin === 'function' ? (origin as () => unknown)() : origin;
|
|
78
136
|
|
|
@@ -84,7 +142,7 @@ export function handleSimpleValue<Value>(
|
|
|
84
142
|
if (actual === state.promise) {
|
|
85
143
|
state.promise = undefined;
|
|
86
144
|
|
|
87
|
-
setValue(
|
|
145
|
+
setValue(instance, value);
|
|
88
146
|
}
|
|
89
147
|
})
|
|
90
148
|
.catch(() => {
|
|
@@ -93,7 +151,7 @@ export function handleSimpleValue<Value>(
|
|
|
93
151
|
}
|
|
94
152
|
});
|
|
95
153
|
} else {
|
|
96
|
-
setValue(
|
|
154
|
+
setValue(instance, actual);
|
|
97
155
|
}
|
|
98
156
|
} catch {
|
|
99
157
|
// ?
|
|
@@ -101,3 +159,36 @@ export function handleSimpleValue<Value>(
|
|
|
101
159
|
onAfter?.();
|
|
102
160
|
}
|
|
103
161
|
}
|
|
162
|
+
|
|
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;
|
|
168
|
+
|
|
169
|
+
if (copy !== true) {
|
|
170
|
+
return peeked;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (Array.isArray(peeked)) {
|
|
174
|
+
peeked = peeked.slice();
|
|
175
|
+
} else if (isPlainObject(peeked)) {
|
|
176
|
+
peeked = {...peeked};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return peeked;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function updateSignalValue(
|
|
183
|
+
instance: InternalSignal,
|
|
184
|
+
callback: (value: unknown) => unknown,
|
|
185
|
+
setValue: (instance: InternalSignal, value: unknown) => void,
|
|
186
|
+
): void {
|
|
187
|
+
if (typeof callback !== 'function') {
|
|
188
|
+
throw new TypeError('Callback must be a function');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
handleSignalValue(instance, callback(instance[SYMBOL_STATE].value), setValue);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// #endregion
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type {Subscription} from '@oscarpalmer/atoms/subscription';
|
|
1
2
|
export {startBatch, stopBatch} from './batch';
|
|
2
3
|
export {effect} from './effect';
|
|
3
4
|
export {
|
|
@@ -16,7 +17,6 @@ export type {
|
|
|
16
17
|
ReactiveStore,
|
|
17
18
|
ReadonlySignal,
|
|
18
19
|
Signal,
|
|
19
|
-
Unsubscribe,
|
|
20
20
|
} from './models';
|
|
21
21
|
export {array} from './value/array';
|
|
22
22
|
export {computed} from './value/computed';
|
package/src/models.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type {GenericCallback, Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
-
import type {
|
|
2
|
+
import type {Subscription, Subscriptions} from '@oscarpalmer/atoms/subscription';
|
|
3
|
+
import {SYMBOL_EFFECT, SYMBOL_STATE, type PROPERTY_LENGTH} from './constants';
|
|
4
|
+
|
|
5
|
+
// #region Types
|
|
3
6
|
|
|
4
7
|
export type Active = {
|
|
5
8
|
computed?: ComputedEffect;
|
|
@@ -9,7 +12,7 @@ export type Active = {
|
|
|
9
12
|
export type Batch = {
|
|
10
13
|
depth: number;
|
|
11
14
|
flushing: boolean;
|
|
12
|
-
handlers:
|
|
15
|
+
handlers: Map<EffectState | Subscription, EffectState | StoredSubscription>;
|
|
13
16
|
};
|
|
14
17
|
|
|
15
18
|
export type Computed<Value> = Reactive<Value> & SimpleReactive<Value>;
|
|
@@ -25,20 +28,37 @@ export type EffectState = {
|
|
|
25
28
|
callback: GenericCallback;
|
|
26
29
|
};
|
|
27
30
|
|
|
31
|
+
export type InternalComputed = {
|
|
32
|
+
[SYMBOL_EFFECT]: ComputedEffect;
|
|
33
|
+
} & InternalSignal;
|
|
34
|
+
|
|
35
|
+
export type InternalProxy = {
|
|
36
|
+
[SYMBOL_STATE]: ReactiveProxyState;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type InternalReadonly = {
|
|
40
|
+
frozen: boolean;
|
|
41
|
+
} & InternalSignal;
|
|
42
|
+
|
|
43
|
+
export type InternalSignal = {
|
|
44
|
+
[SYMBOL_STATE]: SignalState;
|
|
45
|
+
};
|
|
46
|
+
|
|
28
47
|
export type Reactive<Value> = {
|
|
29
48
|
/**
|
|
30
|
-
*
|
|
49
|
+
* _JSON_ representation of the value
|
|
31
50
|
*
|
|
32
|
-
* @returns
|
|
51
|
+
* @returns _JSON_ value
|
|
33
52
|
*/
|
|
34
53
|
toJSON(): Value;
|
|
35
54
|
|
|
36
55
|
/**
|
|
37
56
|
* String representation of the value
|
|
38
57
|
*
|
|
58
|
+
* @param json When `true`, returns the _JSON_ string representation of the value _(defaults to `false`)_
|
|
39
59
|
* @returns Value as string
|
|
40
60
|
*/
|
|
41
|
-
toString(): string;
|
|
61
|
+
toString(json?: boolean): string;
|
|
42
62
|
};
|
|
43
63
|
|
|
44
64
|
export type ReactiveArray<Item> = {
|
|
@@ -227,19 +247,21 @@ export type ReactiveArray<Item> = {
|
|
|
227
247
|
/**
|
|
228
248
|
* Subscribe to changes
|
|
229
249
|
*
|
|
230
|
-
* @param
|
|
231
|
-
* @
|
|
250
|
+
* @param subscriber Callback for changes
|
|
251
|
+
* @param copy Copy the array? _(defaults to `false`)_
|
|
252
|
+
* @returns Subscription
|
|
232
253
|
*/
|
|
233
|
-
subscribe(
|
|
254
|
+
subscribe(subscriber: Subscriber<Item[]>, copy?: boolean): Subscription;
|
|
234
255
|
|
|
235
256
|
/**
|
|
236
257
|
* Subscribe to changes at a specific index
|
|
237
258
|
*
|
|
238
259
|
* @param index Index of item to subscribe to
|
|
239
|
-
* @param
|
|
240
|
-
* @
|
|
260
|
+
* @param subscriber Callback for changes
|
|
261
|
+
* @param copy If the item is an array or record, should it be copied? _(defaults to `false`)_
|
|
262
|
+
* @returns Subscription
|
|
241
263
|
*/
|
|
242
|
-
subscribe(index: number,
|
|
264
|
+
subscribe(index: number, subscriber: Subscriber<Item | undefined>, copy?: boolean): Subscription;
|
|
243
265
|
|
|
244
266
|
/**
|
|
245
267
|
* Add items to the beginning of the array
|
|
@@ -248,21 +270,6 @@ export type ReactiveArray<Item> = {
|
|
|
248
270
|
*/
|
|
249
271
|
unshift(...items: Item[]): number;
|
|
250
272
|
|
|
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
273
|
/**
|
|
267
274
|
* Update the value _(based on the current value)_
|
|
268
275
|
*
|
|
@@ -282,14 +289,20 @@ export type ReactiveOptions<Value> = {
|
|
|
282
289
|
equal?: (first: Value, second: Value) => boolean;
|
|
283
290
|
};
|
|
284
291
|
|
|
285
|
-
export type
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
292
|
+
export type ReactiveProxyState = {
|
|
293
|
+
isArray: boolean;
|
|
294
|
+
length?: Signal<number>;
|
|
295
|
+
mapped?: Map<string, [Computed<unknown>, ComputedEffect]>;
|
|
296
|
+
} & SignalState;
|
|
297
|
+
|
|
298
|
+
export type ReactiveState = {
|
|
299
|
+
computeds?: Set<ComputedEffect>;
|
|
300
|
+
effects?: Set<EffectState>;
|
|
301
|
+
equal?: (first: unknown, second: unknown) => boolean;
|
|
302
|
+
promise?: Promise<unknown>;
|
|
290
303
|
promises?: Map<Key, Promise<never>>;
|
|
291
|
-
subscriptions
|
|
292
|
-
value:
|
|
304
|
+
subscriptions?: Subscriptions<GenericCallback>;
|
|
305
|
+
value: unknown;
|
|
293
306
|
};
|
|
294
307
|
|
|
295
308
|
export type ReactiveStore<Store> = {
|
|
@@ -402,57 +415,35 @@ export type ReactiveStore<Store> = {
|
|
|
402
415
|
/**
|
|
403
416
|
* Subscribe to changes
|
|
404
417
|
*
|
|
405
|
-
* @param
|
|
406
|
-
* @
|
|
418
|
+
* @param subscriber Callback for changes
|
|
419
|
+
* @param copy Copy the store? _(defaults to `false`)_
|
|
420
|
+
* @returns Subscription
|
|
407
421
|
*/
|
|
408
|
-
subscribe(
|
|
422
|
+
subscribe(subscriber: Subscriber<Store>, copy?: boolean): Subscription;
|
|
409
423
|
|
|
410
424
|
/**
|
|
411
425
|
* Subscribe to changes for a specific key
|
|
412
426
|
*
|
|
413
427
|
* @param key Key of the value to subscribe to
|
|
414
|
-
* @param
|
|
415
|
-
* @
|
|
428
|
+
* @param subscriber Callback for changes
|
|
429
|
+
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
430
|
+
* @returns Subscription
|
|
416
431
|
*/
|
|
417
432
|
subscribe<Key extends keyof Store>(
|
|
418
433
|
key: Key,
|
|
419
|
-
|
|
420
|
-
|
|
434
|
+
subscriber: Subscriber<Store[Key] | undefined>,
|
|
435
|
+
copy?: boolean,
|
|
436
|
+
): Subscription;
|
|
421
437
|
|
|
422
438
|
/**
|
|
423
439
|
* Subscribe to changes for a specific key
|
|
424
440
|
*
|
|
425
441
|
* @param key Key of the value to subscribe to
|
|
426
|
-
* @param
|
|
427
|
-
* @
|
|
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
|
|
442
|
+
* @param subscriber Callback for changes
|
|
443
|
+
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
444
|
+
* @returns Subscription
|
|
454
445
|
*/
|
|
455
|
-
|
|
446
|
+
subscribe(key: Key, subscriber: Subscriber<unknown>, copy?: boolean): Subscription;
|
|
456
447
|
|
|
457
448
|
/**
|
|
458
449
|
* Update the value _(based on the current value)_
|
|
@@ -462,7 +453,7 @@ export type ReactiveStore<Store> = {
|
|
|
462
453
|
update(callback: (value: Store) => Store): void;
|
|
463
454
|
} & Reactive<Store>;
|
|
464
455
|
|
|
465
|
-
|
|
456
|
+
type ReadonlyInstances<Value> = {
|
|
466
457
|
frozen?: ReadonlyFrozenSignal<Value>;
|
|
467
458
|
original?: ReadonlySignal<Value>;
|
|
468
459
|
};
|
|
@@ -483,15 +474,6 @@ export type ReadonlySignalValue<Value> = Value extends unknown[]
|
|
|
483
474
|
? Readonly<Value>
|
|
484
475
|
: Value;
|
|
485
476
|
|
|
486
|
-
export type SetValueInProxyParameters<Value, Equal> = {
|
|
487
|
-
target: Value;
|
|
488
|
-
property: PropertyKey;
|
|
489
|
-
value: unknown;
|
|
490
|
-
state: ReactiveState<Value, Equal>;
|
|
491
|
-
isArray: boolean;
|
|
492
|
-
length?: Signal<number>;
|
|
493
|
-
};
|
|
494
|
-
|
|
495
477
|
export type Signal<Value> = {
|
|
496
478
|
/**
|
|
497
479
|
* Get a readonly version of the signal
|
|
@@ -527,6 +509,10 @@ export type Signal<Value> = {
|
|
|
527
509
|
} & Reactive<Value> &
|
|
528
510
|
SimpleReactive<Value>;
|
|
529
511
|
|
|
512
|
+
export type SignalState = {
|
|
513
|
+
readonlies?: ReadonlyInstances<unknown>;
|
|
514
|
+
} & ReactiveState;
|
|
515
|
+
|
|
530
516
|
type SimpleReactive<Value> = {
|
|
531
517
|
/**
|
|
532
518
|
* Get the value
|
|
@@ -538,34 +524,31 @@ type SimpleReactive<Value> = {
|
|
|
538
524
|
/**
|
|
539
525
|
* Get the value _(without reactivity)_
|
|
540
526
|
*
|
|
527
|
+
* @param copy If the value is an array or record, should it be copied? _(defaults to `false`)_
|
|
541
528
|
* @returns Current value
|
|
542
529
|
*/
|
|
543
|
-
peek(): Value;
|
|
530
|
+
peek(copy?: boolean): Value;
|
|
544
531
|
|
|
545
532
|
/**
|
|
546
533
|
* Subscribe to changes
|
|
547
534
|
*
|
|
548
|
-
* @param
|
|
549
|
-
* @
|
|
550
|
-
|
|
551
|
-
subscribe(callback: (value: Value) => void): Unsubscribe;
|
|
552
|
-
|
|
553
|
-
/**
|
|
554
|
-
* Unsubscribe from changes
|
|
555
|
-
*
|
|
556
|
-
* @param callback Callback to unsubscribe
|
|
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
|
|
557
538
|
*/
|
|
558
|
-
|
|
539
|
+
subscribe(subscriber: Subscriber<Value>, copy?: boolean): Subscription;
|
|
559
540
|
};
|
|
560
541
|
|
|
561
|
-
export type
|
|
542
|
+
export type StoredSubscription = {
|
|
562
543
|
callback: GenericCallback;
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
544
|
+
copy: boolean;
|
|
545
|
+
frozen: boolean;
|
|
546
|
+
instance: InternalSignal;
|
|
547
|
+
state: SignalState;
|
|
566
548
|
};
|
|
567
549
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
550
|
+
export type Subscriber<Value> = (value: Value, subscription: Subscription) => void;
|
|
551
|
+
|
|
552
|
+
export type SubscriptionType = 'copy' | 'frozen' | 'original' | 'readonly';
|
|
553
|
+
|
|
554
|
+
// #endregion
|