@esportsplus/reactivity 0.30.3 → 0.31.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/build/constants.d.ts +2 -1
- package/build/constants.js +2 -1
- package/build/reactive/object.js +7 -9
- package/build/system.d.ts +2 -1
- package/build/system.js +31 -20
- package/build/types.d.ts +2 -3
- package/package.json +1 -1
- package/src/constants.ts +3 -1
- package/src/reactive/object.ts +12 -12
- package/src/system.ts +42 -28
- package/src/types.ts +2 -8
- package/tests/array.ts +249 -0
- package/tests/async-computed.ts +195 -0
- package/tests/bench/array.ts +65 -0
- package/tests/bench/reactive-object.ts +54 -0
- package/tests/bench/system.ts +88 -1
- package/tests/compiler.ts +326 -0
- package/tests/reactive.ts +210 -0
- package/tests/system.ts +359 -0
- package/tests/tsconfig.json +17 -0
package/build/constants.d.ts
CHANGED
|
@@ -12,5 +12,6 @@ declare const STATE_CHECK: number;
|
|
|
12
12
|
declare const STATE_DIRTY: number;
|
|
13
13
|
declare const STATE_RECOMPUTING: number;
|
|
14
14
|
declare const STATE_IN_HEAP: number;
|
|
15
|
+
declare const STATE_COMPUTED: number;
|
|
15
16
|
declare const STATE_NOTIFY_MASK: number;
|
|
16
|
-
export { COMPUTED, REACTIVE_ARRAY, REACTIVE_OBJECT, PACKAGE_NAME, SIGNAL, STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_NOTIFY_MASK, STATE_RECOMPUTING };
|
|
17
|
+
export { COMPUTED, REACTIVE_ARRAY, REACTIVE_OBJECT, PACKAGE_NAME, SIGNAL, STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_COMPUTED, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_NOTIFY_MASK, STATE_RECOMPUTING };
|
package/build/constants.js
CHANGED
|
@@ -12,5 +12,6 @@ const STATE_CHECK = 1 << 0;
|
|
|
12
12
|
const STATE_DIRTY = 1 << 1;
|
|
13
13
|
const STATE_RECOMPUTING = 1 << 2;
|
|
14
14
|
const STATE_IN_HEAP = 1 << 3;
|
|
15
|
+
const STATE_COMPUTED = 1 << 4;
|
|
15
16
|
const STATE_NOTIFY_MASK = (STATE_CHECK | STATE_DIRTY);
|
|
16
|
-
export { COMPUTED, REACTIVE_ARRAY, REACTIVE_OBJECT, PACKAGE_NAME, SIGNAL, STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_NOTIFY_MASK, STATE_RECOMPUTING };
|
|
17
|
+
export { COMPUTED, REACTIVE_ARRAY, REACTIVE_OBJECT, PACKAGE_NAME, SIGNAL, STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_COMPUTED, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_NOTIFY_MASK, STATE_RECOMPUTING };
|
package/build/reactive/object.js
CHANGED
|
@@ -49,21 +49,19 @@ class ReactiveObject {
|
|
|
49
49
|
return root(() => {
|
|
50
50
|
let node = computed(value);
|
|
51
51
|
if (isPromise(node.value)) {
|
|
52
|
-
let factory = node,
|
|
53
|
-
node = signal(undefined);
|
|
52
|
+
let factory = node, out = signal(undefined), v = 0;
|
|
54
53
|
(this.disposers ??= []).push(effect(() => {
|
|
55
|
-
let id = ++
|
|
56
|
-
read(factory).then((
|
|
57
|
-
if (id !==
|
|
54
|
+
let id = ++v;
|
|
55
|
+
read(factory).then((resolved) => {
|
|
56
|
+
if (id !== v) {
|
|
58
57
|
return;
|
|
59
58
|
}
|
|
60
|
-
write(
|
|
59
|
+
write(out, resolved);
|
|
61
60
|
});
|
|
62
61
|
}));
|
|
62
|
+
return out;
|
|
63
63
|
}
|
|
64
|
-
|
|
65
|
-
(this.disposers ??= []).push(() => dispose(node));
|
|
66
|
-
}
|
|
64
|
+
(this.disposers ??= []).push(() => dispose(node));
|
|
67
65
|
return node;
|
|
68
66
|
});
|
|
69
67
|
}
|
package/build/system.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Computed, Signal } from './types.js';
|
|
2
|
+
declare const asyncComputed: <T>(fn: Computed<Promise<T>>["fn"]) => Signal<T | undefined>;
|
|
2
3
|
declare const computed: <T>(fn: Computed<T>["fn"]) => Computed<T>;
|
|
3
4
|
declare const dispose: <T>(computed: Computed<T>) => void;
|
|
4
5
|
declare const effect: <T>(fn: Computed<T>["fn"]) => () => void;
|
|
@@ -12,5 +13,5 @@ declare const root: {
|
|
|
12
13
|
};
|
|
13
14
|
declare const signal: <T>(value: T) => Signal<T>;
|
|
14
15
|
declare const write: <T>(signal: Signal<T>, value: T) => void;
|
|
15
|
-
export { computed, dispose, effect, isComputed, isSignal, onCleanup, read, root, signal, write };
|
|
16
|
+
export { asyncComputed, computed, dispose, effect, isComputed, isSignal, onCleanup, read, root, signal, write };
|
|
16
17
|
export type { Computed, Signal };
|
package/build/system.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SIGNAL, STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_COMPUTED, STATE_DIRTY, STATE_IN_HEAP, STATE_NOTIFY_MASK, STATE_RECOMPUTING } from './constants.js';
|
|
2
2
|
import { isObject } from '@esportsplus/utilities';
|
|
3
|
-
let depth = 0, heap = new Array(64), heap_i = 0, heap_n = 0,
|
|
3
|
+
let depth = 0, heap = new Array(64), heap_i = 0, heap_n = 0, linkPoolHead = null, microtask = queueMicrotask, notified = false, observer = null, scope = null, stabilizer = STABILIZER_IDLE, version = 0;
|
|
4
4
|
function cleanup(computed) {
|
|
5
5
|
if (!computed.cleanup) {
|
|
6
6
|
return;
|
|
@@ -82,9 +82,10 @@ function link(dep, sub) {
|
|
|
82
82
|
prevSub.sub === sub) {
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
|
-
let pooled =
|
|
85
|
+
let pooled = linkPoolHead, newLink = sub.depsTail =
|
|
86
86
|
dep.subsTail = pooled
|
|
87
|
-
? (
|
|
87
|
+
? (linkPoolHead = pooled.nextDep,
|
|
88
|
+
pooled.dep = dep,
|
|
88
89
|
pooled.sub = sub,
|
|
89
90
|
pooled.nextDep = nextDep,
|
|
90
91
|
pooled.prevSub = prevSub,
|
|
@@ -136,7 +137,7 @@ function recompute(computed, del) {
|
|
|
136
137
|
let o = observer, ok = true, value;
|
|
137
138
|
observer = computed;
|
|
138
139
|
computed.depsTail = null;
|
|
139
|
-
computed.state = STATE_RECOMPUTING;
|
|
140
|
+
computed.state = STATE_COMPUTED | STATE_RECOMPUTING;
|
|
140
141
|
depth++;
|
|
141
142
|
version++;
|
|
142
143
|
try {
|
|
@@ -147,7 +148,7 @@ function recompute(computed, del) {
|
|
|
147
148
|
}
|
|
148
149
|
depth--;
|
|
149
150
|
observer = o;
|
|
150
|
-
computed.state =
|
|
151
|
+
computed.state = STATE_COMPUTED;
|
|
151
152
|
let depsTail = computed.depsTail, remove = depsTail ? depsTail.nextDep : computed.deps;
|
|
152
153
|
if (remove) {
|
|
153
154
|
do {
|
|
@@ -220,21 +221,20 @@ function unlink(link) {
|
|
|
220
221
|
if (prevSub) {
|
|
221
222
|
prevSub.nextSub = nextSub;
|
|
222
223
|
}
|
|
223
|
-
else if ((dep.subs = nextSub) === null && dep.
|
|
224
|
+
else if ((dep.subs = nextSub) === null && dep.state & STATE_COMPUTED) {
|
|
224
225
|
dispose(dep);
|
|
225
226
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
227
|
+
link.dep = link.sub = null;
|
|
228
|
+
link.nextSub = link.prevSub = null;
|
|
229
|
+
link.nextDep = linkPoolHead;
|
|
230
|
+
linkPoolHead = link;
|
|
231
231
|
return nextDep;
|
|
232
232
|
}
|
|
233
233
|
function update(computed) {
|
|
234
234
|
if (computed.state & STATE_CHECK) {
|
|
235
235
|
for (let link = computed.deps; link; link = link.nextDep) {
|
|
236
236
|
let dep = link.dep;
|
|
237
|
-
if (dep.
|
|
237
|
+
if (dep.state & STATE_COMPUTED) {
|
|
238
238
|
update(dep);
|
|
239
239
|
if (computed.state & STATE_DIRTY) {
|
|
240
240
|
break;
|
|
@@ -245,8 +245,20 @@ function update(computed) {
|
|
|
245
245
|
if (computed.state & STATE_DIRTY) {
|
|
246
246
|
recompute(computed, true);
|
|
247
247
|
}
|
|
248
|
-
computed.state =
|
|
248
|
+
computed.state = STATE_COMPUTED;
|
|
249
249
|
}
|
|
250
|
+
const asyncComputed = (fn) => {
|
|
251
|
+
let factory = computed(fn), node = signal(undefined), v = 0;
|
|
252
|
+
onCleanup(effect(() => {
|
|
253
|
+
let id = ++v;
|
|
254
|
+
read(factory).then((value) => {
|
|
255
|
+
if (id === v) {
|
|
256
|
+
write(node, value);
|
|
257
|
+
}
|
|
258
|
+
}, () => { });
|
|
259
|
+
}));
|
|
260
|
+
return node;
|
|
261
|
+
};
|
|
250
262
|
const computed = (fn) => {
|
|
251
263
|
let self = {
|
|
252
264
|
cleanup: null,
|
|
@@ -256,10 +268,9 @@ const computed = (fn) => {
|
|
|
256
268
|
height: 0,
|
|
257
269
|
nextHeap: undefined,
|
|
258
270
|
prevHeap: null,
|
|
259
|
-
state:
|
|
271
|
+
state: STATE_COMPUTED,
|
|
260
272
|
subs: null,
|
|
261
273
|
subsTail: null,
|
|
262
|
-
type: COMPUTED,
|
|
263
274
|
value: undefined,
|
|
264
275
|
};
|
|
265
276
|
self.prevHeap = self;
|
|
@@ -303,7 +314,7 @@ const effect = (fn) => {
|
|
|
303
314
|
};
|
|
304
315
|
};
|
|
305
316
|
const isComputed = (value) => {
|
|
306
|
-
return isObject(value) && value.
|
|
317
|
+
return isObject(value) && !!(value.state & STATE_COMPUTED);
|
|
307
318
|
};
|
|
308
319
|
const isSignal = (value) => {
|
|
309
320
|
return isObject(value) && value.type === SIGNAL;
|
|
@@ -328,7 +339,7 @@ const onCleanup = (fn) => {
|
|
|
328
339
|
const read = (node) => {
|
|
329
340
|
if (observer) {
|
|
330
341
|
link(node, observer);
|
|
331
|
-
if (node.
|
|
342
|
+
if (node.state & STATE_COMPUTED) {
|
|
332
343
|
let height = node.height;
|
|
333
344
|
if (height >= observer.height) {
|
|
334
345
|
observer.height = height + 1;
|
|
@@ -353,7 +364,7 @@ const root = (fn) => {
|
|
|
353
364
|
observer = null;
|
|
354
365
|
root.disposables = 0;
|
|
355
366
|
if (tracking) {
|
|
356
|
-
scope = self = { cleanup: null };
|
|
367
|
+
scope = self = { cleanup: null, state: STATE_COMPUTED };
|
|
357
368
|
value = fn(c = () => dispose(self));
|
|
358
369
|
}
|
|
359
370
|
else {
|
|
@@ -391,4 +402,4 @@ const write = (signal, value) => {
|
|
|
391
402
|
}
|
|
392
403
|
schedule();
|
|
393
404
|
};
|
|
394
|
-
export { computed, dispose, effect, isComputed, isSignal, onCleanup, read, root, signal, write };
|
|
405
|
+
export { asyncComputed, computed, dispose, effect, isComputed, isSignal, onCleanup, read, root, signal, write };
|
package/build/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ts } from '@esportsplus/typescript';
|
|
2
|
-
import {
|
|
2
|
+
import { SIGNAL } from './constants.js';
|
|
3
3
|
import { ReactiveArray } from './reactive/index.js';
|
|
4
4
|
interface Computed<T> {
|
|
5
5
|
cleanup: VoidFunction | VoidFunction[] | null;
|
|
@@ -9,10 +9,9 @@ interface Computed<T> {
|
|
|
9
9
|
height: number;
|
|
10
10
|
nextHeap: Computed<unknown> | undefined;
|
|
11
11
|
prevHeap: Computed<unknown>;
|
|
12
|
-
state:
|
|
12
|
+
state: number;
|
|
13
13
|
subs: Link | null;
|
|
14
14
|
subsTail: Link | null;
|
|
15
|
-
type: typeof COMPUTED;
|
|
16
15
|
value: T;
|
|
17
16
|
}
|
|
18
17
|
interface Link {
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
|
@@ -26,6 +26,8 @@ const STATE_RECOMPUTING = 1 << 2;
|
|
|
26
26
|
|
|
27
27
|
const STATE_IN_HEAP = 1 << 3;
|
|
28
28
|
|
|
29
|
+
const STATE_COMPUTED = 1 << 4;
|
|
30
|
+
|
|
29
31
|
const STATE_NOTIFY_MASK = (STATE_CHECK | STATE_DIRTY);
|
|
30
32
|
|
|
31
33
|
|
|
@@ -35,5 +37,5 @@ export {
|
|
|
35
37
|
PACKAGE_NAME,
|
|
36
38
|
SIGNAL,
|
|
37
39
|
STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED,
|
|
38
|
-
STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_NOTIFY_MASK, STATE_RECOMPUTING
|
|
40
|
+
STATE_CHECK, STATE_COMPUTED, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_NOTIFY_MASK, STATE_RECOMPUTING
|
|
39
41
|
};
|
package/src/reactive/object.ts
CHANGED
|
@@ -72,29 +72,29 @@ class ReactiveObject<T extends Record<PropertyKey, unknown>> {
|
|
|
72
72
|
let node: Computed<ReturnType<T>> | Signal<ReturnType<T> | undefined> = computed(value);
|
|
73
73
|
|
|
74
74
|
if (isPromise(node.value)) {
|
|
75
|
-
let factory = node
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
node = signal<ReturnType<T> | undefined>(undefined);
|
|
75
|
+
let factory = node as Computed<ReturnType<T>>,
|
|
76
|
+
out = signal<ReturnType<T> | undefined>(undefined),
|
|
77
|
+
v = 0;
|
|
79
78
|
|
|
80
79
|
(this.disposers ??= []).push(
|
|
81
80
|
effect(() => {
|
|
82
|
-
let id = ++
|
|
81
|
+
let id = ++v;
|
|
83
82
|
|
|
84
|
-
(read(factory) as Promise<ReturnType<T>>).then((
|
|
85
|
-
if (id !==
|
|
83
|
+
(read(factory) as Promise<ReturnType<T>>).then((resolved) => {
|
|
84
|
+
if (id !== v) {
|
|
86
85
|
return;
|
|
87
86
|
}
|
|
88
87
|
|
|
89
|
-
write(
|
|
88
|
+
write(out as Signal<typeof resolved>, resolved);
|
|
90
89
|
});
|
|
91
90
|
})
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
(this.disposers ??= []).push(() => dispose(node as Computed<ReturnType<T>>));
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
return out;
|
|
96
94
|
}
|
|
97
95
|
|
|
96
|
+
(this.disposers ??= []).push(() => dispose(node as Computed<ReturnType<T>>));
|
|
97
|
+
|
|
98
98
|
return node;
|
|
99
99
|
});
|
|
100
100
|
}
|
package/src/system.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
COMPUTED,
|
|
3
2
|
SIGNAL,
|
|
4
3
|
STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED,
|
|
5
|
-
STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP,
|
|
4
|
+
STATE_CHECK, STATE_COMPUTED, STATE_DIRTY, STATE_IN_HEAP, STATE_NOTIFY_MASK, STATE_RECOMPUTING
|
|
6
5
|
} from './constants';
|
|
7
6
|
import { Computed, Link, Signal } from './types';
|
|
8
7
|
import { isObject } from '@esportsplus/utilities';
|
|
@@ -12,8 +11,7 @@ let depth = 0,
|
|
|
12
11
|
heap: (Computed<unknown> | undefined)[] = new Array(64),
|
|
13
12
|
heap_i = 0,
|
|
14
13
|
heap_n = 0,
|
|
15
|
-
|
|
16
|
-
linkPoolMax = 1000,
|
|
14
|
+
linkPoolHead: Link | null = null,
|
|
17
15
|
microtask = queueMicrotask,
|
|
18
16
|
notified = false,
|
|
19
17
|
observer: Computed<unknown> | null = null,
|
|
@@ -138,11 +136,12 @@ function link<T>(dep: Signal<T> | Computed<T>, sub: Computed<T>) {
|
|
|
138
136
|
return;
|
|
139
137
|
}
|
|
140
138
|
|
|
141
|
-
let pooled =
|
|
139
|
+
let pooled = linkPoolHead,
|
|
142
140
|
newLink =
|
|
143
141
|
sub.depsTail =
|
|
144
142
|
dep.subsTail = pooled
|
|
145
|
-
? (
|
|
143
|
+
? (linkPoolHead = pooled.nextDep,
|
|
144
|
+
pooled.dep = dep,
|
|
146
145
|
pooled.sub = sub,
|
|
147
146
|
pooled.nextDep = nextDep,
|
|
148
147
|
pooled.prevSub = prevSub,
|
|
@@ -206,7 +205,7 @@ function recompute<T>(computed: Computed<T>, del: boolean) {
|
|
|
206
205
|
|
|
207
206
|
observer = computed;
|
|
208
207
|
computed.depsTail = null;
|
|
209
|
-
computed.state = STATE_RECOMPUTING;
|
|
208
|
+
computed.state = STATE_COMPUTED | STATE_RECOMPUTING;
|
|
210
209
|
|
|
211
210
|
depth++;
|
|
212
211
|
version++;
|
|
@@ -220,7 +219,7 @@ function recompute<T>(computed: Computed<T>, del: boolean) {
|
|
|
220
219
|
|
|
221
220
|
depth--;
|
|
222
221
|
observer = o;
|
|
223
|
-
computed.state =
|
|
222
|
+
computed.state = STATE_COMPUTED;
|
|
224
223
|
|
|
225
224
|
let depsTail = computed.depsTail as Link | null,
|
|
226
225
|
remove = depsTail ? depsTail.nextDep : computed.deps;
|
|
@@ -323,16 +322,14 @@ function unlink(link: Link): Link | null {
|
|
|
323
322
|
if (prevSub) {
|
|
324
323
|
prevSub.nextSub = nextSub;
|
|
325
324
|
}
|
|
326
|
-
else if ((dep.subs = nextSub) === null && dep.
|
|
327
|
-
dispose(dep);
|
|
325
|
+
else if ((dep.subs = nextSub) === null && (dep as Computed<unknown>).state & STATE_COMPUTED) {
|
|
326
|
+
dispose(dep as Computed<unknown>);
|
|
328
327
|
}
|
|
329
328
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
linkPool.push(link);
|
|
335
|
-
}
|
|
329
|
+
link.dep = link.sub = null as any;
|
|
330
|
+
link.nextSub = link.prevSub = null;
|
|
331
|
+
link.nextDep = linkPoolHead;
|
|
332
|
+
linkPoolHead = link;
|
|
336
333
|
|
|
337
334
|
return nextDep;
|
|
338
335
|
}
|
|
@@ -342,8 +339,8 @@ function update<T>(computed: Computed<T>): void {
|
|
|
342
339
|
for (let link = computed.deps; link; link = link.nextDep) {
|
|
343
340
|
let dep = link.dep;
|
|
344
341
|
|
|
345
|
-
if (dep.
|
|
346
|
-
update(dep);
|
|
342
|
+
if ((dep as Computed<unknown>).state & STATE_COMPUTED) {
|
|
343
|
+
update(dep as Computed<unknown>);
|
|
347
344
|
|
|
348
345
|
if (computed.state & STATE_DIRTY) {
|
|
349
346
|
break;
|
|
@@ -356,10 +353,28 @@ function update<T>(computed: Computed<T>): void {
|
|
|
356
353
|
recompute(computed, true);
|
|
357
354
|
}
|
|
358
355
|
|
|
359
|
-
computed.state =
|
|
356
|
+
computed.state = STATE_COMPUTED;
|
|
360
357
|
}
|
|
361
358
|
|
|
362
359
|
|
|
360
|
+
const asyncComputed = <T>(fn: Computed<Promise<T>>['fn']): Signal<T | undefined> => {
|
|
361
|
+
let factory = computed(fn),
|
|
362
|
+
node = signal<T | undefined>(undefined),
|
|
363
|
+
v = 0;
|
|
364
|
+
|
|
365
|
+
onCleanup(effect(() => {
|
|
366
|
+
let id = ++v;
|
|
367
|
+
|
|
368
|
+
(read(factory) as Promise<T>).then((value) => {
|
|
369
|
+
if (id === v) {
|
|
370
|
+
write(node, value);
|
|
371
|
+
}
|
|
372
|
+
}, () => {});
|
|
373
|
+
}));
|
|
374
|
+
|
|
375
|
+
return node;
|
|
376
|
+
};
|
|
377
|
+
|
|
363
378
|
const computed = <T>(fn: Computed<T>['fn']): Computed<T> => {
|
|
364
379
|
let self: Computed<T> = {
|
|
365
380
|
cleanup: null,
|
|
@@ -369,10 +384,9 @@ const computed = <T>(fn: Computed<T>['fn']): Computed<T> => {
|
|
|
369
384
|
height: 0,
|
|
370
385
|
nextHeap: undefined,
|
|
371
386
|
prevHeap: null as any,
|
|
372
|
-
state:
|
|
387
|
+
state: STATE_COMPUTED,
|
|
373
388
|
subs: null,
|
|
374
389
|
subsTail: null,
|
|
375
|
-
type: COMPUTED,
|
|
376
390
|
value: undefined as T,
|
|
377
391
|
};
|
|
378
392
|
|
|
@@ -429,7 +443,7 @@ const effect = <T>(fn: Computed<T>['fn']) => {
|
|
|
429
443
|
};
|
|
430
444
|
|
|
431
445
|
const isComputed = (value: unknown): value is Computed<unknown> => {
|
|
432
|
-
return isObject(value) && value.
|
|
446
|
+
return isObject(value) && !!((value as unknown as Computed<unknown>).state & STATE_COMPUTED);
|
|
433
447
|
};
|
|
434
448
|
|
|
435
449
|
const isSignal = (value: unknown): value is Signal<unknown> => {
|
|
@@ -462,14 +476,14 @@ const read = <T>(node: Signal<T> | Computed<T>): T => {
|
|
|
462
476
|
if (observer) {
|
|
463
477
|
link(node, observer);
|
|
464
478
|
|
|
465
|
-
if (node.
|
|
466
|
-
let height = node.height;
|
|
479
|
+
if ((node as Computed<unknown>).state & STATE_COMPUTED) {
|
|
480
|
+
let height = (node as Computed<T>).height;
|
|
467
481
|
|
|
468
482
|
if (height >= observer.height) {
|
|
469
483
|
observer.height = height + 1;
|
|
470
484
|
}
|
|
471
485
|
|
|
472
|
-
if (height >= heap_i || node.state & STATE_NOTIFY_MASK) {
|
|
486
|
+
if (height >= heap_i || (node as Computed<T>).state & STATE_NOTIFY_MASK) {
|
|
473
487
|
if (!notified) {
|
|
474
488
|
notified = true;
|
|
475
489
|
|
|
@@ -480,7 +494,7 @@ const read = <T>(node: Signal<T> | Computed<T>): T => {
|
|
|
480
494
|
}
|
|
481
495
|
}
|
|
482
496
|
|
|
483
|
-
update(node);
|
|
497
|
+
update(node as Computed<T>);
|
|
484
498
|
}
|
|
485
499
|
}
|
|
486
500
|
}
|
|
@@ -501,7 +515,7 @@ const root = <T>(fn: ((dispose: VoidFunction) => T) | (() => T)) => {
|
|
|
501
515
|
root.disposables = 0;
|
|
502
516
|
|
|
503
517
|
if (tracking) {
|
|
504
|
-
scope = self = { cleanup: null } as Computed<unknown>;
|
|
518
|
+
scope = self = { cleanup: null, state: STATE_COMPUTED } as Computed<unknown>;
|
|
505
519
|
value = (fn as (dispose: VoidFunction) => T)(c = () => dispose(self!));
|
|
506
520
|
}
|
|
507
521
|
else {
|
|
@@ -553,7 +567,7 @@ const write = <T>(signal: Signal<T>, value: T) => {
|
|
|
553
567
|
|
|
554
568
|
|
|
555
569
|
export {
|
|
556
|
-
computed,
|
|
570
|
+
asyncComputed, computed,
|
|
557
571
|
dispose,
|
|
558
572
|
effect,
|
|
559
573
|
isComputed, isSignal,
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ts } from '@esportsplus/typescript';
|
|
2
|
-
import {
|
|
2
|
+
import { SIGNAL } from './constants';
|
|
3
3
|
import { ReactiveArray } from './reactive';
|
|
4
4
|
|
|
5
5
|
|
|
@@ -11,15 +11,9 @@ interface Computed<T> {
|
|
|
11
11
|
height: number;
|
|
12
12
|
nextHeap: Computed<unknown> | undefined;
|
|
13
13
|
prevHeap: Computed<unknown>;
|
|
14
|
-
state:
|
|
15
|
-
typeof STATE_CHECK |
|
|
16
|
-
typeof STATE_DIRTY |
|
|
17
|
-
typeof STATE_IN_HEAP |
|
|
18
|
-
typeof STATE_NONE |
|
|
19
|
-
typeof STATE_RECOMPUTING;
|
|
14
|
+
state: number;
|
|
20
15
|
subs: Link | null;
|
|
21
16
|
subsTail: Link | null;
|
|
22
|
-
type: typeof COMPUTED;
|
|
23
17
|
value: T;
|
|
24
18
|
}
|
|
25
19
|
|