@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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +24 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -1
- package/dist/utilities/component-error-analyzer.d.ts +20 -0
- package/dist/utilities/component-error-analyzer.d.ts.map +1 -0
- package/dist/utilities/component-error-analyzer.js +204 -0
- package/dist/utilities/component-styles.d.ts +4 -0
- package/dist/utilities/component-styles.d.ts.map +1 -0
- package/dist/utilities/component-styles.js +97 -0
- package/dist/utilities/index.d.ts +6 -0
- package/dist/utilities/index.d.ts.map +1 -0
- package/dist/utilities/index.js +21 -0
- package/dist/utilities/library-loader.d.ts +33 -0
- package/dist/utilities/library-loader.d.ts.map +1 -0
- package/dist/utilities/library-loader.js +193 -0
- package/dist/utilities/runtime-utilities.d.ts +10 -0
- package/dist/utilities/runtime-utilities.d.ts.map +1 -0
- package/dist/utilities/runtime-utilities.js +92 -0
- package/dist/utilities/standard-libraries.d.ts +27 -0
- package/dist/utilities/standard-libraries.d.ts.map +1 -0
- package/dist/utilities/standard-libraries.js +55 -0
- package/package.json +4 -1
- package/src/index.ts +31 -0
- package/src/utilities/component-error-analyzer.ts +315 -0
- package/src/utilities/component-styles.ts +121 -0
- package/src/utilities/index.ts +10 -0
- package/src/utilities/library-loader.ts +307 -0
- package/src/utilities/runtime-utilities.ts +122 -0
- package/src/utilities/standard-libraries.ts +97 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Library loading utilities for React runtime
|
|
3
|
+
* Provides methods to load and manage external JavaScript libraries and CSS
|
|
4
|
+
* @module @memberjunction/react-runtime/utilities
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
STANDARD_LIBRARY_URLS,
|
|
9
|
+
StandardLibraries,
|
|
10
|
+
getCoreLibraryUrls,
|
|
11
|
+
getUILibraryUrls,
|
|
12
|
+
getCSSUrls
|
|
13
|
+
} from './standard-libraries';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Represents a loaded script or CSS resource
|
|
17
|
+
*/
|
|
18
|
+
interface LoadedResource {
|
|
19
|
+
element: HTMLScriptElement | HTMLLinkElement;
|
|
20
|
+
promise: Promise<any>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Options for loading libraries
|
|
25
|
+
*/
|
|
26
|
+
export interface LibraryLoadOptions {
|
|
27
|
+
/** Load core libraries (lodash, d3, Chart.js, dayjs) */
|
|
28
|
+
loadCore?: boolean;
|
|
29
|
+
/** Load UI libraries (antd, React Bootstrap) */
|
|
30
|
+
loadUI?: boolean;
|
|
31
|
+
/** Load CSS files for UI libraries */
|
|
32
|
+
loadCSS?: boolean;
|
|
33
|
+
/** Custom library URLs to load */
|
|
34
|
+
customLibraries?: { url: string; globalName: string }[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Result of loading libraries
|
|
39
|
+
*/
|
|
40
|
+
export interface LibraryLoadResult {
|
|
41
|
+
React: any;
|
|
42
|
+
ReactDOM: any;
|
|
43
|
+
Babel: any;
|
|
44
|
+
libraries: StandardLibraries;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Library loader class for managing external script loading
|
|
49
|
+
*/
|
|
50
|
+
export class LibraryLoader {
|
|
51
|
+
private static loadedResources = new Map<string, LoadedResource>();
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Load all standard libraries (core + UI + CSS)
|
|
55
|
+
* This is the main method that should be used by test harness and Angular wrapper
|
|
56
|
+
*/
|
|
57
|
+
static async loadAllLibraries(): Promise<LibraryLoadResult> {
|
|
58
|
+
return this.loadLibraries({
|
|
59
|
+
loadCore: true,
|
|
60
|
+
loadUI: true,
|
|
61
|
+
loadCSS: true
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Load libraries with specific options
|
|
67
|
+
*/
|
|
68
|
+
static async loadLibraries(options: LibraryLoadOptions): Promise<LibraryLoadResult> {
|
|
69
|
+
const {
|
|
70
|
+
loadCore = true,
|
|
71
|
+
loadUI = true,
|
|
72
|
+
loadCSS = true,
|
|
73
|
+
customLibraries = []
|
|
74
|
+
} = options;
|
|
75
|
+
|
|
76
|
+
// Load React ecosystem first
|
|
77
|
+
const [React, ReactDOM, Babel] = await Promise.all([
|
|
78
|
+
this.loadScript(STANDARD_LIBRARY_URLS.REACT, 'React'),
|
|
79
|
+
this.loadScript(STANDARD_LIBRARY_URLS.REACT_DOM, 'ReactDOM'),
|
|
80
|
+
this.loadScript(STANDARD_LIBRARY_URLS.BABEL, 'Babel')
|
|
81
|
+
]);
|
|
82
|
+
|
|
83
|
+
// Load CSS files if requested (non-blocking)
|
|
84
|
+
if (loadCSS) {
|
|
85
|
+
getCSSUrls().forEach(url => this.loadCSS(url));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Prepare library loading promises
|
|
89
|
+
const libraryPromises: Promise<any>[] = [];
|
|
90
|
+
const libraryNames: string[] = [];
|
|
91
|
+
|
|
92
|
+
// Core libraries
|
|
93
|
+
if (loadCore) {
|
|
94
|
+
const coreUrls = getCoreLibraryUrls();
|
|
95
|
+
coreUrls.forEach(url => {
|
|
96
|
+
const name = this.getLibraryNameFromUrl(url);
|
|
97
|
+
libraryNames.push(name);
|
|
98
|
+
libraryPromises.push(this.loadScript(url, name));
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// UI libraries
|
|
103
|
+
if (loadUI) {
|
|
104
|
+
const uiUrls = getUILibraryUrls();
|
|
105
|
+
uiUrls.forEach(url => {
|
|
106
|
+
const name = this.getLibraryNameFromUrl(url);
|
|
107
|
+
libraryNames.push(name);
|
|
108
|
+
libraryPromises.push(this.loadScript(url, name));
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Custom libraries
|
|
113
|
+
customLibraries.forEach(({ url, globalName }) => {
|
|
114
|
+
libraryNames.push(globalName);
|
|
115
|
+
libraryPromises.push(this.loadScript(url, globalName));
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// Load all libraries
|
|
119
|
+
const loadedLibraries = await Promise.all(libraryPromises);
|
|
120
|
+
|
|
121
|
+
// Build libraries object
|
|
122
|
+
const libraries: StandardLibraries = {
|
|
123
|
+
_: undefined // Initialize with required property
|
|
124
|
+
};
|
|
125
|
+
libraryNames.forEach((name, index) => {
|
|
126
|
+
// Map common names
|
|
127
|
+
if (name === '_') {
|
|
128
|
+
libraries._ = loadedLibraries[index];
|
|
129
|
+
} else {
|
|
130
|
+
libraries[name] = loadedLibraries[index];
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Ensure all standard properties exist
|
|
135
|
+
if (!libraries._) libraries._ = (window as any)._;
|
|
136
|
+
if (!libraries.d3) libraries.d3 = (window as any).d3;
|
|
137
|
+
if (!libraries.Chart) libraries.Chart = (window as any).Chart;
|
|
138
|
+
if (!libraries.dayjs) libraries.dayjs = (window as any).dayjs;
|
|
139
|
+
if (!libraries.antd) libraries.antd = (window as any).antd;
|
|
140
|
+
if (!libraries.ReactBootstrap) libraries.ReactBootstrap = (window as any).ReactBootstrap;
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
React,
|
|
144
|
+
ReactDOM,
|
|
145
|
+
Babel,
|
|
146
|
+
libraries
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Load a script from URL
|
|
152
|
+
*/
|
|
153
|
+
private static async loadScript(url: string, globalName: string): Promise<any> {
|
|
154
|
+
// Check if already loaded
|
|
155
|
+
const existing = this.loadedResources.get(url);
|
|
156
|
+
if (existing) {
|
|
157
|
+
return existing.promise;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const promise = new Promise((resolve, reject) => {
|
|
161
|
+
// Check if global already exists
|
|
162
|
+
const existingGlobal = (window as any)[globalName];
|
|
163
|
+
if (existingGlobal) {
|
|
164
|
+
resolve(existingGlobal);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Check if script tag exists
|
|
169
|
+
const existingScript = document.querySelector(`script[src="${url}"]`);
|
|
170
|
+
if (existingScript) {
|
|
171
|
+
this.waitForScriptLoad(existingScript as HTMLScriptElement, globalName, resolve, reject);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Create new script
|
|
176
|
+
const script = document.createElement('script');
|
|
177
|
+
script.src = url;
|
|
178
|
+
script.async = true;
|
|
179
|
+
script.crossOrigin = 'anonymous';
|
|
180
|
+
|
|
181
|
+
script.onload = () => {
|
|
182
|
+
const global = (window as any)[globalName];
|
|
183
|
+
if (global) {
|
|
184
|
+
resolve(global);
|
|
185
|
+
} else {
|
|
186
|
+
// Some libraries may take a moment to initialize
|
|
187
|
+
setTimeout(() => {
|
|
188
|
+
const delayedGlobal = (window as any)[globalName];
|
|
189
|
+
if (delayedGlobal) {
|
|
190
|
+
resolve(delayedGlobal);
|
|
191
|
+
} else {
|
|
192
|
+
reject(new Error(`${globalName} not found after script load`));
|
|
193
|
+
}
|
|
194
|
+
}, 100);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
script.onerror = () => {
|
|
199
|
+
reject(new Error(`Failed to load script: ${url}`));
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
document.head.appendChild(script);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
this.loadedResources.set(url, {
|
|
206
|
+
element: document.querySelector(`script[src="${url}"]`)!,
|
|
207
|
+
promise
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
return promise;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Load CSS from URL
|
|
215
|
+
*/
|
|
216
|
+
private static loadCSS(url: string): void {
|
|
217
|
+
if (this.loadedResources.has(url)) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const existingLink = document.querySelector(`link[href="${url}"]`);
|
|
222
|
+
if (existingLink) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const link = document.createElement('link');
|
|
227
|
+
link.rel = 'stylesheet';
|
|
228
|
+
link.href = url;
|
|
229
|
+
document.head.appendChild(link);
|
|
230
|
+
|
|
231
|
+
this.loadedResources.set(url, {
|
|
232
|
+
element: link,
|
|
233
|
+
promise: Promise.resolve()
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Wait for existing script to load
|
|
239
|
+
*/
|
|
240
|
+
private static waitForScriptLoad(
|
|
241
|
+
script: HTMLScriptElement,
|
|
242
|
+
globalName: string,
|
|
243
|
+
resolve: (value: any) => void,
|
|
244
|
+
reject: (reason: any) => void
|
|
245
|
+
): void {
|
|
246
|
+
const checkGlobal = () => {
|
|
247
|
+
const global = (window as any)[globalName];
|
|
248
|
+
if (global) {
|
|
249
|
+
resolve(global);
|
|
250
|
+
} else {
|
|
251
|
+
// Retry after a short delay
|
|
252
|
+
setTimeout(() => {
|
|
253
|
+
const delayedGlobal = (window as any)[globalName];
|
|
254
|
+
if (delayedGlobal) {
|
|
255
|
+
resolve(delayedGlobal);
|
|
256
|
+
} else {
|
|
257
|
+
reject(new Error(`${globalName} not found after script load`));
|
|
258
|
+
}
|
|
259
|
+
}, 100);
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// Check if already loaded
|
|
264
|
+
if ((script as any).complete || (script as any).readyState === 'complete') {
|
|
265
|
+
checkGlobal();
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Wait for load
|
|
270
|
+
const loadHandler = () => {
|
|
271
|
+
script.removeEventListener('load', loadHandler);
|
|
272
|
+
checkGlobal();
|
|
273
|
+
};
|
|
274
|
+
script.addEventListener('load', loadHandler);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Get library name from URL for global variable mapping
|
|
279
|
+
*/
|
|
280
|
+
private static getLibraryNameFromUrl(url: string): string {
|
|
281
|
+
// Map known URLs to their global variable names
|
|
282
|
+
if (url.includes('lodash')) return '_';
|
|
283
|
+
if (url.includes('d3')) return 'd3';
|
|
284
|
+
if (url.includes('Chart.js') || url.includes('chart')) return 'Chart';
|
|
285
|
+
if (url.includes('dayjs')) return 'dayjs';
|
|
286
|
+
if (url.includes('antd')) return 'antd';
|
|
287
|
+
if (url.includes('react-bootstrap')) return 'ReactBootstrap';
|
|
288
|
+
|
|
289
|
+
// Default: extract name from URL
|
|
290
|
+
const match = url.match(/\/([^\/]+)(?:\.min)?\.js$/);
|
|
291
|
+
return match ? match[1] : 'unknown';
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Get all loaded resources (for cleanup)
|
|
296
|
+
*/
|
|
297
|
+
static getLoadedResources(): Map<string, LoadedResource> {
|
|
298
|
+
return this.loadedResources;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Clear loaded resources cache
|
|
303
|
+
*/
|
|
304
|
+
static clearCache(): void {
|
|
305
|
+
this.loadedResources.clear();
|
|
306
|
+
}
|
|
307
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Runtime utilities for React components providing access to MemberJunction core functionality
|
|
3
|
+
* @module @memberjunction/react-runtime/utilities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
Metadata,
|
|
8
|
+
RunView,
|
|
9
|
+
RunQuery,
|
|
10
|
+
RunViewParams,
|
|
11
|
+
RunQueryParams,
|
|
12
|
+
LogError
|
|
13
|
+
} from '@memberjunction/core';
|
|
14
|
+
|
|
15
|
+
import { MJGlobal, RegisterClass } from '@memberjunction/global';
|
|
16
|
+
import { ComponentUtilities, SimpleMetadata, SimpleRunQuery, SimpleRunView } from '@memberjunction/interactive-component-types';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Base class for providing runtime utilities to React components.
|
|
20
|
+
* This class can be extended and registered with MJ's ClassFactory
|
|
21
|
+
* to provide custom implementations of data access methods.
|
|
22
|
+
*/
|
|
23
|
+
@RegisterClass(RuntimeUtilities, 'RuntimeUtilities')
|
|
24
|
+
export class RuntimeUtilities {
|
|
25
|
+
/**
|
|
26
|
+
* Builds the complete utilities object for React components
|
|
27
|
+
* This is the main method that components will use
|
|
28
|
+
*/
|
|
29
|
+
public buildUtilities(): ComponentUtilities {
|
|
30
|
+
const md = new Metadata();
|
|
31
|
+
return this.SetupUtilities(md);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Sets up the utilities object - copied from skip-chat implementation
|
|
36
|
+
*/
|
|
37
|
+
private SetupUtilities(md: Metadata): ComponentUtilities {
|
|
38
|
+
const rv = new RunView();
|
|
39
|
+
const rq = new RunQuery();
|
|
40
|
+
const u: ComponentUtilities = {
|
|
41
|
+
md: this.CreateSimpleMetadata(md),
|
|
42
|
+
rv: this.CreateSimpleRunView(rv),
|
|
43
|
+
rq: this.CreateSimpleRunQuery(rq)
|
|
44
|
+
};
|
|
45
|
+
return u;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private CreateSimpleMetadata(md: Metadata): SimpleMetadata {
|
|
49
|
+
return {
|
|
50
|
+
Entities: md.Entities,
|
|
51
|
+
GetEntityObject: (entityName: string) => {
|
|
52
|
+
return md.GetEntityObject(entityName)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private CreateSimpleRunQuery(rq: RunQuery): SimpleRunQuery {
|
|
58
|
+
return {
|
|
59
|
+
RunQuery: async (params: RunQueryParams) => {
|
|
60
|
+
// Run a single query and return the results
|
|
61
|
+
try {
|
|
62
|
+
const result = await rq.RunQuery(params);
|
|
63
|
+
return result;
|
|
64
|
+
} catch (error) {
|
|
65
|
+
LogError(error);
|
|
66
|
+
throw error; // Re-throw to handle it in the caller
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private CreateSimpleRunView(rv: RunView): SimpleRunView {
|
|
73
|
+
return {
|
|
74
|
+
RunView: async (params: RunViewParams) => {
|
|
75
|
+
// Run a single view and return the results
|
|
76
|
+
try {
|
|
77
|
+
const result = await rv.RunView(params);
|
|
78
|
+
return result;
|
|
79
|
+
} catch (error) {
|
|
80
|
+
LogError(error);
|
|
81
|
+
throw error; // Re-throw to handle it in the caller
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
RunViews: async (params: RunViewParams[]) => {
|
|
85
|
+
// Runs multiple views and returns the results
|
|
86
|
+
try {
|
|
87
|
+
const results = await rv.RunViews(params);
|
|
88
|
+
return results;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
LogError(error);
|
|
91
|
+
throw error; // Re-throw to handle it in the caller
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Factory function to create RuntimeUtilities
|
|
100
|
+
* In a Node.js environment, this will use MJ's ClassFactory for runtime substitution
|
|
101
|
+
* In a browser environment, it will use the base class directly
|
|
102
|
+
*/
|
|
103
|
+
export function createRuntimeUtilities(): RuntimeUtilities {
|
|
104
|
+
// Check if we're in a Node.js environment with MJGlobal available
|
|
105
|
+
if (typeof window === 'undefined') {
|
|
106
|
+
try {
|
|
107
|
+
// Use ClassFactory to get the registered class, defaulting to base RuntimeUtilities
|
|
108
|
+
const obj = MJGlobal.Instance.ClassFactory.CreateInstance<RuntimeUtilities>(RuntimeUtilities);
|
|
109
|
+
if (!obj) {
|
|
110
|
+
throw new Error('Failed to create RuntimeUtilities instance');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Ensure the object is an instance of RuntimeUtilities
|
|
114
|
+
return obj;
|
|
115
|
+
} catch (e) {
|
|
116
|
+
// Fall through to default
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Default: just use the base class
|
|
121
|
+
return new RuntimeUtilities();
|
|
122
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Standard libraries configuration for React components
|
|
3
|
+
* @module @memberjunction/react-runtime/utilities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* CDN URLs for standard libraries used by React components
|
|
8
|
+
*/
|
|
9
|
+
export const STANDARD_LIBRARY_URLS = {
|
|
10
|
+
// Core React libraries
|
|
11
|
+
REACT: 'https://unpkg.com/react@18/umd/react.development.js',
|
|
12
|
+
REACT_DOM: 'https://unpkg.com/react-dom@18/umd/react-dom.development.js',
|
|
13
|
+
BABEL: 'https://unpkg.com/@babel/standalone/babel.min.js',
|
|
14
|
+
|
|
15
|
+
// Data Visualization
|
|
16
|
+
D3: 'https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js',
|
|
17
|
+
CHART_JS: 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.0/chart.umd.js',
|
|
18
|
+
|
|
19
|
+
// Utilities
|
|
20
|
+
LODASH: 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js',
|
|
21
|
+
DAYJS: 'https://unpkg.com/dayjs@1.11.10/dayjs.min.js',
|
|
22
|
+
|
|
23
|
+
// UI Libraries (optional)
|
|
24
|
+
ANTD: 'https://unpkg.com/antd@5.11.5/dist/antd.min.js',
|
|
25
|
+
REACT_BOOTSTRAP: 'https://unpkg.com/react-bootstrap@2.9.1/dist/react-bootstrap.min.js',
|
|
26
|
+
|
|
27
|
+
// CSS
|
|
28
|
+
ANTD_CSS: 'https://unpkg.com/antd@5.11.5/dist/reset.css',
|
|
29
|
+
BOOTSTRAP_CSS: 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css'
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Interface for standard libraries available to React components
|
|
34
|
+
*/
|
|
35
|
+
export interface StandardLibraries {
|
|
36
|
+
_: any; // lodash
|
|
37
|
+
d3?: any;
|
|
38
|
+
Chart?: any;
|
|
39
|
+
dayjs?: any;
|
|
40
|
+
antd?: any;
|
|
41
|
+
ReactBootstrap?: any;
|
|
42
|
+
[key: string]: any; // Allow additional libraries
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Get the list of core libraries that should always be loaded
|
|
47
|
+
*/
|
|
48
|
+
export function getCoreLibraryUrls(): string[] {
|
|
49
|
+
return [
|
|
50
|
+
STANDARD_LIBRARY_URLS.LODASH,
|
|
51
|
+
STANDARD_LIBRARY_URLS.D3,
|
|
52
|
+
STANDARD_LIBRARY_URLS.CHART_JS,
|
|
53
|
+
STANDARD_LIBRARY_URLS.DAYJS
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get the list of optional UI library URLs
|
|
59
|
+
*/
|
|
60
|
+
export function getUILibraryUrls(): string[] {
|
|
61
|
+
return [
|
|
62
|
+
STANDARD_LIBRARY_URLS.ANTD,
|
|
63
|
+
STANDARD_LIBRARY_URLS.REACT_BOOTSTRAP
|
|
64
|
+
];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get the list of CSS URLs for UI libraries
|
|
69
|
+
*/
|
|
70
|
+
export function getCSSUrls(): string[] {
|
|
71
|
+
return [
|
|
72
|
+
STANDARD_LIBRARY_URLS.ANTD_CSS,
|
|
73
|
+
STANDARD_LIBRARY_URLS.BOOTSTRAP_CSS
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Creates a standard libraries object for browser environments
|
|
79
|
+
* This assumes the libraries are already loaded as globals
|
|
80
|
+
*/
|
|
81
|
+
export function createStandardLibraries(): StandardLibraries {
|
|
82
|
+
if (typeof window === 'undefined') {
|
|
83
|
+
// Return empty object in Node.js environments
|
|
84
|
+
return {
|
|
85
|
+
_: undefined
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
_: (window as any)._,
|
|
91
|
+
d3: (window as any).d3,
|
|
92
|
+
Chart: (window as any).Chart,
|
|
93
|
+
dayjs: (window as any).dayjs,
|
|
94
|
+
antd: (window as any).antd,
|
|
95
|
+
ReactBootstrap: (window as any).ReactBootstrap
|
|
96
|
+
};
|
|
97
|
+
}
|