@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
package/src/value/readonly.ts
CHANGED
|
@@ -1,71 +1,85 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import {
|
|
2
|
+
NAME_MORA,
|
|
3
|
+
NAME_READONLY,
|
|
4
|
+
SUBSCRIPTION_TYPE_FROZEN,
|
|
5
|
+
SUBSCRIPTION_TYPE_ORIGINAL,
|
|
6
|
+
SYMBOL_STATE,
|
|
7
|
+
} from '../constants';
|
|
8
|
+
import {subscribeToReadonly} from '../helpers/subscription';
|
|
9
|
+
import {getFrozenValue, getSignalValue, getStringValue, peekSignalValue} from '../helpers/value';
|
|
10
|
+
import type {ReadonlyFrozenSignal, ReadonlySignal, SignalState, InternalSignal} from '../models';
|
|
11
|
+
|
|
12
|
+
// #region Instance
|
|
13
|
+
|
|
14
|
+
function Readonly(this: any, state: SignalState, frozen: boolean) {
|
|
15
|
+
this[SYMBOL_STATE] = state;
|
|
16
|
+
|
|
17
|
+
Object.defineProperty(this, SUBSCRIPTION_TYPE_FROZEN, {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
value: frozen,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Readonly.prototype[NAME_MORA] = NAME_READONLY;
|
|
24
|
+
|
|
25
|
+
Readonly.prototype.subscribe = subscribeToReadonly;
|
|
26
|
+
Readonly.prototype.toString = getStringValue;
|
|
27
|
+
|
|
28
|
+
Readonly.prototype.get = function () {
|
|
29
|
+
return getReadonlyValue(this, false, this[SUBSCRIPTION_TYPE_FROZEN]);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
Readonly.prototype.peek = function (copy?: boolean) {
|
|
33
|
+
return getReadonlyValue(this, true, this[SUBSCRIPTION_TYPE_FROZEN], copy);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
Readonly.prototype.toJSON = function () {
|
|
37
|
+
return this[SYMBOL_STATE].value;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// #endregion
|
|
41
|
+
|
|
42
|
+
// #region Functions
|
|
12
43
|
|
|
13
44
|
export function getReadonlyInstance<Value>(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
handlers: Record<string, GenericCallback>,
|
|
17
|
-
frozen: boolean,
|
|
45
|
+
this: InternalSignal,
|
|
46
|
+
frozen?: never,
|
|
18
47
|
): ReadonlySignal<Value> {
|
|
19
|
-
const key = frozen ?
|
|
48
|
+
const key = (frozen === true ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_ORIGINAL) as never;
|
|
20
49
|
|
|
21
|
-
|
|
50
|
+
this[SYMBOL_STATE].readonlies ??= {};
|
|
22
51
|
|
|
23
|
-
|
|
52
|
+
this[SYMBOL_STATE].readonlies[key] ??= getReadonlySignal(
|
|
53
|
+
this[SYMBOL_STATE],
|
|
54
|
+
frozen === true,
|
|
55
|
+
) as never;
|
|
56
|
+
|
|
57
|
+
return this[SYMBOL_STATE].readonlies[key] as never;
|
|
24
58
|
}
|
|
25
59
|
|
|
26
|
-
export function getReadonlySignal
|
|
27
|
-
state:
|
|
28
|
-
handlers: Record<string, GenericCallback>,
|
|
60
|
+
export function getReadonlySignal(
|
|
61
|
+
state: SignalState,
|
|
29
62
|
frozen: boolean,
|
|
30
|
-
): ReadonlySignal<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
get: () => getReadonlyValue(state, false, frozen),
|
|
34
|
-
peek: () => getReadonlyValue(state, true, frozen),
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
Object.defineProperties(instance, {
|
|
38
|
-
[NAME_MORA]: {
|
|
39
|
-
enumerable: false,
|
|
40
|
-
value: NAME_READONLY,
|
|
41
|
-
},
|
|
42
|
-
frozen: {
|
|
43
|
-
enumerable: true,
|
|
44
|
-
value: frozen,
|
|
45
|
-
},
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
return Object.freeze(instance) as ReadonlySignal<Value>;
|
|
63
|
+
): ReadonlySignal<unknown> | ReadonlyFrozenSignal<unknown> {
|
|
64
|
+
// @ts-expect-error All good, no worries :-)
|
|
65
|
+
return new Readonly(state, frozen);
|
|
49
66
|
}
|
|
50
67
|
|
|
51
|
-
function getReadonlyValue
|
|
52
|
-
|
|
68
|
+
function getReadonlyValue(
|
|
69
|
+
instance: InternalSignal,
|
|
53
70
|
peek: boolean,
|
|
54
71
|
frozen: boolean,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (!frozen) {
|
|
59
|
-
return value;
|
|
60
|
-
}
|
|
72
|
+
copy?: boolean,
|
|
73
|
+
): unknown {
|
|
74
|
+
let value: unknown;
|
|
61
75
|
|
|
62
|
-
if (
|
|
63
|
-
value =
|
|
64
|
-
} else if (isPlainObject(state.value)) {
|
|
65
|
-
value = {...state.value} as Value;
|
|
76
|
+
if (peek) {
|
|
77
|
+
value = peekSignalValue.call(instance, copy === true);
|
|
66
78
|
} else {
|
|
67
|
-
value =
|
|
79
|
+
value = getSignalValue.call(instance);
|
|
68
80
|
}
|
|
69
81
|
|
|
70
|
-
return
|
|
82
|
+
return frozen ? getFrozenValue(value) : value;
|
|
71
83
|
}
|
|
84
|
+
|
|
85
|
+
// #endregion
|
package/src/value/signal.ts
CHANGED
|
@@ -1,15 +1,56 @@
|
|
|
1
|
-
import {NAME_MORA, NAME_SIGNAL} from '../constants';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import {NAME_MORA, NAME_SIGNAL, SYMBOL_STATE} from '../constants';
|
|
2
|
+
import {getState} from '../helpers/misc';
|
|
3
|
+
import {subscribeToSignal} from '../helpers/subscription';
|
|
4
|
+
import {
|
|
5
|
+
emitValue,
|
|
6
|
+
getSignalValue,
|
|
7
|
+
getStringValue,
|
|
8
|
+
handleSignalValue,
|
|
9
|
+
peekSignalValue,
|
|
10
|
+
updateSignalValue,
|
|
11
|
+
} from '../helpers/value';
|
|
12
|
+
import type {ReactiveOptions, Signal, InternalSignal} from '../models';
|
|
6
13
|
import {getReadonlyInstance} from './readonly';
|
|
7
14
|
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
// #region Instance
|
|
16
|
+
|
|
17
|
+
function Signal(this: any, value: unknown, options?: ReactiveOptions<unknown>) {
|
|
18
|
+
this[SYMBOL_STATE] = getState(undefined, options);
|
|
19
|
+
|
|
20
|
+
handleSignalValue(this, value, setAndEmit);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Signal.prototype[NAME_MORA] = NAME_SIGNAL;
|
|
24
|
+
|
|
25
|
+
Signal.prototype.asReadonly = getReadonlyInstance;
|
|
26
|
+
Signal.prototype.get = getSignalValue;
|
|
27
|
+
Signal.prototype.peek = peekSignalValue;
|
|
28
|
+
Signal.prototype.subscribe = subscribeToSignal;
|
|
29
|
+
Signal.prototype.toString = getStringValue;
|
|
30
|
+
|
|
31
|
+
Signal.prototype.set = function (value: never) {
|
|
32
|
+
return handleSignalValue(this, value, setAndEmit);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
Signal.prototype.toJSON = function () {
|
|
36
|
+
return this[SYMBOL_STATE].value;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
Signal.prototype.update = function (callback: never) {
|
|
40
|
+
return updateSignalValue(this, callback, setAndEmit);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// #endregion
|
|
44
|
+
|
|
45
|
+
// #region Functions
|
|
46
|
+
|
|
47
|
+
function setAndEmit(instance: InternalSignal, value: unknown): void {
|
|
48
|
+
const state = instance[SYMBOL_STATE];
|
|
49
|
+
|
|
50
|
+
if (!(state.equal ?? Object.is)(state.value as never, value as never)) {
|
|
10
51
|
state.value = value;
|
|
11
52
|
|
|
12
|
-
emitValue(
|
|
53
|
+
emitValue(instance);
|
|
13
54
|
}
|
|
14
55
|
}
|
|
15
56
|
|
|
@@ -46,42 +87,9 @@ export function signal<Value>(
|
|
|
46
87
|
*/
|
|
47
88
|
export function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value>;
|
|
48
89
|
|
|
49
|
-
export function signal<
|
|
50
|
-
|
|
51
|
-
options
|
|
52
|
-
): Signal<Value> {
|
|
53
|
-
const [rx, state] = reactive<Value>(undefined as unknown as Value, options);
|
|
54
|
-
|
|
55
|
-
const readonlies: ReadonlyInstances<Value> = {};
|
|
56
|
-
|
|
57
|
-
const handlers = {
|
|
58
|
-
...rx,
|
|
59
|
-
subscribe: (callback: (value: Value) => void) => subscribe(state, callback),
|
|
60
|
-
unsubscribe: (callback: (value: Value) => void) => {
|
|
61
|
-
state.subscriptions.delete(callback);
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const instance = {
|
|
66
|
-
...handlers,
|
|
67
|
-
asReadonly: (frozen?: unknown) =>
|
|
68
|
-
getReadonlyInstance(state, readonlies, handlers, frozen === true),
|
|
69
|
-
get: () => getSimpleValue(state),
|
|
70
|
-
peek: () => state.value,
|
|
71
|
-
set: (value: Value | (() => Value | Promise<Value>) | Promise<Value>) => {
|
|
72
|
-
handleSimpleValue(state, value, setAndEmit);
|
|
73
|
-
},
|
|
74
|
-
update: (callback: (value: Value) => Value) => {
|
|
75
|
-
handleSimpleValue(state, callback(state.value), setAndEmit);
|
|
76
|
-
},
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
Object.defineProperty(instance, NAME_MORA, {
|
|
80
|
-
enumerable: false,
|
|
81
|
-
value: NAME_SIGNAL,
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
handleSimpleValue(state, value, setAndEmit);
|
|
85
|
-
|
|
86
|
-
return Object.freeze(instance) as Signal<Value>;
|
|
90
|
+
export function signal(value: unknown, options?: ReactiveOptions<unknown>): Signal<unknown> {
|
|
91
|
+
// @ts-expect-error All good, no worries :-)
|
|
92
|
+
return new Signal(value, options);
|
|
87
93
|
}
|
|
94
|
+
|
|
95
|
+
// #endregion
|
package/src/value/store.ts
CHANGED
|
@@ -1,98 +1,55 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {NAME_MORA, NAME_STORE} from '../constants';
|
|
1
|
+
import type {PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
+
import {NAME_MORA, NAME_STORE, SYMBOL_STATE} from '../constants';
|
|
3
|
+
import {getState} from '../helpers/misc';
|
|
5
4
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
emitProxyValues,
|
|
6
|
+
getValueInProxy,
|
|
7
|
+
peekValueInProxy,
|
|
8
8
|
setProxyValue,
|
|
9
9
|
setValueInProxy,
|
|
10
|
+
updateProxyValue,
|
|
10
11
|
} from '../helpers/proxy';
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
ComputedEffect,
|
|
15
|
-
ReactiveOptions,
|
|
16
|
-
ReactiveState,
|
|
17
|
-
ReactiveStore,
|
|
18
|
-
ReadonlyInstances,
|
|
19
|
-
Unsubscribe,
|
|
20
|
-
} from '../models';
|
|
21
|
-
import {noop, subscribe, unsubscribe} from '../subscription';
|
|
22
|
-
import {reactive} from './reactive';
|
|
12
|
+
import {subscribeToProxy} from '../helpers/subscription';
|
|
13
|
+
import {getStringValue} from '../helpers/value';
|
|
14
|
+
import type {ReactiveOptions, ReactiveStore} from '../models';
|
|
23
15
|
import {getReadonlyInstance} from './readonly';
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
return value == null || isPlainObject(value);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function setObject(state: ReactiveState<PlainObject, never>, value: PlainObject | undefined): void {
|
|
30
|
-
startBatch();
|
|
31
|
-
|
|
32
|
-
const actual = value ?? {};
|
|
33
|
-
const proxy = state.value as PlainObject;
|
|
34
|
-
|
|
35
|
-
const proxyKeys = Object.keys(proxy);
|
|
36
|
-
const actualKeys = Object.keys(actual);
|
|
37
|
-
|
|
38
|
-
let {length} = proxyKeys;
|
|
39
|
-
|
|
40
|
-
for (let index = 0; index < length; index += 1) {
|
|
41
|
-
const key = proxyKeys[index];
|
|
42
|
-
|
|
43
|
-
proxy[key] = actualKeys.includes(key) ? actual[key] : undefined;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
length = actualKeys.length;
|
|
47
|
-
|
|
48
|
-
for (let index = 0; index < length; index += 1) {
|
|
49
|
-
const key = actualKeys[index];
|
|
17
|
+
// #region Instance
|
|
50
18
|
|
|
51
|
-
|
|
52
|
-
|
|
19
|
+
function ReactiveStore(this: any, value: never, options?: ReactiveOptions<unknown>) {
|
|
20
|
+
this[SYMBOL_STATE] = {
|
|
21
|
+
...getState(undefined, options),
|
|
22
|
+
isArray: false,
|
|
23
|
+
};
|
|
53
24
|
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
25
|
+
this[SYMBOL_STATE].value = new Proxy(
|
|
26
|
+
{},
|
|
27
|
+
{
|
|
28
|
+
set: (target, property, value) => setValueInProxy(this, target, property, value),
|
|
29
|
+
},
|
|
30
|
+
);
|
|
57
31
|
|
|
58
|
-
|
|
32
|
+
setProxyValue.call(this, value);
|
|
59
33
|
}
|
|
60
34
|
|
|
61
|
-
|
|
62
|
-
state: ReactiveState<Value, Value>,
|
|
63
|
-
first?: unknown,
|
|
64
|
-
second?: boolean,
|
|
65
|
-
): unknown {
|
|
66
|
-
let value: unknown;
|
|
35
|
+
ReactiveStore.prototype[NAME_MORA] = NAME_STORE;
|
|
67
36
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
37
|
+
ReactiveStore.prototype.asReadonly = getReadonlyInstance;
|
|
38
|
+
ReactiveStore.prototype.get = getValueInProxy;
|
|
39
|
+
ReactiveStore.prototype.notify = emitProxyValues;
|
|
40
|
+
ReactiveStore.prototype.peek = peekValueInProxy;
|
|
41
|
+
ReactiveStore.prototype.set = setProxyValue;
|
|
42
|
+
ReactiveStore.prototype.subscribe = subscribeToProxy;
|
|
43
|
+
ReactiveStore.prototype.toString = getStringValue;
|
|
44
|
+
ReactiveStore.prototype.update = updateProxyValue;
|
|
73
45
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
46
|
+
ReactiveStore.prototype.toJSON = function () {
|
|
47
|
+
return this[SYMBOL_STATE].value;
|
|
48
|
+
};
|
|
77
49
|
|
|
78
|
-
|
|
79
|
-
return value.slice();
|
|
80
|
-
}
|
|
50
|
+
// #endregion
|
|
81
51
|
|
|
82
|
-
|
|
83
|
-
return {...value};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return value;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function setProperty<Value extends PlainObject>(
|
|
90
|
-
state: ReactiveState<Value, Value>,
|
|
91
|
-
key: unknown,
|
|
92
|
-
value: unknown,
|
|
93
|
-
): void {
|
|
94
|
-
(state.value as PlainObject)[key as Key] = value;
|
|
95
|
-
}
|
|
52
|
+
// #region Functions
|
|
96
53
|
|
|
97
54
|
/**
|
|
98
55
|
* Create a reactive store from a function result
|
|
@@ -130,92 +87,9 @@ export function store<Value extends PlainObject>(
|
|
|
130
87
|
options?: ReactiveOptions<Value>,
|
|
131
88
|
): ReactiveStore<Value>;
|
|
132
89
|
|
|
133
|
-
export function store<
|
|
134
|
-
|
|
135
|
-
options
|
|
136
|
-
): ReactiveStore<Value> {
|
|
137
|
-
const [rx, state] = reactive<Value>(undefined as never, options);
|
|
138
|
-
|
|
139
|
-
const keyed = new Map<Key, [Computed<unknown>, ComputedEffect]>();
|
|
140
|
-
const readonlies: ReadonlyInstances<Value> = {};
|
|
141
|
-
|
|
142
|
-
let instance: Record<string, GenericCallback> = {};
|
|
143
|
-
|
|
144
|
-
state.value = new Proxy({} as Value, {
|
|
145
|
-
set: (target: Value, property: PropertyKey, value: unknown) =>
|
|
146
|
-
setValueInProxy({
|
|
147
|
-
target,
|
|
148
|
-
property,
|
|
149
|
-
state,
|
|
150
|
-
value,
|
|
151
|
-
isArray: false,
|
|
152
|
-
}),
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
const handlers = {
|
|
156
|
-
...rx,
|
|
157
|
-
get: (value?: unknown): unknown =>
|
|
158
|
-
isKey(value)
|
|
159
|
-
? getReactiveValueInProxy(instance as ReactiveStore<Value>, keyed, value, false).get()
|
|
160
|
-
: getSimpleValue(state),
|
|
161
|
-
peek: (first?: unknown, second?: boolean): unknown => peekStoreValue(state, first, second),
|
|
162
|
-
subscribe: (first: Key | GenericCallback, second?: GenericCallback): Unsubscribe => {
|
|
163
|
-
if (isKey(first) && typeof second === 'function') {
|
|
164
|
-
return getReactiveValueInProxy(
|
|
165
|
-
instance as ReactiveStore<Value>,
|
|
166
|
-
keyed,
|
|
167
|
-
first,
|
|
168
|
-
false,
|
|
169
|
-
).subscribe(second);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return typeof first === 'function' ? subscribe(state, first) : noop;
|
|
173
|
-
},
|
|
174
|
-
unsubscribe: (first: Key | GenericCallback, second?: GenericCallback) => {
|
|
175
|
-
if (isKey(first) && typeof second === 'function') {
|
|
176
|
-
getReactiveValueInProxy(instance as ReactiveStore<Value>, keyed, first, false)?.unsubscribe(
|
|
177
|
-
second,
|
|
178
|
-
);
|
|
179
|
-
} else if (typeof first === 'function') {
|
|
180
|
-
unsubscribe(state, first);
|
|
181
|
-
}
|
|
182
|
-
},
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
instance = {
|
|
186
|
-
...handlers,
|
|
187
|
-
asReadonly: (frozen?: unknown) =>
|
|
188
|
-
getReadonlyInstance(state, readonlies, handlers, frozen === true),
|
|
189
|
-
notify(): void {
|
|
190
|
-
emityProxyValues(state, keyed);
|
|
191
|
-
},
|
|
192
|
-
set: (first?: unknown, second?: unknown) => {
|
|
193
|
-
setProxyValue<Value>(
|
|
194
|
-
false,
|
|
195
|
-
state,
|
|
196
|
-
isStoreObject,
|
|
197
|
-
isKey,
|
|
198
|
-
setObject,
|
|
199
|
-
setProperty,
|
|
200
|
-
first,
|
|
201
|
-
second,
|
|
202
|
-
);
|
|
203
|
-
},
|
|
204
|
-
update: (callback: (value: Value) => Value) => {
|
|
205
|
-
const updated = callback(state.value);
|
|
206
|
-
|
|
207
|
-
if (updated == null || isPlainObject(updated)) {
|
|
208
|
-
setObject(state, updated);
|
|
209
|
-
}
|
|
210
|
-
},
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
Object.defineProperty(instance, NAME_MORA, {
|
|
214
|
-
enumerable: false,
|
|
215
|
-
value: NAME_STORE,
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
instance.set(value);
|
|
219
|
-
|
|
220
|
-
return Object.freeze(instance) as ReactiveStore<Value>;
|
|
90
|
+
export function store(value: unknown, options?: ReactiveOptions<unknown>): ReactiveStore<unknown> {
|
|
91
|
+
// @ts-expect-error All good, no worries :-)
|
|
92
|
+
return new ReactiveStore(value, options);
|
|
221
93
|
}
|
|
94
|
+
|
|
95
|
+
// #endregion
|
package/types/constants.d.ts
CHANGED
|
@@ -12,5 +12,5 @@ export declare const NAME_EFFECT = "effect";
|
|
|
12
12
|
export declare const NAME_MORA = "$mora";
|
|
13
13
|
export declare const NAME_SIGNAL = "signal";
|
|
14
14
|
export declare const NAME_STORE = "store";
|
|
15
|
-
export declare const
|
|
15
|
+
export declare const NAMES: Set<string>;
|
|
16
16
|
export declare const PROPERTY_LENGTH = "length";
|
package/types/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { startBatch, stopBatch } from './batch';
|
|
2
2
|
export { effect, type Effect } from './effect';
|
|
3
|
-
export { isArray, isComputed, isEffect, isReactive, isSignal } from './helpers/is';
|
|
3
|
+
export { isArray, isComputed, isEffect, isReactive, isSignal, } from './helpers/is';
|
|
4
4
|
export type { Unsubscribe } from './models';
|
|
5
5
|
export { array, type ReactiveArray } from './value/array';
|
|
6
6
|
export { computed, type Computed } from './value/computed';
|
package/types/value/array.d.ts
CHANGED
|
@@ -131,7 +131,7 @@ export declare class ReactiveArray<Item> extends Reactive<Item[], Item> {
|
|
|
131
131
|
/**
|
|
132
132
|
* Create a reactive array
|
|
133
133
|
* @param value Initial array of items
|
|
134
|
-
* @param options
|
|
134
|
+
* @param options Optional reactivity options
|
|
135
135
|
* @returns Reactive array
|
|
136
136
|
*/
|
|
137
137
|
export declare function array<Item>(value: Item[], options?: ReactiveOptions<Item>): ReactiveArray<Item>;
|
|
@@ -10,8 +10,5 @@ export declare class Computed<Value> extends Reactive<Value> {
|
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* Create a computed value
|
|
13
|
-
* @param callback Callback to compute the value
|
|
14
|
-
* @param options Reactivity options
|
|
15
|
-
* @returns Computed value
|
|
16
13
|
*/
|
|
17
14
|
export declare function computed<Value>(callback: () => Value, options?: ReactiveOptions<Value>): Computed<Value>;
|
package/types/value/signal.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export declare class Signal<Value> extends Reactive<Value> {
|
|
|
20
20
|
/**
|
|
21
21
|
* Create a reactive value
|
|
22
22
|
* @param value Initial value
|
|
23
|
-
* @param options
|
|
23
|
+
* @param options Optional reactivity options
|
|
24
24
|
* @returns Reactive value
|
|
25
25
|
*/
|
|
26
26
|
export declare function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value>;
|
package/types/value/store.d.ts
CHANGED
|
@@ -88,7 +88,7 @@ export declare class Store<Value extends PlainObject> extends Reactive<Value, Va
|
|
|
88
88
|
/**
|
|
89
89
|
* Create a reactive store
|
|
90
90
|
* @param value Initial object value
|
|
91
|
-
* @param options
|
|
91
|
+
* @param options Optional reactivity options
|
|
92
92
|
* @returns Reactive store
|
|
93
93
|
*/
|
|
94
94
|
export declare function store<Value extends PlainObject>(value: Value, options?: ReactiveOptions<Value>): Store<Value>;
|
package/dist/subscription.d.mts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { ReactiveState, Unsubscribe } from "./models.mjs";
|
|
2
|
-
//#region src/subscription.d.ts
|
|
3
|
-
declare function noop(): void;
|
|
4
|
-
declare function subscribe<Value>(state: ReactiveState<Value, never>, callback: (value: Value) => void): Unsubscribe;
|
|
5
|
-
declare function unsubscribe<Value>(state: ReactiveState<Value, never>, callback: (value: Value) => void): void;
|
|
6
|
-
//#endregion
|
|
7
|
-
export { noop, subscribe, unsubscribe };
|
package/dist/subscription.mjs
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
//#region src/subscription.ts
|
|
2
|
-
function noop() {}
|
|
3
|
-
function subscribe(state, callback) {
|
|
4
|
-
if (typeof callback !== "function" || state.subscriptions.has(callback)) return noop;
|
|
5
|
-
state.subscriptions.set(callback, subscription(state, callback));
|
|
6
|
-
return () => {
|
|
7
|
-
unsubscribe(state, callback);
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
function subscription(state, callback) {
|
|
11
|
-
const instance = {
|
|
12
|
-
callback,
|
|
13
|
-
state,
|
|
14
|
-
destroy: () => {
|
|
15
|
-
instance.callback = noop;
|
|
16
|
-
instance.state = void 0;
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
callback(state.value);
|
|
20
|
-
return instance;
|
|
21
|
-
}
|
|
22
|
-
function unsubscribe(state, callback) {
|
|
23
|
-
state.subscriptions.get(callback)?.destroy();
|
|
24
|
-
state.subscriptions.delete(callback);
|
|
25
|
-
}
|
|
26
|
-
//#endregion
|
|
27
|
-
export { noop, subscribe, unsubscribe };
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { Reactive, ReactiveOptions, ReactiveState } from "../models.mjs";
|
|
2
|
-
//#region src/value/reactive.d.ts
|
|
3
|
-
declare function reactive<Value, Equal = Value>(value: Value, options?: ReactiveOptions<Equal>): [Reactive<Value>, ReactiveState<Value, Equal>];
|
|
4
|
-
//#endregion
|
|
5
|
-
export { reactive };
|
package/dist/value/reactive.mjs
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
//#region src/value/reactive.ts
|
|
2
|
-
function reactive(value, options) {
|
|
3
|
-
const state = {
|
|
4
|
-
computeds: /* @__PURE__ */ new Set(),
|
|
5
|
-
effects: /* @__PURE__ */ new Set(),
|
|
6
|
-
equal: typeof options === "object" && typeof options?.equal === "function" ? options.equal : Object.is,
|
|
7
|
-
subscriptions: /* @__PURE__ */ new Map(),
|
|
8
|
-
value
|
|
9
|
-
};
|
|
10
|
-
return [{
|
|
11
|
-
toJSON: () => state.value,
|
|
12
|
-
toString: () => String(state.value)
|
|
13
|
-
}, state];
|
|
14
|
-
}
|
|
15
|
-
//#endregion
|
|
16
|
-
export { reactive };
|
package/src/subscription.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import type {ReactiveState, Subscription, Unsubscribe} from './models';
|
|
2
|
-
|
|
3
|
-
export function noop(): void {}
|
|
4
|
-
|
|
5
|
-
export function subscribe<Value>(
|
|
6
|
-
state: ReactiveState<Value, never>,
|
|
7
|
-
callback: (value: Value) => void,
|
|
8
|
-
): Unsubscribe {
|
|
9
|
-
if (typeof callback !== 'function' || state.subscriptions.has(callback)) {
|
|
10
|
-
return noop;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
state.subscriptions.set(callback, subscription(state, callback));
|
|
14
|
-
|
|
15
|
-
return () => {
|
|
16
|
-
unsubscribe(state, callback);
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function subscription<Value>(
|
|
21
|
-
state: ReactiveState<Value, never>,
|
|
22
|
-
callback: (value: Value) => void,
|
|
23
|
-
): Subscription {
|
|
24
|
-
const instance: Subscription = {
|
|
25
|
-
callback,
|
|
26
|
-
state,
|
|
27
|
-
destroy: () => {
|
|
28
|
-
instance.callback = noop;
|
|
29
|
-
instance.state = undefined as never;
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
callback(state.value);
|
|
34
|
-
|
|
35
|
-
return instance;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function unsubscribe<Value>(
|
|
39
|
-
state: ReactiveState<Value, never>,
|
|
40
|
-
callback: (value: Value) => void,
|
|
41
|
-
): void {
|
|
42
|
-
state.subscriptions.get(callback)?.destroy();
|
|
43
|
-
|
|
44
|
-
state.subscriptions.delete(callback);
|
|
45
|
-
}
|
package/src/value/reactive.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type {Reactive, ReactiveOptions, ReactiveState} from '../models';
|
|
2
|
-
|
|
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> = {
|
|
8
|
-
computeds: new Set(),
|
|
9
|
-
effects: new Set(),
|
|
10
|
-
equal:
|
|
11
|
-
typeof options === 'object' && typeof options?.equal === 'function'
|
|
12
|
-
? options.equal
|
|
13
|
-
: Object.is,
|
|
14
|
-
subscriptions: new Map(),
|
|
15
|
-
value: value as Value,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const instance = {
|
|
19
|
-
toJSON: () => state.value,
|
|
20
|
-
toString: () => String(state.value),
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
return [instance, state];
|
|
24
|
-
}
|