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
Getting Started
gem 'ruby-await-node'
Or if you want to run the latest version
gem 'ruby-await-node', :git => 'git@github.com: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