@memberjunction/react-runtime 5.33.0 → 5.34.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 +14 -14
- package/CHANGELOG.md +21 -0
- package/dist/324.runtime.umd.js +148 -103
- package/dist/component-manager/component-manager.d.ts.map +1 -1
- package/dist/component-manager/component-manager.js +16 -11
- package/dist/component-manager/component-manager.js.map +1 -1
- package/dist/registry/component-registry-service.d.ts.map +1 -1
- package/dist/registry/component-registry-service.js +5 -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 +3 -21
- package/dist/registry/component-resolver.js.map +1 -1
- package/dist/runtime.umd.js +4554 -2577
- package/package.json +6 -6
- package/src/component-manager/component-manager.ts +36 -41
- package/src/registry/component-registry-service.ts +14 -20
- package/src/registry/component-resolver.ts +11 -32
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/react-runtime",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.34.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
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://github.com/MemberJunction/MJ#readme",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@memberjunction/core": "5.
|
|
33
|
-
"@memberjunction/global": "5.
|
|
34
|
-
"@memberjunction/interactive-component-types": "5.
|
|
35
|
-
"@memberjunction/core-entities": "5.
|
|
36
|
-
"@memberjunction/graphql-dataprovider": "5.
|
|
32
|
+
"@memberjunction/core": "5.34.0",
|
|
33
|
+
"@memberjunction/global": "5.34.0",
|
|
34
|
+
"@memberjunction/interactive-component-types": "5.34.0",
|
|
35
|
+
"@memberjunction/core-entities": "5.34.0",
|
|
36
|
+
"@memberjunction/graphql-dataprovider": "5.34.0",
|
|
37
37
|
"@babel/standalone": "^7.29.1",
|
|
38
38
|
"rxjs": "^7.8.2"
|
|
39
39
|
},
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { ComponentSpec, ComponentLibraryDependency } from '@memberjunction/interactive-component-types';
|
|
7
7
|
import { UserInfo, Metadata, LogError } from '@memberjunction/core';
|
|
8
|
-
import { ComponentMetadataEngine, MJComponentLibraryEntity
|
|
8
|
+
import { ComponentMetadataEngine, MJComponentLibraryEntity } from '@memberjunction/core-entities';
|
|
9
9
|
|
|
10
10
|
import { ComponentCompiler } from '../compiler';
|
|
11
11
|
import { ComponentRegistry } from '../registry';
|
|
@@ -515,87 +515,82 @@ export class ComponentManager {
|
|
|
515
515
|
// Check cache first
|
|
516
516
|
const cacheKey = this.getComponentKey(spec, {});
|
|
517
517
|
const cached = this.fetchCache.get(cacheKey);
|
|
518
|
-
|
|
518
|
+
|
|
519
519
|
if (cached && this.isCacheValid(cached)) {
|
|
520
520
|
this.log(`Using cached spec for: ${spec.name}`);
|
|
521
521
|
return cached.spec;
|
|
522
522
|
}
|
|
523
|
-
|
|
523
|
+
|
|
524
524
|
// Handle LOCAL registry components (registry is null/undefined)
|
|
525
525
|
if (!spec.registry) {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
// Find component in local ComponentMetadataEngine
|
|
529
|
-
const localComponent = this.componentEngine.Components?.find(
|
|
530
|
-
(c: MJComponentEntityExtended) => {
|
|
531
|
-
// Match by name (case-insensitive for better compatibility)
|
|
532
|
-
const nameMatch = c.Name?.toLowerCase() === spec.name?.toLowerCase();
|
|
533
|
-
|
|
534
|
-
// Match by namespace if provided (handle different formats)
|
|
535
|
-
const namespaceMatch = !spec.namespace || c.Namespace?.toLowerCase() === spec.namespace?.toLowerCase();
|
|
526
|
+
const localComponent = await this.componentEngine.FindComponent(spec.name, spec.namespace);
|
|
536
527
|
|
|
537
|
-
if (nameMatch && !namespaceMatch) {
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
return nameMatch && namespaceMatch;
|
|
541
|
-
}
|
|
542
|
-
);
|
|
543
|
-
|
|
544
528
|
if (!localComponent) {
|
|
545
529
|
throw new Error(`Local component not found: ${spec.name}`);
|
|
546
530
|
}
|
|
547
|
-
|
|
548
|
-
// Parse specification from local component
|
|
531
|
+
|
|
549
532
|
if (!localComponent.Specification) {
|
|
550
533
|
throw new Error(`Local component ${spec.name} has no specification`);
|
|
551
534
|
}
|
|
552
|
-
|
|
535
|
+
|
|
553
536
|
const fullSpec = JSON.parse(localComponent.Specification);
|
|
554
|
-
|
|
555
|
-
// Cache it
|
|
537
|
+
|
|
556
538
|
this.fetchCache.set(cacheKey, {
|
|
557
539
|
spec: fullSpec,
|
|
558
540
|
fetchedAt: new Date(),
|
|
559
541
|
usageNotified: false
|
|
560
542
|
});
|
|
561
|
-
|
|
543
|
+
|
|
562
544
|
return fullSpec;
|
|
563
545
|
}
|
|
564
|
-
|
|
546
|
+
|
|
565
547
|
// Handle EXTERNAL registry components (registry has a name)
|
|
566
|
-
// Initialize GraphQL client if needed
|
|
567
548
|
if (!this.graphQLClient) {
|
|
568
549
|
await this.initializeGraphQLClient();
|
|
569
550
|
}
|
|
570
|
-
|
|
551
|
+
|
|
571
552
|
if (!this.graphQLClient) {
|
|
572
553
|
throw new Error('GraphQL client not available for registry fetching');
|
|
573
554
|
}
|
|
574
|
-
|
|
575
|
-
// Fetch from external registry
|
|
555
|
+
|
|
556
|
+
// Fetch from external registry, passing the cached hash (if any) so the
|
|
557
|
+
// server can return 304 Not Modified when the spec hasn't changed
|
|
576
558
|
this.log(`Fetching from external registry: ${spec.registry}/${spec.name}`);
|
|
577
|
-
|
|
578
|
-
|
|
559
|
+
const cachedHash = cached?.hash;
|
|
560
|
+
|
|
561
|
+
const response = await this.graphQLClient.GetRegistryComponentWithHash({
|
|
579
562
|
registryName: spec.registry,
|
|
580
563
|
namespace: spec.namespace || 'Global',
|
|
581
564
|
name: spec.name,
|
|
582
|
-
version: spec.version || 'latest'
|
|
565
|
+
version: spec.version || 'latest',
|
|
566
|
+
hash: cachedHash
|
|
583
567
|
});
|
|
584
|
-
|
|
585
|
-
|
|
568
|
+
|
|
569
|
+
// If not modified (304), reuse the cached spec and refresh the TTL
|
|
570
|
+
if (response.notModified && cached) {
|
|
571
|
+
this.log(`Registry returned 304 for ${spec.name}, reusing cached spec`);
|
|
572
|
+
this.fetchCache.set(cacheKey, {
|
|
573
|
+
...cached,
|
|
574
|
+
fetchedAt: new Date()
|
|
575
|
+
});
|
|
576
|
+
return cached.spec;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
if (!response.specification) {
|
|
586
580
|
throw new Error(`Component not found in registry: ${spec.registry}/${spec.name}`);
|
|
587
581
|
}
|
|
588
|
-
|
|
589
|
-
|
|
582
|
+
|
|
583
|
+
const fullSpec = response.specification as ComponentSpec;
|
|
590
584
|
const processedSpec = this.applyResolutionMode(fullSpec, spec, options?.resolutionMode);
|
|
591
|
-
|
|
592
|
-
// Cache it
|
|
585
|
+
|
|
586
|
+
// Cache it with the registry hash for future 304 checks
|
|
593
587
|
this.fetchCache.set(cacheKey, {
|
|
594
588
|
spec: processedSpec,
|
|
595
589
|
fetchedAt: new Date(),
|
|
590
|
+
hash: response.hash,
|
|
596
591
|
usageNotified: false
|
|
597
592
|
});
|
|
598
|
-
|
|
593
|
+
|
|
599
594
|
return processedSpec;
|
|
600
595
|
}
|
|
601
596
|
|
|
@@ -232,8 +232,8 @@ export class ComponentRegistryService {
|
|
|
232
232
|
): Promise<ComponentObject> {
|
|
233
233
|
await this.initialize(contextUser);
|
|
234
234
|
|
|
235
|
-
// Find component in metadata
|
|
236
|
-
const component = this.componentEngine.
|
|
235
|
+
// Find component in metadata via targeted query
|
|
236
|
+
const component = await this.componentEngine.FindComponentByID(componentId, contextUser);
|
|
237
237
|
if (!component) {
|
|
238
238
|
throw new Error(`Component not found: ${componentId}`);
|
|
239
239
|
}
|
|
@@ -487,7 +487,7 @@ export class ComponentRegistryService {
|
|
|
487
487
|
): Promise<ComponentSpec> {
|
|
488
488
|
await this.initialize(contextUser);
|
|
489
489
|
|
|
490
|
-
const component = this.componentEngine.
|
|
490
|
+
const component = await this.componentEngine.FindComponentByID(componentId, contextUser);
|
|
491
491
|
if (!component) {
|
|
492
492
|
throw new Error(`Component not found: ${componentId}`);
|
|
493
493
|
}
|
|
@@ -697,16 +697,14 @@ export class ComponentRegistryService {
|
|
|
697
697
|
|
|
698
698
|
for (const dep of dependencies) {
|
|
699
699
|
// Find the dependency component
|
|
700
|
-
const depComponent = this.componentEngine.
|
|
701
|
-
|
|
702
|
-
);
|
|
703
|
-
|
|
700
|
+
const depComponent = await this.componentEngine.FindComponentByID(dep.DependencyComponentID, contextUser);
|
|
701
|
+
|
|
704
702
|
if (depComponent) {
|
|
705
703
|
result.push({
|
|
706
704
|
name: depComponent.Name,
|
|
707
705
|
namespace: depComponent.Namespace || '',
|
|
708
|
-
version: depComponent.Version,
|
|
709
|
-
isRequired: true,
|
|
706
|
+
version: depComponent.Version,
|
|
707
|
+
isRequired: true,
|
|
710
708
|
location: depComponent.SourceRegistryID ? 'registry' : 'embedded',
|
|
711
709
|
sourceRegistryID: depComponent.SourceRegistryID
|
|
712
710
|
});
|
|
@@ -734,27 +732,23 @@ export class ComponentRegistryService {
|
|
|
734
732
|
|
|
735
733
|
await this.initialize(contextUser);
|
|
736
734
|
|
|
737
|
-
const component = this.componentEngine.
|
|
735
|
+
const component = await this.componentEngine.FindComponentByID(componentId, contextUser);
|
|
738
736
|
if (!component) {
|
|
739
737
|
return { componentId, dependencies: [] };
|
|
740
738
|
}
|
|
741
|
-
|
|
739
|
+
|
|
742
740
|
// Get direct dependencies
|
|
743
741
|
const directDeps = await this.loadDependencies(componentId, contextUser);
|
|
744
|
-
|
|
742
|
+
|
|
745
743
|
// Recursively resolve each dependency
|
|
746
744
|
const dependencies: DependencyTree[] = [];
|
|
747
745
|
for (const dep of directDeps) {
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
c => c.Name.trim().toLowerCase() === dep.name.trim().toLowerCase() &&
|
|
751
|
-
c.Namespace?.trim().toLowerCase() === dep.namespace?.trim().toLowerCase()
|
|
752
|
-
);
|
|
753
|
-
|
|
746
|
+
const depComponent = await this.componentEngine.FindComponent(dep.name, dep.namespace, undefined, contextUser);
|
|
747
|
+
|
|
754
748
|
if (depComponent) {
|
|
755
749
|
const subTree = await this.resolveDependencyTree(
|
|
756
|
-
depComponent.ID,
|
|
757
|
-
contextUser,
|
|
750
|
+
depComponent.ID,
|
|
751
|
+
contextUser,
|
|
758
752
|
visited
|
|
759
753
|
);
|
|
760
754
|
dependencies.push(subTree);
|
|
@@ -95,7 +95,7 @@ export class ComponentResolver {
|
|
|
95
95
|
}
|
|
96
96
|
await this.componentEngine.Config(false, contextUser);
|
|
97
97
|
if (this.debug) {
|
|
98
|
-
console.log(`✅ [ComponentResolver] Component engine initialized
|
|
98
|
+
console.log(`✅ [ComponentResolver] Component engine initialized`);
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -243,36 +243,18 @@ export class ComponentResolver {
|
|
|
243
243
|
console.error(`❌ [ComponentResolver] Failed to fetch from external registry: ${spec.name} from ${spec.registry}`);
|
|
244
244
|
}
|
|
245
245
|
} else {
|
|
246
|
-
// LOCAL REGISTRY: Get from local database
|
|
246
|
+
// LOCAL REGISTRY: Get from local database via targeted RunView
|
|
247
247
|
if (this.debug) {
|
|
248
|
-
console.log(`💾 [ComponentResolver] Looking for locally registered component`);
|
|
248
|
+
console.log(`💾 [ComponentResolver] Looking for locally registered component: ${spec.name}`);
|
|
249
249
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
// Log all matching names to see duplicates
|
|
258
|
-
const matchingNames = allComponents.filter((c: any) => c.Name === spec.name);
|
|
259
|
-
if (matchingNames.length > 0 && this.debug) {
|
|
260
|
-
console.log(`🔎 [ComponentResolver] Found ${matchingNames.length} components with name "${spec.name}":`,
|
|
261
|
-
matchingNames.map((c: any) => ({
|
|
262
|
-
ID: c.ID,
|
|
263
|
-
Name: c.Name,
|
|
264
|
-
Namespace: c.Namespace,
|
|
265
|
-
Version: c.Version,
|
|
266
|
-
Status: c.Status
|
|
267
|
-
}))
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const component = this.componentEngine.Components?.find(
|
|
272
|
-
(c: any) => c.Name === spec.name &&
|
|
273
|
-
c.Namespace === (spec.namespace || namespace)
|
|
250
|
+
|
|
251
|
+
const component = await this.componentEngine.FindComponent(
|
|
252
|
+
spec.name,
|
|
253
|
+
spec.namespace || namespace,
|
|
254
|
+
undefined,
|
|
255
|
+
contextUser
|
|
274
256
|
);
|
|
275
|
-
|
|
257
|
+
|
|
276
258
|
if (component) {
|
|
277
259
|
if (this.debug) {
|
|
278
260
|
console.log(`✅ [ComponentResolver] Found component in local DB:`, {
|
|
@@ -282,7 +264,7 @@ export class ComponentResolver {
|
|
|
282
264
|
Version: component.Version
|
|
283
265
|
});
|
|
284
266
|
}
|
|
285
|
-
|
|
267
|
+
|
|
286
268
|
// Get compiled component from registry service (local compilation)
|
|
287
269
|
const compiledComponent = await this.registryService.getCompiledComponent(
|
|
288
270
|
component.ID,
|
|
@@ -295,9 +277,6 @@ export class ComponentResolver {
|
|
|
295
277
|
}
|
|
296
278
|
} else {
|
|
297
279
|
console.error(`❌ [ComponentResolver] Local registry component NOT found in database: ${spec.name} with namespace: ${spec.namespace || namespace}`);
|
|
298
|
-
if (this.debug) {
|
|
299
|
-
console.warn(`Local registry component not found in database: ${spec.name}`);
|
|
300
|
-
}
|
|
301
280
|
}
|
|
302
281
|
}
|
|
303
282
|
} catch (error) {
|