diff --git a/README.md b/README.md index ffff3f459a..5d1c0ecab7 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,14 @@ It enables running Ruby application on browsers, WASI compatible WebAssembly run Try ruby.wasm in [TryRuby](https://try.ruby-lang.org/playground#code=puts+RUBY_DESCRIPTION&engine=cruby-3.2.0dev) in your browser. +## Quick Links + +- [[**Cheat Sheet**]](./docs/cheat_sheet.md) +- [[**FAQ**]](./docs/faq.md) +- [[**API Reference**]](https://ruby.github.io/ruby.wasm/JS.html) +- [[**Complete Examples**]](https://github.com/ruby/ruby.wasm/tree/main/packages/npm-packages/ruby-wasm-wasi/example) +- [[**Community Showcase**]](https://github.com/ruby/ruby.wasm/wiki/Showcase) + ## Quick Example: Ruby on browser Create and save `index.html` page with the following contents: @@ -17,7 +25,10 @@ Create and save `index.html` page with the following contents: ``` diff --git a/docs/cheat_sheet.md b/docs/cheat_sheet.md new file mode 100644 index 0000000000..a80707e910 --- /dev/null +++ b/docs/cheat_sheet.md @@ -0,0 +1,168 @@ +[[**Cheat Sheet**]](./cheat_sheet.md) +[[**FAQ**]](./faq.md) +[[**Complete Examples**]](https://github.com/ruby/ruby.wasm/tree/main/packages/npm-packages/ruby-wasm-wasi/example) +[[**Community Showcase**]](https://github.com/ruby/ruby.wasm/wiki/Showcase) + +# ruby.wasm Cheat Sheet + +## Node.js + +To install the package, install `@ruby/3.2-wasm-wasi` and `@ruby/wasm-wasi` from npm: + +```console +npm install --save @ruby/3.2-wasm-wasi @ruby/wasm-wasi +``` + +Then instantiate a Ruby VM by the following code: + +```javascript +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: + +```console +$ node --experimental-wasi-unstable-preview1 index.mjs +``` + +## Browser + +The easiest way to run Ruby on browser is to use `browser.script.iife.js` script from CDN: + +```html + + + + +``` + +If you want to control Ruby VM from JavaScript, you can use `@ruby/wasm-wasi` package API: + +```html + + + +``` + +## Use JavaScript from Ruby + +### Get/set JavaScript variables from Ruby + +```ruby +require "js" + +document = JS.global[:document] +document[:title] = "Hello, world!" +``` + +### Call JavaScript methods from Ruby + +```ruby +require "js" + +JS.global[:document].createElement("div") + +JS.global[:document].call(:createElement, "div".to_js) # same as above +``` + +### Pass Ruby `Proc` to JavaScript (Callback to Ruby) + +```ruby +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 +``` + +### `await` JavaScript `Promise` from Ruby + +```html + + + + +``` + +Or using `@ruby/wasm-wasi` package API: + +```html + + + +``` + +### `new` JavaScript instance from Ruby + +```ruby +require "js" + +JS.global[:Date].new(2000, 9, 13) +``` + +### Convert returned JavaScript `String` value to Ruby `String` + +```ruby +require "js" + +title = JS.global[:document].title # => JS::Object("Hello, world!") +title.to_s # => "Hello, world!" +``` + +### Convert JavaScript `Boolean` value to Ruby `true`/`false` + +```ruby +require "js" + +JS.global[:document].hasFocus? # => true +JS.global[:document].hasFocus # => JS::Object(true) +``` + +### Convert JavaScript `Number` value to Ruby `Integer`/`Float` + +```ruby +require "js" + +rand = JS.global[:Math].random # JS::Object(0.123456789) +rand.to_i # => 0 +rand.to_f # => 0.123456789 +``` diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 0000000000..2af5db9ae5 --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,25 @@ +[[**Cheat Sheet**]](./cheat_sheet.md) +[[**FAQ**]](./faq.md) +[[**API Reference**]](https://ruby.github.io/ruby.wasm/JS.html) +[[**Complete Examples**]](https://github.com/ruby/ruby.wasm/tree/main/packages/npm-packages/ruby-wasm-wasi/example) +[[**Community Showcase**]](https://github.com/ruby/ruby.wasm/wiki/Showcase) + +# FAQ + +## Where my `puts` output goes? + +By default, `puts` output goes to `STDOUT` which is a JavaScript `console.log` function. You can override it by setting `$stdout` to a Ruby object which has `write` method. + +```ruby +$stdout = Object.new.tap do |obj| + def obj.write(str) + JS.global[:document].write(str) + end +end + +puts "Hello, world!" # => Prints "Hello, world!" to the HTML document +``` + +## How to run WebAssembly in Ruby + +Use [`wasmtime` Ruby gem](https://rubygems.org/gems/wasmtime).