UNPKG

@memberjunction/react-runtime

Version:

Platform-agnostic React component runtime for MemberJunction. Provides core compilation, registry, and execution capabilities for React components in any JavaScript environment.

176 lines 7.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.countComponentsInHierarchy = exports.flattenComponentHierarchy = exports.validateComponentSpec = exports.registerComponentHierarchy = exports.ComponentHierarchyRegistrar = void 0; class ComponentHierarchyRegistrar { constructor(compiler, registry, runtimeContext) { this.compiler = compiler; this.registry = registry; this.runtimeContext = runtimeContext; } async registerHierarchy(rootSpec, options) { const { styles, namespace = 'Global', version = 'v1', continueOnError = true, allowOverride = true } = options; console.log('🌳 ComponentHierarchyRegistrar.registerHierarchy:', { rootComponent: rootSpec.name, hasLibraries: !!(rootSpec.libraries && rootSpec.libraries.length > 0), libraryCount: rootSpec.libraries?.length || 0, libraries: rootSpec.libraries?.map(l => l.name) }); const registeredComponents = []; const errors = []; const warnings = []; const rootResult = await this.registerSingleComponent(rootSpec, { styles, namespace, version, allowOverride, allLibraries: options.allLibraries }); if (rootResult.success) { registeredComponents.push(rootSpec.name); } else { errors.push(rootResult.error); if (!continueOnError) { return { success: false, registeredComponents, errors, warnings }; } } const childComponents = rootSpec.dependencies || []; if (childComponents.length > 0) { const childResult = await this.registerChildComponents(childComponents, { styles, namespace, version, continueOnError, allowOverride, allLibraries: options.allLibraries }, registeredComponents, errors, warnings); } return { success: errors.length === 0, registeredComponents, errors, warnings }; } async registerSingleComponent(spec, options) { const { styles, namespace = 'Global', version = 'v1', allowOverride = true } = options; try { if (!spec.code) { return { success: true, error: undefined }; } const existingComponent = this.registry.get(spec.name, namespace, version); if (existingComponent && !allowOverride) { return { success: false, error: { componentName: spec.name, error: `Component already registered in ${namespace}/${version}`, phase: 'registration' } }; } const compileOptions = { componentName: spec.name, componentCode: spec.code, styles, libraries: spec.libraries, allLibraries: options.allLibraries }; console.log(`🔧 Compiling component ${spec.name} with libraries:`, { libraryCount: spec.libraries?.length || 0, libraries: spec.libraries?.map(l => ({ name: l.name, globalVariable: l.globalVariable })) }); const compilationResult = await this.compiler.compile(compileOptions); if (!compilationResult.success) { return { success: false, error: { componentName: spec.name, error: compilationResult.error?.message || 'Unknown compilation error', phase: 'compilation' } }; } const componentFactory = compilationResult.component.component(this.runtimeContext, styles); this.registry.register(spec.name, componentFactory.component, namespace, version); return { success: true }; } catch (error) { return { success: false, error: { componentName: spec.name, error: error instanceof Error ? error.message : String(error), phase: 'registration' } }; } } async registerChildComponents(children, options, registeredComponents, errors, warnings) { for (const child of children) { const childResult = await this.registerSingleComponent(child, { styles: options.styles, namespace: options.namespace, version: options.version, allowOverride: options.allowOverride, allLibraries: options.allLibraries }); if (childResult.success) { if (child.code) { registeredComponents.push(child.name); } } else { errors.push(childResult.error); if (!options.continueOnError) { return; } } const nestedChildren = child.dependencies || []; if (nestedChildren.length > 0) { await this.registerChildComponents(nestedChildren, options, registeredComponents, errors, warnings); } } } } exports.ComponentHierarchyRegistrar = ComponentHierarchyRegistrar; async function registerComponentHierarchy(rootSpec, compiler, registry, runtimeContext, options) { const registrar = new ComponentHierarchyRegistrar(compiler, registry, runtimeContext); return registrar.registerHierarchy(rootSpec, options); } exports.registerComponentHierarchy = registerComponentHierarchy; function validateComponentSpec(spec) { const errors = []; if (!spec.name) { errors.push('Component specification must have a name'); } if (spec.code) { if (typeof spec.code !== 'string') { errors.push(`Component code for ${spec.name} must be a string`); } if (spec.code.trim().length === 0) { errors.push(`Component code for ${spec.name} cannot be empty`); } } const children = spec.dependencies || []; children.forEach((child, index) => { const childErrors = validateComponentSpec(child); childErrors.forEach(error => { errors.push(`Child ${index} (${child.name || 'unnamed'}): ${error}`); }); }); return errors; } exports.validateComponentSpec = validateComponentSpec; function flattenComponentHierarchy(rootSpec) { const components = [rootSpec]; const children = rootSpec.dependencies || []; children.forEach(child => { components.push(...flattenComponentHierarchy(child)); }); return components; } exports.flattenComponentHierarchy = flattenComponentHierarchy; function countComponentsInHierarchy(rootSpec, includeEmpty = false) { let count = 0; if (includeEmpty || rootSpec.code) { count = 1; } const children = rootSpec.dependencies || []; children.forEach(child => { count += countComponentsInHierarchy(child, includeEmpty); }); return count; } exports.countComponentsInHierarchy = countComponentsInHierarchy; //# sourceMappingURL=component-hierarchy.js.map