@veloxts/core 0.3.2 → 0.3.4

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,406 @@
1
+ /**
2
+ * Dependency Injection Container
3
+ *
4
+ * The VeloxTS DI container provides:
5
+ * - Service registration with multiple provider types
6
+ * - Automatic constructor injection via reflect-metadata
7
+ * - Lifecycle management (singleton, transient, request-scoped)
8
+ * - Circular dependency detection
9
+ * - Integration with Fastify for request-scoped services
10
+ *
11
+ * @module di/container
12
+ */
13
+ import type { FastifyInstance, FastifyRequest } from 'fastify';
14
+ import type { NormalizedProvider, Provider } from './providers.js';
15
+ import type { InjectionToken } from './tokens.js';
16
+ /**
17
+ * Options for creating a DI container
18
+ */
19
+ export interface ContainerOptions {
20
+ /**
21
+ * Parent container for hierarchical injection
22
+ *
23
+ * If a service is not found in this container, it will be looked up
24
+ * in the parent container.
25
+ */
26
+ parent?: Container;
27
+ /**
28
+ * Whether to allow auto-registration of classes
29
+ *
30
+ * If true, when resolving a class that isn't registered,
31
+ * the container will attempt to instantiate it directly
32
+ * (only for @Injectable classes).
33
+ *
34
+ * @default false
35
+ */
36
+ autoRegister?: boolean;
37
+ }
38
+ /**
39
+ * Context for resolution, including request for request-scoped services
40
+ */
41
+ export interface ResolutionContext {
42
+ /**
43
+ * The current Fastify request (for request-scoped services)
44
+ */
45
+ request?: FastifyRequest;
46
+ }
47
+ /**
48
+ * Dependency Injection Container
49
+ *
50
+ * The central hub for service registration and resolution.
51
+ * Manages service lifecycles and dependencies.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * // Create a container
56
+ * const container = new Container();
57
+ *
58
+ * // Register services
59
+ * container.register({ provide: UserService, useClass: UserService });
60
+ * container.register({
61
+ * provide: DATABASE,
62
+ * useFactory: (config) => createDb(config.dbUrl),
63
+ * inject: [ConfigService]
64
+ * });
65
+ *
66
+ * // Resolve services
67
+ * const userService = container.resolve(UserService);
68
+ * const db = container.resolve(DATABASE);
69
+ * ```
70
+ */
71
+ export declare class Container {
72
+ /**
73
+ * Registered providers indexed by token
74
+ */
75
+ private readonly providers;
76
+ /**
77
+ * Manages singleton and request-scoped instance caches
78
+ */
79
+ private readonly scopeManager;
80
+ /**
81
+ * Parent container for hierarchical lookup
82
+ */
83
+ private readonly parent?;
84
+ /**
85
+ * Whether to auto-register @Injectable classes
86
+ */
87
+ private readonly autoRegister;
88
+ /**
89
+ * Resolution stack for circular dependency detection
90
+ */
91
+ private readonly resolutionStack;
92
+ /**
93
+ * Creates a new DI container
94
+ *
95
+ * @param options - Container configuration options
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * // Standalone container
100
+ * const container = new Container();
101
+ *
102
+ * // Child container (inherits from parent)
103
+ * const childContainer = new Container({ parent: container });
104
+ *
105
+ * // With auto-registration enabled
106
+ * const autoContainer = new Container({ autoRegister: true });
107
+ * ```
108
+ */
109
+ constructor(options?: ContainerOptions);
110
+ /**
111
+ * Registers a service provider
112
+ *
113
+ * @param provider - The provider configuration
114
+ * @returns The container (for chaining)
115
+ * @throws {VeloxError} If the provider is invalid
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * // Class provider
120
+ * container.register({
121
+ * provide: UserService,
122
+ * useClass: UserService,
123
+ * scope: Scope.REQUEST
124
+ * });
125
+ *
126
+ * // Factory provider
127
+ * container.register({
128
+ * provide: DATABASE,
129
+ * useFactory: (config: ConfigService) => createDb(config.dbUrl),
130
+ * inject: [ConfigService]
131
+ * });
132
+ *
133
+ * // Value provider
134
+ * container.register({
135
+ * provide: CONFIG,
136
+ * useValue: { port: 3210, debug: true }
137
+ * });
138
+ *
139
+ * // Existing/alias provider
140
+ * container.register({
141
+ * provide: LOGGER,
142
+ * useExisting: ConsoleLogger
143
+ * });
144
+ * ```
145
+ */
146
+ register<T>(provider: Provider<T>): this;
147
+ /**
148
+ * Registers multiple providers at once
149
+ *
150
+ * @param providers - Array of provider configurations
151
+ * @returns The container (for chaining)
152
+ *
153
+ * @example
154
+ * ```typescript
155
+ * container.registerMany([
156
+ * { provide: UserService, useClass: UserService },
157
+ * { provide: PostService, useClass: PostService },
158
+ * { provide: CONFIG, useValue: appConfig }
159
+ * ]);
160
+ * ```
161
+ */
162
+ registerMany(providers: Provider[]): this;
163
+ /**
164
+ * Checks if a token is registered
165
+ *
166
+ * @param token - The token to check
167
+ * @returns true if the token is registered
168
+ */
169
+ isRegistered(token: InjectionToken): boolean;
170
+ /**
171
+ * Gets the provider for a token (without resolving)
172
+ *
173
+ * @param token - The token to get the provider for
174
+ * @returns The normalized provider or undefined
175
+ */
176
+ getProvider<T>(token: InjectionToken<T>): NormalizedProvider<T> | undefined;
177
+ /**
178
+ * Resolves a service from the container
179
+ *
180
+ * @param token - The token to resolve
181
+ * @param context - Optional resolution context (for request scope)
182
+ * @returns The resolved service instance
183
+ * @throws {VeloxError} If the service cannot be resolved
184
+ *
185
+ * @example
186
+ * ```typescript
187
+ * // Basic resolution
188
+ * const userService = container.resolve(UserService);
189
+ *
190
+ * // With request context (for request-scoped services)
191
+ * const userContext = container.resolve(UserContext, { request });
192
+ * ```
193
+ */
194
+ resolve<T>(token: InjectionToken<T>, context?: ResolutionContext): T;
195
+ /**
196
+ * Resolves a service, returning undefined if not found
197
+ *
198
+ * @param token - The token to resolve
199
+ * @param context - Optional resolution context
200
+ * @returns The resolved service or undefined
201
+ */
202
+ resolveOptional<T>(token: InjectionToken<T>, context?: ResolutionContext): T | undefined;
203
+ /**
204
+ * Resolves all services registered for a token
205
+ *
206
+ * Useful for multi-injection patterns where multiple implementations
207
+ * are registered for the same token.
208
+ *
209
+ * @param token - The token to resolve
210
+ * @param context - Optional resolution context
211
+ * @returns Array of resolved service instances
212
+ *
213
+ * @example
214
+ * ```typescript
215
+ * // Register multiple validators
216
+ * container.register({ provide: VALIDATOR, useClass: EmailValidator });
217
+ * container.register({ provide: VALIDATOR, useClass: PhoneValidator });
218
+ *
219
+ * // Resolve all validators
220
+ * const validators = container.resolveAll(VALIDATOR);
221
+ * ```
222
+ *
223
+ * Note: Currently returns single instance. Multi-injection to be
224
+ * implemented in v1.1 with a separate multi-provider registration API.
225
+ */
226
+ resolveAll<T>(token: InjectionToken<T>, context?: ResolutionContext): T[];
227
+ /**
228
+ * Resolves with scope management
229
+ *
230
+ * @internal
231
+ */
232
+ private resolveWithScope;
233
+ /**
234
+ * Creates an instance based on provider type
235
+ *
236
+ * @internal
237
+ */
238
+ private createInstance;
239
+ /**
240
+ * Instantiates a class with automatic dependency injection
241
+ *
242
+ * @internal
243
+ */
244
+ private instantiateClass;
245
+ /**
246
+ * Invokes a factory function with dependencies
247
+ *
248
+ * @internal
249
+ */
250
+ private invokeFactory;
251
+ /**
252
+ * Tries to auto-register a class if it's injectable
253
+ *
254
+ * @internal
255
+ */
256
+ private tryAutoRegister;
257
+ /**
258
+ * Resolves a service asynchronously
259
+ *
260
+ * Use this method when your providers include async factories.
261
+ *
262
+ * @param token - The token to resolve
263
+ * @param context - Optional resolution context
264
+ * @returns Promise resolving to the service instance
265
+ *
266
+ * @example
267
+ * ```typescript
268
+ * container.register({
269
+ * provide: DATABASE,
270
+ * useFactory: async (config) => {
271
+ * const client = createClient(config.dbUrl);
272
+ * await client.connect();
273
+ * return client;
274
+ * },
275
+ * inject: [ConfigService]
276
+ * });
277
+ *
278
+ * const db = await container.resolveAsync(DATABASE);
279
+ * ```
280
+ */
281
+ resolveAsync<T>(token: InjectionToken<T>, context?: ResolutionContext): Promise<T>;
282
+ /**
283
+ * Async scope resolution
284
+ *
285
+ * @internal
286
+ */
287
+ private resolveWithScopeAsync;
288
+ /**
289
+ * Async instance creation
290
+ *
291
+ * @internal
292
+ */
293
+ private createInstanceAsync;
294
+ /**
295
+ * Async class instantiation
296
+ *
297
+ * @internal
298
+ */
299
+ private instantiateClassAsync;
300
+ /**
301
+ * Async factory invocation
302
+ *
303
+ * @internal
304
+ */
305
+ private invokeFactoryAsync;
306
+ /**
307
+ * Attaches the container to a Fastify server
308
+ *
309
+ * Sets up the request lifecycle hooks needed for request-scoped services.
310
+ * Must be called before resolving request-scoped services.
311
+ *
312
+ * @param server - Fastify server instance
313
+ * @returns The container (for chaining)
314
+ *
315
+ * @example
316
+ * ```typescript
317
+ * const app = await createVeloxApp();
318
+ * container.attachToFastify(app.server);
319
+ * ```
320
+ */
321
+ attachToFastify(server: FastifyInstance): this;
322
+ /**
323
+ * Creates a resolution context from a Fastify request
324
+ *
325
+ * @param request - The Fastify request
326
+ * @returns Resolution context for request-scoped services
327
+ */
328
+ static createContext(request: FastifyRequest): ResolutionContext;
329
+ /**
330
+ * Creates a child container
331
+ *
332
+ * Child containers inherit from this container but can override registrations.
333
+ * Useful for testing or creating scoped containers.
334
+ *
335
+ * @param options - Options for the child container
336
+ * @returns New child container
337
+ *
338
+ * @example
339
+ * ```typescript
340
+ * const childContainer = container.createChild();
341
+ *
342
+ * // Override a service for testing
343
+ * childContainer.register({
344
+ * provide: UserRepository,
345
+ * useClass: MockUserRepository
346
+ * });
347
+ * ```
348
+ */
349
+ createChild(options?: Omit<ContainerOptions, 'parent'>): Container;
350
+ /**
351
+ * Clears all singleton instances
352
+ *
353
+ * Useful for testing or application shutdown.
354
+ * Does not clear registrations.
355
+ */
356
+ clearInstances(): void;
357
+ /**
358
+ * Clears all registrations and instances
359
+ *
360
+ * @internal
361
+ */
362
+ reset(): void;
363
+ /**
364
+ * Gets debug information about the container
365
+ *
366
+ * @returns Object with container statistics and registered providers
367
+ */
368
+ getDebugInfo(): {
369
+ providerCount: number;
370
+ providers: string[];
371
+ hasParent: boolean;
372
+ autoRegister: boolean;
373
+ };
374
+ }
375
+ /**
376
+ * Default global container instance
377
+ *
378
+ * For convenience, VeloxTS provides a default container.
379
+ * You can also create your own containers for testing or isolation.
380
+ *
381
+ * @example
382
+ * ```typescript
383
+ * import { container } from '@veloxts/core';
384
+ *
385
+ * container.register({
386
+ * provide: UserService,
387
+ * useClass: UserService
388
+ * });
389
+ *
390
+ * const userService = container.resolve(UserService);
391
+ * ```
392
+ */
393
+ export declare const container: Container;
394
+ /**
395
+ * Creates a new DI container
396
+ *
397
+ * @param options - Container configuration options
398
+ * @returns New container instance
399
+ *
400
+ * @example
401
+ * ```typescript
402
+ * const appContainer = createContainer({ autoRegister: true });
403
+ * ```
404
+ */
405
+ export declare function createContainer(options?: ContainerOptions): Container;
406
+ //# sourceMappingURL=container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/di/container.ts"],"names":[],"mappings":"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"}