@memberjunction/react-runtime
Version:
Platform-agnostic React component runtime for MemberJunction. Provides core compilation, registry, and execution capabilities for React components in any JavaScript environment.
226 lines • 8.01 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.resourceManager = exports.ResourceManager = void 0;
const getTimerFunctions = () => {
if (typeof window !== 'undefined' && window.setTimeout) {
return {
setTimeout: window.setTimeout.bind(window),
clearTimeout: window.clearTimeout.bind(window),
setInterval: window.setInterval.bind(window),
clearInterval: window.clearInterval.bind(window),
requestAnimationFrame: window.requestAnimationFrame?.bind(window),
cancelAnimationFrame: window.cancelAnimationFrame?.bind(window)
};
}
else if (typeof global !== 'undefined' && global.setTimeout) {
return {
setTimeout: global.setTimeout,
clearTimeout: global.clearTimeout,
setInterval: global.setInterval,
clearInterval: global.clearInterval,
requestAnimationFrame: undefined,
cancelAnimationFrame: undefined
};
}
else {
const noop = () => { };
const noopWithReturn = () => 0;
return {
setTimeout: noopWithReturn,
clearTimeout: noop,
setInterval: noopWithReturn,
clearInterval: noop,
requestAnimationFrame: undefined,
cancelAnimationFrame: undefined
};
}
};
const timers = getTimerFunctions();
class ResourceManager {
constructor() {
this.resources = new Map();
this.globalResources = new Set();
this.cleanupCallbacks = new Map();
}
setTimeout(componentId, callback, delay, metadata) {
const id = timers.setTimeout(() => {
this.removeResource(componentId, 'timer', id);
callback();
}, delay);
this.addResource(componentId, {
type: 'timer',
id,
cleanup: () => timers.clearTimeout(id),
metadata
});
return id;
}
setInterval(componentId, callback, delay, metadata) {
const id = timers.setInterval(callback, delay);
this.addResource(componentId, {
type: 'interval',
id,
cleanup: () => timers.clearInterval(id),
metadata
});
return id;
}
requestAnimationFrame(componentId, callback, metadata) {
if (!timers.requestAnimationFrame) {
return this.setTimeout(componentId, () => callback(Date.now()), 16, metadata);
}
const id = timers.requestAnimationFrame((time) => {
this.removeResource(componentId, 'animationFrame', id);
callback(time);
});
this.addResource(componentId, {
type: 'animationFrame',
id,
cleanup: () => timers.cancelAnimationFrame?.(id),
metadata
});
return id;
}
clearTimeout(componentId, id) {
timers.clearTimeout(id);
this.removeResource(componentId, 'timer', id);
}
clearInterval(componentId, id) {
timers.clearInterval(id);
this.removeResource(componentId, 'interval', id);
}
cancelAnimationFrame(componentId, id) {
if (timers.cancelAnimationFrame) {
timers.cancelAnimationFrame(id);
}
else {
timers.clearTimeout(id);
}
this.removeResource(componentId, 'animationFrame', id);
}
addEventListener(componentId, target, type, listener, options) {
if (target && typeof target.addEventListener === 'function') {
target.addEventListener(type, listener, options);
const resourceId = `${type}-${Date.now()}-${Math.random()}`;
this.addResource(componentId, {
type: 'eventListener',
id: resourceId,
cleanup: () => {
if (target && typeof target.removeEventListener === 'function') {
target.removeEventListener(type, listener, options);
}
},
metadata: { target, type, options }
});
}
}
registerDOMElement(componentId, element, cleanup) {
if (typeof document !== 'undefined' && element && element.parentNode) {
const resourceId = `dom-${Date.now()}-${Math.random()}`;
this.addResource(componentId, {
type: 'domElement',
id: resourceId,
cleanup: () => {
if (cleanup) {
cleanup();
}
if (element && element.parentNode && typeof element.parentNode.removeChild === 'function') {
element.parentNode.removeChild(element);
}
},
metadata: { element }
});
}
}
registerReactRoot(componentId, root, unmountFn) {
this.addResource(componentId, {
type: 'reactRoot',
id: `react-root-${componentId}`,
cleanup: unmountFn,
metadata: { root }
});
}
registerCleanup(componentId, cleanup) {
if (!this.cleanupCallbacks.has(componentId)) {
this.cleanupCallbacks.set(componentId, []);
}
this.cleanupCallbacks.get(componentId).push(cleanup);
}
registerGlobalResource(resource) {
this.globalResources.add(resource);
}
addResource(componentId, resource) {
if (!this.resources.has(componentId)) {
this.resources.set(componentId, new Set());
}
this.resources.get(componentId).add(resource);
}
removeResource(componentId, type, id) {
const componentResources = this.resources.get(componentId);
if (componentResources) {
const toRemove = Array.from(componentResources).find(r => r.type === type && r.id === id);
if (toRemove) {
componentResources.delete(toRemove);
}
}
}
cleanupComponent(componentId) {
const componentResources = this.resources.get(componentId);
if (componentResources) {
componentResources.forEach(resource => {
try {
resource.cleanup();
}
catch (error) {
console.error(`Error cleaning up ${resource.type} resource:`, error);
}
});
this.resources.delete(componentId);
}
const callbacks = this.cleanupCallbacks.get(componentId);
if (callbacks) {
callbacks.forEach(callback => {
try {
callback();
}
catch (error) {
console.error('Error executing cleanup callback:', error);
}
});
this.cleanupCallbacks.delete(componentId);
}
}
cleanupGlobal() {
this.globalResources.forEach(resource => {
try {
resource.cleanup();
}
catch (error) {
console.error(`Error cleaning up global ${resource.type} resource:`, error);
}
});
this.globalResources.clear();
}
cleanupAll() {
for (const componentId of this.resources.keys()) {
this.cleanupComponent(componentId);
}
this.cleanupGlobal();
}
getStats() {
const resourceCounts = {};
for (const resources of this.resources.values()) {
resources.forEach(resource => {
resourceCounts[resource.type] = (resourceCounts[resource.type] || 0) + 1;
});
}
return {
componentCount: this.resources.size,
resourceCounts,
globalResourceCount: this.globalResources.size
};
}
}
exports.ResourceManager = ResourceManager;
exports.resourceManager = new ResourceManager();
//# sourceMappingURL=resource-manager.js.map