@but212/atom-effect 0.9.0 → 0.9.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 +17 -7
- package/dist/atom-effect.min.js +1 -1
- package/dist/atom-effect.min.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +49 -47
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,6 +12,14 @@ Lightweight, high-performance reactive state management.
|
|
|
12
12
|
npm i @but212/atom-effect
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
### CDN
|
|
16
|
+
|
|
17
|
+
```html
|
|
18
|
+
<script src="https://cdn.jsdelivr.net/npm/@but212/atom-effect@latest"></script>
|
|
19
|
+
<!-- or -->
|
|
20
|
+
<script src="https://unpkg.com/@but212/atom-effect@latest"></script>
|
|
21
|
+
```
|
|
22
|
+
|
|
15
23
|
## Core API
|
|
16
24
|
|
|
17
25
|
### `atom(value)`
|
|
@@ -131,15 +139,17 @@ pnpm build # Build production bundle
|
|
|
131
139
|
|
|
132
140
|
Verified benchmarks vs object pooling and lazy evaluation optimizations.
|
|
133
141
|
|
|
142
|
+
> *Note: These numbers represent pure engine throughput in isolation. Actual app performance often depends on external factors like DOM updates and layout.*
|
|
143
|
+
|
|
134
144
|
| Operation | Performance |
|
|
135
145
|
| --- | --- |
|
|
136
|
-
| Atom creation | ~4.
|
|
137
|
-
| Atom read/write | ~9.
|
|
138
|
-
| Computed creation | ~1.
|
|
139
|
-
| Computed recomputation | ~
|
|
140
|
-
| Effect execution | ~
|
|
141
|
-
| Batched updates | ~3.
|
|
142
|
-
| Deep chain (100 levels) | ~8.
|
|
146
|
+
| Atom creation | ~4.69M ops/sec |
|
|
147
|
+
| Atom read/write | ~9.52M ops/sec |
|
|
148
|
+
| Computed creation | ~1.80M ops/sec |
|
|
149
|
+
| Computed recomputation | ~583K ops/sec |
|
|
150
|
+
| Effect execution | ~2.96M ops/sec |
|
|
151
|
+
| Batched updates | ~3.82M ops/sec |
|
|
152
|
+
| Deep chain (100 levels) | ~8.2K ops/sec |
|
|
143
153
|
|
|
144
154
|
## Contributing
|
|
145
155
|
|
package/dist/atom-effect.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(c,A){typeof exports=="object"&&typeof module<"u"?A(exports):typeof define=="function"&&define.amd?define(["exports"],A):(c=typeof globalThis<"u"?globalThis:c||self,A(c.AtomEffect={}))})(this,(function(c){"use strict";const A={ONE_SECOND_MS:1e3},O={IDLE:"idle",PENDING:"pending",RESOLVED:"resolved",REJECTED:"rejected"},F={DISPOSED:1,EXECUTING:2},h={DIRTY:1,IDLE:2,PENDING:4,RESOLVED:8,REJECTED:16,RECOMPUTING:32,HAS_ERROR:64},ie={MAX_SIZE:1e3,WARMUP_SIZE:100},g={MAX_EXECUTIONS_PER_SECOND:1e3,CLEANUP_THRESHOLD:1e3,MAX_EXECUTIONS_PER_EFFECT:100,MAX_EXECUTIONS_PER_FLUSH:1e4,MAX_FLUSH_ITERATIONS:1e3,MIN_FLUSH_ITERATIONS:10},w={MAX_DEPENDENCIES:1e3,WARN_INFINITE_LOOP:!0},I=1073741823,l=typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production",ne=Object.freeze([]);class E extends Error{constructor(e,t=null,i=!0){super(e),this.name="AtomError",this.cause=t,this.recoverable=i,this.timestamp=new Date}}class m extends E{constructor(e,t=null){super(e,t,!0),this.name="ComputedError"}}class D extends E{constructor(e,t=null){super(e,t,!1),this.name="EffectError"}}class U extends E{constructor(e,t=null){super(e,t,!1),this.name="SchedulerError"}}const u={COMPUTED_MUST_BE_FUNCTION:"Computed function 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",ATOM_SUBSCRIBER_MUST_BE_FUNCTION:"Subscription listener must be a function or Subscriber object",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",CALLBACK_ERROR_IN_ERROR_HANDLER:"Error occurred during onError callback execution"},k=Symbol("debugName"),re=Symbol("id"),q=Symbol("type"),z=Symbol("noDefaultValue");function oe(s){return"dependencies"in s&&Array.isArray(s.dependencies)}let G=0;function X(s,e,t){if(s._visitedEpoch!==t){if(s._visitedEpoch=t,s===e)throw new m("Indirect circular dependency detected");if(oe(s)){const i=s.dependencies;for(let n=0;n<i.length;n++){const r=i[n];r&&X(r,e,t)}}}}const f={enabled:typeof process<"u"&&process.env?.NODE_ENV==="development",maxDependencies:w.MAX_DEPENDENCIES,warnInfiniteLoop:w.WARN_INFINITE_LOOP,warn(s,e){this.enabled&&s&&console.warn(`[Atom Effect] ${e}`)},checkCircular(s,e){if(s===e)throw new m("Direct circular dependency detected");this.enabled&&(G++,X(s,e,G))},attachDebugInfo(s,e,t){if(!this.enabled)return;const i=s;i[k]=`${e}_${t}`,i[re]=t,i[q]=e},getDebugName(s){if(s!=null&&k in s)return s[k]},getDebugType(s){if(s!=null&&q in s)return s[q]}};let ce=1;const he=()=>ce++;class Y{constructor(){this.id=he()&I,this.flags=0}}class H extends Y{constructor(){super(),this.version=0,this._lastSeenEpoch=-1}subscribe(e){if(typeof e=="object"&&e!==null&&"execute"in e)return this._objectSubscribers.add(e);if(typeof e!="function")throw new E(u.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);return this._functionSubscribers.add(e)}subscriberCount(){return this._functionSubscribers.size+this._objectSubscribers.size}_notifySubscribers(e,t){this._functionSubscribers.forEachSafe(i=>i(e,t),i=>console.error(new E(u.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,i))),this._objectSubscribers.forEachSafe(i=>i.execute(),i=>console.error(new E(u.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,i)))}}let v=0;function J(){return v=v+1&I||1,v}function ue(){return v}let P=0,B=0,M=!1;function Q(){return M?(l&&console.warn("Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"),!1):(M=!0,P=P+1&I,B=0,!0)}function $(){M=!1}function _e(){return M?++B:0}class ae{constructor(){this.queueA=[],this.queueB=[],this.queue=this.queueA,this.queueSize=0,this._epoch=0,this.isProcessing=!1,this.isBatching=!1,this.batchDepth=0,this.batchQueue=[],this.batchQueueSize=0,this.isFlushingSync=!1,this.maxFlushIterations=g.MAX_FLUSH_ITERATIONS}get phase(){return this.isProcessing||this.isFlushingSync?2:this.isBatching?1:0}schedule(e){if(typeof e!="function")throw new U("Scheduler callback must be a function");e._nextEpoch!==this._epoch&&(e._nextEpoch=this._epoch,this.isBatching||this.isFlushingSync?this.batchQueue[this.batchQueueSize++]=e:(this.queue[this.queueSize++]=e,this.isProcessing||this.flush()))}flush(){if(this.isProcessing||this.queueSize===0)return;this.isProcessing=!0;const e=this.queue,t=this.queueSize;this.queue=this.queue===this.queueA?this.queueB:this.queueA,this.queueSize=0,this._epoch++,queueMicrotask(()=>{const i=Q();this._processJobs(e,t),this.isProcessing=!1,i&&$(),this.queueSize>0&&!this.isBatching&&this.flush()})}flushSync(){this.isFlushingSync=!0;const e=Q();try{this._mergeBatchQueue(),this._drainQueue()}finally{this.isFlushingSync=!1,e&&$()}}_mergeBatchQueue(){if(this._epoch++,this.batchQueueSize>0){for(let e=0;e<this.batchQueueSize;e++){const t=this.batchQueue[e];t&&t._nextEpoch!==this._epoch&&(t._nextEpoch=this._epoch,this.queue[this.queueSize++]=t)}this.batchQueueSize=0}}_drainQueue(){let e=0;for(;this.queueSize>0;){if(++e>this.maxFlushIterations){this._handleFlushOverflow();break}this._processCurrentQueue(),this._mergeBatchQueue()}}_processCurrentQueue(){const e=this.queue,t=this.queueSize;this.queue=this.queue===this.queueA?this.queueB:this.queueA,this.queueSize=0,this._epoch++,this._processJobs(e,t)}_handleFlushOverflow(){console.error(new U(`Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop.`)),this.queueSize=0,this.queue.length=0,this.batchQueueSize=0}_processJobs(e,t){for(let i=0;i<t;i++)try{e[i]?.()}catch(n){console.error(new U("Error occurred during scheduler execution",n))}e.length=0}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<g.MIN_FLUSH_ITERATIONS)throw new U(`Max flush iterations must be at least ${g.MIN_FLUSH_ITERATIONS}`);this.maxFlushIterations=e}}const R=new ae;function le(s){if(typeof s!="function")throw new E("Batch callback must be a function");R.startBatch();try{return s()}finally{R.endBatch()}}const C={current:null,run(s,e){const t=this.current;this.current=s;try{return e()}finally{this.current=t}},getCurrent(){return this.current}};function W(s){if(typeof s!="function")throw new E("Untracked callback must be a function");const e=C.current;C.current=null;try{return s()}finally{C.current=e}}class L{constructor(){this.subscribers=null}add(e){if(this.subscribers||(this.subscribers=[]),this.subscribers.indexOf(e)!==-1)return()=>{};this.subscribers.push(e);let t=!1;return()=>{t||(t=!0,this.remove(e))}}remove(e){if(!this.subscribers)return!1;const t=this.subscribers.indexOf(e);if(t===-1)return!1;const i=this.subscribers.length-1;return t!==i&&(this.subscribers[t]=this.subscribers[i]),this.subscribers.pop(),!0}has(e){return this.subscribers?this.subscribers.indexOf(e)!==-1:!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 i=0;i<this.subscribers.length;i++)try{e(this.subscribers[i],i)}catch(n){t?t(n):console.error("[SubscriberManager] Error in subscriber callback:",n)}}get size(){return this.subscribers?.length??0}get hasSubscribers(){return this.subscribers!==null&&this.subscribers.length>0}clear(){this.subscribers=null}toArray(){return this.subscribers?[...this.subscribers]:[]}}class j{constructor(){this.pool=[],this.maxPoolSize=50,this.maxReusableCapacity=256,this.stats=l?{acquired:0,released:0,rejected:{frozen:0,tooLarge:0,poolFull:0}}:null}acquire(){return l&&this.stats&&this.stats.acquired++,this.pool.pop()??[]}release(e,t){if(!(t&&e===t)){if(Object.isFrozen(e)){l&&this.stats&&this.stats.rejected.frozen++;return}if(e.length>this.maxReusableCapacity){l&&this.stats&&this.stats.rejected.tooLarge++;return}if(this.pool.length>=this.maxPoolSize){l&&this.stats&&this.stats.rejected.poolFull++;return}e.length=0,this.pool.push(e),l&&this.stats&&this.stats.released++}}getStats(){if(!l||!this.stats)return null;const{acquired:e,released:t,rejected:i}=this.stats,n=i.frozen+i.tooLarge+i.poolFull;return{acquired:e,released:t,rejected:i,leaked:e-t-n,poolSize:this.pool.length}}reset(){this.pool.length=0,l&&this.stats&&(this.stats.acquired=0,this.stats.released=0,this.stats.rejected={frozen:0,tooLarge:0,poolFull:0})}}const _=Object.freeze([]),p=Object.freeze([]),a=Object.freeze([]),y=new j,N=new j,b=new j;function K(s){return s!==null&&typeof s=="object"&&"value"in s&&"subscribe"in s&&typeof s.subscribe=="function"}function fe(s){if(f.enabled&&(s==null||typeof s=="object")){const e=f.getDebugType(s);if(e)return e==="computed"}return K(s)&&"invalidate"in s&&typeof s.invalidate=="function"}function de(s){return s!==null&&typeof s=="object"&&"dispose"in s&&"run"in s&&typeof s.dispose=="function"&&typeof s.run=="function"}function Z(s){return s!=null&&typeof s.then=="function"}function Ee(s){return typeof s=="object"&&s!==null}function pe(s){return(typeof s=="object"||typeof s=="function")&&s!==null&&typeof s.addDependency=="function"}function be(s){return typeof s=="function"&&typeof s.addDependency!="function"}function Se(s){return Ee(s)&&typeof s.execute=="function"}function ee(s,e,t,i){if(e){if(pe(e)){e.addDependency(s);return}if(be(e)){t.add(e);return}Se(e)&&i.add(e)}}function ge(s,e,t,i){if(e!==_&&t!==p)for(let r=0;r<e.length;r++){const o=e[r];o&&(o._tempUnsub=t[r])}const n=N.acquire();n.length=s.length;for(let r=0;r<s.length;r++){const o=s[r];o&&(o._tempUnsub?(n[r]=o._tempUnsub,o._tempUnsub=void 0):(f.checkCircular(o,i),n[r]=o.subscribe(i)))}if(e!==_)for(let r=0;r<e.length;r++){const o=e[r];o?._tempUnsub&&(o._tempUnsub(),o._tempUnsub=void 0)}return t!==p&&N.release(t),n}class De extends H{constructor(e,t){super(),this._isNotificationScheduled=!1,this._value=e,this._functionSubscribersStore=new L,this._objectSubscribersStore=new L,this._sync=t,this._notifyTask=this._flushNotifications.bind(this),f.attachDebugInfo(this,"atom",this.id)}get _functionSubscribers(){return this._functionSubscribersStore}get _objectSubscribers(){return this._objectSubscribersStore}get value(){const e=C.getCurrent();return e&&this._track(e),this._value}set value(e){if(Object.is(this._value,e))return;const t=this._value;this.version=this.version+1&I,this._value=e,!(!this._functionSubscribersStore.hasSubscribers&&!this._objectSubscribersStore.hasSubscribers)&&this._scheduleNotification(t)}_track(e){ee(this,e,this._functionSubscribersStore,this._objectSubscribersStore)}_scheduleNotification(e){this._isNotificationScheduled||(this._pendingOldValue=e,this._isNotificationScheduled=!0),this._sync&&!R.isBatching?this._flushNotifications():R.schedule(this._notifyTask)}_flushNotifications(){if(!this._isNotificationScheduled)return;const e=this._pendingOldValue,t=this._value;this._pendingOldValue=void 0,this._isNotificationScheduled=!1,this._notifySubscribers(t,e)}peek(){return this._value}dispose(){this._functionSubscribersStore.clear(),this._objectSubscribersStore.clear(),this._value=void 0}}function ye(s,e={}){return new De(s,e.sync??!1)}function x(s,e,t){if(s instanceof TypeError)return new e(`Type error (${t}): ${s.message}`,s);if(s instanceof ReferenceError)return new e(`Reference error (${t}): ${s.message}`,s);if(s instanceof E)return s;const i=s instanceof Error?s.message:String(s),n=s instanceof Error?s:null;return new e(`Unexpected error (${t}): ${i}`,n)}const te=h.RESOLVED|h.PENDING|h.REJECTED,V=Array(te+1).fill(O.IDLE);V[h.RESOLVED]=O.RESOLVED,V[h.PENDING]=O.PENDING,V[h.REJECTED]=O.REJECTED;class se extends H{constructor(e,t={}){if(typeof e!="function")throw new m(u.COMPUTED_MUST_BE_FUNCTION);if(super(),this._cachedErrors=null,this._errorCacheEpoch=-1,this._value=void 0,this.flags=h.DIRTY|h.IDLE,this._error=null,this._promiseId=0,this._equal=t.equal??Object.is,this._fn=e,this._defaultValue="defaultValue"in t?t.defaultValue:z,this._hasDefaultValue=this._defaultValue!==z,this._onError=t.onError??null,this.MAX_PROMISE_ID=Number.MAX_SAFE_INTEGER-1,this._functionSubscribersStore=new L,this._objectSubscribersStore=new L,this._dependencies=_,this._dependencyVersions=a,this._unsubscribes=p,this._notifyJob=()=>{this._functionSubscribersStore.forEachSafe(i=>i(),i=>console.error(i)),this._objectSubscribersStore.forEachSafe(i=>i.execute(),i=>console.error(i))},this._trackable=Object.assign(()=>this._markDirty(),{addDependency:i=>{}}),f.attachDebugInfo(this,"computed",this.id),f.enabled){const i=this;i.subscriberCount=()=>this._functionSubscribersStore.size+this._objectSubscribersStore.size,i.isDirty=()=>this._isDirty(),i.dependencies=this._dependencies,i.stateFlags=this._getFlagsAsString()}if(t.lazy===!1)try{this._recompute()}catch{}}get _functionSubscribers(){return this._functionSubscribersStore}get _objectSubscribers(){return this._objectSubscribersStore}get value(){return this._registerTracking(),this._computeValue()}peek(){return this._value}get state(){return this._registerTracking(),this._getAsyncState()}get hasError(){if(this._registerTracking(),this._isRejected())return!0;for(let e=0;e<this._dependencies.length;e++){const t=this._dependencies[e];if(t&&"hasError"in t&&t.hasError)return!0}return!1}get isValid(){return!this.hasError}get errors(){if(this._registerTracking(),!this.hasError)return ne;const e=ue();if(this._errorCacheEpoch===e&&this._cachedErrors!==null)return this._cachedErrors;const t=new Set;this._error&&t.add(this._error);for(let i=0;i<this._dependencies.length;i++){const n=this._dependencies[i];if(n&&"errors"in n){const r=n.errors;for(let o=0;o<r.length;o++){const d=r[o];d&&t.add(d)}}}return this._cachedErrors=Object.freeze([...t]),this._errorCacheEpoch=e,this._cachedErrors}get lastError(){return this._registerTracking(),this._error}get isPending(){return this._registerTracking(),this._isPending()}get isResolved(){return this._registerTracking(),this._isResolved()}invalidate(){this._markDirty(),this._dependencyVersions!==a&&(b.release(this._dependencyVersions),this._dependencyVersions=a),this._errorCacheEpoch=-1,this._cachedErrors=null}dispose(){if(this._unsubscribes!==p){for(let e=0;e<this._unsubscribes.length;e++){const t=this._unsubscribes[e];t&&t()}N.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==_&&(y.release(this._dependencies),this._dependencies=_),this._dependencyVersions!==a&&(b.release(this._dependencyVersions),this._dependencyVersions=a),this._functionSubscribersStore.clear(),this._objectSubscribersStore.clear(),this.flags=h.DIRTY|h.IDLE,this._error=null,this._value=void 0,this._promiseId=(this._promiseId+1)%this.MAX_PROMISE_ID,this._cachedErrors=null,this._errorCacheEpoch=-1}_isDirty(){return(this.flags&h.DIRTY)!==0}_setDirty(){this.flags|=h.DIRTY}_clearDirty(){this.flags&=-2}_isIdle(){return(this.flags&h.IDLE)!==0}_setIdle(){this.flags|=h.IDLE,this.flags&=-29}_isPending(){return(this.flags&h.PENDING)!==0}_setPending(){this.flags|=h.PENDING,this.flags&=-27}_isResolved(){return(this.flags&h.RESOLVED)!==0}_setResolved(){this.flags|=h.RESOLVED,this.flags&=-87}_isRejected(){return(this.flags&h.REJECTED)!==0}_setRejected(){this.flags|=h.REJECTED|h.HAS_ERROR,this.flags&=-15}_isRecomputing(){return(this.flags&h.RECOMPUTING)!==0}_setRecomputing(e){const t=h.RECOMPUTING;this.flags=this.flags&~t|-Number(e)&t}_getAsyncState(){return V[this.flags&te]}_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._isDirty()||this._isIdle())&&this._recompute(),this._isPending()?this._handlePending():this._isRejected()?this._handleRejected():this._value)}_recompute(){if(this._isRecomputing())return;this._setRecomputing(!0);const e=this._prepareComputationContext();let t=!1;try{const i=C.run(this._trackable,this._fn);this._commitDependencies(e),t=!0,Z(i)?this._handleAsyncComputation(i):this._handleSyncResult(i)}catch(i){if(!t)try{this._commitDependencies(e),t=!0}catch(n){this._handleComputationError(n)}this._handleComputationError(i)}finally{this._cleanupContext(e,t),this._setRecomputing(!1)}}_prepareComputationContext(){const e=this._dependencies,t=this._dependencyVersions,i=y.acquire(),n=b.acquire(),r=J(),o={depCount:0},d=S=>{S._lastSeenEpoch!==r&&(S._lastSeenEpoch=r,o.depCount<i.length?(i[o.depCount]=S,n[o.depCount]=S.version):(i.push(S),n.push(S.version)),o.depCount++)},T=this._trackable.addDependency;return this._trackable.addDependency=d,{prevDeps:e,prevVersions:t,nextDeps:i,nextVersions:n,originalAdd:T,state:o}}_commitDependencies(e){const{nextDeps:t,nextVersions:i,state:n,prevDeps:r}=e;t.length=n.depCount,i.length=n.depCount,this._unsubscribes=ge(t,r,this._unsubscribes,this),this._dependencies=t,this._dependencyVersions=i}_cleanupContext(e,t){this._trackable.addDependency=e.originalAdd,t?(e.prevDeps!==_&&y.release(e.prevDeps),e.prevVersions!==a&&b.release(e.prevVersions)):(y.release(e.nextDeps),b.release(e.nextVersions))}_handleSyncResult(e){const t=!this._isResolved()||!this._equal(this._value,e);this.version=this.version+Number(t)&I,this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),this._cachedErrors=null,this._errorCacheEpoch=-1}_handleAsyncComputation(e){this._setPending(),this._clearDirty(),this._notifyJob(),this._promiseId=this._promiseId>=this.MAX_PROMISE_ID?1:this._promiseId+1;const t=this._promiseId;e.then(i=>{t===this._promiseId&&this._handleAsyncResolution(i)}).catch(i=>{t===this._promiseId&&this._handleAsyncRejection(i)})}_handleAsyncResolution(e){const t=!this._isResolved()||!this._equal(this._value,e);this.version=this.version+Number(t)&I,this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),this._cachedErrors=null,this._errorCacheEpoch=-1,this._notifyJob()}_handleAsyncRejection(e){const t=x(e,m,u.COMPUTED_ASYNC_COMPUTATION_FAILED),i=!this._isRejected();if(this.version=this.version+Number(i)&I,this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(n){console.error(u.CALLBACK_ERROR_IN_ERROR_HANDLER,n)}this._notifyJob()}_handleComputationError(e){const t=x(e,m,u.COMPUTED_COMPUTATION_FAILED);if(this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(i){console.error(u.CALLBACK_ERROR_IN_ERROR_HANDLER,i)}throw t}_handlePending(){if(this._hasDefaultValue)return this._defaultValue;throw new m(u.COMPUTED_ASYNC_PENDING_NO_DEFAULT)}_handleRejected(){if(this._error?.recoverable&&this._hasDefaultValue)return this._defaultValue;throw this._error}execute(){this._markDirty()}_markDirty(){this._isRecomputing()||this._isDirty()||(this._setDirty(),this._notifyJob())}_registerTracking(){ee(this,C.getCurrent(),this._functionSubscribersStore,this._objectSubscribersStore)}}Object.freeze(se.prototype);function Ie(s,e={}){return new se(s,e)}class me extends Y{constructor(e,t={}){super(),this.run=()=>{if(this.isDisposed)throw new D(u.EFFECT_MUST_BE_FUNCTION);this._dependencyVersions!==a&&(b.release(this._dependencyVersions),this._dependencyVersions=a),this.execute()},this.dispose=()=>{if(!this.isDisposed){if(this._setDisposed(),this._safeCleanup(),this._unsubscribes!==p){for(let n=0;n<this._unsubscribes.length;n++){const r=this._unsubscribes[n];r&&r()}N.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==_&&(y.release(this._dependencies),this._dependencies=_),this._dependencyVersions!==a&&(b.release(this._dependencyVersions),this._dependencyVersions=a)}},this.addDependency=n=>{if(this.isExecuting&&this._nextDeps&&this._nextUnsubs&&this._nextVersions){const r=this._currentEpoch;if(n._lastSeenEpoch===r)return;n._lastSeenEpoch=r,this._nextDeps.push(n),this._nextVersions.push(n.version),n._tempUnsub?(this._nextUnsubs.push(n._tempUnsub),n._tempUnsub=void 0):this._subscribeTo(n)}},this.execute=()=>{if(this.isDisposed||this.isExecuting||!this._shouldExecute())return;this._checkInfiniteLoop(),this._setExecuting(!0),this._safeCleanup();const n=this._prepareEffectContext();let r=!1;try{const o=C.run(this,this._fn);this._commitEffect(n),r=!0,this._checkLoopWarnings(),Z(o)?o.then(d=>{!this.isDisposed&&typeof d=="function"&&(this._cleanup=d)}).catch(d=>{this._handleExecutionError(d)}):this._cleanup=typeof o=="function"?o:null}catch(o){r=!0,this._handleExecutionError(o),this._cleanup=null}finally{this._cleanupEffect(n,r),this._setExecuting(!1)}},this._currentEpoch=-1,this._lastFlushEpoch=-1,this._executionsInEpoch=0,this._fn=e,this._sync=t.sync??!1,this._maxExecutions=t.maxExecutionsPerSecond??g.MAX_EXECUTIONS_PER_SECOND,this._maxExecutionsPerFlush=t.maxExecutionsPerFlush??g.MAX_EXECUTIONS_PER_EFFECT,this._trackModifications=t.trackModifications??!1,this._cleanup=null,this._dependencies=_,this._dependencyVersions=a,this._unsubscribes=p,this._nextDeps=null,this._nextVersions=null,this._nextUnsubs=null,this._onError=t.onError??null,this._historyPtr=0;const i=Number.isFinite(this._maxExecutions);this._historyCapacity=i?Math.min(this._maxExecutions+1,g.MAX_EXECUTIONS_PER_SECOND+1):0,this._history=l&&i&&this._historyCapacity>0?new Array(this._historyCapacity).fill(0):null,this._executionCount=0,f.attachDebugInfo(this,"effect",this.id)}_prepareEffectContext(){const e=this._dependencies,t=this._dependencyVersions,i=this._unsubscribes,n=y.acquire(),r=b.acquire(),o=N.acquire(),d=J();if(e!==_&&i!==p)for(let T=0;T<e.length;T++){const S=e[T];S&&(S._tempUnsub=i[T])}return this._nextDeps=n,this._nextVersions=r,this._nextUnsubs=o,this._currentEpoch=d,{prevDeps:e,prevVersions:t,prevUnsubs:i,nextDeps:n,nextVersions:r,nextUnsubs:o}}_commitEffect(e){const t=e.nextDeps.length;e.nextDeps.length=t,e.nextVersions.length=t,this._dependencies=e.nextDeps,this._dependencyVersions=e.nextVersions,this._unsubscribes=e.nextUnsubs}_cleanupEffect(e,t){if(this._nextDeps=null,this._nextVersions=null,this._nextUnsubs=null,t){if(e.prevDeps!==_){for(let i=0;i<e.prevDeps.length;i++){const n=e.prevDeps[i];n?._tempUnsub&&(n._tempUnsub(),n._tempUnsub=void 0)}y.release(e.prevDeps)}e.prevUnsubs!==p&&N.release(e.prevUnsubs),e.prevVersions!==a&&b.release(e.prevVersions)}else{y.release(e.nextDeps),b.release(e.nextVersions);for(let i=0;i<e.nextUnsubs.length;i++)e.nextUnsubs[i]?.();if(N.release(e.nextUnsubs),e.prevDeps!==_)for(let i=0;i<e.prevDeps.length;i++){const n=e.prevDeps[i];n&&(n._tempUnsub=void 0)}}}_subscribeTo(e){try{const t=e.subscribe(()=>{this._trackModifications&&this.isExecuting&&(e._modifiedAtEpoch=this._currentEpoch),this._sync?this.execute():R.schedule(this.execute)});this._nextUnsubs&&this._nextUnsubs.push(t)}catch(t){console.error(x(t,D,u.EFFECT_EXECUTION_FAILED)),this._nextUnsubs&&this._nextUnsubs.push(()=>{})}}get isDisposed(){return(this.flags&F.DISPOSED)!==0}get executionCount(){return this._executionCount}get isExecuting(){return(this.flags&F.EXECUTING)!==0}_setDisposed(){this.flags|=F.DISPOSED}_setExecuting(e){const t=F.EXECUTING;this.flags=this.flags&~t|-Number(e)&t}_safeCleanup(){if(this._cleanup){try{this._cleanup()}catch(e){console.error(x(e,D,u.EFFECT_CLEANUP_FAILED))}this._cleanup=null}}_checkInfiniteLoop(){if(this._lastFlushEpoch!==P&&(this._lastFlushEpoch=P,this._executionsInEpoch=0),this._executionsInEpoch++,this._executionsInEpoch>this._maxExecutionsPerFlush&&this._throwInfiniteLoopError("per-effect"),_e()>g.MAX_EXECUTIONS_PER_FLUSH&&this._throwInfiniteLoopError("global"),this._executionCount++,this._history&&this._maxExecutions>0){const e=Date.now(),t=this._historyPtr,i=this._historyCapacity;this._history[t]=e;const n=(t+1)%i,r=this._history[n]??0;if(this._historyPtr=n,r>0&&e-r<A.ONE_SECOND_MS){const o=new D(`Effect executed ${i} times within 1 second. Infinite loop suspected`);if(this.dispose(),console.error(o),this._onError&&this._onError(o),l)throw o}}}_throwInfiniteLoopError(e){const t=new D(`Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${B}`);throw this.dispose(),console.error(t),t}_shouldExecute(){if(this._dependencies===_||this._dependencyVersions===a)return!0;for(let e=0;e<this._dependencies.length;e++){const t=this._dependencies[e];if(t){if("value"in t)try{W(()=>t.value)}catch{return!0}if(t.version!==this._dependencyVersions[e])return!0}}return!1}_handleExecutionError(e){const t=x(e,D,u.EFFECT_EXECUTION_FAILED);console.error(t),this._onError&&this._onError(t)}_checkLoopWarnings(){if(this._trackModifications&&f.enabled){const e=this._dependencies;for(let t=0;t<e.length;t++){const i=e[t];i&&i._modifiedAtEpoch===this._currentEpoch&&f.warn(!0,`Effect is reading a dependency (${f.getDebugName(i)||"unknown"}) that it just modified. Infinite loop may occur`)}}}}function Ce(s,e={}){if(typeof s!="function")throw new D(u.EFFECT_MUST_BE_FUNCTION);const t=new me(s,e);return t.execute(),t}c.AsyncState=O,c.AtomError=E,c.ComputedError=m,c.DEBUG_CONFIG=w,c.DEBUG_RUNTIME=f,c.EffectError=D,c.POOL_CONFIG=ie,c.SCHEDULER_CONFIG=g,c.SchedulerError=U,c.atom=ye,c.batch=le,c.computed=Ie,c.effect=Ce,c.isAtom=K,c.isComputed=fe,c.isEffect=de,c.scheduler=R,c.untracked=W,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})}));
|
|
1
|
+
(function(c,A){typeof exports=="object"&&typeof module<"u"?A(exports):typeof define=="function"&&define.amd?define(["exports"],A):(c=typeof globalThis<"u"?globalThis:c||self,A(c.AtomEffect={}))})(this,(function(c){"use strict";const A={ONE_SECOND_MS:1e3},O={IDLE:"idle",PENDING:"pending",RESOLVED:"resolved",REJECTED:"rejected"},F={DISPOSED:1,EXECUTING:2},h={DIRTY:1,IDLE:2,PENDING:4,RESOLVED:8,REJECTED:16,RECOMPUTING:32,HAS_ERROR:64},ie={MAX_SIZE:1e3,WARMUP_SIZE:100},g={MAX_EXECUTIONS_PER_SECOND:1e3,CLEANUP_THRESHOLD:1e3,MAX_EXECUTIONS_PER_EFFECT:100,MAX_EXECUTIONS_PER_FLUSH:1e4,MAX_FLUSH_ITERATIONS:1e3,MIN_FLUSH_ITERATIONS:10},w={MAX_DEPENDENCIES:1e3,WARN_INFINITE_LOOP:!0},I=1073741823,l=typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production",ne=Object.freeze([]);class E extends Error{constructor(e,t=null,i=!0){super(e),this.name="AtomError",this.cause=t,this.recoverable=i,this.timestamp=new Date}}class m extends E{constructor(e,t=null){super(e,t,!0),this.name="ComputedError"}}class D extends E{constructor(e,t=null){super(e,t,!1),this.name="EffectError"}}class U extends E{constructor(e,t=null){super(e,t,!1),this.name="SchedulerError"}}const u={COMPUTED_MUST_BE_FUNCTION:"Computed function 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",ATOM_SUBSCRIBER_MUST_BE_FUNCTION:"Subscription listener must be a function or Subscriber object",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",CALLBACK_ERROR_IN_ERROR_HANDLER:"Error occurred during onError callback execution"},k=Symbol("debugName"),re=Symbol("id"),B=Symbol("type"),z=Symbol("noDefaultValue");function oe(s){return"dependencies"in s&&Array.isArray(s.dependencies)}let G=0;function X(s,e,t){if(s._visitedEpoch!==t){if(s._visitedEpoch=t,s===e)throw new m("Indirect circular dependency detected");if(oe(s)){const i=s.dependencies;for(let n=0;n<i.length;n++){const r=i[n];r&&X(r,e,t)}}}}const f={enabled:typeof process<"u"&&process.env?.NODE_ENV==="development",maxDependencies:w.MAX_DEPENDENCIES,warnInfiniteLoop:w.WARN_INFINITE_LOOP,warn(s,e){this.enabled&&s&&console.warn(`[Atom Effect] ${e}`)},checkCircular(s,e){if(s===e)throw new m("Direct circular dependency detected");this.enabled&&(G++,X(s,e,G))},attachDebugInfo(s,e,t){if(!this.enabled)return;const i=s;i[k]=`${e}_${t}`,i[re]=t,i[B]=e},getDebugName(s){if(s!=null&&k in s)return s[k]},getDebugType(s){if(s!=null&&B in s)return s[B]}};let ce=1;const he=()=>ce++;class Y{constructor(){this.id=he()&I,this.flags=0}}class Q extends Y{constructor(){super(),this.version=0,this._lastSeenEpoch=-1}subscribe(e){if(typeof e=="object"&&e!==null&&"execute"in e)return this._objectSubscribers.add(e);if(typeof e!="function")throw new E(u.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);return this._functionSubscribers.add(e)}subscriberCount(){return this._functionSubscribers.size+this._objectSubscribers.size}_notifySubscribers(e,t){this._functionSubscribers.forEachSafe(i=>i(e,t),i=>console.error(new E(u.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,i))),this._objectSubscribers.forEachSafe(i=>i.execute(),i=>console.error(new E(u.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,i)))}}let v=0;function H(){return v=v+1&I||1,v}function ue(){return v}let P=0,j=0,M=!1;function $(){return M?(l&&console.warn("Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"),!1):(M=!0,P=P+1&I,j=0,!0)}function J(){M=!1}function ae(){return M?++j:0}class _e{constructor(){this.queueA=[],this.queueB=[],this.queue=this.queueA,this.queueSize=0,this._epoch=0,this.isProcessing=!1,this.isBatching=!1,this.batchDepth=0,this.batchQueue=[],this.batchQueueSize=0,this.isFlushingSync=!1,this.maxFlushIterations=g.MAX_FLUSH_ITERATIONS}get phase(){return this.isProcessing||this.isFlushingSync?2:this.isBatching?1:0}schedule(e){if(typeof e!="function")throw new U("Scheduler callback must be a function");e._nextEpoch!==this._epoch&&(e._nextEpoch=this._epoch,this.isBatching||this.isFlushingSync?this.batchQueue[this.batchQueueSize++]=e:(this.queue[this.queueSize++]=e,this.isProcessing||this.flush()))}flush(){this.isProcessing||this.queueSize===0||(this.isProcessing=!0,queueMicrotask(()=>{try{if(this.queueSize===0)return;const e=$();this._drainQueue(),e&&J()}finally{this.isProcessing=!1,this.queueSize>0&&!this.isBatching&&this.flush()}}))}flushSync(){this.isFlushingSync=!0;const e=$();try{this._mergeBatchQueue(),this._drainQueue()}finally{this.isFlushingSync=!1,e&&J()}}_mergeBatchQueue(){if(this._epoch++,this.batchQueueSize>0){for(let e=0;e<this.batchQueueSize;e++){const t=this.batchQueue[e];t&&t._nextEpoch!==this._epoch&&(t._nextEpoch=this._epoch,this.queue[this.queueSize++]=t)}this.batchQueueSize=0}}_drainQueue(){let e=0;for(;this.queueSize>0;){if(++e>this.maxFlushIterations){this._handleFlushOverflow();break}this._processCurrentQueue(),this._mergeBatchQueue()}}_processCurrentQueue(){const e=this.queue,t=this.queueSize;this.queue=this.queue===this.queueA?this.queueB:this.queueA,this.queueSize=0,this._epoch++,this._processJobs(e,t)}_handleFlushOverflow(){console.error(new U(`Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop.`)),this.queueSize=0,this.queue.length=0,this.batchQueueSize=0}_processJobs(e,t){for(let i=0;i<t;i++)try{e[i]?.()}catch(n){console.error(new U("Error occurred during scheduler execution",n))}e.length=0}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<g.MIN_FLUSH_ITERATIONS)throw new U(`Max flush iterations must be at least ${g.MIN_FLUSH_ITERATIONS}`);this.maxFlushIterations=e}}const R=new _e;function le(s){if(typeof s!="function")throw new E("Batch callback must be a function");R.startBatch();try{return s()}finally{R.endBatch()}}const C={current:null,run(s,e){const t=this.current;this.current=s;try{return e()}finally{this.current=t}},getCurrent(){return this.current}};function W(s){if(typeof s!="function")throw new E("Untracked callback must be a function");const e=C.current;C.current=null;try{return s()}finally{C.current=e}}class L{constructor(){this.subscribers=null}add(e){if(this.subscribers||(this.subscribers=[]),this.subscribers.indexOf(e)!==-1)return()=>{};this.subscribers.push(e);let t=!1;return()=>{t||(t=!0,this.remove(e))}}remove(e){if(!this.subscribers)return!1;const t=this.subscribers.indexOf(e);if(t===-1)return!1;const i=this.subscribers.length-1;return t!==i&&(this.subscribers[t]=this.subscribers[i]),this.subscribers.pop(),!0}has(e){return this.subscribers?this.subscribers.indexOf(e)!==-1:!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 i=0;i<this.subscribers.length;i++)try{e(this.subscribers[i],i)}catch(n){t?t(n):console.error("[SubscriberManager] Error in subscriber callback:",n)}}get size(){return this.subscribers?.length??0}get hasSubscribers(){return this.subscribers!==null&&this.subscribers.length>0}clear(){this.subscribers=null}toArray(){return this.subscribers?[...this.subscribers]:[]}}class q{constructor(){this.pool=[],this.maxPoolSize=50,this.maxReusableCapacity=256,this.stats=l?{acquired:0,released:0,rejected:{frozen:0,tooLarge:0,poolFull:0}}:null}acquire(){return l&&this.stats&&this.stats.acquired++,this.pool.pop()??[]}release(e,t){if(!(t&&e===t)){if(Object.isFrozen(e)){l&&this.stats&&this.stats.rejected.frozen++;return}if(e.length>this.maxReusableCapacity){l&&this.stats&&this.stats.rejected.tooLarge++;return}if(this.pool.length>=this.maxPoolSize){l&&this.stats&&this.stats.rejected.poolFull++;return}e.length=0,this.pool.push(e),l&&this.stats&&this.stats.released++}}getStats(){if(!l||!this.stats)return null;const{acquired:e,released:t,rejected:i}=this.stats,n=i.frozen+i.tooLarge+i.poolFull;return{acquired:e,released:t,rejected:i,leaked:e-t-n,poolSize:this.pool.length}}reset(){this.pool.length=0,l&&this.stats&&(this.stats.acquired=0,this.stats.released=0,this.stats.rejected={frozen:0,tooLarge:0,poolFull:0})}}const a=Object.freeze([]),p=Object.freeze([]),_=Object.freeze([]),y=new q,N=new q,b=new q;function K(s){return s!==null&&typeof s=="object"&&"value"in s&&"subscribe"in s&&typeof s.subscribe=="function"}function fe(s){if(f.enabled&&(s==null||typeof s=="object")){const e=f.getDebugType(s);if(e)return e==="computed"}return K(s)&&"invalidate"in s&&typeof s.invalidate=="function"}function de(s){return s!==null&&typeof s=="object"&&"dispose"in s&&"run"in s&&typeof s.dispose=="function"&&typeof s.run=="function"}function Z(s){return s!=null&&typeof s.then=="function"}function Ee(s){return typeof s=="object"&&s!==null}function pe(s){return(typeof s=="object"||typeof s=="function")&&s!==null&&typeof s.addDependency=="function"}function be(s){return typeof s=="function"&&typeof s.addDependency!="function"}function Se(s){return Ee(s)&&typeof s.execute=="function"}function ee(s,e,t,i){if(e){if(pe(e)){e.addDependency(s);return}if(be(e)){t.add(e);return}Se(e)&&i.add(e)}}function ge(s,e,t,i){if(e!==a&&t!==p)for(let r=0;r<e.length;r++){const o=e[r];o&&(o._tempUnsub=t[r])}const n=N.acquire();n.length=s.length;for(let r=0;r<s.length;r++){const o=s[r];o&&(o._tempUnsub?(n[r]=o._tempUnsub,o._tempUnsub=void 0):(f.checkCircular(o,i),n[r]=o.subscribe(i)))}if(e!==a)for(let r=0;r<e.length;r++){const o=e[r];o?._tempUnsub&&(o._tempUnsub(),o._tempUnsub=void 0)}return t!==p&&N.release(t),n}class De extends Q{constructor(e,t){super(),this._isNotificationScheduled=!1,this._value=e,this._functionSubscribersStore=new L,this._objectSubscribersStore=new L,this._sync=t,this._notifyTask=this._flushNotifications.bind(this),f.attachDebugInfo(this,"atom",this.id)}get _functionSubscribers(){return this._functionSubscribersStore}get _objectSubscribers(){return this._objectSubscribersStore}get value(){const e=C.getCurrent();return e&&this._track(e),this._value}set value(e){if(Object.is(this._value,e))return;const t=this._value;this.version=this.version+1&I,this._value=e,!(!this._functionSubscribersStore.hasSubscribers&&!this._objectSubscribersStore.hasSubscribers)&&this._scheduleNotification(t)}_track(e){ee(this,e,this._functionSubscribersStore,this._objectSubscribersStore)}_scheduleNotification(e){this._isNotificationScheduled||(this._pendingOldValue=e,this._isNotificationScheduled=!0),this._sync&&!R.isBatching?this._flushNotifications():R.schedule(this._notifyTask)}_flushNotifications(){if(!this._isNotificationScheduled)return;const e=this._pendingOldValue,t=this._value;this._pendingOldValue=void 0,this._isNotificationScheduled=!1,this._notifySubscribers(t,e)}peek(){return this._value}dispose(){this._functionSubscribersStore.clear(),this._objectSubscribersStore.clear(),this._value=void 0}}function ye(s,e={}){return new De(s,e.sync??!1)}function x(s,e,t){if(s instanceof TypeError)return new e(`Type error (${t}): ${s.message}`,s);if(s instanceof ReferenceError)return new e(`Reference error (${t}): ${s.message}`,s);if(s instanceof E)return s;const i=s instanceof Error?s.message:String(s),n=s instanceof Error?s:null;return new e(`Unexpected error (${t}): ${i}`,n)}const te=h.RESOLVED|h.PENDING|h.REJECTED,V=Array(te+1).fill(O.IDLE);V[h.RESOLVED]=O.RESOLVED,V[h.PENDING]=O.PENDING,V[h.REJECTED]=O.REJECTED;class se extends Q{constructor(e,t={}){if(typeof e!="function")throw new m(u.COMPUTED_MUST_BE_FUNCTION);if(super(),this._cachedErrors=null,this._errorCacheEpoch=-1,this._value=void 0,this.flags=h.DIRTY|h.IDLE,this._error=null,this._promiseId=0,this._equal=t.equal??Object.is,this._fn=e,this._defaultValue="defaultValue"in t?t.defaultValue:z,this._hasDefaultValue=this._defaultValue!==z,this._onError=t.onError??null,this.MAX_PROMISE_ID=Number.MAX_SAFE_INTEGER-1,this._functionSubscribersStore=new L,this._objectSubscribersStore=new L,this._dependencies=a,this._dependencyVersions=_,this._unsubscribes=p,this._notifyJob=()=>{this._functionSubscribersStore.forEachSafe(i=>i(),i=>console.error(i)),this._objectSubscribersStore.forEachSafe(i=>i.execute(),i=>console.error(i))},this._trackable=Object.assign(()=>this._markDirty(),{addDependency:i=>{}}),f.attachDebugInfo(this,"computed",this.id),f.enabled){const i=this;i.subscriberCount=()=>this._functionSubscribersStore.size+this._objectSubscribersStore.size,i.isDirty=()=>this._isDirty(),i.dependencies=this._dependencies,i.stateFlags=this._getFlagsAsString()}if(t.lazy===!1)try{this._recompute()}catch{}}get _functionSubscribers(){return this._functionSubscribersStore}get _objectSubscribers(){return this._objectSubscribersStore}get value(){return this._registerTracking(),this._computeValue()}peek(){return this._value}get state(){return this._registerTracking(),this._getAsyncState()}get hasError(){if(this._registerTracking(),this._isRejected())return!0;for(let e=0;e<this._dependencies.length;e++){const t=this._dependencies[e];if(t&&"hasError"in t&&t.hasError)return!0}return!1}get isValid(){return!this.hasError}get errors(){if(this._registerTracking(),!this.hasError)return ne;const e=ue();if(this._errorCacheEpoch===e&&this._cachedErrors!==null)return this._cachedErrors;const t=new Set;this._error&&t.add(this._error);for(let i=0;i<this._dependencies.length;i++){const n=this._dependencies[i];if(n&&"errors"in n){const r=n.errors;for(let o=0;o<r.length;o++){const d=r[o];d&&t.add(d)}}}return this._cachedErrors=Object.freeze([...t]),this._errorCacheEpoch=e,this._cachedErrors}get lastError(){return this._registerTracking(),this._error}get isPending(){return this._registerTracking(),this._isPending()}get isResolved(){return this._registerTracking(),this._isResolved()}invalidate(){this._markDirty(),this._dependencyVersions!==_&&(b.release(this._dependencyVersions),this._dependencyVersions=_),this._errorCacheEpoch=-1,this._cachedErrors=null}dispose(){if(this._unsubscribes!==p){for(let e=0;e<this._unsubscribes.length;e++){const t=this._unsubscribes[e];t&&t()}N.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==a&&(y.release(this._dependencies),this._dependencies=a),this._dependencyVersions!==_&&(b.release(this._dependencyVersions),this._dependencyVersions=_),this._functionSubscribersStore.clear(),this._objectSubscribersStore.clear(),this.flags=h.DIRTY|h.IDLE,this._error=null,this._value=void 0,this._promiseId=(this._promiseId+1)%this.MAX_PROMISE_ID,this._cachedErrors=null,this._errorCacheEpoch=-1}_isDirty(){return(this.flags&h.DIRTY)!==0}_setDirty(){this.flags|=h.DIRTY}_clearDirty(){this.flags&=-2}_isIdle(){return(this.flags&h.IDLE)!==0}_setIdle(){this.flags|=h.IDLE,this.flags&=-29}_isPending(){return(this.flags&h.PENDING)!==0}_setPending(){this.flags|=h.PENDING,this.flags&=-27}_isResolved(){return(this.flags&h.RESOLVED)!==0}_setResolved(){this.flags|=h.RESOLVED,this.flags&=-87}_isRejected(){return(this.flags&h.REJECTED)!==0}_setRejected(){this.flags|=h.REJECTED|h.HAS_ERROR,this.flags&=-15}_isRecomputing(){return(this.flags&h.RECOMPUTING)!==0}_setRecomputing(e){const t=h.RECOMPUTING;this.flags=this.flags&~t|-Number(e)&t}_getAsyncState(){return V[this.flags&te]}_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._isDirty()||this._isIdle())&&this._recompute(),this._isPending()?this._handlePending():this._isRejected()?this._handleRejected():this._value)}_recompute(){if(this._isRecomputing())return;this._setRecomputing(!0);const e=this._prepareComputationContext();let t=!1;try{const i=C.run(this._trackable,this._fn);this._commitDependencies(e),t=!0,Z(i)?this._handleAsyncComputation(i):this._handleSyncResult(i)}catch(i){if(!t)try{this._commitDependencies(e),t=!0}catch(n){this._handleComputationError(n)}this._handleComputationError(i)}finally{this._cleanupContext(e,t),this._setRecomputing(!1)}}_prepareComputationContext(){const e=this._dependencies,t=this._dependencyVersions,i=y.acquire(),n=b.acquire(),r=H(),o={depCount:0},d=S=>{S._lastSeenEpoch!==r&&(S._lastSeenEpoch=r,o.depCount<i.length?(i[o.depCount]=S,n[o.depCount]=S.version):(i.push(S),n.push(S.version)),o.depCount++)},T=this._trackable.addDependency;return this._trackable.addDependency=d,{prevDeps:e,prevVersions:t,nextDeps:i,nextVersions:n,originalAdd:T,state:o}}_commitDependencies(e){const{nextDeps:t,nextVersions:i,state:n,prevDeps:r}=e;t.length=n.depCount,i.length=n.depCount,this._unsubscribes=ge(t,r,this._unsubscribes,this),this._dependencies=t,this._dependencyVersions=i}_cleanupContext(e,t){this._trackable.addDependency=e.originalAdd,t?(e.prevDeps!==a&&y.release(e.prevDeps),e.prevVersions!==_&&b.release(e.prevVersions)):(y.release(e.nextDeps),b.release(e.nextVersions))}_handleSyncResult(e){const t=!this._isResolved()||!this._equal(this._value,e);this.version=this.version+Number(t)&I,this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),this._cachedErrors=null,this._errorCacheEpoch=-1}_handleAsyncComputation(e){this._setPending(),this._clearDirty(),this._notifyJob(),this._promiseId=this._promiseId>=this.MAX_PROMISE_ID?1:this._promiseId+1;const t=this._promiseId;e.then(i=>{t===this._promiseId&&this._handleAsyncResolution(i)}).catch(i=>{t===this._promiseId&&this._handleAsyncRejection(i)})}_handleAsyncResolution(e){const t=!this._isResolved()||!this._equal(this._value,e);this.version=this.version+Number(t)&I,this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),this._cachedErrors=null,this._errorCacheEpoch=-1,this._notifyJob()}_handleAsyncRejection(e){const t=x(e,m,u.COMPUTED_ASYNC_COMPUTATION_FAILED),i=!this._isRejected();if(this.version=this.version+Number(i)&I,this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(n){console.error(u.CALLBACK_ERROR_IN_ERROR_HANDLER,n)}this._notifyJob()}_handleComputationError(e){const t=x(e,m,u.COMPUTED_COMPUTATION_FAILED);if(this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(i){console.error(u.CALLBACK_ERROR_IN_ERROR_HANDLER,i)}throw t}_handlePending(){if(this._hasDefaultValue)return this._defaultValue;throw new m(u.COMPUTED_ASYNC_PENDING_NO_DEFAULT)}_handleRejected(){if(this._error?.recoverable&&this._hasDefaultValue)return this._defaultValue;throw this._error}execute(){this._markDirty()}_markDirty(){this._isRecomputing()||this._isDirty()||(this._setDirty(),this._notifyJob())}_registerTracking(){ee(this,C.getCurrent(),this._functionSubscribersStore,this._objectSubscribersStore)}}Object.freeze(se.prototype);function Ie(s,e={}){return new se(s,e)}class me extends Y{constructor(e,t={}){super(),this.run=()=>{if(this.isDisposed)throw new D(u.EFFECT_MUST_BE_FUNCTION);this._dependencyVersions!==_&&(b.release(this._dependencyVersions),this._dependencyVersions=_),this.execute()},this.dispose=()=>{if(!this.isDisposed){if(this._setDisposed(),this._safeCleanup(),this._unsubscribes!==p){for(let n=0;n<this._unsubscribes.length;n++){const r=this._unsubscribes[n];r&&r()}N.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==a&&(y.release(this._dependencies),this._dependencies=a),this._dependencyVersions!==_&&(b.release(this._dependencyVersions),this._dependencyVersions=_)}},this.addDependency=n=>{if(this.isExecuting&&this._nextDeps&&this._nextUnsubs&&this._nextVersions){const r=this._currentEpoch;if(n._lastSeenEpoch===r)return;n._lastSeenEpoch=r,this._nextDeps.push(n),this._nextVersions.push(n.version),n._tempUnsub?(this._nextUnsubs.push(n._tempUnsub),n._tempUnsub=void 0):this._subscribeTo(n)}},this.execute=()=>{if(this.isDisposed||this.isExecuting||!this._shouldExecute())return;this._checkInfiniteLoop(),this._setExecuting(!0),this._safeCleanup();const n=this._prepareEffectContext();let r=!1;try{const o=C.run(this,this._fn);this._commitEffect(n),r=!0,this._checkLoopWarnings(),Z(o)?o.then(d=>{!this.isDisposed&&typeof d=="function"&&(this._cleanup=d)}).catch(d=>{this._handleExecutionError(d)}):this._cleanup=typeof o=="function"?o:null}catch(o){r=!0,this._handleExecutionError(o),this._cleanup=null}finally{this._cleanupEffect(n,r),this._setExecuting(!1)}},this._currentEpoch=-1,this._lastFlushEpoch=-1,this._executionsInEpoch=0,this._fn=e,this._sync=t.sync??!1,this._maxExecutions=t.maxExecutionsPerSecond??g.MAX_EXECUTIONS_PER_SECOND,this._maxExecutionsPerFlush=t.maxExecutionsPerFlush??g.MAX_EXECUTIONS_PER_EFFECT,this._trackModifications=t.trackModifications??!1,this._cleanup=null,this._dependencies=a,this._dependencyVersions=_,this._unsubscribes=p,this._nextDeps=null,this._nextVersions=null,this._nextUnsubs=null,this._onError=t.onError??null,this._historyPtr=0;const i=Number.isFinite(this._maxExecutions);this._historyCapacity=i?Math.min(this._maxExecutions+1,g.MAX_EXECUTIONS_PER_SECOND+1):0,this._history=l&&i&&this._historyCapacity>0?new Array(this._historyCapacity).fill(0):null,this._executionCount=0,f.attachDebugInfo(this,"effect",this.id)}_prepareEffectContext(){const e=this._dependencies,t=this._dependencyVersions,i=this._unsubscribes,n=y.acquire(),r=b.acquire(),o=N.acquire(),d=H();if(e!==a&&i!==p)for(let T=0;T<e.length;T++){const S=e[T];S&&(S._tempUnsub=i[T])}return this._nextDeps=n,this._nextVersions=r,this._nextUnsubs=o,this._currentEpoch=d,{prevDeps:e,prevVersions:t,prevUnsubs:i,nextDeps:n,nextVersions:r,nextUnsubs:o}}_commitEffect(e){const t=e.nextDeps.length;e.nextDeps.length=t,e.nextVersions.length=t,this._dependencies=e.nextDeps,this._dependencyVersions=e.nextVersions,this._unsubscribes=e.nextUnsubs}_cleanupEffect(e,t){if(this._nextDeps=null,this._nextVersions=null,this._nextUnsubs=null,t){if(e.prevDeps!==a){for(let i=0;i<e.prevDeps.length;i++){const n=e.prevDeps[i];n?._tempUnsub&&(n._tempUnsub(),n._tempUnsub=void 0)}y.release(e.prevDeps)}e.prevUnsubs!==p&&N.release(e.prevUnsubs),e.prevVersions!==_&&b.release(e.prevVersions)}else{y.release(e.nextDeps),b.release(e.nextVersions);for(let i=0;i<e.nextUnsubs.length;i++)e.nextUnsubs[i]?.();if(N.release(e.nextUnsubs),e.prevDeps!==a)for(let i=0;i<e.prevDeps.length;i++){const n=e.prevDeps[i];n&&(n._tempUnsub=void 0)}}}_subscribeTo(e){try{const t=e.subscribe(()=>{this._trackModifications&&this.isExecuting&&(e._modifiedAtEpoch=this._currentEpoch),this._sync?this.execute():R.schedule(this.execute)});this._nextUnsubs&&this._nextUnsubs.push(t)}catch(t){console.error(x(t,D,u.EFFECT_EXECUTION_FAILED)),this._nextUnsubs&&this._nextUnsubs.push(()=>{})}}get isDisposed(){return(this.flags&F.DISPOSED)!==0}get executionCount(){return this._executionCount}get isExecuting(){return(this.flags&F.EXECUTING)!==0}_setDisposed(){this.flags|=F.DISPOSED}_setExecuting(e){const t=F.EXECUTING;this.flags=this.flags&~t|-Number(e)&t}_safeCleanup(){if(this._cleanup){try{this._cleanup()}catch(e){console.error(x(e,D,u.EFFECT_CLEANUP_FAILED))}this._cleanup=null}}_checkInfiniteLoop(){if(this._lastFlushEpoch!==P&&(this._lastFlushEpoch=P,this._executionsInEpoch=0),this._executionsInEpoch++,this._executionsInEpoch>this._maxExecutionsPerFlush&&this._throwInfiniteLoopError("per-effect"),ae()>g.MAX_EXECUTIONS_PER_FLUSH&&this._throwInfiniteLoopError("global"),this._executionCount++,this._history&&this._maxExecutions>0){const e=Date.now(),t=this._historyPtr,i=this._historyCapacity;this._history[t]=e;const n=(t+1)%i,r=this._history[n]??0;if(this._historyPtr=n,r>0&&e-r<A.ONE_SECOND_MS){const o=new D(`Effect executed ${i} times within 1 second. Infinite loop suspected`);if(this.dispose(),console.error(o),this._onError&&this._onError(o),l)throw o}}}_throwInfiniteLoopError(e){const t=new D(`Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${j}`);throw this.dispose(),console.error(t),t}_shouldExecute(){if(this._dependencies===a||this._dependencyVersions===_)return!0;for(let e=0;e<this._dependencies.length;e++){const t=this._dependencies[e];if(t){if("value"in t)try{W(()=>t.value)}catch{return!0}if(t.version!==this._dependencyVersions[e])return!0}}return!1}_handleExecutionError(e){const t=x(e,D,u.EFFECT_EXECUTION_FAILED);console.error(t),this._onError&&this._onError(t)}_checkLoopWarnings(){if(this._trackModifications&&f.enabled){const e=this._dependencies;for(let t=0;t<e.length;t++){const i=e[t];i&&i._modifiedAtEpoch===this._currentEpoch&&f.warn(!0,`Effect is reading a dependency (${f.getDebugName(i)||"unknown"}) that it just modified. Infinite loop may occur`)}}}}function Ce(s,e={}){if(typeof s!="function")throw new D(u.EFFECT_MUST_BE_FUNCTION);const t=new me(s,e);return t.execute(),t}c.AsyncState=O,c.AtomError=E,c.ComputedError=m,c.DEBUG_CONFIG=w,c.DEBUG_RUNTIME=f,c.EffectError=D,c.POOL_CONFIG=ie,c.SCHEDULER_CONFIG=g,c.SchedulerError=U,c.atom=ye,c.batch=le,c.computed=Ie,c.effect=Ce,c.isAtom=K,c.isComputed=fe,c.isEffect=de,c.scheduler=R,c.untracked=W,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})}));
|
|
2
2
|
//# sourceMappingURL=atom-effect.min.js.map
|