@memberjunction/react-runtime 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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +17 -0
- package/dist/compiler/component-compiler.d.ts +2 -0
- package/dist/compiler/component-compiler.d.ts.map +1 -1
- package/dist/compiler/component-compiler.js +19 -12
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -25
- package/dist/runtime/index.d.ts +0 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +1 -9
- package/dist/runtime/react-root-manager.d.ts.map +1 -1
- package/dist/runtime/react-root-manager.js +1 -2
- package/dist/utilities/resource-manager.d.ts +6 -4
- package/dist/utilities/resource-manager.d.ts.map +1 -1
- package/dist/utilities/resource-manager.js +82 -31
- package/package.json +4 -4
- package/src/compiler/component-compiler.ts +32 -13
- package/src/index.ts +0 -10
- package/src/runtime/index.ts +0 -10
- package/src/runtime/react-root-manager.ts +2 -3
- package/src/utilities/resource-manager.ts +106 -40
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/runtime/component-wrapper.d.ts +0 -18
- package/dist/runtime/component-wrapper.d.ts.map +0 -1
- package/dist/runtime/component-wrapper.js +0 -108
- package/src/runtime/component-wrapper.ts +0 -249
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview React component wrapper utilities.
|
|
3
|
-
* Provides HOCs and utilities for wrapping components with additional functionality.
|
|
4
|
-
* @module @memberjunction/react-runtime/runtime
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { ComponentProps, ComponentLifecycle } from '../types';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Options for wrapping a component
|
|
11
|
-
*/
|
|
12
|
-
export interface WrapperOptions {
|
|
13
|
-
/** Component display name */
|
|
14
|
-
displayName?: string;
|
|
15
|
-
/** Enable performance monitoring */
|
|
16
|
-
enableProfiling?: boolean;
|
|
17
|
-
/** Enable props logging */
|
|
18
|
-
logProps?: boolean;
|
|
19
|
-
/** Lifecycle hooks */
|
|
20
|
-
lifecycle?: ComponentLifecycle;
|
|
21
|
-
/** Default props */
|
|
22
|
-
defaultProps?: Partial<ComponentProps>;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Wraps a React component with additional functionality
|
|
27
|
-
* @param React - React library instance
|
|
28
|
-
* @param Component - Component to wrap
|
|
29
|
-
* @param options - Wrapper options
|
|
30
|
-
* @returns Wrapped component
|
|
31
|
-
*/
|
|
32
|
-
export function wrapComponent(React: any, Component: any, options: WrapperOptions = {}): any {
|
|
33
|
-
const {
|
|
34
|
-
displayName,
|
|
35
|
-
enableProfiling = false,
|
|
36
|
-
logProps = false,
|
|
37
|
-
lifecycle = {},
|
|
38
|
-
defaultProps = {}
|
|
39
|
-
} = options;
|
|
40
|
-
|
|
41
|
-
// Create wrapper component
|
|
42
|
-
const WrappedComponent = React.forwardRef((props: any, ref: any) => {
|
|
43
|
-
const mergedProps = { ...defaultProps, ...props };
|
|
44
|
-
|
|
45
|
-
// Log props if enabled
|
|
46
|
-
React.useEffect(() => {
|
|
47
|
-
if (logProps) {
|
|
48
|
-
console.log(`[${displayName || Component.name}] Props:`, mergedProps);
|
|
49
|
-
}
|
|
50
|
-
}, [mergedProps]);
|
|
51
|
-
|
|
52
|
-
// Lifecycle: beforeMount
|
|
53
|
-
React.useEffect(() => {
|
|
54
|
-
if (lifecycle.beforeMount) {
|
|
55
|
-
lifecycle.beforeMount();
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Lifecycle: afterMount
|
|
59
|
-
if (lifecycle.afterMount) {
|
|
60
|
-
lifecycle.afterMount();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Lifecycle: beforeUnmount
|
|
64
|
-
return () => {
|
|
65
|
-
if (lifecycle.beforeUnmount) {
|
|
66
|
-
lifecycle.beforeUnmount();
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
}, []);
|
|
70
|
-
|
|
71
|
-
// Lifecycle: beforeUpdate/afterUpdate
|
|
72
|
-
const prevPropsRef = React.useRef(mergedProps);
|
|
73
|
-
React.useEffect(() => {
|
|
74
|
-
const prevProps = prevPropsRef.current;
|
|
75
|
-
|
|
76
|
-
if (lifecycle.beforeUpdate) {
|
|
77
|
-
lifecycle.beforeUpdate(prevProps, mergedProps);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Schedule afterUpdate
|
|
81
|
-
if (lifecycle.afterUpdate) {
|
|
82
|
-
Promise.resolve().then(() => {
|
|
83
|
-
lifecycle.afterUpdate!(prevProps, mergedProps);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
prevPropsRef.current = mergedProps;
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// Render with profiling if enabled
|
|
91
|
-
if (enableProfiling && React.Profiler) {
|
|
92
|
-
return React.createElement(
|
|
93
|
-
React.Profiler,
|
|
94
|
-
{
|
|
95
|
-
id: displayName || Component.name || 'WrappedComponent',
|
|
96
|
-
onRender: (id: string, phase: string, actualDuration: number) => {
|
|
97
|
-
console.log(`[Profiler] ${id} (${phase}): ${actualDuration.toFixed(2)}ms`);
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
React.createElement(Component, { ...mergedProps, ref })
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return React.createElement(Component, { ...mergedProps, ref });
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// Set display name
|
|
108
|
-
WrappedComponent.displayName = displayName || `Wrapped(${Component.displayName || Component.name || 'Component'})`;
|
|
109
|
-
|
|
110
|
-
return WrappedComponent;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Creates a memoized version of a component
|
|
115
|
-
* @param React - React library instance
|
|
116
|
-
* @param Component - Component to memoize
|
|
117
|
-
* @param propsAreEqual - Optional comparison function
|
|
118
|
-
* @returns Memoized component
|
|
119
|
-
*/
|
|
120
|
-
export function memoizeComponent(
|
|
121
|
-
React: any,
|
|
122
|
-
Component: any,
|
|
123
|
-
propsAreEqual?: (prevProps: any, nextProps: any) => boolean
|
|
124
|
-
): any {
|
|
125
|
-
return React.memo(Component, propsAreEqual);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Creates a lazy-loaded component
|
|
130
|
-
* @param React - React library instance
|
|
131
|
-
* @param loader - Function that returns a promise resolving to the component
|
|
132
|
-
* @param fallback - Optional loading fallback
|
|
133
|
-
* @returns Lazy component
|
|
134
|
-
*/
|
|
135
|
-
export function lazyComponent(
|
|
136
|
-
React: any,
|
|
137
|
-
loader: () => Promise<{ default: any }>,
|
|
138
|
-
fallback?: any
|
|
139
|
-
): any {
|
|
140
|
-
const LazyComponent = React.lazy(loader);
|
|
141
|
-
|
|
142
|
-
if (fallback) {
|
|
143
|
-
return (props: any) => React.createElement(
|
|
144
|
-
React.Suspense,
|
|
145
|
-
{ fallback },
|
|
146
|
-
React.createElement(LazyComponent, props)
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return LazyComponent;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Injects additional props into a component
|
|
155
|
-
* @param React - React library instance
|
|
156
|
-
* @param Component - Component to inject props into
|
|
157
|
-
* @param injectedProps - Props to inject
|
|
158
|
-
* @returns Component with injected props
|
|
159
|
-
*/
|
|
160
|
-
export function injectProps(React: any, Component: any, injectedProps: any): any {
|
|
161
|
-
return React.forwardRef((props: any, ref: any) => {
|
|
162
|
-
const mergedProps = { ...injectedProps, ...props };
|
|
163
|
-
return React.createElement(Component, { ...mergedProps, ref });
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Creates a component that renders conditionally
|
|
169
|
-
* @param React - React library instance
|
|
170
|
-
* @param Component - Component to render conditionally
|
|
171
|
-
* @param condition - Condition function or boolean
|
|
172
|
-
* @param fallback - Optional fallback component
|
|
173
|
-
* @returns Conditional component
|
|
174
|
-
*/
|
|
175
|
-
export function conditionalComponent(
|
|
176
|
-
React: any,
|
|
177
|
-
Component: any,
|
|
178
|
-
condition: boolean | ((props: any) => boolean),
|
|
179
|
-
fallback?: any
|
|
180
|
-
): any {
|
|
181
|
-
return (props: any) => {
|
|
182
|
-
const shouldRender = typeof condition === 'function' ? condition(props) : condition;
|
|
183
|
-
|
|
184
|
-
if (shouldRender) {
|
|
185
|
-
return React.createElement(Component, props);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return fallback || null;
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Creates a component with default error handling
|
|
194
|
-
* @param React - React library instance
|
|
195
|
-
* @param Component - Component to wrap
|
|
196
|
-
* @param errorHandler - Error handling function
|
|
197
|
-
* @returns Component with error handling
|
|
198
|
-
*/
|
|
199
|
-
export function withErrorHandler(
|
|
200
|
-
React: any,
|
|
201
|
-
Component: any,
|
|
202
|
-
errorHandler: (error: Error) => void
|
|
203
|
-
): any {
|
|
204
|
-
return class extends React.Component {
|
|
205
|
-
componentDidCatch(error: Error, errorInfo: any) {
|
|
206
|
-
errorHandler(error);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
render() {
|
|
210
|
-
return React.createElement(Component, this.props);
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Creates a portal wrapper component
|
|
217
|
-
* @param React - React library instance
|
|
218
|
-
* @param ReactDOM - ReactDOM library instance
|
|
219
|
-
* @param Component - Component to render in portal
|
|
220
|
-
* @param container - DOM container element or selector
|
|
221
|
-
* @returns Portal component
|
|
222
|
-
*/
|
|
223
|
-
export function portalComponent(
|
|
224
|
-
React: any,
|
|
225
|
-
ReactDOM: any,
|
|
226
|
-
Component: any,
|
|
227
|
-
container: Element | string
|
|
228
|
-
): any {
|
|
229
|
-
return (props: any) => {
|
|
230
|
-
const [mountNode, setMountNode] = React.useState(null as Element | null);
|
|
231
|
-
|
|
232
|
-
React.useEffect(() => {
|
|
233
|
-
const node = typeof container === 'string'
|
|
234
|
-
? document.querySelector(container)
|
|
235
|
-
: container;
|
|
236
|
-
|
|
237
|
-
setMountNode(node);
|
|
238
|
-
}, []);
|
|
239
|
-
|
|
240
|
-
if (!mountNode || !ReactDOM.createPortal) {
|
|
241
|
-
return null;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
return ReactDOM.createPortal(
|
|
245
|
-
React.createElement(Component, props),
|
|
246
|
-
mountNode
|
|
247
|
-
);
|
|
248
|
-
};
|
|
249
|
-
}
|