2024-09-02 23:17:54 +00:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
|
|
|
const path = require('node:path');
|
|
|
|
const os = require('node:os');
|
|
|
|
const { spawn } = require('node:child_process');
|
|
|
|
const { readFile, writeFile, copyFile, rm } = require('node:fs/promises');
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run and wait for command to complete.
|
|
|
|
* @param {string[]} command
|
|
|
|
* @param {SpawnOptionsWithStdioTuple} [opts]
|
|
|
|
* @returns {Promise<void>}
|
|
|
|
*/
|
|
|
|
async function run(command, opts = undefined) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
console.log(`running: ${command.join(' ')}`);
|
|
|
|
const child = spawn(command[0], command.slice(1), {
|
|
|
|
stdio: ['ignore', 'inherit', 'inherit'],
|
|
|
|
...opts,
|
|
|
|
});
|
|
|
|
child.once('error', reject);
|
|
|
|
child.once('close', (code) => {
|
|
|
|
if (code === 0) {
|
|
|
|
resolve();
|
|
|
|
} else {
|
|
|
|
reject(new Error(`process exit with code ${code}`));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {string} filepath
|
|
|
|
* @param {...([Buffer, Buffer])} binaryReplacements
|
|
|
|
*/
|
|
|
|
async function replaceBytes(filepath, ...binaryReplacements) {
|
|
|
|
let content = await readFile(filepath);
|
|
|
|
for (const [search, replace] of binaryReplacements) {
|
|
|
|
let idx = -1;
|
2024-09-07 12:13:39 +00:00
|
|
|
while ((idx = content.indexOf(search, idx + 1)) !== -1) {
|
2024-09-02 23:17:54 +00:00
|
|
|
replace.copy(content, idx, 0, replace.length);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
await writeFile(filepath, content);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {string} filepath
|
|
|
|
* @param {...([RegExp|string, string|(...args: string) => unknown])} replacementRules
|
|
|
|
*/
|
|
|
|
async function replaceFileByRegex(filepath, ...replacementRules) {
|
|
|
|
let content = await readFile(filepath, 'utf-8');
|
|
|
|
for (const [search, replace] of replacementRules) {
|
|
|
|
content = content.replace(search, replace);
|
|
|
|
}
|
|
|
|
await writeFile(filepath, content, 'utf-8');
|
|
|
|
}
|
|
|
|
|
|
|
|
async function main() {
|
|
|
|
const wasmSourceDir = path.join(__dirname, '..', 'um_wasm');
|
|
|
|
const wasmOutDir = path.resolve(__dirname, 'pkg');
|
|
|
|
const wasmDistDir = path.resolve(__dirname, 'dist');
|
|
|
|
await rm(wasmOutDir, { recursive: true, force: true });
|
|
|
|
const wasmRelOutDir = path.relative(wasmSourceDir, wasmOutDir);
|
|
|
|
await run(['wasm-pack', 'build', '--target', 'web', '--out-dir', wasmRelOutDir], {
|
|
|
|
cwd: path.resolve(__dirname, '..', 'um_wasm'),
|
|
|
|
});
|
|
|
|
|
|
|
|
// Remove unneeded files
|
|
|
|
await Promise.all([
|
|
|
|
...['.gitignore', 'package.json', 'README.md'].map((name) => {
|
|
|
|
return rm(path.join(wasmOutDir, name), { force: true });
|
|
|
|
}),
|
|
|
|
rm(wasmDistDir, { recursive: true, force: true }),
|
|
|
|
]);
|
|
|
|
|
|
|
|
const homeDir = os.homedir();
|
|
|
|
const dummyHome = '/h' + homeDir.slice(3).replace(/./g, '_') + '/';
|
|
|
|
|
|
|
|
// Patch some files...
|
|
|
|
await Promise.all([
|
|
|
|
replaceFileByRegex(path.join(wasmOutDir, 'um_wasm.js'), [/export default (__wbg_init);/, 'export { $1 };']),
|
|
|
|
replaceFileByRegex(path.join(wasmOutDir, 'um_wasm.d.ts'), [/export default (function __wbg_init)/, 'export $1']),
|
|
|
|
replaceBytes(path.join(wasmOutDir, 'um_wasm_bg.wasm'), [
|
|
|
|
Buffer.from(homeDir, 'utf-8'),
|
|
|
|
Buffer.from(dummyHome, 'utf-8'),
|
|
|
|
]),
|
|
|
|
copyFile(path.join(__dirname, '../LICENSE_APACHE'), 'LICENSE_APACHE'),
|
|
|
|
copyFile(path.join(__dirname, '../LICENSE_MIT'), 'LICENSE_MIT'),
|
|
|
|
]);
|
|
|
|
|
|
|
|
// Ask rollup to build bundles.
|
|
|
|
await run(['pnpm', 'build:bundle']);
|
2024-09-07 12:13:39 +00:00
|
|
|
await run(['pnpm', 'exec', 'prettier', '--ignore-path', '', '-w', 'dist/loader.d.ts']);
|
2024-09-02 23:17:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
main()
|
|
|
|
.catch((err) => {
|
|
|
|
console.error(err);
|
|
|
|
process.exit(1);
|
|
|
|
})
|
|
|
|
.then(() => {
|
|
|
|
process.exit(0);
|
|
|
|
});
|