@asaidimu/utils-artifacts 8.2.10 → 8.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,12 +1,9 @@
1
- interface SubscribeOptions {
2
- /**
3
- * Debounce delay in milliseconds. When multiple events arrive in quick
4
- * succession, the callback runs only after the quiet period ends, using the
5
- * latest payload. Default = no debouncing.
6
- */
7
- debounce?: number;
8
- }
1
+ import { Issue, Severity, SystemError, SystemError as SystemError$1 } from "@asaidimu/utils-error";
2
+ import { SubscribeOptions, SubscribeOptions as SubscribeOptions$1 } from "@asaidimu/utils-events";
3
+ import { SystemLogger } from "@asaidimu/utils-logger";
4
+ import { EventBus } from "@asaidimu/utils-events/types";
9
5
 
6
+ //#region src/store/types.d.ts
10
7
  /**
11
8
  * Utility type for representing partial updates to the state, allowing deep nesting.
12
9
  * It makes all properties optional and applies the same transformation recursively
@@ -14,29 +11,27 @@ interface SubscribeOptions {
14
11
  * preserving the original structure. It also includes the original type T and
15
12
  * undefined as possibilities for the top level and nested values.
16
13
  */
17
- type DeepPartial<T> = T extends object ? T extends readonly (infer U)[] ? readonly (DeepPartial<U> | undefined)[] | undefined | T : T extends (infer U)[] ? (DeepPartial<U> | undefined)[] | undefined | T : {
18
- [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> | undefined : T[K] | undefined;
19
- } | undefined | T : T | undefined | symbol;
14
+ type DeepPartial<T> = T extends object ? T extends readonly (infer U)[] ? readonly (DeepPartial<U> | undefined)[] | undefined | T : T extends (infer U)[] ? (DeepPartial<U> | undefined)[] | undefined | T : { [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> | undefined : T[K] | undefined } | undefined | T : T | undefined | symbol;
20
15
  /**
21
16
  * Extended store state for monitoring the current execution status (e.g., if an update is in progress).
22
17
  */
23
18
  interface StoreExecutionState<T> {
24
- /** Indicates if a state update process is currently executing. */
25
- executing: boolean;
26
- /** The changes (DeepPartial) currently being processed in the execution cycle. Null if none. */
27
- changes: DeepPartial<T> | null;
28
- /** A queue of pending state update functions/objects to be applied sequentially. */
29
- pendingChanges: Array<StateUpdater<T>>;
30
- /** Names of all currently registered middlewares. */
31
- middlewares: string[];
32
- /** Details of the middleware currently running. Null if none. */
33
- runningMiddleware: {
34
- id: string;
35
- name: string;
36
- startTime: number;
37
- } | null;
38
- /** Indicates if the store is currently within an active transaction block. */
39
- transactionActive: boolean;
19
+ /** Indicates if a state update process is currently executing. */
20
+ executing: boolean;
21
+ /** The changes (DeepPartial) currently being processed in the execution cycle. Null if none. */
22
+ changes: DeepPartial<T> | null;
23
+ /** A queue of pending state update functions/objects to be applied sequentially. */
24
+ pendingChanges: Array<StateUpdater<T>>;
25
+ /** Names of all currently registered middlewares. */
26
+ middlewares: string[];
27
+ /** Details of the middleware currently running. Null if none. */
28
+ runningMiddleware: {
29
+ id: string;
30
+ name: string;
31
+ startTime: number;
32
+ } | null;
33
+ /** Indicates if the store is currently within an active transaction block. */
34
+ transactionActive: boolean;
40
35
  }
41
36
  /**
42
37
  * Event types emitted by the state store for observability and debugging.
@@ -63,194 +58,191 @@ type TransformMiddleware<T> = (state: T, changes: DeepPartial<T>) => Promise<Dee
63
58
  * It returns a boolean or an object containing a `block` boolean and an optional `error`.
64
59
  */
65
60
  type BlockingMiddleware<T> = (state: T, changes: DeepPartial<T>) => Promise<boolean | {
66
- block: boolean;
67
- error?: Error;
61
+ block: boolean;
62
+ error?: Error;
68
63
  }> | boolean | {
69
- block: boolean;
70
- error?: Error;
64
+ block: boolean;
65
+ error?: Error;
71
66
  };
72
67
  /**
73
68
  * Type representing the configuration object passed to the `use` method to register a middleware.
74
69
  */
75
70
  interface MiddlewareConfig<T> {
76
- /** The middleware function (can be a transform or blocking middleware). */
77
- action: TransformMiddleware<T> | BlockingMiddleware<T>;
78
- /** An optional, human-readable name for the middleware. */
79
- name?: string;
80
- /** If true, the middleware is treated as a blocking middleware (must return a boolean or `{ block: boolean }`). */
81
- block?: boolean;
71
+ /** The middleware function (can be a transform or blocking middleware). */
72
+ action: TransformMiddleware<T> | BlockingMiddleware<T>;
73
+ /** An optional, human-readable name for the middleware. */
74
+ name?: string;
75
+ /** If true, the middleware is treated as a blocking middleware (must return a boolean or `{ block: boolean }`). */
76
+ block?: boolean;
82
77
  }
83
78
  /**
84
79
  * Interface for a reactive selector result, providing access to the value and subscription capabilities.
85
80
  */
86
81
  interface ReactiveSelector<S> {
87
- /** Unique identifier for the selector. */
88
- id: string;
89
- /** Function to get the current computed value of the selector. */
90
- get: () => S;
91
- /**
92
- * Subscribes a callback function to run whenever the selector's result changes.
93
- * Returns an unsubscribe function.
94
- */
95
- subscribe: (callback: (state: S) => void) => () => void;
82
+ /** Unique identifier for the selector. */
83
+ id: string;
84
+ /** Function to get the current computed value of the selector. */
85
+ get: () => S;
86
+ /**
87
+ * Subscribes a callback function to run whenever the selector's result changes.
88
+ * Returns an unsubscribe function.
89
+ */
90
+ subscribe: (callback: (state: S) => void) => () => void;
96
91
  }
97
92
  interface ActionWatcher {
98
- /** Unique identifier for the action */
99
- name: string;
100
- /** Function to get the current computed value of the action. */
101
- status: () => boolean;
102
- /**
103
- * Subscribes a callback function to run whenever the action's status changes.
104
- * Returns an unsubscribe function.
105
- */
106
- subscribe: (callback: () => void) => () => void;
93
+ /** Unique identifier for the action */
94
+ name: string;
95
+ /** Function to get the current computed value of the action. */
96
+ status: () => boolean;
97
+ /**
98
+ * Subscribes a callback function to run whenever the action's status changes.
99
+ * Returns an unsubscribe function.
100
+ */
101
+ subscribe: (callback: () => void) => () => void;
107
102
  }
108
103
  interface TransactionOptions {
109
- /** If true, blocks resolution until changes are fully committed to the database row */
110
- flush?: boolean;
104
+ /** If true, blocks resolution until changes are fully committed to the database row */
105
+ flush?: boolean;
111
106
  }
112
107
  /**
113
108
  * Interface defining the contract for the core data state store.
114
109
  * T must be an object type.
115
110
  */
116
111
  interface DataStore<T extends object> {
117
- /**
118
- * Gets the current state of the store.
119
- * @param clone If true, returns a deep clone of the state; otherwise, returns the internal state reference.
120
- * @returns The current state T.
121
- */
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;
130
- /**
131
- * Registers a named action function that can modify the state.
132
- * @param action The action configuration object.
133
- * @returns A function to unregister the action.
134
- */
135
- register<R extends any[]>(action: {
136
- name: string;
137
- fn: (state: T, ...args: R) => DeepPartial<T> | Promise<DeepPartial<T>>;
138
- debounce?: {
139
- delay: number;
140
- condition?: (previous: R, current: R) => boolean;
141
- };
142
- }): () => void;
143
- /**
144
- * Executes (dispatches) a previously registered action by its name.
145
- * @param name The name of the action.
146
- * @param args The parameters to pass to the action function.
147
- * @returns A promise that resolves to the final state after the action and subsequent updates are complete.
148
- */
149
- dispatch<R extends any[]>(name: string, ...args: R): Promise<T>;
150
- /**
151
- * Sets or updates the state using a StateUpdater.
152
- * @param update The new state, partial state, or a function returning a partial state.
153
- * @param options Configuration options for the set operation.
154
- * @returns A promise that resolves to the current state when the update is complete.
155
- */
156
- set(update: StateUpdater<T>, options?: {
157
- force?: boolean;
158
- actionId?: string;
159
- }): Promise<T>;
160
- /**
161
- * Creates a reactive selector that computes a derived value and tracks dependencies.
162
- * @param selector A function to compute the derived state value S from the full state T.
163
- * @returns A `ReactiveSelector<S>` object.
164
- */
165
- select<S>(selector: (state: T) => S): ReactiveSelector<S>;
166
- /**
167
- * Subscribes a callback to run when the data at the specified path(s) changes.
168
- * @param path A single path string or an array of path strings to watch.
169
- * @param callback The function to execute when a change occurs in the watched path(s).
170
- * @param options Extra options to pass to the event bus
171
- * @returns An unsubscribe function.
172
- */
173
- watch(path: string | Array<string>, callback: (state: T) => void, options?: SubscribeOptions): () => void;
174
- /**
175
- * Subscribes to execution‑status changes of a registered action.
176
- *
177
- * The provided callback is called **every time** the action transitions
178
- * between idle and running (i.e. on `action:start`, `action:complete`, or
179
- * `action:error` for the given name). The current status can also be read
180
- * synchronously with `isActionRunning(name)`.
181
- *
182
- * **Deferred listener teardown**
183
- * To avoid unnecessary churn when subscriptions are rapidly created and
184
- * destroyed, the underlying event listeners are not removed immediately
185
- * on unsubscribe. Instead, a *pending reset* is queued via `queueMicrotask`.
186
- * If a new subscription for the same action arrives before that microtask
187
- * executes, the reset is silently cancelled and the already‑established
188
- * listeners are reused. This keeps the subscription infrastructure stable
189
- * and prevents cascading notifications that could otherwise arise from
190
- * repeated subscribe‑unsubscribe‑subscribe cycles.
191
- *
192
- * @param name - The name of the action to watch.
193
- * @returns An ActionWatcher
194
- */
195
- watchAction(name: string): ActionWatcher;
196
- /**
197
- * Executes an operation function within a transaction block.
198
- * All state updates (`set` or actions) within the transaction are batched and applied atomically (all or nothing).
199
- * @param operation The function containing the state updates.
200
- * @returns A promise that resolves to the return value of the operation function.
201
- */
202
- transaction<R>(operation: () => R | Promise<R>, options?: TransactionOptions): Promise<R>;
203
- /**
204
- * Registers a middleware function to intercept state updates.
205
- * @param props The middleware configuration.
206
- * @returns A function to unregister the middleware.
207
- */
208
- use(props: MiddlewareConfig<T>): () => boolean;
209
- /**
210
- * Subscribes a listener to a specific store event type.
211
- * @param event The type of store event to listen for.
212
- * @param listener The callback function to execute when the event fires.
213
- * @returns An unsubscribe function.
214
- */
215
- on(event: StoreEvent, listener: (data: any) => void): () => void;
216
- /**
217
- * Returns the unique identifier of the store instance.
218
- */
219
- id(): string;
220
- /**
221
- * Checks whether the store is fully initialized and ready for use.
222
- */
223
- isReady(): boolean;
224
- /**
225
- * Returns a promise that resolves once the store is fully initialised.
226
- * Safe to call multiple times — all callers share the same latch.
227
- *
228
- * @param timeout - Optional maximum wait time in milliseconds.
229
- * @throws {TimeoutError} If the store does not become ready within the timeout.
230
- *
231
- * @example
232
- * await store.ready();
233
- * const state = store.get();
234
- */
235
- ready(timeout?: number): Promise<void>;
236
- /**
237
- * Returns a readonly snapshot of the current execution state of the store.
238
- */
239
- state(): Readonly<StoreExecutionState<T>>;
240
- /**
241
- * Releases all resources held by the store and renders it unusable
242
- */
243
- dispose(): Promise<void>;
112
+ /**
113
+ * Gets the current state of the store.
114
+ * @param clone If true, returns a deep clone of the state; otherwise, returns the internal state reference.
115
+ * @returns The current state T.
116
+ */
117
+ get(clone?: boolean): T;
118
+ /**
119
+ * Gets a subset of the store.
120
+ * @param paths The paths which to include in the returned object.
121
+ * @param separator Optional separator for paths. Defaults to `.` .
122
+ * @returns An object of the shape K mapping paths to their current values.
123
+ */
124
+ subset<K extends Record<string, any> = Record<string, any>>(paths: Array<string>, separator?: string): K;
125
+ /**
126
+ * Registers a named action function that can modify the state.
127
+ * @param action The action configuration object.
128
+ * @returns A function to unregister the action.
129
+ */
130
+ register<R extends any[]>(action: {
131
+ name: string;
132
+ fn: (state: T, ...args: R) => DeepPartial<T> | Promise<DeepPartial<T>>;
133
+ debounce?: {
134
+ delay: number;
135
+ condition?: (previous: R, current: R) => boolean;
136
+ };
137
+ }): () => void;
138
+ /**
139
+ * Executes (dispatches) a previously registered action by its name.
140
+ * @param name The name of the action.
141
+ * @param args The parameters to pass to the action function.
142
+ * @returns A promise that resolves to the final state after the action and subsequent updates are complete.
143
+ */
144
+ dispatch<R extends any[]>(name: string, ...args: R): Promise<T>;
145
+ /**
146
+ * Sets or updates the state using a StateUpdater.
147
+ * @param update The new state, partial state, or a function returning a partial state.
148
+ * @param options Configuration options for the set operation.
149
+ * @returns A promise that resolves to the current state when the update is complete.
150
+ */
151
+ set(update: StateUpdater<T>, options?: {
152
+ force?: boolean;
153
+ actionId?: string;
154
+ }): Promise<T>;
155
+ /**
156
+ * Creates a reactive selector that computes a derived value and tracks dependencies.
157
+ * @param selector A function to compute the derived state value S from the full state T.
158
+ * @returns A `ReactiveSelector<S>` object.
159
+ */
160
+ select<S>(selector: (state: T) => S): ReactiveSelector<S>;
161
+ /**
162
+ * Subscribes a callback to run when the data at the specified path(s) changes.
163
+ * @param path A single path string or an array of path strings to watch.
164
+ * @param callback The function to execute when a change occurs in the watched path(s).
165
+ * @param options Extra options to pass to the event bus
166
+ * @returns An unsubscribe function.
167
+ */
168
+ watch(path: string | Array<string>, callback: (state: T) => void, options?: SubscribeOptions): () => void;
169
+ /**
170
+ * Subscribes to execution‑status changes of a registered action.
171
+ *
172
+ * The provided callback is called **every time** the action transitions
173
+ * between idle and running (i.e. on `action:start`, `action:complete`, or
174
+ * `action:error` for the given name). The current status can also be read
175
+ * synchronously with `isActionRunning(name)`.
176
+ *
177
+ * **Deferred listener teardown**
178
+ * To avoid unnecessary churn when subscriptions are rapidly created and
179
+ * destroyed, the underlying event listeners are not removed immediately
180
+ * on unsubscribe. Instead, a *pending reset* is queued via `queueMicrotask`.
181
+ * If a new subscription for the same action arrives before that microtask
182
+ * executes, the reset is silently cancelled and the already‑established
183
+ * listeners are reused. This keeps the subscription infrastructure stable
184
+ * and prevents cascading notifications that could otherwise arise from
185
+ * repeated subscribe‑unsubscribe‑subscribe cycles.
186
+ *
187
+ * @param name - The name of the action to watch.
188
+ * @returns An ActionWatcher
189
+ */
190
+ watchAction(name: string): ActionWatcher;
191
+ /**
192
+ * Executes an operation function within a transaction block.
193
+ * All state updates (`set` or actions) within the transaction are batched and applied atomically (all or nothing).
194
+ * @param operation The function containing the state updates.
195
+ * @returns A promise that resolves to the return value of the operation function.
196
+ */
197
+ transaction<R>(operation: () => R | Promise<R>, options?: TransactionOptions): Promise<R>;
198
+ /**
199
+ * Registers a middleware function to intercept state updates.
200
+ * @param props The middleware configuration.
201
+ * @returns A function to unregister the middleware.
202
+ */
203
+ use(props: MiddlewareConfig<T>): () => boolean;
204
+ /**
205
+ * Subscribes a listener to a specific store event type.
206
+ * @param event The type of store event to listen for.
207
+ * @param listener The callback function to execute when the event fires.
208
+ * @returns An unsubscribe function.
209
+ */
210
+ on(event: StoreEvent, listener: (data: any) => void): () => void;
211
+ /**
212
+ * Returns the unique identifier of the store instance.
213
+ */
214
+ id(): string;
215
+ /**
216
+ * Checks whether the store is fully initialized and ready for use.
217
+ */
218
+ isReady(): boolean;
219
+ /**
220
+ * Returns a promise that resolves once the store is fully initialised.
221
+ * Safe to call multiple times — all callers share the same latch.
222
+ *
223
+ * @param timeout - Optional maximum wait time in milliseconds.
224
+ * @throws {TimeoutError} If the store does not become ready within the timeout.
225
+ *
226
+ * @example
227
+ * await store.ready();
228
+ * const state = store.get();
229
+ */
230
+ ready(timeout?: number): Promise<void>;
231
+ /**
232
+ * Returns a readonly snapshot of the current execution state of the store.
233
+ */
234
+ state(): Readonly<StoreExecutionState<T>>;
235
+ /**
236
+ * Releases all resources held by the store and renders it unusable
237
+ */
238
+ dispose(): Promise<void>;
244
239
  }
245
-
246
- /**
247
- * Defines the lifecycle and sharing strategy for an artifact within the container.
248
- */
249
-
240
+ //#endregion
241
+ //#region src/artifacts/types.d.ts
250
242
  /**
251
243
  * Defines the lifecycle and sharing strategy for an artifact.
252
244
  */
253
- type ArtifactScope =
245
+ type ArtifactScope =
254
246
  /**
255
247
  * **Singleton:** A single instance of the artifact is created and shared across all resolutions
256
248
  * within the container. It is created once (often lazily) and reused until invalidated.
@@ -260,42 +252,42 @@ type ArtifactScope =
260
252
  * **Transient:** A new instance of the artifact is created every time it is resolved.
261
253
  * Transient artifacts do not participate in caching or shared state management.
262
254
  */
263
- | "transient";
255
+ | "transient";
264
256
  /**
265
257
  * Enumeration of standard artifact scopes for strongly typed configuration.
266
258
  */
267
259
  declare enum ArtifactScopes {
268
- /** A single instance is shared globally. */
269
- Singleton = "singleton",
270
- /** A new instance is created on every resolution. */
271
- Transient = "transient"
260
+ /** A single instance is shared globally. */
261
+ Singleton = "singleton",
262
+ /** A new instance is created on every resolution. */
263
+ Transient = "transient"
272
264
  }
273
265
  /**
274
266
  * Represents a snapshot of an artifact's state and dependencies for debugging purposes.
275
267
  * Provides insight into the artifact's current status and its position within the dependency graph.
276
268
  */
277
269
  interface ArtifactDebugNode {
278
- /** The unique identifier (key) of the artifact. */
279
- id: string;
280
- /** The scope of the artifact (Singleton or Transient). */
281
- scope: ArtifactScope;
282
- /**
283
- * The current status of the artifact, indicating its lifecycle phase.
284
- * - `'active'`: The artifact is successfully built and its instance is available.
285
- * - `'error'`: The artifact failed to build due to an external (runtime) error.
286
- * - `'idle'`: The artifact has not yet been built (for lazy singletons) or has been disposed.
287
- * - `'building'`: The artifact's factory is currently executing.
288
- * - `'pending'`: The artifact is waiting to be built, often after an invalidation and before any debounce.
289
- */
290
- status: "active" | "error" | "idle" | "building" | "pending" | "debouncing";
291
- /** A list of artifact keys that this artifact directly depends on. */
292
- dependencies: string[];
293
- /** A list of artifact keys that directly depend on this artifact (its consumers). */
294
- dependents: string[];
295
- /** A list of state paths (selectors) that this artifact depends on. */
296
- stateDependencies: string[];
297
- /** The number of times this artifact's factory has been successfully executed/rebuilt. */
298
- buildCount: number;
270
+ /** The unique identifier (key) of the artifact. */
271
+ id: string;
272
+ /** The scope of the artifact (Singleton or Transient). */
273
+ scope: ArtifactScope;
274
+ /**
275
+ * The current status of the artifact, indicating its lifecycle phase.
276
+ * - `'active'`: The artifact is successfully built and its instance is available.
277
+ * - `'error'`: The artifact failed to build due to an external (runtime) error.
278
+ * - `'idle'`: The artifact has not yet been built (for lazy singletons) or has been disposed.
279
+ * - `'building'`: The artifact's factory is currently executing.
280
+ * - `'pending'`: The artifact is waiting to be built, often after an invalidation and before any debounce.
281
+ */
282
+ status: "active" | "error" | "idle" | "building" | "pending" | "debouncing";
283
+ /** A list of artifact keys that this artifact directly depends on. */
284
+ dependencies: string[];
285
+ /** A list of artifact keys that directly depend on this artifact (its consumers). */
286
+ dependents: string[];
287
+ /** A list of state paths (selectors) that this artifact depends on. */
288
+ stateDependencies: string[];
289
+ /** The number of times this artifact's factory has been successfully executed/rebuilt. */
290
+ buildCount: number;
299
291
  }
300
292
  /**
301
293
  * Context provided to the `use` callback within an artifact factory.
@@ -304,37 +296,37 @@ interface ArtifactDebugNode {
304
296
  * @template TState The type of the global state managed by the DataStore.
305
297
  */
306
298
  interface UseDependencyContext<TRegistry extends Record<string, any>, TState extends object> {
307
- /**
308
- * Resolves another artifact from the container and registers a dependency on it.
309
- * If the dependency changes, the current artifact will be invalidated and rebuilt.
310
- * @template K The key of the artifact to resolve.
311
- * @param key The key of the artifact to resolve.
312
- * @param params Parameters with which to resolve the artifact
313
- * @returns A Promise that resolves to a `ResolvedArtifact` containing the instance
314
- * or an external error.
315
- * @throws {SystemError} if the key is missing or if resolving creates a circular dependency.
316
- */
317
- resolve<K extends keyof TRegistry>(key: K, params?: any): Promise<ResolvedArtifact<TRegistry[K]>>;
318
- /**
319
- * Resolves another artifact from the container and registers a dependency on it.
320
- * If the dependency changes, the current artifact will be invalidated and rebuilt.
321
- * @template K The key of the artifact to resolve.
322
- * @param key The key of the artifact to resolve.
323
- * @param params Parameters with which to resolve the artifact
324
- * @returns A Promise that resolves to a the resolved instance, unlike
325
- * resolve, this will throw an error if resolution fails.
326
- * @throws {SystemError} if any error occurs during resolution.
327
- */
328
- require<K extends keyof TRegistry>(key: K, params?: any): Promise<TRegistry[K]>;
329
- /**
330
- * Selects a slice of the global state and registers a dependency on it.
331
- * If the selected state slice changes (based on a deep comparison), the current
332
- * artifact will be invalidated and rebuilt.
333
- * @template S The type of the selected state slice.
334
- * @param selector A function that takes the full state and returns a slice of state.
335
- * @returns The selected slice of state.
336
- */
337
- select<S>(selector: (state: TState) => S, options?: SubscribeOptions): S;
299
+ /**
300
+ * Resolves another artifact from the container and registers a dependency on it.
301
+ * If the dependency changes, the current artifact will be invalidated and rebuilt.
302
+ * @template K The key of the artifact to resolve.
303
+ * @param key The key of the artifact to resolve.
304
+ * @param params Parameters with which to resolve the artifact
305
+ * @returns A Promise that resolves to a `ResolvedArtifact` containing the instance
306
+ * or an external error.
307
+ * @throws {SystemError} if the key is missing or if resolving creates a circular dependency.
308
+ */
309
+ resolve<K extends keyof TRegistry>(key: K, params?: any): Promise<ResolvedArtifact<TRegistry[K]>>;
310
+ /**
311
+ * Resolves another artifact from the container and registers a dependency on it.
312
+ * If the dependency changes, the current artifact will be invalidated and rebuilt.
313
+ * @template K The key of the artifact to resolve.
314
+ * @param key The key of the artifact to resolve.
315
+ * @param params Parameters with which to resolve the artifact
316
+ * @returns A Promise that resolves to a the resolved instance, unlike
317
+ * resolve, this will throw an error if resolution fails.
318
+ * @throws {SystemError} if any error occurs during resolution.
319
+ */
320
+ require<K extends keyof TRegistry>(key: K, params?: any): Promise<TRegistry[K]>;
321
+ /**
322
+ * Selects a slice of the global state and registers a dependency on it.
323
+ * If the selected state slice changes (based on a deep comparison), the current
324
+ * artifact will be invalidated and rebuilt.
325
+ * @template S The type of the selected state slice.
326
+ * @param selector A function that takes the full state and returns a slice of state.
327
+ * @returns The selected slice of state.
328
+ */
329
+ select<S>(selector: (state: TState) => S, options?: SubscribeOptions$1): S;
338
330
  }
339
331
  /**
340
332
  * Context object provided to an artifact stream producer function (`ctx.stream` callback).
@@ -345,38 +337,38 @@ interface UseDependencyContext<TRegistry extends Record<string, any>, TState ext
345
337
  * @template TArtifact The type of the artifact being streamed.
346
338
  */
347
339
  type ArtifactStreamContext<TState, TArtifact> = {
348
- /**
349
- * The current value of the artifact. This is `undefined` before the first value is emitted.
350
- * Useful for diffing or migrating state during an update.
351
- * @returns The current artifact value or `undefined`.
352
- */
353
- value: () => TArtifact | undefined;
354
- /**
355
- * An AbortSignal that indicates if the stream has been cancelled or aborted
356
- * from the consumer side (e.g., due to container disposal or artifact invalidation).
357
- * Producers should check this signal and stop processing when it is set to prevent leaks.
358
- */
359
- signal: AbortSignal;
360
- /**
361
- * A function to asynchronously emit a new value of the artifact to the container.
362
- * Calling this function updates the artifact's resolved value, triggers invalidation
363
- * for its dependents, and updates the `value()` property for subsequent emissions.
364
- *
365
- * @param value The new artifact value to emit.
366
- * @returns A Promise that resolves when the value has been sent and dependents have been notified.
367
- */
368
- emit: (value: TArtifact) => Promise<void>;
369
- /**
370
- * Dispatches a state update to the global store, analogous to a standard `setState`.
371
- * **Note:** This does not automatically register a dependency for the current artifact.
372
- * @param update A `StateUpdater` function or a partial state object.
373
- * @param options Optional settings for the update, including `force` and `actionId`.
374
- * @returns A Promise that resolves when the state update is complete.
375
- */
376
- set(update: StateUpdater<TState>, options?: {
377
- force?: boolean;
378
- actionId?: string;
379
- }): Promise<any>;
340
+ /**
341
+ * The current value of the artifact. This is `undefined` before the first value is emitted.
342
+ * Useful for diffing or migrating state during an update.
343
+ * @returns The current artifact value or `undefined`.
344
+ */
345
+ value: () => TArtifact | undefined;
346
+ /**
347
+ * An AbortSignal that indicates if the stream has been cancelled or aborted
348
+ * from the consumer side (e.g., due to container disposal or artifact invalidation).
349
+ * Producers should check this signal and stop processing when it is set to prevent leaks.
350
+ */
351
+ signal: AbortSignal;
352
+ /**
353
+ * A function to asynchronously emit a new value of the artifact to the container.
354
+ * Calling this function updates the artifact's resolved value, triggers invalidation
355
+ * for its dependents, and updates the `value()` property for subsequent emissions.
356
+ *
357
+ * @param value The new artifact value to emit.
358
+ * @returns A Promise that resolves when the value has been sent and dependents have been notified.
359
+ */
360
+ emit: (value: TArtifact) => Promise<void>;
361
+ /**
362
+ * Dispatches a state update to the global store, analogous to a standard `setState`.
363
+ * **Note:** This does not automatically register a dependency for the current artifact.
364
+ * @param update A `StateUpdater` function or a partial state object.
365
+ * @param options Optional settings for the update, including `force` and `actionId`.
366
+ * @returns A Promise that resolves when the state update is complete.
367
+ */
368
+ set(update: StateUpdater<TState>, options?: {
369
+ force?: boolean;
370
+ actionId?: string;
371
+ }): Promise<any>;
380
372
  };
381
373
  /**
382
374
  * The full context provided to an artifact's factory function.
@@ -387,85 +379,115 @@ type ArtifactStreamContext<TState, TArtifact> = {
387
379
  * @template TArtifact The type of the artifact being created by the factory.
388
380
  */
389
381
  type ArtifactFactoryContext<TRegistry extends Record<string, any>, TState extends object, TArtifact, TExtra extends Record<string, any> = {}> = TExtra & {
390
- /**
391
- * Returns the current global state object. This is a non-reactive read;
392
- * changes to the state will not automatically invalidate the artifact
393
- * unless explicitly selected via `ctx.use` and `ctx.select`.
394
- * @returns The current global state.
395
- */
396
- state(): TState;
397
- /**
398
- * The previous instance of the artifact if it's a Singleton and is being rebuilt
399
- * after an invalidation. This is `undefined` on the initial build.
400
- * Useful for diffing, migrating state, or reusing resources during an update.
401
- */
402
- previous?: TArtifact;
403
- /**
404
- * Executes a callback within a dependency tracking context.
405
- * Any `resolve` or `select` calls made inside this callback will register
406
- * dependencies for the current artifact.
407
- * @template R The return type of the callback.
408
- * @param callback The function to execute to resolve dependencies.
409
- * @returns A Promise resolving to the result of the callback.
410
- */
411
- use<R>(callback: (ctx: UseDependencyContext<TRegistry, TState>) => R | Promise<R>): Promise<R>;
412
- /**
413
- * Registers a cleanup function to be executed when the **current instance** of the
414
- * artifact is invalidated and before its new instance is built. This is useful
415
- * for releasing resources (e.g., event listeners) specific to the *previous* instance.
416
- * @param cleanup The cleanup function.
417
- */
418
- onCleanup(cleanup: ArtifactCleanup): void;
419
- /**
420
- * Registers a dispose function to be executed when the artifact is
421
- * permanently removed from the container or the container itself is disposed.
422
- * This is for final, permanent resource release.
423
- * @param callback The dispose function.
424
- */
425
- onDispose(callback: ArtifactCleanup): void;
426
- /**
427
- * Starts a streaming process for a Singleton artifact.
428
- * The callback receives an `ArtifactStreamContext` to emit values and manage the
429
- * stream's lifecycle. It can return a cleanup function (or a Promise resolving
430
- * to one) to handle resource disposal.
431
- * * @param callback - The streaming logic implementation. Can be synchronous or
432
- * asynchronous, optionally returning a cleanup function.
433
- * @throws {SystemError} If called on a Transient artifact, as they do not
434
- * support persistent streaming states.
435
- */
436
- stream(callback: (ctx: ArtifactStreamContext<TState, TArtifact>) => (void | (() => void | Promise<void>)) | Promise<void | (() => void | Promise<void>)>): void;
437
- stream(callback: (ctx: ArtifactStreamContext<TState, TArtifact>) => (void | (() => void | Promise<void>)) | Promise<void | (() => void | Promise<void>)>): void;
438
- /**
439
- * An AbortSignal that indicates if the artifacts has been unregistered
440
- */
441
- signal: AbortSignal;
442
- /** For parameterized artifacts: the parameters that were passed during resolve/watch. */
443
- params?: any;
382
+ /**
383
+ * Returns the current global state object. This is a non-reactive read;
384
+ * changes to the state will not automatically invalidate the artifact
385
+ * unless explicitly selected via `ctx.use` and `ctx.select`.
386
+ * @returns The current global state.
387
+ */
388
+ state(): TState;
389
+ /**
390
+ * The previous instance of the artifact if it's a Singleton and is being rebuilt
391
+ * after an invalidation. This is `undefined` on the initial build.
392
+ * Useful for diffing, migrating state, or reusing resources during an update.
393
+ */
394
+ previous?: TArtifact;
395
+ /**
396
+ * Executes a callback within a dependency tracking context.
397
+ * Any `resolve` or `select` calls made inside this callback will register
398
+ * dependencies for the current artifact.
399
+ * @template R The return type of the callback.
400
+ * @param callback The function to execute to resolve dependencies.
401
+ * @returns A Promise resolving to the result of the callback.
402
+ */
403
+ use<R>(callback: (ctx: UseDependencyContext<TRegistry, TState>) => R | Promise<R>): Promise<R>;
404
+ /**
405
+ * Registers a cleanup function to be executed when the **current instance** of the
406
+ * artifact is invalidated and before its new instance is built. This is useful
407
+ * for releasing resources (e.g., event listeners) specific to the *previous* instance.
408
+ * @param cleanup The cleanup function.
409
+ */
410
+ onCleanup(cleanup: ArtifactCleanup): void;
411
+ /**
412
+ * Registers a dispose function to be executed when the artifact is
413
+ * permanently removed from the container or the container itself is disposed.
414
+ * This is for final, permanent resource release.
415
+ * @param callback The dispose function.
416
+ */
417
+ onDispose(callback: ArtifactCleanup): void;
418
+ /**
419
+ * Starts a streaming process for a Singleton artifact.
420
+ * The callback receives an `ArtifactStreamContext` to emit values and manage the
421
+ * stream's lifecycle. It can return a cleanup function (or a Promise resolving
422
+ * to one) to handle resource disposal.
423
+ * * @param callback - The streaming logic implementation. Can be synchronous or
424
+ * asynchronous, optionally returning a cleanup function.
425
+ * @throws {SystemError} If called on a Transient artifact, as they do not
426
+ * support persistent streaming states.
427
+ */
428
+ stream(callback: (ctx: ArtifactStreamContext<TState, TArtifact>) => (void | (() => void | Promise<void>)) | Promise<void | (() => void | Promise<void>)>): void;
429
+ stream(callback: (ctx: ArtifactStreamContext<TState, TArtifact>) => (void | (() => void | Promise<void>)) | Promise<void | (() => void | Promise<void>)>): void;
430
+ /**
431
+ * An AbortSignal that indicates if the artifacts has been unregistered
432
+ */
433
+ signal: AbortSignal; /** For parameterized artifacts: the parameters that were passed during resolve/watch. */
434
+ params?: any;
444
435
  };
445
436
  /**
446
437
  * A function that performs cleanup or disposal logic for an artifact, potentially asynchronously.
447
438
  * Used for `onCleanup` and `onDispose` callbacks.
448
439
  */
449
440
  type ArtifactCleanup = () => void | Promise<void>;
441
+ interface ArtifactLifecycleEventMap {
442
+ "build:start": {
443
+ key: string;
444
+ templateKey?: string;
445
+ };
446
+ "build:complete": {
447
+ key: string;
448
+ instance: unknown;
449
+ };
450
+ "build:error": {
451
+ key: string;
452
+ error: unknown;
453
+ };
454
+ "artifact:invalidated": {
455
+ key: string;
456
+ cascade: boolean;
457
+ replace: boolean;
458
+ };
459
+ "artifact:disposed": {
460
+ key: string;
461
+ };
462
+ "artifact:registered": {
463
+ key: string;
464
+ scope: ArtifactScope;
465
+ };
466
+ "stream:emit": {
467
+ key: string;
468
+ value: unknown;
469
+ };
470
+ "container:dispose": {};
471
+ }
450
472
  /**
451
473
  * Common properties shared across all possible states of a resolved artifact.
452
474
  * @template TArtifact The type of the resolved artifact instance.
453
475
  */
454
476
  interface ResolvedArtifactBase {
455
- /**
456
- * A function to manually trigger cleanup associated with this specific
457
- * resolved instance. This is typically only relevant for Transient artifacts
458
- * where the consumer is responsible for cleanup.
459
- */
460
- cleanup?: ArtifactCleanup;
461
- /**
462
- * Manually invalidates this artifact, triggering its rebuild and
463
- * cascading invalidations to its dependents.
464
- * @param replace If `true`, forces immediate rebuild without debounce delay.
465
- * @param fatal If `true`, the artifact will not be rebuilt until next resolve
466
- * regardless of the lazy option during registration.
467
- */
468
- invalidate(replace?: boolean, fatal?: boolean): Promise<void>;
477
+ /**
478
+ * A function to manually trigger cleanup associated with this specific
479
+ * resolved instance. This is typically only relevant for Transient artifacts
480
+ * where the consumer is responsible for cleanup.
481
+ */
482
+ cleanup?: ArtifactCleanup;
483
+ /**
484
+ * Manually invalidates this artifact, triggering its rebuild and
485
+ * cascading invalidations to its dependents.
486
+ * @param replace If `true`, forces immediate rebuild without debounce delay.
487
+ * @param fatal If `true`, the artifact will not be rebuilt until next resolve
488
+ * regardless of the lazy option during registration.
489
+ */
490
+ invalidate(replace?: boolean, fatal?: boolean): Promise<void>;
469
491
  }
470
492
  /**
471
493
  * State of an artifact that is successfully built and ready for use.
@@ -473,34 +495,34 @@ interface ResolvedArtifactBase {
473
495
  * @template TArtifact The type of the resolved artifact instance.
474
496
  */
475
497
  interface ReadyArtifact<TArtifact> extends ResolvedArtifactBase {
476
- /** The successfully resolved instance of the artifact. */
477
- instance: TArtifact;
478
- /** Indicates whether the artifact is ready and has an instance. */
479
- ready: true;
480
- error?: undefined;
498
+ /** The successfully resolved instance of the artifact. */
499
+ instance: TArtifact;
500
+ /** Indicates whether the artifact is ready and has an instance. */
501
+ ready: true;
502
+ error?: undefined;
481
503
  }
482
504
  /**
483
505
  * State of an artifact that failed to build due to an external error.
484
506
  * The instance is guaranteed to be absent.
485
507
  */
486
508
  interface ErrorArtifact extends ResolvedArtifactBase {
487
- instance?: undefined;
488
- ready: false;
489
- /**
490
- * Any runtime or external error that occurred during the artifact's factory
491
- * execution (e.g., network fetch failed).
492
- */
493
- error: any;
509
+ instance?: undefined;
510
+ ready: false;
511
+ /**
512
+ * Any runtime or external error that occurred during the artifact's factory
513
+ * execution (e.g., network fetch failed).
514
+ */
515
+ error: any;
494
516
  }
495
517
  /**
496
518
  * State of an artifact that is pending, idle, or currently building.
497
519
  * Both instance and error are absent.
498
520
  */
499
521
  interface PendingArtifact extends ResolvedArtifactBase {
500
- /** The instance is absent while pending or idle. Always undefined. */
501
- instance?: undefined;
502
- ready: false;
503
- error?: undefined;
522
+ /** The instance is absent while pending or idle. Always undefined. */
523
+ instance?: undefined;
524
+ ready: false;
525
+ error?: undefined;
504
526
  }
505
527
  /**
506
528
  * The result of an artifact resolution. This is a union type representing
@@ -512,9 +534,7 @@ interface PendingArtifact extends ResolvedArtifactBase {
512
534
  * @template TArtifact The type of the resolved artifact instance.
513
535
  */
514
536
  type ResolvedArtifact<TArtifact> = ReadyArtifact<TArtifact> | ErrorArtifact | PendingArtifact;
515
- type KeyedResolvedArtifact<TRegistry, K extends keyof TRegistry> = ResolvedArtifact<TRegistry[K]> & {
516
- [P in K]?: TRegistry[K];
517
- };
537
+ type KeyedResolvedArtifact<TRegistry, K extends keyof TRegistry> = ResolvedArtifact<TRegistry[K]> & { [P in K]?: TRegistry[K] };
518
538
  /**
519
539
  * The factory function responsible for creating an artifact's instance.
520
540
  * It receives an `ArtifactFactoryContext` to interact with the container
@@ -534,37 +554,37 @@ type ArtifactInstance<R> = R extends PromiseLike<infer T> ? T : R;
534
554
  * @template TArtifact The type of the artifact being watched.
535
555
  */
536
556
  interface ArtifactObserver<TRegistry, K extends keyof TRegistry> {
537
- /** The unique identifier (key) of the artifact being watched. */
538
- id: string;
539
- /**
540
- * Number of active references (watchers) to this observer instance.
541
- * Incremented on each `watch()` call, decremented on each `dispose()` call.
542
- */
543
- count: number;
544
- /**
545
- * Retrieves the current `ResolvedArtifact` for the watched key.
546
- * @param resolve Flag indicating whether we should resolve the artifact
547
- * immediately. Defaults to `false`
548
- * @returns The resolved artifact, including its instance and status.
549
- */
550
- get(resolve?: boolean): KeyedResolvedArtifact<TRegistry, K>;
551
- /**
552
- * Subscribes a callback function to be invoked whenever the artifact's
553
- * state (instance, error, or readiness) changes.
554
- * @param callback The function to call on updates. It receives the new `ResolvedArtifact`.
555
- * @param eager a boolean indicating whether we should immediately call the
556
- * callback after subscription. Defaults to `true`
557
- * @returns A function to unsubscribe the callback and stop receiving updates.
558
- */
559
- subscribe(callback: (artifact: KeyedResolvedArtifact<TRegistry, K>) => void, eager?: boolean): () => void;
560
- /**
561
- * Resolves another artifact from the container and registers a dependency on it.
562
- * If the dependency changes, the current artifact will be invalidated and rebuilt.
563
- * @returns A Promise that resolves to a `ResolvedArtifact` containing the instance
564
- * or an external error.
565
- * @throws {SystemError} if resolution fails.
566
- */
567
- resolve(): Promise<KeyedResolvedArtifact<TRegistry, K>>;
557
+ /** The unique identifier (key) of the artifact being watched. */
558
+ id: string;
559
+ /**
560
+ * Number of active references (watchers) to this observer instance.
561
+ * Incremented on each `watch()` call, decremented on each `dispose()` call.
562
+ */
563
+ count: number;
564
+ /**
565
+ * Retrieves the current `ResolvedArtifact` for the watched key.
566
+ * @param resolve Flag indicating whether we should resolve the artifact
567
+ * immediately. Defaults to `false`
568
+ * @returns The resolved artifact, including its instance and status.
569
+ */
570
+ get(resolve?: boolean): KeyedResolvedArtifact<TRegistry, K>;
571
+ /**
572
+ * Subscribes a callback function to be invoked whenever the artifact's
573
+ * state (instance, error, or readiness) changes.
574
+ * @param callback The function to call on updates. It receives the new `ResolvedArtifact`.
575
+ * @param eager a boolean indicating whether we should immediately call the
576
+ * callback after subscription. Defaults to `true`
577
+ * @returns A function to unsubscribe the callback and stop receiving updates.
578
+ */
579
+ subscribe(callback: (artifact: KeyedResolvedArtifact<TRegistry, K>) => void, eager?: boolean): () => void;
580
+ /**
581
+ * Resolves another artifact from the container and registers a dependency on it.
582
+ * If the dependency changes, the current artifact will be invalidated and rebuilt.
583
+ * @returns A Promise that resolves to a `ResolvedArtifact` containing the instance
584
+ * or an external error.
585
+ * @throws {SystemError} if resolution fails.
586
+ */
587
+ resolve(): Promise<KeyedResolvedArtifact<TRegistry, K>>;
568
588
  }
569
589
  /**
570
590
  * Configuration options for defining an artifact. These options control
@@ -574,41 +594,41 @@ interface ArtifactObserver<TRegistry, K extends keyof TRegistry> {
574
594
  * @template TRegistry The type mapping of all artifacts in the container.
575
595
  */
576
596
  interface ArtifactTemplate<TState extends object, TArtifact, TRegistry extends Record<string, any> = Record<string, any>, TExtra extends Record<string, any> = {}> {
577
- /** The unique key identifying this artifact within the registry. */
578
- key: keyof TRegistry;
579
- /** The factory function responsible for creating the artifact's instance. */
580
- factory: ArtifactFactory<TRegistry, TState, TArtifact, TExtra>;
581
- /**
582
- * The scope of the artifact, determining its lifecycle and sharing strategy.
583
- * Defaults to `ArtifactScopes.Singleton`.
584
- */
585
- scope?: ArtifactScope;
586
- /**
587
- * If `true` (default), the artifact's factory is executed only when the artifact
588
- * is first requested (lazy instantiation). If `false`, the artifact is built
589
- * immediately upon registration (only applies to Singleton scopes).
590
- */
591
- lazy?: boolean;
592
- /**
593
- * Maximum time in milliseconds allowed for the artifact's factory function
594
- * to complete execution. If exceeded, the factory will time out.
595
- */
596
- timeout?: number;
597
- /**
598
- * Number of times to retry the artifact's factory on failure due to an
599
- * external (runtime) error (e.g., an exception in an async dependency).
600
- * SystemErrors (e.g., key not found) are not retried. Defaults to `0`.
601
- */
602
- retries?: number;
603
- /**
604
- * Base debounce time in milliseconds for invalidation events originating
605
- * from this artifact's dependencies. This delays the rebuild process to
606
- * aggregate multiple rapid changes.
607
- */
608
- debounce?: number;
609
- /** If defined, the artifact is parameterized. Receives the user‑supplied params and returns a unique string key. */
610
- paramKey?: (params: Record<string, unknown>) => string;
611
- virtual?: true;
597
+ /** The unique key identifying this artifact within the registry. */
598
+ key: keyof TRegistry;
599
+ /** The factory function responsible for creating the artifact's instance. */
600
+ factory: ArtifactFactory<TRegistry, TState, TArtifact, TExtra>;
601
+ /**
602
+ * The scope of the artifact, determining its lifecycle and sharing strategy.
603
+ * Defaults to `ArtifactScopes.Singleton`.
604
+ */
605
+ scope?: ArtifactScope;
606
+ /**
607
+ * If `true` (default), the artifact's factory is executed only when the artifact
608
+ * is first requested (lazy instantiation). If `false`, the artifact is built
609
+ * immediately upon registration (only applies to Singleton scopes).
610
+ */
611
+ lazy?: boolean;
612
+ /**
613
+ * Maximum time in milliseconds allowed for the artifact's factory function
614
+ * to complete execution. If exceeded, the factory will time out.
615
+ */
616
+ timeout?: number;
617
+ /**
618
+ * Number of times to retry the artifact's factory on failure due to an
619
+ * external (runtime) error (e.g., an exception in an async dependency).
620
+ * SystemErrors (e.g., key not found) are not retried. Defaults to `0`.
621
+ */
622
+ retries?: number;
623
+ /**
624
+ * Base debounce time in milliseconds for invalidation events originating
625
+ * from this artifact's dependencies. This delays the rebuild process to
626
+ * aggregate multiple rapid changes.
627
+ */
628
+ debounce?: number;
629
+ /** If defined, the artifact is parameterized. Receives the user‑supplied params and returns a unique string key. */
630
+ paramKey?: (params: Record<string, unknown>) => string;
631
+ virtual?: true;
612
632
  }
613
633
  /**
614
634
  * Extracts the global state type (`TState`) from an `ArtifactTemplate`.
@@ -622,13 +642,13 @@ type ArtifactRegistryType<T> = T extends ArtifactTemplate<any, any, infer TRegis
622
642
  * Extracts the key type (`K`) from an `ArtifactTemplate` (as a string literal if possible).
623
643
  */
624
644
  type ArtifactKey<T> = T extends {
625
- key: infer K;
645
+ key: infer K;
626
646
  } ? K : never;
627
647
  /**
628
648
  * Extracts the scope type (`S`) from an `ArtifactTemplate`, defaulting to `ArtifactScope` if undefined.
629
649
  */
630
650
  type ArtifactScopeType<T> = T extends {
631
- scope: infer S;
651
+ scope: infer S;
632
652
  } ? S extends ArtifactScope ? S : ArtifactScope : ArtifactScope;
633
653
  /**
634
654
  * Helper type that creates a properly typed template map where keys correspond to artifact names
@@ -636,9 +656,7 @@ type ArtifactScopeType<T> = T extends {
636
656
  * @template TState The type of the global state.
637
657
  * @template TRegistry The map of all artifact keys to their resolved types.
638
658
  */
639
- type ArtifactTemplateMap<TState extends object, TRegistry extends Record<string, any> = Record<string, any>> = {
640
- [K in keyof TRegistry]: ArtifactTemplate<TState, TRegistry[K], TRegistry>;
641
- };
659
+ type ArtifactTemplateMap<TState extends object, TRegistry extends Record<string, any> = Record<string, any>> = { [K in keyof TRegistry]: ArtifactTemplate<TState, TRegistry[K], TRegistry> };
642
660
  /**
643
661
  * Extracts the artifact's resolved value type (`TArtifact`) from an object that structurally
644
662
  * resembles an `ArtifactTemplate` (by inspecting the `factory` function's generic arguments).
@@ -646,7 +664,7 @@ type ArtifactTemplateMap<TState extends object, TRegistry extends Record<string,
646
664
  * @template T The type that contains a factory property.
647
665
  */
648
666
  type ArtifactValue<T> = T extends {
649
- factory: ArtifactFactory<any, any, infer TArtifact, any>;
667
+ factory: ArtifactFactory<any, any, infer TArtifact, any>;
650
668
  } ? TArtifact : never;
651
669
  /**
652
670
  * Infers the complete Artifact Registry type from a map of artifact configuration objects.
@@ -657,186 +675,99 @@ type ArtifactValue<T> = T extends {
657
675
  * @template T A map where keys are artifact names and values are their configurations.
658
676
  */
659
677
  type InferRegistry<T extends Record<string, {
660
- factory: (...args: any[]) => any;
661
- [key: string]: any;
662
- }>> = {
663
- [K in keyof T]: ArtifactValue<T[K]>;
664
- };
678
+ factory: (...args: any[]) => any;
679
+ [key: string]: any;
680
+ }>> = { [K in keyof T]: ArtifactValue<T[K]> };
665
681
  /**
666
682
  * State paths grouped by options passed to the store
667
683
  */
668
684
  interface StateGroup {
669
- paths: string[];
670
- options?: SubscribeOptions;
685
+ paths: string[];
686
+ options?: SubscribeOptions$1;
671
687
  }
672
688
  interface ExportedArtifact {
673
- key: string;
674
- instance: any;
675
- state: {
676
- groups: Array<{
677
- paths: string[];
678
- options?: SubscribeOptions;
679
- }>;
680
- hash: string;
681
- };
682
- dependencies: string[];
689
+ key: string;
690
+ instance: any;
691
+ state: {
692
+ groups: Array<{
693
+ paths: string[];
694
+ options?: SubscribeOptions$1;
695
+ }>;
696
+ hash: string;
697
+ };
698
+ dependencies: string[];
683
699
  }
684
700
  interface ExportedContainerState {
685
- version: string;
686
- timestamp: number;
687
- artifacts: ExportedArtifact[];
688
- checksum: string;
701
+ version: string;
702
+ timestamp: number;
703
+ artifacts: ExportedArtifact[];
704
+ checksum: string;
689
705
  }
690
-
691
- /**
692
- * A dependency injection container for managing the lifecycle, dependencies,
693
- * and instances of "artifacts" (any JavaScript/TypeScript object or value).
694
- *
695
- * Separated concerns:
696
- * - ArtifactRegistry: Stores artifact templates (factories + options)
697
- * - ArtifactCache: Stores resolved singleton instances
698
- * - ArtifactDependencyGraph: Tracks artifact dependencies using DependencyGraph
699
- * - ArtifactManager: Handles lifecycle (build, invalidate, dispose)
700
- * - ArtifactObserverManager: Manages watchers and subscriptions
701
- *
702
- * @template TRegistry A type that maps artifact keys to their types
703
- * @template TState The type of the global state object
704
- */
706
+ //#endregion
707
+ //#region src/artifacts/container.d.ts
705
708
  declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<string, any>, TState extends object = any> {
706
- private readonly registry;
707
- private readonly cache;
708
- private readonly graph;
709
- private readonly manager;
710
- private readonly observer;
711
- private readonly store;
712
- /**
713
- * Creates a new ArtifactContainer instance.
714
- * @param store An object providing functions to interact with a global data store
715
- */
716
- constructor(store: Pick<DataStore<TState>, "watch" | "get" | "set" | "subset">);
717
- /**
718
- * Provides debug information about all artifacts currently registered in this container.
719
- *
720
- * Status mapping:
721
- * - `"building"` factory is currently executing (buildOnce.running())
722
- * - `"debouncing"` invalidation is pending behind a debounce timer
723
- * - `"error"` last build attempt failed
724
- * - `"active"` successfully built and instance is available
725
- * - `"idle"` — not yet built (lazy) or has been disposed
726
- *
727
- * @returns An array of ArtifactDebugNode objects
728
- */
729
- debugInfo(): ArtifactDebugNode[];
730
- /**
731
- * Registers a new artifact with the container.
732
- * If an artifact with the same key already exists, it will be overwritten and disposed.
733
- * For Singleton, non-lazy artifacts, the factory will be immediately invoked.
734
- *
735
- * @param params The registration parameters
736
- * @returns A cleanup function that unregisters the artifact
737
- */
738
- register<K extends keyof TRegistry>(params: ArtifactTemplate<TState, TRegistry[K], TRegistry>): () => void;
739
- /**
740
- * Returns a boolean indicating whether a template exists for an artifact.
741
- *
742
- * @param key The unique identifier of the artifact.
743
- * @returns boolean.
744
- */
745
- has<K extends keyof TRegistry>(key: K): boolean;
746
- /**
747
- * Unregisters an artifact from the container, disposing of its current instance
748
- * and removing all associated resources and dependency links.
749
- *
750
- * Also evicts the observer watcher cache entry so singleton watchers do not
751
- * outlive the artifact's registration.
752
- *
753
- * @param key The unique identifier of the artifact
754
- */
755
- unregister<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): Promise<void>;
756
- /**
757
- * Resolves an artifact by its key, returning its instance or an error.
758
- * Handles dependency resolution, cycle detection, caching, and retry logic.
759
- *
760
- * The keyed index property (`artifact[key]`) is set inside `cache.package()`
761
- * so it is always consistent with `artifact.instance`. No post-hoc mutation
762
- * is needed here.
763
- *
764
- * @param key The unique identifier for the artifact
765
- * @param params Parameters with which to resolve the artifact
766
- * @returns A Promise that resolves to a ResolvedArtifact
767
- * @throws {ArtifactNotFoundError} if the artifact is not found
768
- */
769
- resolve<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): Promise<KeyedResolvedArtifact<TRegistry, K>>;
770
- /**
771
- * Resolves an artifact by its key, returning its instance directly.
772
- * Throws if resolution fails.
773
- *
774
- * @param key The unique identifier for the artifact
775
- * @param params Parameters with which to resolve the artifact
776
- * @returns A Promise that resolves to the artifact instance
777
- * @throws {ArtifactNotFoundError} if the artifact is not found
778
- * @throws the artifact's error if resolution failed
779
- */
780
- require<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): Promise<TRegistry[K]>;
781
- /**
782
- * Returns an ArtifactObserver for a given artifact key.
783
- * The observer allows subscribing to changes in the artifact's resolved value.
784
- *
785
- * @param key The unique identifier for the artifact
786
- * @param params Parameters with which to resolve the artifact
787
- * @param ttl Delay before the watcher is cleaned up if we have no subscriber
788
- * @returns An ArtifactObserver instance
789
- */
790
- watch<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>, ttl?: number): ArtifactObserver<TRegistry, K>;
791
- /**
792
- * Peeks at the resolved instance of an artifact without triggering resolution
793
- * or registering a dependency.
794
- *
795
- * @param key The unique identifier for the artifact
796
- * @returns The artifact instance if already built, otherwise undefined
797
- */
798
- peek<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): TRegistry[K] | undefined;
799
- /**
800
- * Invalidates an artifact, triggering rebuild and cascade to dependents.
801
- *
802
- * @param key The artifact key to invalidate
803
- * @param options.replace If true, forces immediate rebuild bypassing debounce
804
- * @param options.params for parametized artifacts
805
- */
806
- invalidate<K extends keyof TRegistry>(key: K, options?: {
807
- replace?: boolean;
808
- params?: Record<string, unknown>;
809
- }): Promise<void>;
810
- /**
811
- * Notifies observers that an artifact has changed.
812
- * Called by ArtifactManager during stream propagation.
813
- *
814
- * @param key The artifact key
815
- */
816
- notifyObservers(key: string): void;
817
- /**
818
- * Checks if an artifact has active watchers.
819
- * Called by ArtifactManager to determine if lazy artifacts should rebuild.
820
- *
821
- * @param key The artifact key
822
- * @returns True if the artifact has active watchers
823
- */
824
- hasWatchers(key: string): boolean;
825
- /**
826
- * Disposes of the entire container and all artifacts registered within it.
827
- * Releases all resources, stops all watchers, and clears all internal state.
828
- *
829
- * Returns a Promise that resolves once all artifact teardowns have settled.
830
- * Callers should await this method to guarantee full resource release.
831
- */
832
- dispose(): Promise<void>;
833
- export(): Promise<ExportedContainerState>;
834
- private restore;
835
- static from<TRegistry extends Record<string, any> = Record<string, any>, TState extends object = any>(options: {
836
- store: Pick<DataStore<TState>, "watch" | "get" | "set" | "subset">;
837
- bundle?: ExportedContainerState;
838
- templates: ArtifactTemplate<TState, any, TRegistry>[];
839
- }): Promise<ArtifactContainer<TRegistry, TState>>;
709
+ private readonly registry;
710
+ private readonly cache;
711
+ private readonly graph;
712
+ private readonly manager;
713
+ private readonly observer;
714
+ private readonly logger;
715
+ private readonly store;
716
+ readonly events: EventBus<ArtifactLifecycleEventMap>;
717
+ constructor(store: Pick<DataStore<TState>, "watch" | "get" | "set" | "subset">, options?: {
718
+ logger?: SystemLogger;
719
+ });
720
+ debugInfo(): ArtifactDebugNode[];
721
+ register<K extends keyof TRegistry>(params: ArtifactTemplate<TState, TRegistry[K], TRegistry>): () => void;
722
+ has<K extends keyof TRegistry>(key: K): boolean;
723
+ unregister<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): Promise<void>;
724
+ resolve<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): Promise<KeyedResolvedArtifact<TRegistry, K>>;
725
+ require<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): Promise<TRegistry[K]>;
726
+ watch<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>, ttl?: number): ArtifactObserver<TRegistry, K>;
727
+ peek<K extends keyof TRegistry>(key: K, params?: Record<string, unknown>): TRegistry[K] | undefined;
728
+ invalidate<K extends keyof TRegistry>(key: K, options?: {
729
+ replace?: boolean;
730
+ params?: Record<string, unknown>;
731
+ }): Promise<void>;
732
+ on<TEventName extends keyof ArtifactLifecycleEventMap>(eventName: TEventName, callback: (payload: ArtifactLifecycleEventMap[TEventName]) => void): () => void;
733
+ on(eventName: "*", callback: (payload: ArtifactLifecycleEventMap[keyof ArtifactLifecycleEventMap], event: keyof ArtifactLifecycleEventMap) => void): () => void;
734
+ once<TEventName extends keyof ArtifactLifecycleEventMap>(eventName: TEventName, callback: (payload: ArtifactLifecycleEventMap[TEventName]) => void): () => void;
735
+ once(eventName: "*", callback: (payload: ArtifactLifecycleEventMap[keyof ArtifactLifecycleEventMap], event: keyof ArtifactLifecycleEventMap) => void): () => void;
736
+ notifyObservers(key: string): void;
737
+ hasWatchers(key: string): boolean;
738
+ dispose(): Promise<void>;
739
+ export(): Promise<ExportedContainerState>;
740
+ private restore;
741
+ static from<TRegistry extends Record<string, any> = Record<string, any>, TState extends object = any>(options: {
742
+ store: Pick<DataStore<TState>, "watch" | "get" | "set" | "subset">;
743
+ bundle?: ExportedContainerState;
744
+ templates: ArtifactTemplate<TState, any, TRegistry>[];
745
+ logger?: SystemLogger;
746
+ }): Promise<ArtifactContainer<TRegistry, TState>>;
840
747
  }
841
-
842
- 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 };
748
+ //#endregion
749
+ //#region src/artifacts/errors.d.ts
750
+ declare const ErrorCodes: {
751
+ readonly NOT_FOUND: "DB-001-NF";
752
+ readonly DUPLICATE_KEY: "DB-002-DUP";
753
+ readonly INVALID_COMMAND: "BUS-001";
754
+ readonly INTERNAL_ERROR: "SYS-001";
755
+ readonly CONCURRENCY_ERROR: "CON-001";
756
+ };
757
+ declare function artifactNotFound(key: string): SystemError$1;
758
+ declare function cycleDetected(path: string[]): SystemError$1;
759
+ declare function illegalScope(message: string): SystemError$1;
760
+ declare function watcherDisposed(key: string): SystemError$1;
761
+ declare function timeoutError(message?: string): SystemError$1;
762
+ declare function keyConflict(key?: string): SystemError$1;
763
+ declare function notParameterized(key: string): SystemError$1;
764
+ declare function paramKeyCollision(key: string, computedKey: string): SystemError$1;
765
+ declare function selfDependency(key: string): SystemError$1;
766
+ declare function buildStaleAfterRetries(depKey: string): SystemError$1;
767
+ declare function invalidImport(message: string): SystemError$1;
768
+ declare function invalidExport(key: string): SystemError$1;
769
+ declare class SupersededBuildError extends Error {
770
+ constructor();
771
+ }
772
+ //#endregion
773
+ export { ArtifactCleanup, ArtifactContainer, ArtifactDebugNode, ArtifactFactory, ArtifactFactoryContext, ArtifactInstance, ArtifactKey, ArtifactLifecycleEventMap, ArtifactObserver, ArtifactRegistryType, ArtifactScope, ArtifactScopeType, ArtifactScopes, ArtifactStateType, ArtifactStreamContext, ArtifactTemplate, ArtifactTemplateMap, ArtifactValue, ErrorArtifact, ErrorCodes, ExportedArtifact, ExportedContainerState, InferRegistry, type Issue, KeyedResolvedArtifact, PendingArtifact, ReadyArtifact, ResolvedArtifact, ResolvedArtifactBase, type Severity, StateGroup, SupersededBuildError, SystemError, UseDependencyContext, artifactNotFound, buildStaleAfterRetries, cycleDetected, illegalScope, invalidExport, invalidImport, keyConflict, notParameterized, paramKeyCollision, selfDependency, timeoutError, watcherDisposed };