mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-27 08:32:56 +00:00
120 lines
4.8 KiB
JavaScript
120 lines
4.8 KiB
JavaScript
//#region src/node.ts
|
|
const sdkImportCache = /* @__PURE__ */ new Map();
|
|
function importNodeModule(name) {
|
|
if (!name) throw new Error("import specifier is required");
|
|
if (sdkImportCache.has(name)) return sdkImportCache.get(name);
|
|
const promise = new Function("name", `return import(name)`)(name).then((res) => res).catch((error) => {
|
|
console.error(`Error importing module ${name}:`, error);
|
|
sdkImportCache.delete(name);
|
|
throw error;
|
|
});
|
|
sdkImportCache.set(name, promise);
|
|
return promise;
|
|
}
|
|
const loadNodeFetch = async () => {
|
|
const fetchModule = await importNodeModule("node-fetch");
|
|
return fetchModule.default || fetchModule;
|
|
};
|
|
const lazyLoaderHookFetch = async (input, init, loaderHook) => {
|
|
const hook = (url, init) => {
|
|
return loaderHook.lifecycle.fetch.emit(url, init);
|
|
};
|
|
const res = await hook(input, init || {});
|
|
if (!res || !(res instanceof Response)) return (typeof fetch === "undefined" ? await loadNodeFetch() : fetch)(input, init || {});
|
|
return res;
|
|
};
|
|
const createScriptNode = typeof ENV_TARGET === "undefined" || ENV_TARGET !== "web" ? (url, cb, attrs, loaderHook) => {
|
|
if (loaderHook?.createScriptHook) {
|
|
const hookResult = loaderHook.createScriptHook(url);
|
|
if (hookResult && typeof hookResult === "object" && "url" in hookResult) url = hookResult.url;
|
|
}
|
|
let urlObj;
|
|
try {
|
|
urlObj = new URL(url);
|
|
} catch (e) {
|
|
console.error("Error constructing URL:", e);
|
|
cb(/* @__PURE__ */ new Error(`Invalid URL: ${e}`));
|
|
return;
|
|
}
|
|
const getFetch = async () => {
|
|
if (loaderHook?.fetch) return (input, init) => lazyLoaderHookFetch(input, init, loaderHook);
|
|
return typeof fetch === "undefined" ? loadNodeFetch() : fetch;
|
|
};
|
|
const handleScriptFetch = async (f, urlObj) => {
|
|
try {
|
|
const res = await f(urlObj.href);
|
|
const data = await res.text();
|
|
const [path, vm] = await Promise.all([importNodeModule("path"), importNodeModule("vm")]);
|
|
const scriptContext = {
|
|
exports: {},
|
|
module: { exports: {} }
|
|
};
|
|
const urlDirname = urlObj.pathname.split("/").slice(0, -1).join("/");
|
|
const filename = path.basename(urlObj.pathname);
|
|
const script = new vm.Script(`(function(exports, module, require, __dirname, __filename) {${data}\n})`, {
|
|
filename,
|
|
importModuleDynamically: vm.constants?.USE_MAIN_CONTEXT_DEFAULT_LOADER ?? importNodeModule
|
|
});
|
|
let requireFn;
|
|
requireFn = (await importNodeModule("node:module")).createRequire(urlObj.protocol === "file:" || urlObj.protocol === "node:" ? urlObj.href : path.join(process.cwd(), "__mf_require_base__.js"));
|
|
script.runInThisContext()(scriptContext.exports, scriptContext.module, requireFn, urlDirname, filename);
|
|
const exportedInterface = scriptContext.module.exports || scriptContext.exports;
|
|
if (attrs && exportedInterface && attrs["globalName"]) {
|
|
cb(void 0, exportedInterface[attrs["globalName"]] || exportedInterface);
|
|
return;
|
|
}
|
|
cb(void 0, exportedInterface);
|
|
} catch (e) {
|
|
cb(e instanceof Error ? e : /* @__PURE__ */ new Error(`Script execution error: ${e}`));
|
|
}
|
|
};
|
|
getFetch().then(async (f) => {
|
|
if (attrs?.["type"] === "esm" || attrs?.["type"] === "module") return loadModule(urlObj.href, {
|
|
fetch: f,
|
|
vm: await importNodeModule("vm")
|
|
}).then(async (module) => {
|
|
await module.evaluate();
|
|
cb(void 0, module.namespace);
|
|
}).catch((e) => {
|
|
cb(e instanceof Error ? e : /* @__PURE__ */ new Error(`Script execution error: ${e}`));
|
|
});
|
|
handleScriptFetch(f, urlObj);
|
|
}).catch((err) => {
|
|
cb(err);
|
|
});
|
|
} : (url, cb, attrs, loaderHook) => {
|
|
cb(/* @__PURE__ */ new Error("createScriptNode is disabled in non-Node.js environment"));
|
|
};
|
|
const loadScriptNode = typeof ENV_TARGET === "undefined" || ENV_TARGET !== "web" ? (url, info) => {
|
|
return new Promise((resolve, reject) => {
|
|
createScriptNode(url, (error, scriptContext) => {
|
|
if (error) reject(error);
|
|
else {
|
|
const remoteEntryKey = info?.attrs?.["globalName"] || `__FEDERATION_${info?.attrs?.["name"]}:custom__`;
|
|
resolve(globalThis[remoteEntryKey] = scriptContext);
|
|
}
|
|
}, info.attrs, info.loaderHook);
|
|
});
|
|
} : (url, info) => {
|
|
throw new Error("loadScriptNode is disabled in non-Node.js environment");
|
|
};
|
|
const esmModuleCache = /* @__PURE__ */ new Map();
|
|
async function loadModule(url, options) {
|
|
if (esmModuleCache.has(url)) return esmModuleCache.get(url);
|
|
const { fetch, vm } = options;
|
|
const code = await (await fetch(url)).text();
|
|
const module = new vm.SourceTextModule(code, { importModuleDynamically: async (specifier, script) => {
|
|
const resolvedUrl = new URL(specifier, url).href;
|
|
return loadModule(resolvedUrl, options);
|
|
} });
|
|
esmModuleCache.set(url, module);
|
|
await module.link(async (specifier) => {
|
|
const resolvedUrl = new URL(specifier, url).href;
|
|
return await loadModule(resolvedUrl, options);
|
|
});
|
|
return module;
|
|
}
|
|
|
|
//#endregion
|
|
export { createScriptNode, loadScriptNode };
|
|
//# sourceMappingURL=node.js.map
|