UNPKG

@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
"use strict"; 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