goscript 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) 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 +10 -2
  13. package/compiler/lowering.go +2676 -349
  14. package/compiler/override-facts.go +77 -27
  15. package/compiler/override-registry.go +5 -4
  16. package/compiler/override-registry_test.go +178 -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 +2371 -296
  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 +149 -10
  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 +143 -34
  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 +55 -10
  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/bytes.gs.d.ts +7 -5
  58. package/dist/gs/bytes/bytes.gs.js +10 -4
  59. package/dist/gs/bytes/bytes.gs.js.map +1 -1
  60. package/dist/gs/bytes/iter.gs.js +13 -13
  61. package/dist/gs/bytes/iter.gs.js.map +1 -1
  62. package/dist/gs/compress/zlib/index.d.ts +26 -0
  63. package/dist/gs/compress/zlib/index.js +168 -0
  64. package/dist/gs/compress/zlib/index.js.map +1 -0
  65. package/dist/gs/context/context.d.ts +1 -1
  66. package/dist/gs/context/context.js +8 -3
  67. package/dist/gs/context/context.js.map +1 -1
  68. package/dist/gs/crypto/ecdh/index.d.ts +52 -0
  69. package/dist/gs/crypto/ecdh/index.js +226 -0
  70. package/dist/gs/crypto/ecdh/index.js.map +1 -0
  71. package/dist/gs/crypto/ed25519/index.d.ts +34 -0
  72. package/dist/gs/crypto/ed25519/index.js +160 -0
  73. package/dist/gs/crypto/ed25519/index.js.map +1 -0
  74. package/dist/gs/crypto/internal/constanttime/index.d.ts +4 -0
  75. package/dist/gs/crypto/internal/constanttime/index.js +18 -0
  76. package/dist/gs/crypto/internal/constanttime/index.js.map +1 -0
  77. package/dist/gs/crypto/rand/index.d.ts +2 -0
  78. package/dist/gs/crypto/rand/index.js +85 -0
  79. package/dist/gs/crypto/rand/index.js.map +1 -1
  80. package/dist/gs/crypto/sha1/index.d.ts +5 -0
  81. package/dist/gs/crypto/sha1/index.js +106 -0
  82. package/dist/gs/crypto/sha1/index.js.map +1 -0
  83. package/dist/gs/crypto/sha256/index.d.ts +8 -0
  84. package/dist/gs/crypto/sha256/index.js +118 -0
  85. package/dist/gs/crypto/sha256/index.js.map +1 -0
  86. package/dist/gs/crypto/sha512/index.d.ts +14 -0
  87. package/dist/gs/crypto/sha512/index.js +129 -0
  88. package/dist/gs/crypto/sha512/index.js.map +1 -0
  89. package/dist/gs/encoding/json/index.d.ts +3 -0
  90. package/dist/gs/encoding/json/index.js +15 -0
  91. package/dist/gs/encoding/json/index.js.map +1 -1
  92. package/dist/gs/errors/errors.js +29 -6
  93. package/dist/gs/errors/errors.js.map +1 -1
  94. package/dist/gs/fmt/fmt.d.ts +1 -1
  95. package/dist/gs/fmt/fmt.js +64 -3
  96. package/dist/gs/fmt/fmt.js.map +1 -1
  97. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +7 -7
  98. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +52 -18
  99. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  100. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +56 -20
  101. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
  102. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +57 -3
  103. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +366 -1
  104. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -1
  105. package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +20 -0
  106. package/dist/gs/github.com/aperturerobotics/util/conc/index.js +134 -0
  107. package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +1 -0
  108. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
  109. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.d.ts +3 -0
  110. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js +50 -0
  111. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js.map +1 -0
  112. package/dist/gs/github.com/klauspost/compress/internal/le/index.js +3 -2
  113. package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -1
  114. package/dist/gs/github.com/mr-tron/base58/base58/index.d.ts +27 -0
  115. package/dist/gs/github.com/mr-tron/base58/base58/index.js +172 -0
  116. package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -0
  117. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.d.ts +21 -0
  118. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js +22 -0
  119. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js.map +1 -0
  120. package/dist/gs/go/token/index.js +11 -4
  121. package/dist/gs/go/token/index.js.map +1 -1
  122. package/dist/gs/hash/fnv/index.d.ts +57 -0
  123. package/dist/gs/hash/fnv/index.js +299 -0
  124. package/dist/gs/hash/fnv/index.js.map +1 -0
  125. package/dist/gs/hash/index.d.ts +17 -0
  126. package/dist/gs/hash/index.js +94 -0
  127. package/dist/gs/hash/index.js.map +1 -0
  128. package/dist/gs/io/fs/readlink.js +2 -6
  129. package/dist/gs/io/fs/readlink.js.map +1 -1
  130. package/dist/gs/io/fs/walk.js.map +1 -1
  131. package/dist/gs/io/io.d.ts +8 -5
  132. package/dist/gs/io/io.js +20 -2
  133. package/dist/gs/io/io.js.map +1 -1
  134. package/dist/gs/iter/iter.d.ts +3 -2
  135. package/dist/gs/iter/iter.js.map +1 -1
  136. package/dist/gs/maps/iter.d.ts +5 -5
  137. package/dist/gs/maps/iter.js +48 -21
  138. package/dist/gs/maps/iter.js.map +1 -1
  139. package/dist/gs/maps/maps.d.ts +6 -6
  140. package/dist/gs/math/bits/index.js +14 -24
  141. package/dist/gs/math/bits/index.js.map +1 -1
  142. package/dist/gs/mime/index.js +3 -1
  143. package/dist/gs/mime/index.js.map +1 -1
  144. package/dist/gs/net/http/httptest/index.d.ts +20 -1
  145. package/dist/gs/net/http/httptest/index.js +85 -3
  146. package/dist/gs/net/http/httptest/index.js.map +1 -1
  147. package/dist/gs/net/http/index.d.ts +118 -6
  148. package/dist/gs/net/http/index.js +389 -14
  149. package/dist/gs/net/http/index.js.map +1 -1
  150. package/dist/gs/net/http/pprof/index.d.ts +8 -0
  151. package/dist/gs/net/http/pprof/index.js +59 -0
  152. package/dist/gs/net/http/pprof/index.js.map +1 -0
  153. package/dist/gs/os/error.gs.js +9 -7
  154. package/dist/gs/os/error.gs.js.map +1 -1
  155. package/dist/gs/os/types_js.gs.js +95 -15
  156. package/dist/gs/os/types_js.gs.js.map +1 -1
  157. package/dist/gs/os/zero_copy_posix.gs.js +1 -1
  158. package/dist/gs/os/zero_copy_posix.gs.js.map +1 -1
  159. package/dist/gs/path/filepath/match.js.map +1 -1
  160. package/dist/gs/path/filepath/path.d.ts +5 -3
  161. package/dist/gs/path/filepath/path.js +65 -10
  162. package/dist/gs/path/filepath/path.js.map +1 -1
  163. package/dist/gs/reflect/index.d.ts +3 -2
  164. package/dist/gs/reflect/index.js +2 -1
  165. package/dist/gs/reflect/index.js.map +1 -1
  166. package/dist/gs/reflect/iter.js +2 -2
  167. package/dist/gs/reflect/iter.js.map +1 -1
  168. package/dist/gs/reflect/map.js +26 -0
  169. package/dist/gs/reflect/map.js.map +1 -1
  170. package/dist/gs/reflect/type.d.ts +24 -5
  171. package/dist/gs/reflect/type.js +390 -38
  172. package/dist/gs/reflect/type.js.map +1 -1
  173. package/dist/gs/reflect/types.d.ts +1 -0
  174. package/dist/gs/reflect/types.js +3 -1
  175. package/dist/gs/reflect/types.js.map +1 -1
  176. package/dist/gs/reflect/value.d.ts +4 -1
  177. package/dist/gs/reflect/value.js +39 -1
  178. package/dist/gs/reflect/value.js.map +1 -1
  179. package/dist/gs/reflect/visiblefields.js +1 -1
  180. package/dist/gs/reflect/visiblefields.js.map +1 -1
  181. package/dist/gs/runtime/debug/index.d.ts +39 -0
  182. package/dist/gs/runtime/debug/index.js +58 -0
  183. package/dist/gs/runtime/debug/index.js.map +1 -1
  184. package/dist/gs/runtime/pprof/index.d.ts +20 -0
  185. package/dist/gs/runtime/pprof/index.js +85 -0
  186. package/dist/gs/runtime/pprof/index.js.map +1 -0
  187. package/dist/gs/runtime/trace/index.d.ts +19 -0
  188. package/dist/gs/runtime/trace/index.js +64 -0
  189. package/dist/gs/runtime/trace/index.js.map +1 -0
  190. package/dist/gs/slices/slices.d.ts +24 -9
  191. package/dist/gs/slices/slices.js +229 -24
  192. package/dist/gs/slices/slices.js.map +1 -1
  193. package/dist/gs/sort/slice.gs.d.ts +5 -3
  194. package/dist/gs/sort/slice.gs.js +55 -17
  195. package/dist/gs/sort/slice.gs.js.map +1 -1
  196. package/dist/gs/strings/builder.js +26 -17
  197. package/dist/gs/strings/builder.js.map +1 -1
  198. package/dist/gs/strings/iter.js +140 -75
  199. package/dist/gs/strings/iter.js.map +1 -1
  200. package/dist/gs/strings/replace.js +2 -2
  201. package/dist/gs/strings/replace.js.map +1 -1
  202. package/dist/gs/strings/strings.js +52 -6
  203. package/dist/gs/strings/strings.js.map +1 -1
  204. package/dist/gs/sync/sync.d.ts +6 -3
  205. package/dist/gs/sync/sync.js +39 -11
  206. package/dist/gs/sync/sync.js.map +1 -1
  207. package/dist/gs/syscall/errors.d.ts +116 -112
  208. package/dist/gs/syscall/errors.js +38 -1
  209. package/dist/gs/syscall/errors.js.map +1 -1
  210. package/dist/gs/syscall/fs.d.ts +2 -8
  211. package/dist/gs/syscall/fs.js.map +1 -1
  212. package/dist/gs/syscall/js/index.js +20 -12
  213. package/dist/gs/syscall/js/index.js.map +1 -1
  214. package/dist/gs/syscall/types.d.ts +4 -1
  215. package/dist/gs/syscall/types.js.map +1 -1
  216. package/dist/gs/testing/testing.d.ts +4 -3
  217. package/dist/gs/testing/testing.js +21 -4
  218. package/dist/gs/testing/testing.js.map +1 -1
  219. package/dist/gs/time/time.js +22 -0
  220. package/dist/gs/time/time.js.map +1 -1
  221. package/dist/gs/unicode/unicode.js.map +1 -1
  222. package/dist/gs/unique/index.js +7 -2
  223. package/dist/gs/unique/index.js.map +1 -1
  224. package/go.mod +8 -8
  225. package/go.sum +14 -23
  226. package/gs/builtin/builtin.ts +364 -37
  227. package/gs/builtin/channel.ts +208 -38
  228. package/gs/builtin/defer.ts +13 -2
  229. package/gs/builtin/hostio.test.ts +1 -0
  230. package/gs/builtin/hostio.ts +38 -0
  231. package/gs/builtin/map.ts +46 -6
  232. package/gs/builtin/print.ts +12 -3
  233. package/gs/builtin/runtime-contract.test.ts +290 -10
  234. package/gs/builtin/slice.test.ts +70 -0
  235. package/gs/builtin/slice.ts +566 -255
  236. package/gs/builtin/type.ts +63 -10
  237. package/gs/builtin/varRef.ts +2 -0
  238. package/gs/bytes/buffer.gs.ts +28 -28
  239. package/gs/bytes/bytes.gs.ts +19 -10
  240. package/gs/bytes/bytes.test.ts +17 -0
  241. package/gs/bytes/iter.gs.ts +13 -14
  242. package/gs/compress/zlib/index.test.ts +28 -0
  243. package/gs/compress/zlib/index.ts +200 -0
  244. package/gs/compress/zlib/meta.json +3 -0
  245. package/gs/context/context.test.ts +36 -2
  246. package/gs/context/context.ts +9 -4
  247. package/gs/crypto/ecdh/index.test.ts +43 -0
  248. package/gs/crypto/ecdh/index.ts +274 -0
  249. package/gs/crypto/ed25519/index.test.ts +41 -0
  250. package/gs/crypto/ed25519/index.ts +238 -0
  251. package/gs/crypto/ed25519/meta.json +13 -0
  252. package/gs/crypto/internal/constanttime/index.test.ts +25 -0
  253. package/gs/crypto/internal/constanttime/index.ts +22 -0
  254. package/gs/crypto/rand/index.test.ts +89 -1
  255. package/gs/crypto/rand/index.ts +103 -1
  256. package/gs/crypto/rand/meta.json +4 -1
  257. package/gs/crypto/sha1/index.test.ts +28 -0
  258. package/gs/crypto/sha1/index.ts +130 -0
  259. package/gs/crypto/sha1/meta.json +8 -0
  260. package/gs/crypto/sha256/index.test.ts +78 -0
  261. package/gs/crypto/sha256/index.ts +150 -0
  262. package/gs/crypto/sha256/meta.json +9 -0
  263. package/gs/crypto/sha512/index.test.ts +31 -0
  264. package/gs/crypto/sha512/index.ts +161 -0
  265. package/gs/crypto/sha512/meta.json +11 -0
  266. package/gs/encoding/json/index.test.ts +25 -3
  267. package/gs/encoding/json/index.ts +21 -3
  268. package/gs/errors/errors.test.ts +4 -1
  269. package/gs/errors/errors.ts +32 -8
  270. package/gs/fmt/fmt.test.ts +23 -1
  271. package/gs/fmt/fmt.ts +76 -10
  272. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +62 -7
  273. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +78 -36
  274. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +32 -11
  275. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +122 -43
  276. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +31 -0
  277. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +518 -4
  278. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +6 -0
  279. package/gs/github.com/aperturerobotics/util/conc/index.test.ts +30 -0
  280. package/gs/github.com/aperturerobotics/util/conc/index.ts +172 -0
  281. package/gs/github.com/aperturerobotics/util/conc/meta.json +9 -0
  282. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.ts +1 -4
  283. package/gs/github.com/hack-pad/safejs/internal/catch/index.test.ts +35 -0
  284. package/gs/github.com/hack-pad/safejs/internal/catch/index.ts +65 -0
  285. package/gs/github.com/hack-pad/safejs/internal/catch/meta.json +9 -0
  286. package/gs/github.com/klauspost/compress/internal/le/index.test.ts +2 -1
  287. package/gs/github.com/klauspost/compress/internal/le/index.ts +6 -5
  288. package/gs/github.com/mr-tron/base58/base58/index.test.ts +70 -0
  289. package/gs/github.com/mr-tron/base58/base58/index.ts +231 -0
  290. package/gs/github.com/mr-tron/base58/base58/meta.json +3 -0
  291. package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +46 -0
  292. package/gs/github.com/zeebo/blake3/internal/consts/index.ts +26 -0
  293. package/gs/go/token/index.ts +17 -4
  294. package/gs/hash/fnv/index.test.ts +67 -0
  295. package/gs/hash/fnv/index.ts +351 -0
  296. package/gs/hash/fnv/meta.json +3 -0
  297. package/gs/hash/index.test.ts +37 -0
  298. package/gs/hash/index.ts +118 -0
  299. package/gs/hash/meta.json +5 -0
  300. package/gs/internal/byteorder/index.test.ts +6 -6
  301. package/gs/io/fs/readlink.ts +40 -48
  302. package/gs/io/fs/walk.ts +10 -2
  303. package/gs/io/io.test.ts +64 -0
  304. package/gs/io/io.ts +34 -13
  305. package/gs/iter/iter.ts +8 -2
  306. package/gs/maps/iter.ts +69 -26
  307. package/gs/maps/maps.test.ts +23 -0
  308. package/gs/maps/maps.ts +6 -6
  309. package/gs/math/bits/index.test.ts +20 -0
  310. package/gs/math/bits/index.ts +15 -28
  311. package/gs/mime/index.ts +8 -2
  312. package/gs/net/http/httptest/index.test.ts +85 -0
  313. package/gs/net/http/httptest/index.ts +113 -3
  314. package/gs/net/http/index.test.ts +159 -1
  315. package/gs/net/http/index.ts +515 -15
  316. package/gs/net/http/meta.json +6 -0
  317. package/gs/net/http/pprof/index.test.ts +47 -0
  318. package/gs/net/http/pprof/index.ts +65 -0
  319. package/gs/os/error.gs.ts +9 -10
  320. package/gs/os/error.test.ts +41 -0
  321. package/gs/os/file_unix_js.test.ts +55 -0
  322. package/gs/os/tempfile.gs.test.ts +37 -10
  323. package/gs/os/types_js.gs.ts +94 -15
  324. package/gs/os/zero_copy_posix.gs.ts +1 -2
  325. package/gs/path/filepath/match.ts +4 -1
  326. package/gs/path/filepath/meta.json +6 -0
  327. package/gs/path/filepath/path.test.ts +57 -2
  328. package/gs/path/filepath/path.ts +91 -12
  329. package/gs/reflect/field.test.ts +63 -0
  330. package/gs/reflect/index.ts +4 -1
  331. package/gs/reflect/iter.ts +2 -2
  332. package/gs/reflect/map.test.ts +24 -2
  333. package/gs/reflect/map.ts +35 -0
  334. package/gs/reflect/type.ts +543 -60
  335. package/gs/reflect/typefor.test.ts +100 -0
  336. package/gs/reflect/types.ts +3 -1
  337. package/gs/reflect/value.ts +50 -1
  338. package/gs/reflect/visiblefields.ts +1 -1
  339. package/gs/runtime/debug/index.test.ts +22 -1
  340. package/gs/runtime/debug/index.ts +88 -0
  341. package/gs/runtime/pprof/index.test.ts +36 -0
  342. package/gs/runtime/pprof/index.ts +104 -0
  343. package/gs/runtime/pprof/meta.json +6 -0
  344. package/gs/runtime/trace/index.test.ts +45 -0
  345. package/gs/runtime/trace/index.ts +97 -0
  346. package/gs/runtime/trace/meta.json +7 -0
  347. package/gs/slices/meta.json +2 -1
  348. package/gs/slices/slices.test.ts +86 -0
  349. package/gs/slices/slices.ts +284 -37
  350. package/gs/sort/slice.gs.ts +73 -23
  351. package/gs/sort/slice.test.ts +40 -0
  352. package/gs/strings/builder.test.ts +8 -0
  353. package/gs/strings/builder.ts +29 -17
  354. package/gs/strings/iter.test.ts +5 -7
  355. package/gs/strings/iter.ts +146 -71
  356. package/gs/strings/replace.test.ts +1 -4
  357. package/gs/strings/replace.ts +6 -6
  358. package/gs/strings/strings.test.ts +4 -0
  359. package/gs/strings/strings.ts +54 -6
  360. package/gs/sync/meta.json +1 -0
  361. package/gs/sync/sync.test.ts +57 -1
  362. package/gs/sync/sync.ts +45 -13
  363. package/gs/syscall/errors.ts +158 -115
  364. package/gs/syscall/fs.ts +8 -8
  365. package/gs/syscall/js/index.ts +49 -22
  366. package/gs/syscall/net.test.ts +26 -0
  367. package/gs/syscall/types.ts +7 -2
  368. package/gs/testing/testing.test.ts +56 -0
  369. package/gs/testing/testing.ts +27 -10
  370. package/gs/time/meta.json +2 -2
  371. package/gs/time/time.test.ts +4 -0
  372. package/gs/time/time.ts +33 -2
  373. package/gs/unicode/unicode.test.ts +14 -3
  374. package/gs/unicode/unicode.ts +1 -5
  375. package/gs/unique/index.ts +9 -2
  376. package/package.json +3 -3
@@ -0,0 +1,200 @@
1
+ import * as $ from '@goscript/builtin/index.js'
2
+ import * as errors from '@goscript/errors/index.js'
3
+ import * as io from '@goscript/io/index.js'
4
+
5
+ export type Resetter = {
6
+ Reset(r: io.Reader | null, dict: $.Bytes | null): Promise<$.GoError>
7
+ }
8
+
9
+ export let ErrChecksum = errors.New('zlib: invalid checksum')
10
+ export let ErrDictionary = errors.New('zlib: invalid dictionary')
11
+ export let ErrHeader = errors.New('zlib: invalid header')
12
+
13
+ export function __goscript_set_ErrChecksum(value: $.GoError): void {
14
+ ErrChecksum = value
15
+ }
16
+
17
+ export function __goscript_set_ErrDictionary(value: $.GoError): void {
18
+ ErrDictionary = value
19
+ }
20
+
21
+ export function __goscript_set_ErrHeader(value: $.GoError): void {
22
+ ErrHeader = value
23
+ }
24
+
25
+ class zlibReader implements io.ReadCloser {
26
+ private offset = 0
27
+
28
+ constructor(private data: Uint8Array) {}
29
+
30
+ Read(p: $.Bytes): [number, $.GoError] {
31
+ if (this.offset >= this.data.length) {
32
+ return [0, io.EOF]
33
+ }
34
+ const out = $.bytesToUint8Array(p)
35
+ const n = Math.min(out.length, this.data.length - this.offset)
36
+ out.set(this.data.subarray(this.offset, this.offset + n))
37
+ this.offset += n
38
+ return [n, null]
39
+ }
40
+
41
+ Close(): $.GoError {
42
+ return null
43
+ }
44
+ }
45
+
46
+ export class Writer {
47
+ private chunks: Uint8Array[] = []
48
+ private closed = false
49
+
50
+ constructor(private w: io.Writer | null) {}
51
+
52
+ Write(p: $.Bytes): [number, $.GoError] {
53
+ if (this.closed) {
54
+ return [0, errors.New('zlib: writer closed')]
55
+ }
56
+ const data = $.bytesToUint8Array(p)
57
+ this.chunks.push(data.slice())
58
+ return [data.length, null]
59
+ }
60
+
61
+ Close(): $.GoError {
62
+ if (this.closed) {
63
+ return null
64
+ }
65
+ this.closed = true
66
+ if (this.w == null) {
67
+ return errors.New('zlib: nil writer')
68
+ }
69
+ const compressed = deflate(concat(this.chunks))
70
+ const [, err] = this.w.Write(compressed)
71
+ return err
72
+ }
73
+
74
+ Flush(): $.GoError {
75
+ return null
76
+ }
77
+
78
+ Reset(w: io.Writer | null): void {
79
+ this.w = w
80
+ this.chunks = []
81
+ this.closed = false
82
+ }
83
+ }
84
+
85
+ export function NewWriter(w: io.Writer | null): Writer {
86
+ return new Writer(w)
87
+ }
88
+
89
+ export function NewWriterLevel(
90
+ w: io.Writer | null,
91
+ _level: number,
92
+ ): [Writer | null, $.GoError] {
93
+ return [new Writer(w), null]
94
+ }
95
+
96
+ export function NewWriterLevelDict(
97
+ w: io.Writer | null,
98
+ _level: number,
99
+ _dict: $.Bytes | null,
100
+ ): [Writer | null, $.GoError] {
101
+ return [new Writer(w), null]
102
+ }
103
+
104
+ export function NewReader(
105
+ r: io.Reader | null,
106
+ ): [io.ReadCloser | null, $.GoError] {
107
+ return NewReaderDict(r, null)
108
+ }
109
+
110
+ export function NewReaderDict(
111
+ r: io.Reader | null,
112
+ _dict: $.Bytes | null,
113
+ ): [io.ReadCloser | null, $.GoError] {
114
+ if (r == null) {
115
+ return [null, errors.New('zlib: nil reader')]
116
+ }
117
+ const [data, readErr] = readAll(r)
118
+ if (readErr != null) {
119
+ return [null, readErr]
120
+ }
121
+ try {
122
+ const out = inflate($.bytesToUint8Array(data))
123
+ return [new zlibReader(out), null]
124
+ } catch {
125
+ return [null, ErrHeader]
126
+ }
127
+ }
128
+
129
+ function deflate(data: Uint8Array): Uint8Array {
130
+ const zlib = nodeZlib()
131
+ return new Uint8Array(zlib.deflateSync(data))
132
+ }
133
+
134
+ function inflate(data: Uint8Array): Uint8Array {
135
+ const zlib = nodeZlib()
136
+ return new Uint8Array(zlib.inflateSync(data))
137
+ }
138
+
139
+ function nodeZlib(): any {
140
+ const processObj = (globalThis as any).process
141
+ if (processObj && typeof processObj.getBuiltinModule === 'function') {
142
+ const mod = processObj.getBuiltinModule('zlib')
143
+ if (mod && typeof mod.deflateSync === 'function') {
144
+ return mod
145
+ }
146
+ }
147
+ const requireFn = (() => {
148
+ try {
149
+ return Function(
150
+ "return typeof require !== 'undefined' ? require : null",
151
+ )() as ((specifier: string) => unknown) | null
152
+ } catch {
153
+ return null
154
+ }
155
+ })()
156
+ if (requireFn != null) {
157
+ for (const specifier of ['node:zlib', 'zlib']) {
158
+ try {
159
+ const mod = requireFn(specifier) as any
160
+ if (mod && typeof mod.deflateSync === 'function') {
161
+ return mod
162
+ }
163
+ } catch {
164
+ // Try the next fallback.
165
+ }
166
+ }
167
+ }
168
+ throw new Error('compress/zlib: node zlib module unavailable')
169
+ }
170
+
171
+ function readAll(r: io.Reader): [Uint8Array, $.GoError] {
172
+ const chunks: Uint8Array[] = []
173
+ const buf = $.makeSlice<number>(32 * 1024, undefined, 'byte')
174
+ while (true) {
175
+ const [n, err] = r.Read(buf)
176
+ if (n > 0) {
177
+ chunks.push($.bytesToUint8Array($.goSlice(buf, 0, n)).slice())
178
+ }
179
+ if (err != null) {
180
+ if (err === io.EOF) {
181
+ return [concat(chunks), null]
182
+ }
183
+ return [new Uint8Array(0), err]
184
+ }
185
+ }
186
+ }
187
+
188
+ function concat(chunks: Uint8Array[]): Uint8Array {
189
+ let total = 0
190
+ for (const chunk of chunks) {
191
+ total += chunk.length
192
+ }
193
+ const out = new Uint8Array(total)
194
+ let offset = 0
195
+ for (const chunk of chunks) {
196
+ out.set(chunk, offset)
197
+ offset += chunk.length
198
+ }
199
+ return out
200
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "dependencies": []
3
+ }
@@ -1,12 +1,38 @@
1
1
  import { describe, expect, it } from 'vitest'
2
2
 
3
- import { AfterFunc, WithCancel, Background } from './index.js'
3
+ import * as $ from '@goscript/builtin/index.js'
4
+
5
+ import { AfterFunc, WithCancel, Background, WithValue } from './index.js'
4
6
 
5
7
  async function nextMicrotask(): Promise<void> {
6
8
  await new Promise<void>((resolve) => queueMicrotask(resolve))
7
9
  }
8
10
 
11
+ async function nextTask(): Promise<void> {
12
+ await new Promise<void>((resolve) => setTimeout(resolve, 0))
13
+ }
14
+
9
15
  describe('context override', () => {
16
+ it('matches generated struct keys by Go comparable value', () => {
17
+ class Key {
18
+ public _fields: Record<string, $.VarRef<unknown>>
19
+
20
+ constructor() {
21
+ this._fields = {}
22
+ }
23
+ }
24
+
25
+ const ctx = WithValue(
26
+ Background(),
27
+ $.interfaceValue($.markAsStructValue(new Key()), 'example.key'),
28
+ 'stored',
29
+ )
30
+
31
+ expect(
32
+ ctx.Value($.interfaceValue($.markAsStructValue(new Key()), 'example.key')),
33
+ ).toBe('stored')
34
+ })
35
+
10
36
  it('runs AfterFunc after cancellation', async () => {
11
37
  const [ctx, cancel] = WithCancel(Background())
12
38
  let called = false
@@ -17,7 +43,7 @@ describe('context override', () => {
17
43
 
18
44
  cancel?.()
19
45
  await nextMicrotask()
20
- await nextMicrotask()
46
+ await nextTask()
21
47
 
22
48
  expect(called).toBe(true)
23
49
  expect(stop()).toBe(false)
@@ -38,4 +64,12 @@ describe('context override', () => {
38
64
 
39
65
  expect(called).toBe(false)
40
66
  })
67
+
68
+ it('accepts nil AfterFunc callbacks for type compatibility', () => {
69
+ const [ctx] = WithCancel(Background())
70
+
71
+ const stop = AfterFunc(ctx, null)
72
+
73
+ expect(stop()).toBe(true)
74
+ })
41
75
  })
@@ -87,7 +87,7 @@ class valueContext extends baseContext {
87
87
  }
88
88
 
89
89
  Value(key: any): any {
90
- if (this.key === key) {
90
+ if (this.key === key || $.comparableEqual(this.key, key)) {
91
91
  return this.val
92
92
  }
93
93
  return this.parent.Value(key)
@@ -388,8 +388,8 @@ export function Cause(ctx: Context): $.GoError {
388
388
  return c.Err()
389
389
  }
390
390
 
391
- // AfterFunc runs f in a separate goroutine after ctx is done
392
- export function AfterFunc(ctx: Context, f: () => void): () => boolean {
391
+ // AfterFunc runs f in a separate goroutine after ctx is done.
392
+ export function AfterFunc(ctx: Context, f: (() => void) | null): () => boolean {
393
393
  if (ctx === null) {
394
394
  throw new Error('cannot create context from nil parent')
395
395
  }
@@ -405,7 +405,12 @@ export function AfterFunc(ctx: Context, f: () => void): () => boolean {
405
405
  if (!stopped) {
406
406
  done = true
407
407
  // Run in next tick to simulate goroutine
408
- queueMicrotask(f)
408
+ queueMicrotask(() => {
409
+ if (f === null) {
410
+ throw new Error('context: nil AfterFunc callback')
411
+ }
412
+ f()
413
+ })
409
414
  }
410
415
  })()
411
416
 
@@ -0,0 +1,43 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { X25519 } from './index.js'
4
+
5
+ describe('crypto/ecdh override', () => {
6
+ it('matches the RFC 7748 X25519 test vector', () => {
7
+ const curve = X25519()
8
+ const [alice, aliceErr] = curve.NewPrivateKey(
9
+ hex('77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a'),
10
+ )
11
+ const [bobPub, bobPubErr] = curve.NewPublicKey(
12
+ hex('de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f'),
13
+ )
14
+
15
+ expect(aliceErr).toBeNull()
16
+ expect(bobPubErr).toBeNull()
17
+ expect(toHex(alice!.PublicKey().Bytes())).toBe(
18
+ '8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a',
19
+ )
20
+
21
+ const [shared, sharedErr] = alice!.ECDH(bobPub)
22
+ expect(sharedErr).toBeNull()
23
+ expect(toHex(shared)).toBe(
24
+ '4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742',
25
+ )
26
+ })
27
+
28
+ it('rejects low-order remote points', () => {
29
+ const [priv] = X25519().NewPrivateKey(new Uint8Array(32).fill(7))
30
+ const [zero] = X25519().NewPublicKey(new Uint8Array(32))
31
+ const [, err] = priv!.ECDH(zero)
32
+
33
+ expect(err?.Error()).toContain('low order point')
34
+ })
35
+ })
36
+
37
+ function hex(value: string): Uint8Array {
38
+ return new Uint8Array(value.match(/../g)!.map((byte) => Number.parseInt(byte, 16)))
39
+ }
40
+
41
+ function toHex(value: Uint8Array | null): string {
42
+ return Array.from(value ?? [], (byte) => byte.toString(16).padStart(2, '0')).join('')
43
+ }
@@ -0,0 +1,274 @@
1
+ import * as $ from '@goscript/builtin/index.js'
2
+ import * as io from '@goscript/io/index.js'
3
+
4
+ export type Curve = x25519Curve | unsupportedCurve
5
+ export type KeyExchanger = PrivateKey
6
+
7
+ const x25519PublicKeySize = 32
8
+ const x25519PrivateKeySize = 32
9
+ const x25519SharedSecretSize = 32
10
+ const p = (1n << 255n) - 19n
11
+ const a24 = 121665n
12
+
13
+ export class PublicKey {
14
+ public curve: Curve
15
+ public publicKey: $.Bytes
16
+
17
+ constructor(init?: Partial<{ curve: Curve; publicKey: $.Bytes }>) {
18
+ this.curve = init?.curve ?? x25519
19
+ this.publicKey = copyBytes(init?.publicKey ?? null)
20
+ }
21
+
22
+ public Bytes(): $.Bytes {
23
+ return copyBytes(this.publicKey)
24
+ }
25
+
26
+ public Curve(): Curve {
27
+ return this.curve
28
+ }
29
+
30
+ public Equal(x: PublicKey | $.VarRef<PublicKey> | null): boolean {
31
+ const other = $.pointerValueOrNil(x)
32
+ return other instanceof PublicKey && bytesEqual(this.publicKey, other.publicKey)
33
+ }
34
+ }
35
+
36
+ export class PrivateKey {
37
+ public curve: Curve
38
+ public privateKey: $.Bytes
39
+ public publicKey: PublicKey
40
+
41
+ constructor(
42
+ init?: Partial<{ curve: Curve; privateKey: $.Bytes; publicKey: PublicKey }>,
43
+ ) {
44
+ this.curve = init?.curve ?? x25519
45
+ this.privateKey = copyBytes(init?.privateKey ?? null)
46
+ this.publicKey = init?.publicKey ?? new PublicKey({ curve: this.curve })
47
+ }
48
+
49
+ public Bytes(): $.Bytes {
50
+ return copyBytes(this.privateKey)
51
+ }
52
+
53
+ public Curve(): Curve {
54
+ return this.curve
55
+ }
56
+
57
+ public ECDH(remote: PublicKey | $.VarRef<PublicKey> | null): [$.Bytes, $.GoError] {
58
+ const remoteKey = $.pointerValueOrNil(remote)
59
+ if (remoteKey == null || remoteKey.curve !== this.curve) {
60
+ return [null, $.newError('crypto/ecdh: private key and public key curves do not match')]
61
+ }
62
+ return this.curve.ecdh(this, remoteKey)
63
+ }
64
+
65
+ public Equal(x: PrivateKey | $.VarRef<PrivateKey> | null): boolean {
66
+ const other = $.pointerValueOrNil(x)
67
+ return other instanceof PrivateKey && bytesEqual(this.privateKey, other.privateKey)
68
+ }
69
+
70
+ public Public(): PublicKey {
71
+ return this.publicKey
72
+ }
73
+
74
+ public PublicKey(): PublicKey {
75
+ return this.publicKey
76
+ }
77
+ }
78
+
79
+ export class x25519Curve {
80
+ public GenerateKey(r: io.Reader | null): [PrivateKey | null, $.GoError] {
81
+ const key = new Uint8Array(x25519PrivateKeySize)
82
+ if (r != null) {
83
+ throw new Error('crypto/ecdh: custom random readers are not implemented in GoScript')
84
+ }
85
+ globalThis.crypto.getRandomValues(key)
86
+ return this.NewPrivateKey(key)
87
+ }
88
+
89
+ public NewPrivateKey(key: $.Bytes): [PrivateKey | null, $.GoError] {
90
+ if ($.len(key) !== x25519PrivateKeySize) {
91
+ return [null, $.newError('crypto/ecdh: invalid private key size')]
92
+ }
93
+ const privateKey = copyBytes(key)
94
+ const publicKey = scalarMult(privateKey, basepoint())
95
+ return [
96
+ new PrivateKey({
97
+ curve: this,
98
+ privateKey,
99
+ publicKey: new PublicKey({ curve: this, publicKey }),
100
+ }),
101
+ null,
102
+ ]
103
+ }
104
+
105
+ public NewPublicKey(key: $.Bytes): [PublicKey | null, $.GoError] {
106
+ if ($.len(key) !== x25519PublicKeySize) {
107
+ return [null, $.newError('crypto/ecdh: invalid public key')]
108
+ }
109
+ return [new PublicKey({ curve: this, publicKey: key }), null]
110
+ }
111
+
112
+ public String(): string {
113
+ return 'X25519'
114
+ }
115
+
116
+ public ecdh(local: PrivateKey | null, remote: PublicKey | null): [$.Bytes, $.GoError] {
117
+ const out = scalarMult(local?.privateKey ?? null, remote?.publicKey ?? null)
118
+ if (isZero(out)) {
119
+ return [null, $.newError('crypto/ecdh: bad X25519 remote ECDH input: low order point')]
120
+ }
121
+ return [out, null]
122
+ }
123
+ }
124
+
125
+ export function X25519(): Curve {
126
+ return x25519
127
+ }
128
+
129
+ export const x25519 = new x25519Curve()
130
+
131
+ export class unsupportedCurve {
132
+ constructor(private readonly name: string) {}
133
+
134
+ public GenerateKey(_r: io.Reader | null): [PrivateKey | null, $.GoError] {
135
+ return [null, $.newError(`crypto/ecdh: ${this.name} is not implemented in GoScript`)]
136
+ }
137
+
138
+ public NewPrivateKey(_key: $.Bytes): [PrivateKey | null, $.GoError] {
139
+ return [null, $.newError(`crypto/ecdh: ${this.name} is not implemented in GoScript`)]
140
+ }
141
+
142
+ public NewPublicKey(_key: $.Bytes): [PublicKey | null, $.GoError] {
143
+ return [null, $.newError(`crypto/ecdh: ${this.name} is not implemented in GoScript`)]
144
+ }
145
+
146
+ public String(): string {
147
+ return this.name
148
+ }
149
+
150
+ public ecdh(_local: PrivateKey | null, _remote: PublicKey | null): [$.Bytes, $.GoError] {
151
+ return [null, $.newError(`crypto/ecdh: ${this.name} is not implemented in GoScript`)]
152
+ }
153
+ }
154
+
155
+ export function P256(): Curve {
156
+ return p256
157
+ }
158
+
159
+ export function P384(): Curve {
160
+ return p384
161
+ }
162
+
163
+ export function P521(): Curve {
164
+ return p521
165
+ }
166
+
167
+ const p256 = new unsupportedCurve('P-256')
168
+ const p384 = new unsupportedCurve('P-384')
169
+ const p521 = new unsupportedCurve('P-521')
170
+
171
+ function scalarMult(scalar: $.Bytes, point: $.Bytes): Uint8Array {
172
+ const e = copyBytes(scalar)
173
+ const uBytes = copyBytes(point)
174
+ e[0] &= 248
175
+ e[31] &= 127
176
+ e[31] |= 64
177
+ uBytes[31] &= 127
178
+
179
+ const x1 = decodeLittleEndian(uBytes)
180
+ let x2 = 1n
181
+ let z2 = 0n
182
+ let x3 = x1
183
+ let z3 = 1n
184
+ let swap = 0n
185
+
186
+ for (let t = 254; t >= 0; t--) {
187
+ const k = (BigInt(e[Math.floor(t / 8)]) >> BigInt(t & 7)) & 1n
188
+ swap ^= k
189
+ ;[x2, x3] = cswap(swap, x2, x3)
190
+ ;[z2, z3] = cswap(swap, z2, z3)
191
+ swap = k
192
+
193
+ const a = mod(x2 + z2)
194
+ const aa = mod(a * a)
195
+ const b = mod(x2 - z2)
196
+ const bb = mod(b * b)
197
+ const eDiff = mod(aa - bb)
198
+ const c = mod(x3 + z3)
199
+ const d = mod(x3 - z3)
200
+ const da = mod(d * a)
201
+ const cb = mod(c * b)
202
+ x3 = mod((da + cb) ** 2n)
203
+ z3 = mod(x1 * mod((da - cb) ** 2n))
204
+ x2 = mod(aa * bb)
205
+ z2 = mod(eDiff * mod(aa + a24 * eDiff))
206
+ }
207
+
208
+ x2 = cswap(swap, x2, x3)[0]
209
+ z2 = cswap(swap, z2, z3)[0]
210
+
211
+ return encodeLittleEndian(mod(x2 * modInverse(z2)))
212
+ }
213
+
214
+ function cswap(swap: bigint, x: bigint, y: bigint): [bigint, bigint] {
215
+ const mask = -swap
216
+ const t = mask & (x ^ y)
217
+ return [x ^ t, y ^ t]
218
+ }
219
+
220
+ function mod(value: bigint): bigint {
221
+ const result = value % p
222
+ return result >= 0n ? result : result + p
223
+ }
224
+
225
+ function modInverse(value: bigint): bigint {
226
+ let lm = 1n
227
+ let hm = 0n
228
+ let low = mod(value)
229
+ let high = p
230
+ while (low > 1n) {
231
+ const r = high / low
232
+ ;[lm, hm] = [hm - lm * r, lm]
233
+ ;[low, high] = [high - low * r, low]
234
+ }
235
+ return mod(lm)
236
+ }
237
+
238
+ function decodeLittleEndian(bytes: Uint8Array): bigint {
239
+ let out = 0n
240
+ for (let i = bytes.length - 1; i >= 0; i--) {
241
+ out = (out << 8n) | BigInt(bytes[i])
242
+ }
243
+ return out
244
+ }
245
+
246
+ function encodeLittleEndian(value: bigint): Uint8Array {
247
+ const out = new Uint8Array(x25519SharedSecretSize)
248
+ let v = mod(value)
249
+ for (let i = 0; i < out.length; i++) {
250
+ out[i] = Number(v & 0xffn)
251
+ v >>= 8n
252
+ }
253
+ return out
254
+ }
255
+
256
+ function basepoint(): Uint8Array {
257
+ const out = new Uint8Array(x25519PublicKeySize)
258
+ out[0] = 9
259
+ return out
260
+ }
261
+
262
+ function copyBytes(bytes: $.Bytes | null): Uint8Array {
263
+ return new Uint8Array($.bytesToUint8Array(bytes ?? null))
264
+ }
265
+
266
+ function bytesEqual(a: $.Bytes, b: $.Bytes): boolean {
267
+ const aa = $.bytesToUint8Array(a)
268
+ const bb = $.bytesToUint8Array(b)
269
+ return aa.length === bb.length && aa.every((v, i) => v === bb[i])
270
+ }
271
+
272
+ function isZero(bytes: Uint8Array): boolean {
273
+ return bytes.every((b) => b === 0)
274
+ }
@@ -0,0 +1,41 @@
1
+ import { describe, expect, test } from 'vitest'
2
+ import * as $ from '@goscript/builtin/index.js'
3
+
4
+ import {
5
+ GenerateKey,
6
+ PrivateKeySize,
7
+ PrivateKey_Public,
8
+ PublicKeySize,
9
+ SignatureSize,
10
+ Sign,
11
+ Verify,
12
+ } from './index.js'
13
+
14
+ describe('crypto/ed25519 override', () => {
15
+ test('generates keys and verifies signatures', async () => {
16
+ const [pub, priv, err] = await GenerateKey(null)
17
+ expect(err).toBeNull()
18
+ expect($.len(pub)).toBe(PublicKeySize)
19
+ expect($.len(priv)).toBe(PrivateKeySize)
20
+
21
+ const message = $.stringToBytes('goscript')
22
+ const sig = await Sign(priv, message)
23
+ expect($.len(sig)).toBe(SignatureSize)
24
+ expect(await Verify(pub, message, sig)).toBe(true)
25
+ expect(await Verify(pub, $.stringToBytes('wrong'), sig)).toBe(false)
26
+ })
27
+
28
+ test('boxes public keys as crypto public keys', async () => {
29
+ const [pub, priv, err] = await GenerateKey(null)
30
+ expect(err).toBeNull()
31
+
32
+ const boxed = PrivateKey_Public(priv)
33
+ const [unboxed, ok] = $.typeAssertTuple<Uint8Array>(
34
+ boxed,
35
+ 'ed25519.PublicKey',
36
+ )
37
+ expect(ok).toBe(true)
38
+ expect(Array.from(unboxed)).toEqual(Array.from(pub))
39
+ expect((boxed as any).Equal(boxed)).toBe(true)
40
+ })
41
+ })