1- const fs = require ( "fs/promises" ) ;
2- const path = require ( "path" ) ;
3- const { WASI } = require ( "wasi" ) ;
4- const { RubyVM } = require ( "../dist/cjs/index" ) ;
1+ import * as fs from "fs/promises" ;
2+ import * as path from "path" ;
3+ import { WASI } from "wasi" ;
4+ import { RubyVM } from "../src/index" ;
5+ import * as preview2Shim from "@bytecodealliance/preview2-shim"
56
67const rubyModule = ( async ( ) => {
78 let binaryPath ;
@@ -19,7 +20,7 @@ const rubyModule = (async () => {
1920 return await WebAssembly . compile ( binary . buffer ) ;
2021} ) ( ) ;
2122
22- const initRubyVM = async ( { suppressStderr } = { suppressStderr : false } ) => {
23+ const initModuleRubyVM = async ( { suppressStderr } = { suppressStderr : false } ) => {
2324 let preopens = { } ;
2425 if ( process . env . RUBY_ROOT ) {
2526 preopens [ "/usr" ] = path . join ( process . env . RUBY_ROOT , "./usr" ) ;
@@ -30,6 +31,8 @@ const initRubyVM = async ({ suppressStderr } = { suppressStderr: false }) => {
3031 stderrFd = devNullFd . fd ;
3132 }
3233 const wasi = new WASI ( {
34+ version : "preview1" ,
35+ returnOnExit : true ,
3336 args : [ "ruby.wasm" ] . concat ( process . argv . slice ( 2 ) ) ,
3437 stderr : stderrFd ,
3538 preopens,
@@ -51,6 +54,63 @@ const initRubyVM = async ({ suppressStderr } = { suppressStderr: false }) => {
5154 return vm ;
5255} ;
5356
57+ const moduleCache = new Map ( ) ;
58+ async function initComponentRubyVM ( { suppressStderr } = { suppressStderr : false } ) {
59+ const pkgPath = process . env . RUBY_NPM_PACKAGE_ROOT
60+ if ( ! pkgPath ) {
61+ throw new Error ( "RUBY_NPM_PACKAGE_ROOT must be set" ) ;
62+ }
63+ const componentJsPath = path . resolve ( pkgPath , "dist/component/ruby.component.js" ) ;
64+ const { instantiate } = await import ( componentJsPath ) ;
65+ const getCoreModule = async ( relativePath ) => {
66+ const coreModulePath = path . resolve ( pkgPath , "dist/component" , relativePath ) ;
67+ if ( moduleCache . has ( coreModulePath ) ) {
68+ return moduleCache . get ( coreModulePath ) ;
69+ }
70+ const buffer = await fs . readFile ( coreModulePath ) ;
71+ const module = WebAssembly . compile ( buffer ) ;
72+ moduleCache . set ( coreModulePath , module ) ;
73+ return module ;
74+ }
75+ const vm = await RubyVM . _instantiate ( async ( jsRuntime ) => {
76+ const { cli, clocks, filesystem, io, random, sockets } = preview2Shim ;
77+ filesystem . _setPreopens ( { } )
78+ cli . _setArgs ( [ "ruby.wasm" ] . concat ( process . argv . slice ( 2 ) ) ) ;
79+ cli . _setCwd ( "/" )
80+ const root = await instantiate ( getCoreModule , {
81+ "ruby:js/js-runtime" : jsRuntime ,
82+ "wasi:cli/environment" : cli . environment ,
83+ "wasi:cli/exit" : cli . exit ,
84+ "wasi:cli/stderr" : cli . stderr ,
85+ "wasi:cli/stdin" : cli . stdin ,
86+ "wasi:cli/stdout" : cli . stdout ,
87+ "wasi:cli/terminal-input" : cli . terminalInput ,
88+ "wasi:cli/terminal-output" : cli . terminalOutput ,
89+ "wasi:cli/terminal-stderr" : cli . terminalStderr ,
90+ "wasi:cli/terminal-stdin" : cli . terminalStdin ,
91+ "wasi:cli/terminal-stdout" : cli . terminalStdout ,
92+ "wasi:clocks/monotonic-clock" : clocks . monotonicClock ,
93+ "wasi:clocks/wall-clock" : clocks . wallClock ,
94+ "wasi:filesystem/preopens" : filesystem . preopens ,
95+ "wasi:filesystem/types" : filesystem . types ,
96+ "wasi:io/error" : io . error ,
97+ "wasi:io/poll" : io . poll ,
98+ "wasi:io/streams" : io . streams ,
99+ "wasi:random/random" : random . random ,
100+ "wasi:sockets/tcp" : sockets . tcp ,
101+ } )
102+ return root . rubyRuntime ;
103+ } , { } )
104+ return vm ;
105+ }
106+
107+ const initRubyVM = async ( { suppressStderr } = { suppressStderr : false } ) => {
108+ if ( process . env . ENABLE_COMPONENT_TESTS && process . env . ENABLE_COMPONENT_TESTS !== 'false' ) {
109+ return initComponentRubyVM ( { suppressStderr } ) ;
110+ }
111+ return initModuleRubyVM ( { suppressStderr } ) ;
112+ }
113+
54114class RubyVersion {
55115 constructor ( version ) {
56116 this . version = version ;
0 commit comments