@asaidimu/utils-artifacts 5.0.1 → 6.0.1

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
@@ -603,6 +603,15 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
603
603
  constructor(store: Pick<DataStore<TState>, "watch" | "get" | "set">);
604
604
  /**
605
605
  * Provides debug information about all artifacts currently registered in this container.
606
+ *
607
+ * Status mapping:
608
+ * - `"building"` — factory is currently executing (buildOnce.running())
609
+ * - `"debouncing"` — invalidation is pending behind a debounce timer
610
+ * - `"pending"` — buildOnce is in flight but not yet running (queued)
611
+ * - `"error"` — last build attempt failed
612
+ * - `"active"` — successfully built and instance is available
613
+ * - `"idle"` — not yet built (lazy) or has been disposed
614
+ *
606
615
  * @returns An array of ArtifactDebugNode objects
607
616
  */
608
617
  debugInfo(): ArtifactDebugNode[];
@@ -686,8 +695,13 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
686
695
  * Disposes of the entire ArtifactContainer and all artifacts registered within it.
687
696
  * This releases all resources, stops all watchers, and clears all internal state.
688
697
  * After disposal, the container should no longer be used.
698
+ *
699
+ * Returns a Promise that resolves once all artifact teardowns have settled.
700
+ * Previously this was synchronous (fire-and-forget), which meant the container
701
+ * could be garbage-collected before async cleanup completed. Callers should
702
+ * await this method to guarantee full resource release.
689
703
  */
690
- dispose(): void;
704
+ dispose(): Promise<void>;
691
705
  }
692
706
 
693
707
  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 };
package/index.d.ts CHANGED
@@ -603,6 +603,15 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
603
603
  constructor(store: Pick<DataStore<TState>, "watch" | "get" | "set">);
604
604
  /**
605
605
  * Provides debug information about all artifacts currently registered in this container.
606
+ *
607
+ * Status mapping:
608
+ * - `"building"` — factory is currently executing (buildOnce.running())
609
+ * - `"debouncing"` — invalidation is pending behind a debounce timer
610
+ * - `"pending"` — buildOnce is in flight but not yet running (queued)
611
+ * - `"error"` — last build attempt failed
612
+ * - `"active"` — successfully built and instance is available
613
+ * - `"idle"` — not yet built (lazy) or has been disposed
614
+ *
606
615
  * @returns An array of ArtifactDebugNode objects
607
616
  */
608
617
  debugInfo(): ArtifactDebugNode[];
@@ -686,8 +695,13 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
686
695
  * Disposes of the entire ArtifactContainer and all artifacts registered within it.
687
696
  * This releases all resources, stops all watchers, and clears all internal state.
688
697
  * After disposal, the container should no longer be used.
698
+ *
699
+ * Returns a Promise that resolves once all artifact teardowns have settled.
700
+ * Previously this was synchronous (fire-and-forget), which meant the container
701
+ * could be garbage-collected before async cleanup completed. Callers should
702
+ * await this method to guarantee full resource release.
689
703
  */
690
- dispose(): void;
704
+ dispose(): Promise<void>;
691
705
  }
692
706
 
693
707
  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 };
package/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e,t,r=Object.create,s=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.getPrototypeOf,o=Object.prototype.hasOwnProperty,c=(e={"node_modules/@asaidimu/events/index.js"(e,t){var r,s=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.prototype.hasOwnProperty,o={};((e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})})(o,{createEventBus:()=>c}),t.exports=(r=o,((e,t,r,o)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of i(t))a.call(e,c)||c===r||s(e,c,{get:()=>t[c],enumerable:!(o=n(t,c))||o.enumerable});return e})(s({},"__esModule",{value:!0}),r));var c=(e={async:!1,batchSize:1e3,batchDelay:16,errorHandler:e=>console.error("EventBus Error:",e),crossTab:!1,channelName:"event-bus-channel"})=>{const t=new Map;let r=[],s=0,n=0;const i=new Map,a=new Map;let o=null;e.crossTab&&"undefined"!=typeof BroadcastChannel?o=new BroadcastChannel(e.channelName):e.crossTab&&console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");const c=(e,t)=>{s++,n+=t,i.set(e,(i.get(e)||0)+1)},h=()=>{const t=r;r=[],t.forEach((({name:t,payload:r})=>{const s=performance.now();try{(a.get(t)||[]).forEach((e=>e(r)))}catch(s){e.errorHandler({...s,eventName:t,payload:r})}c(t,performance.now()-s)}))},d=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(h,e.batchDelay)}})(),l=e=>{const r=t.get(e);r?a.set(e,Array.from(r)):a.delete(e)};return o&&(o.onmessage=e=>{const{name:t,payload:r}=e.data;(a.get(t)||[]).forEach((e=>e(r)))}),{subscribe:(e,r)=>{t.has(e)||t.set(e,new Set);const s=t.get(e);return s.add(r),l(e),()=>{s.delete(r),0===s.size?(t.delete(e),a.delete(e)):l(e)}},emit:({name:t,payload:s})=>{if(e.async)return r.push({name:t,payload:s}),r.length>=e.batchSize?h():d(),void(o&&o.postMessage({name:t,payload:s}));const n=performance.now();try{(a.get(t)||[]).forEach((e=>e(s))),o&&o.postMessage({name:t,payload:s})}catch(r){e.errorHandler({...r,eventName:t,payload:s})}c(t,performance.now()-n)},getMetrics:()=>({totalEvents:s,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:i,averageEmitDuration:s>0?n/s:0}),clear:()=>{t.clear(),a.clear(),r=[],s=0,n=0,i.clear(),o&&(o.close(),o=null)}}}}},function(){return t||(0,e[i(e)[0]])((t={exports:{}}).exports,t),t.exports}),h=(e=>(e.Singleton="singleton",e.Transient="transient",e))(h||{}),d=class e extends Error{category;constructor(t,r,s){super(t,{cause:s}),this.name="ArtifactError",this.category=r,Object.setPrototypeOf(this,e.prototype)}},l=class extends d{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system")}},u=class extends d{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`,"system")}},p=class extends d{constructor(e){super(`[ArtifactContainer] An artifact with key:${e} already exists!`,"system")}},g=class extends d{constructor(){super("[Serializer] The serializer has been marked as done!","system")}},f=class{artifacts=new Map;register({key:e,factory:t,lazy:r,...s}){if(this.artifacts.has(e))throw new p(String(e));const{scope:n,...i}=s,a={key:e,factory:t,scope:s.scope??"singleton",lazy:void 0===r||r,...i};return this.artifacts.set(e,a),()=>this.unregister(e)}get(e){if(!this.has(e))throw new l(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()}};((e,t,c)=>{c=null!=e?r(a(e)):{},((e,t,r,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of i(t))o.call(e,c)||c===r||s(e,c,{get:()=>t[c],enumerable:!(a=n(t,c))||a.enumerable})})(e&&e.__esModule?c:s(c,"default",{value:e,enumerable:!0}),e)})(c());var y=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));this.waiters.push(t),null!=e?await Promise.race([r,new Promise(((r,s)=>setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),s(new u("Mutex lock timed out"))}),e)))]):await r}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}},w=class{constructor(e=!1,t=!1){this.retry=e,this.throws=t}mutex=new y({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;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{const t=await e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.promise=null}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}isReady(){return this._done&&null===this.promise}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(){this._done=!1,this.promise=null,this._value=null,this._error=void 0}resolved(){return this.promise}done(){return this._done}_awaitWithTimeout(e,t,r="Operation timed out"){return null==t?e:Promise.race([e,new Promise(((e,s)=>setTimeout((()=>s(new u(r))),t)))])}},m=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;constructor(e){this.mutex=new y({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new g};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let r,s=null;try{if(this._done)throw new g;s=await e(),this._lastValue=s,this._lastError=void 0}catch(e){r=e,this._lastError=e}finally{this.mutex.unlock()}return{value:s,error:r}}peek(){return{value:this._lastValue,error:this._lastError}}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}};function v(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 b(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 S=class extends Error{constructor(){super("Build superseded by invalidation"),this.name="SupersededBuildError"}},_=class{constructor(e,t,r,s,n){this.registry=e,this.cache=t,this.graph=r,this.store=s,this.observer=n}async build(e,t){const r=this.cache.get(e);if(r&&null!==r.buildOnce&&r.buildOnce.isReady())return this.cache.package(e,((t,r)=>this.invalidate(e,t,r)));const s=this.registry.get(e);if(!s)throw new d(`Template not found for artifact "${String(e)}"`,"system");const n=t?new Set(t):new Set;if(n.has(e))throw new d(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${Array.from(n).join(" -> ")}`,"system");n.add(e);let i=r;return i||(i=this.createCachedArtifact(s),this.cache.set(e,i)),"transient"===s.scope?this.executeBuild(s,i,n):(await i.buildOnce.do((()=>this.executeBuild(s,i,n))),i.stream&&i.streamOnce.do(i.stream),this.cache.package(e,((t,r)=>this.invalidate(e,t,r))))}async executeBuild(e,t,r){const s=e.key,n=String(s),i="transient"===e.scope;t.buildCount++,t.activeDebounceMs=e.debounce??0;const a=[],o=[];let c=!0;a.push((()=>{c=!1}));let h=null,l=null,u=null;const p=this.graph,g=this.cache,f=this;async function y(e){if(e===s)throw new d(`Artifact "${n}" depends on itself.`,"system");const t=p.wouldCreateCycle(s,e,r);if(t)throw new d(`Adding dependency "${String(e)}" to "${n}" would create a cycle: ${t.join(" -> ")}`,"system");null===l&&(l=new Set),null===u&&(u=new Map),l.add(e);const i=await f.build(e,r),a=g.get(e);return a&&u.set(e,a.version),i}const w={state:()=>f.store.get(!0),previous:t.instance,onCleanup:e=>a.push(e),onDispose:e=>o.push(e),use:async e=>e({resolve:y,require:async e=>{const t=await y(e);if(t.error)throw t.error;return t.instance},select:e=>{const t=function(e,t="."){const r=new Set,s=(e=[])=>new Proxy({},{get:(n,i)=>{if("symbol"==typeof i)return;const a=[...e,i],o=a.join(t);return r.add(o),s(a)}});try{e(s())}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)}`)}const n=Array.from(r);return n.filter((e=>!n.some((r=>r!==e&&r.startsWith(e+t)))))}(e);return null===h&&(h=new Set),t.forEach((e=>h.add(e))),e(f.store.get(!0))}}),stream:e=>{if(i)throw new d(`[ArtifactManager] Illegal stream on transient artifact "${n}"`,"system");const r=async(e,r=void 0)=>{await t.streamSerializer.do((async()=>{void 0!==t.stream&&(t.instance=e,t.error=r,t.version++,this.cache.invalidatePackage(s),await this.processStream(s))}))},a={value:()=>t.instance,get signal(){return t.streamController.signal},set:(...e)=>this.store.set(...e),emit:e=>r(e)};t.stream=async()=>{try{const r=await e(a);r&&t.cleanupFunctions.push(r)}catch(e){await r(void 0,e),await this.invalidate(s,!1,!0)}}}};let m,_,k=0;const A=(e.retries??0)+1;for(;k<A;)try{const t=e.factory(w);if(e.timeout){const r=new Promise(((t,r)=>setTimeout((()=>r(new Error(`Timeout: ${e.timeout}ms`))),e.timeout)));m=await Promise.race([t,r])}else m=await t;const r=u?this.detectStaleness(u):null;if(!r){_=void 0;break}if(k++,u?.clear(),k<A)continue;_=new d(`Build stale after all retries: dependency "${String(r)}" changed during build.`,"system")}catch(e){if(e instanceof d)throw e;k++,k>=A&&(_=e)}if(!c)throw await b(a,n),new S;if(i||(this.updateDependencyGraph(s,l??new Set,h??new Set),t.cleanupFunctions=a,t.disposeFunctions=o),_?(t.error=_,t.instance=void 0):(t.instance=m,t.error=void 0),t.version++,this.cache.invalidatePackage(s),i)return{instance:m,cleanup:v(a,String(s)),error:_,ready:!0,invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${String(s)}"`)}}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(((n,i)=>{s.debounceTimer=setTimeout((()=>{s.debounceTimer=void 0,this.executeInvalidation(e,t,r).then(n).catch(i)}),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 i=this.registry.get(e);!i||!t&&i.lazy&&!this.hasWatchers(e)||r||await this.build(e).catch((t=>{t instanceof S||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),this.observer.notify(e)}))}async dispose(e){const t=this.cache.get(e);if(!t)return;null===t.buildOnce||(await t.buildOnce.resolved(),await t.invalidationSerializer.do((async()=>{})),await t.streamOnce.resolved()),await this.cache.invalidateInstance(e),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,streamController:new AbortController};return t?{...r,buildOnce:null,streamOnce:null,streamSerializer:null,invalidationSerializer:null}:{...r,buildOnce:new w(!0,!0),streamOnce:new w(!0,!0),streamSerializer:new m({yieldMode:"microtask"}),invalidationSerializer:new m({yieldMode:"macrotask"})}}hasWatchers(e){return this.observer.hasWatchers(e)??!1}},k=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)??A}iterDependencies(e){return this.dependencies.get(e)??A}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]),n=new Map;for(;r.length>0;){const i=r.shift();if(i===e){const r=[];let s=e;for(;void 0!==s&&(r.push(s),s!==t);)s=n.get(s);return r.reverse(),[e,...r]}const a=this.dependencies.get(i);if(a)for(const e of a)s.has(e)||(s.add(e),n.set(e,i),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 n=this.dependents.get(t);if(n)for(const t of n){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,n=new Set,i=[e];n.add(e),r&&s.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;i.length>0;){const e=i.shift(),t=a.get(e);if(t)for(const e of t)n.has(e)||(n.add(e),s.add(e),i.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")}},A=new Set,C=class{graph;constructor(){this.graph=new k}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){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),n=e.slice(s);return n.push(t),n}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()}},O=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 Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});if(r.packagedArtifact)return r.packagedArtifact;const s=String(e);let n=null;const i={instance:r.instance,error:r.error,ready:r.buildOnce?.isReady()??!1,get cleanup(){return null===n&&(n=v(r.cleanupFunctions,s)??void 0),n},invalidate:t};return r.packagedArtifact=i,i}invalidatePackage(e){const t=this.get(e);t&&(t.packagedArtifact=void 0)}async invalidateInstance(e){const t=this.get(e);if(!t)return;t.stateUnsubscribe&&(t.stateUnsubscribe(),t.stateUnsubscribe=void 0),t.debounceTimer&&(clearTimeout(t.debounceTimer),t.debounceTimer=void 0);const r=null===t.buildOnce;r||(t.streamController.abort(),await t.streamOnce.resolved(),t.streamOnce=new w(!0,!0),t.streamSerializer.close(),t.stream=void 0,t.streamSerializer=new m,t.streamController=new AbortController),await b(t.cleanupFunctions,String(e)),await b(t.disposeFunctions,String(e)),t.cleanupFunctions=[],t.disposeFunctions=[],r||t.buildOnce.reset(),t.instance=void 0,t.error=void 0}},D=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;if(this.watcherCache.has(s))return this.watcherCache.get(s).watcher;const n={count:0,init:new w(!1,!0),watcher:null},i=()=>n.init.do((async()=>{"transient"!==r.scope||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:()=>0===n.count?Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}}):this.cache.package(s,(e=>this.container.invalidate(s,e))),resolve:async()=>(await i(),this.container.resolve(s)),subscribe:e=>{0===n.count&&i(),n.count++,this.listeners.has(s)||this.listeners.set(s,new Set);const t=()=>e(n.watcher.get());return this.container.resolve(s).then((()=>{t(),this.listeners.get(s)?.add(t)})).catch((e=>{console.error(`[ArtifactObserver] Background resolution failed for "${s}":`,e),this.listeners.get(s)?.add(t)})),()=>{this.listeners.get(s)?.delete(t),n.count--,0===n.count&&(this.listeners.delete(s),"transient"===r.scope&&(this.registry.unregister(s).catch((e=>{console.error(`[ArtifactObserver] Cleanup failed for "${s}":`,e)})),this.cache.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 f,this.cache=new O,this.graph=new C,this.observer=new D(this.registry,this.cache,this),this.manager=new _(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;const n=s?s.buildOnce.running()?"pending":s.error?"error":void 0!==s.instance?"active":"idle":"idle";e.push({id:t,scope:r.scope??"singleton",status:n,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)}async unregister(e){await this.manager.dispose(e),await this.registry.unregister(e)}async resolve(e){if(!this.registry.has(e))throw new l(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 l(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)}dispose(){this.registry.keys().forEach((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=h;
1
+ "use strict";var e,t,r=Object.create,s=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.getPrototypeOf,o=Object.prototype.hasOwnProperty,c=(e={"node_modules/@asaidimu/events/index.js"(e,t){var r,s=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.prototype.hasOwnProperty,o={};((e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})})(o,{createEventBus:()=>c}),t.exports=(r=o,((e,t,r,o)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of i(t))a.call(e,c)||c===r||s(e,c,{get:()=>t[c],enumerable:!(o=n(t,c))||o.enumerable});return e})(s({},"__esModule",{value:!0}),r));var c=(e={async:!1,batchSize:1e3,batchDelay:16,errorHandler:e=>console.error("EventBus Error:",e),crossTab:!1,channelName:"event-bus-channel"})=>{const t=new Map;let r=[],s=0,n=0;const i=new Map,a=new Map;let o=null;e.crossTab&&"undefined"!=typeof BroadcastChannel?o=new BroadcastChannel(e.channelName):e.crossTab&&console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");const c=(e,t)=>{s++,n+=t,i.set(e,(i.get(e)||0)+1)},h=()=>{const t=r;r=[],t.forEach((({name:t,payload:r})=>{const s=performance.now();try{(a.get(t)||[]).forEach((e=>e(r)))}catch(s){e.errorHandler({...s,eventName:t,payload:r})}c(t,performance.now()-s)}))},d=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(h,e.batchDelay)}})(),l=e=>{const r=t.get(e);r?a.set(e,Array.from(r)):a.delete(e)};return o&&(o.onmessage=e=>{const{name:t,payload:r}=e.data;(a.get(t)||[]).forEach((e=>e(r)))}),{subscribe:(e,r)=>{t.has(e)||t.set(e,new Set);const s=t.get(e);return s.add(r),l(e),()=>{s.delete(r),0===s.size?(t.delete(e),a.delete(e)):l(e)}},emit:({name:t,payload:s})=>{if(e.async)return r.push({name:t,payload:s}),r.length>=e.batchSize?h():d(),void(o&&o.postMessage({name:t,payload:s}));const n=performance.now();try{(a.get(t)||[]).forEach((e=>e(s))),o&&o.postMessage({name:t,payload:s})}catch(r){e.errorHandler({...r,eventName:t,payload:s})}c(t,performance.now()-n)},getMetrics:()=>({totalEvents:s,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:i,averageEmitDuration:s>0?n/s:0}),clear:()=>{t.clear(),a.clear(),r=[],s=0,n=0,i.clear(),o&&(o.close(),o=null)}}}}},function(){return t||(0,e[i(e)[0]])((t={exports:{}}).exports,t),t.exports}),h=(e=>(e.Singleton="singleton",e.Transient="transient",e))(h||{}),d=class e extends Error{category;constructor(t,r,s){super(t,{cause:s}),this.name="ArtifactError",this.category=r,Object.setPrototypeOf(this,e.prototype)}},l=class extends d{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system")}},u=class extends d{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`,"system")}},p=class extends d{constructor(e){super(`[ArtifactContainer] An artifact with key:${e} already exists!`,"system")}},g=class extends d{constructor(){super("[Serializer] The serializer has been marked as done!","system")}},f=class{artifacts=new Map;register({key:e,factory:t,lazy:r,...s}){if(this.artifacts.has(e))throw new p(String(e));const{scope:n,...i}=s,a={key:e,factory:t,scope:s.scope??"singleton",lazy:void 0===r||r,...i};return this.artifacts.set(e,a),()=>this.unregister(e)}get(e){if(!this.has(e))throw new l(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()}};((e,t,c)=>{c=null!=e?r(a(e)):{},((e,t,r,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of i(t))o.call(e,c)||c===r||s(e,c,{get:()=>t[c],enumerable:!(a=n(t,c))||a.enumerable})})(e&&e.__esModule?c:s(c,"default",{value:e,enumerable:!0}),e)})(c());var y=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));this.waiters.push(t),null!=e?await Promise.race([r,new Promise(((r,s)=>setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),s(new u("Mutex lock timed out"))}),e)))]):await r}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}},m=class{constructor(e=!1,t=!1){this.retry=e,this.throws=t}mutex=new y({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;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{const t=await e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.promise=null}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}isReady(){return this._done&&null===this.promise}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(){this._done=!1,this.promise=null,this._value=null,this._error=void 0}resolved(){return this.promise}done(){return this._done}_awaitWithTimeout(e,t,r="Operation timed out"){return null==t?e:Promise.race([e,new Promise(((e,s)=>setTimeout((()=>s(new u(r))),t)))])}},w=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;constructor(e){this.mutex=new y({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new g};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let r,s=null;try{if(this._done)throw new g;s=await e(),this._lastValue=s,this._lastError=void 0}catch(e){r=e,this._lastError=e}finally{this.mutex.unlock()}return{value:s,error:r}}peek(){return{value:this._lastValue,error:this._lastError}}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}};function v(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 b(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 S=class extends Error{constructor(){super("Build superseded by invalidation"),this.name="SupersededBuildError"}},_=class{constructor(e,t,r,s,n){this.registry=e,this.cache=t,this.graph=r,this.store=s,this.observer=n}async build(e,t){const r=this.cache.get(e);if(r&&null!==r.buildOnce&&r.buildOnce.isReady())return this.cache.package(e,((t,r)=>this.invalidate(e,t,r)));const s=this.registry.get(e),n=t?new Set(t):new Set;if(n.has(e))throw new d(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${Array.from(n).join(" -> ")}`,"system");n.add(e);let i=r;return i||(i=this.createCachedArtifact(s),this.cache.set(e,i)),"transient"===s.scope?this.executeBuild(s,i,n):(await i.buildOnce.do((()=>this.executeBuild(s,i,n))),i.stream&&i.streamOnce.do(i.stream),this.cache.package(e,((t,r)=>this.invalidate(e,t,r))))}async executeBuild(e,t,r){const s=e.key,n=String(s),i="transient"===e.scope;t.buildCount++,t.activeDebounceMs=e.debounce??0;const a=[],o=[];let c=!0;a.push((()=>{c=!1}));let h=null,l=null,u=null;const p=this.graph,g=this.cache,f=this;async function y(e){if(e===s)throw new d(`Artifact "${n}" depends on itself.`,"system");const t=p.wouldCreateCycle(s,e,r);if(t)throw new d(`Adding dependency "${String(e)}" to "${n}" would create a cycle: ${t.join(" -> ")}`,"system");null===l&&(l=new Set),null===u&&(u=new Map),l.add(e);const i=await f.build(e,r),a=g.get(e);return a&&u.set(e,a.version),i}const m={state:()=>f.store.get(!0),previous:t.instance,onCleanup:e=>a.push(e),onDispose:e=>o.push(e),use:async e=>e({resolve:y,require:async e=>{const t=await y(e);if(t.error)throw t.error;return t.instance},select:e=>{const t=function(e,t="."){const r=new Set,s=(e=[])=>new Proxy({},{get:(n,i)=>{if("symbol"==typeof i)return;const a=[...e,i],o=a.join(t);return r.add(o),s(a)}});try{e(s())}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)}`)}const n=Array.from(r);return n.filter((e=>!n.some((r=>r!==e&&r.startsWith(e+t)))))}(e);return null===h&&(h=new Set),t.forEach((e=>h.add(e))),e(f.store.get(!0))}}),stream:e=>{if(i)throw new d(`[ArtifactManager] Illegal stream on transient artifact "${n}"`,"system");const r=async(e,r=void 0)=>{await t.streamSerializer.do((async()=>{void 0!==t.stream&&(t.instance=e,t.error=r,t.version++,this.cache.invalidatePackage(s),await this.processStream(s))}))},a={value:()=>t.instance,get signal(){return t.streamController.signal},set:(...e)=>this.store.set(...e),emit:e=>r(e)};t.stream=async()=>{try{const r=await e(a);r&&t.cleanupFunctions.push(r)}catch(e){await r(void 0,e),await this.invalidate(s,!1,!0)}}}};let w,_,k=0;const A=(e.retries??0)+1;for(;k<A;)try{const t=e.factory(m);if(e.timeout){let r;const s=new Promise(((t,s)=>{r=setTimeout((()=>s(new Error(`Timeout: ${e.timeout}ms`))),e.timeout)}));try{w=await Promise.race([t,s])}finally{clearTimeout(r)}}else w=await t;const r=u?this.detectStaleness(u):null;if(!r){_=void 0;break}if(k++,u?.clear(),k<A)continue;_=new d(`Build stale after all retries: dependency "${String(r)}" changed during build.`,"system")}catch(e){if(e instanceof d)throw e;k++,k>=A&&(_=e)}if(!c)throw await b(a,n),new S;if(i||(this.updateDependencyGraph(s,l??new Set,h??new Set),t.cleanupFunctions=a,t.disposeFunctions=o),_?(t.error=_,t.instance=void 0):(t.instance=w,t.error=void 0),t.version++,this.cache.invalidatePackage(s),i)return{instance:w,cleanup:v(a,String(s)),error:_,ready:!0,invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${String(s)}"`)}}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(((n,i)=>{s.debounceTimer=setTimeout((()=>{s.debounceTimer=void 0,this.executeInvalidation(e,t,r).then(n).catch(i)}),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 i=this.registry.get(e);!i||!t&&i.lazy&&!this.hasWatchers(e)||r||await this.build(e).catch((t=>{t instanceof S||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),this.observer.notify(e)}))}async dispose(e){const t=this.cache.get(e);if(!t)return;null===t.buildOnce||(await t.buildOnce.resolved(),await t.invalidationSerializer.do((async()=>{})),await t.streamOnce.resolved()),await this.cache.invalidateInstance(e),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,streamController:new AbortController};return t?{...r,buildOnce:null,streamOnce:null,streamSerializer:null,invalidationSerializer:null}:{...r,buildOnce:new m(!0,!0),streamOnce:new m(!0,!0),streamSerializer:new w({yieldMode:"microtask"}),invalidationSerializer:new w({yieldMode:"macrotask"})}}hasWatchers(e){return this.observer.hasWatchers(e)??!1}},k=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)??A}iterDependencies(e){return this.dependencies.get(e)??A}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]),n=new Map;for(;r.length>0;){const i=r.shift();if(i===e){const r=[];let s=e;for(;void 0!==s&&(r.push(s),s!==t);)s=n.get(s);return r.reverse(),r.unshift(e),r}const a=this.dependencies.get(i);if(a)for(const e of a)s.has(e)||(s.add(e),n.set(e,i),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 n=this.dependents.get(t);if(n)for(const t of n){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,n=new Set,i=[e];n.add(e),r&&s.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;i.length>0;){const e=i.shift(),t=a.get(e);if(t)for(const e of t)n.has(e)||(n.add(e),s.add(e),i.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")}},A=new Set,C=class{graph;constructor(){this.graph=new k}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){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),n=e.slice(s);return n.push(t),n}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()}},O=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 Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});if(r.packagedArtifact)return r.packagedArtifact;const s=String(e);let n=null;const i={instance:r.instance,error:r.error,ready:r.buildOnce?.isReady()??!1,get cleanup(){return null===n&&(n=v(r.cleanupFunctions,s)??void 0),n},invalidate:t};return r.packagedArtifact=i,i}invalidatePackage(e){const t=this.get(e);t&&(t.packagedArtifact=void 0)}async invalidateInstance(e){const t=this.get(e);if(!t)return;t.stateUnsubscribe&&(t.stateUnsubscribe(),t.stateUnsubscribe=void 0),t.debounceTimer&&(clearTimeout(t.debounceTimer),t.debounceTimer=void 0);const r=null===t.buildOnce;r||(t.streamController.abort(),await t.streamOnce.resolved(),t.streamOnce=new m(!0,!0),t.streamSerializer.close(),t.stream=void 0,t.streamSerializer=new w,t.streamController=new AbortController),await b(t.cleanupFunctions,String(e)),await b(t.disposeFunctions,String(e)),t.cleanupFunctions=[],t.disposeFunctions=[],r||t.buildOnce.reset(),t.instance=void 0,t.error=void 0}},D=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,n="transient"===r.scope;if(this.watcherCache.has(s))return this.watcherCache.get(s).watcher;const i={count:0,init:new m(!1,!0),watcher:null},a=()=>i.init.do((async()=>{n&&!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 i.watcher={id:t,get count(){return i.count},get:()=>0===i.count?Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}}):this.cache.package(s,(e=>this.container.invalidate(s,e))),resolve:async()=>(await a(),this.container.resolve(s)),subscribe:e=>{0===i.count&&a(),i.count++,this.listeners.has(s)||this.listeners.set(s,new Set);const t=()=>e(i.watcher.get());return this.container.resolve(s).then((()=>{t(),this.listeners.get(s)?.add(t)})).catch((e=>{console.error(`[ArtifactObserver] Background resolution failed for "${s}":`,e),this.listeners.get(s)?.add(t)})),()=>{this.listeners.get(s)?.delete(t),i.count--,0===i.count&&(this.listeners.delete(s),n&&(this.registry.unregister(s).catch((e=>{console.error(`[ArtifactObserver] Cleanup failed for "${s}":`,e)})),this.cache.delete(s),this.watcherCache.delete(s)),i.init.reset())}}},this.watcherCache.set(s,i),i.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 f,this.cache=new O,this.graph=new C,this.observer=new D(this.registry,this.cache,this),this.manager=new _(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 n="idle";s&&(void 0!==s.debounceTimer?n="debouncing":s.buildOnce?.running()?n="building":s.buildOnce?.done()&&!s.buildOnce?.isReady()?n="pending":s.error?n="error":void 0!==s.instance&&(n="active")),e.push({id:t,scope:r.scope??"singleton",status:n,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)}async unregister(e){await this.manager.dispose(e),await this.registry.unregister(e)}async resolve(e){if(!this.registry.has(e))throw new l(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 l(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=h;
package/index.mjs CHANGED
@@ -1 +1 @@
1
- var e,t,r=Object.create,s=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.getPrototypeOf,o=Object.prototype.hasOwnProperty,c=(e={"node_modules/@asaidimu/events/index.js"(e,t){var r,s=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.prototype.hasOwnProperty,o={};((e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})})(o,{createEventBus:()=>c}),t.exports=(r=o,((e,t,r,o)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of i(t))a.call(e,c)||c===r||s(e,c,{get:()=>t[c],enumerable:!(o=n(t,c))||o.enumerable});return e})(s({},"__esModule",{value:!0}),r));var c=(e={async:!1,batchSize:1e3,batchDelay:16,errorHandler:e=>console.error("EventBus Error:",e),crossTab:!1,channelName:"event-bus-channel"})=>{const t=new Map;let r=[],s=0,n=0;const i=new Map,a=new Map;let o=null;e.crossTab&&"undefined"!=typeof BroadcastChannel?o=new BroadcastChannel(e.channelName):e.crossTab&&console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");const c=(e,t)=>{s++,n+=t,i.set(e,(i.get(e)||0)+1)},h=()=>{const t=r;r=[],t.forEach((({name:t,payload:r})=>{const s=performance.now();try{(a.get(t)||[]).forEach((e=>e(r)))}catch(s){e.errorHandler({...s,eventName:t,payload:r})}c(t,performance.now()-s)}))},d=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(h,e.batchDelay)}})(),l=e=>{const r=t.get(e);r?a.set(e,Array.from(r)):a.delete(e)};return o&&(o.onmessage=e=>{const{name:t,payload:r}=e.data;(a.get(t)||[]).forEach((e=>e(r)))}),{subscribe:(e,r)=>{t.has(e)||t.set(e,new Set);const s=t.get(e);return s.add(r),l(e),()=>{s.delete(r),0===s.size?(t.delete(e),a.delete(e)):l(e)}},emit:({name:t,payload:s})=>{if(e.async)return r.push({name:t,payload:s}),r.length>=e.batchSize?h():d(),void(o&&o.postMessage({name:t,payload:s}));const n=performance.now();try{(a.get(t)||[]).forEach((e=>e(s))),o&&o.postMessage({name:t,payload:s})}catch(r){e.errorHandler({...r,eventName:t,payload:s})}c(t,performance.now()-n)},getMetrics:()=>({totalEvents:s,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:i,averageEmitDuration:s>0?n/s:0}),clear:()=>{t.clear(),a.clear(),r=[],s=0,n=0,i.clear(),o&&(o.close(),o=null)}}}}},function(){return t||(0,e[i(e)[0]])((t={exports:{}}).exports,t),t.exports}),h=(e=>(e.Singleton="singleton",e.Transient="transient",e))(h||{}),d=class e extends Error{category;constructor(t,r,s){super(t,{cause:s}),this.name="ArtifactError",this.category=r,Object.setPrototypeOf(this,e.prototype)}},l=class extends d{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system")}},u=class extends d{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`,"system")}},p=class extends d{constructor(e){super(`[ArtifactContainer] An artifact with key:${e} already exists!`,"system")}},g=class extends d{constructor(){super("[Serializer] The serializer has been marked as done!","system")}},f=class{artifacts=new Map;register({key:e,factory:t,lazy:r,...s}){if(this.artifacts.has(e))throw new p(String(e));const{scope:n,...i}=s,a={key:e,factory:t,scope:s.scope??"singleton",lazy:void 0===r||r,...i};return this.artifacts.set(e,a),()=>this.unregister(e)}get(e){if(!this.has(e))throw new l(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()}};((e,t,c)=>{c=null!=e?r(a(e)):{},((e,t,r,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of i(t))o.call(e,c)||c===r||s(e,c,{get:()=>t[c],enumerable:!(a=n(t,c))||a.enumerable})})(e&&e.__esModule?c:s(c,"default",{value:e,enumerable:!0}),e)})(c());var y=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));this.waiters.push(t),null!=e?await Promise.race([r,new Promise(((r,s)=>setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),s(new u("Mutex lock timed out"))}),e)))]):await r}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}},w=class{constructor(e=!1,t=!1){this.retry=e,this.throws=t}mutex=new y({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;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{const t=await e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.promise=null}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}isReady(){return this._done&&null===this.promise}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(){this._done=!1,this.promise=null,this._value=null,this._error=void 0}resolved(){return this.promise}done(){return this._done}_awaitWithTimeout(e,t,r="Operation timed out"){return null==t?e:Promise.race([e,new Promise(((e,s)=>setTimeout((()=>s(new u(r))),t)))])}},m=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;constructor(e){this.mutex=new y({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new g};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let r,s=null;try{if(this._done)throw new g;s=await e(),this._lastValue=s,this._lastError=void 0}catch(e){r=e,this._lastError=e}finally{this.mutex.unlock()}return{value:s,error:r}}peek(){return{value:this._lastValue,error:this._lastError}}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}};function v(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 b(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 S=class extends Error{constructor(){super("Build superseded by invalidation"),this.name="SupersededBuildError"}},_=class{constructor(e,t,r,s,n){this.registry=e,this.cache=t,this.graph=r,this.store=s,this.observer=n}async build(e,t){const r=this.cache.get(e);if(r&&null!==r.buildOnce&&r.buildOnce.isReady())return this.cache.package(e,((t,r)=>this.invalidate(e,t,r)));const s=this.registry.get(e);if(!s)throw new d(`Template not found for artifact "${String(e)}"`,"system");const n=t?new Set(t):new Set;if(n.has(e))throw new d(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${Array.from(n).join(" -> ")}`,"system");n.add(e);let i=r;return i||(i=this.createCachedArtifact(s),this.cache.set(e,i)),"transient"===s.scope?this.executeBuild(s,i,n):(await i.buildOnce.do((()=>this.executeBuild(s,i,n))),i.stream&&i.streamOnce.do(i.stream),this.cache.package(e,((t,r)=>this.invalidate(e,t,r))))}async executeBuild(e,t,r){const s=e.key,n=String(s),i="transient"===e.scope;t.buildCount++,t.activeDebounceMs=e.debounce??0;const a=[],o=[];let c=!0;a.push((()=>{c=!1}));let h=null,l=null,u=null;const p=this.graph,g=this.cache,f=this;async function y(e){if(e===s)throw new d(`Artifact "${n}" depends on itself.`,"system");const t=p.wouldCreateCycle(s,e,r);if(t)throw new d(`Adding dependency "${String(e)}" to "${n}" would create a cycle: ${t.join(" -> ")}`,"system");null===l&&(l=new Set),null===u&&(u=new Map),l.add(e);const i=await f.build(e,r),a=g.get(e);return a&&u.set(e,a.version),i}const w={state:()=>f.store.get(!0),previous:t.instance,onCleanup:e=>a.push(e),onDispose:e=>o.push(e),use:async e=>e({resolve:y,require:async e=>{const t=await y(e);if(t.error)throw t.error;return t.instance},select:e=>{const t=function(e,t="."){const r=new Set,s=(e=[])=>new Proxy({},{get:(n,i)=>{if("symbol"==typeof i)return;const a=[...e,i],o=a.join(t);return r.add(o),s(a)}});try{e(s())}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)}`)}const n=Array.from(r);return n.filter((e=>!n.some((r=>r!==e&&r.startsWith(e+t)))))}(e);return null===h&&(h=new Set),t.forEach((e=>h.add(e))),e(f.store.get(!0))}}),stream:e=>{if(i)throw new d(`[ArtifactManager] Illegal stream on transient artifact "${n}"`,"system");const r=async(e,r=void 0)=>{await t.streamSerializer.do((async()=>{void 0!==t.stream&&(t.instance=e,t.error=r,t.version++,this.cache.invalidatePackage(s),await this.processStream(s))}))},a={value:()=>t.instance,get signal(){return t.streamController.signal},set:(...e)=>this.store.set(...e),emit:e=>r(e)};t.stream=async()=>{try{const r=await e(a);r&&t.cleanupFunctions.push(r)}catch(e){await r(void 0,e),await this.invalidate(s,!1,!0)}}}};let m,_,k=0;const A=(e.retries??0)+1;for(;k<A;)try{const t=e.factory(w);if(e.timeout){const r=new Promise(((t,r)=>setTimeout((()=>r(new Error(`Timeout: ${e.timeout}ms`))),e.timeout)));m=await Promise.race([t,r])}else m=await t;const r=u?this.detectStaleness(u):null;if(!r){_=void 0;break}if(k++,u?.clear(),k<A)continue;_=new d(`Build stale after all retries: dependency "${String(r)}" changed during build.`,"system")}catch(e){if(e instanceof d)throw e;k++,k>=A&&(_=e)}if(!c)throw await b(a,n),new S;if(i||(this.updateDependencyGraph(s,l??new Set,h??new Set),t.cleanupFunctions=a,t.disposeFunctions=o),_?(t.error=_,t.instance=void 0):(t.instance=m,t.error=void 0),t.version++,this.cache.invalidatePackage(s),i)return{instance:m,cleanup:v(a,String(s)),error:_,ready:!0,invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${String(s)}"`)}}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(((n,i)=>{s.debounceTimer=setTimeout((()=>{s.debounceTimer=void 0,this.executeInvalidation(e,t,r).then(n).catch(i)}),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 i=this.registry.get(e);!i||!t&&i.lazy&&!this.hasWatchers(e)||r||await this.build(e).catch((t=>{t instanceof S||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),this.observer.notify(e)}))}async dispose(e){const t=this.cache.get(e);if(!t)return;null===t.buildOnce||(await t.buildOnce.resolved(),await t.invalidationSerializer.do((async()=>{})),await t.streamOnce.resolved()),await this.cache.invalidateInstance(e),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,streamController:new AbortController};return t?{...r,buildOnce:null,streamOnce:null,streamSerializer:null,invalidationSerializer:null}:{...r,buildOnce:new w(!0,!0),streamOnce:new w(!0,!0),streamSerializer:new m({yieldMode:"microtask"}),invalidationSerializer:new m({yieldMode:"macrotask"})}}hasWatchers(e){return this.observer.hasWatchers(e)??!1}},k=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)??A}iterDependencies(e){return this.dependencies.get(e)??A}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]),n=new Map;for(;r.length>0;){const i=r.shift();if(i===e){const r=[];let s=e;for(;void 0!==s&&(r.push(s),s!==t);)s=n.get(s);return r.reverse(),[e,...r]}const a=this.dependencies.get(i);if(a)for(const e of a)s.has(e)||(s.add(e),n.set(e,i),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 n=this.dependents.get(t);if(n)for(const t of n){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,n=new Set,i=[e];n.add(e),r&&s.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;i.length>0;){const e=i.shift(),t=a.get(e);if(t)for(const e of t)n.has(e)||(n.add(e),s.add(e),i.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")}},A=new Set,C=class{graph;constructor(){this.graph=new k}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){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),n=e.slice(s);return n.push(t),n}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()}},O=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 Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});if(r.packagedArtifact)return r.packagedArtifact;const s=String(e);let n=null;const i={instance:r.instance,error:r.error,ready:r.buildOnce?.isReady()??!1,get cleanup(){return null===n&&(n=v(r.cleanupFunctions,s)??void 0),n},invalidate:t};return r.packagedArtifact=i,i}invalidatePackage(e){const t=this.get(e);t&&(t.packagedArtifact=void 0)}async invalidateInstance(e){const t=this.get(e);if(!t)return;t.stateUnsubscribe&&(t.stateUnsubscribe(),t.stateUnsubscribe=void 0),t.debounceTimer&&(clearTimeout(t.debounceTimer),t.debounceTimer=void 0);const r=null===t.buildOnce;r||(t.streamController.abort(),await t.streamOnce.resolved(),t.streamOnce=new w(!0,!0),t.streamSerializer.close(),t.stream=void 0,t.streamSerializer=new m,t.streamController=new AbortController),await b(t.cleanupFunctions,String(e)),await b(t.disposeFunctions,String(e)),t.cleanupFunctions=[],t.disposeFunctions=[],r||t.buildOnce.reset(),t.instance=void 0,t.error=void 0}},D=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;if(this.watcherCache.has(s))return this.watcherCache.get(s).watcher;const n={count:0,init:new w(!1,!0),watcher:null},i=()=>n.init.do((async()=>{"transient"!==r.scope||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:()=>0===n.count?Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}}):this.cache.package(s,(e=>this.container.invalidate(s,e))),resolve:async()=>(await i(),this.container.resolve(s)),subscribe:e=>{0===n.count&&i(),n.count++,this.listeners.has(s)||this.listeners.set(s,new Set);const t=()=>e(n.watcher.get());return this.container.resolve(s).then((()=>{t(),this.listeners.get(s)?.add(t)})).catch((e=>{console.error(`[ArtifactObserver] Background resolution failed for "${s}":`,e),this.listeners.get(s)?.add(t)})),()=>{this.listeners.get(s)?.delete(t),n.count--,0===n.count&&(this.listeners.delete(s),"transient"===r.scope&&(this.registry.unregister(s).catch((e=>{console.error(`[ArtifactObserver] Cleanup failed for "${s}":`,e)})),this.cache.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()}},M=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 f,this.cache=new O,this.graph=new C,this.observer=new D(this.registry,this.cache,this),this.manager=new _(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;const n=s?s.buildOnce.running()?"pending":s.error?"error":void 0!==s.instance?"active":"idle":"idle";e.push({id:t,scope:r.scope??"singleton",status:n,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)}async unregister(e){await this.manager.dispose(e),await this.registry.unregister(e)}async resolve(e){if(!this.registry.has(e))throw new l(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 l(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)}dispose(){this.registry.keys().forEach((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{M as ArtifactContainer,h as ArtifactScopes};
1
+ var e,t,r=Object.create,s=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.getPrototypeOf,o=Object.prototype.hasOwnProperty,c=(e={"node_modules/@asaidimu/events/index.js"(e,t){var r,s=Object.defineProperty,n=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.prototype.hasOwnProperty,o={};((e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})})(o,{createEventBus:()=>c}),t.exports=(r=o,((e,t,r,o)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of i(t))a.call(e,c)||c===r||s(e,c,{get:()=>t[c],enumerable:!(o=n(t,c))||o.enumerable});return e})(s({},"__esModule",{value:!0}),r));var c=(e={async:!1,batchSize:1e3,batchDelay:16,errorHandler:e=>console.error("EventBus Error:",e),crossTab:!1,channelName:"event-bus-channel"})=>{const t=new Map;let r=[],s=0,n=0;const i=new Map,a=new Map;let o=null;e.crossTab&&"undefined"!=typeof BroadcastChannel?o=new BroadcastChannel(e.channelName):e.crossTab&&console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");const c=(e,t)=>{s++,n+=t,i.set(e,(i.get(e)||0)+1)},h=()=>{const t=r;r=[],t.forEach((({name:t,payload:r})=>{const s=performance.now();try{(a.get(t)||[]).forEach((e=>e(r)))}catch(s){e.errorHandler({...s,eventName:t,payload:r})}c(t,performance.now()-s)}))},d=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(h,e.batchDelay)}})(),l=e=>{const r=t.get(e);r?a.set(e,Array.from(r)):a.delete(e)};return o&&(o.onmessage=e=>{const{name:t,payload:r}=e.data;(a.get(t)||[]).forEach((e=>e(r)))}),{subscribe:(e,r)=>{t.has(e)||t.set(e,new Set);const s=t.get(e);return s.add(r),l(e),()=>{s.delete(r),0===s.size?(t.delete(e),a.delete(e)):l(e)}},emit:({name:t,payload:s})=>{if(e.async)return r.push({name:t,payload:s}),r.length>=e.batchSize?h():d(),void(o&&o.postMessage({name:t,payload:s}));const n=performance.now();try{(a.get(t)||[]).forEach((e=>e(s))),o&&o.postMessage({name:t,payload:s})}catch(r){e.errorHandler({...r,eventName:t,payload:s})}c(t,performance.now()-n)},getMetrics:()=>({totalEvents:s,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:i,averageEmitDuration:s>0?n/s:0}),clear:()=>{t.clear(),a.clear(),r=[],s=0,n=0,i.clear(),o&&(o.close(),o=null)}}}}},function(){return t||(0,e[i(e)[0]])((t={exports:{}}).exports,t),t.exports}),h=(e=>(e.Singleton="singleton",e.Transient="transient",e))(h||{}),d=class e extends Error{category;constructor(t,r,s){super(t,{cause:s}),this.name="ArtifactError",this.category=r,Object.setPrototypeOf(this,e.prototype)}},l=class extends d{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system")}},u=class extends d{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`,"system")}},p=class extends d{constructor(e){super(`[ArtifactContainer] An artifact with key:${e} already exists!`,"system")}},g=class extends d{constructor(){super("[Serializer] The serializer has been marked as done!","system")}},f=class{artifacts=new Map;register({key:e,factory:t,lazy:r,...s}){if(this.artifacts.has(e))throw new p(String(e));const{scope:n,...i}=s,a={key:e,factory:t,scope:s.scope??"singleton",lazy:void 0===r||r,...i};return this.artifacts.set(e,a),()=>this.unregister(e)}get(e){if(!this.has(e))throw new l(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()}};((e,t,c)=>{c=null!=e?r(a(e)):{},((e,t,r,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of i(t))o.call(e,c)||c===r||s(e,c,{get:()=>t[c],enumerable:!(a=n(t,c))||a.enumerable})})(e&&e.__esModule?c:s(c,"default",{value:e,enumerable:!0}),e)})(c());var y=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));this.waiters.push(t),null!=e?await Promise.race([r,new Promise(((r,s)=>setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),s(new u("Mutex lock timed out"))}),e)))]):await r}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}},m=class{constructor(e=!1,t=!1){this.retry=e,this.throws=t}mutex=new y({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;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{const t=await e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.promise=null}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}isReady(){return this._done&&null===this.promise}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(){this._done=!1,this.promise=null,this._value=null,this._error=void 0}resolved(){return this.promise}done(){return this._done}_awaitWithTimeout(e,t,r="Operation timed out"){return null==t?e:Promise.race([e,new Promise(((e,s)=>setTimeout((()=>s(new u(r))),t)))])}},w=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;constructor(e){this.mutex=new y({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new g};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let r,s=null;try{if(this._done)throw new g;s=await e(),this._lastValue=s,this._lastError=void 0}catch(e){r=e,this._lastError=e}finally{this.mutex.unlock()}return{value:s,error:r}}peek(){return{value:this._lastValue,error:this._lastError}}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}};function v(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 b(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 S=class extends Error{constructor(){super("Build superseded by invalidation"),this.name="SupersededBuildError"}},_=class{constructor(e,t,r,s,n){this.registry=e,this.cache=t,this.graph=r,this.store=s,this.observer=n}async build(e,t){const r=this.cache.get(e);if(r&&null!==r.buildOnce&&r.buildOnce.isReady())return this.cache.package(e,((t,r)=>this.invalidate(e,t,r)));const s=this.registry.get(e),n=t?new Set(t):new Set;if(n.has(e))throw new d(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${Array.from(n).join(" -> ")}`,"system");n.add(e);let i=r;return i||(i=this.createCachedArtifact(s),this.cache.set(e,i)),"transient"===s.scope?this.executeBuild(s,i,n):(await i.buildOnce.do((()=>this.executeBuild(s,i,n))),i.stream&&i.streamOnce.do(i.stream),this.cache.package(e,((t,r)=>this.invalidate(e,t,r))))}async executeBuild(e,t,r){const s=e.key,n=String(s),i="transient"===e.scope;t.buildCount++,t.activeDebounceMs=e.debounce??0;const a=[],o=[];let c=!0;a.push((()=>{c=!1}));let h=null,l=null,u=null;const p=this.graph,g=this.cache,f=this;async function y(e){if(e===s)throw new d(`Artifact "${n}" depends on itself.`,"system");const t=p.wouldCreateCycle(s,e,r);if(t)throw new d(`Adding dependency "${String(e)}" to "${n}" would create a cycle: ${t.join(" -> ")}`,"system");null===l&&(l=new Set),null===u&&(u=new Map),l.add(e);const i=await f.build(e,r),a=g.get(e);return a&&u.set(e,a.version),i}const m={state:()=>f.store.get(!0),previous:t.instance,onCleanup:e=>a.push(e),onDispose:e=>o.push(e),use:async e=>e({resolve:y,require:async e=>{const t=await y(e);if(t.error)throw t.error;return t.instance},select:e=>{const t=function(e,t="."){const r=new Set,s=(e=[])=>new Proxy({},{get:(n,i)=>{if("symbol"==typeof i)return;const a=[...e,i],o=a.join(t);return r.add(o),s(a)}});try{e(s())}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)}`)}const n=Array.from(r);return n.filter((e=>!n.some((r=>r!==e&&r.startsWith(e+t)))))}(e);return null===h&&(h=new Set),t.forEach((e=>h.add(e))),e(f.store.get(!0))}}),stream:e=>{if(i)throw new d(`[ArtifactManager] Illegal stream on transient artifact "${n}"`,"system");const r=async(e,r=void 0)=>{await t.streamSerializer.do((async()=>{void 0!==t.stream&&(t.instance=e,t.error=r,t.version++,this.cache.invalidatePackage(s),await this.processStream(s))}))},a={value:()=>t.instance,get signal(){return t.streamController.signal},set:(...e)=>this.store.set(...e),emit:e=>r(e)};t.stream=async()=>{try{const r=await e(a);r&&t.cleanupFunctions.push(r)}catch(e){await r(void 0,e),await this.invalidate(s,!1,!0)}}}};let w,_,k=0;const A=(e.retries??0)+1;for(;k<A;)try{const t=e.factory(m);if(e.timeout){let r;const s=new Promise(((t,s)=>{r=setTimeout((()=>s(new Error(`Timeout: ${e.timeout}ms`))),e.timeout)}));try{w=await Promise.race([t,s])}finally{clearTimeout(r)}}else w=await t;const r=u?this.detectStaleness(u):null;if(!r){_=void 0;break}if(k++,u?.clear(),k<A)continue;_=new d(`Build stale after all retries: dependency "${String(r)}" changed during build.`,"system")}catch(e){if(e instanceof d)throw e;k++,k>=A&&(_=e)}if(!c)throw await b(a,n),new S;if(i||(this.updateDependencyGraph(s,l??new Set,h??new Set),t.cleanupFunctions=a,t.disposeFunctions=o),_?(t.error=_,t.instance=void 0):(t.instance=w,t.error=void 0),t.version++,this.cache.invalidatePackage(s),i)return{instance:w,cleanup:v(a,String(s)),error:_,ready:!0,invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${String(s)}"`)}}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(((n,i)=>{s.debounceTimer=setTimeout((()=>{s.debounceTimer=void 0,this.executeInvalidation(e,t,r).then(n).catch(i)}),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 i=this.registry.get(e);!i||!t&&i.lazy&&!this.hasWatchers(e)||r||await this.build(e).catch((t=>{t instanceof S||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),this.observer.notify(e)}))}async dispose(e){const t=this.cache.get(e);if(!t)return;null===t.buildOnce||(await t.buildOnce.resolved(),await t.invalidationSerializer.do((async()=>{})),await t.streamOnce.resolved()),await this.cache.invalidateInstance(e),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,streamController:new AbortController};return t?{...r,buildOnce:null,streamOnce:null,streamSerializer:null,invalidationSerializer:null}:{...r,buildOnce:new m(!0,!0),streamOnce:new m(!0,!0),streamSerializer:new w({yieldMode:"microtask"}),invalidationSerializer:new w({yieldMode:"macrotask"})}}hasWatchers(e){return this.observer.hasWatchers(e)??!1}},k=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)??A}iterDependencies(e){return this.dependencies.get(e)??A}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]),n=new Map;for(;r.length>0;){const i=r.shift();if(i===e){const r=[];let s=e;for(;void 0!==s&&(r.push(s),s!==t);)s=n.get(s);return r.reverse(),r.unshift(e),r}const a=this.dependencies.get(i);if(a)for(const e of a)s.has(e)||(s.add(e),n.set(e,i),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 n=this.dependents.get(t);if(n)for(const t of n){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,n=new Set,i=[e];n.add(e),r&&s.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;i.length>0;){const e=i.shift(),t=a.get(e);if(t)for(const e of t)n.has(e)||(n.add(e),s.add(e),i.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")}},A=new Set,C=class{graph;constructor(){this.graph=new k}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){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),n=e.slice(s);return n.push(t),n}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()}},O=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 Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});if(r.packagedArtifact)return r.packagedArtifact;const s=String(e);let n=null;const i={instance:r.instance,error:r.error,ready:r.buildOnce?.isReady()??!1,get cleanup(){return null===n&&(n=v(r.cleanupFunctions,s)??void 0),n},invalidate:t};return r.packagedArtifact=i,i}invalidatePackage(e){const t=this.get(e);t&&(t.packagedArtifact=void 0)}async invalidateInstance(e){const t=this.get(e);if(!t)return;t.stateUnsubscribe&&(t.stateUnsubscribe(),t.stateUnsubscribe=void 0),t.debounceTimer&&(clearTimeout(t.debounceTimer),t.debounceTimer=void 0);const r=null===t.buildOnce;r||(t.streamController.abort(),await t.streamOnce.resolved(),t.streamOnce=new m(!0,!0),t.streamSerializer.close(),t.stream=void 0,t.streamSerializer=new w,t.streamController=new AbortController),await b(t.cleanupFunctions,String(e)),await b(t.disposeFunctions,String(e)),t.cleanupFunctions=[],t.disposeFunctions=[],r||t.buildOnce.reset(),t.instance=void 0,t.error=void 0}},D=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,n="transient"===r.scope;if(this.watcherCache.has(s))return this.watcherCache.get(s).watcher;const i={count:0,init:new m(!1,!0),watcher:null},a=()=>i.init.do((async()=>{n&&!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 i.watcher={id:t,get count(){return i.count},get:()=>0===i.count?Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}}):this.cache.package(s,(e=>this.container.invalidate(s,e))),resolve:async()=>(await a(),this.container.resolve(s)),subscribe:e=>{0===i.count&&a(),i.count++,this.listeners.has(s)||this.listeners.set(s,new Set);const t=()=>e(i.watcher.get());return this.container.resolve(s).then((()=>{t(),this.listeners.get(s)?.add(t)})).catch((e=>{console.error(`[ArtifactObserver] Background resolution failed for "${s}":`,e),this.listeners.get(s)?.add(t)})),()=>{this.listeners.get(s)?.delete(t),i.count--,0===i.count&&(this.listeners.delete(s),n&&(this.registry.unregister(s).catch((e=>{console.error(`[ArtifactObserver] Cleanup failed for "${s}":`,e)})),this.cache.delete(s),this.watcherCache.delete(s)),i.init.reset())}}},this.watcherCache.set(s,i),i.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()}},M=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 f,this.cache=new O,this.graph=new C,this.observer=new D(this.registry,this.cache,this),this.manager=new _(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 n="idle";s&&(void 0!==s.debounceTimer?n="debouncing":s.buildOnce?.running()?n="building":s.buildOnce?.done()&&!s.buildOnce?.isReady()?n="pending":s.error?n="error":void 0!==s.instance&&(n="active")),e.push({id:t,scope:r.scope??"singleton",status:n,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)}async unregister(e){await this.manager.dispose(e),await this.registry.unregister(e)}async resolve(e){if(!this.registry.has(e))throw new l(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 l(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{M as ArtifactContainer,h as ArtifactScopes};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asaidimu/utils-artifacts",
3
- "version": "5.0.1",
3
+ "version": "6.0.1",
4
4
  "description": "Reactive artifact container.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",