@oscarpalmer/mora 0.30.0 → 0.32.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 +29 -18
- package/dist/constants.mjs +19 -2
- package/dist/effect.d.mts +4 -5
- package/dist/effect.mjs +2 -2
- package/dist/helpers/is.d.mts +21 -15
- package/dist/helpers/is.mjs +21 -12
- package/dist/helpers/proxy.d.mts +12 -10
- package/dist/helpers/proxy.mjs +32 -14
- package/dist/helpers/subscription.d.mts +8 -0
- package/dist/helpers/subscription.mjs +27 -0
- package/dist/helpers/value.d.mts +8 -6
- package/dist/helpers/value.mjs +30 -4
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +2 -2
- package/dist/models.d.mts +108 -84
- package/dist/mora.full.mjs +504 -247
- package/dist/value/array.d.mts +4 -5
- package/dist/value/array.mjs +25 -56
- package/dist/value/computed.d.mts +3 -4
- package/dist/value/computed.mjs +14 -14
- package/dist/value/reactive.d.mts +2 -3
- package/dist/value/reactive.mjs +0 -1
- package/dist/value/readonly.d.mts +5 -0
- package/dist/value/readonly.mjs +33 -0
- package/dist/value/signal.d.mts +4 -5
- package/dist/value/signal.mjs +10 -17
- package/dist/value/store.d.mts +4 -5
- package/dist/value/store.mjs +17 -41
- package/package.json +6 -6
- package/src/batch.ts +15 -5
- package/src/constants.ts +41 -3
- package/src/effect.ts +6 -2
- package/src/helpers/is.ts +37 -12
- package/src/helpers/proxy.ts +99 -49
- package/src/helpers/subscription.ts +78 -0
- package/src/helpers/value.ts +69 -4
- package/src/index.ts +18 -2
- package/src/models.ts +131 -86
- package/src/value/array.ts +67 -120
- package/src/value/computed.ts +36 -13
- package/src/value/reactive.ts +8 -5
- package/src/value/readonly.ts +72 -0
- package/src/value/signal.ts +22 -16
- package/src/value/store.ts +37 -70
- 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/src/subscription.ts +0 -45
package/src/helpers/is.ts
CHANGED
|
@@ -5,20 +5,21 @@ import {
|
|
|
5
5
|
NAME_COMPUTED,
|
|
6
6
|
NAME_EFFECT,
|
|
7
7
|
NAME_MORA,
|
|
8
|
+
NAME_READONLY,
|
|
8
9
|
NAME_SIGNAL,
|
|
9
10
|
NAME_STORE,
|
|
10
11
|
} from '../constants';
|
|
11
|
-
import type {
|
|
12
|
+
import type {
|
|
13
|
+
Computed,
|
|
14
|
+
Effect,
|
|
15
|
+
Reactive,
|
|
16
|
+
ReactiveArray,
|
|
17
|
+
ReactiveStore,
|
|
18
|
+
ReadonlySignal,
|
|
19
|
+
Signal,
|
|
20
|
+
} from '../models';
|
|
12
21
|
|
|
13
|
-
|
|
14
|
-
* Is the value a reactive array?
|
|
15
|
-
*
|
|
16
|
-
* @param value Value to check
|
|
17
|
-
* @returns True if value is a {@link ReactiveArray}
|
|
18
|
-
*/
|
|
19
|
-
export function isArray<Item>(value: unknown): value is ReactiveArray<Item> {
|
|
20
|
-
return isMora<ReactiveArray<Item>>(value, NAME_ARRAY);
|
|
21
|
-
}
|
|
22
|
+
// #region Functions
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Is the value a computed signal?
|
|
@@ -40,7 +41,7 @@ export function isEffect(value: unknown): value is Effect {
|
|
|
40
41
|
return isMora<Effect>(value, NAME_EFFECT);
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
function isMora<
|
|
44
|
+
function isMora<Instance>(value: unknown, name: string | Set<string>): value is Instance {
|
|
44
45
|
return (
|
|
45
46
|
typeof value === 'object' &&
|
|
46
47
|
value != null &&
|
|
@@ -71,12 +72,36 @@ export function isSignal<Value>(value: unknown): value is Signal<Value> {
|
|
|
71
72
|
return isMora<Signal<Value>>(value, NAME_SIGNAL);
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Is the value a reactive array?
|
|
77
|
+
*
|
|
78
|
+
* @param value Value to check
|
|
79
|
+
* @returns True if value is a {@link ReactiveArray}
|
|
80
|
+
*/
|
|
81
|
+
export function isReactiveArray<Item>(value: unknown): value is ReactiveArray<Item> {
|
|
82
|
+
return isMora<ReactiveArray<Item>>(value, NAME_ARRAY);
|
|
83
|
+
}
|
|
84
|
+
|
|
74
85
|
/**
|
|
75
86
|
* Is the value a reactive store?
|
|
76
87
|
*
|
|
77
88
|
* @param value Value to check
|
|
78
89
|
* @returns True if value is a {@link Store}
|
|
79
90
|
*/
|
|
80
|
-
export function
|
|
91
|
+
export function isReactiveStore<Value extends PlainObject>(
|
|
92
|
+
value: unknown,
|
|
93
|
+
): value is ReactiveStore<Value> {
|
|
81
94
|
return isMora<ReactiveStore<Value>>(value, NAME_STORE);
|
|
82
95
|
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Is the value a readonly signal?
|
|
99
|
+
*
|
|
100
|
+
* @param value Value to check
|
|
101
|
+
* @returns True if value is a {@link ReadonlySignal}
|
|
102
|
+
*/
|
|
103
|
+
export function isReadonlySignal<Value>(value: unknown): value is ReadonlySignal<Value> {
|
|
104
|
+
return isMora<ReadonlySignal<Value>>(value, NAME_READONLY);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// #endregion
|
package/src/helpers/proxy.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {isKey, isPlainObject} from '@oscarpalmer/atoms/is';
|
|
1
2
|
import type {ArrayOrPlainObject, Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
3
|
import {PROPERTY_LENGTH} from '../constants';
|
|
3
4
|
import type {
|
|
@@ -6,23 +7,30 @@ import type {
|
|
|
6
7
|
ReactiveArray,
|
|
7
8
|
ReactiveState,
|
|
8
9
|
ReactiveStore,
|
|
9
|
-
|
|
10
|
+
Signal,
|
|
10
11
|
} from '../models';
|
|
11
12
|
import {internalComputed} from '../value/computed';
|
|
12
|
-
import {emitValue} from './value';
|
|
13
|
+
import {emitValue, getSimpleValue, peekSimpleValue} from './value';
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
state: ReactiveState<Value, Value>,
|
|
16
|
-
mapped: Map<Key, [Computed<unknown>, ComputedEffect]>,
|
|
17
|
-
): void;
|
|
15
|
+
// #region Types
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
state: ReactiveState<Value
|
|
21
|
-
|
|
22
|
-
)
|
|
17
|
+
type SetObjectCallback<Value, Item> = (
|
|
18
|
+
state: ReactiveState<Value, Item>,
|
|
19
|
+
value: Value | undefined,
|
|
20
|
+
) => void;
|
|
21
|
+
|
|
22
|
+
type SetPropertyCallback<Value, Item> = (
|
|
23
|
+
state: ReactiveState<Value, Item>,
|
|
24
|
+
property: unknown,
|
|
25
|
+
value: Item,
|
|
26
|
+
) => void;
|
|
27
|
+
|
|
28
|
+
// #endregion
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
// #region Functions
|
|
31
|
+
|
|
32
|
+
export function emitProxyValues<Value, Item = Value>(
|
|
33
|
+
state: ReactiveState<Value, Item>,
|
|
26
34
|
mapped: Map<Key, [Computed<unknown>, ComputedEffect]>,
|
|
27
35
|
): void {
|
|
28
36
|
const values = [...mapped.values()];
|
|
@@ -35,27 +43,15 @@ export function emityProxyValues(
|
|
|
35
43
|
emitValue(state);
|
|
36
44
|
}
|
|
37
45
|
|
|
38
|
-
export function getReactiveValueInProxy<Value
|
|
39
|
-
|
|
40
|
-
mapped: Map<Key, [Computed<unknown>, ComputedEffect]>,
|
|
41
|
-
index: number,
|
|
42
|
-
isArray: true,
|
|
43
|
-
): Computed<Result>;
|
|
44
|
-
|
|
45
|
-
export function getReactiveValueInProxy<Value extends PlainObject>(
|
|
46
|
-
store: ReactiveStore<Value>,
|
|
47
|
-
mapped: Map<Key, [Computed<unknown>, ComputedEffect]>,
|
|
48
|
-
key: Key,
|
|
49
|
-
isArray: false,
|
|
50
|
-
): Computed<unknown>;
|
|
51
|
-
|
|
52
|
-
export function getReactiveValueInProxy(
|
|
53
|
-
reactive: ReactiveArray<unknown> | ReactiveStore<PlainObject>,
|
|
46
|
+
export function getReactiveValueInProxy<Value>(
|
|
47
|
+
reactive: ReactiveArray<Value> | ReactiveStore<Value>,
|
|
54
48
|
mapped: Map<Key, [Computed<unknown>, ComputedEffect]>,
|
|
55
49
|
key: Key,
|
|
56
50
|
isArray: boolean,
|
|
57
51
|
): Computed<unknown> {
|
|
58
|
-
|
|
52
|
+
const mapKey = String(key);
|
|
53
|
+
|
|
54
|
+
let item = mapped.get(mapKey);
|
|
59
55
|
|
|
60
56
|
if (item == null) {
|
|
61
57
|
item = internalComputed(() =>
|
|
@@ -64,37 +60,72 @@ export function getReactiveValueInProxy(
|
|
|
64
60
|
: (reactive.get() as PlainObject)[key],
|
|
65
61
|
);
|
|
66
62
|
|
|
67
|
-
mapped.set(
|
|
63
|
+
mapped.set(mapKey, item);
|
|
68
64
|
}
|
|
69
65
|
|
|
70
66
|
return item[0];
|
|
71
67
|
}
|
|
72
68
|
|
|
69
|
+
export function getValueInProxy<Value, Item = Value>(
|
|
70
|
+
isArray: boolean,
|
|
71
|
+
instance: ReactiveArray<Value> | ReactiveStore<Value>,
|
|
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();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return getSimpleValue(state);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function isProxyObject(isArray: boolean, value: unknown): value is ArrayOrPlainObject {
|
|
84
|
+
return value == null || (isArray ? Array.isArray(value) : isPlainObject(value));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function peekValueInProxy<Value, Item = Value>(
|
|
88
|
+
isArray: boolean,
|
|
89
|
+
state: ReactiveState<Value, Item>,
|
|
90
|
+
first?: unknown,
|
|
91
|
+
second?: boolean,
|
|
92
|
+
): unknown {
|
|
93
|
+
let value: unknown;
|
|
94
|
+
|
|
95
|
+
if (isArray ? typeof first === 'number' : isKey(first)) {
|
|
96
|
+
value = isArray
|
|
97
|
+
? (state.value as unknown[]).at(first as number)
|
|
98
|
+
: (state.value as PlainObject)[first as Key];
|
|
99
|
+
} else {
|
|
100
|
+
value = state.value;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return peekSimpleValue(value, first === true || second === true);
|
|
104
|
+
}
|
|
105
|
+
|
|
73
106
|
export function setProxyValue<Value, Item = Value>(
|
|
74
|
-
|
|
107
|
+
isArray: boolean,
|
|
75
108
|
state: ReactiveState<Value, Item>,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
setObject: (state: ReactiveState<Value, Item>, value: Value | undefined) => void,
|
|
79
|
-
setProperty: (state: ReactiveState<Value, Item>, property: unknown, value: Item) => void,
|
|
109
|
+
setObject: SetObjectCallback<Value, Item>,
|
|
110
|
+
setProperty: SetPropertyCallback<Value, Item>,
|
|
80
111
|
first?: unknown,
|
|
81
112
|
second?: unknown,
|
|
82
113
|
): void {
|
|
83
|
-
if (
|
|
114
|
+
if (isArray && first === PROPERTY_LENGTH) {
|
|
84
115
|
(state.value as unknown[]).length = second as number;
|
|
85
116
|
|
|
86
117
|
return;
|
|
87
118
|
}
|
|
88
119
|
|
|
89
|
-
if (
|
|
90
|
-
setObject(state, first);
|
|
120
|
+
if (isProxyObject(isArray, first)) {
|
|
121
|
+
setObject(state, first as Value);
|
|
91
122
|
|
|
92
123
|
return;
|
|
93
124
|
}
|
|
94
125
|
|
|
95
|
-
const property =
|
|
126
|
+
const property = isArray ? typeof first === 'number' : isKey(first);
|
|
96
127
|
|
|
97
|
-
if (
|
|
128
|
+
if (isArray && property && Number.isNaN(first)) {
|
|
98
129
|
return;
|
|
99
130
|
}
|
|
100
131
|
|
|
@@ -127,10 +158,10 @@ export function setProxyValue<Value, Item = Value>(
|
|
|
127
158
|
return;
|
|
128
159
|
}
|
|
129
160
|
|
|
130
|
-
if (!property &&
|
|
161
|
+
if (!property && isProxyObject(isArray, value) && state.promise === actual) {
|
|
131
162
|
state.promise = undefined;
|
|
132
163
|
|
|
133
|
-
setObject(state, value);
|
|
164
|
+
setObject(state, value as Value);
|
|
134
165
|
}
|
|
135
166
|
})
|
|
136
167
|
.catch(() => {
|
|
@@ -142,16 +173,19 @@ export function setProxyValue<Value, Item = Value>(
|
|
|
142
173
|
});
|
|
143
174
|
} else if (property) {
|
|
144
175
|
setProperty(state, first, actual as Item);
|
|
145
|
-
} else if (
|
|
146
|
-
setObject(state, actual);
|
|
176
|
+
} else if (isProxyObject(isArray, actual)) {
|
|
177
|
+
setObject(state, actual as Value);
|
|
147
178
|
}
|
|
148
179
|
}
|
|
149
180
|
|
|
150
|
-
export function setValueInProxy<Value
|
|
151
|
-
|
|
181
|
+
export function setValueInProxy<Value, Item = Value>(
|
|
182
|
+
isArray: boolean,
|
|
183
|
+
state: ReactiveState<Value, Item>,
|
|
184
|
+
target: object,
|
|
185
|
+
property: PropertyKey,
|
|
186
|
+
value: unknown,
|
|
187
|
+
length?: Signal<number>,
|
|
152
188
|
): boolean {
|
|
153
|
-
const {isArray, length, property, state, target, value} = parameters;
|
|
154
|
-
|
|
155
189
|
if (isArray) {
|
|
156
190
|
const isIndex = !Number.isNaN(Number(property));
|
|
157
191
|
const isLength = property === PROPERTY_LENGTH;
|
|
@@ -161,7 +195,7 @@ export function setValueInProxy<Value extends ArrayOrPlainObject, Equal>(
|
|
|
161
195
|
}
|
|
162
196
|
}
|
|
163
197
|
|
|
164
|
-
const previous = Reflect.get(target, property);
|
|
198
|
+
const previous = Reflect.get(target as object, property);
|
|
165
199
|
|
|
166
200
|
if (!state.equal(previous as never, value as never)) {
|
|
167
201
|
Reflect.set(target, property, value);
|
|
@@ -175,3 +209,19 @@ export function setValueInProxy<Value extends ArrayOrPlainObject, Equal>(
|
|
|
175
209
|
|
|
176
210
|
return true;
|
|
177
211
|
}
|
|
212
|
+
|
|
213
|
+
export function updateProxyValue<Value, Item = Value>(
|
|
214
|
+
isArray: boolean,
|
|
215
|
+
state: ReactiveState<Value, Item>,
|
|
216
|
+
setObject: SetObjectCallback<Value, Item>,
|
|
217
|
+
setProperty: SetPropertyCallback<Value, Item>,
|
|
218
|
+
callback: unknown,
|
|
219
|
+
): void {
|
|
220
|
+
if (typeof callback !== 'function') {
|
|
221
|
+
throw new TypeError('Callback must be a function');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
setProxyValue(isArray, state, setObject, setProperty, callback(state.value));
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// #endregion
|
|
@@ -0,0 +1,78 @@
|
|
|
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_TYPES,
|
|
10
|
+
SUBSCRIPTION_TYPES_COPY,
|
|
11
|
+
} from '../constants';
|
|
12
|
+
import type {
|
|
13
|
+
Computed,
|
|
14
|
+
ComputedEffect,
|
|
15
|
+
ReactiveArray,
|
|
16
|
+
ReactiveState,
|
|
17
|
+
ReactiveStore,
|
|
18
|
+
SubscriptionType,
|
|
19
|
+
} from '../models';
|
|
20
|
+
import {getReactiveValueInProxy} from './proxy';
|
|
21
|
+
import {getFrozenValue, peekSimpleValue} from './value';
|
|
22
|
+
|
|
23
|
+
export function subscribeToProxy<Value, Item = Value>(
|
|
24
|
+
isArray: boolean,
|
|
25
|
+
instance: ReactiveArray<Value> | ReactiveStore<Value>,
|
|
26
|
+
state: ReactiveState<Value, Item>,
|
|
27
|
+
mapped: Map<Key, [Computed<unknown>, ComputedEffect]>,
|
|
28
|
+
first: Key | ((value: unknown) => unknown),
|
|
29
|
+
second?: ((value: unknown) => unknown) | boolean,
|
|
30
|
+
third?: boolean,
|
|
31
|
+
): Subscription {
|
|
32
|
+
if (isKey(first)) {
|
|
33
|
+
return getReactiveValueInProxy(instance as never, mapped, first, isArray).subscribe(
|
|
34
|
+
second as never,
|
|
35
|
+
third as never,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return subscribeToSignal(state, first, second === true);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function subscribeToReactive<Value, Item = Value>(
|
|
43
|
+
type: SubscriptionType,
|
|
44
|
+
state: ReactiveState<Value, Item>,
|
|
45
|
+
callback: (value: unknown) => unknown,
|
|
46
|
+
): Subscription {
|
|
47
|
+
state.subscriptions ??= subscriptions({
|
|
48
|
+
keys: SUBSCRIPTION_TYPES,
|
|
49
|
+
property: SUBSCRIPTION_PROPERTY,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const [subscription, existing] = state.subscriptions.create({
|
|
53
|
+
key: type,
|
|
54
|
+
value: callback,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (!existing) {
|
|
58
|
+
callback(
|
|
59
|
+
type === SUBSCRIPTION_TYPE_FROZEN
|
|
60
|
+
? getFrozenValue(state.value)
|
|
61
|
+
: peekSimpleValue(state.value, SUBSCRIPTION_TYPES_COPY.has(type)),
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return subscription;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function subscribeToSignal<Value, Item = Value>(
|
|
69
|
+
state: ReactiveState<Value, Item>,
|
|
70
|
+
callback: (value: unknown) => unknown,
|
|
71
|
+
copy: boolean,
|
|
72
|
+
): Subscription {
|
|
73
|
+
return subscribeToReactive(
|
|
74
|
+
copy ? SUBSCRIPTION_TYPE_COPY : SUBSCRIPTION_TYPE_ORIGINAL,
|
|
75
|
+
state,
|
|
76
|
+
callback,
|
|
77
|
+
);
|
|
78
|
+
}
|
package/src/helpers/value.ts
CHANGED
|
@@ -1,18 +1,41 @@
|
|
|
1
|
+
import {isPlainObject} from '@oscarpalmer/atoms/is';
|
|
1
2
|
import {flushHandlers} from '../batch';
|
|
2
|
-
import {
|
|
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
|
+
} from '../constants';
|
|
3
13
|
import type {ReactiveState} from '../models';
|
|
4
14
|
|
|
15
|
+
// #region Functions
|
|
16
|
+
|
|
5
17
|
export function emitValue<Value>(state: ReactiveState<Value, never>): void {
|
|
6
18
|
for (const computed of state.computeds) {
|
|
7
19
|
computed.dirty = true;
|
|
8
20
|
}
|
|
9
21
|
|
|
10
22
|
for (const effect of state.effects) {
|
|
11
|
-
BATCH.handlers.
|
|
23
|
+
BATCH.handlers.set(effect, effect);
|
|
12
24
|
}
|
|
13
25
|
|
|
14
|
-
for (const
|
|
15
|
-
|
|
26
|
+
for (const type of SUBSCRIPTION_TYPES) {
|
|
27
|
+
const subscriptions = state.subscriptions?.values.to.keyed?.get(type);
|
|
28
|
+
|
|
29
|
+
if (subscriptions != null) {
|
|
30
|
+
for (const [subscription, callback] of subscriptions) {
|
|
31
|
+
BATCH.handlers.set(subscription, {
|
|
32
|
+
callback,
|
|
33
|
+
state,
|
|
34
|
+
frozen: type === SUBSCRIPTION_TYPE_FROZEN,
|
|
35
|
+
copy: SUBSCRIPTION_TYPES_COPY.has(type),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
16
39
|
}
|
|
17
40
|
|
|
18
41
|
if (BATCH.depth === 0) {
|
|
@@ -55,6 +78,18 @@ export function equalArrays<Value>(
|
|
|
55
78
|
return true;
|
|
56
79
|
}
|
|
57
80
|
|
|
81
|
+
export function getFrozenValue(value: unknown): unknown {
|
|
82
|
+
let frozen = value;
|
|
83
|
+
|
|
84
|
+
if (Array.isArray(frozen)) {
|
|
85
|
+
frozen = Object.freeze(frozen.slice());
|
|
86
|
+
} else if (isPlainObject(frozen)) {
|
|
87
|
+
frozen = Object.freeze({...frozen});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return frozen;
|
|
91
|
+
}
|
|
92
|
+
|
|
58
93
|
export function getSimpleValue<Value>(state: ReactiveState<Value, never>): Value {
|
|
59
94
|
if (ACTIVE.computed != null) {
|
|
60
95
|
state.computeds.add(ACTIVE.computed);
|
|
@@ -101,3 +136,33 @@ export function handleSimpleValue<Value>(
|
|
|
101
136
|
onAfter?.();
|
|
102
137
|
}
|
|
103
138
|
}
|
|
139
|
+
|
|
140
|
+
export function peekSimpleValue(value: unknown, copy: boolean): unknown {
|
|
141
|
+
let peeked: unknown = value;
|
|
142
|
+
|
|
143
|
+
if (!copy) {
|
|
144
|
+
return peeked;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (Array.isArray(peeked)) {
|
|
148
|
+
peeked = peeked.slice();
|
|
149
|
+
} else if (isPlainObject(peeked)) {
|
|
150
|
+
peeked = {...peeked};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return peeked;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function updateSimpleValue<Value>(
|
|
157
|
+
state: ReactiveState<Value, Value>,
|
|
158
|
+
callback: (value: Value) => Value,
|
|
159
|
+
setValue: (state: ReactiveState<Value, Value>, value: Value) => void,
|
|
160
|
+
): void {
|
|
161
|
+
if (typeof callback !== 'function') {
|
|
162
|
+
throw new TypeError('Callback must be a function');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
handleSimpleValue(state, callback(state.value), setValue);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// #endregion
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,23 @@
|
|
|
1
|
+
export type {Subscription} from '@oscarpalmer/atoms/subscription';
|
|
1
2
|
export {startBatch, stopBatch} from './batch';
|
|
2
3
|
export {effect} from './effect';
|
|
3
|
-
export {
|
|
4
|
-
|
|
4
|
+
export {
|
|
5
|
+
isComputed,
|
|
6
|
+
isEffect,
|
|
7
|
+
isReactive,
|
|
8
|
+
isReactiveArray,
|
|
9
|
+
isReactiveStore,
|
|
10
|
+
isReadonlySignal,
|
|
11
|
+
isSignal,
|
|
12
|
+
} from './helpers/is';
|
|
13
|
+
export type {
|
|
14
|
+
Computed,
|
|
15
|
+
Effect,
|
|
16
|
+
ReactiveArray,
|
|
17
|
+
ReactiveStore,
|
|
18
|
+
ReadonlySignal,
|
|
19
|
+
Signal,
|
|
20
|
+
} from './models';
|
|
5
21
|
export {array} from './value/array';
|
|
6
22
|
export {computed} from './value/computed';
|
|
7
23
|
export {signal} from './value/signal';
|