rexfect 0.0.7
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/README.md +1756 -0
- package/dist/abortableContext.d.ts +3 -0
- package/dist/abortableContext.d.ts.map +1 -0
- package/dist/abortableContext.js +48 -0
- package/dist/abortableContext.js.map +1 -0
- package/dist/action.d.ts +64 -0
- package/dist/action.d.ts.map +1 -0
- package/dist/action.js +208 -0
- package/dist/action.js.map +1 -0
- package/dist/action.test.d.ts +2 -0
- package/dist/action.test.d.ts.map +1 -0
- package/dist/action.test.js +189 -0
- package/dist/action.test.js.map +1 -0
- package/dist/async/abortable-guard.d.ts +25 -0
- package/dist/async/abortable-guard.d.ts.map +1 -0
- package/dist/async/abortable-guard.js +33 -0
- package/dist/async/abortable-guard.js.map +1 -0
- package/dist/async/abortable.d.ts +331 -0
- package/dist/async/abortable.d.ts.map +1 -0
- package/dist/async/abortable.js +410 -0
- package/dist/async/abortable.js.map +1 -0
- package/dist/async/abortable.test.d.ts +2 -0
- package/dist/async/abortable.test.d.ts.map +1 -0
- package/dist/async/abortable.test.js +535 -0
- package/dist/async/abortable.test.js.map +1 -0
- package/dist/async/abortable.typeCheck.d.ts +8 -0
- package/dist/async/abortable.typeCheck.d.ts.map +1 -0
- package/dist/async/abortable.typeCheck.js +138 -0
- package/dist/async/abortable.typeCheck.js.map +1 -0
- package/dist/async/async.d.ts +18 -0
- package/dist/async/async.d.ts.map +1 -0
- package/dist/async/async.js +20 -0
- package/dist/async/async.js.map +1 -0
- package/dist/async/index.d.ts +15 -0
- package/dist/async/index.d.ts.map +1 -0
- package/dist/async/index.js +13 -0
- package/dist/async/index.js.map +1 -0
- package/dist/async/loadable.d.ts +7 -0
- package/dist/async/loadable.d.ts.map +1 -0
- package/dist/async/loadable.js +52 -0
- package/dist/async/loadable.js.map +1 -0
- package/dist/async/loadable.test.d.ts +2 -0
- package/dist/async/loadable.test.d.ts.map +1 -0
- package/dist/async/loadable.test.js +322 -0
- package/dist/async/loadable.test.js.map +1 -0
- package/dist/async/promiseCache.d.ts +14 -0
- package/dist/async/promiseCache.d.ts.map +1 -0
- package/dist/async/promiseCache.js +29 -0
- package/dist/async/promiseCache.js.map +1 -0
- package/dist/async/read.d.ts +120 -0
- package/dist/async/read.d.ts.map +1 -0
- package/dist/async/read.js +286 -0
- package/dist/async/read.js.map +1 -0
- package/dist/async/read.test.d.ts +2 -0
- package/dist/async/read.test.d.ts.map +1 -0
- package/dist/async/read.test.js +419 -0
- package/dist/async/read.test.js.map +1 -0
- package/dist/async/read.typeCheck.d.ts +6 -0
- package/dist/async/read.typeCheck.d.ts.map +1 -0
- package/dist/async/read.typeCheck.js +101 -0
- package/dist/async/read.typeCheck.js.map +1 -0
- package/dist/async/safe.d.ts +230 -0
- package/dist/async/safe.d.ts.map +1 -0
- package/dist/async/safe.js +247 -0
- package/dist/async/safe.js.map +1 -0
- package/dist/async/safe.test.d.ts +2 -0
- package/dist/async/safe.test.d.ts.map +1 -0
- package/dist/async/safe.test.js +447 -0
- package/dist/async/safe.test.js.map +1 -0
- package/dist/async/utils.d.ts +17 -0
- package/dist/async/utils.d.ts.map +1 -0
- package/dist/async/utils.js +38 -0
- package/dist/async/utils.js.map +1 -0
- package/dist/async/wait.d.ts +120 -0
- package/dist/async/wait.d.ts.map +1 -0
- package/dist/async/wait.js +112 -0
- package/dist/async/wait.js.map +1 -0
- package/dist/async/wait.test.d.ts +2 -0
- package/dist/async/wait.test.d.ts.map +1 -0
- package/dist/async/wait.test.js +122 -0
- package/dist/async/wait.test.js.map +1 -0
- package/dist/async/wait.typeCheck.d.ts +6 -0
- package/dist/async/wait.typeCheck.d.ts.map +1 -0
- package/dist/async/wait.typeCheck.js +104 -0
- package/dist/async/wait.typeCheck.js.map +1 -0
- package/dist/atom.d.ts +46 -0
- package/dist/atom.d.ts.map +1 -0
- package/dist/atom.js +86 -0
- package/dist/atom.js.map +1 -0
- package/dist/atom.test.d.ts +2 -0
- package/dist/atom.test.d.ts.map +1 -0
- package/dist/atom.test.js +75 -0
- package/dist/atom.test.js.map +1 -0
- package/dist/batch.d.ts +15 -0
- package/dist/batch.d.ts.map +1 -0
- package/dist/batch.js +45 -0
- package/dist/batch.js.map +1 -0
- package/dist/defer.d.ts +56 -0
- package/dist/defer.d.ts.map +1 -0
- package/dist/defer.js +49 -0
- package/dist/defer.js.map +1 -0
- package/dist/effect.d.ts +91 -0
- package/dist/effect.d.ts.map +1 -0
- package/dist/effect.js +311 -0
- package/dist/effect.js.map +1 -0
- package/dist/effect.test.d.ts +2 -0
- package/dist/effect.test.d.ts.map +1 -0
- package/dist/effect.test.js +123 -0
- package/dist/effect.test.js.map +1 -0
- package/dist/emitter.d.ts +129 -0
- package/dist/emitter.d.ts.map +1 -0
- package/dist/emitter.js +164 -0
- package/dist/emitter.js.map +1 -0
- package/dist/emitter.test.d.ts +2 -0
- package/dist/emitter.test.d.ts.map +1 -0
- package/dist/emitter.test.js +259 -0
- package/dist/emitter.test.js.map +1 -0
- package/dist/equality.d.ts +66 -0
- package/dist/equality.d.ts.map +1 -0
- package/dist/equality.js +145 -0
- package/dist/equality.js.map +1 -0
- package/dist/event.d.ts +18 -0
- package/dist/event.d.ts.map +1 -0
- package/dist/event.js +166 -0
- package/dist/event.js.map +1 -0
- package/dist/event.test.d.ts +2 -0
- package/dist/event.test.d.ts.map +1 -0
- package/dist/event.test.js +167 -0
- package/dist/event.test.js.map +1 -0
- package/dist/hooks.d.ts +152 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +122 -0
- package/dist/hooks.js.map +1 -0
- package/dist/hooks.test.d.ts +2 -0
- package/dist/hooks.test.d.ts.map +1 -0
- package/dist/hooks.test.js +99 -0
- package/dist/hooks.test.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/isPromiseLike.d.ts +10 -0
- package/dist/isPromiseLike.d.ts.map +1 -0
- package/dist/isPromiseLike.js +15 -0
- package/dist/isPromiseLike.js.map +1 -0
- package/dist/pick.d.ts +22 -0
- package/dist/pick.d.ts.map +1 -0
- package/dist/pick.js +46 -0
- package/dist/pick.js.map +1 -0
- package/dist/react/index.d.ts +8 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +8 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/useRx.d.ts +14 -0
- package/dist/react/useRx.d.ts.map +1 -0
- package/dist/react/useRx.js +110 -0
- package/dist/react/useRx.js.map +1 -0
- package/dist/react/useRx.test.d.ts +2 -0
- package/dist/react/useRx.test.d.ts.map +1 -0
- package/dist/react/useRx.test.js +457 -0
- package/dist/react/useRx.test.js.map +1 -0
- package/dist/strictModeTest.d.ts +11 -0
- package/dist/strictModeTest.d.ts.map +1 -0
- package/dist/strictModeTest.js +41 -0
- package/dist/strictModeTest.js.map +1 -0
- package/dist/types.d.ts +606 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/untrack.d.ts +14 -0
- package/dist/untrack.d.ts.map +1 -0
- package/dist/untrack.js +17 -0
- package/dist/untrack.js.map +1 -0
- package/dist/utils/withUse.d.ts +10 -0
- package/dist/utils/withUse.d.ts.map +1 -0
- package/dist/utils/withUse.js +21 -0
- package/dist/utils/withUse.js.map +1 -0
- package/dist/utils/withUse.test.d.ts +2 -0
- package/dist/utils/withUse.test.d.ts.map +1 -0
- package/dist/utils/withUse.test.js +233 -0
- package/dist/utils/withUse.test.js.map +1 -0
- package/dist/utils.d.ts +7 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +7 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.test.d.ts +2 -0
- package/dist/utils.test.d.ts.map +1 -0
- package/dist/utils.test.js +119 -0
- package/dist/utils.test.js.map +1 -0
- package/package.json +64 -0
package/dist/batch.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { withHooks } from "./hooks";
|
|
2
|
+
import { emitter } from "./emitter";
|
|
3
|
+
let batchDepth = 0;
|
|
4
|
+
/**
|
|
5
|
+
* Batches multiple state updates into a single reactive update.
|
|
6
|
+
*
|
|
7
|
+
* @param fn - Function containing multiple state updates
|
|
8
|
+
* @returns The return value of the function
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* batch(() => {
|
|
12
|
+
* setA(1);
|
|
13
|
+
* setB(2);
|
|
14
|
+
* setC(3);
|
|
15
|
+
* }); // Effects run once after all updates
|
|
16
|
+
*/
|
|
17
|
+
export function batch(fn) {
|
|
18
|
+
batchDepth++;
|
|
19
|
+
// First batch - set up the notification hook
|
|
20
|
+
if (batchDepth === 1) {
|
|
21
|
+
const onNotify = emitter();
|
|
22
|
+
try {
|
|
23
|
+
return withHooks({ scheduleNotify: onNotify.on }, fn);
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
batchDepth--;
|
|
27
|
+
// Keep hooks active while processing notifications
|
|
28
|
+
// This ensures effect re-runs are also batched
|
|
29
|
+
withHooks({ scheduleNotify: onNotify.on }, () => {
|
|
30
|
+
// Process until no more notifications (handles cascading updates)
|
|
31
|
+
while (onNotify.size > 0) {
|
|
32
|
+
onNotify.emitAndClear();
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Nested batch - just run the function
|
|
38
|
+
try {
|
|
39
|
+
return fn();
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
batchDepth--;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=batch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch.js","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,IAAI,UAAU,GAAG,CAAC,CAAC;AACnB;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,KAAK,CAAI,EAAW;IAClC,UAAU,EAAE,CAAC;IAEb,6CAA6C;IAC7C,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,OAAO,SAAS,CAAC,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACxD,CAAC;gBAAS,CAAC;YACT,UAAU,EAAE,CAAC;YACb,mDAAmD;YACnD,+CAA+C;YAC/C,SAAS,CAAC,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE;gBAC9C,kEAAkE;gBAClE,OAAO,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;oBACzB,QAAQ,CAAC,YAAY,EAAE,CAAC;gBAC1B,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;YAAS,CAAC;QACT,UAAU,EAAE,CAAC;IACf,CAAC;AACH,CAAC"}
|
package/dist/defer.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A deferred promise - a promise whose resolve/reject can be called externally.
|
|
3
|
+
*
|
|
4
|
+
* Unlike a regular Promise where resolve/reject are only accessible inside
|
|
5
|
+
* the executor function, a Deferred exposes them as properties, allowing
|
|
6
|
+
* the promise to be resolved/rejected from anywhere.
|
|
7
|
+
*
|
|
8
|
+
* @template T - The type of value the promise resolves to
|
|
9
|
+
*/
|
|
10
|
+
export interface Deferred<T> {
|
|
11
|
+
/** The underlying promise that will be resolved/rejected */
|
|
12
|
+
readonly promise: Promise<T>;
|
|
13
|
+
/** Resolves the promise with the given value */
|
|
14
|
+
readonly resolve: (value: T) => void;
|
|
15
|
+
/** Rejects the promise with the given error */
|
|
16
|
+
readonly reject: (error: unknown) => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Creates a deferred promise - a promise with externally accessible resolve/reject.
|
|
20
|
+
*
|
|
21
|
+
* This is useful when you need to resolve a promise from a different context
|
|
22
|
+
* than where it was created, such as:
|
|
23
|
+
* - Waiting for an event to fire (`await action`)
|
|
24
|
+
* - Coordinating between async operations
|
|
25
|
+
* - Building thenable objects
|
|
26
|
+
*
|
|
27
|
+
* @template T - The type of value the promise resolves to
|
|
28
|
+
* @returns A Deferred object with { promise, resolve, reject }
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* const deferred = defer<string>();
|
|
33
|
+
*
|
|
34
|
+
* // Somewhere else in the code...
|
|
35
|
+
* setTimeout(() => {
|
|
36
|
+
* deferred.resolve("done!");
|
|
37
|
+
* }, 1000);
|
|
38
|
+
*
|
|
39
|
+
* // Await the promise
|
|
40
|
+
* const result = await deferred.promise; // "done!"
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* // Used internally by action() for thenable support:
|
|
46
|
+
* let nextDispatch = defer<T>();
|
|
47
|
+
*
|
|
48
|
+
* // When action is awaited:
|
|
49
|
+
* action.then(...) → nextDispatch.promise.then(...)
|
|
50
|
+
*
|
|
51
|
+
* // When action is dispatched:
|
|
52
|
+
* action(payload) → nextDispatch.resolve(payload)
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function defer<T>(): Deferred<T>;
|
|
56
|
+
//# sourceMappingURL=defer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defer.d.ts","sourceRoot":"","sources":["../src/defer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7B,gDAAgD;IAChD,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACrC,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,KAAK,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAYtC"}
|
package/dist/defer.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a deferred promise - a promise with externally accessible resolve/reject.
|
|
3
|
+
*
|
|
4
|
+
* This is useful when you need to resolve a promise from a different context
|
|
5
|
+
* than where it was created, such as:
|
|
6
|
+
* - Waiting for an event to fire (`await action`)
|
|
7
|
+
* - Coordinating between async operations
|
|
8
|
+
* - Building thenable objects
|
|
9
|
+
*
|
|
10
|
+
* @template T - The type of value the promise resolves to
|
|
11
|
+
* @returns A Deferred object with { promise, resolve, reject }
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const deferred = defer<string>();
|
|
16
|
+
*
|
|
17
|
+
* // Somewhere else in the code...
|
|
18
|
+
* setTimeout(() => {
|
|
19
|
+
* deferred.resolve("done!");
|
|
20
|
+
* }, 1000);
|
|
21
|
+
*
|
|
22
|
+
* // Await the promise
|
|
23
|
+
* const result = await deferred.promise; // "done!"
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* // Used internally by action() for thenable support:
|
|
29
|
+
* let nextDispatch = defer<T>();
|
|
30
|
+
*
|
|
31
|
+
* // When action is awaited:
|
|
32
|
+
* action.then(...) → nextDispatch.promise.then(...)
|
|
33
|
+
*
|
|
34
|
+
* // When action is dispatched:
|
|
35
|
+
* action(payload) → nextDispatch.resolve(payload)
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export function defer() {
|
|
39
|
+
// These will be assigned synchronously by the Promise executor
|
|
40
|
+
let resolve;
|
|
41
|
+
let reject;
|
|
42
|
+
// Create promise and capture resolve/reject from executor
|
|
43
|
+
const promise = new Promise((...args) => {
|
|
44
|
+
[resolve, reject] = args;
|
|
45
|
+
});
|
|
46
|
+
// Non-null assertions are safe because Promise executor runs synchronously
|
|
47
|
+
return { promise, resolve: resolve, reject: reject };
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=defer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defer.js","sourceRoot":"","sources":["../src/defer.ts"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,UAAU,KAAK;IACnB,+DAA+D;IAC/D,IAAI,OAA2B,CAAC;IAChC,IAAI,MAAgC,CAAC;IAErC,0DAA0D;IAC1D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAI,CAAC,GAAG,IAAI,EAAE,EAAE;QACzC,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,2EAA2E;IAC3E,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAQ,EAAE,MAAM,EAAE,MAAO,EAAE,CAAC;AACzD,CAAC"}
|
package/dist/effect.d.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { EffectContext, EffectOptions } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a reactive effect that runs when its dependencies change.
|
|
4
|
+
*
|
|
5
|
+
* ## How It Works
|
|
6
|
+
*
|
|
7
|
+
* 1. Effect runs immediately on creation
|
|
8
|
+
* 2. During execution, any atom/signal reads are automatically tracked
|
|
9
|
+
* 3. When any tracked dependency changes, effect re-runs
|
|
10
|
+
* 4. Before each re-run, cleanup functions are called
|
|
11
|
+
* 5. Dependencies are re-tracked on each run (supports conditional reads)
|
|
12
|
+
*
|
|
13
|
+
* ## Key Characteristics
|
|
14
|
+
*
|
|
15
|
+
* - **Synchronous only**: Effects cannot be async (throws if you return a Promise)
|
|
16
|
+
* - **Auto-tracking**: Dependencies detected automatically via signal reads
|
|
17
|
+
* - **Cleanup support**: Register cleanup via `ctx.onCleanup()`
|
|
18
|
+
* - **Error handling**: Register error handlers via `ctx.onError()`
|
|
19
|
+
* - **Deduplication**: Multiple dependency changes in same tick = single re-run
|
|
20
|
+
*
|
|
21
|
+
* @param fn - The effect function to run. Receives an EffectContext.
|
|
22
|
+
* @param options - Optional configuration (key for debugging)
|
|
23
|
+
* @returns A dispose function to stop the effect permanently
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* const [count, setCount] = atom(0);
|
|
28
|
+
*
|
|
29
|
+
* const dispose = effect((ctx) => {
|
|
30
|
+
* console.log("Count:", count()); // count() is auto-tracked
|
|
31
|
+
* });
|
|
32
|
+
* // Output: "Count: 0"
|
|
33
|
+
*
|
|
34
|
+
* setCount(1);
|
|
35
|
+
* // Output: "Count: 1"
|
|
36
|
+
*
|
|
37
|
+
* dispose(); // Stop the effect
|
|
38
|
+
* setCount(2); // No output
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* // With cleanup for subscriptions/timers
|
|
44
|
+
* effect((ctx) => {
|
|
45
|
+
* const interval = setInterval(() => tick(), 1000);
|
|
46
|
+
* ctx.onCleanup(() => clearInterval(interval));
|
|
47
|
+
* });
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* // With error handling
|
|
53
|
+
* effect((ctx) => {
|
|
54
|
+
* ctx.onError((err) => console.error("Effect failed:", err));
|
|
55
|
+
* if (data() === "bad") throw new Error("Invalid data");
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* // Conditional tracking - only re-runs when relevant deps change
|
|
62
|
+
* effect(() => {
|
|
63
|
+
* if (showDetails()) {
|
|
64
|
+
* // details() only tracked when showDetails() is true
|
|
65
|
+
* console.log(details());
|
|
66
|
+
* }
|
|
67
|
+
* });
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare function effect(fn: (context: EffectContext) => void, options?: EffectOptions): VoidFunction;
|
|
71
|
+
/**
|
|
72
|
+
* Creates an effect instance without immediately running it.
|
|
73
|
+
*
|
|
74
|
+
* This is the internal factory used by `effect()`. It's exposed separately
|
|
75
|
+
* for cases where you need to control when the effect first runs (e.g., testing,
|
|
76
|
+
* or deferred initialization).
|
|
77
|
+
*
|
|
78
|
+
* @internal
|
|
79
|
+
* @param fn - The effect function
|
|
80
|
+
* @param options - Optional configuration
|
|
81
|
+
* @returns An object with { options, run, dispose }
|
|
82
|
+
*/
|
|
83
|
+
export declare function effectInstance(fn: (context: EffectContext) => void, options?: EffectOptions): {
|
|
84
|
+
/** Original options passed to effectInstance */
|
|
85
|
+
options: EffectOptions | undefined;
|
|
86
|
+
/** Manually trigger the effect to run */
|
|
87
|
+
run: () => void;
|
|
88
|
+
/** Stop the effect permanently */
|
|
89
|
+
dispose: () => void;
|
|
90
|
+
};
|
|
91
|
+
//# sourceMappingURL=effect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effect.d.ts","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAU,MAAM,SAAS,CAAC;AASpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,wBAAgB,MAAM,CACpB,EAAE,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,EACpC,OAAO,CAAC,EAAE,aAAa,GACtB,YAAY,CAMd;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,EACpC,OAAO,CAAC,EAAE,aAAa;IAsOrB,gDAAgD;;IAEhD,yCAAyC;;IAEzC,kCAAkC;;EAGrC"}
|
package/dist/effect.js
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { emitter } from "./emitter";
|
|
2
|
+
import { getHooks, withHooks } from "./hooks";
|
|
3
|
+
import { isPromiseLike } from "./isPromiseLike";
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// Effect - Reactive Side Effects
|
|
6
|
+
// ============================================================================
|
|
7
|
+
/**
|
|
8
|
+
* Creates a reactive effect that runs when its dependencies change.
|
|
9
|
+
*
|
|
10
|
+
* ## How It Works
|
|
11
|
+
*
|
|
12
|
+
* 1. Effect runs immediately on creation
|
|
13
|
+
* 2. During execution, any atom/signal reads are automatically tracked
|
|
14
|
+
* 3. When any tracked dependency changes, effect re-runs
|
|
15
|
+
* 4. Before each re-run, cleanup functions are called
|
|
16
|
+
* 5. Dependencies are re-tracked on each run (supports conditional reads)
|
|
17
|
+
*
|
|
18
|
+
* ## Key Characteristics
|
|
19
|
+
*
|
|
20
|
+
* - **Synchronous only**: Effects cannot be async (throws if you return a Promise)
|
|
21
|
+
* - **Auto-tracking**: Dependencies detected automatically via signal reads
|
|
22
|
+
* - **Cleanup support**: Register cleanup via `ctx.onCleanup()`
|
|
23
|
+
* - **Error handling**: Register error handlers via `ctx.onError()`
|
|
24
|
+
* - **Deduplication**: Multiple dependency changes in same tick = single re-run
|
|
25
|
+
*
|
|
26
|
+
* @param fn - The effect function to run. Receives an EffectContext.
|
|
27
|
+
* @param options - Optional configuration (key for debugging)
|
|
28
|
+
* @returns A dispose function to stop the effect permanently
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* const [count, setCount] = atom(0);
|
|
33
|
+
*
|
|
34
|
+
* const dispose = effect((ctx) => {
|
|
35
|
+
* console.log("Count:", count()); // count() is auto-tracked
|
|
36
|
+
* });
|
|
37
|
+
* // Output: "Count: 0"
|
|
38
|
+
*
|
|
39
|
+
* setCount(1);
|
|
40
|
+
* // Output: "Count: 1"
|
|
41
|
+
*
|
|
42
|
+
* dispose(); // Stop the effect
|
|
43
|
+
* setCount(2); // No output
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* // With cleanup for subscriptions/timers
|
|
49
|
+
* effect((ctx) => {
|
|
50
|
+
* const interval = setInterval(() => tick(), 1000);
|
|
51
|
+
* ctx.onCleanup(() => clearInterval(interval));
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* // With error handling
|
|
58
|
+
* effect((ctx) => {
|
|
59
|
+
* ctx.onError((err) => console.error("Effect failed:", err));
|
|
60
|
+
* if (data() === "bad") throw new Error("Invalid data");
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* // Conditional tracking - only re-runs when relevant deps change
|
|
67
|
+
* effect(() => {
|
|
68
|
+
* if (showDetails()) {
|
|
69
|
+
* // details() only tracked when showDetails() is true
|
|
70
|
+
* console.log(details());
|
|
71
|
+
* }
|
|
72
|
+
* });
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export function effect(fn, options) {
|
|
76
|
+
const instance = effectInstance(fn, options);
|
|
77
|
+
// Run immediately on creation
|
|
78
|
+
instance.run();
|
|
79
|
+
// Return dispose function for cleanup
|
|
80
|
+
return instance.dispose;
|
|
81
|
+
}
|
|
82
|
+
// ============================================================================
|
|
83
|
+
// Effect Instance - Internal Implementation
|
|
84
|
+
// ============================================================================
|
|
85
|
+
/**
|
|
86
|
+
* Creates an effect instance without immediately running it.
|
|
87
|
+
*
|
|
88
|
+
* This is the internal factory used by `effect()`. It's exposed separately
|
|
89
|
+
* for cases where you need to control when the effect first runs (e.g., testing,
|
|
90
|
+
* or deferred initialization).
|
|
91
|
+
*
|
|
92
|
+
* @internal
|
|
93
|
+
* @param fn - The effect function
|
|
94
|
+
* @param options - Optional configuration
|
|
95
|
+
* @returns An object with { options, run, dispose }
|
|
96
|
+
*/
|
|
97
|
+
export function effectInstance(fn, options) {
|
|
98
|
+
const { key } = options ?? {};
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
// Internal State
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
/** True after dispose() is called - prevents further runs */
|
|
103
|
+
let disposed = false;
|
|
104
|
+
/**
|
|
105
|
+
* True when a re-run is scheduled but not yet executed.
|
|
106
|
+
* Used to deduplicate: if multiple deps change before next tick,
|
|
107
|
+
* we only run once.
|
|
108
|
+
*/
|
|
109
|
+
let scheduled = false;
|
|
110
|
+
/**
|
|
111
|
+
* Error handler emitter. Lazily created when ctx.onError() is first called.
|
|
112
|
+
* If no error handler is registered and an error occurs, it propagates up.
|
|
113
|
+
*/
|
|
114
|
+
let onErrorEmitter;
|
|
115
|
+
/**
|
|
116
|
+
* Cleanup handler emitter. Lazily created when ctx.onCleanup() is first called.
|
|
117
|
+
* Cleanup functions run:
|
|
118
|
+
* - Before each re-run (to clean up previous run's resources)
|
|
119
|
+
* - NOT on dispose (use dispose for final cleanup if needed)
|
|
120
|
+
*/
|
|
121
|
+
let onCleanupEmitter;
|
|
122
|
+
/**
|
|
123
|
+
* Run counter. Starts at -1, incremented before each run.
|
|
124
|
+
* - First run: nth = 0
|
|
125
|
+
* - Second run: nth = 1
|
|
126
|
+
* - etc.
|
|
127
|
+
*
|
|
128
|
+
* Useful for skipping logic on first run:
|
|
129
|
+
* ```ts
|
|
130
|
+
* effect((ctx) => {
|
|
131
|
+
* if (ctx.nth === 0) return; // Skip first run
|
|
132
|
+
* // ... logic for subsequent runs only
|
|
133
|
+
* });
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
let nth = -1;
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
// Context Builders
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
/**
|
|
141
|
+
* Registers a cleanup function to run before the next effect execution.
|
|
142
|
+
*
|
|
143
|
+
* Note: Cleanup does NOT run on dispose - only before re-runs.
|
|
144
|
+
* This matches React's useEffect cleanup behavior.
|
|
145
|
+
*/
|
|
146
|
+
const onCleanup = (listener) => {
|
|
147
|
+
// Lazy creation of cleanup emitter
|
|
148
|
+
if (!onCleanupEmitter)
|
|
149
|
+
onCleanupEmitter = emitter();
|
|
150
|
+
return onCleanupEmitter.on(listener);
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Registers an error handler for this effect.
|
|
154
|
+
*
|
|
155
|
+
* If an error handler is registered, errors are caught and passed to handlers
|
|
156
|
+
* instead of propagating up. If no handler is registered, errors throw normally.
|
|
157
|
+
*/
|
|
158
|
+
const onError = (listener) => {
|
|
159
|
+
// Lazy creation of error emitter
|
|
160
|
+
if (!onErrorEmitter)
|
|
161
|
+
onErrorEmitter = emitter();
|
|
162
|
+
return onErrorEmitter.on(listener);
|
|
163
|
+
};
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
// Core Run Logic
|
|
166
|
+
// ---------------------------------------------------------------------------
|
|
167
|
+
/**
|
|
168
|
+
* Executes the effect function and sets up dependency tracking.
|
|
169
|
+
*
|
|
170
|
+
* Execution flow:
|
|
171
|
+
* 1. Clear scheduled flag
|
|
172
|
+
* 2. Exit early if disposed
|
|
173
|
+
* 3. Run cleanup functions from previous run
|
|
174
|
+
* 4. Clear error handlers (fresh set for this run)
|
|
175
|
+
* 5. Increment run counter
|
|
176
|
+
* 6. Execute effect function with hooks for dependency tracking
|
|
177
|
+
* 7. Check for async (throw if Promise returned)
|
|
178
|
+
* 8. Subscribe to all tracked dependencies
|
|
179
|
+
*/
|
|
180
|
+
const run = () => {
|
|
181
|
+
// Step 1: Clear scheduled flag (we're running now)
|
|
182
|
+
scheduled = false;
|
|
183
|
+
// Step 2: Exit if disposed
|
|
184
|
+
if (disposed)
|
|
185
|
+
return;
|
|
186
|
+
// Step 3: Run cleanup from previous run
|
|
187
|
+
// emitAndClear() calls all listeners then removes them
|
|
188
|
+
onCleanupEmitter?.emitAndClear();
|
|
189
|
+
// Step 4: Clear error handlers (user registers fresh ones each run)
|
|
190
|
+
onErrorEmitter?.clear();
|
|
191
|
+
// Step 5: Increment run counter
|
|
192
|
+
nth++;
|
|
193
|
+
// Track which signals are read during this execution
|
|
194
|
+
const signals = new Set();
|
|
195
|
+
try {
|
|
196
|
+
// Build the context object passed to the effect function
|
|
197
|
+
const ctx = {
|
|
198
|
+
nth,
|
|
199
|
+
key,
|
|
200
|
+
onError,
|
|
201
|
+
onCleanup,
|
|
202
|
+
/**
|
|
203
|
+
* Plugin system for extending context functionality.
|
|
204
|
+
* Same pattern as OnContext.use() in actions.
|
|
205
|
+
*/
|
|
206
|
+
use(plugin, ...args) {
|
|
207
|
+
return plugin(ctx, ...args);
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
// Step 6: Execute effect with hooks enabled
|
|
211
|
+
// withHooks() sets up the tracking context so that:
|
|
212
|
+
// - Any signal.on() call during execution triggers track()
|
|
213
|
+
// - scheduleCleanup is available for nested subscriptions
|
|
214
|
+
const result = withHooks({
|
|
215
|
+
// Register cleanup handlers for subscriptions created during effect
|
|
216
|
+
scheduleCleanup: onCleanup,
|
|
217
|
+
// Track signals that are read during effect execution
|
|
218
|
+
track(signal) {
|
|
219
|
+
signals.add(signal);
|
|
220
|
+
},
|
|
221
|
+
}, () => fn(ctx));
|
|
222
|
+
// Step 7: Check for async functions (common mistake)
|
|
223
|
+
// Effects must be synchronous for predictable dependency tracking
|
|
224
|
+
if (isPromiseLike(result)) {
|
|
225
|
+
throw new Error("effect() received an async function. Effects must be synchronous. " +
|
|
226
|
+
"Use event().on() for async operations instead.");
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
// Handle errors: if error handler registered, emit to it
|
|
231
|
+
// Otherwise, re-throw the error
|
|
232
|
+
if (onErrorEmitter && onErrorEmitter.size > 0) {
|
|
233
|
+
onErrorEmitter.emitAndClear(error);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
throw error;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
finally {
|
|
240
|
+
// Step 8: Subscribe to all tracked dependencies
|
|
241
|
+
// When any dependency changes, schedule a re-run
|
|
242
|
+
// The subscription itself is registered as a cleanup, so it's
|
|
243
|
+
// automatically removed before the next run (then re-added with fresh deps)
|
|
244
|
+
signals.forEach((signal) => onCleanup(signal.on(scheduleRun)));
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
// ---------------------------------------------------------------------------
|
|
248
|
+
// Scheduling
|
|
249
|
+
// ---------------------------------------------------------------------------
|
|
250
|
+
/**
|
|
251
|
+
* Schedules an effect re-run on the next tick.
|
|
252
|
+
*
|
|
253
|
+
* This is called when any tracked dependency changes.
|
|
254
|
+
* Deduplication: if multiple deps change before next tick, only runs once.
|
|
255
|
+
*
|
|
256
|
+
* Uses hooks.scheduleNotify() which typically queues to microtask,
|
|
257
|
+
* allowing multiple sync updates to batch into single effect run.
|
|
258
|
+
*/
|
|
259
|
+
const scheduleRun = () => {
|
|
260
|
+
// Skip if already scheduled or disposed
|
|
261
|
+
if (scheduled || disposed)
|
|
262
|
+
return;
|
|
263
|
+
scheduled = true;
|
|
264
|
+
// Queue the run for next microtask
|
|
265
|
+
getHooks().scheduleNotify(run);
|
|
266
|
+
};
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
268
|
+
// Disposal
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
270
|
+
/**
|
|
271
|
+
* Permanently stops the effect.
|
|
272
|
+
*
|
|
273
|
+
* After dispose:
|
|
274
|
+
* - No more runs will occur
|
|
275
|
+
* - Error and cleanup handlers are cleared
|
|
276
|
+
* - Subscriptions are NOT explicitly cleaned up here - they'll be
|
|
277
|
+
* garbage collected when the effect instance is no longer referenced
|
|
278
|
+
*/
|
|
279
|
+
const dispose = () => {
|
|
280
|
+
if (disposed)
|
|
281
|
+
return;
|
|
282
|
+
disposed = true;
|
|
283
|
+
// Clear emitters to release handler references
|
|
284
|
+
onErrorEmitter?.clear();
|
|
285
|
+
onCleanupEmitter?.emitAndClear();
|
|
286
|
+
};
|
|
287
|
+
// ---------------------------------------------------------------------------
|
|
288
|
+
// Hook Integration
|
|
289
|
+
// ---------------------------------------------------------------------------
|
|
290
|
+
/**
|
|
291
|
+
* Register this effect's dispose with the current hooks context.
|
|
292
|
+
*
|
|
293
|
+
* This enables automatic cleanup when effects are created inside:
|
|
294
|
+
* - React components (via useRx internals)
|
|
295
|
+
* - Other effects (nested effects dispose with parent)
|
|
296
|
+
* - Test harnesses
|
|
297
|
+
*
|
|
298
|
+
* If no scheduleCleanup hook is set, this is a no-op.
|
|
299
|
+
*/
|
|
300
|
+
getHooks().scheduleCleanup?.(dispose);
|
|
301
|
+
// Return the effect instance interface
|
|
302
|
+
return {
|
|
303
|
+
/** Original options passed to effectInstance */
|
|
304
|
+
options,
|
|
305
|
+
/** Manually trigger the effect to run */
|
|
306
|
+
run,
|
|
307
|
+
/** Stop the effect permanently */
|
|
308
|
+
dispose,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
//# sourceMappingURL=effect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effect.js","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effect.test.d.ts","sourceRoot":"","sources":["../src/effect.test.ts"],"names":[],"mappings":""}
|