vite-plugin-wat2wasm 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -7
- package/dist/index.d.ts +23 -2
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,10 +18,7 @@ import watVitePlugin from "vite-plugin-wat2wasm";
|
|
|
18
18
|
|
|
19
19
|
export default defineConfig({
|
|
20
20
|
plugins: [
|
|
21
|
-
watVitePlugins(
|
|
22
|
-
{ /* ...wasm features to include */ },
|
|
23
|
-
{ /* ...wasm generation settings */ }
|
|
24
|
-
),
|
|
21
|
+
watVitePlugins({ /* Refer to the API docs below for options */ }),
|
|
25
22
|
/* ...other plugins */
|
|
26
23
|
],
|
|
27
24
|
|
|
@@ -54,8 +51,7 @@ or include it in your `tsconfig.json` file
|
|
|
54
51
|
``` ts
|
|
55
52
|
import initFoo from "./foo.wat"
|
|
56
53
|
|
|
57
|
-
const bar = new WebAssembly.Global("i32");
|
|
58
|
-
|
|
54
|
+
const bar = new WebAssembly.Global("i32", { value: 13 });
|
|
59
55
|
const foo = await initFoo<FooExports, FooImports>({
|
|
60
56
|
bar: { val: bar },
|
|
61
57
|
|
|
@@ -67,7 +63,7 @@ const foo = await initFoo<FooExports, FooImports>({
|
|
|
67
63
|
});
|
|
68
64
|
|
|
69
65
|
console.log(foo.add(21, 46)); // returns 67
|
|
70
|
-
foo.logBar();
|
|
66
|
+
foo.logBar(); // logs 13
|
|
71
67
|
|
|
72
68
|
// In Typescript, you can also specify the types of your .wat file module.
|
|
73
69
|
interface FooExports {
|
|
@@ -80,3 +76,54 @@ interface FooImports {
|
|
|
80
76
|
console: { log(a: number): void; };
|
|
81
77
|
}
|
|
82
78
|
```
|
|
79
|
+
|
|
80
|
+
## Reference
|
|
81
|
+
|
|
82
|
+
This section contains more in-depth details about the `vite-plugin-wat2wasm` library and how to make use of what `vite-plugin-wat2wasm` offers.
|
|
83
|
+
|
|
84
|
+
### `watVitePlugin`
|
|
85
|
+
|
|
86
|
+
Enables compilation of `.wat` files and generation of `.wasm`, with modifiable settings.
|
|
87
|
+
|
|
88
|
+
`watVitePlugin(options:` [`Wat2WasmOptions`](#wat2wasmoptions)`):`[`Plugin`](<https://vite.dev/guide/api-plugin>)
|
|
89
|
+
|
|
90
|
+
#### Parameters
|
|
91
|
+
|
|
92
|
+
- `options:` [`Wat2WasmOptions`](#wat2wasmoptions) `= {}` - the configuration options for `vite-plugin-wat2wasm`.
|
|
93
|
+
|
|
94
|
+
#### Returns
|
|
95
|
+
|
|
96
|
+
- [`Plugin`](https://vite.dev/guide/api-plugin) - a Vite plugin object that allows for compilation of `.wat` files.
|
|
97
|
+
|
|
98
|
+
### `Wat2WasmOptions`
|
|
99
|
+
|
|
100
|
+
The configuration settings for `vite-plugin-wat2wasm`.
|
|
101
|
+
|
|
102
|
+
#### Properties
|
|
103
|
+
|
|
104
|
+
- `emitWasm?: boolean = true` - Determines whether `.wasm` files will be outputted after compiling `.wat` files during build. Useful if you want other bundlers/compilers to take over generation of `.wasm` files.
|
|
105
|
+
|
|
106
|
+
- `target?: "all" |` [`WasmTarget`](#wasmtarget) `| WasmTarget[] = "all"` - Selects the targets that can use the `.wat` modules. "all" means that all targets available in [`WasmTarget`](#wasmtarget) can use said modules.
|
|
107
|
+
|
|
108
|
+
- `parser?:` [`WasmParserOptions`](#wasmparseroptions) `= {}` -
|
|
109
|
+
Configures `.wasm` features you wish to enable for `vite-plugin-wat2wasm`.
|
|
110
|
+
|
|
111
|
+
- `generator?:` [`WasmGeneratorOptions`](#wasmgeneratoroptions) `= {}` - Configures how `vite-plugin-wat2wasm` to generate `.wasm` files.
|
|
112
|
+
|
|
113
|
+
### `WasmTarget`
|
|
114
|
+
|
|
115
|
+
The available targets that is supported by `vite-plugin-wat2wasm`.
|
|
116
|
+
|
|
117
|
+
#### Values
|
|
118
|
+
|
|
119
|
+
`"browser"` - Browsers and runtimes that include DOM libraries can use the bundled `.wat` modules.
|
|
120
|
+
|
|
121
|
+
`"node"` - Node.js and runtimes that include the node library can use the bundled `.wat` modules.
|
|
122
|
+
|
|
123
|
+
### `WasmParserOptions`
|
|
124
|
+
|
|
125
|
+
See [`wabt.WasmFeatures`](https://github.com/AssemblyScript/wabt.js/blob/main/README.md) for more info.
|
|
126
|
+
|
|
127
|
+
### `WasmGeneratorOptions`
|
|
128
|
+
|
|
129
|
+
See [`wabt.ToBinaryOptions`](https://github.com/AssemblyScript/wabt.js/blob/main/README.md) for more info.
|
package/dist/index.d.ts
CHANGED
|
@@ -3,9 +3,30 @@ import { Plugin } from "vite";
|
|
|
3
3
|
|
|
4
4
|
//#region src/index.d.ts
|
|
5
5
|
type WabtParserFunc = Awaited<ReturnType<typeof initWabt>>["parseWat"];
|
|
6
|
+
/** See @see {@link https://github.com/AssemblyScript/wabt.js/blob/main/README.md|`wabt.WasmFeatures`} for more info. @see WasmParserOptions */
|
|
6
7
|
type WasmParserOptions = Parameters<WabtParserFunc>[2];
|
|
8
|
+
/** See @see {@link https://github.com/AssemblyScript/wabt.js/blob/main/README.md|`wabt.ToBinaryOptions`} for more info. @see WasmGeneratorOptions */
|
|
7
9
|
type WasmGeneratorOptions = Parameters<ReturnType<WabtParserFunc>["toBinary"]>[0];
|
|
8
|
-
declare const
|
|
10
|
+
declare const WASM_TARGETS: readonly ["browser", "node"];
|
|
11
|
+
/** The available targets that is supported by `vite-plugin-wat2wasm`. @see WasmTarget */
|
|
12
|
+
type WasmTarget = typeof WASM_TARGETS[number];
|
|
13
|
+
/** The configuration settings for `vite-plugin-wat2wasm`. @see Wat2WasmOptions */
|
|
14
|
+
interface Wat2WasmOptions {
|
|
15
|
+
/** Determines whether `.wasm` files will be outputted after compiling `.wat` files during build. Useful if you want other bundlers/compilers to take over generation of `.wasm` files. @default true */
|
|
16
|
+
emitWasm?: boolean;
|
|
17
|
+
/** Selects the targets that can use the `.wat` modules. "all" means that all targets available in @see {@link WasmTarget|`WasmTarget`} can use said modules. @default "all" */
|
|
18
|
+
target?: "all" | WasmTarget | WasmTarget[];
|
|
19
|
+
/** Configures `.wasm` features you wish to enable for `vite-plugin-wat2wasm`. @default {} @see {@link WasmParserOptions|`WasmParserOptions`} */
|
|
20
|
+
parser?: WasmParserOptions;
|
|
21
|
+
/** Configures how `vite-plugin-wat2wasm` to generate `.wasm` files. @default {} @see {@link WasmGeneratorOptions|`WasmGeneratorOptions`} */
|
|
22
|
+
generator?: WasmGeneratorOptions;
|
|
23
|
+
}
|
|
24
|
+
/** Enables compilation of `.wat` files and generation of `.wasm`, with modifiable settings.
|
|
25
|
+
*
|
|
26
|
+
* @param options - the configuration options for `vite-plugin-wat2wasm`. @see {@link Wat2WasmOptions|`Wat2WasmOptions`}
|
|
27
|
+
* @returns a Vite plugin object that allows for compilation of `.wat` files. @see {@link https://vite.dev/guide/api-plugin|`Plugin`}
|
|
28
|
+
*/
|
|
29
|
+
declare const watCompilerPlugin: (options?: Wat2WasmOptions) => Plugin;
|
|
9
30
|
//#endregion
|
|
10
|
-
export { watCompilerPlugin as default };
|
|
31
|
+
export { type WasmGeneratorOptions, type WasmParserOptions, type WasmTarget, type Wat2WasmOptions, watCompilerPlugin as default };
|
|
11
32
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import e from"fs";import t from"path";import n from"crypto";import r from"wabt";const i=/(^|\s)import\s+([A-Za-z_$][\w$]*)\s+from\s*['"]([^'"\n]*\.wat)['"](\s*;|$)/m,a=/(^|\s)import\s*\*\s*as\s+([A-Za-z_$][\w$]*)\s+from\s*['"]([^'"\n]*\.wat)[;"](\s*;|$)/m,o=/\.([mc]?[jt]sx?)$/i,s=await r();var
|
|
2
|
-
`,`\\n`).replaceAll(`\r`,`\\r`)
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
1
|
+
import e from"fs";import t from"path";import n from"crypto";import r from"wabt";const i=/(^|\s)import\s+([A-Za-z_$][\w$]*)\s+from\s*['"]([^'"\n]*\.wat)['"](\s*;|$)/m,a=/(^|\s)import\s*\*\s*as\s+([A-Za-z_$][\w$]*)\s+from\s*['"]([^'"\n]*\.wat)[;"](\s*;|$)/m,o=/\.([mc]?[jt]sx?)$/i,s=await r(),c=[`browser`,`node`];var l=(r={})=>{let{target:l=`all`,parser:u={},generator:d={}}=r,f=l===`all`?c:typeof l==`string`?[l]:l.length===0?c:l,p=new Map,m=n=>{let r=t.basename(n,`.wat`),i=e.readFileSync(n,{encoding:`utf-8`});return s.parseWat(r,i,u).toBinary(d).buffer},h=async(e,r,i,a,o)=>{for(let s=r.match(a);s!==null;s=r.match(a)){s.index??=0;let a=s[3],c=(await e.resolve(a,i))?.id??null;if(c===null)return r;let l=m(c),u=n.createHash(`sha-256`);u.update(l);let d=u.digest(`base64url`).slice(0,8),f=t.basename(a,`.wat`)+`-`+d,h=t.dirname(a),g=t.posix.join(h,f+`.wasm`);p.has(g)||p.set(g,l);let _=s[2],v=s[1],y=s[4],b=s.index??0,x=b+s[0].length;r=r.slice(0,b)+v+o(g,_)+y+r.slice(x)}return r};return{name:`wat-compiler`,enforce:`post`,async load(e){if((r.emitWasm??(`environment`in this&&this.environment.mode===`build`))||!e.endsWith(`.wat`))return null;let t=m(e);return`const init = async (imports = {}) => WebAssembly.instantiate(new TextEncoder().encode(\`${new TextDecoder(`utf-8`).decode(t).replaceAll(`\\`,`\\\\`).replaceAll("`","\\`").replaceAll(`
|
|
2
|
+
`,`\\n`).replaceAll(`\r`,`\\r`)}\`), imports).then(({ instance: { exports } }) => exports);
|
|
3
|
+
export default init;
|
|
4
|
+
`},async transform(e,t){if(!(r.emitWasm??(`environment`in this&&this.environment.mode===`build`))||!o.test(t))return null;let s=`__`+n.randomBytes(4).toString(`hex`),c=`const ${s} = (path, imports) => {
|
|
5
|
+
`+(f.includes(`node`)?` if (typeof process !== "undefined" && "versions" in process && "node" in process.versions) return WebAssembly.instantiate(require("fs").readFileSync(path), imports);
|
|
6
|
+
`:``)+(f.includes(`browser`)?` if (typeof window !== "undefined" && typeof document !== "undefined") return WebAssembly.instantiateStreaming(fetch(path), imports);
|
|
7
|
+
`:``)+`
|
|
8
|
+
throw new Error("This JavaScript runtime is not supported by this module. If this is a mistake, adjust your target to fit your specific runtime.");
|
|
9
|
+
};
|
|
10
|
+
`,l=e=>`async (imports) => ${s}("${e}", imports).then(({ instance: { exports } }) => exports)`,u=e;return e=await h(this,e,t,i,(e,t)=>`const ${t} = ${l(e)};`),e=await h(this,e,t,a,(e,t)=>`const ${t} = { default: ${l(e)} };`),e!==u&&(e=c+e),e},buildEnd(){for(let[e,t]of p)this.emitFile({type:`asset`,fileName:e,source:t})}}};export{l as default};
|
|
11
11
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["path"],"sources":["../src/index.ts"],"sourcesContent":["import fs from \"fs\";\r\nimport path from \"path\";\r\n\r\nimport crypto from \"crypto\";\r\n\r\nimport type { Plugin } from \"vite\";\r\nimport type { TransformPluginContext } from \"rolldown\";\r\n\r\nimport initWabt from \"wabt\";\r\n\r\nconst IMPORT_DEFAULT_REG = /(^|\\s)import\\s+([A-Za-z_$][\\w$]*)\\s+from\\s*['\"]([^'\"\\n]*\\.wat)['\"](\\s*;|$)/m;\r\nconst IMPORT_STAR_REG = /(^|\\s)import\\s*\\*\\s*as\\s+([A-Za-z_$][\\w$]*)\\s+from\\s*['\"]([^'\"\\n]*\\.wat)[;\"](\\s*;|$)/m;\r\n\r\nconst JS_FILE_EXT_REG = /\\.([mc]?[jt]sx?)$/i;\r\n\r\nconst wabt = await initWabt();\r\n\r\ntype WabtParserFunc = Awaited<ReturnType<typeof initWabt>>[\"parseWat\"];\r\n\r\ntype WasmParserOptions = Parameters<WabtParserFunc>[2];\r\ntype WasmGeneratorOptions = Parameters<ReturnType<WabtParserFunc>[\"toBinary\"]>[0];\r\n\r\nconst watCompilerPlugin = (parserOptions: WasmParserOptions = {}, generatorOptions: WasmGeneratorOptions = {}): Plugin => {\r\n const importedWatFiles = new Map<string, Uint8Array>();\r\n\r\n const compileWat = (watPath: string): Uint8Array => {\r\n const name = path.basename(watPath, \".wat\");\r\n const textBfr = fs.readFileSync(watPath, { encoding: \"utf-8\" });\r\n\r\n const module = wabt.parseWat(name, textBfr, parserOptions);\r\n const bfr = module.toBinary(generatorOptions).buffer;\r\n\r\n return bfr;\r\n };\r\n\r\n const transformImports = async (ctx: TransformPluginContext, code: string, codePath: string, statementReg: RegExp, replacement: (importPath: string, name: string) => string): Promise<string> => {\r\n for (let match = code.match(statementReg); match !== null; match = code.match(statementReg)) {\r\n match.index ??= 0;\r\n\r\n const watRelPath = match[3];\r\n\r\n const watAbsPath = (await ctx.resolve(watRelPath, codePath))?.id ?? null;\r\n if (watAbsPath === null) continue;\r\n\r\n const bfr = compileWat(watAbsPath);\r\n\r\n const hasher = crypto.createHash(\"sha-256\");\r\n hasher.update(bfr);\r\n\r\n const hash = hasher.digest(\"base64url\").slice(0, 8);\r\n\r\n const watName = path.basename(watRelPath, \".wat\") + \"-\" + hash;\r\n const watParent = path.dirname(watRelPath);\r\n\r\n const wasmFilePath = path.posix.join(watParent, watName + \".wasm\");\r\n if (!importedWatFiles.has(wasmFilePath)) importedWatFiles.set(wasmFilePath, bfr);\r\n\r\n const importName = match[2];\r\n\r\n const preSpacing = match[1];\r\n const postSpacing = match[4];\r\n\r\n const statementStart = match.index ?? 0;\r\n const statementEnd = statementStart + match[0].length;\r\n\r\n code = code.slice(0, statementStart) + preSpacing + replacement(wasmFilePath, importName) + postSpacing + code.slice(statementEnd);\r\n }\r\n\r\n return code;\r\n };\r\n\r\n return {\r\n name: \"wat-compiler\",\r\n enforce: \"post\",\r\n\r\n load(id: string) {\r\n if (!id.endsWith(\".wat\")) return null;\r\n\r\n const bfr = compileWat(id);\r\n const str = new TextDecoder(\"utf-8\").decode(bfr).replaceAll(\"`\", \"\\\\`\").replaceAll(\"\\n\", \"\\\\n\").replaceAll(\"\\r\", \"\\\\r\");\r\n\r\n return (\r\n \"let hasInitialized = false;\" + \"\\n\" +\r\n \"\" + \"\\n\" +\r\n \"export default async function init(imports = {}) {\" + \"\\n\" +\r\n ` if (hasInitialized) throw new Error(\"Module at \\\\\"${path.resolve(this.environment.config.base, id)}\\\\\" has already been initialized!\");` + \"\\n\" +\r\n \" hasInitialized = true;\" + \"\\n\" +\r\n \"\" + \"\\n\" +\r\n ` return WebAssembly.instantiate(new TextEncoder().encode(\\`${str}\\`), imports).then(({ instance: { exports } }) => exports);` + \"\\n\" +\r\n \"}\" + \"\\n\"\r\n );\r\n },\r\n\r\n async transform(code: string, id: string) {\r\n if (this.environment.mode !== \"build\" || !JS_FILE_EXT_REG.test(id)) return null;\r\n\r\n code = await transformImports(this as any, code, id, IMPORT_DEFAULT_REG, (path, name) => `const ${name} = async (imports) => WebAssembly.instantiateStreaming(fetch(\"${path}\"), imports).then(({ instance: { exports } }) => exports);`);\r\n code = await transformImports(this as any, code, id, IMPORT_STAR_REG , (path, name) => `const ${name} = { default: async (imports) => WebAssembly.instantiateStreaming(fetch(\"${path}\"), imports).then(({ instance: { exports } }) => exports) };`);\r\n\r\n return code;\r\n },\r\n\r\n generateBundle() {\r\n for (const [distPath, bfr] of importedWatFiles)\r\n this.emitFile({\r\n type: \"asset\",\r\n\r\n fileName: distPath,\r\n source: bfr\r\n });\r\n }\r\n };\r\n};\r\n\r\nexport default watCompilerPlugin;\r\n"],"mappings":"gFAUA,MAAM,EAAqB,8EACrB,EAAqB,wFAErB,EAAkB,qBAElB,EAAO,MAAM,GAAU,CAmG7B,IAAA,GA5F2B,EAAmC,EAAE,CAAE,EAAyC,EAAE,GAAa,CACtH,IAAM,EAAmB,IAAI,IAEvB,EAAc,GAAgC,CAChD,IAAM,EAAO,EAAK,SAAS,EAAS,OAAO,CACrC,EAAU,EAAG,aAAa,EAAS,CAAE,SAAU,QAAS,CAAC,CAK/D,OAHe,EAAK,SAAS,EAAM,EAAS,EAAc,CACvC,SAAS,EAAiB,CAAC,QAK5C,EAAmB,MAAO,EAA6B,EAAc,EAAkB,EAAsB,IAA+E,CAC9L,IAAK,IAAI,EAAQ,EAAK,MAAM,EAAa,CAAE,IAAU,KAAM,EAAQ,EAAK,MAAM,EAAa,CAAE,CACzF,EAAM,QAAU,EAEhB,IAAM,EAAa,EAAM,GAEnB,GAAc,MAAM,EAAI,QAAQ,EAAY,EAAS,GAAG,IAAM,KACpE,GAAI,IAAe,KAAM,SAEzB,IAAM,EAAM,EAAW,EAAW,CAE5B,EAAS,EAAO,WAAW,UAAU,CAC3C,EAAO,OAAO,EAAI,CAElB,IAAM,EAAO,EAAO,OAAO,YAAY,CAAC,MAAM,EAAG,EAAE,CAE7C,EAAY,EAAK,SAAS,EAAY,OAAO,CAAG,IAAM,EACtD,EAAY,EAAK,QAAQ,EAAW,CAEpC,EAAe,EAAK,MAAM,KAAK,EAAW,EAAU,QAAQ,CAC7D,EAAiB,IAAI,EAAa,EAAE,EAAiB,IAAI,EAAc,EAAI,CAEhF,IAAM,EAAa,EAAM,GAEnB,EAAa,EAAM,GACnB,EAAc,EAAM,GAEpB,EAAiB,EAAM,OAAS,EAChC,EAAe,EAAiB,EAAM,GAAG,OAE/C,EAAO,EAAK,MAAM,EAAG,EAAe,CAAG,EAAa,EAAY,EAAc,EAAW,CAAG,EAAc,EAAK,MAAM,EAAa,CAGtI,OAAO,GAGX,MAAO,CACH,KAAM,eACN,QAAS,OAET,KAAK,EAAY,CACb,GAAI,CAAC,EAAG,SAAS,OAAO,CAAE,OAAO,KAEjC,IAAM,EAAM,EAAW,EAAG,CACpB,EAAM,IAAI,YAAY,QAAQ,CAAC,OAAO,EAAI,CAAC,WAAW,IAAK,MAAM,CAAC,WAAW;EAAM,MAAM,CAAC,WAAW,KAAM,MAAM,CAEvH,MACI;;;wDAGyD,EAAK,QAAQ,KAAK,YAAY,OAAO,KAAM,EAAG,CAAC;;;gEAGvC,EAAI;;GAK7E,MAAM,UAAU,EAAc,EAAY,CAMtC,OALI,KAAK,YAAY,OAAS,SAAW,CAAC,EAAgB,KAAK,EAAG,CAAS,MAE3E,EAAO,MAAM,EAAiB,KAAa,EAAM,EAAI,GAAqB,EAAM,IAAS,SAAS,EAAK,gEAAgEA,EAAK,4DAA4D,CACxO,EAAO,MAAM,EAAiB,KAAa,EAAM,EAAI,GAAqB,EAAM,IAAS,SAAS,EAAK,2EAA2EA,EAAK,8DAA8D,CAE9O,IAGX,gBAAiB,CACb,IAAK,GAAM,CAAC,EAAU,KAAQ,EAC1B,KAAK,SAAS,CACV,KAAM,QAEN,SAAU,EACV,OAAQ,EACX,CAAC,EAEb"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["path"],"sources":["../src/index.ts"],"sourcesContent":["import fs from \"fs\";\r\nimport path from \"path\";\r\n\r\nimport crypto from \"crypto\";\r\n\r\nimport type { Plugin } from \"vite\";\r\nimport type { TransformPluginContext } from \"rolldown\";\r\n\r\nimport initWabt from \"wabt\";\r\n\r\nconst IMPORT_DEFAULT_REG = /(^|\\s)import\\s+([A-Za-z_$][\\w$]*)\\s+from\\s*['\"]([^'\"\\n]*\\.wat)['\"](\\s*;|$)/m;\r\nconst IMPORT_STAR_REG = /(^|\\s)import\\s*\\*\\s*as\\s+([A-Za-z_$][\\w$]*)\\s+from\\s*['\"]([^'\"\\n]*\\.wat)[;\"](\\s*;|$)/m;\r\n\r\nconst JS_FILE_EXT_REG = /\\.([mc]?[jt]sx?)$/i;\r\n\r\nconst wabt = await initWabt();\r\n\r\ntype WabtParserFunc = Awaited<ReturnType<typeof initWabt>>[\"parseWat\"];\r\n\r\n/** See @see {@link https://github.com/AssemblyScript/wabt.js/blob/main/README.md|`wabt.WasmFeatures`} for more info. @see WasmParserOptions */\r\ntype WasmParserOptions = Parameters<WabtParserFunc>[2];\r\n\r\n/** See @see {@link https://github.com/AssemblyScript/wabt.js/blob/main/README.md|`wabt.ToBinaryOptions`} for more info. @see WasmGeneratorOptions */\r\ntype WasmGeneratorOptions = Parameters<ReturnType<WabtParserFunc>[\"toBinary\"]>[0];\r\n\r\nconst WASM_TARGETS = [\"browser\", \"node\"] as const;\r\n\r\n/** The available targets that is supported by `vite-plugin-wat2wasm`. @see WasmTarget */\r\ntype WasmTarget = typeof WASM_TARGETS[number];\r\n\r\n/** The configuration settings for `vite-plugin-wat2wasm`. @see Wat2WasmOptions */\r\ninterface Wat2WasmOptions {\r\n /** Determines whether `.wasm` files will be outputted after compiling `.wat` files during build. Useful if you want other bundlers/compilers to take over generation of `.wasm` files. @default true */\r\n emitWasm?: boolean;\r\n\r\n /** Selects the targets that can use the `.wat` modules. \"all\" means that all targets available in @see {@link WasmTarget|`WasmTarget`} can use said modules. @default \"all\" */\r\n target?: \"all\" | WasmTarget | WasmTarget[];\r\n\r\n /** Configures `.wasm` features you wish to enable for `vite-plugin-wat2wasm`. @default {} @see {@link WasmParserOptions|`WasmParserOptions`} */\r\n parser?: WasmParserOptions;\r\n\r\n /** Configures how `vite-plugin-wat2wasm` to generate `.wasm` files. @default {} @see {@link WasmGeneratorOptions|`WasmGeneratorOptions`} */\r\n generator?: WasmGeneratorOptions;\r\n}\r\n\r\n/** Enables compilation of `.wat` files and generation of `.wasm`, with modifiable settings.\r\n *\r\n * @param options - the configuration options for `vite-plugin-wat2wasm`. @see {@link Wat2WasmOptions|`Wat2WasmOptions`}\r\n * @returns a Vite plugin object that allows for compilation of `.wat` files. @see {@link https://vite.dev/guide/api-plugin|`Plugin`}\r\n */\r\nconst watCompilerPlugin = (options: Wat2WasmOptions = {}): Plugin => {\r\n const {\r\n target: optionsTarget = \"all\",\r\n\r\n parser: parserOptions = {},\r\n generator: generatorOptions = {}\r\n } = options;\r\n\r\n const targets =\r\n optionsTarget === \"all\"\r\n ? WASM_TARGETS as unknown as WasmTarget[] :\r\n typeof optionsTarget === \"string\"\r\n ? [optionsTarget] :\r\n optionsTarget.length === 0\r\n ? WASM_TARGETS as unknown as WasmTarget[]\r\n : optionsTarget;\r\n\r\n const importedWatFiles = new Map<string, Uint8Array>();\r\n\r\n const compileWat = (watPath: string): Uint8Array => {\r\n const name = path.basename(watPath, \".wat\");\r\n const textBfr = fs.readFileSync(watPath, { encoding: \"utf-8\" });\r\n\r\n const module = wabt.parseWat(name, textBfr, parserOptions);\r\n const bfr = module.toBinary(generatorOptions).buffer;\r\n\r\n return bfr;\r\n };\r\n\r\n const transformImports = async (ctx: TransformPluginContext, code: string, codePath: string, statementReg: RegExp, replacement: (importPath: string, name: string) => string): Promise<string> => {\r\n for (let match = code.match(statementReg); match !== null; match = code.match(statementReg)) {\r\n match.index ??= 0;\r\n\r\n const watRelPath = match[3];\r\n\r\n const watAbsPath = (await ctx.resolve(watRelPath, codePath))?.id ?? null;\r\n if (watAbsPath === null) return code;\r\n\r\n const bfr = compileWat(watAbsPath);\r\n\r\n const hasher = crypto.createHash(\"sha-256\");\r\n hasher.update(bfr);\r\n\r\n const hash = hasher.digest(\"base64url\").slice(0, 8);\r\n\r\n const watName = path.basename(watRelPath, \".wat\") + \"-\" + hash;\r\n const watParent = path.dirname(watRelPath);\r\n\r\n const wasmFilePath = path.posix.join(watParent, watName + \".wasm\");\r\n if (!importedWatFiles.has(wasmFilePath)) importedWatFiles.set(wasmFilePath, bfr);\r\n\r\n const importName = match[2];\r\n\r\n const preSpacing = match[1];\r\n const postSpacing = match[4];\r\n\r\n const statementStart = match.index ?? 0;\r\n const statementEnd = statementStart + match[0].length;\r\n\r\n code = code.slice(0, statementStart) + preSpacing + replacement(wasmFilePath, importName) + postSpacing + code.slice(statementEnd);\r\n }\r\n\r\n return code;\r\n };\r\n\r\n return {\r\n name: \"wat-compiler\",\r\n enforce: \"post\",\r\n\r\n async load(id: string) {\r\n const emitWasm = options.emitWasm ?? (\"environment\" in this && this.environment.mode === \"build\");\r\n\r\n if (emitWasm || !id.endsWith(\".wat\")) return null;\r\n\r\n const bfr = compileWat(id);\r\n const str = new TextDecoder(\"utf-8\").decode(bfr).replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll(\"`\", \"\\\\`\").replaceAll(\"\\n\", \"\\\\n\").replaceAll(\"\\r\", \"\\\\r\");\r\n\r\n return (\r\n `const init = async (imports = {}) => WebAssembly.instantiate(new TextEncoder().encode(\\`${str}\\`), imports).then(({ instance: { exports } }) => exports);` + \"\\n\" +\r\n \"export default init;\" + \"\\n\"\r\n );\r\n },\r\n\r\n async transform(code: string, id: string) {\r\n const emitWasm = options.emitWasm ?? (\"environment\" in this && this.environment.mode === \"build\");\r\n\r\n if (!emitWasm || !JS_FILE_EXT_REG.test(id)) return null;\r\n\r\n const initWasmFuncName = \"__\" + crypto.randomBytes(4).toString(\"hex\");\r\n const generateInitWasmFunc =\r\n `const ${initWasmFuncName} = (path, imports) => {` + \"\\n\" +\r\n (targets.includes(\"node\") ?\r\n \" if (typeof process !== \\\"undefined\\\" && \\\"versions\\\" in process && \\\"node\\\" in process.versions) return WebAssembly.instantiate(require(\\\"fs\\\").readFileSync(path), imports);\" + \"\\n\" :\r\n \"\") +\r\n (targets.includes(\"browser\") ?\r\n ` if (typeof window !== \"undefined\" && typeof document !== \"undefined\") return WebAssembly.instantiateStreaming(fetch(path), imports);` + \"\\n\" :\r\n \"\") +\r\n \"\" + \"\\n\" +\r\n \" throw new Error(\\\"This JavaScript runtime is not supported by this module. If this is a mistake, adjust your target to fit your specific runtime.\\\");\" + \"\\n\" +\r\n \"};\" + \"\\n\";\r\n\r\n const generateInitModuleFunc = (path: string): string => `async (imports) => ${initWasmFuncName}(\"${path}\", imports).then(({ instance: { exports } }) => exports)`;\r\n\r\n const originalCode = code;\r\n\r\n code = await transformImports(this as any, code, id, IMPORT_DEFAULT_REG, (path, name) => `const ${name} = ${generateInitModuleFunc(path)};`);\r\n code = await transformImports(this as any, code, id, IMPORT_STAR_REG , (path, name) => `const ${name} = { default: ${generateInitModuleFunc(path)} };`);\r\n\r\n if (code !== originalCode) code = generateInitWasmFunc + code;\r\n return code;\r\n },\r\n\r\n buildEnd() {\r\n for (const [distPath, bfr] of importedWatFiles)\r\n this.emitFile({\r\n type: \"asset\",\r\n\r\n fileName: distPath,\r\n source: bfr\r\n });\r\n }\r\n };\r\n};\r\n\r\nexport default watCompilerPlugin;\r\nexport type { Wat2WasmOptions, WasmParserOptions, WasmGeneratorOptions, WasmTarget };\r\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-wat2wasm",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.1.1",
|
|
5
5
|
"description": "Enable .wat compilation and integrate generated WebAssembly modules into your codebase with type support",
|
|
6
6
|
"author": "osoclos",
|
|
7
7
|
"license": "MIT",
|