UNPKG

@jakobcooldown/react-csr-sdk

Version:

Mockery SDK for dynamic bundle loading in web applications

146 lines (145 loc) 5.71 kB
"use strict"; /** * Mockery Bundle Loader * * This script should be included in HTML BEFORE any React bundle scripts. * It checks localStorage for a custom bundle URL and loads it, or falls back to default. * * Usage in HTML: * <script src="mockery-bundle-loader.js"></script> * <script data-mockery-default-bundle src="./assets/index-abc123.js"></script> */ (function () { 'use strict'; const STORAGE_KEY = 'mockery_bundle_url'; const DEBUG_KEY = 'mockery_debug'; function log(message, ...args) { if (localStorage.getItem(DEBUG_KEY) === 'true') { console.log('[Mockery Bundle Loader]', message, ...args); } } function loadScript(src, onLoad, onError) { log('Loading script:', src); const script = document.createElement('script'); script.src = src; script.type = 'module'; script.crossOrigin = 'anonymous'; script.onload = function () { log('Script loaded successfully:', src); onLoad && onLoad(); }; script.onerror = function (error) { log('Script failed to load:', src, error); onError && onError(error); }; document.head.appendChild(script); return script; } function getDefaultBundleUrl() { // Look for script tag with data-mockery-default-bundle attribute const defaultScript = document.querySelector('script[data-mockery-default-bundle]'); if (defaultScript && defaultScript.src) { return defaultScript.src; } // Fallback: look for common bundle patterns const scripts = document.querySelectorAll('script[src]'); for (const script of scripts) { const src = script.src; if (src.includes('index-') || src.includes('main-') || src.includes('app-')) { return src; } } return undefined; } function preventDefaultBundleLoad() { // Prevent default bundle scripts from loading by removing them const defaultScript = document.querySelector('script[data-mockery-default-bundle]'); if (defaultScript) { log('Preventing default bundle load:', defaultScript.src); defaultScript.remove(); } // Also remove any script that might be the default bundle const scripts = document.querySelectorAll('script[src]'); scripts.forEach(script => { const src = script.src; if (src && (src.includes('index-') || src.includes('main-') || src.includes('app-'))) { log('Removing potential default bundle script:', src); script.remove(); } }); } function initializeBundleLoader() { log('Initializing bundle loader'); try { const customBundleUrl = localStorage.getItem(STORAGE_KEY) || undefined; const defaultBundleUrl = getDefaultBundleUrl(); log('Custom bundle URL:', customBundleUrl); log('Default bundle URL:', defaultBundleUrl); if (customBundleUrl) { // Load custom bundle instead of default preventDefaultBundleLoad(); loadScript(customBundleUrl, null, function (error) { log('Custom bundle failed, falling back to default'); if (defaultBundleUrl) { loadScript(defaultBundleUrl); } }); } else { // Let default bundle load normally log('No custom bundle set, using default'); } // Expose global utilities for setting bundle URL window.mockery = window.mockery || {}; window.mockery.setCustomBundle = function (bundleUrl) { const currentBundle = localStorage.getItem(STORAGE_KEY) || undefined; // Exit early if bundle URL is unchanged if (bundleUrl === currentBundle) { return; } log('Setting custom bundle:', bundleUrl); if (bundleUrl) { localStorage.setItem(STORAGE_KEY, bundleUrl); } else { localStorage.removeItem(STORAGE_KEY); } }; window.mockery.getCustomBundle = function () { return localStorage.getItem(STORAGE_KEY) || undefined; }; window.mockery.clearCustomBundle = function () { log('Clearing custom bundle'); localStorage.removeItem(STORAGE_KEY); }; window.mockery.reloadWithBundle = function (bundleUrl) { log('Reloading with bundle:', bundleUrl); if (bundleUrl) { localStorage.setItem(STORAGE_KEY, bundleUrl); } else { localStorage.removeItem(STORAGE_KEY); } window.location.reload(); }; window.mockery.setDebug = function (enabled) { if (enabled) { localStorage.setItem(DEBUG_KEY, 'true'); } else { localStorage.removeItem(DEBUG_KEY); } }; } catch (error) { log('Error during initialization:', error); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initializeBundleLoader); } else { initializeBundleLoader(); } })();