@khapu2906/treasure-chest 1.0.4 → 1.3.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,89 @@
1
+ /**
2
+ * Scope management for scoped instances
3
+ *
4
+ * @module Scope
5
+ */
6
+ /**
7
+ * Scope class for managing scoped instances
8
+ * A scope contains instances that live for a specific duration (e.g., per HTTP request)
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const scope = container.createScope();
13
+ * const conn = container.resolve('dbConnection'); // Scoped instance
14
+ * await scope.dispose(); // Cleanup all scoped resources
15
+ * ```
16
+ */
17
+ export class Scope {
18
+ constructor() {
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ this.instances = new Map();
21
+ this.disposables = [];
22
+ }
23
+ /**
24
+ * Get an instance from this scope
25
+ * @param key The service key
26
+ * @returns The instance or undefined
27
+ */
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ get(key) {
30
+ return this.instances.get(key);
31
+ }
32
+ /**
33
+ * Set an instance in this scope with optional cleanup
34
+ * Auto-detects IDisposable instances
35
+ *
36
+ * @param key The service key
37
+ * @param value The instance to store
38
+ * @param dispose Optional disposal function
39
+ */
40
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
+ set(key, value, dispose) {
42
+ this.instances.set(key, value);
43
+ // Auto-detect IDisposable
44
+ if (!dispose && this.isDisposable(value)) {
45
+ dispose = () => value.dispose();
46
+ }
47
+ if (dispose) {
48
+ this.disposables.push(dispose);
49
+ }
50
+ }
51
+ /**
52
+ * Check if instance exists in scope
53
+ * @param key The service key
54
+ * @returns True if the instance exists
55
+ */
56
+ has(key) {
57
+ return this.instances.has(key);
58
+ }
59
+ /**
60
+ * Check if value implements IDisposable interface
61
+ * @private
62
+ * @param value The value to check
63
+ * @returns True if the value is disposable
64
+ */
65
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
+ isDisposable(value) {
67
+ return (value !== null &&
68
+ value !== undefined &&
69
+ typeof value === 'object' &&
70
+ typeof value.dispose === 'function');
71
+ }
72
+ /**
73
+ * Dispose all instances in this scope
74
+ * Calls all registered disposal functions and clears the scope
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * await scope.dispose();
79
+ * ```
80
+ */
81
+ async dispose() {
82
+ for (const disposeFn of this.disposables) {
83
+ await disposeFn();
84
+ }
85
+ this.instances.clear();
86
+ this.disposables = [];
87
+ }
88
+ }
89
+ //# sourceMappingURL=Scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Scope.js","sourceRoot":"","sources":["../../src/Scope.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;;;;;;;GAUG;AACH,MAAM,OAAO,KAAK;IAAlB;QACE,8DAA8D;QACtD,cAAS,GAAqB,IAAI,GAAG,EAAE,CAAC;QACxC,gBAAW,GAAgB,EAAE,CAAC;IA2ExC,CAAC;IAzEC;;;;OAIG;IACH,8DAA8D;IAC9D,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;;OAOG;IACH,8DAA8D;IAC9D,GAAG,CAAC,GAAW,EAAE,KAAU,EAAE,OAAmB;QAC9C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE/B,0BAA0B;QAC1B,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YACzC,OAAO,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAClC,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACH,8DAA8D;IACtD,YAAY,CAAC,KAAU;QAC7B,OAAO,CACL,KAAK,KAAK,IAAI;YACd,KAAK,KAAK,SAAS;YACnB,OAAO,KAAK,KAAK,QAAQ;YACzB,OAAO,KAAK,CAAC,OAAO,KAAK,UAAU,CACpC,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,OAAO;QACX,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,SAAS,EAAE,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;IACxB,CAAC;CACF"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Treasure Chest - A lightweight TypeScript dependency injection container
3
+ *
4
+ * @module treasure-chest
5
+ * @author Kent Phung
6
+ * @license DIB
7
+ *
8
+ * Features:
9
+ * - Transient, Singleton, and Scoped bindings
10
+ * - Conditional binding based on runtime conditions
11
+ * - Contextual binding for different implementations per context
12
+ * - Alias support for service keys
13
+ * - Nested dependency resolution
14
+ * - Lazy loading with deferred initialization
15
+ * - Child containers with hierarchy
16
+ * - Circular dependency detection
17
+ * - High-performance Map-based storage (v1.2.0)
18
+ * - Auto-dispose for IDisposable instances (v1.2.0)
19
+ * - Modular architecture (v1.2.0)
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * import { Container } from '@khapu2906/treasure-chest';
24
+ *
25
+ * const container = new Container();
26
+ * container.bind('logger', () => new Logger());
27
+ * const logger = container.resolve('logger');
28
+ * ```
29
+ */
30
+ // Export main classes
31
+ export { Container } from './Container';
32
+ export { Lazy } from './Lazy';
33
+ export { Scope } from './Scope';
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,sBAAsB;AACtB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Type definitions for Treasure Chest DI Container
3
+ *
4
+ * @module types
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,299 @@
1
+ /**
2
+ * Container class for dependency injection
3
+ *
4
+ * @module Container
5
+ */
6
+ import type { ConditionFn, DisposeFn, FactoryFn, Lifecycle } from './types';
7
+ import { Scope } from './Scope';
8
+ /**
9
+ * Container class for dependency injection
10
+ * Manages service bindings, instances, and resolution logic
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const container = new Container();
15
+ * container.bind('logger', () => new Logger());
16
+ * const logger = container.resolve<Logger>('logger');
17
+ * ```
18
+ */
19
+ export declare class Container {
20
+ /** Map-based storage for bindings - O(1) lookup */
21
+ private bindings;
22
+ /** Cache for singleton instances */
23
+ private instances;
24
+ /** Mapping of aliases to original keys */
25
+ private aliases;
26
+ /** Cache for resolved bindings - performance optimization */
27
+ private bindingCache;
28
+ /** Current resolution context for contextual binding */
29
+ private currentContext?;
30
+ /** Parent container for hierarchy */
31
+ private parent?;
32
+ /** Composed containers for composition pattern */
33
+ private composedContainers;
34
+ /** Current active scope */
35
+ private currentScope?;
36
+ /** Resolution stack for circular dependency detection */
37
+ private resolutionStack;
38
+ /**
39
+ * Create a new container
40
+ * @param parent Optional parent container for hierarchy
41
+ */
42
+ constructor(parent?: Container);
43
+ /**
44
+ * Register a transient binding (new instance on each resolve)
45
+ *
46
+ * @template T The type of service being bound
47
+ * @param key The unique identifier for this service
48
+ * @param factory Factory function that creates the service instance
49
+ * @param condition Optional condition function for conditional binding
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * container.bind('database', (c) => new Database());
54
+ * container.bind('cache', (c) => new Cache(), (c) => process.env.CACHE_ENABLED === 'true');
55
+ * ```
56
+ */
57
+ bind<T>(key: string, factory: FactoryFn<T>, condition?: ConditionFn): void;
58
+ /**
59
+ * Register a singleton binding (single instance shared across all resolves)
60
+ *
61
+ * @template T The type of service being bound
62
+ * @param key The unique identifier for this service
63
+ * @param factory Factory function that creates the service instance
64
+ * @param condition Optional condition function for conditional binding
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * container.singleton('config', (c) => new Config());
69
+ * ```
70
+ */
71
+ singleton<T>(key: string, factory: FactoryFn<T>, condition?: ConditionFn): void;
72
+ /**
73
+ * Register a scoped binding (single instance per scope)
74
+ *
75
+ * @template T The type of service being bound
76
+ * @param key The unique identifier for this service
77
+ * @param factory Factory function that creates the service instance
78
+ * @param dispose Optional disposal function for cleanup
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * container.scoped('dbConnection', (c) => new DbConnection(), () => {
83
+ * console.log('Closing connection');
84
+ * });
85
+ * ```
86
+ */
87
+ scoped<T>(key: string, factory: FactoryFn<T>, dispose?: DisposeFn): void;
88
+ /**
89
+ * Register a lazy binding (deferred initialization)
90
+ *
91
+ * @template T The type of service being bound
92
+ * @param key The unique identifier for this service
93
+ * @param factory Factory function that creates the service instance
94
+ * @param lifecycle The lifecycle type (default: singleton)
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * container.lazy('heavyService', (c) => new HeavyService());
99
+ * const lazy = container.resolve<Lazy<HeavyService>>('heavyService');
100
+ * // Not initialized yet
101
+ * const service = lazy.value; // Initialized now
102
+ * ```
103
+ */
104
+ lazy<T>(key: string, factory: FactoryFn<T>, lifecycle?: Lifecycle): void;
105
+ /**
106
+ * Create an alias for an existing service key
107
+ *
108
+ * @param aliasKey The new alias name
109
+ * @param originalKey The original service key to alias
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * container.bind('UserRepository', () => new UserRepo());
114
+ * container.alias('UserRepo', 'UserRepository');
115
+ * // Both keys now resolve to the same binding
116
+ * ```
117
+ */
118
+ alias(aliasKey: string, originalKey: string): void;
119
+ /**
120
+ * Create a child container that inherits from this container
121
+ *
122
+ * @returns A new child container
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * const parent = new Container();
127
+ * parent.singleton('config', () => new Config());
128
+ *
129
+ * const child = parent.createChild();
130
+ * child.bind('logger', () => new Logger());
131
+ *
132
+ * // Child can resolve both parent and own bindings
133
+ * const config = child.resolve('config'); // From parent
134
+ * const logger = child.resolve('logger'); // From child
135
+ * ```
136
+ */
137
+ createChild(): Container;
138
+ /**
139
+ * Create a new scope for scoped instances
140
+ *
141
+ * @returns A new scope
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * const scope = container.createScope();
146
+ * container.scoped('request', () => new Request());
147
+ *
148
+ * const req1 = container.resolve('request'); // Same instance within scope
149
+ * const req2 = container.resolve('request'); // Same as req1
150
+ *
151
+ * await scope.dispose(); // Clean up scoped instances
152
+ * ```
153
+ */
154
+ createScope(): Scope;
155
+ /**
156
+ * Execute a callback with a temporary scope
157
+ * Auto-disposes the scope when done (like C# using statement)
158
+ *
159
+ * @param callback Function to execute within the scope
160
+ * @returns The result of the callback
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * await container.withScope(async (scope) => {
165
+ * const db = container.resolve('dbConnection');
166
+ * await db.query('...');
167
+ * // Auto-disposed when callback completes
168
+ * });
169
+ * ```
170
+ */
171
+ withScope<T>(callback: (scope: Scope) => T | Promise<T>): Promise<T>;
172
+ /**
173
+ * Find the appropriate binding for a given key and context
174
+ * Searches in current container and parent containers
175
+ * Uses cached result when possible for performance
176
+ *
177
+ * @private
178
+ * @param key The service key to find
179
+ * @param context Optional context for contextual binding
180
+ * @returns The matching binding or undefined
181
+ */
182
+ private findBinding;
183
+ /**
184
+ * Resolve a service instance from the container
185
+ * Handles transient, singleton, scoped, and lazy bindings
186
+ *
187
+ * @template T The expected type of the resolved service
188
+ * @param key The service key to resolve
189
+ * @param context Optional context for contextual resolution
190
+ * @returns The resolved service instance
191
+ * @throws Error if no binding exists for the key
192
+ * @throws Error if circular dependency is detected
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * const logger = container.resolve<Logger>('logger');
197
+ * const userRepo = container.resolve('UserRepo', 'UserService');
198
+ * ```
199
+ */
200
+ resolve<T>(key: string, context?: string): T;
201
+ /**
202
+ * Resolve a transient instance
203
+ * @private
204
+ */
205
+ private resolveTransient;
206
+ /**
207
+ * Resolve a singleton instance
208
+ * @private
209
+ */
210
+ private resolveSingleton;
211
+ /**
212
+ * Resolve a scoped instance
213
+ * @private
214
+ */
215
+ private resolveScoped;
216
+ /**
217
+ * Resolve a lazy instance
218
+ * @private
219
+ */
220
+ private resolveLazy;
221
+ /**
222
+ * Create a contextual binding (different implementations based on context)
223
+ * Provides a fluent API for defining context-specific dependencies
224
+ *
225
+ * @param context The context identifier (usually a service name)
226
+ * @returns A fluent API object with needs() method
227
+ *
228
+ * @example
229
+ * ```typescript
230
+ * // UserService will receive MockUserRepo
231
+ * container.when('UserService').needs('UserRepo').give(() => new MockUserRepo());
232
+ *
233
+ * // OrderService will receive RealUserRepo
234
+ * container.when('OrderService').needs('UserRepo').give(() => new RealUserRepo());
235
+ * ```
236
+ */
237
+ when(context: string): {
238
+ needs: (depKey: string) => {
239
+ give: (factory: FactoryFn<any>) => void;
240
+ };
241
+ };
242
+ /**
243
+ * Check if a binding exists for a key
244
+ *
245
+ * @param key The service key to check
246
+ * @returns True if binding exists
247
+ *
248
+ * @example
249
+ * ```typescript
250
+ * if (container.has('logger')) {
251
+ * const logger = container.resolve('logger');
252
+ * }
253
+ * ```
254
+ */
255
+ has(key: string): boolean;
256
+ /**
257
+ * Get all registered service keys
258
+ *
259
+ * @returns Array of service keys
260
+ *
261
+ * @example
262
+ * ```typescript
263
+ * const keys = container.keys();
264
+ * console.log('Registered services:', keys);
265
+ * ```
266
+ */
267
+ keys(): string[];
268
+ /**
269
+ * Reset the container to its initial state
270
+ * Clears all bindings, instances, aliases, and context
271
+ * Useful for testing scenarios
272
+ *
273
+ * @example
274
+ * ```typescript
275
+ * afterEach(() => {
276
+ * container.reset();
277
+ * });
278
+ * ```
279
+ */
280
+ reset(): void;
281
+ /**
282
+ * Compose multiple containers into a new container
283
+ * This allows mixing services from different domains without inheritance
284
+ *
285
+ * @param containers Array of containers to compose
286
+ * @returns New composed container
287
+ */
288
+ static compose(containers: Container[]): Container;
289
+ /**
290
+ * Resolve a service from composed containers
291
+ * @private
292
+ */
293
+ private resolveFromComposition;
294
+ /**
295
+ * Dispose the container and all its scoped instances
296
+ */
297
+ dispose(): Promise<void>;
298
+ }
299
+ //# sourceMappingURL=Container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Container.d.ts","sourceRoot":"","sources":["../../src/Container.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Lazy wrapper for deferred initialization
3
+ *
4
+ * @module Lazy
5
+ */
6
+ /**
7
+ * Lazy wrapper for deferred initialization
8
+ * Delays the creation of an instance until it's actually accessed
9
+ *
10
+ * @template T The type of the lazy value
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const lazy = new Lazy(() => new ExpensiveService());
15
+ * console.log(lazy.isInitialized); // false
16
+ * const service = lazy.value; // NOW it's created
17
+ * console.log(lazy.isInitialized); // true
18
+ * ```
19
+ */
20
+ export declare class Lazy<T> {
21
+ private factory;
22
+ private _value?;
23
+ private _initialized;
24
+ constructor(factory: () => T);
25
+ /**
26
+ * Get the lazy value, initializing it if necessary
27
+ */
28
+ get value(): T;
29
+ /**
30
+ * Check if the lazy value has been initialized
31
+ */
32
+ get isInitialized(): boolean;
33
+ }
34
+ //# sourceMappingURL=Lazy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Lazy.d.ts","sourceRoot":"","sources":["../../src/Lazy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;GAaG;AACH,qBAAa,IAAI,CAAC,CAAC;IAIL,OAAO,CAAC,OAAO;IAH3B,OAAO,CAAC,MAAM,CAAC,CAAI;IACnB,OAAO,CAAC,YAAY,CAAS;gBAET,OAAO,EAAE,MAAM,CAAC;IAEpC;;OAEG;IACH,IAAI,KAAK,IAAI,CAAC,CAMb;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,OAAO,CAE3B;CACF"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Scope management for scoped instances
3
+ *
4
+ * @module Scope
5
+ */
6
+ import type { DisposeFn } from './types';
7
+ /**
8
+ * Scope class for managing scoped instances
9
+ * A scope contains instances that live for a specific duration (e.g., per HTTP request)
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const scope = container.createScope();
14
+ * const conn = container.resolve('dbConnection'); // Scoped instance
15
+ * await scope.dispose(); // Cleanup all scoped resources
16
+ * ```
17
+ */
18
+ export declare class Scope {
19
+ private instances;
20
+ private disposables;
21
+ /**
22
+ * Get an instance from this scope
23
+ * @param key The service key
24
+ * @returns The instance or undefined
25
+ */
26
+ get(key: string): any;
27
+ /**
28
+ * Set an instance in this scope with optional cleanup
29
+ * Auto-detects IDisposable instances
30
+ *
31
+ * @param key The service key
32
+ * @param value The instance to store
33
+ * @param dispose Optional disposal function
34
+ */
35
+ set(key: string, value: any, dispose?: DisposeFn): void;
36
+ /**
37
+ * Check if instance exists in scope
38
+ * @param key The service key
39
+ * @returns True if the instance exists
40
+ */
41
+ has(key: string): boolean;
42
+ /**
43
+ * Check if value implements IDisposable interface
44
+ * @private
45
+ * @param value The value to check
46
+ * @returns True if the value is disposable
47
+ */
48
+ private isDisposable;
49
+ /**
50
+ * Dispose all instances in this scope
51
+ * Calls all registered disposal functions and clears the scope
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * await scope.dispose();
56
+ * ```
57
+ */
58
+ dispose(): Promise<void>;
59
+ }
60
+ //# sourceMappingURL=Scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Scope.d.ts","sourceRoot":"","sources":["../../src/Scope.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,SAAS,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,qBAAa,KAAK;IAEhB,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,WAAW,CAAmB;IAEtC;;;;OAIG;IAEH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG;IAIrB;;;;;;;OAOG;IAEH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,SAAS;IAahD;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;;;;OAKG;IAEH,OAAO,CAAC,YAAY;IASpB;;;;;;;;OAQG;IACG,OAAO;CAOd"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Treasure Chest - A lightweight TypeScript dependency injection container
3
+ *
4
+ * @module treasure-chest
5
+ * @author Kent Phung
6
+ * @license DIB
7
+ *
8
+ * Features:
9
+ * - Transient, Singleton, and Scoped bindings
10
+ * - Conditional binding based on runtime conditions
11
+ * - Contextual binding for different implementations per context
12
+ * - Alias support for service keys
13
+ * - Nested dependency resolution
14
+ * - Lazy loading with deferred initialization
15
+ * - Child containers with hierarchy
16
+ * - Circular dependency detection
17
+ * - High-performance Map-based storage (v1.2.0)
18
+ * - Auto-dispose for IDisposable instances (v1.2.0)
19
+ * - Modular architecture (v1.2.0)
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * import { Container } from '@khapu2906/treasure-chest';
24
+ *
25
+ * const container = new Container();
26
+ * container.bind('logger', () => new Logger());
27
+ * const logger = container.resolve('logger');
28
+ * ```
29
+ */
30
+ export { Container } from './Container';
31
+ export { Lazy } from './Lazy';
32
+ export { Scope } from './Scope';
33
+ export type { Lifecycle, IDisposable, DisposeFn } from './types';
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Type definitions for Treasure Chest DI Container
3
+ *
4
+ * @module types
5
+ */
6
+ /**
7
+ * Lifecycle type for service bindings
8
+ */
9
+ export type Lifecycle = 'transient' | 'singleton' | 'scoped';
10
+ /**
11
+ * Interface for disposable resources
12
+ * Implement this interface to enable auto-cleanup
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * class DbConnection implements IDisposable {
17
+ * async dispose() {
18
+ * await this.close();
19
+ * }
20
+ * }
21
+ * ```
22
+ */
23
+ export interface IDisposable {
24
+ dispose(): void | Promise<void>;
25
+ }
26
+ /**
27
+ * Disposal function for cleaning up resources
28
+ */
29
+ export type DisposeFn = () => void | Promise<void>;
30
+ /**
31
+ * Factory function type that creates instances of type T
32
+ * @template T The type of instance to create
33
+ * @param _c The container instance for resolving dependencies
34
+ * @returns An instance of type T
35
+ */
36
+ export type FactoryFn<T> = (_c: any) => T;
37
+ /**
38
+ * Condition function type for conditional bindings
39
+ * @param _c The container instance
40
+ * @returns True if the binding should be used
41
+ */
42
+ export type ConditionFn = (_c: any) => boolean;
43
+ /**
44
+ * Options for container composition
45
+ */
46
+ export interface ComposeOptions {
47
+ /** How to handle binding conflicts between containers */
48
+ conflictResolution?: 'first-wins' | 'last-wins' | 'throw-error';
49
+ /** Whether to prefix binding keys to avoid conflicts */
50
+ prefixBindings?: boolean;
51
+ /** Separator for prefixed binding keys */
52
+ prefixSeparator?: string;
53
+ /** Whether to inherit lifecycles from composed containers */
54
+ inheritLifecycles?: boolean;
55
+ }
56
+ /**
57
+ * Internal binding interface representing a service registration
58
+ * @template T The type of service being bound
59
+ * @internal
60
+ */
61
+ export interface Binding<T = any> {
62
+ /** The service key identifier */
63
+ key: string;
64
+ /** Factory function to create the service instance */
65
+ factory: FactoryFn<T>;
66
+ /** Lifecycle type: transient, singleton, or scoped */
67
+ lifecycle: Lifecycle;
68
+ /** Optional condition for conditional binding */
69
+ condition?: ConditionFn;
70
+ /** Optional context for contextual binding */
71
+ context?: string;
72
+ /** Whether this is a lazy binding */
73
+ lazy?: boolean;
74
+ /** Optional disposal function */
75
+ dispose?: DisposeFn;
76
+ }
77
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE7D;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnD;;;;;GAKG;AAEH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,CAAC;AAE1C;;;;GAIG;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,EAAE,EAAE,GAAG,KAAK,OAAO,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,kBAAkB,CAAC,EAAE,YAAY,GAAG,WAAW,GAAG,aAAa,CAAC;IAChE,wDAAwD;IACxD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0CAA0C;IAC1C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;GAIG;AAEH,MAAM,WAAW,OAAO,CAAC,CAAC,GAAG,GAAG;IAC9B,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACtB,sDAAsD;IACtD,SAAS,EAAE,SAAS,CAAC;IACrB,iDAAiD;IACjD,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iCAAiC;IACjC,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB"}