@but212/atom-effect 0.5.1 → 0.7.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/dist/atom-effect.min.js +2 -0
- package/dist/atom-effect.min.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.mjs +246 -202
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(c,O){typeof exports=="object"&&typeof module<"u"?O(exports):typeof define=="function"&&define.amd?define(["exports"],O):(c=typeof globalThis<"u"?globalThis:c||self,O(c.AtomEffect={}))})(this,(function(c){"use strict";const O={ONE_SECOND_MS:1e3},U={IDLE:"idle",PENDING:"pending",RESOLVED:"resolved",REJECTED:"rejected"},x={DISPOSED:1,EXECUTING:2},u={DIRTY:1,IDLE:2,PENDING:4,RESOLVED:8,REJECTED:16,RECOMPUTING:32,HAS_ERROR:64},re={MAX_SIZE:1e3,WARMUP_SIZE:100},g={MAX_EXECUTIONS_PER_SECOND:1e3,CLEANUP_THRESHOLD:1e3,MAX_EXECUTIONS_PER_EFFECT:100,MAX_EXECUTIONS_PER_FLUSH:1e4,MAX_FLUSH_ITERATIONS:1e3,MIN_FLUSH_ITERATIONS:10},w={MAX_DEPENDENCIES:1e3,WARN_INFINITE_LOOP:!0},I=1073741823,l=typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production",oe=Object.freeze([]);class d extends Error{constructor(e,t=null,s=!0){super(e),this.name="AtomError",this.cause=t,this.recoverable=s,this.timestamp=new Date}}class m extends d{constructor(e,t=null){super(e,t,!0),this.name="ComputedError"}}class b extends d{constructor(e,t=null){super(e,t,!1),this.name="EffectError"}}class F extends d{constructor(e,t=null){super(e,t,!1),this.name="SchedulerError"}}const h={COMPUTED_MUST_BE_FUNCTION:"Computed function must be a function",COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION:"Subscriber listener must be a function or Subscriber object",COMPUTED_ASYNC_PENDING_NO_DEFAULT:"Async computation is pending. No default value provided",COMPUTED_COMPUTATION_FAILED:"Computed computation failed",COMPUTED_ASYNC_COMPUTATION_FAILED:"Async computed computation failed",COMPUTED_DEPENDENCY_SUBSCRIPTION_FAILED:"Failed to subscribe to dependency",ATOM_SUBSCRIBER_MUST_BE_FUNCTION:"Subscription listener must be a function or Subscriber object",ATOM_SUBSCRIBER_EXECUTION_FAILED:"Error occurred while executing atom subscribers",ATOM_INDIVIDUAL_SUBSCRIBER_FAILED:"Error during individual atom subscriber execution",EFFECT_MUST_BE_FUNCTION:"Effect function must be a function",EFFECT_EXECUTION_FAILED:"Effect execution failed",EFFECT_CLEANUP_FAILED:"Effect cleanup function execution failed",LARGE_DEPENDENCY_GRAPH:i=>`Large dependency graph detected: ${i} dependencies`,UNSUBSCRIBE_NON_EXISTENT:"Attempted to unsubscribe a non-existent listener",CALLBACK_ERROR_IN_ERROR_HANDLER:"Error occurred during onError callback execution"},B=Symbol("debugName"),ce=Symbol("id"),k=Symbol("type"),z=Symbol("noDefaultValue");function ue(i){return"dependencies"in i&&Array.isArray(i.dependencies)}let G=0;function X(i,e,t){if(i._visitedEpoch!==t){if(i._visitedEpoch=t,i===e)throw new m("Indirect circular dependency detected");if(ue(i)){const s=i.dependencies;for(let n=0;n<s.length;n++){const r=s[n];r&&X(r,e,t)}}}}const f={enabled:typeof process<"u"&&process.env?.NODE_ENV==="development",maxDependencies:w.MAX_DEPENDENCIES,warnInfiniteLoop:w.WARN_INFINITE_LOOP,warn(i,e){this.enabled&&i&&console.warn(`[Atom Effect] ${e}`)},checkCircular(i,e){if(i===e)throw new m("Direct circular dependency detected");this.enabled&&(G++,X(i,e,G))},attachDebugInfo(i,e,t){if(!this.enabled)return;const s=i;s[B]=`${e}_${t}`,s[ce]=t,s[k]=e},getDebugName(i){if(i!=null&&B in i)return i[B]},getDebugType(i){if(i!=null&&k in i)return i[k]}};let he=1;const _e=()=>he++;class Y{constructor(){this.id=_e()&I,this.flags=0}}class H extends Y{constructor(){super(),this.version=0,this._lastSeenEpoch=-1}subscribe(e){if(typeof e=="object"&&e!==null&&"execute"in e)return this._objectSubscribers.add(e);if(typeof e!="function")throw new d(h.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 d(h.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,s))),this._objectSubscribers.forEachSafe(s=>s.execute(),s=>console.error(new d(h.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,s)))}}let P=0;function $(){return P=(P+1|0)&I,P}function ae(){return P}let v=0,q=0,L=!1;function J(){return L?(l&&console.warn("Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"),!1):(L=!0,v=v+1&I,q=0,!0)}function Q(){L=!1}function le(){return L?++q:0}class fe{constructor(){this.queueA=[],this.queueB=[],this.queue=this.queueA,this.queueSize=0,this._epoch=0,this.isProcessing=!1,this.isBatching=!1,this.batchDepth=0,this.batchQueue=[],this.batchQueueSize=0,this.isFlushingSync=!1,this.maxFlushIterations=g.MAX_FLUSH_ITERATIONS}get phase(){return this.isProcessing||this.isFlushingSync?2:this.isBatching?1:0}schedule(e){if(typeof e!="function")throw new F("Scheduler callback must be a function");e._nextEpoch!==this._epoch&&(e._nextEpoch=this._epoch,this.isBatching||this.isFlushingSync?this.batchQueue[this.batchQueueSize++]=e:(this.queue[this.queueSize++]=e,this.isProcessing||this.flush()))}flush(){if(this.isProcessing||this.queueSize===0)return;this.isProcessing=!0;const e=this.queue,t=this.queueSize;this.queue=this.queue===this.queueA?this.queueB:this.queueA,this.queueSize=0,this._epoch++,queueMicrotask(()=>{const s=J();this._processJobs(e,t),this.isProcessing=!1,s&&Q(),this.queueSize>0&&!this.isBatching&&this.flush()})}flushSync(){this.isFlushingSync=!0;const e=J();try{this._mergeBatchQueue(),this._drainQueue()}finally{this.isFlushingSync=!1,e&&Q()}}_mergeBatchQueue(){if(this._epoch++,this.batchQueueSize>0){for(let e=0;e<this.batchQueueSize;e++){const t=this.batchQueue[e];t&&t._nextEpoch!==this._epoch&&(t._nextEpoch=this._epoch,this.queue[this.queueSize++]=t)}this.batchQueueSize=0}}_drainQueue(){let e=0;for(;this.queueSize>0;){if(++e>this.maxFlushIterations){this._handleFlushOverflow();break}this._processCurrentQueue(),this._mergeBatchQueue()}}_processCurrentQueue(){const e=this.queue,t=this.queueSize;this.queue=this.queue===this.queueA?this.queueB:this.queueA,this.queueSize=0,this._epoch++,this._processJobs(e,t)}_handleFlushOverflow(){console.error(new F(`Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop.`)),this.queueSize=0,this.queue.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<g.MIN_FLUSH_ITERATIONS)throw new F(`Max flush iterations must be at least ${g.MIN_FLUSH_ITERATIONS}`);this.maxFlushIterations=e}}const N=new fe;function de(i){if(typeof i!="function")throw new d("Batch callback must be a function");N.startBatch();try{return i()}finally{N.endBatch()}}const y={current:null,run(i,e){const t=this.current;this.current=i;try{return e()}finally{this.current=t}},getCurrent(){return this.current}};function W(i){if(typeof i!="function")throw new d("Untracked callback must be a function");const e=y.current;y.current=null;try{return i()}finally{y.current=e}}class M{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]:[]}}function K(i){return i!==null&&typeof i=="object"&&"value"in i&&"subscribe"in i&&typeof i.subscribe=="function"}function Ee(i){if(f.enabled&&(i==null||typeof i=="object")){const e=f.getDebugType(i);if(e)return e==="computed"}return K(i)&&"invalidate"in i&&typeof i.invalidate=="function"}function pe(i){return i!==null&&typeof i=="object"&&"dispose"in i&&"run"in i&&typeof i.dispose=="function"&&typeof i.run=="function"}function Z(i){return i!=null&&typeof i.then=="function"}function be(i){return typeof i=="object"&&i!==null}function ee(i){return(typeof i=="object"||typeof i=="function")&&i!==null&&typeof i.addDependency=="function"}function te(i){return typeof i=="function"&&typeof i.addDependency!="function"}function se(i){return be(i)&&typeof i.execute=="function"}class Se extends H{constructor(e,t){super(),this._isNotificationScheduled=!1,this._value=e,this._functionSubscribersStore=new M,this._objectSubscribersStore=new M,this._sync=t,this._notifyTask=this._flushNotifications.bind(this),f.attachDebugInfo(this,"atom",this.id)}get _functionSubscribers(){return this._functionSubscribersStore}get _objectSubscribers(){return this._objectSubscribersStore}get value(){const e=y.getCurrent();return e&&this._track(e),this._value}set value(e){if(Object.is(this._value,e))return;const t=this._value;this.version=this.version+1&I,this._value=e,!(!this._functionSubscribersStore.hasSubscribers&&!this._objectSubscribersStore.hasSubscribers)&&this._scheduleNotification(t)}_track(e){if(ee(e)){e.addDependency(this);return}if(te(e)){this._functionSubscribersStore.add(e);return}se(e)&&this._objectSubscribersStore.add(e)}_scheduleNotification(e){this._isNotificationScheduled||(this._pendingOldValue=e,this._isNotificationScheduled=!0),this._sync&&!N.isBatching?this._flushNotifications():N.schedule(this._notifyTask)}_flushNotifications(){if(!this._isNotificationScheduled)return;const e=this._pendingOldValue,t=this._value;this._pendingOldValue=void 0,this._isNotificationScheduled=!1,this._notifySubscribers(t,e)}peek(){return this._value}dispose(){this._functionSubscribersStore.clear(),this._objectSubscribersStore.clear(),this._value=void 0}}function ge(i,e={}){return new Se(i,e.sync??!1)}class j{constructor(){this.pool=[],this.maxPoolSize=50,this.maxReusableCapacity=256,this.stats=l?{acquired:0,released:0,rejected:{frozen:0,tooLarge:0,poolFull:0}}:null}acquire(){return l&&this.stats&&this.stats.acquired++,this.pool.pop()??[]}release(e,t){if(!(t&&e===t)){if(Object.isFrozen(e)){l&&this.stats&&this.stats.rejected.frozen++;return}if(e.length>this.maxReusableCapacity){l&&this.stats&&this.stats.rejected.tooLarge++;return}if(this.pool.length>=this.maxPoolSize){l&&this.stats&&this.stats.rejected.poolFull++;return}e.length=0,this.pool.push(e),l&&this.stats&&this.stats.released++}}getStats(){if(!l||!this.stats)return null;const{acquired:e,released:t,rejected: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,l&&this.stats&&(this.stats.acquired=0,this.stats.released=0,this.stats.rejected={frozen:0,tooLarge:0,poolFull:0})}}const _=Object.freeze([]),E=Object.freeze([]),a=Object.freeze([]),D=new j,C=new j,p=new j;function De(i,e,t,s){if(e!==_&&t!==E)for(let r=0;r<e.length;r++){const o=e[r];o&&(o._tempUnsub=t[r])}const n=C.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):(f.checkCircular(o,s),n[r]=o.subscribe(s)))}if(e!==_)for(let r=0;r<e.length;r++){const o=e[r];o?._tempUnsub&&(o._tempUnsub(),o._tempUnsub=void 0)}return t!==E&&C.release(t),n}function R(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 d)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=u.RESOLVED|u.PENDING|u.REJECTED,V=Array(ie+1).fill(U.IDLE);V[u.RESOLVED]=U.RESOLVED,V[u.PENDING]=U.PENDING,V[u.REJECTED]=U.REJECTED;class ne extends H{constructor(e,t={}){if(typeof e!="function")throw new m(h.COMPUTED_MUST_BE_FUNCTION);if(super(),this._cachedErrors=null,this._errorCacheEpoch=-1,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:z,this._hasDefaultValue=this._defaultValue!==z,this._onError=t.onError??null,this.MAX_PROMISE_ID=Number.MAX_SAFE_INTEGER-1,this._functionSubscribersStore=new M,this._objectSubscribersStore=new M,this._dependencies=_,this._dependencyVersions=a,this._unsubscribes=E,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=>{}}),f.attachDebugInfo(this,"computed",this.id),f.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=ae();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 T=r[o];T&&t.add(T)}}}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&&(p.release(this._dependencyVersions),this._dependencyVersions=a),this._errorCacheEpoch=-1,this._cachedErrors=null}dispose(){if(this._unsubscribes!==E){for(let e=0;e<this._unsubscribes.length;e++){const t=this._unsubscribes[e];t&&t()}C.release(this._unsubscribes),this._unsubscribes=E}this._dependencies!==_&&(D.release(this._dependencies),this._dependencies=_),this._dependencyVersions!==a&&(p.release(this._dependencyVersions),this._dependencyVersions=a),this._functionSubscribersStore.clear(),this._objectSubscribersStore.clear(),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&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=y.run(this._trackable,this._fn);this._commitDependencies(e),t=!0,Z(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=D.acquire(),n=p.acquire(),r=$(),o={depCount:0},T=S=>{S._lastSeenEpoch!==r&&(S._lastSeenEpoch=r,o.depCount<s.length?(s[o.depCount]=S,n[o.depCount]=S.version):(s.push(S),n.push(S.version)),o.depCount++)},A=this._trackable.addDependency;return this._trackable.addDependency=T,{prevDeps:e,prevVersions:t,nextDeps:s,nextVersions:n,originalAdd:A,state:o}}_commitDependencies(e){const{nextDeps:t,nextVersions:s,state:n,prevDeps:r}=e;t.length=n.depCount,s.length=n.depCount,this._unsubscribes=De(t,r,this._unsubscribes,this),this._dependencies=t,this._dependencyVersions=s}_cleanupContext(e,t){this._trackable.addDependency=e.originalAdd,t?(e.prevDeps!==_&&D.release(e.prevDeps),e.prevVersions!==a&&p.release(e.prevVersions)):(D.release(e.nextDeps),p.release(e.nextVersions))}_handleSyncResult(e){const t=!this._isResolved()||!this._equal(this._value,e);this.version=this.version+Number(t)&I,this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),this._cachedErrors=null,this._errorCacheEpoch=-1}_handleAsyncComputation(e){this._setPending(),this._clearDirty(),this._notifyJob(),this._promiseId=this._promiseId>=this.MAX_PROMISE_ID?1:this._promiseId+1;const t=this._promiseId;e.then(s=>{t===this._promiseId&&this._handleAsyncResolution(s)}).catch(s=>{t===this._promiseId&&this._handleAsyncRejection(s)})}_handleAsyncResolution(e){const t=!this._isResolved()||!this._equal(this._value,e);this.version=this.version+Number(t)&I,this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),this._cachedErrors=null,this._errorCacheEpoch=-1,this._notifyJob()}_handleAsyncRejection(e){const t=R(e,m,h.COMPUTED_ASYNC_COMPUTATION_FAILED),s=!this._isRejected();if(this.version=this.version+Number(s)&I,this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(n){console.error(h.CALLBACK_ERROR_IN_ERROR_HANDLER,n)}this._notifyJob()}_handleComputationError(e){const t=R(e,m,h.COMPUTED_COMPUTATION_FAILED);if(this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(s){console.error(h.CALLBACK_ERROR_IN_ERROR_HANDLER,s)}throw t}_handlePending(){if(this._hasDefaultValue)return this._defaultValue;throw new m(h.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(){const e=y.getCurrent();if(e){if(ee(e)){e.addDependency(this);return}if(te(e)){this._functionSubscribersStore.add(e);return}se(e)&&this._objectSubscribersStore.add(e)}}}Object.freeze(ne.prototype);function Ie(i,e={}){return new ne(i,e)}class me extends Y{constructor(e,t={}){super(),this.run=()=>{if(this.isDisposed)throw new b(h.EFFECT_MUST_BE_FUNCTION);this._dependencyVersions!==a&&(p.release(this._dependencyVersions),this._dependencyVersions=a),this.execute()},this.dispose=()=>{if(!this.isDisposed){if(this._setDisposed(),this._safeCleanup(),this._unsubscribes!==E){for(let s=0;s<this._unsubscribes.length;s++){const n=this._unsubscribes[s];n&&n()}C.release(this._unsubscribes),this._unsubscribes=E}this._dependencies!==_&&(D.release(this._dependencies),this._dependencies=_),this._dependencyVersions!==a&&(p.release(this._dependencyVersions),this._dependencyVersions=a)}},this.addDependency=s=>{if(this.isExecuting&&this._nextDeps&&this._nextUnsubs&&this._nextVersions){const n=this._currentEpoch;if(s._lastSeenEpoch===n)return;s._lastSeenEpoch=n,this._nextDeps.push(s),this._nextVersions.push(s.version),s._tempUnsub?(this._nextUnsubs.push(s._tempUnsub),s._tempUnsub=void 0):this._subscribeTo(s)}},this.execute=()=>{if(this.isDisposed||this.isExecuting||!this._shouldExecute())return;this._checkInfiniteLoop(),this._setExecuting(!0),this._safeCleanup();const s=this._prepareEffectContext();let n=!1;try{const r=y.run(this,this._fn);this._commitEffect(s),n=!0,this._checkLoopWarnings(),Z(r)?r.then(o=>{!this.isDisposed&&typeof o=="function"&&(this._cleanup=o)}).catch(o=>{console.error(R(o,b,h.EFFECT_EXECUTION_FAILED))}):this._cleanup=typeof r=="function"?r:null}catch(r){n=!0,console.error(R(r,b,h.EFFECT_EXECUTION_FAILED)),this._cleanup=null}finally{this._cleanupEffect(s,n),this._setExecuting(!1)}},this._currentEpoch=-1,this._lastFlushEpoch=-1,this._executionsInEpoch=0,this._fn=e,this._sync=t.sync??!1,this._maxExecutions=t.maxExecutionsPerSecond??g.MAX_EXECUTIONS_PER_SECOND,this._maxExecutionsPerFlush=t.maxExecutionsPerFlush??g.MAX_EXECUTIONS_PER_EFFECT,this._trackModifications=t.trackModifications??!1,this._cleanup=null,this._dependencies=_,this._dependencyVersions=a,this._unsubscribes=E,this._nextDeps=null,this._nextVersions=null,this._nextUnsubs=null,this._history=l?[]:null,this._executionCount=0,f.attachDebugInfo(this,"effect",this.id)}_prepareEffectContext(){const e=this._dependencies,t=this._dependencyVersions,s=this._unsubscribes,n=D.acquire(),r=p.acquire(),o=C.acquire(),T=$();if(e!==_&&s!==E)for(let A=0;A<e.length;A++){const S=e[A];S&&(S._tempUnsub=s[A])}return this._nextDeps=n,this._nextVersions=r,this._nextUnsubs=o,this._currentEpoch=T,{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!==_){for(let s=0;s<e.prevDeps.length;s++){const n=e.prevDeps[s];n?._tempUnsub&&(n._tempUnsub(),n._tempUnsub=void 0)}D.release(e.prevDeps)}e.prevUnsubs!==E&&C.release(e.prevUnsubs),e.prevVersions!==a&&p.release(e.prevVersions)}else{D.release(e.nextDeps),p.release(e.nextVersions);for(let s=0;s<e.nextUnsubs.length;s++)e.nextUnsubs[s]?.();if(C.release(e.nextUnsubs),e.prevDeps!==_)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():N.schedule(this.execute)});this._nextUnsubs&&this._nextUnsubs.push(t)}catch(t){console.error(R(t,b,h.EFFECT_EXECUTION_FAILED)),this._nextUnsubs&&this._nextUnsubs.push(()=>{})}}get isDisposed(){return(this.flags&x.DISPOSED)!==0}get executionCount(){return this._executionCount}get isExecuting(){return(this.flags&x.EXECUTING)!==0}_setDisposed(){this.flags|=x.DISPOSED}_setExecuting(e){const t=x.EXECUTING;this.flags=this.flags&~t|-Number(e)&t}_safeCleanup(){if(this._cleanup){try{this._cleanup()}catch(e){console.error(R(e,b,h.EFFECT_CLEANUP_FAILED))}this._cleanup=null}}_checkInfiniteLoop(){if(this._lastFlushEpoch!==v&&(this._lastFlushEpoch=v,this._executionsInEpoch=0),this._executionsInEpoch++,this._executionsInEpoch>this._maxExecutionsPerFlush&&this._throwInfiniteLoopError("per-effect"),le()>g.MAX_EXECUTIONS_PER_FLUSH&&this._throwInfiniteLoopError("global"),this._executionCount++,this._history){const e=Date.now();this._history.push(e),this._history.length>g.MAX_EXECUTIONS_PER_SECOND+10&&this._history.shift(),this._checkTimestampLoop(e)}}_checkTimestampLoop(e){const t=this._history;if(!t||this._maxExecutions<=0)return;const s=e-O.ONE_SECOND_MS;let n=0;for(let r=t.length-1;r>=0&&!(t[r]<s);r--)n++;if(n>this._maxExecutions){const r=new b(`Effect executed ${n} times within 1 second. Infinite loop suspected`);if(this.dispose(),console.error(r),l)throw r}}_throwInfiniteLoopError(e){const t=new b(`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{W(()=>t.value)}catch{return!0}if(t.version!==this._dependencyVersions[e])return!0}}return!1}_checkLoopWarnings(){if(this._trackModifications&&f.enabled){const e=this._dependencies;for(let t=0;t<e.length;t++){const s=e[t];s&&s._modifiedAtEpoch===this._currentEpoch&&f.warn(!0,`Effect is reading a dependency (${f.getDebugName(s)||"unknown"}) that it just modified. Infinite loop may occur`)}}}}function ye(i,e={}){if(typeof i!="function")throw new b(h.EFFECT_MUST_BE_FUNCTION);const t=new me(i,e);return t.execute(),t}c.AsyncState=U,c.AtomError=d,c.ComputedError=m,c.DEBUG_CONFIG=w,c.DEBUG_RUNTIME=f,c.EffectError=b,c.POOL_CONFIG=re,c.SCHEDULER_CONFIG=g,c.SchedulerError=F,c.atom=ge,c.batch=de,c.computed=Ie,c.effect=ye,c.isAtom=K,c.isComputed=Ee,c.isEffect=pe,c.scheduler=N,c.untracked=W,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})}));
|
|
2
|
+
//# sourceMappingURL=atom-effect.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atom-effect.min.js","sources":["../src/constants.ts","../src/errors/errors.ts","../src/errors/messages.ts","../src/utils/debug.ts","../src/core/base/reactive-node.ts","../src/core/base/reactive-dependency.ts","../src/internal/epoch.ts","../src/internal/scheduler/scheduler.ts","../src/internal/scheduler/batch.ts","../src/tracking/context.ts","../src/tracking/untracked.ts","../src/utils/subscriber-manager.ts","../src/utils/type-guards.ts","../src/core/atom/atom.ts","../src/utils/array-pool.ts","../src/internal/pool.ts","../src/core/utils/dep-tracking.ts","../src/utils/error.ts","../src/core/computed/index.ts","../src/core/effect/effect.ts"],"sourcesContent":["/**\n * Time-related constants (in milliseconds)\n */\nexport const TIME_CONSTANTS = {\n /** One second in milliseconds */\n ONE_SECOND_MS: 1000,\n} as const;\n\n/**\n * Async computation states for computed atoms\n */\nexport const AsyncState = {\n IDLE: 'idle' as const,\n PENDING: 'pending' as const,\n RESOLVED: 'resolved' as const,\n REJECTED: 'rejected' as const,\n} as const;\n\n/**\n * Bit flags for effect state management\n * Using bit flags for efficient state checks (O(1) operations)\n */\nexport const EFFECT_STATE_FLAGS = {\n DISPOSED: 1 << 0, // 0001 - Effect has been disposed\n EXECUTING: 1 << 1, // 0010 - Effect is currently executing\n} as const;\n\n/**\n * Bit flags for computed atom state management\n * Enables fast state transitions and checks without multiple boolean fields\n */\nexport const COMPUTED_STATE_FLAGS = {\n DIRTY: 1 << 0, // 0001 - Needs recomputation\n IDLE: 1 << 1, // 0010 - Initial state, not computed yet\n PENDING: 1 << 2, // 0100 - Async computation in progress\n RESOLVED: 1 << 3, // 1000 - Successfully computed\n REJECTED: 1 << 4, // 10000 - Computation failed\n RECOMPUTING: 1 << 5, // 100000 - Currently recomputing\n HAS_ERROR: 1 << 6, // 1000000 - Has error state\n} as const;\n\n/**\n * Object pool configuration\n * Controls memory management and GC pressure reduction\n */\nexport const POOL_CONFIG = {\n /** Maximum number of pooled objects to prevent memory bloat */\n MAX_SIZE: 1000,\n /** Number of objects to pre-allocate for performance-critical paths */\n WARMUP_SIZE: 100,\n} as const;\n\n/**\n * Scheduler configuration\n * Controls batching behavior and performance limits\n */\nexport const SCHEDULER_CONFIG = {\n /** Maximum effect executions per second to detect infinite loops (Legacy/Fallback) */\n MAX_EXECUTIONS_PER_SECOND: 1000,\n /** Threshold for cleaning up old execution timestamps */\n CLEANUP_THRESHOLD: 1000,\n\n /**\n * Maximum executions per effect within a single flush cycle\n * Increased from 50 to 100\n */\n MAX_EXECUTIONS_PER_EFFECT: 100,\n\n /**\n * Maximum total executions across all effects in a single flush cycle\n * Increased from 5000 to 10000\n */\n MAX_EXECUTIONS_PER_FLUSH: 10000,\n\n /** Maximum iterations for synchronous flush loop to prevent infinite loops */\n MAX_FLUSH_ITERATIONS: 1000,\n\n /** Minimum allowed value for max flush iterations */\n MIN_FLUSH_ITERATIONS: 10,\n} as const;\n\n/**\n * Debug configuration defaults\n */\nexport const DEBUG_CONFIG = {\n /** Maximum dependencies before warning about large dependency graphs */\n MAX_DEPENDENCIES: 1000,\n /** Enable infinite loop detection warnings */\n WARN_INFINITE_LOOP: true,\n} as const;\n\n/**\n * Maximum Small Integer (Smi) value in V8 (31-bit signed integer)\n * Used for IDs and Versions to prevent HeapNumber allocation\n */\nexport const SMI_MAX = 0x3fffffff;\n\n/**\n * Environment detection\n */\nexport const IS_DEV =\n typeof process !== 'undefined' && process.env && process.env.NODE_ENV !== 'production';\n\n/**\n * Empty frozen error array constant to avoid allocations\n * Used for computed atoms with no errors (the common case)\n */\nexport const EMPTY_ERROR_ARRAY: readonly Error[] = Object.freeze([]);\n","/**\n * Base error class for all atom-effect errors\n *\n * Provides enhanced error information including:\n * - Original cause tracking for error chains\n * - Recoverability flag for error handling strategies\n * - Timestamp for debugging and logging\n *\n * @example\n * ```ts\n * throw new AtomError('Invalid state', originalError, false);\n * ```\n */\nexport class AtomError extends Error {\n /** Original error that caused this error, if any */\n cause: Error | null;\n /** Whether this error can be recovered from */\n recoverable: boolean;\n /** When this error occurred */\n timestamp: Date;\n\n /**\n * Creates a new AtomError\n * @param message - Error message describing what went wrong\n * @param cause - Original error that caused this error\n * @param recoverable - Whether the operation can be retried\n */\n constructor(message: string, cause: Error | null = null, recoverable: boolean = true) {\n super(message);\n this.name = 'AtomError';\n this.cause = cause;\n this.recoverable = recoverable;\n this.timestamp = new Date();\n }\n}\n\n/**\n * Error thrown during computed value computation\n *\n * Computed errors are considered recoverable by default since they typically\n * result from transient data issues rather than programming errors.\n */\nexport class ComputedError extends AtomError {\n /**\n * Creates a new ComputedError\n * @param message - Error message\n * @param cause - Original error\n */\n constructor(message: string, cause: Error | null = null) {\n super(message, cause, true);\n this.name = 'ComputedError';\n }\n}\n\n/**\n * Error thrown during effect execution\n *\n * Effect errors are considered non-recoverable by default since effects\n * typically represent critical side effects that shouldn't fail silently.\n */\nexport class EffectError extends AtomError {\n /**\n * Creates a new EffectError\n * @param message - Error message\n * @param cause - Original error\n */\n constructor(message: string, cause: Error | null = null) {\n super(message, cause, false);\n this.name = 'EffectError';\n }\n}\n\n/**\n * Error thrown by the scheduler system\n *\n * Scheduler errors indicate fundamental issues with the batching/scheduling\n * mechanism and are considered non-recoverable.\n */\nexport class SchedulerError extends AtomError {\n /**\n * Creates a new SchedulerError\n * @param message - Error message\n * @param cause - Original error\n */\n constructor(message: string, cause: Error | null = null) {\n super(message, cause, false);\n this.name = 'SchedulerError';\n }\n}\n","/**\n * Centralized error message constants for the atom-effect library.\n *\n * @description\n * Provides consistent, maintainable error messages across the library.\n * All messages are in English for international accessibility.\n *\n * @remarks\n * - Computed errors: Related to computed atom creation and execution\n * - Atom errors: Related to atom subscription and notification\n * - Effect errors: Related to effect lifecycle and cleanup\n * - Debug warnings: Non-critical warnings for debugging\n *\n * @example\n * ```ts\n * import { ERROR_MESSAGES } from './messages';\n *\n * if (typeof fn !== 'function') {\n * throw new Error(ERROR_MESSAGES.COMPUTED_MUST_BE_FUNCTION);\n * }\n * ```\n */\nexport const ERROR_MESSAGES = {\n // ─────────────────────────────────────────────────────────────────\n // Computed errors\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Error thrown when computed() receives a non-function argument.\n */\n COMPUTED_MUST_BE_FUNCTION: 'Computed function must be a function',\n\n /**\n * Error thrown when subscribe() receives an invalid listener.\n */\n COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION:\n 'Subscriber listener must be a function or Subscriber object',\n\n /**\n * Error thrown when accessing a pending async computed without a default value.\n */\n COMPUTED_ASYNC_PENDING_NO_DEFAULT: 'Async computation is pending. No default value provided',\n\n /**\n * Error thrown when a synchronous computed computation fails.\n */\n COMPUTED_COMPUTATION_FAILED: 'Computed computation failed',\n\n /**\n * Error thrown when an asynchronous computed computation fails.\n */\n COMPUTED_ASYNC_COMPUTATION_FAILED: 'Async computed computation failed',\n\n /**\n * Error thrown when subscribing to a dependency fails.\n */\n COMPUTED_DEPENDENCY_SUBSCRIPTION_FAILED: 'Failed to subscribe to dependency',\n\n // ─────────────────────────────────────────────────────────────────\n // Atom errors\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Error thrown when atom.subscribe() receives an invalid listener.\n */\n ATOM_SUBSCRIBER_MUST_BE_FUNCTION: 'Subscription listener must be a function or Subscriber object',\n\n /**\n * Error thrown when the atom subscriber notification process fails.\n */\n ATOM_SUBSCRIBER_EXECUTION_FAILED: 'Error occurred while executing atom subscribers',\n\n /**\n * Error logged when an individual subscriber throws during notification.\n * @remarks This error is caught and logged to prevent cascading failures.\n */\n ATOM_INDIVIDUAL_SUBSCRIBER_FAILED: 'Error during individual atom subscriber execution',\n\n // ─────────────────────────────────────────────────────────────────\n // Effect errors\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Error thrown when effect() receives a non-function argument.\n */\n EFFECT_MUST_BE_FUNCTION: 'Effect function must be a function',\n\n /**\n * Error thrown when an effect's execution fails.\n */\n EFFECT_EXECUTION_FAILED: 'Effect execution failed',\n\n /**\n * Error thrown when an effect's cleanup function fails.\n */\n EFFECT_CLEANUP_FAILED: 'Effect cleanup function execution failed',\n\n // ─────────────────────────────────────────────────────────────────\n // Debug warnings\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Warning message for large dependency graphs.\n *\n * @param count - The number of dependencies detected\n * @returns Formatted warning message with dependency count\n *\n * @example\n * ```ts\n * console.warn(ERROR_MESSAGES.LARGE_DEPENDENCY_GRAPH(150));\n * // Output: \"Large dependency graph detected: 150 dependencies\"\n * ```\n */\n LARGE_DEPENDENCY_GRAPH: (count: number): string =>\n `Large dependency graph detected: ${count} dependencies`,\n\n /**\n * Warning logged when attempting to unsubscribe a non-existent listener.\n */\n UNSUBSCRIBE_NON_EXISTENT: 'Attempted to unsubscribe a non-existent listener',\n\n /**\n * Error logged when the onError callback itself throws an error.\n * @remarks This prevents cascading failures from masking the original error.\n */\n CALLBACK_ERROR_IN_ERROR_HANDLER: 'Error occurred during onError callback execution',\n} as const;\n","import { DEBUG_CONFIG } from '@/constants';\nimport { ComputedError } from '@/errors/errors';\nimport type { DebugConfig, Dependency, DependencyId } from '@/types';\n\n/** Symbol for debug display name on reactive objects */\nexport const DEBUG_NAME: unique symbol = Symbol('debugName');\n\n/** Symbol for unique identifier on reactive objects */\nexport const DEBUG_ID: unique symbol = Symbol('id');\n\n/** Symbol for type discriminator ('atom' | 'computed' | 'effect') */\nexport const DEBUG_TYPE: unique symbol = Symbol('type');\n\n/** Sentinel to distinguish \"no default\" from explicit `undefined` */\nexport const NO_DEFAULT_VALUE: unique symbol = Symbol('noDefaultValue');\n\n/** Type guard for objects with dependencies array */\nfunction hasDependencies(obj: Dependency): obj is Dependency & { dependencies: Dependency[] } {\n return 'dependencies' in obj && Array.isArray((obj as { dependencies: unknown }).dependencies);\n}\n\nlet globalCheckEpoch = 0;\n\n/** Internal recursive checker for circular dependency detection */\nfunction checkCircularInternal(dep: Dependency, current: object, epoch: number): void {\n if (dep._visitedEpoch === epoch) {\n return;\n }\n dep._visitedEpoch = epoch;\n\n if (dep === current) {\n throw new ComputedError('Indirect circular dependency detected');\n }\n\n if (hasDependencies(dep)) {\n const deps = dep.dependencies;\n for (let i = 0; i < deps.length; i++) {\n const child = deps[i];\n if (child) checkCircularInternal(child, current, epoch);\n }\n }\n}\n\n/**\n * Debug utilities for development-time dependency tracking and circular detection.\n * Most features only active when `NODE_ENV === 'development'`.\n */\nexport const debug: DebugConfig = {\n enabled:\n typeof process !== 'undefined' && (process as NodeJS.Process).env?.NODE_ENV === 'development',\n\n maxDependencies: DEBUG_CONFIG.MAX_DEPENDENCIES,\n\n warnInfiniteLoop: DEBUG_CONFIG.WARN_INFINITE_LOOP,\n\n warn(condition: boolean, message: string): void {\n if (this.enabled && condition) {\n console.warn(`[Atom Effect] ${message}`);\n }\n },\n\n /**\n * Checks for circular dependencies.\n * Direct check runs always; indirect check only in dev mode.\n * @throws {ComputedError} When circular dependency detected\n */\n checkCircular(dep: Dependency, current: object): void {\n if (dep === current) {\n throw new ComputedError('Direct circular dependency detected');\n }\n\n if (!this.enabled) {\n return;\n }\n\n globalCheckEpoch++;\n checkCircularInternal(dep, current, globalCheckEpoch);\n },\n\n attachDebugInfo(obj: object, type: string, id: DependencyId): void {\n if (!this.enabled) {\n return;\n }\n\n const target = obj as Record<symbol, unknown>;\n target[DEBUG_NAME] = `${type}_${id}`;\n target[DEBUG_ID] = id;\n target[DEBUG_TYPE] = type;\n },\n\n getDebugName(obj: object | null | undefined): string | undefined {\n if (obj != null && DEBUG_NAME in obj) {\n return (obj as Record<symbol, unknown>)[DEBUG_NAME] as string | undefined;\n }\n return undefined;\n },\n\n getDebugType(obj: object | null | undefined): string | undefined {\n if (obj != null && DEBUG_TYPE in obj) {\n return (obj as Record<symbol, unknown>)[DEBUG_TYPE] as string | undefined;\n }\n return undefined;\n },\n};\n\nlet nextId = 1;\n\n/** Generates a unique numeric ID for reactive objects */\nexport const generateId = (): DependencyId => nextId++ as DependencyId;\n","import { SMI_MAX } from '@/constants';\nimport type { DependencyId } from '@/types';\nimport { generateId } from '@/utils/debug';\n\n/**\n * Base class for all reactive nodes (Atoms, Computed, Effects).\n *\n * Optimized for V8 hidden classes:\n * - Initializes Smi (Small Integer) fields first.\n * - Provides common identity and flag management.\n */\nexport class ReactiveNode {\n /** Unique numerical identifier (Smi) */\n readonly id: DependencyId;\n\n /** Internal flags (Smi) for state management (Disposed, Dirty, etc.) */\n flags: number;\n\n constructor() {\n this.id = (generateId() & SMI_MAX) as DependencyId;\n this.flags = 0;\n }\n}\n","import { AtomError } from '@/errors/errors';\nimport { ERROR_MESSAGES } from '@/errors/messages';\nimport type { Subscriber } from '@/types';\nimport type { SubscriberManager } from '@/utils/subscriber-manager';\nimport { ReactiveNode } from './reactive-node';\n\n/**\n * Abstract base class for reactive nodes that can be dependencies (Atom, Computed).\n *\n * Extends ReactiveNode with versioning and subscriber management.\n *\n * Performance Note:\n * Abstract accessors are used for subscriber managers to allow subclasses\n * to define the actual storage fields *after* their own Smi fields.\n * This ensures all Smi fields (from Base, Dependency, and Subclass) are\n * packed together at the start of the object for V8 optimization.\n */\nexport abstract class ReactiveDependency<T> extends ReactiveNode {\n /** Version counter for change detection (Smi) */\n version: number;\n\n /** Last seen epoch for dependency collection (Smi) */\n _lastSeenEpoch: number;\n\n constructor() {\n super();\n this.version = 0;\n this._lastSeenEpoch = -1;\n }\n\n protected abstract get _functionSubscribers(): SubscriberManager<\n (newValue?: T, oldValue?: T) => void\n >;\n protected abstract get _objectSubscribers(): SubscriberManager<Subscriber>;\n\n /**\n * Subscribes a listener function or Subscriber object to value changes.\n *\n * @param listener - Function or Subscriber object to call when the value changes\n * @returns An unsubscribe function\n * @throws {AtomError} If listener is not a function or Subscriber\n */\n subscribe(listener: ((newValue?: T, oldValue?: T) => void) | Subscriber): () => void {\n // Support Subscriber object for zero-allocation pattern\n if (typeof listener === 'object' && listener !== null && 'execute' in listener) {\n return this._objectSubscribers.add(listener);\n }\n\n if (typeof listener !== 'function') {\n throw new AtomError(ERROR_MESSAGES.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);\n }\n return this._functionSubscribers.add(listener);\n }\n\n /**\n * Gets the total number of active subscribers.\n */\n subscriberCount(): number {\n return this._functionSubscribers.size + this._objectSubscribers.size;\n }\n\n /**\n * Notifies all subscribers of a change.\n *\n * @param newValue - The new value\n * @param oldValue - The old value\n */\n protected _notifySubscribers(newValue: T | undefined, oldValue: T | undefined): void {\n this._functionSubscribers.forEachSafe(\n (sub) => sub(newValue, oldValue),\n (err) =>\n console.error(new AtomError(ERROR_MESSAGES.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, err as Error))\n );\n\n this._objectSubscribers.forEachSafe(\n (sub) => sub.execute(),\n (err) =>\n console.error(new AtomError(ERROR_MESSAGES.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED, err as Error))\n );\n }\n}\n","import { IS_DEV, SMI_MAX } from '@/constants';\n\nlet collectorEpoch = 0;\n\n/**\n * Increments and returns the next tracking epoch.\n * Used for O(1) dependency management and freshness checks.\n */\nexport function nextEpoch(): number {\n collectorEpoch = ((collectorEpoch + 1) | 0) & SMI_MAX;\n return collectorEpoch;\n}\n\n/** Returns the current tracking epoch. */\nexport function currentEpoch(): number {\n return collectorEpoch;\n}\n\n// === Infinite Loop Detection State ===\n\nexport let flushEpoch = 0;\nexport let flushExecutionCount = 0;\nlet isFlushing = false;\n\n/**\n * Starts a new scheduler flush cycle.\n * Increments the flush epoch and resets execution counts for loop detection.\n * @returns true if a new flush cycle was started, false if already flushing.\n */\nexport function startFlush(): boolean {\n if (isFlushing) {\n if (IS_DEV) {\n console.warn(\n 'Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass'\n );\n }\n return false;\n }\n\n isFlushing = true;\n flushEpoch = (flushEpoch + 1) & SMI_MAX;\n flushExecutionCount = 0;\n return true;\n}\n\n/** Ends the current scheduler flush cycle. */\nexport function endFlush(): void {\n isFlushing = false;\n}\n\n/**\n * Increments the global execution count for the current flush cycle.\n * Used to detect global infinite loops.\n * @returns The new execution count.\n */\nexport function incrementFlushExecutionCount(): number {\n if (!isFlushing) return 0;\n return ++flushExecutionCount;\n}\n\n/** Resets all flush-related state. */\nexport function resetFlushState(): void {\n flushEpoch = 0;\n flushExecutionCount = 0;\n isFlushing = false;\n}\n","import { SCHEDULER_CONFIG } from '@/constants';\nimport { SchedulerError } from '../../errors/errors';\nimport { endFlush, startFlush } from '../epoch';\n\nexport enum SchedulerPhase {\n IDLE = 0,\n BATCHING = 1,\n FLUSHING = 2,\n}\n\nexport interface SchedulerJob {\n (): void;\n _nextEpoch?: number;\n}\n\n/**\n * Scheduler for reactive updates.\n * Manages the execution of effects and computed updates using batching and double-buffering.\n * Supports both asynchronous (microtask-based) and synchronous (manual or batch-end) flushing.\n */\nclass Scheduler {\n private queueA: SchedulerJob[] = [];\n private queueB: SchedulerJob[] = [];\n private queue: SchedulerJob[] = this.queueA;\n private queueSize = 0;\n private _epoch = 0;\n private isProcessing: boolean = false;\n public isBatching: boolean = false;\n private batchDepth: number = 0;\n private batchQueue: SchedulerJob[] = [];\n private batchQueueSize = 0;\n private isFlushingSync: boolean = false;\n private maxFlushIterations: number = SCHEDULER_CONFIG.MAX_FLUSH_ITERATIONS;\n\n get phase(): SchedulerPhase {\n if (this.isProcessing || this.isFlushingSync) {\n return SchedulerPhase.FLUSHING;\n }\n if (this.isBatching) {\n return SchedulerPhase.BATCHING;\n }\n return SchedulerPhase.IDLE;\n }\n\n /**\n * Schedules a task for execution.\n * Tasks are deduplicated within the same flush cycle using epoch tracking.\n * @param callback - The function to execute.\n * @throws {SchedulerError} If the callback is not a function.\n */\n schedule(callback: SchedulerJob): void {\n if (typeof callback !== 'function') {\n throw new SchedulerError('Scheduler callback must be a function');\n }\n\n // O(1) dedup via epoch\n if (callback._nextEpoch === this._epoch) return;\n callback._nextEpoch = this._epoch;\n\n if (this.isBatching || this.isFlushingSync) {\n this.batchQueue[this.batchQueueSize++] = callback;\n } else {\n this.queue[this.queueSize++] = callback;\n if (!this.isProcessing) {\n this.flush();\n }\n }\n }\n\n private flush(): void {\n if (this.isProcessing || this.queueSize === 0) return;\n\n this.isProcessing = true;\n\n // Swap queues\n const jobs = this.queue;\n const count = this.queueSize;\n\n this.queue = this.queue === this.queueA ? this.queueB : this.queueA;\n this.queueSize = 0;\n this._epoch++;\n\n queueMicrotask(() => {\n const flushStarted = startFlush();\n\n this._processJobs(jobs, count);\n\n this.isProcessing = false;\n\n if (flushStarted) endFlush();\n\n if (this.queueSize > 0 && !this.isBatching) {\n this.flush();\n }\n });\n }\n\n private flushSync(): void {\n this.isFlushingSync = true;\n const flushStarted = startFlush();\n\n try {\n this._mergeBatchQueue();\n this._drainQueue();\n } finally {\n this.isFlushingSync = false;\n if (flushStarted) endFlush();\n }\n }\n\n private _mergeBatchQueue(): void {\n this._epoch++;\n if (this.batchQueueSize > 0) {\n for (let i = 0; i < this.batchQueueSize; i++) {\n const job = this.batchQueue[i];\n if (job && job._nextEpoch !== this._epoch) {\n job._nextEpoch = this._epoch;\n this.queue[this.queueSize++] = job;\n }\n }\n this.batchQueueSize = 0;\n }\n }\n\n private _drainQueue(): void {\n let iterations = 0;\n\n while (this.queueSize > 0) {\n if (++iterations > this.maxFlushIterations) {\n this._handleFlushOverflow();\n break;\n }\n\n this._processCurrentQueue();\n this._mergeBatchQueue();\n }\n }\n\n private _processCurrentQueue(): void {\n const jobs = this.queue;\n const count = this.queueSize;\n\n this.queue = this.queue === this.queueA ? this.queueB : this.queueA;\n this.queueSize = 0;\n this._epoch++;\n\n this._processJobs(jobs, count);\n }\n\n private _handleFlushOverflow(): void {\n console.error(\n new SchedulerError(\n `Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop.`\n )\n );\n this.queueSize = 0;\n this.queue.length = 0;\n this.batchQueueSize = 0;\n }\n\n private _processJobs(jobs: SchedulerJob[], count: number): void {\n for (let i = 0; i < count; i++) {\n try {\n jobs[i]?.();\n } catch (error) {\n console.error(\n new SchedulerError('Error occurred during scheduler execution', error as Error)\n );\n }\n }\n jobs.length = 0;\n }\n\n /** Starts a new batch of updates. Updates will be deferred until endBatch is called. */\n startBatch(): void {\n this.batchDepth++;\n this.isBatching = true;\n }\n\n /**\n * Ends the current batch. If the batch depth reaches zero, all pending updates are flushed synchronously.\n */\n endBatch(): void {\n this.batchDepth = Math.max(0, this.batchDepth - 1);\n\n if (this.batchDepth === 0) {\n this.flushSync();\n this.isBatching = false;\n }\n }\n\n /**\n * Configures the maximum number of iterations allowed during a synchronous flush.\n * Used to prevent infinite loops.\n * @param max - Maximum iterations count.\n */\n setMaxFlushIterations(max: number): void {\n if (max < SCHEDULER_CONFIG.MIN_FLUSH_ITERATIONS) {\n throw new SchedulerError(\n `Max flush iterations must be at least ${SCHEDULER_CONFIG.MIN_FLUSH_ITERATIONS}`\n );\n }\n this.maxFlushIterations = max;\n }\n}\n\nexport const scheduler = new Scheduler();\n","import { AtomError } from '@/errors/errors';\nimport { scheduler } from './scheduler';\n\n/**\n * Executes multiple reactive updates in a single batch.\n *\n * Batching groups multiple state changes together, deferring notifications\n * until all updates are complete. This prevents intermediate states from\n * triggering unnecessary recomputations and improves performance.\n *\n * @template T - The return type of the callback function\n * @param callback - The function containing batched updates\n * @returns The result of the callback function\n * @throws {AtomError} If the callback is not a function\n * @throws Propagates any error thrown by the callback function\n *\n * @example\n * ```typescript\n * const firstName = atom('John');\n * const lastName = atom('Doe');\n *\n * // Without batching: triggers 2 separate updates\n * firstName.value = 'Jane';\n * lastName.value = 'Smith';\n *\n * // With batching: triggers 1 combined update\n * batch(() => {\n * firstName.value = 'Jane';\n * lastName.value = 'Smith';\n * });\n * ```\n */\nexport function batch<T>(callback: () => T): T {\n if (typeof callback !== 'function') {\n throw new AtomError('Batch callback must be a function');\n }\n\n scheduler.startBatch();\n\n try {\n return callback();\n } finally {\n scheduler.endBatch();\n }\n}\n","import type { Listener } from './tracking.types';\n\n/** Interface for the tracking context managing dependency collection */\nexport interface TrackingContext {\n current: Listener | null;\n\n /** Executes fn within tracking context with given listener */\n run<T>(listener: Listener, fn: () => T): T;\n\n getCurrent(): Listener | null;\n}\n\n/**\n * Global tracking context for dependency collection.\n * Atoms register as dependencies when accessed within a tracked context.\n */\nexport const trackingContext: TrackingContext = {\n current: null,\n\n run<T>(listener: Listener, fn: () => T): T {\n const prev = this.current;\n this.current = listener;\n try {\n return fn();\n } finally {\n this.current = prev;\n }\n },\n\n getCurrent(): Listener | null {\n return this.current;\n },\n};\n","import { AtomError } from '@/errors/errors';\nimport { trackingContext } from './context';\n\n/**\n * Executes a function without tracking any reactive dependencies.\n *\n * This utility allows reading atom values without establishing\n * a dependency relationship, useful for accessing values that\n * shouldn't trigger recomputation when they change.\n *\n * @template T - The return type of the function\n * @param fn - The function to execute without tracking\n * @returns The result of the executed function\n * @throws {AtomError} If the callback is not a function\n * @throws Propagates any error thrown by the callback function\n *\n * @example\n * ```typescript\n * const count = atom(0);\n * const doubled = computed(() => {\n * // This read will NOT be tracked as a dependency\n * const untrackedValue = untracked(() => count.value);\n * return untrackedValue * 2;\n * });\n * ```\n */\nexport function untracked<T>(fn: () => T): T {\n if (typeof fn !== 'function') {\n throw new AtomError('Untracked callback must be a function');\n }\n\n const prev = trackingContext.current;\n trackingContext.current = null;\n\n try {\n return fn();\n } finally {\n trackingContext.current = prev;\n }\n}\n","/**\n * Manages subscribers with optimized array-based operations.\n * Uses linear search (cache-friendly for small arrays) and swap-and-pop removal for performance.\n */\nexport class SubscriberManager<T> {\n private subscribers: T[] | null = null;\n\n /** Adds subscriber and returns unsubscribe function (idempotent) */\n add(subscriber: T): () => void {\n if (!this.subscribers) {\n this.subscribers = [];\n }\n\n if (this.subscribers.indexOf(subscriber) !== -1) {\n return () => {};\n }\n\n this.subscribers.push(subscriber);\n\n let isUnsubscribed = false;\n return () => {\n if (isUnsubscribed) return;\n isUnsubscribed = true;\n this.remove(subscriber);\n };\n }\n\n /** Removes subscriber using swap-and-pop */\n remove(subscriber: T): boolean {\n if (!this.subscribers) {\n return false;\n }\n\n const idx = this.subscribers.indexOf(subscriber);\n if (idx === -1) {\n return false;\n }\n\n const lastIndex = this.subscribers.length - 1;\n if (idx !== lastIndex) {\n this.subscribers[idx] = this.subscribers[lastIndex]!;\n }\n this.subscribers.pop();\n\n return true;\n }\n\n has(subscriber: T): boolean {\n if (!this.subscribers) return false;\n return this.subscribers.indexOf(subscriber) !== -1;\n }\n\n forEach(fn: (subscriber: T, index: number) => void): void {\n if (!this.subscribers) return;\n\n for (let i = 0; i < this.subscribers.length; i++) {\n fn(this.subscribers[i]!, i);\n }\n }\n\n /** Iterates with error handling to prevent one failure from breaking the chain */\n forEachSafe(fn: (subscriber: T, index: number) => void, onError?: (error: Error) => void): void {\n if (!this.subscribers) return;\n\n for (let i = 0; i < this.subscribers.length; i++) {\n try {\n fn(this.subscribers[i]!, i);\n } catch (error) {\n if (onError) {\n onError(error as Error);\n } else {\n console.error('[SubscriberManager] Error in subscriber callback:', error);\n }\n }\n }\n }\n\n get size(): number {\n return this.subscribers?.length ?? 0;\n }\n\n get hasSubscribers(): boolean {\n return this.subscribers !== null && this.subscribers.length > 0;\n }\n\n clear(): void {\n this.subscribers = null;\n }\n\n toArray(): T[] {\n return this.subscribers ? [...this.subscribers] : [];\n }\n}\n","import type {\n DependencySubscriber,\n ExecutableSubscriber,\n TrackableFunction,\n} from '@/tracking/tracking.types';\nimport type { ComputedAtom, EffectObject, ReadonlyAtom } from '@/types';\nimport { debug } from './debug';\n\n/** Checks if the given object is a ReadonlyAtom. */\nexport function isAtom(obj: unknown): obj is ReadonlyAtom {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n 'value' in obj &&\n 'subscribe' in obj &&\n typeof (obj as Record<string, unknown>).subscribe === 'function'\n );\n}\n\n/** Checks if the given object is a ComputedAtom. */\nexport function isComputed(obj: unknown): obj is ComputedAtom {\n if (debug.enabled && (obj === null || obj === undefined || typeof obj === 'object')) {\n const debugType = debug.getDebugType(obj);\n if (debugType) {\n return debugType === 'computed';\n }\n }\n return (\n isAtom(obj) &&\n 'invalidate' in obj &&\n typeof (obj as Record<string, unknown>).invalidate === 'function'\n );\n}\n\n/** Checks if the given object is an EffectObject. */\nexport function isEffect(obj: unknown): obj is EffectObject {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n 'dispose' in obj &&\n 'run' in obj &&\n typeof (obj as Record<string, unknown>).dispose === 'function' &&\n typeof (obj as Record<string, unknown>).run === 'function'\n );\n}\n\n/**\n * Type guard to check if a value is a Promise\n *\n * Uses duck-typing to detect Promise-like objects by checking for\n * the presence of a `then` method.\n *\n * @template T - The type the Promise resolves to\n * @param value - Value to check\n * @returns True if value has a `then` method (is Promise-like)\n */\nexport function isPromise<T>(value: unknown): value is Promise<T> {\n return value != null && typeof (value as { then?: unknown }).then === 'function';\n}\n\n/** Internal guard to verify if a value is a non-null object. */\nfunction isNonNullObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n/** Checks if the value implements the {@link DependencySubscriber} interface. */\nexport function hasDependencyMethod(value: unknown): value is DependencySubscriber {\n return (\n (typeof value === 'object' || typeof value === 'function') &&\n value !== null &&\n typeof (value as DependencySubscriber).addDependency === 'function'\n );\n}\n\n/** Checks if the value is a function with an `addDependency` method. */\nexport function isTrackableFunction(\n value: unknown\n): value is TrackableFunction & DependencySubscriber {\n return (\n typeof value === 'function' && typeof (value as TrackableFunction).addDependency === 'function'\n );\n}\n\n/** Checks if the value is a plain function without dependency tracking capabilities. */\nexport function isPlainListener(value: unknown): value is () => void {\n return (\n typeof value === 'function' && typeof (value as TrackableFunction).addDependency !== 'function'\n );\n}\n\n/** Checks if the value implements the {@link ExecutableSubscriber} interface. */\nexport function hasExecuteMethod(value: unknown): value is ExecutableSubscriber {\n return isNonNullObject(value) && typeof value.execute === 'function';\n}\n","import { SMI_MAX } from '@/constants';\nimport { ReactiveDependency } from '@/core/base/reactive-dependency';\nimport { scheduler } from '@/internal/scheduler';\nimport { trackingContext } from '@/tracking';\nimport type { AtomOptions, Subscriber, WritableAtom } from '@/types';\nimport { debug } from '@/utils/debug';\nimport { SubscriberManager } from '@/utils/subscriber-manager';\nimport { hasDependencyMethod, hasExecuteMethod, isPlainListener } from '@/utils/type-guards';\n\n/**\n * Internal {@link WritableAtom} implementation.\n * Extends {@link ReactiveDependency} to provide reactive state that can be observed and updated.\n * Optimized for fast subscriber notification and tracking.\n */\nclass AtomImpl<T> extends ReactiveDependency<T> implements WritableAtom<T> {\n private _value: T;\n private readonly _functionSubscribersStore: SubscriberManager<\n (newValue?: T, oldValue?: T) => void\n >;\n private readonly _objectSubscribersStore: SubscriberManager<Subscriber>;\n private readonly _sync: boolean;\n private readonly _notifyTask: () => void;\n private _pendingOldValue: T | undefined;\n private _isNotificationScheduled: boolean = false;\n\n constructor(initialValue: T, sync: boolean) {\n super();\n this._value = initialValue;\n this._functionSubscribersStore = new SubscriberManager();\n this._objectSubscribersStore = new SubscriberManager();\n this._sync = sync;\n this._notifyTask = this._flushNotifications.bind(this);\n debug.attachDebugInfo(this, 'atom', this.id);\n }\n\n /** Gets the manager for function-based subscribers. */\n protected get _functionSubscribers(): SubscriberManager<(newValue?: T, oldValue?: T) => void> {\n return this._functionSubscribersStore;\n }\n\n /** Gets the manager for object-based subscribers. */\n protected get _objectSubscribers(): SubscriberManager<Subscriber> {\n return this._objectSubscribersStore;\n }\n\n /**\n * Returns the current value and registers the atom as a dependency in the current tracking context.\n */\n get value(): T {\n const current = trackingContext.getCurrent();\n if (current) this._track(current);\n return this._value;\n }\n\n /**\n * Sets a new value and schedules notifications if the value has changed.\n * Uses `Object.is` for comparison.\n */\n set value(newValue: T) {\n if (Object.is(this._value, newValue)) return;\n\n const oldValue = this._value;\n this.version = (this.version + 1) & SMI_MAX;\n this._value = newValue;\n\n // Early exit: no subscribers to notify\n if (\n !this._functionSubscribersStore.hasSubscribers &&\n !this._objectSubscribersStore.hasSubscribers\n )\n return;\n\n this._scheduleNotification(oldValue);\n }\n\n private _track(current: unknown): void {\n // Priority 1: TrackableListener pattern (addDependency method)\n if (hasDependencyMethod(current)) {\n current.addDependency(this);\n return;\n }\n // Priority 2: Plain function callback\n if (isPlainListener(current)) {\n this._functionSubscribersStore.add(current as (newValue?: T, oldValue?: T) => void);\n return;\n }\n // Priority 3: Subscriber pattern (execute method)\n if (hasExecuteMethod(current)) {\n this._objectSubscribersStore.add(current);\n }\n }\n\n private _scheduleNotification(oldValue: T): void {\n if (!this._isNotificationScheduled) {\n this._pendingOldValue = oldValue;\n this._isNotificationScheduled = true;\n }\n\n // Hot path first: sync mode without batching flushes immediately\n if (this._sync && !scheduler.isBatching) {\n this._flushNotifications();\n } else {\n scheduler.schedule(this._notifyTask);\n }\n }\n\n private _flushNotifications(): void {\n if (!this._isNotificationScheduled) return;\n\n const oldValue = this._pendingOldValue as T;\n const newValue = this._value;\n\n this._pendingOldValue = undefined;\n this._isNotificationScheduled = false;\n\n this._notifySubscribers(newValue, oldValue);\n }\n\n /**\n * Returns the current value without registering as a dependency in the tracking context.\n */\n peek(): T {\n return this._value;\n }\n\n /**\n * Disposes of the atom, clearing all subscribers and resetting the value.\n */\n dispose(): void {\n this._functionSubscribersStore.clear();\n this._objectSubscribersStore.clear();\n this._value = undefined as T;\n }\n}\n\n/**\n * Creates a reactive atom holding mutable state.\n *\n * Atoms are the building blocks of reactive state. When an atom's value changes,\n * any effects or computed atoms that depend on it will be automatically re-executed.\n *\n * @param initialValue - The initial value of the atom.\n * @param options - Configuration options.\n * @param options.sync - If true, notifications are delivered synchronously when the value changes.\n * @returns A writable atom object.\n *\n * @example\n * ```ts\n * const count = atom(0);\n * count.value = 1; // Notifies subscribers\n * console.log(count.value); // 1\n * ```\n */\nexport function atom<T>(initialValue: T, options: AtomOptions = {}): WritableAtom<T> {\n return new AtomImpl(initialValue, options.sync ?? false);\n}\n","import { IS_DEV } from '@/constants';\nimport type { PoolStats } from '@/types/internal';\n\n/**\n * Generic Array Pool.\n * Provides type-safe pooling for different array types to reduce GC pressure.\n * Supports capacity limits and stats tracking in development mode.\n */\nexport class ArrayPool<T> {\n private pool: T[][] = [];\n private readonly maxPoolSize = 50;\n private readonly maxReusableCapacity = 256;\n\n private stats = IS_DEV\n ? {\n acquired: 0,\n released: 0,\n rejected: { frozen: 0, tooLarge: 0, poolFull: 0 },\n }\n : null;\n\n /** Acquires an array from the pool or creates a new one if the pool is empty. */\n acquire(): T[] {\n if (IS_DEV && this.stats) this.stats.acquired++;\n return this.pool.pop() ?? [];\n }\n\n /**\n * Releases an array back to the pool.\n * Clears the array before storing it.\n * @param arr - The array to release.\n * @param emptyConst - Optional reference to a constant empty array to skip.\n */\n release(arr: T[], emptyConst?: readonly T[]): void {\n if (emptyConst && arr === emptyConst) return;\n\n if (Object.isFrozen(arr)) {\n if (IS_DEV && this.stats) this.stats.rejected.frozen++;\n return;\n }\n\n if (arr.length > this.maxReusableCapacity) {\n if (IS_DEV && this.stats) this.stats.rejected.tooLarge++;\n return;\n }\n\n if (this.pool.length >= this.maxPoolSize) {\n if (IS_DEV && this.stats) this.stats.rejected.poolFull++;\n return;\n }\n\n arr.length = 0;\n this.pool.push(arr);\n if (IS_DEV && this.stats) this.stats.released++;\n }\n\n /** Returns current stats for the pool (dev mode only). */\n getStats(): PoolStats | null {\n if (!IS_DEV || !this.stats) return null;\n const { acquired, released, rejected } = this.stats;\n const totalRejected = rejected.frozen + rejected.tooLarge + rejected.poolFull;\n return {\n acquired,\n released,\n rejected,\n leaked: acquired - released - totalRejected,\n poolSize: this.pool.length,\n };\n }\n\n /** Resets the pool and its stats. */\n reset(): void {\n this.pool.length = 0;\n if (IS_DEV && this.stats) {\n this.stats.acquired = 0;\n this.stats.released = 0;\n this.stats.rejected = { frozen: 0, tooLarge: 0, poolFull: 0 };\n }\n }\n}\n","import type { Dependency, Subscriber } from '@/types';\nimport { ArrayPool } from '@/utils/array-pool';\n\n// Shared Constants\nexport const EMPTY_DEPS = Object.freeze([]) as unknown as Dependency[];\nexport const EMPTY_SUBS = Object.freeze([]) as unknown as Subscriber[];\nexport const EMPTY_UNSUBS = Object.freeze([]) as unknown as (() => void)[];\n\nexport const EMPTY_VERSIONS = Object.freeze([]) as unknown as number[];\n\n// Per-type Pool Instances (V8 Shape Optimization)\nexport const depArrayPool = new ArrayPool<Dependency>();\nexport const subArrayPool = new ArrayPool<Subscriber>();\nexport const unsubArrayPool = new ArrayPool<() => void>();\nexport const versionArrayPool = new ArrayPool<number>();\n","import { EMPTY_DEPS, EMPTY_UNSUBS, unsubArrayPool } from '@/internal/pool';\nimport type { Dependency, Subscriber } from '@/types';\nimport { debug } from '@/utils/debug';\n\n/**\n * Synchronizes subscriptions based on dependency changes using O(N) strategy.\n * Maps unsubs 1:1 with dependencies array.\n *\n * Shared logic for Computed and Effect to manage their dependencies.\n *\n * @param nextDeps - The new list of dependencies collected\n * @param prevDeps - The previous list of dependencies\n * @param prevUnsubs - The previous list of unsubscribe functions\n * @param tracker - The object tracking these dependencies (Computed or Effect)\n * @returns The new list of unsubscribe functions\n */\nexport function syncDependencies(\n nextDeps: Dependency[],\n prevDeps: Dependency[],\n prevUnsubs: (() => void)[],\n tracker: Subscriber\n): (() => void)[] {\n // 1. Map existing subscriptions to dependencies for O(1) lookup during sync\n if (prevDeps !== EMPTY_DEPS && prevUnsubs !== EMPTY_UNSUBS) {\n for (let i = 0; i < prevDeps.length; i++) {\n const dep = prevDeps[i];\n if (dep) dep._tempUnsub = prevUnsubs[i];\n }\n }\n\n // 2. Build new unsubscribe array\n const nextUnsubs = unsubArrayPool.acquire();\n\n // Ensure nextUnsubs has same length as nextDeps\n nextUnsubs.length = nextDeps.length;\n\n for (let i = 0; i < nextDeps.length; i++) {\n const dep = nextDeps[i];\n if (!dep) continue;\n\n if (dep._tempUnsub) {\n // Reuse existing subscription\n nextUnsubs[i] = dep._tempUnsub;\n dep._tempUnsub = undefined; // Consumed\n } else {\n debug.checkCircular(dep, tracker);\n nextUnsubs[i] = dep.subscribe(tracker);\n }\n }\n\n // 3. Cleanup unused subscriptions (from removals)\n if (prevDeps !== EMPTY_DEPS) {\n for (let i = 0; i < prevDeps.length; i++) {\n const dep = prevDeps[i];\n if (dep?._tempUnsub) {\n // Still has _tempUnsub => was not reused in nextDeps => Removed\n dep._tempUnsub();\n dep._tempUnsub = undefined;\n }\n }\n }\n\n // 4. Release old unsub array\n if (prevUnsubs !== EMPTY_UNSUBS) {\n unsubArrayPool.release(prevUnsubs);\n }\n\n return nextUnsubs;\n}\n","import { AtomError } from '@/errors/errors';\n\n/**\n * Wraps an unknown error in the appropriate AtomError subclass\n *\n * Provides consistent error handling by:\n * - Preserving original error information in the cause field\n * - Adding contextual information about where the error occurred\n * - Returning existing AtomErrors unchanged\n * - Handling various error types (TypeError, ReferenceError, etc.)\n *\n * @param error - Unknown error to wrap\n * @param ErrorClass - AtomError subclass to use for wrapping\n * @param context - Context string describing where the error occurred\n * @returns Wrapped error with contextual information\n *\n * @example\n * ```ts\n * try {\n * computeFn();\n * } catch (err) {\n * throw wrapError(err, ComputedError, 'computation phase');\n * }\n * ```\n */\nexport function wrapError(\n error: unknown,\n ErrorClass: typeof AtomError,\n context: string\n): AtomError {\n if (error instanceof TypeError) {\n return new ErrorClass(`Type error (${context}): ${error.message}`, error);\n }\n if (error instanceof ReferenceError) {\n return new ErrorClass(`Reference error (${context}): ${error.message}`, error);\n }\n if (error instanceof AtomError) {\n return error;\n }\n\n // Handle other error types\n const errorMessage = error instanceof Error ? error.message : String(error);\n const cause = error instanceof Error ? error : null;\n return new ErrorClass(`Unexpected error (${context}): ${errorMessage}`, cause);\n}\n","import { AsyncState, COMPUTED_STATE_FLAGS, EMPTY_ERROR_ARRAY, SMI_MAX } from '@/constants';\nimport { ReactiveDependency } from '@/core/base/reactive-dependency';\nimport { syncDependencies } from '@/core/utils/dep-tracking';\nimport type { AtomError } from '@/errors/errors';\nimport { ComputedError } from '@/errors/errors';\nimport { ERROR_MESSAGES } from '@/errors/messages';\nimport { currentEpoch, nextEpoch } from '@/internal/epoch';\nimport {\n depArrayPool,\n EMPTY_DEPS,\n EMPTY_UNSUBS,\n EMPTY_VERSIONS,\n unsubArrayPool,\n versionArrayPool,\n} from '@/internal/pool';\nimport { trackingContext } from '@/tracking';\n\nimport type {\n AsyncStateType,\n ComputedAtom,\n ComputedOptions,\n Dependency,\n Subscriber,\n} from '@/types';\nimport { debug, NO_DEFAULT_VALUE } from '@/utils/debug';\nimport { wrapError } from '@/utils/error';\nimport { SubscriberManager } from '@/utils/subscriber-manager';\nimport {\n hasDependencyMethod,\n hasExecuteMethod,\n isPlainListener,\n isPromise,\n} from '@/utils/type-guards';\n\n// AsyncState mapping\nconst ASYNC_STATE_MASK =\n COMPUTED_STATE_FLAGS.RESOLVED | COMPUTED_STATE_FLAGS.PENDING | COMPUTED_STATE_FLAGS.REJECTED;\nconst ASYNC_STATE_LOOKUP = Array(ASYNC_STATE_MASK + 1).fill(AsyncState.IDLE);\nASYNC_STATE_LOOKUP[COMPUTED_STATE_FLAGS.RESOLVED] = AsyncState.RESOLVED;\nASYNC_STATE_LOOKUP[COMPUTED_STATE_FLAGS.PENDING] = AsyncState.PENDING;\nASYNC_STATE_LOOKUP[COMPUTED_STATE_FLAGS.REJECTED] = AsyncState.REJECTED;\n\ntype TrackableListener = (() => void) & {\n addDependency: (dep: Dependency) => void;\n};\n\n/**\n * Computed atom with lazy evaluation, caching, and async support.\n * Uses bit flags for state and epoch-based dependency deduplication.\n */\nclass ComputedAtomImpl<T> extends ReactiveDependency<T> implements ComputedAtom<T>, Subscriber {\n private _value: T;\n private _error: AtomError | null;\n private _promiseId: number;\n private readonly _equal: (a: T, b: T) => boolean;\n\n private readonly _fn: () => T | Promise<T>;\n private readonly _defaultValue: T;\n private readonly _hasDefaultValue: boolean;\n private readonly _onError: ((error: Error) => void) | null;\n private readonly _functionSubscribersStore: SubscriberManager<\n (newValue?: T, oldValue?: T) => void\n >;\n private readonly _objectSubscribersStore: SubscriberManager<Subscriber>;\n private _dependencies: Dependency[];\n private _dependencyVersions: number[];\n private _unsubscribes: (() => void)[];\n\n // Error propagation fields\n private _cachedErrors: readonly Error[] | null = null;\n private _errorCacheEpoch = -1;\n\n private readonly _notifyJob: () => void;\n private readonly _trackable: TrackableListener;\n private readonly MAX_PROMISE_ID: number;\n\n constructor(fn: () => T | Promise<T>, options: ComputedOptions<T> = {}) {\n if (typeof fn !== 'function') {\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_MUST_BE_FUNCTION);\n }\n\n super();\n\n this._value = undefined as T;\n this.flags = COMPUTED_STATE_FLAGS.DIRTY | COMPUTED_STATE_FLAGS.IDLE;\n\n this._error = null;\n this._promiseId = 0;\n this._equal = options.equal ?? Object.is;\n\n this._fn = fn;\n this._defaultValue = 'defaultValue' in options ? options.defaultValue : (NO_DEFAULT_VALUE as T);\n this._hasDefaultValue = this._defaultValue !== (NO_DEFAULT_VALUE as T);\n this._onError = options.onError ?? null;\n this.MAX_PROMISE_ID = Number.MAX_SAFE_INTEGER - 1;\n\n this._functionSubscribersStore = new SubscriberManager<(newValue?: T, oldValue?: T) => void>();\n this._objectSubscribersStore = new SubscriberManager<Subscriber>();\n\n this._dependencies = EMPTY_DEPS;\n this._dependencyVersions = EMPTY_VERSIONS;\n this._unsubscribes = EMPTY_UNSUBS;\n\n this._notifyJob = () => {\n this._functionSubscribersStore.forEachSafe(\n (subscriber) => subscriber(),\n (err) => console.error(err)\n );\n\n this._objectSubscribersStore.forEachSafe(\n (subscriber) => subscriber.execute(),\n (err) => console.error(err)\n );\n };\n\n this._trackable = Object.assign(() => this._markDirty(), {\n addDependency: (_dep: Dependency) => {},\n });\n\n debug.attachDebugInfo(this as unknown as ComputedAtom<T>, 'computed', this.id);\n\n if (debug.enabled) {\n const debugObj = this as unknown as ComputedAtom<T> & {\n subscriberCount: () => number;\n isDirty: () => boolean;\n dependencies: Dependency[];\n stateFlags: string;\n };\n debugObj.subscriberCount = () =>\n this._functionSubscribersStore.size + this._objectSubscribersStore.size;\n debugObj.isDirty = () => this._isDirty();\n debugObj.dependencies = this._dependencies;\n debugObj.stateFlags = this._getFlagsAsString();\n }\n\n if (options.lazy === false) {\n try {\n this._recompute();\n } catch {\n // Ignore initial computation failure\n }\n }\n }\n\n protected get _functionSubscribers(): SubscriberManager<(newValue?: T, oldValue?: T) => void> {\n return this._functionSubscribersStore;\n }\n\n protected get _objectSubscribers(): SubscriberManager<Subscriber> {\n return this._objectSubscribersStore;\n }\n\n get value(): T {\n // Register tracking FIRST so this computed becomes a dependency\n // even if _computeValue throws. This is critical for error propagation.\n this._registerTracking();\n const result = this._computeValue();\n return result;\n }\n\n peek(): T {\n return this._value;\n }\n\n get state(): AsyncStateType {\n this._registerTracking();\n return this._getAsyncState();\n }\n\n get hasError(): boolean {\n this._registerTracking();\n\n // 1. Check own error state\n if (this._isRejected()) {\n return true;\n }\n\n // 2. Check dependency errors (early return)\n for (let i = 0; i < this._dependencies.length; i++) {\n const dep = this._dependencies[i];\n if (dep && 'hasError' in dep && (dep as unknown as ComputedAtom<unknown>).hasError) {\n return true;\n }\n }\n\n return false;\n }\n\n get isValid(): boolean {\n return !this.hasError;\n }\n\n get errors(): readonly Error[] {\n this._registerTracking();\n\n // Fast path: no errors\n if (!this.hasError) {\n return EMPTY_ERROR_ARRAY;\n }\n\n // Check epoch cache\n const epoch = currentEpoch();\n if (this._errorCacheEpoch === epoch && this._cachedErrors !== null) {\n return this._cachedErrors;\n }\n\n // Collect errors (lazy) using Set for deduplication\n const errorSet = new Set<Error>();\n\n // Own error\n if (this._error) {\n errorSet.add(this._error);\n }\n\n // Dependency errors (recursive collection, deduplicated)\n for (let i = 0; i < this._dependencies.length; i++) {\n const dep = this._dependencies[i];\n if (dep && 'errors' in dep) {\n const depErrors = (dep as unknown as ComputedAtom<unknown>).errors;\n for (let j = 0; j < depErrors.length; j++) {\n const err = depErrors[j];\n if (err) {\n errorSet.add(err);\n }\n }\n }\n }\n\n // Cache and freeze\n this._cachedErrors = Object.freeze([...errorSet]);\n this._errorCacheEpoch = epoch;\n\n return this._cachedErrors;\n }\n\n get lastError(): Error | null {\n this._registerTracking();\n return this._error;\n }\n\n get isPending(): boolean {\n this._registerTracking();\n return this._isPending();\n }\n\n get isResolved(): boolean {\n this._registerTracking();\n return this._isResolved();\n }\n\n invalidate(): void {\n this._markDirty();\n if (this._dependencyVersions !== EMPTY_VERSIONS) {\n versionArrayPool.release(this._dependencyVersions);\n this._dependencyVersions = EMPTY_VERSIONS;\n }\n // Invalidate error cache\n this._errorCacheEpoch = -1;\n this._cachedErrors = null;\n }\n\n dispose(): void {\n if (this._unsubscribes !== EMPTY_UNSUBS) {\n for (let i = 0; i < this._unsubscribes.length; i++) {\n const unsub = this._unsubscribes[i];\n if (unsub) unsub();\n }\n unsubArrayPool.release(this._unsubscribes);\n this._unsubscribes = EMPTY_UNSUBS;\n }\n\n if (this._dependencies !== EMPTY_DEPS) {\n depArrayPool.release(this._dependencies);\n this._dependencies = EMPTY_DEPS;\n }\n\n if (this._dependencyVersions !== EMPTY_VERSIONS) {\n versionArrayPool.release(this._dependencyVersions);\n this._dependencyVersions = EMPTY_VERSIONS;\n }\n\n this._functionSubscribersStore.clear();\n this._objectSubscribersStore.clear();\n this.flags = COMPUTED_STATE_FLAGS.DIRTY | COMPUTED_STATE_FLAGS.IDLE;\n this._error = null;\n this._value = undefined as T;\n this._promiseId = (this._promiseId + 1) % this.MAX_PROMISE_ID;\n // Clear error cache\n this._cachedErrors = null;\n this._errorCacheEpoch = -1;\n }\n\n // State flag operations\n private _isDirty(): boolean {\n return (this.flags & COMPUTED_STATE_FLAGS.DIRTY) !== 0;\n }\n\n private _setDirty(): void {\n this.flags |= COMPUTED_STATE_FLAGS.DIRTY;\n }\n\n private _clearDirty(): void {\n this.flags &= ~COMPUTED_STATE_FLAGS.DIRTY;\n }\n\n private _isIdle(): boolean {\n return (this.flags & COMPUTED_STATE_FLAGS.IDLE) !== 0;\n }\n\n private _setIdle(): void {\n this.flags |= COMPUTED_STATE_FLAGS.IDLE;\n this.flags &= ~(\n COMPUTED_STATE_FLAGS.PENDING |\n COMPUTED_STATE_FLAGS.RESOLVED |\n COMPUTED_STATE_FLAGS.REJECTED\n );\n }\n\n private _isPending(): boolean {\n return (this.flags & COMPUTED_STATE_FLAGS.PENDING) !== 0;\n }\n\n private _setPending(): void {\n this.flags |= COMPUTED_STATE_FLAGS.PENDING;\n this.flags &= ~(\n COMPUTED_STATE_FLAGS.IDLE |\n COMPUTED_STATE_FLAGS.RESOLVED |\n COMPUTED_STATE_FLAGS.REJECTED\n );\n }\n\n private _isResolved(): boolean {\n return (this.flags & COMPUTED_STATE_FLAGS.RESOLVED) !== 0;\n }\n\n private _setResolved(): void {\n this.flags |= COMPUTED_STATE_FLAGS.RESOLVED;\n this.flags &= ~(\n COMPUTED_STATE_FLAGS.IDLE |\n COMPUTED_STATE_FLAGS.PENDING |\n COMPUTED_STATE_FLAGS.REJECTED |\n COMPUTED_STATE_FLAGS.HAS_ERROR\n );\n }\n\n private _isRejected(): boolean {\n return (this.flags & COMPUTED_STATE_FLAGS.REJECTED) !== 0;\n }\n\n private _setRejected(): void {\n this.flags |= COMPUTED_STATE_FLAGS.REJECTED | COMPUTED_STATE_FLAGS.HAS_ERROR;\n this.flags &= ~(\n COMPUTED_STATE_FLAGS.IDLE |\n COMPUTED_STATE_FLAGS.PENDING |\n COMPUTED_STATE_FLAGS.RESOLVED\n );\n }\n\n private _isRecomputing(): boolean {\n return (this.flags & COMPUTED_STATE_FLAGS.RECOMPUTING) !== 0;\n }\n\n private _setRecomputing(value: boolean): void {\n const mask = COMPUTED_STATE_FLAGS.RECOMPUTING;\n this.flags = (this.flags & ~mask) | (-Number(value) & mask);\n }\n\n private _getAsyncState(): AsyncStateType {\n return ASYNC_STATE_LOOKUP[this.flags & ASYNC_STATE_MASK];\n }\n\n private _getFlagsAsString(): string {\n const states: string[] = [];\n if (this._isDirty()) states.push('DIRTY');\n if (this._isIdle()) states.push('IDLE');\n if (this._isPending()) states.push('PENDING');\n if (this._isResolved()) states.push('RESOLVED');\n if (this._isRejected()) states.push('REJECTED');\n if (this._isRecomputing()) states.push('RECOMPUTING');\n return states.join(' | ');\n }\n\n private _computeValue(): T {\n if (this._isRecomputing()) return this._value;\n\n if (this._isDirty() || this._isIdle()) {\n this._recompute();\n }\n\n if (this._isPending()) return this._handlePending();\n if (this._isRejected()) return this._handleRejected();\n\n return this._value;\n }\n\n private _recompute(): void {\n if (this._isRecomputing()) return;\n\n this._setRecomputing(true);\n\n const context = this._prepareComputationContext();\n let committed = false;\n\n try {\n const result = trackingContext.run(this._trackable, this._fn);\n\n this._commitDependencies(context);\n committed = true;\n\n isPromise(result) ? this._handleAsyncComputation(result) : this._handleSyncResult(result);\n } catch (err) {\n if (!committed) {\n try {\n this._commitDependencies(context);\n committed = true;\n } catch (commitErr) {\n this._handleComputationError(commitErr);\n }\n }\n this._handleComputationError(err);\n } finally {\n this._cleanupContext(context, committed);\n this._setRecomputing(false);\n }\n }\n\n private _prepareComputationContext() {\n const prevDeps = this._dependencies;\n const prevVersions = this._dependencyVersions;\n const nextDeps = depArrayPool.acquire();\n const nextVersions = versionArrayPool.acquire();\n const epoch = nextEpoch();\n const state = { depCount: 0 };\n\n const collect = (dep: Dependency) => {\n if (dep._lastSeenEpoch === epoch) return;\n dep._lastSeenEpoch = epoch;\n\n if (state.depCount < nextDeps.length) {\n nextDeps[state.depCount] = dep;\n nextVersions[state.depCount] = dep.version;\n } else {\n nextDeps.push(dep);\n nextVersions.push(dep.version);\n }\n state.depCount++;\n };\n\n const originalAdd = this._trackable.addDependency;\n this._trackable.addDependency = collect;\n\n return { prevDeps, prevVersions, nextDeps, nextVersions, originalAdd, state };\n }\n\n private _commitDependencies(ctx: {\n nextDeps: Dependency[];\n nextVersions: number[];\n state: { depCount: number };\n prevDeps: Dependency[];\n }): void {\n const { nextDeps, nextVersions, state, prevDeps } = ctx;\n\n nextDeps.length = state.depCount;\n nextVersions.length = state.depCount;\n\n this._unsubscribes = syncDependencies(nextDeps, prevDeps, this._unsubscribes, this);\n this._dependencies = nextDeps;\n this._dependencyVersions = nextVersions;\n }\n\n private _cleanupContext(\n ctx: {\n nextDeps: Dependency[];\n nextVersions: number[];\n originalAdd: (dep: Dependency) => void;\n prevDeps: Dependency[];\n prevVersions: number[];\n },\n committed: boolean\n ): void {\n this._trackable.addDependency = ctx.originalAdd;\n\n if (committed) {\n if (ctx.prevDeps !== EMPTY_DEPS) {\n depArrayPool.release(ctx.prevDeps);\n }\n if (ctx.prevVersions !== EMPTY_VERSIONS) {\n versionArrayPool.release(ctx.prevVersions);\n }\n } else {\n depArrayPool.release(ctx.nextDeps);\n versionArrayPool.release(ctx.nextVersions);\n }\n }\n\n private _handleSyncResult(result: T): void {\n const valueChanged = !this._isResolved() || !this._equal(this._value, result);\n this.version = (this.version + Number(valueChanged)) & SMI_MAX;\n\n this._value = result;\n this._clearDirty();\n this._setResolved();\n this._error = null;\n this._setRecomputing(false);\n // Clear error cache on successful computation (recovery)\n this._cachedErrors = null;\n this._errorCacheEpoch = -1;\n }\n\n private _handleAsyncComputation(promise: Promise<T>): void {\n this._setPending();\n this._clearDirty();\n this._notifyJob();\n\n this._promiseId = this._promiseId >= this.MAX_PROMISE_ID ? 1 : this._promiseId + 1;\n const promiseId = this._promiseId;\n\n promise\n .then((resolvedValue) => {\n if (promiseId !== this._promiseId) return;\n this._handleAsyncResolution(resolvedValue);\n })\n .catch((err) => {\n if (promiseId !== this._promiseId) return;\n this._handleAsyncRejection(err);\n });\n }\n\n private _handleAsyncResolution(resolvedValue: T): void {\n const valueChanged = !this._isResolved() || !this._equal(this._value, resolvedValue);\n this.version = (this.version + Number(valueChanged)) & SMI_MAX;\n\n this._value = resolvedValue;\n this._clearDirty();\n this._setResolved();\n this._error = null;\n this._setRecomputing(false);\n // Clear error cache on successful computation (recovery)\n this._cachedErrors = null;\n this._errorCacheEpoch = -1;\n\n // Notify subscribers when async computation resolves\n this._notifyJob();\n }\n\n private _handleAsyncRejection(err: unknown): void {\n const error = wrapError(err, ComputedError, ERROR_MESSAGES.COMPUTED_ASYNC_COMPUTATION_FAILED);\n\n // Increment version so effects detect the state change (pending -> rejected)\n const stateChanged = !this._isRejected();\n this.version = (this.version + Number(stateChanged)) & SMI_MAX;\n\n this._error = error;\n this._setRejected();\n this._clearDirty();\n this._setRecomputing(false);\n\n if (this._onError) {\n try {\n this._onError(error);\n } catch (callbackError) {\n console.error(ERROR_MESSAGES.CALLBACK_ERROR_IN_ERROR_HANDLER, callbackError);\n }\n }\n\n this._notifyJob();\n }\n\n private _handleComputationError(err: unknown): never {\n const error = wrapError(err, ComputedError, ERROR_MESSAGES.COMPUTED_COMPUTATION_FAILED);\n\n this._error = error;\n this._setRejected();\n this._clearDirty();\n this._setRecomputing(false);\n\n if (this._onError) {\n try {\n this._onError(error);\n } catch (callbackError) {\n console.error(ERROR_MESSAGES.CALLBACK_ERROR_IN_ERROR_HANDLER, callbackError);\n }\n }\n\n throw error;\n }\n\n private _handlePending(): T {\n if (this._hasDefaultValue) {\n return this._defaultValue;\n }\n throw new ComputedError(ERROR_MESSAGES.COMPUTED_ASYNC_PENDING_NO_DEFAULT);\n }\n\n private _handleRejected(): T {\n if (this._error?.recoverable && this._hasDefaultValue) {\n return this._defaultValue;\n }\n throw this._error;\n }\n\n /** Subscriber interface - marks dirty on dependency change */\n execute(): void {\n this._markDirty();\n }\n\n private _markDirty(): void {\n if (this._isRecomputing() || this._isDirty()) return;\n\n this._setDirty();\n this._notifyJob();\n }\n\n private _registerTracking(): void {\n const current = trackingContext.getCurrent();\n if (!current) return;\n\n // Priority 1: Has addDependency method (TrackableListener or DependencyTracker)\n if (hasDependencyMethod(current)) {\n current.addDependency(this);\n return;\n }\n\n // Priority 2: Plain function callback\n if (isPlainListener(current)) {\n this._functionSubscribersStore.add(current);\n return;\n }\n\n // Priority 3: Object with execute method (Subscriber pattern)\n if (hasExecuteMethod(current)) {\n this._objectSubscribersStore.add(current);\n }\n }\n}\n\nObject.freeze(ComputedAtomImpl.prototype);\n\n/**\n * Creates a computed value with automatic dependency tracking.\n * Supports sync/async computations with caching and lazy evaluation.\n * @param fn - Computation function (sync or async)\n * @param options - { equal?, defaultValue?, onError?, lazy? }\n */\nexport function computed<T>(fn: () => T, options?: ComputedOptions<T>): ComputedAtom<T>;\nexport function computed<T>(\n fn: () => Promise<T>,\n options: ComputedOptions<T> & { defaultValue: T }\n): ComputedAtom<T>;\nexport function computed<T>(\n fn: () => T | Promise<T>,\n options: ComputedOptions<T> = {}\n): ComputedAtom<T> {\n return new ComputedAtomImpl(fn, options) as unknown as ComputedAtom<T>;\n}\n","import { EFFECT_STATE_FLAGS, IS_DEV, SCHEDULER_CONFIG, TIME_CONSTANTS } from '@/constants';\nimport { ReactiveNode } from '@/core/base/reactive-node';\nimport { EffectError } from '@/errors/errors';\nimport { ERROR_MESSAGES } from '@/errors/messages';\nimport {\n flushEpoch,\n flushExecutionCount,\n incrementFlushExecutionCount,\n nextEpoch,\n} from '@/internal/epoch';\nimport {\n depArrayPool,\n EMPTY_DEPS,\n EMPTY_UNSUBS,\n EMPTY_VERSIONS,\n unsubArrayPool,\n versionArrayPool,\n} from '@/internal/pool';\nimport { scheduler } from '@/internal/scheduler';\nimport { type DependencyTracker, trackingContext, untracked } from '@/tracking';\nimport type { Dependency, EffectFunction, EffectObject, EffectOptions } from '@/types';\nimport { debug } from '@/utils/debug';\nimport { wrapError } from '@/utils/error';\nimport { isPromise } from '@/utils/type-guards';\n\n/**\n * Internal context used during effect execution to track dependency changes.\n */\ninterface EffectContext {\n prevDeps: Dependency[];\n prevVersions: number[];\n prevUnsubs: (() => void)[];\n nextDeps: Dependency[];\n nextVersions: number[];\n nextUnsubs: (() => void)[];\n}\n\n/**\n * Internal effect implementation with dependency tracking and infinite loop detection.\n * Extends {@link ReactiveNode} and implements {@link EffectObject} and {@link DependencyTracker}.\n */\n\nclass EffectImpl extends ReactiveNode implements EffectObject, DependencyTracker {\n /** Current execution epoch for tracking freshness */\n private _currentEpoch: number;\n /** Epoch of the last scheduler flush */\n private _lastFlushEpoch: number;\n /** Number of executions within the current flush */\n private _executionsInEpoch: number;\n\n /** The effect function to execute */\n private readonly _fn: EffectFunction;\n /** Whether to execute synchronously on dependency change */\n private readonly _sync: boolean;\n /** Maximum allowed executions per second */\n private readonly _maxExecutions: number;\n /** Maximum allowed executions per scheduler flush */\n private readonly _maxExecutionsPerFlush: number;\n /** Whether to track if dependencies are modified during execution */\n private readonly _trackModifications: boolean;\n\n /** Cleanup function returned by the last execution */\n private _cleanup: (() => void) | null;\n /** Current active dependencies */\n private _dependencies: Dependency[];\n /** Cached versions of dependencies at last execution */\n private _dependencyVersions: number[];\n /** Unsubscribe functions for current dependencies */\n private _unsubscribes: (() => void)[];\n /** Temporary storage for dependencies being tracked in current execution */\n private _nextDeps: Dependency[] | null;\n /** Temporary storage for dependency versions being tracked in current execution */\n private _nextVersions: number[] | null;\n /** Temporary storage for unsubscribes being tracked in current execution */\n private _nextUnsubs: (() => void)[] | null;\n /** Execution timestamps for rate limiting (dev only) */\n private _history: number[] | null;\n /** Total number of executions */\n private _executionCount: number;\n\n /**\n * Creates a new EffectImpl instance.\n * @param fn - The effect function to run.\n * @param options - Configuration options for the effect.\n */\n\n constructor(fn: EffectFunction, options: EffectOptions = {}) {\n super();\n\n this._currentEpoch = -1;\n this._lastFlushEpoch = -1;\n this._executionsInEpoch = 0;\n\n this._fn = fn;\n this._sync = options.sync ?? false;\n this._maxExecutions =\n options.maxExecutionsPerSecond ?? SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_SECOND;\n this._maxExecutionsPerFlush =\n options.maxExecutionsPerFlush ?? SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_EFFECT;\n this._trackModifications = options.trackModifications ?? false;\n\n this._cleanup = null;\n this._dependencies = EMPTY_DEPS;\n this._dependencyVersions = EMPTY_VERSIONS;\n this._unsubscribes = EMPTY_UNSUBS;\n this._nextDeps = null;\n this._nextVersions = null;\n this._nextUnsubs = null;\n this._history = IS_DEV ? [] : null;\n this._executionCount = 0;\n\n debug.attachDebugInfo(this, 'effect', this.id);\n }\n\n /**\n * Manually triggers effect execution.\n * Forces re-execution even if dependencies haven't changed.\n * @throws {EffectError} If the effect is already disposed.\n */\n public run = (): void => {\n if (this.isDisposed) {\n throw new EffectError(ERROR_MESSAGES.EFFECT_MUST_BE_FUNCTION);\n }\n if (this._dependencyVersions !== EMPTY_VERSIONS) {\n versionArrayPool.release(this._dependencyVersions);\n this._dependencyVersions = EMPTY_VERSIONS as number[];\n }\n this.execute();\n };\n\n /**\n * Disposes of the effect, cleaning up all subscriptions and resources.\n * Prevents further executions and releases arrays back to pools.\n */\n public dispose = (): void => {\n if (this.isDisposed) return;\n\n this._setDisposed();\n this._safeCleanup();\n\n if (this._unsubscribes !== EMPTY_UNSUBS) {\n for (let i = 0; i < this._unsubscribes.length; i++) {\n const unsub = this._unsubscribes[i];\n if (unsub) unsub();\n }\n unsubArrayPool.release(this._unsubscribes);\n this._unsubscribes = EMPTY_UNSUBS;\n }\n\n if (this._dependencies !== EMPTY_DEPS) {\n depArrayPool.release(this._dependencies);\n this._dependencies = EMPTY_DEPS;\n }\n\n if (this._dependencyVersions !== EMPTY_VERSIONS) {\n versionArrayPool.release(this._dependencyVersions);\n this._dependencyVersions = EMPTY_VERSIONS;\n }\n };\n\n /**\n * Adds a dependency to the current tracking context.\n * Called automatically when a reactive node is accessed during execution.\n * @param dep - The dependency to track.\n */\n public addDependency = (dep: Dependency): void => {\n if (this.isExecuting && this._nextDeps && this._nextUnsubs && this._nextVersions) {\n const epoch = this._currentEpoch;\n\n if (dep._lastSeenEpoch === epoch) return;\n dep._lastSeenEpoch = epoch;\n\n this._nextDeps.push(dep);\n this._nextVersions.push(dep.version);\n\n if (dep._tempUnsub) {\n this._nextUnsubs.push(dep._tempUnsub);\n dep._tempUnsub = undefined;\n } else {\n this._subscribeTo(dep);\n }\n }\n };\n\n /**\n * Executes the effect function.\n * Handles dependency tracking, cleanup, and infinite loop protection.\n * If the function returns a cleanup function or a Promise, it will be handled accordingly.\n */\n public execute = (): void => {\n if (this.isDisposed || this.isExecuting) return;\n if (!this._shouldExecute()) return;\n\n this._checkInfiniteLoop();\n this._setExecuting(true);\n this._safeCleanup();\n\n const context = this._prepareEffectContext();\n let committed = false;\n\n try {\n const result = trackingContext.run(this, this._fn);\n\n this._commitEffect(context);\n committed = true;\n\n this._checkLoopWarnings();\n\n if (isPromise(result)) {\n result\n .then((asyncCleanup) => {\n if (!this.isDisposed && typeof asyncCleanup === 'function') {\n this._cleanup = asyncCleanup;\n }\n })\n .catch((error) => {\n console.error(wrapError(error, EffectError, ERROR_MESSAGES.EFFECT_EXECUTION_FAILED));\n });\n } else {\n this._cleanup = typeof result === 'function' ? result : null;\n }\n } catch (error) {\n committed = true;\n console.error(wrapError(error, EffectError, ERROR_MESSAGES.EFFECT_EXECUTION_FAILED));\n this._cleanup = null;\n } finally {\n this._cleanupEffect(context, committed);\n this._setExecuting(false);\n }\n };\n\n /**\n * Prepares the execution context by acquiring pools and setting up epoch.\n * @returns The prepared EffectContext.\n */\n private _prepareEffectContext(): EffectContext {\n const prevDeps = this._dependencies;\n const prevVersions = this._dependencyVersions;\n const prevUnsubs = this._unsubscribes;\n const nextDeps = depArrayPool.acquire();\n const nextVersions = versionArrayPool.acquire();\n const nextUnsubs = unsubArrayPool.acquire();\n const epoch = nextEpoch();\n\n if (prevDeps !== EMPTY_DEPS && prevUnsubs !== EMPTY_UNSUBS) {\n for (let i = 0; i < prevDeps.length; i++) {\n const dep = prevDeps[i];\n if (dep) dep._tempUnsub = prevUnsubs[i];\n }\n }\n\n this._nextDeps = nextDeps;\n this._nextVersions = nextVersions;\n this._nextUnsubs = nextUnsubs;\n this._currentEpoch = epoch;\n\n return { prevDeps, prevVersions, prevUnsubs, nextDeps, nextVersions, nextUnsubs };\n }\n\n /**\n * Commits the tracked dependencies as the current active dependencies.\n * @param ctx - The current effect context.\n */\n private _commitEffect(ctx: EffectContext): void {\n // Structural Guarantee: nextDeps length is controlled by the tracking phase\n // We use the context's nextDeps directly, avoiding `this._nextDeps!`\n const trackedCount = ctx.nextDeps.length;\n\n ctx.nextDeps.length = trackedCount;\n ctx.nextVersions.length = trackedCount;\n\n this._dependencies = ctx.nextDeps;\n this._dependencyVersions = ctx.nextVersions;\n this._unsubscribes = ctx.nextUnsubs;\n }\n\n /**\n * Cleans up the effect execution context, releasing resources back to pools.\n * @param ctx - The effect context to clean up.\n * @param committed - Whether the changes were committed to the effect.\n */\n private _cleanupEffect(ctx: EffectContext, committed: boolean): void {\n this._nextDeps = null;\n this._nextVersions = null;\n this._nextUnsubs = null;\n\n if (committed) {\n if (ctx.prevDeps !== EMPTY_DEPS) {\n for (let i = 0; i < ctx.prevDeps.length; i++) {\n const dep = ctx.prevDeps[i];\n if (dep?._tempUnsub) {\n dep._tempUnsub();\n dep._tempUnsub = undefined;\n }\n }\n depArrayPool.release(ctx.prevDeps);\n }\n if (ctx.prevUnsubs !== EMPTY_UNSUBS) {\n unsubArrayPool.release(ctx.prevUnsubs);\n }\n if (ctx.prevVersions !== EMPTY_VERSIONS) {\n versionArrayPool.release(ctx.prevVersions);\n }\n } else {\n depArrayPool.release(ctx.nextDeps);\n versionArrayPool.release(ctx.nextVersions);\n for (let i = 0; i < ctx.nextUnsubs.length; i++) {\n ctx.nextUnsubs[i]?.();\n }\n unsubArrayPool.release(ctx.nextUnsubs);\n\n if (ctx.prevDeps !== EMPTY_DEPS) {\n for (let i = 0; i < ctx.prevDeps.length; i++) {\n const dep = ctx.prevDeps[i];\n if (dep) dep._tempUnsub = undefined;\n }\n }\n }\n }\n\n /**\n * Subscribes to a dependency's changes.\n * @param dep - The dependency to subscribe to.\n */\n private _subscribeTo(dep: Dependency): void {\n try {\n const unsubscribe = dep.subscribe(() => {\n if (this._trackModifications && this.isExecuting) {\n dep._modifiedAtEpoch = this._currentEpoch;\n }\n\n if (this._sync) {\n this.execute();\n } else {\n scheduler.schedule(this.execute);\n }\n });\n if (this._nextUnsubs) {\n this._nextUnsubs.push(unsubscribe);\n }\n } catch (error) {\n console.error(wrapError(error, EffectError, ERROR_MESSAGES.EFFECT_EXECUTION_FAILED));\n if (this._nextUnsubs) this._nextUnsubs.push(() => {});\n }\n }\n\n /**\n * Whether the effect has been disposed.\n */\n get isDisposed(): boolean {\n return (this.flags & EFFECT_STATE_FLAGS.DISPOSED) !== 0;\n }\n\n /**\n * Total number of times this effect has executed.\n */\n get executionCount(): number {\n return this._executionCount;\n }\n\n /**\n * Whether the effect is currently executing.\n */\n get isExecuting(): boolean {\n return (this.flags & EFFECT_STATE_FLAGS.EXECUTING) !== 0;\n }\n\n private _setDisposed(): void {\n this.flags |= EFFECT_STATE_FLAGS.DISPOSED;\n }\n\n private _setExecuting(value: boolean): void {\n const mask = EFFECT_STATE_FLAGS.EXECUTING;\n this.flags = (this.flags & ~mask) | (-Number(value) & mask);\n }\n\n /**\n * Executes the cleanup function if it exists.\n */\n private _safeCleanup(): void {\n if (this._cleanup) {\n try {\n this._cleanup();\n } catch (error) {\n console.error(wrapError(error, EffectError, ERROR_MESSAGES.EFFECT_CLEANUP_FAILED));\n }\n this._cleanup = null;\n }\n }\n\n /**\n * Checks for infinite loops by tracking execution counts within a flush and time period.\n * @throws {EffectError} If an infinite loop is detected.\n */\n private _checkInfiniteLoop(): void {\n if (this._lastFlushEpoch !== flushEpoch) {\n this._lastFlushEpoch = flushEpoch;\n this._executionsInEpoch = 0;\n }\n\n this._executionsInEpoch++;\n\n if (this._executionsInEpoch > this._maxExecutionsPerFlush) {\n this._throwInfiniteLoopError('per-effect');\n }\n\n if (incrementFlushExecutionCount() > SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_FLUSH) {\n this._throwInfiniteLoopError('global');\n }\n\n this._executionCount++;\n\n if (this._history) {\n const now = Date.now();\n this._history.push(now);\n\n if (this._history.length > SCHEDULER_CONFIG.MAX_EXECUTIONS_PER_SECOND + 10) {\n this._history.shift();\n }\n\n this._checkTimestampLoop(now);\n }\n }\n\n private _checkTimestampLoop(now: number): void {\n const history = this._history;\n if (!history || this._maxExecutions <= 0) return;\n\n const oneSecondAgo = now - TIME_CONSTANTS.ONE_SECOND_MS;\n let count = 0;\n\n for (let i = history.length - 1; i >= 0; i--) {\n if (history[i]! < oneSecondAgo) break;\n count++;\n }\n\n if (count > this._maxExecutions) {\n const error = new EffectError(\n `Effect executed ${count} times within 1 second. Infinite loop suspected`\n );\n this.dispose();\n console.error(error);\n if (IS_DEV) {\n throw error;\n }\n }\n }\n\n private _throwInfiniteLoopError(type: 'per-effect' | 'global'): never {\n const error = new EffectError(\n `Infinite loop detected (${type}): ` +\n `effect executed ${this._executionsInEpoch} times in current flush. ` +\n `Total executions in flush: ${flushExecutionCount}`\n );\n this.dispose();\n console.error(error);\n throw error;\n }\n\n /**\n * Determines if the effect should execute based on dependency versions.\n * @returns true if any dependency has changed or if it's the first run.\n */\n private _shouldExecute(): boolean {\n // Early exit: no deps or no version cache means first run or invalidated\n if (this._dependencies === EMPTY_DEPS || this._dependencyVersions === EMPTY_VERSIONS)\n return true;\n\n for (let i = 0; i < this._dependencies.length; i++) {\n const dep = this._dependencies[i];\n if (!dep) continue;\n\n if ('value' in dep) {\n try {\n untracked(() => (dep as { value: unknown }).value);\n } catch {\n return true;\n }\n }\n\n if (dep.version !== this._dependencyVersions[i]) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Checks for potential infinite loops where an effect modifies its own dependencies.\n * Only active if trackModifications is enabled and debug is on.\n */\n private _checkLoopWarnings(): void {\n if (this._trackModifications && debug.enabled) {\n const dependencies = this._dependencies;\n for (let i = 0; i < dependencies.length; i++) {\n const dep = dependencies[i];\n if (dep && dep._modifiedAtEpoch === this._currentEpoch) {\n debug.warn(\n true,\n `Effect is reading a dependency (${\n debug.getDebugName(dep) || 'unknown'\n }) that it just modified. Infinite loop may occur`\n );\n }\n }\n }\n }\n}\n\n/**\n * Creates a reactive effect that re-executes when its dependencies change.\n *\n * An effect automatically tracks any reactive state (atoms, computed) accessed during its execution.\n * When those dependencies change, the effect is scheduled for re-execution.\n *\n * @param fn - The effect function to execute. Can return a cleanup function or a Promise that resolves to one.\n * @param options - Configuration options for the effect.\n * @param options.sync - If true, the effect runs synchronously when dependencies change. Defaults to false (scheduled).\n * @param options.maxExecutionsPerSecond - Rate limiting for the effect.\n * @param options.trackModifications - If true, warns when an effect modifies its own dependencies.\n * @returns An object representing the effect with `run()` and `dispose()` methods.\n * @throws {EffectError} If `fn` is not a function.\n *\n * @example\n * ```ts\n * const count = atom(0);\n * const stop = effect(() => {\n * console.log('Count changed:', count.value);\n * return () => console.log('Cleaning up...');\n * });\n * ```\n */\nexport function effect(fn: EffectFunction, options: EffectOptions = {}): EffectObject {\n if (typeof fn !== 'function') {\n throw new EffectError(ERROR_MESSAGES.EFFECT_MUST_BE_FUNCTION);\n }\n\n const effectInstance = new EffectImpl(fn, options);\n effectInstance.execute();\n\n return effectInstance;\n}\n"],"names":["TIME_CONSTANTS","AsyncState","EFFECT_STATE_FLAGS","COMPUTED_STATE_FLAGS","POOL_CONFIG","SCHEDULER_CONFIG","DEBUG_CONFIG","SMI_MAX","IS_DEV","EMPTY_ERROR_ARRAY","AtomError","message","cause","recoverable","ComputedError","EffectError","SchedulerError","ERROR_MESSAGES","count","DEBUG_NAME","DEBUG_ID","DEBUG_TYPE","NO_DEFAULT_VALUE","hasDependencies","obj","globalCheckEpoch","checkCircularInternal","dep","current","epoch","deps","i","child","debug","condition","type","id","target","nextId","generateId","ReactiveNode","ReactiveDependency","listener","newValue","oldValue","sub","err","collectorEpoch","nextEpoch","currentEpoch","flushEpoch","flushExecutionCount","isFlushing","startFlush","endFlush","incrementFlushExecutionCount","Scheduler","callback","jobs","flushStarted","job","iterations","error","max","scheduler","batch","trackingContext","fn","prev","untracked","SubscriberManager","subscriber","isUnsubscribed","idx","lastIndex","onError","isAtom","isComputed","debugType","isEffect","isPromise","value","isNonNullObject","hasDependencyMethod","isPlainListener","hasExecuteMethod","AtomImpl","initialValue","sync","atom","options","ArrayPool","arr","emptyConst","acquired","released","rejected","totalRejected","EMPTY_DEPS","EMPTY_UNSUBS","EMPTY_VERSIONS","depArrayPool","unsubArrayPool","versionArrayPool","syncDependencies","nextDeps","prevDeps","prevUnsubs","tracker","nextUnsubs","wrapError","ErrorClass","context","errorMessage","ASYNC_STATE_MASK","ASYNC_STATE_LOOKUP","ComputedAtomImpl","_dep","debugObj","errorSet","depErrors","j","unsub","mask","states","committed","result","commitErr","prevVersions","nextVersions","state","collect","originalAdd","ctx","valueChanged","promise","promiseId","resolvedValue","stateChanged","callbackError","computed","EffectImpl","asyncCleanup","trackedCount","unsubscribe","now","history","oneSecondAgo","dependencies","effect","effectInstance"],"mappings":"mOAGO,MAAMA,EAAiB,CAE5B,cAAe,GACjB,EAKaC,EAAa,CACxB,KAAM,OACN,QAAS,UACT,SAAU,WACV,SAAU,UACZ,EAMaC,EAAqB,CAChC,SAAU,EACV,UAAW,CACb,EAMaC,EAAuB,CAClC,MAAO,EACP,KAAM,EACN,QAAS,EACT,SAAU,EACV,SAAU,GACV,YAAa,GACb,UAAW,EACb,EAMaC,GAAc,CAEzB,SAAU,IAEV,YAAa,GACf,EAMaC,EAAmB,CAE9B,0BAA2B,IAE3B,kBAAmB,IAMnB,0BAA2B,IAM3B,yBAA0B,IAG1B,qBAAsB,IAGtB,qBAAsB,EACxB,EAKaC,EAAe,CAE1B,iBAAkB,IAElB,mBAAoB,EACtB,EAMaC,EAAU,WAKVC,EACX,OAAO,QAAY,KAAe,QAAQ,KAAO,QAAQ,IAAI,WAAa,aAM/DC,GAAsC,OAAO,OAAO,EAAE,EC9F5D,MAAMC,UAAkB,KAAM,CAcnC,YAAYC,EAAiBC,EAAsB,KAAMC,EAAuB,GAAM,CACpF,MAAMF,CAAO,EACb,KAAK,KAAO,YACZ,KAAK,MAAQC,EACb,KAAK,YAAcC,EACnB,KAAK,cAAgB,IACvB,CACF,CAQO,MAAMC,UAAsBJ,CAAU,CAM3C,YAAYC,EAAiBC,EAAsB,KAAM,CACvD,MAAMD,EAASC,EAAO,EAAI,EAC1B,KAAK,KAAO,eACd,CACF,CAQO,MAAMG,UAAoBL,CAAU,CAMzC,YAAYC,EAAiBC,EAAsB,KAAM,CACvD,MAAMD,EAASC,EAAO,EAAK,EAC3B,KAAK,KAAO,aACd,CACF,CAQO,MAAMI,UAAuBN,CAAU,CAM5C,YAAYC,EAAiBC,EAAsB,KAAM,CACvD,MAAMD,EAASC,EAAO,EAAK,EAC3B,KAAK,KAAO,gBACd,CACF,CClEO,MAAMK,EAAiB,CAQ5B,0BAA2B,uCAK3B,qCACE,8DAKF,kCAAmC,0DAKnC,4BAA6B,8BAK7B,kCAAmC,oCAKnC,wCAAyC,oCASzC,iCAAkC,gEAKlC,iCAAkC,kDAMlC,kCAAmC,oDASnC,wBAAyB,qCAKzB,wBAAyB,0BAKzB,sBAAuB,2CAkBvB,uBAAyBC,GACvB,oCAAoCA,CAAK,gBAK3C,yBAA0B,mDAM1B,gCAAiC,kDACnC,ECzHaC,SAAmC,WAAW,EAG9CC,UAAiC,IAAI,EAGrCC,SAAmC,MAAM,EAGzCC,SAAyC,gBAAgB,EAGtE,SAASC,GAAgBC,EAAqE,CAC5F,MAAO,iBAAkBA,GAAO,MAAM,QAASA,EAAkC,YAAY,CAC/F,CAEA,IAAIC,EAAmB,EAGvB,SAASC,EAAsBC,EAAiBC,EAAiBC,EAAqB,CACpF,GAAIF,EAAI,gBAAkBE,EAK1B,IAFAF,EAAI,cAAgBE,EAEhBF,IAAQC,EACV,MAAM,IAAId,EAAc,uCAAuC,EAGjE,GAAIS,GAAgBI,CAAG,EAAG,CACxB,MAAMG,EAAOH,EAAI,aACjB,QAASI,EAAI,EAAGA,EAAID,EAAK,OAAQC,IAAK,CACpC,MAAMC,EAAQF,EAAKC,CAAC,EAChBC,GAAON,EAAsBM,EAAOJ,EAASC,CAAK,CACxD,CACF,EACF,CAMO,MAAMI,EAAqB,CAChC,QACE,OAAO,QAAY,KAAgB,QAA2B,KAAK,WAAa,cAElF,gBAAiB3B,EAAa,iBAE9B,iBAAkBA,EAAa,mBAE/B,KAAK4B,EAAoBvB,EAAuB,CAC1C,KAAK,SAAWuB,GAClB,QAAQ,KAAK,iBAAiBvB,CAAO,EAAE,CAE3C,EAOA,cAAcgB,EAAiBC,EAAuB,CACpD,GAAID,IAAQC,EACV,MAAM,IAAId,EAAc,qCAAqC,EAG1D,KAAK,UAIVW,IACAC,EAAsBC,EAAKC,EAASH,CAAgB,EACtD,EAEA,gBAAgBD,EAAaW,EAAcC,EAAwB,CACjE,GAAI,CAAC,KAAK,QACR,OAGF,MAAMC,EAASb,EACfa,EAAOlB,CAAU,EAAI,GAAGgB,CAAI,IAAIC,CAAE,GAClCC,EAAOjB,EAAQ,EAAIgB,EACnBC,EAAOhB,CAAU,EAAIc,CACvB,EAEA,aAAaX,EAAoD,CAC/D,GAAIA,GAAO,MAAQL,KAAcK,EAC/B,OAAQA,EAAgCL,CAAU,CAGtD,EAEA,aAAaK,EAAoD,CAC/D,GAAIA,GAAO,MAAQH,KAAcG,EAC/B,OAAQA,EAAgCH,CAAU,CAGtD,CACF,EAEA,IAAIiB,GAAS,EAGN,MAAMC,GAAa,IAAoBD,KCjGvC,MAAME,CAAa,CAOxB,aAAc,CACZ,KAAK,GAAMD,KAAehC,EAC1B,KAAK,MAAQ,CACf,CACF,CCLO,MAAekC,UAA8BD,CAAa,CAO/D,aAAc,CACZ,MAAA,EACA,KAAK,QAAU,EACf,KAAK,eAAiB,EACxB,CAcA,UAAUE,EAA2E,CAEnF,GAAI,OAAOA,GAAa,UAAYA,IAAa,MAAQ,YAAaA,EACpE,OAAO,KAAK,mBAAmB,IAAIA,CAAQ,EAG7C,GAAI,OAAOA,GAAa,WACtB,MAAM,IAAIhC,EAAUO,EAAe,gCAAgC,EAErE,OAAO,KAAK,qBAAqB,IAAIyB,CAAQ,CAC/C,CAKA,iBAA0B,CACxB,OAAO,KAAK,qBAAqB,KAAO,KAAK,mBAAmB,IAClE,CAQU,mBAAmBC,EAAyBC,EAA+B,CACnF,KAAK,qBAAqB,YACvBC,GAAQA,EAAIF,EAAUC,CAAQ,EAC9BE,GACC,QAAQ,MAAM,IAAIpC,EAAUO,EAAe,kCAAmC6B,CAAY,CAAC,CAAA,EAG/F,KAAK,mBAAmB,YACrBD,GAAQA,EAAI,QAAA,EACZC,GACC,QAAQ,MAAM,IAAIpC,EAAUO,EAAe,kCAAmC6B,CAAY,CAAC,CAAA,CAEjG,CACF,CC9EA,IAAIC,EAAiB,EAMd,SAASC,GAAoB,CAClC,OAAAD,GAAmBA,EAAiB,EAAK,GAAKxC,EACvCwC,CACT,CAGO,SAASE,IAAuB,CACrC,OAAOF,CACT,CAIO,IAAIG,EAAa,EACbC,EAAsB,EAC7BC,EAAa,GAOV,SAASC,GAAsB,CACpC,OAAID,GACE5C,GACF,QAAQ,KACN,+FAAA,EAGG,KAGT4C,EAAa,GACbF,EAAcA,EAAa,EAAK3C,EAChC4C,EAAsB,EACf,GACT,CAGO,SAASG,GAAiB,CAC/BF,EAAa,EACf,CAOO,SAASG,IAAuC,CACrD,OAAKH,EACE,EAAED,EADe,CAE1B,CCtCA,MAAMK,EAAU,CAAhB,aAAA,CACE,KAAQ,OAAyB,CAAA,EACjC,KAAQ,OAAyB,CAAA,EACjC,KAAQ,MAAwB,KAAK,OACrC,KAAQ,UAAY,EACpB,KAAQ,OAAS,EACjB,KAAQ,aAAwB,GAChC,KAAO,WAAsB,GAC7B,KAAQ,WAAqB,EAC7B,KAAQ,WAA6B,CAAA,EACrC,KAAQ,eAAiB,EACzB,KAAQ,eAA0B,GAClC,KAAQ,mBAA6BnD,EAAiB,oBAAA,CAEtD,IAAI,OAAwB,CAC1B,OAAI,KAAK,cAAgB,KAAK,eACrB,EAEL,KAAK,WACA,EAEF,CACT,CAQA,SAASoD,EAA8B,CACrC,GAAI,OAAOA,GAAa,WACtB,MAAM,IAAIzC,EAAe,uCAAuC,EAI9DyC,EAAS,aAAe,KAAK,SACjCA,EAAS,WAAa,KAAK,OAEvB,KAAK,YAAc,KAAK,eAC1B,KAAK,WAAW,KAAK,gBAAgB,EAAIA,GAEzC,KAAK,MAAM,KAAK,WAAW,EAAIA,EAC1B,KAAK,cACR,KAAK,MAAA,GAGX,CAEQ,OAAc,CACpB,GAAI,KAAK,cAAgB,KAAK,YAAc,EAAG,OAE/C,KAAK,aAAe,GAGpB,MAAMC,EAAO,KAAK,MACZxC,EAAQ,KAAK,UAEnB,KAAK,MAAQ,KAAK,QAAU,KAAK,OAAS,KAAK,OAAS,KAAK,OAC7D,KAAK,UAAY,EACjB,KAAK,SAEL,eAAe,IAAM,CACnB,MAAMyC,EAAeN,EAAA,EAErB,KAAK,aAAaK,EAAMxC,CAAK,EAE7B,KAAK,aAAe,GAEhByC,GAAcL,EAAA,EAEd,KAAK,UAAY,GAAK,CAAC,KAAK,YAC9B,KAAK,MAAA,CAET,CAAC,CACH,CAEQ,WAAkB,CACxB,KAAK,eAAiB,GACtB,MAAMK,EAAeN,EAAA,EAErB,GAAI,CACF,KAAK,iBAAA,EACL,KAAK,YAAA,CACP,QAAA,CACE,KAAK,eAAiB,GAClBM,GAAcL,EAAA,CACpB,CACF,CAEQ,kBAAyB,CAE/B,GADA,KAAK,SACD,KAAK,eAAiB,EAAG,CAC3B,QAASvB,EAAI,EAAGA,EAAI,KAAK,eAAgBA,IAAK,CAC5C,MAAM6B,EAAM,KAAK,WAAW7B,CAAC,EACzB6B,GAAOA,EAAI,aAAe,KAAK,SACjCA,EAAI,WAAa,KAAK,OACtB,KAAK,MAAM,KAAK,WAAW,EAAIA,EAEnC,CACA,KAAK,eAAiB,CACxB,CACF,CAEQ,aAAoB,CAC1B,IAAIC,EAAa,EAEjB,KAAO,KAAK,UAAY,GAAG,CACzB,GAAI,EAAEA,EAAa,KAAK,mBAAoB,CAC1C,KAAK,qBAAA,EACL,KACF,CAEA,KAAK,qBAAA,EACL,KAAK,iBAAA,CACP,CACF,CAEQ,sBAA6B,CACnC,MAAMH,EAAO,KAAK,MACZxC,EAAQ,KAAK,UAEnB,KAAK,MAAQ,KAAK,QAAU,KAAK,OAAS,KAAK,OAAS,KAAK,OAC7D,KAAK,UAAY,EACjB,KAAK,SAEL,KAAK,aAAawC,EAAMxC,CAAK,CAC/B,CAEQ,sBAA6B,CACnC,QAAQ,MACN,IAAIF,EACF,6BAA6B,KAAK,kBAAkB,qCAAA,CACtD,EAEF,KAAK,UAAY,EACjB,KAAK,MAAM,OAAS,EACpB,KAAK,eAAiB,CACxB,CAEQ,aAAa0C,EAAsBxC,EAAqB,CAC9D,QAASa,EAAI,EAAGA,EAAIb,EAAOa,IACzB,GAAI,CACF2B,EAAK3B,CAAC,IAAA,CACR,OAAS+B,EAAO,CACd,QAAQ,MACN,IAAI9C,EAAe,4CAA6C8C,CAAc,CAAA,CAElF,CAEFJ,EAAK,OAAS,CAChB,CAGA,YAAmB,CACjB,KAAK,aACL,KAAK,WAAa,EACpB,CAKA,UAAiB,CACf,KAAK,WAAa,KAAK,IAAI,EAAG,KAAK,WAAa,CAAC,EAE7C,KAAK,aAAe,IACtB,KAAK,UAAA,EACL,KAAK,WAAa,GAEtB,CAOA,sBAAsBK,EAAmB,CACvC,GAAIA,EAAM1D,EAAiB,qBACzB,MAAM,IAAIW,EACR,yCAAyCX,EAAiB,oBAAoB,EAAA,EAGlF,KAAK,mBAAqB0D,CAC5B,CACF,CAEO,MAAMC,EAAY,IAAIR,GC9KtB,SAASS,GAASR,EAAsB,CAC7C,GAAI,OAAOA,GAAa,WACtB,MAAM,IAAI/C,EAAU,mCAAmC,EAGzDsD,EAAU,WAAA,EAEV,GAAI,CACF,OAAOP,EAAA,CACT,QAAA,CACEO,EAAU,SAAA,CACZ,CACF,CC5BO,MAAME,EAAmC,CAC9C,QAAS,KAET,IAAOxB,EAAoByB,EAAgB,CACzC,MAAMC,EAAO,KAAK,QAClB,KAAK,QAAU1B,EACf,GAAI,CACF,OAAOyB,EAAA,CACT,QAAA,CACE,KAAK,QAAUC,CACjB,CACF,EAEA,YAA8B,CAC5B,OAAO,KAAK,OACd,CACF,ECNO,SAASC,EAAaF,EAAgB,CAC3C,GAAI,OAAOA,GAAO,WAChB,MAAM,IAAIzD,EAAU,uCAAuC,EAG7D,MAAM0D,EAAOF,EAAgB,QAC7BA,EAAgB,QAAU,KAE1B,GAAI,CACF,OAAOC,EAAA,CACT,QAAA,CACED,EAAgB,QAAUE,CAC5B,CACF,CCnCO,MAAME,CAAqB,CAA3B,aAAA,CACL,KAAQ,YAA0B,IAAA,CAGlC,IAAIC,EAA2B,CAK7B,GAJK,KAAK,cACR,KAAK,YAAc,CAAA,GAGjB,KAAK,YAAY,QAAQA,CAAU,IAAM,GAC3C,MAAO,IAAM,CAAC,EAGhB,KAAK,YAAY,KAAKA,CAAU,EAEhC,IAAIC,EAAiB,GACrB,MAAO,IAAM,CACPA,IACJA,EAAiB,GACjB,KAAK,OAAOD,CAAU,EACxB,CACF,CAGA,OAAOA,EAAwB,CAC7B,GAAI,CAAC,KAAK,YACR,MAAO,GAGT,MAAME,EAAM,KAAK,YAAY,QAAQF,CAAU,EAC/C,GAAIE,IAAQ,GACV,MAAO,GAGT,MAAMC,EAAY,KAAK,YAAY,OAAS,EAC5C,OAAID,IAAQC,IACV,KAAK,YAAYD,CAAG,EAAI,KAAK,YAAYC,CAAS,GAEpD,KAAK,YAAY,IAAA,EAEV,EACT,CAEA,IAAIH,EAAwB,CAC1B,OAAK,KAAK,YACH,KAAK,YAAY,QAAQA,CAAU,IAAM,GADlB,EAEhC,CAEA,QAAQJ,EAAkD,CACxD,GAAK,KAAK,YAEV,QAASpC,EAAI,EAAGA,EAAI,KAAK,YAAY,OAAQA,IAC3CoC,EAAG,KAAK,YAAYpC,CAAC,EAAIA,CAAC,CAE9B,CAGA,YAAYoC,EAA4CQ,EAAwC,CAC9F,GAAK,KAAK,YAEV,QAAS5C,EAAI,EAAGA,EAAI,KAAK,YAAY,OAAQA,IAC3C,GAAI,CACFoC,EAAG,KAAK,YAAYpC,CAAC,EAAIA,CAAC,CAC5B,OAAS+B,EAAO,CACVa,EACFA,EAAQb,CAAc,EAEtB,QAAQ,MAAM,oDAAqDA,CAAK,CAE5E,CAEJ,CAEA,IAAI,MAAe,CACjB,OAAO,KAAK,aAAa,QAAU,CACrC,CAEA,IAAI,gBAA0B,CAC5B,OAAO,KAAK,cAAgB,MAAQ,KAAK,YAAY,OAAS,CAChE,CAEA,OAAc,CACZ,KAAK,YAAc,IACrB,CAEA,SAAe,CACb,OAAO,KAAK,YAAc,CAAC,GAAG,KAAK,WAAW,EAAI,CAAA,CACpD,CACF,CCnFO,SAASc,EAAOpD,EAAmC,CACxD,OACEA,IAAQ,MACR,OAAOA,GAAQ,UACf,UAAWA,GACX,cAAeA,GACf,OAAQA,EAAgC,WAAc,UAE1D,CAGO,SAASqD,GAAWrD,EAAmC,CAC5D,GAAIS,EAAM,UAAYT,GAAQ,MAA6B,OAAOA,GAAQ,UAAW,CACnF,MAAMsD,EAAY7C,EAAM,aAAaT,CAAG,EACxC,GAAIsD,EACF,OAAOA,IAAc,UAEzB,CACA,OACEF,EAAOpD,CAAG,GACV,eAAgBA,GAChB,OAAQA,EAAgC,YAAe,UAE3D,CAGO,SAASuD,GAASvD,EAAmC,CAC1D,OACEA,IAAQ,MACR,OAAOA,GAAQ,UACf,YAAaA,GACb,QAASA,GACT,OAAQA,EAAgC,SAAY,YACpD,OAAQA,EAAgC,KAAQ,UAEpD,CAYO,SAASwD,EAAaC,EAAqC,CAChE,OAAOA,GAAS,MAAQ,OAAQA,EAA6B,MAAS,UACxE,CAGA,SAASC,GAAgBD,EAAkD,CACzE,OAAO,OAAOA,GAAU,UAAYA,IAAU,IAChD,CAGO,SAASE,GAAoBF,EAA+C,CACjF,OACG,OAAOA,GAAU,UAAY,OAAOA,GAAU,aAC/CA,IAAU,MACV,OAAQA,EAA+B,eAAkB,UAE7D,CAYO,SAASG,GAAgBH,EAAqC,CACnE,OACE,OAAOA,GAAU,YAAc,OAAQA,EAA4B,eAAkB,UAEzF,CAGO,SAASI,GAAiBJ,EAA+C,CAC9E,OAAOC,GAAgBD,CAAK,GAAK,OAAOA,EAAM,SAAY,UAC5D,CC/EA,MAAMK,WAAoB7C,CAAiD,CAWzE,YAAY8C,EAAiBC,EAAe,CAC1C,MAAA,EAHF,KAAQ,yBAAoC,GAI1C,KAAK,OAASD,EACd,KAAK,0BAA4B,IAAIjB,EACrC,KAAK,wBAA0B,IAAIA,EACnC,KAAK,MAAQkB,EACb,KAAK,YAAc,KAAK,oBAAoB,KAAK,IAAI,EACrDvD,EAAM,gBAAgB,KAAM,OAAQ,KAAK,EAAE,CAC7C,CAGA,IAAc,sBAAgF,CAC5F,OAAO,KAAK,yBACd,CAGA,IAAc,oBAAoD,CAChE,OAAO,KAAK,uBACd,CAKA,IAAI,OAAW,CACb,MAAML,EAAUsC,EAAgB,WAAA,EAChC,OAAItC,GAAS,KAAK,OAAOA,CAAO,EACzB,KAAK,MACd,CAMA,IAAI,MAAMe,EAAa,CACrB,GAAI,OAAO,GAAG,KAAK,OAAQA,CAAQ,EAAG,OAEtC,MAAMC,EAAW,KAAK,OACtB,KAAK,QAAW,KAAK,QAAU,EAAKrC,EACpC,KAAK,OAASoC,EAIZ,GAAC,KAAK,0BAA0B,gBAChC,CAAC,KAAK,wBAAwB,iBAIhC,KAAK,sBAAsBC,CAAQ,CACrC,CAEQ,OAAOhB,EAAwB,CAErC,GAAIuD,GAAoBvD,CAAO,EAAG,CAChCA,EAAQ,cAAc,IAAI,EAC1B,MACF,CAEA,GAAIwD,GAAgBxD,CAAO,EAAG,CAC5B,KAAK,0BAA0B,IAAIA,CAA+C,EAClF,MACF,CAEIyD,GAAiBzD,CAAO,GAC1B,KAAK,wBAAwB,IAAIA,CAAO,CAE5C,CAEQ,sBAAsBgB,EAAmB,CAC1C,KAAK,2BACR,KAAK,iBAAmBA,EACxB,KAAK,yBAA2B,IAI9B,KAAK,OAAS,CAACoB,EAAU,WAC3B,KAAK,oBAAA,EAELA,EAAU,SAAS,KAAK,WAAW,CAEvC,CAEQ,qBAA4B,CAClC,GAAI,CAAC,KAAK,yBAA0B,OAEpC,MAAMpB,EAAW,KAAK,iBAChBD,EAAW,KAAK,OAEtB,KAAK,iBAAmB,OACxB,KAAK,yBAA2B,GAEhC,KAAK,mBAAmBA,EAAUC,CAAQ,CAC5C,CAKA,MAAU,CACR,OAAO,KAAK,MACd,CAKA,SAAgB,CACd,KAAK,0BAA0B,MAAA,EAC/B,KAAK,wBAAwB,MAAA,EAC7B,KAAK,OAAS,MAChB,CACF,CAoBO,SAAS6C,GAAQF,EAAiBG,EAAuB,GAAqB,CACnF,OAAO,IAAIJ,GAASC,EAAcG,EAAQ,MAAQ,EAAK,CACzD,CCnJO,MAAMC,CAAa,CAAnB,aAAA,CACL,KAAQ,KAAc,CAAA,EACtB,KAAiB,YAAc,GAC/B,KAAiB,oBAAsB,IAEvC,KAAQ,MAAQnF,EACZ,CACE,SAAU,EACV,SAAU,EACV,SAAU,CAAE,OAAQ,EAAG,SAAU,EAAG,SAAU,CAAA,CAAE,EAElD,IAAA,CAGJ,SAAe,CACb,OAAIA,GAAU,KAAK,OAAO,KAAK,MAAM,WAC9B,KAAK,KAAK,IAAA,GAAS,CAAA,CAC5B,CAQA,QAAQoF,EAAUC,EAAiC,CACjD,GAAI,EAAAA,GAAcD,IAAQC,GAE1B,IAAI,OAAO,SAASD,CAAG,EAAG,CACpBpF,GAAU,KAAK,OAAO,KAAK,MAAM,SAAS,SAC9C,MACF,CAEA,GAAIoF,EAAI,OAAS,KAAK,oBAAqB,CACrCpF,GAAU,KAAK,OAAO,KAAK,MAAM,SAAS,WAC9C,MACF,CAEA,GAAI,KAAK,KAAK,QAAU,KAAK,YAAa,CACpCA,GAAU,KAAK,OAAO,KAAK,MAAM,SAAS,WAC9C,MACF,CAEAoF,EAAI,OAAS,EACb,KAAK,KAAK,KAAKA,CAAG,EACdpF,GAAU,KAAK,OAAO,KAAK,MAAM,WACvC,CAGA,UAA6B,CAC3B,GAAI,CAACA,GAAU,CAAC,KAAK,MAAO,OAAO,KACnC,KAAM,CAAE,SAAAsF,EAAU,SAAAC,EAAU,SAAAC,CAAA,EAAa,KAAK,MACxCC,EAAgBD,EAAS,OAASA,EAAS,SAAWA,EAAS,SACrE,MAAO,CACL,SAAAF,EACA,SAAAC,EACA,SAAAC,EACA,OAAQF,EAAWC,EAAWE,EAC9B,SAAU,KAAK,KAAK,MAAA,CAExB,CAGA,OAAc,CACZ,KAAK,KAAK,OAAS,EACfzF,GAAU,KAAK,QACjB,KAAK,MAAM,SAAW,EACtB,KAAK,MAAM,SAAW,EACtB,KAAK,MAAM,SAAW,CAAE,OAAQ,EAAG,SAAU,EAAG,SAAU,CAAA,EAE9D,CACF,CC3EO,MAAM0F,EAAa,OAAO,OAAO,EAAE,EAE7BC,EAAe,OAAO,OAAO,EAAE,EAE/BC,EAAiB,OAAO,OAAO,EAAE,EAGjCC,EAAe,IAAIV,EAEnBW,EAAiB,IAAIX,EACrBY,EAAmB,IAAIZ,ECE7B,SAASa,GACdC,EACAC,EACAC,EACAC,EACgB,CAEhB,GAAIF,IAAaR,GAAcS,IAAeR,EAC5C,QAASpE,EAAI,EAAGA,EAAI2E,EAAS,OAAQ3E,IAAK,CACxC,MAAMJ,EAAM+E,EAAS3E,CAAC,EAClBJ,IAAKA,EAAI,WAAagF,EAAW5E,CAAC,EACxC,CAIF,MAAM8E,EAAaP,EAAe,QAAA,EAGlCO,EAAW,OAASJ,EAAS,OAE7B,QAAS1E,EAAI,EAAGA,EAAI0E,EAAS,OAAQ1E,IAAK,CACxC,MAAMJ,EAAM8E,EAAS1E,CAAC,EACjBJ,IAEDA,EAAI,YAENkF,EAAW9E,CAAC,EAAIJ,EAAI,WACpBA,EAAI,WAAa,SAEjBM,EAAM,cAAcN,EAAKiF,CAAO,EAChCC,EAAW9E,CAAC,EAAIJ,EAAI,UAAUiF,CAAO,GAEzC,CAGA,GAAIF,IAAaR,EACf,QAASnE,EAAI,EAAGA,EAAI2E,EAAS,OAAQ3E,IAAK,CACxC,MAAMJ,EAAM+E,EAAS3E,CAAC,EAClBJ,GAAK,aAEPA,EAAI,WAAA,EACJA,EAAI,WAAa,OAErB,CAIF,OAAIgF,IAAeR,GACjBG,EAAe,QAAQK,CAAU,EAG5BE,CACT,CC3CO,SAASC,EACdhD,EACAiD,EACAC,EACW,CACX,GAAIlD,aAAiB,UACnB,OAAO,IAAIiD,EAAW,eAAeC,CAAO,MAAMlD,EAAM,OAAO,GAAIA,CAAK,EAE1E,GAAIA,aAAiB,eACnB,OAAO,IAAIiD,EAAW,oBAAoBC,CAAO,MAAMlD,EAAM,OAAO,GAAIA,CAAK,EAE/E,GAAIA,aAAiBpD,EACnB,OAAOoD,EAIT,MAAMmD,EAAenD,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACpElD,EAAQkD,aAAiB,MAAQA,EAAQ,KAC/C,OAAO,IAAIiD,EAAW,qBAAqBC,CAAO,MAAMC,CAAY,GAAIrG,CAAK,CAC/E,CCTA,MAAMsG,GACJ/G,EAAqB,SAAWA,EAAqB,QAAUA,EAAqB,SAChFgH,EAAqB,MAAMD,GAAmB,CAAC,EAAE,KAAKjH,EAAW,IAAI,EAC3EkH,EAAmBhH,EAAqB,QAAQ,EAAIF,EAAW,SAC/DkH,EAAmBhH,EAAqB,OAAO,EAAIF,EAAW,QAC9DkH,EAAmBhH,EAAqB,QAAQ,EAAIF,EAAW,SAU/D,MAAMmH,WAA4B3E,CAA6D,CA0B7F,YAAY0B,EAA0BuB,EAA8B,GAAI,CACtE,GAAI,OAAOvB,GAAO,WAChB,MAAM,IAAIrD,EAAcG,EAAe,yBAAyB,EA2ClE,GAxCA,MAAA,EAZF,KAAQ,cAAyC,KACjD,KAAQ,iBAAmB,GAazB,KAAK,OAAS,OACd,KAAK,MAAQd,EAAqB,MAAQA,EAAqB,KAE/D,KAAK,OAAS,KACd,KAAK,WAAa,EAClB,KAAK,OAASuF,EAAQ,OAAS,OAAO,GAEtC,KAAK,IAAMvB,EACX,KAAK,cAAgB,iBAAkBuB,EAAUA,EAAQ,aAAgBpE,EACzE,KAAK,iBAAmB,KAAK,gBAAmBA,EAChD,KAAK,SAAWoE,EAAQ,SAAW,KACnC,KAAK,eAAiB,OAAO,iBAAmB,EAEhD,KAAK,0BAA4B,IAAIpB,EACrC,KAAK,wBAA0B,IAAIA,EAEnC,KAAK,cAAgB4B,EACrB,KAAK,oBAAsBE,EAC3B,KAAK,cAAgBD,EAErB,KAAK,WAAa,IAAM,CACtB,KAAK,0BAA0B,YAC5B5B,GAAeA,EAAA,EACfzB,GAAQ,QAAQ,MAAMA,CAAG,CAAA,EAG5B,KAAK,wBAAwB,YAC1ByB,GAAeA,EAAW,QAAA,EAC1BzB,GAAQ,QAAQ,MAAMA,CAAG,CAAA,CAE9B,EAEA,KAAK,WAAa,OAAO,OAAO,IAAM,KAAK,aAAc,CACvD,cAAgBuE,GAAqB,CAAC,CAAA,CACvC,EAEDpF,EAAM,gBAAgB,KAAoC,WAAY,KAAK,EAAE,EAEzEA,EAAM,QAAS,CACjB,MAAMqF,EAAW,KAMjBA,EAAS,gBAAkB,IACzB,KAAK,0BAA0B,KAAO,KAAK,wBAAwB,KACrEA,EAAS,QAAU,IAAM,KAAK,SAAA,EAC9BA,EAAS,aAAe,KAAK,cAC7BA,EAAS,WAAa,KAAK,kBAAA,CAC7B,CAEA,GAAI5B,EAAQ,OAAS,GACnB,GAAI,CACF,KAAK,WAAA,CACP,MAAQ,CAER,CAEJ,CAEA,IAAc,sBAAgF,CAC5F,OAAO,KAAK,yBACd,CAEA,IAAc,oBAAoD,CAChE,OAAO,KAAK,uBACd,CAEA,IAAI,OAAW,CAGb,YAAK,kBAAA,EACU,KAAK,cAAA,CAEtB,CAEA,MAAU,CACR,OAAO,KAAK,MACd,CAEA,IAAI,OAAwB,CAC1B,YAAK,kBAAA,EACE,KAAK,eAAA,CACd,CAEA,IAAI,UAAoB,CAItB,GAHA,KAAK,kBAAA,EAGD,KAAK,cACP,MAAO,GAIT,QAAS3D,EAAI,EAAGA,EAAI,KAAK,cAAc,OAAQA,IAAK,CAClD,MAAMJ,EAAM,KAAK,cAAcI,CAAC,EAChC,GAAIJ,GAAO,aAAcA,GAAQA,EAAyC,SACxE,MAAO,EAEX,CAEA,MAAO,EACT,CAEA,IAAI,SAAmB,CACrB,MAAO,CAAC,KAAK,QACf,CAEA,IAAI,QAA2B,CAI7B,GAHA,KAAK,kBAAA,EAGD,CAAC,KAAK,SACR,OAAOlB,GAIT,MAAMoB,EAAQoB,GAAA,EACd,GAAI,KAAK,mBAAqBpB,GAAS,KAAK,gBAAkB,KAC5D,OAAO,KAAK,cAId,MAAM0F,MAAe,IAGjB,KAAK,QACPA,EAAS,IAAI,KAAK,MAAM,EAI1B,QAASxF,EAAI,EAAGA,EAAI,KAAK,cAAc,OAAQA,IAAK,CAClD,MAAMJ,EAAM,KAAK,cAAcI,CAAC,EAChC,GAAIJ,GAAO,WAAYA,EAAK,CAC1B,MAAM6F,EAAa7F,EAAyC,OAC5D,QAAS8F,EAAI,EAAGA,EAAID,EAAU,OAAQC,IAAK,CACzC,MAAM3E,EAAM0E,EAAUC,CAAC,EACnB3E,GACFyE,EAAS,IAAIzE,CAAG,CAEpB,CACF,CACF,CAGA,YAAK,cAAgB,OAAO,OAAO,CAAC,GAAGyE,CAAQ,CAAC,EAChD,KAAK,iBAAmB1F,EAEjB,KAAK,aACd,CAEA,IAAI,WAA0B,CAC5B,YAAK,kBAAA,EACE,KAAK,MACd,CAEA,IAAI,WAAqB,CACvB,YAAK,kBAAA,EACE,KAAK,WAAA,CACd,CAEA,IAAI,YAAsB,CACxB,YAAK,kBAAA,EACE,KAAK,YAAA,CACd,CAEA,YAAmB,CACjB,KAAK,WAAA,EACD,KAAK,sBAAwBuE,IAC/BG,EAAiB,QAAQ,KAAK,mBAAmB,EACjD,KAAK,oBAAsBH,GAG7B,KAAK,iBAAmB,GACxB,KAAK,cAAgB,IACvB,CAEA,SAAgB,CACd,GAAI,KAAK,gBAAkBD,EAAc,CACvC,QAASpE,EAAI,EAAGA,EAAI,KAAK,cAAc,OAAQA,IAAK,CAClD,MAAM2F,EAAQ,KAAK,cAAc3F,CAAC,EAC9B2F,GAAOA,EAAA,CACb,CACApB,EAAe,QAAQ,KAAK,aAAa,EACzC,KAAK,cAAgBH,CACvB,CAEI,KAAK,gBAAkBD,IACzBG,EAAa,QAAQ,KAAK,aAAa,EACvC,KAAK,cAAgBH,GAGnB,KAAK,sBAAwBE,IAC/BG,EAAiB,QAAQ,KAAK,mBAAmB,EACjD,KAAK,oBAAsBH,GAG7B,KAAK,0BAA0B,MAAA,EAC/B,KAAK,wBAAwB,MAAA,EAC7B,KAAK,MAAQjG,EAAqB,MAAQA,EAAqB,KAC/D,KAAK,OAAS,KACd,KAAK,OAAS,OACd,KAAK,YAAc,KAAK,WAAa,GAAK,KAAK,eAE/C,KAAK,cAAgB,KACrB,KAAK,iBAAmB,EAC1B,CAGQ,UAAoB,CAC1B,OAAQ,KAAK,MAAQA,EAAqB,SAAW,CACvD,CAEQ,WAAkB,CACxB,KAAK,OAASA,EAAqB,KACrC,CAEQ,aAAoB,CAC1B,KAAK,OAAS,EAChB,CAEQ,SAAmB,CACzB,OAAQ,KAAK,MAAQA,EAAqB,QAAU,CACtD,CAEQ,UAAiB,CACvB,KAAK,OAASA,EAAqB,KACnC,KAAK,OAAS,GAKhB,CAEQ,YAAsB,CAC5B,OAAQ,KAAK,MAAQA,EAAqB,WAAa,CACzD,CAEQ,aAAoB,CAC1B,KAAK,OAASA,EAAqB,QACnC,KAAK,OAAS,GAKhB,CAEQ,aAAuB,CAC7B,OAAQ,KAAK,MAAQA,EAAqB,YAAc,CAC1D,CAEQ,cAAqB,CAC3B,KAAK,OAASA,EAAqB,SACnC,KAAK,OAAS,GAMhB,CAEQ,aAAuB,CAC7B,OAAQ,KAAK,MAAQA,EAAqB,YAAc,CAC1D,CAEQ,cAAqB,CAC3B,KAAK,OAASA,EAAqB,SAAWA,EAAqB,UACnE,KAAK,OAAS,GAKhB,CAEQ,gBAA0B,CAChC,OAAQ,KAAK,MAAQA,EAAqB,eAAiB,CAC7D,CAEQ,gBAAgB8E,EAAsB,CAC5C,MAAM0C,EAAOxH,EAAqB,YAClC,KAAK,MAAS,KAAK,MAAQ,CAACwH,EAAS,CAAC,OAAO1C,CAAK,EAAI0C,CACxD,CAEQ,gBAAiC,CACvC,OAAOR,EAAmB,KAAK,MAAQD,EAAgB,CACzD,CAEQ,mBAA4B,CAClC,MAAMU,EAAmB,CAAA,EACzB,OAAI,KAAK,SAAA,GAAYA,EAAO,KAAK,OAAO,EACpC,KAAK,QAAA,GAAWA,EAAO,KAAK,MAAM,EAClC,KAAK,WAAA,GAAcA,EAAO,KAAK,SAAS,EACxC,KAAK,YAAA,GAAeA,EAAO,KAAK,UAAU,EAC1C,KAAK,YAAA,GAAeA,EAAO,KAAK,UAAU,EAC1C,KAAK,eAAA,GAAkBA,EAAO,KAAK,aAAa,EAC7CA,EAAO,KAAK,KAAK,CAC1B,CAEQ,eAAmB,CACzB,OAAI,KAAK,iBAAyB,KAAK,SAEnC,KAAK,SAAA,GAAc,KAAK,YAC1B,KAAK,WAAA,EAGH,KAAK,WAAA,EAAqB,KAAK,eAAA,EAC/B,KAAK,YAAA,EAAsB,KAAK,gBAAA,EAE7B,KAAK,OACd,CAEQ,YAAmB,CACzB,GAAI,KAAK,iBAAkB,OAE3B,KAAK,gBAAgB,EAAI,EAEzB,MAAMZ,EAAU,KAAK,2BAAA,EACrB,IAAIa,EAAY,GAEhB,GAAI,CACF,MAAMC,EAAS5D,EAAgB,IAAI,KAAK,WAAY,KAAK,GAAG,EAE5D,KAAK,oBAAoB8C,CAAO,EAChCa,EAAY,GAEZ7C,EAAU8C,CAAM,EAAI,KAAK,wBAAwBA,CAAM,EAAI,KAAK,kBAAkBA,CAAM,CAC1F,OAAShF,EAAK,CACZ,GAAI,CAAC+E,EACH,GAAI,CACF,KAAK,oBAAoBb,CAAO,EAChCa,EAAY,EACd,OAASE,EAAW,CAClB,KAAK,wBAAwBA,CAAS,CACxC,CAEF,KAAK,wBAAwBjF,CAAG,CAClC,QAAA,CACE,KAAK,gBAAgBkE,EAASa,CAAS,EACvC,KAAK,gBAAgB,EAAK,CAC5B,CACF,CAEQ,4BAA6B,CACnC,MAAMnB,EAAW,KAAK,cAChBsB,EAAe,KAAK,oBACpBvB,EAAWJ,EAAa,QAAA,EACxB4B,EAAe1B,EAAiB,QAAA,EAChC1E,EAAQmB,EAAA,EACRkF,EAAQ,CAAE,SAAU,CAAA,EAEpBC,EAAWxG,GAAoB,CAC/BA,EAAI,iBAAmBE,IAC3BF,EAAI,eAAiBE,EAEjBqG,EAAM,SAAWzB,EAAS,QAC5BA,EAASyB,EAAM,QAAQ,EAAIvG,EAC3BsG,EAAaC,EAAM,QAAQ,EAAIvG,EAAI,UAEnC8E,EAAS,KAAK9E,CAAG,EACjBsG,EAAa,KAAKtG,EAAI,OAAO,GAE/BuG,EAAM,WACR,EAEME,EAAc,KAAK,WAAW,cACpC,YAAK,WAAW,cAAgBD,EAEzB,CAAE,SAAAzB,EAAU,aAAAsB,EAAc,SAAAvB,EAAU,aAAAwB,EAAc,YAAAG,EAAa,MAAAF,CAAA,CACxE,CAEQ,oBAAoBG,EAKnB,CACP,KAAM,CAAE,SAAA5B,EAAU,aAAAwB,EAAc,MAAAC,EAAO,SAAAxB,GAAa2B,EAEpD5B,EAAS,OAASyB,EAAM,SACxBD,EAAa,OAASC,EAAM,SAE5B,KAAK,cAAgB1B,GAAiBC,EAAUC,EAAU,KAAK,cAAe,IAAI,EAClF,KAAK,cAAgBD,EACrB,KAAK,oBAAsBwB,CAC7B,CAEQ,gBACNI,EAOAR,EACM,CACN,KAAK,WAAW,cAAgBQ,EAAI,YAEhCR,GACEQ,EAAI,WAAanC,GACnBG,EAAa,QAAQgC,EAAI,QAAQ,EAE/BA,EAAI,eAAiBjC,GACvBG,EAAiB,QAAQ8B,EAAI,YAAY,IAG3ChC,EAAa,QAAQgC,EAAI,QAAQ,EACjC9B,EAAiB,QAAQ8B,EAAI,YAAY,EAE7C,CAEQ,kBAAkBP,EAAiB,CACzC,MAAMQ,EAAe,CAAC,KAAK,YAAA,GAAiB,CAAC,KAAK,OAAO,KAAK,OAAQR,CAAM,EAC5E,KAAK,QAAW,KAAK,QAAU,OAAOQ,CAAY,EAAK/H,EAEvD,KAAK,OAASuH,EACd,KAAK,YAAA,EACL,KAAK,aAAA,EACL,KAAK,OAAS,KACd,KAAK,gBAAgB,EAAK,EAE1B,KAAK,cAAgB,KACrB,KAAK,iBAAmB,EAC1B,CAEQ,wBAAwBS,EAA2B,CACzD,KAAK,YAAA,EACL,KAAK,YAAA,EACL,KAAK,WAAA,EAEL,KAAK,WAAa,KAAK,YAAc,KAAK,eAAiB,EAAI,KAAK,WAAa,EACjF,MAAMC,EAAY,KAAK,WAEvBD,EACG,KAAME,GAAkB,CACnBD,IAAc,KAAK,YACvB,KAAK,uBAAuBC,CAAa,CAC3C,CAAC,EACA,MAAO3F,GAAQ,CACV0F,IAAc,KAAK,YACvB,KAAK,sBAAsB1F,CAAG,CAChC,CAAC,CACL,CAEQ,uBAAuB2F,EAAwB,CACrD,MAAMH,EAAe,CAAC,KAAK,YAAA,GAAiB,CAAC,KAAK,OAAO,KAAK,OAAQG,CAAa,EACnF,KAAK,QAAW,KAAK,QAAU,OAAOH,CAAY,EAAK/H,EAEvD,KAAK,OAASkI,EACd,KAAK,YAAA,EACL,KAAK,aAAA,EACL,KAAK,OAAS,KACd,KAAK,gBAAgB,EAAK,EAE1B,KAAK,cAAgB,KACrB,KAAK,iBAAmB,GAGxB,KAAK,WAAA,CACP,CAEQ,sBAAsB3F,EAAoB,CAChD,MAAMgB,EAAQgD,EAAUhE,EAAKhC,EAAeG,EAAe,iCAAiC,EAGtFyH,EAAe,CAAC,KAAK,YAAA,EAQ3B,GAPA,KAAK,QAAW,KAAK,QAAU,OAAOA,CAAY,EAAKnI,EAEvD,KAAK,OAASuD,EACd,KAAK,aAAA,EACL,KAAK,YAAA,EACL,KAAK,gBAAgB,EAAK,EAEtB,KAAK,SACP,GAAI,CACF,KAAK,SAASA,CAAK,CACrB,OAAS6E,EAAe,CACtB,QAAQ,MAAM1H,EAAe,gCAAiC0H,CAAa,CAC7E,CAGF,KAAK,WAAA,CACP,CAEQ,wBAAwB7F,EAAqB,CACnD,MAAMgB,EAAQgD,EAAUhE,EAAKhC,EAAeG,EAAe,2BAA2B,EAOtF,GALA,KAAK,OAAS6C,EACd,KAAK,aAAA,EACL,KAAK,YAAA,EACL,KAAK,gBAAgB,EAAK,EAEtB,KAAK,SACP,GAAI,CACF,KAAK,SAASA,CAAK,CACrB,OAAS6E,EAAe,CACtB,QAAQ,MAAM1H,EAAe,gCAAiC0H,CAAa,CAC7E,CAGF,MAAM7E,CACR,CAEQ,gBAAoB,CAC1B,GAAI,KAAK,iBACP,OAAO,KAAK,cAEd,MAAM,IAAIhD,EAAcG,EAAe,iCAAiC,CAC1E,CAEQ,iBAAqB,CAC3B,GAAI,KAAK,QAAQ,aAAe,KAAK,iBACnC,OAAO,KAAK,cAEd,MAAM,KAAK,MACb,CAGA,SAAgB,CACd,KAAK,WAAA,CACP,CAEQ,YAAmB,CACrB,KAAK,eAAA,GAAoB,KAAK,aAElC,KAAK,UAAA,EACL,KAAK,WAAA,EACP,CAEQ,mBAA0B,CAChC,MAAMW,EAAUsC,EAAgB,WAAA,EAChC,GAAKtC,EAGL,IAAIuD,GAAoBvD,CAAO,EAAG,CAChCA,EAAQ,cAAc,IAAI,EAC1B,MACF,CAGA,GAAIwD,GAAgBxD,CAAO,EAAG,CAC5B,KAAK,0BAA0B,IAAIA,CAAO,EAC1C,MACF,CAGIyD,GAAiBzD,CAAO,GAC1B,KAAK,wBAAwB,IAAIA,CAAO,EAE5C,CACF,CAEA,OAAO,OAAOwF,GAAiB,SAAS,EAajC,SAASwB,GACdzE,EACAuB,EAA8B,GACb,CACjB,OAAO,IAAI0B,GAAiBjD,EAAIuB,CAAO,CACzC,CCpmBA,MAAMmD,WAAmBrG,CAAwD,CA4C/E,YAAY2B,EAAoBuB,EAAyB,GAAI,CAC3D,MAAA,EAgCF,KAAO,IAAM,IAAY,CACvB,GAAI,KAAK,WACP,MAAM,IAAI3E,EAAYE,EAAe,uBAAuB,EAE1D,KAAK,sBAAwBmF,IAC/BG,EAAiB,QAAQ,KAAK,mBAAmB,EACjD,KAAK,oBAAsBH,GAE7B,KAAK,QAAA,CACP,EAMA,KAAO,QAAU,IAAY,CAC3B,GAAI,MAAK,WAKT,IAHA,KAAK,aAAA,EACL,KAAK,aAAA,EAED,KAAK,gBAAkBD,EAAc,CACvC,QAASpE,EAAI,EAAGA,EAAI,KAAK,cAAc,OAAQA,IAAK,CAClD,MAAM2F,EAAQ,KAAK,cAAc3F,CAAC,EAC9B2F,GAAOA,EAAA,CACb,CACApB,EAAe,QAAQ,KAAK,aAAa,EACzC,KAAK,cAAgBH,CACvB,CAEI,KAAK,gBAAkBD,IACzBG,EAAa,QAAQ,KAAK,aAAa,EACvC,KAAK,cAAgBH,GAGnB,KAAK,sBAAwBE,IAC/BG,EAAiB,QAAQ,KAAK,mBAAmB,EACjD,KAAK,oBAAsBH,GAE/B,EAOA,KAAO,cAAiBzE,GAA0B,CAChD,GAAI,KAAK,aAAe,KAAK,WAAa,KAAK,aAAe,KAAK,cAAe,CAChF,MAAME,EAAQ,KAAK,cAEnB,GAAIF,EAAI,iBAAmBE,EAAO,OAClCF,EAAI,eAAiBE,EAErB,KAAK,UAAU,KAAKF,CAAG,EACvB,KAAK,cAAc,KAAKA,EAAI,OAAO,EAE/BA,EAAI,YACN,KAAK,YAAY,KAAKA,EAAI,UAAU,EACpCA,EAAI,WAAa,QAEjB,KAAK,aAAaA,CAAG,CAEzB,CACF,EAOA,KAAO,QAAU,IAAY,CAE3B,GADI,KAAK,YAAc,KAAK,aACxB,CAAC,KAAK,iBAAkB,OAE5B,KAAK,mBAAA,EACL,KAAK,cAAc,EAAI,EACvB,KAAK,aAAA,EAEL,MAAMqF,EAAU,KAAK,sBAAA,EACrB,IAAIa,EAAY,GAEhB,GAAI,CACF,MAAMC,EAAS5D,EAAgB,IAAI,KAAM,KAAK,GAAG,EAEjD,KAAK,cAAc8C,CAAO,EAC1Ba,EAAY,GAEZ,KAAK,mBAAA,EAED7C,EAAU8C,CAAM,EAClBA,EACG,KAAMgB,GAAiB,CAClB,CAAC,KAAK,YAAc,OAAOA,GAAiB,aAC9C,KAAK,SAAWA,EAEpB,CAAC,EACA,MAAOhF,GAAU,CAChB,QAAQ,MAAMgD,EAAUhD,EAAO/C,EAAaE,EAAe,uBAAuB,CAAC,CACrF,CAAC,EAEH,KAAK,SAAW,OAAO6G,GAAW,WAAaA,EAAS,IAE5D,OAAShE,EAAO,CACd+D,EAAY,GACZ,QAAQ,MAAMf,EAAUhD,EAAO/C,EAAaE,EAAe,uBAAuB,CAAC,EACnF,KAAK,SAAW,IAClB,QAAA,CACE,KAAK,eAAe+F,EAASa,CAAS,EACtC,KAAK,cAAc,EAAK,CAC1B,CACF,EA5IE,KAAK,cAAgB,GACrB,KAAK,gBAAkB,GACvB,KAAK,mBAAqB,EAE1B,KAAK,IAAM1D,EACX,KAAK,MAAQuB,EAAQ,MAAQ,GAC7B,KAAK,eACHA,EAAQ,wBAA0BrF,EAAiB,0BACrD,KAAK,uBACHqF,EAAQ,uBAAyBrF,EAAiB,0BACpD,KAAK,oBAAsBqF,EAAQ,oBAAsB,GAEzD,KAAK,SAAW,KAChB,KAAK,cAAgBQ,EACrB,KAAK,oBAAsBE,EAC3B,KAAK,cAAgBD,EACrB,KAAK,UAAY,KACjB,KAAK,cAAgB,KACrB,KAAK,YAAc,KACnB,KAAK,SAAW3F,EAAS,CAAA,EAAK,KAC9B,KAAK,gBAAkB,EAEvByB,EAAM,gBAAgB,KAAM,SAAU,KAAK,EAAE,CAC/C,CA2HQ,uBAAuC,CAC7C,MAAMyE,EAAW,KAAK,cAChBsB,EAAe,KAAK,oBACpBrB,EAAa,KAAK,cAClBF,EAAWJ,EAAa,QAAA,EACxB4B,EAAe1B,EAAiB,QAAA,EAChCM,EAAaP,EAAe,QAAA,EAC5BzE,EAAQmB,EAAA,EAEd,GAAI0D,IAAaR,GAAcS,IAAeR,EAC5C,QAASpE,EAAI,EAAGA,EAAI2E,EAAS,OAAQ3E,IAAK,CACxC,MAAMJ,EAAM+E,EAAS3E,CAAC,EAClBJ,IAAKA,EAAI,WAAagF,EAAW5E,CAAC,EACxC,CAGF,YAAK,UAAY0E,EACjB,KAAK,cAAgBwB,EACrB,KAAK,YAAcpB,EACnB,KAAK,cAAgBhF,EAEd,CAAE,SAAA6E,EAAU,aAAAsB,EAAc,WAAArB,EAAY,SAAAF,EAAU,aAAAwB,EAAc,WAAApB,CAAA,CACvE,CAMQ,cAAcwB,EAA0B,CAG9C,MAAMU,EAAeV,EAAI,SAAS,OAElCA,EAAI,SAAS,OAASU,EACtBV,EAAI,aAAa,OAASU,EAE1B,KAAK,cAAgBV,EAAI,SACzB,KAAK,oBAAsBA,EAAI,aAC/B,KAAK,cAAgBA,EAAI,UAC3B,CAOQ,eAAeA,EAAoBR,EAA0B,CAKnE,GAJA,KAAK,UAAY,KACjB,KAAK,cAAgB,KACrB,KAAK,YAAc,KAEfA,EAAW,CACb,GAAIQ,EAAI,WAAanC,EAAY,CAC/B,QAASnE,EAAI,EAAGA,EAAIsG,EAAI,SAAS,OAAQtG,IAAK,CAC5C,MAAMJ,EAAM0G,EAAI,SAAStG,CAAC,EACtBJ,GAAK,aACPA,EAAI,WAAA,EACJA,EAAI,WAAa,OAErB,CACA0E,EAAa,QAAQgC,EAAI,QAAQ,CACnC,CACIA,EAAI,aAAelC,GACrBG,EAAe,QAAQ+B,EAAI,UAAU,EAEnCA,EAAI,eAAiBjC,GACvBG,EAAiB,QAAQ8B,EAAI,YAAY,CAE7C,KAAO,CACLhC,EAAa,QAAQgC,EAAI,QAAQ,EACjC9B,EAAiB,QAAQ8B,EAAI,YAAY,EACzC,QAAStG,EAAI,EAAGA,EAAIsG,EAAI,WAAW,OAAQtG,IACzCsG,EAAI,WAAWtG,CAAC,IAAA,EAIlB,GAFAuE,EAAe,QAAQ+B,EAAI,UAAU,EAEjCA,EAAI,WAAanC,EACnB,QAASnE,EAAI,EAAGA,EAAIsG,EAAI,SAAS,OAAQtG,IAAK,CAC5C,MAAMJ,EAAM0G,EAAI,SAAStG,CAAC,EACtBJ,MAAS,WAAa,OAC5B,CAEJ,CACF,CAMQ,aAAaA,EAAuB,CAC1C,GAAI,CACF,MAAMqH,EAAcrH,EAAI,UAAU,IAAM,CAClC,KAAK,qBAAuB,KAAK,cACnCA,EAAI,iBAAmB,KAAK,eAG1B,KAAK,MACP,KAAK,QAAA,EAELqC,EAAU,SAAS,KAAK,OAAO,CAEnC,CAAC,EACG,KAAK,aACP,KAAK,YAAY,KAAKgF,CAAW,CAErC,OAASlF,EAAO,CACd,QAAQ,MAAMgD,EAAUhD,EAAO/C,EAAaE,EAAe,uBAAuB,CAAC,EAC/E,KAAK,aAAa,KAAK,YAAY,KAAK,IAAM,CAAC,CAAC,CACtD,CACF,CAKA,IAAI,YAAsB,CACxB,OAAQ,KAAK,MAAQf,EAAmB,YAAc,CACxD,CAKA,IAAI,gBAAyB,CAC3B,OAAO,KAAK,eACd,CAKA,IAAI,aAAuB,CACzB,OAAQ,KAAK,MAAQA,EAAmB,aAAe,CACzD,CAEQ,cAAqB,CAC3B,KAAK,OAASA,EAAmB,QACnC,CAEQ,cAAc+E,EAAsB,CAC1C,MAAM0C,EAAOzH,EAAmB,UAChC,KAAK,MAAS,KAAK,MAAQ,CAACyH,EAAS,CAAC,OAAO1C,CAAK,EAAI0C,CACxD,CAKQ,cAAqB,CAC3B,GAAI,KAAK,SAAU,CACjB,GAAI,CACF,KAAK,SAAA,CACP,OAAS7D,EAAO,CACd,QAAQ,MAAMgD,EAAUhD,EAAO/C,EAAaE,EAAe,qBAAqB,CAAC,CACnF,CACA,KAAK,SAAW,IAClB,CACF,CAMQ,oBAA2B,CAkBjC,GAjBI,KAAK,kBAAoBiC,IAC3B,KAAK,gBAAkBA,EACvB,KAAK,mBAAqB,GAG5B,KAAK,qBAED,KAAK,mBAAqB,KAAK,wBACjC,KAAK,wBAAwB,YAAY,EAGvCK,GAAA,EAAiClD,EAAiB,0BACpD,KAAK,wBAAwB,QAAQ,EAGvC,KAAK,kBAED,KAAK,SAAU,CACjB,MAAM4I,EAAM,KAAK,IAAA,EACjB,KAAK,SAAS,KAAKA,CAAG,EAElB,KAAK,SAAS,OAAS5I,EAAiB,0BAA4B,IACtE,KAAK,SAAS,MAAA,EAGhB,KAAK,oBAAoB4I,CAAG,CAC9B,CACF,CAEQ,oBAAoBA,EAAmB,CAC7C,MAAMC,EAAU,KAAK,SACrB,GAAI,CAACA,GAAW,KAAK,gBAAkB,EAAG,OAE1C,MAAMC,EAAeF,EAAMjJ,EAAe,cAC1C,IAAIkB,EAAQ,EAEZ,QAASa,EAAImH,EAAQ,OAAS,EAAGnH,GAAK,GAChC,EAAAmH,EAAQnH,CAAC,EAAKoH,GADqBpH,IAEvCb,IAGF,GAAIA,EAAQ,KAAK,eAAgB,CAC/B,MAAM4C,EAAQ,IAAI/C,EAChB,mBAAmBG,CAAK,iDAAA,EAI1B,GAFA,KAAK,QAAA,EACL,QAAQ,MAAM4C,CAAK,EACftD,EACF,MAAMsD,CAEV,CACF,CAEQ,wBAAwB3B,EAAsC,CACpE,MAAM2B,EAAQ,IAAI/C,EAChB,2BAA2BoB,CAAI,sBACV,KAAK,kBAAkB,uDACZgB,CAAmB,EAAA,EAErD,WAAK,QAAA,EACL,QAAQ,MAAMW,CAAK,EACbA,CACR,CAMQ,gBAA0B,CAEhC,GAAI,KAAK,gBAAkBoC,GAAc,KAAK,sBAAwBE,EACpE,MAAO,GAET,QAASrE,EAAI,EAAGA,EAAI,KAAK,cAAc,OAAQA,IAAK,CAClD,MAAMJ,EAAM,KAAK,cAAcI,CAAC,EAChC,GAAKJ,EAEL,IAAI,UAAWA,EACb,GAAI,CACF0C,EAAU,IAAO1C,EAA2B,KAAK,CACnD,MAAQ,CACN,MAAO,EACT,CAGF,GAAIA,EAAI,UAAY,KAAK,oBAAoBI,CAAC,EAC5C,MAAO,GAEX,CAEA,MAAO,EACT,CAMQ,oBAA2B,CACjC,GAAI,KAAK,qBAAuBE,EAAM,QAAS,CAC7C,MAAMmH,EAAe,KAAK,cAC1B,QAASrH,EAAI,EAAGA,EAAIqH,EAAa,OAAQrH,IAAK,CAC5C,MAAMJ,EAAMyH,EAAarH,CAAC,EACtBJ,GAAOA,EAAI,mBAAqB,KAAK,eACvCM,EAAM,KACJ,GACA,mCACEA,EAAM,aAAaN,CAAG,GAAK,SAC7B,kDAAA,CAGN,CACF,CACF,CACF,CAyBO,SAAS0H,GAAOlF,EAAoBuB,EAAyB,GAAkB,CACpF,GAAI,OAAOvB,GAAO,WAChB,MAAM,IAAIpD,EAAYE,EAAe,uBAAuB,EAG9D,MAAMqI,EAAiB,IAAIT,GAAW1E,EAAIuB,CAAO,EACjD,OAAA4D,EAAe,QAAA,EAERA,CACT"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const te={ONE_SECOND_MS:1e3},T={IDLE:"idle",PENDING:"pending",RESOLVED:"resolved",REJECTED:"rejected"},O={DISPOSED:1,EXECUTING:2},u={DIRTY:1,IDLE:2,PENDING:4,RESOLVED:8,REJECTED:16,RECOMPUTING:32,HAS_ERROR:64},se={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},V={MAX_DEPENDENCIES:1e3,WARN_INFINITE_LOOP:!0},N=1073741823,l=typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production";class p 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 p{constructor(e,t=null){super(e,t,!0),this.name="ComputedError"}}class b extends p{constructor(e,t=null){super(e,t,!1),this.name="EffectError"}}class A extends p{constructor(e,t=null){super(e,t,!1),this.name="SchedulerError"}}const c={COMPUTED_MUST_BE_FUNCTION:"Computed function must be a function",COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION:"Subscriber listener must be a function or Subscriber object",COMPUTED_ASYNC_PENDING_NO_DEFAULT:"Async computation is pending. No default value provided",COMPUTED_COMPUTATION_FAILED:"Computed computation failed",COMPUTED_ASYNC_COMPUTATION_FAILED:"Async computed computation failed",COMPUTED_DEPENDENCY_SUBSCRIPTION_FAILED:"Failed to subscribe to dependency",ATOM_SUBSCRIBER_MUST_BE_FUNCTION:"Subscription listener must be a function or Subscriber object",ATOM_SUBSCRIBER_EXECUTION_FAILED:"Error occurred while executing atom subscribers",ATOM_INDIVIDUAL_SUBSCRIBER_FAILED:"Error during individual atom subscriber execution",EFFECT_MUST_BE_FUNCTION:"Effect function must be a function",EFFECT_EXECUTION_FAILED:"Effect execution failed",EFFECT_CLEANUP_FAILED:"Effect cleanup function execution failed",LARGE_DEPENDENCY_GRAPH:i=>`Large dependency graph detected: ${i} dependencies`,UNSUBSCRIBE_NON_EXISTENT:"Attempted to unsubscribe a non-existent listener",CALLBACK_ERROR_IN_ERROR_HANDLER:"Error occurred during onError callback execution"},P=Symbol("debugName"),ie=Symbol("id"),M=Symbol("type"),q=Symbol("noDefaultValue");function ne(i){return"dependencies"in i&&Array.isArray(i.dependencies)}let k=0;function G(i,e,t){if(i._visitedEpoch!==t){if(i._visitedEpoch=t,i===e)throw new D("Indirect circular dependency detected");if(ne(i)){const s=i.dependencies;for(let n=0;n<s.length;n++){const r=s[n];r&&G(r,e,t)}}}}const a={enabled:typeof process<"u"&&process.env?.NODE_ENV==="development",maxDependencies:V.MAX_DEPENDENCIES,warnInfiniteLoop:V.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&&(k++,G(i,e,k))},attachDebugInfo(i,e,t){if(!this.enabled)return;const s=i;s[P]=`${e}_${t}`,s[ie]=t,s[M]=e},getDebugName(i){if(i!=null&&P in i)return i[P]},getDebugType(i){if(i!=null&&M in i)return i[M]}};let re=1;const oe=()=>re++;class X{constructor(){this.id=oe()&N,this.flags=0}}class H extends X{constructor(){super(),this.version=0,this._lastSeenEpoch=-1}subscribe(e){if(typeof e=="object"&&e!==null&&"execute"in e)return this._objectSubscribers.add(e);if(typeof e!="function")throw new p(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 p(c.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,s))),this._objectSubscribers.forEachSafe(s=>s.execute(),s=>console.error(new p(c.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,s)))}}let L=0;function $(){return L=(L+1|0)&N,L}let U=0,w=0,x=!1;function j(){return x?(l&&console.warn("Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"),!1):(x=!0,U=U+1&N,w=0,!0)}function z(){x=!1}function ue(){return x?++w:0}class ce{constructor(){this.queueA=[],this.queueB=[],this.queue=this.queueA,this.queueSize=0,this._epoch=0,this.isProcessing=!1,this.isBatching=!1,this.batchDepth=0,this.batchQueue=[],this.batchQueueSize=0,this.isFlushingSync=!1,this.maxFlushIterations=S.MAX_FLUSH_ITERATIONS}get phase(){return this.isProcessing||this.isFlushingSync?2:this.isBatching?1:0}schedule(e){if(typeof e!="function")throw new A("Scheduler callback must be a function");e._nextEpoch!==this._epoch&&(e._nextEpoch=this._epoch,this.isBatching||this.isFlushingSync?this.batchQueue[this.batchQueueSize++]=e:(this.queue[this.queueSize++]=e,this.isProcessing||this.flush()))}flush(){if(this.isProcessing||this.queueSize===0)return;this.isProcessing=!0;const e=this.queue,t=this.queueSize;this.queue=this.queue===this.queueA?this.queueB:this.queueA,this.queueSize=0,this._epoch++,queueMicrotask(()=>{const s=j();this._processJobs(e,t),this.isProcessing=!1,s&&z(),this.queueSize>0&&!this.isBatching&&this.flush()})}flushSync(){this.isFlushingSync=!0;const e=j();try{this._mergeBatchQueue(),this._drainQueue()}finally{this.isFlushingSync=!1,e&&z()}}_mergeBatchQueue(){if(this._epoch++,this.batchQueueSize>0){for(let e=0;e<this.batchQueueSize;e++){const t=this.batchQueue[e];t&&t._nextEpoch!==this._epoch&&(t._nextEpoch=this._epoch,this.queue[this.queueSize++]=t)}this.batchQueueSize=0}}_drainQueue(){let e=0;for(;this.queueSize>0;){if(++e>this.maxFlushIterations){this._handleFlushOverflow();break}this._processCurrentQueue(),this._mergeBatchQueue()}}_processCurrentQueue(){const e=this.queue,t=this.queueSize;this.queue=this.queue===this.queueA?this.queueB:this.queueA,this.queueSize=0,this._epoch++,this._processJobs(e,t)}_handleFlushOverflow(){console.error(new A(`Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop.`)),this.queueSize=0,this.queue.length=0,this.batchQueueSize=0}_processJobs(e,t){for(let s=0;s<t;s++)try{e[s]?.()}catch(n){console.error(new A("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 A(`Max flush iterations must be at least ${S.MIN_FLUSH_ITERATIONS}`);this.maxFlushIterations=e}}const R=new ce;function he(i){if(typeof i!="function")throw new p("Batch callback must be a function");R.startBatch();try{return i()}finally{R.endBatch()}}const m={current:null,run(i,e){const t=this.current;this.current=i;try{return e()}finally{this.current=t}},getCurrent(){return this.current}};function Q(i){if(typeof i!="function")throw new p("Untracked callback must be a function");const e=m.current;m.current=null;try{return i()}finally{m.current=e}}class F{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]:[]}}function Y(i){return i!==null&&typeof i=="object"&&"value"in i&&"subscribe"in i&&typeof i.subscribe=="function"}function _e(i){if(a.enabled&&(i==null||typeof i=="object")){const e=a.getDebugType(i);if(e)return e==="computed"}return Y(i)&&"invalidate"in i&&typeof i.invalidate=="function"}function le(i){return i!==null&&typeof i=="object"&&"dispose"in i&&"run"in i&&typeof i.dispose=="function"&&typeof i.run=="function"}function J(i){return i!=null&&typeof i.then=="function"}function ae(i){return typeof i=="object"&&i!==null}function W(i){return(typeof i=="object"||typeof i=="function")&&i!==null&&typeof i.addDependency=="function"}function K(i){return typeof i=="function"&&typeof i.addDependency!="function"}function Z(i){return ae(i)&&typeof i.execute=="function"}class fe extends H{constructor(e,t){super(),this._isNotificationScheduled=!1,this._value=e,this._functionSubscribersStore=new F,this._objectSubscribersStore=new F,this._sync=t,this._notifyTask=this._flushNotifications.bind(this),a.attachDebugInfo(this,"atom",this.id)}get _functionSubscribers(){return this._functionSubscribersStore}get _objectSubscribers(){return this._objectSubscribersStore}get value(){const e=m.getCurrent();return e&&this._track(e),this._value}set value(e){if(Object.is(this._value,e))return;const t=this._value;this.version=this.version+1&N,this._value=e,!(!this._functionSubscribersStore.hasSubscribers&&!this._objectSubscribersStore.hasSubscribers)&&this._scheduleNotification(t)}_track(e){if(W(e)){e.addDependency(this);return}if(K(e)){this._functionSubscribersStore.add(e);return}Z(e)&&this._objectSubscribersStore.add(e)}_scheduleNotification(e){this._isNotificationScheduled||(this._pendingOldValue=e,this._isNotificationScheduled=!0),this._sync&&!R.isBatching?this._flushNotifications():R.schedule(this._notifyTask)}_flushNotifications(){if(!this._isNotificationScheduled)return;const e=this._pendingOldValue,t=this._value;this._pendingOldValue=void 0,this._isNotificationScheduled=!1,this._notifySubscribers(t,e)}peek(){return this._value}dispose(){this._functionSubscribersStore.clear(),this._objectSubscribersStore.clear(),this._value=void 0}}function de(i,e={}){return new fe(i,e.sync??!1)}class B{constructor(){this.pool=[],this.maxPoolSize=50,this.maxReusableCapacity=256,this.stats=l?{acquired:0,released:0,rejected:{frozen:0,tooLarge:0,poolFull:0}}:null}acquire(){return l&&this.stats&&this.stats.acquired++,this.pool.pop()??[]}release(e,t){if(!(t&&e===t)){if(Object.isFrozen(e)){l&&this.stats&&this.stats.rejected.frozen++;return}if(e.length>this.maxReusableCapacity){l&&this.stats&&this.stats.rejected.tooLarge++;return}if(this.pool.length>=this.maxPoolSize){l&&this.stats&&this.stats.rejected.poolFull++;return}e.length=0,this.pool.push(e),l&&this.stats&&this.stats.released++}}getStats(){if(!l||!this.stats)return null;const{acquired:e,released:t,rejected: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,l&&this.stats&&(this.stats.acquired=0,this.stats.released=0,this.stats.rejected={frozen:0,tooLarge:0,poolFull:0})}}const h=Object.freeze([]),f=Object.freeze([]),_=Object.freeze([]),g=new B,I=new B,d=new B;function pe(i,e,t,s){if(e!==h&&t!==f)for(let r=0;r<e.length;r++){const o=e[r];o&&(o._tempUnsub=t[r])}const n=I.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):(a.checkCircular(o,s),n[r]=o.subscribe(s)))}if(e!==h)for(let r=0;r<e.length;r++){const o=e[r];o?._tempUnsub&&(o._tempUnsub(),o._tempUnsub=void 0)}return t!==f&&I.release(t),n}function C(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 p)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)}class ee extends H{constructor(e,t={}){if(typeof e!="function")throw new D(c.COMPUTED_MUST_BE_FUNCTION);if(super(),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._functionSubscribersStore=new F,this._objectSubscribersStore=new F,this._dependencies=h,this._dependencyVersions=_,this._unsubscribes=f,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=>{}}),a.attachDebugInfo(this,"computed",this.id),a.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(){const e=this._computeValue();return this._registerTracking(),e}peek(){return this._value}get state(){return this._getAsyncState()}get hasError(){return this._isRejected()}get lastError(){return this._error}get isPending(){return this._isPending()}get isResolved(){return this._isResolved()}invalidate(){this._markDirty(),this._dependencyVersions!==_&&(d.release(this._dependencyVersions),this._dependencyVersions=_)}dispose(){if(this._unsubscribes!==f){for(let e=0;e<this._unsubscribes.length;e++){const t=this._unsubscribes[e];t&&t()}I.release(this._unsubscribes),this._unsubscribes=f}this._dependencies!==h&&(g.release(this._dependencies),this._dependencies=h),this._dependencyVersions!==_&&(d.release(this._dependencyVersions),this._dependencyVersions=_),this._functionSubscribersStore.clear(),this._objectSubscribersStore.clear(),this.flags=u.DIRTY|u.IDLE,this._error=null,this._value=void 0,this._promiseId=(this._promiseId+1)%this.MAX_PROMISE_ID}_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 this._isResolved()?T.RESOLVED:this._isPending()?T.PENDING:this._isRejected()?T.REJECTED:T.IDLE}_getFlagsAsString(){const e=[];return this._isDirty()&&e.push("DIRTY"),this._isIdle()&&e.push("IDLE"),this._isPending()&&e.push("PENDING"),this._isResolved()&&e.push("RESOLVED"),this._isRejected()&&e.push("REJECTED"),this._isRecomputing()&&e.push("RECOMPUTING"),e.join(" | ")}_computeValue(){return this._isRecomputing()?this._value:((this._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);J(s)?(this._commitDependencies(e),t=!0,this._handleAsyncComputation(s)):(this._commitDependencies(e),t=!0,this._handleSyncResult(s))}catch(s){this._commitDependencies(e),t=!0,this._handleComputationError(s)}finally{this._cleanupContext(e,t),this._setRecomputing(!1)}}_prepareComputationContext(){const e=this._dependencies,t=this._dependencyVersions,s=g.acquire(),n=d.acquire(),r=$(),o={depCount:0},v=E=>{E._lastSeenEpoch!==r&&(E._lastSeenEpoch=r,o.depCount<s.length?(s[o.depCount]=E,n[o.depCount]=E.version):(s.push(E),n.push(E.version)),o.depCount++)},y=this._trackable.addDependency;return this._trackable.addDependency=v,{prevDeps:e,prevVersions:t,nextDeps:s,nextVersions:n,originalAdd:y,state:o}}_commitDependencies(e){const{nextDeps:t,nextVersions:s,state:n,prevDeps:r}=e;t.length=n.depCount,s.length=n.depCount,this._unsubscribes=pe(t,r,this._unsubscribes,this),this._dependencies=t,this._dependencyVersions=s}_cleanupContext(e,t){this._trackable.addDependency=e.originalAdd,t?(e.prevDeps!==h&&g.release(e.prevDeps),e.prevVersions!==_&&d.release(e.prevVersions)):(g.release(e.nextDeps),d.release(e.nextVersions))}_handleSyncResult(e){(!this._isResolved()||!this._equal(this._value,e))&&(this.version=this.version+1&N),this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1)}_handleAsyncComputation(e){this._setPending(),this._clearDirty(),this._promiseId=this._promiseId>=this.MAX_PROMISE_ID?1:this._promiseId+1;const t=this._promiseId;e.then(s=>{t===this._promiseId&&this._handleAsyncResolution(s)}).catch(s=>{t===this._promiseId&&this._handleAsyncRejection(s)})}_handleAsyncResolution(e){(!this._isResolved()||!this._equal(this._value,e))&&(this.version=this.version+1&N),this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1)}_handleAsyncRejection(e){const t=C(e,D,c.COMPUTED_ASYNC_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)}this._notifySubscribers(void 0,void 0)}_handleComputationError(e){const t=C(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(){const e=m.getCurrent();if(e){if(W(e)){e.addDependency(this);return}if(K(e)){this._functionSubscribersStore.add(e);return}Z(e)&&this._objectSubscribersStore.add(e)}}}Object.freeze(ee.prototype);function Ee(i,e={}){return new ee(i,e)}class be extends X{constructor(e,t={}){super(),this.run=()=>{if(this.isDisposed)throw new b(c.EFFECT_MUST_BE_FUNCTION);this._dependencyVersions!==_&&(d.release(this._dependencyVersions),this._dependencyVersions=_),this.execute()},this.dispose=()=>{if(!this.isDisposed){if(this._setDisposed(),this._safeCleanup(),this._unsubscribes!==f){for(let s=0;s<this._unsubscribes.length;s++){const n=this._unsubscribes[s];n&&n()}I.release(this._unsubscribes),this._unsubscribes=f}this._dependencies!==h&&(g.release(this._dependencies),this._dependencies=h),this._dependencyVersions!==_&&(d.release(this._dependencyVersions),this._dependencyVersions=_)}},this.addDependency=s=>{if(this.isExecuting&&this._nextDeps&&this._nextUnsubs&&this._nextVersions){const n=this._currentEpoch;if(s._lastSeenEpoch===n)return;s._lastSeenEpoch=n,this._nextDeps.push(s),this._nextVersions.push(s.version),s._tempUnsub?(this._nextUnsubs.push(s._tempUnsub),s._tempUnsub=void 0):this._subscribeTo(s)}},this.execute=()=>{if(this.isDisposed||this.isExecuting||!this._shouldExecute())return;this._checkInfiniteLoop(),this._setExecuting(!0),this._safeCleanup();const s=this._prepareEffectContext();let n=!1;try{const r=m.run(this,this._fn);this._commitEffect(s),n=!0,this._checkLoopWarnings(),J(r)?r.then(o=>{!this.isDisposed&&typeof o=="function"&&(this._cleanup=o)}).catch(o=>{console.error(C(o,b,c.EFFECT_EXECUTION_FAILED))}):this._cleanup=typeof r=="function"?r:null}catch(r){n=!0,console.error(C(r,b,c.EFFECT_EXECUTION_FAILED)),this._cleanup=null}finally{this._cleanupEffect(s,n),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=h,this._dependencyVersions=_,this._unsubscribes=f,this._nextDeps=null,this._nextVersions=null,this._nextUnsubs=null,this._history=l?[]:null,this._executionCount=0,a.attachDebugInfo(this,"effect",this.id)}_prepareEffectContext(){const e=this._dependencies,t=this._dependencyVersions,s=this._unsubscribes,n=g.acquire(),r=d.acquire(),o=I.acquire(),v=$();if(e!==h&&s!==f)for(let y=0;y<e.length;y++){const E=e[y];E&&(E._tempUnsub=s[y])}return this._nextDeps=n,this._nextVersions=r,this._nextUnsubs=o,this._currentEpoch=v,{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!==h){for(let s=0;s<e.prevDeps.length;s++){const n=e.prevDeps[s];n?._tempUnsub&&(n._tempUnsub(),n._tempUnsub=void 0)}g.release(e.prevDeps)}e.prevUnsubs!==f&&I.release(e.prevUnsubs),e.prevVersions!==_&&d.release(e.prevVersions)}else{g.release(e.nextDeps),d.release(e.nextVersions);for(let s=0;s<e.nextUnsubs.length;s++)e.nextUnsubs[s]?.();if(I.release(e.nextUnsubs),e.prevDeps!==h)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():R.schedule(this.execute)});this._nextUnsubs&&this._nextUnsubs.push(t)}catch(t){console.error(C(t,b,c.EFFECT_EXECUTION_FAILED)),this._nextUnsubs&&this._nextUnsubs.push(()=>{})}}get isDisposed(){return(this.flags&O.DISPOSED)!==0}get executionCount(){return this._executionCount}get isExecuting(){return(this.flags&O.EXECUTING)!==0}_setDisposed(){this.flags|=O.DISPOSED}_setExecuting(e){const t=O.EXECUTING;this.flags=this.flags&~t|-Number(e)&t}_safeCleanup(){if(this._cleanup){try{this._cleanup()}catch(e){console.error(C(e,b,c.EFFECT_CLEANUP_FAILED))}this._cleanup=null}}_checkInfiniteLoop(){if(this._lastFlushEpoch!==U&&(this._lastFlushEpoch=U,this._executionsInEpoch=0),this._executionsInEpoch++,this._executionsInEpoch>this._maxExecutionsPerFlush&&this._throwInfiniteLoopError("per-effect"),ue()>S.MAX_EXECUTIONS_PER_FLUSH&&this._throwInfiniteLoopError("global"),this._executionCount++,this._history){const e=Date.now();this._history.push(e),this._history.length>S.MAX_EXECUTIONS_PER_SECOND+10&&this._history.shift(),this._checkTimestampLoop(e)}}_checkTimestampLoop(e){const t=this._history;if(!t||this._maxExecutions<=0)return;const s=e-te.ONE_SECOND_MS;let n=0;for(let r=t.length-1;r>=0&&!(t[r]<s);r--)n++;if(n>this._maxExecutions){const r=new b(`Effect executed ${n} times within 1 second. Infinite loop suspected`);if(this.dispose(),console.error(r),l)throw r}}_throwInfiniteLoopError(e){const t=new b(`Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${w}`);throw this.dispose(),console.error(t),t}_shouldExecute(){if(this._dependencies===h||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{Q(()=>t.value)}catch{return!0}if(t.version!==this._dependencyVersions[e])return!0}}return!1}_checkLoopWarnings(){if(this._trackModifications&&a.enabled){const e=this._dependencies;for(let t=0;t<e.length;t++){const s=e[t];s&&s._modifiedAtEpoch===this._currentEpoch&&a.warn(!0,`Effect is reading a dependency (${a.getDebugName(s)||"unknown"}) that it just modified. Infinite loop may occur`)}}}}function Se(i,e={}){if(typeof i!="function")throw new b(c.EFFECT_MUST_BE_FUNCTION);const t=new be(i,e);return t.execute(),t}exports.AsyncState=T;exports.AtomError=p;exports.ComputedError=D;exports.DEBUG_CONFIG=V;exports.DEBUG_RUNTIME=a;exports.EffectError=b;exports.POOL_CONFIG=se;exports.SCHEDULER_CONFIG=S;exports.SchedulerError=A;exports.atom=de;exports.batch=he;exports.computed=Ee;exports.effect=Se;exports.isAtom=Y;exports.isComputed=_e;exports.isEffect=le;exports.scheduler=R;exports.untracked=Q;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ie={ONE_SECOND_MS:1e3},O={IDLE:"idle",PENDING:"pending",RESOLVED:"resolved",REJECTED:"rejected"},U={DISPOSED:1,EXECUTING:2},c={DIRTY:1,IDLE:2,PENDING:4,RESOLVED:8,REJECTED:16,RECOMPUTING:32,HAS_ERROR:64},ne={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},w={MAX_DEPENDENCIES:1e3,WARN_INFINITE_LOOP:!0},m=1073741823,a=typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production",re=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 b extends E{constructor(e,t=null){super(e,t,!1),this.name="EffectError"}}class A extends E{constructor(e,t=null){super(e,t,!1),this.name="SchedulerError"}}const u={COMPUTED_MUST_BE_FUNCTION:"Computed function must be a function",COMPUTED_SUBSCRIBER_MUST_BE_FUNCTION:"Subscriber listener must be a function or Subscriber object",COMPUTED_ASYNC_PENDING_NO_DEFAULT:"Async computation is pending. No default value provided",COMPUTED_COMPUTATION_FAILED:"Computed computation failed",COMPUTED_ASYNC_COMPUTATION_FAILED:"Async computed computation failed",COMPUTED_DEPENDENCY_SUBSCRIPTION_FAILED:"Failed to subscribe to dependency",ATOM_SUBSCRIBER_MUST_BE_FUNCTION:"Subscription listener must be a function or Subscriber object",ATOM_SUBSCRIBER_EXECUTION_FAILED:"Error occurred while executing atom subscribers",ATOM_INDIVIDUAL_SUBSCRIBER_FAILED:"Error during individual atom subscriber execution",EFFECT_MUST_BE_FUNCTION:"Effect function must be a function",EFFECT_EXECUTION_FAILED:"Effect execution failed",EFFECT_CLEANUP_FAILED:"Effect cleanup function execution failed",LARGE_DEPENDENCY_GRAPH:i=>`Large dependency graph detected: ${i} dependencies`,UNSUBSCRIBE_NON_EXISTENT:"Attempted to unsubscribe a non-existent listener",CALLBACK_ERROR_IN_ERROR_HANDLER:"Error occurred during onError callback execution"},M=Symbol("debugName"),oe=Symbol("id"),V=Symbol("type"),q=Symbol("noDefaultValue");function ce(i){return"dependencies"in i&&Array.isArray(i.dependencies)}let j=0;function X(i,e,t){if(i._visitedEpoch!==t){if(i._visitedEpoch=t,i===e)throw new D("Indirect circular dependency detected");if(ce(i)){const s=i.dependencies;for(let n=0;n<s.length;n++){const r=s[n];r&&X(r,e,t)}}}}const l={enabled:typeof process<"u"&&process.env?.NODE_ENV==="development",maxDependencies:w.MAX_DEPENDENCIES,warnInfiniteLoop:w.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&&(j++,X(i,e,j))},attachDebugInfo(i,e,t){if(!this.enabled)return;const s=i;s[M]=`${e}_${t}`,s[oe]=t,s[V]=e},getDebugName(i){if(i!=null&&M in i)return i[M]},getDebugType(i){if(i!=null&&V in i)return i[V]}};let ue=1;const he=()=>ue++;class Y{constructor(){this.id=he()&m,this.flags=0}}class H extends Y{constructor(){super(),this.version=0,this._lastSeenEpoch=-1}subscribe(e){if(typeof e=="object"&&e!==null&&"execute"in e)return this._objectSubscribers.add(e);if(typeof e!="function")throw new E(u.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);return this._functionSubscribers.add(e)}subscriberCount(){return this._functionSubscribers.size+this._objectSubscribers.size}_notifySubscribers(e,t){this._functionSubscribers.forEachSafe(s=>s(e,t),s=>console.error(new E(u.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,s))),this._objectSubscribers.forEachSafe(s=>s.execute(),s=>console.error(new E(u.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,s)))}}let x=0;function $(){return x=(x+1|0)&m,x}function _e(){return x}let F=0,B=0,P=!1;function z(){return P?(a&&console.warn("Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"),!1):(P=!0,F=F+1&m,B=0,!0)}function G(){P=!1}function ae(){return P?++B:0}class le{constructor(){this.queueA=[],this.queueB=[],this.queue=this.queueA,this.queueSize=0,this._epoch=0,this.isProcessing=!1,this.isBatching=!1,this.batchDepth=0,this.batchQueue=[],this.batchQueueSize=0,this.isFlushingSync=!1,this.maxFlushIterations=S.MAX_FLUSH_ITERATIONS}get phase(){return this.isProcessing||this.isFlushingSync?2:this.isBatching?1:0}schedule(e){if(typeof e!="function")throw new A("Scheduler callback must be a function");e._nextEpoch!==this._epoch&&(e._nextEpoch=this._epoch,this.isBatching||this.isFlushingSync?this.batchQueue[this.batchQueueSize++]=e:(this.queue[this.queueSize++]=e,this.isProcessing||this.flush()))}flush(){if(this.isProcessing||this.queueSize===0)return;this.isProcessing=!0;const e=this.queue,t=this.queueSize;this.queue=this.queue===this.queueA?this.queueB:this.queueA,this.queueSize=0,this._epoch++,queueMicrotask(()=>{const s=z();this._processJobs(e,t),this.isProcessing=!1,s&&G(),this.queueSize>0&&!this.isBatching&&this.flush()})}flushSync(){this.isFlushingSync=!0;const e=z();try{this._mergeBatchQueue(),this._drainQueue()}finally{this.isFlushingSync=!1,e&&G()}}_mergeBatchQueue(){if(this._epoch++,this.batchQueueSize>0){for(let e=0;e<this.batchQueueSize;e++){const t=this.batchQueue[e];t&&t._nextEpoch!==this._epoch&&(t._nextEpoch=this._epoch,this.queue[this.queueSize++]=t)}this.batchQueueSize=0}}_drainQueue(){let e=0;for(;this.queueSize>0;){if(++e>this.maxFlushIterations){this._handleFlushOverflow();break}this._processCurrentQueue(),this._mergeBatchQueue()}}_processCurrentQueue(){const e=this.queue,t=this.queueSize;this.queue=this.queue===this.queueA?this.queueB:this.queueA,this.queueSize=0,this._epoch++,this._processJobs(e,t)}_handleFlushOverflow(){console.error(new A(`Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop.`)),this.queueSize=0,this.queue.length=0,this.batchQueueSize=0}_processJobs(e,t){for(let s=0;s<t;s++)try{e[s]?.()}catch(n){console.error(new A("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 A(`Max flush iterations must be at least ${S.MIN_FLUSH_ITERATIONS}`);this.maxFlushIterations=e}}const T=new le;function fe(i){if(typeof i!="function")throw new E("Batch callback must be a function");T.startBatch();try{return i()}finally{T.endBatch()}}const y={current:null,run(i,e){const t=this.current;this.current=i;try{return e()}finally{this.current=t}},getCurrent(){return this.current}};function J(i){if(typeof i!="function")throw new E("Untracked callback must be a function");const e=y.current;y.current=null;try{return i()}finally{y.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]:[]}}function Q(i){return i!==null&&typeof i=="object"&&"value"in i&&"subscribe"in i&&typeof i.subscribe=="function"}function de(i){if(l.enabled&&(i==null||typeof i=="object")){const e=l.getDebugType(i);if(e)return e==="computed"}return Q(i)&&"invalidate"in i&&typeof i.invalidate=="function"}function Ee(i){return i!==null&&typeof i=="object"&&"dispose"in i&&"run"in i&&typeof i.dispose=="function"&&typeof i.run=="function"}function W(i){return i!=null&&typeof i.then=="function"}function pe(i){return typeof i=="object"&&i!==null}function K(i){return(typeof i=="object"||typeof i=="function")&&i!==null&&typeof i.addDependency=="function"}function Z(i){return typeof i=="function"&&typeof i.addDependency!="function"}function ee(i){return pe(i)&&typeof i.execute=="function"}class be extends H{constructor(e,t){super(),this._isNotificationScheduled=!1,this._value=e,this._functionSubscribersStore=new v,this._objectSubscribersStore=new v,this._sync=t,this._notifyTask=this._flushNotifications.bind(this),l.attachDebugInfo(this,"atom",this.id)}get _functionSubscribers(){return this._functionSubscribersStore}get _objectSubscribers(){return this._objectSubscribersStore}get value(){const e=y.getCurrent();return e&&this._track(e),this._value}set value(e){if(Object.is(this._value,e))return;const t=this._value;this.version=this.version+1&m,this._value=e,!(!this._functionSubscribersStore.hasSubscribers&&!this._objectSubscribersStore.hasSubscribers)&&this._scheduleNotification(t)}_track(e){if(K(e)){e.addDependency(this);return}if(Z(e)){this._functionSubscribersStore.add(e);return}ee(e)&&this._objectSubscribersStore.add(e)}_scheduleNotification(e){this._isNotificationScheduled||(this._pendingOldValue=e,this._isNotificationScheduled=!0),this._sync&&!T.isBatching?this._flushNotifications():T.schedule(this._notifyTask)}_flushNotifications(){if(!this._isNotificationScheduled)return;const e=this._pendingOldValue,t=this._value;this._pendingOldValue=void 0,this._isNotificationScheduled=!1,this._notifySubscribers(t,e)}peek(){return this._value}dispose(){this._functionSubscribersStore.clear(),this._objectSubscribersStore.clear(),this._value=void 0}}function Se(i,e={}){return new be(i,e.sync??!1)}class k{constructor(){this.pool=[],this.maxPoolSize=50,this.maxReusableCapacity=256,this.stats=a?{acquired:0,released:0,rejected:{frozen:0,tooLarge:0,poolFull:0}}:null}acquire(){return a&&this.stats&&this.stats.acquired++,this.pool.pop()??[]}release(e,t){if(!(t&&e===t)){if(Object.isFrozen(e)){a&&this.stats&&this.stats.rejected.frozen++;return}if(e.length>this.maxReusableCapacity){a&&this.stats&&this.stats.rejected.tooLarge++;return}if(this.pool.length>=this.maxPoolSize){a&&this.stats&&this.stats.rejected.poolFull++;return}e.length=0,this.pool.push(e),a&&this.stats&&this.stats.released++}}getStats(){if(!a||!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,a&&this.stats&&(this.stats.acquired=0,this.stats.released=0,this.stats.rejected={frozen:0,tooLarge:0,poolFull:0})}}const h=Object.freeze([]),f=Object.freeze([]),_=Object.freeze([]),g=new k,I=new k,d=new k;function ge(i,e,t,s){if(e!==h&&t!==f)for(let r=0;r<e.length;r++){const o=e[r];o&&(o._tempUnsub=t[r])}const n=I.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):(l.checkCircular(o,s),n[r]=o.subscribe(s)))}if(e!==h)for(let r=0;r<e.length;r++){const o=e[r];o?._tempUnsub&&(o._tempUnsub(),o._tempUnsub=void 0)}return t!==f&&I.release(t),n}function R(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 te=c.RESOLVED|c.PENDING|c.REJECTED,L=Array(te+1).fill(O.IDLE);L[c.RESOLVED]=O.RESOLVED;L[c.PENDING]=O.PENDING;L[c.REJECTED]=O.REJECTED;class se extends H{constructor(e,t={}){if(typeof e!="function")throw new D(u.COMPUTED_MUST_BE_FUNCTION);if(super(),this._cachedErrors=null,this._errorCacheEpoch=-1,this._value=void 0,this.flags=c.DIRTY|c.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._functionSubscribersStore=new v,this._objectSubscribersStore=new v,this._dependencies=h,this._dependencyVersions=_,this._unsubscribes=f,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=>{}}),l.attachDebugInfo(this,"computed",this.id),l.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 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 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 C=r[o];C&&t.add(C)}}}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!==_&&(d.release(this._dependencyVersions),this._dependencyVersions=_),this._errorCacheEpoch=-1,this._cachedErrors=null}dispose(){if(this._unsubscribes!==f){for(let e=0;e<this._unsubscribes.length;e++){const t=this._unsubscribes[e];t&&t()}I.release(this._unsubscribes),this._unsubscribes=f}this._dependencies!==h&&(g.release(this._dependencies),this._dependencies=h),this._dependencyVersions!==_&&(d.release(this._dependencyVersions),this._dependencyVersions=_),this._functionSubscribersStore.clear(),this._objectSubscribersStore.clear(),this.flags=c.DIRTY|c.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&c.DIRTY)!==0}_setDirty(){this.flags|=c.DIRTY}_clearDirty(){this.flags&=-2}_isIdle(){return(this.flags&c.IDLE)!==0}_setIdle(){this.flags|=c.IDLE,this.flags&=-29}_isPending(){return(this.flags&c.PENDING)!==0}_setPending(){this.flags|=c.PENDING,this.flags&=-27}_isResolved(){return(this.flags&c.RESOLVED)!==0}_setResolved(){this.flags|=c.RESOLVED,this.flags&=-87}_isRejected(){return(this.flags&c.REJECTED)!==0}_setRejected(){this.flags|=c.REJECTED|c.HAS_ERROR,this.flags&=-15}_isRecomputing(){return(this.flags&c.RECOMPUTING)!==0}_setRecomputing(e){const t=c.RECOMPUTING;this.flags=this.flags&~t|-Number(e)&t}_getAsyncState(){return L[this.flags&te]}_getFlagsAsString(){const e=[];return this._isDirty()&&e.push("DIRTY"),this._isIdle()&&e.push("IDLE"),this._isPending()&&e.push("PENDING"),this._isResolved()&&e.push("RESOLVED"),this._isRejected()&&e.push("REJECTED"),this._isRecomputing()&&e.push("RECOMPUTING"),e.join(" | ")}_computeValue(){return this._isRecomputing()?this._value:((this._isDirty()||this._isIdle())&&this._recompute(),this._isPending()?this._handlePending():this._isRejected()?this._handleRejected():this._value)}_recompute(){if(this._isRecomputing())return;this._setRecomputing(!0);const e=this._prepareComputationContext();let t=!1;try{const s=y.run(this._trackable,this._fn);this._commitDependencies(e),t=!0,W(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=g.acquire(),n=d.acquire(),r=$(),o={depCount:0},C=p=>{p._lastSeenEpoch!==r&&(p._lastSeenEpoch=r,o.depCount<s.length?(s[o.depCount]=p,n[o.depCount]=p.version):(s.push(p),n.push(p.version)),o.depCount++)},N=this._trackable.addDependency;return this._trackable.addDependency=C,{prevDeps:e,prevVersions:t,nextDeps:s,nextVersions:n,originalAdd:N,state:o}}_commitDependencies(e){const{nextDeps:t,nextVersions:s,state:n,prevDeps:r}=e;t.length=n.depCount,s.length=n.depCount,this._unsubscribes=ge(t,r,this._unsubscribes,this),this._dependencies=t,this._dependencyVersions=s}_cleanupContext(e,t){this._trackable.addDependency=e.originalAdd,t?(e.prevDeps!==h&&g.release(e.prevDeps),e.prevVersions!==_&&d.release(e.prevVersions)):(g.release(e.nextDeps),d.release(e.nextVersions))}_handleSyncResult(e){const t=!this._isResolved()||!this._equal(this._value,e);this.version=this.version+Number(t)&m,this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),this._cachedErrors=null,this._errorCacheEpoch=-1}_handleAsyncComputation(e){this._setPending(),this._clearDirty(),this._notifyJob(),this._promiseId=this._promiseId>=this.MAX_PROMISE_ID?1:this._promiseId+1;const t=this._promiseId;e.then(s=>{t===this._promiseId&&this._handleAsyncResolution(s)}).catch(s=>{t===this._promiseId&&this._handleAsyncRejection(s)})}_handleAsyncResolution(e){const t=!this._isResolved()||!this._equal(this._value,e);this.version=this.version+Number(t)&m,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=R(e,D,u.COMPUTED_ASYNC_COMPUTATION_FAILED),s=!this._isRejected();if(this.version=this.version+Number(s)&m,this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(n){console.error(u.CALLBACK_ERROR_IN_ERROR_HANDLER,n)}this._notifyJob()}_handleComputationError(e){const t=R(e,D,u.COMPUTED_COMPUTATION_FAILED);if(this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(s){console.error(u.CALLBACK_ERROR_IN_ERROR_HANDLER,s)}throw t}_handlePending(){if(this._hasDefaultValue)return this._defaultValue;throw new D(u.COMPUTED_ASYNC_PENDING_NO_DEFAULT)}_handleRejected(){if(this._error?.recoverable&&this._hasDefaultValue)return this._defaultValue;throw this._error}execute(){this._markDirty()}_markDirty(){this._isRecomputing()||this._isDirty()||(this._setDirty(),this._notifyJob())}_registerTracking(){const e=y.getCurrent();if(e){if(K(e)){e.addDependency(this);return}if(Z(e)){this._functionSubscribersStore.add(e);return}ee(e)&&this._objectSubscribersStore.add(e)}}}Object.freeze(se.prototype);function De(i,e={}){return new se(i,e)}class Ie extends Y{constructor(e,t={}){super(),this.run=()=>{if(this.isDisposed)throw new b(u.EFFECT_MUST_BE_FUNCTION);this._dependencyVersions!==_&&(d.release(this._dependencyVersions),this._dependencyVersions=_),this.execute()},this.dispose=()=>{if(!this.isDisposed){if(this._setDisposed(),this._safeCleanup(),this._unsubscribes!==f){for(let s=0;s<this._unsubscribes.length;s++){const n=this._unsubscribes[s];n&&n()}I.release(this._unsubscribes),this._unsubscribes=f}this._dependencies!==h&&(g.release(this._dependencies),this._dependencies=h),this._dependencyVersions!==_&&(d.release(this._dependencyVersions),this._dependencyVersions=_)}},this.addDependency=s=>{if(this.isExecuting&&this._nextDeps&&this._nextUnsubs&&this._nextVersions){const n=this._currentEpoch;if(s._lastSeenEpoch===n)return;s._lastSeenEpoch=n,this._nextDeps.push(s),this._nextVersions.push(s.version),s._tempUnsub?(this._nextUnsubs.push(s._tempUnsub),s._tempUnsub=void 0):this._subscribeTo(s)}},this.execute=()=>{if(this.isDisposed||this.isExecuting||!this._shouldExecute())return;this._checkInfiniteLoop(),this._setExecuting(!0),this._safeCleanup();const s=this._prepareEffectContext();let n=!1;try{const r=y.run(this,this._fn);this._commitEffect(s),n=!0,this._checkLoopWarnings(),W(r)?r.then(o=>{!this.isDisposed&&typeof o=="function"&&(this._cleanup=o)}).catch(o=>{console.error(R(o,b,u.EFFECT_EXECUTION_FAILED))}):this._cleanup=typeof r=="function"?r:null}catch(r){n=!0,console.error(R(r,b,u.EFFECT_EXECUTION_FAILED)),this._cleanup=null}finally{this._cleanupEffect(s,n),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=h,this._dependencyVersions=_,this._unsubscribes=f,this._nextDeps=null,this._nextVersions=null,this._nextUnsubs=null,this._history=a?[]:null,this._executionCount=0,l.attachDebugInfo(this,"effect",this.id)}_prepareEffectContext(){const e=this._dependencies,t=this._dependencyVersions,s=this._unsubscribes,n=g.acquire(),r=d.acquire(),o=I.acquire(),C=$();if(e!==h&&s!==f)for(let N=0;N<e.length;N++){const p=e[N];p&&(p._tempUnsub=s[N])}return this._nextDeps=n,this._nextVersions=r,this._nextUnsubs=o,this._currentEpoch=C,{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!==h){for(let s=0;s<e.prevDeps.length;s++){const n=e.prevDeps[s];n?._tempUnsub&&(n._tempUnsub(),n._tempUnsub=void 0)}g.release(e.prevDeps)}e.prevUnsubs!==f&&I.release(e.prevUnsubs),e.prevVersions!==_&&d.release(e.prevVersions)}else{g.release(e.nextDeps),d.release(e.nextVersions);for(let s=0;s<e.nextUnsubs.length;s++)e.nextUnsubs[s]?.();if(I.release(e.nextUnsubs),e.prevDeps!==h)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(R(t,b,u.EFFECT_EXECUTION_FAILED)),this._nextUnsubs&&this._nextUnsubs.push(()=>{})}}get isDisposed(){return(this.flags&U.DISPOSED)!==0}get executionCount(){return this._executionCount}get isExecuting(){return(this.flags&U.EXECUTING)!==0}_setDisposed(){this.flags|=U.DISPOSED}_setExecuting(e){const t=U.EXECUTING;this.flags=this.flags&~t|-Number(e)&t}_safeCleanup(){if(this._cleanup){try{this._cleanup()}catch(e){console.error(R(e,b,u.EFFECT_CLEANUP_FAILED))}this._cleanup=null}}_checkInfiniteLoop(){if(this._lastFlushEpoch!==F&&(this._lastFlushEpoch=F,this._executionsInEpoch=0),this._executionsInEpoch++,this._executionsInEpoch>this._maxExecutionsPerFlush&&this._throwInfiniteLoopError("per-effect"),ae()>S.MAX_EXECUTIONS_PER_FLUSH&&this._throwInfiniteLoopError("global"),this._executionCount++,this._history){const e=Date.now();this._history.push(e),this._history.length>S.MAX_EXECUTIONS_PER_SECOND+10&&this._history.shift(),this._checkTimestampLoop(e)}}_checkTimestampLoop(e){const t=this._history;if(!t||this._maxExecutions<=0)return;const s=e-ie.ONE_SECOND_MS;let n=0;for(let r=t.length-1;r>=0&&!(t[r]<s);r--)n++;if(n>this._maxExecutions){const r=new b(`Effect executed ${n} times within 1 second. Infinite loop suspected`);if(this.dispose(),console.error(r),a)throw r}}_throwInfiniteLoopError(e){const t=new b(`Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${B}`);throw this.dispose(),console.error(t),t}_shouldExecute(){if(this._dependencies===h||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{J(()=>t.value)}catch{return!0}if(t.version!==this._dependencyVersions[e])return!0}}return!1}_checkLoopWarnings(){if(this._trackModifications&&l.enabled){const e=this._dependencies;for(let t=0;t<e.length;t++){const s=e[t];s&&s._modifiedAtEpoch===this._currentEpoch&&l.warn(!0,`Effect is reading a dependency (${l.getDebugName(s)||"unknown"}) that it just modified. Infinite loop may occur`)}}}}function me(i,e={}){if(typeof i!="function")throw new b(u.EFFECT_MUST_BE_FUNCTION);const t=new Ie(i,e);return t.execute(),t}exports.AsyncState=O;exports.AtomError=E;exports.ComputedError=D;exports.DEBUG_CONFIG=w;exports.DEBUG_RUNTIME=l;exports.EffectError=b;exports.POOL_CONFIG=ne;exports.SCHEDULER_CONFIG=S;exports.SchedulerError=A;exports.atom=Se;exports.batch=fe;exports.computed=De;exports.effect=me;exports.isAtom=Q;exports.isComputed=de;exports.isEffect=Ee;exports.scheduler=T;exports.untracked=J;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|