Files
antrean-anjungan/examples/nuxt3-websocket-client/node_modules/unwasm/dist/plugin.cjs
2025-09-18 19:01:22 +07:00

378 lines
10 KiB
JavaScript

'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const node_fs = require('node:fs');
const pathe = require('pathe');
const MagicString = require('magic-string');
const unplugin$1 = require('unplugin');
const node_crypto = require('node:crypto');
const knitwork = require('knitwork');
const tools = require('./tools.cjs');
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
const MagicString__default = /*#__PURE__*/_interopDefaultCompat(MagicString);
const UNWASM_EXTERNAL_PREFIX = "\0unwasm:external:";
const UNWASM_EXTERNAL_RE = /(\0|\\0)unwasm:external:([^"']+)/gu;
const UMWASM_HELPERS_ID = "\0unwasm:helpers";
function sha1(source) {
return node_crypto.createHash("sha1").update(source).digest("hex").slice(0, 16);
}
async function getWasmImports(asset, _opts) {
const importNames = Object.keys(asset.imports || {});
if (importNames.length === 0) {
return {
code: "const _imports = { /* no imports */ }",
resolved: true
};
}
const { readPackageJSON } = await import('pkg-types');
const pkgJSON = await readPackageJSON(asset.id);
let resolved = true;
const imports = [];
const importsObject = {};
for (const moduleName of importNames) {
const importNames2 = asset.imports[moduleName];
const pkgImport = pkgJSON.imports?.[moduleName] || pkgJSON.imports?.[`#${moduleName}`];
const importName = "_imports_" + knitwork.genSafeVariableName(moduleName);
if (pkgImport && typeof pkgImport === "string") {
imports.push(knitwork.genImport(pkgImport, { name: "*", as: importName }));
} else {
resolved = false;
}
importsObject[moduleName] = Object.fromEntries(
importNames2.map((name) => [
name,
pkgImport ? `${importName}[${knitwork.genString(name)}]` : `() => { throw new Error(${knitwork.genString(moduleName + "." + importName)} + " is not provided!")}`
])
);
}
const code = `${imports.join("\n")}
const _imports = ${knitwork.genObjectFromRaw(importsObject)}`;
return {
code,
resolved
};
}
async function getWasmESMBinding(asset, opts) {
const autoImports = await getWasmImports(asset);
const instantiateCode = opts.esmImport ? getESMImportInstantiate(asset, autoImports.code) : getBase64Instantiate(asset, autoImports.code);
return opts.lazy !== true && autoImports.resolved ? getExports(asset, instantiateCode) : getLazyExports(asset, instantiateCode);
}
function getWasmModuleBinding(asset, opts) {
return opts.esmImport ? (
/* js */
`
const _mod = ${opts.lazy === true ? "" : `await`} import("${UNWASM_EXTERNAL_PREFIX}${asset.name}").then(r => r.default || r);
export default _mod;
`
) : (
/* js */
`
import { base64ToUint8Array } from "${UMWASM_HELPERS_ID}";
const _data = base64ToUint8Array("${asset.source.toString("base64")}");
const _mod = new WebAssembly.Module(_data);
export default _mod;
`
);
}
function getESMImportInstantiate(asset, importsCode) {
return (
/* js */
`
${importsCode}
async function _instantiate(imports = _imports) {
const _mod = await import("${UNWASM_EXTERNAL_PREFIX}${asset.name}").then(r => r.default || r);
return WebAssembly.instantiate(_mod, imports)
}
`
);
}
function getBase64Instantiate(asset, importsCode) {
return (
/* js */
`
import { base64ToUint8Array } from "${UMWASM_HELPERS_ID}";
${importsCode}
function _instantiate(imports = _imports) {
const _data = base64ToUint8Array("${asset.source.toString("base64")}")
return WebAssembly.instantiate(_data, imports) }
`
);
}
function getExports(asset, instantiateCode) {
return (
/* js */
`
import { getExports } from "${UMWASM_HELPERS_ID}";
${instantiateCode}
const $exports = getExports(await _instantiate());
${asset.exports.map((name) => `export const ${name} = $exports.${name};`).join("\n")}
const defaultExport = () => $exports;
${asset.exports.map((name) => `defaultExport["${name}"] = $exports.${name};`).join("\n")}
export default defaultExport;
`
);
}
function getLazyExports(asset, instantiateCode) {
return (
/* js */
`
import { createLazyWasmModule } from "${UMWASM_HELPERS_ID}";
${instantiateCode}
const _mod = createLazyWasmModule(_instantiate);
${asset.exports.map((name) => `export const ${name} = _mod.${name};`).join("\n")}
export default _mod;
`
);
}
function getPluginUtils() {
return (
/* js */
`
export function debug(...args) {
console.log('[unwasm] [debug]', ...args);
}
export function getExports(input) {
return input?.instance?.exports || input?.exports || input;
}
export function base64ToUint8Array(str) {
const data = atob(str);
const size = data.length;
const bytes = new Uint8Array(size);
for (let i = 0; i < size; i++) {
bytes[i] = data.charCodeAt(i);
}
return bytes;
}
export function createLazyWasmModule(_instantiator) {
const _exports = Object.create(null);
let _loaded;
let _promise;
const init = (imports) => {
if (_loaded) {
return Promise.resolve(exportsProxy);
}
if (_promise) {
return _promise;
}
return _promise = _instantiator(imports)
.then(r => {
Object.assign(_exports, getExports(r));
_loaded = true;
_promise = undefined;
return exportsProxy;
})
.catch(error => {
_promise = undefined;
console.error('[wasm] [error]', error);
throw error;
});
}
const exportsProxy = new Proxy(_exports, {
get(_, prop) {
if (_loaded) {
return _exports[prop];
}
return (...args) => {
return _loaded
? _exports[prop]?.(...args)
: init().then(() => _exports[prop]?.(...args));
};
},
});
const lazyProxy = new Proxy(() => {}, {
get(_, prop) {
return exportsProxy[prop];
},
apply(_, __, args) {
return init(args[0])
},
});
return lazyProxy;
}
`
);
}
const WASM_ID_RE = /\.wasm\??.*$/i;
const unplugin = unplugin$1.createUnplugin((opts) => {
const assets = /* @__PURE__ */ Object.create(null);
const _parseCache = /* @__PURE__ */ Object.create(null);
function parse(name, source) {
if (_parseCache[name]) {
return _parseCache[name];
}
const imports = /* @__PURE__ */ Object.create(null);
const exports = [];
try {
const parsed = tools.parseWasm(source, { name });
for (const mod of parsed.modules) {
exports.push(...mod.exports.map((e) => e.name));
for (const imp of mod.imports) {
if (!imports[imp.module]) {
imports[imp.module] = [];
}
imports[imp.module].push(imp.name);
}
}
} catch (error) {
console.warn(`[unwasm] Failed to parse WASM module ${name}:`, error);
}
_parseCache[name] = {
imports,
exports
};
return _parseCache[name];
}
return {
name: "unwasm",
rollup: {
async resolveId(id, importer) {
if (id === UMWASM_HELPERS_ID) {
return id;
}
if (id.startsWith(UNWASM_EXTERNAL_PREFIX)) {
return {
id,
external: true
};
}
if (WASM_ID_RE.test(id)) {
const r = await this.resolve(id, importer, { skipSelf: true });
if (r?.id && r.id !== id) {
return {
id: r.id.startsWith("file://") ? r.id.slice(7) : r.id,
external: false,
moduleSideEffects: false
};
}
}
},
generateBundle() {
if (opts.esmImport) {
for (const asset of Object.values(assets)) {
this.emitFile({
type: "asset",
source: asset.source,
fileName: asset.name
});
}
}
}
},
async load(id) {
if (id === UMWASM_HELPERS_ID) {
return getPluginUtils();
}
if (!WASM_ID_RE.test(id)) {
return;
}
const idPath = id.split("?")[0];
if (!node_fs.existsSync(idPath)) {
return;
}
this.addWatchFile(idPath);
const buff = await node_fs.promises.readFile(idPath);
return buff.toString("binary");
},
async transform(code, id) {
if (!WASM_ID_RE.test(id)) {
return;
}
const buff = Buffer.from(code, "binary");
const isModule = id.endsWith("?module");
const name = `wasm/${pathe.basename(id.split("?")[0], ".wasm")}-${sha1(buff)}.wasm`;
const parsed = isModule ? { imports: [], exports: ["default"] } : parse(name, buff);
const asset = assets[name] = {
name,
id,
source: buff,
imports: parsed.imports,
exports: parsed.exports
};
return {
code: isModule ? await getWasmModuleBinding(asset, opts) : await getWasmESMBinding(asset, opts),
map: { mappings: "" }
};
},
renderChunk(code, chunk) {
if (!opts.esmImport) {
return;
}
if (!(chunk.moduleIds.some((id) => WASM_ID_RE.test(id)) || chunk.imports.some((id) => WASM_ID_RE.test(id)))) {
return;
}
const s = new MagicString__default(code);
const resolveImport = (id) => {
if (typeof id !== "string") {
return;
}
const asset = assets[id];
if (!asset) {
return;
}
const nestedLevel = chunk.fileName.split("/").filter(
Boolean
/* handle // */
).length - 1;
const relativeId = (nestedLevel ? "../".repeat(nestedLevel) : "./") + asset.name;
return {
relativeId,
asset
};
};
for (const match of code.matchAll(UNWASM_EXTERNAL_RE)) {
const resolved = resolveImport(match[2]);
const index = match.index;
const len = match[0].length;
if (!resolved || !index) {
console.warn(
`Failed to resolve WASM import: ${JSON.stringify(match[1])}`
);
continue;
}
s.overwrite(index, index + len, resolved.relativeId);
}
if (s.hasChanged()) {
return {
code: s.toString(),
map: s.generateMap({ includeContent: true })
};
}
}
};
});
const rollup = unplugin.rollup;
const index = {
rollup
};
exports.default = index;
exports.rollup = rollup;