@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
|
@@ -11,6 +11,10 @@ import {
|
|
|
11
11
|
import { LibraryConfiguration, ExternalLibraryConfig, LibraryLoadOptions as ConfigLoadOptions } from '../types/library-config';
|
|
12
12
|
import { getCoreRuntimeLibraries, isCoreRuntimeLibrary } from './core-libraries';
|
|
13
13
|
import { resourceManager } from './resource-manager';
|
|
14
|
+
import { ComponentLibraryEntity } from '@memberjunction/core-entities';
|
|
15
|
+
import { LibraryDependencyResolver } from './library-dependency-resolver';
|
|
16
|
+
import { LoadedLibraryState, DependencyResolutionOptions } from '../types/dependency-types';
|
|
17
|
+
import { LibraryRegistry } from './library-registry';
|
|
14
18
|
|
|
15
19
|
// Unique component ID for resource tracking
|
|
16
20
|
const LIBRARY_LOADER_COMPONENT_ID = 'mj-react-runtime-library-loader-singleton';
|
|
@@ -53,6 +57,8 @@ export interface LibraryLoadResult {
|
|
|
53
57
|
*/
|
|
54
58
|
export class LibraryLoader {
|
|
55
59
|
private static loadedResources = new Map<string, LoadedResource>();
|
|
60
|
+
private static loadedLibraryStates = new Map<string, LoadedLibraryState>();
|
|
61
|
+
private static dependencyResolver = new LibraryDependencyResolver({ debug: false });
|
|
56
62
|
|
|
57
63
|
/**
|
|
58
64
|
* Load all standard libraries (core + UI + CSS)
|
|
@@ -383,8 +389,276 @@ export class LibraryLoader {
|
|
|
383
389
|
});
|
|
384
390
|
|
|
385
391
|
this.loadedResources.clear();
|
|
392
|
+
this.loadedLibraryStates.clear();
|
|
386
393
|
|
|
387
394
|
// Clean up any resources managed by resource manager
|
|
388
395
|
resourceManager.cleanupComponent(LIBRARY_LOADER_COMPONENT_ID);
|
|
389
396
|
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Load a library with its dependencies
|
|
400
|
+
* @param libraryName - Name of the library to load
|
|
401
|
+
* @param allLibraries - All available libraries for dependency resolution
|
|
402
|
+
* @param requestedBy - Name of the component/library requesting this load
|
|
403
|
+
* @param options - Dependency resolution options
|
|
404
|
+
* @returns Promise resolving to the loaded library global object
|
|
405
|
+
*/
|
|
406
|
+
static async loadLibraryWithDependencies(
|
|
407
|
+
libraryName: string,
|
|
408
|
+
allLibraries: ComponentLibraryEntity[],
|
|
409
|
+
requestedBy: string = 'user',
|
|
410
|
+
options?: DependencyResolutionOptions
|
|
411
|
+
): Promise<any> {
|
|
412
|
+
const debug = options?.debug || false;
|
|
413
|
+
|
|
414
|
+
if (debug) {
|
|
415
|
+
console.log(`📚 Loading library '${libraryName}' with dependencies`);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// Check if already loaded
|
|
419
|
+
const existingState = this.loadedLibraryStates.get(libraryName);
|
|
420
|
+
if (existingState) {
|
|
421
|
+
if (debug) {
|
|
422
|
+
console.log(`✅ Library '${libraryName}' already loaded (version: ${existingState.version})`);
|
|
423
|
+
}
|
|
424
|
+
// Track who requested it
|
|
425
|
+
if (!existingState.requestedBy.includes(requestedBy)) {
|
|
426
|
+
existingState.requestedBy.push(requestedBy);
|
|
427
|
+
}
|
|
428
|
+
return (window as any)[existingState.globalVariable];
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Get load order including dependencies
|
|
432
|
+
const loadOrderResult = this.dependencyResolver.getLoadOrder(
|
|
433
|
+
[libraryName],
|
|
434
|
+
allLibraries,
|
|
435
|
+
options
|
|
436
|
+
);
|
|
437
|
+
|
|
438
|
+
if (!loadOrderResult.success) {
|
|
439
|
+
const errors = loadOrderResult.errors?.join(', ') || 'Unknown error';
|
|
440
|
+
throw new Error(`Failed to resolve dependencies for '${libraryName}': ${errors}`);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (loadOrderResult.warnings && debug) {
|
|
444
|
+
console.warn(`⚠️ Warnings for '${libraryName}':`, loadOrderResult.warnings);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
const loadOrder = loadOrderResult.order || [];
|
|
448
|
+
if (debug) {
|
|
449
|
+
console.log(`📋 Load order for '${libraryName}':`, loadOrder.map(lib => `${lib.Name}@${lib.Version}`));
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// Load libraries in order
|
|
453
|
+
for (const library of loadOrder) {
|
|
454
|
+
// Skip if already loaded
|
|
455
|
+
if (this.loadedLibraryStates.has(library.Name)) {
|
|
456
|
+
if (debug) {
|
|
457
|
+
console.log(`⏭️ Skipping '${library.Name}' (already loaded)`);
|
|
458
|
+
}
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
if (debug) {
|
|
463
|
+
console.log(`📥 Loading '${library.Name}@${library.Version}'`);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// Load the library
|
|
467
|
+
if (!library.CDNUrl || !library.GlobalVariable) {
|
|
468
|
+
throw new Error(`Library '${library.Name}' missing CDN URL or global variable`);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Load CSS if available
|
|
472
|
+
if (library.CDNCssUrl) {
|
|
473
|
+
const cssUrls = library.CDNCssUrl.split(',').map(url => url.trim());
|
|
474
|
+
for (const cssUrl of cssUrls) {
|
|
475
|
+
if (cssUrl) {
|
|
476
|
+
this.loadCSS(cssUrl);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Load the script
|
|
482
|
+
const loadedGlobal = await this.loadScript(library.CDNUrl, library.GlobalVariable);
|
|
483
|
+
|
|
484
|
+
// Track the loaded state
|
|
485
|
+
const dependencies = Array.from(
|
|
486
|
+
this.dependencyResolver.getDirectDependencies(library).keys()
|
|
487
|
+
);
|
|
488
|
+
|
|
489
|
+
this.loadedLibraryStates.set(library.Name, {
|
|
490
|
+
name: library.Name,
|
|
491
|
+
version: library.Version || 'unknown',
|
|
492
|
+
globalVariable: library.GlobalVariable,
|
|
493
|
+
loadedAt: new Date(),
|
|
494
|
+
requestedBy: library.Name === libraryName ? [requestedBy] : [],
|
|
495
|
+
dependencies
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
if (debug) {
|
|
499
|
+
console.log(`✅ Loaded '${library.Name}@${library.Version}'`);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Return the originally requested library's global
|
|
504
|
+
const targetLibrary = loadOrder.find(lib => lib.Name === libraryName);
|
|
505
|
+
if (!targetLibrary || !targetLibrary.GlobalVariable) {
|
|
506
|
+
throw new Error(`Failed to load library '${libraryName}'`);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
return (window as any)[targetLibrary.GlobalVariable];
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Load multiple libraries with dependency resolution
|
|
514
|
+
* @param libraryNames - Names of libraries to load
|
|
515
|
+
* @param allLibraries - All available libraries for dependency resolution
|
|
516
|
+
* @param requestedBy - Name of the component requesting these libraries
|
|
517
|
+
* @param options - Dependency resolution options
|
|
518
|
+
* @returns Map of library names to their loaded global objects
|
|
519
|
+
*/
|
|
520
|
+
static async loadLibrariesWithDependencies(
|
|
521
|
+
libraryNames: string[],
|
|
522
|
+
allLibraries: ComponentLibraryEntity[],
|
|
523
|
+
requestedBy: string = 'user',
|
|
524
|
+
options?: DependencyResolutionOptions
|
|
525
|
+
): Promise<Map<string, any>> {
|
|
526
|
+
const debug = options?.debug || false;
|
|
527
|
+
const result = new Map<string, any>();
|
|
528
|
+
|
|
529
|
+
if (debug) {
|
|
530
|
+
console.log(`📚 Loading libraries with dependencies:`, libraryNames);
|
|
531
|
+
console.log(` 📦 Total available libraries: ${allLibraries.length}`);
|
|
532
|
+
console.log(` 📋 Available library list:`, allLibraries.map(l => `${l.Name}@${l.Version}`));
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// Get combined load order for all requested libraries
|
|
536
|
+
const loadOrderResult = this.dependencyResolver.getLoadOrder(
|
|
537
|
+
libraryNames,
|
|
538
|
+
allLibraries,
|
|
539
|
+
options
|
|
540
|
+
);
|
|
541
|
+
|
|
542
|
+
if (!loadOrderResult.success) {
|
|
543
|
+
const errors = loadOrderResult.errors?.join(', ') || 'Unknown error';
|
|
544
|
+
throw new Error(`Failed to resolve dependencies: ${errors}`);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
if (debug) {
|
|
548
|
+
console.log(` 📊 Dependency resolution result:`, {
|
|
549
|
+
success: loadOrderResult.success,
|
|
550
|
+
errors: loadOrderResult.errors || [],
|
|
551
|
+
warnings: loadOrderResult.warnings || []
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
if (loadOrderResult.order) {
|
|
555
|
+
console.log(` 🔄 Resolved dependencies for each library:`);
|
|
556
|
+
loadOrderResult.order.forEach(lib => {
|
|
557
|
+
const deps = this.dependencyResolver.parseDependencies(lib.Dependencies);
|
|
558
|
+
if (deps.size > 0) {
|
|
559
|
+
console.log(` • ${lib.Name}@${lib.Version} requires:`, Array.from(deps.entries()));
|
|
560
|
+
} else {
|
|
561
|
+
console.log(` • ${lib.Name}@${lib.Version} (no dependencies)`);
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
if (loadOrderResult.warnings && debug) {
|
|
568
|
+
console.warn(` ⚠️ Warnings:`, loadOrderResult.warnings);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
const loadOrder = loadOrderResult.order || [];
|
|
572
|
+
if (debug) {
|
|
573
|
+
console.log(` 📋 Final load order:`, loadOrder.map(lib => `${lib.Name}@${lib.Version}`));
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// Load all libraries in order
|
|
577
|
+
for (const library of loadOrder) {
|
|
578
|
+
// Skip if already loaded
|
|
579
|
+
if (this.loadedLibraryStates.has(library.Name)) {
|
|
580
|
+
if (debug) {
|
|
581
|
+
console.log(`⏭️ Skipping '${library.Name}' (already loaded)`);
|
|
582
|
+
}
|
|
583
|
+
const state = this.loadedLibraryStates.get(library.Name)!;
|
|
584
|
+
if (libraryNames.includes(library.Name)) {
|
|
585
|
+
result.set(library.Name, (window as any)[state.globalVariable]);
|
|
586
|
+
}
|
|
587
|
+
continue;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
if (debug) {
|
|
591
|
+
console.log(`📥 Loading '${library.Name}@${library.Version}'`);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Load the library
|
|
595
|
+
if (!library.CDNUrl || !library.GlobalVariable) {
|
|
596
|
+
throw new Error(`Library '${library.Name}' missing CDN URL or global variable`);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// Load CSS if available
|
|
600
|
+
if (library.CDNCssUrl) {
|
|
601
|
+
const cssUrls = library.CDNCssUrl.split(',').map(url => url.trim());
|
|
602
|
+
for (const cssUrl of cssUrls) {
|
|
603
|
+
if (cssUrl) {
|
|
604
|
+
this.loadCSS(cssUrl);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// Load the script
|
|
610
|
+
const loadedGlobal = await this.loadScript(library.CDNUrl, library.GlobalVariable);
|
|
611
|
+
|
|
612
|
+
// Track the loaded state
|
|
613
|
+
const dependencies = Array.from(
|
|
614
|
+
this.dependencyResolver.getDirectDependencies(library).keys()
|
|
615
|
+
);
|
|
616
|
+
|
|
617
|
+
this.loadedLibraryStates.set(library.Name, {
|
|
618
|
+
name: library.Name,
|
|
619
|
+
version: library.Version || 'unknown',
|
|
620
|
+
globalVariable: library.GlobalVariable,
|
|
621
|
+
loadedAt: new Date(),
|
|
622
|
+
requestedBy: libraryNames.includes(library.Name) ? [requestedBy] : [],
|
|
623
|
+
dependencies
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
// Add to result if it was directly requested
|
|
627
|
+
if (libraryNames.includes(library.Name)) {
|
|
628
|
+
result.set(library.Name, loadedGlobal);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
if (debug) {
|
|
632
|
+
console.log(`✅ Loaded '${library.Name}@${library.Version}'`);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
return result;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Get information about loaded libraries
|
|
641
|
+
* @returns Map of loaded library states
|
|
642
|
+
*/
|
|
643
|
+
static getLoadedLibraryStates(): Map<string, LoadedLibraryState> {
|
|
644
|
+
return new Map(this.loadedLibraryStates);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Check if a library is loaded
|
|
649
|
+
* @param libraryName - Name of the library
|
|
650
|
+
* @returns True if the library is loaded
|
|
651
|
+
*/
|
|
652
|
+
static isLibraryLoaded(libraryName: string): boolean {
|
|
653
|
+
return this.loadedLibraryStates.has(libraryName);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Get the version of a loaded library
|
|
658
|
+
* @param libraryName - Name of the library
|
|
659
|
+
* @returns Version string or undefined if not loaded
|
|
660
|
+
*/
|
|
661
|
+
static getLoadedLibraryVersion(libraryName: string): string | undefined {
|
|
662
|
+
return this.loadedLibraryStates.get(libraryName)?.version;
|
|
663
|
+
}
|
|
390
664
|
}
|