visaljs 0.0.10 → 0.0.11

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 (221) hide show
  1. package/README.md +12 -4
  2. package/THIRD_PARTY_LICENSES +31 -1
  3. package/cli.js +962 -68
  4. package/node/include/js_node.h +11 -1
  5. package/node/prelude/_http_common.js +29 -0
  6. package/node/prelude/async_hooks.js +50 -11
  7. package/node/prelude/child_process.js +31 -4
  8. package/node/prelude/console.js +311 -143
  9. package/node/prelude/crypto.js +6 -4
  10. package/node/prelude/dgram.js +1169 -0
  11. package/node/prelude/diagnostics_channel.js +3 -1
  12. package/node/prelude/dns.js +250 -45
  13. package/node/prelude/dns_promises.js +8 -2
  14. package/node/prelude/fs_promises.js +9 -1
  15. package/node/prelude/http.js +395 -86
  16. package/node/prelude/https.js +13 -4
  17. package/node/prelude/internal/console_class.js +7 -0
  18. package/node/prelude/internal/console_global.js +25 -0
  19. package/node/prelude/internal/crypto/key_encryption.js +217 -0
  20. package/node/prelude/internal/crypto/keys.js +161 -26
  21. package/node/prelude/internal/crypto/random.js +24 -0
  22. package/node/prelude/internal/crypto/util.js +2 -1
  23. package/node/prelude/internal/crypto_x509.js +161 -0
  24. package/node/prelude/internal/dns_classes.js +6 -0
  25. package/node/prelude/internal/dns_resolver.js +371 -0
  26. package/node/prelude/internal/errors.js +9 -0
  27. package/node/prelude/internal/events_on.js +82 -37
  28. package/node/prelude/internal/features.js +8 -4
  29. package/node/prelude/internal/fs_filehandle.js +10 -4
  30. package/node/prelude/internal/perf_histogram.js +1 -1
  31. package/node/prelude/internal/process_more.js +32 -17
  32. package/node/prelude/internal/process_signals.js +8 -2
  33. package/node/prelude/internal/punycode.ts +163 -0
  34. package/node/prelude/internal/readline.js +648 -274
  35. package/node/prelude/internal/readline_editor.js +1240 -0
  36. package/node/prelude/internal/string_width.js +43 -0
  37. package/node/prelude/internal/tls/common.js +145 -33
  38. package/node/prelude/internal/tls/wrap.js +182 -49
  39. package/node/prelude/internal/tls/x509.js +4 -1
  40. package/node/prelude/internal/udp.js +177 -0
  41. package/node/prelude/net.js +13 -1
  42. package/node/prelude/os.js +24 -6
  43. package/node/prelude/perf_hooks.js +37 -2
  44. package/node/prelude/punycode.js +2 -130
  45. package/node/prelude/readline.js +113 -4
  46. package/node/prelude/readline_promises.js +56 -32
  47. package/node/prelude/tls.js +21 -4
  48. package/node/prelude/util.js +3 -16
  49. package/node/src/host_dns.c +623 -0
  50. package/node/src/host_http.c +12 -0
  51. package/node/src/host_net.c +46 -0
  52. package/node/src/host_os.c +1 -6
  53. package/node/src/host_sys.c +70 -0
  54. package/node/src/host_udp.c +418 -0
  55. package/node/third_party/c-ares/LICENSE.md +24 -0
  56. package/node/third_party/c-ares/config/darwin/ares_config.h +573 -0
  57. package/node/third_party/c-ares/config/freebsd/ares_config.h +573 -0
  58. package/node/third_party/c-ares/config/linux/ares_config.h +573 -0
  59. package/node/third_party/c-ares/config/openbsd/ares_config.h +583 -0
  60. package/node/third_party/c-ares/include/ares.h +1237 -0
  61. package/node/third_party/c-ares/include/ares_build.h +202 -0
  62. package/node/third_party/c-ares/include/ares_dns.h +127 -0
  63. package/node/third_party/c-ares/include/ares_dns_record.h +1119 -0
  64. package/node/third_party/c-ares/include/ares_nameser.h +510 -0
  65. package/node/third_party/c-ares/include/ares_version.h +47 -0
  66. package/node/third_party/c-ares/src/lib/ares_addrinfo2hostent.c +305 -0
  67. package/node/third_party/c-ares/src/lib/ares_addrinfo_localhost.c +245 -0
  68. package/node/third_party/c-ares/src/lib/ares_android.c +496 -0
  69. package/node/third_party/c-ares/src/lib/ares_android.h +38 -0
  70. package/node/third_party/c-ares/src/lib/ares_cancel.c +87 -0
  71. package/node/third_party/c-ares/src/lib/ares_close_sockets.c +137 -0
  72. package/node/third_party/c-ares/src/lib/ares_conn.c +511 -0
  73. package/node/third_party/c-ares/src/lib/ares_conn.h +202 -0
  74. package/node/third_party/c-ares/src/lib/ares_cookie.c +461 -0
  75. package/node/third_party/c-ares/src/lib/ares_data.c +168 -0
  76. package/node/third_party/c-ares/src/lib/ares_data.h +92 -0
  77. package/node/third_party/c-ares/src/lib/ares_destroy.c +159 -0
  78. package/node/third_party/c-ares/src/lib/ares_free_hostent.c +54 -0
  79. package/node/third_party/c-ares/src/lib/ares_free_string.c +33 -0
  80. package/node/third_party/c-ares/src/lib/ares_freeaddrinfo.c +67 -0
  81. package/node/third_party/c-ares/src/lib/ares_getaddrinfo.c +806 -0
  82. package/node/third_party/c-ares/src/lib/ares_getenv.c +38 -0
  83. package/node/third_party/c-ares/src/lib/ares_getenv.h +34 -0
  84. package/node/third_party/c-ares/src/lib/ares_gethostbyaddr.c +229 -0
  85. package/node/third_party/c-ares/src/lib/ares_gethostbyname.c +341 -0
  86. package/node/third_party/c-ares/src/lib/ares_getnameinfo.c +437 -0
  87. package/node/third_party/c-ares/src/lib/ares_hosts_file.c +960 -0
  88. package/node/third_party/c-ares/src/lib/ares_inet_net_pton.h +31 -0
  89. package/node/third_party/c-ares/src/lib/ares_init.c +631 -0
  90. package/node/third_party/c-ares/src/lib/ares_ipv6.h +115 -0
  91. package/node/third_party/c-ares/src/lib/ares_library_init.c +190 -0
  92. package/node/third_party/c-ares/src/lib/ares_metrics.c +261 -0
  93. package/node/third_party/c-ares/src/lib/ares_options.c +492 -0
  94. package/node/third_party/c-ares/src/lib/ares_parse_into_addrinfo.c +179 -0
  95. package/node/third_party/c-ares/src/lib/ares_private.h +648 -0
  96. package/node/third_party/c-ares/src/lib/ares_process.c +1649 -0
  97. package/node/third_party/c-ares/src/lib/ares_qcache.c +442 -0
  98. package/node/third_party/c-ares/src/lib/ares_query.c +151 -0
  99. package/node/third_party/c-ares/src/lib/ares_search.c +623 -0
  100. package/node/third_party/c-ares/src/lib/ares_send.c +300 -0
  101. package/node/third_party/c-ares/src/lib/ares_set_socket_functions.c +590 -0
  102. package/node/third_party/c-ares/src/lib/ares_setup.h +224 -0
  103. package/node/third_party/c-ares/src/lib/ares_socket.c +427 -0
  104. package/node/third_party/c-ares/src/lib/ares_socket.h +163 -0
  105. package/node/third_party/c-ares/src/lib/ares_sortaddrinfo.c +447 -0
  106. package/node/third_party/c-ares/src/lib/ares_strerror.c +91 -0
  107. package/node/third_party/c-ares/src/lib/ares_sysconfig.c +642 -0
  108. package/node/third_party/c-ares/src/lib/ares_sysconfig_files.c +851 -0
  109. package/node/third_party/c-ares/src/lib/ares_sysconfig_mac.c +373 -0
  110. package/node/third_party/c-ares/src/lib/ares_sysconfig_win.c +673 -0
  111. package/node/third_party/c-ares/src/lib/ares_timeout.c +162 -0
  112. package/node/third_party/c-ares/src/lib/ares_update_servers.c +1376 -0
  113. package/node/third_party/c-ares/src/lib/ares_version.c +36 -0
  114. package/node/third_party/c-ares/src/lib/config-dos.h +114 -0
  115. package/node/third_party/c-ares/src/lib/config-win32.h +396 -0
  116. package/node/third_party/c-ares/src/lib/dsa/ares_array.c +409 -0
  117. package/node/third_party/c-ares/src/lib/dsa/ares_htable.c +451 -0
  118. package/node/third_party/c-ares/src/lib/dsa/ares_htable.h +174 -0
  119. package/node/third_party/c-ares/src/lib/dsa/ares_htable_asvp.c +224 -0
  120. package/node/third_party/c-ares/src/lib/dsa/ares_htable_dict.c +230 -0
  121. package/node/third_party/c-ares/src/lib/dsa/ares_htable_strvp.c +210 -0
  122. package/node/third_party/c-ares/src/lib/dsa/ares_htable_szvp.c +188 -0
  123. package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpstr.c +186 -0
  124. package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpvp.c +194 -0
  125. package/node/third_party/c-ares/src/lib/dsa/ares_llist.c +385 -0
  126. package/node/third_party/c-ares/src/lib/dsa/ares_slist.c +479 -0
  127. package/node/third_party/c-ares/src/lib/dsa/ares_slist.h +207 -0
  128. package/node/third_party/c-ares/src/lib/event/ares_event.h +191 -0
  129. package/node/third_party/c-ares/src/lib/event/ares_event_configchg.c +746 -0
  130. package/node/third_party/c-ares/src/lib/event/ares_event_epoll.c +192 -0
  131. package/node/third_party/c-ares/src/lib/event/ares_event_kqueue.c +248 -0
  132. package/node/third_party/c-ares/src/lib/event/ares_event_poll.c +140 -0
  133. package/node/third_party/c-ares/src/lib/event/ares_event_select.c +159 -0
  134. package/node/third_party/c-ares/src/lib/event/ares_event_thread.c +575 -0
  135. package/node/third_party/c-ares/src/lib/event/ares_event_wake_pipe.c +172 -0
  136. package/node/third_party/c-ares/src/lib/event/ares_event_win32.c +981 -0
  137. package/node/third_party/c-ares/src/lib/event/ares_event_win32.h +161 -0
  138. package/node/third_party/c-ares/src/lib/include/ares_array.h +276 -0
  139. package/node/third_party/c-ares/src/lib/include/ares_buf.h +732 -0
  140. package/node/third_party/c-ares/src/lib/include/ares_htable_asvp.h +130 -0
  141. package/node/third_party/c-ares/src/lib/include/ares_htable_dict.h +123 -0
  142. package/node/third_party/c-ares/src/lib/include/ares_htable_strvp.h +130 -0
  143. package/node/third_party/c-ares/src/lib/include/ares_htable_szvp.h +118 -0
  144. package/node/third_party/c-ares/src/lib/include/ares_htable_vpstr.h +111 -0
  145. package/node/third_party/c-ares/src/lib/include/ares_htable_vpvp.h +128 -0
  146. package/node/third_party/c-ares/src/lib/include/ares_llist.h +239 -0
  147. package/node/third_party/c-ares/src/lib/include/ares_mem.h +41 -0
  148. package/node/third_party/c-ares/src/lib/include/ares_str.h +261 -0
  149. package/node/third_party/c-ares/src/lib/inet_net_pton.c +451 -0
  150. package/node/third_party/c-ares/src/lib/inet_ntop.c +219 -0
  151. package/node/third_party/c-ares/src/lib/legacy/ares_create_query.c +78 -0
  152. package/node/third_party/c-ares/src/lib/legacy/ares_expand_name.c +99 -0
  153. package/node/third_party/c-ares/src/lib/legacy/ares_expand_string.c +107 -0
  154. package/node/third_party/c-ares/src/lib/legacy/ares_fds.c +80 -0
  155. package/node/third_party/c-ares/src/lib/legacy/ares_getsock.c +85 -0
  156. package/node/third_party/c-ares/src/lib/legacy/ares_parse_a_reply.c +107 -0
  157. package/node/third_party/c-ares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
  158. package/node/third_party/c-ares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
  159. package/node/third_party/c-ares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
  160. package/node/third_party/c-ares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
  161. package/node/third_party/c-ares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
  162. package/node/third_party/c-ares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
  163. package/node/third_party/c-ares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
  164. package/node/third_party/c-ares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
  165. package/node/third_party/c-ares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
  166. package/node/third_party/c-ares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
  167. package/node/third_party/c-ares/src/lib/record/ares_dns_mapping.c +982 -0
  168. package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.c +309 -0
  169. package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.h +72 -0
  170. package/node/third_party/c-ares/src/lib/record/ares_dns_name.c +736 -0
  171. package/node/third_party/c-ares/src/lib/record/ares_dns_parse.c +1360 -0
  172. package/node/third_party/c-ares/src/lib/record/ares_dns_private.h +273 -0
  173. package/node/third_party/c-ares/src/lib/record/ares_dns_record.c +1701 -0
  174. package/node/third_party/c-ares/src/lib/record/ares_dns_write.c +1229 -0
  175. package/node/third_party/c-ares/src/lib/str/ares_buf.c +1510 -0
  176. package/node/third_party/c-ares/src/lib/str/ares_str.c +562 -0
  177. package/node/third_party/c-ares/src/lib/str/ares_strsplit.c +90 -0
  178. package/node/third_party/c-ares/src/lib/str/ares_strsplit.h +51 -0
  179. package/node/third_party/c-ares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
  180. package/node/third_party/c-ares/src/lib/util/ares_iface_ips.c +640 -0
  181. package/node/third_party/c-ares/src/lib/util/ares_iface_ips.h +140 -0
  182. package/node/third_party/c-ares/src/lib/util/ares_math.c +167 -0
  183. package/node/third_party/c-ares/src/lib/util/ares_math.h +58 -0
  184. package/node/third_party/c-ares/src/lib/util/ares_rand.c +389 -0
  185. package/node/third_party/c-ares/src/lib/util/ares_rand.h +36 -0
  186. package/node/third_party/c-ares/src/lib/util/ares_threads.c +613 -0
  187. package/node/third_party/c-ares/src/lib/util/ares_threads.h +60 -0
  188. package/node/third_party/c-ares/src/lib/util/ares_time.h +49 -0
  189. package/node/third_party/c-ares/src/lib/util/ares_timeval.c +95 -0
  190. package/node/third_party/c-ares/src/lib/util/ares_uri.c +1627 -0
  191. package/node/third_party/c-ares/src/lib/util/ares_uri.h +252 -0
  192. package/node/third_party/c-ares/src/lib/windows_port.c +29 -0
  193. package/package.json +1 -1
  194. package/prebuilt/darwin-arm64/cares-a6286c65ca9374a3.a +0 -0
  195. package/prebuilt/darwin-x64/cares-a6286c65ca9374a3.a +0 -0
  196. package/prebuilt/linux-arm64/cares-4ba05ac8e948af8e.a +0 -0
  197. package/prebuilt/linux-arm64-musl/cares-4ba05ac8e948af8e.a +0 -0
  198. package/prebuilt/linux-x64/cares-4ba05ac8e948af8e.a +0 -0
  199. package/prebuilt/linux-x64-musl/cares-4ba05ac8e948af8e.a +0 -0
  200. package/prebuilt/win32-x64/boringssl-ce573858472b7fc9.a +0 -0
  201. package/prebuilt/win32-x64/brotli-20d86a61f30baeb3.a +0 -0
  202. package/prebuilt/win32-x64/cares-49c9ec95162b912d.a +0 -0
  203. package/prebuilt/win32-x64/uv-b11bae65d7fced82.a +0 -0
  204. package/prebuilt/win32-x64/zlib-4ce2317a4c3f5fb5.a +0 -0
  205. package/prebuilt/win32-x64/zstd-015315ac7c784c73.a +0 -0
  206. package/runtime/include/js_builtins.h +5 -0
  207. package/runtime/include/js_crypto.h +11 -0
  208. package/runtime/include/js_gc.h +13 -10
  209. package/runtime/include/js_jobs.h +2 -0
  210. package/runtime/include/js_object.h +58 -0
  211. package/runtime/include/jscontext.h +1 -0
  212. package/runtime/src/crypto_internal.h +1 -0
  213. package/runtime/src/crypto_subtle.c +66 -7
  214. package/runtime/src/crypto_tls.c +265 -19
  215. package/runtime/src/gc.c +73 -92
  216. package/runtime/src/inspect.c +18 -1
  217. package/runtime/src/jobs.c +37 -22
  218. package/runtime/src/object.c +49 -2
  219. package/runtime/src/os.c +16 -6
  220. package/runtime/src/os.h +2 -0
  221. package/runtime/src/process.c +97 -10
@@ -1,9 +1,17 @@
1
- // events.on: an emitter's or EventTarget's events as an async iterator. Linked into programs that
2
- // name it (internal/features.js).
3
- import { invalidArgType } from "./errors.js";
1
+ // events.on (Node's lib/events.js): an emitter's or EventTarget's events as an async iterator,
2
+ // buffered until read, the emitter paused above highWaterMark and resumed below lowWaterMark.
3
+ // Linked into programs that name it (internal/features.js), and with node:readline's iterator.
4
+ // Ported from Node.js (Copyright Node.js contributors, MIT): node/third_party/nodejs/LICENSE.
5
+ import { invalidArgType, outOfRange } from "./errors.js";
4
6
  import { features } from "./features.js";
5
7
 
6
- const isEventTarget = (target) => typeof target?.addEventListener === "function" && typeof target?.on !== "function";
8
+ /* the iterator's watermarks and state (events.on's [kWatermarkData]) */
9
+ const kWatermarkData = Symbol.for("nodejs.watermarkData");
10
+ /** Node's internal option: each event's first argument, not an array of them (readline's lines).
11
+ * In the registry: readline's iterator names it without linking this module. */
12
+ export const kFirstEventParam = Symbol.for("visaljs.events.kFirstEventParam");
13
+
14
+ const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(async function* () {}).prototype);
7
15
 
8
16
  function validateSignal(signal, name) {
9
17
  if (signal !== undefined && (signal === null || typeof signal !== "object" || !("aborted" in signal))) {
@@ -11,6 +19,12 @@ function validateSignal(signal, name) {
11
19
  }
12
20
  }
13
21
 
22
+ function validateWatermark(value, name) {
23
+ if (typeof value !== "number") throw invalidArgType(name, "of type number", value);
24
+ if (!Number.isInteger(value)) throw outOfRange(name, "an integer", value);
25
+ if (value < 1 || value > Number.MAX_SAFE_INTEGER) throw outOfRange(name, `>= 1 && <= ${Number.MAX_SAFE_INTEGER}`, value);
26
+ }
27
+
14
28
  /* Node's AbortError: name and code, the signal's reason as its cause */
15
29
  function abortError(signal) {
16
30
  const error = new Error("The operation was aborted", { cause: signal?.reason });
@@ -19,29 +33,48 @@ function abortError(signal) {
19
33
  return error;
20
34
  }
21
35
 
22
- /** events.on(emitter, name[, { signal, close }]): the events as an async iterator of their
23
- * arguments, buffered until read; an 'error' ends it by throwing, a `close` event by finishing. */
24
- function on(emitter, event, options = {}) {
25
- const signal = options?.signal;
36
+ function addListener(emitter, name, listener) {
37
+ if (typeof emitter.on === "function") emitter.on(name, listener);
38
+ else if (typeof emitter.addEventListener === "function") emitter.addEventListener(name, listener);
39
+ else throw invalidArgType("emitter", "an instance of EventEmitter", emitter);
40
+ }
41
+
42
+ function removeListener(emitter, name, listener) {
43
+ if (typeof emitter.removeListener === "function") emitter.removeListener(name, listener);
44
+ else if (typeof emitter.removeEventListener === "function") emitter.removeEventListener(name, listener);
45
+ else throw invalidArgType("emitter", "an instance of EventEmitter", emitter);
46
+ }
47
+
48
+ const iterResult = (value, done) => ({ value, done });
49
+
50
+ /** events.on(emitter, name[, { signal, close, highWaterMark, lowWaterMark }]) */
51
+ export function on(emitter, event, options = {}) {
52
+ if (typeof options !== "object" || options === null || Array.isArray(options)) throw invalidArgType("options", "of type object", options);
53
+ const signal = options.signal;
26
54
  validateSignal(signal, "options.signal");
27
55
  if (signal?.aborted) throw abortError(signal);
28
- const close = options?.close ?? [];
56
+ const highWatermark = options.highWaterMark ?? options.highWatermark ?? Number.MAX_SAFE_INTEGER;
57
+ validateWatermark(highWatermark, "options.highWaterMark");
58
+ const lowWatermark = options.lowWaterMark ?? options.lowWatermark ?? 1;
59
+ validateWatermark(lowWatermark, "options.lowWaterMark");
60
+
29
61
  const unconsumedEvents = [];
30
62
  const unconsumedPromises = [];
63
+ let paused = false;
31
64
  let error = null;
32
65
  let finished = false;
33
66
  const listening = [];
34
- const listen = (name, handler) => {
35
- if (isEventTarget(emitter)) emitter.addEventListener(name, handler);
36
- else emitter.on(name, handler);
37
- listening.push([name, handler]);
38
- };
39
- const result = (value, done) => ({ value, done });
40
67
 
41
- const iterator = {
68
+ const iterator = Object.setPrototypeOf({
42
69
  next() {
43
- const value = unconsumedEvents.shift();
44
- if (value) return Promise.resolve(result(value, false));
70
+ if (unconsumedEvents.length) {
71
+ const value = unconsumedEvents.shift();
72
+ if (paused && unconsumedEvents.length < lowWatermark) {
73
+ emitter.resume();
74
+ paused = false;
75
+ }
76
+ return Promise.resolve(iterResult(value, false));
77
+ }
45
78
  if (error) {
46
79
  const p = Promise.reject(error);
47
80
  error = null;
@@ -54,45 +87,57 @@ function on(emitter, event, options = {}) {
54
87
  return closeHandler();
55
88
  },
56
89
  throw(err) {
57
- if (!(err instanceof Error)) throw invalidArgType("EventEmitter.AsyncIterator", "an instance of Error", err);
90
+ if (!err || !(err instanceof Error)) throw invalidArgType("EventEmitter.AsyncIterator", "an instance of Error", err);
58
91
  errorHandler(err);
59
92
  },
60
93
  [Symbol.asyncIterator]() {
61
94
  return this;
62
95
  },
96
+ [kWatermarkData]: {
97
+ get size() { return unconsumedEvents.length; },
98
+ get low() { return lowWatermark; },
99
+ get high() { return highWatermark; },
100
+ get isPaused() { return paused; },
101
+ },
102
+ }, AsyncIteratorPrototype);
103
+
104
+ const listen = (name, handler) => {
105
+ addListener(emitter, name, handler);
106
+ listening.push([name, handler]);
63
107
  };
64
108
 
65
- function eventHandler(...args) {
66
- const pending = unconsumedPromises.shift();
67
- if (pending) pending.resolve(result(args, false));
68
- else unconsumedEvents.push(args);
109
+ function eventHandler(value) {
110
+ if (unconsumedPromises.length === 0) {
111
+ if (!paused && unconsumedEvents.length + 1 > highWatermark) {
112
+ paused = true;
113
+ emitter.pause();
114
+ }
115
+ unconsumedEvents.push(value);
116
+ } else {
117
+ unconsumedPromises.shift().resolve(iterResult(value, false));
118
+ }
69
119
  }
70
120
  function errorHandler(err) {
71
- finished = true;
72
- const pending = unconsumedPromises.shift();
73
- if (pending) pending.reject(err);
74
- else error = err;
75
- iterator.return();
121
+ if (unconsumedPromises.length === 0) error = err;
122
+ else unconsumedPromises.shift().reject(err);
123
+ closeHandler();
76
124
  }
77
125
  function abortListener() {
78
126
  errorHandler(abortError(signal));
79
127
  }
80
128
  function closeHandler() {
81
- for (const [name, handler] of listening) {
82
- if (isEventTarget(emitter)) emitter.removeEventListener(name, handler);
83
- else emitter.removeListener(name, handler);
84
- }
85
- listening.length = 0;
86
129
  signal?.removeEventListener("abort", abortListener);
130
+ while (listening.length) removeListener(emitter, ...listening.pop());
87
131
  finished = true;
88
- const done = result(undefined, true);
132
+ paused = false;
133
+ const done = iterResult(undefined, true);
89
134
  while (unconsumedPromises.length) unconsumedPromises.shift().resolve(done);
90
135
  return Promise.resolve(done);
91
136
  }
92
137
 
93
- listen(event, eventHandler);
94
- if (event !== "error" && !isEventTarget(emitter)) listen("error", errorHandler);
95
- for (const name of close) listen(name, closeHandler);
138
+ listen(event, options[kFirstEventParam] ? eventHandler : (...args) => eventHandler(args));
139
+ if (event !== "error" && typeof emitter.on === "function") listen("error", errorHandler);
140
+ for (const name of options?.close ?? []) listen(name, closeHandler);
96
141
  signal?.addEventListener("abort", abortListener, { once: true });
97
142
  return iterator;
98
143
  }
@@ -23,14 +23,18 @@ export function lazyFunction(name, length = 0) {
23
23
  return f;
24
24
  }
25
25
 
26
+ const kFeatureKey = Symbol("kFeatureKey");
27
+
26
28
  /** A class the program may construct, as a function the feature's module gives its prototype:
27
- * `new Wrapper(…)` builds the feature's class, and instanceof holds. */
28
- export function lazyClass(name) {
29
+ * `new Wrapper(…)` builds the feature's class, and instanceof holds. `key`, when two modules'
30
+ * classes share a name (dns's and dns/promises' Resolver). */
31
+ export function lazyClass(name, key = name) {
29
32
  const Wrapper = function (...args) {
30
33
  if (!new.target) throw new TypeError(`Class constructor ${name} cannot be invoked without 'new'`);
31
- return Reflect.construct(feature(name), args, new.target);
34
+ return Reflect.construct(feature(key), args, new.target);
32
35
  };
33
36
  Object.defineProperty(Wrapper, "name", { value: name });
37
+ Object.defineProperty(Wrapper, kFeatureKey, { value: key });
34
38
  return Wrapper;
35
39
  }
36
40
 
@@ -48,7 +52,7 @@ export function lazyConstructor(name, length = 1) {
48
52
 
49
53
  /** Called by a feature's module for a lazyClass: the wrapper takes the class's prototype. */
50
54
  export function provideClass(Wrapper, Class) {
51
- features[Wrapper.name] = Class;
55
+ features[Wrapper[kFeatureKey] ?? Wrapper.name] = Class;
52
56
  Wrapper.prototype = Class.prototype;
53
57
  Object.defineProperty(Class.prototype, "constructor", { value: Wrapper, writable: true, configurable: true });
54
58
  Object.setPrototypeOf(Wrapper, Object.getPrototypeOf(Class));
@@ -62,13 +62,18 @@ export class FileHandle extends EventEmitter {
62
62
  }
63
63
 
64
64
  /* the call on the fd as a promise; EBADF once the handle is closed */
65
+ /* done at once, settled on a later turn of the loop: Node's run on the thread pool, so what
66
+ * the caller's ticks and promise jobs do (an abort) comes first. An async operation's promise
67
+ * is followed at once (its steps are these calls), so its rejection has a handler. */
65
68
  #call(syscall, fn) {
66
69
  return new Promise((resolve, reject) => {
67
70
  if (this.#fd < 0) return reject(closedError(syscall));
68
71
  try {
69
- resolve(fn(this.#fd));
72
+ const result = fn(this.#fd);
73
+ if (typeof result?.then === "function") resolve(result);
74
+ else setImmediate(resolve, result);
70
75
  } catch (e) {
71
- reject(e);
76
+ setImmediate(reject, e);
72
77
  }
73
78
  });
74
79
  }
@@ -274,12 +279,13 @@ export class FileHandle extends EventEmitter {
274
279
  }
275
280
 
276
281
  /** fs/promises' open(path[, flags[, mode]]): a FileHandle. */
282
+ /* settled on a later turn of the loop, as Node's open on its thread pool (FileHandle's #call) */
277
283
  function promisesOpen(path, flags = "r", mode = 0o666) {
278
284
  return new Promise((resolve, reject) => {
279
285
  try {
280
- resolve(new FileHandle(openSync(path, flags, mode)));
286
+ setImmediate(resolve, new FileHandle(openSync(path, flags, mode)));
281
287
  } catch (e) {
282
- reject(e);
288
+ setImmediate(reject, e);
283
289
  }
284
290
  });
285
291
  }
@@ -432,4 +432,4 @@ function monitorEventLoopDelay(options = {}) {
432
432
  return new ELDHistogram(new Hdr(1, MAX_SAFE, 3), resolution);
433
433
  }
434
434
 
435
- Object.assign(features, { createHistogram, monitorEventLoopDelay });
435
+ Object.assign(features, { createHistogram, monitorEventLoopDelay, isHistogram: (value) => value instanceof Histogram });
@@ -10,7 +10,7 @@ import {
10
10
  } from "visaljs:host";
11
11
  import { isBuiltin, REQUIRE_TABLE } from "../module.js";
12
12
  import { parseDotenv } from "./dotenv.js";
13
- import { codeError, invalidArgType, notSupported, systemError } from "./errors.js";
13
+ import { codeError, invalidArgType, invalidArgValue, notSupported, outOfRange, systemError } from "./errors.js";
14
14
  import "./process_events.js";
15
15
 
16
16
  const p = globalThis.process;
@@ -66,13 +66,13 @@ define("uptime", function uptime() {
66
66
  function cpuUsageOf(thread, prevValue) {
67
67
  const usage = procCpuUsage(thread);
68
68
  const [user, system] = typeof usage === "number" ? [0, 0] : usage;
69
- if (prevValue === undefined) return { user, system };
69
+ if (!prevValue) return { user, system }; /* as Node's: any falsy prevValue */
70
70
  for (const key of ["user", "system"]) {
71
- const value = prevValue?.[key];
71
+ const value = prevValue[key];
72
+ if (typeof value === "number" && value >= 0 && Number.isFinite(value)) continue;
73
+ if (key === "user" && (typeof prevValue !== "object" || Array.isArray(prevValue))) throw invalidArgType("prevValue", "of type object", prevValue);
72
74
  if (typeof value !== "number") throw invalidArgType(`prevValue.${key}`, "of type number", value);
73
- if (!(value >= 0) || !Number.isFinite(value)) {
74
- throw codeError(RangeError, "ERR_INVALID_ARG_VALUE", `The property 'prevValue.${key}' is invalid. Received ${value}`);
75
- }
75
+ throw codeError(RangeError, "ERR_INVALID_ARG_VALUE", `The property 'prevValue.${key}' is invalid. Received ${value}`);
76
76
  }
77
77
  return { user: user - prevValue.user, system: system - prevValue.system };
78
78
  }
@@ -140,28 +140,36 @@ if (posix) {
140
140
  return groups;
141
141
  });
142
142
 
143
+ /* Node's validateId: a uint32 or a name; all checked before any is looked up */
144
+ const validateId = (id, name) => {
145
+ if (typeof id === "number") {
146
+ if (!Number.isInteger(id)) throw outOfRange(name, "an integer", id);
147
+ if (id < 0 || id > 4294967295) throw outOfRange(name, ">= 0 && <= 4294967295", id);
148
+ } else if (typeof id !== "string") {
149
+ throw invalidArgType(name, "one of type number or string", id);
150
+ }
151
+ };
152
+
143
153
  define("setgroups", function setgroups(groups) {
144
154
  if (!Array.isArray(groups)) throw invalidArgType("groups", "an instance of Array", groups);
145
- const ids = groups.map((group, i) => {
146
- if (typeof group !== "number" && typeof group !== "string") throw invalidArgType(`groups[${i}]`, "one of type number or string", group);
147
- return idOf(group, "Group");
148
- });
155
+ groups.forEach((group, i) => validateId(group, `groups[${i}]`));
156
+ const ids = groups.map((group) => idOf(group, "Group"));
149
157
  const err = procSetGroups(ids);
150
158
  if (err < 0) throw errnoException(err, "setgroups");
151
159
  });
152
160
 
153
161
  define("initgroups", function initgroups(user, extraGroup) {
162
+ validateId(user, "user");
163
+ validateId(extraGroup, "extraGroup");
164
+ const group = idOf(extraGroup, "Group"); /* as Node's: an unknown group is reported before an unknown user */
154
165
  let name = user;
155
166
  if (typeof user === "number") {
156
167
  name = procUserName(user);
157
168
  if (name === null) throw codeError(Error, "ERR_UNKNOWN_CREDENTIAL", `User identifier does not exist: ${user}`);
158
- } else if (typeof user !== "string") {
159
- throw invalidArgType("user", "one of type number or string", user);
160
169
  } else if (procUserId(user) === -1) {
161
170
  throw codeError(Error, "ERR_UNKNOWN_CREDENTIAL", `User identifier does not exist: ${user}`);
162
171
  }
163
- if (typeof extraGroup !== "number" && typeof extraGroup !== "string") throw invalidArgType("extraGroup", "one of type number or string", extraGroup);
164
- const err = procInitGroups(name, idOf(extraGroup, "Group"));
172
+ const err = procInitGroups(name, group);
165
173
  if (err < 0) throw errnoException(err, "initgroups");
166
174
  });
167
175
  }
@@ -183,9 +191,16 @@ define("execve", function execve(execPath, args = [], env = p.env) {
183
191
  if (!posix) throw codeError(Error, "ERR_FEATURE_UNAVAILABLE_ON_PLATFORM", `process.execve is not available on ${p.platform}`);
184
192
  validateString(execPath, "execPath");
185
193
  if (!Array.isArray(args)) throw invalidArgType("args", "an instance of Array", args);
186
- args.forEach((arg, i) => validateString(arg, `args[${i}]`));
187
- if (env === null || typeof env !== "object") throw invalidArgType("env", "of type object", env);
188
- const pairs = Object.entries(env).map(([key, value]) => `${key}=${value}`);
194
+ args.forEach((arg, i) => {
195
+ if (typeof arg !== "string" || arg.includes("\u0000")) throw invalidArgValue(`args[${i}]`, "must be a string without null bytes", arg);
196
+ });
197
+ if (env === null || typeof env !== "object" || Array.isArray(env)) throw invalidArgType("env", "of type object", env);
198
+ const pairs = Object.entries(env).map(([key, value]) => {
199
+ if (typeof value !== "string" || key.includes("\u0000") || value.includes("\u0000")) {
200
+ throw invalidArgValue("env", "must be an object with string keys and values without null bytes", env);
201
+ }
202
+ return `${key}=${value}`;
203
+ });
189
204
  const err = procExecve(execPath, args, pairs);
190
205
  p.stderr.write(`process.execve failed with error code ${errnoName(err)}\n`);
191
206
  procAbort();
@@ -28,6 +28,12 @@ p.on("removeListener", (type) => {
28
28
  watched[type] = false;
29
29
  });
30
30
 
31
+ /* the system call, as Node's binding: 0 or -errno */
32
+ p._kill = function _kill(pid, signum) {
33
+ return processKill(pid, signum);
34
+ };
35
+
36
+ /* through process._kill, as Node's: a program (or a test) that replaces it sends no signal */
31
37
  p.kill = function kill(pid, sig) {
32
38
  if (pid != (pid | 0)) throw invalidArgType("pid", "of type number", pid);
33
39
  let signum;
@@ -37,7 +43,7 @@ p.kill = function kill(pid, sig) {
37
43
  signum = signals[sig];
38
44
  if (signum === undefined) throw codeError(TypeError, "ERR_UNKNOWN_SIGNAL", "Unknown signal: " + sig);
39
45
  }
40
- const err = processKill(pid, signum);
41
- if (err < 0) throw errnoException(err, "kill");
46
+ const err = p._kill(pid, signum);
47
+ if (err) throw errnoException(err, "kill");
42
48
  return true;
43
49
  };
@@ -0,0 +1,163 @@
1
+ "use static";
2
+ // Punycode (RFC 3492), node:punycode's decode and encode, typed: code points in an i32[], the
3
+ // arithmetic in ints (its divisions are of non-negative values: Math.floor's).
4
+ // Ported from punycode.js 2.1.0 (Copyright Mathias Bynens, MIT): node/third_party/punycode/LICENSE.
5
+ import type { i32, int } from "visaljs";
6
+
7
+ const maxInt: int = 2147483647;
8
+ const base: int = 36;
9
+ const tMin: int = 1;
10
+ const tMax: int = 26;
11
+ const skew: int = 38;
12
+ const damp: int = 700;
13
+ const initialBias: int = 72;
14
+ const initialN: int = 128;
15
+
16
+ const overflow = "Overflow: input needs wider integers to process";
17
+ const notBasic = "Illegal input >= 0x80 (not a basic code point)";
18
+ const invalidInput = "Invalid input";
19
+
20
+ /** A string's code points: surrogate pairs joined, lone surrogates kept. */
21
+ function ucs2decode(s: string): i32[] {
22
+ const output: i32[] = [];
23
+ const length: int = s.length;
24
+ let counter: int = 0;
25
+ while (counter < length) {
26
+ const value: int = s.charCodeAt(counter++);
27
+ if (value >= 0xd800 && value <= 0xdbff && counter < length) {
28
+ const extra: int = s.charCodeAt(counter++);
29
+ if ((extra & 0xfc00) === 0xdc00) output.push(((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000);
30
+ else {
31
+ output.push(value);
32
+ counter--;
33
+ }
34
+ } else output.push(value);
35
+ }
36
+ return output;
37
+ }
38
+
39
+ /* a basic code point's digit value, or base for anything else */
40
+ function basicToDigit(codePoint: int): int {
41
+ if (codePoint >= 0x30 && codePoint < 0x3a) return 26 + (codePoint - 0x30);
42
+ if (codePoint >= 0x41 && codePoint < 0x5b) return codePoint - 0x41;
43
+ if (codePoint >= 0x61 && codePoint < 0x7b) return codePoint - 0x61;
44
+ return base;
45
+ }
46
+
47
+ /* a digit's code point, lowercase (0..25 a..z, 26..35 0..9) */
48
+ function digitToBasic(digit: int): int {
49
+ return digit < 26 ? digit + 97 : digit + 22;
50
+ }
51
+
52
+ /* RFC 3492 3.4 */
53
+ function adapt(delta: int, numPoints: int, firstTime: boolean): int {
54
+ let k: int = 0;
55
+ delta = firstTime ? delta / damp : delta >> 1;
56
+ delta += delta / numPoints;
57
+ for (; delta > ((base - tMin) * tMax) >> 1; k += base) delta = delta / (base - tMin);
58
+ return k + ((base - tMin + 1) * delta) / (delta + skew);
59
+ }
60
+
61
+ /** Punycode (ASCII only) to the Unicode string it encodes. */
62
+ export function decode(input: string): string {
63
+ const output: i32[] = [];
64
+ const inputLength: int = input.length;
65
+ let i: int = 0;
66
+ let n: int = initialN;
67
+ let bias: int = initialBias;
68
+
69
+ /* the basic code points: everything before the last delimiter */
70
+ let basic: int = input.lastIndexOf("-");
71
+ if (basic < 0) basic = 0;
72
+ for (let j: int = 0; j < basic; ++j) {
73
+ const c: int = input.charCodeAt(j);
74
+ if (c >= 0x80) throw new RangeError(notBasic);
75
+ output.push(c);
76
+ }
77
+
78
+ /* the deltas, each inserting a code point */
79
+ for (let index: int = basic > 0 ? basic + 1 : 0; index < inputLength;) {
80
+ const oldi: int = i;
81
+ for (let w: int = 1, k: int = base; ; k += base) {
82
+ if (index >= inputLength) throw new RangeError(invalidInput);
83
+ const digit: int = basicToDigit(input.charCodeAt(index++));
84
+ if (digit >= base) throw new RangeError(invalidInput);
85
+ if (digit > (maxInt - i) / w) throw new RangeError(overflow);
86
+ i += digit * w;
87
+ const t: int = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias;
88
+ if (digit < t) break;
89
+ const baseMinusT: int = base - t;
90
+ if (w > maxInt / baseMinusT) throw new RangeError(overflow);
91
+ w *= baseMinusT;
92
+ }
93
+ const out: int = output.length + 1;
94
+ bias = adapt(i - oldi, out, oldi === 0);
95
+ if (i / out > maxInt - n) throw new RangeError(overflow);
96
+ n += i / out;
97
+ i %= out;
98
+ output.push(0);
99
+ for (let m: int = output.length - 1; m > i; m--) output[m] = output[m - 1];
100
+ output[i++] = n;
101
+ }
102
+
103
+ let s = "";
104
+ for (let k: int = 0; k < output.length; k++) {
105
+ const c: int = output[k];
106
+ /* past U+10FFFF: String.fromCodePoint's RangeError */
107
+ s += c < 0x10000 ? String.fromCharCode(c) : String.fromCodePoint(c);
108
+ }
109
+ return s;
110
+ }
111
+
112
+ /** A Unicode string as Punycode (ASCII only). */
113
+ export function encode(str: string): string {
114
+ const input = ucs2decode(str);
115
+ const inputLength: int = input.length;
116
+ let n: int = initialN;
117
+ let delta: int = 0;
118
+ let bias: int = initialBias;
119
+
120
+ let output = "";
121
+ for (let j: int = 0; j < inputLength; j++) {
122
+ const c: int = input[j];
123
+ if (c < 0x80) output += String.fromCharCode(c);
124
+ }
125
+ const basicLength: int = output.length;
126
+ let handledCPCount: int = basicLength;
127
+ if (basicLength > 0) output += "-";
128
+
129
+ while (handledCPCount < inputLength) {
130
+ /* the next code point to insert: the smallest not yet handled */
131
+ let m: int = maxInt;
132
+ for (let j: int = 0; j < inputLength; j++) {
133
+ const c: int = input[j];
134
+ if (c >= n && c < m) m = c;
135
+ }
136
+ const handledCPCountPlusOne: int = handledCPCount + 1;
137
+ if (m - n > (maxInt - delta) / handledCPCountPlusOne) throw new RangeError(overflow);
138
+ delta += (m - n) * handledCPCountPlusOne;
139
+ n = m;
140
+ for (let j: int = 0; j < inputLength; j++) {
141
+ const c: int = input[j];
142
+ if (c < n && ++delta > maxInt) throw new RangeError(overflow);
143
+ if (c === n) {
144
+ let q: int = delta;
145
+ for (let k: int = base; ; k += base) {
146
+ const t: int = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias;
147
+ if (q < t) break;
148
+ const qMinusT: int = q - t;
149
+ const baseMinusT: int = base - t;
150
+ output += String.fromCharCode(digitToBasic(t + (qMinusT % baseMinusT)));
151
+ q = qMinusT / baseMinusT;
152
+ }
153
+ output += String.fromCharCode(digitToBasic(q));
154
+ bias = adapt(delta, handledCPCountPlusOne, handledCPCount === basicLength);
155
+ delta = 0;
156
+ ++handledCPCount;
157
+ }
158
+ }
159
+ ++delta;
160
+ ++n;
161
+ }
162
+ return output;
163
+ }