@but212/atom-effect 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -8
- package/dist/atom-effect.min.js +1 -1
- package/dist/atom-effect.min.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +79 -21
- package/dist/index.mjs +408 -262
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
a signal for reactive state management.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
@@ -143,13 +143,14 @@ pnpm build # Build production bundle
|
|
|
143
143
|
|
|
144
144
|
| Operation | Performance |
|
|
145
145
|
| --- | --- |
|
|
146
|
-
| Atom creation | ~
|
|
147
|
-
| Atom read
|
|
148
|
-
|
|
|
149
|
-
| Computed
|
|
150
|
-
|
|
|
151
|
-
|
|
|
152
|
-
|
|
|
146
|
+
| Atom creation | ~6.16M ops/sec |
|
|
147
|
+
| Atom read | ~11.56M ops/sec |
|
|
148
|
+
| Atom write | ~9.45M ops/sec |
|
|
149
|
+
| Computed creation | ~1.85M ops/sec |
|
|
150
|
+
| Computed recomputation | ~558K ops/sec |
|
|
151
|
+
| Effect execution | ~2.49M ops/sec |
|
|
152
|
+
| Batched updates | ~4.11M ops/sec |
|
|
153
|
+
| Deep chain (100 levels) | ~8.48K ops/sec |
|
|
153
154
|
|
|
154
155
|
## Contributing
|
|
155
156
|
|
package/dist/atom-effect.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(c,A){typeof exports=="object"&&typeof module<"u"?A(exports):typeof define=="function"&&define.amd?define(["exports"],A):(c=typeof globalThis<"u"?globalThis:c||self,A(c.AtomEffect={}))})(this,(function(c){"use strict";const A={ONE_SECOND_MS:1e3},O={IDLE:"idle",PENDING:"pending",RESOLVED:"resolved",REJECTED:"rejected"},F={DISPOSED:1,EXECUTING:2},h={DIRTY:1,IDLE:2,PENDING:4,RESOLVED:8,REJECTED:16,RECOMPUTING:32,HAS_ERROR:64},ie={MAX_SIZE:1e3,WARMUP_SIZE:100},g={MAX_EXECUTIONS_PER_SECOND:1e3,CLEANUP_THRESHOLD:1e3,MAX_EXECUTIONS_PER_EFFECT:100,MAX_EXECUTIONS_PER_FLUSH:1e4,MAX_FLUSH_ITERATIONS:1e3,MIN_FLUSH_ITERATIONS:10},w={MAX_DEPENDENCIES:1e3,WARN_INFINITE_LOOP:!0},I=1073741823,l=typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production",ne=Object.freeze([]);class E extends Error{constructor(e,t=null,s=!0){super(e),this.name="AtomError",this.cause=t,this.recoverable=s,this.timestamp=new Date}}class m extends E{constructor(e,t=null){super(e,t,!0),this.name="ComputedError"}}class D extends E{constructor(e,t=null){super(e,t,!1),this.name="EffectError"}}class U extends E{constructor(e,t=null){super(e,t,!1),this.name="SchedulerError"}}const u={COMPUTED_MUST_BE_FUNCTION:"Computed function must be a function",COMPUTED_ASYNC_PENDING_NO_DEFAULT:"Async computation is pending. No default value provided",COMPUTED_COMPUTATION_FAILED:"Computed computation failed",COMPUTED_ASYNC_COMPUTATION_FAILED:"Async computed computation failed",ATOM_SUBSCRIBER_MUST_BE_FUNCTION:"Subscription listener must be a function or Subscriber object",ATOM_INDIVIDUAL_SUBSCRIBER_FAILED:"Error during individual atom subscriber execution",EFFECT_MUST_BE_FUNCTION:"Effect function must be a function",EFFECT_EXECUTION_FAILED:"Effect execution failed",EFFECT_CLEANUP_FAILED:"Effect cleanup function execution failed",CALLBACK_ERROR_IN_ERROR_HANDLER:"Error occurred during onError callback execution"},k=Symbol("debugName"),re=Symbol("id"),B=Symbol("type"),z=Symbol("noDefaultValue");function oe(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(oe(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[k]=`${e}_${t}`,s[re]=t,s[B]=e},getDebugName(i){if(i!=null&&k in i)return i[k]},getDebugType(i){if(i!=null&&B in i)return i[B]}};let ce=1;const he=()=>ce++;class Y{constructor(){this.id=he()&I,this.flags=0}}class Q extends Y{constructor(){super(),this.version=0,this._lastSeenEpoch=-1}subscribe(e){if(typeof e=="object"&&e!==null&&"execute"in e)return this._objectSubscribers.add(e);if(typeof e!="function")throw new E(u.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);return this._functionSubscribers.add(e)}subscriberCount(){return this._functionSubscribers.size+this._objectSubscribers.size}_notifySubscribers(e,t){this._functionSubscribers.forEachSafe(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 v=0;function H(){return v=v+1&I||1,v}function ue(){return v}let P=0,j=0,M=!1;function $(){return M?(l&&console.warn("Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"),!1):(M=!0,P=P+1&I,j=0,!0)}function J(){M=!1}function ae(){return M?++j:0}class _e{constructor(){this.queueA=[],this.queueB=[],this.queue=this.queueA,this.queueSize=0,this._epoch=0,this.isProcessing=!1,this.isBatching=!1,this.batchDepth=0,this.batchQueue=[],this.batchQueueSize=0,this.isFlushingSync=!1,this.maxFlushIterations=g.MAX_FLUSH_ITERATIONS}get phase(){return this.isProcessing||this.isFlushingSync?2:this.isBatching?1:0}schedule(e){if(typeof e!="function")throw new U("Scheduler callback must be a function");e._nextEpoch!==this._epoch&&(e._nextEpoch=this._epoch,this.isBatching||this.isFlushingSync?this.batchQueue[this.batchQueueSize++]=e:(this.queue[this.queueSize++]=e,this.isProcessing||this.flush()))}flush(){this.isProcessing||this.queueSize===0||(this.isProcessing=!0,queueMicrotask(()=>{try{if(this.queueSize===0)return;const e=$();this._drainQueue(),e&&J()}finally{this.isProcessing=!1,this.queueSize>0&&!this.isBatching&&this.flush()}}))}flushSync(){this.isFlushingSync=!0;const e=$();try{this._mergeBatchQueue(),this._drainQueue()}finally{this.isFlushingSync=!1,e&&J()}}_mergeBatchQueue(){if(this._epoch++,this.batchQueueSize>0){for(let e=0;e<this.batchQueueSize;e++){const t=this.batchQueue[e];t&&t._nextEpoch!==this._epoch&&(t._nextEpoch=this._epoch,this.queue[this.queueSize++]=t)}this.batchQueueSize=0}}_drainQueue(){let e=0;for(;this.queueSize>0;){if(++e>this.maxFlushIterations){this._handleFlushOverflow();break}this._processCurrentQueue(),this._mergeBatchQueue()}}_processCurrentQueue(){const e=this.queue,t=this.queueSize;this.queue=this.queue===this.queueA?this.queueB:this.queueA,this.queueSize=0,this._epoch++,this._processJobs(e,t)}_handleFlushOverflow(){console.error(new U(`Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop.`)),this.queueSize=0,this.queue.length=0,this.batchQueueSize=0}_processJobs(e,t){for(let s=0;s<t;s++)try{e[s]?.()}catch(n){console.error(new U("Error occurred during scheduler execution",n))}e.length=0}startBatch(){this.batchDepth++,this.isBatching=!0}endBatch(){this.batchDepth=Math.max(0,this.batchDepth-1),this.batchDepth===0&&(this.flushSync(),this.isBatching=!1)}setMaxFlushIterations(e){if(e<g.MIN_FLUSH_ITERATIONS)throw new U(`Max flush iterations must be at least ${g.MIN_FLUSH_ITERATIONS}`);this.maxFlushIterations=e}}const R=new _e;function le(i){if(typeof i!="function")throw new E("Batch callback must be a function");R.startBatch();try{return i()}finally{R.endBatch()}}class fe{constructor(){this.current=null}run(e,t){const s=this.current;this.current=e;try{return t()}finally{this.current=s}}getCurrent(){return this.current}}const C=new fe;function W(i){if(typeof i!="function")throw new E("Untracked callback must be a function");const e=C.current;C.current=null;try{return i()}finally{C.current=e}}class L{constructor(){this.subscribers=null}add(e){if(this.subscribers||(this.subscribers=[]),this.subscribers.indexOf(e)!==-1)return()=>{};this.subscribers.push(e);let t=!1;return()=>{t||(t=!0,this.remove(e))}}remove(e){if(!this.subscribers)return!1;const t=this.subscribers.indexOf(e);if(t===-1)return!1;const s=this.subscribers.length-1;return t!==s&&(this.subscribers[t]=this.subscribers[s]),this.subscribers.pop(),!0}has(e){return this.subscribers?this.subscribers.indexOf(e)!==-1:!1}forEach(e){if(this.subscribers)for(let t=0;t<this.subscribers.length;t++)e(this.subscribers[t],t)}forEachSafe(e,t){if(this.subscribers)for(let s=0;s<this.subscribers.length;s++)try{e(this.subscribers[s],s)}catch(n){t?t(n):console.error("[SubscriberManager] Error in subscriber callback:",n)}}get size(){return this.subscribers?.length??0}get hasSubscribers(){return this.subscribers!==null&&this.subscribers.length>0}clear(){this.subscribers=null}toArray(){return this.subscribers?[...this.subscribers]:[]}}class q{constructor(){this.pool=[],this.maxPoolSize=50,this.maxReusableCapacity=256,this.stats=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 a=Object.freeze([]),p=Object.freeze([]),_=Object.freeze([]),y=new q,N=new q,b=new q;function K(i){return i!==null&&typeof i=="object"&&"value"in i&&"subscribe"in i&&typeof i.subscribe=="function"}function de(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 Ee(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 pe(i){return typeof i=="object"&&i!==null}function be(i){return(typeof i=="object"||typeof i=="function")&&i!==null&&typeof i.addDependency=="function"}function Se(i){return typeof i=="function"&&typeof i.addDependency!="function"}function ge(i){return pe(i)&&typeof i.execute=="function"}function ee(i,e,t,s){if(e){if(be(e)){e.addDependency(i);return}if(Se(e)){t.add(e);return}ge(e)&&s.add(e)}}function De(i,e,t,s){if(e!==a&&t!==p)for(let r=0;r<e.length;r++){const o=e[r];o&&(o._tempUnsub=t[r])}const n=N.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!==a)for(let r=0;r<e.length;r++){const o=e[r];o?._tempUnsub&&(o._tempUnsub(),o._tempUnsub=void 0)}return t!==p&&N.release(t),n}class ye extends Q{constructor(e,t){super(),this._isNotificationScheduled=!1,this._value=e,this._functionSubscribersStore=new L,this._objectSubscribersStore=new L,this._sync=t,this._notifyTask=this._flushNotifications.bind(this),f.attachDebugInfo(this,"atom",this.id)}get _functionSubscribers(){return this._functionSubscribersStore}get _objectSubscribers(){return this._objectSubscribersStore}get value(){const e=C.getCurrent();return e&&this._track(e),this._value}set value(e){if(Object.is(this._value,e))return;const t=this._value;this.version=this.version+1&I,this._value=e,!(!this._functionSubscribersStore.hasSubscribers&&!this._objectSubscribersStore.hasSubscribers)&&this._scheduleNotification(t)}_track(e){ee(this,e,this._functionSubscribersStore,this._objectSubscribersStore)}_scheduleNotification(e){this._isNotificationScheduled||(this._pendingOldValue=e,this._isNotificationScheduled=!0),this._sync&&!R.isBatching?this._flushNotifications():R.schedule(this._notifyTask)}_flushNotifications(){if(!this._isNotificationScheduled)return;const e=this._pendingOldValue,t=this._value;this._pendingOldValue=void 0,this._isNotificationScheduled=!1,this._notifySubscribers(t,e)}peek(){return this._value}dispose(){this._functionSubscribersStore.clear(),this._objectSubscribersStore.clear(),this._value=void 0}}function Ie(i,e={}){return new ye(i,e.sync??!1)}function x(i,e,t){if(i instanceof TypeError)return new e(`Type error (${t}): ${i.message}`,i);if(i instanceof ReferenceError)return new e(`Reference error (${t}): ${i.message}`,i);if(i instanceof E)return i;const s=i instanceof Error?i.message:String(i),n=i instanceof Error?i:null;return new e(`Unexpected error (${t}): ${s}`,n)}const te=h.RESOLVED|h.PENDING|h.REJECTED,V=Array(te+1).fill(O.IDLE);V[h.RESOLVED]=O.RESOLVED,V[h.PENDING]=O.PENDING,V[h.REJECTED]=O.REJECTED;class se extends Q{constructor(e,t={}){if(typeof e!="function")throw new m(u.COMPUTED_MUST_BE_FUNCTION);if(super(),this._cachedErrors=null,this._errorCacheEpoch=-1,this._value=void 0,this.flags=h.DIRTY|h.IDLE,this._error=null,this._promiseId=0,this._equal=t.equal??Object.is,this._fn=e,this._defaultValue="defaultValue"in t?t.defaultValue:z,this._hasDefaultValue=this._defaultValue!==z,this._onError=t.onError??null,this.MAX_PROMISE_ID=Number.MAX_SAFE_INTEGER-1,this._functionSubscribersStore=new L,this._objectSubscribersStore=new L,this._dependencies=a,this._dependencyVersions=_,this._unsubscribes=p,this._notifyJob=()=>{this._functionSubscribersStore.forEachSafe(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 ne;const e=ue();if(this._errorCacheEpoch===e&&this._cachedErrors!==null)return this._cachedErrors;const t=new Set;this._error&&t.add(this._error);for(let 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 d=r[o];d&&t.add(d)}}}return this._cachedErrors=Object.freeze([...t]),this._errorCacheEpoch=e,this._cachedErrors}get lastError(){return this._registerTracking(),this._error}get isPending(){return this._registerTracking(),this._isPending()}get isResolved(){return this._registerTracking(),this._isResolved()}invalidate(){this._markDirty(),this._dependencyVersions!==_&&(b.release(this._dependencyVersions),this._dependencyVersions=_),this._errorCacheEpoch=-1,this._cachedErrors=null}dispose(){if(this._unsubscribes!==p){for(let e=0;e<this._unsubscribes.length;e++){const t=this._unsubscribes[e];t&&t()}N.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==a&&(y.release(this._dependencies),this._dependencies=a),this._dependencyVersions!==_&&(b.release(this._dependencyVersions),this._dependencyVersions=_),this._functionSubscribersStore.clear(),this._objectSubscribersStore.clear(),this.flags=h.DIRTY|h.IDLE,this._error=null,this._value=void 0,this._promiseId=(this._promiseId+1)%this.MAX_PROMISE_ID,this._cachedErrors=null,this._errorCacheEpoch=-1}_isDirty(){return(this.flags&h.DIRTY)!==0}_setDirty(){this.flags|=h.DIRTY}_clearDirty(){this.flags&=-2}_isIdle(){return(this.flags&h.IDLE)!==0}_setIdle(){this.flags|=h.IDLE,this.flags&=-29}_isPending(){return(this.flags&h.PENDING)!==0}_setPending(){this.flags|=h.PENDING,this.flags&=-27}_isResolved(){return(this.flags&h.RESOLVED)!==0}_setResolved(){this.flags|=h.RESOLVED,this.flags&=-87}_isRejected(){return(this.flags&h.REJECTED)!==0}_setRejected(){this.flags|=h.REJECTED|h.HAS_ERROR,this.flags&=-15}_isRecomputing(){return(this.flags&h.RECOMPUTING)!==0}_setRecomputing(e){const t=h.RECOMPUTING;this.flags=this.flags&~t|-Number(e)&t}_getAsyncState(){return V[this.flags&te]}_getFlagsAsString(){const e=[];return this._isDirty()&&e.push("DIRTY"),this._isIdle()&&e.push("IDLE"),this._isPending()&&e.push("PENDING"),this._isResolved()&&e.push("RESOLVED"),this._isRejected()&&e.push("REJECTED"),this._isRecomputing()&&e.push("RECOMPUTING"),e.join(" | ")}_computeValue(){return this._isRecomputing()?this._value:((this._isDirty()||this._isIdle())&&this._recompute(),this._isPending()?this._handlePending():this._isRejected()?this._handleRejected():this._value)}_recompute(){if(this._isRecomputing())return;this._setRecomputing(!0);const e=this._prepareComputationContext();let t=!1;try{const s=C.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=y.acquire(),n=b.acquire(),r=H(),o={depCount:0},d=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++)},T=this._trackable.addDependency;return this._trackable.addDependency=d,{prevDeps:e,prevVersions:t,nextDeps:s,nextVersions:n,originalAdd:T,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!==a&&y.release(e.prevDeps),e.prevVersions!==_&&b.release(e.prevVersions)):(y.release(e.nextDeps),b.release(e.nextVersions))}_handleSyncResult(e){const t=!this._isResolved()||!this._equal(this._value,e);this.version=this.version+Number(t)&I,this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),this._cachedErrors=null,this._errorCacheEpoch=-1}_handleAsyncComputation(e){this._setPending(),this._clearDirty(),this._notifyJob(),this._promiseId=this._promiseId>=this.MAX_PROMISE_ID?1:this._promiseId+1;const t=this._promiseId;e.then(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=x(e,m,u.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(u.CALLBACK_ERROR_IN_ERROR_HANDLER,n)}this._notifyJob()}_handleComputationError(e){const t=x(e,m,u.COMPUTED_COMPUTATION_FAILED);if(this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(s){console.error(u.CALLBACK_ERROR_IN_ERROR_HANDLER,s)}throw t}_handlePending(){if(this._hasDefaultValue)return this._defaultValue;throw new m(u.COMPUTED_ASYNC_PENDING_NO_DEFAULT)}_handleRejected(){if(this._error?.recoverable&&this._hasDefaultValue)return this._defaultValue;throw this._error}execute(){this._markDirty()}_markDirty(){this._isRecomputing()||this._isDirty()||(this._setDirty(),this._notifyJob())}_registerTracking(){ee(this,C.getCurrent(),this._functionSubscribersStore,this._objectSubscribersStore)}}Object.freeze(se.prototype);function me(i,e={}){return new se(i,e)}class Ce extends Y{constructor(e,t={}){super(),this.run=()=>{if(this.isDisposed)throw new D(u.EFFECT_MUST_BE_FUNCTION);this._dependencyVersions!==_&&(b.release(this._dependencyVersions),this._dependencyVersions=_),this.execute()},this.dispose=()=>{if(!this.isDisposed){if(this._setDisposed(),this._safeCleanup(),this._unsubscribes!==p){for(let n=0;n<this._unsubscribes.length;n++){const r=this._unsubscribes[n];r&&r()}N.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==a&&(y.release(this._dependencies),this._dependencies=a),this._dependencyVersions!==_&&(b.release(this._dependencyVersions),this._dependencyVersions=_)}},this.addDependency=n=>{if(this.isExecuting&&this._nextDeps&&this._nextUnsubs&&this._nextVersions){const r=this._currentEpoch;if(n._lastSeenEpoch===r)return;n._lastSeenEpoch=r,this._nextDeps.push(n),this._nextVersions.push(n.version),n._tempUnsub?(this._nextUnsubs.push(n._tempUnsub),n._tempUnsub=void 0):this._subscribeTo(n)}},this.execute=()=>{if(this.isDisposed||this.isExecuting||!this._shouldExecute())return;this._checkInfiniteLoop(),this._setExecuting(!0),this._safeCleanup();const n=this._prepareEffectContext();let r=!1;try{const o=C.run(this,this._fn);this._commitEffect(n),r=!0,this._checkLoopWarnings(),Z(o)?o.then(d=>{!this.isDisposed&&typeof d=="function"&&(this._cleanup=d)}).catch(d=>{this._handleExecutionError(d)}):this._cleanup=typeof o=="function"?o:null}catch(o){r=!0,this._handleExecutionError(o),this._cleanup=null}finally{this._cleanupEffect(n,r),this._setExecuting(!1)}},this._currentEpoch=-1,this._lastFlushEpoch=-1,this._executionsInEpoch=0,this._fn=e,this._sync=t.sync??!1,this._maxExecutions=t.maxExecutionsPerSecond??g.MAX_EXECUTIONS_PER_SECOND,this._maxExecutionsPerFlush=t.maxExecutionsPerFlush??g.MAX_EXECUTIONS_PER_EFFECT,this._trackModifications=t.trackModifications??!1,this._cleanup=null,this._dependencies=a,this._dependencyVersions=_,this._unsubscribes=p,this._nextDeps=null,this._nextVersions=null,this._nextUnsubs=null,this._onError=t.onError??null,this._historyPtr=0;const s=Number.isFinite(this._maxExecutions);this._historyCapacity=s?Math.min(this._maxExecutions+1,g.MAX_EXECUTIONS_PER_SECOND+1):0,this._history=l&&s&&this._historyCapacity>0?new Array(this._historyCapacity).fill(0):null,this._executionCount=0,f.attachDebugInfo(this,"effect",this.id)}_prepareEffectContext(){const e=this._dependencies,t=this._dependencyVersions,s=this._unsubscribes,n=y.acquire(),r=b.acquire(),o=N.acquire(),d=H();if(e!==a&&s!==p)for(let T=0;T<e.length;T++){const S=e[T];S&&(S._tempUnsub=s[T])}return this._nextDeps=n,this._nextVersions=r,this._nextUnsubs=o,this._currentEpoch=d,{prevDeps:e,prevVersions:t,prevUnsubs:s,nextDeps:n,nextVersions:r,nextUnsubs:o}}_commitEffect(e){const t=e.nextDeps.length;e.nextDeps.length=t,e.nextVersions.length=t,this._dependencies=e.nextDeps,this._dependencyVersions=e.nextVersions,this._unsubscribes=e.nextUnsubs}_cleanupEffect(e,t){if(this._nextDeps=null,this._nextVersions=null,this._nextUnsubs=null,t){if(e.prevDeps!==a){for(let s=0;s<e.prevDeps.length;s++){const n=e.prevDeps[s];n?._tempUnsub&&(n._tempUnsub(),n._tempUnsub=void 0)}y.release(e.prevDeps)}e.prevUnsubs!==p&&N.release(e.prevUnsubs),e.prevVersions!==_&&b.release(e.prevVersions)}else{y.release(e.nextDeps),b.release(e.nextVersions);for(let s=0;s<e.nextUnsubs.length;s++)e.nextUnsubs[s]?.();if(N.release(e.nextUnsubs),e.prevDeps!==a)for(let s=0;s<e.prevDeps.length;s++){const n=e.prevDeps[s];n&&(n._tempUnsub=void 0)}}}_subscribeTo(e){try{const t=e.subscribe(()=>{this._trackModifications&&this.isExecuting&&(e._modifiedAtEpoch=this._currentEpoch),this._sync?this.execute():R.schedule(this.execute)});this._nextUnsubs&&this._nextUnsubs.push(t)}catch(t){console.error(x(t,D,u.EFFECT_EXECUTION_FAILED)),this._nextUnsubs&&this._nextUnsubs.push(()=>{})}}get isDisposed(){return(this.flags&F.DISPOSED)!==0}get executionCount(){return this._executionCount}get isExecuting(){return(this.flags&F.EXECUTING)!==0}_setDisposed(){this.flags|=F.DISPOSED}_setExecuting(e){const t=F.EXECUTING;this.flags=this.flags&~t|-Number(e)&t}_safeCleanup(){if(this._cleanup){try{this._cleanup()}catch(e){console.error(x(e,D,u.EFFECT_CLEANUP_FAILED))}this._cleanup=null}}_checkInfiniteLoop(){if(this._lastFlushEpoch!==P&&(this._lastFlushEpoch=P,this._executionsInEpoch=0),this._executionsInEpoch++,this._executionsInEpoch>this._maxExecutionsPerFlush&&this._throwInfiniteLoopError("per-effect"),ae()>g.MAX_EXECUTIONS_PER_FLUSH&&this._throwInfiniteLoopError("global"),this._executionCount++,this._history&&this._maxExecutions>0){const e=Date.now(),t=this._historyPtr,s=this._historyCapacity;this._history[t]=e;const n=(t+1)%s,r=this._history[n]??0;if(this._historyPtr=n,r>0&&e-r<A.ONE_SECOND_MS){const o=new D(`Effect executed ${s} times within 1 second. Infinite loop suspected`);if(this.dispose(),console.error(o),this._onError&&this._onError(o),l)throw o}}}_throwInfiniteLoopError(e){const t=new D(`Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${j}`);throw this.dispose(),console.error(t),t}_shouldExecute(){if(this._dependencies===a||this._dependencyVersions===_)return!0;for(let e=0;e<this._dependencies.length;e++){const t=this._dependencies[e];if(t){if("value"in t)try{W(()=>t.value)}catch{return!0}if(t.version!==this._dependencyVersions[e])return!0}}return!1}_handleExecutionError(e){const t=x(e,D,u.EFFECT_EXECUTION_FAILED);console.error(t),this._onError&&this._onError(t)}_checkLoopWarnings(){if(this._trackModifications&&f.enabled){const e=this._dependencies;for(let t=0;t<e.length;t++){const 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 Ne(i,e={}){if(typeof i!="function")throw new D(u.EFFECT_MUST_BE_FUNCTION);const t=new Ce(i,e);return t.execute(),t}c.AsyncState=O,c.AtomError=E,c.ComputedError=m,c.DEBUG_CONFIG=w,c.DEBUG_RUNTIME=f,c.EffectError=D,c.POOL_CONFIG=ie,c.SCHEDULER_CONFIG=g,c.SchedulerError=U,c.atom=Ie,c.batch=le,c.computed=me,c.effect=Ne,c.isAtom=K,c.isComputed=de,c.isEffect=Ee,c.scheduler=R,c.untracked=W,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})}));
|
|
1
|
+
(function(u,N){typeof exports=="object"&&typeof module<"u"?N(exports):typeof define=="function"&&define.amd?define(["exports"],N):(u=typeof globalThis<"u"?globalThis:u||self,N(u.AtomEffect={}))})(this,(function(u){"use strict";const N={ONE_SECOND_MS:1e3},O={IDLE:"idle",PENDING:"pending",RESOLVED:"resolved",REJECTED:"rejected"},P={DISPOSED:1,EXECUTING:2},h={DIRTY:1,IDLE:2,PENDING:4,RESOLVED:8,REJECTED:16,RECOMPUTING:32,HAS_ERROR:64},U={SYNC:1,NOTIFICATION_SCHEDULED:2},re={MAX_SIZE:1e3,WARMUP_SIZE:100},S={MAX_EXECUTIONS_PER_SECOND:1e3,CLEANUP_THRESHOLD:1e3,MAX_EXECUTIONS_PER_EFFECT:100,MAX_EXECUTIONS_PER_FLUSH:1e4,MAX_FLUSH_ITERATIONS:1e3,MIN_FLUSH_ITERATIONS:10},j={MAX_DEPENDENCIES:1e3,WARN_INFINITE_LOOP:!0},y=1073741823,z=1<<19,f=typeof process<"u"&&process.env&&process.env.NODE_ENV!=="production",oe=Object.freeze([]);class E extends Error{constructor(e,t=null,s=!0){super(e),this.name="AtomError",this.cause=t,this.recoverable=s,this.timestamp=new Date}}class D extends E{constructor(e,t=null){super(e,t,!0),this.name="ComputedError"}}class I extends E{constructor(e,t=null){super(e,t,!1),this.name="EffectError"}}class F extends E{constructor(e,t=null){super(e,t,!1),this.name="SchedulerError"}}const c={COMPUTED_MUST_BE_FUNCTION:"Computed function must be a function",COMPUTED_ASYNC_PENDING_NO_DEFAULT:"Async computation is pending. No default value provided",COMPUTED_COMPUTATION_FAILED:"Computed computation failed",COMPUTED_ASYNC_COMPUTATION_FAILED:"Async computed computation failed",ATOM_SUBSCRIBER_MUST_BE_FUNCTION:"Subscription listener must be a function or Subscriber object",ATOM_INDIVIDUAL_SUBSCRIBER_FAILED:"Error during individual atom subscriber execution",EFFECT_MUST_BE_FUNCTION:"Effect function must be a function",EFFECT_EXECUTION_FAILED:"Effect execution failed",EFFECT_CLEANUP_FAILED:"Effect cleanup function execution failed",CALLBACK_ERROR_IN_ERROR_HANDLER:"Error occurred during onError callback execution"},k=Symbol("debugName"),ue=Symbol("id"),B=Symbol("type"),G=Symbol("noDefaultValue");function he(i){return"dependencies"in i&&Array.isArray(i.dependencies)}let X=0;function Y(i,e,t){if(i._visitedEpoch!==t){if(i._visitedEpoch=t,i===e)throw new D("Indirect circular dependency detected");if(he(i)){const s=i.dependencies;for(let n=0;n<s.length;n++){const r=s[n];r&&Y(r,e,t)}}}}const d={enabled:typeof process<"u"&&process.env?.NODE_ENV==="development",maxDependencies:j.MAX_DEPENDENCIES,warnInfiniteLoop:j.WARN_INFINITE_LOOP,warn(i,e){this.enabled&&i&&console.warn(`[Atom Effect] ${e}`)},checkCircular(i,e){if(i===e)throw new D("Direct circular dependency detected");this.enabled&&(X++,Y(i,e,X))},attachDebugInfo(i,e,t){if(!this.enabled)return;const s=i;s[k]=`${e}_${t}`,s[ue]=t,s[B]=e},getDebugName(i){if(i!=null&&k in i)return i[k]},getDebugType(i){if(i!=null&&B in i)return i[B]}};let ce=1;const ae=()=>ce++;class H{constructor(){this.id=ae()&y,this.flags=0,this.version=0}rotatePhase(){return this.version=this.version+1&y,this.version}getShift(e){return this.version-e&y}}class $ extends H{constructor(){super(),this._lastSeenEpoch=-1}subscribe(e){if(typeof e=="object"&&e!==null&&"execute"in e)return this._objectSubscribers.add(e);if(typeof e!="function")throw new E(c.ATOM_SUBSCRIBER_MUST_BE_FUNCTION);return this._functionSubscribers.add(e)}subscriberCount(){return this._functionSubscribers.size+this._objectSubscribers.size}_notifySubscribers(e,t){this._functionSubscribers.forEachSafe(s=>s(e,t),s=>console.error(new E(c.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,s))),this._objectSubscribers.forEachSafe(s=>s.execute(),s=>console.error(new E(c.ATOM_INDIVIDUAL_SUBSCRIBER_FAILED,s)))}}let v=0;function J(){return v=v+1&y||1,v}function _e(){return v}let M=0,Q=0,L=!1;function W(){return L?(f&&console.warn("Warning: startFlush() called during flush - ignored to prevent infinite loop detection bypass"),!1):(L=!0,M=M+1&y,Q=0,!0)}function K(){L=!1}function le(){return L?++Q:0}class fe{constructor(){this.queueA=[],this.queueB=[],this.queue=this.queueA,this.queueSize=0,this.urgentQueueA=[],this.urgentQueueB=[],this.urgentQueue=this.urgentQueueA,this.urgentQueueSize=0,this._epoch=0,this.isProcessing=!1,this.isBatching=!1,this.batchDepth=0,this.batchQueue=[],this.batchQueueSize=0,this.isFlushingSync=!1,this.maxFlushIterations=S.MAX_FLUSH_ITERATIONS}get phase(){return this.isProcessing||this.isFlushingSync?2:this.isBatching?1:0}schedule(e,t){if(typeof e!="function")throw new F("Scheduler callback must be a function");if(e._nextEpoch!==this._epoch)if(e._nextEpoch=this._epoch,this.isBatching||this.isFlushingSync)this.batchQueue[this.batchQueueSize++]=e;else{const s=this._calculateUrgency(e,t);this.urgentQueue[this.urgentQueueSize]=e,this.queue[this.queueSize]=e,this.urgentQueueSize+=s,this.queueSize+=s^1,this.isProcessing||this.flush()}}_calculateUrgency(e,t){if(!t||e._cachedVersion===void 0)return 0;const s=t.getShift(e._cachedVersion);return z-1-s>>>31&1}flush(){this.isProcessing||this.queueSize===0&&this.urgentQueueSize===0||(this.isProcessing=!0,queueMicrotask(()=>{try{if(this.queueSize===0&&this.urgentQueueSize===0)return;const e=W();this._drainQueue(),e&&K()}finally{this.isProcessing=!1,(this.queueSize>0||this.urgentQueueSize>0)&&!this.isBatching&&this.flush()}}))}flushSync(){this.isFlushingSync=!0;const e=W();try{this._mergeBatchQueue(),this._drainQueue()}finally{this.isFlushingSync=!1,e&&K()}}_mergeBatchQueue(){if(this._epoch++,this.batchQueueSize>0){for(let e=0;e<this.batchQueueSize;e++){const t=this.batchQueue[e];t&&t._nextEpoch!==this._epoch&&(t._nextEpoch=this._epoch,this.queue[this.queueSize++]=t)}this.batchQueueSize=0}}_drainQueue(){let e=0;for(;this.urgentQueueSize>0||this.queueSize>0;){if(++e>this.maxFlushIterations){this._handleFlushOverflow();break}this.urgentQueueSize>0&&this._processUrgentQueue(),this.queueSize>0&&this._processCurrentQueue(),this._mergeBatchQueue()}}_processUrgentQueue(){const e=this.urgentQueue,t=this.urgentQueueSize;this.urgentQueue=this.urgentQueue===this.urgentQueueA?this.urgentQueueB:this.urgentQueueA,this.urgentQueueSize=0,this._epoch++,this._processJobs(e,t)}_processCurrentQueue(){const e=this.queue,t=this.queueSize;this.queue=this.queue===this.queueA?this.queueB:this.queueA,this.queueSize=0,this._epoch++,this._processJobs(e,t)}_handleFlushOverflow(){console.error(new F(`Maximum flush iterations (${this.maxFlushIterations}) exceeded. Possible infinite loop.`)),this.queueSize=0,this.queue.length=0,this.urgentQueueSize=0,this.urgentQueue.length=0,this.batchQueueSize=0}_processJobs(e,t){for(let s=0;s<t;s++)try{e[s]?.()}catch(n){console.error(new F("Error occurred during scheduler execution",n))}e.length=0}startBatch(){this.batchDepth++,this.isBatching=!0}endBatch(){this.batchDepth=Math.max(0,this.batchDepth-1),this.batchDepth===0&&(this.flushSync(),this.isBatching=!1)}setMaxFlushIterations(e){if(e<S.MIN_FLUSH_ITERATIONS)throw new F(`Max flush iterations must be at least ${S.MIN_FLUSH_ITERATIONS}`);this.maxFlushIterations=e}}const T=new fe;function de(i){if(typeof i!="function")throw new E("Batch callback must be a function");T.startBatch();try{return i()}finally{T.endBatch()}}class Ee{constructor(){this.current=null}run(e,t){const s=this.current;this.current=e;try{return t()}finally{this.current=s}}getCurrent(){return this.current}}const m=new Ee;function Z(i){if(typeof i!="function")throw new E("Untracked callback must be a function");const e=m.current;m.current=null;try{return i()}finally{m.current=e}}class V{constructor(){this.subscribers=null}add(e){if(this.subscribers||(this.subscribers=[]),this.subscribers.indexOf(e)!==-1)return()=>{};this.subscribers.push(e);let t=!1;return()=>{t||(t=!0,this.remove(e))}}remove(e){if(!this.subscribers)return!1;const t=this.subscribers.indexOf(e);if(t===-1)return!1;const s=this.subscribers.length-1;return t!==s&&(this.subscribers[t]=this.subscribers[s]),this.subscribers.pop(),!0}has(e){return this.subscribers?this.subscribers.indexOf(e)!==-1:!1}forEach(e){if(this.subscribers)for(let t=0;t<this.subscribers.length;t++)e(this.subscribers[t],t)}forEachSafe(e,t){if(this.subscribers)for(let s=0;s<this.subscribers.length;s++)try{e(this.subscribers[s],s)}catch(n){t?t(n):console.error("[SubscriberManager] Error in subscriber callback:",n)}}get size(){return this.subscribers?.length??0}get hasSubscribers(){return this.subscribers!==null&&this.subscribers.length>0}clear(){this.subscribers=null}toArray(){return this.subscribers?[...this.subscribers]:[]}}class q{constructor(){this.pool=[],this.maxPoolSize=50,this.maxReusableCapacity=256,this.stats=f?{acquired:0,released:0,rejected:{frozen:0,tooLarge:0,poolFull:0}}:null}acquire(){return f&&this.stats&&this.stats.acquired++,this.pool.pop()??[]}release(e,t){if(!(t&&e===t)){if(Object.isFrozen(e)){f&&this.stats&&this.stats.rejected.frozen++;return}if(e.length>this.maxReusableCapacity){f&&this.stats&&this.stats.rejected.tooLarge++;return}if(this.pool.length>=this.maxPoolSize){f&&this.stats&&this.stats.rejected.poolFull++;return}e.length=0,this.pool.push(e),f&&this.stats&&this.stats.released++}}getStats(){if(!f||!this.stats)return null;const{acquired:e,released:t,rejected:s}=this.stats,n=s.frozen+s.tooLarge+s.poolFull;return{acquired:e,released:t,rejected:s,leaked:e-t-n,poolSize:this.pool.length}}reset(){this.pool.length=0,f&&this.stats&&(this.stats.acquired=0,this.stats.released=0,this.stats.rejected={frozen:0,tooLarge:0,poolFull:0})}}const a=Object.freeze([]),p=Object.freeze([]),_=Object.freeze([]),C=new q,A=new q,b=new q;function ee(i){return i!==null&&typeof i=="object"&&"value"in i&&"subscribe"in i&&typeof i.subscribe=="function"}function pe(i){if(d.enabled&&(i==null||typeof i=="object")){const e=d.getDebugType(i);if(e)return e==="computed"}return ee(i)&&"invalidate"in i&&typeof i.invalidate=="function"}function be(i){return i!==null&&typeof i=="object"&&"dispose"in i&&"run"in i&&typeof i.dispose=="function"&&typeof i.run=="function"}function te(i){return i!=null&&typeof i.then=="function"}function ge(i){return typeof i=="object"&&i!==null}function Se(i){return(typeof i=="object"||typeof i=="function")&&i!==null&&typeof i.addDependency=="function"}function ye(i){return typeof i=="function"&&typeof i.addDependency!="function"}function De(i){return ge(i)&&typeof i.execute=="function"}function se(i,e,t,s){if(e){if(Se(e)){e.addDependency(i);return}if(ye(e)){t.add(e);return}De(e)&&s.add(e)}}function Ie(i,e,t,s){if(e!==a&&t!==p)for(let r=0;r<e.length;r++){const o=e[r];o&&(o._tempUnsub=t[r])}const n=A.acquire();n.length=i.length;for(let r=0;r<i.length;r++){const o=i[r];o&&(o._tempUnsub?(n[r]=o._tempUnsub,o._tempUnsub=void 0):(d.checkCircular(o,s),n[r]=o.subscribe(s)))}if(e!==a)for(let r=0;r<e.length;r++){const o=e[r];o?._tempUnsub&&(o._tempUnsub(),o._tempUnsub=void 0)}return t!==p&&A.release(t),n}class Ce extends ${constructor(e,t){super(),this._functionSubscribersStore=null,this._objectSubscribersStore=null,this._value=e,t&&(this.flags|=U.SYNC),d.attachDebugInfo(this,"atom",this.id)}get _functionSubscribers(){return this._functionSubscribersStore||(this._functionSubscribersStore=new V),this._functionSubscribersStore}get _objectSubscribers(){return this._objectSubscribersStore||(this._objectSubscribersStore=new V),this._objectSubscribersStore}get value(){const e=m.current;return e&&se(this,e,this._functionSubscribers,this._objectSubscribers),this._value}set value(e){if(Object.is(this._value,e))return;const t=this._value;this._value=e,this.rotatePhase();const s=this._functionSubscribersStore?.hasSubscribers,n=this._objectSubscribersStore?.hasSubscribers;(s||n)&&this._scheduleNotification(t)}_scheduleNotification(e){if(this.flags&U.NOTIFICATION_SCHEDULED||(this._pendingOldValue=e,this.flags|=U.NOTIFICATION_SCHEDULED),this.flags&U.SYNC&&!T.isBatching){this._flushNotifications();return}this._notifyTask||(this._notifyTask=()=>this._flushNotifications()),T.schedule(this._notifyTask)}_flushNotifications(){if(!(this.flags&U.NOTIFICATION_SCHEDULED))return;const e=this._pendingOldValue,t=this._value;this._pendingOldValue=void 0,this.flags&=-3,this._notifySubscribers(t,e)}_notifySubscribers(e,t){this._functionSubscribersStore&&this._functionSubscribersStore.forEachSafe(s=>s(e,t)),this._objectSubscribersStore&&this._objectSubscribersStore.forEachSafe(s=>s.execute())}peek(){return this._value}dispose(){this._functionSubscribersStore?.clear(),this._objectSubscribersStore?.clear(),this._value=void 0,this._notifyTask=void 0}}function me(i,e={}){return new Ce(i,e.sync??!1)}function x(i,e,t){if(i instanceof TypeError)return new e(`Type error (${t}): ${i.message}`,i);if(i instanceof ReferenceError)return new e(`Reference error (${t}): ${i.message}`,i);if(i instanceof E)return i;const s=i instanceof Error?i.message:String(i),n=i instanceof Error?i:null;return new e(`Unexpected error (${t}): ${s}`,n)}const ie=h.RESOLVED|h.PENDING|h.REJECTED,w=Array(ie+1).fill(O.IDLE);w[h.RESOLVED]=O.RESOLVED,w[h.PENDING]=O.PENDING,w[h.REJECTED]=O.REJECTED;class ne extends ${constructor(e,t={}){if(typeof e!="function")throw new D(c.COMPUTED_MUST_BE_FUNCTION);if(super(),this._cachedErrors=null,this._errorCacheEpoch=-1,this._asyncStartAggregateVersion=0,this._asyncRetryCount=0,this.MAX_ASYNC_RETRIES=3,this._value=void 0,this.flags=h.DIRTY|h.IDLE,this._error=null,this._promiseId=0,this._equal=t.equal??Object.is,this._fn=e,this._defaultValue="defaultValue"in t?t.defaultValue:G,this._hasDefaultValue=this._defaultValue!==G,this._onError=t.onError??null,this.MAX_PROMISE_ID=Number.MAX_SAFE_INTEGER-1,this._functionSubscribersStore=new V,this._objectSubscribersStore=new V,this._dependencies=a,this._dependencyVersions=_,this._unsubscribes=p,this._notifyJob=()=>{this._functionSubscribersStore.forEachSafe(s=>s(),s=>console.error(s)),this._objectSubscribersStore.forEachSafe(s=>s.execute(),s=>console.error(s))},this._trackable=Object.assign(()=>this._markDirty(),{addDependency:s=>{}}),d.attachDebugInfo(this,"computed",this.id),d.enabled){const s=this;s.subscriberCount=()=>this._functionSubscribersStore.size+this._objectSubscribersStore.size,s.isDirty=()=>this._isDirty(),s.dependencies=this._dependencies,s.stateFlags=this._getFlagsAsString()}if(t.lazy===!1)try{this._recompute()}catch{}}get _functionSubscribers(){return this._functionSubscribersStore}get _objectSubscribers(){return this._objectSubscribersStore}get value(){return this._registerTracking(),this._computeValue()}peek(){return this._value}get state(){return this._registerTracking(),this._getAsyncState()}get hasError(){if(this._registerTracking(),this._isRejected())return!0;for(let e=0;e<this._dependencies.length;e++){const t=this._dependencies[e];if(t&&"hasError"in t&&t.hasError)return!0}return!1}get isValid(){return!this.hasError}get errors(){if(this._registerTracking(),!this.hasError)return oe;const e=_e();if(this._errorCacheEpoch===e&&this._cachedErrors!==null)return this._cachedErrors;const t=new Set;this._error&&t.add(this._error);for(let s=0;s<this._dependencies.length;s++){const n=this._dependencies[s];if(n&&"errors"in n){const r=n.errors;for(let o=0;o<r.length;o++){const l=r[o];l&&t.add(l)}}}return this._cachedErrors=Object.freeze([...t]),this._errorCacheEpoch=e,this._cachedErrors}get lastError(){return this._registerTracking(),this._error}get isPending(){return this._registerTracking(),this._isPending()}get isResolved(){return this._registerTracking(),this._isResolved()}invalidate(){this._markDirty(),this._dependencyVersions!==_&&(b.release(this._dependencyVersions),this._dependencyVersions=_),this._errorCacheEpoch=-1,this._cachedErrors=null}dispose(){if(this._unsubscribes!==p){for(let e=0;e<this._unsubscribes.length;e++){const t=this._unsubscribes[e];t&&t()}A.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==a&&(C.release(this._dependencies),this._dependencies=a),this._dependencyVersions!==_&&(b.release(this._dependencyVersions),this._dependencyVersions=_),this._functionSubscribersStore.clear(),this._objectSubscribersStore.clear(),this.flags=h.DIRTY|h.IDLE,this._error=null,this._value=void 0,this._promiseId=(this._promiseId+1)%this.MAX_PROMISE_ID,this._cachedErrors=null,this._errorCacheEpoch=-1}_isDirty(){return(this.flags&h.DIRTY)!==0}_setDirty(){this.flags|=h.DIRTY}_clearDirty(){this.flags&=-2}_isIdle(){return(this.flags&h.IDLE)!==0}_setIdle(){this.flags|=h.IDLE,this.flags&=-29}_isPending(){return(this.flags&h.PENDING)!==0}_setPending(){this.flags|=h.PENDING,this.flags&=-27}_isResolved(){return(this.flags&h.RESOLVED)!==0}_setResolved(){this.flags|=h.RESOLVED,this.flags&=-87}_isRejected(){return(this.flags&h.REJECTED)!==0}_setRejected(){this.flags|=h.REJECTED|h.HAS_ERROR,this.flags&=-15}_isRecomputing(){return(this.flags&h.RECOMPUTING)!==0}_setRecomputing(e){const t=h.RECOMPUTING;this.flags=this.flags&~t|-Number(e)&t}_getAsyncState(){return w[this.flags&ie]}_getFlagsAsString(){const e=[];return this._isDirty()&&e.push("DIRTY"),this._isIdle()&&e.push("IDLE"),this._isPending()&&e.push("PENDING"),this._isResolved()&&e.push("RESOLVED"),this._isRejected()&&e.push("REJECTED"),this._isRecomputing()&&e.push("RECOMPUTING"),e.join(" | ")}_computeValue(){return this._isRecomputing()?this._value:((this._isDirty()||this._isIdle())&&this._recompute(),this._isPending()?this._handlePending():this._isRejected()?this._handleRejected():this._value)}_recompute(){if(this._isRecomputing())return;this._setRecomputing(!0);const e=this._prepareComputationContext();let t=!1;try{const s=m.run(this._trackable,this._fn);this._commitDependencies(e),t=!0,te(s)?this._handleAsyncComputation(s):this._handleSyncResult(s)}catch(s){if(!t)try{this._commitDependencies(e),t=!0}catch(n){this._handleComputationError(n)}this._handleComputationError(s)}finally{this._cleanupContext(e,t),this._setRecomputing(!1)}}_prepareComputationContext(){const e=this._dependencies,t=this._dependencyVersions,s=C.acquire(),n=b.acquire(),r=J(),o={depCount:0},l=g=>{g._lastSeenEpoch!==r&&(g._lastSeenEpoch=r,o.depCount<s.length?(s[o.depCount]=g,n[o.depCount]=g.version):(s.push(g),n.push(g.version)),o.depCount++)},R=this._trackable.addDependency;return this._trackable.addDependency=l,{prevDeps:e,prevVersions:t,nextDeps:s,nextVersions:n,originalAdd:R,state:o}}_commitDependencies(e){const{nextDeps:t,nextVersions:s,state:n,prevDeps:r}=e;t.length=n.depCount,s.length=n.depCount,this._unsubscribes=Ie(t,r,this._unsubscribes,this),this._dependencies=t,this._dependencyVersions=s}_cleanupContext(e,t){this._trackable.addDependency=e.originalAdd,t?(e.prevDeps!==a&&C.release(e.prevDeps),e.prevVersions!==_&&b.release(e.prevVersions)):(C.release(e.nextDeps),b.release(e.nextVersions))}_getAggregateShift(){let e=0;const t=this._dependencies,s=this._dependencyVersions;for(let n=0;n<t.length;n++){const r=t[n],o=s[n];r&&o!==void 0&&(e=e+r.getShift(o)&y)}return e}isUrgent(){return this._getAggregateShift()>=z}_handleSyncResult(e){(!this._isResolved()||!this._equal(this._value,e))&&this.rotatePhase(),this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),this._cachedErrors=null,this._errorCacheEpoch=-1}_handleAsyncComputation(e){this._setPending(),this._clearDirty(),this._notifyJob(),this._asyncStartAggregateVersion=this._captureVersionSnapshot(),this._asyncRetryCount=0,this._promiseId=this._promiseId>=this.MAX_PROMISE_ID?1:this._promiseId+1;const t=this._promiseId;e.then(s=>{if(t!==this._promiseId)return;const r=this._captureVersionSnapshot()-this._asyncStartAggregateVersion&y;if(z-1-r>>>31&1){if(this._asyncRetryCount<this.MAX_ASYNC_RETRIES){this._asyncRetryCount++,this._markDirty();return}const l=new D(`Async drift exceeded threshold after ${this.MAX_ASYNC_RETRIES} retries. Dependencies changed too rapidly for stable computation.`);this._handleAsyncRejection(l);return}this._handleAsyncResolution(s)}).catch(s=>{t===this._promiseId&&this._handleAsyncRejection(s)})}_captureVersionSnapshot(){let e=0;const t=this._dependencies;for(let s=0;s<t.length;s++){const n=t[s];n&&(e=e+n.version&y)}return e}_handleAsyncResolution(e){(!this._isResolved()||!this._equal(this._value,e))&&this.rotatePhase(),this._value=e,this._clearDirty(),this._setResolved(),this._error=null,this._setRecomputing(!1),this._cachedErrors=null,this._errorCacheEpoch=-1,this._notifyJob()}_handleAsyncRejection(e){const t=x(e,D,c.COMPUTED_ASYNC_COMPUTATION_FAILED);if(!this._isRejected()&&this.rotatePhase(),this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(n){console.error(c.CALLBACK_ERROR_IN_ERROR_HANDLER,n)}this._notifyJob()}_handleComputationError(e){const t=x(e,D,c.COMPUTED_COMPUTATION_FAILED);if(this._error=t,this._setRejected(),this._clearDirty(),this._setRecomputing(!1),this._onError)try{this._onError(t)}catch(s){console.error(c.CALLBACK_ERROR_IN_ERROR_HANDLER,s)}throw t}_handlePending(){if(this._hasDefaultValue)return this._defaultValue;throw new D(c.COMPUTED_ASYNC_PENDING_NO_DEFAULT)}_handleRejected(){if(this._error?.recoverable&&this._hasDefaultValue)return this._defaultValue;throw this._error}execute(){this._markDirty()}_markDirty(){this._isRecomputing()||this._isDirty()||(this._setDirty(),this._notifyJob())}_registerTracking(){se(this,m.getCurrent(),this._functionSubscribersStore,this._objectSubscribersStore)}}Object.freeze(ne.prototype);function Ae(i,e={}){return new ne(i,e)}class Te extends H{constructor(e,t={}){super(),this.run=()=>{if(this.isDisposed)throw new I(c.EFFECT_MUST_BE_FUNCTION);this._dependencyVersions!==_&&(b.release(this._dependencyVersions),this._dependencyVersions=_),this.execute()},this.dispose=()=>{if(!this.isDisposed){if(this._setDisposed(),this._safeCleanup(),this._unsubscribes!==p){for(let n=0;n<this._unsubscribes.length;n++){const r=this._unsubscribes[n];r&&r()}A.release(this._unsubscribes),this._unsubscribes=p}this._dependencies!==a&&(C.release(this._dependencies),this._dependencies=a),this._dependencyVersions!==_&&(b.release(this._dependencyVersions),this._dependencyVersions=_)}},this.addDependency=n=>{if(this.isExecuting&&this._nextDeps&&this._nextUnsubs&&this._nextVersions){const r=this._currentEpoch;if(n._lastSeenEpoch===r)return;n._lastSeenEpoch=r,this._nextDeps.push(n),this._nextVersions.push(n.version),n._tempUnsub?(this._nextUnsubs.push(n._tempUnsub),n._tempUnsub=void 0):this._subscribeTo(n)}},this.execute=()=>{if(this.isDisposed||this.isExecuting||!this._shouldExecute())return;this._checkInfiniteLoop(),this._setExecuting(!0),this._safeCleanup();const n=this._prepareEffectContext();let r=!1;try{const o=m.run(this,this._fn);this._commitEffect(n),r=!0,this._checkLoopWarnings(),te(o)?o.then(l=>{!this.isDisposed&&typeof l=="function"&&(this._cleanup=l)}).catch(l=>{this._handleExecutionError(l)}):this._cleanup=typeof o=="function"?o:null}catch(o){r=!0,this._handleExecutionError(o),this._cleanup=null}finally{this._cleanupEffect(n,r),this._setExecuting(!1)}},this._currentEpoch=-1,this._lastFlushEpoch=-1,this._executionsInEpoch=0,this._fn=e,this._sync=t.sync??!1,this._maxExecutions=t.maxExecutionsPerSecond??S.MAX_EXECUTIONS_PER_SECOND,this._maxExecutionsPerFlush=t.maxExecutionsPerFlush??S.MAX_EXECUTIONS_PER_EFFECT,this._trackModifications=t.trackModifications??!1,this._cleanup=null,this._dependencies=a,this._dependencyVersions=_,this._unsubscribes=p,this._nextDeps=null,this._nextVersions=null,this._nextUnsubs=null,this._onError=t.onError??null,this._historyPtr=0;const s=Number.isFinite(this._maxExecutions);this._historyCapacity=s?Math.min(this._maxExecutions+1,S.MAX_EXECUTIONS_PER_SECOND+1):0,this._history=f&&s&&this._historyCapacity>0?new Array(this._historyCapacity).fill(0):null,this._executionCount=0,d.attachDebugInfo(this,"effect",this.id)}_prepareEffectContext(){const e=this._dependencies,t=this._dependencyVersions,s=this._unsubscribes,n=C.acquire(),r=b.acquire(),o=A.acquire(),l=J();if(e!==a&&s!==p)for(let R=0;R<e.length;R++){const g=e[R];g&&(g._tempUnsub=s[R])}return this._nextDeps=n,this._nextVersions=r,this._nextUnsubs=o,this._currentEpoch=l,{prevDeps:e,prevVersions:t,prevUnsubs:s,nextDeps:n,nextVersions:r,nextUnsubs:o}}_commitEffect(e){const t=e.nextDeps.length;e.nextDeps.length=t,e.nextVersions.length=t,this._dependencies=e.nextDeps,this._dependencyVersions=e.nextVersions,this._unsubscribes=e.nextUnsubs}_cleanupEffect(e,t){if(this._nextDeps=null,this._nextVersions=null,this._nextUnsubs=null,t){if(e.prevDeps!==a){for(let s=0;s<e.prevDeps.length;s++){const n=e.prevDeps[s];n?._tempUnsub&&(n._tempUnsub(),n._tempUnsub=void 0)}C.release(e.prevDeps)}e.prevUnsubs!==p&&A.release(e.prevUnsubs),e.prevVersions!==_&&b.release(e.prevVersions)}else{C.release(e.nextDeps),b.release(e.nextVersions);for(let s=0;s<e.nextUnsubs.length;s++)e.nextUnsubs[s]?.();if(A.release(e.nextUnsubs),e.prevDeps!==a)for(let s=0;s<e.prevDeps.length;s++){const n=e.prevDeps[s];n&&(n._tempUnsub=void 0)}}}_subscribeTo(e){try{const t=e.subscribe(()=>{this._trackModifications&&this.isExecuting&&(e._modifiedAtEpoch=this._currentEpoch),this._sync?this.execute():T.schedule(this.execute)});this._nextUnsubs&&this._nextUnsubs.push(t)}catch(t){console.error(x(t,I,c.EFFECT_EXECUTION_FAILED)),this._nextUnsubs&&this._nextUnsubs.push(()=>{})}}get isDisposed(){return(this.flags&P.DISPOSED)!==0}get executionCount(){return this._executionCount}get isExecuting(){return(this.flags&P.EXECUTING)!==0}_setDisposed(){this.flags|=P.DISPOSED}_setExecuting(e){const t=P.EXECUTING;this.flags=this.flags&~t|-Number(e)&t}_safeCleanup(){if(this._cleanup){try{this._cleanup()}catch(e){console.error(x(e,I,c.EFFECT_CLEANUP_FAILED))}this._cleanup=null}}_checkInfiniteLoop(){if(this._lastFlushEpoch!==M&&(this._lastFlushEpoch=M,this._executionsInEpoch=0),this._executionsInEpoch++,this._executionsInEpoch>this._maxExecutionsPerFlush&&this._throwInfiniteLoopError("per-effect"),le()>S.MAX_EXECUTIONS_PER_FLUSH&&this._throwInfiniteLoopError("global"),this._executionCount++,this._history&&this._maxExecutions>0){const e=Date.now(),t=this._historyPtr,s=this._historyCapacity;this._history[t]=e;const n=(t+1)%s,r=this._history[n]??0;if(this._historyPtr=n,r>0&&e-r<N.ONE_SECOND_MS){const o=new I(`Effect executed ${s} times within 1 second. Infinite loop suspected`);if(this.dispose(),console.error(o),this._onError&&this._onError(o),f)throw o}}}_throwInfiniteLoopError(e){const t=new I(`Infinite loop detected (${e}): effect executed ${this._executionsInEpoch} times in current flush. Total executions in flush: ${Q}`);throw this.dispose(),console.error(t),t}_shouldExecute(){if(this._dependencies===a||this._dependencyVersions===_)return!0;for(let e=0;e<this._dependencies.length;e++){const t=this._dependencies[e];if(t){if("value"in t)try{Z(()=>t.value)}catch{return!0}if(t.version!==this._dependencyVersions[e])return!0}}return!1}_handleExecutionError(e){const t=x(e,I,c.EFFECT_EXECUTION_FAILED);console.error(t),this._onError&&this._onError(t)}_checkLoopWarnings(){if(this._trackModifications&&d.enabled){const e=this._dependencies;for(let t=0;t<e.length;t++){const s=e[t];s&&s._modifiedAtEpoch===this._currentEpoch&&d.warn(!0,`Effect is reading a dependency (${d.getDebugName(s)||"unknown"}) that it just modified. Infinite loop may occur`)}}}}function Re(i,e={}){if(typeof i!="function")throw new I(c.EFFECT_MUST_BE_FUNCTION);const t=new Te(i,e);return t.execute(),t}u.AsyncState=O,u.AtomError=E,u.ComputedError=D,u.DEBUG_CONFIG=j,u.DEBUG_RUNTIME=d,u.EffectError=I,u.POOL_CONFIG=re,u.SCHEDULER_CONFIG=S,u.SchedulerError=F,u.atom=me,u.batch=de,u.computed=Ae,u.effect=Re,u.isAtom=ee,u.isComputed=pe,u.isEffect=be,u.scheduler=T,u.untracked=Z,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})}));
|
|
2
2
|
//# sourceMappingURL=atom-effect.min.js.map
|