135 lines
3.9 KiB
JavaScript
135 lines
3.9 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { existsSync, promises as fs } from "node:fs";
|
|
import url from "node:url";
|
|
import spawn from "nano-spawn";
|
|
import { outdent } from "outdent";
|
|
import packageJson from "../../../package.json" with { type: "json" };
|
|
|
|
const TEMPORARY_DIRECTORY = new URL("../../../.tmp/", import.meta.url);
|
|
const DIRECTORY_NAME = "prettier-oxc-wasm-parser";
|
|
const PACKAGE_NAME = "@oxc-parser/binding-wasm32-wasi";
|
|
|
|
const runYarn = (command, options) =>
|
|
spawn("yarn", command.split(" "), options);
|
|
|
|
async function install(version) {
|
|
const directory = new URL(`./working.${Date.now()}/`, TEMPORARY_DIRECTORY);
|
|
|
|
await fs.rm(directory, { force: true, recursive: true });
|
|
await fs.mkdir(directory, { recursive: true });
|
|
await runYarn("init", { cwd: directory });
|
|
await fs.writeFile(new URL("./yarn.lock", directory), "");
|
|
await fs.writeFile(new URL(".yarnrc.yml", directory), "");
|
|
await runYarn("config set supportedArchitectures.cpu wasm32", {
|
|
cwd: directory,
|
|
});
|
|
|
|
await runYarn(`add ${PACKAGE_NAME}@${version}`, { cwd: directory });
|
|
|
|
assert.ok(existsSync(new URL(`./node_modules/${PACKAGE_NAME}/`, directory)));
|
|
|
|
const { version: installedVersion } = JSON.parse(
|
|
await fs.readFile(
|
|
new URL(`./node_modules/${PACKAGE_NAME}/package.json`, directory),
|
|
),
|
|
);
|
|
|
|
assert.equal(installedVersion, version);
|
|
|
|
return directory;
|
|
}
|
|
|
|
const wasmUrlPattern =
|
|
/const __wasmUrl = new URL\("(?<wasmUrl>.\/[a-z0-9.-]+\.wasm)", import\.meta\.url\)\.href;/;
|
|
async function buildEntry(directory) {
|
|
const packageDirectory = new URL(
|
|
"./node_modules/@oxc-parser/binding-wasm32-wasi/",
|
|
directory,
|
|
);
|
|
const entryFile = new URL("./browser-bundle.js", packageDirectory);
|
|
let text = await fs.readFile(entryFile, "utf8");
|
|
|
|
// Remove useless `visitorKeys`
|
|
const moduleStartMark = "\n//#region src-js/generated/visit/keys.js\n";
|
|
const moduleEndMark = "\n//#endregion\n";
|
|
const moduleStart = text.indexOf(moduleStartMark);
|
|
if (moduleStart === -1) {
|
|
throw new Error("Unexpected source");
|
|
}
|
|
const moduleEnd = text.indexOf(
|
|
moduleEndMark,
|
|
moduleStart + moduleStartMark.length,
|
|
);
|
|
if (moduleEnd === -1) {
|
|
throw new Error("Unexpected source");
|
|
}
|
|
|
|
text = outdent`
|
|
${text.slice(0, moduleStart + moduleStartMark.length)}
|
|
var keys_default;
|
|
${text.slice(moduleEnd)}
|
|
`;
|
|
|
|
const { wasmUrl } = text.match(wasmUrlPattern).groups;
|
|
const wasmFile = new URL(wasmUrl, entryFile);
|
|
|
|
const wasmBase64String = await fs.readFile(wasmFile, "base64");
|
|
|
|
text = outdent`
|
|
import { decode as __decode } from "base64-arraybuffer-es6";
|
|
|
|
const __base64ToArrayBuffer = Uint8Array.fromBase64
|
|
? (string) => Uint8Array.fromBase64(string).buffer
|
|
: __decode;
|
|
|
|
${text}
|
|
`;
|
|
|
|
text = text.replace(wasmUrlPattern, "");
|
|
text = text.replace(
|
|
"const __wasmResponse = await globalThis.fetch(__wasmUrl);",
|
|
"const __wasmResponse = {ok: true};",
|
|
);
|
|
text = text.replace(
|
|
"await __wasmResponse.arrayBuffer();",
|
|
outdent`
|
|
__base64ToArrayBuffer(
|
|
/* "${wasmUrl}" */ ${JSON.stringify(wasmBase64String)}
|
|
)
|
|
`,
|
|
);
|
|
|
|
text = text.replace("await __rollbackWasiInitialization()", "[]");
|
|
|
|
text = text.replace(
|
|
"await instantiateNapiModule(",
|
|
"instantiateNapiModuleSync(",
|
|
);
|
|
|
|
text = text.replaceAll(
|
|
/new URL\((?<url>".*?"), import\.meta\.url\)/g,
|
|
"{/* $<url> */}",
|
|
);
|
|
|
|
return { entry: url.fileURLToPath(entryFile), text, directory };
|
|
}
|
|
|
|
async function buildOxcWasmParser() {
|
|
const version = packageJson.dependencies["oxc-parser"];
|
|
const directory = new URL(
|
|
`./${DIRECTORY_NAME}@${version}/`,
|
|
TEMPORARY_DIRECTORY,
|
|
);
|
|
|
|
if (!existsSync(directory)) {
|
|
await fs.rm(directory, { recursive: true, force: true });
|
|
|
|
const installDirectory = await install(version);
|
|
await fs.rename(installDirectory, directory);
|
|
}
|
|
|
|
return await buildEntry(directory);
|
|
}
|
|
|
|
export default buildOxcWasmParser;
|