@memberjunction/react-runtime 2.70.0 → 2.72.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 (32) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +24 -0
  3. package/dist/index.d.ts +5 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +17 -1
  6. package/dist/utilities/component-error-analyzer.d.ts +20 -0
  7. package/dist/utilities/component-error-analyzer.d.ts.map +1 -0
  8. package/dist/utilities/component-error-analyzer.js +204 -0
  9. package/dist/utilities/component-styles.d.ts +4 -0
  10. package/dist/utilities/component-styles.d.ts.map +1 -0
  11. package/dist/utilities/component-styles.js +97 -0
  12. package/dist/utilities/index.d.ts +6 -0
  13. package/dist/utilities/index.d.ts.map +1 -0
  14. package/dist/utilities/index.js +21 -0
  15. package/dist/utilities/library-loader.d.ts +33 -0
  16. package/dist/utilities/library-loader.d.ts.map +1 -0
  17. package/dist/utilities/library-loader.js +193 -0
  18. package/dist/utilities/runtime-utilities.d.ts +10 -0
  19. package/dist/utilities/runtime-utilities.d.ts.map +1 -0
  20. package/dist/utilities/runtime-utilities.js +92 -0
  21. package/dist/utilities/standard-libraries.d.ts +27 -0
  22. package/dist/utilities/standard-libraries.d.ts.map +1 -0
  23. package/dist/utilities/standard-libraries.js +55 -0
  24. package/package.json +4 -1
  25. package/src/index.ts +31 -0
  26. package/src/utilities/component-error-analyzer.ts +315 -0
  27. package/src/utilities/component-styles.ts +121 -0
  28. package/src/utilities/index.ts +10 -0
  29. package/src/utilities/library-loader.ts +307 -0
  30. package/src/utilities/runtime-utilities.ts +122 -0
  31. package/src/utilities/standard-libraries.ts +97 -0
  32. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,315 @@
1
+ /**
2
+ * @fileoverview Component error analysis utilities
3
+ * Provides methods to analyze component errors and identify failed components
4
+ * @module @memberjunction/react-runtime/utilities
5
+ */
6
+
7
+ /**
8
+ * Information about a failed component
9
+ */
10
+ export interface FailedComponentInfo {
11
+ /** Component name that failed */
12
+ componentName: string;
13
+ /** Error type (e.g., 'not_defined', 'render_error', 'property_error') */
14
+ errorType: string;
15
+ /** Original error message */
16
+ errorMessage: string;
17
+ /** Line number if available */
18
+ lineNumber?: number;
19
+ /** Additional context */
20
+ context?: string;
21
+ }
22
+
23
+ /**
24
+ * Analyzes component errors to provide detailed failure information
25
+ */
26
+ export class ComponentErrorAnalyzer {
27
+ /**
28
+ * Common error patterns for component failures
29
+ */
30
+ private static readonly ERROR_PATTERNS = [
31
+ {
32
+ // Component is not defined
33
+ pattern: /ReferenceError: (\w+) is not defined/,
34
+ errorType: 'not_defined',
35
+ extractComponent: (match: RegExpMatchArray) => match[1]
36
+ },
37
+ {
38
+ // Cannot read property of undefined (component reference)
39
+ pattern: /Cannot read propert(?:y|ies) '(\w+)' of undefined/,
40
+ errorType: 'property_error',
41
+ extractComponent: (match: RegExpMatchArray) => match[1]
42
+ },
43
+ {
44
+ // Component render errors
45
+ pattern: /(\w+)\(\.\.\.\): Nothing was returned from render/,
46
+ errorType: 'render_error',
47
+ extractComponent: (match: RegExpMatchArray) => match[1]
48
+ },
49
+ {
50
+ // Component in stack trace
51
+ pattern: /at (\w+Component\w*)/,
52
+ errorType: 'stack_trace',
53
+ extractComponent: (match: RegExpMatchArray) => match[1]
54
+ },
55
+ {
56
+ // React component errors
57
+ pattern: /Error: Unable to find node on an unmounted component/,
58
+ errorType: 'unmounted_component',
59
+ extractComponent: () => null // Need to look at stack trace
60
+ },
61
+ {
62
+ // Hook errors
63
+ pattern: /Invalid hook call.*component (\w+)/,
64
+ errorType: 'invalid_hook',
65
+ extractComponent: (match: RegExpMatchArray) => match[1]
66
+ },
67
+ {
68
+ // Type errors in components
69
+ pattern: /TypeError:.*in (\w+) \(at/,
70
+ errorType: 'type_error',
71
+ extractComponent: (match: RegExpMatchArray) => match[1]
72
+ },
73
+ {
74
+ // Missing imports/components
75
+ pattern: /Module not found: Error: Can't resolve '\.\/(\w+)'/,
76
+ errorType: 'missing_import',
77
+ extractComponent: (match: RegExpMatchArray) => match[1]
78
+ },
79
+ {
80
+ // Component is not a function
81
+ pattern: /(\w+) is not a function/,
82
+ errorType: 'not_a_function',
83
+ extractComponent: (match: RegExpMatchArray) => match[1]
84
+ },
85
+ {
86
+ // Minified React error with component hint
87
+ pattern: /Minified React error.*Visit.*for the full message.*component[: ](\w+)/s,
88
+ errorType: 'react_error',
89
+ extractComponent: (match: RegExpMatchArray) => match[1]
90
+ }
91
+ ];
92
+
93
+ /**
94
+ * Analyzes error messages to identify which components failed
95
+ * @param errors Array of error messages
96
+ * @returns Array of failed component names
97
+ */
98
+ static identifyFailedComponents(errors: string[]): string[] {
99
+ const failedComponents = new Set<string>();
100
+
101
+ for (const error of errors) {
102
+ const components = this.extractComponentsFromError(error);
103
+ components.forEach(comp => failedComponents.add(comp));
104
+ }
105
+
106
+ return Array.from(failedComponents);
107
+ }
108
+
109
+ /**
110
+ * Analyzes errors and returns detailed information about failures
111
+ * @param errors Array of error messages
112
+ * @returns Array of detailed failure information
113
+ */
114
+ static analyzeComponentErrors(errors: string[]): FailedComponentInfo[] {
115
+ const failures: FailedComponentInfo[] = [];
116
+
117
+ for (const error of errors) {
118
+ const failureInfo = this.analyzeError(error);
119
+ failures.push(...failureInfo);
120
+ }
121
+
122
+ // Remove duplicates based on component name and error type
123
+ const uniqueFailures = new Map<string, FailedComponentInfo>();
124
+ failures.forEach(failure => {
125
+ const key = `${failure.componentName}-${failure.errorType}`;
126
+ if (!uniqueFailures.has(key)) {
127
+ uniqueFailures.set(key, failure);
128
+ }
129
+ });
130
+
131
+ return Array.from(uniqueFailures.values());
132
+ }
133
+
134
+ /**
135
+ * Extract component names from a single error message
136
+ */
137
+ private static extractComponentsFromError(error: string): string[] {
138
+ const components: string[] = [];
139
+
140
+ for (const errorPattern of this.ERROR_PATTERNS) {
141
+ const match = error.match(errorPattern.pattern);
142
+ if (match) {
143
+ const componentName = errorPattern.extractComponent(match);
144
+ if (componentName && this.isLikelyComponentName(componentName)) {
145
+ components.push(componentName);
146
+ }
147
+ }
148
+ }
149
+
150
+ // Also check for components in stack traces
151
+ const stackComponents = this.extractComponentsFromStackTrace(error);
152
+ components.push(...stackComponents);
153
+
154
+ return components;
155
+ }
156
+
157
+ /**
158
+ * Analyze a single error and return detailed information
159
+ */
160
+ private static analyzeError(error: string): FailedComponentInfo[] {
161
+ const failures: FailedComponentInfo[] = [];
162
+
163
+ for (const errorPattern of this.ERROR_PATTERNS) {
164
+ const match = error.match(errorPattern.pattern);
165
+ if (match) {
166
+ const componentName = errorPattern.extractComponent(match);
167
+ if (componentName && this.isLikelyComponentName(componentName)) {
168
+ failures.push({
169
+ componentName,
170
+ errorType: errorPattern.errorType,
171
+ errorMessage: error,
172
+ lineNumber: this.extractLineNumber(error),
173
+ context: this.extractContext(error)
174
+ });
175
+ }
176
+ }
177
+ }
178
+
179
+ // If no specific pattern matched, try to extract from stack trace
180
+ if (failures.length === 0) {
181
+ const stackComponents = this.extractComponentsFromStackTrace(error);
182
+ stackComponents.forEach(componentName => {
183
+ failures.push({
184
+ componentName,
185
+ errorType: 'unknown',
186
+ errorMessage: error,
187
+ lineNumber: this.extractLineNumber(error)
188
+ });
189
+ });
190
+ }
191
+
192
+ return failures;
193
+ }
194
+
195
+ /**
196
+ * Extract component names from stack trace
197
+ */
198
+ private static extractComponentsFromStackTrace(error: string): string[] {
199
+ const components: string[] = [];
200
+
201
+ // Look for React component patterns in stack traces
202
+ const stackPatterns = [
203
+ /at (\w+Component\w*)/g,
204
+ /at (\w+)\s*\(/g,
205
+ /in (\w+)\s*\(at/g,
206
+ /in (\w+)\s*\(created by/g
207
+ ];
208
+
209
+ for (const pattern of stackPatterns) {
210
+ let match;
211
+ while ((match = pattern.exec(error)) !== null) {
212
+ const name = match[1];
213
+ if (this.isLikelyComponentName(name)) {
214
+ components.push(name);
215
+ }
216
+ }
217
+ }
218
+
219
+ return [...new Set(components)]; // Remove duplicates
220
+ }
221
+
222
+ /**
223
+ * Check if a string is likely to be a React component name
224
+ */
225
+ private static isLikelyComponentName(name: string): boolean {
226
+ // Component names typically:
227
+ // - Start with uppercase letter
228
+ // - Are not JavaScript built-ins
229
+ // - Are not common non-component names
230
+
231
+ const jsBuiltins = new Set([
232
+ 'Object', 'Array', 'String', 'Number', 'Boolean', 'Function',
233
+ 'Promise', 'Error', 'TypeError', 'ReferenceError', 'SyntaxError',
234
+ 'undefined', 'null', 'console', 'window', 'document'
235
+ ]);
236
+
237
+ const nonComponents = new Set([
238
+ 'render', 'setState', 'forceUpdate', 'props', 'state', 'context',
239
+ 'componentDidMount', 'componentWillUnmount', 'useEffect', 'useState'
240
+ ]);
241
+
242
+ return (
243
+ name.length > 0 &&
244
+ /^[A-Z]/.test(name) && // Starts with uppercase
245
+ !jsBuiltins.has(name) &&
246
+ !nonComponents.has(name) &&
247
+ !/^use[A-Z]/.test(name) // Not a hook
248
+ );
249
+ }
250
+
251
+ /**
252
+ * Extract line number from error message
253
+ */
254
+ private static extractLineNumber(error: string): number | undefined {
255
+ // Look for patterns like ":12:34" or "line 12"
256
+ const patterns = [
257
+ /:(\d+):\d+/,
258
+ /line (\d+)/i,
259
+ /Line (\d+)/
260
+ ];
261
+
262
+ for (const pattern of patterns) {
263
+ const match = error.match(pattern);
264
+ if (match) {
265
+ return parseInt(match[1], 10);
266
+ }
267
+ }
268
+
269
+ return undefined;
270
+ }
271
+
272
+ /**
273
+ * Extract additional context from error
274
+ */
275
+ private static extractContext(error: string): string | undefined {
276
+ // Extract file names or additional context
277
+ const fileMatch = error.match(/\(at ([^)]+)\)/);
278
+ if (fileMatch) {
279
+ return fileMatch[1];
280
+ }
281
+
282
+ // Extract "created by" information
283
+ const createdByMatch = error.match(/created by (\w+)/);
284
+ if (createdByMatch) {
285
+ return `Created by ${createdByMatch[1]}`;
286
+ }
287
+
288
+ return undefined;
289
+ }
290
+
291
+ /**
292
+ * Format error analysis results for logging
293
+ */
294
+ static formatAnalysisResults(failures: FailedComponentInfo[]): string {
295
+ if (failures.length === 0) {
296
+ return 'No component failures detected';
297
+ }
298
+
299
+ let result = `Detected ${failures.length} component failure(s):\n`;
300
+
301
+ failures.forEach((failure, index) => {
302
+ result += `\n${index + 1}. Component: ${failure.componentName}\n`;
303
+ result += ` Error Type: ${failure.errorType}\n`;
304
+ if (failure.lineNumber) {
305
+ result += ` Line: ${failure.lineNumber}\n`;
306
+ }
307
+ if (failure.context) {
308
+ result += ` Context: ${failure.context}\n`;
309
+ }
310
+ result += ` Message: ${failure.errorMessage.substring(0, 200)}${failure.errorMessage.length > 200 ? '...' : ''}\n`;
311
+ });
312
+
313
+ return result;
314
+ }
315
+ }
@@ -0,0 +1,121 @@
1
+ /**
2
+ * @fileoverview Default component styles for React runtime
3
+ * @module @memberjunction/react-runtime/utilities
4
+ */
5
+
6
+ import { ComponentStyles } from '@memberjunction/interactive-component-types';
7
+
8
+ /**
9
+ * Creates the default component styles for Skip components
10
+ * These provide a modern, contemporary look and feel
11
+ * Copied from skip-chat implementation
12
+ */
13
+ export function SetupStyles(): ComponentStyles {
14
+ // Return modern, contemporary styles for generated components
15
+ return {
16
+ colors: {
17
+ // Primary colors - modern purple/blue gradient feel
18
+ primary: '#5B4FE9',
19
+ primaryHover: '#4940D4',
20
+ primaryLight: '#E8E6FF',
21
+
22
+ // Secondary colors - sophisticated gray
23
+ secondary: '#64748B',
24
+ secondaryHover: '#475569',
25
+
26
+ // Status colors
27
+ success: '#10B981',
28
+ successLight: '#D1FAE5',
29
+ warning: '#F59E0B',
30
+ warningLight: '#FEF3C7',
31
+ error: '#EF4444',
32
+ errorLight: '#FEE2E2',
33
+ info: '#3B82F6',
34
+ infoLight: '#DBEAFE',
35
+
36
+ // Base colors
37
+ background: '#FFFFFF',
38
+ surface: '#F8FAFC',
39
+ surfaceHover: '#F1F5F9',
40
+
41
+ // Text colors with better contrast
42
+ text: '#1E293B',
43
+ textSecondary: '#64748B',
44
+ textTertiary: '#94A3B8',
45
+ textInverse: '#FFFFFF',
46
+
47
+ // Border colors
48
+ border: '#E2E8F0',
49
+ borderLight: '#F1F5F9',
50
+ borderFocus: '#5B4FE9',
51
+
52
+ // Shadows (as color strings for easy use)
53
+ shadow: 'rgba(0, 0, 0, 0.05)',
54
+ shadowMedium: 'rgba(0, 0, 0, 0.1)',
55
+ shadowLarge: 'rgba(0, 0, 0, 0.15)',
56
+ },
57
+ spacing: {
58
+ xs: '4px',
59
+ sm: '8px',
60
+ md: '16px',
61
+ lg: '24px',
62
+ xl: '32px',
63
+ xxl: '48px',
64
+ xxxl: '64px',
65
+ },
66
+ typography: {
67
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, sans-serif',
68
+ fontSize: {
69
+ xs: '11px',
70
+ sm: '12px',
71
+ md: '14px',
72
+ lg: '16px',
73
+ xl: '20px',
74
+ xxl: '24px',
75
+ xxxl: '32px',
76
+ },
77
+ fontWeight: {
78
+ light: '300',
79
+ regular: '400',
80
+ medium: '500',
81
+ semibold: '600',
82
+ bold: '700',
83
+ },
84
+ lineHeight: {
85
+ tight: '1.25',
86
+ normal: '1.5',
87
+ relaxed: '1.75',
88
+ },
89
+ },
90
+ borders: {
91
+ radius: {
92
+ sm: '6px',
93
+ md: '8px',
94
+ lg: '12px',
95
+ xl: '16px',
96
+ full: '9999px',
97
+ },
98
+ width: {
99
+ thin: '1px',
100
+ medium: '2px',
101
+ thick: '3px',
102
+ },
103
+ },
104
+ shadows: {
105
+ sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
106
+ md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
107
+ lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
108
+ xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
109
+ inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',
110
+ },
111
+ transitions: {
112
+ fast: '150ms ease-in-out',
113
+ normal: '250ms ease-in-out',
114
+ slow: '350ms ease-in-out',
115
+ },
116
+ overflow: 'auto' // Default overflow style
117
+ }
118
+ }
119
+
120
+ // Also export with the original name for backward compatibility
121
+ export const createDefaultComponentStyles = SetupStyles;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @fileoverview Utilities module exports
3
+ * @module @memberjunction/react-runtime/utilities
4
+ */
5
+
6
+ export * from './runtime-utilities';
7
+ export * from './component-styles';
8
+ export * from './standard-libraries';
9
+ export * from './library-loader';
10
+ export * from './component-error-analyzer';