@oscarpalmer/mora 0.38.0 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/batch.d.mts +1 -3
- package/dist/batch.mjs +3 -4
- package/dist/constants.d.mts +16 -10
- package/dist/constants.mjs +12 -6
- package/dist/effect.d.mts +2 -3
- package/dist/effect.mjs +27 -8
- package/dist/helpers/is.d.mts +1 -3
- package/dist/helpers/is.mjs +8 -5
- package/dist/helpers/misc.d.mts +8 -4
- package/dist/helpers/misc.mjs +66 -4
- package/dist/helpers/proxy.d.mts +3 -4
- package/dist/helpers/proxy.mjs +26 -11
- package/dist/helpers/subscription.d.mts +1 -3
- package/dist/helpers/subscription.mjs +15 -7
- package/dist/helpers/value.d.mts +4 -5
- package/dist/helpers/value.mjs +18 -13
- package/dist/models.d.mts +38 -5
- package/dist/mora.full.mjs +555 -276
- package/dist/value/array.d.mts +1 -3
- package/dist/value/array.mjs +46 -22
- package/dist/value/computed.d.mts +1 -3
- package/dist/value/computed.mjs +17 -11
- package/dist/value/readonly.d.mts +2 -5
- package/dist/value/readonly.mjs +24 -16
- package/dist/value/signal.d.mts +1 -3
- package/dist/value/signal.mjs +9 -6
- package/dist/value/store.d.mts +1 -3
- package/dist/value/store.mjs +9 -6
- package/package.json +5 -12
- package/src/batch.ts +8 -4
- package/src/constants.ts +26 -16
- package/src/effect.ts +37 -7
- package/src/helpers/is.ts +18 -8
- package/src/helpers/misc.ts +121 -2
- package/src/helpers/proxy.ts +59 -9
- package/src/helpers/subscription.ts +34 -4
- package/src/helpers/value.ts +48 -15
- package/src/models.ts +42 -3
- package/src/value/array.ts +100 -21
- package/src/value/computed.ts +29 -10
- package/src/value/readonly.ts +38 -33
- package/src/value/signal.ts +11 -5
- package/src/value/store.ts +11 -5
- package/types/batch.d.ts +0 -11
- package/types/constants.d.ts +0 -16
- package/types/effect.d.ts +0 -13
- package/types/helpers/is.d.ts +0 -43
- package/types/helpers/proxy.d.ts +0 -11
- package/types/helpers/value.d.ts +0 -4
- package/types/index.d.ts +0 -9
- package/types/models.d.ts +0 -56
- package/types/subscription.d.ts +0 -11
- package/types/value/array.d.ts +0 -137
- package/types/value/computed.d.ts +0 -14
- package/types/value/reactive.d.ts +0 -36
- package/types/value/signal.d.ts +0 -26
- package/types/value/store.d.ts +0 -94
package/dist/batch.d.mts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
//#region src/batch.d.ts
|
|
2
1
|
export declare function flushHandlers(): void;
|
|
3
2
|
/**
|
|
4
3
|
* Start batching effects
|
|
@@ -9,5 +8,4 @@ export declare function startBatch(): void;
|
|
|
9
8
|
/**
|
|
10
9
|
* Stop batching effects and flush _(run)_ them
|
|
11
10
|
*/
|
|
12
|
-
export declare function stopBatch(): void;
|
|
13
|
-
//#endregion
|
|
11
|
+
export declare function stopBatch(): void;
|
package/dist/batch.mjs
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { BATCH } from "./constants.mjs";
|
|
2
2
|
import { runEffect } from "./effect.mjs";
|
|
3
3
|
import { getFrozenValue, peekSignalValue } from "./helpers/value.mjs";
|
|
4
|
-
|
|
5
|
-
//#region src/batch.ts
|
|
4
|
+
// src/batch.ts
|
|
6
5
|
function flushHandlers() {
|
|
7
6
|
if (BATCH.flushing) return;
|
|
8
7
|
BATCH.flushing = true;
|
|
@@ -12,7 +11,8 @@ function flushHandlers() {
|
|
|
12
11
|
const { length } = handlers;
|
|
13
12
|
BATCH.handlers.clear();
|
|
14
13
|
for (let index = 0; index < length; index += 1) {
|
|
15
|
-
const [, handler] = handlers[index];
|
|
14
|
+
const [owner, handler] = handlers[index];
|
|
15
|
+
if (!owner.active) continue;
|
|
16
16
|
const subscription = handler;
|
|
17
17
|
if (typeof subscription.frozen === "boolean") subscription.callback(subscription.frozen ? getFrozenValue(subscription.state.value) : peekSignalValue.call(subscription.instance, subscription.copy));
|
|
18
18
|
else runEffect(handler);
|
|
@@ -37,5 +37,4 @@ function stopBatch() {
|
|
|
37
37
|
if (BATCH.depth > 0) BATCH.depth -= 1;
|
|
38
38
|
flushHandlers();
|
|
39
39
|
}
|
|
40
|
-
//#endregion
|
|
41
40
|
export { flushHandlers, startBatch, stopBatch };
|
package/dist/constants.d.mts
CHANGED
|
@@ -1,30 +1,36 @@
|
|
|
1
1
|
import { Active, Batch, SubscriptionType } from "./models.mjs";
|
|
2
2
|
import { SubscriptionProperty } from "@oscarpalmer/atoms/subscription";
|
|
3
|
-
//#region src/constants.d.ts
|
|
4
3
|
export declare const ACTIVE: Active;
|
|
5
4
|
export declare const ARRAY_THRESHOLD = 100;
|
|
6
5
|
export declare const ARRAY_OFFSET = 25;
|
|
7
6
|
export declare const ARRAY_PEEK = 10;
|
|
8
7
|
export declare const BATCH: Batch;
|
|
8
|
+
export declare const MESSAGE_COMPUTED_CALLBACK = "Computed callback must be a function";
|
|
9
|
+
export declare const MESSAGE_DEACTIVATED_ARRAY_FILTER = "Cannot filter an inactive reactive array";
|
|
10
|
+
export declare const MESSAGE_DEACTIVATED_ARRAY_MAP = "Cannot map an inactive reactive array";
|
|
11
|
+
export declare const MESSAGE_DEACTIVATED_ARRAY_SELECT = "Cannot select from an inactive reactive array";
|
|
12
|
+
export declare const MESSAGE_DEACTIVATED_READONLY = "Cannot create readonly variant of inactive signal";
|
|
13
|
+
export declare const MESSAGE_DEACTIVATED_SUBSCRIPTION = "Cannot subscribe to inactive signal";
|
|
14
|
+
export declare const MESSAGE_EFFECT_CALLBACK = "Effect callback must be a function";
|
|
15
|
+
export declare const MESSAGE_UPDATE_CALLBACK = "Update callback must be a function";
|
|
9
16
|
export declare const METHODS_AFFECTING_LENGTH: Set<string | symbol>;
|
|
10
17
|
export declare const METHODS_UPDATE: Set<string | symbol>;
|
|
11
18
|
export declare const NAME_ARRAY = "array";
|
|
12
19
|
export declare const NAME_COMPUTED = "computed";
|
|
13
20
|
export declare const NAME_EFFECT = "effect";
|
|
14
|
-
export declare const NAME_MORA = "$mora";
|
|
15
21
|
export declare const NAME_READONLY = "readonly";
|
|
16
22
|
export declare const NAME_SIGNAL = "signal";
|
|
17
23
|
export declare const NAME_STORE = "store";
|
|
18
24
|
export declare const NAME_SUBSCRIPTION = "subscription";
|
|
19
25
|
export declare const NAME_ALL: Set<string>;
|
|
20
26
|
export declare const PROPERTY_LENGTH = "length";
|
|
21
|
-
export declare const SYMBOL_EFFECT: symbol;
|
|
22
|
-
export declare const
|
|
27
|
+
export declare const SYMBOL_EFFECT: unique symbol;
|
|
28
|
+
export declare const SYMBOL_READONLY: unique symbol;
|
|
29
|
+
export declare const SYMBOL_STATE: unique symbol;
|
|
23
30
|
export declare const SUBSCRIPTION_PROPERTY: SubscriptionProperty;
|
|
24
|
-
export declare const SUBSCRIPTION_TYPE_COPY:
|
|
25
|
-
export declare const SUBSCRIPTION_TYPE_FROZEN:
|
|
26
|
-
export declare const SUBSCRIPTION_TYPE_ORIGINAL:
|
|
27
|
-
export declare const SUBSCRIPTION_TYPE_READONLY:
|
|
31
|
+
export declare const SUBSCRIPTION_TYPE_COPY: "copy";
|
|
32
|
+
export declare const SUBSCRIPTION_TYPE_FROZEN: "frozen";
|
|
33
|
+
export declare const SUBSCRIPTION_TYPE_ORIGINAL: "original";
|
|
34
|
+
export declare const SUBSCRIPTION_TYPE_READONLY: "readonly";
|
|
28
35
|
export declare const SUBSCRIPTION_TYPES_COPY: Set<SubscriptionType>;
|
|
29
|
-
export declare const SUBSCRIPTION_TYPES: Set<SubscriptionType>;
|
|
30
|
-
//#endregion
|
|
36
|
+
export declare const SUBSCRIPTION_TYPES: Set<SubscriptionType>;
|
package/dist/constants.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/constants.ts
|
|
2
2
|
const ACTIVE = {};
|
|
3
3
|
const ARRAY_THRESHOLD = 100;
|
|
4
4
|
const ARRAY_OFFSET = 25;
|
|
@@ -8,6 +8,14 @@ const BATCH = {
|
|
|
8
8
|
flushing: false,
|
|
9
9
|
handlers: /* @__PURE__ */ new Map()
|
|
10
10
|
};
|
|
11
|
+
const MESSAGE_COMPUTED_CALLBACK = "Computed callback must be a function";
|
|
12
|
+
const MESSAGE_DEACTIVATED_ARRAY_FILTER = "Cannot filter an inactive reactive array";
|
|
13
|
+
const MESSAGE_DEACTIVATED_ARRAY_MAP = "Cannot map an inactive reactive array";
|
|
14
|
+
const MESSAGE_DEACTIVATED_ARRAY_SELECT = "Cannot select from an inactive reactive array";
|
|
15
|
+
const MESSAGE_DEACTIVATED_READONLY = "Cannot create readonly variant of inactive signal";
|
|
16
|
+
const MESSAGE_DEACTIVATED_SUBSCRIPTION = "Cannot subscribe to inactive signal";
|
|
17
|
+
const MESSAGE_EFFECT_CALLBACK = "Effect callback must be a function";
|
|
18
|
+
const MESSAGE_UPDATE_CALLBACK = "Update callback must be a function";
|
|
11
19
|
const METHODS_AFFECTING_LENGTH = /* @__PURE__ */ new Set([
|
|
12
20
|
"pop",
|
|
13
21
|
"push",
|
|
@@ -25,7 +33,6 @@ const METHODS_UPDATE = /* @__PURE__ */ new Set([
|
|
|
25
33
|
const NAME_ARRAY = "array";
|
|
26
34
|
const NAME_COMPUTED = "computed";
|
|
27
35
|
const NAME_EFFECT = "effect";
|
|
28
|
-
const NAME_MORA = "$mora";
|
|
29
36
|
const NAME_READONLY = "readonly";
|
|
30
37
|
const NAME_SIGNAL = "signal";
|
|
31
38
|
const NAME_STORE = "store";
|
|
@@ -33,15 +40,15 @@ const NAME_SUBSCRIPTION = "subscription";
|
|
|
33
40
|
const NAME_ALL = /* @__PURE__ */ new Set([
|
|
34
41
|
NAME_ARRAY,
|
|
35
42
|
NAME_COMPUTED,
|
|
36
|
-
NAME_READONLY,
|
|
37
43
|
NAME_SIGNAL,
|
|
38
44
|
NAME_STORE
|
|
39
45
|
]);
|
|
40
46
|
const PROPERTY_LENGTH = "length";
|
|
41
47
|
const SYMBOL_EFFECT = Symbol("effect");
|
|
48
|
+
const SYMBOL_READONLY = Symbol("readonly");
|
|
42
49
|
const SYMBOL_STATE = Symbol("state");
|
|
43
50
|
const SUBSCRIPTION_PROPERTY = {
|
|
44
|
-
key:
|
|
51
|
+
key: "$mora",
|
|
45
52
|
value: NAME_SUBSCRIPTION
|
|
46
53
|
};
|
|
47
54
|
const SUBSCRIPTION_TYPE_COPY = "copy";
|
|
@@ -54,5 +61,4 @@ const SUBSCRIPTION_TYPES = /* @__PURE__ */ new Set([
|
|
|
54
61
|
SUBSCRIPTION_TYPE_FROZEN,
|
|
55
62
|
SUBSCRIPTION_TYPE_ORIGINAL
|
|
56
63
|
]);
|
|
57
|
-
|
|
58
|
-
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_READONLY, NAME_SIGNAL, NAME_STORE, NAME_SUBSCRIPTION, PROPERTY_LENGTH, SUBSCRIPTION_PROPERTY, SUBSCRIPTION_TYPES, SUBSCRIPTION_TYPES_COPY, SUBSCRIPTION_TYPE_COPY, SUBSCRIPTION_TYPE_FROZEN, SUBSCRIPTION_TYPE_ORIGINAL, SUBSCRIPTION_TYPE_READONLY, SYMBOL_EFFECT, SYMBOL_STATE };
|
|
64
|
+
export { ACTIVE, ARRAY_OFFSET, ARRAY_PEEK, ARRAY_THRESHOLD, BATCH, MESSAGE_COMPUTED_CALLBACK, MESSAGE_DEACTIVATED_ARRAY_FILTER, MESSAGE_DEACTIVATED_ARRAY_MAP, MESSAGE_DEACTIVATED_ARRAY_SELECT, MESSAGE_DEACTIVATED_READONLY, MESSAGE_DEACTIVATED_SUBSCRIPTION, MESSAGE_EFFECT_CALLBACK, MESSAGE_UPDATE_CALLBACK, METHODS_AFFECTING_LENGTH, METHODS_UPDATE, NAME_ALL, NAME_ARRAY, NAME_COMPUTED, NAME_EFFECT, NAME_READONLY, NAME_SIGNAL, NAME_STORE, NAME_SUBSCRIPTION, PROPERTY_LENGTH, SUBSCRIPTION_PROPERTY, SUBSCRIPTION_TYPES, SUBSCRIPTION_TYPES_COPY, SUBSCRIPTION_TYPE_COPY, SUBSCRIPTION_TYPE_FROZEN, SUBSCRIPTION_TYPE_ORIGINAL, SUBSCRIPTION_TYPE_READONLY, SYMBOL_EFFECT, SYMBOL_READONLY, SYMBOL_STATE };
|
package/dist/effect.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Effect, EffectState } from "./models.mjs";
|
|
2
2
|
import { GenericCallback } from "@oscarpalmer/atoms/models";
|
|
3
|
-
|
|
3
|
+
export declare function deactivateEffect(state: EffectState): void;
|
|
4
4
|
/**
|
|
5
5
|
* Create an effect
|
|
6
6
|
*
|
|
@@ -9,5 +9,4 @@ import { GenericCallback } from "@oscarpalmer/atoms/models";
|
|
|
9
9
|
*/
|
|
10
10
|
export declare function effect(callback: GenericCallback): Effect;
|
|
11
11
|
export declare function internalEffect(callback: GenericCallback): EffectState;
|
|
12
|
-
export declare function runEffect(state: EffectState): void;
|
|
13
|
-
//#endregion
|
|
12
|
+
export declare function runEffect(state: EffectState): void;
|
package/dist/effect.mjs
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
|
-
import { ACTIVE,
|
|
2
|
-
import "@oscarpalmer/atoms/
|
|
3
|
-
|
|
1
|
+
import { ACTIVE, BATCH, MESSAGE_EFFECT_CALLBACK, NAME_EFFECT, SYMBOL_STATE } from "./constants.mjs";
|
|
2
|
+
import { noop } from "@oscarpalmer/atoms/function";
|
|
3
|
+
// src/effect.ts
|
|
4
4
|
function Effect(callback) {
|
|
5
|
-
this[SYMBOL_STATE] = {
|
|
5
|
+
this[SYMBOL_STATE] = {
|
|
6
|
+
callback,
|
|
7
|
+
active: true,
|
|
8
|
+
name: NAME_EFFECT
|
|
9
|
+
};
|
|
6
10
|
runEffect(this[SYMBOL_STATE]);
|
|
7
11
|
}
|
|
8
|
-
Effect.prototype
|
|
12
|
+
Effect.prototype.stop = stopEffect;
|
|
13
|
+
Object.defineProperties(Effect.prototype, { active: {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: getActive
|
|
16
|
+
} });
|
|
17
|
+
function deactivateEffect(state) {
|
|
18
|
+
state.active = false;
|
|
19
|
+
state.callback = noop;
|
|
20
|
+
BATCH.handlers.delete(state);
|
|
21
|
+
}
|
|
9
22
|
/**
|
|
10
23
|
* Create an effect
|
|
11
24
|
*
|
|
@@ -13,9 +26,12 @@ Effect.prototype[NAME_MORA] = NAME_EFFECT;
|
|
|
13
26
|
* @returns Effect
|
|
14
27
|
*/
|
|
15
28
|
function effect(callback) {
|
|
16
|
-
if (typeof callback !== "function") throw new TypeError(
|
|
29
|
+
if (typeof callback !== "function") throw new TypeError(MESSAGE_EFFECT_CALLBACK);
|
|
17
30
|
return getEffect(callback)[0];
|
|
18
31
|
}
|
|
32
|
+
function getActive() {
|
|
33
|
+
return this[SYMBOL_STATE].active;
|
|
34
|
+
}
|
|
19
35
|
function getEffect(callback) {
|
|
20
36
|
const instance = new Effect(callback);
|
|
21
37
|
return [instance, instance[SYMBOL_STATE]];
|
|
@@ -32,5 +48,8 @@ function runEffect(state) {
|
|
|
32
48
|
ACTIVE.effect = previousEffect;
|
|
33
49
|
}
|
|
34
50
|
}
|
|
35
|
-
|
|
36
|
-
|
|
51
|
+
function stopEffect() {
|
|
52
|
+
const state = this[SYMBOL_STATE];
|
|
53
|
+
if (state.active) deactivateEffect(state);
|
|
54
|
+
}
|
|
55
|
+
export { deactivateEffect, effect, internalEffect, runEffect };
|
package/dist/helpers/is.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Computed, Effect, Reactive, ReactiveArray, ReactiveStore, ReadonlySignal, Signal } from "../models.mjs";
|
|
2
2
|
import { PlainObject } from "@oscarpalmer/atoms/models";
|
|
3
|
-
//#region src/helpers/is.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Is the value a computed signal?
|
|
6
5
|
*
|
|
@@ -49,5 +48,4 @@ export declare function isReactiveStore<Value extends PlainObject = PlainObject>
|
|
|
49
48
|
* @param value Value to check
|
|
50
49
|
* @returns True if value is a {@link ReadonlySignal}
|
|
51
50
|
*/
|
|
52
|
-
export declare function isReadonlySignal<Value = unknown>(value: unknown): value is ReadonlySignal<Value>;
|
|
53
|
-
//#endregion
|
|
51
|
+
export declare function isReadonlySignal<Value = unknown>(value: unknown): value is ReadonlySignal<Value>;
|
package/dist/helpers/is.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { NAME_ALL, NAME_ARRAY, NAME_COMPUTED, NAME_EFFECT, NAME_READONLY, NAME_SIGNAL, NAME_STORE } from "../constants.mjs";
|
|
2
|
-
|
|
1
|
+
import { NAME_ALL, NAME_ARRAY, NAME_COMPUTED, NAME_EFFECT, NAME_READONLY, NAME_SIGNAL, NAME_STORE, SYMBOL_READONLY, SYMBOL_STATE } from "../constants.mjs";
|
|
2
|
+
// src/helpers/is.ts
|
|
3
3
|
/**
|
|
4
4
|
* Is the value a computed signal?
|
|
5
5
|
*
|
|
@@ -18,8 +18,12 @@ function isComputed(value) {
|
|
|
18
18
|
function isEffect(value) {
|
|
19
19
|
return isMora(value, NAME_EFFECT);
|
|
20
20
|
}
|
|
21
|
-
function isMora(
|
|
22
|
-
|
|
21
|
+
function isMora(input, value) {
|
|
22
|
+
if (typeof input !== "object" || input === null) return false;
|
|
23
|
+
if (value === "readonly") return SYMBOL_READONLY in input;
|
|
24
|
+
if (!(SYMBOL_STATE in input)) return false;
|
|
25
|
+
const state = input[SYMBOL_STATE];
|
|
26
|
+
return typeof value === "string" ? state.name === value : value.has(state.name);
|
|
23
27
|
}
|
|
24
28
|
/**
|
|
25
29
|
* Is the value reactive?
|
|
@@ -66,5 +70,4 @@ function isReactiveStore(value) {
|
|
|
66
70
|
function isReadonlySignal(value) {
|
|
67
71
|
return isMora(value, NAME_READONLY);
|
|
68
72
|
}
|
|
69
|
-
//#endregion
|
|
70
73
|
export { isComputed, isEffect, isReactive, isReactiveArray, isReactiveStore, isReadonlySignal, isSignal };
|
package/dist/helpers/misc.d.mts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import { ReactiveOptions, ReactiveState } from "../models.mjs";
|
|
2
|
-
|
|
3
|
-
export declare function
|
|
4
|
-
|
|
1
|
+
import { InternalArray, InternalComputed, InternalReactive, InternalReadonly, InternalStore, ReactiveOptions, ReactiveState } from "../models.mjs";
|
|
2
|
+
export declare function deactivateComputed(this: InternalComputed): void;
|
|
3
|
+
export declare function deactivateProxy(this: InternalArray | InternalStore): void;
|
|
4
|
+
export declare function deactivateReactive(this: InternalReactive): void;
|
|
5
|
+
export declare function deactivateReadonly(this: InternalReadonly): void;
|
|
6
|
+
export declare function getReactiveActive(this: InternalReactive): boolean;
|
|
7
|
+
export declare function getReadonlyActive(this: InternalReadonly): boolean;
|
|
8
|
+
export declare function getState(name: string, value: unknown, options?: ReactiveOptions<unknown>): ReactiveState;
|
package/dist/helpers/misc.mjs
CHANGED
|
@@ -1,9 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { SYMBOL_EFFECT, SYMBOL_READONLY, SYMBOL_STATE } from "../constants.mjs";
|
|
2
|
+
import { deactivateEffect } from "../effect.mjs";
|
|
3
|
+
import { peekSignalValue } from "./value.mjs";
|
|
4
|
+
import { noop } from "@oscarpalmer/atoms/function";
|
|
5
|
+
// src/helpers/misc.ts
|
|
6
|
+
function deactivateComputed() {
|
|
7
|
+
if (!this[SYMBOL_STATE].active) return;
|
|
8
|
+
deactivateEffect(this[SYMBOL_EFFECT].instance);
|
|
9
|
+
deactivateReactive.call(this);
|
|
10
|
+
}
|
|
11
|
+
function deactivateProxy() {
|
|
12
|
+
const state = this[SYMBOL_STATE];
|
|
13
|
+
if (!state.active) return;
|
|
14
|
+
if (state.derived != null) {
|
|
15
|
+
for (const computed of state.derived) computed.deactivate();
|
|
16
|
+
state.derived.clear();
|
|
17
|
+
state.derived = void 0;
|
|
18
|
+
}
|
|
19
|
+
if (state.mapped != null) {
|
|
20
|
+
for (const [, computed] of state.mapped) computed.deactivate();
|
|
21
|
+
state.mapped.clear();
|
|
22
|
+
state.mapped = void 0;
|
|
23
|
+
}
|
|
24
|
+
deactivateReactive.call(this);
|
|
25
|
+
}
|
|
26
|
+
function deactivateReactive() {
|
|
27
|
+
const state = this[SYMBOL_STATE];
|
|
28
|
+
if (!state.active) return;
|
|
29
|
+
state.active = false;
|
|
30
|
+
state.computeds?.clear();
|
|
31
|
+
state.effects?.clear();
|
|
32
|
+
state.promises?.clear();
|
|
33
|
+
state.readonlies?.frozen?.deactivate();
|
|
34
|
+
state.readonlies?.original?.deactivate();
|
|
35
|
+
state.subscriptions?.clear();
|
|
36
|
+
state.equal = noop;
|
|
37
|
+
state.promise = void 0;
|
|
38
|
+
state.computeds = void 0;
|
|
39
|
+
state.effects = void 0;
|
|
40
|
+
state.promises = void 0;
|
|
41
|
+
state.readonlies = void 0;
|
|
42
|
+
state.subscriptions = void 0;
|
|
43
|
+
}
|
|
44
|
+
function deactivateReadonly() {
|
|
45
|
+
const readonly = this[SYMBOL_READONLY];
|
|
46
|
+
const signal = this[SYMBOL_STATE];
|
|
47
|
+
if (!readonly.active) return;
|
|
48
|
+
signal.readonlies[readonly.name] = void 0;
|
|
49
|
+
if (readonly.subscriptions != null) {
|
|
50
|
+
for (const subscription of readonly.subscriptions) subscription.unsubscribe();
|
|
51
|
+
readonly.subscriptions.clear();
|
|
52
|
+
readonly.subscriptions = void 0;
|
|
53
|
+
}
|
|
54
|
+
readonly.active = false;
|
|
55
|
+
readonly.value = peekSignalValue.call(this, true);
|
|
56
|
+
}
|
|
57
|
+
function getReactiveActive() {
|
|
58
|
+
return this[SYMBOL_STATE].active;
|
|
59
|
+
}
|
|
60
|
+
function getReadonlyActive() {
|
|
61
|
+
return this[SYMBOL_READONLY].active;
|
|
62
|
+
}
|
|
63
|
+
function getState(name, value, options) {
|
|
3
64
|
return {
|
|
65
|
+
name,
|
|
4
66
|
value,
|
|
67
|
+
active: true,
|
|
5
68
|
equal: typeof options === "object" && typeof options?.equal === "function" ? options.equal : void 0
|
|
6
69
|
};
|
|
7
70
|
}
|
|
8
|
-
|
|
9
|
-
export { getState };
|
|
71
|
+
export { deactivateComputed, deactivateProxy, deactivateReactive, deactivateReadonly, getReactiveActive, getReadonlyActive, getState };
|
package/dist/helpers/proxy.d.mts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { InternalArray, InternalComputed, InternalStore } from "../models.mjs";
|
|
1
|
+
import { Computed, InternalArray, InternalComputed, InternalStore } from "../models.mjs";
|
|
2
2
|
import { Key } from "@oscarpalmer/atoms/models";
|
|
3
|
-
//#region src/helpers/proxy.d.ts
|
|
4
3
|
export declare function getReactiveValueInProxy(instance: InternalArray | InternalStore, key: Key): InternalComputed;
|
|
5
4
|
export declare function getValueInProxy(this: InternalArray | InternalStore, first?: unknown): unknown;
|
|
6
5
|
export declare function notifyProxyValue(this: InternalArray | InternalStore): void;
|
|
7
6
|
export declare function peekValueInProxy(this: InternalArray | InternalStore, first?: unknown, second?: boolean): unknown;
|
|
8
7
|
export declare function setProxyValue(this: InternalArray | InternalStore, first?: unknown, second?: unknown): void;
|
|
9
8
|
export declare function setValueInProxy(instance: InternalArray | InternalStore, target: object, property: PropertyKey, value: unknown): boolean;
|
|
10
|
-
export declare function
|
|
11
|
-
|
|
9
|
+
export declare function updateProxyDerivations(instance: InternalArray | InternalStore, value: Computed<unknown[]>): Computed<unknown[]>;
|
|
10
|
+
export declare function updateProxyValue(this: InternalArray | InternalStore, callback: unknown): void;
|
package/dist/helpers/proxy.mjs
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { SYMBOL_EFFECT, SYMBOL_STATE } from "../constants.mjs";
|
|
1
|
+
import { MESSAGE_UPDATE_CALLBACK, SYMBOL_EFFECT, SYMBOL_STATE } from "../constants.mjs";
|
|
2
2
|
import { emitValue, getSignalValue, peekSignalValue } from "./value.mjs";
|
|
3
3
|
import { startBatch, stopBatch } from "../batch.mjs";
|
|
4
4
|
import { internalComputed } from "../value/computed.mjs";
|
|
5
|
-
import "@oscarpalmer/atoms/result";
|
|
6
5
|
import { isKey, isPlainObject } from "@oscarpalmer/atoms/is";
|
|
7
|
-
|
|
6
|
+
import { getNumber } from "@oscarpalmer/atoms/number";
|
|
7
|
+
import { getString } from "@oscarpalmer/atoms/string";
|
|
8
|
+
// src/helpers/proxy.ts
|
|
8
9
|
function getReactiveValueInProxy(instance, key) {
|
|
9
10
|
const state = instance[SYMBOL_STATE];
|
|
10
11
|
state.mapped ??= /* @__PURE__ */ new Map();
|
|
11
|
-
const mapKey =
|
|
12
|
+
const mapKey = getString(key);
|
|
12
13
|
let item = state.mapped.get(mapKey);
|
|
13
14
|
if (item == null) {
|
|
14
15
|
item = internalComputed(() => state.isArray ? instance.get().at(key) : instance.get()[key]);
|
|
@@ -17,18 +18,21 @@ function getReactiveValueInProxy(instance, key) {
|
|
|
17
18
|
return item;
|
|
18
19
|
}
|
|
19
20
|
function getValueInProxy(first) {
|
|
21
|
+
const state = this[SYMBOL_STATE];
|
|
22
|
+
if (!state.active) return peekValueInProxy.call(this, first);
|
|
20
23
|
let signal;
|
|
21
|
-
if (
|
|
24
|
+
if (state.isArray ? typeof first === "number" : isKey(first)) signal = getReactiveValueInProxy(this, first);
|
|
22
25
|
return getSignalValue.call(signal ?? this);
|
|
23
26
|
}
|
|
24
27
|
function isProxyKey(isArray, value) {
|
|
25
|
-
return isArray
|
|
28
|
+
return isArray && typeof value === "number" || isKey(value);
|
|
26
29
|
}
|
|
27
30
|
function isProxyObject(isArray, value) {
|
|
28
31
|
return value == null || (isArray ? Array.isArray(value) : isPlainObject(value));
|
|
29
32
|
}
|
|
30
33
|
function notifyProxyValue() {
|
|
31
34
|
const state = this[SYMBOL_STATE];
|
|
35
|
+
if (!state.active) return;
|
|
32
36
|
state.mapped ??= /* @__PURE__ */ new Map();
|
|
33
37
|
const values = [...state.mapped.values()];
|
|
34
38
|
const { length } = values;
|
|
@@ -80,6 +84,7 @@ function setProxyProperty(state, property, value) {
|
|
|
80
84
|
}
|
|
81
85
|
function setProxyValue(first, second) {
|
|
82
86
|
const state = this[SYMBOL_STATE];
|
|
87
|
+
if (!state.active) return;
|
|
83
88
|
if (state.isArray && first === "length") {
|
|
84
89
|
state.value.length = second;
|
|
85
90
|
return;
|
|
@@ -120,8 +125,9 @@ function setProxyValue(first, second) {
|
|
|
120
125
|
}
|
|
121
126
|
function setValueInProxy(instance, target, property, value) {
|
|
122
127
|
const state = instance[SYMBOL_STATE];
|
|
128
|
+
if (!state.active) return true;
|
|
123
129
|
if (state.isArray) {
|
|
124
|
-
if (!(!Number.isNaN(
|
|
130
|
+
if (!(!Number.isNaN(getNumber(property)) || property === "length")) return Reflect.set(target, property, value);
|
|
125
131
|
}
|
|
126
132
|
const previous = Reflect.get(target, property);
|
|
127
133
|
if (!(state.equal ?? Object.is)(previous, value)) {
|
|
@@ -131,9 +137,18 @@ function setValueInProxy(instance, target, property, value) {
|
|
|
131
137
|
}
|
|
132
138
|
return true;
|
|
133
139
|
}
|
|
140
|
+
function updateProxyDerivations(instance, value) {
|
|
141
|
+
const state = instance[SYMBOL_STATE];
|
|
142
|
+
if (state.derived == null) {
|
|
143
|
+
state.derived = /* @__PURE__ */ new Set([value]);
|
|
144
|
+
return value;
|
|
145
|
+
}
|
|
146
|
+
for (const computed of state.derived) if (!computed.active) state.derived.delete(computed);
|
|
147
|
+
state.derived.add(value);
|
|
148
|
+
return value;
|
|
149
|
+
}
|
|
134
150
|
function updateProxyValue(callback) {
|
|
135
|
-
if (typeof callback !== "function") throw new TypeError(
|
|
136
|
-
setProxyValue.call(this, callback(this[SYMBOL_STATE].value));
|
|
151
|
+
if (typeof callback !== "function") throw new TypeError(MESSAGE_UPDATE_CALLBACK);
|
|
152
|
+
if (this[SYMBOL_STATE].active) setProxyValue.call(this, callback(this[SYMBOL_STATE].value));
|
|
137
153
|
}
|
|
138
|
-
|
|
139
|
-
export { getReactiveValueInProxy, getValueInProxy, notifyProxyValue, peekValueInProxy, setProxyValue, setValueInProxy, updateProxyValue };
|
|
154
|
+
export { getReactiveValueInProxy, getValueInProxy, notifyProxyValue, peekValueInProxy, setProxyValue, setValueInProxy, updateProxyDerivations, updateProxyValue };
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { InternalArray, InternalReadonly, InternalStateful, InternalStore, Subscriber } from "../models.mjs";
|
|
2
2
|
import { Subscription } from "@oscarpalmer/atoms/subscription";
|
|
3
3
|
import { Key } from "@oscarpalmer/atoms/models";
|
|
4
|
-
//#region src/helpers/subscription.d.ts
|
|
5
4
|
export declare function subscribeToProxy(this: InternalArray | InternalStore, first: Key | Subscriber<unknown>, second?: Subscriber<unknown> | boolean, third?: boolean): Subscription;
|
|
6
5
|
export declare function subscribeToReadonly(this: InternalReadonly, subscriber: Subscriber<unknown>): Subscription;
|
|
7
|
-
export declare function subscribeToSignal(this: InternalStateful, subscriber: Subscriber<unknown>, copy?: unknown): Subscription;
|
|
8
|
-
//#endregion
|
|
6
|
+
export declare function subscribeToSignal(this: InternalStateful, subscriber: Subscriber<unknown>, copy?: unknown): Subscription;
|
|
@@ -1,30 +1,38 @@
|
|
|
1
|
-
import { SUBSCRIPTION_PROPERTY, SUBSCRIPTION_TYPES, SUBSCRIPTION_TYPES_COPY, SUBSCRIPTION_TYPE_COPY, SUBSCRIPTION_TYPE_FROZEN, SUBSCRIPTION_TYPE_ORIGINAL, SUBSCRIPTION_TYPE_READONLY, SYMBOL_STATE } from "../constants.mjs";
|
|
1
|
+
import { MESSAGE_DEACTIVATED_SUBSCRIPTION, SUBSCRIPTION_PROPERTY, SUBSCRIPTION_TYPES, SUBSCRIPTION_TYPES_COPY, SUBSCRIPTION_TYPE_COPY, SUBSCRIPTION_TYPE_FROZEN, SUBSCRIPTION_TYPE_ORIGINAL, SUBSCRIPTION_TYPE_READONLY, SYMBOL_READONLY, SYMBOL_STATE } from "../constants.mjs";
|
|
2
2
|
import { getFrozenValue, peekSignalValue } from "./value.mjs";
|
|
3
3
|
import { getReactiveValueInProxy } from "./proxy.mjs";
|
|
4
4
|
import { isKey } from "@oscarpalmer/atoms/is";
|
|
5
5
|
import { subscriptions } from "@oscarpalmer/atoms/subscription";
|
|
6
|
-
|
|
6
|
+
// src/helpers/subscription.ts
|
|
7
7
|
function subscribeToProxy(first, second, third) {
|
|
8
|
+
if (!this[SYMBOL_STATE].active) throw new Error(MESSAGE_DEACTIVATED_SUBSCRIPTION);
|
|
8
9
|
if (isKey(first)) return getReactiveValueInProxy(this, first).subscribe(second, third);
|
|
9
10
|
return subscribeToSignal.call(this, first, second);
|
|
10
11
|
}
|
|
11
12
|
function subscribeToReactive(type, subscriber) {
|
|
12
|
-
this[SYMBOL_STATE]
|
|
13
|
+
const state = this[SYMBOL_STATE];
|
|
14
|
+
if (!state.active) throw new Error(MESSAGE_DEACTIVATED_SUBSCRIPTION);
|
|
15
|
+
state.subscriptions ??= subscriptions({
|
|
13
16
|
keys: SUBSCRIPTION_TYPES,
|
|
14
17
|
property: SUBSCRIPTION_PROPERTY
|
|
15
18
|
});
|
|
16
|
-
const [subscription, existing] =
|
|
19
|
+
const [subscription, existing] = state.subscriptions.create({
|
|
17
20
|
key: type,
|
|
18
21
|
value: subscriber
|
|
19
22
|
});
|
|
20
|
-
if (!existing) subscriber(type === "frozen" ? getFrozenValue(
|
|
23
|
+
if (!existing) subscriber(type === "frozen" ? getFrozenValue(state.value) : peekSignalValue.call(this, SUBSCRIPTION_TYPES_COPY.has(type)), subscription);
|
|
21
24
|
return subscription;
|
|
22
25
|
}
|
|
23
26
|
function subscribeToReadonly(subscriber) {
|
|
24
|
-
|
|
27
|
+
const state = this[SYMBOL_READONLY];
|
|
28
|
+
if (!state.active) throw new Error(MESSAGE_DEACTIVATED_SUBSCRIPTION);
|
|
29
|
+
const subscription = subscribeToReactive.call(this, this.frozen ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_READONLY, subscriber);
|
|
30
|
+
state.subscriptions ??= /* @__PURE__ */ new Set();
|
|
31
|
+
for (const existing of state.subscriptions) if (!existing.active) state.subscriptions.delete(existing);
|
|
32
|
+
state.subscriptions.add(subscription);
|
|
33
|
+
return subscription;
|
|
25
34
|
}
|
|
26
35
|
function subscribeToSignal(subscriber, copy) {
|
|
27
36
|
return subscribeToReactive.call(this, copy === true ? SUBSCRIPTION_TYPE_COPY : SUBSCRIPTION_TYPE_ORIGINAL, subscriber);
|
|
28
37
|
}
|
|
29
|
-
//#endregion
|
|
30
38
|
export { subscribeToProxy, subscribeToReadonly, subscribeToSignal };
|
package/dist/helpers/value.d.mts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { InternalStateful } from "../models.mjs";
|
|
2
|
-
//#region src/helpers/value.d.ts
|
|
1
|
+
import { InternalReadonly, InternalStateful } from "../models.mjs";
|
|
3
2
|
type SetValue = (instance: InternalStateful, value: unknown, notify: boolean) => void;
|
|
4
3
|
export declare function emitValue(instance: InternalStateful, notify?: boolean): void;
|
|
5
4
|
export declare function equalArrays(first: unknown[], second: unknown[], equal?: (first: unknown, second: unknown) => boolean): boolean;
|
|
6
5
|
export declare function getFrozenValue(value: unknown): unknown;
|
|
7
|
-
export declare function getJsonValue(this: InternalStateful): unknown;
|
|
6
|
+
export declare function getJsonValue(this: InternalReadonly | InternalStateful): unknown;
|
|
8
7
|
export declare function getSignalValue(this: InternalStateful): unknown;
|
|
9
|
-
export declare function getStringValue(this: InternalStateful, json?: boolean): string;
|
|
8
|
+
export declare function getStringValue(this: InternalReadonly | InternalStateful, json?: boolean): string;
|
|
10
9
|
export declare function handleSignal(instance: InternalStateful, origin: unknown, setValue: SetValue, onAfter?: () => void, notify?: boolean): void;
|
|
11
10
|
export declare function peekSignalValue(this: InternalStateful | [InternalStateful, unknown], copy?: boolean): unknown;
|
|
12
11
|
export declare function updateSignal(instance: InternalStateful, callback: (value: unknown) => unknown, setValue: (instance: InternalStateful, value: unknown) => void): void;
|
|
13
|
-
|
|
12
|
+
export {};
|
package/dist/helpers/value.mjs
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { ACTIVE, BATCH, SUBSCRIPTION_TYPES, SUBSCRIPTION_TYPES_COPY, SUBSCRIPTION_TYPE_FROZEN, SYMBOL_EFFECT, SYMBOL_STATE } from "../constants.mjs";
|
|
1
|
+
import { ACTIVE, BATCH, MESSAGE_UPDATE_CALLBACK, SUBSCRIPTION_TYPES, SUBSCRIPTION_TYPES_COPY, SUBSCRIPTION_TYPE_FROZEN, SYMBOL_EFFECT, SYMBOL_READONLY, SYMBOL_STATE } from "../constants.mjs";
|
|
2
2
|
import { flushHandlers } from "../batch.mjs";
|
|
3
|
-
import "@oscarpalmer/atoms/result";
|
|
4
3
|
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
5
|
-
import { round } from "@oscarpalmer/atoms/math";
|
|
6
|
-
|
|
4
|
+
import { min, round } from "@oscarpalmer/atoms/math";
|
|
5
|
+
// src/helpers/value.ts
|
|
7
6
|
function emitValue(instance, notify) {
|
|
8
7
|
const state = instance[SYMBOL_STATE];
|
|
9
|
-
if (state.computeds != null && state.computeds.size > 0) for (const computed of state.computeds) computed.dirty = true;
|
|
10
|
-
|
|
8
|
+
if (state.computeds != null && state.computeds.size > 0) for (const computed of state.computeds) if (computed.instance.active) computed.dirty = true;
|
|
9
|
+
else state.computeds.delete(computed);
|
|
10
|
+
if (state.effects != null && state.effects.size > 0) for (const effect of state.effects) if (effect.active) BATCH.handlers.set(effect, effect);
|
|
11
|
+
else state.effects.delete(effect);
|
|
11
12
|
if (notify ?? false) {
|
|
12
13
|
const mapped = instance[SYMBOL_STATE].mapped;
|
|
13
14
|
for (const [, item] of mapped) {
|
|
14
|
-
const
|
|
15
|
-
BATCH.handlers.set(
|
|
15
|
+
const { instance } = item[SYMBOL_EFFECT];
|
|
16
|
+
BATCH.handlers.set(instance, instance);
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
for (const type of SUBSCRIPTION_TYPES) {
|
|
@@ -34,7 +35,7 @@ function equalArrays(first, second, equal) {
|
|
|
34
35
|
let offset = 0;
|
|
35
36
|
if (length >= 100) {
|
|
36
37
|
offset = round(length / 10);
|
|
37
|
-
offset = offset
|
|
38
|
+
offset = min([offset, 25]);
|
|
38
39
|
for (let index = 0; index < offset; index += 1) if (!(eq(first[index], second[index]) && eq(first[length - index - 1], second[length - index - 1]))) return false;
|
|
39
40
|
}
|
|
40
41
|
const end = length - offset;
|
|
@@ -48,10 +49,12 @@ function getFrozenValue(value) {
|
|
|
48
49
|
return frozen;
|
|
49
50
|
}
|
|
50
51
|
function getJsonValue() {
|
|
52
|
+
if (SYMBOL_READONLY in this && !this[SYMBOL_READONLY].active) return this[SYMBOL_READONLY].value;
|
|
51
53
|
return this[SYMBOL_STATE].value;
|
|
52
54
|
}
|
|
53
55
|
function getSignalValue() {
|
|
54
56
|
const state = this[SYMBOL_STATE];
|
|
57
|
+
if (!state.active) return state.value;
|
|
55
58
|
if (ACTIVE.computed != null) {
|
|
56
59
|
state.computeds ??= /* @__PURE__ */ new Set();
|
|
57
60
|
state.computeds.add(ACTIVE.computed);
|
|
@@ -63,10 +66,13 @@ function getSignalValue() {
|
|
|
63
66
|
return state.value;
|
|
64
67
|
}
|
|
65
68
|
function getStringValue(json) {
|
|
66
|
-
|
|
69
|
+
let { value } = this[SYMBOL_STATE];
|
|
70
|
+
if (SYMBOL_READONLY in this && !this[SYMBOL_READONLY].active) value = this[SYMBOL_READONLY].value;
|
|
71
|
+
return json === true ? JSON.stringify(value) : String(value);
|
|
67
72
|
}
|
|
68
73
|
function handleSignal(instance, origin, setValue, onAfter, notify) {
|
|
69
74
|
const state = instance[SYMBOL_STATE];
|
|
75
|
+
if (!state.active) return;
|
|
70
76
|
try {
|
|
71
77
|
let actual = typeof origin === "function" ? origin() : origin;
|
|
72
78
|
if (actual instanceof Promise) {
|
|
@@ -92,8 +98,7 @@ function peekSignalValue(copy) {
|
|
|
92
98
|
return peeked;
|
|
93
99
|
}
|
|
94
100
|
function updateSignal(instance, callback, setValue) {
|
|
95
|
-
if (typeof callback !== "function") throw new TypeError(
|
|
96
|
-
handleSignal(instance, callback(instance[SYMBOL_STATE].value), setValue);
|
|
101
|
+
if (typeof callback !== "function") throw new TypeError(MESSAGE_UPDATE_CALLBACK);
|
|
102
|
+
if (instance[SYMBOL_STATE].active) handleSignal(instance, callback(instance[SYMBOL_STATE].value), setValue);
|
|
97
103
|
}
|
|
98
|
-
//#endregion
|
|
99
104
|
export { emitValue, equalArrays, getFrozenValue, getJsonValue, getSignalValue, getStringValue, handleSignal, peekSignalValue, updateSignal };
|