@oscarpalmer/mora 0.28.0 → 0.30.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 +15 -6
- package/dist/constants.d.mts +0 -1
- package/dist/constants.mjs +4 -3
- package/dist/effect.d.mts +5 -8
- package/dist/effect.mjs +23 -19
- package/dist/helpers/is.d.mts +9 -9
- package/dist/helpers/is.mjs +6 -0
- package/dist/helpers/proxy.d.mts +5 -9
- package/dist/helpers/proxy.mjs +4 -4
- package/dist/helpers/value.d.mts +3 -3
- package/dist/helpers/value.mjs +21 -3
- package/dist/index.d.mts +7 -8
- package/dist/index.mjs +1 -1
- package/dist/models.d.mts +356 -18
- package/dist/mora.full.mjs +458 -409
- package/dist/subscription.d.mts +1 -9
- package/dist/subscription.mjs +14 -15
- package/dist/value/array.d.mts +5 -133
- package/dist/value/array.mjs +91 -137
- package/dist/value/computed.d.mts +4 -12
- package/dist/value/computed.mjs +54 -50
- package/dist/value/reactive.d.mts +3 -38
- package/dist/value/reactive.mjs +10 -49
- package/dist/value/signal.d.mts +5 -21
- package/dist/value/signal.mjs +27 -49
- package/dist/value/store.d.mts +9 -92
- package/dist/value/store.mjs +42 -49
- package/package.json +8 -8
- package/src/batch.ts +22 -9
- package/src/constants.ts +3 -4
- package/src/effect.ts +31 -26
- package/src/helpers/is.ts +11 -10
- package/src/helpers/proxy.ts +23 -18
- package/src/helpers/value.ts +38 -3
- package/src/index.ts +6 -7
- package/src/models.ts +431 -16
- package/src/subscription.ts +20 -20
- package/src/value/array.ts +183 -265
- package/src/value/computed.ts +80 -74
- package/src/value/reactive.ts +16 -64
- package/src/value/signal.ts +34 -71
- package/src/value/store.ts +84 -177
package/src/value/reactive.ts
CHANGED
|
@@ -1,72 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {ReactiveOptions, ReactiveState, Unsubscribe} from '../models';
|
|
3
|
-
import {subscribe, unsubscribe} from '../subscription';
|
|
1
|
+
import type {Reactive, ReactiveOptions, ReactiveState} from '../models';
|
|
4
2
|
|
|
5
|
-
export
|
|
6
|
-
|
|
3
|
+
export function reactive<Value, Equal = Value>(
|
|
4
|
+
value: Value,
|
|
5
|
+
options?: ReactiveOptions<Equal>,
|
|
6
|
+
): [Reactive<Value>, ReactiveState<Value, Equal>] {
|
|
7
|
+
const state: ReactiveState<Value, Equal> = {
|
|
7
8
|
computeds: new Set(),
|
|
8
9
|
effects: new Set(),
|
|
9
|
-
equal:
|
|
10
|
+
equal:
|
|
11
|
+
typeof options === 'object' && typeof options?.equal === 'function'
|
|
12
|
+
? options.equal
|
|
13
|
+
: Object.is,
|
|
10
14
|
subscriptions: new Map(),
|
|
11
|
-
value:
|
|
15
|
+
value: value as Value,
|
|
12
16
|
};
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
this.state.equal = options.equal;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
Object.defineProperty(this, NAME_MORA, {
|
|
22
|
-
value: name,
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Get the value
|
|
28
|
-
* @return Current value
|
|
29
|
-
*/
|
|
30
|
-
abstract get(): Value;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Get the value _(without reactivity)_
|
|
34
|
-
* @return Current value
|
|
35
|
-
*/
|
|
36
|
-
peek(): Value {
|
|
37
|
-
return this.state.value;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Subscribe to changes
|
|
42
|
-
* @param callback Callback for changes
|
|
43
|
-
* @return Unsubscribe callback
|
|
44
|
-
*/
|
|
45
|
-
subscribe(callback: (value: Value) => void): Unsubscribe {
|
|
46
|
-
return subscribe(this.state, callback);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* JSON representation of the value
|
|
51
|
-
* @return JSON value
|
|
52
|
-
*/
|
|
53
|
-
toJSON(): Value {
|
|
54
|
-
return this.get();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* String representation of the value
|
|
59
|
-
* @return Value as string
|
|
60
|
-
*/
|
|
61
|
-
toString(): string {
|
|
62
|
-
return String(this.get());
|
|
63
|
-
}
|
|
18
|
+
const instance = {
|
|
19
|
+
toJSON: () => state.value,
|
|
20
|
+
toString: () => String(state.value),
|
|
21
|
+
};
|
|
64
22
|
|
|
65
|
-
|
|
66
|
-
* Unsubscribe from changes
|
|
67
|
-
* @param callback Callback to unsubscribe
|
|
68
|
-
*/
|
|
69
|
-
unsubscribe(callback: (value: Value) => void): void {
|
|
70
|
-
unsubscribe(this.state, callback);
|
|
71
|
-
}
|
|
23
|
+
return [instance, state];
|
|
72
24
|
}
|
package/src/value/signal.ts
CHANGED
|
@@ -1,36 +1,8 @@
|
|
|
1
|
-
import {NAME_SIGNAL} from '../constants';
|
|
2
|
-
import {emitValue,
|
|
3
|
-
import type {ReactiveOptions, ReactiveState} from '../models';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
export class Signal<Value> extends Reactive<Value> {
|
|
7
|
-
constructor(value: Value, options?: ReactiveOptions<Value>) {
|
|
8
|
-
super(NAME_SIGNAL, value, options);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @inheritdoc
|
|
13
|
-
*/
|
|
14
|
-
get(): Value {
|
|
15
|
-
return getValue(this.state);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Set the value
|
|
20
|
-
* @param value New value
|
|
21
|
-
*/
|
|
22
|
-
set(value: Value | (() => Value | Promise<Value>) | Promise<Value>): void {
|
|
23
|
-
setValue<Value>(this.state, value);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Update the value _(based on the current value)_
|
|
28
|
-
* @param callback Callback to update the value
|
|
29
|
-
*/
|
|
30
|
-
update(callback: (value: Value) => Value): void {
|
|
31
|
-
this.set(callback(this.state.value));
|
|
32
|
-
}
|
|
33
|
-
}
|
|
1
|
+
import {NAME_MORA, NAME_SIGNAL} from '../constants';
|
|
2
|
+
import {emitValue, getSimpleValue, handleSimpleValue} from '../helpers/value';
|
|
3
|
+
import type {ReactiveOptions, ReactiveState, Signal} from '../models';
|
|
4
|
+
import {subscribe} from '../subscription';
|
|
5
|
+
import {reactive} from './reactive';
|
|
34
6
|
|
|
35
7
|
function setAndEmit<Value>(state: ReactiveState<Value, Value>, value: Value): void {
|
|
36
8
|
if (!state.equal(state.value, value)) {
|
|
@@ -40,41 +12,9 @@ function setAndEmit<Value>(state: ReactiveState<Value, Value>, value: Value): vo
|
|
|
40
12
|
}
|
|
41
13
|
}
|
|
42
14
|
|
|
43
|
-
function setValue<Value>(
|
|
44
|
-
state: ReactiveState<Value, Value>,
|
|
45
|
-
value: Value | (() => Value | Promise<Value>) | Promise<Value>,
|
|
46
|
-
): void {
|
|
47
|
-
try {
|
|
48
|
-
let actual = value;
|
|
49
|
-
|
|
50
|
-
if (typeof value === 'function') {
|
|
51
|
-
actual = (value as () => Value | Promise<Value>)() as Value | Promise<Value>;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (actual instanceof Promise) {
|
|
55
|
-
state.promise = actual;
|
|
56
|
-
|
|
57
|
-
void actual
|
|
58
|
-
.then(value => {
|
|
59
|
-
if (actual === state.promise) {
|
|
60
|
-
state.promise = undefined;
|
|
61
|
-
|
|
62
|
-
setAndEmit(state, value);
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
|
-
.catch(() => {
|
|
66
|
-
if (actual === state.promise) {
|
|
67
|
-
state.promise = undefined;
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
} else {
|
|
71
|
-
setAndEmit(state, actual as Value);
|
|
72
|
-
}
|
|
73
|
-
} catch {}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
15
|
/**
|
|
77
16
|
* Create a reactive value from a function result
|
|
17
|
+
*
|
|
78
18
|
* @param value Initial value
|
|
79
19
|
* @param options Reactivity options
|
|
80
20
|
* @returns Reactive value
|
|
@@ -86,6 +26,7 @@ export function signal<Value>(
|
|
|
86
26
|
|
|
87
27
|
/**
|
|
88
28
|
* Create a reactive value from a promise
|
|
29
|
+
*
|
|
89
30
|
* @param value Initial value
|
|
90
31
|
* @param options Reactivity options
|
|
91
32
|
* @returns Reactive value
|
|
@@ -97,6 +38,7 @@ export function signal<Value>(
|
|
|
97
38
|
|
|
98
39
|
/**
|
|
99
40
|
* Create a reactive value
|
|
41
|
+
*
|
|
100
42
|
* @param value Initial value
|
|
101
43
|
* @param options Reactivity options
|
|
102
44
|
* @returns Reactive value
|
|
@@ -107,9 +49,30 @@ export function signal<Value>(
|
|
|
107
49
|
value: Value | (() => Value | Promise<Value>) | Promise<Value>,
|
|
108
50
|
options?: ReactiveOptions<Value>,
|
|
109
51
|
): Signal<Value> {
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
instance
|
|
113
|
-
|
|
114
|
-
|
|
52
|
+
const [rx, state] = reactive<Value>(undefined as unknown as Value, options);
|
|
53
|
+
|
|
54
|
+
const instance = {
|
|
55
|
+
...rx,
|
|
56
|
+
get: () => getSimpleValue(state),
|
|
57
|
+
peek: () => state.value,
|
|
58
|
+
set: (value: Value | (() => Value | Promise<Value>) | Promise<Value>) => {
|
|
59
|
+
handleSimpleValue(state, value, setAndEmit);
|
|
60
|
+
},
|
|
61
|
+
update: (callback: (value: Value) => Value) => {
|
|
62
|
+
handleSimpleValue(state, callback(state.value), setAndEmit);
|
|
63
|
+
},
|
|
64
|
+
subscribe: (callback: (value: Value) => void) => subscribe(state, callback),
|
|
65
|
+
unsubscribe: (callback: (value: Value) => void) => {
|
|
66
|
+
state.subscriptions.delete(callback);
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
Object.defineProperty(instance, NAME_MORA, {
|
|
71
|
+
enumerable: false,
|
|
72
|
+
value: NAME_SIGNAL,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
handleSimpleValue(state, value, setAndEmit);
|
|
76
|
+
|
|
77
|
+
return Object.freeze(instance) as Signal<Value>;
|
|
115
78
|
}
|
package/src/value/store.ts
CHANGED
|
@@ -1,183 +1,24 @@
|
|
|
1
1
|
import {isKey, isPlainObject} from '@oscarpalmer/atoms/is';
|
|
2
2
|
import type {GenericCallback, Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
3
3
|
import {startBatch, stopBatch} from '../batch';
|
|
4
|
-
import {NAME_STORE} from '../constants';
|
|
4
|
+
import {NAME_MORA, NAME_STORE} from '../constants';
|
|
5
5
|
import {
|
|
6
6
|
emityProxyValues,
|
|
7
7
|
getReactiveValueInProxy,
|
|
8
8
|
setProxyValue,
|
|
9
9
|
setValueInProxy,
|
|
10
10
|
} from '../helpers/proxy';
|
|
11
|
-
import {
|
|
12
|
-
import type {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
NAME_STORE,
|
|
23
|
-
new Proxy(value, {
|
|
24
|
-
set: (target: Value, property: PropertyKey, value: unknown) =>
|
|
25
|
-
setValueInProxy({
|
|
26
|
-
target,
|
|
27
|
-
property,
|
|
28
|
-
value,
|
|
29
|
-
isArray: false,
|
|
30
|
-
state: this.state,
|
|
31
|
-
}),
|
|
32
|
-
}),
|
|
33
|
-
options,
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @inheritdoc
|
|
39
|
-
*/
|
|
40
|
-
get(): Value;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Get a value by key
|
|
44
|
-
* @param key Key of the value to get
|
|
45
|
-
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
46
|
-
*/
|
|
47
|
-
get<Key extends keyof Value>(key: Key): Value[Key];
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Get a value by key
|
|
51
|
-
* @param key Key of the value to get
|
|
52
|
-
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
53
|
-
*/
|
|
54
|
-
get(key: Key): unknown;
|
|
55
|
-
|
|
56
|
-
get(key?: unknown): unknown {
|
|
57
|
-
return isKey(key)
|
|
58
|
-
? getReactiveValueInProxy(this, this.#keyed, key, false).get()
|
|
59
|
-
: getValue(this.state);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Notify dependents of changes
|
|
64
|
-
*
|
|
65
|
-
* _This bypasses equality checks and will immediately notify dependents.
|
|
66
|
-
* Use this only if you're modifying nested data that would be ignored by equality checks._
|
|
67
|
-
*/
|
|
68
|
-
notify(): void {
|
|
69
|
-
emityProxyValues(this.state, this.#keyed);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Get the value _(without reactivity)_
|
|
74
|
-
* @returns The current value
|
|
75
|
-
*/
|
|
76
|
-
override peek(): Value;
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Get a value by key _(without reactivity)_
|
|
80
|
-
* @param key Key of the value to get
|
|
81
|
-
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
82
|
-
*/
|
|
83
|
-
override peek<Key extends keyof Value>(key: Key): Value[Key];
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Get a value by key _(without reactivity)_
|
|
87
|
-
* @param key Key of the value to get
|
|
88
|
-
* @returns Value for the specified key, or `undefined` if it doesn't exist
|
|
89
|
-
*/
|
|
90
|
-
override peek(key: Key): unknown;
|
|
91
|
-
|
|
92
|
-
override peek(key?: unknown): unknown {
|
|
93
|
-
return isKey(key) ? this.state.value[key] : {...this.state.value};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Set the value
|
|
98
|
-
* @param value New value _(defaults to an empty object)_
|
|
99
|
-
*/
|
|
100
|
-
set(
|
|
101
|
-
value?:
|
|
102
|
-
| Value
|
|
103
|
-
| (() => null | undefined | Value | Promise<null | undefined | Value>)
|
|
104
|
-
| Promise<null | undefined | Value>,
|
|
105
|
-
): void;
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Set a value by key
|
|
109
|
-
* @param key Key of the value to set
|
|
110
|
-
* @param value New value
|
|
111
|
-
*/
|
|
112
|
-
set<Key extends keyof Value>(
|
|
113
|
-
key: Key,
|
|
114
|
-
value: Value[Key] | (() => Value[Key] | Promise<Value[Key]>) | Promise<Value[Key]>,
|
|
115
|
-
): void;
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Set a value by key
|
|
119
|
-
* @param key Key of the value to set
|
|
120
|
-
* @param value New value
|
|
121
|
-
*/
|
|
122
|
-
set(key: Key, value: unknown): void;
|
|
123
|
-
|
|
124
|
-
set(first?: unknown, second?: unknown): void {
|
|
125
|
-
setProxyValue<Value>(
|
|
126
|
-
false,
|
|
127
|
-
this.state,
|
|
128
|
-
isStoreObject,
|
|
129
|
-
isKey,
|
|
130
|
-
setObject,
|
|
131
|
-
setProperty,
|
|
132
|
-
first,
|
|
133
|
-
second,
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* @inheritdoc
|
|
139
|
-
*/
|
|
140
|
-
override subscribe(callback: (value: Value) => void): Unsubscribe;
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Subscribe to changes for a specific key
|
|
144
|
-
* @param key Key of the value to subscribe to
|
|
145
|
-
* @param callback Callback for changes
|
|
146
|
-
* @returns Unsubscribe callback
|
|
147
|
-
*/
|
|
148
|
-
override subscribe<Key extends keyof Value>(
|
|
149
|
-
key: Key,
|
|
150
|
-
callback: (value: Value[Key] | undefined) => void,
|
|
151
|
-
): Unsubscribe;
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Subscribe to changes for a specific key
|
|
155
|
-
* @param key Key of the value to subscribe to
|
|
156
|
-
* @param callback Callback for changes
|
|
157
|
-
* @returns Unsubscribe callback
|
|
158
|
-
*/
|
|
159
|
-
override subscribe(key: Key, callback: (value: unknown) => void): Unsubscribe;
|
|
160
|
-
|
|
161
|
-
override subscribe(first: Key | GenericCallback, second?: GenericCallback): Unsubscribe {
|
|
162
|
-
if (isKey(first) && typeof second === 'function') {
|
|
163
|
-
return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return typeof first === 'function' ? subscribe(this.state, first) : noop;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Update the value _(based on the current value)_
|
|
171
|
-
* @param callback Callback to update the value
|
|
172
|
-
*/
|
|
173
|
-
update(callback: (value: Value) => Value): void {
|
|
174
|
-
const updated = callback(this.state.value);
|
|
175
|
-
|
|
176
|
-
if (updated == null || isPlainObject(updated)) {
|
|
177
|
-
setObject(this.state, updated);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
11
|
+
import {getSimpleValue} from '../helpers/value';
|
|
12
|
+
import type {
|
|
13
|
+
Computed,
|
|
14
|
+
ComputedEffect,
|
|
15
|
+
ReactiveOptions,
|
|
16
|
+
ReactiveState,
|
|
17
|
+
ReactiveStore,
|
|
18
|
+
Unsubscribe,
|
|
19
|
+
} from '../models';
|
|
20
|
+
import {noop, subscribe, unsubscribe} from '../subscription';
|
|
21
|
+
import {reactive} from './reactive';
|
|
181
22
|
|
|
182
23
|
function isStoreObject<Value extends PlainObject>(value: unknown): value is Value | undefined {
|
|
183
24
|
return value == null || isPlainObject(value);
|
|
@@ -225,6 +66,7 @@ function setProperty<Value extends PlainObject>(
|
|
|
225
66
|
|
|
226
67
|
/**
|
|
227
68
|
* Create a reactive store from a function result
|
|
69
|
+
*
|
|
228
70
|
* @param value Initial object value
|
|
229
71
|
* @param options Reactivity options
|
|
230
72
|
* @returns Reactive store
|
|
@@ -232,10 +74,11 @@ function setProperty<Value extends PlainObject>(
|
|
|
232
74
|
export function store<Value extends PlainObject>(
|
|
233
75
|
value: () => Value | Promise<Value>,
|
|
234
76
|
options?: ReactiveOptions<Value>,
|
|
235
|
-
):
|
|
77
|
+
): ReactiveStore<Value>;
|
|
236
78
|
|
|
237
79
|
/**
|
|
238
80
|
* Create a reactive store from a promise
|
|
81
|
+
*
|
|
239
82
|
* @param value Initial object value
|
|
240
83
|
* @param options Reactivity options
|
|
241
84
|
* @returns Reactive store
|
|
@@ -243,10 +86,11 @@ export function store<Value extends PlainObject>(
|
|
|
243
86
|
export function store<Value extends PlainObject>(
|
|
244
87
|
value: Promise<Value>,
|
|
245
88
|
options?: ReactiveOptions<Value>,
|
|
246
|
-
):
|
|
89
|
+
): ReactiveStore<Value>;
|
|
247
90
|
|
|
248
91
|
/**
|
|
249
92
|
* Create a reactive store
|
|
93
|
+
*
|
|
250
94
|
* @param value Initial object value
|
|
251
95
|
* @param options Reactivity options
|
|
252
96
|
* @returns Reactive store
|
|
@@ -254,15 +98,78 @@ export function store<Value extends PlainObject>(
|
|
|
254
98
|
export function store<Value extends PlainObject>(
|
|
255
99
|
value: Value,
|
|
256
100
|
options?: ReactiveOptions<Value>,
|
|
257
|
-
):
|
|
101
|
+
): ReactiveStore<Value>;
|
|
258
102
|
|
|
259
103
|
export function store<Value extends PlainObject>(
|
|
260
104
|
value: Value | (() => Value | Promise<Value>) | Promise<Value>,
|
|
261
105
|
options?: ReactiveOptions<Value>,
|
|
262
|
-
):
|
|
263
|
-
const
|
|
106
|
+
): ReactiveStore<Value> {
|
|
107
|
+
const [rx, state] = reactive<Value>(undefined as never, options);
|
|
108
|
+
|
|
109
|
+
const keyed = new Map<Key, [Computed<unknown>, ComputedEffect]>();
|
|
110
|
+
|
|
111
|
+
state.value = new Proxy({} as Value, {
|
|
112
|
+
set: (target: Value, property: PropertyKey, value: unknown) =>
|
|
113
|
+
setValueInProxy({
|
|
114
|
+
target,
|
|
115
|
+
property,
|
|
116
|
+
state,
|
|
117
|
+
value,
|
|
118
|
+
isArray: false,
|
|
119
|
+
}),
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const instance = {
|
|
123
|
+
...rx,
|
|
124
|
+
get: (value?: unknown): unknown =>
|
|
125
|
+
isKey(value)
|
|
126
|
+
? getReactiveValueInProxy(instance, keyed, value, false).get()
|
|
127
|
+
: getSimpleValue(state),
|
|
128
|
+
notify(): void {
|
|
129
|
+
emityProxyValues(state, keyed);
|
|
130
|
+
},
|
|
131
|
+
peek: (value?: unknown): unknown => (isKey(value) ? state.value[value] : {...state.value}),
|
|
132
|
+
set: (first?: unknown, second?: unknown) => {
|
|
133
|
+
setProxyValue<Value>(
|
|
134
|
+
false,
|
|
135
|
+
state,
|
|
136
|
+
isStoreObject,
|
|
137
|
+
isKey,
|
|
138
|
+
setObject,
|
|
139
|
+
setProperty,
|
|
140
|
+
first,
|
|
141
|
+
second,
|
|
142
|
+
);
|
|
143
|
+
},
|
|
144
|
+
subscribe: (first: Key | GenericCallback, second?: GenericCallback): Unsubscribe => {
|
|
145
|
+
if (isKey(first) && typeof second === 'function') {
|
|
146
|
+
return getReactiveValueInProxy(instance, keyed, first, false).subscribe(second);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return typeof first === 'function' ? subscribe(state, first) : noop;
|
|
150
|
+
},
|
|
151
|
+
unsubscribe: (first: Key | GenericCallback, second?: GenericCallback) => {
|
|
152
|
+
if (isKey(first) && typeof second === 'function') {
|
|
153
|
+
getReactiveValueInProxy(instance, keyed, first, false)?.unsubscribe(second);
|
|
154
|
+
} else if (typeof first === 'function') {
|
|
155
|
+
unsubscribe(state, first);
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
update: (callback: (value: Value) => Value) => {
|
|
159
|
+
const updated = callback(state.value);
|
|
160
|
+
|
|
161
|
+
if (updated == null || isPlainObject(updated)) {
|
|
162
|
+
setObject(state, updated);
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
Object.defineProperty(instance, NAME_MORA, {
|
|
168
|
+
enumerable: false,
|
|
169
|
+
value: NAME_STORE,
|
|
170
|
+
});
|
|
264
171
|
|
|
265
172
|
instance.set(value);
|
|
266
173
|
|
|
267
|
-
return instance
|
|
174
|
+
return Object.freeze(instance) as ReactiveStore<Value>;
|
|
268
175
|
}
|