funicular 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/README.md +12 -4
  4. data/Rakefile +29 -0
  5. data/docs/architecture.md +113 -404
  6. data/lib/funicular/assets/funicular.css +23 -0
  7. data/lib/funicular/compiler.rb +25 -18
  8. data/lib/funicular/helpers/picoruby_helper.rb +65 -3
  9. data/lib/funicular/middleware.rb +34 -9
  10. data/lib/funicular/plugin.rb +147 -0
  11. data/lib/funicular/schema.rb +167 -0
  12. data/lib/funicular/ssr/runtime.rb +101 -0
  13. data/lib/funicular/ssr.rb +51 -0
  14. data/lib/funicular/testing/node_runner.mjs +293 -0
  15. data/lib/funicular/testing/node_runner.rb +190 -0
  16. data/lib/funicular/testing.rb +22 -0
  17. data/lib/funicular/vendor/picorbc/picorbc.wasm +0 -0
  18. data/lib/funicular/vendor/picoruby/debug/picoruby.js +115 -87
  19. data/lib/funicular/vendor/picoruby/debug/picoruby.wasm +0 -0
  20. data/lib/funicular/vendor/picoruby/dist/picoruby.js +1 -1
  21. data/lib/funicular/vendor/picoruby/dist/picoruby.wasm +0 -0
  22. data/lib/funicular/vendor/picoruby-test-node/VERSION +1 -0
  23. data/lib/funicular/vendor/picoruby-test-node/picoruby.js +6908 -0
  24. data/lib/funicular/vendor/picoruby-test-node/picoruby.wasm +0 -0
  25. data/lib/funicular/vendor/picoruby-test-node/picoruby.wasm.map +1 -0
  26. data/lib/funicular/version.rb +1 -1
  27. data/lib/funicular.rb +3 -0
  28. data/lib/generators/funicular/chat/chat_generator.rb +104 -0
  29. data/lib/generators/funicular/chat/templates/application_cable_channel.rb.tt +4 -0
  30. data/lib/generators/funicular/chat/templates/application_cable_connection.rb.tt +4 -0
  31. data/lib/generators/funicular/chat/templates/create_funicular_chat_messages.rb.tt +10 -0
  32. data/lib/generators/funicular/chat/templates/funicular_chat.css.tt +141 -0
  33. data/lib/generators/funicular/chat/templates/funicular_chat_channel.rb.tt +5 -0
  34. data/lib/generators/funicular/chat/templates/funicular_chat_component.rb.tt +135 -0
  35. data/lib/generators/funicular/chat/templates/funicular_chat_component_picotest.rb.tt +64 -0
  36. data/lib/generators/funicular/chat/templates/funicular_chat_controller.rb.tt +4 -0
  37. data/lib/generators/funicular/chat/templates/funicular_chat_message.rb.tt +13 -0
  38. data/lib/generators/funicular/chat/templates/funicular_chat_messages_controller.rb.tt +23 -0
  39. data/lib/generators/funicular/chat/templates/initializer.rb.tt +4 -0
  40. data/lib/generators/funicular/chat/templates/show.html.erb.tt +6 -0
  41. data/lib/tasks/funicular.rake +87 -4
  42. data/minitest/fixtures/funicular_app/components/greeting_component.rb +16 -0
  43. data/minitest/fixtures/funicular_app/initializer.rb +5 -0
  44. data/minitest/form_for_test.rb +106 -0
  45. data/minitest/hydration_test.rb +87 -0
  46. data/minitest/plugin_test.rb +51 -0
  47. data/minitest/schema_test.rb +106 -0
  48. data/minitest/ssr_test.rb +94 -0
  49. data/minitest/validations_test.rb +183 -0
  50. data/mrbgem.rake +1 -0
  51. data/mrblib/0_validations.rb +206 -0
  52. data/mrblib/1_validators.rb +180 -0
  53. data/mrblib/cable.rb +24 -9
  54. data/mrblib/component.rb +246 -47
  55. data/mrblib/debug.rb +3 -0
  56. data/mrblib/differ.rb +47 -37
  57. data/mrblib/file_upload.rb +9 -1
  58. data/mrblib/form_builder.rb +28 -6
  59. data/mrblib/funicular.rb +97 -8
  60. data/mrblib/html_serializer.rb +121 -0
  61. data/mrblib/http.rb +123 -29
  62. data/mrblib/model.rb +50 -0
  63. data/mrblib/patcher.rb +78 -8
  64. data/mrblib/router.rb +40 -3
  65. data/mrblib/store.rb +304 -0
  66. data/mrblib/store_collection.rb +171 -0
  67. data/mrblib/store_singleton.rb +79 -0
  68. data/mrblib/vdom.rb +2 -0
  69. data/sig/cable.rbs +1 -0
  70. data/sig/component.rbs +13 -5
  71. data/sig/funicular.rbs +14 -1
  72. data/sig/html_serializer.rbs +20 -0
  73. data/sig/http.rbs +21 -6
  74. data/sig/model.rbs +6 -1
  75. data/sig/patcher.rbs +4 -1
  76. data/sig/router.rbs +3 -2
  77. data/sig/store.rbs +89 -0
  78. data/sig/store_collection.rbs +43 -0
  79. data/sig/store_singleton.rbs +19 -0
  80. data/sig/validations.rbs +103 -0
  81. data/sig/vdom.rbs +6 -6
  82. metadata +48 -12
  83. data/docs/README.md +0 -419
  84. data/docs/advanced-features.md +0 -632
  85. data/docs/components-and-state.md +0 -539
  86. data/docs/data-fetching.md +0 -528
  87. data/docs/forms.md +0 -446
  88. data/docs/rails-integration.md +0 -426
  89. data/docs/realtime.md +0 -543
  90. data/docs/routing-and-navigation.md +0 -427
  91. data/docs/styling.md +0 -285
@@ -794,6 +794,21 @@ async function createWasm() {
794
794
  var ___assert_fail = (condition, filename, line, func) =>
795
795
  abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']);
796
796
 
797
+ var wasmTableMirror = [];
798
+
799
+
800
+ var getWasmTableEntry = (funcPtr) => {
801
+ var func = wasmTableMirror[funcPtr];
802
+ if (!func) {
803
+ /** @suppress {checkTypes} */
804
+ wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
805
+ }
806
+ /** @suppress {checkTypes} */
807
+ assert(wasmTable.get(funcPtr) == func, 'JavaScript-side Wasm function table mirror is out of date!');
808
+ return func;
809
+ };
810
+ var ___call_sighandler = (fp, sig) => getWasmTableEntry(fp)(sig);
811
+
797
812
  var PATH = {
798
813
  isAbs:(path) => path.charAt(0) === '/',
799
814
  splitPath:(filename) => {
@@ -4242,6 +4257,12 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4242
4257
  var __abort_js = () =>
4243
4258
  abort('native code called abort()');
4244
4259
 
4260
+ var runtimeKeepaliveCounter = 0;
4261
+ var __emscripten_runtime_keepalive_clear = () => {
4262
+ noExitRuntime = false;
4263
+ runtimeKeepaliveCounter = 0;
4264
+ };
4265
+
4245
4266
  var __emscripten_throw_longjmp = () => {
4246
4267
  throw Infinity;
4247
4268
  };
@@ -4621,7 +4642,6 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4621
4642
  };
4622
4643
 
4623
4644
 
4624
- var runtimeKeepaliveCounter = 0;
4625
4645
  var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
4626
4646
  var _proc_exit = (code) => {
4627
4647
  EXITSTATUS = code;
@@ -4826,19 +4846,6 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4826
4846
  }
4827
4847
 
4828
4848
 
4829
- var wasmTableMirror = [];
4830
-
4831
-
4832
- var getWasmTableEntry = (funcPtr) => {
4833
- var func = wasmTableMirror[funcPtr];
4834
- if (!func) {
4835
- /** @suppress {checkTypes} */
4836
- wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
4837
- }
4838
- /** @suppress {checkTypes} */
4839
- assert(wasmTable.get(funcPtr) == func, 'JavaScript-side Wasm function table mirror is out of date!');
4840
- return func;
4841
- };
4842
4849
 
4843
4850
  var getCFunc = (ident) => {
4844
4851
  var func = Module['_' + ident]; // closure exported function
@@ -4935,6 +4942,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4935
4942
 
4936
4943
 
4937
4944
 
4945
+
4938
4946
  FS.createPreloadedFile = FS_createPreloadedFile;
4939
4947
  FS.preloadFile = FS_preloadFile;
4940
4948
  FS.staticInit();;
@@ -4990,6 +4998,7 @@ if (Module['wasmBinary']) wasmBinary = Module['wasmBinary'];
4990
4998
  Module['UTF8ToString'] = UTF8ToString;
4991
4999
  Module['stringToUTF8'] = stringToUTF8;
4992
5000
  Module['lengthBytesUTF8'] = lengthBytesUTF8;
5001
+ Module['FS'] = FS;
4993
5002
  var missingLibrarySymbols = [
4994
5003
  'writeI53ToI64',
4995
5004
  'writeI53ToI64Clamped',
@@ -5258,7 +5267,6 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
5258
5267
  'FS_createPath',
5259
5268
  'FS_createDevice',
5260
5269
  'FS_readFile',
5261
- 'FS',
5262
5270
  'FS_root',
5263
5271
  'FS_mounts',
5264
5272
  'FS_devices',
@@ -5403,21 +5411,23 @@ function checkIncomingModuleAPI() {
5403
5411
  ignoredModuleProp('loadSplitModule');
5404
5412
  }
5405
5413
  var ASM_CONSTS = {
5406
- 2552013: ($0) => { globalThis.picorubyRefs[$0] = null; },
5407
- 2552053: ($0) => { globalThis.picorubyRefs[$0] = true; },
5408
- 2552093: ($0) => { globalThis.picorubyRefs[$0] = false; },
5409
- 2552134: ($0, $1) => { globalThis.picorubyRefs[$0] = $1; },
5410
- 2552172: ($0, $1) => { globalThis.picorubyRefs[$0] = $1; },
5411
- 2552210: ($0, $1, $2) => { const str = UTF8ToString($1, $2); globalThis.picorubyRefs[$0] = str; },
5412
- 2552283: ($0, $1) => { const arr = globalThis.picorubyRefs[$0]; const elem = globalThis.picorubyRefs[$1]; arr.push(elem); delete globalThis.picorubyRefs[$1]; },
5413
- 2552422: ($0, $1, $2) => { const obj = globalThis.picorubyRefs[$0]; const key = UTF8ToString($1); const val = globalThis.picorubyRefs[$2]; obj[key] = val; delete globalThis.picorubyRefs[$2]; }
5414
+ 2639196: ($0) => { globalThis.picorubyRefs[$0] = null; },
5415
+ 2639236: ($0) => { globalThis.picorubyRefs[$0] = true; },
5416
+ 2639276: ($0) => { globalThis.picorubyRefs[$0] = false; },
5417
+ 2639317: ($0, $1) => { globalThis.picorubyRefs[$0] = $1; },
5418
+ 2639355: ($0, $1) => { globalThis.picorubyRefs[$0] = $1; },
5419
+ 2639393: ($0, $1, $2) => { const str = UTF8ToString($1, $2); globalThis.picorubyRefs[$0] = str; },
5420
+ 2639466: ($0, $1) => { const arr = globalThis.picorubyRefs[$0]; const elem = globalThis.picorubyRefs[$1]; arr.push(elem); delete globalThis.picorubyRefs[$1]; },
5421
+ 2639605: ($0, $1, $2) => { const obj = globalThis.picorubyRefs[$0]; const key = UTF8ToString($1); const val = globalThis.picorubyRefs[$2]; obj[key] = val; delete globalThis.picorubyRefs[$2]; }
5414
5422
  };
5415
5423
  function ble_dataview_length(ref_id) { try { const dv = globalThis.picorubyRefs[ref_id]; if (dv && dv.byteLength !== undefined) { return dv.byteLength; } return 0; } catch(e) { console.error('ble_dataview_length failed:', e); return 0; } }
5416
5424
  function ble_dataview_read(ref_id,out_buf,max_len) { try { const dv = globalThis.picorubyRefs[ref_id]; if (!dv) return 0; const len = Math.min(dv.byteLength, max_len); for (let i = 0; i < len; i++) { HEAPU8[out_buf + i] = dv.getUint8(i); } return len; } catch(e) { console.error('ble_dataview_read failed:', e); return 0; } }
5417
5425
  function ble_create_uint8array(data,length) { try { const buffer = new Uint8Array(HEAPU8.buffer, data, length); const copy = new Uint8Array(buffer); const refId = globalThis.picorubyRefs.push(copy) - 1; return refId; } catch(e) { console.error('ble_create_uint8array failed:', e); return -1; } }
5418
5426
  function ble_set_notify_handler(char_ref_id,callback_id) { try { const char_obj = globalThis.picorubyRefs[char_ref_id]; char_obj.addEventListener('characteristicvaluechanged', (event) => { const dataview = event.target.value; const len = dataview.byteLength; const ptr = _malloc(len); for (let i = 0; i < len; i++) { HEAPU8[ptr + i] = dataview.getUint8(i); } ccall( 'ble_notify_callback', 'void', ['number', 'number', 'number'], [callback_id, ptr, len] ); _free(ptr); }); } catch(e) { console.error('ble_set_notify_handler failed:', e); } }
5419
- function init_js_refs() { if (typeof globalThis.picorubyRefs === 'undefined') { globalThis.picorubyRefs = []; globalThis.picorubyRefs.push(window); } if (typeof window._js_remove_event_listener_wrapper === 'undefined') { window._js_remove_event_listener_wrapper = function(callback_id) { if (!globalThis.picorubyEventHandlers) return false; const info = globalThis.picorubyEventHandlers[callback_id]; if (!info) return false; info.target.removeEventListener(info.type, info.handler); delete globalThis.picorubyEventHandlers[callback_id]; return true; }; } }
5420
- function is_array_like(ref_id) { const obj = globalThis.picorubyRefs[ref_id]; return obj instanceof NodeList || obj instanceof HTMLCollection || (typeof obj === 'object' && obj !== null && 'length' in obj && typeof obj.length === 'number'); }
5427
+ function init_js_refs() { if (typeof globalThis.picorubyRefs === 'undefined') { globalThis.picorubyRefs = []; const rootObject = typeof window !== 'undefined' ? window : globalThis; globalThis.picorubyRefs.push(rootObject); } if (typeof window !== 'undefined' && typeof window._js_remove_event_listener_wrapper === 'undefined') { window._js_remove_event_listener_wrapper = function(callback_id) { if (!globalThis.picorubyEventHandlers) return false; const info = globalThis.picorubyEventHandlers[callback_id]; if (!info) return false; info.target.removeEventListener(info.type, info.handler); delete globalThis.picorubyEventHandlers[callback_id]; return true; }; } }
5428
+ function js_last_error_length() { const message = globalThis.picorubyLastError; return message ? lengthBytesUTF8(message) : 0; }
5429
+ function js_copy_last_error(buffer,buffer_size) { const message = globalThis.picorubyLastError; if (!message) { globalThis.picorubyLastError = null; return; } stringToUTF8(message, buffer, buffer_size); globalThis.picorubyLastError = null; }
5430
+ function is_array_like(ref_id) { const obj = globalThis.picorubyRefs[ref_id]; const isNodeList = typeof NodeList !== 'undefined' && obj instanceof NodeList; const isHTMLCollection = typeof HTMLCollection !== 'undefined' && obj instanceof HTMLCollection; return isNodeList || isHTMLCollection || (typeof obj === 'object' && obj !== null && 'length' in obj && typeof obj.length === 'number'); }
5421
5431
  function get_element(ref_id,index) { try { const nodeList = globalThis.picorubyRefs[ref_id]; const element = nodeList[index]; if (element === undefined) { return -1; } const newRefId = globalThis.picorubyRefs.push(element) - 1; return newRefId; } catch(e) { return -1; } }
5422
5432
  function set_property(ref_id,key,value,value_len) { try { if (!globalThis.picorubyRefs || ref_id >= globalThis.picorubyRefs.length) { console.error('Invalid reference ID:', ref_id); return false; } const obj = globalThis.picorubyRefs[ref_id]; if (!obj) { console.error('Object not found for ref_id:', ref_id); return false; } const property = UTF8ToString(key); const val = UTF8ToString(value, value_len); obj[property] = val; return true; } catch(e) { console.error('Error in set_property:', e); return false; } }
5423
5433
  function set_property_int(ref_id,key,value) { try { const obj = globalThis.picorubyRefs[ref_id]; if (!obj) return false; obj[UTF8ToString(key)] = value; return true; } catch(e) { console.error('Error in set_property_int:', e); return false; } }
@@ -5429,27 +5439,29 @@ function get_property(ref_id,key) { try { const obj = globalThis.picorubyRefs[re
5429
5439
  function get_js_type(ref_id) { try { const value = globalThis.picorubyRefs[ref_id]; const type = typeof value; if (value === null) return 1; if (value === undefined) return 0; if (type === 'boolean') return 2; if (type === 'number') return 3; if (type === 'string') return 5; if (value instanceof String) return 5; if (Array.isArray(value)) return 7; if (type === 'function') return 9; return 8; } catch(e) { console.error('Error in get_js_type (JS side):', e); return 0; } }
5430
5440
  function get_js_property_type(ref_id,property_name) { try { const obj = globalThis.picorubyRefs[ref_id]; const propName = UTF8ToString(property_name); const value = obj[propName]; const type = typeof value; if (value === null) return 1; if (value === undefined) return 0; if (type === 'boolean') return 2; if (type === 'number') return 3; if (type === 'string') return 5; if (value instanceof String) return 5; if (Array.isArray(value)) return 7; if (type === 'function') return 9; return 8; } catch(e) { return 0; } }
5431
5441
  function get_boolean_value(ref_id) { return globalThis.picorubyRefs[ref_id] ? true : false; }
5442
+ function js_classify_composite(ref_id) { try { const v = globalThis.picorubyRefs[ref_id]; if (Array.isArray(v)) return 1; if (typeof v === 'function') return 2; if (typeof Promise !== 'undefined' && v instanceof Promise) return 3; return 0; } catch(e) { return 0; } }
5443
+ function js_classify_dom(ref_id) { try { const v = globalThis.picorubyRefs[ref_id]; if (typeof Event !== 'undefined' && v instanceof Event) return 1; if (typeof Response !== 'undefined' && v instanceof Response) return 2; if (typeof Element !== 'undefined' && (v instanceof Element || (typeof Document !== 'undefined' && v instanceof Document))) return 3; return 0; } catch(e) { return 0; } }
5432
5444
  function get_number_value(ref_id) { return globalThis.picorubyRefs[ref_id]; }
5433
5445
  function get_string_value_length(ref_id) { const str = globalThis.picorubyRefs[ref_id]; return lengthBytesUTF8(str); }
5434
5446
  function copy_string_value(ref_id,buffer,buffer_size) { const str = globalThis.picorubyRefs[ref_id]; stringToUTF8(str, buffer, buffer_size); }
5435
- function js_string_equals(ref_id,ruby_str,ruby_str_len) { const js_str = globalThis.picorubyRefs[ref_id]; return js_str === UTF8ToString(ruby_str, ruby_str_len); }
5436
5447
  function get_length(ref_id) { try { const obj = globalThis.picorubyRefs[ref_id]; return obj.length || 0; } catch(e) { return -1; } }
5437
- function call_method(ref_id,method,arg,arg_len) { try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; const argString = UTF8ToString(arg, arg_len); let result; if (methodName === 'new') { result = new obj(argString); } else { if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } result = func.call(obj, argString); } const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { console.error(e); return -1; } }
5438
- function call_method_no_arg(ref_id,method) { try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } let result = func.call(obj); const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { console.error(e); return -1; } }
5439
- function call_method_no_return(ref_id,method) { try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; if (typeof func === 'function') { func.call(obj); } } catch(e) { console.error('call_method_no_return error:', e); } }
5440
- function call_method_int(ref_id,method,arg) { try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; let result; if (methodName === 'new') { result = new obj(arg); } else { if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } result = func.call(obj, arg); } const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { console.error(e); return -1; } }
5441
- function call_method_str(ref_id,method,arg1,arg1_len,arg2,arg2_len) { try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; const argString1 = UTF8ToString(arg1, arg1_len); const argString2 = UTF8ToString(arg2, arg2_len); let result; if (methodName === 'new') { result = new obj(argString1, argString2); } else { if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } result = func.call(obj, argString1, argString2); } const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { console.error(e); return -1; } }
5442
- function call_method_with_ref(ref_id,method,arg_ref_id) { try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; const argObj = globalThis.picorubyRefs[arg_ref_id]; let result; if (methodName === 'new') { result = new obj(argObj); } else { if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } result = func.call(obj, argObj); } const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { console.error(e); return -1; } }
5443
- function call_method_with_ref_ref(ref_id,method,arg_ref_1_id,arg_ref_2_id) { try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; const argObj1 = globalThis.picorubyRefs[arg_ref_1_id]; const argObj2 = globalThis.picorubyRefs[arg_ref_2_id]; let result; if (methodName === 'new') { result = new obj(argObj1, argObj2); } else { if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } result = func.call(obj, argObj1, argObj2); } const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { console.error(e); return -1; } }
5444
- function call_method_with_ref_str_str(ref_id,method,arg1_ref_id,arg2_str,arg2_len,arg3_str,arg3_len) { try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; const argObj1 = globalThis.picorubyRefs[arg1_ref_id]; const argString2 = UTF8ToString(arg2_str, arg2_len); const argString3 = UTF8ToString(arg3_str, arg3_len); if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } let result = func.call(obj, argObj1, argString2, argString3); const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { console.error('Error in call_method_with_ref_str_str:', e); return -1; } }
5445
- function call_method_with_args(ref_id,method,args_json,args_json_len) { try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } const argsStr = UTF8ToString(args_json, args_json_len); const argsData = JSON.parse(argsStr); if (!Array.isArray(argsData)) { console.error('args_json must be a JSON array'); return -1; } const args = argsData.map(arg => { switch (arg.type) { case 'string': return arg.value; case 'integer': return arg.value; case 'float': return arg.value; case 'boolean': return arg.value; case 'ref': return globalThis.picorubyRefs[arg.value]; case 'nil': return null; default: console.error('Unknown argument type:', arg.type); return null; } }); const result = func.call(obj, ...args); const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { console.error('Error in call_method_with_args:', e); return -1; } }
5446
- function call_constructor_with_args(ref_id,args_json,args_json_len) { try { const ctor = globalThis.picorubyRefs[ref_id]; if (typeof ctor !== 'function') { console.error('Object is not a constructor function'); return -1; } const argsStr = UTF8ToString(args_json, args_json_len); const argsData = JSON.parse(argsStr); if (!Array.isArray(argsData)) { console.error('args_json must be a JSON array'); return -1; } const args = argsData.map(arg => { switch (arg.type) { case 'string': return arg.value; case 'integer': return arg.value; case 'float': return arg.value; case 'boolean': return arg.value; case 'ref': return globalThis.picorubyRefs[arg.value]; case 'nil': return null; default: console.error('Unknown argument type:', arg.type); return null; } }); const result = new ctor(...args); const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { console.error('Error in call_constructor_with_args:', e); return -1; } }
5447
- function call_fetch_with_json_options(ref_id,url,options_json) { try { const obj = globalThis.picorubyRefs[ref_id]; const urlStr = UTF8ToString(url); const optionsStr = UTF8ToString(options_json); const options = JSON.parse(optionsStr); const result = obj.fetch(urlStr, options); const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { console.error(e); return -1; } }
5448
- function setup_promise_handler(promise_id,callback_id,mrb_ptr,task_ptr) { const promise = globalThis.picorubyRefs[promise_id]; promise.then( (result) => { const resultId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); ccall( 'resume_promise_task', 'void', ['number', 'number', 'number', 'number'], [mrb_ptr, task_ptr, callback_id, resultId] ); } ); }
5448
+ function call_method(ref_id,method,arg,arg_len) { globalThis.picorubyLastError = null; try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; const argString = UTF8ToString(arg, arg_len); let result; if (methodName === 'new') { result = new obj(argString); } else { if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } result = func.call(obj, argString); } const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { globalThis.picorubyLastError = e && typeof e.message === 'string' ? e.message : String(e); return -1; } }
5449
+ function call_method_no_arg(ref_id,method) { globalThis.picorubyLastError = null; try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } let result = func.call(obj); const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { globalThis.picorubyLastError = e && typeof e.message === 'string' ? e.message : String(e); return -1; } }
5450
+ function call_method_no_return(ref_id,method) { globalThis.picorubyLastError = null; try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; if (typeof func === 'function') { func.call(obj); } } catch(e) { globalThis.picorubyLastError = e && typeof e.message === 'string' ? e.message : String(e); } }
5451
+ function call_method_int(ref_id,method,arg) { globalThis.picorubyLastError = null; try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; let result; if (methodName === 'new') { result = new obj(arg); } else { if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } result = func.call(obj, arg); } const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { globalThis.picorubyLastError = e && typeof e.message === 'string' ? e.message : String(e); return -1; } }
5452
+ function call_method_str(ref_id,method,arg1,arg1_len,arg2,arg2_len) { globalThis.picorubyLastError = null; try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; const argString1 = UTF8ToString(arg1, arg1_len); const argString2 = UTF8ToString(arg2, arg2_len); let result; if (methodName === 'new') { result = new obj(argString1, argString2); } else { if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } result = func.call(obj, argString1, argString2); } const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { globalThis.picorubyLastError = e && typeof e.message === 'string' ? e.message : String(e); return -1; } }
5453
+ function call_method_with_ref(ref_id,method,arg_ref_id) { globalThis.picorubyLastError = null; try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; const argObj = globalThis.picorubyRefs[arg_ref_id]; let result; if (methodName === 'new') { result = new obj(argObj); } else { if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } result = func.call(obj, argObj); } const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { globalThis.picorubyLastError = e && typeof e.message === 'string' ? e.message : String(e); return -1; } }
5454
+ function call_method_with_ref_ref(ref_id,method,arg_ref_1_id,arg_ref_2_id) { globalThis.picorubyLastError = null; try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; const argObj1 = globalThis.picorubyRefs[arg_ref_1_id]; const argObj2 = globalThis.picorubyRefs[arg_ref_2_id]; let result; if (methodName === 'new') { result = new obj(argObj1, argObj2); } else { if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } result = func.call(obj, argObj1, argObj2); } const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { globalThis.picorubyLastError = e && typeof e.message === 'string' ? e.message : String(e); return -1; } }
5455
+ function call_method_with_ref_str_str(ref_id,method,arg1_ref_id,arg2_str,arg2_len,arg3_str,arg3_len) { globalThis.picorubyLastError = null; try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; const argObj1 = globalThis.picorubyRefs[arg1_ref_id]; const argString2 = UTF8ToString(arg2_str, arg2_len); const argString3 = UTF8ToString(arg3_str, arg3_len); if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } let result = func.call(obj, argObj1, argString2, argString3); const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { globalThis.picorubyLastError = e && typeof e.message === 'string' ? e.message : String(e); return -1; } }
5456
+ function call_method_with_args(ref_id,method,args_json,args_json_len) { globalThis.picorubyLastError = null; try { const obj = globalThis.picorubyRefs[ref_id]; const methodName = UTF8ToString(method); const func = obj[methodName]; if (typeof func !== 'function') { console.error('Method not found or not a function:', methodName); return -1; } const argsStr = UTF8ToString(args_json, args_json_len); const argsData = JSON.parse(argsStr); if (!Array.isArray(argsData)) { console.error('args_json must be a JSON array'); return -1; } const args = argsData.map(arg => { switch (arg.type) { case 'string': return arg.value; case 'integer': return arg.value; case 'float': return arg.value; case 'boolean': return arg.value; case 'ref': return globalThis.picorubyRefs[arg.value]; case 'nil': return null; default: console.error('Unknown argument type:', arg.type); return null; } }); const result = func.call(obj, ...args); const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { globalThis.picorubyLastError = e && typeof e.message === 'string' ? e.message : String(e); return -1; } }
5457
+ function call_constructor_with_args(ref_id,args_json,args_json_len) { globalThis.picorubyLastError = null; try { const ctor = globalThis.picorubyRefs[ref_id]; if (typeof ctor !== 'function') { console.error('Object is not a constructor function'); return -1; } const argsStr = UTF8ToString(args_json, args_json_len); const argsData = JSON.parse(argsStr); if (!Array.isArray(argsData)) { console.error('args_json must be a JSON array'); return -1; } const args = argsData.map(arg => { switch (arg.type) { case 'string': return arg.value; case 'integer': return arg.value; case 'float': return arg.value; case 'boolean': return arg.value; case 'ref': return globalThis.picorubyRefs[arg.value]; case 'nil': return null; default: console.error('Unknown argument type:', arg.type); return null; } }); const result = new ctor(...args); const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { globalThis.picorubyLastError = e && typeof e.message === 'string' ? e.message : String(e); return -1; } }
5458
+ function js_function_apply_args(func_ref_id,args_json,args_json_len) { globalThis.picorubyLastError = null; try { const fn = globalThis.picorubyRefs[func_ref_id]; if (typeof fn !== 'function') { console.error('js_function_apply_args: not a function'); return -1; } const argsData = JSON.parse(UTF8ToString(args_json, args_json_len)); if (!Array.isArray(argsData)) { console.error('js_function_apply_args: args_json must be a JSON array'); return -1; } const args = argsData.map(arg => { switch (arg.type) { case 'string': case 'integer': case 'float': case 'boolean': return arg.value; case 'ref': return globalThis.picorubyRefs[arg.value]; case 'nil': return null; default: return null; } }); const result = fn(...args); const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { globalThis.picorubyLastError = e && typeof e.message === 'string' ? e.message : String(e); return -1; } }
5459
+ function call_fetch_with_json_options(ref_id,url,options_json) { globalThis.picorubyLastError = null; try { const obj = globalThis.picorubyRefs[ref_id]; const urlStr = UTF8ToString(url); const optionsStr = UTF8ToString(options_json); const options = JSON.parse(optionsStr); const result = obj.fetch(urlStr, options); const newRefId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return newRefId; } catch(e) { globalThis.picorubyLastError = e && typeof e.message === 'string' ? e.message : String(e); return -1; } }
5460
+ function setup_promise_handler(promise_id,callback_id,mrb_ptr,task_ptr) { const promise = globalThis.picorubyRefs[promise_id]; promise.then( (result) => { const resultId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); ccall( 'resume_promise_task', 'void', ['number', 'number', 'number', 'number'], [mrb_ptr, task_ptr, callback_id, resultId] ); } ).catch( (error) => { const message = error && typeof error.message === 'string' ? error.message : String(error); const size = lengthBytesUTF8(message) + 1; const errorPtr = _malloc(size); stringToUTF8(message, errorPtr, size); ccall( 'resume_promise_error_task', 'void', ['number', 'number', 'number', 'number'], [mrb_ptr, task_ptr, callback_id, errorPtr] ); } ); }
5449
5461
  function js_add_event_listener(ref_id,callback_id,event_type) { const target = globalThis.picorubyRefs[ref_id]; const type = UTF8ToString(event_type); const handler = (event) => { if (!globalThis.picorubyEventHandlers || !globalThis.picorubyEventHandlers[callback_id]) { return; } if (type === 'submit' || (type === 'click' && target.tagName === 'A')) { event.preventDefault(); } const eventRefId = globalThis.picorubyRefs.push(event) - 1; ccall( 'call_ruby_callback', 'void', ['number', 'number'], [callback_id, eventRefId] ); }; target.addEventListener(type, handler); if (!globalThis.picorubyEventHandlers) { globalThis.picorubyEventHandlers = {}; } globalThis.picorubyEventHandlers[callback_id] = { target, type, handler }; }
5450
5462
  function js_register_generic_callback(callback_id,callback_name) { const name = UTF8ToString(callback_name); if (!globalThis.picorubyGenericCallbacks) { globalThis.picorubyGenericCallbacks = {}; } globalThis.picorubyGenericCallbacks[name] = function(...args) { const argRefIds = args.map(arg => { const refId = globalThis.picorubyRefs.push(arg) - 1; return refId; }); const argRefIdsPtr = _malloc(argRefIds.length * 4); for (let i = 0; i < argRefIds.length; i++) { HEAP32[(argRefIdsPtr >> 2) + i] = argRefIds[i]; } const resultRefId = ccall( 'call_ruby_callback_sync_generic', 'number', ['number', 'number', 'number'], [callback_id, argRefIdsPtr, argRefIds.length] ); _free(argRefIdsPtr); if (resultRefId >= 0 && resultRefId < globalThis.picorubyRefs.length) { return globalThis.picorubyRefs[resultRefId]; } return undefined; }; }
5451
5463
  function js_create_callback_function(callback_id) { try { const fn = function(...args) { const argRefIds = args.map(arg => globalThis.picorubyRefs.push(arg) - 1); const argRefIdsPtr = _malloc(argRefIds.length * 4); for (let i = 0; i < argRefIds.length; i++) { HEAP32[(argRefIdsPtr >> 2) + i] = argRefIds[i]; } const resultRefId = ccall( 'call_ruby_callback_sync_generic', 'number', ['number', 'number', 'number'], [callback_id, argRefIdsPtr, argRefIds.length] ); _free(argRefIdsPtr); if (resultRefId >= 0 && resultRefId < globalThis.picorubyRefs.length) { return globalThis.picorubyRefs[resultRefId]; } return undefined; }; return globalThis.picorubyRefs.push(fn) - 1; } catch (e) { console.error('js_create_callback_function failed:', e); return -1; } }
5452
- function js_set_timeout(callback_id,delay_ms) { const timerId = setTimeout(function() { if (!globalThis.picorubyTimeoutHandlers || !globalThis.picorubyTimeoutHandlers[callback_id]) { return; } ccall( 'call_ruby_callback', 'void', ['number', 'number'], [callback_id, -1] ); delete globalThis.picorubyTimeoutHandlers[callback_id]; }, delay_ms); if (!globalThis.picorubyTimeoutHandlers) { globalThis.picorubyTimeoutHandlers = {}; } globalThis.picorubyTimeoutHandlers[callback_id] = timerId; return timerId; }
5464
+ function js_set_timeout(callback_id,delay_ms) { const timerId = setTimeout(function() { if (!globalThis.picorubyTimeoutHandlers || !globalThis.picorubyTimeoutHandlers[callback_id]) { return; } ccall( 'call_ruby_callback_oneshot', 'void', ['number', 'number'], [callback_id, -1] ); delete globalThis.picorubyTimeoutHandlers[callback_id]; }, delay_ms); if (!globalThis.picorubyTimeoutHandlers) { globalThis.picorubyTimeoutHandlers = {}; } globalThis.picorubyTimeoutHandlers[callback_id] = timerId; return timerId; }
5453
5465
  function js_clear_timeout(callback_id) { try { if (!globalThis.picorubyTimeoutHandlers) return false; const timerId = globalThis.picorubyTimeoutHandlers[callback_id]; if (timerId === undefined) return false; clearTimeout(timerId); delete globalThis.picorubyTimeoutHandlers[callback_id]; return true; } catch(e) { console.error('Error in js_clear_timeout:', e); return false; } }
5454
5466
  function js_remove_event_listener(callback_id) { try { if (!globalThis.picorubyEventHandlers) return false; const info = globalThis.picorubyEventHandlers[callback_id]; if (!info) return false; info.target.removeEventListener(info.type, info.handler); delete globalThis.picorubyEventHandlers[callback_id]; return true; } catch(e) { console.error('Error in js_remove_event_listener:', e); return false; } }
5455
5467
  function js_create_element(tag_name) { try { const element = document.createElement(UTF8ToString(tag_name)); const refId = globalThis.picorubyRefs.push(element) - 1; return refId; } catch(e) { console.error('Error in js_create_element:', e); return -1; } }
@@ -5466,13 +5478,18 @@ function setup_binary_handler(ref_id,mrb_ptr,task_ptr,callback_id) { const respo
5466
5478
  function init_js_type_offsets(type_offset,value_offset,is_integer_offset,string_value_offset) { globalThis.JS_TYPE_INFO_OFFSETS = { type: type_offset, value: value_offset, is_integer: is_integer_offset, string_value: string_value_offset }; }
5467
5479
  function js_get_type_info(ref_id,info) { const value = globalThis.picorubyRefs[ref_id]; const offsets = globalThis.JS_TYPE_INFO_OFFSETS; let type = typeof value; if (value === null) { HEAP32[info + offsets.type >> 2] = 1; HEAP32[info + offsets.string_value >> 2] = 0; } else if (Array.isArray(value)) { HEAP32[info + offsets.type >> 2] = 7; HEAP32[info + offsets.value >> 2] = value.length; HEAP32[info + offsets.string_value >> 2] = 0; } else { switch(type) { case "undefined": HEAP32[info + offsets.type >> 2] = 0; HEAP32[info + offsets.string_value >> 2] = 0; break; case "boolean": HEAP32[info + offsets.type >> 2] = 2; HEAPU8[info + offsets.value] = value ? 1 : 0; HEAP32[info + offsets.string_value >> 2] = 0; break; case "number": HEAP32[info + offsets.type >> 2] = 3; HEAPF64[info + offsets.value >> 3] = value; HEAPU8[info + offsets.is_integer] = Number.isInteger(value) ? 1 : 0; HEAP32[info + offsets.string_value >> 2] = 0; break; case "bigint": case "string": case "symbol": { HEAP32[info + offsets.type >> 2] = type === "bigint" ? 4 : type === "string" ? 5 : 6; const str = type === "symbol" ? (value.description || "") : value.toString(); const length = lengthBytesUTF8(str) + 1; const ptr = _malloc(length); stringToUTF8(str, ptr, length); HEAP32[info + offsets.string_value >> 2] = ptr; break; } case "object": HEAP32[info + offsets.type >> 2] = 8; HEAP32[info + offsets.string_value >> 2] = 0; break; case "function": HEAP32[info + offsets.type >> 2] = 9; HEAP32[info + offsets.string_value >> 2] = 0; break; } } }
5468
5480
  function js_eval(script) { try { var result = (0, eval)(UTF8ToString(script)); if (result === undefined || result === null) return -1; var refId = globalThis.picorubyRefs.length; globalThis.picorubyRefs.push(result); return refId; } catch(e) { console.error('JS.eval error:', e); return -1; } }
5469
- function regexp_new(pattern,flags) { try { var re = new RegExp(UTF8ToString(pattern), UTF8ToString(flags)); return globalThis.picorubyRefs.push(re) - 1; } catch(e) { console.error('RegExp creation failed:', e); return -1; } }
5481
+ function js_inspect_to_buffer(ref_id,buf,buf_size) { function clip(s, max) { if (s.length > max) return s.slice(0, max - 3) + '...'; return s; } function previewValue(val) { if (val === null) return 'null'; if (val === undefined) return 'undefined'; const t = typeof val; if (t === 'string') return JSON.stringify(val); if (t === 'number' || t === 'boolean') return String(val); if (t === 'bigint') return val.toString() + 'n'; if (t === 'symbol') return val.toString(); if (t === 'function') return 'function'; return '...'; } let result; try { const v = globalThis.picorubyRefs[ref_id]; if (v === null) { result = 'null'; } else if (v === undefined) { result = 'undefined'; } else if (typeof v === 'string') { result = 'String ' + clip(JSON.stringify(v), 120); } else if (typeof v === 'number') { result = 'Number ' + String(v); } else if (typeof v === 'boolean') { result = 'Boolean ' + (v ? 'true' : 'false'); } else if (typeof v === 'bigint') { result = 'BigInt ' + v.toString() + 'n'; } else if (typeof v === 'symbol') { result = 'Symbol ' + v.toString(); } else if (typeof v === 'function') { const name = v.name && v.name.length > 0 ? v.name : '(anonymous)'; result = 'Function ' + name; } else if (Array.isArray(v)) { const len = v.length; const sample = v.slice(0, 5).map(previewValue).join(','); const preview = len > 5 ? '[' + sample + ',...]' : '[' + sample + ']'; result = 'Array length=' + len + ' ' + clip(preview, 120); } else { let ctor = 'Object'; try { if (v.constructor && v.constructor.name) ctor = v.constructor.name; } catch (e) {} let extras = ""; try { if (typeof Event !== 'undefined' && v instanceof Event) { if (v.type) extras += ' type=' + JSON.stringify(String(v.type)); } else if (typeof Response !== 'undefined' && v instanceof Response) { if (v.status !== undefined) extras += ' status=' + v.status; if (v.url) extras += ' url=' + JSON.stringify(String(v.url)); } else if (typeof Element !== 'undefined' && v instanceof Element) { if (v.id) extras += ' id=' + JSON.stringify(String(v.id)); const cls = v.getAttribute && v.getAttribute('class'); if (cls) extras += ' class=' + JSON.stringify(String(cls)); } else { const keys = Object.keys(v).slice(0, 3); if (keys.length > 0) { const items = keys.map(function(k) { return k + '=' + previewValue(v[k]); }); extras = ' ' + items.join(' '); if (Object.keys(v).length > 3) extras += ' ...'; } } } catch (e) {} result = ctor + extras; } } catch (e) { result = '<inspect error: ' + (e && e.message ? e.message : 'unknown') + '>'; } if (buf_size > 0) { if (result.length > buf_size - 1) { result = result.slice(0, buf_size - 4) + '...'; } stringToUTF8(result, buf, buf_size); } }
5482
+ function regexp_new(pattern,flags) { try { var flagStr = UTF8ToString(flags); if (flagStr.indexOf('d') < 0) flagStr += 'd'; if (flagStr.indexOf('u') < 0) flagStr += 'u'; var re = new RegExp(UTF8ToString(pattern), flagStr); return globalThis.picorubyRefs.push(re) - 1; } catch(e) { console.error('RegExp creation failed:', e); return -1; } }
5470
5483
  function regexp_test(ref_id,str,str_len) { try { var re = globalThis.picorubyRefs[ref_id]; re.lastIndex = 0; return re.test(UTF8ToString(str, str_len)) ? 1 : 0; } catch(e) { return 0; } }
5471
- function regexp_exec(ref_id,str,str_len) { try { var re = globalThis.picorubyRefs[ref_id]; re.lastIndex = 0; var result = re.exec(UTF8ToString(str, str_len)); if (result === null) return -1; return globalThis.picorubyRefs.push(result) - 1; } catch(e) { return -1; } }
5472
- function regexp_match_index(ref_id) { var result = globalThis.picorubyRefs[ref_id]; return result.index; }
5473
- function regexp_match_length(ref_id) { var result = globalThis.picorubyRefs[ref_id]; return result.length; }
5474
- function regexp_match_item(ref_id,idx) { var result = globalThis.picorubyRefs[ref_id]; var item = result[idx]; if (item === undefined) return 0; var len = lengthBytesUTF8(item) + 1; var ptr = _malloc(len); stringToUTF8(item, ptr, len); return ptr; }
5475
- function regexp_match_item_is_undefined(ref_id,idx) { var result = globalThis.picorubyRefs[ref_id]; return (result[idx] === undefined) ? 1 : 0; }
5484
+ function regexp_exec(ref_id,str,str_len,base_byte,base_char) { try { var re = globalThis.picorubyRefs[ref_id]; re.lastIndex = 0; var jsStr = UTF8ToString(str, str_len); var result = re.exec(jsStr); if (result === null) return -1; var entries = []; for (var i = 0; i < result.length; i++) { var item = result[i]; if (item === undefined) { entries.push(null); continue; } var startU16, endU16; if (i === 0) { startU16 = result.index; endU16 = result.index + item.length; } else if (result.indices && result.indices[i]) { startU16 = result.indices[i][0]; endU16 = result.indices[i][1]; } else { startU16 = jsStr.indexOf(item, result.index); endU16 = startU16 < 0 ? -1 : startU16 + item.length; } var prefix = jsStr.slice(0, startU16); var matchPart = jsStr.slice(startU16, endU16); var byteStart = lengthBytesUTF8(prefix); var byteLen = lengthBytesUTF8(matchPart); var charStart = 0; for (var _c1 of prefix) charStart++; var charLen = 0; for (var _c2 of matchPart) charLen++; entries.push({ byteStart: base_byte + byteStart, byteEnd: base_byte + byteStart + byteLen, charStart: base_char + charStart, charEnd: base_char + charStart + charLen, text: item }); } var info = { entries: entries, length: result.length }; return globalThis.picorubyRefs.push(info) - 1; } catch(e) { console.error('RegExp exec failed:', e); return -1; } }
5485
+ function regexp_match_length(ref_id) { var info = globalThis.picorubyRefs[ref_id]; return info.length; }
5486
+ function regexp_match_byte_begin(ref_id,idx) { var info = globalThis.picorubyRefs[ref_id]; var e = info.entries[idx]; return (e == null) ? -1 : e.byteStart; }
5487
+ function regexp_match_byte_end(ref_id,idx) { var info = globalThis.picorubyRefs[ref_id]; var e = info.entries[idx]; return (e == null) ? -1 : e.byteEnd; }
5488
+ function regexp_match_char_begin(ref_id,idx) { var info = globalThis.picorubyRefs[ref_id]; var e = info.entries[idx]; return (e == null) ? -1 : e.charStart; }
5489
+ function regexp_match_char_end(ref_id,idx) { var info = globalThis.picorubyRefs[ref_id]; var e = info.entries[idx]; return (e == null) ? -1 : e.charEnd; }
5490
+ function regexp_match_item(ref_id,idx) { var info = globalThis.picorubyRefs[ref_id]; var e = info.entries[idx]; if (e == null) return 0; var item = e.text; if (item === undefined) return 0; var len = lengthBytesUTF8(item) + 1; var ptr = _malloc(len); stringToUTF8(item, ptr, len); return ptr; }
5491
+ function regexp_match_item_is_undefined(ref_id,idx) { var info = globalThis.picorubyRefs[ref_id]; var e = info.entries[idx]; return (e == null) ? 1 : 0; }
5492
+ function regexp_release_ref(ref_id) { if (globalThis.picorubyRefs && ref_id >= 0 && ref_id < globalThis.picorubyRefs.length) { globalThis.picorubyRefs[ref_id] = null; } }
5476
5493
  function regexp_source(ref_id) { var re = globalThis.picorubyRefs[ref_id]; var str = re.source; var len = lengthBytesUTF8(str) + 1; var ptr = _malloc(len); stringToUTF8(str, ptr, len); return ptr; }
5477
5494
  function regexp_flags(ref_id) { var re = globalThis.picorubyRefs[ref_id]; var str = re.flags; var len = lengthBytesUTF8(str) + 1; var ptr = _malloc(len); stringToUTF8(str, ptr, len); return ptr; }
5478
5495
  function serial_write(ref_id,data,len) { try { const port = globalThis.picorubyRefs[ref_id]; if (!port || !port.writable) { console.error('serial_write: port not writable'); return; } if (!globalThis.picorubySerialWriteQueues) { globalThis.picorubySerialWriteQueues = Object.create(null); } const bytes = new Uint8Array(HEAPU8.buffer, data, len).slice(); const key = String(ref_id); const prev = globalThis.picorubySerialWriteQueues[key] || Promise.resolve(); const next = prev.then(async () => { const writer = port.writable.getWriter(); try { await writer.write(bytes); } finally { writer.releaseLock(); } }).catch((e) => { console.error('serial_write queue failed:', e); }); globalThis.picorubySerialWriteQueues[key] = next; } catch(e) { console.error('serial_write failed:', e); } }
@@ -5498,10 +5515,13 @@ function ws_close(ref_id) { try { const ws = globalThis.picorubyRefs[ref_id]; if
5498
5515
  function ws_ready_state(ref_id) { try { const ws = globalThis.picorubyRefs[ref_id]; if (ws) { return ws.readyState; } return -1; } catch(e) { return -1; } }
5499
5516
  function ws_set_binary_type(ref_id,type) { try { const ws = globalThis.picorubyRefs[ref_id]; if (ws) { ws.binaryType = UTF8ToString(type); } } catch(e) { console.error('WebSocket set_binary_type failed:', e); } }
5500
5517
  function ws_get_binary_type(ref_id,buffer,buffer_size) { try { const ws = globalThis.picorubyRefs[ref_id]; if (ws && ws.binaryType) { const type = ws.binaryType; const bytes = lengthBytesUTF8(type) + 1; if (bytes <= buffer_size) { stringToUTF8(type, buffer, buffer_size); return bytes - 1; } } return 0; } catch(e) { return 0; } }
5501
- function ws_set_onopen(ref_id,callback_id) { const ws = globalThis.picorubyRefs[ref_id]; ws.onopen = (event) => { const eventRefId = globalThis.picorubyRefs.push(event) - 1; ccall( 'call_ruby_callback', 'void', ['number', 'number'], [callback_id, eventRefId] ); }; }
5518
+ function ws_set_onopen(ref_id,callback_id) { const ws = globalThis.picorubyRefs[ref_id]; ws.onopen = (event) => { const eventRefId = globalThis.picorubyRefs.push(event) - 1; ccall( 'call_ruby_callback_oneshot', 'void', ['number', 'number'], [callback_id, eventRefId] ); }; }
5502
5519
  function ws_set_onmessage(ref_id,callback_id) { const ws = globalThis.picorubyRefs[ref_id]; ws.onmessage = (event) => { let data = event.data; if (data instanceof ArrayBuffer) { const uint8Array = new Uint8Array(data); const length = uint8Array.length; const ptr = _malloc(length); HEAPU8.set(uint8Array, ptr); ccall( 'call_ruby_callback_with_binary_data', 'void', ['number', 'number', 'number'], [callback_id, ptr, length] ); } else { const eventRefId = globalThis.picorubyRefs.push(event) - 1; ccall( 'call_ruby_callback', 'void', ['number', 'number'], [callback_id, eventRefId] ); } }; }
5503
- function ws_set_onerror(ref_id,callback_id) { const ws = globalThis.picorubyRefs[ref_id]; ws.onerror = (event) => { const eventRefId = globalThis.picorubyRefs.push(event) - 1; ccall( 'call_ruby_callback', 'void', ['number', 'number'], [callback_id, eventRefId] ); }; }
5504
- function ws_set_onclose(ref_id,callback_id) { const ws = globalThis.picorubyRefs[ref_id]; ws.onclose = (event) => { const eventRefId = globalThis.picorubyRefs.push(event) - 1; ccall( 'call_ruby_callback', 'void', ['number', 'number'], [callback_id, eventRefId] ); }; }
5520
+ function ws_set_onerror(ref_id,callback_id) { const ws = globalThis.picorubyRefs[ref_id]; ws.onerror = (event) => { const eventRefId = globalThis.picorubyRefs.push(event) - 1; ccall( 'call_ruby_callback_oneshot', 'void', ['number', 'number'], [callback_id, eventRefId] ); }; }
5521
+ function ws_set_onclose(ref_id,callback_id) { const ws = globalThis.picorubyRefs[ref_id]; ws.onclose = (event) => { const eventRefId = globalThis.picorubyRefs.push(event) - 1; ccall( 'call_ruby_callback_oneshot', 'void', ['number', 'number'], [callback_id, eventRefId] ); }; }
5522
+ function idb_request_to_promise(req_ref_id) { try { const req = globalThis.picorubyRefs[req_ref_id]; if (!req) { console.error('idb_request_to_promise: invalid ref_id', req_ref_id); return -1; } const promise = new Promise((resolve, reject) => { req.onsuccess = () => { resolve(req.result); }; req.onerror = () => { const msg = (req.error && req.error.message) || 'IDB request failed'; reject(new Error(msg)); }; }); return globalThis.picorubyRefs.push(promise) - 1; } catch (e) { console.error('idb_request_to_promise failed:', e); return -1; } }
5523
+ function idb_open_with_upgrade(name_ptr,version,callback_id) { try { const name = UTF8ToString(name_ptr); const idb = globalThis.indexedDB; if (!idb) { console.error('idb_open_with_upgrade: indexedDB unavailable'); return -1; } const req = (version > 0) ? idb.open(name, version) : idb.open(name); req.onupgradeneeded = (event) => { if (callback_id === 0) return; const db = req.result; const oldV = event.oldVersion; const newV = event.newVersion; const dbRef = globalThis.picorubyRefs.push(db) - 1; const oldRef = globalThis.picorubyRefs.push(oldV) - 1; const newRef = globalThis.picorubyRefs.push(newV) - 1; const argRefIds = [dbRef, oldRef, newRef]; const argRefIdsPtr = _malloc(argRefIds.length * 4); for (let i = 0; i < argRefIds.length; i++) { HEAP32[(argRefIdsPtr >> 2) + i] = argRefIds[i]; } try { ccall( 'call_ruby_callback_sync_generic', 'number', ['number', 'number', 'number'], [callback_id, argRefIdsPtr, argRefIds.length] ); } catch (e) { console.error('idb upgrade callback threw:', e); } finally { _free(argRefIdsPtr); } }; const promise = new Promise((resolve, reject) => { req.onsuccess = () => { resolve(req.result); }; req.onerror = () => { const msg = (req.error && req.error.message) || 'IDB open failed'; reject(new Error(msg)); }; req.onblocked = () => { reject(new Error('IDB open blocked: another connection holds an older version')); }; }); return globalThis.picorubyRefs.push(promise) - 1; } catch (e) { console.error('idb_open_with_upgrade failed:', e); return -1; } }
5524
+ function idb_transaction_to_promise(tx_ref_id) { try { const tx = globalThis.picorubyRefs[tx_ref_id]; if (!tx) { console.error('idb_transaction_to_promise: invalid ref_id', tx_ref_id); return -1; } const promise = new Promise((resolve, reject) => { tx.oncomplete = () => { resolve(true); }; tx.onerror = () => { const msg = (tx.error && tx.error.message) || 'IDB transaction error'; reject(new Error(msg)); }; tx.onabort = () => { const msg = (tx.error && tx.error.message) || 'IDB transaction aborted'; reject(new Error(msg)); }; }); return globalThis.picorubyRefs.push(promise) - 1; } catch (e) { console.error('idb_transaction_to_promise failed:', e); return -1; } }
5505
5525
  function emscripten_date_now() { return Date.now(); }
5506
5526
 
5507
5527
  // Imports from the Wasm binary.
@@ -5518,7 +5538,9 @@ var _mrb_debug_step = Module['_mrb_debug_step'] = makeInvalidEarlyAccess('_mrb_d
5518
5538
  var _mrb_debug_next = Module['_mrb_debug_next'] = makeInvalidEarlyAccess('_mrb_debug_next');
5519
5539
  var _mrb_debug_get_callstack = Module['_mrb_debug_get_callstack'] = makeInvalidEarlyAccess('_mrb_debug_get_callstack');
5520
5540
  var _call_ruby_callback = Module['_call_ruby_callback'] = makeInvalidEarlyAccess('_call_ruby_callback');
5541
+ var _call_ruby_callback_oneshot = Module['_call_ruby_callback_oneshot'] = makeInvalidEarlyAccess('_call_ruby_callback_oneshot');
5521
5542
  var _resume_promise_task = Module['_resume_promise_task'] = makeInvalidEarlyAccess('_resume_promise_task');
5543
+ var _resume_promise_error_task = Module['_resume_promise_error_task'] = makeInvalidEarlyAccess('_resume_promise_error_task');
5522
5544
  var _resume_binary_task = Module['_resume_binary_task'] = makeInvalidEarlyAccess('_resume_binary_task');
5523
5545
  var _call_ruby_callback_sync_generic = Module['_call_ruby_callback_sync_generic'] = makeInvalidEarlyAccess('_call_ruby_callback_sync_generic');
5524
5546
  var _mrb_tick_wasm = Module['_mrb_tick_wasm'] = makeInvalidEarlyAccess('_mrb_tick_wasm');
@@ -5562,7 +5584,9 @@ function assignWasmExports(wasmExports) {
5562
5584
  assert(typeof wasmExports['mrb_debug_next'] != 'undefined', 'missing Wasm export: mrb_debug_next');
5563
5585
  assert(typeof wasmExports['mrb_debug_get_callstack'] != 'undefined', 'missing Wasm export: mrb_debug_get_callstack');
5564
5586
  assert(typeof wasmExports['call_ruby_callback'] != 'undefined', 'missing Wasm export: call_ruby_callback');
5587
+ assert(typeof wasmExports['call_ruby_callback_oneshot'] != 'undefined', 'missing Wasm export: call_ruby_callback_oneshot');
5565
5588
  assert(typeof wasmExports['resume_promise_task'] != 'undefined', 'missing Wasm export: resume_promise_task');
5589
+ assert(typeof wasmExports['resume_promise_error_task'] != 'undefined', 'missing Wasm export: resume_promise_error_task');
5566
5590
  assert(typeof wasmExports['resume_binary_task'] != 'undefined', 'missing Wasm export: resume_binary_task');
5567
5591
  assert(typeof wasmExports['call_ruby_callback_sync_generic'] != 'undefined', 'missing Wasm export: call_ruby_callback_sync_generic');
5568
5592
  assert(typeof wasmExports['mrb_tick_wasm'] != 'undefined', 'missing Wasm export: mrb_tick_wasm');
@@ -5602,7 +5626,9 @@ function assignWasmExports(wasmExports) {
5602
5626
  _mrb_debug_next = Module['_mrb_debug_next'] = createExportWrapper('mrb_debug_next', 0);
5603
5627
  _mrb_debug_get_callstack = Module['_mrb_debug_get_callstack'] = createExportWrapper('mrb_debug_get_callstack', 0);
5604
5628
  _call_ruby_callback = Module['_call_ruby_callback'] = createExportWrapper('call_ruby_callback', 2);
5629
+ _call_ruby_callback_oneshot = Module['_call_ruby_callback_oneshot'] = createExportWrapper('call_ruby_callback_oneshot', 2);
5605
5630
  _resume_promise_task = Module['_resume_promise_task'] = createExportWrapper('resume_promise_task', 4);
5631
+ _resume_promise_error_task = Module['_resume_promise_error_task'] = createExportWrapper('resume_promise_error_task', 4);
5606
5632
  _resume_binary_task = Module['_resume_binary_task'] = createExportWrapper('resume_binary_task', 5);
5607
5633
  _call_ruby_callback_sync_generic = Module['_call_ruby_callback_sync_generic'] = createExportWrapper('call_ruby_callback_sync_generic', 3);
5608
5634
  _mrb_tick_wasm = Module['_mrb_tick_wasm'] = createExportWrapper('mrb_tick_wasm', 0);
@@ -5635,6 +5661,8 @@ var wasmImports = {
5635
5661
  /** @export */
5636
5662
  __assert_fail: ___assert_fail,
5637
5663
  /** @export */
5664
+ __call_sighandler: ___call_sighandler,
5665
+ /** @export */
5638
5666
  __syscall_chdir: ___syscall_chdir,
5639
5667
  /** @export */
5640
5668
  __syscall_chmod: ___syscall_chmod,
@@ -5681,6 +5709,8 @@ var wasmImports = {
5681
5709
  /** @export */
5682
5710
  _abort_js: __abort_js,
5683
5711
  /** @export */
5712
+ _emscripten_runtime_keepalive_clear: __emscripten_runtime_keepalive_clear,
5713
+ /** @export */
5684
5714
  _emscripten_throw_longjmp: __emscripten_throw_longjmp,
5685
5715
  /** @export */
5686
5716
  _localtime_js: __localtime_js,
@@ -5773,6 +5803,12 @@ var wasmImports = {
5773
5803
  /** @export */
5774
5804
  get_string_value_length,
5775
5805
  /** @export */
5806
+ idb_open_with_upgrade,
5807
+ /** @export */
5808
+ idb_request_to_promise,
5809
+ /** @export */
5810
+ idb_transaction_to_promise,
5811
+ /** @export */
5776
5812
  init_js_refs,
5777
5813
  /** @export */
5778
5814
  init_js_type_offsets,
@@ -5791,8 +5827,6 @@ var wasmImports = {
5791
5827
  /** @export */
5792
5828
  invoke_iijiiiiii,
5793
5829
  /** @export */
5794
- invoke_ijji,
5795
- /** @export */
5796
5830
  invoke_ji,
5797
5831
  /** @export */
5798
5832
  invoke_jii,
@@ -5801,8 +5835,6 @@ var wasmImports = {
5801
5835
  /** @export */
5802
5836
  invoke_vii,
5803
5837
  /** @export */
5804
- invoke_viid,
5805
- /** @export */
5806
5838
  invoke_viii,
5807
5839
  /** @export */
5808
5840
  invoke_viiii,
@@ -5813,8 +5845,6 @@ var wasmImports = {
5813
5845
  /** @export */
5814
5846
  invoke_viiiij,
5815
5847
  /** @export */
5816
- invoke_viiiiji,
5817
- /** @export */
5818
5848
  invoke_viiiijii,
5819
5849
  /** @export */
5820
5850
  invoke_viiij,
@@ -5829,12 +5859,20 @@ var wasmImports = {
5829
5859
  /** @export */
5830
5860
  invoke_vij,
5831
5861
  /** @export */
5862
+ invoke_vijii,
5863
+ /** @export */
5832
5864
  js_add_event_listener,
5833
5865
  /** @export */
5834
5866
  js_append_child,
5835
5867
  /** @export */
5868
+ js_classify_composite,
5869
+ /** @export */
5870
+ js_classify_dom,
5871
+ /** @export */
5836
5872
  js_clear_timeout,
5837
5873
  /** @export */
5874
+ js_copy_last_error,
5875
+ /** @export */
5838
5876
  js_create_array,
5839
5877
  /** @export */
5840
5878
  js_create_callback_function,
@@ -5847,10 +5885,16 @@ var wasmImports = {
5847
5885
  /** @export */
5848
5886
  js_eval,
5849
5887
  /** @export */
5888
+ js_function_apply_args,
5889
+ /** @export */
5850
5890
  js_get_type_info,
5851
5891
  /** @export */
5852
5892
  js_insert_before,
5853
5893
  /** @export */
5894
+ js_inspect_to_buffer,
5895
+ /** @export */
5896
+ js_last_error_length,
5897
+ /** @export */
5854
5898
  js_register_generic_callback,
5855
5899
  /** @export */
5856
5900
  js_remove_attribute,
@@ -5865,15 +5909,19 @@ var wasmImports = {
5865
5909
  /** @export */
5866
5910
  js_set_timeout,
5867
5911
  /** @export */
5868
- js_string_equals,
5869
- /** @export */
5870
5912
  proc_exit: _proc_exit,
5871
5913
  /** @export */
5872
5914
  regexp_exec,
5873
5915
  /** @export */
5874
5916
  regexp_flags,
5875
5917
  /** @export */
5876
- regexp_match_index,
5918
+ regexp_match_byte_begin,
5919
+ /** @export */
5920
+ regexp_match_byte_end,
5921
+ /** @export */
5922
+ regexp_match_char_begin,
5923
+ /** @export */
5924
+ regexp_match_char_end,
5877
5925
  /** @export */
5878
5926
  regexp_match_item,
5879
5927
  /** @export */
@@ -5883,6 +5931,8 @@ var wasmImports = {
5883
5931
  /** @export */
5884
5932
  regexp_new,
5885
5933
  /** @export */
5934
+ regexp_release_ref,
5935
+ /** @export */
5886
5936
  regexp_source,
5887
5937
  /** @export */
5888
5938
  regexp_test,
@@ -6102,10 +6152,10 @@ function invoke_iiii(index,a1,a2,a3) {
6102
6152
  }
6103
6153
  }
6104
6154
 
6105
- function invoke_viiiij(index,a1,a2,a3,a4,a5) {
6155
+ function invoke_iiiii(index,a1,a2,a3,a4) {
6106
6156
  var sp = stackSave();
6107
6157
  try {
6108
- getWasmTableEntry(index)(a1,a2,a3,a4,a5);
6158
+ return getWasmTableEntry(index)(a1,a2,a3,a4);
6109
6159
  } catch(e) {
6110
6160
  stackRestore(sp);
6111
6161
  if (e !== e+0) throw e;
@@ -6113,10 +6163,10 @@ function invoke_viiiij(index,a1,a2,a3,a4,a5) {
6113
6163
  }
6114
6164
  }
6115
6165
 
6116
- function invoke_vij(index,a1,a2) {
6166
+ function invoke_viiiij(index,a1,a2,a3,a4,a5) {
6117
6167
  var sp = stackSave();
6118
6168
  try {
6119
- getWasmTableEntry(index)(a1,a2);
6169
+ getWasmTableEntry(index)(a1,a2,a3,a4,a5);
6120
6170
  } catch(e) {
6121
6171
  stackRestore(sp);
6122
6172
  if (e !== e+0) throw e;
@@ -6124,10 +6174,10 @@ function invoke_vij(index,a1,a2) {
6124
6174
  }
6125
6175
  }
6126
6176
 
6127
- function invoke_iiiii(index,a1,a2,a3,a4) {
6177
+ function invoke_vij(index,a1,a2) {
6128
6178
  var sp = stackSave();
6129
6179
  try {
6130
- return getWasmTableEntry(index)(a1,a2,a3,a4);
6180
+ getWasmTableEntry(index)(a1,a2);
6131
6181
  } catch(e) {
6132
6182
  stackRestore(sp);
6133
6183
  if (e !== e+0) throw e;
@@ -6168,28 +6218,6 @@ function invoke_viiji(index,a1,a2,a3,a4) {
6168
6218
  }
6169
6219
  }
6170
6220
 
6171
- function invoke_ijji(index,a1,a2,a3) {
6172
- var sp = stackSave();
6173
- try {
6174
- return getWasmTableEntry(index)(a1,a2,a3);
6175
- } catch(e) {
6176
- stackRestore(sp);
6177
- if (e !== e+0) throw e;
6178
- _setThrew(1, 0);
6179
- }
6180
- }
6181
-
6182
- function invoke_viiiiji(index,a1,a2,a3,a4,a5,a6) {
6183
- var sp = stackSave();
6184
- try {
6185
- getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6);
6186
- } catch(e) {
6187
- stackRestore(sp);
6188
- if (e !== e+0) throw e;
6189
- _setThrew(1, 0);
6190
- }
6191
- }
6192
-
6193
6221
  function invoke_viijj(index,a1,a2,a3,a4) {
6194
6222
  var sp = stackSave();
6195
6223
  try {
@@ -6235,10 +6263,10 @@ function invoke_jii(index,a1,a2) {
6235
6263
  }
6236
6264
  }
6237
6265
 
6238
- function invoke_viid(index,a1,a2,a3) {
6266
+ function invoke_vijii(index,a1,a2,a3,a4) {
6239
6267
  var sp = stackSave();
6240
6268
  try {
6241
- getWasmTableEntry(index)(a1,a2,a3);
6269
+ getWasmTableEntry(index)(a1,a2,a3,a4);
6242
6270
  } catch(e) {
6243
6271
  stackRestore(sp);
6244
6272
  if (e !== e+0) throw e;