@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.
- package/.turbo/turbo-build.log +9 -9
- package/CHANGELOG.md +28 -0
- package/dist/compiler/component-compiler.d.ts.map +1 -1
- package/dist/compiler/component-compiler.js +90 -18
- package/dist/compiler/component-compiler.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/registry/component-registry-service.d.ts.map +1 -1
- package/dist/registry/component-registry-service.js +14 -6
- package/dist/registry/component-registry-service.js.map +1 -1
- package/dist/registry/component-resolver.d.ts.map +1 -1
- package/dist/registry/component-resolver.js +75 -35
- package/dist/registry/component-resolver.js.map +1 -1
- package/dist/runtime/component-hierarchy.d.ts +1 -0
- package/dist/runtime/component-hierarchy.d.ts.map +1 -1
- package/dist/runtime/component-hierarchy.js.map +1 -1
- package/dist/runtime.umd.js +1 -1
- package/dist/utilities/core-libraries.d.ts +1 -2
- package/dist/utilities/core-libraries.d.ts.map +1 -1
- package/dist/utilities/core-libraries.js +55 -45
- package/dist/utilities/core-libraries.js.map +1 -1
- package/dist/utilities/library-dependency-resolver.d.ts.map +1 -1
- package/dist/utilities/library-dependency-resolver.js +26 -2
- package/dist/utilities/library-dependency-resolver.js.map +1 -1
- package/dist/utilities/library-loader.d.ts +4 -2
- package/dist/utilities/library-loader.d.ts.map +1 -1
- package/dist/utilities/library-loader.js +24 -9
- package/dist/utilities/library-loader.js.map +1 -1
- package/package.json +5 -5
- package/src/compiler/component-compiler.ts +104 -19
- package/src/index.ts +5 -0
- package/src/registry/component-registry-service.ts +15 -6
- package/src/registry/component-resolver.ts +75 -35
- package/src/runtime/component-hierarchy.ts +1 -0
- package/src/utilities/core-libraries.ts +60 -46
- package/src/utilities/library-dependency-resolver.ts +31 -2
- 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
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
86
|
+
if (this.debug) {
|
|
87
|
+
console.log(`🔄 [ComponentResolver] Initializing component engine...`);
|
|
88
|
+
}
|
|
83
89
|
await this.componentEngine.Config(false, contextUser);
|
|
84
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
119
|
-
name
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|
|
@@ -1,61 +1,75 @@
|
|
|
1
1
|
import { ExternalLibraryConfig } from '../types/library-config';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* These are not plugin libraries and are always loaded.
|
|
4
|
+
* Get the React CDN URL based on debug mode
|
|
6
5
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
|
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
|
-
|
|
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 = [...
|
|
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(
|