@but212/atom-effect 0.11.0 → 0.12.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 +7 -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.d.ts +13 -0
- package/dist/index.mjs +365 -385
- 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 | ~6.
|
|
147
|
-
| Atom read | ~11.
|
|
148
|
-
| Atom write | ~9.
|
|
149
|
-
| Computed creation | ~1.
|
|
146
|
+
| Atom creation | ~6.13M ops/sec |
|
|
147
|
+
| Atom read | ~11.45M ops/sec |
|
|
148
|
+
| Atom write | ~9.44M ops/sec |
|
|
149
|
+
| Computed creation | ~1.96M ops/sec |
|
|
150
150
|
| Computed recomputation | ~558K ops/sec |
|
|
151
|
-
| Effect execution | ~2.
|
|
152
|
-
| Batched updates | ~
|
|
153
|
-
| Deep chain (100 levels) | ~8.
|
|
151
|
+
| Effect execution | ~2.75M ops/sec |
|
|
152
|
+
| Batched updates | ~3.86M ops/sec |
|
|
153
|
+
| Deep chain (100 levels) | ~8.03K ops/sec |
|
|
154
154
|
|
|
155
155
|
## Contributing
|
|
156
156
|
|
package/dist/atom-effect.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(u,N){typeof exports=="object"&&typeof module<"u"?N(exports):typeof define=="function"&&define.amd?define(["exports"],N):(u=typeof globalThis<"u"?globalThis:u||self,N(u.AtomEffect={}))})(this,(function(u){"use strict";const N={ONE_SECOND_MS:1e3},O={IDLE:"idle",PENDING:"pending",RESOLVED:"resolved",REJECTED:"rejected"},P={DISPOSED:1,EXECUTING:2},h={DIRTY:1,IDLE:2,PENDING:4,RESOLVED:8,REJECTED:16,RECOMPUTING:32,HAS_ERROR:64},U={SYNC:1,NOTIFICATION_SCHEDULED:2},re={MAX_SIZE:1e3,WARMUP_SIZE:100},S={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},j={MAX_DEPENDENCIES:1e3,WARN_INFINITE_LOOP:!0},y=1073741823,z=1<<19,f=typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production",oe=Object.freeze([]);class E extends Error{constructor(e,t=null,s=!0){super(e),this.name="AtomError",this.cause=t,this.recoverable=s,this.timestamp=new Date}}class D extends 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"},k=Symbol("debugName"),ue=Symbol("id"),B=Symbol("type"),G=Symbol("noDefaultValue");function he(i){return"dependencies"in i&&Array.isArray(i.dependencies)}let X=0;function Y(i,e,t){if(i._visitedEpoch!==t){if(i._visitedEpoch=t,i===e)throw new D("Indirect circular dependency detected");if(he(i)){const s=i.dependencies;for(let n=0;n<s.length;n++){const r=s[n];r&&Y(r,e,t)}}}}const d={enabled:typeof process<"u"&&process.env?.NODE_ENV==="development",maxDependencies:j.MAX_DEPENDENCIES,warnInfiniteLoop:j.WARN_INFINITE_LOOP,warn(i,e){this.enabled&&i&&console.warn(`[Atom Effect] ${e}`)},checkCircular(i,e){if(i===e)throw new D("Direct circular dependency detected");this.enabled&&(X++,Y(i,e,X))},attachDebugInfo(i,e,t){if(!this.enabled)return;const s=i;s[k]=`${e}_${t}`,s[ue]=t,s[B]=e},getDebugName(i){if(i!=null&&k in i)return i[k]},getDebugType(i){if(i!=null&&B in i)return i[B]}};let ce=1;const ae=()=>ce++;class H{constructor(){this.id=ae()&y,this.flags=0,this.version=0}rotatePhase(){return this.version=this.version+1&y,this.version}getShift(e){return this.version-e&y}}class $ extends H{constructor(){super(),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(c.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);return this._functionSubscribers.add(e)}subscriberCount(){return this._functionSubscribers.size+this._objectSubscribers.size}_notifySubscribers(e,t){this._functionSubscribers.forEachSafe(s=>s(e,t),s=>console.error(new E(c.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,s))),this._objectSubscribers.forEachSafe(s=>s.execute(),s=>console.error(new E(c.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,s)))}}let v=0;function J(){return v=v+1&y||1,v}function _e(){return v}let M=0,Q=0,L=!1;function W(){return L?(f&&console.warn("Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"),!1):(L=!0,M=M+1&y,Q=0,!0)}function K(){L=!1}function le(){return L?++Q:0}class fe{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=S.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 s=this._calculateUrgency(e,t);this.urgentQueue[this.urgentQueueSize]=e,this.queue[this.queueSize]=e,this.urgentQueueSize+=s,this.queueSize+=s^1,this.isProcessing||this.flush()}}_calculateUrgency(e,t){if(!t||e._cachedVersion===void 0)return 0;const s=t.getShift(e._cachedVersion);return z-1-s>>>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=W();this._drainQueue(),e&&K()}finally{this.isProcessing=!1,(this.queueSize>0||this.urgentQueueSize>0)&&!this.isBatching&&this.flush()}}))}flushSync(){this.isFlushingSync=!0;const e=W();try{this._mergeBatchQueue(),this._drainQueue()}finally{this.isFlushingSync=!1,e&&K()}}_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();break}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 s=0;s<t;s++)try{e[s]?.()}catch(n){console.error(new F("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<S.MIN_FLUSH_ITERATIONS)throw new F(`Max flush iterations must be at least ${S.MIN_FLUSH_ITERATIONS}`);this.maxFlushIterations=e}}const T=new fe;function de(i){if(typeof i!="function")throw new E("Batch callback must be a function");T.startBatch();try{return i()}finally{T.endBatch()}}class Ee{constructor(){this.current=null}run(e,t){const s=this.current;this.current=e;try{return t()}finally{this.current=s}}getCurrent(){return this.current}}const m=new Ee;function Z(i){if(typeof i!="function")throw new E("Untracked callback must be a function");const e=m.current;m.current=null;try{return i()}finally{m.current=e}}class V{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 s=this.subscribers.length-1;return t!==s&&(this.subscribers[t]=this.subscribers[s]),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 s=0;s<this.subscribers.length;s++)try{e(this.subscribers[s],s)}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=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:s}=this.stats,n=s.frozen+s.tooLarge+s.poolFull;return{acquired:e,released:t,rejected:s,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 a=Object.freeze([]),p=Object.freeze([]),_=Object.freeze([]),C=new q,A=new q,b=new q;function ee(i){return i!==null&&typeof i=="object"&&"value"in i&&"subscribe"in i&&typeof i.subscribe=="function"}function pe(i){if(d.enabled&&(i==null||typeof i=="object")){const e=d.getDebugType(i);if(e)return e==="computed"}return ee(i)&&"invalidate"in i&&typeof i.invalidate=="function"}function be(i){return i!==null&&typeof i=="object"&&"dispose"in i&&"run"in i&&typeof i.dispose=="function"&&typeof i.run=="function"}function te(i){return i!=null&&typeof i.then=="function"}function ge(i){return typeof i=="object"&&i!==null}function Se(i){return(typeof i=="object"||typeof i=="function")&&i!==null&&typeof i.addDependency=="function"}function ye(i){return typeof i=="function"&&typeof i.addDependency!="function"}function De(i){return ge(i)&&typeof i.execute=="function"}function se(i,e,t,s){if(e){if(Se(e)){e.addDependency(i);return}if(ye(e)){t.add(e);return}De(e)&&s.add(e)}}function Ie(i,e,t,s){if(e!==a&&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=i.length;for(let r=0;r<i.length;r++){const o=i[r];o&&(o._tempUnsub?(n[r]=o._tempUnsub,o._tempUnsub=void 0):(d.checkCircular(o,s),n[r]=o.subscribe(s)))}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&&A.release(t),n}class Ce extends ${constructor(e,t){super(),this._functionSubscribersStore=null,this._objectSubscribersStore=null,this._value=e,t&&(this.flags|=U.SYNC),d.attachDebugInfo(this,"atom",this.id)}get _functionSubscribers(){return this._functionSubscribersStore||(this._functionSubscribersStore=new V),this._functionSubscribersStore}get _objectSubscribers(){return this._objectSubscribersStore||(this._objectSubscribersStore=new V),this._objectSubscribersStore}get value(){const e=m.current;return e&&se(this,e,this._functionSubscribers,this._objectSubscribers),this._value}set value(e){if(Object.is(this._value,e))return;const t=this._value;this._value=e,this.rotatePhase();const s=this._functionSubscribersStore?.hasSubscribers,n=this._objectSubscribersStore?.hasSubscribers;(s||n)&&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)}_notifySubscribers(e,t){this._functionSubscribersStore&&this._functionSubscribersStore.forEachSafe(s=>s(e,t)),this._objectSubscribersStore&&this._objectSubscribersStore.forEachSafe(s=>s.execute())}peek(){return this._value}dispose(){this._functionSubscribersStore?.clear(),this._objectSubscribersStore?.clear(),this._value=void 0,this._notifyTask=void 0}}function me(i,e={}){return new Ce(i,e.sync??!1)}function x(i,e,t){if(i instanceof TypeError)return new e(`Type error (${t}): ${i.message}`,i);if(i instanceof ReferenceError)return new e(`Reference error (${t}): ${i.message}`,i);if(i instanceof E)return i;const s=i instanceof Error?i.message:String(i),n=i instanceof Error?i:null;return new e(`Unexpected error (${t}): ${s}`,n)}const ie=h.RESOLVED|h.PENDING|h.REJECTED,w=Array(ie+1).fill(O.IDLE);w[h.RESOLVED]=O.RESOLVED,w[h.PENDING]=O.PENDING,w[h.REJECTED]=O.REJECTED;class ne extends ${constructor(e,t={}){if(typeof e!="function")throw new D(c.COMPUTED_MUST_BE_FUNCTION);if(super(),this._cachedErrors=null,this._errorCacheEpoch=-1,this._asyncStartAggregateVersion=0,this._asyncRetryCount=0,this.MAX_ASYNC_RETRIES=3,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:G,this._hasDefaultValue=this._defaultValue!==G,this._onError=t.onError??null,this.MAX_PROMISE_ID=Number.MAX_SAFE_INTEGER-1,this._functionSubscribersStore=new V,this._objectSubscribersStore=new V,this._dependencies=a,this._dependencyVersions=_,this._unsubscribes=p,this._notifyJob=()=>{this._functionSubscribersStore.forEachSafe(s=>s(),s=>console.error(s)),this._objectSubscribersStore.forEachSafe(s=>s.execute(),s=>console.error(s))},this._trackable=Object.assign(()=>this._markDirty(),{addDependency:s=>{}}),d.attachDebugInfo(this,"computed",this.id),d.enabled){const s=this;s.subscriberCount=()=>this._functionSubscribersStore.size+this._objectSubscribersStore.size,s.isDirty=()=>this._isDirty(),s.dependencies=this._dependencies,s.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 oe;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 s=0;s<this._dependencies.length;s++){const n=this._dependencies[s];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!==_&&(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()}A.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==a&&(C.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 w[this.flags&ie]}_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 s=m.run(this._trackable,this._fn);this._commitDependencies(e),t=!0,te(s)?this._handleAsyncComputation(s):this._handleSyncResult(s)}catch(s){if(!t)try{this._commitDependencies(e),t=!0}catch(n){this._handleComputationError(n)}this._handleComputationError(s)}finally{this._cleanupContext(e,t),this._setRecomputing(!1)}}_prepareComputationContext(){const e=this._dependencies,t=this._dependencyVersions,s=C.acquire(),n=b.acquire(),r=J(),o={depCount:0},l=g=>{g._lastSeenEpoch!==r&&(g._lastSeenEpoch=r,o.depCount<s.length?(s[o.depCount]=g,n[o.depCount]=g.version):(s.push(g),n.push(g.version)),o.depCount++)},R=this._trackable.addDependency;return this._trackable.addDependency=l,{prevDeps:e,prevVersions:t,nextDeps:s,nextVersions:n,originalAdd:R,state:o}}_commitDependencies(e){const{nextDeps:t,nextVersions:s,state:n,prevDeps:r}=e;t.length=n.depCount,s.length=n.depCount,this._unsubscribes=Ie(t,r,this._unsubscribes,this),this._dependencies=t,this._dependencyVersions=s}_cleanupContext(e,t){this._trackable.addDependency=e.originalAdd,t?(e.prevDeps!==a&&C.release(e.prevDeps),e.prevVersions!==_&&b.release(e.prevVersions)):(C.release(e.nextDeps),b.release(e.nextVersions))}_getAggregateShift(){let e=0;const t=this._dependencies,s=this._dependencyVersions;for(let n=0;n<t.length;n++){const r=t[n],o=s[n];r&&o!==void 0&&(e=e+r.getShift(o)&y)}return e}isUrgent(){return this._getAggregateShift()>=z}_handleSyncResult(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}_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(s=>{if(t!==this._promiseId)return;const r=this._captureVersionSnapshot()-this._asyncStartAggregateVersion&y;if(z-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(s)}).catch(s=>{t===this._promiseId&&this._handleAsyncRejection(s)})}_captureVersionSnapshot(){let e=0;const t=this._dependencies;for(let s=0;s<t.length;s++){const n=t[s];n&&(e=e+n.version&y)}return e}_handleAsyncResolution(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,this._notifyJob()}_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(s){console.error(c.CALLBACK_ERROR_IN_ERROR_HANDLER,s)}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(){se(this,m.getCurrent(),this._functionSubscribersStore,this._objectSubscribersStore)}}Object.freeze(ne.prototype);function Ae(i,e={}){return new ne(i,e)}class Te extends H{constructor(e,t={}){super(),this.run=()=>{if(this.isDisposed)throw new I(c.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()}A.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==a&&(C.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=m.run(this,this._fn);this._commitEffect(n),r=!0,this._checkLoopWarnings(),te(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._currentEpoch=-1,this._lastFlushEpoch=-1,this._executionsInEpoch=0,this._fn=e,this._sync=t.sync??!1,this._maxExecutions=t.maxExecutionsPerSecond??S.MAX_EXECUTIONS_PER_SECOND,this._maxExecutionsPerFlush=t.maxExecutionsPerFlush??S.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 s=Number.isFinite(this._maxExecutions);this._historyCapacity=s?Math.min(this._maxExecutions+1,S.MAX_EXECUTIONS_PER_SECOND+1):0,this._history=f&&s&&this._historyCapacity>0?new Array(this._historyCapacity).fill(0):null,this._executionCount=0,d.attachDebugInfo(this,"effect",this.id)}_prepareEffectContext(){const e=this._dependencies,t=this._dependencyVersions,s=this._unsubscribes,n=C.acquire(),r=b.acquire(),o=A.acquire(),l=J();if(e!==a&&s!==p)for(let R=0;R<e.length;R++){const g=e[R];g&&(g._tempUnsub=s[R])}return this._nextDeps=n,this._nextVersions=r,this._nextUnsubs=o,this._currentEpoch=l,{prevDeps:e,prevVersions:t,prevUnsubs:s,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 s=0;s<e.prevDeps.length;s++){const n=e.prevDeps[s];n?._tempUnsub&&(n._tempUnsub(),n._tempUnsub=void 0)}C.release(e.prevDeps)}e.prevUnsubs!==p&&A.release(e.prevUnsubs),e.prevVersions!==_&&b.release(e.prevVersions)}else{C.release(e.nextDeps),b.release(e.nextVersions);for(let s=0;s<e.nextUnsubs.length;s++)e.nextUnsubs[s]?.();if(A.release(e.nextUnsubs),e.prevDeps!==a)for(let s=0;s<e.prevDeps.length;s++){const n=e.prevDeps[s];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!==M&&(this._lastFlushEpoch=M,this._executionsInEpoch=0),this._executionsInEpoch++,this._executionsInEpoch>this._maxExecutionsPerFlush&&this._throwInfiniteLoopError("per-effect"),le()>S.MAX_EXECUTIONS_PER_FLUSH&&this._throwInfiniteLoopError("global"),this._executionCount++,this._history&&this._maxExecutions>0){const e=Date.now(),t=this._historyPtr,s=this._historyCapacity;this._history[t]=e;const n=(t+1)%s,r=this._history[n]??0;if(this._historyPtr=n,r>0&&e-r<N.ONE_SECOND_MS){const o=new I(`Effect executed ${s} 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===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{Z(()=>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 s=e[t];s&&s._modifiedAtEpoch===this._currentEpoch&&d.warn(!0,`Effect is reading a dependency (${d.getDebugName(s)||"unknown"}) that it just modified. Infinite loop may occur`)}}}}function Re(i,e={}){if(typeof i!="function")throw new I(c.EFFECT_MUST_BE_FUNCTION);const t=new Te(i,e);return t.execute(),t}u.AsyncState=O,u.AtomError=E,u.ComputedError=D,u.DEBUG_CONFIG=j,u.DEBUG_RUNTIME=d,u.EffectError=I,u.POOL_CONFIG=re,u.SCHEDULER_CONFIG=S,u.SchedulerError=F,u.atom=me,u.batch=de,u.computed=Ae,u.effect=Re,u.isAtom=ee,u.isComputed=pe,u.isEffect=be,u.scheduler=T,u.untracked=Z,Object.defineProperty(u,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,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"})}));
|
|
2
2
|
//# sourceMappingURL=atom-effect.min.js.map
|