@scriptc/runtime 0.0.0 → 0.0.2

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 (416) hide show
  1. package/LICENSE +202 -0
  2. package/package.json +16 -6
  3. package/src/scr_array.c +488 -0
  4. package/src/scr_assert.c +1393 -0
  5. package/src/scr_async.c +2593 -0
  6. package/src/scr_async_dyn.c +607 -0
  7. package/src/scr_bytes.c +1425 -0
  8. package/src/scr_bytes_io.c +161 -0
  9. package/src/scr_child.c +3587 -0
  10. package/src/scr_closure.c +214 -0
  11. package/src/scr_console.c +143 -0
  12. package/src/scr_cycle.c +218 -0
  13. package/src/scr_dc.c +805 -0
  14. package/src/scr_dgram.c +1007 -0
  15. package/src/scr_dyn_handle.c +154 -0
  16. package/src/scr_dyn_invoke.c +644 -0
  17. package/src/scr_error.c +332 -0
  18. package/src/scr_events.c +714 -0
  19. package/src/scr_events_emitter.c +699 -0
  20. package/src/scr_exception.c +242 -0
  21. package/src/scr_fetch.c +1130 -0
  22. package/src/scr_fetch_curl.c +654 -0
  23. package/src/scr_http.c +3482 -0
  24. package/src/scr_http2.c +3030 -0
  25. package/src/scr_inspect.c +803 -0
  26. package/src/scr_inspect_island.c +51 -0
  27. package/src/scr_island.c +9363 -0
  28. package/src/scr_json.c +2151 -0
  29. package/src/scr_lib.c +3612 -0
  30. package/src/scr_loop_epoll.c +241 -0
  31. package/src/scr_loop_kqueue.c +121 -0
  32. package/src/scr_loop_wsapoll.c +208 -0
  33. package/src/scr_map.c +591 -0
  34. package/src/scr_net.c +3017 -0
  35. package/src/scr_net_island.c +458 -0
  36. package/src/scr_number.c +115 -0
  37. package/src/scr_object.c +25 -0
  38. package/src/scr_path.c +1266 -0
  39. package/src/scr_platform.h +119 -0
  40. package/src/scr_readline.c +287 -0
  41. package/src/scr_regex.c +1080 -0
  42. package/src/scr_runtime.h +5046 -0
  43. package/src/scr_stream.c +2877 -0
  44. package/src/scr_string.c +1264 -0
  45. package/src/scr_symbol.c +132 -0
  46. package/src/scr_test.c +662 -0
  47. package/src/scr_tls.c +1520 -0
  48. package/src/scr_union.c +105 -0
  49. package/src/scr_url.c +911 -0
  50. package/src/scr_url_internal.h +29 -0
  51. package/src/scr_url_params.c +561 -0
  52. package/src/scr_watch.c +568 -0
  53. package/src/scr_web.c +1778 -0
  54. package/src/scr_win.c +76 -0
  55. package/src/scr_zlib.c +197 -0
  56. package/src/scr_zlib_island.c +15 -0
  57. package/vendor/README.md +52 -0
  58. package/vendor/curl/COPYRIGHT +534 -0
  59. package/vendor/curl/include/curl/curl.h +3214 -0
  60. package/vendor/curl/include/curl/curlver.h +79 -0
  61. package/vendor/curl/include/curl/easy.h +125 -0
  62. package/vendor/curl/include/curl/header.h +74 -0
  63. package/vendor/curl/include/curl/mprintf.h +52 -0
  64. package/vendor/curl/include/curl/multi.h +460 -0
  65. package/vendor/curl/include/curl/options.h +70 -0
  66. package/vendor/curl/include/curl/stdcheaders.h +35 -0
  67. package/vendor/curl/include/curl/system.h +508 -0
  68. package/vendor/curl/include/curl/typecheck-gcc.h +716 -0
  69. package/vendor/curl/include/curl/urlapi.h +149 -0
  70. package/vendor/curl/include/curl/websockets.h +84 -0
  71. package/vendor/mbedtls/LICENSE +553 -0
  72. package/vendor/mbedtls/include/CMakeLists.txt +22 -0
  73. package/vendor/mbedtls/include/mbedtls/aes.h +631 -0
  74. package/vendor/mbedtls/include/mbedtls/aria.h +343 -0
  75. package/vendor/mbedtls/include/mbedtls/asn1.h +642 -0
  76. package/vendor/mbedtls/include/mbedtls/asn1write.h +390 -0
  77. package/vendor/mbedtls/include/mbedtls/base64.h +82 -0
  78. package/vendor/mbedtls/include/mbedtls/bignum.h +1088 -0
  79. package/vendor/mbedtls/include/mbedtls/block_cipher.h +76 -0
  80. package/vendor/mbedtls/include/mbedtls/build_info.h +194 -0
  81. package/vendor/mbedtls/include/mbedtls/camellia.h +305 -0
  82. package/vendor/mbedtls/include/mbedtls/ccm.h +526 -0
  83. package/vendor/mbedtls/include/mbedtls/chacha20.h +209 -0
  84. package/vendor/mbedtls/include/mbedtls/chachapoly.h +351 -0
  85. package/vendor/mbedtls/include/mbedtls/check_config.h +1149 -0
  86. package/vendor/mbedtls/include/mbedtls/cipher.h +1250 -0
  87. package/vendor/mbedtls/include/mbedtls/cmac.h +246 -0
  88. package/vendor/mbedtls/include/mbedtls/compat-2.x.h +46 -0
  89. package/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h +578 -0
  90. package/vendor/mbedtls/include/mbedtls/config_adjust_legacy_from_psa.h +873 -0
  91. package/vendor/mbedtls/include/mbedtls/config_adjust_psa_from_legacy.h +359 -0
  92. package/vendor/mbedtls/include/mbedtls/config_adjust_psa_superset_legacy.h +145 -0
  93. package/vendor/mbedtls/include/mbedtls/config_adjust_ssl.h +91 -0
  94. package/vendor/mbedtls/include/mbedtls/config_adjust_x509.h +35 -0
  95. package/vendor/mbedtls/include/mbedtls/config_psa.h +61 -0
  96. package/vendor/mbedtls/include/mbedtls/constant_time.h +36 -0
  97. package/vendor/mbedtls/include/mbedtls/ctr_drbg.h +596 -0
  98. package/vendor/mbedtls/include/mbedtls/debug.h +156 -0
  99. package/vendor/mbedtls/include/mbedtls/des.h +385 -0
  100. package/vendor/mbedtls/include/mbedtls/dhm.h +972 -0
  101. package/vendor/mbedtls/include/mbedtls/ecdh.h +455 -0
  102. package/vendor/mbedtls/include/mbedtls/ecdsa.h +674 -0
  103. package/vendor/mbedtls/include/mbedtls/ecjpake.h +298 -0
  104. package/vendor/mbedtls/include/mbedtls/ecp.h +1517 -0
  105. package/vendor/mbedtls/include/mbedtls/entropy.h +274 -0
  106. package/vendor/mbedtls/include/mbedtls/error.h +201 -0
  107. package/vendor/mbedtls/include/mbedtls/gcm.h +387 -0
  108. package/vendor/mbedtls/include/mbedtls/hkdf.h +124 -0
  109. package/vendor/mbedtls/include/mbedtls/hmac_drbg.h +434 -0
  110. package/vendor/mbedtls/include/mbedtls/lms.h +440 -0
  111. package/vendor/mbedtls/include/mbedtls/mbedtls_config.h +4446 -0
  112. package/vendor/mbedtls/include/mbedtls/md.h +526 -0
  113. package/vendor/mbedtls/include/mbedtls/md5.h +190 -0
  114. package/vendor/mbedtls/include/mbedtls/memory_buffer_alloc.h +142 -0
  115. package/vendor/mbedtls/include/mbedtls/net_sockets.h +299 -0
  116. package/vendor/mbedtls/include/mbedtls/nist_kw.h +166 -0
  117. package/vendor/mbedtls/include/mbedtls/oid.h +727 -0
  118. package/vendor/mbedtls/include/mbedtls/pem.h +160 -0
  119. package/vendor/mbedtls/include/mbedtls/pk.h +1303 -0
  120. package/vendor/mbedtls/include/mbedtls/pkcs12.h +186 -0
  121. package/vendor/mbedtls/include/mbedtls/pkcs5.h +198 -0
  122. package/vendor/mbedtls/include/mbedtls/pkcs7.h +252 -0
  123. package/vendor/mbedtls/include/mbedtls/platform.h +516 -0
  124. package/vendor/mbedtls/include/mbedtls/platform_time.h +79 -0
  125. package/vendor/mbedtls/include/mbedtls/platform_util.h +247 -0
  126. package/vendor/mbedtls/include/mbedtls/poly1305.h +168 -0
  127. package/vendor/mbedtls/include/mbedtls/private_access.h +20 -0
  128. package/vendor/mbedtls/include/mbedtls/psa_util.h +207 -0
  129. package/vendor/mbedtls/include/mbedtls/ripemd160.h +136 -0
  130. package/vendor/mbedtls/include/mbedtls/rsa.h +1170 -0
  131. package/vendor/mbedtls/include/mbedtls/sha1.h +219 -0
  132. package/vendor/mbedtls/include/mbedtls/sha256.h +200 -0
  133. package/vendor/mbedtls/include/mbedtls/sha3.h +172 -0
  134. package/vendor/mbedtls/include/mbedtls/sha512.h +208 -0
  135. package/vendor/mbedtls/include/mbedtls/ssl.h +5887 -0
  136. package/vendor/mbedtls/include/mbedtls/ssl_cache.h +187 -0
  137. package/vendor/mbedtls/include/mbedtls/ssl_ciphersuites.h +482 -0
  138. package/vendor/mbedtls/include/mbedtls/ssl_cookie.h +106 -0
  139. package/vendor/mbedtls/include/mbedtls/ssl_ticket.h +199 -0
  140. package/vendor/mbedtls/include/mbedtls/threading.h +167 -0
  141. package/vendor/mbedtls/include/mbedtls/timing.h +94 -0
  142. package/vendor/mbedtls/include/mbedtls/version.h +78 -0
  143. package/vendor/mbedtls/include/mbedtls/x509.h +500 -0
  144. package/vendor/mbedtls/include/mbedtls/x509_crl.h +184 -0
  145. package/vendor/mbedtls/include/mbedtls/x509_crt.h +1208 -0
  146. package/vendor/mbedtls/include/mbedtls/x509_csr.h +382 -0
  147. package/vendor/mbedtls/include/psa/build_info.h +20 -0
  148. package/vendor/mbedtls/include/psa/crypto.h +4998 -0
  149. package/vendor/mbedtls/include/psa/crypto_adjust_auto_enabled.h +31 -0
  150. package/vendor/mbedtls/include/psa/crypto_adjust_config_dependencies.h +51 -0
  151. package/vendor/mbedtls/include/psa/crypto_adjust_config_key_pair_types.h +101 -0
  152. package/vendor/mbedtls/include/psa/crypto_adjust_config_synonyms.h +49 -0
  153. package/vendor/mbedtls/include/psa/crypto_builtin_composites.h +214 -0
  154. package/vendor/mbedtls/include/psa/crypto_builtin_key_derivation.h +118 -0
  155. package/vendor/mbedtls/include/psa/crypto_builtin_primitives.h +114 -0
  156. package/vendor/mbedtls/include/psa/crypto_compat.h +230 -0
  157. package/vendor/mbedtls/include/psa/crypto_config.h +145 -0
  158. package/vendor/mbedtls/include/psa/crypto_driver_common.h +44 -0
  159. package/vendor/mbedtls/include/psa/crypto_driver_contexts_composites.h +151 -0
  160. package/vendor/mbedtls/include/psa/crypto_driver_contexts_key_derivation.h +52 -0
  161. package/vendor/mbedtls/include/psa/crypto_driver_contexts_primitives.h +105 -0
  162. package/vendor/mbedtls/include/psa/crypto_extra.h +2145 -0
  163. package/vendor/mbedtls/include/psa/crypto_legacy.h +88 -0
  164. package/vendor/mbedtls/include/psa/crypto_platform.h +102 -0
  165. package/vendor/mbedtls/include/psa/crypto_se_driver.h +1383 -0
  166. package/vendor/mbedtls/include/psa/crypto_sizes.h +1319 -0
  167. package/vendor/mbedtls/include/psa/crypto_struct.h +527 -0
  168. package/vendor/mbedtls/include/psa/crypto_types.h +508 -0
  169. package/vendor/mbedtls/include/psa/crypto_values.h +2782 -0
  170. package/vendor/mbedtls/library/aes.c +2294 -0
  171. package/vendor/mbedtls/library/aesce.c +624 -0
  172. package/vendor/mbedtls/library/aesce.h +136 -0
  173. package/vendor/mbedtls/library/aesni.c +846 -0
  174. package/vendor/mbedtls/library/aesni.h +162 -0
  175. package/vendor/mbedtls/library/alignment.h +704 -0
  176. package/vendor/mbedtls/library/aria.c +969 -0
  177. package/vendor/mbedtls/library/asn1parse.c +468 -0
  178. package/vendor/mbedtls/library/asn1write.c +440 -0
  179. package/vendor/mbedtls/library/base64.c +322 -0
  180. package/vendor/mbedtls/library/base64_internal.h +45 -0
  181. package/vendor/mbedtls/library/bignum.c +2583 -0
  182. package/vendor/mbedtls/library/bignum_core.c +1240 -0
  183. package/vendor/mbedtls/library/bignum_core.h +872 -0
  184. package/vendor/mbedtls/library/bignum_core_invasive.h +38 -0
  185. package/vendor/mbedtls/library/bignum_internal.h +122 -0
  186. package/vendor/mbedtls/library/bignum_mod.c +394 -0
  187. package/vendor/mbedtls/library/bignum_mod.h +452 -0
  188. package/vendor/mbedtls/library/bignum_mod_raw.c +276 -0
  189. package/vendor/mbedtls/library/bignum_mod_raw.h +416 -0
  190. package/vendor/mbedtls/library/bignum_mod_raw_invasive.h +34 -0
  191. package/vendor/mbedtls/library/block_cipher.c +207 -0
  192. package/vendor/mbedtls/library/block_cipher_internal.h +99 -0
  193. package/vendor/mbedtls/library/bn_mul.h +1094 -0
  194. package/vendor/mbedtls/library/camellia.c +1058 -0
  195. package/vendor/mbedtls/library/ccm.c +777 -0
  196. package/vendor/mbedtls/library/chacha20.c +563 -0
  197. package/vendor/mbedtls/library/chacha20_internal.h +23 -0
  198. package/vendor/mbedtls/library/chachapoly.c +487 -0
  199. package/vendor/mbedtls/library/check_crypto_config.h +136 -0
  200. package/vendor/mbedtls/library/cipher.c +1712 -0
  201. package/vendor/mbedtls/library/cipher_invasive.h +28 -0
  202. package/vendor/mbedtls/library/cipher_wrap.c +2482 -0
  203. package/vendor/mbedtls/library/cipher_wrap.h +178 -0
  204. package/vendor/mbedtls/library/cmac.c +1067 -0
  205. package/vendor/mbedtls/library/common.h +487 -0
  206. package/vendor/mbedtls/library/constant_time.c +247 -0
  207. package/vendor/mbedtls/library/constant_time_impl.h +541 -0
  208. package/vendor/mbedtls/library/constant_time_internal.h +579 -0
  209. package/vendor/mbedtls/library/ctr.h +35 -0
  210. package/vendor/mbedtls/library/ctr_drbg.c +1016 -0
  211. package/vendor/mbedtls/library/debug.c +475 -0
  212. package/vendor/mbedtls/library/debug_internal.h +185 -0
  213. package/vendor/mbedtls/library/des.c +1042 -0
  214. package/vendor/mbedtls/library/dhm.c +700 -0
  215. package/vendor/mbedtls/library/ecdh.c +696 -0
  216. package/vendor/mbedtls/library/ecdsa.c +858 -0
  217. package/vendor/mbedtls/library/ecjpake.c +1216 -0
  218. package/vendor/mbedtls/library/ecp.c +3674 -0
  219. package/vendor/mbedtls/library/ecp_curves.c +6125 -0
  220. package/vendor/mbedtls/library/ecp_curves_new.c +9 -0
  221. package/vendor/mbedtls/library/ecp_internal_alt.h +287 -0
  222. package/vendor/mbedtls/library/ecp_invasive.h +305 -0
  223. package/vendor/mbedtls/library/entropy.c +680 -0
  224. package/vendor/mbedtls/library/entropy_poll.c +233 -0
  225. package/vendor/mbedtls/library/entropy_poll.h +64 -0
  226. package/vendor/mbedtls/library/error.c +878 -0
  227. package/vendor/mbedtls/library/gcm.c +1330 -0
  228. package/vendor/mbedtls/library/hkdf.c +161 -0
  229. package/vendor/mbedtls/library/hmac_drbg.c +633 -0
  230. package/vendor/mbedtls/library/lmots.c +789 -0
  231. package/vendor/mbedtls/library/lmots.h +288 -0
  232. package/vendor/mbedtls/library/lms.c +778 -0
  233. package/vendor/mbedtls/library/md.c +1108 -0
  234. package/vendor/mbedtls/library/md5.c +426 -0
  235. package/vendor/mbedtls/library/md_psa.h +26 -0
  236. package/vendor/mbedtls/library/md_wrap.h +46 -0
  237. package/vendor/mbedtls/library/memory_buffer_alloc.c +751 -0
  238. package/vendor/mbedtls/library/mps_common.h +181 -0
  239. package/vendor/mbedtls/library/mps_error.h +89 -0
  240. package/vendor/mbedtls/library/mps_reader.c +538 -0
  241. package/vendor/mbedtls/library/mps_reader.h +366 -0
  242. package/vendor/mbedtls/library/mps_trace.c +112 -0
  243. package/vendor/mbedtls/library/mps_trace.h +154 -0
  244. package/vendor/mbedtls/library/net_sockets.c +694 -0
  245. package/vendor/mbedtls/library/nist_kw.c +729 -0
  246. package/vendor/mbedtls/library/oid.c +1166 -0
  247. package/vendor/mbedtls/library/padlock.c +157 -0
  248. package/vendor/mbedtls/library/padlock.h +111 -0
  249. package/vendor/mbedtls/library/pem.c +554 -0
  250. package/vendor/mbedtls/library/pk.c +1602 -0
  251. package/vendor/mbedtls/library/pk_ecc.c +261 -0
  252. package/vendor/mbedtls/library/pk_internal.h +241 -0
  253. package/vendor/mbedtls/library/pk_wrap.c +1618 -0
  254. package/vendor/mbedtls/library/pk_wrap.h +138 -0
  255. package/vendor/mbedtls/library/pkcs12.c +437 -0
  256. package/vendor/mbedtls/library/pkcs5.c +500 -0
  257. package/vendor/mbedtls/library/pkcs7.c +787 -0
  258. package/vendor/mbedtls/library/pkparse.c +1392 -0
  259. package/vendor/mbedtls/library/pkwrite.c +631 -0
  260. package/vendor/mbedtls/library/pkwrite.h +121 -0
  261. package/vendor/mbedtls/library/platform.c +402 -0
  262. package/vendor/mbedtls/library/platform_util.c +258 -0
  263. package/vendor/mbedtls/library/poly1305.c +492 -0
  264. package/vendor/mbedtls/library/psa_crypto.c +9532 -0
  265. package/vendor/mbedtls/library/psa_crypto_aead.c +646 -0
  266. package/vendor/mbedtls/library/psa_crypto_aead.h +499 -0
  267. package/vendor/mbedtls/library/psa_crypto_cipher.c +747 -0
  268. package/vendor/mbedtls/library/psa_crypto_cipher.h +316 -0
  269. package/vendor/mbedtls/library/psa_crypto_client.c +22 -0
  270. package/vendor/mbedtls/library/psa_crypto_core.h +983 -0
  271. package/vendor/mbedtls/library/psa_crypto_core_common.h +52 -0
  272. package/vendor/mbedtls/library/psa_crypto_driver_wrappers.h +2896 -0
  273. package/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.c +256 -0
  274. package/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.h +31 -0
  275. package/vendor/mbedtls/library/psa_crypto_ecp.c +594 -0
  276. package/vendor/mbedtls/library/psa_crypto_ecp.h +267 -0
  277. package/vendor/mbedtls/library/psa_crypto_ffdh.c +361 -0
  278. package/vendor/mbedtls/library/psa_crypto_ffdh.h +131 -0
  279. package/vendor/mbedtls/library/psa_crypto_hash.c +470 -0
  280. package/vendor/mbedtls/library/psa_crypto_hash.h +211 -0
  281. package/vendor/mbedtls/library/psa_crypto_invasive.h +92 -0
  282. package/vendor/mbedtls/library/psa_crypto_its.h +131 -0
  283. package/vendor/mbedtls/library/psa_crypto_mac.c +505 -0
  284. package/vendor/mbedtls/library/psa_crypto_mac.h +264 -0
  285. package/vendor/mbedtls/library/psa_crypto_pake.c +571 -0
  286. package/vendor/mbedtls/library/psa_crypto_pake.h +159 -0
  287. package/vendor/mbedtls/library/psa_crypto_random.c +181 -0
  288. package/vendor/mbedtls/library/psa_crypto_random.h +72 -0
  289. package/vendor/mbedtls/library/psa_crypto_random_impl.h +200 -0
  290. package/vendor/mbedtls/library/psa_crypto_rsa.c +714 -0
  291. package/vendor/mbedtls/library/psa_crypto_rsa.h +321 -0
  292. package/vendor/mbedtls/library/psa_crypto_se.c +373 -0
  293. package/vendor/mbedtls/library/psa_crypto_se.h +192 -0
  294. package/vendor/mbedtls/library/psa_crypto_slot_management.c +1137 -0
  295. package/vendor/mbedtls/library/psa_crypto_slot_management.h +344 -0
  296. package/vendor/mbedtls/library/psa_crypto_storage.c +481 -0
  297. package/vendor/mbedtls/library/psa_crypto_storage.h +392 -0
  298. package/vendor/mbedtls/library/psa_its_file.c +254 -0
  299. package/vendor/mbedtls/library/psa_util.c +614 -0
  300. package/vendor/mbedtls/library/psa_util_internal.h +100 -0
  301. package/vendor/mbedtls/library/ripemd160.c +490 -0
  302. package/vendor/mbedtls/library/rsa.c +3121 -0
  303. package/vendor/mbedtls/library/rsa_alt_helpers.c +455 -0
  304. package/vendor/mbedtls/library/rsa_alt_helpers.h +209 -0
  305. package/vendor/mbedtls/library/rsa_internal.h +188 -0
  306. package/vendor/mbedtls/library/sha1.c +480 -0
  307. package/vendor/mbedtls/library/sha256.c +983 -0
  308. package/vendor/mbedtls/library/sha3.c +721 -0
  309. package/vendor/mbedtls/library/sha512.c +1115 -0
  310. package/vendor/mbedtls/library/ssl_cache.c +410 -0
  311. package/vendor/mbedtls/library/ssl_ciphersuites.c +2050 -0
  312. package/vendor/mbedtls/library/ssl_ciphersuites_internal.h +154 -0
  313. package/vendor/mbedtls/library/ssl_client.c +1023 -0
  314. package/vendor/mbedtls/library/ssl_client.h +22 -0
  315. package/vendor/mbedtls/library/ssl_cookie.c +384 -0
  316. package/vendor/mbedtls/library/ssl_debug_helpers.h +85 -0
  317. package/vendor/mbedtls/library/ssl_debug_helpers_generated.c +251 -0
  318. package/vendor/mbedtls/library/ssl_misc.h +3198 -0
  319. package/vendor/mbedtls/library/ssl_msg.c +6619 -0
  320. package/vendor/mbedtls/library/ssl_ticket.c +556 -0
  321. package/vendor/mbedtls/library/ssl_tls.c +10234 -0
  322. package/vendor/mbedtls/library/ssl_tls12_client.c +3688 -0
  323. package/vendor/mbedtls/library/ssl_tls12_server.c +4311 -0
  324. package/vendor/mbedtls/library/ssl_tls13_client.c +3208 -0
  325. package/vendor/mbedtls/library/ssl_tls13_generic.c +1793 -0
  326. package/vendor/mbedtls/library/ssl_tls13_invasive.h +23 -0
  327. package/vendor/mbedtls/library/ssl_tls13_keys.c +1918 -0
  328. package/vendor/mbedtls/library/ssl_tls13_keys.h +668 -0
  329. package/vendor/mbedtls/library/ssl_tls13_server.c +3624 -0
  330. package/vendor/mbedtls/library/threading.c +193 -0
  331. package/vendor/mbedtls/library/threading_internal.h +28 -0
  332. package/vendor/mbedtls/library/timing.c +152 -0
  333. package/vendor/mbedtls/library/version.c +32 -0
  334. package/vendor/mbedtls/library/version_features.c +856 -0
  335. package/vendor/mbedtls/library/x509.c +1776 -0
  336. package/vendor/mbedtls/library/x509_create.c +570 -0
  337. package/vendor/mbedtls/library/x509_crl.c +708 -0
  338. package/vendor/mbedtls/library/x509_crt.c +3311 -0
  339. package/vendor/mbedtls/library/x509_csr.c +648 -0
  340. package/vendor/mbedtls/library/x509_internal.h +101 -0
  341. package/vendor/mbedtls/library/x509write.c +174 -0
  342. package/vendor/mbedtls/library/x509write_crt.c +688 -0
  343. package/vendor/mbedtls/library/x509write_csr.c +336 -0
  344. package/vendor/quickjs-ng/CMakeLists.txt +566 -0
  345. package/vendor/quickjs-ng/LICENSE +24 -0
  346. package/vendor/quickjs-ng/README.md +24 -0
  347. package/vendor/quickjs-ng/api-test.c +1195 -0
  348. package/vendor/quickjs-ng/builtin-array-fromasync.h +119 -0
  349. package/vendor/quickjs-ng/builtin-iterator-zip-keyed.h +332 -0
  350. package/vendor/quickjs-ng/builtin-iterator-zip.h +337 -0
  351. package/vendor/quickjs-ng/cutils.h +1998 -0
  352. package/vendor/quickjs-ng/dtoa.c +1619 -0
  353. package/vendor/quickjs-ng/dtoa.h +87 -0
  354. package/vendor/quickjs-ng/gen/function_source.c +81 -0
  355. package/vendor/quickjs-ng/gen/hello.c +53 -0
  356. package/vendor/quickjs-ng/gen/hello_module.c +106 -0
  357. package/vendor/quickjs-ng/gen/repl.c +3036 -0
  358. package/vendor/quickjs-ng/gen/standalone.c +323 -0
  359. package/vendor/quickjs-ng/gen/test_fib.c +81 -0
  360. package/vendor/quickjs-ng/libregexp-opcode.h +73 -0
  361. package/vendor/quickjs-ng/libregexp.c +3474 -0
  362. package/vendor/quickjs-ng/libregexp.h +101 -0
  363. package/vendor/quickjs-ng/libunicode-table.h +5173 -0
  364. package/vendor/quickjs-ng/libunicode.c +2069 -0
  365. package/vendor/quickjs-ng/libunicode.h +172 -0
  366. package/vendor/quickjs-ng/list.h +107 -0
  367. package/vendor/quickjs-ng/lre-test.c +52 -0
  368. package/vendor/quickjs-ng/qjs.c +762 -0
  369. package/vendor/quickjs-ng/qjsc.c +673 -0
  370. package/vendor/quickjs-ng/quickjs-atom.h +280 -0
  371. package/vendor/quickjs-ng/quickjs-c-atomics.h +54 -0
  372. package/vendor/quickjs-ng/quickjs-libc.c +5037 -0
  373. package/vendor/quickjs-ng/quickjs-libc.h +87 -0
  374. package/vendor/quickjs-ng/quickjs-opcode.h +377 -0
  375. package/vendor/quickjs-ng/quickjs.c +64041 -0
  376. package/vendor/quickjs-ng/quickjs.h +1447 -0
  377. package/vendor/quickjs-ng/run-test262.c +2374 -0
  378. package/vendor/quickjs-ng/unicode_gen.c +3121 -0
  379. package/vendor/quickjs-ng/unicode_gen_def.h +310 -0
  380. package/vendor/ryu/LICENSE-Boost +23 -0
  381. package/vendor/ryu/common.h +114 -0
  382. package/vendor/ryu/d2s.c +509 -0
  383. package/vendor/ryu/d2s_full_table.h +367 -0
  384. package/vendor/ryu/d2s_intrinsics.h +357 -0
  385. package/vendor/ryu/d2s_small_table.h +186 -0
  386. package/vendor/ryu/digit_table.h +35 -0
  387. package/vendor/ryu/ryu.h +46 -0
  388. package/vendor/zlib/LICENSE +22 -0
  389. package/vendor/zlib/adler32.c +164 -0
  390. package/vendor/zlib/compress.c +75 -0
  391. package/vendor/zlib/crc32.c +1049 -0
  392. package/vendor/zlib/crc32.h +9446 -0
  393. package/vendor/zlib/deflate.c +2139 -0
  394. package/vendor/zlib/deflate.h +377 -0
  395. package/vendor/zlib/gzclose.c +23 -0
  396. package/vendor/zlib/gzguts.h +214 -0
  397. package/vendor/zlib/gzlib.c +582 -0
  398. package/vendor/zlib/gzread.c +602 -0
  399. package/vendor/zlib/gzwrite.c +631 -0
  400. package/vendor/zlib/infback.c +628 -0
  401. package/vendor/zlib/inffast.c +320 -0
  402. package/vendor/zlib/inffast.h +11 -0
  403. package/vendor/zlib/inffixed.h +94 -0
  404. package/vendor/zlib/inflate.c +1526 -0
  405. package/vendor/zlib/inflate.h +126 -0
  406. package/vendor/zlib/inftrees.c +299 -0
  407. package/vendor/zlib/inftrees.h +62 -0
  408. package/vendor/zlib/trees.c +1117 -0
  409. package/vendor/zlib/trees.h +128 -0
  410. package/vendor/zlib/uncompr.c +85 -0
  411. package/vendor/zlib/zconf.h +543 -0
  412. package/vendor/zlib/zlib.h +1938 -0
  413. package/vendor/zlib/zutil.c +299 -0
  414. package/vendor/zlib/zutil.h +254 -0
  415. package/README.md +0 -3
  416. package/index.js +0 -2
package/src/scr_web.c ADDED
@@ -0,0 +1,1778 @@
1
+ /* Web-platform globals for the dynamic island: a pure-JS prelude evaluated
2
+ * once at engine boot (before any embedded module runs — eventsource-parser
3
+ * subclasses TransformStream at module-eval time), defining the WHATWG
4
+ * subset the embedded-npm request paths exercise. Compiled and linked ONLY
5
+ * under -DSCR_DYNAMIC, like scr_island.c.
6
+ *
7
+ * This file owns the semantics-heavy globals: the streams library
8
+ * (ReadableStream, TransformStream), the encoders (TextEncoder,
9
+ * TextDecoder — the WHATWG utf-8 state machine exactly, other labels
10
+ * fenced — and TextDecoderStream), URLSearchParams, btoa/atob, Headers,
11
+ * the fetch value classes (Request/Response with stream-or-bytes bodies,
12
+ * consumed through text/json/bytes/arrayBuffer; clone() fenced; plus the
13
+ * __scr_mk_response seam scr_fetch.c's glue builds wire responses
14
+ * through), DOMException and AbortController/AbortSignal (pure JS state;
15
+ * AbortSignal.timeout arms an unref'd island timer through host.timer —
16
+ * the machinery at the bottom of this file; fetch's signal wiring lives
17
+ * in scr_fetch.c's glue), crypto (getRandomValues/randomUUID over host functions
18
+ * bridging to the SAME arc4random_buf CSPRNG the static crypto lowerings
19
+ * use), and a console shim (String()-formatted writes to the real fds —
20
+ * no printf formatting, no object inspection). fetch itself lives in
21
+ * scr_fetch.c, linked only when the embedded graph references it. The correctness bar is the WHATWG
22
+ * subset the AI-SDK / eventsource-parser paths use — implemented honestly
23
+ * and pinned by the differential harness against Node's REAL
24
+ * implementations (the web-streams npm fixture, corpus 1120) plus
25
+ * scriptc-only fence tests (tests/harness/web-globals.test.ts). OUT,
26
+ * with clear errors: byte streams ('type': 'bytes') and BYOB readers,
27
+ * tee(), pipeTo(), custom queuing strategies (accepted, ignored — HWM is
28
+ * always 1), a global WritableStream (TransformStream.writable is an
29
+ * internal writable; the class is not exposed), and non-utf-8 TextDecoder
30
+ * labels. One documented behavioral divergence: transforms run EAGERLY on
31
+ * write (no readable-side backpressure), so writer.write() never blocks
32
+ * on downstream demand — order-exact, buffering-different. SEMANTICS.md
33
+ * states the subset; keep the three in sync.
34
+ *
35
+ * The JS was verified line-for-line against Node's native WHATWG
36
+ * implementations (a transcript battery: reader protocol, pull timing,
37
+ * error propagation both directions, cancel-on-break, flush ordering,
38
+ * utf-8 maximal-subpart replacement, BOM handling, form encoding, header
39
+ * combining/sorting) running under BOTH engines before being embedded. */
40
+ #ifdef SCR_DYNAMIC
41
+
42
+ #include "scr_runtime.h"
43
+
44
+ #include <math.h>
45
+ #include <stdio.h>
46
+ #include <stdlib.h>
47
+ #include <string.h>
48
+ #include <time.h>
49
+
50
+ #include "quickjs.h"
51
+
52
+ /* The prelude: one arrow function evaluated at boot and called with a host
53
+ * object (I/O-free today; the host parameter is the seam later slices —
54
+ * encoders, crypto — bridge through). */
55
+ static const char web_prelude[] =
56
+ "(host) => {\n"
57
+ " 'use strict';\n"
58
+ " const g = globalThis;\n"
59
+ "\n"
60
+ " /* Timers: Node's setTimeout/clearTimeout/setInterval/clearInterval\n"
61
+ " * for embedded code, bridged onto the SHARED static timer heap\n"
62
+ " * (host.setTimer/host.clearTimer) — REF'd like Node's (an armed\n"
63
+ " * timer keeps the process alive), FIFO-ordered against static\n"
64
+ " * timers on one heap, Node's <1ms clamp. Returns a Timeout-shaped\n"
65
+ " * object (ref/unref/refresh/close, numeric via toPrimitive) that\n"
66
+ " * clearTimeout/clearInterval accept alongside plain ids; unref is\n"
67
+ " * accepted but not honored (the entry stays ref'd — a documented\n"
68
+ " * approximation). */\n"
69
+ " class Timeout {\n"
70
+ " constructor(fn, delay, repeat) {\n"
71
+ " this._fn = fn;\n"
72
+ " this._delay = delay;\n"
73
+ " this._repeat = repeat;\n"
74
+ " this._id = host.setTimer(fn, delay, repeat);\n"
75
+ " }\n"
76
+ " ref() { return this; }\n"
77
+ " unref() { return this; }\n"
78
+ " hasRef() { return true; }\n"
79
+ " refresh() {\n"
80
+ " host.clearTimer(this._id);\n"
81
+ " this._id = host.setTimer(this._fn, this._delay, this._repeat);\n"
82
+ " return this;\n"
83
+ " }\n"
84
+ " close() { host.clearTimer(this._id); return this; }\n"
85
+ " [Symbol.toPrimitive]() { return this._id; }\n"
86
+ " }\n"
87
+ " const mkTimer = (fn, ms, args, repeat) => {\n"
88
+ " if (typeof fn !== 'function') {\n"
89
+ " throw new TypeError('The \"callback\" argument must be of type function. Received type ' + typeof fn);\n"
90
+ " }\n"
91
+ " const cb = args.length === 0 ? fn : () => fn(...args);\n"
92
+ " return new Timeout(cb, Number(ms), repeat);\n"
93
+ " };\n"
94
+ " g.setTimeout = (fn, ms, ...args) => mkTimer(fn, ms, args, false);\n"
95
+ " g.setInterval = (fn, ms, ...args) => mkTimer(fn, ms, args, true);\n"
96
+ " g.clearTimeout = (t) => {\n"
97
+ " if (t === undefined || t === null) return;\n"
98
+ " const id = typeof t === 'number' ? t : Number(t);\n"
99
+ " if (Number.isFinite(id)) host.clearTimer(id);\n"
100
+ " };\n"
101
+ " g.clearInterval = g.clearTimeout;\n"
102
+ "\n"
103
+ " class ReadableStream {\n"
104
+ " constructor(source, _strategy) {\n"
105
+ " if (source === undefined) source = {};\n"
106
+ " if (source === null || typeof source !== 'object') {\n"
107
+ " throw new TypeError('underlying source must be an object');\n"
108
+ " }\n"
109
+ " if (source.type !== undefined) {\n"
110
+ " throw new RangeError(\"byte streams (type: 'bytes') are not supported in the scriptc island\");\n"
111
+ " }\n"
112
+ " this._src = source;\n"
113
+ " this._queue = [];\n"
114
+ " this._state = 'readable';\n"
115
+ " this._storedError = undefined;\n"
116
+ " this._locked = false;\n"
117
+ " this._reads = [];\n"
118
+ " this._closeRequested = false;\n"
119
+ " this._started = false;\n"
120
+ " this._pulling = false;\n"
121
+ " this._pullAgain = false;\n"
122
+ " this._closedResolve = null;\n"
123
+ " this._closedReject = null;\n"
124
+ " const self = this;\n"
125
+ " this._controller = {\n"
126
+ " get desiredSize() {\n"
127
+ " if (self._state === 'errored') return null;\n"
128
+ " if (self._state === 'closed') return 0;\n"
129
+ " return 1 - self._queue.length;\n"
130
+ " },\n"
131
+ " enqueue(chunk) {\n"
132
+ " if (self._closeRequested || self._state !== 'readable') {\n"
133
+ " throw new TypeError('cannot enqueue on a stream that is ' + (self._closeRequested ? 'closing' : self._state));\n"
134
+ " }\n"
135
+ " if (self._reads.length > 0) self._reads.shift().resolve({ value: chunk, done: false });\n"
136
+ " else self._queue.push(chunk);\n"
137
+ " self._maybePull();\n"
138
+ " },\n"
139
+ " close() {\n"
140
+ " if (self._closeRequested || self._state !== 'readable') {\n"
141
+ " throw new TypeError('cannot close a stream that is ' + (self._closeRequested ? 'closing' : self._state));\n"
142
+ " }\n"
143
+ " self._closeRequested = true;\n"
144
+ " if (self._queue.length === 0) self._finishClose();\n"
145
+ " },\n"
146
+ " error(e) {\n"
147
+ " self._errorStream(e);\n"
148
+ " },\n"
149
+ " };\n"
150
+ " let startResult;\n"
151
+ " if (source.start) startResult = source.start(this._controller); // a sync throw propagates, per spec\n"
152
+ " Promise.resolve(startResult).then(\n"
153
+ " () => { this._started = true; this._maybePull(); },\n"
154
+ " (e) => this._errorStream(e),\n"
155
+ " );\n"
156
+ " }\n"
157
+ " _finishClose() {\n"
158
+ " if (this._state !== 'readable') return;\n"
159
+ " this._state = 'closed';\n"
160
+ " const reads = this._reads;\n"
161
+ " this._reads = [];\n"
162
+ " for (const r of reads) r.resolve({ value: undefined, done: true });\n"
163
+ " if (this._closedResolve) this._closedResolve();\n"
164
+ " }\n"
165
+ " _errorStream(e) {\n"
166
+ " if (this._state !== 'readable') return;\n"
167
+ " this._state = 'errored';\n"
168
+ " this._storedError = e;\n"
169
+ " this._queue.length = 0;\n"
170
+ " const reads = this._reads;\n"
171
+ " this._reads = [];\n"
172
+ " for (const r of reads) r.reject(e);\n"
173
+ " if (this._closedReject) this._closedReject(e);\n"
174
+ " }\n"
175
+ " /* Proactive pull, like the spec with the default HWM-1 strategy: pull\n"
176
+ " * whenever there is space (queue empty), started, and no pull running. */\n"
177
+ " _maybePull() {\n"
178
+ " const src = this._src;\n"
179
+ " if (!src.pull || !this._started) return;\n"
180
+ " if (this._state !== 'readable' || this._closeRequested) return;\n"
181
+ " if (this._queue.length >= 1) return;\n"
182
+ " if (this._pulling) { this._pullAgain = true; return; }\n"
183
+ " this._pulling = true;\n"
184
+ " Promise.resolve().then(() => {\n"
185
+ " if (this._state !== 'readable' || this._closeRequested) { this._pulling = false; return; }\n"
186
+ " let r;\n"
187
+ " try { r = src.pull(this._controller); } catch (e) { this._pulling = false; this._errorStream(e); return; }\n"
188
+ " Promise.resolve(r).then(\n"
189
+ " () => {\n"
190
+ " this._pulling = false;\n"
191
+ " if (this._pullAgain || this._queue.length === 0) { this._pullAgain = false; this._maybePull(); }\n"
192
+ " },\n"
193
+ " (e) => { this._pulling = false; this._errorStream(e); },\n"
194
+ " );\n"
195
+ " });\n"
196
+ " }\n"
197
+ " get locked() { return this._locked; }\n"
198
+ " cancel(reason) {\n"
199
+ " if (this._locked) return Promise.reject(new TypeError('cannot cancel a locked ReadableStream'));\n"
200
+ " return this._cancelInternal(reason);\n"
201
+ " }\n"
202
+ " _cancelInternal(reason) {\n"
203
+ " if (this._state === 'closed') return Promise.resolve();\n"
204
+ " if (this._state === 'errored') return Promise.reject(this._storedError);\n"
205
+ " this._queue.length = 0;\n"
206
+ " this._closeRequested = true;\n"
207
+ " this._finishClose();\n"
208
+ " const src = this._src;\n"
209
+ " return Promise.resolve(src.cancel ? src.cancel(reason) : undefined).then(() => undefined);\n"
210
+ " }\n"
211
+ " getReader(options) {\n"
212
+ " if (options !== undefined && options !== null && options.mode !== undefined) {\n"
213
+ " throw new TypeError('BYOB readers are not supported in the scriptc island');\n"
214
+ " }\n"
215
+ " if (this._locked) throw new TypeError('ReadableStream is locked');\n"
216
+ " this._locked = true;\n"
217
+ " const self = this;\n"
218
+ " let res, rej;\n"
219
+ " const closed = new Promise((a, b) => { res = a; rej = b; });\n"
220
+ " closed.catch(() => {});\n"
221
+ " this._closedResolve = res;\n"
222
+ " this._closedReject = rej;\n"
223
+ " if (this._state === 'closed') res();\n"
224
+ " else if (this._state === 'errored') rej(this._storedError);\n"
225
+ " let released = false;\n"
226
+ " return {\n"
227
+ " get closed() { return closed; },\n"
228
+ " read() {\n"
229
+ " if (released) return Promise.reject(new TypeError('reader has been released'));\n"
230
+ " if (self._queue.length > 0) {\n"
231
+ " const chunk = self._queue.shift();\n"
232
+ " if (self._closeRequested && self._queue.length === 0) self._finishClose();\n"
233
+ " else self._maybePull();\n"
234
+ " return Promise.resolve({ value: chunk, done: false });\n"
235
+ " }\n"
236
+ " if (self._state === 'closed') return Promise.resolve({ value: undefined, done: true });\n"
237
+ " if (self._state === 'errored') return Promise.reject(self._storedError);\n"
238
+ " return new Promise((resolve, reject) => {\n"
239
+ " self._reads.push({ resolve, reject });\n"
240
+ " self._maybePull();\n"
241
+ " });\n"
242
+ " },\n"
243
+ " releaseLock() {\n"
244
+ " if (released) return;\n"
245
+ " released = true;\n"
246
+ " const reads = self._reads;\n"
247
+ " self._reads = [];\n"
248
+ " for (const r of reads) r.reject(new TypeError('reader was released'));\n"
249
+ " self._locked = false;\n"
250
+ " self._closedResolve = null;\n"
251
+ " self._closedReject = null;\n"
252
+ " },\n"
253
+ " cancel(reason) {\n"
254
+ " if (released) return Promise.reject(new TypeError('reader has been released'));\n"
255
+ " return self._cancelInternal(reason);\n"
256
+ " },\n"
257
+ " };\n"
258
+ " }\n"
259
+ " /* The iterator carries a `finished` latch because the ENGINE's\n"
260
+ " * for-await closes more eagerly than V8: quickjs-ng calls return()\n"
261
+ " * on NORMAL completion and after a next() rejection (V8 does\n"
262
+ " * neither), and an unlatched return() would then cancel a released\n"
263
+ " * reader — minting a rejected promise nobody awaits, which the\n"
264
+ " * unhandled-rejection tracker reports at exit. Same story for the\n"
265
+ " * no-op catch on return()'s result: the engine drops it on those\n"
266
+ " * paths, so a real cancel rejection must be pre-observed (callers\n"
267
+ " * who DO await it — the break path — still see the rejection). */\n"
268
+ " values(options) {\n"
269
+ " const preventCancel = options !== undefined && options !== null && !!options.preventCancel;\n"
270
+ " const reader = this.getReader();\n"
271
+ " let finished = false;\n"
272
+ " const it = {\n"
273
+ " next() {\n"
274
+ " if (finished) return Promise.resolve({ value: undefined, done: true });\n"
275
+ " return reader.read().then(\n"
276
+ " (r) => {\n"
277
+ " if (r.done) { finished = true; reader.releaseLock(); }\n"
278
+ " return r;\n"
279
+ " },\n"
280
+ " (e) => { finished = true; reader.releaseLock(); throw e; },\n"
281
+ " );\n"
282
+ " },\n"
283
+ " return(v) {\n"
284
+ " if (finished) return Promise.resolve({ value: v, done: true });\n"
285
+ " finished = true;\n"
286
+ " const p = preventCancel ? Promise.resolve() : reader.cancel(v);\n"
287
+ " reader.releaseLock();\n"
288
+ " const res = p.then(() => ({ value: v, done: true }));\n"
289
+ " res.catch(() => {});\n"
290
+ " return res;\n"
291
+ " },\n"
292
+ " [Symbol.asyncIterator]() { return this; },\n"
293
+ " };\n"
294
+ " return it;\n"
295
+ " }\n"
296
+ " [Symbol.asyncIterator](options) { return this.values(options); }\n"
297
+ " pipeThrough(transform, options) {\n"
298
+ " if (transform === null || typeof transform !== 'object' || !transform.writable || !transform.readable) {\n"
299
+ " throw new TypeError('pipeThrough requires a { writable, readable } pair');\n"
300
+ " }\n"
301
+ " if (options !== undefined && options !== null && options.signal !== undefined) {\n"
302
+ " throw new Error('scriptc: AbortSignal is not supported by island streams yet');\n"
303
+ " }\n"
304
+ " pump(this, transform.writable);\n"
305
+ " return transform.readable;\n"
306
+ " }\n"
307
+ " pipeTo() {\n"
308
+ " throw new Error('ReadableStream.pipeTo is not supported in the scriptc island (use pipeThrough or a reader)');\n"
309
+ " }\n"
310
+ " tee() {\n"
311
+ " throw new Error('ReadableStream.tee is not supported in the scriptc island');\n"
312
+ " }\n"
313
+ " }\n"
314
+ "\n"
315
+ " /* The internal writable half of TransformStream. Deliberately NOT\n"
316
+ " * installed as a global WritableStream: the island fences the class\n"
317
+ " * (nothing in the supported graph constructs one). */\n"
318
+ " class WritableLite {\n"
319
+ " constructor(sink) {\n"
320
+ " this._sink = sink;\n"
321
+ " this._state = 'writable';\n"
322
+ " this._err = undefined;\n"
323
+ " this._locked = false;\n"
324
+ " this._closedRes = null;\n"
325
+ " this._closedRej = null;\n"
326
+ " }\n"
327
+ " get locked() { return this._locked; }\n"
328
+ " _error(e) {\n"
329
+ " if (this._state === 'errored') return;\n"
330
+ " this._state = 'errored';\n"
331
+ " this._err = e;\n"
332
+ " if (this._closedRej) this._closedRej(e);\n"
333
+ " }\n"
334
+ " abort(e) {\n"
335
+ " if (this._state === 'errored') return Promise.resolve();\n"
336
+ " this._error(e);\n"
337
+ " return Promise.resolve(this._sink.abort ? this._sink.abort(e) : undefined).then(() => undefined);\n"
338
+ " }\n"
339
+ " getWriter() {\n"
340
+ " if (this._locked) throw new TypeError('WritableStream is locked');\n"
341
+ " this._locked = true;\n"
342
+ " const self = this;\n"
343
+ " let res, rej;\n"
344
+ " const closed = new Promise((a, b) => { res = a; rej = b; });\n"
345
+ " closed.catch(() => {});\n"
346
+ " this._closedRes = res;\n"
347
+ " this._closedRej = rej;\n"
348
+ " if (this._state === 'errored') rej(this._err);\n"
349
+ " return {\n"
350
+ " get closed() { return closed; },\n"
351
+ " get ready() { return self._state === 'errored' ? Promise.reject(self._err) : Promise.resolve(); },\n"
352
+ " get desiredSize() {\n"
353
+ " if (self._state === 'errored') return null;\n"
354
+ " return self._state === 'writable' ? 1 : 0;\n"
355
+ " },\n"
356
+ " write(chunk) {\n"
357
+ " if (self._state === 'errored') return Promise.reject(self._err);\n"
358
+ " if (self._state !== 'writable') return Promise.reject(new TypeError('cannot write to a ' + self._state + ' stream'));\n"
359
+ " let r;\n"
360
+ " try { r = self._sink.write(chunk); } catch (e) { self._error(e); return Promise.reject(e); }\n"
361
+ " return Promise.resolve(r).catch((e) => { self._error(e); throw e; });\n"
362
+ " },\n"
363
+ " close() {\n"
364
+ " if (self._state === 'errored') return Promise.reject(self._err);\n"
365
+ " if (self._state !== 'writable') return Promise.reject(new TypeError('cannot close a ' + self._state + ' stream'));\n"
366
+ " self._state = 'closed';\n"
367
+ " let r;\n"
368
+ " try { r = self._sink.close ? self._sink.close() : undefined; } catch (e) { self._state = 'errored'; self._err = e; rej(e); return Promise.reject(e); }\n"
369
+ " return Promise.resolve(r).then(\n"
370
+ " () => { res(); },\n"
371
+ " (e) => { self._state = 'errored'; self._err = e; rej(e); throw e; },\n"
372
+ " );\n"
373
+ " },\n"
374
+ " abort(e) { return self.abort(e); },\n"
375
+ " releaseLock() { self._locked = false; },\n"
376
+ " };\n"
377
+ " }\n"
378
+ " }\n"
379
+ "\n"
380
+ " const pump = (rs, ws) => {\n"
381
+ " const reader = rs.getReader();\n"
382
+ " const writer = ws.getWriter();\n"
383
+ " const step = () =>\n"
384
+ " reader.read().then((r) => {\n"
385
+ " if (r.done) return writer.close();\n"
386
+ " return writer.write(r.value).then(step);\n"
387
+ " });\n"
388
+ " step().catch((e) => {\n"
389
+ " writer.abort(e).catch(() => {});\n"
390
+ " reader.cancel(e).catch(() => {});\n"
391
+ " });\n"
392
+ " };\n"
393
+ "\n"
394
+ " class TransformStream {\n"
395
+ " constructor(transformer, _ws, _rs) {\n"
396
+ " if (transformer === undefined || transformer === null) transformer = {};\n"
397
+ " if (transformer.readableType !== undefined || transformer.writableType !== undefined) {\n"
398
+ " throw new RangeError('readableType/writableType are not supported in the scriptc island');\n"
399
+ " }\n"
400
+ " const t = transformer;\n"
401
+ " const self = this;\n"
402
+ " let rc = null;\n"
403
+ " this._readable = new ReadableStream({\n"
404
+ " start(c) { rc = c; },\n"
405
+ " cancel(reason) { self._writable._error(reason); },\n"
406
+ " });\n"
407
+ " const tc = {\n"
408
+ " enqueue(chunk) { rc.enqueue(chunk); },\n"
409
+ " error(e) {\n"
410
+ " self._readable._errorStream(e);\n"
411
+ " self._writable._error(e);\n"
412
+ " },\n"
413
+ " terminate() {\n"
414
+ " if (self._readable._state === 'readable' && !self._readable._closeRequested) rc.close();\n"
415
+ " self._writable._error(new TypeError('The transform stream has been terminated'));\n"
416
+ " },\n"
417
+ " get desiredSize() { return rc.desiredSize; },\n"
418
+ " };\n"
419
+ " this._controller = tc;\n"
420
+ " this._writable = new WritableLite({\n"
421
+ " /* Eager transform: writes run the transformer immediately (no\n"
422
+ " * readable-side backpressure) — order-exact, documented. */\n"
423
+ " write(chunk) {\n"
424
+ " let r;\n"
425
+ " try { r = t.transform ? t.transform(chunk, tc) : tc.enqueue(chunk); } catch (e) { tc.error(e); throw e; }\n"
426
+ " return Promise.resolve(r).catch((e) => { tc.error(e); throw e; });\n"
427
+ " },\n"
428
+ " close() {\n"
429
+ " let r;\n"
430
+ " try { r = t.flush ? t.flush(tc) : undefined; } catch (e) { tc.error(e); throw e; }\n"
431
+ " return Promise.resolve(r).then(\n"
432
+ " () => {\n"
433
+ " if (self._readable._state === 'readable' && !self._readable._closeRequested) rc.close();\n"
434
+ " },\n"
435
+ " (e) => { tc.error(e); throw e; },\n"
436
+ " );\n"
437
+ " },\n"
438
+ " abort(e) { self._readable._errorStream(e); },\n"
439
+ " });\n"
440
+ " if (t.start) t.start(tc); // sync start, like eventsource-parser needs\n"
441
+ " }\n"
442
+ " get readable() { return this._readable; }\n"
443
+ " get writable() { return this._writable; }\n"
444
+ " }\n"
445
+ "\n"
446
+ " g.ReadableStream = ReadableStream;\n"
447
+ " g.TransformStream = TransformStream;\n"
448
+ "\n"
449
+ "\n"
450
+ " class TextEncoder {\n"
451
+ " get encoding() { return 'utf-8'; }\n"
452
+ " encode(input) {\n"
453
+ " const s = input === undefined ? '' : String(input);\n"
454
+ " const bytes = [];\n"
455
+ " for (let i = 0; i < s.length; i++) {\n"
456
+ " let c = s.charCodeAt(i);\n"
457
+ " if (c >= 0xd800 && c <= 0xdbff) {\n"
458
+ " const n = i + 1 < s.length ? s.charCodeAt(i + 1) : 0;\n"
459
+ " if (n >= 0xdc00 && n <= 0xdfff) { c = 0x10000 + ((c - 0xd800) << 10) + (n - 0xdc00); i++; }\n"
460
+ " else c = 0xfffd;\n"
461
+ " } else if (c >= 0xdc00 && c <= 0xdfff) c = 0xfffd;\n"
462
+ " if (c <= 0x7f) bytes.push(c);\n"
463
+ " else if (c <= 0x7ff) bytes.push(0xc0 | (c >> 6), 0x80 | (c & 63));\n"
464
+ " else if (c <= 0xffff) bytes.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 63), 0x80 | (c & 63));\n"
465
+ " else bytes.push(0xf0 | (c >> 18), 0x80 | ((c >> 12) & 63), 0x80 | ((c >> 6) & 63), 0x80 | (c & 63));\n"
466
+ " }\n"
467
+ " return new Uint8Array(bytes);\n"
468
+ " }\n"
469
+ " }\n"
470
+ "\n"
471
+ " /* The WHATWG utf-8 decoder state machine, exactly (maximal-subpart\n"
472
+ " * replacement, streaming carry, BOM stripping, fatal mode). */\n"
473
+ " class TextDecoder {\n"
474
+ " constructor(label, options) {\n"
475
+ " const l = String(label === undefined ? 'utf-8' : label).trim().toLowerCase();\n"
476
+ " if (l !== 'utf-8' && l !== 'utf8' && l !== 'unicode-1-1-utf-8') {\n"
477
+ " throw new RangeError(\"the scriptc island's TextDecoder supports utf-8 only (got '\" + l + \"')\");\n"
478
+ " }\n"
479
+ " this._fatal = !!(options && options.fatal);\n"
480
+ " this._ignoreBOM = !!(options && options.ignoreBOM);\n"
481
+ " this._cp = 0; this._needed = 0; this._seen = 0; this._lo = 0x80; this._hi = 0xbf;\n"
482
+ " this._bomPending = !this._ignoreBOM;\n"
483
+ " }\n"
484
+ " get encoding() { return 'utf-8'; }\n"
485
+ " get fatal() { return this._fatal; }\n"
486
+ " get ignoreBOM() { return this._ignoreBOM; }\n"
487
+ " _reset() {\n"
488
+ " this._cp = 0; this._needed = 0; this._seen = 0; this._lo = 0x80; this._hi = 0xbf;\n"
489
+ " this._bomPending = !this._ignoreBOM;\n"
490
+ " }\n"
491
+ " decode(input, options) {\n"
492
+ " const stream = !!(options && options.stream);\n"
493
+ " let bytes;\n"
494
+ " if (input === undefined) bytes = new Uint8Array(0);\n"
495
+ " else if (input instanceof Uint8Array) bytes = input;\n"
496
+ " else if (input instanceof ArrayBuffer) bytes = new Uint8Array(input);\n"
497
+ " else if (ArrayBuffer.isView(input)) bytes = new Uint8Array(input.buffer, input.byteOffset, input.byteLength);\n"
498
+ " else throw new TypeError('TextDecoder.decode takes an ArrayBuffer or ArrayBufferView');\n"
499
+ " const units = [];\n"
500
+ " const fail = () => {\n"
501
+ " if (this._fatal) { this._reset(); throw new TypeError('The encoded data was not valid utf-8'); }\n"
502
+ " units.push(0xfffd);\n"
503
+ " };\n"
504
+ " const emit = (cp) => {\n"
505
+ " if (cp <= 0xffff) units.push(cp);\n"
506
+ " else { cp -= 0x10000; units.push(0xd800 + (cp >> 10), 0xdc00 + (cp & 0x3ff)); }\n"
507
+ " };\n"
508
+ " for (let i = 0; i < bytes.length; i++) {\n"
509
+ " const b = bytes[i];\n"
510
+ " if (this._needed === 0) {\n"
511
+ " if (b <= 0x7f) { emit(b); continue; }\n"
512
+ " if (b >= 0xc2 && b <= 0xdf) { this._needed = 1; this._cp = b & 0x1f; }\n"
513
+ " else if (b >= 0xe0 && b <= 0xef) {\n"
514
+ " if (b === 0xe0) this._lo = 0xa0;\n"
515
+ " if (b === 0xed) this._hi = 0x9f;\n"
516
+ " this._needed = 2; this._cp = b & 0xf;\n"
517
+ " } else if (b >= 0xf0 && b <= 0xf4) {\n"
518
+ " if (b === 0xf0) this._lo = 0x90;\n"
519
+ " if (b === 0xf4) this._hi = 0x8f;\n"
520
+ " this._needed = 3; this._cp = b & 0x7;\n"
521
+ " } else fail();\n"
522
+ " continue;\n"
523
+ " }\n"
524
+ " if (b < this._lo || b > this._hi) {\n"
525
+ " this._cp = 0; this._needed = 0; this._seen = 0; this._lo = 0x80; this._hi = 0xbf;\n"
526
+ " fail();\n"
527
+ " i--; // reprocess as a sequence start\n"
528
+ " continue;\n"
529
+ " }\n"
530
+ " this._lo = 0x80; this._hi = 0xbf;\n"
531
+ " this._cp = (this._cp << 6) | (b & 0x3f);\n"
532
+ " if (++this._seen === this._needed) {\n"
533
+ " emit(this._cp);\n"
534
+ " this._cp = 0; this._needed = 0; this._seen = 0;\n"
535
+ " }\n"
536
+ " }\n"
537
+ " if (!stream && this._needed !== 0) {\n"
538
+ " this._cp = 0; this._needed = 0; this._seen = 0; this._lo = 0x80; this._hi = 0xbf;\n"
539
+ " fail();\n"
540
+ " }\n"
541
+ " let start = 0;\n"
542
+ " if (this._bomPending && units.length > 0) {\n"
543
+ " this._bomPending = false;\n"
544
+ " if (units[0] === 0xfeff) start = 1;\n"
545
+ " }\n"
546
+ " let s = '';\n"
547
+ " for (let i = start; i < units.length; i += 4096) {\n"
548
+ " s += String.fromCharCode.apply(null, units.slice(i, i + 4096));\n"
549
+ " }\n"
550
+ " if (!stream) { const keepIgnore = this._ignoreBOM; this._reset(); this._bomPending = !keepIgnore; }\n"
551
+ " return s;\n"
552
+ " }\n"
553
+ " }\n"
554
+ "\n"
555
+ " class TextDecoderStream extends g.TransformStream {\n"
556
+ " constructor(label, options) {\n"
557
+ " const dec = new TextDecoder(label, options);\n"
558
+ " super({\n"
559
+ " transform(chunk, c) {\n"
560
+ " const s = dec.decode(chunk, { stream: true });\n"
561
+ " if (s !== '') c.enqueue(s);\n"
562
+ " },\n"
563
+ " flush(c) {\n"
564
+ " const s = dec.decode();\n"
565
+ " if (s !== '') c.enqueue(s);\n"
566
+ " },\n"
567
+ " });\n"
568
+ " this._dec = dec;\n"
569
+ " }\n"
570
+ " get encoding() { return this._dec.encoding; }\n"
571
+ " get fatal() { return this._dec.fatal; }\n"
572
+ " get ignoreBOM() { return this._dec.ignoreBOM; }\n"
573
+ " }\n"
574
+ "\n"
575
+ " /* application/x-www-form-urlencoded serializer/parser (URLSearchParams). */\n"
576
+ " const FORM_SAFE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*-._';\n"
577
+ " const formEncode = (s) => {\n"
578
+ " const bytes = new TextEncoder().encode(s);\n"
579
+ " let out = '';\n"
580
+ " for (let i = 0; i < bytes.length; i++) {\n"
581
+ " const b = bytes[i];\n"
582
+ " const ch = String.fromCharCode(b);\n"
583
+ " if (b === 0x20) out += '+';\n"
584
+ " else if (FORM_SAFE.indexOf(ch) >= 0) out += ch;\n"
585
+ " else out += '%' + (b < 16 ? '0' : '') + b.toString(16).toUpperCase();\n"
586
+ " }\n"
587
+ " return out;\n"
588
+ " };\n"
589
+ " const formDecode = (s) => {\n"
590
+ " const bytes = [];\n"
591
+ " for (let i = 0; i < s.length; i++) {\n"
592
+ " const ch = s[i];\n"
593
+ " if (ch === '+') bytes.push(0x20);\n"
594
+ " else if (ch === '%' && i + 2 < s.length && /^[0-9a-fA-F]{2}$/.test(s.slice(i + 1, i + 3))) {\n"
595
+ " bytes.push(parseInt(s.slice(i + 1, i + 3), 16));\n"
596
+ " i += 2;\n"
597
+ " } else {\n"
598
+ " const enc = new TextEncoder().encode(ch);\n"
599
+ " for (let j = 0; j < enc.length; j++) bytes.push(enc[j]);\n"
600
+ " }\n"
601
+ " }\n"
602
+ " return new TextDecoder().decode(new Uint8Array(bytes));\n"
603
+ " };\n"
604
+ "\n"
605
+ " class URLSearchParams {\n"
606
+ " constructor(init) {\n"
607
+ " this._pairs = [];\n"
608
+ " if (init === undefined || init === null) return;\n"
609
+ " if (init instanceof URLSearchParams) {\n"
610
+ " for (const [k, v] of init._pairs) this._pairs.push([k, v]);\n"
611
+ " return;\n"
612
+ " }\n"
613
+ " if (typeof init === 'string') {\n"
614
+ " let s = init;\n"
615
+ " if (s.startsWith('?')) s = s.slice(1);\n"
616
+ " if (s === '') return;\n"
617
+ " for (const part of s.split('&')) {\n"
618
+ " if (part === '') continue;\n"
619
+ " const eq = part.indexOf('=');\n"
620
+ " if (eq < 0) this._pairs.push([formDecode(part), '']);\n"
621
+ " else this._pairs.push([formDecode(part.slice(0, eq)), formDecode(part.slice(eq + 1))]);\n"
622
+ " }\n"
623
+ " return;\n"
624
+ " }\n"
625
+ " if (typeof init === 'object') {\n"
626
+ " if (typeof init[Symbol.iterator] === 'function') {\n"
627
+ " for (const pair of init) {\n"
628
+ " const p = [...pair];\n"
629
+ " if (p.length !== 2) throw new TypeError('URLSearchParams sequence init entries must be [name, value] pairs');\n"
630
+ " this._pairs.push([String(p[0]), String(p[1])]);\n"
631
+ " }\n"
632
+ " } else {\n"
633
+ " for (const k of Object.keys(init)) this._pairs.push([String(k), String(init[k])]);\n"
634
+ " }\n"
635
+ " return;\n"
636
+ " }\n"
637
+ " throw new TypeError('unsupported URLSearchParams init');\n"
638
+ " }\n"
639
+ " get size() { return this._pairs.length; }\n"
640
+ " append(name, value) { this._pairs.push([String(name), String(value)]); }\n"
641
+ " delete(name, value) {\n"
642
+ " name = String(name);\n"
643
+ " const hasValue = value !== undefined;\n"
644
+ " if (hasValue) value = String(value);\n"
645
+ " this._pairs = this._pairs.filter(([k, v]) => k !== name || (hasValue && v !== value));\n"
646
+ " }\n"
647
+ " get(name) {\n"
648
+ " name = String(name);\n"
649
+ " for (const [k, v] of this._pairs) if (k === name) return v;\n"
650
+ " return null;\n"
651
+ " }\n"
652
+ " getAll(name) {\n"
653
+ " name = String(name);\n"
654
+ " const out = [];\n"
655
+ " for (const [k, v] of this._pairs) if (k === name) out.push(v);\n"
656
+ " return out;\n"
657
+ " }\n"
658
+ " has(name, value) {\n"
659
+ " name = String(name);\n"
660
+ " const hasValue = value !== undefined;\n"
661
+ " if (hasValue) value = String(value);\n"
662
+ " for (const [k, v] of this._pairs) if (k === name && (!hasValue || v === value)) return true;\n"
663
+ " return false;\n"
664
+ " }\n"
665
+ " set(name, value) {\n"
666
+ " name = String(name);\n"
667
+ " value = String(value);\n"
668
+ " let found = false;\n"
669
+ " const next = [];\n"
670
+ " for (const pair of this._pairs) {\n"
671
+ " if (pair[0] !== name) { next.push(pair); continue; }\n"
672
+ " if (!found) { next.push([name, value]); found = true; }\n"
673
+ " }\n"
674
+ " if (!found) next.push([name, value]);\n"
675
+ " this._pairs = next;\n"
676
+ " }\n"
677
+ " sort() {\n"
678
+ " // stable sort by name (code units), preserving value order per name\n"
679
+ " this._pairs = this._pairs\n"
680
+ " .map((p, i) => [p, i])\n"
681
+ " .sort((a, b) => (a[0][0] < b[0][0] ? -1 : a[0][0] > b[0][0] ? 1 : a[1] - b[1]))\n"
682
+ " .map((x) => x[0]);\n"
683
+ " }\n"
684
+ " toString() {\n"
685
+ " return this._pairs.map(([k, v]) => formEncode(k) + '=' + formEncode(v)).join('&');\n"
686
+ " }\n"
687
+ " forEach(fn, thisArg) {\n"
688
+ " for (const [k, v] of this._pairs.slice()) fn.call(thisArg, v, k, this);\n"
689
+ " }\n"
690
+ " *entries() { for (const [k, v] of this._pairs) yield [k, v]; }\n"
691
+ " *keys() { for (const [k] of this._pairs) yield k; }\n"
692
+ " *values() { for (const [, v] of this._pairs) yield v; }\n"
693
+ " [Symbol.iterator]() { return this.entries(); }\n"
694
+ " }\n"
695
+ "\n"
696
+ " const B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n"
697
+ " const invalidChar = (op) => {\n"
698
+ " const e = new Error(\"Invalid character\");\n"
699
+ " e.name = 'InvalidCharacterError';\n"
700
+ " return e;\n"
701
+ " };\n"
702
+ " const btoa = (data) => {\n"
703
+ " const s = String(data);\n"
704
+ " let out = '';\n"
705
+ " for (let i = 0; i < s.length; i += 3) {\n"
706
+ " const c0 = s.charCodeAt(i), c1 = i + 1 < s.length ? s.charCodeAt(i + 1) : NaN, c2 = i + 2 < s.length ? s.charCodeAt(i + 2) : NaN;\n"
707
+ " if (c0 > 0xff || c1 > 0xff || c2 > 0xff) throw invalidChar('btoa');\n"
708
+ " const n = (c0 << 16) | ((c1 || 0) << 8) | (c2 || 0);\n"
709
+ " out += B64[(n >> 18) & 63] + B64[(n >> 12) & 63] +\n"
710
+ " (Number.isNaN(c1) ? '=' : B64[(n >> 6) & 63]) +\n"
711
+ " (Number.isNaN(c2) ? '=' : B64[n & 63]);\n"
712
+ " }\n"
713
+ " return out;\n"
714
+ " };\n"
715
+ " const atob = (data) => {\n"
716
+ " // forgiving-base64: strip ASCII whitespace, then up to two trailing '='\n"
717
+ " let s = String(data).replace(/[\\t\\n\\f\\r ]+/g, '');\n"
718
+ " if (s.length % 4 === 0) s = s.replace(/={1,2}$/, '');\n"
719
+ " if (s.length % 4 === 1) throw invalidChar('atob');\n"
720
+ " let out = '';\n"
721
+ " let buf = 0, bits = 0;\n"
722
+ " for (let i = 0; i < s.length; i++) {\n"
723
+ " const v = B64.indexOf(s[i]);\n"
724
+ " if (v < 0) throw invalidChar('atob');\n"
725
+ " buf = (buf << 6) | v;\n"
726
+ " bits += 6;\n"
727
+ " if (bits >= 8) {\n"
728
+ " bits -= 8;\n"
729
+ " out += String.fromCharCode((buf >> bits) & 0xff);\n"
730
+ " }\n"
731
+ " }\n"
732
+ " return out;\n"
733
+ " };\n"
734
+ "\n"
735
+ " /* Headers: lowercase names, combine-on-append, sorted iteration. */\n"
736
+ " const HDR_TOKEN = /^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$/;\n"
737
+ " const normValue = (v) => String(v).replace(/^[\\t\\n\\r ]+|[\\t\\n\\r ]+$/g, '');\n"
738
+ " class Headers {\n"
739
+ " constructor(init) {\n"
740
+ " this._map = new Map(); // lowercased name -> [values]\n"
741
+ " if (init === undefined || init === null) return;\n"
742
+ " if (init instanceof Headers) {\n"
743
+ " for (const [k, vs] of init._map) this._map.set(k, vs.slice());\n"
744
+ " return;\n"
745
+ " }\n"
746
+ " if (typeof init === 'object' && typeof init[Symbol.iterator] === 'function') {\n"
747
+ " for (const pair of init) {\n"
748
+ " const p = [...pair];\n"
749
+ " if (p.length !== 2) throw new TypeError('Headers sequence init entries must be [name, value] pairs');\n"
750
+ " this.append(p[0], p[1]);\n"
751
+ " }\n"
752
+ " return;\n"
753
+ " }\n"
754
+ " if (typeof init === 'object') {\n"
755
+ " for (const k of Object.keys(init)) this.append(k, init[k]);\n"
756
+ " return;\n"
757
+ " }\n"
758
+ " throw new TypeError('unsupported Headers init');\n"
759
+ " }\n"
760
+ " _check(name) {\n"
761
+ " const n = String(name).toLowerCase();\n"
762
+ " if (!HDR_TOKEN.test(n)) throw new TypeError(`Invalid header name: \"${name}\"`);\n"
763
+ " return n;\n"
764
+ " }\n"
765
+ " append(name, value) {\n"
766
+ " const n = this._check(name);\n"
767
+ " const list = this._map.get(n);\n"
768
+ " if (list) list.push(normValue(value));\n"
769
+ " else this._map.set(n, [normValue(value)]);\n"
770
+ " }\n"
771
+ " set(name, value) { this._map.set(this._check(name), [normValue(value)]); }\n"
772
+ " get(name) {\n"
773
+ " const list = this._map.get(this._check(name));\n"
774
+ " return list ? list.join(', ') : null;\n"
775
+ " }\n"
776
+ " has(name) { return this._map.has(this._check(name)); }\n"
777
+ " delete(name) { this._map.delete(this._check(name)); }\n"
778
+ " getSetCookie() {\n"
779
+ " const list = this._map.get('set-cookie');\n"
780
+ " return list ? list.slice() : [];\n"
781
+ " }\n"
782
+ " _sorted() {\n"
783
+ " return [...this._map.keys()].sort().map((k) => [k, this._map.get(k).join(', ')]);\n"
784
+ " }\n"
785
+ " forEach(fn, thisArg) {\n"
786
+ " for (const [k, v] of this._sorted()) fn.call(thisArg, v, k, this);\n"
787
+ " }\n"
788
+ " *entries() { for (const p of this._sorted()) yield p; }\n"
789
+ " *keys() { for (const [k] of this._sorted()) yield k; }\n"
790
+ " *values() { for (const [, v] of this._sorted()) yield v; }\n"
791
+ " [Symbol.iterator]() { return this.entries(); }\n"
792
+ " }\n"
793
+ "\n"
794
+ /* Event + EventTarget + CustomEvent — the DOM event plumbing Node
795
+ * exposes as globals since v15. Synchronous dispatch on one target
796
+ * (no tree, no phases — composedPath answers []), once/capture-shaped
797
+ * options accepted, handleEvent objects honored, dispatchEvent
798
+ * answers !defaultPrevented. undici's fileapi/websocket classes
799
+ * extend Event at LOAD. */
800
+ " class Event {\n"
801
+ " constructor(type, init) {\n"
802
+ " if (arguments.length === 0) throw new TypeError(\"Failed to construct 'Event': 1 argument required, but only 0 present.\");\n"
803
+ " this._type = String(type);\n"
804
+ " this.bubbles = !!(init && init.bubbles);\n"
805
+ " this.cancelable = !!(init && init.cancelable);\n"
806
+ " this.composed = !!(init && init.composed);\n"
807
+ " this.defaultPrevented = false;\n"
808
+ " this.target = null;\n"
809
+ " this.currentTarget = null;\n"
810
+ " this.srcElement = null;\n"
811
+ " this.eventPhase = 0;\n"
812
+ " this.isTrusted = false;\n"
813
+ " this.returnValue = true;\n"
814
+ " this.timeStamp = Date.now();\n"
815
+ " this._stopImmediate = false;\n"
816
+ " }\n"
817
+ " get type() { return this._type; }\n"
818
+ " preventDefault() { if (this.cancelable) { this.defaultPrevented = true; this.returnValue = false; } }\n"
819
+ " stopPropagation() {}\n"
820
+ " stopImmediatePropagation() { this._stopImmediate = true; }\n"
821
+ " composedPath() { return []; }\n"
822
+ " }\n"
823
+ " Event.NONE = 0; Event.CAPTURING_PHASE = 1; Event.AT_TARGET = 2; Event.BUBBLING_PHASE = 3;\n"
824
+ " class CustomEvent extends Event {\n"
825
+ " constructor(type, init) {\n"
826
+ " super(type, init);\n"
827
+ " this.detail = init !== null && init !== undefined && init.detail !== undefined ? init.detail : null;\n"
828
+ " }\n"
829
+ " }\n"
830
+ " class EventTarget {\n"
831
+ " constructor() { this._et = Object.create(null); }\n"
832
+ " addEventListener(type, listener, options) {\n"
833
+ " if (listener === null || listener === undefined) return;\n"
834
+ " const t = String(type);\n"
835
+ " const once = !!(options !== null && typeof options === 'object' && options.once);\n"
836
+ " const list = this._et[t] || (this._et[t] = []);\n"
837
+ " for (const e of list) { if (e.listener === listener) return; }\n"
838
+ " list.push({ listener, once });\n"
839
+ " }\n"
840
+ " removeEventListener(type, listener) {\n"
841
+ " const list = this._et[String(type)];\n"
842
+ " if (!list) return;\n"
843
+ " const i = list.findIndex((e) => e.listener === listener);\n"
844
+ " if (i >= 0) list.splice(i, 1);\n"
845
+ " }\n"
846
+ " dispatchEvent(event) {\n"
847
+ " if (!(event instanceof Event)) throw new TypeError('The \"event\" argument must be an instance of Event.');\n"
848
+ " event.target = this;\n"
849
+ " event.currentTarget = this;\n"
850
+ " event.eventPhase = Event.AT_TARGET;\n"
851
+ " const list = this._et[event.type];\n"
852
+ " if (list) {\n"
853
+ " for (const e of [...list]) {\n"
854
+ " if (event._stopImmediate) break;\n"
855
+ " if (e.once) this.removeEventListener(event.type, e.listener);\n"
856
+ " if (typeof e.listener === 'function') e.listener.call(this, event);\n"
857
+ " else if (e.listener !== null && typeof e.listener.handleEvent === 'function') e.listener.handleEvent(event);\n"
858
+ " }\n"
859
+ " }\n"
860
+ " event.eventPhase = Event.NONE;\n"
861
+ " event.currentTarget = null;\n"
862
+ " return !event.defaultPrevented;\n"
863
+ " }\n"
864
+ " }\n"
865
+ "\n"
866
+ /* Blob + File — the WHATWG classes Node exposes as globals (and
867
+ * re-exports from node:buffer) since v18. Bytes concatenate at
868
+ * construction (strings through TextEncoder, views copied, nested
869
+ * Blobs flattened); type normalizes per spec (printable-ASCII-only,
870
+ * lowercased, else ""); slice carries WHATWG's negative-index
871
+ * clamping; stream() rides the prelude's own ReadableStream. undici
872
+ * (in embedded graphs) extends buffer.Blob at load. */
873
+ " const blobBytesOf = (parts) => {\n"
874
+ " const chunks = [];\n"
875
+ " let total = 0;\n"
876
+ " for (const p of parts) {\n"
877
+ " let u8;\n"
878
+ " if (typeof p === 'string') u8 = new TextEncoder().encode(p);\n"
879
+ " else if (p instanceof Blob) u8 = p._bytes;\n"
880
+ " else if (p instanceof ArrayBuffer) u8 = new Uint8Array(p.slice(0));\n"
881
+ " else if (ArrayBuffer.isView(p)) u8 = new Uint8Array(p.buffer.slice(p.byteOffset, p.byteOffset + p.byteLength));\n"
882
+ " else u8 = new TextEncoder().encode(String(p));\n"
883
+ " chunks.push(u8);\n"
884
+ " total += u8.length;\n"
885
+ " }\n"
886
+ " const out = new Uint8Array(total);\n"
887
+ " let off = 0;\n"
888
+ " for (const c of chunks) { out.set(c, off); off += c.length; }\n"
889
+ " return out;\n"
890
+ " };\n"
891
+ " const blobTypeOf = (t) => {\n"
892
+ " const s = String(t);\n"
893
+ " for (let i = 0; i < s.length; i++) {\n"
894
+ " const c = s.charCodeAt(i);\n"
895
+ " if (c < 0x20 || c > 0x7e) return '';\n"
896
+ " }\n"
897
+ " return s.toLowerCase();\n"
898
+ " };\n"
899
+ " class Blob {\n"
900
+ " constructor(parts = [], options = {}) {\n"
901
+ " if (typeof parts !== 'object' || parts === null || typeof parts[Symbol.iterator] !== 'function') {\n"
902
+ " throw new TypeError('The \"sources\" argument must be an instance of Iterable. Received ' + (parts === null ? 'null' : typeof parts));\n"
903
+ " }\n"
904
+ " this._bytes = blobBytesOf([...parts]);\n"
905
+ " this._type = options !== null && options !== undefined && options.type !== undefined ? blobTypeOf(options.type) : '';\n"
906
+ " }\n"
907
+ " get size() { return this._bytes.length; }\n"
908
+ " get type() { return this._type; }\n"
909
+ " async arrayBuffer() {\n"
910
+ " return this._bytes.buffer.slice(this._bytes.byteOffset, this._bytes.byteOffset + this._bytes.byteLength);\n"
911
+ " }\n"
912
+ " async bytes() { return new Uint8Array(this._bytes); }\n"
913
+ " async text() { return new TextDecoder().decode(this._bytes); }\n"
914
+ " slice(start, end, contentType) {\n"
915
+ " const size = this._bytes.length;\n"
916
+ " let s = start === undefined ? 0 : Math.trunc(Number(start) || 0);\n"
917
+ " s = s < 0 ? Math.max(size + s, 0) : Math.min(s, size);\n"
918
+ " let e = end === undefined ? size : Math.trunc(Number(end) || 0);\n"
919
+ " e = e < 0 ? Math.max(size + e, 0) : Math.min(e, size);\n"
920
+ " const b = new Blob([], contentType === undefined ? {} : { type: contentType });\n"
921
+ " b._bytes = this._bytes.slice(s, Math.max(e, s));\n"
922
+ " return b;\n"
923
+ " }\n"
924
+ " stream() {\n"
925
+ " const bytes = this._bytes;\n"
926
+ " return new ReadableStream({\n"
927
+ " start(c) {\n"
928
+ " if (bytes.length > 0) c.enqueue(new Uint8Array(bytes));\n"
929
+ " c.close();\n"
930
+ " },\n"
931
+ " });\n"
932
+ " }\n"
933
+ " get [Symbol.toStringTag]() { return 'Blob'; }\n"
934
+ " }\n"
935
+ " class File extends Blob {\n"
936
+ " constructor(fileBits, fileName, options = {}) {\n"
937
+ " if (arguments.length < 2) throw new TypeError('The \"fileName\" argument must be specified');\n"
938
+ " super(fileBits, options);\n"
939
+ " this._name = String(fileName);\n"
940
+ " this._lastModified = options !== null && options !== undefined && options.lastModified !== undefined ? Number(options.lastModified) : Date.now();\n"
941
+ " }\n"
942
+ " get name() { return this._name; }\n"
943
+ " get lastModified() { return this._lastModified; }\n"
944
+ " get webkitRelativePath() { return ''; }\n"
945
+ " get [Symbol.toStringTag]() { return 'File'; }\n"
946
+ " }\n"
947
+ "\n"
948
+ " g.TextEncoder = TextEncoder;\n"
949
+ " g.TextDecoder = TextDecoder;\n"
950
+ " g.TextDecoderStream = TextDecoderStream;\n"
951
+ " g.URLSearchParams = URLSearchParams;\n"
952
+ " g.btoa = btoa;\n"
953
+ " g.atob = atob;\n"
954
+ " g.Headers = Headers;\n"
955
+ " g.Blob = Blob;\n"
956
+ " g.File = File;\n"
957
+ " g.Event = Event;\n"
958
+ " g.CustomEvent = CustomEvent;\n"
959
+ " g.EventTarget = EventTarget;\n"
960
+ "\n"
961
+ " /* DOMException + AbortController/AbortSignal: pure JS state, with the\n"
962
+ " * ONE host hook AbortSignal.timeout needs (host.timer arms a one-shot\n"
963
+ " * island timer — unref'd like Node's, so an armed timeout never keeps\n"
964
+ " * the process alive). Default abort reasons match Node exactly:\n"
965
+ " * DOMException AbortError 'This operation was aborted' and\n"
966
+ " * TimeoutError 'The operation was aborted due to timeout'. */\n"
967
+ " const DOM_CODES = {\n"
968
+ " IndexSizeError: 1, HierarchyRequestError: 3, WrongDocumentError: 4,\n"
969
+ " InvalidCharacterError: 5, NoModificationAllowedError: 7, NotFoundError: 8,\n"
970
+ " NotSupportedError: 9, InUseAttributeError: 10, InvalidStateError: 11,\n"
971
+ " SyntaxError: 12, InvalidModificationError: 13, NamespaceError: 14,\n"
972
+ " InvalidAccessError: 15, TypeMismatchError: 17, SecurityError: 18,\n"
973
+ " NetworkError: 19, AbortError: 20, URLMismatchError: 21,\n"
974
+ " QuotaExceededError: 22, TimeoutError: 23, InvalidNodeTypeError: 24,\n"
975
+ " DataCloneError: 25,\n"
976
+ " };\n"
977
+ " class DOMException extends Error {\n"
978
+ " constructor(message, name) {\n"
979
+ " super(message === undefined ? '' : String(message));\n"
980
+ " this.name = name === undefined ? 'Error' : String(name);\n"
981
+ " }\n"
982
+ " get code() { return DOM_CODES[this.name] || 0; }\n"
983
+ " }\n"
984
+ "\n"
985
+ " const mkAbortError = () => new DOMException('This operation was aborted', 'AbortError');\n"
986
+ " const mkSignal = () => {\n"
987
+ " const s = Object.create(AbortSignal.prototype);\n"
988
+ " s._aborted = false;\n"
989
+ " s._reason = undefined;\n"
990
+ " s._onabort = null;\n"
991
+ " s._listeners = [];\n"
992
+ " return s;\n"
993
+ " };\n"
994
+ " /* Fires listeners in registration order (onabort first), each once-\n"
995
+ " * unregistered BEFORE its call like EventTarget; a throwing listener\n"
996
+ " * doesn't stop the others — the first error rethrows at the end. */\n"
997
+ " const signalAbort = (s, reason) => {\n"
998
+ " if (s._aborted) return;\n"
999
+ " s._aborted = true;\n"
1000
+ " s._reason = reason === undefined ? mkAbortError() : reason;\n"
1001
+ " const ev = { type: 'abort', target: s, currentTarget: s };\n"
1002
+ " let firstErr;\n"
1003
+ " let threw = false;\n"
1004
+ " if (s._onabort !== null) {\n"
1005
+ " try { s._onabort.call(s, ev); } catch (e) { firstErr = e; threw = true; }\n"
1006
+ " }\n"
1007
+ " for (const l of s._listeners.slice()) {\n"
1008
+ " if (l.once) s.removeEventListener('abort', l.fn);\n"
1009
+ " try { l.fn.call(s, ev); } catch (e) { if (!threw) { firstErr = e; threw = true; } }\n"
1010
+ " }\n"
1011
+ " if (threw) throw firstErr;\n"
1012
+ " };\n"
1013
+ "\n"
1014
+ " class AbortSignal {\n"
1015
+ " constructor() { throw new TypeError('Illegal constructor'); }\n"
1016
+ " get aborted() { return this._aborted; }\n"
1017
+ " get reason() { return this._reason; }\n"
1018
+ " get onabort() { return this._onabort; }\n"
1019
+ " set onabort(fn) { this._onabort = typeof fn === 'function' ? fn : null; }\n"
1020
+ " throwIfAborted() { if (this._aborted) throw this._reason; }\n"
1021
+ " addEventListener(type, fn, options) {\n"
1022
+ " if (String(type) !== 'abort' || typeof fn !== 'function') return;\n"
1023
+ " const once = options !== undefined && options !== null && !!options.once;\n"
1024
+ " this._listeners.push({ fn, once });\n"
1025
+ " }\n"
1026
+ " removeEventListener(type, fn) {\n"
1027
+ " if (String(type) !== 'abort') return;\n"
1028
+ " const i = this._listeners.findIndex((l) => l.fn === fn);\n"
1029
+ " if (i >= 0) this._listeners.splice(i, 1);\n"
1030
+ " }\n"
1031
+ " static abort(reason) {\n"
1032
+ " const s = mkSignal();\n"
1033
+ " s._aborted = true;\n"
1034
+ " s._reason = reason === undefined ? mkAbortError() : reason;\n"
1035
+ " return s;\n"
1036
+ " }\n"
1037
+ " static timeout(ms) {\n"
1038
+ " const s = mkSignal();\n"
1039
+ " host.timer(() => {\n"
1040
+ " signalAbort(s, new DOMException('The operation was aborted due to timeout', 'TimeoutError'));\n"
1041
+ " }, Number(ms));\n"
1042
+ " return s;\n"
1043
+ " }\n"
1044
+ " static any(signals) {\n"
1045
+ " const list = [...signals];\n"
1046
+ " const s = mkSignal();\n"
1047
+ " for (const src of list) {\n"
1048
+ " if (!(src instanceof AbortSignal)) throw new TypeError('AbortSignal.any takes AbortSignals');\n"
1049
+ " if (src._aborted) {\n"
1050
+ " s._aborted = true;\n"
1051
+ " s._reason = src._reason;\n"
1052
+ " return s;\n"
1053
+ " }\n"
1054
+ " }\n"
1055
+ " const handlers = [];\n"
1056
+ " for (const src of list) {\n"
1057
+ " const h = () => {\n"
1058
+ " for (const [sig, fn] of handlers) sig.removeEventListener('abort', fn);\n"
1059
+ " signalAbort(s, src._reason);\n"
1060
+ " };\n"
1061
+ " handlers.push([src, h]);\n"
1062
+ " src.addEventListener('abort', h);\n"
1063
+ " }\n"
1064
+ " return s;\n"
1065
+ " }\n"
1066
+ " }\n"
1067
+ "\n"
1068
+ " class AbortController {\n"
1069
+ " constructor() { this._signal = mkSignal(); }\n"
1070
+ " get signal() { return this._signal; }\n"
1071
+ " abort(reason) { signalAbort(this._signal, reason); }\n"
1072
+ " }\n"
1073
+ "\n"
1074
+ " g.DOMException = DOMException;\n"
1075
+ " g.AbortSignal = AbortSignal;\n"
1076
+ " g.AbortController = AbortController;\n"
1077
+ "\n"
1078
+ " /* structuredClone — the HTML StructuredSerialize subset the island\n"
1079
+ " * honestly carries: primitives (bigint included), plain objects and\n"
1080
+ " * arrays (cycles preserved through a memo, like Node), Map/Set/Date/\n"
1081
+ " * RegExp/ArrayBuffer/typed arrays, Blob/File (shared immutable\n"
1082
+ " * bytes), and DOMException (name/message per WebIDL serialization).\n"
1083
+ " * Class instances flatten to plain own-enumerable copies (the\n"
1084
+ " * spec's default record path). Functions and symbols throw the\n"
1085
+ " * spec's DataCloneError; transfer LISTS with members throw\n"
1086
+ " * DataCloneError too (nothing here is transferable — divergence:\n"
1087
+ " * Node transfers its streams). Option validation is Node's, byte\n"
1088
+ " * for byte. */\n"
1089
+ " const scErr = (m) => { const e = new TypeError(m); e.code = 'ERR_INVALID_ARG_TYPE'; return e; };\n"
1090
+ " const scClone = (v, memo) => {\n"
1091
+ " switch (typeof v) {\n"
1092
+ " case 'undefined': case 'boolean': case 'number': case 'string': case 'bigint':\n"
1093
+ " return v;\n"
1094
+ " case 'symbol':\n"
1095
+ " throw new DOMException('symbol could not be cloned.', 'DataCloneError');\n"
1096
+ " case 'function':\n"
1097
+ " throw new DOMException(String(v) + ' could not be cloned.', 'DataCloneError');\n"
1098
+ " }\n"
1099
+ " if (v === null) return null;\n"
1100
+ " const seen = memo.get(v);\n"
1101
+ " if (seen !== undefined) return seen;\n"
1102
+ " if (v instanceof Date) return new Date(v.getTime());\n"
1103
+ " if (v instanceof RegExp) return new RegExp(v.source, v.flags);\n"
1104
+ " if (v instanceof DOMException) return new DOMException(v.message, v.name);\n"
1105
+ " if (v instanceof ArrayBuffer) return v.slice(0);\n"
1106
+ " if (ArrayBuffer.isView(v)) return new v.constructor(v.buffer.slice(0), v.byteOffset, v.length);\n"
1107
+ " if (typeof g.Blob === 'function' && v instanceof g.Blob) return v;\n"
1108
+ " if (v instanceof Map) {\n"
1109
+ " const m = new Map();\n"
1110
+ " memo.set(v, m);\n"
1111
+ " for (const [k, val] of v) m.set(scClone(k, memo), scClone(val, memo));\n"
1112
+ " return m;\n"
1113
+ " }\n"
1114
+ " if (v instanceof Set) {\n"
1115
+ " const s = new Set();\n"
1116
+ " memo.set(v, s);\n"
1117
+ " for (const val of v) s.add(scClone(val, memo));\n"
1118
+ " return s;\n"
1119
+ " }\n"
1120
+ " if (Array.isArray(v)) {\n"
1121
+ " const a = new Array(v.length);\n"
1122
+ " memo.set(v, a);\n"
1123
+ " for (let i = 0; i < v.length; i++) if (i in v) a[i] = scClone(v[i], memo);\n"
1124
+ " return a;\n"
1125
+ " }\n"
1126
+ " /* Errors serialize name/message (the spec's error record). */\n"
1127
+ " if (v instanceof Error) {\n"
1128
+ " const e = new Error(v.message);\n"
1129
+ " e.name = v.name;\n"
1130
+ " memo.set(v, e);\n"
1131
+ " return e;\n"
1132
+ " }\n"
1133
+ " /* The default record path: own enumerable properties onto a plain\n"
1134
+ " * object (class prototypes flatten, like the spec). */\n"
1135
+ " const o = {};\n"
1136
+ " memo.set(v, o);\n"
1137
+ " for (const k of Object.keys(v)) o[k] = scClone(v[k], memo);\n"
1138
+ " return o;\n"
1139
+ " };\n"
1140
+ " g.structuredClone = function structuredClone(value, options) {\n"
1141
+ " if (arguments.length === 0) {\n"
1142
+ " const e = new TypeError('The \"The value argument must be specified\" argument must be specified');\n"
1143
+ " e.code = 'ERR_MISSING_ARGS';\n"
1144
+ " throw e;\n"
1145
+ " }\n"
1146
+ " if (options !== undefined && options !== null) {\n"
1147
+ " if (typeof options !== 'object' && typeof options !== 'function') {\n"
1148
+ " throw scErr(\"Failed to execute 'structuredClone': Options cannot be converted to a dictionary\");\n"
1149
+ " }\n"
1150
+ " const tr = options.transfer;\n"
1151
+ " if (tr !== undefined) {\n"
1152
+ " let list;\n"
1153
+ " /* WebIDL sequence conversion rejects strings (iterable or\n"
1154
+ " * not) — Node's transfer:'' error is the member error. */\n"
1155
+ " try {\n"
1156
+ " if (typeof tr === 'string') throw 0;\n"
1157
+ " list = [...tr];\n"
1158
+ " } catch (e) {\n"
1159
+ " throw scErr(\"Failed to execute 'structuredClone': transfer in Options can not be converted to sequence.\");\n"
1160
+ " }\n"
1161
+ " if (list.length > 0) {\n"
1162
+ " throw new DOMException('Found invalid value in transferList.', 'DataCloneError');\n"
1163
+ " }\n"
1164
+ " }\n"
1165
+ " }\n"
1166
+ " return scClone(value, new WeakMap());\n"
1167
+ " };\n"
1168
+ "\n"
1169
+ " /* MessageEvent + MessagePort/MessageChannel — Node globals (v15+),\n"
1170
+ " * the same-thread subset: postMessage queues a structuredClone COPY\n"
1171
+ " * on the peer; the queue drains as 'message' events on a microtask\n"
1172
+ " * once start() runs (adding a 'message' listener via on() starts,\n"
1173
+ " * like Node), and worker_threads' receiveMessageOnPort drains the\n"
1174
+ " * queue directly (its consumers — undici's structuredClone\n"
1175
+ " * fallback — never start()). on/once/off are the NodeEventTarget\n"
1176
+ " * compat surface: 'message' handlers receive the DATA, like Node. */\n"
1177
+ " class MessageEvent extends Event {\n"
1178
+ " constructor(type, init) {\n"
1179
+ " super(type, init);\n"
1180
+ " const d = init || {};\n"
1181
+ " this._data = d.data !== undefined ? d.data : null;\n"
1182
+ " this._origin = d.origin || '';\n"
1183
+ " this._lastEventId = d.lastEventId || '';\n"
1184
+ " this._ports = d.ports ? [...d.ports] : [];\n"
1185
+ " }\n"
1186
+ " get data() { return this._data; }\n"
1187
+ " get origin() { return this._origin; }\n"
1188
+ " get lastEventId() { return this._lastEventId; }\n"
1189
+ " get ports() { return this._ports; }\n"
1190
+ " }\n"
1191
+ " class MessagePort extends EventTarget {\n"
1192
+ " constructor() {\n"
1193
+ " super();\n"
1194
+ " this._other = null;\n"
1195
+ " this._queue = [];\n"
1196
+ " this._started = false;\n"
1197
+ " this._nodeHandlers = new Map();\n"
1198
+ " }\n"
1199
+ " postMessage(value) {\n"
1200
+ " if (this._other === null) return;\n"
1201
+ " this._other._queue.push({ message: g.structuredClone(value) });\n"
1202
+ " this._other._drain();\n"
1203
+ " }\n"
1204
+ " _drain() {\n"
1205
+ " if (!this._started) return;\n"
1206
+ " queueMicrotask(() => {\n"
1207
+ " while (this._started && this._queue.length > 0) {\n"
1208
+ " const { message } = this._queue.shift();\n"
1209
+ " this.dispatchEvent(new MessageEvent('message', { data: message }));\n"
1210
+ " }\n"
1211
+ " });\n"
1212
+ " }\n"
1213
+ " start() { this._started = true; this._drain(); }\n"
1214
+ " close() { this._started = false; queueMicrotask(() => this.dispatchEvent(new Event('close'))); }\n"
1215
+ " ref() { return this; }\n"
1216
+ " unref() { return this; }\n"
1217
+ " on(name, fn) {\n"
1218
+ " const h = (ev) => fn(name === 'message' || name === 'messageerror' ? ev.data : ev);\n"
1219
+ " this._nodeHandlers.set(fn, h);\n"
1220
+ " this.addEventListener(name, h);\n"
1221
+ " if (name === 'message') this.start();\n"
1222
+ " return this;\n"
1223
+ " }\n"
1224
+ " once(name, fn) {\n"
1225
+ " const h = (ev) => fn(name === 'message' || name === 'messageerror' ? ev.data : ev);\n"
1226
+ " this._nodeHandlers.set(fn, h);\n"
1227
+ " this.addEventListener(name, h, { once: true });\n"
1228
+ " if (name === 'message') this.start();\n"
1229
+ " return this;\n"
1230
+ " }\n"
1231
+ " off(name, fn) {\n"
1232
+ " const h = this._nodeHandlers.get(fn);\n"
1233
+ " if (h) { this.removeEventListener(name, h); this._nodeHandlers.delete(fn); }\n"
1234
+ " return this;\n"
1235
+ " }\n"
1236
+ " }\n"
1237
+ " MessagePort.prototype.addListener = MessagePort.prototype.on;\n"
1238
+ " MessagePort.prototype.removeListener = MessagePort.prototype.off;\n"
1239
+ " class MessageChannel {\n"
1240
+ " constructor() {\n"
1241
+ " this.port1 = new MessagePort();\n"
1242
+ " this.port2 = new MessagePort();\n"
1243
+ " this.port1._other = this.port2;\n"
1244
+ " this.port2._other = this.port1;\n"
1245
+ " }\n"
1246
+ " }\n"
1247
+ " g.MessageEvent = MessageEvent;\n"
1248
+ " g.MessagePort = MessagePort;\n"
1249
+ " g.MessageChannel = MessageChannel;\n"
1250
+ "\n"
1251
+ " const te = () => new g.TextEncoder();\n"
1252
+ "\n"
1253
+ " const coerceBodyBytes = (body) => {\n"
1254
+ " // → [bytes|stream, implicit content-type or null]\n"
1255
+ " if (typeof body === 'string') return [te().encode(body), 'text/plain;charset=UTF-8'];\n"
1256
+ " if (body instanceof g.URLSearchParams) {\n"
1257
+ " return [te().encode(String(body)), 'application/x-www-form-urlencoded;charset=UTF-8'];\n"
1258
+ " }\n"
1259
+ " if (body instanceof Uint8Array) return [new Uint8Array(body), null];\n"
1260
+ " if (body instanceof ArrayBuffer) return [new Uint8Array(body.slice(0)), null];\n"
1261
+ " if (ArrayBuffer.isView(body)) {\n"
1262
+ " return [new Uint8Array(body.buffer.slice(body.byteOffset, body.byteOffset + body.byteLength)), null];\n"
1263
+ " }\n"
1264
+ " if (body instanceof g.ReadableStream) return [body, null];\n"
1265
+ " throw new TypeError('unsupported body type in the scriptc island (string, Uint8Array, ArrayBuffer, URLSearchParams, or ReadableStream)');\n"
1266
+ " };\n"
1267
+ "\n"
1268
+ " const consume = (self) => {\n"
1269
+ " if (self._bodyUsed) return Promise.reject(new TypeError('Body is unusable: Body has already been read'));\n"
1270
+ " self._bodyUsed = true;\n"
1271
+ " const body = self._body;\n"
1272
+ " if (body === null) return Promise.resolve(new Uint8Array(0));\n"
1273
+ " if (body instanceof Uint8Array) return Promise.resolve(body);\n"
1274
+ " // a ReadableStream of Uint8Array (or string) chunks\n"
1275
+ " const chunks = [];\n"
1276
+ " let total = 0;\n"
1277
+ " const reader = body.getReader();\n"
1278
+ " const step = () =>\n"
1279
+ " reader.read().then((r) => {\n"
1280
+ " if (r.done) {\n"
1281
+ " const out = new Uint8Array(total);\n"
1282
+ " let off = 0;\n"
1283
+ " for (const c of chunks) { out.set(c, off); off += c.length; }\n"
1284
+ " return out;\n"
1285
+ " }\n"
1286
+ " const c = typeof r.value === 'string' ? te().encode(r.value) : r.value;\n"
1287
+ " if (!(c instanceof Uint8Array)) throw new TypeError('body stream produced a non-byte chunk');\n"
1288
+ " chunks.push(c);\n"
1289
+ " total += c.length;\n"
1290
+ " return step();\n"
1291
+ " });\n"
1292
+ " return step();\n"
1293
+ " };\n"
1294
+ "\n"
1295
+ " const bodyMixin = (cls) => {\n"
1296
+ " Object.defineProperties(cls.prototype, {\n"
1297
+ " body: {\n"
1298
+ " get() {\n"
1299
+ " if (this._body === null) return null;\n"
1300
+ " if (this._body instanceof Uint8Array) {\n"
1301
+ " // lazily wrap fixed bytes in a stream, once\n"
1302
+ " const bytes = this._body;\n"
1303
+ " const self = this;\n"
1304
+ " this._body = new g.ReadableStream({\n"
1305
+ " start(c) { c.enqueue(bytes); c.close(); },\n"
1306
+ " cancel() { self._bodyUsed = true; },\n"
1307
+ " });\n"
1308
+ " }\n"
1309
+ " return this._body;\n"
1310
+ " },\n"
1311
+ " configurable: true,\n"
1312
+ " },\n"
1313
+ " bodyUsed: { get() { return this._bodyUsed; }, configurable: true },\n"
1314
+ " });\n"
1315
+ " cls.prototype.arrayBuffer = function () {\n"
1316
+ " return consume(this).then((b) => b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength));\n"
1317
+ " };\n"
1318
+ " cls.prototype.bytes = function () { return consume(this); };\n"
1319
+ " cls.prototype.text = function () {\n"
1320
+ " return consume(this).then((b) => new g.TextDecoder().decode(b));\n"
1321
+ " };\n"
1322
+ " cls.prototype.json = function () { return this.text().then((t) => JSON.parse(t)); };\n"
1323
+ " cls.prototype.clone = function () {\n"
1324
+ " throw new Error(cls.name + '.clone is not supported in the scriptc island');\n"
1325
+ " };\n"
1326
+ " };\n"
1327
+ "\n"
1328
+ " const normalizeMethod = (m) => {\n"
1329
+ " const s = String(m);\n"
1330
+ " const u = s.toUpperCase();\n"
1331
+ " if (u === 'DELETE' || u === 'GET' || u === 'HEAD' || u === 'OPTIONS' || u === 'POST' || u === 'PUT') return u;\n"
1332
+ " if (u === 'CONNECT' || u === 'TRACE' || u === 'TRACK') throw new TypeError(`'${s}' HTTP method is unsupported.`);\n"
1333
+ " return s;\n"
1334
+ " };\n"
1335
+ "\n"
1336
+ " class Request {\n"
1337
+ " constructor(input, init) {\n"
1338
+ " init = init === undefined || init === null ? {} : init;\n"
1339
+ " if (input instanceof Request) {\n"
1340
+ " this._url = input._url;\n"
1341
+ " this._method = input._method;\n"
1342
+ " this._headers = new g.Headers(input._headers);\n"
1343
+ " this._body = input._body; // shared bytes; fetch copies\n"
1344
+ " this._signal = input._signal;\n"
1345
+ " } else {\n"
1346
+ " this._url = String(input);\n"
1347
+ " this._method = 'GET';\n"
1348
+ " this._headers = new g.Headers();\n"
1349
+ " this._body = null;\n"
1350
+ " this._signal = null;\n"
1351
+ " }\n"
1352
+ " if (init.method !== undefined) this._method = normalizeMethod(init.method);\n"
1353
+ " if (init.headers !== undefined) this._headers = new g.Headers(init.headers);\n"
1354
+ " if (init.signal !== undefined) {\n"
1355
+ " if (init.signal !== null && !(init.signal instanceof g.AbortSignal)) {\n"
1356
+ " throw new TypeError('Request init.signal must be an AbortSignal or null');\n"
1357
+ " }\n"
1358
+ " this._signal = init.signal;\n"
1359
+ " }\n"
1360
+ " if (init.body !== undefined && init.body !== null) {\n"
1361
+ " if (this._method === 'GET' || this._method === 'HEAD') {\n"
1362
+ " throw new TypeError('Request with GET/HEAD method cannot have body.');\n"
1363
+ " }\n"
1364
+ " const [bytes, ct] = coerceBodyBytes(init.body);\n"
1365
+ " this._body = bytes;\n"
1366
+ " if (ct !== null && !this._headers.has('content-type')) this._headers.set('content-type', ct);\n"
1367
+ " }\n"
1368
+ " this._bodyUsed = false;\n"
1369
+ " }\n"
1370
+ " get url() { return this._url; }\n"
1371
+ " get method() { return this._method; }\n"
1372
+ " get headers() { return this._headers; }\n"
1373
+ " /* Node's Request.signal is never null — a request built without one\n"
1374
+ " * carries an inert signal; mint it lazily on first access. */\n"
1375
+ " get signal() {\n"
1376
+ " if (this._signal === null) this._signal = mkSignal();\n"
1377
+ " return this._signal;\n"
1378
+ " }\n"
1379
+ " }\n"
1380
+ " bodyMixin(Request);\n"
1381
+ "\n"
1382
+ " class Response {\n"
1383
+ " constructor(body, init) {\n"
1384
+ " init = init === undefined || init === null ? {} : init;\n"
1385
+ " const status = init.status === undefined ? 200 : Number(init.status);\n"
1386
+ " if (!Number.isInteger(status) || status < 200 || status > 599) {\n"
1387
+ " throw new RangeError(`init[\"status\"] must be in the range of 200 to 599, inclusive.`);\n"
1388
+ " }\n"
1389
+ " this._status = status;\n"
1390
+ " this._statusText = init.statusText === undefined ? '' : String(init.statusText);\n"
1391
+ " this._headers = new g.Headers(init.headers);\n"
1392
+ " this._url = '';\n"
1393
+ " this._redirected = false;\n"
1394
+ " this._bodyUsed = false;\n"
1395
+ " if (body === undefined || body === null) {\n"
1396
+ " this._body = null;\n"
1397
+ " } else {\n"
1398
+ " const [bytes, ct] = coerceBodyBytes(body);\n"
1399
+ " this._body = bytes;\n"
1400
+ " if (ct !== null && !this._headers.has('content-type')) this._headers.set('content-type', ct);\n"
1401
+ " }\n"
1402
+ " }\n"
1403
+ " get status() { return this._status; }\n"
1404
+ " get statusText() { return this._statusText; }\n"
1405
+ " get ok() { return this._status >= 200 && this._status <= 299; }\n"
1406
+ " get headers() { return this._headers; }\n"
1407
+ " get url() { return this._url; }\n"
1408
+ " get redirected() { return this._redirected; }\n"
1409
+ " get type() { return 'default'; }\n"
1410
+ " static json(data, init) {\n"
1411
+ " const r = new Response(JSON.stringify(data), init);\n"
1412
+ " r._headers.set('content-type', 'application/json');\n"
1413
+ " return r;\n"
1414
+ " }\n"
1415
+ " }\n"
1416
+ " bodyMixin(Response);\n"
1417
+ "\n"
1418
+ " g.Request = Request;\n"
1419
+ " g.Response = Response;\n"
1420
+ " /* Internal: fetch builds Responses outside the constructor's 200–599\n"
1421
+ " * validation surface (statusText from the wire, url/redirected set). */\n"
1422
+ " g.__scr_mk_response = (status, statusText, headers, url, redirected, bodyStream) => {\n"
1423
+ " const r = new Response(null, { statusText: String(statusText) });\n"
1424
+ " r._status = status;\n"
1425
+ " r._headers = headers;\n"
1426
+ " r._url = url;\n"
1427
+ " r._redirected = redirected;\n"
1428
+ " r._body = bodyStream;\n"
1429
+ " return r;\n"
1430
+ " };\n"
1431
+ " /* crypto: randomness bridges to the HOST functions (one source of truth —\n"
1432
+ " * the same arc4random_buf CSPRNG behind the static crypto lowerings). */\n"
1433
+ " const intTA = ['Int8Array', 'Uint8Array', 'Uint8ClampedArray', 'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array', 'BigInt64Array', 'BigUint64Array'];\n"
1434
+ " g.crypto = {\n"
1435
+ " getRandomValues(ta) {\n"
1436
+ " const tag = ta === null || typeof ta !== 'object' ? '' : Object.prototype.toString.call(ta).slice(8, -1);\n"
1437
+ " if (intTA.indexOf(tag) < 0) {\n"
1438
+ " const e = new TypeError('crypto.getRandomValues takes an integer TypedArray');\n"
1439
+ " e.name = 'TypeMismatchError';\n"
1440
+ " throw e;\n"
1441
+ " }\n"
1442
+ " if (ta.byteLength > 65536) {\n"
1443
+ " const e = new Error('The requested length exceeds 65,536 bytes');\n"
1444
+ " e.name = 'QuotaExceededError';\n"
1445
+ " throw e;\n"
1446
+ " }\n"
1447
+ " host.fill(ta);\n"
1448
+ " return ta;\n"
1449
+ " },\n"
1450
+ " randomUUID() { return host.uuid(); },\n"
1451
+ " };\n"
1452
+ "\n"
1453
+ " /* console: String()-formatted, space-joined, newline-terminated writes to\n"
1454
+ " * the REAL fds (same stdio buffers as static console.log). No printf-style\n"
1455
+ " * formatting and no object inspection — SEMANTICS.md documents the\n"
1456
+ " * subset. */\n"
1457
+ " const consoleFmt = (args) => {\n"
1458
+ " let s = '';\n"
1459
+ " for (let i = 0; i < args.length; i++) {\n"
1460
+ " if (i > 0) s += ' ';\n"
1461
+ " try { s += String(args[i]); } catch (_e) { s += '[value]'; }\n"
1462
+ " }\n"
1463
+ " return s + '\\n';\n"
1464
+ " };\n"
1465
+ " const consoleTo = (fd) => (...args) => { host.write(fd, consoleFmt(args)); };\n"
1466
+ " g.console = {\n"
1467
+ " log: consoleTo(1),\n"
1468
+ " info: consoleTo(1),\n"
1469
+ " debug: consoleTo(1),\n"
1470
+ " warn: consoleTo(2),\n"
1471
+ " error: consoleTo(2),\n"
1472
+ " trace: consoleTo(2),\n"
1473
+ " };\n"
1474
+ "\n"
1475
+ " /* Date#toString/#toTimeString: the engine stops at the GMT offset\n"
1476
+ " * (\"Tue Jan 02 2024 00:00:00 GMT+0000\"); Node/V8 appends the zone's\n"
1477
+ " * long name (\"(Coordinated Universal Time)\"). The suffix rides\n"
1478
+ " * host.tzname(ms) — exact for UTC, the C library's zone name for\n"
1479
+ " * other zones (long names outside UTC are ICU data the runtime does\n"
1480
+ " * not carry; SEMANTICS.md). */\n"
1481
+ " {\n"
1482
+ " const dToString = Date.prototype.toString;\n"
1483
+ " const dToTimeString = Date.prototype.toTimeString;\n"
1484
+ " const dGetTime = Date.prototype.getTime;\n"
1485
+ " const withZone = (self, base) => {\n"
1486
+ " if (base === 'Invalid Date') return base;\n"
1487
+ " const name = host.tzname(dGetTime.call(self));\n"
1488
+ " return name === '' ? base : base + ' (' + name + ')';\n"
1489
+ " };\n"
1490
+ " Date.prototype.toString = function toString() { return withZone(this, dToString.call(this)); };\n"
1491
+ " Date.prototype.toTimeString = function toTimeString() { return withZone(this, dToTimeString.call(this)); };\n"
1492
+ " }\n"
1493
+ "}\n";
1494
+
1495
+ /* ── island timers (AbortSignal.timeout) ──────────────────────────────
1496
+ * One-shot engine callbacks on the loop's monotonic clock, armed by the
1497
+ * prelude's host.timer(fn, ms). UNREF'd like Node's AbortSignal.timeout
1498
+ * timer: an armed timer never keeps the loop alive (it joins neither the
1499
+ * exhaustion test nor io-pending unless already DUE); the island's io
1500
+ * poll caps its sleeps at the earliest deadline and fires due timers, so
1501
+ * a fetch timeout fires on time while the transfer keeps the loop
1502
+ * running. Fired on the main stack from the io hook — isl_entry already
1503
+ * re-anchored the engine. Unfired callbacks are freed at teardown. */
1504
+
1505
+ typedef struct WebTimer {
1506
+ double deadline_ms;
1507
+ JSContext *ctx;
1508
+ JSValue fn; /* owned */
1509
+ struct WebTimer *next;
1510
+ } WebTimer;
1511
+
1512
+ static WebTimer *web_timers = NULL;
1513
+
1514
+ /* ── the setTimeout/setInterval bridge (the prelude's host.setTimer) ──
1515
+ * Entries live on the STATIC timer heap (scr_async.c): ref'd liveness,
1516
+ * FIFO ordering against static timers, and clearing all come from there.
1517
+ * Each entry's closure captures the engine callback through a SCR_BOX_OBJ
1518
+ * whose retain/release manage this little handle. */
1519
+
1520
+ typedef struct {
1521
+ size_t rc;
1522
+ JSContext *ctx;
1523
+ JSValue fn; /* owned */
1524
+ } WebTimerFn;
1525
+
1526
+ static void *web_timerfn_retain(void *p) {
1527
+ WebTimerFn *h = p;
1528
+ h->rc++;
1529
+ return p;
1530
+ }
1531
+
1532
+ static void web_timerfn_release(void *p) {
1533
+ WebTimerFn *h = p;
1534
+ if (--h->rc == 0) {
1535
+ JS_FreeValue(h->ctx, h->fn);
1536
+ free(h);
1537
+ }
1538
+ }
1539
+
1540
+ /* The static-heap closure body: calls the engine callback on the main
1541
+ * stack (where the loop fires every timer), then drains the engine jobs
1542
+ * it queued (Node runs microtasks right after the macrotask). A throw
1543
+ * bridges into the loop's uncaught path, exactly like a static timer
1544
+ * callback's throw. */
1545
+ static void web_timer_fire_cb(ScrClosure *env) {
1546
+ WebTimerFn *h = scr_box_get_ref(env->caps[0]); /* +1 */
1547
+ JSValue r = JS_Call(h->ctx, h->fn, JS_UNDEFINED, 0, NULL);
1548
+ if (JS_IsException(r)) {
1549
+ scr_island_bridge_exception();
1550
+ } else {
1551
+ JS_FreeValue(h->ctx, r);
1552
+ scr_island_drain_jobs();
1553
+ }
1554
+ web_timerfn_release(h);
1555
+ }
1556
+
1557
+ static JSValue web_host_set_timer(JSContext *ctx, JSValueConst this_val,
1558
+ int argc, JSValueConst *argv) {
1559
+ (void)this_val;
1560
+ (void)argc;
1561
+ double ms = 0;
1562
+ if (JS_ToFloat64(ctx, &ms, argv[1])) return JS_EXCEPTION;
1563
+ bool repeat = JS_ToBool(ctx, argv[2]) > 0;
1564
+ WebTimerFn *h = malloc(sizeof *h);
1565
+ if (!h) {
1566
+ fprintf(stderr, "scriptc: out of memory\n");
1567
+ abort();
1568
+ }
1569
+ h->rc = 1;
1570
+ h->ctx = ctx;
1571
+ h->fn = JS_DupValue(ctx, argv[0]);
1572
+ ScrBox *box = scr_box_new_obj(web_timerfn_retain, web_timerfn_release, NULL);
1573
+ scr_box_set_ref(box, h); /* the box owns the +1 */
1574
+ ScrClosure *cb = scr_closure_new((void *)web_timer_fire_cb, 1);
1575
+ cb->caps[0] = box;
1576
+ double id = repeat ? scr_set_interval(cb, ms) : scr_set_timeout_handle(cb, ms);
1577
+ return JS_NewFloat64(ctx, id);
1578
+ }
1579
+
1580
+ static JSValue web_host_clear_timer(JSContext *ctx, JSValueConst this_val,
1581
+ int argc, JSValueConst *argv) {
1582
+ (void)this_val;
1583
+ (void)argc;
1584
+ double id = 0;
1585
+ if (JS_ToFloat64(ctx, &id, argv[0])) return JS_EXCEPTION;
1586
+ scr_clear_interval(id);
1587
+ return JS_UNDEFINED;
1588
+ }
1589
+
1590
+ static JSValue web_host_timer(JSContext *ctx, JSValueConst this_val, int argc,
1591
+ JSValueConst *argv) {
1592
+ (void)this_val;
1593
+ (void)argc;
1594
+ double ms = 0;
1595
+ if (JS_ToFloat64(ctx, &ms, argv[1])) return JS_EXCEPTION;
1596
+ if (!(ms >= 0)) ms = 0; /* NaN/negative clamp, like the static setTimeout */
1597
+ WebTimer *t = malloc(sizeof *t);
1598
+ if (!t) {
1599
+ fprintf(stderr, "scriptc: out of memory\n");
1600
+ abort();
1601
+ }
1602
+ t->deadline_ms = scr_now_ms() + ms;
1603
+ t->ctx = ctx;
1604
+ t->fn = JS_DupValue(ctx, argv[0]);
1605
+ t->next = web_timers;
1606
+ web_timers = t;
1607
+ return JS_UNDEFINED;
1608
+ }
1609
+
1610
+ double scr_island_timers_deadline(void) {
1611
+ double best = HUGE_VAL;
1612
+ for (WebTimer *t = web_timers; t; t = t->next) {
1613
+ if (t->deadline_ms < best) best = t->deadline_ms;
1614
+ }
1615
+ return best;
1616
+ }
1617
+
1618
+ bool scr_island_timers_due(void) {
1619
+ return web_timers != NULL && scr_island_timers_deadline() <= scr_now_ms();
1620
+ }
1621
+
1622
+ /* Fires every due timer (a callback may arm new ones — the scan restarts
1623
+ * after each firing, so late arrivals with passed deadlines fire too).
1624
+ * A throwing callback is our own glue misbehaving: reported, never fatal,
1625
+ * the remaining timers still fire. */
1626
+ bool scr_island_timers_fire_due(void) {
1627
+ bool fired = false;
1628
+ double now = scr_now_ms();
1629
+ for (;;) {
1630
+ WebTimer **link = &web_timers;
1631
+ WebTimer *due = NULL;
1632
+ while (*link) {
1633
+ if ((*link)->deadline_ms <= now) {
1634
+ due = *link;
1635
+ *link = due->next;
1636
+ break;
1637
+ }
1638
+ link = &(*link)->next;
1639
+ }
1640
+ if (!due) break;
1641
+ JSValue r = JS_Call(due->ctx, due->fn, JS_UNDEFINED, 0, NULL);
1642
+ if (JS_IsException(r)) {
1643
+ JSValue e = JS_GetException(due->ctx);
1644
+ const char *msg = JS_ToCString(due->ctx, e);
1645
+ fprintf(stderr, "scriptc: island timer callback threw: %s\n", msg ? msg : "?");
1646
+ if (msg) JS_FreeCString(due->ctx, msg);
1647
+ JS_FreeValue(due->ctx, e);
1648
+ } else {
1649
+ JS_FreeValue(due->ctx, r);
1650
+ }
1651
+ JS_FreeValue(due->ctx, due->fn);
1652
+ free(due);
1653
+ fired = true;
1654
+ }
1655
+ return fired;
1656
+ }
1657
+
1658
+ void scr_island_timers_teardown(void) {
1659
+ while (web_timers) {
1660
+ WebTimer *t = web_timers;
1661
+ web_timers = t->next;
1662
+ JS_FreeValue(t->ctx, t->fn);
1663
+ free(t);
1664
+ }
1665
+ }
1666
+
1667
+ /* ── host functions ───────────────────────────────────────────────────
1668
+ * The prelude's I/O-free exceptions: randomness (bridged to the SAME
1669
+ * arc4random_buf CSPRNG behind the static crypto lowerings — one source
1670
+ * of truth), console's fd writes (the real stdio buffers, interleaving
1671
+ * correctly with static console.log), and the timer above. Engine
1672
+ * ownership rules as ever: argv borrowed, results owned. */
1673
+
1674
+ /* host.fill(typedArray): fill the view's bytes with CSPRNG output. The
1675
+ * JS side already validated the view kind and the 65536-byte quota. */
1676
+ static JSValue web_host_fill(JSContext *ctx, JSValueConst this_val, int argc,
1677
+ JSValueConst *argv) {
1678
+ (void)this_val;
1679
+ (void)argc;
1680
+ size_t off = 0, len = 0, bpe = 0;
1681
+ JSValue ab = JS_GetTypedArrayBuffer(ctx, argv[0], &off, &len, &bpe);
1682
+ if (JS_IsException(ab)) return JS_EXCEPTION;
1683
+ size_t absize = 0;
1684
+ uint8_t *buf = JS_GetArrayBuffer(ctx, &absize, ab);
1685
+ JS_FreeValue(ctx, ab);
1686
+ if (!buf) return JS_EXCEPTION;
1687
+ if (len > 0) arc4random_buf(buf + off, len);
1688
+ return JS_UNDEFINED;
1689
+ }
1690
+
1691
+ static JSValue web_host_uuid(JSContext *ctx, JSValueConst this_val, int argc,
1692
+ JSValueConst *argv) {
1693
+ (void)this_val;
1694
+ (void)argc;
1695
+ (void)argv;
1696
+ ScrStr *s = scr_crypto_random_uuid(); /* +1 */
1697
+ JSValue r = JS_NewStringLen(ctx, s->data, s->len);
1698
+ scr_str_release(s);
1699
+ return r;
1700
+ }
1701
+
1702
+ /* Date#toString's timezone-name suffix (the prelude's Date patch): Node
1703
+ * prints the zone's CLDR long name ("Coordinated Universal Time"); without
1704
+ * ICU data the C library only knows the zone's own name for the instant
1705
+ * (tm_zone: "UTC", "CST" — DST-correct via localtime). UTC maps to its
1706
+ * exact CLDR spelling; every other zone renders the C library name — the
1707
+ * documented divergence in SEMANTICS.md. */
1708
+ static JSValue web_host_tzname(JSContext *ctx, JSValueConst this_val, int argc,
1709
+ JSValueConst *argv) {
1710
+ (void)this_val;
1711
+ (void)argc;
1712
+ double ms = 0;
1713
+ if (JS_ToFloat64(ctx, &ms, argv[0])) return JS_EXCEPTION;
1714
+ if (!isfinite(ms)) return JS_NewString(ctx, "");
1715
+ time_t t = (time_t)floor(ms / 1000.0);
1716
+ #if defined(_WIN32)
1717
+ /* MinGW's struct tm carries no tm_zone; tzname[] (after tzset) holds the
1718
+ * CRT's zone names — full names on Windows ("Central Standard Time"). */
1719
+ struct tm *lt = localtime(&t);
1720
+ if (lt == NULL) return JS_NewString(ctx, "");
1721
+ tzset();
1722
+ const char *name = tzname[lt->tm_isdst > 0 ? 1 : 0];
1723
+ #else
1724
+ struct tm tmv;
1725
+ if (localtime_r(&t, &tmv) == NULL) return JS_NewString(ctx, "");
1726
+ const char *name = tmv.tm_zone;
1727
+ #endif
1728
+ if (name == NULL) name = "";
1729
+ if (strcmp(name, "UTC") == 0) name = "Coordinated Universal Time";
1730
+ return JS_NewString(ctx, name);
1731
+ }
1732
+
1733
+ static JSValue web_host_write(JSContext *ctx, JSValueConst this_val, int argc,
1734
+ JSValueConst *argv) {
1735
+ (void)this_val;
1736
+ (void)argc;
1737
+ int32_t fd = 1;
1738
+ JS_ToInt32(ctx, &fd, argv[0]);
1739
+ size_t len;
1740
+ const char *s = JS_ToCStringLen(ctx, &len, argv[1]);
1741
+ if (!s) return JS_EXCEPTION;
1742
+ fwrite(s, 1, len, fd == 2 ? stderr : stdout);
1743
+ JS_FreeCString(ctx, s);
1744
+ return JS_UNDEFINED;
1745
+ }
1746
+
1747
+ void scr_island_web_boot(void *jsctx) {
1748
+ JSContext *ctx = (JSContext *)jsctx;
1749
+ JSValue fn = JS_Eval(ctx, web_prelude, sizeof web_prelude - 1,
1750
+ "<scr-web>", JS_EVAL_TYPE_GLOBAL);
1751
+ if (JS_IsException(fn)) {
1752
+ fprintf(stderr, "scriptc: island web prelude failed to evaluate\n");
1753
+ JSValue e = JS_GetException(ctx);
1754
+ JS_FreeValue(ctx, e);
1755
+ abort();
1756
+ }
1757
+ JSValue host = JS_NewObject(ctx);
1758
+ /* JS_SetPropertyStr consumes the function values. */
1759
+ JS_SetPropertyStr(ctx, host, "fill", JS_NewCFunction(ctx, web_host_fill, "fill", 1));
1760
+ JS_SetPropertyStr(ctx, host, "uuid", JS_NewCFunction(ctx, web_host_uuid, "uuid", 0));
1761
+ JS_SetPropertyStr(ctx, host, "write", JS_NewCFunction(ctx, web_host_write, "write", 2));
1762
+ JS_SetPropertyStr(ctx, host, "tzname", JS_NewCFunction(ctx, web_host_tzname, "tzname", 1));
1763
+ JS_SetPropertyStr(ctx, host, "timer", JS_NewCFunction(ctx, web_host_timer, "timer", 2));
1764
+ JS_SetPropertyStr(ctx, host, "setTimer", JS_NewCFunction(ctx, web_host_set_timer, "setTimer", 3));
1765
+ JS_SetPropertyStr(ctx, host, "clearTimer", JS_NewCFunction(ctx, web_host_clear_timer, "clearTimer", 1));
1766
+ JSValue r = JS_Call(ctx, fn, JS_UNDEFINED, 1, (JSValueConst *)&host);
1767
+ JS_FreeValue(ctx, host);
1768
+ JS_FreeValue(ctx, fn);
1769
+ if (JS_IsException(r)) {
1770
+ fprintf(stderr, "scriptc: island web prelude failed to run\n");
1771
+ JSValue e = JS_GetException(ctx);
1772
+ JS_FreeValue(ctx, e);
1773
+ abort();
1774
+ }
1775
+ JS_FreeValue(ctx, r);
1776
+ }
1777
+
1778
+ #endif /* SCR_DYNAMIC */