@esportsplus/reactivity 0.31.2 → 0.32.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/.claude/CHANGELOG.md +43 -0
- package/README.md +13 -6
- package/bench/cellx.bench.ts +61 -0
- package/bench/dynamic.bench.ts +103 -0
- package/bench/kairo.bench.ts +368 -0
- package/bench/lib/reactive-adapter.ts +51 -0
- package/bench/molbench.bench.ts +75 -0
- package/{tests/bench/system.ts → bench/system.bench.ts} +3 -3
- package/build/compiler/array.d.ts +1 -1
- package/build/compiler/constants.d.ts +7 -6
- package/build/compiler/constants.js +6 -7
- package/build/compiler/object.d.ts +1 -1
- package/build/compiler/object.js +1 -2
- package/build/compiler/primitives.d.ts +1 -1
- package/build/constants.d.ts +3 -1
- package/build/constants.js +3 -1
- package/build/reactive/array.d.ts +8 -5
- package/build/reactive/array.js +14 -14
- package/build/reactive/index.d.ts +2 -2
- package/build/reactive/index.js +1 -1
- package/build/reactive/object.d.ts +4 -4
- package/build/reactive/object.js +8 -23
- package/build/system.d.ts +15 -6
- package/build/system.js +415 -69
- package/build/types.d.ts +16 -4
- package/package.json +5 -2
- package/pnpm-workspace.yaml +2 -0
- package/src/compiler/array.ts +1 -1
- package/src/compiler/constants.ts +8 -6
- package/src/compiler/index.ts +2 -1
- package/src/compiler/object.ts +2 -2
- package/src/compiler/plugins/vite.ts +1 -0
- package/src/compiler/primitives.ts +1 -1
- package/src/constants.ts +6 -2
- package/src/reactive/array.ts +26 -23
- package/src/reactive/index.ts +6 -6
- package/src/reactive/object.ts +16 -41
- package/src/system.ts +612 -80
- package/src/types.ts +29 -9
- package/test/async-computed.test.ts +323 -0
- package/test/async-errors.test.ts +146 -0
- package/test/async-hardening.test.ts +73 -0
- package/test/async-iterable.test.ts +221 -0
- package/test/async-nested.test.ts +19 -0
- package/test/deep-graphs.test.ts +215 -0
- package/{tests/effects.ts → test/effects.test.ts} +60 -0
- package/test/equals.test.ts +142 -0
- package/test/errors.test.ts +201 -0
- package/test/flush.test.ts +185 -0
- package/test/glitch-freedom.test.ts +115 -0
- package/test/invalidate.test.ts +147 -0
- package/test/lib/wait-for.ts +28 -0
- package/test/pending-writes.test.ts +139 -0
- package/{tests/reactive.ts → test/reactive/reactive.test.ts} +20 -19
- package/test/read-dedup.test.ts +120 -0
- package/test/signal-selector.test.ts +187 -0
- package/{tests/system.ts → test/system.test.ts} +214 -23
- package/test/tsconfig.json +16 -0
- package/test/untrack.test.ts +146 -0
- package/vitest.config.ts +2 -2
- package/tests/async-computed.ts +0 -239
- /package/{tests/bench/array.ts → bench/reactive/array.bench.ts} +0 -0
- /package/{tests/bench/reactive-object.ts → bench/reactive/reactive-object.bench.ts} +0 -0
- /package/{tests → bench}/tsconfig.json +0 -0
- /package/{tests/compiler.ts → test/compiler/compiler.test.ts} +0 -0
- /package/{tests/primitives.ts → test/primitives.test.ts} +0 -0
- /package/{tests/array.ts → test/reactive/array.test.ts} +0 -0
- /package/{tests/nested.ts → test/reactive/nested.test.ts} +0 -0
- /package/{tests/objects.ts → test/reactive/objects.test.ts} +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { bench, describe } from 'vitest';
|
|
2
|
+
import { assert, framework } from './lib/reactive-adapter';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
// Ported from milomg/js-reactivity-benchmark packages/core/src/benches/kairo/molBench.ts (MIT)
|
|
6
|
+
|
|
7
|
+
let numbers = Array.from({ length: 5 }, (_, i) => i);
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
function fib(n: number): number {
|
|
11
|
+
if (n < 2) {
|
|
12
|
+
return 1;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return fib(n - 1) + fib(n - 2);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function hard(n: number) {
|
|
19
|
+
return n + fib(16);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function mol() {
|
|
23
|
+
let res: number[] = [];
|
|
24
|
+
|
|
25
|
+
let a = framework.signal(0);
|
|
26
|
+
|
|
27
|
+
let b = framework.signal(0);
|
|
28
|
+
|
|
29
|
+
let c = framework.computed(() => (a.read() % 2) + (b.read() % 2));
|
|
30
|
+
|
|
31
|
+
let d = framework.computed(() => numbers.map((i) => ({ x: i + (a.read() % 2) - (b.read() % 2) })));
|
|
32
|
+
|
|
33
|
+
let e = framework.computed(() => hard(c.read() + a.read() + d.read()[0].x));
|
|
34
|
+
|
|
35
|
+
let f = framework.computed(() => hard(d.read()[2].x || b.read()));
|
|
36
|
+
|
|
37
|
+
let g = framework.computed(() => c.read() + (c.read() || e.read() % 2) + d.read()[4].x + f.read());
|
|
38
|
+
|
|
39
|
+
// Keeper: G reads E conditionally; without a live subscriber E would auto-dispose on first drop
|
|
40
|
+
framework.effect(() => e.read());
|
|
41
|
+
|
|
42
|
+
framework.effect(() => res.push(hard(g.read())));
|
|
43
|
+
|
|
44
|
+
framework.effect(() => res.push(g.read()));
|
|
45
|
+
|
|
46
|
+
framework.effect(() => res.push(hard(f.read())));
|
|
47
|
+
|
|
48
|
+
let i = 0;
|
|
49
|
+
|
|
50
|
+
return async () => {
|
|
51
|
+
i++;
|
|
52
|
+
res.length = 0;
|
|
53
|
+
|
|
54
|
+
await framework.withBatch(() => {
|
|
55
|
+
b.write(1);
|
|
56
|
+
a.write(1 + i * 2);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
await framework.withBatch(() => {
|
|
60
|
+
a.write(2 + i * 2);
|
|
61
|
+
b.write(2);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
assert(res.length > 0, 'molBench: effects did not run');
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
describe('molBench', () => {
|
|
70
|
+
let molRun = framework.withBuild(mol);
|
|
71
|
+
|
|
72
|
+
bench('molBench', async () => {
|
|
73
|
+
await molRun();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { bench, describe } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { computed, dispose, effect, onCleanup, read, root, signal, write } from '~/system';
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
describe('signal', () => {
|
|
@@ -78,13 +78,13 @@ describe('computed', () => {
|
|
|
78
78
|
|
|
79
79
|
describe('asyncComputed', () => {
|
|
80
80
|
bench('create asyncComputed', () => {
|
|
81
|
-
|
|
81
|
+
computed(() => Promise.resolve(0));
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
bench('create asyncComputed from signal', () => {
|
|
85
85
|
let s = signal(0);
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
computed(() => Promise.resolve(read(s)));
|
|
88
88
|
});
|
|
89
89
|
});
|
|
90
90
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ReplacementIntent } from '@esportsplus/typescript/compiler';
|
|
2
1
|
import { ts } from '@esportsplus/typescript';
|
|
2
|
+
import type { ReplacementIntent } from '@esportsplus/typescript/compiler';
|
|
3
3
|
import type { Bindings } from './types.js';
|
|
4
4
|
declare const _default: (sourceFile: ts.SourceFile, bindings: Bindings, checker?: ts.TypeChecker) => ReplacementIntent[];
|
|
5
5
|
export default _default;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
declare const ENTRYPOINT = "reactive";
|
|
2
2
|
declare const ENTRYPOINT_REGEX: RegExp;
|
|
3
3
|
declare const NAMESPACE: string;
|
|
4
|
-
declare const
|
|
5
|
-
Array
|
|
6
|
-
Computed
|
|
7
|
-
Object
|
|
8
|
-
Signal
|
|
9
|
-
}
|
|
4
|
+
declare const TYPES: {
|
|
5
|
+
readonly Array: 0;
|
|
6
|
+
readonly Computed: 1;
|
|
7
|
+
readonly Object: 2;
|
|
8
|
+
readonly Signal: 3;
|
|
9
|
+
};
|
|
10
|
+
type TYPES = typeof TYPES[keyof typeof TYPES];
|
|
10
11
|
export { ENTRYPOINT, ENTRYPOINT_REGEX, NAMESPACE, TYPES };
|
|
11
12
|
export { PACKAGE_NAME } from '../constants.js';
|
|
@@ -2,12 +2,11 @@ import { uid } from '@esportsplus/typescript/compiler';
|
|
|
2
2
|
const ENTRYPOINT = 'reactive';
|
|
3
3
|
const ENTRYPOINT_REGEX = /\breactive\b/;
|
|
4
4
|
const NAMESPACE = uid('reactivity');
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
})(TYPES || (TYPES = {}));
|
|
5
|
+
const TYPES = {
|
|
6
|
+
Array: 0,
|
|
7
|
+
Computed: 1,
|
|
8
|
+
Object: 2,
|
|
9
|
+
Signal: 3
|
|
10
|
+
};
|
|
12
11
|
export { ENTRYPOINT, ENTRYPOINT_REGEX, NAMESPACE, TYPES };
|
|
13
12
|
export { PACKAGE_NAME } from '../constants.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type ReplacementIntent } from '@esportsplus/typescript/compiler';
|
|
2
1
|
import { ts } from '@esportsplus/typescript';
|
|
2
|
+
import type { ReplacementIntent } from '@esportsplus/typescript/compiler';
|
|
3
3
|
import type { Bindings } from './types.js';
|
|
4
4
|
type ObjectTransformResult = {
|
|
5
5
|
prepend: string[];
|
package/build/compiler/object.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { code, imports } from '@esportsplus/typescript/compiler';
|
|
2
1
|
import { ts } from '@esportsplus/typescript';
|
|
3
|
-
import { uid } from '@esportsplus/typescript/compiler';
|
|
2
|
+
import { code, imports, uid } from '@esportsplus/typescript/compiler';
|
|
4
3
|
import { ENTRYPOINT, NAMESPACE, PACKAGE_NAME, TYPES } from './constants.js';
|
|
5
4
|
function analyzeProperty(prop, sourceFile) {
|
|
6
5
|
if (!ts.isPropertyAssignment(prop)) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ReplacementIntent } from '@esportsplus/typescript/compiler';
|
|
2
1
|
import { ts } from '@esportsplus/typescript';
|
|
2
|
+
import type { ReplacementIntent } from '@esportsplus/typescript/compiler';
|
|
3
3
|
import type { Bindings } from './types.js';
|
|
4
4
|
declare const _default: (sourceFile: ts.SourceFile, bindings: Bindings, isReactiveCall: (node: ts.Node) => boolean) => ReplacementIntent[];
|
|
5
5
|
export default _default;
|
package/build/constants.d.ts
CHANGED
|
@@ -13,5 +13,7 @@ declare const STATE_DIRTY: number;
|
|
|
13
13
|
declare const STATE_RECOMPUTING: number;
|
|
14
14
|
declare const STATE_IN_HEAP: number;
|
|
15
15
|
declare const STATE_COMPUTED: number;
|
|
16
|
+
declare const STATE_ERROR: number;
|
|
17
|
+
declare const STATE_EFFECT: number;
|
|
16
18
|
declare const STATE_NOTIFY_MASK: number;
|
|
17
|
-
export { COMPUTED, REACTIVE_ARRAY, REACTIVE_OBJECT,
|
|
19
|
+
export { COMPUTED, PACKAGE_NAME, REACTIVE_ARRAY, REACTIVE_OBJECT, SIGNAL, STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_COMPUTED, STATE_DIRTY, STATE_EFFECT, STATE_ERROR, STATE_IN_HEAP, STATE_NONE, STATE_NOTIFY_MASK, STATE_RECOMPUTING };
|
package/build/constants.js
CHANGED
|
@@ -13,5 +13,7 @@ const STATE_DIRTY = 1 << 1;
|
|
|
13
13
|
const STATE_RECOMPUTING = 1 << 2;
|
|
14
14
|
const STATE_IN_HEAP = 1 << 3;
|
|
15
15
|
const STATE_COMPUTED = 1 << 4;
|
|
16
|
+
const STATE_ERROR = 1 << 5;
|
|
17
|
+
const STATE_EFFECT = 1 << 6;
|
|
16
18
|
const STATE_NOTIFY_MASK = (STATE_CHECK | STATE_DIRTY);
|
|
17
|
-
export { COMPUTED, REACTIVE_ARRAY, REACTIVE_OBJECT,
|
|
19
|
+
export { COMPUTED, PACKAGE_NAME, REACTIVE_ARRAY, REACTIVE_OBJECT, SIGNAL, STABILIZER_IDLE, STABILIZER_RESCHEDULE, STABILIZER_RUNNING, STABILIZER_SCHEDULED, STATE_CHECK, STATE_COMPUTED, STATE_DIRTY, STATE_EFFECT, STATE_ERROR, STATE_IN_HEAP, STATE_NONE, STATE_NOTIFY_MASK, STATE_RECOMPUTING };
|
|
@@ -33,18 +33,19 @@ type Listener<V> = {
|
|
|
33
33
|
once?: boolean;
|
|
34
34
|
(value: V): void;
|
|
35
35
|
};
|
|
36
|
-
type
|
|
36
|
+
type AnyListener<T> = Listener<Events<T>[keyof Events<T>]>;
|
|
37
|
+
type Listeners<T> = {
|
|
38
|
+
[K in keyof Events<T>]?: (AnyListener<T> | null)[];
|
|
39
|
+
};
|
|
37
40
|
declare class ReactiveArray<T> extends Array<T> {
|
|
38
41
|
private _length;
|
|
39
|
-
listeners: Listeners
|
|
42
|
+
listeners: Listeners<T>;
|
|
40
43
|
constructor(...items: T[]);
|
|
41
|
-
get $length(): number;
|
|
42
|
-
set $length(value: number);
|
|
43
44
|
$set(i: number, value: T): void;
|
|
44
45
|
clear(): void;
|
|
45
46
|
concat(...items: ConcatArray<T>[]): ReactiveArray<T>;
|
|
46
47
|
concat(...items: (T | ConcatArray<T>)[]): ReactiveArray<T>;
|
|
47
|
-
dispatch<K extends keyof Events<T
|
|
48
|
+
dispatch<K extends keyof Events<T>>(event: K, value?: Events<T>[K]): void;
|
|
48
49
|
dispose(): void;
|
|
49
50
|
on<K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>): void;
|
|
50
51
|
once<K extends keyof Events<T>>(event: K, listener: Listener<Events<T>[K]>): void;
|
|
@@ -55,5 +56,7 @@ declare class ReactiveArray<T> extends Array<T> {
|
|
|
55
56
|
sort(fn?: (a: T, b: T) => number): this;
|
|
56
57
|
splice(start: number, deleteCount?: number, ...items: T[]): T[];
|
|
57
58
|
unshift(...items: T[]): number;
|
|
59
|
+
get $length(): number;
|
|
60
|
+
set $length(value: number);
|
|
58
61
|
}
|
|
59
62
|
export { ReactiveArray };
|
package/build/reactive/array.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isArray } from '@esportsplus/utilities';
|
|
2
|
-
import { read, signal, write } from '../system.js';
|
|
3
2
|
import { REACTIVE_ARRAY } from '../constants.js';
|
|
3
|
+
import { read, signal, write } from '../system.js';
|
|
4
4
|
import { isReactiveObject } from './object.js';
|
|
5
5
|
function dispose(value) {
|
|
6
6
|
if (isReactiveObject(value)) {
|
|
@@ -14,15 +14,6 @@ class ReactiveArray extends Array {
|
|
|
14
14
|
super(...items);
|
|
15
15
|
this._length = signal(items.length);
|
|
16
16
|
}
|
|
17
|
-
get $length() {
|
|
18
|
-
return read(this._length);
|
|
19
|
-
}
|
|
20
|
-
set $length(value) {
|
|
21
|
-
if (value > this.length) {
|
|
22
|
-
throw Error(`@esportsplus/reactivity: cannot set length to a value larger than the current length, use splice instead.`);
|
|
23
|
-
}
|
|
24
|
-
this.splice(value, this.length);
|
|
25
|
-
}
|
|
26
17
|
$set(i, value) {
|
|
27
18
|
let prev = this[i];
|
|
28
19
|
if (prev === value) {
|
|
@@ -97,22 +88,22 @@ class ReactiveArray extends Array {
|
|
|
97
88
|
write(this._length, 0);
|
|
98
89
|
}
|
|
99
90
|
on(event, listener) {
|
|
100
|
-
let listeners = this.listeners[event];
|
|
91
|
+
let entry = listener, listeners = this.listeners[event];
|
|
101
92
|
if (listeners === undefined) {
|
|
102
|
-
this.listeners[event] = [
|
|
93
|
+
this.listeners[event] = [entry];
|
|
103
94
|
}
|
|
104
95
|
else {
|
|
105
96
|
let hole = listeners.length;
|
|
106
97
|
for (let i = 0, n = hole; i < n; i++) {
|
|
107
98
|
let l = listeners[i];
|
|
108
|
-
if (l ===
|
|
99
|
+
if (l === entry) {
|
|
109
100
|
return;
|
|
110
101
|
}
|
|
111
102
|
else if (l === null && hole === n) {
|
|
112
103
|
hole = i;
|
|
113
104
|
}
|
|
114
105
|
}
|
|
115
|
-
listeners[hole] =
|
|
106
|
+
listeners[hole] = entry;
|
|
116
107
|
while (listeners.length && listeners[listeners.length - 1] === null) {
|
|
117
108
|
listeners.pop();
|
|
118
109
|
}
|
|
@@ -200,6 +191,15 @@ class ReactiveArray extends Array {
|
|
|
200
191
|
this.dispatch('unshift', { items });
|
|
201
192
|
return length;
|
|
202
193
|
}
|
|
194
|
+
get $length() {
|
|
195
|
+
return read(this._length);
|
|
196
|
+
}
|
|
197
|
+
set $length(value) {
|
|
198
|
+
if (value > this.length) {
|
|
199
|
+
throw Error(`@esportsplus/reactivity: cannot set length to a value larger than the current length, use splice instead.`);
|
|
200
|
+
}
|
|
201
|
+
this.splice(value, this.length);
|
|
202
|
+
}
|
|
203
203
|
}
|
|
204
204
|
Object.defineProperty(ReactiveArray.prototype, REACTIVE_ARRAY, { value: true });
|
|
205
205
|
export { ReactiveArray };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Reactive } from '../types.js';
|
|
1
|
+
import type { Reactive } from '../types.js';
|
|
2
2
|
import { ReactiveArray } from './array.js';
|
|
3
3
|
import { ReactiveObject } from './object.js';
|
|
4
4
|
type Guard<T> = T extends Record<PropertyKey, unknown> ? T extends {
|
|
5
|
-
dispose:
|
|
5
|
+
dispose: unknown;
|
|
6
6
|
} ? {
|
|
7
7
|
never: '[ dispose ] is a reserved key';
|
|
8
8
|
} : T : never;
|
package/build/reactive/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { onCleanup, root } from '@esportsplus/reactivity';
|
|
2
2
|
import { isArray, isObject } from '@esportsplus/utilities';
|
|
3
|
+
import { PACKAGE_NAME } from '../constants.js';
|
|
3
4
|
import { ReactiveArray } from './array.js';
|
|
4
5
|
import { ReactiveObject } from './object.js';
|
|
5
|
-
import { PACKAGE_NAME } from '../constants.js';
|
|
6
6
|
function reactive(input) {
|
|
7
7
|
let dispose = false, value = root(() => {
|
|
8
8
|
let response;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Computed, Signal } from '../types.js';
|
|
2
1
|
import { COMPUTED, REACTIVE_ARRAY, SIGNAL } from '../constants.js';
|
|
2
|
+
import { Computed } from '../types.js';
|
|
3
3
|
import { ReactiveArray } from './array.js';
|
|
4
4
|
declare class ReactiveObject<T extends Record<PropertyKey, unknown>> {
|
|
5
5
|
protected disposers: VoidFunction[] | null;
|
|
6
6
|
constructor(data: T | null);
|
|
7
|
+
protected [COMPUTED]<T extends Computed<ReturnType<T>>['fn']>(value: T): Computed<import("../types.js").Settled<ReturnType<T>>>;
|
|
7
8
|
protected [REACTIVE_ARRAY]<U>(value: U[]): ReactiveArray<U>;
|
|
8
|
-
protected [
|
|
9
|
-
protected [SIGNAL]<T>(value: T): Signal<T>;
|
|
9
|
+
protected [SIGNAL]<T>(value: T): import("../types.js").Signal<T>;
|
|
10
10
|
dispose(): void;
|
|
11
11
|
}
|
|
12
|
-
declare const isReactiveObject: (value:
|
|
12
|
+
declare const isReactiveObject: (value: unknown) => value is ReactiveObject<Record<PropertyKey, unknown>>;
|
|
13
13
|
export { isReactiveObject, ReactiveObject };
|
package/build/reactive/object.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { defineProperty, isArray
|
|
2
|
-
import { computed, dispose, effect, read, root, signal, write } from '../system.js';
|
|
1
|
+
import { defineProperty, isArray } from '@esportsplus/utilities';
|
|
3
2
|
import { COMPUTED, REACTIVE_ARRAY, REACTIVE_OBJECT, SIGNAL } from '../constants.js';
|
|
3
|
+
import { computed, dispose, read, root, signal, write } from '../system.js';
|
|
4
4
|
import { ReactiveArray } from './array.js';
|
|
5
5
|
class ReactiveObject {
|
|
6
6
|
disposers = null;
|
|
@@ -19,9 +19,7 @@ class ReactiveObject {
|
|
|
19
19
|
});
|
|
20
20
|
continue;
|
|
21
21
|
}
|
|
22
|
-
if (value
|
|
23
|
-
}
|
|
24
|
-
else if (isArray(value)) {
|
|
22
|
+
if (value != null && type === 'object' && isArray(value)) {
|
|
25
23
|
defineProperty(this, key, {
|
|
26
24
|
enumerable: true,
|
|
27
25
|
value: this[REACTIVE_ARRAY](value)
|
|
@@ -40,31 +38,18 @@ class ReactiveObject {
|
|
|
40
38
|
});
|
|
41
39
|
}
|
|
42
40
|
}
|
|
43
|
-
[REACTIVE_ARRAY](value) {
|
|
44
|
-
let node = new ReactiveArray(...value);
|
|
45
|
-
(this.disposers ??= []).push(() => node.dispose());
|
|
46
|
-
return node;
|
|
47
|
-
}
|
|
48
41
|
[COMPUTED](value) {
|
|
49
42
|
return root(() => {
|
|
50
43
|
let node = computed(value);
|
|
51
|
-
if (isPromise(node.value)) {
|
|
52
|
-
let factory = node, out = signal(undefined), v = 0;
|
|
53
|
-
(this.disposers ??= []).push(effect(() => {
|
|
54
|
-
let id = ++v;
|
|
55
|
-
read(factory).then((resolved) => {
|
|
56
|
-
if (id !== v) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
write(out, resolved);
|
|
60
|
-
});
|
|
61
|
-
}));
|
|
62
|
-
return out;
|
|
63
|
-
}
|
|
64
44
|
(this.disposers ??= []).push(() => dispose(node));
|
|
65
45
|
return node;
|
|
66
46
|
});
|
|
67
47
|
}
|
|
48
|
+
[REACTIVE_ARRAY](value) {
|
|
49
|
+
let node = new ReactiveArray(...value);
|
|
50
|
+
(this.disposers ??= []).push(() => node.dispose());
|
|
51
|
+
return node;
|
|
52
|
+
}
|
|
68
53
|
[SIGNAL](value) {
|
|
69
54
|
return signal(value);
|
|
70
55
|
}
|
package/build/system.d.ts
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
|
-
import { Computed, Signal } from './types.js';
|
|
2
|
-
declare const
|
|
3
|
-
declare const computed:
|
|
1
|
+
import { Computed, Settled, Signal } from './types.js';
|
|
2
|
+
declare const batch: <T>(fn: () => T) => T;
|
|
3
|
+
declare const computed: {
|
|
4
|
+
<T>(fn: Computed<T>["fn"], equals?: ((a: Settled<T>, b: Settled<T>) => boolean) | null): Computed<Settled<T>>;
|
|
5
|
+
invalidate<T>(c: Computed<T>): void;
|
|
6
|
+
};
|
|
4
7
|
declare const dispose: <T>(computed: Computed<T>) => void;
|
|
5
|
-
declare const effect: <T>(fn: Computed<T>["fn"]) => () => void;
|
|
8
|
+
declare const effect: <T>(fn: Computed<T>["fn"], onError?: (e: unknown) => void) => () => void;
|
|
9
|
+
declare const flush: () => void;
|
|
6
10
|
declare const isComputed: (value: unknown) => value is Computed<unknown>;
|
|
7
11
|
declare const isSignal: (value: unknown) => value is Signal<unknown>;
|
|
8
12
|
declare const onCleanup: (fn: VoidFunction) => typeof fn;
|
|
13
|
+
declare const peek: <T>(node: Signal<T> | Computed<T>) => T;
|
|
9
14
|
declare const read: <T>(node: Signal<T> | Computed<T>) => T;
|
|
10
15
|
declare const root: {
|
|
11
16
|
<T>(fn: ((dispose: VoidFunction) => T) | (() => T)): T;
|
|
12
17
|
disposables: number;
|
|
13
18
|
};
|
|
14
|
-
declare const signal:
|
|
19
|
+
declare const signal: {
|
|
20
|
+
<T>(value: T, equals?: ((a: T, b: T) => boolean) | null): Signal<T>;
|
|
21
|
+
selector<T>(node: Signal<T>, key: T): boolean;
|
|
22
|
+
};
|
|
23
|
+
declare const untrack: <T>(fn: () => T) => T;
|
|
15
24
|
declare const write: <T>(signal: Signal<T>, value: T) => void;
|
|
16
|
-
export {
|
|
25
|
+
export { batch, computed, dispose, effect, flush, isComputed, isSignal, onCleanup, peek, read, root, signal, untrack, write };
|
|
17
26
|
export type { Computed, Signal };
|