Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wasmer-JS running on Node #387

Open
2 tasks
syrusakbary opened this issue Dec 21, 2023 · 2 comments
Open
2 tasks

Wasmer-JS running on Node #387

syrusakbary opened this issue Dec 21, 2023 · 2 comments
Labels

Comments

@syrusakbary
Copy link
Member

syrusakbary commented Dec 21, 2023

The JavaScript SDK currently only officially supports running in a browser. This issue tracks what is needed to add NodeJS support.

  • Spawning Web Workers using a data URL (needed for spawning a worker)
  • Requires access to the navigator.hardwareConcurrency API (required by WASIX syscalls - here)
Copy link

linear bot commented Dec 21, 2023

@Michael-F-Bryan
Copy link
Contributor

It looks like NodeJS doesn't let you spawn a new worker with a blob URL, so in #399 (ad304b4) I tried encoding the worker.js file as a base64 data URL.

This seems to work fine for NodeJS, but it looks like we run into Cross-Origin Isolation issues in the browser when passing the data URL to new Worker().

According to the spec...

Any same-origin URL (including blob: URLs) can be used. data: URLs can also be used, but they create a worker with an opaque origin.

The concrete error I'm seeing is this (when running wasm-pack test):

Access to script at 'http://127.0.0.1:8000/wasm-bindgen-test' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
data:text/javascript;base64,RXJ..wo=:55 Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: http://127.0.0.1:8000/wasm-bindgen-test

For posterity's sake, here is the change I made:

diff --git a/src/tasks/worker.js b/src/tasks/worker.js
index 18c5b97..e3596d7 100644
--- a/src/tasks/worker.js
+++ b/src/tasks/worker.js
@@ -15,9 +15,7 @@ let handleMessage = async data => {
 globalThis.onmessage = async ev => {
     if (ev.data.type == "init") {
         const { memory, module, id, import_url } = ev.data;
-        const imported = await import(
-            new URL(import_url, self.location.origin)
-        );
+        const imported = await import(new URL(import_url));
 
         // HACK: How we load our imports will change depending on how the code
         // is deployed. If we are being used in "wasm-pack test" then we can
diff --git a/src/tasks/worker_handle.rs b/src/tasks/worker_handle.rs
index 7ff6a6e..46af8c6 100644
--- a/src/tasks/worker_handle.rs
+++ b/src/tasks/worker_handle.rs
@@ -1,7 +1,8 @@
 use std::fmt::Debug;
 
 use anyhow::{Context, Error};
-use js_sys::{Array, JsString, Uint8Array};
+use base64::{engine::general_purpose::STANDARD, Engine};
+use js_sys::JsString;
 use once_cell::sync::Lazy;
 use wasm_bindgen::{
     prelude::{wasm_bindgen, Closure},
@@ -165,12 +166,6 @@ fn import_meta_url() -> String {
 /// A data URL containing our worker's bootstrap script.
 static WORKER_URL: Lazy<String> = Lazy::new(|| {
     let script = include_str!("worker.js");
-
-    let blob = web_sys::Blob::new_with_u8_array_sequence_and_options(
-        Array::from_iter([Uint8Array::from(script.as_bytes())]).as_ref(),
-        web_sys::BlobPropertyBag::new().type_("application/javascript"),
-    )
-    .unwrap();
-
-    web_sys::Url::create_object_url_with_blob(&blob).unwrap()
+    let encoded = STANDARD.encode(script);
+    format!("data:text/javascript;base64,{encoded}")
 });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants