@memberjunction/react-runtime 2.74.0 → 2.76.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 (54) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +27 -0
  3. package/README.md +96 -4
  4. package/dist/compiler/component-compiler.d.ts +0 -1
  5. package/dist/compiler/component-compiler.d.ts.map +1 -1
  6. package/dist/compiler/component-compiler.js +34 -25
  7. package/dist/index.d.ts +2 -2
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +3 -6
  10. package/dist/registry/component-resolver.d.ts +1 -6
  11. package/dist/registry/component-resolver.d.ts.map +1 -1
  12. package/dist/registry/component-resolver.js +19 -19
  13. package/dist/registry/index.d.ts +2 -1
  14. package/dist/registry/index.d.ts.map +1 -1
  15. package/dist/registry/index.js +3 -1
  16. package/dist/runtime/component-hierarchy.d.ts +1 -1
  17. package/dist/runtime/component-hierarchy.d.ts.map +1 -1
  18. package/dist/runtime/component-hierarchy.js +25 -25
  19. package/dist/runtime/index.d.ts +1 -1
  20. package/dist/runtime/index.d.ts.map +1 -1
  21. package/dist/runtime/index.js +1 -2
  22. package/dist/runtime/prop-builder.d.ts +1 -2
  23. package/dist/runtime/prop-builder.d.ts.map +1 -1
  24. package/dist/runtime/prop-builder.js +4 -76
  25. package/dist/types/index.d.ts +2 -0
  26. package/dist/types/index.d.ts.map +1 -1
  27. package/dist/types/index.js +15 -0
  28. package/dist/types/library-config.d.ts +32 -0
  29. package/dist/types/library-config.d.ts.map +1 -0
  30. package/dist/types/library-config.js +2 -0
  31. package/dist/utilities/core-libraries.d.ts +5 -0
  32. package/dist/utilities/core-libraries.d.ts.map +1 -0
  33. package/dist/utilities/core-libraries.js +52 -0
  34. package/dist/utilities/library-loader.d.ts +3 -2
  35. package/dist/utilities/library-loader.d.ts.map +1 -1
  36. package/dist/utilities/library-loader.js +65 -76
  37. package/dist/utilities/standard-libraries.d.ts +13 -24
  38. package/dist/utilities/standard-libraries.d.ts.map +1 -1
  39. package/dist/utilities/standard-libraries.js +58 -47
  40. package/package.json +4 -4
  41. package/samples/entities-1.js +493 -0
  42. package/src/compiler/component-compiler.ts +64 -35
  43. package/src/index.ts +1 -5
  44. package/src/registry/component-resolver.ts +21 -30
  45. package/src/registry/index.ts +2 -1
  46. package/src/runtime/component-hierarchy.ts +26 -26
  47. package/src/runtime/index.ts +0 -1
  48. package/src/runtime/prop-builder.ts +5 -112
  49. package/src/types/index.ts +6 -1
  50. package/src/types/library-config.ts +75 -0
  51. package/src/utilities/core-libraries.ts +61 -0
  52. package/src/utilities/library-loader.ts +113 -93
  53. package/src/utilities/standard-libraries.ts +104 -71
  54. package/tsconfig.tsbuildinfo +1 -1
@@ -5,16 +5,7 @@
5
5
  */
6
6
 
7
7
  import { ComponentRegistry } from './component-registry';
8
-
9
- /**
10
- * Component specification interface matching Skip component structure
11
- */
12
- export interface ComponentSpec {
13
- componentName: string;
14
- componentCode?: string;
15
- childComponents?: ComponentSpec[];
16
- components?: ComponentSpec[]; // Alternative property name for children
17
- }
8
+ import { ComponentSpec } from '@memberjunction/interactive-component-types';
18
9
 
19
10
  /**
20
11
  * Resolved component map for passing to React components
@@ -67,20 +58,20 @@ export class ComponentResolver {
67
58
  visited: Set<string> = new Set()
68
59
  ): void {
69
60
  // Prevent circular dependencies
70
- if (visited.has(spec.componentName)) {
71
- console.warn(`Circular dependency detected for component: ${spec.componentName}`);
61
+ if (visited.has(spec.name)) {
62
+ console.warn(`Circular dependency detected for component: ${spec.name}`);
72
63
  return;
73
64
  }
74
- visited.add(spec.componentName);
65
+ visited.add(spec.name);
75
66
 
76
67
  // Try to get component from registry
77
- const component = this.registry.get(spec.componentName, namespace);
68
+ const component = this.registry.get(spec.name, namespace);
78
69
  if (component) {
79
- resolved[spec.componentName] = component;
70
+ resolved[spec.name] = component;
80
71
  }
81
72
 
82
- // Process child components (handle both property names)
83
- const children = spec.childComponents || spec.components || [];
73
+ // Process child components
74
+ const children = spec.dependencies || [];
84
75
  for (const child of children) {
85
76
  this.resolveComponentHierarchy(child, resolved, namespace, visited);
86
77
  }
@@ -114,16 +105,16 @@ export class ComponentResolver {
114
105
  missing: string[],
115
106
  checked: Set<string>
116
107
  ): void {
117
- if (checked.has(spec.componentName)) return;
118
- checked.add(spec.componentName);
108
+ if (checked.has(spec.name)) return;
109
+ checked.add(spec.name);
119
110
 
120
111
  // Check if component exists in registry
121
- if (!this.registry.has(spec.componentName, namespace)) {
122
- missing.push(spec.componentName);
112
+ if (!this.registry.has(spec.name, namespace)) {
113
+ missing.push(spec.name);
123
114
  }
124
115
 
125
116
  // Check children
126
- const children = spec.childComponents || spec.components || [];
117
+ const children = spec.dependencies || [];
127
118
  for (const child of children) {
128
119
  this.checkDependencies(child, namespace, missing, checked);
129
120
  }
@@ -154,13 +145,13 @@ export class ComponentResolver {
154
145
  graph: Map<string, string[]>,
155
146
  visited: Set<string>
156
147
  ): void {
157
- if (visited.has(spec.componentName)) return;
158
- visited.add(spec.componentName);
148
+ if (visited.has(spec.name)) return;
149
+ visited.add(spec.name);
159
150
 
160
- const children = spec.childComponents || spec.components || [];
161
- const dependencies = children.map(child => child.componentName);
151
+ const children = spec.dependencies || [];
152
+ const dependencies = children.map(child => child.name);
162
153
 
163
- graph.set(spec.componentName, dependencies);
154
+ graph.set(spec.name, dependencies);
164
155
 
165
156
  // Recursively process children
166
157
  for (const child of children) {
@@ -262,12 +253,12 @@ export class ComponentResolver {
262
253
  collected: ComponentSpec[],
263
254
  visited: Set<string>
264
255
  ): void {
265
- if (visited.has(spec.componentName)) return;
266
- visited.add(spec.componentName);
256
+ if (visited.has(spec.name)) return;
257
+ visited.add(spec.name);
267
258
 
268
259
  collected.push(spec);
269
260
 
270
- const children = spec.childComponents || spec.components || [];
261
+ const children = spec.dependencies || [];
271
262
  for (const child of children) {
272
263
  this.collectComponentSpecs(child, collected, visited);
273
264
  }
@@ -4,4 +4,5 @@
4
4
  */
5
5
 
6
6
  export { ComponentRegistry } from './component-registry';
7
- export { ComponentResolver, ComponentSpec, ResolvedComponents } from './component-resolver';
7
+ export { ComponentResolver, ResolvedComponents } from './component-resolver';
8
+ export { ComponentSpec } from '@memberjunction/interactive-component-types';
@@ -13,7 +13,7 @@ import {
13
13
  import { ComponentCompiler } from '../compiler';
14
14
  import { ComponentRegistry } from '../registry';
15
15
 
16
- import { ComponentSpec } from '../registry/component-resolver';
16
+ import { ComponentSpec } from '@memberjunction/interactive-component-types';
17
17
 
18
18
  /**
19
19
  * Result of a hierarchy registration operation
@@ -89,7 +89,7 @@ export class ComponentHierarchyRegistrar {
89
89
  );
90
90
 
91
91
  if (rootResult.success) {
92
- registeredComponents.push(rootSpec.componentName);
92
+ registeredComponents.push(rootSpec.name);
93
93
  } else {
94
94
  errors.push(rootResult.error!);
95
95
  if (!continueOnError) {
@@ -98,7 +98,7 @@ export class ComponentHierarchyRegistrar {
98
98
  }
99
99
 
100
100
  // Register child components recursively
101
- const childComponents = rootSpec.childComponents || rootSpec.components || [];
101
+ const childComponents = rootSpec.dependencies || [];
102
102
  if (childComponents.length > 0) {
103
103
  const childResult = await this.registerChildComponents(
104
104
  childComponents,
@@ -136,7 +136,7 @@ export class ComponentHierarchyRegistrar {
136
136
 
137
137
  try {
138
138
  // Skip if no component code
139
- if (!spec.componentCode) {
139
+ if (!spec.code) {
140
140
  return {
141
141
  success: true,
142
142
  error: undefined
@@ -144,12 +144,12 @@ export class ComponentHierarchyRegistrar {
144
144
  }
145
145
 
146
146
  // Check if component already exists
147
- const existingComponent = this.registry.get(spec.componentName, namespace, version);
147
+ const existingComponent = this.registry.get(spec.name, namespace, version);
148
148
  if (existingComponent && !allowOverride) {
149
149
  return {
150
150
  success: false,
151
151
  error: {
152
- componentName: spec.componentName,
152
+ componentName: spec.name,
153
153
  error: `Component already registered in ${namespace}/${version}`,
154
154
  phase: 'registration'
155
155
  }
@@ -158,8 +158,8 @@ export class ComponentHierarchyRegistrar {
158
158
 
159
159
  // Compile the component
160
160
  const compileOptions: CompileOptions = {
161
- componentName: spec.componentName,
162
- componentCode: spec.componentCode,
161
+ componentName: spec.name,
162
+ componentCode: spec.code,
163
163
  styles
164
164
  };
165
165
 
@@ -169,7 +169,7 @@ export class ComponentHierarchyRegistrar {
169
169
  return {
170
170
  success: false,
171
171
  error: {
172
- componentName: spec.componentName,
172
+ componentName: spec.name,
173
173
  error: compilationResult.error?.message || 'Unknown compilation error',
174
174
  phase: 'compilation'
175
175
  }
@@ -181,7 +181,7 @@ export class ComponentHierarchyRegistrar {
181
181
 
182
182
  // Register the component
183
183
  this.registry.register(
184
- spec.componentName,
184
+ spec.name,
185
185
  componentFactory.component,
186
186
  namespace,
187
187
  version
@@ -193,7 +193,7 @@ export class ComponentHierarchyRegistrar {
193
193
  return {
194
194
  success: false,
195
195
  error: {
196
- componentName: spec.componentName,
196
+ componentName: spec.name,
197
197
  error: error instanceof Error ? error.message : String(error),
198
198
  phase: 'registration'
199
199
  }
@@ -226,8 +226,8 @@ export class ComponentHierarchyRegistrar {
226
226
  });
227
227
 
228
228
  if (childResult.success) {
229
- if (child.componentCode) {
230
- registeredComponents.push(child.componentName);
229
+ if (child.code) {
230
+ registeredComponents.push(child.name);
231
231
  }
232
232
  } else {
233
233
  errors.push(childResult.error!);
@@ -237,7 +237,7 @@ export class ComponentHierarchyRegistrar {
237
237
  }
238
238
 
239
239
  // Register nested children recursively
240
- const nestedChildren = child.childComponents || child.components || [];
240
+ const nestedChildren = child.dependencies || [];
241
241
  if (nestedChildren.length > 0) {
242
242
  await this.registerChildComponents(
243
243
  nestedChildren,
@@ -279,26 +279,26 @@ export async function registerComponentHierarchy(
279
279
  export function validateComponentSpec(spec: ComponentSpec): string[] {
280
280
  const errors: string[] = [];
281
281
 
282
- if (!spec.componentName) {
283
- errors.push('Component specification must have a componentName');
282
+ if (!spec.name) {
283
+ errors.push('Component specification must have a name');
284
284
  }
285
285
 
286
286
  // If componentCode is provided, do basic validation
287
- if (spec.componentCode) {
288
- if (typeof spec.componentCode !== 'string') {
289
- errors.push(`Component code for ${spec.componentName} must be a string`);
287
+ if (spec.code) {
288
+ if (typeof spec.code !== 'string') {
289
+ errors.push(`Component code for ${spec.name} must be a string`);
290
290
  }
291
- if (spec.componentCode.trim().length === 0) {
292
- errors.push(`Component code for ${spec.componentName} cannot be empty`);
291
+ if (spec.code.trim().length === 0) {
292
+ errors.push(`Component code for ${spec.name} cannot be empty`);
293
293
  }
294
294
  }
295
295
 
296
296
  // Validate child components recursively
297
- const children = spec.childComponents || spec.components || [];
297
+ const children = spec.dependencies || [];
298
298
  children.forEach((child, index) => {
299
299
  const childErrors = validateComponentSpec(child);
300
300
  childErrors.forEach(error => {
301
- errors.push(`Child ${index} (${child.componentName || 'unnamed'}): ${error}`);
301
+ errors.push(`Child ${index} (${child.name || 'unnamed'}): ${error}`);
302
302
  });
303
303
  });
304
304
 
@@ -313,7 +313,7 @@ export function validateComponentSpec(spec: ComponentSpec): string[] {
313
313
  export function flattenComponentHierarchy(rootSpec: ComponentSpec): ComponentSpec[] {
314
314
  const components: ComponentSpec[] = [rootSpec];
315
315
 
316
- const children = rootSpec.childComponents || rootSpec.components || [];
316
+ const children = rootSpec.dependencies || [];
317
317
  children.forEach(child => {
318
318
  components.push(...flattenComponentHierarchy(child));
319
319
  });
@@ -333,11 +333,11 @@ export function countComponentsInHierarchy(
333
333
  ): number {
334
334
  let count = 0;
335
335
 
336
- if (includeEmpty || rootSpec.componentCode) {
336
+ if (includeEmpty || rootSpec.code) {
337
337
  count = 1;
338
338
  }
339
339
 
340
- const children = rootSpec.childComponents || rootSpec.components || [];
340
+ const children = rootSpec.dependencies || [];
341
341
  children.forEach(child => {
342
342
  count += countComponentsInHierarchy(child, includeEmpty);
343
343
  });
@@ -23,7 +23,6 @@ export {
23
23
 
24
24
  export {
25
25
  buildComponentProps,
26
- cleanupPropBuilder,
27
26
  normalizeCallbacks,
28
27
  normalizeStyles,
29
28
  validateComponentProps,
@@ -41,7 +41,8 @@ export function buildComponentProps(
41
41
  callbacks: ComponentCallbacks = {},
42
42
  components: Record<string, any> = {},
43
43
  styles?: ComponentStyles,
44
- options: PropBuilderOptions = {}
44
+ options: PropBuilderOptions = {},
45
+ onStateChanged?: (stateUpdate: Record<string, any>) => void
45
46
  ): ComponentProps {
46
47
  const {
47
48
  validate = true,
@@ -61,7 +62,8 @@ export function buildComponentProps(
61
62
  utilities,
62
63
  callbacks: normalizeCallbacks(callbacks, debounceUpdateUserState),
63
64
  components,
64
- styles: normalizeStyles(styles)
65
+ styles: normalizeStyles(styles),
66
+ onStateChanged
65
67
  };
66
68
 
67
69
  // Validate if enabled
@@ -124,74 +126,6 @@ export function normalizeCallbacks(callbacks: any, debounceMs: number = 3000): C
124
126
  normalized.OpenEntityRecord = callbacks.OpenEntityRecord;
125
127
  }
126
128
 
127
- if (callbacks.UpdateUserState && typeof callbacks.UpdateUserState === 'function') {
128
- // Create a debounced version of UpdateUserState with loop detection
129
- const originalCallback = callbacks.UpdateUserState;
130
-
131
- // Get or create a subject for this callback
132
- let subject = updateUserStateSubjects.get(originalCallback);
133
- if (!subject) {
134
- subject = new Subject<any>();
135
- updateUserStateSubjects.set(originalCallback, subject);
136
-
137
- // Subscribe to the subject with debounce
138
- const subscription = subject.pipe(
139
- debounceTime(debounceMs)
140
- ).subscribe(state => {
141
- console.log(`[Skip Component] UpdateUserState called after ${debounceMs}ms debounce`);
142
- originalCallback(state);
143
- });
144
-
145
- // Store the subscription for cleanup
146
- updateUserStateSubscriptions.set(originalCallback, subscription);
147
- }
148
-
149
- // Get or create loop detection state
150
- let loopState = loopDetectionStates.get(originalCallback);
151
- if (!loopState) {
152
- loopState = { count: 0, lastUpdate: 0, lastState: null };
153
- loopDetectionStates.set(originalCallback, loopState);
154
- }
155
-
156
- // Return a function that prevents redundant updates
157
- normalized.UpdateUserState = (state: any) => {
158
- // Check if this is a redundant update
159
- if (loopState!.lastState && deepEqual(state, loopState!.lastState)) {
160
- console.log('[Skip Component] Skipping redundant state update');
161
- return; // Don't process identical state updates
162
- }
163
-
164
- const now = Date.now();
165
- const timeSinceLastUpdate = now - loopState!.lastUpdate;
166
-
167
- // Check for rapid updates
168
- if (timeSinceLastUpdate < 100) {
169
- loopState!.count++;
170
-
171
- if (loopState!.count > 5) {
172
- console.error('[Skip Component] Rapid state updates detected - possible infinite loop');
173
- console.error('Updates in last 100ms:', loopState!.count);
174
- // Still process the update but warn
175
- }
176
- } else {
177
- // Reset counter if more than 100ms has passed
178
- loopState!.count = 0;
179
- }
180
-
181
- loopState!.lastUpdate = now;
182
- loopState!.lastState = JSON.parse(JSON.stringify(state)); // Deep clone to preserve state
183
-
184
- console.log('[Skip Component] Processing state update');
185
-
186
- // Push to debounce subject (which already has 3 second debounce)
187
- subject!.next(state);
188
- };
189
- }
190
-
191
- if (callbacks.NotifyEvent && typeof callbacks.NotifyEvent === 'function') {
192
- normalized.NotifyEvent = callbacks.NotifyEvent;
193
- }
194
-
195
129
  return normalized;
196
130
  }
197
131
 
@@ -284,34 +218,7 @@ export function mergeProps(...propsList: Partial<ComponentProps>[]): ComponentPr
284
218
 
285
219
  return merged;
286
220
  }
287
-
288
- /**
289
- * Cleanup function for prop builder resources
290
- * @param callbacks - The callbacks object that was used to build props
291
- */
292
- export function cleanupPropBuilder(callbacks: ComponentCallbacks): void {
293
- if (callbacks.UpdateUserState && typeof callbacks.UpdateUserState === 'function') {
294
- const originalCallback = callbacks.UpdateUserState;
295
-
296
- // Unsubscribe from the subject
297
- const subscription = updateUserStateSubscriptions.get(originalCallback);
298
- if (subscription) {
299
- subscription.unsubscribe();
300
- updateUserStateSubscriptions.delete(originalCallback);
301
- }
302
-
303
- // Complete and remove the subject
304
- const subject = updateUserStateSubjects.get(originalCallback);
305
- if (subject) {
306
- subject.complete();
307
- updateUserStateSubjects.delete(originalCallback);
308
- }
309
-
310
- // Clear loop detection state
311
- loopDetectionStates.delete(originalCallback);
312
- }
313
- }
314
-
221
+
315
222
  /**
316
223
  * Creates a props transformer function
317
224
  * @param transformations - Map of prop paths to transformer functions
@@ -372,20 +279,6 @@ export function wrapCallbacksWithLogging(
372
279
  };
373
280
  }
374
281
 
375
- if (callbacks.UpdateUserState) {
376
- wrapped.UpdateUserState = (state: any) => {
377
- console.log(`[${componentName}] UpdateUserState called:`, state);
378
- callbacks.UpdateUserState!(state);
379
- };
380
- }
381
-
382
- if (callbacks.NotifyEvent) {
383
- wrapped.NotifyEvent = (event: string, data: any) => {
384
- console.log(`[${componentName}] NotifyEvent called:`, { event, data });
385
- callbacks.NotifyEvent!(event, data);
386
- };
387
- }
388
-
389
282
  return wrapped;
390
283
  }
391
284
 
@@ -114,6 +114,8 @@ export interface ComponentProps {
114
114
  components?: Record<string, any>;
115
115
  /** Component styles */
116
116
  styles?: ComponentStyles;
117
+ /** Standard state change handler for controlled components */
118
+ onStateChanged?: (stateUpdate: Record<string, any>) => void;
117
119
  }
118
120
 
119
121
  /**
@@ -223,4 +225,7 @@ export interface ErrorBoundaryOptions {
223
225
  logErrors?: boolean;
224
226
  /** Error recovery strategy */
225
227
  recovery?: 'retry' | 'reset' | 'none';
226
- }
228
+ }
229
+
230
+ // Export library configuration types
231
+ export * from './library-config';
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Configuration for external libraries used in React components
3
+ */
4
+
5
+ export interface ExternalLibraryConfig {
6
+ /** Unique identifier for the library */
7
+ id: string;
8
+
9
+ /** Library name (e.g., 'lodash') */
10
+ name: string;
11
+
12
+ /** Display name for UI (e.g., 'Lodash') */
13
+ displayName: string;
14
+
15
+ /** Library category */
16
+ category: 'core' | 'runtime' | 'ui' | 'charting' | 'utility';
17
+
18
+ /** Global variable name when loaded (e.g., '_' for lodash) */
19
+ globalVariable: string;
20
+
21
+ /** Library version */
22
+ version: string;
23
+
24
+ /** CDN URL for the library JavaScript */
25
+ cdnUrl: string;
26
+
27
+ /** Optional CDN URL for library CSS */
28
+ cdnCssUrl?: string;
29
+
30
+ /** Library description */
31
+ description: string;
32
+
33
+ /** Instructions for AI when using this library */
34
+ aiInstructions?: string;
35
+
36
+ /** Example usage code */
37
+ exampleUsage?: string;
38
+
39
+ /** Whether the library is enabled */
40
+ isEnabled: boolean;
41
+
42
+ /** Whether this is a core library (always loaded) */
43
+ isCore: boolean;
44
+
45
+ /** Whether this is runtime-only (not exposed to generated components) */
46
+ isRuntimeOnly?: boolean;
47
+ }
48
+
49
+ export interface LibraryConfigurationMetadata {
50
+ version: string;
51
+ lastUpdated: string;
52
+ description?: string;
53
+ }
54
+
55
+ export interface LibraryConfiguration {
56
+ libraries: ExternalLibraryConfig[];
57
+ metadata: LibraryConfigurationMetadata;
58
+ }
59
+
60
+ /**
61
+ * Library loading options
62
+ */
63
+ export interface LibraryLoadOptions {
64
+ /** Skip loading if already loaded */
65
+ skipIfLoaded?: boolean;
66
+
67
+ /** Timeout for loading (ms) */
68
+ timeout?: number;
69
+
70
+ /** Filter to specific categories */
71
+ categories?: Array<ExternalLibraryConfig['category']>;
72
+
73
+ /** Exclude runtime-only libraries */
74
+ excludeRuntimeOnly?: boolean;
75
+ }
@@ -0,0 +1,61 @@
1
+ import { ExternalLibraryConfig } from '../types/library-config';
2
+
3
+ /**
4
+ * Core runtime libraries required for the React runtime to function.
5
+ * These are not plugin libraries and are always loaded.
6
+ */
7
+ export const CORE_RUNTIME_LIBRARIES: ExternalLibraryConfig[] = [
8
+ {
9
+ id: 'react',
10
+ name: 'react',
11
+ displayName: 'React',
12
+ category: 'runtime',
13
+ globalVariable: 'React',
14
+ version: '18.2.0',
15
+ cdnUrl: 'https://unpkg.com/react@18.2.0/umd/react.production.min.js',
16
+ description: 'React core library',
17
+ isEnabled: true,
18
+ isCore: true,
19
+ isRuntimeOnly: true
20
+ },
21
+ {
22
+ id: 'react-dom',
23
+ name: 'react-dom',
24
+ displayName: 'ReactDOM',
25
+ category: 'runtime',
26
+ globalVariable: 'ReactDOM',
27
+ version: '18.2.0',
28
+ cdnUrl: 'https://unpkg.com/react-dom@18.2.0/umd/react-dom.production.min.js',
29
+ description: 'React DOM library',
30
+ isEnabled: true,
31
+ isCore: true,
32
+ isRuntimeOnly: true
33
+ },
34
+ {
35
+ id: 'babel-standalone',
36
+ name: '@babel/standalone',
37
+ displayName: 'Babel Standalone',
38
+ category: 'runtime',
39
+ globalVariable: 'Babel',
40
+ version: '7.24.4',
41
+ cdnUrl: 'https://unpkg.com/@babel/standalone@7.24.4/babel.min.js',
42
+ description: 'Babel compiler for JSX transformation',
43
+ isEnabled: true,
44
+ isCore: true,
45
+ isRuntimeOnly: true
46
+ }
47
+ ];
48
+
49
+ /**
50
+ * Get the core runtime libraries configuration
51
+ */
52
+ export function getCoreRuntimeLibraries(): ExternalLibraryConfig[] {
53
+ return CORE_RUNTIME_LIBRARIES;
54
+ }
55
+
56
+ /**
57
+ * Check if a library ID is a core runtime library
58
+ */
59
+ export function isCoreRuntimeLibrary(libraryId: string): boolean {
60
+ return CORE_RUNTIME_LIBRARIES.some(lib => lib.id === libraryId);
61
+ }