@khapu2906/treasure-chest 1.0.3 → 1.2.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,284 @@
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
+ /** Current active scope */
33
+ private currentScope?;
34
+ /** Resolution stack for circular dependency detection */
35
+ private resolutionStack;
36
+ /**
37
+ * Create a new container
38
+ * @param parent Optional parent container for hierarchy
39
+ */
40
+ constructor(parent?: Container);
41
+ /**
42
+ * Register a transient binding (new instance on each resolve)
43
+ *
44
+ * @template T The type of service being bound
45
+ * @param key The unique identifier for this service
46
+ * @param factory Factory function that creates the service instance
47
+ * @param condition Optional condition function for conditional binding
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * container.bind('database', (c) => new Database());
52
+ * container.bind('cache', (c) => new Cache(), (c) => process.env.CACHE_ENABLED === 'true');
53
+ * ```
54
+ */
55
+ bind<T>(key: string, factory: FactoryFn<T>, condition?: ConditionFn): void;
56
+ /**
57
+ * Register a singleton binding (single instance shared across all resolves)
58
+ *
59
+ * @template T The type of service being bound
60
+ * @param key The unique identifier for this service
61
+ * @param factory Factory function that creates the service instance
62
+ * @param condition Optional condition function for conditional binding
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * container.singleton('config', (c) => new Config());
67
+ * ```
68
+ */
69
+ singleton<T>(key: string, factory: FactoryFn<T>, condition?: ConditionFn): void;
70
+ /**
71
+ * Register a scoped binding (single instance per scope)
72
+ *
73
+ * @template T The type of service being bound
74
+ * @param key The unique identifier for this service
75
+ * @param factory Factory function that creates the service instance
76
+ * @param dispose Optional disposal function for cleanup
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * container.scoped('dbConnection', (c) => new DbConnection(), () => {
81
+ * console.log('Closing connection');
82
+ * });
83
+ * ```
84
+ */
85
+ scoped<T>(key: string, factory: FactoryFn<T>, dispose?: DisposeFn): void;
86
+ /**
87
+ * Register a lazy binding (deferred initialization)
88
+ *
89
+ * @template T The type of service being bound
90
+ * @param key The unique identifier for this service
91
+ * @param factory Factory function that creates the service instance
92
+ * @param lifecycle The lifecycle type (default: singleton)
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * container.lazy('heavyService', (c) => new HeavyService());
97
+ * const lazy = container.resolve<Lazy<HeavyService>>('heavyService');
98
+ * // Not initialized yet
99
+ * const service = lazy.value; // Initialized now
100
+ * ```
101
+ */
102
+ lazy<T>(key: string, factory: FactoryFn<T>, lifecycle?: Lifecycle): void;
103
+ /**
104
+ * Create an alias for an existing service key
105
+ *
106
+ * @param aliasKey The new alias name
107
+ * @param originalKey The original service key to alias
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * container.bind('UserRepository', () => new UserRepo());
112
+ * container.alias('UserRepo', 'UserRepository');
113
+ * // Both keys now resolve to the same binding
114
+ * ```
115
+ */
116
+ alias(aliasKey: string, originalKey: string): void;
117
+ /**
118
+ * Create a child container that inherits from this container
119
+ *
120
+ * @returns A new child container
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * const parent = new Container();
125
+ * parent.singleton('config', () => new Config());
126
+ *
127
+ * const child = parent.createChild();
128
+ * child.bind('logger', () => new Logger());
129
+ *
130
+ * // Child can resolve both parent and own bindings
131
+ * const config = child.resolve('config'); // From parent
132
+ * const logger = child.resolve('logger'); // From child
133
+ * ```
134
+ */
135
+ createChild(): Container;
136
+ /**
137
+ * Create a new scope for scoped instances
138
+ *
139
+ * @returns A new scope
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * const scope = container.createScope();
144
+ * container.scoped('request', () => new Request());
145
+ *
146
+ * const req1 = container.resolve('request'); // Same instance within scope
147
+ * const req2 = container.resolve('request'); // Same as req1
148
+ *
149
+ * await scope.dispose(); // Clean up scoped instances
150
+ * ```
151
+ */
152
+ createScope(): Scope;
153
+ /**
154
+ * Execute a callback with a temporary scope
155
+ * Auto-disposes the scope when done (like C# using statement)
156
+ *
157
+ * @param callback Function to execute within the scope
158
+ * @returns The result of the callback
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * await container.withScope(async (scope) => {
163
+ * const db = container.resolve('dbConnection');
164
+ * await db.query('...');
165
+ * // Auto-disposed when callback completes
166
+ * });
167
+ * ```
168
+ */
169
+ withScope<T>(callback: (scope: Scope) => T | Promise<T>): Promise<T>;
170
+ /**
171
+ * Find the appropriate binding for a given key and context
172
+ * Searches in current container and parent containers
173
+ * Uses cached result when possible for performance
174
+ *
175
+ * @private
176
+ * @param key The service key to find
177
+ * @param context Optional context for contextual binding
178
+ * @returns The matching binding or undefined
179
+ */
180
+ private findBinding;
181
+ /**
182
+ * Resolve a service instance from the container
183
+ * Handles transient, singleton, scoped, and lazy bindings
184
+ *
185
+ * @template T The expected type of the resolved service
186
+ * @param key The service key to resolve
187
+ * @param context Optional context for contextual resolution
188
+ * @returns The resolved service instance
189
+ * @throws Error if no binding exists for the key
190
+ * @throws Error if circular dependency is detected
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * const logger = container.resolve<Logger>('logger');
195
+ * const userRepo = container.resolve('UserRepo', 'UserService');
196
+ * ```
197
+ */
198
+ resolve<T>(key: string, context?: string): T;
199
+ /**
200
+ * Resolve a transient instance
201
+ * @private
202
+ */
203
+ private resolveTransient;
204
+ /**
205
+ * Resolve a singleton instance
206
+ * @private
207
+ */
208
+ private resolveSingleton;
209
+ /**
210
+ * Resolve a scoped instance
211
+ * @private
212
+ */
213
+ private resolveScoped;
214
+ /**
215
+ * Resolve a lazy instance
216
+ * @private
217
+ */
218
+ private resolveLazy;
219
+ /**
220
+ * Create a contextual binding (different implementations based on context)
221
+ * Provides a fluent API for defining context-specific dependencies
222
+ *
223
+ * @param context The context identifier (usually a service name)
224
+ * @returns A fluent API object with needs() method
225
+ *
226
+ * @example
227
+ * ```typescript
228
+ * // UserService will receive MockUserRepo
229
+ * container.when('UserService').needs('UserRepo').give(() => new MockUserRepo());
230
+ *
231
+ * // OrderService will receive RealUserRepo
232
+ * container.when('OrderService').needs('UserRepo').give(() => new RealUserRepo());
233
+ * ```
234
+ */
235
+ when(context: string): {
236
+ needs: (depKey: string) => {
237
+ give: (factory: FactoryFn<any>) => void;
238
+ };
239
+ };
240
+ /**
241
+ * Check if a binding exists for a key
242
+ *
243
+ * @param key The service key to check
244
+ * @returns True if binding exists
245
+ *
246
+ * @example
247
+ * ```typescript
248
+ * if (container.has('logger')) {
249
+ * const logger = container.resolve('logger');
250
+ * }
251
+ * ```
252
+ */
253
+ has(key: string): boolean;
254
+ /**
255
+ * Get all registered service keys
256
+ *
257
+ * @returns Array of service keys
258
+ *
259
+ * @example
260
+ * ```typescript
261
+ * const keys = container.keys();
262
+ * console.log('Registered services:', keys);
263
+ * ```
264
+ */
265
+ keys(): string[];
266
+ /**
267
+ * Reset the container to its initial state
268
+ * Clears all bindings, instances, aliases, and context
269
+ * Useful for testing scenarios
270
+ *
271
+ * @example
272
+ * ```typescript
273
+ * afterEach(() => {
274
+ * container.reset();
275
+ * });
276
+ * ```
277
+ */
278
+ reset(): void;
279
+ /**
280
+ * Dispose the container and all its scoped instances
281
+ */
282
+ dispose(): Promise<void>;
283
+ }
284
+ //# sourceMappingURL=Container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Container.d.ts","sourceRoot":"","sources":["../../src/Container.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAEV,WAAW,EACX,SAAS,EACT,SAAS,EACT,SAAS,EACV,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC;;;;;;;;;;GAUG;AACH,qBAAa,SAAS;IACpB,mDAAmD;IACnD,OAAO,CAAC,QAAQ,CAAgC;IAEhD,oCAAoC;IAEpC,OAAO,CAAC,SAAS,CAA0B;IAE3C,0CAA0C;IAC1C,OAAO,CAAC,OAAO,CAA6B;IAE5C,6DAA6D;IAC7D,OAAO,CAAC,YAAY,CAA8B;IAElD,wDAAwD;IACxD,OAAO,CAAC,cAAc,CAAC,CAAS;IAEhC,qCAAqC;IACrC,OAAO,CAAC,MAAM,CAAC,CAAY;IAE3B,2BAA2B;IAC3B,OAAO,CAAC,YAAY,CAAC,CAAQ;IAE7B,yDAAyD;IACzD,OAAO,CAAC,eAAe,CAAgB;IAEvC;;;OAGG;gBACS,MAAM,CAAC,EAAE,SAAS;IAI9B;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,WAAW;IAOnE;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,WAAW;IAOxE;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,SAAS;IAOjE;;;;;;;;;;;;;;;OAeG;IACH,IAAI,CAAC,CAAC,EACJ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EACrB,SAAS,GAAE,SAAuB;IAQpC;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAI3C;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,IAAI,SAAS;IAIxB;;;;;;;;;;;;;;;OAeG;IACH,WAAW,IAAI,KAAK;IAMpB;;;;;;;;;;;;;;;OAeG;IACG,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAS1E;;;;;;;;;OASG;IACH,OAAO,CAAC,WAAW;IA0CnB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC;IA6C5C;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAcxB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAgBrB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAgBnB;;;;;;;;;;;;;;;OAeG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM;wBAEA,MAAM;4BAEJ,SAAS,CAAC,GAAG,CAAC;;;IAepC;;;;;;;;;;;;OAYG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;;;;;;;;;OAUG;IACH,IAAI,IAAI,MAAM,EAAE;IAMhB;;;;;;;;;;;OAWG;IACH,KAAK;IAUL;;OAEG;IACG,OAAO;CAMd"}
@@ -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,64 @@
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
+ * Internal binding interface representing a service registration
45
+ * @template T The type of service being bound
46
+ * @internal
47
+ */
48
+ export interface Binding<T = any> {
49
+ /** The service key identifier */
50
+ key: string;
51
+ /** Factory function to create the service instance */
52
+ factory: FactoryFn<T>;
53
+ /** Lifecycle type: transient, singleton, or scoped */
54
+ lifecycle: Lifecycle;
55
+ /** Optional condition for conditional binding */
56
+ condition?: ConditionFn;
57
+ /** Optional context for contextual binding */
58
+ context?: string;
59
+ /** Whether this is a lazy binding */
60
+ lazy?: boolean;
61
+ /** Optional disposal function */
62
+ dispose?: DisposeFn;
63
+ }
64
+ //# 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;;;;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"}
package/package.json CHANGED
@@ -1,25 +1,64 @@
1
1
  {
2
2
  "name": "@khapu2906/treasure-chest",
3
- "version": "1.0.3",
4
- "description": "A container package for system utilities",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
3
+ "version": "1.2.0",
4
+ "description": "A lightweight TypeScript dependency injection container for managing service dependencies",
5
+ "main": "dist/cjs/index.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/types/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/types/index.d.ts",
11
+ "import": "./dist/esm/index.js",
12
+ "require": "./dist/cjs/index.js"
13
+ }
14
+ },
7
15
  "files": [
8
- "dist"
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
9
19
  ],
10
20
  "scripts": {
11
- "build": "tsc",
12
- "test": "vitest",
21
+ "build": "npm run clean && npm run build:cjs && npm run build:esm && npm run build:types",
22
+ "build:cjs": "tsc -p tsconfig.cjs.json",
23
+ "build:esm": "tsc -p tsconfig.esm.json",
24
+ "build:types": "tsc -p tsconfig.types.json",
25
+ "clean": "rm -rf dist",
26
+ "test": "vitest run",
27
+ "test:watch": "vitest",
13
28
  "test:ui": "vitest --ui",
14
- "prepublishOnly": "npm run build && npm test"
29
+ "test:coverage": "vitest run --coverage",
30
+ "bench": "tsx benchmarks/performance.ts",
31
+ "example": "tsx",
32
+ "example:01": "tsx examples/01-basic-usage.ts",
33
+ "example:02": "tsx examples/02-dependency-injection.ts",
34
+ "example:03": "tsx examples/03-conditional-binding.ts",
35
+ "example:04": "tsx examples/04-contextual-binding.ts",
36
+ "example:05": "tsx examples/05-alias.ts",
37
+ "example:06": "tsx examples/06-scoped-lifecycle.ts",
38
+ "example:07": "tsx examples/07-lazy-loading.ts",
39
+ "example:08": "tsx examples/08-child-containers.ts",
40
+ "example:09": "tsx examples/09-circular-dependency.ts",
41
+ "examples": "npm run example:01 && npm run example:02 && npm run example:03 && npm run example:04 && npm run example:05 && npm run example:06 && npm run example:07 && npm run example:08 && npm run example:09",
42
+ "lint": "eslint . --ext .ts",
43
+ "lint:fix": "eslint . --ext .ts --fix",
44
+ "format": "prettier --write \"**/*.{ts,json,md}\"",
45
+ "format:check": "prettier --check \"**/*.{ts,json,md}\"",
46
+ "prepublishOnly": "npm run lint && npm run format:check && npm run build && npm test"
15
47
  },
16
48
  "keywords": [
17
49
  "container",
18
- "system",
19
- "utilities"
50
+ "dependency-injection",
51
+ "di",
52
+ "ioc",
53
+ "inversion-of-control",
54
+ "service-container",
55
+ "typescript",
56
+ "singleton",
57
+ "transient",
58
+ "contextual-binding"
20
59
  ],
21
60
  "author": "Kent Phung",
22
- "license": "MIT",
61
+ "license": "DIB",
23
62
  "repository": {
24
63
  "type": "git",
25
64
  "url": "git+https://github.com/khapu2906/treasure-chest.git"
@@ -30,10 +69,13 @@
30
69
  "homepage": "https://github.com/khapu2906/treasure-chest#readme",
31
70
  "devDependencies": {
32
71
  "@types/node": "^24.10.0",
33
- "typescript": "^5.9.3"
34
- },
35
- "dependencies": {
36
- "vitest": "^4.0.7",
37
- "vittest": "^1.0.2"
72
+ "@typescript-eslint/eslint-plugin": "^8.20.0",
73
+ "@typescript-eslint/parser": "^8.20.0",
74
+ "@vitest/coverage-v8": "^4.0.7",
75
+ "eslint": "^9.17.0",
76
+ "prettier": "^3.4.2",
77
+ "tsx": "^4.19.2",
78
+ "typescript": "^5.9.3",
79
+ "vitest": "^4.0.7"
38
80
  }
39
- }
81
+ }
package/dist/index.d.ts DELETED
@@ -1,53 +0,0 @@
1
- /**
2
- * Treasure Chest Service Container in TypeScript
3
- * Supports:
4
- * - bind / singleton
5
- * - conditional binding
6
- * - contextual binding
7
- * - alias
8
- * - resolve
9
- */
10
- type FactoryFn<T> = (c: Container) => T;
11
- type ConditionFn = (c: Container) => boolean;
12
- export declare class Container {
13
- private bindings;
14
- private instances;
15
- private aliases;
16
- private currentContext?;
17
- /**
18
- * Bind a dependency (default: transient)
19
- */
20
- bind<T>(key: string, factory: FactoryFn<T>, condition?: ConditionFn): void;
21
- /**
22
- * Bind a dependency as singleton (only one instance created)
23
- */
24
- singleton<T>(key: string, factory: FactoryFn<T>, condition?: ConditionFn): void;
25
- /**
26
- * Add an alias for an existing key
27
- */
28
- alias(aliasKey: string, originalKey: string): void;
29
- /**
30
- * Internal: find correct binding based on key + condition + context
31
- */
32
- private findBinding;
33
- /**
34
- * Resolve an instance from the container
35
- */
36
- resolve<T>(key: string, context?: string): T;
37
- /**
38
- * Contextual binding:
39
- * Example:
40
- * container.when('UserService').needs('UserRepo').give(...)
41
- */
42
- when(context: string): {
43
- needs: (depKey: string) => {
44
- give: (factory: FactoryFn<any>) => void;
45
- };
46
- };
47
- /**
48
- * Clear all bindings and instances (useful for testing)
49
- */
50
- reset(): void;
51
- }
52
- export {};
53
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,SAAS,KAAK,CAAC,CAAC;AACxC,KAAK,WAAW,GAAG,CAAC,CAAC,EAAE,SAAS,KAAK,OAAO,CAAC;AAU7C,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,cAAc,CAAC,CAAS;IAEhC;;OAEG;IACH,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,WAAW;IAInE;;OAEG;IACH,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,WAAW;IAIxE;;OAEG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAI3C;;OAEG;IACH,OAAO,CAAC,WAAW;IAsBnB;;OAEG;IACH,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC;IA8B5C;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM;wBAEA,MAAM;4BACJ,SAAS,CAAC,GAAG,CAAC;;;IAYpC;;OAEG;IACH,KAAK;CAMN"}