@illuma/core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,378 @@
1
+ import { N as NodeBase, P as Provider, T as Token, M as MultiNodeToken, a as NodeToken, C as Ctor } from './providers-D9YA8L_g.js';
2
+ export { e as extractToken, g as iNodeAliasProvider, f as iNodeClassProvider, d as iNodeFactoryProvider, h as iNodeProvider, b as iNodeTokenBaseOptions, c as iNodeValueProvider, i as isNodeBase } from './providers-D9YA8L_g.js';
3
+ export { E as ExtractInjectedType, N as NodeInjectFn, i as iNodeInjectorOptions, n as nodeInject } from './injection-Y_bVmBSk.js';
4
+ import { i as iInjectionNode, T as TreeNode, I as Illuma } from './plugin-container-CwkVlVS4.js';
5
+
6
+ /** @internal */
7
+ type InjectorFn = (token: NodeBase<any>, optional?: boolean) => any;
8
+ /**
9
+ * Internal context manager for tracking dependency injections during factory execution.
10
+ * This class manages the injection context lifecycle and tracks all injection calls.
11
+ *
12
+ * @internal
13
+ */
14
+ declare abstract class InjectionContext {
15
+ static contextOpen: boolean;
16
+ static readonly _calls: Set<iInjectionNode<any>>;
17
+ static injector: InjectorFn | null;
18
+ private static readonly _scanners;
19
+ /**
20
+ * Adds a dependency to the current injection context.
21
+ * Called by `nodeInject` when a dependency is requested.
22
+ *
23
+ * @param node - The injection node representing the dependency
24
+ * @throws {InjectionError} If called outside of an active injection context
25
+ */
26
+ static addDep(node: iInjectionNode<any>): void;
27
+ /**
28
+ * Opens a new injection context.
29
+ * Resets the calls set and sets the injector if provided.
30
+ *
31
+ * @param injector - Optional injector function to use for resolving dependencies
32
+ */
33
+ /**
34
+ * Scans a factory function for dependencies.
35
+ * Executes the factory in a dry-run mode to capture `nodeInject` calls.
36
+ * Also runs registered context scanners.
37
+ *
38
+ * @param factory - The factory function to scan
39
+ * @returns A set of detected injection nodes
40
+ */
41
+ static open(injector?: InjectorFn): void;
42
+ static scan(factory: any): Set<iInjectionNode<any>>;
43
+ static instantiate<T>(factory: () => T, injector: InjectorFn): T;
44
+ static closeAndReport(): Set<iInjectionNode<any>>;
45
+ }
46
+
47
+ /**
48
+ * Interface for dependency injection containers.
49
+ * Defines the core methods that all DI containers must implement.
50
+ */
51
+ interface iDIContainer {
52
+ /**
53
+ * Registers a provider in the container.
54
+ * @template T - The type of value being provided
55
+ * @param provider - The provider configuration
56
+ */
57
+ provide<T>(provider: Provider<T>): void;
58
+ /**
59
+ * @internal Finds the tree node associated with the given token.
60
+ * @template T - The type of value being searched
61
+ * @param token - The token or constructor to find
62
+ * @returns The associated tree node, or null if not found
63
+ */
64
+ findNode<T>(token: Token<T>): TreeNode<T> | null;
65
+ /**
66
+ * Retrieves an instance for the given token.
67
+ * @template T - The type of value being retrieved
68
+ * @param token - The token or constructor to retrieve
69
+ * @returns The resolved instance
70
+ */
71
+ get<T>(token: MultiNodeToken<T>): T[];
72
+ get<T>(token: NodeToken<T>): T;
73
+ get<T>(token: Ctor<T>): T;
74
+ produce<T>(fn: Ctor<T> | (() => T)): T;
75
+ }
76
+
77
+ /**
78
+ * Symbol used to mark classes as injectable and store their associated token.
79
+ * @internal
80
+ */
81
+ declare const INJECTION_SYMBOL: unique symbol;
82
+ /**
83
+ * Decorator that marks a class as injectable in the dependency injection system.
84
+ * Automatically creates and associates a NodeToken with the class.
85
+ *
86
+ * @template T - The type of the class being decorated
87
+ * @returns A class decorator function
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * @NodeInjectable()
92
+ * class UserService {
93
+ * public getUser() {
94
+ * return { id: 1, name: 'John' };
95
+ * }
96
+ * }
97
+ *
98
+ * container.provide(UserService);
99
+ * container.bootstrap();
100
+ * const service = container.get(UserService);
101
+ * ```
102
+ */
103
+ declare function NodeInjectable<T>(): (ctor: Ctor<T>) => Ctor<T>;
104
+ /**
105
+ * Alternative function to mark a class as injectable in the dependency injection system for environments
106
+ * that do not support decorators.
107
+ * @param ctor
108
+ * @returns
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * import { makeInjectable } from '@illuma/core';
113
+ *
114
+ * class _UserService {
115
+ * public getUser() {
116
+ * return { id: 1, name: "John Doe" };
117
+ * }
118
+ * }
119
+ *
120
+ * export type UserService = _UserService;
121
+ * export const UserService = makeInjectable(_UserService);
122
+ * ```
123
+ */
124
+ declare function makeInjectable<T>(ctor: Ctor<T>): Ctor<T>;
125
+ /** @internal */
126
+ declare function isInjectable<T>(ctor: unknown): ctor is Ctor<T> & {
127
+ [INJECTION_SYMBOL]: NodeToken<T>;
128
+ };
129
+ /** @internal */
130
+ declare function getInjectableToken<T>(ctor: Ctor<T> & {
131
+ [INJECTION_SYMBOL]: NodeToken<T>;
132
+ }): NodeToken<T>;
133
+ declare function isConstructor(fn: unknown): fn is Ctor<any>;
134
+
135
+ /**
136
+ * Configuration options for the NodeContainer.
137
+ */
138
+ interface iContainerOptions {
139
+ /**
140
+ * When true, logs the bootstrap time to the console based on performance.now()
141
+ * difference before and after bootstrap.
142
+ * @default false
143
+ */
144
+ measurePerformance?: boolean;
145
+ diagnostics?: boolean;
146
+ parent?: iDIContainer;
147
+ }
148
+ declare class NodeContainer extends Illuma implements iDIContainer {
149
+ private readonly _opts?;
150
+ private _bootstrapped;
151
+ private _rootNode?;
152
+ private readonly _parent?;
153
+ private readonly _protoNodes;
154
+ private readonly _multiProtoNodes;
155
+ constructor(_opts?: iContainerOptions | undefined);
156
+ /**
157
+ * Registers a provider in the container.
158
+ * Must be called before {@link bootstrap}.
159
+ *
160
+ * @template T - The type of value being provided
161
+ * @param provider - The provider configuration (token, class, or provider object)
162
+ * @throws {InjectionError} If called after bootstrap or if a duplicate provider is detected
163
+ *
164
+ * @example
165
+ * ```typescript
166
+ * // Provide a value
167
+ * container.provide({ provide: CONFIG_TOKEN, value: { apiKey: '123' } });
168
+ *
169
+ * // Provide a factory
170
+ * container.provide({ provide: LOGGER_TOKEN, factory: () => new ConsoleLogger() });
171
+ *
172
+ * // Provide an injectable class directly
173
+ * container.provide(UserService);
174
+ *
175
+ * // Provide a class override
176
+ * container.provide({ provide: ServiceClass, useClass: ServiceOverride });
177
+ * ```
178
+ */
179
+ provide<T>(provider: Provider<T>): void;
180
+ findNode<T>(token: Token<T>): TreeNode<T> | null;
181
+ private _getFromParent;
182
+ private _buildInjectionTree;
183
+ /**
184
+ * Bootstraps the container by resolving the dependency trees and instantiating all providers.
185
+ * This must be called after all providers are registered and before calling {@link get}.
186
+ *
187
+ * The bootstrap process:
188
+ * 1. Validates all provider registrations
189
+ * 2. Builds dependency injection trees
190
+ * 3. Detects circular dependencies in each tree
191
+ * 4. Instantiates all dependencies in the correct order
192
+ *
193
+ * @throws {InjectionError} If the container is already bootstrapped or if circular dependencies are detected
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * const container = new NodeContainer();
198
+ * container.provide(UserService);
199
+ * container.provide(LoggerService);
200
+ * container.bootstrap(); // Resolves and instantiates all dependencies
201
+ * ```
202
+ */
203
+ bootstrap(): void;
204
+ /**
205
+ * Retrieves an instance from the container.
206
+ * Must be called after {@link bootstrap}.
207
+ *
208
+ * @template T - The type of value being retrieved (typically inferred)
209
+ * @param token - The token or class to retrieve
210
+ * @returns For NodeToken: a single instance. For MultiNodeToken: an array of instances.
211
+ * @throws {InjectionError} If called before bootstrap or if the token is not found
212
+ *
213
+ * @example
214
+ * ```typescript
215
+ * // Get a single provider
216
+ * const logger = container.get(LoggerToken);
217
+ *
218
+ * // Get a decorated class
219
+ * const service = container.get(UserService);
220
+ *
221
+ * // Get multiple providers
222
+ * const plugins = container.get(PluginToken); // Returns array
223
+ * ```
224
+ */
225
+ get<T>(token: MultiNodeToken<T>): T[];
226
+ get<T>(token: NodeToken<T>): T;
227
+ get<T>(token: Ctor<T>): T;
228
+ /**
229
+ * Instantiates a class outside injection context. Primarily used to create instances via Injector.
230
+ * Class does not get registered in the container and cannot be retrieved via {@link get} or {@link nodeInject}.
231
+ * Must be called after {@link bootstrap}.
232
+ *
233
+ * @template T - The type of the class being instantiated
234
+ * @param factory - Factory or class constructor to instantiate
235
+ * @returns A new instance of the class with dependencies injected
236
+ * @throws {InjectionError} If called before bootstrap or if the constructor is invalid
237
+ */
238
+ produce<T>(fn: Ctor<T> | (() => T)): T;
239
+ }
240
+
241
+ declare class InjectionError extends Error {
242
+ readonly code: number;
243
+ constructor(code: number, message: string);
244
+ static duplicate(token: NodeBase<unknown>): InjectionError;
245
+ static duplicateFactory(token: NodeBase<unknown>): InjectionError;
246
+ static invalidCtor(ctor: Ctor<unknown>): InjectionError;
247
+ static invalidProvider(provider: string): InjectionError;
248
+ static invalidAlias(alias: unknown): InjectionError;
249
+ static loopAlias(alias: NodeBase<unknown>): InjectionError;
250
+ static notBootstrapped(): InjectionError;
251
+ static bootstrapped(): InjectionError;
252
+ static doubleBootstrap(): InjectionError;
253
+ static notFound(token: NodeBase<unknown>): InjectionError;
254
+ static circularDependency(provider: NodeBase<unknown> | Ctor<unknown>, path: (NodeBase<unknown> | Ctor<unknown>)[]): InjectionError;
255
+ static untracked(token: NodeBase<unknown> | Ctor<unknown>, parent: NodeBase<unknown> | Ctor<unknown>): InjectionError;
256
+ static outsideContext(token: NodeBase<unknown> | Ctor<unknown>): InjectionError;
257
+ static calledUtilsOutsideContext(): InjectionError;
258
+ static instanceAccessFailed(token: NodeBase<unknown>): InjectionError;
259
+ static accessFailed(): InjectionError;
260
+ }
261
+
262
+ interface iInjector {
263
+ /** The DI container associated with this injector */
264
+ readonly container: iDIContainer;
265
+ /**
266
+ * Retrieves an instance for the given token.
267
+ * @template T - The type of value being retrieved
268
+ * @param token - The token or constructor to retrieve
269
+ * @returns The resolved instance
270
+ */
271
+ get<T>(token: MultiNodeToken<T>): T[];
272
+ get<T>(token: NodeToken<T>): T;
273
+ get<T>(token: Ctor<T>): T;
274
+ /**
275
+ * Instantiates a class with injections in runtime using current context.
276
+ * Useful when creating an object that requires injections in runtime.
277
+ * Class does not get registered in the container and cannot be retrieved via {@link get} or {@link nodeInject}.
278
+ *
279
+ * @template T - The type of the class being instantiated
280
+ * @param ctor - The constructor of the class to instantiate
281
+ * @returns A new instance of the class with dependencies injected
282
+ * @throws {InjectionError} If called before bootstrap or if the constructor is invalid
283
+ * Must be called after {@link bootstrap}.
284
+ */
285
+ produce<T>(fn: Ctor<T> | (() => T)): T;
286
+ }
287
+ /**
288
+ * Injector implementation that allows retrieving instances from the parent DI container.
289
+ */
290
+ declare class InjectorImpl implements iInjector {
291
+ readonly container: iDIContainer;
292
+ constructor(container: iDIContainer);
293
+ get<T>(token: MultiNodeToken<T>): T[];
294
+ get<T>(token: NodeToken<T>): T;
295
+ get<T>(token: Ctor<T>): T;
296
+ produce<T>(fn: Ctor<T> | (() => T)): T;
297
+ }
298
+ /**
299
+ * Injector node that is used to access provider outside of injection context.
300
+ * @example
301
+ * ```typescript
302
+ * import { Injector, nodeInject, NodeInjectable, NodeContainer } from "@illuma/core";
303
+ *
304
+ * @NodeInjectable()
305
+ * class MyService {
306
+ * private readonly _injector = nodeInject(Injector);
307
+ * public doSomething() {
308
+ * const otherService = this._injector.get(OtherService);
309
+ * // Use otherService...
310
+ * }
311
+ * }
312
+ * ```
313
+ */
314
+ declare const Injector: NodeToken<iInjector>;
315
+
316
+ type MaybeAsyncFactory<T> = () => T | Promise<T>;
317
+ interface iInjectionOptions {
318
+ /**
319
+ * Whether to cache the result of the injection function
320
+ * Prevents multiple invocations from creating multiple sub-containers or injections
321
+ * @default true
322
+ */
323
+ withCache?: boolean;
324
+ /**
325
+ * Overrides to provide to the sub-container
326
+ * These will be provided in addition to the main injection
327
+ * @default []
328
+ */
329
+ overrides?: Provider[];
330
+ }
331
+ /**
332
+ * Creates an async function that injects a group of dependencies as a sub-container.
333
+ * The returned function, when called, will create a new sub-container, provide the given dependencies,
334
+ * bootstrap it, and return its injector.
335
+ *
336
+ * @note
337
+ * `injectGroupAsync` should be called within an injection context where the parent container is accessible.
338
+ *
339
+ * @param fn - A function that returns an array of providers or a promise resolving to one
340
+ * @returns A function that returns a promise resolving to the injector of the sub-container
341
+ */
342
+ declare function injectGroupAsync(fn: MaybeAsyncFactory<Provider[]>, opts?: iInjectionOptions): () => Promise<iInjector>;
343
+ /**
344
+ * Creates an async function that injects a dependency for the given token or constructor.
345
+ * The returned function, when called, will create a new sub-container,
346
+ * provide the token or constructor, bootstrap it, and return the resolved instance(s).
347
+ *
348
+ * @note
349
+ * `injectAsync` should be called within an injection context where the parent container is accessible.
350
+ *
351
+ * @template T - The type of value being injected
352
+ * @param fn - A function that returns a token, constructor, or a promise resolving to one
353
+ * @returns A function that returns a promise resolving to the injected instance(s)
354
+ */
355
+ declare function injectAsync<T>(fn: MaybeAsyncFactory<MultiNodeToken<T>>, opts?: iInjectionOptions): () => Promise<T[]>;
356
+ declare function injectAsync<T>(fn: MaybeAsyncFactory<NodeToken<T>>, opts?: iInjectionOptions): () => Promise<T>;
357
+ declare function injectAsync<T>(fn: MaybeAsyncFactory<Ctor<T>>, opts?: iInjectionOptions): () => Promise<T>;
358
+ interface iEntrypointConfig<T extends Token<any>> {
359
+ readonly entrypoint: T;
360
+ readonly providers: Provider[];
361
+ }
362
+ /**
363
+ * Creates an async function that injects a sub-container with a specific entrypoint.
364
+ * The returned function, when called, will create a new sub-container,
365
+ * provide the given providers, bootstrap it, and return the resolved instance(s) of the entrypoint.
366
+ *
367
+ * @note
368
+ * `injectEntryAsync` should be called within an injection context where the parent container is accessible.
369
+ *
370
+ * @template T - The type of the entrypoint token
371
+ * @param fn - A function that returns an entrypoint configuration or a promise resolving to one
372
+ * @returns A function that returns a promise resolving to the injected instance(s) of the entrypoint
373
+ */
374
+ declare function injectEntryAsync<T>(fn: MaybeAsyncFactory<iEntrypointConfig<NodeToken<T>>>, opts?: iInjectionOptions): () => Promise<T[]>;
375
+ declare function injectEntryAsync<T>(fn: MaybeAsyncFactory<iEntrypointConfig<Ctor<T>>>, opts?: iInjectionOptions): () => Promise<T>;
376
+ declare function injectEntryAsync<T>(fn: MaybeAsyncFactory<iEntrypointConfig<MultiNodeToken<T>>>, opts?: iInjectionOptions): () => Promise<T>;
377
+
378
+ export { Ctor, INJECTION_SYMBOL, InjectionContext, InjectionError, Injector, type InjectorFn, InjectorImpl, MultiNodeToken, NodeBase, NodeContainer, NodeInjectable, NodeToken, Provider, Token, getInjectableToken, type iDIContainer, type iEntrypointConfig, iInjectionNode, type iInjector, injectAsync, injectEntryAsync, injectGroupAsync, isConstructor, isInjectable, makeInjectable };