decorator-dependency-injection 1.0.6 → 1.1.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.
package/eslint.config.js CHANGED
@@ -62,7 +62,10 @@ export default defineConfig([
62
62
  beforeEach: "readonly",
63
63
  afterEach: "readonly",
64
64
  jest: "readonly",
65
- fail: "readonly"
65
+ fail: "readonly",
66
+ setTimeout: "readonly",
67
+ clearTimeout: "readonly",
68
+ Promise: "readonly"
66
69
  }
67
70
  },
68
71
  rules: {
package/index.d.ts CHANGED
@@ -1,256 +1,67 @@
1
- /**
2
- * Type definitions for decorator-dependency-injection
3
- */
4
-
5
- /**
6
- * A class constructor type.
7
- * @template T The instance type
8
- */
9
1
  export type Constructor<T = any> = new (...args: any[]) => T
10
-
11
- /**
12
- * Valid injection target: either a class constructor or a string name.
13
- */
14
2
  export type InjectionToken<T = any> = string | Constructor<T>
15
3
 
16
- /**
17
- * Context for registered instances in the container
18
- */
19
4
  export interface InstanceContext {
20
- /** The type of registration */
21
5
  type: 'singleton' | 'factory'
22
- /** The current class constructor (may be a mock) */
23
6
  clazz: new (...args: any[]) => any
24
- /** The original class constructor if mocked */
25
7
  originalClazz?: new (...args: any[]) => any
26
- /** The cached singleton instance */
27
8
  instance?: any
28
- /** Whether to use proxy mocking */
29
9
  proxy?: boolean
30
10
  }
31
11
 
32
- /**
33
- * A dependency injection container that manages singleton and factory instances.
34
- */
12
+ export interface RegistrationInfo {
13
+ key: string | Constructor
14
+ name: string
15
+ type: 'singleton' | 'factory'
16
+ isMocked: boolean
17
+ hasInstance: boolean
18
+ }
19
+
35
20
  export declare class Container {
36
- /**
37
- * Enable or disable debug logging.
38
- * When enabled, logs when instances are created.
39
- */
21
+ readonly [Symbol.toStringTag]: 'Container'
22
+ [Symbol.iterator](): IterableIterator<RegistrationInfo>
23
+ readonly size: number
40
24
  setDebug(enabled: boolean): void
41
-
42
- /**
43
- * Register a class as a singleton.
44
- */
45
25
  registerSingleton<T>(clazz: Constructor<T>, name?: string): void
46
-
47
- /**
48
- * Register a class as a factory.
49
- */
50
26
  registerFactory<T>(clazz: Constructor<T>, name?: string): void
51
-
52
- /**
53
- * Get the context for a given class or name.
54
- * @throws Error if the class/name is not registered
55
- */
56
27
  getContext<T>(clazzOrName: InjectionToken<T>): InstanceContext
57
-
58
- /**
59
- * Check if a class or name is registered.
60
- */
61
28
  has<T>(clazzOrName: InjectionToken<T>): boolean
62
-
63
- /**
64
- * Resolve and return an instance by class or name.
65
- * This allows non-decorator code to retrieve instances from the container.
66
- */
29
+ isMocked<T>(clazzOrName: InjectionToken<T>): boolean
30
+ unregister<T>(clazzOrName: InjectionToken<T>): boolean
31
+ list(): RegistrationInfo[]
67
32
  resolve<T>(clazzOrName: InjectionToken<T>, ...params: any[]): T
68
-
69
- /**
70
- * Get or create an instance based on the context.
71
- */
72
33
  getInstance<T>(instanceContext: InstanceContext, params: any[]): T
73
-
74
- /**
75
- * Register a mock for an existing class.
76
- */
77
- registerMock<T>(
78
- targetClazzOrName: InjectionToken<T>,
79
- mockClazz: Constructor<T>,
80
- useProxy?: boolean
81
- ): void
82
-
83
- /**
84
- * Reset a specific mock to its original class.
85
- */
86
- resetMock<T>(clazzOrName: InjectionToken<T>): void
87
-
88
- /**
89
- * Reset all mocks to their original classes.
90
- */
91
- resetAllMocks(): void
92
-
93
- /**
94
- * Clear all registered instances and mocks.
95
- */
96
- clear(): void
34
+ registerMock<T>(targetClazzOrName: InjectionToken<T>, mockClazz: Constructor<Partial<T>>, useProxy?: boolean): void
35
+ getMockInstance<T>(clazzOrName: InjectionToken<T>, ...params: any[]): T
36
+ removeMock<T>(clazzOrName: InjectionToken<T>): void
37
+ removeAllMocks(): void
38
+ resetSingletons(options?: { preserveMocks?: boolean }): void
39
+ clear(options?: { preserveRegistrations?: boolean }): void
97
40
  }
98
41
 
99
- /**
100
- * Register a class as a singleton.
101
- * @param name Optional name to register the singleton under
102
- */
103
- export declare function Singleton(name?: string): ClassDecorator
104
-
105
- /**
106
- * Register a class as a factory.
107
- * @param name Optional name to register the factory under
108
- */
109
- export declare function Factory(name?: string): ClassDecorator
110
-
111
- /**
112
- * Decorator return type that works for both fields and accessors.
113
- * For fields, returns a function that provides the initial value.
114
- * For accessors, returns an object with get/set/init.
115
- */
116
42
  export type FieldOrAccessorDecorator = (
117
43
  target: undefined,
118
44
  context: ClassFieldDecoratorContext | ClassAccessorDecoratorContext
119
45
  ) => void | ((initialValue: any) => any) | ClassAccessorDecoratorResult<any, any>
120
46
 
121
- /**
122
- * Inject a singleton or factory instance into a class field or accessor.
123
- *
124
- * Supports:
125
- * - Public fields: `@Inject(MyClass) myField`
126
- * - Private fields: `@Inject(MyClass) #myField`
127
- * - Public accessors: `@Inject(MyClass) accessor myField`
128
- * - Private accessors: `@Inject(MyClass) accessor #myField`
129
- *
130
- * @param clazzOrName The class or name to inject
131
- * @param params Optional parameters to pass to the constructor
132
- *
133
- * @example
134
- * class MyService {
135
- * @Inject(Database) db
136
- * @Inject(Logger) #logger // private field
137
- * @Inject(Cache) accessor cache // accessor (recommended for lazy-like behavior)
138
- * }
139
- */
140
- export declare function Inject<T>(
141
- clazzOrName: InjectionToken<T>,
142
- ...params: any[]
143
- ): FieldOrAccessorDecorator
144
-
145
- /**
146
- * Inject a singleton or factory instance lazily into a class field or accessor.
147
- * The instance is created on first access.
148
- *
149
- * Supports:
150
- * - Public fields: `@InjectLazy(MyClass) myField` (true lazy)
151
- * - Private fields: `@InjectLazy(MyClass) #myField` (not truly lazy - use accessor instead)
152
- * - Public accessors: `@InjectLazy(MyClass) accessor myField` (true lazy)
153
- * - Private accessors: `@InjectLazy(MyClass) accessor #myField` (true lazy, recommended)
154
- *
155
- * Note: For true lazy injection with private members, use the accessor syntax:
156
- * `@InjectLazy(MyClass) accessor #myField`
157
- *
158
- * @param clazzOrName The class or name to inject
159
- * @param params Optional parameters to pass to the constructor
160
- *
161
- * @example
162
- * class MyService {
163
- * @InjectLazy(ExpensiveService) accessor #expensiveService
164
- * }
165
- */
166
- export declare function InjectLazy<T>(
167
- clazzOrName: InjectionToken<T>,
168
- ...params: any[]
169
- ): FieldOrAccessorDecorator
170
-
171
- /**
172
- * Mark a class as a mock for another class.
173
- * @param mockedClazzOrName The class or name to mock
174
- * @param proxy If true, unmocked methods delegate to the original
175
- */
176
- export declare function Mock<T>(
177
- mockedClazzOrName: InjectionToken<T>,
178
- proxy?: boolean
179
- ): ClassDecorator
180
-
181
- /**
182
- * Reset all mocks to their original classes.
183
- */
184
- export declare function resetMocks(): void
185
-
186
- /**
187
- * Reset a specific mock to its original class.
188
- * @param clazzOrName The class or name to reset
189
- */
190
- export declare function resetMock<T>(clazzOrName: InjectionToken<T>): void
191
-
192
- /**
193
- * Clear all registered instances and mocks from the container.
194
- */
195
- export declare function clearContainer(): void
196
-
197
- /**
198
- * Get the default container instance.
199
- */
47
+ export declare function Singleton(name?: string): ClassDecorator
48
+ export declare function Factory(name?: string): ClassDecorator
49
+ export declare function Inject<T>(clazzOrName: InjectionToken<T>, ...params: any[]): FieldOrAccessorDecorator
50
+ export declare function InjectLazy<T>(clazzOrName: InjectionToken<T>, ...params: any[]): FieldOrAccessorDecorator
51
+ export declare function Mock<T>(mockedClazzOrName: InjectionToken<T>, proxy?: boolean): ClassDecorator
52
+
53
+ export declare function removeAllMocks(): void
54
+ export declare function removeMock<T>(clazzOrName: InjectionToken<T>): void
55
+ export declare function resetSingletons(options?: { preserveMocks?: boolean }): void
56
+ export declare function clearContainer(options?: { preserveRegistrations?: boolean }): void
200
57
  export declare function getContainer(): Container
201
-
202
- /**
203
- * Enable or disable debug logging for dependency injection.
204
- * When enabled, logs when instances are registered, created, and mocked.
205
- * @param enabled Whether to enable debug mode
206
- */
207
58
  export declare function setDebug(enabled: boolean): void
208
-
209
- /**
210
- * Check if a class or name is registered in the default container.
211
- * Useful for validation before injection.
212
- * @param clazzOrName The class or name to check
213
- * @returns true if registered, false otherwise
214
- */
215
59
  export declare function isRegistered<T>(clazzOrName: InjectionToken<T>): boolean
216
-
217
- /**
218
- * Validate that all provided injection tokens are registered.
219
- * Throws an error with details about missing registrations.
220
- * Useful for fail-fast validation at application startup.
221
- * @param tokens Array of classes or names to validate
222
- * @throws Error if any token is not registered
223
- */
60
+ export declare function isMocked<T>(clazzOrName: InjectionToken<T>): boolean
61
+ export declare function getMockInstance<T>(clazzOrName: InjectionToken<T>, ...params: any[]): T
62
+ export declare function unregister<T>(clazzOrName: InjectionToken<T>): boolean
63
+ export declare function listRegistrations(): RegistrationInfo[]
224
64
  export declare function validateRegistrations<T extends InjectionToken[]>(...tokens: T): void
225
-
226
- /**
227
- * Resolve and return an instance by class or name.
228
- * This allows non-decorator code (plain functions, modules, etc.) to retrieve
229
- * instances from the DI container.
230
- *
231
- * @param clazzOrName The class or name to resolve
232
- * @param params Optional parameters to pass to the constructor
233
- * @returns The resolved instance
234
- * @throws Error if the class or name is not registered
235
- *
236
- * @example
237
- * // In a plain function:
238
- * function handleRequest(req: Request) {
239
- * const userService = resolve(UserService)
240
- * return userService.getUser(req.userId)
241
- * }
242
- *
243
- * @example
244
- * // With a named registration:
245
- * const db = resolve<Database>('database')
246
- */
247
65
  export declare function resolve<T>(clazzOrName: InjectionToken<T>, ...params: any[]): T
248
-
249
- /**
250
- * Create a proxy that delegates to the mock first, then falls back to the original.
251
- * This is an internal utility but exported for advanced use cases.
252
- *
253
- * @param mock The mock instance
254
- * @param original The original instance to fall back to
255
- */
256
66
  export declare function createProxy<T extends object>(mock: T, original: T): T
67
+ export declare const defaultContainer: Container
package/index.js CHANGED
@@ -1,31 +1,15 @@
1
- /**
2
- * Decorator Dependency Injection
3
- *
4
- * A simple library for dependency injection using TC39 Stage 3 decorators.
5
- *
6
- * @module decorator-dependency-injection
7
- */
8
-
9
1
  import {Container} from './src/Container.js'
10
2
 
11
- /** @type {Container} The default global container */
3
+ /** @type {Container} */
12
4
  const defaultContainer = new Container()
13
5
 
14
- /**
15
- * Creates a lazy accessor descriptor with WeakMap-based caching.
16
- * @param {WeakMap} cache - WeakMap for per-instance caching
17
- * @param {Function} getValue - Factory function to create the value
18
- * @param {string} name - The accessor name for error messages
19
- * @returns {{init: Function, get: Function, set: Function}} Accessor descriptor
20
- * @private
21
- */
6
+ /** @private */
22
7
  function createLazyAccessor(cache, getValue, name) {
23
8
  return {
24
9
  init(initialValue) {
25
- if (initialValue) {
10
+ if (initialValue !== undefined) {
26
11
  throw new Error(`Cannot assign value to injected accessor "${name}"`)
27
12
  }
28
- return undefined
29
13
  },
30
14
  get() {
31
15
  if (!cache.has(this)) {
@@ -39,20 +23,9 @@ function createLazyAccessor(cache, getValue, name) {
39
23
  }
40
24
  }
41
25
 
42
- /**
43
- * Register a class as a singleton. If a name is provided, it will be used as the key in the singleton map.
44
- * Singleton instances only ever have one instance created via the @Inject decorator.
45
- *
46
- * @param {string} [name] The name of the singleton. If not provided, the class will be used as the key.
47
- * @returns {(function(Function, {kind: string}): void)}
48
- * @example @Singleton() class MySingleton {}
49
- * @example @Singleton('customName') class MySingleton {}
50
- * @throws {Error} If the injection target is not a class
51
- * @throws {Error} If a singleton or factory with the same name is already defined
52
- * @throws {Error} If the target is not a class constructor
53
- */
26
+ /** @param {string} [name] */
54
27
  export function Singleton(name) {
55
- return function (clazz, context) {
28
+ return (clazz, context) => {
56
29
  if (context.kind !== 'class') {
57
30
  throw new Error('Invalid injection target')
58
31
  }
@@ -63,20 +36,9 @@ export function Singleton(name) {
63
36
  }
64
37
  }
65
38
 
66
- /**
67
- * Register a class as a factory. If a name is provided, it will be used as the key in the factory map.
68
- * Factory instances are created via the @Inject decorator. Each call to the factory will create a new instance.
69
- *
70
- * @param {string} [name] The name of the factory. If not provided, the class will be used as the key.
71
- * @returns {(function(Function, {kind: string}): void)}
72
- * @example @Factory() class MyFactory {}
73
- * @example @Factory('customName') class MyFactory {}
74
- * @throws {Error} If the injection target is not a class
75
- * @throws {Error} If a factory or singleton with the same name is already defined
76
- * @throws {Error} If the target is not a class constructor
77
- */
39
+ /** @param {string} [name] */
78
40
  export function Factory(name) {
79
- return function (clazz, context) {
41
+ return (clazz, context) => {
80
42
  if (context.kind !== 'class') {
81
43
  throw new Error('Invalid injection target')
82
44
  }
@@ -88,35 +50,19 @@ export function Factory(name) {
88
50
  }
89
51
 
90
52
  /**
91
- * Inject a singleton or factory instance into a class field. You can also provide parameters to the constructor.
92
- * If the instance is a singleton, it will only be created once with the first set of parameters it encounters.
93
- *
94
- * Supports:
95
- * - Public fields: @Inject(MyClass) myField
96
- * - Private fields: @Inject(MyClass) #myField
97
- * - Accessors: @Inject(MyClass) accessor myField
98
- * - Private accessors: @Inject(MyClass) accessor #myField
99
- *
100
- * @param {string|Function} clazzOrName The singleton or factory class or name
101
- * @param {...*} params Parameters to pass to the constructor. Recommended to use only with factories.
102
- * @returns {(function(*, {kind: string, name: string}): function(): Object)}
103
- * @example @Inject(MySingleton) mySingleton
104
- * @example @Inject("myCustomName") myFactory
105
- * @example @Inject(MyService) #privateService
106
- * @example @Inject(MyService) accessor myService
107
- * @throws {Error} If the injection target is not a field or accessor
108
- * @throws {Error} If the injected field is assigned a value
53
+ * @param {string|Function} clazzOrName
54
+ * @param {...*} params
109
55
  */
110
56
  export function Inject(clazzOrName, ...params) {
111
- return function (_, context) {
57
+ return (_, context) => {
112
58
  const getValue = () => {
113
59
  const instanceContext = defaultContainer.getContext(clazzOrName)
114
60
  return defaultContainer.getInstance(instanceContext, params)
115
61
  }
116
62
 
117
63
  if (context.kind === 'field') {
118
- return function (initialValue) {
119
- if (initialValue) {
64
+ return (initialValue) => {
65
+ if (initialValue !== undefined) {
120
66
  throw new Error(`Cannot assign value to injected field "${context.name}"`)
121
67
  }
122
68
  return getValue()
@@ -133,31 +79,9 @@ export function Inject(clazzOrName, ...params) {
133
79
  }
134
80
 
135
81
  /**
136
- * Inject a singleton or factory instance lazily into a class field. You can also provide parameters to the constructor.
137
- * If the instance is a singleton, it will only be created once with the first set of parameters it encounters.
138
- *
139
- * The lazy injection defers instantiation until the field is first accessed. This is useful for:
140
- * - Breaking circular dependencies
141
- * - Deferring expensive initializations
142
- *
143
- * Supports:
144
- * - Public fields: @InjectLazy(MyClass) myField
145
- * - Private fields: @InjectLazy(MyClass) #myField
146
- * - Accessors: @InjectLazy(MyClass) accessor myField
147
- * - Private accessors: @InjectLazy(MyClass) accessor #myField
148
- *
149
- * Note: For private fields, the lazy behavior is achieved through the field initializer
150
- * returning a getter-based proxy. For accessors, it's achieved through the accessor's
151
- * get/set methods directly.
152
- *
153
- * @param {string|Function} clazzOrName The singleton or factory class or name
154
- * @param {...*} params Parameters to pass to the constructor. Recommended to use only with factories.
155
- * @returns {(function(*, {kind: string, name: string, addInitializer: Function}): void)}
156
- * @example @InjectLazy(MySingleton) mySingleton
157
- * @example @InjectLazy("myCustomName") myFactory
158
- * @example @InjectLazy(MyService) #privateService
159
- * @throws {Error} If the injection target is not a field or accessor
160
- * @throws {Error} If the injected field is assigned a value
82
+ * Defers instantiation until first access. For private fields, use accessor syntax for true lazy behavior.
83
+ * @param {string|Function} clazzOrName
84
+ * @param {...*} params
161
85
  */
162
86
  export function InjectLazy(clazzOrName, ...params) {
163
87
  const cache = new WeakMap()
@@ -172,8 +96,8 @@ export function InjectLazy(clazzOrName, ...params) {
172
96
  // For private fields, we cannot use Object.defineProperty to create a lazy getter.
173
97
  // Instead, we eagerly create the value. For true lazy behavior, use accessor syntax.
174
98
  if (context.private) {
175
- return function (initialValue) {
176
- if (initialValue) {
99
+ return (initialValue) => {
100
+ if (initialValue !== undefined) {
177
101
  throw new Error(`Cannot assign value to lazy-injected field "${context.name}"`)
178
102
  }
179
103
  return getValue()
@@ -208,19 +132,11 @@ export function InjectLazy(clazzOrName, ...params) {
208
132
  }
209
133
 
210
134
  /**
211
- * Mark a class as a mock. This will replace the class with a mock instance when injected.
212
- *
213
- * @param {string|Function} mockedClazzOrName The singleton or factory class or name to be mocked
214
- * @param {boolean} [proxy=false] If true, the mock will proxy to the original class.
215
- * Any methods not defined in the mock will be called on the original class.
216
- * @returns {(function(Function, {kind: string}): void)}
217
- * @example @Mock(MySingleton) class MyMock {}
218
- * @example @Mock("myCustomName", true) class MyMock {}
219
- * @throws {Error} If the injection target is not a class
220
- * @throws {Error} If the injection source is not found
135
+ * @param {string|Function} mockedClazzOrName
136
+ * @param {boolean} [proxy=false] If true, unmocked methods delegate to the original
221
137
  */
222
138
  export function Mock(mockedClazzOrName, proxy = false) {
223
- return function (clazz, context) {
139
+ return (clazz, context) => {
224
140
  if (context.kind !== 'class') {
225
141
  throw new Error('Invalid injection target')
226
142
  }
@@ -228,120 +144,97 @@ export function Mock(mockedClazzOrName, proxy = false) {
228
144
  }
229
145
  }
230
146
 
231
- /**
232
- * Reset all mocks to their original classes.
233
- */
234
- export function resetMocks() {
235
- defaultContainer.resetAllMocks()
147
+ /** Remove all mocks and restore originals. Does NOT clear mock call history. */
148
+ export function removeAllMocks() {
149
+ defaultContainer.removeAllMocks()
236
150
  }
237
151
 
238
- /**
239
- * Reset a specific mock to its original class.
240
- *
241
- * @param {string|Function} clazzOrName The singleton or factory class or name to reset
242
- */
243
- export function resetMock(clazzOrName) {
244
- defaultContainer.resetMock(clazzOrName)
152
+ /** @param {string|Function} clazzOrName */
153
+ export function removeMock(clazzOrName) {
154
+ defaultContainer.removeMock(clazzOrName)
245
155
  }
246
156
 
247
- /**
248
- * Clear all registered instances and mocks from the container.
249
- * Useful for complete test isolation between test suites.
250
- */
251
- export function clearContainer() {
252
- defaultContainer.clear()
157
+ /** @param {{preserveMocks?: boolean}} [options] */
158
+ export function resetSingletons(options) {
159
+ defaultContainer.resetSingletons(options)
253
160
  }
254
161
 
255
- /**
256
- * Get the default container instance.
257
- * Useful for advanced use cases or testing the container itself.
258
- *
259
- * @returns {Container} The default container
260
- */
162
+ /** @param {{preserveRegistrations?: boolean}} [options] */
163
+ export function clearContainer(options) {
164
+ defaultContainer.clear(options)
165
+ }
166
+
167
+ /** @returns {Container} */
261
168
  export function getContainer() {
262
169
  return defaultContainer
263
170
  }
264
171
 
265
- /**
266
- * Enable or disable debug logging for dependency injection.
267
- * When enabled, logs when instances are registered, created, and mocked.
268
- *
269
- * @param {boolean} enabled Whether to enable debug mode
270
- * @example
271
- * setDebug(true)
272
- * // [DI] Registered singleton: UserService
273
- * // [DI] Creating singleton: UserService
274
- */
172
+ /** @param {boolean} enabled */
275
173
  export function setDebug(enabled) {
276
174
  defaultContainer.setDebug(enabled)
277
175
  }
278
176
 
279
177
  /**
280
- * Check if a class or name is registered in the default container.
281
- * Useful for validation before injection.
282
- *
283
- * @param {string|Function} clazzOrName The class or name to check
284
- * @returns {boolean} true if registered, false otherwise
285
- * @example
286
- * if (!isRegistered(MyService)) {
287
- * console.warn('MyService not registered!')
288
- * }
178
+ * @param {string|Function} clazzOrName
179
+ * @returns {boolean}
289
180
  */
290
181
  export function isRegistered(clazzOrName) {
291
182
  return defaultContainer.has(clazzOrName)
292
183
  }
293
184
 
294
- /**
295
- * Validate that all provided injection tokens are registered.
296
- * Throws an error with details about missing registrations.
297
- * Useful for fail-fast validation at application startup.
298
- *
299
- * @param {...(string|Function)} tokens Classes or names to validate
300
- * @throws {Error} If any token is not registered
301
- * @example
302
- * // At app startup:
303
- * validateRegistrations(UserService, AuthService, 'databaseConnection')
304
- */
185
+ /** @param {...(string|Function)} tokens */
305
186
  export function validateRegistrations(...tokens) {
306
187
  const missing = tokens.filter(token => !defaultContainer.has(token))
307
- if (missing.length > 0) {
308
- const names = missing.map(t => typeof t === 'string' ? t : t.name).join(', ')
309
- throw new Error(
310
- `Missing registrations: [${names}]. ` +
311
- `Ensure these classes are decorated with @Singleton() or @Factory() before use.`
312
- )
313
- }
188
+ if (missing.length === 0) return
189
+
190
+ const names = missing.map(t => t?.name ?? t).join(', ')
191
+ throw new Error(
192
+ `Missing registrations: [${names}]. ` +
193
+ `Ensure these classes are decorated with @Singleton() or @Factory() before use.`
194
+ )
314
195
  }
315
196
 
316
197
  /**
317
- * Resolve and return an instance by class or name.
318
- * This allows non-decorator code (plain functions, modules, etc.) to retrieve
319
- * instances from the DI container.
320
- *
321
198
  * @template T
322
- * @param {string|Function} clazzOrName The class or name to resolve
323
- * @param {...*} params Parameters to pass to the constructor
324
- * @returns {T} The resolved instance
325
- * @throws {Error} If the class or name is not registered
326
- * @example
327
- * // In a plain function:
328
- * function handleRequest(req) {
329
- * const userService = resolve(UserService)
330
- * return userService.getUser(req.userId)
331
- * }
332
- * @example
333
- * // With a named registration:
334
- * const db = resolve('database')
335
- * @example
336
- * // With factory parameters:
337
- * const logger = resolve(Logger, 'my-module')
199
+ * @param {string|Function} clazzOrName
200
+ * @param {...*} params
201
+ * @returns {T}
338
202
  */
339
203
  export function resolve(clazzOrName, ...params) {
340
204
  return defaultContainer.resolve(clazzOrName, ...params)
341
205
  }
342
206
 
343
- // Export Container class for advanced use cases (e.g., isolated containers)
344
- export {Container}
207
+ /**
208
+ * @template T
209
+ * @param {string|Function} clazzOrName
210
+ * @param {...*} params
211
+ * @returns {T}
212
+ */
213
+ export function getMockInstance(clazzOrName, ...params) {
214
+ return defaultContainer.getMockInstance(clazzOrName, ...params)
215
+ }
216
+
217
+ /**
218
+ * @param {string|Function} clazzOrName
219
+ * @returns {boolean}
220
+ */
221
+ export function isMocked(clazzOrName) {
222
+ return defaultContainer.isMocked(clazzOrName)
223
+ }
224
+
225
+ /**
226
+ * @param {string|Function} clazzOrName
227
+ * @returns {boolean}
228
+ */
229
+ export function unregister(clazzOrName) {
230
+ return defaultContainer.unregister(clazzOrName)
231
+ }
345
232
 
346
- // Export createProxy for advanced proxy use cases
233
+ /** @returns {Array<{key: string|Function, name: string, type: 'singleton'|'factory', isMocked: boolean, hasInstance: boolean}>} */
234
+ export function listRegistrations() {
235
+ return defaultContainer.list()
236
+ }
237
+
238
+ export {Container}
239
+ export {defaultContainer}
347
240
  export {createProxy} from './src/proxy.js'