funicular 0.4.0 → 0.5.0

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +429 -1
  3. data/demo/local_notes.html +207 -0
  4. data/docs/architecture.md +181 -3
  5. data/docs/local_database.md +1035 -0
  6. data/lib/funicular/assets/funicular.rb +14 -0
  7. data/lib/funicular/configuration.rb +65 -0
  8. data/lib/funicular/epoch_header.rb +69 -0
  9. data/lib/funicular/epoch_stamping.rb +66 -0
  10. data/lib/funicular/helpers/picoruby_helper.rb +96 -1
  11. data/lib/funicular/railtie.rb +30 -0
  12. data/lib/funicular/schema.rb +45 -12
  13. data/lib/funicular/session_epoch.rb +110 -0
  14. data/lib/funicular/ssr/runtime.rb +57 -12
  15. data/lib/funicular/ssr.rb +25 -0
  16. data/lib/funicular/testing/node_runner.mjs +19 -0
  17. data/lib/funicular/testing.rb +47 -0
  18. data/lib/funicular/vendor/mrbc/VERSION +1 -1
  19. data/lib/funicular/vendor/mrbc/mrbc.js +69 -115
  20. data/lib/funicular/vendor/mrbc/mrbc.wasm +0 -0
  21. data/lib/funicular/vendor/picoruby/VERSION +1 -1
  22. data/lib/funicular/vendor/picoruby/debug/picoruby.js +170 -120
  23. data/lib/funicular/vendor/picoruby/debug/picoruby.wasm +0 -0
  24. data/lib/funicular/vendor/picoruby/dist/picoruby.js +1 -1
  25. data/lib/funicular/vendor/picoruby/dist/picoruby.wasm +0 -0
  26. data/lib/funicular/vendor/picoruby-test-node/VERSION +1 -1
  27. data/lib/funicular/vendor/picoruby-test-node/picoruby.js +2 -7201
  28. data/lib/funicular/vendor/picoruby-test-node/picoruby.wasm +0 -0
  29. data/lib/funicular/version.rb +1 -1
  30. data/lib/funicular.rb +1 -0
  31. data/lib/tasks/funicular.rake +10 -2
  32. data/minitest/callback_error_visibility_test.rb +48 -0
  33. data/minitest/configuration_test.rb +78 -0
  34. data/minitest/dsl_test.rb +27 -0
  35. data/minitest/epoch_header_test.rb +149 -0
  36. data/minitest/epoch_stamping_test.rb +225 -0
  37. data/minitest/fixtures/funicular_app/components/probe_component.rb +15 -0
  38. data/minitest/navigation_guard_test.rb +65 -0
  39. data/minitest/picoruby_helper_test.rb +236 -0
  40. data/minitest/schema_test.rb +47 -0
  41. data/minitest/session_epoch_test.rb +122 -0
  42. data/minitest/ssr_database_test.rb +78 -0
  43. data/minitest/ssr_reload_test.rb +106 -0
  44. data/minitest/ssr_test.rb +41 -0
  45. data/minitest/testing_ensure_compiled_test.rb +52 -0
  46. data/minitest/validations_test.rb +35 -5
  47. data/mrbgem.rake +2 -0
  48. data/mrblib/cable.rb +1 -1
  49. data/mrblib/component.rb +113 -1
  50. data/mrblib/db.rb +3116 -0
  51. data/mrblib/file_upload.rb +17 -7
  52. data/mrblib/funicular.rb +136 -17
  53. data/mrblib/http.rb +84 -107
  54. data/mrblib/model.rb +1178 -23
  55. data/mrblib/relation.rb +342 -0
  56. data/mrblib/router.rb +45 -4
  57. data/mrblib/styles.rb +20 -0
  58. data/sig/component.rbs +7 -0
  59. data/sig/db.rbs +328 -0
  60. data/sig/funicular.rbs +5 -0
  61. data/sig/http.rbs +8 -21
  62. data/sig/model.rbs +101 -7
  63. data/sig/relation.rbs +44 -0
  64. data/sig/router.rbs +1 -0
  65. data/sig/styles.rbs +1 -0
  66. metadata +19 -2
  67. data/lib/funicular/vendor/picoruby-test-node/picoruby.wasm.map +0 -1
@@ -644,36 +644,15 @@ async function createWasm() {
644
644
  }
645
645
  }
646
646
 
647
- /** @type {!Int16Array} */
648
- var HEAP16;
649
-
650
647
  /** @type {!Int32Array} */
651
648
  var HEAP32;
652
649
 
653
- /** not-@type {!BigInt64Array} */
654
- var HEAP64;
655
-
656
650
  /** @type {!Int8Array} */
657
651
  var HEAP8;
658
652
 
659
- /** @type {!Float32Array} */
660
- var HEAPF32;
661
-
662
- /** @type {!Float64Array} */
663
- var HEAPF64;
664
-
665
- /** @type {!Uint16Array} */
666
- var HEAPU16;
667
-
668
653
  /** @type {!Uint32Array} */
669
654
  var HEAPU32;
670
655
 
671
- /** not-@type {!BigUint64Array} */
672
- var HEAPU64;
673
-
674
- /** @type {!Uint8Array} */
675
- var HEAPU8;
676
-
677
656
  var callRuntimeCallbacks = (callbacks) => {
678
657
  while (callbacks.length > 0) {
679
658
  // Pass the module as the first argument.
@@ -687,26 +666,6 @@ async function createWasm() {
687
666
  var addOnPreRun = (cb) => onPreRuns.push(cb);
688
667
 
689
668
 
690
-
691
- /**
692
- * @param {number} ptr
693
- * @param {string} type
694
- */
695
- function getValue(ptr, type = 'i8') {
696
- if (type.endsWith('*')) type = '*';
697
- switch (type) {
698
- case 'i1': return HEAP8[ptr];
699
- case 'i8': return HEAP8[ptr];
700
- case 'i16': return HEAP16[((ptr)>>1)];
701
- case 'i32': return HEAP32[((ptr)>>2)];
702
- case 'i64': return HEAP64[((ptr)>>3)];
703
- case 'float': return HEAPF32[((ptr)>>2)];
704
- case 'double': return HEAPF64[((ptr)>>3)];
705
- case '*': return HEAPU32[((ptr)>>2)];
706
- default: abort(`invalid type for getValue: ${type}`);
707
- }
708
- }
709
-
710
669
  var noExitRuntime = true;
711
670
 
712
671
  function ptrToString(ptr) {
@@ -716,27 +675,6 @@ async function createWasm() {
716
675
  return '0x' + ptr.toString(16).padStart(8, '0');
717
676
  }
718
677
 
719
-
720
- /**
721
- * @param {number} ptr
722
- * @param {number} value
723
- * @param {string} type
724
- */
725
- function setValue(ptr, value, type = 'i8') {
726
- if (type.endsWith('*')) type = '*';
727
- switch (type) {
728
- case 'i1': HEAP8[ptr] = value; break;
729
- case 'i8': HEAP8[ptr] = value; break;
730
- case 'i16': HEAP16[((ptr)>>1)] = value; break;
731
- case 'i32': HEAP32[((ptr)>>2)] = value; break;
732
- case 'i64': HEAP64[((ptr)>>3)] = BigInt(value); break;
733
- case 'float': HEAPF32[((ptr)>>2)] = value; break;
734
- case 'double': HEAPF64[((ptr)>>3)] = value; break;
735
- case '*': HEAPU32[((ptr)>>2)] = value; break;
736
- default: abort(`invalid type for setValue: ${type}`);
737
- }
738
- }
739
-
740
678
  var stackRestore = (val) => __emscripten_stack_restore(val);
741
679
 
742
680
  var stackSave = () => _emscripten_stack_get_current();
@@ -819,6 +757,9 @@ async function createWasm() {
819
757
  return str;
820
758
  };
821
759
 
760
+ /** @type {!Uint8Array} */
761
+ var HEAPU8;
762
+
822
763
  /**
823
764
  * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
824
765
  * emscripten HEAP, returns a copy of that string as a Javascript String object.
@@ -1125,7 +1066,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
1125
1066
  } catch (e) {
1126
1067
  throw new FS.ErrnoError(29);
1127
1068
  }
1128
- if (result === undefined && bytesRead === 0) {
1069
+ if (result === undefined && !bytesRead) {
1129
1070
  throw new FS.ErrnoError(6);
1130
1071
  }
1131
1072
  if (result === null || result === undefined) break;
@@ -1225,6 +1166,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
1225
1166
  if (ptr) zeroMemory(ptr, size);
1226
1167
  return ptr;
1227
1168
  };
1169
+
1228
1170
  var MEMFS = {
1229
1171
  ops_table:null,
1230
1172
  mount(mount) {
@@ -1368,7 +1310,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
1368
1310
  return attr;
1369
1311
  },
1370
1312
  setattr(node, attr) {
1371
- for (const key of ["mode", "atime", "mtime", "ctime"]) {
1313
+ for (const key of ['mode', 'atime', 'mtime', 'ctime']) {
1372
1314
  if (attr[key] != null) {
1373
1315
  node[key] = attr[key];
1374
1316
  }
@@ -1454,10 +1396,10 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
1454
1396
  node.mtime = node.ctime = Date.now();
1455
1397
 
1456
1398
  if (canOwn) {
1457
- assert(position === 0, 'canOwn must imply no weird position inside the file');
1399
+ assert(!position, 'canOwn must imply no weird position inside the file');
1458
1400
  node.contents = buffer.subarray(offset, offset + length);
1459
1401
  node.usedBytes = length;
1460
- } else if (node.usedBytes === 0 && position === 0) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
1402
+ } else if (!node.usedBytes && !position) { // If this is a simple first write to an empty file, do a fast set since we don't need to care about old data.
1461
1403
  node.contents = buffer.slice(offset, offset + length);
1462
1404
  node.usedBytes = length;
1463
1405
  } else {
@@ -1745,7 +1687,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
1745
1687
  assert(id, 'addRunDependency requires an ID')
1746
1688
  assert(!runDependencyTracking[id]);
1747
1689
  runDependencyTracking[id] = 1;
1748
- if (runDependencyWatcher === null && globalThis.setInterval) {
1690
+ if (!runDependencyWatcher && globalThis.setInterval) {
1749
1691
  // Check for missing dependencies every few seconds
1750
1692
  runDependencyWatcher = setInterval(() => {
1751
1693
  if (ABORT) {
@@ -1809,6 +1751,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
1809
1751
  var FS_createPreloadedFile = (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) => {
1810
1752
  FS_preloadFile(parent, name, url, canRead, canWrite, dontCreateFile, canOwn, preFinish).then(onload).catch(onerror);
1811
1753
  };
1754
+
1812
1755
  var FS = {
1813
1756
  root:null,
1814
1757
  mounts:[],
@@ -2800,7 +2743,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
2800
2743
  });
2801
2744
  },
2802
2745
  open(path, flags, mode = 0o666) {
2803
- if (path === "") {
2746
+ if (path === '') {
2804
2747
  throw new FS.ErrnoError(44);
2805
2748
  }
2806
2749
  flags = FS_modeStringToFlags(flags);
@@ -2814,7 +2757,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
2814
2757
  if (typeof path == 'object') {
2815
2758
  node = path;
2816
2759
  } else {
2817
- isDirPath = path.endsWith("/");
2760
+ isDirPath = path.endsWith('/');
2818
2761
  // noent_okay makes it so that if the final component of the path
2819
2762
  // doesn't exist, lookupPath returns `node: undefined`. `path` will be
2820
2763
  // updated to point to the target of all symlinks.
@@ -2996,8 +2939,8 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
2996
2939
  // to write to file opened in read-only mode with MAP_PRIVATE flag,
2997
2940
  // as all modifications will be visible only in the memory of
2998
2941
  // the current process.
2999
- if ((prot & 2) !== 0
3000
- && (flags & 2) === 0
2942
+ if ((prot & 2)
2943
+ && !(flags & 2)
3001
2944
  && (stream.flags & 2097155) !== 2) {
3002
2945
  throw new FS.ErrnoError(2);
3003
2946
  }
@@ -3090,7 +3033,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3090
3033
  // use a buffer to avoid overhead of individual crypto calls per byte
3091
3034
  var randomBuffer = new Uint8Array(1024), randomLeft = 0;
3092
3035
  var randomByte = () => {
3093
- if (randomLeft === 0) {
3036
+ if (!randomLeft) {
3094
3037
  randomFill(randomBuffer);
3095
3038
  randomLeft = randomBuffer.byteLength;
3096
3039
  }
@@ -3306,7 +3249,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3306
3249
  } catch (e) {
3307
3250
  throw new FS.ErrnoError(29);
3308
3251
  }
3309
- if (result === undefined && bytesRead === 0) {
3252
+ if (result === undefined && !bytesRead) {
3310
3253
  throw new FS.ErrnoError(6);
3311
3254
  }
3312
3255
  if (result === null || result === undefined) break;
@@ -3337,7 +3280,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3337
3280
  forceLoadFile(obj) {
3338
3281
  if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
3339
3282
  if (globalThis.XMLHttpRequest) {
3340
- abort("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
3283
+ abort('Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.');
3341
3284
  } else { // Command-line.
3342
3285
  try {
3343
3286
  obj.contents = readBinary(obj.url);
@@ -3368,11 +3311,11 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3368
3311
  var xhr = new XMLHttpRequest();
3369
3312
  xhr.open('HEAD', url, false);
3370
3313
  xhr.send(null);
3371
- if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort("Couldn't load " + url + ". Status: " + xhr.status);
3372
- var datalength = Number(xhr.getResponseHeader("Content-length"));
3314
+ if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort(`Couldn't load ${url}. Status: ${xhr.status}`);
3315
+ var datalength = Number(xhr.getResponseHeader('Content-length'));
3373
3316
  var header;
3374
- var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
3375
- var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip";
3317
+ var hasByteServing = (header = xhr.getResponseHeader('Accept-Ranges')) && header === 'bytes';
3318
+ var usesGzip = (header = xhr.getResponseHeader('Content-Encoding')) && header === 'gzip';
3376
3319
 
3377
3320
  var chunkSize = 1024*1024; // Chunk size in bytes
3378
3321
 
@@ -3386,7 +3329,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3386
3329
  // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
3387
3330
  var xhr = new XMLHttpRequest();
3388
3331
  xhr.open('GET', url, false);
3389
- if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
3332
+ if (datalength !== chunkSize) xhr.setRequestHeader('Range', `bytes=${from}-${to}`);
3390
3333
 
3391
3334
  // Some hints to the browser that we want binary data.
3392
3335
  xhr.responseType = 'arraybuffer';
@@ -3395,7 +3338,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3395
3338
  }
3396
3339
 
3397
3340
  xhr.send(null);
3398
- if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort("Couldn't load " + url + ". Status: " + xhr.status);
3341
+ if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) abort(`Couldn't load ${url}. Status: ${xhr.status}`);
3399
3342
  if (xhr.response !== undefined) {
3400
3343
  return new Uint8Array(/** @type{Array<number>} */(xhr.response || []));
3401
3344
  }
@@ -3418,7 +3361,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3418
3361
  chunkSize = datalength = 1; // this will force getter(0)/doXHR do download the whole file
3419
3362
  datalength = this.getter(0).length;
3420
3363
  chunkSize = datalength;
3421
- out("LazyFiles on gzip forces download of the whole file when length is accessed");
3364
+ out('LazyFiles on gzip forces download of the whole file when length is accessed');
3422
3365
  }
3423
3366
 
3424
3367
  this._length = datalength;
@@ -3508,6 +3451,12 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3508
3451
  },
3509
3452
  };
3510
3453
 
3454
+
3455
+
3456
+
3457
+
3458
+ /** not-@type {!BigInt64Array} */
3459
+ var HEAP64;
3511
3460
  var SYSCALLS = {
3512
3461
  currentUmask:18,
3513
3462
  calculateAt(dirfd, path, allowEmpty) {
@@ -3655,6 +3604,9 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3655
3604
  var syscallGetVarargP = syscallGetVarargI;
3656
3605
 
3657
3606
 
3607
+
3608
+ /** @type {!Int16Array} */
3609
+ var HEAP16;
3658
3610
  function ___syscall_fcntl64(fd, cmd, varargs) {
3659
3611
  SYSCALLS.varargs = varargs;
3660
3612
  try {
@@ -3739,6 +3691,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3739
3691
  }
3740
3692
 
3741
3693
 
3694
+
3742
3695
  var stringToUTF8 = (str, outPtr, maxBytesToWrite) => {
3743
3696
  assert(typeof maxBytesToWrite == 'number', 'stringToUTF8 requires a third parameter that specifies the length of the output buffer');
3744
3697
  return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
@@ -3746,7 +3699,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3746
3699
  function ___syscall_getcwd(buf, size) {
3747
3700
  try {
3748
3701
 
3749
- if (size === 0) return -28;
3702
+ if (!size) return -28;
3750
3703
  var cwd = FS.cwd();
3751
3704
  var cwdLengthInBytes = lengthBytesUTF8(cwd) + 1;
3752
3705
  if (size < cwdLengthInBytes) return -68;
@@ -3760,6 +3713,9 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3760
3713
 
3761
3714
 
3762
3715
 
3716
+
3717
+
3718
+
3763
3719
  function ___syscall_getdents64(fd, dirp, count) {
3764
3720
  try {
3765
3721
 
@@ -3821,6 +3777,9 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3821
3777
 
3822
3778
 
3823
3779
 
3780
+
3781
+
3782
+
3824
3783
  function ___syscall_ioctl(fd, op, varargs) {
3825
3784
  SYSCALLS.varargs = varargs;
3826
3785
  try {
@@ -3981,6 +3940,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
3981
3940
  }
3982
3941
 
3983
3942
 
3943
+
3984
3944
  var PIPEFS = {
3985
3945
  BUCKET_BUFFER_SIZE:8192,
3986
3946
  mount(mount) {
@@ -4240,17 +4200,17 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4240
4200
  // When the last write end closes, wake any poll/epoll waiter on the read
4241
4201
  // end with POLLHUP so a reader blocked on the writer dropping unblocks.
4242
4202
  if ((stream.flags & 2097155) === 1) {
4243
- if (--pipe.writerCount === 0) {
4203
+ if (!--pipe.writerCount) {
4244
4204
  pipe.writeClosed = true;
4245
4205
  pipe.readNode.notifyListeners(16 | 64 | 1);
4246
4206
  }
4247
- } else if (--pipe.readerCount === 0) {
4207
+ } else if (!--pipe.readerCount) {
4248
4208
  // Mirror: when the last read end closes, wake any poll/epoll waiter on
4249
4209
  // the write end with POLLERR (a further write would get EPIPE).
4250
4210
  pipe.readClosed = true;
4251
4211
  pipe.writeNode.notifyListeners(8 | 256 | 4);
4252
4212
  }
4253
- if (pipe.readerCount === 0 && pipe.writerCount === 0) {
4213
+ if (!pipe.readerCount && !pipe.writerCount) {
4254
4214
  pipe.buckets = null;
4255
4215
  }
4256
4216
  },
@@ -4262,6 +4222,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4262
4222
  return 'pipe[' + (PIPEFS.nextname.current++) + ']';
4263
4223
  },
4264
4224
  };
4225
+
4265
4226
  function ___syscall_pipe2(fdPtr, flags) {
4266
4227
  try {
4267
4228
 
@@ -4301,6 +4262,8 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4301
4262
  : 5;
4302
4263
  return flags & (events | 8 | 16 | 32);
4303
4264
  };
4265
+
4266
+
4304
4267
  var doPollSync = (fds, nfds) => {
4305
4268
  var count = 0;
4306
4269
  for (var i = 0, pollfd = fds; i < nfds; i++, pollfd += 8) {
@@ -4338,6 +4301,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4338
4301
 
4339
4302
 
4340
4303
 
4304
+
4341
4305
  function ___syscall_readlinkat(dirfd, path, buf, bufsize) {
4342
4306
  try {
4343
4307
 
@@ -4475,6 +4439,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4475
4439
  return yday;
4476
4440
  };
4477
4441
 
4442
+
4478
4443
  function __localtime_js(time, tmPtr) {
4479
4444
  time = bigintToI53Checked(time);
4480
4445
 
@@ -4506,6 +4471,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4506
4471
  }
4507
4472
 
4508
4473
 
4474
+
4509
4475
  var __mktime_js = function(tmPtr) {
4510
4476
 
4511
4477
  var ret = (() => {
@@ -4579,6 +4545,8 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4579
4545
  }
4580
4546
 
4581
4547
 
4548
+
4549
+
4582
4550
  var __tzset_js = (timezone, daylight, std_name, dst_name) => {
4583
4551
  // TODO: Use (malleable) environment variables instead of system settings.
4584
4552
  var currentYear = new Date().getFullYear();
@@ -4607,11 +4575,11 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4607
4575
  var extractZone = (timezoneOffset) => {
4608
4576
  // Why inverse sign?
4609
4577
  // Read here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
4610
- var sign = timezoneOffset >= 0 ? "-" : "+";
4578
+ var sign = timezoneOffset >= 0 ? '-' : '+';
4611
4579
 
4612
4580
  var absOffset = Math.abs(timezoneOffset)
4613
- var hours = String(Math.floor(absOffset / 60)).padStart(2, "0");
4614
- var minutes = String(absOffset % 60).padStart(2, "0");
4581
+ var hours = String(Math.floor(absOffset / 60)).padStart(2, '0');
4582
+ var minutes = String(absOffset % 60).padStart(2, '0');
4615
4583
 
4616
4584
  return `UTC${sign}${hours}${minutes}`;
4617
4585
  }
@@ -4639,6 +4607,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4639
4607
 
4640
4608
  var checkWasiClock = (clock_id) => clock_id >= 0 && clock_id <= 3;
4641
4609
 
4610
+
4642
4611
  function _clock_time_get(clk_id, ignored_precision, ptime) {
4643
4612
  ignored_precision = bigintToI53Checked(ignored_precision);
4644
4613
 
@@ -4663,6 +4632,13 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4663
4632
  }
4664
4633
 
4665
4634
  var readEmAsmArgsArray = [];
4635
+
4636
+
4637
+
4638
+
4639
+ /** @type {!Float64Array} */
4640
+ var HEAPF64;
4641
+
4666
4642
  var readEmAsmArgs = (sigPtr, buf) => {
4667
4643
  // Nobody should have mutated _readEmAsmArgsArray underneath us to be something else than an array.
4668
4644
  assert(Array.isArray(readEmAsmArgsArray));
@@ -4728,9 +4704,10 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4728
4704
  } catch(e) {
4729
4705
  err(`growMemory: Attempted to grow heap from ${oldHeapSize} bytes to ${size} bytes, but got error: ${e}`);
4730
4706
  }
4731
- // implicit 0 return to save code size (caller will cast "undefined" into 0
4707
+ // implicit 0 return to save code size (caller will cast 'undefined' into 0
4732
4708
  // anyhow)
4733
4709
  };
4710
+
4734
4711
  var _emscripten_resize_heap = (requestedSize) => {
4735
4712
  var oldSize = HEAPU8.length;
4736
4713
  // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
@@ -4818,6 +4795,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4818
4795
  return getEnvStrings.strings;
4819
4796
  };
4820
4797
 
4798
+
4821
4799
  var _environ_get = (__environ, environ_buf) => {
4822
4800
  var bufSize = 0;
4823
4801
  var envp = 0;
@@ -4831,6 +4809,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4831
4809
  };
4832
4810
 
4833
4811
 
4812
+
4834
4813
  var _environ_sizes_get = (penviron_count, penviron_buf_size) => {
4835
4814
  var strings = getEnvStrings();
4836
4815
  HEAPU32[((penviron_count)>>2)] = strings.length;
@@ -4883,6 +4862,9 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4883
4862
  }
4884
4863
 
4885
4864
 
4865
+
4866
+
4867
+
4886
4868
  function _fd_fdstat_get(fd, pbuf) {
4887
4869
  try {
4888
4870
 
@@ -4910,6 +4892,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4910
4892
  }
4911
4893
 
4912
4894
 
4895
+
4913
4896
  /** @param {number=} offset */
4914
4897
  var doReadv = (stream, iov, iovcnt, offset) => {
4915
4898
  var ret = 0;
@@ -4940,6 +4923,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4940
4923
  };
4941
4924
 
4942
4925
 
4926
+
4943
4927
  function _fd_pread(fd, iov, iovcnt, offset, pnum) {
4944
4928
  offset = bigintToI53Checked(offset);
4945
4929
 
@@ -4958,6 +4942,8 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4958
4942
  ;
4959
4943
  }
4960
4944
 
4945
+
4946
+
4961
4947
  /** @param {number=} offset */
4962
4948
  var doWritev = (stream, iov, iovcnt, offset) => {
4963
4949
  // Gather all iovecs into one contiguous buffer and issue a single
@@ -4984,6 +4970,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
4984
4970
  };
4985
4971
 
4986
4972
 
4973
+
4987
4974
  function _fd_pwrite(fd, iov, iovcnt, offset, pnum) {
4988
4975
  offset = bigintToI53Checked(offset);
4989
4976
 
@@ -5003,6 +4990,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
5003
4990
  }
5004
4991
 
5005
4992
 
4993
+
5006
4994
  function _fd_read(fd, iov, iovcnt, pnum) {
5007
4995
  try {
5008
4996
 
@@ -5018,6 +5006,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
5018
5006
 
5019
5007
 
5020
5008
 
5009
+
5021
5010
  function _fd_seek(fd, offset, whence, newOffset) {
5022
5011
  offset = bigintToI53Checked(offset);
5023
5012
 
@@ -5028,7 +5017,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
5028
5017
  var stream = SYSCALLS.getStreamFromFD(fd);
5029
5018
  FS.llseek(stream, offset, whence);
5030
5019
  HEAP64[((newOffset)>>3)] = BigInt(stream.position);
5031
- if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; // reset readdir state
5020
+ if (stream.getdents && !offset && whence === 0) stream.getdents = null; // reset readdir state
5032
5021
  return 0;
5033
5022
  } catch (e) {
5034
5023
  if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
@@ -5051,6 +5040,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
5051
5040
 
5052
5041
 
5053
5042
 
5043
+
5054
5044
  function _fd_write(fd, iov, iovcnt, pnum) {
5055
5045
  try {
5056
5046
 
@@ -5067,6 +5057,74 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
5067
5057
 
5068
5058
 
5069
5059
 
5060
+
5061
+
5062
+
5063
+
5064
+
5065
+
5066
+
5067
+
5068
+
5069
+
5070
+
5071
+
5072
+
5073
+
5074
+
5075
+
5076
+
5077
+
5078
+
5079
+
5080
+
5081
+
5082
+
5083
+
5084
+
5085
+
5086
+
5087
+
5088
+
5089
+
5090
+
5091
+
5092
+
5093
+
5094
+
5095
+
5096
+
5097
+
5098
+
5099
+ /** @type {!Uint16Array} */
5100
+ var HEAPU16;
5101
+
5102
+
5103
+
5104
+ /** @type {!Float32Array} */
5105
+ var HEAPF32;
5106
+
5107
+
5108
+
5109
+ /** not-@type {!BigUint64Array} */
5110
+ var HEAPU64;
5111
+
5112
+
5113
+
5114
+
5115
+
5116
+
5117
+
5118
+
5119
+
5120
+
5121
+
5122
+
5123
+
5124
+
5125
+
5126
+
5127
+
5070
5128
  var getCFunc = (ident) => {
5071
5129
  var func = Module['_' + ident]; // closure exported function
5072
5130
  assert(func, `Cannot call unknown function ${ident}, make sure it is exported`);
@@ -5131,7 +5189,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
5131
5189
  for (var i = 0; i < args.length; i++) {
5132
5190
  var converter = toC[argTypes[i]];
5133
5191
  if (converter) {
5134
- if (stack === 0) stack = stackSave();
5192
+ if (!stack) stack = stackSave();
5135
5193
  cArgs[i] = converter(args[i]);
5136
5194
  } else {
5137
5195
  cArgs[i] = args[i];
@@ -5140,7 +5198,7 @@ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
5140
5198
  }
5141
5199
  var ret = func(...cArgs);
5142
5200
  function onDone(ret) {
5143
- if (stack !== 0) stackRestore(stack);
5201
+ if (stack) stackRestore(stack);
5144
5202
  return convertReturnValue(ret);
5145
5203
  }
5146
5204
 
@@ -5269,6 +5327,8 @@ if (Module['printErr']) err = Module['printErr'];
5269
5327
  'getFunctionAddress',
5270
5328
  'addFunction',
5271
5329
  'removeFunction',
5330
+ 'setValue',
5331
+ 'getValue',
5272
5332
  'intArrayToString',
5273
5333
  'AsciiToString',
5274
5334
  'stringToAscii',
@@ -5337,10 +5397,6 @@ if (Module['printErr']) err = Module['printErr'];
5337
5397
  'addPromise',
5338
5398
  'idsToPromises',
5339
5399
  'makePromiseCallback',
5340
- 'ExceptionInfo',
5341
- 'findMatchingCatch',
5342
- 'incrementUncaughtExceptionCount',
5343
- 'decrementUncaughtExceptionCount',
5344
5400
  'Browser_asyncPrepareDataCounter',
5345
5401
  'arraySum',
5346
5402
  'addDays',
@@ -5371,14 +5427,10 @@ if (Module['printErr']) err = Module['printErr'];
5371
5427
  'writeGLArray',
5372
5428
  'registerWebGlEventCallback',
5373
5429
  'runAndAbortIfError',
5374
- 'ALLOC_NORMAL',
5375
- 'ALLOC_STACK',
5376
- 'allocate',
5377
5430
  'writeStringToMemory',
5378
5431
  'writeAsciiToMemory',
5379
5432
  'allocateUTF8',
5380
5433
  'allocateUTF8OnStack',
5381
- 'demangle',
5382
5434
  'stackTrace',
5383
5435
  'getNativeTypeSize',
5384
5436
  ];
@@ -5439,8 +5491,6 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
5439
5491
  'addOnPostRun',
5440
5492
  'freeTableIndexes',
5441
5493
  'functionsInTableMap',
5442
- 'setValue',
5443
- 'getValue',
5444
5494
  'PATH',
5445
5495
  'PATH_FS',
5446
5496
  'UTF8Decoder',
@@ -5466,11 +5516,8 @@ missingLibrarySymbols.forEach(missingLibrarySymbol)
5466
5516
  'emClearImmediate_deps',
5467
5517
  'emClearImmediate',
5468
5518
  'promiseMap',
5469
- 'uncaughtExceptionCount',
5470
- 'exceptionCaught',
5471
5519
  'Browser',
5472
5520
  'requestFullscreen',
5473
- 'requestFullScreen',
5474
5521
  'setCanvasSize',
5475
5522
  'getUserMedia',
5476
5523
  'createContext',
@@ -5658,20 +5705,20 @@ function checkIncomingModuleAPI() {
5658
5705
  ignoredModuleProp('wasmBinary');
5659
5706
  }
5660
5707
  var ASM_CONSTS = {
5661
- 2651478: ($0) => { globalThis.picorubyRefs[$0] = null; },
5662
- 2651518: ($0) => { globalThis.picorubyRefs[$0] = true; },
5663
- 2651558: ($0) => { globalThis.picorubyRefs[$0] = false; },
5664
- 2651599: ($0, $1) => { globalThis.picorubyRefs[$0] = $1; },
5665
- 2651637: ($0, $1) => { globalThis.picorubyRefs[$0] = $1; },
5666
- 2651675: ($0, $1, $2) => { const str = UTF8ToString($1, $2); globalThis.picorubyRefs[$0] = str; },
5667
- 2651748: ($0, $1) => { const arr = globalThis.picorubyRefs[$0]; const elem = globalThis.picorubyRefs[$1]; arr.push(elem); delete globalThis.picorubyRefs[$1]; },
5668
- 2651887: ($0, $1, $2) => { const obj = globalThis.picorubyRefs[$0]; const key = UTF8ToString($1); const val = globalThis.picorubyRefs[$2]; obj[key] = val; delete globalThis.picorubyRefs[$2]; }
5708
+ 2823398: ($0) => { globalThis.picorubyRefs[$0] = null; },
5709
+ 2823438: ($0) => { globalThis.picorubyRefs[$0] = true; },
5710
+ 2823478: ($0) => { globalThis.picorubyRefs[$0] = false; },
5711
+ 2823519: ($0, $1) => { globalThis.picorubyRefs[$0] = $1; },
5712
+ 2823557: ($0, $1) => { globalThis.picorubyRefs[$0] = $1; },
5713
+ 2823595: ($0, $1, $2) => { const str = UTF8ToString($1, $2); globalThis.picorubyRefs[$0] = str; },
5714
+ 2823668: ($0, $1) => { const arr = globalThis.picorubyRefs[$0]; const elem = globalThis.picorubyRefs[$1]; arr.push(elem); delete globalThis.picorubyRefs[$1]; },
5715
+ 2823807: ($0, $1, $2) => { const obj = globalThis.picorubyRefs[$0]; const key = UTF8ToString($1); const val = globalThis.picorubyRefs[$2]; obj[key] = val; delete globalThis.picorubyRefs[$2]; }
5669
5716
  };
5670
5717
  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; } }
5671
5718
  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; } }
5672
5719
  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; } }
5673
- 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); } }
5674
- 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; }; } }
5720
+ function ble_set_notify_handler(char_ref_id,callback_id) { try { const char_obj = globalThis.picorubyRefs[char_ref_id]; if (char_obj.__picorbNotifyListener) { char_obj.removeEventListener('characteristicvaluechanged', char_obj.__picorbNotifyListener); } const listener = (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); }; char_obj.__picorbNotifyListener = listener; char_obj.addEventListener('characteristicvaluechanged', listener); } catch(e) { console.error('ble_set_notify_handler failed:', e); } }
5721
+ 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, !!info.capture); delete globalThis.picorubyEventHandlers[callback_id]; return true; }; } }
5675
5722
  function js_last_error_length() { const message = globalThis.picorubyLastError; return message ? lengthBytesUTF8(message) : 0; }
5676
5723
  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; }
5677
5724
  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'); }
@@ -5705,12 +5752,12 @@ function call_constructor_with_args(ref_id,args_json,args_json_len) { globalThis
5705
5752
  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; } }
5706
5753
  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; } }
5707
5754
  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] ); } ); }
5708
- 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 }; }
5755
+ function js_add_event_listener(ref_id,callback_id,event_type,sync,capture,once,passive) { const target = globalThis.picorubyRefs[ref_id]; const type = UTF8ToString(event_type); const isSync = !!sync; const isOnce = !!once; const isCapture = !!capture; let options = undefined; if (isCapture || isOnce || passive >= 0) { options = { capture: isCapture, once: isOnce }; if (passive >= 0) options.passive = (passive === 1); } const handler = (event) => { if (!globalThis.picorubyEventHandlers || !globalThis.picorubyEventHandlers[callback_id]) { return; } if (isOnce) { delete globalThis.picorubyEventHandlers[callback_id]; } if (!isSync && passive !== 1 && (type === 'submit' || (type === 'click' && target.tagName === 'A'))) { event.preventDefault(); } const eventRefId = globalThis.picorubyRefs.push(event) - 1; if (isSync) { try { ccall( 'call_ruby_callback_sync_event', 'void', ['number', 'number', 'number'], [callback_id, eventRefId, isOnce ? 1 : 0] ); } finally { delete globalThis.picorubyRefs[eventRefId]; } } else { ccall( isOnce ? 'call_ruby_callback_oneshot' : 'call_ruby_callback', 'void', ['number', 'number'], [callback_id, eventRefId] ); } }; if (options) { target.addEventListener(type, handler, options); } else { target.addEventListener(type, handler); } if (!globalThis.picorubyEventHandlers) { globalThis.picorubyEventHandlers = {}; } globalThis.picorubyEventHandlers[callback_id] = { target, type, handler, capture: isCapture }; }
5709
5756
  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; }; }
5710
5757
  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; } }
5711
5758
  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; }
5712
5759
  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; } }
5713
- 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; } }
5760
+ 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, !!info.capture); delete globalThis.picorubyEventHandlers[callback_id]; return true; } catch(e) { console.error('Error in js_remove_event_listener:', e); return false; } }
5714
5761
  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; } }
5715
5762
  function js_create_text_node(text) { try { const node = document.createTextNode(UTF8ToString(text)); const refId = globalThis.picorubyRefs.push(node) - 1; return refId; } catch(e) { console.error('Error in js_create_text_node:', e); return -1; } }
5716
5763
  function js_create_object() { try { const obj = {}; const refId = globalThis.picorubyRefs.push(obj) - 1; return refId; } catch(e) { console.error('Error in js_create_object:', e); return -1; } }
@@ -5766,9 +5813,9 @@ function ws_set_onopen(ref_id,callback_id) { const ws = globalThis.picorubyRefs[
5766
5813
  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] ); } }; }
5767
5814
  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] ); }; }
5768
5815
  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] ); }; }
5769
- 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; } }
5770
- 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; } }
5771
- 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; } }
5816
+ 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) => { req.onsuccess = () => { resolve({ ok: true, value: req.result }); }; req.onerror = () => { resolve({ ok: false, name: (req.error && req.error.name) || 'UnknownError', message: (req.error && req.error.message) || 'IDB request failed' }); }; }); return globalThis.picorubyRefs.push(promise) - 1; } catch (e) { console.error('idb_request_to_promise failed:', e); return -1; } }
5817
+ function idb_open_with_upgrade(name_ptr,version,callback_id,blocked_timeout_ms) { try { const name = UTF8ToString(name_ptr); const idb = globalThis.indexedDB; if (!idb) { console.error('idb_open_with_upgrade: indexedDB unavailable'); return -1; } let req; try { req = (version > 0) ? idb.open(name, version) : idb.open(name); } catch (e) { const promise = Promise.resolve({ ok: false, name: (e && e.name) || 'UnknownError', message: (e && e.message) || 'IDB open failed' }); return globalThis.picorubyRefs.push(promise) - 1; } let settled = false; let timedOut = false; let blockedTimer = null; req.onupgradeneeded = (event) => { if (timedOut) { try { if (req.transaction) req.transaction.abort(); } catch (e) { console.error('failed to abort late IDB upgrade:', e); } return; } 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) => { const settle = (result) => { if (settled) return; settled = true; if (blockedTimer) { clearTimeout(blockedTimer); blockedTimer = null; } resolve(result); }; req.onsuccess = () => { if (settled) { try { req.result.close(); } catch (e) {} return; } settle({ ok: true, value: req.result }); }; req.onerror = () => { settle({ ok: false, name: (req.error && req.error.name) || 'UnknownError', message: (req.error && req.error.message) || 'IDB open failed' }); }; req.onblocked = () => { if (settled || blockedTimer) return; blockedTimer = setTimeout(() => { timedOut = true; settle({ ok: false, name: 'PicoRubyBlockedTimeout', message: 'IDB open blocked: another connection held an older version past the timeout' }); }, blocked_timeout_ms); }; }); return globalThis.picorubyRefs.push(promise) - 1; } catch (e) { console.error('idb_open_with_upgrade failed:', e); return -1; } }
5818
+ 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) => { tx.oncomplete = () => { resolve({ ok: true, value: true }); }; tx.onerror = () => { resolve({ ok: false, name: (tx.error && tx.error.name) || 'UnknownError', message: (tx.error && tx.error.message) || 'IDB transaction error' }); }; tx.onabort = () => { resolve({ ok: false, name: (tx.error && tx.error.name) || 'AbortError', message: (tx.error && tx.error.message) || 'IDB transaction aborted' }); }; }); return globalThis.picorubyRefs.push(promise) - 1; } catch (e) { console.error('idb_transaction_to_promise failed:', e); return -1; } }
5772
5819
  function emscripten_date_now() { return Date.now(); }
5773
5820
 
5774
5821
  // Imports from the Wasm binary.
@@ -5786,6 +5833,7 @@ var _mrb_debug_next = Module['_mrb_debug_next'] = makeInvalidEarlyAccess('_mrb_d
5786
5833
  var _mrb_debug_get_callstack = Module['_mrb_debug_get_callstack'] = makeInvalidEarlyAccess('_mrb_debug_get_callstack');
5787
5834
  var _call_ruby_callback = Module['_call_ruby_callback'] = makeInvalidEarlyAccess('_call_ruby_callback');
5788
5835
  var _call_ruby_callback_oneshot = Module['_call_ruby_callback_oneshot'] = makeInvalidEarlyAccess('_call_ruby_callback_oneshot');
5836
+ var _call_ruby_callback_sync_event = Module['_call_ruby_callback_sync_event'] = makeInvalidEarlyAccess('_call_ruby_callback_sync_event');
5789
5837
  var _resume_promise_task = Module['_resume_promise_task'] = makeInvalidEarlyAccess('_resume_promise_task');
5790
5838
  var _resume_promise_error_task = Module['_resume_promise_error_task'] = makeInvalidEarlyAccess('_resume_promise_error_task');
5791
5839
  var _resume_binary_task = Module['_resume_binary_task'] = makeInvalidEarlyAccess('_resume_binary_task');
@@ -5834,6 +5882,7 @@ function assignWasmExports(wasmExports) {
5834
5882
  assert(typeof wasmExports['mrb_debug_get_callstack'] != 'undefined', 'missing Wasm export: mrb_debug_get_callstack');
5835
5883
  assert(typeof wasmExports['call_ruby_callback'] != 'undefined', 'missing Wasm export: call_ruby_callback');
5836
5884
  assert(typeof wasmExports['call_ruby_callback_oneshot'] != 'undefined', 'missing Wasm export: call_ruby_callback_oneshot');
5885
+ assert(typeof wasmExports['call_ruby_callback_sync_event'] != 'undefined', 'missing Wasm export: call_ruby_callback_sync_event');
5837
5886
  assert(typeof wasmExports['resume_promise_task'] != 'undefined', 'missing Wasm export: resume_promise_task');
5838
5887
  assert(typeof wasmExports['resume_promise_error_task'] != 'undefined', 'missing Wasm export: resume_promise_error_task');
5839
5888
  assert(typeof wasmExports['resume_binary_task'] != 'undefined', 'missing Wasm export: resume_binary_task');
@@ -5878,6 +5927,7 @@ function assignWasmExports(wasmExports) {
5878
5927
  _mrb_debug_get_callstack = Module['_mrb_debug_get_callstack'] = createExportWrapper('mrb_debug_get_callstack', wasmExports['mrb_debug_get_callstack'], 0);
5879
5928
  _call_ruby_callback = Module['_call_ruby_callback'] = createExportWrapper('call_ruby_callback', wasmExports['call_ruby_callback'], 2);
5880
5929
  _call_ruby_callback_oneshot = Module['_call_ruby_callback_oneshot'] = createExportWrapper('call_ruby_callback_oneshot', wasmExports['call_ruby_callback_oneshot'], 2);
5930
+ _call_ruby_callback_sync_event = Module['_call_ruby_callback_sync_event'] = createExportWrapper('call_ruby_callback_sync_event', wasmExports['call_ruby_callback_sync_event'], 3);
5881
5931
  _resume_promise_task = Module['_resume_promise_task'] = createExportWrapper('resume_promise_task', wasmExports['resume_promise_task'], 4);
5882
5932
  _resume_promise_error_task = Module['_resume_promise_error_task'] = createExportWrapper('resume_promise_error_task', wasmExports['resume_promise_error_task'], 4);
5883
5933
  _resume_binary_task = Module['_resume_binary_task'] = createExportWrapper('resume_binary_task', wasmExports['resume_binary_task'], 5);