@goatlab/node-backend 0.2.5 → 0.4.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 +146 -14
- package/dist/container/Container.d.ts +113 -25
- package/dist/container/Container.js +391 -168
- package/dist/container/Container.js.map +1 -1
- package/dist/container/examples/batch-operations.example.d.ts +1 -0
- package/dist/container/examples/batch-operations.example.js +165 -0
- package/dist/container/examples/batch-operations.example.js.map +1 -0
- package/dist/container/helpers.d.ts +8 -0
- package/dist/container/helpers.js +22 -0
- package/dist/container/helpers.js.map +1 -1
- package/dist/container/types.d.ts +60 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/server/bootstraps/getExpressTrpcApp.d.ts +5 -1
- package/dist/server/bootstraps/getExpressTrpcApp.js +216 -12
- package/dist/server/bootstraps/getExpressTrpcApp.js.map +1 -1
- package/dist/server/middleware/memoryMonitor.example.d.ts +1 -0
- package/dist/server/middleware/memoryMonitor.example.js +109 -0
- package/dist/server/middleware/memoryMonitor.example.js.map +1 -0
- package/dist/server/middleware/memoryMonitor.middleware.d.ts +42 -0
- package/dist/server/middleware/memoryMonitor.middleware.js +134 -0
- package/dist/server/middleware/memoryMonitor.middleware.js.map +1 -0
- package/dist/server/middleware/productionError.middleware.d.ts +16 -0
- package/dist/server/middleware/productionError.middleware.js +94 -0
- package/dist/server/middleware/productionError.middleware.js.map +1 -0
- package/dist/server/middleware/security.middleware.d.ts +28 -0
- package/dist/server/middleware/security.middleware.js +151 -0
- package/dist/server/middleware/security.middleware.js.map +1 -0
- package/dist/server/services/secrets/examples/container-preload.example.d.ts +1 -0
- package/dist/server/services/secrets/examples/container-preload.example.js +148 -0
- package/dist/server/services/secrets/examples/container-preload.example.js.map +1 -0
- package/dist/server/services/secrets/index.d.ts +1 -0
- package/dist/server/services/secrets/index.js +6 -0
- package/dist/server/services/secrets/index.js.map +1 -0
- package/dist/server/services/secrets/secret.service.d.ts +48 -6
- package/dist/server/services/secrets/secret.service.js +280 -28
- package/dist/server/services/secrets/secret.service.js.map +1 -1
- package/dist/server/services/translations/translation.model.js +2 -1
- package/dist/server/services/translations/translation.model.js.map +1 -1
- package/dist/server/services/translations/translation.service.d.ts +8 -1
- package/dist/server/services/translations/translation.service.js +123 -13
- package/dist/server/services/translations/translation.service.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -1
package/README.md
CHANGED
|
@@ -62,38 +62,88 @@ const result = await cache.remember('expensive-op', 300000, async () => {
|
|
|
62
62
|
|
|
63
63
|
## Secret Management
|
|
64
64
|
|
|
65
|
-
The `SecretService` provides secure secret management with support for multiple backends:
|
|
65
|
+
The `SecretService` provides secure secret management with support for multiple backends and preloading:
|
|
66
66
|
|
|
67
67
|
```typescript
|
|
68
68
|
import { SecretService } from '@goatlab/node-backend'
|
|
69
69
|
|
|
70
|
-
// File-based encrypted secrets
|
|
71
|
-
const fileSecrets = new SecretService(
|
|
70
|
+
// File-based encrypted secrets with TTL caching
|
|
71
|
+
const fileSecrets = new SecretService({
|
|
72
|
+
provider: 'FILE',
|
|
73
|
+
location: '/path/to/secrets.json',
|
|
74
|
+
encryptionKey: process.env.ENCRYPTION_KEY,
|
|
75
|
+
cacheTTL: 300000 // 5 minutes (optional, default: 5 minutes)
|
|
76
|
+
})
|
|
72
77
|
|
|
73
78
|
// HashiCorp Vault integration
|
|
74
|
-
const vaultSecrets = new SecretService(
|
|
79
|
+
const vaultSecrets = new SecretService({
|
|
80
|
+
provider: 'VAULT',
|
|
81
|
+
location: 'my-app/secrets',
|
|
82
|
+
encryptionKey: process.env.ENCRYPTION_KEY
|
|
83
|
+
})
|
|
75
84
|
|
|
76
|
-
// Environment variables
|
|
77
|
-
const envSecrets = new SecretService(
|
|
78
|
-
|
|
85
|
+
// Environment variables
|
|
86
|
+
const envSecrets = new SecretService({
|
|
87
|
+
provider: 'ENV',
|
|
88
|
+
location: 'APP', // Loads APP_* env vars
|
|
89
|
+
encryptionKey: process.env.ENCRYPTION_KEY // Now supports encryption for all providers
|
|
90
|
+
})
|
|
79
91
|
|
|
80
|
-
//
|
|
81
|
-
await fileSecrets.
|
|
82
|
-
const apiKey =
|
|
83
|
-
const config =
|
|
92
|
+
// Preload secrets for synchronous access (new!)
|
|
93
|
+
await fileSecrets.preload()
|
|
94
|
+
const apiKey = fileSecrets.getSecretSync('API_KEY') // Synchronous!
|
|
95
|
+
const config = fileSecrets.getSecretJsonSync('CONFIG') // Synchronous!
|
|
96
|
+
|
|
97
|
+
// Async operations still available
|
|
98
|
+
const apiKeyAsync = await fileSecrets.getSecret('API_KEY')
|
|
99
|
+
const configAsync = await fileSecrets.getSecretJson('CONFIG')
|
|
84
100
|
|
|
85
101
|
// Store secrets (FILE and VAULT providers)
|
|
86
102
|
await fileSecrets.storeSecrets({ API_KEY: 'secret-value' })
|
|
103
|
+
|
|
104
|
+
// Manual cache cleanup
|
|
105
|
+
SecretService.cleanupExpiredCache()
|
|
106
|
+
|
|
107
|
+
// Dispose when done (stops file watching)
|
|
108
|
+
fileSecrets.dispose()
|
|
87
109
|
```
|
|
88
110
|
|
|
89
111
|
### Secret Provider Features
|
|
90
112
|
|
|
91
|
-
- **FILE**: Encrypted local file storage using AES encryption
|
|
113
|
+
- **FILE**: Encrypted local file storage using AES encryption with file watching
|
|
92
114
|
- **VAULT**: HashiCorp Vault integration with automatic token management
|
|
93
|
-
- **ENV**: Runtime environment variable access with
|
|
94
|
-
- **
|
|
115
|
+
- **ENV**: Runtime environment variable access with encryption support
|
|
116
|
+
- **Preloading**: Load secrets once async, access synchronously afterward
|
|
117
|
+
- **Per-Tenant Encryption**: Each tenant can have its own encryption key
|
|
118
|
+
- **Automatic Invalidation**: File changes trigger automatic reload (FILE provider)
|
|
119
|
+
- **TTL Caching**: Configurable time-to-live caching with automatic expiration
|
|
95
120
|
- **Type Safety**: Generic type support for JSON secrets
|
|
96
121
|
|
|
122
|
+
### Preloading Pattern with Container
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
const container = new Container(factories, async (preload, meta) => {
|
|
126
|
+
// Create and preload secret service
|
|
127
|
+
const secretService = preload.secrets(meta.tenantId, {
|
|
128
|
+
provider: 'FILE',
|
|
129
|
+
location: meta.secretsLocation,
|
|
130
|
+
encryptionKey: meta.encryptionKey
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
await secretService.preload() // Load once async
|
|
134
|
+
|
|
135
|
+
// Use sync methods for instant access
|
|
136
|
+
const dbUrl = secretService.getSecretSync('DATABASE_URL')
|
|
137
|
+
const apiKey = secretService.getSecretSync('API_KEY')
|
|
138
|
+
|
|
139
|
+
// Create other services with preloaded secrets
|
|
140
|
+
const database = preload.database(meta.tenantId, { url: dbUrl })
|
|
141
|
+
const api = preload.api(meta.tenantId, { apiKey })
|
|
142
|
+
|
|
143
|
+
return { secrets: secretService, database, api }
|
|
144
|
+
})
|
|
145
|
+
```
|
|
146
|
+
|
|
97
147
|
## Express + tRPC Integration
|
|
98
148
|
|
|
99
149
|
Helper for creating Express applications with tRPC integration:
|
|
@@ -117,6 +167,88 @@ const app = getExpressTrpcApp({
|
|
|
117
167
|
})
|
|
118
168
|
```
|
|
119
169
|
|
|
170
|
+
### Performance Features (New!)
|
|
171
|
+
|
|
172
|
+
- **Optimized Compression**: Automatically skips compression for small responses (<1KB), SSE, WebSocket upgrades, and pre-compressed content
|
|
173
|
+
- **Memory Monitoring**: Built-in middleware tracks heap usage and triggers garbage collection when needed
|
|
174
|
+
- **Smart Rate Limiting**: Different limits for auth endpoints, API endpoints, and general routes
|
|
175
|
+
|
|
176
|
+
## Container - Dependency Injection
|
|
177
|
+
|
|
178
|
+
Multi-tenant dependency injection container with performance optimizations:
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
import { Container } from '@goatlab/node-backend'
|
|
182
|
+
|
|
183
|
+
// Define your service factories
|
|
184
|
+
const factories = {
|
|
185
|
+
database: DatabaseService,
|
|
186
|
+
api: ApiService,
|
|
187
|
+
cache: CacheService
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Create container with initializer
|
|
191
|
+
const container = new Container(factories, async (preload, tenantMeta) => {
|
|
192
|
+
const db = preload.database(tenantMeta.id, tenantMeta.dbConfig)
|
|
193
|
+
const cache = preload.cache(tenantMeta.id)
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
database: db,
|
|
197
|
+
api: preload.api(tenantMeta.id, db),
|
|
198
|
+
cache
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
// Bootstrap for a tenant
|
|
203
|
+
await container.bootstrap(tenantMeta, async () => {
|
|
204
|
+
const { database, api } = container.context
|
|
205
|
+
// Use services...
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
// Batch operations (new!)
|
|
209
|
+
const results = await container.bootstrapBatch([
|
|
210
|
+
{ metadata: tenant1, fn: processTenant1 },
|
|
211
|
+
{ metadata: tenant2, fn: processTenant2 }
|
|
212
|
+
], {
|
|
213
|
+
concurrency: 10,
|
|
214
|
+
continueOnError: true,
|
|
215
|
+
onProgress: (completed, total) => console.log(`${completed}/${total}`)
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
// Batch cache invalidation (new!)
|
|
219
|
+
await container.invalidateTenantBatch(['tenant1', 'tenant2', 'tenant3'])
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Container Features
|
|
223
|
+
|
|
224
|
+
- **Multi-tenancy**: Isolated service instances per tenant
|
|
225
|
+
- **Batch Operations**: Process multiple tenants in parallel with concurrency control
|
|
226
|
+
- **Performance Metrics**: Built-in performance tracking and statistics
|
|
227
|
+
- **Cache Management**: Efficient caching with batch invalidation support
|
|
228
|
+
- **Type Safety**: Full TypeScript support with inference
|
|
229
|
+
|
|
230
|
+
## Translation Service
|
|
231
|
+
|
|
232
|
+
High-performance translation service with template caching:
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import { translationService } from '@goatlab/node-backend'
|
|
236
|
+
|
|
237
|
+
// Translations are automatically loaded and cached
|
|
238
|
+
const greeting = translationService.translate('welcome', { language: 'es' })
|
|
239
|
+
|
|
240
|
+
// With template parameters
|
|
241
|
+
const message = translationService.translate('user.greeting',
|
|
242
|
+
{ language: 'en' },
|
|
243
|
+
{ name: 'John' }
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
// Performance optimized with:
|
|
247
|
+
// - Compiled template caching
|
|
248
|
+
// - Locale preloading at startup
|
|
249
|
+
// - In-memory locale storage
|
|
250
|
+
```
|
|
251
|
+
|
|
120
252
|
## Testing Utilities
|
|
121
253
|
|
|
122
254
|
Comprehensive testing setup with testcontainers support:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ContainerOptions, InstancesStructure, PreloadStructure } from './types';
|
|
1
|
+
import { ContainerOptions, InstancesStructure, PreloadStructure, BatchBootstrapOptions, BatchBootstrapResult, BatchInvalidationResult } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* ═══════════════════════════════════════════════════════════════════════════════
|
|
4
4
|
* 🏗️ MULTI-TENANT DEPENDENCY INJECTION CONTAINER
|
|
@@ -83,6 +83,7 @@ export declare class Container<Defs extends Record<string, unknown>, TenantMetad
|
|
|
83
83
|
/**
|
|
84
84
|
* Service instance cache managers - one per service type
|
|
85
85
|
* Each manager handles LRU caching for that specific service
|
|
86
|
+
* Lazy-allocated to save memory for unused services
|
|
86
87
|
*/
|
|
87
88
|
private readonly managers;
|
|
88
89
|
/**
|
|
@@ -109,11 +110,6 @@ export declare class Container<Defs extends Record<string, unknown>, TenantMetad
|
|
|
109
110
|
* Prevents concurrent bootstrap for same tenant from running initializer twice
|
|
110
111
|
*/
|
|
111
112
|
private readonly initializerPromises;
|
|
112
|
-
/**
|
|
113
|
-
* Path string cache: converts ['user', 'repo'] -> "user.repo"
|
|
114
|
-
* Optimized to avoid repeated string joins and array operations
|
|
115
|
-
*/
|
|
116
|
-
private readonly pathCache;
|
|
117
113
|
/**
|
|
118
114
|
* Proxy object cache: reuses proxy objects for the same paths
|
|
119
115
|
* Reduces memory allocation and improves performance
|
|
@@ -132,14 +128,14 @@ export declare class Container<Defs extends Record<string, unknown>, TenantMetad
|
|
|
132
128
|
private readonly initializerCache;
|
|
133
129
|
/**
|
|
134
130
|
* High-performance metrics using Uint32Array for better JIT optimization
|
|
135
|
-
* Indices: [hits, misses, creates, ctx,
|
|
131
|
+
* Indices: [hits, misses, creates, ctx, proxy, initHits, resets, batchOps, batchErrors]
|
|
136
132
|
* Auto-wraps at 2^32 without overflow checks for maximum performance
|
|
137
133
|
*/
|
|
138
134
|
private readonly metrics;
|
|
139
135
|
/**
|
|
140
136
|
* Metric indices for Uint32Array
|
|
141
137
|
*/
|
|
142
|
-
private static readonly
|
|
138
|
+
private static readonly METRIC;
|
|
143
139
|
/**
|
|
144
140
|
* Legacy overflow threshold for test compatibility
|
|
145
141
|
* Note: With Uint32Array, overflow is handled automatically, but tests may mock this
|
|
@@ -166,25 +162,16 @@ export declare class Container<Defs extends Record<string, unknown>, TenantMetad
|
|
|
166
162
|
*/
|
|
167
163
|
constructor(factories: Defs, initializer: (preload: PreloadStructure<Defs>, meta: TenantMetadata) => Promise<Partial<InstancesStructure<Defs>>>, options?: ContainerOptions);
|
|
168
164
|
/**
|
|
169
|
-
*
|
|
170
|
-
*
|
|
165
|
+
* Get or create a cache manager for a service - lazy allocation
|
|
166
|
+
* Saves memory by only creating caches for services that are actually used
|
|
167
|
+
* Note: Type safety is enforced at compile time through generics, not runtime
|
|
171
168
|
*/
|
|
172
|
-
private
|
|
173
|
-
/**
|
|
174
|
-
* Optimized path caching that maintains flat key strings to avoid repeated joins
|
|
175
|
-
* Uses closure to keep pre-computed cache and final keys for maximum performance
|
|
176
|
-
*/
|
|
177
|
-
private getOrCachePath;
|
|
169
|
+
private getManager;
|
|
178
170
|
/**
|
|
179
171
|
* Pre-populate the factory cache by walking the entire factory tree
|
|
180
172
|
* This eliminates the need for recursive object traversal during runtime
|
|
181
173
|
*/
|
|
182
174
|
private preloadFactoryCache;
|
|
183
|
-
/**
|
|
184
|
-
* Pre-warm proxy cache with static builders for common paths
|
|
185
|
-
* This reduces proxy creation overhead during runtime access patterns
|
|
186
|
-
*/
|
|
187
|
-
private prewarmProxyCache;
|
|
188
175
|
/**
|
|
189
176
|
* Recursive factory tree walker that builds the flat factory cache
|
|
190
177
|
* Converts nested object structure to flat dot-notation keys
|
|
@@ -252,8 +239,15 @@ export declare class Container<Defs extends Record<string, unknown>, TenantMetad
|
|
|
252
239
|
*/
|
|
253
240
|
private createContextProxy;
|
|
254
241
|
/**
|
|
255
|
-
*
|
|
256
|
-
* Uses
|
|
242
|
+
* Simple string hash function for fallback tenant keys
|
|
243
|
+
* Uses djb2 algorithm - fast and good enough for cache keys
|
|
244
|
+
* Note: For very large metadata objects, consider upgrading to FNV-1a or crypto.createHash
|
|
245
|
+
* if collision resistance is critical. Current implementation is optimized for speed.
|
|
246
|
+
*/
|
|
247
|
+
private simpleHash;
|
|
248
|
+
/**
|
|
249
|
+
* Create a stable cache key from tenant metadata
|
|
250
|
+
* Uses common tenant properties or hashed JSON as fallback
|
|
257
251
|
*/
|
|
258
252
|
private createTenantCacheKey;
|
|
259
253
|
/**
|
|
@@ -291,6 +285,85 @@ export declare class Container<Defs extends Record<string, unknown>, TenantMetad
|
|
|
291
285
|
instances: InstancesStructure<Defs>;
|
|
292
286
|
result?: T;
|
|
293
287
|
}>;
|
|
288
|
+
/**
|
|
289
|
+
* Bootstrap multiple tenants in parallel with controlled concurrency
|
|
290
|
+
*
|
|
291
|
+
* This method enables efficient initialization of multiple tenants while:
|
|
292
|
+
* - Controlling concurrency to avoid overwhelming the system
|
|
293
|
+
* - Isolating errors so one failure doesn't affect others
|
|
294
|
+
* - Providing progress tracking for long-running operations
|
|
295
|
+
* - Collecting performance metrics for each operation
|
|
296
|
+
*
|
|
297
|
+
* @param tenantBatch - Array of tenant metadata and optional functions to execute
|
|
298
|
+
* @param options - Options for controlling the batch operation
|
|
299
|
+
* @returns Array of results for each tenant, including successes and failures
|
|
300
|
+
*
|
|
301
|
+
* ```typescript
|
|
302
|
+
* const results = await container.bootstrapBatch([
|
|
303
|
+
* { metadata: tenant1Meta, fn: async () => processТenant1() },
|
|
304
|
+
* { metadata: tenant2Meta, fn: async () => processTenant2() },
|
|
305
|
+
* { metadata: tenant3Meta } // No function, just bootstrap
|
|
306
|
+
* ], {
|
|
307
|
+
* concurrency: 5,
|
|
308
|
+
* continueOnError: true,
|
|
309
|
+
* onProgress: (completed, total) => console.log(`${completed}/${total}`)
|
|
310
|
+
* })
|
|
311
|
+
*
|
|
312
|
+
* // Process results
|
|
313
|
+
* for (const result of results) {
|
|
314
|
+
* if (result.status === 'success') {
|
|
315
|
+
* console.log(`Tenant ${result.metadata.id} initialized in ${result.metrics.duration}ms`)
|
|
316
|
+
* } else {
|
|
317
|
+
* console.error(`Tenant ${result.metadata.id} failed:`, result.error)
|
|
318
|
+
* }
|
|
319
|
+
* }
|
|
320
|
+
* ```
|
|
321
|
+
*/
|
|
322
|
+
bootstrapBatch<TMetadata = unknown, T = unknown>(tenantBatch: Array<{
|
|
323
|
+
metadata: TMetadata;
|
|
324
|
+
fn?: () => Promise<T>;
|
|
325
|
+
}>, options?: BatchBootstrapOptions<TMetadata>): Promise<Array<BatchBootstrapResult<Defs, TMetadata, T>>>;
|
|
326
|
+
/**
|
|
327
|
+
* Invalidate multiple tenant caches in batch
|
|
328
|
+
*
|
|
329
|
+
* Efficiently invalidates caches for multiple tenants with proper disposal
|
|
330
|
+
* and error handling. Useful for bulk updates or maintenance operations.
|
|
331
|
+
*
|
|
332
|
+
* @param tenantIds - Array of tenant IDs to invalidate
|
|
333
|
+
* @param reason - Optional reason for invalidation (for logging)
|
|
334
|
+
* @param distributed - Whether to propagate invalidation to other instances
|
|
335
|
+
* @returns Summary of the batch invalidation operation
|
|
336
|
+
*
|
|
337
|
+
* ```typescript
|
|
338
|
+
* const result = await container.invalidateTenantBatch(
|
|
339
|
+
* ['tenant1', 'tenant2', 'tenant3'],
|
|
340
|
+
* 'Bulk configuration update',
|
|
341
|
+
* true // Distribute to other instances
|
|
342
|
+
* )
|
|
343
|
+
*
|
|
344
|
+
* console.log(`Invalidated ${result.succeeded}/${result.total} tenants`)
|
|
345
|
+
* if (result.failed > 0) {
|
|
346
|
+
* console.error('Failed invalidations:', result.errors)
|
|
347
|
+
* }
|
|
348
|
+
* ```
|
|
349
|
+
*/
|
|
350
|
+
invalidateTenantBatch(tenantIds: string[], reason?: string, distributed?: boolean): Promise<BatchInvalidationResult>;
|
|
351
|
+
/**
|
|
352
|
+
* Invalidate multiple service caches in batch
|
|
353
|
+
*
|
|
354
|
+
* @param serviceTypes - Array of service types to invalidate
|
|
355
|
+
* @param reason - Optional reason for invalidation
|
|
356
|
+
* @param distributed - Whether to propagate invalidation
|
|
357
|
+
* @returns Summary of the batch invalidation operation
|
|
358
|
+
*
|
|
359
|
+
* ```typescript
|
|
360
|
+
* const result = await container.invalidateServiceBatch(
|
|
361
|
+
* ['database', 'api.users', 'api.auth'],
|
|
362
|
+
* 'Service configuration update'
|
|
363
|
+
* )
|
|
364
|
+
* ```
|
|
365
|
+
*/
|
|
366
|
+
invalidateServiceBatch(serviceTypes: string[], reason?: string, distributed?: boolean): Promise<BatchInvalidationResult>;
|
|
294
367
|
/**
|
|
295
368
|
* Get current performance metrics
|
|
296
369
|
* Converts Uint32Array back to object format for compatibility
|
|
@@ -300,9 +373,10 @@ export declare class Container<Defs extends Record<string, unknown>, TenantMetad
|
|
|
300
373
|
cacheMisses: number;
|
|
301
374
|
instanceCreations: number;
|
|
302
375
|
contextAccesses: number;
|
|
303
|
-
pathCacheHits: number;
|
|
304
376
|
proxyCacheHits: number;
|
|
305
377
|
initializerCacheHits: number;
|
|
378
|
+
batchOperations: number;
|
|
379
|
+
batchErrors: number;
|
|
306
380
|
};
|
|
307
381
|
/**
|
|
308
382
|
* Reset all performance metrics to zero
|
|
@@ -314,6 +388,12 @@ export declare class Container<Defs extends Record<string, unknown>, TenantMetad
|
|
|
314
388
|
* Calls optional dispose() hooks to prevent memory leaks (sockets, db handles, etc.)
|
|
315
389
|
*/
|
|
316
390
|
clearCaches(): void;
|
|
391
|
+
/**
|
|
392
|
+
* Async version of clearCaches that properly awaits all disposal operations
|
|
393
|
+
* Use this method when you need to ensure all resources are fully disposed
|
|
394
|
+
* before continuing (e.g., during graceful shutdown)
|
|
395
|
+
*/
|
|
396
|
+
clearCachesAsync(): Promise<void>;
|
|
317
397
|
/**
|
|
318
398
|
* Setup distributed cache invalidation system
|
|
319
399
|
* Connects to Redis pub/sub for coordinating cache invalidation across instances
|
|
@@ -345,6 +425,12 @@ export declare class Container<Defs extends Record<string, unknown>, TenantMetad
|
|
|
345
425
|
* Invalidate all cached data (local only)
|
|
346
426
|
*/
|
|
347
427
|
private invalidateAllLocally;
|
|
428
|
+
/**
|
|
429
|
+
* Dispose all service instances across all tenants and clear caches
|
|
430
|
+
* Useful for graceful shutdown and testing cleanup
|
|
431
|
+
* Note: This also clears all caches to prevent resurrection of disposed services
|
|
432
|
+
*/
|
|
433
|
+
disposeAll(): Promise<void>;
|
|
348
434
|
/**
|
|
349
435
|
* Get detailed cache statistics for each service
|
|
350
436
|
* Shows how many instances are cached and the cache limits
|
|
@@ -369,13 +455,15 @@ export declare class Container<Defs extends Record<string, unknown>, TenantMetad
|
|
|
369
455
|
initializerCacheSize: number;
|
|
370
456
|
initializerPromisesSize: number;
|
|
371
457
|
cacheHitRatio: number;
|
|
458
|
+
batchSuccessRatio: number;
|
|
372
459
|
cacheHits: number;
|
|
373
460
|
cacheMisses: number;
|
|
374
461
|
instanceCreations: number;
|
|
375
462
|
contextAccesses: number;
|
|
376
|
-
pathCacheHits: number;
|
|
377
463
|
proxyCacheHits: number;
|
|
378
464
|
initializerCacheHits: number;
|
|
465
|
+
batchOperations: number;
|
|
466
|
+
batchErrors: number;
|
|
379
467
|
};
|
|
380
468
|
/**
|
|
381
469
|
* Check if there's an active tenant context
|