@memberjunction/react-runtime 2.76.0 → 2.78.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 +18 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/registry/component-registry.d.ts +1 -0
- package/dist/registry/component-registry.d.ts.map +1 -1
- package/dist/registry/component-registry.js +6 -3
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +4 -1
- package/dist/runtime/react-root-manager.d.ts +26 -0
- package/dist/runtime/react-root-manager.d.ts.map +1 -0
- package/dist/runtime/react-root-manager.js +122 -0
- package/dist/utilities/cache-manager.d.ts +38 -0
- package/dist/utilities/cache-manager.d.ts.map +1 -0
- package/dist/utilities/cache-manager.js +156 -0
- package/dist/utilities/index.d.ts +2 -0
- package/dist/utilities/index.d.ts.map +1 -1
- package/dist/utilities/index.js +2 -0
- package/dist/utilities/library-loader.d.ts.map +1 -1
- package/dist/utilities/library-loader.js +25 -8
- package/dist/utilities/resource-manager.d.ts +36 -0
- package/dist/utilities/resource-manager.d.ts.map +1 -0
- package/dist/utilities/resource-manager.js +225 -0
- package/package.json +4 -4
- package/src/index.ts +18 -0
- package/src/registry/component-registry.ts +14 -4
- package/src/runtime/index.ts +7 -1
- package/src/runtime/react-root-manager.ts +218 -0
- package/src/utilities/cache-manager.ts +253 -0
- package/src/utilities/index.ts +3 -1
- package/src/utilities/library-loader.ts +66 -21
- package/src/utilities/resource-manager.ts +371 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.LibraryLoader = void 0;
|
|
4
4
|
const standard_libraries_1 = require("./standard-libraries");
|
|
5
5
|
const core_libraries_1 = require("./core-libraries");
|
|
6
|
+
const resource_manager_1 = require("./resource-manager");
|
|
7
|
+
const LIBRARY_LOADER_COMPONENT_ID = 'mj-react-runtime-library-loader-singleton';
|
|
6
8
|
class LibraryLoader {
|
|
7
9
|
static async loadAllLibraries(config, additionalLibraries) {
|
|
8
10
|
if (config) {
|
|
@@ -98,13 +100,18 @@ class LibraryLoader {
|
|
|
98
100
|
script.src = url;
|
|
99
101
|
script.async = true;
|
|
100
102
|
script.crossOrigin = 'anonymous';
|
|
101
|
-
|
|
103
|
+
const cleanup = () => {
|
|
104
|
+
script.removeEventListener('load', onLoad);
|
|
105
|
+
script.removeEventListener('error', onError);
|
|
106
|
+
};
|
|
107
|
+
const onLoad = () => {
|
|
108
|
+
cleanup();
|
|
102
109
|
const global = window[globalName];
|
|
103
110
|
if (global) {
|
|
104
111
|
resolve(global);
|
|
105
112
|
}
|
|
106
113
|
else {
|
|
107
|
-
setTimeout(() => {
|
|
114
|
+
const timeoutId = resource_manager_1.resourceManager.setTimeout(LIBRARY_LOADER_COMPONENT_ID, () => {
|
|
108
115
|
const delayedGlobal = window[globalName];
|
|
109
116
|
if (delayedGlobal) {
|
|
110
117
|
resolve(delayedGlobal);
|
|
@@ -112,13 +119,17 @@ class LibraryLoader {
|
|
|
112
119
|
else {
|
|
113
120
|
reject(new Error(`${globalName} not found after script load`));
|
|
114
121
|
}
|
|
115
|
-
}, 100);
|
|
122
|
+
}, 100, { url, globalName });
|
|
116
123
|
}
|
|
117
124
|
};
|
|
118
|
-
|
|
125
|
+
const onError = () => {
|
|
126
|
+
cleanup();
|
|
119
127
|
reject(new Error(`Failed to load script: ${url}`));
|
|
120
128
|
};
|
|
129
|
+
script.addEventListener('load', onLoad);
|
|
130
|
+
script.addEventListener('error', onError);
|
|
121
131
|
document.head.appendChild(script);
|
|
132
|
+
resource_manager_1.resourceManager.registerDOMElement(LIBRARY_LOADER_COMPONENT_ID, script);
|
|
122
133
|
});
|
|
123
134
|
this.loadedResources.set(url, {
|
|
124
135
|
element: document.querySelector(`script[src="${url}"]`),
|
|
@@ -138,6 +149,7 @@ class LibraryLoader {
|
|
|
138
149
|
link.rel = 'stylesheet';
|
|
139
150
|
link.href = url;
|
|
140
151
|
document.head.appendChild(link);
|
|
152
|
+
resource_manager_1.resourceManager.registerDOMElement(LIBRARY_LOADER_COMPONENT_ID, link);
|
|
141
153
|
this.loadedResources.set(url, {
|
|
142
154
|
element: link,
|
|
143
155
|
promise: Promise.resolve()
|
|
@@ -150,7 +162,7 @@ class LibraryLoader {
|
|
|
150
162
|
resolve(global);
|
|
151
163
|
}
|
|
152
164
|
else {
|
|
153
|
-
setTimeout(() => {
|
|
165
|
+
resource_manager_1.resourceManager.setTimeout(LIBRARY_LOADER_COMPONENT_ID, () => {
|
|
154
166
|
const delayedGlobal = window[globalName];
|
|
155
167
|
if (delayedGlobal) {
|
|
156
168
|
resolve(delayedGlobal);
|
|
@@ -158,7 +170,7 @@ class LibraryLoader {
|
|
|
158
170
|
else {
|
|
159
171
|
reject(new Error(`${globalName} not found after script load`));
|
|
160
172
|
}
|
|
161
|
-
}, 100);
|
|
173
|
+
}, 100, { context: 'waitForScriptLoad', globalName });
|
|
162
174
|
}
|
|
163
175
|
};
|
|
164
176
|
if (script.complete || script.readyState === 'complete') {
|
|
@@ -166,16 +178,21 @@ class LibraryLoader {
|
|
|
166
178
|
return;
|
|
167
179
|
}
|
|
168
180
|
const loadHandler = () => {
|
|
169
|
-
script.removeEventListener('load', loadHandler);
|
|
170
181
|
checkGlobal();
|
|
171
182
|
};
|
|
172
|
-
|
|
183
|
+
resource_manager_1.resourceManager.addEventListener(LIBRARY_LOADER_COMPONENT_ID, script, 'load', loadHandler, { once: true });
|
|
173
184
|
}
|
|
174
185
|
static getLoadedResources() {
|
|
175
186
|
return this.loadedResources;
|
|
176
187
|
}
|
|
177
188
|
static clearCache() {
|
|
189
|
+
this.loadedResources.forEach((resource, url) => {
|
|
190
|
+
if (resource.element && resource.element.parentNode) {
|
|
191
|
+
resource.element.parentNode.removeChild(resource.element);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
178
194
|
this.loadedResources.clear();
|
|
195
|
+
resource_manager_1.resourceManager.cleanupComponent(LIBRARY_LOADER_COMPONENT_ID);
|
|
179
196
|
}
|
|
180
197
|
}
|
|
181
198
|
exports.LibraryLoader = LibraryLoader;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
export type TimerId = number | NodeJS.Timeout;
|
|
3
|
+
export interface ManagedResource {
|
|
4
|
+
type: 'timer' | 'interval' | 'animationFrame' | 'eventListener' | 'domElement' | 'observable' | 'reactRoot';
|
|
5
|
+
id: string | TimerId;
|
|
6
|
+
cleanup: () => void;
|
|
7
|
+
metadata?: Record<string, any>;
|
|
8
|
+
}
|
|
9
|
+
export declare class ResourceManager {
|
|
10
|
+
private resources;
|
|
11
|
+
private globalResources;
|
|
12
|
+
private cleanupCallbacks;
|
|
13
|
+
setTimeout(componentId: string, callback: () => void, delay: number, metadata?: Record<string, any>): number;
|
|
14
|
+
setInterval(componentId: string, callback: () => void, delay: number, metadata?: Record<string, any>): number;
|
|
15
|
+
requestAnimationFrame(componentId: string, callback: FrameRequestCallback, metadata?: Record<string, any>): TimerId;
|
|
16
|
+
clearTimeout(componentId: string, id: number): void;
|
|
17
|
+
clearInterval(componentId: string, id: number): void;
|
|
18
|
+
cancelAnimationFrame(componentId: string, id: TimerId): void;
|
|
19
|
+
addEventListener(componentId: string, target: EventTarget, type: string, listener: EventListener, options?: AddEventListenerOptions): void;
|
|
20
|
+
registerDOMElement(componentId: string, element: any, cleanup?: () => void): void;
|
|
21
|
+
registerReactRoot(componentId: string, root: any, unmountFn: () => void): void;
|
|
22
|
+
registerCleanup(componentId: string, cleanup: () => void): void;
|
|
23
|
+
registerGlobalResource(resource: ManagedResource): void;
|
|
24
|
+
private addResource;
|
|
25
|
+
private removeResource;
|
|
26
|
+
cleanupComponent(componentId: string): void;
|
|
27
|
+
cleanupGlobal(): void;
|
|
28
|
+
cleanupAll(): void;
|
|
29
|
+
getStats(): {
|
|
30
|
+
componentCount: number;
|
|
31
|
+
resourceCounts: Record<string, number>;
|
|
32
|
+
globalResourceCount: number;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export declare const resourceManager: ResourceManager;
|
|
36
|
+
//# sourceMappingURL=resource-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-manager.d.ts","sourceRoot":"","sources":["../../src/utilities/resource-manager.ts"],"names":[],"mappings":";AAOA,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,gBAAgB,GAAG,eAAe,GAAG,YAAY,GAAG,YAAY,GAAG,WAAW,CAAC;IAC5G,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAiDD,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAA2C;IAC5D,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,gBAAgB,CAAqC;IAK7D,UAAU,CACR,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,IAAI,EACpB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC7B,MAAM;IAmBT,WAAW,CACT,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,IAAI,EACpB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC7B,MAAM;IAgBT,qBAAqB,CACnB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,oBAAoB,EAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC7B,OAAO;IAwBV,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAQnD,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAQpD,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,GAAG,IAAI;IAa5D,gBAAgB,CACd,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE,uBAAuB,GAChC,IAAI;IAsBP,kBAAkB,CAChB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,GAAG,EACZ,OAAO,CAAC,EAAE,MAAM,IAAI,GACnB,IAAI;IAuBP,iBAAiB,CACf,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,GAAG,EACT,SAAS,EAAE,MAAM,IAAI,GACpB,IAAI;IAYP,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAU/D,sBAAsB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAOvD,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,cAAc;IAmBtB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IA+B3C,aAAa,IAAI,IAAI;IAcrB,UAAU,IAAI,IAAI;IAalB,QAAQ,IAAI;QACV,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvC,mBAAmB,EAAE,MAAM,CAAC;KAC7B;CAeF;AAGD,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resourceManager = exports.ResourceManager = void 0;
|
|
4
|
+
const getTimerFunctions = () => {
|
|
5
|
+
if (typeof window !== 'undefined' && window.setTimeout) {
|
|
6
|
+
return {
|
|
7
|
+
setTimeout: window.setTimeout.bind(window),
|
|
8
|
+
clearTimeout: window.clearTimeout.bind(window),
|
|
9
|
+
setInterval: window.setInterval.bind(window),
|
|
10
|
+
clearInterval: window.clearInterval.bind(window),
|
|
11
|
+
requestAnimationFrame: window.requestAnimationFrame?.bind(window),
|
|
12
|
+
cancelAnimationFrame: window.cancelAnimationFrame?.bind(window)
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
else if (typeof global !== 'undefined' && global.setTimeout) {
|
|
16
|
+
return {
|
|
17
|
+
setTimeout: global.setTimeout,
|
|
18
|
+
clearTimeout: global.clearTimeout,
|
|
19
|
+
setInterval: global.setInterval,
|
|
20
|
+
clearInterval: global.clearInterval,
|
|
21
|
+
requestAnimationFrame: undefined,
|
|
22
|
+
cancelAnimationFrame: undefined
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
const noop = () => { };
|
|
27
|
+
const noopWithReturn = () => 0;
|
|
28
|
+
return {
|
|
29
|
+
setTimeout: noopWithReturn,
|
|
30
|
+
clearTimeout: noop,
|
|
31
|
+
setInterval: noopWithReturn,
|
|
32
|
+
clearInterval: noop,
|
|
33
|
+
requestAnimationFrame: undefined,
|
|
34
|
+
cancelAnimationFrame: undefined
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const timers = getTimerFunctions();
|
|
39
|
+
class ResourceManager {
|
|
40
|
+
constructor() {
|
|
41
|
+
this.resources = new Map();
|
|
42
|
+
this.globalResources = new Set();
|
|
43
|
+
this.cleanupCallbacks = new Map();
|
|
44
|
+
}
|
|
45
|
+
setTimeout(componentId, callback, delay, metadata) {
|
|
46
|
+
const id = timers.setTimeout(() => {
|
|
47
|
+
this.removeResource(componentId, 'timer', id);
|
|
48
|
+
callback();
|
|
49
|
+
}, delay);
|
|
50
|
+
this.addResource(componentId, {
|
|
51
|
+
type: 'timer',
|
|
52
|
+
id,
|
|
53
|
+
cleanup: () => timers.clearTimeout(id),
|
|
54
|
+
metadata
|
|
55
|
+
});
|
|
56
|
+
return id;
|
|
57
|
+
}
|
|
58
|
+
setInterval(componentId, callback, delay, metadata) {
|
|
59
|
+
const id = timers.setInterval(callback, delay);
|
|
60
|
+
this.addResource(componentId, {
|
|
61
|
+
type: 'interval',
|
|
62
|
+
id,
|
|
63
|
+
cleanup: () => timers.clearInterval(id),
|
|
64
|
+
metadata
|
|
65
|
+
});
|
|
66
|
+
return id;
|
|
67
|
+
}
|
|
68
|
+
requestAnimationFrame(componentId, callback, metadata) {
|
|
69
|
+
if (!timers.requestAnimationFrame) {
|
|
70
|
+
return this.setTimeout(componentId, () => callback(Date.now()), 16, metadata);
|
|
71
|
+
}
|
|
72
|
+
const id = timers.requestAnimationFrame((time) => {
|
|
73
|
+
this.removeResource(componentId, 'animationFrame', id);
|
|
74
|
+
callback(time);
|
|
75
|
+
});
|
|
76
|
+
this.addResource(componentId, {
|
|
77
|
+
type: 'animationFrame',
|
|
78
|
+
id,
|
|
79
|
+
cleanup: () => timers.cancelAnimationFrame?.(id),
|
|
80
|
+
metadata
|
|
81
|
+
});
|
|
82
|
+
return id;
|
|
83
|
+
}
|
|
84
|
+
clearTimeout(componentId, id) {
|
|
85
|
+
timers.clearTimeout(id);
|
|
86
|
+
this.removeResource(componentId, 'timer', id);
|
|
87
|
+
}
|
|
88
|
+
clearInterval(componentId, id) {
|
|
89
|
+
timers.clearInterval(id);
|
|
90
|
+
this.removeResource(componentId, 'interval', id);
|
|
91
|
+
}
|
|
92
|
+
cancelAnimationFrame(componentId, id) {
|
|
93
|
+
if (timers.cancelAnimationFrame) {
|
|
94
|
+
timers.cancelAnimationFrame(id);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
timers.clearTimeout(id);
|
|
98
|
+
}
|
|
99
|
+
this.removeResource(componentId, 'animationFrame', id);
|
|
100
|
+
}
|
|
101
|
+
addEventListener(componentId, target, type, listener, options) {
|
|
102
|
+
if (target && typeof target.addEventListener === 'function') {
|
|
103
|
+
target.addEventListener(type, listener, options);
|
|
104
|
+
const resourceId = `${type}-${Date.now()}-${Math.random()}`;
|
|
105
|
+
this.addResource(componentId, {
|
|
106
|
+
type: 'eventListener',
|
|
107
|
+
id: resourceId,
|
|
108
|
+
cleanup: () => {
|
|
109
|
+
if (target && typeof target.removeEventListener === 'function') {
|
|
110
|
+
target.removeEventListener(type, listener, options);
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
metadata: { target, type, options }
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
registerDOMElement(componentId, element, cleanup) {
|
|
118
|
+
if (typeof document !== 'undefined' && element && element.parentNode) {
|
|
119
|
+
const resourceId = `dom-${Date.now()}-${Math.random()}`;
|
|
120
|
+
this.addResource(componentId, {
|
|
121
|
+
type: 'domElement',
|
|
122
|
+
id: resourceId,
|
|
123
|
+
cleanup: () => {
|
|
124
|
+
if (cleanup) {
|
|
125
|
+
cleanup();
|
|
126
|
+
}
|
|
127
|
+
if (element && element.parentNode && typeof element.parentNode.removeChild === 'function') {
|
|
128
|
+
element.parentNode.removeChild(element);
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
metadata: { element }
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
registerReactRoot(componentId, root, unmountFn) {
|
|
136
|
+
this.addResource(componentId, {
|
|
137
|
+
type: 'reactRoot',
|
|
138
|
+
id: `react-root-${componentId}`,
|
|
139
|
+
cleanup: unmountFn,
|
|
140
|
+
metadata: { root }
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
registerCleanup(componentId, cleanup) {
|
|
144
|
+
if (!this.cleanupCallbacks.has(componentId)) {
|
|
145
|
+
this.cleanupCallbacks.set(componentId, []);
|
|
146
|
+
}
|
|
147
|
+
this.cleanupCallbacks.get(componentId).push(cleanup);
|
|
148
|
+
}
|
|
149
|
+
registerGlobalResource(resource) {
|
|
150
|
+
this.globalResources.add(resource);
|
|
151
|
+
}
|
|
152
|
+
addResource(componentId, resource) {
|
|
153
|
+
if (!this.resources.has(componentId)) {
|
|
154
|
+
this.resources.set(componentId, new Set());
|
|
155
|
+
}
|
|
156
|
+
this.resources.get(componentId).add(resource);
|
|
157
|
+
}
|
|
158
|
+
removeResource(componentId, type, id) {
|
|
159
|
+
const componentResources = this.resources.get(componentId);
|
|
160
|
+
if (componentResources) {
|
|
161
|
+
const toRemove = Array.from(componentResources).find(r => r.type === type && r.id === id);
|
|
162
|
+
if (toRemove) {
|
|
163
|
+
componentResources.delete(toRemove);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
cleanupComponent(componentId) {
|
|
168
|
+
const componentResources = this.resources.get(componentId);
|
|
169
|
+
if (componentResources) {
|
|
170
|
+
componentResources.forEach(resource => {
|
|
171
|
+
try {
|
|
172
|
+
resource.cleanup();
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
console.error(`Error cleaning up ${resource.type} resource:`, error);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
this.resources.delete(componentId);
|
|
179
|
+
}
|
|
180
|
+
const callbacks = this.cleanupCallbacks.get(componentId);
|
|
181
|
+
if (callbacks) {
|
|
182
|
+
callbacks.forEach(callback => {
|
|
183
|
+
try {
|
|
184
|
+
callback();
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
console.error('Error executing cleanup callback:', error);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
this.cleanupCallbacks.delete(componentId);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
cleanupGlobal() {
|
|
194
|
+
this.globalResources.forEach(resource => {
|
|
195
|
+
try {
|
|
196
|
+
resource.cleanup();
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
console.error(`Error cleaning up global ${resource.type} resource:`, error);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
this.globalResources.clear();
|
|
203
|
+
}
|
|
204
|
+
cleanupAll() {
|
|
205
|
+
for (const componentId of this.resources.keys()) {
|
|
206
|
+
this.cleanupComponent(componentId);
|
|
207
|
+
}
|
|
208
|
+
this.cleanupGlobal();
|
|
209
|
+
}
|
|
210
|
+
getStats() {
|
|
211
|
+
const resourceCounts = {};
|
|
212
|
+
for (const resources of this.resources.values()) {
|
|
213
|
+
resources.forEach(resource => {
|
|
214
|
+
resourceCounts[resource.type] = (resourceCounts[resource.type] || 0) + 1;
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
componentCount: this.resources.size,
|
|
219
|
+
resourceCounts,
|
|
220
|
+
globalResourceCount: this.globalResources.size
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
exports.ResourceManager = ResourceManager;
|
|
225
|
+
exports.resourceManager = new ResourceManager();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/react-runtime",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.78.0",
|
|
4
4
|
"description": "Platform-agnostic React component runtime for MemberJunction. Provides core compilation, registry, and execution capabilities for React components in any JavaScript environment.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://github.com/MemberJunction/MJ#readme",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@memberjunction/core": "2.
|
|
29
|
-
"@memberjunction/global": "2.
|
|
30
|
-
"@memberjunction/interactive-component-types": "2.
|
|
28
|
+
"@memberjunction/core": "2.78.0",
|
|
29
|
+
"@memberjunction/global": "2.78.0",
|
|
30
|
+
"@memberjunction/interactive-component-types": "2.78.0",
|
|
31
31
|
"@babel/standalone": "^7.23.5",
|
|
32
32
|
"rxjs": "^7.8.1"
|
|
33
33
|
},
|
package/src/index.ts
CHANGED
|
@@ -74,6 +74,12 @@ export {
|
|
|
74
74
|
HierarchyRegistrationOptions
|
|
75
75
|
} from './runtime';
|
|
76
76
|
|
|
77
|
+
export {
|
|
78
|
+
ReactRootManager,
|
|
79
|
+
reactRootManager,
|
|
80
|
+
ManagedReactRoot
|
|
81
|
+
} from './runtime';
|
|
82
|
+
|
|
77
83
|
// Export utilities
|
|
78
84
|
export {
|
|
79
85
|
RuntimeUtilities,
|
|
@@ -102,6 +108,18 @@ export {
|
|
|
102
108
|
FailedComponentInfo
|
|
103
109
|
} from './utilities/component-error-analyzer';
|
|
104
110
|
|
|
111
|
+
export {
|
|
112
|
+
ResourceManager,
|
|
113
|
+
resourceManager,
|
|
114
|
+
ManagedResource
|
|
115
|
+
} from './utilities/resource-manager';
|
|
116
|
+
|
|
117
|
+
export {
|
|
118
|
+
CacheManager,
|
|
119
|
+
CacheEntry,
|
|
120
|
+
CacheOptions
|
|
121
|
+
} from './utilities/cache-manager';
|
|
122
|
+
|
|
105
123
|
// Version information
|
|
106
124
|
export const VERSION = '2.69.1';
|
|
107
125
|
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
ComponentMetadata,
|
|
10
10
|
RegistryConfig
|
|
11
11
|
} from '../types';
|
|
12
|
+
import { resourceManager } from '../utilities/resource-manager';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Default registry configuration
|
|
@@ -28,6 +29,7 @@ export class ComponentRegistry {
|
|
|
28
29
|
private registry: Map<string, RegistryEntry>;
|
|
29
30
|
private config: RegistryConfig;
|
|
30
31
|
private cleanupTimer?: NodeJS.Timeout | number;
|
|
32
|
+
private registryId: string;
|
|
31
33
|
|
|
32
34
|
/**
|
|
33
35
|
* Creates a new ComponentRegistry instance
|
|
@@ -36,6 +38,7 @@ export class ComponentRegistry {
|
|
|
36
38
|
constructor(config?: Partial<RegistryConfig>) {
|
|
37
39
|
this.config = { ...DEFAULT_REGISTRY_CONFIG, ...config };
|
|
38
40
|
this.registry = new Map();
|
|
41
|
+
this.registryId = `component-registry-${Date.now()}`;
|
|
39
42
|
|
|
40
43
|
// Start cleanup timer if configured
|
|
41
44
|
if (this.config.cleanupInterval > 0) {
|
|
@@ -297,6 +300,8 @@ export class ComponentRegistry {
|
|
|
297
300
|
destroy(): void {
|
|
298
301
|
this.stopCleanupTimer();
|
|
299
302
|
this.clear();
|
|
303
|
+
// Clean up any resources associated with this registry
|
|
304
|
+
resourceManager.cleanupComponent(this.registryId);
|
|
300
305
|
}
|
|
301
306
|
|
|
302
307
|
/**
|
|
@@ -362,9 +367,14 @@ export class ComponentRegistry {
|
|
|
362
367
|
* Starts the automatic cleanup timer
|
|
363
368
|
*/
|
|
364
369
|
private startCleanupTimer(): void {
|
|
365
|
-
this.cleanupTimer = setInterval(
|
|
366
|
-
this.
|
|
367
|
-
|
|
370
|
+
this.cleanupTimer = resourceManager.setInterval(
|
|
371
|
+
this.registryId,
|
|
372
|
+
() => {
|
|
373
|
+
this.cleanup();
|
|
374
|
+
},
|
|
375
|
+
this.config.cleanupInterval,
|
|
376
|
+
{ purpose: 'component-registry-cleanup' }
|
|
377
|
+
);
|
|
368
378
|
}
|
|
369
379
|
|
|
370
380
|
/**
|
|
@@ -372,7 +382,7 @@ export class ComponentRegistry {
|
|
|
372
382
|
*/
|
|
373
383
|
private stopCleanupTimer(): void {
|
|
374
384
|
if (this.cleanupTimer) {
|
|
375
|
-
clearInterval(this.cleanupTimer as
|
|
385
|
+
resourceManager.clearInterval(this.registryId, this.cleanupTimer as number);
|
|
376
386
|
this.cleanupTimer = undefined;
|
|
377
387
|
}
|
|
378
388
|
}
|
package/src/runtime/index.ts
CHANGED
|
@@ -42,4 +42,10 @@ export {
|
|
|
42
42
|
HierarchyRegistrationResult,
|
|
43
43
|
ComponentRegistrationError,
|
|
44
44
|
HierarchyRegistrationOptions
|
|
45
|
-
} from './component-hierarchy';
|
|
45
|
+
} from './component-hierarchy';
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
ReactRootManager,
|
|
49
|
+
reactRootManager,
|
|
50
|
+
ManagedReactRoot
|
|
51
|
+
} from './react-root-manager';
|