@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.
- package/README.md +490 -27
- package/dist/cjs/Container.js +491 -0
- package/dist/cjs/Container.js.map +1 -0
- package/dist/cjs/Lazy.js +46 -0
- package/dist/cjs/Lazy.js.map +1 -0
- package/dist/cjs/Scope.js +93 -0
- package/dist/cjs/Scope.js.map +1 -0
- package/dist/cjs/index.js +40 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/types.js +8 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/Container.js +487 -0
- package/dist/esm/Container.js.map +1 -0
- package/dist/esm/Lazy.js +42 -0
- package/dist/esm/Lazy.js.map +1 -0
- package/dist/esm/Scope.js +89 -0
- package/dist/esm/Scope.js.map +1 -0
- package/dist/esm/index.js +34 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/types.js +7 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/types/Container.d.ts +299 -0
- package/dist/types/Container.d.ts.map +1 -0
- package/dist/types/Lazy.d.ts +34 -0
- package/dist/types/Lazy.d.ts.map +1 -0
- package/dist/types/Scope.d.ts +60 -0
- package/dist/types/Scope.d.ts.map +1 -0
- package/dist/types/index.d.ts +34 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/types.d.ts +77 -0
- package/dist/types/types.d.ts.map +1 -0
- package/package.json +63 -16
- package/dist/index.d.ts +0 -53
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -110
- package/dist/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,43 @@
|
|
|
1
1
|
# Treasure Chest
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@khapu2906/treasure-chest)
|
|
4
|
+
[](https://github.com/khapu2906/treasure-chest/actions/workflows/ci.yml)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://nodejs.org/)
|
|
8
|
+
|
|
9
|
+
A lightweight and powerful TypeScript dependency injection container for managing service dependencies with support for transient, singleton, scoped, lazy, conditional, and contextual bindings.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
### Core Features
|
|
14
|
+
|
|
15
|
+
- **Lightweight**: Zero runtime dependencies, minimal footprint
|
|
16
|
+
- **TypeScript First**: Full TypeScript support with complete type safety
|
|
17
|
+
- **Flexible Lifecycle**: Transient, singleton, and scoped bindings
|
|
18
|
+
- **Lazy Loading**: Deferred initialization for performance optimization
|
|
19
|
+
- **Container Hierarchy**: Child containers with inheritance
|
|
20
|
+
- **Nested Dependencies**: Automatic resolution of dependency chains
|
|
21
|
+
- **Circular Detection**: Automatic circular dependency detection
|
|
22
|
+
- **Conditional & Contextual**: Environment and context-aware bindings
|
|
23
|
+
- **Alias Support**: Multiple names for the same service
|
|
24
|
+
|
|
25
|
+
### Performance (v1.2.0)
|
|
26
|
+
|
|
27
|
+
- **Map-based Storage**: O(1) lookup complexity (10-100x faster)
|
|
28
|
+
- **Binding Cache**: Memoized results for non-conditional bindings
|
|
29
|
+
- **High-Speed Resolution**: 3.67M ops/sec (worst case), 24.7M ops/sec (cached)
|
|
30
|
+
- **Auto-Dispose**: IDisposable interface with zero overhead
|
|
31
|
+
- **Modular Architecture**: Better tree-shaking and code splitting
|
|
32
|
+
|
|
33
|
+
### Developer Experience
|
|
34
|
+
|
|
35
|
+
- **Intuitive API**: Fluent API with comprehensive JSDoc
|
|
36
|
+
- **Well Tested**: 62+ test cases with full coverage
|
|
37
|
+
- **Dual Module Support**: Both CommonJS and ES Modules (ESM)
|
|
38
|
+
- **Type Safe**: Full TypeScript declarations
|
|
39
|
+
- **Production Ready**: Battle-tested patterns
|
|
40
|
+
- **Modular Codebase**: Clean separation of concerns
|
|
4
41
|
|
|
5
42
|
## Installation
|
|
6
43
|
|
|
@@ -8,7 +45,7 @@ A simple and powerful TypeScript dependency injection container.
|
|
|
8
45
|
npm install @khapu2906/treasure-chest
|
|
9
46
|
```
|
|
10
47
|
|
|
11
|
-
##
|
|
48
|
+
## Quick Start
|
|
12
49
|
|
|
13
50
|
```typescript
|
|
14
51
|
import { Container } from '@khapu2906/treasure-chest';
|
|
@@ -17,7 +54,7 @@ const container = new Container();
|
|
|
17
54
|
|
|
18
55
|
// Register a service
|
|
19
56
|
container.bind('logger', () => ({
|
|
20
|
-
log: (message: string) => console.log(`[LOG] ${message}`)
|
|
57
|
+
log: (message: string) => console.log(`[LOG] ${message}`),
|
|
21
58
|
}));
|
|
22
59
|
|
|
23
60
|
// Use the service
|
|
@@ -28,6 +65,7 @@ logger.log('Hello World!');
|
|
|
28
65
|
## Key Features
|
|
29
66
|
|
|
30
67
|
### 1. Bind (Transient)
|
|
68
|
+
|
|
31
69
|
Creates a new instance on each resolve:
|
|
32
70
|
|
|
33
71
|
```typescript
|
|
@@ -39,6 +77,7 @@ console.log(instance1.id !== instance2.id); // true
|
|
|
39
77
|
```
|
|
40
78
|
|
|
41
79
|
### 2. Singleton
|
|
80
|
+
|
|
42
81
|
Creates only one instance:
|
|
43
82
|
|
|
44
83
|
```typescript
|
|
@@ -50,6 +89,7 @@ console.log(cache1 === cache2); // true
|
|
|
50
89
|
```
|
|
51
90
|
|
|
52
91
|
### 3. Alias
|
|
92
|
+
|
|
53
93
|
Create aliases for services:
|
|
54
94
|
|
|
55
95
|
```typescript
|
|
@@ -60,49 +100,341 @@ const logger = container.resolve('appLogger'); // Same as 'logger'
|
|
|
60
100
|
```
|
|
61
101
|
|
|
62
102
|
### 4. Conditional Binding
|
|
103
|
+
|
|
63
104
|
Register services based on conditions:
|
|
64
105
|
|
|
65
106
|
```typescript
|
|
66
107
|
const env = 'production';
|
|
67
108
|
|
|
68
|
-
container.bind(
|
|
69
|
-
|
|
109
|
+
container.bind(
|
|
110
|
+
'storage',
|
|
111
|
+
() => ({ type: 'local' }),
|
|
112
|
+
() => env === 'development'
|
|
113
|
+
);
|
|
114
|
+
container.bind(
|
|
115
|
+
'storage',
|
|
116
|
+
() => ({ type: 's3' }),
|
|
117
|
+
() => env === 'production'
|
|
118
|
+
);
|
|
70
119
|
|
|
71
120
|
const storage = container.resolve('storage'); // { type: 's3' }
|
|
72
121
|
```
|
|
73
122
|
|
|
74
123
|
### 5. Contextual Binding
|
|
124
|
+
|
|
75
125
|
Register different implementations for different contexts:
|
|
76
126
|
|
|
77
127
|
```typescript
|
|
78
|
-
container
|
|
79
|
-
|
|
128
|
+
container
|
|
129
|
+
.when('UserService')
|
|
130
|
+
.needs('repository')
|
|
131
|
+
.give(() => new UserRepository());
|
|
132
|
+
container
|
|
133
|
+
.when('AdminService')
|
|
134
|
+
.needs('repository')
|
|
135
|
+
.give(() => new AdminRepository());
|
|
80
136
|
|
|
81
137
|
const userRepo = container.resolve('repository', 'UserService'); // UserRepository
|
|
82
138
|
const adminRepo = container.resolve('repository', 'AdminService'); // AdminRepository
|
|
83
139
|
```
|
|
84
140
|
|
|
141
|
+
### 6. Container Composition (NEW in v1.3.0)
|
|
142
|
+
|
|
143
|
+
Mix services from different domains without inheritance:
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { Container } from '@khapu2906/treasure-chest';
|
|
147
|
+
|
|
148
|
+
// Create domain-specific containers
|
|
149
|
+
const infra = new Container();
|
|
150
|
+
infra.singleton('db', () => new Database());
|
|
151
|
+
|
|
152
|
+
const services = new Container();
|
|
153
|
+
services.singleton('userService', () => new UserService());
|
|
154
|
+
|
|
155
|
+
const controllers = new Container();
|
|
156
|
+
controllers.singleton('userController', () => new UserController());
|
|
157
|
+
|
|
158
|
+
// Compose them together
|
|
159
|
+
const app = Container.compose([infra, services, controllers]);
|
|
160
|
+
|
|
161
|
+
// All services available in one container
|
|
162
|
+
const db = app.resolve('db');
|
|
163
|
+
const userService = app.resolve('userService');
|
|
164
|
+
const userController = app.resolve('userController');
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 7. Scoped Lifecycle (NEW in v1.2.0)
|
|
168
|
+
|
|
169
|
+
Per-scope instances with automatic cleanup:
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import { Container } from '@khapu2906/treasure-chest';
|
|
173
|
+
|
|
174
|
+
const container = new Container();
|
|
175
|
+
|
|
176
|
+
// Register scoped service with cleanup
|
|
177
|
+
container.scoped(
|
|
178
|
+
'dbConnection',
|
|
179
|
+
() => new DbConnection(),
|
|
180
|
+
function () {
|
|
181
|
+
this.close();
|
|
182
|
+
} // Cleanup function
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
// Create a scope (e.g., per HTTP request)
|
|
186
|
+
const scope = container.createScope();
|
|
187
|
+
|
|
188
|
+
const conn1 = container.resolve('dbConnection');
|
|
189
|
+
const conn2 = container.resolve('dbConnection');
|
|
190
|
+
console.log(conn1 === conn2); // true - same instance within scope
|
|
191
|
+
|
|
192
|
+
// Cleanup when done
|
|
193
|
+
await scope.dispose(); // Calls cleanup functions
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### 7. Lazy Loading (NEW in v1.2.0)
|
|
197
|
+
|
|
198
|
+
Defer expensive initialization:
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import { Container, Lazy } from '@khapu2906/treasure-chest';
|
|
202
|
+
|
|
203
|
+
const container = new Container();
|
|
204
|
+
|
|
205
|
+
// Register lazy service
|
|
206
|
+
container.lazy('heavyService', () => new HeavyMLModel());
|
|
207
|
+
|
|
208
|
+
// Resolve as Lazy wrapper
|
|
209
|
+
const lazy = container.resolve<Lazy<HeavyMLModel>>('heavyService');
|
|
210
|
+
|
|
211
|
+
console.log(lazy.isInitialized); // false - not loaded yet
|
|
212
|
+
|
|
213
|
+
// Access when needed
|
|
214
|
+
const model = lazy.value; // NOW it's initialized
|
|
215
|
+
|
|
216
|
+
console.log(lazy.isInitialized); // true
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### 8. Child Containers (NEW in v1.2.0)
|
|
220
|
+
|
|
221
|
+
Container hierarchy for multi-tenant apps:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
const parent = new Container();
|
|
225
|
+
parent.singleton('config', () => new Config());
|
|
226
|
+
|
|
227
|
+
// Create child container
|
|
228
|
+
const tenant1 = parent.createChild();
|
|
229
|
+
tenant1.singleton('logger', () => new TenantLogger('tenant1'));
|
|
230
|
+
|
|
231
|
+
const tenant2 = parent.createChild();
|
|
232
|
+
tenant2.singleton('logger', () => new TenantLogger('tenant2'));
|
|
233
|
+
|
|
234
|
+
// Each tenant has its own logger but shares config
|
|
235
|
+
tenant1.resolve('config'); // From parent
|
|
236
|
+
tenant1.resolve('logger'); // From tenant1
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### 9. Circular Dependency Detection (NEW in v1.2.0)
|
|
240
|
+
|
|
241
|
+
Automatic detection with clear error messages:
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
container.bind('A', (c) => {
|
|
245
|
+
const b = c.resolve('B');
|
|
246
|
+
return { name: 'A', dep: b };
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
container.bind('B', (c) => {
|
|
250
|
+
const a = c.resolve('A'); // Circular!
|
|
251
|
+
return { name: 'B', dep: a };
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
try {
|
|
255
|
+
container.resolve('A');
|
|
256
|
+
} catch (error) {
|
|
257
|
+
console.log(error.message);
|
|
258
|
+
// "Circular dependency detected: A -> B -> A"
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### 10. IDisposable Interface & Auto-Dispose (NEW in v1.2.0)
|
|
263
|
+
|
|
264
|
+
Automatic cleanup detection with zero overhead:
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
import { Container, IDisposable } from '@khapu2906/treasure-chest';
|
|
268
|
+
|
|
269
|
+
// Implement IDisposable for auto-cleanup
|
|
270
|
+
class DbConnection implements IDisposable {
|
|
271
|
+
async connect() {
|
|
272
|
+
console.log('Connected');
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async dispose() {
|
|
276
|
+
console.log('Disconnected');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const container = new Container();
|
|
281
|
+
|
|
282
|
+
// Auto-detection: No need to pass dispose function!
|
|
283
|
+
container.scoped('db', () => new DbConnection());
|
|
284
|
+
|
|
285
|
+
// Using withScope() - C# using pattern
|
|
286
|
+
await container.withScope(async (scope) => {
|
|
287
|
+
const db = container.resolve<DbConnection>('db');
|
|
288
|
+
await db.connect();
|
|
289
|
+
// Auto-disposed when scope exits
|
|
290
|
+
});
|
|
291
|
+
// Dispose called automatically here
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### 11. Web Framework Integration Pattern
|
|
295
|
+
|
|
296
|
+
Pattern for automatic per-request scope management. See `examples/10-middleware.ts` for full implementation.
|
|
297
|
+
|
|
298
|
+
> **Note:** Middleware helpers are not exported from the core package to keep it framework-agnostic.
|
|
299
|
+
> For production use, consider creating separate adapter packages.
|
|
300
|
+
|
|
301
|
+
**Pattern Example:**
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
import { Container } from '@khapu2906/treasure-chest';
|
|
305
|
+
|
|
306
|
+
const container = new Container();
|
|
307
|
+
container.scoped('db', () => new DbConnection());
|
|
308
|
+
|
|
309
|
+
// Express pattern
|
|
310
|
+
function expressScope(container: Container) {
|
|
311
|
+
return (req, res, next) => {
|
|
312
|
+
const scope = container.createScope();
|
|
313
|
+
req.scope = scope;
|
|
314
|
+
res.on('finish', () => scope.dispose());
|
|
315
|
+
next();
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
app.use(expressScope(container));
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**Supported Patterns:**
|
|
323
|
+
|
|
324
|
+
- ✅ Express middleware
|
|
325
|
+
- ✅ Fastify hooks (onRequest/onResponse)
|
|
326
|
+
- ✅ Koa middleware
|
|
327
|
+
|
|
328
|
+
See [examples/10-middleware.ts](./examples/10-middleware.ts) for complete implementations.
|
|
329
|
+
|
|
85
330
|
## API Reference
|
|
86
331
|
|
|
87
332
|
### Container Class
|
|
88
333
|
|
|
89
|
-
####
|
|
90
|
-
|
|
334
|
+
#### Lifecycle Methods
|
|
335
|
+
|
|
336
|
+
**`bind<T>(key: string, factory: FactoryFn<T>, condition?: ConditionFn)`**
|
|
337
|
+
|
|
338
|
+
- Register a transient service (new instance each time)
|
|
339
|
+
|
|
340
|
+
**`singleton<T>(key: string, factory: FactoryFn<T>, condition?: ConditionFn)`**
|
|
341
|
+
|
|
342
|
+
- Register a singleton service (single instance shared)
|
|
343
|
+
|
|
344
|
+
**`scoped<T>(key: string, factory: FactoryFn<T>, dispose?: DisposeFn)` ⭐ NEW**
|
|
345
|
+
|
|
346
|
+
- Register a scoped service (instance per scope)
|
|
347
|
+
- Optional cleanup function called on dispose
|
|
348
|
+
|
|
349
|
+
**`lazy<T>(key: string, factory: FactoryFn<T>, lifecycle?: Lifecycle)` ⭐ NEW**
|
|
350
|
+
|
|
351
|
+
- Register a lazy service (deferred initialization)
|
|
352
|
+
- Returns `Lazy<T>` wrapper
|
|
353
|
+
- Default lifecycle: singleton
|
|
354
|
+
|
|
355
|
+
#### Resolution Methods
|
|
356
|
+
|
|
357
|
+
**`resolve<T>(key: string, context?: string): T`**
|
|
358
|
+
|
|
359
|
+
- Resolve a service from the container
|
|
360
|
+
- Supports circular dependency detection
|
|
361
|
+
|
|
362
|
+
**`has(key: string): boolean` ⭐ NEW**
|
|
363
|
+
|
|
364
|
+
- Check if a binding exists for a key
|
|
365
|
+
|
|
366
|
+
**`keys(): string[]` ⭐ NEW**
|
|
367
|
+
|
|
368
|
+
- Get all registered service keys
|
|
369
|
+
|
|
370
|
+
#### Contextual Binding
|
|
371
|
+
|
|
372
|
+
**`when(context: string).needs(key: string).give(factory: FactoryFn)`**
|
|
373
|
+
|
|
374
|
+
- Create context-specific bindings
|
|
375
|
+
- Fluent API for readability
|
|
376
|
+
|
|
377
|
+
**`alias(aliasKey: string, originalKey: string)`**
|
|
91
378
|
|
|
92
|
-
|
|
93
|
-
Register a singleton service.
|
|
379
|
+
- Create an alias for a service
|
|
94
380
|
|
|
95
|
-
####
|
|
96
|
-
Create an alias for a service.
|
|
381
|
+
#### Container Composition
|
|
97
382
|
|
|
98
|
-
|
|
99
|
-
Resolve a service from the container.
|
|
383
|
+
**`Container.compose(containers: Container[]): Container` ⭐ NEW v1.2.0**
|
|
100
384
|
|
|
101
|
-
|
|
102
|
-
|
|
385
|
+
- Combine multiple containers into one
|
|
386
|
+
- Allows mixing services from different domains
|
|
387
|
+
- First-wins conflict resolution
|
|
388
|
+
- Maintains container isolation
|
|
103
389
|
|
|
104
|
-
####
|
|
105
|
-
|
|
390
|
+
#### Container Hierarchy
|
|
391
|
+
|
|
392
|
+
**`createChild(): Container` ⭐ NEW**
|
|
393
|
+
|
|
394
|
+
- Create a child container that inherits from parent
|
|
395
|
+
- Children can override parent bindings
|
|
396
|
+
|
|
397
|
+
**`createScope(): Scope` ⭐ NEW**
|
|
398
|
+
|
|
399
|
+
- Create a new scope for scoped instances
|
|
400
|
+
- Returns a `Scope` object
|
|
401
|
+
|
|
402
|
+
**`withScope<T>(callback: (scope: Scope) => T | Promise<T>): Promise<T>` ⭐ NEW v1.2.0**
|
|
403
|
+
|
|
404
|
+
- Execute callback with auto-managed scope
|
|
405
|
+
- C#-style `using` statement pattern
|
|
406
|
+
- Automatic disposal even on errors
|
|
407
|
+
- Exception-safe cleanup
|
|
408
|
+
|
|
409
|
+
#### Cleanup
|
|
410
|
+
|
|
411
|
+
**`reset()`**
|
|
412
|
+
|
|
413
|
+
- Clear all bindings and instances
|
|
414
|
+
|
|
415
|
+
**`dispose(): Promise<void>` ⭐ NEW**
|
|
416
|
+
|
|
417
|
+
- Dispose container and all scoped instances
|
|
418
|
+
- Calls cleanup functions
|
|
419
|
+
|
|
420
|
+
### Exported Types
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
import {
|
|
424
|
+
Container,
|
|
425
|
+
Lazy,
|
|
426
|
+
Scope,
|
|
427
|
+
Lifecycle,
|
|
428
|
+
IDisposable,
|
|
429
|
+
DisposeFn,
|
|
430
|
+
} from '@khapu2906/treasure-chest';
|
|
431
|
+
|
|
432
|
+
// Lifecycle: 'transient' | 'singleton' | 'scoped'
|
|
433
|
+
// Lazy<T>: Wrapper with .value and .isInitialized
|
|
434
|
+
// Scope: Scope management with .dispose()
|
|
435
|
+
// IDisposable: Interface for auto-cleanup detection ⭐ NEW v1.2.0
|
|
436
|
+
// DisposeFn: Type for cleanup functions
|
|
437
|
+
```
|
|
106
438
|
|
|
107
439
|
### Global Container
|
|
108
440
|
|
|
@@ -145,31 +477,162 @@ const container = new Container();
|
|
|
145
477
|
|
|
146
478
|
container.singleton('db', () => new Database());
|
|
147
479
|
container.singleton('userRepo', (c) => new UserRepository(c.resolve('db')));
|
|
148
|
-
container.singleton(
|
|
480
|
+
container.singleton(
|
|
481
|
+
'userService',
|
|
482
|
+
(c) => new UserService(c.resolve('userRepo'))
|
|
483
|
+
);
|
|
149
484
|
|
|
150
485
|
// Contextual binding
|
|
151
|
-
container
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
486
|
+
container
|
|
487
|
+
.when('AdminService')
|
|
488
|
+
.needs('userRepo')
|
|
489
|
+
.give((c) => ({
|
|
490
|
+
...c.resolve('userRepo'),
|
|
491
|
+
adminAccess: true,
|
|
492
|
+
}));
|
|
155
493
|
|
|
156
494
|
// Usage
|
|
157
495
|
const userService = container.resolve<UserService>('userService');
|
|
158
496
|
console.log(userService.getUser(1)); // { id: 1, name: 'John Doe' }
|
|
159
497
|
```
|
|
160
498
|
|
|
161
|
-
##
|
|
499
|
+
## Examples
|
|
500
|
+
|
|
501
|
+
Check out the [examples](./examples) directory for comprehensive real-world usage patterns:
|
|
502
|
+
|
|
503
|
+
### Basic Features
|
|
504
|
+
|
|
505
|
+
1. **Basic Usage**: Transient and singleton bindings
|
|
506
|
+
2. **Dependency Injection**: Nested dependency resolution
|
|
507
|
+
3. **Conditional Binding**: Environment-based configuration
|
|
508
|
+
4. **Contextual Binding**: Context-aware service resolution
|
|
509
|
+
5. **Alias**: Multiple names for the same service
|
|
510
|
+
|
|
511
|
+
### Advanced Features (v1.2.0)
|
|
512
|
+
|
|
513
|
+
6. **Scoped Lifecycle**: Per-request services with cleanup
|
|
514
|
+
7. **Lazy Loading**: Performance optimization with deferred init
|
|
515
|
+
8. **Child Containers**: Multi-tenant and plugin systems
|
|
516
|
+
9. **Circular Dependency**: Detection and best practices
|
|
517
|
+
10. **Container Composition**: Mix services from different domains
|
|
518
|
+
|
|
519
|
+
### Performance & Integration (v1.2.0) ⭐ NEW
|
|
520
|
+
|
|
521
|
+
11. **Web Framework Middleware**: Express, Fastify, Koa integration
|
|
522
|
+
- Auto-scoping per HTTP request
|
|
523
|
+
- IDisposable auto-detection
|
|
524
|
+
- withScope() pattern demos
|
|
525
|
+
|
|
526
|
+
Each example includes detailed comments and runnable code.
|
|
527
|
+
|
|
528
|
+
## Development
|
|
529
|
+
|
|
530
|
+
### Install Dependencies
|
|
162
531
|
|
|
163
532
|
```bash
|
|
533
|
+
npm install
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### Running Tests
|
|
537
|
+
|
|
538
|
+
```bash
|
|
539
|
+
# Run all tests
|
|
164
540
|
npm test
|
|
541
|
+
|
|
542
|
+
# Run tests in watch mode
|
|
543
|
+
npm run test:watch
|
|
544
|
+
|
|
545
|
+
# Run tests with coverage
|
|
546
|
+
npm run test:coverage
|
|
547
|
+
|
|
548
|
+
# Run tests with UI
|
|
549
|
+
npm run test:ui
|
|
165
550
|
```
|
|
166
551
|
|
|
167
|
-
|
|
552
|
+
### Linting and Formatting
|
|
168
553
|
|
|
169
554
|
```bash
|
|
555
|
+
# Run ESLint
|
|
556
|
+
npm run lint
|
|
557
|
+
|
|
558
|
+
# Fix linting issues
|
|
559
|
+
npm run lint:fix
|
|
560
|
+
|
|
561
|
+
# Format code with Prettier
|
|
562
|
+
npm run format
|
|
563
|
+
|
|
564
|
+
# Check formatting
|
|
565
|
+
npm run format:check
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
### Building
|
|
569
|
+
|
|
570
|
+
```bash
|
|
571
|
+
# Build for production (generates CJS, ESM, and type declarations)
|
|
170
572
|
npm run build
|
|
573
|
+
|
|
574
|
+
# Clean build artifacts
|
|
575
|
+
npm run clean
|
|
171
576
|
```
|
|
172
577
|
|
|
578
|
+
### Running Benchmarks ⭐ NEW v1.2.0
|
|
579
|
+
|
|
580
|
+
```bash
|
|
581
|
+
# Run performance benchmarks
|
|
582
|
+
npm run benchmark
|
|
583
|
+
|
|
584
|
+
# Results auto-saved to:
|
|
585
|
+
# - benchmarks/results/run-YYYY-MM-DD-HH-MM-SS.json (timestamped)
|
|
586
|
+
# - benchmarks/results/history.jsonl (append-only log)
|
|
587
|
+
# - benchmarks/results/LATEST.md (human-readable report)
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
See [benchmarks/README.md](./benchmarks/README.md) for detailed documentation on:
|
|
591
|
+
|
|
592
|
+
- Benchmark categories
|
|
593
|
+
- Result formats
|
|
594
|
+
- Comparing performance over time
|
|
595
|
+
- Expected performance metrics
|
|
596
|
+
|
|
597
|
+
### Running Examples
|
|
598
|
+
|
|
599
|
+
```bash
|
|
600
|
+
# Run a specific example
|
|
601
|
+
npm run example:01 # Basic usage
|
|
602
|
+
npm run example:02 # Dependency injection
|
|
603
|
+
npm run example:10 # Middleware (v1.2.0)
|
|
604
|
+
|
|
605
|
+
# Run all examples sequentially
|
|
606
|
+
npm run examples
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
## Contributing
|
|
610
|
+
|
|
611
|
+
Contributions are welcome! Please read the [CONTRIBUTING.md](./CONTRIBUTING.md) for details on our code of conduct and development process.
|
|
612
|
+
|
|
613
|
+
## Changelog
|
|
614
|
+
|
|
615
|
+
See [CHANGELOG.md](./CHANGELOG.md) for a list of changes and version history.
|
|
616
|
+
|
|
173
617
|
## License
|
|
174
618
|
|
|
175
|
-
DIB
|
|
619
|
+
This project is licensed under the DIB License - see the [LICENSE](./LICENSE) file for details.
|
|
620
|
+
|
|
621
|
+
## Author
|
|
622
|
+
|
|
623
|
+
**Kent Phung**
|
|
624
|
+
|
|
625
|
+
- GitHub: [@khapu2906](https://github.com/khapu2906)
|
|
626
|
+
- Package: [@khapu2906/treasure-chest](https://www.npmjs.com/package/@khapu2906/treasure-chest)
|
|
627
|
+
|
|
628
|
+
## Support
|
|
629
|
+
|
|
630
|
+
If you encounter any issues or have questions:
|
|
631
|
+
|
|
632
|
+
- Open an issue on [GitHub Issues](https://github.com/khapu2906/treasure-chest/issues)
|
|
633
|
+
- Check the [examples](./examples) for usage patterns
|
|
634
|
+
- Read the [API Reference](#api-reference) above
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
Made with ❤️ by Kent Phung
|