@oscarpalmer/mora 0.26.0 → 0.28.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 +14 -0
- package/dist/{batch.js → batch.mjs} +13 -3
- package/dist/constants.d.mts +20 -0
- package/dist/{constants.js → constants.mjs} +2 -0
- package/dist/effect.d.mts +17 -0
- package/dist/{effect.js → effect.mjs} +11 -4
- package/dist/helpers/is.d.mts +47 -0
- package/dist/helpers/is.mjs +55 -0
- package/dist/helpers/proxy.d.mts +15 -0
- package/dist/helpers/proxy.mjs +72 -0
- package/dist/helpers/value.d.mts +8 -0
- package/dist/helpers/{value.js → value.mjs} +4 -2
- package/dist/index.d.mts +10 -0
- package/dist/index.mjs +8 -0
- package/dist/models.d.mts +62 -0
- package/dist/models.mjs +1 -0
- package/dist/{mora.full.js → mora.full.mjs} +206 -106
- package/dist/subscription.d.mts +15 -0
- package/dist/{subscription.js → subscription.mjs} +2 -0
- package/dist/value/array.d.mts +156 -0
- package/dist/value/array.mjs +165 -0
- package/dist/value/computed.d.mts +21 -0
- package/dist/value/computed.mjs +68 -0
- package/dist/value/reactive.d.mts +40 -0
- package/dist/value/{reactive.js → reactive.mjs} +25 -2
- package/dist/value/signal.d.mts +44 -0
- package/dist/value/signal.mjs +59 -0
- package/dist/value/store.d.mts +112 -0
- package/dist/value/store.mjs +81 -0
- package/package.json +41 -35
- package/src/constants.ts +1 -6
- package/src/helpers/is.ts +1 -1
- package/src/helpers/proxy.ts +64 -17
- package/src/models.ts +3 -1
- package/src/value/array.ts +79 -23
- package/src/value/computed.ts +65 -30
- package/src/value/signal.ts +77 -9
- package/src/value/store.ts +101 -12
- package/dist/helpers/is.js +0 -23
- package/dist/helpers/proxy.js +0 -48
- package/dist/index.js +0 -8
- package/dist/models.js +0 -0
- package/dist/value/array.js +0 -100
- package/dist/value/computed.js +0 -36
- package/dist/value/signal.js +0 -24
- package/dist/value/store.js +0 -43
package/src/value/computed.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import {flushHandlers} from '../batch';
|
|
1
2
|
import {ACTIVE, BATCH, NAME_COMPUTED} from '../constants';
|
|
2
3
|
import {effect, runEffect} from '../effect';
|
|
3
|
-
import type {ComputedEffect, ReactiveOptions} from '../models';
|
|
4
|
+
import type {ComputedEffect, InternalComputed, ReactiveOptions, ReactiveState} from '../models';
|
|
4
5
|
import {Reactive} from './reactive';
|
|
5
6
|
|
|
6
7
|
export class Computed<Value> extends Reactive<Value> {
|
|
@@ -9,39 +10,15 @@ export class Computed<Value> extends Reactive<Value> {
|
|
|
9
10
|
instance: undefined as never,
|
|
10
11
|
};
|
|
11
12
|
|
|
12
|
-
constructor(callback: () => Value
|
|
13
|
+
constructor(callback: () => Value | Promise<Value>, options?: ReactiveOptions<Value>) {
|
|
13
14
|
super(NAME_COMPUTED, undefined as never, options);
|
|
14
15
|
|
|
15
16
|
this.effect.instance = effect(() => {
|
|
16
|
-
if (
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const previousComputed = ACTIVE.computed;
|
|
21
|
-
|
|
22
|
-
ACTIVE.computed = this as never;
|
|
23
|
-
|
|
24
|
-
const value = callback();
|
|
25
|
-
|
|
26
|
-
ACTIVE.computed = previousComputed;
|
|
27
|
-
|
|
28
|
-
if (!this.state.equal(this.state.value, value)) {
|
|
29
|
-
this.state.value = value;
|
|
17
|
+
if (this.effect.dirty) {
|
|
18
|
+
setValue(this, this.state, callback);
|
|
30
19
|
|
|
31
|
-
|
|
32
|
-
computed.effect.dirty = true;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
for (const effect of this.state.effects) {
|
|
36
|
-
BATCH.handlers.add(effect);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
for (const [, subscription] of this.state.subscriptions) {
|
|
40
|
-
subscription.callback(value);
|
|
41
|
-
}
|
|
20
|
+
this.effect.dirty = false;
|
|
42
21
|
}
|
|
43
|
-
|
|
44
|
-
this.effect.dirty = false;
|
|
45
22
|
});
|
|
46
23
|
}
|
|
47
24
|
|
|
@@ -72,8 +49,66 @@ export class Computed<Value> extends Reactive<Value> {
|
|
|
72
49
|
* @returns Computed value
|
|
73
50
|
*/
|
|
74
51
|
export function computed<Value>(
|
|
75
|
-
callback: () => Value
|
|
52
|
+
callback: () => Value | Promise<Value>,
|
|
76
53
|
options?: ReactiveOptions<Value>,
|
|
77
54
|
): Computed<Value> {
|
|
78
55
|
return new Computed(callback, options);
|
|
79
56
|
}
|
|
57
|
+
|
|
58
|
+
function setAndEmit<Value>(state: ReactiveState<Value, Value>, value: Value): void {
|
|
59
|
+
if (state.equal(state.value, value)) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
state.value = value;
|
|
64
|
+
|
|
65
|
+
for (const computed of state.computeds) {
|
|
66
|
+
(computed as unknown as InternalComputed).effect.dirty = true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for (const effect of state.effects) {
|
|
70
|
+
BATCH.handlers.add(effect);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
for (const [, subscription] of state.subscriptions) {
|
|
74
|
+
subscription.callback(value);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
flushHandlers();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function setValue<Value>(
|
|
81
|
+
instance: Computed<Value>,
|
|
82
|
+
state: ReactiveState<Value, Value>,
|
|
83
|
+
callback: () => Value | Promise<Value>,
|
|
84
|
+
): void {
|
|
85
|
+
const previousComputed = ACTIVE.computed;
|
|
86
|
+
|
|
87
|
+
ACTIVE.computed = instance as never;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const value = callback();
|
|
91
|
+
|
|
92
|
+
if (value instanceof Promise) {
|
|
93
|
+
state.promise = value;
|
|
94
|
+
|
|
95
|
+
value
|
|
96
|
+
.then(resolvedValue => {
|
|
97
|
+
if (state.promise === value) {
|
|
98
|
+
state.promise = undefined;
|
|
99
|
+
|
|
100
|
+
setAndEmit(state, resolvedValue);
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
.catch(() => {
|
|
104
|
+
if (state.promise === value) {
|
|
105
|
+
state.promise = undefined;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
} else {
|
|
109
|
+
setAndEmit(state, value);
|
|
110
|
+
}
|
|
111
|
+
} finally {
|
|
112
|
+
ACTIVE.computed = previousComputed;
|
|
113
|
+
}
|
|
114
|
+
}
|
package/src/value/signal.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {NAME_SIGNAL} from '../constants';
|
|
2
2
|
import {emitValue, getValue} from '../helpers/value';
|
|
3
|
-
import type {ReactiveOptions} from '../models';
|
|
3
|
+
import type {ReactiveOptions, ReactiveState} from '../models';
|
|
4
4
|
import {Reactive} from './reactive';
|
|
5
5
|
|
|
6
6
|
export class Signal<Value> extends Reactive<Value> {
|
|
@@ -19,12 +19,8 @@ export class Signal<Value> extends Reactive<Value> {
|
|
|
19
19
|
* Set the value
|
|
20
20
|
* @param value New value
|
|
21
21
|
*/
|
|
22
|
-
set(value: Value): void {
|
|
23
|
-
|
|
24
|
-
this.state.value = value;
|
|
25
|
-
|
|
26
|
-
emitValue(this.state);
|
|
27
|
-
}
|
|
22
|
+
set(value: Value | (() => Value | Promise<Value>) | Promise<Value>): void {
|
|
23
|
+
setValue<Value>(this.state, value);
|
|
28
24
|
}
|
|
29
25
|
|
|
30
26
|
/**
|
|
@@ -36,12 +32,84 @@ export class Signal<Value> extends Reactive<Value> {
|
|
|
36
32
|
}
|
|
37
33
|
}
|
|
38
34
|
|
|
35
|
+
function setAndEmit<Value>(state: ReactiveState<Value, Value>, value: Value): void {
|
|
36
|
+
if (!state.equal(state.value, value)) {
|
|
37
|
+
state.value = value;
|
|
38
|
+
|
|
39
|
+
emitValue(state);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
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
|
+
/**
|
|
77
|
+
* Create a reactive value from a function result
|
|
78
|
+
* @param value Initial value
|
|
79
|
+
* @param options Reactivity options
|
|
80
|
+
* @returns Reactive value
|
|
81
|
+
*/
|
|
82
|
+
export function signal<Value>(
|
|
83
|
+
value: () => Value | Promise<Value>,
|
|
84
|
+
options?: ReactiveOptions<Value>,
|
|
85
|
+
): Signal<Value>;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Create a reactive value from a promise
|
|
89
|
+
* @param value Initial value
|
|
90
|
+
* @param options Reactivity options
|
|
91
|
+
* @returns Reactive value
|
|
92
|
+
*/
|
|
93
|
+
export function signal<Value>(
|
|
94
|
+
value: Promise<Value>,
|
|
95
|
+
options?: ReactiveOptions<Value>,
|
|
96
|
+
): Signal<Value>;
|
|
97
|
+
|
|
39
98
|
/**
|
|
40
99
|
* Create a reactive value
|
|
41
100
|
* @param value Initial value
|
|
42
101
|
* @param options Reactivity options
|
|
43
102
|
* @returns Reactive value
|
|
44
103
|
*/
|
|
45
|
-
export function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value
|
|
46
|
-
|
|
104
|
+
export function signal<Value>(value: Value, options?: ReactiveOptions<Value>): Signal<Value>;
|
|
105
|
+
|
|
106
|
+
export function signal<Value>(
|
|
107
|
+
value: Value | (() => Value | Promise<Value>) | Promise<Value>,
|
|
108
|
+
options?: ReactiveOptions<Value>,
|
|
109
|
+
): Signal<Value> {
|
|
110
|
+
const instance = new Signal<Value>(undefined as unknown as Value, options);
|
|
111
|
+
|
|
112
|
+
instance.set(value);
|
|
113
|
+
|
|
114
|
+
return instance;
|
|
47
115
|
}
|
package/src/value/store.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import {isKey, isPlainObject} from '@oscarpalmer/atoms/is';
|
|
2
2
|
import type {GenericCallback, Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
3
|
+
import {startBatch, stopBatch} from '../batch';
|
|
3
4
|
import {NAME_STORE} from '../constants';
|
|
4
5
|
import {
|
|
5
|
-
getReactiveValueInProxy,
|
|
6
6
|
emityProxyValues,
|
|
7
|
+
getReactiveValueInProxy,
|
|
7
8
|
setProxyValue,
|
|
8
9
|
setValueInProxy,
|
|
9
10
|
} from '../helpers/proxy';
|
|
10
11
|
import {getValue} from '../helpers/value';
|
|
11
|
-
import type {ReactiveOptions, Unsubscribe} from '../models';
|
|
12
|
+
import type {ReactiveOptions, ReactiveState, Unsubscribe} from '../models';
|
|
12
13
|
import {noop, subscribe} from '../subscription';
|
|
13
14
|
import type {Computed} from './computed';
|
|
14
15
|
import {Reactive} from './reactive';
|
|
@@ -96,14 +97,22 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
|
|
|
96
97
|
* Set the value
|
|
97
98
|
* @param value New value _(defaults to an empty object)_
|
|
98
99
|
*/
|
|
99
|
-
set(
|
|
100
|
+
set(
|
|
101
|
+
value?:
|
|
102
|
+
| Value
|
|
103
|
+
| (() => null | undefined | Value | Promise<null | undefined | Value>)
|
|
104
|
+
| Promise<null | undefined | Value>,
|
|
105
|
+
): void;
|
|
100
106
|
|
|
101
107
|
/**
|
|
102
108
|
* Set a value by key
|
|
103
109
|
* @param key Key of the value to set
|
|
104
110
|
* @param value New value
|
|
105
111
|
*/
|
|
106
|
-
set<Key extends keyof Value>(
|
|
112
|
+
set<Key extends keyof Value>(
|
|
113
|
+
key: Key,
|
|
114
|
+
value: Value[Key] | (() => Value[Key] | Promise<Value[Key]>) | Promise<Value[Key]>,
|
|
115
|
+
): void;
|
|
107
116
|
|
|
108
117
|
/**
|
|
109
118
|
* Set a value by key
|
|
@@ -113,11 +122,16 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
|
|
|
113
122
|
set(key: Key, value: unknown): void;
|
|
114
123
|
|
|
115
124
|
set(first?: unknown, second?: unknown): void {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
125
|
+
setProxyValue<Value>(
|
|
126
|
+
false,
|
|
127
|
+
this.state,
|
|
128
|
+
isStoreObject,
|
|
129
|
+
isKey,
|
|
130
|
+
setObject,
|
|
131
|
+
setProperty,
|
|
132
|
+
first,
|
|
133
|
+
second,
|
|
134
|
+
);
|
|
121
135
|
}
|
|
122
136
|
|
|
123
137
|
/**
|
|
@@ -157,14 +171,80 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
|
|
|
157
171
|
* @param callback Callback to update the value
|
|
158
172
|
*/
|
|
159
173
|
update(callback: (value: Value) => Value): void {
|
|
160
|
-
const updated = callback(
|
|
174
|
+
const updated = callback(this.state.value);
|
|
161
175
|
|
|
162
176
|
if (updated == null || isPlainObject(updated)) {
|
|
163
|
-
|
|
177
|
+
setObject(this.state, updated);
|
|
164
178
|
}
|
|
165
179
|
}
|
|
166
180
|
}
|
|
167
181
|
|
|
182
|
+
function isStoreObject<Value extends PlainObject>(value: unknown): value is Value | undefined {
|
|
183
|
+
return value == null || isPlainObject(value);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function setObject(state: ReactiveState<PlainObject, never>, value: PlainObject | undefined): void {
|
|
187
|
+
startBatch();
|
|
188
|
+
|
|
189
|
+
const actual = value ?? {};
|
|
190
|
+
const proxy = state.value as PlainObject;
|
|
191
|
+
|
|
192
|
+
const proxyKeys = Object.keys(proxy);
|
|
193
|
+
const actualKeys = Object.keys(actual);
|
|
194
|
+
|
|
195
|
+
let {length} = proxyKeys;
|
|
196
|
+
|
|
197
|
+
for (let index = 0; index < length; index += 1) {
|
|
198
|
+
const key = proxyKeys[index];
|
|
199
|
+
|
|
200
|
+
proxy[key] = actualKeys.includes(key) ? actual[key] : undefined;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
length = actualKeys.length;
|
|
204
|
+
|
|
205
|
+
for (let index = 0; index < length; index += 1) {
|
|
206
|
+
const key = actualKeys[index];
|
|
207
|
+
|
|
208
|
+
if (!proxyKeys.includes(key)) {
|
|
209
|
+
const keyedValue = actual[key];
|
|
210
|
+
|
|
211
|
+
proxy[key] = keyedValue;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
stopBatch();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function setProperty<Value extends PlainObject>(
|
|
219
|
+
state: ReactiveState<Value, Value>,
|
|
220
|
+
key: unknown,
|
|
221
|
+
value: unknown,
|
|
222
|
+
): void {
|
|
223
|
+
(state.value as PlainObject)[key as Key] = value;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Create a reactive store from a function result
|
|
228
|
+
* @param value Initial object value
|
|
229
|
+
* @param options Reactivity options
|
|
230
|
+
* @returns Reactive store
|
|
231
|
+
*/
|
|
232
|
+
export function store<Value extends PlainObject>(
|
|
233
|
+
value: () => Value | Promise<Value>,
|
|
234
|
+
options?: ReactiveOptions<Value>,
|
|
235
|
+
): Store<Value>;
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Create a reactive store from a promise
|
|
239
|
+
* @param value Initial object value
|
|
240
|
+
* @param options Reactivity options
|
|
241
|
+
* @returns Reactive store
|
|
242
|
+
*/
|
|
243
|
+
export function store<Value extends PlainObject>(
|
|
244
|
+
value: Promise<Value>,
|
|
245
|
+
options?: ReactiveOptions<Value>,
|
|
246
|
+
): Store<Value>;
|
|
247
|
+
|
|
168
248
|
/**
|
|
169
249
|
* Create a reactive store
|
|
170
250
|
* @param value Initial object value
|
|
@@ -174,6 +254,15 @@ export class Store<Value extends PlainObject> extends Reactive<Value, Value> {
|
|
|
174
254
|
export function store<Value extends PlainObject>(
|
|
175
255
|
value: Value,
|
|
176
256
|
options?: ReactiveOptions<Value>,
|
|
257
|
+
): Store<Value>;
|
|
258
|
+
|
|
259
|
+
export function store<Value extends PlainObject>(
|
|
260
|
+
value: Value | (() => Value | Promise<Value>) | Promise<Value>,
|
|
261
|
+
options?: ReactiveOptions<Value>,
|
|
177
262
|
): Store<Value> {
|
|
178
|
-
|
|
263
|
+
const instance = new Store({} as unknown as Value, options);
|
|
264
|
+
|
|
265
|
+
instance.set(value);
|
|
266
|
+
|
|
267
|
+
return instance;
|
|
179
268
|
}
|
package/dist/helpers/is.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { NAME_ALL, NAME_ARRAY, NAME_COMPUTED, NAME_EFFECT, NAME_MORA, NAME_SIGNAL, NAME_STORE } from "../constants.js";
|
|
2
|
-
function isArray(value) {
|
|
3
|
-
return isMora(value, NAME_ARRAY);
|
|
4
|
-
}
|
|
5
|
-
function isComputed(value) {
|
|
6
|
-
return isMora(value, NAME_COMPUTED);
|
|
7
|
-
}
|
|
8
|
-
function isEffect(value) {
|
|
9
|
-
return isMora(value, NAME_EFFECT);
|
|
10
|
-
}
|
|
11
|
-
function isMora(value, name) {
|
|
12
|
-
return typeof value === "object" && value != null && "$mora" in value && (typeof name === "string" ? value["$mora"] === name : name.has(value["$mora"]));
|
|
13
|
-
}
|
|
14
|
-
function isReactive(value) {
|
|
15
|
-
return isMora(value, NAME_ALL);
|
|
16
|
-
}
|
|
17
|
-
function isSignal(value) {
|
|
18
|
-
return isMora(value, NAME_SIGNAL);
|
|
19
|
-
}
|
|
20
|
-
function isStore(value) {
|
|
21
|
-
return isMora(value, NAME_STORE);
|
|
22
|
-
}
|
|
23
|
-
export { isArray, isComputed, isEffect, isReactive, isSignal, isStore };
|
package/dist/helpers/proxy.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { PROPERTY_LENGTH } from "../constants.js";
|
|
2
|
-
import { startBatch, stopBatch } from "../batch.js";
|
|
3
|
-
import { computed } from "../value/computed.js";
|
|
4
|
-
import { emitValue } from "./value.js";
|
|
5
|
-
function emityProxyValues(state, mapped) {
|
|
6
|
-
const values = [...mapped.values()];
|
|
7
|
-
const { length } = values;
|
|
8
|
-
for (let index = 0; index < length; index += 1) values[index].effect.dirty = true;
|
|
9
|
-
emitValue(state);
|
|
10
|
-
}
|
|
11
|
-
function getReactiveValueInProxy(reactive, mapped, key, isArray) {
|
|
12
|
-
let item = mapped.get(key);
|
|
13
|
-
if (item == null) {
|
|
14
|
-
item = computed(() => isArray ? reactive.get().at(key) : reactive.get()[key]);
|
|
15
|
-
mapped.set(key, item);
|
|
16
|
-
}
|
|
17
|
-
return item;
|
|
18
|
-
}
|
|
19
|
-
function setProxyValue(proxy, value) {
|
|
20
|
-
startBatch();
|
|
21
|
-
const proxyKeys = Object.keys(proxy);
|
|
22
|
-
const valueKeys = Object.keys(value);
|
|
23
|
-
let { length } = proxyKeys;
|
|
24
|
-
for (let index = 0; index < length; index += 1) {
|
|
25
|
-
const key = proxyKeys[index];
|
|
26
|
-
proxy[key] = valueKeys.includes(key) ? value[key] : void 0;
|
|
27
|
-
}
|
|
28
|
-
length = valueKeys.length;
|
|
29
|
-
for (let index = 0; index < length; index += 1) {
|
|
30
|
-
const key = valueKeys[index];
|
|
31
|
-
if (!proxyKeys.includes(key)) proxy[key] = value[key];
|
|
32
|
-
}
|
|
33
|
-
stopBatch();
|
|
34
|
-
}
|
|
35
|
-
function setValueInProxy(parameters) {
|
|
36
|
-
const { isArray, length, property, state, target, value } = parameters;
|
|
37
|
-
if (isArray) {
|
|
38
|
-
if (!(!Number.isNaN(Number(property)) || property === "length")) return Reflect.set(target, property, value);
|
|
39
|
-
}
|
|
40
|
-
const previous = Reflect.get(target, property);
|
|
41
|
-
if (!state.equal(previous, value)) {
|
|
42
|
-
Reflect.set(target, property, value);
|
|
43
|
-
emitValue(state);
|
|
44
|
-
if (isArray) length?.set(target.length);
|
|
45
|
-
}
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
export { emityProxyValues, getReactiveValueInProxy, setProxyValue, setValueInProxy };
|
package/dist/index.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { effect } from "./effect.js";
|
|
2
|
-
import { isArray, isComputed, isEffect, isReactive, isSignal } from "./helpers/is.js";
|
|
3
|
-
import { startBatch, stopBatch } from "./batch.js";
|
|
4
|
-
import { computed } from "./value/computed.js";
|
|
5
|
-
import { signal } from "./value/signal.js";
|
|
6
|
-
import { array } from "./value/array.js";
|
|
7
|
-
import { store } from "./value/store.js";
|
|
8
|
-
export { array, computed, effect, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };
|
package/dist/models.js
DELETED
|
File without changes
|
package/dist/value/array.js
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { METHODS_AFFECTING_LENGTH, METHODS_UPDATE, NAME_ARRAY, PROPERTY_LENGTH } from "../constants.js";
|
|
2
|
-
import { noop, subscribe } from "../subscription.js";
|
|
3
|
-
import { Reactive } from "./reactive.js";
|
|
4
|
-
import { computed } from "./computed.js";
|
|
5
|
-
import { emitValue, equalArrays, getValue } from "../helpers/value.js";
|
|
6
|
-
import { emityProxyValues, getReactiveValueInProxy, setValueInProxy } from "../helpers/proxy.js";
|
|
7
|
-
import { signal } from "./signal.js";
|
|
8
|
-
var ReactiveArray = class extends Reactive {
|
|
9
|
-
#indiced = /* @__PURE__ */ new Map();
|
|
10
|
-
#size = signal(0);
|
|
11
|
-
get length() {
|
|
12
|
-
return this.#size.get();
|
|
13
|
-
}
|
|
14
|
-
set length(value) {
|
|
15
|
-
if (typeof value === "number" && value >= 0 && value !== this.state.value.length) this.get().length = value;
|
|
16
|
-
}
|
|
17
|
-
constructor(value, options) {
|
|
18
|
-
super(NAME_ARRAY, new Proxy(value, {
|
|
19
|
-
get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(property, target, this.state, this.#size) : Reflect.get(target, property),
|
|
20
|
-
set: (target, property, value$1) => setValueInProxy({
|
|
21
|
-
property,
|
|
22
|
-
target,
|
|
23
|
-
value: value$1,
|
|
24
|
-
isArray: true,
|
|
25
|
-
state: this.state,
|
|
26
|
-
length: this.#size
|
|
27
|
-
})
|
|
28
|
-
}), options);
|
|
29
|
-
this.#size.set(value.length);
|
|
30
|
-
}
|
|
31
|
-
clear() {
|
|
32
|
-
this.length = 0;
|
|
33
|
-
}
|
|
34
|
-
filter(callback) {
|
|
35
|
-
return computed(() => this.get().filter(callback));
|
|
36
|
-
}
|
|
37
|
-
get(first) {
|
|
38
|
-
if (typeof first === "number") return getReactiveValueInProxy(this, this.#indiced, first, true).get();
|
|
39
|
-
return first === "length" ? this.length : getValue(this.state);
|
|
40
|
-
}
|
|
41
|
-
map(callback) {
|
|
42
|
-
return computed(() => this.get().map(callback));
|
|
43
|
-
}
|
|
44
|
-
notify() {
|
|
45
|
-
emityProxyValues(this.state, this.#indiced);
|
|
46
|
-
}
|
|
47
|
-
peek(value) {
|
|
48
|
-
if (value === "length") return this.#size.peek();
|
|
49
|
-
return typeof value === "number" ? this.state.value.at(value) : [...this.state.value];
|
|
50
|
-
}
|
|
51
|
-
pop() {
|
|
52
|
-
return this.state.value.pop();
|
|
53
|
-
}
|
|
54
|
-
push(...items) {
|
|
55
|
-
return this.state.value.push(...items);
|
|
56
|
-
}
|
|
57
|
-
set(first, second) {
|
|
58
|
-
if (first == null || Array.isArray(first)) this.state.value.splice(0, this.state.value.length, ...first ?? []);
|
|
59
|
-
else if (first === "length") this.length = second;
|
|
60
|
-
else if (typeof first === "number" && !Number.isNaN(first)) setAtIndex(this.state.value, first, second);
|
|
61
|
-
}
|
|
62
|
-
shift() {
|
|
63
|
-
return this.state.value.shift();
|
|
64
|
-
}
|
|
65
|
-
splice(from, to, ...items) {
|
|
66
|
-
return this.state.value.splice(from, to ?? this.state.value.length, ...items);
|
|
67
|
-
}
|
|
68
|
-
subscribe(first, second) {
|
|
69
|
-
if (typeof first === "number" && typeof second === "function") return getReactiveValueInProxy(this, this.#indiced, first, true).subscribe(second);
|
|
70
|
-
return typeof first === "function" ? subscribe(this.state, first) : noop;
|
|
71
|
-
}
|
|
72
|
-
unshift(...items) {
|
|
73
|
-
return this.state.value.unshift(...items);
|
|
74
|
-
}
|
|
75
|
-
update(callback) {
|
|
76
|
-
const updated = callback(this.state.value);
|
|
77
|
-
if (updated == null || Array.isArray(updated)) this.set(updated);
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
function array(value, options) {
|
|
81
|
-
return new ReactiveArray(Array.isArray(value) ? value : [], options);
|
|
82
|
-
}
|
|
83
|
-
function updateArray(type, array$1, state, length) {
|
|
84
|
-
const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
|
|
85
|
-
const previousArray = affectsLength ? [] : [...array$1];
|
|
86
|
-
const previousLength = array$1.length;
|
|
87
|
-
return (...args) => {
|
|
88
|
-
const result = array$1[type](...args);
|
|
89
|
-
if (affectsLength ? array$1.length !== previousLength : !equalArrays(state, previousArray, array$1)) {
|
|
90
|
-
emitValue(state);
|
|
91
|
-
length.set(array$1.length);
|
|
92
|
-
}
|
|
93
|
-
return result;
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
function setAtIndex(array$1, index, value) {
|
|
97
|
-
const actual = index < 0 ? array$1.length + index : index;
|
|
98
|
-
if (actual > -1) array$1[actual] = value;
|
|
99
|
-
}
|
|
100
|
-
export { ReactiveArray, array };
|
package/dist/value/computed.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { ACTIVE, BATCH, NAME_COMPUTED } from "../constants.js";
|
|
2
|
-
import { effect, runEffect } from "../effect.js";
|
|
3
|
-
import { Reactive } from "./reactive.js";
|
|
4
|
-
var Computed = class extends Reactive {
|
|
5
|
-
effect = {
|
|
6
|
-
dirty: true,
|
|
7
|
-
instance: void 0
|
|
8
|
-
};
|
|
9
|
-
constructor(callback, options) {
|
|
10
|
-
super(NAME_COMPUTED, void 0, options);
|
|
11
|
-
this.effect.instance = effect(() => {
|
|
12
|
-
if (!this.effect.dirty) return;
|
|
13
|
-
const previousComputed = ACTIVE.computed;
|
|
14
|
-
ACTIVE.computed = this;
|
|
15
|
-
const value = callback();
|
|
16
|
-
ACTIVE.computed = previousComputed;
|
|
17
|
-
if (!this.state.equal(this.state.value, value)) {
|
|
18
|
-
this.state.value = value;
|
|
19
|
-
for (const computed$1 of this.state.computeds) computed$1.effect.dirty = true;
|
|
20
|
-
for (const effect$1 of this.state.effects) BATCH.handlers.add(effect$1);
|
|
21
|
-
for (const [, subscription] of this.state.subscriptions) subscription.callback(value);
|
|
22
|
-
}
|
|
23
|
-
this.effect.dirty = false;
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
get() {
|
|
27
|
-
if (ACTIVE.computed != null && this !== ACTIVE.computed) this.state.computeds.add(ACTIVE.computed);
|
|
28
|
-
if (ACTIVE.effect != null && ACTIVE.effect !== this.effect.instance) this.state.effects.add(ACTIVE.effect);
|
|
29
|
-
if (this.effect.dirty && BATCH.depth === 0) runEffect(this.effect.instance);
|
|
30
|
-
return this.state.value;
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
function computed(callback, options) {
|
|
34
|
-
return new Computed(callback, options);
|
|
35
|
-
}
|
|
36
|
-
export { Computed, computed };
|
package/dist/value/signal.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { NAME_SIGNAL } from "../constants.js";
|
|
2
|
-
import { Reactive } from "./reactive.js";
|
|
3
|
-
import { emitValue, getValue } from "../helpers/value.js";
|
|
4
|
-
var Signal = class extends Reactive {
|
|
5
|
-
constructor(value, options) {
|
|
6
|
-
super(NAME_SIGNAL, value, options);
|
|
7
|
-
}
|
|
8
|
-
get() {
|
|
9
|
-
return getValue(this.state);
|
|
10
|
-
}
|
|
11
|
-
set(value) {
|
|
12
|
-
if (!this.state.equal(this.state.value, value)) {
|
|
13
|
-
this.state.value = value;
|
|
14
|
-
emitValue(this.state);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
update(callback) {
|
|
18
|
-
this.set(callback(this.state.value));
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
function signal(value, options) {
|
|
22
|
-
return new Signal(value, options);
|
|
23
|
-
}
|
|
24
|
-
export { Signal, signal };
|
package/dist/value/store.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { NAME_STORE } from "../constants.js";
|
|
2
|
-
import { noop, subscribe } from "../subscription.js";
|
|
3
|
-
import { Reactive } from "./reactive.js";
|
|
4
|
-
import { getValue } from "../helpers/value.js";
|
|
5
|
-
import { emityProxyValues, getReactiveValueInProxy, setProxyValue, setValueInProxy } from "../helpers/proxy.js";
|
|
6
|
-
import { isKey, isPlainObject } from "@oscarpalmer/atoms/is";
|
|
7
|
-
var Store = class extends Reactive {
|
|
8
|
-
#keyed = /* @__PURE__ */ new Map();
|
|
9
|
-
constructor(value, options) {
|
|
10
|
-
super(NAME_STORE, new Proxy(value, { set: (target, property, value$1) => setValueInProxy({
|
|
11
|
-
target,
|
|
12
|
-
property,
|
|
13
|
-
value: value$1,
|
|
14
|
-
isArray: false,
|
|
15
|
-
state: this.state
|
|
16
|
-
}) }), options);
|
|
17
|
-
}
|
|
18
|
-
get(key) {
|
|
19
|
-
return isKey(key) ? getReactiveValueInProxy(this, this.#keyed, key, false).get() : getValue(this.state);
|
|
20
|
-
}
|
|
21
|
-
notify() {
|
|
22
|
-
emityProxyValues(this.state, this.#keyed);
|
|
23
|
-
}
|
|
24
|
-
peek(key) {
|
|
25
|
-
return isKey(key) ? this.state.value[key] : { ...this.state.value };
|
|
26
|
-
}
|
|
27
|
-
set(first, second) {
|
|
28
|
-
if (isKey(first)) this.state.value[first] = second;
|
|
29
|
-
else if (first == null || isPlainObject(first)) setProxyValue(this.state.value, first ?? {});
|
|
30
|
-
}
|
|
31
|
-
subscribe(first, second) {
|
|
32
|
-
if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
|
|
33
|
-
return typeof first === "function" ? subscribe(this.state, first) : noop;
|
|
34
|
-
}
|
|
35
|
-
update(callback) {
|
|
36
|
-
const updated = callback({ ...this.state.value });
|
|
37
|
-
if (updated == null || isPlainObject(updated)) setProxyValue(this.state.value, updated ?? {});
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
function store(value, options) {
|
|
41
|
-
return new Store(isPlainObject(value) ? value : {}, options);
|
|
42
|
-
}
|
|
43
|
-
export { Store, store };
|