@@ -45,6 +45,31 @@ function generateRequestId(): string {
4545 return `req_${ ++ requestIdCounter } _${ Date . now ( ) } ` ;
4646}
4747
48+ // T-Ruby library files in dependency order (only core compilation files)
49+ // Excluded: lsp_server, watcher, cli, cache, package_manager, bundler_integration, benchmark, doc_generator
50+ // These require external gems (listen, etc.) not available in WASM
51+ const T_RUBY_FILES = [
52+ 't_ruby/version.rb' ,
53+ 't_ruby/config.rb' ,
54+ 't_ruby/ir.rb' ,
55+ 't_ruby/parser_combinator.rb' ,
56+ 't_ruby/smt_solver.rb' ,
57+ 't_ruby/type_alias_registry.rb' ,
58+ 't_ruby/parser.rb' ,
59+ 't_ruby/union_type_parser.rb' ,
60+ 't_ruby/generic_type_parser.rb' ,
61+ 't_ruby/intersection_type_parser.rb' ,
62+ 't_ruby/type_erasure.rb' ,
63+ 't_ruby/error_handler.rb' ,
64+ 't_ruby/rbs_generator.rb' ,
65+ 't_ruby/declaration_generator.rb' ,
66+ 't_ruby/compiler.rb' ,
67+ 't_ruby/constraint_checker.rb' ,
68+ 't_ruby/type_inferencer.rb' ,
69+ 't_ruby/runtime_validator.rb' ,
70+ 't_ruby/type_checker.rb' ,
71+ ] ;
72+
4873// Web Worker code as a string - runs in isolated thread
4974const WORKER_CODE = `
5075// Web Worker for T-Ruby WASM compilation
@@ -55,13 +80,23 @@ const RUBY_WASM_CDN = 'https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.7.1/dist/b
5580// Use Ruby 3.4 WASM binary (more stable)
5681const RUBY_WASM_BINARY = 'https://cdn.jsdelivr.net/npm/@ruby/3.4-wasm-wasi@2.7.1/dist/ruby+stdlib.wasm';
5782
83+ // T-Ruby library base URL (will be set from main thread)
84+ let T_RUBY_LIB_BASE = '';
85+
86+ // T-Ruby library files in dependency order
87+ const T_RUBY_FILES = ${ JSON . stringify ( T_RUBY_FILES ) } ;
88+
5889const BOOTSTRAP_CODE = \`
5990require "json"
6091
92+ # Define TRuby module if not already defined
93+ module TRuby
94+ end unless defined?(TRuby)
95+
6196$trb_compiler = nil
6297
6398def get_compiler
64- $trb_compiler ||= TRuby::Compiler.new
99+ $trb_compiler ||= TRuby::Compiler.new(nil, use_ir: true, optimize: false)
65100end
66101
67102def __trb_compile__(code)
@@ -88,7 +123,7 @@ def __trb_compile__(code)
88123 success: false,
89124 ruby: "",
90125 rbs: "",
91- errors: ["Compilation error: " + e.message]
126+ errors: ["Compilation error: " + e.message + " at " + e.backtrace.first.to_s ]
92127 }.to_json
93128 end
94129end
@@ -110,34 +145,72 @@ function sendToMain(type, data, requestId) {
110145 self.postMessage({ type, data, requestId });
111146}
112147
113- // Initialize Ruby VM
148+ // Fetch T-Ruby library file
149+ async function fetchTRubyFile(filename) {
150+ const url = T_RUBY_LIB_BASE + filename;
151+ const response = await fetch(url);
152+ if (!response.ok) {
153+ throw new Error('Failed to fetch ' + filename + ': ' + response.status);
154+ }
155+ return await response.text();
156+ }
157+
158+ // Initialize Ruby VM with T-Ruby library
114159async function initialize() {
115160 try {
116161 console.log('[WASM Worker] Step 1: Loading Ruby WASM module...');
117- sendToMain('progress', { message: 'Loading Ruby runtime...', progress: 10 });
162+ sendToMain('progress', { message: 'Loading Ruby runtime...', progress: 5 });
118163
119164 const { DefaultRubyVM } = await import(RUBY_WASM_CDN);
120165 console.log('[WASM Worker] Step 1 complete');
121166
122167 console.log('[WASM Worker] Step 2: Fetching WASM binary...');
123- sendToMain('progress', { message: 'Downloading Ruby WASM binary...', progress: 30 });
168+ sendToMain('progress', { message: 'Downloading Ruby WASM binary...', progress: 15 });
124169
125170 const response = await fetch(RUBY_WASM_BINARY);
126171 const wasmModule = await WebAssembly.compileStreaming(response);
127172 console.log('[WASM Worker] Step 2 complete');
128173
129174 console.log('[WASM Worker] Step 3: Initializing Ruby VM...');
130- sendToMain('progress', { message: 'Initializing Ruby VM...', progress: 60 });
175+ sendToMain('progress', { message: 'Initializing Ruby VM...', progress: 30 });
131176
132177 const result = await DefaultRubyVM(wasmModule);
133178 vm = result.vm;
134179 console.log('[WASM Worker] Step 3 complete');
135180
136- console.log('[WASM Worker] Step 4: Loading T-Ruby bootstrap...');
137- sendToMain('progress', { message: 'Loading T-Ruby compiler...', progress: 80 });
181+ console.log('[WASM Worker] Step 4: Loading T-Ruby library files...');
182+ sendToMain('progress', { message: 'Loading T-Ruby compiler...', progress: 40 });
183+
184+ // Load each T-Ruby library file
185+ const totalFiles = T_RUBY_FILES.length;
186+ for (let i = 0; i < totalFiles; i++) {
187+ const filename = T_RUBY_FILES[i];
188+ const progress = 40 + Math.floor((i / totalFiles) * 50);
189+ sendToMain('progress', { message: 'Loading ' + filename + '...', progress });
190+
191+ try {
192+ const code = await fetchTRubyFile(filename);
193+ // Remove frozen_string_literal comment and require_relative statements
194+ // since we're loading files directly
195+ const processedCode = code
196+ .replace(/# frozen_string_literal: true\\n?/g, '')
197+ .replace(/require_relative\\s+["'][^"']+["']\\n?/g, '')
198+ .replace(/require\\s+["']fileutils["']\\n?/g, '');
199+
200+ console.log('[WASM Worker] Loading:', filename);
201+ vm.eval(processedCode);
202+ } catch (err) {
203+ console.error('[WASM Worker] Error loading ' + filename + ':', err);
204+ throw err;
205+ }
206+ }
207+ console.log('[WASM Worker] Step 4 complete');
208+
209+ console.log('[WASM Worker] Step 5: Running bootstrap code...');
210+ sendToMain('progress', { message: 'Initializing compiler...', progress: 95 });
138211
139212 vm.eval(BOOTSTRAP_CODE);
140- console.log('[WASM Worker] Step 4 complete');
213+ console.log('[WASM Worker] Step 5 complete');
141214
142215 // Health check
143216 const healthResult = vm.eval('__trb_health_check__');
@@ -166,7 +239,10 @@ function compile(code, requestId) {
166239
167240 try {
168241 console.log('[WASM Worker] Compiling:', code.substring(0, 50) + '...');
169- const resultJson = vm.eval('__trb_compile__(' + JSON.stringify(code) + ')');
242+ // Use Base64 encoding to safely pass code with any special characters
243+ const base64Code = btoa(unescape(encodeURIComponent(code)));
244+ const decodeAndCompile = 'require "base64"; __trb_compile__(Base64.decode64("' + base64Code + '").force_encoding("UTF-8"))';
245+ const resultJson = vm.eval(decodeAndCompile);
170246 const result = JSON.parse(resultJson.toString());
171247 console.log('[WASM Worker] Compile result:', result);
172248 sendToMain('compile-result', result, requestId);
@@ -187,6 +263,8 @@ self.addEventListener('message', (event) => {
187263
188264 switch (type) {
189265 case 'init':
266+ // Set base URL from main thread
267+ T_RUBY_LIB_BASE = data.origin + '/t-ruby-lib/';
190268 initialize();
191269 break;
192270 case 'compile':
@@ -237,7 +315,7 @@ async function doLoadCompiler(
237315 onProgress ?.( {
238316 state : 'loading' ,
239317 message : 'Initializing compiler worker...' ,
240- progress : 5
318+ progress : 0
241319 } ) ;
242320
243321 // Create Web Worker from blob URL
@@ -257,7 +335,7 @@ async function doLoadCompiler(
257335 switch ( type ) {
258336 case 'loaded' :
259337 console . log ( '[T-Ruby] Worker loaded, sending init command...' ) ;
260- worker . postMessage ( { type : 'init' } ) ;
338+ worker . postMessage ( { type : 'init' , data : { origin : window . location . origin } } ) ;
261339 break ;
262340
263341 case 'progress' :
@@ -351,7 +429,7 @@ async function doLoadCompiler(
351429 worker . terminate ( ) ;
352430 reject ( new Error ( 'WASM worker initialization timeout' ) ) ;
353431 }
354- } , 60000 ) ; // 60 second timeout for initial load
432+ } , 120000 ) ; // 120 second timeout for initial load (loading many files)
355433
356434 // Clear timeout when ready
357435 const originalResolve = resolve ;
0 commit comments