@fjell/registry 4.4.6 → 4.4.9

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.
Files changed (54) hide show
  1. package/README.md +81 -4
  2. package/dist/Registry.cjs +20 -1
  3. package/dist/Registry.js +20 -1
  4. package/dist/RegistryHub.cjs +17 -1
  5. package/dist/RegistryHub.js +17 -1
  6. package/dist/index.cjs +35 -0
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/types.d.ts +15 -0
  9. package/docs/README.md +74 -0
  10. package/docs/index.html +17 -0
  11. package/docs/memory-data/scaling-10-instances.json +206 -206
  12. package/docs/memory-data/scaling-100-instances.json +206 -206
  13. package/docs/memory-data/scaling-1000-instances.json +108 -108
  14. package/docs/memory-data/scaling-10000-instances.json +49 -49
  15. package/docs/memory-data/scaling-20-instances.json +208 -208
  16. package/docs/memory-data/scaling-200-instances.json +201 -201
  17. package/docs/memory-data/scaling-2000-instances.json +107 -107
  18. package/docs/memory-data/scaling-50-instances.json +206 -206
  19. package/docs/memory-data/scaling-500-instances.json +108 -108
  20. package/docs/memory-data/scaling-5000-instances.json +49 -49
  21. package/docs/memory-overhead.svg +17 -17
  22. package/docs/memory.md +111 -111
  23. package/docs/package.json +35 -0
  24. package/docs/public/README.md +623 -0
  25. package/docs/public/TIMING_NODE_OPTIMIZATION.md +207 -0
  26. package/docs/public/examples/coordinates-example.ts +253 -0
  27. package/docs/public/examples/multi-level-keys.ts +374 -0
  28. package/docs/public/examples/registry-hub-coordinates-example.ts +370 -0
  29. package/docs/public/examples/registry-hub-types.ts +437 -0
  30. package/docs/public/examples/simple-example.ts +250 -0
  31. package/docs/public/examples-README.md +222 -0
  32. package/docs/public/fjell-icon.svg +1 -0
  33. package/docs/public/icon.png +0 -0
  34. package/docs/public/icon2.png +0 -0
  35. package/docs/public/memory-overhead.svg +120 -0
  36. package/docs/public/memory.md +430 -0
  37. package/docs/public/pano.png +0 -0
  38. package/docs/public/pano2.png +0 -0
  39. package/docs/public/timing-range.svg +176 -0
  40. package/docs/public/timing.md +483 -0
  41. package/docs/src/App.css +1175 -0
  42. package/docs/src/App.test.tsx +50 -0
  43. package/docs/src/App.tsx +583 -0
  44. package/docs/src/index.css +40 -0
  45. package/docs/src/main.tsx +10 -0
  46. package/docs/src/test/setup.ts +1 -0
  47. package/docs/timing-range.svg +41 -41
  48. package/docs/timing.md +101 -101
  49. package/docs/tsconfig.node.json +13 -0
  50. package/docs/vitest.config.ts +14 -0
  51. package/examples/README.md +35 -0
  52. package/examples/coordinates-example.ts +253 -0
  53. package/examples/registry-hub-coordinates-example.ts +370 -0
  54. package/package.json +2 -2
@@ -0,0 +1,623 @@
1
+ # Fjell Registry
2
+
3
+ A comprehensive dependency injection and service location system for the Fjell ecosystem. The Registry provides a centralized way to register, scope, and retrieve service instances based on type hierarchies and contextual scopes.
4
+
5
+ ## Core Concepts
6
+
7
+ ### Instance
8
+ An `Instance` represents any registered service or component in the system. It consists of:
9
+ - **Coordinate**: Defines the service's identity (key types + scopes)
10
+ - **Registry**: Reference to the registry managing this instance
11
+
12
+ ```typescript
13
+ interface Instance<S extends string, L1 extends string = never, ...> {
14
+ coordinate: Coordinate<S, L1, L2, L3, L4, L5>;
15
+ registry: Registry;
16
+ }
17
+ ```
18
+
19
+ ### Coordinate
20
+ A `Coordinate` uniquely identifies an instance using:
21
+ - **Key Type Array (KTA)**: Hierarchical type identifiers (e.g., `['User', 'Profile']`)
22
+ - **Scopes**: Context qualifiers (e.g., `['firestore']`, `['postgresql']`)
23
+
24
+ This allows multiple implementations of the same service:
25
+ ```typescript
26
+ // Same User service, different storage backends
27
+ const firestoreUser = createCoordinate(['User'], ['firestore']);
28
+ const postgresUser = createCoordinate(['User'], ['postgresql']);
29
+ ```
30
+
31
+ ### Registry
32
+ The central service locator that:
33
+ - **Has a mandatory type identifier** (e.g., 'services', 'data', 'cache')
34
+ - Creates and registers instances atomically (no circular dependencies)
35
+ - Retrieves instances by type and scope
36
+ - Maintains a hierarchical tree of services
37
+
38
+ ```typescript
39
+ interface Registry {
40
+ readonly type: string; // Mandatory type identifier
41
+ createInstance: <...>(...) => Instance<...>;
42
+ register: (...) => void; // Deprecated
43
+ get: (...) => Instance | null;
44
+ getCoordinates: () => Coordinate[]; // Discover all registered coordinates
45
+ instanceTree: InstanceTree;
46
+ }
47
+
48
+ // Create registries with their type
49
+ const serviceRegistry = createRegistry('services');
50
+ const dataRegistry = createRegistry('data');
51
+ const cacheRegistry = createRegistry('cache');
52
+ ```
53
+
54
+ ### RegistryHub
55
+ A higher-level registry that manages multiple Registry instances. The RegistryHub serves as a central hub where different registries can be organized automatically using their type property.
56
+
57
+ **Key Features:**
58
+ - **Automatic Registry Organization**: Registers registries using their built-in type property
59
+ - **Unified Access**: Single point of access to instances across all registries
60
+ - **Type Safety**: Maintains type safety while providing cross-registry access
61
+ - **Lifecycle Management**: Register, unregister, and manage multiple registries
62
+
63
+ ```typescript
64
+ interface RegistryHub {
65
+ registerRegistry: (registry: Registry) => void; // Uses registry.type automatically
66
+ get: (type: string, kta: string[], options?: { scopes?: string[] }) => Instance | null;
67
+ getRegistry: (type: string) => Registry | null;
68
+ getRegisteredTypes: () => string[];
69
+ getAllCoordinates: () => CoordinateWithRegistry[]; // Discover coordinates across all registries
70
+ unregisterRegistry: (type: string) => boolean;
71
+ }
72
+ ```
73
+
74
+ **Architecture:**
75
+ ```
76
+ RegistryHub
77
+ ├── Registry (type: 'services') → Auth, User, Payment services
78
+ ├── Registry (type: 'data') → Repositories, Data layers
79
+ ├── Registry (type: 'cache') → Cache implementations
80
+ └── Registry (type: 'integrations') → External APIs, webhooks
81
+ ```
82
+
83
+ ### InstanceFactory
84
+ A factory function that creates instances:
85
+ ```typescript
86
+ type InstanceFactory<S extends string, L1, L2, L3, L4, L5> = (
87
+ registry: Registry,
88
+ coordinate: Coordinate<S, L1, L2, L3, L4, L5>
89
+ ) => Instance<S, L1, L2, L3, L4, L5>;
90
+ ```
91
+
92
+ **Benefits:**
93
+ - ✅ No circular dependencies (factory receives populated registry + coordinate)
94
+ - ✅ Dependency injection friendly (factory can access other services)
95
+ - ✅ Atomic creation and registration
96
+ - ✅ Type-safe instance creation
97
+
98
+ ## Architecture
99
+
100
+ ```
101
+ createRegistry('services').createInstance(['User'], ['firestore'], factory)
102
+
103
+ 1. Creates Coordinate { kta: ['User'], scopes: ['firestore'] }
104
+ 2. Calls factory(registry, coordinate)
105
+ 3. Validates returned instance
106
+ 4. Registers instance automatically
107
+ 5. Returns ready-to-use instance
108
+ ```
109
+
110
+ **Registry Structure:**
111
+ ```
112
+ Registry (type: 'services')
113
+ ├── Instance Tree (by Key Types)
114
+ │ ├── User
115
+ │ │ ├── [ScopedInstance] scope: ['firestore'] ← Created via factory
116
+ │ │ └── [ScopedInstance] scope: ['postgresql'] ← Created via factory
117
+ │ └── User.Profile
118
+ │ ├── [ScopedInstance] scope: ['firestore']
119
+ │ └── [ScopedInstance] scope: ['postgresql']
120
+ └── Atomic Create+Register Logic
121
+ ```
122
+
123
+ **RegistryHub Structure:**
124
+ ```
125
+ RegistryHub
126
+ ├── Registry (type: 'services')
127
+ │ ├── User (multiple scopes)
128
+ │ ├── Auth (multiple scopes)
129
+ │ └── Payment (multiple scopes)
130
+ ├── Registry (type: 'data')
131
+ │ ├── UserRepository (multiple scopes)
132
+ │ └── OrderRepository (multiple scopes)
133
+ └── Registry (type: 'cache')
134
+ ├── UserCache (multiple scopes)
135
+ └── SessionCache (multiple scopes)
136
+ ```
137
+
138
+ ## Usage Patterns
139
+
140
+ ### 1. **Recommended: Registry-Managed Creation** ✅
141
+ ```typescript
142
+ const registry = createRegistry('services');
143
+
144
+ // Create and register instances atomically - no circular dependency!
145
+ const userService = registry.createInstance(['User'], ['firestore'], (registry, coordinate) => {
146
+ // Your instance implementation here
147
+ return {
148
+ coordinate,
149
+ registry,
150
+ // ... your service implementation
151
+ };
152
+ });
153
+
154
+ // Instance is automatically registered and ready to use
155
+ const retrievedService = registry.get(['User'], { scopes: ['firestore'] });
156
+ console.log(userService === retrievedService); // true
157
+ ```
158
+
159
+ ### 2. **RegistryHub: Managing Multiple Registries** ✅
160
+ ```typescript
161
+ const hub = createRegistryHub();
162
+
163
+ // Create domain-specific registries with their types
164
+ const serviceRegistry = createRegistry('services');
165
+ const dataRegistry = createRegistry('data');
166
+ const cacheRegistry = createRegistry('cache');
167
+
168
+ // Register registries in the hub - no type parameter needed!
169
+ hub.registerRegistry(serviceRegistry); // Uses 'services' from registry.type
170
+ hub.registerRegistry(dataRegistry); // Uses 'data' from registry.type
171
+ hub.registerRegistry(cacheRegistry); // Uses 'cache' from registry.type
172
+
173
+ // Create instances in specific registries
174
+ const authService = serviceRegistry.createInstance(['Auth'], ['jwt'], authFactory);
175
+ const userRepo = dataRegistry.createInstance(['User'], ['firestore'], repoFactory);
176
+ const userCache = cacheRegistry.createInstance(['User'], ['redis'], cacheFactory);
177
+
178
+ // Access instances through the hub - unified interface
179
+ const auth = hub.get('services', ['Auth'], { scopes: ['jwt'] });
180
+ const user = hub.get('data', ['User'], { scopes: ['firestore'] });
181
+ const cache = hub.get('cache', ['User'], { scopes: ['redis'] });
182
+
183
+ // Hub management
184
+ console.log(hub.getRegisteredTypes()); // ['services', 'data', 'cache']
185
+ const specificRegistry = hub.getRegistry('services');
186
+ hub.unregisterRegistry('cache'); // Remove if needed
187
+ ```
188
+
189
+ ### 2a. **RegistryHub: Cross-Registry Coordinate Discovery** ✅
190
+ ```typescript
191
+ // Discover all coordinates across ALL registries in the hub
192
+ const allCoordinates = hub.getAllCoordinates();
193
+ console.log(`Found ${allCoordinates.length} total services`);
194
+
195
+ // Each coordinate includes its registry type
196
+ allCoordinates.forEach(({ coordinate, registryType }) => {
197
+ console.log(`${registryType}: ${coordinate.kta.join('.')} [${coordinate.scopes.join(', ')}]`);
198
+ });
199
+
200
+ // Group coordinates by registry type for analysis
201
+ const byRegistry = allCoordinates.reduce((acc, item) => {
202
+ if (!acc[item.registryType]) acc[item.registryType] = [];
203
+ acc[item.registryType].push(item.coordinate);
204
+ return acc;
205
+ }, {} as Record<string, Coordinate[]>);
206
+
207
+ // Environment-based analysis across all registries
208
+ const productionServices = allCoordinates.filter(c =>
209
+ c.coordinate.scopes.includes('production')
210
+ );
211
+ const productionByRegistry = productionServices.reduce((acc, c) => {
212
+ acc[c.registryType] = (acc[c.registryType] || 0) + 1;
213
+ return acc;
214
+ }, {} as Record<string, number>);
215
+
216
+ console.log('Production services by registry:', productionByRegistry);
217
+ // Output: { services: 2, data: 3, cache: 1 }
218
+ ```
219
+
220
+ **Use Cases for hub.getAllCoordinates():**
221
+ - **System-Wide Health Monitoring**: Check services across all registry domains
222
+ - **Architecture Analysis**: Understand service distribution across domains
223
+ - **Environment Validation**: Ensure complete deployment across all registry types
224
+ - **Cross-Registry Dependencies**: Map service relationships between domains
225
+ - **Documentation Generation**: Auto-generate complete system catalogs
226
+
227
+ ### 3. Multiple Implementations with Scopes
228
+ ```typescript
229
+ const registry = createRegistry('data');
230
+
231
+ // Firestore implementation
232
+ const firestoreUser = registry.createInstance(['User'], ['firestore'], (registry, coordinate) => ({
233
+ coordinate,
234
+ registry,
235
+ save: async (user) => { /* firestore logic */ },
236
+ find: async (query) => { /* firestore logic */ }
237
+ }));
238
+
239
+ // PostgreSQL implementation
240
+ const postgresUser = registry.createInstance(['User'], ['postgresql'], (registry, coordinate) => ({
241
+ coordinate,
242
+ registry,
243
+ save: async (user) => { /* postgresql logic */ },
244
+ find: async (query) => { /* postgresql logic */ }
245
+ }));
246
+
247
+ // Context-aware retrieval
248
+ const prodService = registry.get(['User'], { scopes: ['firestore'] });
249
+ const devService = registry.get(['User'], { scopes: ['postgresql'] });
250
+ ```
251
+
252
+ ### 4. Hierarchical Services
253
+ ```typescript
254
+ const registry = createRegistry('services');
255
+
256
+ // Register nested services
257
+ const profileService = registry.createInstance(['User', 'Profile'], ['firestore'], factoryFunction);
258
+ const settingsService = registry.createInstance(['User', 'Settings'], ['postgresql'], factoryFunction);
259
+
260
+ // Retrieve nested services
261
+ const userProfile = registry.get(['User', 'Profile'], { scopes: ['firestore'] });
262
+ ```
263
+
264
+ ### 5. **Cross-Registry Dependencies with RegistryHub**
265
+ ```typescript
266
+ const hub = createRegistryHub();
267
+ const serviceRegistry = createRegistry('services');
268
+ const dataRegistry = createRegistry('data');
269
+
270
+ // Registries automatically use their type property
271
+ hub.registerRegistry(serviceRegistry); // → 'services'
272
+ hub.registerRegistry(dataRegistry); // → 'data'
273
+
274
+ // Service that depends on data layer
275
+ const orderService = serviceRegistry.createInstance(['Order'], ['business'], (registry, coordinate) => {
276
+ // Access data layer through hub
277
+ const userRepo = hub.get('data', ['User'], { scopes: ['firestore'] });
278
+ const orderRepo = hub.get('data', ['Order'], { scopes: ['firestore'] });
279
+
280
+ return {
281
+ coordinate,
282
+ registry,
283
+ createOrder: async (orderData) => {
284
+ const user = await userRepo.operations.findOne(orderData.userId);
285
+ return orderRepo.operations.create({ ...orderData, user });
286
+ }
287
+ };
288
+ });
289
+ ```
290
+
291
+ ### 6. ~~Legacy Registration~~ (Deprecated)
292
+ ```typescript
293
+ // OLD WAY - has circular dependency issue
294
+ const registry = createRegistry('legacy');
295
+ const userService = createInstance(registry, createCoordinate(['User'], ['firestore'])); // ❌ Circular!
296
+ registry.register(['User'], userService, { scopes: ['firestore'] });
297
+
298
+ // Use registry.createInstance() instead! ✅
299
+ ```
300
+
301
+ ### 7. Coordinate Discovery with getCoordinates()
302
+ The Registry provides introspection capabilities to discover all registered instances:
303
+ ```typescript
304
+ const registry = createRegistry('services');
305
+
306
+ // Register various services
307
+ registry.createInstance(['User'], ['firestore'], userFirestoreFactory);
308
+ registry.createInstance(['User'], ['postgresql'], userPostgresFactory);
309
+ registry.createInstance(['Cache', 'Redis'], ['production'], redisFactory);
310
+ registry.createInstance(['Cache', 'Memory'], ['development'], memoryFactory);
311
+
312
+ // Discover all registered coordinates
313
+ const coordinates = registry.getCoordinates();
314
+ console.log(`Found ${coordinates.length} registered services`);
315
+
316
+ // Analyze registration patterns
317
+ coordinates.forEach(coord => {
318
+ console.log(`Service: ${coord.kta.join('.')} | Scopes: ${coord.scopes.join(', ')}`);
319
+ });
320
+
321
+ // Group by environment for health checks
322
+ const productionServices = coordinates.filter(c => c.scopes.includes('production'));
323
+ const developmentServices = coordinates.filter(c => c.scopes.includes('development'));
324
+
325
+ // Service discovery - find all cache implementations
326
+ const cacheServices = coordinates.filter(c => c.kta.includes('Cache'));
327
+ ```
328
+
329
+ **Use Cases for getCoordinates():**
330
+ - **Health Monitoring**: Verify all expected services are registered
331
+ - **Development Tools**: Debug service registration in development
332
+ - **Service Discovery**: Find available implementations at runtime
333
+ - **Environment Validation**: Ensure proper scope configuration
334
+ - **Documentation Generation**: Auto-generate service catalogs
335
+
336
+ ### 8. Cascade Pattern
337
+ The Registry enables automatic service discovery:
338
+ ```typescript
339
+ // System receives an item and automatically finds the right service
340
+ function saveItem(item: Item) {
341
+ const registry = createRegistry('services');
342
+ const service = registry.get(item.getKeyTypes(), {
343
+ scopes: ['cache', 'fast']
344
+ }) || registry.get(item.getKeyTypes(), {
345
+ scopes: ['database']
346
+ });
347
+
348
+ return service.operations.save(item);
349
+ }
350
+ ```
351
+
352
+ ## RegistryHub Patterns
353
+
354
+ ### 1. **Domain-Driven Registry Organization**
355
+ ```typescript
356
+ const hub = createRegistryHub();
357
+
358
+ // Domain registries with explicit types
359
+ const userDomainRegistry = createRegistry('user-domain');
360
+ const orderDomainRegistry = createRegistry('order-domain');
361
+ const paymentDomainRegistry = createRegistry('payment-domain');
362
+ const notificationDomainRegistry = createRegistry('notification-domain');
363
+
364
+ // Register using their built-in types
365
+ hub.registerRegistry(userDomainRegistry); // → 'user-domain'
366
+ hub.registerRegistry(orderDomainRegistry); // → 'order-domain'
367
+ hub.registerRegistry(paymentDomainRegistry); // → 'payment-domain'
368
+ hub.registerRegistry(notificationDomainRegistry); // → 'notification-domain'
369
+
370
+ // Each domain manages its own services
371
+ const userService = hub.get('user-domain', ['User'], { scopes: ['api'] });
372
+ const orderService = hub.get('order-domain', ['Order'], { scopes: ['business'] });
373
+ const paymentGateway = hub.get('payment-domain', ['Gateway'], { scopes: ['stripe'] });
374
+ ```
375
+
376
+ ### 2. **Environment-Based Registry Management**
377
+ ```typescript
378
+ const hub = createRegistryHub();
379
+
380
+ if (process.env.NODE_ENV === 'production') {
381
+ const prodDataRegistry = createRegistry('data');
382
+ const redisRegistry = createRegistry('cache');
383
+ hub.registerRegistry(prodDataRegistry);
384
+ hub.registerRegistry(redisRegistry);
385
+ } else {
386
+ const devDataRegistry = createRegistry('data');
387
+ const memoryRegistry = createRegistry('cache');
388
+ hub.registerRegistry(devDataRegistry);
389
+ hub.registerRegistry(memoryRegistry);
390
+ }
391
+
392
+ // Same code works across environments
393
+ const userRepo = hub.get('data', ['User']);
394
+ const userCache = hub.get('cache', ['User']);
395
+ ```
396
+
397
+ ### 3. **Module-Based Registry Organization**
398
+ ```typescript
399
+ // Each module/library provides its own typed registry
400
+ import { createUserModuleRegistry } from '@myapp/user-module';
401
+ import { createOrderModuleRegistry } from '@myapp/order-module';
402
+ import { createPaymentModuleRegistry } from '@myapp/payment-module';
403
+
404
+ const hub = createRegistryHub();
405
+
406
+ // These functions return registries with proper types
407
+ const userRegistry = createUserModuleRegistry(); // Registry with type 'users'
408
+ const orderRegistry = createOrderModuleRegistry(); // Registry with type 'orders'
409
+ const paymentRegistry = createPaymentModuleRegistry(); // Registry with type 'payments'
410
+
411
+ // Auto-register using their types
412
+ hub.registerRegistry(userRegistry); // → 'users'
413
+ hub.registerRegistry(orderRegistry); // → 'orders'
414
+ hub.registerRegistry(paymentRegistry); // → 'payments'
415
+
416
+ // Cross-module integration
417
+ const orderService = hub.get('orders', ['OrderService']);
418
+ const paymentProcessor = hub.get('payments', ['Processor'], { scopes: ['stripe'] });
419
+ ```
420
+
421
+ ## Library Integration Patterns
422
+
423
+ ### fjell-lib Integration
424
+ ```typescript
425
+ // In fjell-lib
426
+ export const createServiceRegistry = () => createRegistry('fjell-lib');
427
+
428
+ // In applications
429
+ import { createServiceRegistry } from '@fjell/lib';
430
+ const hub = createRegistryHub();
431
+ hub.registerRegistry(createServiceRegistry()); // → 'fjell-lib'
432
+ ```
433
+
434
+ ### fjell-cache Integration
435
+ ```typescript
436
+ // In fjell-cache
437
+ export const createCacheRegistry = () => createRegistry('fjell-cache');
438
+
439
+ // In applications
440
+ import { createCacheRegistry } from '@fjell/cache';
441
+ const hub = createRegistryHub();
442
+ hub.registerRegistry(createCacheRegistry()); // → 'fjell-cache'
443
+ ```
444
+
445
+ ### fjell-client-api Integration
446
+ ```typescript
447
+ // In fjell-client-api
448
+ export const createClientApiRegistry = () => createRegistry('fjell-client-api');
449
+
450
+ // In applications
451
+ import { createClientApiRegistry } from '@fjell/client-api';
452
+ const hub = createRegistryHub();
453
+ hub.registerRegistry(createClientApiRegistry()); // → 'fjell-client-api'
454
+ ```
455
+
456
+ ## Design Benefits
457
+
458
+ 1. **Unified Service Location**: Single pattern across all Fjell libraries
459
+ 2. **Multiple Implementations**: Support Firestore, PostgreSQL, etc. for same types
460
+ 3. **Contextual Scoping**: Environment-aware service selection
461
+ 4. **Hierarchical Organization**: Natural type hierarchy support
462
+ 5. **Dependency Injection**: Clean separation of configuration and usage
463
+ 6. **Service Introspection**: Discover all registered coordinates with `getCoordinates()`
464
+ 7. **Cross-Registry Discovery**: System-wide coordinate discovery with `getAllCoordinates()`
465
+ 8. **Self-Documenting Registries**: Registry type is built-in, no external tracking needed
466
+ 9. **Cross-Registry Access**: Unified interface for accessing instances across multiple registries
467
+ 10. **Error Prevention**: Impossible to register a registry under the wrong type
468
+
469
+ ## Migration Strategy
470
+
471
+ ### Phase 1: Core Libraries
472
+ - ✅ fjell-registry (base implementation + RegistryHub with typed registries)
473
+ - 🔄 fjell-lib (create registry with type 'fjell-lib')
474
+ - 🔄 fjell-lib-sequelize (create registry with type 'fjell-lib-sequelize')
475
+ - 🔄 fjell-lib-firestore (create registry with type 'fjell-lib-firestore')
476
+
477
+ ### Phase 2: Service Libraries
478
+ - 🔄 fjell-cache (create registry with type 'fjell-cache')
479
+ - 🔄 fjell-client-api (create registry with type 'fjell-client-api')
480
+
481
+ ### Phase 3: UI Libraries (Future)
482
+ - fjell-express-router (create registry with type 'fjell-express-router')
483
+ - fjell-providers (create registry with type 'fjell-providers')
484
+
485
+ ### Phase 4: RegistryHub Integration
486
+ - Applications use RegistryHub to organize all typed registries
487
+ - Libraries export factory functions that create properly typed registries
488
+ - Cross-module dependency management through hub
489
+
490
+ ## Configuration Examples
491
+
492
+ ### Multi-Database Setup with RegistryHub
493
+ ```typescript
494
+ const hub = createRegistryHub();
495
+
496
+ // Create typed registries
497
+ const servicesRegistry = createRegistry('services');
498
+ const firestoreDataRegistry = createRegistry('firestore-data');
499
+ const postgresDataRegistry = createRegistry('postgres-data');
500
+
501
+ // Register Firestore services
502
+ firestoreDataRegistry.createInstance(['User'], ['production'], firestoreUserFactory);
503
+ firestoreDataRegistry.createInstance(['Order'], ['production'], firestoreOrderFactory);
504
+
505
+ // Register PostgreSQL services
506
+ postgresDataRegistry.createInstance(['User'], ['development'], postgresUserFactory);
507
+ postgresDataRegistry.createInstance(['Analytics'], [], postgresAnalyticsFactory);
508
+
509
+ // Register business services
510
+ servicesRegistry.createInstance(['UserService'], ['business'], userServiceFactory);
511
+ servicesRegistry.createInstance(['OrderService'], ['business'], orderServiceFactory);
512
+
513
+ // Register all typed registries
514
+ hub.registerRegistry(servicesRegistry); // → 'services'
515
+ hub.registerRegistry(firestoreDataRegistry); // → 'firestore-data'
516
+ hub.registerRegistry(postgresDataRegistry); // → 'postgres-data'
517
+
518
+ // Context-aware retrieval through hub
519
+ const userService = hub.get('services', ['UserService']);
520
+ const userRepo = hub.get('firestore-data', ['User'], { scopes: ['production'] });
521
+ const analyticsRepo = hub.get('postgres-data', ['Analytics']);
522
+ ```
523
+
524
+ ### Service Composition with RegistryHub
525
+ ```typescript
526
+ const hub = createRegistryHub();
527
+
528
+ // Create and register typed registries
529
+ const dataRegistry = createRegistry('data');
530
+ const servicesRegistry = createRegistry('services');
531
+ const integrationsRegistry = createRegistry('integrations');
532
+
533
+ hub.registerRegistry(dataRegistry); // → 'data'
534
+ hub.registerRegistry(servicesRegistry); // → 'services'
535
+ hub.registerRegistry(integrationsRegistry); // → 'integrations'
536
+
537
+ // Complex service with cross-registry dependencies
538
+ const orderService = servicesRegistry.createInstance(['Order'], ['business'], (registry, coordinate) => {
539
+ return {
540
+ coordinate,
541
+ registry,
542
+ createOrder: async (orderData) => {
543
+ const userRepo = hub.get('data', ['User']);
544
+ const paymentService = hub.get('integrations', ['Payment']);
545
+ const inventoryService = hub.get('services', ['Inventory']);
546
+
547
+ // Business logic using services from different typed registries
548
+ const user = await userRepo.operations.findOne(orderData.userId);
549
+ const payment = await paymentService.processPayment(orderData.payment);
550
+ const inventory = await inventoryService.reserveItems(orderData.items);
551
+
552
+ return { user, payment, inventory };
553
+ }
554
+ };
555
+ });
556
+ ```
557
+
558
+ This architecture provides the foundation for a scalable, maintainable service ecosystem where components can be developed independently but work together seamlessly. The RegistryHub with typed registries extends this capability by enabling better organization and automatic management of multiple registries across different domains or modules.
559
+
560
+ ## Memory Profiling and Performance
561
+
562
+ ### Memory Overhead Testing
563
+
564
+ The Fjell Registry includes comprehensive memory profiling to ensure optimal performance in production environments. The memory tests measure the actual memory footprint of core infrastructure components and provide automated documentation.
565
+
566
+ #### Running Memory Tests
567
+
568
+ ```bash
569
+ # Run memory tests and generate documentation
570
+ pnpm run test:memory
571
+ ```
572
+
573
+ #### Memory Test Coverage
574
+
575
+ The memory tests analyze:
576
+
577
+ - **Registry Infrastructure**: Memory overhead of creating Registry and RegistryHub instances
578
+ - **Instance Creation**: Memory cost per instance including coordinates and storage
579
+ - **Tree Structure**: Memory efficiency of the instance tree data structures
580
+ - **Scoped Instances**: Additional memory overhead for scoped instance management
581
+ - **Scaling Behavior**: Memory usage from 10 to 100,000 instances with detailed scaling analysis
582
+
583
+ #### Comprehensive Scaling Tests
584
+
585
+ Memory tests include scaling analysis across multiple instance counts:
586
+
587
+ - **Small Scale**: 10, 20, 50, 100, 200 instances
588
+ - **Medium Scale**: 500, 1,000, 2,000, 5,000 instances
589
+ - **Large Scale**: 10,000, 20,000, 50,000, 100,000 instances
590
+
591
+ #### Memory Constraints
592
+
593
+ Current memory constraints ensure optimal performance:
594
+
595
+ - **Registry Creation**: ≤ 83 kB per registry
596
+ - **Instance Creation**: ≤ 2.4 kB per instance
597
+ - **Coordinate Objects**: ≤ 1.5 kB per coordinate
598
+ - **Tree Nodes**: ≤ 3.9 kB per tree node
599
+ - **Complex Instances**: ≤ 4.9 kB for multi-level instances
600
+
601
+ #### Generated Documentation
602
+
603
+ Memory tests automatically generate `./docs/memory.md` with:
604
+
605
+ - Detailed memory usage analysis with human-readable units (kB, MB)
606
+ - Comprehensive scaling analysis from 10 to 100,000 instances
607
+ - Performance characteristics and scaling efficiency metrics
608
+ - Memory growth patterns and per-instance consistency analysis
609
+ - Efficiency metrics and optimization recommendations
610
+ - Troubleshooting guide for memory issues
611
+ - Constraint definitions and thresholds
612
+
613
+ #### Key Performance Characteristics
614
+
615
+ - **Linear Scaling**: Memory usage scales predictably from 10 to 100,000 instances
616
+ - **Consistent Per-Instance Cost**: ~1.9-2.4 kB per instance across all scales
617
+ - **Efficient Storage**: Optimized tree structures minimize overhead
618
+ - **High-Volume Performance**: 100,000 instances use only ~189 MB (excellent memory efficiency)
619
+ - **Scope Efficiency**: Minimal additional memory for scoped instances
620
+ - **Fast Creation**: Instance creation remains fast even at large scales
621
+ - **Human-Readable Reporting**: All memory measurements displayed in kB/MB format
622
+
623
+ Use these metrics to monitor memory usage in production and ensure the registry infrastructure remains performant as your application scales from prototype to enterprise levels.