goscript 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. package/cmd/goscript/cmd-test.go +104 -11
  2. package/cmd/goscript/cmd-test_test.go +1 -1
  3. package/cmd/goscript/cmd_compile.go +9 -0
  4. package/compiler/compile-request.go +31 -0
  5. package/compiler/compiler.go +1 -1
  6. package/compiler/compliance_test.go +0 -2
  7. package/compiler/config.go +2 -0
  8. package/compiler/gotest/package-result.go +2 -0
  9. package/compiler/gotest/request.go +85 -20
  10. package/compiler/gotest/runner.go +733 -96
  11. package/compiler/gotest/runner_test.go +647 -3
  12. package/compiler/lowered-program.go +9 -2
  13. package/compiler/lowering.go +2001 -345
  14. package/compiler/override-facts.go +77 -27
  15. package/compiler/override-registry.go +5 -4
  16. package/compiler/override-registry_test.go +135 -0
  17. package/compiler/package-graph_test.go +62 -7
  18. package/compiler/package-test-graph-variant.go +40 -16
  19. package/compiler/package-test-graph.go +0 -5
  20. package/compiler/package-test-graph_test.go +61 -3
  21. package/compiler/runtime-contract.go +40 -0
  22. package/compiler/semantic-model-types.go +16 -0
  23. package/compiler/semantic-model.go +336 -91
  24. package/compiler/semantic-model_test.go +50 -1
  25. package/compiler/service.go +9 -3
  26. package/compiler/skeleton_test.go +1921 -298
  27. package/compiler/tsworkspace/owner-process-unix_test.go +72 -0
  28. package/compiler/tsworkspace/owner.go +8 -0
  29. package/compiler/tsworkspace/tool-process-other.go +14 -0
  30. package/compiler/tsworkspace/tool-process-unix.go +19 -0
  31. package/compiler/typescript-emitter.go +122 -9
  32. package/dist/gs/builtin/builtin.d.ts +20 -1
  33. package/dist/gs/builtin/builtin.js +246 -26
  34. package/dist/gs/builtin/builtin.js.map +1 -1
  35. package/dist/gs/builtin/channel.d.ts +24 -10
  36. package/dist/gs/builtin/channel.js +107 -25
  37. package/dist/gs/builtin/channel.js.map +1 -1
  38. package/dist/gs/builtin/defer.d.ts +1 -0
  39. package/dist/gs/builtin/defer.js +12 -2
  40. package/dist/gs/builtin/defer.js.map +1 -1
  41. package/dist/gs/builtin/hostio.d.ts +9 -0
  42. package/dist/gs/builtin/hostio.js +25 -0
  43. package/dist/gs/builtin/hostio.js.map +1 -1
  44. package/dist/gs/builtin/map.js +40 -6
  45. package/dist/gs/builtin/map.js.map +1 -1
  46. package/dist/gs/builtin/print.js.map +1 -1
  47. package/dist/gs/builtin/slice.d.ts +43 -9
  48. package/dist/gs/builtin/slice.js +437 -234
  49. package/dist/gs/builtin/slice.js.map +1 -1
  50. package/dist/gs/builtin/type.d.ts +2 -0
  51. package/dist/gs/builtin/type.js +47 -7
  52. package/dist/gs/builtin/type.js.map +1 -1
  53. package/dist/gs/builtin/varRef.d.ts +2 -0
  54. package/dist/gs/builtin/varRef.js.map +1 -1
  55. package/dist/gs/bytes/buffer.gs.js +28 -28
  56. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  57. package/dist/gs/bytes/iter.gs.js +13 -13
  58. package/dist/gs/bytes/iter.gs.js.map +1 -1
  59. package/dist/gs/compress/zlib/index.d.ts +26 -0
  60. package/dist/gs/compress/zlib/index.js +168 -0
  61. package/dist/gs/compress/zlib/index.js.map +1 -0
  62. package/dist/gs/context/context.d.ts +1 -1
  63. package/dist/gs/context/context.js +8 -3
  64. package/dist/gs/context/context.js.map +1 -1
  65. package/dist/gs/crypto/ecdh/index.d.ts +52 -0
  66. package/dist/gs/crypto/ecdh/index.js +226 -0
  67. package/dist/gs/crypto/ecdh/index.js.map +1 -0
  68. package/dist/gs/crypto/ed25519/index.d.ts +34 -0
  69. package/dist/gs/crypto/ed25519/index.js +160 -0
  70. package/dist/gs/crypto/ed25519/index.js.map +1 -0
  71. package/dist/gs/crypto/internal/constanttime/index.d.ts +4 -0
  72. package/dist/gs/crypto/internal/constanttime/index.js +18 -0
  73. package/dist/gs/crypto/internal/constanttime/index.js.map +1 -0
  74. package/dist/gs/crypto/rand/index.d.ts +2 -0
  75. package/dist/gs/crypto/rand/index.js +85 -0
  76. package/dist/gs/crypto/rand/index.js.map +1 -1
  77. package/dist/gs/crypto/sha256/index.d.ts +8 -0
  78. package/dist/gs/crypto/sha256/index.js +118 -0
  79. package/dist/gs/crypto/sha256/index.js.map +1 -0
  80. package/dist/gs/crypto/sha512/index.d.ts +14 -0
  81. package/dist/gs/crypto/sha512/index.js +129 -0
  82. package/dist/gs/crypto/sha512/index.js.map +1 -0
  83. package/dist/gs/encoding/json/index.d.ts +3 -0
  84. package/dist/gs/encoding/json/index.js +15 -0
  85. package/dist/gs/encoding/json/index.js.map +1 -1
  86. package/dist/gs/errors/errors.js +29 -6
  87. package/dist/gs/errors/errors.js.map +1 -1
  88. package/dist/gs/fmt/fmt.js.map +1 -1
  89. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +7 -7
  90. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +52 -18
  91. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  92. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +56 -20
  93. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
  94. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +57 -3
  95. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +366 -1
  96. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -1
  97. package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +20 -0
  98. package/dist/gs/github.com/aperturerobotics/util/conc/index.js +134 -0
  99. package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +1 -0
  100. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
  101. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.d.ts +3 -0
  102. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js +50 -0
  103. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js.map +1 -0
  104. package/dist/gs/github.com/klauspost/compress/internal/le/index.js +3 -2
  105. package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -1
  106. package/dist/gs/github.com/mr-tron/base58/base58/index.d.ts +27 -0
  107. package/dist/gs/github.com/mr-tron/base58/base58/index.js +172 -0
  108. package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -0
  109. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.d.ts +21 -0
  110. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js +22 -0
  111. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js.map +1 -0
  112. package/dist/gs/go/token/index.js +11 -4
  113. package/dist/gs/go/token/index.js.map +1 -1
  114. package/dist/gs/hash/fnv/index.d.ts +57 -0
  115. package/dist/gs/hash/fnv/index.js +299 -0
  116. package/dist/gs/hash/fnv/index.js.map +1 -0
  117. package/dist/gs/hash/index.d.ts +17 -0
  118. package/dist/gs/hash/index.js +94 -0
  119. package/dist/gs/hash/index.js.map +1 -0
  120. package/dist/gs/io/fs/readlink.js +2 -6
  121. package/dist/gs/io/fs/readlink.js.map +1 -1
  122. package/dist/gs/io/fs/walk.js.map +1 -1
  123. package/dist/gs/io/io.js.map +1 -1
  124. package/dist/gs/iter/iter.d.ts +3 -2
  125. package/dist/gs/iter/iter.js.map +1 -1
  126. package/dist/gs/maps/iter.d.ts +5 -5
  127. package/dist/gs/maps/iter.js +48 -21
  128. package/dist/gs/maps/iter.js.map +1 -1
  129. package/dist/gs/maps/maps.d.ts +6 -6
  130. package/dist/gs/math/bits/index.js +14 -24
  131. package/dist/gs/math/bits/index.js.map +1 -1
  132. package/dist/gs/mime/index.js +3 -1
  133. package/dist/gs/mime/index.js.map +1 -1
  134. package/dist/gs/net/http/httptest/index.d.ts +20 -1
  135. package/dist/gs/net/http/httptest/index.js +83 -3
  136. package/dist/gs/net/http/httptest/index.js.map +1 -1
  137. package/dist/gs/net/http/index.d.ts +110 -6
  138. package/dist/gs/net/http/index.js +262 -16
  139. package/dist/gs/net/http/index.js.map +1 -1
  140. package/dist/gs/net/http/pprof/index.d.ts +8 -0
  141. package/dist/gs/net/http/pprof/index.js +59 -0
  142. package/dist/gs/net/http/pprof/index.js.map +1 -0
  143. package/dist/gs/os/error.gs.js +9 -7
  144. package/dist/gs/os/error.gs.js.map +1 -1
  145. package/dist/gs/os/types_js.gs.js +95 -15
  146. package/dist/gs/os/types_js.gs.js.map +1 -1
  147. package/dist/gs/path/filepath/match.js.map +1 -1
  148. package/dist/gs/path/filepath/path.d.ts +5 -3
  149. package/dist/gs/path/filepath/path.js +65 -10
  150. package/dist/gs/path/filepath/path.js.map +1 -1
  151. package/dist/gs/reflect/index.d.ts +3 -2
  152. package/dist/gs/reflect/index.js +2 -1
  153. package/dist/gs/reflect/index.js.map +1 -1
  154. package/dist/gs/reflect/iter.js +2 -2
  155. package/dist/gs/reflect/iter.js.map +1 -1
  156. package/dist/gs/reflect/map.js +26 -0
  157. package/dist/gs/reflect/map.js.map +1 -1
  158. package/dist/gs/reflect/type.d.ts +24 -5
  159. package/dist/gs/reflect/type.js +390 -38
  160. package/dist/gs/reflect/type.js.map +1 -1
  161. package/dist/gs/reflect/types.d.ts +1 -0
  162. package/dist/gs/reflect/types.js +3 -1
  163. package/dist/gs/reflect/types.js.map +1 -1
  164. package/dist/gs/reflect/value.d.ts +4 -1
  165. package/dist/gs/reflect/value.js +39 -1
  166. package/dist/gs/reflect/value.js.map +1 -1
  167. package/dist/gs/reflect/visiblefields.js +1 -1
  168. package/dist/gs/reflect/visiblefields.js.map +1 -1
  169. package/dist/gs/runtime/debug/index.d.ts +39 -0
  170. package/dist/gs/runtime/debug/index.js +58 -0
  171. package/dist/gs/runtime/debug/index.js.map +1 -1
  172. package/dist/gs/runtime/pprof/index.d.ts +20 -0
  173. package/dist/gs/runtime/pprof/index.js +85 -0
  174. package/dist/gs/runtime/pprof/index.js.map +1 -0
  175. package/dist/gs/runtime/trace/index.d.ts +19 -0
  176. package/dist/gs/runtime/trace/index.js +64 -0
  177. package/dist/gs/runtime/trace/index.js.map +1 -0
  178. package/dist/gs/slices/slices.d.ts +24 -9
  179. package/dist/gs/slices/slices.js +229 -24
  180. package/dist/gs/slices/slices.js.map +1 -1
  181. package/dist/gs/sort/slice.gs.d.ts +5 -3
  182. package/dist/gs/sort/slice.gs.js +55 -17
  183. package/dist/gs/sort/slice.gs.js.map +1 -1
  184. package/dist/gs/strings/builder.js +26 -17
  185. package/dist/gs/strings/builder.js.map +1 -1
  186. package/dist/gs/strings/iter.js +140 -75
  187. package/dist/gs/strings/iter.js.map +1 -1
  188. package/dist/gs/strings/replace.js +2 -2
  189. package/dist/gs/strings/replace.js.map +1 -1
  190. package/dist/gs/strings/strings.js +52 -6
  191. package/dist/gs/strings/strings.js.map +1 -1
  192. package/dist/gs/sync/sync.d.ts +6 -3
  193. package/dist/gs/sync/sync.js +39 -11
  194. package/dist/gs/sync/sync.js.map +1 -1
  195. package/dist/gs/syscall/errors.d.ts +116 -112
  196. package/dist/gs/syscall/errors.js +38 -1
  197. package/dist/gs/syscall/errors.js.map +1 -1
  198. package/dist/gs/syscall/fs.d.ts +2 -8
  199. package/dist/gs/syscall/fs.js.map +1 -1
  200. package/dist/gs/syscall/js/index.js +20 -12
  201. package/dist/gs/syscall/js/index.js.map +1 -1
  202. package/dist/gs/syscall/types.d.ts +4 -1
  203. package/dist/gs/syscall/types.js.map +1 -1
  204. package/dist/gs/testing/testing.d.ts +4 -3
  205. package/dist/gs/testing/testing.js +21 -4
  206. package/dist/gs/testing/testing.js.map +1 -1
  207. package/dist/gs/time/time.js +22 -0
  208. package/dist/gs/time/time.js.map +1 -1
  209. package/dist/gs/unicode/unicode.js.map +1 -1
  210. package/dist/gs/unique/index.js +7 -2
  211. package/dist/gs/unique/index.js.map +1 -1
  212. package/go.mod +8 -8
  213. package/go.sum +14 -23
  214. package/gs/builtin/builtin.ts +364 -37
  215. package/gs/builtin/channel.ts +161 -29
  216. package/gs/builtin/defer.ts +13 -2
  217. package/gs/builtin/hostio.test.ts +1 -0
  218. package/gs/builtin/hostio.ts +38 -0
  219. package/gs/builtin/map.ts +46 -6
  220. package/gs/builtin/print.ts +12 -3
  221. package/gs/builtin/runtime-contract.test.ts +257 -10
  222. package/gs/builtin/slice.test.ts +70 -0
  223. package/gs/builtin/slice.ts +566 -255
  224. package/gs/builtin/type.ts +53 -9
  225. package/gs/builtin/varRef.ts +2 -0
  226. package/gs/bytes/buffer.gs.ts +28 -28
  227. package/gs/bytes/iter.gs.ts +13 -14
  228. package/gs/compress/zlib/index.test.ts +28 -0
  229. package/gs/compress/zlib/index.ts +200 -0
  230. package/gs/compress/zlib/meta.json +3 -0
  231. package/gs/context/context.test.ts +31 -1
  232. package/gs/context/context.ts +9 -4
  233. package/gs/crypto/ecdh/index.test.ts +43 -0
  234. package/gs/crypto/ecdh/index.ts +274 -0
  235. package/gs/crypto/ed25519/index.test.ts +41 -0
  236. package/gs/crypto/ed25519/index.ts +238 -0
  237. package/gs/crypto/ed25519/meta.json +13 -0
  238. package/gs/crypto/internal/constanttime/index.test.ts +25 -0
  239. package/gs/crypto/internal/constanttime/index.ts +22 -0
  240. package/gs/crypto/rand/index.test.ts +89 -1
  241. package/gs/crypto/rand/index.ts +103 -1
  242. package/gs/crypto/rand/meta.json +4 -1
  243. package/gs/crypto/sha256/index.test.ts +78 -0
  244. package/gs/crypto/sha256/index.ts +150 -0
  245. package/gs/crypto/sha256/meta.json +9 -0
  246. package/gs/crypto/sha512/index.test.ts +31 -0
  247. package/gs/crypto/sha512/index.ts +161 -0
  248. package/gs/crypto/sha512/meta.json +11 -0
  249. package/gs/encoding/json/index.test.ts +25 -3
  250. package/gs/encoding/json/index.ts +21 -3
  251. package/gs/errors/errors.test.ts +4 -1
  252. package/gs/errors/errors.ts +32 -8
  253. package/gs/fmt/fmt.test.ts +3 -1
  254. package/gs/fmt/fmt.ts +1 -5
  255. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +62 -7
  256. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +78 -36
  257. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +32 -11
  258. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +122 -43
  259. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +31 -0
  260. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +518 -4
  261. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +6 -0
  262. package/gs/github.com/aperturerobotics/util/conc/index.test.ts +30 -0
  263. package/gs/github.com/aperturerobotics/util/conc/index.ts +172 -0
  264. package/gs/github.com/aperturerobotics/util/conc/meta.json +9 -0
  265. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.ts +1 -4
  266. package/gs/github.com/hack-pad/safejs/internal/catch/index.test.ts +35 -0
  267. package/gs/github.com/hack-pad/safejs/internal/catch/index.ts +65 -0
  268. package/gs/github.com/hack-pad/safejs/internal/catch/meta.json +9 -0
  269. package/gs/github.com/klauspost/compress/internal/le/index.test.ts +2 -1
  270. package/gs/github.com/klauspost/compress/internal/le/index.ts +6 -5
  271. package/gs/github.com/mr-tron/base58/base58/index.test.ts +70 -0
  272. package/gs/github.com/mr-tron/base58/base58/index.ts +231 -0
  273. package/gs/github.com/mr-tron/base58/base58/meta.json +3 -0
  274. package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +46 -0
  275. package/gs/github.com/zeebo/blake3/internal/consts/index.ts +26 -0
  276. package/gs/go/token/index.ts +17 -4
  277. package/gs/hash/fnv/index.test.ts +67 -0
  278. package/gs/hash/fnv/index.ts +351 -0
  279. package/gs/hash/fnv/meta.json +3 -0
  280. package/gs/hash/index.test.ts +37 -0
  281. package/gs/hash/index.ts +118 -0
  282. package/gs/hash/meta.json +5 -0
  283. package/gs/internal/byteorder/index.test.ts +6 -6
  284. package/gs/io/fs/readlink.ts +40 -48
  285. package/gs/io/fs/walk.ts +10 -2
  286. package/gs/io/io.ts +4 -1
  287. package/gs/iter/iter.ts +8 -2
  288. package/gs/maps/iter.ts +69 -26
  289. package/gs/maps/maps.test.ts +23 -0
  290. package/gs/maps/maps.ts +6 -6
  291. package/gs/math/bits/index.test.ts +20 -0
  292. package/gs/math/bits/index.ts +15 -28
  293. package/gs/mime/index.ts +8 -2
  294. package/gs/net/http/httptest/index.test.ts +53 -0
  295. package/gs/net/http/httptest/index.ts +98 -3
  296. package/gs/net/http/index.test.ts +129 -1
  297. package/gs/net/http/index.ts +370 -19
  298. package/gs/net/http/meta.json +6 -0
  299. package/gs/net/http/pprof/index.test.ts +47 -0
  300. package/gs/net/http/pprof/index.ts +65 -0
  301. package/gs/os/error.gs.ts +9 -10
  302. package/gs/os/error.test.ts +41 -0
  303. package/gs/os/file_unix_js.test.ts +55 -0
  304. package/gs/os/tempfile.gs.test.ts +37 -10
  305. package/gs/os/types_js.gs.ts +94 -15
  306. package/gs/path/filepath/match.ts +4 -1
  307. package/gs/path/filepath/meta.json +6 -0
  308. package/gs/path/filepath/path.test.ts +57 -2
  309. package/gs/path/filepath/path.ts +91 -12
  310. package/gs/reflect/field.test.ts +63 -0
  311. package/gs/reflect/index.ts +4 -1
  312. package/gs/reflect/iter.ts +2 -2
  313. package/gs/reflect/map.test.ts +24 -2
  314. package/gs/reflect/map.ts +35 -0
  315. package/gs/reflect/type.ts +543 -60
  316. package/gs/reflect/typefor.test.ts +100 -0
  317. package/gs/reflect/types.ts +3 -1
  318. package/gs/reflect/value.ts +50 -1
  319. package/gs/reflect/visiblefields.ts +1 -1
  320. package/gs/runtime/debug/index.test.ts +22 -1
  321. package/gs/runtime/debug/index.ts +88 -0
  322. package/gs/runtime/pprof/index.test.ts +36 -0
  323. package/gs/runtime/pprof/index.ts +104 -0
  324. package/gs/runtime/pprof/meta.json +6 -0
  325. package/gs/runtime/trace/index.test.ts +45 -0
  326. package/gs/runtime/trace/index.ts +97 -0
  327. package/gs/runtime/trace/meta.json +7 -0
  328. package/gs/slices/meta.json +2 -1
  329. package/gs/slices/slices.test.ts +86 -0
  330. package/gs/slices/slices.ts +284 -37
  331. package/gs/sort/slice.gs.ts +73 -23
  332. package/gs/sort/slice.test.ts +40 -0
  333. package/gs/strings/builder.test.ts +8 -0
  334. package/gs/strings/builder.ts +29 -17
  335. package/gs/strings/iter.test.ts +5 -7
  336. package/gs/strings/iter.ts +146 -71
  337. package/gs/strings/replace.test.ts +1 -4
  338. package/gs/strings/replace.ts +6 -6
  339. package/gs/strings/strings.test.ts +4 -0
  340. package/gs/strings/strings.ts +54 -6
  341. package/gs/sync/sync.test.ts +57 -1
  342. package/gs/sync/sync.ts +45 -13
  343. package/gs/syscall/errors.ts +158 -115
  344. package/gs/syscall/fs.ts +8 -8
  345. package/gs/syscall/js/index.ts +49 -22
  346. package/gs/syscall/net.test.ts +26 -0
  347. package/gs/syscall/types.ts +7 -2
  348. package/gs/testing/testing.test.ts +56 -0
  349. package/gs/testing/testing.ts +27 -10
  350. package/gs/time/meta.json +2 -2
  351. package/gs/time/time.test.ts +4 -0
  352. package/gs/time/time.ts +33 -2
  353. package/gs/unicode/unicode.test.ts +14 -3
  354. package/gs/unicode/unicode.ts +1 -5
  355. package/gs/unique/index.ts +9 -2
  356. package/package.json +3 -3
@@ -56,7 +56,7 @@ export interface Channel<T> {
56
56
  * @param id An identifier for this case in the select statement
57
57
  * @returns Promise that resolves when this case is selected
58
58
  */
59
- selectReceive(id: number): Promise<SelectResult<T>>
59
+ selectReceive(id: number, signal?: AbortSignal): Promise<SelectResult<T>>
60
60
 
61
61
  /**
62
62
  * Used in select statements to create a send operation promise.
@@ -64,7 +64,11 @@ export interface Channel<T> {
64
64
  * @param id An identifier for this case in the select statement
65
65
  * @returns Promise that resolves when this case is selected
66
66
  */
67
- selectSend(value: T, id: number): Promise<SelectResult<boolean>>
67
+ selectSend(
68
+ value: T,
69
+ id: number,
70
+ signal?: AbortSignal,
71
+ ): Promise<SelectResult<boolean>>
68
72
 
69
73
  /**
70
74
  * Checks if the channel has data ready to be received without blocking.
@@ -82,6 +86,11 @@ export interface Channel<T> {
82
86
  * Reports the number of buffered values currently queued in the channel.
83
87
  */
84
88
  len(): number
89
+
90
+ /**
91
+ * Reports the channel buffer capacity.
92
+ */
93
+ cap(): number
85
94
  }
86
95
 
87
96
  /**
@@ -96,6 +105,27 @@ export interface SelectCase<T> {
96
105
  onSelected?: (result: SelectResult<T>) => Promise<any>
97
106
  }
98
107
 
108
+ const selectVoidReturnMarker = '__goscriptSelectVoidReturn'
109
+
110
+ export interface SelectVoidReturn {
111
+ readonly [selectVoidReturnMarker]: true
112
+ }
113
+
114
+ export function selectVoidReturn(): SelectVoidReturn {
115
+ return { [selectVoidReturnMarker]: true }
116
+ }
117
+
118
+ function selectHandlerResult<V>(handlerResult: any): [boolean, V] {
119
+ if (
120
+ handlerResult &&
121
+ typeof handlerResult === 'object' &&
122
+ handlerResult[selectVoidReturnMarker] === true
123
+ ) {
124
+ return [true, undefined as V]
125
+ }
126
+ return [handlerResult !== undefined, handlerResult as V]
127
+ }
128
+
99
129
  /**
100
130
  * Helper for 'select' statements. Takes an array of select cases
101
131
  * and resolves when one of them completes, following Go's select rules.
@@ -151,13 +181,13 @@ export async function selectStatement<T, V = void>(
151
181
  const handlerResult = await selectedCase.onSelected(
152
182
  result as SelectResult<T>,
153
183
  )
154
- return [handlerResult !== undefined, handlerResult as V]
184
+ return selectHandlerResult<V>(handlerResult)
155
185
  }
156
186
  } else {
157
187
  const result = await selectedCase.channel.selectReceive(selectedCase.id)
158
188
  if (selectedCase.onSelected) {
159
189
  const handlerResult = await selectedCase.onSelected(result)
160
- return [handlerResult !== undefined, handlerResult as V]
190
+ return selectHandlerResult<V>(handlerResult)
161
191
  }
162
192
  }
163
193
  } else {
@@ -178,22 +208,27 @@ export async function selectStatement<T, V = void>(
178
208
  ok: false,
179
209
  id: -1,
180
210
  } as SelectResult<T>)
181
- return [handlerResult !== undefined, handlerResult as V]
211
+ return selectHandlerResult<V>(handlerResult)
182
212
  }
183
213
  return [false, undefined as V] // Return after executing the default case
184
214
  }
185
215
 
186
216
  // 3. If no operations are ready and no default case, block until one is ready
187
217
  // Use Promise.race on the blocking promises
218
+ const abort = new AbortController()
188
219
  const blockingPromises = cases
189
220
  .filter((c) => c.id !== -1) // Exclude default case
190
221
  .filter((c) => c.channel !== null) // Exclude nil channels (they would block forever)
191
222
  .map((caseObj) => {
192
223
  // At this point caseObj.channel is guaranteed to be non-null
193
224
  if (caseObj.isSend) {
194
- return caseObj.channel!.selectSend(caseObj.value, caseObj.id)
225
+ return caseObj.channel!.selectSend(
226
+ caseObj.value,
227
+ caseObj.id,
228
+ abort.signal,
229
+ )
195
230
  } else {
196
- return caseObj.channel!.selectReceive(caseObj.id)
231
+ return caseObj.channel!.selectReceive(caseObj.id, abort.signal)
197
232
  }
198
233
  })
199
234
 
@@ -204,11 +239,12 @@ export async function selectStatement<T, V = void>(
204
239
  }
205
240
 
206
241
  const result = await Promise.race(blockingPromises)
242
+ abort.abort()
207
243
  // Execute onSelected handler for the selected case
208
244
  const selectedCase = cases.find((c) => c.id === result.id)
209
245
  if (selectedCase && selectedCase.onSelected) {
210
246
  const handlerResult = await selectedCase.onSelected(result)
211
- return [handlerResult !== undefined, handlerResult as V]
247
+ return selectHandlerResult<V>(handlerResult)
212
248
  }
213
249
 
214
250
  // No explicit return needed here, as the function will implicitly return after the await
@@ -430,7 +466,10 @@ class BufferedChannel<T> implements Channel<T> {
430
466
  })
431
467
  }
432
468
 
433
- async selectReceive(id: number): Promise<SelectResult<T>> {
469
+ async selectReceive(
470
+ id: number,
471
+ signal?: AbortSignal,
472
+ ): Promise<SelectResult<T>> {
434
473
  if (this.buffer.length > 0) {
435
474
  const value = this.buffer.shift()!
436
475
  if (this.senders.length > 0) {
@@ -452,15 +491,43 @@ class BufferedChannel<T> implements Channel<T> {
452
491
  }
453
492
 
454
493
  return new Promise<SelectResult<T>>((resolve) => {
455
- this.receiversWithOk.push({
494
+ const state = { done: false }
495
+ const receiversWithOk = this.receiversWithOk
496
+ const task = {
456
497
  resolveReceive: (result: ChannelReceiveResult<T>) => {
457
- resolve({ ...result, id })
498
+ if (!state.done) {
499
+ state.done = true
500
+ cleanup()
501
+ resolve({ ...result, id })
502
+ }
458
503
  },
459
- })
504
+ }
505
+ function cleanup() {
506
+ signal?.removeEventListener('abort', onAbort)
507
+ const idx = receiversWithOk.indexOf(task)
508
+ if (idx >= 0) {
509
+ receiversWithOk.splice(idx, 1)
510
+ }
511
+ }
512
+ function onAbort() {
513
+ if (!state.done) {
514
+ state.done = true
515
+ cleanup()
516
+ }
517
+ }
518
+ if (signal?.aborted) {
519
+ return
520
+ }
521
+ signal?.addEventListener('abort', onAbort, { once: true })
522
+ this.receiversWithOk.push(task)
460
523
  })
461
524
  }
462
525
 
463
- async selectSend(value: T, id: number): Promise<SelectResult<boolean>> {
526
+ async selectSend(
527
+ value: T,
528
+ id: number,
529
+ signal?: AbortSignal,
530
+ ): Promise<SelectResult<boolean>> {
464
531
  if (this.closed) {
465
532
  // A select case sending on a closed channel panics in Go.
466
533
  // This will cause Promise.race in selectStatement to reject.
@@ -484,11 +551,43 @@ class BufferedChannel<T> implements Channel<T> {
484
551
  }
485
552
 
486
553
  return new Promise<SelectResult<boolean>>((resolve, reject) => {
487
- this.senders.push({
554
+ const state = { done: false }
555
+ const senders = this.senders
556
+ const task = {
488
557
  value,
489
- resolveSend: () => resolve({ value: true, ok: true, id }),
490
- rejectSend: (e) => reject(e), // Propagate error if channel closes
491
- })
558
+ resolveSend: () => {
559
+ if (!state.done) {
560
+ state.done = true
561
+ cleanup()
562
+ resolve({ value: true, ok: true, id })
563
+ }
564
+ },
565
+ rejectSend: (e: Error) => {
566
+ if (!state.done) {
567
+ state.done = true
568
+ cleanup()
569
+ reject(e)
570
+ }
571
+ },
572
+ }
573
+ function cleanup() {
574
+ signal?.removeEventListener('abort', onAbort)
575
+ const idx = senders.indexOf(task)
576
+ if (idx >= 0) {
577
+ senders.splice(idx, 1)
578
+ }
579
+ }
580
+ function onAbort() {
581
+ if (!state.done) {
582
+ state.done = true
583
+ cleanup()
584
+ }
585
+ }
586
+ if (signal?.aborted) {
587
+ return
588
+ }
589
+ signal?.addEventListener('abort', onAbort, { once: true })
590
+ this.senders.push(task)
492
591
  })
493
592
  }
494
593
 
@@ -539,6 +638,10 @@ class BufferedChannel<T> implements Channel<T> {
539
638
  len(): number {
540
639
  return this.buffer.length
541
640
  }
641
+
642
+ cap(): number {
643
+ return this.capacity
644
+ }
542
645
  }
543
646
 
544
647
  /**
@@ -562,9 +665,14 @@ export interface ChannelRef<T> {
562
665
  close(): void
563
666
  canSendNonBlocking(): boolean
564
667
  canReceiveNonBlocking(): boolean
565
- selectSend(value: T, id: number): Promise<SelectResult<boolean>>
566
- selectReceive(id: number): Promise<SelectResult<T>>
668
+ selectSend(
669
+ value: T,
670
+ id: number,
671
+ signal?: AbortSignal,
672
+ ): Promise<SelectResult<boolean>>
673
+ selectReceive(id: number, signal?: AbortSignal): Promise<SelectResult<T>>
567
674
  len(): number
675
+ cap(): number
568
676
  }
569
677
 
570
678
  /**
@@ -600,17 +708,25 @@ export class BidirectionalChannelRef<T> implements ChannelRef<T> {
600
708
  return this.channel.canReceiveNonBlocking()
601
709
  }
602
710
 
603
- selectSend(value: T, id: number): Promise<SelectResult<boolean>> {
604
- return this.channel.selectSend(value, id)
711
+ selectSend(
712
+ value: T,
713
+ id: number,
714
+ signal?: AbortSignal,
715
+ ): Promise<SelectResult<boolean>> {
716
+ return this.channel.selectSend(value, id, signal)
605
717
  }
606
718
 
607
- selectReceive(id: number): Promise<SelectResult<T>> {
608
- return this.channel.selectReceive(id)
719
+ selectReceive(id: number, signal?: AbortSignal): Promise<SelectResult<T>> {
720
+ return this.channel.selectReceive(id, signal)
609
721
  }
610
722
 
611
723
  len(): number {
612
724
  return this.channel.len()
613
725
  }
726
+
727
+ cap(): number {
728
+ return this.channel.cap()
729
+ }
614
730
  }
615
731
 
616
732
  /**
@@ -635,8 +751,12 @@ export class SendOnlyChannelRef<T> implements ChannelRef<T> {
635
751
  return this.channel.canSendNonBlocking()
636
752
  }
637
753
 
638
- selectSend(value: T, id: number): Promise<SelectResult<boolean>> {
639
- return this.channel.selectSend(value, id)
754
+ selectSend(
755
+ value: T,
756
+ id: number,
757
+ signal?: AbortSignal,
758
+ ): Promise<SelectResult<boolean>> {
759
+ return this.channel.selectSend(value, id, signal)
640
760
  }
641
761
 
642
762
  // Disallow receive operations
@@ -652,13 +772,17 @@ export class SendOnlyChannelRef<T> implements ChannelRef<T> {
652
772
  return false
653
773
  }
654
774
 
655
- selectReceive(_id: number): Promise<SelectResult<T>> {
775
+ selectReceive(_id: number, _signal?: AbortSignal): Promise<SelectResult<T>> {
656
776
  throw new Error('Cannot receive from send-only channel')
657
777
  }
658
778
 
659
779
  len(): number {
660
780
  return this.channel.len()
661
781
  }
782
+
783
+ cap(): number {
784
+ return this.channel.cap()
785
+ }
662
786
  }
663
787
 
664
788
  /**
@@ -682,8 +806,8 @@ export class ReceiveOnlyChannelRef<T> implements ChannelRef<T> {
682
806
  return this.channel.canReceiveNonBlocking()
683
807
  }
684
808
 
685
- selectReceive(id: number): Promise<SelectResult<T>> {
686
- return this.channel.selectReceive(id)
809
+ selectReceive(id: number, signal?: AbortSignal): Promise<SelectResult<T>> {
810
+ return this.channel.selectReceive(id, signal)
687
811
  }
688
812
 
689
813
  // Disallow send operations
@@ -700,13 +824,21 @@ export class ReceiveOnlyChannelRef<T> implements ChannelRef<T> {
700
824
  return false
701
825
  }
702
826
 
703
- selectSend(_value: T, _id: number): Promise<SelectResult<boolean>> {
827
+ selectSend(
828
+ _value: T,
829
+ _id: number,
830
+ _signal?: AbortSignal,
831
+ ): Promise<SelectResult<boolean>> {
704
832
  throw new Error('Cannot send to receive-only channel')
705
833
  }
706
834
 
707
835
  len(): number {
708
836
  return this.channel.len()
709
837
  }
838
+
839
+ cap(): number {
840
+ return this.channel.cap()
841
+ }
710
842
  }
711
843
 
712
844
  /**
@@ -51,8 +51,19 @@ export class AsyncDisposableStack implements AsyncDisposable {
51
51
  */
52
52
  async [Symbol.asyncDispose](): Promise<void> {
53
53
  // Execute in LIFO order, awaiting each potentially async function
54
- for (let i = this.stack.length - 1; i >= 0; --i) {
55
- await this.stack[i]()
54
+ while (this.stack.length) {
55
+ const fn = this.stack.pop()!
56
+ await fn()
57
+ }
58
+ }
59
+
60
+ [Symbol.dispose](): void {
61
+ while (this.stack.length) {
62
+ const fn = this.stack.pop()!
63
+ const result = fn()
64
+ if (result && typeof (result as Promise<void>).then === "function") {
65
+ throw new Error("async deferred function disposed synchronously")
66
+ }
56
67
  }
57
68
  }
58
69
  }
@@ -36,6 +36,7 @@ function runtimeFixture(platform: string): HostRuntime {
36
36
  deno: null,
37
37
  getEnv: () => '',
38
38
  getStdioHandle: () => null,
39
+ nodeCrypto: null,
39
40
  nodeFS: null,
40
41
  platform,
41
42
  processObj: null,
@@ -54,6 +54,16 @@ export type NodeFSModule = {
54
54
  ): void
55
55
  }
56
56
 
57
+ export type NodeCryptoHash = {
58
+ copy?(): NodeCryptoHash
59
+ update(data: Uint8Array): NodeCryptoHash
60
+ digest(): Uint8Array
61
+ }
62
+
63
+ export type NodeCryptoModule = {
64
+ createHash(algorithm: string): NodeCryptoHash
65
+ }
66
+
57
67
  export type DenoStream = {
58
68
  readSync?(buffer: Uint8Array): number | null
59
69
  writeSync?(buffer: Uint8Array): number
@@ -74,6 +84,7 @@ type HostTextWrite = (data: string) => void
74
84
 
75
85
  export type HostRuntime = {
76
86
  deno: any | null
87
+ nodeCrypto: NodeCryptoModule | null
77
88
  nodeFS: NodeFSModule | null
78
89
  platform: string
79
90
  processObj: any | null
@@ -166,6 +177,31 @@ function detectNodeFS(processObj: any | null): NodeFSModule | null {
166
177
  return null
167
178
  }
168
179
 
180
+ function detectNodeCrypto(processObj: any | null): NodeCryptoModule | null {
181
+ if (processObj && typeof processObj.getBuiltinModule === 'function') {
182
+ const module = processObj.getBuiltinModule('crypto')
183
+ if (module && typeof module.createHash === 'function') {
184
+ return module as NodeCryptoModule
185
+ }
186
+ }
187
+
188
+ const requireFn = getDynamicRequire()
189
+ if (requireFn) {
190
+ for (const specifier of ['node:crypto', 'crypto']) {
191
+ try {
192
+ const module = requireFn(specifier) as NodeCryptoModule | null
193
+ if (module && typeof module.createHash === 'function') {
194
+ return module
195
+ }
196
+ } catch {
197
+ // Try the next fallback.
198
+ }
199
+ }
200
+ }
201
+
202
+ return null
203
+ }
204
+
169
205
  function hasURLScheme(path: string): boolean {
170
206
  return /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(path)
171
207
  }
@@ -247,6 +283,7 @@ function detectHostRuntime(): HostRuntime {
247
283
  const deno = globalObj.Deno ?? null
248
284
  const processObj = globalObj.process ?? null
249
285
  const nodeFS = detectNodeFS(processObj)
286
+ const nodeCrypto = detectNodeCrypto(processObj)
250
287
 
251
288
  const getStdioHandle = (fd: number): DenoFileLike | null => {
252
289
  if (!deno) {
@@ -344,6 +381,7 @@ function detectHostRuntime(): HostRuntime {
344
381
  deno,
345
382
  getEnv,
346
383
  getStdioHandle,
384
+ nodeCrypto,
347
385
  nodeFS,
348
386
  platform,
349
387
  processObj,
package/gs/builtin/map.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import { comparableEqual } from './builtin.js'
2
+ import { GoBinaryString, stringEqual } from './slice.js'
3
+
1
4
  /**
2
5
  * Creates a new map (TypeScript Map).
3
6
  * @returns A new TypeScript Map.
@@ -18,9 +21,9 @@ export function mapGet<K, V, D>(
18
21
  key: K,
19
22
  defaultValue: D,
20
23
  ): [V, true] | [D, false] {
21
- const exists = map?.has(key)
22
- if (exists) {
23
- return [map!.get(key)!, true]
24
+ const entry = findMapEntry(map, key)
25
+ if (entry.found) {
26
+ return [entry.value, true]
24
27
  } else {
25
28
  return [defaultValue, false]
26
29
  }
@@ -36,7 +39,8 @@ export const mapSet = <K, V>(map: Map<K, V> | null, key: K, value: V): void => {
36
39
  if (!map) {
37
40
  throw new Error('assign to nil map')
38
41
  }
39
- map.set(key, value)
42
+ const entry = findMapEntry(map, key)
43
+ map.set(entry.found ? entry.key : key, value)
40
44
  }
41
45
 
42
46
  /**
@@ -45,7 +49,10 @@ export const mapSet = <K, V>(map: Map<K, V> | null, key: K, value: V): void => {
45
49
  * @param key The key to delete.
46
50
  */
47
51
  export const deleteMapEntry = <K, V>(map: Map<K, V> | null, key: K): void => {
48
- map?.delete(key)
52
+ const entry = findMapEntry(map, key)
53
+ if (entry.found) {
54
+ map!.delete(entry.key)
55
+ }
49
56
  }
50
57
 
51
58
  /**
@@ -55,5 +62,38 @@ export const deleteMapEntry = <K, V>(map: Map<K, V> | null, key: K): void => {
55
62
  * @returns True if the key exists, false otherwise.
56
63
  */
57
64
  export const mapHas = <K, V>(map: Map<K, V> | null, key: K): boolean => {
58
- return map?.has(key) ?? false
65
+ return findMapEntry(map, key).found
66
+ }
67
+
68
+ function findMapEntry<K, V>(
69
+ map: Map<K, V> | null,
70
+ key: K,
71
+ ): { found: false } | { found: true; key: K; value: V } {
72
+ if (!map) {
73
+ return { found: false }
74
+ }
75
+ if (map.has(key)) {
76
+ return { found: true, key, value: map.get(key)! }
77
+ }
78
+ if (isGoStringKey(key)) {
79
+ for (const [candidate, value] of map.entries()) {
80
+ if (isGoStringKey(candidate) && stringEqual(candidate as string, key as string)) {
81
+ return { found: true, key: candidate, value }
82
+ }
83
+ }
84
+ return { found: false }
85
+ }
86
+ if (key === null || (typeof key !== 'object' && typeof key !== 'function')) {
87
+ return { found: false }
88
+ }
89
+ for (const [candidate, value] of map.entries()) {
90
+ if (candidate !== key && comparableEqual(candidate, key)) {
91
+ return { found: true, key: candidate, value }
92
+ }
93
+ }
94
+ return { found: false }
95
+ }
96
+
97
+ function isGoStringKey(value: unknown): value is string | GoBinaryString {
98
+ return typeof value === 'string' || value instanceof GoBinaryString
59
99
  }
@@ -68,7 +68,10 @@ function formatValue(
68
68
  try {
69
69
  if (value instanceof Map) {
70
70
  return formatArray(
71
- Array.from(value.entries()).map(([k, v]) => `${formatValue(k, depth + 1, true, seen)} => ${formatValue(v, depth + 1, true, seen)}`),
71
+ Array.from(value.entries()).map(
72
+ ([k, v]) =>
73
+ `${formatValue(k, depth + 1, true, seen)} => ${formatValue(v, depth + 1, true, seen)}`,
74
+ ),
72
75
  depth,
73
76
  seen,
74
77
  )
@@ -113,7 +116,11 @@ function formatUint8Array(value: Uint8Array): string {
113
116
  return `Uint8Array(${value.length}) [ ${Array.from(value).join(', ')} ]`
114
117
  }
115
118
 
116
- function formatArray(value: readonly any[], depth: number, seen: WeakSet<object>): string {
119
+ function formatArray(
120
+ value: readonly any[],
121
+ depth: number,
122
+ seen: WeakSet<object>,
123
+ ): string {
117
124
  if (value.length === 0) {
118
125
  return '[]'
119
126
  }
@@ -150,5 +157,7 @@ function getObjectEntries(value: Record<string, any>): [string, any][] {
150
157
  })
151
158
  }
152
159
 
153
- return Object.entries(value).filter(([, entry]) => typeof entry !== 'function')
160
+ return Object.entries(value).filter(
161
+ ([, entry]) => typeof entry !== 'function',
162
+ )
154
163
  }