const require_utils = require('./utils.cjs'); //#region src/dom.ts async function safeWrapper(callback, disableWarn) { try { return await callback(); } catch (e) { !disableWarn && require_utils.warn(e); return; } } function isStaticResourcesEqual(url1, url2) { const REG_EXP = /^(https?:)?\/\//i; return url1.replace(REG_EXP, "").replace(/\/$/, "") === url2.replace(REG_EXP, "").replace(/\/$/, ""); } function createScript(info) { let script = null; let needAttach = true; let timeout = 2e4; let timeoutId; const scripts = document.getElementsByTagName("script"); for (let i = 0; i < scripts.length; i++) { const s = scripts[i]; const scriptSrc = s.getAttribute("src"); if (scriptSrc && isStaticResourcesEqual(scriptSrc, info.url)) { script = s; needAttach = false; break; } } if (!script) { const attrs = info.attrs; script = document.createElement("script"); script.type = attrs?.["type"] === "module" ? "module" : "text/javascript"; let createScriptRes = void 0; if (info.createScriptHook) { createScriptRes = info.createScriptHook(info.url, info.attrs); if (createScriptRes instanceof HTMLScriptElement) script = createScriptRes; else if (typeof createScriptRes === "object") { if ("script" in createScriptRes && createScriptRes.script) script = createScriptRes.script; if ("timeout" in createScriptRes && createScriptRes.timeout) timeout = createScriptRes.timeout; } } if (!script.src) script.src = info.url; if (attrs && !createScriptRes) Object.keys(attrs).forEach((name) => { if (script) { if (name === "async" || name === "defer") script[name] = attrs[name]; else if (!script.getAttribute(name)) script.setAttribute(name, attrs[name]); } }); } let executionError = null; const executionErrorHandler = typeof window !== "undefined" ? (evt) => { if (evt.filename && isStaticResourcesEqual(evt.filename, info.url)) { const err = /* @__PURE__ */ new Error(`ScriptExecutionError: Script "${info.url}" loaded but threw a runtime error during execution: ${evt.message} (${evt.filename}:${evt.lineno}:${evt.colno})`); err.name = "ScriptExecutionError"; executionError = err; } } : null; if (executionErrorHandler) window.addEventListener("error", executionErrorHandler); const onScriptComplete = async (prev, event) => { clearTimeout(timeoutId); if (executionErrorHandler) window.removeEventListener("error", executionErrorHandler); const onScriptCompleteCallback = () => { if (event?.type === "error") { const networkError = /* @__PURE__ */ new Error(event?.isTimeout ? `ScriptNetworkError: Script "${info.url}" timed out.` : `ScriptNetworkError: Failed to load script "${info.url}" - the script URL is unreachable or the server returned an error (network failure, 404, CORS, etc.)`); networkError.name = "ScriptNetworkError"; info?.onErrorCallback && info?.onErrorCallback(networkError); } else if (executionError) info?.onErrorCallback && info?.onErrorCallback(executionError); else info?.cb && info?.cb(); }; if (script) { script.onerror = null; script.onload = null; safeWrapper(() => { const { needDeleteScript = true } = info; if (needDeleteScript) script?.parentNode && script.parentNode.removeChild(script); }); if (prev && typeof prev === "function") { const result = prev(event); if (result instanceof Promise) { const res = await result; onScriptCompleteCallback(); return res; } onScriptCompleteCallback(); return result; } } onScriptCompleteCallback(); }; script.onerror = onScriptComplete.bind(null, script.onerror); script.onload = onScriptComplete.bind(null, script.onload); timeoutId = setTimeout(() => { onScriptComplete(null, { type: "error", isTimeout: true }); }, timeout); return { script, needAttach }; } function createLink(info) { let link = null; let needAttach = true; let timeout = 2e4; let timeoutId; const links = document.getElementsByTagName("link"); for (let i = 0; i < links.length; i++) { const l = links[i]; const linkHref = l.getAttribute("href"); const linkRel = l.getAttribute("rel"); if (linkHref && isStaticResourcesEqual(linkHref, info.url) && linkRel === info.attrs["rel"]) { link = l; needAttach = false; break; } } if (!link) { link = document.createElement("link"); link.setAttribute("href", info.url); let createLinkRes = void 0; let shouldApplyAttrs = true; const attrs = info.attrs; if (info.createLinkHook) { createLinkRes = info.createLinkHook(info.url, attrs); if (createLinkRes instanceof HTMLLinkElement) { link = createLinkRes; shouldApplyAttrs = false; } else if (typeof createLinkRes === "object") { if ("link" in createLinkRes && createLinkRes.link) { link = createLinkRes.link; shouldApplyAttrs = false; } if ("timeout" in createLinkRes && createLinkRes.timeout) timeout = createLinkRes.timeout; } } if (attrs && shouldApplyAttrs) Object.keys(attrs).forEach((name) => { if (link && !link.getAttribute(name)) link.setAttribute(name, attrs[name]); }); } if (!needAttach) { Promise.resolve().then(() => { info?.cb && info?.cb(); }); return { link, needAttach }; } const onLinkComplete = (prev, event) => { if (timeoutId) clearTimeout(timeoutId); const onLinkCompleteCallback = () => { if (event?.type === "error") { const linkError = /* @__PURE__ */ new Error(event?.isTimeout ? `LinkNetworkError: Link "${info.url}" timed out.` : `LinkNetworkError: Failed to load link "${info.url}" - the URL is unreachable or the server returned an error.`); linkError.name = "LinkNetworkError"; info?.onErrorCallback && info?.onErrorCallback(linkError); } else info?.cb && info?.cb(); }; if (link) { link.onerror = null; link.onload = null; safeWrapper(() => { const { needDeleteLink = true } = info; if (needDeleteLink) link?.parentNode && link.parentNode.removeChild(link); }); if (prev) { const res = prev(event); onLinkCompleteCallback(); return res; } } onLinkCompleteCallback(); }; link.onerror = onLinkComplete.bind(null, link.onerror); link.onload = onLinkComplete.bind(null, link.onload); timeoutId = setTimeout(() => { onLinkComplete(null, { type: "error", isTimeout: true }); }, timeout); return { link, needAttach }; } function loadScript(url, info) { const { attrs = {}, createScriptHook } = info; return new Promise((resolve, reject) => { const { script, needAttach } = createScript({ url, cb: resolve, onErrorCallback: reject, attrs: { fetchpriority: "high", ...attrs }, createScriptHook, needDeleteScript: true }); needAttach && document.head.appendChild(script); }); } //#endregion exports.createLink = createLink; exports.createScript = createScript; exports.isStaticResourcesEqual = isStaticResourcesEqual; exports.loadScript = loadScript; exports.safeWrapper = safeWrapper; //# sourceMappingURL=dom.cjs.map