@oscarpalmer/mora 0.12.0 → 0.14.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.cjs +2 -2
- package/dist/batch.js +1 -1
- package/dist/effect.cjs +2 -1
- package/dist/effect.js +2 -1
- package/dist/helpers/emit.cjs +42 -0
- package/dist/helpers/emit.js +42 -0
- package/dist/helpers/is.cjs +34 -0
- package/dist/helpers/is.js +34 -0
- package/dist/helpers/value.cjs +22 -0
- package/dist/helpers/value.js +22 -0
- package/dist/index.cjs +12 -9
- package/dist/index.js +6 -3
- package/dist/mora.full.js +214 -55
- package/dist/value/array.cjs +108 -0
- package/dist/value/array.js +108 -0
- package/dist/{computed.cjs → value/computed.cjs} +6 -5
- package/dist/{computed.js → value/computed.js} +4 -3
- package/dist/{reactive.cjs → value/reactive.cjs} +13 -1
- package/dist/{reactive.js → value/reactive.js} +13 -1
- package/dist/value/signal.cjs +33 -0
- package/dist/value/signal.js +33 -0
- package/package.json +1 -1
- package/src/batch.ts +1 -1
- package/src/effect.ts +12 -11
- package/src/helpers/emit.ts +52 -0
- package/src/helpers/is.ts +56 -0
- package/src/helpers/value.ts +27 -0
- package/src/index.ts +11 -5
- package/src/subscription.ts +1 -1
- package/src/value/array.ts +170 -0
- package/src/{computed.ts → value/computed.ts} +4 -3
- package/src/{reactive.ts → value/reactive.ts} +17 -3
- package/src/value/signal.ts +37 -0
- package/types/batch.d.cts +8 -0
- package/types/{is.d.cts → helpers/emit.d.cts} +10 -28
- package/types/helpers/emit.d.ts +3 -0
- package/types/helpers/is.d.cts +133 -0
- package/types/helpers/is.d.ts +26 -0
- package/types/helpers/value.d.cts +63 -0
- package/types/helpers/value.d.ts +3 -0
- package/types/index.d.cts +63 -8
- package/types/index.d.ts +5 -4
- package/types/subscription.d.cts +8 -0
- package/types/subscription.d.ts +1 -1
- package/types/value/array.d.cts +101 -0
- package/types/value/array.d.ts +41 -0
- package/types/{computed.d.cts → value/computed.d.cts} +8 -0
- package/types/{computed.d.ts → value/computed.d.ts} +1 -1
- package/types/{reactive.d.cts → value/reactive.d.cts} +8 -0
- package/types/{reactive.d.ts → value/reactive.d.ts} +10 -2
- package/types/{signal.d.cts → value/signal.d.cts} +11 -0
- package/types/{signal.d.ts → value/signal.d.ts} +3 -0
- package/dist/is.cjs +0 -21
- package/dist/is.js +0 -21
- package/dist/signal.cjs +0 -55
- package/dist/signal.js +0 -55
- package/src/is.ts +0 -39
- package/src/signal.ts +0 -63
- package/types/is.d.ts +0 -17
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __typeError = (msg) => {
|
|
3
|
+
throw TypeError(msg);
|
|
4
|
+
};
|
|
5
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
6
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
7
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
8
|
+
var _size;
|
|
9
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
const helpers_emit = require("../helpers/emit.cjs");
|
|
11
|
+
const helpers_is = require("../helpers/is.cjs");
|
|
12
|
+
const helpers_value = require("../helpers/value.cjs");
|
|
13
|
+
const value_reactive = require("./reactive.cjs");
|
|
14
|
+
const value_signal = require("./signal.cjs");
|
|
15
|
+
class ReactiveArray extends value_reactive.Reactive {
|
|
16
|
+
constructor(value) {
|
|
17
|
+
super(
|
|
18
|
+
helpers_is.arrayName,
|
|
19
|
+
new Proxy(value, {
|
|
20
|
+
get: (target, property) => updateMethods.has(property) ? updateArray(property, target, this.state, __privateGet(this, _size)) : Reflect.get(target, property),
|
|
21
|
+
set: (target, property, value2) => setValue(target, property, value2, this.state, __privateGet(this, _size))
|
|
22
|
+
})
|
|
23
|
+
);
|
|
24
|
+
__privateAdd(this, _size, value_signal.signal(0));
|
|
25
|
+
__privateGet(this, _size).set(value.length);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The length of the array
|
|
29
|
+
*/
|
|
30
|
+
get length() {
|
|
31
|
+
return __privateGet(this, _size).get();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Set the length of the array
|
|
35
|
+
*/
|
|
36
|
+
set length(value) {
|
|
37
|
+
if (typeof value === "number" && value >= 0 && value !== this.state.value.length) {
|
|
38
|
+
this.get().length = value;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* @inheritdoc
|
|
43
|
+
*/
|
|
44
|
+
get() {
|
|
45
|
+
return helpers_value.getValue(this.state);
|
|
46
|
+
}
|
|
47
|
+
peek(length) {
|
|
48
|
+
return length === true ? __privateGet(this, _size).peek() : [...this.state.value];
|
|
49
|
+
}
|
|
50
|
+
set(first, second) {
|
|
51
|
+
if (Array.isArray(first)) {
|
|
52
|
+
this.state.value.splice(0, this.state.value.length, ...first);
|
|
53
|
+
} else if (first === "length") {
|
|
54
|
+
this.length = second;
|
|
55
|
+
} else if (typeof first === "number") {
|
|
56
|
+
this.state.value[first] = second;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
_size = new WeakMap();
|
|
61
|
+
function array(value) {
|
|
62
|
+
return new ReactiveArray(Array.isArray(value) ? value : []);
|
|
63
|
+
}
|
|
64
|
+
function setValue(target, property, value, state, length) {
|
|
65
|
+
const isIndex = !Number.isNaN(Number(property));
|
|
66
|
+
const isLength = property === "length";
|
|
67
|
+
if (!isIndex && !isLength) {
|
|
68
|
+
return Reflect.set(target, property, value);
|
|
69
|
+
}
|
|
70
|
+
const previous = Reflect.get(target, property);
|
|
71
|
+
if (!Object.is(previous, value)) {
|
|
72
|
+
Reflect.set(target, property, value);
|
|
73
|
+
helpers_emit.emitValue(state);
|
|
74
|
+
length.set(target.length);
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
function updateArray(type, array2, state, length) {
|
|
79
|
+
const affectsLength = lengthAffectingMethods.has(type);
|
|
80
|
+
const previousArray = affectsLength ? [] : [...array2];
|
|
81
|
+
const previousLength = array2.length;
|
|
82
|
+
return (...args) => {
|
|
83
|
+
const result = array2[type](
|
|
84
|
+
...args
|
|
85
|
+
);
|
|
86
|
+
if (affectsLength ? array2.length !== previousLength : helpers_emit.emitArrayChanges(previousArray, array2)) {
|
|
87
|
+
helpers_emit.emitValue(state);
|
|
88
|
+
length.set(array2.length);
|
|
89
|
+
}
|
|
90
|
+
return result;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const lengthAffectingMethods = /* @__PURE__ */ new Set([
|
|
94
|
+
"pop",
|
|
95
|
+
"push",
|
|
96
|
+
"shift",
|
|
97
|
+
"unshift"
|
|
98
|
+
]);
|
|
99
|
+
const updateMethods = /* @__PURE__ */ new Set([
|
|
100
|
+
...lengthAffectingMethods,
|
|
101
|
+
"copyWithin",
|
|
102
|
+
"fill",
|
|
103
|
+
"reverse",
|
|
104
|
+
"sort",
|
|
105
|
+
"splice"
|
|
106
|
+
]);
|
|
107
|
+
exports.ReactiveArray = ReactiveArray;
|
|
108
|
+
exports.array = array;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
var __typeError = (msg) => {
|
|
2
|
+
throw TypeError(msg);
|
|
3
|
+
};
|
|
4
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
5
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
6
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
7
|
+
var _size;
|
|
8
|
+
import { emitValue, emitArrayChanges } from "../helpers/emit.js";
|
|
9
|
+
import { arrayName } from "../helpers/is.js";
|
|
10
|
+
import { getValue } from "../helpers/value.js";
|
|
11
|
+
import { Reactive } from "./reactive.js";
|
|
12
|
+
import { signal } from "./signal.js";
|
|
13
|
+
class ReactiveArray extends Reactive {
|
|
14
|
+
constructor(value) {
|
|
15
|
+
super(
|
|
16
|
+
arrayName,
|
|
17
|
+
new Proxy(value, {
|
|
18
|
+
get: (target, property) => updateMethods.has(property) ? updateArray(property, target, this.state, __privateGet(this, _size)) : Reflect.get(target, property),
|
|
19
|
+
set: (target, property, value2) => setValue(target, property, value2, this.state, __privateGet(this, _size))
|
|
20
|
+
})
|
|
21
|
+
);
|
|
22
|
+
__privateAdd(this, _size, signal(0));
|
|
23
|
+
__privateGet(this, _size).set(value.length);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The length of the array
|
|
27
|
+
*/
|
|
28
|
+
get length() {
|
|
29
|
+
return __privateGet(this, _size).get();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Set the length of the array
|
|
33
|
+
*/
|
|
34
|
+
set length(value) {
|
|
35
|
+
if (typeof value === "number" && value >= 0 && value !== this.state.value.length) {
|
|
36
|
+
this.get().length = value;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* @inheritdoc
|
|
41
|
+
*/
|
|
42
|
+
get() {
|
|
43
|
+
return getValue(this.state);
|
|
44
|
+
}
|
|
45
|
+
peek(length) {
|
|
46
|
+
return length === true ? __privateGet(this, _size).peek() : [...this.state.value];
|
|
47
|
+
}
|
|
48
|
+
set(first, second) {
|
|
49
|
+
if (Array.isArray(first)) {
|
|
50
|
+
this.state.value.splice(0, this.state.value.length, ...first);
|
|
51
|
+
} else if (first === "length") {
|
|
52
|
+
this.length = second;
|
|
53
|
+
} else if (typeof first === "number") {
|
|
54
|
+
this.state.value[first] = second;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
_size = new WeakMap();
|
|
59
|
+
function array(value) {
|
|
60
|
+
return new ReactiveArray(Array.isArray(value) ? value : []);
|
|
61
|
+
}
|
|
62
|
+
function setValue(target, property, value, state, length) {
|
|
63
|
+
const isIndex = !Number.isNaN(Number(property));
|
|
64
|
+
const isLength = property === "length";
|
|
65
|
+
if (!isIndex && !isLength) {
|
|
66
|
+
return Reflect.set(target, property, value);
|
|
67
|
+
}
|
|
68
|
+
const previous = Reflect.get(target, property);
|
|
69
|
+
if (!Object.is(previous, value)) {
|
|
70
|
+
Reflect.set(target, property, value);
|
|
71
|
+
emitValue(state);
|
|
72
|
+
length.set(target.length);
|
|
73
|
+
}
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
function updateArray(type, array2, state, length) {
|
|
77
|
+
const affectsLength = lengthAffectingMethods.has(type);
|
|
78
|
+
const previousArray = affectsLength ? [] : [...array2];
|
|
79
|
+
const previousLength = array2.length;
|
|
80
|
+
return (...args) => {
|
|
81
|
+
const result = array2[type](
|
|
82
|
+
...args
|
|
83
|
+
);
|
|
84
|
+
if (affectsLength ? array2.length !== previousLength : emitArrayChanges(previousArray, array2)) {
|
|
85
|
+
emitValue(state);
|
|
86
|
+
length.set(array2.length);
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const lengthAffectingMethods = /* @__PURE__ */ new Set([
|
|
92
|
+
"pop",
|
|
93
|
+
"push",
|
|
94
|
+
"shift",
|
|
95
|
+
"unshift"
|
|
96
|
+
]);
|
|
97
|
+
const updateMethods = /* @__PURE__ */ new Set([
|
|
98
|
+
...lengthAffectingMethods,
|
|
99
|
+
"copyWithin",
|
|
100
|
+
"fill",
|
|
101
|
+
"reverse",
|
|
102
|
+
"sort",
|
|
103
|
+
"splice"
|
|
104
|
+
]);
|
|
105
|
+
export {
|
|
106
|
+
ReactiveArray,
|
|
107
|
+
array
|
|
108
|
+
};
|
|
@@ -3,13 +3,14 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
6
|
-
const batch = require("
|
|
7
|
-
const effect = require("
|
|
8
|
-
const
|
|
6
|
+
const batch = require("../batch.cjs");
|
|
7
|
+
const effect = require("../effect.cjs");
|
|
8
|
+
const helpers_is = require("../helpers/is.cjs");
|
|
9
|
+
const value_reactive = require("./reactive.cjs");
|
|
9
10
|
exports.activeComputed = void 0;
|
|
10
|
-
class Computed extends
|
|
11
|
+
class Computed extends value_reactive.Reactive {
|
|
11
12
|
constructor(callback) {
|
|
12
|
-
super(
|
|
13
|
+
super(helpers_is.computedName, void 0);
|
|
13
14
|
__publicField(this, "effect", {
|
|
14
15
|
dirty: true,
|
|
15
16
|
instance: void 0
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
import { batchedHandlers, batchDepth } from "
|
|
5
|
-
import { effect, activeEffect, runEffect } from "
|
|
4
|
+
import { batchedHandlers, batchDepth } from "../batch.js";
|
|
5
|
+
import { effect, activeEffect, runEffect } from "../effect.js";
|
|
6
|
+
import { computedName } from "../helpers/is.js";
|
|
6
7
|
import { Reactive } from "./reactive.js";
|
|
7
8
|
let activeComputed;
|
|
8
9
|
class Computed extends Reactive {
|
|
9
10
|
constructor(callback) {
|
|
10
|
-
super(
|
|
11
|
+
super(computedName, void 0);
|
|
11
12
|
__publicField(this, "effect", {
|
|
12
13
|
dirty: true,
|
|
13
14
|
instance: void 0
|
|
@@ -3,7 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
6
|
-
const subscription = require("
|
|
6
|
+
const subscription = require("../subscription.cjs");
|
|
7
7
|
class Reactive {
|
|
8
8
|
constructor(name, value) {
|
|
9
9
|
__publicField(this, "state", {
|
|
@@ -29,6 +29,18 @@ class Reactive {
|
|
|
29
29
|
subscribe(callback) {
|
|
30
30
|
return subscription.subscribe(this.state, callback);
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* JSON representation of the value
|
|
34
|
+
*/
|
|
35
|
+
toJSON() {
|
|
36
|
+
return this.get();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* String representation of the value
|
|
40
|
+
*/
|
|
41
|
+
toString() {
|
|
42
|
+
return String(this.get());
|
|
43
|
+
}
|
|
32
44
|
/**
|
|
33
45
|
* Unsubscribe from changes
|
|
34
46
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
import { subscribe, unsubscribe } from "
|
|
4
|
+
import { subscribe, unsubscribe } from "../subscription.js";
|
|
5
5
|
class Reactive {
|
|
6
6
|
constructor(name, value) {
|
|
7
7
|
__publicField(this, "state", {
|
|
@@ -27,6 +27,18 @@ class Reactive {
|
|
|
27
27
|
subscribe(callback) {
|
|
28
28
|
return subscribe(this.state, callback);
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* JSON representation of the value
|
|
32
|
+
*/
|
|
33
|
+
toJSON() {
|
|
34
|
+
return this.get();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* String representation of the value
|
|
38
|
+
*/
|
|
39
|
+
toString() {
|
|
40
|
+
return String(this.get());
|
|
41
|
+
}
|
|
30
42
|
/**
|
|
31
43
|
* Unsubscribe from changes
|
|
32
44
|
*/
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const helpers_is = require("../helpers/is.cjs");
|
|
4
|
+
const helpers_value = require("../helpers/value.cjs");
|
|
5
|
+
const value_reactive = require("./reactive.cjs");
|
|
6
|
+
class Signal extends value_reactive.Reactive {
|
|
7
|
+
constructor(value) {
|
|
8
|
+
super(helpers_is.signalName, value);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* @inheritdoc
|
|
12
|
+
*/
|
|
13
|
+
get() {
|
|
14
|
+
return helpers_value.getValue(this.state);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Set the value
|
|
18
|
+
*/
|
|
19
|
+
set(value) {
|
|
20
|
+
helpers_value.setValue(this.state, value);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Update the value
|
|
24
|
+
*/
|
|
25
|
+
update(callback) {
|
|
26
|
+
this.set(callback(this.state.value));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function signal(value) {
|
|
30
|
+
return new Signal(value);
|
|
31
|
+
}
|
|
32
|
+
exports.Signal = Signal;
|
|
33
|
+
exports.signal = signal;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { signalName } from "../helpers/is.js";
|
|
2
|
+
import { getValue, setValue } from "../helpers/value.js";
|
|
3
|
+
import { Reactive } from "./reactive.js";
|
|
4
|
+
class Signal extends Reactive {
|
|
5
|
+
constructor(value) {
|
|
6
|
+
super(signalName, value);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* @inheritdoc
|
|
10
|
+
*/
|
|
11
|
+
get() {
|
|
12
|
+
return getValue(this.state);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Set the value
|
|
16
|
+
*/
|
|
17
|
+
set(value) {
|
|
18
|
+
setValue(this.state, value);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Update the value
|
|
22
|
+
*/
|
|
23
|
+
update(callback) {
|
|
24
|
+
this.set(callback(this.state.value));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function signal(value) {
|
|
28
|
+
return new Signal(value);
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
Signal,
|
|
32
|
+
signal
|
|
33
|
+
};
|
package/package.json
CHANGED
package/src/batch.ts
CHANGED
package/src/effect.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {GenericCallback} from '@oscarpalmer/atoms/models';
|
|
2
|
+
import {effectName} from './helpers/is';
|
|
2
3
|
|
|
3
4
|
type EffectState = {
|
|
4
5
|
callback: GenericCallback;
|
|
@@ -9,22 +10,22 @@ type InternalEffect = {
|
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
export class Effect {
|
|
12
|
-
|
|
13
|
+
private declare readonly $mora: string;
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
private declare readonly state: EffectState;
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
constructor(callback: GenericCallback) {
|
|
18
|
+
Object.defineProperty(this, '$mora', {
|
|
19
|
+
value: effectName,
|
|
20
|
+
});
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
this.state = {
|
|
23
|
+
callback,
|
|
24
|
+
};
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
}
|
|
26
|
+
runEffect(this);
|
|
27
27
|
}
|
|
28
|
+
}
|
|
28
29
|
|
|
29
30
|
export function runEffect(effect: Effect): void {
|
|
30
31
|
const previousEffect = activeEffect;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {batchDepth, batchedHandlers, flushEffects} from '../batch';
|
|
2
|
+
import type {InternalComputed} from '../value/computed';
|
|
3
|
+
import type {ReactiveState} from '../value/reactive';
|
|
4
|
+
|
|
5
|
+
export function emitArrayChanges(first: unknown[], second: unknown[]): boolean {
|
|
6
|
+
let {length} = first;
|
|
7
|
+
|
|
8
|
+
if (length !== second.length) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let offset = 0;
|
|
13
|
+
|
|
14
|
+
if (length >= 100) {
|
|
15
|
+
offset = Math.round(length / 10);
|
|
16
|
+
offset = offset > 25 ? 25 : offset;
|
|
17
|
+
|
|
18
|
+
for (let index = 0; index < offset; index += 1) {
|
|
19
|
+
if (!Object.is(first[index], second[index])) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
length -= offset;
|
|
26
|
+
|
|
27
|
+
for (let index = offset; index < length; index += 1) {
|
|
28
|
+
if (!Object.is(first[index], second[index])) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function emitValue<Value>(state: ReactiveState<Value>): void {
|
|
37
|
+
for (const computed of state.computeds) {
|
|
38
|
+
(computed as unknown as InternalComputed).effect.dirty = true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
for (const effect of state.effects) {
|
|
42
|
+
batchedHandlers.add(effect);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for (const [, subscription] of state.subscriptions) {
|
|
46
|
+
batchedHandlers.add(subscription as never);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (batchDepth === 0) {
|
|
50
|
+
flushEffects();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type {PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
+
import type {Effect} from '../effect';
|
|
3
|
+
import type {ReactiveArray} from '../value/array';
|
|
4
|
+
import type {Computed} from '../value/computed';
|
|
5
|
+
import type {Reactive} from '../value/reactive';
|
|
6
|
+
import {signal, type Signal} from '../value/signal';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Is the value a reactive array?
|
|
10
|
+
*/
|
|
11
|
+
export function isArray(value: unknown): value is ReactiveArray<unknown> {
|
|
12
|
+
return isMora<ReactiveArray<unknown>>(value, arrayName);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Is the value a computed signal?
|
|
17
|
+
*/
|
|
18
|
+
export function isComputed(value: unknown): value is Computed<unknown> {
|
|
19
|
+
return isMora<Computed<unknown>>(value, computedName);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Is the value an effect?
|
|
24
|
+
*/
|
|
25
|
+
export function isEffect(value: unknown): value is Effect {
|
|
26
|
+
return isMora<Effect>(value, effectName);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function isMora<T>(value: unknown, name: string | Set<string>): value is T {
|
|
30
|
+
return (
|
|
31
|
+
typeof value === 'object' &&
|
|
32
|
+
value != null &&
|
|
33
|
+
'$mora' in value &&
|
|
34
|
+
(typeof name === 'string'
|
|
35
|
+
? (value as PlainObject).$mora === name
|
|
36
|
+
: name.has((value as PlainObject).$mora as never))
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function isReactive(value: unknown): value is Reactive<unknown> {
|
|
41
|
+
return isMora<Reactive<unknown>>(value, reactiveNames);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Is the value a signal?
|
|
46
|
+
*/
|
|
47
|
+
export function isSignal(value: unknown): value is Signal<unknown> {
|
|
48
|
+
return isMora<Signal<unknown>>(value, signalName);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const arrayName = 'array';
|
|
52
|
+
export const computedName = 'computed';
|
|
53
|
+
export const effectName = 'effect';
|
|
54
|
+
export const signalName = 'signal';
|
|
55
|
+
|
|
56
|
+
const reactiveNames = new Set([arrayName, computedName, signalName]);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {activeEffect} from '../effect';
|
|
2
|
+
import {activeComputed} from '../value/computed';
|
|
3
|
+
import type {ReactiveState} from '../value/reactive';
|
|
4
|
+
import {emitValue} from './emit';
|
|
5
|
+
|
|
6
|
+
export function getValue<Value>(state: ReactiveState<Value>): Value {
|
|
7
|
+
if (activeComputed != null) {
|
|
8
|
+
state.computeds.add(activeComputed);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (activeEffect != null) {
|
|
12
|
+
state.effects.add(activeEffect);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return state.value;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function setValue<Value>(
|
|
19
|
+
state: ReactiveState<Value>,
|
|
20
|
+
value: Value,
|
|
21
|
+
): void {
|
|
22
|
+
if (!Object.is(state.value, value)) {
|
|
23
|
+
state.value = value;
|
|
24
|
+
|
|
25
|
+
emitValue(state);
|
|
26
|
+
}
|
|
27
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
export {startBatch, stopBatch} from './batch';
|
|
2
|
-
export {computed, type Computed} from './computed';
|
|
3
2
|
export {effect, type Effect} from './effect';
|
|
4
|
-
export {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
export {
|
|
4
|
+
isArray,
|
|
5
|
+
isComputed,
|
|
6
|
+
isEffect,
|
|
7
|
+
isReactive,
|
|
8
|
+
isSignal,
|
|
9
|
+
} from './helpers/is';
|
|
10
|
+
export {array, type ReactiveArray} from './value/array';
|
|
11
|
+
export {computed, type Computed} from './value/computed';
|
|
12
|
+
export type {Reactive} from './value/reactive';
|
|
13
|
+
export {signal, type Signal} from './value/signal';
|
package/src/subscription.ts
CHANGED