Introduction

This was inspired by https://github.com/mavenlink/alaska Unfortunately, alaska was designed to run every new script in a new sandbox, thus things like require won't work. So we don't have access to all the power offered by nodejs

Out of our need to call javascript in a rapid fashion from javascript with minimal setup, we decided to rewrite alaska into ruby-await-node with the goal of efficiently execute sophisticated javascript code from ruby.

The key to the performance is to launch a nodejs webserver, then use such webserver to dangerously eval any given javascript part.

It's risky, we know. But with great power come great responsibility. You should be using this if you want to leverage the expertise of javascript where ruby fall short

TODO For ruby-await-node

  • [x] Execute any javascript from ruby
  • [x] Pass all test
  • [x] Execute await/async method

Getting Started

gem 'ruby-await-node'

Or if you want to run the latest version

gem 'ruby-await-node', :git => '[email protected]:remitano/ruby-await-node.git'

Then to invoke some javascript

runtime = RubyAwaitNode::Runtime.new(debug: true)
context = RubyAwaitNode::Context.new(runtime)
entry_path = File.expand_path("entry.js", __dir__)
context.eval("global.actor = require(#{entry_path.to_json})")
result = context.eval("actor.method()")

Your entry.js may look like this:

const moment = require("moment")
module.exports = {
  method: function() {
    return something;
  },

  asyncMethod: async function() {
    await operation;
    return something;
  }
}

Under the hood ruby-await-node will automatically wait for async method to complete

Examples

Load a javascript file

context.load(File.expand_path("entry.js", __dir__))

Warning: always pass the absolute path

Simple execution

context.eval("1.0 + 2.0")
context.eval("global.a = 1.0")

Calling function with arguments

context.call("(function(b) { return global.a * b })", 5)

This will be equivalent to execute this in nodejs

(function(b) { return a * b }).apply(this, [5])

Other examples

Look into spec/ for other potential examples