@memberjunction/react-runtime 2.111.0 → 2.112.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.
Files changed (43) hide show
  1. package/.turbo/turbo-build.log +10 -11
  2. package/CHANGELOG.md +6 -6
  3. package/dist/compiler/component-compiler.d.ts.map +1 -1
  4. package/dist/compiler/component-compiler.js +66 -56
  5. package/dist/compiler/component-compiler.js.map +1 -1
  6. package/dist/component-manager/component-manager.d.ts.map +1 -1
  7. package/dist/component-manager/component-manager.js +48 -42
  8. package/dist/component-manager/component-manager.js.map +1 -1
  9. package/dist/component-manager/types.d.ts +1 -1
  10. package/dist/component-manager/types.d.ts.map +1 -1
  11. package/dist/component-manager/types.js.map +1 -1
  12. package/dist/registry/component-registry-service.d.ts +1 -1
  13. package/dist/registry/component-registry-service.d.ts.map +1 -1
  14. package/dist/registry/component-registry-service.js +34 -34
  15. package/dist/registry/component-registry-service.js.map +1 -1
  16. package/dist/registry/component-resolver.d.ts +1 -1
  17. package/dist/registry/component-resolver.d.ts.map +1 -1
  18. package/dist/registry/component-resolver.js +10 -11
  19. package/dist/registry/component-resolver.js.map +1 -1
  20. package/dist/runtime/component-hierarchy.d.ts +1 -1
  21. package/dist/runtime/component-hierarchy.d.ts.map +1 -1
  22. package/dist/runtime/component-hierarchy.js +43 -43
  23. package/dist/runtime/component-hierarchy.js.map +1 -1
  24. package/dist/runtime/prop-builder.d.ts.map +1 -1
  25. package/dist/runtime/prop-builder.js +22 -24
  26. package/dist/runtime/prop-builder.js.map +1 -1
  27. package/dist/runtime.umd.js +494 -511
  28. package/dist/types/index.d.ts.map +1 -1
  29. package/dist/types/index.js.map +1 -1
  30. package/dist/utilities/library-registry.d.ts +1 -1
  31. package/dist/utilities/library-registry.d.ts.map +1 -1
  32. package/dist/utilities/library-registry.js +10 -10
  33. package/dist/utilities/library-registry.js.map +1 -1
  34. package/package.json +5 -6
  35. package/src/compiler/component-compiler.ts +186 -164
  36. package/src/component-manager/component-manager.ts +162 -216
  37. package/src/component-manager/types.ts +27 -27
  38. package/src/registry/component-registry-service.ts +190 -218
  39. package/src/registry/component-resolver.ts +87 -98
  40. package/src/runtime/component-hierarchy.ts +57 -94
  41. package/src/runtime/prop-builder.ts +28 -33
  42. package/src/types/index.ts +3 -4
  43. package/src/utilities/library-registry.ts +14 -19
@@ -9,7 +9,7 @@ import { ComponentRegistryService } from './component-registry-service';
9
9
  import { ComponentSpec } from '@memberjunction/interactive-component-types';
10
10
  import { ComponentCompiler } from '../compiler';
11
11
  import { RuntimeContext } from '../types';
12
- import { UserInfo } from '@memberjunction/core';
12
+ import { UserInfo } from '@memberjunction/global';
13
13
  import { ComponentMetadataEngine } from '@memberjunction/core-entities';
14
14
 
15
15
  /**
@@ -39,16 +39,11 @@ export class ComponentResolver {
39
39
  * @param runtimeContext - Optional runtime context for registry-based components
40
40
  * @param debug - Enable debug logging (defaults to false)
41
41
  */
42
- constructor(
43
- registry: ComponentRegistry,
44
- compiler?: ComponentCompiler,
45
- runtimeContext?: RuntimeContext,
46
- debug: boolean = false
47
- ) {
42
+ constructor(registry: ComponentRegistry, compiler?: ComponentCompiler, runtimeContext?: RuntimeContext, debug: boolean = false) {
48
43
  this.registry = registry;
49
44
  this.resolverInstanceId = `resolver-${Date.now()}-${Math.random()}`;
50
45
  this.debug = debug;
51
-
46
+
52
47
  if (compiler && runtimeContext) {
53
48
  this.compiler = compiler;
54
49
  this.runtimeContext = runtimeContext;
@@ -63,11 +58,7 @@ export class ComponentResolver {
63
58
  * @param contextUser - Optional user context for database operations
64
59
  * @returns Map of component names to resolved components
65
60
  */
66
- async resolveComponents(
67
- spec: ComponentSpec,
68
- namespace: string = 'Global',
69
- contextUser?: UserInfo
70
- ): Promise<ResolvedComponents> {
61
+ async resolveComponents(spec: ComponentSpec, namespace: string = 'Global', contextUser?: UserInfo): Promise<ResolvedComponents> {
71
62
  console.log(`🚀 [ComponentResolver] Starting component resolution for: ${spec.name}`);
72
63
  console.log(`📋 [ComponentResolver] Root component spec:`, {
73
64
  name: spec.name,
@@ -75,19 +66,22 @@ export class ComponentResolver {
75
66
  registry: spec.registry,
76
67
  namespace: spec.namespace,
77
68
  hasCode: !!spec.code,
78
- hasDependencies: !!(spec.dependencies && spec.dependencies.length > 0)
69
+ hasDependencies: !!(spec.dependencies && spec.dependencies.length > 0),
79
70
  });
80
-
71
+
81
72
  if (this.debug) {
82
- console.log(`📋 [ComponentResolver] Dependencies to resolve:`, (spec.dependencies || []).map(d => ({
83
- name: d.name,
84
- location: d.location,
85
- namespace: d.namespace
86
- })));
73
+ console.log(
74
+ `📋 [ComponentResolver] Dependencies to resolve:`,
75
+ (spec.dependencies || []).map((d) => ({
76
+ name: d.name,
77
+ location: d.location,
78
+ namespace: d.namespace,
79
+ }))
80
+ );
87
81
  }
88
-
82
+
89
83
  const resolved: ResolvedComponents = {};
90
-
84
+
91
85
  // Initialize component engine if we have registry service
92
86
  if (this.registryService) {
93
87
  if (this.debug) {
@@ -98,22 +92,22 @@ export class ComponentResolver {
98
92
  console.log(`✅ [ComponentResolver] Component engine initialized with ${this.componentEngine.Components?.length || 0} components`);
99
93
  }
100
94
  }
101
-
95
+
102
96
  // Resolve the component hierarchy
103
97
  console.log(`🔄 [ComponentResolver] About to call resolveComponentHierarchy for root: ${spec.name}`);
104
98
  await this.resolveComponentHierarchy(spec, resolved, namespace, new Set(), contextUser);
105
99
  console.log(`✅ [ComponentResolver] Returned from resolveComponentHierarchy`);
106
100
  console.log(`🔍 [ComponentResolver] Looking for root component '${spec.name}' in resolved:`, !!resolved[spec.name]);
107
-
101
+
108
102
  if (!resolved[spec.name]) {
109
103
  console.error(`❌ [ComponentResolver] Root component '${spec.name}' was NOT added to resolved map!`);
110
104
  console.log(`📦 [ComponentResolver] What IS in resolved map:`, Object.keys(resolved));
111
105
  }
112
-
106
+
113
107
  if (this.debug) {
114
108
  console.log(`📊 [ComponentResolver] Resolved components before unwrapping:`, Object.keys(resolved));
115
109
  }
116
-
110
+
117
111
  // Unwrap component wrappers before returning
118
112
  // Components from the registry come as objects with component/print/refresh properties
119
113
  // We need to extract just the component function for use in child components
@@ -143,15 +137,18 @@ export class ComponentResolver {
143
137
  unwrapped[name] = value; // Pass through for debugging
144
138
  }
145
139
  }
146
-
140
+
147
141
  if (this.debug) {
148
- console.log(`🎯 [ComponentResolver] Final resolved components:`, Object.keys(unwrapped).map(name => ({
149
- name,
150
- type: typeof unwrapped[name],
151
- isUndefined: unwrapped[name] === undefined
152
- })));
142
+ console.log(
143
+ `🎯 [ComponentResolver] Final resolved components:`,
144
+ Object.keys(unwrapped).map((name) => ({
145
+ name,
146
+ type: typeof unwrapped[name],
147
+ isUndefined: unwrapped[name] === undefined,
148
+ }))
149
+ );
153
150
  }
154
-
151
+
155
152
  return unwrapped;
156
153
  }
157
154
 
@@ -172,7 +169,7 @@ export class ComponentResolver {
172
169
  ): Promise<void> {
173
170
  // Create a unique identifier for this component
174
171
  const componentId = `${spec.namespace || namespace}/${spec.name}@${spec.version || 'latest'}`;
175
-
172
+
176
173
  // Check if already resolved (not just visited)
177
174
  if (resolved[spec.name]) {
178
175
  if (this.debug) {
@@ -180,7 +177,7 @@ export class ComponentResolver {
180
177
  }
181
178
  return;
182
179
  }
183
-
180
+
184
181
  // Prevent circular dependencies
185
182
  if (visited.has(componentId)) {
186
183
  if (this.debug) {
@@ -217,7 +214,7 @@ export class ComponentResolver {
217
214
  console.log(` 📍 [ComponentResolver] Local registry (no registry field specified)`);
218
215
  }
219
216
  }
220
-
217
+
221
218
  try {
222
219
  // If spec.registry is populated, this is an external registry component
223
220
  // If spec.registry is blank/undefined, this is a local registry component
@@ -226,17 +223,17 @@ export class ComponentResolver {
226
223
  if (this.debug) {
227
224
  console.log(`🌐 [ComponentResolver] Fetching from external registry: ${spec.registry}`);
228
225
  }
229
-
226
+
230
227
  // Get compiled component from registry service (which will handle the external fetch)
231
228
  const compiledComponent = await this.registryService.getCompiledComponentFromRegistry(
232
- spec.registry, // Registry name
229
+ spec.registry, // Registry name
233
230
  spec.namespace || namespace,
234
231
  spec.name,
235
232
  spec.version || 'latest',
236
233
  this.resolverInstanceId,
237
234
  contextUser
238
235
  );
239
-
236
+
240
237
  if (compiledComponent) {
241
238
  resolved[spec.name] = compiledComponent;
242
239
  if (this.debug) {
@@ -250,54 +247,54 @@ export class ComponentResolver {
250
247
  if (this.debug) {
251
248
  console.log(`💾 [ComponentResolver] Looking for locally registered component`);
252
249
  }
253
-
250
+
254
251
  // First, try to find the component in the metadata engine
255
252
  const allComponents = this.componentEngine.Components || [];
256
253
  if (this.debug) {
257
254
  console.log(`📊 [ComponentResolver] Total components in engine: ${allComponents.length}`);
258
255
  }
259
-
256
+
260
257
  // Log all matching names to see duplicates
261
258
  const matchingNames = allComponents.filter((c: any) => c.Name === spec.name);
262
259
  if (matchingNames.length > 0 && this.debug) {
263
- console.log(`🔎 [ComponentResolver] Found ${matchingNames.length} components with name "${spec.name}":`,
260
+ console.log(
261
+ `🔎 [ComponentResolver] Found ${matchingNames.length} components with name "${spec.name}":`,
264
262
  matchingNames.map((c: any) => ({
265
263
  ID: c.ID,
266
264
  Name: c.Name,
267
265
  Namespace: c.Namespace,
268
266
  Version: c.Version,
269
- Status: c.Status
267
+ Status: c.Status,
270
268
  }))
271
269
  );
272
270
  }
273
-
271
+
274
272
  const component = this.componentEngine.Components?.find(
275
- (c: any) => c.Name === spec.name &&
276
- c.Namespace === (spec.namespace || namespace)
273
+ (c: any) => c.Name === spec.name && c.Namespace === (spec.namespace || namespace)
277
274
  );
278
-
275
+
279
276
  if (component) {
280
277
  if (this.debug) {
281
278
  console.log(`✅ [ComponentResolver] Found component in local DB:`, {
282
279
  ID: component.ID,
283
280
  Name: component.Name,
284
281
  Namespace: component.Namespace,
285
- Version: component.Version
282
+ Version: component.Version,
286
283
  });
287
284
  }
288
-
285
+
289
286
  // Get compiled component from registry service (local compilation)
290
- const compiledComponent = await this.registryService.getCompiledComponent(
291
- component.ID,
292
- this.resolverInstanceId,
293
- contextUser
294
- );
287
+ const compiledComponent = await this.registryService.getCompiledComponent(component.ID, this.resolverInstanceId, contextUser);
295
288
  resolved[spec.name] = compiledComponent;
296
289
  if (this.debug) {
297
- console.log(`📦 [ComponentResolver] Successfully compiled and resolved local component: ${spec.name}, type: ${typeof compiledComponent}`);
290
+ console.log(
291
+ `📦 [ComponentResolver] Successfully compiled and resolved local component: ${spec.name}, type: ${typeof compiledComponent}`
292
+ );
298
293
  }
299
294
  } else {
300
- console.error(`❌ [ComponentResolver] Local registry component NOT found in database: ${spec.name} with namespace: ${spec.namespace || namespace}`);
295
+ console.error(
296
+ `❌ [ComponentResolver] Local registry component NOT found in database: ${spec.name} with namespace: ${spec.namespace || namespace}`
297
+ );
301
298
  if (this.debug) {
302
299
  console.warn(`Local registry component not found in database: ${spec.name}`);
303
300
  }
@@ -312,13 +309,13 @@ export class ComponentResolver {
312
309
  // Embedded/Local component
313
310
  // Use the component's specified namespace if it has one, otherwise use parent's namespace
314
311
  const componentNamespace = spec.namespace || namespace;
315
-
312
+
316
313
  // First check if component has inline code that needs compilation
317
314
  if (spec.code && this.compiler) {
318
315
  if (this.debug) {
319
316
  console.log(`🔨 [ComponentResolver] Component ${spec.name} has inline code, compiling...`);
320
317
  }
321
-
318
+
322
319
  try {
323
320
  // Compile the component with its code
324
321
  const compilationResult = await this.compiler.compile({
@@ -326,9 +323,9 @@ export class ComponentResolver {
326
323
  componentCode: spec.code,
327
324
  libraries: spec.libraries,
328
325
  dependencies: spec.dependencies,
329
- allLibraries: [] // TODO: Get from ComponentMetadataEngine if needed
326
+ allLibraries: [], // TODO: Get from ComponentMetadataEngine if needed
330
327
  });
331
-
328
+
332
329
  if (compilationResult.success && compilationResult.component) {
333
330
  // Get the component object from the factory (only if we have runtimeContext)
334
331
  if (!this.runtimeContext) {
@@ -336,13 +333,13 @@ export class ComponentResolver {
336
333
  return;
337
334
  }
338
335
  const componentObject = compilationResult.component.factory(this.runtimeContext);
339
-
336
+
340
337
  // Register it in the local registry for future use
341
338
  this.registry.register(spec.name, componentObject, componentNamespace, spec.version || 'latest');
342
-
339
+
343
340
  // Add to resolved
344
341
  resolved[spec.name] = componentObject;
345
-
342
+
346
343
  if (this.debug) {
347
344
  console.log(`✅ [ComponentResolver] Successfully compiled and registered inline component: ${spec.name}`);
348
345
  }
@@ -357,7 +354,7 @@ export class ComponentResolver {
357
354
  if (this.debug) {
358
355
  console.log(`🔍 [ComponentResolver] Looking for embedded component: ${spec.name} in namespace: ${componentNamespace}`);
359
356
  }
360
-
357
+
361
358
  const component = this.registry.get(spec.name, componentNamespace);
362
359
  if (component) {
363
360
  resolved[spec.name] = component;
@@ -376,14 +373,21 @@ export class ComponentResolver {
376
373
  if (fallbackComponent) {
377
374
  resolved[spec.name] = fallbackComponent;
378
375
  if (this.debug) {
379
- console.log(`✅ [ComponentResolver] Found embedded component in fallback namespace: ${spec.name}, type: ${typeof fallbackComponent}`);
376
+ console.log(
377
+ `✅ [ComponentResolver] Found embedded component in fallback namespace: ${spec.name}, type: ${typeof fallbackComponent}`
378
+ );
380
379
  }
381
380
  if (this.debug) {
382
- console.log(`📄 Resolved embedded component: ${spec.name} from fallback namespace ${namespace}, type:`, typeof fallbackComponent);
381
+ console.log(
382
+ `📄 Resolved embedded component: ${spec.name} from fallback namespace ${namespace}, type:`,
383
+ typeof fallbackComponent
384
+ );
383
385
  }
384
386
  } else {
385
387
  // Component not found - this might cause issues later
386
- console.error(`❌ [ComponentResolver] Could not resolve embedded component: ${spec.name} in namespace ${componentNamespace} or ${namespace}`);
388
+ console.error(
389
+ `❌ [ComponentResolver] Could not resolve embedded component: ${spec.name} in namespace ${componentNamespace} or ${namespace}`
390
+ );
387
391
  if (this.debug) {
388
392
  console.warn(`⚠️ Could not resolve embedded component: ${spec.name} in namespace ${componentNamespace} or ${namespace}`);
389
393
  }
@@ -393,7 +397,7 @@ export class ComponentResolver {
393
397
  }
394
398
  }
395
399
  }
396
-
400
+
397
401
  // Child components have already been processed at the beginning of this method
398
402
  // No need to process them again - we're using depth-first, post-order traversal
399
403
  }
@@ -421,9 +425,9 @@ export class ComponentResolver {
421
425
  validateDependencies(spec: ComponentSpec, namespace: string = 'Global'): string[] {
422
426
  const missing: string[] = [];
423
427
  const checked = new Set<string>();
424
-
428
+
425
429
  this.checkDependencies(spec, namespace, missing, checked);
426
-
430
+
427
431
  return missing;
428
432
  }
429
433
 
@@ -434,12 +438,7 @@ export class ComponentResolver {
434
438
  * @param missing - Array to collect missing components
435
439
  * @param checked - Set of already checked components
436
440
  */
437
- private checkDependencies(
438
- spec: ComponentSpec,
439
- namespace: string,
440
- missing: string[],
441
- checked: Set<string>
442
- ): void {
441
+ private checkDependencies(spec: ComponentSpec, namespace: string, missing: string[], checked: Set<string>): void {
443
442
  if (checked.has(spec.name)) return;
444
443
  checked.add(spec.name);
445
444
 
@@ -463,9 +462,9 @@ export class ComponentResolver {
463
462
  getDependencyGraph(spec: ComponentSpec): Map<string, string[]> {
464
463
  const graph = new Map<string, string[]>();
465
464
  const visited = new Set<string>();
466
-
465
+
467
466
  this.buildDependencyGraph(spec, graph, visited);
468
-
467
+
469
468
  return graph;
470
469
  }
471
470
 
@@ -475,17 +474,13 @@ export class ComponentResolver {
475
474
  * @param graph - Graph to build
476
475
  * @param visited - Set of visited components
477
476
  */
478
- private buildDependencyGraph(
479
- spec: ComponentSpec,
480
- graph: Map<string, string[]>,
481
- visited: Set<string>
482
- ): void {
477
+ private buildDependencyGraph(spec: ComponentSpec, graph: Map<string, string[]>, visited: Set<string>): void {
483
478
  if (visited.has(spec.name)) return;
484
479
  visited.add(spec.name);
485
480
 
486
481
  const children = spec.dependencies || [];
487
- const dependencies = children.map(child => child.name);
488
-
482
+ const dependencies = children.map((child) => child.name);
483
+
489
484
  graph.set(spec.name, dependencies);
490
485
 
491
486
  // Recursively process children
@@ -522,12 +517,7 @@ export class ComponentResolver {
522
517
  * @param visited - Set of visited nodes
523
518
  * @param stack - Result stack
524
519
  */
525
- private topologicalSortDFS(
526
- node: string,
527
- graph: Map<string, string[]>,
528
- visited: Set<string>,
529
- stack: string[]
530
- ): void {
520
+ private topologicalSortDFS(node: string, graph: Map<string, string[]>, visited: Set<string>, stack: string[]): void {
531
521
  visited.add(node);
532
522
 
533
523
  const dependencies = graph.get(node) || [];
@@ -546,7 +536,10 @@ export class ComponentResolver {
546
536
  * @param namespace - Namespace for resolution
547
537
  * @returns Ordered array of resolved components
548
538
  */
549
- resolveInOrder(spec: ComponentSpec, namespace: string = 'Global'): Array<{
539
+ resolveInOrder(
540
+ spec: ComponentSpec,
541
+ namespace: string = 'Global'
542
+ ): Array<{
550
543
  name: string;
551
544
  component: any;
552
545
  }> {
@@ -583,11 +576,7 @@ export class ComponentResolver {
583
576
  * @param collected - Array to collect specs
584
577
  * @param visited - Set of visited component names
585
578
  */
586
- private collectComponentSpecs(
587
- spec: ComponentSpec,
588
- collected: ComponentSpec[],
589
- visited: Set<string>
590
- ): void {
579
+ private collectComponentSpecs(spec: ComponentSpec, collected: ComponentSpec[], visited: Set<string>): void {
591
580
  if (visited.has(spec.name)) return;
592
581
  visited.add(spec.name);
593
582
 
@@ -598,4 +587,4 @@ export class ComponentResolver {
598
587
  this.collectComponentSpecs(child, collected, visited);
599
588
  }
600
589
  }
601
- }
590
+ }