import { b as ScriptNetworkEvents } from './unhead.yem5I2v_.mjs'; function createNoopedRecordingProxy(instance = {}) { const stack = []; let stackIdx = -1; const handler = (reuseStack = false) => ({ get(_, prop, receiver) { if (!reuseStack) { const v = Reflect.get(_, prop, receiver); if (typeof v !== "undefined") { return v; } stackIdx++; stack[stackIdx] = []; } stack[stackIdx].push({ type: "get", key: prop }); return new Proxy(() => { }, handler(true)); }, apply(_, __, args) { stack[stackIdx].push({ type: "apply", key: "", args }); return void 0; } }); return { proxy: new Proxy(instance || {}, handler()), stack }; } function createForwardingProxy(target) { const handler = { get(_, prop, receiver) { const v = Reflect.get(_, prop, receiver); if (typeof v === "object") { return new Proxy(v, handler); } return v; }, apply(_, __, args) { Reflect.apply(_, __, args); return void 0; } }; return new Proxy(target, handler); } function replayProxyRecordings(target, stack) { stack.forEach((recordings) => { let context = target; let prevContext = target; recordings.forEach(({ type, key, args }) => { if (type === "get") { prevContext = context; context = context[key]; } else if (type === "apply") { context = context.call(prevContext, ...args); } }); }); } function resolveScriptKey(input) { return input.key || input.src || (typeof input.innerHTML === "string" ? input.innerHTML : ""); } const PreconnectServerModes = ["preconnect", "dns-prefetch"]; function useScript(head, _input, _options) { const input = typeof _input === "string" ? { src: _input } : _input; const options = _options || {}; const id = resolveScriptKey(input); const prevScript = head._scripts?.[id]; if (prevScript) { prevScript.setupTriggerHandler(options.trigger); return prevScript; } options.beforeInit?.(); const syncStatus = (s) => { script.status = s; head.hooks.callHook(`script:updated`, hookCtx); }; ScriptNetworkEvents.forEach((fn) => { const k = fn; const _fn = typeof input[k] === "function" ? input[k].bind(options.eventContext) : null; input[k] = (e) => { syncStatus(fn === "onload" ? "loaded" : fn === "onerror" ? "error" : "loading"); _fn?.(e); }; }); const _cbs = { loaded: [], error: [] }; const _uniqueCbs = /* @__PURE__ */ new Set(); const _registerCb = (key, cb, options2) => { if (head.ssr) { return; } if (options2?.key) { const key2 = `${options2?.key}:${options2.key}`; if (_uniqueCbs.has(key2)) { return; } _uniqueCbs.add(key2); } if (_cbs[key]) { const i = _cbs[key].push(cb); return () => _cbs[key]?.splice(i - 1, 1); } cb(script.instance); return () => { }; }; const loadPromise = new Promise((resolve) => { if (head.ssr) return; const emit = (api) => requestAnimationFrame(() => resolve(api)); const _ = head.hooks.hook("script:updated", ({ script: script2 }) => { const status = script2.status; if (script2.id === id && (status === "loaded" || status === "error")) { if (status === "loaded") { if (typeof options.use === "function") { const api = options.use(); if (api) { emit(api); } } else { emit({}); } } else if (status === "error") { resolve(false); } _(); } }); }); const script = { _loadPromise: loadPromise, instance: !head.ssr && options?.use?.() || null, proxy: null, id, status: "awaitingLoad", remove() { script._triggerAbortController?.abort(); script._triggerPromises = []; script._warmupEl?.dispose(); if (script.entry) { script.entry.dispose(); script.entry = void 0; syncStatus("removed"); delete head._scripts?.[id]; return true; } return false; }, warmup(rel) { const { src } = input; const isCrossOrigin = !src.startsWith("/") || src.startsWith("//"); const isPreconnect = rel && PreconnectServerModes.includes(rel); let href = src; if (!rel || isPreconnect && !isCrossOrigin) { return; } if (isPreconnect) { const $url = new URL(src); href = `${$url.protocol}//${$url.host}`; } const link = { href, rel, crossorigin: typeof input.crossorigin !== "undefined" ? input.crossorigin : isCrossOrigin ? "anonymous" : void 0, referrerpolicy: typeof input.referrerpolicy !== "undefined" ? input.referrerpolicy : isCrossOrigin ? "no-referrer" : void 0, fetchpriority: typeof input.fetchpriority !== "undefined" ? input.fetchpriority : "low", integrity: input.integrity, as: rel === "preload" ? "script" : void 0 }; script._warmupEl = head.push({ link: [link] }, { head, tagPriority: "high" }); return script._warmupEl; }, load(cb) { script._triggerAbortController?.abort(); script._triggerPromises = []; if (!script.entry) { syncStatus("loading"); const defaults = { defer: true, fetchpriority: "low" }; if (input.src && (input.src.startsWith("http") || input.src.startsWith("//"))) { defaults.crossorigin = "anonymous"; defaults.referrerpolicy = "no-referrer"; } script.entry = head.push({ script: [{ ...defaults, ...input }] }, options); } if (cb) _registerCb("loaded", cb); return loadPromise; }, onLoaded(cb, options2) { return _registerCb("loaded", cb, options2); }, onError(cb, options2) { return _registerCb("error", cb, options2); }, setupTriggerHandler(trigger) { if (script.status !== "awaitingLoad") { return; } if ((typeof trigger === "undefined" || trigger === "client") && !head.ssr || trigger === "server") { script.load(); } else if (trigger instanceof Promise) { if (head.ssr) { return; } if (!script._triggerAbortController) { script._triggerAbortController = new AbortController(); script._triggerAbortPromise = new Promise((resolve) => { script._triggerAbortController.signal.addEventListener("abort", () => { script._triggerAbortController = null; resolve(); }); }); } script._triggerPromises = script._triggerPromises || []; const idx = script._triggerPromises.push(Promise.race([ trigger.then((v) => typeof v === "undefined" || v ? script.load : void 0), script._triggerAbortPromise ]).catch(() => { }).then((res) => { res?.(); }).finally(() => { script._triggerPromises?.splice(idx, 1); })); } else if (typeof trigger === "function") { trigger(script.load); } }, _cbs }; loadPromise.then((api) => { if (api !== false) { script.instance = api; _cbs.loaded?.forEach((cb) => cb(api)); _cbs.loaded = null; } else { _cbs.error?.forEach((cb) => cb()); _cbs.error = null; } }); const hookCtx = { script }; script.setupTriggerHandler(options.trigger); if (options.use) { const { proxy, stack } = createNoopedRecordingProxy(head.ssr ? {} : options.use() || {}); script.proxy = proxy; script.onLoaded((instance) => { replayProxyRecordings(instance, stack); script.proxy = createForwardingProxy(instance); }); } if (!options.warmupStrategy && (typeof options.trigger === "undefined" || options.trigger === "client")) { options.warmupStrategy = "preload"; } if (options.warmupStrategy) { script.warmup(options.warmupStrategy); } head._scripts = Object.assign(head._scripts || {}, { [id]: script }); return script; } export { resolveScriptKey as r, useScript as u };