@fjell/registry 4.4.7 → 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 +1 -1
@@ -0,0 +1,222 @@
1
+ # Registry Examples
2
+
3
+ This directory contains examples demonstrating how to use the Registry with different key patterns and configurations.
4
+
5
+ ## Examples
6
+
7
+ ### 1. `simple-example.ts` ⭐ **Start Here!**
8
+ **Perfect for beginners!** Demonstrates the simplest possible way to use the Registry:
9
+ - **No RegistryHub required** - just call `createRegistry()`
10
+ - **No scopes needed** - pass empty array `[]` or omit entirely
11
+ - **Basic dependency injection** - register and retrieve services
12
+ - **Service dependencies** - shows how services can depend on each other
13
+
14
+ Great for simple applications that just need basic dependency injection without complexity.
15
+
16
+ ### 2. `multi-level-keys.ts`
17
+ **Advanced usage with scopes and multi-level keys!** Demonstrates how Registry supports hierarchical key type arrays:
18
+ - **Single level**: `['user']`, `['task']` - SQL vs NoSQL implementations
19
+ - **Two levels**: `['user', 'profile']` - S3 vs Local storage implementations
20
+ - **Three levels**: `['user', 'profile', 'preference']` - Redis implementation
21
+ - **Real scopes**: Production vs development environments
22
+ - **Multiple implementations**: Same interface, different backends
23
+
24
+ Shows how each key path maps to different implementations via scopes using the real library.
25
+
26
+ ### 3. `registry-hub-types.ts` 🏗️ **Enterprise Architecture**
27
+ **Large-scale application with service organization!** Demonstrates how RegistryHub manages multiple registries for different service types:
28
+ - **Service Categories**: Business logic, data access, infrastructure, communication
29
+ - **Type-based Organization**: Services organized by purpose and responsibility
30
+ - **Cross-Registry Workflows**: Services from different registries working together
31
+ - **Environment Configuration**: Production vs development implementations
32
+ - **Centralized Discovery**: Single hub for all service types
33
+
34
+ Perfect for enterprise applications that need clean separation of concerns and organized service architecture.
35
+
36
+ ## Key Concepts Demonstrated
37
+
38
+ ### Simple Usage (simple-example.ts)
39
+ ```typescript
40
+ // Import the real registry functionality
41
+ import { createRegistry, createInstance } from '../src/Registry';
42
+
43
+ // Create a registry - no RegistryHub needed!
44
+ const registry = createRegistry('app');
45
+
46
+ // Register a service - no scopes needed!
47
+ registry.createInstance(['logger'], [], (coordinate, context) => {
48
+ const service = new LoggerService();
49
+ const instance = createInstance(context.registry, coordinate);
50
+ (instance as any).log = service.log.bind(service);
51
+ return instance;
52
+ });
53
+
54
+ // Get the service - no scopes needed!
55
+ const logger = registry.get(['logger']);
56
+ logger.log('Hello from the registry!');
57
+ ```
58
+
59
+ ### Multi-Level Key Arrays
60
+ ```typescript
61
+ // Different key path levels
62
+ ['user'] // → UserService implementation
63
+ ['user', 'profile'] // → UserProfileService implementation
64
+ ['user', 'profile', 'preference'] // → UserPreferenceService implementation
65
+ ['task'] // → TaskService implementation
66
+ ```
67
+
68
+ ### RegistryHub Usage (registry-hub-types.ts)
69
+ ```typescript
70
+ // Import RegistryHub functionality
71
+ import { createRegistryHub } from '../src/RegistryHub';
72
+ import { createRegistry } from '../src/Registry';
73
+
74
+ // Create a hub to manage multiple registries
75
+ const hub = createRegistryHub();
76
+
77
+ // Create specialized registries for different service types
78
+ const servicesRegistry = createRegistry('services'); // Business logic
79
+ const dataRegistry = createRegistry('data'); // Data access
80
+ const infraRegistry = createRegistry('infrastructure'); // Infrastructure
81
+ const commRegistry = createRegistry('communication'); // External services
82
+
83
+ // Register all registries in the hub
84
+ hub.registerRegistry(servicesRegistry);
85
+ hub.registerRegistry(dataRegistry);
86
+ hub.registerRegistry(infraRegistry);
87
+ hub.registerRegistry(commRegistry);
88
+
89
+ // Register services by type and scope
90
+ servicesRegistry.createInstance(['auth'], ['prod'], (coordinate, context) => {
91
+ // JWT implementation for production
92
+ });
93
+
94
+ dataRegistry.createInstance(['user'], ['sql'], (coordinate, context) => {
95
+ // PostgreSQL implementation
96
+ });
97
+
98
+ // Retrieve services by type and scope through the hub
99
+ const prodAuth = hub.get('services', ['auth'], { scopes: ['prod'] });
100
+ const sqlUser = hub.get('data', ['user'], { scopes: ['sql'] });
101
+ const cache = hub.get('infrastructure', ['cache'], { scopes: ['dev'] });
102
+ const email = hub.get('communication', ['email'], { scopes: ['prod'] });
103
+ ```
104
+
105
+ ### Scope-Based Implementation Selection
106
+ - Multiple implementations per key path
107
+ - Runtime selection via scopes
108
+ - Environment-based switching (prod/dev/test)
109
+ - Feature flags and A/B testing support
110
+
111
+ ### Real-World Use Cases
112
+ - **Database Abstraction**: Different implementations for PostgreSQL, MongoDB, etc.
113
+ - **Environment Selection**: Different implementations for prod/dev
114
+ - **Testing**: Mock implementations with 'test' scope
115
+ - **Microservices**: Each key path represents a different service
116
+ - **Multi-Region**: Different implementations across regions
117
+
118
+ ## Using the Registry
119
+
120
+ The registry provides a centralized way to manage instances in your application. Here are the main operations you can perform:
121
+
122
+ ### Getting All Coordinates
123
+
124
+ You can retrieve a list of all coordinates currently registered in the registry:
125
+
126
+ ```typescript
127
+ import { createRegistry } from '@fjell/registry';
128
+
129
+ const registry = createRegistry('myRegistry');
130
+
131
+ // Register some instances...
132
+ registry.createInstance(['service'], ['production'], factory1);
133
+ registry.createInstance(['cache', 'redis'], ['development'], factory2);
134
+
135
+ // Get all coordinates
136
+ const coordinates = registry.getCoordinates();
137
+ console.log(`Found ${coordinates.length} registered coordinates:`);
138
+ coordinates.forEach(coord => {
139
+ console.log(`- ${coord.toString()}`);
140
+ });
141
+ ```
142
+
143
+ This is useful for debugging, monitoring, or implementing discovery mechanisms in your application.
144
+
145
+ ### Basic Instance Management
146
+
147
+ ## Running Examples
148
+
149
+ ```bash
150
+ # Start with the simple example (recommended)
151
+ npx tsx examples/simple-example.ts
152
+
153
+ # Run the multi-level keys example
154
+ npx tsx examples/multi-level-keys.ts
155
+
156
+ # Run the RegistryHub with service types example
157
+ npx tsx examples/registry-hub-types.ts
158
+
159
+ # Run the coordinate discovery and introspection example
160
+ npx tsx examples/coordinates-example.ts
161
+
162
+ # Run the RegistryHub cross-registry coordinate discovery example
163
+ npx tsx examples/registry-hub-coordinates-example.ts
164
+
165
+ # Or in Node.js
166
+ node -r esbuild-register examples/simple-example.ts
167
+ node -r esbuild-register examples/registry-hub-types.ts
168
+ ```
169
+
170
+ ## Integration with Real Fjell Registry
171
+
172
+ Both examples now use the real library! In actual usage with the built package:
173
+
174
+ ```typescript
175
+ import { createRegistry, createInstance } from '@fjell/registry';
176
+
177
+ // Simple usage - no RegistryHub, no scopes
178
+ const registry = createRegistry('app');
179
+
180
+ registry.createInstance(['user'], [], (coordinate, context) => {
181
+ const service = new UserService();
182
+ const instance = createInstance(context.registry, coordinate);
183
+ (instance as any).save = service.save.bind(service);
184
+ return instance;
185
+ });
186
+
187
+ const user = registry.get(['user']);
188
+
189
+ // Advanced usage - with scopes for multiple implementations
190
+ registry.createInstance(['user'], ['sql', 'prod'], (coordinate, context) => {
191
+ const service = new SqlUserService();
192
+ const instance = createInstance(context.registry, coordinate);
193
+ (instance as any).save = service.save.bind(service);
194
+ return instance;
195
+ });
196
+
197
+ const prodUser = registry.get(['user'], { scopes: ['prod'] });
198
+ ```
199
+
200
+ ## When to Use What
201
+
202
+ **Use `simple-example.ts` approach when:**
203
+ - You're just getting started
204
+ - You have a simple application
205
+ - You don't need multiple implementations per service
206
+ - You want basic dependency injection
207
+
208
+ **Use `multi-level-keys.ts` approach when:**
209
+ - You need multiple implementations (prod/dev/test)
210
+ - You have complex service hierarchies
211
+ - You need environment-based switching
212
+ - You're building a large, complex application
213
+
214
+ **Use `registry-hub-types.ts` approach when:**
215
+ - You're building enterprise-scale applications
216
+ - You need to organize services by type/category
217
+ - You have multiple teams working on different service layers
218
+ - You want clean separation between business logic, data, and infrastructure
219
+ - You need centralized service discovery across service types
220
+ - You're implementing microservices or modular architecture
221
+
222
+ This approach provides the foundation for the Fjell library's architecture pattern with swappable implementations and enterprise-scale service organization.
@@ -0,0 +1 @@
1
+
Binary file
Binary file
@@ -0,0 +1,120 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="1200" height="800" xmlns="http://www.w3.org/2000/svg">
3
+ <style>
4
+ .axis { stroke: #333; stroke-width: 1; }
5
+ .grid { stroke: #ddd; stroke-width: 0.5; }
6
+ .label { font-family: Arial, sans-serif; font-size: 14px; fill: #333; }
7
+ .title { font-family: Arial, sans-serif; font-size: 16px; font-weight: bold; fill: #333; }
8
+ .subtitle { font-family: Arial, sans-serif; font-size: 12px; fill: #666; }
9
+ .per-instance { stroke: #3498db; stroke-width: 3; fill: none; }
10
+ .per-instance-dot { fill: #3498db; }
11
+ .legend { font-family: Arial, sans-serif; font-size: 12px; fill: #333; }
12
+ .axis-title { font-family: Arial, sans-serif; font-size: 16px; font-weight: bold; fill: #333; }
13
+ .metadata-section { font-family: Arial, sans-serif; font-size: 14px; font-weight: bold; fill: #444; }
14
+ .metadata-label { font-family: Arial, sans-serif; font-size: 10px; fill: #666; }
15
+ .metadata-value { font-family: Arial, sans-serif; font-size: 10px; fill: #333; }
16
+ </style>
17
+
18
+ <!-- Background -->
19
+ <rect width="1200" height="800" fill="white"/>
20
+
21
+ <!-- Title -->
22
+ <text x="600" y="25" text-anchor="middle" class="title">Memory Efficiency Per Instance</text>
23
+ <text x="600" y="45" text-anchor="middle" class="subtitle">Average memory overhead per registry instance across different scale sizes</text>
24
+
25
+ <!-- Plot area -->
26
+ <g transform="translate(110,60)">
27
+
28
+ <!-- Grid lines (Y-axis - memory in KB) -->
29
+ <line x1="0" y1="355.57592837740003" x2="990" y2="355.57592837740003" class="grid"/>
30
+ <text x="-10" y="359.57592837740003" text-anchor="end" class="label">2KB</text>
31
+ <line x1="0" y1="153.13821696732998" x2="990" y2="153.13821696732998" class="grid"/>
32
+ <text x="-10" y="157.13821696732998" text-anchor="end" class="label">5KB</text>
33
+ <line x1="0" y1="0" x2="990" y2="0" class="grid"/>
34
+ <text x="-10" y="4" text-anchor="end" class="label">10KB</text>
35
+ <line x1="0" y1="0" x2="0" y2="460" class="grid"/>
36
+ <text x="0" y="480" text-anchor="middle" class="label">10</text>
37
+ <line x1="99.33989856911381" y1="0" x2="99.33989856911381" y2="460" class="grid"/>
38
+ <text x="99.33989856911381" y="480" text-anchor="middle" class="label">20</text>
39
+ <line x1="230.6601014308862" y1="0" x2="230.6601014308862" y2="460" class="grid"/>
40
+ <text x="230.6601014308862" y="480" text-anchor="middle" class="label">50</text>
41
+ <line x1="330" y1="0" x2="330" y2="460" class="grid"/>
42
+ <text x="330" y="480" text-anchor="middle" class="label">100</text>
43
+ <line x1="429.3398985691138" y1="0" x2="429.3398985691138" y2="460" class="grid"/>
44
+ <text x="429.3398985691138" y="480" text-anchor="middle" class="label">200</text>
45
+ <line x1="560.6601014308862" y1="0" x2="560.6601014308862" y2="460" class="grid"/>
46
+ <text x="560.6601014308862" y="480" text-anchor="middle" class="label">500</text>
47
+ <line x1="660" y1="0" x2="660" y2="460" class="grid"/>
48
+ <text x="660" y="480" text-anchor="middle" class="label">1k</text>
49
+ <line x1="759.3398985691139" y1="0" x2="759.3398985691139" y2="460" class="grid"/>
50
+ <text x="759.3398985691139" y="480" text-anchor="middle" class="label">2k</text>
51
+ <line x1="890.6601014308862" y1="0" x2="890.6601014308862" y2="460" class="grid"/>
52
+ <text x="890.6601014308862" y="480" text-anchor="middle" class="label">5k</text>
53
+ <line x1="990" y1="0" x2="990" y2="460" class="grid"/>
54
+ <text x="990" y="480" text-anchor="middle" class="label">10k</text>
55
+ <!-- Y-axis -->
56
+ <line x1="0" y1="0" x2="0" y2="460" class="axis"/>
57
+
58
+ <!-- X-axis -->
59
+ <line x1="0" y1="460" x2="990" y2="460" class="axis"/>
60
+
61
+ <!-- Axis labels -->
62
+ <text x="495" y="510" text-anchor="middle" class="axis-title">Instance Count - Log Scale</text>
63
+ <text transform="rotate(-90,-70,230)" x="-70" y="230" text-anchor="middle" class="axis-title">Memory Usage (KB)</text>
64
+ <path d="M 0 240.70120928043835 L 99.33989856911381 282.22270579627764 L 230.6601014308862 327.2110056876071 L 330 354.03530806378257 L 429.3398985691138 346.21437843228813 L 560.6601014308862 360.1862852477646 L 660 352.43697251573866 L 759.3398985691139 365.33853358657484 L 890.6601014308862 349.28769665195966 L 990 410.70050555725993" class="per-instance"/>
65
+ <circle cx="0" cy="240.70120928043835" r="4" class="per-instance-dot"/>
66
+ <circle cx="99.33989856911381" cy="282.22270579627764" r="4" class="per-instance-dot"/>
67
+ <circle cx="230.6601014308862" cy="327.2110056876071" r="4" class="per-instance-dot"/>
68
+ <circle cx="330" cy="354.03530806378257" r="4" class="per-instance-dot"/>
69
+ <circle cx="429.3398985691138" cy="346.21437843228813" r="4" class="per-instance-dot"/>
70
+ <circle cx="560.6601014308862" cy="360.1862852477646" r="4" class="per-instance-dot"/>
71
+ <circle cx="660" cy="352.43697251573866" r="4" class="per-instance-dot"/>
72
+ <circle cx="759.3398985691139" cy="365.33853358657484" r="4" class="per-instance-dot"/>
73
+ <circle cx="890.6601014308862" cy="349.28769665195966" r="4" class="per-instance-dot"/>
74
+ <circle cx="990" cy="410.70050555725993" r="4" class="per-instance-dot"/>
75
+ <!-- Legend -->
76
+ <g transform="translate(20, 20)">
77
+ <rect x="0" y="0" width="190" height="60" fill="white" stroke="#ccc" stroke-width="1"/>
78
+
79
+ <!-- Memory Per Instance Legend -->
80
+ <text x="10" y="20" class="legend" font-weight="bold">Memory Per Instance</text>
81
+ <line x1="10" y1="30" x2="40" y2="30" class="per-instance"/>
82
+ <circle cx="25" cy="30" r="3" class="per-instance-dot"/>
83
+ <text x="45" y="34" class="legend">Average Performance</text>
84
+ </g>
85
+
86
+ </g>
87
+
88
+ <!-- Test Metadata Section - match timing chart layout exactly -->
89
+ <g transform="translate(50, 620)">
90
+ <!-- Left Column: System Information -->
91
+ <g transform="translate(20, 20)">
92
+ <text x="0" y="0" class="metadata-section">System Information</text>
93
+
94
+ <text x="0" y="25" class="metadata-label">Test Date:</text>
95
+ <text x="150" y="25" class="metadata-value">2025-07-21</text>
96
+
97
+ <text x="0" y="45" class="metadata-label">Package Version:</text>
98
+ <text x="150" y="45" class="metadata-value">@fjell/registry v4.4.7</text>
99
+
100
+ <text x="0" y="65" class="metadata-label">Node.js Version:</text>
101
+ <text x="150" y="65" class="metadata-value">v22.0.0 (darwin arm64)</text>
102
+
103
+ <text x="0" y="85" class="metadata-label">Platform:</text>
104
+ <text x="150" y="85" class="metadata-value">darwin arm64</text>
105
+
106
+ <text x="0" y="105" class="metadata-label">Compiler:</text>
107
+ <text x="150" y="105" class="metadata-value">TypeScript + Vite</text>
108
+ </g>
109
+
110
+ <!-- Right Column: Test Notes -->
111
+ <g transform="translate(400, 20)">
112
+ <text x="0" y="0" class="metadata-section">Test Notes</text>
113
+ <text x="0" y="25" class="metadata-label">• Memory measurements use Node.js process.memoryUsage() with heap precision</text>
114
+ <text x="0" y="42" class="metadata-label">• Each test includes garbage collection to minimize measurement variance</text>
115
+ <text x="0" y="59" class="metadata-label">• Logging is mocked during memory tests to eliminate overhead</text>
116
+ <text x="0" y="76" class="metadata-label">• Tests verify memory efficiency and consistency across instance counts</text>
117
+ <text x="0" y="93" class="metadata-label">• Statistical analysis ensures reliable performance measurements</text>
118
+ </g>
119
+ </g>
120
+ </svg>