@oscarpalmer/mora 0.8.0 → 0.10.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 +12 -5
- package/dist/batch.js +13 -6
- package/dist/computed.cjs +21 -1
- package/dist/computed.js +23 -3
- package/dist/effect.cjs +3 -2
- package/dist/effect.js +3 -2
- 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 +108 -9
- package/dist/signal.cjs +23 -3
- package/dist/signal.js +24 -4
- package/dist/subscription.cjs +32 -0
- package/dist/subscription.js +32 -0
- package/package.json +4 -2
- package/src/batch.ts +14 -6
- package/src/computed.ts +37 -10
- package/src/effect.ts +13 -9
- package/src/index.ts +1 -0
- package/src/is.ts +34 -0
- package/src/signal.ts +37 -4
- package/src/subscription.ts +45 -0
- package/types/batch.d.cts +48 -0
- package/types/batch.d.ts +3 -0
- package/types/computed.d.cts +23 -0
- package/types/computed.d.ts +13 -2
- package/types/effect.d.cts +1 -1
- package/types/effect.d.ts +1 -1
- package/types/index.d.cts +57 -25
- package/types/index.d.ts +1 -0
- package/types/is.d.cts +73 -0
- package/types/is.d.ts +15 -0
- package/types/signal.d.cts +56 -0
- package/types/signal.d.ts +19 -0
- package/types/subscription.d.cts +54 -0
- package/types/subscription.d.ts +12 -0
package/dist/batch.cjs
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const effect = require("./effect.cjs");
|
|
4
|
+
const is = require("./is.cjs");
|
|
4
5
|
function flushEffects() {
|
|
5
|
-
while (exports.batchDepth === 0 &&
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
for (const
|
|
9
|
-
|
|
6
|
+
while (exports.batchDepth === 0 && batchedHandlers.size > 0) {
|
|
7
|
+
const handlers = [...batchedHandlers];
|
|
8
|
+
batchedHandlers.clear();
|
|
9
|
+
for (const handler of handlers) {
|
|
10
|
+
if (is.isEffect(handler)) {
|
|
11
|
+
effect.runEffect(handler);
|
|
12
|
+
} else {
|
|
13
|
+
handler.callback(handler.state.value);
|
|
14
|
+
}
|
|
10
15
|
}
|
|
11
16
|
}
|
|
12
17
|
}
|
|
@@ -19,7 +24,9 @@ function stopBatch() {
|
|
|
19
24
|
}
|
|
20
25
|
flushEffects();
|
|
21
26
|
}
|
|
27
|
+
const batchedHandlers = /* @__PURE__ */ new Set();
|
|
22
28
|
exports.batchDepth = 0;
|
|
29
|
+
exports.batchedHandlers = batchedHandlers;
|
|
23
30
|
exports.flushEffects = flushEffects;
|
|
24
31
|
exports.startBatch = startBatch;
|
|
25
32
|
exports.stopBatch = stopBatch;
|
package/dist/batch.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { runEffect } from "./effect.js";
|
|
2
|
+
import { isEffect } from "./is.js";
|
|
2
3
|
function flushEffects() {
|
|
3
|
-
while (batchDepth === 0 &&
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
for (const
|
|
7
|
-
|
|
4
|
+
while (batchDepth === 0 && batchedHandlers.size > 0) {
|
|
5
|
+
const handlers = [...batchedHandlers];
|
|
6
|
+
batchedHandlers.clear();
|
|
7
|
+
for (const handler of handlers) {
|
|
8
|
+
if (isEffect(handler)) {
|
|
9
|
+
runEffect(handler);
|
|
10
|
+
} else {
|
|
11
|
+
handler.callback(handler.state.value);
|
|
12
|
+
}
|
|
8
13
|
}
|
|
9
14
|
}
|
|
10
15
|
}
|
|
@@ -17,9 +22,11 @@ function stopBatch() {
|
|
|
17
22
|
}
|
|
18
23
|
flushEffects();
|
|
19
24
|
}
|
|
25
|
+
const batchedHandlers = /* @__PURE__ */ new Set();
|
|
20
26
|
let batchDepth = 0;
|
|
21
27
|
export {
|
|
22
28
|
batchDepth,
|
|
29
|
+
batchedHandlers,
|
|
23
30
|
flushEffects,
|
|
24
31
|
startBatch,
|
|
25
32
|
stopBatch
|
package/dist/computed.cjs
CHANGED
|
@@ -5,15 +5,20 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
5
5
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
6
6
|
const batch = require("./batch.cjs");
|
|
7
7
|
const effect = require("./effect.cjs");
|
|
8
|
+
const subscription = require("./subscription.cjs");
|
|
8
9
|
exports.activeComputed = void 0;
|
|
9
10
|
class Computed {
|
|
10
11
|
constructor(callback) {
|
|
11
12
|
__publicField(this, "state");
|
|
13
|
+
Object.defineProperty(this, "$mora", {
|
|
14
|
+
value: "computed"
|
|
15
|
+
});
|
|
12
16
|
this.state = {
|
|
13
17
|
computeds: /* @__PURE__ */ new Set(),
|
|
14
18
|
dirty: true,
|
|
15
19
|
effect: void 0,
|
|
16
20
|
effects: /* @__PURE__ */ new Set(),
|
|
21
|
+
subscriptions: /* @__PURE__ */ new Map(),
|
|
17
22
|
value: void 0
|
|
18
23
|
};
|
|
19
24
|
this.state.effect = effect.effect(() => {
|
|
@@ -28,7 +33,10 @@ class Computed {
|
|
|
28
33
|
computed2.state.dirty = true;
|
|
29
34
|
}
|
|
30
35
|
for (const effect2 of this.state.effects) {
|
|
31
|
-
|
|
36
|
+
batch.batchedHandlers.add(effect2);
|
|
37
|
+
}
|
|
38
|
+
for (const [, subscription2] of this.state.subscriptions) {
|
|
39
|
+
subscription2.callback(value);
|
|
32
40
|
}
|
|
33
41
|
}
|
|
34
42
|
this.state.dirty = false;
|
|
@@ -56,6 +64,18 @@ class Computed {
|
|
|
56
64
|
peek() {
|
|
57
65
|
return this.state.value;
|
|
58
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Subscribe to changes
|
|
69
|
+
*/
|
|
70
|
+
subscribe(callback) {
|
|
71
|
+
return subscription.subscribe(this.state, callback);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Unsubscribe from changes
|
|
75
|
+
*/
|
|
76
|
+
unsubscribe(callback) {
|
|
77
|
+
subscription.unsubscribe(this.state, callback);
|
|
78
|
+
}
|
|
59
79
|
}
|
|
60
80
|
function computed(callback) {
|
|
61
81
|
return new Computed(callback);
|
package/dist/computed.js
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
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 { batchDepth } from "./batch.js";
|
|
5
|
-
import { effect,
|
|
4
|
+
import { batchedHandlers, batchDepth } from "./batch.js";
|
|
5
|
+
import { effect, activeEffect, runEffect } from "./effect.js";
|
|
6
|
+
import { subscribe, unsubscribe } from "./subscription.js";
|
|
6
7
|
let activeComputed;
|
|
7
8
|
class Computed {
|
|
8
9
|
constructor(callback) {
|
|
9
10
|
__publicField(this, "state");
|
|
11
|
+
Object.defineProperty(this, "$mora", {
|
|
12
|
+
value: "computed"
|
|
13
|
+
});
|
|
10
14
|
this.state = {
|
|
11
15
|
computeds: /* @__PURE__ */ new Set(),
|
|
12
16
|
dirty: true,
|
|
13
17
|
effect: void 0,
|
|
14
18
|
effects: /* @__PURE__ */ new Set(),
|
|
19
|
+
subscriptions: /* @__PURE__ */ new Map(),
|
|
15
20
|
value: void 0
|
|
16
21
|
};
|
|
17
22
|
this.state.effect = effect(() => {
|
|
@@ -26,7 +31,10 @@ class Computed {
|
|
|
26
31
|
computed2.state.dirty = true;
|
|
27
32
|
}
|
|
28
33
|
for (const effect2 of this.state.effects) {
|
|
29
|
-
|
|
34
|
+
batchedHandlers.add(effect2);
|
|
35
|
+
}
|
|
36
|
+
for (const [, subscription] of this.state.subscriptions) {
|
|
37
|
+
subscription.callback(value);
|
|
30
38
|
}
|
|
31
39
|
}
|
|
32
40
|
this.state.dirty = false;
|
|
@@ -54,6 +62,18 @@ class Computed {
|
|
|
54
62
|
peek() {
|
|
55
63
|
return this.state.value;
|
|
56
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Subscribe to changes
|
|
67
|
+
*/
|
|
68
|
+
subscribe(callback) {
|
|
69
|
+
return subscribe(this.state, callback);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Unsubscribe from changes
|
|
73
|
+
*/
|
|
74
|
+
unsubscribe(callback) {
|
|
75
|
+
unsubscribe(this.state, callback);
|
|
76
|
+
}
|
|
57
77
|
}
|
|
58
78
|
function computed(callback) {
|
|
59
79
|
return new Computed(callback);
|
package/dist/effect.cjs
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
class Effect {
|
|
4
4
|
constructor(callback) {
|
|
5
|
+
Object.defineProperty(this, "$mora", {
|
|
6
|
+
value: "effect"
|
|
7
|
+
});
|
|
5
8
|
this.state = {
|
|
6
9
|
callback
|
|
7
10
|
};
|
|
@@ -21,8 +24,6 @@ function effect(callback) {
|
|
|
21
24
|
return new Effect(callback);
|
|
22
25
|
}
|
|
23
26
|
exports.activeEffect = void 0;
|
|
24
|
-
const dirtyEffects = /* @__PURE__ */ new Set();
|
|
25
27
|
exports.Effect = Effect;
|
|
26
|
-
exports.dirtyEffects = dirtyEffects;
|
|
27
28
|
exports.effect = effect;
|
|
28
29
|
exports.runEffect = runEffect;
|
package/dist/effect.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
class Effect {
|
|
2
2
|
constructor(callback) {
|
|
3
|
+
Object.defineProperty(this, "$mora", {
|
|
4
|
+
value: "effect"
|
|
5
|
+
});
|
|
3
6
|
this.state = {
|
|
4
7
|
callback
|
|
5
8
|
};
|
|
@@ -19,11 +22,9 @@ function effect(callback) {
|
|
|
19
22
|
return new Effect(callback);
|
|
20
23
|
}
|
|
21
24
|
let activeEffect;
|
|
22
|
-
const dirtyEffects = /* @__PURE__ */ new Set();
|
|
23
25
|
export {
|
|
24
26
|
Effect,
|
|
25
27
|
activeEffect,
|
|
26
|
-
dirtyEffects,
|
|
27
28
|
effect,
|
|
28
29
|
runEffect
|
|
29
30
|
};
|
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,5 +1,8 @@
|
|
|
1
1
|
class Effect {
|
|
2
2
|
constructor(callback) {
|
|
3
|
+
Object.defineProperty(this, '$mora', {
|
|
4
|
+
value: 'effect',
|
|
5
|
+
});
|
|
3
6
|
this.state = {
|
|
4
7
|
callback,
|
|
5
8
|
};
|
|
@@ -23,14 +26,43 @@ function effect(callback) {
|
|
|
23
26
|
return new Effect(callback);
|
|
24
27
|
}
|
|
25
28
|
let activeEffect;
|
|
26
|
-
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Is the value a computed signal?
|
|
32
|
+
*/
|
|
33
|
+
function isComputed(value) {
|
|
34
|
+
return isMora(value, 'computed');
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Is the value an effect?
|
|
38
|
+
*/
|
|
39
|
+
function isEffect(value) {
|
|
40
|
+
return isMora(value, 'effect');
|
|
41
|
+
}
|
|
42
|
+
function isMora(value, name) {
|
|
43
|
+
return (typeof value === 'object' &&
|
|
44
|
+
value != null &&
|
|
45
|
+
'$mora' in value &&
|
|
46
|
+
value.$mora === name);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Is the value a signal?
|
|
50
|
+
*/
|
|
51
|
+
function isSignal(value) {
|
|
52
|
+
return isMora(value, 'signal');
|
|
53
|
+
}
|
|
27
54
|
|
|
28
55
|
function flushEffects() {
|
|
29
|
-
while (batchDepth === 0 &&
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
for (const
|
|
33
|
-
|
|
56
|
+
while (batchDepth === 0 && batchedHandlers.size > 0) {
|
|
57
|
+
const handlers = [...batchedHandlers];
|
|
58
|
+
batchedHandlers.clear();
|
|
59
|
+
for (const handler of handlers) {
|
|
60
|
+
if (isEffect(handler)) {
|
|
61
|
+
runEffect(handler);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
handler.callback(handler.state.value);
|
|
65
|
+
}
|
|
34
66
|
}
|
|
35
67
|
}
|
|
36
68
|
}
|
|
@@ -49,17 +81,50 @@ function stopBatch() {
|
|
|
49
81
|
}
|
|
50
82
|
flushEffects();
|
|
51
83
|
}
|
|
84
|
+
const batchedHandlers = new Set();
|
|
52
85
|
let batchDepth = 0;
|
|
53
86
|
|
|
87
|
+
class Subscription {
|
|
88
|
+
state;
|
|
89
|
+
callback;
|
|
90
|
+
constructor(state, callback) {
|
|
91
|
+
this.state = state;
|
|
92
|
+
this.callback = callback;
|
|
93
|
+
callback(state.value);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function noop() { }
|
|
97
|
+
function subscribe(state, callback) {
|
|
98
|
+
if (typeof callback !== 'function' || state.subscriptions.has(callback)) {
|
|
99
|
+
return noop;
|
|
100
|
+
}
|
|
101
|
+
state.subscriptions.set(callback, new Subscription(state, callback));
|
|
102
|
+
return () => {
|
|
103
|
+
unsubscribe(state, callback);
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function unsubscribe(state, callback) {
|
|
107
|
+
const subscription = state.subscriptions.get(callback);
|
|
108
|
+
state.subscriptions.delete(callback);
|
|
109
|
+
if (subscription != null) {
|
|
110
|
+
subscription.callback = noop;
|
|
111
|
+
subscription.state = undefined;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
54
115
|
let activeComputed;
|
|
55
116
|
class Computed {
|
|
56
117
|
state;
|
|
57
118
|
constructor(callback) {
|
|
119
|
+
Object.defineProperty(this, '$mora', {
|
|
120
|
+
value: 'computed',
|
|
121
|
+
});
|
|
58
122
|
this.state = {
|
|
59
123
|
computeds: new Set(),
|
|
60
124
|
dirty: true,
|
|
61
125
|
effect: undefined,
|
|
62
126
|
effects: new Set(),
|
|
127
|
+
subscriptions: new Map(),
|
|
63
128
|
value: undefined,
|
|
64
129
|
};
|
|
65
130
|
this.state.effect = effect(() => {
|
|
@@ -74,7 +139,10 @@ class Computed {
|
|
|
74
139
|
computed.state.dirty = true;
|
|
75
140
|
}
|
|
76
141
|
for (const effect of this.state.effects) {
|
|
77
|
-
|
|
142
|
+
batchedHandlers.add(effect);
|
|
143
|
+
}
|
|
144
|
+
for (const [, subscription] of this.state.subscriptions) {
|
|
145
|
+
subscription.callback(value);
|
|
78
146
|
}
|
|
79
147
|
}
|
|
80
148
|
this.state.dirty = false;
|
|
@@ -102,6 +170,18 @@ class Computed {
|
|
|
102
170
|
peek() {
|
|
103
171
|
return this.state.value;
|
|
104
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Subscribe to changes
|
|
175
|
+
*/
|
|
176
|
+
subscribe(callback) {
|
|
177
|
+
return subscribe(this.state, callback);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Unsubscribe from changes
|
|
181
|
+
*/
|
|
182
|
+
unsubscribe(callback) {
|
|
183
|
+
unsubscribe(this.state, callback);
|
|
184
|
+
}
|
|
105
185
|
}
|
|
106
186
|
/**
|
|
107
187
|
* Create a computed value
|
|
@@ -113,10 +193,14 @@ function computed(callback) {
|
|
|
113
193
|
class Signal {
|
|
114
194
|
state;
|
|
115
195
|
constructor(value) {
|
|
196
|
+
Object.defineProperty(this, '$mora', {
|
|
197
|
+
value: 'signal',
|
|
198
|
+
});
|
|
116
199
|
this.state = {
|
|
117
200
|
value,
|
|
118
201
|
computeds: new Set(),
|
|
119
202
|
effects: new Set(),
|
|
203
|
+
subscriptions: new Map(),
|
|
120
204
|
};
|
|
121
205
|
}
|
|
122
206
|
/**
|
|
@@ -149,12 +233,27 @@ class Signal {
|
|
|
149
233
|
computed.state.dirty = true;
|
|
150
234
|
}
|
|
151
235
|
for (const effect of this.state.effects) {
|
|
152
|
-
|
|
236
|
+
batchedHandlers.add(effect);
|
|
237
|
+
}
|
|
238
|
+
for (const [, subscription] of this.state.subscriptions) {
|
|
239
|
+
batchedHandlers.add(subscription);
|
|
153
240
|
}
|
|
154
241
|
if (batchDepth === 0) {
|
|
155
242
|
flushEffects();
|
|
156
243
|
}
|
|
157
244
|
}
|
|
245
|
+
/**
|
|
246
|
+
* Subscribe to changes
|
|
247
|
+
*/
|
|
248
|
+
subscribe(callback) {
|
|
249
|
+
return subscribe(this.state, callback);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Unsubscribe from changes
|
|
253
|
+
*/
|
|
254
|
+
unsubscribe(callback) {
|
|
255
|
+
unsubscribe(this.state, callback);
|
|
256
|
+
}
|
|
158
257
|
/**
|
|
159
258
|
* Update the value
|
|
160
259
|
*/
|
|
@@ -166,4 +265,4 @@ function signal(value) {
|
|
|
166
265
|
return new Signal(value);
|
|
167
266
|
}
|
|
168
267
|
|
|
169
|
-
export { computed, effect, signal, startBatch, stopBatch };
|
|
268
|
+
export { computed, effect, isComputed, isEffect, isSignal, signal, startBatch, stopBatch };
|
package/dist/signal.cjs
CHANGED
|
@@ -6,13 +6,18 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
6
6
|
const batch = require("./batch.cjs");
|
|
7
7
|
const computed = require("./computed.cjs");
|
|
8
8
|
const effect = require("./effect.cjs");
|
|
9
|
+
const subscription = require("./subscription.cjs");
|
|
9
10
|
class Signal {
|
|
10
11
|
constructor(value) {
|
|
11
12
|
__publicField(this, "state");
|
|
13
|
+
Object.defineProperty(this, "$mora", {
|
|
14
|
+
value: "signal"
|
|
15
|
+
});
|
|
12
16
|
this.state = {
|
|
13
17
|
value,
|
|
14
18
|
computeds: /* @__PURE__ */ new Set(),
|
|
15
|
-
effects: /* @__PURE__ */ new Set()
|
|
19
|
+
effects: /* @__PURE__ */ new Set(),
|
|
20
|
+
subscriptions: /* @__PURE__ */ new Map()
|
|
16
21
|
};
|
|
17
22
|
}
|
|
18
23
|
/**
|
|
@@ -44,13 +49,28 @@ class Signal {
|
|
|
44
49
|
for (const computed2 of this.state.computeds) {
|
|
45
50
|
computed2.state.dirty = true;
|
|
46
51
|
}
|
|
47
|
-
for (const
|
|
48
|
-
|
|
52
|
+
for (const effect2 of this.state.effects) {
|
|
53
|
+
batch.batchedHandlers.add(effect2);
|
|
54
|
+
}
|
|
55
|
+
for (const [, subscription2] of this.state.subscriptions) {
|
|
56
|
+
batch.batchedHandlers.add(subscription2);
|
|
49
57
|
}
|
|
50
58
|
if (batch.batchDepth === 0) {
|
|
51
59
|
batch.flushEffects();
|
|
52
60
|
}
|
|
53
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Subscribe to changes
|
|
64
|
+
*/
|
|
65
|
+
subscribe(callback) {
|
|
66
|
+
return subscription.subscribe(this.state, callback);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Unsubscribe from changes
|
|
70
|
+
*/
|
|
71
|
+
unsubscribe(callback) {
|
|
72
|
+
subscription.unsubscribe(this.state, callback);
|
|
73
|
+
}
|
|
54
74
|
/**
|
|
55
75
|
* Update the value
|
|
56
76
|
*/
|
package/dist/signal.js
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
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 { flushEffects, batchDepth } from "./batch.js";
|
|
4
|
+
import { batchedHandlers, flushEffects, batchDepth } from "./batch.js";
|
|
5
5
|
import { activeComputed } from "./computed.js";
|
|
6
|
-
import { activeEffect
|
|
6
|
+
import { activeEffect } from "./effect.js";
|
|
7
|
+
import { subscribe, unsubscribe } from "./subscription.js";
|
|
7
8
|
class Signal {
|
|
8
9
|
constructor(value) {
|
|
9
10
|
__publicField(this, "state");
|
|
11
|
+
Object.defineProperty(this, "$mora", {
|
|
12
|
+
value: "signal"
|
|
13
|
+
});
|
|
10
14
|
this.state = {
|
|
11
15
|
value,
|
|
12
16
|
computeds: /* @__PURE__ */ new Set(),
|
|
13
|
-
effects: /* @__PURE__ */ new Set()
|
|
17
|
+
effects: /* @__PURE__ */ new Set(),
|
|
18
|
+
subscriptions: /* @__PURE__ */ new Map()
|
|
14
19
|
};
|
|
15
20
|
}
|
|
16
21
|
/**
|
|
@@ -43,12 +48,27 @@ class Signal {
|
|
|
43
48
|
computed.state.dirty = true;
|
|
44
49
|
}
|
|
45
50
|
for (const effect of this.state.effects) {
|
|
46
|
-
|
|
51
|
+
batchedHandlers.add(effect);
|
|
52
|
+
}
|
|
53
|
+
for (const [, subscription] of this.state.subscriptions) {
|
|
54
|
+
batchedHandlers.add(subscription);
|
|
47
55
|
}
|
|
48
56
|
if (batchDepth === 0) {
|
|
49
57
|
flushEffects();
|
|
50
58
|
}
|
|
51
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Subscribe to changes
|
|
62
|
+
*/
|
|
63
|
+
subscribe(callback) {
|
|
64
|
+
return subscribe(this.state, callback);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Unsubscribe from changes
|
|
68
|
+
*/
|
|
69
|
+
unsubscribe(callback) {
|
|
70
|
+
unsubscribe(this.state, callback);
|
|
71
|
+
}
|
|
52
72
|
/**
|
|
53
73
|
* Update the value
|
|
54
74
|
*/
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
class Subscription {
|
|
4
|
+
constructor(state, callback) {
|
|
5
|
+
this.state = state;
|
|
6
|
+
this.callback = callback;
|
|
7
|
+
callback(state.value);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function noop() {
|
|
11
|
+
}
|
|
12
|
+
function subscribe(state, callback) {
|
|
13
|
+
if (typeof callback !== "function" || state.subscriptions.has(callback)) {
|
|
14
|
+
return noop;
|
|
15
|
+
}
|
|
16
|
+
state.subscriptions.set(callback, new Subscription(state, callback));
|
|
17
|
+
return () => {
|
|
18
|
+
unsubscribe(state, callback);
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function unsubscribe(state, callback) {
|
|
22
|
+
const subscription = state.subscriptions.get(callback);
|
|
23
|
+
state.subscriptions.delete(callback);
|
|
24
|
+
if (subscription != null) {
|
|
25
|
+
subscription.callback = noop;
|
|
26
|
+
subscription.state = void 0;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.Subscription = Subscription;
|
|
30
|
+
exports.noop = noop;
|
|
31
|
+
exports.subscribe = subscribe;
|
|
32
|
+
exports.unsubscribe = unsubscribe;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class Subscription {
|
|
2
|
+
constructor(state, callback) {
|
|
3
|
+
this.state = state;
|
|
4
|
+
this.callback = callback;
|
|
5
|
+
callback(state.value);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
function noop() {
|
|
9
|
+
}
|
|
10
|
+
function subscribe(state, callback) {
|
|
11
|
+
if (typeof callback !== "function" || state.subscriptions.has(callback)) {
|
|
12
|
+
return noop;
|
|
13
|
+
}
|
|
14
|
+
state.subscriptions.set(callback, new Subscription(state, callback));
|
|
15
|
+
return () => {
|
|
16
|
+
unsubscribe(state, callback);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function unsubscribe(state, callback) {
|
|
20
|
+
const subscription = state.subscriptions.get(callback);
|
|
21
|
+
state.subscriptions.delete(callback);
|
|
22
|
+
if (subscription != null) {
|
|
23
|
+
subscription.callback = noop;
|
|
24
|
+
subscription.state = void 0;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
Subscription,
|
|
29
|
+
noop,
|
|
30
|
+
subscribe,
|
|
31
|
+
unsubscribe
|
|
32
|
+
};
|
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.10.0"
|
|
56
58
|
}
|