@scriptc/cli-darwin-x64 0.0.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (960) hide show
  1. package/dist/LICENSE +202 -0
  2. package/dist/THIRD_PARTY_NOTICES +4 -0
  3. package/dist/bin/scriptc +0 -0
  4. package/dist/bin/scriptc.json +21 -0
  5. package/dist/lib/declarations/scriptc-node-fallback.d.ts +3847 -0
  6. package/dist/lib/declarations/scriptc-overrides.d.ts +92 -0
  7. package/dist/lib/declarations/scriptc.d.ts +98 -0
  8. package/dist/lib/llvm/LICENSE +1 -0
  9. package/dist/lib/llvm/SCRIPTC_LICENSE +1 -0
  10. package/dist/lib/llvm/THIRD_PARTY_NOTICES +1 -0
  11. package/dist/lib/llvm/bin/scriptc-llvm-codegen +0 -0
  12. package/dist/lib/llvm/package.json +35 -0
  13. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_array.o +0 -0
  14. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_assert.o +0 -0
  15. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_async.o +0 -0
  16. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_async_dyn.o +0 -0
  17. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bigint.o +0 -0
  18. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bigint_assert.o +0 -0
  19. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bytes.o +0 -0
  20. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bytes_io.o +0 -0
  21. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_child.o +0 -0
  22. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_closure.o +0 -0
  23. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_console.o +0 -0
  24. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_console_native.o +0 -0
  25. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_copying.o +0 -0
  26. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_crypto_async.o +0 -0
  27. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_cycle.o +0 -0
  28. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_dc.o +0 -0
  29. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_dgram.o +0 -0
  30. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_dyn_handle.o +0 -0
  31. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_dyn_invoke.o +0 -0
  32. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_error.o +0 -0
  33. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_events.o +0 -0
  34. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_events_emitter.o +0 -0
  35. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_exception.o +0 -0
  36. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_fetch.o +0 -0
  37. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_ffi.o +0 -0
  38. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_ffi_queue.o +0 -0
  39. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_file_handle.o +0 -0
  40. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_grapheme.o +0 -0
  41. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_http.o +0 -0
  42. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_http2.o +0 -0
  43. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_inspect.o +0 -0
  44. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_json.o +0 -0
  45. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_lib.o +0 -0
  46. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_loop_epoll.o +0 -0
  47. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_loop_kqueue.o +0 -0
  48. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_loop_wsapoll.o +0 -0
  49. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_map.o +0 -0
  50. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_net.o +0 -0
  51. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_node_builtin.o +0 -0
  52. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_number.o +0 -0
  53. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_object.o +0 -0
  54. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_path.o +0 -0
  55. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_qs.o +0 -0
  56. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_readline.o +0 -0
  57. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_regex.o +0 -0
  58. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_stream.o +0 -0
  59. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_string.o +0 -0
  60. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_symbol.o +0 -0
  61. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_test.o +0 -0
  62. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_tls.o +0 -0
  63. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_tls_ca.o +0 -0
  64. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_union.o +0 -0
  65. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_url.o +0 -0
  66. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_url_params.o +0 -0
  67. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_util.o +0 -0
  68. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_watch.o +0 -0
  69. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_zlib.o +0 -0
  70. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_array.o +0 -0
  71. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_assert.o +0 -0
  72. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_async.o +0 -0
  73. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_async_dyn.o +0 -0
  74. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bigint.o +0 -0
  75. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bigint_assert.o +0 -0
  76. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bytes.o +0 -0
  77. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bytes_io.o +0 -0
  78. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_child.o +0 -0
  79. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_closure.o +0 -0
  80. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_console.o +0 -0
  81. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_console_native.o +0 -0
  82. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_copying.o +0 -0
  83. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_crypto_async.o +0 -0
  84. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_cycle.o +0 -0
  85. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_dc.o +0 -0
  86. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_dgram.o +0 -0
  87. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_dyn_handle.o +0 -0
  88. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_dyn_invoke.o +0 -0
  89. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_error.o +0 -0
  90. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_events.o +0 -0
  91. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_events_emitter.o +0 -0
  92. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_exception.o +0 -0
  93. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_fetch.o +0 -0
  94. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_ffi.o +0 -0
  95. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_ffi_queue.o +0 -0
  96. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_file_handle.o +0 -0
  97. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_grapheme.o +0 -0
  98. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_http.o +0 -0
  99. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_http2.o +0 -0
  100. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_inspect.o +0 -0
  101. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_inspect_island.o +0 -0
  102. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_island.o +0 -0
  103. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_json.o +0 -0
  104. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_lib.o +0 -0
  105. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_loop_epoll.o +0 -0
  106. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_loop_kqueue.o +0 -0
  107. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_loop_wsapoll.o +0 -0
  108. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_map.o +0 -0
  109. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_net.o +0 -0
  110. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_net_island.o +0 -0
  111. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_node_builtin.o +0 -0
  112. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_number.o +0 -0
  113. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_object.o +0 -0
  114. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_path.o +0 -0
  115. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_qs.o +0 -0
  116. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_readline.o +0 -0
  117. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_regex.o +0 -0
  118. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_stream.o +0 -0
  119. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_string.o +0 -0
  120. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_symbol.o +0 -0
  121. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_test.o +0 -0
  122. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_tls.o +0 -0
  123. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_tls_ca.o +0 -0
  124. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_union.o +0 -0
  125. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_url.o +0 -0
  126. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_url_params.o +0 -0
  127. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_util.o +0 -0
  128. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_watch.o +0 -0
  129. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_web.o +0 -0
  130. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_zlib.o +0 -0
  131. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_zlib_island.o +0 -0
  132. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
  133. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  134. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_array.o +0 -0
  135. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_assert.o +0 -0
  136. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bigint.o +0 -0
  137. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bigint_assert.o +0 -0
  138. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bytes.o +0 -0
  139. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bytes_io.o +0 -0
  140. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_closure.o +0 -0
  141. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_console.o +0 -0
  142. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_console_native.o +0 -0
  143. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_copying.o +0 -0
  144. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_cycle.o +0 -0
  145. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_dyn_handle.o +0 -0
  146. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_dyn_invoke.o +0 -0
  147. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_error.o +0 -0
  148. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_events_emitter.o +0 -0
  149. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_exception.o +0 -0
  150. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_grapheme.o +0 -0
  151. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_inspect.o +0 -0
  152. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_json.o +0 -0
  153. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_lib.o +0 -0
  154. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_library.o +0 -0
  155. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_map.o +0 -0
  156. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_node_builtin.o +0 -0
  157. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_number.o +0 -0
  158. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_object.o +0 -0
  159. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_path.o +0 -0
  160. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_regex.o +0 -0
  161. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_string.o +0 -0
  162. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_symbol.o +0 -0
  163. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_union.o +0 -0
  164. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_url.o +0 -0
  165. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_url_params.o +0 -0
  166. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_zlib.o +0 -0
  167. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  168. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_array.o +0 -0
  169. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_assert.o +0 -0
  170. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bigint.o +0 -0
  171. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bigint_assert.o +0 -0
  172. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bytes.o +0 -0
  173. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bytes_io.o +0 -0
  174. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_closure.o +0 -0
  175. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_console.o +0 -0
  176. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_console_native.o +0 -0
  177. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_copying.o +0 -0
  178. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_cycle.o +0 -0
  179. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_dyn_handle.o +0 -0
  180. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_dyn_invoke.o +0 -0
  181. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_error.o +0 -0
  182. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_events_emitter.o +0 -0
  183. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_exception.o +0 -0
  184. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_grapheme.o +0 -0
  185. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_inspect.o +0 -0
  186. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_json.o +0 -0
  187. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_lib.o +0 -0
  188. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_library.o +0 -0
  189. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_map.o +0 -0
  190. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_node_builtin.o +0 -0
  191. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_number.o +0 -0
  192. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_object.o +0 -0
  193. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_path.o +0 -0
  194. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_regex.o +0 -0
  195. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_string.o +0 -0
  196. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_symbol.o +0 -0
  197. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_union.o +0 -0
  198. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_url.o +0 -0
  199. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_url_params.o +0 -0
  200. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_zlib.o +0 -0
  201. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  202. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_array.o +0 -0
  203. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_assert.o +0 -0
  204. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bigint.o +0 -0
  205. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bigint_assert.o +0 -0
  206. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bytes.o +0 -0
  207. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bytes_io.o +0 -0
  208. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_closure.o +0 -0
  209. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_console.o +0 -0
  210. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_console_native.o +0 -0
  211. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_copying.o +0 -0
  212. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_cycle.o +0 -0
  213. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_dyn_handle.o +0 -0
  214. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_dyn_invoke.o +0 -0
  215. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_error.o +0 -0
  216. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_events_emitter.o +0 -0
  217. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_exception.o +0 -0
  218. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_grapheme.o +0 -0
  219. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_inspect.o +0 -0
  220. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_json.o +0 -0
  221. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_lib.o +0 -0
  222. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_library.o +0 -0
  223. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_map.o +0 -0
  224. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_node_builtin.o +0 -0
  225. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_number.o +0 -0
  226. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_object.o +0 -0
  227. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_path.o +0 -0
  228. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_regex.o +0 -0
  229. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_string.o +0 -0
  230. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_symbol.o +0 -0
  231. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_union.o +0 -0
  232. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_url.o +0 -0
  233. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_url_params.o +0 -0
  234. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_zlib.o +0 -0
  235. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  236. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_array.o +0 -0
  237. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_assert.o +0 -0
  238. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bigint.o +0 -0
  239. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bigint_assert.o +0 -0
  240. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bytes.o +0 -0
  241. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bytes_io.o +0 -0
  242. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_closure.o +0 -0
  243. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_console.o +0 -0
  244. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_console_native.o +0 -0
  245. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_copying.o +0 -0
  246. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_cycle.o +0 -0
  247. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_dyn_handle.o +0 -0
  248. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_dyn_invoke.o +0 -0
  249. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_error.o +0 -0
  250. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_events_emitter.o +0 -0
  251. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_exception.o +0 -0
  252. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_grapheme.o +0 -0
  253. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_inspect.o +0 -0
  254. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_json.o +0 -0
  255. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_lib.o +0 -0
  256. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_library.o +0 -0
  257. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_map.o +0 -0
  258. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_node_builtin.o +0 -0
  259. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_number.o +0 -0
  260. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_object.o +0 -0
  261. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_path.o +0 -0
  262. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_regex.o +0 -0
  263. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_string.o +0 -0
  264. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_symbol.o +0 -0
  265. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_union.o +0 -0
  266. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_url.o +0 -0
  267. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_url_params.o +0 -0
  268. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_zlib.o +0 -0
  269. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  270. package/dist/lib/runtime-darwin-x64/artifacts/licenses/mbedtls.txt +553 -0
  271. package/dist/lib/runtime-darwin-x64/artifacts/licenses/quickjs-ng.txt +24 -0
  272. package/dist/lib/runtime-darwin-x64/artifacts/licenses/ryu.txt +23 -0
  273. package/dist/lib/runtime-darwin-x64/artifacts/licenses/scriptc-runtime.txt +202 -0
  274. package/dist/lib/runtime-darwin-x64/artifacts/licenses/unicode.txt +39 -0
  275. package/dist/lib/runtime-darwin-x64/artifacts/licenses/zlib.txt +22 -0
  276. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_array.o +0 -0
  277. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_assert.o +0 -0
  278. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_async.o +0 -0
  279. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_async_dyn.o +0 -0
  280. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bigint.o +0 -0
  281. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bigint_assert.o +0 -0
  282. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bytes.o +0 -0
  283. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bytes_io.o +0 -0
  284. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_child.o +0 -0
  285. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_closure.o +0 -0
  286. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_console.o +0 -0
  287. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_console_native.o +0 -0
  288. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_copying.o +0 -0
  289. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_crypto_async.o +0 -0
  290. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_cycle.o +0 -0
  291. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_dc.o +0 -0
  292. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_dgram.o +0 -0
  293. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_dyn_handle.o +0 -0
  294. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_dyn_invoke.o +0 -0
  295. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_error.o +0 -0
  296. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_events.o +0 -0
  297. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_events_emitter.o +0 -0
  298. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_exception.o +0 -0
  299. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_fetch.o +0 -0
  300. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_ffi.o +0 -0
  301. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_ffi_queue.o +0 -0
  302. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_file_handle.o +0 -0
  303. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_grapheme.o +0 -0
  304. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_http.o +0 -0
  305. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_http2.o +0 -0
  306. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_inspect.o +0 -0
  307. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_json.o +0 -0
  308. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_lib.o +0 -0
  309. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_loop_epoll.o +0 -0
  310. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_loop_kqueue.o +0 -0
  311. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_loop_wsapoll.o +0 -0
  312. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_map.o +0 -0
  313. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_net.o +0 -0
  314. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_node_builtin.o +0 -0
  315. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_number.o +0 -0
  316. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_object.o +0 -0
  317. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_path.o +0 -0
  318. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_qs.o +0 -0
  319. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_readline.o +0 -0
  320. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_regex.o +0 -0
  321. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_stream.o +0 -0
  322. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_string.o +0 -0
  323. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_symbol.o +0 -0
  324. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_test.o +0 -0
  325. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_tls.o +0 -0
  326. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_tls_ca.o +0 -0
  327. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_union.o +0 -0
  328. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_url.o +0 -0
  329. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_url_params.o +0 -0
  330. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_util.o +0 -0
  331. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_watch.o +0 -0
  332. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_zlib.o +0 -0
  333. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_array.o +0 -0
  334. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_assert.o +0 -0
  335. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_async.o +0 -0
  336. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_async_dyn.o +0 -0
  337. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bigint.o +0 -0
  338. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bigint_assert.o +0 -0
  339. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bytes.o +0 -0
  340. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bytes_io.o +0 -0
  341. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_child.o +0 -0
  342. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_closure.o +0 -0
  343. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_console.o +0 -0
  344. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_console_native.o +0 -0
  345. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_copying.o +0 -0
  346. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_crypto_async.o +0 -0
  347. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_cycle.o +0 -0
  348. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_dc.o +0 -0
  349. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_dgram.o +0 -0
  350. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_dyn_handle.o +0 -0
  351. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_dyn_invoke.o +0 -0
  352. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_error.o +0 -0
  353. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_events.o +0 -0
  354. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_events_emitter.o +0 -0
  355. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_exception.o +0 -0
  356. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_fetch.o +0 -0
  357. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_ffi.o +0 -0
  358. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_ffi_queue.o +0 -0
  359. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_file_handle.o +0 -0
  360. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_grapheme.o +0 -0
  361. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_http.o +0 -0
  362. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_http2.o +0 -0
  363. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_inspect.o +0 -0
  364. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_inspect_island.o +0 -0
  365. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_island.o +0 -0
  366. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_json.o +0 -0
  367. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_lib.o +0 -0
  368. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_loop_epoll.o +0 -0
  369. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_loop_kqueue.o +0 -0
  370. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_loop_wsapoll.o +0 -0
  371. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_map.o +0 -0
  372. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_net.o +0 -0
  373. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_net_island.o +0 -0
  374. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_node_builtin.o +0 -0
  375. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_number.o +0 -0
  376. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_object.o +0 -0
  377. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_path.o +0 -0
  378. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_qs.o +0 -0
  379. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_readline.o +0 -0
  380. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_regex.o +0 -0
  381. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_stream.o +0 -0
  382. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_string.o +0 -0
  383. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_symbol.o +0 -0
  384. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_test.o +0 -0
  385. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_tls.o +0 -0
  386. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_tls_ca.o +0 -0
  387. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_union.o +0 -0
  388. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_url.o +0 -0
  389. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_url_params.o +0 -0
  390. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_util.o +0 -0
  391. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_watch.o +0 -0
  392. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_web.o +0 -0
  393. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_zlib.o +0 -0
  394. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_zlib_island.o +0 -0
  395. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
  396. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  397. package/dist/lib/runtime-darwin-x64/artifacts/vendor/libregexp/libscriptc-libregexp.a +0 -0
  398. package/dist/lib/runtime-darwin-x64/artifacts/vendor/mbedtls/libscriptc-mbedtls.a +0 -0
  399. package/dist/lib/runtime-darwin-x64/artifacts/vendor/quickjs/libscriptc-quickjs.a +0 -0
  400. package/dist/lib/runtime-darwin-x64/artifacts/vendor/zlib/libscriptc-zlib.a +0 -0
  401. package/dist/lib/runtime-darwin-x64/package.json +24 -0
  402. package/dist/lib/runtime-darwin-x64/runtime-pack.json +5758 -0
  403. package/dist/lib/runtime-sources/LICENSE +202 -0
  404. package/dist/lib/runtime-sources/package.json +22 -0
  405. package/dist/lib/runtime-sources/src/scr_array.c +1444 -0
  406. package/dist/lib/runtime-sources/src/scr_assert.c +1537 -0
  407. package/dist/lib/runtime-sources/src/scr_async.c +3920 -0
  408. package/dist/lib/runtime-sources/src/scr_async.test.c +134 -0
  409. package/dist/lib/runtime-sources/src/scr_async.test.ts +34 -0
  410. package/dist/lib/runtime-sources/src/scr_async_dyn.c +803 -0
  411. package/dist/lib/runtime-sources/src/scr_bigint.c +890 -0
  412. package/dist/lib/runtime-sources/src/scr_bigint_assert.c +22 -0
  413. package/dist/lib/runtime-sources/src/scr_bytes.c +2518 -0
  414. package/dist/lib/runtime-sources/src/scr_bytes_io.c +755 -0
  415. package/dist/lib/runtime-sources/src/scr_child.c +5808 -0
  416. package/dist/lib/runtime-sources/src/scr_closure.c +213 -0
  417. package/dist/lib/runtime-sources/src/scr_console.c +259 -0
  418. package/dist/lib/runtime-sources/src/scr_console_native.c +95 -0
  419. package/dist/lib/runtime-sources/src/scr_copying.c +146 -0
  420. package/dist/lib/runtime-sources/src/scr_crypto_async.c +24 -0
  421. package/dist/lib/runtime-sources/src/scr_cycle.c +565 -0
  422. package/dist/lib/runtime-sources/src/scr_dc.c +814 -0
  423. package/dist/lib/runtime-sources/src/scr_dgram.c +1182 -0
  424. package/dist/lib/runtime-sources/src/scr_dyn_handle.c +96 -0
  425. package/dist/lib/runtime-sources/src/scr_dyn_invoke.c +1626 -0
  426. package/dist/lib/runtime-sources/src/scr_error.c +372 -0
  427. package/dist/lib/runtime-sources/src/scr_events.c +1222 -0
  428. package/dist/lib/runtime-sources/src/scr_events_emitter.c +842 -0
  429. package/dist/lib/runtime-sources/src/scr_exception.c +468 -0
  430. package/dist/lib/runtime-sources/src/scr_fetch.c +7215 -0
  431. package/dist/lib/runtime-sources/src/scr_fetch_curl.c +666 -0
  432. package/dist/lib/runtime-sources/src/scr_ffi.c +143 -0
  433. package/dist/lib/runtime-sources/src/scr_ffi_queue.c +379 -0
  434. package/dist/lib/runtime-sources/src/scr_file_handle.c +562 -0
  435. package/dist/lib/runtime-sources/src/scr_grapheme.c +203 -0
  436. package/dist/lib/runtime-sources/src/scr_grapheme_data.h +842 -0
  437. package/dist/lib/runtime-sources/src/scr_http.c +5808 -0
  438. package/dist/lib/runtime-sources/src/scr_http2.c +3243 -0
  439. package/dist/lib/runtime-sources/src/scr_inspect.c +923 -0
  440. package/dist/lib/runtime-sources/src/scr_inspect_island.c +51 -0
  441. package/dist/lib/runtime-sources/src/scr_island.c +9987 -0
  442. package/dist/lib/runtime-sources/src/scr_island_manifest.h +153 -0
  443. package/dist/lib/runtime-sources/src/scr_json.c +7928 -0
  444. package/dist/lib/runtime-sources/src/scr_json.test.c +182 -0
  445. package/dist/lib/runtime-sources/src/scr_json.test.ts +33 -0
  446. package/dist/lib/runtime-sources/src/scr_lib.c +6304 -0
  447. package/dist/lib/runtime-sources/src/scr_library.c +444 -0
  448. package/dist/lib/runtime-sources/src/scr_loop_epoll.c +241 -0
  449. package/dist/lib/runtime-sources/src/scr_loop_kqueue.c +121 -0
  450. package/dist/lib/runtime-sources/src/scr_loop_wsapoll.c +208 -0
  451. package/dist/lib/runtime-sources/src/scr_map.c +705 -0
  452. package/dist/lib/runtime-sources/src/scr_musl.c +438 -0
  453. package/dist/lib/runtime-sources/src/scr_net.c +3708 -0
  454. package/dist/lib/runtime-sources/src/scr_net_island.c +458 -0
  455. package/dist/lib/runtime-sources/src/scr_node_builtin.c +281 -0
  456. package/dist/lib/runtime-sources/src/scr_number.c +192 -0
  457. package/dist/lib/runtime-sources/src/scr_object.c +80 -0
  458. package/dist/lib/runtime-sources/src/scr_path.c +1281 -0
  459. package/dist/lib/runtime-sources/src/scr_platform.h +119 -0
  460. package/dist/lib/runtime-sources/src/scr_qs.c +496 -0
  461. package/dist/lib/runtime-sources/src/scr_readline.c +288 -0
  462. package/dist/lib/runtime-sources/src/scr_regex.c +1274 -0
  463. package/dist/lib/runtime-sources/src/scr_runtime.h +7207 -0
  464. package/dist/lib/runtime-sources/src/scr_stream.c +3149 -0
  465. package/dist/lib/runtime-sources/src/scr_string.c +1849 -0
  466. package/dist/lib/runtime-sources/src/scr_symbol.c +234 -0
  467. package/dist/lib/runtime-sources/src/scr_test.c +662 -0
  468. package/dist/lib/runtime-sources/src/scr_text_decoder_data.h +7389 -0
  469. package/dist/lib/runtime-sources/src/scr_tls.c +1806 -0
  470. package/dist/lib/runtime-sources/src/scr_tls_ca.c +433 -0
  471. package/dist/lib/runtime-sources/src/scr_union.c +105 -0
  472. package/dist/lib/runtime-sources/src/scr_url.c +1231 -0
  473. package/dist/lib/runtime-sources/src/scr_url_internal.h +29 -0
  474. package/dist/lib/runtime-sources/src/scr_url_params.c +526 -0
  475. package/dist/lib/runtime-sources/src/scr_util.c +984 -0
  476. package/dist/lib/runtime-sources/src/scr_watch.c +568 -0
  477. package/dist/lib/runtime-sources/src/scr_web.c +1854 -0
  478. package/dist/lib/runtime-sources/src/scr_win.c +231 -0
  479. package/dist/lib/runtime-sources/src/scr_win_stats.h +23 -0
  480. package/dist/lib/runtime-sources/src/scr_zlib.c +358 -0
  481. package/dist/lib/runtime-sources/src/scr_zlib_island.c +15 -0
  482. package/dist/lib/runtime-sources/vendor/README.md +60 -0
  483. package/dist/lib/runtime-sources/vendor/curl/COPYRIGHT +534 -0
  484. package/dist/lib/runtime-sources/vendor/curl/include/curl/curl.h +3214 -0
  485. package/dist/lib/runtime-sources/vendor/curl/include/curl/curlver.h +79 -0
  486. package/dist/lib/runtime-sources/vendor/curl/include/curl/easy.h +125 -0
  487. package/dist/lib/runtime-sources/vendor/curl/include/curl/header.h +74 -0
  488. package/dist/lib/runtime-sources/vendor/curl/include/curl/mprintf.h +52 -0
  489. package/dist/lib/runtime-sources/vendor/curl/include/curl/multi.h +460 -0
  490. package/dist/lib/runtime-sources/vendor/curl/include/curl/options.h +70 -0
  491. package/dist/lib/runtime-sources/vendor/curl/include/curl/stdcheaders.h +35 -0
  492. package/dist/lib/runtime-sources/vendor/curl/include/curl/system.h +508 -0
  493. package/dist/lib/runtime-sources/vendor/curl/include/curl/typecheck-gcc.h +716 -0
  494. package/dist/lib/runtime-sources/vendor/curl/include/curl/urlapi.h +149 -0
  495. package/dist/lib/runtime-sources/vendor/curl/include/curl/websockets.h +84 -0
  496. package/dist/lib/runtime-sources/vendor/mbedtls/LICENSE +553 -0
  497. package/dist/lib/runtime-sources/vendor/mbedtls/include/CMakeLists.txt +22 -0
  498. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/aes.h +631 -0
  499. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/aria.h +343 -0
  500. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/asn1.h +642 -0
  501. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/asn1write.h +390 -0
  502. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/base64.h +82 -0
  503. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/bignum.h +1088 -0
  504. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/block_cipher.h +76 -0
  505. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/build_info.h +194 -0
  506. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/camellia.h +305 -0
  507. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ccm.h +526 -0
  508. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/chacha20.h +209 -0
  509. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/chachapoly.h +351 -0
  510. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/check_config.h +1149 -0
  511. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/cipher.h +1250 -0
  512. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/cmac.h +246 -0
  513. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/compat-2.x.h +46 -0
  514. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h +578 -0
  515. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_adjust_legacy_from_psa.h +873 -0
  516. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_adjust_psa_from_legacy.h +359 -0
  517. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_adjust_psa_superset_legacy.h +145 -0
  518. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_adjust_ssl.h +91 -0
  519. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_adjust_x509.h +35 -0
  520. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/config_psa.h +61 -0
  521. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/constant_time.h +36 -0
  522. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ctr_drbg.h +596 -0
  523. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/debug.h +156 -0
  524. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/des.h +385 -0
  525. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/dhm.h +972 -0
  526. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ecdh.h +455 -0
  527. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ecdsa.h +674 -0
  528. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ecjpake.h +298 -0
  529. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ecp.h +1517 -0
  530. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/entropy.h +274 -0
  531. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/error.h +201 -0
  532. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/gcm.h +387 -0
  533. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/hkdf.h +124 -0
  534. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/hmac_drbg.h +434 -0
  535. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/lms.h +440 -0
  536. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/mbedtls_config.h +4446 -0
  537. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/md.h +526 -0
  538. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/md5.h +190 -0
  539. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/memory_buffer_alloc.h +142 -0
  540. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/net_sockets.h +299 -0
  541. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/nist_kw.h +166 -0
  542. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/oid.h +727 -0
  543. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/pem.h +160 -0
  544. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/pk.h +1303 -0
  545. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/pkcs12.h +186 -0
  546. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/pkcs5.h +198 -0
  547. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/pkcs7.h +252 -0
  548. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/platform.h +516 -0
  549. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/platform_time.h +79 -0
  550. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/platform_util.h +247 -0
  551. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/poly1305.h +168 -0
  552. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/private_access.h +20 -0
  553. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/psa_util.h +207 -0
  554. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ripemd160.h +136 -0
  555. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/rsa.h +1170 -0
  556. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/sha1.h +219 -0
  557. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/sha256.h +200 -0
  558. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/sha3.h +172 -0
  559. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/sha512.h +208 -0
  560. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ssl.h +5887 -0
  561. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ssl_cache.h +187 -0
  562. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ssl_ciphersuites.h +482 -0
  563. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ssl_cookie.h +106 -0
  564. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/ssl_ticket.h +199 -0
  565. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/threading.h +167 -0
  566. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/timing.h +94 -0
  567. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/version.h +78 -0
  568. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/x509.h +500 -0
  569. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/x509_crl.h +184 -0
  570. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/x509_crt.h +1208 -0
  571. package/dist/lib/runtime-sources/vendor/mbedtls/include/mbedtls/x509_csr.h +382 -0
  572. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/build_info.h +20 -0
  573. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto.h +4998 -0
  574. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_adjust_auto_enabled.h +31 -0
  575. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_adjust_config_dependencies.h +51 -0
  576. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_adjust_config_key_pair_types.h +101 -0
  577. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_adjust_config_synonyms.h +49 -0
  578. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_builtin_composites.h +214 -0
  579. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_builtin_key_derivation.h +118 -0
  580. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_builtin_primitives.h +114 -0
  581. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_compat.h +230 -0
  582. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_config.h +145 -0
  583. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_driver_common.h +44 -0
  584. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_driver_contexts_composites.h +151 -0
  585. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_driver_contexts_key_derivation.h +52 -0
  586. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_driver_contexts_primitives.h +105 -0
  587. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_extra.h +2145 -0
  588. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_legacy.h +88 -0
  589. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_platform.h +102 -0
  590. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_se_driver.h +1383 -0
  591. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_sizes.h +1319 -0
  592. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_struct.h +527 -0
  593. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_types.h +508 -0
  594. package/dist/lib/runtime-sources/vendor/mbedtls/include/psa/crypto_values.h +2782 -0
  595. package/dist/lib/runtime-sources/vendor/mbedtls/library/aes.c +2294 -0
  596. package/dist/lib/runtime-sources/vendor/mbedtls/library/aesce.c +624 -0
  597. package/dist/lib/runtime-sources/vendor/mbedtls/library/aesce.h +136 -0
  598. package/dist/lib/runtime-sources/vendor/mbedtls/library/aesni.c +846 -0
  599. package/dist/lib/runtime-sources/vendor/mbedtls/library/aesni.h +162 -0
  600. package/dist/lib/runtime-sources/vendor/mbedtls/library/alignment.h +704 -0
  601. package/dist/lib/runtime-sources/vendor/mbedtls/library/aria.c +969 -0
  602. package/dist/lib/runtime-sources/vendor/mbedtls/library/asn1parse.c +468 -0
  603. package/dist/lib/runtime-sources/vendor/mbedtls/library/asn1write.c +440 -0
  604. package/dist/lib/runtime-sources/vendor/mbedtls/library/base64.c +322 -0
  605. package/dist/lib/runtime-sources/vendor/mbedtls/library/base64_internal.h +45 -0
  606. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum.c +2583 -0
  607. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_core.c +1240 -0
  608. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_core.h +872 -0
  609. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_core_invasive.h +38 -0
  610. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_internal.h +122 -0
  611. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_mod.c +394 -0
  612. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_mod.h +452 -0
  613. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_mod_raw.c +276 -0
  614. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_mod_raw.h +416 -0
  615. package/dist/lib/runtime-sources/vendor/mbedtls/library/bignum_mod_raw_invasive.h +34 -0
  616. package/dist/lib/runtime-sources/vendor/mbedtls/library/block_cipher.c +207 -0
  617. package/dist/lib/runtime-sources/vendor/mbedtls/library/block_cipher_internal.h +99 -0
  618. package/dist/lib/runtime-sources/vendor/mbedtls/library/bn_mul.h +1094 -0
  619. package/dist/lib/runtime-sources/vendor/mbedtls/library/camellia.c +1058 -0
  620. package/dist/lib/runtime-sources/vendor/mbedtls/library/ccm.c +777 -0
  621. package/dist/lib/runtime-sources/vendor/mbedtls/library/chacha20.c +563 -0
  622. package/dist/lib/runtime-sources/vendor/mbedtls/library/chacha20_internal.h +23 -0
  623. package/dist/lib/runtime-sources/vendor/mbedtls/library/chachapoly.c +487 -0
  624. package/dist/lib/runtime-sources/vendor/mbedtls/library/check_crypto_config.h +136 -0
  625. package/dist/lib/runtime-sources/vendor/mbedtls/library/cipher.c +1712 -0
  626. package/dist/lib/runtime-sources/vendor/mbedtls/library/cipher_invasive.h +28 -0
  627. package/dist/lib/runtime-sources/vendor/mbedtls/library/cipher_wrap.c +2482 -0
  628. package/dist/lib/runtime-sources/vendor/mbedtls/library/cipher_wrap.h +178 -0
  629. package/dist/lib/runtime-sources/vendor/mbedtls/library/cmac.c +1067 -0
  630. package/dist/lib/runtime-sources/vendor/mbedtls/library/common.h +487 -0
  631. package/dist/lib/runtime-sources/vendor/mbedtls/library/constant_time.c +247 -0
  632. package/dist/lib/runtime-sources/vendor/mbedtls/library/constant_time_impl.h +541 -0
  633. package/dist/lib/runtime-sources/vendor/mbedtls/library/constant_time_internal.h +579 -0
  634. package/dist/lib/runtime-sources/vendor/mbedtls/library/ctr.h +35 -0
  635. package/dist/lib/runtime-sources/vendor/mbedtls/library/ctr_drbg.c +1016 -0
  636. package/dist/lib/runtime-sources/vendor/mbedtls/library/debug.c +475 -0
  637. package/dist/lib/runtime-sources/vendor/mbedtls/library/debug_internal.h +185 -0
  638. package/dist/lib/runtime-sources/vendor/mbedtls/library/des.c +1042 -0
  639. package/dist/lib/runtime-sources/vendor/mbedtls/library/dhm.c +700 -0
  640. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecdh.c +696 -0
  641. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecdsa.c +858 -0
  642. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecjpake.c +1216 -0
  643. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecp.c +3674 -0
  644. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecp_curves.c +6125 -0
  645. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecp_curves_new.c +9 -0
  646. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecp_internal_alt.h +287 -0
  647. package/dist/lib/runtime-sources/vendor/mbedtls/library/ecp_invasive.h +305 -0
  648. package/dist/lib/runtime-sources/vendor/mbedtls/library/entropy.c +680 -0
  649. package/dist/lib/runtime-sources/vendor/mbedtls/library/entropy_poll.c +233 -0
  650. package/dist/lib/runtime-sources/vendor/mbedtls/library/entropy_poll.h +64 -0
  651. package/dist/lib/runtime-sources/vendor/mbedtls/library/error.c +878 -0
  652. package/dist/lib/runtime-sources/vendor/mbedtls/library/gcm.c +1330 -0
  653. package/dist/lib/runtime-sources/vendor/mbedtls/library/hkdf.c +161 -0
  654. package/dist/lib/runtime-sources/vendor/mbedtls/library/hmac_drbg.c +633 -0
  655. package/dist/lib/runtime-sources/vendor/mbedtls/library/lmots.c +789 -0
  656. package/dist/lib/runtime-sources/vendor/mbedtls/library/lmots.h +288 -0
  657. package/dist/lib/runtime-sources/vendor/mbedtls/library/lms.c +778 -0
  658. package/dist/lib/runtime-sources/vendor/mbedtls/library/md.c +1108 -0
  659. package/dist/lib/runtime-sources/vendor/mbedtls/library/md5.c +426 -0
  660. package/dist/lib/runtime-sources/vendor/mbedtls/library/md_psa.h +26 -0
  661. package/dist/lib/runtime-sources/vendor/mbedtls/library/md_wrap.h +46 -0
  662. package/dist/lib/runtime-sources/vendor/mbedtls/library/memory_buffer_alloc.c +751 -0
  663. package/dist/lib/runtime-sources/vendor/mbedtls/library/mps_common.h +181 -0
  664. package/dist/lib/runtime-sources/vendor/mbedtls/library/mps_error.h +89 -0
  665. package/dist/lib/runtime-sources/vendor/mbedtls/library/mps_reader.c +538 -0
  666. package/dist/lib/runtime-sources/vendor/mbedtls/library/mps_reader.h +366 -0
  667. package/dist/lib/runtime-sources/vendor/mbedtls/library/mps_trace.c +112 -0
  668. package/dist/lib/runtime-sources/vendor/mbedtls/library/mps_trace.h +154 -0
  669. package/dist/lib/runtime-sources/vendor/mbedtls/library/net_sockets.c +694 -0
  670. package/dist/lib/runtime-sources/vendor/mbedtls/library/nist_kw.c +729 -0
  671. package/dist/lib/runtime-sources/vendor/mbedtls/library/oid.c +1166 -0
  672. package/dist/lib/runtime-sources/vendor/mbedtls/library/padlock.c +157 -0
  673. package/dist/lib/runtime-sources/vendor/mbedtls/library/padlock.h +111 -0
  674. package/dist/lib/runtime-sources/vendor/mbedtls/library/pem.c +554 -0
  675. package/dist/lib/runtime-sources/vendor/mbedtls/library/pk.c +1602 -0
  676. package/dist/lib/runtime-sources/vendor/mbedtls/library/pk_ecc.c +261 -0
  677. package/dist/lib/runtime-sources/vendor/mbedtls/library/pk_internal.h +241 -0
  678. package/dist/lib/runtime-sources/vendor/mbedtls/library/pk_wrap.c +1618 -0
  679. package/dist/lib/runtime-sources/vendor/mbedtls/library/pk_wrap.h +138 -0
  680. package/dist/lib/runtime-sources/vendor/mbedtls/library/pkcs12.c +437 -0
  681. package/dist/lib/runtime-sources/vendor/mbedtls/library/pkcs5.c +500 -0
  682. package/dist/lib/runtime-sources/vendor/mbedtls/library/pkcs7.c +787 -0
  683. package/dist/lib/runtime-sources/vendor/mbedtls/library/pkparse.c +1392 -0
  684. package/dist/lib/runtime-sources/vendor/mbedtls/library/pkwrite.c +631 -0
  685. package/dist/lib/runtime-sources/vendor/mbedtls/library/pkwrite.h +121 -0
  686. package/dist/lib/runtime-sources/vendor/mbedtls/library/platform.c +402 -0
  687. package/dist/lib/runtime-sources/vendor/mbedtls/library/platform_util.c +258 -0
  688. package/dist/lib/runtime-sources/vendor/mbedtls/library/poly1305.c +492 -0
  689. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto.c +9532 -0
  690. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_aead.c +646 -0
  691. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_aead.h +499 -0
  692. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_cipher.c +747 -0
  693. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_cipher.h +316 -0
  694. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_client.c +22 -0
  695. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_core.h +983 -0
  696. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_core_common.h +52 -0
  697. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_driver_wrappers.h +2896 -0
  698. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.c +256 -0
  699. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.h +31 -0
  700. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_ecp.c +594 -0
  701. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_ecp.h +267 -0
  702. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_ffdh.c +361 -0
  703. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_ffdh.h +131 -0
  704. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_hash.c +470 -0
  705. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_hash.h +211 -0
  706. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_invasive.h +92 -0
  707. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_its.h +131 -0
  708. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_mac.c +505 -0
  709. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_mac.h +264 -0
  710. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_pake.c +571 -0
  711. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_pake.h +159 -0
  712. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_random.c +181 -0
  713. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_random.h +72 -0
  714. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_random_impl.h +200 -0
  715. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_rsa.c +714 -0
  716. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_rsa.h +321 -0
  717. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_se.c +373 -0
  718. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_se.h +192 -0
  719. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_slot_management.c +1137 -0
  720. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_slot_management.h +344 -0
  721. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_storage.c +481 -0
  722. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_crypto_storage.h +392 -0
  723. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_its_file.c +254 -0
  724. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_util.c +614 -0
  725. package/dist/lib/runtime-sources/vendor/mbedtls/library/psa_util_internal.h +100 -0
  726. package/dist/lib/runtime-sources/vendor/mbedtls/library/ripemd160.c +490 -0
  727. package/dist/lib/runtime-sources/vendor/mbedtls/library/rsa.c +3121 -0
  728. package/dist/lib/runtime-sources/vendor/mbedtls/library/rsa_alt_helpers.c +455 -0
  729. package/dist/lib/runtime-sources/vendor/mbedtls/library/rsa_alt_helpers.h +209 -0
  730. package/dist/lib/runtime-sources/vendor/mbedtls/library/rsa_internal.h +188 -0
  731. package/dist/lib/runtime-sources/vendor/mbedtls/library/sha1.c +480 -0
  732. package/dist/lib/runtime-sources/vendor/mbedtls/library/sha256.c +983 -0
  733. package/dist/lib/runtime-sources/vendor/mbedtls/library/sha3.c +721 -0
  734. package/dist/lib/runtime-sources/vendor/mbedtls/library/sha512.c +1115 -0
  735. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_cache.c +410 -0
  736. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_ciphersuites.c +2050 -0
  737. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_ciphersuites_internal.h +154 -0
  738. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_client.c +1023 -0
  739. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_client.h +22 -0
  740. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_cookie.c +384 -0
  741. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_debug_helpers.h +85 -0
  742. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_debug_helpers_generated.c +251 -0
  743. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_misc.h +3198 -0
  744. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_msg.c +6619 -0
  745. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_ticket.c +556 -0
  746. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls.c +10234 -0
  747. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls12_client.c +3688 -0
  748. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls12_server.c +4311 -0
  749. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls13_client.c +3208 -0
  750. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls13_generic.c +1793 -0
  751. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls13_invasive.h +23 -0
  752. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls13_keys.c +1918 -0
  753. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls13_keys.h +668 -0
  754. package/dist/lib/runtime-sources/vendor/mbedtls/library/ssl_tls13_server.c +3624 -0
  755. package/dist/lib/runtime-sources/vendor/mbedtls/library/threading.c +193 -0
  756. package/dist/lib/runtime-sources/vendor/mbedtls/library/threading_internal.h +28 -0
  757. package/dist/lib/runtime-sources/vendor/mbedtls/library/timing.c +152 -0
  758. package/dist/lib/runtime-sources/vendor/mbedtls/library/version.c +32 -0
  759. package/dist/lib/runtime-sources/vendor/mbedtls/library/version_features.c +856 -0
  760. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509.c +1776 -0
  761. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509_create.c +570 -0
  762. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509_crl.c +708 -0
  763. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509_crt.c +3311 -0
  764. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509_csr.c +648 -0
  765. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509_internal.h +101 -0
  766. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509write.c +174 -0
  767. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509write_crt.c +688 -0
  768. package/dist/lib/runtime-sources/vendor/mbedtls/library/x509write_csr.c +336 -0
  769. package/dist/lib/runtime-sources/vendor/quickjs-ng/CMakeLists.txt +566 -0
  770. package/dist/lib/runtime-sources/vendor/quickjs-ng/LICENSE +24 -0
  771. package/dist/lib/runtime-sources/vendor/quickjs-ng/README.md +24 -0
  772. package/dist/lib/runtime-sources/vendor/quickjs-ng/api-test.c +1195 -0
  773. package/dist/lib/runtime-sources/vendor/quickjs-ng/builtin-array-fromasync.h +119 -0
  774. package/dist/lib/runtime-sources/vendor/quickjs-ng/builtin-iterator-zip-keyed.h +332 -0
  775. package/dist/lib/runtime-sources/vendor/quickjs-ng/builtin-iterator-zip.h +337 -0
  776. package/dist/lib/runtime-sources/vendor/quickjs-ng/cutils.h +1998 -0
  777. package/dist/lib/runtime-sources/vendor/quickjs-ng/dtoa.c +1619 -0
  778. package/dist/lib/runtime-sources/vendor/quickjs-ng/dtoa.h +87 -0
  779. package/dist/lib/runtime-sources/vendor/quickjs-ng/gen/function_source.c +81 -0
  780. package/dist/lib/runtime-sources/vendor/quickjs-ng/gen/hello.c +53 -0
  781. package/dist/lib/runtime-sources/vendor/quickjs-ng/gen/hello_module.c +106 -0
  782. package/dist/lib/runtime-sources/vendor/quickjs-ng/gen/repl.c +3036 -0
  783. package/dist/lib/runtime-sources/vendor/quickjs-ng/gen/standalone.c +323 -0
  784. package/dist/lib/runtime-sources/vendor/quickjs-ng/gen/test_fib.c +81 -0
  785. package/dist/lib/runtime-sources/vendor/quickjs-ng/libregexp-opcode.h +73 -0
  786. package/dist/lib/runtime-sources/vendor/quickjs-ng/libregexp.c +3474 -0
  787. package/dist/lib/runtime-sources/vendor/quickjs-ng/libregexp.h +101 -0
  788. package/dist/lib/runtime-sources/vendor/quickjs-ng/libunicode-table.h +5173 -0
  789. package/dist/lib/runtime-sources/vendor/quickjs-ng/libunicode.c +2069 -0
  790. package/dist/lib/runtime-sources/vendor/quickjs-ng/libunicode.h +172 -0
  791. package/dist/lib/runtime-sources/vendor/quickjs-ng/list.h +107 -0
  792. package/dist/lib/runtime-sources/vendor/quickjs-ng/lre-test.c +52 -0
  793. package/dist/lib/runtime-sources/vendor/quickjs-ng/qjs.c +762 -0
  794. package/dist/lib/runtime-sources/vendor/quickjs-ng/qjsc.c +673 -0
  795. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs-atom.h +280 -0
  796. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs-c-atomics.h +54 -0
  797. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs-libc.c +5037 -0
  798. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs-libc.h +87 -0
  799. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs-opcode.h +377 -0
  800. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs.c +64041 -0
  801. package/dist/lib/runtime-sources/vendor/quickjs-ng/quickjs.h +1447 -0
  802. package/dist/lib/runtime-sources/vendor/quickjs-ng/run-test262.c +2374 -0
  803. package/dist/lib/runtime-sources/vendor/quickjs-ng/unicode_gen.c +3121 -0
  804. package/dist/lib/runtime-sources/vendor/quickjs-ng/unicode_gen_def.h +310 -0
  805. package/dist/lib/runtime-sources/vendor/ryu/LICENSE-Boost +23 -0
  806. package/dist/lib/runtime-sources/vendor/ryu/common.h +114 -0
  807. package/dist/lib/runtime-sources/vendor/ryu/d2s.c +509 -0
  808. package/dist/lib/runtime-sources/vendor/ryu/d2s_full_table.h +367 -0
  809. package/dist/lib/runtime-sources/vendor/ryu/d2s_intrinsics.h +357 -0
  810. package/dist/lib/runtime-sources/vendor/ryu/d2s_small_table.h +186 -0
  811. package/dist/lib/runtime-sources/vendor/ryu/digit_table.h +35 -0
  812. package/dist/lib/runtime-sources/vendor/ryu/ryu.h +46 -0
  813. package/dist/lib/runtime-sources/vendor/unicode/LICENSE +39 -0
  814. package/dist/lib/runtime-sources/vendor/zlib/LICENSE +22 -0
  815. package/dist/lib/runtime-sources/vendor/zlib/adler32.c +164 -0
  816. package/dist/lib/runtime-sources/vendor/zlib/compress.c +75 -0
  817. package/dist/lib/runtime-sources/vendor/zlib/crc32.c +1049 -0
  818. package/dist/lib/runtime-sources/vendor/zlib/crc32.h +9446 -0
  819. package/dist/lib/runtime-sources/vendor/zlib/deflate.c +2139 -0
  820. package/dist/lib/runtime-sources/vendor/zlib/deflate.h +377 -0
  821. package/dist/lib/runtime-sources/vendor/zlib/gzclose.c +23 -0
  822. package/dist/lib/runtime-sources/vendor/zlib/gzguts.h +214 -0
  823. package/dist/lib/runtime-sources/vendor/zlib/gzlib.c +582 -0
  824. package/dist/lib/runtime-sources/vendor/zlib/gzread.c +602 -0
  825. package/dist/lib/runtime-sources/vendor/zlib/gzwrite.c +631 -0
  826. package/dist/lib/runtime-sources/vendor/zlib/infback.c +628 -0
  827. package/dist/lib/runtime-sources/vendor/zlib/inffast.c +320 -0
  828. package/dist/lib/runtime-sources/vendor/zlib/inffast.h +11 -0
  829. package/dist/lib/runtime-sources/vendor/zlib/inffixed.h +94 -0
  830. package/dist/lib/runtime-sources/vendor/zlib/inflate.c +1526 -0
  831. package/dist/lib/runtime-sources/vendor/zlib/inflate.h +126 -0
  832. package/dist/lib/runtime-sources/vendor/zlib/inftrees.c +299 -0
  833. package/dist/lib/runtime-sources/vendor/zlib/inftrees.h +62 -0
  834. package/dist/lib/runtime-sources/vendor/zlib/trees.c +1117 -0
  835. package/dist/lib/runtime-sources/vendor/zlib/trees.h +128 -0
  836. package/dist/lib/runtime-sources/vendor/zlib/uncompr.c +85 -0
  837. package/dist/lib/runtime-sources/vendor/zlib/zconf.h +543 -0
  838. package/dist/lib/runtime-sources/vendor/zlib/zlib.h +1938 -0
  839. package/dist/lib/runtime-sources/vendor/zlib/zutil.c +299 -0
  840. package/dist/lib/runtime-sources/vendor/zlib/zutil.h +254 -0
  841. package/dist/lib/scriptc-comptime +0 -0
  842. package/dist/lib/typescript/LICENSE +55 -0
  843. package/dist/lib/typescript/NOTICE.txt +436 -0
  844. package/dist/lib/typescript/lib/lib.d.ts +20 -0
  845. package/dist/lib/typescript/lib/lib.decorators.d.ts +382 -0
  846. package/dist/lib/typescript/lib/lib.decorators.legacy.d.ts +20 -0
  847. package/dist/lib/typescript/lib/lib.dom.asynciterable.d.ts +18 -0
  848. package/dist/lib/typescript/lib/lib.dom.d.ts +45125 -0
  849. package/dist/lib/typescript/lib/lib.dom.iterable.d.ts +18 -0
  850. package/dist/lib/typescript/lib/lib.es2015.collection.d.ts +159 -0
  851. package/dist/lib/typescript/lib/lib.es2015.core.d.ts +595 -0
  852. package/dist/lib/typescript/lib/lib.es2015.d.ts +26 -0
  853. package/dist/lib/typescript/lib/lib.es2015.generator.d.ts +75 -0
  854. package/dist/lib/typescript/lib/lib.es2015.iterable.d.ts +603 -0
  855. package/dist/lib/typescript/lib/lib.es2015.promise.d.ts +79 -0
  856. package/dist/lib/typescript/lib/lib.es2015.proxy.d.ts +126 -0
  857. package/dist/lib/typescript/lib/lib.es2015.reflect.d.ts +142 -0
  858. package/dist/lib/typescript/lib/lib.es2015.symbol.d.ts +44 -0
  859. package/dist/lib/typescript/lib/lib.es2015.symbol.wellknown.d.ts +324 -0
  860. package/dist/lib/typescript/lib/lib.es2016.array.include.d.ts +114 -0
  861. package/dist/lib/typescript/lib/lib.es2016.d.ts +19 -0
  862. package/dist/lib/typescript/lib/lib.es2016.full.d.ts +21 -0
  863. package/dist/lib/typescript/lib/lib.es2016.intl.d.ts +29 -0
  864. package/dist/lib/typescript/lib/lib.es2017.arraybuffer.d.ts +19 -0
  865. package/dist/lib/typescript/lib/lib.es2017.d.ts +24 -0
  866. package/dist/lib/typescript/lib/lib.es2017.date.d.ts +29 -0
  867. package/dist/lib/typescript/lib/lib.es2017.full.d.ts +21 -0
  868. package/dist/lib/typescript/lib/lib.es2017.intl.d.ts +42 -0
  869. package/dist/lib/typescript/lib/lib.es2017.object.d.ts +47 -0
  870. package/dist/lib/typescript/lib/lib.es2017.sharedmemory.d.ts +133 -0
  871. package/dist/lib/typescript/lib/lib.es2017.string.d.ts +47 -0
  872. package/dist/lib/typescript/lib/lib.es2017.typedarrays.d.ts +51 -0
  873. package/dist/lib/typescript/lib/lib.es2018.asyncgenerator.d.ts +75 -0
  874. package/dist/lib/typescript/lib/lib.es2018.asynciterable.d.ts +51 -0
  875. package/dist/lib/typescript/lib/lib.es2018.d.ts +22 -0
  876. package/dist/lib/typescript/lib/lib.es2018.full.d.ts +22 -0
  877. package/dist/lib/typescript/lib/lib.es2018.intl.d.ts +81 -0
  878. package/dist/lib/typescript/lib/lib.es2018.promise.d.ts +28 -0
  879. package/dist/lib/typescript/lib/lib.es2018.regexp.d.ts +35 -0
  880. package/dist/lib/typescript/lib/lib.es2019.array.d.ts +77 -0
  881. package/dist/lib/typescript/lib/lib.es2019.d.ts +22 -0
  882. package/dist/lib/typescript/lib/lib.es2019.full.d.ts +22 -0
  883. package/dist/lib/typescript/lib/lib.es2019.intl.d.ts +21 -0
  884. package/dist/lib/typescript/lib/lib.es2019.object.d.ts +31 -0
  885. package/dist/lib/typescript/lib/lib.es2019.string.d.ts +35 -0
  886. package/dist/lib/typescript/lib/lib.es2019.symbol.d.ts +22 -0
  887. package/dist/lib/typescript/lib/lib.es2020.bigint.d.ts +763 -0
  888. package/dist/lib/typescript/lib/lib.es2020.d.ts +25 -0
  889. package/dist/lib/typescript/lib/lib.es2020.date.d.ts +40 -0
  890. package/dist/lib/typescript/lib/lib.es2020.full.d.ts +22 -0
  891. package/dist/lib/typescript/lib/lib.es2020.intl.d.ts +472 -0
  892. package/dist/lib/typescript/lib/lib.es2020.number.d.ts +26 -0
  893. package/dist/lib/typescript/lib/lib.es2020.promise.d.ts +45 -0
  894. package/dist/lib/typescript/lib/lib.es2020.sharedmemory.d.ts +97 -0
  895. package/dist/lib/typescript/lib/lib.es2020.string.d.ts +42 -0
  896. package/dist/lib/typescript/lib/lib.es2020.symbol.wellknown.d.ts +39 -0
  897. package/dist/lib/typescript/lib/lib.es2021.d.ts +21 -0
  898. package/dist/lib/typescript/lib/lib.es2021.full.d.ts +22 -0
  899. package/dist/lib/typescript/lib/lib.es2021.intl.d.ts +164 -0
  900. package/dist/lib/typescript/lib/lib.es2021.promise.d.ts +46 -0
  901. package/dist/lib/typescript/lib/lib.es2021.string.d.ts +31 -0
  902. package/dist/lib/typescript/lib/lib.es2021.weakref.d.ts +76 -0
  903. package/dist/lib/typescript/lib/lib.es2022.array.d.ts +119 -0
  904. package/dist/lib/typescript/lib/lib.es2022.d.ts +23 -0
  905. package/dist/lib/typescript/lib/lib.es2022.error.d.ts +73 -0
  906. package/dist/lib/typescript/lib/lib.es2022.full.d.ts +22 -0
  907. package/dist/lib/typescript/lib/lib.es2022.intl.d.ts +143 -0
  908. package/dist/lib/typescript/lib/lib.es2022.object.d.ts +24 -0
  909. package/dist/lib/typescript/lib/lib.es2022.regexp.d.ts +37 -0
  910. package/dist/lib/typescript/lib/lib.es2022.string.d.ts +23 -0
  911. package/dist/lib/typescript/lib/lib.es2023.array.d.ts +922 -0
  912. package/dist/lib/typescript/lib/lib.es2023.collection.d.ts +19 -0
  913. package/dist/lib/typescript/lib/lib.es2023.d.ts +20 -0
  914. package/dist/lib/typescript/lib/lib.es2023.full.d.ts +22 -0
  915. package/dist/lib/typescript/lib/lib.es2023.intl.d.ts +62 -0
  916. package/dist/lib/typescript/lib/lib.es2024.arraybuffer.d.ts +63 -0
  917. package/dist/lib/typescript/lib/lib.es2024.collection.d.ts +27 -0
  918. package/dist/lib/typescript/lib/lib.es2024.d.ts +24 -0
  919. package/dist/lib/typescript/lib/lib.es2024.full.d.ts +22 -0
  920. package/dist/lib/typescript/lib/lib.es2024.object.d.ts +27 -0
  921. package/dist/lib/typescript/lib/lib.es2024.promise.d.ts +33 -0
  922. package/dist/lib/typescript/lib/lib.es2024.regexp.d.ts +23 -0
  923. package/dist/lib/typescript/lib/lib.es2024.sharedmemory.d.ts +66 -0
  924. package/dist/lib/typescript/lib/lib.es2024.string.d.ts +27 -0
  925. package/dist/lib/typescript/lib/lib.es2025.collection.d.ts +94 -0
  926. package/dist/lib/typescript/lib/lib.es2025.d.ts +23 -0
  927. package/dist/lib/typescript/lib/lib.es2025.float16.d.ts +443 -0
  928. package/dist/lib/typescript/lib/lib.es2025.full.d.ts +22 -0
  929. package/dist/lib/typescript/lib/lib.es2025.intl.d.ts +200 -0
  930. package/dist/lib/typescript/lib/lib.es2025.iterator.d.ts +146 -0
  931. package/dist/lib/typescript/lib/lib.es2025.promise.d.ts +32 -0
  932. package/dist/lib/typescript/lib/lib.es2025.regexp.d.ts +30 -0
  933. package/dist/lib/typescript/lib/lib.es5.d.ts +4599 -0
  934. package/dist/lib/typescript/lib/lib.es6.d.ts +21 -0
  935. package/dist/lib/typescript/lib/lib.esnext.array.d.ts +33 -0
  936. package/dist/lib/typescript/lib/lib.esnext.collection.d.ts +47 -0
  937. package/dist/lib/typescript/lib/lib.esnext.d.ts +27 -0
  938. package/dist/lib/typescript/lib/lib.esnext.date.d.ts +21 -0
  939. package/dist/lib/typescript/lib/lib.esnext.decorators.d.ts +26 -0
  940. package/dist/lib/typescript/lib/lib.esnext.disposable.d.ts +191 -0
  941. package/dist/lib/typescript/lib/lib.esnext.error.d.ts +22 -0
  942. package/dist/lib/typescript/lib/lib.esnext.full.d.ts +22 -0
  943. package/dist/lib/typescript/lib/lib.esnext.intl.d.ts +107 -0
  944. package/dist/lib/typescript/lib/lib.esnext.sharedmemory.d.ts +23 -0
  945. package/dist/lib/typescript/lib/lib.esnext.temporal.d.ts +485 -0
  946. package/dist/lib/typescript/lib/lib.esnext.typedarrays.d.ts +90 -0
  947. package/dist/lib/typescript/lib/lib.scripthost.d.ts +320 -0
  948. package/dist/lib/typescript/lib/lib.webworker.asynciterable.d.ts +18 -0
  949. package/dist/lib/typescript/lib/lib.webworker.d.ts +15606 -0
  950. package/dist/lib/typescript/lib/lib.webworker.importscripts.d.ts +21 -0
  951. package/dist/lib/typescript/lib/lib.webworker.iterable.d.ts +18 -0
  952. package/dist/lib/typescript/lib/tsc +0 -0
  953. package/dist/lib/typescript/package.json +45 -0
  954. package/dist/lib/wasi/cli/wasi-paths.js +41 -0
  955. package/dist/lib/wasi/cli/wasi-runner.js +28 -0
  956. package/dist/lib/wasi/package.json +1 -0
  957. package/dist/lib/wasi/wasi-paths.js +25 -0
  958. package/package.json +22 -6
  959. package/README.md +0 -3
  960. package/index.js +0 -2
@@ -0,0 +1,3708 @@
1
+ /* node:net — the inbound-networking slice: TCP servers and sockets over
2
+ * the event loop's readiness poller, the first LISTENING capability of
3
+ * the runtime. The poller is the scr_platform.h contract — kqueue on
4
+ * macOS/BSD (scr_loop_kqueue.c, a stateless spelling of the syscall
5
+ * sequences this file inlined historically), epoll+timerfd on Linux
6
+ * (scr_loop_epoll.c). Two Linux-only obligations shape this file's use
7
+ * of the seam: a watched fd is scrp_forget-ed BEFORE close(2) (epoll
8
+ * registrations can outlive a close; the kqueue backend's forget is a
9
+ * no-op so macOS behavior is untouched), and socket sends go through
10
+ * scr_net_send (MSG_NOSIGNAL where it exists) because Linux has no
11
+ * SO_NOSIGPIPE — a write to a closed peer must surface as an 'error'
12
+ * event, never a process-killing SIGPIPE.
13
+ *
14
+ * ── Design note (the server core) ────────────────────────────────────
15
+ *
16
+ * Object model. Two refcounted handle kinds, both LEAN allocations (no
17
+ * cycle header — the child precedent): ScrNetServer (a listener: fd,
18
+ * bound port, connection/error/close listener lists) and ScrNetSocket (a
19
+ * connection: fd, a state machine over the read/write halves, a growable
20
+ * write buffer, data/end/close/error/connect listener lists, an optional
21
+ * pipe destination, and — for accepted sockets — a +1 backref to the
22
+ * owning server so its connection count can gate the server's 'close').
23
+ * Listeners MOVE in (+1) and are released when the handle settles (a
24
+ * socket's 'close' fired, a server's 'close' fired, or the listen/connect
25
+ * failure delivered) — so a listener capturing its own handle cannot
26
+ * cycle past settlement, exactly the ScrChild ownership story. Handles a
27
+ * program abandons at exit are released by the unit's atexit cleanup, so
28
+ * the RC audit never mistakes a process-lifetime server for a leak.
29
+ *
30
+ * Event dispatch. One poller owned by this unit (lazily created), fds all
31
+ * non-blocking. The loop (scr_async.c) calls scr_net_dispatch() at every
32
+ * turn top — the scr_events.c hook shape — which alternates two phases
33
+ * until neither has work: (1) a SWEEP delivering deferred emits
34
+ * ('listening' callbacks, listen/connect failures, socket 'close', then
35
+ * server 'close' — socket-before-server order is what lets a drained
36
+ * server observe its last connection die in the same pass), and (2) a
37
+ * zero-timeout poller drain (accepts, reads, connect completions, write
38
+ * flushes) whose callbacks fire directly, macrotask-style on the main
39
+ * stack. The alternation stops early when a callback enqueued microtasks
40
+ * (scr_loop_has_ready) so promise jobs interleave between event batches,
41
+ * or when a callback threw (the loop surfaces the uncaught exception).
42
+ * Between turns the loop's idle poll(2) watches this unit's poller FD —
43
+ * kqueue and epoll fds both poll readable while events are pending — so socket
44
+ * readiness ends the sleep immediately; while curl's io poll owns the
45
+ * sleep instead (a --dynamic fetch in flight), net latency is capped at
46
+ * the signal-poll granularity, like signals.
47
+ *
48
+ * Read model. Sockets are CONSUMER-DRIVEN like the stdin slice: the read
49
+ * filter is armed only while a consumer exists (a 'data' listener or a
50
+ * pipe destination), one read(2) per arrived chunk, delivered borrowed to
51
+ * the listener snapshot (Node's emit-over-a-copy semantics; `once`
52
+ * entries leave the live list before running) and appended to the pipe
53
+ * destination. EOF fires 'end', then — allowHalfOpen is always false, the
54
+ * Node default — ends the write half; when both halves are done the fd
55
+ * closes and 'close' fires on the next sweep.
56
+ *
57
+ * Write model. write() attempts the syscall immediately when nothing is
58
+ * buffered (the common case: small responses go out in one call) and
59
+ * buffers the remainder with the write filter armed; end() marks the
60
+ * write half ENDING so the FIN (shutdown) goes out when the buffer
61
+ * drains. Backpressure is not modeled — Node's write() returns false and
62
+ * keeps buffering; this write() is void and buffers without bound.
63
+ *
64
+ * Loop liveness. A handle keeps the process alive from listen()/connect()
65
+ * until its 'close' delivers (scr_net_pending — the loop's exhaustion
66
+ * test): a listening server is a live interval, server.close() releases
67
+ * once every accepted connection drains, and an open socket holds the
68
+ * loop like Node's active TCP handle. A server that never listened and a
69
+ * socket already closed hold nothing.
70
+ *
71
+ * Close semantics, Node-matched: server.close() stops accepting NOW
72
+ * (the listening fd closes) and fires close callbacks + 'close' when the
73
+ * connection count reaches zero; socket 'end' precedes 'close';
74
+ * connect/listen failures fire 'error' then 'close' ('error' with no
75
+ * listener prints the error and exits 1 — the unhandled-'error'
76
+ * EventEmitter behavior, the child precedent); listeners registered
77
+ * after settlement release immediately and never fire; 'listening' (the
78
+ * listen callback) is deferred to the next dispatch pass, Node's
79
+ * next-tick emit.
80
+ *
81
+ * The differential harness pattern (tests/harness/server.test.ts): a
82
+ * LISTENING program cannot be compared by stdout alone — something must
83
+ * talk to it. Each fixture binds port 0, reports the real port over
84
+ * stderr (`PORT <n>\n` — stderr is never compared), and a per-case Node
85
+ * driver script issues the same requests against both lanes; the SERVER
86
+ * program's stdout/exit code and the DRIVER's stdout must each match
87
+ * byte-for-byte between the Node lane and the compiled lane. Ephemeral
88
+ * ports never appear in compared output. This is the template TLS/http2
89
+ * lanes inherit.
90
+ */
91
+ #include "scr_platform.h"
92
+ #include "scr_runtime.h"
93
+
94
+ #include <errno.h>
95
+ #include <limits.h>
96
+ #include <math.h>
97
+ #include <fcntl.h>
98
+ #include <stdio.h>
99
+ #include <stdlib.h>
100
+ #include <string.h>
101
+ #include <unistd.h>
102
+ #ifdef _WIN32
103
+ #include <winsock2.h>
104
+ #include <ws2tcpip.h>
105
+ #else
106
+ #include <arpa/inet.h>
107
+ #include <netdb.h> /* getaddrinfo — the client bridges' blocking lookup */
108
+ #include <netinet/in.h>
109
+ #include <netinet/tcp.h>
110
+ #include <sys/socket.h>
111
+ #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(_AIX) || defined(__sun)
112
+ #include <sys/param.h>
113
+ #endif
114
+ #endif
115
+
116
+ /* MinGW's errno headers do not expose ENOTSUP on every supported toolchain.
117
+ * Keep a stable internal value for the Node/libuv unsupported reuse-port
118
+ * result, while preserving the platform's EOPNOTSUPP spelling when present. */
119
+ #ifndef ENOTSUP
120
+ #ifdef EOPNOTSUPP
121
+ #define ENOTSUP EOPNOTSUPP
122
+ #else
123
+ #define ENOTSUP 4095
124
+ #endif
125
+ #endif
126
+
127
+ static void scr_net_oom(void) {
128
+ fputs("scriptc: out of memory\n", stderr);
129
+ abort();
130
+ }
131
+
132
+ #ifdef _WIN32
133
+ /* ── the winsock arm ───────────────────────────────────────────────────
134
+ * The BSD socket calls this file speaks, respelled once so every call
135
+ * site below stays byte-identical: SOCKETs narrow through the int fd
136
+ * contract (kernel handles fit — scr_child.c's stdio plumbing relies on
137
+ * the same), failures land their WSA code in errno TRANSLATED to the
138
+ * POSIX constant the call sites and the error-name table test (libuv
139
+ * performs the same translation for Node, so the spellings agree with
140
+ * the Windows oracle), socket reads are recv (ReadFile/_read do not
141
+ * apply to winsock handles), and close is closesocket. WSAStartup lives
142
+ * in scrp_poller_new (scr_loop_wsapoll.c) — every socket() site in this
143
+ * file is preceded by scr_net_poller_init(). Two call-shape notes: a
144
+ * pending nonblocking connect answers WSAEWOULDBLOCK where the sites
145
+ * test EINPROGRESS (the connect wrapper translates), and SO_ERROR
146
+ * answers a WSA code the getsockopt wrapper maps before the table sees
147
+ * it. No SIGPIPE exists on Windows — a closed-peer send just fails. */
148
+ static int scr_w32_map_err(int e) {
149
+ switch (e) {
150
+ case WSAEWOULDBLOCK: return EAGAIN;
151
+ case WSAEINTR: return EINTR;
152
+ case WSAECONNREFUSED: return ECONNREFUSED;
153
+ case WSAECONNRESET: return ECONNRESET;
154
+ case WSAECONNABORTED: return ECONNABORTED;
155
+ case WSAESHUTDOWN: return EPIPE; /* libuv's map: send-after-shutdown is EPIPE */
156
+ case WSAEADDRINUSE: return EADDRINUSE;
157
+ case WSAEACCES: return EACCES;
158
+ case WSAEADDRNOTAVAIL: return EADDRNOTAVAIL;
159
+ case WSAETIMEDOUT: return ETIMEDOUT;
160
+ case WSAEHOSTUNREACH: return EHOSTUNREACH;
161
+ case WSAENETUNREACH: return ENETUNREACH;
162
+ case WSAEINVAL: return EINVAL;
163
+ default: return e;
164
+ }
165
+ }
166
+
167
+ static void scr_w32_seterr(void) { errno = scr_w32_map_err((int)WSAGetLastError()); }
168
+
169
+ static int scr_w32_socket(int af, int type, int proto) {
170
+ SOCKET s = socket(af, type, proto);
171
+ if (s == INVALID_SOCKET) {
172
+ scr_w32_seterr();
173
+ return -1;
174
+ }
175
+ return (int)s;
176
+ }
177
+
178
+ static int scr_w32_bind(int fd, const struct sockaddr *sa, socklen_t len) {
179
+ if (bind((SOCKET)fd, sa, (int)len) != 0) {
180
+ scr_w32_seterr();
181
+ return -1;
182
+ }
183
+ return 0;
184
+ }
185
+
186
+ static int scr_w32_connect(int fd, const struct sockaddr *sa, socklen_t len) {
187
+ if (connect((SOCKET)fd, sa, (int)len) != 0) {
188
+ int e = (int)WSAGetLastError();
189
+ /* pending nonblocking connect: WSAEWOULDBLOCK here is the callers'
190
+ * EINPROGRESS, not recv's EAGAIN */
191
+ errno = e == WSAEWOULDBLOCK ? EINPROGRESS : scr_w32_map_err(e);
192
+ return -1;
193
+ }
194
+ return 0;
195
+ }
196
+
197
+ static int scr_w32_listen(int fd, int backlog) {
198
+ if (listen((SOCKET)fd, backlog) != 0) {
199
+ scr_w32_seterr();
200
+ return -1;
201
+ }
202
+ return 0;
203
+ }
204
+
205
+ static int scr_w32_accept(int fd, struct sockaddr *sa, socklen_t *len) {
206
+ int ilen = len != NULL ? (int)*len : 0;
207
+ SOCKET s = accept((SOCKET)fd, sa, len != NULL ? &ilen : NULL);
208
+ if (len != NULL) *len = (socklen_t)ilen;
209
+ if (s == INVALID_SOCKET) {
210
+ scr_w32_seterr();
211
+ return -1;
212
+ }
213
+ return (int)s;
214
+ }
215
+
216
+ static int scr_w32_getsockname(int fd, struct sockaddr *sa, socklen_t *len) {
217
+ int ilen = (int)*len;
218
+ int rc = getsockname((SOCKET)fd, sa, &ilen);
219
+ *len = (socklen_t)ilen;
220
+ if (rc != 0) {
221
+ scr_w32_seterr();
222
+ return -1;
223
+ }
224
+ return 0;
225
+ }
226
+
227
+ static int scr_w32_setsockopt(int fd, int level, int name, const void *val, socklen_t len) {
228
+ if (setsockopt((SOCKET)fd, level, name, (const char *)val, (int)len) != 0) {
229
+ scr_w32_seterr();
230
+ return -1;
231
+ }
232
+ return 0;
233
+ }
234
+
235
+ static int scr_w32_getsockopt(int fd, int level, int name, void *val, socklen_t *len) {
236
+ int ilen = (int)*len;
237
+ int rc = getsockopt((SOCKET)fd, level, name, (char *)val, &ilen);
238
+ *len = (socklen_t)ilen;
239
+ if (rc != 0) {
240
+ scr_w32_seterr();
241
+ return -1;
242
+ }
243
+ if (level == SOL_SOCKET && name == SO_ERROR && ilen == (int)sizeof(int)) {
244
+ *(int *)val = scr_w32_map_err(*(int *)val); /* the table speaks POSIX */
245
+ }
246
+ return 0;
247
+ }
248
+
249
+ static ssize_t scr_w32_read(int fd, void *buf, size_t len) {
250
+ int n = recv((SOCKET)fd, (char *)buf, len > 0x40000000 ? 0x40000000 : (int)len, 0);
251
+ if (n < 0) scr_w32_seterr();
252
+ return n;
253
+ }
254
+
255
+ static int scr_w32_close(int fd) {
256
+ if (closesocket((SOCKET)fd) != 0) {
257
+ scr_w32_seterr();
258
+ return -1;
259
+ }
260
+ return 0;
261
+ }
262
+
263
+ #define socket(af, type, proto) scr_w32_socket((af), (type), (proto))
264
+ #define bind(fd, sa, len) scr_w32_bind((fd), (sa), (len))
265
+ #define connect(fd, sa, len) scr_w32_connect((fd), (sa), (len))
266
+ #define listen(fd, backlog) scr_w32_listen((fd), (backlog))
267
+ #define accept(fd, sa, len) scr_w32_accept((fd), (sa), (len))
268
+ #define getsockname(fd, sa, len) scr_w32_getsockname((fd), (sa), (len))
269
+ #define setsockopt(fd, l, n, v, len) scr_w32_setsockopt((fd), (l), (n), (v), (len))
270
+ #define getsockopt(fd, l, n, v, len) scr_w32_getsockopt((fd), (l), (n), (v), (len))
271
+ #define read(fd, buf, len) scr_w32_read((fd), (buf), (len))
272
+ #define close(fd) scr_w32_close(fd)
273
+ #define SHUT_WR SD_SEND
274
+ #endif /* _WIN32 */
275
+
276
+ /* Node's error-code names for the socket errors this slice can meet. */
277
+ static const char *scr_net_errname(int err) {
278
+ switch (err) {
279
+ case ECONNREFUSED: return "ECONNREFUSED";
280
+ case ECONNRESET: return "ECONNRESET";
281
+ case ECONNABORTED: return "ECONNABORTED";
282
+ case EPIPE: return "EPIPE";
283
+ case EADDRINUSE: return "EADDRINUSE";
284
+ case EACCES: return "EACCES";
285
+ case EADDRNOTAVAIL: return "EADDRNOTAVAIL";
286
+ case ETIMEDOUT: return "ETIMEDOUT";
287
+ case EHOSTUNREACH: return "EHOSTUNREACH";
288
+ case ENETUNREACH: return "ENETUNREACH";
289
+ #ifdef EHOSTDOWN
290
+ case EHOSTDOWN: return "EHOSTDOWN"; /* absent from the win32 CRT */
291
+ #endif
292
+ case EINVAL: return "EINVAL";
293
+ case ENOTSUP: return "ENOTSUP";
294
+ #if defined(EOPNOTSUPP) && (!defined(ENOTSUP) || EOPNOTSUPP != ENOTSUP)
295
+ case EOPNOTSUPP: return "EOPNOTSUPP";
296
+ #endif
297
+ default: return "EUNKNOWN";
298
+ }
299
+ }
300
+
301
+ /* ── listener lists (the events/child snapshot discipline) ─────────────
302
+ * The types live in scr_runtime.h: scr_http.c reuses the whole family
303
+ * for its request-body listener lists. */
304
+
305
+ struct ScrNetOnce {
306
+ size_t rc;
307
+ bool fired;
308
+ };
309
+
310
+ ScrNetOnce *scr_net_once_new(void) {
311
+ ScrNetOnce *once = calloc(1, sizeof *once);
312
+ if (!once) scr_net_oom();
313
+ once->rc = 1;
314
+ return once;
315
+ }
316
+
317
+ ScrNetOnce *scr_net_once_retain(ScrNetOnce *once) {
318
+ once->rc++;
319
+ return once;
320
+ }
321
+
322
+ void scr_net_once_release(ScrNetOnce *once) {
323
+ if (once != NULL && --once->rc == 0) free(once);
324
+ }
325
+
326
+ void scr_net_ls_add(ScrNetLs *l, ScrClosure *cb, void *fn, bool once) {
327
+ if (l->n == l->cap) {
328
+ l->cap = l->cap ? l->cap * 2 : 2;
329
+ l->ls = realloc(l->ls, l->cap * sizeof *l->ls);
330
+ if (!l->ls) scr_net_oom();
331
+ }
332
+ l->ls[l->n].cb = cb;
333
+ l->ls[l->n].fn = fn;
334
+ l->ls[l->n].once = once;
335
+ l->ls[l->n].shared_once = NULL;
336
+ l->n++;
337
+ }
338
+
339
+ void scr_net_ls_add_shared_once(ScrNetLs *l, ScrClosure *cb, void *fn,
340
+ ScrNetOnce *once /*moves*/) {
341
+ scr_net_ls_add(l, cb, fn, true);
342
+ l->ls[l->n - 1].shared_once = once;
343
+ }
344
+
345
+ bool scr_net_ls_has_live(const ScrNetLs *l) {
346
+ for (size_t i = 0; i < l->n; i++) {
347
+ if (l->ls[i].shared_once == NULL || !l->ls[i].shared_once->fired) return true;
348
+ }
349
+ return false;
350
+ }
351
+
352
+ void scr_net_ls_drop(ScrNetLs *l) {
353
+ for (size_t i = 0; i < l->n; i++) {
354
+ scr_closure_release(l->ls[i].cb);
355
+ scr_net_once_release(l->ls[i].shared_once);
356
+ }
357
+ free(l->ls);
358
+ l->ls = NULL;
359
+ l->n = l->cap = 0;
360
+ }
361
+
362
+ /* Snapshot for a firing pass: entries retained; `once` entries leave the
363
+ * LIVE list before their callback runs (Node's once semantics — a
364
+ * re-delivery during the callback re-registers cleanly). Caller invokes
365
+ * each snapshot entry, releases it, and frees the vector. */
366
+ size_t scr_net_ls_snapshot(ScrNetLs *l, ScrNetL **out) {
367
+ size_t n = l->n;
368
+ if (n == 0) {
369
+ *out = NULL;
370
+ return 0;
371
+ }
372
+ ScrNetL *snap = malloc(n * sizeof *snap);
373
+ if (!snap) scr_net_oom();
374
+ size_t nsnap = 0;
375
+ size_t w = 0;
376
+ for (size_t i = 0; i < l->n; i++) {
377
+ ScrNetL entry = l->ls[i];
378
+ bool emit = entry.shared_once == NULL || !entry.shared_once->fired;
379
+ if (emit) {
380
+ if (entry.shared_once != NULL) entry.shared_once->fired = true;
381
+ snap[nsnap] = entry;
382
+ snap[nsnap].shared_once = NULL;
383
+ scr_closure_retain(snap[nsnap].cb);
384
+ nsnap++;
385
+ }
386
+ if (l->ls[i].once) {
387
+ scr_closure_release(l->ls[i].cb);
388
+ scr_net_once_release(l->ls[i].shared_once);
389
+ } else {
390
+ l->ls[w++] = l->ls[i];
391
+ }
392
+ }
393
+ l->n = w;
394
+ if (nsnap == 0) {
395
+ free(snap);
396
+ snap = NULL;
397
+ }
398
+ *out = snap;
399
+ return nsnap;
400
+ }
401
+
402
+ /* Fire a zero-payload event list (end/close/connect/listening) with the
403
+ * emitting handle bound as the ambient receiver for each callback (Node
404
+ * calls listeners with `this` === the emitter — scr_runtime.h's design
405
+ * note). `self` is BORROWED (the caller keeps the handle alive across
406
+ * the pass); NULL binds the undefined receiver. */
407
+ void scr_net_fire0_this(ScrNetLs *l, void *self, ScrDynHandleTag tag) {
408
+ ScrNetL *snap;
409
+ size_t n = scr_net_ls_snapshot(l, &snap);
410
+ scr_dyn_this_push(self, tag);
411
+ for (size_t i = 0; i < n; i++) {
412
+ if (!scr_exc_pending()) ((void (*)(ScrClosure *))snap[i].cb->fn)(snap[i].cb);
413
+ scr_closure_release(snap[i].cb);
414
+ }
415
+ scr_dyn_this_pop();
416
+ free(snap);
417
+ }
418
+
419
+ void scr_net_fire0(ScrNetLs *l) { scr_net_fire0_this(l, NULL, 0); }
420
+
421
+ /* Fire an error list through the ScrChildErrFn adapters (msg borrowed),
422
+ * the emitting handle bound as the ambient receiver. An 'error' with NO
423
+ * listener is fatal, like Node's unhandled 'error' EventEmitter throw:
424
+ * print and die 1 (_Exit skips atexit on purpose — the loop dies
425
+ * mid-turn with registries live, like process.exit). Exported:
426
+ * scr_http.c's req/res/client fire their 'error' the same way. */
427
+ void scr_net_fire_err_this(ScrNetLs *l, ScrStr *msg, void *self, ScrDynHandleTag tag) {
428
+ if (l->n == 0) {
429
+ fflush(stdout);
430
+ fprintf(stderr, "Unhandled 'error' event: Error: %s\n", msg->data);
431
+ _Exit(1);
432
+ }
433
+ ScrNetL *snap;
434
+ size_t n = scr_net_ls_snapshot(l, &snap);
435
+ scr_dyn_this_push(self, tag);
436
+ for (size_t i = 0; i < n; i++) {
437
+ if (!scr_exc_pending()) ((ScrChildErrFn)snap[i].fn)(snap[i].cb, msg);
438
+ scr_closure_release(snap[i].cb);
439
+ }
440
+ scr_dyn_this_pop();
441
+ free(snap);
442
+ }
443
+
444
+ void scr_net_fire_err(ScrNetLs *l, ScrStr *msg) { scr_net_fire_err_this(l, msg, NULL, 0); }
445
+
446
+ /* ── the handles ─────────────────────────────────────────────────────── */
447
+
448
+ enum { SCR_NET_K_SERVER = 1, SCR_NET_K_SOCKET = 2 };
449
+
450
+ struct ScrNetServer {
451
+ int kind; /* FIRST: poller udata routes on it */
452
+ size_t rc;
453
+ int fd; /* -1 while not listening */
454
+ int port;
455
+ bool listening;
456
+ bool closing; /* close() called; 'close' fires when conns drain */
457
+ bool close_emitted; /* settled: off the registry, listeners dropped */
458
+ bool emit_listening;
459
+ /* The writable http.Server timeout property values. Kept on the shared
460
+ * server handle because http/https servers retain that handle identity;
461
+ * plain net servers never expose these fields through the static type
462
+ * surface. Indices match lower-server.ts's selector ABI. */
463
+ double http_timeouts[5];
464
+ /* A dynamic write may store any JS value on these ordinary writable
465
+ * properties. Numeric writes stay in http_timeouts; every other value
466
+ * is retained here so dynamic reads preserve kind and identity. */
467
+ ScrDyn *http_timeout_dyn[5];
468
+ bool http_timeout_surface; /* true only for HTTP/1 and HTTPS servers */
469
+ bool defer_conn; /* TLS: 'connection' fires post-handshake, not at accept */
470
+ bool bound_v6; /* the bound family (address()'s 'IPv6'/'IPv4' split) */
471
+ ScrStr *bound_host; /* the explicit bind host (NULL = the host-less any:
472
+ * '::' when bound_v6, else '0.0.0.0' — Node's own
473
+ * address().address answers) */
474
+ ScrStr *pending_err; /* deferred listen failure */
475
+ size_t nconns;
476
+ ScrNetLs conn_ls, err_ls, close_ls, listening_cbs, timeout_ls;
477
+ /* protocol layer (scr_http.c): a C-level connection consumer + its
478
+ * context, freed with the handle */
479
+ ScrNetNativeConnFn native_conn;
480
+ void *native_ctx;
481
+ void (*native_ctx_free)(void *);
482
+ /* the HTTP-parser ctx ALIAS (borrowed — owned through the native-conn
483
+ * chain): late 'request' installs reach it even after a TLS wrap
484
+ * replaced native_ctx (the https/http2 servers). NULL = no parser. */
485
+ void *http_ctx;
486
+ /* The protocol layer's settle hook (scr_http.c): drops the ctx's OWN
487
+ * listener lists when the server settles — the settle-releases-
488
+ * listeners story extended across the layer seam. A request handler
489
+ * capturing its own server through a dyn binding box would otherwise
490
+ * cycle through edges the collector cannot trace (box → dyn → handle →
491
+ * ctx → closure → box). Takes http_ctx; NULL = no hook. */
492
+ void (*proto_settle)(void *http_ctx);
493
+ /* wrapper.close = fn — the portless close-proxy idiom: when set,
494
+ * server.close() invokes THIS closure (a compiler-emitted zero-arg
495
+ * wrapper around the user override) instead of closing; the override
496
+ * body reaches the real close through its bound `origClose` value
497
+ * (scr_net_server_close_direct — never re-consults the override). */
498
+ ScrClosure *close_override;
499
+ /* close-REQUEST order (a global stamp set by close_direct): drained
500
+ * servers settle in ascending order, matching Node's emission order
501
+ * when several close in one turn (the wrapper-closes-inner idiom). */
502
+ size_t close_seq;
503
+ bool in_registry;
504
+ struct ScrNetServer *next;
505
+ };
506
+
507
+ struct ScrNetSocket {
508
+ int kind; /* FIRST: poller udata routes on it */
509
+ size_t rc;
510
+ int fd; /* -1 once closed */
511
+ bool connecting;
512
+ bool rd_eof; /* peer FIN seen (or read half abandoned) */
513
+ bool enc_utf8; /* setEncoding('utf8'): 'data' delivers strings */
514
+ bool wr_ending; /* end() called: FIN when the buffer drains */
515
+ bool wr_done; /* FIN sent (or write half dead) */
516
+ bool had_error;
517
+ bool emit_close; /* fd closed; 'close' fires at the next sweep */
518
+ bool close_emitted; /* settled */
519
+ bool read_armed, write_armed;
520
+ /* write buffer: [whead, wlen) of wbuf is unsent */
521
+ char *wbuf;
522
+ size_t whead, wlen, wcap;
523
+ /* receive buffer: [rhead, rlen) of rbuf is arrived-but-unconsumed —
524
+ * fed by paused-mode reads ('readable' consumers) and unshift; drained
525
+ * FIRST by every consumer (data listeners, the parser attach, the TLS
526
+ * bio) so a peeked byte re-enters the stream ahead of the kernel's */
527
+ char *rbuf;
528
+ size_t rhead, rlen, rcap;
529
+ ScrNetSocket *pipe_dst; /* +1; src EOF end()s the dst, Node's pipe default */
530
+ /* peer identity for Node-shaped connect error messages */
531
+ char peer_ip[64];
532
+ int peer_port;
533
+ /* remoteAddress, cached at first read like Node's _getpeername — a
534
+ * value read while connected survives destroy; never-read sockets
535
+ * answer undefined after close */
536
+ ScrStr *remote_cache;
537
+ ScrStr *pending_err; /* deferred connect failure */
538
+ /* the caller-lookup dial (net.connect with a lookup option): true while
539
+ * the lookup decides; dial_ips holds its answered addresses (+1 each),
540
+ * dialed in order — a connect failure closes the fd and tries
541
+ * dial_ips[dial_i]; the LAST failure's message surfaces (Node's
542
+ * autoSelectFamily aggregate is the documented divergence) */
543
+ bool lookup_wait;
544
+ /* a deferred dial (the http agent's maxSockets queue): registered and
545
+ * "connecting" (writes buffer), the actual dial starts on
546
+ * scr_net_sock_dial_start */
547
+ bool dial_deferred;
548
+ ScrStr **dial_ips;
549
+ size_t dial_n, dial_i;
550
+ /* the in-flight dial chain's LAST failure — surfaced (moved into
551
+ * pending_err) only when the list exhausts; a later success drops it */
552
+ ScrStr *dial_err;
553
+ ScrNetLs data_ls, end_ls, close_ls, err_ls, conn_ls, timeout_ls, readable_ls;
554
+ /* Flow control (pause()/resume()): user_paused holds reads OFF even
555
+ * with consumers (kernel/TCP backpressure is the buffer); flowing
556
+ * counts as a consumer even with no 'data' listener
557
+ * (resume()'s flow-and-discard drain, how Node reaches 'end' on an
558
+ * unconsumed stream). resume() clears user_paused and sets flowing. */
559
+ bool user_paused;
560
+ bool flowing;
561
+ /* destroySoon(): end() now, destroy once the FIN actually went out */
562
+ bool destroy_on_finish;
563
+ /* socket.bytesWritten: every byte accepted by the write paths (user
564
+ * writes, protocol heads, pipe deliveries — plaintext on TLS sockets) */
565
+ size_t bytes_written;
566
+ /* end(callback)/write(chunk, callback): 'finish'-shaped callbacks fire
567
+ * from the SWEEP (never the registering stack — Node defers them too).
568
+ * finish_ls waits for the FIN (wr_done); wcb_ls waits for the write
569
+ * buffer to drain (this surface's flush moment). */
570
+ ScrNetLs finish_ls, wcb_ls;
571
+ bool finish_pending; /* wr_done seen: fire finish_ls at the next sweep */
572
+ /* a server whose 'connection' waits for this socket's handshake — the
573
+ * TLS defer target (+1; the socket's own `server` backref stays the
574
+ * ACCEPTING server, which may be the demux wrapper) */
575
+ ScrNetServer *conn_pending;
576
+ /* the idle timer (setTimeout): a one-shot poller timer keyed by this
577
+ * socket's pointer, re-armed on every read/write/connect activity —
578
+ * 'timeout' fires once per idle period and never destroys the socket,
579
+ * Node's semantics */
580
+ double timeout_ms;
581
+ bool timeout_armed;
582
+ ScrNetServer *server; /* +1 backref (accepted sockets), NULL for clients */
583
+ /* protocol layer (scr_http.c): a C-level reader — counts as a consumer
584
+ * for read-arming; its context BORROWS this socket and is freed with it */
585
+ ScrNetNativeDataFn native_data;
586
+ ScrNetNativeEventFn native_eof;
587
+ ScrNetNativeEventFn native_closed;
588
+ ScrNetNativeEventFn native_timeout;
589
+ ScrNetNativeTimeoutHandledFn native_http_timeout; /* HTTP req/res timeout handled */
590
+ ScrNetNativeEventFn native_established; /* client connect completed (the
591
+ * h2 session's 'connect' moment;
592
+ * fires before conn_ls) */
593
+ ScrNetNativeErrFn native_err; /* true = consumed (the protocol layer owns
594
+ * the error story); false falls through to
595
+ * this socket's own err_ls */
596
+ bool (*native_idle)(void *); /* HTTP parser: no active request or partial head */
597
+ void *native_ctx;
598
+ void (*native_ctx_free)(void *);
599
+ /* transport layer (scr_tls.c): reads/writes redirect through the ops
600
+ * once set; writes buffer and readiness drives the handshake until
601
+ * t_est. Sits BELOW the protocol layer — an https socket carries both
602
+ * (the parser in native_*, the TLS engine here). */
603
+ const ScrNetTransportOps *tops;
604
+ void *tctx;
605
+ bool t_est;
606
+ bool t_want_write; /* a handshake send hit EAGAIN: arm the write filter */
607
+ bool in_registry;
608
+ struct ScrNetSocket *next;
609
+ };
610
+
611
+ #ifdef SCR_RC_AUDIT
612
+ static long scr_net_live = 0;
613
+ long scr_net_live_count(void) { return scr_net_live; }
614
+ #endif
615
+
616
+ static ScrNetServer *scr_net_servers = NULL; /* registry: +1 each, tail-appended */
617
+ static ScrNetSocket *scr_net_socks = NULL;
618
+ static ScrPoller *scr_net_poller = NULL;
619
+
620
+ /* ── RC ──────────────────────────────────────────────────────────────── */
621
+
622
+ static void scr_net_close_fd_raw(int fd); /* forget-then-close, defined below */
623
+
624
+ ScrNetServer *scr_net_server_retain(ScrNetServer *s) {
625
+ if (s->rc != SIZE_MAX) s->rc++;
626
+ return s;
627
+ }
628
+
629
+ void scr_net_server_release(ScrNetServer *s) {
630
+ if (!s || s->rc == SIZE_MAX) return;
631
+ if (--s->rc == 0) {
632
+ if (s->native_ctx_free) s->native_ctx_free(s->native_ctx);
633
+ scr_net_ls_drop(&s->conn_ls);
634
+ scr_net_ls_drop(&s->err_ls);
635
+ scr_net_ls_drop(&s->close_ls);
636
+ scr_net_ls_drop(&s->listening_cbs);
637
+ scr_net_ls_drop(&s->timeout_ls);
638
+ scr_closure_release(s->close_override);
639
+ for (size_t i = 0; i < 5; i++) scr_dyn_release(s->http_timeout_dyn[i]);
640
+ scr_str_release(s->bound_host);
641
+ scr_str_release(s->pending_err);
642
+ if (s->fd >= 0) scr_net_close_fd_raw(s->fd);
643
+ #ifdef SCR_RC_AUDIT
644
+ scr_net_live--;
645
+ #endif
646
+ free(s);
647
+ }
648
+ }
649
+
650
+ void *scr_net_server_retain_v(void *p) { return scr_net_server_retain((ScrNetServer *)p); }
651
+ void scr_net_server_release_v(void *p) { scr_net_server_release((ScrNetServer *)p); }
652
+
653
+ ScrNetSocket *scr_net_sock_retain(ScrNetSocket *s) {
654
+ if (s->rc != SIZE_MAX) s->rc++;
655
+ return s;
656
+ }
657
+
658
+ void scr_net_sock_release(ScrNetSocket *s) {
659
+ if (!s || s->rc == SIZE_MAX) return;
660
+ if (--s->rc == 0) {
661
+ if (s->native_ctx_free) s->native_ctx_free(s->native_ctx);
662
+ if (s->tops && s->tops->free) s->tops->free(s->tctx);
663
+ scr_net_ls_drop(&s->data_ls);
664
+ scr_net_ls_drop(&s->end_ls);
665
+ scr_net_ls_drop(&s->close_ls);
666
+ scr_net_ls_drop(&s->err_ls);
667
+ scr_net_ls_drop(&s->conn_ls);
668
+ scr_net_ls_drop(&s->timeout_ls);
669
+ scr_net_ls_drop(&s->readable_ls);
670
+ scr_net_ls_drop(&s->finish_ls);
671
+ scr_net_ls_drop(&s->wcb_ls);
672
+ scr_str_release(s->pending_err);
673
+ scr_str_release(s->remote_cache);
674
+ for (size_t i = 0; i < s->dial_n; i++) scr_str_release(s->dial_ips[i]);
675
+ free(s->dial_ips);
676
+ scr_str_release(s->dial_err);
677
+ free(s->wbuf);
678
+ free(s->rbuf);
679
+ if (s->pipe_dst) scr_net_sock_release(s->pipe_dst);
680
+ if (s->conn_pending) scr_net_server_release(s->conn_pending);
681
+ if (s->server) scr_net_server_release(s->server);
682
+ if (s->fd >= 0) scr_net_close_fd_raw(s->fd);
683
+ #ifdef SCR_RC_AUDIT
684
+ scr_net_live--;
685
+ #endif
686
+ free(s);
687
+ }
688
+ }
689
+
690
+ void *scr_net_sock_retain_v(void *p) { return scr_net_sock_retain((ScrNetSocket *)p); }
691
+ void scr_net_sock_release_v(void *p) { scr_net_sock_release((ScrNetSocket *)p); }
692
+
693
+ /* ── poller plumbing (the scr_platform.h seam) ───────────────────────── */
694
+
695
+ static bool scr_net_poller_init(void) {
696
+ if (scr_net_poller != NULL) return true;
697
+ scr_net_poller = scrp_poller_new();
698
+ return scr_net_poller != NULL;
699
+ }
700
+
701
+ static void scr_net_nonblock(int fd) {
702
+ #ifdef _WIN32
703
+ u_long one = 1;
704
+ ioctlsocket((SOCKET)fd, FIONBIO, &one);
705
+ /* FD_CLOEXEC's spelling: spawned children must not inherit the socket */
706
+ SetHandleInformation((HANDLE)(SOCKET)fd, HANDLE_FLAG_INHERIT, 0);
707
+ #else
708
+ fcntl(fd, F_SETFL, O_NONBLOCK);
709
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
710
+ #ifdef SO_NOSIGPIPE
711
+ int one = 1;
712
+ setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof one);
713
+ #endif
714
+ #endif
715
+ }
716
+
717
+ /* SO_REUSEADDR on listeners, POSIX only — libuv's exact split. On Unix
718
+ * the flag lets a restarted server rebind its TIME_WAIT port (Node's
719
+ * behavior, so the historical call stands). On Windows the SAME flag
720
+ * means port hijacking: a second bind of an actively-listened port
721
+ * SUCCEEDS and so does its listen(), so EADDRINUSE never surfaces — the
722
+ * net-port-check/net-error-codes fixtures hang waiting for an 'error'
723
+ * that never comes. Winsock's default already permits the TIME_WAIT
724
+ * rebind, so omitting the flag there loses nothing and restores Node's
725
+ * (libuv's) EADDRINUSE. */
726
+ static void scr_net_listen_reuseaddr(int fd) {
727
+ #ifdef _WIN32
728
+ (void)fd;
729
+ #else
730
+ int one = 1;
731
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
732
+ #endif
733
+ }
734
+
735
+ /* Node/libuv's TCP reuse-port matrix. SO_REUSEPORT is deliberately NOT
736
+ * selected merely because a platform header happens to expose it: macOS's
737
+ * meaning is not the required TCP load-balancing contract, and Windows'
738
+ * SO_REUSEADDR is port hijacking rather than reuse-port support. FreeBSD's
739
+ * ordinary SO_REUSEPORT does not distribute connections, so FreeBSD 12+
740
+ * uses the load-balancing spelling instead. A setsockopt failure is returned
741
+ * to the caller so an unsupported kernel cannot silently become a singleton. */
742
+ static int scr_net_listen_reuseport(int fd) {
743
+ int rc;
744
+ #if defined(__FreeBSD__) && defined(__FreeBSD_version) && \
745
+ __FreeBSD_version >= 1200000 && defined(SO_REUSEPORT_LB)
746
+ int one = 1;
747
+ rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB, &one, sizeof one);
748
+ #elif (defined(__linux__) || defined(_AIX73) || \
749
+ (defined(__DragonFly__) && defined(__DragonFly_version) && __DragonFly_version >= 300600) || \
750
+ (defined(__sun) && !defined(__illumos__) && defined(SO_FLOW_NAME))) && \
751
+ defined(SO_REUSEPORT)
752
+ int one = 1;
753
+ rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof one);
754
+ #else
755
+ (void)fd;
756
+ errno = ENOTSUP;
757
+ return -1;
758
+ #endif
759
+ #if defined(__linux__) && defined(ENOPROTOOPT)
760
+ /* Linux kernels predating 3.9 expose no reuse-port TCP support. Keep
761
+ * Node's stable unsupported result instead of leaking ENOPROTOOPT. */
762
+ if (rc != 0 && errno == ENOPROTOOPT) errno = ENOTSUP;
763
+ #endif
764
+ return rc;
765
+ }
766
+
767
+ /* Shared bind setup for both host-less and explicit-interface listeners.
768
+ * SO_REUSEADDR remains first, reuse-port is requested next, and both are
769
+ * complete before bind/listen. The returned errno is the native failure. */
770
+ static int scr_net_bind_listen(int fd, const struct sockaddr *sa, socklen_t salen,
771
+ bool reuse_port) {
772
+ scr_net_listen_reuseaddr(fd);
773
+ if (reuse_port && scr_net_listen_reuseport(fd) != 0) return -1;
774
+ scr_net_nonblock(fd);
775
+ int rc = bind(fd, sa, salen);
776
+ if (rc == 0) rc = listen(fd, 511); /* Node's default backlog */
777
+ return rc;
778
+ }
779
+
780
+ static const char *scr_net_listen_reason(int err, bool explicit_host) {
781
+ if (err == EADDRINUSE) return "address already in use";
782
+ #ifdef EADDRNOTAVAIL
783
+ if (explicit_host && err == EADDRNOTAVAIL) return "address not available";
784
+ #endif
785
+ if (err == ENOTSUP) return "operation not supported";
786
+ #if defined(EOPNOTSUPP) && (!defined(ENOTSUP) || EOPNOTSUPP != ENOTSUP)
787
+ if (err == EOPNOTSUPP) return "operation not supported";
788
+ #endif
789
+ return "permission denied";
790
+ }
791
+
792
+ /* write(2) to a socket with SIGPIPE suppressed. macOS sets SO_NOSIGPIPE
793
+ * per fd above (send() path unchanged: write, exactly the historical
794
+ * call); Linux has no SO_NOSIGPIPE — MSG_NOSIGNAL on each send is the
795
+ * per-socket equivalent, turning a closed-peer write into EPIPE for the
796
+ * deferred 'error' sweep instead of process death. */
797
+ static ssize_t scr_net_send(int fd, const void *buf, size_t len) {
798
+ #if defined(_WIN32)
799
+ /* No SIGPIPE exists on Windows: a closed-peer send fails outright
800
+ * (WSAECONNRESET/WSAESHUTDOWN, mapped) for the deferred 'error' sweep. */
801
+ int n = send((SOCKET)fd, (const char *)buf, len > 0x40000000 ? 0x40000000 : (int)len, 0);
802
+ if (n < 0) scr_w32_seterr();
803
+ return n;
804
+ #elif defined(MSG_NOSIGNAL)
805
+ return send(fd, buf, len, MSG_NOSIGNAL);
806
+ #else
807
+ return write(fd, buf, len);
808
+ #endif
809
+ }
810
+
811
+ /* The idle timer rides the same poller: one-shot, keyed by the socket
812
+ * pointer (kqueue: EVFILT_TIMER ident; epoll: a per-key timerfd), in
813
+ * milliseconds. Re-arming an armed key replaces the deadline. */
814
+ static void scr_net_sock_timer_arm(ScrNetSocket *s) {
815
+ if (scr_net_poller == NULL || s->fd < 0 || s->timeout_ms <= 0) return;
816
+ (void)scrp_timer_arm(scr_net_poller, s, s->timeout_ms, s);
817
+ s->timeout_armed = true;
818
+ }
819
+
820
+ static void scr_net_sock_timer_cancel(ScrNetSocket *s) {
821
+ if (!s->timeout_armed) return;
822
+ s->timeout_armed = false;
823
+ if (scr_net_poller == NULL) return;
824
+ scrp_timer_cancel(scr_net_poller, s); /* may already have fired */
825
+ }
826
+
827
+ /* Activity: every read/write/connect resets the idle clock (re-arming an
828
+ * existing timer replaces its deadline). */
829
+ static void scr_net_sock_touch(ScrNetSocket *s) {
830
+ if (s->timeout_ms > 0 && s->fd >= 0) scr_net_sock_timer_arm(s);
831
+ }
832
+
833
+ /* Drop a watched fd's registrations and close it — forget MUST precede
834
+ * close(2) under epoll (see scr_platform.h; the kqueue forget is a
835
+ * no-op). Every close of a possibly-watched fd in this unit goes through
836
+ * here. */
837
+ static void scr_net_close_fd_raw(int fd) {
838
+ if (fd < 0) return;
839
+ if (scr_net_poller != NULL) scrp_forget(scr_net_poller, fd);
840
+ close(fd);
841
+ }
842
+
843
+ /* NULL-poller-safe watch wrappers (the historical scr_net_filter guards);
844
+ * registration failures are ignored exactly as kevent's always were. */
845
+ static void scr_net_watch_read(int fd, void *udata, bool on) {
846
+ if (scr_net_poller == NULL) return;
847
+ (void)scrp_watch_read(scr_net_poller, fd, udata, on);
848
+ }
849
+
850
+ static void scr_net_watch_write(int fd, void *udata, bool on) {
851
+ if (scr_net_poller == NULL) return;
852
+ (void)scrp_watch_write(scr_net_poller, fd, udata, on);
853
+ }
854
+
855
+ /* ── registries ──────────────────────────────────────────────────────── */
856
+
857
+ static void scr_net_server_register(ScrNetServer *s) {
858
+ if (s->in_registry) return;
859
+ s->in_registry = true;
860
+ s->next = NULL;
861
+ ScrNetServer **link = &scr_net_servers;
862
+ while (*link) link = &(*link)->next;
863
+ *link = scr_net_server_retain(s);
864
+ }
865
+
866
+ static void scr_net_server_unregister(ScrNetServer *s) {
867
+ if (!s->in_registry) return;
868
+ ScrNetServer **link = &scr_net_servers;
869
+ while (*link && *link != s) link = &(*link)->next;
870
+ if (*link) {
871
+ *link = s->next;
872
+ s->next = NULL;
873
+ s->in_registry = false;
874
+ scr_net_server_release(s);
875
+ }
876
+ }
877
+
878
+ static void scr_net_sock_register(ScrNetSocket *s) {
879
+ if (s->in_registry) return;
880
+ s->in_registry = true;
881
+ s->next = NULL;
882
+ ScrNetSocket **link = &scr_net_socks;
883
+ while (*link) link = &(*link)->next;
884
+ *link = scr_net_sock_retain(s);
885
+ }
886
+
887
+ static void scr_net_sock_unregister(ScrNetSocket *s) {
888
+ if (!s->in_registry) return;
889
+ ScrNetSocket **link = &scr_net_socks;
890
+ while (*link && *link != s) link = &(*link)->next;
891
+ if (*link) {
892
+ *link = s->next;
893
+ s->next = NULL;
894
+ s->in_registry = false;
895
+ scr_net_sock_release(s);
896
+ }
897
+ }
898
+
899
+ /* ── socket state machine ────────────────────────────────────────────── */
900
+
901
+ static ScrNetSocket *scr_net_sock_new(void) {
902
+ ScrNetSocket *s = calloc(1, sizeof *s);
903
+ if (!s) scr_net_oom();
904
+ s->kind = SCR_NET_K_SOCKET;
905
+ s->rc = 1;
906
+ s->fd = -1;
907
+ #ifdef SCR_RC_AUDIT
908
+ scr_net_live++;
909
+ #endif
910
+ return s;
911
+ }
912
+
913
+ /* Consumer-driven read arming (the stdin discipline: never read a byte
914
+ * nobody consumes — the socket buffer is the backpressure). */
915
+ static void scr_net_sock_update_read(ScrNetSocket *s) {
916
+ bool want = s->fd >= 0 && !s->connecting && !s->rd_eof && !s->user_paused &&
917
+ (s->data_ls.n > 0 || s->pipe_dst != NULL || s->native_data != NULL ||
918
+ s->flowing /* resume(): flow (and discard sans listeners) */ ||
919
+ s->readable_ls.n > 0 /* paused-mode consumer: bytes buffer */ ||
920
+ s->tops != NULL /* a transport is ALWAYS a consumer: the TLS
921
+ * layer must process protocol frames (the
922
+ * handshake, close_notify, 1.3 tickets)
923
+ * even when no app consumer exists, and a
924
+ * peer's FIN must reach the teardown —
925
+ * decrypted app data buffers like the
926
+ * paused-mode path's */ ||
927
+ s->wr_done /* FIN sent: drain to EOF so the peer's close is
928
+ * seen even with no consumer — Node resumes a
929
+ * finished socket the same way */);
930
+ if (want && !s->read_armed) {
931
+ scr_net_watch_read(s->fd, s, true);
932
+ s->read_armed = true;
933
+ } else if (!want && s->read_armed) {
934
+ scr_net_watch_read(s->fd, s, false);
935
+ s->read_armed = false;
936
+ }
937
+ }
938
+
939
+ static void scr_net_sock_update_write(ScrNetSocket *s) {
940
+ bool want = s->fd >= 0 && (s->connecting || s->wlen > s->whead || s->t_want_write);
941
+ if (want && !s->write_armed) {
942
+ scr_net_watch_write(s->fd, s, true);
943
+ s->write_armed = true;
944
+ } else if (!want && s->write_armed) {
945
+ scr_net_watch_write(s->fd, s, false);
946
+ s->write_armed = false;
947
+ }
948
+ }
949
+
950
+ /* Close the fd (registrations dropped first — the epoll obligation) and
951
+ * flag the 'close' sweep. */
952
+ static void scr_net_sock_close_fd(ScrNetSocket *s) {
953
+ scr_net_sock_timer_cancel(s);
954
+ if (s->fd >= 0) {
955
+ scr_net_close_fd_raw(s->fd);
956
+ s->fd = -1;
957
+ s->read_armed = s->write_armed = false;
958
+ }
959
+ if (!s->close_emitted) s->emit_close = true;
960
+ }
961
+
962
+ /* The FIN half: called when the write half is ENDING and the buffer just
963
+ * drained (or was empty). Full close once the read half is done too. */
964
+ static void scr_net_sock_maybe_finish_write(ScrNetSocket *s) {
965
+ if (s->fd < 0 || !s->wr_ending || s->wr_done || s->wlen > s->whead) return;
966
+ /* a transport says goodbye first (TLS close_notify), best-effort */
967
+ if (s->tops && s->t_est) s->tops->shutdown_write(s->tctx);
968
+ shutdown(s->fd, SHUT_WR);
969
+ s->wr_done = true;
970
+ if (s->finish_ls.n > 0) s->finish_pending = true; /* end(cb): the sweep fires it */
971
+ if (s->destroy_on_finish) {
972
+ /* destroySoon(): the FIN is out — tear down now (Node's 'finish'-then-
973
+ * destroy). The close emits through the ordinary sweep. */
974
+ scr_net_sock_close_fd(s);
975
+ return;
976
+ }
977
+ if (s->rd_eof) scr_net_sock_close_fd(s);
978
+ else scr_net_sock_update_read(s); /* the drain-to-EOF mode arms here */
979
+ }
980
+
981
+ /* Append bytes to the write buffer (post-immediate-write remainder, or
982
+ * everything while connecting/buffered). */
983
+ static void scr_net_sock_buffer(ScrNetSocket *s, const char *data, size_t len) {
984
+ if (len == 0) return;
985
+ /* compact the consumed head first */
986
+ if (s->whead > 0) {
987
+ memmove(s->wbuf, s->wbuf + s->whead, s->wlen - s->whead);
988
+ s->wlen -= s->whead;
989
+ s->whead = 0;
990
+ }
991
+ if (s->wlen + len > s->wcap) {
992
+ size_t cap = s->wcap ? s->wcap : 4096;
993
+ while (cap < s->wlen + len) cap *= 2;
994
+ s->wbuf = realloc(s->wbuf, cap);
995
+ if (!s->wbuf) scr_net_oom();
996
+ s->wcap = cap;
997
+ }
998
+ memcpy(s->wbuf + s->wlen, data, len);
999
+ s->wlen += len;
1000
+ }
1001
+
1002
+ /* The write path shared by write()/end(data)/pipe delivery. Ignored on a
1003
+ * dead or ended write half (Node fires 'error' there; this slice drops —
1004
+ * SEMANTICS.md documents the bound). */
1005
+ static void scr_net_sock_write_raw(ScrNetSocket *s, const char *data, size_t len) {
1006
+ /* A socket whose dial hasn't STARTED yet (the agent's deferred dial,
1007
+ * the caller-lookup wait) has no fd but is logically connecting —
1008
+ * bytes buffer and flush at establishment like any mid-connect write. */
1009
+ bool pre_dial = s->fd < 0 && (s->dial_deferred || s->lookup_wait) &&
1010
+ !s->wr_ending && !s->close_emitted;
1011
+ if (!pre_dial && (s->fd < 0 || s->wr_ending || s->close_emitted)) return;
1012
+ if (len == 0) return;
1013
+ s->bytes_written += len; /* accepted bytes (Node counts buffered ones too) */
1014
+ if (pre_dial || s->connecting || s->wlen > s->whead || (s->tops && !s->t_est)) {
1015
+ /* mid-connect and mid-handshake bytes buffer; the flush after
1016
+ * 'connect'/establishment sends them */
1017
+ scr_net_sock_buffer(s, data, len);
1018
+ scr_net_sock_update_write(s);
1019
+ return;
1020
+ }
1021
+ ssize_t sent = s->tops ? s->tops->xwrite(s->tctx, data, len) : scr_net_send(s->fd, data, len);
1022
+ if (sent > 0) scr_net_sock_touch(s);
1023
+ if (sent < 0) {
1024
+ if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) sent = 0;
1025
+ else {
1026
+ /* Delivery failure (EPIPE/ECONNRESET): defer to the error sweep. */
1027
+ char msg[96];
1028
+ snprintf(msg, sizeof msg, "write %s", scr_net_errname(errno));
1029
+ if (!s->pending_err) s->pending_err = scr_str_new(msg, strlen(msg));
1030
+ s->had_error = true;
1031
+ scr_net_sock_close_fd(s);
1032
+ return;
1033
+ }
1034
+ }
1035
+ if ((size_t)sent < len) {
1036
+ scr_net_sock_buffer(s, data + sent, len - (size_t)sent);
1037
+ scr_net_sock_update_write(s);
1038
+ }
1039
+ }
1040
+
1041
+ /* Flush on write-readiness; drives the FIN when ENDING. */
1042
+ static void scr_net_sock_flush(ScrNetSocket *s) {
1043
+ if (s->tops && !s->t_est) return; /* nothing moves until the handshake ends */
1044
+ while (s->fd >= 0 && s->wlen > s->whead) {
1045
+ ssize_t sent = s->tops ? s->tops->xwrite(s->tctx, s->wbuf + s->whead, s->wlen - s->whead)
1046
+ : scr_net_send(s->fd, s->wbuf + s->whead, s->wlen - s->whead);
1047
+ if (sent < 0) {
1048
+ if (errno == EINTR) continue;
1049
+ if (errno == EAGAIN || errno == EWOULDBLOCK) return;
1050
+ char msg[96];
1051
+ snprintf(msg, sizeof msg, "write %s", scr_net_errname(errno));
1052
+ if (!s->pending_err) s->pending_err = scr_str_new(msg, strlen(msg));
1053
+ s->had_error = true;
1054
+ scr_net_sock_close_fd(s);
1055
+ return;
1056
+ }
1057
+ if (sent > 0) scr_net_sock_touch(s);
1058
+ s->whead += (size_t)sent;
1059
+ }
1060
+ if (s->wlen == s->whead) {
1061
+ s->whead = s->wlen = 0;
1062
+ scr_net_sock_update_write(s);
1063
+ scr_net_sock_maybe_finish_write(s);
1064
+ }
1065
+ }
1066
+
1067
+ /* EOF: 'end' fires now (directly — Node's poll-phase emit), then the
1068
+ * write half ends (allowHalfOpen false), and the fd closes once the FIN
1069
+ * is out. 'close' waits for the sweep. */
1070
+ static void scr_net_sock_eof(ScrNetSocket *s) {
1071
+ s->rd_eof = true;
1072
+ scr_net_sock_update_read(s);
1073
+ if (s->native_eof) {
1074
+ s->native_eof(s->native_ctx);
1075
+ if (scr_exc_pending()) return;
1076
+ }
1077
+ if (s->pipe_dst) {
1078
+ /* pipe's end-the-destination default */
1079
+ ScrNetSocket *dst = s->pipe_dst;
1080
+ if (!dst->wr_ending && dst->fd >= 0) {
1081
+ dst->wr_ending = true;
1082
+ scr_net_sock_maybe_finish_write(dst);
1083
+ }
1084
+ }
1085
+ scr_net_fire0_this(&s->end_ls, s, SCR_DYNH_NET_SOCKET);
1086
+ if (scr_exc_pending()) return;
1087
+ if (!s->wr_ending) {
1088
+ s->wr_ending = true;
1089
+ scr_net_sock_maybe_finish_write(s);
1090
+ }
1091
+ if (s->wr_done) scr_net_sock_close_fd(s);
1092
+ }
1093
+
1094
+ /* Deliver one arrived chunk to the socket's consumers (the protocol
1095
+ * layer, the pipe destination, the 'data' listeners). Returns false when
1096
+ * a callback threw (the caller bails; the loop surfaces it). */
1097
+ static bool scr_net_sock_deliver(ScrNetSocket *s, const char *buf, size_t n) {
1098
+ if (s->native_data) {
1099
+ s->native_data(s->native_ctx, buf, n);
1100
+ if (scr_exc_pending()) return false;
1101
+ /* the protocol layer OWNS this chunk exclusively — an upgrade
1102
+ * handover inside the call (native reader cleared, 'data' listeners
1103
+ * registered) must not re-deliver bytes the parser consumed; the
1104
+ * next chunk takes the listener path */
1105
+ return true;
1106
+ }
1107
+ if (s->pipe_dst) scr_net_sock_write_raw(s->pipe_dst, buf, n);
1108
+ if (s->data_ls.n > 0) {
1109
+ ScrBytes *chunk = scr_bytes_new(SCR_BYTES_U8, (double)n);
1110
+ memcpy(chunk->data, buf, n);
1111
+ ScrNetL *snap;
1112
+ size_t nl = scr_net_ls_snapshot(&s->data_ls, &snap);
1113
+ scr_dyn_this_push(s, SCR_DYNH_NET_SOCKET);
1114
+ scr_dyn_chunk_enc(s->enc_utf8);
1115
+ for (size_t i = 0; i < nl; i++) {
1116
+ if (!scr_exc_pending()) ((ScrNetDataFn)snap[i].fn)(snap[i].cb, chunk);
1117
+ scr_closure_release(snap[i].cb);
1118
+ }
1119
+ scr_dyn_chunk_enc(false);
1120
+ scr_dyn_this_pop();
1121
+ free(snap);
1122
+ scr_bytes_release(chunk);
1123
+ if (scr_exc_pending()) return false;
1124
+ }
1125
+ return true;
1126
+ }
1127
+
1128
+ /* One readable wake: read until EAGAIN/EOF OR a bounded batch, one 'data'
1129
+ * emit per read(2) chunk (Node's chunking is arrival-driven too — only the
1130
+ * reassembled bytes are contractual, the stdin stance). The batch bound is
1131
+ * the loop's fairness fence: a continuously writing peer can otherwise keep
1132
+ * every nonblocking read successful forever and strand timers plus every
1133
+ * other fd inside this function. All poller arms are level-triggered, so
1134
+ * unread kernel bytes make the socket ready again on the next loop turn.
1135
+ * Peeked/unshifted bytes in the receive buffer deliver first — they precede
1136
+ * the kernel's in the stream. A TLS socket drains those through the engine's
1137
+ * bio instead. */
1138
+ static void scr_net_sock_append_rbuf(ScrNetSocket *s, const char *data, size_t len);
1139
+ static void scr_net_sock_transport_pump(ScrNetSocket *s);
1140
+
1141
+ static void scr_net_sock_read(ScrNetSocket *s) {
1142
+ size_t reads_left = 32; /* at most 2 MiB with the 64 KiB read buffer */
1143
+ if (s->tops && !s->t_est) return; /* readiness feeds the handshake pump instead */
1144
+ for (;;) {
1145
+ if (s->fd < 0 || s->user_paused) return;
1146
+ bool flowing = s->data_ls.n > 0 || s->pipe_dst || s->native_data || s->flowing;
1147
+ /* buffered (peeked/unshifted) bytes first — they precede the
1148
+ * kernel's in the stream; a TLS engine drains them through its bio */
1149
+ if (!s->tops && flowing && s->rlen > s->rhead) {
1150
+ char buf[65536];
1151
+ size_t take = scr_net_sock_take_buffered(s, buf, sizeof buf);
1152
+ if (!scr_net_sock_deliver(s, buf, take)) return;
1153
+ scr_net_sock_update_read(s);
1154
+ continue;
1155
+ }
1156
+ if (s->rd_eof || (!flowing && s->readable_ls.n == 0 && !s->wr_done &&
1157
+ !(s->tops != NULL && s->t_est))) {
1158
+ /* No consumer: stay paused — except through an ESTABLISHED
1159
+ * transport, which must keep processing protocol frames (close
1160
+ * alerts, 1.3 tickets) so a peer's close reaches the teardown
1161
+ * (the handler-less TLS server whose client hangs up). */
1162
+ return;
1163
+ }
1164
+ char buf[65536];
1165
+ ssize_t n = s->tops ? s->tops->xread(s->tctx, buf, sizeof buf) : read(s->fd, buf, sizeof buf);
1166
+ if (n < 0) {
1167
+ if (errno == EINTR) continue;
1168
+ if (errno == EAGAIN || errno == EWOULDBLOCK) return;
1169
+ char msg[96];
1170
+ snprintf(msg, sizeof msg, "read %s", scr_net_errname(errno));
1171
+ if (!s->pending_err) s->pending_err = scr_str_new(msg, strlen(msg));
1172
+ s->had_error = true;
1173
+ scr_net_sock_close_fd(s);
1174
+ return;
1175
+ }
1176
+ if (n == 0) {
1177
+ /* EOF announces 'readable' first (Node: a read() there answers
1178
+ * null — the demux's dead-peer arm), then 'end' and the teardown */
1179
+ scr_net_fire0_this(&s->readable_ls, s, SCR_DYNH_NET_SOCKET);
1180
+ if (scr_exc_pending()) return;
1181
+ scr_net_sock_eof(s);
1182
+ return;
1183
+ }
1184
+ scr_net_sock_touch(s);
1185
+ if (flowing) {
1186
+ if (!scr_net_sock_deliver(s, buf, (size_t)n)) return;
1187
+ } else if (s->readable_ls.n == 0) {
1188
+ /* the drain-to-EOF modes (wr_done, or an established transport
1189
+ * with no consumer): bytes arriving with nobody listening drop —
1190
+ * Node's resumed-but-unconsumed stream for the FIN-sent arm; for
1191
+ * the transport arm the peer would have to send app data at a
1192
+ * handler-less server for the difference to observe */
1193
+ } else {
1194
+ /* paused mode ('readable' consumers only): buffer and announce —
1195
+ * the listener consumes via read()/unshift */
1196
+ scr_net_sock_append_rbuf(s, buf, (size_t)n);
1197
+ scr_net_fire0_this(&s->readable_ls, s, SCR_DYNH_NET_SOCKET);
1198
+ if (scr_exc_pending()) return;
1199
+ if (s->tops && !s->t_est) {
1200
+ /* the listener routed this socket into a TLS server: the peeked
1201
+ * bytes now belong to the engine, and the poller may never signal
1202
+ * again if the whole flight is already buffered — pump NOW */
1203
+ scr_net_sock_transport_pump(s);
1204
+ return;
1205
+ }
1206
+ }
1207
+ scr_net_sock_update_read(s); /* a once-listener may have been the last consumer */
1208
+ if (--reads_left == 0) return;
1209
+ }
1210
+ }
1211
+
1212
+ static void scr_net_sock_transport_pump(ScrNetSocket *s);
1213
+
1214
+ static void scr_net_sock_dial_next(ScrNetSocket *s);
1215
+
1216
+ /* Connect completion (write-readiness while connecting). */
1217
+ static void scr_net_sock_connect_done(ScrNetSocket *s) {
1218
+ int err = 0;
1219
+ socklen_t len = sizeof err;
1220
+ if (getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &err, &len) != 0) err = errno;
1221
+ s->connecting = false;
1222
+ if (err != 0 && s->dial_i < s->dial_n) {
1223
+ /* a caller-lookup dial with addresses left: record the failure
1224
+ * (last-wins, surfaced only on exhaustion) and retry QUIETLY — no
1225
+ * 'error'/'close' until the list runs out */
1226
+ char msg[128];
1227
+ snprintf(msg, sizeof msg, "connect %s %s:%d", scr_net_errname(err), s->peer_ip,
1228
+ s->peer_port);
1229
+ scr_str_release(s->dial_err);
1230
+ s->dial_err = scr_str_new(msg, strlen(msg));
1231
+ scr_net_close_fd_raw(s->fd); /* registrations dropped, then the fd */
1232
+ s->fd = -1;
1233
+ s->read_armed = s->write_armed = false;
1234
+ scr_net_sock_dial_next(s);
1235
+ return;
1236
+ }
1237
+ if (err != 0) {
1238
+ char msg[128];
1239
+ snprintf(msg, sizeof msg, "connect %s %s:%d", scr_net_errname(err), s->peer_ip,
1240
+ s->peer_port);
1241
+ if (s->dial_n > 0) {
1242
+ /* the dial chain's LAST address failed asynchronously */
1243
+ scr_str_release(s->dial_err);
1244
+ s->dial_err = NULL;
1245
+ if (!s->pending_err) s->pending_err = scr_str_new(msg, strlen(msg));
1246
+ } else if (!s->pending_err) {
1247
+ s->pending_err = scr_str_new(msg, strlen(msg));
1248
+ }
1249
+ s->had_error = true;
1250
+ scr_net_sock_close_fd(s);
1251
+ return;
1252
+ }
1253
+ if (s->dial_err) {
1254
+ /* an earlier address failed but THIS one connected: the recorded
1255
+ * failure never surfaces */
1256
+ scr_str_release(s->dial_err);
1257
+ s->dial_err = NULL;
1258
+ }
1259
+ scr_net_sock_update_write(s); /* keeps the filter iff bytes are buffered */
1260
+ scr_net_sock_update_read(s);
1261
+ scr_net_sock_touch(s);
1262
+ if (s->tops && !s->t_est) {
1263
+ /* TCP is up; the TLS handshake starts now. 'connect' listeners wait
1264
+ * for establishment (they registered as secureConnect) and buffered
1265
+ * bytes flush there too. */
1266
+ scr_net_sock_transport_pump(s);
1267
+ return;
1268
+ }
1269
+ if (s->native_established) {
1270
+ s->native_established(s->native_ctx);
1271
+ if (scr_exc_pending()) return;
1272
+ }
1273
+ scr_net_fire0_this(&s->conn_ls, s, SCR_DYNH_NET_SOCKET);
1274
+ if (scr_exc_pending()) return;
1275
+ scr_net_sock_flush(s);
1276
+ }
1277
+
1278
+ /* Drive the transport handshake off readiness until it settles. On
1279
+ * establishment: the protocol layer attaches (https' parser), a
1280
+ * deferred server 'connection' fires ('secureConnection' timing), the
1281
+ * socket's own 'connect' listeners fire (the client's secureConnect),
1282
+ * buffered writes flush, and any plaintext that rode in with the final
1283
+ * handshake flight delivers. Failure already tore the socket down via
1284
+ * scr_net_sock_transport_error. */
1285
+ static void scr_net_sock_transport_pump(ScrNetSocket *s) {
1286
+ if (!s->tops || s->t_est || s->fd < 0 || s->connecting) return;
1287
+ int r = s->tops->handshake(s->tctx);
1288
+ if (r == 0) {
1289
+ scr_net_sock_update_read(s);
1290
+ scr_net_sock_update_write(s);
1291
+ return;
1292
+ }
1293
+ if (r < 0) return; /* the transport reported the failure */
1294
+ s->t_est = true;
1295
+ scr_net_sock_touch(s);
1296
+ if (s->tops->on_established) {
1297
+ s->tops->on_established(s->tctx);
1298
+ if (scr_exc_pending()) return;
1299
+ }
1300
+ if (s->conn_pending) {
1301
+ /* the deferred 'connection' ('secureConnection' timing): the target
1302
+ * is the server this socket was routed INTO — the accepting server
1303
+ * for a plain TLS accept, the emit('connection') target after a
1304
+ * demux */
1305
+ ScrNetServer *target = s->conn_pending;
1306
+ s->conn_pending = NULL;
1307
+ if (!target->close_emitted) {
1308
+ ScrNetL *snap;
1309
+ size_t n = scr_net_ls_snapshot(&target->conn_ls, &snap);
1310
+ scr_dyn_this_push(target, SCR_DYNH_NET_SERVER);
1311
+ for (size_t i = 0; i < n; i++) {
1312
+ if (!scr_exc_pending()) ((ScrNetConnFn)snap[i].fn)(snap[i].cb, scr_net_sock_retain(s));
1313
+ scr_closure_release(snap[i].cb);
1314
+ }
1315
+ scr_dyn_this_pop();
1316
+ free(snap);
1317
+ }
1318
+ scr_net_server_release(target);
1319
+ if (scr_exc_pending()) return;
1320
+ }
1321
+ if (s->native_established) {
1322
+ s->native_established(s->native_ctx);
1323
+ if (scr_exc_pending()) return;
1324
+ }
1325
+ scr_net_fire0_this(&s->conn_ls, s, SCR_DYNH_NET_SOCKET);
1326
+ if (scr_exc_pending()) return;
1327
+ scr_net_sock_flush(s);
1328
+ scr_net_sock_update_read(s);
1329
+ scr_net_sock_update_write(s);
1330
+ scr_net_sock_read(s); /* plaintext buffered inside the engine, if any */
1331
+ }
1332
+
1333
+ /* ── the server ──────────────────────────────────────────────────────── */
1334
+
1335
+ static ScrNetServer *scr_net_server_new(void) {
1336
+ ScrNetServer *s = calloc(1, sizeof *s);
1337
+ if (!s) scr_net_oom();
1338
+ s->kind = SCR_NET_K_SERVER;
1339
+ s->rc = 1;
1340
+ s->fd = -1;
1341
+ s->http_timeouts[0] = 0; /* timeout */
1342
+ s->http_timeouts[1] = 5000; /* keepAliveTimeout */
1343
+ s->http_timeouts[2] = 60000; /* headersTimeout */
1344
+ s->http_timeouts[3] = 300000; /* requestTimeout */
1345
+ s->http_timeouts[4] = 1000; /* keepAliveTimeoutBuffer */
1346
+ #ifdef SCR_RC_AUDIT
1347
+ scr_net_live++;
1348
+ #endif
1349
+ return s;
1350
+ }
1351
+
1352
+ ScrNetServer *scr_net_create_server(ScrClosure *handler /*moves, nullable*/, ScrNetConnFn fn) {
1353
+ ScrNetServer *s = scr_net_server_new();
1354
+ if (handler) scr_net_ls_add(&s->conn_ls, handler, (void *)fn, false);
1355
+ return s;
1356
+ }
1357
+
1358
+ /* listen(port): bind + listen NOW (Node fails synchronously into an async
1359
+ * 'error'); success defers the listen callback ('listening') to the next
1360
+ * dispatch pass, Node's next-tick emit. Binds like Node's host-less
1361
+ * listen: IPv6 any with dual-stack when the kernel allows, IPv4 fallback. */
1362
+ static void scr_net_listen_any(ScrNetServer *s, double port, bool reuse_port,
1363
+ ScrClosure *cb /*moves, nullable*/) {
1364
+ if (cb) scr_net_ls_add(&s->listening_cbs, cb, NULL, true);
1365
+ if (s->listening || s->close_emitted) return;
1366
+ if (!scr_net_poller_init()) {
1367
+ fputs("scriptc: event poller init failed\n", stderr);
1368
+ abort();
1369
+ }
1370
+ int p = (int)port;
1371
+ int fd = socket(AF_INET6, SOCK_STREAM, 0);
1372
+ bool v6 = fd >= 0;
1373
+ if (v6) {
1374
+ int off = 0;
1375
+ setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof off);
1376
+ } else {
1377
+ fd = socket(AF_INET, SOCK_STREAM, 0);
1378
+ }
1379
+ if (fd < 0) {
1380
+ fputs("scriptc: socket() failed\n", stderr);
1381
+ abort();
1382
+ }
1383
+ int rc;
1384
+ if (v6) {
1385
+ struct sockaddr_in6 addr;
1386
+ memset(&addr, 0, sizeof addr);
1387
+ addr.sin6_family = AF_INET6;
1388
+ addr.sin6_addr = in6addr_any;
1389
+ addr.sin6_port = htons((uint16_t)p);
1390
+ rc = scr_net_bind_listen(fd, (struct sockaddr *)&addr, sizeof addr, reuse_port);
1391
+ } else {
1392
+ struct sockaddr_in addr;
1393
+ memset(&addr, 0, sizeof addr);
1394
+ addr.sin_family = AF_INET;
1395
+ addr.sin_addr.s_addr = INADDR_ANY;
1396
+ addr.sin_port = htons((uint16_t)p);
1397
+ rc = scr_net_bind_listen(fd, (struct sockaddr *)&addr, sizeof addr, reuse_port);
1398
+ }
1399
+ if (rc != 0) {
1400
+ int err = errno;
1401
+ close(fd);
1402
+ char msg[128];
1403
+ /* Node: "listen EADDRINUSE: address already in use :::4000" */
1404
+ snprintf(msg, sizeof msg, "listen %s: %s %s:%d", scr_net_errname(err),
1405
+ scr_net_listen_reason(err, false),
1406
+ v6 ? "::" : "0.0.0.0", p);
1407
+ if (!s->pending_err) s->pending_err = scr_str_new(msg, strlen(msg));
1408
+ scr_net_server_register(s); /* the sweep delivers the failure */
1409
+ return;
1410
+ }
1411
+ /* the real port (ephemeral listen(0) discovers it here) */
1412
+ struct sockaddr_storage bound;
1413
+ socklen_t blen = sizeof bound;
1414
+ if (getsockname(fd, (struct sockaddr *)&bound, &blen) == 0) {
1415
+ s->port = bound.ss_family == AF_INET6
1416
+ ? ntohs(((struct sockaddr_in6 *)&bound)->sin6_port)
1417
+ : ntohs(((struct sockaddr_in *)&bound)->sin_port);
1418
+ }
1419
+ s->fd = fd;
1420
+ s->listening = true;
1421
+ s->emit_listening = true;
1422
+ s->bound_v6 = v6;
1423
+ scr_net_watch_read(fd, s, true);
1424
+ scr_net_server_register(s);
1425
+ }
1426
+
1427
+ void scr_net_listen(ScrNetServer *s, double port, ScrClosure *cb /*moves, nullable*/) {
1428
+ scr_net_listen_any(s, port, false, cb);
1429
+ }
1430
+
1431
+ /* listen({ port, host, ipv6Only, reusePort }) — the explicit-interface bind
1432
+ * (portless's listenOnProxyInterface): host is an IP literal ("" = the
1433
+ * host-less dual-stack default above; "localhost" pins to 127.0.0.1, the
1434
+ * connect-side divergence); ipv6Only sets IPV6_V6ONLY before the bind
1435
+ * (meaningful on v6 addresses — "::" with ipv6Only leaves v4 to its own
1436
+ * listener, exactly the portless pair). Failures are the async 'error'
1437
+ * with Node's listen message naming the requested host; a non-IP host is
1438
+ * the async getaddrinfo ENOTFOUND (no resolver in this slice). */
1439
+ static void scr_net_listen_opts_impl(ScrNetServer *s, double port, ScrStr *host /*borrowed*/,
1440
+ bool ipv6_only, bool reuse_port,
1441
+ ScrClosure *cb /*moves, nullable*/) {
1442
+ if (host == NULL || host->len == 0) {
1443
+ scr_net_listen_any(s, port, reuse_port, cb);
1444
+ return;
1445
+ }
1446
+ if (cb) scr_net_ls_add(&s->listening_cbs, cb, NULL, true);
1447
+ if (s->listening || s->close_emitted) return;
1448
+ if (!scr_net_poller_init()) {
1449
+ fputs("scriptc: event poller init failed\n", stderr);
1450
+ abort();
1451
+ }
1452
+ int p = (int)port;
1453
+ char h[64];
1454
+ snprintf(h, sizeof h, "%.*s", (int)(host->len < 63 ? host->len : 63), host->data);
1455
+ if (strcmp(h, "localhost") == 0) snprintf(h, sizeof h, "127.0.0.1");
1456
+ struct sockaddr_in a4;
1457
+ struct sockaddr_in6 a6;
1458
+ struct sockaddr *sa = NULL;
1459
+ socklen_t salen = 0;
1460
+ bool v6 = false;
1461
+ memset(&a4, 0, sizeof a4);
1462
+ memset(&a6, 0, sizeof a6);
1463
+ if (inet_pton(AF_INET, h, &a4.sin_addr) == 1) {
1464
+ a4.sin_family = AF_INET;
1465
+ a4.sin_port = htons((uint16_t)p);
1466
+ sa = (struct sockaddr *)&a4;
1467
+ salen = sizeof a4;
1468
+ } else if (inet_pton(AF_INET6, h, &a6.sin6_addr) == 1) {
1469
+ a6.sin6_family = AF_INET6;
1470
+ a6.sin6_port = htons((uint16_t)p);
1471
+ sa = (struct sockaddr *)&a6;
1472
+ salen = sizeof a6;
1473
+ v6 = true;
1474
+ }
1475
+ if (!sa) {
1476
+ char msg[160];
1477
+ snprintf(msg, sizeof msg, "getaddrinfo ENOTFOUND %s", h);
1478
+ if (!s->pending_err) s->pending_err = scr_str_new(msg, strlen(msg));
1479
+ scr_net_server_register(s);
1480
+ return;
1481
+ }
1482
+ int fd = socket(sa->sa_family, SOCK_STREAM, 0);
1483
+ if (fd < 0) {
1484
+ fputs("scriptc: socket() failed\n", stderr);
1485
+ abort();
1486
+ }
1487
+ if (v6) {
1488
+ int only = ipv6_only ? 1 : 0;
1489
+ setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &only, sizeof only);
1490
+ }
1491
+ int rc = scr_net_bind_listen(fd, sa, salen, reuse_port);
1492
+ if (rc != 0) {
1493
+ int err = errno;
1494
+ close(fd);
1495
+ char msg[160];
1496
+ snprintf(msg, sizeof msg, "listen %s: %s %s:%d", scr_net_errname(err),
1497
+ scr_net_listen_reason(err, true),
1498
+ h, p);
1499
+ if (!s->pending_err) s->pending_err = scr_str_new(msg, strlen(msg));
1500
+ scr_net_server_register(s);
1501
+ return;
1502
+ }
1503
+ struct sockaddr_storage bound;
1504
+ socklen_t blen = sizeof bound;
1505
+ if (getsockname(fd, (struct sockaddr *)&bound, &blen) == 0) {
1506
+ s->port = bound.ss_family == AF_INET6
1507
+ ? ntohs(((struct sockaddr_in6 *)&bound)->sin6_port)
1508
+ : ntohs(((struct sockaddr_in *)&bound)->sin_port);
1509
+ }
1510
+ s->fd = fd;
1511
+ s->listening = true;
1512
+ s->emit_listening = true;
1513
+ s->bound_v6 = v6;
1514
+ scr_str_release(s->bound_host);
1515
+ s->bound_host = scr_str_new(h, strlen(h));
1516
+ scr_net_watch_read(fd, s, true);
1517
+ scr_net_server_register(s);
1518
+ }
1519
+
1520
+ void scr_net_listen_opts(ScrNetServer *s, double port, ScrStr *host /*borrowed*/,
1521
+ bool ipv6_only, ScrClosure *cb /*moves, nullable*/) {
1522
+ scr_net_listen_opts_impl(s, port, host, ipv6_only, false, cb);
1523
+ }
1524
+
1525
+ void scr_net_listen_opts_reuse_port(ScrNetServer *s, double port, ScrStr *host /*borrowed*/,
1526
+ bool ipv6_only, bool reuse_port,
1527
+ ScrClosure *cb /*moves, nullable*/) {
1528
+ scr_net_listen_opts_impl(s, port, host, ipv6_only, reuse_port, cb);
1529
+ }
1530
+
1531
+ double scr_net_server_port(ScrNetServer *s) { return (double)s->port; }
1532
+ bool scr_net_server_listening(ScrNetServer *s) { return s->listening; }
1533
+
1534
+ double scr_net_server_timeout_get(ScrNetServer *s, double field) {
1535
+ static const char *const names[] = {
1536
+ "timeout", "keepAliveTimeout", "headersTimeout", "requestTimeout",
1537
+ "keepAliveTimeoutBuffer",
1538
+ };
1539
+ int i = (int)field;
1540
+ if (i < 0 || i >= 5) abort(); /* compiler/runtime ABI violation */
1541
+ if (s->http_timeout_dyn[i] != NULL) {
1542
+ scr_dyn_arg_type_fail(names[i], "of type number", s->http_timeout_dyn[i]);
1543
+ return 0; /* pending exception; typed reads validate an any-written value */
1544
+ }
1545
+ return s->http_timeouts[i];
1546
+ }
1547
+
1548
+ void scr_net_server_timeout_set(ScrNetServer *s, double field, double value) {
1549
+ int i = (int)field;
1550
+ if (i < 0 || i >= 5) abort(); /* compiler/runtime ABI violation */
1551
+ scr_dyn_release(s->http_timeout_dyn[i]);
1552
+ s->http_timeout_dyn[i] = NULL;
1553
+ s->http_timeouts[i] = value;
1554
+ }
1555
+
1556
+ void scr_net_server_set_timeout_plain(ScrNetServer *s, double ms) {
1557
+ scr_net_server_timeout_set(s, 0, ms);
1558
+ }
1559
+
1560
+ void scr_net_server_set_timeout_cb(ScrNetServer *s, double ms, ScrClosure *cb /*moves*/,
1561
+ ScrNetConnFn fn) {
1562
+ scr_net_server_timeout_set(s, 0, ms);
1563
+ scr_net_server_on_timeout(s, cb, fn, false);
1564
+ }
1565
+
1566
+ void scr_net_server_enable_http_timeout_surface(ScrNetServer *s) {
1567
+ s->http_timeout_surface = true;
1568
+ }
1569
+
1570
+ /* Constructor-option validation is intentionally separate from the plain
1571
+ * writable-property setter above. Node validates these option values as
1572
+ * non-negative safe integers, while later property assignments store the
1573
+ * number directly. */
1574
+ bool scr_net_server_timeout_option_check(double field, double value) {
1575
+ static const char *const names[] = {
1576
+ "timeout", "keepAliveTimeout", "headersTimeout", "requestTimeout",
1577
+ "keepAliveTimeoutBuffer",
1578
+ };
1579
+ int i = (int)field;
1580
+ if (i < 0 || i >= 5) abort(); /* compiler/runtime ABI violation */
1581
+ char recv[48], msg[224];
1582
+ if (!(isfinite(value) && trunc(value) == value)) {
1583
+ scr_num_received(value, recv);
1584
+ int len = snprintf(msg, sizeof msg,
1585
+ "The value of \"%s\" is out of range. It must be an integer. Received %s",
1586
+ names[i], recv);
1587
+ scr_throw_error_msg_code(SCR_ERR_RANGE, msg, (size_t)len, "ERR_OUT_OF_RANGE");
1588
+ return false;
1589
+ }
1590
+ if (value < 0 || value > 9007199254740991.0) {
1591
+ scr_num_received(value, recv);
1592
+ int len = snprintf(msg, sizeof msg,
1593
+ "The value of \"%s\" is out of range. It must be >= 0 && <= 9007199254740991. Received %s",
1594
+ names[i], recv);
1595
+ scr_throw_error_msg_code(SCR_ERR_RANGE, msg, (size_t)len, "ERR_OUT_OF_RANGE");
1596
+ return false;
1597
+ }
1598
+ return true;
1599
+ }
1600
+
1601
+ void scr_net_server_timeout_option_set(ScrNetServer *s, double field, const ScrDyn *value) {
1602
+ int i = (int)field;
1603
+ if (i < 0 || i >= 5) abort(); /* compiler/runtime ABI violation */
1604
+ if (value->kind == SCR_DYN_UNDEF) return; /* optional field is absent */
1605
+ if (value->kind != SCR_DYN_NUM) {
1606
+ static const char *const names[] = {
1607
+ "timeout", "keepAliveTimeout", "headersTimeout", "requestTimeout",
1608
+ "keepAliveTimeoutBuffer",
1609
+ };
1610
+ scr_dyn_arg_type_fail(names[i], "of type number", value);
1611
+ return;
1612
+ }
1613
+ if (!scr_net_server_timeout_option_check(field, value->v.num)) return;
1614
+ scr_net_server_timeout_set(s, field, value->v.num);
1615
+ }
1616
+
1617
+ /* address()'s other two fields — the bound host ('::'/'0.0.0.0' for the
1618
+ * host-less any, the normalized explicit host otherwise) and the family
1619
+ * string. Answer the any-form defaults before listen (Node answers null
1620
+ * there — the serverPort stance, port 0). */
1621
+ ScrStr *scr_net_server_addr_ip(ScrNetServer *s) {
1622
+ if (s->bound_host) return scr_str_retain(s->bound_host);
1623
+ return s->bound_v6 ? scr_str_new("::", 2) : scr_str_new("0.0.0.0", 7);
1624
+ }
1625
+
1626
+ ScrStr *scr_net_server_addr_family(ScrNetServer *s) {
1627
+ return s->bound_v6 ? scr_str_new("IPv6", 4) : scr_str_new("IPv4", 4);
1628
+ }
1629
+
1630
+ /* The REAL close — what the bound `origClose` value reaches (never
1631
+ * consults the override, so the portless proxy-through idiom cannot
1632
+ * recurse). */
1633
+ void scr_net_server_close_direct(ScrNetServer *s, ScrClosure *cb /*moves, nullable*/) {
1634
+ if (s->close_emitted) {
1635
+ scr_closure_release(cb);
1636
+ return;
1637
+ }
1638
+ if (cb) scr_net_ls_add(&s->close_ls, cb, NULL, true);
1639
+ if (s->listening) {
1640
+ scr_net_close_fd_raw(s->fd); /* stops accepting NOW (registrations dropped first) */
1641
+ s->fd = -1;
1642
+ s->listening = false;
1643
+ }
1644
+ /* A close BEFORE the deferred 'listening' delivered cancels it — Node's
1645
+ * emitListeningNT checks the handle close() nulled, so the listen
1646
+ * callback never runs (test-net-listen-close-server's mustNotCall). */
1647
+ if (s->emit_listening) {
1648
+ s->emit_listening = false;
1649
+ scr_net_ls_drop(&s->listening_cbs);
1650
+ }
1651
+ if (!s->closing) {
1652
+ static size_t scr_net_close_seq = 0;
1653
+ s->close_seq = ++scr_net_close_seq;
1654
+ }
1655
+ s->closing = true; /* the sweep fires 'close' once nconns drains */
1656
+ }
1657
+
1658
+ void scr_net_server_close(ScrNetServer *s, ScrClosure *cb /*moves, nullable*/) {
1659
+ if (s->close_override != NULL && !s->close_emitted) {
1660
+ /* The override runs INSTEAD of the close; a close callback still
1661
+ * fires when the override's origClose completes the close — Node's
1662
+ * behavior with the callback passed through. */
1663
+ if (cb) scr_net_ls_add(&s->close_ls, cb, NULL, true);
1664
+ ScrClosure *ov = scr_closure_retain(s->close_override);
1665
+ ((void (*)(ScrClosure *))ov->fn)(ov);
1666
+ scr_closure_release(ov);
1667
+ return;
1668
+ }
1669
+ scr_net_server_close_direct(s, cb);
1670
+ }
1671
+
1672
+ static void scr_net_server_close_http_connections(ScrNetServer *s, bool idle_only) {
1673
+ ScrNetSocket *sock = scr_net_socks;
1674
+ while (sock) {
1675
+ ScrNetSocket *next = sock->next;
1676
+ if (sock->server == s && sock->native_idle != NULL && sock->fd >= 0 &&
1677
+ (!idle_only || sock->native_idle(sock->native_ctx))) {
1678
+ scr_net_sock_retain(sock);
1679
+ scr_net_sock_destroy(sock);
1680
+ scr_net_sock_release(sock);
1681
+ }
1682
+ sock = next;
1683
+ }
1684
+ }
1685
+
1686
+ void scr_net_server_close_all_connections(ScrNetServer *s) {
1687
+ scr_net_server_close_http_connections(s, false);
1688
+ }
1689
+
1690
+ void scr_net_server_close_idle_connections(ScrNetServer *s) {
1691
+ scr_net_server_close_http_connections(s, true);
1692
+ }
1693
+
1694
+ /* wrapper.close = fn: the override MOVES in (a compiler-emitted zero-arg
1695
+ * wrapper — see the struct comment); reassignment releases the old one,
1696
+ * matching JS's last-write-wins. */
1697
+ void scr_net_server_set_close_override(ScrNetServer *s, ScrClosure *ov /*moves*/) {
1698
+ scr_closure_release(s->close_override);
1699
+ s->close_override = ov;
1700
+ }
1701
+
1702
+ void scr_net_server_on_error(ScrNetServer *s, ScrClosure *cb /*moves*/, ScrChildErrFn fn,
1703
+ bool once) {
1704
+ if (s->close_emitted) {
1705
+ scr_closure_release(cb);
1706
+ return;
1707
+ }
1708
+ scr_net_ls_add(&s->err_ls, cb, (void *)fn, once);
1709
+ }
1710
+
1711
+ void scr_net_server_on_close(ScrNetServer *s, ScrClosure *cb /*moves*/, bool once) {
1712
+ if (s->close_emitted) {
1713
+ scr_closure_release(cb);
1714
+ return;
1715
+ }
1716
+ scr_net_ls_add(&s->close_ls, cb, NULL, once);
1717
+ }
1718
+
1719
+ /* server.on('listening', cb): joins the deferred 'listening' list the
1720
+ * listen(port, cb) callback rides (the sweep fires it once after a
1721
+ * successful bind — Node's next-tick emit). A registration AFTER the
1722
+ * emit sits inert forever, exactly Node's once-per-listen event; a
1723
+ * settled (closed) server releases the closure unregistered. */
1724
+ void scr_net_server_on_listening(ScrNetServer *s, ScrClosure *cb /*moves*/, bool once) {
1725
+ if (s->close_emitted) {
1726
+ scr_closure_release(cb);
1727
+ return;
1728
+ }
1729
+ scr_net_ls_add(&s->listening_cbs, cb, NULL, once);
1730
+ }
1731
+
1732
+ /* 'secureConnection': a TLS server's 'connection' list already fires at
1733
+ * handshake completion (defer_conn) — Node's secureConnection timing; on
1734
+ * a plain server the event never fires in Node, so the registration is
1735
+ * released unread. */
1736
+ void scr_net_server_on_secure_connection(ScrNetServer *s, ScrClosure *cb /*moves*/,
1737
+ ScrNetConnFn fn, bool once) {
1738
+ if (!s->defer_conn) {
1739
+ scr_closure_release(cb);
1740
+ return;
1741
+ }
1742
+ scr_net_server_on_connection(s, cb, fn, once);
1743
+ }
1744
+
1745
+ void scr_net_server_on_connection(ScrNetServer *s, ScrClosure *cb /*moves*/, ScrNetConnFn fn,
1746
+ bool once) {
1747
+ if (s->close_emitted) {
1748
+ scr_closure_release(cb);
1749
+ return;
1750
+ }
1751
+ scr_net_ls_add(&s->conn_ls, cb, (void *)fn, once);
1752
+ }
1753
+
1754
+ void scr_net_server_on_timeout(ScrNetServer *s, ScrClosure *cb /*moves*/, ScrNetConnFn fn,
1755
+ bool once) {
1756
+ if (s->close_emitted) {
1757
+ scr_closure_release(cb);
1758
+ return;
1759
+ }
1760
+ scr_net_ls_add(&s->timeout_ls, cb, (void *)fn, once);
1761
+ }
1762
+
1763
+ /* Accept until EAGAIN; each connection fires the 'connection' listeners
1764
+ * directly (the accepted socket passes +1 per listener via the adapter). */
1765
+ static void scr_net_server_accept(ScrNetServer *srv) {
1766
+ for (;;) {
1767
+ if (!srv->listening || srv->fd < 0) return;
1768
+ int fd = accept(srv->fd, NULL, NULL);
1769
+ if (fd < 0) {
1770
+ if (errno == EINTR) continue;
1771
+ return; /* EAGAIN or a transient failure: the next wake retries */
1772
+ }
1773
+ scr_net_nonblock(fd);
1774
+ int one = 1;
1775
+ setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof one);
1776
+ ScrNetSocket *sock = scr_net_sock_new();
1777
+ sock->fd = fd;
1778
+ sock->server = scr_net_server_retain(srv);
1779
+ srv->nconns++;
1780
+ scr_net_sock_register(sock);
1781
+ if (srv->http_timeout_surface && srv->http_timeouts[0] > 0)
1782
+ scr_net_sock_set_timeout(sock, srv->http_timeouts[0]);
1783
+ if (srv->native_conn) {
1784
+ /* the protocol layer (scr_http.c / scr_tls.c) claims the connection */
1785
+ srv->native_conn(srv->native_ctx, sock);
1786
+ if (scr_exc_pending()) return;
1787
+ }
1788
+ if (srv->defer_conn) {
1789
+ /* 'connection' waits for the handshake (secureConnection timing) */
1790
+ sock->conn_pending = scr_net_server_retain(srv);
1791
+ }
1792
+ if (!srv->defer_conn) {
1793
+ ScrNetL *snap;
1794
+ size_t n = scr_net_ls_snapshot(&srv->conn_ls, &snap);
1795
+ scr_dyn_this_push(srv, SCR_DYNH_NET_SERVER);
1796
+ for (size_t i = 0; i < n; i++) {
1797
+ if (!scr_exc_pending()) ((ScrNetConnFn)snap[i].fn)(snap[i].cb, scr_net_sock_retain(sock));
1798
+ scr_closure_release(snap[i].cb);
1799
+ }
1800
+ scr_dyn_this_pop();
1801
+ free(snap);
1802
+ }
1803
+ scr_net_sock_release(sock); /* registry + server-count refs remain */
1804
+ if (scr_exc_pending()) return;
1805
+ }
1806
+ }
1807
+
1808
+ /* ── the client ──────────────────────────────────────────────────────── */
1809
+
1810
+ /* connect(port, host): numeric IPv4/IPv6 hosts and "localhost" (pinned to
1811
+ * 127.0.0.1 — the documented divergence from Node's family autoselect).
1812
+ * The connect callback registers as once('connect'). Never throws: every
1813
+ * failure is the async 'error' event, like Node. */
1814
+ /* Blocking first-answer hostname resolution for the CLIENT bridges (the
1815
+ * native fetch, the island's http/https client) — the dns.lookup
1816
+ * precedent (scr_dgram.c): getaddrinfo runs AT CALL TIME, first answer
1817
+ * wins. Returns +1: the resolved IP string, or a RETAIN of `host` when it
1818
+ * is already an IP literal or localhost (scr_net_connect's own arms) or
1819
+ * unresolvable — the dial's deferred "getaddrinfo ENOTFOUND host" error
1820
+ * is then Node's exact cause shape. node:net's own connect surface stays
1821
+ * resolver-less on purpose (Node's async lookup semantics are not this). */
1822
+ ScrStr *scr_net_blocking_lookup(ScrStr *host /*borrowed*/) {
1823
+ if (host->len == 9 && memcmp(host->data, "localhost", 9) == 0) return scr_str_retain(host);
1824
+ struct in_addr a4;
1825
+ struct in6_addr a6;
1826
+ if (inet_pton(AF_INET, host->data, &a4) == 1 || inet_pton(AF_INET6, host->data, &a6) == 1) {
1827
+ return scr_str_retain(host);
1828
+ }
1829
+ if (!scr_net_poller_init()) return scr_str_retain(host); /* WSAStartup on win32 */
1830
+ struct addrinfo hints;
1831
+ memset(&hints, 0, sizeof hints);
1832
+ hints.ai_socktype = SOCK_STREAM;
1833
+ struct addrinfo *res = NULL;
1834
+ if (getaddrinfo(host->data, NULL, &hints, &res) != 0 || res == NULL) {
1835
+ if (res) freeaddrinfo(res);
1836
+ return scr_str_retain(host);
1837
+ }
1838
+ char ip[INET6_ADDRSTRLEN] = "";
1839
+ const char *out = NULL;
1840
+ if (res->ai_family == AF_INET) {
1841
+ out = inet_ntop(AF_INET, &((struct sockaddr_in *)res->ai_addr)->sin_addr, ip, sizeof ip);
1842
+ } else if (res->ai_family == AF_INET6) {
1843
+ out = inet_ntop(AF_INET6, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, ip, sizeof ip);
1844
+ }
1845
+ freeaddrinfo(res);
1846
+ if (!out) return scr_str_retain(host);
1847
+ return scr_str_new(ip, strlen(ip));
1848
+ }
1849
+
1850
+ /* The dial itself (peer_ip/peer_port already set): the sockaddr arms,
1851
+ * socket(), and the nonblocking connect(). Shared by the immediate dial
1852
+ * (scr_net_connect) and the DEFERRED one (the http agent's maxSockets
1853
+ * queue — the socket exists, buffers writes, and dials when a slot
1854
+ * frees). */
1855
+ static void scr_net_sock_dial_peer(ScrNetSocket *s) {
1856
+ const char *h = s->peer_ip;
1857
+ struct sockaddr_in a4;
1858
+ struct sockaddr_in6 a6;
1859
+ struct sockaddr *sa = NULL;
1860
+ socklen_t salen = 0;
1861
+ memset(&a4, 0, sizeof a4);
1862
+ memset(&a6, 0, sizeof a6);
1863
+ if (inet_pton(AF_INET, h, &a4.sin_addr) == 1) {
1864
+ a4.sin_family = AF_INET;
1865
+ a4.sin_port = htons((uint16_t)s->peer_port);
1866
+ sa = (struct sockaddr *)&a4;
1867
+ salen = sizeof a4;
1868
+ } else if (inet_pton(AF_INET6, h, &a6.sin6_addr) == 1) {
1869
+ a6.sin6_family = AF_INET6;
1870
+ a6.sin6_port = htons((uint16_t)s->peer_port);
1871
+ sa = (struct sockaddr *)&a6;
1872
+ salen = sizeof a6;
1873
+ }
1874
+ if (!sa) {
1875
+ /* Non-numeric host: no resolver in this slice. Node's shape for a
1876
+ * failed lookup is ENOTFOUND; deliver it deferred. */
1877
+ char msg[160];
1878
+ snprintf(msg, sizeof msg, "getaddrinfo ENOTFOUND %s", h);
1879
+ s->pending_err = scr_str_new(msg, strlen(msg));
1880
+ s->had_error = true;
1881
+ s->emit_close = true;
1882
+ s->connecting = false;
1883
+ return;
1884
+ }
1885
+ int fd = socket(sa->sa_family, SOCK_STREAM, 0);
1886
+ if (fd < 0) {
1887
+ fputs("scriptc: socket() failed\n", stderr);
1888
+ abort();
1889
+ }
1890
+ scr_net_nonblock(fd);
1891
+ int one = 1;
1892
+ setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof one);
1893
+ s->fd = fd;
1894
+ int rc = connect(fd, sa, salen);
1895
+ if (rc == 0) {
1896
+ /* Immediate success (loopback can): still async — the write filter
1897
+ * fires at once and connect_done delivers 'connect' from dispatch. */
1898
+ s->connecting = true;
1899
+ scr_net_sock_update_write(s);
1900
+ } else if (errno == EINPROGRESS) {
1901
+ s->connecting = true;
1902
+ scr_net_sock_update_write(s);
1903
+ } else {
1904
+ char msg[128];
1905
+ snprintf(msg, sizeof msg, "connect %s %s:%d", scr_net_errname(errno), s->peer_ip,
1906
+ s->peer_port);
1907
+ s->pending_err = scr_str_new(msg, strlen(msg));
1908
+ s->had_error = true;
1909
+ s->connecting = false;
1910
+ scr_net_sock_close_fd(s);
1911
+ }
1912
+ }
1913
+
1914
+ ScrNetSocket *scr_net_connect(double port, ScrStr *host /*borrowed, nullable*/,
1915
+ ScrClosure *cb /*moves, nullable*/) {
1916
+ ScrNetSocket *s = scr_net_sock_new();
1917
+ if (cb) scr_net_ls_add(&s->conn_ls, cb, NULL, true);
1918
+ s->peer_port = (int)port;
1919
+ const char *h = host && host->len > 0 ? host->data : "localhost";
1920
+ if (strcmp(h, "localhost") == 0) h = "127.0.0.1";
1921
+ snprintf(s->peer_ip, sizeof s->peer_ip, "%s", h);
1922
+ if (!scr_net_poller_init()) {
1923
+ fputs("scriptc: event poller init failed\n", stderr);
1924
+ abort();
1925
+ }
1926
+ scr_net_sock_dial_peer(s);
1927
+ scr_net_sock_register(s);
1928
+ return s;
1929
+ }
1930
+
1931
+ /* ── the connect option-bag validation ladders (checked-dynamic lane) ──
1932
+ * Node-order validation over dyn option values with Node's exact typed
1933
+ * errors; the honest tail (connect for the validated forms, the
1934
+ * compiler-rendered fence for bags with unmodeled keys) runs only after
1935
+ * every validation passes. */
1936
+
1937
+ static bool scr_net_attempt_timeout_chk(const ScrDyn *t, const char *name) {
1938
+ if (t->kind != SCR_DYN_NUM) {
1939
+ scr_dyn_prop_type_fail(name, "of type number", t);
1940
+ return false;
1941
+ }
1942
+ char recv[48], msg[192];
1943
+ if (!(isfinite(t->v.num) && trunc(t->v.num) == t->v.num)) {
1944
+ scr_num_received(t->v.num, recv);
1945
+ int len = snprintf(msg, sizeof msg,
1946
+ "The value of \"%s\" is out of range. It must be an integer. Received %s",
1947
+ name, recv);
1948
+ scr_throw_error_msg_code(SCR_ERR_RANGE, msg, (size_t)len, "ERR_OUT_OF_RANGE");
1949
+ return false;
1950
+ }
1951
+ if (t->v.num < 1 || t->v.num > 2147483647.0) {
1952
+ scr_num_received(t->v.num, recv);
1953
+ int len = snprintf(msg, sizeof msg,
1954
+ "The value of \"%s\" is out of range. It must be >= 1 && <= 2147483647. Received %s",
1955
+ name, recv);
1956
+ scr_throw_error_msg_code(SCR_ERR_RANGE, msg, (size_t)len, "ERR_OUT_OF_RANGE");
1957
+ return false;
1958
+ }
1959
+ return true;
1960
+ }
1961
+
1962
+ /* connect({ ..., autoSelectFamilyAttemptTimeout }): the budget validates
1963
+ * (validateInt32 from 1, Node's exact texts) and is then inert — this
1964
+ * slice's single dial has nothing to time, the same simplification the
1965
+ * autoSelectFamily flag already takes. NULL with the throw pending. */
1966
+ ScrNetSocket *scr_net_connect_attempt(double port, ScrStr *host, const ScrDyn *t) {
1967
+ if (!scr_net_attempt_timeout_chk(t, "options.autoSelectFamilyAttemptTimeout")) return NULL;
1968
+ return scr_net_connect(port, host, NULL);
1969
+ }
1970
+
1971
+ static bool scr_net_dyn_truthy(const ScrDyn *v) {
1972
+ switch (v->kind) {
1973
+ case SCR_DYN_UNDEF:
1974
+ case SCR_DYN_NULL: return false;
1975
+ case SCR_DYN_BOOL: return v->v.b;
1976
+ case SCR_DYN_NUM: return v->v.num == v->v.num && v->v.num != 0;
1977
+ case SCR_DYN_STR: return v->v.str->len > 0;
1978
+ default: return true;
1979
+ }
1980
+ }
1981
+
1982
+ /* net.connect/createConnection over a RUNTIME option bag (computed keys
1983
+ * — the invalid-input probes): Node's Socket-constructor order — the
1984
+ * objectMode trio throws ERR_INVALID_ARG_VALUE first, then the port
1985
+ * (validatePort), the host's string contract, autoSelectFamily's boolean
1986
+ * contract, and the attempt budget. A bag that survives everything meets
1987
+ * the compiler-rendered fence: an unmodeled key must refuse loudly, never
1988
+ * silently drop. Always leaves an exception pending. */
1989
+ void scr_net_connect_opts_chk(const ScrDyn *opts, const ScrStr *fence) {
1990
+ if (opts == NULL || opts->kind != SCR_DYN_OBJ) {
1991
+ scr_dyn_arg_type_fail("options", "of type object",
1992
+ opts ? opts : scr_dyn_undefined());
1993
+ return;
1994
+ }
1995
+ static const char *const om[] = { "objectMode", "readableObjectMode", "writableObjectMode" };
1996
+ for (size_t i = 0; i < 3; i++) {
1997
+ const ScrDyn *v = scr_dyn_obj_get(opts, om[i], strlen(om[i]));
1998
+ if (v != NULL && scr_net_dyn_truthy(v)) {
1999
+ char name[48];
2000
+ snprintf(name, sizeof name, "options.%s", om[i]);
2001
+ scr_dyn_arg_value_fail(name, "is not supported", v);
2002
+ return;
2003
+ }
2004
+ }
2005
+ const ScrDyn *port = scr_dyn_obj_get(opts, "port", 4);
2006
+ if (port != NULL && port->kind != SCR_DYN_UNDEF) {
2007
+ bool ok = port->kind == SCR_DYN_NUM && trunc(port->v.num) == port->v.num &&
2008
+ port->v.num >= 0 && port->v.num < 65536;
2009
+ if (!ok && port->kind == SCR_DYN_STR) {
2010
+ ScrStr *ps = scr_str_retain(port->v.str);
2011
+ double n = scr_string_to_number(ps);
2012
+ scr_str_release(ps);
2013
+ ok = n == n && trunc(n) == n && n >= 0 && n < 65536 && port->v.str->len > 0;
2014
+ }
2015
+ if (!ok) {
2016
+ char detail[64], msg[160];
2017
+ const char *d = scr_dyn_specific_type(port, detail, sizeof detail);
2018
+ int len = snprintf(msg, sizeof msg,
2019
+ "options.port should be >= 0 and < 65536. Received %s", d);
2020
+ scr_throw_error_msg_code(SCR_ERR_RANGE, msg, (size_t)len, "ERR_SOCKET_BAD_PORT");
2021
+ return;
2022
+ }
2023
+ }
2024
+ const ScrDyn *host = scr_dyn_obj_get(opts, "host", 4);
2025
+ if (host != NULL && host->kind != SCR_DYN_UNDEF && host->kind != SCR_DYN_STR) {
2026
+ scr_dyn_prop_type_fail("options.host", "of type string", host);
2027
+ return;
2028
+ }
2029
+ const ScrDyn *asf = scr_dyn_obj_get(opts, "autoSelectFamily", 16);
2030
+ if (asf != NULL && asf->kind != SCR_DYN_UNDEF && asf->kind != SCR_DYN_BOOL) {
2031
+ scr_dyn_prop_type_fail("options.autoSelectFamily", "of type boolean", asf);
2032
+ return;
2033
+ }
2034
+ const ScrDyn *att = scr_dyn_obj_get(opts, "autoSelectFamilyAttemptTimeout", 30);
2035
+ if (att != NULL && att->kind != SCR_DYN_UNDEF &&
2036
+ !scr_net_attempt_timeout_chk(att, "options.autoSelectFamilyAttemptTimeout")) {
2037
+ return;
2038
+ }
2039
+ scr_throw_lowering_fence(fence);
2040
+ }
2041
+
2042
+ /* A dial the caller starts LATER (the http agent's maxSockets queue):
2043
+ * the socket exists, registers, and buffers writes as "connecting" —
2044
+ * scr_net_sock_dial_start runs the actual dial when a slot frees. */
2045
+ ScrNetSocket *scr_net_connect_deferred(double port, ScrStr *host /*borrowed, nullable*/) {
2046
+ ScrNetSocket *s = scr_net_sock_new();
2047
+ s->peer_port = (int)port;
2048
+ const char *h = host && host->len > 0 ? host->data : "localhost";
2049
+ if (strcmp(h, "localhost") == 0) h = "127.0.0.1";
2050
+ snprintf(s->peer_ip, sizeof s->peer_ip, "%s", h);
2051
+ if (!scr_net_poller_init()) {
2052
+ fputs("scriptc: event poller init failed\n", stderr);
2053
+ abort();
2054
+ }
2055
+ s->connecting = true; /* logically connecting while the dial waits */
2056
+ s->dial_deferred = true;
2057
+ scr_net_sock_register(s);
2058
+ return s;
2059
+ }
2060
+
2061
+ void scr_net_sock_dial_start(ScrNetSocket *s) {
2062
+ if (!s->dial_deferred || s->close_emitted || s->emit_close || s->fd >= 0) return;
2063
+ s->dial_deferred = false;
2064
+ scr_net_sock_dial_peer(s);
2065
+ }
2066
+
2067
+ /* ── the caller-lookup dial (net.connect with a lookup option) ─────────
2068
+ *
2069
+ * portless's createLoopbackConnection: connect({ host, port,
2070
+ * autoSelectFamily: true, lookup }) — the runtime invokes the caller's
2071
+ * resolver exactly as Node does (lookup(hostname, options, callback))
2072
+ * and dials its answered addresses IN ORDER: each connect failure closes
2073
+ * the fd and tries the next; the last failure's message is the socket's
2074
+ * 'error' (Node's AggregateError under autoSelectFamily is a documented
2075
+ * divergence). The answer callback is a runtime-minted closure over the
2076
+ * boxed socket whose fn is an emitter-synthesized per-shape thunk (the
2077
+ * SNI-answer pattern); late, repeated, or dead-socket answers are
2078
+ * ignored. */
2079
+
2080
+ /* Dials one IP now. Success (established or in progress) answers true;
2081
+ * failure records the message (LAST-wins — the retry chain's contract),
2082
+ * closes any fd, and answers false without emitting. */
2083
+ static bool scr_net_sock_dial_ip(ScrNetSocket *s, const ScrStr *ip) {
2084
+ char h[64];
2085
+ snprintf(h, sizeof h, "%.*s", (int)(ip->len < 63 ? ip->len : 63), ip->data);
2086
+ snprintf(s->peer_ip, sizeof s->peer_ip, "%s", h);
2087
+ struct sockaddr_in a4;
2088
+ struct sockaddr_in6 a6;
2089
+ struct sockaddr *sa = NULL;
2090
+ socklen_t salen = 0;
2091
+ memset(&a4, 0, sizeof a4);
2092
+ memset(&a6, 0, sizeof a6);
2093
+ if (inet_pton(AF_INET, h, &a4.sin_addr) == 1) {
2094
+ a4.sin_family = AF_INET;
2095
+ a4.sin_port = htons((uint16_t)s->peer_port);
2096
+ sa = (struct sockaddr *)&a4;
2097
+ salen = sizeof a4;
2098
+ } else if (inet_pton(AF_INET6, h, &a6.sin6_addr) == 1) {
2099
+ a6.sin6_family = AF_INET6;
2100
+ a6.sin6_port = htons((uint16_t)s->peer_port);
2101
+ sa = (struct sockaddr *)&a6;
2102
+ salen = sizeof a6;
2103
+ }
2104
+ char msg[160];
2105
+ if (!sa) {
2106
+ /* a non-IP answer: the lookup was supposed to resolve — Node's
2107
+ * lookup-failure shape */
2108
+ snprintf(msg, sizeof msg, "getaddrinfo ENOTFOUND %s", h);
2109
+ scr_str_release(s->dial_err);
2110
+ s->dial_err = scr_str_new(msg, strlen(msg));
2111
+ return false;
2112
+ }
2113
+ int fd = socket(sa->sa_family, SOCK_STREAM, 0);
2114
+ if (fd < 0) {
2115
+ fputs("scriptc: socket() failed\n", stderr);
2116
+ abort();
2117
+ }
2118
+ scr_net_nonblock(fd);
2119
+ int one = 1;
2120
+ setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof one);
2121
+ int rc = connect(fd, sa, salen);
2122
+ if (rc == 0 || errno == EINPROGRESS) {
2123
+ s->fd = fd;
2124
+ s->connecting = true;
2125
+ scr_net_sock_update_write(s);
2126
+ return true;
2127
+ }
2128
+ snprintf(msg, sizeof msg, "connect %s %s:%d", scr_net_errname(errno), s->peer_ip, s->peer_port);
2129
+ scr_str_release(s->dial_err);
2130
+ s->dial_err = scr_str_new(msg, strlen(msg));
2131
+ close(fd);
2132
+ return false;
2133
+ }
2134
+
2135
+ /* Dials the next answered addresses until one starts; exhaustion flags
2136
+ * the deferred 'error' + 'close' (the last dial's message stands). */
2137
+ static void scr_net_sock_dial_next(ScrNetSocket *s) {
2138
+ while (s->dial_i < s->dial_n) {
2139
+ const ScrStr *ip = s->dial_ips[s->dial_i++];
2140
+ if (scr_net_sock_dial_ip(s, ip)) return;
2141
+ }
2142
+ /* exhausted: the last failure surfaces now */
2143
+ if (s->dial_err != NULL && s->pending_err == NULL) {
2144
+ s->pending_err = s->dial_err;
2145
+ s->dial_err = NULL;
2146
+ }
2147
+ s->connecting = false;
2148
+ s->had_error = true;
2149
+ s->emit_close = true;
2150
+ }
2151
+
2152
+ ScrNetSocket *scr_net_connect_lookup(double port, ScrStr *host /*borrowed*/,
2153
+ ScrClosure *lookup /*moves*/, void *answer_fn) {
2154
+ ScrNetSocket *s = scr_net_sock_new();
2155
+ s->peer_port = (int)port;
2156
+ snprintf(s->peer_ip, sizeof s->peer_ip, "%.*s",
2157
+ (int)(host->len < 63 ? host->len : 63), host->data);
2158
+ if (!scr_net_poller_init()) {
2159
+ fputs("scriptc: event poller init failed\n", stderr);
2160
+ abort();
2161
+ }
2162
+ s->connecting = true; /* logically connecting while the lookup decides */
2163
+ s->lookup_wait = true;
2164
+ scr_net_sock_register(s);
2165
+ ScrClosure *ans = scr_closure_new(answer_fn, 1);
2166
+ ScrBox *box = scr_box_new_obj(&scr_net_sock_retain_v, &scr_net_sock_release_v, NULL);
2167
+ scr_box_set_ref(box, scr_net_sock_retain(s));
2168
+ ans->caps[0] = box;
2169
+ /* the lookup owns its +1 params per the universal convention; options
2170
+ * crosses as the dyn undefined (Node passes its option bag — the
2171
+ * lowered resolver shape types it `unknown` and portless ignores it) */
2172
+ ((void (*)(ScrClosure *, ScrStr *, ScrDyn *, ScrClosure *))lookup->fn)(
2173
+ lookup, scr_str_retain(host), scr_dyn_undefined(), ans);
2174
+ scr_closure_release(lookup);
2175
+ /* a synchronous throw inside the lookup left the exception pending —
2176
+ * the emitter's may-throw check unwinds past this return */
2177
+ return s;
2178
+ }
2179
+
2180
+ /* The answer closure's runtime half (its fn is the emitted per-shape
2181
+ * thunk; caps[0] boxes the socket). msg/ips are borrowed (nullable). */
2182
+ void scr_net_lookup_answer(ScrClosure *self, bool has_err, ScrStr *msg /*borrowed, nullable*/,
2183
+ ScrArr *ips /*borrowed, nullable*/) {
2184
+ ScrNetSocket *s = (ScrNetSocket *)scr_box_get_ref(self->caps[0]);
2185
+ if (s == NULL) return;
2186
+ if (!s->lookup_wait || s->close_emitted || s->fd >= 0) {
2187
+ scr_net_sock_release(s);
2188
+ return; /* late/repeated/dead-socket answers: the first decided */
2189
+ }
2190
+ s->lookup_wait = false;
2191
+ size_t n = ips != NULL ? (size_t)scr_arr_len(ips) : 0;
2192
+ if (has_err || n == 0) {
2193
+ /* lookup failure: the deferred 'error' (Node defers these too); an
2194
+ * EMPTY answer wears getaddrinfo's shape */
2195
+ if (msg != NULL && msg->len > 0) {
2196
+ scr_str_release(s->pending_err);
2197
+ s->pending_err = scr_str_retain(msg);
2198
+ } else if (s->pending_err == NULL) {
2199
+ char fb[160];
2200
+ snprintf(fb, sizeof fb, "getaddrinfo ENOTFOUND %s", s->peer_ip);
2201
+ s->pending_err = scr_str_new(fb, strlen(fb));
2202
+ }
2203
+ s->connecting = false;
2204
+ s->had_error = true;
2205
+ s->emit_close = true;
2206
+ scr_net_sock_release(s);
2207
+ return;
2208
+ }
2209
+ s->dial_ips = malloc(n * sizeof *s->dial_ips);
2210
+ if (!s->dial_ips) scr_net_oom();
2211
+ for (size_t i = 0; i < n; i++) s->dial_ips[i] = (ScrStr *)scr_arr_get_ref(ips, (double)i);
2212
+ s->dial_n = n;
2213
+ s->dial_i = 0;
2214
+ scr_net_sock_dial_next(s);
2215
+ scr_net_sock_release(s);
2216
+ }
2217
+
2218
+ /* ── the socket surface ──────────────────────────────────────────────── */
2219
+
2220
+ void scr_net_sock_write_str(ScrNetSocket *s, ScrStr *data /*borrowed*/) {
2221
+ scr_net_sock_write_raw(s, data->data, data->len);
2222
+ }
2223
+
2224
+ void scr_net_sock_write_bytes(ScrNetSocket *s, ScrBytes *data /*borrowed*/) {
2225
+ scr_net_sock_write_raw(s, (const char *)data->data, (data->len * scr_bytes_elem_size(data->elem)));
2226
+ }
2227
+
2228
+ void scr_net_sock_end(ScrNetSocket *s) {
2229
+ if (s->fd < 0 || s->wr_ending) return;
2230
+ s->wr_ending = true;
2231
+ scr_net_sock_maybe_finish_write(s);
2232
+ if (s->rd_eof && s->wr_done) scr_net_sock_close_fd(s);
2233
+ }
2234
+
2235
+ void scr_net_sock_end_str(ScrNetSocket *s, ScrStr *data /*borrowed*/) {
2236
+ scr_net_sock_write_str(s, data);
2237
+ scr_net_sock_end(s);
2238
+ }
2239
+
2240
+ void scr_net_sock_end_bytes(ScrNetSocket *s, ScrBytes *data /*borrowed*/) {
2241
+ scr_net_sock_write_bytes(s, data);
2242
+ scr_net_sock_end(s);
2243
+ }
2244
+
2245
+ /* socket.pause(): reads stay off — the kernel buffer (and TCP flow
2246
+ * control) holds arrived bytes. Delivery restarts on
2247
+ * resume(), always from the poller/sweep, never this stack. Answers the
2248
+ * socket (+1) — Node's chaining. */
2249
+ ScrNetSocket *scr_net_sock_pause(ScrNetSocket *s) {
2250
+ s->user_paused = true;
2251
+ scr_net_sock_update_read(s);
2252
+ return scr_net_sock_retain(s);
2253
+ }
2254
+
2255
+ /* socket.resume(): flowing mode — a consumer even with no 'data'
2256
+ * listener (arrived bytes discard, so 'end' can be reached, Node's
2257
+ * resumed-but-unconsumed stream). Buffered bytes deliver from the next
2258
+ * sweep (flags_pending sees the flowing consumer), not this stack.
2259
+ * Answers the socket (+1) — Node's chaining. */
2260
+ ScrNetSocket *scr_net_sock_resume(ScrNetSocket *s) {
2261
+ s->user_paused = false;
2262
+ s->flowing = true;
2263
+ scr_net_sock_update_read(s);
2264
+ return scr_net_sock_retain(s);
2265
+ }
2266
+
2267
+ /* socket.setNoDelay(enable): TCP_NODELAY on the live fd (client dials
2268
+ * already set it — Node's default there is off, a documented divergence
2269
+ * in the dial path; this call makes the state explicit either way).
2270
+ * Answers the socket (+1) — Node's chaining. */
2271
+ ScrNetSocket *scr_net_sock_set_nodelay(ScrNetSocket *s, bool enable) {
2272
+ if (s->fd >= 0) {
2273
+ int v = enable ? 1 : 0;
2274
+ setsockopt(s->fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof v);
2275
+ }
2276
+ return scr_net_sock_retain(s);
2277
+ }
2278
+
2279
+ void scr_net_sock_set_keepalive(ScrNetSocket *s, bool enable, double delay_ms) {
2280
+ if (s->fd < 0) return;
2281
+ int value = enable ? 1 : 0;
2282
+ setsockopt(s->fd, SOL_SOCKET, SO_KEEPALIVE, &value, sizeof value);
2283
+ if (!enable || !(delay_ms > 0) || !isfinite(delay_ms)) return;
2284
+ int seconds = (int)fmin((double)INT_MAX, fmax(1.0, floor(delay_ms / 1000.0)));
2285
+ #if defined(TCP_KEEPIDLE)
2286
+ setsockopt(s->fd, IPPROTO_TCP, TCP_KEEPIDLE, &seconds, sizeof seconds);
2287
+ #elif defined(TCP_KEEPALIVE)
2288
+ setsockopt(s->fd, IPPROTO_TCP, TCP_KEEPALIVE, &seconds, sizeof seconds);
2289
+ #endif
2290
+ }
2291
+
2292
+ /* socket.destroySoon(): end the write half now, destroy once the FIN is
2293
+ * actually out (buffered bytes flush first — Node's 'finish'-then-destroy). */
2294
+ void scr_net_sock_destroy_soon(ScrNetSocket *s) {
2295
+ if (s->fd < 0) return;
2296
+ if (s->wr_done) {
2297
+ scr_net_sock_close_fd(s);
2298
+ return;
2299
+ }
2300
+ s->destroy_on_finish = true;
2301
+ s->wr_ending = true;
2302
+ scr_net_sock_maybe_finish_write(s);
2303
+ }
2304
+
2305
+ /* end(callback): fires once the FIN went out ('finish'), from the sweep. */
2306
+ void scr_net_sock_on_finish(ScrNetSocket *s, ScrClosure *cb /*moves*/) {
2307
+ if (s->close_emitted) {
2308
+ scr_closure_release(cb);
2309
+ return;
2310
+ }
2311
+ scr_net_ls_add(&s->finish_ls, cb, NULL, true);
2312
+ if (s->wr_done) s->finish_pending = true; /* already finished: next sweep */
2313
+ }
2314
+
2315
+ /* write(chunk, callback): fires when the write buffer drains (this
2316
+ * surface's flush moment), from the sweep. */
2317
+ void scr_net_sock_on_write_flush(ScrNetSocket *s, ScrClosure *cb /*moves*/) {
2318
+ if (s->close_emitted) {
2319
+ scr_closure_release(cb);
2320
+ return;
2321
+ }
2322
+ scr_net_ls_add(&s->wcb_ls, cb, NULL, true);
2323
+ }
2324
+
2325
+ double scr_net_sock_bytes_written(ScrNetSocket *s) { return (double)s->bytes_written; }
2326
+
2327
+ /* socket.readable: true until the read half is done (peer FIN / destroy). */
2328
+ bool scr_net_sock_readable(ScrNetSocket *s) { return s->fd >= 0 && !s->rd_eof; }
2329
+
2330
+ /* socket.setTimeout(ms): ms > 0 arms the idle timer NOW (Node starts the
2331
+ * clock at the call — connecting time counts), ms <= 0 disables. */
2332
+ void scr_net_sock_set_timeout(ScrNetSocket *s, double ms) {
2333
+ if (ms > 0 && s->fd >= 0) {
2334
+ s->timeout_ms = ms;
2335
+ scr_net_sock_timer_arm(s);
2336
+ } else {
2337
+ s->timeout_ms = 0;
2338
+ scr_net_sock_timer_cancel(s);
2339
+ }
2340
+ }
2341
+
2342
+ void scr_net_sock_on_timeout(ScrNetSocket *s, ScrClosure *cb /*moves*/, bool once) {
2343
+ if (s->close_emitted) {
2344
+ scr_closure_release(cb);
2345
+ return;
2346
+ }
2347
+ scr_net_ls_add(&s->timeout_ls, cb, NULL, once);
2348
+ }
2349
+
2350
+ /* socket.remoteAddress: the peer's address (+1), cached at first read
2351
+ * (Node's _getpeername cache: a value read while connected survives
2352
+ * destroy), or NULL — the undefined arm — for a never-read socket after
2353
+ * close. A dual-stack accept of an IPv4 peer reads "::ffff:a.b.c.d",
2354
+ * like Node. */
2355
+ /* socket.encrypted: true iff the socket carries a TLS transport (Node
2356
+ * types `encrypted: true` on TLSSocket from construction; plain sockets
2357
+ * answer the undefined arm — the emitter maps false to it). */
2358
+ bool scr_net_sock_encrypted(ScrNetSocket *s) { return s->tops != NULL; }
2359
+
2360
+ ScrStr *scr_net_sock_remote_address(ScrNetSocket *s) {
2361
+ if (s->remote_cache) return scr_str_retain(s->remote_cache);
2362
+ if (s->fd < 0) return NULL;
2363
+ struct sockaddr_storage ss;
2364
+ socklen_t len = sizeof ss;
2365
+ if (getpeername(s->fd, (struct sockaddr *)&ss, &len) != 0) return NULL;
2366
+ char buf[INET6_ADDRSTRLEN];
2367
+ const char *out = NULL;
2368
+ if (ss.ss_family == AF_INET) {
2369
+ out = inet_ntop(AF_INET, &((struct sockaddr_in *)&ss)->sin_addr, buf, sizeof buf);
2370
+ } else if (ss.ss_family == AF_INET6) {
2371
+ out = inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&ss)->sin6_addr, buf, sizeof buf);
2372
+ }
2373
+ if (!out) return NULL;
2374
+ s->remote_cache = scr_str_new(out, strlen(out));
2375
+ return scr_str_retain(s->remote_cache);
2376
+ }
2377
+
2378
+ void scr_net_sock_destroy(ScrNetSocket *s) {
2379
+ if (s->fd < 0 && !s->in_registry) return;
2380
+ s->rd_eof = true;
2381
+ s->wr_done = true;
2382
+ scr_net_sock_close_fd(s); /* 'close' fires at the next sweep */
2383
+ }
2384
+
2385
+ /* ── the paused-mode surface (the demux path: once('readable') +
2386
+ * read(1) + unshift) ─────────────────────────────────────────────────── */
2387
+
2388
+ /* Append arrived bytes to the receive buffer (paused-mode reads). */
2389
+ static void scr_net_sock_append_rbuf(ScrNetSocket *s, const char *data, size_t len) {
2390
+ if (len == 0) return;
2391
+ if (s->rhead > 0) {
2392
+ memmove(s->rbuf, s->rbuf + s->rhead, s->rlen - s->rhead);
2393
+ s->rlen -= s->rhead;
2394
+ s->rhead = 0;
2395
+ }
2396
+ if (s->rlen + len > s->rcap) {
2397
+ size_t cap = s->rcap ? s->rcap : 4096;
2398
+ while (cap < s->rlen + len) cap *= 2;
2399
+ s->rbuf = realloc(s->rbuf, cap);
2400
+ if (!s->rbuf) scr_net_oom();
2401
+ s->rcap = cap;
2402
+ }
2403
+ memcpy(s->rbuf + s->rlen, data, len);
2404
+ s->rlen += len;
2405
+ }
2406
+
2407
+ void scr_net_sock_on_readable(ScrNetSocket *s, ScrClosure *cb /*moves*/, bool once) {
2408
+ if (s->close_emitted || s->rd_eof) {
2409
+ scr_closure_release(cb);
2410
+ return;
2411
+ }
2412
+ scr_net_ls_add(&s->readable_ls, cb, NULL, once);
2413
+ scr_net_sock_update_read(s);
2414
+ }
2415
+
2416
+ /* socket.read(n): n > 0 answers exactly n buffered bytes or NULL (Node's
2417
+ * less-than-n-buffered answer); n <= 0 (the read() form) drains the
2418
+ * whole buffer, NULL when empty. Always +1. */
2419
+ ScrBytes *scr_net_sock_read_bytes(ScrNetSocket *s, double n) {
2420
+ size_t avail = s->rlen - s->rhead;
2421
+ size_t want = n > 0 ? (size_t)n : avail;
2422
+ if (avail == 0 || want == 0 || want > avail) return NULL;
2423
+ ScrBytes *out = scr_bytes_new(SCR_BYTES_U8, (double)want);
2424
+ size_t took = scr_net_sock_take_buffered(s, (char *)out->data, want);
2425
+ (void)took;
2426
+ return out;
2427
+ }
2428
+
2429
+ /* socket.unshift(buf): the bytes re-enter the FRONT of the receive
2430
+ * buffer — every consumer (data listeners, an http parser, a TLS bio)
2431
+ * sees them before anything still in the kernel. */
2432
+ void scr_net_sock_unshift_bytes(ScrNetSocket *s, ScrBytes *data /*borrowed*/) {
2433
+ if (data->len == 0) return;
2434
+ size_t avail = s->rlen - s->rhead;
2435
+ if (s->rhead >= data->len) {
2436
+ /* room at the front (the read(1)-then-unshift shape: the byte slots
2437
+ * straight back where it came from) */
2438
+ s->rhead -= data->len;
2439
+ memcpy(s->rbuf + s->rhead, data->data, data->len);
2440
+ return;
2441
+ }
2442
+ size_t total = data->len + avail;
2443
+ char *fresh = malloc(total > 0 ? total : 1);
2444
+ if (!fresh) scr_net_oom();
2445
+ memcpy(fresh, data->data, data->len);
2446
+ if (avail > 0) memcpy(fresh + data->len, s->rbuf + s->rhead, avail);
2447
+ free(s->rbuf);
2448
+ s->rbuf = fresh;
2449
+ s->rhead = 0;
2450
+ s->rlen = total;
2451
+ s->rcap = total > 0 ? total : 1;
2452
+ }
2453
+
2454
+ /* server.emit('connection', socket): route an accepted socket into
2455
+ * ANOTHER server — the demux pattern (portless's first-byte TLS peek).
2456
+ * The target's protocol layer claims the socket (the http parser, or
2457
+ * the TLS transport whose deferred 'connection' fires post-handshake);
2458
+ * the socket's owning server stays the accepting one, exactly Node's
2459
+ * connection accounting. */
2460
+ void scr_net_server_emit_connection(ScrNetServer *srv, ScrNetSocket *sock) {
2461
+ if (srv->close_emitted) return;
2462
+ if (srv->native_conn) {
2463
+ srv->native_conn(srv->native_ctx, sock);
2464
+ if (scr_exc_pending()) return;
2465
+ }
2466
+ if (srv->defer_conn) {
2467
+ if (sock->conn_pending) scr_net_server_release(sock->conn_pending);
2468
+ sock->conn_pending = scr_net_server_retain(srv);
2469
+ return;
2470
+ }
2471
+ ScrNetL *snap;
2472
+ size_t n = scr_net_ls_snapshot(&srv->conn_ls, &snap);
2473
+ scr_dyn_this_push(srv, SCR_DYNH_NET_SERVER);
2474
+ for (size_t i = 0; i < n; i++) {
2475
+ if (!scr_exc_pending()) ((ScrNetConnFn)snap[i].fn)(snap[i].cb, scr_net_sock_retain(sock));
2476
+ scr_closure_release(snap[i].cb);
2477
+ }
2478
+ scr_dyn_this_pop();
2479
+ free(snap);
2480
+ }
2481
+
2482
+ /* The accepting server of a server-side socket (BORROWED; NULL on client
2483
+ * sockets) — the protocol layer binds it as the ambient receiver when
2484
+ * firing server-level events ('request': Node's this === server). */
2485
+ ScrNetServer *scr_net_sock_server(ScrNetSocket *s) { return s->server; }
2486
+
2487
+ /* socket.setEncoding(enc) — the req twin (scr_http_req_set_encoding's
2488
+ * contract: utf8 flips 'data' to strings, real-but-unsupported encodings
2489
+ * fence loudly, unknown names throw ERR_UNKNOWN_ENCODING). */
2490
+ void scr_net_sock_set_encoding(ScrNetSocket *s, ScrStr *enc /*borrowed*/) {
2491
+ if ((enc->len == 4 && memcmp(enc->data, "utf8", 4) == 0) ||
2492
+ (enc->len == 5 && memcmp(enc->data, "utf-8", 5) == 0)) {
2493
+ s->enc_utf8 = true;
2494
+ return;
2495
+ }
2496
+ static const char *const known[] = { "ascii", "latin1", "binary", "base64",
2497
+ "base64url", "hex", "ucs2", "ucs-2", "utf16le", "utf-16le", NULL };
2498
+ for (size_t i = 0; known[i]; i++) {
2499
+ if (enc->len == strlen(known[i]) && memcmp(enc->data, known[i], enc->len) == 0) {
2500
+ char msg[128];
2501
+ int n = snprintf(msg, sizeof msg, "setEncoding('%s') is not supported yet (only 'utf8' here)",
2502
+ known[i]);
2503
+ scr_throw_error_msg(SCR_ERR_ERROR, msg, (size_t)n);
2504
+ return;
2505
+ }
2506
+ }
2507
+ char msg[128];
2508
+ int n = snprintf(msg, sizeof msg, "Unknown encoding: %.*s",
2509
+ (int)(enc->len < 64 ? enc->len : 64), enc->data);
2510
+ scr_throw_error_msg_code(SCR_ERR_TYPE, msg, (size_t)n, "ERR_UNKNOWN_ENCODING");
2511
+ }
2512
+
2513
+ /* pipe(dst): every arrived chunk forwards to dst; src EOF end()s dst
2514
+ * (Node's default). Also arms the read side — a pipe is a consumer. */
2515
+ void scr_net_sock_pipe(ScrNetSocket *src, ScrNetSocket *dst) {
2516
+ if (src->pipe_dst) scr_net_sock_release(src->pipe_dst);
2517
+ src->pipe_dst = scr_net_sock_retain(dst);
2518
+ scr_net_sock_update_read(src);
2519
+ }
2520
+
2521
+ void scr_net_sock_on_data(ScrNetSocket *s, ScrClosure *cb /*moves*/, ScrNetDataFn fn,
2522
+ bool once) {
2523
+ if (s->close_emitted || s->rd_eof) {
2524
+ scr_closure_release(cb);
2525
+ return;
2526
+ }
2527
+ scr_net_ls_add(&s->data_ls, cb, (void *)fn, once);
2528
+ scr_net_sock_update_read(s);
2529
+ }
2530
+
2531
+ void scr_net_sock_on_end(ScrNetSocket *s, ScrClosure *cb /*moves*/, bool once) {
2532
+ if (s->close_emitted || s->rd_eof) {
2533
+ scr_closure_release(cb);
2534
+ return;
2535
+ }
2536
+ scr_net_ls_add(&s->end_ls, cb, NULL, once);
2537
+ }
2538
+
2539
+ void scr_net_sock_on_close(ScrNetSocket *s, ScrClosure *cb /*moves*/, bool once) {
2540
+ if (s->close_emitted) {
2541
+ scr_closure_release(cb);
2542
+ return;
2543
+ }
2544
+ scr_net_ls_add(&s->close_ls, cb, NULL, once);
2545
+ }
2546
+
2547
+ void scr_net_sock_on_error(ScrNetSocket *s, ScrClosure *cb /*moves*/, ScrChildErrFn fn,
2548
+ bool once) {
2549
+ if (s->close_emitted) {
2550
+ scr_closure_release(cb);
2551
+ return;
2552
+ }
2553
+ scr_net_ls_add(&s->err_ls, cb, (void *)fn, once);
2554
+ }
2555
+
2556
+ void scr_net_sock_on_connect(ScrNetSocket *s, ScrClosure *cb /*moves*/, bool once) {
2557
+ if (s->close_emitted || (!s->connecting && s->fd < 0)) {
2558
+ scr_closure_release(cb);
2559
+ return;
2560
+ }
2561
+ if (!s->connecting) {
2562
+ /* already connected: Node fires a late once('connect')… never — the
2563
+ * event is past. Release, like listeners after 'exit'. */
2564
+ scr_closure_release(cb);
2565
+ return;
2566
+ }
2567
+ scr_net_ls_add(&s->conn_ls, cb, NULL, once);
2568
+ }
2569
+
2570
+ /* The runtime-provided data adapters (the child/stdin thunk pattern). */
2571
+ void scr_net_data_thunk0(ScrClosure *cb, ScrBytes *chunk) {
2572
+ (void)chunk;
2573
+ ((void (*)(ScrClosure *))cb->fn)(cb);
2574
+ }
2575
+
2576
+ void scr_net_data_thunk_bytes(ScrClosure *cb, ScrBytes *chunk) {
2577
+ /* the listener owns its +1 param per the universal convention */
2578
+ ((void (*)(ScrClosure *, ScrBytes *))cb->fn)(cb, scr_bytes_retain(chunk));
2579
+ }
2580
+
2581
+ /* The checked-dynamic data listener (a dynCheck-adapted (dyn) => void
2582
+ * closure): the chunk boxes BUFFER-flavored — Node hands Buffers to
2583
+ * 'data', so toString()/string coercion decode utf8 (the stream lane's
2584
+ * box-by-tag stance). The adapter owns its +1 dyn param. */
2585
+ void scr_net_data_thunk_dyn(ScrClosure *cb, ScrBytes *chunk) {
2586
+ ScrDyn *d = scr_dyn_new_chunk(chunk);
2587
+ ((void (*)(ScrClosure *, ScrDyn *))cb->fn)(cb, d);
2588
+ }
2589
+
2590
+ /* The string-TYPED data listener ((chunk: string) => void — the
2591
+ * setEncoding('utf8') shape): the chunk decodes as UTF-8 (WHATWG
2592
+ * replacement, Buffer.toString's algorithm) into the string the
2593
+ * annotation promises. Without setEncoding Node would hand a Buffer —
2594
+ * a string-typed listener there mistypes its own input, and the decode
2595
+ * is the honest reading of the annotation. */
2596
+ void scr_net_data_thunk_str(ScrClosure *cb, ScrBytes *chunk) {
2597
+ ScrStr *enc = scr_str_new("utf8", 4);
2598
+ ScrStr *text = scr_bytes_to_str(chunk, enc);
2599
+ scr_str_release(enc);
2600
+ ((void (*)(ScrClosure *, ScrStr *))cb->fn)(cb, text);
2601
+ }
2602
+
2603
+ /* The connection-handler adapters: the socket arrives +1 from the firing
2604
+ * site; the zero-param shape releases it. */
2605
+ void scr_net_conn_thunk0(ScrClosure *cb, ScrNetSocket *sock) {
2606
+ scr_net_sock_release(sock);
2607
+ ((void (*)(ScrClosure *))cb->fn)(cb);
2608
+ }
2609
+
2610
+ void scr_net_conn_thunk_sock(ScrClosure *cb, ScrNetSocket *sock) {
2611
+ ((void (*)(ScrClosure *, ScrNetSocket *))cb->fn)(cb, sock);
2612
+ }
2613
+
2614
+ /* ── the protocol-layer hooks (scr_http.c) ───────────────────────────── */
2615
+
2616
+ void scr_net_server_set_native_conn(ScrNetServer *s, ScrNetNativeConnFn fn, void *ctx,
2617
+ void (*ctx_free)(void *)) {
2618
+ s->native_conn = fn;
2619
+ s->native_ctx = ctx;
2620
+ s->native_ctx_free = ctx_free;
2621
+ }
2622
+
2623
+ void scr_net_server_set_proto_settle(ScrNetServer *s, void (*fn)(void *)) {
2624
+ s->proto_settle = fn;
2625
+ }
2626
+
2627
+ bool scr_net_server_settled(ScrNetServer *s) { return s->close_emitted; }
2628
+
2629
+ void scr_net_server_set_http_ctx(ScrNetServer *s, void *ctx) { s->http_ctx = ctx; }
2630
+ void *scr_net_server_get_http_ctx(ScrNetServer *s) { return s->http_ctx; }
2631
+
2632
+ void scr_net_sock_set_native_reader(ScrNetSocket *s, ScrNetNativeDataFn data,
2633
+ ScrNetNativeEventFn eof, ScrNetNativeEventFn closed,
2634
+ void *ctx, void (*ctx_free)(void *)) {
2635
+ s->native_data = data;
2636
+ s->native_eof = eof;
2637
+ s->native_closed = closed;
2638
+ s->native_idle = NULL;
2639
+ s->native_ctx = ctx;
2640
+ s->native_ctx_free = ctx_free;
2641
+ scr_net_sock_update_read(s);
2642
+ }
2643
+
2644
+ void scr_net_sock_set_native_idle_checker(ScrNetSocket *s, bool (*fn)(void *)) {
2645
+ s->native_idle = fn;
2646
+ }
2647
+
2648
+ /* The upgrade handover: clear the native reader's FN POINTERS but keep
2649
+ * the ctx (still freed at socket death as registered) — the protocol
2650
+ * parser steps aside mid-call and 'data'/pipe consumers take the raw
2651
+ * stream from the next byte on. */
2652
+ void scr_net_sock_clear_native_reader(ScrNetSocket *s) {
2653
+ s->native_data = NULL;
2654
+ s->native_eof = NULL;
2655
+ s->native_closed = NULL;
2656
+ s->native_idle = NULL; /* upgraded and CONNECT sockets are outside HTTP close sweeps */
2657
+ s->native_http_timeout = NULL;
2658
+ scr_net_sock_update_read(s);
2659
+ }
2660
+
2661
+ /* socket.destroyed — true once the fd is gone (destroy() or full close),
2662
+ * Node's flag for "this stream is done". */
2663
+ bool scr_net_sock_destroyed(ScrNetSocket *s) { return s->fd < 0; }
2664
+
2665
+ /* socket.writable — Node's stream flag: the write half is open (no end()
2666
+ * yet, no FIN sent, fd alive). Connecting sockets answer true — writes
2667
+ * queue, exactly Node. */
2668
+ bool scr_net_sock_writable(ScrNetSocket *s) {
2669
+ return s->fd >= 0 && !s->wr_ending && !s->wr_done;
2670
+ }
2671
+
2672
+ bool scr_net_sock_established(ScrNetSocket *s) {
2673
+ return s->fd >= 0 && !s->connecting && (!s->tops || s->t_est);
2674
+ }
2675
+
2676
+ /* The protocol layer's timeout/error hooks (scr_http.c's client and the
2677
+ * server parser's error swallowing). */
2678
+ void scr_net_sock_set_native_events(ScrNetSocket *s, ScrNetNativeEventFn timeout,
2679
+ ScrNetNativeErrFn err) {
2680
+ s->native_timeout = timeout;
2681
+ s->native_err = err;
2682
+ }
2683
+
2684
+ void scr_net_sock_set_native_http_timeout(ScrNetSocket *s, ScrNetNativeTimeoutHandledFn fn) {
2685
+ s->native_http_timeout = fn;
2686
+ }
2687
+
2688
+ /* Client connect completion for the protocol layer (the h2 session's
2689
+ * 'connect' moment) — fires before the socket's own conn_ls. */
2690
+ void scr_net_sock_set_native_established(ScrNetSocket *s, ScrNetNativeEventFn fn) {
2691
+ s->native_established = fn;
2692
+ }
2693
+
2694
+ /* Raw bytes from the protocol layer (head/framing text). */
2695
+ void scr_net_sock_write_native(ScrNetSocket *s, const char *buf, size_t n) {
2696
+ scr_net_sock_write_raw(s, buf, n);
2697
+ }
2698
+
2699
+ /* ── the transport hooks (scr_tls.c) ─────────────────────────────────── */
2700
+
2701
+ void scr_net_sock_set_transport(ScrNetSocket *s, const ScrNetTransportOps *ops, void *tctx) {
2702
+ s->tops = ops;
2703
+ s->tctx = tctx;
2704
+ s->t_est = false;
2705
+ scr_net_sock_update_read(s); /* the handshake is a consumer */
2706
+ scr_net_sock_update_write(s);
2707
+ }
2708
+
2709
+ int scr_net_sock_fd(ScrNetSocket *s) { return s->fd; }
2710
+
2711
+ /* Drain up to n bytes of the receive buffer (peeked/unshifted bytes) —
2712
+ * consumers call this BEFORE the fd so re-queued bytes keep their
2713
+ * position in the stream. */
2714
+ size_t scr_net_sock_take_buffered(ScrNetSocket *s, char *buf, size_t n) {
2715
+ size_t avail = s->rlen - s->rhead;
2716
+ if (avail == 0) return 0;
2717
+ size_t take = n < avail ? n : avail;
2718
+ memcpy(buf, s->rbuf + s->rhead, take);
2719
+ s->rhead += take;
2720
+ if (s->rhead == s->rlen) s->rhead = s->rlen = 0;
2721
+ return take;
2722
+ }
2723
+
2724
+ void scr_net_sock_transport_want_write(ScrNetSocket *s) {
2725
+ s->t_want_write = true;
2726
+ scr_net_sock_update_write(s);
2727
+ }
2728
+
2729
+ /* The transport context, guarded by ops identity — the SNI answer path
2730
+ * re-finds its engine from the boxed socket, which may have died (or
2731
+ * been re-routed) between the callback and the answer. */
2732
+ void *scr_net_sock_transport_ctx_for(ScrNetSocket *s, const ScrNetTransportOps *ops) {
2733
+ return s->tops == ops ? s->tctx : NULL;
2734
+ }
2735
+
2736
+ /* Re-drive a parked handshake (the asynchronous SNI answer arrived; no
2737
+ * fd readiness is coming — the client is waiting for the ServerHello). */
2738
+ void scr_net_sock_transport_resume(ScrNetSocket *s) { scr_net_sock_transport_pump(s); }
2739
+
2740
+ /* Replay raw bytes at the FRONT of the receive buffer (the SNI
2741
+ * pre-parse handing the consumed ClientHello back to the TLS bio) —
2742
+ * unshift's shape over a raw span. */
2743
+ void scr_net_sock_replay(ScrNetSocket *s, const char *data, size_t len) {
2744
+ if (len == 0) return;
2745
+ size_t avail = s->rlen - s->rhead;
2746
+ if (s->rhead >= len) {
2747
+ s->rhead -= len;
2748
+ memcpy(s->rbuf + s->rhead, data, len);
2749
+ return;
2750
+ }
2751
+ size_t total = len + avail;
2752
+ char *fresh = malloc(total);
2753
+ if (!fresh) scr_net_oom();
2754
+ memcpy(fresh, data, len);
2755
+ if (avail > 0) memcpy(fresh + len, s->rbuf + s->rhead, avail);
2756
+ free(s->rbuf);
2757
+ s->rbuf = fresh;
2758
+ s->rhead = 0;
2759
+ s->rlen = total;
2760
+ s->rcap = total;
2761
+ }
2762
+
2763
+ void scr_net_sock_transport_error(ScrNetSocket *s, const char *msg) {
2764
+ if (msg != NULL) {
2765
+ if (!s->pending_err) s->pending_err = scr_str_new(msg, strlen(msg));
2766
+ s->had_error = true;
2767
+ }
2768
+ scr_net_sock_close_fd(s); /* the sweep delivers 'error' (if any) then 'close' */
2769
+ }
2770
+
2771
+ void scr_net_server_defer_connections(ScrNetServer *s) { s->defer_conn = true; }
2772
+
2773
+ void scr_net_server_get_native_conn(ScrNetServer *s, ScrNetNativeConnFn *fn, void **ctx,
2774
+ void (**ctx_free)(void *)) {
2775
+ *fn = s->native_conn;
2776
+ *ctx = s->native_ctx;
2777
+ *ctx_free = s->native_ctx_free;
2778
+ }
2779
+
2780
+ /* ── the sweep: deferred emits ───────────────────────────────────────── */
2781
+
2782
+ /* The protocol layer's deferred-emit hook (scr_http.c: response/request
2783
+ * 'close' events and the client teardown queue fire from the sweep, one
2784
+ * pass after the work that flagged them — Node's later-than-the-handler
2785
+ * emits). Registered once by scr_http install-time code. */
2786
+ enum { SCR_NET_PROTO_SLOTS = 4 };
2787
+ static bool (*scr_net_proto_pendings[SCR_NET_PROTO_SLOTS])(void);
2788
+ static void (*scr_net_proto_sweeps[SCR_NET_PROTO_SLOTS])(void);
2789
+ static size_t scr_net_proto_n = 0;
2790
+
2791
+ /* ADDITIVE registration (each protocol unit — scr_http.c, scr_http2.c —
2792
+ * claims a slot at its install; both can co-link in one binary). */
2793
+ void scr_net_set_proto_sweep(bool (*pending)(void), void (*sweep)(void)) {
2794
+ if (scr_net_proto_n == SCR_NET_PROTO_SLOTS) abort();
2795
+ scr_net_proto_pendings[scr_net_proto_n] = pending;
2796
+ scr_net_proto_sweeps[scr_net_proto_n] = sweep;
2797
+ scr_net_proto_n++;
2798
+ }
2799
+
2800
+ static bool scr_net_proto_pending(void) {
2801
+ for (size_t i = 0; i < scr_net_proto_n; i++) {
2802
+ if (scr_net_proto_pendings[i]()) return true;
2803
+ }
2804
+ return false;
2805
+ }
2806
+
2807
+ static void scr_net_proto_sweep(void) {
2808
+ for (size_t i = 0; i < scr_net_proto_n; i++) {
2809
+ scr_net_proto_sweeps[i]();
2810
+ if (scr_exc_pending()) return;
2811
+ }
2812
+ }
2813
+
2814
+ static bool scr_net_flags_pending(void) {
2815
+ if (scr_net_proto_pending()) return true;
2816
+ for (ScrNetSocket *s = scr_net_socks; s; s = s->next) {
2817
+ if (s->pending_err || (s->emit_close && !s->close_emitted)) return true;
2818
+ if (s->finish_pending && s->finish_ls.n > 0) return true;
2819
+ if (s->wcb_ls.n > 0 && (s->wlen == s->whead || s->fd < 0)) return true;
2820
+ /* bytes already out of the kernel with a consumer waiting — decrypted
2821
+ * plaintext inside a transport, or unshifted bytes in the receive
2822
+ * buffer: the poller can't re-signal them, the sweep must deliver */
2823
+ bool consumers = (s->data_ls.n > 0 || s->pipe_dst || s->native_data || s->flowing) &&
2824
+ !s->user_paused;
2825
+ if (consumers && s->fd >= 0) {
2826
+ if (s->tops && s->t_est && s->tops->pending && s->tops->pending(s->tctx)) return true;
2827
+ if (!s->tops && s->rlen > s->rhead) return true;
2828
+ }
2829
+ }
2830
+ for (ScrNetServer *s = scr_net_servers; s; s = s->next) {
2831
+ if (s->pending_err || s->emit_listening) return true;
2832
+ if (s->closing && s->nconns == 0 && !s->close_emitted) return true;
2833
+ }
2834
+ return false;
2835
+ }
2836
+
2837
+ /* Settles a server whose 'close' is due: fires the close callbacks and
2838
+ * listeners, drops every listener list (the cycle story), and leaves the
2839
+ * registry. Shared by the server sweep and the socket settle below —
2840
+ * Node emits a DRAINED server's 'close' before the dying socket's own
2841
+ * 'close', so the socket settle calls this mid-flight. */
2842
+ static void scr_net_server_settle(ScrNetServer *srv) {
2843
+ srv->close_emitted = true;
2844
+ scr_net_fire0_this(&srv->close_ls, srv, SCR_DYNH_NET_SERVER);
2845
+ scr_net_ls_drop(&srv->conn_ls);
2846
+ scr_net_ls_drop(&srv->err_ls);
2847
+ scr_net_ls_drop(&srv->close_ls);
2848
+ scr_net_ls_drop(&srv->listening_cbs);
2849
+ scr_net_ls_drop(&srv->timeout_ls);
2850
+ if (srv->proto_settle && srv->http_ctx) srv->proto_settle(srv->http_ctx);
2851
+ scr_net_server_unregister(srv);
2852
+ }
2853
+
2854
+ /* Sockets first (a dying connection may drain its server), servers after.
2855
+ * Every fire checks for a pending exception and bails — the loop surfaces
2856
+ * it as an uncaught throw. */
2857
+ static void scr_net_sweep(void) {
2858
+ scr_net_proto_sweep();
2859
+ if (scr_exc_pending()) return;
2860
+ ScrNetSocket *sock = scr_net_socks;
2861
+ while (sock) {
2862
+ ScrNetSocket *next = sock->next; /* may unregister below */
2863
+ scr_net_sock_retain(sock); /* callbacks may drop every other ref */
2864
+ if (sock->fd >= 0 && !sock->user_paused &&
2865
+ (sock->data_ls.n > 0 || sock->pipe_dst || sock->native_data || sock->flowing) &&
2866
+ ((sock->tops && sock->t_est && sock->tops->pending && sock->tops->pending(sock->tctx)) ||
2867
+ (!sock->tops && sock->rlen > sock->rhead))) {
2868
+ /* deliver bytes the kernel can't re-signal (see flags_pending) */
2869
+ scr_net_sock_read(sock);
2870
+ if (scr_exc_pending()) {
2871
+ scr_net_sock_release(sock);
2872
+ return;
2873
+ }
2874
+ }
2875
+ if (sock->wcb_ls.n > 0 && (sock->wlen == sock->whead || sock->fd < 0)) {
2876
+ /* write(chunk, cb): the buffer drained (this surface's flush
2877
+ * moment) — the callbacks fire off the sweep, never the writing
2878
+ * stack. A dead socket fires them too (the buffered bytes are
2879
+ * gone either way; Node errors them — documented divergence,
2880
+ * the no-backpressure stance). */
2881
+ scr_net_fire0_this(&sock->wcb_ls, sock, SCR_DYNH_NET_SOCKET);
2882
+ if (scr_exc_pending()) {
2883
+ scr_net_sock_release(sock);
2884
+ return;
2885
+ }
2886
+ }
2887
+ if (sock->finish_pending) {
2888
+ sock->finish_pending = false;
2889
+ scr_net_fire0_this(&sock->finish_ls, sock, SCR_DYNH_NET_SOCKET);
2890
+ if (scr_exc_pending()) {
2891
+ scr_net_sock_release(sock);
2892
+ return;
2893
+ }
2894
+ }
2895
+ if (sock->pending_err) {
2896
+ ScrStr *msg = sock->pending_err;
2897
+ sock->pending_err = NULL;
2898
+ /* the protocol layer gets first claim (the http conn/client owns
2899
+ * the error story: 'error' on the req, or Node's silent server-side
2900
+ * teardown); unconsumed errors fall through to the socket's own
2901
+ * listeners — and the unhandled-'error' exit */
2902
+ bool consumed = false;
2903
+ if (sock->native_err) consumed = sock->native_err(sock->native_ctx, msg);
2904
+ if (!consumed && !scr_exc_pending()) scr_net_fire_err_this(&sock->err_ls, msg, sock, SCR_DYNH_NET_SOCKET);
2905
+ scr_str_release(msg);
2906
+ if (scr_exc_pending()) {
2907
+ scr_net_sock_release(sock);
2908
+ return;
2909
+ }
2910
+ }
2911
+ if (sock->emit_close && !sock->close_emitted && sock->fd < 0) {
2912
+ sock->close_emitted = true;
2913
+ sock->emit_close = false;
2914
+ /* The owning server's count drains FIRST, and a now-drained closing
2915
+ * server settles before this socket's own 'close' fires — Node's
2916
+ * observed order (differential: the net-echo fixture). */
2917
+ if (sock->server) {
2918
+ ScrNetServer *srv = sock->server;
2919
+ sock->server = NULL;
2920
+ srv->nconns--;
2921
+ if (srv->closing && srv->nconns == 0 && !srv->close_emitted) {
2922
+ scr_net_server_settle(srv);
2923
+ }
2924
+ scr_net_server_release(srv);
2925
+ if (scr_exc_pending()) {
2926
+ scr_net_sock_release(sock);
2927
+ return;
2928
+ }
2929
+ }
2930
+ if (sock->native_closed) {
2931
+ sock->native_closed(sock->native_ctx);
2932
+ if (scr_exc_pending()) {
2933
+ scr_net_sock_release(sock);
2934
+ return;
2935
+ }
2936
+ }
2937
+ scr_net_fire0_this(&sock->close_ls, sock, SCR_DYNH_NET_SOCKET);
2938
+ /* settle: listeners drop (cycle story) */
2939
+ scr_net_ls_drop(&sock->data_ls);
2940
+ scr_net_ls_drop(&sock->end_ls);
2941
+ scr_net_ls_drop(&sock->close_ls);
2942
+ scr_net_ls_drop(&sock->err_ls);
2943
+ scr_net_ls_drop(&sock->conn_ls);
2944
+ scr_net_ls_drop(&sock->timeout_ls);
2945
+ scr_net_ls_drop(&sock->readable_ls);
2946
+ scr_net_ls_drop(&sock->finish_ls);
2947
+ scr_net_ls_drop(&sock->wcb_ls);
2948
+ if (sock->pipe_dst) {
2949
+ scr_net_sock_release(sock->pipe_dst);
2950
+ sock->pipe_dst = NULL;
2951
+ }
2952
+ if (sock->conn_pending) {
2953
+ scr_net_server_release(sock->conn_pending);
2954
+ sock->conn_pending = NULL;
2955
+ }
2956
+ scr_net_sock_unregister(sock);
2957
+ if (scr_exc_pending()) {
2958
+ scr_net_sock_release(sock);
2959
+ return;
2960
+ }
2961
+ }
2962
+ scr_net_sock_release(sock);
2963
+ sock = next;
2964
+ }
2965
+ ScrNetServer *srv = scr_net_servers;
2966
+ while (srv) {
2967
+ ScrNetServer *next = srv->next;
2968
+ scr_net_server_retain(srv);
2969
+ if (srv->emit_listening) {
2970
+ srv->emit_listening = false;
2971
+ scr_net_fire0_this(&srv->listening_cbs, srv, SCR_DYNH_NET_SERVER);
2972
+ if (scr_exc_pending()) {
2973
+ scr_net_server_release(srv);
2974
+ return;
2975
+ }
2976
+ }
2977
+ if (srv->pending_err) {
2978
+ ScrStr *msg = srv->pending_err;
2979
+ srv->pending_err = NULL;
2980
+ scr_net_fire_err_this(&srv->err_ls, msg, srv, SCR_DYNH_NET_SERVER);
2981
+ scr_str_release(msg);
2982
+ /* A failed listen SETTLES the handle: listeners drop (an error
2983
+ * listener capturing its own server would otherwise cycle forever —
2984
+ * the RC audit caught exactly that) and it leaves the registry. A
2985
+ * later listen() starts fresh; pre-failure listeners are gone,
2986
+ * where Node's would survive (SEMANTICS.md divergence 48). */
2987
+ if (!srv->listening && !srv->closing) {
2988
+ scr_net_ls_drop(&srv->conn_ls);
2989
+ scr_net_ls_drop(&srv->err_ls);
2990
+ scr_net_ls_drop(&srv->close_ls);
2991
+ scr_net_ls_drop(&srv->listening_cbs);
2992
+ scr_net_ls_drop(&srv->timeout_ls);
2993
+ scr_net_server_unregister(srv);
2994
+ }
2995
+ if (scr_exc_pending()) {
2996
+ scr_net_server_release(srv);
2997
+ return;
2998
+ }
2999
+ }
3000
+ scr_net_server_release(srv);
3001
+ srv = next;
3002
+ }
3003
+ /* Drained closing servers settle in close-REQUEST order (close_seq),
3004
+ * not registry order — Node emits 'close' in the order close() was
3005
+ * called when several drain in one turn. */
3006
+ for (;;) {
3007
+ ScrNetServer *due = NULL;
3008
+ for (ScrNetServer *it = scr_net_servers; it; it = it->next) {
3009
+ if (it->closing && it->nconns == 0 && !it->close_emitted &&
3010
+ (due == NULL || it->close_seq < due->close_seq)) {
3011
+ due = it;
3012
+ }
3013
+ }
3014
+ if (due == NULL) return;
3015
+ scr_net_server_retain(due);
3016
+ scr_net_server_settle(due);
3017
+ scr_net_server_release(due);
3018
+ if (scr_exc_pending()) return;
3019
+ }
3020
+ }
3021
+
3022
+ /* ── the loop hooks (scr_async.c) ────────────────────────────────────── */
3023
+
3024
+ static bool scr_net_pending(void) {
3025
+ if (scr_net_servers != NULL || scr_net_socks != NULL) return true;
3026
+ return scr_net_proto_pending();
3027
+ }
3028
+
3029
+ static int scr_net_pollfd(void) {
3030
+ return scr_net_poller != NULL ? scrp_poller_fd(scr_net_poller) : -1;
3031
+ }
3032
+
3033
+ static void scr_net_dispatch(void) {
3034
+ if (!scr_net_servers && !scr_net_socks &&
3035
+ !scr_net_proto_pending()) {
3036
+ return;
3037
+ }
3038
+ for (;;) {
3039
+ scr_net_sweep();
3040
+ if (scr_exc_pending()) return;
3041
+ if (scr_net_poller == NULL) return;
3042
+ ScrPollerEvent evs[64];
3043
+ int n = scrp_drain(scr_net_poller, evs, 64);
3044
+ for (int i = 0; i < n; i++) {
3045
+ void *udata = evs[i].udata;
3046
+ if (!udata) continue;
3047
+ int kind = *(int *)udata;
3048
+ if (kind == SCR_NET_K_SERVER) {
3049
+ scr_net_server_accept((ScrNetServer *)udata);
3050
+ } else if (kind == SCR_NET_K_SOCKET) {
3051
+ ScrNetSocket *s = (ScrNetSocket *)udata;
3052
+ /* A callback earlier in this batch may have closed this fd
3053
+ * (destroy inside a data listener) — its remaining events are
3054
+ * stale; the handle itself stays alive until the sweep. */
3055
+ if (s->fd < 0) continue;
3056
+ if (evs[i].events & SCRP_TIMER) {
3057
+ /* the idle period elapsed: 'timeout' fires once (one-shot — the
3058
+ * next activity re-arms); the socket stays open, like Node */
3059
+ s->timeout_armed = false;
3060
+ if (s->native_timeout) {
3061
+ s->native_timeout(s->native_ctx);
3062
+ if (scr_exc_pending()) return;
3063
+ }
3064
+ if (s->server && s->server->http_timeout_surface &&
3065
+ s->native_http_timeout) {
3066
+ ScrNetServer *srv = scr_net_server_retain(s->server);
3067
+ bool handled = s->native_http_timeout(s->native_ctx);
3068
+ if (scr_exc_pending()) {
3069
+ scr_net_server_release(srv);
3070
+ return;
3071
+ }
3072
+ bool server_handled = srv->timeout_ls.n > 0;
3073
+ if (server_handled) {
3074
+ ScrNetL *snap;
3075
+ size_t count = scr_net_ls_snapshot(&srv->timeout_ls, &snap);
3076
+ scr_dyn_this_push(srv, SCR_DYNH_NET_SERVER);
3077
+ for (size_t j = 0; j < count; j++) {
3078
+ if (!scr_exc_pending()) ((ScrNetConnFn)snap[j].fn)(snap[j].cb, scr_net_sock_retain(s));
3079
+ scr_closure_release(snap[j].cb);
3080
+ }
3081
+ scr_dyn_this_pop();
3082
+ free(snap);
3083
+ }
3084
+ if (!handled && !server_handled && !scr_exc_pending())
3085
+ scr_net_sock_destroy(s); /* Node's unhandled server timeout */
3086
+ scr_net_server_release(srv);
3087
+ if (scr_exc_pending()) return;
3088
+ }
3089
+ scr_net_fire0_this(&s->timeout_ls, s, SCR_DYNH_NET_SOCKET);
3090
+ if (scr_exc_pending()) return;
3091
+ if (s->fd < 0) continue;
3092
+ }
3093
+ /* kqueue delivers one direction per event (today's exact order);
3094
+ * epoll may coalesce both into one — writes first (connect
3095
+ * completion, flushes), then reads, re-checking the fd a write
3096
+ * failure may have closed. */
3097
+ if (evs[i].events & SCRP_WRITABLE) {
3098
+ if (s->connecting) scr_net_sock_connect_done(s);
3099
+ else if (s->tops && !s->t_est) {
3100
+ s->t_want_write = false;
3101
+ scr_net_sock_transport_pump(s);
3102
+ if (!scr_exc_pending() && s->fd >= 0) scr_net_sock_update_write(s);
3103
+ } else {
3104
+ s->t_want_write = false;
3105
+ scr_net_sock_flush(s);
3106
+ }
3107
+ }
3108
+ if ((evs[i].events & SCRP_READABLE) && !scr_exc_pending() && s->fd >= 0) {
3109
+ if (s->tops && !s->t_est) scr_net_sock_transport_pump(s);
3110
+ else scr_net_sock_read(s);
3111
+ }
3112
+ }
3113
+ if (scr_exc_pending()) return;
3114
+ }
3115
+ if (!scr_net_flags_pending()) return;
3116
+ if (scr_loop_has_ready()) return; /* microtasks interleave first */
3117
+ }
3118
+ }
3119
+
3120
+ /* Exit-time registry cleanup (the events-unit precedent): handles a
3121
+ * program legitimately leaves live at exit — a server running until
3122
+ * SIGTERM, sockets the peer never closed — release their listeners and
3123
+ * registry references so the RC audit sees a clean heap. */
3124
+ static void scr_net_cleanup_atexit(void) {
3125
+ while (scr_net_socks) {
3126
+ ScrNetSocket *s = scr_net_socks;
3127
+ scr_net_ls_drop(&s->data_ls);
3128
+ scr_net_ls_drop(&s->end_ls);
3129
+ scr_net_ls_drop(&s->close_ls);
3130
+ scr_net_ls_drop(&s->err_ls);
3131
+ scr_net_ls_drop(&s->conn_ls);
3132
+ scr_net_ls_drop(&s->timeout_ls);
3133
+ scr_net_ls_drop(&s->readable_ls);
3134
+ /* Tear down the protocol layer's parser NOW: an in-flight http
3135
+ * exchange (a handler that threw before res.end()) holds req/res,
3136
+ * and the res holds this socket back — a cycle the lean untraced
3137
+ * handles cannot collect, visible only to the RC audit. No reads
3138
+ * follow at exit, so the parser hooks unhook first and the ctx
3139
+ * frees (scr_http_conn_free drops the in-flight pair; its close
3140
+ * emits are discarded at exit — the http unit's exiting flag). */
3141
+ if (s->native_ctx_free) {
3142
+ void (*ctx_free)(void *) = s->native_ctx_free;
3143
+ void *ctx = s->native_ctx;
3144
+ s->native_ctx_free = NULL;
3145
+ s->native_ctx = NULL;
3146
+ s->native_data = NULL;
3147
+ s->native_eof = NULL;
3148
+ s->native_closed = NULL;
3149
+ s->native_timeout = NULL;
3150
+ s->native_http_timeout = NULL;
3151
+ s->native_established = NULL;
3152
+ s->native_err = NULL;
3153
+ ctx_free(ctx);
3154
+ }
3155
+ if (s->pipe_dst) {
3156
+ scr_net_sock_release(s->pipe_dst);
3157
+ s->pipe_dst = NULL;
3158
+ }
3159
+ if (s->conn_pending) {
3160
+ scr_net_server_release(s->conn_pending);
3161
+ s->conn_pending = NULL;
3162
+ }
3163
+ if (s->server) {
3164
+ s->server->nconns--;
3165
+ scr_net_server_release(s->server);
3166
+ s->server = NULL;
3167
+ }
3168
+ scr_net_sock_unregister(s);
3169
+ }
3170
+ while (scr_net_servers) {
3171
+ ScrNetServer *s = scr_net_servers;
3172
+ scr_net_ls_drop(&s->conn_ls);
3173
+ scr_net_ls_drop(&s->err_ls);
3174
+ scr_net_ls_drop(&s->close_ls);
3175
+ scr_net_ls_drop(&s->listening_cbs);
3176
+ scr_closure_release(s->close_override);
3177
+ s->close_override = NULL;
3178
+ scr_net_server_unregister(s);
3179
+ }
3180
+ }
3181
+
3182
+ void scr_net_install(void) {
3183
+ static bool installed = false;
3184
+ if (installed) return;
3185
+ installed = true;
3186
+ atexit(scr_net_cleanup_atexit);
3187
+ scr_loop_set_net(&scr_net_pending, &scr_net_dispatch, &scr_net_pollfd);
3188
+ }
3189
+
3190
+ /* ── checked-dynamic handle dispatch (SCR_DYNH_NET_SOCKET ops) ─────────
3191
+ * The socket half of the HANDLE crossing (scr_http.c hosts the req/res
3192
+ * half and the shared design comment): members dispatch onto the same
3193
+ * entry points the static lowerings use; real-but-unmodeled members meet
3194
+ * the loud "not supported yet" ladder; unknown names answer Node's own
3195
+ * shapes ("<what> is not a function" / the undefined singleton). */
3196
+
3197
+ static void scr_net_dynh_unsupported(const char *member, const char *why) {
3198
+ char msg[160];
3199
+ int n = snprintf(msg, sizeof msg, "'Socket.prototype.%s' on a dynamic value is not supported yet%s%s",
3200
+ member, why ? " — " : "", why ? why : "");
3201
+ scr_throw_error_msg(SCR_ERR_ERROR, msg, (size_t)n);
3202
+ }
3203
+
3204
+ /* The TLS-member hooks (scr_tls.c registers them when linked): TLSSocket
3205
+ * property reads, event names, and method names layer over the plain
3206
+ * socket dispatch without this unit naming that one's symbols. */
3207
+ static const ScrNetDynhTlsHooks *scr_net_dynh_tls = NULL;
3208
+ void scr_net_set_dynh_tls(const ScrNetDynhTlsHooks *hooks) { scr_net_dynh_tls = hooks; }
3209
+
3210
+ static bool scr_net_dynh_name_is(const ScrDyn *name, const char *lit) {
3211
+ size_t n = strlen(lit);
3212
+ return name->kind == SCR_DYN_STR && name->v.str->len == n &&
3213
+ memcmp(name->v.str->data, lit, n) == 0;
3214
+ }
3215
+
3216
+ static ScrDyn *scr_net_dynh_sock_invoke(void *h, ScrDyn *self, const char *method,
3217
+ ScrDyn *const *args, size_t argc, const char *what) {
3218
+ ScrNetSocket *s = (ScrNetSocket *)h;
3219
+ bool reg = false, once = false;
3220
+ if (strcmp(method, "on") == 0 || strcmp(method, "addListener") == 0) reg = true;
3221
+ else if (strcmp(method, "once") == 0) { reg = true; once = true; }
3222
+ if (reg) {
3223
+ const ScrDyn *name = argc > 0 ? args[0] : scr_dyn_undefined();
3224
+ const ScrDyn *cb = argc > 1 ? args[1] : scr_dyn_undefined();
3225
+ scr_dyn_check_listener(cb, "listener");
3226
+ if (scr_exc_pending()) return NULL;
3227
+ if (scr_net_dynh_name_is(name, "data")) {
3228
+ scr_net_sock_on_data(s, scr_dyn_listener_closure_data(cb), (ScrNetDataFn)&scr_dyn_listener_fire_data, once);
3229
+ } else if (scr_net_dynh_name_is(name, "end")) {
3230
+ scr_net_sock_on_end(s, scr_dyn_listener_closure0(cb), once);
3231
+ } else if (scr_net_dynh_name_is(name, "close")) {
3232
+ scr_net_sock_on_close(s, scr_dyn_listener_closure0(cb), once);
3233
+ } else if (scr_net_dynh_name_is(name, "error")) {
3234
+ scr_net_sock_on_error(s, scr_dyn_listener_closure_err(cb), (ScrChildErrFn)&scr_dyn_listener_fire_err, once);
3235
+ } else if (scr_net_dynh_name_is(name, "connect")) {
3236
+ scr_net_sock_on_connect(s, scr_dyn_listener_closure0(cb), once);
3237
+ } else if (scr_net_dynh_name_is(name, "timeout")) {
3238
+ scr_net_sock_on_timeout(s, scr_dyn_listener_closure0(cb), once);
3239
+ } else if (scr_net_dynh_name_is(name, "readable")) {
3240
+ scr_net_sock_on_readable(s, scr_dyn_listener_closure0(cb), once);
3241
+ } else if (scr_net_dynh_name_is(name, "finish")) {
3242
+ /* fires once when the FIN goes out — once either way */
3243
+ scr_net_sock_on_finish(s, scr_dyn_listener_closure0(cb));
3244
+ } else if (scr_net_dynh_name_is(name, "drain")) {
3245
+ /* This surface never backpressures (write answers true) — an
3246
+ * accepted, never-fired registration is the consistent answer. */
3247
+ } else if (scr_net_dynh_tls != NULL && name->kind == SCR_DYN_STR &&
3248
+ scr_net_dynh_tls->on(s, name->v.str->data, cb, once)) {
3249
+ /* a TLS event name ('secureConnect'), handled by the TLS unit */
3250
+ } else {
3251
+ ScrJsonBuf b;
3252
+ scr_jb_init(&b);
3253
+ scr_jb_puts(&b, "listening for '");
3254
+ if (name->kind == SCR_DYN_STR) {
3255
+ for (size_t i = 0; i < name->v.str->len; i++) scr_jb_putc(&b, name->v.str->data[i]);
3256
+ }
3257
+ scr_jb_puts(&b, "' on a dynamic Socket is not supported yet");
3258
+ scr_throw_error(SCR_ERR_ERROR, scr_jb_finish(&b));
3259
+ return NULL;
3260
+ }
3261
+ return scr_dyn_retain(self);
3262
+ }
3263
+ if (strcmp(method, "write") == 0) {
3264
+ const ScrDyn *chunk = argc > 0 ? args[0] : scr_dyn_undefined();
3265
+ if (chunk->kind != SCR_DYN_STR && chunk->kind != SCR_DYN_BYTES) {
3266
+ scr_dyn_arg_type_fail("chunk", "of type string or an instance of Buffer or Uint8Array", chunk);
3267
+ return NULL;
3268
+ }
3269
+ if (chunk->kind == SCR_DYN_STR) scr_net_sock_write_str(s, chunk->v.str);
3270
+ else scr_net_sock_write_bytes(s, chunk->v.bytes);
3271
+ if (argc > 1 && args[1]->kind == SCR_DYN_FUNC) {
3272
+ /* write(chunk, cb): fires when the buffer drains (sweep-deferred) */
3273
+ scr_net_sock_on_write_flush(s, scr_dyn_listener_closure0(args[1]));
3274
+ }
3275
+ return scr_dyn_new_bool(true); /* backpressure is not modeled (SEMANTICS.md) */
3276
+ }
3277
+ if (strcmp(method, "end") == 0) {
3278
+ const ScrDyn *chunk = argc > 0 ? args[0] : scr_dyn_undefined();
3279
+ const ScrDyn *cb = NULL;
3280
+ if (chunk->kind == SCR_DYN_FUNC) { /* end(callback) */
3281
+ cb = chunk;
3282
+ chunk = scr_dyn_undefined();
3283
+ } else if (argc > 1 && args[1]->kind == SCR_DYN_FUNC) {
3284
+ cb = args[1]; /* end(chunk, callback) */
3285
+ }
3286
+ if (cb != NULL) scr_net_sock_on_finish(s, scr_dyn_listener_closure0(cb));
3287
+ if (chunk->kind == SCR_DYN_STR) scr_net_sock_end_str(s, chunk->v.str);
3288
+ else if (chunk->kind == SCR_DYN_BYTES) scr_net_sock_end_bytes(s, chunk->v.bytes);
3289
+ else if (chunk->kind == SCR_DYN_UNDEF || argc == 0) scr_net_sock_end(s);
3290
+ else {
3291
+ scr_dyn_arg_type_fail("chunk", "of type string or an instance of Buffer or Uint8Array", chunk);
3292
+ return NULL;
3293
+ }
3294
+ return scr_dyn_retain(self);
3295
+ }
3296
+ if (strcmp(method, "pause") == 0) {
3297
+ scr_net_sock_release(scr_net_sock_pause(s)); /* the chaining +1; self answers */
3298
+ return scr_dyn_retain(self);
3299
+ }
3300
+ if (strcmp(method, "resume") == 0) {
3301
+ scr_net_sock_release(scr_net_sock_resume(s));
3302
+ return scr_dyn_retain(self);
3303
+ }
3304
+ if (strcmp(method, "setNoDelay") == 0) {
3305
+ /* setNoDelay([enable]) — missing/undefined means true, Node */
3306
+ bool enable = argc == 0 || args[0]->kind == SCR_DYN_UNDEF || scr_dyn_truthy(args[0]);
3307
+ scr_net_sock_release(scr_net_sock_set_nodelay(s, enable));
3308
+ return scr_dyn_retain(self);
3309
+ }
3310
+ if (strcmp(method, "destroySoon") == 0) {
3311
+ scr_net_sock_destroy_soon(s);
3312
+ return scr_dyn_retain(scr_dyn_undefined());
3313
+ }
3314
+ if (strcmp(method, "destroy") == 0) {
3315
+ if (argc > 0 && args[0]->kind != SCR_DYN_UNDEF) {
3316
+ scr_net_dynh_unsupported("destroy", "destroy(error) carries a payload this surface does not model");
3317
+ return NULL;
3318
+ }
3319
+ scr_net_sock_destroy(s);
3320
+ return scr_dyn_retain(self);
3321
+ }
3322
+ if (strcmp(method, "setTimeout") == 0) {
3323
+ const ScrDyn *ms = argc > 0 ? args[0] : scr_dyn_undefined();
3324
+ if (ms->kind != SCR_DYN_NUM) {
3325
+ scr_dyn_arg_type_fail("msecs", "of type number", ms);
3326
+ return NULL;
3327
+ }
3328
+ scr_net_sock_set_timeout(s, ms->v.num);
3329
+ if (argc > 1 && args[1]->kind == SCR_DYN_FUNC) {
3330
+ scr_net_sock_on_timeout(s, scr_dyn_listener_closure0(args[1]), true);
3331
+ } else if (argc > 1 && args[1]->kind != SCR_DYN_UNDEF) {
3332
+ scr_dyn_check_listener(args[1], "callback");
3333
+ return NULL;
3334
+ }
3335
+ return scr_dyn_retain(self);
3336
+ }
3337
+ if (strcmp(method, "setEncoding") == 0) {
3338
+ const ScrDyn *enc = argc > 0 ? args[0] : scr_dyn_undefined();
3339
+ if (enc->kind != SCR_DYN_STR) {
3340
+ scr_dyn_arg_type_fail("encoding", "of type string", enc);
3341
+ return NULL;
3342
+ }
3343
+ scr_net_sock_set_encoding(s, enc->v.str);
3344
+ if (scr_exc_pending()) return NULL;
3345
+ return scr_dyn_retain(self);
3346
+ }
3347
+ if (strcmp(method, "pipe") == 0) {
3348
+ const ScrDyn *dst = argc > 0 ? args[0] : scr_dyn_undefined();
3349
+ if (dst->kind == SCR_DYN_HANDLE && dst->v.handle.tag == SCR_DYNH_NET_SOCKET) {
3350
+ scr_net_sock_pipe(s, (ScrNetSocket *)dst->v.handle.ptr);
3351
+ return scr_dyn_retain((ScrDyn *)dst);
3352
+ }
3353
+ if (dst->kind == SCR_DYN_HANDLE) {
3354
+ /* Cross-unit destinations (a ServerResponse) accept the source
3355
+ * through their pipe_from hook — this unit cannot name theirs. */
3356
+ const ScrDynHandleOps *dops = scr_dyn_handle_ops_of(dst);
3357
+ if (dops->pipe_from && dops->pipe_from(dst->v.handle.ptr, self)) {
3358
+ return scr_dyn_retain((ScrDyn *)dst);
3359
+ }
3360
+ }
3361
+ scr_net_dynh_unsupported("pipe", "only Socket and ServerResponse destinations are modeled");
3362
+ return NULL;
3363
+ }
3364
+ if (strcmp(method, "toString") == 0) {
3365
+ ScrStr *str = scr_str_new("[object Object]", 15);
3366
+ ScrDyn *d = scr_dyn_new_str(str);
3367
+ scr_str_release(str);
3368
+ return d;
3369
+ }
3370
+ if (scr_net_dynh_tls != NULL) {
3371
+ ScrDyn *out = NULL;
3372
+ if (scr_net_dynh_tls->invoke(s, method, args, argc, &out)) return out;
3373
+ }
3374
+ {
3375
+ static const char *const known[] = { "connect", "setKeepAlive",
3376
+ "address", "ref", "unref", "cork", "uncork", "read", "unpipe",
3377
+ "off", "removeListener", "removeAllListeners", "emit", "prependListener",
3378
+ "prependOnceListener", "listenerCount", "listeners", "resetAndDestroy", NULL };
3379
+ for (size_t i = 0; known[i]; i++) {
3380
+ if (strcmp(method, known[i]) == 0) {
3381
+ scr_net_dynh_unsupported(method, NULL);
3382
+ return NULL;
3383
+ }
3384
+ }
3385
+ }
3386
+ {
3387
+ char msg[160];
3388
+ int n = snprintf(msg, sizeof msg, "%s is not a function", what);
3389
+ scr_throw_error_msg(SCR_ERR_TYPE, msg, (size_t)n);
3390
+ }
3391
+ return NULL;
3392
+ }
3393
+
3394
+ static ScrDyn *scr_net_dynh_sock_get(void *h, const char *key, size_t key_len) {
3395
+ ScrNetSocket *s = (ScrNetSocket *)h;
3396
+ (void)key_len;
3397
+ if (strcmp(key, "destroyed") == 0) return scr_dyn_new_bool(scr_net_sock_destroyed(s));
3398
+ if (strcmp(key, "writable") == 0) return scr_dyn_new_bool(scr_net_sock_writable(s));
3399
+ if (strcmp(key, "remoteAddress") == 0) {
3400
+ ScrStr *a = scr_net_sock_remote_address(s);
3401
+ if (!a) return NULL; /* the undefined arm, the static lane's split */
3402
+ ScrDyn *d = scr_dyn_new_str(a);
3403
+ scr_str_release(a);
3404
+ return d;
3405
+ }
3406
+ if (strcmp(key, "encrypted") == 0) {
3407
+ /* Node types `encrypted: true` on TLSSocket only; plain sockets read
3408
+ * undefined — the static lane's false→undefined mapping. */
3409
+ return scr_net_sock_encrypted(s) ? scr_dyn_new_bool(true) : NULL;
3410
+ }
3411
+ if (strcmp(key, "bytesWritten") == 0) return scr_dyn_new_num(scr_net_sock_bytes_written(s));
3412
+ if (strcmp(key, "readable") == 0) return scr_dyn_new_bool(scr_net_sock_readable(s));
3413
+ if (strcmp(key, "writableHighWaterMark") == 0 || strcmp(key, "readableHighWaterMark") == 0) {
3414
+ /* Node's default stream highWaterMark — a constant here (backpressure
3415
+ * is not modeled; SEMANTICS.md) */
3416
+ return scr_dyn_new_num(16384);
3417
+ }
3418
+ if (scr_net_dynh_tls != NULL) {
3419
+ ScrDyn *out = NULL;
3420
+ if (scr_net_dynh_tls->get(s, key, &out)) return out;
3421
+ }
3422
+ {
3423
+ static const char *const known[] = { "remotePort", "remoteFamily", "localAddress",
3424
+ "localPort", "localFamily", "bytesRead", "connecting", "pending",
3425
+ "readyState", "bufferSize", "timeout", "closed", "errored", NULL };
3426
+ for (size_t i = 0; known[i]; i++) {
3427
+ if (strcmp(key, known[i]) == 0) {
3428
+ scr_net_dynh_unsupported(key, NULL);
3429
+ return NULL;
3430
+ }
3431
+ }
3432
+ }
3433
+ return NULL;
3434
+ }
3435
+
3436
+ static bool scr_net_dynh_sock_set(void *h, const char *key, size_t key_len, const ScrDyn *value) {
3437
+ (void)h; (void)key; (void)key_len; (void)value;
3438
+ return false;
3439
+ }
3440
+
3441
+ static const ScrDynHandleOps scr_net_dynh_sock_ops = {
3442
+ "Socket",
3443
+ &scr_net_sock_retain_v,
3444
+ &scr_net_sock_release_v,
3445
+ &scr_net_dynh_sock_invoke,
3446
+ &scr_net_dynh_sock_get,
3447
+ &scr_net_dynh_sock_set,
3448
+ NULL,
3449
+ };
3450
+
3451
+ /* ── checked-dynamic handle dispatch (SCR_DYNH_NET_SERVER ops) ─────────
3452
+ * The server half: `let server; server = createServer(...)` puts the
3453
+ * handle into a dyn binding, and every listener body's `this` answers
3454
+ * the emitting server (the ambient receiver) — both dispatch here.
3455
+ * Members ride the same entry points the static lowerings use. HTTP
3456
+ * server events ('request') route through the hook scr_http.c registers
3457
+ * at its dyn install — this unit cannot name http entry points without
3458
+ * breaking the link gate. */
3459
+
3460
+ static bool (*scr_net_dynh_http_on)(ScrNetServer *s, const char *event, const ScrDyn *cb,
3461
+ bool once);
3462
+ void scr_net_set_dynh_http_on(bool (*fn)(ScrNetServer *, const char *, const ScrDyn *, bool)) {
3463
+ scr_net_dynh_http_on = fn;
3464
+ }
3465
+
3466
+ static void scr_net_dynh_srv_unsupported(const char *member, const char *why) {
3467
+ char msg[160];
3468
+ int n = snprintf(msg, sizeof msg, "'Server.prototype.%s' on a dynamic value is not supported yet%s%s",
3469
+ member, why ? " — " : "", why ? why : "");
3470
+ scr_throw_error_msg(SCR_ERR_ERROR, msg, (size_t)n);
3471
+ }
3472
+
3473
+ /* The 'connection' fire for a dyn listener: box the socket by reference
3474
+ * and call through the checked-dynamic machinery (the ScrNetConnFn ABI —
3475
+ * sock arrives +1 and the adapter owns it, like the static adapters). */
3476
+ static void scr_net_dynh_fire_conn(ScrClosure *cb, ScrNetSocket *sock /* +1 */) {
3477
+ ScrDyn *fn = scr_dyn_listener_fn(cb);
3478
+ ScrDyn *dsock = scr_dyn_new_handle(sock, SCR_DYNH_NET_SOCKET);
3479
+ ScrDyn *args[1] = { dsock };
3480
+ ScrDyn *r = scr_dyn_call(fn, args, 1, "listener");
3481
+ scr_dyn_release(r);
3482
+ scr_dyn_release(dsock);
3483
+ scr_dyn_release(fn);
3484
+ scr_net_sock_release(sock);
3485
+ }
3486
+
3487
+ /* server.address() — Node's { address, family, port } object, null while
3488
+ * not listening (never bound, or already closed). */
3489
+ static ScrDyn *scr_net_dynh_srv_address(ScrNetServer *s) {
3490
+ if (!s->listening || s->fd < 0) return scr_dyn_new_null();
3491
+ ScrDyn *o = scr_dyn_new_obj();
3492
+ {
3493
+ ScrStr *a = s->bound_host ? scr_str_retain(s->bound_host)
3494
+ : scr_str_new(s->bound_v6 ? "::" : "0.0.0.0", s->bound_v6 ? 2 : 7);
3495
+ scr_dyn_obj_set(o, "address", 7, scr_dyn_new_str(a));
3496
+ scr_str_release(a);
3497
+ }
3498
+ {
3499
+ const char *fam = s->bound_v6 ? "IPv6" : "IPv4";
3500
+ ScrStr *f = scr_str_new(fam, 4);
3501
+ scr_dyn_obj_set(o, "family", 6, scr_dyn_new_str(f));
3502
+ scr_str_release(f);
3503
+ }
3504
+ scr_dyn_obj_set(o, "port", 4, scr_dyn_new_num((double)s->port));
3505
+ return o;
3506
+ }
3507
+
3508
+ static ScrDyn *scr_net_dynh_srv_invoke(void *h, ScrDyn *self, const char *method,
3509
+ ScrDyn *const *args, size_t argc, const char *what) {
3510
+ ScrNetServer *s = (ScrNetServer *)h;
3511
+ bool reg = false, once = false;
3512
+ if (strcmp(method, "on") == 0 || strcmp(method, "addListener") == 0) reg = true;
3513
+ else if (strcmp(method, "once") == 0) { reg = true; once = true; }
3514
+ if (reg) {
3515
+ const ScrDyn *name = argc > 0 ? args[0] : scr_dyn_undefined();
3516
+ const ScrDyn *cb = argc > 1 ? args[1] : scr_dyn_undefined();
3517
+ scr_dyn_check_listener(cb, "listener");
3518
+ if (scr_exc_pending()) return NULL;
3519
+ if (scr_net_dynh_name_is(name, "listening")) {
3520
+ scr_net_server_on_listening(s, scr_dyn_listener_closure0(cb), once);
3521
+ } else if (scr_net_dynh_name_is(name, "close")) {
3522
+ scr_net_server_on_close(s, scr_dyn_listener_closure0(cb), once);
3523
+ } else if (scr_net_dynh_name_is(name, "error")) {
3524
+ scr_net_server_on_error(s, scr_dyn_listener_closure_err(cb),
3525
+ (ScrChildErrFn)&scr_dyn_listener_fire_err, once);
3526
+ } else if (scr_net_dynh_name_is(name, "connection")) {
3527
+ scr_net_server_on_connection(s, scr_dyn_listener_closure_fn(cb, (void *)&scr_net_dynh_fire_conn),
3528
+ (ScrNetConnFn)&scr_net_dynh_fire_conn, once);
3529
+ } else if (scr_net_dynh_name_is(name, "secureConnection") && s->defer_conn) {
3530
+ /* a TLS server's 'connection' list IS post-handshake (deferred) —
3531
+ * exactly Node's secureConnection timing; on a plain server the
3532
+ * name falls through to the fence below */
3533
+ scr_net_server_on_connection(s, scr_dyn_listener_closure_fn(cb, (void *)&scr_net_dynh_fire_conn),
3534
+ (ScrNetConnFn)&scr_net_dynh_fire_conn, once);
3535
+ } else if (name->kind == SCR_DYN_STR && scr_net_dynh_http_on &&
3536
+ scr_net_dynh_http_on(s, name->v.str->data, cb, once)) {
3537
+ /* the http layer accepted the event ('request') */
3538
+ } else {
3539
+ ScrJsonBuf b;
3540
+ scr_jb_init(&b);
3541
+ scr_jb_puts(&b, "listening for '");
3542
+ if (name->kind == SCR_DYN_STR) {
3543
+ for (size_t i = 0; i < name->v.str->len; i++) scr_jb_putc(&b, name->v.str->data[i]);
3544
+ }
3545
+ scr_jb_puts(&b, "' on a dynamic Server is not supported yet");
3546
+ scr_throw_error(SCR_ERR_ERROR, scr_jb_finish(&b));
3547
+ return NULL;
3548
+ }
3549
+ return scr_dyn_retain(self);
3550
+ }
3551
+ if (strcmp(method, "listen") == 0) {
3552
+ /* listen([port][, host][, cb]) — the static lowering's shapes over
3553
+ * dyn arguments; the options-object form fences loudly. */
3554
+ double port = 0;
3555
+ ScrStr *host = NULL;
3556
+ const ScrDyn *cb = NULL;
3557
+ size_t i = 0;
3558
+ if (i < argc && args[i]->kind == SCR_DYN_NUM) { port = args[i]->v.num; i++; }
3559
+ else if (i < argc && args[i]->kind == SCR_DYN_STR && args[i]->v.str->len > 0 &&
3560
+ args[i]->v.str->data[0] >= '0' && args[i]->v.str->data[0] <= '9') {
3561
+ /* Node coerces a numeric port string */
3562
+ port = strtod(args[i]->v.str->data, NULL);
3563
+ i++;
3564
+ } else if (i < argc && args[i]->kind == SCR_DYN_OBJ) {
3565
+ scr_net_dynh_srv_unsupported("listen", "the options-object form on a dynamic value is not modeled (use listen(port[, host][, cb]))");
3566
+ return NULL;
3567
+ }
3568
+ if (i < argc && args[i]->kind == SCR_DYN_STR) { host = args[i]->v.str; i++; }
3569
+ if (i < argc && args[i]->kind == SCR_DYN_FUNC) { cb = args[i]; i++; }
3570
+ if (i < argc && args[i]->kind != SCR_DYN_UNDEF && args[i]->kind != SCR_DYN_NULL) {
3571
+ scr_net_dynh_srv_unsupported("listen", "unrecognized arguments (the modeled shape is listen(port[, host][, cb]))");
3572
+ return NULL;
3573
+ }
3574
+ ScrClosure *clo = cb ? scr_dyn_listener_closure0(cb) : NULL;
3575
+ if (host) scr_net_listen_opts(s, port, host, false, clo);
3576
+ else scr_net_listen(s, port, clo);
3577
+ return scr_dyn_retain(self); /* Node's `return this` chaining */
3578
+ }
3579
+ if (strcmp(method, "close") == 0) {
3580
+ const ScrDyn *cb = argc > 0 ? args[0] : scr_dyn_undefined();
3581
+ if (cb->kind == SCR_DYN_FUNC) {
3582
+ scr_net_server_close(s, scr_dyn_listener_closure0(cb));
3583
+ } else if (cb->kind == SCR_DYN_UNDEF || argc == 0) {
3584
+ scr_net_server_close(s, NULL);
3585
+ } else {
3586
+ scr_dyn_check_listener(cb, "callback");
3587
+ return NULL;
3588
+ }
3589
+ return scr_dyn_retain(self);
3590
+ }
3591
+ if (strcmp(method, "address") == 0) {
3592
+ return scr_net_dynh_srv_address(s);
3593
+ }
3594
+ if (strcmp(method, "emit") == 0 && argc > 0 && scr_net_dynh_name_is(args[0], "connection")) {
3595
+ const ScrDyn *sockd = argc > 1 ? args[1] : scr_dyn_undefined();
3596
+ if (sockd->kind == SCR_DYN_HANDLE && sockd->v.handle.tag == SCR_DYNH_NET_SOCKET) {
3597
+ scr_net_server_emit_connection(s, (ScrNetSocket *)sockd->v.handle.ptr);
3598
+ return scr_dyn_new_bool(true);
3599
+ }
3600
+ scr_dyn_arg_type_fail("socket", "an instance of Socket", sockd);
3601
+ return NULL;
3602
+ }
3603
+ if (strcmp(method, "toString") == 0) {
3604
+ ScrStr *str = scr_str_new("[object Object]", 15);
3605
+ ScrDyn *d = scr_dyn_new_str(str);
3606
+ scr_str_release(str);
3607
+ return d;
3608
+ }
3609
+ {
3610
+ static const char *const known[] = { "ref", "unref", "setTimeout", "getConnections",
3611
+ "off", "removeListener", "removeAllListeners", "emit", "prependListener",
3612
+ "prependOnceListener", "listenerCount", "listeners", "closeAllConnections",
3613
+ "closeIdleConnections", NULL };
3614
+ for (size_t i = 0; known[i]; i++) {
3615
+ if (strcmp(method, known[i]) == 0) {
3616
+ scr_net_dynh_srv_unsupported(method, NULL);
3617
+ return NULL;
3618
+ }
3619
+ }
3620
+ }
3621
+ {
3622
+ char msg[160];
3623
+ int n = snprintf(msg, sizeof msg, "%s is not a function", what);
3624
+ scr_throw_error_msg(SCR_ERR_TYPE, msg, (size_t)n);
3625
+ }
3626
+ return NULL;
3627
+ }
3628
+
3629
+ static int scr_net_dynh_srv_timeout_field(const char *key) {
3630
+ if (strcmp(key, "timeout") == 0) return 0;
3631
+ if (strcmp(key, "keepAliveTimeout") == 0) return 1;
3632
+ if (strcmp(key, "headersTimeout") == 0) return 2;
3633
+ if (strcmp(key, "requestTimeout") == 0) return 3;
3634
+ if (strcmp(key, "keepAliveTimeoutBuffer") == 0) return 4;
3635
+ return -1;
3636
+ }
3637
+
3638
+ static ScrDyn *scr_net_dynh_srv_get(void *h, const char *key, size_t key_len) {
3639
+ ScrNetServer *s = (ScrNetServer *)h;
3640
+ (void)key_len;
3641
+ if (strcmp(key, "listening") == 0) return scr_dyn_new_bool(s->listening);
3642
+ int timeout_field = scr_net_dynh_srv_timeout_field(key);
3643
+ if (timeout_field >= 0 && s->http_timeout_surface) {
3644
+ if (s->http_timeout_dyn[timeout_field] != NULL) {
3645
+ return scr_dyn_retain(s->http_timeout_dyn[timeout_field]);
3646
+ }
3647
+ return scr_dyn_new_num(scr_net_server_timeout_get(s, (double)timeout_field));
3648
+ }
3649
+ {
3650
+ static const char *const known[] = { "maxConnections", "connections", "maxHeadersCount", NULL };
3651
+ for (size_t i = 0; known[i]; i++) {
3652
+ if (strcmp(key, known[i]) == 0) {
3653
+ scr_net_dynh_srv_unsupported(key, NULL);
3654
+ return NULL;
3655
+ }
3656
+ }
3657
+ }
3658
+ return NULL;
3659
+ }
3660
+
3661
+ static bool scr_net_dynh_srv_set(void *h, const char *key, size_t key_len, const ScrDyn *value) {
3662
+ ScrNetServer *s = (ScrNetServer *)h;
3663
+ (void)key_len;
3664
+ int timeout_field = scr_net_dynh_srv_timeout_field(key);
3665
+ if (timeout_field >= 0 && s->http_timeout_surface) {
3666
+ if (value->kind == SCR_DYN_NUM) {
3667
+ scr_net_server_timeout_set(s, (double)timeout_field, value->v.num);
3668
+ } else {
3669
+ scr_dyn_release(s->http_timeout_dyn[timeout_field]);
3670
+ s->http_timeout_dyn[timeout_field] = scr_dyn_retain((ScrDyn *)value);
3671
+ }
3672
+ return true;
3673
+ }
3674
+ return false;
3675
+ }
3676
+
3677
+ static const ScrDynHandleOps scr_net_dynh_srv_ops = {
3678
+ "Server",
3679
+ &scr_net_server_retain_v,
3680
+ &scr_net_server_release_v,
3681
+ &scr_net_dynh_srv_invoke,
3682
+ &scr_net_dynh_srv_get,
3683
+ &scr_net_dynh_srv_set,
3684
+ NULL,
3685
+ };
3686
+
3687
+ void scr_net_dyn_install(void) {
3688
+ scr_dyn_handle_install(SCR_DYNH_NET_SOCKET, &scr_net_dynh_sock_ops);
3689
+ scr_dyn_handle_install(SCR_DYNH_NET_SERVER, &scr_net_dynh_srv_ops);
3690
+ }
3691
+
3692
+ /* Checked-dynamic chunks into a TYPED socket (an untyped JS payload
3693
+ * flowing into socket.write/end — the static lowering's dyn-data arm):
3694
+ * STR/BYTES dispatch onto the typed entries; undefined/null end()s plain
3695
+ * (Node accepts them); anything else throws Node's ERR_INVALID_ARG_TYPE
3696
+ * chunk TypeError. Both borrowed. */
3697
+ void scr_net_sock_write_dynv(ScrNetSocket *s, const ScrDyn *d) {
3698
+ if (d->kind == SCR_DYN_STR) scr_net_sock_write_str(s, d->v.str);
3699
+ else if (d->kind == SCR_DYN_BYTES) scr_net_sock_write_bytes(s, d->v.bytes);
3700
+ else scr_dyn_arg_type_fail("chunk", "of type string or an instance of Buffer or Uint8Array", d);
3701
+ }
3702
+
3703
+ void scr_net_sock_end_dynv(ScrNetSocket *s, const ScrDyn *d) {
3704
+ if (d->kind == SCR_DYN_STR) scr_net_sock_end_str(s, d->v.str);
3705
+ else if (d->kind == SCR_DYN_BYTES) scr_net_sock_end_bytes(s, d->v.bytes);
3706
+ else if (d->kind == SCR_DYN_UNDEF || d->kind == SCR_DYN_NULL) scr_net_sock_end(s);
3707
+ else scr_dyn_arg_type_fail("chunk", "of type string or an instance of Buffer or Uint8Array", d);
3708
+ }