PC-mj/.output/server/node_modules/unhead/dist/shared/unhead.B578PsDV.mjs
2025-03-11 13:57:38 +08:00

267 lines
8.0 KiB
JavaScript

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 };