diff --git a/crates/wasm/.npmignore b/crates/wasm/.npmignore index d8dcb746e2..2ee1b99cba 100644 --- a/crates/wasm/.npmignore +++ b/crates/wasm/.npmignore @@ -1,6 +1,5 @@ src/ scripts/ -*.ts tsconfig.json .gitignore node_modules/ diff --git a/crates/wasm/init_web.js b/crates/wasm/init_web.js index 7537ceb308..5c191eed87 100644 --- a/crates/wasm/init_web.js +++ b/crates/wasm/init_web.js @@ -4,7 +4,26 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. -import init from "./dist/web/e3_wasm.js"; +import * as bindgen from "./dist/web/e3_wasm.js"; + +let promise; + export default async function initializeWasm(initParams) { - return await init(initParams); + promise ??= (async () => { + const { default: base64 } = await import("./dist/web/e3_wasm_base64.js"); + + const binaryString = atob(base64); + const len = binaryString.length; + const bytes = new Uint8Array(len); + + for (let i = 0; i < len; i++) { + bytes[i] = binaryString.charCodeAt(i); + } + + bindgen.initSync(bytes); + + return bindgen; + })(); + + return promise; } diff --git a/crates/wasm/package.json b/crates/wasm/package.json index b8af9950bc..95cfbe3224 100644 --- a/crates/wasm/package.json +++ b/crates/wasm/package.json @@ -2,12 +2,12 @@ "name": "@enclave-e3/wasm", "version": "0.0.13-test", "description": "Wasm modules for enclave.", - "main": "dist/nodejs/e3_wasm.js", + "main": "dist/node/e3_wasm.js", "module": "dist/web/e3_wasm.js", "types": "dist/web/e3_wasm.d.ts", "files": [ "dist/", - "dist/nodejs/**", + "dist/node/**", "dist/web/**", "init_node.js", "init_node.cjs", @@ -18,15 +18,15 @@ "access": "public" }, "scripts": { - "build": "./scripts/build.sh", + "build": "rm -rf dist && node scripts/build.js", "prerelease": "pnpm build", "release": "pnpm publish --access=public" }, "exports": { ".": { "node": { - "types": "./dist/nodejs/e3_wasm.d.ts", - "default": "./dist/nodejs/e3_wasm.js" + "types": "./dist/node/e3_wasm.d.ts", + "default": "./dist/node/e3_wasm.js" }, "browser": { "types": "./dist/web/e3_wasm.d.ts", @@ -61,5 +61,9 @@ "url": "https://github.com/gnosisguild" }, "license": "LGPL-3.0-only", - "packageManager": "pnpm@10.7.1+sha512.2d92c86b7928dc8284f53494fb4201f983da65f0fb4f0d40baafa5cf628fa31dae3e5968f12466f17df7e97310e30f343a648baea1b9b350685dafafffdf5808" + "packageManager": "pnpm@10.7.1+sha512.2d92c86b7928dc8284f53494fb4201f983da65f0fb4f0d40baafa5cf628fa31dae3e5968f12466f17df7e97310e30f343a648baea1b9b350685dafafffdf5808", + "devDependencies": { + "execa": "^8.0.1", + "replace-in-file": "^7.2.0" + } } diff --git a/crates/wasm/scripts/build.js b/crates/wasm/scripts/build.js new file mode 100644 index 0000000000..276b2e2805 --- /dev/null +++ b/crates/wasm/scripts/build.js @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + +import { execa } from "execa"; +import { readFile, writeFile, rm } from "fs/promises"; +import replaceInFile from "replace-in-file"; + +try { + // Build WASM with web and node target - generates e3_wasm.js and e3_wasm_bg.wasm. + await execa("wasm-pack", [ + "build", + "--target=web", + "--out-dir=dist/web", + "--no-pack", + ]); + await execa("wasm-pack", [ + "build", + "--target=nodejs", + "--out-dir=dist/node", + "--no-pack", + ]); + + // Convert WASM binary to base64 for bundler compatibility. + const wasmBinary = await readFile("./dist/web/e3_wasm_bg.wasm"); + const base64Src = `export default '${wasmBinary.toString("base64")}';\n`; + + // Parallel cleanup and JS modification to prevent Next.js and other bundlers static analysis issues. + await Promise.all([ + await Promise.all([ + rm("./dist/web/e3_wasm_bg.wasm", { force: true }), + rm("./dist/web/e3_wasm_bg.wasm.d.ts", { force: true }), + rm("./dist/web/.gitignore", { force: true }), + rm("./dist/node/.gitignore", { force: true }), + ]), + replaceInFile({ + files: "./dist/web/e3_wasm.js", + from: /module_or_path\s*=\s*new URL\(['"]e3_wasm_bg\.wasm['"],\s*import\.meta\.url\);\s*/g, + to: "/* wasm URL disabled: load via @enclave-e3/wasm/init */\n", + }), + writeFile("./dist/web/e3_wasm_base64.js", base64Src), + ]); +} catch (error) { + console.error(error); + process.exit(1); +} diff --git a/crates/wasm/scripts/build.sh b/crates/wasm/scripts/build.sh deleted file mode 100755 index a1ab3209d1..0000000000 --- a/crates/wasm/scripts/build.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -pnpm wasm-pack build --target web --out-dir dist/web -pnpm wasm-pack build --target nodejs --out-dir dist/nodejs diff --git a/package.json b/package.json index 70c1f7ef07..fa89f3c7bc 100644 --- a/package.json +++ b/package.json @@ -57,8 +57,9 @@ }, "packageManager": "pnpm@10.7.1+sha512.2d92c86b7928dc8284f53494fb4201f983da65f0fb4f0d40baafa5cf628fa31dae3e5968f12466f17df7e97310e30f343a648baea1b9b350685dafafffdf5808", "devDependencies": { - "husky": "^9.1.7", - "@changesets/cli": "^2.27.1" + "@changesets/cli": "^2.27.1", + "@types/node": "22.7.5", + "husky": "^9.1.7" }, "pnpm": { "overrides": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a45297c81f..0a80eb77e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,11 +18,21 @@ importers: '@changesets/cli': specifier: ^2.27.1 version: 2.29.6(@types/node@22.7.5) + '@types/node': + specifier: 22.7.5 + version: 22.7.5 husky: specifier: ^9.1.7 version: 9.1.7 - crates/wasm: {} + crates/wasm: + devDependencies: + execa: + specifier: ^8.0.1 + version: 8.0.1 + replace-in-file: + specifier: ^7.2.0 + version: 7.2.0 docs: dependencies: @@ -8171,6 +8181,11 @@ packages: resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} engines: {node: '>=0.10'} + replace-in-file@7.2.0: + resolution: {integrity: sha512-CiLXVop3o8/h2Kd1PwKPPimmS9wUV0Ki6Fl8+1ITD35nB3Gl/PrW5IONpTE0AXk0z4v8WYcpEpdeZqMXvSnWpg==} + engines: {node: '>=10'} + hasBin: true + req-cwd@2.0.0: resolution: {integrity: sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==} engines: {node: '>=4'} @@ -19780,6 +19795,12 @@ snapshots: repeat-string@1.6.1: {} + replace-in-file@7.2.0: + dependencies: + chalk: 4.1.2 + glob: 8.1.0 + yargs: 17.7.2 + req-cwd@2.0.0: dependencies: req-from: 2.0.0