@memberjunction/ng-react 2.77.0 → 2.79.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.
|
@@ -123,7 +123,20 @@ export class MJReactComponent {
|
|
|
123
123
|
}
|
|
124
124
|
// Get runtime context and execute component factory
|
|
125
125
|
const context = this.adapter.getRuntimeContext();
|
|
126
|
-
|
|
126
|
+
// Call the factory function to get the component wrapper
|
|
127
|
+
// result.component is a CompiledComponent object with a 'component' property that's the factory
|
|
128
|
+
const componentWrapper = result.component.component(context, this.styles);
|
|
129
|
+
// Validate the component wrapper structure
|
|
130
|
+
if (!componentWrapper || typeof componentWrapper !== 'object') {
|
|
131
|
+
throw new Error(`Invalid component wrapper returned for ${this.component.name}: ${typeof componentWrapper}`);
|
|
132
|
+
}
|
|
133
|
+
if (!componentWrapper.component) {
|
|
134
|
+
throw new Error(`Component wrapper missing 'component' property for ${this.component.name}`);
|
|
135
|
+
}
|
|
136
|
+
if (typeof componentWrapper.component !== 'function') {
|
|
137
|
+
throw new Error(`Component is not a function for ${this.component.name}: ${typeof componentWrapper.component}`);
|
|
138
|
+
}
|
|
139
|
+
this.compiledComponent = componentWrapper;
|
|
127
140
|
this.currentState = { ...this._state };
|
|
128
141
|
// Create managed React root
|
|
129
142
|
const reactContext = this.reactBridge.getCurrentContext();
|
|
@@ -207,6 +220,11 @@ export class MJReactComponent {
|
|
|
207
220
|
savedUserSettings: this._savedUserSettings,
|
|
208
221
|
onSaveUserSettings: this.handleSaveUserSettings.bind(this)
|
|
209
222
|
};
|
|
223
|
+
// Validate component before creating element
|
|
224
|
+
if (!this.compiledComponent.component) {
|
|
225
|
+
LogError(`Component is undefined for ${this.component.name} during render`);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
210
228
|
// Create error boundary
|
|
211
229
|
const ErrorBoundary = createErrorBoundary(React, {
|
|
212
230
|
onError: this.handleReactError.bind(this),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mj-react-component.component.js","sourceRoot":"","sources":["../../../src/lib/components/mj-react-component.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Angular component that hosts React components with proper memory management.\n * Provides a bridge between Angular and React ecosystems in MemberJunction applications.\n * @module @memberjunction/ng-react\n */\n\nimport {\n Component,\n Input,\n Output,\n EventEmitter,\n ViewChild,\n ElementRef,\n AfterViewInit,\n OnDestroy,\n ChangeDetectionStrategy,\n ChangeDetectorRef\n} from '@angular/core';\nimport { Subject, takeUntil } from 'rxjs';\nimport { ComponentSpec, ComponentCallbacks, ComponentStyles } from '@memberjunction/interactive-component-types';\nimport { ReactBridgeService } from '../services/react-bridge.service';\nimport { AngularAdapterService } from '../services/angular-adapter.service';\nimport { \n buildComponentProps,\n createErrorBoundary,\n ComponentHierarchyRegistrar,\n HierarchyRegistrationResult,\n resourceManager,\n reactRootManager\n} from '@memberjunction/react-runtime';\nimport { LogError, CompositeKey, KeyValuePair } from '@memberjunction/core';\n\n/**\n * Event emitted by React components\n */\nexport interface ReactComponentEvent {\n type: string;\n payload: any;\n}\n\n/**\n * State change event emitted when component state updates\n */\nexport interface StateChangeEvent {\n path: string;\n value: any;\n}\n\n/**\n * User settings changed event emitted when component saves user preferences\n */\nexport interface UserSettingsChangedEvent {\n settings: Record<string, any>;\n componentName?: string;\n timestamp: Date;\n}\n\n/**\n * Angular component that hosts React components with proper memory management.\n * This component provides a bridge between Angular and React, allowing React components\n * to be used seamlessly within Angular applications.\n */\n@Component({\n selector: 'mj-react-component',\n template: `\n <div class=\"react-component-wrapper\">\n <div #container class=\"react-component-container\" [class.loading]=\"!isInitialized\"></div>\n @if (!isInitialized && !hasError) {\n <div class=\"loading-overlay\">\n <div class=\"loading-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n <div class=\"loading-text\">Loading component...</div>\n </div>\n }\n </div>\n `,\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n .react-component-wrapper {\n position: relative;\n width: 100%;\n height: 100%;\n }\n .react-component-container {\n width: 100%;\n height: 100%;\n transition: opacity 0.3s ease;\n }\n .react-component-container.loading {\n opacity: 0;\n }\n .loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n background-color: rgba(255, 255, 255, 0.9);\n z-index: 1;\n }\n .loading-spinner {\n font-size: 48px;\n color: #5B4FE9;\n margin-bottom: 16px;\n }\n .loading-text {\n font-family: -apple-system, BlinkMacSystemFont, \"Inter\", \"Segoe UI\", Roboto, sans-serif;\n font-size: 14px;\n color: #64748B;\n margin-top: 8px;\n }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MJReactComponent implements AfterViewInit, OnDestroy {\n @Input() component!: ComponentSpec;\n \n private _data: any = {};\n @Input() \n set data(value: any) {\n const oldData = this._data;\n this._data = value;\n \n // Only re-render if data actually changed and component is initialized\n if (this.isInitialized && !this.isEqual(oldData, value)) {\n this.renderComponent();\n }\n }\n get data(): any {\n return this._data;\n }\n \n private _state: any = {};\n @Input() \n set state(value: any) {\n const oldState = this._state;\n this._state = value;\n \n // Only update state and re-render if it actually changed\n if (this.isInitialized && !this.isEqual(oldState, value)) {\n this.currentState = { ...value };\n this.renderComponent();\n }\n }\n get state(): any {\n return this._state;\n }\n \n @Input() utilities: any = {};\n @Input() styles?: Partial<ComponentStyles>;\n \n private _savedUserSettings: any = {};\n @Input()\n set savedUserSettings(value: any) {\n this._savedUserSettings = value || {};\n // Re-render if component is initialized\n if (this.isInitialized) {\n this.renderComponent();\n }\n }\n get savedUserSettings(): any {\n return this._savedUserSettings;\n }\n \n @Output() stateChange = new EventEmitter<StateChangeEvent>();\n @Output() componentEvent = new EventEmitter<ReactComponentEvent>();\n @Output() refreshData = new EventEmitter<void>();\n @Output() openEntityRecord = new EventEmitter<{ entityName: string; key: CompositeKey }>();\n @Output() userSettingsChanged = new EventEmitter<UserSettingsChangedEvent>();\n \n @ViewChild('container', { read: ElementRef, static: true }) container!: ElementRef<HTMLDivElement>;\n \n private reactRootId: string | null = null;\n private compiledComponent: any = null;\n private destroyed$ = new Subject<void>();\n private currentCallbacks: ComponentCallbacks | null = null;\n private currentState: any = {};\n isInitialized = false;\n private isRendering = false;\n private pendingRender = false;\n private isDestroying = false;\n private componentId: string;\n hasError = false;\n\n constructor(\n private reactBridge: ReactBridgeService,\n private adapter: AngularAdapterService,\n private cdr: ChangeDetectorRef\n ) {\n // Generate unique component ID for resource tracking\n this.componentId = `mj-react-component-${Date.now()}-${Math.random()}`;\n }\n\n async ngAfterViewInit() {\n // Trigger change detection to show loading state\n this.cdr.detectChanges();\n await this.initializeComponent();\n }\n\n ngOnDestroy() {\n // Set destroying flag immediately\n this.isDestroying = true;\n \n // Cancel any pending renders\n this.pendingRender = false;\n \n this.destroyed$.next();\n this.destroyed$.complete();\n this.cleanup();\n }\n\n\n /**\n * Initialize the React component\n */\n private async initializeComponent() {\n try {\n // Ensure React is loaded\n await this.reactBridge.getReactContext();\n \n // Wait for React to be fully ready (handles first-load delay)\n await this.reactBridge.waitForReactReady();\n \n // Register component hierarchy\n await this.registerComponentHierarchy();\n \n // Compile main component\n const result = await this.adapter.compileComponent({\n componentName: this.component.name,\n componentCode: this.component.code,\n styles: this.styles\n });\n\n if (!result.success) {\n throw new Error(result.error?.message || 'Component compilation failed');\n }\n\n // Get runtime context and execute component factory\n const context = this.adapter.getRuntimeContext();\n this.compiledComponent = result.component!.component(context, this.styles);\n this.currentState = { ...this._state };\n \n // Create managed React root\n const reactContext = this.reactBridge.getCurrentContext();\n if (!reactContext) {\n throw new Error('React context not available');\n }\n \n this.reactRootId = reactRootManager.createRoot(\n this.container.nativeElement,\n (container: HTMLElement) => reactContext.ReactDOM.createRoot(container),\n this.componentId\n );\n \n // Initial render\n this.renderComponent();\n this.isInitialized = true;\n \n // Trigger change detection since we're using OnPush\n this.cdr.detectChanges();\n \n } catch (error) {\n this.hasError = true;\n LogError(`Failed to initialize React component: ${error}`);\n this.componentEvent.emit({\n type: 'error',\n payload: {\n error: error instanceof Error ? error.message : String(error),\n source: 'initialization'\n }\n });\n // Trigger change detection to show error state\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Register all components in the hierarchy\n */\n private async registerComponentHierarchy() {\n // Create the hierarchy registrar with adapter's compiler and registry\n const registrar = new ComponentHierarchyRegistrar(\n this.adapter.getCompiler(),\n this.adapter.getRegistry(),\n this.adapter.getRuntimeContext()\n );\n \n // Register the entire hierarchy\n const result: HierarchyRegistrationResult = await registrar.registerHierarchy(\n this.component,\n {\n styles: this.styles as any, // Skip components use SkipComponentStyles which is a superset\n namespace: 'Global',\n version: 'v1'\n }\n );\n \n // Check for errors\n if (!result.success) {\n const errorMessages = result.errors.map(e => \n `${e.componentName}: ${e.error}`\n );\n throw new Error(`Component registration failed: ${errorMessages.join(', ')}`);\n }\n }\n\n /**\n * Render the React component\n */\n private renderComponent() {\n // Don't render if component is being destroyed\n if (this.isDestroying) {\n return;\n }\n \n if (!this.compiledComponent || !this.reactRootId) {\n return;\n }\n\n // Prevent concurrent renders\n if (this.isRendering) {\n this.pendingRender = true;\n return;\n }\n\n const context = this.reactBridge.getCurrentContext();\n if (!context) {\n return;\n }\n\n this.isRendering = true;\n const { React } = context;\n \n // Get components from resolver\n const components = this.adapter.getResolver().resolveComponents(this.component);\n \n // Create callbacks once per component instance\n if (!this.currentCallbacks) {\n this.currentCallbacks = this.createCallbacks();\n }\n \n // Build props with savedUserSettings pattern\n const props = {\n ...this._data, // Spread data properties directly\n utilities: this.utilities || {},\n callbacks: this.currentCallbacks,\n components,\n styles: this.styles as any,\n savedUserSettings: this._savedUserSettings,\n onSaveUserSettings: this.handleSaveUserSettings.bind(this)\n };\n\n // Create error boundary\n const ErrorBoundary = createErrorBoundary(React, {\n onError: this.handleReactError.bind(this),\n logErrors: true,\n recovery: 'retry'\n });\n\n // Create element with error boundary\n const element = React.createElement(\n ErrorBoundary,\n null,\n React.createElement(this.compiledComponent.component, props)\n );\n\n // Render with timeout protection using resource manager\n const timeoutId = resourceManager.setTimeout(\n this.componentId,\n () => {\n // Check if still rendering and not destroyed\n if (this.isRendering && !this.isDestroying) {\n this.componentEvent.emit({\n type: 'error',\n payload: {\n error: 'Component render timeout - possible infinite loop detected',\n source: 'render'\n }\n });\n }\n },\n 5000,\n { purpose: 'render-timeout-protection' }\n );\n\n // Use managed React root for rendering\n reactRootManager.render(\n this.reactRootId,\n element,\n () => {\n // Clear the timeout as render completed\n resourceManager.clearTimeout(this.componentId, timeoutId);\n \n // Don't update state if component is destroyed\n if (this.isDestroying) {\n return;\n }\n \n this.isRendering = false;\n \n // If there was a pending render request, execute it now\n if (this.pendingRender) {\n this.pendingRender = false;\n this.renderComponent();\n }\n }\n );\n }\n\n /**\n * Create callbacks for the React component\n */\n private createCallbacks(): ComponentCallbacks {\n return {\n OpenEntityRecord: (entityName: string, key: CompositeKey) => {\n let keyToUse: CompositeKey | null = null;\n if (key instanceof Array) {\n keyToUse = CompositeKey.FromKeyValuePairs(key);\n }\n else if (typeof key === 'object' && !!key.GetValueByFieldName) {\n keyToUse = key as CompositeKey;\n }\n else if (typeof key === 'object') {\n //} && !!key.FieldName && !!key.Value) {\n // possible that have an object that is a simple key/value pair with\n // FieldName and value properties\n const keyAny = key as any;\n if (keyAny.FieldName && keyAny.Value) {\n keyToUse = CompositeKey.FromKeyValuePairs([keyAny as KeyValuePair]);\n }\n }\n if (keyToUse) {\n this.openEntityRecord.emit({ entityName, key: keyToUse });\n } \n } \n };\n }\n\n /**\n * Handle React component errors\n */\n private handleReactError(error: any, errorInfo?: any) {\n LogError(`React component error: ${error?.toString() || 'Unknown error'}`, errorInfo);\n this.componentEvent.emit({\n type: 'error',\n payload: {\n error: error?.toString() || 'Unknown error',\n errorInfo,\n source: 'react'\n }\n });\n }\n\n /**\n * Handle onSaveUserSettings from components\n * This implements the SavedUserSettings pattern\n */\n private handleSaveUserSettings(newSettings: Record<string, any>) {\n // Check if there are actual changes\n const hasChanges = !this.isEqual(this._savedUserSettings, newSettings);\n \n if (!hasChanges) {\n // No actual changes, skip update to prevent infinite loop\n return;\n }\n \n // Update saved settings\n this._savedUserSettings = { ...newSettings };\n \n // Emit user settings changed event\n this.userSettingsChanged.emit({\n settings: this._savedUserSettings,\n componentName: this.component?.name,\n timestamp: new Date()\n });\n \n // Schedule re-render\n this.renderComponent();\n }\n\n /**\n * Clean up resources\n */\n private cleanup() {\n // Clean up all resources managed by resource manager\n resourceManager.cleanupComponent(this.componentId);\n \n // Clean up prop builder subscriptions\n if (this.currentCallbacks) {\n this.currentCallbacks = null;\n }\n \n // Unmount React root using managed unmount\n if (this.reactRootId) {\n // Force stop rendering flags\n this.isRendering = false;\n this.pendingRender = false;\n \n // This will handle waiting for render completion if needed\n reactRootManager.unmountRoot(this.reactRootId);\n this.reactRootId = null;\n }\n\n // Clear references\n this.compiledComponent = null;\n this.currentState = {};\n this.isInitialized = false;\n\n // Trigger registry cleanup\n this.adapter.getRegistry().cleanup();\n }\n\n /**\n * Public method to refresh the component\n * @param newData - Optional new data to merge\n */\n refresh(newData?: any) {\n if (newData) {\n // Use the setter to trigger change detection\n this.data = { ...this._data, ...newData };\n } else {\n this.renderComponent();\n }\n }\n\n /**\n * Public method to update state programmatically\n * @param path - State path to update\n * @param value - New value\n */\n updateState(path: string, value: any) {\n this.currentState = {\n ...this.currentState,\n [path]: value\n };\n this.stateChange.emit({ path, value });\n this.renderComponent();\n }\n\n /**\n * Deep equality check that handles null/undefined properly\n */\n private isEqual(a: any, b: any): boolean {\n // Handle null/undefined cases\n if (a === b) return true;\n if (a == null || b == null) return false;\n \n // For objects/arrays, use JSON comparison\n if (typeof a === 'object' && typeof b === 'object') {\n return JSON.stringify(a) === JSON.stringify(b);\n }\n \n return a === b;\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"mj-react-component.component.js","sourceRoot":"","sources":["../../../src/lib/components/mj-react-component.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Angular component that hosts React components with proper memory management.\n * Provides a bridge between Angular and React ecosystems in MemberJunction applications.\n * @module @memberjunction/ng-react\n */\n\nimport {\n Component,\n Input,\n Output,\n EventEmitter,\n ViewChild,\n ElementRef,\n AfterViewInit,\n OnDestroy,\n ChangeDetectionStrategy,\n ChangeDetectorRef\n} from '@angular/core';\nimport { Subject, takeUntil } from 'rxjs';\nimport { ComponentSpec, ComponentCallbacks, ComponentStyles } from '@memberjunction/interactive-component-types';\nimport { ReactBridgeService } from '../services/react-bridge.service';\nimport { AngularAdapterService } from '../services/angular-adapter.service';\nimport { \n buildComponentProps,\n createErrorBoundary,\n ComponentHierarchyRegistrar,\n HierarchyRegistrationResult,\n resourceManager,\n reactRootManager\n} from '@memberjunction/react-runtime';\nimport { LogError, CompositeKey, KeyValuePair } from '@memberjunction/core';\n\n/**\n * Event emitted by React components\n */\nexport interface ReactComponentEvent {\n type: string;\n payload: any;\n}\n\n/**\n * State change event emitted when component state updates\n */\nexport interface StateChangeEvent {\n path: string;\n value: any;\n}\n\n/**\n * User settings changed event emitted when component saves user preferences\n */\nexport interface UserSettingsChangedEvent {\n settings: Record<string, any>;\n componentName?: string;\n timestamp: Date;\n}\n\n/**\n * Angular component that hosts React components with proper memory management.\n * This component provides a bridge between Angular and React, allowing React components\n * to be used seamlessly within Angular applications.\n */\n@Component({\n selector: 'mj-react-component',\n template: `\n <div class=\"react-component-wrapper\">\n <div #container class=\"react-component-container\" [class.loading]=\"!isInitialized\"></div>\n @if (!isInitialized && !hasError) {\n <div class=\"loading-overlay\">\n <div class=\"loading-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n <div class=\"loading-text\">Loading component...</div>\n </div>\n }\n </div>\n `,\n styles: [`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n .react-component-wrapper {\n position: relative;\n width: 100%;\n height: 100%;\n }\n .react-component-container {\n width: 100%;\n height: 100%;\n transition: opacity 0.3s ease;\n }\n .react-component-container.loading {\n opacity: 0;\n }\n .loading-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n background-color: rgba(255, 255, 255, 0.9);\n z-index: 1;\n }\n .loading-spinner {\n font-size: 48px;\n color: #5B4FE9;\n margin-bottom: 16px;\n }\n .loading-text {\n font-family: -apple-system, BlinkMacSystemFont, \"Inter\", \"Segoe UI\", Roboto, sans-serif;\n font-size: 14px;\n color: #64748B;\n margin-top: 8px;\n }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MJReactComponent implements AfterViewInit, OnDestroy {\n @Input() component!: ComponentSpec;\n \n private _data: any = {};\n @Input() \n set data(value: any) {\n const oldData = this._data;\n this._data = value;\n \n // Only re-render if data actually changed and component is initialized\n if (this.isInitialized && !this.isEqual(oldData, value)) {\n this.renderComponent();\n }\n }\n get data(): any {\n return this._data;\n }\n \n private _state: any = {};\n @Input() \n set state(value: any) {\n const oldState = this._state;\n this._state = value;\n \n // Only update state and re-render if it actually changed\n if (this.isInitialized && !this.isEqual(oldState, value)) {\n this.currentState = { ...value };\n this.renderComponent();\n }\n }\n get state(): any {\n return this._state;\n }\n \n @Input() utilities: any = {};\n @Input() styles?: Partial<ComponentStyles>;\n \n private _savedUserSettings: any = {};\n @Input()\n set savedUserSettings(value: any) {\n this._savedUserSettings = value || {};\n // Re-render if component is initialized\n if (this.isInitialized) {\n this.renderComponent();\n }\n }\n get savedUserSettings(): any {\n return this._savedUserSettings;\n }\n \n @Output() stateChange = new EventEmitter<StateChangeEvent>();\n @Output() componentEvent = new EventEmitter<ReactComponentEvent>();\n @Output() refreshData = new EventEmitter<void>();\n @Output() openEntityRecord = new EventEmitter<{ entityName: string; key: CompositeKey }>();\n @Output() userSettingsChanged = new EventEmitter<UserSettingsChangedEvent>();\n \n @ViewChild('container', { read: ElementRef, static: true }) container!: ElementRef<HTMLDivElement>;\n \n private reactRootId: string | null = null;\n private compiledComponent: any = null;\n private destroyed$ = new Subject<void>();\n private currentCallbacks: ComponentCallbacks | null = null;\n private currentState: any = {};\n isInitialized = false;\n private isRendering = false;\n private pendingRender = false;\n private isDestroying = false;\n private componentId: string;\n hasError = false;\n\n constructor(\n private reactBridge: ReactBridgeService,\n private adapter: AngularAdapterService,\n private cdr: ChangeDetectorRef\n ) {\n // Generate unique component ID for resource tracking\n this.componentId = `mj-react-component-${Date.now()}-${Math.random()}`;\n }\n\n async ngAfterViewInit() {\n // Trigger change detection to show loading state\n this.cdr.detectChanges();\n await this.initializeComponent();\n }\n\n ngOnDestroy() {\n // Set destroying flag immediately\n this.isDestroying = true;\n \n // Cancel any pending renders\n this.pendingRender = false;\n \n this.destroyed$.next();\n this.destroyed$.complete();\n this.cleanup();\n }\n\n\n /**\n * Initialize the React component\n */\n private async initializeComponent() {\n try {\n // Ensure React is loaded\n await this.reactBridge.getReactContext();\n \n // Wait for React to be fully ready (handles first-load delay)\n await this.reactBridge.waitForReactReady();\n \n // Register component hierarchy\n await this.registerComponentHierarchy();\n \n // Compile main component\n const result = await this.adapter.compileComponent({\n componentName: this.component.name,\n componentCode: this.component.code,\n styles: this.styles\n });\n\n if (!result.success) {\n throw new Error(result.error?.message || 'Component compilation failed');\n }\n\n // Get runtime context and execute component factory\n const context = this.adapter.getRuntimeContext();\n \n // Call the factory function to get the component wrapper\n // result.component is a CompiledComponent object with a 'component' property that's the factory\n const componentWrapper = result.component!.component(context, this.styles);\n \n // Validate the component wrapper structure\n if (!componentWrapper || typeof componentWrapper !== 'object') {\n throw new Error(`Invalid component wrapper returned for ${this.component.name}: ${typeof componentWrapper}`);\n }\n \n if (!componentWrapper.component) {\n throw new Error(`Component wrapper missing 'component' property for ${this.component.name}`);\n }\n \n if (typeof componentWrapper.component !== 'function') {\n throw new Error(`Component is not a function for ${this.component.name}: ${typeof componentWrapper.component}`);\n }\n \n this.compiledComponent = componentWrapper;\n this.currentState = { ...this._state };\n \n // Create managed React root\n const reactContext = this.reactBridge.getCurrentContext();\n if (!reactContext) {\n throw new Error('React context not available');\n }\n \n this.reactRootId = reactRootManager.createRoot(\n this.container.nativeElement,\n (container: HTMLElement) => reactContext.ReactDOM.createRoot(container),\n this.componentId\n );\n \n // Initial render\n this.renderComponent();\n this.isInitialized = true;\n \n // Trigger change detection since we're using OnPush\n this.cdr.detectChanges();\n \n } catch (error) {\n this.hasError = true;\n LogError(`Failed to initialize React component: ${error}`);\n this.componentEvent.emit({\n type: 'error',\n payload: {\n error: error instanceof Error ? error.message : String(error),\n source: 'initialization'\n }\n });\n // Trigger change detection to show error state\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Register all components in the hierarchy\n */\n private async registerComponentHierarchy() {\n // Create the hierarchy registrar with adapter's compiler and registry\n const registrar = new ComponentHierarchyRegistrar(\n this.adapter.getCompiler(),\n this.adapter.getRegistry(),\n this.adapter.getRuntimeContext()\n );\n \n // Register the entire hierarchy\n const result: HierarchyRegistrationResult = await registrar.registerHierarchy(\n this.component,\n {\n styles: this.styles as any, // Skip components use SkipComponentStyles which is a superset\n namespace: 'Global',\n version: 'v1'\n }\n );\n \n // Check for errors\n if (!result.success) {\n const errorMessages = result.errors.map(e => \n `${e.componentName}: ${e.error}`\n );\n throw new Error(`Component registration failed: ${errorMessages.join(', ')}`);\n }\n }\n\n /**\n * Render the React component\n */\n private renderComponent() {\n // Don't render if component is being destroyed\n if (this.isDestroying) {\n return;\n }\n \n if (!this.compiledComponent || !this.reactRootId) {\n return;\n }\n\n // Prevent concurrent renders\n if (this.isRendering) {\n this.pendingRender = true;\n return;\n }\n\n const context = this.reactBridge.getCurrentContext();\n if (!context) {\n return;\n }\n\n this.isRendering = true;\n const { React } = context;\n \n // Get components from resolver\n const components = this.adapter.getResolver().resolveComponents(this.component);\n \n // Create callbacks once per component instance\n if (!this.currentCallbacks) {\n this.currentCallbacks = this.createCallbacks();\n }\n \n // Build props with savedUserSettings pattern\n const props = {\n ...this._data, // Spread data properties directly\n utilities: this.utilities || {},\n callbacks: this.currentCallbacks,\n components,\n styles: this.styles as any,\n savedUserSettings: this._savedUserSettings,\n onSaveUserSettings: this.handleSaveUserSettings.bind(this)\n };\n\n // Validate component before creating element\n if (!this.compiledComponent.component) {\n LogError(`Component is undefined for ${this.component.name} during render`);\n return;\n }\n\n // Create error boundary\n const ErrorBoundary = createErrorBoundary(React, {\n onError: this.handleReactError.bind(this),\n logErrors: true,\n recovery: 'retry'\n });\n\n // Create element with error boundary\n const element = React.createElement(\n ErrorBoundary,\n null,\n React.createElement(this.compiledComponent.component, props)\n );\n\n // Render with timeout protection using resource manager\n const timeoutId = resourceManager.setTimeout(\n this.componentId,\n () => {\n // Check if still rendering and not destroyed\n if (this.isRendering && !this.isDestroying) {\n this.componentEvent.emit({\n type: 'error',\n payload: {\n error: 'Component render timeout - possible infinite loop detected',\n source: 'render'\n }\n });\n }\n },\n 5000,\n { purpose: 'render-timeout-protection' }\n );\n\n // Use managed React root for rendering\n reactRootManager.render(\n this.reactRootId,\n element,\n () => {\n // Clear the timeout as render completed\n resourceManager.clearTimeout(this.componentId, timeoutId);\n \n // Don't update state if component is destroyed\n if (this.isDestroying) {\n return;\n }\n \n this.isRendering = false;\n \n // If there was a pending render request, execute it now\n if (this.pendingRender) {\n this.pendingRender = false;\n this.renderComponent();\n }\n }\n );\n }\n\n /**\n * Create callbacks for the React component\n */\n private createCallbacks(): ComponentCallbacks {\n return {\n OpenEntityRecord: (entityName: string, key: CompositeKey) => {\n let keyToUse: CompositeKey | null = null;\n if (key instanceof Array) {\n keyToUse = CompositeKey.FromKeyValuePairs(key);\n }\n else if (typeof key === 'object' && !!key.GetValueByFieldName) {\n keyToUse = key as CompositeKey;\n }\n else if (typeof key === 'object') {\n //} && !!key.FieldName && !!key.Value) {\n // possible that have an object that is a simple key/value pair with\n // FieldName and value properties\n const keyAny = key as any;\n if (keyAny.FieldName && keyAny.Value) {\n keyToUse = CompositeKey.FromKeyValuePairs([keyAny as KeyValuePair]);\n }\n }\n if (keyToUse) {\n this.openEntityRecord.emit({ entityName, key: keyToUse });\n } \n } \n };\n }\n\n /**\n * Handle React component errors\n */\n private handleReactError(error: any, errorInfo?: any) {\n LogError(`React component error: ${error?.toString() || 'Unknown error'}`, errorInfo);\n this.componentEvent.emit({\n type: 'error',\n payload: {\n error: error?.toString() || 'Unknown error',\n errorInfo,\n source: 'react'\n }\n });\n }\n\n /**\n * Handle onSaveUserSettings from components\n * This implements the SavedUserSettings pattern\n */\n private handleSaveUserSettings(newSettings: Record<string, any>) {\n // Check if there are actual changes\n const hasChanges = !this.isEqual(this._savedUserSettings, newSettings);\n \n if (!hasChanges) {\n // No actual changes, skip update to prevent infinite loop\n return;\n }\n \n // Update saved settings\n this._savedUserSettings = { ...newSettings };\n \n // Emit user settings changed event\n this.userSettingsChanged.emit({\n settings: this._savedUserSettings,\n componentName: this.component?.name,\n timestamp: new Date()\n });\n \n // Schedule re-render\n this.renderComponent();\n }\n\n /**\n * Clean up resources\n */\n private cleanup() {\n // Clean up all resources managed by resource manager\n resourceManager.cleanupComponent(this.componentId);\n \n // Clean up prop builder subscriptions\n if (this.currentCallbacks) {\n this.currentCallbacks = null;\n }\n \n // Unmount React root using managed unmount\n if (this.reactRootId) {\n // Force stop rendering flags\n this.isRendering = false;\n this.pendingRender = false;\n \n // This will handle waiting for render completion if needed\n reactRootManager.unmountRoot(this.reactRootId);\n this.reactRootId = null;\n }\n\n // Clear references\n this.compiledComponent = null;\n this.currentState = {};\n this.isInitialized = false;\n\n // Trigger registry cleanup\n this.adapter.getRegistry().cleanup();\n }\n\n /**\n * Public method to refresh the component\n * @param newData - Optional new data to merge\n */\n refresh(newData?: any) {\n if (newData) {\n // Use the setter to trigger change detection\n this.data = { ...this._data, ...newData };\n } else {\n this.renderComponent();\n }\n }\n\n /**\n * Public method to update state programmatically\n * @param path - State path to update\n * @param value - New value\n */\n updateState(path: string, value: any) {\n this.currentState = {\n ...this.currentState,\n [path]: value\n };\n this.stateChange.emit({ path, value });\n this.renderComponent();\n }\n\n /**\n * Deep equality check that handles null/undefined properly\n */\n private isEqual(a: any, b: any): boolean {\n // Handle null/undefined cases\n if (a === b) return true;\n if (a == null || b == null) return false;\n \n // For objects/arrays, use JSON comparison\n if (typeof a === 'object' && typeof b === 'object') {\n return JSON.stringify(a) === JSON.stringify(b);\n }\n \n return a === b;\n }\n}"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-react",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.79.0",
|
|
4
4
|
"description": "Angular components for hosting React components in MemberJunction applications",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "ngc -p tsconfig.json",
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
"styles"
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@memberjunction/core": "2.
|
|
44
|
-
"@memberjunction/react-runtime": "2.
|
|
45
|
-
"@memberjunction/interactive-component-types": "^2.
|
|
43
|
+
"@memberjunction/core": "2.79.0",
|
|
44
|
+
"@memberjunction/react-runtime": "2.79.0",
|
|
45
|
+
"@memberjunction/interactive-component-types": "^2.79.0",
|
|
46
46
|
"@angular/common": ">=18.0.0",
|
|
47
47
|
"@angular/core": ">=18.0.0",
|
|
48
48
|
"@angular/platform-browser": ">=18.0.0",
|