Project

quickjs

0.0
The project is in a healthy, maintained state
A native wrapper to run QuickJS in Ruby
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

 Project Readme

quickjs.rb

A Ruby wrapper for QuickJS to run JavaScript codes via Ruby with a smaller footprint.

Gem Version GitHub Actions Workflow Status

Installation

gem install quickjs
gem 'quickjs'

Usage

Quickjs.eval_code: Evaluate JavaScript code instantly

require 'quickjs'

Quickjs.eval_code('const fn = (n, pow) => n ** pow; fn(2,8);') # => 256
Quickjs.eval_code('const fn = (name) => `Hi, ${name}!`; fn("Itadori");') # => "Hi, Itadori!
Quickjs.eval_code("const isOne = (n) => 1 === n; func(1);") #=> true (TrueClass)
Quickjs.eval_code("const isOne = (n) => 1 === n; func(3);") #=> false (FalseClass)

# When code returns 'object' for `typeof`, the result is converted via JSON.stringify (JS) -> JSON.parse (Ruby)
Quickjs.eval_code("[1,2,3]") #=> [1, 2, 3] (Array)
Quickjs.eval_code("({ a: '1', b: 1 })") #=> { 'a' => '1', 'b' => 1 } (Hash)

Quickjs.eval_code("null") #=> nil
Quickjs.eval_code('const obj = {}; obj.missingKey;') # => :undefined (Quickjs::Value::Undefined)
Quickjs.eval_code("Number('whatever')") #=> :NaN (Quickjs::Value::NAN)
Options

Resources

# 1GB memory limit
Quickjs.eval_code(code, { memory_limit: 1024 ** 3 })

# 1MB max stack size
Quickjs.eval_code(code, { max_stack_size: 1024 ** 2 })

Built-in modules

To enable std module and os module selectively.

# enable std module
Quickjs.eval_code(code, { features: [Quickjs::MODULE_STD] })

# enable os module
Quickjs.eval_code(code, { features: [Quickjs::MODULE_OS] })

# enable timeout features `setTimeout`, `clearTimeout` from os module specifically
Quickjs.eval_code(code, { features: [Quickjs::FEATURES_TIMEOUT] })

Quickjs::VM: Maintain a consistent VM/runtime

vm = Quickjs::VM.new
vm.eval_code('const a = { b: "c" };')
vm.eval_code('a.b;') #=> "c"
vm.eval_code('a.b = "d";')
vm.eval_code('a.b;') #=> "d"
Config VM/runtime

Resources

vm = Quickjs::VM.new(
  memory_limit: 1024 ** 3,
  max_stack_size: 1024 ** 2,
)

Built-in modules

To enable std module and os module selectively.

# enable std module
vm = Quickjs::VM.new(features: [::Quickjs::MODULE_STD])

# enable os module
vm = Quickjs::VM.new(features: [::Quickjs::MODULE_OS])

# enable timeout features `setTimeout`, `clearTimeout`
vm = Quickjs::VM.new(features: [::Quickjs::FEATURES_TIMEOUT])

VM timeout

# `eval_code` will be interrupted after 1 sec (default: 100 msec)
vm = Quickjs::VM.new(timeout_msec: 1_000)

Quickjs::VM#import: 🔌 Import ESM from a source code

vm = Quickjs::VM.new

# Equivalent to `import { default: aliasedDefault, member: member } from './exports.esm.js';`
vm.import({ default: 'aliasedDefault', member: 'member' }, from: File.read('exports.esm.js'))

vm.eval_code("aliasedDefault()") #=> Exported `default` of the ESM is called
vm.eval_code("member()") #=> Exported `member` of the ESM is called

# import { member, defaultMember } from './exports.esm.js';
vm.import(['member', 'defaultMember'], from: File.read('exports.esm.js'))

# import DefaultExport from './exports.esm.js';
vm.import('DefaultExport', from: File.read('exports.esm.js'))

# import * as all from './exports.esm.js';
vm.import('* as all', from: File.read('exports.esm.js'))

Quickjs::VM#define_function: 💎 Define a global function for JS by Ruby

vm = Quickjs::VM.new
vm.define_function("greetingTo") do |arg1|
  ['Hello!', arg1].join(' ')
end

vm.eval_code("greetingTo('Rick')") #=> 'Hello! Rick'

Quickjs::VM#logs: 💾 Capture console logs

All logs by console.(log|info|debug|warn|error) on VM are recorded and inspectable.

vm = Quickjs::VM.new
vm.eval_code('console.log("log me", null)')

vm.logs #=> Array of Quickjs::VM::Log
vm.logs.last.severity #=> :info
vm.logs.last.to_s #=> 'log me null'
vm,logs.last.raw #=> ['log me', nil]

License

Every file in ext/quickjsrb/quickjs is licensed under the MIT License Copyright 2017-2021 by Fabrice Bellard and Charlie Goron.

For otherwise, the MIT License, Copyright 2024 by Kengo Hamasaki.