@esportsplus/reactivity 0.31.3 → 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.
Files changed (68) hide show
  1. package/.claude/CHANGELOG.md +43 -0
  2. package/README.md +13 -6
  3. package/bench/cellx.bench.ts +61 -0
  4. package/bench/dynamic.bench.ts +103 -0
  5. package/bench/kairo.bench.ts +368 -0
  6. package/bench/lib/reactive-adapter.ts +51 -0
  7. package/bench/molbench.bench.ts +75 -0
  8. package/{tests/bench/system.ts → bench/system.bench.ts} +3 -3
  9. package/build/compiler/array.d.ts +1 -1
  10. package/build/compiler/constants.d.ts +7 -6
  11. package/build/compiler/constants.js +6 -7
  12. package/build/compiler/object.d.ts +1 -1
  13. package/build/compiler/object.js +1 -2
  14. package/build/compiler/primitives.d.ts +1 -1
  15. package/build/constants.d.ts +3 -1
  16. package/build/constants.js +3 -1
  17. package/build/reactive/array.d.ts +8 -5
  18. package/build/reactive/array.js +14 -14
  19. package/build/reactive/index.d.ts +2 -2
  20. package/build/reactive/index.js +1 -1
  21. package/build/reactive/object.d.ts +4 -4
  22. package/build/reactive/object.js +8 -23
  23. package/build/system.d.ts +15 -6
  24. package/build/system.js +415 -69
  25. package/build/types.d.ts +16 -4
  26. package/package.json +5 -2
  27. package/src/compiler/array.ts +1 -1
  28. package/src/compiler/constants.ts +8 -6
  29. package/src/compiler/index.ts +2 -1
  30. package/src/compiler/object.ts +2 -2
  31. package/src/compiler/plugins/vite.ts +1 -0
  32. package/src/compiler/primitives.ts +1 -1
  33. package/src/constants.ts +6 -2
  34. package/src/reactive/array.ts +26 -23
  35. package/src/reactive/index.ts +6 -6
  36. package/src/reactive/object.ts +16 -41
  37. package/src/system.ts +612 -80
  38. package/src/types.ts +29 -9
  39. package/test/async-computed.test.ts +323 -0
  40. package/test/async-errors.test.ts +146 -0
  41. package/test/async-hardening.test.ts +73 -0
  42. package/test/async-iterable.test.ts +221 -0
  43. package/test/async-nested.test.ts +19 -0
  44. package/test/deep-graphs.test.ts +215 -0
  45. package/{tests/effects.ts → test/effects.test.ts} +60 -0
  46. package/test/equals.test.ts +142 -0
  47. package/test/errors.test.ts +201 -0
  48. package/test/flush.test.ts +185 -0
  49. package/test/glitch-freedom.test.ts +115 -0
  50. package/test/invalidate.test.ts +147 -0
  51. package/test/lib/wait-for.ts +28 -0
  52. package/test/pending-writes.test.ts +139 -0
  53. package/{tests/reactive.ts → test/reactive/reactive.test.ts} +20 -19
  54. package/test/read-dedup.test.ts +120 -0
  55. package/test/signal-selector.test.ts +187 -0
  56. package/{tests/system.ts → test/system.test.ts} +214 -23
  57. package/test/tsconfig.json +16 -0
  58. package/test/untrack.test.ts +146 -0
  59. package/vitest.config.ts +2 -2
  60. package/tests/async-computed.ts +0 -239
  61. /package/{tests/bench/array.ts → bench/reactive/array.bench.ts} +0 -0
  62. /package/{tests/bench/reactive-object.ts → bench/reactive/reactive-object.bench.ts} +0 -0
  63. /package/{tests → bench}/tsconfig.json +0 -0
  64. /package/{tests/compiler.ts → test/compiler/compiler.test.ts} +0 -0
  65. /package/{tests/primitives.ts → test/primitives.test.ts} +0 -0
  66. /package/{tests/array.ts → test/reactive/array.test.ts} +0 -0
  67. /package/{tests/nested.ts → test/reactive/nested.test.ts} +0 -0
  68. /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 { asyncComputed, computed, dispose, effect, onCleanup, read, root, signal, write } from '~/system';
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
- asyncComputed(() => Promise.resolve(0));
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
- asyncComputed(() => Promise.resolve(read(s)));
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 enum TYPES {
5
- Array = 0,
6
- Computed = 1,
7
- Object = 2,
8
- Signal = 3
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
- var TYPES;
6
- (function (TYPES) {
7
- TYPES[TYPES["Array"] = 0] = "Array";
8
- TYPES[TYPES["Computed"] = 1] = "Computed";
9
- TYPES[TYPES["Object"] = 2] = "Object";
10
- TYPES[TYPES["Signal"] = 3] = "Signal";
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[];
@@ -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;
@@ -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, 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 };
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 };
@@ -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, 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 };
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 Listeners = Record<string, (Listener<any> | null)[]>;
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>, V>(event: K, value?: V): void;
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 };
@@ -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] = [listener];
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 === listener) {
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] = listener;
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: any;
5
+ dispose: unknown;
6
6
  } ? {
7
7
  never: '[ dispose ] is a reserved key';
8
8
  } : T : never;
@@ -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 [COMPUTED]<T extends Computed<ReturnType<T>>['fn']>(value: T): Computed<ReturnType<T>> | Signal<ReturnType<T> | undefined>;
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: any) => value is ReactiveObject<any>;
12
+ declare const isReactiveObject: (value: unknown) => value is ReactiveObject<Record<PropertyKey, unknown>>;
13
13
  export { isReactiveObject, ReactiveObject };
@@ -1,6 +1,6 @@
1
- import { defineProperty, isArray, isPromise } from '@esportsplus/utilities';
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 == null || type !== 'object') {
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 asyncComputed: <T>(fn: Computed<Promise<T>>["fn"]) => Signal<T | undefined>;
3
- declare const computed: <T>(fn: Computed<T>["fn"]) => Computed<T>;
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: <T>(value: T) => Signal<T>;
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 { asyncComputed, computed, dispose, effect, isComputed, isSignal, onCleanup, read, root, signal, write };
25
+ export { batch, computed, dispose, effect, flush, isComputed, isSignal, onCleanup, peek, read, root, signal, untrack, write };
17
26
  export type { Computed, Signal };