@memberjunction/react-runtime 2.70.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 +4 -0
- package/CHANGELOG.md +3 -0
- package/README.md +224 -0
- package/dist/compiler/babel-config.d.ts +40 -0
- package/dist/compiler/babel-config.d.ts.map +1 -0
- package/dist/compiler/babel-config.js +52 -0
- package/dist/compiler/component-compiler.d.ts +22 -0
- package/dist/compiler/component-compiler.d.ts.map +1 -0
- package/dist/compiler/component-compiler.js +188 -0
- package/dist/compiler/index.d.ts +3 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/index.js +13 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +95 -0
- package/dist/registry/component-registry.d.ts +32 -0
- package/dist/registry/component-registry.d.ts.map +1 -0
- package/dist/registry/component-registry.js +197 -0
- package/dist/registry/component-resolver.d.ts +29 -0
- package/dist/registry/component-resolver.d.ts.map +1 -0
- package/dist/registry/component-resolver.js +112 -0
- package/dist/registry/index.d.ts +3 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +7 -0
- package/dist/runtime/component-hierarchy.d.ts +44 -0
- package/dist/runtime/component-hierarchy.d.ts.map +1 -0
- package/dist/runtime/component-hierarchy.js +162 -0
- package/dist/runtime/component-wrapper.d.ts +18 -0
- package/dist/runtime/component-wrapper.d.ts.map +1 -0
- package/dist/runtime/component-wrapper.js +108 -0
- package/dist/runtime/error-boundary.d.ts +6 -0
- package/dist/runtime/error-boundary.d.ts.map +1 -0
- package/dist/runtime/error-boundary.js +139 -0
- package/dist/runtime/index.d.ts +5 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +31 -0
- package/dist/runtime/prop-builder.d.ts +16 -0
- package/dist/runtime/prop-builder.d.ts.map +1 -0
- package/dist/runtime/prop-builder.js +161 -0
- package/dist/types/index.d.ts +98 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/package.json +36 -0
- package/src/compiler/babel-config.ts +97 -0
- package/src/compiler/component-compiler.ts +366 -0
- package/src/compiler/index.ts +15 -0
- package/src/index.ts +125 -0
- package/src/registry/component-registry.ts +379 -0
- package/src/registry/component-resolver.ts +275 -0
- package/src/registry/index.ts +7 -0
- package/src/runtime/component-hierarchy.ts +346 -0
- package/src/runtime/component-wrapper.ts +249 -0
- package/src/runtime/error-boundary.ts +242 -0
- package/src/runtime/index.ts +45 -0
- package/src/runtime/prop-builder.ts +290 -0
- package/src/types/index.ts +226 -0
- package/tsconfig.json +37 -0
- package/tsconfig.tsbuildinfo +1 -0
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# @memberjunction/react-runtime
|
|
2
|
+
|
|
3
|
+
Platform-agnostic React component runtime for MemberJunction. This package provides core compilation, registry, and execution capabilities for React components in any JavaScript environment.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The React Runtime package enables dynamic compilation and execution of React components from source code. It works in both browser and Node.js environments, making it suitable for client-side rendering and server-side testing.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Dynamic Compilation**: Transform JSX and React code at runtime using Babel
|
|
12
|
+
- **Component Registry**: Manage compiled components with namespace support
|
|
13
|
+
- **Dependency Resolution**: Handle component hierarchies and dependencies
|
|
14
|
+
- **Error Boundaries**: Comprehensive error handling for React components
|
|
15
|
+
- **Platform Agnostic**: Works in any JavaScript environment
|
|
16
|
+
- **Type Safe**: Full TypeScript support with strict typing
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @memberjunction/react-runtime
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Basic Usage
|
|
25
|
+
|
|
26
|
+
### Creating a Runtime Instance
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { createReactRuntime } from '@memberjunction/react-runtime';
|
|
30
|
+
import * as Babel from '@babel/standalone';
|
|
31
|
+
|
|
32
|
+
// Create runtime with Babel instance
|
|
33
|
+
const runtime = createReactRuntime(Babel);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Compiling a Component
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
const componentCode = `
|
|
40
|
+
function MyComponent({ data, userState, callbacks }) {
|
|
41
|
+
return (
|
|
42
|
+
<div>
|
|
43
|
+
<h1>Hello, {data.name}!</h1>
|
|
44
|
+
<button onClick={() => callbacks.RefreshData()}>
|
|
45
|
+
Refresh
|
|
46
|
+
</button>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
`;
|
|
51
|
+
|
|
52
|
+
// Compile the component
|
|
53
|
+
const result = await runtime.compiler.compile({
|
|
54
|
+
componentName: 'MyComponent',
|
|
55
|
+
componentCode: componentCode
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (result.success) {
|
|
59
|
+
// Register the compiled component
|
|
60
|
+
runtime.registry.register(
|
|
61
|
+
'MyComponent',
|
|
62
|
+
result.component.component,
|
|
63
|
+
'MyNamespace',
|
|
64
|
+
'v1'
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Using the Component
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// Get React context (provided by your environment)
|
|
73
|
+
const React = window.React; // or require('react')
|
|
74
|
+
const ReactDOM = window.ReactDOM; // or require('react-dom')
|
|
75
|
+
|
|
76
|
+
// Create runtime context
|
|
77
|
+
const context = { React, ReactDOM };
|
|
78
|
+
|
|
79
|
+
// Get the compiled component
|
|
80
|
+
const MyComponent = runtime.registry.get('MyComponent', 'MyNamespace');
|
|
81
|
+
|
|
82
|
+
// Execute the component factory
|
|
83
|
+
const { component } = MyComponent(context);
|
|
84
|
+
|
|
85
|
+
// Render with props
|
|
86
|
+
const props = {
|
|
87
|
+
data: { name: 'World' },
|
|
88
|
+
userState: {},
|
|
89
|
+
callbacks: {
|
|
90
|
+
RefreshData: () => console.log('Refresh clicked!')
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
React.createElement(component, props);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Advanced Features
|
|
98
|
+
|
|
99
|
+
### Component Hierarchies
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
const parentSpec = {
|
|
103
|
+
componentName: 'ParentComponent',
|
|
104
|
+
componentCode: '...',
|
|
105
|
+
childComponents: [
|
|
106
|
+
{
|
|
107
|
+
componentName: 'ChildComponent1',
|
|
108
|
+
componentCode: '...'
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
componentName: 'ChildComponent2',
|
|
112
|
+
componentCode: '...'
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// Resolve all components in hierarchy
|
|
118
|
+
const components = runtime.resolver.resolveComponents(parentSpec);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Error Boundaries
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { createErrorBoundary } from '@memberjunction/react-runtime';
|
|
125
|
+
|
|
126
|
+
const ErrorBoundary = createErrorBoundary(React, {
|
|
127
|
+
onError: (error, errorInfo) => {
|
|
128
|
+
console.error('Component error:', error);
|
|
129
|
+
},
|
|
130
|
+
fallback: <div>Something went wrong</div>,
|
|
131
|
+
recovery: 'retry'
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Wrap your component
|
|
135
|
+
<ErrorBoundary>
|
|
136
|
+
<YourComponent />
|
|
137
|
+
</ErrorBoundary>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Component Registry Management
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
// Check if component exists
|
|
144
|
+
if (runtime.registry.has('MyComponent')) {
|
|
145
|
+
// Get component with reference counting
|
|
146
|
+
const component = runtime.registry.get('MyComponent');
|
|
147
|
+
|
|
148
|
+
// Release when done
|
|
149
|
+
runtime.registry.release('MyComponent');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Get registry statistics
|
|
153
|
+
const stats = runtime.registry.getStats();
|
|
154
|
+
console.log(`Total components: ${stats.totalComponents}`);
|
|
155
|
+
|
|
156
|
+
// Clean up unused components
|
|
157
|
+
const removed = runtime.registry.cleanup();
|
|
158
|
+
console.log(`Removed ${removed} unused components`);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Configuration
|
|
162
|
+
|
|
163
|
+
### Compiler Configuration
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
const runtime = createReactRuntime(Babel, {
|
|
167
|
+
compiler: {
|
|
168
|
+
babel: {
|
|
169
|
+
presets: ['react'],
|
|
170
|
+
plugins: ['transform-optional-chaining']
|
|
171
|
+
},
|
|
172
|
+
minify: true,
|
|
173
|
+
sourceMaps: true,
|
|
174
|
+
cache: true,
|
|
175
|
+
maxCacheSize: 200
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Registry Configuration
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
const runtime = createReactRuntime(Babel, {
|
|
184
|
+
registry: {
|
|
185
|
+
maxComponents: 500,
|
|
186
|
+
cleanupInterval: 30000, // 30 seconds
|
|
187
|
+
useLRU: true,
|
|
188
|
+
enableNamespaces: true
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## API Reference
|
|
194
|
+
|
|
195
|
+
### Types
|
|
196
|
+
|
|
197
|
+
- `CompileOptions` - Options for compiling components
|
|
198
|
+
- `ComponentProps` - Standard props passed to components
|
|
199
|
+
- `ComponentCallbacks` - Callback functions available to components
|
|
200
|
+
- `RegistryEntry` - Registry entry with metadata
|
|
201
|
+
|
|
202
|
+
### Classes
|
|
203
|
+
|
|
204
|
+
- `ComponentCompiler` - Compiles React components from source
|
|
205
|
+
- `ComponentRegistry` - Manages compiled components
|
|
206
|
+
- `ComponentResolver` - Resolves component dependencies
|
|
207
|
+
|
|
208
|
+
### Utilities
|
|
209
|
+
|
|
210
|
+
- `createErrorBoundary()` - Creates error boundary components
|
|
211
|
+
- `buildComponentProps()` - Builds standardized component props
|
|
212
|
+
- `wrapComponent()` - Wraps components with additional functionality
|
|
213
|
+
|
|
214
|
+
## Best Practices
|
|
215
|
+
|
|
216
|
+
1. **Always Set Babel Instance**: Call `setBabelInstance()` before compiling
|
|
217
|
+
2. **Use Namespaces**: Organize components with namespaces
|
|
218
|
+
3. **Handle Errors**: Always check compilation results for errors
|
|
219
|
+
4. **Clean Up**: Use registry cleanup for long-running applications
|
|
220
|
+
5. **Type Safety**: Leverage TypeScript types for better development experience
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
See the main MemberJunction LICENSE file in the repository root.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export declare const DEFAULT_PRESETS: string[];
|
|
2
|
+
export declare const DEFAULT_PLUGINS: string[];
|
|
3
|
+
export declare const PRODUCTION_CONFIG: {
|
|
4
|
+
presets: string[];
|
|
5
|
+
plugins: string[];
|
|
6
|
+
minified: boolean;
|
|
7
|
+
comments: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare const DEVELOPMENT_CONFIG: {
|
|
10
|
+
presets: string[];
|
|
11
|
+
plugins: string[];
|
|
12
|
+
sourceMaps: string;
|
|
13
|
+
minified: boolean;
|
|
14
|
+
comments: boolean;
|
|
15
|
+
};
|
|
16
|
+
export declare function getBabelConfig(production?: boolean): {
|
|
17
|
+
presets: string[];
|
|
18
|
+
plugins: string[];
|
|
19
|
+
minified: boolean;
|
|
20
|
+
comments: boolean;
|
|
21
|
+
};
|
|
22
|
+
export declare function validateBabelPresets(babel: any): boolean;
|
|
23
|
+
export declare const JSX_PRAGMAS: {
|
|
24
|
+
classic: {
|
|
25
|
+
pragma: string;
|
|
26
|
+
pragmaFrag: string;
|
|
27
|
+
};
|
|
28
|
+
automatic: {
|
|
29
|
+
runtime: string;
|
|
30
|
+
importSource: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
export declare function getJSXConfig(reactVersion?: string): {
|
|
34
|
+
pragma: string;
|
|
35
|
+
pragmaFrag: string;
|
|
36
|
+
} | {
|
|
37
|
+
runtime: string;
|
|
38
|
+
importSource: string;
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=babel-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"babel-config.d.ts","sourceRoot":"","sources":["../../src/compiler/babel-config.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,eAAe,UAE3B,CAAC;AAKF,eAAO,MAAM,eAAe,EAAE,MAAM,EAGnC,CAAC;AAKF,eAAO,MAAM,iBAAiB;;;;;CAQ7B,CAAC;AAKF,eAAO,MAAM,kBAAkB;;;;;;CAS9B,CAAC;AAOF,wBAAgB,cAAc,CAAC,UAAU,GAAE,OAAe;;;;;EAEzD;AAOD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAOxD;AAKD,eAAO,MAAM,WAAW;;;;;;;;;CASvB,CAAC;AAOF,wBAAgB,YAAY,CAAC,YAAY,CAAC,EAAE,MAAM;;;;;;EAMjD"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getJSXConfig = exports.JSX_PRAGMAS = exports.validateBabelPresets = exports.getBabelConfig = exports.DEVELOPMENT_CONFIG = exports.PRODUCTION_CONFIG = exports.DEFAULT_PLUGINS = exports.DEFAULT_PRESETS = void 0;
|
|
4
|
+
exports.DEFAULT_PRESETS = [
|
|
5
|
+
'react',
|
|
6
|
+
];
|
|
7
|
+
exports.DEFAULT_PLUGINS = [];
|
|
8
|
+
exports.PRODUCTION_CONFIG = {
|
|
9
|
+
presets: exports.DEFAULT_PRESETS,
|
|
10
|
+
plugins: [
|
|
11
|
+
...exports.DEFAULT_PLUGINS,
|
|
12
|
+
],
|
|
13
|
+
minified: true,
|
|
14
|
+
comments: false
|
|
15
|
+
};
|
|
16
|
+
exports.DEVELOPMENT_CONFIG = {
|
|
17
|
+
presets: exports.DEFAULT_PRESETS,
|
|
18
|
+
plugins: [
|
|
19
|
+
...exports.DEFAULT_PLUGINS,
|
|
20
|
+
],
|
|
21
|
+
sourceMaps: 'inline',
|
|
22
|
+
minified: false,
|
|
23
|
+
comments: true
|
|
24
|
+
};
|
|
25
|
+
function getBabelConfig(production = false) {
|
|
26
|
+
return production ? exports.PRODUCTION_CONFIG : exports.DEVELOPMENT_CONFIG;
|
|
27
|
+
}
|
|
28
|
+
exports.getBabelConfig = getBabelConfig;
|
|
29
|
+
function validateBabelPresets(babel) {
|
|
30
|
+
if (!babel || !babel.availablePresets) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
return 'react' in babel.availablePresets;
|
|
34
|
+
}
|
|
35
|
+
exports.validateBabelPresets = validateBabelPresets;
|
|
36
|
+
exports.JSX_PRAGMAS = {
|
|
37
|
+
classic: {
|
|
38
|
+
pragma: 'React.createElement',
|
|
39
|
+
pragmaFrag: 'React.Fragment'
|
|
40
|
+
},
|
|
41
|
+
automatic: {
|
|
42
|
+
runtime: 'automatic',
|
|
43
|
+
importSource: 'react'
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
function getJSXConfig(reactVersion) {
|
|
47
|
+
if (reactVersion && parseInt(reactVersion.split('.')[0]) >= 17) {
|
|
48
|
+
return exports.JSX_PRAGMAS.automatic;
|
|
49
|
+
}
|
|
50
|
+
return exports.JSX_PRAGMAS.classic;
|
|
51
|
+
}
|
|
52
|
+
exports.getJSXConfig = getJSXConfig;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CompileOptions, CompilationResult, CompilerConfig } from '../types';
|
|
2
|
+
export declare class ComponentCompiler {
|
|
3
|
+
private config;
|
|
4
|
+
private compilationCache;
|
|
5
|
+
private babelInstance;
|
|
6
|
+
constructor(config?: Partial<CompilerConfig>);
|
|
7
|
+
setBabelInstance(babel: any): void;
|
|
8
|
+
compile(options: CompileOptions): Promise<CompilationResult>;
|
|
9
|
+
private transpileComponent;
|
|
10
|
+
private wrapComponentCode;
|
|
11
|
+
private createComponentFactory;
|
|
12
|
+
private createStateUpdaterUtility;
|
|
13
|
+
private validateCompileOptions;
|
|
14
|
+
private generateComponentId;
|
|
15
|
+
private getCachedComponent;
|
|
16
|
+
private cacheComponent;
|
|
17
|
+
private createCompilationError;
|
|
18
|
+
clearCache(): void;
|
|
19
|
+
getCacheSize(): number;
|
|
20
|
+
updateConfig(config: Partial<CompilerConfig>): void;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=component-compiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-compiler.d.ts","sourceRoot":"","sources":["../../src/compiler/component-compiler.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,cAAc,EAEd,iBAAiB,EACjB,cAAc,EAGf,MAAM,UAAU,CAAC;AAoBlB,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,aAAa,CAAM;gBAMf,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC;IAS5C,gBAAgB,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IAS5B,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAqElE,OAAO,CAAC,kBAAkB;IAgC1B,OAAO,CAAC,iBAAiB;IAgCzB,OAAO,CAAC,sBAAsB;IAmD9B,OAAO,CAAC,yBAAyB;IAwBjC,OAAO,CAAC,sBAAsB;IAwB9B,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,sBAAsB;IAa9B,UAAU,IAAI,IAAI;IAQlB,YAAY,IAAI,MAAM;IAQtB,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI;CAGpD"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ComponentCompiler = void 0;
|
|
4
|
+
const DEFAULT_COMPILER_CONFIG = {
|
|
5
|
+
babel: {
|
|
6
|
+
presets: ['react'],
|
|
7
|
+
plugins: []
|
|
8
|
+
},
|
|
9
|
+
minify: false,
|
|
10
|
+
sourceMaps: false,
|
|
11
|
+
cache: true,
|
|
12
|
+
maxCacheSize: 100
|
|
13
|
+
};
|
|
14
|
+
class ComponentCompiler {
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.config = { ...DEFAULT_COMPILER_CONFIG, ...config };
|
|
17
|
+
this.compilationCache = new Map();
|
|
18
|
+
}
|
|
19
|
+
setBabelInstance(babel) {
|
|
20
|
+
this.babelInstance = babel;
|
|
21
|
+
}
|
|
22
|
+
async compile(options) {
|
|
23
|
+
const startTime = Date.now();
|
|
24
|
+
try {
|
|
25
|
+
if (this.config.cache) {
|
|
26
|
+
const cached = this.getCachedComponent(options.componentName);
|
|
27
|
+
if (cached) {
|
|
28
|
+
return {
|
|
29
|
+
success: true,
|
|
30
|
+
component: cached,
|
|
31
|
+
duration: Date.now() - startTime
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
this.validateCompileOptions(options);
|
|
36
|
+
const transpiledCode = this.transpileComponent(options.componentCode, options.componentName, options);
|
|
37
|
+
const componentFactory = this.createComponentFactory(transpiledCode, options.componentName);
|
|
38
|
+
const compiledComponent = {
|
|
39
|
+
component: componentFactory,
|
|
40
|
+
id: this.generateComponentId(options.componentName),
|
|
41
|
+
name: options.componentName,
|
|
42
|
+
compiledAt: new Date(),
|
|
43
|
+
warnings: []
|
|
44
|
+
};
|
|
45
|
+
if (this.config.cache) {
|
|
46
|
+
this.cacheComponent(compiledComponent);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
success: true,
|
|
50
|
+
component: compiledComponent,
|
|
51
|
+
duration: Date.now() - startTime,
|
|
52
|
+
size: transpiledCode.length
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
return {
|
|
57
|
+
success: false,
|
|
58
|
+
error: this.createCompilationError(error, options.componentName),
|
|
59
|
+
duration: Date.now() - startTime
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
transpileComponent(code, componentName, options) {
|
|
64
|
+
if (!this.babelInstance) {
|
|
65
|
+
throw new Error('Babel instance not set. Call setBabelInstance() first.');
|
|
66
|
+
}
|
|
67
|
+
const wrappedCode = this.wrapComponentCode(code, componentName);
|
|
68
|
+
try {
|
|
69
|
+
const result = this.babelInstance.transform(wrappedCode, {
|
|
70
|
+
presets: options.babelPresets || this.config.babel.presets,
|
|
71
|
+
plugins: options.babelPlugins || this.config.babel.plugins,
|
|
72
|
+
filename: `${componentName}.jsx`,
|
|
73
|
+
sourceMaps: this.config.sourceMaps,
|
|
74
|
+
minified: this.config.minify
|
|
75
|
+
});
|
|
76
|
+
return result.code;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
throw new Error(`Transpilation failed: ${error.message}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
wrapComponentCode(componentCode, componentName) {
|
|
83
|
+
return `
|
|
84
|
+
function createComponent(React, ReactDOM, useState, useEffect, useCallback, createStateUpdater, libraries, styles, console) {
|
|
85
|
+
${componentCode}
|
|
86
|
+
|
|
87
|
+
// Ensure the component exists
|
|
88
|
+
if (typeof ${componentName} === 'undefined') {
|
|
89
|
+
throw new Error('Component "${componentName}" is not defined in the provided code');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Return the component with utilities
|
|
93
|
+
return {
|
|
94
|
+
component: ${componentName},
|
|
95
|
+
print: function() {
|
|
96
|
+
if (typeof window !== 'undefined' && window.print) {
|
|
97
|
+
window.print();
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
refresh: function(data) {
|
|
101
|
+
// Refresh functionality is handled by the host environment
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
`;
|
|
106
|
+
}
|
|
107
|
+
createComponentFactory(transpiledCode, componentName) {
|
|
108
|
+
try {
|
|
109
|
+
const factoryCreator = new Function('React', 'ReactDOM', 'useState', 'useEffect', 'useCallback', 'createStateUpdater', 'libraries', 'styles', 'console', `${transpiledCode}; return createComponent;`);
|
|
110
|
+
return (context, styles = {}) => {
|
|
111
|
+
const { React, ReactDOM, libraries = {} } = context;
|
|
112
|
+
const createStateUpdater = this.createStateUpdaterUtility();
|
|
113
|
+
const createComponentFn = factoryCreator(React, ReactDOM, React.useState, React.useEffect, React.useCallback, createStateUpdater, libraries, styles, console);
|
|
114
|
+
return createComponentFn(React, ReactDOM, React.useState, React.useEffect, React.useCallback, createStateUpdater, libraries, styles, console);
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
throw new Error(`Failed to create component factory: ${error.message}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
createStateUpdaterUtility() {
|
|
122
|
+
return (statePath, parentStateUpdater) => {
|
|
123
|
+
return (componentStateUpdate) => {
|
|
124
|
+
if (!statePath) {
|
|
125
|
+
parentStateUpdater(componentStateUpdate);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
const pathParts = statePath.split('.');
|
|
129
|
+
const componentKey = pathParts[pathParts.length - 1];
|
|
130
|
+
parentStateUpdater({
|
|
131
|
+
[componentKey]: componentStateUpdate
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
validateCompileOptions(options) {
|
|
138
|
+
if (!options.componentName) {
|
|
139
|
+
throw new Error('Component name is required');
|
|
140
|
+
}
|
|
141
|
+
if (!options.componentCode) {
|
|
142
|
+
throw new Error('Component code is required');
|
|
143
|
+
}
|
|
144
|
+
if (typeof options.componentCode !== 'string') {
|
|
145
|
+
throw new Error('Component code must be a string');
|
|
146
|
+
}
|
|
147
|
+
if (!options.componentCode.includes(options.componentName)) {
|
|
148
|
+
throw new Error(`Component code must define a component named "${options.componentName}"`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
generateComponentId(componentName) {
|
|
152
|
+
return `${componentName}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
153
|
+
}
|
|
154
|
+
getCachedComponent(componentName) {
|
|
155
|
+
for (const [key, component] of this.compilationCache) {
|
|
156
|
+
if (component.name === componentName) {
|
|
157
|
+
return component;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
cacheComponent(component) {
|
|
163
|
+
if (this.compilationCache.size >= this.config.maxCacheSize) {
|
|
164
|
+
const firstKey = this.compilationCache.keys().next().value;
|
|
165
|
+
this.compilationCache.delete(firstKey);
|
|
166
|
+
}
|
|
167
|
+
this.compilationCache.set(component.id, component);
|
|
168
|
+
}
|
|
169
|
+
createCompilationError(error, componentName) {
|
|
170
|
+
return {
|
|
171
|
+
message: error.message || 'Unknown compilation error',
|
|
172
|
+
stack: error.stack,
|
|
173
|
+
componentName,
|
|
174
|
+
phase: 'compilation',
|
|
175
|
+
details: error
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
clearCache() {
|
|
179
|
+
this.compilationCache.clear();
|
|
180
|
+
}
|
|
181
|
+
getCacheSize() {
|
|
182
|
+
return this.compilationCache.size;
|
|
183
|
+
}
|
|
184
|
+
updateConfig(config) {
|
|
185
|
+
this.config = { ...this.config, ...config };
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
exports.ComponentCompiler = ComponentCompiler;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compiler/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EACL,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,YAAY,EACb,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getJSXConfig = exports.validateBabelPresets = exports.getBabelConfig = exports.DEVELOPMENT_CONFIG = exports.PRODUCTION_CONFIG = exports.DEFAULT_PLUGINS = exports.DEFAULT_PRESETS = exports.ComponentCompiler = void 0;
|
|
4
|
+
var component_compiler_1 = require("./component-compiler");
|
|
5
|
+
Object.defineProperty(exports, "ComponentCompiler", { enumerable: true, get: function () { return component_compiler_1.ComponentCompiler; } });
|
|
6
|
+
var babel_config_1 = require("./babel-config");
|
|
7
|
+
Object.defineProperty(exports, "DEFAULT_PRESETS", { enumerable: true, get: function () { return babel_config_1.DEFAULT_PRESETS; } });
|
|
8
|
+
Object.defineProperty(exports, "DEFAULT_PLUGINS", { enumerable: true, get: function () { return babel_config_1.DEFAULT_PLUGINS; } });
|
|
9
|
+
Object.defineProperty(exports, "PRODUCTION_CONFIG", { enumerable: true, get: function () { return babel_config_1.PRODUCTION_CONFIG; } });
|
|
10
|
+
Object.defineProperty(exports, "DEVELOPMENT_CONFIG", { enumerable: true, get: function () { return babel_config_1.DEVELOPMENT_CONFIG; } });
|
|
11
|
+
Object.defineProperty(exports, "getBabelConfig", { enumerable: true, get: function () { return babel_config_1.getBabelConfig; } });
|
|
12
|
+
Object.defineProperty(exports, "validateBabelPresets", { enumerable: true, get: function () { return babel_config_1.validateBabelPresets; } });
|
|
13
|
+
Object.defineProperty(exports, "getJSXConfig", { enumerable: true, get: function () { return babel_config_1.getJSXConfig; } });
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ComponentCompiler } from './compiler';
|
|
2
|
+
import { ComponentRegistry } from './registry';
|
|
3
|
+
import { ComponentResolver } from './registry';
|
|
4
|
+
export * from './types';
|
|
5
|
+
export { ComponentCompiler } from './compiler';
|
|
6
|
+
export { DEFAULT_PRESETS, DEFAULT_PLUGINS, PRODUCTION_CONFIG, DEVELOPMENT_CONFIG, getBabelConfig, validateBabelPresets, getJSXConfig } from './compiler';
|
|
7
|
+
export { ComponentRegistry } from './registry';
|
|
8
|
+
export { ComponentResolver, ComponentSpec, ResolvedComponents } from './registry';
|
|
9
|
+
export { createErrorBoundary, withErrorBoundary, formatComponentError, createErrorLogger } from './runtime';
|
|
10
|
+
export { wrapComponent, memoizeComponent, lazyComponent, injectProps, conditionalComponent, withErrorHandler, portalComponent, WrapperOptions } from './runtime';
|
|
11
|
+
export { buildComponentProps, normalizeCallbacks, normalizeStyles, validateComponentProps, mergeProps, createPropsTransformer, wrapCallbacksWithLogging, extractPropPaths, PropBuilderOptions } from './runtime';
|
|
12
|
+
export { ComponentHierarchyRegistrar, registerComponentHierarchy, validateComponentSpec, flattenComponentHierarchy, countComponentsInHierarchy, HierarchyRegistrationResult, ComponentRegistrationError, HierarchyRegistrationOptions } from './runtime';
|
|
13
|
+
export declare const VERSION = "2.69.1";
|
|
14
|
+
export declare const DEFAULT_CONFIGS: {
|
|
15
|
+
compiler: {
|
|
16
|
+
babel: {
|
|
17
|
+
presets: string[];
|
|
18
|
+
plugins: never[];
|
|
19
|
+
};
|
|
20
|
+
minify: boolean;
|
|
21
|
+
sourceMaps: boolean;
|
|
22
|
+
cache: boolean;
|
|
23
|
+
maxCacheSize: number;
|
|
24
|
+
};
|
|
25
|
+
registry: {
|
|
26
|
+
maxComponents: number;
|
|
27
|
+
cleanupInterval: number;
|
|
28
|
+
useLRU: boolean;
|
|
29
|
+
enableNamespaces: boolean;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export declare function createReactRuntime(babelInstance: any, config?: {
|
|
33
|
+
compiler?: Partial<import('./types').CompilerConfig>;
|
|
34
|
+
registry?: Partial<import('./types').RegistryConfig>;
|
|
35
|
+
}): {
|
|
36
|
+
compiler: ComponentCompiler;
|
|
37
|
+
registry: ComponentRegistry;
|
|
38
|
+
resolver: ComponentResolver;
|
|
39
|
+
version: string;
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAG/C,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EACL,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,YAAY,EACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,UAAU,EACV,sBAAsB,EACtB,wBAAwB,EACxB,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,qBAAqB,EACrB,yBAAyB,EACzB,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,WAAW,CAAC;AAGnB,eAAO,MAAM,OAAO,WAAW,CAAC;AAGhC,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;CAiB3B,CAAC;AAQF,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,GAAG,EAClB,MAAM,CAAC,EAAE;IACP,QAAQ,CAAC,EAAE,OAAO,CAAC,OAAO,SAAS,EAAE,cAAc,CAAC,CAAC;IACrD,QAAQ,CAAC,EAAE,OAAO,CAAC,OAAO,SAAS,EAAE,cAAc,CAAC,CAAC;CACtD;;;;;EAcF"}
|