@scriptc/cli-darwin-arm64 0.2.1 → 0.2.3

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 (198) hide show
  1. package/dist/THIRD_PARTY_NOTICES +1 -1
  2. package/dist/bin/scriptc +0 -0
  3. package/dist/bin/scriptc.json +1 -1
  4. package/dist/lib/declarations/scriptc-node-fallback.d.ts +158 -31
  5. package/dist/lib/llvm/bin/scriptc-llvm-codegen +0 -0
  6. package/dist/lib/llvm/package.json +1 -1
  7. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_array.o +0 -0
  8. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_assert.o +0 -0
  9. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_async.o +0 -0
  10. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_async_dyn.o +0 -0
  11. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_bytes.o +0 -0
  12. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_bytes_io.o +0 -0
  13. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_crypto_async.o +0 -0
  14. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_dyn_invoke.o +0 -0
  15. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_events.o +0 -0
  16. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_exception.o +0 -0
  17. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_file_handle.o +0 -0
  18. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_json.o +0 -0
  19. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_lib.o +0 -0
  20. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_map.o +0 -0
  21. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_node_builtin.o +0 -0
  22. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_qs.o +0 -0
  23. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_regex.o +0 -0
  24. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_symbol.o +0 -0
  25. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_url.o +0 -0
  26. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_url_params.o +0 -0
  27. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_util_compare.o +0 -0
  28. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_util_style.o +0 -0
  29. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_array.o +0 -0
  30. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_assert.o +0 -0
  31. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_async.o +0 -0
  32. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_async_dyn.o +0 -0
  33. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_bytes.o +0 -0
  34. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_bytes_io.o +0 -0
  35. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_crypto_async.o +0 -0
  36. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_dyn_invoke.o +0 -0
  37. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_events.o +0 -0
  38. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_exception.o +0 -0
  39. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_file_handle.o +0 -0
  40. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_island.o +0 -0
  41. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_json.o +0 -0
  42. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_lib.o +0 -0
  43. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_map.o +0 -0
  44. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_node_builtin.o +0 -0
  45. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_qs.o +0 -0
  46. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_regex.o +0 -0
  47. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_symbol.o +0 -0
  48. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_url.o +0 -0
  49. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_url_params.o +0 -0
  50. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_util_compare.o +0 -0
  51. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_util_style.o +0 -0
  52. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_web.o +0 -0
  53. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
  54. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  55. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_array.o +0 -0
  56. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_assert.o +0 -0
  57. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_bytes.o +0 -0
  58. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_bytes_io.o +0 -0
  59. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_dyn_invoke.o +0 -0
  60. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_exception.o +0 -0
  61. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_json.o +0 -0
  62. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_lib.o +0 -0
  63. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_map.o +0 -0
  64. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_node_builtin.o +0 -0
  65. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_regex.o +0 -0
  66. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_symbol.o +0 -0
  67. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_url.o +0 -0
  68. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_url_params.o +0 -0
  69. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  70. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_array.o +0 -0
  71. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_assert.o +0 -0
  72. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_bytes.o +0 -0
  73. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_bytes_io.o +0 -0
  74. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_dyn_invoke.o +0 -0
  75. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_exception.o +0 -0
  76. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_json.o +0 -0
  77. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_lib.o +0 -0
  78. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_map.o +0 -0
  79. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_node_builtin.o +0 -0
  80. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_regex.o +0 -0
  81. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_symbol.o +0 -0
  82. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_url.o +0 -0
  83. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_url_params.o +0 -0
  84. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  85. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_array.o +0 -0
  86. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_assert.o +0 -0
  87. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_bytes.o +0 -0
  88. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_bytes_io.o +0 -0
  89. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_dyn_invoke.o +0 -0
  90. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_exception.o +0 -0
  91. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_json.o +0 -0
  92. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_lib.o +0 -0
  93. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_map.o +0 -0
  94. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_node_builtin.o +0 -0
  95. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_regex.o +0 -0
  96. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_symbol.o +0 -0
  97. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_url.o +0 -0
  98. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_url_params.o +0 -0
  99. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  100. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_array.o +0 -0
  101. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_assert.o +0 -0
  102. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_bytes.o +0 -0
  103. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_bytes_io.o +0 -0
  104. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_dyn_invoke.o +0 -0
  105. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_exception.o +0 -0
  106. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_json.o +0 -0
  107. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_lib.o +0 -0
  108. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_map.o +0 -0
  109. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_node_builtin.o +0 -0
  110. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_regex.o +0 -0
  111. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_symbol.o +0 -0
  112. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_url.o +0 -0
  113. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_url_params.o +0 -0
  114. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  115. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_array.o +0 -0
  116. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_assert.o +0 -0
  117. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_async.o +0 -0
  118. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_async_dyn.o +0 -0
  119. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_bytes.o +0 -0
  120. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_bytes_io.o +0 -0
  121. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_crypto_async.o +0 -0
  122. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_dyn_invoke.o +0 -0
  123. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_events.o +0 -0
  124. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_exception.o +0 -0
  125. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_file_handle.o +0 -0
  126. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_json.o +0 -0
  127. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_lib.o +0 -0
  128. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_map.o +0 -0
  129. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_node_builtin.o +0 -0
  130. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_qs.o +0 -0
  131. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_regex.o +0 -0
  132. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_symbol.o +0 -0
  133. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_url.o +0 -0
  134. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_url_params.o +0 -0
  135. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_util_compare.o +0 -0
  136. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_util_style.o +0 -0
  137. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_array.o +0 -0
  138. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_assert.o +0 -0
  139. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_async.o +0 -0
  140. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_async_dyn.o +0 -0
  141. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_bytes.o +0 -0
  142. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_bytes_io.o +0 -0
  143. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_crypto_async.o +0 -0
  144. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_dyn_invoke.o +0 -0
  145. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_events.o +0 -0
  146. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_exception.o +0 -0
  147. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_file_handle.o +0 -0
  148. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_island.o +0 -0
  149. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_json.o +0 -0
  150. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_lib.o +0 -0
  151. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_map.o +0 -0
  152. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_node_builtin.o +0 -0
  153. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_qs.o +0 -0
  154. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_regex.o +0 -0
  155. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_symbol.o +0 -0
  156. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_url.o +0 -0
  157. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_url_params.o +0 -0
  158. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_util_compare.o +0 -0
  159. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_util_style.o +0 -0
  160. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_web.o +0 -0
  161. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
  162. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  163. package/dist/lib/runtime-darwin-arm64/package.json +1 -1
  164. package/dist/lib/runtime-darwin-arm64/runtime-pack.json +423 -297
  165. package/dist/lib/runtime-sources/package.json +1 -1
  166. package/dist/lib/runtime-sources/src/scr_abort.c +5 -0
  167. package/dist/lib/runtime-sources/src/scr_array.c +5 -0
  168. package/dist/lib/runtime-sources/src/scr_assert.c +26 -0
  169. package/dist/lib/runtime-sources/src/scr_async.c +56 -4
  170. package/dist/lib/runtime-sources/src/scr_async_dyn.c +118 -24
  171. package/dist/lib/runtime-sources/src/scr_bytes.c +226 -0
  172. package/dist/lib/runtime-sources/src/scr_bytes_io.c +355 -51
  173. package/dist/lib/runtime-sources/src/scr_crypto_async.c +22 -2
  174. package/dist/lib/runtime-sources/src/scr_dyn_invoke.c +181 -43
  175. package/dist/lib/runtime-sources/src/scr_events.c +9 -0
  176. package/dist/lib/runtime-sources/src/scr_exception.c +1 -0
  177. package/dist/lib/runtime-sources/src/scr_fetch.c +45 -1
  178. package/dist/lib/runtime-sources/src/scr_file_handle.c +42 -0
  179. package/dist/lib/runtime-sources/src/scr_island.c +2166 -786
  180. package/dist/lib/runtime-sources/src/scr_island_manifest.h +19 -13
  181. package/dist/lib/runtime-sources/src/scr_json.c +584 -54
  182. package/dist/lib/runtime-sources/src/scr_json.test.ts +1 -0
  183. package/dist/lib/runtime-sources/src/scr_lib.c +1192 -43
  184. package/dist/lib/runtime-sources/src/scr_map.c +8 -0
  185. package/dist/lib/runtime-sources/src/scr_node_builtin.c +78 -0
  186. package/dist/lib/runtime-sources/src/scr_qs.c +10 -0
  187. package/dist/lib/runtime-sources/src/scr_regex.c +107 -5
  188. package/dist/lib/runtime-sources/src/scr_runtime.h +136 -9
  189. package/dist/lib/runtime-sources/src/scr_symbol.c +5 -0
  190. package/dist/lib/runtime-sources/src/scr_system_errors.h +573 -0
  191. package/dist/lib/runtime-sources/src/scr_text_decoder_labels.h +12 -12
  192. package/dist/lib/runtime-sources/src/scr_url.c +547 -64
  193. package/dist/lib/runtime-sources/src/scr_url_internal.h +6 -0
  194. package/dist/lib/runtime-sources/src/scr_url_params.c +10 -0
  195. package/dist/lib/runtime-sources/src/scr_util_compare.c +222 -0
  196. package/dist/lib/runtime-sources/src/scr_util_style.c +337 -0
  197. package/dist/lib/runtime-sources/src/scr_web.c +849 -264
  198. package/package.json +1 -1
@@ -135,6 +135,11 @@ static const ScrIslandModule *isl_mods = NULL;
135
135
  static size_t isl_nmods = 0;
136
136
  static const ScrIslandEdge *isl_edges = NULL;
137
137
  static size_t isl_nedges = 0;
138
+ static const char *isl_main_module = NULL;
139
+
140
+ void scr_island_entry_module(const char *filename) {
141
+ isl_main_module = filename;
142
+ }
138
143
 
139
144
  /* Compressed embedded module text (src_raw/esm_raw > 0: raw DEFLATE, the
140
145
  * emitter's size lever) inflates LAZILY at a module's first load and the
@@ -222,6 +227,7 @@ static const char *isl_edge_find(const char *from, const char *spec, int want) {
222
227
 
223
228
  /* Defined with the module system below; called from isl_init. */
224
229
  static void isl_install_module_loader(void);
230
+ static void isl_init_type_brands(void);
225
231
  /* Defined with the host-function machinery below; called from isl_init. */
226
232
  static void isl_register_hostfn_class(void);
227
233
  /* Defined with the island → static promise bridge below; called from the
@@ -536,6 +542,7 @@ static void isl_init(void) {
536
542
  fprintf(stderr, "scriptc: island engine context allocation failed\n");
537
543
  abort();
538
544
  }
545
+ isl_init_type_brands();
539
546
  JSValue arr = JS_Eval(isl_ctx, isl_prelude, sizeof isl_prelude - 1,
540
547
  "<scr-prelude>", JS_EVAL_TYPE_GLOBAL);
541
548
  if (JS_IsException(arr)) {
@@ -1154,6 +1161,103 @@ static bool isl_dynjs_strict_eq(ScrJsval *a, ScrJsval *b) {
1154
1161
  static bool isl_dynjs_is_array(ScrJsval *cell) { return JS_IsArray(cell->v); }
1155
1162
  static bool isl_dynjs_is_error(ScrJsval *cell) { return JS_IsError(cell->v); }
1156
1163
 
1164
+ /* Cache engine class IDs from pristine builtins before user code runs.
1165
+ * Class comparisons never inspect public properties or execute traps. */
1166
+ static SCR_TL JSClassID isl_module_namespace_class;
1167
+ static const char *const isl_brand_names[] = { "SharedArrayBuffer", "GeneratorFunction", "AsyncGeneratorFunction", "Generator", "AsyncGenerator",
1168
+ "Arguments", "Arguments", "Map Iterator", "Set Iterator", "Number", "String", "Boolean", "Symbol", "BigInt" };
1169
+ static SCR_TL JSClassID isl_brand_classes[sizeof isl_brand_names / sizeof isl_brand_names[0]];
1170
+ static void isl_init_type_brands(void) {
1171
+ static const char brand_source[] =
1172
+ "[new SharedArrayBuffer(0), function*(){}, async function*(){}, (function*(){})(), (async function*(){})(),"
1173
+ "(function(){'use strict';return arguments})(1), Function('a','return arguments')(1),"
1174
+ "new Map().entries(), new Set().values(), Object(0), Object(''), Object(false), Object(Symbol()), Object(0n)]";
1175
+ JSValue brands = JS_Eval(isl_ctx, brand_source, sizeof brand_source - 1, "<scr-type-brands>", JS_EVAL_TYPE_GLOBAL);
1176
+ if (JS_IsException(brands)) {
1177
+ fprintf(stderr, "scriptc: island type brands failed to initialize\n");
1178
+ abort();
1179
+ }
1180
+ for (size_t i = 0; i < sizeof isl_brand_classes / sizeof isl_brand_classes[0]; i++) {
1181
+ JSValue value = JS_GetPropertyUint32(isl_ctx, brands, (uint32_t)i);
1182
+ isl_brand_classes[i] = JS_GetClassID(value);
1183
+ JS_FreeValue(isl_ctx, value);
1184
+ }
1185
+ JS_FreeValue(isl_ctx, brands);
1186
+ static const char namespace_source[] = "export {};";
1187
+ JSValue module = JS_Eval(isl_ctx, namespace_source, sizeof namespace_source - 1,
1188
+ "<scr-type-brands>", JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
1189
+ JSValue evaluated = JS_IsException(module) ? JS_EXCEPTION : JS_EvalFunction(isl_ctx, JS_DupValue(isl_ctx, module));
1190
+ JSValue namespace = JS_IsException(evaluated) ? JS_EXCEPTION : JS_GetModuleNamespace(isl_ctx, JS_VALUE_GET_PTR(module));
1191
+ if (JS_IsException(namespace)) {
1192
+ fprintf(stderr, "scriptc: island type brands failed to initialize\n");
1193
+ abort();
1194
+ }
1195
+ isl_module_namespace_class = JS_GetClassID(namespace);
1196
+ JS_FreeValue(isl_ctx, namespace);
1197
+ JS_FreeValue(isl_ctx, evaluated);
1198
+ JS_FreeValue(isl_ctx, module);
1199
+ }
1200
+
1201
+ static bool isl_class_named(JSValueConst value, const char *name) {
1202
+ JSClassID id = JS_GetClassID(value);
1203
+ if (!id) return false;
1204
+ for (size_t i = 0; i < sizeof isl_brand_names / sizeof isl_brand_names[0]; i++)
1205
+ if (id == isl_brand_classes[i] && strcmp(isl_brand_names[i], name) == 0) return true;
1206
+ return false;
1207
+ }
1208
+
1209
+ static bool isl_type_probe(JSValueConst value, const char *probe, size_t len) {
1210
+ #define PROBE(name) (len == sizeof(name) - 1 && memcmp(probe, name, sizeof(name) - 1) == 0)
1211
+ int typed = JS_GetTypedArrayType(value);
1212
+ if (PROBE("isTypedArray")) return typed >= 0;
1213
+ if (PROBE("isArrayBufferView")) return typed >= 0 || JS_IsDataView(value);
1214
+ if (PROBE("isUint8Array")) return typed == JS_TYPED_ARRAY_UINT8;
1215
+ if (PROBE("isUint8ClampedArray")) return typed == JS_TYPED_ARRAY_UINT8C;
1216
+ if (PROBE("isUint16Array")) return typed == JS_TYPED_ARRAY_UINT16;
1217
+ if (PROBE("isUint32Array")) return typed == JS_TYPED_ARRAY_UINT32;
1218
+ if (PROBE("isInt8Array")) return typed == JS_TYPED_ARRAY_INT8;
1219
+ if (PROBE("isInt16Array")) return typed == JS_TYPED_ARRAY_INT16;
1220
+ if (PROBE("isInt32Array")) return typed == JS_TYPED_ARRAY_INT32;
1221
+ if (PROBE("isFloat16Array")) return typed == JS_TYPED_ARRAY_FLOAT16;
1222
+ if (PROBE("isFloat32Array")) return typed == JS_TYPED_ARRAY_FLOAT32;
1223
+ if (PROBE("isFloat64Array")) return typed == JS_TYPED_ARRAY_FLOAT64;
1224
+ if (PROBE("isBigInt64Array")) return typed == JS_TYPED_ARRAY_BIG_INT64;
1225
+ if (PROBE("isBigUint64Array")) return typed == JS_TYPED_ARRAY_BIG_UINT64;
1226
+ if (PROBE("isArrayBuffer")) return JS_IsArrayBuffer(value);
1227
+ if (PROBE("isDataView")) return JS_IsDataView(value);
1228
+ if (PROBE("isDate")) return JS_IsDate(value);
1229
+ if (PROBE("isMap")) return JS_IsMap(value);
1230
+ if (PROBE("isSet")) return JS_IsSet(value);
1231
+ if (PROBE("isWeakMap")) return JS_IsWeakMap(value);
1232
+ if (PROBE("isWeakSet")) return JS_IsWeakSet(value);
1233
+ if (PROBE("isRegExp")) return JS_IsRegExp(value);
1234
+ if (PROBE("isPromise")) return JS_IsPromise(value);
1235
+ if (PROBE("isProxy")) return JS_IsProxy(value);
1236
+ if (PROBE("isNativeError")) return JS_IsError(value);
1237
+ if (PROBE("isAnyArrayBuffer")) return JS_IsArrayBuffer(value) || isl_class_named(value, "SharedArrayBuffer");
1238
+ if (PROBE("isSharedArrayBuffer")) return isl_class_named(value, "SharedArrayBuffer");
1239
+ if (PROBE("isAsyncFunction")) return JS_IsAsyncFunction(value) || isl_class_named(value, "AsyncGeneratorFunction");
1240
+ if (PROBE("isGeneratorFunction")) return isl_class_named(value, "GeneratorFunction") || isl_class_named(value, "AsyncGeneratorFunction");
1241
+ if (PROBE("isGeneratorObject")) return isl_class_named(value, "Generator") || isl_class_named(value, "AsyncGenerator");
1242
+ if (PROBE("isArgumentsObject")) return isl_class_named(value, "Arguments");
1243
+ if (PROBE("isMapIterator")) return isl_class_named(value, "Map Iterator");
1244
+ if (PROBE("isSetIterator")) return isl_class_named(value, "Set Iterator");
1245
+ if (PROBE("isModuleNamespaceObject")) return isl_module_namespace_class && JS_GetClassID(value) == isl_module_namespace_class;
1246
+ if (PROBE("isNumberObject")) return isl_class_named(value, "Number");
1247
+ if (PROBE("isStringObject")) return isl_class_named(value, "String");
1248
+ if (PROBE("isBooleanObject")) return isl_class_named(value, "Boolean");
1249
+ if (PROBE("isSymbolObject")) return isl_class_named(value, "Symbol");
1250
+ if (PROBE("isBigIntObject")) return isl_class_named(value, "BigInt");
1251
+ if (PROBE("isBoxedPrimitive")) return isl_class_named(value, "Number") || isl_class_named(value, "String") ||
1252
+ isl_class_named(value, "Boolean") || isl_class_named(value, "Symbol") || isl_class_named(value, "BigInt");
1253
+ #undef PROBE
1254
+ return false;
1255
+ }
1256
+
1257
+ static bool isl_dynjs_type_probe(ScrJsval *cell, const ScrStr *probe) {
1258
+ return isl_type_probe(cell->v, probe->data, probe->len);
1259
+ }
1260
+
1157
1261
  static const ScrDynJsvalOps isl_dynjs_ops;
1158
1262
 
1159
1263
  /* The jsval→dyn wrap over a RAW engine value (BORROWED) — the scalar
@@ -1442,6 +1546,7 @@ static const ScrDynJsvalOps isl_dynjs_ops = {
1442
1546
  isl_dynjs_iter_drain,
1443
1547
  isl_dynjs_iterator,
1444
1548
  isl_dynjs_iter_n,
1549
+ isl_dynjs_type_probe,
1445
1550
  };
1446
1551
 
1447
1552
  ScrDyn *scr_dyn_from_jsval(ScrJsval *cell) {
@@ -2552,32 +2657,49 @@ static JSModuleDef *isl_module_load(JSContext *ctx, const char *name, void *opaq
2552
2657
  free(heap);
2553
2658
  if (JS_IsException(v)) return NULL;
2554
2659
  JSModuleDef *def = JS_VALUE_GET_PTR(v);
2555
- /* import.meta.url — Node sets the module's file:// URL; embedded keys
2556
- * are realpaths, builtins keep their node: name. Emscripten factory
2557
- * modules read it (_scriptName, createRequire(import.meta.url)). */
2660
+ /* File-backed metadata uses the same converters as node:url. Embedded
2661
+ * keys are resolved paths, including spaces, percent signs and Unicode;
2662
+ * concatenating file:// would reinterpret those as URL syntax. */
2558
2663
  JSValue meta = JS_GetImportMeta(ctx, def);
2559
2664
  if (!JS_IsException(meta)) {
2560
2665
  JSValue url;
2561
- if (name[0] == '/') {
2562
- size_t n = strlen(name) + 8;
2563
- char *buf2 = malloc(n);
2564
- if (buf2) {
2565
- snprintf(buf2, n, "file://%s", name);
2566
- url = JS_NewString(ctx, buf2);
2567
- free(buf2);
2568
- } else {
2569
- url = JS_NewString(ctx, name);
2666
+ bool file_backed = name[0] == '/' ||
2667
+ (name[0] && name[1] == ':' && (name[2] == '/' || name[2] == '\\')) ||
2668
+ (name[0] == '\\' && name[1] == '\\');
2669
+ if (file_backed) {
2670
+ ScrStr *path = scr_str_new(name, strlen(name));
2671
+ ScrUrl *parsed = scr_url_from_path(path);
2672
+ ScrStr *href = parsed ? scr_url_href(parsed) : NULL;
2673
+ ScrStr *dir = scr_path_dirname(path);
2674
+ if (!href || !dir) {
2675
+ if (href) scr_str_release(href);
2676
+ if (dir) scr_str_release(dir);
2677
+ if (parsed) scr_url_release(parsed);
2678
+ scr_str_release(path);
2679
+ isl_throw_pending(ctx);
2680
+ JS_FreeValue(ctx, meta);
2681
+ JS_FreeValue(ctx, v);
2682
+ return NULL;
2570
2683
  }
2684
+ JS_SetPropertyStr(ctx, meta, "dirname", JS_NewStringLen(ctx, dir->data, dir->len));
2685
+ JS_SetPropertyStr(ctx, meta, "filename", JS_NewStringLen(ctx, path->data, path->len));
2686
+ url = JS_NewStringLen(ctx, href->data, href->len);
2687
+ scr_str_release(href);
2688
+ scr_str_release(dir);
2689
+ scr_url_release(parsed);
2690
+ scr_str_release(path);
2571
2691
  } else {
2572
2692
  url = JS_NewString(ctx, name);
2573
2693
  }
2574
- JS_SetPropertyStr(ctx, meta, "url", url); /* consumed */
2694
+ JS_SetPropertyStr(ctx, meta, "main", JS_NewBool(ctx, isl_main_module && strcmp(isl_main_module, name) == 0));
2575
2695
  JSValue key = JS_NewString(ctx, name);
2576
2696
  JSValueConst data[1] = {key};
2577
2697
  JSValue resolve_fn = JS_NewCFunctionData(ctx, isl_import_meta_resolve, 1,
2578
2698
  0, 1, data);
2579
2699
  JS_FreeValue(ctx, key); /* resolve_fn's func_data retains it */
2700
+ JS_DefinePropertyValueStr(ctx, resolve_fn, "name", JS_NewString(ctx, "resolve"), JS_PROP_CONFIGURABLE);
2580
2701
  JS_SetPropertyStr(ctx, meta, "resolve", resolve_fn); /* consumed */
2702
+ JS_SetPropertyStr(ctx, meta, "url", url); /* consumed */
2581
2703
  JS_FreeValue(ctx, meta);
2582
2704
  }
2583
2705
  JS_FreeValue(ctx, v);
@@ -2663,7 +2785,7 @@ static JSValue isl_host_env(JSContext *ctx, JSValueConst this_val, int argc,
2663
2785
  for (size_t i = 0; i + 1 < n; i += 2) {
2664
2786
  ScrStr *k = scr_arr_get_ref(pairs, (double)i);
2665
2787
  ScrStr *v = scr_arr_get_ref(pairs, (double)(i + 1));
2666
- JS_SetPropertyStr(ctx, obj, k->data, JS_NewStringLen(ctx, v->data, v->len));
2788
+ JS_DefinePropertyValueStr(ctx, obj, k->data, JS_NewStringLen(ctx, v->data, v->len), JS_PROP_C_W_E);
2667
2789
  scr_str_release(k);
2668
2790
  scr_str_release(v);
2669
2791
  }
@@ -2856,6 +2978,143 @@ static ScrStr *isl_arg_str(JSContext *ctx, JSValueConst v) {
2856
2978
  return out;
2857
2979
  }
2858
2980
 
2981
+ /* Dotenv and environment mutations share the native process environment.
2982
+ * The JS layer validates types before these host calls. */
2983
+ static JSValue isl_host_env_get(JSContext *ctx, JSValueConst this_val, int argc,
2984
+ JSValueConst *argv) {
2985
+ (void)this_val; (void)argc;
2986
+ ScrStr *key = isl_arg_str(ctx, argv[0]);
2987
+ if (!key) return JS_EXCEPTION;
2988
+ ScrStr *value = scr_env_get(key);
2989
+ scr_str_release(key);
2990
+ JSValue result = value ? JS_NewStringLen(ctx, value->data, value->len) : JS_UNDEFINED;
2991
+ scr_str_release(value);
2992
+ return result;
2993
+ }
2994
+
2995
+ static JSValue isl_host_chdir(JSContext *ctx, JSValueConst this_val, int argc,
2996
+ JSValueConst *argv) {
2997
+ (void)this_val; (void)argc;
2998
+ ScrStr *directory = isl_arg_str(ctx, argv[0]);
2999
+ if (!directory) return JS_EXCEPTION;
3000
+ scr_process_chdir(directory);
3001
+ scr_str_release(directory);
3002
+ return scr_exc_pending() ? isl_throw_pending(ctx) : JS_UNDEFINED;
3003
+ }
3004
+
3005
+ static JSValue isl_host_env_set(JSContext *ctx, JSValueConst this_val, int argc,
3006
+ JSValueConst *argv) {
3007
+ (void)this_val; (void)argc;
3008
+ ScrStr *key = isl_arg_str(ctx, argv[0]);
3009
+ if (!key) return JS_EXCEPTION;
3010
+ ScrStr *value = isl_arg_str(ctx, argv[1]);
3011
+ if (!value) { scr_str_release(key); return JS_EXCEPTION; }
3012
+ scr_env_set(key, value);
3013
+ scr_str_release(key);
3014
+ scr_str_release(value);
3015
+ return JS_TRUE;
3016
+ }
3017
+
3018
+ static JSValue isl_host_env_delete(JSContext *ctx, JSValueConst this_val, int argc,
3019
+ JSValueConst *argv) {
3020
+ (void)this_val; (void)argc;
3021
+ ScrStr *key = isl_arg_str(ctx, argv[0]);
3022
+ if (!key) return JS_EXCEPTION;
3023
+ scr_env_unset(key);
3024
+ scr_str_release(key);
3025
+ return JS_TRUE;
3026
+ }
3027
+
3028
+ static JSValue isl_host_system_error_entries(JSContext *ctx, JSValueConst this_val, int argc,
3029
+ JSValueConst *argv) {
3030
+ (void)ctx; (void)this_val; (void)argc; (void)argv;
3031
+ ScrDyn *entries = scr_util_system_error_entries();
3032
+ JSValue result = isl_from_dyn(entries);
3033
+ scr_dyn_release(entries);
3034
+ return result;
3035
+ }
3036
+
3037
+ static JSValue isl_host_system_error_info(JSContext *ctx, JSValueConst this_val, int argc,
3038
+ JSValueConst *argv) {
3039
+ (void)this_val;
3040
+ if (argc != 2) return JS_ThrowTypeError(ctx, "invalid system error bridge arity");
3041
+ double number;
3042
+ if (JS_ToFloat64(ctx, &number, argv[0]) < 0) return JS_EXCEPTION;
3043
+ ScrDyn value = {0}; value.kind = SCR_DYN_NUM; value.v.num = number;
3044
+ ScrStr *text = JS_ToBool(ctx, argv[1]) ? scr_util_system_error_message(&value) : scr_util_system_error_name(&value);
3045
+ if (!text) return isl_throw_pending(ctx);
3046
+ JSValue result = JS_NewStringLen(ctx, text->data, text->len);
3047
+ scr_str_release(text);
3048
+ return result;
3049
+ }
3050
+
3051
+ static JSValue isl_host_parse_env(JSContext *ctx, JSValueConst this_val, int argc,
3052
+ JSValueConst *argv) {
3053
+ (void)this_val; (void)argc;
3054
+ ScrDyn *content = isl_dyn_from_value(argv[0]);
3055
+ ScrDyn *parsed = scr_util_parse_env(content);
3056
+ scr_dyn_release(content);
3057
+ if (!parsed) return isl_throw_pending(ctx);
3058
+ /* Preserve embedded NUL keys: JS_SetPropertyStr would truncate them. */
3059
+ JSValue result = JS_NewObject(ctx);
3060
+ for (size_t i = 0; i < parsed->v.obj.len; i++) {
3061
+ const ScrDynEntry *entry = &parsed->v.obj.entries[i];
3062
+ JSAtom key = JS_NewAtomLen(ctx, entry->key, entry->key_len);
3063
+ int status = JS_SetProperty(ctx, result, key, isl_from_dyn(entry->value));
3064
+ JS_FreeAtom(ctx, key);
3065
+ if (status < 0) { JS_FreeValue(ctx, result); result = JS_EXCEPTION; break; }
3066
+ }
3067
+ scr_dyn_release(parsed);
3068
+ return result;
3069
+ }
3070
+
3071
+ static JSValue isl_host_transcode(JSContext *ctx, JSValueConst this_val, int argc,
3072
+ JSValueConst *argv) {
3073
+ (void)this_val;
3074
+ if (argc != 3) return JS_ThrowTypeError(ctx, "invalid transcode bridge arity");
3075
+ size_t length = 0;
3076
+ uint8_t *data = JS_GetUint8Array(ctx, &length, argv[0]);
3077
+ if (!data && length) return JS_EXCEPTION;
3078
+ ScrBytes bytes = {0};
3079
+ bytes.elem = SCR_BYTES_U8; bytes.len = length; bytes.data = data;
3080
+ ScrDyn source = {0};
3081
+ source.kind = SCR_DYN_BYTES; source.v.bytes = &bytes;
3082
+ ScrDyn *from = isl_dyn_from_value(argv[1]), *to = isl_dyn_from_value(argv[2]);
3083
+ ScrBytes *result = scr_buffer_transcode(&source, from, to);
3084
+ scr_dyn_release(from); scr_dyn_release(to);
3085
+ if (!result) {
3086
+ JSValue error = isl_pending_to_value(ctx);
3087
+ JSValue code = JS_GetPropertyStr(ctx, error, "code");
3088
+ const char *name = JS_ToCString(ctx, code);
3089
+ if (name && strcmp(name, "U_INVALID_CHAR_FOUND") == 0) JS_SetPropertyStr(ctx, error, "errno", JS_NewInt32(ctx, 10));
3090
+ else if (name && strcmp(name, "U_ILLEGAL_ARGUMENT_ERROR") == 0) JS_SetPropertyStr(ctx, error, "errno", JS_NewInt32(ctx, 1));
3091
+ JS_FreeCString(ctx, name); JS_FreeValue(ctx, code);
3092
+ return JS_Throw(ctx, error);
3093
+ }
3094
+ JSValue value = JS_NewUint8ArrayCopy(ctx, result->data, result->len);
3095
+ scr_bytes_release(result);
3096
+ return value;
3097
+ }
3098
+
3099
+ static JSValue isl_host_load_env_file(JSContext *ctx, JSValueConst this_val, int argc,
3100
+ JSValueConst *argv) {
3101
+ (void)this_val;
3102
+ ScrDyn *path;
3103
+ if (argc > 1 && JS_ToBool(ctx, argv[1])) {
3104
+ size_t len;
3105
+ uint8_t *data = JS_GetUint8Array(ctx, &len, argv[0]);
3106
+ if (!data) return JS_EXCEPTION;
3107
+ ScrBytes *bytes = scr_bytes_new(SCR_BYTES_U8, (double)len);
3108
+ if (len) memcpy(bytes->data, data, len);
3109
+ path = scr_dyn_new_bytes(bytes);
3110
+ path->buffer = argc > 2 && JS_ToBool(ctx, argv[2]);
3111
+ scr_bytes_release(bytes);
3112
+ } else path = isl_dyn_from_value(argc ? argv[0] : JS_UNDEFINED);
3113
+ scr_process_load_env_file(path);
3114
+ scr_dyn_release(path);
3115
+ return scr_exc_pending() ? isl_throw_pending(ctx) : JS_UNDEFINED;
3116
+ }
3117
+
2859
3118
  static JSValue isl_host_fs(JSContext *ctx, JSValueConst this_val, int argc,
2860
3119
  JSValueConst *argv) {
2861
3120
  (void)this_val;
@@ -2871,8 +3130,47 @@ static JSValue isl_host_fs(JSContext *ctx, JSValueConst this_val, int argc,
2871
3130
  return JS_EXCEPTION;
2872
3131
  }
2873
3132
  }
2874
- if (strcmp(op, "readFile") == 0) {
2875
- ScrBytes *data = scr_fs_read_file_bytes(a);
3133
+ if (strcmp(op, "open") == 0) {
3134
+ double flags = 0, mode = 0666;
3135
+ JS_ToFloat64(ctx, &flags, argv[2]);
3136
+ JS_ToFloat64(ctx, &mode, argv[3]);
3137
+ ret = JS_NewFloat64(ctx, scr_fs_open_native(a, flags, mode));
3138
+ } else if (strcmp(op, "close") == 0 || strcmp(op, "fsync") == 0 ||
3139
+ strcmp(op, "fdatasync") == 0 || strcmp(op, "ftruncate") == 0 ||
3140
+ strcmp(op, "fchmod") == 0) {
3141
+ double fd = 0, value = 0;
3142
+ JS_ToFloat64(ctx, &fd, argv[1]);
3143
+ if (argc > 2) JS_ToFloat64(ctx, &value, argv[2]);
3144
+ if (strcmp(op, "close") == 0) scr_fs_close(fd);
3145
+ else if (strcmp(op, "fsync") == 0) scr_fs_fsync(fd);
3146
+ else if (strcmp(op, "fdatasync") == 0) scr_fs_fdatasync(fd);
3147
+ else if (strcmp(op, "ftruncate") == 0) scr_fs_ftruncate(fd, value);
3148
+ else scr_fs_fchmod(fd, value);
3149
+ } else if (strcmp(op, "read") == 0 || strcmp(op, "write") == 0 ||
3150
+ strcmp(op, "readv") == 0 || strcmp(op, "writev") == 0) {
3151
+ double fd = 0, offset = 0, length = 0, position = -1;
3152
+ JS_ToFloat64(ctx, &fd, argv[1]);
3153
+ JS_ToFloat64(ctx, &offset, argv[3]);
3154
+ JS_ToFloat64(ctx, &length, argv[4]);
3155
+ JS_ToFloat64(ctx, &position, argv[5]);
3156
+ size_t size = 0;
3157
+ uint8_t *data = JS_GetUint8Array(ctx, &size, argv[2]);
3158
+ if (data || size == 0) {
3159
+ ScrBytes buffer = {SIZE_MAX, size, SCR_BYTES_U8, data, NULL};
3160
+ if (strcmp(op, "readv") == 0 && argc > 6 && JS_ToBool(ctx, argv[6])) {
3161
+ scr_fs_throw(EINVAL, "read", NULL);
3162
+ } else {
3163
+ double n = op[0] == 'r'
3164
+ ? strcmp(op, "readv") == 0 && length == 0 ? scr_fs_read_zero(fd, position)
3165
+ : scr_fs_read_sync(fd, &buffer, offset, length, position)
3166
+ : scr_fs_write_sync(fd, &buffer, offset, length, position);
3167
+ ret = JS_NewFloat64(ctx, n);
3168
+ }
3169
+ } else ret = JS_EXCEPTION;
3170
+ } else if (strcmp(op, "readFile") == 0) {
3171
+ double fd = 0;
3172
+ if (!a) JS_ToFloat64(ctx, &fd, argv[1]);
3173
+ ScrBytes *data = a ? scr_fs_read_file_bytes(a) : scr_fs_read_fd_bytes(fd);
2876
3174
  if (data) {
2877
3175
  ret = JS_NewUint8ArrayCopy(ctx, data->data, (size_t)scr_bytes_len(data));
2878
3176
  scr_bytes_release(data);
@@ -2881,10 +3179,22 @@ static JSValue isl_host_fs(JSContext *ctx, JSValueConst this_val, int argc,
2881
3179
  size_t len = 0;
2882
3180
  uint8_t *buf = JS_GetUint8Array(ctx, &len, argv[2]);
2883
3181
  if (buf || len == 0) {
2884
- ScrStr *data = scr_str_new((const char *)buf, len);
2885
- if (strcmp(op, "writeFile") == 0) scr_fs_write_file(a, data);
2886
- else scr_fs_append_file(a, data);
2887
- scr_str_release(data);
3182
+ if (a) {
3183
+ ScrStr *data = scr_str_new((const char *)buf, len);
3184
+ if (strcmp(op, "writeFile") == 0) scr_fs_write_file(a, data);
3185
+ else scr_fs_append_file(a, data);
3186
+ scr_str_release(data);
3187
+ } else {
3188
+ double fd = 0;
3189
+ JS_ToFloat64(ctx, &fd, argv[1]);
3190
+ ScrBytes buffer = {SIZE_MAX, len, SCR_BYTES_U8, buf, NULL};
3191
+ size_t at = 0;
3192
+ while (at < len && !scr_exc_pending()) {
3193
+ double n = scr_fs_write_sync(fd, &buffer, (double)at, (double)(len - at), -1);
3194
+ if (n <= 0) { if (!scr_exc_pending()) scr_fs_throw(EIO, "write", NULL); break; }
3195
+ at += (size_t)n;
3196
+ }
3197
+ }
2888
3198
  } else {
2889
3199
  ret = JS_EXCEPTION;
2890
3200
  }
@@ -2945,8 +3255,11 @@ static JSValue isl_host_fs(JSContext *ctx, JSValueConst this_val, int argc,
2945
3255
  scr_fs_scandir_free(s);
2946
3256
  ret = arr;
2947
3257
  }
2948
- } else if (strcmp(op, "stat") == 0 || strcmp(op, "lstat") == 0) {
2949
- ScrStats *st = strcmp(op, "stat") == 0 ? scr_fs_stat(a) : scr_fs_lstat(a);
3258
+ } else if (strcmp(op, "stat") == 0 || strcmp(op, "lstat") == 0 || strcmp(op, "fstat") == 0) {
3259
+ double fd = 0;
3260
+ if (strcmp(op, "fstat") == 0) JS_ToFloat64(ctx, &fd, argv[1]);
3261
+ ScrStats *st = strcmp(op, "fstat") == 0 ? scr_fs_fstat(fd)
3262
+ : strcmp(op, "stat") == 0 ? scr_fs_stat(a) : scr_fs_lstat(a);
2950
3263
  if (st) {
2951
3264
  JSValue arr = JS_NewArray(ctx);
2952
3265
  JS_SetPropertyUint32(ctx, arr, 0, JS_NewBool(ctx, scr_stats_is_file(st)));
@@ -3143,41 +3456,44 @@ static JSValue isl_host_zlib(JSContext *ctx, JSValueConst this_val, int argc,
3143
3456
  static JSValue isl_host_url_to_path(JSContext *ctx, JSValueConst this_val, int argc,
3144
3457
  JSValueConst *argv) {
3145
3458
  (void)this_val;
3146
- (void)argc;
3147
- ScrStr *s = isl_arg_str(ctx, argv[0]);
3148
- if (!s) return JS_EXCEPTION;
3149
- #ifdef _WIN32
3150
- ScrUrl *u = scr_url_new(s);
3151
- ScrStr *r = u ? scr_url_to_path_w32(u) : NULL;
3152
- if (u) scr_url_release(u);
3153
- #else
3154
- ScrStr *r = scr_url_str_to_path(s);
3155
- #endif
3156
- scr_str_release(s);
3157
- if (!r) return isl_throw_pending(ctx);
3158
- JSValue out = JS_NewStringLen(ctx, r->data, r->len);
3159
- scr_str_release(r);
3160
- return out;
3459
+ ScrDyn *input = isl_dyn_from_value(argc ? argv[0] : JS_UNDEFINED);
3460
+ if (!input) return JS_EXCEPTION;
3461
+ ScrDyn *options = isl_dyn_from_value(argc > 1 ? argv[1] : JS_UNDEFINED);
3462
+ ScrStr *path = scr_url_checked_to_path_options(input, options);
3463
+ scr_dyn_release(input); scr_dyn_release(options);
3464
+ if (!path) return isl_throw_pending(ctx);
3465
+ JSValue result = JS_NewStringLen(ctx, path->data, path->len);
3466
+ scr_str_release(path);
3467
+ return result;
3468
+ }
3469
+
3470
+ static JSValue isl_host_url_to_path_buffer(JSContext *ctx, JSValueConst this_val, int argc,
3471
+ JSValueConst *argv) {
3472
+ (void)this_val;
3473
+ ScrDyn *input = isl_dyn_from_value(argc ? argv[0] : JS_UNDEFINED);
3474
+ if (!input) return JS_EXCEPTION;
3475
+ ScrDyn *options = isl_dyn_from_value(argc > 1 ? argv[1] : JS_UNDEFINED);
3476
+ ScrBytes *path = scr_url_checked_to_path_buffer(input, options);
3477
+ scr_dyn_release(input); scr_dyn_release(options);
3478
+ if (!path) return isl_throw_pending(ctx);
3479
+ JSValue result = JS_NewUint8ArrayCopy(ctx, path->data, path->len);
3480
+ scr_bytes_release(path);
3481
+ return result;
3161
3482
  }
3162
3483
 
3163
3484
  static JSValue isl_host_url_from_path(JSContext *ctx, JSValueConst this_val, int argc,
3164
3485
  JSValueConst *argv) {
3165
3486
  (void)this_val;
3166
- (void)argc;
3167
- ScrStr *s = isl_arg_str(ctx, argv[0]);
3168
- if (!s) return JS_EXCEPTION;
3169
- #ifdef _WIN32
3170
- ScrUrl *u = scr_url_from_path_w32(s);
3171
- #else
3172
- ScrUrl *u = scr_url_from_path(s);
3173
- #endif
3174
- scr_str_release(s);
3175
- if (!u) return isl_throw_pending(ctx);
3176
- ScrStr *href = scr_url_href(u);
3177
- scr_url_release(u);
3178
- JSValue out = JS_NewStringLen(ctx, href->data, href->len);
3487
+ ScrDyn *input = isl_dyn_from_value(argc ? argv[0] : JS_UNDEFINED);
3488
+ ScrDyn *options = isl_dyn_from_value(argc > 1 ? argv[1] : JS_UNDEFINED);
3489
+ ScrUrl *url = scr_url_checked_from_path(input, options);
3490
+ scr_dyn_release(input); scr_dyn_release(options);
3491
+ if (!url) return isl_throw_pending(ctx);
3492
+ ScrStr *href = scr_url_href(url);
3493
+ scr_url_release(url);
3494
+ JSValue result = JS_NewStringLen(ctx, href->data, href->len);
3179
3495
  scr_str_release(href);
3180
- return out;
3496
+ return result;
3181
3497
  }
3182
3498
 
3183
3499
  /* fs.constants (and the legacy `constants` module's fs half): the REAL
@@ -3205,6 +3521,14 @@ static JSValue isl_host_fs_constants(JSContext *ctx, JSValueConst this_val, int
3205
3521
  ISL_CONST(O_EXCL);
3206
3522
  ISL_CONST(O_TRUNC);
3207
3523
  ISL_CONST(O_APPEND);
3524
+ #ifdef O_SYNC
3525
+ ISL_CONST(O_SYNC);
3526
+ #else
3527
+ JS_SetPropertyStr(ctx, o, "O_SYNC", JS_NewInt32(ctx, 0));
3528
+ #endif
3529
+ #ifdef O_NOFOLLOW
3530
+ ISL_CONST(O_NOFOLLOW);
3531
+ #endif
3208
3532
  #ifdef O_NONBLOCK
3209
3533
  ISL_CONST(O_NONBLOCK);
3210
3534
  #endif
@@ -3253,7 +3577,7 @@ static JSValue isl_host_digest(JSContext *ctx, JSValueConst this_val, int argc,
3253
3577
  JS_FreeCString(ctx, alg);
3254
3578
  return JS_EXCEPTION;
3255
3579
  }
3256
- unsigned char out[32];
3580
+ unsigned char out[64];
3257
3581
  size_t n = scr_crypto_digest_raw(alg, data, len, out);
3258
3582
  JS_FreeCString(ctx, alg);
3259
3583
  return n == 0 ? JS_UNDEFINED : JS_NewUint8ArrayCopy(ctx, out, n);
@@ -3273,12 +3597,38 @@ static JSValue isl_host_hmac(JSContext *ctx, JSValueConst this_val, int argc,
3273
3597
  JS_FreeCString(ctx, alg);
3274
3598
  return JS_EXCEPTION;
3275
3599
  }
3276
- unsigned char out[32];
3600
+ unsigned char out[64];
3277
3601
  size_t n = scr_crypto_hmac_raw(alg, key, keylen, data, len, out);
3278
3602
  JS_FreeCString(ctx, alg);
3279
3603
  return n == 0 ? JS_UNDEFINED : JS_NewUint8ArrayCopy(ctx, out, n);
3280
3604
  }
3281
3605
 
3606
+ /* The island validates JavaScript overloads; the native RFC 7914 core
3607
+ * owns memory accounting, ROMix, and sensitive scratch cleanup. */
3608
+ static JSValue isl_host_scrypt(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
3609
+ (void)this_val;
3610
+ if (argc != 7) return JS_ThrowTypeError(ctx, "invalid scrypt bridge arity");
3611
+ size_t password_len = 0, salt_len = 0;
3612
+ uint8_t *password_data = JS_GetUint8Array(ctx, &password_len, argv[0]);
3613
+ uint8_t *salt_data = JS_GetUint8Array(ctx, &salt_len, argv[1]);
3614
+ if ((!password_data && password_len) || (!salt_data && salt_len)) return JS_EXCEPTION;
3615
+ double values[5];
3616
+ for (int i = 0; i < 5; i++) if (JS_ToFloat64(ctx, &values[i], argv[i + 2]) < 0) return JS_EXCEPTION;
3617
+ /* These wrappers borrow engine storage for the synchronous core. No
3618
+ * extra heap copies of the password or salt outlive the bridge call. */
3619
+ ScrBytes password = {0}, salt = {0};
3620
+ password.elem = salt.elem = SCR_BYTES_U8;
3621
+ password.len = password_len;
3622
+ password.data = password_data;
3623
+ salt.len = salt_len;
3624
+ salt.data = salt_data;
3625
+ ScrBytes *result = scr_crypto_scrypt_derive(&password, &salt, values[0], values[1], values[2], values[3], values[4]);
3626
+ if (scr_exc_pending()) return isl_throw_pending(ctx);
3627
+ JSValue value = JS_NewUint8ArrayCopy(ctx, result->data, result->len);
3628
+ scr_bytes_release(result);
3629
+ return value;
3630
+ }
3631
+
3282
3632
  static JSValue isl_host_pid(JSContext *ctx, JSValueConst this_val, int argc,
3283
3633
  JSValueConst *argv) {
3284
3634
  (void)this_val;
@@ -3484,6 +3834,18 @@ static JSValue isl_host_hostname(JSContext *ctx, JSValueConst this_val, int argc
3484
3834
  return JS_NewString(ctx, buf);
3485
3835
  }
3486
3836
 
3837
+ static JSValue isl_host_type_probe(JSContext *ctx, JSValueConst this_val,
3838
+ int argc, JSValueConst *argv) {
3839
+ (void)this_val;
3840
+ if (argc < 2) return JS_FALSE;
3841
+ size_t len;
3842
+ const char *probe = JS_ToCStringLen(ctx, &len, argv[0]);
3843
+ if (!probe) return JS_EXCEPTION;
3844
+ bool result = isl_type_probe(argv[1], probe, len);
3845
+ JS_FreeCString(ctx, probe);
3846
+ return JS_NewBool(ctx, result);
3847
+ }
3848
+
3487
3849
  /* The bootstrap: the CommonJS require shim over the embedded map, the
3488
3850
  * builtin shims, and the real process bridge. Evaluated once (module boot);
3489
3851
  * returns the CJS import helper the boundary below pins. Everything JS
@@ -3554,16 +3916,15 @@ static const char isl_modules_bootstrap[] =
3554
3916
  " const cache = Object.create(null);\n"
3555
3917
  " const builtins = Object.create(null);\n"
3556
3918
  " const builtinModules = ['assert','assert/strict','async_hooks','buffer','child_process','cluster','console','constants','crypto','dgram','diagnostics_channel','dns','dns/promises','domain','events','fs','fs/promises','http','http2','https','inspector','inspector/promises','module','net','os','path','path/posix','path/win32','perf_hooks','process','punycode','querystring','readline','readline/promises','repl','stream','stream/consumers','stream/promises','stream/web','string_decoder','sys','timers','timers/promises','tls','trace_events','tty','url','util','util/types','v8','vm','wasi','worker_threads','zlib'];\n"
3557
- /* Node's require stack: each CJS module remembers its FIRST requirer
3558
- * (Node's module.parent / moduleParentCache — the chain is static,
3559
- * captured at first load, not the dynamic call stack), and a failing
3560
- * resolution reports the requiring module plus its parent chain.
3919
+ /* Node's require stack follows module records, including parents
3920
+ * whose evaluation failed or whose cache entry was deleted. A failing
3921
+ * resolution reports the requiring module plus its first-parent chain.
3561
3922
  * Entry modules loaded from the compiled (ESM-like) world have no
3562
3923
  * parent, exactly like Node's ESM→CJS boundary. */
3563
- " const parents = Object.create(null);\n"
3564
- " const requireStackOf = (from) => {\n"
3924
+ " const moduleParents = new WeakMap();\n"
3925
+ " const requireStackOf = (parent) => {\n"
3565
3926
  " const stack = [];\n"
3566
- " for (let m = from; m !== undefined; m = parents[m]) stack.push(m);\n"
3927
+ " for (let m = parent; m; m = moduleParents.get(m)) stack.push(m.filename || m.id);\n"
3567
3928
  " return stack;\n"
3568
3929
  " };\n"
3569
3930
  /* Node resolves core modules unconditionally, before node_modules
@@ -3576,12 +3937,13 @@ static const char isl_modules_bootstrap[] =
3576
3937
  * properties. (Unshimmed BUILTINS reached by build-time-visible lazy
3577
3938
  * edges resolve through the edge table to their node: keys and take
3578
3939
  * requireKey's does-not-provide throw below instead.) */
3579
- " const resolveFrom = (from, spec) => {\n"
3940
+ " const resolveFrom = (parent, spec) => {\n"
3941
+ " const from = parent.filename;\n"
3580
3942
  " const to = host.resolve(from, spec);\n"
3581
3943
  " if (to === undefined) {\n"
3582
3944
  " const name = spec.startsWith('node:') ? spec.slice(5) : spec;\n"
3583
3945
  " if (builtins[name]) return 'node:' + name;\n"
3584
- " const stack = requireStackOf(from);\n"
3946
+ " const stack = requireStackOf(parent);\n"
3585
3947
  " const err = new Error(\"Cannot find module '\" + spec + \"'\" +\n"
3586
3948
  " (stack.length ? '\\nRequire stack:\\n- ' + stack.join('\\n- ') : ''));\n"
3587
3949
  " err.code = 'MODULE_NOT_FOUND';\n"
@@ -3611,12 +3973,52 @@ static const char isl_modules_bootstrap[] =
3611
3973
  " }\n"
3612
3974
  " return out;\n"
3613
3975
  " };\n"
3614
- " const decorateRequire = (req, from) => {\n"
3976
+ " // CommonJS module records retain identity across cache hits and circular loads.\n"
3977
+ " const modulePathsFrom = (directory) => {\n"
3978
+ " const paths = [];\n"
3979
+ " const path = builtins.path();\n"
3980
+ " for (let dir = directory;;) {\n"
3981
+ " if (path.basename(dir) !== 'node_modules') paths.push(path.join(dir, 'node_modules'));\n"
3982
+ " const parent = path.dirname(dir);\n"
3983
+ " if (parent === dir) break;\n"
3984
+ " dir = parent;\n"
3985
+ " }\n"
3986
+ " return paths;\n"
3987
+ " };\n"
3988
+ " const updateChildren = (parent, child) => {\n"
3989
+ " if (parent && parent.children && !parent.children.includes(child)) parent.children.push(child);\n"
3990
+ " };\n"
3991
+ " function Module(id = '', parent) {\n"
3992
+ " this.id = id;\n"
3993
+ " this.path = builtins.path().dirname(id);\n"
3994
+ " this.exports = {};\n"
3995
+ " moduleParents.set(this, parent);\n"
3996
+ " updateChildren(parent, this);\n"
3997
+ " this.filename = null;\n"
3998
+ " this.loaded = false;\n"
3999
+ " this.children = [];\n"
4000
+ " }\n"
4001
+ " Object.defineProperty(Module.prototype, 'parent', {\n"
4002
+ " get() { return moduleParents.get(this); },\n"
4003
+ " set(parent) { moduleParents.set(this, parent); },\n"
4004
+ " });\n"
4005
+ " Object.defineProperty(Module.prototype, 'isPreloading', { get() { return false; } });\n"
4006
+ " Module.prototype.require = function(id) {\n"
4007
+ " if (typeof id !== 'string') envArgumentError('id', 'of type string', id);\n"
4008
+ " if (id.length === 0) {\n"
4009
+ " const error = new TypeError(\"The argument 'id' must be a non-empty string. Received ''\");\n"
4010
+ " error.code = 'ERR_INVALID_ARG_VALUE';\n"
4011
+ " throw error;\n"
4012
+ " }\n"
4013
+ " return requireKey(resolveFrom(this, id), this);\n"
4014
+ " };\n"
4015
+ " const decorateRequire = (req, parent) => {\n"
4016
+ " const from = parent.filename;\n"
3615
4017
  " const resolve = (spec) => {\n"
3616
4018
  " if (typeof spec !== 'string') return requirePathsFrom(from, spec);\n"
3617
4019
  " const bare = spec.startsWith('node:') ? spec.slice(5) : spec;\n"
3618
4020
  " if (builtinModules.includes(bare) && (spec.startsWith('node:') || bare !== 'test')) return spec;\n"
3619
- " return resolveFrom(from, spec);\n"
4021
+ " return resolveFrom(parent, spec);\n"
3620
4022
  " };\n"
3621
4023
  " resolve.paths = (spec) => requirePathsFrom(from, spec);\n"
3622
4024
  " req.resolve = resolve;\n"
@@ -3630,26 +4032,32 @@ static const char isl_modules_bootstrap[] =
3630
4032
  " return b();\n"
3631
4033
  " }\n"
3632
4034
  " const hit = cache[key];\n"
3633
- " if (hit) return hit.exports;\n"
4035
+ " if (hit) { updateChildren(parent, hit); return hit.exports; }\n"
3634
4036
  " const info = host.source(key);\n"
3635
4037
  " if (info === undefined) throw new Error(\"module '\" + key + \"' is not embedded\");\n"
3636
4038
  " const src = info[0], format = info[1];\n"
3637
- " const mod = { exports: {} };\n"
4039
+ " const mod = new Module(key, parent);\n"
4040
+ " mod.filename = key;\n"
4041
+ " mod.paths = modulePathsFrom(mod.path);\n"
3638
4042
  " cache[key] = mod;\n"
3639
- " if (parent !== undefined && !(key in parents)) parents[key] = parent;\n"
3640
- " if (format === 2) { mod.exports = JSON.parse(src); return mod.exports; }\n"
3641
- " if (format === 0) { delete cache[key]; throw new Error('require() of ES module ' + key); }\n"
3642
- " const fn = new Function('exports', 'require', 'module', '__filename', '__dirname', src);\n"
3643
- " const req = decorateRequire((spec) => requireKey(resolveFrom(key, spec), key), key);\n"
3644
- " const dir = key.slice(0, key.lastIndexOf('/')) || '/';\n"
4043
+ " const req = decorateRequire((spec) => mod.require(spec), mod);\n"
3645
4044
  /* A module whose evaluation THROWS leaves no cache entry — Node
3646
4045
  * deletes it so a later require re-evaluates (and a lazy require
3647
4046
  * trap throws EVERY time instead of answering {} on the retry). */
3648
4047
  " try {\n"
3649
- " fn.call(mod.exports, mod.exports, req, mod, key, dir);\n"
4048
+ " if (format === 2) mod.exports = JSON.parse(src);\n"
4049
+ " else {\n"
4050
+ " if (format === 0) throw new Error('require() of ES module ' + key);\n"
4051
+ " const fn = new Function('exports', 'require', 'module', '__filename', '__dirname', src);\n"
4052
+ " fn.call(mod.exports, mod.exports, req, mod, key, mod.path);\n"
4053
+ " }\n"
4054
+ " mod.loaded = true;\n"
3650
4055
  " } catch (e) {\n"
3651
4056
  " delete cache[key];\n"
3652
- " delete parents[key];\n"
4057
+ " if (parent && Array.isArray(parent.children)) {\n"
4058
+ " const index = parent.children.indexOf(mod);\n"
4059
+ " if (index !== -1) parent.children.splice(index, 1);\n"
4060
+ " }\n"
3653
4061
  " throw e;\n"
3654
4062
  " }\n"
3655
4063
  " return mod.exports;\n"
@@ -3658,20 +4066,19 @@ static const char isl_modules_bootstrap[] =
3658
4066
  /* Node's events module: the emitter surface streams and CLIs drive —
3659
4067
  * prepend/once/remove with listener-unwrap, maxListeners bookkeeping
3660
4068
  * (warnings are not emitted), eventNames/rawListeners, Node's
3661
- * unhandled-'error' throw, and the once/getEventListeners statics.
4069
+ * unhandled-'error' throw, cancellable once, and async event iteration.
3662
4070
  * EventEmitter is callable so legacy constructors can use .call(this). */
3663
4071
  " builtins.events = memo(() => {\n"
3664
4072
  " function EventEmitter() {\n"
3665
4073
  " if (this._events === undefined || !Object.prototype.hasOwnProperty.call(this, '_events')) this._events = Object.create(null);\n"
3666
4074
  " if (!Object.prototype.hasOwnProperty.call(this, '_maxListeners')) this._maxListeners = undefined;\n"
3667
4075
  " }\n"
4076
+ " const checkListener = (listener) => {\n"
4077
+ " if (typeof listener !== 'function') envArgumentError('listener', 'of type function', listener);\n"
4078
+ " };\n"
3668
4079
  " class EventEmitterMethods {\n"
3669
4080
  " _add(n, f, prepend) {\n"
3670
- " if (typeof f !== 'function') {\n"
3671
- " const e = new TypeError('The \"listener\" argument must be of type function. Received ' + (f === null ? 'null' : typeof f));\n"
3672
- " e.code = 'ERR_INVALID_ARG_TYPE';\n"
3673
- " throw e;\n"
3674
- " }\n"
4081
+ " checkListener(f);\n"
3675
4082
  " this.emit('newListener', n, f.listener !== undefined ? f.listener : f);\n"
3676
4083
  " const a = this._events[n] = this._events[n] || [];\n"
3677
4084
  " if (prepend) a.unshift(f); else a.push(f);\n"
@@ -3681,42 +4088,64 @@ static const char isl_modules_bootstrap[] =
3681
4088
  " addListener(n, f) { return this.on(n, f); }\n"
3682
4089
  " prependListener(n, f) { return this._add(n, f, true); }\n"
3683
4090
  " _wrapOnce(n, f) {\n"
3684
- " const g = (...a) => { this.removeListener(n, g); f.apply(this, a); };\n"
4091
+ " let fired = false;\n"
4092
+ " const g = (...a) => {\n"
4093
+ " if (fired) return;\n"
4094
+ " this.removeListener(n, g);\n"
4095
+ " fired = true;\n"
4096
+ " return f.apply(this, a);\n"
4097
+ " };\n"
4098
+ " Object.defineProperty(g, \"name\", { value: \"bound onceWrapper\", configurable: true });\n"
3685
4099
  " g.listener = f;\n"
3686
4100
  " return g;\n"
3687
4101
  " }\n"
3688
- " once(n, f) { return this._add(n, this._wrapOnce(n, f), false); }\n"
3689
- " prependOnceListener(n, f) { return this._add(n, this._wrapOnce(n, f), true); }\n"
4102
+ " once(n, f) { checkListener(f); return this._add(n, this._wrapOnce(n, f), false); }\n"
4103
+ " prependOnceListener(n, f) { checkListener(f); return this._add(n, this._wrapOnce(n, f), true); }\n"
3690
4104
  " removeListener(n, f) {\n"
4105
+ " checkListener(f);\n"
3691
4106
  " const a = this._events[n];\n"
3692
4107
  " if (a) {\n"
3693
- " const i = a.findIndex((x) => x === f || x.listener === f);\n"
4108
+ " let i = a.length - 1;\n"
4109
+ " while (i >= 0 && a[i] !== f && a[i].listener !== f) i--;\n"
3694
4110
  " if (i >= 0) {\n"
3695
- " const x = a[i];\n"
4111
+ " const x = a.length === 1 ? (a[i].listener !== undefined ? a[i].listener : a[i]) : f;\n"
3696
4112
  " a.splice(i, 1);\n"
3697
4113
  " if (a.length === 0) delete this._events[n];\n"
3698
- " this.emit('removeListener', n, x.listener !== undefined ? x.listener : x);\n"
4114
+ " this.emit('removeListener', n, x);\n"
3699
4115
  " }\n"
3700
4116
  " }\n"
3701
4117
  " return this;\n"
3702
4118
  " }\n"
3703
4119
  " off(n, f) { return this.removeListener(n, f); }\n"
3704
4120
  " removeAllListeners(n) {\n"
3705
- " if (n === undefined) this._events = Object.create(null);\n"
3706
- " else delete this._events[n];\n"
4121
+ " if (!this._events.removeListener) {\n"
4122
+ " if (arguments.length === 0) this._events = Object.create(null);\n"
4123
+ " else delete this._events[n];\n"
4124
+ " return this;\n"
4125
+ " }\n"
4126
+ " if (arguments.length === 0) {\n"
4127
+ " for (const key of Reflect.ownKeys(this._events)) {\n"
4128
+ " if (key !== 'removeListener') this.removeAllListeners(key);\n"
4129
+ " }\n"
4130
+ " this.removeAllListeners('removeListener');\n"
4131
+ " this._events = Object.create(null);\n"
4132
+ " } else {\n"
4133
+ " const listeners = this._events[n];\n"
4134
+ " if (listeners) for (let i = listeners.length - 1; i >= 0; i--) this.removeListener(n, listeners[i]);\n"
4135
+ " }\n"
3707
4136
  " return this;\n"
3708
4137
  " }\n"
3709
4138
  " setMaxListeners(m) { this._maxListeners = m; return this; }\n"
3710
4139
  " getMaxListeners() { return this._maxListeners === undefined ? EventEmitter.defaultMaxListeners : this._maxListeners; }\n"
3711
4140
  " emit(n, ...args) {\n"
4141
+ " if (n === 'error' && this._events[EventEmitter.errorMonitor]) this.emit(EventEmitter.errorMonitor, ...args);\n"
3712
4142
  " const a = this._events[n];\n"
3713
4143
  " if (!a || a.length === 0) {\n"
3714
4144
  " if (n === 'error') {\n"
3715
- /* Node throws the unhandled error payload (or a synthetic one) —
3716
- * inside the island this crosses the bridge like any engine throw. */
4145
+ /* Unhandled error payloads cross the bridge as engine exceptions. */
3717
4146
  " const err = args[0];\n"
3718
4147
  " if (err instanceof Error) throw err;\n"
3719
- " const e = new Error(\"Unhandled error.\" + (err === undefined ? '' : ' (' + String(err) + ')'));\n"
4148
+ " const e = new Error(\"Unhandled error.\" + ' (' + builtins.util().inspect(err) + ')');\n"
3720
4149
  " e.code = 'ERR_UNHANDLED_ERROR';\n"
3721
4150
  " e.context = err;\n"
3722
4151
  " throw e;\n"
@@ -3726,13 +4155,16 @@ static const char isl_modules_bootstrap[] =
3726
4155
  " for (const f of a.slice()) f.apply(this, args);\n"
3727
4156
  " return true;\n"
3728
4157
  " }\n"
3729
- " listenerCount(n) { const a = this._events[n]; return a ? a.length : 0; }\n"
4158
+ " listenerCount(n, listener) {\n"
4159
+ " const a = this._events[n];\n"
4160
+ " return a ? listener == null ? a.length : a.filter(f => f === listener || f.listener === listener).length : 0;\n"
4161
+ " }\n"
3730
4162
  " listeners(n) {\n"
3731
4163
  " const a = this._events[n];\n"
3732
4164
  " return a ? a.map((x) => (x.listener !== undefined ? x.listener : x)) : [];\n"
3733
4165
  " }\n"
3734
4166
  " rawListeners(n) { const a = this._events[n]; return a ? a.slice() : []; }\n"
3735
- " eventNames() { return Object.keys(this._events); }\n"
4167
+ " eventNames() { return Reflect.ownKeys(this._events); }\n"
3736
4168
  " }\n"
3737
4169
  " EventEmitter.prototype = EventEmitterMethods.prototype;\n"
3738
4170
  " EventEmitter.prototype.constructor = EventEmitter;\n"
@@ -3742,18 +4174,155 @@ static const char isl_modules_bootstrap[] =
3742
4174
  " EventEmitter.listenerCount = (emitter, n) => emitter.listenerCount(n);\n"
3743
4175
  " EventEmitter.getEventListeners = (emitter, n) => emitter.listeners(n);\n"
3744
4176
  " EventEmitter.setMaxListeners = (m, ...emitters) => { for (const e of emitters) e.setMaxListeners(m); };\n"
3745
- " EventEmitter.once = (emitter, name) => new Promise((resolve, reject) => {\n"
3746
- " const onEvent = (...args) => {\n"
3747
- " emitter.removeListener('error', onError);\n"
3748
- " resolve(args);\n"
4177
+ " const resistStopPropagation = Symbol.for('scriptc.events.resistStopPropagation');\n"
4178
+ " const checkSignal = (signal, name) => {\n"
4179
+ " if (signal !== undefined && (signal === null || typeof signal !== 'object' || !('aborted' in signal)))\n"
4180
+ " envArgumentError(name, 'an instance of AbortSignal', signal);\n"
4181
+ " };\n"
4182
+ " const checkOptions = (options) => {\n"
4183
+ " if (options === null || typeof options !== 'object' || Array.isArray(options))\n"
4184
+ " envArgumentError('options', 'of type object', options);\n"
4185
+ " };\n"
4186
+ " const abortError = (signal) => {\n"
4187
+ " const error = new Error('The operation was aborted', { cause: signal.reason });\n"
4188
+ " error.name = 'AbortError';\n"
4189
+ " error.code = 'ABORT_ERR';\n"
4190
+ " return error;\n"
4191
+ " };\n"
4192
+ " const add = (emitter, name, listener, flags) => {\n"
4193
+ " if (typeof emitter.on === 'function') {\n"
4194
+ " if (flags && flags.once) emitter.once(name, listener);\n"
4195
+ " else emitter.on(name, listener);\n"
4196
+ " } else if (typeof emitter.addEventListener === 'function') emitter.addEventListener(name, listener, flags);\n"
4197
+ " else envArgumentError('emitter', 'an instance of EventEmitter', emitter);\n"
4198
+ " };\n"
4199
+ " const remove = (emitter, name, listener) => {\n"
4200
+ " if (typeof emitter.removeListener === 'function') emitter.removeListener(name, listener);\n"
4201
+ " else if (typeof emitter.removeEventListener === 'function') emitter.removeEventListener(name, listener);\n"
4202
+ " else envArgumentError('emitter', 'an instance of EventEmitter', emitter);\n"
4203
+ " };\n"
4204
+ " EventEmitter.addAbortListener = (signal, listener) => {\n"
4205
+ " if (signal === undefined) envArgumentError('signal', 'an instance of AbortSignal', signal);\n"
4206
+ " checkSignal(signal, 'signal');\n"
4207
+ " checkListener(listener);\n"
4208
+ " let dispose;\n"
4209
+ " if (signal.aborted) queueMicrotask(() => listener());\n"
4210
+ " else {\n"
4211
+ " signal.addEventListener('abort', listener, { once: true, [resistStopPropagation]: true });\n"
4212
+ " dispose = () => signal.removeEventListener('abort', listener);\n"
4213
+ " }\n"
4214
+ " return { __proto__: null, [Symbol.dispose]() { if (dispose) dispose(); } };\n"
4215
+ " };\n"
4216
+ " EventEmitter.once = async (emitter, name, options = {}) => {\n"
4217
+ " checkOptions(options);\n"
4218
+ " const signal = options.signal;\n"
4219
+ " checkSignal(signal, 'options.signal');\n"
4220
+ " if (signal && signal.aborted) throw abortError(signal);\n"
4221
+ " return new Promise((resolve, reject) => {\n"
4222
+ " const onError = (err) => {\n"
4223
+ " remove(emitter, name, onEvent);\n"
4224
+ " if (signal) remove(signal, 'abort', onAbort);\n"
4225
+ " reject(err);\n"
4226
+ " };\n"
4227
+ " const onEvent = (...args) => {\n"
4228
+ " if (typeof emitter.removeListener === 'function') emitter.removeListener('error', onError);\n"
4229
+ " if (signal) remove(signal, 'abort', onAbort);\n"
4230
+ " resolve(args);\n"
4231
+ " };\n"
4232
+ " const onAbort = () => {\n"
4233
+ " remove(emitter, name, onEvent);\n"
4234
+ " remove(emitter, 'error', onError);\n"
4235
+ " reject(abortError(signal));\n"
4236
+ " };\n"
4237
+ " const flags = { __proto__: null, once: true, [resistStopPropagation]: true };\n"
4238
+ " add(emitter, name, onEvent, flags);\n"
4239
+ " if (name !== 'error' && typeof emitter.once === 'function') emitter.once('error', onError);\n"
4240
+ " if (signal) add(signal, 'abort', onAbort, flags);\n"
4241
+ " });\n"
4242
+ " };\n"
4243
+ " const queue = () => {\n"
4244
+ " let values = [], head = 0;\n"
4245
+ " return {\n"
4246
+ " get size() { return values.length - head; },\n"
4247
+ " push(value) { values.push(value); },\n"
4248
+ " shift() {\n"
4249
+ " const value = values[head];\n"
4250
+ " values[head++] = undefined;\n"
4251
+ " if (head === values.length) { values = []; head = 0; }\n"
4252
+ " else if (head >= 1024 && head * 2 > values.length) { values = values.slice(head); head = 0; }\n"
4253
+ " return value;\n"
4254
+ " },\n"
4255
+ " };\n"
4256
+ " };\n"
4257
+ " const checkWatermark = (value, name) => {\n"
4258
+ " if (typeof value !== 'number') envArgumentError(name, 'of type number', value);\n"
4259
+ " if (!Number.isInteger(value) || value < 1 || value > Number.MAX_SAFE_INTEGER) {\n"
4260
+ " const range = Number.isInteger(value) ? '>= 1 && <= 9007199254740991' : 'an integer';\n"
4261
+ " const received = Number.isInteger(value) && Math.abs(value) > 2 ** 32 ? String(value).replace(/\\B(?=(\\d{3})+(?!\\d))/g, '_') : String(value);\n"
4262
+ " const error = new RangeError('The value of \"' + name + '\" is out of range. It must be ' + range + '. Received ' + received);\n"
4263
+ " error.code = 'ERR_OUT_OF_RANGE';\n"
4264
+ " throw error;\n"
4265
+ " }\n"
4266
+ " };\n"
4267
+ " const iteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf((async function* () {})())));\n"
4268
+ " EventEmitter.on = (emitter, name, options = {}) => {\n"
4269
+ " checkOptions(options);\n"
4270
+ " const signal = options.signal;\n"
4271
+ " checkSignal(signal, 'options.signal');\n"
4272
+ " if (signal && signal.aborted) throw abortError(signal);\n"
4273
+ " const high = options.highWaterMark ?? options.highWatermark ?? Number.MAX_SAFE_INTEGER;\n"
4274
+ " checkWatermark(high, 'options.highWaterMark');\n"
4275
+ " const low = options.lowWaterMark ?? options.lowWatermark ?? 1;\n"
4276
+ " checkWatermark(low, 'options.lowWaterMark');\n"
4277
+ " const events = queue(), pending = queue(), listeners = [];\n"
4278
+ " let paused = false, error = null, finished = false, abortListener;\n"
4279
+ " const close = () => {\n"
4280
+ " if (abortListener) abortListener[Symbol.dispose]();\n"
4281
+ " while (listeners.length) { const [event, handler] = listeners.pop(); remove(emitter, event, handler); }\n"
4282
+ " finished = true;\n"
4283
+ " paused = false;\n"
4284
+ " const result = { value: undefined, done: true };\n"
4285
+ " while (pending.size) pending.shift().resolve(result);\n"
4286
+ " return Promise.resolve(result);\n"
3749
4287
  " };\n"
3750
4288
  " const onError = (err) => {\n"
3751
- " emitter.removeListener(name, onEvent);\n"
3752
- " reject(err);\n"
4289
+ " if (pending.size) pending.shift().reject(err);\n"
4290
+ " else error = err;\n"
4291
+ " close();\n"
3753
4292
  " };\n"
3754
- " emitter.once(name, onEvent);\n"
3755
- " if (name !== 'error') emitter.once('error', onError);\n"
3756
- " });\n"
4293
+ " const onEvent = (...args) => {\n"
4294
+ " if (pending.size) pending.shift().resolve({ value: args, done: false });\n"
4295
+ " else {\n"
4296
+ " if (!paused && events.size + 1 > high) { paused = true; emitter.pause(); }\n"
4297
+ " events.push(args);\n"
4298
+ " }\n"
4299
+ " };\n"
4300
+ " const iterator = Object.setPrototypeOf({\n"
4301
+ " next() {\n"
4302
+ " if (events.size) {\n"
4303
+ " const value = events.shift();\n"
4304
+ " if (paused && events.size < low) { emitter.resume(); paused = false; }\n"
4305
+ " return Promise.resolve({ value, done: false });\n"
4306
+ " }\n"
4307
+ " if (error) { const err = error; error = null; return Promise.reject(err); }\n"
4308
+ " if (finished) return close();\n"
4309
+ " return new Promise((resolve, reject) => pending.push({ resolve, reject }));\n"
4310
+ " },\n"
4311
+ " return() { return close(); },\n"
4312
+ " throw(err) {\n"
4313
+ " if (!(err instanceof Error)) envArgumentError('EventEmitter.AsyncIterator', 'an instance of Error', err);\n"
4314
+ " onError(err);\n"
4315
+ " },\n"
4316
+ " [Symbol.asyncIterator]() { return this; },\n"
4317
+ " }, iteratorPrototype);\n"
4318
+ " const listen = (event, handler) => { add(emitter, event, handler); listeners.push([event, handler]); };\n"
4319
+ " listen(name, onEvent);\n"
4320
+ " if (name !== 'error' && typeof emitter.on === 'function') listen('error', onError);\n"
4321
+ " const closeEvents = options.close;\n"
4322
+ " if (closeEvents && closeEvents.length) { for (let i = 0; i < closeEvents.length; i++) listen(closeEvents[i], close); }\n"
4323
+ " if (signal) abortListener = EventEmitter.addAbortListener(signal, () => onError(abortError(signal)));\n"
4324
+ " return iterator;\n"
4325
+ " };\n"
3757
4326
  " EventEmitter.EventEmitter = EventEmitter;\n"
3758
4327
  " EventEmitter.default = EventEmitter;\n"
3759
4328
  " return EventEmitter;\n"
@@ -3987,13 +4556,19 @@ static const char isl_modules_bootstrap[] =
3987
4556
  "function makeFs(env) {\n"
3988
4557
  " const Buffer = env.Buffer;\n"
3989
4558
  " const constants = env.fsConstants();\n"
3990
- " const call = env.fs;\n"
4559
+ " const call = (op, ...args) => {\n"
4560
+ " try { return env.fs(op, ...args); } catch (e) {\n"
4561
+ " if (e.code && !e.code.startsWith('ERR_') && e.code !== 'SC2020') {\n"
4562
+ " e.syscall = op === 'readv' ? 'read' : op === 'writev' ? 'write' : op;\n"
4563
+ " if (typeof args[0] === 'string') e.path = args[0];\n"
4564
+ " }\n"
4565
+ " throw e;\n"
4566
+ " }\n"
4567
+ " };\n"
3991
4568
  " const pathOf = (p) => {\n"
3992
4569
  " if (typeof p === \"string\") return p;\n"
3993
4570
  " if (p instanceof Uint8Array) return Buffer.from(p).toString(\"utf8\");\n"
3994
- " if (p !== null && typeof p === \"object\" && typeof p.href === \"string\" && p.href.startsWith(\"file://\")) {\n"
3995
- " return decodeURIComponent(p.href.slice(7));\n"
3996
- " }\n"
4571
+ " if (p instanceof env.URL) return env.fileURLToPath(p);\n"
3997
4572
  " const e = new TypeError('The \"path\" argument must be of type string or an instance of Buffer or URL. Received ' + (p === null ? \"null\" : typeof p === \"object\" ? \"an instance of \" + ((p.constructor && p.constructor.name) || \"Object\") : \"type \" + typeof p + \" (\" + JSON.stringify(p) + \")\"));\n"
3998
4573
  " e.code = \"ERR_INVALID_ARG_TYPE\";\n"
3999
4574
  " throw e;\n"
@@ -4049,16 +4624,16 @@ static const char isl_modules_bootstrap[] =
4049
4624
  " isBlockDevice() { return this._kind === 7; }\n"
4050
4625
  " }\n"
4051
4626
  " const readFileSync = (p, options) => {\n"
4052
- " const u8 = call(\"readFile\", pathOf(p));\n"
4627
+ " const u8 = call(\"readFile\", typeof p === \"number\" ? fdOf(p) : pathOf(p));\n"
4053
4628
  " const enc = encodingOf(options, null);\n"
4054
4629
  " const buf = Buffer.from(u8.buffer, u8.byteOffset, u8.length);\n"
4055
4630
  " return enc === null ? buf : buf.toString(enc);\n"
4056
4631
  " };\n"
4057
4632
  " const writeFileSync = (p, data, options) => {\n"
4058
- " call(\"writeFile\", pathOf(p), dataToU8(data, options));\n"
4633
+ " call(\"writeFile\", typeof p === \"number\" ? fdOf(p) : pathOf(p), dataToU8(data, options));\n"
4059
4634
  " };\n"
4060
4635
  " const appendFileSync = (p, data, options) => {\n"
4061
- " call(\"appendFile\", pathOf(p), dataToU8(data, options));\n"
4636
+ " call(\"appendFile\", typeof p === \"number\" ? fdOf(p) : pathOf(p), dataToU8(data, options));\n"
4062
4637
  " };\n"
4063
4638
  " const existsSync = (p) => {\n"
4064
4639
  " try {\n"
@@ -4112,11 +4687,209 @@ static const char isl_modules_bootstrap[] =
4112
4687
  " const readlinkSync = (p) => call(\"readlink\", pathOf(p));\n"
4113
4688
  " const copyFileSync = (src, dest) => call(\"copyFile\", pathOf(src), pathOf(dest));\n"
4114
4689
  " const renameSync = (src, dest) => call(\"rename\", pathOf(src), pathOf(dest));\n"
4690
+ " // Descriptor callbacks validate before scheduling; only system I/O failures\n"
4691
+ " // travel through the callback. Payloads always retain the caller's identity.\n"
4692
+ " const received = (v) => v === undefined ? 'undefined' : v === null ? 'null' : typeof v === 'string' ? 'type string (' + JSON.stringify(v) + ')' : typeof v === 'object' ? 'an instance of ' + ((v.constructor && v.constructor.name) || 'Object') : 'type ' + typeof v + ' (' + String(v) + ')';\n"
4693
+ " const failType = (name, expected, v) => { const e = new TypeError('The \"' + name + '\" argument must be ' + expected + '. Received ' + received(v)); e.code = 'ERR_INVALID_ARG_TYPE'; throw e; };\n"
4694
+ " const failRange = (name, range, v) => { const e = new RangeError('The value of \"' + name + '\" is out of range. It must be ' + range + '. Received ' + String(v)); e.code = 'ERR_OUT_OF_RANGE'; throw e; };\n"
4695
+ " const integer = (v, name, min = -9007199254740991, max = 9007199254740991) => {\n"
4696
+ " if (typeof v !== 'number') failType(name, 'of type number', v);\n"
4697
+ " if (!Number.isInteger(v)) failRange(name, 'an integer', v);\n"
4698
+ " if (v < min || v > max) failRange(name, '>= ' + min + ' && <= ' + max, v);\n"
4699
+ " return v;\n"
4700
+ " };\n"
4701
+ " const fdOf = (fd) => integer(fd, 'fd', 0, 2147483647);\n"
4702
+ " const cbOf = (cb) => { if (typeof cb !== 'function') failType('cb', 'of type function', cb); return cb; };\n"
4703
+ " const optionsOf = (o) => { if (o != null && (typeof o !== 'object' || Array.isArray(o))) failType('options', 'of type object', o); return o || {}; };\n"
4704
+ " const viewOf = (v) => { if (!ArrayBuffer.isView(v)) failType('buffer', 'an instance of Buffer, TypedArray, or DataView', v); return new Uint8Array(v.buffer, v.byteOffset, v.byteLength); };\n"
4705
+ " const modeOf = (m, dflt = 0o666) => { if (m === undefined) return dflt; if (typeof m === 'string') { if (!/^[0-7]+$/.test(m)) { const e = new TypeError(\"The argument 'mode' must be a 32-bit unsigned integer or an octal string. Received '\" + m + \"'\"); e.code = 'ERR_INVALID_ARG_VALUE'; throw e; } m = parseInt(m, 8); } return integer(m, 'mode', 0, 4294967295); };\n"
4706
+ " const flagsOf = (f) => {\n"
4707
+ " if (f === undefined) f = 'r';\n"
4708
+ " if (typeof f === 'number') return integer(f, 'flags', -2147483648, 2147483647);\n"
4709
+ " if (typeof f !== 'string') failType('flags', 'of type string or number', f);\n"
4710
+ " const c = constants, sync = c.O_SYNC || 0;\n"
4711
+ " const flags = { r: c.O_RDONLY, rs: c.O_RDONLY | sync, sr: c.O_RDONLY | sync, 'r+': c.O_RDWR, 'rs+': c.O_RDWR | sync, 'sr+': c.O_RDWR | sync,\n"
4712
+ " w: c.O_WRONLY | c.O_CREAT | c.O_TRUNC, wx: c.O_WRONLY | c.O_CREAT | c.O_TRUNC | c.O_EXCL, xw: c.O_WRONLY | c.O_CREAT | c.O_TRUNC | c.O_EXCL,\n"
4713
+ " 'w+': c.O_RDWR | c.O_CREAT | c.O_TRUNC, 'wx+': c.O_RDWR | c.O_CREAT | c.O_TRUNC | c.O_EXCL, 'xw+': c.O_RDWR | c.O_CREAT | c.O_TRUNC | c.O_EXCL,\n"
4714
+ " a: c.O_WRONLY | c.O_CREAT | c.O_APPEND, ax: c.O_WRONLY | c.O_CREAT | c.O_APPEND | c.O_EXCL, xa: c.O_WRONLY | c.O_CREAT | c.O_APPEND | c.O_EXCL,\n"
4715
+ " as: c.O_WRONLY | c.O_CREAT | c.O_APPEND | sync, sa: c.O_WRONLY | c.O_CREAT | c.O_APPEND | sync,\n"
4716
+ " 'a+': c.O_RDWR | c.O_CREAT | c.O_APPEND, 'ax+': c.O_RDWR | c.O_CREAT | c.O_APPEND | c.O_EXCL, 'xa+': c.O_RDWR | c.O_CREAT | c.O_APPEND | c.O_EXCL,\n"
4717
+ " 'as+': c.O_RDWR | c.O_CREAT | c.O_APPEND | sync, 'sa+': c.O_RDWR | c.O_CREAT | c.O_APPEND | sync };\n"
4718
+ " if (Object.prototype.hasOwnProperty.call(flags, f)) return flags[f];\n"
4719
+ " const e = new TypeError(\"The argument 'flags' is invalid. Received '\" + f + \"'\"); e.code = 'ERR_INVALID_ARG_VALUE'; throw e;\n"
4720
+ " };\n"
4721
+ " const openArgs = (p, flags, mode) => {\n"
4722
+ " const path = pathOf(p);\n"
4723
+ " if (path.includes('\\0')) { const e = new TypeError(\"The argument 'path' must be a string, Uint8Array, or URL without null bytes. Received \" + JSON.stringify(path)); e.code = 'ERR_INVALID_ARG_VALUE'; throw e; }\n"
4724
+ " return [path, flagsOf(flags), modeOf(mode)];\n"
4725
+ " };\n"
4726
+ " const openSync = (p, flags, mode) => call('open', ...openArgs(p, flags, mode));\n"
4727
+ " const closeSync = (fd) => call('close', fdOf(fd));\n"
4728
+ " const fsyncSync = (fd) => call('fsync', fdOf(fd));\n"
4729
+ " const fdatasyncSync = (fd) => call('fdatasync', fdOf(fd));\n"
4730
+ " const ftruncateSync = (fd, len = 0) => { fdOf(fd); integer(len, 'len'); return call('ftruncate', fd, Math.max(0, len)); };\n"
4731
+ " const fchmodSync = (fd, mode) => { fdOf(fd); if (mode === undefined) failType('mode', 'of type number', mode); return call('fchmod', fd, modeOf(mode)); };\n"
4732
+ " const fstatSync = (fd, options) => {\n"
4733
+ " fdOf(fd);\n"
4734
+ " if (options && options.bigint) { const e = new Error('fs.fstat with bigint Stats is not supported in the scriptc island'); e.code = 'SC2020'; throw e; }\n"
4735
+ " return new Stats(call('fstat', fd));\n"
4736
+ " };\n"
4737
+ " const readWindow = (buffer, offset, length, position, nullOffset, coerceLength = true) => {\n"
4738
+ " const bytes = viewOf(buffer);\n"
4739
+ " offset = offset === undefined || (nullOffset && offset === null) ? 0 : integer(offset, 'offset', 0);\n"
4740
+ " if (coerceLength) length |= 0;\n"
4741
+ " if (length === 0) return [bytes, offset, 0, -1];\n"
4742
+ " if (bytes.length === 0) { const e = new TypeError(\"The argument 'buffer' is empty and cannot be written. Received \" + (Buffer.isBuffer(buffer) ? '<Buffer >' : String(buffer))); e.code = 'ERR_INVALID_ARG_VALUE'; throw e; }\n"
4743
+ " if (offset > bytes.length) failRange('offset', '>= 0 && <= 9007199254740991', offset);\n"
4744
+ " if (length < 0 || offset + length > bytes.length) failRange('length', '<= ' + (bytes.length - offset), length);\n"
4745
+ " if (position == null) position = -1;\n"
4746
+ " else if (typeof position === 'bigint') {\n"
4747
+ " if (position < -1n || position > 9007199254740991n) { const e = new Error('fs.read positions outside the safe integer range are not supported in the scriptc island'); e.code = 'SC2020'; throw e; }\n"
4748
+ " position = Number(position);\n"
4749
+ " } else integer(position, 'position', -1);\n"
4750
+ " return [bytes, offset, length, position];\n"
4751
+ " };\n"
4752
+ " const readSync = function(fd, buffer, offset, length, position) {\n"
4753
+ " viewOf(buffer);\n"
4754
+ " if (arguments.length <= 3 || typeof offset === 'object') {\n"
4755
+ " ({ offset = 0, length = buffer.byteLength - offset, position = null } = optionsOf(offset));\n"
4756
+ " }\n"
4757
+ " const a = readWindow(buffer, offset, length, position, false);\n"
4758
+ " if (a[2] === 0) return 0;\n"
4759
+ " return call('read', fdOf(fd), ...a);\n"
4760
+ " };\n"
4761
+ " const writeWindow = (buffer, offset, length, position) => {\n"
4762
+ " const bytes = viewOf(buffer);\n"
4763
+ " offset = offset == null || typeof offset === 'function' ? 0 : integer(offset, 'offset', 0);\n"
4764
+ " if (typeof length !== 'number') length = bytes.length - offset;\n"
4765
+ " if (offset > bytes.length) failRange('offset', '<= ' + bytes.length, offset);\n"
4766
+ " if (length < 0) failRange('length', '>= 0', length);\n"
4767
+ " if (length > bytes.length - offset) failRange('length', '<= ' + (bytes.length - offset), length);\n"
4768
+ " integer(length, 'length', 0);\n"
4769
+ " position = typeof position === 'number' ? position : -1;\n"
4770
+ " return [bytes, offset, length, position];\n"
4771
+ " };\n"
4772
+ " const stringBytes = (buffer, encoding) => {\n"
4773
+ " if (typeof buffer !== 'string') failType('buffer', 'of type string or an instance of Buffer, TypedArray, or DataView', buffer);\n"
4774
+ " if (encoding && !Buffer.isEncoding(encoding)) { const e = new TypeError('Unknown encoding: ' + encoding); e.code = 'ERR_UNKNOWN_ENCODING'; throw e; }\n"
4775
+ " return Buffer.from(buffer, encoding || 'utf8');\n"
4776
+ " };\n"
4777
+ " const writeSync = (fd, buffer, offset, length, position) => {\n"
4778
+ " let a;\n"
4779
+ " if (ArrayBuffer.isView(buffer)) {\n"
4780
+ " if (typeof offset === 'object') { const o = optionsOf(offset); offset = o.offset; length = o.length; position = o.position; }\n"
4781
+ " a = writeWindow(buffer, offset, length, position);\n"
4782
+ " } else { const bytes = stringBytes(buffer, length); a = [bytes, 0, bytes.length, typeof offset === 'number' ? offset : -1]; }\n"
4783
+ " return call('write', fdOf(fd), ...a);\n"
4784
+ " };\n"
4785
+ " const vectorArgs = (buffers, position) => {\n"
4786
+ " if (!Array.isArray(buffers)) failType('buffers', 'an instance of Array', buffers);\n"
4787
+ " const views = buffers.map((b) => viewOf(b));\n"
4788
+ " position = typeof position === 'number' && Number.isFinite(position) && position >= 0 ? Math.trunc(position) : -1;\n"
4789
+ " return [views, position];\n"
4790
+ " };\n"
4791
+ " const vectorIO = (writing, fd, buffers, views, position) => {\n"
4792
+ " if (writing && buffers.length === 0) return 0;\n"
4793
+ " fdOf(fd);\n"
4794
+ " const length = views.reduce((n, b) => n + b.length, 0);\n"
4795
+ " const bytes = writing ? Buffer.concat(views) : Buffer.alloc(length);\n"
4796
+ " const n = call(writing ? 'writev' : 'readv', fd, bytes, 0, length, position, buffers.length === 0);\n"
4797
+ " if (!writing) { let at = 0; for (const b of views) { const size = Math.min(b.length, n - at); if (size > 0) b.set(bytes.subarray(at, at + size)); at += b.length; } }\n"
4798
+ " return n;\n"
4799
+ " };\n"
4800
+ " const readvSync = (fd, buffers, position) => { const [views, pos] = vectorArgs(buffers, position); return vectorIO(false, fd, buffers, views, pos); };\n"
4801
+ " const writevSync = (fd, buffers, position) => { const [views, pos] = vectorArgs(buffers, position); return vectorIO(true, fd, buffers, views, pos); };\n"
4802
+ " const callbackIO = (cb, action, payload) => {\n"
4803
+ " let result, error = null;\n"
4804
+ " try { result = action(); } catch (e) { error = e; }\n"
4805
+ " env.nextTick(() => payload === undefined ? cb(error, result) : cb(error, result || 0, payload));\n"
4806
+ " };\n"
4807
+ " const open = function(p, flags, mode, cb) {\n"
4808
+ " if (arguments.length < 3) { cb = flags; flags = 'r'; mode = 0o666; }\n"
4809
+ " else if (typeof mode === 'function') { cb = mode; mode = 0o666; }\n"
4810
+ " const a = openArgs(p, flags, mode); cbOf(cb); callbackIO(cb, () => call('open', ...a));\n"
4811
+ " };\n"
4812
+ " const read = function(fd, buffer, offset, length, position, cb) {\n"
4813
+ " fdOf(fd);\n"
4814
+ " if (arguments.length <= 4) {\n"
4815
+ " let o;\n"
4816
+ " if (arguments.length === 4) { o = optionsOf(offset); cb = length; }\n"
4817
+ " else if (arguments.length === 3) { cb = offset; if (!ArrayBuffer.isView(buffer)) { o = optionsOf(buffer); ({ buffer = Buffer.alloc(16384) } = o); } }\n"
4818
+ " else { cb = buffer; buffer = Buffer.alloc(16384); }\n"
4819
+ " ({ offset = 0, length = buffer.byteLength - offset, position = null } = o || {});\n"
4820
+ " }\n"
4821
+ " viewOf(buffer); cbOf(cb);\n"
4822
+ " const a = readWindow(buffer, offset, length, position, true);\n"
4823
+ " callbackIO(cb, () => a[2] === 0 ? 0 : call('read', fd, ...a), buffer);\n"
4824
+ " };\n"
4825
+ " const write = function(fd, buffer, offset, length, position, cb) {\n"
4826
+ " fdOf(fd); let a;\n"
4827
+ " if (ArrayBuffer.isView(buffer)) {\n"
4828
+ " cb = cb || position || length || offset; cbOf(cb);\n"
4829
+ " if (typeof offset === 'object') { const o = optionsOf(offset); offset = o.offset; length = o.length; position = o.position; }\n"
4830
+ " a = writeWindow(buffer, offset, length, position);\n"
4831
+ " } else {\n"
4832
+ " if (typeof position !== 'function') { if (typeof offset === 'function') { position = offset; offset = null; } else position = length; length = 'utf8'; }\n"
4833
+ " const bytes = stringBytes(buffer, length); cb = position; cbOf(cb); a = [bytes, 0, bytes.length, typeof offset === 'number' ? offset : -1];\n"
4834
+ " }\n"
4835
+ " callbackIO(cb, () => call('write', fd, ...a), buffer);\n"
4836
+ " };\n"
4837
+ " const vectorCallback = (writing) => (fd, buffers, position, cb) => {\n"
4838
+ " fdOf(fd); const [views, pos] = vectorArgs(buffers, position); cb = cb || position; cbOf(cb);\n"
4839
+ " callbackIO(cb, () => vectorIO(writing, fd, buffers, views, pos), buffers);\n"
4840
+ " };\n"
4841
+ " const controlCallback = (op, normalize) => (...args) => {\n"
4842
+ " const cb = args.pop(); fdOf(args[0]); normalize(args); cbOf(cb);\n"
4843
+ " callbackIO(cb, () => call(op, ...args));\n"
4844
+ " };\n"
4845
+ " const handleState = new WeakMap();\n"
4846
+ " class FileHandle extends env.EventEmitter {\n"
4847
+ " constructor(fd) { super(); handleState.set(this, { fd }); }\n"
4848
+ " get fd() { return handleState.get(this).fd; }\n"
4849
+ " close = () => {\n"
4850
+ " const state = handleState.get(this);\n"
4851
+ " if (state.fd === -1) return Promise.resolve();\n"
4852
+ " const fd = state.fd; state.fd = -1;\n"
4853
+ " const result = Promise.resolve().then(() => closeSync(fd));\n"
4854
+ " this.emit('close'); return result;\n"
4855
+ " };\n"
4856
+ " async [Symbol.asyncDispose || Symbol.for('nodejs.asyncDispose')]() { await this.close(); }\n"
4857
+ " async _call(op, action) {\n"
4858
+ " if (this.fd === -1) { const e = new Error('file closed'); e.code = 'EBADF'; e.syscall = op; throw e; }\n"
4859
+ " return action(this.fd);\n"
4860
+ " }\n"
4861
+ " read(buffer, offset, length, position) {\n"
4862
+ " return this._call('read', (fd) => {\n"
4863
+ " if (!ArrayBuffer.isView(buffer)) { ({ buffer = Buffer.alloc(16384), offset = 0, length = buffer.byteLength - offset, position = null } = optionsOf(buffer)); }\n"
4864
+ " if (offset !== null && typeof offset === 'object') { ({ offset = 0, length = buffer.byteLength - offset, position = null } = optionsOf(offset)); }\n"
4865
+ " if (offset == null) offset = 0;\n"
4866
+ " if (length == null) length = buffer.byteLength - offset;\n"
4867
+ " const a = readWindow(buffer, offset, length, position, true, false);\n"
4868
+ " return { __proto__: null, bytesRead: a[2] === 0 ? 0 : call('read', fd, ...a), buffer };\n"
4869
+ " });\n"
4870
+ " }\n"
4871
+ " write(buffer, offset, length, position) {\n"
4872
+ " return this._call('write', (fd) => {\n"
4873
+ " const bytesWritten = buffer && buffer.byteLength === 0 ? 0 : writeSync(fd, buffer, offset, length, position);\n"
4874
+ " return { __proto__: null, bytesWritten, buffer };\n"
4875
+ " });\n"
4876
+ " }\n"
4877
+ " readv(buffers, position) { return this._call('readv', (fd) => ({ __proto__: null, bytesRead: readvSync(fd, buffers, position), buffers })); }\n"
4878
+ " writev(buffers, position) { return this._call('writev', (fd) => ({ __proto__: null, bytesWritten: writevSync(fd, buffers, position), buffers })); }\n"
4879
+ " readFile(options) { return this._call('readFile', (fd) => readFileSync(fd, options)); }\n"
4880
+ " writeFile(data, options) { return this._call('writeFile', (fd) => writeFileSync(fd, data, options)); }\n"
4881
+ " appendFile(data, options) { return this._call('writeFile', (fd) => writeFileSync(fd, data, options)); }\n"
4882
+ " stat(options) { return this._call('fstat', (fd) => fstatSync(fd, options)); }\n"
4883
+ " sync() { return this._call('fsync', fsyncSync); }\n"
4884
+ " datasync() { return this._call('fdatasync', fdatasyncSync); }\n"
4885
+ " truncate(len = 0) { return this._call('ftruncate', (fd) => ftruncateSync(fd, len)); }\n"
4886
+ " chmod(mode) { return this._call('fchmod', (fd) => fchmodSync(fd, mode)); }\n"
4887
+ " }\n"
4115
4888
  " const sync = {\n"
4116
4889
  " readFileSync, writeFileSync, appendFileSync, existsSync, realpathSync,\n"
4117
4890
  " mkdirSync, rmSync, rmdirSync, unlinkSync, readdirSync, statSync,\n"
4118
4891
  " lstatSync, accessSync, mkdtempSync, chmodSync, copyFileSync, renameSync,\n"
4119
- " readlinkSync,\n"
4892
+ " readlinkSync, openSync, closeSync, readSync, writeSync, readvSync, writevSync, fstatSync, fchmodSync, ftruncateSync, fsyncSync, fdatasyncSync,\n"
4120
4893
  " };\n"
4121
4894
  " const callbackify = (syncFn) => (...args) => {\n"
4122
4895
  " const cb = args.pop();\n"
@@ -4213,22 +4986,13 @@ static const char isl_modules_bootstrap[] =
4213
4986
  " watchFile: () => {\n"
4214
4987
  " throw new Error(\"fs.watchFile is not available in the scriptc island\");\n"
4215
4988
  " },\n"
4216
- " openSync: () => {\n"
4217
- " throw new Error(\"fs.openSync is not available in the scriptc island (whole-file reads/writes only)\");\n"
4218
- " },\n"
4219
- " closeSync: () => undefined,\n"
4220
- " readSync: () => {\n"
4221
- " throw new Error(\"fs.readSync is not available in the scriptc island (whole-file reads/writes only)\");\n"
4222
- " },\n"
4223
- " writeSync: () => {\n"
4224
- " throw new Error(\"fs.writeSync is not available in the scriptc island (whole-file reads/writes only)\");\n"
4225
- " },\n"
4226
- " read: () => {\n"
4227
- " throw new Error(\"fs.read is not available in the scriptc island (whole-file reads/writes only)\");\n"
4228
- " },\n"
4229
- " open: () => {\n"
4230
- " throw new Error(\"fs.open is not available in the scriptc island (whole-file reads/writes only)\");\n"
4231
- " },\n"
4989
+ " open, read, write, readv: vectorCallback(false), writev: vectorCallback(true),\n"
4990
+ " close: controlCallback('close', () => {}),\n"
4991
+ " fsync: controlCallback('fsync', () => {}),\n"
4992
+ " fdatasync: controlCallback('fdatasync', () => {}),\n"
4993
+ " ftruncate: controlCallback('ftruncate', (a) => { a[1] = a[1] === undefined ? 0 : integer(a[1], 'len'); }),\n"
4994
+ " fchmod: controlCallback('fchmod', (a) => { if (a[1] === undefined) failType('mode', 'of type number', a[1]); a[1] = modeOf(a[1]); }),\n"
4995
+ " fstat: (fd, options, cb) => { fdOf(fd); if (typeof options === 'function') { cb = options; options = undefined; } cbOf(cb); callbackIO(cb, () => fstatSync(fd, options)); },\n"
4232
4996
  " unwatchFile: () => undefined,\n"
4233
4997
  " };\n"
4234
4998
  " fs.promises = {\n"
@@ -4250,13 +5014,11 @@ static const char isl_modules_bootstrap[] =
4250
5014
  " rename: promisify(renameSync),\n"
4251
5015
  " readlink: promisify(readlinkSync),\n"
4252
5016
  " constants,\n"
4253
- " open: () => {\n"
4254
- " return Promise.reject(new Error(\"fs.promises.open is not available in the scriptc island (whole-file reads/writes only)\"));\n"
4255
- " },\n"
5017
+ " open: async (p, flags, mode) => new FileHandle(openSync(p, flags, mode)),\n"
4256
5018
  " };\n"
4257
5019
  " return fs;\n"
4258
5020
  "}\n"
4259
- " const fs = makeFs({ fs: (...a) => host.fs(...a), fsConstants: () => host.fsConstants(), Buffer: builtins.buffer().Buffer, Readable: builtins.stream().Readable, Writable: builtins.stream().Writable, nextTick: (fn) => queueMicrotask(fn) });\n"
5021
+ " const fs = makeFs({ fs: (...a) => host.fs(...a), fsConstants: () => host.fsConstants(), Buffer: builtins.buffer().Buffer, Readable: builtins.stream().Readable, Writable: builtins.stream().Writable, EventEmitter: builtins.events().EventEmitter, URL: builtins.url().URL, fileURLToPath: builtins.url().fileURLToPath, nextTick: (fn) => queueMicrotask(fn) });\n"
4260
5022
  " fs.default = fs;\n"
4261
5023
  " return fs;\n"
4262
5024
  " });\n"
@@ -4339,44 +5101,161 @@ static const char isl_modules_bootstrap[] =
4339
5101
  " return tty;\n"
4340
5102
  " });\n"
4341
5103
  " builtins.diagnostics_channel = memo(() => {\n"
4342
- /* Real pub/sub semantics for plain channels (publish with no
4343
- * subscribers is a no-op, matching Node); tracingChannel reports
4344
- * hasSubscribers=false and its trace* methods run the traced function
4345
- * without publishing lifecycle events — the AI SDK checks
4346
- * hasSubscribers and skips tracing, exactly the Node path when nothing
4347
- * subscribed. */
4348
- " const channels = Object.create(null);\n"
5104
+ " // Store bindings count as active even when there are no message subscribers.\n"
5105
+ " // Store propagation follows the island's synchronous AsyncLocalStorage model.\n"
5106
+ " const channels = new Map();\n"
5107
+ " const deferError = (error) => { queueMicrotask(() => { throw error; }); };\n"
5108
+ " const deactivate = (channel) => {\n"
5109
+ " if (!channel._subscribers.length && !channel._stores.size) {\n"
5110
+ " channel._subscribers = undefined;\n"
5111
+ " channel._stores = undefined;\n"
5112
+ " }\n"
5113
+ " };\n"
4349
5114
  " class Channel {\n"
4350
- " constructor(name) { this.name = name; this._subs = []; }\n"
4351
- " get hasSubscribers() { return this._subs.length > 0; }\n"
4352
- " subscribe(fn) { this._subs.push(fn); }\n"
4353
- " unsubscribe(fn) {\n"
4354
- " const i = this._subs.indexOf(fn);\n"
4355
- " if (i < 0) return false;\n"
4356
- " this._subs.splice(i, 1);\n"
5115
+ " constructor(name) {\n"
5116
+ " this._subscribers = undefined;\n"
5117
+ " this._stores = undefined;\n"
5118
+ " this.name = name;\n"
5119
+ " channels.set(name, this);\n"
5120
+ " }\n"
5121
+ " static [Symbol.hasInstance](value) {\n"
5122
+ " if (value == null) throw new TypeError('Cannot convert undefined or null to object');\n"
5123
+ " return Object.getPrototypeOf(value) === Channel.prototype;\n"
5124
+ " }\n"
5125
+ " _activate() {\n"
5126
+ " if (this._subscribers === undefined) {\n"
5127
+ " this._subscribers = [];\n"
5128
+ " this._stores = new Map();\n"
5129
+ " }\n"
5130
+ " }\n"
5131
+ " get hasSubscribers() { return this._subscribers !== undefined; }\n"
5132
+ " subscribe(subscription) {\n"
5133
+ " this._activate();\n"
5134
+ " if (typeof subscription !== 'function') envArgumentError('subscription', 'of type function', subscription);\n"
5135
+ " this._subscribers = [...this._subscribers, subscription];\n"
5136
+ " }\n"
5137
+ " unsubscribe(subscription) {\n"
5138
+ " const index = this._subscribers?.indexOf(subscription) ?? -1;\n"
5139
+ " if (index === -1) return false;\n"
5140
+ " this._subscribers = [...this._subscribers.slice(0, index), ...this._subscribers.slice(index + 1)];\n"
5141
+ " deactivate(this);\n"
4357
5142
  " return true;\n"
4358
5143
  " }\n"
4359
- " publish(msg) { for (const f of this._subs.slice()) f(msg, this.name); }\n"
5144
+ " publish(data) {\n"
5145
+ " const subscribers = this._subscribers;\n"
5146
+ " for (const subscriber of subscribers ?? []) {\n"
5147
+ " try { subscriber(data, this.name); }\n"
5148
+ " catch (error) { deferError(error); }\n"
5149
+ " }\n"
5150
+ " }\n"
5151
+ " bindStore(store, transform) { this._activate(); this._stores.set(store, transform); }\n"
5152
+ " unbindStore(store) {\n"
5153
+ " if (!this._stores?.delete(store)) return false;\n"
5154
+ " deactivate(this);\n"
5155
+ " return true;\n"
5156
+ " }\n"
5157
+ " runStores(data, fn, thisArg, ...args) {\n"
5158
+ " let run = () => { this.publish(data); return Reflect.apply(fn, thisArg, args); };\n"
5159
+ " for (const [store, transform = (data) => data] of this._stores ?? []) {\n"
5160
+ " const next = run;\n"
5161
+ " run = () => {\n"
5162
+ " let context;\n"
5163
+ " try { context = transform(data); }\n"
5164
+ " catch (error) { deferError(error); return next(); }\n"
5165
+ " return store.run(context, next);\n"
5166
+ " };\n"
5167
+ " }\n"
5168
+ " return run();\n"
5169
+ " }\n"
4360
5170
  " }\n"
4361
- " const channel = (name) => channels[name] || (channels[name] = new Channel(name));\n"
4362
- " const tracingChannel = (name) => ({\n"
4363
- " get hasSubscribers() {\n"
4364
- " if (typeof name !== 'string') return false;\n"
4365
- " for (const s of ['start', 'end', 'asyncStart', 'asyncEnd', 'error']) {\n"
4366
- " if (channel('tracing:' + name + ':' + s).hasSubscribers) return true;\n"
5171
+ " const channel = (name) => {\n"
5172
+ " const existing = channels.get(name);\n"
5173
+ " if (existing) return existing;\n"
5174
+ " if (typeof name !== 'string' && typeof name !== 'symbol') envArgumentError('channel', 'one of type string or symbol', name);\n"
5175
+ " return new Channel(name);\n"
5176
+ " };\n"
5177
+ " const traceEvents = ['start', 'end', 'asyncStart', 'asyncEnd', 'error'];\n"
5178
+ " class TracingChannel {\n"
5179
+ " constructor(nameOrChannels) {\n"
5180
+ " for (const name of traceEvents) {\n"
5181
+ " let event;\n"
5182
+ " if (typeof nameOrChannels === 'string') event = channel('tracing:' + nameOrChannels + ':' + name);\n"
5183
+ " else if (nameOrChannels !== null && typeof nameOrChannels === 'object') {\n"
5184
+ " event = nameOrChannels[name];\n"
5185
+ " if (!(event instanceof Channel)) envArgumentError('nameOrChannels.' + name, 'an instance of Channel', event);\n"
5186
+ " } else envArgumentError('nameOrChannels', 'of type string or an instance of TracingChannel or Object', nameOrChannels);\n"
5187
+ " Object.defineProperty(this, name, { value: event });\n"
4367
5188
  " }\n"
4368
- " return false;\n"
4369
- " },\n"
4370
- " traceSync(fn, ctx, thisArg, ...args) { return fn.apply(thisArg, args); },\n"
4371
- " tracePromise(fn, ctx, thisArg, ...args) { return fn.apply(thisArg, args); },\n"
4372
- " traceCallback(fn, position, ctx, thisArg, ...args) { return fn.apply(thisArg, args); },\n"
4373
- " });\n"
5189
+ " }\n"
5190
+ " get hasSubscribers() { return traceEvents.some((name) => this[name]?.hasSubscribers); }\n"
5191
+ " subscribe(handlers) {\n"
5192
+ " for (const name of traceEvents) if (handlers[name]) this[name]?.subscribe(handlers[name]);\n"
5193
+ " }\n"
5194
+ " unsubscribe(handlers) {\n"
5195
+ " let done = true;\n"
5196
+ " for (const name of traceEvents) if (handlers[name] && !this[name]?.unsubscribe(handlers[name])) done = false;\n"
5197
+ " return done;\n"
5198
+ " }\n"
5199
+ " traceSync(fn, context = {}, thisArg, ...args) {\n"
5200
+ " if (!this.hasSubscribers) return Reflect.apply(fn, thisArg, args);\n"
5201
+ " return this.start.runStores(context, () => {\n"
5202
+ " try { const result = Reflect.apply(fn, thisArg, args); context.result = result; return result; }\n"
5203
+ " catch (error) { context.error = error; this.error.publish(context); throw error; }\n"
5204
+ " finally { this.end.publish(context); }\n"
5205
+ " });\n"
5206
+ " }\n"
5207
+ " tracePromise(fn, context = {}, thisArg, ...args) {\n"
5208
+ " if (!this.hasSubscribers) return Reflect.apply(fn, thisArg, args);\n"
5209
+ " const resolve = (result) => {\n"
5210
+ " context.result = result;\n"
5211
+ " this.asyncStart.publish(context);\n"
5212
+ " this.asyncEnd.publish(context);\n"
5213
+ " return result;\n"
5214
+ " };\n"
5215
+ " const reject = (error) => {\n"
5216
+ " context.error = error;\n"
5217
+ " this.error.publish(context);\n"
5218
+ " this.asyncStart.publish(context);\n"
5219
+ " this.asyncEnd.publish(context);\n"
5220
+ " return Promise.reject(error);\n"
5221
+ " };\n"
5222
+ " return this.start.runStores(context, () => {\n"
5223
+ " try {\n"
5224
+ " let promise = Reflect.apply(fn, thisArg, args);\n"
5225
+ " if (!(promise instanceof Promise)) promise = Promise.resolve(promise);\n"
5226
+ " return Promise.prototype.then.call(promise, resolve, reject);\n"
5227
+ " } catch (error) { context.error = error; this.error.publish(context); throw error; }\n"
5228
+ " finally { this.end.publish(context); }\n"
5229
+ " });\n"
5230
+ " }\n"
5231
+ " traceCallback(fn, position = -1, context = {}, thisArg, ...args) {\n"
5232
+ " if (!this.hasSubscribers) return Reflect.apply(fn, thisArg, args);\n"
5233
+ " const { start, end, asyncStart, asyncEnd, error } = this;\n"
5234
+ " const callback = args.at(position);\n"
5235
+ " if (typeof callback !== 'function') envArgumentError('callback', 'of type function', callback);\n"
5236
+ " function wrappedCallback(err, result) {\n"
5237
+ " if (err) { context.error = err; error.publish(context); }\n"
5238
+ " else context.result = result;\n"
5239
+ " asyncStart.runStores(context, () => {\n"
5240
+ " try { return Reflect.apply(callback, this, arguments); }\n"
5241
+ " finally { asyncEnd.publish(context); }\n"
5242
+ " });\n"
5243
+ " }\n"
5244
+ " args.splice(position, 1, wrappedCallback);\n"
5245
+ " return start.runStores(context, () => {\n"
5246
+ " try { return Reflect.apply(fn, thisArg, args); }\n"
5247
+ " catch (err) { context.error = err; error.publish(context); throw err; }\n"
5248
+ " finally { end.publish(context); }\n"
5249
+ " });\n"
5250
+ " }\n"
5251
+ " }\n"
4374
5252
  " const dc = {\n"
4375
5253
  " channel,\n"
4376
- " subscribe: (name, fn) => { channel(name).subscribe(fn); },\n"
4377
- " unsubscribe: (name, fn) => channel(name).unsubscribe(fn),\n"
4378
- " hasSubscribers: (name) => channel(name).hasSubscribers,\n"
4379
- " tracingChannel,\n"
5254
+ " subscribe: (name, subscription) => channel(name).subscribe(subscription),\n"
5255
+ " unsubscribe: (name, subscription) => channel(name).unsubscribe(subscription),\n"
5256
+ " hasSubscribers: (name) => channels.get(name)?.hasSubscribers ?? false,\n"
5257
+ " tracingChannel: (nameOrChannels) => new TracingChannel(nameOrChannels),\n"
5258
+ " Channel,\n"
4380
5259
  " };\n"
4381
5260
  " dc.default = dc;\n"
4382
5261
  " return dc;\n"
@@ -4394,7 +5273,10 @@ static const char isl_modules_bootstrap[] =
4394
5273
  " if (key.startsWith('file://')) key = decodeURIComponent(key.slice(7));\n"
4395
5274
  /* The base file is the created require's parent, like Node: modules
4396
5275
  * it loads report it in their require stacks. */
4397
- " return decorateRequire((spec) => requireKey(spec.startsWith('node:') ? spec : resolveFrom(key, spec), key), key);\n"
5276
+ " const parent = new Module(key);\n"
5277
+ " parent.filename = key;\n"
5278
+ " parent.paths = modulePathsFrom(parent.path);\n"
5279
+ " return decorateRequire((spec) => parent.require(spec), parent);\n"
4398
5280
  " };\n"
4399
5281
  /* builtinModules/isBuiltin answer Node's QUESTION ("is this name a
4400
5282
  * Node builtin?") with Node's full list — resolution of unshimmed
@@ -4422,11 +5304,11 @@ static const char isl_modules_bootstrap[] =
4422
5304
  * converters riding the static scr_url.c implementations (Node's
4423
5305
  * exact rules), and the legacy parse/format/resolve trio over the
4424
5306
  * WHATWG parser. */
4425
- " const fileURLToPath = (u) => {\n"
4426
- " const s = typeof u === 'object' && u !== null && 'href' in u ? String(u.href) : String(u);\n"
4427
- " return host.urlToPath(s);\n"
4428
- " };\n"
4429
- " const pathToFileURL = (p) => new globalThis.URL(host.urlFromPath(String(p)));\n"
5307
+ /* Read user option getters in their engine so thrown values preserve
5308
+ * identity. The path-to-URL public wrapper validates its path first. */
5309
+ " const fileURLToPath = (u, options) => host.urlToPath(u, { windows: options?.windows });\n"
5310
+ " const fileURLToPathBuffer = (u, options) => builtins.buffer().Buffer.from(host.urlToPathBuffer(u, { windows: options?.windows }));\n"
5311
+ " const pathToFileURL = (p, options) => new globalThis.URL(host.urlFromPath(p, typeof p === 'string' ? { windows: options?.windows } : undefined));\n"
4430
5312
  " const parse = (input, parseQuery) => {\n"
4431
5313
  " const out = { protocol: null, slashes: null, auth: null, host: null, port: null,\n"
4432
5314
  " hostname: null, hash: null, search: null, query: null, pathname: null, path: null, href: String(input) };\n"
@@ -4488,7 +5370,7 @@ static const char isl_modules_bootstrap[] =
4488
5370
  " const u = {\n"
4489
5371
  " URL: globalThis.URL,\n"
4490
5372
  " URLSearchParams: globalThis.URLSearchParams,\n"
4491
- " fileURLToPath, pathToFileURL, parse, format, resolve,\n"
5373
+ " fileURLToPath, fileURLToPathBuffer, pathToFileURL, parse, format, resolve,\n"
4492
5374
  /* IDNA is not carried: ASCII hostnames pass through lowercased
4493
5375
  * (documented divergence for internationalized domains). */
4494
5376
  " domainToASCII: (d) => String(d).toLowerCase(),\n"
@@ -4510,7 +5392,7 @@ static const char isl_modules_bootstrap[] =
4510
5392
  " const K_STRING_MAX_LENGTH = 536870888;\n"
4511
5393
  " const INSPECT_MAX_BYTES = 50;\n"
4512
5394
  " const utf8Enc = new TextEncoder();\n"
4513
- " const utf8Dec = new TextDecoder();\n"
5395
+ " const utf8Dec = new TextDecoder(\"utf-8\", { ignoreBOM: true });\n"
4514
5396
  " const B64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n"
4515
5397
  " const B64U = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n"
4516
5398
  " const b64Val = (() => {\n"
@@ -4548,7 +5430,7 @@ static const char isl_modules_bootstrap[] =
4548
5430
  " return e;\n"
4549
5431
  " };\n"
4550
5432
  " const invalidArg = (name, expected, actual) => {\n"
4551
- " const t = actual === null ? \"null\" : typeof actual === \"object\" ? \"an instance of \" + (actual.constructor && actual.constructor.name || \"Object\") : typeof actual === \"string\" ? \"type string ('\" + actual + \"')\" : \"type \" + typeof actual + \" (\" + String(actual) + \")\";\n"
5433
+ " const t = actual == null ? String(actual) : typeof actual === \"object\" ? \"an instance of \" + (actual.constructor && actual.constructor.name || \"Object\") : typeof actual === \"string\" ? \"type string ('\" + actual + \"')\" : \"type \" + typeof actual + \" (\" + String(actual) + (typeof actual === 'bigint' ? 'n' : '') + \")\";\n"
4552
5434
  " const label = name === \"first argument\" ? \"The first argument\" : 'The \"' + name + '\" argument';\n"
4553
5435
  " const e = new TypeError(label + \" must be \" + expected + \". Received \" + t);\n"
4554
5436
  " e.code = \"ERR_INVALID_ARG_TYPE\";\n"
@@ -5210,15 +6092,20 @@ static const char isl_modules_bootstrap[] =
5210
6092
  " return -1;\n"
5211
6093
  " };\n"
5212
6094
  " function SlowBuffer(size) { return Buffer.alloc(size); }\n"
6095
+ " const validationBytes = (input) => {\n"
6096
+ " if (ArrayBuffer.isView(input) && !(input instanceof DataView)) return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);\n"
6097
+ " if (input instanceof ArrayBuffer || (typeof SharedArrayBuffer === 'function' && input instanceof SharedArrayBuffer)) return new Uint8Array(input);\n"
6098
+ " throw invalidArg('input', 'an instance of ArrayBuffer, Buffer, or TypedArray', input);\n"
6099
+ " };\n"
5213
6100
  " const isAscii = (input) => {\n"
5214
- " const u8 = input instanceof Uint8Array ? input : new Uint8Array(input);\n"
6101
+ " const u8 = validationBytes(input);\n"
5215
6102
  " for (let i = 0; i < u8.length; i++) {\n"
5216
6103
  " if (u8[i] > 0x7f) return false;\n"
5217
6104
  " }\n"
5218
6105
  " return true;\n"
5219
6106
  " };\n"
5220
6107
  " const isUtf8 = (input) => {\n"
5221
- " const u8 = input instanceof Uint8Array ? input : new Uint8Array(input);\n"
6108
+ " const u8 = validationBytes(input);\n"
5222
6109
  " let i = 0;\n"
5223
6110
  " while (i < u8.length) {\n"
5224
6111
  " const b = u8[i];\n"
@@ -5256,8 +6143,9 @@ static const char isl_modules_bootstrap[] =
5256
6143
  * (scr_web.c) owns the implementations. */
5257
6144
  " Blob: globalThis.Blob,\n"
5258
6145
  " File: globalThis.File,\n"
5259
- " transcode: () => {\n"
5260
- " throw new Error(\"buffer.transcode is not available in the scriptc island\");\n"
6146
+ " transcode: (source, from, to) => {\n"
6147
+ " if (!(source instanceof Uint8Array)) throw invalidArg('source', 'an instance of Buffer or Uint8Array', source);\n"
6148
+ " return Buffer.from(host.transcode(source, from, to));\n"
5261
6149
  " },\n"
5262
6150
  " resolveObjectURL: () => undefined,\n"
5263
6151
  " };\n"
@@ -5266,97 +6154,89 @@ static const char isl_modules_bootstrap[] =
5266
6154
  " mod.default = mod;\n"
5267
6155
  " return mod;\n"
5268
6156
  " });\n"
5269
- /* node:string_decoder — StringDecoder over the Buffer shim: utf8
5270
- * rides the prelude TextDecoder's streaming state machine,
5271
- * utf16le holds byte parity, base64 carries mod-3 remainders. */
6157
+ /* node:string_decoder — preserve Node's byte buffering independently
6158
+ * of WHATWG TextDecoder: BOMs, invalid prefixes, UTF-16 pairs, and
6159
+ * base64 groups retain their chunk-boundary behavior. */
5272
6160
  " builtins.string_decoder = memo(() => {\n"
5273
6161
  "function makeStringDecoder(Buffer) {\n"
5274
6162
  " const normEnc = (enc) => {\n"
5275
- " if (enc === undefined || enc === null) return \"utf8\";\n"
5276
- " const e = String(enc).toLowerCase();\n"
5277
- " if (e === \"utf8\" || e === \"utf-8\") return \"utf8\";\n"
5278
- " if (e === \"hex\") return \"hex\";\n"
5279
- " if (e === \"base64\") return \"base64\";\n"
5280
- " if (e === \"base64url\") return \"base64url\";\n"
5281
- " if (e === \"latin1\" || e === \"binary\") return \"latin1\";\n"
5282
- " if (e === \"ascii\") return \"ascii\";\n"
5283
- " if (e === \"utf16le\" || e === \"utf-16le\" || e === \"ucs2\" || e === \"ucs-2\") return \"utf16le\";\n"
5284
- " const err = new TypeError(\"Unknown encoding: \" + enc);\n"
5285
- " err.code = \"ERR_UNKNOWN_ENCODING\";\n"
6163
+ " if (enc === undefined || enc === null || enc === '') return 'utf8';\n"
6164
+ " const e = typeof enc === 'string' ? enc.toLowerCase() : enc;\n"
6165
+ " if (e === 'utf8' || e === 'utf-8') return 'utf8';\n"
6166
+ " if (e === 'hex' || e === 'base64' || e === 'base64url' || e === 'ascii') return e;\n"
6167
+ " if (e === 'latin1' || e === 'binary') return 'latin1';\n"
6168
+ " if (e === 'utf16le' || e === 'utf-16le' || e === 'ucs2' || e === 'ucs-2') return 'utf16le';\n"
6169
+ " const err = new TypeError('Unknown encoding: ' + String(enc));\n"
6170
+ " err.code = 'ERR_UNKNOWN_ENCODING';\n"
5286
6171
  " throw err;\n"
5287
6172
  " };\n"
5288
6173
  " class StringDecoder {\n"
5289
6174
  " constructor(encoding) {\n"
5290
6175
  " this.encoding = normEnc(encoding);\n"
5291
- " if (this.encoding === \"utf8\") {\n"
5292
- " this._dec = new TextDecoder();\n"
5293
- " } else if (this.encoding === \"utf16le\") {\n"
5294
- " this._oddByte = -1;\n"
5295
- " } else if (this.encoding === \"base64\" || this.encoding === \"base64url\") {\n"
5296
- " this._rem = null;\n"
5297
- " }\n"
6176
+ " this._encoding = this.encoding;\n"
6177
+ " this._pending = new Uint8Array(0);\n"
6178
+ " this._missing = 0;\n"
5298
6179
  " }\n"
5299
6180
  " write(buf) {\n"
5300
- " if (typeof buf === \"string\") return buf;\n"
5301
- " const u8 = buf instanceof Uint8Array ? buf : new Uint8Array(buf);\n"
5302
- " switch (this.encoding) {\n"
5303
- " case \"utf8\":\n"
5304
- " return this._dec.decode(u8, { stream: true });\n"
5305
- " case \"utf16le\": {\n"
5306
- " let bytes = u8;\n"
5307
- " if (this._oddByte >= 0) {\n"
5308
- " const joined = new Uint8Array(u8.length + 1);\n"
5309
- " joined[0] = this._oddByte;\n"
5310
- " joined.set(u8, 1);\n"
5311
- " bytes = joined;\n"
5312
- " this._oddByte = -1;\n"
5313
- " }\n"
5314
- " if (bytes.length % 2 !== 0) {\n"
5315
- " this._oddByte = bytes[bytes.length - 1];\n"
5316
- " bytes = bytes.subarray(0, bytes.length - 1);\n"
6181
+ " if (typeof buf === 'string') return buf;\n"
6182
+ " if (!ArrayBuffer.isView(buf)) {\n"
6183
+ " const received = buf === null ? 'null' : buf === undefined ? 'undefined' : typeof buf === 'object' ? 'an instance of ' + (buf.constructor && buf.constructor.name || 'Object') : 'type ' + typeof buf + ' (' + String(buf) + ')';\n"
6184
+ " const err = new TypeError('The \"buf\" argument must be an instance of Buffer, TypedArray, or DataView. Received ' + received);\n"
6185
+ " err.code = 'ERR_INVALID_ARG_TYPE';\n"
6186
+ " throw err;\n"
6187
+ " }\n"
6188
+ " const bytes = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n"
6189
+ " const enc = this._encoding;\n"
6190
+ " let offset = 0;\n"
6191
+ " let out = '';\n"
6192
+ " if (this._missing > 0) {\n"
6193
+ " let take = Math.min(bytes.length, this._missing);\n"
6194
+ " if (enc === 'utf8') {\n"
6195
+ " for (let i = 0; i < take; i++) {\n"
6196
+ " if ((bytes[i] & 0xc0) !== 0x80) { take = i; this._missing = i; break; }\n"
5317
6197
  " }\n"
5318
- " return Buffer.from(bytes).toString(\"utf16le\");\n"
5319
6198
  " }\n"
5320
- " case \"base64\":\n"
5321
- " case \"base64url\": {\n"
5322
- " let bytes = u8;\n"
5323
- " if (this._rem !== null) {\n"
5324
- " const joined = new Uint8Array(this._rem.length + u8.length);\n"
5325
- " joined.set(this._rem, 0);\n"
5326
- " joined.set(u8, this._rem.length);\n"
5327
- " bytes = joined;\n"
5328
- " this._rem = null;\n"
5329
- " }\n"
5330
- " const usable = bytes.length - (bytes.length % 3);\n"
5331
- " if (usable < bytes.length) {\n"
5332
- " this._rem = bytes.slice(usable);\n"
5333
- " bytes = bytes.subarray(0, usable);\n"
5334
- " }\n"
5335
- " return Buffer.from(bytes).toString(this.encoding);\n"
6199
+ " const pending = new Uint8Array(this._pending.length + take);\n"
6200
+ " pending.set(this._pending);\n"
6201
+ " pending.set(bytes.subarray(0, take), this._pending.length);\n"
6202
+ " this._pending = pending;\n"
6203
+ " this._missing -= take;\n"
6204
+ " offset = take;\n"
6205
+ " if (this._missing === 0) {\n"
6206
+ " out = Buffer.from(pending).toString(enc);\n"
6207
+ " this._pending = new Uint8Array(0);\n"
5336
6208
  " }\n"
5337
- " default:\n"
5338
- " return Buffer.from(u8).toString(this.encoding);\n"
5339
- " }\n"
6209
+ " if (offset === bytes.length) return out;\n"
6210
+ " }\n"
6211
+ " const n = bytes.length - offset;\n"
6212
+ " let held = 0;\n"
6213
+ " let total = 0;\n"
6214
+ " if (enc === 'utf8') {\n"
6215
+ " for (let back = 1; back <= Math.min(n, 3); back++) {\n"
6216
+ " const b = bytes[bytes.length - back];\n"
6217
+ " if ((b & 0xc0) === 0x80) continue;\n"
6218
+ " total = (b & 0xe0) === 0xc0 ? 2 : (b & 0xf0) === 0xe0 ? 3 : (b & 0xf8) === 0xf0 ? 4 : 0;\n"
6219
+ " if (back < total) held = back;\n"
6220
+ " break;\n"
6221
+ " }\n"
6222
+ " } else if (enc === 'utf16le') {\n"
6223
+ " if (n % 2) { held = 1; total = 2; }\n"
6224
+ " else if (n >= 2 && (bytes[bytes.length - 1] & 0xfc) === 0xd8) { held = 2; total = 4; }\n"
6225
+ " } else if (enc === 'base64' || enc === 'base64url') {\n"
6226
+ " held = n % 3;\n"
6227
+ " total = 3;\n"
6228
+ " }\n"
6229
+ " const end = bytes.length - held;\n"
6230
+ " this._pending = bytes.slice(end);\n"
6231
+ " this._missing = held ? total - held : 0;\n"
6232
+ " return out + Buffer.from(bytes.subarray(offset, end)).toString(enc);\n"
5340
6233
  " }\n"
5341
6234
  " end(buf) {\n"
5342
- " let out = buf !== undefined ? this.write(buf) : \"\";\n"
5343
- " switch (this.encoding) {\n"
5344
- " case \"utf8\":\n"
5345
- " out += this._dec.decode();\n"
5346
- " this._dec = new TextDecoder();\n"
5347
- " break;\n"
5348
- " case \"utf16le\":\n"
5349
- " this._oddByte = -1;\n"
5350
- " break;\n"
5351
- " case \"base64\":\n"
5352
- " case \"base64url\":\n"
5353
- " if (this._rem !== null) {\n"
5354
- " out += Buffer.from(this._rem).toString(this.encoding);\n"
5355
- " this._rem = null;\n"
5356
- " }\n"
5357
- " break;\n"
5358
- " }\n"
5359
- " return out;\n"
6235
+ " const out = buf === undefined ? '' : this.write(buf);\n"
6236
+ " const tail = Buffer.from(this._pending).toString(this._encoding);\n"
6237
+ " this._pending = new Uint8Array(0);\n"
6238
+ " this._missing = 0;\n"
6239
+ " return out + tail;\n"
5360
6240
  " }\n"
5361
6241
  " }\n"
5362
6242
  " return { StringDecoder };\n"
@@ -5366,7 +6246,7 @@ static const char isl_modules_bootstrap[] =
5366
6246
  " return mod;\n"
5367
6247
  " });\n"
5368
6248
  /* node:crypto — the hashing/random slice over host bridges
5369
- * (md5/sha1/sha256 digest + HMAC through the same C
6249
+ * (MD5/SHA-1/SHA-2 digest + HMAC through the same C
5370
6250
  * implementations the static lowerings use; randomness through
5371
6251
  * the web prelude's CSPRNG), pbkdf2 over the HMAC bridge, and
5372
6252
  * honest throwing stubs for the key/cipher machinery the island
@@ -5584,12 +6464,119 @@ static const char isl_modules_bootstrap[] =
5584
6464
  " }\n"
5585
6465
  " queueMicrotask(() => callback(null, derived));\n"
5586
6466
  " };\n"
6467
+ " const kdfError = (kind, code, message) => {\n"
6468
+ " const error = new kind(message);\n"
6469
+ " error.code = code;\n"
6470
+ " return error;\n"
6471
+ " };\n"
6472
+ " const kdfNumber = (value) => Number.isInteger(value) && Math.abs(value) > 4294967296 ? String(value).replace(/\\B(?=(\\d{3})+(?!\\d))/g, \"_\") : String(value);\n"
6473
+ " const kdfInteger = (value, name, max) => {\n"
6474
+ " if (typeof value !== \"number\") {\n"
6475
+ " const received = value === null ? \"null\" : value === undefined ? \"undefined\" : typeof value === \"object\" ? \"an instance of \" + ((value.constructor && value.constructor.name) || \"Object\") : \"type \" + typeof value + \" (\" + (typeof value === \"string\" ? \"'\" + value + \"'\" : String(value)) + \")\";\n"
6476
+ " throw kdfError(TypeError, \"ERR_INVALID_ARG_TYPE\", 'The \"' + name + '\" argument must be of type number. Received ' + received);\n"
6477
+ " }\n"
6478
+ " if (!Number.isInteger(value) || value < 0 || value > max) {\n"
6479
+ " const range = Number.isInteger(value) ? \">= 0 && <= \" + max : \"an integer\";\n"
6480
+ " throw kdfError(RangeError, \"ERR_OUT_OF_RANGE\", 'The value of \"' + name + '\" is out of range. It must be ' + range + '. Received ' + kdfNumber(value));\n"
6481
+ " }\n"
6482
+ " return value;\n"
6483
+ " };\n"
6484
+ " const kdfInput = (value, name, hkdfKey = false, hkdfSource = false) => {\n"
6485
+ " if (typeof value === \"string\") return Buffer.from(value);\n"
6486
+ " if (value instanceof ArrayBuffer) return new Uint8Array(value);\n"
6487
+ " if (ArrayBuffer.isView(value)) return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n"
6488
+ " const received = value === null ? \"null\" : value === undefined ? \"undefined\" : typeof value === \"object\" ? \"an instance of \" + ((value.constructor && value.constructor.name) || \"Object\") : \"type \" + typeof value + \" (\" + (typeof value === \"string\" ? \"'\" + value + \"'\" : String(value)) + \")\";\n"
6489
+ " const expected = hkdfKey ? \"string or an instance of SecretKeyObject, ArrayBuffer, TypedArray, DataView, or Buffer\" : hkdfSource ? \"string or an instance of ArrayBuffer, TypedArray, DataView, or Buffer\" : \"string or an instance of ArrayBuffer, Buffer, TypedArray, or DataView\";\n"
6490
+ " throw kdfError(TypeError, \"ERR_INVALID_ARG_TYPE\", 'The \"' + name + '\" argument must be of type ' + expected + '. Received ' + received);\n"
6491
+ " };\n"
6492
+ " const kdfCallback = (callback) => {\n"
6493
+ " if (typeof callback !== \"function\") {\n"
6494
+ " const received = callback === undefined ? \"undefined\" : callback === null ? \"null\" : typeof callback === \"object\" ? \"an instance of \" + ((callback.constructor && callback.constructor.name) || \"Object\") : \"type \" + typeof callback + \" (\" + String(callback) + \")\";\n"
6495
+ " throw kdfError(TypeError, \"ERR_INVALID_ARG_TYPE\", 'The \"callback\" argument must be of type function. Received ' + received);\n"
6496
+ " }\n"
6497
+ " };\n"
6498
+ " const hkdfParameters = (digest, ikm, salt, info, keylen) => {\n"
6499
+ " if (typeof digest !== \"string\") {\n"
6500
+ " const received = digest === undefined ? \"undefined\" : digest === null ? \"null\" : \"type \" + typeof digest + \" (\" + String(digest) + \")\";\n"
6501
+ " throw kdfError(TypeError, \"ERR_INVALID_ARG_TYPE\", 'The \"digest\" argument must be of type string. Received ' + received);\n"
6502
+ " }\n"
6503
+ " ikm = kdfInput(ikm, \"ikm\", true);\n"
6504
+ " salt = kdfInput(salt, \"salt\", false, true);\n"
6505
+ " info = kdfInput(info, \"info\", false, true);\n"
6506
+ " kdfInteger(keylen, \"length\", Number.MAX_SAFE_INTEGER);\n"
6507
+ " if (info.length > 1024) throw kdfError(RangeError, \"ERR_OUT_OF_RANGE\", 'The value of \"info\" is out of range. It must be must not contain more than 1024 bytes. Received ' + info.length);\n"
6508
+ " return [digest, ikm, salt, info, keylen];\n"
6509
+ " };\n"
6510
+ " const hkdfDerive = (digest, ikm, salt, info, keylen) => {\n"
6511
+ " const prk = env.hmac(digest.toLowerCase(), salt, ikm);\n"
6512
+ " if (prk === undefined) throw kdfError(TypeError, \"ERR_CRYPTO_INVALID_DIGEST\", \"Invalid digest: \" + digest);\n"
6513
+ " if (keylen > 255 * prk.length) {\n"
6514
+ " prk.fill(0);\n"
6515
+ " throw kdfError(RangeError, \"ERR_CRYPTO_INVALID_KEYLEN\", \"Invalid key length\");\n"
6516
+ " }\n"
6517
+ " const result = new Uint8Array(keylen);\n"
6518
+ " let previous = new Uint8Array(0), offset = 0;\n"
6519
+ " for (let counter = 1; offset < keylen; counter++) {\n"
6520
+ " const block = new Uint8Array(previous.length + info.length + 1);\n"
6521
+ " block.set(previous);\n"
6522
+ " block.set(info, previous.length);\n"
6523
+ " block[block.length - 1] = counter;\n"
6524
+ " const next = env.hmac(digest.toLowerCase(), prk, block);\n"
6525
+ " previous.fill(0);\n"
6526
+ " block.fill(0);\n"
6527
+ " previous = next;\n"
6528
+ " const take = Math.min(next.length, keylen - offset);\n"
6529
+ " result.set(next.subarray(0, take), offset);\n"
6530
+ " offset += take;\n"
6531
+ " }\n"
6532
+ " prk.fill(0);\n"
6533
+ " previous.fill(0);\n"
6534
+ " return result.buffer;\n"
6535
+ " };\n"
6536
+ " const hkdfSync = (digest, ikm, salt, info, keylen) => {\n"
6537
+ " const result = hkdfDerive(...hkdfParameters(digest, ikm, salt, info, keylen));\n"
6538
+ " if (result.byteLength === 0) throw new Error(\"Deriving bits failed\");\n"
6539
+ " return result;\n"
6540
+ " };\n"
6541
+ " const hkdf = (digest, ikm, salt, info, keylen, callback) => {\n"
6542
+ " const params = hkdfParameters(digest, ikm, salt, info, keylen);\n"
6543
+ " kdfCallback(callback);\n"
6544
+ " const result = hkdfDerive(...params);\n"
6545
+ " setImmediate(() => result.byteLength === 0 ? callback(new Error(\"Deriving bits failed\")) : callback(null, result));\n"
6546
+ " };\n"
6547
+ " const scryptParameters = (password, salt, keylen, options) => {\n"
6548
+ " password = kdfInput(password, \"password\");\n"
6549
+ " salt = kdfInput(salt, \"salt\");\n"
6550
+ " kdfInteger(keylen, \"keylen\", 2147483647);\n"
6551
+ " const values = [16384, 8, 1, 33554432];\n"
6552
+ " if (options) {\n"
6553
+ " const names = [\"N\", \"r\", \"p\"], aliases = [\"cost\", \"blockSize\", \"parallelization\"];\n"
6554
+ " for (let i = 0; i < 3; i++) {\n"
6555
+ " const name = names[i], alias = aliases[i], present = options[name] !== undefined;\n"
6556
+ " if (present) values[i] = kdfInteger(options[name], name, 4294967295);\n"
6557
+ " if (options[alias] !== undefined) {\n"
6558
+ " if (present) throw kdfError(TypeError, \"ERR_INCOMPATIBLE_OPTION_PAIR\", 'Option \"' + name + '\" cannot be used in combination with option \"' + alias + '\"');\n"
6559
+ " values[i] = kdfInteger(options[alias], alias, 4294967295);\n"
6560
+ " }\n"
6561
+ " }\n"
6562
+ " if (options.maxmem !== undefined) values[3] = kdfInteger(options.maxmem, \"maxmem\", Number.MAX_SAFE_INTEGER);\n"
6563
+ " }\n"
6564
+ " return [password, salt, keylen, ...values];\n"
6565
+ " };\n"
6566
+ " const scryptSync = (password, salt, keylen, options) => Buffer.from(env.scrypt(...scryptParameters(password, salt, keylen, options)));\n"
6567
+ " const scrypt = (password, salt, keylen, options, callback) => {\n"
6568
+ " if (callback === undefined) { callback = options; options = undefined; }\n"
6569
+ " const params = scryptParameters(password, salt, keylen, options);\n"
6570
+ " kdfCallback(callback);\n"
6571
+ " const result = Buffer.from(env.scrypt(...params));\n"
6572
+ " setImmediate(() => callback(null, result));\n"
6573
+ " };\n"
5587
6574
  " const die = (name) => function unsupported() {\n"
5588
- " throw new Error(\"crypto.\" + name + \" is not available in the scriptc island (the embedded runtime carries the hashing/random slice only)\");\n"
6575
+ " throw new Error(\"crypto.\" + name + \" is not available in the scriptc island (the embedded runtime carries the hashing/random/KDF slice only)\");\n"
5589
6576
  " };\n"
5590
6577
  " class KeyObject {\n"
5591
6578
  " constructor() {\n"
5592
- " throw new Error(\"crypto.KeyObject is not available in the scriptc island (the embedded runtime carries the hashing/random slice only)\");\n"
6579
+ " throw new Error(\"crypto.KeyObject is not available in the scriptc island (the embedded runtime carries the hashing/random/KDF slice only)\");\n"
5593
6580
  " }\n"
5594
6581
  " }\n"
5595
6582
  " const constants = {\n"
@@ -5607,8 +6594,8 @@ static const char isl_modules_bootstrap[] =
5607
6594
  " createHash, createHmac, hash, Hash, Hmac,\n"
5608
6595
  " randomBytes, randomFillSync, randomFill, randomInt, randomUUID,\n"
5609
6596
  " getRandomValues: (ta) => webcrypto.getRandomValues(ta),\n"
5610
- " timingSafeEqual, pbkdf2, pbkdf2Sync,\n"
5611
- " getHashes: () => [\"md5\", \"sha1\", \"sha256\"],\n"
6597
+ " timingSafeEqual, pbkdf2, pbkdf2Sync, hkdf, hkdfSync, scrypt, scryptSync,\n"
6598
+ " getHashes: () => [\"md5\", \"sha1\", \"sha224\", \"sha256\", \"sha384\", \"sha512\"],\n"
5612
6599
  " getCiphers: () => [],\n"
5613
6600
  " getCurves: () => [],\n"
5614
6601
  " webcrypto,\n"
@@ -5634,10 +6621,6 @@ static const char isl_modules_bootstrap[] =
5634
6621
  " publicDecrypt: die(\"publicDecrypt\"),\n"
5635
6622
  " privateEncrypt: die(\"privateEncrypt\"),\n"
5636
6623
  " privateDecrypt: die(\"privateDecrypt\"),\n"
5637
- " scrypt: die(\"scrypt\"),\n"
5638
- " scryptSync: die(\"scryptSync\"),\n"
5639
- " hkdf: die(\"hkdf\"),\n"
5640
- " hkdfSync: die(\"hkdfSync\"),\n"
5641
6624
  " X509Certificate: die(\"X509Certificate\"),\n"
5642
6625
  " Certificate: die(\"Certificate\"),\n"
5643
6626
  " checkPrime: die(\"checkPrime\"),\n"
@@ -5652,7 +6635,7 @@ static const char isl_modules_bootstrap[] =
5652
6635
  " crypto.subtle = webcrypto ? webcrypto.subtle : undefined;\n"
5653
6636
  " return crypto;\n"
5654
6637
  "}\n"
5655
- " const mod = makeCrypto({ digest: (a, d) => host.digest(a, d), hmac: (a, k, d) => host.hmac(a, k, d), Buffer: builtins.buffer().Buffer });\n"
6638
+ " const mod = makeCrypto({ digest: (a, d) => host.digest(a, d), hmac: (a, k, d) => host.hmac(a, k, d), scrypt: (...args) => host.scrypt(...args), Buffer: builtins.buffer().Buffer });\n"
5656
6639
  " mod.default = mod;\n"
5657
6640
  " return mod;\n"
5658
6641
  " });\n"
@@ -6553,7 +7536,12 @@ static const char isl_modules_bootstrap[] =
6553
7536
  " const g = globalThis;\n"
6554
7537
  " const w = {\n"
6555
7538
  " ReadableStream: g.ReadableStream, TransformStream: g.TransformStream,\n"
6556
- " TextDecoderStream: g.TextDecoderStream,\n"
7539
+ " ReadableStreamDefaultReader: g.ReadableStreamDefaultReader, ReadableStreamDefaultController: g.ReadableStreamDefaultController,\n"
7540
+ " TextDecoderStream: g.TextDecoderStream, TextEncoderStream: g.TextEncoderStream,\n"
7541
+ " TransformStreamDefaultController: g.TransformStreamDefaultController,\n"
7542
+ " WritableStream: g.WritableStream, WritableStreamDefaultWriter: g.WritableStreamDefaultWriter,\n"
7543
+ " WritableStreamDefaultController: g.WritableStreamDefaultController,\n"
7544
+ " CountQueuingStrategy: g.CountQueuingStrategy, ByteLengthQueuingStrategy: g.ByteLengthQueuingStrategy,\n"
6557
7545
  " };\n"
6558
7546
  " w.default = w;\n"
6559
7547
  " return w;\n"
@@ -6738,6 +7726,44 @@ static const char isl_modules_bootstrap[] =
6738
7726
  " generatedMessage: true,\n"
6739
7727
  " });\n"
6740
7728
  " };\n"
7729
+ " const noErrorRegexExec = RegExp.prototype.exec;\n"
7730
+ " const noErrorMatches = (actual, expected) => {\n"
7731
+ " if (typeof expected === 'function') {\n"
7732
+ " if (expected.prototype !== undefined && actual instanceof expected) return true;\n"
7733
+ " if (Object.prototype.isPrototypeOf.call(Error, expected)) return false;\n"
7734
+ " if (expected === Error && typeof actual === 'symbol') throw new TypeError('Cannot convert a Symbol value to a string');\n"
7735
+ " return Reflect.apply(expected, {}, [actual]) === true;\n"
7736
+ " }\n"
7737
+ " if (expected instanceof RegExp) return Reflect.apply(noErrorRegexExec, expected, [String(actual)]) !== null;\n"
7738
+ " envArgumentError('expected', 'of type function or an instance of RegExp', expected);\n"
7739
+ " };\n"
7740
+ " const noErrorFailure = (actual, expected, message, operator) => {\n"
7741
+ " if (typeof expected === 'string') { message = expected; expected = undefined; }\n"
7742
+ " if (!expected || noErrorMatches(actual, expected)) {\n"
7743
+ " const kind = operator === 'doesNotReject' ? 'rejection' : 'exception';\n"
7744
+ " throw new AssertionError({ actual, expected, operator,\n"
7745
+ " message: 'Got unwanted ' + kind + (message ? ': ' + message : '.') + '\\nActual message: \"' + actual?.message + '\"',\n"
7746
+ " });\n"
7747
+ " }\n"
7748
+ " throw actual;\n"
7749
+ " };\n"
7750
+ " const waitForNoError = async (input) => {\n"
7751
+ " const isPromise = (p) => env.isPromise(p) || (p !== null && typeof p === 'object' && typeof p.then === 'function' && typeof p.catch === 'function');\n"
7752
+ " let result;\n"
7753
+ " if (typeof input !== 'function') {\n"
7754
+ " if (!isPromise(input)) envArgumentError('promiseFn', 'of type function or an instance of Promise', input);\n"
7755
+ " result = input;\n"
7756
+ " } else {\n"
7757
+ " result = input();\n"
7758
+ " if (!isPromise(result)) {\n"
7759
+ " const error = new TypeError('Expected instance of Promise to be returned from the \\\"promiseFn\\\" function but got ' + envReceivedType(result) + '.');\n"
7760
+ " error.code = 'ERR_INVALID_RETURN_VALUE';\n"
7761
+ " throw error;\n"
7762
+ " }\n"
7763
+ " }\n"
7764
+ " try { await result; } catch (actual) { return { didFail: true, actual }; }\n"
7765
+ " return { didFail: false };\n"
7766
+ " };\n"
6741
7767
  " const assert = Object.assign(ok, {\n"
6742
7768
  " AssertionError,\n"
6743
7769
  " ok,\n"
@@ -6806,20 +7832,11 @@ static const char isl_modules_bootstrap[] =
6806
7832
  " }\n"
6807
7833
  " },\n"
6808
7834
  " doesNotThrow(fn, expected, message) {\n"
6809
- " if (typeof expected === \"string\") {\n"
6810
- " message = expected;\n"
6811
- " expected = undefined;\n"
6812
- " }\n"
7835
+ " if (typeof fn !== 'function') envArgumentError('fn', 'of type function', fn);\n"
6813
7836
  " try {\n"
6814
7837
  " fn();\n"
6815
7838
  " } catch (e) {\n"
6816
- " if (expected === undefined || checkExpected(e, expected, message, \"doesNotThrow\")) {\n"
6817
- " throw new AssertionError({\n"
6818
- " message: \"Got unwanted exception\" + (message ? \": \" + message : \".\") + \"\\nActual message: \\\"\" + (e && e.message) + \"\\\"\",\n"
6819
- " operator: \"doesNotThrow\",\n"
6820
- " });\n"
6821
- " }\n"
6822
- " throw e;\n"
7839
+ " noErrorFailure(e, expected, message, 'doesNotThrow');\n"
6823
7840
  " }\n"
6824
7841
  " },\n"
6825
7842
  " async rejects(promiseOrFn, expected, message) {\n"
@@ -6846,21 +7863,8 @@ static const char isl_modules_bootstrap[] =
6846
7863
  " }\n"
6847
7864
  " },\n"
6848
7865
  " async doesNotReject(promiseOrFn, expected, message) {\n"
6849
- " if (typeof expected === \"string\") {\n"
6850
- " message = expected;\n"
6851
- " expected = undefined;\n"
6852
- " }\n"
6853
- " try {\n"
6854
- " await (typeof promiseOrFn === \"function\" ? promiseOrFn() : promiseOrFn);\n"
6855
- " } catch (e) {\n"
6856
- " if (expected === undefined || checkExpected(e, expected, message, \"doesNotReject\")) {\n"
6857
- " throw new AssertionError({\n"
6858
- " message: \"Got unwanted rejection\" + (message ? \": \" + message : \".\") + \"\\nActual message: \\\"\" + (e && e.message) + \"\\\"\",\n"
6859
- " operator: \"doesNotReject\",\n"
6860
- " });\n"
6861
- " }\n"
6862
- " throw e;\n"
6863
- " }\n"
7866
+ " const result = await waitForNoError(promiseOrFn);\n"
7867
+ " if (result.didFail) noErrorFailure(result.actual, expected, message, 'doesNotReject');\n"
6864
7868
  " },\n"
6865
7869
  " match(string, regexp, message) {\n"
6866
7870
  " if (!(regexp instanceof RegExp)) {\n"
@@ -6927,7 +7931,7 @@ static const char isl_modules_bootstrap[] =
6927
7931
  " return assert;\n"
6928
7932
  "}\n"
6929
7933
  " const u = builtins.util();\n"
6930
- " const a = makeAssert({ isDeepStrictEqual: u.isDeepStrictEqual, inspect: u.inspect });\n"
7934
+ " const a = makeAssert({ isDeepStrictEqual: u.isDeepStrictEqual, inspect: u.inspect, isPromise: u.types.isPromise });\n"
6931
7935
  " a.default = a;\n"
6932
7936
  " return a;\n"
6933
7937
  " });\n"
@@ -6942,6 +7946,21 @@ static const char isl_modules_bootstrap[] =
6942
7946
  * isDeepStrictEqual, stripVTControlCharacters, styleText,
6943
7947
  * parseArgs, toUSVString). The host supplies what JS cannot see:
6944
7948
  * promise state (JS_PromiseState), the pid, and fd writes. */
7949
+ " const envReceivedType = (value) => {\n"
7950
+ " const type = typeof value;\n"
7951
+ " let received;\n"
7952
+ " if (value === null || value === undefined) received = String(value);\n"
7953
+ " else if (type === 'function') received = 'function ' + value.name;\n"
7954
+ " else if (type === 'object' && value.constructor && value.constructor.name) received = 'an instance of ' + value.constructor.name;\n"
7955
+ " else received = type === 'object' ? builtins.util().inspect(value, { depth: -1 }) : 'type ' + type + ' (' + builtins.util().inspect(value) + ')';\n"
7956
+ " return received;\n"
7957
+ " };\n"
7958
+ " const envArgumentError = (name, expected, value) => {\n"
7959
+ " const received = envReceivedType(value);\n"
7960
+ " const error = new TypeError('The \"' + name + '\" ' + (name.includes('.') ? 'property' : 'argument') + ' must be ' + expected + '. Received ' + received);\n"
7961
+ " error.code = 'ERR_INVALID_ARG_TYPE';\n"
7962
+ " throw error;\n"
7963
+ " };\n"
6945
7964
  " builtins.util = memo(() => {\n"
6946
7965
  "function makeUtil(env) {\n"
6947
7966
  " const inspectCustom = Symbol.for(\"nodejs.util.inspect.custom\");\n"
@@ -7337,7 +8356,7 @@ static const char isl_modules_bootstrap[] =
7337
8356
  " braces = [\"{\", \"}\"];\n"
7338
8357
  " formatter = () => [];\n"
7339
8358
  " } else {\n"
7340
- " if (depth > ctx.depth && ctx.depth !== null) {\n"
8359
+ " if (keys.length > 0 && depth > ctx.depth && ctx.depth !== null) {\n"
7341
8360
  " return \"[\" + (ctorName === null ? \"Object: null prototype\" : ctorName) + \"]\";\n"
7342
8361
  " }\n"
7343
8362
  " if (protoOf === null) {\n"
@@ -7527,21 +8546,33 @@ static const char isl_modules_bootstrap[] =
7527
8546
  " Object.defineProperty(ctor, \"super_\", { value: superCtor, writable: true, configurable: true });\n"
7528
8547
  " Object.setPrototypeOf(ctor.prototype, superCtor.prototype);\n"
7529
8548
  " };\n"
8549
+ " const received = (v) => {\n"
8550
+ " if (v === null || v === undefined) return String(v);\n"
8551
+ " if (typeof v === 'object') return v.constructor && 'name' in v.constructor ? 'an instance of ' + v.constructor.name : inspect(v, { depth: -1 });\n"
8552
+ " if (typeof v === 'function') return 'function ' + v.name;\n"
8553
+ " if (typeof v === 'string') {\n"
8554
+ " if (v.length > 28) v = v.slice(0, 25) + '...';\n"
8555
+ " return 'type string (' + (v.includes(\"'\") ? JSON.stringify(v) : \"'\" + v + \"'\") + ')';\n"
8556
+ " }\n"
8557
+ " if (typeof v === 'number') return 'type number (' + (Object.is(v, -0) ? '-0' : String(v)) + ')';\n"
8558
+ " if (typeof v === 'bigint') return 'type bigint (' + v + 'n)';\n"
8559
+ " if (typeof v === 'symbol') return 'type symbol (' + String(v) + ')';\n"
8560
+ " return 'type ' + typeof v + ' (' + String(v) + ')';\n"
8561
+ " };\n"
8562
+ " const validateAdapterFunction = (value, name) => {\n"
8563
+ " if (typeof value !== 'function') {\n"
8564
+ " const e = new TypeError('The ' + (name === 'last argument' ? name : '\"' + name + '\" ' + (name.includes('.') ? 'property' : 'argument')) + ' must be of type function. Received ' + received(value));\n"
8565
+ " e.code = 'ERR_INVALID_ARG_TYPE';\n"
8566
+ " throw e;\n"
8567
+ " }\n"
8568
+ " };\n"
7530
8569
  " const kCustomPromisified = Symbol.for(\"nodejs.util.promisify.custom\");\n"
7531
8570
  " const kCustomPromisifyArgs = Symbol(\"customPromisifyArgs\");\n"
7532
8571
  " const promisify = (original) => {\n"
7533
- " if (typeof original !== \"function\") {\n"
7534
- " const e = new TypeError('The \"original\" argument must be of type function. Received ' + (original === null ? \"null\" : typeof original === \"object\" ? \"an instance of Object\" : typeof original === \"undefined\" ? \"undefined\" : \"type \" + typeof original + \" (\" + JSON.stringify(original) + \")\"));\n"
7535
- " e.code = \"ERR_INVALID_ARG_TYPE\";\n"
7536
- " throw e;\n"
7537
- " }\n"
8572
+ " validateAdapterFunction(original, 'original');\n"
7538
8573
  " if (original[kCustomPromisified]) {\n"
7539
8574
  " const fn = original[kCustomPromisified];\n"
7540
- " if (typeof fn !== \"function\") {\n"
7541
- " const e = new TypeError('The \"util.promisify.custom\" property must be of type function');\n"
7542
- " e.code = \"ERR_INVALID_ARG_TYPE\";\n"
7543
- " throw e;\n"
7544
- " }\n"
8575
+ " validateAdapterFunction(fn, 'util.promisify.custom');\n"
7545
8576
  " return Object.defineProperty(fn, kCustomPromisified, { value: fn, enumerable: false, writable: false, configurable: true });\n"
7546
8577
  " }\n"
7547
8578
  " const argumentNames = original[kCustomPromisifyArgs];\n"
@@ -7563,30 +8594,21 @@ static const char isl_modules_bootstrap[] =
7563
8594
  " Object.setPrototypeOf(fn, Object.getPrototypeOf(original));\n"
7564
8595
  " Object.defineProperty(fn, kCustomPromisified, { value: fn, enumerable: false, writable: false, configurable: true });\n"
7565
8596
  " const descriptors = Object.getOwnPropertyDescriptors(original);\n"
7566
- " delete descriptors.name;\n"
7567
- " delete descriptors.length;\n"
8597
+ " for (const descriptor of Object.values(descriptors)) Object.setPrototypeOf(descriptor, null);\n"
7568
8598
  " return Object.defineProperties(fn, descriptors);\n"
7569
8599
  " };\n"
7570
8600
  " promisify.custom = kCustomPromisified;\n"
7571
8601
  " const callbackify = (original) => {\n"
7572
- " if (typeof original !== \"function\") {\n"
7573
- " const e = new TypeError('The \"original\" argument must be of type function');\n"
7574
- " e.code = \"ERR_INVALID_ARG_TYPE\";\n"
7575
- " throw e;\n"
7576
- " }\n"
8602
+ " validateAdapterFunction(original, 'original');\n"
7577
8603
  " function callbackified(...args) {\n"
7578
8604
  " const maybeCb = args.pop();\n"
7579
- " if (typeof maybeCb !== \"function\") {\n"
7580
- " const e = new TypeError(\"The last argument must be of type function\");\n"
7581
- " e.code = \"ERR_INVALID_ARG_TYPE\";\n"
7582
- " throw e;\n"
7583
- " }\n"
8605
+ " validateAdapterFunction(maybeCb, 'last argument');\n"
7584
8606
  " const cb = (...cbArgs) => Reflect.apply(maybeCb, this, cbArgs);\n"
7585
8607
  " Reflect.apply(original, this, args).then(\n"
7586
8608
  " (ret) => queueMicrotask(() => cb(null, ret)),\n"
7587
8609
  " (rej) => queueMicrotask(() => {\n"
7588
- " if (rej === null || (typeof rej !== \"object\" && typeof rej !== \"function\")) {\n"
7589
- " const wrapped = new Error(\"Promise was rejected with a falsy value\");\n"
8610
+ " if (!rej) {\n"
8611
+ " const wrapped = new Error(\"Promise was rejected with falsy value\");\n"
7590
8612
  " wrapped.code = \"ERR_FALSY_VALUE_REJECTION\";\n"
7591
8613
  " wrapped.reason = rej;\n"
7592
8614
  " return cb(wrapped);\n"
@@ -7595,8 +8617,10 @@ static const char isl_modules_bootstrap[] =
7595
8617
  " }),\n"
7596
8618
  " );\n"
7597
8619
  " }\n"
7598
- " Object.setPrototypeOf(callbackified, Object.getPrototypeOf(original));\n"
7599
8620
  " const descriptors = Object.getOwnPropertyDescriptors(original);\n"
8621
+ " if (typeof descriptors.length.value === 'number') descriptors.length.value++;\n"
8622
+ " if (typeof descriptors.name.value === 'string') descriptors.name.value += 'Callbackified';\n"
8623
+ " for (const descriptor of Object.values(descriptors)) Object.setPrototypeOf(descriptor, null);\n"
7600
8624
  " Object.defineProperties(callbackified, descriptors);\n"
7601
8625
  " return callbackified;\n"
7602
8626
  " };\n"
@@ -7642,390 +8666,613 @@ static const char isl_modules_bootstrap[] =
7642
8666
  " return fn;\n"
7643
8667
  " };\n"
7644
8668
  " const tagOf = (v) => Object.prototype.toString.call(v).slice(8, -1);\n"
7645
- " const taggedTest = (tag) => (v) => tagOf(v) === tag && typeof v === \"object\";\n"
7646
8669
  " const taTagGetter = Object.getOwnPropertyDescriptor(\n"
7647
8670
  " Object.getPrototypeOf(Object.getPrototypeOf(new Uint8Array(0))), Symbol.toStringTag).get;\n"
7648
- " const brandTA = (v) => {\n"
7649
- " try {\n"
7650
- " return taTagGetter.call(v) !== undefined;\n"
7651
- " } catch (e) {\n"
7652
- " return false;\n"
7653
- " }\n"
7654
- " };\n"
7655
8671
  " const types = {\n"
7656
- " isAnyArrayBuffer: (v) => tagOf(v) === \"ArrayBuffer\" || tagOf(v) === \"SharedArrayBuffer\",\n"
7657
- " isArrayBufferView: (v) => ArrayBuffer.isView(v),\n"
7658
- " isArgumentsObject: taggedTest(\"Arguments\"),\n"
7659
- " isArrayBuffer: (v) => {\n"
7660
- " try { Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, \"byteLength\").get.call(v); return true; }\n"
7661
- " catch (e) { return false; }\n"
7662
- " },\n"
7663
- " isAsyncFunction: (v) => typeof v === \"function\" && tagOf(v) === \"AsyncFunction\",\n"
7664
- " isBigInt64Array: (v) => tagOf(v) === \"BigInt64Array\",\n"
7665
- " isBigUint64Array: (v) => tagOf(v) === \"BigUint64Array\",\n"
7666
- " isBooleanObject: (v) => {\n"
7667
- " try { Boolean.prototype.valueOf.call(v); return typeof v === \"object\"; }\n"
7668
- " catch (e) { return false; }\n"
7669
- " },\n"
7670
- " isBoxedPrimitive: (v) =>\n"
7671
- " types.isStringObject(v) || types.isNumberObject(v) || types.isBooleanObject(v) ||\n"
7672
- " types.isSymbolObject(v) || types.isBigIntObject(v),\n"
7673
- " isBigIntObject: (v) => {\n"
7674
- " try { BigInt.prototype.valueOf.call(v); return typeof v === \"object\"; }\n"
7675
- " catch (e) { return false; }\n"
7676
- " },\n"
7677
- " isCryptoKey: () => false,\n"
7678
- " isDataView: (v) => {\n"
7679
- " try { Object.getOwnPropertyDescriptor(DataView.prototype, \"byteLength\").get.call(v); return true; }\n"
7680
- " catch (e) { return false; }\n"
7681
- " },\n"
7682
- " isDate: (v) => {\n"
7683
- " try { Date.prototype.getTime.call(v); return true; }\n"
7684
- " catch (e) { return false; }\n"
7685
- " },\n"
7686
- " isExternal: () => false,\n"
7687
- " isFloat16Array: (v) => tagOf(v) === \"Float16Array\",\n"
7688
- " isFloat32Array: (v) => tagOf(v) === \"Float32Array\",\n"
7689
- " isFloat64Array: (v) => tagOf(v) === \"Float64Array\",\n"
7690
- " isGeneratorFunction: (v) => typeof v === \"function\" && tagOf(v) === \"GeneratorFunction\",\n"
7691
- " isGeneratorObject: (v) => typeof v === \"object\" && v !== null && tagOf(v) === \"Generator\",\n"
7692
- " isInt8Array: (v) => tagOf(v) === \"Int8Array\",\n"
7693
- " isInt16Array: (v) => tagOf(v) === \"Int16Array\",\n"
7694
- " isInt32Array: (v) => tagOf(v) === \"Int32Array\",\n"
7695
- " isKeyObject: () => false,\n"
7696
- " isMap: (v) => {\n"
7697
- " try { Object.getOwnPropertyDescriptor(Map.prototype, \"size\").get.call(v); return true; }\n"
7698
- " catch (e) { return false; }\n"
7699
- " },\n"
7700
- " isMapIterator: (v) => tagOf(v) === \"Map Iterator\",\n"
7701
- " isModuleNamespaceObject: (v) => typeof v === \"object\" && v !== null && tagOf(v) === \"Module\",\n"
7702
- " isNativeError: (v) => v instanceof Error && (\n"
7703
- " [\"Error\", \"EvalError\", \"RangeError\", \"ReferenceError\", \"SyntaxError\", \"TypeError\", \"URIError\", \"AggregateError\", \"SuppressedError\"].includes(tagOf(v))\n"
7704
- " ),\n"
7705
- " isNumberObject: (v) => {\n"
7706
- " try { Number.prototype.valueOf.call(v); return typeof v === \"object\"; }\n"
7707
- " catch (e) { return false; }\n"
7708
- " },\n"
7709
- " isPromise: (v) => v instanceof Promise,\n"
7710
- " isProxy: () => false,\n"
7711
- " isRegExp: (v) => tagOf(v) === \"RegExp\",\n"
7712
- " isSet: (v) => {\n"
7713
- " try { Object.getOwnPropertyDescriptor(Set.prototype, \"size\").get.call(v); return true; }\n"
7714
- " catch (e) { return false; }\n"
7715
- " },\n"
7716
- " isSetIterator: (v) => tagOf(v) === \"Set Iterator\",\n"
7717
- " isSharedArrayBuffer: (v) => tagOf(v) === \"SharedArrayBuffer\",\n"
7718
- " isStringObject: (v) => {\n"
7719
- " try { String.prototype.valueOf.call(v); return typeof v === \"object\"; }\n"
7720
- " catch (e) { return false; }\n"
7721
- " },\n"
7722
- " isSymbolObject: (v) => {\n"
7723
- " try { Symbol.prototype.valueOf.call(v); return typeof v === \"object\"; }\n"
7724
- " catch (e) { return false; }\n"
7725
- " },\n"
7726
- " isTypedArray: brandTA,\n"
7727
- " isUint8Array: (v) => tagOf(v) === \"Uint8Array\",\n"
7728
- " isUint8ClampedArray: (v) => tagOf(v) === \"Uint8ClampedArray\",\n"
7729
- " isUint16Array: (v) => tagOf(v) === \"Uint16Array\",\n"
7730
- " isUint32Array: (v) => tagOf(v) === \"Uint32Array\",\n"
7731
- " isWeakMap: (v) => {\n"
7732
- " try { WeakMap.prototype.has.call(v, {}); return true; }\n"
7733
- " catch (e) { return false; }\n"
7734
- " },\n"
7735
- " isWeakSet: (v) => {\n"
7736
- " try { WeakSet.prototype.has.call(v, {}); return true; }\n"
7737
- " catch (e) { return false; }\n"
7738
- " },\n"
8672
+ " isAnyArrayBuffer: (v) => env.typeProbe(\"isAnyArrayBuffer\", v),\n"
8673
+ " isArrayBufferView: (v) => env.typeProbe(\"isArrayBufferView\", v),\n"
8674
+ " isArgumentsObject: (v) => env.typeProbe(\"isArgumentsObject\", v),\n"
8675
+ " isArrayBuffer: (v) => env.typeProbe(\"isArrayBuffer\", v),\n"
8676
+ " isAsyncFunction: (v) => env.typeProbe(\"isAsyncFunction\", v),\n"
8677
+ " isBigInt64Array: (v) => env.typeProbe(\"isBigInt64Array\", v),\n"
8678
+ " isBigUint64Array: (v) => env.typeProbe(\"isBigUint64Array\", v),\n"
8679
+ " isBooleanObject: (v) => env.typeProbe(\"isBooleanObject\", v),\n"
8680
+ " isBoxedPrimitive: (v) => env.typeProbe(\"isBoxedPrimitive\", v),\n"
8681
+ " isBigIntObject: (v) => env.typeProbe(\"isBigIntObject\", v),\n"
8682
+ " isCryptoKey: (v) => env.typeProbe(\"isCryptoKey\", v),\n"
8683
+ " isDataView: (v) => env.typeProbe(\"isDataView\", v),\n"
8684
+ " isDate: (v) => env.typeProbe(\"isDate\", v),\n"
8685
+ " isExternal: (v) => env.typeProbe(\"isExternal\", v),\n"
8686
+ " isFloat16Array: (v) => env.typeProbe(\"isFloat16Array\", v),\n"
8687
+ " isFloat32Array: (v) => env.typeProbe(\"isFloat32Array\", v),\n"
8688
+ " isFloat64Array: (v) => env.typeProbe(\"isFloat64Array\", v),\n"
8689
+ " isGeneratorFunction: (v) => env.typeProbe(\"isGeneratorFunction\", v),\n"
8690
+ " isGeneratorObject: (v) => env.typeProbe(\"isGeneratorObject\", v),\n"
8691
+ " isInt8Array: (v) => env.typeProbe(\"isInt8Array\", v),\n"
8692
+ " isInt16Array: (v) => env.typeProbe(\"isInt16Array\", v),\n"
8693
+ " isInt32Array: (v) => env.typeProbe(\"isInt32Array\", v),\n"
8694
+ " isKeyObject: (v) => env.typeProbe(\"isKeyObject\", v),\n"
8695
+ " isMap: (v) => env.typeProbe(\"isMap\", v),\n"
8696
+ " isMapIterator: (v) => env.typeProbe(\"isMapIterator\", v),\n"
8697
+ " isModuleNamespaceObject: (v) => env.typeProbe(\"isModuleNamespaceObject\", v),\n"
8698
+ " isNativeError: (v) => env.typeProbe(\"isNativeError\", v),\n"
8699
+ " isNumberObject: (v) => env.typeProbe(\"isNumberObject\", v),\n"
8700
+ " isPromise: (v) => env.typeProbe(\"isPromise\", v),\n"
8701
+ " isProxy: (v) => env.typeProbe(\"isProxy\", v),\n"
8702
+ " isRegExp: (v) => env.typeProbe(\"isRegExp\", v),\n"
8703
+ " isSet: (v) => env.typeProbe(\"isSet\", v),\n"
8704
+ " isSetIterator: (v) => env.typeProbe(\"isSetIterator\", v),\n"
8705
+ " isSharedArrayBuffer: (v) => env.typeProbe(\"isSharedArrayBuffer\", v),\n"
8706
+ " isStringObject: (v) => env.typeProbe(\"isStringObject\", v),\n"
8707
+ " isSymbolObject: (v) => env.typeProbe(\"isSymbolObject\", v),\n"
8708
+ " isTypedArray: (v) => env.typeProbe(\"isTypedArray\", v),\n"
8709
+ " isUint8Array: (v) => env.typeProbe(\"isUint8Array\", v),\n"
8710
+ " isUint8ClampedArray: (v) => env.typeProbe(\"isUint8ClampedArray\", v),\n"
8711
+ " isUint16Array: (v) => env.typeProbe(\"isUint16Array\", v),\n"
8712
+ " isUint32Array: (v) => env.typeProbe(\"isUint32Array\", v),\n"
8713
+ " isWeakMap: (v) => env.typeProbe(\"isWeakMap\", v),\n"
8714
+ " isWeakSet: (v) => env.typeProbe(\"isWeakSet\", v),\n"
7739
8715
  " };\n"
7740
- " const deepEquals = (a, b, memos) => {\n"
8716
+ " for (const [name, probe] of Object.entries(types)) {\n"
8717
+ " const wrapper = name === \"isTypedArray\" || /Array$/.test(name) && name !== \"isAnyArrayBuffer\" && name !== \"isArrayBuffer\";\n"
8718
+ " if (!wrapper && name !== \"isArrayBufferView\" && name !== \"isCryptoKey\" && name !== \"isKeyObject\") {\n"
8719
+ " Object.defineProperty(probe, \"name\", { value: \"\", configurable: true });\n"
8720
+ " Object.defineProperty(probe, \"length\", { value: 0, configurable: true });\n"
8721
+ " }\n"
8722
+ " }\n"
8723
+ " types.isArrayBufferView = ArrayBuffer.isView;\n"
8724
+ " Object.defineProperty(types.isCryptoKey, \"name\", { value: \"value\", configurable: true });\n"
8725
+ " Object.defineProperty(types.isKeyObject, \"name\", { value: \"value\", configurable: true });\n"
8726
+ " const deepConstructors = new Set([Array, ArrayBuffer, BigInt, Boolean, DataView, Date, Error, Function,\n"
8727
+ " Map, Number, Object, Promise, RegExp, Set, String, Symbol, WeakMap, WeakSet, Uint8Array,\n"
8728
+ " Uint8ClampedArray, Uint16Array, Uint32Array, Int8Array, Int16Array, Int32Array, Float32Array,\n"
8729
+ " Float64Array, BigInt64Array, BigUint64Array, Buffer]);\n"
8730
+ " if (typeof Float16Array !== \"undefined\") deepConstructors.add(Float16Array);\n"
8731
+ " const deepEquals = (a, b, skipPrototype, memos) => {\n"
7741
8732
  " if (Object.is(a, b)) return true;\n"
7742
- " const ta = typeof a;\n"
7743
- " const tb = typeof b;\n"
7744
- " if (ta !== tb) return false;\n"
7745
- " if (ta === \"number\") return Number.isNaN(a) && Number.isNaN(b);\n"
7746
- " if (ta !== \"object\" && ta !== \"function\") return false;\n"
7747
- " if (a === null || b === null) return false;\n"
7748
- " const tagA = tagOf(a);\n"
7749
- " if (tagA !== tagOf(b)) return false;\n"
7750
- " if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) return false;\n"
7751
- " if (tagA === \"Date\") return Object.is(Date.prototype.getTime.call(a), Date.prototype.getTime.call(b));\n"
7752
- " if (tagA === \"RegExp\") return String(a) === String(b);\n"
7753
- " if (Array.isArray(a) && a.length !== b.length) return false;\n"
7754
- " if (types.isTypedArray(a)) {\n"
7755
- " if (a.length !== b.length) return false;\n"
7756
- " if (tagA === \"Float32Array\" || tagA === \"Float64Array\" || tagA === \"Float16Array\") {\n"
7757
- " for (let i = 0; i < a.length; i++) if (!Object.is(a[i], b[i])) return false;\n"
7758
- " } else {\n"
7759
- " for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n"
7760
- " }\n"
7761
- " return true;\n"
8733
+ " if (typeof a !== \"object\" || a === null || typeof b !== \"object\" || b === null) return false;\n"
8734
+ " if (!skipPrototype) {\n"
8735
+ " if (deepConstructors.has(a.constructor) ||\n"
8736
+ " (a.constructor !== undefined && !Object.prototype.hasOwnProperty.call(a, \"constructor\"))) {\n"
8737
+ " if (a.constructor !== b.constructor) return false;\n"
8738
+ " } else if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) return false;\n"
8739
+ " }\n"
8740
+ " const array = Array.isArray(a);\n"
8741
+ " const view = ArrayBuffer.isView(a);\n"
8742
+ " const map = types.isMap(a);\n"
8743
+ " const set = types.isSet(a);\n"
8744
+ " const date = types.isDate(a);\n"
8745
+ " const regexp = types.isRegExp(a);\n"
8746
+ " const buffer = types.isAnyArrayBuffer(a);\n"
8747
+ " if (array !== Array.isArray(b) || view !== ArrayBuffer.isView(b) ||\n"
8748
+ " map !== types.isMap(b) || set !== types.isSet(b) || date !== types.isDate(b) ||\n"
8749
+ " regexp !== types.isRegExp(b) || buffer !== types.isAnyArrayBuffer(b)) return false;\n"
8750
+ " if (!view && tagOf(a) !== tagOf(b)) return false;\n"
8751
+ " if (array && a.length !== b.length) return false;\n"
8752
+ " if (view) {\n"
8753
+ " if (taTagGetter.call(a) !== taTagGetter.call(b) || a.byteLength !== b.byteLength) return false;\n"
8754
+ " const ua = new Uint8Array(a.buffer, a.byteOffset, a.byteLength);\n"
8755
+ " const ub = new Uint8Array(b.buffer, b.byteOffset, b.byteLength);\n"
8756
+ " for (let i = 0; i < ua.length; i++) if (ua[i] !== ub[i]) return false;\n"
7762
8757
  " }\n"
7763
- " if (tagA === \"ArrayBuffer\") {\n"
8758
+ " if (buffer) {\n"
8759
+ " if (a.byteLength !== b.byteLength) return false;\n"
7764
8760
  " const ua = new Uint8Array(a);\n"
7765
8761
  " const ub = new Uint8Array(b);\n"
7766
- " if (ua.length !== ub.length) return false;\n"
7767
8762
  " for (let i = 0; i < ua.length; i++) if (ua[i] !== ub[i]) return false;\n"
7768
- " return true;\n"
7769
8763
  " }\n"
7770
- " if (a instanceof Error && (a.message !== b.message || a.name !== b.name)) return false;\n"
7771
- " if (types.isBoxedPrimitive(a)) {\n"
7772
- " return Object.is(\n"
7773
- " (tagA === \"String\" ? String.prototype.valueOf : tagA === \"Number\" ? Number.prototype.valueOf\n"
7774
- " : tagA === \"Boolean\" ? Boolean.prototype.valueOf : tagA === \"BigInt\" ? BigInt.prototype.valueOf\n"
7775
- " : Symbol.prototype.valueOf).call(a),\n"
7776
- " (tagA === \"String\" ? String.prototype.valueOf : tagA === \"Number\" ? Number.prototype.valueOf\n"
7777
- " : tagA === \"Boolean\" ? Boolean.prototype.valueOf : tagA === \"BigInt\" ? BigInt.prototype.valueOf\n"
7778
- " : Symbol.prototype.valueOf).call(b));\n"
7779
- " }\n"
7780
- " memos = memos || { a: new Map(), b: new Map(), position: 0 };\n"
7781
- " const memoA = memos.a.get(a);\n"
7782
- " if (memoA !== undefined) {\n"
7783
- " const memoB = memos.b.get(b);\n"
7784
- " if (memoB !== undefined) return memoA === memoB;\n"
7785
- " }\n"
7786
- " memos.position++;\n"
7787
- " memos.a.set(a, memos.position);\n"
7788
- " memos.b.set(b, memos.position);\n"
8764
+ " if (date && !Object.is(Date.prototype.getTime.call(a), Date.prototype.getTime.call(b))) return false;\n"
8765
+ " if (regexp && (a.source !== b.source || a.flags !== b.flags || a.lastIndex !== b.lastIndex)) return false;\n"
8766
+ " if (types.isPromise(a) || types.isPromise(b) || types.isWeakMap(a) || types.isWeakMap(b) ||\n"
8767
+ " types.isWeakSet(a) || types.isWeakSet(b)) return false;\n"
8768
+ " const boxed = types.isBoxedPrimitive(a);\n"
8769
+ " if (boxed !== types.isBoxedPrimitive(b)) return false;\n"
8770
+ " if (boxed) {\n"
8771
+ " const unbox = (v) => (types.isStringObject(v) ? String.prototype.valueOf :\n"
8772
+ " types.isNumberObject(v) ? Number.prototype.valueOf : types.isBooleanObject(v) ? Boolean.prototype.valueOf :\n"
8773
+ " types.isBigIntObject(v) ? BigInt.prototype.valueOf : Symbol.prototype.valueOf).call(v);\n"
8774
+ " if (!Object.is(unbox(a), unbox(b))) return false;\n"
8775
+ " }\n"
8776
+ " const error = a instanceof Error;\n"
8777
+ " if (error !== (b instanceof Error)) return false;\n"
8778
+ " if (typeof URL !== \"undefined\" && (a instanceof URL || b instanceof URL)) {\n"
8779
+ " if (!(a instanceof URL && b instanceof URL) || a.href !== b.href) return false;\n"
8780
+ " }\n"
8781
+ " const enumerable = (v, k) => Object.prototype.propertyIsEnumerable.call(v, k);\n"
8782
+ " // Typed view elements were compared by bytes. Object.is on float elements\n"
8783
+ " // would erase distinct NaN payloads that Node's strict comparison preserves.\n"
8784
+ " const keys = (v) => Reflect.ownKeys(v).filter((k) => enumerable(v, k) &&\n"
8785
+ " !((array || view) && typeof k === \"string\" && String(k >>> 0) === k && k !== \"4294967295\"));\n"
8786
+ " const keysA = keys(a);\n"
8787
+ " const keysB = keys(b);\n"
8788
+ " if (keysA.length !== keysB.length || keysA.some((k) => !enumerable(b, k))) return false;\n"
8789
+ " if (map || set) {\n"
8790
+ " if (a.size !== b.size) return false;\n"
8791
+ " }\n"
8792
+ " // Node 24's pair fast path for the first ancestor, then ancestor-set\n"
8793
+ " // matching at greater depth. Keep this state local to each traversal path.\n"
8794
+ " memos = memos || [];\n"
8795
+ " if (memos.length === 1) {\n"
8796
+ " if (memos[0][0] === a) return memos[0][1] === b;\n"
8797
+ " if (memos[0][1] === b) return false;\n"
8798
+ " } else if (memos.length > 1) {\n"
8799
+ " const seenA = memos.some((p) => p[0] === a || p[1] === a);\n"
8800
+ " const seenB = memos.some((p) => p[0] === b || p[1] === b);\n"
8801
+ " if (seenA || seenB) return seenA && seenB;\n"
8802
+ " }\n"
8803
+ " memos.push([a, b]);\n"
7789
8804
  " try {\n"
7790
- " if (tagA === \"Map\") {\n"
7791
- " if (a.size !== b.size) return false;\n"
7792
- " outer: for (const [k, v] of a) {\n"
7793
- " if (b.has(k)) {\n"
7794
- " if (deepEquals(v, b.get(k), memos)) continue;\n"
7795
- " }\n"
7796
- " for (const [k2, v2] of b) {\n"
7797
- " if (deepEquals(k, k2, memos) && deepEquals(v, v2, memos)) continue outer;\n"
7798
- " }\n"
7799
- " return false;\n"
8805
+ " if (error) {\n"
8806
+ " for (const k of [\"name\", \"message\", \"cause\", \"errors\"]) {\n"
8807
+ " if (!enumerable(b, k) && !deepEquals(a[k], b[k], skipPrototype, memos)) return false;\n"
7800
8808
  " }\n"
7801
- " return true;\n"
7802
- " }\n"
7803
- " if (tagA === \"Set\") {\n"
7804
- " if (a.size !== b.size) return false;\n"
7805
- " outer2: for (const v of a) {\n"
7806
- " if (b.has(v)) continue;\n"
7807
- " for (const v2 of b) {\n"
7808
- " if (deepEquals(v, v2, memos)) continue outer2;\n"
7809
- " }\n"
7810
- " return false;\n"
8809
+ " if (Object.prototype.hasOwnProperty.call(a, \"cause\") !== Object.prototype.hasOwnProperty.call(b, \"cause\")) return false;\n"
8810
+ " }\n"
8811
+ " let ordered = true;\n"
8812
+ " for (let i = 0; i < keysB.length; i++) {\n"
8813
+ " const k = keysB[i];\n"
8814
+ " ordered = ordered && keysA[i] === k;\n"
8815
+ " const descriptor = !ordered ? Object.getOwnPropertyDescriptor(a, k) : undefined;\n"
8816
+ " if (!ordered && (!descriptor || !descriptor.enumerable)) return false;\n"
8817
+ " const value = descriptor && descriptor.writable !== undefined ? descriptor.value : a[k];\n"
8818
+ " if (!deepEquals(value, b[k], skipPrototype, memos)) return false;\n"
8819
+ " }\n"
8820
+ " if (array) {\n"
8821
+ " for (let i = 0; i < a.length; i++) {\n"
8822
+ " if (b[i] === undefined) {\n"
8823
+ " if (!Object.prototype.hasOwnProperty.call(b, i)) {\n"
8824
+ " const indicesA = Object.keys(a);\n"
8825
+ " const indicesB = Object.keys(b);\n"
8826
+ " if (indicesA.length !== indicesB.length) return false;\n"
8827
+ " for (; i < indicesB.length; i++) {\n"
8828
+ " const k = indicesB[i];\n"
8829
+ " if ((a[k] === undefined && !Object.prototype.hasOwnProperty.call(a, k)) ||\n"
8830
+ " !deepEquals(a[k], b[k], skipPrototype, memos)) return false;\n"
8831
+ " }\n"
8832
+ " return true;\n"
8833
+ " }\n"
8834
+ " if (a[i] !== undefined || !Object.prototype.hasOwnProperty.call(a, i)) return false;\n"
8835
+ " } else if (a[i] === undefined || !deepEquals(a[i], b[i], skipPrototype, memos)) return false;\n"
7811
8836
  " }\n"
7812
- " return true;\n"
7813
- " }\n"
7814
- " const keysA = Object.keys(a);\n"
7815
- " const keysB = Object.keys(b);\n"
7816
- " if (keysA.length !== keysB.length) return false;\n"
7817
- " for (const k of keysA) {\n"
7818
- " if (!Object.prototype.propertyIsEnumerable.call(b, k)) return false;\n"
7819
- " if (!deepEquals(a[k], b[k], memos)) return false;\n"
7820
8837
  " }\n"
7821
- " const symsA = Object.getOwnPropertySymbols(a).filter((s) => Object.prototype.propertyIsEnumerable.call(a, s));\n"
7822
- " const symsB = Object.getOwnPropertySymbols(b).filter((s) => Object.prototype.propertyIsEnumerable.call(b, s));\n"
7823
- " if (symsA.length !== symsB.length) return false;\n"
7824
- " for (const s of symsA) {\n"
7825
- " if (!Object.prototype.propertyIsEnumerable.call(b, s)) return false;\n"
7826
- " if (!deepEquals(a[s], b[s], memos)) return false;\n"
8838
+ " if (map || set) {\n"
8839
+ " const remaining = map ? Array.from(b.entries()) : Array.from(b.values());\n"
8840
+ " for (const item of a) {\n"
8841
+ " const index = remaining.findIndex((other) => map\n"
8842
+ " ? deepEquals(item[0], other[0], skipPrototype, memos) && deepEquals(item[1], other[1], skipPrototype, memos)\n"
8843
+ " : deepEquals(item, other, skipPrototype, memos));\n"
8844
+ " if (index === -1) return false;\n"
8845
+ " remaining.splice(index, 1);\n"
8846
+ " }\n"
7827
8847
  " }\n"
7828
8848
  " return true;\n"
7829
8849
  " } finally {\n"
7830
- " memos.a.delete(a);\n"
7831
- " memos.b.delete(b);\n"
8850
+ " memos.pop();\n"
7832
8851
  " }\n"
7833
8852
  " };\n"
7834
- " const isDeepStrictEqual = (a, b) => deepEquals(a, b, undefined);\n"
7835
- " const ansiRe = /[\\u001b›][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/\\\\#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/\\\\#&.:=?%@~_]*)*)?(?:|\\u001b\\|œ))|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))/g;\n"
8853
+ " const isDeepStrictEqual = (a, b, skipPrototype) => deepEquals(a, b, !!skipPrototype, undefined);\n"
8854
+ " const ansiRe = /[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/\\#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/\\#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))/g;\n"
7836
8855
  " const stripVTControlCharacters = (str) => {\n"
7837
- " if (typeof str !== \"string\") {\n"
7838
- " const e = new TypeError('The \"str\" argument must be of type string. Received ' + (str === null ? \"null\" : typeof str === \"object\" ? \"an instance of Object\" : typeof str === \"undefined\" ? \"undefined\" : \"type \" + typeof str));\n"
7839
- " e.code = \"ERR_INVALID_ARG_TYPE\";\n"
7840
- " throw e;\n"
7841
- " }\n"
8856
+ " if (typeof str !== \"string\") envArgumentError(\"str\", \"of type string\", str);\n"
7842
8857
  " return str.replace(ansiRe, \"\");\n"
7843
8858
  " };\n"
7844
- " const styleText = (fmt, text, options) => {\n"
7845
- " if (typeof text !== \"string\") {\n"
7846
- " const e = new TypeError('The \"text\" argument must be of type string. Received ' + (text === null ? \"null\" : typeof text === \"object\" ? \"an instance of Object\" : typeof text === \"undefined\" ? \"undefined\" : \"type \" + typeof text));\n"
7847
- " e.code = \"ERR_INVALID_ARG_TYPE\";\n"
7848
- " throw e;\n"
7849
- " }\n"
7850
- " const stream = options !== undefined && options !== null && options.stream !== undefined\n"
7851
- " ? options.stream : env.stdout;\n"
7852
- " let colorize = !!(stream && stream.isTTY);\n"
7853
- " if (env.env.NO_COLOR !== undefined || env.env.NODE_DISABLE_COLORS !== undefined) colorize = false;\n"
7854
- " if (env.env.FORCE_COLOR !== undefined && env.env.FORCE_COLOR !== \"0\") colorize = true;\n"
7855
- " const formats = Array.isArray(fmt) ? fmt : [fmt];\n"
7856
- " let left = \"\";\n"
7857
- " let right = \"\";\n"
7858
- " for (const f of formats) {\n"
7859
- " const pair = inspect.colors[f];\n"
7860
- " if (pair === undefined) {\n"
7861
- " const e = new TypeError(\"The value \\\"\" + String(f) + \"\\\" is invalid for argument 'format'. Reason: must be one of: \" + Object.keys(inspect.colors).join(\", \"));\n"
7862
- " e.code = \"ERR_INVALID_ARG_VALUE\";\n"
7863
- " throw e;\n"
8859
+ " const styleAliases = { grey: 'gray', blackBright: 'gray', bgGrey: 'bgGray', bgBlackBright: 'bgGray', faint: 'dim', crossedout: 'strikethrough', strikeThrough: 'strikethrough', crossedOut: 'strikethrough', conceal: 'hidden', swapColors: 'inverse', swapcolors: 'inverse', doubleUnderline: 'doubleunderline' };\n"
8860
+ " for (const [name, target] of Object.entries(styleAliases)) Object.defineProperty(inspect.colors, name, {\n"
8861
+ " configurable: true, get: () => inspect.colors[target], set: (value) => { inspect.colors[target] = value; },\n"
8862
+ " });\n"
8863
+ " let styleCache;\n"
8864
+ " const getStyleCache = () => {\n"
8865
+ " if (styleCache === undefined) {\n"
8866
+ " styleCache = Object.create(null);\n"
8867
+ " for (const key of Object.getOwnPropertyNames(inspect.colors)) {\n"
8868
+ " const pair = inspect.colors[key];\n"
8869
+ " if (!pair) continue;\n"
8870
+ " styleCache[key] = { open: '\\u001b[' + pair[0] + 'm', close: '\\u001b[' + pair[1] + 'm', keepClose: pair[0] === 1 || pair[0] === 2 };\n"
7864
8871
  " }\n"
7865
- " left += \"\\u001b[\" + pair[0] + \"m\";\n"
7866
- " right = \"\\u001b[\" + pair[1] + \"m\" + right;\n"
7867
8872
  " }\n"
7868
- " return colorize ? left + text + right : text;\n"
8873
+ " return styleCache;\n"
7869
8874
  " };\n"
7870
- " const parseArgs = (config) => {\n"
7871
- " config = config === undefined ? {} : config;\n"
7872
- " const args = config.args !== undefined ? config.args : env.argv.slice(2);\n"
7873
- " const strict = config.strict !== undefined ? !!config.strict : true;\n"
7874
- " const allowPositionals = config.allowPositionals !== undefined ? !!config.allowPositionals : !strict;\n"
7875
- " const allowNegative = !!config.allowNegative;\n"
7876
- " const returnTokens = !!config.tokens;\n"
7877
- " const options = config.options !== undefined ? config.options : {};\n"
7878
- " const result = { values: { __proto__: null }, positionals: [] };\n"
7879
- " const tokens = [];\n"
7880
- " const shortOf = (ch) => {\n"
7881
- " for (const name of Object.keys(options)) {\n"
7882
- " if (options[name].short === ch) return name;\n"
7883
- " }\n"
7884
- " return undefined;\n"
7885
- " };\n"
7886
- " const unknownError = (raw) => {\n"
7887
- " const e = new TypeError(\"Unknown option '\" + raw + \"'. To specify a positional argument starting with a '-', place it at the end of the command after '--', as in '-- \\\"\" + raw + \"\\\"\");\n"
7888
- " e.code = \"ERR_PARSE_ARGS_UNKNOWN_OPTION\";\n"
7889
- " throw e;\n"
8875
+ " const replaceCloseCode = (text, style) => {\n"
8876
+ " let at = 0, index = text.indexOf(style.close), result = '';\n"
8877
+ " while (index !== -1 && index + style.close.length < text.length) {\n"
8878
+ " result += text.slice(at, index) + (style.keepClose ? style.close : '') + style.open;\n"
8879
+ " at = index + style.close.length;\n"
8880
+ " index = text.indexOf(style.close, at);\n"
8881
+ " }\n"
8882
+ " return result + text.slice(at);\n"
8883
+ " };\n"
8884
+ " let warnedColors = false;\n"
8885
+ " const terminalColors = () => {\n"
8886
+ " const e = env.env, force = e.FORCE_COLOR;\n"
8887
+ " if (force !== undefined) {\n"
8888
+ " const enabled = ['', '1', '2', '3', 'true'].includes(force);\n"
8889
+ " const disabled = e.NO_COLOR ? 'NO_COLOR' : e.NODE_DISABLE_COLORS ? 'NODE_DISABLE_COLORS' : undefined;\n"
8890
+ " if (enabled && disabled && !warnedColors) {\n"
8891
+ " env.emitWarning(\"The '\" + disabled + \"' env is ignored due to the 'FORCE_COLOR' env being set.\", 'Warning');\n"
8892
+ " warnedColors = true;\n"
8893
+ " }\n"
8894
+ " return enabled;\n"
8895
+ " }\n"
8896
+ " if (e.NO_COLOR || e.NODE_DISABLE_COLORS || e.TERM === 'dumb') return false;\n"
8897
+ " if (env.platform === 'win32' || e.TMUX || e.TF_BUILD !== undefined && e.AGENT_NAME !== undefined) return true;\n"
8898
+ " if (e.CI !== undefined) return ['APPVEYOR', 'BUILDKITE', 'CIRCLECI', 'DRONE', 'GITEA_ACTIONS', 'GITHUB_ACTIONS', 'GITLAB_CI', 'TRAVIS'].some((name) => e[name] !== undefined) || e.CI_NAME === 'codeship';\n"
8899
+ " if (e.TEAMCITY_VERSION !== undefined) return /^(9\\.(0*[1-9]\\d*)\\.|\\d{2,}\\.)/.test(e.TEAMCITY_VERSION);\n"
8900
+ " if (['iTerm.app', 'HyperTerm', 'MacTerm', 'Apple_Terminal'].includes(e.TERM_PROGRAM)) return true;\n"
8901
+ " if (e.COLORTERM === 'truecolor' || e.COLORTERM === '24bit') return true;\n"
8902
+ " if (e.TERM) {\n"
8903
+ " if (e.TERM.includes('truecolor') || e.TERM.startsWith('xterm-256')) return true;\n"
8904
+ " const term = e.TERM.toLowerCase();\n"
8905
+ " if (['eterm', 'cons25', 'console', 'cygwin', 'dtterm', 'gnome', 'hurd', 'jfbterm', 'konsole', 'kterm', 'mlterm', 'mosh', 'putty', 'st', 'rxvt-unicode-24bit', 'terminator', 'xterm-kitty'].includes(term) || /ansi|color|linux|direct|^con[0-9]*x[0-9]|^rxvt|^screen|^xterm|^vt100|^vt220/.test(term)) return true;\n"
8906
+ " }\n"
8907
+ " return !!e.COLORTERM;\n"
8908
+ " };\n"
8909
+ " const styleText = (format, text, options) => {\n"
8910
+ " const validateStream = options?.validateStream ?? true;\n"
8911
+ " const cache = getStyleCache();\n"
8912
+ " if (!validateStream && typeof format === 'string' && typeof text === 'string') {\n"
8913
+ " if (format === 'none') return text;\n"
8914
+ " const style = cache[format];\n"
8915
+ " if (style !== undefined) return style.open + replaceCloseCode(text, style) + style.close;\n"
8916
+ " }\n"
8917
+ " if (typeof text !== 'string') envArgumentError('text', 'of type string', text);\n"
8918
+ " if (options !== undefined && (options === null || typeof options !== 'object' || Array.isArray(options))) envArgumentError('options', 'of type object', options);\n"
8919
+ " if (typeof validateStream !== 'boolean') envArgumentError('options.validateStream', 'of type boolean', validateStream);\n"
8920
+ " let skipColorize = false;\n"
8921
+ " if (validateStream) {\n"
8922
+ " const stream = options?.stream ?? env.stdout;\n"
8923
+ " const node = stream && (stream._readableState || stream._writableState || typeof stream.write === 'function' && typeof stream.on === 'function' || typeof stream.pipe === 'function' && typeof stream.on === 'function');\n"
8924
+ " const readable = stream && !node && typeof stream.pipeThrough === 'function' && typeof stream.getReader === 'function' && typeof stream.cancel === 'function';\n"
8925
+ " const writable = stream && !node && typeof stream.getWriter === 'function' && typeof stream.abort === 'function';\n"
8926
+ " if (!node && !readable && !writable) envArgumentError('stream', 'an instance of ReadableStream, WritableStream, or Stream', stream);\n"
8927
+ " let colorize;\n"
8928
+ " if (env.env.FORCE_COLOR !== undefined) colorize = terminalColors();\n"
8929
+ " else colorize = stream?.isTTY && (typeof stream.getColorDepth === 'function' ? stream.getColorDepth() > 2 : stream === env.stdout || stream === env.stderr || stream === env.stdin ? terminalColors() : true);\n"
8930
+ " skipColorize = !colorize;\n"
8931
+ " }\n"
8932
+ " const formats = Array.isArray(format) ? format : [format];\n"
8933
+ " let open = '', close = '', processed = text;\n"
8934
+ " for (const key of formats) {\n"
8935
+ " if (key === 'none') continue;\n"
8936
+ " const style = cache[key];\n"
8937
+ " if (style === undefined && !Object.getOwnPropertyNames(inspect.colors).includes(key)) {\n"
8938
+ " const error = new TypeError(\"The argument 'format' must be one of: \" + Object.getOwnPropertyNames(inspect.colors).map((name) => \"'\" + name + \"'\").join(', ') + '. Received ' + inspect(key));\n"
8939
+ " error.code = 'ERR_INVALID_ARG_VALUE';\n"
8940
+ " throw error;\n"
8941
+ " }\n"
8942
+ " open += style.open; close = style.close + close;\n"
8943
+ " processed = replaceCloseCode(processed, style);\n"
8944
+ " }\n"
8945
+ " return skipColorize ? text : open + processed + close;\n"
8946
+ " };\n"
8947
+ " const parseArgs = (config = {}) => {\n"
8948
+ " if (config === null) throw new TypeError(\"Cannot convert undefined or null to object\");\n"
8949
+ " const own = (o, k) => Object.prototype.hasOwnProperty.call(o, k);\n"
8950
+ " const get = (o, k) => own(o, k) ? o[k] : undefined;\n"
8951
+ " const args = get(config, 'args') ?? env.argv.slice(2);\n"
8952
+ " const strict = get(config, 'strict') ?? true;\n"
8953
+ " const allowPositionals = get(config, 'allowPositionals') ?? !strict;\n"
8954
+ " const returnTokens = get(config, 'tokens') ?? false;\n"
8955
+ " const allowNegative = get(config, 'allowNegative') ?? false;\n"
8956
+ " const options = get(config, 'options') ?? Object.create(null);\n"
8957
+ " const fail = (code, message) => { const e = new TypeError(message); e.code = code; throw e; };\n"
8958
+ " const validate = (v, name, expected, ok) => {\n"
8959
+ " if (!ok) fail('ERR_INVALID_ARG_TYPE', 'The \"' + name + '\" ' + (name.startsWith('options.') ? 'property' : 'argument') + ' must be ' + expected + '. Received ' + received(v));\n"
7890
8960
  " };\n"
7891
- " const store = (name, value, raw) => {\n"
7892
- " const cfg = options[name] || {};\n"
7893
- " const type = cfg.type;\n"
7894
- " if (strict) {\n"
7895
- " if (options[name] === undefined) unknownError(raw);\n"
7896
- " if (type === \"string\" && value === undefined) {\n"
7897
- " const e = new TypeError(\"Option '\" + raw + (cfg.short && raw.startsWith(\"--\") === false ? \"\" : \"\") + \" <value>' argument missing\");\n"
7898
- " e.code = \"ERR_PARSE_ARGS_INVALID_OPTION_VALUE\";\n"
7899
- " throw e;\n"
7900
- " }\n"
7901
- " if (type === \"boolean\" && value !== undefined) {\n"
7902
- " const e = new TypeError(\"Option '\" + raw + \"' does not take an argument\");\n"
7903
- " e.code = \"ERR_PARSE_ARGS_INVALID_OPTION_VALUE\";\n"
7904
- " throw e;\n"
7905
- " }\n"
7906
- " }\n"
7907
- " const finalValue = value === undefined ? true : value;\n"
7908
- " tokens.push({ kind: \"option\", name, rawName: raw, index: tokenIndex, value: value === undefined ? undefined : value, inlineValue: inline });\n"
7909
- " if (cfg.multiple) {\n"
7910
- " if (result.values[name] === undefined) result.values[name] = [];\n"
7911
- " result.values[name].push(finalValue);\n"
7912
- " } else {\n"
7913
- " result.values[name] = finalValue;\n"
8961
+ " const object = (v, name) => validate(v, name, 'of type object', v !== null && typeof v === 'object' && !Array.isArray(v));\n"
8962
+ " const boolean = (v, name) => validate(v, name, 'of type boolean', typeof v === 'boolean');\n"
8963
+ " const string = (v, name) => validate(v, name, 'of type string', typeof v === 'string');\n"
8964
+ " validate(args, 'args', 'an instance of Array', Array.isArray(args));\n"
8965
+ " boolean(strict, 'strict');\n"
8966
+ " boolean(allowPositionals, 'allowPositionals');\n"
8967
+ " boolean(returnTokens, 'tokens');\n"
8968
+ " boolean(allowNegative, 'allowNegative');\n"
8969
+ " object(options, 'options');\n"
8970
+ " for (const [name, option] of Object.entries(options)) {\n"
8971
+ " const path = 'options.' + name;\n"
8972
+ " object(option, path);\n"
8973
+ " const type = get(option, 'type');\n"
8974
+ " validate(type, path + '.type', \"('string|boolean')\", type === 'string' || type === 'boolean');\n"
8975
+ " if (own(option, 'short')) {\n"
8976
+ " const short = option.short;\n"
8977
+ " string(short, path + '.short');\n"
8978
+ " if (short.length !== 1) fail('ERR_INVALID_ARG_VALUE', \"The property '\" + path + \".short' must be a single character. Received \" + inspect(short));\n"
8979
+ " }\n"
8980
+ " const multiple = get(option, 'multiple');\n"
8981
+ " if (own(option, 'multiple')) boolean(multiple, path + '.multiple');\n"
8982
+ " const value = get(option, 'default');\n"
8983
+ " if (value !== undefined) {\n"
8984
+ " const check = type === 'string' ? string : boolean;\n"
8985
+ " if (multiple) {\n"
8986
+ " validate(value, path + '.default', 'an instance of Array', Array.isArray(value));\n"
8987
+ " for (let i = 0; i < value.length; i++) check(value[i], path + '.default[' + i + ']');\n"
8988
+ " } else check(value, path + '.default');\n"
7914
8989
  " }\n"
8990
+ " }\n"
8991
+ " const optionGet = (name, key) => own(options, name) ? get(options[name], key) : undefined;\n"
8992
+ " const shortName = (ch) => {\n"
8993
+ " const entry = Object.entries(options).find(([, option]) => get(option, 'short') === ch);\n"
8994
+ " return entry ? entry[0] : ch;\n"
7915
8995
  " };\n"
7916
- " let tokenIndex = -1;\n"
7917
- " let inline;\n"
7918
- " let afterDashDash = false;\n"
7919
- " for (let i = 0; i < args.length; i++) {\n"
7920
- " const arg = args[i];\n"
7921
- " tokenIndex = i;\n"
7922
- " inline = undefined;\n"
7923
- " if (afterDashDash) {\n"
7924
- " tokens.push({ kind: \"positional\", index: i, value: arg });\n"
7925
- " result.positionals.push(arg);\n"
7926
- " continue;\n"
7927
- " }\n"
7928
- " if (arg === \"--\") {\n"
7929
- " afterDashDash = true;\n"
7930
- " tokens.push({ kind: \"option-terminator\", index: i });\n"
7931
- " continue;\n"
8996
+ " const tokens = [];\n"
8997
+ " // Tokenize the full argument snapshot before checking usage, as Node does.\n"
8998
+ " const remaining = Array.prototype.slice.call(args);\n"
8999
+ " let index = -1;\n"
9000
+ " let groupCount = 0;\n"
9001
+ " while (remaining.length) {\n"
9002
+ " const arg = remaining.shift();\n"
9003
+ " if (groupCount > 0) groupCount--; else index++;\n"
9004
+ " if (arg === '--') {\n"
9005
+ " tokens.push({ kind: 'option-terminator', index });\n"
9006
+ " for (const value of remaining) tokens.push({ kind: 'positional', index: ++index, value });\n"
9007
+ " break;\n"
7932
9008
  " }\n"
7933
- " if (arg.startsWith(\"--\")) {\n"
7934
- " const eq = arg.indexOf(\"=\");\n"
7935
- " if (eq !== -1) {\n"
7936
- " const name = arg.slice(2, eq);\n"
7937
- " inline = true;\n"
7938
- " store(name, arg.slice(eq + 1), \"--\" + name);\n"
9009
+ " // Reading length first deliberately preserves Node's nullish-argument error.\n"
9010
+ " if (arg == null) throw new TypeError(\"Cannot read properties of \" + arg + \" (reading 'length')\");\n"
9011
+ " const length = arg.length;\n"
9012
+ " if (length === 2 && String.prototype.charAt.call(arg, 0) === '-' && String.prototype.charAt.call(arg, 1) !== '-') {\n"
9013
+ " const name = shortName(String.prototype.charAt.call(arg, 1));\n"
9014
+ " let value, inlineValue;\n"
9015
+ " if (optionGet(name, 'type') === 'string' && remaining[0] != null) { value = remaining.shift(); inlineValue = false; }\n"
9016
+ " tokens.push({ kind: 'option', name, rawName: arg, index, value, inlineValue });\n"
9017
+ " if (value != null) index++;\n"
9018
+ " } else if (length > 2 && String.prototype.charAt.call(arg, 0) === '-' && String.prototype.charAt.call(arg, 1) !== '-') {\n"
9019
+ " const firstName = shortName(String.prototype.charAt.call(arg, 1));\n"
9020
+ " if (optionGet(firstName, 'type') === 'string') {\n"
9021
+ " tokens.push({ kind: 'option', name: firstName, rawName: '-' + String.prototype.charAt.call(arg, 1), index, value: String.prototype.slice.call(arg, 2), inlineValue: true });\n"
7939
9022
  " } else {\n"
7940
- " const name = arg.slice(2);\n"
7941
- " const cfg = options[name];\n"
7942
- " if (cfg !== undefined && cfg.type === \"string\" && i + 1 < args.length) {\n"
7943
- " inline = false;\n"
7944
- " store(name, args[++i], arg);\n"
7945
- " } else if (allowNegative && name.startsWith(\"no-\") && (options[name.slice(3)] || {}).type === \"boolean\") {\n"
7946
- " const positive = name.slice(3);\n"
7947
- " tokens.push({ kind: \"option\", name: positive, rawName: arg, index: i, value: undefined, inlineValue: undefined });\n"
7948
- " result.values[positive] = false;\n"
7949
- " } else {\n"
7950
- " if (strict && cfg === undefined) unknownError(arg);\n"
7951
- " if (strict && cfg.type === \"string\") {\n"
7952
- " const e = new TypeError(\"Option '--\" + name + \" <value>' argument missing\");\n"
7953
- " e.code = \"ERR_PARSE_ARGS_INVALID_OPTION_VALUE\";\n"
7954
- " throw e;\n"
7955
- " }\n"
7956
- " store(name, undefined, arg);\n"
9023
+ " const expanded = [];\n"
9024
+ " for (let i = 1; i < length; i++) {\n"
9025
+ " const ch = String.prototype.charAt.call(arg, i);\n"
9026
+ " const name = shortName(ch);\n"
9027
+ " if (optionGet(name, 'type') === 'string' && i !== length - 1) { expanded.push('-' + String.prototype.slice.call(arg, i)); break; }\n"
9028
+ " expanded.push('-' + ch);\n"
7957
9029
  " }\n"
9030
+ " remaining.unshift(...expanded);\n"
9031
+ " groupCount = expanded.length;\n"
7958
9032
  " }\n"
7959
- " continue;\n"
7960
- " }\n"
7961
- " if (arg.length > 1 && arg[0] === \"-\") {\n"
7962
- " const chars = arg.slice(1);\n"
7963
- " let consumed = false;\n"
7964
- " for (let c = 0; c < chars.length; c++) {\n"
7965
- " const ch = chars[c];\n"
7966
- " const name = shortOf(ch);\n"
7967
- " const raw = \"-\" + ch;\n"
7968
- " const cfg = name !== undefined ? options[name] : undefined;\n"
7969
- " if (cfg !== undefined && cfg.type === \"string\") {\n"
7970
- " if (c < chars.length - 1) {\n"
7971
- " inline = true;\n"
7972
- " store(name, chars.slice(c + 1), raw);\n"
7973
- " } else if (i + 1 < args.length) {\n"
7974
- " inline = false;\n"
7975
- " store(name, args[++i], raw);\n"
7976
- " } else if (strict) {\n"
7977
- " const e = new TypeError(\"Option '\" + raw + \", --\" + name + \" <value>' argument missing\");\n"
7978
- " e.code = \"ERR_PARSE_ARGS_INVALID_OPTION_VALUE\";\n"
7979
- " throw e;\n"
7980
- " } else {\n"
7981
- " store(name, undefined, raw);\n"
7982
- " }\n"
7983
- " consumed = true;\n"
7984
- " break;\n"
9033
+ " } else if (length > 2 && String.prototype.startsWith.call(arg, '--')) {\n"
9034
+ " const eq = String.prototype.indexOf.call(arg, '=', 3);\n"
9035
+ " const name = String.prototype.slice.call(arg, 2, eq < 0 ? undefined : eq);\n"
9036
+ " let value, inlineValue;\n"
9037
+ " if (eq >= 0) { value = String.prototype.slice.call(arg, eq + 1); inlineValue = true; }\n"
9038
+ " else if (optionGet(name, 'type') === 'string' && remaining[0] != null) { value = remaining.shift(); inlineValue = false; }\n"
9039
+ " tokens.push({ kind: 'option', name, rawName: '--' + name, index, value, inlineValue });\n"
9040
+ " if (eq < 0 && value != null) index++;\n"
9041
+ " } else tokens.push({ kind: 'positional', index, value: arg });\n"
9042
+ " }\n"
9043
+ " const result = { values: Object.create(null), positionals: [] };\n"
9044
+ " if (returnTokens) result.tokens = tokens;\n"
9045
+ " for (const token of tokens) {\n"
9046
+ " if (token.kind === 'positional') {\n"
9047
+ " if (!allowPositionals) fail('ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL', \"Unexpected argument '\" + token.value + \"'. This command does not take positional arguments\");\n"
9048
+ " result.positionals.push(token.value);\n"
9049
+ " } else if (token.kind === 'option') {\n"
9050
+ " let name = token.name;\n"
9051
+ " if (strict) {\n"
9052
+ " if (!own(options, name)) {\n"
9053
+ " if (allowNegative && name.startsWith('no-') && own(options, name.slice(3)) && optionGet(name.slice(3), 'type') === 'boolean') name = name.slice(3);\n"
9054
+ " else fail('ERR_PARSE_ARGS_UNKNOWN_OPTION', \"Unknown option '\" + token.rawName + \"'\" + (allowPositionals ? \". To specify a positional argument starting with a '-', place it at the end of the command after '--', as in '-- \\\"\" + token.rawName + \"\\\"\" : ''));\n"
7985
9055
  " }\n"
7986
- " if (name === undefined) {\n"
7987
- " if (strict) unknownError(raw);\n"
7988
- " store(ch, undefined, raw);\n"
7989
- " } else {\n"
7990
- " store(name, undefined, raw);\n"
9056
+ " const short = optionGet(name, 'short');\n"
9057
+ " const label = (short ? '-' + short + ', ' : '') + '--' + name;\n"
9058
+ " if (optionGet(name, 'type') === 'string' && typeof token.value !== 'string') fail('ERR_PARSE_ARGS_INVALID_OPTION_VALUE', \"Option '\" + label + \" <value>' argument missing\");\n"
9059
+ " if (optionGet(name, 'type') === 'boolean' && token.value != null) fail('ERR_PARSE_ARGS_INVALID_OPTION_VALUE', \"Option '\" + label + \"' does not take an argument\");\n"
9060
+ " if (!token.inlineValue && token.value != null && token.value.length > 1 && String.prototype.charAt.call(token.value, 0) === '-') {\n"
9061
+ " const example = token.rawName.startsWith('--') ? \"'\" + token.rawName + \"=-XYZ'\" : \"'--\" + token.name + \"=-XYZ' or '\" + token.rawName + \"-XYZ'\";\n"
9062
+ " fail('ERR_PARSE_ARGS_INVALID_OPTION_VALUE', \"Option '\" + token.rawName + \"' argument is ambiguous.\\nDid you forget to specify the option argument for '\" + token.rawName + \"'?\\nTo specify an option argument starting with a dash use \" + example + '.');\n"
7991
9063
  " }\n"
7992
9064
  " }\n"
7993
- " void consumed;\n"
7994
- " continue;\n"
7995
- " }\n"
7996
- " if (strict && !allowPositionals) {\n"
7997
- " const e = new TypeError(\"Unexpected argument '\" + arg + \"'. This command does not take positional arguments\");\n"
7998
- " e.code = \"ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL\";\n"
7999
- " throw e;\n"
9065
+ " name = token.name;\n"
9066
+ " let value = token.value;\n"
9067
+ " if (name === '__proto__') continue;\n"
9068
+ " if (allowNegative && name.startsWith('no-') && value === undefined) { name = name.slice(3); token.name = name; value = false; }\n"
9069
+ " value = value ?? true;\n"
9070
+ " if (optionGet(name, 'multiple')) {\n"
9071
+ " if (!result.values[name]) result.values[name] = [];\n"
9072
+ " result.values[name].push(value);\n"
9073
+ " } else result.values[name] = value;\n"
8000
9074
  " }\n"
8001
- " tokens.push({ kind: \"positional\", index: i, value: arg });\n"
8002
- " result.positionals.push(arg);\n"
8003
9075
  " }\n"
8004
- " for (const name of Object.keys(options)) {\n"
8005
- " const cfg = options[name];\n"
8006
- " if (cfg.default !== undefined && !(name in result.values)) {\n"
8007
- " result.values[name] = cfg.default;\n"
8008
- " }\n"
9076
+ " for (const [name, option] of Object.entries(options)) {\n"
9077
+ " if (name !== '__proto__' && get(option, 'default') !== undefined && result.values[name] === undefined) result.values[name] = get(option, 'default');\n"
8009
9078
  " }\n"
8010
- " if (returnTokens) result.tokens = tokens;\n"
8011
9079
  " return result;\n"
8012
9080
  " };\n"
8013
- " const toUSVString = (s) => String(s).replace(/[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/g, \"�\");\n"
9081
+ " const toUSVString = (s) => {\n"
9082
+ " let primitive = s;\n"
9083
+ " const isObject = (v) => v !== null && (typeof v === 'object' || typeof v === 'function');\n"
9084
+ " if (isObject(s)) {\n"
9085
+ " const exotic = s[Symbol.toPrimitive];\n"
9086
+ " if (exotic !== undefined && exotic !== null) {\n"
9087
+ " if (typeof exotic !== 'function') {\n"
9088
+ " const kind = typeof exotic;\n"
9089
+ " const label = ['object', 'symbol', 'bigint'].includes(kind) ? kind : kind + ' ' + (kind === 'string' ? '\"' + exotic + '\"' : String(exotic));\n"
9090
+ " throw new TypeError(label + ' is not a function');\n"
9091
+ " }\n"
9092
+ " primitive = Reflect.apply(exotic, s, ['string']);\n"
9093
+ " if (isObject(primitive)) throw new TypeError('Cannot convert object to primitive value');\n"
9094
+ " } else {\n"
9095
+ " let converted = false;\n"
9096
+ " for (const name of ['toString', 'valueOf']) {\n"
9097
+ " const method = s[name];\n"
9098
+ " if (typeof method !== 'function') continue;\n"
9099
+ " primitive = Reflect.apply(method, s, []);\n"
9100
+ " if (!isObject(primitive)) { converted = true; break; }\n"
9101
+ " }\n"
9102
+ " if (!converted) throw new TypeError('Cannot convert object to primitive value');\n"
9103
+ " }\n"
9104
+ " }\n"
9105
+ " if (typeof primitive === 'symbol') throw new TypeError('Cannot convert a Symbol value to a string');\n"
9106
+ " return `${primitive}`.replace(/[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/g, \"�\");\n"
9107
+ " };\n"
8014
9108
  " const _extend = (target, source) => {\n"
8015
9109
  " if (source === null || typeof source !== \"object\") return target;\n"
8016
9110
  " for (const k of Object.keys(source)) target[k] = source[k];\n"
8017
9111
  " return target;\n"
8018
9112
  " };\n"
9113
+ " // Node 24's MIME API uses HTTP whitespace and token grammar, not Unicode trimming.\n"
9114
+ " const mimeInvalidToken = /[^!#$%&'*+\\-.^_`|~A-Za-z0-9]/;\n"
9115
+ " const mimeInvalidValue = /[^\\t\\u0020-\\u007e\\u0080-\\u00ff]/;\n"
9116
+ " const mimeLeadingWhitespace = /^[\\r\\n\\t ]*/;\n"
9117
+ " const mimeTrailingWhitespace = /[\\r\\n\\t ]*$/;\n"
9118
+ " const mimeLower = (s) => s.replace(/[A-Z]/g, (c) => c.toLowerCase());\n"
9119
+ " const mimeError = (production, input, index) => {\n"
9120
+ " const error = new TypeError('The MIME syntax for a ' + production + ' in \"' + input + '\" is invalid' + (index === -1 ? '' : ' at ' + index));\n"
9121
+ " error.code = 'ERR_INVALID_MIME_SYNTAX';\n"
9122
+ " throw error;\n"
9123
+ " };\n"
9124
+ " const mimeValidateToken = (value, production, input = value) => {\n"
9125
+ " const index = value.search(mimeInvalidToken);\n"
9126
+ " if (!value.length || index !== -1) mimeError(production, input, index);\n"
9127
+ " };\n"
9128
+ " const mimeEncode = (value) => {\n"
9129
+ " if (value.length && value.search(mimeInvalidToken) === -1) return value;\n"
9130
+ " return '\"' + value.replace(/[\"\\\\]/g, (c) => '\\\\' + c) + '\"';\n"
9131
+ " };\n"
9132
+ " let mimeParamsFromSource;\n"
9133
+ " class MIMEParams {\n"
9134
+ " #data = new Map();\n"
9135
+ " #source = null;\n"
9136
+ " static {\n"
9137
+ " mimeParamsFromSource = (source) => {\n"
9138
+ " const params = new MIMEParams();\n"
9139
+ " params.#source = source;\n"
9140
+ " return params;\n"
9141
+ " };\n"
9142
+ " }\n"
9143
+ " #parse() {\n"
9144
+ " if (this.#source === null) return;\n"
9145
+ " const source = this.#source;\n"
9146
+ " const end = source.search(mimeTrailingWhitespace);\n"
9147
+ " let pos = 0;\n"
9148
+ " while (pos < end) {\n"
9149
+ " pos += source.slice(pos).match(mimeLeadingWhitespace)[0].length;\n"
9150
+ " const start = pos;\n"
9151
+ " while (pos < source.length && source[pos] !== ';' && source[pos] !== '=') pos++;\n"
9152
+ " const name = mimeLower(source.slice(start, pos));\n"
9153
+ " if (pos < end && source[pos++] === ';') continue;\n"
9154
+ " if (pos >= end) break;\n"
9155
+ " let value = '';\n"
9156
+ " if (source[pos] === '\"') {\n"
9157
+ " pos++;\n"
9158
+ " // Quoted values accept escaped characters and a missing closing quote.\n"
9159
+ " while (pos < source.length) {\n"
9160
+ " const char = source[pos++];\n"
9161
+ " if (char === '\"') break;\n"
9162
+ " value += char === '\\\\' && pos < source.length ? source[pos++] : char;\n"
9163
+ " }\n"
9164
+ " } else {\n"
9165
+ " const startValue = pos;\n"
9166
+ " while (pos < source.length && source[pos] !== ';') pos++;\n"
9167
+ " value = source.slice(startValue, pos).replace(mimeTrailingWhitespace, '');\n"
9168
+ " if (!value.length) continue;\n"
9169
+ " }\n"
9170
+ " // Parsing ignores invalid parameters and keeps the first duplicate.\n"
9171
+ " if (name.length && name.search(mimeInvalidToken) === -1 &&\n"
9172
+ " value.search(mimeInvalidValue) === -1 && !this.#data.has(name)) {\n"
9173
+ " this.#data.set(name, value);\n"
9174
+ " }\n"
9175
+ " pos++;\n"
9176
+ " }\n"
9177
+ " this.#source = null;\n"
9178
+ " }\n"
9179
+ " delete(name) { this.#parse(); this.#data.delete(name); }\n"
9180
+ " get(name) { this.#parse(); return this.#data.has(name) ? this.#data.get(name) : null; }\n"
9181
+ " has(name) { this.#parse(); return this.#data.has(name); }\n"
9182
+ " set(name, value) {\n"
9183
+ " this.#parse();\n"
9184
+ " name = `${name}`;\n"
9185
+ " value = `${value}`;\n"
9186
+ " mimeValidateToken(name, 'parameter name');\n"
9187
+ " const index = value.search(mimeInvalidValue);\n"
9188
+ " if (index !== -1) mimeError('parameter value', value, index);\n"
9189
+ " this.#data.set(name, value);\n"
9190
+ " }\n"
9191
+ " *entries() { this.#parse(); yield* this.#data.entries(); }\n"
9192
+ " *keys() { this.#parse(); yield* this.#data.keys(); }\n"
9193
+ " *values() { this.#parse(); yield* this.#data.values(); }\n"
9194
+ " toString() {\n"
9195
+ " this.#parse();\n"
9196
+ " let result = '';\n"
9197
+ " for (const [name, value] of this.#data) {\n"
9198
+ " if (result.length) result += ';';\n"
9199
+ " result += name + '=' + mimeEncode(value);\n"
9200
+ " }\n"
9201
+ " return result;\n"
9202
+ " }\n"
9203
+ " }\n"
9204
+ " const mimeParamsStringify = MIMEParams.prototype.toString;\n"
9205
+ " Object.defineProperty(MIMEParams.prototype, Symbol.iterator, {\n"
9206
+ " value: MIMEParams.prototype.entries, writable: true, configurable: true,\n"
9207
+ " });\n"
9208
+ " Object.defineProperty(MIMEParams.prototype, 'toJSON', {\n"
9209
+ " value: mimeParamsStringify, writable: true, configurable: true,\n"
9210
+ " });\n"
9211
+ " class MIMEType {\n"
9212
+ " #type;\n"
9213
+ " #subtype;\n"
9214
+ " #params;\n"
9215
+ " constructor(input) {\n"
9216
+ " input = `${input}`;\n"
9217
+ " const start = input.match(mimeLeadingWhitespace)[0].length;\n"
9218
+ " const slash = input.indexOf('/', start);\n"
9219
+ " const type = input.slice(start, slash === -1 ? input.length : slash);\n"
9220
+ " mimeValidateToken(type, 'type', input);\n"
9221
+ " if (slash === -1) mimeError('type', input, -1);\n"
9222
+ " const semicolon = input.indexOf(';', slash + 1);\n"
9223
+ " const subtype = input.slice(slash + 1, semicolon === -1 ? input.length : semicolon).replace(mimeTrailingWhitespace, '');\n"
9224
+ " mimeValidateToken(subtype, 'subtype', input);\n"
9225
+ " this.#type = mimeLower(type);\n"
9226
+ " this.#subtype = mimeLower(subtype);\n"
9227
+ " this.#params = mimeParamsFromSource(semicolon === -1 ? '' : input.slice(semicolon + 1));\n"
9228
+ " }\n"
9229
+ " get type() { return this.#type; }\n"
9230
+ " set type(value) {\n"
9231
+ " value = `${value}`;\n"
9232
+ " mimeValidateToken(value, 'type');\n"
9233
+ " this.#type = mimeLower(value);\n"
9234
+ " }\n"
9235
+ " get subtype() { return this.#subtype; }\n"
9236
+ " set subtype(value) {\n"
9237
+ " value = `${value}`;\n"
9238
+ " mimeValidateToken(value, 'subtype');\n"
9239
+ " this.#subtype = mimeLower(value);\n"
9240
+ " }\n"
9241
+ " get essence() { return this.#type + '/' + this.#subtype; }\n"
9242
+ " get params() { return this.#params; }\n"
9243
+ " toString() {\n"
9244
+ " // Capture the serializer so user overrides cannot change MIME serialization.\n"
9245
+ " const params = mimeParamsStringify.call(this.#params);\n"
9246
+ " return this.#type + '/' + this.#subtype + (params.length ? ';' + params : '');\n"
9247
+ " }\n"
9248
+ " }\n"
9249
+ " Object.defineProperty(MIMEType.prototype, 'toJSON', {\n"
9250
+ " value: MIMEType.prototype.toString, writable: true, configurable: true,\n"
9251
+ " });\n"
8019
9252
  " const util = {\n"
9253
+ " getSystemErrorMap: () => new Map(host.systemErrorEntries()),\n"
9254
+ " getSystemErrorName: (err) => {\n"
9255
+ " if (typeof err !== 'number') envArgumentError('err', 'of type number', err);\n"
9256
+ " return host.systemErrorInfo(err, false);\n"
9257
+ " },\n"
9258
+ " getSystemErrorMessage: (err) => {\n"
9259
+ " if (typeof err !== 'number') envArgumentError('err', 'of type number', err);\n"
9260
+ " return host.systemErrorInfo(err, true);\n"
9261
+ " },\n"
8020
9262
  " format, formatWithOptions, inspect, inherits, promisify, callbackify,\n"
8021
9263
  " deprecate, debuglog, debug: debuglog, types, isDeepStrictEqual,\n"
8022
- " stripVTControlCharacters, styleText, parseArgs, toUSVString, _extend,\n"
9264
+ " stripVTControlCharacters, styleText, parseArgs, toUSVString, _extend, MIMEType, MIMEParams,\n"
9265
+ " parseEnv: (content) => {\n"
9266
+ " if (typeof content !== 'string') envArgumentError('content', 'of type string', content);\n"
9267
+ " return host.parseEnv(toUSVString(content));\n"
9268
+ " },\n"
8023
9269
  " TextEncoder: globalThis.TextEncoder, TextDecoder: globalThis.TextDecoder,\n"
8024
9270
  " isArray: (v) => Array.isArray(v),\n"
8025
9271
  " };\n"
8026
9272
  " return util;\n"
8027
9273
  "}\n"
8028
9274
  " const util = makeUtil({\n"
9275
+ " typeProbe: host.typeProbe,\n"
8029
9276
  " promiseState: (p) => host.promiseState(p),\n"
8030
9277
  " writeErr: (s) => host.write(2, s),\n"
8031
9278
  " env: builtins.process().env,\n"
@@ -8040,7 +9287,6 @@ static const char isl_modules_bootstrap[] =
8040
9287
  * same object; require('util/types') === require('util').types). */
8041
9288
  " builtins['util/types'] = memo(() => {\n"
8042
9289
  " const t = builtins.util().types;\n"
8043
- " t.default = t;\n"
8044
9290
  " return t;\n"
8045
9291
  " });\n"
8046
9292
  " builtins.child_process = memo(() => {\n"
@@ -8791,9 +10037,8 @@ static const char isl_modules_bootstrap[] =
8791
10037
  " c.default = c;\n"
8792
10038
  " return c;\n"
8793
10039
  " });\n"
8794
- /* node:timers (+ timers/promises) over the island's timer
8795
- * bridge; setImmediate rides a zero-delay timer (Node's check
8796
- * phase does not exist here — documented divergence). */
10040
+ /* node:timers and timers/promises share the native timer heap and
10041
+ * immediate queue through the web prelude's handle objects. */
8797
10042
  " builtins.timers = memo(() => {\n"
8798
10043
  " const t = {\n"
8799
10044
  " setTimeout: globalThis.setTimeout,\n"
@@ -8807,30 +10052,94 @@ static const char isl_modules_bootstrap[] =
8807
10052
  " return t;\n"
8808
10053
  " });\n"
8809
10054
  " builtins['timers/promises'] = memo(() => {\n"
8810
- " const delay = (ms, value, options) => new Promise((resolve, reject) => {\n"
8811
- " const t = globalThis.setTimeout(() => resolve(value), ms);\n"
8812
- " if (options !== undefined && options !== null && options.signal !== undefined && typeof options.signal.addEventListener === 'function') {\n"
8813
- " options.signal.addEventListener('abort', () => {\n"
8814
- " globalThis.clearTimeout(t);\n"
8815
- " const e = new Error('The operation was aborted');\n"
8816
- " e.name = 'AbortError';\n"
8817
- " e.code = 'ABORT_ERR';\n"
8818
- " reject(e);\n"
8819
- " });\n"
10055
+ " const resistant = Symbol.for('scriptc.events.resistStopPropagation');\n"
10056
+ " const checkDelay = (delay) => {\n"
10057
+ " if (delay !== undefined && typeof delay !== 'number') envArgumentError('delay', 'of type number', delay);\n"
10058
+ " };\n"
10059
+ " const checkOptions = (options) => {\n"
10060
+ " if (options === null || typeof options !== 'object' || Array.isArray(options)) envArgumentError('options', 'of type object', options);\n"
10061
+ " if (options.signal !== undefined) {\n"
10062
+ " const signal = options.signal;\n"
10063
+ " if (signal === null || typeof signal !== 'object' || !('aborted' in signal)) envArgumentError('options.signal', 'an instance of AbortSignal', signal);\n"
10064
+ " }\n"
10065
+ " if (options.ref !== undefined) {\n"
10066
+ " const ref = options.ref;\n"
10067
+ " if (typeof ref !== 'boolean') envArgumentError('options.ref', 'of type boolean', ref);\n"
10068
+ " }\n"
10069
+ " const { signal, ref = true } = options;\n"
10070
+ " return { signal, ref };\n"
10071
+ " };\n"
10072
+ " const abortError = (signal) => {\n"
10073
+ " const error = new Error('The operation was aborted', { cause: signal.reason });\n"
10074
+ " error.name = 'AbortError'; error.code = 'ABORT_ERR';\n"
10075
+ " return error;\n"
10076
+ " };\n"
10077
+ " const wait = (immediate, delay, value, options) => {\n"
10078
+ " let signal, ref;\n"
10079
+ " try {\n"
10080
+ " if (!immediate) checkDelay(delay);\n"
10081
+ " ({ signal, ref } = checkOptions(options));\n"
10082
+ " } catch (error) { return Promise.reject(error); }\n"
10083
+ " if (signal && signal.aborted) return Promise.reject(abortError(signal));\n"
10084
+ " let timer, onCancel;\n"
10085
+ " const promise = new Promise((resolve, reject) => {\n"
10086
+ " timer = immediate ? globalThis.setImmediate(resolve, value) : globalThis.setTimeout(resolve, delay, value);\n"
10087
+ " if (!ref) timer.unref();\n"
10088
+ " if (signal) {\n"
10089
+ " onCancel = () => {\n"
10090
+ " if (!timer._destroyed) {\n"
10091
+ " if (immediate) globalThis.clearImmediate(timer); else globalThis.clearTimeout(timer);\n"
10092
+ " reject(abortError(signal));\n"
10093
+ " }\n"
10094
+ " };\n"
10095
+ " signal.addEventListener('abort', onCancel, { __proto__: null, [resistant]: true });\n"
10096
+ " }\n"
10097
+ " });\n"
10098
+ " return onCancel ? promise.finally(() => signal.removeEventListener('abort', onCancel)) : promise;\n"
10099
+ " };\n"
10100
+ " function setTimeout(delay, value, options = {}) { return wait(false, delay, value, options); }\n"
10101
+ " function setImmediate(value, options = {}) { return wait(true, undefined, value, options); }\n"
10102
+ " async function* setInterval(delay, value, options = {}) {\n"
10103
+ " checkDelay(delay);\n"
10104
+ " const { signal, ref } = checkOptions(options);\n"
10105
+ " if (signal && signal.aborted) throw abortError(signal);\n"
10106
+ " let timer, onCancel;\n"
10107
+ " try {\n"
10108
+ " let notYielded = 0, callback;\n"
10109
+ " timer = globalThis.setInterval(() => {\n"
10110
+ " notYielded++;\n"
10111
+ " if (callback) { callback(); callback = undefined; }\n"
10112
+ " }, delay);\n"
10113
+ " if (!ref) timer.unref();\n"
10114
+ " if (signal) {\n"
10115
+ " onCancel = () => {\n"
10116
+ " globalThis.clearInterval(timer);\n"
10117
+ " if (callback) { callback(Promise.reject(abortError(signal))); callback = undefined; }\n"
10118
+ " };\n"
10119
+ " signal.addEventListener('abort', onCancel, { __proto__: null, once: true, [resistant]: true });\n"
10120
+ " }\n"
10121
+ " while (!(signal && signal.aborted)) {\n"
10122
+ " if (notYielded === 0) await new Promise(resolve => callback = resolve);\n"
10123
+ " for (; notYielded > 0; notYielded--) yield value;\n"
10124
+ " }\n"
10125
+ " throw abortError(signal);\n"
10126
+ " } finally {\n"
10127
+ " globalThis.clearInterval(timer);\n"
10128
+ " if (signal) signal.removeEventListener('abort', onCancel);\n"
8820
10129
  " }\n"
8821
- " });\n"
10130
+ " }\n"
10131
+ " const schedulerBrand = Symbol('kScheduler');\n"
10132
+ " const checkScheduler = (receiver) => {\n"
10133
+ " if (!receiver[schedulerBrand]) { const error = new TypeError('Value of \"this\" must be of type Scheduler'); error.code = 'ERR_INVALID_THIS'; throw error; }\n"
10134
+ " };\n"
10135
+ " class Scheduler {\n"
10136
+ " constructor() { const error = new TypeError('Illegal constructor'); error.code = 'ERR_ILLEGAL_CONSTRUCTOR'; throw error; }\n"
10137
+ " yield() { checkScheduler(this); return setImmediate(); }\n"
10138
+ " wait(delay, options) { checkScheduler(this); return setTimeout(delay, undefined, options); }\n"
10139
+ " }\n"
10140
+ " const scheduler = Object.create(Scheduler.prototype); scheduler[schedulerBrand] = true;\n"
8822
10141
  " const tp = {\n"
8823
- " setTimeout: delay,\n"
8824
- " setImmediate: (value) => delay(0, value),\n"
8825
- " setInterval: (ms, value, options) => ({\n"
8826
- " async *[Symbol.asyncIterator]() {\n"
8827
- " for (;;) {\n"
8828
- " await delay(ms, undefined, options);\n"
8829
- " yield value;\n"
8830
- " }\n"
8831
- " },\n"
8832
- " }),\n"
8833
- " scheduler: { wait: (ms) => delay(ms), yield: () => delay(0) },\n"
10142
+ " setTimeout, setImmediate, setInterval, scheduler,\n"
8834
10143
  " };\n"
8835
10144
  " tp.default = tp;\n"
8836
10145
  " return tp;\n"
@@ -9224,9 +10533,54 @@ static const char isl_modules_bootstrap[] =
9224
10533
  " s.emit = () => false;\n"
9225
10534
  " return s;\n"
9226
10535
  " };\n"
10536
+ " const envPrototype = Object.create(Object.prototype);\n"
10537
+ " Object.defineProperty(envPrototype, 'constructor', { value: Object, writable: true, configurable: true });\n"
10538
+ " const envTarget = Object.create(envPrototype);\n"
10539
+ " const env = new Proxy(envTarget, {\n"
10540
+ " get: (target, key, receiver) => {\n"
10541
+ " if (typeof key === 'symbol') return Reflect.get(target, key, receiver);\n"
10542
+ " const value = host.envGet(key);\n"
10543
+ " return value === undefined ? Reflect.get(target, key, receiver) : value;\n"
10544
+ " },\n"
10545
+ " set: (_, key, value) => {\n"
10546
+ " if (typeof key === 'symbol' || typeof value === 'symbol') throw new TypeError('Cannot convert a Symbol value to a string');\n"
10547
+ " return host.envSet(key, String(value));\n"
10548
+ " },\n"
10549
+ " deleteProperty: (_, key) => {\n"
10550
+ " if (typeof key === 'symbol') return true;\n"
10551
+ " return host.envDelete(key);\n"
10552
+ " },\n"
10553
+ " has: (target, key) => typeof key !== 'symbol' && host.envGet(key) !== undefined || Reflect.has(target, key),\n"
10554
+ " ownKeys: () => Reflect.ownKeys(host.env()),\n"
10555
+ " getOwnPropertyDescriptor: (_, key) => {\n"
10556
+ " if (typeof key === 'symbol') return undefined;\n"
10557
+ " const value = host.envGet(key);\n"
10558
+ " return value === undefined ? undefined : { value, writable: true, enumerable: true, configurable: true };\n"
10559
+ " },\n"
10560
+ " defineProperty: (_, key, descriptor) => {\n"
10561
+ " if (!descriptor.configurable || !descriptor.writable || !descriptor.enumerable || !('value' in descriptor) || 'get' in descriptor || 'set' in descriptor) {\n"
10562
+ " const error = new TypeError(\"'process.env' only accepts a configurable, writable, and enumerable data descriptor\");\n"
10563
+ " error.code = 'ERR_INVALID_OBJECT_DEFINE_PROPERTY';\n"
10564
+ " throw error;\n"
10565
+ " }\n"
10566
+ " if (typeof key === 'symbol' || typeof descriptor.value === 'symbol') throw new TypeError('Cannot convert a Symbol value to a string');\n"
10567
+ " return host.envSet(key, String(descriptor.value));\n"
10568
+ " },\n"
10569
+ " preventExtensions: () => { throw new TypeError('Cannot prevent extensions'); },\n"
10570
+ " });\n"
10571
+ " const loadEnvFile = (path) => {\n"
10572
+ " if (path instanceof globalThis.URL) path = host.urlToPath(path.href);\n"
10573
+ " const bytes = path instanceof Uint8Array;\n"
10574
+ " if (path != null && typeof path !== 'string' && !bytes) envArgumentError('path', 'of type string or an instance of Buffer or URL', path);\n"
10575
+ " return host.loadEnvFile(path, bytes, bytes && builtins.buffer().Buffer.isBuffer(path));\n"
10576
+ " };\n"
9227
10577
  " const p = {\n"
9228
10578
  " argv,\n"
9229
- " env: host.env(),\n"
10579
+ " env, loadEnvFile,\n"
10580
+ " chdir: (directory) => {\n"
10581
+ " if (typeof directory !== 'string') envArgumentError('directory', 'of type string', directory);\n"
10582
+ " return host.chdir(directory);\n"
10583
+ " },\n"
9230
10584
  " platform: host.platform(),\n"
9231
10585
  " execPath: argv[0],\n"
9232
10586
  " execArgv: [],\n"
@@ -9337,15 +10691,9 @@ static const char isl_modules_bootstrap[] =
9337
10691
  /* Node's Buffer global (and `global` itself) — embedded CJS
9338
10692
  * reaches both without requiring anything. */
9339
10693
  " globalThis.Buffer = builtins.buffer().Buffer;\n"
9340
- /* setImmediate/clearImmediate globals (zero-delay timers — no
9341
- * check phase in the island; documented divergence), and the
9342
- * global console upgraded to Node's util.format semantics for
10694
+ /* The global console upgraded to Node's util.format semantics for
9343
10695
  * npm builds (the web prelude's String() console stays for
9344
10696
  * non-npm islands). */
9345
- " if (globalThis.setImmediate === undefined) {\n"
9346
- " globalThis.setImmediate = (fn, ...args) => globalThis.setTimeout(fn, 0, ...args);\n"
9347
- " globalThis.clearImmediate = (t) => globalThis.clearTimeout(t);\n"
9348
- " }\n"
9349
10697
  " {\n"
9350
10698
  " const fmt = (...a) => builtins.util().formatWithOptions({}, ...a);\n"
9351
10699
  " const to = (fd, prefix) => (...a) => { host.write(fd, (prefix || '') + fmt(...a) + '\\n'); };\n"
@@ -9363,7 +10711,8 @@ static const char isl_modules_bootstrap[] =
9363
10711
  " const spec = String(raw);\n"
9364
10712
  " const bare = spec.startsWith('node:') ? spec.slice(5) : spec;\n"
9365
10713
  " if (builtinModules.includes(bare) && (spec.startsWith('node:') || bare !== 'test')) return 'node:' + bare;\n"
9366
- " const base = from.startsWith('/') ? new URL('file://' + from).href : from;\n"
10714
+ " const filePath = (s) => s.startsWith('/') || /^[A-Za-z]:[\\\\/]/.test(s) || s.startsWith('\\\\\\\\');\n"
10715
+ " const base = filePath(from) ? host.urlFromPath(from) : from;\n"
9367
10716
  " if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(spec) || spec.startsWith('./') || spec.startsWith('../') || spec.startsWith('/')) {\n"
9368
10717
  " return new URL(spec, base).href;\n"
9369
10718
  " }\n"
@@ -9373,7 +10722,7 @@ static const char isl_modules_bootstrap[] =
9373
10722
  " err.code = 'ERR_MODULE_NOT_FOUND';\n"
9374
10723
  " throw err;\n"
9375
10724
  " }\n"
9376
- " return to.startsWith('/') ? new URL('file://' + to).href : to;\n"
10725
+ " return filePath(to) ? host.urlFromPath(to) : to;\n"
9377
10726
  " };\n"
9378
10727
  " return (key, name) => {\n"
9379
10728
  " const exports = requireKey(key);\n"
@@ -9405,11 +10754,21 @@ static void isl_modules_boot(void) {
9405
10754
  abort();
9406
10755
  }
9407
10756
  JSValue host = JS_NewObject(isl_ctx);
10757
+ JS_SetPropertyStr(isl_ctx, host, "typeProbe", JS_NewCFunction(isl_ctx, isl_host_type_probe, "typeProbe", 2));
9408
10758
  /* JS_SetPropertyStr consumes the function values. */
9409
10759
  JS_SetPropertyStr(isl_ctx, host, "source", JS_NewCFunction(isl_ctx, isl_host_source, "source", 1));
9410
10760
  JS_SetPropertyStr(isl_ctx, host, "resolve", JS_NewCFunction(isl_ctx, isl_host_resolve, "resolve", 2));
9411
10761
  JS_SetPropertyStr(isl_ctx, host, "argv", JS_NewCFunction(isl_ctx, isl_host_argv, "argv", 0));
9412
10762
  JS_SetPropertyStr(isl_ctx, host, "env", JS_NewCFunction(isl_ctx, isl_host_env, "env", 0));
10763
+ JS_SetPropertyStr(isl_ctx, host, "chdir", JS_NewCFunction(isl_ctx, isl_host_chdir, "chdir", 1));
10764
+ JS_SetPropertyStr(isl_ctx, host, "envGet", JS_NewCFunction(isl_ctx, isl_host_env_get, "envGet", 1));
10765
+ JS_SetPropertyStr(isl_ctx, host, "envSet", JS_NewCFunction(isl_ctx, isl_host_env_set, "envSet", 2));
10766
+ JS_SetPropertyStr(isl_ctx, host, "envDelete", JS_NewCFunction(isl_ctx, isl_host_env_delete, "envDelete", 1));
10767
+ JS_SetPropertyStr(isl_ctx, host, "parseEnv", JS_NewCFunction(isl_ctx, isl_host_parse_env, "parseEnv", 1));
10768
+ JS_SetPropertyStr(isl_ctx, host, "systemErrorEntries", JS_NewCFunction(isl_ctx, isl_host_system_error_entries, "systemErrorEntries", 0));
10769
+ JS_SetPropertyStr(isl_ctx, host, "systemErrorInfo", JS_NewCFunction(isl_ctx, isl_host_system_error_info, "systemErrorInfo", 2));
10770
+ JS_SetPropertyStr(isl_ctx, host, "transcode", JS_NewCFunction(isl_ctx, isl_host_transcode, "transcode", 3));
10771
+ JS_SetPropertyStr(isl_ctx, host, "loadEnvFile", JS_NewCFunction(isl_ctx, isl_host_load_env_file, "loadEnvFile", 2));
9413
10772
  JS_SetPropertyStr(isl_ctx, host, "write", JS_NewCFunction(isl_ctx, isl_host_write, "write", 2));
9414
10773
  JS_SetPropertyStr(isl_ctx, host, "readStdin",
9415
10774
  JS_NewCFunction(isl_ctx, isl_host_read_stdin, "readStdin", 0));
@@ -9428,11 +10787,13 @@ static void isl_modules_boot(void) {
9428
10787
  JS_SetPropertyStr(isl_ctx, host, "promiseState", JS_NewCFunction(isl_ctx, isl_host_promise_state, "promiseState", 1));
9429
10788
  JS_SetPropertyStr(isl_ctx, host, "digest", JS_NewCFunction(isl_ctx, isl_host_digest, "digest", 2));
9430
10789
  JS_SetPropertyStr(isl_ctx, host, "hmac", JS_NewCFunction(isl_ctx, isl_host_hmac, "hmac", 3));
10790
+ JS_SetPropertyStr(isl_ctx, host, "scrypt", JS_NewCFunction(isl_ctx, isl_host_scrypt, "scrypt", 7));
9431
10791
  JS_SetPropertyStr(isl_ctx, host, "fs", JS_NewCFunction(isl_ctx, isl_host_fs, "fs", 4));
9432
10792
  JS_SetPropertyStr(isl_ctx, host, "fsConstants", JS_NewCFunction(isl_ctx, isl_host_fs_constants, "fsConstants", 0));
9433
10793
  JS_SetPropertyStr(isl_ctx, host, "path", JS_NewCFunction(isl_ctx, isl_host_path, "path", 4));
9434
- JS_SetPropertyStr(isl_ctx, host, "urlToPath", JS_NewCFunction(isl_ctx, isl_host_url_to_path, "urlToPath", 1));
9435
- JS_SetPropertyStr(isl_ctx, host, "urlFromPath", JS_NewCFunction(isl_ctx, isl_host_url_from_path, "urlFromPath", 1));
10794
+ JS_SetPropertyStr(isl_ctx, host, "urlToPath", JS_NewCFunction(isl_ctx, isl_host_url_to_path, "urlToPath", 2));
10795
+ JS_SetPropertyStr(isl_ctx, host, "urlToPathBuffer", JS_NewCFunction(isl_ctx, isl_host_url_to_path_buffer, "urlToPathBuffer", 2));
10796
+ JS_SetPropertyStr(isl_ctx, host, "urlFromPath", JS_NewCFunction(isl_ctx, isl_host_url_from_path, "urlFromPath", 2));
9436
10797
  JS_SetPropertyStr(isl_ctx, host, "hrtime", JS_NewCFunction(isl_ctx, isl_host_hrtime, "hrtime", 0));
9437
10798
  JS_SetPropertyStr(isl_ctx, host, "versions", JS_NewCFunction(isl_ctx, isl_host_versions, "versions", 0));
9438
10799
  JS_SetPropertyStr(isl_ctx, host, "ids", JS_NewCFunction(isl_ctx, isl_host_ids, "ids", 0));
@@ -9809,30 +11170,22 @@ ScrJsval *scr_jsval_from_bytes(const ScrBytes *b) {
9809
11170
  * installs a minimal class: construction re-parses through the SAME
9810
11171
  * WHATWG parser the static URL uses (scr_url.c, via a host function), so
9811
11172
  * a marshaled URL and `new URL(href)` in embedded code agree exactly.
9812
- * href/protocol/pathname are the components the native accessors expose;
9813
- * the other component reads and ALL component writes throw a clear
9814
- * TypeError instead of silently diverging from the live re-serializing
9815
- * accessors a real URL has (SEMANTICS.md). If a URL global already exists
11173
+ * Component reads and writes share the native parser and setter
11174
+ * state overrides. If a URL global already exists
9816
11175
  * (a future web-prelude one, or embedded code's own), it wins — the
9817
11176
  * marshal constructs through whatever globalThis.URL is. */
9818
- static JSValue isl_url_parse_host(JSContext *ctx, JSValueConst this_val,
9819
- int argc, JSValueConst *argv) {
9820
- (void)this_val;
9821
- if (argc < 1) return JS_ThrowTypeError(ctx, "Invalid URL");
9822
- size_t len;
9823
- const char *s = JS_ToCStringLen(ctx, &len, argv[0]);
9824
- if (!s) return JS_EXCEPTION;
9825
- ScrStr *in = scr_str_new(s, len);
9826
- JS_FreeCString(ctx, s);
9827
- ScrUrl *u = scr_url_new(in);
9828
- scr_str_release(in);
9829
- if (!u) return isl_throw_pending(ctx); /* the parser's catchable TypeError */
11177
+ static JSValue isl_url_components(JSContext *ctx, ScrUrl *u) {
9830
11178
  ScrStr *href = scr_url_href(u);
9831
11179
  ScrStr *protocol = scr_url_protocol(u);
9832
11180
  ScrStr *pathname = scr_url_pathname(u);
9833
11181
  ScrStr *host = scr_url_host(u);
9834
11182
  ScrStr *hostname = scr_url_hostname(u);
9835
11183
  ScrStr *search = scr_url_search(u);
11184
+ ScrStr *origin = scr_url_origin(u);
11185
+ ScrStr *username = scr_url_username(u);
11186
+ ScrStr *password = scr_url_password(u);
11187
+ ScrStr *hash = scr_url_hash(u);
11188
+ ScrStr *port = scr_url_port(u);
9836
11189
  scr_url_release(u);
9837
11190
  JSValue arr = JS_NewArray(ctx);
9838
11191
  JS_SetPropertyUint32(ctx, arr, 0, JS_NewStringLen(ctx, href->data, href->len));
@@ -9841,123 +11194,147 @@ static JSValue isl_url_parse_host(JSContext *ctx, JSValueConst this_val,
9841
11194
  JS_SetPropertyUint32(ctx, arr, 3, JS_NewStringLen(ctx, host->data, host->len));
9842
11195
  JS_SetPropertyUint32(ctx, arr, 4, JS_NewStringLen(ctx, hostname->data, hostname->len));
9843
11196
  JS_SetPropertyUint32(ctx, arr, 5, JS_NewStringLen(ctx, search->data, search->len));
11197
+ JS_SetPropertyUint32(ctx, arr, 6, JS_NewStringLen(ctx, origin->data, origin->len));
11198
+ JS_SetPropertyUint32(ctx, arr, 7, JS_NewStringLen(ctx, username->data, username->len));
11199
+ JS_SetPropertyUint32(ctx, arr, 8, JS_NewStringLen(ctx, password->data, password->len));
11200
+ JS_SetPropertyUint32(ctx, arr, 9, JS_NewStringLen(ctx, hash->data, hash->len));
11201
+ JS_SetPropertyUint32(ctx, arr, 10, JS_NewStringLen(ctx, port->data, port->len));
9844
11202
  scr_str_release(href);
9845
11203
  scr_str_release(protocol);
9846
11204
  scr_str_release(pathname);
9847
11205
  scr_str_release(host);
9848
11206
  scr_str_release(hostname);
9849
11207
  scr_str_release(search);
11208
+ scr_str_release(origin);
11209
+ scr_str_release(username);
11210
+ scr_str_release(password);
11211
+ scr_str_release(hash);
11212
+ scr_str_release(port);
9850
11213
  return arr;
9851
11214
  }
9852
11215
 
11216
+ static JSValue isl_url_parse_host(JSContext *ctx, JSValueConst this_val,
11217
+ int argc, JSValueConst *argv) {
11218
+ (void)this_val;
11219
+ if (argc < 1) return JS_ThrowTypeError(ctx, "Invalid URL");
11220
+ ScrStr *in = isl_arg_str(ctx, argv[0]);
11221
+ if (!in) return JS_EXCEPTION;
11222
+ ScrStr *base = argc > 1 && !JS_IsUndefined(argv[1]) ? isl_arg_str(ctx, argv[1]) : NULL;
11223
+ if (argc > 1 && !JS_IsUndefined(argv[1]) && !base) {
11224
+ scr_str_release(in);
11225
+ return JS_EXCEPTION;
11226
+ }
11227
+ ScrUrl *u = base ? scr_url_new_base(in, base) : scr_url_new(in);
11228
+ scr_str_release(in);
11229
+ scr_str_release(base);
11230
+ if (!u) {
11231
+ if (argc > 2 && JS_ToBool(ctx, argv[2])) {
11232
+ scr_exc_clear();
11233
+ return JS_NULL;
11234
+ }
11235
+ return isl_throw_pending(ctx);
11236
+ }
11237
+ return isl_url_components(ctx, u);
11238
+ }
11239
+
11240
+ static JSValue isl_url_set_host(JSContext *ctx, JSValueConst this_val,
11241
+ int argc, JSValueConst *argv) {
11242
+ (void)this_val;
11243
+ if (argc < 3) return JS_ThrowTypeError(ctx, "Invalid URL");
11244
+ ScrStr *href = isl_arg_str(ctx, argv[0]);
11245
+ if (!href) return JS_EXCEPTION;
11246
+ ScrStr *field = isl_arg_str(ctx, argv[1]);
11247
+ if (!field) { scr_str_release(href); return JS_EXCEPTION; }
11248
+ ScrStr *value = isl_arg_str(ctx, argv[2]);
11249
+ if (!value) { scr_str_release(href); scr_str_release(field); return JS_EXCEPTION; }
11250
+ ScrUrl *u = scr_url_new(href);
11251
+ scr_str_release(href);
11252
+ bool applied = u && scr_url_set_component(u, field, value);
11253
+ scr_str_release(field);
11254
+ scr_str_release(value);
11255
+ if (!u || scr_exc_pending()) {
11256
+ scr_url_release(u);
11257
+ return isl_throw_pending(ctx);
11258
+ }
11259
+ if (!applied) { scr_url_release(u); return JS_NULL; }
11260
+ return isl_url_components(ctx, u);
11261
+ }
11262
+
9853
11263
  static const char isl_url_src[] =
9854
- "(function (parse) {\n"
11264
+ "(function (parse, mutate) {\n"
9855
11265
  " 'use strict';\n"
9856
- " const def = (o, n, v) => Object.defineProperty(o, n, { value: v, enumerable: true });\n"
11266
+ " const text = (v) => {\n"
11267
+ " if (typeof v === 'symbol') throw new TypeError('Cannot convert a Symbol value to a string');\n"
11268
+ " return `${v}`;\n"
11269
+ " };\n"
11270
+ " const fields = ['href', 'protocol', 'pathname', 'host', 'hostname', 'search', 'origin', 'username', 'password', 'hash', 'port'];\n"
9857
11271
  " class URL {\n"
9858
- /* The (input, base) form supports RELATIVE resolution — the Emscripten
9859
- * loader's `new URL("x.wasm", import.meta.url)` — with RFC 3986
9860
- * dot-segment removal over the base's path. Inputs that carry their
9861
- * own scheme ignore the base (per spec); protocol-relative inputs
9862
- * keep a narrow fence. */
9863
11272
  " constructor(input, base) {\n"
9864
- " let s = String(input);\n"
9865
- " const hasScheme = /^[A-Za-z][A-Za-z0-9+.-]*:/;\n"
9866
- " if (base !== undefined && !hasScheme.test(s)) {\n"
9867
- " const b = String(base !== null && typeof base === 'object' && 'href' in base ? base.href : base);\n"
9868
- " const m = hasScheme.test(b) && b.match(/^([A-Za-z][A-Za-z0-9+.-]*:)(\\/\\/[^\\/?#]*)?([^?#]*)/);\n"
9869
- " if (!m) throw new TypeError('Invalid base URL');\n"
9870
- " if (s.startsWith('//')) {\n"
9871
- " throw new TypeError('protocol-relative URLs are not supported in the scriptc island yet');\n"
9872
- " }\n"
9873
- " let path = s.startsWith('/') ? s : (m[3] || '/').replace(/[^\\/]*$/, '') + s;\n"
9874
- " const out = [];\n"
9875
- " for (const seg of path.split('/')) {\n"
9876
- " if (seg === '.') continue;\n"
9877
- " if (seg === '..') { if (out.length > 1) out.pop(); continue; }\n"
9878
- " out.push(seg);\n"
9879
- " }\n"
9880
- " s = m[1] + (m[2] || '') + out.join('/');\n"
9881
- " }\n"
9882
- " const c = parse(s);\n"
9883
- /* href and search are LIVE-COUPLED (the one WHATWG mutation loop the
9884
- * a real CLI's API client drives: url.searchParams.set('teamId', …)
9885
- * then fetch(url)): both live in writable slots, the search setter
9886
- * recomposes href around the old query, and the searchParams getter
9887
- * hands out ONE URLSearchParams whose mutators write back through
9888
- * it. The other components stay parse-time snapshots. */
9889
- " Object.defineProperty(this, '_href', { value: c[0], writable: true });\n"
9890
- " Object.defineProperty(this, '_search', { value: c[5], writable: true });\n"
9891
- " const self = this;\n"
9892
- " Object.defineProperty(this, 'href', { enumerable: true, get: () => self._href });\n"
9893
- " Object.defineProperty(this, 'search', {\n"
9894
- " enumerable: true,\n"
9895
- " get: () => self._search,\n"
9896
- " set: (v) => {\n"
9897
- " self._applySearch(String(v));\n"
9898
- " if (self._sp !== undefined) {\n"
9899
- " self._sp._pairs.length = 0;\n"
9900
- " for (const [k, val] of new globalThis.URLSearchParams(self._search)) self._sp._pairs.push([k, val]);\n"
9901
- " }\n"
9902
- " },\n"
9903
- " });\n"
9904
- " def(this, 'protocol', c[1]);\n"
9905
- " def(this, 'pathname', c[2]);\n"
9906
- " def(this, 'host', c[3]);\n"
9907
- " def(this, 'hostname', c[4]);\n"
9908
- " def(this, 'port', c[3].length > c[4].length ? c[3].slice(c[4].length + 1) : '');\n"
9909
- " const hashAt = c[0].indexOf('#');\n"
9910
- " def(this, 'hash', hashAt < 0 ? '' : c[0].slice(hashAt));\n"
9911
- " const cred = c[3] !== '' && c[0].startsWith(c[1] + '//')\n"
9912
- " ? c[0].slice(c[1].length + 2, c[0].indexOf(c[3], c[1].length + 2)) : '';\n"
9913
- " const at = cred.lastIndexOf('@');\n"
9914
- " const userinfo = at < 0 ? '' : cred.slice(0, at);\n"
9915
- " const colon = userinfo.indexOf(':');\n"
9916
- " def(this, 'username', colon < 0 ? userinfo : userinfo.slice(0, colon));\n"
9917
- " def(this, 'password', colon < 0 ? '' : userinfo.slice(colon + 1));\n"
9918
- " def(this, 'origin', (c[1] === 'http:' || c[1] === 'https:' || c[1] === 'ws:' || c[1] === 'wss:' || c[1] === 'ftp:')\n"
9919
- " ? c[1] + '//' + c[3] : 'null');\n"
9920
- " }\n"
9921
- /* The search half of the live coupling: normalize the assigned
9922
- * query, splice it into href between the pre-query part and the
9923
- * fragment. */
9924
- " _applySearch(v) {\n"
9925
- " let s = String(v);\n"
9926
- " if (s !== '' && !s.startsWith('?')) s = '?' + s;\n"
9927
- " if (s === '?') s = '';\n"
9928
- " const base = this._href.split('#')[0].split('?')[0];\n"
9929
- " this._search = s;\n"
9930
- " this._href = base + s + this.hash;\n"
9931
- " }\n"
9932
- /* searchParams: ONE URLSearchParams per URL (identity stable, like
9933
- * the spec) whose mutators — append/set/delete/sort — write the
9934
- * serialized list back into search/href. Reads AND writes agree with
9935
- * Node for the query component; the other components stay parse-time
9936
- * snapshots. */
11273
+ " if (arguments.length === 0) throw URL._missing();\n"
11274
+ " const s = text(input);\n"
11275
+ " const b = base === undefined ? undefined : text(base);\n"
11276
+ " this._init(parse(s, b));\n"
11277
+ " }\n"
11278
+ " static _missing() {\n"
11279
+ " const error = new TypeError('The \"url\" argument must be specified');\n"
11280
+ " error.code = 'ERR_MISSING_ARGS';\n"
11281
+ " return error;\n"
11282
+ " }\n"
11283
+ " _init(c) {\n"
11284
+ " Object.defineProperty(this, '_components', { value: c, writable: true });\n"
11285
+ " for (let i = 0; i < fields.length; i++) {\n"
11286
+ " const name = fields[i];\n"
11287
+ " const descriptor = { enumerable: true, get: () => this._components[i] };\n"
11288
+ " if (name !== 'origin') descriptor.set = (v) => this._set(name, v);\n"
11289
+ " Object.defineProperty(this, name, descriptor);\n"
11290
+ " }\n"
11291
+ " }\n"
11292
+ " _set(name, value) {\n"
11293
+ " const href = this.href;\n"
11294
+ " const ignored = name === 'pathname' && !href.slice(this.protocol.length).startsWith('/');\n"
11295
+ " const converted = text(value);\n"
11296
+ " if (ignored) return;\n"
11297
+ " const components = mutate(name === 'href' ? this.href : href, name, converted);\n"
11298
+ " if (components === null) return;\n"
11299
+ " this._components = components;\n"
11300
+ " if ((name === 'search' || name === 'href') && this._sp !== undefined) {\n"
11301
+ " this._sp._pairs.length = 0;\n"
11302
+ " for (const [k, v] of new globalThis.URLSearchParams(this.search)) this._sp._pairs.push([k, v]);\n"
11303
+ " }\n"
11304
+ " }\n"
9937
11305
  " get searchParams() {\n"
9938
11306
  " if (this._sp === undefined) {\n"
9939
11307
  " const sp = new globalThis.URLSearchParams(this.search);\n"
9940
11308
  " const sync = () => {\n"
9941
11309
  " const q = sp.toString();\n"
9942
- " this._applySearch(q === '' ? '' : '?' + q);\n"
11310
+ " this._set('search', q === '' ? '' : '?' + q);\n"
9943
11311
  " };\n"
9944
11312
  " for (const m of ['append', 'set', 'delete', 'sort']) {\n"
9945
11313
  " const orig = sp[m].bind(sp);\n"
9946
- " Object.defineProperty(sp, m, {\n"
9947
- " value: (...args) => { const r = orig(...args); sync(); return r; },\n"
9948
- " });\n"
11314
+ " Object.defineProperty(sp, m, { value: (...args) => { const r = orig(...args); sync(); return r; } });\n"
9949
11315
  " }\n"
9950
11316
  " Object.defineProperty(this, '_sp', { value: sp });\n"
9951
11317
  " }\n"
9952
11318
  " return this._sp;\n"
9953
11319
  " }\n"
11320
+ " get href() { throw new TypeError('Receiver must be an instance of class URL'); }\n"
9954
11321
  " toString() { return this.href; }\n"
9955
11322
  " toJSON() { return this.href; }\n"
9956
11323
  " static canParse(input, base) {\n"
9957
- " try { new URL(input, base); return true; } catch (e) { return false; }\n"
11324
+ " if (arguments.length === 0) throw URL._missing();\n"
11325
+ " const s = text(input);\n"
11326
+ " const b = base === undefined ? undefined : text(base);\n"
11327
+ " return parse(s, b, true) !== null;\n"
9958
11328
  " }\n"
9959
11329
  " static parse(input, base) {\n"
9960
- " try { return new URL(input, base); } catch (e) { return null; }\n"
11330
+ " if (arguments.length === 0) throw URL._missing();\n"
11331
+ " const s = text(input);\n"
11332
+ " const b = base === undefined ? undefined : text(base);\n"
11333
+ " const c = parse(s, b, true);\n"
11334
+ " if (c === null) return null;\n"
11335
+ " const result = Object.create(URL.prototype);\n"
11336
+ " result._init(c);\n"
11337
+ " return result;\n"
9961
11338
  " }\n"
9962
11339
  " }\n"
9963
11340
  " globalThis.URL = URL;\n"
@@ -9976,8 +11353,11 @@ static void isl_install_url_class(void) {
9976
11353
  fprintf(stderr, "scriptc: island URL prelude failed to evaluate\n");
9977
11354
  abort(); /* fixed source; failing to parse is a build defect */
9978
11355
  }
9979
- JSValue parse = JS_NewCFunction(isl_ctx, isl_url_parse_host, "__scr_url_parse", 1);
9980
- JSValue r = JS_Call(isl_ctx, installer, JS_UNDEFINED, 1, &parse);
11356
+ JSValue parse = JS_NewCFunction(isl_ctx, isl_url_parse_host, "__scr_url_parse", 3);
11357
+ JSValue mutate = JS_NewCFunction(isl_ctx, isl_url_set_host, "__scr_url_set", 3);
11358
+ JSValue args[2] = {parse, mutate};
11359
+ JSValue r = JS_Call(isl_ctx, installer, JS_UNDEFINED, 2, args);
11360
+ JS_FreeValue(isl_ctx, mutate);
9981
11361
  JS_FreeValue(isl_ctx, parse);
9982
11362
  JS_FreeValue(isl_ctx, installer);
9983
11363
  if (JS_IsException(r)) {