@oscarpalmer/mora 0.9.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 +18 -1
- package/dist/computed.js +20 -3
- package/dist/effect.cjs +0 -2
- package/dist/effect.js +0 -2
- package/dist/mora.full.js +98 -33
- package/dist/signal.cjs +20 -3
- package/dist/signal.js +21 -4
- package/dist/subscription.cjs +32 -0
- package/dist/subscription.js +32 -0
- package/package.json +1 -1
- package/src/batch.ts +14 -6
- package/src/computed.ts +79 -58
- package/src/effect.ts +0 -2
- package/src/signal.ts +82 -55
- 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 +21 -0
- package/types/computed.d.ts +12 -2
- package/types/effect.d.cts +0 -1
- package/types/effect.d.ts +0 -1
- package/types/index.d.cts +38 -21
- package/types/is.d.cts +31 -14
- package/types/signal.d.cts +55 -0
- package/types/signal.d.ts +18 -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,6 +5,7 @@ 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) {
|
|
@@ -17,6 +18,7 @@ class Computed {
|
|
|
17
18
|
dirty: true,
|
|
18
19
|
effect: void 0,
|
|
19
20
|
effects: /* @__PURE__ */ new Set(),
|
|
21
|
+
subscriptions: /* @__PURE__ */ new Map(),
|
|
20
22
|
value: void 0
|
|
21
23
|
};
|
|
22
24
|
this.state.effect = effect.effect(() => {
|
|
@@ -31,7 +33,10 @@ class Computed {
|
|
|
31
33
|
computed2.state.dirty = true;
|
|
32
34
|
}
|
|
33
35
|
for (const effect2 of this.state.effects) {
|
|
34
|
-
|
|
36
|
+
batch.batchedHandlers.add(effect2);
|
|
37
|
+
}
|
|
38
|
+
for (const [, subscription2] of this.state.subscriptions) {
|
|
39
|
+
subscription2.callback(value);
|
|
35
40
|
}
|
|
36
41
|
}
|
|
37
42
|
this.state.dirty = false;
|
|
@@ -59,6 +64,18 @@ class Computed {
|
|
|
59
64
|
peek() {
|
|
60
65
|
return this.state.value;
|
|
61
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
|
+
}
|
|
62
79
|
}
|
|
63
80
|
function computed(callback) {
|
|
64
81
|
return new Computed(callback);
|
package/dist/computed.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
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) {
|
|
@@ -15,6 +16,7 @@ class Computed {
|
|
|
15
16
|
dirty: true,
|
|
16
17
|
effect: void 0,
|
|
17
18
|
effects: /* @__PURE__ */ new Set(),
|
|
19
|
+
subscriptions: /* @__PURE__ */ new Map(),
|
|
18
20
|
value: void 0
|
|
19
21
|
};
|
|
20
22
|
this.state.effect = effect(() => {
|
|
@@ -29,7 +31,10 @@ class Computed {
|
|
|
29
31
|
computed2.state.dirty = true;
|
|
30
32
|
}
|
|
31
33
|
for (const effect2 of this.state.effects) {
|
|
32
|
-
|
|
34
|
+
batchedHandlers.add(effect2);
|
|
35
|
+
}
|
|
36
|
+
for (const [, subscription] of this.state.subscriptions) {
|
|
37
|
+
subscription.callback(value);
|
|
33
38
|
}
|
|
34
39
|
}
|
|
35
40
|
this.state.dirty = false;
|
|
@@ -57,6 +62,18 @@ class Computed {
|
|
|
57
62
|
peek() {
|
|
58
63
|
return this.state.value;
|
|
59
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
|
+
}
|
|
60
77
|
}
|
|
61
78
|
function computed(callback) {
|
|
62
79
|
return new Computed(callback);
|
package/dist/effect.cjs
CHANGED
|
@@ -24,8 +24,6 @@ function effect(callback) {
|
|
|
24
24
|
return new Effect(callback);
|
|
25
25
|
}
|
|
26
26
|
exports.activeEffect = void 0;
|
|
27
|
-
const dirtyEffects = /* @__PURE__ */ new Set();
|
|
28
27
|
exports.Effect = Effect;
|
|
29
|
-
exports.dirtyEffects = dirtyEffects;
|
|
30
28
|
exports.effect = effect;
|
|
31
29
|
exports.runEffect = runEffect;
|
package/dist/effect.js
CHANGED
package/dist/mora.full.js
CHANGED
|
@@ -26,14 +26,43 @@ function effect(callback) {
|
|
|
26
26
|
return new Effect(callback);
|
|
27
27
|
}
|
|
28
28
|
let activeEffect;
|
|
29
|
-
|
|
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
|
+
}
|
|
30
54
|
|
|
31
55
|
function flushEffects() {
|
|
32
|
-
while (batchDepth === 0 &&
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
for (const
|
|
36
|
-
|
|
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
|
+
}
|
|
37
66
|
}
|
|
38
67
|
}
|
|
39
68
|
}
|
|
@@ -52,8 +81,37 @@ function stopBatch() {
|
|
|
52
81
|
}
|
|
53
82
|
flushEffects();
|
|
54
83
|
}
|
|
84
|
+
const batchedHandlers = new Set();
|
|
55
85
|
let batchDepth = 0;
|
|
56
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
|
+
|
|
57
115
|
let activeComputed;
|
|
58
116
|
class Computed {
|
|
59
117
|
state;
|
|
@@ -66,6 +124,7 @@ class Computed {
|
|
|
66
124
|
dirty: true,
|
|
67
125
|
effect: undefined,
|
|
68
126
|
effects: new Set(),
|
|
127
|
+
subscriptions: new Map(),
|
|
69
128
|
value: undefined,
|
|
70
129
|
};
|
|
71
130
|
this.state.effect = effect(() => {
|
|
@@ -80,7 +139,10 @@ class Computed {
|
|
|
80
139
|
computed.state.dirty = true;
|
|
81
140
|
}
|
|
82
141
|
for (const effect of this.state.effects) {
|
|
83
|
-
|
|
142
|
+
batchedHandlers.add(effect);
|
|
143
|
+
}
|
|
144
|
+
for (const [, subscription] of this.state.subscriptions) {
|
|
145
|
+
subscription.callback(value);
|
|
84
146
|
}
|
|
85
147
|
}
|
|
86
148
|
this.state.dirty = false;
|
|
@@ -108,6 +170,18 @@ class Computed {
|
|
|
108
170
|
peek() {
|
|
109
171
|
return this.state.value;
|
|
110
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
|
+
}
|
|
111
185
|
}
|
|
112
186
|
/**
|
|
113
187
|
* Create a computed value
|
|
@@ -116,31 +190,6 @@ function computed(callback) {
|
|
|
116
190
|
return new Computed(callback);
|
|
117
191
|
}
|
|
118
192
|
|
|
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
|
-
|
|
144
193
|
class Signal {
|
|
145
194
|
state;
|
|
146
195
|
constructor(value) {
|
|
@@ -151,6 +200,7 @@ class Signal {
|
|
|
151
200
|
value,
|
|
152
201
|
computeds: new Set(),
|
|
153
202
|
effects: new Set(),
|
|
203
|
+
subscriptions: new Map(),
|
|
154
204
|
};
|
|
155
205
|
}
|
|
156
206
|
/**
|
|
@@ -183,12 +233,27 @@ class Signal {
|
|
|
183
233
|
computed.state.dirty = true;
|
|
184
234
|
}
|
|
185
235
|
for (const effect of this.state.effects) {
|
|
186
|
-
|
|
236
|
+
batchedHandlers.add(effect);
|
|
237
|
+
}
|
|
238
|
+
for (const [, subscription] of this.state.subscriptions) {
|
|
239
|
+
batchedHandlers.add(subscription);
|
|
187
240
|
}
|
|
188
241
|
if (batchDepth === 0) {
|
|
189
242
|
flushEffects();
|
|
190
243
|
}
|
|
191
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
|
+
}
|
|
192
257
|
/**
|
|
193
258
|
* Update the value
|
|
194
259
|
*/
|
package/dist/signal.cjs
CHANGED
|
@@ -6,6 +6,7 @@ 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");
|
|
@@ -15,7 +16,8 @@ class Signal {
|
|
|
15
16
|
this.state = {
|
|
16
17
|
value,
|
|
17
18
|
computeds: /* @__PURE__ */ new Set(),
|
|
18
|
-
effects: /* @__PURE__ */ new Set()
|
|
19
|
+
effects: /* @__PURE__ */ new Set(),
|
|
20
|
+
subscriptions: /* @__PURE__ */ new Map()
|
|
19
21
|
};
|
|
20
22
|
}
|
|
21
23
|
/**
|
|
@@ -47,13 +49,28 @@ class Signal {
|
|
|
47
49
|
for (const computed2 of this.state.computeds) {
|
|
48
50
|
computed2.state.dirty = true;
|
|
49
51
|
}
|
|
50
|
-
for (const
|
|
51
|
-
|
|
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);
|
|
52
57
|
}
|
|
53
58
|
if (batch.batchDepth === 0) {
|
|
54
59
|
batch.flushEffects();
|
|
55
60
|
}
|
|
56
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
|
+
}
|
|
57
74
|
/**
|
|
58
75
|
* Update the value
|
|
59
76
|
*/
|
package/dist/signal.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
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");
|
|
@@ -13,7 +14,8 @@ class Signal {
|
|
|
13
14
|
this.state = {
|
|
14
15
|
value,
|
|
15
16
|
computeds: /* @__PURE__ */ new Set(),
|
|
16
|
-
effects: /* @__PURE__ */ new Set()
|
|
17
|
+
effects: /* @__PURE__ */ new Set(),
|
|
18
|
+
subscriptions: /* @__PURE__ */ new Map()
|
|
17
19
|
};
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
@@ -46,12 +48,27 @@ class Signal {
|
|
|
46
48
|
computed.state.dirty = true;
|
|
47
49
|
}
|
|
48
50
|
for (const effect of this.state.effects) {
|
|
49
|
-
|
|
51
|
+
batchedHandlers.add(effect);
|
|
52
|
+
}
|
|
53
|
+
for (const [, subscription] of this.state.subscriptions) {
|
|
54
|
+
batchedHandlers.add(subscription);
|
|
50
55
|
}
|
|
51
56
|
if (batchDepth === 0) {
|
|
52
57
|
flushEffects();
|
|
53
58
|
}
|
|
54
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
|
+
}
|
|
55
72
|
/**
|
|
56
73
|
* Update the value
|
|
57
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
package/src/batch.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {type Effect, runEffect} from './effect';
|
|
2
|
+
import {isEffect} from './is';
|
|
3
|
+
import type {Subscription} from './subscription';
|
|
2
4
|
|
|
3
5
|
export function flushEffects(): void {
|
|
4
|
-
while (batchDepth === 0 &&
|
|
5
|
-
const
|
|
6
|
+
while (batchDepth === 0 && batchedHandlers.size > 0) {
|
|
7
|
+
const handlers = [...batchedHandlers];
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
batchedHandlers.clear();
|
|
8
10
|
|
|
9
|
-
for (const
|
|
10
|
-
|
|
11
|
+
for (const handler of handlers) {
|
|
12
|
+
if (isEffect(handler)) {
|
|
13
|
+
runEffect(handler);
|
|
14
|
+
} else {
|
|
15
|
+
handler.callback(handler.state.value);
|
|
16
|
+
}
|
|
11
17
|
}
|
|
12
18
|
}
|
|
13
19
|
}
|
|
@@ -30,4 +36,6 @@ export function stopBatch(): void {
|
|
|
30
36
|
flushEffects();
|
|
31
37
|
}
|
|
32
38
|
|
|
39
|
+
export const batchedHandlers = new Set<Effect | Subscription>();
|
|
40
|
+
|
|
33
41
|
export let batchDepth = 0;
|