@memberjunction/react-runtime 2.90.0 → 2.91.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 (83) hide show
  1. package/.turbo/turbo-build.log +29 -1
  2. package/CHANGELOG.md +15 -0
  3. package/dist/compiler/babel-config.js +1 -0
  4. package/dist/compiler/babel-config.js.map +1 -0
  5. package/dist/compiler/component-compiler.d.ts.map +1 -1
  6. package/dist/compiler/component-compiler.js +51 -6
  7. package/dist/compiler/component-compiler.js.map +1 -0
  8. package/dist/compiler/index.js +1 -0
  9. package/dist/compiler/index.js.map +1 -0
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +4 -4
  13. package/dist/index.js.map +1 -0
  14. package/dist/registry/component-registry.d.ts +1 -0
  15. package/dist/registry/component-registry.d.ts.map +1 -1
  16. package/dist/registry/component-registry.js +10 -0
  17. package/dist/registry/component-registry.js.map +1 -0
  18. package/dist/registry/component-resolver.js +1 -0
  19. package/dist/registry/component-resolver.js.map +1 -0
  20. package/dist/registry/index.js +1 -0
  21. package/dist/registry/index.js.map +1 -0
  22. package/dist/runtime/component-hierarchy.d.ts +7 -4
  23. package/dist/runtime/component-hierarchy.d.ts.map +1 -1
  24. package/dist/runtime/component-hierarchy.js +19 -6
  25. package/dist/runtime/component-hierarchy.js.map +1 -0
  26. package/dist/runtime/error-boundary.js +1 -0
  27. package/dist/runtime/error-boundary.js.map +1 -0
  28. package/dist/runtime/index.js +1 -0
  29. package/dist/runtime/index.js.map +1 -0
  30. package/dist/runtime/prop-builder.d.ts +2 -1
  31. package/dist/runtime/prop-builder.d.ts.map +1 -1
  32. package/dist/runtime/prop-builder.js +1 -0
  33. package/dist/runtime/prop-builder.js.map +1 -0
  34. package/dist/runtime/react-root-manager.js +1 -0
  35. package/dist/runtime/react-root-manager.js.map +1 -0
  36. package/dist/runtime.umd.js +2 -0
  37. package/dist/runtime.umd.js.LICENSE.txt +10 -0
  38. package/dist/types/index.d.ts +4 -6
  39. package/dist/types/index.d.ts.map +1 -1
  40. package/dist/types/index.js +1 -0
  41. package/dist/types/index.js.map +1 -0
  42. package/dist/types/library-config.js +1 -0
  43. package/dist/types/library-config.js.map +1 -0
  44. package/dist/utilities/cache-manager.js +1 -0
  45. package/dist/utilities/cache-manager.js.map +1 -0
  46. package/dist/utilities/component-error-analyzer.js +1 -0
  47. package/dist/utilities/component-error-analyzer.js.map +1 -0
  48. package/dist/utilities/component-styles.js +1 -0
  49. package/dist/utilities/component-styles.js.map +1 -0
  50. package/dist/utilities/core-libraries.js +1 -0
  51. package/dist/utilities/core-libraries.js.map +1 -0
  52. package/dist/utilities/index.d.ts +0 -1
  53. package/dist/utilities/index.d.ts.map +1 -1
  54. package/dist/utilities/index.js +1 -1
  55. package/dist/utilities/index.js.map +1 -0
  56. package/dist/utilities/library-loader.d.ts.map +1 -1
  57. package/dist/utilities/library-loader.js +15 -0
  58. package/dist/utilities/library-loader.js.map +1 -0
  59. package/dist/utilities/library-registry.d.ts +3 -1
  60. package/dist/utilities/library-registry.d.ts.map +1 -1
  61. package/dist/utilities/library-registry.js +43 -518
  62. package/dist/utilities/library-registry.js.map +1 -0
  63. package/dist/utilities/resource-manager.js +1 -0
  64. package/dist/utilities/resource-manager.js.map +1 -0
  65. package/dist/utilities/standard-libraries.js +1 -0
  66. package/dist/utilities/standard-libraries.js.map +1 -0
  67. package/package.json +16 -6
  68. package/src/compiler/component-compiler.ts +66 -8
  69. package/src/index.ts +5 -4
  70. package/src/registry/component-registry.ts +18 -0
  71. package/src/runtime/component-hierarchy.ts +28 -8
  72. package/src/runtime/prop-builder.ts +3 -2
  73. package/src/types/index.ts +11 -12
  74. package/src/utilities/index.ts +0 -1
  75. package/src/utilities/library-loader.ts +18 -0
  76. package/src/utilities/library-registry.ts +57 -552
  77. package/tsconfig.json +1 -0
  78. package/tsconfig.tsbuildinfo +1 -1
  79. package/webpack.umd.config.js +76 -0
  80. package/dist/utilities/runtime-utilities.d.ts +0 -10
  81. package/dist/utilities/runtime-utilities.d.ts.map +0 -1
  82. package/dist/utilities/runtime-utilities.js +0 -92
  83. package/src/utilities/runtime-utilities.ts +0 -122
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@memberjunction/react-runtime",
3
- "version": "2.90.0",
3
+ "version": "2.91.0",
4
4
  "description": "Platform-agnostic React component runtime for MemberJunction. Provides core compilation, registry, and execution capabilities for React components in any JavaScript environment.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "browser": "dist/runtime.umd.js",
7
8
  "scripts": {
8
- "build": "tsc",
9
+ "build": "npm run build:node && npm run build:umd",
10
+ "build:node": "tsc",
11
+ "build:umd": "webpack --config webpack.umd.config.js",
9
12
  "build:clean": "rimraf ./dist && npm run build",
10
13
  "watch": "tsc -w",
11
14
  "patchVersion": "npm version patch",
@@ -25,9 +28,10 @@
25
28
  },
26
29
  "homepage": "https://github.com/MemberJunction/MJ#readme",
27
30
  "dependencies": {
28
- "@memberjunction/core": "2.90.0",
29
- "@memberjunction/global": "2.90.0",
30
- "@memberjunction/interactive-component-types": "2.90.0",
31
+ "@memberjunction/core": "2.91.0",
32
+ "@memberjunction/global": "2.91.0",
33
+ "@memberjunction/interactive-component-types": "2.91.0",
34
+ "@memberjunction/core-entities": "2.91.0",
31
35
  "@babel/standalone": "^7.23.5",
32
36
  "rxjs": "^7.8.1"
33
37
  },
@@ -35,6 +39,12 @@
35
39
  "@types/node": "20.10.0",
36
40
  "jest": "^27.5.1",
37
41
  "rimraf": "^3.0.2",
38
- "typescript": "~5.3.3"
42
+ "typescript": "~5.3.3",
43
+ "webpack": "^5.89.0",
44
+ "webpack-cli": "^5.1.4",
45
+ "babel-loader": "^9.1.3",
46
+ "@babel/core": "^7.23.5",
47
+ "@babel/preset-env": "^7.23.5",
48
+ "path-browserify": "^1.0.1"
39
49
  }
40
50
  }
@@ -4,6 +4,7 @@
4
4
  * @module @memberjunction/react-runtime/compiler
5
5
  */
6
6
 
7
+ import { UserInfo } from '@memberjunction/core';
7
8
  import {
8
9
  CompileOptions,
9
10
  CompiledComponent,
@@ -13,6 +14,7 @@ import {
13
14
  RuntimeContext
14
15
  } from '../types';
15
16
  import { LibraryRegistry } from '../utilities/library-registry';
17
+ import { ComponentLibraryEntity } from '@memberjunction/core-entities';
16
18
 
17
19
  /**
18
20
  * Default compiler configuration
@@ -80,7 +82,7 @@ export class ComponentCompiler {
80
82
  this.validateCompileOptions(options);
81
83
 
82
84
  // Load required libraries if specified
83
- const loadedLibraries = await this.loadRequiredLibraries(options.libraries);
85
+ const loadedLibraries = await this.loadRequiredLibraries(options.libraries!, options.allLibraries);
84
86
 
85
87
  // Transpile the component code
86
88
  const transpiledCode = this.transpileComponent(
@@ -207,12 +209,19 @@ export class ComponentCompiler {
207
209
  /**
208
210
  * Load required libraries from the registry
209
211
  * @param libraries - Array of library dependencies
212
+ * @param contextUser - Context user for accessing library registry
210
213
  * @returns Map of loaded libraries
211
214
  */
212
- private async loadRequiredLibraries(libraries?: any[]): Promise<Map<string, any>> {
215
+ private async loadRequiredLibraries(libraries: any[], componentLibraries: ComponentLibraryEntity[]): Promise<Map<string, any>> {
213
216
  const loadedLibraries = new Map<string, any>();
214
217
 
218
+ console.log('🔍 loadRequiredLibraries called with:', {
219
+ librariesCount: libraries?.length || 0,
220
+ libraries: libraries?.map(l => ({ name: l.name, version: l.version, globalVariable: l.globalVariable }))
221
+ });
222
+
215
223
  if (!libraries || libraries.length === 0) {
224
+ console.log('📚 No libraries to load, returning empty map');
216
225
  return loadedLibraries;
217
226
  }
218
227
 
@@ -222,28 +231,49 @@ export class ComponentCompiler {
222
231
  return loadedLibraries;
223
232
  }
224
233
 
234
+ // Initialize LibraryRegistry with componentLibraries if provided
235
+ if (componentLibraries) {
236
+ await LibraryRegistry.Config(false, componentLibraries);
237
+ } else {
238
+ console.warn('⚠️ No componentLibraries provided for LibraryRegistry initialization');
239
+ }
240
+
225
241
  const loadPromises = libraries.map(async (lib) => {
242
+ console.log(`📦 Processing library: ${lib.name}`);
243
+
226
244
  // Check if library is approved
227
- if (!LibraryRegistry.isApproved(lib.name)) {
245
+ const isApproved = LibraryRegistry.isApproved(lib.name);
246
+ console.log(` ✓ Approved check for ${lib.name}: ${isApproved}`);
247
+
248
+ if (!isApproved) {
249
+ console.error(` ❌ Library '${lib.name}' is not approved`);
228
250
  throw new Error(`Library '${lib.name}' is not approved. Only approved libraries can be used.`);
229
251
  }
230
252
 
231
253
  // Get library definition for complete info
232
254
  const libraryDef = LibraryRegistry.getLibrary(lib.name);
255
+ console.log(` ✓ Library definition found for ${lib.name}: ${!!libraryDef}`);
256
+
233
257
  if (!libraryDef) {
258
+ console.error(` ❌ Library '${lib.name}' not found in registry`);
234
259
  throw new Error(`Library '${lib.name}' not found in registry`);
235
260
  }
236
261
 
237
262
  // Get CDN URL for the library
238
263
  const resolvedVersion = LibraryRegistry.resolveVersion(lib.name, lib.version);
264
+ console.log(` ✓ Resolved version for ${lib.name}: ${resolvedVersion}`);
265
+
239
266
  const cdnUrl = LibraryRegistry.getCdnUrl(lib.name, resolvedVersion);
267
+ console.log(` ✓ CDN URL for ${lib.name}: ${cdnUrl}`);
240
268
 
241
269
  if (!cdnUrl) {
270
+ console.error(` ❌ No CDN URL found for library '${lib.name}' version '${lib.version || 'default'}'`);
242
271
  throw new Error(`No CDN URL found for library '${lib.name}' version '${lib.version || 'default'}'`);
243
272
  }
244
273
 
245
274
  // Check if already loaded
246
275
  if ((window as any)[lib.globalVariable]) {
276
+ console.log(` ℹ️ Library ${lib.name} already loaded globally as ${lib.globalVariable}`);
247
277
  loadedLibraries.set(lib.globalVariable, (window as any)[lib.globalVariable]);
248
278
  return;
249
279
  }
@@ -255,20 +285,29 @@ export class ComponentCompiler {
255
285
  }
256
286
 
257
287
  // Load the library dynamically (cdnUrl is guaranteed to be non-null here due to check above)
288
+ console.log(` 📥 Loading script from CDN for ${lib.name}...`);
258
289
  await this.loadScript(cdnUrl!, lib.globalVariable);
259
290
 
260
291
  // Capture the library value from global scope
261
292
  // Note: Libraries loaded from CDN typically attach to window automatically
262
293
  // We capture them here to pass through the component's closure
263
294
  const libraryValue = (window as any)[lib.globalVariable];
295
+ console.log(` ✓ Library ${lib.name} loaded successfully, global variable ${lib.globalVariable} is:`, typeof libraryValue);
296
+
264
297
  if (libraryValue) {
265
298
  loadedLibraries.set(lib.globalVariable, libraryValue);
299
+ console.log(` ✅ Added ${lib.name} to loaded libraries map`);
266
300
  } else {
301
+ console.error(` ❌ Library '${lib.name}' failed to expose global variable '${lib.globalVariable}'`);
267
302
  throw new Error(`Library '${lib.name}' failed to load or did not expose '${lib.globalVariable}'`);
268
303
  }
269
304
  });
270
305
 
271
306
  await Promise.all(loadPromises);
307
+
308
+ console.log(`✅ All libraries loaded successfully. Total: ${loadedLibraries.size}`);
309
+ console.log('📚 Loaded libraries map:', Array.from(loadedLibraries.keys()));
310
+
272
311
  return loadedLibraries;
273
312
  }
274
313
 
@@ -313,11 +352,16 @@ export class ComponentCompiler {
313
352
  // Check if script already exists
314
353
  const existingScript = document.querySelector(`script[src="${url}"]`);
315
354
  if (existingScript) {
316
- // Wait for it to finish loading
355
+ // Wait for it to finish loading with exponential backoff
356
+ let attempts = 0;
357
+ const maxAttempts = 50; // 5 seconds total with 100ms intervals
317
358
  const checkLoaded = () => {
318
359
  if ((window as any)[globalName]) {
319
360
  resolve();
361
+ } else if (attempts >= maxAttempts) {
362
+ reject(new Error(`${globalName} not found after ${maxAttempts * 100}ms waiting for existing script`));
320
363
  } else {
364
+ attempts++;
321
365
  setTimeout(checkLoaded, 100);
322
366
  }
323
367
  };
@@ -331,14 +375,28 @@ export class ComponentCompiler {
331
375
  script.async = true;
332
376
 
333
377
  script.onload = () => {
334
- // Give the library a moment to initialize
335
- setTimeout(() => {
378
+ // More robust checking with multiple attempts
379
+ let attempts = 0;
380
+ const maxAttempts = 20; // 2 seconds total
381
+ const checkInterval = 100; // Check every 100ms
382
+
383
+ const checkGlobal = () => {
336
384
  if ((window as any)[globalName]) {
385
+ console.log(` ✓ Global variable ${globalName} found after ${attempts * checkInterval}ms`);
337
386
  resolve();
387
+ } else if (attempts >= maxAttempts) {
388
+ // Final check - some libraries might use a different global name pattern
389
+ console.error(` ❌ ${globalName} not found after ${attempts * checkInterval}ms`);
390
+ console.log(` ℹ️ Window properties:`, Object.keys(window).filter(k => k.toLowerCase().includes(globalName.toLowerCase())));
391
+ reject(new Error(`${globalName} not found after loading script from ${url}`));
338
392
  } else {
339
- reject(new Error(`${globalName} not found after loading script`));
393
+ attempts++;
394
+ setTimeout(checkGlobal, checkInterval);
340
395
  }
341
- }, 100);
396
+ };
397
+
398
+ // Start checking immediately (don't wait 100ms first)
399
+ checkGlobal();
342
400
  };
343
401
 
344
402
  script.onerror = () => {
package/src/index.ts CHANGED
@@ -71,10 +71,6 @@ export {
71
71
  } from './runtime';
72
72
 
73
73
  // Export utilities
74
- export {
75
- RuntimeUtilities,
76
- createRuntimeUtilities
77
- } from './utilities/runtime-utilities';
78
74
 
79
75
  export {
80
76
  SetupStyles,
@@ -93,6 +89,11 @@ export {
93
89
  LibraryLoadResult
94
90
  } from './utilities/library-loader';
95
91
 
92
+ export {
93
+ LibraryRegistry,
94
+ LibraryDefinition
95
+ } from './utilities/library-registry';
96
+
96
97
  export {
97
98
  ComponentErrorAnalyzer,
98
99
  FailedComponentInfo
@@ -167,6 +167,24 @@ export class ComponentRegistry {
167
167
  return components;
168
168
  }
169
169
 
170
+ /**
171
+ * Gets all components in a namespace and version as a map
172
+ * @param namespace - Namespace to query (default: 'Global')
173
+ * @param version - Version to query (default: 'v1')
174
+ * @returns Object mapping component names to components
175
+ */
176
+ getAll(namespace: string = 'Global', version: string = 'v1'): Record<string, any> {
177
+ const components: Record<string, any> = {};
178
+
179
+ for (const entry of this.registry.values()) {
180
+ if (entry.metadata.namespace === namespace && entry.metadata.version === version) {
181
+ components[entry.metadata.name] = entry.component;
182
+ }
183
+ }
184
+
185
+ return components;
186
+ }
187
+
170
188
  /**
171
189
  * Gets all registered namespaces
172
190
  * @returns Array of unique namespace names
@@ -7,13 +7,14 @@
7
7
  import {
8
8
  CompilationResult,
9
9
  CompileOptions,
10
- ComponentStyles,
11
10
  RuntimeContext
12
11
  } from '../types';
13
12
  import { ComponentCompiler } from '../compiler';
14
13
  import { ComponentRegistry } from '../registry';
15
14
 
16
- import { ComponentSpec } from '@memberjunction/interactive-component-types';
15
+ import { ComponentSpec, ComponentStyles } from '@memberjunction/interactive-component-types';
16
+ import { UserInfo } from '@memberjunction/core';
17
+ import { ComponentLibraryEntity } from '@memberjunction/core-entities';
17
18
 
18
19
  /**
19
20
  * Result of a hierarchy registration operation
@@ -48,6 +49,10 @@ export interface HierarchyRegistrationOptions {
48
49
  continueOnError?: boolean;
49
50
  /** Whether to override existing components */
50
51
  allowOverride?: boolean;
52
+ /**
53
+ * Required, metadata for all possible libraries allowed by the system
54
+ */
55
+ allLibraries: ComponentLibraryEntity[];
51
56
  }
52
57
 
53
58
  /**
@@ -68,7 +73,7 @@ export class ComponentHierarchyRegistrar {
68
73
  */
69
74
  async registerHierarchy(
70
75
  rootSpec: ComponentSpec,
71
- options: HierarchyRegistrationOptions = {}
76
+ options: HierarchyRegistrationOptions
72
77
  ): Promise<HierarchyRegistrationResult> {
73
78
  const {
74
79
  styles,
@@ -78,6 +83,13 @@ export class ComponentHierarchyRegistrar {
78
83
  allowOverride = true
79
84
  } = options;
80
85
 
86
+ console.log('🌳 ComponentHierarchyRegistrar.registerHierarchy:', {
87
+ rootComponent: rootSpec.name,
88
+ hasLibraries: !!(rootSpec.libraries && rootSpec.libraries.length > 0),
89
+ libraryCount: rootSpec.libraries?.length || 0,
90
+ libraries: rootSpec.libraries?.map(l => l.name)
91
+ });
92
+
81
93
  const registeredComponents: string[] = [];
82
94
  const errors: ComponentRegistrationError[] = [];
83
95
  const warnings: string[] = [];
@@ -85,7 +97,7 @@ export class ComponentHierarchyRegistrar {
85
97
  // Register the root component
86
98
  const rootResult = await this.registerSingleComponent(
87
99
  rootSpec,
88
- { styles, namespace, version, allowOverride }
100
+ { styles, namespace, version, allowOverride, allLibraries: options.allLibraries }
89
101
  );
90
102
 
91
103
  if (rootResult.success) {
@@ -102,7 +114,7 @@ export class ComponentHierarchyRegistrar {
102
114
  if (childComponents.length > 0) {
103
115
  const childResult = await this.registerChildComponents(
104
116
  childComponents,
105
- { styles, namespace, version, continueOnError, allowOverride },
117
+ { styles, namespace, version, continueOnError, allowOverride, allLibraries: options.allLibraries },
106
118
  registeredComponents,
107
119
  errors,
108
120
  warnings
@@ -130,6 +142,7 @@ export class ComponentHierarchyRegistrar {
130
142
  namespace?: string;
131
143
  version?: string;
132
144
  allowOverride?: boolean;
145
+ allLibraries: ComponentLibraryEntity[];
133
146
  }
134
147
  ): Promise<{ success: boolean; error?: ComponentRegistrationError }> {
135
148
  const { styles, namespace = 'Global', version = 'v1', allowOverride = true } = options;
@@ -161,9 +174,15 @@ export class ComponentHierarchyRegistrar {
161
174
  componentName: spec.name,
162
175
  componentCode: spec.code,
163
176
  styles,
164
- libraries: spec.libraries // Pass along library dependencies from the spec
177
+ libraries: spec.libraries, // Pass along library dependencies from the spec
178
+ allLibraries: options.allLibraries
165
179
  };
166
180
 
181
+ console.log(`🔧 Compiling component ${spec.name} with libraries:`, {
182
+ libraryCount: spec.libraries?.length || 0,
183
+ libraries: spec.libraries?.map(l => ({ name: l.name, globalVariable: l.globalVariable }))
184
+ });
185
+
167
186
  const compilationResult = await this.compiler.compile(compileOptions);
168
187
 
169
188
  if (!compilationResult.success) {
@@ -223,7 +242,8 @@ export class ComponentHierarchyRegistrar {
223
242
  styles: options.styles,
224
243
  namespace: options.namespace,
225
244
  version: options.version,
226
- allowOverride: options.allowOverride
245
+ allowOverride: options.allowOverride,
246
+ allLibraries: options.allLibraries
227
247
  });
228
248
 
229
249
  if (childResult.success) {
@@ -266,7 +286,7 @@ export async function registerComponentHierarchy(
266
286
  compiler: ComponentCompiler,
267
287
  registry: ComponentRegistry,
268
288
  runtimeContext: RuntimeContext,
269
- options: HierarchyRegistrationOptions = {}
289
+ options: HierarchyRegistrationOptions
270
290
  ): Promise<HierarchyRegistrationResult> {
271
291
  const registrar = new ComponentHierarchyRegistrar(compiler, registry, runtimeContext);
272
292
  return registrar.registerHierarchy(rootSpec, options);
@@ -4,7 +4,8 @@
4
4
  * @module @memberjunction/react-runtime/runtime
5
5
  */
6
6
 
7
- import { ComponentProps, ComponentCallbacks, ComponentStyles } from '../types';
7
+ import { ComponentStyles } from '@memberjunction/interactive-component-types';
8
+ import { ComponentProps, ComponentCallbacks } from '../types';
8
9
  import { Subject, debounceTime, Subscription } from 'rxjs';
9
10
 
10
11
  /**
@@ -187,7 +188,7 @@ export function mergeProps(...propsList: Partial<ComponentProps>[]): ComponentPr
187
188
  utilities: {},
188
189
  callbacks: {},
189
190
  components: {},
190
- styles: {}
191
+ styles: {} as ComponentStyles
191
192
  };
192
193
 
193
194
  for (const props of propsList) {
@@ -4,6 +4,10 @@
4
4
  * @module @memberjunction/react-runtime/types
5
5
  */
6
6
 
7
+ import { UserInfo } from '@memberjunction/core';
8
+ import { ComponentLibraryEntity } from '@memberjunction/core-entities';
9
+ import { ComponentLibraryDependency, ComponentStyles } from '@memberjunction/interactive-component-types';
10
+
7
11
  /**
8
12
  * Represents a compiled React component with its metadata
9
13
  */
@@ -36,22 +40,17 @@ export interface CompileOptions {
36
40
  babelPlugins?: string[];
37
41
  /** Custom Babel presets to use */
38
42
  babelPresets?: string[];
43
+
39
44
  /** Library dependencies that the component requires */
40
- libraries?: any[]; // Using any[] to avoid circular dependency with InteractiveComponents
41
- }
45
+ libraries?: ComponentLibraryDependency[];
42
46
 
43
- /**
44
- * Component styles that can be applied
45
- */
46
- export interface ComponentStyles {
47
- /** CSS classes to apply */
48
- className?: string;
49
- /** Inline styles */
50
- style?: Record<string, any>;
51
- /** Global CSS to inject */
52
- globalCss?: string;
47
+ /**
48
+ * Required, metadata for all possible libraries allowed by the system
49
+ */
50
+ allLibraries: ComponentLibraryEntity[];
53
51
  }
54
52
 
53
+
55
54
  /**
56
55
  * Registry entry for a compiled component
57
56
  */
@@ -3,7 +3,6 @@
3
3
  * @module @memberjunction/react-runtime/utilities
4
4
  */
5
5
 
6
- export * from './runtime-utilities';
7
6
  export * from './component-styles';
8
7
  export * from './standard-libraries';
9
8
  export * from './library-loader';
@@ -99,6 +99,24 @@ export class LibraryLoader {
99
99
  const ReactDOM = coreResults.find((_, i) => coreLibraries[i].globalVariable === 'ReactDOM');
100
100
  const Babel = coreResults.find((_, i) => coreLibraries[i].globalVariable === 'Babel');
101
101
 
102
+ // Expose React and ReactDOM as globals for UMD libraries that expect them
103
+ // Many React component libraries (Recharts, Victory, etc.) expect these as globals
104
+ if (typeof window !== 'undefined') {
105
+ if (React && !(window as any).React) {
106
+ (window as any).React = React;
107
+ console.log('✓ Exposed React as window.React for UMD compatibility');
108
+ }
109
+ if (ReactDOM && !(window as any).ReactDOM) {
110
+ (window as any).ReactDOM = ReactDOM;
111
+ console.log('✓ Exposed ReactDOM as window.ReactDOM for UMD compatibility');
112
+ }
113
+ // Also expose PropTypes as empty object if not present (for older libraries)
114
+ if (!(window as any).PropTypes) {
115
+ (window as any).PropTypes = {};
116
+ console.log('✓ Exposed empty PropTypes as window.PropTypes for UMD compatibility');
117
+ }
118
+ }
119
+
102
120
  // Now load plugin libraries from configuration
103
121
  const config = StandardLibraryManager.getConfiguration();
104
122
  const enabledLibraries = StandardLibraryManager.getEnabledLibraries();