@oscarpalmer/mora 0.38.0 → 0.39.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 +1 -3
- package/dist/batch.mjs +3 -4
- package/dist/constants.d.mts +16 -10
- package/dist/constants.mjs +12 -6
- package/dist/effect.d.mts +2 -3
- package/dist/effect.mjs +27 -8
- package/dist/helpers/is.d.mts +1 -3
- package/dist/helpers/is.mjs +8 -5
- package/dist/helpers/misc.d.mts +8 -4
- package/dist/helpers/misc.mjs +66 -4
- package/dist/helpers/proxy.d.mts +3 -4
- package/dist/helpers/proxy.mjs +26 -11
- package/dist/helpers/subscription.d.mts +1 -3
- package/dist/helpers/subscription.mjs +15 -7
- package/dist/helpers/value.d.mts +4 -5
- package/dist/helpers/value.mjs +18 -13
- package/dist/models.d.mts +38 -5
- package/dist/mora.full.mjs +555 -276
- package/dist/value/array.d.mts +1 -3
- package/dist/value/array.mjs +46 -22
- package/dist/value/computed.d.mts +1 -3
- package/dist/value/computed.mjs +17 -11
- package/dist/value/readonly.d.mts +2 -5
- package/dist/value/readonly.mjs +24 -16
- package/dist/value/signal.d.mts +1 -3
- package/dist/value/signal.mjs +9 -6
- package/dist/value/store.d.mts +1 -3
- package/dist/value/store.mjs +9 -6
- package/package.json +5 -12
- package/src/batch.ts +8 -4
- package/src/constants.ts +26 -16
- package/src/effect.ts +37 -7
- package/src/helpers/is.ts +18 -8
- package/src/helpers/misc.ts +121 -2
- package/src/helpers/proxy.ts +59 -9
- package/src/helpers/subscription.ts +34 -4
- package/src/helpers/value.ts +48 -15
- package/src/models.ts +42 -3
- package/src/value/array.ts +100 -21
- package/src/value/computed.ts +29 -10
- package/src/value/readonly.ts +38 -33
- package/src/value/signal.ts +11 -5
- package/src/value/store.ts +11 -5
- package/types/batch.d.ts +0 -11
- package/types/constants.d.ts +0 -16
- package/types/effect.d.ts +0 -13
- package/types/helpers/is.d.ts +0 -43
- package/types/helpers/proxy.d.ts +0 -11
- package/types/helpers/value.d.ts +0 -4
- package/types/index.d.ts +0 -9
- package/types/models.d.ts +0 -56
- package/types/subscription.d.ts +0 -11
- package/types/value/array.d.ts +0 -137
- package/types/value/computed.d.ts +0 -14
- package/types/value/reactive.d.ts +0 -36
- package/types/value/signal.d.ts +0 -26
- package/types/value/store.d.ts +0 -94
package/src/value/array.ts
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
import {filter} from '@oscarpalmer/atoms/array/filter';
|
|
2
2
|
import {select} from '@oscarpalmer/atoms/array/select';
|
|
3
3
|
import {
|
|
4
|
+
MESSAGE_DEACTIVATED_ARRAY_FILTER,
|
|
5
|
+
MESSAGE_DEACTIVATED_ARRAY_MAP,
|
|
6
|
+
MESSAGE_DEACTIVATED_ARRAY_SELECT,
|
|
4
7
|
METHODS_AFFECTING_LENGTH,
|
|
5
8
|
METHODS_UPDATE,
|
|
6
9
|
NAME_ARRAY,
|
|
7
|
-
NAME_MORA,
|
|
8
10
|
PROPERTY_LENGTH,
|
|
9
11
|
SYMBOL_STATE,
|
|
10
12
|
} from '../constants';
|
|
11
|
-
import {getState} from '../helpers/misc';
|
|
13
|
+
import {deactivateProxy, getReactiveActive, getState} from '../helpers/misc';
|
|
12
14
|
import {
|
|
13
15
|
getValueInProxy,
|
|
14
16
|
notifyProxyValue,
|
|
15
17
|
peekValueInProxy,
|
|
16
18
|
setProxyValue,
|
|
17
19
|
setValueInProxy,
|
|
20
|
+
updateProxyDerivations,
|
|
18
21
|
updateProxyValue,
|
|
19
22
|
} from '../helpers/proxy';
|
|
20
23
|
import {subscribeToProxy} from '../helpers/subscription';
|
|
@@ -28,7 +31,7 @@ import {signal} from './signal';
|
|
|
28
31
|
|
|
29
32
|
function ReactiveArray(this: any, value: unknown, options?: ReactiveOptions<unknown>): void {
|
|
30
33
|
this[SYMBOL_STATE] = {
|
|
31
|
-
...getState(undefined, options),
|
|
34
|
+
...getState(NAME_ARRAY, undefined, options),
|
|
32
35
|
isArray: true,
|
|
33
36
|
length: signal(0),
|
|
34
37
|
};
|
|
@@ -44,17 +47,10 @@ function ReactiveArray(this: any, value: unknown, options?: ReactiveOptions<unkn
|
|
|
44
47
|
setProxyValue.call(this, value);
|
|
45
48
|
}
|
|
46
49
|
|
|
47
|
-
ReactiveArray.prototype[NAME_MORA] = NAME_ARRAY;
|
|
48
|
-
|
|
49
|
-
Object.defineProperty(ReactiveArray.prototype, PROPERTY_LENGTH, {
|
|
50
|
-
enumerable: true,
|
|
51
|
-
get: getArrayLength,
|
|
52
|
-
set: setArrayLength,
|
|
53
|
-
});
|
|
54
|
-
|
|
55
50
|
ReactiveArray.prototype.asReadonly = getReadonlySignal;
|
|
56
51
|
ReactiveArray.prototype.at = getArrayValues;
|
|
57
52
|
ReactiveArray.prototype.clear = clearArrayValues;
|
|
53
|
+
ReactiveArray.prototype.deactivate = deactivateArray;
|
|
58
54
|
ReactiveArray.prototype.filter = filterArrayValues;
|
|
59
55
|
ReactiveArray.prototype.get = getArrayValues;
|
|
60
56
|
ReactiveArray.prototype.map = mapArrayValues;
|
|
@@ -72,6 +68,18 @@ ReactiveArray.prototype.toJSON = getJsonValue;
|
|
|
72
68
|
ReactiveArray.prototype.unshift = unshiftArrayValues;
|
|
73
69
|
ReactiveArray.prototype.update = updateProxyValue;
|
|
74
70
|
|
|
71
|
+
Object.defineProperties(ReactiveArray.prototype, {
|
|
72
|
+
[PROPERTY_LENGTH]: {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: getArrayLength,
|
|
75
|
+
set: setArrayLength,
|
|
76
|
+
},
|
|
77
|
+
active: {
|
|
78
|
+
enumerable: true,
|
|
79
|
+
get: getReactiveActive,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
|
|
75
83
|
// #endregion
|
|
76
84
|
|
|
77
85
|
// #region Functions
|
|
@@ -115,11 +123,34 @@ export function array(value: unknown, options?: ReactiveOptions<unknown>): React
|
|
|
115
123
|
}
|
|
116
124
|
|
|
117
125
|
function clearArrayValues(this: InternalArray): void {
|
|
118
|
-
|
|
126
|
+
const state = this[SYMBOL_STATE];
|
|
127
|
+
|
|
128
|
+
if (state.active) {
|
|
129
|
+
(state.value as unknown[]).length = 0;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function deactivateArray(this: InternalArray): void {
|
|
134
|
+
const state = this[SYMBOL_STATE];
|
|
135
|
+
|
|
136
|
+
if (!state.active) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
state.length?.deactivate?.();
|
|
141
|
+
|
|
142
|
+
deactivateProxy.call(this);
|
|
119
143
|
}
|
|
120
144
|
|
|
121
145
|
function filterArrayValues(this: InternalArray, callback: never): Computed<unknown[]> {
|
|
122
|
-
|
|
146
|
+
if (!this[SYMBOL_STATE].active) {
|
|
147
|
+
throw new Error(MESSAGE_DEACTIVATED_ARRAY_FILTER);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return updateProxyDerivations(
|
|
151
|
+
this,
|
|
152
|
+
computed(() => filter(getArrayValues.call(this) as never, callback) as never),
|
|
153
|
+
);
|
|
123
154
|
}
|
|
124
155
|
|
|
125
156
|
function getArrayLength(this: InternalArray): number {
|
|
@@ -132,8 +163,22 @@ function getArrayValues(this: InternalArray, value?: unknown): unknown {
|
|
|
132
163
|
: getValueInProxy.call(this, value);
|
|
133
164
|
}
|
|
134
165
|
|
|
135
|
-
function mapArrayValues(
|
|
136
|
-
|
|
166
|
+
function mapArrayValues(
|
|
167
|
+
this: InternalArray,
|
|
168
|
+
callback: (item: unknown, index: number, array: unknown[]) => unknown,
|
|
169
|
+
): Computed<unknown[]> {
|
|
170
|
+
if (!this[SYMBOL_STATE].active) {
|
|
171
|
+
throw new Error(MESSAGE_DEACTIVATED_ARRAY_MAP);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return updateProxyDerivations(
|
|
175
|
+
this,
|
|
176
|
+
computed(() =>
|
|
177
|
+
(getArrayValues.call(this) as unknown[]).map((item, index, array) =>
|
|
178
|
+
callback(item, index, array),
|
|
179
|
+
),
|
|
180
|
+
),
|
|
181
|
+
);
|
|
137
182
|
}
|
|
138
183
|
|
|
139
184
|
function peekArrayValue(this: InternalArray, first?: unknown, second?: boolean): unknown {
|
|
@@ -143,19 +188,37 @@ function peekArrayValue(this: InternalArray, first?: unknown, second?: boolean):
|
|
|
143
188
|
}
|
|
144
189
|
|
|
145
190
|
function popArrayValue(this: InternalArray): unknown {
|
|
146
|
-
|
|
191
|
+
const state = this[SYMBOL_STATE];
|
|
192
|
+
|
|
193
|
+
return state.active ? (state.value as unknown[]).pop() : undefined;
|
|
147
194
|
}
|
|
148
195
|
|
|
149
196
|
function pushArrayValues(this: InternalArray, ...items: unknown[]): number {
|
|
150
|
-
|
|
197
|
+
const state = this[SYMBOL_STATE];
|
|
198
|
+
|
|
199
|
+
return state.active
|
|
200
|
+
? (state.value as unknown[]).push(...items)
|
|
201
|
+
: (state.value as unknown[]).length;
|
|
151
202
|
}
|
|
152
203
|
|
|
153
204
|
function selectArrayValues(this: InternalArray, filter: never, map: never): Computed<unknown[]> {
|
|
154
|
-
|
|
205
|
+
if (!this[SYMBOL_STATE].active) {
|
|
206
|
+
throw new Error(MESSAGE_DEACTIVATED_ARRAY_SELECT);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return updateProxyDerivations(
|
|
210
|
+
this,
|
|
211
|
+
computed(() => select(getArrayValues.call(this) as unknown[], filter, map)),
|
|
212
|
+
);
|
|
155
213
|
}
|
|
156
214
|
|
|
157
215
|
function setArrayLength(this: InternalArray, value: number): void {
|
|
158
216
|
const state = this[SYMBOL_STATE];
|
|
217
|
+
|
|
218
|
+
if (!state.active) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
159
222
|
const values = state.value as unknown[];
|
|
160
223
|
|
|
161
224
|
if (typeof value === 'number' && !Number.isNaN(value) && value >= 0 && value !== values.length) {
|
|
@@ -164,7 +227,9 @@ function setArrayLength(this: InternalArray, value: number): void {
|
|
|
164
227
|
}
|
|
165
228
|
|
|
166
229
|
function shiftArrayValue(this: InternalArray): unknown {
|
|
167
|
-
|
|
230
|
+
const state = this[SYMBOL_STATE];
|
|
231
|
+
|
|
232
|
+
return state.active ? (state.value as unknown[]).shift() : undefined;
|
|
168
233
|
}
|
|
169
234
|
|
|
170
235
|
function spliceArrayValues(
|
|
@@ -173,18 +238,32 @@ function spliceArrayValues(
|
|
|
173
238
|
to?: never,
|
|
174
239
|
...items: unknown[]
|
|
175
240
|
): unknown[] {
|
|
176
|
-
const
|
|
241
|
+
const state = this[SYMBOL_STATE];
|
|
242
|
+
|
|
243
|
+
if (!state.active) {
|
|
244
|
+
return [];
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const values = state.value as unknown[];
|
|
177
248
|
|
|
178
249
|
return values.splice(from, to ?? values.length, ...items);
|
|
179
250
|
}
|
|
180
251
|
|
|
181
252
|
function unshiftArrayValues(this: InternalArray, ...items: unknown[]): number {
|
|
182
|
-
|
|
253
|
+
const state = this[SYMBOL_STATE];
|
|
254
|
+
|
|
255
|
+
return state.active
|
|
256
|
+
? (state.value as unknown[]).unshift(...items)
|
|
257
|
+
: (state.value as unknown[]).length;
|
|
183
258
|
}
|
|
184
259
|
|
|
185
260
|
function updateArray(instance: InternalArray, type: string | symbol, array: unknown[]): unknown {
|
|
186
261
|
const state = instance[SYMBOL_STATE];
|
|
187
262
|
|
|
263
|
+
if (!state.active) {
|
|
264
|
+
return () => undefined;
|
|
265
|
+
}
|
|
266
|
+
|
|
188
267
|
const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
|
|
189
268
|
const previousArray = affectsLength ? [] : array.slice();
|
|
190
269
|
const previousLength = array.length;
|
package/src/value/computed.ts
CHANGED
|
@@ -3,8 +3,8 @@ import {flushHandlers} from '../batch';
|
|
|
3
3
|
import {
|
|
4
4
|
ACTIVE,
|
|
5
5
|
BATCH,
|
|
6
|
+
MESSAGE_COMPUTED_CALLBACK,
|
|
6
7
|
NAME_COMPUTED,
|
|
7
|
-
NAME_MORA,
|
|
8
8
|
SUBSCRIPTION_TYPE_FROZEN,
|
|
9
9
|
SUBSCRIPTION_TYPES,
|
|
10
10
|
SUBSCRIPTION_TYPES_COPY,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
SYMBOL_STATE,
|
|
13
13
|
} from '../constants';
|
|
14
14
|
import {internalEffect, runEffect} from '../effect';
|
|
15
|
-
import {getState} from '../helpers/misc';
|
|
15
|
+
import {deactivateComputed, getReactiveActive, getState} from '../helpers/misc';
|
|
16
16
|
import {subscribeToSignal} from '../helpers/subscription';
|
|
17
17
|
import {getJsonValue, getStringValue, handleSignal, peekSignalValue} from '../helpers/value';
|
|
18
18
|
import type {
|
|
@@ -26,18 +26,24 @@ import type {
|
|
|
26
26
|
// #region Instance
|
|
27
27
|
|
|
28
28
|
function Computed(this: any, callback: GenericCallback, options?: ReactiveOptions<unknown>): void {
|
|
29
|
-
this[SYMBOL_STATE] = getState(undefined, options);
|
|
29
|
+
this[SYMBOL_STATE] = getState(NAME_COMPUTED, undefined, options);
|
|
30
30
|
this[SYMBOL_EFFECT] = getComputedEffect(this, callback);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
Computed.prototype
|
|
34
|
-
|
|
33
|
+
Computed.prototype.deactivate = deactivateComputed;
|
|
35
34
|
Computed.prototype.get = getComputedValue;
|
|
36
35
|
Computed.prototype.peek = peekSignalValue;
|
|
37
36
|
Computed.prototype.subscribe = subscribeToSignal;
|
|
38
37
|
Computed.prototype.toJSON = getJsonValue;
|
|
39
38
|
Computed.prototype.toString = getStringValue;
|
|
40
39
|
|
|
40
|
+
Object.defineProperties(Computed.prototype, {
|
|
41
|
+
active: {
|
|
42
|
+
enumerable: true,
|
|
43
|
+
get: getReactiveActive,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
41
47
|
// #endregion
|
|
42
48
|
|
|
43
49
|
// #region Functions
|
|
@@ -61,7 +67,7 @@ function getComputed<Value>(
|
|
|
61
67
|
options?: ReactiveOptions<Value>,
|
|
62
68
|
): InternalComputed {
|
|
63
69
|
if (typeof callback !== 'function') {
|
|
64
|
-
throw new TypeError(
|
|
70
|
+
throw new TypeError(MESSAGE_COMPUTED_CALLBACK);
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
// @ts-expect-error All good, no worries :-)
|
|
@@ -104,9 +110,14 @@ function getComputedEffect(
|
|
|
104
110
|
}
|
|
105
111
|
|
|
106
112
|
function getComputedValue(this: InternalComputed): unknown {
|
|
107
|
-
const fx = this[SYMBOL_EFFECT];
|
|
108
113
|
const state = this[SYMBOL_STATE];
|
|
109
114
|
|
|
115
|
+
if (!state.active) {
|
|
116
|
+
return state.value;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const fx = this[SYMBOL_EFFECT];
|
|
120
|
+
|
|
110
121
|
if (ACTIVE.computed != null && fx !== ACTIVE.computed) {
|
|
111
122
|
state.computeds ??= new Set();
|
|
112
123
|
|
|
@@ -136,7 +147,7 @@ export function internalComputed(
|
|
|
136
147
|
function setAndEmit(instance: InternalStateful, value: unknown, notify: boolean): void {
|
|
137
148
|
const state = instance[SYMBOL_STATE];
|
|
138
149
|
|
|
139
|
-
if (!notify && (state.equal ?? Object.is)(state.value, value)) {
|
|
150
|
+
if (!state.active || (!notify && (state.equal ?? Object.is)(state.value, value))) {
|
|
140
151
|
return;
|
|
141
152
|
}
|
|
142
153
|
|
|
@@ -144,13 +155,21 @@ function setAndEmit(instance: InternalStateful, value: unknown, notify: boolean)
|
|
|
144
155
|
|
|
145
156
|
if (state.computeds != null && state.computeds.size > 0) {
|
|
146
157
|
for (const computed of state.computeds) {
|
|
147
|
-
computed.
|
|
158
|
+
if (computed.instance.active) {
|
|
159
|
+
computed.dirty = true;
|
|
160
|
+
} else {
|
|
161
|
+
state.computeds.delete(computed);
|
|
162
|
+
}
|
|
148
163
|
}
|
|
149
164
|
}
|
|
150
165
|
|
|
151
166
|
if (state.effects != null && state.effects.size > 0) {
|
|
152
167
|
for (const effect of state.effects) {
|
|
153
|
-
|
|
168
|
+
if (effect.active) {
|
|
169
|
+
BATCH.handlers.set(effect, effect);
|
|
170
|
+
} else {
|
|
171
|
+
state.effects.delete(effect);
|
|
172
|
+
}
|
|
154
173
|
}
|
|
155
174
|
}
|
|
156
175
|
|
package/src/value/readonly.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
NAME_READONLY,
|
|
2
|
+
MESSAGE_DEACTIVATED_READONLY,
|
|
4
3
|
SUBSCRIPTION_TYPE_FROZEN,
|
|
5
4
|
SUBSCRIPTION_TYPE_ORIGINAL,
|
|
5
|
+
SYMBOL_READONLY,
|
|
6
6
|
SYMBOL_STATE,
|
|
7
7
|
} from '../constants';
|
|
8
|
+
import {deactivateReadonly, getReadonlyActive} from '../helpers/misc';
|
|
8
9
|
import {subscribeToReadonly} from '../helpers/subscription';
|
|
9
10
|
import {
|
|
10
11
|
getFrozenValue,
|
|
@@ -13,61 +14,63 @@ import {
|
|
|
13
14
|
getStringValue,
|
|
14
15
|
peekSignalValue,
|
|
15
16
|
} from '../helpers/value';
|
|
16
|
-
import type {
|
|
17
|
-
|
|
18
|
-
// #region Types
|
|
19
|
-
|
|
20
|
-
type InternalReadonly = {
|
|
21
|
-
[SUBSCRIPTION_TYPE_FROZEN]: boolean;
|
|
22
|
-
} & InternalSignal;
|
|
23
|
-
|
|
24
|
-
// #endregion
|
|
17
|
+
import type {InternalReadonly, InternalSignal, ReadonlySignal, SignalState} from '../models';
|
|
25
18
|
|
|
26
19
|
// #region Instance
|
|
27
20
|
|
|
28
|
-
function Readonly(this:
|
|
29
|
-
this[SUBSCRIPTION_TYPE_FROZEN] = frozen;
|
|
21
|
+
function Readonly(this: InternalReadonly, state: SignalState, frozen: boolean): void {
|
|
30
22
|
this[SYMBOL_STATE] = state;
|
|
31
|
-
}
|
|
32
23
|
|
|
33
|
-
|
|
24
|
+
this[SYMBOL_READONLY] = {
|
|
25
|
+
active: true,
|
|
26
|
+
name: frozen ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_ORIGINAL,
|
|
27
|
+
};
|
|
34
28
|
|
|
29
|
+
Object.defineProperty(this, SUBSCRIPTION_TYPE_FROZEN, {
|
|
30
|
+
value: frozen,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Readonly.prototype.deactivate = deactivateReadonly;
|
|
35
35
|
Readonly.prototype.get = getReadonlyValue;
|
|
36
36
|
Readonly.prototype.peek = peekReadonlyValue;
|
|
37
37
|
Readonly.prototype.subscribe = subscribeToReadonly;
|
|
38
38
|
Readonly.prototype.toJSON = getJsonValue;
|
|
39
39
|
Readonly.prototype.toString = getStringValue;
|
|
40
40
|
|
|
41
|
+
Object.defineProperties(Readonly.prototype, {
|
|
42
|
+
active: {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: getReadonlyActive,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
41
48
|
// #endregion
|
|
42
49
|
|
|
43
50
|
// #region Functions
|
|
44
51
|
|
|
45
|
-
export function getReadonlyInstance(
|
|
46
|
-
state: SignalState,
|
|
47
|
-
frozen: boolean,
|
|
48
|
-
): ReadonlySignal<unknown> | ReadonlyFrozenSignal<unknown> {
|
|
49
|
-
// @ts-expect-error All good, no worries :-)
|
|
50
|
-
return new Readonly(state, frozen);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
52
|
export function getReadonlySignal<Value>(
|
|
54
53
|
this: InternalSignal,
|
|
55
54
|
frozen?: never,
|
|
56
55
|
): ReadonlySignal<Value> {
|
|
56
|
+
const state = this[SYMBOL_STATE];
|
|
57
|
+
|
|
58
|
+
if (!state.active) {
|
|
59
|
+
throw new Error(MESSAGE_DEACTIVATED_READONLY);
|
|
60
|
+
}
|
|
61
|
+
|
|
57
62
|
const key = (frozen === true ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_ORIGINAL) as never;
|
|
58
63
|
|
|
59
|
-
|
|
64
|
+
state.readonlies ??= {};
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
frozen === true,
|
|
64
|
-
) as never;
|
|
66
|
+
// @ts-expect-error All good, no worries :-)
|
|
67
|
+
state.readonlies[key] ??= new Readonly(state, frozen === true);
|
|
65
68
|
|
|
66
|
-
return
|
|
69
|
+
return state.readonlies[key] as never;
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
function getReadonlyValue(this: InternalReadonly) {
|
|
70
|
-
return handleReadonlyValue(this, false, this
|
|
73
|
+
return handleReadonlyValue(this, false, this.frozen);
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
function handleReadonlyValue(
|
|
@@ -76,19 +79,21 @@ function handleReadonlyValue(
|
|
|
76
79
|
frozen: boolean,
|
|
77
80
|
copy?: boolean,
|
|
78
81
|
): unknown {
|
|
82
|
+
const state = instance[SYMBOL_READONLY];
|
|
83
|
+
|
|
79
84
|
let value: unknown;
|
|
80
85
|
|
|
81
86
|
if (peek) {
|
|
82
|
-
value = peekSignalValue.call(instance, copy === true);
|
|
87
|
+
value = peekSignalValue.call(state.active ? instance : [instance, state.value], copy === true);
|
|
83
88
|
} else {
|
|
84
|
-
value = getSignalValue.call(instance);
|
|
89
|
+
value = state.active ? getSignalValue.call(instance) : state.value;
|
|
85
90
|
}
|
|
86
91
|
|
|
87
92
|
return frozen ? getFrozenValue(value) : value;
|
|
88
93
|
}
|
|
89
94
|
|
|
90
95
|
function peekReadonlyValue(this: InternalReadonly, copy?: boolean) {
|
|
91
|
-
return handleReadonlyValue(this, true, this
|
|
96
|
+
return handleReadonlyValue(this, true, this.frozen, copy);
|
|
92
97
|
}
|
|
93
98
|
|
|
94
99
|
// #endregion
|
package/src/value/signal.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {getState} from '../helpers/misc';
|
|
1
|
+
import {NAME_SIGNAL, SYMBOL_STATE} from '../constants';
|
|
2
|
+
import {deactivateReactive, getReactiveActive, getState} from '../helpers/misc';
|
|
3
3
|
import {subscribeToSignal} from '../helpers/subscription';
|
|
4
4
|
import {
|
|
5
5
|
emitValue,
|
|
@@ -16,14 +16,13 @@ import {getReadonlySignal} from './readonly';
|
|
|
16
16
|
// #region Instance
|
|
17
17
|
|
|
18
18
|
function Signal(this: any, value: unknown, options?: ReactiveOptions<unknown>): void {
|
|
19
|
-
this[SYMBOL_STATE] = getState(undefined, options);
|
|
19
|
+
this[SYMBOL_STATE] = getState(NAME_SIGNAL, undefined, options);
|
|
20
20
|
|
|
21
21
|
handleSignal(this, value, setAndEmit);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
Signal.prototype[NAME_MORA] = NAME_SIGNAL;
|
|
25
|
-
|
|
26
24
|
Signal.prototype.asReadonly = getReadonlySignal;
|
|
25
|
+
Signal.prototype.deactivate = deactivateReactive;
|
|
27
26
|
Signal.prototype.get = getSignalValue;
|
|
28
27
|
Signal.prototype.peek = peekSignalValue;
|
|
29
28
|
Signal.prototype.set = setSignalValue;
|
|
@@ -32,6 +31,13 @@ Signal.prototype.toString = getStringValue;
|
|
|
32
31
|
Signal.prototype.toJSON = getJsonValue;
|
|
33
32
|
Signal.prototype.update = updateSignalValue;
|
|
34
33
|
|
|
34
|
+
Object.defineProperties(Signal.prototype, {
|
|
35
|
+
active: {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
get: getReactiveActive,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
35
41
|
// #endregion
|
|
36
42
|
|
|
37
43
|
// #region Functions
|
package/src/value/store.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type {PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
-
import {
|
|
3
|
-
import {getState} from '../helpers/misc';
|
|
2
|
+
import {NAME_STORE, SYMBOL_STATE} from '../constants';
|
|
3
|
+
import {deactivateProxy, getReactiveActive, getState} from '../helpers/misc';
|
|
4
4
|
import {
|
|
5
5
|
getValueInProxy,
|
|
6
6
|
notifyProxyValue,
|
|
@@ -18,7 +18,7 @@ import {getReadonlySignal} from './readonly';
|
|
|
18
18
|
|
|
19
19
|
function ReactiveStore(this: any, value: never, options?: ReactiveOptions<unknown>): void {
|
|
20
20
|
this[SYMBOL_STATE] = {
|
|
21
|
-
...getState(undefined, options),
|
|
21
|
+
...getState(NAME_STORE, undefined, options),
|
|
22
22
|
isArray: false,
|
|
23
23
|
};
|
|
24
24
|
|
|
@@ -32,9 +32,8 @@ function ReactiveStore(this: any, value: never, options?: ReactiveOptions<unknow
|
|
|
32
32
|
setProxyValue.call(this, value);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
ReactiveStore.prototype[NAME_MORA] = NAME_STORE;
|
|
36
|
-
|
|
37
35
|
ReactiveStore.prototype.asReadonly = getReadonlySignal;
|
|
36
|
+
ReactiveStore.prototype.deactivate = deactivateProxy;
|
|
38
37
|
ReactiveStore.prototype.get = getValueInProxy;
|
|
39
38
|
ReactiveStore.prototype.notify = notifyProxyValue;
|
|
40
39
|
ReactiveStore.prototype.peek = peekValueInProxy;
|
|
@@ -44,6 +43,13 @@ ReactiveStore.prototype.toJSON = getJsonValue;
|
|
|
44
43
|
ReactiveStore.prototype.toString = getStringValue;
|
|
45
44
|
ReactiveStore.prototype.update = updateProxyValue;
|
|
46
45
|
|
|
46
|
+
Object.defineProperties(ReactiveStore.prototype, {
|
|
47
|
+
active: {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
get: getReactiveActive,
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
47
53
|
// #endregion
|
|
48
54
|
|
|
49
55
|
// #region Functions
|
package/types/batch.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export declare function flushHandlers(): void;
|
|
2
|
-
/**
|
|
3
|
-
* Start batching effects
|
|
4
|
-
*
|
|
5
|
-
* _(Use {@link stopBatch} to flush and run batched effects)_
|
|
6
|
-
*/
|
|
7
|
-
export declare function startBatch(): void;
|
|
8
|
-
/**
|
|
9
|
-
* Stop batching effects and flush _(run)_ them
|
|
10
|
-
*/
|
|
11
|
-
export declare function stopBatch(): void;
|
package/types/constants.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { Active, Batch } from './models';
|
|
2
|
-
export declare const ACTIVE: Active;
|
|
3
|
-
export declare const ARRAY_THRESHOLD = 100;
|
|
4
|
-
export declare const ARRAY_OFFSET = 25;
|
|
5
|
-
export declare const ARRAY_PEEK = 10;
|
|
6
|
-
export declare const BATCH: Batch;
|
|
7
|
-
export declare const METHODS_AFFECTING_LENGTH: Set<string>;
|
|
8
|
-
export declare const METHODS_UPDATE: Set<string>;
|
|
9
|
-
export declare const NAME_ARRAY = "array";
|
|
10
|
-
export declare const NAME_COMPUTED = "computed";
|
|
11
|
-
export declare const NAME_EFFECT = "effect";
|
|
12
|
-
export declare const NAME_MORA = "$mora";
|
|
13
|
-
export declare const NAME_SIGNAL = "signal";
|
|
14
|
-
export declare const NAME_STORE = "store";
|
|
15
|
-
export declare const NAMES: Set<string>;
|
|
16
|
-
export declare const PROPERTY_LENGTH = "length";
|
package/types/effect.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { GenericCallback } from '@oscarpalmer/atoms/models';
|
|
2
|
-
export declare class Effect {
|
|
3
|
-
private readonly $mora;
|
|
4
|
-
private readonly state;
|
|
5
|
-
constructor(callback: GenericCallback);
|
|
6
|
-
}
|
|
7
|
-
export declare function runEffect(effect: Effect): void;
|
|
8
|
-
/**
|
|
9
|
-
* Create an effect
|
|
10
|
-
* @param callback Callback for handling signal effects
|
|
11
|
-
* @returns Effect
|
|
12
|
-
*/
|
|
13
|
-
export declare function effect(callback: GenericCallback): Effect;
|
package/types/helpers/is.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { PlainObject } from '@oscarpalmer/atoms/models';
|
|
2
|
-
import type { Effect } from '../effect';
|
|
3
|
-
import type { ReactiveArray } from '../value/array';
|
|
4
|
-
import type { Computed } from '../value/computed';
|
|
5
|
-
import type { Reactive } from '../value/reactive';
|
|
6
|
-
import type { Signal } from '../value/signal';
|
|
7
|
-
import type { Store } from '../value/store';
|
|
8
|
-
/**
|
|
9
|
-
* Is the value a reactive array?
|
|
10
|
-
* @param value Value to check
|
|
11
|
-
* @returns True if value is a {@link ReactiveArray}
|
|
12
|
-
*/
|
|
13
|
-
export declare function isArray<Item>(value: unknown): value is ReactiveArray<Item>;
|
|
14
|
-
/**
|
|
15
|
-
* Is the value a computed signal?
|
|
16
|
-
* @param value Value to check
|
|
17
|
-
* @returns True if value is a {@link Computed}
|
|
18
|
-
*/
|
|
19
|
-
export declare function isComputed<Value>(value: unknown): value is Computed<Value>;
|
|
20
|
-
/**
|
|
21
|
-
* Is the value an effect?
|
|
22
|
-
* @param value Value to check
|
|
23
|
-
* @returns True if value is an {@link Effect}
|
|
24
|
-
*/
|
|
25
|
-
export declare function isEffect(value: unknown): value is Effect;
|
|
26
|
-
/**
|
|
27
|
-
* Is the value reactive?
|
|
28
|
-
* @param value Value to check
|
|
29
|
-
* @returns True if value is a {@link Reactive}
|
|
30
|
-
*/
|
|
31
|
-
export declare function isReactive<Value, Equal = Value>(value: unknown): value is Reactive<Value, Equal>;
|
|
32
|
-
/**
|
|
33
|
-
* Is the value a signal?
|
|
34
|
-
* @param value Value to check
|
|
35
|
-
* @returns True if value is a {@link Signal}
|
|
36
|
-
*/
|
|
37
|
-
export declare function isSignal<Value>(value: unknown): value is Signal<Value>;
|
|
38
|
-
/**
|
|
39
|
-
* Is the value a reactive store?
|
|
40
|
-
* @param value Value to check
|
|
41
|
-
* @returns True if value is a {@link Store}
|
|
42
|
-
*/
|
|
43
|
-
export declare function isStore<Value extends PlainObject>(value: unknown): value is Store<Value>;
|
package/types/helpers/proxy.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { ArrayOrPlainObject, Key, PlainObject } from '@oscarpalmer/atoms/models';
|
|
2
|
-
import type { ReactiveState, SetValueInProxyParameters } from '../models';
|
|
3
|
-
import type { ReactiveArray } from '../value/array';
|
|
4
|
-
import { type Computed } from '../value/computed';
|
|
5
|
-
import type { Store } from '../value/store';
|
|
6
|
-
export declare function emityProxyValues<Value>(state: ReactiveState<Value, Value>, mapped: Map<Key, Computed<unknown>>): void;
|
|
7
|
-
export declare function emityProxyValues<Value>(state: ReactiveState<Value[], Value>, mapped: Map<Key, Computed<unknown>>): void;
|
|
8
|
-
export declare function getReactiveValueInProxy<Value>(array: ReactiveArray<Value>, mapped: Map<Key, Computed<unknown>>, index: number, isArray: true): Computed<unknown>;
|
|
9
|
-
export declare function getReactiveValueInProxy<Value extends PlainObject>(store: Store<Value>, mapped: Map<Key, Computed<unknown>>, key: Key, isArray: false): Computed<unknown>;
|
|
10
|
-
export declare function setProxyValue(proxy: ArrayOrPlainObject, value: ArrayOrPlainObject): void;
|
|
11
|
-
export declare function setValueInProxy<Value extends ArrayOrPlainObject, Equal>(parameters: SetValueInProxyParameters<Value, Equal>): boolean;
|
package/types/helpers/value.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { ReactiveState } from '../models';
|
|
2
|
-
export declare function emitValue<Value>(state: ReactiveState<Value, never>): void;
|
|
3
|
-
export declare function equalArrays<Value>(state: ReactiveState<Value[], Value>, first: Value[], second: Value[]): boolean;
|
|
4
|
-
export declare function getValue<Value>(state: ReactiveState<Value, never>): Value;
|
package/types/index.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export { startBatch, stopBatch } from './batch';
|
|
2
|
-
export { effect, type Effect } from './effect';
|
|
3
|
-
export { isArray, isComputed, isEffect, isReactive, isSignal, } from './helpers/is';
|
|
4
|
-
export type { Unsubscribe } from './models';
|
|
5
|
-
export { array, type ReactiveArray } from './value/array';
|
|
6
|
-
export { computed, type Computed } from './value/computed';
|
|
7
|
-
export type { Reactive } from './value/reactive';
|
|
8
|
-
export { signal, type Signal } from './value/signal';
|
|
9
|
-
export { store, type Store } from './value/store';
|