GithubHelp home page GithubHelp logo

second-state / wasmedge-quickjs Goto Github PK

View Code? Open in Web Editor NEW
451.0 14.0 54.0 66.09 MB

A high-performance, secure, extensible, and OCI-complaint JavaScript runtime for WasmEdge.

License: Apache License 2.0

Rust 16.74% JavaScript 83.07% CSS 0.08% HTML 0.07% Dockerfile 0.04%
webassembly rust javascript wasmedge

wasmedge-quickjs's Introduction

Run JavaScript in WebAssembly

Checkout the documentation

Quick start

git clone https://github.com/second-state/wasmedge-quickjs
cd wasmedge-quickjs

cargo build --target wasm32-wasi --release

wasmedge --dir .:. target/wasm32-wasi/release/wasmedge_quickjs.wasm example_js/hello.js WasmEdge Runtime
Hello WasmEdge Runtime

wasmedge-quickjs's People

Contributors

alabulei1 avatar darumadocker avatar juntao avatar l-jasmine avatar puellaquae avatar q82419 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wasmedge-quickjs's Issues

Consider mimicking the browser's `fetch` API for `http_module`

Hi there, I'm really impressed with this project! I'm looking for a WASM or JS runtime to create a plugin system for Atomic Server, and this looks very interesting.

I'd love to be able to use my existing JS / Node library in here, but that one currently depends on having some form of fetch - either from window or from node.

I was wondering whether it would be possible to mimick the browser's fetch API for the GET / POST part of the http_module, so it would be a drop-in replacement. That would allow users to run many existing libraries in this runtime.

Good luck with this project!

Hydrate is not a function

Hi
I have a few observations whilst building a new React SSR application.

I get an error (in the client's browser console) as shown below, when the app is started. Interestingly, the page still loads successfully. But I am not wanting to just ignore this browser console error (in case we need to address this)

Uncaught TypeError: n.createRoot(...).hydrate is not a function

Here is my understanding of render vs hydrate

Render provides a way for the app to render a React element into the DOM and return a reference to the component.

Hydrate is essentially the same as render. However, hydrate is used to hydrate a container whose HTML contents were rendered by React's ReactDOMServer.

The original code in the src/index.js file (which the create-react-app command generated) is as follows

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Interestingly the above original code works even when we have already implemented all of the other SSR conversions (server/index.js and rollup.config.js etc.) and are starting the server using wasmedge command (as apposed to npm).

Please note, that there is no error in the browser console with the above code (root.render).

We of course change the root.render to root.hydrate in our documentation so I went ahead and did that. The root.hydrate generates the above error. I then also tried importing and using ReactDOMServer instead of just ReactDOM but the error still persists.

Do you have any ideas about solving this error.
Thanks so much
Tim

How to run code out of the modules folder

In fact, I'm building an application on top of wasmedge quickjs to execute javascript, but I want to version its modules folder and optimized wasm files via npm, and I'd like to know how to modify the relevant code to support this behavior

Define Nodejs Version

I saw in the platform.js that we support version 16.8.

Is this a valid assumption?

implement Serialize/Deserialize for JsValue

Currently when I want to parse or deconstruct a JsValue coming from a JsFn, I have to manually match and navigate into the JsValue structure. It's currently easier to just use JSON.stringify() on the JS side and pass the data to the Rust function, and deserialize from there using serde_json::from_string().

It would be great if JsValue would natively support serde so we can create JsFn with strong generic boundaries and/or auto-deserialization.

Routing with WasmEdge SSR vs regular SSR

It would be great to take a look at how WasmEdge SSR can implement routing.

The standard way to route in React is to install the npm install react-router-dom package and then implement in the App.js file, as shown below.

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

Below is the full App.js file which uses routing and this is where the page on the client's browser stops responding (when using WasmEdge SSR)

import React from 'react';
import Navbar from './Navbar';
import Home from './Home';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

function App() {
  return (
    <Router>
      <div className="App">
        <Navbar />
        <div className="content">
          <Switch>
            <Route path="/">
              <Home />
            </Route>
          </Switch>
        </div>
      </div>
    </Router>
  );
}

export default App;

This is the client's browser when running routing via WasmEdge (FYI there seems to be no messages in the terminal where the wasmedge command is run and also no messages in the browser's console)

image


If the same source is run using regular SSR via the npm start command, the page renders correctly at localhost:3000 in the client's browser and no messages or errors etc. are present.

image

Javascript setTimeout not working

I'm unable to get setTimeout to work in the example hello.js and react18_ssr, on a mac m1.

The function exists however it never actually times out - it just hangs indefinitely.

[Question] Http support

I've noticed that certain key features are currently missing in the wasmedge-quickjs repository, which may not be prioritized at the moment. Firstly, there is no HTTPS support, and I also encountered a long-standing bug (#102) related to the response buffer length, which rendered the fetch functionality unusable in my tests.

I'm currently working on a project that uses a custom WASM WASI runner, and I believe the wasmedge-quickjs project could be a valuable resource for JavaScript support. However, there are a few essential features that are lacking for my use case, namely HTTPS support and a complete implementation of the Response/Request standards. While I managed to address the HTTPS aspect by rewriting the Rust part to accommodate my custom networking hostcalls, I'm finding it more challenging to work with the JS SDK.

Specifically, I require the ability to stream data with the .body -> ReadableStream API on the Response and Request objects, along with the standard response constructor constructor(body, options) instead of the current constructor(resp, buffer, reader, option = {}). It would greatly benefit me if the library could provide as much of the standard API as possible, allowing my users' code to run with minimal modifications.

I'm curious to know if there are any plans for development in this area or if it aligns with your future roadmap for the networking API. If not, I'm willing to contribute and implement these features myself. Would you be interested in my contributions, or would it conflict with your plans?

Additionally, I noticed that quickjs doesn't implement ReadableStream/WritableStream, but the modules/internal/streams folder contains Readable and Writable functions. Apart from the naming difference, are there any significant distinctions between these functions and the standard ReadableStream/WritableStream objects? Could they potentially create difficulties for users or require them to make adjustments?

[Feature Request] Standalone QuickJS server

If you have a standalone HTTP/HTTPS server module for QuickJS it would be helpful to publish that code standalone, so users don't necessarily need WasmEdge to import and run the server. Thanks.

Support `crypto` Node API in wasmedge-quickjs

Motivation

In WasmEdge, we already support JavaScript, NPM packages, ES6 modules, and even using Rust to implement JS APIs.

However, one of the most commonly requested features is full node.js compatibility in WasmEdge. We can implement all node.js APIs in either JavaScript or Rust. This issue tracks this feature. Most of the code is in the wasmedge-quickjs repo

The node.js APIs can be implemented in JS (in the modules directory) and in Rust / C (in the src/internal_module directory).

This issue is to add crypto API.

module_name language
crypto rust/c

Implementing Fetch

Client side interaction (fetch)

Ideally it will be great if a user is able to action the fetch functionality from their web browser. For example, the user clicks "Display Data" button and then the app goes and fetches data which it displays to the user's browser.

The best way I can think of to achieve this is to have another listening port in the server/index.js file, as shown below.

async function fetch_start() {
  print('listen 8003...');
  try {
    let s = new net.WasiTcpServer(8003);
    for (var i = 0; ; i++) {
      let cs = await s.accept();
      handle_fetch();
    }
  } catch (e) {
    print(e);
  }
}
fetch_start()

This allows port 8003 to listen for URLs to fetch, when asked by the client's browser.

The handle_fetch code in the server/index.js file which processes these requests could look like the following.

// Implement Fetch
import { fetch } from 'http';

async function handle_fetch() {
  try {
    console.log("Testing 123");
    let resp = new http.WasiResponse();
    let r = await fetch("http://httpbin.org/get?id=1")
    console.log("Testing 456");
    print('test_fetch\n', await r.text())
    console.log("Testing 789");
  } catch (e) {
    print(e)
  }
}

I have tested the above and we are able to listen and respond on port 8003 (albeit only in the terminal's output for now). Below is the output for your convenience.

Testing 123
Testing 456
test_fetch
 {
  "args": {
    "id": "1"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "X-Amzn-Trace-Id": "Root=1-628878d7-0914ef354f63f7d655346fdc"
  }, 
  "origin": "27.33.80.26", 
  "url": "http://httpbin.org/get?id=1"
}
Testing 789

Questions

This leads to the following 2 part question. What would be your preferred design choice to:

  1. provide the URL from the browser's request to the listening server?
  2. identify the HTML element which is going to be updated with the new data from the fetch?

Ideas

  1. The URL could be passed from the browser's request to the server as a simple string.
  2. The client side could fill a specific HTML element by making the request and then updating the element's contents.

Both of these are really leaning towards client-side rendering though.

Perhaps another way, which leans more towards SSR is for the browser to perform a HTTP POST request (as per this WasmEdge demo). Specifically, the request could use multi-part form data which could pass in both the URL endpoint to fetch as well as the HTML element which is to be updated/altered. This way the server-side will have the ability to fetch and render the new data (leaving as little as possible to the client-side). The server/index.js file would just need the required functionality to process the multi-part form request.

Just FYI, the recent issue regarding the hydrate error has been resolved. We can now hydrate in the src/index.js file using the following syntax without error.

import { hydrateRoot } from 'react-dom/client';
const container = document.getElementById('root');
const root = hydrateRoot(container, <App />);

I am not sure why the new React 8.x.x function is called hydrateRoot and not just hydrate. I am assuming that hydrateRoot can hydrate any element in the HTML (as long as the handle is fetched by document.getElementById and then passed to the hydrateRoot function call).

Hope this all makes sense. I would love to hear any thoughts and ideas on this.

Kind regards
Tim

Update support for the image module

The new Tensorflow Lite plugin for WASI NN in 0.12 removes built-in image host functions. The Rust examples for WASI NN now uses Rust's image crate to pre-process images. As a result, the tensorflow lite JS examples are now failing.

# wasmedge --dir .:. wasmedge_quickjs.wasm example_js/tensorflow_lite_demo/wasi_nn_main.js
ReferenceError: could not load module filename 'image'

I think we need to update the image module support using the Rust image crate as well.

Demo(Async HTTP Request) can't work on macOS

Enviroment:

  1. macOS version:

image

  1. rust version:

image

  1. wasmedge version:

image

  1. more information:
    the default version of wasmedge 0.10.0 also can't work on macOS

image

  1. Description:
    After cargo build, many of the examples in this repository can work such as hello.js ,Add Core Module With JavaScript(ES), but the demo of Async Http Request can't work

image

How can I solve this problem? @juntao

And I test it by the same way on linux , it looks works.

http post request
image

server
image

Thanks

Splitting quickjs-sys into its own crate

Hello!
I'm making a project utilizing quickjs in rust, so this crate's quickjs features are extremely useful to me(I need to compile to wasm). However, I don't need any of the features related to the wasmedge runtime -- in fact, some of them break my application. (Right now I'm modifying the crate locally, which is problematic)
Because of this, it would be super helpful if quickjs-sys could be split into a seperate crate without any of the wasmedge-specific imports.
Thanks for the amazing bindings!

How to support asynchronous processing in JsFn::call ?

Hi,

I want to call rust's asynchronous processing logic in js (such as hyper_wasi project's asynchronous httpclient), how should I handle it?

struct HttpGetFn;
impl JsFn for HttpGetFn {
    fn call(ctx: &mut Context, _this_val: JsValue, argv: &[JsValue]) -> JsValue {
        // How to support asynchronous processing? like:
        // let resp = http_req(...).await;
    }
}

Http server connect issue

I tried with the steps, and found the http server demo can not work properly:

image

Then send request will failed:

coderscat@MININT-ODP168:~/dapr-wasm$ curl -d "WasmEdge" -X POST http://127.0.0.1:8000
curl: (7) Failed to connect to 127.0.0.1 port 8000: Connection refused

If we try to telnet, it will crash with an error:
image

~/wasmedge-quickjs/example_js$ wasmedge --dir .:. ../target/wasm32-wasi/release/wasmedge_quickjs.wasm http_server_demo.js
listen on 0.0.0.0:8000
InternalError: Error(TrackableError { kind: InvalidInput, cause: Some(Cause("assertion failed: `left == right`; assertion failed: `(left == right)` (left: `'\\r'`, right: `' '`)")), history: History([Location { module_path: "httpcodec::method", file: "/home/coderscat/.c
    at accept (native)
    at <anonymous> (http_server_demo.js:15)

Dome Hello World in readme may not work

If run

$ cd example_js
$ wasmedge --dir .:. ../target/wasm32-wasi/release/wasmedge_quickjs.wasm hello.js WasmEdge Runtime

which written in readme will show ReferenceError: could not load module filename 'process'. The module files are not loaded into wasm environment (or maybe there has other way to access the module files that I don't know).

Or use this?

$ wasmedge --dir .:. ./target/wasm32-wasi/release/wasmedge_quickjs.wasm example_js/hello.js WasmEdge Runtime

Support `readline` Node API in wasmedge-quickjs

Motivation

In WasmEdge, we already support JavaScript, NPM packages, ES6 modules, and even using Rust to implement JS APIs.

However, one of the most commonly requested features is full node.js compatibility in WasmEdge. We can implement all node.js APIs in either JavaScript or Rust. This issue tracks this feature. Most of the code is in the wasmedge-quickjs repo

The node.js APIs can be implemented in JS (in the modules directory) and in Rust / C (in the src/internal_module directory).

This issue is to add readline API.

module_name language
readline rust/c

Support `dns` Node API in wasmedge-quickjs

Motivation

In WasmEdge, we already support JavaScript, NPM packages, ES6 modules, and even using Rust to implement JS APIs.

However, one of the most commonly requested features is full node.js compatibility in WasmEdge. We can implement all node.js APIs in either JavaScript or Rust. This issue tracks this feature. Most of the code is in the wasmedge-quickjs repo

The node.js APIs can be implemented in JS (in the modules directory) and in Rust / C (in the src/internal_module directory).

This issue is to add dns API.

module_name language
dns rust/c/js

Unable to start server - OS error 28 on Ubuntu 20.04

Originates from this line: https://github.com/second-state/wasmedge-quickjs/blob/main/modules/http.js#L764

Machine details:

❯ uname -sr
Linux 5.15.0-46-generic

❯ uname -a
Linux bropletop 5.15.0-46-generic #49~20.04.1-Ubuntu SMP Thu Aug 4 19:15:44 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

❯ wasmedge --version
wasmedge version 0.9.1

❯ cargo --version
cargo 1.62.0 (a748cf5a3 2022-06-08)

Using a pre-built image of the much simpler HTTP app works for me via cri-o and crun, but I'm not aware of such an image for the react examples, and I am unable to run the the simple HTTP example bytecode locally either (same error).

Call non-runtime Host function

As I understand it, Rust's main() function is compiled to WASM. Is it possible to call a non-WASM host function so that Javascript could actually call to the host outside of the runtime?

My case is that I am drawing on a canvas from my JS code, but no canvas component exists there (and Skia cannot be compiled to wasm-wasi), so I have to pass the draw commands and draw outside of the runtime.

Asynchronous operations are not available in the http server

import { createServer, fetch } from 'http';

createServer((req, resp) => {
  req.on('data',async (body) => {

    if(req.url == '/wait'){
      print("fetch...");
      let response = await fetch('http://127.0.0.1:8001/echo', { method: 'POST', body: 'hello server' })
      let result = await response.text()
      print("fetched:",result);
      resp.end(result)
    }else{
      resp.end(body)
    }
    
  })
}).listen(8001,'0.0.0.0', () => {
  print('listen 8001 ...\n');
})

async function test_fetch() {
  let resp = await fetch('http://127.0.0.1:8001/wait', { method: 'POST', body: 'hello server' })
  print('fetch client recv:', await resp.text())
  print()
}

async function run_test() {
  await test_fetch()
  exit(0)
}

run_test()

Output after execution.

wait...
fetched: hello server

No output fetch client recv:hello server

So, after adding async/await operations to the http server, the request cannot get a response.

To return an empty response using CURL.

curl -d 'hello server' http://127.0.0.1:8001/wait -X POST
curl: (52) Empty response from the server

Provide pre-built files in the release assets

Hi,

I have a few questions:

  1. Is the wasmedge-quickjs stable now?
  2. I would like to know if is it possible to have a release with all the pre-built files, because some people may not want to re-build the quickjs on their host environment.
  3. Is it possible to have version tags and changelogs when some new features are introduced?

Using the WASM file from Rust code instead of the WasmEdge CLI Tool

I want to embed this Javascript WASM runtime by using a Rust WASM runtime in a Rust program, for example wasmer or wasmtime and so on. However, When I use wasmer and wasmer_wasi crates to write code, I realize that I encountered a problem about WASI.

Error: Error while importing "wasi_snapshot_preview1"."sock_open": unknown import. Expected Function(FunctionType { params: [I32, I32, I32], results: [I32] })

Is there any way to help me solve it here? I will be very grateful for your help.

http server cannot read the body of the request with `"transfer-encoding":"chunked"` request header

Description

I write a simple echo service by quickjs:

import { createServer } from 'http';

createServer((req, resp) => {
  let data = "";
  req.on('data', (body) => {
    data += body;
    resp.write("echo: ");
  })
  req.on("end", () => {
    resp.end(data);
  });
}).listen(8080, () => {
  print('listen 8080 ...\n');
})

Start it:

$ wasmedge --dir .:. wasmedge_quickjs.wasm server.js
listen 8080 ...

Open another terminal, try to send a request, it's OK:

$ curl 127.0.0.1:8080 -d "name=WasmEdge" -i
HTTP/1.1 200 OK
Transfer-Encoding: chunked

echo: name=WasmEdge

But when send a request with "transfer-encoding":"chunked", the server cannot echo the request body:

$ curl 127.0.0.1:8080 -d "name=WasmEdge" -H "transfer-encoding":"chunked" -i
HTTP/1.1 200 OK

Expected

$ curl 127.0.0.1:8080 -d "name=WasmEdge" -H "transfer-encoding":"chunked" -i
HTTP/1.1 200 OK
Transfer-Encoding: chunked

echo: name=WasmEdge

Environment

  • Hardware Architecture: x86_64
  • Operating system: Ubuntu 20.04

wasmedge version:

$ wasmedge -v
wasmedge version 0.10.0

wasmedge_quickjs.wasm version:

https://github.com/second-state/wasmedge-quickjs/releases/download/v0.4.0-alpha/wasmedge_quickjs.wasm

[Question] License

Hi,

I want to use the files in the modules folder in another project. Am I free to use the files? Is there a license for that?

I did not see a license file in the project.

Error: instantiation failed: unknown import, Code: 0x62

I have cloned this React blog software [1] which is also part of a comprehensive YouTube tutorial about React [2].
After building it using the standard npm commands (to make sure it worked) I then went ahead and update the source code and config to be rendered server side. I used the SSR [3] instructions from the WasmEdge book.

Everything was successful right up until the final command to start the server i.e. wasmedge --dir .:. wasmedge_quickjs.wasm ./server-build/index.js

Here is the error which was returned from that command.

[2022-04-26 10:31:26.387] [error] instantiation failed: unknown import, Code: 0x62
[2022-04-26 10:31:26.387] [error]     When linking module: "wasi_snapshot_preview1" , function name: "sock_setsockopt"
[2022-04-26 10:31:26.387] [error]     At AST node: import description
[2022-04-26 10:31:26.387] [error]     When linking module: "wasi_snapshot_preview1" , function name: "sock_setsockopt"
[2022-04-26 10:31:26.387] [error]     At AST node: import description
[2022-04-26 10:31:26.387] [error]     At AST node: import section
[2022-04-26 10:31:26.387] [error]     At AST node: module

[1] https://github.com/iamshaunjp/Complete-React-Tutorial/tree/lesson-32/dojo-blog
[2] https://www.youtube.com/watch?v=j942wKiXFu8&list=PL4cUxeGkcC9gZD-Tvwfod2gaISzfRiP9d&index=1
[3] https://wasmedge.org/book/en/dev/js/ssr.html

Performance of React SSR

Although the React App is very small, the performance of rendering it via wasmedge-quickjs is rather slow, compared to rendering it via a local node process:

# macbook pro 2019, i7, 32GB RAM
❯ hyperfine "wasmedge --dir .:. ../../target/wasm32-wasi/release/wasmedge_quickjs.wasm dist/main.js" "node dist/main.js"
Benchmark #1: wasmedge --dir .:. ../../target/wasm32-wasi/release/wasmedge_quickjs.wasm dist/main.js
  Time (mean ± σ):      1.843 s ±  0.024 s    [User: 1.793 s, System: 0.032 s]
  Range (min … max):    1.807 s …  1.877 s    10 runs

Benchmark #2: node dist/main.js
  Time (mean ± σ):      54.5 ms ±   2.8 ms    [User: 42.9 ms, System: 8.9 ms]
  Range (min … max):    51.4 ms …  64.7 ms    51 runs

Summary
  'node dist/main.js' ran
   33.80 ± 1.76 times faster than 'wasmedge --dir .:. ../../target/wasm32-wasi/release/wasmedge_quickjs.wasm dist/main.js' 

Are there any options to improve the performance for SSR in wasm?

A new release on crates.io

Could the authors publish the latest version on crates.io so we can embed it in other software?

EDIT: I forked the project and released it on crates.io under the name encedeus_js_runtime. The only difference is that I embedded the modules folder directly inside the binary, which adds the Node.js compatibility layer to the engine without having to create a symbolic link for the modules directory. The API is exactly the same.

Support `net` Node API in wasmedge-quickj

Motivation

In WasmEdge, we already support JavaScript, NPM packages, ES6 modules, and even using Rust to implement JS APIs.

However, one of the most commonly requested features is full node.js compatibility in WasmEdge. We can implement all node.js APIs in either JavaScript or Rust. This issue tracks this feature. Most of the code is in the wasmedge-quickjs repo

The node.js APIs can be implemented in JS (in the modules directory) and in Rust / C (in the src/internal_module directory).

This issue is to add net API.

module_name language
net rust/c

Support `fs` Node API in wasmedge-quickjs

Motivation

In WasmEdge, we already support JavaScript, NPM packages, ES6 modules, and even using Rust to implement JS APIs.

However, one of the most commonly requested features is full node.js compatibility in WasmEdge. We can implement all node.js APIs in either JavaScript or Rust. This issue tracks this feature. Most of the code is in the wasmedge-quickjs repo

The node.js APIs can be implemented in JS (in the modules directory) and in Rust / C (in the src/internal_module directory).

This issue is to add fs API.

module_name language
fs rust/c

How to convert JsValue to Rust type?

JS code is as follows:

export async function wait_simple_val (key){
    return "abc"
}

wasmedge-quickjs/examples/embed_js/src/main.rs

let result = p.get_result();
println!("promise result:{:?}", result);

the result is JsValue, and i got promise result:String(JsString(abc))

my question is how can i get the real result "abc" from the JsValue? any doc about this?

Support `http2` Node API in wasmedge-quickjs

Motivation

In WasmEdge, we already support JavaScript, NPM packages, ES6 modules, and even using Rust to implement JS APIs.

However, one of the most commonly requested features is full node.js compatibility in WasmEdge. We can implement all node.js APIs in either JavaScript or Rust. This issue tracks this feature. Most of the code is in the wasmedge-quickjs repo

The node.js APIs can be implemented in JS (in the modules directory) and in Rust / C (in the src/internal_module directory).

This issue is to add http2 API.

module_name language
http2 rust/c

Nested Buffer dependency fails

I want to run wasmedge-quickjs on the following JS code:

var std = require('std');
import {Buffer} from 'buffer';
var WebAssembly = require('webassemblyjs');

let f = std.open('./add.wasm', 'r');
f.seek(0, std.SEEK_END);
let sz = f.tell();
f.seek(0, std.SEEK_SET);
let wasmBuffer = new ArrayBuffer(sz);
f.read(wasmBuffer, 0, sz);

WebAssembly.instantiate(wasmBuffer).then(wasmModule => {
  const { add } = wasmModule.instance.exports;
  const sum = add(5, 6);
  console.log(sum); 
});

Now the issue is that the dependency WebAssembly uses Buffer internally and this nested dependency is not handled properly. To make the code work, I had to perform a manual adjustment of the dist/index.js file produced by ncc as follows:

sed -i "s/ Buffer/ external_buffer_namespaceObject.Buffer/g" dist/index.js
sed -i "1s;^;const external_buffer_namespaceObject = require(\"buffer\")\;;" dist/index.js

I wonder if there is a canonical approach to deal with this issue. You can fully reproduce my issue by running:

git clone https://github.com/mraszyk/wasmedge-quickjs.git
cd wasmedge-quickjs
git checkout mraszyk/import-buffer
bash -x ./import-buffer.sh

Unable to run examples on M1 mac: `cannot execute binary file`

Hi there! This project looks very very cool. However, I've tried running cargo run in the various example_js folders, but none of them seem to work.

target/wasm32-wasi/debug/embed_js_module.wasm: target/wasm32-wasi/debug/embed_js_module.wasm: cannot execute binary file

I also tried embedding some examples' rust code in an existing rust project of mine, and got errors containing:

...out/libquickjs.a, building for macOS-arm64 but attempting to link with file built for unknown-unsupported file format (...)
          Undefined symbols for architecture arm64:
            "_JS_AddModuleExport", referenced fro...

I'm assuming there is no arm64 support yet? Or am I missing some sort of runtime dependency?

Need ARM support

While running

$ cargo build --target wasm32-wasi --release

I got the following error:

root@a550d255c1a1:~/examples/wasmedge-quickjs# cargo build --target wasm32-wasi --release
   Compiling argparse v0.2.2
   Compiling idna v0.2.3
   Compiling url v2.2.2
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/librustc_driver-15fe7307aff1f259.so(+0x5205d3)[0x40021ce5d3]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x141f0)[0x4005c2d1f0]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(+0x21b1d4e)[0x4007fecd4e]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(_ZN4llvm13AttributeList7getImplERNS_11LLVMContextENS_8ArrayRefINS_12AttributeSetEEE+0x249)[0x4007fec879]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(_ZNK4llvm13AttributeList13setAttributesERNS_11LLVMContextEjNS_12AttributeSetE+0xb4)[0x4007fec414]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(_ZNK4llvm13AttributeList12addAttributeERNS_11LLVMContextEjNS_9Attribute8AttrKindE+0x1aa)[0x40080b516a]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(+0x28eaf2a)[0x4008725f2a]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(+0x28e7f58)[0x4008722f58]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(+0x27d4df6)[0x400860fdf6]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE+0x36c)[0x4008ddc46c]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(LLVMRunPassManager+0xa)[0x40090b1a9a]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/librustc_driver-15fe7307aff1f259.so(+0x21e2555)[0x4003e90555]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/librustc_driver-15fe7307aff1f259.so(+0x215cc34)[0x4003e0ac34]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/librustc_driver-15fe7307aff1f259.so(+0x2190d40)[0x4003e3ed40]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/librustc_driver-15fe7307aff1f259.so(+0x21c91ac)[0x4003e771ac]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/libstd-7c582493123fc1dd.so(rust_metadata_std_5c4e0e91f40690d7+0xaa933)[0x400594f933]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x9450)[0x4005c22450]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x43)[0x4005d64d53]
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
error: could not compile `argparse`

Caused by:
  process didn't exit successfully: `rustc --crate-name argparse /root/.cargo/registry/src/github.com-1ecc6299db9ec823/argparse-0.2.2/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts --crate-type lib --emit=dep-info,metadata,link -C opt-level=3 -C embed-bitcode=no -C metadata=cdd4ade14f2dea66 -C extra-filename=-cdd4ade14f2dea66 --out-dir /root/examples/wasmedge-quickjs/target/wasm32-wasi/release/deps --target wasm32-wasi -L dependency=/root/examples/wasmedge-quickjs/target/wasm32-wasi/release/deps -L dependency=/root/examples/wasmedge-quickjs/target/release/deps --cap-lints allow -C target-feature=+bulk-memory` (signal: 11, SIGSEGV: invalid memory reference)
warning: build failed, waiting for other jobs to finish...
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/librustc_driver-15fe7307aff1f259.so(+0x5205d3)[0x40021ce5d3]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x141f0)[0x4005c2d1f0]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(+0x21b1bd1)[0x4007fecbd1]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(_ZN4llvm13AttributeList7getImplERNS_11LLVMContextENS_8ArrayRefINS_12AttributeSetEEE+0x249)[0x4007fec879]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(_ZNK4llvm13AttributeList13setAttributesERNS_11LLVMContextEjNS_12AttributeSetE+0xb4)[0x4007fec414]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(_ZNK4llvm13AttributeList12addAttributeERNS_11LLVMContextEjNS_9Attribute8AttrKindE+0x1aa)[0x40080b516a]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(+0x28ea562)[0x4008725562]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(+0x28e7f16)[0x4008722f16]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(+0x27d4df6)[0x400860fdf6]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE+0x36c)[0x4008ddc46c]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/../lib/libLLVM-13-rust-1.57.0-stable.so(LLVMRunPassManager+0xa)[0x40090b1a9a]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/librustc_driver-15fe7307aff1f259.so(+0x21e2555)[0x4003e90555]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/librustc_driver-15fe7307aff1f259.so(+0x215cc34)[0x4003e0ac34]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/librustc_driver-15fe7307aff1f259.so(+0x2190d40)[0x4003e3ed40]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/librustc_driver-15fe7307aff1f259.so(+0x21c91ac)[0x4003e771ac]
/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/../lib/libstd-7c582493123fc1dd.so(rust_metadata_std_5c4e0e91f40690d7+0xaa933)[0x400594f933]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x9450)[0x4005c22450]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x43)[0x4005d64d53]
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
error: build failed

I'm using Macbook Pro with M1 pro chip. Looking forward to ARM support!

Run as a Cloudflare worker

  • Cloudflare recently added support for Wasm and offers a Rust SDK with compile target wasm32-unknown-unknown. Certain JS language features, like eval(), which are disabled in the web worker for security reasons, could run safely in the wasm sandbox as embedded js, using quickjs. Naturally, the target for wasmedge_quickjs is wasm32-wasi, given the purpose is to embed js in the wasmedge runtime.

Question about:js + wasmedge-quickjs

1. Scene

Developers use JS to write a function in the FAAS architecture, as follows:

import {xxx} from 'yyy'

function handle (request){
    //handle...
    return result
}

It is expected that Wasmedge-QuickJS will load the file and put the received request, such as http, handed over tohandle

2. What I had done

I have learned examples sub-project in wasmedge-quickjs and tried the following two options:

a. import

faas.js:

import {xxx} from 'yyy'

export function handle (request){
    //handle...
    return result
}

wasmedge-quickjs:

let code = r#"
(x) => {
  import('faas.js').then((demo)=>{
      return demo.handle(x)
  })
}
let r = ctx.eval_global_str(code);
if let crate::quickjs_sys::JsValue::Function(f) = r {
     let request = xxx;
     let response = f(request);
}
"#;

i got nothing, It's like the import statement did not execute.

b. function

faas.js:

import {xxx} from 'yyy'

function handle (request){
    //handle...
    return result
}

wasmedge-quickjs:

let code = std::fs::read_to_string("faas.js").unwrap();
let r = ctx.eval_global_str(&code);
if let crate::quickjs_sys::JsValue::Function(f) = r {
     let request = xxx;
     let response = f(request);
}

i got an error:

SyntaxError: expecting '('
    at <evalScript>:1

I found it may be related to the Import statement in the faas.js

3. Question

For my use scenario,Can you give me a suggestion?

React SSR (from book) not working anymore

I have created a new React App and am using the wasmedge quickjs docs to build another SSR demo.

When I run the App via WasmEdge like this.

wasmedge --dir .:. wasmedge_quickjs.wasm ./server-build/index.js

I get the following error

TypeError: not a function
    at <anonymous> (./server-build/index.js:7568)

The error is pointing to the following line in the machine generated index.js file that is located in the server-build dir

var u = new aa.TextEncoder();

Support `tls` Node API in wasmedge-quickjs

Motivation

In WasmEdge, we already support JavaScript, NPM packages, ES6 modules, and even using Rust to implement JS APIs.

However, one of the most commonly requested features is full node.js compatibility in WasmEdge. We can implement all node.js APIs in either JavaScript or Rust. This issue tracks this feature. Most of the code is in the wasmedge-quickjs repo

The node.js APIs can be implemented in JS (in the modules directory) and in Rust / C (in the src/internal_module directory).

This issue is to add tls API.

module_name language
tls rust/c

Support `global` Node API in wasmedge-quickjs

Motivation

In WasmEdge, we already support JavaScript, NPM packages, ES6 modules, and even using Rust to implement JS APIs.

However, one of the most commonly requested features is full node.js compatibility in WasmEdge. We can implement all node.js APIs in either JavaScript or Rust. This issue tracks this feature. Most of the code is in the wasmedge-quickjs repo

The node.js APIs can be implemented in JS (in the modules directory) and in Rust / C (in the src/internal_module directory).

This issue is to add global API.

module_name language
global rust/c

Question on Javascript example

Following the the instruction to run the example code in windows 10 environment but an error message.
_wasmedge --dir .:. ../target/wasm32-wasi/release/wasmedge_quickjs.wasm hello.js WasmEdge Runtime
error message:
[error] Bind guest directory failed:52

Could you let me know the problem? thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.