@oscarpalmer/mora 0.7.0 → 0.9.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/README.md +2 -0
- package/dist/computed.cjs +13 -9
- package/dist/computed.js +13 -9
- package/dist/effect.cjs +3 -4
- package/dist/effect.js +3 -4
- package/dist/index.cjs +4 -0
- package/dist/index.js +4 -0
- package/dist/is.cjs +17 -0
- package/dist/is.js +17 -0
- package/dist/mora.full.js +53 -15
- package/dist/signal.cjs +11 -3
- package/dist/signal.js +11 -3
- package/package.json +4 -2
- package/src/computed.ts +50 -50
- package/src/effect.ts +13 -7
- package/src/index.ts +1 -0
- package/src/is.ts +34 -0
- package/src/signal.ts +53 -49
- package/types/computed.d.cts +6 -0
- package/types/computed.d.ts +5 -0
- package/types/effect.d.cts +1 -0
- package/types/effect.d.ts +1 -0
- package/types/index.d.cts +31 -8
- package/types/index.d.ts +1 -0
- package/types/is.d.cts +56 -0
- package/types/is.d.ts +15 -0
- package/types/signal.d.cts +5 -0
- package/types/signal.d.ts +5 -0
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Mora
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@oscarpalmer/mora) [](https://github.com/oscarpalmer/mora/actions/workflows/test.yml)
|
|
4
|
+
|
|
3
5
|
Signals and stuff…
|
|
4
6
|
|
|
5
7
|
## License
|
package/dist/computed.cjs
CHANGED
|
@@ -9,6 +9,9 @@ exports.activeComputed = void 0;
|
|
|
9
9
|
class Computed {
|
|
10
10
|
constructor(callback) {
|
|
11
11
|
__publicField(this, "state");
|
|
12
|
+
Object.defineProperty(this, "$mora", {
|
|
13
|
+
value: "computed"
|
|
14
|
+
});
|
|
12
15
|
this.state = {
|
|
13
16
|
computeds: /* @__PURE__ */ new Set(),
|
|
14
17
|
dirty: true,
|
|
@@ -24,9 +27,8 @@ class Computed {
|
|
|
24
27
|
exports.activeComputed = previousComputed;
|
|
25
28
|
if (!Object.is(this.state.value, value)) {
|
|
26
29
|
this.state.value = value;
|
|
27
|
-
for (const
|
|
28
|
-
|
|
29
|
-
effect.dirtyEffects.add(comp.state.effect);
|
|
30
|
+
for (const computed2 of this.state.computeds) {
|
|
31
|
+
computed2.state.dirty = true;
|
|
30
32
|
}
|
|
31
33
|
for (const effect2 of this.state.effects) {
|
|
32
34
|
effect.dirtyEffects.add(effect2);
|
|
@@ -46,15 +48,17 @@ class Computed {
|
|
|
46
48
|
if (effect.activeEffect != null && effect.activeEffect !== this.state.effect) {
|
|
47
49
|
this.state.effects.add(effect.activeEffect);
|
|
48
50
|
}
|
|
49
|
-
if (this.state.dirty) {
|
|
50
|
-
|
|
51
|
-
effect.runEffect(this.state.effect);
|
|
52
|
-
} else {
|
|
53
|
-
effect.dirtyEffects.add(this.state.effect);
|
|
54
|
-
}
|
|
51
|
+
if (this.state.dirty && batch.batchDepth === 0) {
|
|
52
|
+
effect.runEffect(this.state.effect);
|
|
55
53
|
}
|
|
56
54
|
return this.state.value;
|
|
57
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Get the value _(without reactivity)_
|
|
58
|
+
*/
|
|
59
|
+
peek() {
|
|
60
|
+
return this.state.value;
|
|
61
|
+
}
|
|
58
62
|
}
|
|
59
63
|
function computed(callback) {
|
|
60
64
|
return new Computed(callback);
|
package/dist/computed.js
CHANGED
|
@@ -7,6 +7,9 @@ let activeComputed;
|
|
|
7
7
|
class Computed {
|
|
8
8
|
constructor(callback) {
|
|
9
9
|
__publicField(this, "state");
|
|
10
|
+
Object.defineProperty(this, "$mora", {
|
|
11
|
+
value: "computed"
|
|
12
|
+
});
|
|
10
13
|
this.state = {
|
|
11
14
|
computeds: /* @__PURE__ */ new Set(),
|
|
12
15
|
dirty: true,
|
|
@@ -22,9 +25,8 @@ class Computed {
|
|
|
22
25
|
activeComputed = previousComputed;
|
|
23
26
|
if (!Object.is(this.state.value, value)) {
|
|
24
27
|
this.state.value = value;
|
|
25
|
-
for (const
|
|
26
|
-
|
|
27
|
-
dirtyEffects.add(comp.state.effect);
|
|
28
|
+
for (const computed2 of this.state.computeds) {
|
|
29
|
+
computed2.state.dirty = true;
|
|
28
30
|
}
|
|
29
31
|
for (const effect2 of this.state.effects) {
|
|
30
32
|
dirtyEffects.add(effect2);
|
|
@@ -44,15 +46,17 @@ class Computed {
|
|
|
44
46
|
if (activeEffect != null && activeEffect !== this.state.effect) {
|
|
45
47
|
this.state.effects.add(activeEffect);
|
|
46
48
|
}
|
|
47
|
-
if (this.state.dirty) {
|
|
48
|
-
|
|
49
|
-
runEffect(this.state.effect);
|
|
50
|
-
} else {
|
|
51
|
-
dirtyEffects.add(this.state.effect);
|
|
52
|
-
}
|
|
49
|
+
if (this.state.dirty && batchDepth === 0) {
|
|
50
|
+
runEffect(this.state.effect);
|
|
53
51
|
}
|
|
54
52
|
return this.state.value;
|
|
55
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Get the value _(without reactivity)_
|
|
56
|
+
*/
|
|
57
|
+
peek() {
|
|
58
|
+
return this.state.value;
|
|
59
|
+
}
|
|
56
60
|
}
|
|
57
61
|
function computed(callback) {
|
|
58
62
|
return new Computed(callback);
|
package/dist/effect.cjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
6
3
|
class Effect {
|
|
7
4
|
constructor(callback) {
|
|
8
|
-
|
|
5
|
+
Object.defineProperty(this, "$mora", {
|
|
6
|
+
value: "effect"
|
|
7
|
+
});
|
|
9
8
|
this.state = {
|
|
10
9
|
callback
|
|
11
10
|
};
|
package/dist/effect.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
1
|
class Effect {
|
|
5
2
|
constructor(callback) {
|
|
6
|
-
|
|
3
|
+
Object.defineProperty(this, "$mora", {
|
|
4
|
+
value: "effect"
|
|
5
|
+
});
|
|
7
6
|
this.state = {
|
|
8
7
|
callback
|
|
9
8
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -3,9 +3,13 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const batch = require("./batch.cjs");
|
|
4
4
|
const computed = require("./computed.cjs");
|
|
5
5
|
const effect = require("./effect.cjs");
|
|
6
|
+
const is = require("./is.cjs");
|
|
6
7
|
const signal = require("./signal.cjs");
|
|
7
8
|
exports.startBatch = batch.startBatch;
|
|
8
9
|
exports.stopBatch = batch.stopBatch;
|
|
9
10
|
exports.computed = computed.computed;
|
|
10
11
|
exports.effect = effect.effect;
|
|
12
|
+
exports.isComputed = is.isComputed;
|
|
13
|
+
exports.isEffect = is.isEffect;
|
|
14
|
+
exports.isSignal = is.isSignal;
|
|
11
15
|
exports.signal = signal.signal;
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { startBatch, stopBatch } from "./batch.js";
|
|
2
2
|
import { computed } from "./computed.js";
|
|
3
3
|
import { effect } from "./effect.js";
|
|
4
|
+
import { isComputed, isEffect, isSignal } from "./is.js";
|
|
4
5
|
import { signal } from "./signal.js";
|
|
5
6
|
export {
|
|
6
7
|
computed,
|
|
7
8
|
effect,
|
|
9
|
+
isComputed,
|
|
10
|
+
isEffect,
|
|
11
|
+
isSignal,
|
|
8
12
|
signal,
|
|
9
13
|
startBatch,
|
|
10
14
|
stopBatch
|
package/dist/is.cjs
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
function isComputed(value) {
|
|
4
|
+
return isMora(value, "computed");
|
|
5
|
+
}
|
|
6
|
+
function isEffect(value) {
|
|
7
|
+
return isMora(value, "effect");
|
|
8
|
+
}
|
|
9
|
+
function isMora(value, name) {
|
|
10
|
+
return typeof value === "object" && value != null && "$mora" in value && value.$mora === name;
|
|
11
|
+
}
|
|
12
|
+
function isSignal(value) {
|
|
13
|
+
return isMora(value, "signal");
|
|
14
|
+
}
|
|
15
|
+
exports.isComputed = isComputed;
|
|
16
|
+
exports.isEffect = isEffect;
|
|
17
|
+
exports.isSignal = isSignal;
|
package/dist/is.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function isComputed(value) {
|
|
2
|
+
return isMora(value, "computed");
|
|
3
|
+
}
|
|
4
|
+
function isEffect(value) {
|
|
5
|
+
return isMora(value, "effect");
|
|
6
|
+
}
|
|
7
|
+
function isMora(value, name) {
|
|
8
|
+
return typeof value === "object" && value != null && "$mora" in value && value.$mora === name;
|
|
9
|
+
}
|
|
10
|
+
function isSignal(value) {
|
|
11
|
+
return isMora(value, "signal");
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
isComputed,
|
|
15
|
+
isEffect,
|
|
16
|
+
isSignal
|
|
17
|
+
};
|
package/dist/mora.full.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
class Effect {
|
|
2
|
-
state;
|
|
3
2
|
constructor(callback) {
|
|
3
|
+
Object.defineProperty(this, '$mora', {
|
|
4
|
+
value: 'effect',
|
|
5
|
+
});
|
|
4
6
|
this.state = {
|
|
5
7
|
callback,
|
|
6
8
|
};
|
|
@@ -56,6 +58,9 @@ let activeComputed;
|
|
|
56
58
|
class Computed {
|
|
57
59
|
state;
|
|
58
60
|
constructor(callback) {
|
|
61
|
+
Object.defineProperty(this, '$mora', {
|
|
62
|
+
value: 'computed',
|
|
63
|
+
});
|
|
59
64
|
this.state = {
|
|
60
65
|
computeds: new Set(),
|
|
61
66
|
dirty: true,
|
|
@@ -71,9 +76,8 @@ class Computed {
|
|
|
71
76
|
activeComputed = previousComputed;
|
|
72
77
|
if (!Object.is(this.state.value, value)) {
|
|
73
78
|
this.state.value = value;
|
|
74
|
-
for (const
|
|
75
|
-
|
|
76
|
-
dirtyEffects.add(comp.state.effect);
|
|
79
|
+
for (const computed of this.state.computeds) {
|
|
80
|
+
computed.state.dirty = true;
|
|
77
81
|
}
|
|
78
82
|
for (const effect of this.state.effects) {
|
|
79
83
|
dirtyEffects.add(effect);
|
|
@@ -93,16 +97,17 @@ class Computed {
|
|
|
93
97
|
if (activeEffect != null && activeEffect !== this.state.effect) {
|
|
94
98
|
this.state.effects.add(activeEffect);
|
|
95
99
|
}
|
|
96
|
-
if (this.state.dirty) {
|
|
97
|
-
|
|
98
|
-
runEffect(this.state.effect);
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
dirtyEffects.add(this.state.effect);
|
|
102
|
-
}
|
|
100
|
+
if (this.state.dirty && batchDepth === 0) {
|
|
101
|
+
runEffect(this.state.effect);
|
|
103
102
|
}
|
|
104
103
|
return this.state.value;
|
|
105
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Get the value _(without reactivity)_
|
|
107
|
+
*/
|
|
108
|
+
peek() {
|
|
109
|
+
return this.state.value;
|
|
110
|
+
}
|
|
106
111
|
}
|
|
107
112
|
/**
|
|
108
113
|
* Create a computed value
|
|
@@ -111,9 +116,37 @@ function computed(callback) {
|
|
|
111
116
|
return new Computed(callback);
|
|
112
117
|
}
|
|
113
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Is the value a computed signal?
|
|
121
|
+
*/
|
|
122
|
+
function isComputed(value) {
|
|
123
|
+
return isMora(value, 'computed');
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Is the value an effect?
|
|
127
|
+
*/
|
|
128
|
+
function isEffect(value) {
|
|
129
|
+
return isMora(value, 'effect');
|
|
130
|
+
}
|
|
131
|
+
function isMora(value, name) {
|
|
132
|
+
return (typeof value === 'object' &&
|
|
133
|
+
value != null &&
|
|
134
|
+
'$mora' in value &&
|
|
135
|
+
value.$mora === name);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Is the value a signal?
|
|
139
|
+
*/
|
|
140
|
+
function isSignal(value) {
|
|
141
|
+
return isMora(value, 'signal');
|
|
142
|
+
}
|
|
143
|
+
|
|
114
144
|
class Signal {
|
|
115
145
|
state;
|
|
116
146
|
constructor(value) {
|
|
147
|
+
Object.defineProperty(this, '$mora', {
|
|
148
|
+
value: 'signal',
|
|
149
|
+
});
|
|
117
150
|
this.state = {
|
|
118
151
|
value,
|
|
119
152
|
computeds: new Set(),
|
|
@@ -132,6 +165,12 @@ class Signal {
|
|
|
132
165
|
}
|
|
133
166
|
return this.state.value;
|
|
134
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Get the value _(without reactivity)_
|
|
170
|
+
*/
|
|
171
|
+
peek() {
|
|
172
|
+
return this.state.value;
|
|
173
|
+
}
|
|
135
174
|
/**
|
|
136
175
|
* Set the value
|
|
137
176
|
*/
|
|
@@ -140,9 +179,8 @@ class Signal {
|
|
|
140
179
|
return;
|
|
141
180
|
}
|
|
142
181
|
this.state.value = value;
|
|
143
|
-
for (const
|
|
144
|
-
|
|
145
|
-
dirtyEffects.add(comp.state.effect);
|
|
182
|
+
for (const computed of this.state.computeds) {
|
|
183
|
+
computed.state.dirty = true;
|
|
146
184
|
}
|
|
147
185
|
for (const effect of this.state.effects) {
|
|
148
186
|
dirtyEffects.add(effect);
|
|
@@ -162,4 +200,4 @@ function signal(value) {
|
|
|
162
200
|
return new Signal(value);
|
|
163
201
|
}
|
|
164
202
|
|
|
165
|
-
export { computed, effect, signal, startBatch, stopBatch };
|
|
203
|
+
export { computed, effect, isComputed, isEffect, isSignal, signal, startBatch, stopBatch };
|
package/dist/signal.cjs
CHANGED
|
@@ -9,6 +9,9 @@ const effect = require("./effect.cjs");
|
|
|
9
9
|
class Signal {
|
|
10
10
|
constructor(value) {
|
|
11
11
|
__publicField(this, "state");
|
|
12
|
+
Object.defineProperty(this, "$mora", {
|
|
13
|
+
value: "signal"
|
|
14
|
+
});
|
|
12
15
|
this.state = {
|
|
13
16
|
value,
|
|
14
17
|
computeds: /* @__PURE__ */ new Set(),
|
|
@@ -27,6 +30,12 @@ class Signal {
|
|
|
27
30
|
}
|
|
28
31
|
return this.state.value;
|
|
29
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Get the value _(without reactivity)_
|
|
35
|
+
*/
|
|
36
|
+
peek() {
|
|
37
|
+
return this.state.value;
|
|
38
|
+
}
|
|
30
39
|
/**
|
|
31
40
|
* Set the value
|
|
32
41
|
*/
|
|
@@ -35,9 +44,8 @@ class Signal {
|
|
|
35
44
|
return;
|
|
36
45
|
}
|
|
37
46
|
this.state.value = value;
|
|
38
|
-
for (const
|
|
39
|
-
|
|
40
|
-
effect.dirtyEffects.add(comp.state.effect);
|
|
47
|
+
for (const computed2 of this.state.computeds) {
|
|
48
|
+
computed2.state.dirty = true;
|
|
41
49
|
}
|
|
42
50
|
for (const effect$1 of this.state.effects) {
|
|
43
51
|
effect.dirtyEffects.add(effect$1);
|
package/dist/signal.js
CHANGED
|
@@ -7,6 +7,9 @@ import { activeEffect, dirtyEffects } from "./effect.js";
|
|
|
7
7
|
class Signal {
|
|
8
8
|
constructor(value) {
|
|
9
9
|
__publicField(this, "state");
|
|
10
|
+
Object.defineProperty(this, "$mora", {
|
|
11
|
+
value: "signal"
|
|
12
|
+
});
|
|
10
13
|
this.state = {
|
|
11
14
|
value,
|
|
12
15
|
computeds: /* @__PURE__ */ new Set(),
|
|
@@ -25,6 +28,12 @@ class Signal {
|
|
|
25
28
|
}
|
|
26
29
|
return this.state.value;
|
|
27
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the value _(without reactivity)_
|
|
33
|
+
*/
|
|
34
|
+
peek() {
|
|
35
|
+
return this.state.value;
|
|
36
|
+
}
|
|
28
37
|
/**
|
|
29
38
|
* Set the value
|
|
30
39
|
*/
|
|
@@ -33,9 +42,8 @@ class Signal {
|
|
|
33
42
|
return;
|
|
34
43
|
}
|
|
35
44
|
this.state.value = value;
|
|
36
|
-
for (const
|
|
37
|
-
|
|
38
|
-
dirtyEffects.add(comp.state.effect);
|
|
45
|
+
for (const computed of this.state.computeds) {
|
|
46
|
+
computed.state.dirty = true;
|
|
39
47
|
}
|
|
40
48
|
for (const effect of this.state.effects) {
|
|
41
49
|
dirtyEffects.add(effect);
|
package/package.json
CHANGED
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
"name": "Oscar Palmér",
|
|
4
4
|
"url": "https://oscarpalmer.se"
|
|
5
5
|
},
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@oscarpalmer/atoms": "^0.100"
|
|
8
|
+
},
|
|
6
9
|
"description": "Signals and stuff…",
|
|
7
10
|
"devDependencies": {
|
|
8
11
|
"@biomejs/biome": "^1.9",
|
|
9
|
-
"@oscarpalmer/atoms": "^0.100",
|
|
10
12
|
"@rollup/plugin-node-resolve": "^16",
|
|
11
13
|
"@rollup/plugin-typescript": "^12.1",
|
|
12
14
|
"@types/node": "^22.15",
|
|
@@ -52,5 +54,5 @@
|
|
|
52
54
|
},
|
|
53
55
|
"type": "module",
|
|
54
56
|
"types": "./types/index.d.ts",
|
|
55
|
-
"version": "0.
|
|
57
|
+
"version": "0.9.0"
|
|
56
58
|
}
|
package/src/computed.ts
CHANGED
|
@@ -22,76 +22,76 @@ export type InternalComputed = {
|
|
|
22
22
|
export let activeComputed: Computed<unknown> | undefined;
|
|
23
23
|
|
|
24
24
|
export class Computed<Value> {
|
|
25
|
-
|
|
25
|
+
private declare readonly $mora: string;
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
this.state = {
|
|
29
|
-
computeds: new Set(),
|
|
30
|
-
dirty: true,
|
|
31
|
-
effect: undefined as never,
|
|
32
|
-
effects: new Set(),
|
|
33
|
-
value: undefined as never,
|
|
34
|
-
};
|
|
27
|
+
private readonly state: ComputedState<Value>;
|
|
35
28
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
constructor(callback: () => Value) {
|
|
30
|
+
Object.defineProperty(this, '$mora', {
|
|
31
|
+
value: 'computed',
|
|
32
|
+
});
|
|
39
33
|
|
|
40
|
-
|
|
34
|
+
this.state = {
|
|
35
|
+
computeds: new Set(),
|
|
36
|
+
dirty: true,
|
|
37
|
+
effect: undefined as never,
|
|
38
|
+
effects: new Set(),
|
|
39
|
+
value: undefined as never,
|
|
40
|
+
};
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
this.state.effect = effect(() => {
|
|
43
|
+
if (this.state.dirty) {
|
|
44
|
+
const previousComputed = activeComputed;
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
activeComputed = this;
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
this.state.value = value;
|
|
48
|
+
const value = callback();
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
computed.state.dirty = true;
|
|
50
|
+
activeComputed = previousComputed;
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
if (!Object.is(this.state.value, value)) {
|
|
53
|
+
this.state.value = value;
|
|
54
|
+
|
|
55
|
+
for (const computed of this.state.computeds) {
|
|
56
|
+
computed.state.dirty = true;
|
|
57
|
+
}
|
|
54
58
|
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
for (const effect of this.state.effects) {
|
|
60
|
+
dirtyEffects.add(effect);
|
|
61
|
+
}
|
|
57
62
|
}
|
|
63
|
+
|
|
64
|
+
this.state.dirty = false;
|
|
58
65
|
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
59
68
|
|
|
60
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Get the value
|
|
71
|
+
*/
|
|
72
|
+
get(): Value {
|
|
73
|
+
if (activeComputed != null && activeComputed !== this) {
|
|
74
|
+
this.state.computeds.add(activeComputed);
|
|
61
75
|
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Get the value
|
|
67
|
-
*/
|
|
68
|
-
get(): Value {
|
|
69
|
-
if (activeComputed != null && activeComputed !== this) {
|
|
70
|
-
this.state.computeds.add(activeComputed);
|
|
71
|
-
}
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
if (activeEffect != null && activeEffect !== this.state.effect) {
|
|
78
|
+
this.state.effects.add(activeEffect);
|
|
79
|
+
}
|
|
76
80
|
|
|
77
|
-
|
|
78
|
-
if (batchDepth === 0) {
|
|
81
|
+
if (this.state.dirty && batchDepth === 0) {
|
|
79
82
|
runEffect(this.state.effect);
|
|
80
|
-
} else {
|
|
81
|
-
dirtyEffects.add(this.state.effect);
|
|
82
83
|
}
|
|
83
|
-
}
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
return this.state.value;
|
|
86
|
+
}
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Get the value _(without reactivity)_
|
|
90
|
+
*/
|
|
91
|
+
peek(): Value {
|
|
92
|
+
return this.state.value;
|
|
93
|
+
}
|
|
93
94
|
}
|
|
94
|
-
}
|
|
95
95
|
|
|
96
96
|
/**
|
|
97
97
|
* Create a computed value
|
package/src/effect.ts
CHANGED
|
@@ -9,16 +9,22 @@ type InternalEffect = {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export class Effect {
|
|
12
|
-
|
|
12
|
+
private declare readonly $mora: string;
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
this.state = {
|
|
16
|
-
callback,
|
|
17
|
-
};
|
|
14
|
+
private declare readonly state: EffectState;
|
|
18
15
|
|
|
19
|
-
|
|
16
|
+
constructor(callback: GenericCallback) {
|
|
17
|
+
Object.defineProperty(this, '$mora', {
|
|
18
|
+
value: 'effect',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
this.state = {
|
|
22
|
+
callback,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
runEffect(this);
|
|
26
|
+
}
|
|
20
27
|
}
|
|
21
|
-
}
|
|
22
28
|
|
|
23
29
|
export function runEffect(effect: Effect): void {
|
|
24
30
|
const previousEffect = activeEffect;
|
package/src/index.ts
CHANGED
package/src/is.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type {PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
+
import type {Computed} from './computed';
|
|
3
|
+
import type {Effect} from './effect';
|
|
4
|
+
import type {Signal} from './signal';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Is the value a computed signal?
|
|
8
|
+
*/
|
|
9
|
+
export function isComputed(value: unknown): value is Computed<unknown> {
|
|
10
|
+
return isMora<Computed<unknown>>(value, 'computed');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Is the value an effect?
|
|
15
|
+
*/
|
|
16
|
+
export function isEffect(value: unknown): value is Effect {
|
|
17
|
+
return isMora<Effect>(value, 'effect');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function isMora<T>(value: unknown, name: string): value is T {
|
|
21
|
+
return (
|
|
22
|
+
typeof value === 'object' &&
|
|
23
|
+
value != null &&
|
|
24
|
+
'$mora' in value &&
|
|
25
|
+
(value as PlainObject).$mora === name
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Is the value a signal?
|
|
31
|
+
*/
|
|
32
|
+
export function isSignal(value: unknown): value is Signal<unknown> {
|
|
33
|
+
return isMora<Signal<unknown>>(value, 'signal');
|
|
34
|
+
}
|
package/src/signal.ts
CHANGED
|
@@ -9,70 +9,74 @@ type SignalState<Value> = {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export class Signal<Value> {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
constructor(value: Value) {
|
|
15
|
-
this.state = {
|
|
16
|
-
value,
|
|
17
|
-
computeds: new Set(),
|
|
18
|
-
effects: new Set(),
|
|
19
|
-
};
|
|
20
|
-
}
|
|
12
|
+
private declare readonly $mora: string;
|
|
21
13
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
14
|
+
private readonly state: SignalState<Value>;
|
|
15
|
+
|
|
16
|
+
constructor(value: Value) {
|
|
17
|
+
Object.defineProperty(this, '$mora', {
|
|
18
|
+
value: 'signal',
|
|
19
|
+
});
|
|
29
20
|
|
|
30
|
-
|
|
31
|
-
|
|
21
|
+
this.state = {
|
|
22
|
+
value,
|
|
23
|
+
computeds: new Set(),
|
|
24
|
+
effects: new Set(),
|
|
25
|
+
};
|
|
32
26
|
}
|
|
33
27
|
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Get the value
|
|
30
|
+
*/
|
|
31
|
+
get(): Value {
|
|
32
|
+
if (activeComputed != null) {
|
|
33
|
+
this.state.computeds.add(activeComputed);
|
|
34
|
+
}
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
if (activeEffect != null) {
|
|
37
|
+
this.state.effects.add(activeEffect);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return this.state.value;
|
|
41
|
+
}
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return;
|
|
43
|
+
/**
|
|
44
|
+
* Get the value _(without reactivity)_
|
|
45
|
+
*/
|
|
46
|
+
peek(): Value {
|
|
47
|
+
return this.state.value;
|
|
50
48
|
}
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Set the value
|
|
52
|
+
*/
|
|
53
|
+
set(value: Value): void {
|
|
54
|
+
if (Object.is(this.state.value, value)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
53
57
|
|
|
54
|
-
|
|
55
|
-
(computed as unknown as InternalComputed).state.dirty = true;
|
|
58
|
+
this.state.value = value;
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
for (const computed of this.state.computeds) {
|
|
61
|
+
(computed as unknown as InternalComputed).state.dirty = true;
|
|
62
|
+
}
|
|
59
63
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
for (const effect of this.state.effects) {
|
|
65
|
+
dirtyEffects.add(effect);
|
|
66
|
+
}
|
|
63
67
|
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
if (batchDepth === 0) {
|
|
69
|
+
flushEffects();
|
|
70
|
+
}
|
|
66
71
|
}
|
|
67
|
-
}
|
|
68
72
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Update the value
|
|
75
|
+
*/
|
|
76
|
+
update(callback: (value: Value) => Value): void {
|
|
77
|
+
this.set(callback(this.state.value));
|
|
78
|
+
}
|
|
74
79
|
}
|
|
75
|
-
}
|
|
76
80
|
|
|
77
81
|
export function signal<Value>(value: Value): Signal<Value> {
|
|
78
82
|
return new Signal(value);
|
package/types/computed.d.cts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
export type GenericCallback = (...args: any[]) => any;
|
|
4
4
|
declare class Effect {
|
|
5
|
+
private readonly $mora;
|
|
5
6
|
private readonly state;
|
|
6
7
|
constructor(callback: GenericCallback);
|
|
7
8
|
}
|
|
@@ -17,12 +18,17 @@ export type InternalComputed = {
|
|
|
17
18
|
};
|
|
18
19
|
export declare let activeComputed: Computed<unknown> | undefined;
|
|
19
20
|
export declare class Computed<Value> {
|
|
21
|
+
private readonly $mora;
|
|
20
22
|
private readonly state;
|
|
21
23
|
constructor(callback: () => Value);
|
|
22
24
|
/**
|
|
23
25
|
* Get the value
|
|
24
26
|
*/
|
|
25
27
|
get(): Value;
|
|
28
|
+
/**
|
|
29
|
+
* Get the value _(without reactivity)_
|
|
30
|
+
*/
|
|
31
|
+
peek(): Value;
|
|
26
32
|
}
|
|
27
33
|
/**
|
|
28
34
|
* Create a computed value
|
package/types/computed.d.ts
CHANGED
|
@@ -11,12 +11,17 @@ export type InternalComputed = {
|
|
|
11
11
|
};
|
|
12
12
|
export declare let activeComputed: Computed<unknown> | undefined;
|
|
13
13
|
export declare class Computed<Value> {
|
|
14
|
+
private readonly $mora;
|
|
14
15
|
private readonly state;
|
|
15
16
|
constructor(callback: () => Value);
|
|
16
17
|
/**
|
|
17
18
|
* Get the value
|
|
18
19
|
*/
|
|
19
20
|
get(): Value;
|
|
21
|
+
/**
|
|
22
|
+
* Get the value _(without reactivity)_
|
|
23
|
+
*/
|
|
24
|
+
peek(): Value;
|
|
20
25
|
}
|
|
21
26
|
/**
|
|
22
27
|
* Create a computed value
|
package/types/effect.d.cts
CHANGED
package/types/effect.d.ts
CHANGED
package/types/index.d.cts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
// Generated by dts-bundle-generator v9.5.1
|
|
2
2
|
|
|
3
3
|
export declare class Signal<Value> {
|
|
4
|
+
private readonly $mora;
|
|
4
5
|
private readonly state;
|
|
5
6
|
constructor(value: Value);
|
|
6
7
|
/**
|
|
7
8
|
* Get the value
|
|
8
9
|
*/
|
|
9
10
|
get(): Value;
|
|
11
|
+
/**
|
|
12
|
+
* Get the value _(without reactivity)_
|
|
13
|
+
*/
|
|
14
|
+
peek(): Value;
|
|
10
15
|
/**
|
|
11
16
|
* Set the value
|
|
12
17
|
*/
|
|
@@ -17,16 +22,9 @@ export declare class Signal<Value> {
|
|
|
17
22
|
update(callback: (value: Value) => Value): void;
|
|
18
23
|
}
|
|
19
24
|
export declare function signal<Value>(value: Value): Signal<Value>;
|
|
20
|
-
/**
|
|
21
|
-
* Start batching effects _(use `stopBatch` to flush and run batched effects)_
|
|
22
|
-
*/
|
|
23
|
-
export declare function startBatch(): void;
|
|
24
|
-
/**
|
|
25
|
-
* Stop batching effects and flush _(run)_ them
|
|
26
|
-
*/
|
|
27
|
-
export declare function stopBatch(): void;
|
|
28
25
|
export type GenericCallback = (...args: any[]) => any;
|
|
29
26
|
export declare class Effect {
|
|
27
|
+
private readonly $mora;
|
|
30
28
|
private readonly state;
|
|
31
29
|
constructor(callback: GenericCallback);
|
|
32
30
|
}
|
|
@@ -35,16 +33,41 @@ export declare class Effect {
|
|
|
35
33
|
*/
|
|
36
34
|
export declare function effect(callback: GenericCallback): Effect;
|
|
37
35
|
export declare class Computed<Value> {
|
|
36
|
+
private readonly $mora;
|
|
38
37
|
private readonly state;
|
|
39
38
|
constructor(callback: () => Value);
|
|
40
39
|
/**
|
|
41
40
|
* Get the value
|
|
42
41
|
*/
|
|
43
42
|
get(): Value;
|
|
43
|
+
/**
|
|
44
|
+
* Get the value _(without reactivity)_
|
|
45
|
+
*/
|
|
46
|
+
peek(): Value;
|
|
44
47
|
}
|
|
45
48
|
/**
|
|
46
49
|
* Create a computed value
|
|
47
50
|
*/
|
|
48
51
|
export declare function computed<Value>(callback: () => Value): Computed<Value>;
|
|
52
|
+
/**
|
|
53
|
+
* Is the value a computed signal?
|
|
54
|
+
*/
|
|
55
|
+
export declare function isComputed(value: unknown): value is Computed<unknown>;
|
|
56
|
+
/**
|
|
57
|
+
* Is the value an effect?
|
|
58
|
+
*/
|
|
59
|
+
export declare function isEffect(value: unknown): value is Effect;
|
|
60
|
+
/**
|
|
61
|
+
* Is the value a signal?
|
|
62
|
+
*/
|
|
63
|
+
export declare function isSignal(value: unknown): value is Signal<unknown>;
|
|
64
|
+
/**
|
|
65
|
+
* Start batching effects _(use `stopBatch` to flush and run batched effects)_
|
|
66
|
+
*/
|
|
67
|
+
export declare function startBatch(): void;
|
|
68
|
+
/**
|
|
69
|
+
* Stop batching effects and flush _(run)_ them
|
|
70
|
+
*/
|
|
71
|
+
export declare function stopBatch(): void;
|
|
49
72
|
|
|
50
73
|
export {};
|
package/types/index.d.ts
CHANGED
package/types/is.d.cts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Generated by dts-bundle-generator v9.5.1
|
|
2
|
+
|
|
3
|
+
declare class Signal<Value> {
|
|
4
|
+
private readonly $mora;
|
|
5
|
+
private readonly state;
|
|
6
|
+
constructor(value: Value);
|
|
7
|
+
/**
|
|
8
|
+
* Get the value
|
|
9
|
+
*/
|
|
10
|
+
get(): Value;
|
|
11
|
+
/**
|
|
12
|
+
* Get the value _(without reactivity)_
|
|
13
|
+
*/
|
|
14
|
+
peek(): Value;
|
|
15
|
+
/**
|
|
16
|
+
* Set the value
|
|
17
|
+
*/
|
|
18
|
+
set(value: Value): void;
|
|
19
|
+
/**
|
|
20
|
+
* Update the value
|
|
21
|
+
*/
|
|
22
|
+
update(callback: (value: Value) => Value): void;
|
|
23
|
+
}
|
|
24
|
+
export type GenericCallback = (...args: any[]) => any;
|
|
25
|
+
declare class Effect {
|
|
26
|
+
private readonly $mora;
|
|
27
|
+
private readonly state;
|
|
28
|
+
constructor(callback: GenericCallback);
|
|
29
|
+
}
|
|
30
|
+
declare class Computed<Value> {
|
|
31
|
+
private readonly $mora;
|
|
32
|
+
private readonly state;
|
|
33
|
+
constructor(callback: () => Value);
|
|
34
|
+
/**
|
|
35
|
+
* Get the value
|
|
36
|
+
*/
|
|
37
|
+
get(): Value;
|
|
38
|
+
/**
|
|
39
|
+
* Get the value _(without reactivity)_
|
|
40
|
+
*/
|
|
41
|
+
peek(): Value;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Is the value a computed signal?
|
|
45
|
+
*/
|
|
46
|
+
export declare function isComputed(value: unknown): value is Computed<unknown>;
|
|
47
|
+
/**
|
|
48
|
+
* Is the value an effect?
|
|
49
|
+
*/
|
|
50
|
+
export declare function isEffect(value: unknown): value is Effect;
|
|
51
|
+
/**
|
|
52
|
+
* Is the value a signal?
|
|
53
|
+
*/
|
|
54
|
+
export declare function isSignal(value: unknown): value is Signal<unknown>;
|
|
55
|
+
|
|
56
|
+
export {};
|
package/types/is.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Computed } from './computed';
|
|
2
|
+
import type { Effect } from './effect';
|
|
3
|
+
import type { Signal } from './signal';
|
|
4
|
+
/**
|
|
5
|
+
* Is the value a computed signal?
|
|
6
|
+
*/
|
|
7
|
+
export declare function isComputed(value: unknown): value is Computed<unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* Is the value an effect?
|
|
10
|
+
*/
|
|
11
|
+
export declare function isEffect(value: unknown): value is Effect;
|
|
12
|
+
/**
|
|
13
|
+
* Is the value a signal?
|
|
14
|
+
*/
|
|
15
|
+
export declare function isSignal(value: unknown): value is Signal<unknown>;
|
package/types/signal.d.cts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
// Generated by dts-bundle-generator v9.5.1
|
|
2
2
|
|
|
3
3
|
export declare class Signal<Value> {
|
|
4
|
+
private readonly $mora;
|
|
4
5
|
private readonly state;
|
|
5
6
|
constructor(value: Value);
|
|
6
7
|
/**
|
|
7
8
|
* Get the value
|
|
8
9
|
*/
|
|
9
10
|
get(): Value;
|
|
11
|
+
/**
|
|
12
|
+
* Get the value _(without reactivity)_
|
|
13
|
+
*/
|
|
14
|
+
peek(): Value;
|
|
10
15
|
/**
|
|
11
16
|
* Set the value
|
|
12
17
|
*/
|
package/types/signal.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
export declare class Signal<Value> {
|
|
2
|
+
private readonly $mora;
|
|
2
3
|
private readonly state;
|
|
3
4
|
constructor(value: Value);
|
|
4
5
|
/**
|
|
5
6
|
* Get the value
|
|
6
7
|
*/
|
|
7
8
|
get(): Value;
|
|
9
|
+
/**
|
|
10
|
+
* Get the value _(without reactivity)_
|
|
11
|
+
*/
|
|
12
|
+
peek(): Value;
|
|
8
13
|
/**
|
|
9
14
|
* Set the value
|
|
10
15
|
*/
|