-
Notifications
You must be signed in to change notification settings - Fork 60
Cheat Sheet
Yuta Saito edited this page Dec 3, 2023
·
2 revisions
- See packages/npm-packages/ruby-wasm-wasi/example for complete examples.
- See Showcase for real-world use cases
To install the package, install @ruby/3.2-wasm-wasi
and @ruby/wasm-wasi
from npm:
npm install --save @ruby/3.2-wasm-wasi @ruby/wasm-wasi
Then instantiate a Ruby VM by the following code:
import fs from "fs/promises";
import { DefaultRubyVM } from "@ruby/wasm-wasi/dist/node";
const binary = await fs.readFile("./node_modules/@ruby/3.2-wasm-wasi/dist/ruby.wasm");
const module = await WebAssembly.compile(binary);
const { vm } = await DefaultRubyVM(module);
vm.eval(`puts "hello world"`);
Then run the example code with --experimental-wasi-unstable-preview1
flag to enable WASI support:
$ node --experimental-wasi-unstable-preview1 index.mjs
The easiest way to run Ruby on browser is to use browser.script.iife.js
script from CDN:
<html>
<script src="https://cdn.jsdelivr.net/npm/@ruby/3.2-wasm-wasi@2.3.0/dist/browser.script.iife.js"></script>
<script type="text/ruby">
require "js"
JS.global[:document].write "Hello, world!"
</script>
</html>
If you want to control Ruby VM from JavaScript, you can use @ruby/wasm-wasi
package API:
<html>
<script type="module">
import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.3.0/dist/esm/browser.js";
const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.2-wasm-wasi@2.3.0/dist/ruby+stdlib.wasm");
const module = await WebAssembly.compileStreaming(response);
const { vm } = await DefaultRubyVM(module);
vm.eval(`
require "js"
JS.global[:document].write "Hello, world!"
`);
</script>
</html>
require "js"
document = JS.global[:document]
document[:title] = "Hello, world!"
require "js"
JS.global[:document].createElement("div")
JS.global[:document].call(:createElement, "div".to_js) # same as above
require "js"
JS.global.setTimeout(proc { puts "Hello, world!" }, 1000)
input = JS.global[:document].querySelector("input")
input.addEventListener("change") do |event|
puts event[:target][:value].to_s
end
<html>
<script src="https://cdn.jsdelivr.net/npm/@ruby/3.2-wasm-wasi@2.3.0/dist/browser.script.iife.js"></script>
<script type="text/ruby" data-eval="async">
require "js"
response = JS.global.fetch("https://www.ruby-lang.org/").await
puts response[:status]
</script>
</html>
Or using @ruby/wasm-wasi
package API:
<html>
<script type="module">
import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.3.0/dist/esm/browser.js";
const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/3.2-wasm-wasi@2.3.0/dist/ruby+stdlib.wasm");
const module = await WebAssembly.compileStreaming(response);
const { vm } = await DefaultRubyVM(module);
vm.evalAsync(`
require "js"
response = JS.global.fetch("https://www.ruby-lang.org/").await
puts response[:status]
`);
</script>
</html>
require "js"
JS.global[:Date].new(2021, 1, 1)
require "js"
title = JS.global[:document].title # => JS::Object("Hello, world!")
title.to_s # => "Hello, world!"
require "js"
JS.global[:document].hasFocus? # => true
JS.global[:document].hasFocus # => JS::Object(true)
require "js"
rand = JS.global[:Math].random # JS::Object(0.123456789)
rand.to_i # => 0
rand.to_f # => 0.123456789