@memberjunction/react-runtime 2.93.0 â 2.95.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 +6 -6
- package/CHANGELOG.md +28 -0
- package/README.md +180 -2
- package/dist/compiler/component-compiler.d.ts +1 -0
- package/dist/compiler/component-compiler.d.ts.map +1 -1
- package/dist/compiler/component-compiler.js +253 -61
- package/dist/compiler/component-compiler.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/dist/registry/component-registry-service.d.ts +6 -3
- package/dist/registry/component-registry-service.d.ts.map +1 -1
- package/dist/registry/component-registry-service.js +38 -11
- package/dist/registry/component-registry-service.js.map +1 -1
- package/dist/registry/component-registry.d.ts +6 -3
- package/dist/registry/component-registry.d.ts.map +1 -1
- package/dist/registry/component-registry.js +17 -0
- package/dist/registry/component-registry.js.map +1 -1
- package/dist/registry/component-resolver.d.ts +2 -1
- package/dist/registry/component-resolver.d.ts.map +1 -1
- package/dist/registry/component-resolver.js +101 -14
- package/dist/registry/component-resolver.js.map +1 -1
- package/dist/runtime/component-hierarchy.d.ts.map +1 -1
- package/dist/runtime/component-hierarchy.js +75 -13
- package/dist/runtime/component-hierarchy.js.map +1 -1
- package/dist/runtime/prop-builder.d.ts +2 -2
- package/dist/runtime/prop-builder.d.ts.map +1 -1
- package/dist/runtime/prop-builder.js +32 -14
- package/dist/runtime/prop-builder.js.map +1 -1
- package/dist/runtime.umd.js +1 -1
- package/dist/types/dependency-types.d.ts +62 -0
- package/dist/types/dependency-types.d.ts.map +1 -0
- package/dist/types/dependency-types.js +3 -0
- package/dist/types/dependency-types.js.map +1 -0
- package/dist/types/index.d.ts +8 -10
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utilities/index.d.ts +1 -0
- package/dist/utilities/index.d.ts.map +1 -1
- package/dist/utilities/index.js +1 -0
- package/dist/utilities/index.js.map +1 -1
- package/dist/utilities/library-dependency-resolver.d.ts +19 -0
- package/dist/utilities/library-dependency-resolver.d.ts.map +1 -0
- package/dist/utilities/library-dependency-resolver.js +419 -0
- package/dist/utilities/library-dependency-resolver.js.map +1 -0
- package/dist/utilities/library-loader.d.ts +9 -0
- package/dist/utilities/library-loader.d.ts.map +1 -1
- package/dist/utilities/library-loader.js +164 -0
- package/dist/utilities/library-loader.js.map +1 -1
- package/package.json +5 -5
- package/src/compiler/component-compiler.ts +280 -82
- package/src/index.ts +20 -5
- package/src/registry/component-registry-service.ts +53 -14
- package/src/registry/component-registry.ts +36 -7
- package/src/registry/component-resolver.ts +130 -16
- package/src/runtime/component-hierarchy.ts +101 -27
- package/src/runtime/prop-builder.ts +38 -18
- package/src/types/dependency-types.ts +110 -0
- package/src/types/index.ts +17 -21
- package/src/utilities/index.ts +1 -0
- package/src/utilities/library-dependency-resolver.ts +613 -0
- package/src/utilities/library-loader.ts +274 -0
|
@@ -13,7 +13,9 @@ import {
|
|
|
13
13
|
ComponentError,
|
|
14
14
|
RuntimeContext
|
|
15
15
|
} from '../types';
|
|
16
|
+
import { ComponentStyles, ComponentObject } from '@memberjunction/interactive-component-types';
|
|
16
17
|
import { LibraryRegistry } from '../utilities/library-registry';
|
|
18
|
+
import { LibraryLoader } from '../utilities/library-loader';
|
|
17
19
|
import { ComponentLibraryEntity } from '@memberjunction/core-entities';
|
|
18
20
|
|
|
19
21
|
/**
|
|
@@ -27,7 +29,8 @@ const DEFAULT_COMPILER_CONFIG: CompilerConfig = {
|
|
|
27
29
|
minify: false,
|
|
28
30
|
sourceMaps: false,
|
|
29
31
|
cache: true,
|
|
30
|
-
maxCacheSize: 100
|
|
32
|
+
maxCacheSize: 100,
|
|
33
|
+
debug: false
|
|
31
34
|
};
|
|
32
35
|
|
|
33
36
|
/**
|
|
@@ -100,7 +103,7 @@ export class ComponentCompiler {
|
|
|
100
103
|
|
|
101
104
|
// Build the compiled component
|
|
102
105
|
const compiledComponent: CompiledComponent = {
|
|
103
|
-
|
|
106
|
+
factory: componentFactory,
|
|
104
107
|
id: this.generateComponentId(options.componentName),
|
|
105
108
|
name: options.componentName,
|
|
106
109
|
compiledAt: new Date(),
|
|
@@ -169,67 +172,241 @@ export class ComponentCompiler {
|
|
|
169
172
|
* @param dependencies - Optional child component dependencies
|
|
170
173
|
* @returns Wrapped component code
|
|
171
174
|
*/
|
|
175
|
+
// Core libraries that are passed as parameters to createComponent and should not be destructured
|
|
176
|
+
private readonly CORE_LIBRARIES = new Set(['React', 'ReactDOM']);
|
|
177
|
+
|
|
172
178
|
private wrapComponentCode(componentCode: string, componentName: string, libraries?: any[], dependencies?: Array<{ name: string }>): string {
|
|
173
179
|
// Generate library declarations if libraries are provided
|
|
180
|
+
// Skip core libraries as they're passed as parameters to createComponent
|
|
174
181
|
const libraryDeclarations = libraries && libraries.length > 0
|
|
175
182
|
? libraries
|
|
176
|
-
.filter(lib => lib.globalVariable) //
|
|
183
|
+
.filter(lib => lib.globalVariable && !this.CORE_LIBRARIES.has(lib.globalVariable)) // Skip core libraries
|
|
177
184
|
.map(lib => `const ${lib.globalVariable} = libraries['${lib.globalVariable}'];`)
|
|
178
185
|
.join('\n ')
|
|
179
186
|
: '';
|
|
180
|
-
|
|
187
|
+
const libraryLogChecks = libraries && libraries.length > 0
|
|
188
|
+
? libraries
|
|
189
|
+
.filter(lib => lib.globalVariable && !this.CORE_LIBRARIES.has(lib.globalVariable)) // Skip core libraries
|
|
190
|
+
.map(lib => `\nif (!${lib.globalVariable}) { console.error('[React-Runtime-JS] Library "${lib.globalVariable}" is not defined'); } else { console.log('[React-Runtime-JS] Library "${lib.globalVariable}" is defined'); }`)
|
|
191
|
+
.join('\n ')
|
|
192
|
+
: '';
|
|
193
|
+
|
|
181
194
|
// Generate component declarations if dependencies are provided
|
|
195
|
+
// Filter out the component being compiled to avoid naming conflicts
|
|
182
196
|
const componentDeclarations = dependencies && dependencies.length > 0
|
|
183
197
|
? dependencies
|
|
184
|
-
.
|
|
198
|
+
.filter(dep => dep.name !== componentName) // Don't destructure the component being compiled itself
|
|
199
|
+
.map(dep => `const ${dep.name} = componentsOuter['${dep.name}'];`)
|
|
200
|
+
.join('\n ')
|
|
201
|
+
: '';
|
|
202
|
+
const componentLogChecks = dependencies && dependencies.length > 0
|
|
203
|
+
? dependencies
|
|
204
|
+
.filter(dep => dep.name !== componentName) // Don't destructure the component being compiled itself
|
|
205
|
+
.map(dep => `if (!${dep.name}) { console.error('[React-Runtime-JS] Dependency "${dep.name}" is not defined'); } else { console.log('[React-Runtime-JS] Dependency "${dep.name}" is defined'); }`)
|
|
185
206
|
.join('\n ')
|
|
186
207
|
: '';
|
|
187
208
|
|
|
188
|
-
|
|
209
|
+
const wrappedCode = `
|
|
189
210
|
function createComponent(
|
|
190
211
|
React, ReactDOM,
|
|
191
212
|
useState, useEffect, useCallback, useMemo, useRef, useContext, useReducer, useLayoutEffect,
|
|
192
213
|
libraries, styles, console, components
|
|
193
214
|
) {
|
|
194
|
-
|
|
215
|
+
// Code for ${componentName}
|
|
216
|
+
${componentCode}
|
|
195
217
|
|
|
196
218
|
// Ensure the component exists
|
|
197
219
|
if (typeof ${componentName} === 'undefined') {
|
|
198
220
|
throw new Error('Component "${componentName}" is not defined in the provided code');
|
|
199
221
|
}
|
|
222
|
+
else {
|
|
223
|
+
console.log('[React-Runtime-JS] Component "${componentName}" is defined');
|
|
224
|
+
}
|
|
200
225
|
|
|
201
|
-
//
|
|
226
|
+
// Store the component in a variable so we don't lose it
|
|
227
|
+
const UserComponent = ${componentName};
|
|
228
|
+
|
|
229
|
+
// Check if the component is already a ComponentObject (has a .component property)
|
|
230
|
+
// If so, extract the actual React component
|
|
231
|
+
const ActualComponent = (typeof UserComponent === 'object' && UserComponent !== null && 'component' in UserComponent)
|
|
232
|
+
? UserComponent.component
|
|
233
|
+
: UserComponent;
|
|
234
|
+
|
|
235
|
+
// Debug logging to understand what we're getting
|
|
236
|
+
console.log('[React-Runtime-JS]Component ${componentName} type:', typeof UserComponent);
|
|
237
|
+
if (typeof UserComponent === 'object' && UserComponent !== null) {
|
|
238
|
+
console.log('[React-Runtime-JS]Component ${componentName} keys:', Object.keys(UserComponent));
|
|
239
|
+
console.log('[React-Runtime-JS]Component ${componentName} has .component:', 'component' in UserComponent);
|
|
240
|
+
if ('component' in UserComponent) {
|
|
241
|
+
console.log('[React-Runtime-JS]Component ${componentName}.component type:', typeof UserComponent.component);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Validate that we have a function (React component)
|
|
246
|
+
if (typeof ActualComponent !== 'function') {
|
|
247
|
+
console.error('[React-Runtime-JS] Invalid component type for ${componentName}:', typeof ActualComponent);
|
|
248
|
+
console.error('[React-Runtime-JS] ActualComponent value:', ActualComponent);
|
|
249
|
+
console.error('[React-Runtime-JS] Original UserComponent value:', UserComponent);
|
|
250
|
+
throw new Error('[React-Runtime-JS] Component "${componentName}" must be a function (React component) or an object with a .component property that is a function. Got: ' + typeof ActualComponent);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
let componentsOuter = null, utilitiesOuter = null;
|
|
254
|
+
const DestructureWrapperUserComponent = (props) => {
|
|
255
|
+
if (!componentsOuter) {
|
|
256
|
+
componentsOuter = props?.components || components;
|
|
257
|
+
}
|
|
258
|
+
if (!utilitiesOuter) {
|
|
259
|
+
utilitiesOuter = props?.utilities;
|
|
260
|
+
}
|
|
261
|
+
console.log('Props for ${componentName}:', props);
|
|
262
|
+
console.log('components for ${componentName}:', componentsOuter);
|
|
263
|
+
console.log('styles for ${componentName}:', styles);
|
|
264
|
+
console.log('utilities for ${componentName}:', utilitiesOuter);
|
|
265
|
+
console.log('libraries for ${componentName}:', libraries);
|
|
266
|
+
${libraryDeclarations ? '// Destructure Libraries\n' + libraryDeclarations + '\n ' : ''}
|
|
267
|
+
${componentDeclarations ? '// Destructure Dependencies\n' + componentDeclarations + '\n ' : ''}
|
|
268
|
+
${libraryLogChecks}
|
|
269
|
+
${componentLogChecks}
|
|
270
|
+
|
|
271
|
+
const newProps = {
|
|
272
|
+
...props,
|
|
273
|
+
components: componentsOuter,
|
|
274
|
+
utilities: utilitiesOuter
|
|
275
|
+
}
|
|
276
|
+
return ActualComponent(newProps);
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
// Create a fresh method registry for each factory call
|
|
280
|
+
const methodRegistry = new Map();
|
|
281
|
+
|
|
282
|
+
// Create a wrapper component that provides RegisterMethod in callbacks
|
|
283
|
+
const ComponentWithMethodRegistry = (props) => {
|
|
284
|
+
// Register methods on mount
|
|
285
|
+
React.useEffect(() => {
|
|
286
|
+
// Clear previous methods
|
|
287
|
+
methodRegistry.clear();
|
|
288
|
+
|
|
289
|
+
// Provide RegisterMethod callback if callbacks exist
|
|
290
|
+
if (props.callbacks && typeof props.callbacks.RegisterMethod === 'function') {
|
|
291
|
+
// Component can now register its methods
|
|
292
|
+
// This will be called from within the component
|
|
293
|
+
}
|
|
294
|
+
}, [props.callbacks]);
|
|
295
|
+
|
|
296
|
+
// Create enhanced callbacks with RegisterMethod
|
|
297
|
+
const enhancedCallbacks = React.useMemo(() => {
|
|
298
|
+
if (!props.callbacks) return {};
|
|
299
|
+
|
|
300
|
+
return {
|
|
301
|
+
...props.callbacks,
|
|
302
|
+
RegisterMethod: (methodName, handler) => {
|
|
303
|
+
if (methodName && handler) {
|
|
304
|
+
methodRegistry.set(methodName, handler);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
}, [props.callbacks]);
|
|
309
|
+
|
|
310
|
+
// Render the original component with enhanced callbacks
|
|
311
|
+
return React.createElement(DestructureWrapperUserComponent, {
|
|
312
|
+
...props,
|
|
313
|
+
callbacks: enhancedCallbacks
|
|
314
|
+
});
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
ComponentWithMethodRegistry.displayName = '${componentName}WithMethods';
|
|
318
|
+
|
|
319
|
+
// Return the component object with method access
|
|
202
320
|
return {
|
|
203
|
-
component:
|
|
321
|
+
component: ComponentWithMethodRegistry,
|
|
322
|
+
|
|
204
323
|
print: function() {
|
|
205
|
-
|
|
324
|
+
const printMethod = methodRegistry.get('print');
|
|
325
|
+
if (printMethod) {
|
|
326
|
+
printMethod();
|
|
327
|
+
} else if (typeof window !== 'undefined' && window.print) {
|
|
206
328
|
window.print();
|
|
207
329
|
}
|
|
208
330
|
},
|
|
209
331
|
refresh: function(data) {
|
|
332
|
+
const refreshMethod = methodRegistry.get('refresh');
|
|
333
|
+
if (refreshMethod) {
|
|
334
|
+
refreshMethod(data);
|
|
335
|
+
}
|
|
210
336
|
// Refresh functionality is handled by the host environment
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
// Standard method accessors with type safety
|
|
340
|
+
getCurrentDataState: function() {
|
|
341
|
+
const method = methodRegistry.get('getCurrentDataState');
|
|
342
|
+
return method ? method() : undefined;
|
|
343
|
+
},
|
|
344
|
+
getDataStateHistory: function() {
|
|
345
|
+
const method = methodRegistry.get('getDataStateHistory');
|
|
346
|
+
return method ? method() : [];
|
|
347
|
+
},
|
|
348
|
+
validate: function() {
|
|
349
|
+
const method = methodRegistry.get('validate');
|
|
350
|
+
return method ? method() : true;
|
|
351
|
+
},
|
|
352
|
+
isDirty: function() {
|
|
353
|
+
const method = methodRegistry.get('isDirty');
|
|
354
|
+
return method ? method() : false;
|
|
355
|
+
},
|
|
356
|
+
reset: function() {
|
|
357
|
+
const method = methodRegistry.get('reset');
|
|
358
|
+
if (method) method();
|
|
359
|
+
},
|
|
360
|
+
scrollTo: function(target) {
|
|
361
|
+
const method = methodRegistry.get('scrollTo');
|
|
362
|
+
if (method) method(target);
|
|
363
|
+
},
|
|
364
|
+
focus: function(target) {
|
|
365
|
+
const method = methodRegistry.get('focus');
|
|
366
|
+
if (method) method(target);
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
// Generic method invoker for custom methods
|
|
370
|
+
invokeMethod: function(methodName, ...args) {
|
|
371
|
+
const method = methodRegistry.get(methodName);
|
|
372
|
+
if (method) {
|
|
373
|
+
return method(...args);
|
|
374
|
+
}
|
|
375
|
+
console.warn(\`[React-Runtime-JS] Method '\${methodName}' is not registered on component ${componentName}\`);
|
|
376
|
+
return undefined;
|
|
377
|
+
},
|
|
378
|
+
|
|
379
|
+
// Check if a method exists
|
|
380
|
+
hasMethod: function(methodName) {
|
|
381
|
+
return methodRegistry.has(methodName);
|
|
211
382
|
}
|
|
212
383
|
};
|
|
213
384
|
}
|
|
214
385
|
`;
|
|
386
|
+
|
|
387
|
+
return wrappedCode;
|
|
215
388
|
}
|
|
216
389
|
|
|
217
390
|
/**
|
|
218
|
-
* Load required libraries from the registry
|
|
391
|
+
* Load required libraries from the registry with dependency resolution
|
|
219
392
|
* @param libraries - Array of library dependencies
|
|
220
|
-
* @param
|
|
393
|
+
* @param componentLibraries - All available component libraries for dependency resolution
|
|
221
394
|
* @returns Map of loaded libraries
|
|
222
395
|
*/
|
|
223
396
|
private async loadRequiredLibraries(libraries: any[], componentLibraries: ComponentLibraryEntity[]): Promise<Map<string, any>> {
|
|
224
397
|
const loadedLibraries = new Map<string, any>();
|
|
225
398
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
399
|
+
if (this.config.debug) {
|
|
400
|
+
console.log('đ loadRequiredLibraries called with:', {
|
|
401
|
+
librariesCount: libraries?.length || 0,
|
|
402
|
+
libraries: libraries?.map(l => ({ name: l.name, version: l.version, globalVariable: l.globalVariable }))
|
|
403
|
+
});
|
|
404
|
+
}
|
|
230
405
|
|
|
231
406
|
if (!libraries || libraries.length === 0) {
|
|
232
|
-
|
|
407
|
+
if (this.config.debug) {
|
|
408
|
+
console.log('đ No libraries to load, returning empty map');
|
|
409
|
+
}
|
|
233
410
|
return loadedLibraries;
|
|
234
411
|
}
|
|
235
412
|
|
|
@@ -246,75 +423,90 @@ export class ComponentCompiler {
|
|
|
246
423
|
console.warn('â ī¸ No componentLibraries provided for LibraryRegistry initialization');
|
|
247
424
|
}
|
|
248
425
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
if (!isApproved) {
|
|
257
|
-
console.error(` â Library '${lib.name}' is not approved`);
|
|
258
|
-
throw new Error(`Library '${lib.name}' is not approved. Only approved libraries can be used.`);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// Get library definition for complete info
|
|
262
|
-
const libraryDef = LibraryRegistry.getLibrary(lib.name);
|
|
263
|
-
console.log(` â Library definition found for ${lib.name}: ${!!libraryDef}`);
|
|
264
|
-
|
|
265
|
-
if (!libraryDef) {
|
|
266
|
-
console.error(` â Library '${lib.name}' not found in registry`);
|
|
267
|
-
throw new Error(`Library '${lib.name}' not found in registry`);
|
|
268
|
-
}
|
|
426
|
+
// Extract library names from the requested libraries
|
|
427
|
+
const libraryNames = libraries.map(lib => lib.name);
|
|
428
|
+
|
|
429
|
+
if (this.config.debug) {
|
|
430
|
+
console.log('đĻ Using dependency-aware loading for libraries:', libraryNames);
|
|
431
|
+
}
|
|
269
432
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
console.error(` â No CDN URL found for library '${lib.name}' version '${lib.version || 'default'}'`);
|
|
279
|
-
throw new Error(`No CDN URL found for library '${lib.name}' version '${lib.version || 'default'}'`);
|
|
280
|
-
}
|
|
433
|
+
try {
|
|
434
|
+
// Use the new dependency-aware loading
|
|
435
|
+
const loadedLibraryMap = await LibraryLoader.loadLibrariesWithDependencies(
|
|
436
|
+
libraryNames,
|
|
437
|
+
componentLibraries,
|
|
438
|
+
'component-compiler',
|
|
439
|
+
{ debug: this.config.debug }
|
|
440
|
+
);
|
|
281
441
|
|
|
282
|
-
//
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
442
|
+
// Map the results to match the expected format
|
|
443
|
+
// We need to map from library name to global variable
|
|
444
|
+
for (const lib of libraries) {
|
|
445
|
+
// Check if library is approved first
|
|
446
|
+
const isApproved = LibraryRegistry.isApproved(lib.name);
|
|
447
|
+
if (!isApproved) {
|
|
448
|
+
console.error(`â Library '${lib.name}' is not approved`);
|
|
449
|
+
throw new Error(`Library '${lib.name}' is not approved. Only approved libraries can be used.`);
|
|
450
|
+
}
|
|
288
451
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
452
|
+
// Get the loaded library from the map
|
|
453
|
+
const loadedValue = loadedLibraryMap.get(lib.name);
|
|
454
|
+
|
|
455
|
+
if (loadedValue) {
|
|
456
|
+
// Store by global variable name for component access
|
|
457
|
+
loadedLibraries.set(lib.globalVariable, loadedValue);
|
|
458
|
+
if (this.config.debug) {
|
|
459
|
+
console.log(`â
Mapped ${lib.name} to global variable ${lib.globalVariable}`);
|
|
460
|
+
}
|
|
461
|
+
} else {
|
|
462
|
+
// Fallback: check if it's already globally available (might be a dependency)
|
|
463
|
+
const globalValue = (window as any)[lib.globalVariable];
|
|
464
|
+
if (globalValue) {
|
|
465
|
+
loadedLibraries.set(lib.globalVariable, globalValue);
|
|
466
|
+
if (this.config.debug) {
|
|
467
|
+
console.log(`â
Found ${lib.name} already loaded as ${lib.globalVariable}`);
|
|
468
|
+
}
|
|
469
|
+
} else {
|
|
470
|
+
console.error(`â Library '${lib.name}' failed to load`);
|
|
471
|
+
throw new Error(`Library '${lib.name}' failed to load or did not expose '${lib.globalVariable}'`);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
293
474
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
console.log(` đĨ Loading script from CDN for ${lib.name}...`);
|
|
297
|
-
await this.loadScript(cdnUrl!, lib.globalVariable);
|
|
475
|
+
} catch (error: any) {
|
|
476
|
+
console.error('Failed to load libraries with dependencies:', error);
|
|
298
477
|
|
|
299
|
-
//
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
console.log(` â Library ${lib.name} loaded successfully, global variable ${lib.globalVariable} is:`, typeof libraryValue);
|
|
478
|
+
// Fallback to old loading method if dependency resolution fails
|
|
479
|
+
if (this.config.debug) {
|
|
480
|
+
console.warn('â ī¸ Falling back to non-dependency-aware loading due to error');
|
|
481
|
+
}
|
|
304
482
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
483
|
+
// Load each library independently (old method)
|
|
484
|
+
for (const lib of libraries) {
|
|
485
|
+
if ((window as any)[lib.globalVariable]) {
|
|
486
|
+
loadedLibraries.set(lib.globalVariable, (window as any)[lib.globalVariable]);
|
|
487
|
+
} else {
|
|
488
|
+
// Try to load using LibraryRegistry
|
|
489
|
+
const libraryDef = LibraryRegistry.getLibrary(lib.name);
|
|
490
|
+
if (libraryDef) {
|
|
491
|
+
const resolvedVersion = LibraryRegistry.resolveVersion(lib.name, lib.version);
|
|
492
|
+
const cdnUrl = LibraryRegistry.getCdnUrl(lib.name, resolvedVersion);
|
|
493
|
+
|
|
494
|
+
if (cdnUrl) {
|
|
495
|
+
await this.loadScript(cdnUrl, lib.globalVariable);
|
|
496
|
+
const libraryValue = (window as any)[lib.globalVariable];
|
|
497
|
+
if (libraryValue) {
|
|
498
|
+
loadedLibraries.set(lib.globalVariable, libraryValue);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
311
503
|
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
await Promise.all(loadPromises);
|
|
504
|
+
}
|
|
315
505
|
|
|
316
|
-
|
|
317
|
-
|
|
506
|
+
if (this.config.debug) {
|
|
507
|
+
console.log(`â
All libraries loaded successfully. Total: ${loadedLibraries.size}`);
|
|
508
|
+
console.log('đ Loaded libraries map:', Array.from(loadedLibraries.keys()));
|
|
509
|
+
}
|
|
318
510
|
|
|
319
511
|
return loadedLibraries;
|
|
320
512
|
}
|
|
@@ -390,12 +582,18 @@ export class ComponentCompiler {
|
|
|
390
582
|
|
|
391
583
|
const checkGlobal = () => {
|
|
392
584
|
if ((window as any)[globalName]) {
|
|
393
|
-
|
|
585
|
+
if (this.config.debug) {
|
|
586
|
+
console.log(` â Global variable ${globalName} found after ${attempts * checkInterval}ms`);
|
|
587
|
+
}
|
|
394
588
|
resolve();
|
|
395
589
|
} else if (attempts >= maxAttempts) {
|
|
396
590
|
// Final check - some libraries might use a different global name pattern
|
|
397
|
-
|
|
398
|
-
|
|
591
|
+
if (this.config.debug) {
|
|
592
|
+
console.error(` â ${globalName} not found after ${attempts * checkInterval}ms`);
|
|
593
|
+
// Only log matching property names, not the entire window object
|
|
594
|
+
const matchingKeys = Object.keys(window).filter(k => k.toLowerCase().includes(globalName.toLowerCase()));
|
|
595
|
+
console.log(` âšī¸ Matching window properties: ${matchingKeys.join(', ') || 'none'}`);
|
|
596
|
+
}
|
|
399
597
|
reject(new Error(`${globalName} not found after loading script from ${url}`));
|
|
400
598
|
} else {
|
|
401
599
|
attempts++;
|
|
@@ -426,7 +624,7 @@ export class ComponentCompiler {
|
|
|
426
624
|
transpiledCode: string,
|
|
427
625
|
componentName: string,
|
|
428
626
|
loadedLibraries: Map<string, any>
|
|
429
|
-
):
|
|
627
|
+
): (context: RuntimeContext, styles?: ComponentStyles) => ComponentObject {
|
|
430
628
|
try {
|
|
431
629
|
// Create the factory function with all React hooks
|
|
432
630
|
const factoryCreator = new Function(
|
package/src/index.ts
CHANGED
|
@@ -29,7 +29,8 @@ export { ComponentRegistry } from './registry';
|
|
|
29
29
|
export {
|
|
30
30
|
ComponentResolver,
|
|
31
31
|
ComponentSpec,
|
|
32
|
-
ResolvedComponents
|
|
32
|
+
ResolvedComponents,
|
|
33
|
+
ComponentRegistryService
|
|
33
34
|
} from './registry';
|
|
34
35
|
|
|
35
36
|
// Export runtime APIs
|
|
@@ -139,6 +140,7 @@ export const DEFAULT_CONFIGS = {
|
|
|
139
140
|
* @param babelInstance - Babel standalone instance for compilation
|
|
140
141
|
* @param config - Optional configuration overrides
|
|
141
142
|
* @param runtimeContext - Optional runtime context for registry-based components
|
|
143
|
+
* @param debug - Enable debug logging (defaults to false)
|
|
142
144
|
* @returns Object containing compiler, registry, and resolver instances
|
|
143
145
|
*/
|
|
144
146
|
export function createReactRuntime(
|
|
@@ -147,18 +149,31 @@ export function createReactRuntime(
|
|
|
147
149
|
compiler?: Partial<import('./types').CompilerConfig>;
|
|
148
150
|
registry?: Partial<import('./types').RegistryConfig>;
|
|
149
151
|
},
|
|
150
|
-
runtimeContext?: import('./types').RuntimeContext
|
|
152
|
+
runtimeContext?: import('./types').RuntimeContext,
|
|
153
|
+
debug: boolean = false
|
|
151
154
|
) {
|
|
152
|
-
|
|
155
|
+
// Merge debug flag into configs
|
|
156
|
+
const compilerConfig = {
|
|
157
|
+
...config?.compiler,
|
|
158
|
+
debug: config?.compiler?.debug ?? debug
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const registryConfig = {
|
|
162
|
+
...config?.registry,
|
|
163
|
+
debug: config?.registry?.debug ?? debug
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const compiler = new ComponentCompiler(compilerConfig);
|
|
153
167
|
compiler.setBabelInstance(babelInstance);
|
|
154
168
|
|
|
155
|
-
const registry = new ComponentRegistry(
|
|
169
|
+
const registry = new ComponentRegistry(registryConfig);
|
|
156
170
|
const resolver = new ComponentResolver(registry, compiler, runtimeContext);
|
|
157
171
|
|
|
158
172
|
return {
|
|
159
173
|
compiler,
|
|
160
174
|
registry,
|
|
161
175
|
resolver,
|
|
162
|
-
version: VERSION
|
|
176
|
+
version: VERSION,
|
|
177
|
+
debug
|
|
163
178
|
};
|
|
164
179
|
}
|