Skip to content

fix: wasm init#740

Merged
ctrlc03 merged 14 commits into
mainfrom
fix/wasm-init
Sep 17, 2025
Merged

fix: wasm init#740
ctrlc03 merged 14 commits into
mainfrom
fix/wasm-init

Conversation

@cedoor

@cedoor cedoor commented Sep 17, 2025

Copy link
Copy Markdown
Contributor

Fixes #736

Summary by CodeRabbit

  • New Features

    • Added a unified “init” entry for Node and browsers to simplify WASM initialization.
    • Browser initialization is now lazy and runs only once, improving subsequent load times.
    • TypeScript source files are now included in the published package for better DX.
  • Chores

    • Migrated the WASM package build to a Node-based script and adjusted packaging outputs.
    • Updated package exports to reflect new build outputs and expose the new “init” entry.
    • Added development dependencies, including @types/node, to support the new build flow.

@cedoor cedoor requested a review from ctrlc03 September 17, 2025 13:04
@vercel

vercel Bot commented Sep 17, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
crisp Ready Ready Preview Comment Sep 17, 2025 3:21pm
enclave-docs Ready Ready Preview Comment Sep 17, 2025 3:21pm

@coderabbitai

coderabbitai Bot commented Sep 17, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

The WASM package updates include a new Node.js build script, revised exports and files in package.json, a web initializer that lazily loads and decodes base64 WASM, adjusted npm packaging (including TypeScript sources), and a root devDependency addition. The legacy shell build script is removed/emptied, and node/web dist paths are normalized.

Changes

Cohort / File(s) Summary
Web WASM initialization flow
crates/wasm/init_web.js
Switch to namespace import; add memoized async init that dynamically imports base64 WASM, decodes to bytes, and calls bindgen.initSync(bytes); returns cached module on subsequent calls.
Packaging and exports
crates/wasm/package.json, crates/wasm/.npmignore
Move node output from nodejs→node; update exports (add ./init for node/web, set default web export); add init_web.js and init.d.ts to files; include TypeScript sources by removing *.ts ignore; add devDeps; change build script to JS runner.
Build system migration
crates/wasm/scripts/build.js, crates/wasm/scripts/build.sh
Replace shell build with JS script: runs wasm-pack for web and node; rewrites web JS to avoid URL-based WASM loading; emits base64 module and cleans artifacts; removes content of legacy shell script.
Repo tooling
package.json
Add @types/node devDependency; reorder entries without functional impact.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor App as App (Web)
  participant Init as initializeWasm()
  participant B64 as dist/web/e3_wasm_base64.js
  participant Bindgen as dist/web/e3_wasm.js

  Note over Init,B64: First call only (memoized)
  App->>Init: initializeWasm(initParams)
  alt no cached init
    Init->>B64: dynamic import base64 string
    B64-->>Init: default export (base64)
    Init->>Init: decode base64 -> Uint8Array
    Init->>Bindgen: Bindgen.initSync(bytes)
    Bindgen-->>Init: module ready
    Init-->>App: Promise<Bindgen module>
    Note over Init: Cache resolved promise
  else cached
    Init-->>App: Return cached Promise
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • 0xjei

Poem

I hopped through bytes and base64 streams,
Packed my wasm into sunny beams.
No more chasing URLs at night—
One nibble, decode, and all’s alright.
Dist paths tidy, scripts anew,
Ship the carrots, node and web too. 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning Although the core wasm-init changes are relevant, the PR also includes broader packaging and tooling changes that are outside the narrow scope of issue #736: removal of "*.ts" from crates/wasm/.npmignore (which will include TypeScript sources in the published package), renaming/moving dist/nodejs -> dist/node and corresponding package.json export/main changes, addition of devDependencies (execa, replace-in-file) in crates/wasm/package.json and "@types/node" in the repo root package.json, and deleting the original build.sh in favor of scripts/build.js. These changes affect publish contents, exports mapping, and repo dev-deps and should be reviewed or separated from the runtime fix. Move unrelated packaging and dependency edits into a separate PR or add justification in this PR, revert or explicitly confirm the .npmignore change if unintended, and run a package publish dry-run to verify the final file set before merging.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "fix: wasm init" is concise and directly names the primary intent of the PR—repairing WASM initialization. It aligns with the changes to init_web.js and the build/packaging adjustments aimed at resolving the runtime WASM-loading error described in issue #736. The phrasing is clear and appropriate for a quick scan of repository history.
Linked Issues Check ✅ Passed The PR addresses issue #736 by removing the runtime dependency on resolving e3_wasm_bg.wasm via URL: the build script emits dist/web/e3_wasm_base64.js containing the WASM bytes, init_web.js decodes those bytes and calls bindgen.initSync(bytes), and the build step rewrites the original URL-based reference in dist/web/e3_wasm.js, which together eliminate the incorrect-path fetch that produced HTML instead of the WASM binary. These code-level changes directly target the "expected magic word" error and implement a deterministic initialization path for the browser. I recommend verifying the fix by running the default template app in a browser and performing a package publish dry-run to confirm the published artifacts.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/wasm-init

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@vercel vercel Bot temporarily deployed to Preview – enclave-docs September 17, 2025 13:05 Inactive
@vercel vercel Bot temporarily deployed to Preview – crisp September 17, 2025 13:05 Inactive
@vercel vercel Bot temporarily deployed to Preview – enclave-docs September 17, 2025 13:06 Inactive
@vercel vercel Bot temporarily deployed to Preview – crisp September 17, 2025 13:06 Inactive
@cedoor cedoor changed the title Fix/wasm init fix: wasm init Sep 17, 2025
@theinterfold theinterfold deleted a comment from github-actions Bot Sep 17, 2025
@theinterfold theinterfold deleted a comment from github-actions Bot Sep 17, 2025
@vercel vercel Bot temporarily deployed to Preview – enclave-docs September 17, 2025 13:13 Inactive
@vercel vercel Bot temporarily deployed to Preview – crisp September 17, 2025 13:13 Inactive

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/wasm/package.json (1)

10-16: Packaging vs imports: init_web.js still imports ../srcWasm — fix before publish

crates/wasm/init_web.js imports ../srcWasm/summon_ts_wasm.js and ../srcWasm/summon_ts_wasm_base64.js (lines 7, 14). crates/wasm/package.json ships init_web.js but not srcWasm, so consumers will fail to resolve these imports.
Action: update init_web.js to import the built files from ./dist/web/ (e.g. ./dist/web/summon_ts_wasm*.js) OR add the srcWasm artifacts to package.json "files", then re-run a search to confirm no remaining ../srcWasm references.

🧹 Nitpick comments (5)
crates/wasm/init_web.js (2)

17-23: Micro: simpler/leaner base64 decode

You can avoid the manual loop:

-    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);
-    }
+    const binaryString = atob(base64);
+    const bytes = Uint8Array.from(binaryString, c => c.charCodeAt(0));

11-33: Resilience: reset promise on first-failure

If the first init attempt rejects, subsequent calls will always return the same rejected promise. Consider resetting promise on failure.

-  promise ??= (async () => {
+  promise ??= (async () => {
     ...
-    return bindgen;
-  })();
+    return bindgen;
+  })().catch((e) => {
+    promise = undefined;
+    throw e;
+  });
crates/wasm/scripts/build.js (2)

11-24: Prefer visible build logs

Forward wasm-pack output for easier CI debugging.

-  await execa("wasm-pack", [
+  await execa("wasm-pack", [
     "build",
     "--target=web",
     "--out-dir=dist/web",
     "--no-pack",
-  ]);
-  await execa("wasm-pack", [
+  ], { stdio: "inherit" });
+  await execa("wasm-pack", [
     "build",
     "--target=nodejs",
     "--out-dir=dist/node",
     "--no-pack",
-  ]);
+  ], { stdio: "inherit" });

43-46: Minor: preserve exit code but add context

Consider annotating failures to distinguish wasm-pack vs post-processing steps.

-} catch (error) {
-  console.error(error);
+} catch (error) {
+  console.error("[wasm build] failed:", error);
   process.exit(1);
 }
crates/wasm/package.json (1)

21-23: Keep script as node scripts/build.js only if build.js stays CJS-compatible

Given the proposed change to build.js (dynamic imports in CJS), no package.json changes are required. If you prefer pure ESM, rename to scripts/build.mjs and update this line accordingly.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c0686c6 and a5ff98f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • crates/wasm/.npmignore (0 hunks)
  • crates/wasm/init_web.js (1 hunks)
  • crates/wasm/package.json (3 hunks)
  • crates/wasm/scripts/build.js (1 hunks)
  • crates/wasm/scripts/build.sh (0 hunks)
  • package.json (1 hunks)
💤 Files with no reviewable changes (2)
  • crates/wasm/.npmignore
  • crates/wasm/scripts/build.sh
🧰 Additional context used
🧬 Code graph analysis (1)
crates/wasm/init_web.js (1)
crates/wasm/init_node.js (1)
  • initializeWasm (7-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: test_net
  • GitHub Check: rust_unit
  • GitHub Check: build_enclave_cli
  • GitHub Check: integration_prebuild
  • GitHub Check: Build & Push Image
🔇 Additional comments (3)
package.json (1)

59-61: LGTM: add @types/node at root

Matches the pinned override; no action needed.

crates/wasm/package.json (2)

64-68: Dev deps OK

execa and replace-in-file are appropriate for the new build flow.


26-38: Confirmed — default web loader intentionally disabled; use '@enclave-e3/wasm/init' for browser consumers.

crates/wasm/scripts/build.js replaces the URL-based loader in the web bundle with a throw; crates/wasm/init_web.js is the browser-safe loader. packages/enclave-sdk/src/enclave-sdk.ts already imports '@enclave-e3/wasm/init' and awaits initializeWasm() before calling bfv_* — no change required in this repo.

Comment thread crates/wasm/init_web.js Outdated
Comment thread crates/wasm/scripts/build.js
Comment thread crates/wasm/scripts/build.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (5)
crates/wasm/scripts/build.js (1)

13-24: Build in release mode to reduce base64 size and load time.

Debug builds bloat the base64 payload and slow startup. Use --release for both targets.

-  await execa("wasm-pack", [
+  await execa("wasm-pack", [
     "build",
     "--target=web",
     "--out-dir=dist/web",
     "--no-pack",
+    "--release",
   ]);
@@
-  await execa("wasm-pack", [
+  await execa("wasm-pack", [
     "build",
     "--target=nodejs",
     "--out-dir=dist/node",
     "--no-pack",
+    "--release",
   ]);
crates/wasm/init_web.js (2)

17-23: SSR safety: atob is not available server-side.

Given this file is the browser export, you’re likely fine. If SSR ever touches it, add a small decoder that falls back to Buffer.

-    const binaryString = atob(base64);
+    const binaryString =
+      (typeof atob === "function"
+        ? atob
+        : (b) => Buffer.from(b, "base64").toString("binary"))(base64);

11-11: Unused parameter.

initParams isn’t used anymore; either remove it (if API allows) or mark deprecated in init.d.ts.

crates/wasm/package.json (2)

8-16: If you keep importing bindgen from src files, include them in the package.

Current files list omits srcWasm/**. If any published entry imports from ./srcWasm, add it here. With my init_web.js fix to import from ./dist/web, this is not needed.


6-7: Top-level "types" may mislead Node consumers on older TS.

Older TS versions prefer "types" over conditional exports. Consider removing the top-level "types" or adding typesVersions to steer resolution if you see mis-resolutions.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c0686c6 and ca2e4bd.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • crates/wasm/.npmignore (0 hunks)
  • crates/wasm/init_web.js (1 hunks)
  • crates/wasm/package.json (3 hunks)
  • crates/wasm/scripts/build.js (1 hunks)
  • crates/wasm/scripts/build.sh (0 hunks)
  • package.json (1 hunks)
💤 Files with no reviewable changes (2)
  • crates/wasm/scripts/build.sh
  • crates/wasm/.npmignore
🧰 Additional context used
🧬 Code graph analysis (1)
crates/wasm/init_web.js (1)
crates/wasm/init_node.js (1)
  • initializeWasm (7-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: crisp_e2e
🔇 Additional comments (6)
package.json (1)

59-61: LGTM: dev tooling addition is fine.

Adding @types/node at the root is reasonable given the new Node-based build script in crates/wasm.

crates/wasm/scripts/build.js (1)

41-41: Confirm consumer path: base64 artifact lives in dist/web but init_web imports from srcWasm.

init_web.js currently imports ../srcWasm/summon_ts_wasm_base64.js. You generate ./dist/web/e3_wasm_base64.js here. Align one of them (see my suggested fix in init_web.js).

crates/wasm/init_web.js (1)

11-12: Memoized lazy init looks good.

promise ??= ... ensures single initialization under concurrency.

If you expect repeated calls across SSR/CSR boundaries, ensure this module only loads in the browser (per exports mapping). Otherwise atob will be undefined during SSR.

Also applies to: 32-33

crates/wasm/package.json (3)

5-5: LGTM: main now points to dist/node/e3_wasm.js.

Matches the new node build output.


65-68: DevDeps additions are appropriate.

execa and replace-in-file match the new build flow.


26-38: Breaking change risk — package root ("." ) points to mutated dist/web/e3_wasm.js

If consumers import "@enclave-e3/wasm" (without "/init") they may load a neutered file.

  • Keep dist/web/e3_wasm.js immutable and require consumers to call "./init" (preferred).
  • Or change the browser export for "." to a safe shim that re-exports from the bindgen module after init, and document usage.

Location: crates/wasm/package.json (exports for "." — ~lines 26–38).

Automated verification in the sandbox failed (ripgrep returned "No files were searched"); manually confirm no internal code imports "@enclave-e3/wasm" (without "/init"), e.g. run locally:
git grep -n "@enclave-e3/wasm" -- ':!dist' ':!node_modules' || rg -n "@enclave-e3/wasm" -g '!/dist/' -g '!/node_modules/' | rg -v '/init'

Comment thread crates/wasm/init_web.js Outdated
Comment thread crates/wasm/scripts/build.js
Comment thread crates/wasm/scripts/build.js
@vercel vercel Bot temporarily deployed to Preview – enclave-docs September 17, 2025 14:11 Inactive
@vercel vercel Bot temporarily deployed to Preview – crisp September 17, 2025 14:11 Inactive

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
crates/wasm/init_web.js (2)

7-7: Fix wrong relative paths (will not resolve at runtime).

From this file, dist/* is sibling, not parent. Update to "./dist/...".

-import * as bindgen from "../dist/web/e3_wasm.js";
+import * as bindgen from "./dist/web/e3_wasm.js";
@@
-    const { default: base64 } = await import("../dist/web/e3_wasm_base64.js");
+    const { default: base64 } = await import("./dist/web/e3_wasm_base64.js");

Also applies to: 13-13


23-25: Remove undeclared global and guard optional init_ext.

lib = bindgen; throws in ESM (strict mode). If init_ext may be absent in some builds, guard it.

     bindgen.initSync(bytes);
-    bindgen.init_ext();
-    lib = bindgen;
+    bindgen.init_ext?.();
🧹 Nitpick comments (2)
crates/wasm/init_web.js (2)

12-14: Make memoization retry-safe on init failure.

If init rejects once, future calls keep returning the same rejected promise. Reset on error.

-  promise ??= (async () => {
-    const { default: base64 } = await import("./dist/web/e3_wasm_base64.js");
+  promise ??= (async () => {
+    try {
+      const { default: base64 } = await import("./dist/web/e3_wasm_base64.js");
@@
-    return bindgen;
-  })();
+      return bindgen;
+    } catch (err) {
+      promise = undefined;
+      throw err;
+    }
+  })();

Also applies to: 27-28


15-21: Micro: simplify base64→bytes conversion.

Shorter and typically faster; same result.

-    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);
-    }
+    const bytes = Uint8Array.from(atob(base64), c => c.charCodeAt(0));
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ca2e4bd and ae3db07.

📒 Files selected for processing (3)
  • crates/wasm/init_web.js (1 hunks)
  • crates/wasm/package.json (3 hunks)
  • crates/wasm/scripts/build.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/wasm/scripts/build.js
  • crates/wasm/package.json
🧰 Additional context used
🧬 Code graph analysis (1)
crates/wasm/init_web.js (1)
crates/wasm/init_node.js (1)
  • initializeWasm (7-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: build_sdk
  • GitHub Check: integration_prebuild
  • GitHub Check: build_enclave_cli
  • GitHub Check: rust_unit
  • GitHub Check: test_contracts
  • GitHub Check: test_net
  • GitHub Check: Build & Push Image
🔇 Additional comments (1)
crates/wasm/init_web.js (1)

9-10: LGTM: lazy, memoized one-time init.

The promise ??= pattern is correct and prevents duplicate inits.

Also applies to: 30-30

@vercel vercel Bot temporarily deployed to Preview – crisp September 17, 2025 14:42 Inactive
@vercel vercel Bot temporarily deployed to Preview – enclave-docs September 17, 2025 14:42 Inactive
@vercel vercel Bot temporarily deployed to Preview – enclave-docs September 17, 2025 14:44 Inactive
@vercel vercel Bot temporarily deployed to Preview – crisp September 17, 2025 14:44 Inactive

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/enclave-sdk/package.json (2)

31-38: Move build/test-only deps to devDependencies to avoid shipping them to consumers.

vite-plugin-wasm, vite-plugin-top-level-await, and vitest should be dev-only.

   "devDependencies": {
     "@enclave-e3/config": "workspace:*",
     "concurrently": "^9.1.2",
     "tsup": "^8.5.0",
     "typescript": "5.8.3",
     "vite": "^6.2.0",
-    "vite-plugin-dts": "^4.5.3"
+    "vite-plugin-dts": "^4.5.3",
+    "vitest": "^1.6.1",
+    "vite-plugin-top-level-await": "^1.5.0",
+    "vite-plugin-wasm": "^3.4.1"
   },
   "dependencies": {
@@
-    "vite-plugin-top-level-await": "^1.5.0",
-    "vite-plugin-wasm": "^3.4.1",
-    "vitest": "^1.6.1",
     "web-worker": "^1.5.0"
   }

Also applies to: 46-49


22-29: Prefer pnpm filters over cd-chains in prebuild for reliability and clarity.

Avoids path fragility and leverages workspace metadata.

-    "prebuild": "cd ../enclave-contracts && pnpm build && cd ../../crates/wasm && pnpm build",
+    "prebuild": "pnpm -w --filter @enclave-e3/contracts build && pnpm -w --filter @enclave-e3/wasm build",
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ae3db07 and c5f5ee4.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • crates/wasm/init_web.js (1 hunks)
  • crates/wasm/package.json (3 hunks)
  • packages/enclave-sdk/package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/wasm/init_web.js
  • crates/wasm/package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: build_sdk
  • GitHub Check: build_enclave_cli
  • GitHub Check: integration_prebuild
  • GitHub Check: test_net
  • GitHub Check: test_contracts
  • GitHub Check: rust_unit
  • GitHub Check: Build & Push Image
🔇 Additional comments (2)
packages/enclave-sdk/package.json (2)

35-35: Keep typescript@5.8.3 — verified present on npm.
npm registry: latest 5.9.2; 5.8.3 present.


42-42: Verify imports align with @enclave-e3/wasm exports

crates/wasm/package.json exposes both dist defaults and a "./init" conditional export (init_node.{js,cjs}, init_web.js, init.d.ts); the ripgrep run errored ("unrecognized file type: tsx") and returned no import matches — re-run the import scan with tsx support and confirm no callers import direct dist artifacts (callers should use "@enclave-e3/wasm" or "@enclave-e3/wasm/init").

@vercel vercel Bot temporarily deployed to Preview – crisp September 17, 2025 14:57 Inactive
@vercel vercel Bot temporarily deployed to Preview – enclave-docs September 17, 2025 14:57 Inactive

@ctrlc03 ctrlc03 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ctrlc03 ctrlc03 enabled auto-merge (squash) September 17, 2025 15:29
@ctrlc03 ctrlc03 merged commit 58f7905 into main Sep 17, 2025
26 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
crates/wasm/scripts/build.js (1)

7-10: Build script is ESM but executed as CJS; will crash under node scripts/build.js.

Top‑level import/await requires ESM ("type":"module" or .mjs). Either (a) rename to scripts/build.mjs and update package.json, or (b) convert to CJS with dynamic imports + async IIFE.

Below is option (b), which keeps the .js name working everywhere:

-import { execa } from "execa";
-import { readFile, writeFile, rm } from "fs/promises";
-import replaceInFile from "replace-in-file";
-
-try {
+// CJS-friendly build script (dynamic ESM imports)
+const { readFile, writeFile, rm } = require("fs").promises;
+(async () => {
+  const { execa } = await import("execa");
+  const replaceInFile = (await import("replace-in-file")).default;
+  try {
   // Build WASM with web and node target - generates e3_wasm.js and e3_wasm_bg.wasm.
-  await execa("wasm-pack", [
+  await execa("wasm-pack", [
     "build",
     "--target=web",
     "--out-dir=dist/web",
     "--no-pack",
-  ]);
-  await execa("wasm-pack", [
+  ], { stdio: "inherit" });
+  await execa("wasm-pack", [
     "build",
     "--target=nodejs",
     "--out-dir=dist/node",
     "--no-pack",
-  ]);
+  ], { stdio: "inherit" });
@@
-  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);
-}
+  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);
+  }
+})().catch((err) => {
+  console.error(err);
+  process.exit(1);
+});

Also applies to: 11-48

crates/wasm/package.json (1)

21-23: Build script will fail unless scripts/build.js runs as ESM.

Given the current script uses top‑level import/await, either convert it to CJS (see build.js comment) or rename to .mjs and update this field.

Example if you choose the rename route:

-    "build": "rm -rf dist && node scripts/build.js",
+    "build": "rm -rf dist && node scripts/build.mjs",
🧹 Nitpick comments (5)
crates/wasm/scripts/build.js (2)

31-44: Flatten nested Promise.all; avoid await inside the array literal.

Current code awaits an inner Promise before forming the outer list, which is confusing and partially serializes work. Flatten it.

-  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),
-  ]);
+  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),
+  ]);

13-24: Surface wasm-pack output (DX).

Forward stdio so build logs/errors are visible in CI/local runs.

-  await execa("wasm-pack", [
+  await execa("wasm-pack", [
     "build",
     "--target=web",
     "--out-dir=dist/web",
     "--no-pack",
-  ]);
+  ], { stdio: "inherit" });
   await execa("wasm-pack", [
     "build",
     "--target=nodejs",
     "--out-dir=dist/node",
     "--no-pack",
-  ]);
+  ], { stdio: "inherit" });
crates/wasm/init_web.js (2)

12-26: Make base64 decoding environment-robust (SSR safety).

atob is browser‑only; if this module runs during SSR by mistake, it throws. Add a guarded fallback to Buffer and centralize decoding.

-    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);
-    }
+    const { default: base64 } = await import("./dist/web/e3_wasm_base64.js");
+    const decodeBase64ToBytes = (b64) => {
+      if (typeof atob === "function") {
+        const bin = atob(b64);
+        const out = new Uint8Array(bin.length);
+        for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
+        return out;
+      }
+      if (typeof Buffer !== "undefined") {
+        return Uint8Array.from(Buffer.from(b64, "base64"));
+      }
+      throw new Error("Base64 decoder unavailable in this environment");
+    };
+    const bytes = decodeBase64ToBytes(base64);

11-11: initParams is unused.

Either remove it (and update init.d.ts) or plumb it through if you plan to support flags/options.

crates/wasm/package.json (1)

8-16: Files list is redundant.

"dist/" already includes dist/node/** and dist/web/**. You can drop the explicit dist/node/**.

   "files": [
     "dist/",
-    "dist/node/**",
     "dist/web/**",
     "init_node.js",
     "init_node.cjs",
     "init_web.js",
     "init.d.ts"
   ],
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c5f5ee4 and afb9478.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • crates/wasm/.npmignore (0 hunks)
  • crates/wasm/init_web.js (1 hunks)
  • crates/wasm/package.json (3 hunks)
  • crates/wasm/scripts/build.js (1 hunks)
  • crates/wasm/scripts/build.sh (0 hunks)
  • package.json (1 hunks)
💤 Files with no reviewable changes (2)
  • crates/wasm/scripts/build.sh
  • crates/wasm/.npmignore
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json
🧰 Additional context used
🧬 Code graph analysis (1)
crates/wasm/init_web.js (1)
crates/wasm/init_node.js (1)
  • initializeWasm (7-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: build_sdk
  • GitHub Check: integration_prebuild
  • GitHub Check: build_enclave_cli
  • GitHub Check: test_contracts
  • GitHub Check: rust_unit
  • GitHub Check: test_net
  • GitHub Check: Build & Push Image
🔇 Additional comments (4)
crates/wasm/scripts/build.js (1)

38-41: Good: resilient replacement prevents stale .wasm URL usage.

Regex looks robust to minor formatting changes in bindgen output. This directly addresses the “wrong WASM URL resolves to HTML” failure mode.

crates/wasm/init_web.js (1)

12-29: LGTM: idempotent lazy init with memoized Promise.

Memoization ensures single init across callers and fixes the broken URL‑based loader path when paired with the build step.

crates/wasm/package.json (2)

25-57: Exports shape looks consistent with the new init flow.

The ./init subpath cleanly separates browser and node entry points and should prevent the broken web URL loader path when used as intended.

Please confirm the template app imports @enclave-e3/wasm/init on the web path.


26-39: Confirm Node entry format and expose both import and require

dist/node/e3_wasm.js not found in the repo — module format (ESM vs CJS) is unknown. Update crates/wasm/package.json (node field) to explicitly expose both entry points or provide ESM/CJS wrappers so both consumers work.

Examples:

  • If ESM: node: { "types":"./dist/node/e3_wasm.d.ts", "import":"./dist/node/e3_wasm.js", "require":"./dist/node/e3_wasm.cjs" }
  • If CJS: node: { "types":"./dist/node/e3_wasm.d.ts", "require":"./dist/node/e3_wasm.js", "import":"./dist/node/e3_wasm.mjs" }

Location: crates/wasm/package.json (node field).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WASM module is not initialized correctly

2 participants