@but212/atom-effect 0.12.0 → 0.13.0
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 +8 -8
- 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.d.ts +36 -0
- package/dist/index.mjs +169 -169
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -143,14 +143,14 @@ pnpm build # Build production bundle
|
|
|
143
143
|
|
|
144
144
|
| Operation | Performance |
|
|
145
145
|
| --- | --- |
|
|
146
|
-
| Atom creation | ~
|
|
147
|
-
| Atom read | ~
|
|
148
|
-
| Atom write | ~
|
|
149
|
-
| Computed creation | ~
|
|
150
|
-
| Computed recomputation | ~
|
|
151
|
-
| Effect execution | ~2.
|
|
152
|
-
| Batched updates | ~3.
|
|
153
|
-
| Deep chain (100 levels) | ~8.
|
|
146
|
+
| Atom creation (x1000) | ~13.9K ops/sec |
|
|
147
|
+
| Atom read (x1000) | ~38.1K ops/sec |
|
|
148
|
+
| Atom write (x1000) | ~343K ops/sec |
|
|
149
|
+
| Computed creation | ~2.17M ops/sec |
|
|
150
|
+
| Computed recomputation | ~564K ops/sec |
|
|
151
|
+
| Effect execution | ~2.78M ops/sec |
|
|
152
|
+
| Batched updates (x2) | ~3.97M ops/sec |
|
|
153
|
+
| Deep chain (100 levels) | ~8.16K ops/sec |
|
|
154
154
|
|
|
155
155
|
## Contributing
|
|
156
156
|
|
package/dist/atom-effect.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(h,N){typeof exports=="object"&&typeof module<"u"?N(exports):typeof define=="function"&&define.amd?define(["exports"],N):(h=typeof globalThis<"u"?globalThis:h||self,N(h.AtomEffect={}))})(this,(function(h){"use strict";const N={ONE_SECOND_MS:1e3},O={IDLE:"idle",PENDING:"pending",RESOLVED:"resolved",REJECTED:"rejected"},P={DISPOSED:1,EXECUTING:2},u={DIRTY:1,IDLE:2,PENDING:4,RESOLVED:8,REJECTED:16,RECOMPUTING:32,HAS_ERROR:64},U={SYNC:1,NOTIFICATION_SCHEDULED:2},ne={MAX_SIZE:1e3,WARMUP_SIZE:100},b={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},y=1073741823,j=1<<19,f=typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production",re=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 D extends E{constructor(e,t=null){super(e,t,!0),this.name="ComputedError"}}class I extends E{constructor(e,t=null){super(e,t,!1),this.name="EffectError"}}class F extends E{constructor(e,t=null){super(e,t,!1),this.name="SchedulerError"}}const c={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"},z=Symbol("debugName"),oe=Symbol("id"),B=Symbol("type"),q=Symbol("noDefaultValue");function he(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 D("Indirect circular dependency detected");if(he(s)){const i=s.dependencies;for(let n=0;n<i.length;n++){const r=i[n];r&&X(r,e,t)}}}}const d={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 D("Direct circular dependency detected");this.enabled&&(G++,X(s,e,G))},attachDebugInfo(s,e,t){if(!this.enabled)return;const i=s;i[z]=`${e}_${t}`,i[oe]=t,i[B]=e},getDebugName(s){if(s!=null&&z in s)return s[z]},getDebugType(s){if(s!=null&&B in s)return s[B]}};let ue=1;const ce=()=>ue++;class Y{constructor(){this.flags=0,this.version=0,this._lastSeenEpoch=-1,this.id=ce()&y}rotatePhase(){return this.version=this.version+1&y,this.version}getShift(e){return this.version-e&y}}class H extends Y{subscribe(e){if(typeof e=="object"&&e!==null&&"execute"in e)return this._addSubscriber(this._getObjSubs(),e);if(typeof e!="function")throw new E(c.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);return this._addSubscriber(this._getFnSubs(),e)}subscriberCount(){return(this._fnSubs?.length??0)+(this._objSubs?.length??0)}_addSubscriber(e,t){if(e.indexOf(t)!==-1)return()=>{};e.push(t);let i=!1;return()=>{if(i)return;i=!0;const n=e.indexOf(t);if(n!==-1){const r=e.length-1;n!==r&&(e[n]=e[r]),e.pop()}}}_notifySubscribers(e,t){const i=this._fnSubs;if(i)for(let r=i.length-1;r>=0;r--)try{const o=i[r];o&&o(e,t)}catch(o){console.error(new E(c.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,o))}const n=this._objSubs;if(n)for(let r=n.length-1;r>=0;r--)try{const o=n[r];o&&o.execute()}catch(o){console.error(new E(c.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,o))}}}let v=0;function $(){return v=v+1&y||1,v}function _e(){return v}let L=0,k=0,M=!1;function J(){return M?(f&&console.warn("Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"),!1):(M=!0,L=L+1&y,k=0,!0)}function W(){M=!1}function ae(){return M?++k:0}class le{constructor(){this.queueA=[],this.queueB=[],this.queue=this.queueA,this.queueSize=0,this.urgentQueueA=[],this.urgentQueueB=[],this.urgentQueue=this.urgentQueueA,this.urgentQueueSize=0,this._epoch=0,this.isProcessing=!1,this.isBatching=!1,this.batchDepth=0,this.batchQueue=[],this.batchQueueSize=0,this.isFlushingSync=!1,this.maxFlushIterations=b.MAX_FLUSH_ITERATIONS}get phase(){return this.isProcessing||this.isFlushingSync?2:this.isBatching?1:0}schedule(e,t){if(typeof e!="function")throw new F("Scheduler callback must be a function");if(e._nextEpoch!==this._epoch)if(e._nextEpoch=this._epoch,this.isBatching||this.isFlushingSync)this.batchQueue[this.batchQueueSize++]=e;else{const i=this._calculateUrgency(e,t);this.urgentQueue[this.urgentQueueSize]=e,this.queue[this.queueSize]=e,this.urgentQueueSize+=i,this.queueSize+=i^1,this.isProcessing||this.flush()}}_calculateUrgency(e,t){if(!t||e._cachedVersion===void 0)return 0;const i=t.getShift(e._cachedVersion);return j-1-i>>>31&1}flush(){this.isProcessing||this.queueSize===0&&this.urgentQueueSize===0||(this.isProcessing=!0,queueMicrotask(()=>{try{if(this.queueSize===0&&this.urgentQueueSize===0)return;const e=J();this._drainQueue(),e&&W()}finally{this.isProcessing=!1,(this.queueSize>0||this.urgentQueueSize>0)&&!this.isBatching&&this.flush()}}))}flushSync(){this.isFlushingSync=!0;const e=J();try{this._mergeBatchQueue(),this._drainQueue()}finally{this.isFlushingSync=!1,e&&W()}}_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.urgentQueueSize>0||this.queueSize>0;){if(++e>this.maxFlushIterations){this._handleFlushOverflow();return}this.urgentQueueSize>0&&this._processUrgentQueue(),this.queueSize>0&&this._processCurrentQueue(),this._mergeBatchQueue()}}_processUrgentQueue(){const e=this.urgentQueue,t=this.urgentQueueSize;this.urgentQueue=this.urgentQueue===this.urgentQueueA?this.urgentQueueB:this.urgentQueueA,this.urgentQueueSize=0,this._epoch++,this._processJobs(e,t)}_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 F(`Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop.`)),this.queueSize=0,this.queue.length=0,this.urgentQueueSize=0,this.urgentQueue.length=0,this.batchQueueSize=0}_processJobs(e,t){for(let i=0;i<t;i++){const n=e[i];if(n)try{n()}catch(r){console.error(new F("Error occurred during scheduler execution",r))}}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<b.MIN_FLUSH_ITERATIONS)throw new F(`Max flush iterations must be at least ${b.MIN_FLUSH_ITERATIONS}`);this.maxFlushIterations=e}}const T=new le;function fe(s){if(typeof s!="function")throw new E("Batch callback must be a function");T.startBatch();try{return s()}finally{T.endBatch()}}class de{constructor(){this.current=null}run(e,t){const i=this.current;this.current=e;try{return t()}finally{this.current=i}}getCurrent(){return this.current}}const m=new de;function K(s){if(typeof s!="function")throw new E("Untracked callback must be a function");const e=m.current;m.current=null;try{return s()}finally{m.current=e}}class Q{constructor(){this.pool=[],this.maxPoolSize=50,this.maxReusableCapacity=256,this.stats=f?{acquired:0,released:0,rejected:{frozen:0,tooLarge:0,poolFull:0}}:null}acquire(){return f&&this.stats&&this.stats.acquired++,this.pool.pop()??[]}release(e,t){if(!(t&&e===t)){if(Object.isFrozen(e)){f&&this.stats&&this.stats.rejected.frozen++;return}if(e.length>this.maxReusableCapacity){f&&this.stats&&this.stats.rejected.tooLarge++;return}if(this.pool.length>=this.maxPoolSize){f&&this.stats&&this.stats.rejected.poolFull++;return}e.length=0,this.pool.push(e),f&&this.stats&&this.stats.released++}}getStats(){if(!f||!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,f&&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([]),C=new Q,A=new Q,g=new Q;function Z(s){return s!==null&&typeof s=="object"&&"value"in s&&"subscribe"in s&&typeof s.subscribe=="function"}function Ee(s){if(d.enabled&&(s==null||typeof s=="object")){const e=d.getDebugType(s);if(e)return e==="computed"}return Z(s)&&"invalidate"in s&&typeof s.invalidate=="function"}function pe(s){return s!==null&&typeof s=="object"&&"dispose"in s&&"run"in s&&typeof s.dispose=="function"&&typeof s.run=="function"}function ee(s){return s!=null&&typeof s.then=="function"}function ge(s){return typeof s=="object"&&s!==null}function Se(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 ye(s){return ge(s)&&typeof s.execute=="function"}function te(s,e,t,i){if(e){if(Se(e)){e.addDependency(s);return}if(be(e)){const n=e;t.indexOf(n)===-1&&t.push(n);return}ye(e)&&i.indexOf(e)===-1&&i.push(e)}}function De(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=A.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):(d.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&&A.release(t),n}class Ie extends H{constructor(e,t){super(),this._fnSubs=null,this._objSubs=null,this._value=e,t&&(this.flags|=U.SYNC),d.attachDebugInfo(this,"atom",this.id)}_getFnSubs(){return this._fnSubs??=[],this._fnSubs}_getObjSubs(){return this._objSubs??=[],this._objSubs}get value(){const e=m.current;return e&&te(this,e,this._getFnSubs(),this._getObjSubs()),this._value}set value(e){if(Object.is(this._value,e))return;const t=this._value;this._value=e,this.rotatePhase(),((this._fnSubs?.length??0)>0||(this._objSubs?.length??0)>0)&&this._scheduleNotification(t)}_scheduleNotification(e){if(this.flags&U.NOTIFICATION_SCHEDULED||(this._pendingOldValue=e,this.flags|=U.NOTIFICATION_SCHEDULED),this.flags&U.SYNC&&!T.isBatching){this._flushNotifications();return}this._notifyTask||(this._notifyTask=()=>this._flushNotifications()),T.schedule(this._notifyTask)}_flushNotifications(){if(!(this.flags&U.NOTIFICATION_SCHEDULED))return;const e=this._pendingOldValue,t=this._value;this._pendingOldValue=void 0,this.flags&=-3,this._notifySubscribers(t,e)}peek(){return this._value}dispose(){this._fnSubs=null,this._objSubs=null,this._value=void 0,this._notifyTask=void 0}}function Ce(s,e={}){return new Ie(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 se=u.RESOLVED|u.PENDING|u.REJECTED,V=Array(se+1).fill(O.IDLE);V[u.RESOLVED]=O.RESOLVED,V[u.PENDING]=O.PENDING,V[u.REJECTED]=O.REJECTED;class ie extends H{constructor(e,t={}){if(typeof e!="function")throw new D(c.COMPUTED_MUST_BE_FUNCTION);if(super(),this._fnSubs=null,this._objSubs=null,this._cachedErrors=null,this._errorCacheEpoch=-1,this._asyncStartAggregateVersion=0,this._asyncRetryCount=0,this.MAX_ASYNC_RETRIES=3,this._value=void 0,this.flags=u.DIRTY|u.IDLE,this._error=null,this._promiseId=0,this._equal=t.equal??Object.is,this._fn=e,this._defaultValue="defaultValue"in t?t.defaultValue:q,this._hasDefaultValue=this._defaultValue!==q,this._onError=t.onError??null,this.MAX_PROMISE_ID=Number.MAX_SAFE_INTEGER-1,this._dependencies=_,this._dependencyVersions=a,this._unsubscribes=p,this._notifyJob=()=>{const i=this._fnSubs;if(i)for(let r=i.length-1;r>=0;r--)try{const o=i[r];o&&o(void 0,void 0)}catch(o){console.error(o)}const n=this._objSubs;if(n)for(let r=n.length-1;r>=0;r--)try{const o=n[r];o&&o.execute()}catch(o){console.error(o)}},this._trackable=Object.assign(()=>this._markDirty(),{addDependency:i=>{}}),d.attachDebugInfo(this,"computed",this.id),d.enabled){const i=this;i.subscriberCount=this.subscriberCount.bind(this),i.isDirty=()=>this._isDirty(),i.dependencies=this._dependencies,i.stateFlags=this._getFlagsAsString()}if(t.lazy===!1)try{this._recompute()}catch{}}_getFnSubs(){return this._fnSubs??=[],this._fnSubs}_getObjSubs(){return this._objSubs??=[],this._objSubs}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 re;const e=_e();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 l=r[o];l&&t.add(l)}}}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&&(g.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()}A.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==_&&(C.release(this._dependencies),this._dependencies=_),this._dependencyVersions!==a&&(g.release(this._dependencyVersions),this._dependencyVersions=a),this._fnSubs=null,this._objSubs=null,this.flags=u.DIRTY|u.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&u.DIRTY)!==0}_setDirty(){this.flags|=u.DIRTY}_clearDirty(){this.flags&=-2}_isIdle(){return(this.flags&u.IDLE)!==0}_setIdle(){this.flags|=u.IDLE,this.flags&=-29}_isPending(){return(this.flags&u.PENDING)!==0}_setPending(){this.flags|=u.PENDING,this.flags&=-27}_isResolved(){return(this.flags&u.RESOLVED)!==0}_setResolved(){this.flags|=u.RESOLVED,this.flags&=-87}_isRejected(){return(this.flags&u.REJECTED)!==0}_setRejected(){this.flags|=u.REJECTED|u.HAS_ERROR,this.flags&=-15}_isRecomputing(){return(this.flags&u.RECOMPUTING)!==0}_setRecomputing(e){const t=u.RECOMPUTING;this.flags=this.flags&~t|-Number(e)&t}_getAsyncState(){return V[this.flags&se]}_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=m.run(this._trackable,this._fn);this._commitDependencies(e),t=!0,ee(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=C.acquire(),n=g.acquire(),r=$(),o={depCount:0},l=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++)},R=this._trackable.addDependency;return this._trackable.addDependency=l,{prevDeps:e,prevVersions:t,nextDeps:i,nextVersions:n,originalAdd:R,state:o}}_commitDependencies(e){const{nextDeps:t,nextVersions:i,state:n,prevDeps:r}=e;t.length=n.depCount,i.length=n.depCount,this._unsubscribes=De(t,r,this._unsubscribes,this),this._dependencies=t,this._dependencyVersions=i}_cleanupContext(e,t){this._trackable.addDependency=e.originalAdd,t?(e.prevDeps!==_&&C.release(e.prevDeps),e.prevVersions!==a&&g.release(e.prevVersions)):(C.release(e.nextDeps),g.release(e.nextVersions))}_getAggregateShift(){let e=0;const t=this._dependencies,i=this._dependencyVersions;for(let n=0;n<t.length;n++){const r=t[n],o=i[n];r&&o!==void 0&&(e=e+r.getShift(o)&y)}return e}isUrgent(){return this._getAggregateShift()>=j}_handleSyncResult(e){this._finalizeResolution(e)}_handleAsyncComputation(e){this._setPending(),this._clearDirty(),this._notifyJob(),this._asyncStartAggregateVersion=this._captureVersionSnapshot(),this._asyncRetryCount=0,this._promiseId=this._promiseId>=this.MAX_PROMISE_ID?1:this._promiseId+1;const t=this._promiseId;e.then(i=>{if(t!==this._promiseId)return;const r=this._captureVersionSnapshot()-this._asyncStartAggregateVersion&y;if(j-1-r>>>31&1){if(this._asyncRetryCount<this.MAX_ASYNC_RETRIES){this._asyncRetryCount++,this._markDirty();return}const l=new D(`Async drift exceeded threshold after ${this.MAX_ASYNC_RETRIES} retries. Dependencies changed too rapidly for stable computation.`);this._handleAsyncRejection(l);return}this._handleAsyncResolution(i)}).catch(i=>{t===this._promiseId&&this._handleAsyncRejection(i)})}_captureVersionSnapshot(){let e=0;const t=this._dependencies;for(let i=0;i<t.length;i++){const n=t[i];n&&(e=e+n.version&y)}return e}_handleAsyncResolution(e){this._finalizeResolution(e),this._notifyJob()}_finalizeResolution(e){(!this._isResolved()||!this._equal(this._value,e))&&this.rotatePhase(),this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),this._cachedErrors=null,this._errorCacheEpoch=-1}_handleAsyncRejection(e){const t=x(e,D,c.COMPUTED_ASYNC_COMPUTATION_FAILED);if(!this._isRejected()&&this.rotatePhase(),this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(n){console.error(c.CALLBACK_ERROR_IN_ERROR_HANDLER,n)}this._notifyJob()}_handleComputationError(e){const t=x(e,D,c.COMPUTED_COMPUTATION_FAILED);if(this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(i){console.error(c.CALLBACK_ERROR_IN_ERROR_HANDLER,i)}throw t}_handlePending(){if(this._hasDefaultValue)return this._defaultValue;throw new D(c.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(){te(this,m.getCurrent(),this._getFnSubs(),this._getObjSubs())}}Object.freeze(ie.prototype);function me(s,e={}){return new ie(s,e)}class Ae extends Y{constructor(e,t={}){super(),this.run=()=>{if(this.isDisposed)throw new I(c.EFFECT_MUST_BE_FUNCTION);this._dependencyVersions!==a&&(g.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()}A.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==_&&(C.release(this._dependencies),this._dependencies=_),this._dependencyVersions!==a&&(g.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._prepareEffectExecutionContext();let r=!1;try{const o=m.run(this,this._fn);this._commitEffect(n),r=!0,this._checkLoopWarnings(),ee(o)?o.then(l=>{!this.isDisposed&&typeof l=="function"&&(this._cleanup=l)}).catch(l=>{this._handleExecutionError(l)}):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._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._currentEpoch=-1,this._lastFlushEpoch=-1,this._executionsInEpoch=0,this._fn=e,this._sync=t.sync??!1,this._maxExecutions=t.maxExecutionsPerSecond??b.MAX_EXECUTIONS_PER_SECOND,this._maxExecutionsPerFlush=t.maxExecutionsPerFlush??b.MAX_EXECUTIONS_PER_EFFECT,this._trackModifications=t.trackModifications??!1,this._historyPtr=0;const i=Number.isFinite(this._maxExecutions);this._historyCapacity=i?Math.min(this._maxExecutions+1,b.MAX_EXECUTIONS_PER_SECOND+1):0,this._history=f&&i&&this._historyCapacity>0?new Array(this._historyCapacity).fill(0):null,this._executionCount=0,d.attachDebugInfo(this,"effect",this.id)}_prepareEffectExecutionContext(){const e=this._dependencies,t=this._dependencyVersions,i=this._unsubscribes,n=C.acquire(),r=g.acquire(),o=A.acquire(),l=$();if(e!==_&&i!==p)for(let R=0;R<e.length;R++){const S=e[R];S&&(S._tempUnsub=i[R])}return this._nextDeps=n,this._nextVersions=r,this._nextUnsubs=o,this._currentEpoch=l,{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)}C.release(e.prevDeps)}e.prevUnsubs!==p&&A.release(e.prevUnsubs),e.prevVersions!==a&&g.release(e.prevVersions)}else{C.release(e.nextDeps),g.release(e.nextVersions);for(let i=0;i<e.nextUnsubs.length;i++)e.nextUnsubs[i]?.();if(A.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():T.schedule(this.execute)});this._nextUnsubs&&this._nextUnsubs.push(t)}catch(t){console.error(x(t,I,c.EFFECT_EXECUTION_FAILED)),this._nextUnsubs&&this._nextUnsubs.push(()=>{})}}get isDisposed(){return(this.flags&P.DISPOSED)!==0}get executionCount(){return this._executionCount}get isExecuting(){return(this.flags&P.EXECUTING)!==0}_setDisposed(){this.flags|=P.DISPOSED}_setExecuting(e){const t=P.EXECUTING;this.flags=this.flags&~t|-Number(e)&t}_safeCleanup(){if(this._cleanup){try{this._cleanup()}catch(e){console.error(x(e,I,c.EFFECT_CLEANUP_FAILED))}this._cleanup=null}}_checkInfiniteLoop(){if(this._lastFlushEpoch!==L&&(this._lastFlushEpoch=L,this._executionsInEpoch=0),this._executionsInEpoch++,this._executionsInEpoch>this._maxExecutionsPerFlush&&this._throwInfiniteLoopError("per-effect"),ae()>b.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<N.ONE_SECOND_MS){const o=new I(`Effect executed ${i} times within 1 second. Infinite loop suspected`);if(this.dispose(),console.error(o),this._onError&&this._onError(o),f)throw o}}}_throwInfiniteLoopError(e){const t=new I(`Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${k}`);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{K(()=>t.value)}catch{return!0}if(t.version!==this._dependencyVersions[e])return!0}}return!1}_handleExecutionError(e){const t=x(e,I,c.EFFECT_EXECUTION_FAILED);console.error(t),this._onError&&this._onError(t)}_checkLoopWarnings(){if(this._trackModifications&&d.enabled){const e=this._dependencies;for(let t=0;t<e.length;t++){const i=e[t];i&&i._modifiedAtEpoch===this._currentEpoch&&d.warn(!0,`Effect is reading a dependency (${d.getDebugName(i)||"unknown"}) that it just modified. Infinite loop may occur`)}}}}function Te(s,e={}){if(typeof s!="function")throw new I(c.EFFECT_MUST_BE_FUNCTION);const t=new Ae(s,e);return t.execute(),t}h.AsyncState=O,h.AtomError=E,h.ComputedError=D,h.DEBUG_CONFIG=w,h.DEBUG_RUNTIME=d,h.EffectError=I,h.POOL_CONFIG=ne,h.SCHEDULER_CONFIG=b,h.SchedulerError=F,h.atom=Ce,h.batch=fe,h.computed=me,h.effect=Te,h.isAtom=Z,h.isComputed=Ee,h.isEffect=pe,h.scheduler=T,h.untracked=K,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})}));
|
|
1
|
+
(function(h,N){typeof exports=="object"&&typeof module<"u"?N(exports):typeof define=="function"&&define.amd?define(["exports"],N):(h=typeof globalThis<"u"?globalThis:h||self,N(h.AtomEffect={}))})(this,(function(h){"use strict";const N={ONE_SECOND_MS:1e3},O={IDLE:"idle",PENDING:"pending",RESOLVED:"resolved",REJECTED:"rejected"},P={DISPOSED:1,EXECUTING:2},u={DIRTY:1,IDLE:2,PENDING:4,RESOLVED:8,REJECTED:16,RECOMPUTING:32,HAS_ERROR:64},U={SYNC:1,NOTIFICATION_SCHEDULED:2},ne={MAX_SIZE:1e3,WARMUP_SIZE:100},b={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},y=1073741823,B=1<<20-1,f=typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production",re=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 D extends E{constructor(e,t=null){super(e,t,!0),this.name="ComputedError"}}class I extends E{constructor(e,t=null){super(e,t,!1),this.name="EffectError"}}class F extends E{constructor(e,t=null){super(e,t,!1),this.name="SchedulerError"}}const c={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"},j=Symbol("debugName"),oe=Symbol("id"),z=Symbol("type"),q=Symbol("noDefaultValue");function he(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 D("Indirect circular dependency detected");if(he(s)){const i=s.dependencies;for(let n=0;n<i.length;n++){const r=i[n];r&&X(r,e,t)}}}}const d={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 D("Direct circular dependency detected");this.enabled&&(G++,X(s,e,G))},attachDebugInfo(s,e,t){if(!this.enabled)return;const i=s;i[j]=`${e}_${t}`,i[oe]=t,i[z]=e},getDebugName(s){if(s!=null&&j in s)return s[j]},getDebugType(s){if(s!=null&&z in s)return s[z]}};let ue=1;const ce=()=>ue++;class H{constructor(){this.flags=0,this.version=0,this._lastSeenEpoch=-1,this.id=ce()&y}rotatePhase(){return this.version=this.version+1&y,this.version}getShift(e){return this.version-e&y}}class Y extends H{subscribe(e){if(typeof e=="object"&&e!==null&&"execute"in e)return this._addSubscriber(this._getObjSubs(),e);if(typeof e!="function")throw new E(c.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);return this._addSubscriber(this._getFnSubs(),e)}subscriberCount(){return(this._fnSubs?.length??0)+(this._objSubs?.length??0)}_addSubscriber(e,t){if(e.indexOf(t)!==-1)return()=>{};e.push(t);let i=!1;return()=>{if(i)return;i=!0;const n=e.indexOf(t);if(n!==-1){const r=e.length-1;n!==r&&(e[n]=e[r]),e.pop()}}}_notifySubscribers(e,t){const i=this._fnSubs;if(i)for(let r=i.length-1;r>=0;r--)try{const o=i[r];o&&o(e,t)}catch(o){console.error(new E(c.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,o))}const n=this._objSubs;if(n)for(let r=n.length-1;r>=0;r--)try{const o=n[r];o&&o.execute()}catch(o){console.error(new E(c.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,o))}}}class k{constructor(){this.pool=[],this.maxPoolSize=50,this.maxReusableCapacity=256,this.stats=f?{acquired:0,released:0,rejected:{frozen:0,tooLarge:0,poolFull:0}}:null}acquire(){return f&&this.stats&&this.stats.acquired++,this.pool.pop()??[]}release(e,t){if(!(t&&e===t)){if(Object.isFrozen(e)){f&&this.stats&&this.stats.rejected.frozen++;return}if(e.length>this.maxReusableCapacity){f&&this.stats&&this.stats.rejected.tooLarge++;return}if(this.pool.length>=this.maxPoolSize){f&&this.stats&&this.stats.rejected.poolFull++;return}e.length=0,this.pool.push(e),f&&this.stats&&this.stats.released++}}getStats(){if(!f||!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,f&&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([]),C=new k,m=new k,g=new k;function $(s){return s!==null&&typeof s=="object"&&"value"in s&&"subscribe"in s&&typeof s.subscribe=="function"}function _e(s){if(d.enabled&&(s==null||typeof s=="object")){const e=d.getDebugType(s);if(e)return e==="computed"}return $(s)&&"invalidate"in s&&typeof s.invalidate=="function"}function ae(s){return s!==null&&typeof s=="object"&&"dispose"in s&&"run"in s&&typeof s.dispose=="function"&&typeof s.run=="function"}function J(s){return s!=null&&typeof s.then=="function"}function le(s){return typeof s=="object"&&s!==null}function fe(s){return(typeof s=="object"||typeof s=="function")&&s!==null&&typeof s.addDependency=="function"}function de(s){return typeof s=="function"&&typeof s.addDependency!="function"}function Ee(s){return le(s)&&typeof s.execute=="function"}function W(s,e,t,i){if(e){if(fe(e)){e.addDependency(s);return}if(de(e)){const n=e;t.indexOf(n)===-1&&t.push(n);return}Ee(e)&&i.indexOf(e)===-1&&i.push(e)}}function pe(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=m.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):(d.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&&m.release(t),n}let v=0;function K(){return v=v+1&y||1,v}function ge(){return v}let L=0,Q=0,M=!1;function Z(){return M?(f&&console.warn("Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"),!1):(M=!0,L=L+1&y,Q=0,!0)}function ee(){M=!1}function Se(){return M?++Q:0}class be{constructor(){this.queueA=[],this.queueB=[],this.queue=this.queueA,this.queueSize=0,this.urgentQueueA=[],this.urgentQueueB=[],this.urgentQueue=this.urgentQueueA,this.urgentQueueSize=0,this._epoch=0,this.isProcessing=!1,this.isBatching=!1,this.batchDepth=0,this.batchQueue=[],this.batchQueueSize=0,this.isFlushingSync=!1,this.maxFlushIterations=b.MAX_FLUSH_ITERATIONS}get phase(){return this.isProcessing||this.isFlushingSync?2:this.isBatching?1:0}schedule(e,t){if(typeof e!="function")throw new F("Scheduler callback must be a function");if(e._nextEpoch!==this._epoch)if(e._nextEpoch=this._epoch,this.isBatching||this.isFlushingSync)this.batchQueue[this.batchQueueSize++]=e;else{const i=this._calculateUrgency(e,t);this.urgentQueue[this.urgentQueueSize]=e,this.queue[this.queueSize]=e,this.urgentQueueSize+=i,this.queueSize+=i^1,this.isProcessing||this.flush()}}_calculateUrgency(e,t){if(!t||e._cachedVersion===void 0)return 0;const i=t.getShift(e._cachedVersion);return B-1-i>>>31&1}flush(){this.isProcessing||this.queueSize===0&&this.urgentQueueSize===0||(this.isProcessing=!0,queueMicrotask(()=>{try{if(this.queueSize===0&&this.urgentQueueSize===0)return;const e=Z();this._drainQueue(),e&&ee()}finally{this.isProcessing=!1,(this.queueSize>0||this.urgentQueueSize>0)&&!this.isBatching&&this.flush()}}))}flushSync(){this.isFlushingSync=!0;const e=Z();try{this._mergeBatchQueue(),this._drainQueue()}finally{this.isFlushingSync=!1,e&&ee()}}_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.urgentQueueSize>0||this.queueSize>0;){if(++e>this.maxFlushIterations){this._handleFlushOverflow();return}this.urgentQueueSize>0&&this._processUrgentQueue(),this.queueSize>0&&this._processCurrentQueue(),this._mergeBatchQueue()}}_processUrgentQueue(){const e=this.urgentQueue,t=this.urgentQueueSize;this.urgentQueue=this.urgentQueue===this.urgentQueueA?this.urgentQueueB:this.urgentQueueA,this.urgentQueueSize=0,this._epoch++,this._processJobs(e,t)}_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 F(`Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop.`)),this.queueSize=0,this.queue.length=0,this.urgentQueueSize=0,this.urgentQueue.length=0,this.batchQueueSize=0}_processJobs(e,t){for(let i=0;i<t;i++){const n=e[i];if(n)try{n()}catch(r){console.error(new F("Error occurred during scheduler execution",r))}}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<b.MIN_FLUSH_ITERATIONS)throw new F(`Max flush iterations must be at least ${b.MIN_FLUSH_ITERATIONS}`);this.maxFlushIterations=e}}const T=new be;class ye{constructor(){this.current=null}run(e,t){const i=this.current;this.current=e;try{return t()}finally{this.current=i}}getCurrent(){return this.current}}const A=new ye;function te(s){if(typeof s!="function")throw new E("Untracked callback must be a function");const e=A.current;A.current=null;try{return s()}finally{A.current=e}}class De extends Y{constructor(e,t){super(),this._fnSubs=null,this._objSubs=null,this._value=e,t&&(this.flags|=U.SYNC),d.attachDebugInfo(this,"atom",this.id)}_getFnSubs(){return this._fnSubs??=[],this._fnSubs}_getObjSubs(){return this._objSubs??=[],this._objSubs}get value(){const e=A.current;return e&&W(this,e,this._getFnSubs(),this._getObjSubs()),this._value}set value(e){if(Object.is(this._value,e))return;const t=this._value;this._value=e,this.rotatePhase(),((this._fnSubs?.length??0)>0||(this._objSubs?.length??0)>0)&&this._scheduleNotification(t)}_scheduleNotification(e){if(this.flags&U.NOTIFICATION_SCHEDULED||(this._pendingOldValue=e,this.flags|=U.NOTIFICATION_SCHEDULED),this.flags&U.SYNC&&!T.isBatching){this._flushNotifications();return}this._notifyTask||(this._notifyTask=()=>this._flushNotifications()),T.schedule(this._notifyTask)}_flushNotifications(){if(!(this.flags&U.NOTIFICATION_SCHEDULED))return;const e=this._pendingOldValue,t=this._value;this._pendingOldValue=void 0,this.flags&=-3,this._notifySubscribers(t,e)}peek(){return this._value}dispose(){this._fnSubs=null,this._objSubs=null,this._value=void 0,this._notifyTask=void 0}}function Ie(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 se=u.RESOLVED|u.PENDING|u.REJECTED,V=Array(se+1).fill(O.IDLE);V[u.RESOLVED]=O.RESOLVED,V[u.PENDING]=O.PENDING,V[u.REJECTED]=O.REJECTED;class ie extends Y{constructor(e,t={}){if(typeof e!="function")throw new D(c.COMPUTED_MUST_BE_FUNCTION);if(super(),this._fnSubs=null,this._objSubs=null,this._cachedErrors=null,this._errorCacheEpoch=-1,this._asyncStartAggregateVersion=0,this._asyncRetryCount=0,this.MAX_ASYNC_RETRIES=3,this._value=void 0,this.flags=u.DIRTY|u.IDLE,this._error=null,this._promiseId=0,this._equal=t.equal??Object.is,this._fn=e,this._defaultValue="defaultValue"in t?t.defaultValue:q,this._hasDefaultValue=this._defaultValue!==q,this._onError=t.onError??null,this.MAX_PROMISE_ID=Number.MAX_SAFE_INTEGER-1,this._dependencies=_,this._dependencyVersions=a,this._unsubscribes=p,this._notifyJob=()=>{const i=this._fnSubs;if(i)for(let r=i.length-1;r>=0;r--)try{const o=i[r];o&&o(void 0,void 0)}catch(o){console.error(o)}const n=this._objSubs;if(n)for(let r=n.length-1;r>=0;r--)try{const o=n[r];o&&o.execute()}catch(o){console.error(o)}},this._trackable=Object.assign(()=>this._markDirty(),{addDependency:i=>{}}),d.attachDebugInfo(this,"computed",this.id),d.enabled){const i=this;i.subscriberCount=this.subscriberCount.bind(this),i.isDirty=()=>this._isDirty(),i.dependencies=this._dependencies,i.stateFlags=this._getFlagsAsString()}if(t.lazy===!1)try{this._recompute()}catch{}}_getFnSubs(){return this._fnSubs??=[],this._fnSubs}_getObjSubs(){return this._objSubs??=[],this._objSubs}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 re;const e=ge();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 l=r[o];l&&t.add(l)}}}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&&(g.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()}m.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==_&&(C.release(this._dependencies),this._dependencies=_),this._dependencyVersions!==a&&(g.release(this._dependencyVersions),this._dependencyVersions=a),this._fnSubs=null,this._objSubs=null,this.flags=u.DIRTY|u.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&u.DIRTY)!==0}_setDirty(){this.flags|=u.DIRTY}_clearDirty(){this.flags&=-2}_isIdle(){return(this.flags&u.IDLE)!==0}_setIdle(){this.flags|=u.IDLE,this.flags&=-29}_isPending(){return(this.flags&u.PENDING)!==0}_setPending(){this.flags|=u.PENDING,this.flags&=-27}_isResolved(){return(this.flags&u.RESOLVED)!==0}_setResolved(){this.flags|=u.RESOLVED,this.flags&=-87}_isRejected(){return(this.flags&u.REJECTED)!==0}_setRejected(){this.flags|=u.REJECTED|u.HAS_ERROR,this.flags&=-15}_isRecomputing(){return(this.flags&u.RECOMPUTING)!==0}_setRecomputing(e){const t=u.RECOMPUTING;this.flags=this.flags&~t|-Number(e)&t}_getAsyncState(){return V[this.flags&se]}_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=A.run(this._trackable,this._fn);this._commitDependencies(e),t=!0,J(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=C.acquire(),n=g.acquire(),r=K(),o={depCount:0},l=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++)},R=this._trackable.addDependency;return this._trackable.addDependency=l,{prevDeps:e,prevVersions:t,nextDeps:i,nextVersions:n,originalAdd:R,state:o}}_commitDependencies(e){const{nextDeps:t,nextVersions:i,state:n,prevDeps:r}=e;t.length=n.depCount,i.length=n.depCount,this._unsubscribes=pe(t,r,this._unsubscribes,this),this._dependencies=t,this._dependencyVersions=i}_cleanupContext(e,t){this._trackable.addDependency=e.originalAdd,t?(e.prevDeps!==_&&C.release(e.prevDeps),e.prevVersions!==a&&g.release(e.prevVersions)):(C.release(e.nextDeps),g.release(e.nextVersions))}_getAggregateShift(){let e=0;const t=this._dependencies,i=this._dependencyVersions;for(let n=0;n<t.length;n++){const r=t[n],o=i[n];r&&o!==void 0&&(e=e+r.getShift(o)&y)}return e}isUrgent(){return this._getAggregateShift()>=B}_handleSyncResult(e){this._finalizeResolution(e)}_handleAsyncComputation(e){this._setPending(),this._clearDirty(),this._notifyJob(),this._asyncStartAggregateVersion=this._captureVersionSnapshot(),this._asyncRetryCount=0,this._promiseId=this._promiseId>=this.MAX_PROMISE_ID?1:this._promiseId+1;const t=this._promiseId;e.then(i=>{if(t!==this._promiseId)return;const r=this._captureVersionSnapshot()-this._asyncStartAggregateVersion&y;if(B-1-r>>>31&1){if(this._asyncRetryCount<this.MAX_ASYNC_RETRIES){this._asyncRetryCount++,this._markDirty();return}const l=new D(`Async drift exceeded threshold after ${this.MAX_ASYNC_RETRIES} retries. Dependencies changed too rapidly for stable computation.`);this._handleAsyncRejection(l);return}this._handleAsyncResolution(i)}).catch(i=>{t===this._promiseId&&this._handleAsyncRejection(i)})}_captureVersionSnapshot(){let e=0;const t=this._dependencies;for(let i=0;i<t.length;i++){const n=t[i];n&&(e=e+n.version&y)}return e}_handleAsyncResolution(e){this._finalizeResolution(e),this._notifyJob()}_finalizeResolution(e){(!this._isResolved()||!this._equal(this._value,e))&&this.rotatePhase(),this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),this._cachedErrors=null,this._errorCacheEpoch=-1}_handleAsyncRejection(e){const t=x(e,D,c.COMPUTED_ASYNC_COMPUTATION_FAILED);if(!this._isRejected()&&this.rotatePhase(),this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(n){console.error(c.CALLBACK_ERROR_IN_ERROR_HANDLER,n)}this._notifyJob()}_handleComputationError(e){const t=x(e,D,c.COMPUTED_COMPUTATION_FAILED);if(this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(i){console.error(c.CALLBACK_ERROR_IN_ERROR_HANDLER,i)}throw t}_handlePending(){if(this._hasDefaultValue)return this._defaultValue;throw new D(c.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(){W(this,A.getCurrent(),this._getFnSubs(),this._getObjSubs())}}Object.freeze(ie.prototype);function Ce(s,e={}){return new ie(s,e)}class me extends H{constructor(e,t={}){super(),this.run=()=>{if(this.isDisposed)throw new I(c.EFFECT_MUST_BE_FUNCTION);this._dependencyVersions!==a&&(g.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()}m.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==_&&(C.release(this._dependencies),this._dependencies=_),this._dependencyVersions!==a&&(g.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._prepareEffectExecutionContext();let r=!1;try{const o=A.run(this,this._fn);this._commitEffect(n),r=!0,this._checkLoopWarnings(),J(o)?o.then(l=>{!this.isDisposed&&typeof l=="function"&&(this._cleanup=l)}).catch(l=>{this._handleExecutionError(l)}):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._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._currentEpoch=-1,this._lastFlushEpoch=-1,this._executionsInEpoch=0,this._fn=e,this._sync=t.sync??!1,this._maxExecutions=t.maxExecutionsPerSecond??b.MAX_EXECUTIONS_PER_SECOND,this._maxExecutionsPerFlush=t.maxExecutionsPerFlush??b.MAX_EXECUTIONS_PER_EFFECT,this._trackModifications=t.trackModifications??!1,this._historyPtr=0;const i=Number.isFinite(this._maxExecutions);this._historyCapacity=i?Math.min(this._maxExecutions+1,b.MAX_EXECUTIONS_PER_SECOND+1):0,this._history=f&&i&&this._historyCapacity>0?new Array(this._historyCapacity).fill(0):null,this._executionCount=0,d.attachDebugInfo(this,"effect",this.id)}_prepareEffectExecutionContext(){const e=this._dependencies,t=this._dependencyVersions,i=this._unsubscribes,n=C.acquire(),r=g.acquire(),o=m.acquire(),l=K();if(e!==_&&i!==p)for(let R=0;R<e.length;R++){const S=e[R];S&&(S._tempUnsub=i[R])}return this._nextDeps=n,this._nextVersions=r,this._nextUnsubs=o,this._currentEpoch=l,{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)}C.release(e.prevDeps)}e.prevUnsubs!==p&&m.release(e.prevUnsubs),e.prevVersions!==a&&g.release(e.prevVersions)}else{C.release(e.nextDeps),g.release(e.nextVersions);for(let i=0;i<e.nextUnsubs.length;i++)e.nextUnsubs[i]?.();if(m.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():T.schedule(this.execute)});this._nextUnsubs&&this._nextUnsubs.push(t)}catch(t){console.error(x(t,I,c.EFFECT_EXECUTION_FAILED)),this._nextUnsubs&&this._nextUnsubs.push(()=>{})}}get isDisposed(){return(this.flags&P.DISPOSED)!==0}get executionCount(){return this._executionCount}get isExecuting(){return(this.flags&P.EXECUTING)!==0}_setDisposed(){this.flags|=P.DISPOSED}_setExecuting(e){const t=P.EXECUTING;this.flags=this.flags&~t|-Number(e)&t}_safeCleanup(){if(this._cleanup){try{this._cleanup()}catch(e){console.error(x(e,I,c.EFFECT_CLEANUP_FAILED))}this._cleanup=null}}_checkInfiniteLoop(){if(this._lastFlushEpoch!==L&&(this._lastFlushEpoch=L,this._executionsInEpoch=0),this._executionsInEpoch++,this._executionsInEpoch>this._maxExecutionsPerFlush&&this._throwInfiniteLoopError("per-effect"),Se()>b.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<N.ONE_SECOND_MS){const o=new I(`Effect executed ${i} times within 1 second. Infinite loop suspected`);if(this.dispose(),console.error(o),this._onError&&this._onError(o),f)throw o}}}_throwInfiniteLoopError(e){const t=new I(`Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${Q}`);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{te(()=>t.value)}catch{return!0}if(t.version!==this._dependencyVersions[e])return!0}}return!1}_handleExecutionError(e){const t=x(e,I,c.EFFECT_EXECUTION_FAILED);console.error(t),this._onError&&this._onError(t)}_checkLoopWarnings(){if(this._trackModifications&&d.enabled){const e=this._dependencies;for(let t=0;t<e.length;t++){const i=e[t];i&&i._modifiedAtEpoch===this._currentEpoch&&d.warn(!0,`Effect is reading a dependency (${d.getDebugName(i)||"unknown"}) that it just modified. Infinite loop may occur`)}}}}function Ae(s,e={}){if(typeof s!="function")throw new I(c.EFFECT_MUST_BE_FUNCTION);const t=new me(s,e);return t.execute(),t}function Te(s){if(typeof s!="function")throw new E("Batch callback must be a function");T.startBatch();try{return s()}finally{T.endBatch()}}h.AsyncState=O,h.AtomError=E,h.ComputedError=D,h.DEBUG_CONFIG=w,h.DEBUG_RUNTIME=d,h.EffectError=I,h.POOL_CONFIG=ne,h.SCHEDULER_CONFIG=b,h.SchedulerError=F,h.atom=Ie,h.batch=Te,h.computed=Ce,h.effect=Ae,h.isAtom=$,h.isComputed=_e,h.isEffect=ae,h.scheduler=T,h.untracked=te,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})}));
|
|
2
2
|
//# sourceMappingURL=atom-effect.min.js.map
|