API mostly mirrors Rust version.
You can grab the latest release on Releases page.
- Files prefixed with
web-are designed to work in the browser - Files prefixes with
nodejs-are for Node.js only
Alternatively you can include web version from GitHub pages:
<script type="text/javascript" src="https://lib-ruby-parser.github.io/wasm-bindings/lib-ruby-parser.js">
</script>please note, this URL is not going to be stable or versioned. Moreover, GitHub pages always host what's in the master branch, so better use proper vendoring. This URL is for quick testing only.
If you use vendored version:
- for Node.js:
- make sure that
.wasmfile is callednodejs-lib-ruby-parser.wasm - put in the same folder as your JS file, it uses a relative hardcoded
require
- make sure that
- for web version:
- name of the
wasmfile is inferred from thejsfile, i.e. for/a/b/c.jsWASM file must be available at/a/b/c.wasm. JS file literally callsdocument.currentScript.src.replace(/.js$/, '.wasm')to get WASM file URL.
- name of the
Once both JS and WASM files are included:
- for Node.js run
const LibRubyParser = require('./path/to/nodejs-lib-ruby-parser.js') - or, in browser,
LibRubyParserbecomes globally available, however, there's an important note. In browser WASM files are loaded asynchronously, and so your code must wait for WASM code to be loaded and executed, there's a hook for that:
LibRubyParser.onLoad(() => {
// lib-ruby-parser is ready to be used
})const parserResult = LibRubyParser.parse('2 + 2')here parserResult is an instance of LibRubyParser.ParserResult class that fully mirrors Rust API. It has fields:
ast-undefined | LibRubyParser.Node,Nodeclass has a bunch of subclasses located underLibRubyParser.nodesnamespacetokens-Array<LibRubyParser.Token>, every token hastoken_type,token_value,locdiagnostics-Array<LibRubyParser.Diagnostic>, every diagnostic haslevel,message,loc. All message variants are placed underLibRubyParser.messagesnamespace, all of them are inherited fromLibRubyParser.DiagnsoticMessageclass.comments-Array<LibRubyParser.Comment>, every comment haslocationandkind.magic_comments-Array<LibRubyParser.MagicComment>, every magic comment haskind,key_l,value_linput-LibRubyParser.DecodedInputwithname,linesandbytes
It is possible to pass buffer name as the second argument, "(eval)" is the default value:
const parserResult = LibRubyParser.parse('2 + 2', 'filename.rb')It is also possible to specify custom decoder if your code has encoding different from UTF-8/ASCII-8BIT/BINARY:
function decoder(encoding, input) {
// encoding is a string taked from `# encoding: ...` magic comment
// input is a Uint8Array of raw bytes
}
const parserResult = LibRubyParser.parse('2 + 2', null, decoder);To return decoded input simply return a new Uint8Array array.
To return decoding error simply throw a string with message (that you'll later get back in .diagnostics list).
Results recoded on 10 Dec 2021:
Rust:
1.7832756400
Ruby:
4.865621000062674
WASM (Node.js):
9.535977154970169
WASM (Headless Chrome):
7.8802999999523164
To run it locally make sure to compile and test Node.js and web versions:
$ TARGET=no-modules make tests/no-modules
$ TARGET=nodejs make tests/nodejs
and run benchmarks:
$ make benchmark/compare
# prints to stdout
$ make benchmark/record
# prints to ./benchmark-out file