@oscarpalmer/mora 0.27.0 → 0.29.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/constants.d.mts +19 -1
- package/dist/effect.d.mts +26 -1
- package/dist/helpers/is.d.mts +4 -2
- package/dist/helpers/proxy.d.mts +3 -2
- package/dist/helpers/proxy.mjs +36 -14
- package/dist/helpers/value.d.mts +1 -1
- package/dist/helpers/value.mjs +2 -1
- package/dist/index.d.mts +5 -2
- package/dist/models.d.mts +61 -1
- package/dist/mora.full.mjs +187 -84
- package/dist/subscription.d.mts +14 -1
- package/dist/value/array.d.mts +20 -4
- package/dist/value/array.mjs +19 -16
- package/dist/value/computed.d.mts +20 -1
- package/dist/value/computed.mjs +32 -11
- package/dist/value/reactive.d.mts +50 -1
- package/dist/value/reactive.mjs +5 -0
- package/dist/value/signal.d.mts +43 -1
- package/dist/value/signal.mjs +27 -11
- package/dist/value/store.d.mts +18 -3
- package/dist/value/store.mjs +31 -11
- package/package.json +6 -5
- package/src/effect.ts +10 -0
- package/src/helpers/proxy.ts +64 -17
- package/src/helpers/value.ts +2 -1
- package/src/models.ts +3 -1
- package/src/value/array.ts +74 -18
- package/src/value/computed.ts +65 -30
- package/src/value/reactive.ts +13 -0
- package/src/value/signal.ts +77 -9
- package/src/value/store.ts +100 -11
- 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/constants-Cy6_M9Vk.d.mts +0 -20
- package/dist/effect-BkupB1p9.d.mts +0 -17
- package/dist/models-QwNga87R.d.mts +0 -148
package/dist/constants.d.mts
CHANGED
|
@@ -1,2 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Active, Batch } from "./models.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/constants.d.ts
|
|
4
|
+
declare const ACTIVE: Active;
|
|
5
|
+
declare const ARRAY_THRESHOLD = 100;
|
|
6
|
+
declare const ARRAY_OFFSET = 25;
|
|
7
|
+
declare const ARRAY_PEEK = 10;
|
|
8
|
+
declare const BATCH: Batch;
|
|
9
|
+
declare const METHODS_AFFECTING_LENGTH: Set<string>;
|
|
10
|
+
declare const METHODS_UPDATE: Set<string>;
|
|
11
|
+
declare const NAME_ARRAY = "array";
|
|
12
|
+
declare const NAME_COMPUTED = "computed";
|
|
13
|
+
declare const NAME_EFFECT = "effect";
|
|
14
|
+
declare const NAME_MORA = "$mora";
|
|
15
|
+
declare const NAME_SIGNAL = "signal";
|
|
16
|
+
declare const NAME_STORE = "store";
|
|
17
|
+
declare const NAME_ALL: Set<string>;
|
|
18
|
+
declare const PROPERTY_LENGTH = "length";
|
|
19
|
+
//#endregion
|
|
2
20
|
export { ACTIVE, ARRAY_OFFSET, ARRAY_PEEK, ARRAY_THRESHOLD, BATCH, METHODS_AFFECTING_LENGTH, METHODS_UPDATE, NAME_ALL, NAME_ARRAY, NAME_COMPUTED, NAME_EFFECT, NAME_MORA, NAME_SIGNAL, NAME_STORE, PROPERTY_LENGTH };
|
package/dist/effect.d.mts
CHANGED
|
@@ -1,2 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GenericCallback } from "@oscarpalmer/atoms/models";
|
|
2
|
+
|
|
3
|
+
//#region src/effect.d.ts
|
|
4
|
+
declare class Effect {
|
|
5
|
+
/**
|
|
6
|
+
* Internal name of the effect
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
private readonly $mora;
|
|
11
|
+
/**
|
|
12
|
+
* Internal state of the effect
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
private readonly state;
|
|
17
|
+
constructor(callback: GenericCallback);
|
|
18
|
+
}
|
|
19
|
+
declare function runEffect(effect: Effect): void;
|
|
20
|
+
/**
|
|
21
|
+
* Create an effect
|
|
22
|
+
* @param callback Callback for handling signal effects
|
|
23
|
+
* @returns Effect
|
|
24
|
+
*/
|
|
25
|
+
declare function effect(callback: GenericCallback): Effect;
|
|
26
|
+
//#endregion
|
|
2
27
|
export { Effect, effect, runEffect };
|
package/dist/helpers/is.d.mts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Effect } from "../effect.mjs";
|
|
2
|
+
import { Reactive } from "../value/reactive.mjs";
|
|
3
|
+
import { Computed } from "../value/computed.mjs";
|
|
4
|
+
import { Signal } from "../value/signal.mjs";
|
|
3
5
|
import { ReactiveArray } from "../value/array.mjs";
|
|
4
6
|
import { Store } from "../value/store.mjs";
|
|
5
7
|
import { PlainObject } from "@oscarpalmer/atoms/models";
|
package/dist/helpers/proxy.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Computed } from "../value/computed.mjs";
|
|
2
|
+
import { ReactiveState, SetValueInProxyParameters } from "../models.mjs";
|
|
2
3
|
import { ReactiveArray } from "../value/array.mjs";
|
|
3
4
|
import { Store } from "../value/store.mjs";
|
|
4
5
|
import { ArrayOrPlainObject, Key, PlainObject } from "@oscarpalmer/atoms/models";
|
|
@@ -8,7 +9,7 @@ declare function emityProxyValues<Value>(state: ReactiveState<Value, Value>, map
|
|
|
8
9
|
declare function emityProxyValues<Value>(state: ReactiveState<Value[], Value>, mapped: Map<Key, Computed<unknown>>): void;
|
|
9
10
|
declare function getReactiveValueInProxy<Value>(array: ReactiveArray<Value>, mapped: Map<Key, Computed<unknown>>, index: number, isArray: true): Computed<unknown>;
|
|
10
11
|
declare function getReactiveValueInProxy<Value extends PlainObject>(store: Store<Value>, mapped: Map<Key, Computed<unknown>>, key: Key, isArray: false): Computed<unknown>;
|
|
11
|
-
declare function setProxyValue(
|
|
12
|
+
declare function setProxyValue<Value, Item = Value>(array: boolean, state: ReactiveState<Value, Item>, isObject: (value: unknown) => value is Value | undefined, isProperty: (value: unknown) => boolean, setObject: (state: ReactiveState<Value, Item>, value: Value | undefined) => void, setProperty: (state: ReactiveState<Value, Item>, property: unknown, value: Item) => void, first?: unknown, second?: unknown): void;
|
|
12
13
|
declare function setValueInProxy<Value extends ArrayOrPlainObject, Equal>(parameters: SetValueInProxyParameters<Value, Equal>): boolean;
|
|
13
14
|
//#endregion
|
|
14
15
|
export { emityProxyValues, getReactiveValueInProxy, setProxyValue, setValueInProxy };
|
package/dist/helpers/proxy.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import "../constants.mjs";
|
|
2
|
-
import { startBatch, stopBatch } from "../batch.mjs";
|
|
3
2
|
import { computed } from "../value/computed.mjs";
|
|
4
3
|
import { emitValue } from "./value.mjs";
|
|
5
4
|
//#region src/helpers/proxy.ts
|
|
@@ -17,21 +16,44 @@ function getReactiveValueInProxy(reactive, mapped, key, isArray) {
|
|
|
17
16
|
}
|
|
18
17
|
return item;
|
|
19
18
|
}
|
|
20
|
-
function setProxyValue(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
let { length } = proxyKeys;
|
|
25
|
-
for (let index = 0; index < length; index += 1) {
|
|
26
|
-
const key = proxyKeys[index];
|
|
27
|
-
proxy[key] = valueKeys.includes(key) ? value[key] : void 0;
|
|
19
|
+
function setProxyValue(array, state, isObject, isProperty, setObject, setProperty, first, second) {
|
|
20
|
+
if (array && first === "length") {
|
|
21
|
+
state.value.length = second;
|
|
22
|
+
return;
|
|
28
23
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (!proxyKeys.includes(key)) proxy[key] = value[key];
|
|
24
|
+
if (isObject(first)) {
|
|
25
|
+
setObject(state, first);
|
|
26
|
+
return;
|
|
33
27
|
}
|
|
34
|
-
|
|
28
|
+
const property = isProperty(first);
|
|
29
|
+
if (array && property && Number.isNaN(first)) return;
|
|
30
|
+
let actual = property ? second : first;
|
|
31
|
+
if (typeof actual === "function") try {
|
|
32
|
+
actual = actual();
|
|
33
|
+
} catch {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (actual instanceof Promise) {
|
|
37
|
+
if (property) {
|
|
38
|
+
state.promises ??= /* @__PURE__ */ new Map();
|
|
39
|
+
state.promises.set(first, actual);
|
|
40
|
+
} else state.promise = actual;
|
|
41
|
+
actual.then((value) => {
|
|
42
|
+
if (property && state.promises.get(first) === actual) {
|
|
43
|
+
state.promises.delete(first);
|
|
44
|
+
setProperty(state, first, value);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (!property && isObject(value) && state.promise === actual) {
|
|
48
|
+
state.promise = void 0;
|
|
49
|
+
setObject(state, value);
|
|
50
|
+
}
|
|
51
|
+
}).catch(() => {
|
|
52
|
+
if (property && state.promises.get(first) === actual) state.promises.delete(first);
|
|
53
|
+
else if (!property && state.promise === actual) state.promise = void 0;
|
|
54
|
+
});
|
|
55
|
+
} else if (property) setProperty(state, first, actual);
|
|
56
|
+
else if (isObject(actual)) setObject(state, actual);
|
|
35
57
|
}
|
|
36
58
|
function setValueInProxy(parameters) {
|
|
37
59
|
const { isArray, length, property, state, target, value } = parameters;
|
package/dist/helpers/value.d.mts
CHANGED
package/dist/helpers/value.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ACTIVE, BATCH } from "../constants.mjs";
|
|
2
2
|
import { flushHandlers } from "../batch.mjs";
|
|
3
|
+
import { round } from "@oscarpalmer/atoms/math";
|
|
3
4
|
//#region src/helpers/value.ts
|
|
4
5
|
function emitValue(state) {
|
|
5
6
|
for (const computed of state.computeds) computed.effect.dirty = true;
|
|
@@ -12,7 +13,7 @@ function equalArrays(state, first, second) {
|
|
|
12
13
|
if (length !== second.length) return false;
|
|
13
14
|
let offset = 0;
|
|
14
15
|
if (length >= 100) {
|
|
15
|
-
offset =
|
|
16
|
+
offset = round(length / 10);
|
|
16
17
|
offset = offset > 25 ? 25 : offset;
|
|
17
18
|
for (let index = 0; index < offset; index += 1) if (!state.equal(first[index], second[index])) return false;
|
|
18
19
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { startBatch, stopBatch } from "./batch.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { Effect, effect } from "./effect.mjs";
|
|
3
|
+
import { Reactive } from "./value/reactive.mjs";
|
|
4
|
+
import { Computed, computed } from "./value/computed.mjs";
|
|
5
|
+
import { Signal, signal } from "./value/signal.mjs";
|
|
6
|
+
import { Unsubscribe } from "./models.mjs";
|
|
4
7
|
import { ReactiveArray, array } from "./value/array.mjs";
|
|
5
8
|
import { Store, store } from "./value/store.mjs";
|
|
6
9
|
import { isArray, isComputed, isEffect, isReactive, isSignal } from "./helpers/is.mjs";
|
package/dist/models.d.mts
CHANGED
|
@@ -1,2 +1,62 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Effect } from "./effect.mjs";
|
|
2
|
+
import { Subscription } from "./subscription.mjs";
|
|
3
|
+
import { Computed } from "./value/computed.mjs";
|
|
4
|
+
import { Signal } from "./value/signal.mjs";
|
|
5
|
+
import { GenericCallback, Key } from "@oscarpalmer/atoms/models";
|
|
6
|
+
|
|
7
|
+
//#region src/models.d.ts
|
|
8
|
+
type Active = {
|
|
9
|
+
computed?: Computed<unknown>;
|
|
10
|
+
effect?: Effect;
|
|
11
|
+
};
|
|
12
|
+
type Batch = {
|
|
13
|
+
depth: number;
|
|
14
|
+
handlers: Set<Effect | Subscription>;
|
|
15
|
+
};
|
|
16
|
+
type ComputedEffect = {
|
|
17
|
+
dirty: boolean;
|
|
18
|
+
instance: Effect;
|
|
19
|
+
};
|
|
20
|
+
type EffectState = {
|
|
21
|
+
callback: GenericCallback;
|
|
22
|
+
};
|
|
23
|
+
type InternalComputed = {
|
|
24
|
+
readonly effect: ComputedEffect;
|
|
25
|
+
readonly state: ReactiveState<unknown, unknown>;
|
|
26
|
+
};
|
|
27
|
+
type InternalEffect = {
|
|
28
|
+
state: EffectState;
|
|
29
|
+
};
|
|
30
|
+
type ReactiveOptions<Value> = {
|
|
31
|
+
/**
|
|
32
|
+
* Method for comparing values for equality
|
|
33
|
+
* @param first First value
|
|
34
|
+
* @param second Second value
|
|
35
|
+
* @returns Are the values equal?
|
|
36
|
+
* @default Object.is
|
|
37
|
+
*/
|
|
38
|
+
equal?: (first: Value, second: Value) => boolean;
|
|
39
|
+
};
|
|
40
|
+
type ReactiveState<Value, Equal> = {
|
|
41
|
+
computeds: Set<Computed<unknown>>;
|
|
42
|
+
effects: Set<Effect>;
|
|
43
|
+
equal: (first: Equal, second: Equal) => boolean;
|
|
44
|
+
promise?: Promise<Value>;
|
|
45
|
+
promises?: Map<Key, Promise<never>>;
|
|
46
|
+
subscriptions: Map<GenericCallback, Subscription>;
|
|
47
|
+
value: Value;
|
|
48
|
+
};
|
|
49
|
+
type SetValueInProxyParameters<Value, Equal> = {
|
|
50
|
+
target: Value;
|
|
51
|
+
property: PropertyKey;
|
|
52
|
+
value: unknown;
|
|
53
|
+
state: ReactiveState<Value, Equal>;
|
|
54
|
+
isArray: boolean;
|
|
55
|
+
length?: Signal<number>;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Unsubscribe from changes
|
|
59
|
+
*/
|
|
60
|
+
type Unsubscribe = () => void;
|
|
61
|
+
//#endregion
|
|
2
62
|
export { Active, Batch, ComputedEffect, EffectState, InternalComputed, InternalEffect, ReactiveOptions, ReactiveState, SetValueInProxyParameters, Unsubscribe };
|
package/dist/mora.full.mjs
CHANGED
|
@@ -156,6 +156,11 @@ function unsubscribe(state, callback) {
|
|
|
156
156
|
//#endregion
|
|
157
157
|
//#region src/value/reactive.ts
|
|
158
158
|
var Reactive = class {
|
|
159
|
+
/**
|
|
160
|
+
* Internal state of the reactive value
|
|
161
|
+
*
|
|
162
|
+
* @internal
|
|
163
|
+
*/
|
|
159
164
|
state = {
|
|
160
165
|
computeds: /* @__PURE__ */ new Set(),
|
|
161
166
|
effects: /* @__PURE__ */ new Set(),
|
|
@@ -215,18 +220,10 @@ var Computed = class extends Reactive {
|
|
|
215
220
|
constructor(callback, options) {
|
|
216
221
|
super(NAME_COMPUTED, void 0, options);
|
|
217
222
|
this.effect.instance = effect(() => {
|
|
218
|
-
if (
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const value = callback();
|
|
222
|
-
ACTIVE.computed = previousComputed;
|
|
223
|
-
if (!this.state.equal(this.state.value, value)) {
|
|
224
|
-
this.state.value = value;
|
|
225
|
-
for (const computed of this.state.computeds) computed.effect.dirty = true;
|
|
226
|
-
for (const effect of this.state.effects) BATCH.handlers.add(effect);
|
|
227
|
-
for (const [, subscription] of this.state.subscriptions) subscription.callback(value);
|
|
223
|
+
if (this.effect.dirty) {
|
|
224
|
+
setValue$1(this, this.state, callback);
|
|
225
|
+
this.effect.dirty = false;
|
|
228
226
|
}
|
|
229
|
-
this.effect.dirty = false;
|
|
230
227
|
});
|
|
231
228
|
}
|
|
232
229
|
/**
|
|
@@ -248,6 +245,72 @@ var Computed = class extends Reactive {
|
|
|
248
245
|
function computed(callback, options) {
|
|
249
246
|
return new Computed(callback, options);
|
|
250
247
|
}
|
|
248
|
+
function setAndEmit$1(state, value) {
|
|
249
|
+
if (state.equal(state.value, value)) return;
|
|
250
|
+
state.value = value;
|
|
251
|
+
for (const computed of state.computeds) computed.effect.dirty = true;
|
|
252
|
+
for (const effect of state.effects) BATCH.handlers.add(effect);
|
|
253
|
+
for (const [, subscription] of state.subscriptions) subscription.callback(value);
|
|
254
|
+
flushHandlers();
|
|
255
|
+
}
|
|
256
|
+
function setValue$1(instance, state, callback) {
|
|
257
|
+
const previousComputed = ACTIVE.computed;
|
|
258
|
+
ACTIVE.computed = instance;
|
|
259
|
+
try {
|
|
260
|
+
const value = callback();
|
|
261
|
+
if (value instanceof Promise) {
|
|
262
|
+
state.promise = value;
|
|
263
|
+
value.then((resolvedValue) => {
|
|
264
|
+
if (state.promise === value) {
|
|
265
|
+
state.promise = void 0;
|
|
266
|
+
setAndEmit$1(state, resolvedValue);
|
|
267
|
+
}
|
|
268
|
+
}).catch(() => {
|
|
269
|
+
if (state.promise === value) state.promise = void 0;
|
|
270
|
+
});
|
|
271
|
+
} else setAndEmit$1(state, value);
|
|
272
|
+
} finally {
|
|
273
|
+
ACTIVE.computed = previousComputed;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
//#endregion
|
|
277
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
|
|
278
|
+
/**
|
|
279
|
+
* Is the value a key?
|
|
280
|
+
* @param value Value to check
|
|
281
|
+
* @returns `true` if the value is a `Key` _(`number` or `string`)_, otherwise `false`
|
|
282
|
+
*/
|
|
283
|
+
function isKey(value) {
|
|
284
|
+
return typeof value === "number" || typeof value === "string";
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Is the value a plain object?
|
|
288
|
+
* @param value Value to check
|
|
289
|
+
* @returns `true` if the value is a plain object, otherwise `false`
|
|
290
|
+
*/
|
|
291
|
+
function isPlainObject(value) {
|
|
292
|
+
if (value === null || typeof value !== "object") return false;
|
|
293
|
+
if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
|
|
294
|
+
const prototype = Object.getPrototypeOf(value);
|
|
295
|
+
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
296
|
+
}
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region node_modules/@oscarpalmer/atoms/dist/math.mjs
|
|
299
|
+
/**
|
|
300
|
+
* Round a number
|
|
301
|
+
* @param value Number to round
|
|
302
|
+
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
303
|
+
* @returns Rounded number, or `NaN` if the value if unable to be rounded
|
|
304
|
+
*/
|
|
305
|
+
function round(value, decimals) {
|
|
306
|
+
return roundNumber(Math.round, value, decimals);
|
|
307
|
+
}
|
|
308
|
+
function roundNumber(callback, value, decimals) {
|
|
309
|
+
if (typeof value !== "number") return NaN;
|
|
310
|
+
if (typeof decimals !== "number" || decimals < 1) return callback(value);
|
|
311
|
+
const mod = 10 ** decimals;
|
|
312
|
+
return callback((value + Number.EPSILON) * mod) / mod;
|
|
313
|
+
}
|
|
251
314
|
//#endregion
|
|
252
315
|
//#region src/helpers/value.ts
|
|
253
316
|
function emitValue(state) {
|
|
@@ -261,7 +324,7 @@ function equalArrays(state, first, second) {
|
|
|
261
324
|
if (length !== second.length) return false;
|
|
262
325
|
let offset = 0;
|
|
263
326
|
if (length >= 100) {
|
|
264
|
-
offset =
|
|
327
|
+
offset = round(length / 10);
|
|
265
328
|
offset = offset > 25 ? 25 : offset;
|
|
266
329
|
for (let index = 0; index < offset; index += 1) if (!state.equal(first[index], second[index])) return false;
|
|
267
330
|
}
|
|
@@ -290,21 +353,44 @@ function getReactiveValueInProxy(reactive, mapped, key, isArray) {
|
|
|
290
353
|
}
|
|
291
354
|
return item;
|
|
292
355
|
}
|
|
293
|
-
function setProxyValue(
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
356
|
+
function setProxyValue(array, state, isObject, isProperty, setObject, setProperty, first, second) {
|
|
357
|
+
if (array && first === "length") {
|
|
358
|
+
state.value.length = second;
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
if (isObject(first)) {
|
|
362
|
+
setObject(state, first);
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
const property = isProperty(first);
|
|
366
|
+
if (array && property && Number.isNaN(first)) return;
|
|
367
|
+
let actual = property ? second : first;
|
|
368
|
+
if (typeof actual === "function") try {
|
|
369
|
+
actual = actual();
|
|
370
|
+
} catch {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
if (actual instanceof Promise) {
|
|
374
|
+
if (property) {
|
|
375
|
+
state.promises ??= /* @__PURE__ */ new Map();
|
|
376
|
+
state.promises.set(first, actual);
|
|
377
|
+
} else state.promise = actual;
|
|
378
|
+
actual.then((value) => {
|
|
379
|
+
if (property && state.promises.get(first) === actual) {
|
|
380
|
+
state.promises.delete(first);
|
|
381
|
+
setProperty(state, first, value);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
if (!property && isObject(value) && state.promise === actual) {
|
|
385
|
+
state.promise = void 0;
|
|
386
|
+
setObject(state, value);
|
|
387
|
+
}
|
|
388
|
+
}).catch(() => {
|
|
389
|
+
if (property && state.promises.get(first) === actual) state.promises.delete(first);
|
|
390
|
+
else if (!property && state.promise === actual) state.promise = void 0;
|
|
391
|
+
});
|
|
392
|
+
} else if (property) setProperty(state, first, actual);
|
|
393
|
+
else if (isObject(actual)) setObject(state, actual);
|
|
308
394
|
}
|
|
309
395
|
function setValueInProxy(parameters) {
|
|
310
396
|
const { isArray, length, property, state, target, value } = parameters;
|
|
@@ -336,10 +422,7 @@ var Signal = class extends Reactive {
|
|
|
336
422
|
* @param value New value
|
|
337
423
|
*/
|
|
338
424
|
set(value) {
|
|
339
|
-
|
|
340
|
-
this.state.value = value;
|
|
341
|
-
emitValue(this.state);
|
|
342
|
-
}
|
|
425
|
+
setValue(this.state, value);
|
|
343
426
|
}
|
|
344
427
|
/**
|
|
345
428
|
* Update the value _(based on the current value)_
|
|
@@ -349,14 +432,33 @@ var Signal = class extends Reactive {
|
|
|
349
432
|
this.set(callback(this.state.value));
|
|
350
433
|
}
|
|
351
434
|
};
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
435
|
+
function setAndEmit(state, value) {
|
|
436
|
+
if (!state.equal(state.value, value)) {
|
|
437
|
+
state.value = value;
|
|
438
|
+
emitValue(state);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function setValue(state, value) {
|
|
442
|
+
try {
|
|
443
|
+
let actual = value;
|
|
444
|
+
if (typeof value === "function") actual = value();
|
|
445
|
+
if (actual instanceof Promise) {
|
|
446
|
+
state.promise = actual;
|
|
447
|
+
actual.then((value) => {
|
|
448
|
+
if (actual === state.promise) {
|
|
449
|
+
state.promise = void 0;
|
|
450
|
+
setAndEmit(state, value);
|
|
451
|
+
}
|
|
452
|
+
}).catch(() => {
|
|
453
|
+
if (actual === state.promise) state.promise = void 0;
|
|
454
|
+
});
|
|
455
|
+
} else setAndEmit(state, actual);
|
|
456
|
+
} catch {}
|
|
457
|
+
}
|
|
358
458
|
function signal(value, options) {
|
|
359
|
-
|
|
459
|
+
const instance = new Signal(void 0, options);
|
|
460
|
+
instance.set(value);
|
|
461
|
+
return instance;
|
|
360
462
|
}
|
|
361
463
|
//#endregion
|
|
362
464
|
//#region src/value/array.ts
|
|
@@ -426,7 +528,7 @@ var ReactiveArray = class extends Reactive {
|
|
|
426
528
|
}
|
|
427
529
|
peek(value) {
|
|
428
530
|
if (value === "length") return this.#size.peek();
|
|
429
|
-
return typeof value === "number" ? this.state.value.at(value) :
|
|
531
|
+
return typeof value === "number" ? this.state.value.at(value) : this.state.value.slice();
|
|
430
532
|
}
|
|
431
533
|
/**
|
|
432
534
|
* Remove and return the last item of the array
|
|
@@ -444,9 +546,7 @@ var ReactiveArray = class extends Reactive {
|
|
|
444
546
|
return this.state.value.push(...items);
|
|
445
547
|
}
|
|
446
548
|
set(first, second) {
|
|
447
|
-
|
|
448
|
-
else if (first === "length") this.length = second;
|
|
449
|
-
else if (typeof first === "number" && !Number.isNaN(first)) setAtIndex(this.state.value, first, second);
|
|
549
|
+
setProxyValue(true, this.state, isArrayValue, isArrayIndex, setArray, setAtIndex, first, second);
|
|
450
550
|
}
|
|
451
551
|
/**
|
|
452
552
|
* Remove and return the first item of the array
|
|
@@ -486,18 +586,20 @@ var ReactiveArray = class extends Reactive {
|
|
|
486
586
|
if (updated == null || Array.isArray(updated)) this.set(updated);
|
|
487
587
|
}
|
|
488
588
|
};
|
|
489
|
-
/**
|
|
490
|
-
* Create a reactive array
|
|
491
|
-
* @param value Initial array of items
|
|
492
|
-
* @param options Reactivity options
|
|
493
|
-
* @returns Reactive array
|
|
494
|
-
*/
|
|
495
589
|
function array(value, options) {
|
|
496
|
-
|
|
590
|
+
const instance = new ReactiveArray([], options);
|
|
591
|
+
instance.set(value);
|
|
592
|
+
return instance;
|
|
593
|
+
}
|
|
594
|
+
function isArrayIndex(value) {
|
|
595
|
+
return typeof value === "number";
|
|
596
|
+
}
|
|
597
|
+
function isArrayValue(value) {
|
|
598
|
+
return value == null || Array.isArray(value);
|
|
497
599
|
}
|
|
498
600
|
function updateArray(type, array, state, length) {
|
|
499
601
|
const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
|
|
500
|
-
const previousArray = affectsLength ? [] :
|
|
602
|
+
const previousArray = affectsLength ? [] : array.slice();
|
|
501
603
|
const previousLength = array.length;
|
|
502
604
|
return (...args) => {
|
|
503
605
|
const result = array[type](...args);
|
|
@@ -508,30 +610,12 @@ function updateArray(type, array, state, length) {
|
|
|
508
610
|
return result;
|
|
509
611
|
};
|
|
510
612
|
}
|
|
511
|
-
function
|
|
512
|
-
|
|
513
|
-
if (actual > -1) array[actual] = value;
|
|
613
|
+
function setArray(state, value) {
|
|
614
|
+
state.value.splice(0, state.value.length, ...value ?? []);
|
|
514
615
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
* Is the value a key?
|
|
519
|
-
* @param value Value to check
|
|
520
|
-
* @returns `true` if the value is a `Key` _(`number` or `string`)_, otherwise `false`
|
|
521
|
-
*/
|
|
522
|
-
function isKey(value) {
|
|
523
|
-
return typeof value === "number" || typeof value === "string";
|
|
524
|
-
}
|
|
525
|
-
/**
|
|
526
|
-
* Is the value a plain object?
|
|
527
|
-
* @param value Value to check
|
|
528
|
-
* @returns `true` if the value is a plain object, otherwise `false`
|
|
529
|
-
*/
|
|
530
|
-
function isPlainObject(value) {
|
|
531
|
-
if (value === null || typeof value !== "object") return false;
|
|
532
|
-
if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
|
|
533
|
-
const prototype = Object.getPrototypeOf(value);
|
|
534
|
-
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
616
|
+
function setAtIndex(state, index, value) {
|
|
617
|
+
const actual = index < 0 ? state.value.length + index : index;
|
|
618
|
+
if (actual > -1) state.value[actual] = value;
|
|
535
619
|
}
|
|
536
620
|
//#endregion
|
|
537
621
|
//#region src/value/store.ts
|
|
@@ -562,8 +646,7 @@ var Store = class extends Reactive {
|
|
|
562
646
|
return isKey(key) ? this.state.value[key] : { ...this.state.value };
|
|
563
647
|
}
|
|
564
648
|
set(first, second) {
|
|
565
|
-
|
|
566
|
-
else if (first == null || isPlainObject(first)) setProxyValue(this.state.value, first ?? {});
|
|
649
|
+
setProxyValue(false, this.state, isStoreObject, isKey, setObject, setProperty, first, second);
|
|
567
650
|
}
|
|
568
651
|
subscribe(first, second) {
|
|
569
652
|
if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
|
|
@@ -574,18 +657,38 @@ var Store = class extends Reactive {
|
|
|
574
657
|
* @param callback Callback to update the value
|
|
575
658
|
*/
|
|
576
659
|
update(callback) {
|
|
577
|
-
const updated = callback(
|
|
578
|
-
if (updated == null || isPlainObject(updated))
|
|
660
|
+
const updated = callback(this.state.value);
|
|
661
|
+
if (updated == null || isPlainObject(updated)) setObject(this.state, updated);
|
|
579
662
|
}
|
|
580
663
|
};
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
664
|
+
function isStoreObject(value) {
|
|
665
|
+
return value == null || isPlainObject(value);
|
|
666
|
+
}
|
|
667
|
+
function setObject(state, value) {
|
|
668
|
+
startBatch();
|
|
669
|
+
const actual = value ?? {};
|
|
670
|
+
const proxy = state.value;
|
|
671
|
+
const proxyKeys = Object.keys(proxy);
|
|
672
|
+
const actualKeys = Object.keys(actual);
|
|
673
|
+
let { length } = proxyKeys;
|
|
674
|
+
for (let index = 0; index < length; index += 1) {
|
|
675
|
+
const key = proxyKeys[index];
|
|
676
|
+
proxy[key] = actualKeys.includes(key) ? actual[key] : void 0;
|
|
677
|
+
}
|
|
678
|
+
length = actualKeys.length;
|
|
679
|
+
for (let index = 0; index < length; index += 1) {
|
|
680
|
+
const key = actualKeys[index];
|
|
681
|
+
if (!proxyKeys.includes(key)) proxy[key] = actual[key];
|
|
682
|
+
}
|
|
683
|
+
stopBatch();
|
|
684
|
+
}
|
|
685
|
+
function setProperty(state, key, value) {
|
|
686
|
+
state.value[key] = value;
|
|
687
|
+
}
|
|
587
688
|
function store(value, options) {
|
|
588
|
-
|
|
689
|
+
const instance = new Store({}, options);
|
|
690
|
+
instance.set(value);
|
|
691
|
+
return instance;
|
|
589
692
|
}
|
|
590
693
|
//#endregion
|
|
591
694
|
export { array, computed, effect, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };
|
package/dist/subscription.d.mts
CHANGED
|
@@ -1,2 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactiveState, Unsubscribe } from "./models.mjs";
|
|
2
|
+
import { GenericCallback } from "@oscarpalmer/atoms/models";
|
|
3
|
+
|
|
4
|
+
//#region src/subscription.d.ts
|
|
5
|
+
declare class Subscription {
|
|
6
|
+
callback: GenericCallback;
|
|
7
|
+
state: ReactiveState<unknown, never>;
|
|
8
|
+
constructor(state: ReactiveState<unknown, never>, callback: GenericCallback);
|
|
9
|
+
destroy(): void;
|
|
10
|
+
}
|
|
11
|
+
declare function noop(): void;
|
|
12
|
+
declare function subscribe<Value>(state: ReactiveState<Value, never>, callback: (value: Value) => void): Unsubscribe;
|
|
13
|
+
declare function unsubscribe<Value>(state: ReactiveState<Value, never>, callback: (value: Value) => void): void;
|
|
14
|
+
//#endregion
|
|
2
15
|
export { Subscription, noop, subscribe, unsubscribe };
|