@memberjunction/react-runtime 3.3.0 → 4.0.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.
Files changed (77) hide show
  1. package/.turbo/turbo-build.log +33 -25
  2. package/CHANGELOG.md +40 -0
  3. package/dist/324.runtime.umd.js +817 -0
  4. package/dist/490.runtime.umd.js +1 -0
  5. package/dist/compiler/babel-config.js +15 -21
  6. package/dist/compiler/babel-config.js.map +1 -1
  7. package/dist/compiler/component-compiler.js +13 -17
  8. package/dist/compiler/component-compiler.js.map +1 -1
  9. package/dist/compiler/index.js +2 -13
  10. package/dist/compiler/index.js.map +1 -1
  11. package/dist/component-manager/component-manager.js +7 -34
  12. package/dist/component-manager/component-manager.js.map +1 -1
  13. package/dist/component-manager/index.js +1 -5
  14. package/dist/component-manager/index.js.map +1 -1
  15. package/dist/component-manager/types.js +1 -2
  16. package/dist/index.js +31 -100
  17. package/dist/index.js.map +1 -1
  18. package/dist/registry/component-registry-service.js +8 -35
  19. package/dist/registry/component-registry-service.js.map +1 -1
  20. package/dist/registry/component-registry.js +5 -9
  21. package/dist/registry/component-registry.js.map +1 -1
  22. package/dist/registry/component-resolver.js +5 -9
  23. package/dist/registry/component-resolver.js.map +1 -1
  24. package/dist/registry/index.js +4 -11
  25. package/dist/registry/index.js.map +1 -1
  26. package/dist/registry/registry-provider.js +1 -2
  27. package/dist/runtime/component-hierarchy.js +24 -55
  28. package/dist/runtime/component-hierarchy.js.map +1 -1
  29. package/dist/runtime/component-wrapper.d.ts +18 -0
  30. package/dist/runtime/component-wrapper.d.ts.map +1 -0
  31. package/dist/runtime/component-wrapper.js +108 -0
  32. package/dist/runtime/error-boundary.js +4 -11
  33. package/dist/runtime/error-boundary.js.map +1 -1
  34. package/dist/runtime/index.js +4 -26
  35. package/dist/runtime/index.js.map +1 -1
  36. package/dist/runtime/prop-builder.js +17 -28
  37. package/dist/runtime/prop-builder.js.map +1 -1
  38. package/dist/runtime/react-root-manager.js +4 -8
  39. package/dist/runtime/react-root-manager.js.map +1 -1
  40. package/dist/runtime.umd.js +1 -801
  41. package/dist/types/dependency-types.js +1 -2
  42. package/dist/types/index.js +2 -18
  43. package/dist/types/index.js.map +1 -1
  44. package/dist/types/library-config.js +1 -2
  45. package/dist/utilities/cache-manager.js +1 -5
  46. package/dist/utilities/cache-manager.js.map +1 -1
  47. package/dist/utilities/component-error-analyzer.js +53 -57
  48. package/dist/utilities/component-error-analyzer.js.map +1 -1
  49. package/dist/utilities/component-styles.js +2 -6
  50. package/dist/utilities/component-styles.js.map +1 -1
  51. package/dist/utilities/component-unwrapper.d.ts.map +1 -1
  52. package/dist/utilities/component-unwrapper.js +6 -13
  53. package/dist/utilities/component-unwrapper.js.map +1 -1
  54. package/dist/utilities/core-libraries.js +2 -7
  55. package/dist/utilities/core-libraries.js.map +1 -1
  56. package/dist/utilities/index.js +9 -25
  57. package/dist/utilities/index.js.map +1 -1
  58. package/dist/utilities/library-dependency-resolver.js +1 -5
  59. package/dist/utilities/library-dependency-resolver.js.map +1 -1
  60. package/dist/utilities/library-loader.js +23 -27
  61. package/dist/utilities/library-loader.js.map +1 -1
  62. package/dist/utilities/library-registry.d.ts.map +1 -1
  63. package/dist/utilities/library-registry.js +3 -7
  64. package/dist/utilities/library-registry.js.map +1 -1
  65. package/dist/utilities/resource-manager.d.ts +0 -1
  66. package/dist/utilities/resource-manager.d.ts.map +1 -1
  67. package/dist/utilities/resource-manager.js +2 -6
  68. package/dist/utilities/resource-manager.js.map +1 -1
  69. package/dist/utilities/runtime-utilities.d.ts +10 -0
  70. package/dist/utilities/runtime-utilities.d.ts.map +1 -0
  71. package/dist/utilities/runtime-utilities.js +92 -0
  72. package/dist/utilities/standard-libraries.js +3 -8
  73. package/dist/utilities/standard-libraries.js.map +1 -1
  74. package/package.json +17 -17
  75. package/tsconfig.json +7 -22
  76. package/tsconfig.tsbuildinfo +1 -0
  77. package/typedoc.json +9 -0
@@ -1,27 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.reactRootManager = exports.ReactRootManager = exports.countComponentsInHierarchy = exports.flattenComponentHierarchy = exports.validateComponentSpec = exports.registerComponentHierarchy = exports.ComponentHierarchyRegistrar = exports.extractPropPaths = exports.wrapCallbacksWithLogging = exports.createPropsTransformer = exports.mergeProps = exports.validateComponentProps = exports.normalizeStyles = exports.normalizeCallbacks = exports.buildComponentProps = exports.createErrorLogger = exports.formatComponentError = exports.withErrorBoundary = exports.createErrorBoundary = void 0;
4
- var error_boundary_1 = require("./error-boundary");
5
- Object.defineProperty(exports, "createErrorBoundary", { enumerable: true, get: function () { return error_boundary_1.createErrorBoundary; } });
6
- Object.defineProperty(exports, "withErrorBoundary", { enumerable: true, get: function () { return error_boundary_1.withErrorBoundary; } });
7
- Object.defineProperty(exports, "formatComponentError", { enumerable: true, get: function () { return error_boundary_1.formatComponentError; } });
8
- Object.defineProperty(exports, "createErrorLogger", { enumerable: true, get: function () { return error_boundary_1.createErrorLogger; } });
9
- var prop_builder_1 = require("./prop-builder");
10
- Object.defineProperty(exports, "buildComponentProps", { enumerable: true, get: function () { return prop_builder_1.buildComponentProps; } });
11
- Object.defineProperty(exports, "normalizeCallbacks", { enumerable: true, get: function () { return prop_builder_1.normalizeCallbacks; } });
12
- Object.defineProperty(exports, "normalizeStyles", { enumerable: true, get: function () { return prop_builder_1.normalizeStyles; } });
13
- Object.defineProperty(exports, "validateComponentProps", { enumerable: true, get: function () { return prop_builder_1.validateComponentProps; } });
14
- Object.defineProperty(exports, "mergeProps", { enumerable: true, get: function () { return prop_builder_1.mergeProps; } });
15
- Object.defineProperty(exports, "createPropsTransformer", { enumerable: true, get: function () { return prop_builder_1.createPropsTransformer; } });
16
- Object.defineProperty(exports, "wrapCallbacksWithLogging", { enumerable: true, get: function () { return prop_builder_1.wrapCallbacksWithLogging; } });
17
- Object.defineProperty(exports, "extractPropPaths", { enumerable: true, get: function () { return prop_builder_1.extractPropPaths; } });
18
- var component_hierarchy_1 = require("./component-hierarchy");
19
- Object.defineProperty(exports, "ComponentHierarchyRegistrar", { enumerable: true, get: function () { return component_hierarchy_1.ComponentHierarchyRegistrar; } });
20
- Object.defineProperty(exports, "registerComponentHierarchy", { enumerable: true, get: function () { return component_hierarchy_1.registerComponentHierarchy; } });
21
- Object.defineProperty(exports, "validateComponentSpec", { enumerable: true, get: function () { return component_hierarchy_1.validateComponentSpec; } });
22
- Object.defineProperty(exports, "flattenComponentHierarchy", { enumerable: true, get: function () { return component_hierarchy_1.flattenComponentHierarchy; } });
23
- Object.defineProperty(exports, "countComponentsInHierarchy", { enumerable: true, get: function () { return component_hierarchy_1.countComponentsInHierarchy; } });
24
- var react_root_manager_1 = require("./react-root-manager");
25
- Object.defineProperty(exports, "ReactRootManager", { enumerable: true, get: function () { return react_root_manager_1.ReactRootManager; } });
26
- Object.defineProperty(exports, "reactRootManager", { enumerable: true, get: function () { return react_root_manager_1.reactRootManager; } });
1
+ export { createErrorBoundary, withErrorBoundary, formatComponentError, createErrorLogger } from './error-boundary';
2
+ export { buildComponentProps, normalizeCallbacks, normalizeStyles, validateComponentProps, mergeProps, createPropsTransformer, wrapCallbacksWithLogging, extractPropPaths } from './prop-builder';
3
+ export { ComponentHierarchyRegistrar, registerComponentHierarchy, validateComponentSpec, flattenComponentHierarchy, countComponentsInHierarchy } from './component-hierarchy';
4
+ export { ReactRootManager, reactRootManager } from './react-root-manager';
27
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":";;;AAKA,mDAK0B;AAJxB,qHAAA,mBAAmB,OAAA;AACnB,mHAAA,iBAAiB,OAAA;AACjB,sHAAA,oBAAoB,OAAA;AACpB,mHAAA,iBAAiB,OAAA;AAInB,+CAUwB;AATtB,mHAAA,mBAAmB,OAAA;AACnB,kHAAA,kBAAkB,OAAA;AAClB,+GAAA,eAAe,OAAA;AACf,sHAAA,sBAAsB,OAAA;AACtB,0GAAA,UAAU,OAAA;AACV,sHAAA,sBAAsB,OAAA;AACtB,wHAAA,wBAAwB,OAAA;AACxB,gHAAA,gBAAgB,OAAA;AAIlB,6DAS+B;AAR7B,kIAAA,2BAA2B,OAAA;AAC3B,iIAAA,0BAA0B,OAAA;AAC1B,4HAAA,qBAAqB,OAAA;AACrB,gIAAA,yBAAyB,OAAA;AACzB,iIAAA,0BAA0B,OAAA;AAM5B,2DAI8B;AAH5B,sHAAA,gBAAgB,OAAA;AAChB,sHAAA,gBAAgB,OAAA","sourcesContent":["/**\n * @fileoverview Runtime module exports\n * @module @memberjunction/react-runtime/runtime\n */\n\nexport {\n createErrorBoundary,\n withErrorBoundary,\n formatComponentError,\n createErrorLogger\n} from './error-boundary';\n\n\nexport {\n buildComponentProps,\n normalizeCallbacks,\n normalizeStyles,\n validateComponentProps,\n mergeProps,\n createPropsTransformer,\n wrapCallbacksWithLogging,\n extractPropPaths,\n PropBuilderOptions\n} from './prop-builder';\n\nexport {\n ComponentHierarchyRegistrar,\n registerComponentHierarchy,\n validateComponentSpec,\n flattenComponentHierarchy,\n countComponentsInHierarchy,\n HierarchyRegistrationResult,\n ComponentRegistrationError,\n HierarchyRegistrationOptions\n} from './component-hierarchy';\n\nexport {\n ReactRootManager,\n reactRootManager,\n ManagedReactRoot\n} from './react-root-manager';"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,UAAU,EACV,sBAAsB,EACtB,wBAAwB,EACxB,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,qBAAqB,EACrB,yBAAyB,EACzB,0BAA0B,EAI3B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAEjB,MAAM,sBAAsB,CAAC","sourcesContent":["/**\n * @fileoverview Runtime module exports\n * @module @memberjunction/react-runtime/runtime\n */\n\nexport {\n createErrorBoundary,\n withErrorBoundary,\n formatComponentError,\n createErrorLogger\n} from './error-boundary';\n\n\nexport {\n buildComponentProps,\n normalizeCallbacks,\n normalizeStyles,\n validateComponentProps,\n mergeProps,\n createPropsTransformer,\n wrapCallbacksWithLogging,\n extractPropPaths,\n PropBuilderOptions\n} from './prop-builder';\n\nexport {\n ComponentHierarchyRegistrar,\n registerComponentHierarchy,\n validateComponentSpec,\n flattenComponentHierarchy,\n countComponentsInHierarchy,\n HierarchyRegistrationResult,\n ComponentRegistrationError,\n HierarchyRegistrationOptions\n} from './component-hierarchy';\n\nexport {\n ReactRootManager,\n reactRootManager,\n ManagedReactRoot\n} from './react-root-manager';"]}
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.extractPropPaths = exports.wrapCallbacksWithLogging = exports.createPropsTransformer = exports.mergeProps = exports.validateComponentProps = exports.normalizeStyles = exports.normalizeCallbacks = exports.buildComponentProps = void 0;
4
- const core_1 = require("@memberjunction/core");
5
- function buildComponentProps(data = {}, userState = {}, utilities = {}, callbacks = {
1
+ import { LogStatus, GetProductionStatus } from '@memberjunction/core';
2
+ export function buildComponentProps(data = {}, userState = {}, utilities = {}, callbacks = {
6
3
  OpenEntityRecord: () => { },
7
4
  RegisterMethod: () => { },
8
5
  CreateSimpleNotification: () => { }
@@ -24,7 +21,6 @@ function buildComponentProps(data = {}, userState = {}, utilities = {}, callback
24
21
  }
25
22
  return props;
26
23
  }
27
- exports.buildComponentProps = buildComponentProps;
28
24
  const updateUserStateSubjects = new WeakMap();
29
25
  const updateUserStateSubscriptions = new WeakMap();
30
26
  const loopDetectionStates = new WeakMap();
@@ -47,7 +43,7 @@ function deepEqual(obj1, obj2) {
47
43
  }
48
44
  return true;
49
45
  }
50
- function normalizeCallbacks(callbacks, debounceMs = 3000) {
46
+ export function normalizeCallbacks(callbacks, debounceMs = 3000) {
51
47
  const normalized = {
52
48
  OpenEntityRecord: callbacks?.OpenEntityRecord || (() => { }),
53
49
  RegisterMethod: callbacks?.RegisterMethod || (() => { }),
@@ -62,12 +58,10 @@ function normalizeCallbacks(callbacks, debounceMs = 3000) {
62
58
  }
63
59
  return normalized;
64
60
  }
65
- exports.normalizeCallbacks = normalizeCallbacks;
66
- function normalizeStyles(styles) {
61
+ export function normalizeStyles(styles) {
67
62
  return styles;
68
63
  }
69
- exports.normalizeStyles = normalizeStyles;
70
- function validateComponentProps(props) {
64
+ export function validateComponentProps(props) {
71
65
  if (props.data === null || props.data === undefined) {
72
66
  throw new Error('Component props.data cannot be null or undefined');
73
67
  }
@@ -86,8 +80,7 @@ function validateComponentProps(props) {
86
80
  }
87
81
  }
88
82
  }
89
- exports.validateComponentProps = validateComponentProps;
90
- function mergeProps(...propsList) {
83
+ export function mergeProps(...propsList) {
91
84
  const merged = {
92
85
  data: {},
93
86
  userState: {},
@@ -118,8 +111,7 @@ function mergeProps(...propsList) {
118
111
  }
119
112
  return merged;
120
113
  }
121
- exports.mergeProps = mergeProps;
122
- function createPropsTransformer(transformations) {
114
+ export function createPropsTransformer(transformations) {
123
115
  return (props) => {
124
116
  const transformed = { ...props };
125
117
  for (const [path, transformer] of Object.entries(transformations)) {
@@ -139,8 +131,7 @@ function createPropsTransformer(transformations) {
139
131
  return transformed;
140
132
  };
141
133
  }
142
- exports.createPropsTransformer = createPropsTransformer;
143
- function wrapCallbacksWithLogging(callbacks, componentName) {
134
+ export function wrapCallbacksWithLogging(callbacks, componentName) {
144
135
  const wrapped = {
145
136
  OpenEntityRecord: callbacks?.OpenEntityRecord || (() => { }),
146
137
  RegisterMethod: callbacks?.RegisterMethod || (() => { }),
@@ -149,8 +140,8 @@ function wrapCallbacksWithLogging(callbacks, componentName) {
149
140
  Object.keys(callbacks).forEach(key => {
150
141
  if (key !== 'OpenEntityRecord' && key !== 'RegisterMethod' && key !== 'CreateSimpleNotification' && typeof callbacks[key] === 'function') {
151
142
  wrapped[key] = (...args) => {
152
- if (!(0, core_1.GetProductionStatus)()) {
153
- (0, core_1.LogStatus)(`[${componentName}] ${key} called with args:`, undefined, args);
143
+ if (!GetProductionStatus()) {
144
+ LogStatus(`[${componentName}] ${key} called with args:`, undefined, args);
154
145
  }
155
146
  return callbacks[key](...args);
156
147
  };
@@ -158,32 +149,31 @@ function wrapCallbacksWithLogging(callbacks, componentName) {
158
149
  });
159
150
  if (callbacks.OpenEntityRecord) {
160
151
  wrapped.OpenEntityRecord = (entityName, key) => {
161
- if (!(0, core_1.GetProductionStatus)()) {
162
- (0, core_1.LogStatus)(`[${componentName}] OpenEntityRecord called:`, undefined, { entityName, key });
152
+ if (!GetProductionStatus()) {
153
+ LogStatus(`[${componentName}] OpenEntityRecord called:`, undefined, { entityName, key });
163
154
  }
164
155
  callbacks.OpenEntityRecord(entityName, key);
165
156
  };
166
157
  }
167
158
  if (callbacks.RegisterMethod) {
168
159
  wrapped.RegisterMethod = (methodName, handler) => {
169
- if (!(0, core_1.GetProductionStatus)()) {
170
- (0, core_1.LogStatus)(`[${componentName}] RegisterMethod called for:`, undefined, methodName);
160
+ if (!GetProductionStatus()) {
161
+ LogStatus(`[${componentName}] RegisterMethod called for:`, undefined, methodName);
171
162
  }
172
163
  callbacks.RegisterMethod(methodName, handler);
173
164
  };
174
165
  }
175
166
  if (callbacks.CreateSimpleNotification) {
176
167
  wrapped.CreateSimpleNotification = (message, style, hideAfter) => {
177
- if (!(0, core_1.GetProductionStatus)()) {
178
- (0, core_1.LogStatus)(`[${componentName}] CreateSimpleNotification called:`, undefined, { message, style, hideAfter });
168
+ if (!GetProductionStatus()) {
169
+ LogStatus(`[${componentName}] CreateSimpleNotification called:`, undefined, { message, style, hideAfter });
179
170
  }
180
171
  callbacks.CreateSimpleNotification(message, style, hideAfter);
181
172
  };
182
173
  }
183
174
  return wrapped;
184
175
  }
185
- exports.wrapCallbacksWithLogging = wrapCallbacksWithLogging;
186
- function extractPropPaths(componentCode) {
176
+ export function extractPropPaths(componentCode) {
187
177
  const paths = [];
188
178
  const patterns = [
189
179
  /props\.data\.(\w+)/g,
@@ -199,5 +189,4 @@ function extractPropPaths(componentCode) {
199
189
  }
200
190
  return [...new Set(paths)];
201
191
  }
202
- exports.extractPropPaths = extractPropPaths;
203
192
  //# sourceMappingURL=prop-builder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prop-builder.js","sourceRoot":"","sources":["../../src/runtime/prop-builder.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Props builder utilities for React components.\n * Provides utilities for constructing and validating component props.\n * @module @memberjunction/react-runtime/runtime\n */\n\nimport { ComponentStyles, ComponentCallbacks } from '@memberjunction/interactive-component-types';\nimport { ComponentProps } from '../types';\nimport { Subject, debounceTime, Subscription } from 'rxjs';\nimport { LogStatus, GetProductionStatus } from '@memberjunction/core';\n\n/**\n * Options for building component props\n */\nexport interface PropBuilderOptions {\n /** Validate props before building */\n validate?: boolean;\n /** Merge with existing props */\n merge?: boolean;\n /** Transform data before passing to component */\n transformData?: (data: any) => any;\n /** Transform state before passing to component */\n transformState?: (state: any) => any;\n /** Debounce time for UpdateUserState callback in milliseconds */\n debounceUpdateUserState?: number;\n}\n\n/**\n * Builds component props from various sources\n * @param data - Component data\n * @param userState - User state object\n * @param utilities - Utility functions\n * @param callbacks - Component callbacks\n * @param components - Child components\n * @param styles - Component styles\n * @param options - Builder options\n * @returns Built component props\n */\nexport function buildComponentProps(\n data: any = {},\n userState: any = {},\n utilities: any = {},\n callbacks: ComponentCallbacks = {\n OpenEntityRecord: () => {},\n RegisterMethod: () => {},\n CreateSimpleNotification: () => {}\n },\n components: Record<string, any> = {},\n styles?: ComponentStyles,\n options: PropBuilderOptions = {},\n onStateChanged?: (stateUpdate: Record<string, any>) => void\n): ComponentProps {\n const {\n validate = true,\n transformData,\n transformState,\n debounceUpdateUserState = 3000 // Default 3 seconds\n } = options;\n\n // Transform data if transformer provided\n const transformedData = transformData ? transformData(data) : data;\n const transformedState = transformState ? transformState(userState) : userState;\n\n // Build props object\n const props: ComponentProps = {\n data: transformedData,\n userState: transformedState,\n utilities,\n callbacks: normalizeCallbacks(callbacks, debounceUpdateUserState),\n components,\n styles: normalizeStyles(styles),\n onStateChanged\n };\n\n // Validate if enabled\n if (validate) {\n validateComponentProps(props);\n }\n\n return props;\n}\n\n// Store subjects for debouncing per component instance\nconst updateUserStateSubjects = new WeakMap<Function, Subject<any>>();\n\n// Store subscriptions for cleanup\nconst updateUserStateSubscriptions = new WeakMap<Function, Subscription>();\n\n// Loop detection state\ninterface LoopDetectionState {\n count: number;\n lastUpdate: number;\n lastState: any;\n}\nconst loopDetectionStates = new WeakMap<Function, LoopDetectionState>();\n\n// Deep equality check for objects\nfunction deepEqual(obj1: any, obj2: any): boolean {\n if (obj1 === obj2) return true;\n \n if (!obj1 || !obj2) return false;\n if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return false;\n \n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n \n if (keys1.length !== keys2.length) return false;\n \n for (const key of keys1) {\n if (!keys2.includes(key)) return false;\n if (!deepEqual(obj1[key], obj2[key])) return false;\n }\n \n return true;\n}\n\n/**\n * Normalizes component callbacks\n * @param callbacks - Raw callbacks object\n * @param debounceMs - Debounce time for UpdateUserState in milliseconds\n * @returns Normalized callbacks\n */\nexport function normalizeCallbacks(callbacks: any, debounceMs: number = 3000): ComponentCallbacks {\n // Provide default implementations for required callbacks\n const normalized: ComponentCallbacks = {\n OpenEntityRecord: callbacks?.OpenEntityRecord || (() => {}),\n RegisterMethod: callbacks?.RegisterMethod || (() => {}),\n CreateSimpleNotification: callbacks?.CreateSimpleNotification || (() => {})\n };\n\n // Copy any additional callbacks that might exist\n if (callbacks) {\n Object.keys(callbacks).forEach(key => {\n if (typeof callbacks[key] === 'function' && !normalized.hasOwnProperty(key)) {\n (normalized as any)[key] = callbacks[key];\n }\n });\n }\n\n return normalized;\n}\n\n/**\n * Normalizes component styles\n * @param styles - Raw styles object\n * @returns Normalized styles\n */\nexport function normalizeStyles(styles?: any): any {\n // Pass through the full styles object as-is\n // This allows Skip components to access their full style structure\n // including colors, typography, borders, etc.\n return styles;\n}\n\n/**\n * Validates component props\n * @param props - Props to validate\n * @throws Error if validation fails\n */\nexport function validateComponentProps(props: ComponentProps): void {\n // Validate data\n if (props.data === null || props.data === undefined) {\n throw new Error('Component props.data cannot be null or undefined');\n }\n\n // Validate userState\n if (props.userState === null) {\n throw new Error('Component props.userState cannot be null');\n }\n\n // Validate utilities\n if (props.utilities === null) {\n throw new Error('Component props.utilities cannot be null');\n }\n\n // Validate callbacks\n if (!props.callbacks || typeof props.callbacks !== 'object') {\n throw new Error('Component props.callbacks must be an object');\n }\n\n // Validate callback functions\n for (const [key, value] of Object.entries(props.callbacks)) {\n if (value !== undefined && typeof value !== 'function') {\n throw new Error(`Component callback \"${key}\" must be a function`);\n }\n }\n}\n\n/**\n * Merges multiple prop objects\n * @param propsList - Array of props to merge\n * @returns Merged props\n */\nexport function mergeProps(...propsList: Partial<ComponentProps>[]): ComponentProps {\n const merged: ComponentProps = {\n data: {},\n userState: {},\n utilities: {},\n callbacks: {},\n components: {},\n styles: {} as ComponentStyles\n };\n\n for (const props of propsList) {\n if (props.data) {\n merged.data = { ...merged.data, ...props.data };\n }\n\n if (props.userState) {\n merged.userState = { ...merged.userState, ...props.userState };\n }\n\n if (props.utilities) {\n merged.utilities = { ...merged.utilities, ...props.utilities };\n }\n\n if (props.callbacks) {\n merged.callbacks = { ...merged.callbacks, ...props.callbacks };\n }\n\n if (props.components) {\n merged.components = { ...merged.components, ...props.components };\n }\n\n if (props.styles) {\n merged.styles = { ...merged.styles, ...props.styles };\n }\n }\n\n return merged;\n}\n \n/**\n * Creates a props transformer function\n * @param transformations - Map of prop paths to transformer functions\n * @returns Props transformer\n */\nexport function createPropsTransformer(\n transformations: Record<string, (value: any) => any>\n): (props: ComponentProps) => ComponentProps {\n return (props: ComponentProps) => {\n const transformed = { ...props };\n\n for (const [path, transformer] of Object.entries(transformations)) {\n const pathParts = path.split('.');\n let current: any = transformed;\n \n // Navigate to the parent of the target property\n for (let i = 0; i < pathParts.length - 1; i++) {\n if (!current[pathParts[i]]) {\n current[pathParts[i]] = {};\n }\n current = current[pathParts[i]];\n }\n\n // Apply transformation\n const lastPart = pathParts[pathParts.length - 1];\n if (current[lastPart] !== undefined) {\n current[lastPart] = transformer(current[lastPart]);\n }\n }\n\n return transformed;\n };\n}\n\n/**\n * Creates a callback wrapper that adds logging\n * @param callbacks - Original callbacks\n * @param componentName - Component name for logging\n * @returns Wrapped callbacks\n */\nexport function wrapCallbacksWithLogging(\n callbacks: ComponentCallbacks,\n componentName: string\n): ComponentCallbacks {\n const wrapped: ComponentCallbacks = {\n OpenEntityRecord: callbacks?.OpenEntityRecord || (() => {}),\n RegisterMethod: callbacks?.RegisterMethod || (() => {}),\n CreateSimpleNotification: callbacks?.CreateSimpleNotification || (() => {})\n };\n\n // Wrap any additional callbacks that might exist\n Object.keys(callbacks).forEach(key => {\n if (key !== 'OpenEntityRecord' && key !== 'RegisterMethod' && key !== 'CreateSimpleNotification' && typeof (callbacks as any)[key] === 'function') {\n (wrapped as any)[key] = (...args: any[]) => {\n if (!GetProductionStatus()) {\n LogStatus(`[${componentName}] ${key} called with args:`, undefined, args);\n }\n return (callbacks as any)[key](...args);\n };\n }\n });\n\n if (callbacks.OpenEntityRecord) {\n wrapped.OpenEntityRecord = (entityName: string, key: any) => {\n if (!GetProductionStatus()) {\n LogStatus(`[${componentName}] OpenEntityRecord called:`, undefined, { entityName, key });\n }\n callbacks.OpenEntityRecord!(entityName, key);\n };\n }\n\n if (callbacks.RegisterMethod) {\n wrapped.RegisterMethod = (methodName: any, handler: any) => {\n if (!GetProductionStatus()) {\n LogStatus(`[${componentName}] RegisterMethod called for:`, undefined, methodName);\n }\n callbacks.RegisterMethod!(methodName, handler);\n };\n }\n\n if (callbacks.CreateSimpleNotification) {\n wrapped.CreateSimpleNotification = (message: string, style: \"none\" | \"success\" | \"error\" | \"warning\" | \"info\", hideAfter?: number) => {\n if (!GetProductionStatus()) {\n LogStatus(`[${componentName}] CreateSimpleNotification called:`, undefined, { message, style, hideAfter });\n }\n callbacks.CreateSimpleNotification!(message, style, hideAfter);\n };\n }\n\n return wrapped;\n}\n\n/**\n * Extracts props paths used by a component\n * @param componentCode - Component source code\n * @returns Array of prop paths\n */\nexport function extractPropPaths(componentCode: string): string[] {\n const paths: string[] = [];\n \n // Simple regex patterns to find prop access\n const patterns = [\n /props\\.data\\.(\\w+)/g,\n /props\\.userState\\.(\\w+)/g,\n /props\\.utilities\\.(\\w+)/g,\n /props\\.callbacks\\.(\\w+)/g\n ];\n\n for (const pattern of patterns) {\n let match;\n while ((match = pattern.exec(componentCode)) !== null) {\n paths.push(match[0]);\n }\n }\n\n return [...new Set(paths)]; // Remove duplicates\n}"]}
1
+ {"version":3,"file":"prop-builder.js","sourceRoot":"","sources":["../../src/runtime/prop-builder.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Props builder utilities for React components.\n * Provides utilities for constructing and validating component props.\n * @module @memberjunction/react-runtime/runtime\n */\n\nimport { ComponentStyles, ComponentCallbacks } from '@memberjunction/interactive-component-types';\nimport { ComponentProps } from '../types';\nimport { Subject, debounceTime, Subscription } from 'rxjs';\nimport { LogStatus, GetProductionStatus } from '@memberjunction/core';\n\n/**\n * Options for building component props\n */\nexport interface PropBuilderOptions {\n /** Validate props before building */\n validate?: boolean;\n /** Merge with existing props */\n merge?: boolean;\n /** Transform data before passing to component */\n transformData?: (data: any) => any;\n /** Transform state before passing to component */\n transformState?: (state: any) => any;\n /** Debounce time for UpdateUserState callback in milliseconds */\n debounceUpdateUserState?: number;\n}\n\n/**\n * Builds component props from various sources\n * @param data - Component data\n * @param userState - User state object\n * @param utilities - Utility functions\n * @param callbacks - Component callbacks\n * @param components - Child components\n * @param styles - Component styles\n * @param options - Builder options\n * @returns Built component props\n */\nexport function buildComponentProps(\n data: any = {},\n userState: any = {},\n utilities: any = {},\n callbacks: ComponentCallbacks = {\n OpenEntityRecord: () => {},\n RegisterMethod: () => {},\n CreateSimpleNotification: () => {}\n },\n components: Record<string, any> = {},\n styles?: ComponentStyles,\n options: PropBuilderOptions = {},\n onStateChanged?: (stateUpdate: Record<string, any>) => void\n): ComponentProps {\n const {\n validate = true,\n transformData,\n transformState,\n debounceUpdateUserState = 3000 // Default 3 seconds\n } = options;\n\n // Transform data if transformer provided\n const transformedData = transformData ? transformData(data) : data;\n const transformedState = transformState ? transformState(userState) : userState;\n\n // Build props object\n const props: ComponentProps = {\n data: transformedData,\n userState: transformedState,\n utilities,\n callbacks: normalizeCallbacks(callbacks, debounceUpdateUserState),\n components,\n styles: normalizeStyles(styles),\n onStateChanged\n };\n\n // Validate if enabled\n if (validate) {\n validateComponentProps(props);\n }\n\n return props;\n}\n\n// Store subjects for debouncing per component instance\nconst updateUserStateSubjects = new WeakMap<Function, Subject<any>>();\n\n// Store subscriptions for cleanup\nconst updateUserStateSubscriptions = new WeakMap<Function, Subscription>();\n\n// Loop detection state\ninterface LoopDetectionState {\n count: number;\n lastUpdate: number;\n lastState: any;\n}\nconst loopDetectionStates = new WeakMap<Function, LoopDetectionState>();\n\n// Deep equality check for objects\nfunction deepEqual(obj1: any, obj2: any): boolean {\n if (obj1 === obj2) return true;\n \n if (!obj1 || !obj2) return false;\n if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return false;\n \n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n \n if (keys1.length !== keys2.length) return false;\n \n for (const key of keys1) {\n if (!keys2.includes(key)) return false;\n if (!deepEqual(obj1[key], obj2[key])) return false;\n }\n \n return true;\n}\n\n/**\n * Normalizes component callbacks\n * @param callbacks - Raw callbacks object\n * @param debounceMs - Debounce time for UpdateUserState in milliseconds\n * @returns Normalized callbacks\n */\nexport function normalizeCallbacks(callbacks: any, debounceMs: number = 3000): ComponentCallbacks {\n // Provide default implementations for required callbacks\n const normalized: ComponentCallbacks = {\n OpenEntityRecord: callbacks?.OpenEntityRecord || (() => {}),\n RegisterMethod: callbacks?.RegisterMethod || (() => {}),\n CreateSimpleNotification: callbacks?.CreateSimpleNotification || (() => {})\n };\n\n // Copy any additional callbacks that might exist\n if (callbacks) {\n Object.keys(callbacks).forEach(key => {\n if (typeof callbacks[key] === 'function' && !normalized.hasOwnProperty(key)) {\n (normalized as any)[key] = callbacks[key];\n }\n });\n }\n\n return normalized;\n}\n\n/**\n * Normalizes component styles\n * @param styles - Raw styles object\n * @returns Normalized styles\n */\nexport function normalizeStyles(styles?: any): any {\n // Pass through the full styles object as-is\n // This allows Skip components to access their full style structure\n // including colors, typography, borders, etc.\n return styles;\n}\n\n/**\n * Validates component props\n * @param props - Props to validate\n * @throws Error if validation fails\n */\nexport function validateComponentProps(props: ComponentProps): void {\n // Validate data\n if (props.data === null || props.data === undefined) {\n throw new Error('Component props.data cannot be null or undefined');\n }\n\n // Validate userState\n if (props.userState === null) {\n throw new Error('Component props.userState cannot be null');\n }\n\n // Validate utilities\n if (props.utilities === null) {\n throw new Error('Component props.utilities cannot be null');\n }\n\n // Validate callbacks\n if (!props.callbacks || typeof props.callbacks !== 'object') {\n throw new Error('Component props.callbacks must be an object');\n }\n\n // Validate callback functions\n for (const [key, value] of Object.entries(props.callbacks)) {\n if (value !== undefined && typeof value !== 'function') {\n throw new Error(`Component callback \"${key}\" must be a function`);\n }\n }\n}\n\n/**\n * Merges multiple prop objects\n * @param propsList - Array of props to merge\n * @returns Merged props\n */\nexport function mergeProps(...propsList: Partial<ComponentProps>[]): ComponentProps {\n const merged: ComponentProps = {\n data: {},\n userState: {},\n utilities: {},\n callbacks: {},\n components: {},\n styles: {} as ComponentStyles\n };\n\n for (const props of propsList) {\n if (props.data) {\n merged.data = { ...merged.data, ...props.data };\n }\n\n if (props.userState) {\n merged.userState = { ...merged.userState, ...props.userState };\n }\n\n if (props.utilities) {\n merged.utilities = { ...merged.utilities, ...props.utilities };\n }\n\n if (props.callbacks) {\n merged.callbacks = { ...merged.callbacks, ...props.callbacks };\n }\n\n if (props.components) {\n merged.components = { ...merged.components, ...props.components };\n }\n\n if (props.styles) {\n merged.styles = { ...merged.styles, ...props.styles };\n }\n }\n\n return merged;\n}\n \n/**\n * Creates a props transformer function\n * @param transformations - Map of prop paths to transformer functions\n * @returns Props transformer\n */\nexport function createPropsTransformer(\n transformations: Record<string, (value: any) => any>\n): (props: ComponentProps) => ComponentProps {\n return (props: ComponentProps) => {\n const transformed = { ...props };\n\n for (const [path, transformer] of Object.entries(transformations)) {\n const pathParts = path.split('.');\n let current: any = transformed;\n \n // Navigate to the parent of the target property\n for (let i = 0; i < pathParts.length - 1; i++) {\n if (!current[pathParts[i]]) {\n current[pathParts[i]] = {};\n }\n current = current[pathParts[i]];\n }\n\n // Apply transformation\n const lastPart = pathParts[pathParts.length - 1];\n if (current[lastPart] !== undefined) {\n current[lastPart] = transformer(current[lastPart]);\n }\n }\n\n return transformed;\n };\n}\n\n/**\n * Creates a callback wrapper that adds logging\n * @param callbacks - Original callbacks\n * @param componentName - Component name for logging\n * @returns Wrapped callbacks\n */\nexport function wrapCallbacksWithLogging(\n callbacks: ComponentCallbacks,\n componentName: string\n): ComponentCallbacks {\n const wrapped: ComponentCallbacks = {\n OpenEntityRecord: callbacks?.OpenEntityRecord || (() => {}),\n RegisterMethod: callbacks?.RegisterMethod || (() => {}),\n CreateSimpleNotification: callbacks?.CreateSimpleNotification || (() => {})\n };\n\n // Wrap any additional callbacks that might exist\n Object.keys(callbacks).forEach(key => {\n if (key !== 'OpenEntityRecord' && key !== 'RegisterMethod' && key !== 'CreateSimpleNotification' && typeof (callbacks as any)[key] === 'function') {\n (wrapped as any)[key] = (...args: any[]) => {\n if (!GetProductionStatus()) {\n LogStatus(`[${componentName}] ${key} called with args:`, undefined, args);\n }\n return (callbacks as any)[key](...args);\n };\n }\n });\n\n if (callbacks.OpenEntityRecord) {\n wrapped.OpenEntityRecord = (entityName: string, key: any) => {\n if (!GetProductionStatus()) {\n LogStatus(`[${componentName}] OpenEntityRecord called:`, undefined, { entityName, key });\n }\n callbacks.OpenEntityRecord!(entityName, key);\n };\n }\n\n if (callbacks.RegisterMethod) {\n wrapped.RegisterMethod = (methodName: any, handler: any) => {\n if (!GetProductionStatus()) {\n LogStatus(`[${componentName}] RegisterMethod called for:`, undefined, methodName);\n }\n callbacks.RegisterMethod!(methodName, handler);\n };\n }\n\n if (callbacks.CreateSimpleNotification) {\n wrapped.CreateSimpleNotification = (message: string, style: \"none\" | \"success\" | \"error\" | \"warning\" | \"info\", hideAfter?: number) => {\n if (!GetProductionStatus()) {\n LogStatus(`[${componentName}] CreateSimpleNotification called:`, undefined, { message, style, hideAfter });\n }\n callbacks.CreateSimpleNotification!(message, style, hideAfter);\n };\n }\n\n return wrapped;\n}\n\n/**\n * Extracts props paths used by a component\n * @param componentCode - Component source code\n * @returns Array of prop paths\n */\nexport function extractPropPaths(componentCode: string): string[] {\n const paths: string[] = [];\n \n // Simple regex patterns to find prop access\n const patterns = [\n /props\\.data\\.(\\w+)/g,\n /props\\.userState\\.(\\w+)/g,\n /props\\.utilities\\.(\\w+)/g,\n /props\\.callbacks\\.(\\w+)/g\n ];\n\n for (const pattern of patterns) {\n let match;\n while ((match = pattern.exec(componentCode)) !== null) {\n paths.push(match[0]);\n }\n }\n\n return [...new Set(paths)]; // Remove duplicates\n}"]}
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.reactRootManager = exports.ReactRootManager = void 0;
4
- const resource_manager_1 = require("../utilities/resource-manager");
5
- class ReactRootManager {
1
+ import { resourceManager } from '../utilities/resource-manager';
2
+ export class ReactRootManager {
6
3
  constructor() {
7
4
  this.roots = new Map();
8
5
  this.renderingRoots = new Set();
@@ -20,7 +17,7 @@ class ReactRootManager {
20
17
  };
21
18
  this.roots.set(rootId, managedRoot);
22
19
  if (componentId) {
23
- resource_manager_1.resourceManager.registerReactRoot(componentId, root, () => this.unmountRoot(rootId));
20
+ resourceManager.registerReactRoot(componentId, root, () => this.unmountRoot(rootId));
24
21
  }
25
22
  return rootId;
26
23
  }
@@ -117,6 +114,5 @@ class ReactRootManager {
117
114
  await Promise.all(allRootIds.map(id => this.unmountRoot(id, true)));
118
115
  }
119
116
  }
120
- exports.ReactRootManager = ReactRootManager;
121
- exports.reactRootManager = new ReactRootManager();
117
+ export const reactRootManager = new ReactRootManager();
122
118
  //# sourceMappingURL=react-root-manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"react-root-manager.js","sourceRoot":"","sources":["../../src/runtime/react-root-manager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview React root lifecycle management for preventing memory leaks\n * @module @memberjunction/react-runtime/runtime\n */\n\nimport { resourceManager } from '../utilities/resource-manager';\n\nexport interface ManagedReactRoot {\n id: string;\n root: any; // React root instance\n container: HTMLElement;\n isRendering: boolean;\n lastRenderTime?: Date;\n componentId?: string;\n}\n\n/**\n * Manages React root instances to prevent memory leaks and ensure proper cleanup.\n * Handles safe rendering and unmounting with protection against concurrent operations.\n */\nexport class ReactRootManager {\n private roots = new Map<string, ManagedReactRoot>();\n private renderingRoots = new Set<string>();\n private unmountQueue = new Map<string, () => void>();\n \n /**\n * Create a new managed React root\n * @param container - The DOM container element\n * @param createRootFn - Function to create the React root (e.g., ReactDOM.createRoot)\n * @param componentId - Optional component ID for resource tracking\n * @returns The root ID for future operations\n */\n createRoot(\n container: HTMLElement,\n createRootFn: (container: HTMLElement) => any,\n componentId?: string\n ): string {\n const rootId = `react-root-${Date.now()}-${Math.random()}`;\n const root = createRootFn(container);\n \n const managedRoot: ManagedReactRoot = {\n id: rootId,\n root,\n container,\n isRendering: false,\n componentId\n };\n \n this.roots.set(rootId, managedRoot);\n \n // Register with resource manager if component ID provided\n if (componentId) {\n resourceManager.registerReactRoot(\n componentId,\n root,\n () => this.unmountRoot(rootId)\n );\n }\n \n return rootId;\n }\n \n /**\n * Safely render content to a React root\n * @param rootId - The root ID\n * @param element - React element to render\n * @param onComplete - Optional callback when render completes\n */\n render(\n rootId: string,\n element: any,\n onComplete?: () => void\n ): void {\n const managedRoot = this.roots.get(rootId);\n if (!managedRoot) {\n console.warn(`React root ${rootId} not found`);\n return;\n }\n \n // Don't render if we're already unmounting\n if (this.unmountQueue.has(rootId)) {\n console.warn(`React root ${rootId} is being unmounted, skipping render`);\n return;\n }\n \n // Mark as rendering\n managedRoot.isRendering = true;\n this.renderingRoots.add(rootId);\n \n try {\n managedRoot.root.render(element);\n managedRoot.lastRenderTime = new Date();\n \n // Use microtask to ensure React has completed its work\n Promise.resolve().then(() => {\n managedRoot.isRendering = false;\n this.renderingRoots.delete(rootId);\n \n // Process any pending unmount\n const pendingUnmount = this.unmountQueue.get(rootId);\n if (pendingUnmount) {\n this.unmountQueue.delete(rootId);\n pendingUnmount();\n }\n \n if (onComplete) {\n onComplete();\n }\n });\n } catch (error) {\n // Clean up rendering state on error\n managedRoot.isRendering = false;\n this.renderingRoots.delete(rootId);\n throw error;\n }\n }\n \n /**\n * Safely unmount a React root\n * @param rootId - The root ID\n * @param force - Force unmount even if rendering\n */\n unmountRoot(rootId: string, force: boolean = false): Promise<void> {\n return new Promise((resolve) => {\n const managedRoot = this.roots.get(rootId);\n if (!managedRoot) {\n resolve();\n return;\n }\n \n const performUnmount = () => {\n try {\n managedRoot.root.unmount();\n this.roots.delete(rootId);\n this.renderingRoots.delete(rootId);\n \n // Clean up container to ensure no dangling references\n if (managedRoot.container) {\n // Clear React's internal references\n delete (managedRoot.container as any)._reactRootContainer;\n // Clear the container content without replacing the node\n managedRoot.container.innerHTML = '';\n }\n \n resolve();\n } catch (error) {\n console.error(`Error unmounting React root ${rootId}:`, error);\n // Still clean up our tracking even if unmount failed\n this.roots.delete(rootId);\n this.renderingRoots.delete(rootId);\n resolve();\n }\n };\n \n // If not rendering or force unmount, unmount immediately\n if (!managedRoot.isRendering || force) {\n performUnmount();\n } else {\n // Queue unmount for after rendering completes\n this.unmountQueue.set(rootId, () => {\n performUnmount();\n });\n }\n });\n }\n \n /**\n * Unmount all roots associated with a component\n * @param componentId - The component ID\n */\n async unmountComponentRoots(componentId: string): Promise<void> {\n const rootIds: string[] = [];\n \n for (const [rootId, managedRoot] of this.roots) {\n if (managedRoot.componentId === componentId) {\n rootIds.push(rootId);\n }\n }\n \n await Promise.all(rootIds.map(id => this.unmountRoot(id)));\n }\n \n /**\n * Check if a root is currently rendering\n * @param rootId - The root ID\n * @returns true if rendering\n */\n isRendering(rootId: string): boolean {\n return this.renderingRoots.has(rootId);\n }\n \n /**\n * Get statistics about managed roots\n */\n getStats(): {\n totalRoots: number;\n renderingRoots: number;\n pendingUnmounts: number;\n } {\n return {\n totalRoots: this.roots.size,\n renderingRoots: this.renderingRoots.size,\n pendingUnmounts: this.unmountQueue.size\n };\n }\n \n /**\n * Clean up all roots (for testing or shutdown)\n */\n async cleanup(): Promise<void> {\n const allRootIds = Array.from(this.roots.keys());\n await Promise.all(allRootIds.map(id => this.unmountRoot(id, true)));\n }\n}\n\n// Singleton instance\nexport const reactRootManager = new ReactRootManager();"]}
1
+ {"version":3,"file":"react-root-manager.js","sourceRoot":"","sources":["../../src/runtime/react-root-manager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview React root lifecycle management for preventing memory leaks\n * @module @memberjunction/react-runtime/runtime\n */\n\nimport { resourceManager } from '../utilities/resource-manager';\n\nexport interface ManagedReactRoot {\n id: string;\n root: any; // React root instance\n container: HTMLElement;\n isRendering: boolean;\n lastRenderTime?: Date;\n componentId?: string;\n}\n\n/**\n * Manages React root instances to prevent memory leaks and ensure proper cleanup.\n * Handles safe rendering and unmounting with protection against concurrent operations.\n */\nexport class ReactRootManager {\n private roots = new Map<string, ManagedReactRoot>();\n private renderingRoots = new Set<string>();\n private unmountQueue = new Map<string, () => void>();\n \n /**\n * Create a new managed React root\n * @param container - The DOM container element\n * @param createRootFn - Function to create the React root (e.g., ReactDOM.createRoot)\n * @param componentId - Optional component ID for resource tracking\n * @returns The root ID for future operations\n */\n createRoot(\n container: HTMLElement,\n createRootFn: (container: HTMLElement) => any,\n componentId?: string\n ): string {\n const rootId = `react-root-${Date.now()}-${Math.random()}`;\n const root = createRootFn(container);\n \n const managedRoot: ManagedReactRoot = {\n id: rootId,\n root,\n container,\n isRendering: false,\n componentId\n };\n \n this.roots.set(rootId, managedRoot);\n \n // Register with resource manager if component ID provided\n if (componentId) {\n resourceManager.registerReactRoot(\n componentId,\n root,\n () => this.unmountRoot(rootId)\n );\n }\n \n return rootId;\n }\n \n /**\n * Safely render content to a React root\n * @param rootId - The root ID\n * @param element - React element to render\n * @param onComplete - Optional callback when render completes\n */\n render(\n rootId: string,\n element: any,\n onComplete?: () => void\n ): void {\n const managedRoot = this.roots.get(rootId);\n if (!managedRoot) {\n console.warn(`React root ${rootId} not found`);\n return;\n }\n \n // Don't render if we're already unmounting\n if (this.unmountQueue.has(rootId)) {\n console.warn(`React root ${rootId} is being unmounted, skipping render`);\n return;\n }\n \n // Mark as rendering\n managedRoot.isRendering = true;\n this.renderingRoots.add(rootId);\n \n try {\n managedRoot.root.render(element);\n managedRoot.lastRenderTime = new Date();\n \n // Use microtask to ensure React has completed its work\n Promise.resolve().then(() => {\n managedRoot.isRendering = false;\n this.renderingRoots.delete(rootId);\n \n // Process any pending unmount\n const pendingUnmount = this.unmountQueue.get(rootId);\n if (pendingUnmount) {\n this.unmountQueue.delete(rootId);\n pendingUnmount();\n }\n \n if (onComplete) {\n onComplete();\n }\n });\n } catch (error) {\n // Clean up rendering state on error\n managedRoot.isRendering = false;\n this.renderingRoots.delete(rootId);\n throw error;\n }\n }\n \n /**\n * Safely unmount a React root\n * @param rootId - The root ID\n * @param force - Force unmount even if rendering\n */\n unmountRoot(rootId: string, force: boolean = false): Promise<void> {\n return new Promise((resolve) => {\n const managedRoot = this.roots.get(rootId);\n if (!managedRoot) {\n resolve();\n return;\n }\n \n const performUnmount = () => {\n try {\n managedRoot.root.unmount();\n this.roots.delete(rootId);\n this.renderingRoots.delete(rootId);\n \n // Clean up container to ensure no dangling references\n if (managedRoot.container) {\n // Clear React's internal references\n delete (managedRoot.container as any)._reactRootContainer;\n // Clear the container content without replacing the node\n managedRoot.container.innerHTML = '';\n }\n \n resolve();\n } catch (error) {\n console.error(`Error unmounting React root ${rootId}:`, error);\n // Still clean up our tracking even if unmount failed\n this.roots.delete(rootId);\n this.renderingRoots.delete(rootId);\n resolve();\n }\n };\n \n // If not rendering or force unmount, unmount immediately\n if (!managedRoot.isRendering || force) {\n performUnmount();\n } else {\n // Queue unmount for after rendering completes\n this.unmountQueue.set(rootId, () => {\n performUnmount();\n });\n }\n });\n }\n \n /**\n * Unmount all roots associated with a component\n * @param componentId - The component ID\n */\n async unmountComponentRoots(componentId: string): Promise<void> {\n const rootIds: string[] = [];\n \n for (const [rootId, managedRoot] of this.roots) {\n if (managedRoot.componentId === componentId) {\n rootIds.push(rootId);\n }\n }\n \n await Promise.all(rootIds.map(id => this.unmountRoot(id)));\n }\n \n /**\n * Check if a root is currently rendering\n * @param rootId - The root ID\n * @returns true if rendering\n */\n isRendering(rootId: string): boolean {\n return this.renderingRoots.has(rootId);\n }\n \n /**\n * Get statistics about managed roots\n */\n getStats(): {\n totalRoots: number;\n renderingRoots: number;\n pendingUnmounts: number;\n } {\n return {\n totalRoots: this.roots.size,\n renderingRoots: this.renderingRoots.size,\n pendingUnmounts: this.unmountQueue.size\n };\n }\n \n /**\n * Clean up all roots (for testing or shutdown)\n */\n async cleanup(): Promise<void> {\n const allRootIds = Array.from(this.roots.keys());\n await Promise.all(allRootIds.map(id => this.unmountRoot(id, true)));\n }\n}\n\n// Singleton instance\nexport const reactRootManager = new ReactRootManager();"]}