@memberjunction/react-runtime 2.95.0 → 2.97.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 (39) hide show
  1. package/.turbo/turbo-build.log +9 -9
  2. package/CHANGELOG.md +28 -0
  3. package/dist/compiler/component-compiler.d.ts.map +1 -1
  4. package/dist/compiler/component-compiler.js +90 -18
  5. package/dist/compiler/component-compiler.js.map +1 -1
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +4 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/registry/component-registry-service.d.ts.map +1 -1
  11. package/dist/registry/component-registry-service.js +14 -6
  12. package/dist/registry/component-registry-service.js.map +1 -1
  13. package/dist/registry/component-resolver.d.ts.map +1 -1
  14. package/dist/registry/component-resolver.js +75 -35
  15. package/dist/registry/component-resolver.js.map +1 -1
  16. package/dist/runtime/component-hierarchy.d.ts +1 -0
  17. package/dist/runtime/component-hierarchy.d.ts.map +1 -1
  18. package/dist/runtime/component-hierarchy.js.map +1 -1
  19. package/dist/runtime.umd.js +1 -1
  20. package/dist/utilities/core-libraries.d.ts +1 -2
  21. package/dist/utilities/core-libraries.d.ts.map +1 -1
  22. package/dist/utilities/core-libraries.js +55 -45
  23. package/dist/utilities/core-libraries.js.map +1 -1
  24. package/dist/utilities/library-dependency-resolver.d.ts.map +1 -1
  25. package/dist/utilities/library-dependency-resolver.js +26 -2
  26. package/dist/utilities/library-dependency-resolver.js.map +1 -1
  27. package/dist/utilities/library-loader.d.ts +4 -2
  28. package/dist/utilities/library-loader.d.ts.map +1 -1
  29. package/dist/utilities/library-loader.js +24 -9
  30. package/dist/utilities/library-loader.js.map +1 -1
  31. package/package.json +5 -5
  32. package/src/compiler/component-compiler.ts +104 -19
  33. package/src/index.ts +5 -0
  34. package/src/registry/component-registry-service.ts +15 -6
  35. package/src/registry/component-resolver.ts +75 -35
  36. package/src/runtime/component-hierarchy.ts +1 -0
  37. package/src/utilities/core-libraries.ts +60 -46
  38. package/src/utilities/library-dependency-resolver.ts +31 -2
  39. package/src/utilities/library-loader.ts +26 -9
@@ -68,26 +68,36 @@ export class ComponentResolver {
68
68
  namespace: string = 'Global',
69
69
  contextUser?: UserInfo
70
70
  ): Promise<ResolvedComponents> {
71
- console.log(`🚀 [ComponentResolver] Starting component resolution for: ${spec.name}`);
72
- console.log(`📋 [ComponentResolver] Dependencies to resolve:`, (spec.dependencies || []).map(d => ({
73
- name: d.name,
74
- location: d.location,
75
- namespace: d.namespace
76
- })));
71
+ if (this.debug) {
72
+ console.log(`🚀 [ComponentResolver] Starting component resolution for: ${spec.name}`);
73
+ }
74
+ if (this.debug) {
75
+ console.log(`📋 [ComponentResolver] Dependencies to resolve:`, (spec.dependencies || []).map(d => ({
76
+ name: d.name,
77
+ location: d.location,
78
+ namespace: d.namespace
79
+ })));
80
+ }
77
81
 
78
82
  const resolved: ResolvedComponents = {};
79
83
 
80
84
  // Initialize component engine if we have registry service
81
85
  if (this.registryService) {
82
- console.log(`🔄 [ComponentResolver] Initializing component engine...`);
86
+ if (this.debug) {
87
+ console.log(`🔄 [ComponentResolver] Initializing component engine...`);
88
+ }
83
89
  await this.componentEngine.Config(false, contextUser);
84
- console.log(`✅ [ComponentResolver] Component engine initialized with ${this.componentEngine.Components?.length || 0} components`);
90
+ if (this.debug) {
91
+ console.log(`✅ [ComponentResolver] Component engine initialized with ${this.componentEngine.Components?.length || 0} components`);
92
+ }
85
93
  }
86
94
 
87
95
  // Resolve the component hierarchy
88
96
  await this.resolveComponentHierarchy(spec, resolved, namespace, new Set(), contextUser);
89
97
 
90
- console.log(`📊 [ComponentResolver] Resolved components before unwrapping:`, Object.keys(resolved));
98
+ if (this.debug) {
99
+ console.log(`📊 [ComponentResolver] Resolved components before unwrapping:`, Object.keys(resolved));
100
+ }
91
101
 
92
102
  // Unwrap component wrappers before returning
93
103
  // Components from the registry come as objects with component/print/refresh properties
@@ -98,7 +108,9 @@ export class ComponentResolver {
98
108
  if (typeof value.component === 'function') {
99
109
  // This is a wrapped component - extract the actual React component function
100
110
  unwrapped[name] = value.component;
101
- console.log(`✅ [ComponentResolver] Unwrapped component: ${name} (was object with .component)`);
111
+ if (this.debug) {
112
+ console.log(`✅ [ComponentResolver] Unwrapped component: ${name} (was object with .component)`);
113
+ }
102
114
  } else {
103
115
  // ComponentObject has a component property but it's not a function
104
116
  console.error(`❌ [ComponentResolver] Component ${name} has invalid component property:`, typeof value.component, value);
@@ -107,7 +119,9 @@ export class ComponentResolver {
107
119
  } else if (typeof value === 'function') {
108
120
  // Already a function - use as is
109
121
  unwrapped[name] = value;
110
- console.log(`✅ [ComponentResolver] Component already a function: ${name}`);
122
+ if (this.debug) {
123
+ console.log(`✅ [ComponentResolver] Component already a function: ${name}`);
124
+ }
111
125
  } else {
112
126
  // Something else - could be undefined or an error
113
127
  console.warn(`⚠️ [ComponentResolver] Component ${name} is not a function or wrapped component:`, typeof value, value);
@@ -115,11 +129,13 @@ export class ComponentResolver {
115
129
  }
116
130
  }
117
131
 
118
- console.log(`🎯 [ComponentResolver] Final resolved components:`, Object.keys(unwrapped).map(name => ({
119
- name,
120
- type: typeof unwrapped[name],
121
- isUndefined: unwrapped[name] === undefined
122
- })));
132
+ if (this.debug) {
133
+ console.log(`🎯 [ComponentResolver] Final resolved components:`, Object.keys(unwrapped).map(name => ({
134
+ name,
135
+ type: typeof unwrapped[name],
136
+ isUndefined: unwrapped[name] === undefined
137
+ })));
138
+ }
123
139
 
124
140
  return unwrapped;
125
141
  }
@@ -144,7 +160,9 @@ export class ComponentResolver {
144
160
 
145
161
  // Check if already resolved (not just visited)
146
162
  if (resolved[spec.name]) {
147
- console.log(`⏭️ [ComponentResolver] Component already resolved: ${spec.name}`);
163
+ if (this.debug) {
164
+ console.log(`⏭️ [ComponentResolver] Component already resolved: ${spec.name}`);
165
+ }
148
166
  return;
149
167
  }
150
168
 
@@ -158,13 +176,17 @@ export class ComponentResolver {
158
176
  visited.add(componentId);
159
177
 
160
178
  // *** CRITICAL: Process child components FIRST (depth-first, post-order) ***
161
- console.log(`🔄 [ComponentResolver] Resolving dependencies for ${spec.name} BEFORE resolving itself`);
179
+ if (this.debug) {
180
+ console.log(`🔄 [ComponentResolver] Resolving dependencies for ${spec.name} BEFORE resolving itself`);
181
+ }
162
182
  const children = spec.dependencies || [];
163
183
  for (const child of children) {
164
- console.log(` ↳ [ComponentResolver] Resolving dependency: ${child.name} for parent ${spec.name}`);
184
+ if (this.debug) {
185
+ console.log(` ↳ [ComponentResolver] Resolving dependency: ${child.name} for parent ${spec.name}`);
186
+ }
165
187
  await this.resolveComponentHierarchy(child, resolved, namespace, visited, contextUser);
166
188
  }
167
- if (children.length > 0) {
189
+ if (children.length > 0 && this.debug) {
168
190
  console.log(`✅ [ComponentResolver] All ${children.length} dependencies resolved for ${spec.name}, now resolving itself`);
169
191
  }
170
192
 
@@ -172,16 +194,20 @@ export class ComponentResolver {
172
194
  // Handle based on location
173
195
  if (spec.location === 'registry' && this.registryService) {
174
196
  // Registry component - need to load from database or external source
175
- console.log(`🔍 [ComponentResolver] Looking for registry component: ${spec.name} in namespace: ${spec.namespace || namespace}`);
197
+ if (this.debug) {
198
+ console.log(`🔍 [ComponentResolver] Looking for registry component: ${spec.name} in namespace: ${spec.namespace || namespace}`);
199
+ }
176
200
 
177
201
  try {
178
202
  // First, try to find the component in the metadata engine
179
203
  const allComponents = this.componentEngine.Components || [];
180
- console.log(`📊 [ComponentResolver] Total components in engine: ${allComponents.length}`);
204
+ if (this.debug) {
205
+ console.log(`📊 [ComponentResolver] Total components in engine: ${allComponents.length}`);
206
+ }
181
207
 
182
208
  // Log all matching names to see duplicates
183
209
  const matchingNames = allComponents.filter((c: any) => c.Name === spec.name);
184
- if (matchingNames.length > 0) {
210
+ if (matchingNames.length > 0 && this.debug) {
185
211
  console.log(`🔎 [ComponentResolver] Found ${matchingNames.length} components with name "${spec.name}":`,
186
212
  matchingNames.map((c: any) => ({
187
213
  ID: c.ID,
@@ -199,12 +225,14 @@ export class ComponentResolver {
199
225
  );
200
226
 
201
227
  if (component) {
202
- console.log(`✅ [ComponentResolver] Found component in DB:`, {
203
- ID: component.ID,
204
- Name: component.Name,
205
- Namespace: component.Namespace,
206
- Version: component.Version
207
- });
228
+ if (this.debug) {
229
+ console.log(`✅ [ComponentResolver] Found component in DB:`, {
230
+ ID: component.ID,
231
+ Name: component.Name,
232
+ Namespace: component.Namespace,
233
+ Version: component.Version
234
+ });
235
+ }
208
236
 
209
237
  // Get compiled component from registry service
210
238
  const compiledComponent = await this.registryService.getCompiledComponent(
@@ -213,7 +241,9 @@ export class ComponentResolver {
213
241
  contextUser
214
242
  );
215
243
  resolved[spec.name] = compiledComponent;
216
- console.log(`📦 [ComponentResolver] Successfully compiled and resolved: ${spec.name}, type: ${typeof compiledComponent}`);
244
+ if (this.debug) {
245
+ console.log(`📦 [ComponentResolver] Successfully compiled and resolved: ${spec.name}, type: ${typeof compiledComponent}`);
246
+ }
217
247
 
218
248
  if (this.debug) {
219
249
  console.log(`📦 Resolved registry component: ${spec.name} from ${componentId}`);
@@ -233,29 +263,39 @@ export class ComponentResolver {
233
263
  // Embedded component - get from local registry
234
264
  // Use the component's specified namespace if it has one, otherwise use parent's namespace
235
265
  const componentNamespace = spec.namespace || namespace;
236
- console.log(`🔍 [ComponentResolver] Looking for embedded component: ${spec.name} in namespace: ${componentNamespace}`);
266
+ if (this.debug) {
267
+ console.log(`🔍 [ComponentResolver] Looking for embedded component: ${spec.name} in namespace: ${componentNamespace}`);
268
+ }
237
269
 
238
270
  const component = this.registry.get(spec.name, componentNamespace);
239
271
  if (component) {
240
272
  resolved[spec.name] = component;
241
- console.log(`✅ [ComponentResolver] Found embedded component: ${spec.name}, type: ${typeof component}`);
273
+ if (this.debug) {
274
+ console.log(`✅ [ComponentResolver] Found embedded component: ${spec.name}, type: ${typeof component}`);
275
+ }
242
276
  if (this.debug) {
243
277
  console.log(`📄 Resolved embedded component: ${spec.name} from namespace ${componentNamespace}, type:`, typeof component);
244
278
  }
245
279
  } else {
246
280
  // If not found with specified namespace, try the parent namespace as fallback
247
- console.log(`⚠️ [ComponentResolver] Not found in namespace ${componentNamespace}, trying fallback namespace: ${namespace}`);
281
+ if (this.debug) {
282
+ console.log(`⚠️ [ComponentResolver] Not found in namespace ${componentNamespace}, trying fallback namespace: ${namespace}`);
283
+ }
248
284
  const fallbackComponent = this.registry.get(spec.name, namespace);
249
285
  if (fallbackComponent) {
250
286
  resolved[spec.name] = fallbackComponent;
251
- console.log(`✅ [ComponentResolver] Found embedded component in fallback namespace: ${spec.name}, type: ${typeof fallbackComponent}`);
287
+ if (this.debug) {
288
+ console.log(`✅ [ComponentResolver] Found embedded component in fallback namespace: ${spec.name}, type: ${typeof fallbackComponent}`);
289
+ }
252
290
  if (this.debug) {
253
291
  console.log(`📄 Resolved embedded component: ${spec.name} from fallback namespace ${namespace}, type:`, typeof fallbackComponent);
254
292
  }
255
293
  } else {
256
294
  // Component not found - this might cause issues later
257
295
  console.error(`❌ [ComponentResolver] Could not resolve embedded component: ${spec.name} in namespace ${componentNamespace} or ${namespace}`);
258
- console.warn(`⚠️ Could not resolve embedded component: ${spec.name} in namespace ${componentNamespace} or ${namespace}`);
296
+ if (this.debug) {
297
+ console.warn(`⚠️ Could not resolve embedded component: ${spec.name} in namespace ${componentNamespace} or ${namespace}`);
298
+ }
259
299
  // Store undefined explicitly so we know it failed to resolve
260
300
  resolved[spec.name] = undefined;
261
301
  }
@@ -54,6 +54,7 @@ export interface HierarchyRegistrationOptions {
54
54
  * Required, metadata for all possible libraries allowed by the system
55
55
  */
56
56
  allLibraries: ComponentLibraryEntity[];
57
+ debug?: boolean;
57
58
  }
58
59
 
59
60
  /**
@@ -1,61 +1,75 @@
1
1
  import { ExternalLibraryConfig } from '../types/library-config';
2
2
 
3
3
  /**
4
- * Core runtime libraries required for the React runtime to function.
5
- * These are not plugin libraries and are always loaded.
4
+ * Get the React CDN URL based on debug mode
6
5
  */
7
- export const CORE_RUNTIME_LIBRARIES: ExternalLibraryConfig[] = [
8
- {
9
- id: 'react',
10
- name: 'react',
11
- displayName: 'React',
12
- category: 'runtime',
13
- globalVariable: 'React',
14
- version: '18.2.0',
15
- cdnUrl: 'https://unpkg.com/react@18.2.0/umd/react.production.min.js',
16
- description: 'React core library',
17
- isEnabled: true,
18
- isCore: true,
19
- isRuntimeOnly: true
20
- },
21
- {
22
- id: 'react-dom',
23
- name: 'react-dom',
24
- displayName: 'ReactDOM',
25
- category: 'runtime',
26
- globalVariable: 'ReactDOM',
27
- version: '18.2.0',
28
- cdnUrl: 'https://unpkg.com/react-dom@18.2.0/umd/react-dom.production.min.js',
29
- description: 'React DOM library',
30
- isEnabled: true,
31
- isCore: true,
32
- isRuntimeOnly: true
33
- },
34
- {
35
- id: 'babel-standalone',
36
- name: '@babel/standalone',
37
- displayName: 'Babel Standalone',
38
- category: 'runtime',
39
- globalVariable: 'Babel',
40
- version: '7.24.4',
41
- cdnUrl: 'https://unpkg.com/@babel/standalone@7.24.4/babel.min.js',
42
- description: 'Babel compiler for JSX transformation',
43
- isEnabled: true,
44
- isCore: true,
45
- isRuntimeOnly: true
46
- }
47
- ];
6
+ function getReactUrl(debug: boolean = false): string {
7
+ return debug
8
+ ? 'https://unpkg.com/react@18.2.0/umd/react.development.js'
9
+ : 'https://unpkg.com/react@18.2.0/umd/react.production.min.js';
10
+ }
11
+
12
+ /**
13
+ * Get the ReactDOM CDN URL based on debug mode
14
+ */
15
+ function getReactDOMUrl(debug: boolean = false): string {
16
+ return debug
17
+ ? 'https://unpkg.com/react-dom@18.2.0/umd/react-dom.development.js'
18
+ : 'https://unpkg.com/react-dom@18.2.0/umd/react-dom.production.min.js';
19
+ }
48
20
 
49
21
  /**
50
22
  * Get the core runtime libraries configuration
23
+ * @param debug Whether to use development builds for better error messages
51
24
  */
52
- export function getCoreRuntimeLibraries(): ExternalLibraryConfig[] {
53
- return CORE_RUNTIME_LIBRARIES;
25
+ export function getCoreRuntimeLibraries(debug: boolean = false): ExternalLibraryConfig[] {
26
+ return [
27
+ {
28
+ id: 'react',
29
+ name: 'react',
30
+ displayName: 'React',
31
+ category: 'runtime',
32
+ globalVariable: 'React',
33
+ version: '18.2.0',
34
+ cdnUrl: getReactUrl(debug),
35
+ description: 'React core library',
36
+ isEnabled: true,
37
+ isCore: true,
38
+ isRuntimeOnly: true
39
+ },
40
+ {
41
+ id: 'react-dom',
42
+ name: 'react-dom',
43
+ displayName: 'ReactDOM',
44
+ category: 'runtime',
45
+ globalVariable: 'ReactDOM',
46
+ version: '18.2.0',
47
+ cdnUrl: getReactDOMUrl(debug),
48
+ description: 'React DOM library',
49
+ isEnabled: true,
50
+ isCore: true,
51
+ isRuntimeOnly: true
52
+ },
53
+ {
54
+ id: 'babel-standalone',
55
+ name: '@babel/standalone',
56
+ displayName: 'Babel Standalone',
57
+ category: 'runtime',
58
+ globalVariable: 'Babel',
59
+ version: '7.24.4',
60
+ cdnUrl: 'https://unpkg.com/@babel/standalone@7.24.4/babel.min.js',
61
+ description: 'Babel compiler for JSX transformation',
62
+ isEnabled: true,
63
+ isCore: true,
64
+ isRuntimeOnly: true
65
+ }
66
+ ];
54
67
  }
55
68
 
56
69
  /**
57
70
  * Check if a library ID is a core runtime library
58
71
  */
59
72
  export function isCoreRuntimeLibrary(libraryId: string): boolean {
60
- return CORE_RUNTIME_LIBRARIES.some(lib => lib.id === libraryId);
73
+ const coreLibraries = getCoreRuntimeLibraries();
74
+ return coreLibraries.some((lib: ExternalLibraryConfig) => lib.id === libraryId);
61
75
  }
@@ -420,15 +420,33 @@ export class LibraryDependencyResolver {
420
420
  const errors: string[] = [];
421
421
  const warnings: string[] = [];
422
422
 
423
+ // Filter out null, undefined, and non-string values from requestedLibs
424
+ const validRequestedLibs = requestedLibs.filter(lib => {
425
+ if (!lib || typeof lib !== 'string') {
426
+ const warning = `Invalid library name: ${lib} (type: ${typeof lib})`;
427
+ warnings.push(warning);
428
+ if (this.debug || options?.debug) {
429
+ console.warn(`⚠️ ${warning}`);
430
+ }
431
+ return false;
432
+ }
433
+ return true;
434
+ });
435
+
423
436
  if (this.debug || options?.debug) {
424
437
  console.log('🔍 Getting load order for requested libraries:');
425
- console.log(' 📝 Requested:', requestedLibs);
438
+ console.log(' 📝 Requested (raw):', requestedLibs);
439
+ console.log(' 📝 Requested (valid):', validRequestedLibs);
426
440
  console.log(' 📚 Total available libraries:', allLibs.length);
427
441
  }
428
442
 
429
443
  // Build a map for quick lookup (case-insensitive)
430
444
  const libMap = new Map<string, ComponentLibraryEntity[]>();
431
445
  for (const lib of allLibs) {
446
+ if (!lib?.Name) {
447
+ warnings.push(`Library with missing name found in available libraries`);
448
+ continue;
449
+ }
432
450
  const key = lib.Name.toLowerCase();
433
451
  if (!libMap.has(key)) {
434
452
  libMap.set(key, []);
@@ -438,7 +456,7 @@ export class LibraryDependencyResolver {
438
456
 
439
457
  // Collect all libraries needed (requested + their dependencies)
440
458
  const needed = new Set<string>();
441
- const toProcess = [...requestedLibs];
459
+ const toProcess = [...validRequestedLibs];
442
460
  const processed = new Set<string>();
443
461
  const versionRequirements = new Map<string, VersionRequirement[]>();
444
462
  let depth = 0;
@@ -446,6 +464,17 @@ export class LibraryDependencyResolver {
446
464
 
447
465
  while (toProcess.length > 0 && depth < maxDepth) {
448
466
  const current = toProcess.shift()!;
467
+
468
+ // Extra safety check for null/undefined
469
+ if (!current || typeof current !== 'string') {
470
+ const warning = `Unexpected invalid library name during processing: ${current}`;
471
+ warnings.push(warning);
472
+ if (this.debug || options?.debug) {
473
+ console.warn(`⚠️ ${warning}`);
474
+ }
475
+ continue;
476
+ }
477
+
449
478
  if (processed.has(current)) continue;
450
479
 
451
480
  processed.add(current);
@@ -65,10 +65,12 @@ export class LibraryLoader {
65
65
  * This is the main method that should be used by test harness and Angular wrapper
66
66
  * @param config Optional full library configuration to replace the default
67
67
  * @param additionalLibraries Optional additional libraries to merge with the configuration
68
+ * @param options Optional options including debug mode flag
68
69
  */
69
70
  static async loadAllLibraries(
70
71
  config?: LibraryConfiguration,
71
- additionalLibraries?: ExternalLibraryConfig[]
72
+ additionalLibraries?: ExternalLibraryConfig[],
73
+ options?: { debug?: boolean }
72
74
  ): Promise<LibraryLoadResult> {
73
75
  if (config) {
74
76
  StandardLibraryManager.setConfiguration(config);
@@ -87,17 +89,17 @@ export class LibraryLoader {
87
89
  StandardLibraryManager.setConfiguration(mergedConfig);
88
90
  }
89
91
 
90
- return this.loadLibrariesFromConfig();
92
+ return this.loadLibrariesFromConfig(undefined, options?.debug);
91
93
  }
92
94
 
93
95
  /**
94
96
  * Load libraries based on the current configuration
95
97
  */
96
- static async loadLibrariesFromConfig(options?: ConfigLoadOptions): Promise<LibraryLoadResult> {
98
+ static async loadLibrariesFromConfig(options?: ConfigLoadOptions, debug?: boolean): Promise<LibraryLoadResult> {
97
99
  // Always load core runtime libraries first
98
- const coreLibraries = getCoreRuntimeLibraries();
100
+ const coreLibraries = getCoreRuntimeLibraries(debug);
99
101
  const corePromises = coreLibraries.map(lib =>
100
- this.loadScript(lib.cdnUrl, lib.globalVariable)
102
+ this.loadScript(lib.cdnUrl, lib.globalVariable, debug)
101
103
  );
102
104
 
103
105
  const coreResults = await Promise.all(corePromises);
@@ -151,7 +153,7 @@ export class LibraryLoader {
151
153
 
152
154
  // Load plugin libraries
153
155
  const pluginPromises = pluginLibraries.map(lib =>
154
- this.loadScript(lib.cdnUrl, lib.globalVariable)
156
+ this.loadScript(lib.cdnUrl, lib.globalVariable, debug)
155
157
  );
156
158
 
157
159
  const pluginResults = await Promise.all(pluginPromises);
@@ -214,10 +216,13 @@ export class LibraryLoader {
214
216
  /**
215
217
  * Load a script from URL
216
218
  */
217
- private static async loadScript(url: string, globalName: string): Promise<any> {
219
+ private static async loadScript(url: string, globalName: string, debug: boolean = false): Promise<any> {
218
220
  // Check if already loaded
219
221
  const existing = this.loadedResources.get(url);
220
222
  if (existing) {
223
+ if (debug) {
224
+ console.log(`✅ Library '${globalName}' already loaded (cached)`);
225
+ }
221
226
  return existing.promise;
222
227
  }
223
228
 
@@ -225,6 +230,9 @@ export class LibraryLoader {
225
230
  // Check if global already exists
226
231
  const existingGlobal = (window as any)[globalName];
227
232
  if (existingGlobal) {
233
+ if (debug) {
234
+ console.log(`✅ Library '${globalName}' already available globally`);
235
+ }
228
236
  resolve(existingGlobal);
229
237
  return;
230
238
  }
@@ -251,6 +259,9 @@ export class LibraryLoader {
251
259
  cleanup();
252
260
  const global = (window as any)[globalName];
253
261
  if (global) {
262
+ if (debug) {
263
+ console.log(`✅ Library '${globalName}' loaded successfully from ${url}`);
264
+ }
254
265
  resolve(global);
255
266
  } else {
256
267
  // Some libraries may take a moment to initialize
@@ -259,6 +270,9 @@ export class LibraryLoader {
259
270
  () => {
260
271
  const delayedGlobal = (window as any)[globalName];
261
272
  if (delayedGlobal) {
273
+ if (debug) {
274
+ console.log(`✅ Library '${globalName}' loaded successfully (delayed initialization)`);
275
+ }
262
276
  resolve(delayedGlobal);
263
277
  } else {
264
278
  reject(new Error(`${globalName} not found after script load`));
@@ -278,6 +292,9 @@ export class LibraryLoader {
278
292
  script.addEventListener('load', onLoad);
279
293
  script.addEventListener('error', onError);
280
294
 
295
+ if (debug) {
296
+ console.log(`📦 Loading library '${globalName}' from ${url}...`);
297
+ }
281
298
  document.head.appendChild(script);
282
299
 
283
300
  // Register the script element for cleanup
@@ -479,7 +496,7 @@ export class LibraryLoader {
479
496
  }
480
497
 
481
498
  // Load the script
482
- const loadedGlobal = await this.loadScript(library.CDNUrl, library.GlobalVariable);
499
+ const loadedGlobal = await this.loadScript(library.CDNUrl, library.GlobalVariable, debug);
483
500
 
484
501
  // Track the loaded state
485
502
  const dependencies = Array.from(
@@ -607,7 +624,7 @@ export class LibraryLoader {
607
624
  }
608
625
 
609
626
  // Load the script
610
- const loadedGlobal = await this.loadScript(library.CDNUrl, library.GlobalVariable);
627
+ const loadedGlobal = await this.loadScript(library.CDNUrl, library.GlobalVariable, debug);
611
628
 
612
629
  // Track the loaded state
613
630
  const dependencies = Array.from(