@oscarpalmer/mora 0.2.0 → 0.4.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/computed.cjs +56 -0
- package/dist/computed.js +57 -0
- package/dist/effect.cjs +1 -6
- package/dist/effect.js +1 -6
- package/dist/index.cjs +2 -0
- package/dist/index.js +2 -0
- package/dist/mora.iife.js +64 -29
- package/dist/signal.cjs +18 -23
- package/dist/signal.js +18 -23
- package/package.json +1 -1
- package/src/computed.ts +74 -0
- package/src/effect.ts +0 -10
- package/src/index.ts +1 -0
- package/src/signal.ts +22 -26
- package/types/computed.d.cts +26 -0
- package/types/computed.d.ts +16 -0
- package/types/effect.d.cts +0 -12
- package/types/effect.d.ts +0 -2
- package/types/index.d.cts +14 -1
- package/types/index.d.ts +1 -0
- package/types/signal.d.cts +14 -1
- package/types/signal.d.ts +3 -0
|
@@ -0,0 +1,56 @@
|
|
|
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
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
6
|
+
const effect = require("./effect.cjs");
|
|
7
|
+
const signal = require("./signal.cjs");
|
|
8
|
+
exports.activeComputed = void 0;
|
|
9
|
+
class Computed {
|
|
10
|
+
constructor(callback) {
|
|
11
|
+
__publicField(this, "state");
|
|
12
|
+
this.state = {
|
|
13
|
+
dirty: true,
|
|
14
|
+
computeds: /* @__PURE__ */ new Set(),
|
|
15
|
+
effect: void 0,
|
|
16
|
+
effects: /* @__PURE__ */ new Set(),
|
|
17
|
+
value: void 0
|
|
18
|
+
};
|
|
19
|
+
this.state.effect = effect.effect(() => {
|
|
20
|
+
if (this.state.dirty) {
|
|
21
|
+
const previousComputed = exports.activeComputed;
|
|
22
|
+
exports.activeComputed = this;
|
|
23
|
+
const value = callback();
|
|
24
|
+
exports.activeComputed = previousComputed;
|
|
25
|
+
if (!Object.is(this.state.value, value)) {
|
|
26
|
+
this.state.value = value;
|
|
27
|
+
for (const comp of this.state.computeds) {
|
|
28
|
+
comp.state.dirty = true;
|
|
29
|
+
signal.dirtyEffects.add(comp.state.effect);
|
|
30
|
+
}
|
|
31
|
+
for (const effect2 of this.state.effects) {
|
|
32
|
+
signal.dirtyEffects.add(effect2);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
this.state.dirty = false;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
get() {
|
|
40
|
+
if (exports.activeComputed != null && exports.activeComputed !== this) {
|
|
41
|
+
this.state.computeds.add(exports.activeComputed);
|
|
42
|
+
}
|
|
43
|
+
if (effect.activeEffect != null && effect.activeEffect !== this.state.effect) {
|
|
44
|
+
this.state.effects.add(effect.activeEffect);
|
|
45
|
+
}
|
|
46
|
+
if (this.state.dirty) {
|
|
47
|
+
effect.runEffect(this.state.effect);
|
|
48
|
+
}
|
|
49
|
+
return this.state.value;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function computed(callback) {
|
|
53
|
+
return new Computed(callback);
|
|
54
|
+
}
|
|
55
|
+
exports.Computed = Computed;
|
|
56
|
+
exports.computed = computed;
|
package/dist/computed.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
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
|
+
import { effect, activeEffect, runEffect } from "./effect.js";
|
|
5
|
+
import { dirtyEffects } from "./signal.js";
|
|
6
|
+
let activeComputed;
|
|
7
|
+
class Computed {
|
|
8
|
+
constructor(callback) {
|
|
9
|
+
__publicField(this, "state");
|
|
10
|
+
this.state = {
|
|
11
|
+
dirty: true,
|
|
12
|
+
computeds: /* @__PURE__ */ new Set(),
|
|
13
|
+
effect: void 0,
|
|
14
|
+
effects: /* @__PURE__ */ new Set(),
|
|
15
|
+
value: void 0
|
|
16
|
+
};
|
|
17
|
+
this.state.effect = effect(() => {
|
|
18
|
+
if (this.state.dirty) {
|
|
19
|
+
const previousComputed = activeComputed;
|
|
20
|
+
activeComputed = this;
|
|
21
|
+
const value = callback();
|
|
22
|
+
activeComputed = previousComputed;
|
|
23
|
+
if (!Object.is(this.state.value, value)) {
|
|
24
|
+
this.state.value = value;
|
|
25
|
+
for (const comp of this.state.computeds) {
|
|
26
|
+
comp.state.dirty = true;
|
|
27
|
+
dirtyEffects.add(comp.state.effect);
|
|
28
|
+
}
|
|
29
|
+
for (const effect2 of this.state.effects) {
|
|
30
|
+
dirtyEffects.add(effect2);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
this.state.dirty = false;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
get() {
|
|
38
|
+
if (activeComputed != null && activeComputed !== this) {
|
|
39
|
+
this.state.computeds.add(activeComputed);
|
|
40
|
+
}
|
|
41
|
+
if (activeEffect != null && activeEffect !== this.state.effect) {
|
|
42
|
+
this.state.effects.add(activeEffect);
|
|
43
|
+
}
|
|
44
|
+
if (this.state.dirty) {
|
|
45
|
+
runEffect(this.state.effect);
|
|
46
|
+
}
|
|
47
|
+
return this.state.value;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function computed(callback) {
|
|
51
|
+
return new Computed(callback);
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
Computed,
|
|
55
|
+
activeComputed,
|
|
56
|
+
computed
|
|
57
|
+
};
|
package/dist/effect.cjs
CHANGED
|
@@ -8,17 +8,12 @@ class Effect {
|
|
|
8
8
|
constructor(callback) {
|
|
9
9
|
__publicField(this, "state");
|
|
10
10
|
this.state = {
|
|
11
|
-
callback
|
|
12
|
-
signals: /* @__PURE__ */ new Set()
|
|
11
|
+
callback
|
|
13
12
|
};
|
|
14
13
|
runEffect(this);
|
|
15
14
|
}
|
|
16
15
|
}
|
|
17
16
|
function runEffect(effect2) {
|
|
18
|
-
for (const signal of effect2.state.signals) {
|
|
19
|
-
signal.state.effects.delete(effect2);
|
|
20
|
-
}
|
|
21
|
-
effect2.state.signals.clear();
|
|
22
17
|
const previousEffect = exports.activeEffect;
|
|
23
18
|
exports.activeEffect = effect2;
|
|
24
19
|
try {
|
package/dist/effect.js
CHANGED
|
@@ -6,17 +6,12 @@ class Effect {
|
|
|
6
6
|
constructor(callback) {
|
|
7
7
|
__publicField(this, "state");
|
|
8
8
|
this.state = {
|
|
9
|
-
callback
|
|
10
|
-
signals: /* @__PURE__ */ new Set()
|
|
9
|
+
callback
|
|
11
10
|
};
|
|
12
11
|
runEffect(this);
|
|
13
12
|
}
|
|
14
13
|
}
|
|
15
14
|
function runEffect(effect2) {
|
|
16
|
-
for (const signal of effect2.state.signals) {
|
|
17
|
-
signal.state.effects.delete(effect2);
|
|
18
|
-
}
|
|
19
|
-
effect2.state.signals.clear();
|
|
20
15
|
const previousEffect = activeEffect;
|
|
21
16
|
activeEffect = effect2;
|
|
22
17
|
try {
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const computed = require("./computed.cjs");
|
|
3
4
|
const effect = require("./effect.cjs");
|
|
4
5
|
const signal = require("./signal.cjs");
|
|
6
|
+
exports.computed = computed.computed;
|
|
5
7
|
exports.effect = effect.effect;
|
|
6
8
|
exports.signal = signal.signal;
|
package/dist/index.js
CHANGED
package/dist/mora.iife.js
CHANGED
|
@@ -7,16 +7,11 @@ var Mora = (function (exports) {
|
|
|
7
7
|
constructor(callback) {
|
|
8
8
|
this.state = {
|
|
9
9
|
callback,
|
|
10
|
-
signals: new Set(),
|
|
11
10
|
};
|
|
12
11
|
runEffect(this);
|
|
13
12
|
}
|
|
14
13
|
}
|
|
15
14
|
function runEffect(effect) {
|
|
16
|
-
for (const signal of effect.state.signals) {
|
|
17
|
-
signal.state.effects.delete(effect);
|
|
18
|
-
}
|
|
19
|
-
effect.state.signals.clear();
|
|
20
15
|
const previousEffect = activeEffect;
|
|
21
16
|
activeEffect = effect;
|
|
22
17
|
try {
|
|
@@ -31,19 +26,21 @@ var Mora = (function (exports) {
|
|
|
31
26
|
}
|
|
32
27
|
|
|
33
28
|
const dirtyEffects = new Set();
|
|
34
|
-
let batchDepth = 0;
|
|
35
29
|
class Signal {
|
|
36
30
|
state;
|
|
37
31
|
constructor(value) {
|
|
38
32
|
this.state = {
|
|
39
33
|
value,
|
|
34
|
+
computeds: new Set(),
|
|
40
35
|
effects: new Set(),
|
|
41
36
|
};
|
|
42
37
|
}
|
|
43
38
|
get() {
|
|
39
|
+
if (activeComputed != null) {
|
|
40
|
+
this.state.computeds.add(activeComputed);
|
|
41
|
+
}
|
|
44
42
|
if (activeEffect != null) {
|
|
45
43
|
this.state.effects.add(activeEffect);
|
|
46
|
-
activeEffect.state.signals.add(this);
|
|
47
44
|
}
|
|
48
45
|
return this.state.value;
|
|
49
46
|
}
|
|
@@ -52,29 +49,18 @@ var Mora = (function (exports) {
|
|
|
52
49
|
return;
|
|
53
50
|
}
|
|
54
51
|
this.state.value = value;
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (isOutermostBatch) {
|
|
62
|
-
queueMicrotask(() => {
|
|
63
|
-
try {
|
|
64
|
-
for (const effect of dirtyEffects) {
|
|
65
|
-
runEffect(effect);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
finally {
|
|
69
|
-
dirtyEffects.clear();
|
|
70
|
-
batchDepth = 0;
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
}
|
|
52
|
+
for (const computed of this.state.computeds) {
|
|
53
|
+
computed.state.dirty = true;
|
|
54
|
+
dirtyEffects.add(computed.state.effect);
|
|
55
|
+
}
|
|
56
|
+
for (const effect of this.state.effects) {
|
|
57
|
+
dirtyEffects.add(effect);
|
|
74
58
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
59
|
+
while (dirtyEffects.size > 0) {
|
|
60
|
+
const effects = [...dirtyEffects];
|
|
61
|
+
dirtyEffects.clear();
|
|
62
|
+
for (const effect of effects) {
|
|
63
|
+
runEffect(effect);
|
|
78
64
|
}
|
|
79
65
|
}
|
|
80
66
|
}
|
|
@@ -86,6 +72,55 @@ var Mora = (function (exports) {
|
|
|
86
72
|
return new Signal(value);
|
|
87
73
|
}
|
|
88
74
|
|
|
75
|
+
let activeComputed;
|
|
76
|
+
class Computed {
|
|
77
|
+
state;
|
|
78
|
+
constructor(callback) {
|
|
79
|
+
this.state = {
|
|
80
|
+
dirty: true,
|
|
81
|
+
computeds: new Set(),
|
|
82
|
+
effect: undefined,
|
|
83
|
+
effects: new Set(),
|
|
84
|
+
value: undefined,
|
|
85
|
+
};
|
|
86
|
+
this.state.effect = effect(() => {
|
|
87
|
+
if (this.state.dirty) {
|
|
88
|
+
const previousComputed = activeComputed;
|
|
89
|
+
activeComputed = this;
|
|
90
|
+
const value = callback();
|
|
91
|
+
activeComputed = previousComputed;
|
|
92
|
+
if (!Object.is(this.state.value, value)) {
|
|
93
|
+
this.state.value = value;
|
|
94
|
+
for (const comp of this.state.computeds) {
|
|
95
|
+
comp.state.dirty = true;
|
|
96
|
+
dirtyEffects.add(comp.state.effect);
|
|
97
|
+
}
|
|
98
|
+
for (const effect of this.state.effects) {
|
|
99
|
+
dirtyEffects.add(effect);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
this.state.dirty = false;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
get() {
|
|
107
|
+
if (activeComputed != null && activeComputed !== this) {
|
|
108
|
+
this.state.computeds.add(activeComputed);
|
|
109
|
+
}
|
|
110
|
+
if (activeEffect != null && activeEffect !== this.state.effect) {
|
|
111
|
+
this.state.effects.add(activeEffect);
|
|
112
|
+
}
|
|
113
|
+
if (this.state.dirty) {
|
|
114
|
+
runEffect(this.state.effect);
|
|
115
|
+
}
|
|
116
|
+
return this.state.value;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function computed(callback) {
|
|
120
|
+
return new Computed(callback);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
exports.computed = computed;
|
|
89
124
|
exports.effect = effect;
|
|
90
125
|
exports.signal = signal;
|
|
91
126
|
|
package/dist/signal.cjs
CHANGED
|
@@ -3,21 +3,24 @@ 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 computed = require("./computed.cjs");
|
|
6
7
|
const effect = require("./effect.cjs");
|
|
7
8
|
const dirtyEffects = /* @__PURE__ */ new Set();
|
|
8
|
-
let batchDepth = 0;
|
|
9
9
|
class Signal {
|
|
10
10
|
constructor(value) {
|
|
11
11
|
__publicField(this, "state");
|
|
12
12
|
this.state = {
|
|
13
13
|
value,
|
|
14
|
+
computeds: /* @__PURE__ */ new Set(),
|
|
14
15
|
effects: /* @__PURE__ */ new Set()
|
|
15
16
|
};
|
|
16
17
|
}
|
|
17
18
|
get() {
|
|
19
|
+
if (computed.activeComputed != null) {
|
|
20
|
+
this.state.computeds.add(computed.activeComputed);
|
|
21
|
+
}
|
|
18
22
|
if (effect.activeEffect != null) {
|
|
19
23
|
this.state.effects.add(effect.activeEffect);
|
|
20
|
-
effect.activeEffect.state.signals.add(this);
|
|
21
24
|
}
|
|
22
25
|
return this.state.value;
|
|
23
26
|
}
|
|
@@ -26,27 +29,18 @@ class Signal {
|
|
|
26
29
|
return;
|
|
27
30
|
}
|
|
28
31
|
this.state.value = value;
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
} finally {
|
|
42
|
-
dirtyEffects.clear();
|
|
43
|
-
batchDepth = 0;
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
} finally {
|
|
48
|
-
if (isOutermostBatch) {
|
|
49
|
-
batchDepth -= 1;
|
|
32
|
+
for (const computed2 of this.state.computeds) {
|
|
33
|
+
computed2.state.dirty = true;
|
|
34
|
+
dirtyEffects.add(computed2.state.effect);
|
|
35
|
+
}
|
|
36
|
+
for (const effect2 of this.state.effects) {
|
|
37
|
+
dirtyEffects.add(effect2);
|
|
38
|
+
}
|
|
39
|
+
while (dirtyEffects.size > 0) {
|
|
40
|
+
const effects = [...dirtyEffects];
|
|
41
|
+
dirtyEffects.clear();
|
|
42
|
+
for (const effect$1 of effects) {
|
|
43
|
+
effect.runEffect(effect$1);
|
|
50
44
|
}
|
|
51
45
|
}
|
|
52
46
|
}
|
|
@@ -58,4 +52,5 @@ function signal(value) {
|
|
|
58
52
|
return new Signal(value);
|
|
59
53
|
}
|
|
60
54
|
exports.Signal = Signal;
|
|
55
|
+
exports.dirtyEffects = dirtyEffects;
|
|
61
56
|
exports.signal = signal;
|
package/dist/signal.js
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
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 { activeComputed } from "./computed.js";
|
|
4
5
|
import { activeEffect, runEffect } from "./effect.js";
|
|
5
6
|
const dirtyEffects = /* @__PURE__ */ new Set();
|
|
6
|
-
let batchDepth = 0;
|
|
7
7
|
class Signal {
|
|
8
8
|
constructor(value) {
|
|
9
9
|
__publicField(this, "state");
|
|
10
10
|
this.state = {
|
|
11
11
|
value,
|
|
12
|
+
computeds: /* @__PURE__ */ new Set(),
|
|
12
13
|
effects: /* @__PURE__ */ new Set()
|
|
13
14
|
};
|
|
14
15
|
}
|
|
15
16
|
get() {
|
|
17
|
+
if (activeComputed != null) {
|
|
18
|
+
this.state.computeds.add(activeComputed);
|
|
19
|
+
}
|
|
16
20
|
if (activeEffect != null) {
|
|
17
21
|
this.state.effects.add(activeEffect);
|
|
18
|
-
activeEffect.state.signals.add(this);
|
|
19
22
|
}
|
|
20
23
|
return this.state.value;
|
|
21
24
|
}
|
|
@@ -24,27 +27,18 @@ class Signal {
|
|
|
24
27
|
return;
|
|
25
28
|
}
|
|
26
29
|
this.state.value = value;
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
} finally {
|
|
40
|
-
dirtyEffects.clear();
|
|
41
|
-
batchDepth = 0;
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
} finally {
|
|
46
|
-
if (isOutermostBatch) {
|
|
47
|
-
batchDepth -= 1;
|
|
30
|
+
for (const computed of this.state.computeds) {
|
|
31
|
+
computed.state.dirty = true;
|
|
32
|
+
dirtyEffects.add(computed.state.effect);
|
|
33
|
+
}
|
|
34
|
+
for (const effect of this.state.effects) {
|
|
35
|
+
dirtyEffects.add(effect);
|
|
36
|
+
}
|
|
37
|
+
while (dirtyEffects.size > 0) {
|
|
38
|
+
const effects = [...dirtyEffects];
|
|
39
|
+
dirtyEffects.clear();
|
|
40
|
+
for (const effect of effects) {
|
|
41
|
+
runEffect(effect);
|
|
48
42
|
}
|
|
49
43
|
}
|
|
50
44
|
}
|
|
@@ -57,5 +51,6 @@ function signal(value) {
|
|
|
57
51
|
}
|
|
58
52
|
export {
|
|
59
53
|
Signal,
|
|
54
|
+
dirtyEffects,
|
|
60
55
|
signal
|
|
61
56
|
};
|
package/package.json
CHANGED
package/src/computed.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {type Effect, activeEffect, effect, runEffect} from './effect';
|
|
2
|
+
import {dirtyEffects} from './signal';
|
|
3
|
+
|
|
4
|
+
type ComputedState<Value> = {
|
|
5
|
+
dirty: boolean;
|
|
6
|
+
computeds: Set<Computed<unknown>>;
|
|
7
|
+
effect: Effect;
|
|
8
|
+
effects: Set<Effect>;
|
|
9
|
+
value: Value;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export let activeComputed: Computed<unknown> | undefined;
|
|
13
|
+
|
|
14
|
+
export class Computed<Value> {
|
|
15
|
+
readonly state: ComputedState<Value>;
|
|
16
|
+
|
|
17
|
+
constructor(callback: () => Value) {
|
|
18
|
+
this.state = {
|
|
19
|
+
dirty: true,
|
|
20
|
+
computeds: new Set(),
|
|
21
|
+
effect: undefined as never,
|
|
22
|
+
effects: new Set(),
|
|
23
|
+
value: undefined as never,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
this.state.effect = effect(() => {
|
|
27
|
+
if (this.state.dirty) {
|
|
28
|
+
const previousComputed = activeComputed;
|
|
29
|
+
|
|
30
|
+
activeComputed = this;
|
|
31
|
+
|
|
32
|
+
const value = callback();
|
|
33
|
+
|
|
34
|
+
activeComputed = previousComputed;
|
|
35
|
+
|
|
36
|
+
if (!Object.is(this.state.value, value)) {
|
|
37
|
+
this.state.value = value;
|
|
38
|
+
|
|
39
|
+
for (const comp of this.state.computeds) {
|
|
40
|
+
comp.state.dirty = true;
|
|
41
|
+
|
|
42
|
+
dirtyEffects.add(comp.state.effect);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for (const effect of this.state.effects) {
|
|
46
|
+
dirtyEffects.add(effect);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
this.state.dirty = false;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get(): Value {
|
|
56
|
+
if (activeComputed != null && activeComputed !== this) {
|
|
57
|
+
this.state.computeds.add(activeComputed);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (activeEffect != null && activeEffect !== this.state.effect) {
|
|
61
|
+
this.state.effects.add(activeEffect);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (this.state.dirty) {
|
|
65
|
+
runEffect(this.state.effect);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return this.state.value;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function computed<Value>(callback: () => Value): Computed<Value> {
|
|
73
|
+
return new Computed(callback);
|
|
74
|
+
}
|
package/src/effect.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import type {GenericCallback} from '@oscarpalmer/atoms/models';
|
|
2
|
-
import type {Signal} from './signal';
|
|
3
2
|
|
|
4
3
|
type EffectState = {
|
|
5
4
|
callback: GenericCallback;
|
|
6
|
-
signals: Set<Signal<never>>;
|
|
7
5
|
};
|
|
8
6
|
|
|
9
7
|
export let activeEffect: Effect | undefined;
|
|
@@ -14,7 +12,6 @@ export class Effect {
|
|
|
14
12
|
constructor(callback: GenericCallback) {
|
|
15
13
|
this.state = {
|
|
16
14
|
callback,
|
|
17
|
-
signals: new Set(),
|
|
18
15
|
};
|
|
19
16
|
|
|
20
17
|
runEffect(this);
|
|
@@ -22,12 +19,6 @@ export class Effect {
|
|
|
22
19
|
}
|
|
23
20
|
|
|
24
21
|
export function runEffect(effect: Effect): void {
|
|
25
|
-
for (const signal of effect.state.signals) {
|
|
26
|
-
signal.state.effects.delete(effect);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
effect.state.signals.clear();
|
|
30
|
-
|
|
31
22
|
const previousEffect = activeEffect;
|
|
32
23
|
|
|
33
24
|
activeEffect = effect;
|
|
@@ -42,4 +33,3 @@ export function runEffect(effect: Effect): void {
|
|
|
42
33
|
export function effect(callback: GenericCallback): Effect {
|
|
43
34
|
return new Effect(callback);
|
|
44
35
|
}
|
|
45
|
-
|
package/src/index.ts
CHANGED
package/src/signal.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import {type Computed, activeComputed} from './computed';
|
|
1
2
|
import {type Effect, activeEffect, runEffect} from './effect';
|
|
2
3
|
|
|
3
4
|
type SignalState<Value> = {
|
|
5
|
+
computeds: Set<Computed<unknown>>;
|
|
4
6
|
effects: Set<Effect>;
|
|
5
7
|
value: Value;
|
|
6
8
|
};
|
|
7
9
|
|
|
8
|
-
const dirtyEffects = new Set<Effect>();
|
|
9
|
-
|
|
10
|
-
let batchDepth = 0;
|
|
10
|
+
export const dirtyEffects = new Set<Effect>();
|
|
11
11
|
|
|
12
12
|
export class Signal<Value> {
|
|
13
13
|
readonly state: SignalState<Value>;
|
|
@@ -15,14 +15,18 @@ export class Signal<Value> {
|
|
|
15
15
|
constructor(value: Value) {
|
|
16
16
|
this.state = {
|
|
17
17
|
value,
|
|
18
|
+
computeds: new Set(),
|
|
18
19
|
effects: new Set(),
|
|
19
20
|
};
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
get(): Value {
|
|
24
|
+
if (activeComputed != null) {
|
|
25
|
+
this.state.computeds.add(activeComputed);
|
|
26
|
+
}
|
|
27
|
+
|
|
23
28
|
if (activeEffect != null) {
|
|
24
29
|
this.state.effects.add(activeEffect);
|
|
25
|
-
activeEffect.state.signals.add(this as never);
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
return this.state.value;
|
|
@@ -35,31 +39,23 @@ export class Signal<Value> {
|
|
|
35
39
|
|
|
36
40
|
this.state.value = value;
|
|
37
41
|
|
|
38
|
-
const
|
|
42
|
+
for (const computed of this.state.computeds) {
|
|
43
|
+
computed.state.dirty = true;
|
|
39
44
|
|
|
40
|
-
|
|
45
|
+
dirtyEffects.add(computed.state.effect);
|
|
46
|
+
}
|
|
41
47
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
48
|
+
for (const effect of this.state.effects) {
|
|
49
|
+
dirtyEffects.add(effect);
|
|
50
|
+
}
|
|
46
51
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
dirtyEffects.clear();
|
|
55
|
-
|
|
56
|
-
batchDepth = 0;
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
} finally {
|
|
61
|
-
if (isOutermostBatch) {
|
|
62
|
-
batchDepth -= 1;
|
|
52
|
+
while (dirtyEffects.size > 0) {
|
|
53
|
+
const effects = [...dirtyEffects];
|
|
54
|
+
|
|
55
|
+
dirtyEffects.clear();
|
|
56
|
+
|
|
57
|
+
for (const effect of effects) {
|
|
58
|
+
runEffect(effect);
|
|
63
59
|
}
|
|
64
60
|
}
|
|
65
61
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Generated by dts-bundle-generator v9.5.1
|
|
2
|
+
|
|
3
|
+
export type GenericCallback = (...args: any[]) => any;
|
|
4
|
+
export type EffectState = {
|
|
5
|
+
callback: GenericCallback;
|
|
6
|
+
};
|
|
7
|
+
declare class Effect {
|
|
8
|
+
readonly state: EffectState;
|
|
9
|
+
constructor(callback: GenericCallback);
|
|
10
|
+
}
|
|
11
|
+
export type ComputedState<Value> = {
|
|
12
|
+
dirty: boolean;
|
|
13
|
+
computeds: Set<Computed<unknown>>;
|
|
14
|
+
effect: Effect;
|
|
15
|
+
effects: Set<Effect>;
|
|
16
|
+
value: Value;
|
|
17
|
+
};
|
|
18
|
+
export declare let activeComputed: Computed<unknown> | undefined;
|
|
19
|
+
export declare class Computed<Value> {
|
|
20
|
+
readonly state: ComputedState<Value>;
|
|
21
|
+
constructor(callback: () => Value);
|
|
22
|
+
get(): Value;
|
|
23
|
+
}
|
|
24
|
+
export declare function computed<Value>(callback: () => Value): Computed<Value>;
|
|
25
|
+
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Effect } from './effect';
|
|
2
|
+
type ComputedState<Value> = {
|
|
3
|
+
dirty: boolean;
|
|
4
|
+
computeds: Set<Computed<unknown>>;
|
|
5
|
+
effect: Effect;
|
|
6
|
+
effects: Set<Effect>;
|
|
7
|
+
value: Value;
|
|
8
|
+
};
|
|
9
|
+
export declare let activeComputed: Computed<unknown> | undefined;
|
|
10
|
+
export declare class Computed<Value> {
|
|
11
|
+
readonly state: ComputedState<Value>;
|
|
12
|
+
constructor(callback: () => Value);
|
|
13
|
+
get(): Value;
|
|
14
|
+
}
|
|
15
|
+
export declare function computed<Value>(callback: () => Value): Computed<Value>;
|
|
16
|
+
export {};
|
package/types/effect.d.cts
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
export type GenericCallback = (...args: any[]) => any;
|
|
4
4
|
export type EffectState = {
|
|
5
5
|
callback: GenericCallback;
|
|
6
|
-
signals: Set<Signal<never>>;
|
|
7
6
|
};
|
|
8
7
|
export declare let activeEffect: Effect | undefined;
|
|
9
8
|
export declare class Effect {
|
|
@@ -12,16 +11,5 @@ export declare class Effect {
|
|
|
12
11
|
}
|
|
13
12
|
export declare function runEffect(effect: Effect): void;
|
|
14
13
|
export declare function effect(callback: GenericCallback): Effect;
|
|
15
|
-
export type SignalState<Value> = {
|
|
16
|
-
effects: Set<Effect>;
|
|
17
|
-
value: Value;
|
|
18
|
-
};
|
|
19
|
-
declare class Signal<Value> {
|
|
20
|
-
readonly state: SignalState<Value>;
|
|
21
|
-
constructor(value: Value);
|
|
22
|
-
get(): Value;
|
|
23
|
-
set(value: Value): void;
|
|
24
|
-
update(callback: (value: Value) => Value): void;
|
|
25
|
-
}
|
|
26
14
|
|
|
27
15
|
export {};
|
package/types/effect.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { GenericCallback } from '@oscarpalmer/atoms/models';
|
|
2
|
-
import type { Signal } from './signal';
|
|
3
2
|
type EffectState = {
|
|
4
3
|
callback: GenericCallback;
|
|
5
|
-
signals: Set<Signal<never>>;
|
|
6
4
|
};
|
|
7
5
|
export declare let activeEffect: Effect | undefined;
|
|
8
6
|
export declare class Effect {
|
package/types/index.d.cts
CHANGED
|
@@ -3,14 +3,27 @@
|
|
|
3
3
|
export type GenericCallback = (...args: any[]) => any;
|
|
4
4
|
export type EffectState = {
|
|
5
5
|
callback: GenericCallback;
|
|
6
|
-
signals: Set<Signal<never>>;
|
|
7
6
|
};
|
|
8
7
|
export declare class Effect {
|
|
9
8
|
readonly state: EffectState;
|
|
10
9
|
constructor(callback: GenericCallback);
|
|
11
10
|
}
|
|
12
11
|
export declare function effect(callback: GenericCallback): Effect;
|
|
12
|
+
export type ComputedState<Value> = {
|
|
13
|
+
dirty: boolean;
|
|
14
|
+
computeds: Set<Computed<unknown>>;
|
|
15
|
+
effect: Effect;
|
|
16
|
+
effects: Set<Effect>;
|
|
17
|
+
value: Value;
|
|
18
|
+
};
|
|
19
|
+
export declare class Computed<Value> {
|
|
20
|
+
readonly state: ComputedState<Value>;
|
|
21
|
+
constructor(callback: () => Value);
|
|
22
|
+
get(): Value;
|
|
23
|
+
}
|
|
24
|
+
export declare function computed<Value>(callback: () => Value): Computed<Value>;
|
|
13
25
|
export type SignalState<Value> = {
|
|
26
|
+
computeds: Set<Computed<unknown>>;
|
|
14
27
|
effects: Set<Effect>;
|
|
15
28
|
value: Value;
|
|
16
29
|
};
|
package/types/index.d.ts
CHANGED
package/types/signal.d.cts
CHANGED
|
@@ -3,16 +3,29 @@
|
|
|
3
3
|
export type GenericCallback = (...args: any[]) => any;
|
|
4
4
|
export type EffectState = {
|
|
5
5
|
callback: GenericCallback;
|
|
6
|
-
signals: Set<Signal<never>>;
|
|
7
6
|
};
|
|
8
7
|
declare class Effect {
|
|
9
8
|
readonly state: EffectState;
|
|
10
9
|
constructor(callback: GenericCallback);
|
|
11
10
|
}
|
|
11
|
+
export type ComputedState<Value> = {
|
|
12
|
+
dirty: boolean;
|
|
13
|
+
computeds: Set<Computed<unknown>>;
|
|
14
|
+
effect: Effect;
|
|
15
|
+
effects: Set<Effect>;
|
|
16
|
+
value: Value;
|
|
17
|
+
};
|
|
18
|
+
declare class Computed<Value> {
|
|
19
|
+
readonly state: ComputedState<Value>;
|
|
20
|
+
constructor(callback: () => Value);
|
|
21
|
+
get(): Value;
|
|
22
|
+
}
|
|
12
23
|
export type SignalState<Value> = {
|
|
24
|
+
computeds: Set<Computed<unknown>>;
|
|
13
25
|
effects: Set<Effect>;
|
|
14
26
|
value: Value;
|
|
15
27
|
};
|
|
28
|
+
export declare const dirtyEffects: Set<Effect>;
|
|
16
29
|
export declare class Signal<Value> {
|
|
17
30
|
readonly state: SignalState<Value>;
|
|
18
31
|
constructor(value: Value);
|
package/types/signal.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { type Computed } from './computed';
|
|
1
2
|
import { type Effect } from './effect';
|
|
2
3
|
type SignalState<Value> = {
|
|
4
|
+
computeds: Set<Computed<unknown>>;
|
|
3
5
|
effects: Set<Effect>;
|
|
4
6
|
value: Value;
|
|
5
7
|
};
|
|
8
|
+
export declare const dirtyEffects: Set<Effect>;
|
|
6
9
|
export declare class Signal<Value> {
|
|
7
10
|
readonly state: SignalState<Value>;
|
|
8
11
|
constructor(value: Value);
|