@zeix/cause-effect 0.17.1 → 0.17.3

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 (57) hide show
  1. package/.ai-context.md +13 -0
  2. package/.github/copilot-instructions.md +4 -0
  3. package/.zed/settings.json +3 -0
  4. package/CLAUDE.md +41 -7
  5. package/README.md +48 -25
  6. package/archive/benchmark.ts +0 -5
  7. package/archive/collection.ts +6 -65
  8. package/archive/composite.ts +85 -0
  9. package/archive/computed.ts +18 -20
  10. package/archive/list.ts +7 -75
  11. package/archive/memo.ts +15 -15
  12. package/archive/state.ts +2 -1
  13. package/archive/store.ts +8 -78
  14. package/archive/task.ts +20 -25
  15. package/index.dev.js +508 -526
  16. package/index.js +1 -1
  17. package/index.ts +9 -11
  18. package/package.json +6 -6
  19. package/src/classes/collection.ts +70 -107
  20. package/src/classes/computed.ts +165 -149
  21. package/src/classes/list.ts +145 -107
  22. package/src/classes/ref.ts +19 -17
  23. package/src/classes/state.ts +21 -17
  24. package/src/classes/store.ts +125 -73
  25. package/src/diff.ts +2 -1
  26. package/src/effect.ts +17 -10
  27. package/src/errors.ts +14 -1
  28. package/src/resolve.ts +1 -1
  29. package/src/signal.ts +3 -2
  30. package/src/system.ts +159 -61
  31. package/src/util.ts +0 -6
  32. package/test/batch.test.ts +4 -11
  33. package/test/benchmark.test.ts +4 -2
  34. package/test/collection.test.ts +106 -107
  35. package/test/computed.test.ts +351 -112
  36. package/test/effect.test.ts +2 -2
  37. package/test/list.test.ts +62 -102
  38. package/test/ref.test.ts +128 -2
  39. package/test/state.test.ts +16 -22
  40. package/test/store.test.ts +101 -108
  41. package/test/util/dependency-graph.ts +2 -2
  42. package/tsconfig.build.json +11 -0
  43. package/tsconfig.json +5 -7
  44. package/types/index.d.ts +3 -3
  45. package/types/src/classes/collection.d.ts +9 -10
  46. package/types/src/classes/computed.d.ts +17 -20
  47. package/types/src/classes/list.d.ts +8 -6
  48. package/types/src/classes/ref.d.ts +8 -12
  49. package/types/src/classes/state.d.ts +5 -8
  50. package/types/src/classes/store.d.ts +14 -13
  51. package/types/src/effect.d.ts +1 -2
  52. package/types/src/errors.d.ts +2 -1
  53. package/types/src/signal.d.ts +3 -2
  54. package/types/src/system.d.ts +47 -34
  55. package/types/src/util.d.ts +1 -2
  56. package/src/classes/composite.ts +0 -176
  57. package/types/src/classes/composite.d.ts +0 -15
package/tsconfig.json CHANGED
@@ -13,6 +13,9 @@
13
13
  "allowImportingTsExtensions": true,
14
14
  "verbatimModuleSyntax": true,
15
15
 
16
+ // Editor-only mode - no emit
17
+ "noEmit": true,
18
+
16
19
  // Best practices
17
20
  "strict": true,
18
21
  "skipLibCheck": true,
@@ -22,12 +25,7 @@
22
25
  "noUnusedLocals": false,
23
26
  "noUnusedParameters": false,
24
27
  "noPropertyAccessFromIndexSignature": false,
25
-
26
- // Declarations
27
- "declaration": true,
28
- "declarationDir": "./types",
29
- "emitDeclarationOnly": true
30
28
  },
31
- "include": ["./*.ts", "./src/*.ts"],
32
- "exclude": ["node_modules", "test", "types"]
29
+ "include": ["./**/*.ts"],
30
+ "exclude": ["node_modules", "types"],
33
31
  }
package/types/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @name Cause & Effect
3
- * @version 0.17.1
3
+ * @version 0.17.3
4
4
  * @author Esther Brunner
5
5
  */
6
6
  export { type Collection, type CollectionCallback, type CollectionSource, DerivedCollection, isCollection, TYPE_COLLECTION, } from './src/classes/collection';
@@ -15,5 +15,5 @@ export { CircularDependencyError, createError, DuplicateKeyError, type Guard, gu
15
15
  export { type MatchHandlers, match } from './src/match';
16
16
  export { type ResolveResult, resolve } from './src/resolve';
17
17
  export { createSignal, isMutableSignal, isSignal, type Signal, type SignalValues, type UnknownSignalRecord, } from './src/signal';
18
- export { batchSignalWrites, type Cleanup, createWatcher, emitNotification, flushPendingReactions, type Listener, type Listeners, type Notifications, notifyWatchers, subscribeActiveWatcher, trackSignalReads, type Watcher, } from './src/system';
19
- export { isAbortError, isAsyncFunction, isFunction, isNumber, isObjectOfType, isRecord, isRecordOrArray, isString, isSymbol, UNSET, valueString, } from './src/util';
18
+ export { batch, type Cleanup, createWatcher, flush, notifyOf, type SignalOptions, subscribeTo, track, UNSET, untrack, type Watcher, } from './src/system';
19
+ export { isAbortError, isAsyncFunction, isFunction, isNumber, isObjectOfType, isRecord, isRecordOrArray, isString, isSymbol, valueString, } from './src/util';
@@ -1,5 +1,5 @@
1
1
  import type { Signal } from '../signal';
2
- import { type Cleanup, type Listener, type Listeners } from '../system';
2
+ import { type SignalOptions } from '../system';
3
3
  import { type Computed } from './computed';
4
4
  import { type List } from './list';
5
5
  type CollectionSource<T extends {}> = List<T> | Collection<T>;
@@ -8,39 +8,38 @@ type Collection<T extends {}> = {
8
8
  readonly [Symbol.toStringTag]: 'Collection';
9
9
  readonly [Symbol.isConcatSpreadable]: true;
10
10
  [Symbol.iterator](): IterableIterator<Signal<T>>;
11
+ keys(): IterableIterator<string>;
11
12
  get: () => T[];
12
13
  at: (index: number) => Signal<T> | undefined;
13
14
  byKey: (key: string) => Signal<T> | undefined;
14
15
  keyAt: (index: number) => string | undefined;
15
16
  indexOfKey: (key: string) => number | undefined;
16
- on: <K extends keyof Listeners>(type: K, listener: Listener<K>) => Cleanup;
17
17
  deriveCollection: <R extends {}>(callback: CollectionCallback<R, T>) => DerivedCollection<R, T>;
18
18
  readonly length: number;
19
19
  };
20
20
  declare const TYPE_COLLECTION: "Collection";
21
21
  declare class DerivedCollection<T extends {}, U extends {}> implements Collection<T> {
22
22
  #private;
23
- constructor(source: CollectionSource<U> | (() => CollectionSource<U>), callback: CollectionCallback<T, U>);
23
+ constructor(source: CollectionSource<U> | (() => CollectionSource<U>), callback: CollectionCallback<T, U>, options?: SignalOptions<T[]>);
24
24
  get [Symbol.toStringTag](): 'Collection';
25
25
  get [Symbol.isConcatSpreadable](): true;
26
26
  [Symbol.iterator](): IterableIterator<Computed<T>>;
27
- get length(): number;
27
+ keys(): IterableIterator<string>;
28
28
  get(): T[];
29
29
  at(index: number): Computed<T> | undefined;
30
- keys(): IterableIterator<string>;
31
30
  byKey(key: string): Computed<T> | undefined;
32
31
  keyAt(index: number): string | undefined;
33
32
  indexOfKey(key: string): number;
34
- on<K extends keyof Listeners>(type: K, listener: Listener<K>): Cleanup;
35
- deriveCollection<R extends {}>(callback: (sourceValue: T) => R): DerivedCollection<R, T>;
36
- deriveCollection<R extends {}>(callback: (sourceValue: T, abort: AbortSignal) => Promise<R>): DerivedCollection<R, T>;
33
+ deriveCollection<R extends {}>(callback: (sourceValue: T) => R, options?: SignalOptions<R[]>): DerivedCollection<R, T>;
34
+ deriveCollection<R extends {}>(callback: (sourceValue: T, abort: AbortSignal) => Promise<R>, options?: SignalOptions<R[]>): DerivedCollection<R, T>;
35
+ get length(): number;
37
36
  }
38
37
  /**
39
38
  * Check if a value is a collection signal
40
39
  *
41
- * @since 0.17.0
40
+ * @since 0.17.2
42
41
  * @param {unknown} value - Value to check
43
42
  * @returns {boolean} - True if value is a collection signal, false otherwise
44
43
  */
45
- declare const isCollection: <T extends {}, U extends {}>(value: unknown) => value is DerivedCollection<T, U>;
44
+ declare const isCollection: <T extends {}>(value: unknown) => value is Collection<T>;
46
45
  export { type Collection, type CollectionSource, type CollectionCallback, DerivedCollection, isCollection, TYPE_COLLECTION, };
@@ -1,7 +1,11 @@
1
+ import { type SignalOptions } from '../system';
1
2
  type Computed<T extends {}> = {
2
3
  readonly [Symbol.toStringTag]: 'Computed';
3
4
  get(): T;
4
5
  };
6
+ type ComputedOptions<T extends {}> = SignalOptions<T> & {
7
+ initialValue?: T;
8
+ };
5
9
  type MemoCallback<T extends {} & {
6
10
  then?: undefined;
7
11
  }> = (oldValue: T) => T;
@@ -13,18 +17,14 @@ declare const TYPE_COMPUTED: "Computed";
13
17
  * Create a new memoized signal for a synchronous function.
14
18
  *
15
19
  * @since 0.17.0
20
+ * @param {MemoCallback<T>} callback - Callback function to compute the memoized value
21
+ * @param {T} [initialValue = UNSET] - Initial value of the signal
22
+ * @throws {InvalidCallbackError} If the callback is not an sync function
23
+ * @throws {InvalidSignalValueError} If the initial value is not valid
16
24
  */
17
25
  declare class Memo<T extends {}> {
18
26
  #private;
19
- /**
20
- * Create a new memoized signal.
21
- *
22
- * @param {MemoCallback<T>} callback - Callback function to compute the memoized value
23
- * @param {T} [initialValue = UNSET] - Initial value of the signal
24
- * @throws {InvalidCallbackError} If the callback is not an sync function
25
- * @throws {InvalidSignalValueError} If the initial value is not valid
26
- */
27
- constructor(callback: MemoCallback<T>, initialValue?: T);
27
+ constructor(callback: MemoCallback<T>, options?: ComputedOptions<T>);
28
28
  get [Symbol.toStringTag](): 'Computed';
29
29
  /**
30
30
  * Return the memoized value after computing it if necessary.
@@ -39,18 +39,14 @@ declare class Memo<T extends {}> {
39
39
  * Create a new task signals that memoizes the result of an asynchronous function.
40
40
  *
41
41
  * @since 0.17.0
42
+ * @param {TaskCallback<T>} callback - The asynchronous function to compute the memoized value
43
+ * @param {T} [initialValue = UNSET] - Initial value of the signal
44
+ * @throws {InvalidCallbackError} If the callback is not an async function
45
+ * @throws {InvalidSignalValueError} If the initial value is not valid
42
46
  */
43
47
  declare class Task<T extends {}> {
44
48
  #private;
45
- /**
46
- * Create a new task signal for an asynchronous function.
47
- *
48
- * @param {TaskCallback<T>} callback - The asynchronous function to compute the memoized value
49
- * @param {T} [initialValue = UNSET] - Initial value of the signal
50
- * @throws {InvalidCallbackError} If the callback is not an async function
51
- * @throws {InvalidSignalValueError} If the initial value is not valid
52
- */
53
- constructor(callback: TaskCallback<T>, initialValue?: T);
49
+ constructor(callback: TaskCallback<T>, options?: ComputedOptions<T>);
54
50
  get [Symbol.toStringTag](): 'Computed';
55
51
  /**
56
52
  * Return the memoized value after executing the async function if necessary.
@@ -66,8 +62,9 @@ declare class Task<T extends {}> {
66
62
  *
67
63
  * @since 0.9.0
68
64
  * @param {MemoCallback<T> | TaskCallback<T>} callback - Computation callback function
65
+ * @param {ComputedOptions<T>} options - Optional configuration
69
66
  */
70
- declare const createComputed: <T extends {}>(callback: TaskCallback<T> | MemoCallback<T>, initialValue?: T) => Task<T> | Memo<T>;
67
+ declare const createComputed: <T extends {}>(callback: TaskCallback<T> | MemoCallback<T>, options?: ComputedOptions<T>) => Task<T> | Memo<T>;
71
68
  /**
72
69
  * Check if a value is a computed signal
73
70
  *
@@ -94,4 +91,4 @@ declare const isMemoCallback: <T extends {} & {
94
91
  * @returns {boolean} - True if value is an async callback, false otherwise
95
92
  */
96
93
  declare const isTaskCallback: <T extends {}>(value: unknown) => value is TaskCallback<T>;
97
- export { TYPE_COMPUTED, createComputed, isComputed, isMemoCallback, isTaskCallback, Memo, Task, type Computed, type MemoCallback, type TaskCallback, };
94
+ export { TYPE_COMPUTED, createComputed, isComputed, isMemoCallback, isTaskCallback, Memo, Task, type Computed, type ComputedOptions, type MemoCallback, type TaskCallback, };
@@ -1,15 +1,18 @@
1
1
  import { type UnknownArray } from '../diff';
2
- import { type Cleanup, type Listener, type Notifications } from '../system';
2
+ import { type SignalOptions } from '../system';
3
3
  import { DerivedCollection } from './collection';
4
4
  import { State } from './state';
5
5
  type ArrayToRecord<T extends UnknownArray> = {
6
6
  [key: string]: T extends Array<infer U extends {}> ? U : never;
7
7
  };
8
8
  type KeyConfig<T> = string | ((item: T) => string);
9
+ type ListOptions<T extends {}> = SignalOptions<T> & {
10
+ keyConfig?: KeyConfig<T>;
11
+ };
9
12
  declare const TYPE_LIST: "List";
10
13
  declare class List<T extends {}> {
11
14
  #private;
12
- constructor(initialValue: T[], keyConfig?: KeyConfig<T>);
15
+ constructor(initialValue: T[], options?: ListOptions<T>);
13
16
  get [Symbol.toStringTag](): 'List';
14
17
  get [Symbol.isConcatSpreadable](): true;
15
18
  [Symbol.iterator](): IterableIterator<State<T>>;
@@ -26,9 +29,8 @@ declare class List<T extends {}> {
26
29
  remove(keyOrIndex: string | number): void;
27
30
  sort(compareFn?: (a: T, b: T) => number): void;
28
31
  splice(start: number, deleteCount?: number, ...items: T[]): T[];
29
- on<K extends keyof Notifications>(type: K, listener: Listener<K>): Cleanup;
30
- deriveCollection<R extends {}>(callback: (sourceValue: T) => R): DerivedCollection<R, T>;
31
- deriveCollection<R extends {}>(callback: (sourceValue: T, abort: AbortSignal) => Promise<R>): DerivedCollection<R, T>;
32
+ deriveCollection<R extends {}>(callback: (sourceValue: T) => R, options?: SignalOptions<R[]>): DerivedCollection<R, T>;
33
+ deriveCollection<R extends {}>(callback: (sourceValue: T, abort: AbortSignal) => Promise<R>, options?: SignalOptions<R[]>): DerivedCollection<R, T>;
32
34
  }
33
35
  /**
34
36
  * Check if the provided value is a List instance
@@ -38,4 +40,4 @@ declare class List<T extends {}> {
38
40
  * @returns {boolean} - True if the value is a List instance, false otherwise
39
41
  */
40
42
  declare const isList: <T extends {}>(value: unknown) => value is List<T>;
41
- export { isList, List, TYPE_LIST, type ArrayToRecord, type KeyConfig };
43
+ export { isList, List, TYPE_LIST, type ArrayToRecord, type KeyConfig, type ListOptions, };
@@ -1,21 +1,17 @@
1
- import { type Guard } from '../errors';
1
+ import { type SignalOptions } from '../system';
2
2
  declare const TYPE_REF = "Ref";
3
3
  /**
4
4
  * Create a new ref signal.
5
5
  *
6
6
  * @since 0.17.1
7
+ * @param {T} value - Reference to external object
8
+ * @param {Guard<T>} guard - Optional guard function to validate the value
9
+ * @throws {NullishSignalValueError} - If the value is null or undefined
10
+ * @throws {InvalidSignalValueError} - If the value is invalid
7
11
  */
8
12
  declare class Ref<T extends {}> {
9
13
  #private;
10
- /**
11
- * Create a new ref signal.
12
- *
13
- * @param {T} value - Reference to external object
14
- * @param {Guard<T>} guard - Optional guard function to validate the value
15
- * @throws {NullishSignalValueError} - If the value is null or undefined
16
- * @throws {InvalidSignalValueError} - If the value is invalid
17
- */
18
- constructor(value: T, guard?: Guard<T>);
14
+ constructor(value: T, options?: SignalOptions<T>);
19
15
  get [Symbol.toStringTag](): string;
20
16
  /**
21
17
  * Get the value of the ref signal.
@@ -24,7 +20,7 @@ declare class Ref<T extends {}> {
24
20
  */
25
21
  get(): T;
26
22
  /**
27
- * Notify watchers of relevant changes in the external reference
23
+ * Notify watchers of relevant changes in the external reference.
28
24
  */
29
25
  notify(): void;
30
26
  }
@@ -33,7 +29,7 @@ declare class Ref<T extends {}> {
33
29
  *
34
30
  * @since 0.17.1
35
31
  * @param {unknown} value - Value to check
36
- * @returns {boolean} - True if the value is a Ref instance, false otherwise
32
+ * @returns {boolean} - Whether the value is a Ref instance
37
33
  */
38
34
  declare const isRef: <T extends {}>(value: unknown) => value is Ref<T>;
39
35
  export { TYPE_REF, Ref, isRef };
@@ -1,19 +1,16 @@
1
+ import { type SignalOptions } from '../system';
1
2
  declare const TYPE_STATE: "State";
2
3
  /**
3
4
  * Create a new state signal.
4
5
  *
5
6
  * @since 0.17.0
7
+ * @param {T} initialValue - Initial value of the state
8
+ * @throws {NullishSignalValueError} - If the initial value is null or undefined
9
+ * @throws {InvalidSignalValueError} - If the initial value is invalid
6
10
  */
7
11
  declare class State<T extends {}> {
8
12
  #private;
9
- /**
10
- * Create a new state signal.
11
- *
12
- * @param {T} initialValue - Initial value of the state
13
- * @throws {NullishSignalValueError} - If the initial value is null or undefined
14
- * @throws {InvalidSignalValueError} - If the initial value is invalid
15
- */
16
- constructor(initialValue: T);
13
+ constructor(initialValue: T, options?: SignalOptions<T>);
17
14
  get [Symbol.toStringTag](): string;
18
15
  /**
19
16
  * Get the current value of the state signal.
@@ -1,45 +1,46 @@
1
1
  import { type UnknownRecord } from '../diff';
2
2
  import { type MutableSignal } from '../signal';
3
- import { type Cleanup, type Listener, type Listeners } from '../system';
3
+ import { type SignalOptions } from '../system';
4
4
  import type { List } from './list';
5
5
  import type { State } from './state';
6
6
  type Store<T extends UnknownRecord> = BaseStore<T> & {
7
7
  [K in keyof T]: T[K] extends readonly (infer U extends {})[] ? List<U> : T[K] extends UnknownRecord ? Store<T[K]> : State<T[K] & {}>;
8
8
  };
9
9
  declare const TYPE_STORE: "Store";
10
+ /**
11
+ * Create a new store with the given initial value.
12
+ *
13
+ * @since 0.17.0
14
+ * @param {T} initialValue - The initial value of the store
15
+ * @throws {NullishSignalValueError} - If the initial value is null or undefined
16
+ * @throws {InvalidSignalValueError} - If the initial value is not an object
17
+ */
10
18
  declare class BaseStore<T extends UnknownRecord> {
11
19
  #private;
12
- /**
13
- * Create a new store with the given initial value.
14
- *
15
- * @param {T} initialValue - The initial value of the store
16
- * @throws {NullishSignalValueError} - If the initial value is null or undefined
17
- * @throws {InvalidSignalValueError} - If the initial value is not an object
18
- */
19
- constructor(initialValue: T);
20
+ constructor(initialValue: T, options?: SignalOptions<T>);
20
21
  get [Symbol.toStringTag](): 'Store';
21
22
  get [Symbol.isConcatSpreadable](): boolean;
22
23
  [Symbol.iterator](): IterableIterator<[
23
24
  string,
24
25
  MutableSignal<T[keyof T] & {}>
25
26
  ]>;
26
- get(): T;
27
- set(newValue: T): void;
28
27
  keys(): IterableIterator<string>;
29
28
  byKey<K extends keyof T & string>(key: K): T[K] extends readonly (infer U extends {})[] ? List<U> : T[K] extends UnknownRecord ? Store<T[K]> : T[K] extends unknown & {} ? State<T[K] & {}> : State<T[K] & {}> | undefined;
29
+ get(): T;
30
+ set(newValue: T): void;
30
31
  update(fn: (oldValue: T) => T): void;
31
32
  add<K extends keyof T & string>(key: K, value: T[K]): K;
32
33
  remove(key: string): void;
33
- on<K extends keyof Omit<Listeners, 'sort'>>(type: K, listener: Listener<K>): Cleanup;
34
34
  }
35
35
  /**
36
36
  * Create a new store with deeply nested reactive properties
37
37
  *
38
38
  * @since 0.15.0
39
39
  * @param {T} initialValue - Initial object or array value of the store
40
+ * @param {SignalOptions<T>} options - Options for the store
40
41
  * @returns {Store<T>} - New store with reactive properties that preserves the original type T
41
42
  */
42
- declare const createStore: <T extends UnknownRecord>(initialValue: T) => Store<T>;
43
+ declare const createStore: <T extends UnknownRecord>(initialValue: T, options?: SignalOptions<T>) => Store<T>;
43
44
  /**
44
45
  * Check if the provided value is a Store instance
45
46
  *
@@ -1,5 +1,4 @@
1
- import { type Cleanup } from './system';
2
- type MaybeCleanup = Cleanup | undefined | void;
1
+ import { type Cleanup, type MaybeCleanup } from './system';
3
2
  type EffectCallback = (() => MaybeCleanup) | ((abort: AbortSignal) => Promise<MaybeCleanup>);
4
3
  /**
5
4
  * Define what happens when a reactive state changes
@@ -21,8 +21,9 @@ declare class NullishSignalValueError extends TypeError {
21
21
  declare class ReadonlySignalError extends Error {
22
22
  constructor(what: string, value: unknown);
23
23
  }
24
+ declare function assert(condition: unknown, msg?: string): asserts condition;
24
25
  declare const createError: (reason: unknown) => Error;
25
26
  declare const validateCallback: (where: string, value: unknown, guard?: (value: unknown) => boolean) => void;
26
27
  declare const validateSignalValue: (where: string, value: unknown, guard?: (value: unknown) => boolean) => void;
27
28
  declare const guardMutableSignal: <T extends {}>(what: string, value: unknown, signal: unknown) => signal is MutableSignal<T>;
28
- export { type Guard, CircularDependencyError, DuplicateKeyError, InvalidCallbackError, InvalidCollectionSourceError, InvalidSignalValueError, NullishSignalValueError, ReadonlySignalError, createError, validateCallback, validateSignalValue, guardMutableSignal, };
29
+ export { type Guard, CircularDependencyError, DuplicateKeyError, InvalidCallbackError, InvalidCollectionSourceError, InvalidSignalValueError, NullishSignalValueError, ReadonlySignalError, assert, createError, validateCallback, validateSignalValue, guardMutableSignal, };
@@ -6,9 +6,10 @@ import type { UnknownRecord } from './diff';
6
6
  type Signal<T extends {}> = {
7
7
  get(): T;
8
8
  };
9
+ type UnknownSignal = Signal<unknown & {}>;
9
10
  type MutableSignal<T extends {}> = T extends readonly (infer U extends {})[] ? List<U> : T extends UnknownRecord ? Store<T> : State<T>;
10
11
  type ReadonlySignal<T extends {}> = Computed<T>;
11
- type UnknownSignalRecord = Record<string, Signal<unknown & {}>>;
12
+ type UnknownSignalRecord = Record<string, UnknownSignal>;
12
13
  type SignalValues<S extends UnknownSignalRecord> = {
13
14
  [K in keyof S]: S[K] extends Signal<infer T> ? T : never;
14
15
  };
@@ -47,4 +48,4 @@ declare function createMutableSignal<T extends {}>(value: readonly T[]): List<T>
47
48
  declare function createMutableSignal<T extends {}>(value: T[]): List<T>;
48
49
  declare function createMutableSignal<T extends UnknownRecord>(value: T): Store<T>;
49
50
  declare function createMutableSignal<T extends {}>(value: T): State<T>;
50
- export { createMutableSignal, createSignal, isMutableSignal, isSignal, type MutableSignal, type ReadonlySignal, type Signal, type SignalValues, type UnknownSignalRecord, };
51
+ export { createMutableSignal, createSignal, isMutableSignal, isSignal, type MutableSignal, type ReadonlySignal, type Signal, type SignalValues, type UnknownSignal, type UnknownSignalRecord, };
@@ -1,65 +1,78 @@
1
+ import { type Guard } from './errors';
2
+ import type { UnknownSignal } from './signal';
1
3
  type Cleanup = () => void;
4
+ type MaybeCleanup = Cleanup | undefined | void;
2
5
  type Watcher = {
3
6
  (): void;
7
+ run(): void;
4
8
  onCleanup(cleanup: Cleanup): void;
5
9
  stop(): void;
6
10
  };
7
- type Notifications = {
8
- add: readonly string[];
9
- change: readonly string[];
10
- remove: readonly string[];
11
- sort: readonly string[];
12
- };
13
- type Listener<K extends keyof Notifications> = (payload: Notifications[K]) => void;
14
- type Listeners = {
15
- [K in keyof Notifications]: Set<Listener<K>>;
11
+ type SignalOptions<T extends unknown & {}> = {
12
+ guard?: Guard<T>;
13
+ watched?: () => void;
14
+ unwatched?: () => void;
16
15
  };
16
+ declare const UNSET: any;
17
17
  /**
18
- * Create a watcher that can be used to observe changes to a signal
18
+ * Create a watcher to observe changes in signals.
19
19
  *
20
- * A watcher is a reaction function with onCleanup and stop methods
20
+ * A watcher combines push and pull reaction functions with onCleanup and stop methods
21
21
  *
22
- * @since 0.14.1
23
- * @param {() => void} react - Function to be called when the state changes
22
+ * @since 0.17.3
23
+ * @param {() => void} push - Function to be called when the state changes (push)
24
+ * @param {() => void} pull - Function to be called on demand from consumers (pull)
24
25
  * @returns {Watcher} - Watcher object with off and cleanup methods
25
26
  */
26
- declare const createWatcher: (react: () => void) => Watcher;
27
+ declare const createWatcher: (push: () => void, pull: () => void) => Watcher;
28
+ /**
29
+ * Run a function with signal reads in a non-tracking context.
30
+ *
31
+ * @param {() => void} callback - Callback
32
+ */
33
+ declare const untrack: (callback: () => void) => void;
34
+ declare const registerWatchCallbacks: (signal: UnknownSignal, watched: () => void, unwatched?: () => void) => void;
35
+ /**
36
+ * Subscribe active watcher to a signal.
37
+ *
38
+ * @param {UnknownSignal} signal - Signal to subscribe to
39
+ * @returns {boolean} - true if the active watcher was subscribed,
40
+ * false if the watcher was already subscribed or there was no active watcher
41
+ */
42
+ declare const subscribeTo: (signal: UnknownSignal) => boolean;
43
+ declare const subscribeActiveWatcher: (watchers: Set<Watcher>) => boolean;
27
44
  /**
28
- * Subscribe by adding active watcher to the Set of watchers of a signal
45
+ * Unsubscribe all watchers from a signal so it can be garbage collected.
29
46
  *
30
- * @param {Set<Watcher>} watchers - Watchers of the signal
47
+ * @param {UnknownSignal} signal - Signal to unsubscribe from
48
+ * @returns {void}
31
49
  */
32
- declare const subscribeActiveWatcher: (watchers: Set<Watcher>) => void;
50
+ declare const unsubscribeAllFrom: (signal: UnknownSignal) => void;
33
51
  /**
34
- * Notify watchers of a signal change
52
+ * Notify watchers of a signal change.
35
53
  *
36
- * @param {Set<Watcher>} watchers - Watchers of the signal
54
+ * @param {UnknownSignal} signal - Signal to notify watchers of
55
+ * @returns {boolean} - Whether any watchers were notified
37
56
  */
38
- declare const notifyWatchers: (watchers: Set<Watcher>) => void;
57
+ declare const notifyOf: (signal: UnknownSignal) => boolean;
58
+ declare const notifyWatchers: (watchers: Set<Watcher>) => boolean;
39
59
  /**
40
- * Flush all pending reactions of enqueued watchers
60
+ * Flush all pending reactions of enqueued watchers.
41
61
  */
42
- declare const flushPendingReactions: () => void;
62
+ declare const flush: () => void;
43
63
  /**
44
- * Batch multiple signal writes
64
+ * Batch multiple signal writes.
45
65
  *
46
66
  * @param {() => void} callback - Function with multiple signal writes to be batched
47
67
  */
48
- declare const batchSignalWrites: (callback: () => void) => void;
68
+ declare const batch: (callback: () => void) => void;
49
69
  /**
50
- * Run a function with signal reads in a tracking context (or temporarily untrack)
70
+ * Run a function with signal reads in a tracking context (or temporarily untrack).
51
71
  *
52
72
  * @param {Watcher | false} watcher - Watcher to be called when the signal changes
53
73
  * or false for temporary untracking while inserting auto-hydrating DOM nodes
54
74
  * that might read signals (e.g., Web Components)
55
75
  * @param {() => void} run - Function to run the computation or effect
56
76
  */
57
- declare const trackSignalReads: (watcher: Watcher | false, run: () => void) => void;
58
- /**
59
- * Emit a notification to listeners
60
- *
61
- * @param {Set<Listener>} listeners - Listeners to be notified
62
- * @param {Notifications[K]} payload - Payload to be sent to listeners
63
- */
64
- declare const emitNotification: <T extends keyof Notifications>(listeners: Set<Listener<T>>, payload: Notifications[T]) => void;
65
- export { type Cleanup, type Watcher, type Notifications, type Listener, type Listeners, createWatcher, subscribeActiveWatcher, notifyWatchers, flushPendingReactions, batchSignalWrites, trackSignalReads, emitNotification, };
77
+ declare const track: (watcher: Watcher | false, run: () => void) => void;
78
+ export { type Cleanup, type MaybeCleanup, type Watcher, type SignalOptions, UNSET, createWatcher, registerWatchCallbacks, subscribeTo, subscribeActiveWatcher, unsubscribeAllFrom, notifyOf, notifyWatchers, flush, batch, track, untrack, };
@@ -1,4 +1,3 @@
1
- declare const UNSET: any;
2
1
  declare const isString: (value: unknown) => value is string;
3
2
  declare const isNumber: (value: unknown) => value is number;
4
3
  declare const isSymbol: (value: unknown) => value is symbol;
@@ -15,4 +14,4 @@ declare const isUniformArray: <T>(value: unknown, guard?: (item: T) => item is T
15
14
  declare const hasMethod: <T extends object & Record<string, (...args: unknown[]) => unknown>>(obj: T, methodName: string) => obj is T & Record<string, (...args: unknown[]) => unknown>;
16
15
  declare const isAbortError: (error: unknown) => boolean;
17
16
  declare const valueString: (value: unknown) => string;
18
- export { UNSET, isString, isNumber, isSymbol, isFunction, isAsyncFunction, isSyncFunction, isNonNullObject, isObjectOfType, isRecord, isRecordOrArray, isUniformArray, hasMethod, isAbortError, valueString, };
17
+ export { isString, isNumber, isSymbol, isFunction, isAsyncFunction, isSyncFunction, isNonNullObject, isObjectOfType, isRecord, isRecordOrArray, isUniformArray, hasMethod, isAbortError, valueString, };