@zeix/cause-effect 0.17.3 → 0.18.1
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/.ai-context.md +169 -227
- package/.cursorrules +41 -35
- package/.github/copilot-instructions.md +176 -116
- package/ARCHITECTURE.md +276 -0
- package/CHANGELOG.md +29 -0
- package/CLAUDE.md +201 -143
- package/GUIDE.md +298 -0
- package/README.md +246 -193
- package/REQUIREMENTS.md +100 -0
- package/bench/reactivity.bench.ts +577 -0
- package/context7.json +4 -0
- package/examples/events-sensor.ts +187 -0
- package/examples/selector-sensor.ts +173 -0
- package/index.dev.js +1390 -1008
- package/index.js +1 -1
- package/index.ts +60 -74
- package/package.json +5 -2
- package/skills/changelog-keeper/SKILL.md +59 -0
- package/skills/changelog-keeper/agents/openai.yaml +4 -0
- package/src/errors.ts +118 -74
- package/src/graph.ts +612 -0
- package/src/nodes/collection.ts +512 -0
- package/src/nodes/effect.ts +149 -0
- package/src/nodes/list.ts +589 -0
- package/src/nodes/memo.ts +148 -0
- package/src/nodes/sensor.ts +149 -0
- package/src/nodes/state.ts +135 -0
- package/src/nodes/store.ts +378 -0
- package/src/nodes/task.ts +174 -0
- package/src/signal.ts +112 -66
- package/src/util.ts +26 -57
- package/test/batch.test.ts +96 -62
- package/test/benchmark.test.ts +473 -487
- package/test/collection.test.ts +456 -707
- package/test/effect.test.ts +293 -696
- package/test/list.test.ts +335 -592
- package/test/memo.test.ts +574 -0
- package/test/regression.test.ts +156 -0
- package/test/scope.test.ts +191 -0
- package/test/sensor.test.ts +454 -0
- package/test/signal.test.ts +220 -213
- package/test/state.test.ts +217 -265
- package/test/store.test.ts +346 -446
- package/test/task.test.ts +529 -0
- package/test/untrack.test.ts +167 -0
- package/types/index.d.ts +13 -15
- package/types/src/errors.d.ts +73 -17
- package/types/src/graph.d.ts +218 -0
- package/types/src/nodes/collection.d.ts +69 -0
- package/types/src/nodes/effect.d.ts +48 -0
- package/types/src/nodes/list.d.ts +66 -0
- package/types/src/nodes/memo.d.ts +63 -0
- package/types/src/nodes/sensor.d.ts +81 -0
- package/types/src/nodes/state.d.ts +78 -0
- package/types/src/nodes/store.d.ts +51 -0
- package/types/src/nodes/task.d.ts +79 -0
- package/types/src/signal.d.ts +43 -29
- package/types/src/util.d.ts +9 -16
- package/archive/benchmark.ts +0 -683
- package/archive/collection.ts +0 -253
- package/archive/composite.ts +0 -85
- package/archive/computed.ts +0 -195
- package/archive/list.ts +0 -483
- package/archive/memo.ts +0 -139
- package/archive/state.ts +0 -90
- package/archive/store.ts +0 -298
- package/archive/task.ts +0 -189
- package/src/classes/collection.ts +0 -245
- package/src/classes/computed.ts +0 -349
- package/src/classes/list.ts +0 -343
- package/src/classes/ref.ts +0 -70
- package/src/classes/state.ts +0 -102
- package/src/classes/store.ts +0 -262
- package/src/diff.ts +0 -138
- package/src/effect.ts +0 -93
- package/src/match.ts +0 -45
- package/src/resolve.ts +0 -49
- package/src/system.ts +0 -257
- package/test/computed.test.ts +0 -1108
- package/test/diff.test.ts +0 -955
- package/test/match.test.ts +0 -388
- package/test/ref.test.ts +0 -353
- package/test/resolve.test.ts +0 -154
- package/types/src/classes/collection.d.ts +0 -45
- package/types/src/classes/computed.d.ts +0 -94
- package/types/src/classes/list.d.ts +0 -43
- package/types/src/classes/ref.d.ts +0 -35
- package/types/src/classes/state.d.ts +0 -49
- package/types/src/classes/store.d.ts +0 -52
- package/types/src/diff.d.ts +0 -28
- package/types/src/effect.d.ts +0 -15
- package/types/src/match.d.ts +0 -21
- package/types/src/resolve.d.ts +0 -29
- package/types/src/system.d.ts +0 -78
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { type SignalOptions } from '../system';
|
|
2
|
-
declare const TYPE_REF = "Ref";
|
|
3
|
-
/**
|
|
4
|
-
* Create a new ref signal.
|
|
5
|
-
*
|
|
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
|
|
11
|
-
*/
|
|
12
|
-
declare class Ref<T extends {}> {
|
|
13
|
-
#private;
|
|
14
|
-
constructor(value: T, options?: SignalOptions<T>);
|
|
15
|
-
get [Symbol.toStringTag](): string;
|
|
16
|
-
/**
|
|
17
|
-
* Get the value of the ref signal.
|
|
18
|
-
*
|
|
19
|
-
* @returns {T} - Object reference
|
|
20
|
-
*/
|
|
21
|
-
get(): T;
|
|
22
|
-
/**
|
|
23
|
-
* Notify watchers of relevant changes in the external reference.
|
|
24
|
-
*/
|
|
25
|
-
notify(): void;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Check if the provided value is a Ref instance
|
|
29
|
-
*
|
|
30
|
-
* @since 0.17.1
|
|
31
|
-
* @param {unknown} value - Value to check
|
|
32
|
-
* @returns {boolean} - Whether the value is a Ref instance
|
|
33
|
-
*/
|
|
34
|
-
declare const isRef: <T extends {}>(value: unknown) => value is Ref<T>;
|
|
35
|
-
export { TYPE_REF, Ref, isRef };
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { type SignalOptions } from '../system';
|
|
2
|
-
declare const TYPE_STATE: "State";
|
|
3
|
-
/**
|
|
4
|
-
* Create a new state signal.
|
|
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
|
|
10
|
-
*/
|
|
11
|
-
declare class State<T extends {}> {
|
|
12
|
-
#private;
|
|
13
|
-
constructor(initialValue: T, options?: SignalOptions<T>);
|
|
14
|
-
get [Symbol.toStringTag](): string;
|
|
15
|
-
/**
|
|
16
|
-
* Get the current value of the state signal.
|
|
17
|
-
*
|
|
18
|
-
* @returns {T} - Current value of the state
|
|
19
|
-
*/
|
|
20
|
-
get(): T;
|
|
21
|
-
/**
|
|
22
|
-
* Set the value of the state signal.
|
|
23
|
-
*
|
|
24
|
-
* @param {T} newValue - New value of the state
|
|
25
|
-
* @returns {void}
|
|
26
|
-
* @throws {NullishSignalValueError} - If the initial value is null or undefined
|
|
27
|
-
* @throws {InvalidSignalValueError} - If the initial value is invalid
|
|
28
|
-
*/
|
|
29
|
-
set(newValue: T): void;
|
|
30
|
-
/**
|
|
31
|
-
* Update the value of the state signal.
|
|
32
|
-
*
|
|
33
|
-
* @param {Function} updater - Function that takes the current value and returns the new value
|
|
34
|
-
* @returns {void}
|
|
35
|
-
* @throws {InvalidCallbackError} - If the updater function is not a function
|
|
36
|
-
* @throws {NullishSignalValueError} - If the initial value is null or undefined
|
|
37
|
-
* @throws {InvalidSignalValueError} - If the initial value is invalid
|
|
38
|
-
*/
|
|
39
|
-
update(updater: (oldValue: T) => T): void;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Check if the provided value is a State instance
|
|
43
|
-
*
|
|
44
|
-
* @since 0.9.0
|
|
45
|
-
* @param {unknown} value - Value to check
|
|
46
|
-
* @returns {boolean} - True if the value is a State instance, false otherwise
|
|
47
|
-
*/
|
|
48
|
-
declare const isState: <T extends {}>(value: unknown) => value is State<T>;
|
|
49
|
-
export { TYPE_STATE, isState, State };
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { type UnknownRecord } from '../diff';
|
|
2
|
-
import { type MutableSignal } from '../signal';
|
|
3
|
-
import { type SignalOptions } from '../system';
|
|
4
|
-
import type { List } from './list';
|
|
5
|
-
import type { State } from './state';
|
|
6
|
-
type Store<T extends UnknownRecord> = BaseStore<T> & {
|
|
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
|
-
};
|
|
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
|
-
*/
|
|
18
|
-
declare class BaseStore<T extends UnknownRecord> {
|
|
19
|
-
#private;
|
|
20
|
-
constructor(initialValue: T, options?: SignalOptions<T>);
|
|
21
|
-
get [Symbol.toStringTag](): 'Store';
|
|
22
|
-
get [Symbol.isConcatSpreadable](): boolean;
|
|
23
|
-
[Symbol.iterator](): IterableIterator<[
|
|
24
|
-
string,
|
|
25
|
-
MutableSignal<T[keyof T] & {}>
|
|
26
|
-
]>;
|
|
27
|
-
keys(): IterableIterator<string>;
|
|
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;
|
|
31
|
-
update(fn: (oldValue: T) => T): void;
|
|
32
|
-
add<K extends keyof T & string>(key: K, value: T[K]): K;
|
|
33
|
-
remove(key: string): void;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Create a new store with deeply nested reactive properties
|
|
37
|
-
*
|
|
38
|
-
* @since 0.15.0
|
|
39
|
-
* @param {T} initialValue - Initial object or array value of the store
|
|
40
|
-
* @param {SignalOptions<T>} options - Options for the store
|
|
41
|
-
* @returns {Store<T>} - New store with reactive properties that preserves the original type T
|
|
42
|
-
*/
|
|
43
|
-
declare const createStore: <T extends UnknownRecord>(initialValue: T, options?: SignalOptions<T>) => Store<T>;
|
|
44
|
-
/**
|
|
45
|
-
* Check if the provided value is a Store instance
|
|
46
|
-
*
|
|
47
|
-
* @since 0.15.0
|
|
48
|
-
* @param {unknown} value - Value to check
|
|
49
|
-
* @returns {boolean} - True if the value is a Store instance, false otherwise
|
|
50
|
-
*/
|
|
51
|
-
declare const isStore: <T extends UnknownRecord>(value: unknown) => value is BaseStore<T>;
|
|
52
|
-
export { createStore, isStore, BaseStore, TYPE_STORE, type Store };
|
package/types/src/diff.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
type UnknownRecord = Record<string, unknown>;
|
|
2
|
-
type UnknownArray = ReadonlyArray<unknown & {}>;
|
|
3
|
-
type DiffResult = {
|
|
4
|
-
changed: boolean;
|
|
5
|
-
add: UnknownRecord;
|
|
6
|
-
change: UnknownRecord;
|
|
7
|
-
remove: UnknownRecord;
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* Checks if two values are equal with cycle detection
|
|
11
|
-
*
|
|
12
|
-
* @since 0.15.0
|
|
13
|
-
* @param {T} a - First value to compare
|
|
14
|
-
* @param {T} b - Second value to compare
|
|
15
|
-
* @param {WeakSet<object>} visited - Set to track visited objects for cycle detection
|
|
16
|
-
* @returns {boolean} Whether the two values are equal
|
|
17
|
-
*/
|
|
18
|
-
declare const isEqual: <T>(a: T, b: T, visited?: WeakSet<object>) => boolean;
|
|
19
|
-
/**
|
|
20
|
-
* Compares two records and returns a result object containing the differences.
|
|
21
|
-
*
|
|
22
|
-
* @since 0.15.0
|
|
23
|
-
* @param {T} oldObj - The old record to compare
|
|
24
|
-
* @param {T} newObj - The new record to compare
|
|
25
|
-
* @returns {DiffResult} The result of the comparison
|
|
26
|
-
*/
|
|
27
|
-
declare const diff: <T extends UnknownRecord>(oldObj: T, newObj: T) => DiffResult;
|
|
28
|
-
export { type DiffResult, diff, isEqual, type UnknownRecord, type UnknownArray };
|
package/types/src/effect.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { type Cleanup, type MaybeCleanup } from './system';
|
|
2
|
-
type EffectCallback = (() => MaybeCleanup) | ((abort: AbortSignal) => Promise<MaybeCleanup>);
|
|
3
|
-
/**
|
|
4
|
-
* Define what happens when a reactive state changes
|
|
5
|
-
*
|
|
6
|
-
* The callback can be synchronous or asynchronous. Async callbacks receive
|
|
7
|
-
* an AbortSignal parameter, which is automatically aborted when the effect
|
|
8
|
-
* re-runs or is cleaned up, preventing stale async operations.
|
|
9
|
-
*
|
|
10
|
-
* @since 0.1.0
|
|
11
|
-
* @param {EffectCallback} callback - Synchronous or asynchronous effect callback
|
|
12
|
-
* @returns {Cleanup} - Cleanup function for the effect
|
|
13
|
-
*/
|
|
14
|
-
declare const createEffect: (callback: EffectCallback) => Cleanup;
|
|
15
|
-
export { type MaybeCleanup, type EffectCallback, createEffect };
|
package/types/src/match.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { ResolveResult } from './resolve';
|
|
2
|
-
import type { SignalValues, UnknownSignalRecord } from './signal';
|
|
3
|
-
type MatchHandlers<S extends UnknownSignalRecord> = {
|
|
4
|
-
ok: (values: SignalValues<S>) => void;
|
|
5
|
-
err?: (errors: readonly Error[]) => void;
|
|
6
|
-
nil?: () => void;
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* Match on resolve result and call appropriate handler for side effects
|
|
10
|
-
*
|
|
11
|
-
* This is a utility function for those who prefer the handler pattern.
|
|
12
|
-
* All handlers are for side effects only and return void. If you need
|
|
13
|
-
* cleanup logic, use a hoisted let variable in your effect.
|
|
14
|
-
*
|
|
15
|
-
* @since 0.15.0
|
|
16
|
-
* @param {ResolveResult<S>} result - Result from resolve()
|
|
17
|
-
* @param {MatchHandlers<S>} handlers - Handlers for different states (side effects only)
|
|
18
|
-
* @returns {void} - Always returns void
|
|
19
|
-
*/
|
|
20
|
-
declare function match<S extends UnknownSignalRecord>(result: ResolveResult<S>, handlers: MatchHandlers<S>): void;
|
|
21
|
-
export { match, type MatchHandlers };
|
package/types/src/resolve.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { SignalValues, UnknownSignalRecord } from './signal';
|
|
2
|
-
type ResolveResult<S extends UnknownSignalRecord> = {
|
|
3
|
-
ok: true;
|
|
4
|
-
values: SignalValues<S>;
|
|
5
|
-
errors?: never;
|
|
6
|
-
pending?: never;
|
|
7
|
-
} | {
|
|
8
|
-
ok: false;
|
|
9
|
-
errors: readonly Error[];
|
|
10
|
-
values?: never;
|
|
11
|
-
pending?: never;
|
|
12
|
-
} | {
|
|
13
|
-
ok: false;
|
|
14
|
-
pending: true;
|
|
15
|
-
values?: never;
|
|
16
|
-
errors?: never;
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Resolve signal values with perfect type inference
|
|
20
|
-
*
|
|
21
|
-
* Always returns a discriminated union result, regardless of whether
|
|
22
|
-
* handlers are provided or not. This ensures a predictable API.
|
|
23
|
-
*
|
|
24
|
-
* @since 0.15.0
|
|
25
|
-
* @param {S} signals - Signals to resolve
|
|
26
|
-
* @returns {ResolveResult<S>} - Discriminated union result
|
|
27
|
-
*/
|
|
28
|
-
declare function resolve<S extends UnknownSignalRecord>(signals: S): ResolveResult<S>;
|
|
29
|
-
export { resolve, type ResolveResult };
|
package/types/src/system.d.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { type Guard } from './errors';
|
|
2
|
-
import type { UnknownSignal } from './signal';
|
|
3
|
-
type Cleanup = () => void;
|
|
4
|
-
type MaybeCleanup = Cleanup | undefined | void;
|
|
5
|
-
type Watcher = {
|
|
6
|
-
(): void;
|
|
7
|
-
run(): void;
|
|
8
|
-
onCleanup(cleanup: Cleanup): void;
|
|
9
|
-
stop(): void;
|
|
10
|
-
};
|
|
11
|
-
type SignalOptions<T extends unknown & {}> = {
|
|
12
|
-
guard?: Guard<T>;
|
|
13
|
-
watched?: () => void;
|
|
14
|
-
unwatched?: () => void;
|
|
15
|
-
};
|
|
16
|
-
declare const UNSET: any;
|
|
17
|
-
/**
|
|
18
|
-
* Create a watcher to observe changes in signals.
|
|
19
|
-
*
|
|
20
|
-
* A watcher combines push and pull reaction functions with onCleanup and stop methods
|
|
21
|
-
*
|
|
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)
|
|
25
|
-
* @returns {Watcher} - Watcher object with off and cleanup methods
|
|
26
|
-
*/
|
|
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;
|
|
44
|
-
/**
|
|
45
|
-
* Unsubscribe all watchers from a signal so it can be garbage collected.
|
|
46
|
-
*
|
|
47
|
-
* @param {UnknownSignal} signal - Signal to unsubscribe from
|
|
48
|
-
* @returns {void}
|
|
49
|
-
*/
|
|
50
|
-
declare const unsubscribeAllFrom: (signal: UnknownSignal) => void;
|
|
51
|
-
/**
|
|
52
|
-
* Notify watchers of a signal change.
|
|
53
|
-
*
|
|
54
|
-
* @param {UnknownSignal} signal - Signal to notify watchers of
|
|
55
|
-
* @returns {boolean} - Whether any watchers were notified
|
|
56
|
-
*/
|
|
57
|
-
declare const notifyOf: (signal: UnknownSignal) => boolean;
|
|
58
|
-
declare const notifyWatchers: (watchers: Set<Watcher>) => boolean;
|
|
59
|
-
/**
|
|
60
|
-
* Flush all pending reactions of enqueued watchers.
|
|
61
|
-
*/
|
|
62
|
-
declare const flush: () => void;
|
|
63
|
-
/**
|
|
64
|
-
* Batch multiple signal writes.
|
|
65
|
-
*
|
|
66
|
-
* @param {() => void} callback - Function with multiple signal writes to be batched
|
|
67
|
-
*/
|
|
68
|
-
declare const batch: (callback: () => void) => void;
|
|
69
|
-
/**
|
|
70
|
-
* Run a function with signal reads in a tracking context (or temporarily untrack).
|
|
71
|
-
*
|
|
72
|
-
* @param {Watcher | false} watcher - Watcher to be called when the signal changes
|
|
73
|
-
* or false for temporary untracking while inserting auto-hydrating DOM nodes
|
|
74
|
-
* that might read signals (e.g., Web Components)
|
|
75
|
-
* @param {() => void} run - Function to run the computation or effect
|
|
76
|
-
*/
|
|
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, };
|