|
1 | 1 | import { writeFile } from 'node:fs/promises' |
| 2 | +import fs from 'node:fs' |
2 | 3 | import path from 'path' |
3 | 4 | import { createRequire } from 'node:module' |
4 | 5 | import { base32 } from 'iso-base/rfc4648' |
5 | 6 | import * as esbuild from 'esbuild' |
6 | | -import { deleteAsync } from 'del' |
| 7 | +import { deleteSync } from 'del' |
7 | 8 |
|
8 | 9 | // @ts-ignore |
9 | 10 | import replacePlugin from 'esbuild-plugin-replace-regex' |
@@ -63,42 +64,60 @@ async function bundle(filePath) { |
63 | 64 | /** |
64 | 65 | * Generate wasm component from a TypeScript file |
65 | 66 | * |
66 | | - * @param {string} filePath - Path to a TypeScript file |
67 | | - * @param {string} outDir - Path to a directory to write the Wasm component file |
| 67 | + * @param {import('../types.js').WasmifyOptions} options |
68 | 68 | */ |
69 | | -export async function build(filePath, outDir = process.cwd()) { |
70 | | - const pkgPath = require.resolve('@fission-codes/homestar-wit') |
71 | | - const witPath = path.join(pkgPath, '..', '..', 'wit') |
72 | | - let witHash |
| 69 | +export async function build(options) { |
| 70 | + let { |
| 71 | + entryPoint, |
| 72 | + outDir = process.cwd(), |
| 73 | + debug = false, |
| 74 | + worldName, |
| 75 | + witPath, |
| 76 | + } = options |
| 77 | + |
| 78 | + if (!witPath) { |
| 79 | + const pkgPath = require.resolve('@fission-codes/homestar-wit') |
| 80 | + witPath = path.join(pkgPath, '..', '..', 'wit') |
| 81 | + } |
| 82 | + |
| 83 | + if (!worldName) { |
| 84 | + worldName = path.basename(entryPoint, path.extname(entryPoint)) |
| 85 | + } |
73 | 86 |
|
74 | 87 | // Clean up any old WIT files in the wit directory |
75 | 88 | // componentize process.exit(1) if it fails so we can't clean up after it |
76 | | - await deleteAsync([`${witPath}/*.wit`], { force: true }) |
| 89 | + deleteSync([`${witPath}/*.wit`], { force: true }) |
77 | 90 |
|
| 91 | + let witFile |
78 | 92 | try { |
79 | | - const { hash, src, wasiImports } = await bundle(filePath) |
80 | | - witHash = base32.encode(hash).toLowerCase() |
| 93 | + const { hash, src, wasiImports } = await bundle(entryPoint) |
| 94 | + const witHash = base32.encode(hash).toLowerCase() |
| 95 | + const outPath = path.join(outDir, `${worldName}-${witHash}.wasm`) |
| 96 | + witFile = path.join(witPath, `${worldName}-${witHash}.wit`) |
81 | 97 |
|
82 | | - // TODO: check the wit hash and only componentize if it has changed |
83 | | - const witSource = await wit({ filePath, worldName: witHash, wasiImports }) |
84 | | - const witFile = path.join(witPath, `${witHash}.wit`) |
85 | | - await writeFile(witFile, witSource, 'utf8') |
86 | | - const { component } = await componentize(src, { |
87 | | - witPath, |
88 | | - worldName: witHash, |
89 | | - // debug: true, |
90 | | - sourceName: filePath, |
91 | | - }) |
92 | | - const outPath = path.join(outDir, `${witHash}.wasm`) |
93 | | - await writeFile(outPath, component) |
| 98 | + if (!fs.existsSync(outPath)) { |
| 99 | + const witSource = await wit({ |
| 100 | + entryPoint, |
| 101 | + worldName, |
| 102 | + wasiImports, |
| 103 | + }) |
| 104 | + await writeFile(witFile, witSource, 'utf8') |
| 105 | + const { component } = await componentize(src, { |
| 106 | + witPath, |
| 107 | + worldName, |
| 108 | + debug, |
| 109 | + sourceName: entryPoint, |
| 110 | + }) |
| 111 | + await writeFile(outPath, component) |
| 112 | + } |
94 | 113 |
|
95 | 114 | return { |
96 | 115 | outPath, |
97 | 116 | witHash, |
98 | 117 | } |
99 | 118 | } finally { |
100 | | - if (witHash) { |
101 | | - await deleteAsync([path.join(witPath, `${witHash}.wit`)], { force: true }) |
| 119 | + if (witFile) { |
| 120 | + deleteSync([witFile], { force: true }) |
102 | 121 | } |
103 | 122 | } |
104 | 123 | } |
0 commit comments