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
@@ -1,38 +1,99 @@
1
- import { varRef } from './varRef.js';
1
+ import { isVarRef, varRef } from './varRef.js';
2
+ export class GoBinaryString extends String {
3
+ bytes;
4
+ constructor(bytes) {
5
+ super(bytesToBinaryString(bytes));
6
+ this.bytes = bytes.slice();
7
+ }
8
+ toString() {
9
+ return bytesToBinaryString(this.bytes);
10
+ }
11
+ valueOf() {
12
+ return this.toString();
13
+ }
14
+ [Symbol.toPrimitive]() {
15
+ return this.toString();
16
+ }
17
+ }
18
+ function isGoStringValue(value) {
19
+ return typeof value === 'string' || value instanceof GoBinaryString;
20
+ }
21
+ function goStringBytes(str) {
22
+ if (str instanceof GoBinaryString) {
23
+ return str.bytes.slice();
24
+ }
25
+ return new TextEncoder().encode(str);
26
+ }
27
+ function goStringComparableBytes(value) {
28
+ if (isGoStringValue(value)) {
29
+ return goStringBytes(value);
30
+ }
31
+ if (value instanceof Uint8Array) {
32
+ return value;
33
+ }
34
+ if (value === null || value === undefined) {
35
+ return new Uint8Array(0);
36
+ }
37
+ return Uint8Array.from(asArray(value));
38
+ }
39
+ function goStringFromBytes(bytes) {
40
+ try {
41
+ return new TextDecoder('utf-8', { fatal: true }).decode(bytes);
42
+ }
43
+ catch {
44
+ return new GoBinaryString(bytes);
45
+ }
46
+ }
2
47
  const addressStride = 0x100000000;
3
48
  let nextAddressBase = 1;
4
49
  const addressBases = new WeakMap();
50
+ function sliceIndexProperty(prop) {
51
+ if (typeof prop !== 'string' || prop.length === 0) {
52
+ return -1;
53
+ }
54
+ let index = 0;
55
+ for (let i = 0; i < prop.length; i++) {
56
+ const digit = prop.charCodeAt(i) - 48;
57
+ if (digit < 0 || digit > 9) {
58
+ return -1;
59
+ }
60
+ index = index * 10 + digit;
61
+ }
62
+ return index;
63
+ }
5
64
  /**
6
65
  * wrapSliceProxy wraps a SliceProxy in a Proxy to intercept index access
7
66
  * and route it through the backing array.
8
67
  */
9
68
  function wrapSliceProxy(proxy) {
69
+ const meta = proxy.__meta__;
70
+ meta.target = proxy;
10
71
  const handler = {
11
72
  get(target, prop) {
12
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
13
- const index = Number(prop);
14
- if (index >= 0 && index < target.__meta__.length) {
15
- return target.__meta__.backing[target.__meta__.offset + index];
73
+ const index = sliceIndexProperty(prop);
74
+ if (index >= 0) {
75
+ if (index < meta.length) {
76
+ return meta.backing[meta.offset + index];
16
77
  }
17
- throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
78
+ throw new Error(`Slice index out of range: ${index} >= ${meta.length}`);
18
79
  }
19
80
  if (prop === 'length') {
20
- return target.__meta__.length;
81
+ return meta.length;
21
82
  }
22
83
  if (prop === '__meta__') {
23
- return target.__meta__;
84
+ return meta;
24
85
  }
25
86
  return Reflect.get(target, prop);
26
87
  },
27
88
  set(target, prop, value) {
28
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
29
- const index = Number(prop);
30
- if (index >= 0 && index < target.__meta__.length) {
31
- target.__meta__.backing[target.__meta__.offset + index] = value;
89
+ const index = sliceIndexProperty(prop);
90
+ if (index >= 0) {
91
+ if (index < meta.length) {
92
+ meta.backing[meta.offset + index] = value;
32
93
  target[index] = value; // Also update the proxy target for consistency
33
94
  return true;
34
95
  }
35
- throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
96
+ throw new Error(`Slice index out of range: ${index} >= ${meta.length}`);
36
97
  }
37
98
  if (prop === 'length' || prop === '__meta__') {
38
99
  return false;
@@ -42,6 +103,17 @@ function wrapSliceProxy(proxy) {
42
103
  };
43
104
  return new Proxy(proxy, handler);
44
105
  }
106
+ function sliceProxyFromBacking(backing, offset, length, capacity, target) {
107
+ const proxyTargetArray = (target ?? new Array(length));
108
+ proxyTargetArray.length = length;
109
+ if (target === undefined) {
110
+ for (let i = 0; i < length; i++) {
111
+ proxyTargetArray[i] = backing[offset + i];
112
+ }
113
+ }
114
+ proxyTargetArray.__meta__ = { backing, offset, length, capacity };
115
+ return wrapSliceProxy(proxyTargetArray);
116
+ }
45
117
  // asArray converts a slice to a JavaScript array.
46
118
  export function asArray(slice) {
47
119
  if (slice === null || slice === undefined) {
@@ -102,6 +174,21 @@ function normalizeSliceIndex(value) {
102
174
  }
103
175
  return Number(value);
104
176
  }
177
+ function byteSliceMeta(slice) {
178
+ return slice.__meta__;
179
+ }
180
+ function byteSliceView(backing, offset, length, capacity) {
181
+ const view = backing.subarray(offset, offset + length);
182
+ if (capacity !== length) {
183
+ view.__meta__ = {
184
+ backing: backing,
185
+ offset,
186
+ length,
187
+ capacity,
188
+ };
189
+ }
190
+ return view;
191
+ }
105
192
  /**
106
193
  * isSliceProxy checks if a slice is a SliceProxy (has __meta__ property)
107
194
  * This is an alias for isComplexSlice for better type hinting
@@ -125,21 +212,7 @@ export const makeSlice = (length, capacity, typeHint, zeroFactory) => {
125
212
  if (actualCapacity === length) {
126
213
  return new Uint8Array(length);
127
214
  }
128
- // If capacity > length, create a SliceProxy backed by a Uint8Array
129
- const backingUint8 = new Uint8Array(actualCapacity);
130
- const backingNumbers = Array.from(backingUint8); // Convert to number[] for backing
131
- const proxyTargetArray = new Array(length);
132
- for (let i = 0; i < length; i++) {
133
- proxyTargetArray[i] = 0; // Initialize with zeros
134
- }
135
- const proxy = proxyTargetArray;
136
- proxy.__meta__ = {
137
- backing: backingNumbers,
138
- offset: 0,
139
- length: length,
140
- capacity: actualCapacity,
141
- };
142
- return wrapSliceProxy(proxy);
215
+ return byteSliceView(new Uint8Array(actualCapacity), 0, length, actualCapacity);
143
216
  }
144
217
  const actualCapacity = capacity === undefined ? length : capacity;
145
218
  if (length < 0 || actualCapacity < 0 || length > actualCapacity) {
@@ -161,12 +234,11 @@ export const makeSlice = (length, capacity, typeHint, zeroFactory) => {
161
234
  }
162
235
  };
163
236
  const backingArr = new Array(actualCapacity);
164
- // Initialize the relevant part of the backing array
165
- for (let i = 0; i < length; i++) {
237
+ // Go zero-initializes the whole backing array. Elements beyond len become
238
+ // observable when a slice is resliced up to cap.
239
+ for (let i = 0; i < actualCapacity; i++) {
166
240
  backingArr[i] = zeroValue();
167
241
  }
168
- // The rest of backingArr (from length to actualCapacity-1) remains uninitialized (undefined),
169
- // representing available capacity.
170
242
  // OPTIMIZATION: If length equals capacity, return backing array directly
171
243
  if (length === actualCapacity) {
172
244
  return backingArr;
@@ -187,9 +259,9 @@ export const makeSlice = (length, capacity, typeHint, zeroFactory) => {
187
259
  // Create a proper Proxy with the handler for SliceProxy behavior
188
260
  const handler = {
189
261
  get(target, prop) {
190
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
191
- const index = Number(prop);
192
- if (index >= 0 && index < target.__meta__.length) {
262
+ const index = sliceIndexProperty(prop);
263
+ if (index >= 0) {
264
+ if (index < target.__meta__.length) {
193
265
  return target.__meta__.backing[target.__meta__.offset + index];
194
266
  }
195
267
  throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
@@ -203,9 +275,9 @@ export const makeSlice = (length, capacity, typeHint, zeroFactory) => {
203
275
  return Reflect.get(target, prop);
204
276
  },
205
277
  set(target, prop, value) {
206
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
207
- const index = Number(prop);
208
- if (index >= 0 && index < target.__meta__.length) {
278
+ const index = sliceIndexProperty(prop);
279
+ if (index >= 0) {
280
+ if (index < target.__meta__.length) {
209
281
  target.__meta__.backing[target.__meta__.offset + index] = value;
210
282
  target[index] = value; // Also update the proxy target for consistency
211
283
  return true;
@@ -222,14 +294,15 @@ export const makeSlice = (length, capacity, typeHint, zeroFactory) => {
222
294
  };
223
295
  export function goSlice(// T can be number for Uint8Array case
224
296
  s, low, high, max) {
297
+ s = collectionValue(s);
225
298
  low = normalizeSliceIndex(low);
226
299
  high = normalizeSliceIndex(high);
227
300
  max = normalizeSliceIndex(max);
228
301
  const handler = {
229
302
  get(target, prop) {
230
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
231
- const index = Number(prop);
232
- if (index >= 0 && index < target.__meta__.length) {
303
+ const index = sliceIndexProperty(prop);
304
+ if (index >= 0) {
305
+ if (index < target.__meta__.length) {
233
306
  return target.__meta__.backing[target.__meta__.offset + index];
234
307
  }
235
308
  throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
@@ -252,9 +325,9 @@ s, low, high, max) {
252
325
  return Reflect.get(target, prop);
253
326
  },
254
327
  set(target, prop, value) {
255
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
256
- const index = Number(prop);
257
- if (index >= 0 && index < target.__meta__.length) {
328
+ const index = sliceIndexProperty(prop);
329
+ if (index >= 0) {
330
+ if (index < target.__meta__.length) {
258
331
  target.__meta__.backing[target.__meta__.offset + index] = value;
259
332
  target[index] = value;
260
333
  return true;
@@ -275,45 +348,29 @@ s, low, high, max) {
275
348
  },
276
349
  };
277
350
  if (s instanceof Uint8Array) {
351
+ const meta = byteSliceMeta(s);
352
+ const metaBacking = meta?.backing;
353
+ const backing = metaBacking instanceof Uint8Array ? metaBacking : s;
354
+ const baseOffset = meta?.offset ?? 0;
355
+ const baseCapacity = meta?.capacity ?? s.length;
278
356
  const actualLow = low ?? 0;
279
357
  const actualHigh = high ?? s.length;
280
- if (actualLow < 0 || actualHigh < actualLow || actualHigh > s.length) {
281
- throw new Error(`Invalid slice indices: low ${actualLow}, high ${actualHigh} for Uint8Array of length ${s.length}`);
358
+ if (actualLow < 0 ||
359
+ actualHigh < actualLow ||
360
+ actualLow > baseCapacity ||
361
+ actualHigh > baseCapacity) {
362
+ throw new Error(`Invalid slice indices: low ${actualLow}, high ${actualHigh} for Uint8Array with capacity ${baseCapacity}`);
282
363
  }
283
364
  const newLength = actualHigh - actualLow;
284
365
  if (max !== undefined) {
285
- if (max < actualHigh || max > s.length) {
366
+ if (max < actualHigh || max > baseCapacity) {
286
367
  // max is relative to the original s.length (capacity)
287
- throw new Error(`Invalid max index: ${max}. Constraints: low ${actualLow} <= high ${actualHigh} <= max <= original_length ${s.length}`);
368
+ throw new Error(`Invalid max index: ${max}. Constraints: low ${actualLow} <= high ${actualHigh} <= max <= capacity ${baseCapacity}`);
288
369
  }
289
370
  const newCap = max - actualLow; // Capacity of the new slice view
290
- if (newCap !== newLength) {
291
- const proxyTarget = new Array(newLength);
292
- proxyTarget.__meta__ = {
293
- backing: s,
294
- offset: actualLow,
295
- length: newLength,
296
- capacity: newCap,
297
- };
298
- return new Proxy(proxyTarget, handler);
299
- }
300
- else {
301
- // newCap === newLength, standard Uint8Array is fine.
302
- return s.subarray(actualLow, actualHigh); // T is number
303
- }
371
+ return byteSliceView(backing, baseOffset + actualLow, newLength, newCap);
304
372
  }
305
- if (actualHigh !== s.length) {
306
- const proxyTarget = new Array(newLength);
307
- proxyTarget.__meta__ = {
308
- backing: s,
309
- offset: actualLow,
310
- length: newLength,
311
- capacity: s.length - actualLow,
312
- };
313
- return new Proxy(proxyTarget, handler);
314
- }
315
- // max is not defined and length equals capacity, return the Uint8Array view directly.
316
- return s.subarray(actualLow, actualHigh); // T is number
373
+ return byteSliceView(backing, baseOffset + actualLow, newLength, baseCapacity - actualLow);
317
374
  }
318
375
  // Handle nil slices - in Go, slicing a nil slice with valid bounds returns nil
319
376
  if (s === null || s === undefined) {
@@ -385,7 +442,7 @@ s, low, high, max) {
385
442
  const newLength = high - low;
386
443
  const newOffset = oldOffset + low;
387
444
  // OPTIMIZATION: If the result would have offset=0 and length=capacity, return backing directly
388
- if (newOffset === 0 && newLength === newCap) {
445
+ if (newOffset === 0 && newLength === newCap && backing.length === newLength) {
389
446
  return backing;
390
447
  }
391
448
  // Create an array-like target with the correct length
@@ -429,9 +486,9 @@ export const arrayToSlice = (arr, depth = 1) => {
429
486
  };
430
487
  const handler = {
431
488
  get(target, prop) {
432
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
433
- const index = Number(prop);
434
- if (index >= 0 && index < target.__meta__.length) {
489
+ const index = sliceIndexProperty(prop);
490
+ if (index >= 0) {
491
+ if (index < target.__meta__.length) {
435
492
  return target.__meta__.backing[target.__meta__.offset + index];
436
493
  }
437
494
  throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
@@ -454,9 +511,9 @@ export const arrayToSlice = (arr, depth = 1) => {
454
511
  return Reflect.get(target, prop);
455
512
  },
456
513
  set(target, prop, value) {
457
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
458
- const index = Number(prop);
459
- if (index >= 0 && index < target.__meta__.length) {
514
+ const index = sliceIndexProperty(prop);
515
+ if (index >= 0) {
516
+ if (index < target.__meta__.length) {
460
517
  target.__meta__.backing[target.__meta__.offset + index] = value;
461
518
  return true;
462
519
  }
@@ -491,26 +548,34 @@ export const arrayToSlice = (arr, depth = 1) => {
491
548
  * @returns The length of the collection.
492
549
  */
493
550
  export const len = (obj) => {
551
+ obj = collectionValue(obj);
494
552
  if (obj === null || obj === undefined) {
495
553
  return 0;
496
554
  }
497
555
  if (typeof obj === 'string') {
498
- return stringLen(obj); // Call new stringLen for strings
499
- }
500
- if (obj instanceof Map || obj instanceof Set) {
501
- return obj.size;
556
+ return stringLen(obj);
502
557
  }
503
558
  if (obj instanceof Uint8Array) {
504
559
  return obj.length;
505
560
  }
506
- if (typeof obj.len === 'function') {
507
- return obj.len();
561
+ if (Array.isArray(obj)) {
562
+ const meta = obj.__meta__;
563
+ if (meta !== undefined) {
564
+ return meta.length;
565
+ }
566
+ return obj.length;
567
+ }
568
+ if (obj instanceof Map || obj instanceof Set) {
569
+ return obj.size;
570
+ }
571
+ if (obj instanceof GoBinaryString) {
572
+ return stringLen(obj);
508
573
  }
509
574
  if (isComplexSlice(obj)) {
510
575
  return obj.__meta__.length;
511
576
  }
512
- if (Array.isArray(obj)) {
513
- return obj.length;
577
+ if (typeof obj.len === 'function') {
578
+ return obj.len();
514
579
  }
515
580
  throw new Error('cannot determine len of this type');
516
581
  };
@@ -520,18 +585,22 @@ export const len = (obj) => {
520
585
  * @returns The capacity of the slice.
521
586
  */
522
587
  export const cap = (obj) => {
588
+ obj = collectionValue(obj);
523
589
  if (obj === null || obj === undefined) {
524
590
  return 0;
525
591
  }
526
- if (obj instanceof Uint8Array) {
527
- return obj.length; // Uint8Array capacity is its length
528
- }
529
592
  if (isComplexSlice(obj)) {
530
593
  return obj.__meta__.capacity;
531
594
  }
595
+ if (obj instanceof Uint8Array) {
596
+ return obj.length; // Uint8Array capacity is its length
597
+ }
532
598
  if (Array.isArray(obj)) {
533
599
  return obj.length;
534
600
  }
601
+ if (typeof obj.cap === 'function') {
602
+ return obj.cap();
603
+ }
535
604
  return 0;
536
605
  };
537
606
  export function append(slice, ...elements) {
@@ -541,48 +610,7 @@ export function append(slice, ...elements) {
541
610
  const produceUint8Array = inputIsUint8Array;
542
611
  // If producing Uint8Array, all elements must be numbers and potentially flattened from other Uint8Arrays/number slices.
543
612
  if (produceUint8Array) {
544
- let combinedBytes = [];
545
- // Add bytes from the original slice if it exists and is numeric.
546
- if (inputIsUint8Array) {
547
- appendBytes(combinedBytes, slice);
548
- }
549
- else if (slice !== null && slice !== undefined) {
550
- // Original was Slice<number> or number[]
551
- const sliceLen = len(slice);
552
- for (let i = 0; i < sliceLen; i++) {
553
- const val = slice[i];
554
- if (typeof val !== 'number') {
555
- throw new Error('Cannot produce Uint8Array: original slice contains non-number elements.');
556
- }
557
- combinedBytes.push(val);
558
- }
559
- }
560
- // Add bytes from the varargs elements.
561
- // For Uint8Array, elements are always flattened if they are slices/Uint8Arrays.
562
- for (const item of elements) {
563
- if (item instanceof Uint8Array) {
564
- appendBytes(combinedBytes, item);
565
- }
566
- else if (isComplexSlice(item) || Array.isArray(item)) {
567
- const itemLen = len(item);
568
- for (let i = 0; i < itemLen; i++) {
569
- const val = item[i];
570
- if (typeof val !== 'number') {
571
- throw new Error('Cannot produce Uint8Array: appended elements contain non-numbers.');
572
- }
573
- combinedBytes.push(val);
574
- }
575
- }
576
- else {
577
- if (typeof item !== 'number') {
578
- throw new Error('Cannot produce Uint8Array: appended elements contain non-numbers.');
579
- }
580
- combinedBytes.push(item);
581
- }
582
- }
583
- const newArr = new Uint8Array(combinedBytes.length);
584
- newArr.set(combinedBytes);
585
- return newArr;
613
+ return appendByteSlice(slice, elements);
586
614
  }
587
615
  // Handle generic Slice<T> (non-Uint8Array result).
588
616
  // In this case, `elements` are treated as individual items to append,
@@ -591,45 +619,44 @@ export function append(slice, ...elements) {
591
619
  if (numAdded === 0) {
592
620
  return slice;
593
621
  }
594
- let originalElements = [];
622
+ let originalElements;
623
+ let oldLength = 0;
595
624
  let oldCapacity;
596
625
  let isOriginalComplex = false;
597
626
  let originalBacking = undefined;
627
+ let originalTarget = undefined;
598
628
  let originalOffset = 0;
599
629
  if (slice === null || slice === undefined) {
600
630
  oldCapacity = 0;
601
631
  }
602
632
  else if (isComplexSlice(slice)) {
603
633
  const meta = slice.__meta__;
604
- for (let i = 0; i < meta.length; i++)
605
- originalElements.push(meta.backing[meta.offset + i]);
634
+ oldLength = meta.length;
606
635
  oldCapacity = meta.capacity;
607
636
  isOriginalComplex = true;
608
637
  originalBacking = meta.backing;
638
+ originalTarget = meta.target;
609
639
  originalOffset = meta.offset;
610
640
  }
611
641
  else {
612
642
  // Simple T[] array
613
643
  originalElements = slice.slice();
614
- oldCapacity = slice.length;
644
+ oldLength = originalElements.length;
645
+ oldCapacity = oldLength;
615
646
  }
616
- const oldLength = originalElements.length;
617
647
  const newLength = oldLength + numAdded;
618
648
  // Case 1: Modify in-place if original was SliceProxy and has enough capacity.
619
649
  if (isOriginalComplex && newLength <= oldCapacity && originalBacking) {
620
650
  for (let i = 0; i < numAdded; i++) {
621
651
  originalBacking[originalOffset + oldLength + i] = elements[i];
622
652
  }
623
- const resultProxy = new Array(newLength);
624
- for (let i = 0; i < newLength; i++)
625
- resultProxy[i] = originalBacking[originalOffset + i];
626
- resultProxy.__meta__ = {
627
- backing: originalBacking,
628
- offset: originalOffset,
629
- length: newLength,
630
- capacity: oldCapacity,
631
- };
632
- return wrapSliceProxy(resultProxy);
653
+ const target = originalTarget;
654
+ if (target !== undefined) {
655
+ for (let i = 0; i < numAdded; i++) {
656
+ target[oldLength + i] = elements[i];
657
+ }
658
+ }
659
+ return sliceProxyFromBacking(originalBacking, originalOffset, newLength, oldCapacity, target);
633
660
  }
634
661
  // Case 2: Reallocation is needed.
635
662
  let newCapacity = oldCapacity;
@@ -646,26 +673,80 @@ export function append(slice, ...elements) {
646
673
  newCapacity = newLength;
647
674
  }
648
675
  const newBacking = new Array(newCapacity);
649
- for (let i = 0; i < oldLength; i++) {
650
- newBacking[i] = originalElements[i];
676
+ if (isOriginalComplex && originalBacking) {
677
+ for (let i = 0; i < oldLength; i++) {
678
+ newBacking[i] = originalBacking[originalOffset + i];
679
+ }
680
+ }
681
+ else if (originalElements !== undefined) {
682
+ for (let i = 0; i < oldLength; i++) {
683
+ newBacking[i] = originalElements[i];
684
+ }
651
685
  }
652
686
  for (let i = 0; i < numAdded; i++) {
653
687
  newBacking[oldLength + i] = elements[i];
654
688
  }
655
- const resultProxy = new Array(newLength);
656
- for (let i = 0; i < newLength; i++)
657
- resultProxy[i] = newBacking[i];
658
- resultProxy.__meta__ = {
659
- backing: newBacking,
660
- offset: 0,
661
- length: newLength,
662
- capacity: newCapacity,
663
- };
664
- return wrapSliceProxy(resultProxy);
689
+ return sliceProxyFromBacking(newBacking, 0, newLength, newCapacity);
690
+ }
691
+ function appendByteSlice(slice, elements) {
692
+ const meta = byteSliceMeta(slice);
693
+ const metaBacking = meta?.backing;
694
+ const backing = metaBacking instanceof Uint8Array ? metaBacking : slice;
695
+ const offset = meta?.offset ?? 0;
696
+ const oldLength = slice.length;
697
+ const oldCapacity = meta?.capacity ?? oldLength;
698
+ let added = 0;
699
+ for (const item of elements) {
700
+ added += byteElementLength(item);
701
+ }
702
+ const newLength = oldLength + added;
703
+ if (newLength <= oldCapacity) {
704
+ const view = byteSliceView(backing, offset, newLength, oldCapacity);
705
+ writeByteElements(view, oldLength, elements);
706
+ return view;
707
+ }
708
+ const next = new Uint8Array(newLength);
709
+ next.set(slice);
710
+ writeByteElements(next, oldLength, elements);
711
+ return next;
665
712
  }
666
- function appendBytes(dst, src) {
667
- for (let i = 0; i < src.length; i++) {
668
- dst.push(src[i]);
713
+ function byteElementLength(item) {
714
+ if (item instanceof Uint8Array) {
715
+ return item.length;
716
+ }
717
+ if (isComplexSlice(item) || Array.isArray(item)) {
718
+ return len(item);
719
+ }
720
+ if (typeof item !== 'number') {
721
+ throw new Error('Cannot produce Uint8Array: appended elements contain non-numbers.');
722
+ }
723
+ return 1;
724
+ }
725
+ function writeByteElements(dst, offset, elements) {
726
+ let cursor = offset;
727
+ for (const item of elements) {
728
+ if (item instanceof Uint8Array) {
729
+ dst.set(item, cursor);
730
+ cursor += item.length;
731
+ continue;
732
+ }
733
+ if (isComplexSlice(item) || Array.isArray(item)) {
734
+ const itemLen = len(item);
735
+ for (let i = 0; i < itemLen; i++) {
736
+ const value = item[i];
737
+ if (typeof value !== 'number') {
738
+ throw new Error('Cannot produce Uint8Array: appended elements contain non-numbers.');
739
+ }
740
+ dst[cursor] = value;
741
+ cursor++;
742
+ }
743
+ continue;
744
+ }
745
+ if (typeof item !== 'number') {
746
+ throw new Error('Cannot produce Uint8Array: appended elements contain non-numbers.');
747
+ }
748
+ dst[cursor] = item;
749
+ cursor++;
669
750
  }
670
751
  }
671
752
  export function copy(dst, src) {
@@ -673,7 +754,7 @@ export function copy(dst, src) {
673
754
  return 0;
674
755
  }
675
756
  // Handle string source first
676
- if (typeof src === 'string') {
757
+ if (isGoStringValue(src)) {
677
758
  return copyFromString(dst, src);
678
759
  }
679
760
  if (src === null) {
@@ -708,26 +789,27 @@ export function copy(dst, src) {
708
789
  */
709
790
  function copyFromString(dst, src) {
710
791
  const dstLen = dst instanceof Uint8Array ? dst.length : len(dst);
711
- const count = Math.min(dstLen, src.length);
792
+ const bytes = goStringBytes(src);
793
+ const count = Math.min(dstLen, bytes.length);
712
794
  if (count === 0) {
713
795
  return 0;
714
796
  }
715
797
  if (dst instanceof Uint8Array) {
716
798
  for (let i = 0; i < count; i++) {
717
- dst[i] = src.charCodeAt(i);
799
+ dst[i] = bytes[i];
718
800
  }
719
801
  }
720
802
  else if (isComplexSlice(dst)) {
721
803
  const dstMeta = dst.__meta__;
722
804
  for (let i = 0; i < count; i++) {
723
- const byteVal = src.charCodeAt(i);
805
+ const byteVal = bytes[i];
724
806
  dstMeta.backing[dstMeta.offset + i] = byteVal;
725
807
  dst[i] = byteVal;
726
808
  }
727
809
  }
728
810
  else if (Array.isArray(dst)) {
729
811
  for (let i = 0; i < count; i++) {
730
- dst[i] = src.charCodeAt(i);
812
+ dst[i] = bytes[i];
731
813
  }
732
814
  }
733
815
  return count;
@@ -736,16 +818,9 @@ function copyFromString(dst, src) {
736
818
  * Helper: Copy from Slice<number> to Uint8Array
737
819
  */
738
820
  function copyToUint8Array(dst, src, count) {
739
- if (isComplexSlice(src)) {
740
- const srcMeta = src.__meta__;
741
- for (let i = 0; i < count; i++) {
742
- dst[i] = srcMeta.backing[srcMeta.offset + i];
743
- }
744
- }
745
- else if (Array.isArray(src)) {
746
- for (let i = 0; i < count; i++) {
747
- dst[i] = src[i];
748
- }
821
+ const values = copySliceValues(src, count);
822
+ for (let i = 0; i < count; i++) {
823
+ dst[i] = values[i];
749
824
  }
750
825
  return count;
751
826
  }
@@ -753,16 +828,17 @@ function copyToUint8Array(dst, src, count) {
753
828
  * Helper: Copy from Uint8Array to Slice<T>
754
829
  */
755
830
  function copyFromUint8Array(dst, src, count) {
831
+ const values = Array.from(src.subarray(0, count));
756
832
  if (isComplexSlice(dst)) {
757
833
  const dstMeta = dst.__meta__;
758
834
  for (let i = 0; i < count; i++) {
759
- dstMeta.backing[dstMeta.offset + i] = src[i];
760
- dst[i] = src[i];
835
+ dstMeta.backing[dstMeta.offset + i] = values[i];
836
+ dst[i] = values[i];
761
837
  }
762
838
  }
763
839
  else if (Array.isArray(dst)) {
764
840
  for (let i = 0; i < count; i++) {
765
- dst[i] = src[i];
841
+ dst[i] = values[i];
766
842
  }
767
843
  }
768
844
  return count;
@@ -771,38 +847,36 @@ function copyFromUint8Array(dst, src, count) {
771
847
  * Helper: Copy between two Slice<T> instances
772
848
  */
773
849
  function copyBetweenSlices(dst, src, count) {
850
+ const values = copySliceValues(src, count);
774
851
  if (isComplexSlice(dst)) {
775
852
  const dstMeta = dst.__meta__;
776
- if (isComplexSlice(src)) {
777
- const srcMeta = src.__meta__;
778
- for (let i = 0; i < count; i++) {
779
- dstMeta.backing[dstMeta.offset + i] =
780
- srcMeta.backing[srcMeta.offset + i];
781
- dst[i] = srcMeta.backing[srcMeta.offset + i];
782
- }
783
- }
784
- else if (Array.isArray(src)) {
785
- for (let i = 0; i < count; i++) {
786
- dstMeta.backing[dstMeta.offset + i] = src[i];
787
- dst[i] = src[i];
788
- }
853
+ for (let i = 0; i < count; i++) {
854
+ dstMeta.backing[dstMeta.offset + i] = values[i];
855
+ dst[i] = values[i];
789
856
  }
790
857
  }
791
858
  else if (Array.isArray(dst)) {
792
- if (isComplexSlice(src)) {
793
- const srcMeta = src.__meta__;
794
- for (let i = 0; i < count; i++) {
795
- dst[i] = srcMeta.backing[srcMeta.offset + i];
796
- }
797
- }
798
- else if (Array.isArray(src)) {
799
- for (let i = 0; i < count; i++) {
800
- dst[i] = src[i];
801
- }
859
+ for (let i = 0; i < count; i++) {
860
+ dst[i] = values[i];
802
861
  }
803
862
  }
804
863
  return count;
805
864
  }
865
+ function copySliceValues(src, count) {
866
+ const values = new Array(count);
867
+ if (isComplexSlice(src)) {
868
+ const srcMeta = src.__meta__;
869
+ for (let i = 0; i < count; i++) {
870
+ values[i] = srcMeta.backing[srcMeta.offset + i];
871
+ }
872
+ }
873
+ else if (Array.isArray(src)) {
874
+ for (let i = 0; i < count; i++) {
875
+ values[i] = src[i];
876
+ }
877
+ }
878
+ return values;
879
+ }
806
880
  /**
807
881
  * Accesses an element at a specific index for various Go-like types (string, slice, array).
808
882
  * Mimics Go's indexing behavior: `myCollection[index]`
@@ -818,7 +892,7 @@ export function index(collection, index) {
818
892
  if (collection === null || collection === undefined) {
819
893
  throw new Error('runtime error: index on nil or undefined collection');
820
894
  }
821
- if (typeof collection === 'string') {
895
+ if (isGoStringValue(collection)) {
822
896
  return indexString(collection, index); // Use the existing indexString for byte access
823
897
  }
824
898
  else if (collection instanceof Uint8Array) {
@@ -861,6 +935,8 @@ export function indexRef(collection, index) {
861
935
  },
862
936
  __isVarRef: true,
863
937
  __goAddress: () => indexAddress(collection, index),
938
+ __goCollection: collection,
939
+ __goIndex: index,
864
940
  };
865
941
  }
866
942
  if (isComplexSlice(collection)) {
@@ -877,6 +953,8 @@ export function indexRef(collection, index) {
877
953
  },
878
954
  __isVarRef: true,
879
955
  __goAddress: () => indexAddress(collection, index),
956
+ __goCollection: collection,
957
+ __goIndex: index,
880
958
  };
881
959
  }
882
960
  if (Array.isArray(collection)) {
@@ -892,10 +970,25 @@ export function indexRef(collection, index) {
892
970
  },
893
971
  __isVarRef: true,
894
972
  __goAddress: () => indexAddress(collection, index),
973
+ __goCollection: collection,
974
+ __goIndex: index,
895
975
  };
896
976
  }
897
977
  throw new Error('runtime error: index on unsupported type');
898
978
  }
979
+ /**
980
+ * arrayPointerFromIndexRef turns &slice[i] into a pointer to an N-element array
981
+ * view. This models unsafe conversions such as (*[64]byte)(unsafe.Pointer(&b[0]))
982
+ * for packages that immediately slice or index the resulting array pointer.
983
+ */
984
+ export function arrayPointerFromIndexRef(ref, length) {
985
+ const collection = ref.__goCollection;
986
+ if (collection === undefined) {
987
+ throw new Error('unsafe array pointer requires an indexed collection reference');
988
+ }
989
+ const index = ref.__goIndex ?? 0;
990
+ return varRef(goSlice(collection, index, index + length));
991
+ }
899
992
  /**
900
993
  * indexAddress returns a stable synthetic address for an addressable slice or
901
994
  * array element.
@@ -997,7 +1090,7 @@ export const byte = (n) => {
997
1090
  * @throws Error if index is out of bounds.
998
1091
  */
999
1092
  export const indexString = (str, index) => {
1000
- if (typeof str !== 'string') {
1093
+ if (!isGoStringValue(str)) {
1001
1094
  // Bytes - access directly
1002
1095
  if (str instanceof Uint8Array) {
1003
1096
  if (index < 0 || index >= str.length) {
@@ -1014,7 +1107,7 @@ export const indexString = (str, index) => {
1014
1107
  }
1015
1108
  return str[index];
1016
1109
  }
1017
- const bytes = new TextEncoder().encode(str);
1110
+ const bytes = goStringBytes(str);
1018
1111
  if (index < 0 || index >= bytes.length) {
1019
1112
  throw new Error(`runtime error: index out of range [${index}] with length ${bytes.length}`);
1020
1113
  }
@@ -1027,7 +1120,7 @@ export const indexString = (str, index) => {
1027
1120
  * @returns The number of bytes in the UTF-8 representation of the string.
1028
1121
  */
1029
1122
  export const stringLen = (str) => {
1030
- return new TextEncoder().encode(str).length;
1123
+ return goStringBytes(str).length;
1031
1124
  };
1032
1125
  /**
1033
1126
  * Slices a string based on byte indices.
@@ -1039,7 +1132,7 @@ export const stringLen = (str) => {
1039
1132
  * @throws Error if the slice would create invalid UTF-8.
1040
1133
  */
1041
1134
  export const sliceString = (str, low, high) => {
1042
- const bytes = new TextEncoder().encode(str);
1135
+ const bytes = goStringBytes(str);
1043
1136
  const actualLow = low === undefined ? 0 : low;
1044
1137
  const actualHigh = high === undefined ? bytes.length : high;
1045
1138
  if (actualLow < 0 || actualHigh < actualLow || actualHigh > bytes.length) {
@@ -1055,18 +1148,7 @@ export const sliceString = (str, low, high) => {
1055
1148
  }
1056
1149
  throw new Error(`runtime error: slice bounds out of range [${actualLow}:${actualHigh}] with length ${bytes.length}`);
1057
1150
  }
1058
- const slicedBytes = bytes.subarray(actualLow, actualHigh);
1059
- try {
1060
- // Attempt to decode with strict UTF-8 validation
1061
- const result = new TextDecoder('utf-8', { fatal: true }).decode(slicedBytes);
1062
- return result;
1063
- }
1064
- catch (e) {
1065
- // If we get here, the slice would create invalid UTF-8
1066
- // This is a fundamental limitation of JavaScript string handling
1067
- throw new Error(`Cannot slice string at byte indices [${actualLow}:${actualHigh}] because it would create invalid UTF-8. ` +
1068
- `This is a limitation of JavaScript's string handling.`, { cause: e });
1069
- }
1151
+ return goStringFromBytes(bytes.subarray(actualLow, actualHigh));
1070
1152
  };
1071
1153
  /**
1072
1154
  * Converts a Slice<number> (byte array) to a string using TextDecoder.
@@ -1080,7 +1162,7 @@ export const bytesToString = (bytes) => {
1080
1162
  if (typeof bytes === 'string')
1081
1163
  return bytes;
1082
1164
  if (bytes instanceof Uint8Array)
1083
- return decodeGoStringBytes(bytes);
1165
+ return goStringFromBytes(bytes);
1084
1166
  // Ensure we get a plain number[] for Uint8Array.from
1085
1167
  let byteArray;
1086
1168
  if (isComplexSlice(bytes)) {
@@ -1091,15 +1173,85 @@ export const bytesToString = (bytes) => {
1091
1173
  // For simple T[] slices
1092
1174
  byteArray = bytes;
1093
1175
  }
1094
- return decodeGoStringBytes(Uint8Array.from(byteArray));
1176
+ return goStringFromBytes(Uint8Array.from(byteArray));
1095
1177
  };
1096
- function decodeGoStringBytes(bytes) {
1097
- try {
1098
- return new TextDecoder('utf-8', { fatal: true }).decode(bytes);
1178
+ export function stringEqual(left, right) {
1179
+ const leftBytes = goStringComparableBytes(left);
1180
+ const rightBytes = goStringComparableBytes(right);
1181
+ if (leftBytes.length !== rightBytes.length) {
1182
+ return false;
1183
+ }
1184
+ for (let i = 0; i < leftBytes.length; i++) {
1185
+ if (leftBytes[i] !== rightBytes[i]) {
1186
+ return false;
1187
+ }
1099
1188
  }
1100
- catch {
1101
- return bytesToBinaryString(bytes);
1189
+ return true;
1190
+ }
1191
+ export function stringCompare(left, right) {
1192
+ if (!isGoStringValue(left) && !isGoStringValue(right)) {
1193
+ const leftBytes = byteStringView(left);
1194
+ const rightBytes = byteStringView(right);
1195
+ const leftLen = leftBytes.length;
1196
+ const rightLen = rightBytes.length;
1197
+ const sharedLen = Math.min(leftLen, rightLen);
1198
+ for (let i = 0; i < sharedLen; i++) {
1199
+ const diff = (leftBytes.backing[leftBytes.offset + i] ?? 0) -
1200
+ (rightBytes.backing[rightBytes.offset + i] ?? 0);
1201
+ if (diff !== 0) {
1202
+ return diff;
1203
+ }
1204
+ }
1205
+ return leftLen - rightLen;
1206
+ }
1207
+ const leftBytes = goStringComparableBytes(left);
1208
+ const rightBytes = goStringComparableBytes(right);
1209
+ const sharedLen = Math.min(leftBytes.length, rightBytes.length);
1210
+ for (let i = 0; i < sharedLen; i++) {
1211
+ const diff = leftBytes[i] - rightBytes[i];
1212
+ if (diff !== 0) {
1213
+ return diff;
1214
+ }
1102
1215
  }
1216
+ return leftBytes.length - rightBytes.length;
1217
+ }
1218
+ function byteStringView(value) {
1219
+ value = collectionValue(value);
1220
+ if (value === null || value === undefined) {
1221
+ return { backing: [], offset: 0, length: 0 };
1222
+ }
1223
+ if (value instanceof Uint8Array) {
1224
+ return { backing: value, offset: 0, length: value.length };
1225
+ }
1226
+ if (Array.isArray(value)) {
1227
+ const meta = value.__meta__;
1228
+ if (meta !== undefined) {
1229
+ return {
1230
+ backing: meta.backing,
1231
+ offset: meta.offset,
1232
+ length: meta.length,
1233
+ };
1234
+ }
1235
+ return { backing: value, offset: 0, length: value.length };
1236
+ }
1237
+ const meta = value.__meta__;
1238
+ return {
1239
+ backing: meta.backing,
1240
+ offset: meta.offset,
1241
+ length: meta.length,
1242
+ };
1243
+ }
1244
+ function collectionValue(value) {
1245
+ if (isVarRef(value)) {
1246
+ return collectionValue(value.value);
1247
+ }
1248
+ if (typeof value === 'object' &&
1249
+ value !== null &&
1250
+ typeof value.__goType === 'string' &&
1251
+ '__goValue' in value) {
1252
+ return collectionValue(value.__goValue);
1253
+ }
1254
+ return value;
1103
1255
  }
1104
1256
  function bytesToBinaryString(bytes) {
1105
1257
  const chunkSize = 0x8000;
@@ -1115,8 +1267,8 @@ function bytesToBinaryString(bytes) {
1115
1267
  * @returns A Uint8Array representing the UTF-8 bytes of the string.
1116
1268
  */
1117
1269
  export function stringToBytes(s) {
1118
- if (typeof s === 'string') {
1119
- return new TextEncoder().encode(s);
1270
+ if (isGoStringValue(s)) {
1271
+ return goStringBytes(s);
1120
1272
  }
1121
1273
  // Already bytes - normalize to Uint8Array
1122
1274
  if (s instanceof Uint8Array) {
@@ -1128,6 +1280,57 @@ export function stringToBytes(s) {
1128
1280
  // Handle array or slice types
1129
1281
  return new Uint8Array(Array.isArray(s) ? s : []);
1130
1282
  }
1283
+ export function stringHeaderRef(s) {
1284
+ return varRef({
1285
+ get Data() {
1286
+ return { kind: 'string', value: s.value };
1287
+ },
1288
+ set Data(_value) { },
1289
+ get Len() {
1290
+ return stringToBytes(s.value).length;
1291
+ },
1292
+ set Len(_value) { },
1293
+ });
1294
+ }
1295
+ export function sliceHeaderRef(b) {
1296
+ let data = null;
1297
+ let length = 0;
1298
+ let capacity = 0;
1299
+ const refresh = () => {
1300
+ if (data === null) {
1301
+ return;
1302
+ }
1303
+ const bytes = stringToBytes(data.value);
1304
+ const out = makeSlice(length, Math.max(capacity, length), 'byte');
1305
+ if (out !== null) {
1306
+ copy(out, goSlice(bytes, 0, Math.min(length, bytes.length)));
1307
+ }
1308
+ b.value = out;
1309
+ };
1310
+ return varRef({
1311
+ get Data() {
1312
+ return data;
1313
+ },
1314
+ set Data(value) {
1315
+ data = value;
1316
+ refresh();
1317
+ },
1318
+ get Len() {
1319
+ return length;
1320
+ },
1321
+ set Len(value) {
1322
+ length = value;
1323
+ refresh();
1324
+ },
1325
+ get Cap() {
1326
+ return capacity;
1327
+ },
1328
+ set Cap(value) {
1329
+ capacity = value;
1330
+ refresh();
1331
+ },
1332
+ });
1333
+ }
1131
1334
  /**
1132
1335
  * Handles string() conversion for values that could be either string or []byte.
1133
1336
  * Used for generic type parameters with constraint []byte|string.
@@ -1138,7 +1341,7 @@ export function genericBytesOrStringToString(value) {
1138
1341
  if (value === null || value === undefined) {
1139
1342
  return '';
1140
1343
  }
1141
- if (typeof value === 'string') {
1344
+ if (isGoStringValue(value)) {
1142
1345
  return value;
1143
1346
  }
1144
1347
  return bytesToString(value);
@@ -1152,7 +1355,7 @@ export function genericBytesOrStringToString(value) {
1152
1355
  * @returns The byte value at the specified index
1153
1356
  */
1154
1357
  export function indexStringOrBytes(value, index) {
1155
- if (typeof value === 'string') {
1358
+ if (isGoStringValue(value)) {
1156
1359
  return indexString(value, index);
1157
1360
  }
1158
1361
  else if (value instanceof Uint8Array) {
@@ -1184,7 +1387,7 @@ export function indexStringOrBytes(value, index) {
1184
1387
  * @returns The sliced value of the same type as input
1185
1388
  */
1186
1389
  export function sliceStringOrBytes(value, low, high, max) {
1187
- if (typeof value === 'string') {
1390
+ if (isGoStringValue(value)) {
1188
1391
  // For strings, use sliceString and ignore max parameter
1189
1392
  return sliceString(value, low, high);
1190
1393
  }