@asaidimu/utils-artifacts 7.2.0 → 8.0.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
@@ -41,8 +41,8 @@ type StoreEvent = "update:start" | "update:complete" | "middleware:start" | "mid
41
41
  */
42
42
  type StateUpdater<T> = T | DeepPartial<T> | ((state: T) => DeepPartial<T> | Promise<DeepPartial<T>>);
43
43
  /**
44
- * Core types for the reactive data store
45
- */
44
+ * Core types for the reactive data store
45
+ */
46
46
  /**
47
47
  * Type for a Transform Middleware function.
48
48
  * It modifies (transforms) the incoming changes and must return a `DeepPartial<T>`.
@@ -450,6 +450,9 @@ interface PendingArtifact extends ResolvedArtifactBase {
450
450
  * @template TArtifact The type of the resolved artifact instance.
451
451
  */
452
452
  type ResolvedArtifact<TArtifact> = ReadyArtifact<TArtifact> | ErrorArtifact | PendingArtifact;
453
+ type KeyedResolvedArtifact<TRegistry, K extends keyof TRegistry> = ResolvedArtifact<TRegistry[K]> & {
454
+ [P in K]?: TRegistry[K];
455
+ };
453
456
  /**
454
457
  * The factory function responsible for creating an artifact's instance.
455
458
  * It receives an `ArtifactFactoryContext` to interact with the container
@@ -468,7 +471,7 @@ type ArtifactInstance<R> = R extends PromiseLike<infer T> ? T : R;
468
471
  * Provides a way to get the current resolved artifact and subscribe to updates.
469
472
  * @template TArtifact The type of the artifact being watched.
470
473
  */
471
- interface ArtifactObserver<TArtifact> {
474
+ interface ArtifactObserver<TRegistry, K extends keyof TRegistry> {
472
475
  /** The unique identifier (key) of the artifact being watched. */
473
476
  id: string;
474
477
  /**
@@ -482,7 +485,7 @@ interface ArtifactObserver<TArtifact> {
482
485
  * immediately. Defaults to `false`
483
486
  * @returns The resolved artifact, including its instance and status.
484
487
  */
485
- get(resolve?: boolean): ResolvedArtifact<TArtifact>;
488
+ get(resolve?: boolean): KeyedResolvedArtifact<TRegistry, K>;
486
489
  /**
487
490
  * Subscribes a callback function to be invoked whenever the artifact's
488
491
  * state (instance, error, or readiness) changes.
@@ -491,7 +494,7 @@ interface ArtifactObserver<TArtifact> {
491
494
  * callback after subscription. Defaults to `true`
492
495
  * @returns A function to unsubscribe the callback and stop receiving updates.
493
496
  */
494
- subscribe(callback: (artifact: ResolvedArtifact<TArtifact>) => void, eager?: boolean): () => void;
497
+ subscribe(callback: (artifact: KeyedResolvedArtifact<TRegistry, K>) => void, eager?: boolean): () => void;
495
498
  /**
496
499
  * Resolves another artifact from the container and registers a dependency on it.
497
500
  * If the dependency changes, the current artifact will be invalidated and rebuilt.
@@ -499,7 +502,7 @@ interface ArtifactObserver<TArtifact> {
499
502
  * or an external error.
500
503
  * @throws {SystemError} if resolution fails.
501
504
  */
502
- resolve(): Promise<ResolvedArtifact<TArtifact>>;
505
+ resolve(): Promise<KeyedResolvedArtifact<TRegistry, K>>;
503
506
  }
504
507
  /**
505
508
  * Configuration options for defining an artifact. These options control
@@ -604,7 +607,7 @@ type InferRegistry<T extends Record<string, {
604
607
  * - ArtifactCache: Stores resolved singleton instances
605
608
  * - ArtifactDependencyGraph: Tracks artifact dependencies using DependencyGraph
606
609
  * - ArtifactManager: Handles lifecycle (build, invalidate, dispose)
607
- * - ArtifactObserver: Manages watchers and subscriptions
610
+ * - ArtifactObserverManager: Manages watchers and subscriptions
608
611
  *
609
612
  * @template TRegistry A type that maps artifact keys to their types
610
613
  * @template TState The type of the global state object
@@ -644,8 +647,8 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
644
647
  */
645
648
  register<K extends keyof TRegistry>(params: ArtifactTemplate<TState, TRegistry[K], TRegistry>): () => void;
646
649
  /**
647
- * Returns a boolean indicating whether a template exists for an artifact
648
- * @template K The key of the artifact to unregister.
650
+ * Returns a boolean indicating whether a template exists for an artifact.
651
+ *
649
652
  * @param key The unique identifier of the artifact.
650
653
  * @returns boolean.
651
654
  */
@@ -654,45 +657,49 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
654
657
  * Unregisters an artifact from the container, disposing of its current instance
655
658
  * and removing all associated resources and dependency links.
656
659
  *
660
+ * Also evicts the observer watcher cache entry so singleton watchers do not
661
+ * outlive the artifact's registration.
662
+ *
657
663
  * @param key The unique identifier of the artifact
658
664
  */
659
665
  unregister<K extends keyof TRegistry>(key: K): Promise<void>;
660
666
  /**
661
667
  * Resolves an artifact by its key, returning its instance or an error.
662
- * This method handles dependency resolution, cycle detection (via graph),
663
- * caching, and retry logic. Traverses the container hierarchy if the artifact
664
- * is not found locally.
668
+ * Handles dependency resolution, cycle detection, caching, and retry logic.
669
+ *
670
+ * The keyed index property (`artifact[key]`) is set inside `cache.package()`
671
+ * so it is always consistent with `artifact.instance`. No post-hoc mutation
672
+ * is needed here.
665
673
  *
666
674
  * @param key The unique identifier for the artifact
667
675
  * @returns A Promise that resolves to a ResolvedArtifact
668
676
  * @throws {ArtifactNotFoundError} if the artifact is not found
669
- * @throws {ArtifactError} if a cycle is detected or other system errors occur
670
677
  */
671
- resolve<K extends keyof TRegistry>(key: K): Promise<ResolvedArtifact<TRegistry[K]>>;
678
+ resolve<K extends keyof TRegistry>(key: K): Promise<KeyedResolvedArtifact<TRegistry, K>>;
672
679
  /**
673
680
  * Resolves an artifact by its key, returning its instance directly.
674
- * This is a wrapper around resolve to prevent defensive programming
681
+ * Throws if resolution fails.
675
682
  *
676
683
  * @param key The unique identifier for the artifact
677
- * @returns A Promise that resolves to a ResolvedArtifact
684
+ * @returns A Promise that resolves to the artifact instance
678
685
  * @throws {ArtifactNotFoundError} if the artifact is not found
679
- * @throws {ArtifactError} if a cycle is detected or other system errors occur
686
+ * @throws the artifact's error if resolution failed
680
687
  */
681
688
  require<K extends keyof TRegistry>(key: K): Promise<TRegistry[K]>;
682
689
  /**
683
- * Returns an ArtifactWatcher for a given artifact key.
684
- * The watcher allows subscribing to changes in the artifact's resolved value.
690
+ * Returns an ArtifactObserver for a given artifact key.
691
+ * The observer allows subscribing to changes in the artifact's resolved value.
685
692
  *
686
693
  * @param key The unique identifier for the artifact
687
- * @returns An ArtifactWatcher instance
694
+ * @returns An ArtifactObserver instance
688
695
  */
689
- watch<K extends keyof TRegistry>(key: K): ArtifactObserver<TRegistry[K]>;
696
+ watch<K extends keyof TRegistry>(key: K): ArtifactObserver<TRegistry, K>;
690
697
  /**
691
- * Peeks at the resolved instance of an artifact without triggering its resolution
692
- * if it's lazy, or registering a dependency.
698
+ * Peeks at the resolved instance of an artifact without triggering resolution
699
+ * or registering a dependency.
693
700
  *
694
701
  * @param key The unique identifier for the artifact
695
- * @returns The artifact instance if it's already built, otherwise undefined
702
+ * @returns The artifact instance if already built, otherwise undefined
696
703
  */
697
704
  peek<K extends keyof TRegistry>(key: K): TRegistry[K] | undefined;
698
705
  /**
@@ -718,16 +725,13 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
718
725
  */
719
726
  hasWatchers(key: string): boolean;
720
727
  /**
721
- * Disposes of the entire ArtifactContainer and all artifacts registered within it.
722
- * This releases all resources, stops all watchers, and clears all internal state.
723
- * After disposal, the container should no longer be used.
728
+ * Disposes of the entire container and all artifacts registered within it.
729
+ * Releases all resources, stops all watchers, and clears all internal state.
724
730
  *
725
731
  * Returns a Promise that resolves once all artifact teardowns have settled.
726
- * Previously this was synchronous (fire-and-forget), which meant the container
727
- * could be garbage-collected before async cleanup completed. Callers should
728
- * await this method to guarantee full resource release.
732
+ * Callers should await this method to guarantee full resource release.
729
733
  */
730
734
  dispose(): Promise<void>;
731
735
  }
732
736
 
733
- 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 PendingArtifact, type ReadyArtifact, type ResolvedArtifact, type ResolvedArtifactBase, type UseDependencyContext };
737
+ 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
@@ -41,8 +41,8 @@ type StoreEvent = "update:start" | "update:complete" | "middleware:start" | "mid
41
41
  */
42
42
  type StateUpdater<T> = T | DeepPartial<T> | ((state: T) => DeepPartial<T> | Promise<DeepPartial<T>>);
43
43
  /**
44
- * Core types for the reactive data store
45
- */
44
+ * Core types for the reactive data store
45
+ */
46
46
  /**
47
47
  * Type for a Transform Middleware function.
48
48
  * It modifies (transforms) the incoming changes and must return a `DeepPartial<T>`.
@@ -450,6 +450,9 @@ interface PendingArtifact extends ResolvedArtifactBase {
450
450
  * @template TArtifact The type of the resolved artifact instance.
451
451
  */
452
452
  type ResolvedArtifact<TArtifact> = ReadyArtifact<TArtifact> | ErrorArtifact | PendingArtifact;
453
+ type KeyedResolvedArtifact<TRegistry, K extends keyof TRegistry> = ResolvedArtifact<TRegistry[K]> & {
454
+ [P in K]?: TRegistry[K];
455
+ };
453
456
  /**
454
457
  * The factory function responsible for creating an artifact's instance.
455
458
  * It receives an `ArtifactFactoryContext` to interact with the container
@@ -468,7 +471,7 @@ type ArtifactInstance<R> = R extends PromiseLike<infer T> ? T : R;
468
471
  * Provides a way to get the current resolved artifact and subscribe to updates.
469
472
  * @template TArtifact The type of the artifact being watched.
470
473
  */
471
- interface ArtifactObserver<TArtifact> {
474
+ interface ArtifactObserver<TRegistry, K extends keyof TRegistry> {
472
475
  /** The unique identifier (key) of the artifact being watched. */
473
476
  id: string;
474
477
  /**
@@ -482,7 +485,7 @@ interface ArtifactObserver<TArtifact> {
482
485
  * immediately. Defaults to `false`
483
486
  * @returns The resolved artifact, including its instance and status.
484
487
  */
485
- get(resolve?: boolean): ResolvedArtifact<TArtifact>;
488
+ get(resolve?: boolean): KeyedResolvedArtifact<TRegistry, K>;
486
489
  /**
487
490
  * Subscribes a callback function to be invoked whenever the artifact's
488
491
  * state (instance, error, or readiness) changes.
@@ -491,7 +494,7 @@ interface ArtifactObserver<TArtifact> {
491
494
  * callback after subscription. Defaults to `true`
492
495
  * @returns A function to unsubscribe the callback and stop receiving updates.
493
496
  */
494
- subscribe(callback: (artifact: ResolvedArtifact<TArtifact>) => void, eager?: boolean): () => void;
497
+ subscribe(callback: (artifact: KeyedResolvedArtifact<TRegistry, K>) => void, eager?: boolean): () => void;
495
498
  /**
496
499
  * Resolves another artifact from the container and registers a dependency on it.
497
500
  * If the dependency changes, the current artifact will be invalidated and rebuilt.
@@ -499,7 +502,7 @@ interface ArtifactObserver<TArtifact> {
499
502
  * or an external error.
500
503
  * @throws {SystemError} if resolution fails.
501
504
  */
502
- resolve(): Promise<ResolvedArtifact<TArtifact>>;
505
+ resolve(): Promise<KeyedResolvedArtifact<TRegistry, K>>;
503
506
  }
504
507
  /**
505
508
  * Configuration options for defining an artifact. These options control
@@ -604,7 +607,7 @@ type InferRegistry<T extends Record<string, {
604
607
  * - ArtifactCache: Stores resolved singleton instances
605
608
  * - ArtifactDependencyGraph: Tracks artifact dependencies using DependencyGraph
606
609
  * - ArtifactManager: Handles lifecycle (build, invalidate, dispose)
607
- * - ArtifactObserver: Manages watchers and subscriptions
610
+ * - ArtifactObserverManager: Manages watchers and subscriptions
608
611
  *
609
612
  * @template TRegistry A type that maps artifact keys to their types
610
613
  * @template TState The type of the global state object
@@ -644,8 +647,8 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
644
647
  */
645
648
  register<K extends keyof TRegistry>(params: ArtifactTemplate<TState, TRegistry[K], TRegistry>): () => void;
646
649
  /**
647
- * Returns a boolean indicating whether a template exists for an artifact
648
- * @template K The key of the artifact to unregister.
650
+ * Returns a boolean indicating whether a template exists for an artifact.
651
+ *
649
652
  * @param key The unique identifier of the artifact.
650
653
  * @returns boolean.
651
654
  */
@@ -654,45 +657,49 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
654
657
  * Unregisters an artifact from the container, disposing of its current instance
655
658
  * and removing all associated resources and dependency links.
656
659
  *
660
+ * Also evicts the observer watcher cache entry so singleton watchers do not
661
+ * outlive the artifact's registration.
662
+ *
657
663
  * @param key The unique identifier of the artifact
658
664
  */
659
665
  unregister<K extends keyof TRegistry>(key: K): Promise<void>;
660
666
  /**
661
667
  * Resolves an artifact by its key, returning its instance or an error.
662
- * This method handles dependency resolution, cycle detection (via graph),
663
- * caching, and retry logic. Traverses the container hierarchy if the artifact
664
- * is not found locally.
668
+ * Handles dependency resolution, cycle detection, caching, and retry logic.
669
+ *
670
+ * The keyed index property (`artifact[key]`) is set inside `cache.package()`
671
+ * so it is always consistent with `artifact.instance`. No post-hoc mutation
672
+ * is needed here.
665
673
  *
666
674
  * @param key The unique identifier for the artifact
667
675
  * @returns A Promise that resolves to a ResolvedArtifact
668
676
  * @throws {ArtifactNotFoundError} if the artifact is not found
669
- * @throws {ArtifactError} if a cycle is detected or other system errors occur
670
677
  */
671
- resolve<K extends keyof TRegistry>(key: K): Promise<ResolvedArtifact<TRegistry[K]>>;
678
+ resolve<K extends keyof TRegistry>(key: K): Promise<KeyedResolvedArtifact<TRegistry, K>>;
672
679
  /**
673
680
  * Resolves an artifact by its key, returning its instance directly.
674
- * This is a wrapper around resolve to prevent defensive programming
681
+ * Throws if resolution fails.
675
682
  *
676
683
  * @param key The unique identifier for the artifact
677
- * @returns A Promise that resolves to a ResolvedArtifact
684
+ * @returns A Promise that resolves to the artifact instance
678
685
  * @throws {ArtifactNotFoundError} if the artifact is not found
679
- * @throws {ArtifactError} if a cycle is detected or other system errors occur
686
+ * @throws the artifact's error if resolution failed
680
687
  */
681
688
  require<K extends keyof TRegistry>(key: K): Promise<TRegistry[K]>;
682
689
  /**
683
- * Returns an ArtifactWatcher for a given artifact key.
684
- * The watcher allows subscribing to changes in the artifact's resolved value.
690
+ * Returns an ArtifactObserver for a given artifact key.
691
+ * The observer allows subscribing to changes in the artifact's resolved value.
685
692
  *
686
693
  * @param key The unique identifier for the artifact
687
- * @returns An ArtifactWatcher instance
694
+ * @returns An ArtifactObserver instance
688
695
  */
689
- watch<K extends keyof TRegistry>(key: K): ArtifactObserver<TRegistry[K]>;
696
+ watch<K extends keyof TRegistry>(key: K): ArtifactObserver<TRegistry, K>;
690
697
  /**
691
- * Peeks at the resolved instance of an artifact without triggering its resolution
692
- * if it's lazy, or registering a dependency.
698
+ * Peeks at the resolved instance of an artifact without triggering resolution
699
+ * or registering a dependency.
693
700
  *
694
701
  * @param key The unique identifier for the artifact
695
- * @returns The artifact instance if it's already built, otherwise undefined
702
+ * @returns The artifact instance if already built, otherwise undefined
696
703
  */
697
704
  peek<K extends keyof TRegistry>(key: K): TRegistry[K] | undefined;
698
705
  /**
@@ -718,16 +725,13 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
718
725
  */
719
726
  hasWatchers(key: string): boolean;
720
727
  /**
721
- * Disposes of the entire ArtifactContainer and all artifacts registered within it.
722
- * This releases all resources, stops all watchers, and clears all internal state.
723
- * After disposal, the container should no longer be used.
728
+ * Disposes of the entire container and all artifacts registered within it.
729
+ * Releases all resources, stops all watchers, and clears all internal state.
724
730
  *
725
731
  * Returns a Promise that resolves once all artifact teardowns have settled.
726
- * Previously this was synchronous (fire-and-forget), which meant the container
727
- * could be garbage-collected before async cleanup completed. Callers should
728
- * await this method to guarantee full resource release.
732
+ * Callers should await this method to guarantee full resource release.
729
733
  */
730
734
  dispose(): Promise<void>;
731
735
  }
732
736
 
733
- 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 PendingArtifact, type ReadyArtifact, type ResolvedArtifact, type ResolvedArtifactBase, type UseDependencyContext };
737
+ 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,...a}=i,o={key:e,factory:t,scope:i.scope??"singleton",lazy:void 0===r||r,...a};return this.artifacts.set(e,o),()=>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()}},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}},l=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)}))])}},d=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()}},u=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];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)}}var f=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}}),w=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(s&&null!==s.buildOnce&&s.buildOnce.done())return this.cache.package(e,((t,r)=>this.invalidate(e,t,r)));const n=this.registry.get(e),a=r?new Set(r):new Set;if(a.has(e))throw new t(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${Array.from(a).join(" -> ")}`,"system");a.add(e);let o=s;if(o||(o=this.createCachedArtifact(n),this.cache.set(e,o)),"transient"===n.scope)return this.executeBuild(n,o,a);try{await o.buildOnce.do((()=>this.executeBuild(n,o,a)))}catch(t){if(t instanceof i)return this.build(e,r);throw t}return o.stream&&o.streamOnce.do(o.stream),this.cache.package(e,((t,r)=>this.invalidate(e,t,r)))}async executeBuild(e,r,s){const n=r.controller.signal,a=e.key,o=String(a),c="transient"===e.scope;r.buildCount++,r.activeDebounceMs=e.debounce??0;const h=[],l=[];let d=null,g=null,f=null;const w=this.graph,y=this.cache,m=this;async function v(e){if(e===a)throw new t(`Artifact "${o}" depends on itself.`,"system");const r=w.wouldCreateCycle(a,e,s);if(r)throw new t(`Adding dependency "${String(e)}" to "${o}" would create a cycle: ${r.join(" -> ")}`,"system");null===g&&(g=new Set),null===f&&(f=new Map),g.add(e);const i=await m.build(e,s),n=y.get(e);return n&&f.set(e,n.version),i}const b={state:()=>m.store.get(!0),previous:r.instance,get signal(){return r.controller.signal},onCleanup:e=>h.push(e),onDispose:e=>l.push(e),use:async e=>e({resolve:v,require:async e=>{const t=await v(e);if(t.error)throw t.error;return t.instance},select:e=>{const t=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/math/string operations inside a selector.");if(u.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/methods.")}});return s.set(e,n),n};try{e(i())}catch(e){throw new Error(`Selector failed during path analysis. This usually means the selector is too complex. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(r)}(e);return null===d&&(d=new Set),t.forEach((e=>d.add(e))),e(m.store.get(!0))}}),stream:e=>{if(c)throw new t(`[ArtifactManager] Illegal stream on transient artifact "${o}"`,"system");const s=async(e,t=void 0)=>{await r.streamSerializer.do((async()=>{void 0!==r.stream&&(r.instance=e,r.error=t,r.version++,this.cache.invalidatePackage(a),await this.processStream(a))}))},i={value:()=>r.instance,get signal(){return r.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>s(e)};r.stream=async()=>{try{const t=await e(i);t&&r.cleanupFunctions.push(t)}catch(e){await s(void 0,e),await this.invalidate(a,!1,!0)}}}};let S,_,k=0;const A=(e.retries??0)+1;for(;k<A;)try{if(r.controller.signal.aborted)throw new i;const s=e.factory(b);if(s instanceof Promise)if(e.timeout){let t;const r=new Promise(((r,s)=>{t=setTimeout((()=>s(new Error(`Timeout: ${e.timeout}ms`))),e.timeout)}));try{S=await Promise.race([s,r])}finally{clearTimeout(t)}}else S=await s;else S=s;if(r.controller.signal.aborted)throw new i;const n=f?this.detectStaleness(f):null;if(!n){_=void 0;break}if(k++,f?.clear(),k<A)continue;_=new t(`Build stale after all retries: dependency "${String(n)}" changed during build.`,"system")}catch(e){if(n.aborted||e instanceof i)throw new i;if(e instanceof t)throw e;k++,k>=A&&(_=e)}if(c||(this.updateDependencyGraph(a,g??new Set,d??new Set),r.cleanupFunctions=h,r.disposeFunctions=l),_?(r.error=_,r.instance=void 0):(r.instance=S,r.error=void 0),r.version++,this.cache.invalidatePackage(a),c)return{instance:S,cleanup:p(h,String(a)),error:_,ready:!0,invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${String(a)}"`)}}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 s.debounceTimer&&(clearTimeout(s.debounceTimer),s.debounceTimer=void 0),!t&&s.activeDebounceMs>0?new Promise(((i,n)=>{s.debounceTimer=setTimeout((()=>{s.debounceTimer=void 0,this.executeInvalidation(e,t,r).then(i).catch(n)}),s.activeDebounceMs)})):this.executeInvalidation(e,t,r)}async executeInvalidation(e,t,r=!1){const s=this.cache.get(e);s&&await s.invalidationSerializer.do((async()=>{s.version++,await this.cache.invalidateInstance(e);const n=this.graph.iterDependents(e);await Promise.all(Array.from(n).map((e=>this.invalidate(e).catch((t=>{console.error(`[ArtifactManager] Cascade failed for "${String(e)}":`,t)})))));const a=this.registry.get(e);!a||!t&&a.lazy&&!this.hasWatchers(e)||r||await this.build(e).catch((t=>{t instanceof i||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),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){try{const t=this.graph.iterDependents(e);await Promise.all(Array.from(t).map((e=>this.invalidate(e).catch((t=>{console.error(`[ArtifactManager] Failed to invalidate dependent "${String(e)}":`,t)}))))),this.observer.notify(e)}catch(t){console.error(`[ArtifactManager] Stream propagation error "${e}":`,t)}}updateDependencyGraph(e,t,r){const s=this.cache.get(e);s&&(this.graph.hasNode(e)||this.graph.registerNode(e),this.graph.setDependencies(e,t),s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.stateDependencies=r,r.size>0&&(s.stateUnsubscribe=this.store.watch(Array.from(r),(async()=>{await this.invalidate(e)}))))}createCachedArtifact(e){const t="transient"===e.scope,r={instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce??0,controller:new AbortController};return t?{...r,buildOnce:null,streamOnce:null,streamSerializer:null,invalidationSerializer:null}:{...r,buildOnce:new l({retry:!0,throws:!0}),streamOnce:new l({retry:!0,throws:!0}),streamSerializer:new d({yieldMode:"microtask"}),invalidationSerializer:new d({yieldMode:"macrotask"})}}hasWatchers(e){return this.observer.hasWatchers(e)??!1}},y=class{dependencies=new Map;dependents=new Map;metadata=new Map;registerNode(e,t){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set),void 0!==t&&this.metadata.set(e,t)}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),this.metadata.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)??m}iterDependencies(e){return this.dependencies.get(e)??m}getMetadata(e){return this.metadata.get(e)}setMetadata(e,t){this.registerNode(e),this.metadata.set(e,t)}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(),this.metadata.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const r=Array.from(t).join(", ");return`${String(e)} → [${r||"∅"}]`})).join("\n")}},m=new Set,v=class{graph;constructor(){this.graph=new y}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){const t=this.graph.getDependents(e);return Array.from(t)}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){const t=this.graph.getDependencies(e);return Array.from(t)}getTransitiveDependents(e){const t=this.graph.getTransitiveDependents(e,!1);return new Set(Array.from(t))}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()}},b=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=String(e);let i=null;const n={instance:r.instance,error:r.error,ready:r.buildOnce?.done(),get cleanup(){return null===i&&(i=p(r.cleanupFunctions,s)??void 0),i},invalidate:t};return r.package=n,n}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;r.stateUnsubscribe&&(r.stateUnsubscribe(),r.stateUnsubscribe=void 0),r.debounceTimer&&(clearTimeout(r.debounceTimer),r.debounceTimer=void 0);const s=null===r.buildOnce;s||(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 d,r.controller=new AbortController)),await g(r.cleanupFunctions,String(e)),await g(r.disposeFunctions,String(e)),r.cleanupFunctions=[],r.disposeFunctions=[],s||(r.buildOnce=new l({retry:!0,throws:!0})),r.instance=void 0,r.error=void 0}},S=class{constructor(e,t,r){this.registry=e,this.cache=t,this.container=r}listeners=new Map;watcherCache=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?`${t}__watched`:t,i="transient"===r.scope;if(this.watcherCache.has(s))return this.watcherCache.get(s).watcher;const n={count:0,init:new l({retry:!1,throws:!0}),watcher:null},a=()=>n.init.do((async()=>{i&&!this.registry.has(s)&&this.registry.register({key:s,factory:r.factory,scope:"singleton",lazy:r.lazy,timeout:r.timeout,retries:r.retries,debounce:r.debounce})}));return n.watcher={id:t,get count(){return n.count},get:(e=!1)=>0!==n.count||e?this.cache.package(s,(e=>this.container.invalidate(s,e))):f,resolve:()=>(n.resolve||(n.resolve=a().then((()=>this.container.resolve(s))).finally((()=>{n.resolve=void 0}))),n.resolve),subscribe:(e,t=!0)=>{const r=a();n.count++,this.listeners.has(s)||this.listeners.set(s,new Set);const o=()=>e(n.watcher.get());return r.then((()=>this.container.resolve(s))).then((()=>{t&&o(),this.listeners.get(s)?.add(o)})).catch((e=>{console.error(`[ArtifactObserver] Background resolution failed for "${s}":`,e),this.listeners.get(s)?.add(o)})),()=>{this.listeners.get(s)?.delete(o),n.count--,0===n.count&&(this.listeners.delete(s),i&&(this.registry.unregister(s).catch((e=>{console.error(`[ArtifactObserver] Cleanup failed for "${s}":`,e)})),this.cache.delete(s),this.watcherCache.delete(s)),n.init.reset())}}},this.watcherCache.set(s,n),n.watcher}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.watcherCache.has(e)||this.watcherCache.has(`${e}__watched`)}getWatcherCount(e){const t=this.watcherCache.get(e)||this.watcherCache.get(`${e}__watched`);return t?.count??0}clear(){this.watcherCache.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 b,this.graph=new v,this.observer=new S(this.registry,this.cache,this),this.manager=new w(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&&(void 0!==s.debounceTimer?i="debouncing":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:s?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)}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){const t=this.cache.get(e);if(void 0!==t?.instance)return t?.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(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=class e extends Error{constructor(t,r){super(t,{cause:r}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},a=class extends o{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},c=class extends o{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 a("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 a(r))),t)}))])}},l=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()}},u=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];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 f(e){return`${e}__watched`}var w=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function y(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,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:p(o.cleanupFunctions,i),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${i}"`)}}}buildContext(e,r,s,i,n){const o=e.key,a="transient"===r.scope,{cleanupFunctions:c,disposeFunctions:h,capturedStateDeps:d,capturedArtifactDeps:l,dependencyVersions:p}=n,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},f="singleton"===r.scope?r.controller.signal:m,w=async e=>{const t=await g(e);if(t.error)throw t.error;return t.instance},y=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(u.includes(n))throw new Error(`Array method .${n}() is not allowed in selectors.`);const o=e?`${e}${t}${n}`:n;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,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=>d.add(e))),e(this.store.get(!0)));return{state:()=>this.store.get(!0),previous:r.instance,signal:f,onCleanup:e=>c.push(e),onDispose:e=>h.push(e),use:e=>e({resolve:g,require:w,select:y}),stream:e=>{if(a)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))}))},c={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(c);t&&s.cleanupFunctions.push(t)}catch(e){await n(void 0,e),await this.invalidate(o,!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 y(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??0,controller:new AbortController,buildOnce:new d({retry:!0,throws:!0}),streamOnce:new d({retry:!0,throws:!0}),streamSerializer:new l({yieldMode:"microtask"}),invalidationSerializer:new l({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 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")}},k=new Set,_=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()}},S=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=p(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 d({retry:!0,throws:!0}),t||(r.streamSerializer=new l,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;watcherCache=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?f(t):t;if(this.watcherCache.has(i))return this.watcherCache.get(i).watcher;const n={count:0,init:new d({retry:!1,throws:!0}),watcher:null,pendingReset:!1},o=async()=>{s&&!this.registry.has(i)&&this.registry.register({key:i,factory:r.factory,scope:"singleton",lazy:r.lazy,timeout:r.timeout,retries:r.retries,debounce:r.debounce})},a=()=>n.init.do(o);return n.watcher={id:t,get count(){return n.count},get:(e=!1)=>0!==n.count||e?this.cache.package(i,(e=>this.container.invalidate(i,e))):w,resolve:()=>(n.resolve||(n.resolve=a().then((()=>this.container.resolve(i))).finally((()=>{n.resolve=void 0}))),n.resolve),subscribe:(e,t=!0)=>{const r=a();n.pendingReset=!1,n.count++,this.listeners.has(i)||this.listeners.set(i,new Set);const o=()=>e(n.watcher.get());return r.then((()=>this.container.resolve(i))).then((()=>{t&&o(),this.listeners.get(i)?.add(o)})).catch((e=>{console.error(`[ArtifactObserver] Background resolution failed for "${i}":`,e),this.listeners.get(i)?.add(o)})),()=>{if(this.listeners.get(i)?.delete(o),n.count--,0===n.count){if(this.listeners.delete(i),s)return this.registry.unregister(i).catch((e=>{console.error(`[ArtifactObserver] Cleanup failed for "${i}":`,e)})),this.cache.delete(i),void this.watcherCache.delete(i);n.pendingReset=!0,queueMicrotask((()=>{n.pendingReset&&(n.pendingReset=!1,this.cache.invalidatePackage(i),n.init.running()||n.init.reset())}))}}}},this.watcherCache.set(i,n),n.watcher}evictWatcher(e){this.watcherCache.has(e)&&(this.watcherCache.delete(e),this.listeners.delete(e));const t=f(e);this.watcherCache.has(t)&&(this.watcherCache.delete(t),this.listeners.delete(t))}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.watcherCache.has(e)||this.watcherCache.has(f(e))}getWatcherCount(e){const t=this.watcherCache.get(e)||this.watcherCache.get(f(e));return t?.count??0}clear(){this.watcherCache.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 S,this.graph=new _,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=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;
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,...a}=i,o={key:e,factory:t,scope:i.scope??"singleton",lazy:void 0===r||r,...a};return this.artifacts.set(e,o),()=>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()}},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}},l=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)}))])}},d=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()}},u=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];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)}}var f=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}}),w=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(s&&null!==s.buildOnce&&s.buildOnce.done())return this.cache.package(e,((t,r)=>this.invalidate(e,t,r)));const n=this.registry.get(e),a=r?new Set(r):new Set;if(a.has(e))throw new t(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${Array.from(a).join(" -> ")}`,"system");a.add(e);let o=s;if(o||(o=this.createCachedArtifact(n),this.cache.set(e,o)),"transient"===n.scope)return this.executeBuild(n,o,a);try{await o.buildOnce.do((()=>this.executeBuild(n,o,a)))}catch(t){if(t instanceof i)return this.build(e,r);throw t}return o.stream&&o.streamOnce.do(o.stream),this.cache.package(e,((t,r)=>this.invalidate(e,t,r)))}async executeBuild(e,r,s){const n=r.controller.signal,a=e.key,o=String(a),c="transient"===e.scope;r.buildCount++,r.activeDebounceMs=e.debounce??0;const h=[],l=[];let d=null,g=null,f=null;const w=this.graph,y=this.cache,m=this;async function v(e){if(e===a)throw new t(`Artifact "${o}" depends on itself.`,"system");const r=w.wouldCreateCycle(a,e,s);if(r)throw new t(`Adding dependency "${String(e)}" to "${o}" would create a cycle: ${r.join(" -> ")}`,"system");null===g&&(g=new Set),null===f&&(f=new Map),g.add(e);const i=await m.build(e,s),n=y.get(e);return n&&f.set(e,n.version),i}const b={state:()=>m.store.get(!0),previous:r.instance,get signal(){return r.controller.signal},onCleanup:e=>h.push(e),onDispose:e=>l.push(e),use:async e=>e({resolve:v,require:async e=>{const t=await v(e);if(t.error)throw t.error;return t.instance},select:e=>{const t=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/math/string operations inside a selector.");if(u.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/methods.")}});return s.set(e,n),n};try{e(i())}catch(e){throw new Error(`Selector failed during path analysis. This usually means the selector is too complex. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(r)}(e);return null===d&&(d=new Set),t.forEach((e=>d.add(e))),e(m.store.get(!0))}}),stream:e=>{if(c)throw new t(`[ArtifactManager] Illegal stream on transient artifact "${o}"`,"system");const s=async(e,t=void 0)=>{await r.streamSerializer.do((async()=>{void 0!==r.stream&&(r.instance=e,r.error=t,r.version++,this.cache.invalidatePackage(a),await this.processStream(a))}))},i={value:()=>r.instance,get signal(){return r.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>s(e)};r.stream=async()=>{try{const t=await e(i);t&&r.cleanupFunctions.push(t)}catch(e){await s(void 0,e),await this.invalidate(a,!1,!0)}}}};let S,_,k=0;const A=(e.retries??0)+1;for(;k<A;)try{if(r.controller.signal.aborted)throw new i;const s=e.factory(b);if(s instanceof Promise)if(e.timeout){let t;const r=new Promise(((r,s)=>{t=setTimeout((()=>s(new Error(`Timeout: ${e.timeout}ms`))),e.timeout)}));try{S=await Promise.race([s,r])}finally{clearTimeout(t)}}else S=await s;else S=s;if(r.controller.signal.aborted)throw new i;const n=f?this.detectStaleness(f):null;if(!n){_=void 0;break}if(k++,f?.clear(),k<A)continue;_=new t(`Build stale after all retries: dependency "${String(n)}" changed during build.`,"system")}catch(e){if(n.aborted||e instanceof i)throw new i;if(e instanceof t)throw e;k++,k>=A&&(_=e)}if(c||(this.updateDependencyGraph(a,g??new Set,d??new Set),r.cleanupFunctions=h,r.disposeFunctions=l),_?(r.error=_,r.instance=void 0):(r.instance=S,r.error=void 0),r.version++,this.cache.invalidatePackage(a),c)return{instance:S,cleanup:p(h,String(a)),error:_,ready:!0,invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${String(a)}"`)}}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 s.debounceTimer&&(clearTimeout(s.debounceTimer),s.debounceTimer=void 0),!t&&s.activeDebounceMs>0?new Promise(((i,n)=>{s.debounceTimer=setTimeout((()=>{s.debounceTimer=void 0,this.executeInvalidation(e,t,r).then(i).catch(n)}),s.activeDebounceMs)})):this.executeInvalidation(e,t,r)}async executeInvalidation(e,t,r=!1){const s=this.cache.get(e);s&&await s.invalidationSerializer.do((async()=>{s.version++,await this.cache.invalidateInstance(e);const n=this.graph.iterDependents(e);await Promise.all(Array.from(n).map((e=>this.invalidate(e).catch((t=>{console.error(`[ArtifactManager] Cascade failed for "${String(e)}":`,t)})))));const a=this.registry.get(e);!a||!t&&a.lazy&&!this.hasWatchers(e)||r||await this.build(e).catch((t=>{t instanceof i||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),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){try{const t=this.graph.iterDependents(e);await Promise.all(Array.from(t).map((e=>this.invalidate(e).catch((t=>{console.error(`[ArtifactManager] Failed to invalidate dependent "${String(e)}":`,t)}))))),this.observer.notify(e)}catch(t){console.error(`[ArtifactManager] Stream propagation error "${e}":`,t)}}updateDependencyGraph(e,t,r){const s=this.cache.get(e);s&&(this.graph.hasNode(e)||this.graph.registerNode(e),this.graph.setDependencies(e,t),s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.stateDependencies=r,r.size>0&&(s.stateUnsubscribe=this.store.watch(Array.from(r),(async()=>{await this.invalidate(e)}))))}createCachedArtifact(e){const t="transient"===e.scope,r={instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce??0,controller:new AbortController};return t?{...r,buildOnce:null,streamOnce:null,streamSerializer:null,invalidationSerializer:null}:{...r,buildOnce:new l({retry:!0,throws:!0}),streamOnce:new l({retry:!0,throws:!0}),streamSerializer:new d({yieldMode:"microtask"}),invalidationSerializer:new d({yieldMode:"macrotask"})}}hasWatchers(e){return this.observer.hasWatchers(e)??!1}},y=class{dependencies=new Map;dependents=new Map;metadata=new Map;registerNode(e,t){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set),void 0!==t&&this.metadata.set(e,t)}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),this.metadata.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)??m}iterDependencies(e){return this.dependencies.get(e)??m}getMetadata(e){return this.metadata.get(e)}setMetadata(e,t){this.registerNode(e),this.metadata.set(e,t)}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(),this.metadata.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const r=Array.from(t).join(", ");return`${String(e)} → [${r||"∅"}]`})).join("\n")}},m=new Set,v=class{graph;constructor(){this.graph=new y}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){const t=this.graph.getDependents(e);return Array.from(t)}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){const t=this.graph.getDependencies(e);return Array.from(t)}getTransitiveDependents(e){const t=this.graph.getTransitiveDependents(e,!1);return new Set(Array.from(t))}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()}},b=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=String(e);let i=null;const n={instance:r.instance,error:r.error,ready:r.buildOnce?.done(),get cleanup(){return null===i&&(i=p(r.cleanupFunctions,s)??void 0),i},invalidate:t};return r.package=n,n}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;r.stateUnsubscribe&&(r.stateUnsubscribe(),r.stateUnsubscribe=void 0),r.debounceTimer&&(clearTimeout(r.debounceTimer),r.debounceTimer=void 0);const s=null===r.buildOnce;s||(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 d,r.controller=new AbortController)),await g(r.cleanupFunctions,String(e)),await g(r.disposeFunctions,String(e)),r.cleanupFunctions=[],r.disposeFunctions=[],s||(r.buildOnce=new l({retry:!0,throws:!0})),r.instance=void 0,r.error=void 0}},S=class{constructor(e,t,r){this.registry=e,this.cache=t,this.container=r}listeners=new Map;watcherCache=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?`${t}__watched`:t,i="transient"===r.scope;if(this.watcherCache.has(s))return this.watcherCache.get(s).watcher;const n={count:0,init:new l({retry:!1,throws:!0}),watcher:null},a=()=>n.init.do((async()=>{i&&!this.registry.has(s)&&this.registry.register({key:s,factory:r.factory,scope:"singleton",lazy:r.lazy,timeout:r.timeout,retries:r.retries,debounce:r.debounce})}));return n.watcher={id:t,get count(){return n.count},get:(e=!1)=>0!==n.count||e?this.cache.package(s,(e=>this.container.invalidate(s,e))):f,resolve:()=>(n.resolve||(n.resolve=a().then((()=>this.container.resolve(s))).finally((()=>{n.resolve=void 0}))),n.resolve),subscribe:(e,t=!0)=>{const r=a();n.count++,this.listeners.has(s)||this.listeners.set(s,new Set);const o=()=>e(n.watcher.get());return r.then((()=>this.container.resolve(s))).then((()=>{t&&o(),this.listeners.get(s)?.add(o)})).catch((e=>{console.error(`[ArtifactObserver] Background resolution failed for "${s}":`,e),this.listeners.get(s)?.add(o)})),()=>{this.listeners.get(s)?.delete(o),n.count--,0===n.count&&(this.listeners.delete(s),i&&(this.registry.unregister(s).catch((e=>{console.error(`[ArtifactObserver] Cleanup failed for "${s}":`,e)})),this.cache.delete(s),this.watcherCache.delete(s)),n.init.reset())}}},this.watcherCache.set(s,n),n.watcher}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.watcherCache.has(e)||this.watcherCache.has(`${e}__watched`)}getWatcherCount(e){const t=this.watcherCache.get(e)||this.watcherCache.get(`${e}__watched`);return t?.count??0}clear(){this.watcherCache.clear(),this.listeners.clear()}},_=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 b,this.graph=new v,this.observer=new S(this.registry,this.cache,this),this.manager=new w(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&&(void 0!==s.debounceTimer?i="debouncing":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:s?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)}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){const t=this.cache.get(e);if(void 0!==t?.instance)return t?.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{_ 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(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=class e extends Error{constructor(t,r){super(t,{cause:r}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},a=class extends o{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},c=class extends o{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 a("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 a(r))),t)}))])}},l=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()}},u=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];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 f(e){return`${e}__watched`}var w=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function y(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,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:p(o.cleanupFunctions,i),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${i}"`)}}}buildContext(e,r,s,i,n){const o=e.key,a="transient"===r.scope,{cleanupFunctions:c,disposeFunctions:h,capturedStateDeps:d,capturedArtifactDeps:l,dependencyVersions:p}=n,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},f="singleton"===r.scope?r.controller.signal:m,w=async e=>{const t=await g(e);if(t.error)throw t.error;return t.instance},y=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(u.includes(n))throw new Error(`Array method .${n}() is not allowed in selectors.`);const o=e?`${e}${t}${n}`:n;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,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=>d.add(e))),e(this.store.get(!0)));return{state:()=>this.store.get(!0),previous:r.instance,signal:f,onCleanup:e=>c.push(e),onDispose:e=>h.push(e),use:e=>e({resolve:g,require:w,select:y}),stream:e=>{if(a)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))}))},c={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(c);t&&s.cleanupFunctions.push(t)}catch(e){await n(void 0,e),await this.invalidate(o,!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 y(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??0,controller:new AbortController,buildOnce:new d({retry:!0,throws:!0}),streamOnce:new d({retry:!0,throws:!0}),streamSerializer:new l({yieldMode:"microtask"}),invalidationSerializer:new l({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 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")}},k=new Set,_=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()}},S=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=p(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 d({retry:!0,throws:!0}),t||(r.streamSerializer=new l,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;watcherCache=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?f(t):t;if(this.watcherCache.has(i))return this.watcherCache.get(i).watcher;const n={count:0,init:new d({retry:!1,throws:!0}),watcher:null,pendingReset:!1},o=async()=>{s&&!this.registry.has(i)&&this.registry.register({key:i,factory:r.factory,scope:"singleton",lazy:r.lazy,timeout:r.timeout,retries:r.retries,debounce:r.debounce})},a=()=>n.init.do(o);return n.watcher={id:t,get count(){return n.count},get:(e=!1)=>0!==n.count||e?this.cache.package(i,(e=>this.container.invalidate(i,e))):w,resolve:()=>(n.resolve||(n.resolve=a().then((()=>this.container.resolve(i))).finally((()=>{n.resolve=void 0}))),n.resolve),subscribe:(e,t=!0)=>{const r=a();n.pendingReset=!1,n.count++,this.listeners.has(i)||this.listeners.set(i,new Set);const o=()=>e(n.watcher.get());return r.then((()=>this.container.resolve(i))).then((()=>{t&&o(),this.listeners.get(i)?.add(o)})).catch((e=>{console.error(`[ArtifactObserver] Background resolution failed for "${i}":`,e),this.listeners.get(i)?.add(o)})),()=>{if(this.listeners.get(i)?.delete(o),n.count--,0===n.count){if(this.listeners.delete(i),s)return this.registry.unregister(i).catch((e=>{console.error(`[ArtifactObserver] Cleanup failed for "${i}":`,e)})),this.cache.delete(i),void this.watcherCache.delete(i);n.pendingReset=!0,queueMicrotask((()=>{n.pendingReset&&(n.pendingReset=!1,this.cache.invalidatePackage(i),n.init.running()||n.init.reset())}))}}}},this.watcherCache.set(i,n),n.watcher}evictWatcher(e){this.watcherCache.has(e)&&(this.watcherCache.delete(e),this.listeners.delete(e));const t=f(e);this.watcherCache.has(t)&&(this.watcherCache.delete(t),this.listeners.delete(t))}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.watcherCache.has(e)||this.watcherCache.has(f(e))}getWatcherCount(e){const t=this.watcherCache.get(e)||this.watcherCache.get(f(e));return t?.count??0}clear(){this.watcherCache.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 S,this.graph=new _,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=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};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asaidimu/utils-artifacts",
3
- "version": "7.2.0",
3
+ "version": "8.0.0",
4
4
  "description": "Reactive artifact container.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",