@asaidimu/utils-artifacts 8.1.3 → 8.2.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/index.d.mts CHANGED
@@ -412,6 +412,8 @@ type ArtifactFactoryContext<TRegistry extends Record<string, any>, TState extend
412
412
  * An AbortSignal that indicates if the artifacts has been unregistered
413
413
  */
414
414
  signal: AbortSignal;
415
+ /** For parameterized artifacts: the parameters that were passed during resolve/watch. */
416
+ params?: any;
415
417
  };
416
418
  /**
417
419
  * A function that performs cleanup or disposal logic for an artifact, potentially asynchronously.
@@ -544,7 +546,7 @@ interface ArtifactObserver<TRegistry, K extends keyof TRegistry> {
544
546
  * @template TArtifact The resolved type of the artifact instance.
545
547
  * @template TRegistry The type mapping of all artifacts in the container.
546
548
  */
547
- interface ArtifactTemplate<TState extends object, TArtifact, TRegistry extends object = any, TExtra extends Record<string, any> = {}> {
549
+ interface ArtifactTemplate<TState extends object, TArtifact, TRegistry extends Record<string, any> = Record<string, any>, TExtra extends Record<string, any> = {}> {
548
550
  /** The unique key identifying this artifact within the registry. */
549
551
  key: keyof TRegistry;
550
552
  /** The factory function responsible for creating the artifact's instance. */
@@ -577,6 +579,9 @@ interface ArtifactTemplate<TState extends object, TArtifact, TRegistry extends o
577
579
  * aggregate multiple rapid changes.
578
580
  */
579
581
  debounce?: number;
582
+ /** If defined, the artifact is parameterized. Receives the user‑supplied params and returns a unique string key. */
583
+ paramKey?: (params: Record<string, unknown>) => string;
584
+ virtual?: true;
580
585
  }
581
586
  /**
582
587
  * Extracts the global state type (`TState`) from an `ArtifactTemplate`.
@@ -604,7 +609,7 @@ type ArtifactScopeType<T> = T extends {
604
609
  * @template TState The type of the global state.
605
610
  * @template TRegistry The map of all artifact keys to their resolved types.
606
611
  */
607
- type ArtifactTemplateMap<TState extends object, TRegistry extends Record<string, any> = any> = {
612
+ type ArtifactTemplateMap<TState extends object, TRegistry extends Record<string, any> = Record<string, any>> = {
608
613
  [K in keyof TRegistry]: ArtifactTemplate<TState, TRegistry[K], TRegistry>;
609
614
  };
610
615
  /**
@@ -614,7 +619,7 @@ type ArtifactTemplateMap<TState extends object, TRegistry extends Record<string,
614
619
  * @template T The type that contains a factory property.
615
620
  */
616
621
  type ArtifactValue<T> = T extends {
617
- factory: (...args: any[]) => infer TArtifact;
622
+ factory: ArtifactFactory<any, any, infer TArtifact, any>;
618
623
  } ? TArtifact : never;
619
624
  /**
620
625
  * Infers the complete Artifact Registry type from a map of artifact configuration objects.
@@ -695,7 +700,7 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
695
700
  *
696
701
  * @param key The unique identifier of the artifact
697
702
  */
698
- unregister<K extends keyof TRegistry>(key: K): Promise<void>;
703
+ unregister<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): Promise<void>;
699
704
  /**
700
705
  * Resolves an artifact by its key, returning its instance or an error.
701
706
  * Handles dependency resolution, cycle detection, caching, and retry logic.
@@ -708,7 +713,7 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
708
713
  * @returns A Promise that resolves to a ResolvedArtifact
709
714
  * @throws {ArtifactNotFoundError} if the artifact is not found
710
715
  */
711
- resolve<K extends keyof TRegistry>(key: K): Promise<KeyedResolvedArtifact<TRegistry, K>>;
716
+ resolve<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): Promise<KeyedResolvedArtifact<TRegistry, K>>;
712
717
  /**
713
718
  * Resolves an artifact by its key, returning its instance directly.
714
719
  * Throws if resolution fails.
@@ -718,7 +723,7 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
718
723
  * @throws {ArtifactNotFoundError} if the artifact is not found
719
724
  * @throws the artifact's error if resolution failed
720
725
  */
721
- require<K extends keyof TRegistry>(key: K): Promise<TRegistry[K]>;
726
+ require<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): Promise<TRegistry[K]>;
722
727
  /**
723
728
  * Returns an ArtifactObserver for a given artifact key.
724
729
  * The observer allows subscribing to changes in the artifact's resolved value.
@@ -726,7 +731,7 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
726
731
  * @param key The unique identifier for the artifact
727
732
  * @returns An ArtifactObserver instance
728
733
  */
729
- watch<K extends keyof TRegistry>(key: K): ArtifactObserver<TRegistry, K>;
734
+ watch<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): ArtifactObserver<TRegistry, K>;
730
735
  /**
731
736
  * Peeks at the resolved instance of an artifact without triggering resolution
732
737
  * or registering a dependency.
@@ -734,14 +739,18 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
734
739
  * @param key The unique identifier for the artifact
735
740
  * @returns The artifact instance if already built, otherwise undefined
736
741
  */
737
- peek<K extends keyof TRegistry>(key: K): TRegistry[K] | undefined;
742
+ peek<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): TRegistry[K] | undefined;
738
743
  /**
739
744
  * Invalidates an artifact, triggering rebuild and cascade to dependents.
740
745
  *
741
746
  * @param key The artifact key to invalidate
742
- * @param replace If true, forces immediate rebuild bypassing debounce
747
+ * @param options.replace If true, forces immediate rebuild bypassing debounce
748
+ * @param options.params for parametized artifacts
743
749
  */
744
- invalidate<K extends keyof TRegistry>(key: K, replace?: boolean): Promise<void>;
750
+ invalidate<K extends keyof TRegistry>(key: K, options?: {
751
+ replace?: boolean;
752
+ params?: Record<string, unknown>;
753
+ }): Promise<void>;
745
754
  /**
746
755
  * Notifies observers that an artifact has changed.
747
756
  * Called by ArtifactManager during stream propagation.
@@ -765,6 +774,9 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
765
774
  * Callers should await this method to guarantee full resource release.
766
775
  */
767
776
  dispose(): Promise<void>;
777
+ private resolveStatic;
778
+ private resolveParameterized;
779
+ private computeParamKey;
768
780
  }
769
781
 
770
782
  export { type ArtifactCleanup, ArtifactContainer, type ArtifactDebugNode, type ArtifactFactory, type ArtifactFactoryContext, type ArtifactInstance, type ArtifactKey, type ArtifactObserver, type ArtifactRegistryType, type ArtifactScope, type ArtifactScopeType, ArtifactScopes, type ArtifactStateType, type ArtifactStreamContext, type ArtifactTemplate, type ArtifactTemplateMap, type ArtifactValue, type ErrorArtifact, type InferRegistry, type KeyedResolvedArtifact, type PendingArtifact, type ReadyArtifact, type ResolvedArtifact, type ResolvedArtifactBase, type UseDependencyContext };
package/index.d.ts CHANGED
@@ -412,6 +412,8 @@ type ArtifactFactoryContext<TRegistry extends Record<string, any>, TState extend
412
412
  * An AbortSignal that indicates if the artifacts has been unregistered
413
413
  */
414
414
  signal: AbortSignal;
415
+ /** For parameterized artifacts: the parameters that were passed during resolve/watch. */
416
+ params?: any;
415
417
  };
416
418
  /**
417
419
  * A function that performs cleanup or disposal logic for an artifact, potentially asynchronously.
@@ -544,7 +546,7 @@ interface ArtifactObserver<TRegistry, K extends keyof TRegistry> {
544
546
  * @template TArtifact The resolved type of the artifact instance.
545
547
  * @template TRegistry The type mapping of all artifacts in the container.
546
548
  */
547
- interface ArtifactTemplate<TState extends object, TArtifact, TRegistry extends object = any, TExtra extends Record<string, any> = {}> {
549
+ interface ArtifactTemplate<TState extends object, TArtifact, TRegistry extends Record<string, any> = Record<string, any>, TExtra extends Record<string, any> = {}> {
548
550
  /** The unique key identifying this artifact within the registry. */
549
551
  key: keyof TRegistry;
550
552
  /** The factory function responsible for creating the artifact's instance. */
@@ -577,6 +579,9 @@ interface ArtifactTemplate<TState extends object, TArtifact, TRegistry extends o
577
579
  * aggregate multiple rapid changes.
578
580
  */
579
581
  debounce?: number;
582
+ /** If defined, the artifact is parameterized. Receives the user‑supplied params and returns a unique string key. */
583
+ paramKey?: (params: Record<string, unknown>) => string;
584
+ virtual?: true;
580
585
  }
581
586
  /**
582
587
  * Extracts the global state type (`TState`) from an `ArtifactTemplate`.
@@ -604,7 +609,7 @@ type ArtifactScopeType<T> = T extends {
604
609
  * @template TState The type of the global state.
605
610
  * @template TRegistry The map of all artifact keys to their resolved types.
606
611
  */
607
- type ArtifactTemplateMap<TState extends object, TRegistry extends Record<string, any> = any> = {
612
+ type ArtifactTemplateMap<TState extends object, TRegistry extends Record<string, any> = Record<string, any>> = {
608
613
  [K in keyof TRegistry]: ArtifactTemplate<TState, TRegistry[K], TRegistry>;
609
614
  };
610
615
  /**
@@ -614,7 +619,7 @@ type ArtifactTemplateMap<TState extends object, TRegistry extends Record<string,
614
619
  * @template T The type that contains a factory property.
615
620
  */
616
621
  type ArtifactValue<T> = T extends {
617
- factory: (...args: any[]) => infer TArtifact;
622
+ factory: ArtifactFactory<any, any, infer TArtifact, any>;
618
623
  } ? TArtifact : never;
619
624
  /**
620
625
  * Infers the complete Artifact Registry type from a map of artifact configuration objects.
@@ -695,7 +700,7 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
695
700
  *
696
701
  * @param key The unique identifier of the artifact
697
702
  */
698
- unregister<K extends keyof TRegistry>(key: K): Promise<void>;
703
+ unregister<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): Promise<void>;
699
704
  /**
700
705
  * Resolves an artifact by its key, returning its instance or an error.
701
706
  * Handles dependency resolution, cycle detection, caching, and retry logic.
@@ -708,7 +713,7 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
708
713
  * @returns A Promise that resolves to a ResolvedArtifact
709
714
  * @throws {ArtifactNotFoundError} if the artifact is not found
710
715
  */
711
- resolve<K extends keyof TRegistry>(key: K): Promise<KeyedResolvedArtifact<TRegistry, K>>;
716
+ resolve<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): Promise<KeyedResolvedArtifact<TRegistry, K>>;
712
717
  /**
713
718
  * Resolves an artifact by its key, returning its instance directly.
714
719
  * Throws if resolution fails.
@@ -718,7 +723,7 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
718
723
  * @throws {ArtifactNotFoundError} if the artifact is not found
719
724
  * @throws the artifact's error if resolution failed
720
725
  */
721
- require<K extends keyof TRegistry>(key: K): Promise<TRegistry[K]>;
726
+ require<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): Promise<TRegistry[K]>;
722
727
  /**
723
728
  * Returns an ArtifactObserver for a given artifact key.
724
729
  * The observer allows subscribing to changes in the artifact's resolved value.
@@ -726,7 +731,7 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
726
731
  * @param key The unique identifier for the artifact
727
732
  * @returns An ArtifactObserver instance
728
733
  */
729
- watch<K extends keyof TRegistry>(key: K): ArtifactObserver<TRegistry, K>;
734
+ watch<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): ArtifactObserver<TRegistry, K>;
730
735
  /**
731
736
  * Peeks at the resolved instance of an artifact without triggering resolution
732
737
  * or registering a dependency.
@@ -734,14 +739,18 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
734
739
  * @param key The unique identifier for the artifact
735
740
  * @returns The artifact instance if already built, otherwise undefined
736
741
  */
737
- peek<K extends keyof TRegistry>(key: K): TRegistry[K] | undefined;
742
+ peek<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): TRegistry[K] | undefined;
738
743
  /**
739
744
  * Invalidates an artifact, triggering rebuild and cascade to dependents.
740
745
  *
741
746
  * @param key The artifact key to invalidate
742
- * @param replace If true, forces immediate rebuild bypassing debounce
747
+ * @param options.replace If true, forces immediate rebuild bypassing debounce
748
+ * @param options.params for parametized artifacts
743
749
  */
744
- invalidate<K extends keyof TRegistry>(key: K, replace?: boolean): Promise<void>;
750
+ invalidate<K extends keyof TRegistry>(key: K, options?: {
751
+ replace?: boolean;
752
+ params?: Record<string, unknown>;
753
+ }): Promise<void>;
745
754
  /**
746
755
  * Notifies observers that an artifact has changed.
747
756
  * Called by ArtifactManager during stream propagation.
@@ -765,6 +774,9 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
765
774
  * Callers should await this method to guarantee full resource release.
766
775
  */
767
776
  dispose(): Promise<void>;
777
+ private resolveStatic;
778
+ private resolveParameterized;
779
+ private computeParamKey;
768
780
  }
769
781
 
770
782
  export { type ArtifactCleanup, ArtifactContainer, type ArtifactDebugNode, type ArtifactFactory, type ArtifactFactoryContext, type ArtifactInstance, type ArtifactKey, type ArtifactObserver, type ArtifactRegistryType, type ArtifactScope, type ArtifactScopeType, ArtifactScopes, type ArtifactStateType, type ArtifactStreamContext, type ArtifactTemplate, type ArtifactTemplateMap, type ArtifactValue, type ErrorArtifact, type InferRegistry, type KeyedResolvedArtifact, type PendingArtifact, type ReadyArtifact, type ResolvedArtifact, type ResolvedArtifactBase, type UseDependencyContext };
package/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=(e=>(e.Singleton="singleton",e.Transient="transient",e))(e||{}),t=class e extends Error{category;constructor(t,r,s){super(t,{cause:s}),this.name="ArtifactError",this.category=r,Object.setPrototypeOf(this,e.prototype)}},r=class extends t{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system"),this.name="ArtifactNotFoundError"}},s=class extends t{constructor(e){super(`[ArtifactContainer] An artifact with key:${e} already exists!`,"system"),this.name="ArtifactKeyConflict"}},i=class extends t{constructor(){super("Build superseded by invalidation","system"),this.name="SupersededBuildError"}},n=class{artifacts=new Map;register({key:e,factory:t,lazy:r,...i}){if(this.artifacts.has(e))throw new s(String(e));const{scope:n,...o}=i,a={key:e,factory:t,scope:i.scope??"singleton",lazy:void 0===r||r,...o};return this.artifacts.set(e,a),()=>this.unregister(e)}get(e){if(!this.has(e))throw new r(String(e));return this.artifacts.get(e)}has(e){return this.artifacts.has(e)}async unregister(e){this.artifacts.has(e)&&this.artifacts.delete(e)}size(){return this.artifacts.size}keys(){return Array.from(this.artifacts.keys())}clear(){this.artifacts.clear()}},o=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];var a=class e extends Error{constructor(t,r){super(t,{cause:r}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},c=class extends a{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},h=class extends a{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},d=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const r=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await r;let s;await Promise.race([r.then((()=>clearTimeout(s))),new Promise(((r,i)=>{s=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),i(new c("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},l=class{mutex=new d({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,r="Operation timed out"){if(null==t)return e;let s;return Promise.race([e.then((e=>(clearTimeout(s),e))),new Promise(((e,i)=>{s=setTimeout((()=>i(new c(r))),t)}))])}},u=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new d({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new h};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let r,s=null;try{if(this._done)throw new h;s=await e(),this._lastValue=s,this._lastError=void 0,this._hasRun=!0}catch(e){r=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:s,error:r}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},p=class{constructor(e,t,r={}){this.factory=e,this.onCleanup=t,this.options=r}_count=0;init=new l({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}};function g(e,t){if(!e.length)return;const r=e.slice(),s=t?`[${t}]`:"[ArtifactCleanup]";return async()=>{for(let e=r.length-1;e>=0;e--)try{await r[e]()}catch(t){console.error(`${s} Cleanup error at index ${e}:`,t)}}}async function f(e,t){const r=t?`[${t}]`:"[ArtifactCleanup]";for(let t=e.length-1;t>=0;t--)try{await e[t]()}catch(e){console.error(`${r} Cleanup error at index ${t}:`,e)}}function y(e){return`${e}__watched`}var w=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function m(e,t){let r;const s=new Promise(((e,s)=>{r=setTimeout((()=>s(new Error(`Timeout: ${t}ms`))),t)}));try{return Promise.race([e,s])}finally{clearTimeout(r)}}var v=(new AbortController).signal,b=class{constructor(e,t,r,s,i){this.registry=e,this.cache=t,this.graph=r,this.store=s,this.observer=i}async build(e,r){const s=this.cache.get(e);if("singleton"===s?.scope&&s.buildOnce.done())return this.cache.package(e,((t,r)=>this.invalidate(e,t,r)));const n=this.registry.get(e),o=r??[];if(o.includes(e))throw new t(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${[...o,e].join(" -> ")}`,"system");o.push(e);let a=s;a||(a=this.createCachedArtifact(n),this.cache.set(e,a));try{if("transient"===a.scope)return this.executeBuild(n,a,o);const t=a;try{await t.buildOnce.do((()=>this.executeBuild(n,t,o)))}catch(t){if(t instanceof i)return this.build(e,r);throw t}return t.stream&&t.streamOnce.do(t.stream),this.cache.package(e,((t,r)=>this.invalidate(e,t,r)))}finally{o.pop()}}async executeBuild(e,t,r){const s=e.key,i=String(s),n="transient"===t.scope;t.buildCount++,"singleton"===t.scope&&(t.activeDebounceMs=e.debounce??0);const o={cleanupFunctions:[],disposeFunctions:[],capturedStateDeps:new Set,capturedArtifactDeps:new Set,dependencyVersions:new Map},a=this.buildContext(e,t,r,i,o),c=await this.runWithRetries(e,a,o.dependencyVersions);if(this.commitResult(s,t,n,c,o),n){const e=c.ok?c.value:void 0;return{instance:e,error:c.ok?void 0:c.error,ready:c.ok,[s]:e,cleanup:g(o.cleanupFunctions,i),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${i}"`)}}}buildContext(e,r,s,i,n){const a=e.key,c="transient"===r.scope,{cleanupFunctions:h,disposeFunctions:d,capturedStateDeps:l,capturedArtifactDeps:u,dependencyVersions:p}=n,g=async e=>{if(e===a)throw new t(`Artifact "${i}" depends on itself.`,"system");const r=this.graph.wouldCreateCycle(a,e);if(r)throw new t(`Adding dependency "${String(e)}" to "${i}" would create a cycle: ${r.join(" -> ")}`,"system");u.add(e);const n=await this.build(e,s),o=this.cache.get(e);return o&&p.set(e,o.version),n},f="singleton"===r.scope?r.controller.signal:v,y=async e=>{const t=await g(e);if(t.error)throw t.error;return t.instance},w=e=>(function(e,t="."){const r=new Set,s=new Map,i=(e="")=>{if(s.has(e))return s.get(e);const n=new Proxy((()=>{}),{get:(s,n)=>{if("symbol"==typeof n||"then"===n)return;if("valueOf"===n||"toString"===n)throw new Error("Cannot perform logic, arithmetic, or string operations inside a selector.");if(o.includes(n))throw new Error(`Array method .${n}() is not allowed in selectors.`);const a=e?`${e}${t}${n}`:n;return e&&r.delete(e),r.add(a),i(a)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions or methods.")}});return s.set(e,n),n};try{e(i())}catch(e){throw new Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(r)}(e).forEach((e=>l.add(e))),e(this.store.get(!0)));return{state:()=>this.store.get(!0),previous:r.instance,signal:f,onCleanup:e=>h.push(e),onDispose:e=>d.push(e),use:e=>e({resolve:g,require:y,select:w}),stream:e=>{if(c)throw new t(`[ArtifactManager] Illegal stream on transient artifact "${i}"`,"system");const s=r,n=async(e,t=void 0)=>{await s.streamSerializer.do((async()=>{void 0!==s.stream&&(s.instance=e,s.error=t,s.version++,this.cache.invalidatePackage(a),await this.processStream(i))}))},o={value:()=>s.instance,get signal(){return s.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>n(e)};s.stream=async()=>{try{const t=await e(o);t&&s.cleanupFunctions.push(t)}catch(e){await n(void 0,e),await this.invalidate(a,!1,!0)}}}}}async runWithRetries(e,r,s){const n=r.signal,o=(e.retries??0)+1;let a=0;for(;a<o;)try{if(n.aborted)throw new i;const c=e.factory(r);let h;if(h=c instanceof Promise?e.timeout?await m(c,e.timeout):await c:c,n.aborted)throw new i;const d=this.detectStaleness(s);if(d){if(a++,s.clear(),a<o)continue;return{ok:!1,error:new t(`Build stale after all retries: dependency "${String(d)}" changed during build.`,"system")}}return{ok:!0,value:h}}catch(e){if(n.aborted||e instanceof i)throw new i;if(e instanceof t)throw e;if(a++,a>=o)return{ok:!1,error:e}}return{ok:!1,error:new Error("Build exhausted retry budget unexpectedly.")}}commitResult(e,t,r,s,i){const{cleanupFunctions:n,disposeFunctions:o,capturedArtifactDeps:a,capturedStateDeps:c}=i;r||(this.updateDependencyGraph(e,a,c),t.cleanupFunctions=n,t.disposeFunctions=o),s.ok?(t.instance=s.value,t.error=void 0):(t.instance=void 0,t.error=s.error),t.version++,this.cache.invalidatePackage(e)}detectStaleness(e){for(const[t,r]of e){const e=this.cache.get(t);if(e&&e.version!==r)return t}return null}async invalidate(e,t=!1,r=!1){const s=this.cache.get(e);if(!s)return;if("singleton"!==s.scope)return this.executeInvalidation(e,t,r);const i=s;return i.debounceTimer&&(clearTimeout(i.debounceTimer),i.debounceTimer=void 0),!t&&i.activeDebounceMs>0?new Promise(((s,n)=>{i.debounceTimer=setTimeout((()=>{i.debounceTimer=void 0,this.executeInvalidation(e,t,r).then(s).catch(n)}),i.activeDebounceMs)})):this.executeInvalidation(e,t,r)}async executeInvalidation(e,t,r=!1){const s=this.cache.get(e);s&&"singleton"===s.scope&&await s.invalidationSerializer.do((async()=>{s.version++,await this.cache.invalidateInstance(e),await this.cascadeInvalidation(this.graph.iterDependents(e));const n=this.registry.get(e),o=n&&(t||!n.lazy||this.observer.hasWatchers(e))&&!r;o&&await this.build(e).catch((t=>{t instanceof i||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),(o||r)&&this.observer.notify(e)}))}async dispose(e){this.cache.get(e)&&(await this.cache.invalidateInstance(e,!0),this.graph.removeNode(e),this.cache.delete(e))}async processStream(e){await this.cascadeInvalidation(this.graph.iterDependents(e)),this.observer.notify(e)}async cascadeInvalidation(e){if(0===e.size)return;const t=[];for(const r of e)t.push(this.invalidate(r).catch((e=>{console.error(`[ArtifactManager] Cascade failed for "${String(r)}":`,e)})));await Promise.all(t)}updateDependencyGraph(e,t,r){const s=this.cache.get(e);if(s&&"singleton"===s.scope&&(this.graph.registerNode(e),this.graph.setDependencies(e,t),s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.stateDependencies=r,r.size>0)){const t=Array.from(r),i=()=>this.invalidate(e);s.stateUnsubscribe=this.store.watch(t,i)}}createCachedArtifact(e){return"transient"===e.scope?{scope:"transient",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0}:{scope:"singleton",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce?e.debounce:0,controller:new AbortController,buildOnce:new l({retry:!0,throws:!0}),streamOnce:new l({retry:!0,throws:!0}),streamSerializer:new u({yieldMode:"microtask"}),invalidationSerializer:new u({yieldMode:"macrotask"})}}},k=class{dependencies=new Map;dependents=new Map;registerNode(e){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set)}removeNode(e){if(!this.hasNode(e))return;const t=this.dependencies.get(e);if(t)for(const r of t)this.dependents.get(r)?.delete(e);const r=this.dependents.get(e);if(r)for(const t of r)this.dependencies.get(t)?.delete(e);this.dependencies.delete(e),this.dependents.delete(e)}hasNode(e){return this.dependencies.has(e)}addDependency(e,t){this.registerNode(e),this.registerNode(t),this.dependencies.get(e).add(t),this.dependents.get(t).add(e)}removeDependency(e,t){this.dependencies.get(e)?.delete(t),this.dependents.get(t)?.delete(e)}getDependencies(e){const t=this.dependencies.get(e);return t?new Set(t):new Set}getDependents(e){const t=this.dependents.get(e);return t?new Set(t):new Set}iterDependents(e){return this.dependents.get(e)??_}setDependencies(e,t){this.registerNode(e);const r=this.dependencies.get(e),s=new Set(t);for(const t of r)s.has(t)||this.removeDependency(e,t);for(const t of s)r.has(t)||this.addDependency(e,t)}wouldCreateCycle(e,t){if(e===t)return[e,t];const r=[t],s=new Set([t]),i=new Map;for(;r.length>0;){const n=r.shift();if(n===e){const r=[];let s=e;for(;void 0!==s&&(r.push(s),s!==t);)s=i.get(s);return r.reverse(),r.unshift(e),r}const o=this.dependencies.get(n);if(o)for(const e of o)s.has(e)||(s.add(e),i.set(e,n),r.push(e))}return null}topologicalSort(){const e=new Map,t=Array.from(this.dependencies.keys());for(const r of t)e.set(r,this.dependencies.get(r)?.size??0);const r=[];for(const[t,s]of e)0===s&&r.push(t);const s=[];for(;r.length>0;){const t=r.shift();s.push(t);const i=this.dependents.get(t);if(i)for(const t of i){const s=(e.get(t)||0)-1;e.set(t,s),0===s&&r.push(t)}}if(s.length!==t.length)throw new Error("Cycle detected in graph; topological sort impossible.");return s}getTransitiveDependencies(e,t=!1){return this.bfs(e,"dependencies",t)}getTransitiveDependents(e,t=!1){return this.bfs(e,"dependents",t)}bfs(e,t,r){const s=new Set,i=new Set,n=[e];i.add(e),r&&s.add(e);const o="dependencies"===t?this.dependencies:this.dependents;for(;n.length>0;){const e=n.shift(),t=o.get(e);if(t)for(const e of t)i.has(e)||(i.add(e),s.add(e),n.push(e))}return s}getAllNodes(){return Array.from(this.dependencies.keys())}size(){return this.dependencies.size}clear(){this.dependencies.clear(),this.dependents.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const r=Array.from(t).join(", ");return`${String(e)} → [${r||"∅"}]`})).join("\n")}},_=new Set,S=class{graph;constructor(){this.graph=new k}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){return Array.from(this.graph.getDependents(e))}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){return Array.from(this.graph.getDependencies(e))}getTransitiveDependents(e){return new Set(Array.from(this.graph.getTransitiveDependents(e,!1)))}setDependencies(e,t){const r=Array.from(t).map((e=>e));this.graph.setDependencies(e,r)}wouldCreateCycle(e,t,r){if(r?.has(t)){const e=Array.from(r),s=e.indexOf(t),i=e.slice(s);return i.push(t),i}const s=this.graph.wouldCreateCycle(e,t);return s||null}hasNode(e){return this.graph.hasNode(e)}getAllNodes(){return this.graph.getAllNodes()}clear(){this.graph.clear()}size(){return this.graph.size()}toDebugString(){return this.graph.toDebugString()}},C=class{cache=new Map;get(e){return this.cache.get(e)}set(e,t){this.cache.set(e,t)}delete(e){this.cache.delete(e)}has(e){return this.cache.has(e)}clear(){this.cache.clear()}size(){return this.cache.size}keys(){return Array.from(this.cache.keys())}package(e,t){const r=this.get(e);if(!r)return w;if(r.package)return r.package;const s=e,i=g(r.cleanupFunctions,s),n="singleton"!==r.scope||r.buildOnce.done(),o={instance:r.instance,error:r.error,ready:n,[e]:r.instance,cleanup:i,invalidate:t};return r.package=o,o}invalidatePackage(e){const t=this.get(e);t&&(t.package=void 0)}async invalidateInstance(e,t=!1){const r=this.get(e);if(!r)return;const s=e;"singleton"===r.scope&&(r.stateUnsubscribe&&(r.stateUnsubscribe(),r.stateUnsubscribe=void 0),r.debounceTimer&&(clearTimeout(r.debounceTimer),r.debounceTimer=void 0),r.controller.abort(),await r.streamOnce.current(),r.streamSerializer.close(),r.stream=void 0,r.streamOnce=new l({retry:!0,throws:!0}),t||(r.streamSerializer=new u,r.controller=new AbortController)),await f(r.cleanupFunctions,s),await f(r.disposeFunctions,s),r.cleanupFunctions=[],r.disposeFunctions=[],"singleton"===r.scope&&(r.buildOnce=new l({retry:!0,throws:!0})),r.instance=void 0,r.error=void 0}},x=class{constructor(e,t,r){this.registry=e,this.cache=t,this.container=r}listeners=new Map;watchers=new Map;watch(e){const t=String(e),r=this.registry.get(e);if(!r)throw new Error(`Artifact "${t}" not registered`);const s="transient"===r.scope,i=s?y(t):t,n=this.watchers.get(i);if(n)return n.observer;const o=new p((async()=>{s&&!this.registry.has(i)&&this.registry.register({key:i,factory:r.factory,scope:"singleton",lazy:r.lazy})}),(async()=>{s?(await this.registry.unregister(i).catch((()=>{})),this.cache.delete(i),this.watchers.delete(i)):this.cache.invalidatePackage(i),this.listeners.delete(i)}),{gracePeriod:s?"sync":"microtask"});let a;const c={id:t,get count(){return o.subscribers},get:(e=!1)=>0!==o.subscribers||e?this.cache.package(i,(e=>this.container.invalidate(i,e))):w,resolve:()=>a||(a=(async()=>{await o.acquire();try{return await this.container.resolve(i)}finally{o.release(),a=void 0}})(),a),subscribe:(e,t=!0)=>{const r=()=>e(c.get());return o.acquire().then((()=>this.container.resolve(i))).then((()=>{this.listeners.has(i)||this.listeners.set(i,new Set),t&&r(),this.listeners.get(i)?.add(r)})).catch((e=>{console.error(`[ArtifactObserver] Resolution failed for "${i}":`,e),this.listeners.get(i)?.add(r)})),()=>{this.listeners.get(i)?.delete(r),o.release()}}};return this.watchers.set(i,{resource:o,observer:c}),c}evictWatcher(e){[e,y(e)].forEach((e=>{const t=this.watchers.get(e);t&&(t.resource.forceCleanup(),this.watchers.delete(e))}))}notify(e){const t=this.listeners.get(e);if(t&&0!==t.size)for(const r of t)try{r()}catch(t){console.error(`[ArtifactObserver] Listener error for "${e}":`,t)}}hasWatchers(e){return this.watchers.has(e)||this.watchers.has(y(e))}getWatcherCount(e){const t=this.watchers.get(e)||this.watchers.get(y(e));return t?.resource.subscribers??0}clear(){this.watchers.clear(),this.listeners.clear()}};exports.ArtifactContainer=class{registry;cache;graph;manager;observer;store;constructor(e){this.store={watch:(...t)=>e.watch(...t),get:()=>e.get(!0),set:(...t)=>e.set(...t)},this.registry=new n,this.cache=new C,this.graph=new S,this.observer=new x(this.registry,this.cache,this),this.manager=new b(this.registry,this.cache,this.graph,this.store,this.observer)}debugInfo(){const e=[];return this.registry.keys().forEach((t=>{const r=this.registry.get(t),s=this.cache.get(t);if(!r)return;let i="idle";s&&("singleton"===s.scope&&void 0!==s.debounceTimer?i="debouncing":"singleton"===s.scope&&s.buildOnce.running()?i="building":s.error?i="error":void 0!==s.instance&&(i="active")),e.push({id:t,scope:r.scope??"singleton",status:i,dependencies:this.graph.getDependencies(t).map((e=>String(e))),dependents:this.graph.getDependents(t).map((e=>String(e))),stateDependencies:"singleton"===s?.scope?Array.from(s.stateDependencies):[],buildCount:s?.buildCount??0})})),e}register(e){const{key:t}=e,r=t;this.registry.has(t)&&(console.warn(`[ArtifactContainer] Overwriting "${r}".`),this.manager.dispose(t).catch((e=>{console.error(`[ArtifactContainer] Failed to dispose existing artifact "${r}":`,e)}))),this.registry.register(e),this.graph.registerNode(t);const s=e.scope??"singleton";return(e.lazy??!0)||"singleton"!==s||this.resolve(t).catch((e=>{console.error(`[ArtifactContainer] Eager load failed for "${r}":`,e)})),()=>this.unregister(t)}has(e){return this.registry.has(e)}async unregister(e){await this.manager.dispose(e),await this.registry.unregister(e),this.observer.evictWatcher(e)}async resolve(e){if(!this.registry.has(e))throw new r(e);return this.manager.build(e)}async require(e){const t=await this.resolve(e);if(t.error)throw t.error;return t.instance}watch(e){if(!this.registry.has(e))throw new r(e);return this.observer.watch(e)}peek(e){return this.cache.get(e)?.instance}async invalidate(e,t=!1){return this.manager.invalidate(e,t)}notifyObservers(e){this.observer.notify(e)}hasWatchers(e){return this.observer.hasWatchers(e)}async dispose(){const e=this.registry.keys();await Promise.allSettled(e.map((e=>this.manager.dispose(e).catch((t=>{console.error(`[ArtifactContainer] Failed to dispose artifact "${String(e)}":`,t)}))))),this.registry.clear(),this.cache.clear(),this.graph.clear(),this.observer.clear()}},exports.ArtifactScopes=e;
1
+ "use strict";var e=(e=>(e.Singleton="singleton",e.Transient="transient",e))(e||{}),t=class e extends Error{category;constructor(t,r,s){super(t,{cause:s}),this.name="ArtifactError",this.category=r,Object.setPrototypeOf(this,e.prototype)}},r=class extends t{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system"),this.name="ArtifactNotFoundError"}},s=class extends t{constructor(){super("Build superseded by invalidation","system"),this.name="SupersededBuildError"}},i=class{artifacts=new Map;register({key:e,factory:t,lazy:r,...s}){const{scope:i,...n}=s,a={key:e,factory:t,scope:s.scope??"singleton",lazy:void 0===r||r,...n};return this.artifacts.set(e,a),()=>this.unregister(e)}setVirtual(e,t){this.artifacts.set(e,t)}get(e){if(!this.has(e))throw new r(String(e));return this.artifacts.get(e)}getByString(e){return this.artifacts.get(e)}has(e){return this.artifacts.has(e)}hasString(e){return this.artifacts.has(e)}async unregister(e){this.artifacts.has(e)&&this.artifacts.delete(e)}size(){return this.artifacts.size}keys(){return Array.from(this.artifacts.keys())}clear(){this.artifacts.clear()}},n=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];var a=class e extends Error{constructor(t,r){super(t,{cause:r}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},o=class extends a{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},c=class extends a{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},h=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const r=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await r;let s;await Promise.race([r.then((()=>clearTimeout(s))),new Promise(((r,i)=>{s=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),i(new o("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},d=class{mutex=new h({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,r="Operation timed out"){if(null==t)return e;let s;return Promise.race([e.then((e=>(clearTimeout(s),e))),new Promise(((e,i)=>{s=setTimeout((()=>i(new o(r))),t)}))])}},u=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new h({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new c};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let r,s=null;try{if(this._done)throw new c;s=await e(),this._lastValue=s,this._lastError=void 0,this._hasRun=!0}catch(e){r=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:s,error:r}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},l=class{constructor(e,t,r={}){this.factory=e,this.onCleanup=t,this.options=r}_count=0;init=new d({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}};function p(e,t){if(!e.length)return;const r=e.slice(),s=t?`[${t}]`:"[ArtifactCleanup]";return async()=>{for(let e=r.length-1;e>=0;e--)try{await r[e]()}catch(t){console.error(`${s} Cleanup error at index ${e}:`,t)}}}async function g(e,t){const r=t?`[${t}]`:"[ArtifactCleanup]";for(let t=e.length-1;t>=0;t--)try{await e[t]()}catch(e){console.error(`${r} Cleanup error at index ${t}:`,e)}}function y(e){return`${e}__watched`}var f=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function w(e,t){let r;const s=new Promise(((e,s)=>{r=setTimeout((()=>s(new Error(`Timeout: ${t}ms`))),t)}));try{return Promise.race([e,s])}finally{clearTimeout(r)}}var m=(new AbortController).signal,v=class{constructor(e,t,r,s,i){this.registry=e,this.cache=t,this.graph=r,this.store=s,this.observer=i}async build(e,i){const n=this.cache.get(e);if("singleton"===n?.scope&&n.buildOnce.done())return this.cache.package(e,((t,r)=>this.invalidate(e,t,r)));const a=this.registry.getByString(e);if(!a)throw new r(e);const o=i??[];if(o.includes(e))throw new t(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${[...o,e].join(" -> ")}`,"system");o.push(e);let c=n;c||(c=this.createCachedArtifact(a),this.cache.set(e,c));try{if("transient"===c.scope)return this.executeBuild(a,c,o);const t=c;try{await t.buildOnce.do((()=>this.executeBuild(a,t,o)))}catch(t){if(t instanceof s)return this.build(e,i);throw t}return t.stream&&t.streamOnce.do(t.stream),this.cache.package(e,((t,r)=>this.invalidate(e,t,r)))}finally{o.pop()}}async executeBuild(e,t,r){const s=e.key,i=String(s),n="transient"===t.scope;t.buildCount++,"singleton"===t.scope&&(t.activeDebounceMs=e.debounce??0);const a={cleanupFunctions:[],disposeFunctions:[],capturedStateDeps:new Set,capturedArtifactDeps:new Set,dependencyVersions:new Map},o=this.buildContext(e,t,r,i,a),c=await this.runWithRetries(e,o,a.dependencyVersions);if(this.commitResult(s,t,n,c,a),n){const e=c.ok?c.value:void 0;return{instance:e,error:c.ok?void 0:c.error,ready:c.ok,[s]:e,cleanup:p(a.cleanupFunctions,i),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${i}"`)}}}buildContext(e,r,s,i,a){const o=e.key,c="transient"===r.scope,{cleanupFunctions:h,disposeFunctions:d,capturedStateDeps:u,capturedArtifactDeps:l,dependencyVersions:p}=a,g=async e=>{if(e===o)throw new t(`Artifact "${i}" depends on itself.`,"system");const r=this.graph.wouldCreateCycle(o,e);if(r)throw new t(`Adding dependency "${String(e)}" to "${i}" would create a cycle: ${r.join(" -> ")}`,"system");l.add(e);const n=await this.build(e,s),a=this.cache.get(e);return a&&p.set(e,a.version),n},y="singleton"===r.scope?r.controller.signal:m,f=async e=>{const t=await g(e);if(t.error)throw t.error;return t.instance},w=e=>(function(e,t="."){const r=new Set,s=new Map,i=(e="")=>{if(s.has(e))return s.get(e);const a=new Proxy((()=>{}),{get:(s,a)=>{if("symbol"==typeof a||"then"===a)return;if("valueOf"===a||"toString"===a)throw new Error("Cannot perform logic, arithmetic, or string operations inside a selector.");if(n.includes(a))throw new Error(`Array method .${a}() is not allowed in selectors.`);const o=e?`${e}${t}${a}`:a;return e&&r.delete(e),r.add(o),i(o)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions or methods.")}});return s.set(e,a),a};try{e(i())}catch(e){throw new Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(r)}(e).forEach((e=>u.add(e))),e(this.store.get(!0)));return{state:()=>this.store.get(!0),previous:r.instance,signal:y,onCleanup:e=>h.push(e),onDispose:e=>d.push(e),use:e=>e({resolve:g,require:f,select:w}),stream:e=>{if(c)throw new t(`[ArtifactManager] Illegal stream on transient artifact "${i}"`,"system");const s=r,n=async(e,t=void 0)=>{await s.streamSerializer.do((async()=>{void 0!==s.stream&&(s.instance=e,s.error=t,s.version++,this.cache.invalidatePackage(o),await this.processStream(i))}))},a={value:()=>s.instance,get signal(){return s.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>n(e)};s.stream=async()=>{try{const t=await e(a);t&&s.cleanupFunctions.push(t)}catch(e){await n(void 0,e),await this.invalidate(o,!1,!0)}}}}}async runWithRetries(e,r,i){const n=r.signal,a=(e.retries??0)+1;let o=0;for(;o<a;)try{if(n.aborted)throw new s;const c=e.factory(r);let h;if(h=c instanceof Promise?e.timeout?await w(c,e.timeout):await c:c,n.aborted)throw new s;const d=this.detectStaleness(i);if(d){if(o++,i.clear(),o<a)continue;return{ok:!1,error:new t(`Build stale after all retries: dependency "${String(d)}" changed during build.`,"system")}}return{ok:!0,value:h}}catch(e){if(n.aborted||e instanceof s)throw new s;if(e instanceof t)throw e;if(o++,o>=a)return{ok:!1,error:e}}return{ok:!1,error:new Error("Build exhausted retry budget unexpectedly.")}}commitResult(e,t,r,s,i){const{cleanupFunctions:n,disposeFunctions:a,capturedArtifactDeps:o,capturedStateDeps:c}=i;r||(this.updateDependencyGraph(e,o,c),t.cleanupFunctions=n,t.disposeFunctions=a),s.ok?(t.instance=s.value,t.error=void 0):(t.instance=void 0,t.error=s.error),t.version++,this.cache.invalidatePackage(e)}detectStaleness(e){for(const[t,r]of e){const e=this.cache.get(t);if(e&&e.version!==r)return t}return null}async invalidate(e,t=!1,r=!1){const s=this.cache.get(e);if(!s)return;if("singleton"!==s.scope)return this.executeInvalidation(e,t,r);const i=s;return i.debounceTimer&&(clearTimeout(i.debounceTimer),i.debounceTimer=void 0),!t&&i.activeDebounceMs>0?new Promise(((s,n)=>{i.debounceTimer=setTimeout((()=>{i.debounceTimer=void 0,this.executeInvalidation(e,t,r).then(s).catch(n)}),i.activeDebounceMs)})):this.executeInvalidation(e,t,r)}async executeInvalidation(e,t,r=!1){const i=this.cache.get(e);i&&"singleton"===i.scope&&await i.invalidationSerializer.do((async()=>{i.version++,await this.cache.invalidateInstance(e),await this.cascadeInvalidation(this.graph.iterDependents(e));const n=this.registry.get(e),a=n&&(t||!n.lazy||this.observer.hasWatchers(e))&&!r;a&&await this.build(e).catch((t=>{t instanceof s||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),(a||r)&&this.observer.notify(e)}))}async dispose(e){this.cache.get(e)&&(await this.cache.invalidateInstance(e,!0),this.graph.removeNode(e),this.cache.delete(e))}async processStream(e){await this.cascadeInvalidation(this.graph.iterDependents(e)),this.observer.notify(e)}async cascadeInvalidation(e){if(0===e.size)return;const t=[];for(const r of e)t.push(this.invalidate(r).catch((e=>{console.error(`[ArtifactManager] Cascade failed for "${String(r)}":`,e)})));await Promise.all(t)}updateDependencyGraph(e,t,r){const s=this.cache.get(e);if(s&&"singleton"===s.scope&&(this.graph.registerNode(e),this.graph.setDependencies(e,t),s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.stateDependencies=r,r.size>0)){const t=Array.from(r),i=()=>this.invalidate(e);s.stateUnsubscribe=this.store.watch(t,i)}}createCachedArtifact(e){return"transient"===e.scope?{scope:"transient",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0}:{scope:"singleton",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce?e.debounce:0,controller:new AbortController,buildOnce:new d({retry:!0,throws:!0}),streamOnce:new d({retry:!0,throws:!0}),streamSerializer:new u({yieldMode:"microtask"}),invalidationSerializer:new u({yieldMode:"macrotask"})}}},b=class{dependencies=new Map;dependents=new Map;registerNode(e){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set)}removeNode(e){if(!this.hasNode(e))return;const t=this.dependencies.get(e);if(t)for(const r of t)this.dependents.get(r)?.delete(e);const r=this.dependents.get(e);if(r)for(const t of r)this.dependencies.get(t)?.delete(e);this.dependencies.delete(e),this.dependents.delete(e)}hasNode(e){return this.dependencies.has(e)}addDependency(e,t){this.registerNode(e),this.registerNode(t),this.dependencies.get(e).add(t),this.dependents.get(t).add(e)}removeDependency(e,t){this.dependencies.get(e)?.delete(t),this.dependents.get(t)?.delete(e)}getDependencies(e){const t=this.dependencies.get(e);return t?new Set(t):new Set}getDependents(e){const t=this.dependents.get(e);return t?new Set(t):new Set}iterDependents(e){return this.dependents.get(e)??k}setDependencies(e,t){this.registerNode(e);const r=this.dependencies.get(e),s=new Set(t);for(const t of r)s.has(t)||this.removeDependency(e,t);for(const t of s)r.has(t)||this.addDependency(e,t)}wouldCreateCycle(e,t){if(e===t)return[e,t];const r=[t],s=new Set([t]),i=new Map;for(;r.length>0;){const n=r.shift();if(n===e){const r=[];let s=e;for(;void 0!==s&&(r.push(s),s!==t);)s=i.get(s);return r.reverse(),r.unshift(e),r}const a=this.dependencies.get(n);if(a)for(const e of a)s.has(e)||(s.add(e),i.set(e,n),r.push(e))}return null}topologicalSort(){const e=new Map,t=Array.from(this.dependencies.keys());for(const r of t)e.set(r,this.dependencies.get(r)?.size??0);const r=[];for(const[t,s]of e)0===s&&r.push(t);const s=[];for(;r.length>0;){const t=r.shift();s.push(t);const i=this.dependents.get(t);if(i)for(const t of i){const s=(e.get(t)||0)-1;e.set(t,s),0===s&&r.push(t)}}if(s.length!==t.length)throw new Error("Cycle detected in graph; topological sort impossible.");return s}getTransitiveDependencies(e,t=!1){return this.bfs(e,"dependencies",t)}getTransitiveDependents(e,t=!1){return this.bfs(e,"dependents",t)}bfs(e,t,r){const s=new Set,i=new Set,n=[e];i.add(e),r&&s.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;n.length>0;){const e=n.shift(),t=a.get(e);if(t)for(const e of t)i.has(e)||(i.add(e),s.add(e),n.push(e))}return s}getAllNodes(){return Array.from(this.dependencies.keys())}size(){return this.dependencies.size}clear(){this.dependencies.clear(),this.dependents.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const r=Array.from(t).join(", ");return`${String(e)} → [${r||"∅"}]`})).join("\n")}},k=new Set,S=class{graph;constructor(){this.graph=new b}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){return Array.from(this.graph.getDependents(e))}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){return Array.from(this.graph.getDependencies(e))}getTransitiveDependents(e){return new Set(Array.from(this.graph.getTransitiveDependents(e,!1)))}setDependencies(e,t){const r=Array.from(t).map((e=>e));this.graph.setDependencies(e,r)}wouldCreateCycle(e,t,r){if(r?.has(t)){const e=Array.from(r),s=e.indexOf(t),i=e.slice(s);return i.push(t),i}const s=this.graph.wouldCreateCycle(e,t);return s||null}hasNode(e){return this.graph.hasNode(e)}getAllNodes(){return this.graph.getAllNodes()}clear(){this.graph.clear()}size(){return this.graph.size()}toDebugString(){return this.graph.toDebugString()}},_=class{cache=new Map;get(e){return this.cache.get(e)}set(e,t){this.cache.set(e,t)}delete(e){this.cache.delete(e)}has(e){return this.cache.has(e)}clear(){this.cache.clear()}size(){return this.cache.size}keys(){return Array.from(this.cache.keys())}package(e,t){const r=this.get(e);if(!r)return f;if(r.package)return r.package;const s=e,i=p(r.cleanupFunctions,s),n="singleton"!==r.scope||void 0!==r.instance,a={instance:r.instance,error:r.error,ready:n,[e]:r.instance,cleanup:i,invalidate:t};return r.package=a,a}invalidatePackage(e){const t=this.get(e);t&&(t.package=void 0)}async invalidateInstance(e,t=!1){const r=this.get(e);if(!r)return;const s=e;"singleton"===r.scope&&(r.stateUnsubscribe&&(r.stateUnsubscribe(),r.stateUnsubscribe=void 0),r.debounceTimer&&(clearTimeout(r.debounceTimer),r.debounceTimer=void 0),r.controller.abort(),await r.streamOnce.current(),r.streamSerializer.close(),r.stream=void 0,r.streamOnce=new d({retry:!0,throws:!0}),t||(r.streamSerializer=new u,r.controller=new AbortController)),await g(r.cleanupFunctions,s),await g(r.disposeFunctions,s),r.cleanupFunctions=[],r.disposeFunctions=[],"singleton"===r.scope&&(r.buildOnce=new d({retry:!0,throws:!0})),r.instance=void 0,r.error=void 0}},C=class{constructor(e,t,r){this.registry=e,this.cache=t,this.container=r}listeners=new Map;watchers=new Map;watch(e){return this.watchForKey(e,this.registry.get(e))}watchParameterized(e,t){const r=this.registry.get(e);if(!r.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);const s=r.paramKey(t);return this.watchForKey(s,r,t)}watchForKey(e,t,r){const s="transient"===t.scope,i=s?y(e):e,n=this.watchers.get(i);if(n)return n.observer;const a=new l((async()=>{!s&&void 0===r||this.registry.hasString(e)||this.registry.setVirtual(e,{key:e,factory:s?t.factory:e=>t.factory({...e,params:r}),scope:s?"singleton":t.scope,lazy:t.lazy,timeout:t.timeout,retries:t.retries,debounce:t.debounce,virtual:!0})}),(async()=>{s||void 0!==r?(await this.registry.unregister(i).catch((()=>{})),this.cache.delete(i),this.watchers.delete(i)):this.cache.invalidatePackage(i),this.listeners.delete(i)}),{gracePeriod:s?"sync":"microtask"});let o;const c={id:i,get count(){return a.subscribers},get:(e=!1)=>0!==a.subscribers||e?this.cache.package(i,((e,t)=>this.container.invalidate(i,e,t))):f,resolve:()=>o||(o=(async()=>{await a.acquire();try{return await this.container.resolve(i)}finally{a.release(),o=void 0}})(),o),subscribe:(e,t=!0)=>{const r=()=>e(c.get());return a.acquire().then((()=>{this.container.resolve(i).then((()=>{this.listeners.has(i)||this.listeners.set(i,new Set),t&&r(),this.listeners.get(i).add(r)}))})).catch((e=>{console.error(`[ArtifactObserver] Resolution failed for "${i}":`,e),this.listeners.get(i)?.add(r)})),()=>{this.listeners.get(i)?.delete(r),a.release()}}};return this.watchers.set(i,{resource:a,observer:c}),c}evictWatcher(e){[e,y(e)].forEach((e=>{const t=this.watchers.get(e);t&&(t.resource.forceCleanup(),this.watchers.delete(e))}))}notify(e){const t=this.listeners.get(e);if(t&&0!==t.size)for(const r of t)try{r()}catch(t){console.error(`[ArtifactObserver] Listener error for "${e}":`,t)}}hasWatchers(e){return this.watchers.has(e)||this.watchers.has(y(e))}getWatcherCount(e){const t=this.watchers.get(e)||this.watchers.get(y(e));return t?.resource.subscribers??0}clear(){this.watchers.clear(),this.listeners.clear()}};exports.ArtifactContainer=class{registry;cache;graph;manager;observer;store;constructor(e){this.store={watch:(...t)=>e.watch(...t),get:()=>e.get(!0),set:(...t)=>e.set(...t)},this.registry=new i,this.cache=new _,this.graph=new S,this.observer=new C(this.registry,this.cache,this),this.manager=new v(this.registry,this.cache,this.graph,this.store,this.observer)}debugInfo(){const e=[];return this.registry.keys().forEach((t=>{const r=t,s=this.registry.get(r),i=this.cache.get(r);if(!s)return;let n="idle";i&&("singleton"===i.scope&&void 0!==i.debounceTimer?n="debouncing":"singleton"===i.scope&&i.buildOnce.running()?n="building":i.error?n="error":void 0!==i.instance&&(n="active")),e.push({id:r,scope:s.scope??"singleton",status:n,dependencies:this.graph.getDependencies(r).map((e=>String(e))),dependents:this.graph.getDependents(r).map((e=>String(e))),stateDependencies:"singleton"===i?.scope?Array.from(i.stateDependencies):[],buildCount:i?.buildCount??0})})),e}register(e){const{key:t}=e,r=t;this.registry.has(t)&&(console.warn(`[ArtifactContainer] Overwriting "${r}".`),this.manager.dispose(t).catch((e=>{console.error(`[ArtifactContainer] Failed to dispose existing artifact "${r}":`,e)}))),this.registry.register(e),this.graph.registerNode(t);const s=e.scope??"singleton";return(e.lazy??!0)||"singleton"!==s||this.resolve(t).catch((e=>{console.error(`[ArtifactContainer] Eager load failed for "${r}":`,e)})),()=>this.unregister(t)}has(e){return this.registry.has(e)}async unregister(e,t){const r=void 0!==t?this.computeParamKey(e,t):e;await this.manager.dispose(r),await this.registry.unregister(r),this.observer.evictWatcher(r)}async resolve(e,t){return void 0===t?this.resolveStatic(e):this.resolveParameterized(e,t)}async require(e,t){const r=await this.resolve(e,t);if(r.error)throw r.error;return r.instance}watch(e,t){return void 0===t?this.observer.watch(e):this.observer.watchParameterized(e,t)}peek(e,t){const r=void 0!==t?this.computeParamKey(e,t):e;return this.cache.get(r)?.instance}async invalidate(e,t){const r=t?.params,s=t?.replace??!1,i=void 0!==r?this.computeParamKey(e,r):e;return this.manager.invalidate(i,s)}notifyObservers(e){this.observer.notify(e)}hasWatchers(e){return this.observer.hasWatchers(e)}async dispose(){const e=this.registry.keys();await Promise.allSettled(e.map((e=>this.manager.dispose(e).catch((t=>{console.error(`[ArtifactContainer] Failed to dispose artifact "${String(e)}":`,t)}))))),this.registry.clear(),this.cache.clear(),this.graph.clear(),this.observer.clear()}resolveStatic(e){if(!this.registry.has(e))throw new r(e);return this.manager.build(e)}async resolveParameterized(e,s){if(!this.registry.has(e))throw new r(String(e));const i=this.registry.get(e);if(!i.paramKey)throw new t(`Artifact "${String(e)}" is not parameterized.`,"external");const n=i.paramKey(s),a=this.registry.getByString(n);if(a&&!a.paramKey&&!a.virtual)throw new t(`Parameterized artifact "${String(e)}" with params ${JSON.stringify(s)} resolves to key "${n}" which is already registered as a static artifact.`,"system");return this.registry.hasString(n)||this.registry.setVirtual(n,{key:n,factory:e=>i.factory({...e,params:s}),scope:i.scope,lazy:i.lazy,timeout:i.timeout,retries:i.retries,debounce:i.debounce,virtual:!0}),this.manager.build(n)}computeParamKey(e,t){const r=this.registry.get(e);if(!r.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);return r.paramKey(t)}},exports.ArtifactScopes=e;
package/index.mjs CHANGED
@@ -1 +1 @@
1
- var e=(e=>(e.Singleton="singleton",e.Transient="transient",e))(e||{}),t=class e extends Error{category;constructor(t,r,s){super(t,{cause:s}),this.name="ArtifactError",this.category=r,Object.setPrototypeOf(this,e.prototype)}},r=class extends t{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system"),this.name="ArtifactNotFoundError"}},s=class extends t{constructor(e){super(`[ArtifactContainer] An artifact with key:${e} already exists!`,"system"),this.name="ArtifactKeyConflict"}},i=class extends t{constructor(){super("Build superseded by invalidation","system"),this.name="SupersededBuildError"}},n=class{artifacts=new Map;register({key:e,factory:t,lazy:r,...i}){if(this.artifacts.has(e))throw new s(String(e));const{scope:n,...o}=i,a={key:e,factory:t,scope:i.scope??"singleton",lazy:void 0===r||r,...o};return this.artifacts.set(e,a),()=>this.unregister(e)}get(e){if(!this.has(e))throw new r(String(e));return this.artifacts.get(e)}has(e){return this.artifacts.has(e)}async unregister(e){this.artifacts.has(e)&&this.artifacts.delete(e)}size(){return this.artifacts.size}keys(){return Array.from(this.artifacts.keys())}clear(){this.artifacts.clear()}},o=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];var a=class e extends Error{constructor(t,r){super(t,{cause:r}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},c=class extends a{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},h=class extends a{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},d=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const r=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await r;let s;await Promise.race([r.then((()=>clearTimeout(s))),new Promise(((r,i)=>{s=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),i(new c("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},l=class{mutex=new d({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,r="Operation timed out"){if(null==t)return e;let s;return Promise.race([e.then((e=>(clearTimeout(s),e))),new Promise(((e,i)=>{s=setTimeout((()=>i(new c(r))),t)}))])}},u=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new d({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new h};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let r,s=null;try{if(this._done)throw new h;s=await e(),this._lastValue=s,this._lastError=void 0,this._hasRun=!0}catch(e){r=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:s,error:r}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},p=class{constructor(e,t,r={}){this.factory=e,this.onCleanup=t,this.options=r}_count=0;init=new l({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}};function g(e,t){if(!e.length)return;const r=e.slice(),s=t?`[${t}]`:"[ArtifactCleanup]";return async()=>{for(let e=r.length-1;e>=0;e--)try{await r[e]()}catch(t){console.error(`${s} Cleanup error at index ${e}:`,t)}}}async function f(e,t){const r=t?`[${t}]`:"[ArtifactCleanup]";for(let t=e.length-1;t>=0;t--)try{await e[t]()}catch(e){console.error(`${r} Cleanup error at index ${t}:`,e)}}function y(e){return`${e}__watched`}var w=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function m(e,t){let r;const s=new Promise(((e,s)=>{r=setTimeout((()=>s(new Error(`Timeout: ${t}ms`))),t)}));try{return Promise.race([e,s])}finally{clearTimeout(r)}}var v=(new AbortController).signal,b=class{constructor(e,t,r,s,i){this.registry=e,this.cache=t,this.graph=r,this.store=s,this.observer=i}async build(e,r){const s=this.cache.get(e);if("singleton"===s?.scope&&s.buildOnce.done())return this.cache.package(e,((t,r)=>this.invalidate(e,t,r)));const n=this.registry.get(e),o=r??[];if(o.includes(e))throw new t(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${[...o,e].join(" -> ")}`,"system");o.push(e);let a=s;a||(a=this.createCachedArtifact(n),this.cache.set(e,a));try{if("transient"===a.scope)return this.executeBuild(n,a,o);const t=a;try{await t.buildOnce.do((()=>this.executeBuild(n,t,o)))}catch(t){if(t instanceof i)return this.build(e,r);throw t}return t.stream&&t.streamOnce.do(t.stream),this.cache.package(e,((t,r)=>this.invalidate(e,t,r)))}finally{o.pop()}}async executeBuild(e,t,r){const s=e.key,i=String(s),n="transient"===t.scope;t.buildCount++,"singleton"===t.scope&&(t.activeDebounceMs=e.debounce??0);const o={cleanupFunctions:[],disposeFunctions:[],capturedStateDeps:new Set,capturedArtifactDeps:new Set,dependencyVersions:new Map},a=this.buildContext(e,t,r,i,o),c=await this.runWithRetries(e,a,o.dependencyVersions);if(this.commitResult(s,t,n,c,o),n){const e=c.ok?c.value:void 0;return{instance:e,error:c.ok?void 0:c.error,ready:c.ok,[s]:e,cleanup:g(o.cleanupFunctions,i),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${i}"`)}}}buildContext(e,r,s,i,n){const a=e.key,c="transient"===r.scope,{cleanupFunctions:h,disposeFunctions:d,capturedStateDeps:l,capturedArtifactDeps:u,dependencyVersions:p}=n,g=async e=>{if(e===a)throw new t(`Artifact "${i}" depends on itself.`,"system");const r=this.graph.wouldCreateCycle(a,e);if(r)throw new t(`Adding dependency "${String(e)}" to "${i}" would create a cycle: ${r.join(" -> ")}`,"system");u.add(e);const n=await this.build(e,s),o=this.cache.get(e);return o&&p.set(e,o.version),n},f="singleton"===r.scope?r.controller.signal:v,y=async e=>{const t=await g(e);if(t.error)throw t.error;return t.instance},w=e=>(function(e,t="."){const r=new Set,s=new Map,i=(e="")=>{if(s.has(e))return s.get(e);const n=new Proxy((()=>{}),{get:(s,n)=>{if("symbol"==typeof n||"then"===n)return;if("valueOf"===n||"toString"===n)throw new Error("Cannot perform logic, arithmetic, or string operations inside a selector.");if(o.includes(n))throw new Error(`Array method .${n}() is not allowed in selectors.`);const a=e?`${e}${t}${n}`:n;return e&&r.delete(e),r.add(a),i(a)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions or methods.")}});return s.set(e,n),n};try{e(i())}catch(e){throw new Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(r)}(e).forEach((e=>l.add(e))),e(this.store.get(!0)));return{state:()=>this.store.get(!0),previous:r.instance,signal:f,onCleanup:e=>h.push(e),onDispose:e=>d.push(e),use:e=>e({resolve:g,require:y,select:w}),stream:e=>{if(c)throw new t(`[ArtifactManager] Illegal stream on transient artifact "${i}"`,"system");const s=r,n=async(e,t=void 0)=>{await s.streamSerializer.do((async()=>{void 0!==s.stream&&(s.instance=e,s.error=t,s.version++,this.cache.invalidatePackage(a),await this.processStream(i))}))},o={value:()=>s.instance,get signal(){return s.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>n(e)};s.stream=async()=>{try{const t=await e(o);t&&s.cleanupFunctions.push(t)}catch(e){await n(void 0,e),await this.invalidate(a,!1,!0)}}}}}async runWithRetries(e,r,s){const n=r.signal,o=(e.retries??0)+1;let a=0;for(;a<o;)try{if(n.aborted)throw new i;const c=e.factory(r);let h;if(h=c instanceof Promise?e.timeout?await m(c,e.timeout):await c:c,n.aborted)throw new i;const d=this.detectStaleness(s);if(d){if(a++,s.clear(),a<o)continue;return{ok:!1,error:new t(`Build stale after all retries: dependency "${String(d)}" changed during build.`,"system")}}return{ok:!0,value:h}}catch(e){if(n.aborted||e instanceof i)throw new i;if(e instanceof t)throw e;if(a++,a>=o)return{ok:!1,error:e}}return{ok:!1,error:new Error("Build exhausted retry budget unexpectedly.")}}commitResult(e,t,r,s,i){const{cleanupFunctions:n,disposeFunctions:o,capturedArtifactDeps:a,capturedStateDeps:c}=i;r||(this.updateDependencyGraph(e,a,c),t.cleanupFunctions=n,t.disposeFunctions=o),s.ok?(t.instance=s.value,t.error=void 0):(t.instance=void 0,t.error=s.error),t.version++,this.cache.invalidatePackage(e)}detectStaleness(e){for(const[t,r]of e){const e=this.cache.get(t);if(e&&e.version!==r)return t}return null}async invalidate(e,t=!1,r=!1){const s=this.cache.get(e);if(!s)return;if("singleton"!==s.scope)return this.executeInvalidation(e,t,r);const i=s;return i.debounceTimer&&(clearTimeout(i.debounceTimer),i.debounceTimer=void 0),!t&&i.activeDebounceMs>0?new Promise(((s,n)=>{i.debounceTimer=setTimeout((()=>{i.debounceTimer=void 0,this.executeInvalidation(e,t,r).then(s).catch(n)}),i.activeDebounceMs)})):this.executeInvalidation(e,t,r)}async executeInvalidation(e,t,r=!1){const s=this.cache.get(e);s&&"singleton"===s.scope&&await s.invalidationSerializer.do((async()=>{s.version++,await this.cache.invalidateInstance(e),await this.cascadeInvalidation(this.graph.iterDependents(e));const n=this.registry.get(e),o=n&&(t||!n.lazy||this.observer.hasWatchers(e))&&!r;o&&await this.build(e).catch((t=>{t instanceof i||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),(o||r)&&this.observer.notify(e)}))}async dispose(e){this.cache.get(e)&&(await this.cache.invalidateInstance(e,!0),this.graph.removeNode(e),this.cache.delete(e))}async processStream(e){await this.cascadeInvalidation(this.graph.iterDependents(e)),this.observer.notify(e)}async cascadeInvalidation(e){if(0===e.size)return;const t=[];for(const r of e)t.push(this.invalidate(r).catch((e=>{console.error(`[ArtifactManager] Cascade failed for "${String(r)}":`,e)})));await Promise.all(t)}updateDependencyGraph(e,t,r){const s=this.cache.get(e);if(s&&"singleton"===s.scope&&(this.graph.registerNode(e),this.graph.setDependencies(e,t),s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.stateDependencies=r,r.size>0)){const t=Array.from(r),i=()=>this.invalidate(e);s.stateUnsubscribe=this.store.watch(t,i)}}createCachedArtifact(e){return"transient"===e.scope?{scope:"transient",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0}:{scope:"singleton",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce?e.debounce:0,controller:new AbortController,buildOnce:new l({retry:!0,throws:!0}),streamOnce:new l({retry:!0,throws:!0}),streamSerializer:new u({yieldMode:"microtask"}),invalidationSerializer:new u({yieldMode:"macrotask"})}}},k=class{dependencies=new Map;dependents=new Map;registerNode(e){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set)}removeNode(e){if(!this.hasNode(e))return;const t=this.dependencies.get(e);if(t)for(const r of t)this.dependents.get(r)?.delete(e);const r=this.dependents.get(e);if(r)for(const t of r)this.dependencies.get(t)?.delete(e);this.dependencies.delete(e),this.dependents.delete(e)}hasNode(e){return this.dependencies.has(e)}addDependency(e,t){this.registerNode(e),this.registerNode(t),this.dependencies.get(e).add(t),this.dependents.get(t).add(e)}removeDependency(e,t){this.dependencies.get(e)?.delete(t),this.dependents.get(t)?.delete(e)}getDependencies(e){const t=this.dependencies.get(e);return t?new Set(t):new Set}getDependents(e){const t=this.dependents.get(e);return t?new Set(t):new Set}iterDependents(e){return this.dependents.get(e)??_}setDependencies(e,t){this.registerNode(e);const r=this.dependencies.get(e),s=new Set(t);for(const t of r)s.has(t)||this.removeDependency(e,t);for(const t of s)r.has(t)||this.addDependency(e,t)}wouldCreateCycle(e,t){if(e===t)return[e,t];const r=[t],s=new Set([t]),i=new Map;for(;r.length>0;){const n=r.shift();if(n===e){const r=[];let s=e;for(;void 0!==s&&(r.push(s),s!==t);)s=i.get(s);return r.reverse(),r.unshift(e),r}const o=this.dependencies.get(n);if(o)for(const e of o)s.has(e)||(s.add(e),i.set(e,n),r.push(e))}return null}topologicalSort(){const e=new Map,t=Array.from(this.dependencies.keys());for(const r of t)e.set(r,this.dependencies.get(r)?.size??0);const r=[];for(const[t,s]of e)0===s&&r.push(t);const s=[];for(;r.length>0;){const t=r.shift();s.push(t);const i=this.dependents.get(t);if(i)for(const t of i){const s=(e.get(t)||0)-1;e.set(t,s),0===s&&r.push(t)}}if(s.length!==t.length)throw new Error("Cycle detected in graph; topological sort impossible.");return s}getTransitiveDependencies(e,t=!1){return this.bfs(e,"dependencies",t)}getTransitiveDependents(e,t=!1){return this.bfs(e,"dependents",t)}bfs(e,t,r){const s=new Set,i=new Set,n=[e];i.add(e),r&&s.add(e);const o="dependencies"===t?this.dependencies:this.dependents;for(;n.length>0;){const e=n.shift(),t=o.get(e);if(t)for(const e of t)i.has(e)||(i.add(e),s.add(e),n.push(e))}return s}getAllNodes(){return Array.from(this.dependencies.keys())}size(){return this.dependencies.size}clear(){this.dependencies.clear(),this.dependents.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const r=Array.from(t).join(", ");return`${String(e)} → [${r||"∅"}]`})).join("\n")}},_=new Set,S=class{graph;constructor(){this.graph=new k}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){return Array.from(this.graph.getDependents(e))}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){return Array.from(this.graph.getDependencies(e))}getTransitiveDependents(e){return new Set(Array.from(this.graph.getTransitiveDependents(e,!1)))}setDependencies(e,t){const r=Array.from(t).map((e=>e));this.graph.setDependencies(e,r)}wouldCreateCycle(e,t,r){if(r?.has(t)){const e=Array.from(r),s=e.indexOf(t),i=e.slice(s);return i.push(t),i}const s=this.graph.wouldCreateCycle(e,t);return s||null}hasNode(e){return this.graph.hasNode(e)}getAllNodes(){return this.graph.getAllNodes()}clear(){this.graph.clear()}size(){return this.graph.size()}toDebugString(){return this.graph.toDebugString()}},C=class{cache=new Map;get(e){return this.cache.get(e)}set(e,t){this.cache.set(e,t)}delete(e){this.cache.delete(e)}has(e){return this.cache.has(e)}clear(){this.cache.clear()}size(){return this.cache.size}keys(){return Array.from(this.cache.keys())}package(e,t){const r=this.get(e);if(!r)return w;if(r.package)return r.package;const s=e,i=g(r.cleanupFunctions,s),n="singleton"!==r.scope||r.buildOnce.done(),o={instance:r.instance,error:r.error,ready:n,[e]:r.instance,cleanup:i,invalidate:t};return r.package=o,o}invalidatePackage(e){const t=this.get(e);t&&(t.package=void 0)}async invalidateInstance(e,t=!1){const r=this.get(e);if(!r)return;const s=e;"singleton"===r.scope&&(r.stateUnsubscribe&&(r.stateUnsubscribe(),r.stateUnsubscribe=void 0),r.debounceTimer&&(clearTimeout(r.debounceTimer),r.debounceTimer=void 0),r.controller.abort(),await r.streamOnce.current(),r.streamSerializer.close(),r.stream=void 0,r.streamOnce=new l({retry:!0,throws:!0}),t||(r.streamSerializer=new u,r.controller=new AbortController)),await f(r.cleanupFunctions,s),await f(r.disposeFunctions,s),r.cleanupFunctions=[],r.disposeFunctions=[],"singleton"===r.scope&&(r.buildOnce=new l({retry:!0,throws:!0})),r.instance=void 0,r.error=void 0}},x=class{constructor(e,t,r){this.registry=e,this.cache=t,this.container=r}listeners=new Map;watchers=new Map;watch(e){const t=String(e),r=this.registry.get(e);if(!r)throw new Error(`Artifact "${t}" not registered`);const s="transient"===r.scope,i=s?y(t):t,n=this.watchers.get(i);if(n)return n.observer;const o=new p((async()=>{s&&!this.registry.has(i)&&this.registry.register({key:i,factory:r.factory,scope:"singleton",lazy:r.lazy})}),(async()=>{s?(await this.registry.unregister(i).catch((()=>{})),this.cache.delete(i),this.watchers.delete(i)):this.cache.invalidatePackage(i),this.listeners.delete(i)}),{gracePeriod:s?"sync":"microtask"});let a;const c={id:t,get count(){return o.subscribers},get:(e=!1)=>0!==o.subscribers||e?this.cache.package(i,(e=>this.container.invalidate(i,e))):w,resolve:()=>a||(a=(async()=>{await o.acquire();try{return await this.container.resolve(i)}finally{o.release(),a=void 0}})(),a),subscribe:(e,t=!0)=>{const r=()=>e(c.get());return o.acquire().then((()=>this.container.resolve(i))).then((()=>{this.listeners.has(i)||this.listeners.set(i,new Set),t&&r(),this.listeners.get(i)?.add(r)})).catch((e=>{console.error(`[ArtifactObserver] Resolution failed for "${i}":`,e),this.listeners.get(i)?.add(r)})),()=>{this.listeners.get(i)?.delete(r),o.release()}}};return this.watchers.set(i,{resource:o,observer:c}),c}evictWatcher(e){[e,y(e)].forEach((e=>{const t=this.watchers.get(e);t&&(t.resource.forceCleanup(),this.watchers.delete(e))}))}notify(e){const t=this.listeners.get(e);if(t&&0!==t.size)for(const r of t)try{r()}catch(t){console.error(`[ArtifactObserver] Listener error for "${e}":`,t)}}hasWatchers(e){return this.watchers.has(e)||this.watchers.has(y(e))}getWatcherCount(e){const t=this.watchers.get(e)||this.watchers.get(y(e));return t?.resource.subscribers??0}clear(){this.watchers.clear(),this.listeners.clear()}},A=class{registry;cache;graph;manager;observer;store;constructor(e){this.store={watch:(...t)=>e.watch(...t),get:()=>e.get(!0),set:(...t)=>e.set(...t)},this.registry=new n,this.cache=new C,this.graph=new S,this.observer=new x(this.registry,this.cache,this),this.manager=new b(this.registry,this.cache,this.graph,this.store,this.observer)}debugInfo(){const e=[];return this.registry.keys().forEach((t=>{const r=this.registry.get(t),s=this.cache.get(t);if(!r)return;let i="idle";s&&("singleton"===s.scope&&void 0!==s.debounceTimer?i="debouncing":"singleton"===s.scope&&s.buildOnce.running()?i="building":s.error?i="error":void 0!==s.instance&&(i="active")),e.push({id:t,scope:r.scope??"singleton",status:i,dependencies:this.graph.getDependencies(t).map((e=>String(e))),dependents:this.graph.getDependents(t).map((e=>String(e))),stateDependencies:"singleton"===s?.scope?Array.from(s.stateDependencies):[],buildCount:s?.buildCount??0})})),e}register(e){const{key:t}=e,r=t;this.registry.has(t)&&(console.warn(`[ArtifactContainer] Overwriting "${r}".`),this.manager.dispose(t).catch((e=>{console.error(`[ArtifactContainer] Failed to dispose existing artifact "${r}":`,e)}))),this.registry.register(e),this.graph.registerNode(t);const s=e.scope??"singleton";return(e.lazy??!0)||"singleton"!==s||this.resolve(t).catch((e=>{console.error(`[ArtifactContainer] Eager load failed for "${r}":`,e)})),()=>this.unregister(t)}has(e){return this.registry.has(e)}async unregister(e){await this.manager.dispose(e),await this.registry.unregister(e),this.observer.evictWatcher(e)}async resolve(e){if(!this.registry.has(e))throw new r(e);return this.manager.build(e)}async require(e){const t=await this.resolve(e);if(t.error)throw t.error;return t.instance}watch(e){if(!this.registry.has(e))throw new r(e);return this.observer.watch(e)}peek(e){return this.cache.get(e)?.instance}async invalidate(e,t=!1){return this.manager.invalidate(e,t)}notifyObservers(e){this.observer.notify(e)}hasWatchers(e){return this.observer.hasWatchers(e)}async dispose(){const e=this.registry.keys();await Promise.allSettled(e.map((e=>this.manager.dispose(e).catch((t=>{console.error(`[ArtifactContainer] Failed to dispose artifact "${String(e)}":`,t)}))))),this.registry.clear(),this.cache.clear(),this.graph.clear(),this.observer.clear()}};export{A as ArtifactContainer,e as ArtifactScopes};
1
+ var e=(e=>(e.Singleton="singleton",e.Transient="transient",e))(e||{}),t=class e extends Error{category;constructor(t,r,s){super(t,{cause:s}),this.name="ArtifactError",this.category=r,Object.setPrototypeOf(this,e.prototype)}},r=class extends t{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system"),this.name="ArtifactNotFoundError"}},s=class extends t{constructor(){super("Build superseded by invalidation","system"),this.name="SupersededBuildError"}},i=class{artifacts=new Map;register({key:e,factory:t,lazy:r,...s}){const{scope:i,...n}=s,a={key:e,factory:t,scope:s.scope??"singleton",lazy:void 0===r||r,...n};return this.artifacts.set(e,a),()=>this.unregister(e)}setVirtual(e,t){this.artifacts.set(e,t)}get(e){if(!this.has(e))throw new r(String(e));return this.artifacts.get(e)}getByString(e){return this.artifacts.get(e)}has(e){return this.artifacts.has(e)}hasString(e){return this.artifacts.has(e)}async unregister(e){this.artifacts.has(e)&&this.artifacts.delete(e)}size(){return this.artifacts.size}keys(){return Array.from(this.artifacts.keys())}clear(){this.artifacts.clear()}},n=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];var a=class e extends Error{constructor(t,r){super(t,{cause:r}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},o=class extends a{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},c=class extends a{constructor(e){super("[Serializer] The serializer has been marked as done!",e)}},h=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const r=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await r;let s;await Promise.race([r.then((()=>clearTimeout(s))),new Promise(((r,i)=>{s=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),i(new o("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},d=class{mutex=new h({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,r="Operation timed out"){if(null==t)return e;let s;return Promise.race([e.then((e=>(clearTimeout(s),e))),new Promise(((e,i)=>{s=setTimeout((()=>i(new o(r))),t)}))])}},u=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new h({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new c};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let r,s=null;try{if(this._done)throw new c;s=await e(),this._lastValue=s,this._lastError=void 0,this._hasRun=!0}catch(e){r=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:s,error:r}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},l=class{constructor(e,t,r={}){this.factory=e,this.onCleanup=t,this.options=r}_count=0;init=new d({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}};function p(e,t){if(!e.length)return;const r=e.slice(),s=t?`[${t}]`:"[ArtifactCleanup]";return async()=>{for(let e=r.length-1;e>=0;e--)try{await r[e]()}catch(t){console.error(`${s} Cleanup error at index ${e}:`,t)}}}async function g(e,t){const r=t?`[${t}]`:"[ArtifactCleanup]";for(let t=e.length-1;t>=0;t--)try{await e[t]()}catch(e){console.error(`${r} Cleanup error at index ${t}:`,e)}}function y(e){return`${e}__watched`}var f=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function w(e,t){let r;const s=new Promise(((e,s)=>{r=setTimeout((()=>s(new Error(`Timeout: ${t}ms`))),t)}));try{return Promise.race([e,s])}finally{clearTimeout(r)}}var m=(new AbortController).signal,v=class{constructor(e,t,r,s,i){this.registry=e,this.cache=t,this.graph=r,this.store=s,this.observer=i}async build(e,i){const n=this.cache.get(e);if("singleton"===n?.scope&&n.buildOnce.done())return this.cache.package(e,((t,r)=>this.invalidate(e,t,r)));const a=this.registry.getByString(e);if(!a)throw new r(e);const o=i??[];if(o.includes(e))throw new t(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${[...o,e].join(" -> ")}`,"system");o.push(e);let c=n;c||(c=this.createCachedArtifact(a),this.cache.set(e,c));try{if("transient"===c.scope)return this.executeBuild(a,c,o);const t=c;try{await t.buildOnce.do((()=>this.executeBuild(a,t,o)))}catch(t){if(t instanceof s)return this.build(e,i);throw t}return t.stream&&t.streamOnce.do(t.stream),this.cache.package(e,((t,r)=>this.invalidate(e,t,r)))}finally{o.pop()}}async executeBuild(e,t,r){const s=e.key,i=String(s),n="transient"===t.scope;t.buildCount++,"singleton"===t.scope&&(t.activeDebounceMs=e.debounce??0);const a={cleanupFunctions:[],disposeFunctions:[],capturedStateDeps:new Set,capturedArtifactDeps:new Set,dependencyVersions:new Map},o=this.buildContext(e,t,r,i,a),c=await this.runWithRetries(e,o,a.dependencyVersions);if(this.commitResult(s,t,n,c,a),n){const e=c.ok?c.value:void 0;return{instance:e,error:c.ok?void 0:c.error,ready:c.ok,[s]:e,cleanup:p(a.cleanupFunctions,i),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${i}"`)}}}buildContext(e,r,s,i,a){const o=e.key,c="transient"===r.scope,{cleanupFunctions:h,disposeFunctions:d,capturedStateDeps:u,capturedArtifactDeps:l,dependencyVersions:p}=a,g=async e=>{if(e===o)throw new t(`Artifact "${i}" depends on itself.`,"system");const r=this.graph.wouldCreateCycle(o,e);if(r)throw new t(`Adding dependency "${String(e)}" to "${i}" would create a cycle: ${r.join(" -> ")}`,"system");l.add(e);const n=await this.build(e,s),a=this.cache.get(e);return a&&p.set(e,a.version),n},y="singleton"===r.scope?r.controller.signal:m,f=async e=>{const t=await g(e);if(t.error)throw t.error;return t.instance},w=e=>(function(e,t="."){const r=new Set,s=new Map,i=(e="")=>{if(s.has(e))return s.get(e);const a=new Proxy((()=>{}),{get:(s,a)=>{if("symbol"==typeof a||"then"===a)return;if("valueOf"===a||"toString"===a)throw new Error("Cannot perform logic, arithmetic, or string operations inside a selector.");if(n.includes(a))throw new Error(`Array method .${a}() is not allowed in selectors.`);const o=e?`${e}${t}${a}`:a;return e&&r.delete(e),r.add(o),i(o)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions or methods.")}});return s.set(e,a),a};try{e(i())}catch(e){throw new Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(r)}(e).forEach((e=>u.add(e))),e(this.store.get(!0)));return{state:()=>this.store.get(!0),previous:r.instance,signal:y,onCleanup:e=>h.push(e),onDispose:e=>d.push(e),use:e=>e({resolve:g,require:f,select:w}),stream:e=>{if(c)throw new t(`[ArtifactManager] Illegal stream on transient artifact "${i}"`,"system");const s=r,n=async(e,t=void 0)=>{await s.streamSerializer.do((async()=>{void 0!==s.stream&&(s.instance=e,s.error=t,s.version++,this.cache.invalidatePackage(o),await this.processStream(i))}))},a={value:()=>s.instance,get signal(){return s.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>n(e)};s.stream=async()=>{try{const t=await e(a);t&&s.cleanupFunctions.push(t)}catch(e){await n(void 0,e),await this.invalidate(o,!1,!0)}}}}}async runWithRetries(e,r,i){const n=r.signal,a=(e.retries??0)+1;let o=0;for(;o<a;)try{if(n.aborted)throw new s;const c=e.factory(r);let h;if(h=c instanceof Promise?e.timeout?await w(c,e.timeout):await c:c,n.aborted)throw new s;const d=this.detectStaleness(i);if(d){if(o++,i.clear(),o<a)continue;return{ok:!1,error:new t(`Build stale after all retries: dependency "${String(d)}" changed during build.`,"system")}}return{ok:!0,value:h}}catch(e){if(n.aborted||e instanceof s)throw new s;if(e instanceof t)throw e;if(o++,o>=a)return{ok:!1,error:e}}return{ok:!1,error:new Error("Build exhausted retry budget unexpectedly.")}}commitResult(e,t,r,s,i){const{cleanupFunctions:n,disposeFunctions:a,capturedArtifactDeps:o,capturedStateDeps:c}=i;r||(this.updateDependencyGraph(e,o,c),t.cleanupFunctions=n,t.disposeFunctions=a),s.ok?(t.instance=s.value,t.error=void 0):(t.instance=void 0,t.error=s.error),t.version++,this.cache.invalidatePackage(e)}detectStaleness(e){for(const[t,r]of e){const e=this.cache.get(t);if(e&&e.version!==r)return t}return null}async invalidate(e,t=!1,r=!1){const s=this.cache.get(e);if(!s)return;if("singleton"!==s.scope)return this.executeInvalidation(e,t,r);const i=s;return i.debounceTimer&&(clearTimeout(i.debounceTimer),i.debounceTimer=void 0),!t&&i.activeDebounceMs>0?new Promise(((s,n)=>{i.debounceTimer=setTimeout((()=>{i.debounceTimer=void 0,this.executeInvalidation(e,t,r).then(s).catch(n)}),i.activeDebounceMs)})):this.executeInvalidation(e,t,r)}async executeInvalidation(e,t,r=!1){const i=this.cache.get(e);i&&"singleton"===i.scope&&await i.invalidationSerializer.do((async()=>{i.version++,await this.cache.invalidateInstance(e),await this.cascadeInvalidation(this.graph.iterDependents(e));const n=this.registry.get(e),a=n&&(t||!n.lazy||this.observer.hasWatchers(e))&&!r;a&&await this.build(e).catch((t=>{t instanceof s||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),(a||r)&&this.observer.notify(e)}))}async dispose(e){this.cache.get(e)&&(await this.cache.invalidateInstance(e,!0),this.graph.removeNode(e),this.cache.delete(e))}async processStream(e){await this.cascadeInvalidation(this.graph.iterDependents(e)),this.observer.notify(e)}async cascadeInvalidation(e){if(0===e.size)return;const t=[];for(const r of e)t.push(this.invalidate(r).catch((e=>{console.error(`[ArtifactManager] Cascade failed for "${String(r)}":`,e)})));await Promise.all(t)}updateDependencyGraph(e,t,r){const s=this.cache.get(e);if(s&&"singleton"===s.scope&&(this.graph.registerNode(e),this.graph.setDependencies(e,t),s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.stateDependencies=r,r.size>0)){const t=Array.from(r),i=()=>this.invalidate(e);s.stateUnsubscribe=this.store.watch(t,i)}}createCachedArtifact(e){return"transient"===e.scope?{scope:"transient",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0}:{scope:"singleton",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce?e.debounce:0,controller:new AbortController,buildOnce:new d({retry:!0,throws:!0}),streamOnce:new d({retry:!0,throws:!0}),streamSerializer:new u({yieldMode:"microtask"}),invalidationSerializer:new u({yieldMode:"macrotask"})}}},b=class{dependencies=new Map;dependents=new Map;registerNode(e){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set)}removeNode(e){if(!this.hasNode(e))return;const t=this.dependencies.get(e);if(t)for(const r of t)this.dependents.get(r)?.delete(e);const r=this.dependents.get(e);if(r)for(const t of r)this.dependencies.get(t)?.delete(e);this.dependencies.delete(e),this.dependents.delete(e)}hasNode(e){return this.dependencies.has(e)}addDependency(e,t){this.registerNode(e),this.registerNode(t),this.dependencies.get(e).add(t),this.dependents.get(t).add(e)}removeDependency(e,t){this.dependencies.get(e)?.delete(t),this.dependents.get(t)?.delete(e)}getDependencies(e){const t=this.dependencies.get(e);return t?new Set(t):new Set}getDependents(e){const t=this.dependents.get(e);return t?new Set(t):new Set}iterDependents(e){return this.dependents.get(e)??k}setDependencies(e,t){this.registerNode(e);const r=this.dependencies.get(e),s=new Set(t);for(const t of r)s.has(t)||this.removeDependency(e,t);for(const t of s)r.has(t)||this.addDependency(e,t)}wouldCreateCycle(e,t){if(e===t)return[e,t];const r=[t],s=new Set([t]),i=new Map;for(;r.length>0;){const n=r.shift();if(n===e){const r=[];let s=e;for(;void 0!==s&&(r.push(s),s!==t);)s=i.get(s);return r.reverse(),r.unshift(e),r}const a=this.dependencies.get(n);if(a)for(const e of a)s.has(e)||(s.add(e),i.set(e,n),r.push(e))}return null}topologicalSort(){const e=new Map,t=Array.from(this.dependencies.keys());for(const r of t)e.set(r,this.dependencies.get(r)?.size??0);const r=[];for(const[t,s]of e)0===s&&r.push(t);const s=[];for(;r.length>0;){const t=r.shift();s.push(t);const i=this.dependents.get(t);if(i)for(const t of i){const s=(e.get(t)||0)-1;e.set(t,s),0===s&&r.push(t)}}if(s.length!==t.length)throw new Error("Cycle detected in graph; topological sort impossible.");return s}getTransitiveDependencies(e,t=!1){return this.bfs(e,"dependencies",t)}getTransitiveDependents(e,t=!1){return this.bfs(e,"dependents",t)}bfs(e,t,r){const s=new Set,i=new Set,n=[e];i.add(e),r&&s.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;n.length>0;){const e=n.shift(),t=a.get(e);if(t)for(const e of t)i.has(e)||(i.add(e),s.add(e),n.push(e))}return s}getAllNodes(){return Array.from(this.dependencies.keys())}size(){return this.dependencies.size}clear(){this.dependencies.clear(),this.dependents.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const r=Array.from(t).join(", ");return`${String(e)} → [${r||"∅"}]`})).join("\n")}},k=new Set,S=class{graph;constructor(){this.graph=new b}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){return Array.from(this.graph.getDependents(e))}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){return Array.from(this.graph.getDependencies(e))}getTransitiveDependents(e){return new Set(Array.from(this.graph.getTransitiveDependents(e,!1)))}setDependencies(e,t){const r=Array.from(t).map((e=>e));this.graph.setDependencies(e,r)}wouldCreateCycle(e,t,r){if(r?.has(t)){const e=Array.from(r),s=e.indexOf(t),i=e.slice(s);return i.push(t),i}const s=this.graph.wouldCreateCycle(e,t);return s||null}hasNode(e){return this.graph.hasNode(e)}getAllNodes(){return this.graph.getAllNodes()}clear(){this.graph.clear()}size(){return this.graph.size()}toDebugString(){return this.graph.toDebugString()}},_=class{cache=new Map;get(e){return this.cache.get(e)}set(e,t){this.cache.set(e,t)}delete(e){this.cache.delete(e)}has(e){return this.cache.has(e)}clear(){this.cache.clear()}size(){return this.cache.size}keys(){return Array.from(this.cache.keys())}package(e,t){const r=this.get(e);if(!r)return f;if(r.package)return r.package;const s=e,i=p(r.cleanupFunctions,s),n="singleton"!==r.scope||void 0!==r.instance,a={instance:r.instance,error:r.error,ready:n,[e]:r.instance,cleanup:i,invalidate:t};return r.package=a,a}invalidatePackage(e){const t=this.get(e);t&&(t.package=void 0)}async invalidateInstance(e,t=!1){const r=this.get(e);if(!r)return;const s=e;"singleton"===r.scope&&(r.stateUnsubscribe&&(r.stateUnsubscribe(),r.stateUnsubscribe=void 0),r.debounceTimer&&(clearTimeout(r.debounceTimer),r.debounceTimer=void 0),r.controller.abort(),await r.streamOnce.current(),r.streamSerializer.close(),r.stream=void 0,r.streamOnce=new d({retry:!0,throws:!0}),t||(r.streamSerializer=new u,r.controller=new AbortController)),await g(r.cleanupFunctions,s),await g(r.disposeFunctions,s),r.cleanupFunctions=[],r.disposeFunctions=[],"singleton"===r.scope&&(r.buildOnce=new d({retry:!0,throws:!0})),r.instance=void 0,r.error=void 0}},C=class{constructor(e,t,r){this.registry=e,this.cache=t,this.container=r}listeners=new Map;watchers=new Map;watch(e){return this.watchForKey(e,this.registry.get(e))}watchParameterized(e,t){const r=this.registry.get(e);if(!r.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);const s=r.paramKey(t);return this.watchForKey(s,r,t)}watchForKey(e,t,r){const s="transient"===t.scope,i=s?y(e):e,n=this.watchers.get(i);if(n)return n.observer;const a=new l((async()=>{!s&&void 0===r||this.registry.hasString(e)||this.registry.setVirtual(e,{key:e,factory:s?t.factory:e=>t.factory({...e,params:r}),scope:s?"singleton":t.scope,lazy:t.lazy,timeout:t.timeout,retries:t.retries,debounce:t.debounce,virtual:!0})}),(async()=>{s||void 0!==r?(await this.registry.unregister(i).catch((()=>{})),this.cache.delete(i),this.watchers.delete(i)):this.cache.invalidatePackage(i),this.listeners.delete(i)}),{gracePeriod:s?"sync":"microtask"});let o;const c={id:i,get count(){return a.subscribers},get:(e=!1)=>0!==a.subscribers||e?this.cache.package(i,((e,t)=>this.container.invalidate(i,e,t))):f,resolve:()=>o||(o=(async()=>{await a.acquire();try{return await this.container.resolve(i)}finally{a.release(),o=void 0}})(),o),subscribe:(e,t=!0)=>{const r=()=>e(c.get());return a.acquire().then((()=>{this.container.resolve(i).then((()=>{this.listeners.has(i)||this.listeners.set(i,new Set),t&&r(),this.listeners.get(i).add(r)}))})).catch((e=>{console.error(`[ArtifactObserver] Resolution failed for "${i}":`,e),this.listeners.get(i)?.add(r)})),()=>{this.listeners.get(i)?.delete(r),a.release()}}};return this.watchers.set(i,{resource:a,observer:c}),c}evictWatcher(e){[e,y(e)].forEach((e=>{const t=this.watchers.get(e);t&&(t.resource.forceCleanup(),this.watchers.delete(e))}))}notify(e){const t=this.listeners.get(e);if(t&&0!==t.size)for(const r of t)try{r()}catch(t){console.error(`[ArtifactObserver] Listener error for "${e}":`,t)}}hasWatchers(e){return this.watchers.has(e)||this.watchers.has(y(e))}getWatcherCount(e){const t=this.watchers.get(e)||this.watchers.get(y(e));return t?.resource.subscribers??0}clear(){this.watchers.clear(),this.listeners.clear()}},x=class{registry;cache;graph;manager;observer;store;constructor(e){this.store={watch:(...t)=>e.watch(...t),get:()=>e.get(!0),set:(...t)=>e.set(...t)},this.registry=new i,this.cache=new _,this.graph=new S,this.observer=new C(this.registry,this.cache,this),this.manager=new v(this.registry,this.cache,this.graph,this.store,this.observer)}debugInfo(){const e=[];return this.registry.keys().forEach((t=>{const r=t,s=this.registry.get(r),i=this.cache.get(r);if(!s)return;let n="idle";i&&("singleton"===i.scope&&void 0!==i.debounceTimer?n="debouncing":"singleton"===i.scope&&i.buildOnce.running()?n="building":i.error?n="error":void 0!==i.instance&&(n="active")),e.push({id:r,scope:s.scope??"singleton",status:n,dependencies:this.graph.getDependencies(r).map((e=>String(e))),dependents:this.graph.getDependents(r).map((e=>String(e))),stateDependencies:"singleton"===i?.scope?Array.from(i.stateDependencies):[],buildCount:i?.buildCount??0})})),e}register(e){const{key:t}=e,r=t;this.registry.has(t)&&(console.warn(`[ArtifactContainer] Overwriting "${r}".`),this.manager.dispose(t).catch((e=>{console.error(`[ArtifactContainer] Failed to dispose existing artifact "${r}":`,e)}))),this.registry.register(e),this.graph.registerNode(t);const s=e.scope??"singleton";return(e.lazy??!0)||"singleton"!==s||this.resolve(t).catch((e=>{console.error(`[ArtifactContainer] Eager load failed for "${r}":`,e)})),()=>this.unregister(t)}has(e){return this.registry.has(e)}async unregister(e,t){const r=void 0!==t?this.computeParamKey(e,t):e;await this.manager.dispose(r),await this.registry.unregister(r),this.observer.evictWatcher(r)}async resolve(e,t){return void 0===t?this.resolveStatic(e):this.resolveParameterized(e,t)}async require(e,t){const r=await this.resolve(e,t);if(r.error)throw r.error;return r.instance}watch(e,t){return void 0===t?this.observer.watch(e):this.observer.watchParameterized(e,t)}peek(e,t){const r=void 0!==t?this.computeParamKey(e,t):e;return this.cache.get(r)?.instance}async invalidate(e,t){const r=t?.params,s=t?.replace??!1,i=void 0!==r?this.computeParamKey(e,r):e;return this.manager.invalidate(i,s)}notifyObservers(e){this.observer.notify(e)}hasWatchers(e){return this.observer.hasWatchers(e)}async dispose(){const e=this.registry.keys();await Promise.allSettled(e.map((e=>this.manager.dispose(e).catch((t=>{console.error(`[ArtifactContainer] Failed to dispose artifact "${String(e)}":`,t)}))))),this.registry.clear(),this.cache.clear(),this.graph.clear(),this.observer.clear()}resolveStatic(e){if(!this.registry.has(e))throw new r(e);return this.manager.build(e)}async resolveParameterized(e,s){if(!this.registry.has(e))throw new r(String(e));const i=this.registry.get(e);if(!i.paramKey)throw new t(`Artifact "${String(e)}" is not parameterized.`,"external");const n=i.paramKey(s),a=this.registry.getByString(n);if(a&&!a.paramKey&&!a.virtual)throw new t(`Parameterized artifact "${String(e)}" with params ${JSON.stringify(s)} resolves to key "${n}" which is already registered as a static artifact.`,"system");return this.registry.hasString(n)||this.registry.setVirtual(n,{key:n,factory:e=>i.factory({...e,params:s}),scope:i.scope,lazy:i.lazy,timeout:i.timeout,retries:i.retries,debounce:i.debounce,virtual:!0}),this.manager.build(n)}computeParamKey(e,t){const r=this.registry.get(e);if(!r.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);return r.paramKey(t)}};export{x as ArtifactContainer,e as ArtifactScopes};
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@asaidimu/utils-artifacts",
3
- "version": "8.1.3",
3
+ "version": "8.2.0",
4
4
  "description": "Reactive artifact container.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
7
7
  "types": "index.d.ts",
8
8
  "dependencies": {
9
- "@asaidimu/utils-events": "^1.0.0"
9
+ "@asaidimu/utils-events": "1.1.0"
10
10
  },
11
11
  "keywords": [
12
12
  "typescript",