@but212/atom-effect 0.1.0 → 0.1.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/README.md +1 -2
- package/dist/core/effect/effect.d.ts +61 -0
- package/dist/core/effect/effect.d.ts.map +1 -1
- package/dist/errors/messages.d.ts +79 -0
- package/dist/errors/messages.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +665 -82
- package/dist/index.mjs.map +1 -1
- package/dist/scheduler/batch.d.ts +29 -0
- package/dist/scheduler/batch.d.ts.map +1 -1
- package/dist/scheduler/scheduler.d.ts +130 -0
- package/dist/scheduler/scheduler.d.ts.map +1 -1
- package/dist/tracking/context.d.ts +68 -0
- package/dist/tracking/context.d.ts.map +1 -1
- package/dist/tracking/dependency-manager.d.ts +203 -0
- package/dist/tracking/dependency-manager.d.ts.map +1 -1
- package/dist/tracking/untracked.d.ts +23 -0
- package/dist/tracking/untracked.d.ts.map +1 -1
- package/dist/utils/debug.d.ts +73 -2
- package/dist/utils/debug.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,14 +10,13 @@ A lightweight, high-performance reactive state management library for TypeScript
|
|
|
10
10
|
|
|
11
11
|
- **Core Primitives**: `atom`, `computed`, `effect`, `batch`, `untracked`
|
|
12
12
|
- **Zero Dependencies** - Minimal footprint
|
|
13
|
-
- **Smart Performance** - Object pooling, lazy initialization, O(1) operations
|
|
14
13
|
- **Full TypeScript Support** - Strict type checking
|
|
15
14
|
- **Developer Friendly** - Circular dependency detection, infinite loop protection, auto debug IDs
|
|
16
15
|
|
|
17
16
|
## Installation
|
|
18
17
|
|
|
19
18
|
```bash
|
|
20
|
-
npm
|
|
19
|
+
npm i @but212/atom-effect
|
|
21
20
|
```
|
|
22
21
|
|
|
23
22
|
## Quick Start
|
|
@@ -1,3 +1,64 @@
|
|
|
1
1
|
import { EffectFunction, EffectObject, EffectOptions } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a reactive effect that automatically re-executes when its dependencies change.
|
|
4
|
+
*
|
|
5
|
+
* @param fn - The effect function to execute. May return a cleanup function
|
|
6
|
+
* or a Promise that resolves to a cleanup function.
|
|
7
|
+
* @param options - Configuration options for the effect
|
|
8
|
+
* @param options.sync - If true, re-executes synchronously on dependency changes.
|
|
9
|
+
* Defaults to false (scheduled/batched execution).
|
|
10
|
+
* @param options.maxExecutionsPerSecond - Maximum executions per second before
|
|
11
|
+
* infinite loop detection triggers.
|
|
12
|
+
* Defaults to `SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_SECOND`.
|
|
13
|
+
* @param options.trackModifications - If true, tracks and warns about dependencies
|
|
14
|
+
* that are both read and modified. Defaults to false.
|
|
15
|
+
*
|
|
16
|
+
* @returns An {@link EffectObject} with `run()`, `dispose()`, and state properties
|
|
17
|
+
*
|
|
18
|
+
* @throws {EffectError} If `fn` is not a function
|
|
19
|
+
*
|
|
20
|
+
* @remarks
|
|
21
|
+
* Effects are the primary way to perform side effects in response to reactive
|
|
22
|
+
* state changes. They automatically track which reactive values (atoms, computed)
|
|
23
|
+
* are accessed during execution and re-run when those values change.
|
|
24
|
+
*
|
|
25
|
+
* The effect function may return a cleanup function that will be called before
|
|
26
|
+
* the next execution or when the effect is disposed. This is useful for
|
|
27
|
+
* cleaning up subscriptions, timers, or other resources.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* Basic usage:
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const counter = atom(0);
|
|
33
|
+
*
|
|
34
|
+
* const fx = effect(() => {
|
|
35
|
+
* console.log('Counter:', counter.value);
|
|
36
|
+
* });
|
|
37
|
+
* // Logs: "Counter: 0"
|
|
38
|
+
*
|
|
39
|
+
* counter.value = 1;
|
|
40
|
+
* // Logs: "Counter: 1"
|
|
41
|
+
*
|
|
42
|
+
* fx.dispose(); // Stop the effect
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* With cleanup function:
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const fx = effect(() => {
|
|
49
|
+
* const timer = setInterval(() => console.log('tick'), 1000);
|
|
50
|
+
* return () => clearInterval(timer); // Cleanup
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* Synchronous execution:
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const fx = effect(
|
|
58
|
+
* () => console.log(counter.value),
|
|
59
|
+
* { sync: true }
|
|
60
|
+
* );
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
2
63
|
export declare function effect(fn: EffectFunction, options?: EffectOptions): EffectObject;
|
|
3
64
|
//# sourceMappingURL=effect.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"effect.d.ts","sourceRoot":"","sources":["../../../src/core/effect/effect.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"effect.d.ts","sourceRoot":"","sources":["../../../src/core/effect/effect.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,KAAK,EAAc,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA+jB3F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,wBAAgB,MAAM,CAAC,EAAE,EAAE,cAAc,EAAE,OAAO,GAAE,aAAkB,GAAG,YAAY,CAUpF"}
|
|
@@ -1,22 +1,101 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Centralized error messages for better maintainability
|
|
3
3
|
* @description All error messages in English for international accessibility
|
|
4
|
+
* @module errors/messages
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Centralized error message constants for the atom-effect library.
|
|
8
|
+
*
|
|
9
|
+
* @description
|
|
10
|
+
* Provides consistent, maintainable error messages across the library.
|
|
11
|
+
* All messages are in English for international accessibility.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* - Computed errors: Related to computed atom creation and execution
|
|
15
|
+
* - Atom errors: Related to atom subscription and notification
|
|
16
|
+
* - Effect errors: Related to effect lifecycle and cleanup
|
|
17
|
+
* - Debug warnings: Non-critical warnings for debugging
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { ERROR_MESSAGES } from './messages';
|
|
22
|
+
*
|
|
23
|
+
* if (typeof fn !== 'function') {
|
|
24
|
+
* throw new Error(ERROR_MESSAGES.COMPUTED_MUST_BE_FUNCTION);
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
4
27
|
*/
|
|
5
28
|
export declare const ERROR_MESSAGES: {
|
|
29
|
+
/**
|
|
30
|
+
* Error thrown when computed() receives a non-function argument.
|
|
31
|
+
*/
|
|
6
32
|
readonly COMPUTED_MUST_BE_FUNCTION: "Computed function must be a function";
|
|
33
|
+
/**
|
|
34
|
+
* Error thrown when subscribe() receives a non-function listener.
|
|
35
|
+
*/
|
|
7
36
|
readonly COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION: "Subscriber listener must be a function";
|
|
37
|
+
/**
|
|
38
|
+
* Error thrown when accessing a pending async computed without a default value.
|
|
39
|
+
*/
|
|
8
40
|
readonly COMPUTED_ASYNC_PENDING_NO_DEFAULT: "Async computation is pending. No default value provided";
|
|
41
|
+
/**
|
|
42
|
+
* Error thrown when a synchronous computed computation fails.
|
|
43
|
+
*/
|
|
9
44
|
readonly COMPUTED_COMPUTATION_FAILED: "Computed computation failed";
|
|
45
|
+
/**
|
|
46
|
+
* Error thrown when an asynchronous computed computation fails.
|
|
47
|
+
*/
|
|
10
48
|
readonly COMPUTED_ASYNC_COMPUTATION_FAILED: "Async computed computation failed";
|
|
49
|
+
/**
|
|
50
|
+
* Error thrown when subscribing to a dependency fails.
|
|
51
|
+
*/
|
|
11
52
|
readonly COMPUTED_DEPENDENCY_SUBSCRIPTION_FAILED: "Failed to subscribe to dependency";
|
|
53
|
+
/**
|
|
54
|
+
* Error thrown when atom.subscribe() receives a non-function listener.
|
|
55
|
+
*/
|
|
12
56
|
readonly ATOM_SUBSCRIBER_MUST_BE_FUNCTION: "Subscription listener must be a function";
|
|
57
|
+
/**
|
|
58
|
+
* Error thrown when the atom subscriber notification process fails.
|
|
59
|
+
*/
|
|
13
60
|
readonly ATOM_SUBSCRIBER_EXECUTION_FAILED: "Error occurred while executing atom subscribers";
|
|
61
|
+
/**
|
|
62
|
+
* Error logged when an individual subscriber throws during notification.
|
|
63
|
+
* @remarks This error is caught and logged to prevent cascading failures.
|
|
64
|
+
*/
|
|
14
65
|
readonly ATOM_INDIVIDUAL_SUBSCRIBER_FAILED: "Error during individual atom subscriber execution";
|
|
66
|
+
/**
|
|
67
|
+
* Error thrown when effect() receives a non-function argument.
|
|
68
|
+
*/
|
|
15
69
|
readonly EFFECT_MUST_BE_FUNCTION: "Effect function must be a function";
|
|
70
|
+
/**
|
|
71
|
+
* Error thrown when an effect's execution fails.
|
|
72
|
+
*/
|
|
16
73
|
readonly EFFECT_EXECUTION_FAILED: "Effect execution failed";
|
|
74
|
+
/**
|
|
75
|
+
* Error thrown when an effect's cleanup function fails.
|
|
76
|
+
*/
|
|
17
77
|
readonly EFFECT_CLEANUP_FAILED: "Effect cleanup function execution failed";
|
|
78
|
+
/**
|
|
79
|
+
* Warning message for large dependency graphs.
|
|
80
|
+
*
|
|
81
|
+
* @param count - The number of dependencies detected
|
|
82
|
+
* @returns Formatted warning message with dependency count
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* console.warn(ERROR_MESSAGES.LARGE_DEPENDENCY_GRAPH(150));
|
|
87
|
+
* // Output: "Large dependency graph detected: 150 dependencies"
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
18
90
|
readonly LARGE_DEPENDENCY_GRAPH: (count: number) => string;
|
|
91
|
+
/**
|
|
92
|
+
* Warning logged when attempting to unsubscribe a non-existent listener.
|
|
93
|
+
*/
|
|
19
94
|
readonly UNSUBSCRIBE_NON_EXISTENT: "Attempted to unsubscribe a non-existent listener";
|
|
95
|
+
/**
|
|
96
|
+
* Error logged when the onError callback itself throws an error.
|
|
97
|
+
* @remarks This prevents cascading failures from masking the original error.
|
|
98
|
+
*/
|
|
20
99
|
readonly CALLBACK_ERROR_IN_ERROR_HANDLER: "Error occurred during onError callback execution";
|
|
21
100
|
};
|
|
22
101
|
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/errors/messages.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/errors/messages.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,cAAc;IAKzB;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAOH;;OAEG;;IAGH;;OAEG;;IAGH;;;OAGG;;IAOH;;OAEG;;IAGH;;OAEG;;IAGH;;OAEG;;IAOH;;;;;;;;;;;OAWG;6CAC6B,MAAM,KAAG,MAAM;IAG/C;;OAEG;;IAGH;;;OAGG;;CAEK,CAAC"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S={IDLE:"idle",PENDING:"pending",RESOLVED:"resolved",REJECTED:"rejected"},y={DISPOSED:1,EXECUTING:2},o={DIRTY:1,IDLE:2,PENDING:4,RESOLVED:8,REJECTED:16,RECOMPUTING:32,HAS_ERROR:64},P={MAX_SIZE:1e3,WARMUP_SIZE:100},A={MAX_EXECUTIONS_PER_SECOND:100,CLEANUP_THRESHOLD:100},m={MAX_DEPENDENCIES:1e3,WARN_INFINITE_LOOP:!0};class a extends Error{constructor(e,t=null,s=!0){super(e),this.name="AtomError",this.cause=t,this.recoverable=s,this.timestamp=new Date}}class d extends a{constructor(e,t=null){super(e,t,!0),this.name="ComputedError"}}class f extends a{constructor(e,t=null){super(e,t,!1),this.name="EffectError"}}class D extends a{constructor(e,t=null){super(e,t,!1),this.name="SchedulerError"}}function p(i,e,t){if(i instanceof TypeError)return new e(`Type error (${t}): ${i.message}`,i);if(i instanceof ReferenceError)return new e(`Reference error (${t}): ${i.message}`,i);if(i instanceof a)return i;const s=i instanceof Error?i.message:String(i),r=i instanceof Error?i:null;return new e(`Unexpected error (${t}): ${s}`,r)}function F(i){return i!=null&&typeof i.then=="function"}const u={COMPUTED_MUST_BE_FUNCTION:"Computed function must be a function",COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION:"Subscriber listener must be a function",COMPUTED_ASYNC_PENDING_NO_DEFAULT:"Async computation is pending. No default value provided",COMPUTED_COMPUTATION_FAILED:"Computed computation failed",COMPUTED_ASYNC_COMPUTATION_FAILED:"Async computed computation failed",COMPUTED_DEPENDENCY_SUBSCRIPTION_FAILED:"Failed to subscribe to dependency",ATOM_SUBSCRIBER_MUST_BE_FUNCTION:"Subscription listener must be a function",ATOM_SUBSCRIBER_EXECUTION_FAILED:"Error occurred while executing atom subscribers",ATOM_INDIVIDUAL_SUBSCRIBER_FAILED:"Error during individual atom subscriber execution",EFFECT_MUST_BE_FUNCTION:"Effect function must be a function",EFFECT_EXECUTION_FAILED:"Effect execution failed",EFFECT_CLEANUP_FAILED:"Effect cleanup function execution failed",LARGE_DEPENDENCY_GRAPH:i=>`Large dependency graph detected: ${i} dependencies`,UNSUBSCRIBE_NON_EXISTENT:"Attempted to unsubscribe a non-existent listener",CALLBACK_ERROR_IN_ERROR_HANDLER:"Error occurred during onError callback execution"};class x{constructor(){this.queue=new Set,this.isProcessing=!1,this.isBatching=!1,this.batchDepth=0,this.batchQueue=[],this.batchQueueSize=0,this.isFlushingSync=!1,this.maxFlushIterations=1e3}schedule(e){if(typeof e!="function")throw new D("Scheduler callback must be a function");this.isBatching||this.isFlushingSync?this.batchQueue[this.batchQueueSize++]=e:(this.queue.add(e),this.isProcessing||this.flush())}flush(){if(this.isProcessing||this.queue.size===0)return;this.isProcessing=!0;const e=Array.from(this.queue);this.queue.clear(),queueMicrotask(()=>{for(let t=0;t<e.length;t++)try{e[t]?.()}catch(s){console.error(new D("Error occurred during scheduler execution",s))}this.isProcessing=!1,this.queue.size>0&&!this.isBatching&&this.flush()})}flushSync(){this.isFlushingSync=!0;try{if(this.batchQueueSize>0){for(let t=0;t<this.batchQueueSize;t++)this.queue.add(this.batchQueue[t]);this.batchQueueSize=0}let e=0;for(;this.queue.size>0;){if(++e>this.maxFlushIterations){console.error(new D(`Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop in reactive dependencies. Consider increasing the limit with scheduler.setMaxFlushIterations()`)),this.queue.clear(),this.batchQueueSize=0;break}const t=Array.from(this.queue);this.queue.clear();for(let s=0;s<t.length;s++)try{t[s]?.()}catch(r){console.error(new D("Error occurred during batch execution",r))}if(this.batchQueueSize>0){for(let s=0;s<this.batchQueueSize;s++)this.queue.add(this.batchQueue[s]);this.batchQueueSize=0}}}finally{this.isFlushingSync=!1}}startBatch(){this.batchDepth++,this.isBatching=!0}endBatch(){this.batchDepth=Math.max(0,this.batchDepth-1),this.batchDepth===0&&(this.flushSync(),this.isBatching=!1)}setMaxFlushIterations(e){if(e<10)throw new D("Max flush iterations must be at least 10");this.maxFlushIterations=e}}const b=new x;function v(i){if(typeof i!="function")throw new a("Batch callback must be a function");b.startBatch();try{return i()}catch(e){throw new a("Error occurred during batch execution",e)}finally{b.endBatch()}}const g={current:null,run(i,e){const t=this.current;this.current=i;try{return e()}finally{this.current=t}},getCurrent(){return this.current}};class M{constructor(){this.depMap=new WeakMap,this.depRefs=[],this.cleanupThreshold=100,this.addCount=0}addDependency(e,t){if(this.depMap.has(e)){t();return}this.depMap.set(e,t),this.depRefs.push(new WeakRef(e)),++this.addCount>=this.cleanupThreshold&&(this.cleanup(),this.addCount=0)}removeDependency(e){const t=this.depMap.get(e);if(t){try{t()}catch(s){console.warn("[DependencyManager] Error during unsubscribe:",s)}return this.depMap.delete(e),!0}return!1}hasDependency(e){return this.depMap.has(e)}unsubscribeAll(){for(let e=0;e<this.depRefs.length;e++){const t=this.depRefs[e].deref();if(t){const s=this.depMap.get(t);if(s){try{s()}catch(r){console.warn("[DependencyManager] Error during unsubscribe:",r)}this.depMap.delete(t)}}}this.depRefs.length=0,this.addCount=0}cleanup(){this.depRefs=this.depRefs.filter(e=>e.deref()!==void 0)}get count(){return this.cleanup(),this.depRefs.length}getDependencies(){const e=[];for(let t=0;t<this.depRefs.length;t++){const s=this.depRefs[t].deref();s!==void 0&&e.push(s)}return e}getDepMap(){return this.depMap}setCleanupThreshold(e){this.cleanupThreshold=Math.max(1,e)}}function w(i){if(typeof i!="function")throw new a("Untracked callback must be a function");const e=g.current;g.current=null;try{return i()}catch(t){throw new a("Error occurred during untracked execution",t)}finally{g.current=e}}const C=Symbol("debugName"),L=Symbol("id"),R=Symbol("type"),T=Symbol("noDefaultValue"),h={enabled:typeof process<"u"&&process.env?.NODE_ENV==="development",maxDependencies:m.MAX_DEPENDENCIES,warnInfiniteLoop:m.WARN_INFINITE_LOOP,warn(i,e){this.enabled&&i&&console.warn(`[Atom Effect] ${e}`)},checkCircular(i,e,t=new Set){if(i===e)throw new d("Direct circular dependency detected");if(this.enabled){if(t.has(i))throw new d("Indirect circular dependency detected");if(t.add(i),i&&typeof i=="object"&&"dependencies"in i){const s=i.dependencies;for(const r of s)this.checkCircular(r,e,t)}}},attachDebugInfo(i,e,t){if(!this.enabled)return;const s=i;s[C]=`${e}_${t}`,s[L]=t,s[R]=e},getDebugName(i){if(i&&typeof i=="object"&&C in i)return i[C]},getDebugType(i){if(i&&typeof i=="object"&&R in i)return i[R]}};let k=1;const I=()=>k++;class B{constructor(e,t){this._value=e,this._version=0,this._fnSubs=[],this._fnSubCount=0,this._objSubs=[],this._objSubCount=0,this._sync=t,this._id=I().toString(),h.attachDebugInfo(this,"atom",I())}get value(){const e=g.getCurrent();return e!=null&&this._track(e),this._value}set value(e){if(Object.is(this._value,e))return;const t=this._value,s=++this._version;this._value=e,(this._fnSubCount|this._objSubCount)!==0&&this._notify(e,t,s)}_track(e){if(typeof e=="function"){const t=e;t.addDependency!==void 0?t.addDependency(this):this._addFnSub(e)}else{const t=e;t.addDependency!==void 0?t.addDependency(this):t.execute!==void 0&&this._addObjSub(t)}}_addFnSub(e){const t=this._fnSubs,s=this._fnSubCount;for(let r=0;r<s;r++)if(t[r]===e)return this._createUnsub(r,!0);return t[s]=e,this._fnSubCount=s+1,this._createUnsub(s,!0)}_addObjSub(e){const t=this._objSubs,s=this._objSubCount;for(let r=0;r<s;r++)if(t[r]===e)return;t[s]=e,this._objSubCount=s+1}_createUnsub(e,t){return()=>{t?this._removeFnSub(e):this._removeObjSub(e)}}_removeFnSub(e){const t=this._fnSubCount;if(e>=t)return;const s=t-1,r=this._fnSubs;r[e]=r[s],r[s]=void 0,this._fnSubCount=s}_removeObjSub(e){const t=this._objSubCount;if(e>=t)return;const s=t-1,r=this._objSubs;r[e]=r[s],r[s]=void 0,this._objSubCount=s}_notify(e,t,s){const r=()=>{if(this._version!==s)return;const c=this._fnSubs,n=this._fnSubCount,_=this._objSubs,U=this._objSubCount;for(let E=0;E<n;E++)try{const l=c[E];l&&l(e,t)}catch(l){console.error(new a(u.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,l))}for(let E=0;E<U;E++)try{const l=_[E];l&&l.execute()}catch(l){console.error(new a(u.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,l))}};this._sync&&!b.isBatching?r():b.schedule(r)}subscribe(e){if(typeof e!="function")throw new a(u.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);return this._addFnSub(e)}peek(){return this._value}dispose(){this._fnSubs.length=0,this._objSubs.length=0,this._fnSubCount=0,this._objSubCount=0,this._value=void 0}subscriberCount(){return this._fnSubCount+this._objSubCount}}function j(i,e={}){return new B(i,e.sync??!1)}class O{constructor(){this.subscribers=null,this.subscriberIndex=null}add(e){if(this.subscribers||(this.subscribers=[],this.subscriberIndex=new WeakMap),this.subscriberIndex.has(e))return()=>{};const t=this.subscribers.length;this.subscribers.push(e),this.subscriberIndex.set(e,t);let s=!1;return()=>{s||(s=!0,this.remove(e))}}remove(e){if(!this.subscribers||!this.subscriberIndex)return!1;const t=this.subscriberIndex.get(e);if(t===void 0)return!1;const s=this.subscribers.length-1;if(t!==s){const r=this.subscribers[s];this.subscribers[t]=r,this.subscriberIndex.set(r,t)}return this.subscribers.pop(),this.subscriberIndex.delete(e),!0}has(e){return this.subscriberIndex?.has(e)??!1}forEach(e){if(this.subscribers)for(let t=0;t<this.subscribers.length;t++)e(this.subscribers[t],t)}forEachSafe(e,t){if(this.subscribers)for(let s=0;s<this.subscribers.length;s++)try{e(this.subscribers[s],s)}catch(r){t?t(r):console.error("[SubscriberManager] Error in subscriber callback:",r)}}get size(){return this.subscribers?.length??0}get hasSubscribers(){return this.size>0}clear(){this.subscribers&&(this.subscribers.length=0),this.subscriberIndex=null,this.subscribers=null}toArray(){return this.subscribers?[...this.subscribers]:[]}}class G{constructor(e,t={}){if(this._error=null,this._promiseId=0,this.MAX_PROMISE_ID=Number.MAX_SAFE_INTEGER-1,typeof e!="function")throw new d(u.COMPUTED_MUST_BE_FUNCTION);this._fn=e,this._stateFlags=o.DIRTY|o.IDLE,this._value=void 0;const{equal:s=Object.is,defaultValue:r=T,lazy:c=!0,onError:n=null}=t;if(this._equal=s,this._defaultValue=r,this._hasDefaultValue=r!==T,this._onError=n,this._functionSubscribers=new O,this._objectSubscribers=new O,this._dependencyManager=new M,this._id=I(),h.attachDebugInfo(this,"computed",this._id),h.enabled){const _=this;_.subscriberCount=()=>this._functionSubscribers.size+this._objectSubscribers.size,_.isDirty=()=>this._isDirty(),_.dependencies=this._dependencyManager.getDependencies(),_.stateFlags=this._getFlagsAsString()}if(!c)try{this._recompute()}catch{}}get value(){if((this._stateFlags&(o.RESOLVED|o.DIRTY))===o.RESOLVED)return this._registerTracking(),this._value;const t=this._computeValue();return this._registerTracking(),t}subscribe(e){if(typeof e!="function")throw new d(u.COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION);return this._functionSubscribers.add(e)}peek(){return this._value}get state(){return this._getAsyncState()}get hasError(){return this._isRejected()}get lastError(){return this._error}get isPending(){return this._isPending()}get isResolved(){return this._isResolved()}invalidate(){this._markDirty()}dispose(){this._dependencyManager.unsubscribeAll(),this._functionSubscribers.clear(),this._objectSubscribers.clear(),this._stateFlags=o.DIRTY|o.IDLE,this._error=null,this._value=void 0,this._promiseId=(this._promiseId+1)%this.MAX_PROMISE_ID}_isDirty(){return(this._stateFlags&o.DIRTY)!==0}_setDirty(){this._stateFlags|=o.DIRTY}_clearDirty(){this._stateFlags&=-2}_isIdle(){return(this._stateFlags&o.IDLE)!==0}_setIdle(){this._stateFlags|=o.IDLE,this._stateFlags&=-29}_isPending(){return(this._stateFlags&o.PENDING)!==0}_setPending(){this._stateFlags|=o.PENDING,this._stateFlags&=-27}_isResolved(){return(this._stateFlags&o.RESOLVED)!==0}_setResolved(){this._stateFlags|=o.RESOLVED,this._stateFlags&=-87}_isRejected(){return(this._stateFlags&o.REJECTED)!==0}_setRejected(){this._stateFlags|=o.REJECTED|o.HAS_ERROR,this._stateFlags&=-15}_isRecomputing(){return(this._stateFlags&o.RECOMPUTING)!==0}_setRecomputing(e){e?this._stateFlags|=o.RECOMPUTING:this._stateFlags&=-33}_getAsyncState(){return this._isPending()?S.PENDING:this._isResolved()?S.RESOLVED:this._isRejected()?S.REJECTED:S.IDLE}_getFlagsAsString(){const e=[];return this._isDirty()&&e.push("DIRTY"),this._isIdle()&&e.push("IDLE"),this._isPending()&&e.push("PENDING"),this._isResolved()&&e.push("RESOLVED"),this._isRejected()&&e.push("REJECTED"),this._isRecomputing()&&e.push("RECOMPUTING"),e.join(" | ")}_computeValue(){return this._isRecomputing()?this._value:this._isPending()?this._handlePending():this._isRejected()?this._handleRejected():(this._isDirty()||this._isIdle())&&(this._recompute(),this._isPending())?this._handlePending():this._value}_recompute(){if(!this._isDirty()&&this._isResolved())return;this._setRecomputing(!0);const e=new Set,t=Object.assign(()=>this._markDirty(),{addDependency:s=>e.add(s)});try{const s=g.run(t,this._fn);if(F(s)){this._updateDependencies(e),this._handleAsyncComputation(s),this._setRecomputing(!1);return}this._updateDependencies(e),this._handleSyncResult(s)}catch(s){this._updateDependencies(e),this._handleComputationError(s)}}_handleSyncResult(e){const t=!this._isResolved()||!this._equal(this._value,e);this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),t&&this._notifySubscribers()}_handleAsyncComputation(e){this._setPending(),this._promiseId=this._promiseId>=this.MAX_PROMISE_ID?1:this._promiseId+1;const t=this._promiseId;e.then(s=>{t===this._promiseId&&this._handleAsyncResolution(s)}).catch(s=>{t===this._promiseId&&this._handleAsyncRejection(s)})}_handleAsyncResolution(e){const t=!this._isResolved()||!this._equal(this._value,e);this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),t&&this._notifySubscribers()}_handleAsyncRejection(e){const t=p(e,d,u.COMPUTED_ASYNC_COMPUTATION_FAILED);if(this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError&&typeof this._onError=="function")try{this._onError(t)}catch(s){console.error(u.CALLBACK_ERROR_IN_ERROR_HANDLER,s)}this._notifySubscribers()}_handleComputationError(e){const t=p(e,d,u.COMPUTED_COMPUTATION_FAILED);if(this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError&&typeof this._onError=="function")try{this._onError(t)}catch(s){console.error(u.CALLBACK_ERROR_IN_ERROR_HANDLER,s)}throw t}_handlePending(){if(this._hasDefaultValue)return this._defaultValue;throw new d(u.COMPUTED_ASYNC_PENDING_NO_DEFAULT)}_handleRejected(){if(this._error?.recoverable&&this._hasDefaultValue)return this._defaultValue;throw this._error}_updateDependencies(e){const t=this._dependencyManager.getDependencies();this._hasSameDependencies(t,e)||this._performDeltaSync(t,e)}_hasSameDependencies(e,t){if(e.length!==t.size)return!1;for(let s=0;s<e.length;s++)if(!t.has(e[s]))return!1;return!0}_performDeltaSync(e,t){const s=new Set(e),r=[],c=[];for(let n=0;n<e.length;n++){const _=e[n];t.has(_)||r.push(_)}t.forEach(n=>{s.has(n)||c.push(n)});for(let n=0;n<r.length;n++)this._dependencyManager.removeDependency(r[n]);for(let n=0;n<c.length;n++)this._addDependency(c[n]);e.length=0,t.forEach(n=>{e.push(n)})}_addDependency(e){h.checkCircular(e,this);const t=this._dependencyManager.count;h.warn(t>h.maxDependencies,u.LARGE_DEPENDENCY_GRAPH(t));try{const s=e.subscribe(()=>this._markDirty());this._dependencyManager.addDependency(e,s)}catch(s){throw p(s,d,"dependency subscription")}}_markDirty(){this._isRecomputing()||this._isDirty()||(this._setDirty(),this._setIdle(),(this._functionSubscribers.hasSubscribers||this._objectSubscribers.hasSubscribers)&&b.schedule(()=>{if(this._isDirty())try{this._recompute()}catch{}}))}_notifySubscribers(){!this._functionSubscribers.hasSubscribers&&!this._objectSubscribers.hasSubscribers||b.schedule(()=>{this._functionSubscribers.forEachSafe(e=>e(),e=>console.error(e)),this._objectSubscribers.forEachSafe(e=>e.execute(),e=>console.error(e))})}_registerTracking(){const e=g.getCurrent();e&&(typeof e=="function"?this._functionSubscribers.add(e):e.addDependency?e.addDependency(this):e.execute&&this._objectSubscribers.add(e))}}function V(i,e={}){return new G(i,e)}function N(i){return i!==null&&typeof i=="object"&&"value"in i&&"subscribe"in i&&typeof i.subscribe=="function"}function X(i){if(h.enabled){const e=h.getDebugType(i);if(e)return e==="computed"}return N(i)&&"invalidate"in i&&typeof i.invalidate=="function"}function z(i){return i!==null&&typeof i=="object"&&"dispose"in i&&"run"in i&&typeof i.dispose=="function"&&typeof i.run=="function"}class q{constructor(e,t={}){this.run=()=>{if(this.isDisposed)throw new f(u.EFFECT_MUST_BE_FUNCTION);this.execute()},this.dispose=()=>{this.isDisposed||(this._setDisposed(),this._safeCleanup(),this._depManager.unsubscribeAll(),this._trackedDeps.size>0&&(this._trackedDeps.forEach(s=>{const r=this._originalDescriptors.get(s);if(r)try{Object.defineProperty(s,"value",r)}catch{h.warn(!0,"Failed to restore original descriptor")}}),this._trackedDeps.clear()))},this.addDependency=s=>{try{const r=s.subscribe(()=>{this._sync?this.execute():b.schedule(this.execute)});this._depManager.addDependency(s,r),this._trackModifications&&N(s)&&this._trackModificationsForDep(s)}catch(r){throw p(r,f,u.EFFECT_EXECUTION_FAILED)}},this.execute=()=>{if(this.isDisposed||this.isExecuting)return;const s=Date.now();this._recordExecution(s),this._setExecuting(!0),this._safeCleanup(),this._depManager.unsubscribeAll(),this._modifiedDeps.clear();try{const r=g.run(this,this._fn);this._checkLoopWarnings(),F(r)?r.then(c=>{!this.isDisposed&&typeof c=="function"&&(this._cleanup=c)}).catch(c=>{console.error(p(c,f,u.EFFECT_EXECUTION_FAILED))}):this._cleanup=typeof r=="function"?r:null}catch(r){console.error(p(r,f,u.EFFECT_EXECUTION_FAILED)),this._cleanup=null}finally{this._setExecuting(!1)}},this._fn=e,this._sync=t.sync??!1,this._maxExecutions=t.maxExecutionsPerSecond??A.MAX_EXECUTIONS_PER_SECOND,this._trackModifications=t.trackModifications??!1,this._id=I(),this._flags=0,this._cleanup=null,this._depManager=new M,this._modifiedDeps=new Set,this._originalDescriptors=new WeakMap,this._trackedDeps=new Set,this._historyCapacity=this._maxExecutions+5,this._history=new Float64Array(this._historyCapacity),this._historyIdx=0,this._historyCount=0,this._executionCount=0,h.attachDebugInfo(this,"effect",this._id)}get isDisposed(){return(this._flags&y.DISPOSED)!==0}get executionCount(){return this._executionCount}get isExecuting(){return(this._flags&y.EXECUTING)!==0}_setDisposed(){this._flags|=y.DISPOSED}_setExecuting(e){e?this._flags|=y.EXECUTING:this._flags&=-3}_safeCleanup(){if(this._cleanup&&typeof this._cleanup=="function"){try{this._cleanup()}catch(e){console.error(p(e,f,u.EFFECT_CLEANUP_FAILED))}this._cleanup=null}}_recordExecution(e){if(this._maxExecutions<=0)return;const t=e-1e3;this._history[this._historyIdx]=e,this._historyIdx=(this._historyIdx+1)%this._historyCapacity,this._historyCount<this._historyCapacity&&this._historyCount++,this._executionCount++;let s=0,r=(this._historyIdx-1+this._historyCapacity)%this._historyCapacity;for(let c=0;c<this._historyCount&&!(this._history[r]<t);c++)s++,r=(r-1+this._historyCapacity)%this._historyCapacity;if(s>this._maxExecutions){const c=`Effect executed ${s} times within 1 second. Infinite loop suspected`,n=new f(c);if(this.dispose(),console.error(n),h.enabled)throw n}}_trackModificationsForDep(e){const t=Object.getPrototypeOf(e),s=Object.getOwnPropertyDescriptor(t,"value");if(s?.set&&!this._originalDescriptors.has(e)){this._originalDescriptors.set(e,s),this._trackedDeps.add(e);const r=this;Object.defineProperty(e,"value",{set(c){r._modifiedDeps.add(e),s.set?.call(e,c)},get(){return e.peek()},configurable:!0,enumerable:!0})}}_checkLoopWarnings(){if(this._trackModifications&&h.enabled){const e=this._depManager.getDependencies();for(let t=0;t<e.length;t++){const s=e[t];this._modifiedDeps.has(s)&&h.warn(!0,`Effect is reading a dependency (${h.getDebugName(s)||"unknown"}) that it just modified. Infinite loop may occur`)}}}}function Y(i,e={}){if(typeof i!="function")throw new f(u.EFFECT_MUST_BE_FUNCTION);const t=new q(i,e);return t.execute(),t}exports.AsyncState=S;exports.AtomError=a;exports.ComputedError=d;exports.DEBUG_CONFIG=m;exports.DEBUG_RUNTIME=h;exports.EffectError=f;exports.POOL_CONFIG=P;exports.SCHEDULER_CONFIG=A;exports.SchedulerError=D;exports.atom=j;exports.batch=v;exports.computed=V;exports.effect=Y;exports.isAtom=N;exports.isComputed=X;exports.isEffect=z;exports.scheduler=b;exports.untracked=w;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S={IDLE:"idle",PENDING:"pending",RESOLVED:"resolved",REJECTED:"rejected"},y={DISPOSED:1,EXECUTING:2},o={DIRTY:1,IDLE:2,PENDING:4,RESOLVED:8,REJECTED:16,RECOMPUTING:32,HAS_ERROR:64},P={MAX_SIZE:1e3,WARMUP_SIZE:100},A={MAX_EXECUTIONS_PER_SECOND:100,CLEANUP_THRESHOLD:100},m={MAX_DEPENDENCIES:1e3,WARN_INFINITE_LOOP:!0};class a extends Error{constructor(e,t=null,s=!0){super(e),this.name="AtomError",this.cause=t,this.recoverable=s,this.timestamp=new Date}}class d extends a{constructor(e,t=null){super(e,t,!0),this.name="ComputedError"}}class f extends a{constructor(e,t=null){super(e,t,!1),this.name="EffectError"}}class g extends a{constructor(e,t=null){super(e,t,!1),this.name="SchedulerError"}}function p(i,e,t){if(i instanceof TypeError)return new e(`Type error (${t}): ${i.message}`,i);if(i instanceof ReferenceError)return new e(`Reference error (${t}): ${i.message}`,i);if(i instanceof a)return i;const s=i instanceof Error?i.message:String(i),r=i instanceof Error?i:null;return new e(`Unexpected error (${t}): ${s}`,r)}function F(i){return i!=null&&typeof i.then=="function"}const u={COMPUTED_MUST_BE_FUNCTION:"Computed function must be a function",COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION:"Subscriber listener must be a function",COMPUTED_ASYNC_PENDING_NO_DEFAULT:"Async computation is pending. No default value provided",COMPUTED_COMPUTATION_FAILED:"Computed computation failed",COMPUTED_ASYNC_COMPUTATION_FAILED:"Async computed computation failed",COMPUTED_DEPENDENCY_SUBSCRIPTION_FAILED:"Failed to subscribe to dependency",ATOM_SUBSCRIBER_MUST_BE_FUNCTION:"Subscription listener must be a function",ATOM_SUBSCRIBER_EXECUTION_FAILED:"Error occurred while executing atom subscribers",ATOM_INDIVIDUAL_SUBSCRIBER_FAILED:"Error during individual atom subscriber execution",EFFECT_MUST_BE_FUNCTION:"Effect function must be a function",EFFECT_EXECUTION_FAILED:"Effect execution failed",EFFECT_CLEANUP_FAILED:"Effect cleanup function execution failed",LARGE_DEPENDENCY_GRAPH:i=>`Large dependency graph detected: ${i} dependencies`,UNSUBSCRIBE_NON_EXISTENT:"Attempted to unsubscribe a non-existent listener",CALLBACK_ERROR_IN_ERROR_HANDLER:"Error occurred during onError callback execution"};class x{constructor(){this.queue=new Set,this.isProcessing=!1,this.isBatching=!1,this.batchDepth=0,this.batchQueue=[],this.batchQueueSize=0,this.isFlushingSync=!1,this.maxFlushIterations=1e3}schedule(e){if(typeof e!="function")throw new g("Scheduler callback must be a function");this.isBatching||this.isFlushingSync?this.batchQueue[this.batchQueueSize++]=e:(this.queue.add(e),this.isProcessing||this.flush())}flush(){if(this.isProcessing||this.queue.size===0)return;this.isProcessing=!0;const e=Array.from(this.queue);this.queue.clear(),queueMicrotask(()=>{for(let t=0;t<e.length;t++)try{e[t]?.()}catch(s){console.error(new g("Error occurred during scheduler execution",s))}this.isProcessing=!1,this.queue.size>0&&!this.isBatching&&this.flush()})}flushSync(){this.isFlushingSync=!0;try{if(this.batchQueueSize>0){for(let t=0;t<this.batchQueueSize;t++)this.queue.add(this.batchQueue[t]);this.batchQueueSize=0}let e=0;for(;this.queue.size>0;){if(++e>this.maxFlushIterations){console.error(new g(`Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop in reactive dependencies. Consider increasing the limit with scheduler.setMaxFlushIterations()`)),this.queue.clear(),this.batchQueueSize=0;break}const t=Array.from(this.queue);this.queue.clear();for(let s=0;s<t.length;s++)try{t[s]?.()}catch(r){console.error(new g("Error occurred during batch execution",r))}if(this.batchQueueSize>0){for(let s=0;s<this.batchQueueSize;s++)this.queue.add(this.batchQueue[s]);this.batchQueueSize=0}}}finally{this.isFlushingSync=!1}}startBatch(){this.batchDepth++,this.isBatching=!0}endBatch(){this.batchDepth=Math.max(0,this.batchDepth-1),this.batchDepth===0&&(this.flushSync(),this.isBatching=!1)}setMaxFlushIterations(e){if(e<10)throw new g("Max flush iterations must be at least 10");this.maxFlushIterations=e}}const b=new x;function v(i){if(typeof i!="function")throw new a("Batch callback must be a function");b.startBatch();try{return i()}catch(e){throw new a("Error occurred during batch execution",e)}finally{b.endBatch()}}const D={current:null,run(i,e){const t=this.current;this.current=i;try{return e()}finally{this.current=t}},getCurrent(){return this.current}};class M{constructor(){this.depMap=new WeakMap,this.depRefs=[],this.cleanupThreshold=100,this.addCount=0}addDependency(e,t){if(this.depMap.has(e)){t();return}this.depMap.set(e,t),this.depRefs.push(new WeakRef(e)),++this.addCount>=this.cleanupThreshold&&(this.cleanup(),this.addCount=0)}removeDependency(e){const t=this.depMap.get(e);if(t){try{t()}catch(s){console.warn("[DependencyManager] Error during unsubscribe:",s)}return this.depMap.delete(e),!0}return!1}hasDependency(e){return this.depMap.has(e)}unsubscribeAll(){for(let e=0;e<this.depRefs.length;e++){const t=this.depRefs[e].deref();if(t){const s=this.depMap.get(t);if(s){try{s()}catch(r){console.warn("[DependencyManager] Error during unsubscribe:",r)}this.depMap.delete(t)}}}this.depRefs.length=0,this.addCount=0}cleanup(){this.depRefs=this.depRefs.filter(e=>e.deref()!==void 0)}get count(){return this.cleanup(),this.depRefs.length}getDependencies(){const e=[];for(let t=0;t<this.depRefs.length;t++){const s=this.depRefs[t].deref();s!==void 0&&e.push(s)}return e}getDepMap(){return this.depMap}setCleanupThreshold(e){this.cleanupThreshold=Math.max(1,e)}}function w(i){if(typeof i!="function")throw new a("Untracked callback must be a function");const e=D.current;D.current=null;try{return i()}catch(t){throw new a("Error occurred during untracked execution",t)}finally{D.current=e}}const C=Symbol("debugName"),L=Symbol("id"),R=Symbol("type"),T=Symbol("noDefaultValue");function k(i){return i!==null&&typeof i=="object"&&"dependencies"in i&&i.dependencies instanceof Set}const h={enabled:typeof process<"u"&&process.env?.NODE_ENV==="development",maxDependencies:m.MAX_DEPENDENCIES,warnInfiniteLoop:m.WARN_INFINITE_LOOP,warn(i,e){this.enabled&&i&&console.warn(`[Atom Effect] ${e}`)},checkCircular(i,e,t=new Set){if(i===e)throw new d("Direct circular dependency detected");if(this.enabled){if(t.has(i))throw new d("Indirect circular dependency detected");if(t.add(i),k(i))for(const s of i.dependencies)this.checkCircular(s,e,t)}},attachDebugInfo(i,e,t){if(!this.enabled)return;const s=i;s[C]=`${e}_${t}`,s[L]=t,s[R]=e},getDebugName(i){if(i!==null&&typeof i=="object"&&C in i)return i[C]},getDebugType(i){if(i!==null&&typeof i=="object"&&R in i)return i[R]}};let B=1;const I=()=>B++;class j{constructor(e,t){this._value=e,this._version=0,this._fnSubs=[],this._fnSubCount=0,this._objSubs=[],this._objSubCount=0,this._sync=t,this._id=I().toString(),h.attachDebugInfo(this,"atom",I())}get value(){const e=D.getCurrent();return e!=null&&this._track(e),this._value}set value(e){if(Object.is(this._value,e))return;const t=this._value,s=++this._version;this._value=e,(this._fnSubCount|this._objSubCount)!==0&&this._notify(e,t,s)}_track(e){if(typeof e=="function"){const t=e;t.addDependency!==void 0?t.addDependency(this):this._addFnSub(e)}else{const t=e;t.addDependency!==void 0?t.addDependency(this):t.execute!==void 0&&this._addObjSub(t)}}_addFnSub(e){const t=this._fnSubs,s=this._fnSubCount;for(let r=0;r<s;r++)if(t[r]===e)return this._createUnsub(r,!0);return t[s]=e,this._fnSubCount=s+1,this._createUnsub(s,!0)}_addObjSub(e){const t=this._objSubs,s=this._objSubCount;for(let r=0;r<s;r++)if(t[r]===e)return;t[s]=e,this._objSubCount=s+1}_createUnsub(e,t){return()=>{t?this._removeFnSub(e):this._removeObjSub(e)}}_removeFnSub(e){const t=this._fnSubCount;if(e>=t)return;const s=t-1,r=this._fnSubs;r[e]=r[s],r[s]=void 0,this._fnSubCount=s}_removeObjSub(e){const t=this._objSubCount;if(e>=t)return;const s=t-1,r=this._objSubs;r[e]=r[s],r[s]=void 0,this._objSubCount=s}_notify(e,t,s){const r=()=>{if(this._version!==s)return;const c=this._fnSubs,n=this._fnSubCount,_=this._objSubs,U=this._objSubCount;for(let E=0;E<n;E++)try{const l=c[E];l&&l(e,t)}catch(l){console.error(new a(u.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,l))}for(let E=0;E<U;E++)try{const l=_[E];l&&l.execute()}catch(l){console.error(new a(u.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,l))}};this._sync&&!b.isBatching?r():b.schedule(r)}subscribe(e){if(typeof e!="function")throw new a(u.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);return this._addFnSub(e)}peek(){return this._value}dispose(){this._fnSubs.length=0,this._objSubs.length=0,this._fnSubCount=0,this._objSubCount=0,this._value=void 0}subscriberCount(){return this._fnSubCount+this._objSubCount}}function G(i,e={}){return new j(i,e.sync??!1)}class O{constructor(){this.subscribers=null,this.subscriberIndex=null}add(e){if(this.subscribers||(this.subscribers=[],this.subscriberIndex=new WeakMap),this.subscriberIndex.has(e))return()=>{};const t=this.subscribers.length;this.subscribers.push(e),this.subscriberIndex.set(e,t);let s=!1;return()=>{s||(s=!0,this.remove(e))}}remove(e){if(!this.subscribers||!this.subscriberIndex)return!1;const t=this.subscriberIndex.get(e);if(t===void 0)return!1;const s=this.subscribers.length-1;if(t!==s){const r=this.subscribers[s];this.subscribers[t]=r,this.subscriberIndex.set(r,t)}return this.subscribers.pop(),this.subscriberIndex.delete(e),!0}has(e){return this.subscriberIndex?.has(e)??!1}forEach(e){if(this.subscribers)for(let t=0;t<this.subscribers.length;t++)e(this.subscribers[t],t)}forEachSafe(e,t){if(this.subscribers)for(let s=0;s<this.subscribers.length;s++)try{e(this.subscribers[s],s)}catch(r){t?t(r):console.error("[SubscriberManager] Error in subscriber callback:",r)}}get size(){return this.subscribers?.length??0}get hasSubscribers(){return this.size>0}clear(){this.subscribers&&(this.subscribers.length=0),this.subscriberIndex=null,this.subscribers=null}toArray(){return this.subscribers?[...this.subscribers]:[]}}class V{constructor(e,t={}){if(this._error=null,this._promiseId=0,this.MAX_PROMISE_ID=Number.MAX_SAFE_INTEGER-1,typeof e!="function")throw new d(u.COMPUTED_MUST_BE_FUNCTION);this._fn=e,this._stateFlags=o.DIRTY|o.IDLE,this._value=void 0;const{equal:s=Object.is,defaultValue:r=T,lazy:c=!0,onError:n=null}=t;if(this._equal=s,this._defaultValue=r,this._hasDefaultValue=r!==T,this._onError=n,this._functionSubscribers=new O,this._objectSubscribers=new O,this._dependencyManager=new M,this._id=I(),h.attachDebugInfo(this,"computed",this._id),h.enabled){const _=this;_.subscriberCount=()=>this._functionSubscribers.size+this._objectSubscribers.size,_.isDirty=()=>this._isDirty(),_.dependencies=this._dependencyManager.getDependencies(),_.stateFlags=this._getFlagsAsString()}if(!c)try{this._recompute()}catch{}}get value(){if((this._stateFlags&(o.RESOLVED|o.DIRTY))===o.RESOLVED)return this._registerTracking(),this._value;const t=this._computeValue();return this._registerTracking(),t}subscribe(e){if(typeof e!="function")throw new d(u.COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION);return this._functionSubscribers.add(e)}peek(){return this._value}get state(){return this._getAsyncState()}get hasError(){return this._isRejected()}get lastError(){return this._error}get isPending(){return this._isPending()}get isResolved(){return this._isResolved()}invalidate(){this._markDirty()}dispose(){this._dependencyManager.unsubscribeAll(),this._functionSubscribers.clear(),this._objectSubscribers.clear(),this._stateFlags=o.DIRTY|o.IDLE,this._error=null,this._value=void 0,this._promiseId=(this._promiseId+1)%this.MAX_PROMISE_ID}_isDirty(){return(this._stateFlags&o.DIRTY)!==0}_setDirty(){this._stateFlags|=o.DIRTY}_clearDirty(){this._stateFlags&=-2}_isIdle(){return(this._stateFlags&o.IDLE)!==0}_setIdle(){this._stateFlags|=o.IDLE,this._stateFlags&=-29}_isPending(){return(this._stateFlags&o.PENDING)!==0}_setPending(){this._stateFlags|=o.PENDING,this._stateFlags&=-27}_isResolved(){return(this._stateFlags&o.RESOLVED)!==0}_setResolved(){this._stateFlags|=o.RESOLVED,this._stateFlags&=-87}_isRejected(){return(this._stateFlags&o.REJECTED)!==0}_setRejected(){this._stateFlags|=o.REJECTED|o.HAS_ERROR,this._stateFlags&=-15}_isRecomputing(){return(this._stateFlags&o.RECOMPUTING)!==0}_setRecomputing(e){e?this._stateFlags|=o.RECOMPUTING:this._stateFlags&=-33}_getAsyncState(){return this._isPending()?S.PENDING:this._isResolved()?S.RESOLVED:this._isRejected()?S.REJECTED:S.IDLE}_getFlagsAsString(){const e=[];return this._isDirty()&&e.push("DIRTY"),this._isIdle()&&e.push("IDLE"),this._isPending()&&e.push("PENDING"),this._isResolved()&&e.push("RESOLVED"),this._isRejected()&&e.push("REJECTED"),this._isRecomputing()&&e.push("RECOMPUTING"),e.join(" | ")}_computeValue(){return this._isRecomputing()?this._value:this._isPending()?this._handlePending():this._isRejected()?this._handleRejected():(this._isDirty()||this._isIdle())&&(this._recompute(),this._isPending())?this._handlePending():this._value}_recompute(){if(!this._isDirty()&&this._isResolved())return;this._setRecomputing(!0);const e=new Set,t=Object.assign(()=>this._markDirty(),{addDependency:s=>e.add(s)});try{const s=D.run(t,this._fn);if(F(s)){this._updateDependencies(e),this._handleAsyncComputation(s),this._setRecomputing(!1);return}this._updateDependencies(e),this._handleSyncResult(s)}catch(s){this._updateDependencies(e),this._handleComputationError(s)}}_handleSyncResult(e){const t=!this._isResolved()||!this._equal(this._value,e);this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),t&&this._notifySubscribers()}_handleAsyncComputation(e){this._setPending(),this._promiseId=this._promiseId>=this.MAX_PROMISE_ID?1:this._promiseId+1;const t=this._promiseId;e.then(s=>{t===this._promiseId&&this._handleAsyncResolution(s)}).catch(s=>{t===this._promiseId&&this._handleAsyncRejection(s)})}_handleAsyncResolution(e){const t=!this._isResolved()||!this._equal(this._value,e);this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),t&&this._notifySubscribers()}_handleAsyncRejection(e){const t=p(e,d,u.COMPUTED_ASYNC_COMPUTATION_FAILED);if(this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError&&typeof this._onError=="function")try{this._onError(t)}catch(s){console.error(u.CALLBACK_ERROR_IN_ERROR_HANDLER,s)}this._notifySubscribers()}_handleComputationError(e){const t=p(e,d,u.COMPUTED_COMPUTATION_FAILED);if(this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError&&typeof this._onError=="function")try{this._onError(t)}catch(s){console.error(u.CALLBACK_ERROR_IN_ERROR_HANDLER,s)}throw t}_handlePending(){if(this._hasDefaultValue)return this._defaultValue;throw new d(u.COMPUTED_ASYNC_PENDING_NO_DEFAULT)}_handleRejected(){if(this._error?.recoverable&&this._hasDefaultValue)return this._defaultValue;throw this._error}_updateDependencies(e){const t=this._dependencyManager.getDependencies();this._hasSameDependencies(t,e)||this._performDeltaSync(t,e)}_hasSameDependencies(e,t){if(e.length!==t.size)return!1;for(let s=0;s<e.length;s++)if(!t.has(e[s]))return!1;return!0}_performDeltaSync(e,t){const s=new Set(e),r=[],c=[];for(let n=0;n<e.length;n++){const _=e[n];t.has(_)||r.push(_)}t.forEach(n=>{s.has(n)||c.push(n)});for(let n=0;n<r.length;n++)this._dependencyManager.removeDependency(r[n]);for(let n=0;n<c.length;n++)this._addDependency(c[n]);e.length=0,t.forEach(n=>{e.push(n)})}_addDependency(e){h.checkCircular(e,this);const t=this._dependencyManager.count;h.warn(t>h.maxDependencies,u.LARGE_DEPENDENCY_GRAPH(t));try{const s=e.subscribe(()=>this._markDirty());this._dependencyManager.addDependency(e,s)}catch(s){throw p(s,d,"dependency subscription")}}_markDirty(){this._isRecomputing()||this._isDirty()||(this._setDirty(),this._setIdle(),(this._functionSubscribers.hasSubscribers||this._objectSubscribers.hasSubscribers)&&b.schedule(()=>{if(this._isDirty())try{this._recompute()}catch{}}))}_notifySubscribers(){!this._functionSubscribers.hasSubscribers&&!this._objectSubscribers.hasSubscribers||b.schedule(()=>{this._functionSubscribers.forEachSafe(e=>e(),e=>console.error(e)),this._objectSubscribers.forEachSafe(e=>e.execute(),e=>console.error(e))})}_registerTracking(){const e=D.getCurrent();e&&(typeof e=="function"?this._functionSubscribers.add(e):e.addDependency?e.addDependency(this):e.execute&&this._objectSubscribers.add(e))}}function X(i,e={}){return new V(i,e)}function N(i){return i!==null&&typeof i=="object"&&"value"in i&&"subscribe"in i&&typeof i.subscribe=="function"}function z(i){if(h.enabled){const e=h.getDebugType(i);if(e)return e==="computed"}return N(i)&&"invalidate"in i&&typeof i.invalidate=="function"}function q(i){return i!==null&&typeof i=="object"&&"dispose"in i&&"run"in i&&typeof i.dispose=="function"&&typeof i.run=="function"}class Y{constructor(e,t={}){this.run=()=>{if(this.isDisposed)throw new f(u.EFFECT_MUST_BE_FUNCTION);this.execute()},this.dispose=()=>{this.isDisposed||(this._setDisposed(),this._safeCleanup(),this._depManager.unsubscribeAll(),this._trackedDeps.size>0&&(this._trackedDeps.forEach(s=>{const r=this._originalDescriptors.get(s);if(r)try{Object.defineProperty(s,"value",r)}catch{h.warn(!0,"Failed to restore original descriptor")}}),this._trackedDeps.clear()))},this.addDependency=s=>{try{const r=s.subscribe(()=>{this._sync?this.execute():b.schedule(this.execute)});this._depManager.addDependency(s,r),this._trackModifications&&N(s)&&this._trackModificationsForDep(s)}catch(r){throw p(r,f,u.EFFECT_EXECUTION_FAILED)}},this.execute=()=>{if(this.isDisposed||this.isExecuting)return;const s=Date.now();this._recordExecution(s),this._setExecuting(!0),this._safeCleanup(),this._depManager.unsubscribeAll(),this._modifiedDeps.clear();try{const r=D.run(this,this._fn);this._checkLoopWarnings(),F(r)?r.then(c=>{!this.isDisposed&&typeof c=="function"&&(this._cleanup=c)}).catch(c=>{console.error(p(c,f,u.EFFECT_EXECUTION_FAILED))}):this._cleanup=typeof r=="function"?r:null}catch(r){console.error(p(r,f,u.EFFECT_EXECUTION_FAILED)),this._cleanup=null}finally{this._setExecuting(!1)}},this._fn=e,this._sync=t.sync??!1,this._maxExecutions=t.maxExecutionsPerSecond??A.MAX_EXECUTIONS_PER_SECOND,this._trackModifications=t.trackModifications??!1,this._id=I(),this._flags=0,this._cleanup=null,this._depManager=new M,this._modifiedDeps=new Set,this._originalDescriptors=new WeakMap,this._trackedDeps=new Set,this._historyCapacity=this._maxExecutions+5,this._history=new Float64Array(this._historyCapacity),this._historyIdx=0,this._historyCount=0,this._executionCount=0,h.attachDebugInfo(this,"effect",this._id)}get isDisposed(){return(this._flags&y.DISPOSED)!==0}get executionCount(){return this._executionCount}get isExecuting(){return(this._flags&y.EXECUTING)!==0}_setDisposed(){this._flags|=y.DISPOSED}_setExecuting(e){e?this._flags|=y.EXECUTING:this._flags&=-3}_safeCleanup(){if(this._cleanup&&typeof this._cleanup=="function"){try{this._cleanup()}catch(e){console.error(p(e,f,u.EFFECT_CLEANUP_FAILED))}this._cleanup=null}}_recordExecution(e){if(this._maxExecutions<=0)return;const t=e-1e3;this._history[this._historyIdx]=e,this._historyIdx=(this._historyIdx+1)%this._historyCapacity,this._historyCount<this._historyCapacity&&this._historyCount++,this._executionCount++;let s=0,r=(this._historyIdx-1+this._historyCapacity)%this._historyCapacity;for(let c=0;c<this._historyCount&&!(this._history[r]<t);c++)s++,r=(r-1+this._historyCapacity)%this._historyCapacity;if(s>this._maxExecutions){const c=`Effect executed ${s} times within 1 second. Infinite loop suspected`,n=new f(c);if(this.dispose(),console.error(n),h.enabled)throw n}}_trackModificationsForDep(e){const t=Object.getPrototypeOf(e),s=Object.getOwnPropertyDescriptor(t,"value");if(s?.set&&!this._originalDescriptors.has(e)){this._originalDescriptors.set(e,s),this._trackedDeps.add(e);const r=this;Object.defineProperty(e,"value",{set(c){r._modifiedDeps.add(e),s.set?.call(e,c)},get(){return e.peek()},configurable:!0,enumerable:!0})}}_checkLoopWarnings(){if(this._trackModifications&&h.enabled){const e=this._depManager.getDependencies();for(let t=0;t<e.length;t++){const s=e[t];this._modifiedDeps.has(s)&&h.warn(!0,`Effect is reading a dependency (${h.getDebugName(s)||"unknown"}) that it just modified. Infinite loop may occur`)}}}}function Q(i,e={}){if(typeof i!="function")throw new f(u.EFFECT_MUST_BE_FUNCTION);const t=new Y(i,e);return t.execute(),t}exports.AsyncState=S;exports.AtomError=a;exports.ComputedError=d;exports.DEBUG_CONFIG=m;exports.DEBUG_RUNTIME=h;exports.EffectError=f;exports.POOL_CONFIG=P;exports.SCHEDULER_CONFIG=A;exports.SchedulerError=g;exports.atom=G;exports.batch=v;exports.computed=X;exports.effect=Q;exports.isAtom=N;exports.isComputed=z;exports.isEffect=q;exports.scheduler=b;exports.untracked=w;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|