@asaidimu/utils-artifacts 8.2.5 → 8.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -224,6 +224,162 @@ observer.subscribe((resolved) => {
224
224
  });
225
225
  ```
226
226
 
227
+ ### Persistence: Export and Import
228
+
229
+ The container can export its current set of built singleton artifacts into a serializable bundle and later restore them in a new container. This is useful for **saving/reloading application state**, or **transferring** a snapshot across environments.
230
+
231
+ #### Exporting Artifacts
232
+
233
+ Call `container.export()` to generate a JSON‑compatible bundle.
234
+
235
+ - The method **waits** for all currently resolving artifacts to finish.
236
+ - Only **singleton** artifacts that have been fully built (i.e., `ready === true`) are included.
237
+ - Each exported artifact stores:
238
+ - Its resolved `instance` (must be JSON‑serializable).
239
+ - The **state groups** (store selectors) it depends on, with their paths and options.
240
+ - Its list of **artifact dependencies** (other artifact keys).
241
+ - The bundle contains a **checksum** to detect corruption.
242
+
243
+ ```typescript
244
+ const bundle = await container.export();
245
+ // {
246
+ // version: "1.0",
247
+ // timestamp: 1700000000000,
248
+ // checksum: "abc123...",
249
+ // artifacts: [
250
+ // {
251
+ // key: "config",
252
+ // instance: { theme: "dark" },
253
+ // state: { groups: [{ paths: ["theme"], options: undefined }] },
254
+ // dependencies: []
255
+ // },
256
+ // // ...
257
+ // ]
258
+ // }
259
+ ```
260
+
261
+ > **Note**: Transient artifacts are **never** exported. If an artifact instance contains non‑serializable values (e.g., functions, symbols), `export()` will throw an error.
262
+
263
+ #### Importing Artifacts
264
+
265
+ Use the static `ArtifactContainer.from()` method to create a new container pre‑filled with exported data.
266
+
267
+ - You must provide:
268
+ - A `store` (the same or a different `ReactiveDataStore`).
269
+ - The previously exported `bundle`.
270
+ - The **original artifact templates** (the container does not store factory functions).
271
+ - The method validates the bundle’s checksum. On mismatch, it throws `"Bundle checksum mismatch"`.
272
+ - For each exported artifact, the container **restores the instance only if** all its state groups still match the current store’s data. If any selected slice has changed, the artifact is marked **stale** (not restored) and will be rebuilt on the next `resolve()`.
273
+
274
+ ```typescript
275
+ // Create a new container from a bundle
276
+ const restoredContainer = await ArtifactContainer.from({
277
+ store: new ReactiveDataStore(initialState),
278
+ bundle: savedBundle,
279
+ templates: [
280
+ {
281
+ key: "config",
282
+ factory: async ({ use }) => ({
283
+ theme: await use(({ select }) => select((s: any) => s.theme)),
284
+ }),
285
+ scope: "singleton",
286
+ },
287
+ {
288
+ key: "userName",
289
+ factory: async ({ use }) =>
290
+ `User-${await use(({ select }) => select((s: any) => s.userId))}`,
291
+ scope: "singleton",
292
+ },
293
+ // ... other templates
294
+ ],
295
+ });
296
+ ```
297
+
298
+ #### Staleness and Reactivity
299
+
300
+ When importing, the container compares the exported **state groups** (store selectors) with the **current store**:
301
+
302
+ - If **all** state group values are identical → the artifact instance is restored directly (no rebuild).
303
+ - If **any** value differs → the artifact is **skipped** (not restored) and its cache entry remains empty. The next `resolve()` will run the factory again, using the latest store data.
304
+
305
+ Staleness **propagates** through the dependency graph: if artifact `A` depends on `B` and `B` is stale, then `A` is also considered stale and will be rebuilt.
306
+
307
+ ```typescript
308
+ // Example: store changed from { theme: "dark", userId: 42 } to { theme: "light", userId: 42 }
309
+ // - config (depends on theme) → stale, not restored
310
+ // - userName (depends on userId) → fresh, restored
311
+ // - greeting (depends on config) → stale (transitive), not restored
312
+ ```
313
+
314
+ #### Parameterized Artifacts
315
+
316
+ Parameterized singletons are exported and imported **per parameter key**. The same staleness checks apply independently for each parameter combination.
317
+
318
+ ```typescript
319
+ container.register({
320
+ key: "user",
321
+ paramKey: (params) => `user:${params.userId}`,
322
+ factory: async (ctx) => ({ id: ctx.params.userId, name: "..." }),
323
+ scope: "singleton",
324
+ });
325
+
326
+ // Export includes both user:alice and user:bob
327
+ const bundle = await container.export();
328
+
329
+ // Later, restore both instances
330
+ const newContainer = await ArtifactContainer.from({ store, bundle, templates });
331
+ newContainer.peek("user", { userId: "alice" }); // restored instance
332
+ newContainer.peek("user", { userId: "bob" }); // restored instance
333
+ ```
334
+
335
+ #### Complete Example
336
+
337
+ ```typescript
338
+ import { ReactiveDataStore } from "@asaidimu/utils-store";
339
+ import { ArtifactContainer } from "@asaidimu/utils-artifacts";
340
+
341
+ // 1. Initial setup
342
+ const store = new ReactiveDataStore({ theme: "dark", userId: 42 });
343
+ const container = new ArtifactContainer(store);
344
+
345
+ container.register({
346
+ key: "greeting",
347
+ factory: async ({ use }) => {
348
+ const theme = await use(({ select }) => select((s: any) => s.theme));
349
+ const userId = await use(({ select }) => select((s: any) => s.userId));
350
+ return `${theme} greeting for user ${userId}`;
351
+ },
352
+ scope: "singleton",
353
+ lazy: false,
354
+ });
355
+
356
+ await container.resolve("greeting"); // builds "dark greeting for user 42"
357
+
358
+ // 2. Export the bundle
359
+ const bundle = await container.export();
360
+
361
+ // 3. Later, in a different environment (e.g., another request)
362
+ const newStore = new ReactiveDataStore({ theme: "light", userId: 42 });
363
+ const restored = await ArtifactContainer.from({
364
+ store: newStore,
365
+ bundle,
366
+ templates: [
367
+ /* same greeting template */
368
+ ],
369
+ });
370
+
371
+ // theme changed → greeting is stale, will be rebuilt on demand
372
+ const greeting = await restored.require("greeting");
373
+ console.log(greeting); // "light greeting for user 42"
374
+ ```
375
+
376
+ #### Important Notes
377
+
378
+ - The exported bundle is **read‑only** and should be treated as an immutable snapshot.
379
+ - Always provide **all necessary templates** when calling `from()`. Missing templates cause resolution errors.
380
+ - For high‑cardinality parameterized artifacts, consider cleaning up unused keys before exporting to keep the bundle size reasonable.
381
+ - The checksum prevents accidental corruption but does **not** provide cryptographic security.
382
+
227
383
  ## 5. Architecture
228
384
 
229
385
  `@asaidimu/utils-artifacts` implements a **Directed Acyclic Graph (DAG)** for dependency management using a **Pull-based Invalidation** model.
package/index.d.mts CHANGED
@@ -120,6 +120,13 @@ interface DataStore<T extends object> {
120
120
  * @returns The current state T.
121
121
  */
122
122
  get(clone?: boolean): T;
123
+ /**
124
+ * Gets a subset of the store.
125
+ * @param paths The paths which to include in the returned object.
126
+ * @param separator Optional separator for paths. Defaults to `.` .
127
+ * @returns An object of the shape K mapping paths to their current values.
128
+ */
129
+ subset<K extends Record<string, any> = Record<string, any>>(paths: Array<string>, separator?: string): K;
123
130
  /**
124
131
  * Registers a named action function that can modify the state.
125
132
  * @param action The action configuration object.
@@ -651,6 +658,31 @@ type InferRegistry<T extends Record<string, {
651
658
  }>> = {
652
659
  [K in keyof T]: ArtifactValue<T[K]>;
653
660
  };
661
+ /**
662
+ * State paths grouped by options passed to the store
663
+ */
664
+ interface StateGroup {
665
+ paths: string[];
666
+ options?: SubscribeOptions;
667
+ }
668
+ interface ExportedArtifact {
669
+ key: string;
670
+ instance: any;
671
+ state: {
672
+ groups: Array<{
673
+ paths: string[];
674
+ options?: SubscribeOptions;
675
+ }>;
676
+ hash: string;
677
+ };
678
+ dependencies: string[];
679
+ }
680
+ interface ExportedContainerState {
681
+ version: string;
682
+ timestamp: number;
683
+ artifacts: ExportedArtifact[];
684
+ checksum: string;
685
+ }
654
686
 
655
687
  /**
656
688
  * A dependency injection container for managing the lifecycle, dependencies,
@@ -677,7 +709,7 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
677
709
  * Creates a new ArtifactContainer instance.
678
710
  * @param store An object providing functions to interact with a global data store
679
711
  */
680
- constructor(store: Pick<DataStore<TState>, "watch" | "get" | "set">);
712
+ constructor(store: Pick<DataStore<TState>, "watch" | "get" | "set" | "subset">);
681
713
  /**
682
714
  * Provides debug information about all artifacts currently registered in this container.
683
715
  *
@@ -794,6 +826,13 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
794
826
  * Callers should await this method to guarantee full resource release.
795
827
  */
796
828
  dispose(): Promise<void>;
829
+ export(): Promise<ExportedContainerState>;
830
+ private restore;
831
+ static from<TRegistry extends Record<string, any> = Record<string, any>, TState extends object = any>(options: {
832
+ store: Pick<DataStore<TState>, "watch" | "get" | "set" | "subset">;
833
+ bundle?: ExportedContainerState;
834
+ templates: ArtifactTemplate<TState, any, TRegistry>[];
835
+ }): Promise<ArtifactContainer<TRegistry, TState>>;
797
836
  }
798
837
 
799
- export { type ArtifactCleanup, ArtifactContainer, type ArtifactDebugNode, type ArtifactFactory, type ArtifactFactoryContext, type ArtifactInstance, type ArtifactKey, type ArtifactObserver, type ArtifactRegistryType, type ArtifactScope, type ArtifactScopeType, ArtifactScopes, type ArtifactStateType, type ArtifactStreamContext, type ArtifactTemplate, type ArtifactTemplateMap, type ArtifactValue, type ErrorArtifact, type InferRegistry, type KeyedResolvedArtifact, type PendingArtifact, type ReadyArtifact, type ResolvedArtifact, type ResolvedArtifactBase, type UseDependencyContext };
838
+ 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 ExportedArtifact, type ExportedContainerState, type InferRegistry, type KeyedResolvedArtifact, type PendingArtifact, type ReadyArtifact, type ResolvedArtifact, type ResolvedArtifactBase, type StateGroup, type UseDependencyContext };
package/index.d.ts CHANGED
@@ -120,6 +120,13 @@ interface DataStore<T extends object> {
120
120
  * @returns The current state T.
121
121
  */
122
122
  get(clone?: boolean): T;
123
+ /**
124
+ * Gets a subset of the store.
125
+ * @param paths The paths which to include in the returned object.
126
+ * @param separator Optional separator for paths. Defaults to `.` .
127
+ * @returns An object of the shape K mapping paths to their current values.
128
+ */
129
+ subset<K extends Record<string, any> = Record<string, any>>(paths: Array<string>, separator?: string): K;
123
130
  /**
124
131
  * Registers a named action function that can modify the state.
125
132
  * @param action The action configuration object.
@@ -651,6 +658,31 @@ type InferRegistry<T extends Record<string, {
651
658
  }>> = {
652
659
  [K in keyof T]: ArtifactValue<T[K]>;
653
660
  };
661
+ /**
662
+ * State paths grouped by options passed to the store
663
+ */
664
+ interface StateGroup {
665
+ paths: string[];
666
+ options?: SubscribeOptions;
667
+ }
668
+ interface ExportedArtifact {
669
+ key: string;
670
+ instance: any;
671
+ state: {
672
+ groups: Array<{
673
+ paths: string[];
674
+ options?: SubscribeOptions;
675
+ }>;
676
+ hash: string;
677
+ };
678
+ dependencies: string[];
679
+ }
680
+ interface ExportedContainerState {
681
+ version: string;
682
+ timestamp: number;
683
+ artifacts: ExportedArtifact[];
684
+ checksum: string;
685
+ }
654
686
 
655
687
  /**
656
688
  * A dependency injection container for managing the lifecycle, dependencies,
@@ -677,7 +709,7 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
677
709
  * Creates a new ArtifactContainer instance.
678
710
  * @param store An object providing functions to interact with a global data store
679
711
  */
680
- constructor(store: Pick<DataStore<TState>, "watch" | "get" | "set">);
712
+ constructor(store: Pick<DataStore<TState>, "watch" | "get" | "set" | "subset">);
681
713
  /**
682
714
  * Provides debug information about all artifacts currently registered in this container.
683
715
  *
@@ -794,6 +826,13 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
794
826
  * Callers should await this method to guarantee full resource release.
795
827
  */
796
828
  dispose(): Promise<void>;
829
+ export(): Promise<ExportedContainerState>;
830
+ private restore;
831
+ static from<TRegistry extends Record<string, any> = Record<string, any>, TState extends object = any>(options: {
832
+ store: Pick<DataStore<TState>, "watch" | "get" | "set" | "subset">;
833
+ bundle?: ExportedContainerState;
834
+ templates: ArtifactTemplate<TState, any, TRegistry>[];
835
+ }): Promise<ArtifactContainer<TRegistry, TState>>;
797
836
  }
798
837
 
799
- export { type ArtifactCleanup, ArtifactContainer, type ArtifactDebugNode, type ArtifactFactory, type ArtifactFactoryContext, type ArtifactInstance, type ArtifactKey, type ArtifactObserver, type ArtifactRegistryType, type ArtifactScope, type ArtifactScopeType, ArtifactScopes, type ArtifactStateType, type ArtifactStreamContext, type ArtifactTemplate, type ArtifactTemplateMap, type ArtifactValue, type ErrorArtifact, type InferRegistry, type KeyedResolvedArtifact, type PendingArtifact, type ReadyArtifact, type ResolvedArtifact, type ResolvedArtifactBase, type UseDependencyContext };
838
+ 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 ExportedArtifact, type ExportedContainerState, type InferRegistry, type KeyedResolvedArtifact, type PendingArtifact, type ReadyArtifact, type ResolvedArtifact, type ResolvedArtifactBase, type StateGroup, type UseDependencyContext };
package/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e={VALIDATION_FAILED:{code:"VAL-001",name:"VALIDATION_FAILED",description:"Input validation failed due to one or more invalid fields",category:"validation",httpStatus:400,logLevel:"warn"},REQUIRED_FIELD_MISSING:{code:"VAL-002",name:"REQUIRED_FIELD_MISSING",description:"A required field was not provided in the request",category:"validation",httpStatus:400,logLevel:"warn"},INVALID_FORMAT:{code:"VAL-003",name:"INVALID_FORMAT",description:"Field value does not match expected format",category:"validation",httpStatus:400,logLevel:"warn"},NOT_FOUND:{code:"DB-001-NF",name:"NOT_FOUND",description:"The requested resource could not be found",category:"database",httpStatus:404,logLevel:"info",action:"Verify the resource identifier exists before accessing"},DUPLICATE_KEY:{code:"DB-002-DUP",name:"DUPLICATE_KEY",description:"A unique constraint violation occurred",category:"database",httpStatus:409,logLevel:"warn",action:"Check if the resource already exists before creation"},RESOURCE_LOCKED:{code:"DB-003-LOCK",name:"RESOURCE_LOCKED",description:"The resource is currently locked by another operation",category:"database",httpStatus:409,logLevel:"warn",action:"Retry the operation after a brief delay"},PERMISSION_DENIED:{code:"AUTH-001-DENIED",name:"PERMISSION_DENIED",description:"The authenticated user lacks permission for this operation",category:"auth",httpStatus:403,logLevel:"warn",action:"Check user roles and permissions"},UNAUTHENTICATED:{code:"AUTH-002-UNAUTH",name:"UNAUTHENTICATED",description:"Authentication is required for this operation",category:"auth",httpStatus:401,logLevel:"info",action:"Provide valid authentication credentials"},INVALID_COMMAND:{code:"BUS-001",name:"INVALID_COMMAND",description:"The command or operation is invalid for the current state",category:"business",httpStatus:400,logLevel:"warn"},OPERATION_ABORTED:{code:"BUS-002-ABORT",name:"OPERATION_ABORTED",description:"The operation was explicitly aborted",category:"business",httpStatus:409,logLevel:"info"},INTERNAL_ERROR:{code:"SYS-001",name:"INTERNAL_ERROR",description:"An unexpected internal error occurred",category:"system",httpStatus:500,logLevel:"error",action:"Check system logs for stack traces and diagnostic information"},BACKEND_ERROR:{code:"SYS-002",name:"BACKEND_ERROR",description:"An error occurred in a backend service",category:"system",httpStatus:502,logLevel:"error"},CONCURRENCY_ERROR:{code:"CON-001",name:"CONCURRENCY_ERROR",description:"A concurrency conflict occurred during the operation",category:"concurrency",httpStatus:409,logLevel:"warn",action:"Retry the operation with updated data"}},t=new Map;var s=class s extends Error{code;codeMetadata;severity;path;operation;issues;cause;constructor(r){const i={...function(s){const r=Object.values(e).find((e=>e.code===s));if(r)return r;return t.get(s)||{code:s,name:s.replace(/-/g,"_"),description:`Unknown error: ${s}`,category:"custom",httpStatus:500,logLevel:"error",action:"Check if this error code is properly registered or handle as unknown error"}}(r.code),...r.metadata,code:r.code};super(r.message??i.description),this.name="SystemError",this.code=r.code,this.codeMetadata=i,this.severity=r.severity??"error",this.path=r.path,this.operation=r.operation,this.issues=r.issues??[],this.cause=r.cause,Object.setPrototypeOf(this,s.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,s)}withPath(e){return new s({code:this.code,message:this.message,severity:this.severity,path:e,operation:this.operation,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withOperation(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:e,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withIssue(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,e],cause:this.cause,metadata:this.codeMetadata})}withIssues(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,...e],cause:this.cause,metadata:this.codeMetadata})}withCause(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:this.issues,cause:e,metadata:this.codeMetadata})}getHttpStatus(){return this.codeMetadata.httpStatus}toLogEntry(){return{name:this.name,code:this.code,category:this.codeMetadata.category,message:this.message,path:this.path,operation:this.operation,issues:this.issues,cause:this.cause instanceof Error?this.cause.message:this.cause,stack:this.stack,timestamp:(new Date).toISOString()}}toString(){let e=`[${this.code}] ${this.message} (${this.codeMetadata.category})`;return this.path&&(e+=` at '${this.path}'`),this.operation&&(e+=` during '${this.operation}'`),this.issues.length>0&&(e+="\nIssues:\n"+this.issues.map(((e,t)=>` ${t+1}. ${e.message} [${e.code}]`)).join("\n")),this.cause&&(e+=`\nCause: ${this.cause instanceof Error?this.cause.message:String(this.cause)}`),e}},r=class e extends s{constructor(t,s){super({code:"SYNC_ERROR",message:t,cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},i=class e extends r{constructor(t){super(`[ArtifactContainer] Operation timed out: ${t}`),this.name="TimeoutError",Object.setPrototypeOf(this,e.prototype)}},n=class e extends r{constructor(t){super("[Serializer] The serializer has been marked as done!",t),this.name="SerializerExecutionDone",Object.setPrototypeOf(this,e.prototype)}},a=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 s=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await s;let r;await Promise.race([s.then((()=>clearTimeout(r))),new Promise(((s,n)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),n(new i("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},o=class{mutex=new a({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,s="Operation timed out"){if(null==t)return e;let r;return Promise.race([e.then((e=>(clearTimeout(r),e))),new Promise(((e,n)=>{r=setTimeout((()=>n(new i(s))),t)}))])}},c=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new a({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new n};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,r=null;try{if(this._done)throw new n;r=await e(),this._lastValue=r,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:r,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},h=class{constructor(e,t,s={}){this.factory=e,this.onCleanup=t,this.options=s}_count=0;init=new o({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}};function d(e,t){if(!e.length)return;const s=e.slice(),r=t?`[${t}]`:"[ArtifactCleanup]";return async()=>{for(let e=s.length-1;e>=0;e--)try{await s[e]()}catch(t){console.error(`${r} Cleanup error at index ${e}:`,t)}}}async function u(e,t){const s=t?`[${t}]`:"[ArtifactCleanup]";for(let t=e.length-1;t>=0;t--)try{await e[t]()}catch(e){console.error(`${s} Cleanup error at index ${t}:`,e)}}function l(e){return`${e}__watched`}var p=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function g(e,t){let s;const r=new Promise(((e,r)=>{s=setTimeout((()=>r(new Error(`Timeout: ${t}ms`))),t)}));try{return Promise.race([e,r])}finally{clearTimeout(s)}}var y=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,s){const r=this.get(e);if(!r)return p;if(r.package)return r.package;const i=e,n=d(r.cleanupFunctions,i),a="singleton"!==r.scope||void 0!==r.instance,o={instance:r.instance,error:r.error,ready:a,[s||e]:r.instance,cleanup:n,invalidate:t};return r.package=o,o}invalidatePackage(e){const t=this.get(e);t&&(t.package=void 0)}async invalidateInstance(e,t=!1){const s=this.get(e);if(!s)return;const r=e;"singleton"===s.scope&&(s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.debounceTimer&&(clearTimeout(s.debounceTimer),s.debounceTimer=void 0),s.controller.abort(),await s.streamOnce.current(),s.streamSerializer.close(),s.stream=void 0,s.streamOnce=new o({retry:!0,throws:!0}),t||(s.streamSerializer=new c,s.controller=new AbortController)),await u(s.cleanupFunctions,r),await u(s.disposeFunctions,r),s.cleanupFunctions=[],s.disposeFunctions=[],"singleton"===s.scope&&(s.buildOnce=new o({retry:!0,throws:!0})),s.instance=void 0,s.error=void 0}},f=class{dependencies=new Map;dependents=new Map;registerNode(e){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set)}removeNode(e){if(!this.hasNode(e))return;const t=this.dependencies.get(e);if(t)for(const s of t)this.dependents.get(s)?.delete(e);const s=this.dependents.get(e);if(s)for(const t of s)this.dependencies.get(t)?.delete(e);this.dependencies.delete(e),this.dependents.delete(e)}hasNode(e){return this.dependencies.has(e)}addDependency(e,t){this.registerNode(e),this.registerNode(t),this.dependencies.get(e).add(t),this.dependents.get(t).add(e)}removeDependency(e,t){this.dependencies.get(e)?.delete(t),this.dependents.get(t)?.delete(e)}getDependencies(e){const t=this.dependencies.get(e);return t?new Set(t):new Set}getDependents(e){const t=this.dependents.get(e);return t?new Set(t):new Set}iterDependents(e){return this.dependents.get(e)??m}setDependencies(e,t){this.registerNode(e);const s=this.dependencies.get(e),r=new Set(t);for(const t of s)r.has(t)||this.removeDependency(e,t);for(const t of r)s.has(t)||this.addDependency(e,t)}wouldCreateCycle(e,t){if(e===t)return[e,t];const s=[t],r=new Set([t]),i=new Map;for(;s.length>0;){const n=s.shift();if(n===e){const s=[];let r=e;for(;void 0!==r&&(s.push(r),r!==t);)r=i.get(r);return s.reverse(),s.unshift(e),s}const a=this.dependencies.get(n);if(a)for(const e of a)r.has(e)||(r.add(e),i.set(e,n),s.push(e))}return null}topologicalSort(){const e=new Map,t=Array.from(this.dependencies.keys());for(const s of t)e.set(s,this.dependencies.get(s)?.size??0);const s=[];for(const[t,r]of e)0===r&&s.push(t);const r=[];for(;s.length>0;){const t=s.shift();r.push(t);const i=this.dependents.get(t);if(i)for(const t of i){const r=(e.get(t)||0)-1;e.set(t,r),0===r&&s.push(t)}}if(r.length!==t.length)throw new Error("Cycle detected in graph; topological sort impossible.");return r}getTransitiveDependencies(e,t=!1){return this.bfs(e,"dependencies",t)}getTransitiveDependents(e,t=!1){return this.bfs(e,"dependents",t)}bfs(e,t,s){const r=new Set,i=new Set,n=[e];i.add(e),s&&r.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;n.length>0;){const e=n.shift(),t=a.get(e);if(t)for(const e of t)i.has(e)||(i.add(e),r.add(e),n.push(e))}return r}getAllNodes(){return Array.from(this.dependencies.keys())}size(){return this.dependencies.size}clear(){this.dependencies.clear(),this.dependents.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const s=Array.from(t).join(", ");return`${String(e)} → [${s||"∅"}]`})).join("\n")}},m=new Set,w=class{graph;constructor(){this.graph=new f}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){return Array.from(this.graph.getDependents(e))}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){return Array.from(this.graph.getDependencies(e))}getTransitiveDependents(e){return new Set(Array.from(this.graph.getTransitiveDependents(e,!1)))}setDependencies(e,t){const s=Array.from(t).map((e=>e));this.graph.setDependencies(e,s)}wouldCreateCycle(e,t,s){if(s?.has(t)){const e=Array.from(s),r=e.indexOf(t),i=e.slice(r);return i.push(t),i}const r=this.graph.wouldCreateCycle(e,t);return r||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()}},v=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];var b=class e extends Error{category;constructor(t,s,r){super(t,{cause:r}),this.name="ArtifactError",this.category=s,Object.setPrototypeOf(this,e.prototype)}},S=class extends b{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system"),this.name="ArtifactNotFoundError"}},_=class extends b{constructor(){super("Build superseded by invalidation","system"),this.name="SupersededBuildError"}},k=(new AbortController).signal,A=class{constructor(e,t,s,r,i){this.registry=e,this.cache=t,this.graph=s,this.store=r,this.observer=i}async build(e,t,s){const r=this.cache.get(e);if("singleton"===r?.scope&&r.buildOnce.done())return this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s);const i=this.registry.getByString(e);if(!i)throw new S(e);const n=t??[];if(n.includes(e))throw new b(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${[...n,e].join(" -> ")}`,"system");n.push(e);let a=r;a||(a=this.createCachedArtifact(i),this.cache.set(e,a));try{if("transient"===a.scope)return this.executeBuild(i,a,n);const r=a;try{await r.buildOnce.do((()=>this.executeBuild(i,r,n)))}catch(r){if(r instanceof _)return this.build(e,t,s);throw r}return r.stream&&r.streamOnce.do(r.stream),this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s)}finally{n.pop()}}async executeBuild(e,t,s){const r=e.key,i=String(r),n="transient"===t.scope;t.buildCount++,"singleton"===t.scope&&(t.activeDebounceMs=e.debounce??0);const a={cleanupFunctions:[],disposeFunctions:[],capturedArtifactDeps:new Set,capturedStateSelectors:[],dependencyVersions:new Map},o=this.buildContext(e,t,s,i,a),c=await this.runWithRetries(e,o,a.dependencyVersions);if(this.commitResult(r,t,n,c,a),n){const e=c.ok?c.value:void 0;return{instance:e,error:c.ok?void 0:c.error,ready:c.ok,[r]:e,cleanup:d(a.cleanupFunctions,i),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${i}"`)}}}buildContext(e,t,s,r,i){const n=e.key,a="transient"===t.scope,{cleanupFunctions:o,disposeFunctions:c,capturedArtifactDeps:h,dependencyVersions:d,capturedStateSelectors:u}=i,l=async(e,t)=>{const i=t?this.computeParamKey(e,t):e;if(i===n)throw new b(`Artifact "${r}" depends on itself.`,"system");const a=this.graph.wouldCreateCycle(n,i);if(a)throw new b(`Adding dependency "${String(i)}" to "${r}" would create a cycle: ${a.join(" -> ")}`,"system");h.add(i);const o=await(t?this.resolveParameterized(e,t):this.build(e,s)),c=this.cache.get(i);return c&&d.set(i,c.version),o},p="singleton"===t.scope?t.controller.signal:k,g=async(e,t)=>{const s=await l(e,t);if(s.error)throw s.error;return s.instance},y=(e,t)=>{const s=function(e,t="."){const s=new Set,r=new Map,i=(e="")=>{if(r.has(e))return r.get(e);const n=new Proxy((()=>{}),{get:(r,n)=>{if("symbol"==typeof n||"then"===n)return;if("valueOf"===n||"toString"===n)throw new Error("Cannot perform logic, arithmetic, or string operations inside a selector.");if(v.includes(n))throw new Error(`Array method .${n}() is not allowed in selectors.`);const a=e?`${e}${t}${n}`:n;return e&&s.delete(e),s.add(a),i(a)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions or methods.")}});return r.set(e,n),n};try{e(i())}catch(e){throw new Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e);return u.push({paths:s,options:t}),e(this.store.get(!0))};return{state:()=>this.store.get(!0),previous:t.instance,signal:p,onCleanup:e=>o.push(e),onDispose:e=>c.push(e),use:e=>e({resolve:l,require:g,select:y}),stream:e=>{if(a)throw new b(`[ArtifactManager] Illegal stream on transient artifact "${r}"`,"system");const s=t,i=async(e,t=void 0)=>{await s.streamSerializer.do((async()=>{void 0!==s.stream&&(s.instance=e,s.error=t,s.version++,this.cache.invalidatePackage(n),await this.processStream(r))}))},o={value:()=>s.instance,get signal(){return s.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>i(e)};s.stream=async()=>{try{const t=await e(o);t&&s.cleanupFunctions.push(t)}catch(e){await i(void 0,e),await this.invalidate(n,!1,!0)}}}}}async runWithRetries(e,t,s){const r=t.signal,i=(e.retries??0)+1;let n=0;for(;n<i;)try{if(r.aborted)throw new _;const a=e.factory(t);let o;if(o=a instanceof Promise?e.timeout?await g(a,e.timeout):await a:a,r.aborted)throw new _;const c=this.detectStaleness(s);if(c){if(n++,s.clear(),n<i)continue;return{ok:!1,error:new b(`Build stale after all retries: dependency "${String(c)}" changed during build.`,"system")}}return{ok:!0,value:o}}catch(e){if(r.aborted||e instanceof _)throw new _;if(e instanceof b)throw e;if(n++,n>=i)return{ok:!1,error:e}}return{ok:!1,error:new Error("Build exhausted retry budget unexpectedly.")}}commitResult(e,t,s,r,i){const{cleanupFunctions:n,disposeFunctions:a,capturedArtifactDeps:o,capturedStateSelectors:c}=i;s||(this.updateDependencyGraph(e,o,c),t.cleanupFunctions=n,t.disposeFunctions=a),r.ok?(t.instance=r.value,t.error=void 0):(t.instance=void 0,t.error=r.error),t.version++,this.cache.invalidatePackage(e)}detectStaleness(e){for(const[t,s]of e){const e=this.cache.get(t);if(e&&e.version!==s)return t}return null}async invalidate(e,t=!1,s=!1){const r=this.cache.get(e);if(!r)return;if("singleton"!==r.scope)return this.executeInvalidation(e,t,s);const i=r;return i.debounceTimer&&(clearTimeout(i.debounceTimer),i.debounceTimer=void 0),!t&&i.activeDebounceMs>0?new Promise(((r,n)=>{i.debounceTimer=setTimeout((()=>{i.debounceTimer=void 0,this.executeInvalidation(e,t,s).then(r).catch(n)}),i.activeDebounceMs)})):this.executeInvalidation(e,t,s)}async executeInvalidation(e,t,s=!1){const r=this.cache.get(e);r&&"singleton"===r.scope&&await r.invalidationSerializer.do((async()=>{r.version++,await this.cache.invalidateInstance(e),await this.cascadeInvalidation(this.graph.iterDependents(e));const i=this.registry.get(e),n=i&&(t||!i.lazy||this.observer.hasWatchers(e))&&!s;n&&await this.build(e).catch((t=>{t instanceof _||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),(n||s)&&this.observer.notify(e)}))}async dispose(e){this.cache.get(e)&&(await this.cache.invalidateInstance(e,!0),this.graph.removeNode(e),this.cache.delete(e))}async processStream(e){await this.cascadeInvalidation(this.graph.iterDependents(e)),this.observer.notify(e)}async cascadeInvalidation(e){if(0===e.size)return;const t=[];for(const s of e)t.push(this.invalidate(s).catch((e=>{console.error(`[ArtifactManager] Cascade failed for "${String(s)}":`,e)})));await Promise.all(t)}updateDependencyGraph(e,t,s){const r=this.cache.get(e);if(!r||"singleton"!==r.scope)return;this.graph.registerNode(e),this.graph.setDependencies(e,t),r.stateDependencies=new Set;for(const{paths:e}of s)for(const t of e)r.stateDependencies.add(t);if(r.stateUnsubscribe&&(r.stateUnsubscribe(),r.stateUnsubscribe=void 0),0===s.length)return;const i=()=>this.invalidate(e),n=new Map;for(const{paths:e,options:t}of s){const s=void 0===t?"undefined":JSON.stringify(t);let r=n.get(s);r||(r={options:t,paths:new Set},n.set(s,r));for(const t of e)r.paths.add(t)}const a=[];for(const{options:e,paths:t}of n.values()){if(0===t.size)continue;const s=Array.from(t);void 0===e?a.push(this.store.watch(s,i)):a.push(this.store.watch(s,i,e))}0===a.length?r.stateUnsubscribe=void 0:1===a.length?r.stateUnsubscribe=a[0]:r.stateUnsubscribe=()=>{for(const e of a)e()}}createCachedArtifact(e){return"transient"===e.scope?{scope:"transient",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0}:{scope:"singleton",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce?e.debounce:0,controller:new AbortController,buildOnce:new o({retry:!0,throws:!0}),streamOnce:new o({retry:!0,throws:!0}),streamSerializer:new c({yieldMode:"microtask"}),invalidationSerializer:new c({yieldMode:"macrotask"})}}resolveStatic(e){if(!this.registry.has(e))throw new S(e);return this.build(e)}async resolveParameterized(e,t){if(!this.registry.has(e))throw new S(String(e));const s=this.registry.get(e);if(!s.paramKey)throw new b(`Artifact "${String(e)}" is not parameterized.`,"external");const r=s.paramKey(t),i=this.registry.getByString(r);if(i&&!i.paramKey&&!i.virtual)throw new b(`Parameterized artifact "${String(e)}" with params ${JSON.stringify(t)} resolves to key "${r}" which is already registered as a static artifact.`,"system");return this.registry.hasString(r)||this.registry.setVirtual(r,{key:r,factory:e=>s.factory({...e,params:t}),scope:s.scope,lazy:s.lazy,timeout:s.timeout,retries:s.retries,debounce:s.debounce,virtual:!0}),this.build(r,void 0,e)}computeParamKey(e,t){const s=this.registry.get(e);if(!s.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);return s.paramKey(t)}},E=class{constructor(e,t,s){this.registry=e,this.cache=t,this.container=s}listeners=new Map;watchers=new Map;watch(e,t=6e4){return this.watchForKey(e,this.registry.get(e),t)}watchParameterized(e,t,s=6e4){const r=this.registry.get(e);if(!r.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);const i=r.paramKey(t);return this.watchForKey(i,r,s,t)}watchForKey(e,t,s,r){const i="transient"===t.scope,n=i?l(e):e,a=this.watchers.get(n);if(a)return a.observer;const o=new h((async()=>{!i&&void 0===r||this.registry.hasString(e)||this.registry.setVirtual(e,{key:e,factory:i?t.factory:e=>t.factory({...e,params:r}),scope:i?"singleton":t.scope,lazy:t.lazy,timeout:t.timeout,retries:t.retries,debounce:t.debounce,paramKey:t.paramKey,virtual:!0})}),(async()=>{i||void 0!==r?(await this.registry.unregister(n).catch((()=>{})),this.cache.delete(n),this.watchers.delete(n)):this.cache.invalidatePackage(n),this.listeners.delete(n)}),{gracePeriod:i&&void 0===r?"sync":s});let c;const d={id:n,get count(){return o.subscribers},get:(t=!1)=>0!==o.subscribers||t?this.cache.package(n,((e,t)=>this.container.invalidate(n,e,t)),e):p,resolve:()=>c||(c=(async()=>{await o.acquire();try{return await this.container.resolve(n)}finally{o.release(),c=void 0}})(),c),subscribe:(e,t=!0)=>{const s=()=>e(d.get());return o.acquire().then((()=>{this.container.resolve(n).then((()=>{this.listeners.has(n)||this.listeners.set(n,new Set),t&&s(),this.listeners.get(n).add(s)}))})).catch((e=>{console.error(`[ArtifactObserver] Resolution failed for "${n}":`,e),this.listeners.get(n)?.add(s)})),()=>{this.listeners.get(n)?.delete(s),o.release()}}};return this.watchers.set(n,{resource:o,observer:d}),d}evictWatcher(e){[e,l(e)].forEach((e=>{const t=this.watchers.get(e);t&&(t.resource.forceCleanup(),this.watchers.delete(e))}))}notify(e){const t=this.listeners.get(e);if(t&&0!==t.size)for(const s of t)try{s()}catch(t){console.error(`[ArtifactObserver] Listener error for "${e}":`,t)}}hasWatchers(e){return this.watchers.has(e)||this.watchers.has(l(e))}getWatcherCount(e){const t=this.watchers.get(e)||this.watchers.get(l(e));return t?.resource.subscribers??0}clear(){this.watchers.clear(),this.listeners.clear()}},D=(e=>(e.Singleton="singleton",e.Transient="transient",e))(D||{}),C=class{artifacts=new Map;register({key:e,factory:t,lazy:s,...r}){const{scope:i,...n}=r,a={key:e,factory:t,scope:r.scope??"singleton",lazy:void 0===s||s,...n};return this.artifacts.set(e,a),()=>this.unregister(e)}setVirtual(e,t){this.artifacts.set(e,t)}get(e){if(!this.has(e))throw new S(String(e));return this.artifacts.get(e)}getByString(e){return this.artifacts.get(e)}has(e){return this.artifacts.has(e)}hasString(e){return this.artifacts.has(e)}async unregister(e){this.artifacts.has(e)&&this.artifacts.delete(e)}size(){return this.artifacts.size}keys(){return Array.from(this.artifacts.keys())}clear(){this.artifacts.clear()}};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 C,this.cache=new y,this.graph=new w,this.observer=new E(this.registry,this.cache,this),this.manager=new A(this.registry,this.cache,this.graph,this.store,this.observer)}debugInfo(){const e=[];return this.registry.keys().forEach((t=>{const s=t,r=this.registry.get(s),i=this.cache.get(s);if(!r)return;let n="idle";i&&("singleton"===i.scope&&void 0!==i.debounceTimer?n="debouncing":"singleton"===i.scope&&i.buildOnce.running()?n="building":i.error?n="error":void 0!==i.instance&&(n="active")),e.push({id:s,scope:r.scope??"singleton",status:n,dependencies:this.graph.getDependencies(s).map((e=>String(e))),dependents:this.graph.getDependents(s).map((e=>String(e))),stateDependencies:"singleton"===i?.scope?Array.from(i.stateDependencies):[],buildCount:i?.buildCount??0})})),e}register(e){const{key:t}=e,s=t;this.registry.has(t)&&(console.warn(`[ArtifactContainer] Overwriting "${s}".`),this.manager.dispose(t).catch((e=>{console.error(`[ArtifactContainer] Failed to dispose existing artifact "${s}":`,e)}))),this.registry.register(e),this.graph.registerNode(t);const r=e.scope??"singleton";return(e.lazy??!0)||"singleton"!==r||this.resolve(t).catch((e=>{console.error(`[ArtifactContainer] Eager load failed for "${s}":`,e)})),()=>this.unregister(t)}has(e){return this.registry.has(e)}async unregister(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;await this.manager.dispose(s),await this.registry.unregister(s),this.observer.evictWatcher(s)}async resolve(e,t){return void 0===t?this.manager.resolveStatic(e):this.manager.resolveParameterized(e,t)}async require(e,t){const s=await this.resolve(e,t);if(s.error)throw s.error;return s.instance}watch(e,t,s){return void 0===t?this.observer.watch(e,s):this.observer.watchParameterized(e,t,s)}peek(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;return this.cache.get(s)?.instance}async invalidate(e,t){const s=t?.params,r=t?.replace??!1,i=void 0!==s?this.manager.computeParamKey(e,s):e;return this.manager.invalidate(i,r)}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=D;
1
+ "use strict";var e={VALIDATION_FAILED:{code:"VAL-001",name:"VALIDATION_FAILED",description:"Input validation failed due to one or more invalid fields",category:"validation",httpStatus:400,logLevel:"warn"},REQUIRED_FIELD_MISSING:{code:"VAL-002",name:"REQUIRED_FIELD_MISSING",description:"A required field was not provided in the request",category:"validation",httpStatus:400,logLevel:"warn"},INVALID_FORMAT:{code:"VAL-003",name:"INVALID_FORMAT",description:"Field value does not match expected format",category:"validation",httpStatus:400,logLevel:"warn"},NOT_FOUND:{code:"DB-001-NF",name:"NOT_FOUND",description:"The requested resource could not be found",category:"database",httpStatus:404,logLevel:"info",action:"Verify the resource identifier exists before accessing"},DUPLICATE_KEY:{code:"DB-002-DUP",name:"DUPLICATE_KEY",description:"A unique constraint violation occurred",category:"database",httpStatus:409,logLevel:"warn",action:"Check if the resource already exists before creation"},RESOURCE_LOCKED:{code:"DB-003-LOCK",name:"RESOURCE_LOCKED",description:"The resource is currently locked by another operation",category:"database",httpStatus:409,logLevel:"warn",action:"Retry the operation after a brief delay"},PERMISSION_DENIED:{code:"AUTH-001-DENIED",name:"PERMISSION_DENIED",description:"The authenticated user lacks permission for this operation",category:"auth",httpStatus:403,logLevel:"warn",action:"Check user roles and permissions"},UNAUTHENTICATED:{code:"AUTH-002-UNAUTH",name:"UNAUTHENTICATED",description:"Authentication is required for this operation",category:"auth",httpStatus:401,logLevel:"info",action:"Provide valid authentication credentials"},INVALID_COMMAND:{code:"BUS-001",name:"INVALID_COMMAND",description:"The command or operation is invalid for the current state",category:"business",httpStatus:400,logLevel:"warn"},OPERATION_ABORTED:{code:"BUS-002-ABORT",name:"OPERATION_ABORTED",description:"The operation was explicitly aborted",category:"business",httpStatus:409,logLevel:"info"},INTERNAL_ERROR:{code:"SYS-001",name:"INTERNAL_ERROR",description:"An unexpected internal error occurred",category:"system",httpStatus:500,logLevel:"error",action:"Check system logs for stack traces and diagnostic information"},BACKEND_ERROR:{code:"SYS-002",name:"BACKEND_ERROR",description:"An error occurred in a backend service",category:"system",httpStatus:502,logLevel:"error"},CONCURRENCY_ERROR:{code:"CON-001",name:"CONCURRENCY_ERROR",description:"A concurrency conflict occurred during the operation",category:"concurrency",httpStatus:409,logLevel:"warn",action:"Retry the operation with updated data"}},t=new Map;var s=class s extends Error{code;codeMetadata;severity;path;operation;issues;cause;constructor(r){const i={...function(s){const r=Object.values(e).find((e=>e.code===s));if(r)return r;return t.get(s)||{code:s,name:s.replace(/-/g,"_"),description:`Unknown error: ${s}`,category:"custom",httpStatus:500,logLevel:"error",action:"Check if this error code is properly registered or handle as unknown error"}}(r.code),...r.metadata,code:r.code};super(r.message??i.description),this.name="SystemError",this.code=r.code,this.codeMetadata=i,this.severity=r.severity??"error",this.path=r.path,this.operation=r.operation,this.issues=r.issues??[],this.cause=r.cause,Object.setPrototypeOf(this,s.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,s)}withPath(e){return new s({code:this.code,message:this.message,severity:this.severity,path:e,operation:this.operation,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withOperation(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:e,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withIssue(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,e],cause:this.cause,metadata:this.codeMetadata})}withIssues(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,...e],cause:this.cause,metadata:this.codeMetadata})}withCause(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:this.issues,cause:e,metadata:this.codeMetadata})}getHttpStatus(){return this.codeMetadata.httpStatus}toLogEntry(){return{name:this.name,code:this.code,category:this.codeMetadata.category,message:this.message,path:this.path,operation:this.operation,issues:this.issues,cause:this.cause instanceof Error?this.cause.message:this.cause,stack:this.stack,timestamp:(new Date).toISOString()}}toString(){let e=`[${this.code}] ${this.message} (${this.codeMetadata.category})`;return this.path&&(e+=` at '${this.path}'`),this.operation&&(e+=` during '${this.operation}'`),this.issues.length>0&&(e+="\nIssues:\n"+this.issues.map(((e,t)=>` ${t+1}. ${e.message} [${e.code}]`)).join("\n")),this.cause&&(e+=`\nCause: ${this.cause instanceof Error?this.cause.message:String(this.cause)}`),e}},r=class e extends s{constructor(t,s){super({code:"SYNC_ERROR",message:t,cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},i=class e extends r{constructor(t){super(`[ArtifactContainer] Operation timed out: ${t}`),this.name="TimeoutError",Object.setPrototypeOf(this,e.prototype)}},n=class e extends r{constructor(t){super("[Serializer] The serializer has been marked as done!",t),this.name="SerializerExecutionDone",Object.setPrototypeOf(this,e.prototype)}},a=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 s=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await s;let r;await Promise.race([s.then((()=>clearTimeout(r))),new Promise(((s,n)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),n(new i("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},o=class{mutex=new a({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}resolve(e){if(this._done)throw new Error("Cannot resolve: operation is already completed.");if(this.running())throw new Error("Cannot resolve: operation is currently running.");this._value=e,this._done=!0}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,s="Operation timed out"){if(null==t)return e;let r;return Promise.race([e.then((e=>(clearTimeout(r),e))),new Promise(((e,n)=>{r=setTimeout((()=>n(new i(s))),t)}))])}},c=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new a({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new n};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,r=null;try{if(this._done)throw new n;r=await e(),this._lastValue=r,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:r,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},h=class{constructor(e,t,s={}){this.factory=e,this.onCleanup=t,this.options=s}_count=0;init=new o({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}};function d(e,t){if(!e.length)return;const s=e.slice(),r=t?`[${t}]`:"[ArtifactCleanup]";return async()=>{for(let e=s.length-1;e>=0;e--)try{await s[e]()}catch(t){console.error(`${r} Cleanup error at index ${e}:`,t)}}}async function u(e,t){const s=t?`[${t}]`:"[ArtifactCleanup]";for(let t=e.length-1;t>=0;t--)try{await e[t]()}catch(e){console.error(`${s} Cleanup error at index ${t}:`,e)}}function l(e){return`${e}__watched`}var p=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function g(e,t){let s;const r=new Promise(((e,r)=>{s=setTimeout((()=>r(new Error(`Timeout: ${t}ms`))),t)}));try{return Promise.race([e,r])}finally{clearTimeout(s)}}async function f(e){const t=(new TextEncoder).encode(e),s=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(s)).map((e=>e.toString(16).padStart(2,"0"))).join("")}var y=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,s){const r=this.get(e);if(!r)return p;if(r.package)return r.package;const i=e,n=d(r.cleanupFunctions,i),a="singleton"!==r.scope||void 0!==r.instance,o={instance:r.instance,error:r.error,ready:a,[s||e]:r.instance,cleanup:n,invalidate:t};return r.package=o,o}invalidatePackage(e){const t=this.get(e);t&&(t.package=void 0)}async invalidateInstance(e,t=!1){const s=this.get(e);if(!s)return;const r=e;"singleton"===s.scope&&(s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.debounceTimer&&(clearTimeout(s.debounceTimer),s.debounceTimer=void 0),s.controller.abort(),await s.streamOnce.current(),s.streamSerializer.close(),s.stream=void 0,s.streamOnce=new o({retry:!0,throws:!0}),t||(s.streamSerializer=new c,s.controller=new AbortController)),await u(s.cleanupFunctions,r),await u(s.disposeFunctions,r),s.cleanupFunctions=[],s.disposeFunctions=[],"singleton"===s.scope&&(s.buildOnce=new o({retry:!0,throws:!0})),s.instance=void 0,s.error=void 0}},w=class{dependencies=new Map;dependents=new Map;registerNode(e){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set)}removeNode(e){if(!this.hasNode(e))return;const t=this.dependencies.get(e);if(t)for(const s of t)this.dependents.get(s)?.delete(e);const s=this.dependents.get(e);if(s)for(const t of s)this.dependencies.get(t)?.delete(e);this.dependencies.delete(e),this.dependents.delete(e)}hasNode(e){return this.dependencies.has(e)}addDependency(e,t){this.registerNode(e),this.registerNode(t),this.dependencies.get(e).add(t),this.dependents.get(t).add(e)}removeDependency(e,t){this.dependencies.get(e)?.delete(t),this.dependents.get(t)?.delete(e)}getDependencies(e){const t=this.dependencies.get(e);return t?new Set(t):new Set}getDependents(e){const t=this.dependents.get(e);return t?new Set(t):new Set}iterDependents(e){return this.dependents.get(e)??m}setDependencies(e,t){this.registerNode(e);const s=this.dependencies.get(e),r=new Set(t);for(const t of s)r.has(t)||this.removeDependency(e,t);for(const t of r)s.has(t)||this.addDependency(e,t)}wouldCreateCycle(e,t){if(e===t)return[e,t];const s=[t],r=new Set([t]),i=new Map;for(;s.length>0;){const n=s.shift();if(n===e){const s=[];let r=e;for(;void 0!==r&&(s.push(r),r!==t);)r=i.get(r);return s.reverse(),s.unshift(e),s}const a=this.dependencies.get(n);if(a)for(const e of a)r.has(e)||(r.add(e),i.set(e,n),s.push(e))}return null}topologicalSort(){const e=new Map,t=Array.from(this.dependencies.keys());for(const s of t)e.set(s,this.dependencies.get(s)?.size??0);const s=[];for(const[t,r]of e)0===r&&s.push(t);const r=[];for(;s.length>0;){const t=s.shift();r.push(t);const i=this.dependents.get(t);if(i)for(const t of i){const r=(e.get(t)||0)-1;e.set(t,r),0===r&&s.push(t)}}if(r.length!==t.length)throw new Error("Cycle detected in graph; topological sort impossible.");return r}getTransitiveDependencies(e,t=!1){return this.bfs(e,"dependencies",t)}getTransitiveDependents(e,t=!1){return this.bfs(e,"dependents",t)}bfs(e,t,s){const r=new Set,i=new Set,n=[e];i.add(e),s&&r.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;n.length>0;){const e=n.shift(),t=a.get(e);if(t)for(const e of t)i.has(e)||(i.add(e),r.add(e),n.push(e))}return r}getAllNodes(){return Array.from(this.dependencies.keys())}size(){return this.dependencies.size}clear(){this.dependencies.clear(),this.dependents.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const s=Array.from(t).join(", ");return`${String(e)} → [${s||"∅"}]`})).join("\n")}},m=new Set,v=class{graph;constructor(){this.graph=new w}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){return Array.from(this.graph.getDependents(e))}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){return Array.from(this.graph.getDependencies(e))}getTransitiveDependents(e){return new Set(Array.from(this.graph.getTransitiveDependents(e,!1)))}setDependencies(e,t){const s=Array.from(t).map((e=>e));this.graph.setDependencies(e,s)}wouldCreateCycle(e,t,s){if(s?.has(t)){const e=Array.from(s),r=e.indexOf(t),i=e.slice(r);return i.push(t),i}const r=this.graph.wouldCreateCycle(e,t);return r||null}hasNode(e){return this.graph.hasNode(e)}getAllNodes(){return this.graph.getAllNodes()}clear(){this.graph.clear()}size(){return this.graph.size()}toDebugString(){return this.graph.toDebugString()}},b=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];var S=class e extends Error{category;constructor(t,s,r){super(t,{cause:r}),this.name="ArtifactError",this.category=s,Object.setPrototypeOf(this,e.prototype)}},k=class extends S{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system"),this.name="ArtifactNotFoundError"}},_=class extends S{constructor(){super("Build superseded by invalidation","system"),this.name="SupersededBuildError"}},A=class extends S{constructor(e){super(e,"system"),this.name="InvalidImportError"}},E=class extends S{constructor(e){super(`Artifact "${e}" instance is not JSON-serializable (POJO are required for persistence)`,"system"),this.name="InvalidExportOperationError"}},D=(new AbortController).signal,C=class{constructor(e,t,s,r,i){this.registry=e,this.cache=t,this.graph=s,this.store=r,this.observer=i}async build(e,t,s){const r=this.cache.get(e);if("singleton"===r?.scope&&r.buildOnce.done())return this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s);const i=this.registry.getByString(e);if(!i)throw new k(e);const n=t??[];if(n.includes(e))throw new S(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${[...n,e].join(" -> ")}`,"system");n.push(e);let a=r;a||(a=this.createCachedArtifact(i),this.cache.set(e,a));try{if("transient"===a.scope)return this.executeBuild(i,a,n);const r=a;try{await r.buildOnce.do((()=>this.executeBuild(i,r,n)))}catch(r){if(r instanceof _)return this.build(e,t,s);throw r}return r.stream&&r.streamOnce.do(r.stream),this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s)}finally{n.pop()}}async executeBuild(e,t,s){const r=e.key,i=String(r),n="transient"===t.scope;t.buildCount++,"singleton"===t.scope&&(t.activeDebounceMs=e.debounce??0);const a={cleanupFunctions:[],disposeFunctions:[],capturedArtifactDeps:new Set,capturedStateSelectors:[],dependencyVersions:new Map},o=this.buildContext(e,t,s,i,a),c=await this.runWithRetries(e,o,a.dependencyVersions);if(this.commitResult(r,t,n,c,a),n){const e=c.ok?c.value:void 0;return{instance:e,error:c.ok?void 0:c.error,ready:c.ok,[r]:e,cleanup:d(a.cleanupFunctions,i),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${i}"`)}}}buildContext(e,t,s,r,i){const n=e.key,a="transient"===t.scope,{cleanupFunctions:o,disposeFunctions:c,capturedArtifactDeps:h,dependencyVersions:d,capturedStateSelectors:u}=i,l=async(e,t)=>{const i=t?this.computeParamKey(e,t):e;if(i===n)throw new S(`Artifact "${r}" depends on itself.`,"system");const a=this.graph.wouldCreateCycle(n,i);if(a)throw new S(`Adding dependency "${String(i)}" to "${r}" would create a cycle: ${a.join(" -> ")}`,"system");h.add(i);const o=await(t?this.resolveParameterized(e,t):this.build(e,s)),c=this.cache.get(i);return c&&d.set(i,c.version),o},p="singleton"===t.scope?t.controller.signal:D,g=async(e,t)=>{const s=await l(e,t);if(s.error)throw s.error;return s.instance},f=(e,t)=>{const s=function(e,t="."){const s=new Set,r=new Map,i=(e="")=>{if(r.has(e))return r.get(e);const n=new Proxy((()=>{}),{get:(r,n)=>{if("symbol"==typeof n||"then"===n)return;if("valueOf"===n||"toString"===n)throw new Error("Cannot perform logic, arithmetic, or string operations inside a selector.");if(b.includes(n))throw new Error(`Array method .${n}() is not allowed in selectors.`);const a=e?`${e}${t}${n}`:n;return e&&s.delete(e),s.add(a),i(a)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions or methods.")}});return r.set(e,n),n};try{e(i())}catch(e){throw new Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e);return u.push({paths:s,options:t}),e(this.store.get(!0))};return{state:()=>this.store.get(!0),previous:t.instance,signal:p,onCleanup:e=>o.push(e),onDispose:e=>c.push(e),use:e=>e({resolve:l,require:g,select:f}),stream:e=>{if(a)throw new S(`[ArtifactManager] Illegal stream on transient artifact "${r}"`,"system");const s=t,i=async(e,t=void 0)=>{await s.streamSerializer.do((async()=>{void 0!==s.stream&&(s.instance=e,s.error=t,s.version++,this.cache.invalidatePackage(n),await this.processStream(r))}))},o={value:()=>s.instance,get signal(){return s.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>i(e)};s.stream=async()=>{try{const t=await e(o);t&&s.cleanupFunctions.push(t)}catch(e){await i(void 0,e),await this.invalidate(n,!1,!0)}}}}}async runWithRetries(e,t,s){const r=t.signal,i=(e.retries??0)+1;let n=0;for(;n<i;)try{if(r.aborted)throw new _;const a=e.factory(t);let o;if(o=a instanceof Promise?e.timeout?await g(a,e.timeout):await a:a,r.aborted)throw new _;const c=this.detectStaleness(s);if(c){if(n++,s.clear(),n<i)continue;return{ok:!1,error:new S(`Build stale after all retries: dependency "${String(c)}" changed during build.`,"system")}}return{ok:!0,value:o}}catch(e){if(r.aborted||e instanceof _)throw new _;if(e instanceof S)throw e;if(n++,n>=i)return{ok:!1,error:e}}return{ok:!1,error:new Error("Build exhausted retry budget unexpectedly.")}}commitResult(e,t,s,r,i){const{cleanupFunctions:n,disposeFunctions:a,capturedArtifactDeps:o,capturedStateSelectors:c}=i;s||(this.updateDependencyGraph(e,o,c),t.cleanupFunctions=n,t.disposeFunctions=a,t.artifactDependencies=new Set(o),t.stateGroups=c.map((({paths:e,options:t})=>({paths:e,options:t})))),r.ok?(t.instance=r.value,t.error=void 0):(t.instance=void 0,t.error=r.error),t.version++,this.cache.invalidatePackage(e)}detectStaleness(e){for(const[t,s]of e){const e=this.cache.get(t);if(e&&e.version!==s)return t}return null}async invalidate(e,t=!1,s=!1){const r=this.cache.get(e);if(!r)return;if("singleton"!==r.scope)return this.executeInvalidation(e,t,s);const i=r;return i.debounceTimer&&(clearTimeout(i.debounceTimer),i.debounceTimer=void 0),!t&&i.activeDebounceMs>0?new Promise(((r,n)=>{i.debounceTimer=setTimeout((()=>{i.debounceTimer=void 0,this.executeInvalidation(e,t,s).then(r).catch(n)}),i.activeDebounceMs)})):this.executeInvalidation(e,t,s)}async executeInvalidation(e,t,s=!1){const r=this.cache.get(e);r&&"singleton"===r.scope&&await r.invalidationSerializer.do((async()=>{r.version++,await this.cache.invalidateInstance(e),await this.cascadeInvalidation(this.graph.iterDependents(e));const i=this.registry.get(e),n=i&&(t||!i.lazy||this.observer.hasWatchers(e))&&!s;n&&await this.build(e).catch((t=>{t instanceof _||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),(n||s)&&this.observer.notify(e)}))}async dispose(e){this.cache.get(e)&&(await this.cache.invalidateInstance(e,!0),this.graph.removeNode(e),this.cache.delete(e))}async processStream(e){await this.cascadeInvalidation(this.graph.iterDependents(e)),this.observer.notify(e)}async cascadeInvalidation(e){if(0===e.size)return;const t=[];for(const s of e)t.push(this.invalidate(s).catch((e=>{console.error(`[ArtifactManager] Cascade failed for "${String(s)}":`,e)})));await Promise.all(t)}updateDependencyGraph(e,t,s){const r=this.cache.get(e);if(!r||"singleton"!==r.scope)return;this.graph.registerNode(e),this.graph.setDependencies(e,t),r.stateDependencies=new Set;for(const{paths:e}of s)for(const t of e)r.stateDependencies.add(t);if(r.stateUnsubscribe&&(r.stateUnsubscribe(),r.stateUnsubscribe=void 0),0===s.length)return;const i=()=>this.invalidate(e),n=new Map;for(const{paths:e,options:t}of s){const s=void 0===t?"undefined":JSON.stringify(t);let r=n.get(s);r||(r={options:t,paths:new Set},n.set(s,r));for(const t of e)r.paths.add(t)}const a=[];for(const{options:e,paths:t}of n.values()){if(0===t.size)continue;const s=Array.from(t);void 0===e?a.push(this.store.watch(s,i)):a.push(this.store.watch(s,i,e))}0===a.length?r.stateUnsubscribe=void 0:1===a.length?r.stateUnsubscribe=a[0]:r.stateUnsubscribe=()=>{for(const e of a)e()}}createCachedArtifact(e){return"transient"===e.scope?{scope:"transient",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0}:{scope:"singleton",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce?e.debounce:0,controller:new AbortController,buildOnce:new o({retry:!0,throws:!0}),streamOnce:new o({retry:!0,throws:!0}),streamSerializer:new c({yieldMode:"microtask"}),invalidationSerializer:new c({yieldMode:"macrotask"}),stateGroups:[],artifactDependencies:new Set}}resolveStatic(e){if(!this.registry.has(e))throw new k(e);return this.build(e)}async resolveParameterized(e,t){if(!this.registry.has(e))throw new k(String(e));const s=this.registry.get(e);if(!s.paramKey)throw new S(`Artifact "${String(e)}" is not parameterized.`,"external");const r=s.paramKey(t),i=this.registry.getByString(r);if(i&&!i.paramKey&&!i.virtual)throw new S(`Parameterized artifact "${String(e)}" with params ${JSON.stringify(t)} resolves to key "${r}" which is already registered as a static artifact.`,"system");return this.registry.hasString(r)||this.registry.setVirtual(r,{key:r,factory:e=>s.factory({...e,params:t}),scope:s.scope,lazy:s.lazy,timeout:s.timeout,retries:s.retries,debounce:s.debounce,virtual:!0}),this.build(r,void 0,e)}computeParamKey(e,t){const s=this.registry.get(e);if(!s.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);return s.paramKey(t)}},O=class{constructor(e,t,s){this.registry=e,this.cache=t,this.container=s}listeners=new Map;watchers=new Map;watch(e,t=6e4){return this.watchForKey(e,this.registry.get(e),t)}watchParameterized(e,t,s=6e4){const r=this.registry.get(e);if(!r.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);const i=r.paramKey(t);return this.watchForKey(i,r,s,t)}watchForKey(e,t,s,r){const i="transient"===t.scope,n=i?l(e):e,a=this.watchers.get(n);if(a)return a.observer;const o=new h((async()=>{!i&&void 0===r||this.registry.hasString(e)||this.registry.setVirtual(e,{key:e,factory:i?t.factory:e=>t.factory({...e,params:r}),scope:i?"singleton":t.scope,lazy:t.lazy,timeout:t.timeout,retries:t.retries,debounce:t.debounce,paramKey:t.paramKey,virtual:!0})}),(async()=>{i||void 0!==r?(await this.registry.unregister(n).catch((()=>{})),this.cache.delete(n),this.watchers.delete(n)):this.cache.invalidatePackage(n),this.listeners.delete(n)}),{gracePeriod:i&&void 0===r?"sync":s});let c;const d={id:n,get count(){return o.subscribers},get:(t=!1)=>0!==o.subscribers||t?this.cache.package(n,((e,t)=>this.container.invalidate(n,e,t)),e):p,resolve:()=>c||(c=(async()=>{await o.acquire();try{return await this.container.resolve(n)}finally{o.release(),c=void 0}})(),c),subscribe:(e,t=!0)=>{const s=()=>e(d.get());return o.acquire().then((()=>{this.container.resolve(n).then((()=>{this.listeners.has(n)||this.listeners.set(n,new Set),t&&s(),this.listeners.get(n).add(s)}))})).catch((e=>{console.error(`[ArtifactObserver] Resolution failed for "${n}":`,e),this.listeners.get(n)?.add(s)})),()=>{this.listeners.get(n)?.delete(s),o.release()}}};return this.watchers.set(n,{resource:o,observer:d}),d}evictWatcher(e){[e,l(e)].forEach((e=>{const t=this.watchers.get(e);t&&(t.resource.forceCleanup(),this.watchers.delete(e))}))}notify(e){const t=this.listeners.get(e);if(t&&0!==t.size)for(const s of t)try{s()}catch(t){console.error(`[ArtifactObserver] Listener error for "${e}":`,t)}}hasWatchers(e){return this.watchers.has(e)||this.watchers.has(l(e))}getWatcherCount(e){const t=this.watchers.get(e)||this.watchers.get(l(e));return t?.resource.subscribers??0}clear(){this.watchers.clear(),this.listeners.clear()}},T=(e=>(e.Singleton="singleton",e.Transient="transient",e))(T||{}),M=class{artifacts=new Map;register({key:e,factory:t,lazy:s,...r}){const{scope:i,...n}=r,a={key:e,factory:t,scope:r.scope??"singleton",lazy:void 0===s||s,...n};return this.artifacts.set(e,a),()=>this.unregister(e)}setVirtual(e,t){this.artifacts.set(e,t)}get(e){if(!this.has(e))throw new k(String(e));return this.artifacts.get(e)}getByString(e){return this.artifacts.get(e)}has(e){return this.artifacts.has(e)}hasString(e){return this.artifacts.has(e)}async unregister(e){this.artifacts.has(e)&&this.artifacts.delete(e)}size(){return this.artifacts.size}keys(){return Array.from(this.artifacts.keys())}clear(){this.artifacts.clear()}};exports.ArtifactContainer=class e{registry;cache;graph;manager;observer;store;constructor(e){this.store={watch:(...t)=>e.watch(...t),get:()=>e.get(!0),set:(...t)=>e.set(...t),subset:(...t)=>e.subset(...t)},this.registry=new M,this.cache=new y,this.graph=new v,this.observer=new O(this.registry,this.cache,this),this.manager=new C(this.registry,this.cache,this.graph,this.store,this.observer)}debugInfo(){const e=[];return this.registry.keys().forEach((t=>{const s=t,r=this.registry.get(s),i=this.cache.get(s);if(!r)return;let n="idle";i&&("singleton"===i.scope&&void 0!==i.debounceTimer?n="debouncing":"singleton"===i.scope&&i.buildOnce.running()?n="building":i.error?n="error":void 0!==i.instance&&(n="active")),e.push({id:s,scope:r.scope??"singleton",status:n,dependencies:this.graph.getDependencies(s).map((e=>String(e))),dependents:this.graph.getDependents(s).map((e=>String(e))),stateDependencies:"singleton"===i?.scope?Array.from(i.stateDependencies):[],buildCount:i?.buildCount??0})})),e}register(e){const{key:t}=e,s=t;this.registry.has(t)&&(console.warn(`[ArtifactContainer] Overwriting "${s}".`),this.manager.dispose(t).catch((e=>{console.error(`[ArtifactContainer] Failed to dispose existing artifact "${s}":`,e)}))),this.registry.register(e),this.graph.registerNode(t);const r=e.scope??"singleton";return(e.lazy??!0)||"singleton"!==r||this.resolve(t).catch((e=>{console.error(`[ArtifactContainer] Eager load failed for "${s}":`,e)})),()=>this.unregister(t)}has(e){return this.registry.has(e)}async unregister(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;await this.manager.dispose(s),await this.registry.unregister(s),this.observer.evictWatcher(s)}async resolve(e,t){return void 0===t?this.manager.resolveStatic(e):this.manager.resolveParameterized(e,t)}async require(e,t){const s=await this.resolve(e,t);if(s.error)throw s.error;return s.instance}watch(e,t,s){return void 0===t?this.observer.watch(e,s):this.observer.watchParameterized(e,t,s)}peek(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;return this.cache.get(s)?.instance}async invalidate(e,t){const s=t?.params,r=t?.replace??!1,i=void 0!==s?this.manager.computeParamKey(e,s):e;return this.manager.invalidate(i,r)}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()}async export(){const e=[];for(const t of this.cache.keys()){const s=this.cache.get(t);if(!s||"singleton"!==s.scope)continue;if(void 0===s.instance)continue;const r=new Set;for(const e of s.stateGroups)for(const t of e.paths)r.add(t);const i=Array.from(r).sort(),n=this.store.subset(i),a=await f(JSON.stringify(n,Object.keys(n).sort()));let o;try{o=structuredClone(s.instance)}catch(e){throw new E(t)}e.push({key:t,instance:o,state:{groups:s.stateGroups.map((e=>({paths:e.paths,options:e.options}))),hash:a},dependencies:Array.from(s.artifactDependencies)})}const t={...{version:"1.0",timestamp:Date.now(),artifacts:e}},s=JSON.stringify(t),r=await f(s);return{...t,checksum:r}}async restore(e){const{checksum:t,...s}=e;if(await f(JSON.stringify(s))!==t)throw new A("Bundle checksum mismatch – data corrupted");if("1.0"!==e.version)throw new A(`Unsupported bundle version: ${e.version}`);const r=new Map;for(const t of e.artifacts)r.set(t.key,t);const i=new Set,n=new Map;for(const t of e.artifacts)for(const e of t.dependencies)n.has(e)||n.set(e,new Set),n.get(e).add(t.key);const a=async e=>{const t=new Set;for(const s of e.state.groups)for(const e of s.paths)t.add(e);const s=Array.from(t).sort(),r=this.store.subset(s);return f(JSON.stringify(r,Object.keys(r).sort()))};for(const t of e.artifacts){await a(t)!==t.state.hash&&i.add(t.key)}const h=Array.from(i);for(;h.length;){const e=h.shift(),t=n.get(e);if(t)for(const e of t)i.has(e)||(i.add(e),h.push(e))}for(const t of e.artifacts){if(i.has(t.key))continue;this.cache.get(t.key)&&await this.cache.invalidateInstance(t.key,!1);const e={scope:"singleton",instance:t.instance,error:void 0,version:1,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set(t.state.groups.flatMap((e=>e.paths))),activeDebounceMs:0,buildOnce:new o({retry:!0,throws:!0}),streamSerializer:new c({yieldMode:"microtask"}),invalidationSerializer:new c({yieldMode:"macrotask"}),stateUnsubscribe:void 0,debounceTimer:void 0,controller:new AbortController,streamOnce:new o({retry:!0,throws:!0}),stream:void 0,stateGroups:t.state.groups,artifactDependencies:new Set(t.dependencies)};e.buildOnce.resolve(t.instance),this.cache.set(t.key,e);const s=[];for(const e of t.state.groups){const r=this.store.watch(e.paths,(()=>this.invalidate(t.key)),e.options);s.push(r)}e.stateUnsubscribe=()=>{for(const e of s)e()},this.graph.setDependencies(t.key,t.dependencies)}}static async from(t){const s=new e(t.store);if(t.bundle){if("object"!=typeof t.bundle||!t.bundle.version||!Array.isArray(t.bundle.artifacts))throw new A("Invalid bundle: missing version or artifacts array");await s.restore(t.bundle)}for(const e of t.templates)s.register(e);return s}},exports.ArtifactScopes=T;
package/index.mjs CHANGED
@@ -1 +1 @@
1
- var e={VALIDATION_FAILED:{code:"VAL-001",name:"VALIDATION_FAILED",description:"Input validation failed due to one or more invalid fields",category:"validation",httpStatus:400,logLevel:"warn"},REQUIRED_FIELD_MISSING:{code:"VAL-002",name:"REQUIRED_FIELD_MISSING",description:"A required field was not provided in the request",category:"validation",httpStatus:400,logLevel:"warn"},INVALID_FORMAT:{code:"VAL-003",name:"INVALID_FORMAT",description:"Field value does not match expected format",category:"validation",httpStatus:400,logLevel:"warn"},NOT_FOUND:{code:"DB-001-NF",name:"NOT_FOUND",description:"The requested resource could not be found",category:"database",httpStatus:404,logLevel:"info",action:"Verify the resource identifier exists before accessing"},DUPLICATE_KEY:{code:"DB-002-DUP",name:"DUPLICATE_KEY",description:"A unique constraint violation occurred",category:"database",httpStatus:409,logLevel:"warn",action:"Check if the resource already exists before creation"},RESOURCE_LOCKED:{code:"DB-003-LOCK",name:"RESOURCE_LOCKED",description:"The resource is currently locked by another operation",category:"database",httpStatus:409,logLevel:"warn",action:"Retry the operation after a brief delay"},PERMISSION_DENIED:{code:"AUTH-001-DENIED",name:"PERMISSION_DENIED",description:"The authenticated user lacks permission for this operation",category:"auth",httpStatus:403,logLevel:"warn",action:"Check user roles and permissions"},UNAUTHENTICATED:{code:"AUTH-002-UNAUTH",name:"UNAUTHENTICATED",description:"Authentication is required for this operation",category:"auth",httpStatus:401,logLevel:"info",action:"Provide valid authentication credentials"},INVALID_COMMAND:{code:"BUS-001",name:"INVALID_COMMAND",description:"The command or operation is invalid for the current state",category:"business",httpStatus:400,logLevel:"warn"},OPERATION_ABORTED:{code:"BUS-002-ABORT",name:"OPERATION_ABORTED",description:"The operation was explicitly aborted",category:"business",httpStatus:409,logLevel:"info"},INTERNAL_ERROR:{code:"SYS-001",name:"INTERNAL_ERROR",description:"An unexpected internal error occurred",category:"system",httpStatus:500,logLevel:"error",action:"Check system logs for stack traces and diagnostic information"},BACKEND_ERROR:{code:"SYS-002",name:"BACKEND_ERROR",description:"An error occurred in a backend service",category:"system",httpStatus:502,logLevel:"error"},CONCURRENCY_ERROR:{code:"CON-001",name:"CONCURRENCY_ERROR",description:"A concurrency conflict occurred during the operation",category:"concurrency",httpStatus:409,logLevel:"warn",action:"Retry the operation with updated data"}},t=new Map;var s=class s extends Error{code;codeMetadata;severity;path;operation;issues;cause;constructor(r){const i={...function(s){const r=Object.values(e).find((e=>e.code===s));if(r)return r;return t.get(s)||{code:s,name:s.replace(/-/g,"_"),description:`Unknown error: ${s}`,category:"custom",httpStatus:500,logLevel:"error",action:"Check if this error code is properly registered or handle as unknown error"}}(r.code),...r.metadata,code:r.code};super(r.message??i.description),this.name="SystemError",this.code=r.code,this.codeMetadata=i,this.severity=r.severity??"error",this.path=r.path,this.operation=r.operation,this.issues=r.issues??[],this.cause=r.cause,Object.setPrototypeOf(this,s.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,s)}withPath(e){return new s({code:this.code,message:this.message,severity:this.severity,path:e,operation:this.operation,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withOperation(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:e,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withIssue(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,e],cause:this.cause,metadata:this.codeMetadata})}withIssues(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,...e],cause:this.cause,metadata:this.codeMetadata})}withCause(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:this.issues,cause:e,metadata:this.codeMetadata})}getHttpStatus(){return this.codeMetadata.httpStatus}toLogEntry(){return{name:this.name,code:this.code,category:this.codeMetadata.category,message:this.message,path:this.path,operation:this.operation,issues:this.issues,cause:this.cause instanceof Error?this.cause.message:this.cause,stack:this.stack,timestamp:(new Date).toISOString()}}toString(){let e=`[${this.code}] ${this.message} (${this.codeMetadata.category})`;return this.path&&(e+=` at '${this.path}'`),this.operation&&(e+=` during '${this.operation}'`),this.issues.length>0&&(e+="\nIssues:\n"+this.issues.map(((e,t)=>` ${t+1}. ${e.message} [${e.code}]`)).join("\n")),this.cause&&(e+=`\nCause: ${this.cause instanceof Error?this.cause.message:String(this.cause)}`),e}},r=class e extends s{constructor(t,s){super({code:"SYNC_ERROR",message:t,cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},i=class e extends r{constructor(t){super(`[ArtifactContainer] Operation timed out: ${t}`),this.name="TimeoutError",Object.setPrototypeOf(this,e.prototype)}},n=class e extends r{constructor(t){super("[Serializer] The serializer has been marked as done!",t),this.name="SerializerExecutionDone",Object.setPrototypeOf(this,e.prototype)}},a=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 s=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await s;let r;await Promise.race([s.then((()=>clearTimeout(r))),new Promise(((s,n)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),n(new i("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},o=class{mutex=new a({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,s="Operation timed out"){if(null==t)return e;let r;return Promise.race([e.then((e=>(clearTimeout(r),e))),new Promise(((e,n)=>{r=setTimeout((()=>n(new i(s))),t)}))])}},c=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new a({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new n};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,r=null;try{if(this._done)throw new n;r=await e(),this._lastValue=r,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:r,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},h=class{constructor(e,t,s={}){this.factory=e,this.onCleanup=t,this.options=s}_count=0;init=new o({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}};function d(e,t){if(!e.length)return;const s=e.slice(),r=t?`[${t}]`:"[ArtifactCleanup]";return async()=>{for(let e=s.length-1;e>=0;e--)try{await s[e]()}catch(t){console.error(`${r} Cleanup error at index ${e}:`,t)}}}async function u(e,t){const s=t?`[${t}]`:"[ArtifactCleanup]";for(let t=e.length-1;t>=0;t--)try{await e[t]()}catch(e){console.error(`${s} Cleanup error at index ${t}:`,e)}}function l(e){return`${e}__watched`}var p=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function g(e,t){let s;const r=new Promise(((e,r)=>{s=setTimeout((()=>r(new Error(`Timeout: ${t}ms`))),t)}));try{return Promise.race([e,r])}finally{clearTimeout(s)}}var y=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,s){const r=this.get(e);if(!r)return p;if(r.package)return r.package;const i=e,n=d(r.cleanupFunctions,i),a="singleton"!==r.scope||void 0!==r.instance,o={instance:r.instance,error:r.error,ready:a,[s||e]:r.instance,cleanup:n,invalidate:t};return r.package=o,o}invalidatePackage(e){const t=this.get(e);t&&(t.package=void 0)}async invalidateInstance(e,t=!1){const s=this.get(e);if(!s)return;const r=e;"singleton"===s.scope&&(s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.debounceTimer&&(clearTimeout(s.debounceTimer),s.debounceTimer=void 0),s.controller.abort(),await s.streamOnce.current(),s.streamSerializer.close(),s.stream=void 0,s.streamOnce=new o({retry:!0,throws:!0}),t||(s.streamSerializer=new c,s.controller=new AbortController)),await u(s.cleanupFunctions,r),await u(s.disposeFunctions,r),s.cleanupFunctions=[],s.disposeFunctions=[],"singleton"===s.scope&&(s.buildOnce=new o({retry:!0,throws:!0})),s.instance=void 0,s.error=void 0}},f=class{dependencies=new Map;dependents=new Map;registerNode(e){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set)}removeNode(e){if(!this.hasNode(e))return;const t=this.dependencies.get(e);if(t)for(const s of t)this.dependents.get(s)?.delete(e);const s=this.dependents.get(e);if(s)for(const t of s)this.dependencies.get(t)?.delete(e);this.dependencies.delete(e),this.dependents.delete(e)}hasNode(e){return this.dependencies.has(e)}addDependency(e,t){this.registerNode(e),this.registerNode(t),this.dependencies.get(e).add(t),this.dependents.get(t).add(e)}removeDependency(e,t){this.dependencies.get(e)?.delete(t),this.dependents.get(t)?.delete(e)}getDependencies(e){const t=this.dependencies.get(e);return t?new Set(t):new Set}getDependents(e){const t=this.dependents.get(e);return t?new Set(t):new Set}iterDependents(e){return this.dependents.get(e)??m}setDependencies(e,t){this.registerNode(e);const s=this.dependencies.get(e),r=new Set(t);for(const t of s)r.has(t)||this.removeDependency(e,t);for(const t of r)s.has(t)||this.addDependency(e,t)}wouldCreateCycle(e,t){if(e===t)return[e,t];const s=[t],r=new Set([t]),i=new Map;for(;s.length>0;){const n=s.shift();if(n===e){const s=[];let r=e;for(;void 0!==r&&(s.push(r),r!==t);)r=i.get(r);return s.reverse(),s.unshift(e),s}const a=this.dependencies.get(n);if(a)for(const e of a)r.has(e)||(r.add(e),i.set(e,n),s.push(e))}return null}topologicalSort(){const e=new Map,t=Array.from(this.dependencies.keys());for(const s of t)e.set(s,this.dependencies.get(s)?.size??0);const s=[];for(const[t,r]of e)0===r&&s.push(t);const r=[];for(;s.length>0;){const t=s.shift();r.push(t);const i=this.dependents.get(t);if(i)for(const t of i){const r=(e.get(t)||0)-1;e.set(t,r),0===r&&s.push(t)}}if(r.length!==t.length)throw new Error("Cycle detected in graph; topological sort impossible.");return r}getTransitiveDependencies(e,t=!1){return this.bfs(e,"dependencies",t)}getTransitiveDependents(e,t=!1){return this.bfs(e,"dependents",t)}bfs(e,t,s){const r=new Set,i=new Set,n=[e];i.add(e),s&&r.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;n.length>0;){const e=n.shift(),t=a.get(e);if(t)for(const e of t)i.has(e)||(i.add(e),r.add(e),n.push(e))}return r}getAllNodes(){return Array.from(this.dependencies.keys())}size(){return this.dependencies.size}clear(){this.dependencies.clear(),this.dependents.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const s=Array.from(t).join(", ");return`${String(e)} → [${s||"∅"}]`})).join("\n")}},m=new Set,w=class{graph;constructor(){this.graph=new f}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){return Array.from(this.graph.getDependents(e))}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){return Array.from(this.graph.getDependencies(e))}getTransitiveDependents(e){return new Set(Array.from(this.graph.getTransitiveDependents(e,!1)))}setDependencies(e,t){const s=Array.from(t).map((e=>e));this.graph.setDependencies(e,s)}wouldCreateCycle(e,t,s){if(s?.has(t)){const e=Array.from(s),r=e.indexOf(t),i=e.slice(r);return i.push(t),i}const r=this.graph.wouldCreateCycle(e,t);return r||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()}},v=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];var b=class e extends Error{category;constructor(t,s,r){super(t,{cause:r}),this.name="ArtifactError",this.category=s,Object.setPrototypeOf(this,e.prototype)}},S=class extends b{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system"),this.name="ArtifactNotFoundError"}},_=class extends b{constructor(){super("Build superseded by invalidation","system"),this.name="SupersededBuildError"}},k=(new AbortController).signal,A=class{constructor(e,t,s,r,i){this.registry=e,this.cache=t,this.graph=s,this.store=r,this.observer=i}async build(e,t,s){const r=this.cache.get(e);if("singleton"===r?.scope&&r.buildOnce.done())return this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s);const i=this.registry.getByString(e);if(!i)throw new S(e);const n=t??[];if(n.includes(e))throw new b(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${[...n,e].join(" -> ")}`,"system");n.push(e);let a=r;a||(a=this.createCachedArtifact(i),this.cache.set(e,a));try{if("transient"===a.scope)return this.executeBuild(i,a,n);const r=a;try{await r.buildOnce.do((()=>this.executeBuild(i,r,n)))}catch(r){if(r instanceof _)return this.build(e,t,s);throw r}return r.stream&&r.streamOnce.do(r.stream),this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s)}finally{n.pop()}}async executeBuild(e,t,s){const r=e.key,i=String(r),n="transient"===t.scope;t.buildCount++,"singleton"===t.scope&&(t.activeDebounceMs=e.debounce??0);const a={cleanupFunctions:[],disposeFunctions:[],capturedArtifactDeps:new Set,capturedStateSelectors:[],dependencyVersions:new Map},o=this.buildContext(e,t,s,i,a),c=await this.runWithRetries(e,o,a.dependencyVersions);if(this.commitResult(r,t,n,c,a),n){const e=c.ok?c.value:void 0;return{instance:e,error:c.ok?void 0:c.error,ready:c.ok,[r]:e,cleanup:d(a.cleanupFunctions,i),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${i}"`)}}}buildContext(e,t,s,r,i){const n=e.key,a="transient"===t.scope,{cleanupFunctions:o,disposeFunctions:c,capturedArtifactDeps:h,dependencyVersions:d,capturedStateSelectors:u}=i,l=async(e,t)=>{const i=t?this.computeParamKey(e,t):e;if(i===n)throw new b(`Artifact "${r}" depends on itself.`,"system");const a=this.graph.wouldCreateCycle(n,i);if(a)throw new b(`Adding dependency "${String(i)}" to "${r}" would create a cycle: ${a.join(" -> ")}`,"system");h.add(i);const o=await(t?this.resolveParameterized(e,t):this.build(e,s)),c=this.cache.get(i);return c&&d.set(i,c.version),o},p="singleton"===t.scope?t.controller.signal:k,g=async(e,t)=>{const s=await l(e,t);if(s.error)throw s.error;return s.instance},y=(e,t)=>{const s=function(e,t="."){const s=new Set,r=new Map,i=(e="")=>{if(r.has(e))return r.get(e);const n=new Proxy((()=>{}),{get:(r,n)=>{if("symbol"==typeof n||"then"===n)return;if("valueOf"===n||"toString"===n)throw new Error("Cannot perform logic, arithmetic, or string operations inside a selector.");if(v.includes(n))throw new Error(`Array method .${n}() is not allowed in selectors.`);const a=e?`${e}${t}${n}`:n;return e&&s.delete(e),s.add(a),i(a)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions or methods.")}});return r.set(e,n),n};try{e(i())}catch(e){throw new Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e);return u.push({paths:s,options:t}),e(this.store.get(!0))};return{state:()=>this.store.get(!0),previous:t.instance,signal:p,onCleanup:e=>o.push(e),onDispose:e=>c.push(e),use:e=>e({resolve:l,require:g,select:y}),stream:e=>{if(a)throw new b(`[ArtifactManager] Illegal stream on transient artifact "${r}"`,"system");const s=t,i=async(e,t=void 0)=>{await s.streamSerializer.do((async()=>{void 0!==s.stream&&(s.instance=e,s.error=t,s.version++,this.cache.invalidatePackage(n),await this.processStream(r))}))},o={value:()=>s.instance,get signal(){return s.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>i(e)};s.stream=async()=>{try{const t=await e(o);t&&s.cleanupFunctions.push(t)}catch(e){await i(void 0,e),await this.invalidate(n,!1,!0)}}}}}async runWithRetries(e,t,s){const r=t.signal,i=(e.retries??0)+1;let n=0;for(;n<i;)try{if(r.aborted)throw new _;const a=e.factory(t);let o;if(o=a instanceof Promise?e.timeout?await g(a,e.timeout):await a:a,r.aborted)throw new _;const c=this.detectStaleness(s);if(c){if(n++,s.clear(),n<i)continue;return{ok:!1,error:new b(`Build stale after all retries: dependency "${String(c)}" changed during build.`,"system")}}return{ok:!0,value:o}}catch(e){if(r.aborted||e instanceof _)throw new _;if(e instanceof b)throw e;if(n++,n>=i)return{ok:!1,error:e}}return{ok:!1,error:new Error("Build exhausted retry budget unexpectedly.")}}commitResult(e,t,s,r,i){const{cleanupFunctions:n,disposeFunctions:a,capturedArtifactDeps:o,capturedStateSelectors:c}=i;s||(this.updateDependencyGraph(e,o,c),t.cleanupFunctions=n,t.disposeFunctions=a),r.ok?(t.instance=r.value,t.error=void 0):(t.instance=void 0,t.error=r.error),t.version++,this.cache.invalidatePackage(e)}detectStaleness(e){for(const[t,s]of e){const e=this.cache.get(t);if(e&&e.version!==s)return t}return null}async invalidate(e,t=!1,s=!1){const r=this.cache.get(e);if(!r)return;if("singleton"!==r.scope)return this.executeInvalidation(e,t,s);const i=r;return i.debounceTimer&&(clearTimeout(i.debounceTimer),i.debounceTimer=void 0),!t&&i.activeDebounceMs>0?new Promise(((r,n)=>{i.debounceTimer=setTimeout((()=>{i.debounceTimer=void 0,this.executeInvalidation(e,t,s).then(r).catch(n)}),i.activeDebounceMs)})):this.executeInvalidation(e,t,s)}async executeInvalidation(e,t,s=!1){const r=this.cache.get(e);r&&"singleton"===r.scope&&await r.invalidationSerializer.do((async()=>{r.version++,await this.cache.invalidateInstance(e),await this.cascadeInvalidation(this.graph.iterDependents(e));const i=this.registry.get(e),n=i&&(t||!i.lazy||this.observer.hasWatchers(e))&&!s;n&&await this.build(e).catch((t=>{t instanceof _||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),(n||s)&&this.observer.notify(e)}))}async dispose(e){this.cache.get(e)&&(await this.cache.invalidateInstance(e,!0),this.graph.removeNode(e),this.cache.delete(e))}async processStream(e){await this.cascadeInvalidation(this.graph.iterDependents(e)),this.observer.notify(e)}async cascadeInvalidation(e){if(0===e.size)return;const t=[];for(const s of e)t.push(this.invalidate(s).catch((e=>{console.error(`[ArtifactManager] Cascade failed for "${String(s)}":`,e)})));await Promise.all(t)}updateDependencyGraph(e,t,s){const r=this.cache.get(e);if(!r||"singleton"!==r.scope)return;this.graph.registerNode(e),this.graph.setDependencies(e,t),r.stateDependencies=new Set;for(const{paths:e}of s)for(const t of e)r.stateDependencies.add(t);if(r.stateUnsubscribe&&(r.stateUnsubscribe(),r.stateUnsubscribe=void 0),0===s.length)return;const i=()=>this.invalidate(e),n=new Map;for(const{paths:e,options:t}of s){const s=void 0===t?"undefined":JSON.stringify(t);let r=n.get(s);r||(r={options:t,paths:new Set},n.set(s,r));for(const t of e)r.paths.add(t)}const a=[];for(const{options:e,paths:t}of n.values()){if(0===t.size)continue;const s=Array.from(t);void 0===e?a.push(this.store.watch(s,i)):a.push(this.store.watch(s,i,e))}0===a.length?r.stateUnsubscribe=void 0:1===a.length?r.stateUnsubscribe=a[0]:r.stateUnsubscribe=()=>{for(const e of a)e()}}createCachedArtifact(e){return"transient"===e.scope?{scope:"transient",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0}:{scope:"singleton",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce?e.debounce:0,controller:new AbortController,buildOnce:new o({retry:!0,throws:!0}),streamOnce:new o({retry:!0,throws:!0}),streamSerializer:new c({yieldMode:"microtask"}),invalidationSerializer:new c({yieldMode:"macrotask"})}}resolveStatic(e){if(!this.registry.has(e))throw new S(e);return this.build(e)}async resolveParameterized(e,t){if(!this.registry.has(e))throw new S(String(e));const s=this.registry.get(e);if(!s.paramKey)throw new b(`Artifact "${String(e)}" is not parameterized.`,"external");const r=s.paramKey(t),i=this.registry.getByString(r);if(i&&!i.paramKey&&!i.virtual)throw new b(`Parameterized artifact "${String(e)}" with params ${JSON.stringify(t)} resolves to key "${r}" which is already registered as a static artifact.`,"system");return this.registry.hasString(r)||this.registry.setVirtual(r,{key:r,factory:e=>s.factory({...e,params:t}),scope:s.scope,lazy:s.lazy,timeout:s.timeout,retries:s.retries,debounce:s.debounce,virtual:!0}),this.build(r,void 0,e)}computeParamKey(e,t){const s=this.registry.get(e);if(!s.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);return s.paramKey(t)}},E=class{constructor(e,t,s){this.registry=e,this.cache=t,this.container=s}listeners=new Map;watchers=new Map;watch(e,t=6e4){return this.watchForKey(e,this.registry.get(e),t)}watchParameterized(e,t,s=6e4){const r=this.registry.get(e);if(!r.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);const i=r.paramKey(t);return this.watchForKey(i,r,s,t)}watchForKey(e,t,s,r){const i="transient"===t.scope,n=i?l(e):e,a=this.watchers.get(n);if(a)return a.observer;const o=new h((async()=>{!i&&void 0===r||this.registry.hasString(e)||this.registry.setVirtual(e,{key:e,factory:i?t.factory:e=>t.factory({...e,params:r}),scope:i?"singleton":t.scope,lazy:t.lazy,timeout:t.timeout,retries:t.retries,debounce:t.debounce,paramKey:t.paramKey,virtual:!0})}),(async()=>{i||void 0!==r?(await this.registry.unregister(n).catch((()=>{})),this.cache.delete(n),this.watchers.delete(n)):this.cache.invalidatePackage(n),this.listeners.delete(n)}),{gracePeriod:i&&void 0===r?"sync":s});let c;const d={id:n,get count(){return o.subscribers},get:(t=!1)=>0!==o.subscribers||t?this.cache.package(n,((e,t)=>this.container.invalidate(n,e,t)),e):p,resolve:()=>c||(c=(async()=>{await o.acquire();try{return await this.container.resolve(n)}finally{o.release(),c=void 0}})(),c),subscribe:(e,t=!0)=>{const s=()=>e(d.get());return o.acquire().then((()=>{this.container.resolve(n).then((()=>{this.listeners.has(n)||this.listeners.set(n,new Set),t&&s(),this.listeners.get(n).add(s)}))})).catch((e=>{console.error(`[ArtifactObserver] Resolution failed for "${n}":`,e),this.listeners.get(n)?.add(s)})),()=>{this.listeners.get(n)?.delete(s),o.release()}}};return this.watchers.set(n,{resource:o,observer:d}),d}evictWatcher(e){[e,l(e)].forEach((e=>{const t=this.watchers.get(e);t&&(t.resource.forceCleanup(),this.watchers.delete(e))}))}notify(e){const t=this.listeners.get(e);if(t&&0!==t.size)for(const s of t)try{s()}catch(t){console.error(`[ArtifactObserver] Listener error for "${e}":`,t)}}hasWatchers(e){return this.watchers.has(e)||this.watchers.has(l(e))}getWatcherCount(e){const t=this.watchers.get(e)||this.watchers.get(l(e));return t?.resource.subscribers??0}clear(){this.watchers.clear(),this.listeners.clear()}},D=(e=>(e.Singleton="singleton",e.Transient="transient",e))(D||{}),C=class{artifacts=new Map;register({key:e,factory:t,lazy:s,...r}){const{scope:i,...n}=r,a={key:e,factory:t,scope:r.scope??"singleton",lazy:void 0===s||s,...n};return this.artifacts.set(e,a),()=>this.unregister(e)}setVirtual(e,t){this.artifacts.set(e,t)}get(e){if(!this.has(e))throw new S(String(e));return this.artifacts.get(e)}getByString(e){return this.artifacts.get(e)}has(e){return this.artifacts.has(e)}hasString(e){return this.artifacts.has(e)}async unregister(e){this.artifacts.has(e)&&this.artifacts.delete(e)}size(){return this.artifacts.size}keys(){return Array.from(this.artifacts.keys())}clear(){this.artifacts.clear()}},O=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 C,this.cache=new y,this.graph=new w,this.observer=new E(this.registry,this.cache,this),this.manager=new A(this.registry,this.cache,this.graph,this.store,this.observer)}debugInfo(){const e=[];return this.registry.keys().forEach((t=>{const s=t,r=this.registry.get(s),i=this.cache.get(s);if(!r)return;let n="idle";i&&("singleton"===i.scope&&void 0!==i.debounceTimer?n="debouncing":"singleton"===i.scope&&i.buildOnce.running()?n="building":i.error?n="error":void 0!==i.instance&&(n="active")),e.push({id:s,scope:r.scope??"singleton",status:n,dependencies:this.graph.getDependencies(s).map((e=>String(e))),dependents:this.graph.getDependents(s).map((e=>String(e))),stateDependencies:"singleton"===i?.scope?Array.from(i.stateDependencies):[],buildCount:i?.buildCount??0})})),e}register(e){const{key:t}=e,s=t;this.registry.has(t)&&(console.warn(`[ArtifactContainer] Overwriting "${s}".`),this.manager.dispose(t).catch((e=>{console.error(`[ArtifactContainer] Failed to dispose existing artifact "${s}":`,e)}))),this.registry.register(e),this.graph.registerNode(t);const r=e.scope??"singleton";return(e.lazy??!0)||"singleton"!==r||this.resolve(t).catch((e=>{console.error(`[ArtifactContainer] Eager load failed for "${s}":`,e)})),()=>this.unregister(t)}has(e){return this.registry.has(e)}async unregister(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;await this.manager.dispose(s),await this.registry.unregister(s),this.observer.evictWatcher(s)}async resolve(e,t){return void 0===t?this.manager.resolveStatic(e):this.manager.resolveParameterized(e,t)}async require(e,t){const s=await this.resolve(e,t);if(s.error)throw s.error;return s.instance}watch(e,t,s){return void 0===t?this.observer.watch(e,s):this.observer.watchParameterized(e,t,s)}peek(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;return this.cache.get(s)?.instance}async invalidate(e,t){const s=t?.params,r=t?.replace??!1,i=void 0!==s?this.manager.computeParamKey(e,s):e;return this.manager.invalidate(i,r)}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{O as ArtifactContainer,D as ArtifactScopes};
1
+ var e={VALIDATION_FAILED:{code:"VAL-001",name:"VALIDATION_FAILED",description:"Input validation failed due to one or more invalid fields",category:"validation",httpStatus:400,logLevel:"warn"},REQUIRED_FIELD_MISSING:{code:"VAL-002",name:"REQUIRED_FIELD_MISSING",description:"A required field was not provided in the request",category:"validation",httpStatus:400,logLevel:"warn"},INVALID_FORMAT:{code:"VAL-003",name:"INVALID_FORMAT",description:"Field value does not match expected format",category:"validation",httpStatus:400,logLevel:"warn"},NOT_FOUND:{code:"DB-001-NF",name:"NOT_FOUND",description:"The requested resource could not be found",category:"database",httpStatus:404,logLevel:"info",action:"Verify the resource identifier exists before accessing"},DUPLICATE_KEY:{code:"DB-002-DUP",name:"DUPLICATE_KEY",description:"A unique constraint violation occurred",category:"database",httpStatus:409,logLevel:"warn",action:"Check if the resource already exists before creation"},RESOURCE_LOCKED:{code:"DB-003-LOCK",name:"RESOURCE_LOCKED",description:"The resource is currently locked by another operation",category:"database",httpStatus:409,logLevel:"warn",action:"Retry the operation after a brief delay"},PERMISSION_DENIED:{code:"AUTH-001-DENIED",name:"PERMISSION_DENIED",description:"The authenticated user lacks permission for this operation",category:"auth",httpStatus:403,logLevel:"warn",action:"Check user roles and permissions"},UNAUTHENTICATED:{code:"AUTH-002-UNAUTH",name:"UNAUTHENTICATED",description:"Authentication is required for this operation",category:"auth",httpStatus:401,logLevel:"info",action:"Provide valid authentication credentials"},INVALID_COMMAND:{code:"BUS-001",name:"INVALID_COMMAND",description:"The command or operation is invalid for the current state",category:"business",httpStatus:400,logLevel:"warn"},OPERATION_ABORTED:{code:"BUS-002-ABORT",name:"OPERATION_ABORTED",description:"The operation was explicitly aborted",category:"business",httpStatus:409,logLevel:"info"},INTERNAL_ERROR:{code:"SYS-001",name:"INTERNAL_ERROR",description:"An unexpected internal error occurred",category:"system",httpStatus:500,logLevel:"error",action:"Check system logs for stack traces and diagnostic information"},BACKEND_ERROR:{code:"SYS-002",name:"BACKEND_ERROR",description:"An error occurred in a backend service",category:"system",httpStatus:502,logLevel:"error"},CONCURRENCY_ERROR:{code:"CON-001",name:"CONCURRENCY_ERROR",description:"A concurrency conflict occurred during the operation",category:"concurrency",httpStatus:409,logLevel:"warn",action:"Retry the operation with updated data"}},t=new Map;var s=class s extends Error{code;codeMetadata;severity;path;operation;issues;cause;constructor(r){const i={...function(s){const r=Object.values(e).find((e=>e.code===s));if(r)return r;return t.get(s)||{code:s,name:s.replace(/-/g,"_"),description:`Unknown error: ${s}`,category:"custom",httpStatus:500,logLevel:"error",action:"Check if this error code is properly registered or handle as unknown error"}}(r.code),...r.metadata,code:r.code};super(r.message??i.description),this.name="SystemError",this.code=r.code,this.codeMetadata=i,this.severity=r.severity??"error",this.path=r.path,this.operation=r.operation,this.issues=r.issues??[],this.cause=r.cause,Object.setPrototypeOf(this,s.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,s)}withPath(e){return new s({code:this.code,message:this.message,severity:this.severity,path:e,operation:this.operation,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withOperation(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:e,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withIssue(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,e],cause:this.cause,metadata:this.codeMetadata})}withIssues(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,...e],cause:this.cause,metadata:this.codeMetadata})}withCause(e){return new s({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:this.issues,cause:e,metadata:this.codeMetadata})}getHttpStatus(){return this.codeMetadata.httpStatus}toLogEntry(){return{name:this.name,code:this.code,category:this.codeMetadata.category,message:this.message,path:this.path,operation:this.operation,issues:this.issues,cause:this.cause instanceof Error?this.cause.message:this.cause,stack:this.stack,timestamp:(new Date).toISOString()}}toString(){let e=`[${this.code}] ${this.message} (${this.codeMetadata.category})`;return this.path&&(e+=` at '${this.path}'`),this.operation&&(e+=` during '${this.operation}'`),this.issues.length>0&&(e+="\nIssues:\n"+this.issues.map(((e,t)=>` ${t+1}. ${e.message} [${e.code}]`)).join("\n")),this.cause&&(e+=`\nCause: ${this.cause instanceof Error?this.cause.message:String(this.cause)}`),e}},r=class e extends s{constructor(t,s){super({code:"SYNC_ERROR",message:t,cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},i=class e extends r{constructor(t){super(`[ArtifactContainer] Operation timed out: ${t}`),this.name="TimeoutError",Object.setPrototypeOf(this,e.prototype)}},n=class e extends r{constructor(t){super("[Serializer] The serializer has been marked as done!",t),this.name="SerializerExecutionDone",Object.setPrototypeOf(this,e.prototype)}},a=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 s=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await s;let r;await Promise.race([s.then((()=>clearTimeout(r))),new Promise(((s,n)=>{r=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),n(new i("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},o=class{mutex=new a({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}resolve(e){if(this._done)throw new Error("Cannot resolve: operation is already completed.");if(this.running())throw new Error("Cannot resolve: operation is currently running.");this._value=e,this._done=!0}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,s="Operation timed out"){if(null==t)return e;let r;return Promise.race([e.then((e=>(clearTimeout(r),e))),new Promise(((e,n)=>{r=setTimeout((()=>n(new i(s))),t)}))])}},c=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new a({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new n};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,r=null;try{if(this._done)throw new n;r=await e(),this._lastValue=r,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:r,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},h=class{constructor(e,t,s={}){this.factory=e,this.onCleanup=t,this.options=s}_count=0;init=new o({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}};function d(e,t){if(!e.length)return;const s=e.slice(),r=t?`[${t}]`:"[ArtifactCleanup]";return async()=>{for(let e=s.length-1;e>=0;e--)try{await s[e]()}catch(t){console.error(`${r} Cleanup error at index ${e}:`,t)}}}async function u(e,t){const s=t?`[${t}]`:"[ArtifactCleanup]";for(let t=e.length-1;t>=0;t--)try{await e[t]()}catch(e){console.error(`${s} Cleanup error at index ${t}:`,e)}}function l(e){return`${e}__watched`}var p=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function g(e,t){let s;const r=new Promise(((e,r)=>{s=setTimeout((()=>r(new Error(`Timeout: ${t}ms`))),t)}));try{return Promise.race([e,r])}finally{clearTimeout(s)}}async function f(e){const t=(new TextEncoder).encode(e),s=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(s)).map((e=>e.toString(16).padStart(2,"0"))).join("")}var y=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,s){const r=this.get(e);if(!r)return p;if(r.package)return r.package;const i=e,n=d(r.cleanupFunctions,i),a="singleton"!==r.scope||void 0!==r.instance,o={instance:r.instance,error:r.error,ready:a,[s||e]:r.instance,cleanup:n,invalidate:t};return r.package=o,o}invalidatePackage(e){const t=this.get(e);t&&(t.package=void 0)}async invalidateInstance(e,t=!1){const s=this.get(e);if(!s)return;const r=e;"singleton"===s.scope&&(s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.debounceTimer&&(clearTimeout(s.debounceTimer),s.debounceTimer=void 0),s.controller.abort(),await s.streamOnce.current(),s.streamSerializer.close(),s.stream=void 0,s.streamOnce=new o({retry:!0,throws:!0}),t||(s.streamSerializer=new c,s.controller=new AbortController)),await u(s.cleanupFunctions,r),await u(s.disposeFunctions,r),s.cleanupFunctions=[],s.disposeFunctions=[],"singleton"===s.scope&&(s.buildOnce=new o({retry:!0,throws:!0})),s.instance=void 0,s.error=void 0}},w=class{dependencies=new Map;dependents=new Map;registerNode(e){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set)}removeNode(e){if(!this.hasNode(e))return;const t=this.dependencies.get(e);if(t)for(const s of t)this.dependents.get(s)?.delete(e);const s=this.dependents.get(e);if(s)for(const t of s)this.dependencies.get(t)?.delete(e);this.dependencies.delete(e),this.dependents.delete(e)}hasNode(e){return this.dependencies.has(e)}addDependency(e,t){this.registerNode(e),this.registerNode(t),this.dependencies.get(e).add(t),this.dependents.get(t).add(e)}removeDependency(e,t){this.dependencies.get(e)?.delete(t),this.dependents.get(t)?.delete(e)}getDependencies(e){const t=this.dependencies.get(e);return t?new Set(t):new Set}getDependents(e){const t=this.dependents.get(e);return t?new Set(t):new Set}iterDependents(e){return this.dependents.get(e)??m}setDependencies(e,t){this.registerNode(e);const s=this.dependencies.get(e),r=new Set(t);for(const t of s)r.has(t)||this.removeDependency(e,t);for(const t of r)s.has(t)||this.addDependency(e,t)}wouldCreateCycle(e,t){if(e===t)return[e,t];const s=[t],r=new Set([t]),i=new Map;for(;s.length>0;){const n=s.shift();if(n===e){const s=[];let r=e;for(;void 0!==r&&(s.push(r),r!==t);)r=i.get(r);return s.reverse(),s.unshift(e),s}const a=this.dependencies.get(n);if(a)for(const e of a)r.has(e)||(r.add(e),i.set(e,n),s.push(e))}return null}topologicalSort(){const e=new Map,t=Array.from(this.dependencies.keys());for(const s of t)e.set(s,this.dependencies.get(s)?.size??0);const s=[];for(const[t,r]of e)0===r&&s.push(t);const r=[];for(;s.length>0;){const t=s.shift();r.push(t);const i=this.dependents.get(t);if(i)for(const t of i){const r=(e.get(t)||0)-1;e.set(t,r),0===r&&s.push(t)}}if(r.length!==t.length)throw new Error("Cycle detected in graph; topological sort impossible.");return r}getTransitiveDependencies(e,t=!1){return this.bfs(e,"dependencies",t)}getTransitiveDependents(e,t=!1){return this.bfs(e,"dependents",t)}bfs(e,t,s){const r=new Set,i=new Set,n=[e];i.add(e),s&&r.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;n.length>0;){const e=n.shift(),t=a.get(e);if(t)for(const e of t)i.has(e)||(i.add(e),r.add(e),n.push(e))}return r}getAllNodes(){return Array.from(this.dependencies.keys())}size(){return this.dependencies.size}clear(){this.dependencies.clear(),this.dependents.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const s=Array.from(t).join(", ");return`${String(e)} → [${s||"∅"}]`})).join("\n")}},m=new Set,v=class{graph;constructor(){this.graph=new w}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){return Array.from(this.graph.getDependents(e))}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){return Array.from(this.graph.getDependencies(e))}getTransitiveDependents(e){return new Set(Array.from(this.graph.getTransitiveDependents(e,!1)))}setDependencies(e,t){const s=Array.from(t).map((e=>e));this.graph.setDependencies(e,s)}wouldCreateCycle(e,t,s){if(s?.has(t)){const e=Array.from(s),r=e.indexOf(t),i=e.slice(r);return i.push(t),i}const r=this.graph.wouldCreateCycle(e,t);return r||null}hasNode(e){return this.graph.hasNode(e)}getAllNodes(){return this.graph.getAllNodes()}clear(){this.graph.clear()}size(){return this.graph.size()}toDebugString(){return this.graph.toDebugString()}},b=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];var S=class e extends Error{category;constructor(t,s,r){super(t,{cause:r}),this.name="ArtifactError",this.category=s,Object.setPrototypeOf(this,e.prototype)}},k=class extends S{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system"),this.name="ArtifactNotFoundError"}},_=class extends S{constructor(){super("Build superseded by invalidation","system"),this.name="SupersededBuildError"}},A=class extends S{constructor(e){super(e,"system"),this.name="InvalidImportError"}},E=class extends S{constructor(e){super(`Artifact "${e}" instance is not JSON-serializable (POJO are required for persistence)`,"system"),this.name="InvalidExportOperationError"}},D=(new AbortController).signal,C=class{constructor(e,t,s,r,i){this.registry=e,this.cache=t,this.graph=s,this.store=r,this.observer=i}async build(e,t,s){const r=this.cache.get(e);if("singleton"===r?.scope&&r.buildOnce.done())return this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s);const i=this.registry.getByString(e);if(!i)throw new k(e);const n=t??[];if(n.includes(e))throw new S(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${[...n,e].join(" -> ")}`,"system");n.push(e);let a=r;a||(a=this.createCachedArtifact(i),this.cache.set(e,a));try{if("transient"===a.scope)return this.executeBuild(i,a,n);const r=a;try{await r.buildOnce.do((()=>this.executeBuild(i,r,n)))}catch(r){if(r instanceof _)return this.build(e,t,s);throw r}return r.stream&&r.streamOnce.do(r.stream),this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s)}finally{n.pop()}}async executeBuild(e,t,s){const r=e.key,i=String(r),n="transient"===t.scope;t.buildCount++,"singleton"===t.scope&&(t.activeDebounceMs=e.debounce??0);const a={cleanupFunctions:[],disposeFunctions:[],capturedArtifactDeps:new Set,capturedStateSelectors:[],dependencyVersions:new Map},o=this.buildContext(e,t,s,i,a),c=await this.runWithRetries(e,o,a.dependencyVersions);if(this.commitResult(r,t,n,c,a),n){const e=c.ok?c.value:void 0;return{instance:e,error:c.ok?void 0:c.error,ready:c.ok,[r]:e,cleanup:d(a.cleanupFunctions,i),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${i}"`)}}}buildContext(e,t,s,r,i){const n=e.key,a="transient"===t.scope,{cleanupFunctions:o,disposeFunctions:c,capturedArtifactDeps:h,dependencyVersions:d,capturedStateSelectors:u}=i,l=async(e,t)=>{const i=t?this.computeParamKey(e,t):e;if(i===n)throw new S(`Artifact "${r}" depends on itself.`,"system");const a=this.graph.wouldCreateCycle(n,i);if(a)throw new S(`Adding dependency "${String(i)}" to "${r}" would create a cycle: ${a.join(" -> ")}`,"system");h.add(i);const o=await(t?this.resolveParameterized(e,t):this.build(e,s)),c=this.cache.get(i);return c&&d.set(i,c.version),o},p="singleton"===t.scope?t.controller.signal:D,g=async(e,t)=>{const s=await l(e,t);if(s.error)throw s.error;return s.instance},f=(e,t)=>{const s=function(e,t="."){const s=new Set,r=new Map,i=(e="")=>{if(r.has(e))return r.get(e);const n=new Proxy((()=>{}),{get:(r,n)=>{if("symbol"==typeof n||"then"===n)return;if("valueOf"===n||"toString"===n)throw new Error("Cannot perform logic, arithmetic, or string operations inside a selector.");if(b.includes(n))throw new Error(`Array method .${n}() is not allowed in selectors.`);const a=e?`${e}${t}${n}`:n;return e&&s.delete(e),s.add(a),i(a)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions or methods.")}});return r.set(e,n),n};try{e(i())}catch(e){throw new Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e);return u.push({paths:s,options:t}),e(this.store.get(!0))};return{state:()=>this.store.get(!0),previous:t.instance,signal:p,onCleanup:e=>o.push(e),onDispose:e=>c.push(e),use:e=>e({resolve:l,require:g,select:f}),stream:e=>{if(a)throw new S(`[ArtifactManager] Illegal stream on transient artifact "${r}"`,"system");const s=t,i=async(e,t=void 0)=>{await s.streamSerializer.do((async()=>{void 0!==s.stream&&(s.instance=e,s.error=t,s.version++,this.cache.invalidatePackage(n),await this.processStream(r))}))},o={value:()=>s.instance,get signal(){return s.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>i(e)};s.stream=async()=>{try{const t=await e(o);t&&s.cleanupFunctions.push(t)}catch(e){await i(void 0,e),await this.invalidate(n,!1,!0)}}}}}async runWithRetries(e,t,s){const r=t.signal,i=(e.retries??0)+1;let n=0;for(;n<i;)try{if(r.aborted)throw new _;const a=e.factory(t);let o;if(o=a instanceof Promise?e.timeout?await g(a,e.timeout):await a:a,r.aborted)throw new _;const c=this.detectStaleness(s);if(c){if(n++,s.clear(),n<i)continue;return{ok:!1,error:new S(`Build stale after all retries: dependency "${String(c)}" changed during build.`,"system")}}return{ok:!0,value:o}}catch(e){if(r.aborted||e instanceof _)throw new _;if(e instanceof S)throw e;if(n++,n>=i)return{ok:!1,error:e}}return{ok:!1,error:new Error("Build exhausted retry budget unexpectedly.")}}commitResult(e,t,s,r,i){const{cleanupFunctions:n,disposeFunctions:a,capturedArtifactDeps:o,capturedStateSelectors:c}=i;s||(this.updateDependencyGraph(e,o,c),t.cleanupFunctions=n,t.disposeFunctions=a,t.artifactDependencies=new Set(o),t.stateGroups=c.map((({paths:e,options:t})=>({paths:e,options:t})))),r.ok?(t.instance=r.value,t.error=void 0):(t.instance=void 0,t.error=r.error),t.version++,this.cache.invalidatePackage(e)}detectStaleness(e){for(const[t,s]of e){const e=this.cache.get(t);if(e&&e.version!==s)return t}return null}async invalidate(e,t=!1,s=!1){const r=this.cache.get(e);if(!r)return;if("singleton"!==r.scope)return this.executeInvalidation(e,t,s);const i=r;return i.debounceTimer&&(clearTimeout(i.debounceTimer),i.debounceTimer=void 0),!t&&i.activeDebounceMs>0?new Promise(((r,n)=>{i.debounceTimer=setTimeout((()=>{i.debounceTimer=void 0,this.executeInvalidation(e,t,s).then(r).catch(n)}),i.activeDebounceMs)})):this.executeInvalidation(e,t,s)}async executeInvalidation(e,t,s=!1){const r=this.cache.get(e);r&&"singleton"===r.scope&&await r.invalidationSerializer.do((async()=>{r.version++,await this.cache.invalidateInstance(e),await this.cascadeInvalidation(this.graph.iterDependents(e));const i=this.registry.get(e),n=i&&(t||!i.lazy||this.observer.hasWatchers(e))&&!s;n&&await this.build(e).catch((t=>{t instanceof _||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),(n||s)&&this.observer.notify(e)}))}async dispose(e){this.cache.get(e)&&(await this.cache.invalidateInstance(e,!0),this.graph.removeNode(e),this.cache.delete(e))}async processStream(e){await this.cascadeInvalidation(this.graph.iterDependents(e)),this.observer.notify(e)}async cascadeInvalidation(e){if(0===e.size)return;const t=[];for(const s of e)t.push(this.invalidate(s).catch((e=>{console.error(`[ArtifactManager] Cascade failed for "${String(s)}":`,e)})));await Promise.all(t)}updateDependencyGraph(e,t,s){const r=this.cache.get(e);if(!r||"singleton"!==r.scope)return;this.graph.registerNode(e),this.graph.setDependencies(e,t),r.stateDependencies=new Set;for(const{paths:e}of s)for(const t of e)r.stateDependencies.add(t);if(r.stateUnsubscribe&&(r.stateUnsubscribe(),r.stateUnsubscribe=void 0),0===s.length)return;const i=()=>this.invalidate(e),n=new Map;for(const{paths:e,options:t}of s){const s=void 0===t?"undefined":JSON.stringify(t);let r=n.get(s);r||(r={options:t,paths:new Set},n.set(s,r));for(const t of e)r.paths.add(t)}const a=[];for(const{options:e,paths:t}of n.values()){if(0===t.size)continue;const s=Array.from(t);void 0===e?a.push(this.store.watch(s,i)):a.push(this.store.watch(s,i,e))}0===a.length?r.stateUnsubscribe=void 0:1===a.length?r.stateUnsubscribe=a[0]:r.stateUnsubscribe=()=>{for(const e of a)e()}}createCachedArtifact(e){return"transient"===e.scope?{scope:"transient",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0}:{scope:"singleton",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce?e.debounce:0,controller:new AbortController,buildOnce:new o({retry:!0,throws:!0}),streamOnce:new o({retry:!0,throws:!0}),streamSerializer:new c({yieldMode:"microtask"}),invalidationSerializer:new c({yieldMode:"macrotask"}),stateGroups:[],artifactDependencies:new Set}}resolveStatic(e){if(!this.registry.has(e))throw new k(e);return this.build(e)}async resolveParameterized(e,t){if(!this.registry.has(e))throw new k(String(e));const s=this.registry.get(e);if(!s.paramKey)throw new S(`Artifact "${String(e)}" is not parameterized.`,"external");const r=s.paramKey(t),i=this.registry.getByString(r);if(i&&!i.paramKey&&!i.virtual)throw new S(`Parameterized artifact "${String(e)}" with params ${JSON.stringify(t)} resolves to key "${r}" which is already registered as a static artifact.`,"system");return this.registry.hasString(r)||this.registry.setVirtual(r,{key:r,factory:e=>s.factory({...e,params:t}),scope:s.scope,lazy:s.lazy,timeout:s.timeout,retries:s.retries,debounce:s.debounce,virtual:!0}),this.build(r,void 0,e)}computeParamKey(e,t){const s=this.registry.get(e);if(!s.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);return s.paramKey(t)}},O=class{constructor(e,t,s){this.registry=e,this.cache=t,this.container=s}listeners=new Map;watchers=new Map;watch(e,t=6e4){return this.watchForKey(e,this.registry.get(e),t)}watchParameterized(e,t,s=6e4){const r=this.registry.get(e);if(!r.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);const i=r.paramKey(t);return this.watchForKey(i,r,s,t)}watchForKey(e,t,s,r){const i="transient"===t.scope,n=i?l(e):e,a=this.watchers.get(n);if(a)return a.observer;const o=new h((async()=>{!i&&void 0===r||this.registry.hasString(e)||this.registry.setVirtual(e,{key:e,factory:i?t.factory:e=>t.factory({...e,params:r}),scope:i?"singleton":t.scope,lazy:t.lazy,timeout:t.timeout,retries:t.retries,debounce:t.debounce,paramKey:t.paramKey,virtual:!0})}),(async()=>{i||void 0!==r?(await this.registry.unregister(n).catch((()=>{})),this.cache.delete(n),this.watchers.delete(n)):this.cache.invalidatePackage(n),this.listeners.delete(n)}),{gracePeriod:i&&void 0===r?"sync":s});let c;const d={id:n,get count(){return o.subscribers},get:(t=!1)=>0!==o.subscribers||t?this.cache.package(n,((e,t)=>this.container.invalidate(n,e,t)),e):p,resolve:()=>c||(c=(async()=>{await o.acquire();try{return await this.container.resolve(n)}finally{o.release(),c=void 0}})(),c),subscribe:(e,t=!0)=>{const s=()=>e(d.get());return o.acquire().then((()=>{this.container.resolve(n).then((()=>{this.listeners.has(n)||this.listeners.set(n,new Set),t&&s(),this.listeners.get(n).add(s)}))})).catch((e=>{console.error(`[ArtifactObserver] Resolution failed for "${n}":`,e),this.listeners.get(n)?.add(s)})),()=>{this.listeners.get(n)?.delete(s),o.release()}}};return this.watchers.set(n,{resource:o,observer:d}),d}evictWatcher(e){[e,l(e)].forEach((e=>{const t=this.watchers.get(e);t&&(t.resource.forceCleanup(),this.watchers.delete(e))}))}notify(e){const t=this.listeners.get(e);if(t&&0!==t.size)for(const s of t)try{s()}catch(t){console.error(`[ArtifactObserver] Listener error for "${e}":`,t)}}hasWatchers(e){return this.watchers.has(e)||this.watchers.has(l(e))}getWatcherCount(e){const t=this.watchers.get(e)||this.watchers.get(l(e));return t?.resource.subscribers??0}clear(){this.watchers.clear(),this.listeners.clear()}},T=(e=>(e.Singleton="singleton",e.Transient="transient",e))(T||{}),M=class{artifacts=new Map;register({key:e,factory:t,lazy:s,...r}){const{scope:i,...n}=r,a={key:e,factory:t,scope:r.scope??"singleton",lazy:void 0===s||s,...n};return this.artifacts.set(e,a),()=>this.unregister(e)}setVirtual(e,t){this.artifacts.set(e,t)}get(e){if(!this.has(e))throw new k(String(e));return this.artifacts.get(e)}getByString(e){return this.artifacts.get(e)}has(e){return this.artifacts.has(e)}hasString(e){return this.artifacts.has(e)}async unregister(e){this.artifacts.has(e)&&this.artifacts.delete(e)}size(){return this.artifacts.size}keys(){return Array.from(this.artifacts.keys())}clear(){this.artifacts.clear()}},N=class e{registry;cache;graph;manager;observer;store;constructor(e){this.store={watch:(...t)=>e.watch(...t),get:()=>e.get(!0),set:(...t)=>e.set(...t),subset:(...t)=>e.subset(...t)},this.registry=new M,this.cache=new y,this.graph=new v,this.observer=new O(this.registry,this.cache,this),this.manager=new C(this.registry,this.cache,this.graph,this.store,this.observer)}debugInfo(){const e=[];return this.registry.keys().forEach((t=>{const s=t,r=this.registry.get(s),i=this.cache.get(s);if(!r)return;let n="idle";i&&("singleton"===i.scope&&void 0!==i.debounceTimer?n="debouncing":"singleton"===i.scope&&i.buildOnce.running()?n="building":i.error?n="error":void 0!==i.instance&&(n="active")),e.push({id:s,scope:r.scope??"singleton",status:n,dependencies:this.graph.getDependencies(s).map((e=>String(e))),dependents:this.graph.getDependents(s).map((e=>String(e))),stateDependencies:"singleton"===i?.scope?Array.from(i.stateDependencies):[],buildCount:i?.buildCount??0})})),e}register(e){const{key:t}=e,s=t;this.registry.has(t)&&(console.warn(`[ArtifactContainer] Overwriting "${s}".`),this.manager.dispose(t).catch((e=>{console.error(`[ArtifactContainer] Failed to dispose existing artifact "${s}":`,e)}))),this.registry.register(e),this.graph.registerNode(t);const r=e.scope??"singleton";return(e.lazy??!0)||"singleton"!==r||this.resolve(t).catch((e=>{console.error(`[ArtifactContainer] Eager load failed for "${s}":`,e)})),()=>this.unregister(t)}has(e){return this.registry.has(e)}async unregister(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;await this.manager.dispose(s),await this.registry.unregister(s),this.observer.evictWatcher(s)}async resolve(e,t){return void 0===t?this.manager.resolveStatic(e):this.manager.resolveParameterized(e,t)}async require(e,t){const s=await this.resolve(e,t);if(s.error)throw s.error;return s.instance}watch(e,t,s){return void 0===t?this.observer.watch(e,s):this.observer.watchParameterized(e,t,s)}peek(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;return this.cache.get(s)?.instance}async invalidate(e,t){const s=t?.params,r=t?.replace??!1,i=void 0!==s?this.manager.computeParamKey(e,s):e;return this.manager.invalidate(i,r)}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()}async export(){const e=[];for(const t of this.cache.keys()){const s=this.cache.get(t);if(!s||"singleton"!==s.scope)continue;if(void 0===s.instance)continue;const r=new Set;for(const e of s.stateGroups)for(const t of e.paths)r.add(t);const i=Array.from(r).sort(),n=this.store.subset(i),a=await f(JSON.stringify(n,Object.keys(n).sort()));let o;try{o=structuredClone(s.instance)}catch(e){throw new E(t)}e.push({key:t,instance:o,state:{groups:s.stateGroups.map((e=>({paths:e.paths,options:e.options}))),hash:a},dependencies:Array.from(s.artifactDependencies)})}const t={...{version:"1.0",timestamp:Date.now(),artifacts:e}},s=JSON.stringify(t),r=await f(s);return{...t,checksum:r}}async restore(e){const{checksum:t,...s}=e;if(await f(JSON.stringify(s))!==t)throw new A("Bundle checksum mismatch – data corrupted");if("1.0"!==e.version)throw new A(`Unsupported bundle version: ${e.version}`);const r=new Map;for(const t of e.artifacts)r.set(t.key,t);const i=new Set,n=new Map;for(const t of e.artifacts)for(const e of t.dependencies)n.has(e)||n.set(e,new Set),n.get(e).add(t.key);const a=async e=>{const t=new Set;for(const s of e.state.groups)for(const e of s.paths)t.add(e);const s=Array.from(t).sort(),r=this.store.subset(s);return f(JSON.stringify(r,Object.keys(r).sort()))};for(const t of e.artifacts){await a(t)!==t.state.hash&&i.add(t.key)}const h=Array.from(i);for(;h.length;){const e=h.shift(),t=n.get(e);if(t)for(const e of t)i.has(e)||(i.add(e),h.push(e))}for(const t of e.artifacts){if(i.has(t.key))continue;this.cache.get(t.key)&&await this.cache.invalidateInstance(t.key,!1);const e={scope:"singleton",instance:t.instance,error:void 0,version:1,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set(t.state.groups.flatMap((e=>e.paths))),activeDebounceMs:0,buildOnce:new o({retry:!0,throws:!0}),streamSerializer:new c({yieldMode:"microtask"}),invalidationSerializer:new c({yieldMode:"macrotask"}),stateUnsubscribe:void 0,debounceTimer:void 0,controller:new AbortController,streamOnce:new o({retry:!0,throws:!0}),stream:void 0,stateGroups:t.state.groups,artifactDependencies:new Set(t.dependencies)};e.buildOnce.resolve(t.instance),this.cache.set(t.key,e);const s=[];for(const e of t.state.groups){const r=this.store.watch(e.paths,(()=>this.invalidate(t.key)),e.options);s.push(r)}e.stateUnsubscribe=()=>{for(const e of s)e()},this.graph.setDependencies(t.key,t.dependencies)}}static async from(t){const s=new e(t.store);if(t.bundle){if("object"!=typeof t.bundle||!t.bundle.version||!Array.isArray(t.bundle.artifacts))throw new A("Invalid bundle: missing version or artifacts array");await s.restore(t.bundle)}for(const e of t.templates)s.register(e);return s}};export{N as ArtifactContainer,T as ArtifactScopes};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asaidimu/utils-artifacts",
3
- "version": "8.2.5",
3
+ "version": "8.2.7",
4
4
  "description": "Reactive artifact container.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",