@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,370 @@
1
+ /**
2
+ * RegistryHub Coordinates Discovery Example
3
+ *
4
+ * This example demonstrates how to use the getAllCoordinates() method on RegistryHub to:
5
+ * - Discover all registered instances across multiple registries
6
+ * - See which registry type contains each coordinate
7
+ * - Analyze cross-registry service architecture
8
+ * - Implement system-wide monitoring and discovery
9
+ * - Validate service deployment across different domains
10
+ *
11
+ * Run this example with: npx tsx examples/registry-hub-coordinates-example.ts
12
+ *
13
+ * Note: In a real application, import from the built package:
14
+ * import { createRegistryHub, createRegistry, createInstance } from '@fjell/registry';
15
+ */
16
+
17
+ // Import the actual registry functionality
18
+ import { createRegistryHub } from '../src/RegistryHub';
19
+ import { createRegistry } from '../src/Registry';
20
+ import { createInstance } from '../src/Instance';
21
+
22
+ // ===== Service Examples =====
23
+
24
+ class AuthService {
25
+ constructor(private provider: string, private environment: string) { }
26
+
27
+ authenticate(token: string) { // eslint-disable-line @typescript-eslint/no-unused-vars
28
+ console.log(`Authenticating with ${this.provider} in ${this.environment}`);
29
+ return { userId: 'user123', provider: this.provider };
30
+ }
31
+
32
+ getInfo() {
33
+ return `${this.provider} Auth (${this.environment})`;
34
+ }
35
+ }
36
+
37
+ class DataRepository {
38
+ constructor(private database: string, private table: string) { }
39
+
40
+ save(data: any) {
41
+ console.log(`Saving to ${this.database}.${this.table}:`, data);
42
+ return { id: 'saved123', database: this.database };
43
+ }
44
+
45
+ getInfo() {
46
+ return `${this.database} Repository for ${this.table}`;
47
+ }
48
+ }
49
+
50
+ class CacheStore {
51
+ constructor(private type: string, private ttl: number) { }
52
+
53
+ set(key: string, value: any) { // eslint-disable-line @typescript-eslint/no-unused-vars
54
+ console.log(`Caching ${key} in ${this.type} for ${this.ttl}s`);
55
+ return { cached: true, type: this.type };
56
+ }
57
+
58
+ getInfo() {
59
+ return `${this.type} Cache (TTL: ${this.ttl}s)`;
60
+ }
61
+ }
62
+
63
+ class IntegrationService {
64
+ constructor(private provider: string, private version: string) { }
65
+
66
+ call(endpoint: string, data: any) { // eslint-disable-line @typescript-eslint/no-unused-vars
67
+ console.log(`Calling ${this.provider} v${this.version} at ${endpoint}`);
68
+ return { success: true, provider: this.provider };
69
+ }
70
+
71
+ getInfo() {
72
+ return `${this.provider} Integration v${this.version}`;
73
+ }
74
+ }
75
+
76
+ // ===== Main Example =====
77
+
78
+ async function runRegistryHubCoordinatesExample() {
79
+ console.log('🌐 RegistryHub Coordinates Discovery Example\n');
80
+
81
+ // Step 1: Create RegistryHub and multiple registries
82
+ console.log('1. Creating RegistryHub and domain-specific registries...');
83
+ const hub = createRegistryHub();
84
+
85
+ const authRegistry = createRegistry('auth');
86
+ const dataRegistry = createRegistry('data');
87
+ const cacheRegistry = createRegistry('cache');
88
+ const integrationsRegistry = createRegistry('integrations');
89
+
90
+ console.log(' ✅ RegistryHub created');
91
+ console.log(' ✅ 4 domain registries created\n');
92
+
93
+ // Step 2: Register all registries in the hub
94
+ console.log('2. Registering registries in the hub...');
95
+ hub.registerRegistry(authRegistry);
96
+ hub.registerRegistry(dataRegistry);
97
+ hub.registerRegistry(cacheRegistry);
98
+ hub.registerRegistry(integrationsRegistry);
99
+
100
+ console.log(' ✅ All registries registered in hub');
101
+ console.log(` 📊 Registered registry types: ${hub.getRegisteredTypes().join(', ')}\n`);
102
+
103
+ // Step 3: Create instances across different registries and environments
104
+ console.log('3. Creating instances across multiple registries and environments...\n');
105
+
106
+ // Auth Registry - Different authentication providers
107
+ authRegistry.createInstance(
108
+ ['Auth', 'JWT'],
109
+ ['production', 'oauth'],
110
+ (coordinate, context) => {
111
+ const service = new AuthService('JWT', 'production');
112
+ const instance = createInstance(context.registry, coordinate);
113
+ (instance as any).authenticate = service.authenticate.bind(service);
114
+ (instance as any).getInfo = service.getInfo.bind(service);
115
+ return instance;
116
+ }
117
+ );
118
+ console.log(' ✅ JWT Auth (production) registered in auth registry');
119
+
120
+ authRegistry.createInstance(
121
+ ['Auth', 'SAML'],
122
+ ['production', 'enterprise'],
123
+ (coordinate, context) => {
124
+ const service = new AuthService('SAML', 'production');
125
+ const instance = createInstance(context.registry, coordinate);
126
+ (instance as any).authenticate = service.authenticate.bind(service);
127
+ (instance as any).getInfo = service.getInfo.bind(service);
128
+ return instance;
129
+ }
130
+ );
131
+ console.log(' ✅ SAML Auth (production) registered in auth registry');
132
+
133
+ authRegistry.createInstance(
134
+ ['Auth', 'Local'],
135
+ ['development', 'testing'],
136
+ (coordinate, context) => {
137
+ const service = new AuthService('Local', 'development');
138
+ const instance = createInstance(context.registry, coordinate);
139
+ (instance as any).authenticate = service.authenticate.bind(service);
140
+ (instance as any).getInfo = service.getInfo.bind(service);
141
+ return instance;
142
+ }
143
+ );
144
+ console.log(' ✅ Local Auth (development) registered in auth registry');
145
+
146
+ // Data Registry - Different databases and entities
147
+ dataRegistry.createInstance(
148
+ ['Repository', 'User'],
149
+ ['production', 'firestore'],
150
+ (coordinate, context) => {
151
+ const repo = new DataRepository('Firestore', 'users');
152
+ const instance = createInstance(context.registry, coordinate);
153
+ (instance as any).save = repo.save.bind(repo);
154
+ (instance as any).getInfo = repo.getInfo.bind(repo);
155
+ return instance;
156
+ }
157
+ );
158
+ console.log(' ✅ User Repository (Firestore/production) registered in data registry');
159
+
160
+ dataRegistry.createInstance(
161
+ ['Repository', 'User'],
162
+ ['development', 'postgresql'],
163
+ (coordinate, context) => {
164
+ const repo = new DataRepository('PostgreSQL', 'users');
165
+ const instance = createInstance(context.registry, coordinate);
166
+ (instance as any).save = repo.save.bind(repo);
167
+ (instance as any).getInfo = repo.getInfo.bind(repo);
168
+ return instance;
169
+ }
170
+ );
171
+ console.log(' ✅ User Repository (PostgreSQL/development) registered in data registry');
172
+
173
+ dataRegistry.createInstance(
174
+ ['Repository', 'Order'],
175
+ ['production', 'firestore'],
176
+ (coordinate, context) => {
177
+ const repo = new DataRepository('Firestore', 'orders');
178
+ const instance = createInstance(context.registry, coordinate);
179
+ (instance as any).save = repo.save.bind(repo);
180
+ (instance as any).getInfo = repo.getInfo.bind(repo);
181
+ return instance;
182
+ }
183
+ );
184
+ console.log(' ✅ Order Repository (Firestore/production) registered in data registry');
185
+
186
+ // Cache Registry - Different cache implementations
187
+ cacheRegistry.createInstance(
188
+ ['Cache', 'Session'],
189
+ ['production', 'redis'],
190
+ (coordinate, context) => {
191
+ const cache = new CacheStore('Redis', 3600);
192
+ const instance = createInstance(context.registry, coordinate);
193
+ (instance as any).set = cache.set.bind(cache);
194
+ (instance as any).getInfo = cache.getInfo.bind(cache);
195
+ return instance;
196
+ }
197
+ );
198
+ console.log(' ✅ Session Cache (Redis/production) registered in cache registry');
199
+
200
+ cacheRegistry.createInstance(
201
+ ['Cache', 'Query'],
202
+ ['production', 'memcached'],
203
+ (coordinate, context) => {
204
+ const cache = new CacheStore('Memcached', 1800);
205
+ const instance = createInstance(context.registry, coordinate);
206
+ (instance as any).set = cache.set.bind(cache);
207
+ (instance as any).getInfo = cache.getInfo.bind(cache);
208
+ return instance;
209
+ }
210
+ );
211
+ console.log(' ✅ Query Cache (Memcached/production) registered in cache registry');
212
+
213
+ cacheRegistry.createInstance(
214
+ ['Cache', 'Memory'],
215
+ ['development', 'local'],
216
+ (coordinate, context) => {
217
+ const cache = new CacheStore('In-Memory', 300);
218
+ const instance = createInstance(context.registry, coordinate);
219
+ (instance as any).set = cache.set.bind(cache);
220
+ (instance as any).getInfo = cache.getInfo.bind(cache);
221
+ return instance;
222
+ }
223
+ );
224
+ console.log(' ✅ Memory Cache (local/development) registered in cache registry');
225
+
226
+ // Integrations Registry - External service integrations
227
+ integrationsRegistry.createInstance(
228
+ ['Payment', 'Stripe'],
229
+ ['production', 'live'],
230
+ (coordinate, context) => {
231
+ const integration = new IntegrationService('Stripe', '2023-10');
232
+ const instance = createInstance(context.registry, coordinate);
233
+ (instance as any).call = integration.call.bind(integration);
234
+ (instance as any).getInfo = integration.getInfo.bind(integration);
235
+ return instance;
236
+ }
237
+ );
238
+ console.log(' ✅ Stripe Payment (production) registered in integrations registry');
239
+
240
+ integrationsRegistry.createInstance(
241
+ ['Email', 'SendGrid'],
242
+ ['production', 'v3'],
243
+ (coordinate, context) => {
244
+ const integration = new IntegrationService('SendGrid', '3.0');
245
+ const instance = createInstance(context.registry, coordinate);
246
+ (instance as any).call = integration.call.bind(integration);
247
+ (instance as any).getInfo = integration.getInfo.bind(integration);
248
+ return instance;
249
+ }
250
+ );
251
+ console.log(' ✅ SendGrid Email (production) registered in integrations registry');
252
+
253
+ // Step 4: Demonstrate getAllCoordinates functionality
254
+ console.log('\n4. Discovering all coordinates across the entire system...\n');
255
+
256
+ const allCoordinates = hub.getAllCoordinates();
257
+ console.log(`🔍 Total coordinates discovered: ${allCoordinates.length}`);
258
+ console.log(`📦 Across ${hub.getRegisteredTypes().length} registry types\n`);
259
+
260
+ // Display all coordinates grouped by registry type
261
+ console.log('📍 All Registered Coordinates by Registry Type:');
262
+ console.log('═'.repeat(80));
263
+
264
+ const coordinatesByRegistry = allCoordinates.reduce((acc, item) => {
265
+ if (!acc[item.registryType]) acc[item.registryType] = [];
266
+ acc[item.registryType].push(item);
267
+ return acc;
268
+ }, {} as Record<string, typeof allCoordinates>);
269
+
270
+ Object.entries(coordinatesByRegistry).forEach(([registryType, coords]) => {
271
+ console.log(`\n📋 ${registryType.toUpperCase()} REGISTRY (${coords.length} instances):`);
272
+ console.log('─'.repeat(60));
273
+ coords.forEach((item, index) => {
274
+ const coord = item.coordinate;
275
+ console.log(` ${index + 1}. ${coord.kta.join(' → ')}`);
276
+ console.log(` Scopes: ${coord.scopes.length > 0 ? coord.scopes.join(', ') : 'none'}`);
277
+ console.log(` Full: ${coord.toString()}`);
278
+ console.log('');
279
+ });
280
+ });
281
+
282
+ // Step 5: Demonstrate cross-registry analysis
283
+ console.log('5. Cross-Registry Architecture Analysis...\n');
284
+
285
+ // Environment analysis
286
+ const environments = ['production', 'development', 'testing'];
287
+ console.log('🌍 Environment Distribution:');
288
+ environments.forEach(env => {
289
+ const envCoords = allCoordinates.filter(c => c.coordinate.scopes.includes(env));
290
+ console.log(` ${env}: ${envCoords.length} service(s) across ${new Set(envCoords.map(c => c.registryType)).size} registry type(s)`);
291
+
292
+ const registryBreakdown = envCoords.reduce((acc, c) => {
293
+ acc[c.registryType] = (acc[c.registryType] || 0) + 1;
294
+ return acc;
295
+ }, {} as Record<string, number>);
296
+
297
+ Object.entries(registryBreakdown).forEach(([regType, count]) => {
298
+ console.log(` - ${regType}: ${count}`);
299
+ });
300
+ });
301
+
302
+ // Service type analysis
303
+ console.log('\n🔧 Service Architecture Overview:');
304
+ const serviceTypes = [...new Set(allCoordinates.map(c => c.coordinate.kta[0]))];
305
+ serviceTypes.forEach(serviceType => {
306
+ const serviceCoords = allCoordinates.filter(c => c.coordinate.kta[0] === serviceType);
307
+ const registries = [...new Set(serviceCoords.map(c => c.registryType))];
308
+ console.log(` ${serviceType}: ${serviceCoords.length} implementation(s) in ${registries.join(', ')} registr${registries.length === 1 ? 'y' : 'ies'}`);
309
+ });
310
+
311
+ // Step 6: Demonstrate practical usage scenarios
312
+ console.log('\n6. Practical Usage Scenarios...\n');
313
+
314
+ // Scenario 1: System health check
315
+ console.log('🏥 System Health Check:');
316
+ const criticalServices = ['Auth', 'Repository', 'Cache', 'Payment'];
317
+ criticalServices.forEach(service => {
318
+ const implementations = allCoordinates.filter(c => c.coordinate.kta.includes(service));
319
+ const status = implementations.length > 0 ? '✅ Available' : '❌ Missing';
320
+ const details = implementations.length > 0 ? `(${implementations.length} implementation(s))` : '';
321
+ console.log(` ${service}: ${status} ${details}`);
322
+ });
323
+
324
+ // Scenario 2: Production readiness check
325
+ console.log('\n🚀 Production Readiness Check:');
326
+ const productionCoords = allCoordinates.filter(c => c.coordinate.scopes.includes('production'));
327
+ const productionByRegistry = productionCoords.reduce((acc, c) => {
328
+ acc[c.registryType] = (acc[c.registryType] || 0) + 1;
329
+ return acc;
330
+ }, {} as Record<string, number>);
331
+
332
+ console.log(` Total production services: ${productionCoords.length}`);
333
+ Object.entries(productionByRegistry).forEach(([regType, count]) => {
334
+ console.log(` - ${regType}: ${count} production service(s)`);
335
+ });
336
+
337
+ // Scenario 3: Development environment completeness
338
+ console.log('\n💻 Development Environment Check:');
339
+ const devCoords = allCoordinates.filter(c => c.coordinate.scopes.includes('development'));
340
+ console.log(` Development services available: ${devCoords.length}`);
341
+
342
+ // Check if we have dev equivalents for production services
343
+ const prodServiceKeys = productionCoords.map(c => c.coordinate.kta.join('.'));
344
+ const devServiceKeys = devCoords.map(c => c.coordinate.kta.join('.'));
345
+
346
+ const missingDevServices = prodServiceKeys.filter(key => !devServiceKeys.includes(key));
347
+ if (missingDevServices.length > 0) {
348
+ console.log(' ⚠️ Missing development equivalents for:');
349
+ missingDevServices.forEach(service => console.log(` - ${service}`));
350
+ } else {
351
+ console.log(' ✅ All production services have development equivalents');
352
+ }
353
+
354
+ console.log('\n✨ RegistryHub coordinates discovery example completed!');
355
+
356
+ return {
357
+ totalCoordinates: allCoordinates.length,
358
+ coordinatesByRegistry,
359
+ registryTypes: hub.getRegisteredTypes(),
360
+ allCoordinates
361
+ };
362
+ }
363
+
364
+ // Export for testing
365
+ export { runRegistryHubCoordinatesExample };
366
+
367
+ // Run the example if this file is executed directly
368
+ if (import.meta.url === `file://${process.argv[1]}`) {
369
+ runRegistryHubCoordinatesExample().catch(console.error);
370
+ }