goscript 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (495) hide show
  1. package/README.md +267 -255
  2. package/cmd/goscript/cmd-test.go +286 -0
  3. package/cmd/goscript/cmd-test_test.go +76 -0
  4. package/cmd/goscript/cmd_compile.go +9 -0
  5. package/cmd/goscript/main.go +1 -0
  6. package/compiler/build-flags.go +38 -0
  7. package/compiler/compile-request.go +33 -0
  8. package/compiler/compiler.go +1 -1
  9. package/compiler/compliance_test.go +0 -10
  10. package/compiler/config.go +2 -0
  11. package/compiler/gotest/owner.go +24 -0
  12. package/compiler/gotest/package-result.go +69 -0
  13. package/compiler/gotest/request.go +210 -0
  14. package/compiler/gotest/result.go +28 -0
  15. package/compiler/gotest/runner.go +1225 -0
  16. package/compiler/gotest/runner_test.go +1271 -0
  17. package/compiler/gotest/test.go +9 -0
  18. package/compiler/index.test.ts +1 -1
  19. package/compiler/lowered-program.go +80 -21
  20. package/compiler/lowering.go +6754 -602
  21. package/compiler/override-facts.go +357 -0
  22. package/compiler/override-registry.go +52 -190
  23. package/compiler/override-registry_test.go +182 -0
  24. package/compiler/package-graph.go +50 -27
  25. package/compiler/package-graph_test.go +99 -9
  26. package/compiler/package-test-function.go +9 -0
  27. package/compiler/package-test-graph-package.go +40 -0
  28. package/compiler/package-test-graph-variant.go +129 -0
  29. package/compiler/package-test-graph.go +112 -0
  30. package/compiler/package-test-graph_test.go +202 -0
  31. package/compiler/runtime-contract.go +229 -29
  32. package/compiler/runtime-contract_test.go +44 -30
  33. package/compiler/semantic-model-types.go +25 -6
  34. package/compiler/semantic-model.go +819 -74
  35. package/compiler/semantic-model_test.go +104 -0
  36. package/compiler/service.go +10 -4
  37. package/compiler/skeleton_test.go +2777 -524
  38. package/compiler/tsworkspace/owner-process-unix_test.go +72 -0
  39. package/compiler/tsworkspace/owner.go +342 -0
  40. package/compiler/tsworkspace/owner_test.go +93 -0
  41. package/compiler/tsworkspace/result.go +17 -0
  42. package/compiler/tsworkspace/tool-process-other.go +14 -0
  43. package/compiler/tsworkspace/tool-process-unix.go +19 -0
  44. package/compiler/typescript-emitter.go +576 -86
  45. package/compiler/wasm/compile.go +1 -1
  46. package/compiler/wasm/compile_test.go +61 -11
  47. package/compiler/wasm_api.go +172 -7
  48. package/dist/gs/builtin/builtin.d.ts +40 -3
  49. package/dist/gs/builtin/builtin.js +430 -22
  50. package/dist/gs/builtin/builtin.js.map +1 -1
  51. package/dist/gs/builtin/channel.d.ts +32 -10
  52. package/dist/gs/builtin/channel.js +119 -25
  53. package/dist/gs/builtin/channel.js.map +1 -1
  54. package/dist/gs/builtin/defer.d.ts +1 -0
  55. package/dist/gs/builtin/defer.js +12 -2
  56. package/dist/gs/builtin/defer.js.map +1 -1
  57. package/dist/gs/builtin/hostio.d.ts +9 -0
  58. package/dist/gs/builtin/hostio.js +25 -0
  59. package/dist/gs/builtin/hostio.js.map +1 -1
  60. package/dist/gs/builtin/map.js +40 -6
  61. package/dist/gs/builtin/map.js.map +1 -1
  62. package/dist/gs/builtin/print.js.map +1 -1
  63. package/dist/gs/builtin/slice.d.ts +64 -10
  64. package/dist/gs/builtin/slice.js +619 -244
  65. package/dist/gs/builtin/slice.js.map +1 -1
  66. package/dist/gs/builtin/type.d.ts +7 -2
  67. package/dist/gs/builtin/type.js +128 -29
  68. package/dist/gs/builtin/type.js.map +1 -1
  69. package/dist/gs/builtin/varRef.d.ts +7 -0
  70. package/dist/gs/builtin/varRef.js +23 -0
  71. package/dist/gs/builtin/varRef.js.map +1 -1
  72. package/dist/gs/bytes/buffer.gs.js +74 -70
  73. package/dist/gs/bytes/buffer.gs.js.map +1 -1
  74. package/dist/gs/bytes/iter.gs.js +13 -13
  75. package/dist/gs/bytes/iter.gs.js.map +1 -1
  76. package/dist/gs/bytes/reader.gs.js +20 -18
  77. package/dist/gs/bytes/reader.gs.js.map +1 -1
  78. package/dist/gs/compress/zlib/index.d.ts +26 -0
  79. package/dist/gs/compress/zlib/index.js +168 -0
  80. package/dist/gs/compress/zlib/index.js.map +1 -0
  81. package/dist/gs/context/context.d.ts +6 -5
  82. package/dist/gs/context/context.js +17 -12
  83. package/dist/gs/context/context.js.map +1 -1
  84. package/dist/gs/crypto/ecdh/index.d.ts +52 -0
  85. package/dist/gs/crypto/ecdh/index.js +226 -0
  86. package/dist/gs/crypto/ecdh/index.js.map +1 -0
  87. package/dist/gs/crypto/ed25519/index.d.ts +34 -0
  88. package/dist/gs/crypto/ed25519/index.js +160 -0
  89. package/dist/gs/crypto/ed25519/index.js.map +1 -0
  90. package/dist/gs/crypto/internal/constanttime/index.d.ts +4 -0
  91. package/dist/gs/crypto/internal/constanttime/index.js +18 -0
  92. package/dist/gs/crypto/internal/constanttime/index.js.map +1 -0
  93. package/dist/gs/crypto/internal/fips140deps/byteorder/index.d.ts +1 -0
  94. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js +2 -0
  95. package/dist/gs/crypto/internal/fips140deps/byteorder/index.js.map +1 -0
  96. package/dist/gs/crypto/internal/fips140deps/godebug/index.d.ts +1 -0
  97. package/dist/gs/crypto/internal/fips140deps/godebug/index.js +2 -0
  98. package/dist/gs/crypto/internal/fips140deps/godebug/index.js.map +1 -0
  99. package/dist/gs/crypto/rand/index.d.ts +2 -0
  100. package/dist/gs/crypto/rand/index.js +85 -0
  101. package/dist/gs/crypto/rand/index.js.map +1 -1
  102. package/dist/gs/crypto/sha256/index.d.ts +8 -0
  103. package/dist/gs/crypto/sha256/index.js +118 -0
  104. package/dist/gs/crypto/sha256/index.js.map +1 -0
  105. package/dist/gs/crypto/sha512/index.d.ts +14 -0
  106. package/dist/gs/crypto/sha512/index.js +129 -0
  107. package/dist/gs/crypto/sha512/index.js.map +1 -0
  108. package/dist/gs/embed/index.d.ts +7 -0
  109. package/dist/gs/embed/index.js +16 -0
  110. package/dist/gs/embed/index.js.map +1 -0
  111. package/dist/gs/encoding/json/index.d.ts +4 -0
  112. package/dist/gs/encoding/json/index.js +33 -0
  113. package/dist/gs/encoding/json/index.js.map +1 -1
  114. package/dist/gs/errors/errors.d.ts +4 -0
  115. package/dist/gs/errors/errors.js +108 -4
  116. package/dist/gs/errors/errors.js.map +1 -1
  117. package/dist/gs/fmt/fmt.d.ts +4 -4
  118. package/dist/gs/fmt/fmt.js +42 -11
  119. package/dist/gs/fmt/fmt.js.map +1 -1
  120. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +37 -2
  121. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +245 -1
  122. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  123. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +189 -0
  124. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +861 -0
  125. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -0
  126. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +217 -0
  127. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +814 -0
  128. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -0
  129. package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +20 -0
  130. package/dist/gs/github.com/aperturerobotics/util/conc/index.js +134 -0
  131. package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +1 -0
  132. package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
  133. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.d.ts +3 -0
  134. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js +50 -0
  135. package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js.map +1 -0
  136. package/dist/gs/github.com/klauspost/compress/internal/le/index.d.ts +9 -0
  137. package/dist/gs/github.com/klauspost/compress/internal/le/index.js +72 -0
  138. package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -0
  139. package/dist/gs/github.com/mr-tron/base58/base58/index.d.ts +27 -0
  140. package/dist/gs/github.com/mr-tron/base58/base58/index.js +172 -0
  141. package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -0
  142. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.d.ts +21 -0
  143. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js +22 -0
  144. package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js.map +1 -0
  145. package/dist/gs/go/internal/scannerhooks/index.d.ts +3 -0
  146. package/dist/gs/go/internal/scannerhooks/index.js +5 -0
  147. package/dist/gs/go/internal/scannerhooks/index.js.map +1 -0
  148. package/dist/gs/go/scanner/index.d.ts +13 -0
  149. package/dist/gs/go/scanner/index.js +35 -0
  150. package/dist/gs/go/scanner/index.js.map +1 -1
  151. package/dist/gs/go/token/index.d.ts +156 -0
  152. package/dist/gs/go/token/index.js +507 -4
  153. package/dist/gs/go/token/index.js.map +1 -1
  154. package/dist/gs/hash/fnv/index.d.ts +57 -0
  155. package/dist/gs/hash/fnv/index.js +299 -0
  156. package/dist/gs/hash/fnv/index.js.map +1 -0
  157. package/dist/gs/hash/index.d.ts +17 -0
  158. package/dist/gs/hash/index.js +94 -0
  159. package/dist/gs/hash/index.js.map +1 -0
  160. package/dist/gs/internal/abi/index.d.ts +4 -0
  161. package/dist/gs/internal/abi/index.js +10 -0
  162. package/dist/gs/internal/abi/index.js.map +1 -1
  163. package/dist/gs/internal/bytealg/index.d.ts +2 -0
  164. package/dist/gs/internal/bytealg/index.js +14 -0
  165. package/dist/gs/internal/bytealg/index.js.map +1 -1
  166. package/dist/gs/internal/byteorder/index.d.ts +8 -2
  167. package/dist/gs/internal/byteorder/index.js +56 -25
  168. package/dist/gs/internal/byteorder/index.js.map +1 -1
  169. package/dist/gs/internal/godebug/index.d.ts +12 -0
  170. package/dist/gs/internal/godebug/index.js +30 -0
  171. package/dist/gs/internal/godebug/index.js.map +1 -0
  172. package/dist/gs/io/fs/index.d.ts +1 -0
  173. package/dist/gs/io/fs/index.js +1 -0
  174. package/dist/gs/io/fs/index.js.map +1 -1
  175. package/dist/gs/io/fs/readlink.d.ts +8 -0
  176. package/dist/gs/io/fs/readlink.js +60 -0
  177. package/dist/gs/io/fs/readlink.js.map +1 -0
  178. package/dist/gs/io/fs/walk.d.ts +3 -3
  179. package/dist/gs/io/fs/walk.js +7 -7
  180. package/dist/gs/io/fs/walk.js.map +1 -1
  181. package/dist/gs/io/io.d.ts +40 -6
  182. package/dist/gs/io/io.js +151 -26
  183. package/dist/gs/io/io.js.map +1 -1
  184. package/dist/gs/iter/iter.d.ts +3 -2
  185. package/dist/gs/iter/iter.js.map +1 -1
  186. package/dist/gs/maps/iter.d.ts +5 -5
  187. package/dist/gs/maps/iter.js +48 -21
  188. package/dist/gs/maps/iter.js.map +1 -1
  189. package/dist/gs/maps/maps.d.ts +6 -6
  190. package/dist/gs/maps/maps.js +1 -1
  191. package/dist/gs/maps/maps.js.map +1 -1
  192. package/dist/gs/math/bits/index.d.ts +13 -4
  193. package/dist/gs/math/bits/index.js +70 -48
  194. package/dist/gs/math/bits/index.js.map +1 -1
  195. package/dist/gs/math/const.gs.d.ts +5 -5
  196. package/dist/gs/math/const.gs.js +4 -4
  197. package/dist/gs/math/const.gs.js.map +1 -1
  198. package/dist/gs/mime/index.d.ts +1 -0
  199. package/dist/gs/mime/index.js +52 -0
  200. package/dist/gs/mime/index.js.map +1 -0
  201. package/dist/gs/net/http/httptest/index.d.ts +30 -0
  202. package/dist/gs/net/http/httptest/index.js +101 -0
  203. package/dist/gs/net/http/httptest/index.js.map +1 -0
  204. package/dist/gs/net/http/index.d.ts +131 -0
  205. package/dist/gs/net/http/index.js +307 -0
  206. package/dist/gs/net/http/index.js.map +1 -0
  207. package/dist/gs/net/http/pprof/index.d.ts +8 -0
  208. package/dist/gs/net/http/pprof/index.js +59 -0
  209. package/dist/gs/net/http/pprof/index.js.map +1 -0
  210. package/dist/gs/os/dir_unix.gs.js +2 -2
  211. package/dist/gs/os/dir_unix.gs.js.map +1 -1
  212. package/dist/gs/os/error.gs.js +9 -7
  213. package/dist/gs/os/error.gs.js.map +1 -1
  214. package/dist/gs/os/types_js.gs.js +95 -15
  215. package/dist/gs/os/types_js.gs.js.map +1 -1
  216. package/dist/gs/path/filepath/match.js +165 -3
  217. package/dist/gs/path/filepath/match.js.map +1 -1
  218. package/dist/gs/path/filepath/path.d.ts +8 -4
  219. package/dist/gs/path/filepath/path.js +192 -8
  220. package/dist/gs/path/filepath/path.js.map +1 -1
  221. package/dist/gs/path/path.d.ts +4 -1
  222. package/dist/gs/path/path.js +16 -4
  223. package/dist/gs/path/path.js.map +1 -1
  224. package/dist/gs/reflect/index.d.ts +4 -3
  225. package/dist/gs/reflect/index.js +3 -2
  226. package/dist/gs/reflect/index.js.map +1 -1
  227. package/dist/gs/reflect/iter.js +2 -2
  228. package/dist/gs/reflect/iter.js.map +1 -1
  229. package/dist/gs/reflect/map.js +29 -0
  230. package/dist/gs/reflect/map.js.map +1 -1
  231. package/dist/gs/reflect/type.d.ts +31 -9
  232. package/dist/gs/reflect/type.js +536 -43
  233. package/dist/gs/reflect/type.js.map +1 -1
  234. package/dist/gs/reflect/types.d.ts +1 -0
  235. package/dist/gs/reflect/types.js +3 -1
  236. package/dist/gs/reflect/types.js.map +1 -1
  237. package/dist/gs/reflect/value.d.ts +4 -1
  238. package/dist/gs/reflect/value.js +39 -1
  239. package/dist/gs/reflect/value.js.map +1 -1
  240. package/dist/gs/reflect/visiblefields.js +1 -1
  241. package/dist/gs/reflect/visiblefields.js.map +1 -1
  242. package/dist/gs/runtime/debug/index.d.ts +41 -0
  243. package/dist/gs/runtime/debug/index.js +66 -0
  244. package/dist/gs/runtime/debug/index.js.map +1 -0
  245. package/dist/gs/runtime/pprof/index.d.ts +20 -0
  246. package/dist/gs/runtime/pprof/index.js +85 -0
  247. package/dist/gs/runtime/pprof/index.js.map +1 -0
  248. package/dist/gs/runtime/runtime.d.ts +35 -3
  249. package/dist/gs/runtime/runtime.js +72 -0
  250. package/dist/gs/runtime/runtime.js.map +1 -1
  251. package/dist/gs/runtime/trace/index.d.ts +19 -0
  252. package/dist/gs/runtime/trace/index.js +64 -0
  253. package/dist/gs/runtime/trace/index.js.map +1 -0
  254. package/dist/gs/slices/slices.d.ts +42 -8
  255. package/dist/gs/slices/slices.js +425 -11
  256. package/dist/gs/slices/slices.js.map +1 -1
  257. package/dist/gs/sort/slice.gs.d.ts +5 -3
  258. package/dist/gs/sort/slice.gs.js +60 -22
  259. package/dist/gs/sort/slice.gs.js.map +1 -1
  260. package/dist/gs/sort/sort.gs.d.ts +4 -4
  261. package/dist/gs/sort/sort.gs.js +11 -8
  262. package/dist/gs/sort/sort.gs.js.map +1 -1
  263. package/dist/gs/strings/builder.d.ts +1 -1
  264. package/dist/gs/strings/builder.js +29 -19
  265. package/dist/gs/strings/builder.js.map +1 -1
  266. package/dist/gs/strings/iter.js +140 -75
  267. package/dist/gs/strings/iter.js.map +1 -1
  268. package/dist/gs/strings/replace.js +2 -2
  269. package/dist/gs/strings/replace.js.map +1 -1
  270. package/dist/gs/strings/strings.js +52 -6
  271. package/dist/gs/strings/strings.js.map +1 -1
  272. package/dist/gs/sync/atomic/type.gs.d.ts +9 -8
  273. package/dist/gs/sync/atomic/type.gs.js +0 -2
  274. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  275. package/dist/gs/sync/sync.d.ts +8 -3
  276. package/dist/gs/sync/sync.js +66 -11
  277. package/dist/gs/sync/sync.js.map +1 -1
  278. package/dist/gs/syscall/constants.d.ts +36 -24
  279. package/dist/gs/syscall/constants.js +12 -0
  280. package/dist/gs/syscall/constants.js.map +1 -1
  281. package/dist/gs/syscall/errors.d.ts +117 -111
  282. package/dist/gs/syscall/errors.js +45 -0
  283. package/dist/gs/syscall/errors.js.map +1 -1
  284. package/dist/gs/syscall/fs.d.ts +37 -0
  285. package/dist/gs/syscall/fs.js +102 -0
  286. package/dist/gs/syscall/fs.js.map +1 -1
  287. package/dist/gs/syscall/js/index.d.ts +90 -0
  288. package/dist/gs/syscall/js/index.js +383 -0
  289. package/dist/gs/syscall/js/index.js.map +1 -0
  290. package/dist/gs/syscall/types.d.ts +26 -1
  291. package/dist/gs/syscall/types.js +45 -1
  292. package/dist/gs/syscall/types.js.map +1 -1
  293. package/dist/gs/testing/index.d.ts +1 -0
  294. package/dist/gs/testing/index.js +2 -0
  295. package/dist/gs/testing/index.js.map +1 -0
  296. package/dist/gs/testing/testing.d.ts +78 -0
  297. package/dist/gs/testing/testing.js +318 -0
  298. package/dist/gs/testing/testing.js.map +1 -0
  299. package/dist/gs/time/time.d.ts +41 -4
  300. package/dist/gs/time/time.js +227 -36
  301. package/dist/gs/time/time.js.map +1 -1
  302. package/dist/gs/unicode/unicode.d.ts +23 -1
  303. package/dist/gs/unicode/unicode.js +79 -10
  304. package/dist/gs/unicode/unicode.js.map +1 -1
  305. package/dist/gs/unicode/utf8/utf8.d.ts +4 -4
  306. package/dist/gs/unicode/utf8/utf8.js +24 -11
  307. package/dist/gs/unicode/utf8/utf8.js.map +1 -1
  308. package/dist/gs/unique/index.d.ts +11 -0
  309. package/dist/gs/unique/index.js +76 -0
  310. package/dist/gs/unique/index.js.map +1 -0
  311. package/go.mod +8 -8
  312. package/go.sum +14 -14
  313. package/gs/builtin/builtin.ts +585 -27
  314. package/gs/builtin/channel.ts +183 -29
  315. package/gs/builtin/defer.ts +13 -2
  316. package/gs/builtin/hostio.test.ts +1 -0
  317. package/gs/builtin/hostio.ts +38 -0
  318. package/gs/builtin/map.ts +46 -6
  319. package/gs/builtin/print.ts +12 -3
  320. package/gs/builtin/runtime-contract.test.ts +383 -10
  321. package/gs/builtin/slice.test.ts +70 -0
  322. package/gs/builtin/slice.ts +785 -265
  323. package/gs/builtin/type.ts +160 -41
  324. package/gs/builtin/varRef.ts +40 -1
  325. package/gs/bytes/buffer.gs.ts +74 -70
  326. package/gs/bytes/iter.gs.ts +13 -14
  327. package/gs/bytes/meta.json +8 -3
  328. package/gs/bytes/reader.gs.ts +20 -19
  329. package/gs/compress/zlib/index.test.ts +28 -0
  330. package/gs/compress/zlib/index.ts +200 -0
  331. package/gs/compress/zlib/meta.json +3 -0
  332. package/gs/context/context.test.ts +71 -0
  333. package/gs/context/context.ts +30 -29
  334. package/gs/crypto/ecdh/index.test.ts +43 -0
  335. package/gs/crypto/ecdh/index.ts +274 -0
  336. package/gs/crypto/ed25519/index.test.ts +41 -0
  337. package/gs/crypto/ed25519/index.ts +238 -0
  338. package/gs/crypto/ed25519/meta.json +13 -0
  339. package/gs/crypto/internal/constanttime/index.test.ts +25 -0
  340. package/gs/crypto/internal/constanttime/index.ts +22 -0
  341. package/gs/crypto/internal/fips140deps/byteorder/index.ts +1 -0
  342. package/gs/crypto/internal/fips140deps/godebug/index.ts +1 -0
  343. package/gs/crypto/rand/index.test.ts +89 -1
  344. package/gs/crypto/rand/index.ts +103 -1
  345. package/gs/crypto/rand/meta.json +4 -1
  346. package/gs/crypto/sha256/index.test.ts +78 -0
  347. package/gs/crypto/sha256/index.ts +150 -0
  348. package/gs/crypto/sha256/meta.json +9 -0
  349. package/gs/crypto/sha512/index.test.ts +31 -0
  350. package/gs/crypto/sha512/index.ts +161 -0
  351. package/gs/crypto/sha512/meta.json +11 -0
  352. package/gs/embed/index.ts +20 -0
  353. package/gs/embed/meta.json +5 -0
  354. package/gs/encoding/json/index.test.ts +39 -3
  355. package/gs/encoding/json/index.ts +45 -3
  356. package/gs/errors/errors.test.ts +85 -0
  357. package/gs/errors/errors.ts +132 -4
  358. package/gs/fmt/fmt.test.ts +3 -1
  359. package/gs/fmt/fmt.ts +55 -19
  360. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +128 -1
  361. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +342 -4
  362. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +180 -0
  363. package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +1084 -0
  364. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +31 -0
  365. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +1233 -0
  366. package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +46 -0
  367. package/gs/github.com/aperturerobotics/util/conc/index.test.ts +30 -0
  368. package/gs/github.com/aperturerobotics/util/conc/index.ts +172 -0
  369. package/gs/github.com/aperturerobotics/util/conc/meta.json +9 -0
  370. package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.ts +1 -4
  371. package/gs/github.com/hack-pad/safejs/internal/catch/index.test.ts +35 -0
  372. package/gs/github.com/hack-pad/safejs/internal/catch/index.ts +65 -0
  373. package/gs/github.com/hack-pad/safejs/internal/catch/meta.json +9 -0
  374. package/gs/github.com/klauspost/compress/internal/le/index.test.ts +37 -0
  375. package/gs/github.com/klauspost/compress/internal/le/index.ts +115 -0
  376. package/gs/github.com/mr-tron/base58/base58/index.test.ts +70 -0
  377. package/gs/github.com/mr-tron/base58/base58/index.ts +231 -0
  378. package/gs/github.com/mr-tron/base58/base58/meta.json +3 -0
  379. package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +46 -0
  380. package/gs/github.com/zeebo/blake3/internal/consts/index.ts +26 -0
  381. package/gs/go/internal/scannerhooks/index.test.ts +14 -0
  382. package/gs/go/internal/scannerhooks/index.ts +9 -0
  383. package/gs/go/scanner/index.test.ts +22 -0
  384. package/gs/go/scanner/index.ts +47 -0
  385. package/gs/go/token/index.test.ts +47 -1
  386. package/gs/go/token/index.ts +583 -4
  387. package/gs/hash/fnv/index.test.ts +67 -0
  388. package/gs/hash/fnv/index.ts +351 -0
  389. package/gs/hash/fnv/meta.json +3 -0
  390. package/gs/hash/index.test.ts +37 -0
  391. package/gs/hash/index.ts +118 -0
  392. package/gs/hash/meta.json +5 -0
  393. package/gs/internal/abi/index.test.ts +18 -0
  394. package/gs/internal/abi/index.ts +14 -0
  395. package/gs/internal/bytealg/index.test.ts +18 -0
  396. package/gs/internal/bytealg/index.ts +16 -0
  397. package/gs/internal/byteorder/index.test.ts +39 -0
  398. package/gs/internal/byteorder/index.ts +100 -27
  399. package/gs/internal/godebug/index.test.ts +16 -0
  400. package/gs/internal/godebug/index.ts +35 -0
  401. package/gs/io/fs/index.ts +1 -0
  402. package/gs/io/fs/meta.json +5 -0
  403. package/gs/io/fs/readlink.test.ts +43 -0
  404. package/gs/io/fs/readlink.ts +69 -0
  405. package/gs/io/fs/walk.test.ts +61 -0
  406. package/gs/io/fs/walk.ts +17 -9
  407. package/gs/io/io.ts +177 -31
  408. package/gs/io/meta.json +10 -2
  409. package/gs/iter/iter.ts +8 -2
  410. package/gs/maps/iter.ts +75 -26
  411. package/gs/maps/maps.test.ts +23 -0
  412. package/gs/maps/maps.ts +13 -11
  413. package/gs/math/bits/index.test.ts +20 -0
  414. package/gs/math/bits/index.ts +107 -64
  415. package/gs/math/const.gs.test.ts +11 -5
  416. package/gs/math/const.gs.ts +5 -6
  417. package/gs/mime/index.ts +60 -0
  418. package/gs/net/http/httptest/index.test.ts +53 -0
  419. package/gs/net/http/httptest/index.ts +120 -0
  420. package/gs/net/http/index.test.ts +148 -0
  421. package/gs/net/http/index.ts +432 -0
  422. package/gs/net/http/meta.json +6 -0
  423. package/gs/net/http/pprof/index.test.ts +47 -0
  424. package/gs/net/http/pprof/index.ts +65 -0
  425. package/gs/os/dir_unix.gs.ts +2 -3
  426. package/gs/os/error.gs.ts +9 -10
  427. package/gs/os/error.test.ts +41 -0
  428. package/gs/os/file_unix_js.test.ts +55 -0
  429. package/gs/os/tempfile.gs.test.ts +37 -10
  430. package/gs/os/types_js.gs.ts +96 -17
  431. package/gs/path/filepath/match.test.ts +31 -12
  432. package/gs/path/filepath/match.ts +181 -3
  433. package/gs/path/filepath/meta.json +6 -0
  434. package/gs/path/filepath/path.test.ts +80 -0
  435. package/gs/path/filepath/path.ts +244 -11
  436. package/gs/path/path.ts +20 -5
  437. package/gs/reflect/field.test.ts +63 -0
  438. package/gs/reflect/index.ts +5 -1
  439. package/gs/reflect/iter.ts +2 -2
  440. package/gs/reflect/map.test.ts +42 -1
  441. package/gs/reflect/map.ts +39 -0
  442. package/gs/reflect/type.ts +728 -65
  443. package/gs/reflect/typefor.test.ts +100 -0
  444. package/gs/reflect/types.ts +3 -1
  445. package/gs/reflect/value.ts +50 -1
  446. package/gs/reflect/visiblefields.ts +1 -1
  447. package/gs/runtime/debug/index.test.ts +45 -0
  448. package/gs/runtime/debug/index.ts +96 -0
  449. package/gs/runtime/pprof/index.test.ts +36 -0
  450. package/gs/runtime/pprof/index.ts +104 -0
  451. package/gs/runtime/pprof/meta.json +6 -0
  452. package/gs/runtime/runtime.test.ts +19 -0
  453. package/gs/runtime/runtime.ts +98 -3
  454. package/gs/runtime/trace/index.test.ts +45 -0
  455. package/gs/runtime/trace/index.ts +97 -0
  456. package/gs/runtime/trace/meta.json +7 -0
  457. package/gs/slices/meta.json +2 -1
  458. package/gs/slices/slices.test.ts +180 -0
  459. package/gs/slices/slices.ts +502 -15
  460. package/gs/sort/meta.json +7 -0
  461. package/gs/sort/slice.gs.ts +85 -26
  462. package/gs/sort/slice.test.ts +40 -0
  463. package/gs/sort/sort.gs.ts +16 -13
  464. package/gs/strings/builder.test.ts +8 -0
  465. package/gs/strings/builder.ts +33 -20
  466. package/gs/strings/iter.test.ts +5 -7
  467. package/gs/strings/iter.ts +146 -71
  468. package/gs/strings/replace.test.ts +1 -4
  469. package/gs/strings/replace.ts +6 -6
  470. package/gs/strings/strings.test.ts +4 -0
  471. package/gs/strings/strings.ts +54 -6
  472. package/gs/sync/atomic/type.gs.ts +13 -14
  473. package/gs/sync/meta.json +3 -1
  474. package/gs/sync/sync.test.ts +69 -1
  475. package/gs/sync/sync.ts +72 -13
  476. package/gs/syscall/constants.ts +39 -24
  477. package/gs/syscall/errors.ts +165 -112
  478. package/gs/syscall/fs.ts +195 -0
  479. package/gs/syscall/js/index.ts +485 -0
  480. package/gs/syscall/js/meta.json +4 -0
  481. package/gs/syscall/net.test.ts +111 -0
  482. package/gs/syscall/types.ts +63 -2
  483. package/gs/testing/index.ts +1 -0
  484. package/gs/testing/meta.json +5 -0
  485. package/gs/testing/testing.test.ts +146 -0
  486. package/gs/testing/testing.ts +399 -0
  487. package/gs/time/meta.json +2 -2
  488. package/gs/time/time.test.ts +110 -0
  489. package/gs/time/time.ts +309 -57
  490. package/gs/unicode/unicode.test.ts +36 -0
  491. package/gs/unicode/unicode.ts +115 -9
  492. package/gs/unicode/utf8/utf8.test.ts +13 -0
  493. package/gs/unicode/utf8/utf8.ts +28 -16
  494. package/gs/unique/index.ts +98 -0
  495. package/package.json +3 -2
@@ -1,34 +1,99 @@
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
+ }
47
+ const addressStride = 0x100000000;
48
+ let nextAddressBase = 1;
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
+ }
1
64
  /**
2
65
  * wrapSliceProxy wraps a SliceProxy in a Proxy to intercept index access
3
66
  * and route it through the backing array.
4
67
  */
5
68
  function wrapSliceProxy(proxy) {
69
+ const meta = proxy.__meta__;
70
+ meta.target = proxy;
6
71
  const handler = {
7
72
  get(target, prop) {
8
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
9
- const index = Number(prop);
10
- if (index >= 0 && index < target.__meta__.length) {
11
- 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];
12
77
  }
13
- throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
78
+ throw new Error(`Slice index out of range: ${index} >= ${meta.length}`);
14
79
  }
15
80
  if (prop === 'length') {
16
- return target.__meta__.length;
81
+ return meta.length;
17
82
  }
18
83
  if (prop === '__meta__') {
19
- return target.__meta__;
84
+ return meta;
20
85
  }
21
86
  return Reflect.get(target, prop);
22
87
  },
23
88
  set(target, prop, value) {
24
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
25
- const index = Number(prop);
26
- if (index >= 0 && index < target.__meta__.length) {
27
- 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;
28
93
  target[index] = value; // Also update the proxy target for consistency
29
94
  return true;
30
95
  }
31
- throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
96
+ throw new Error(`Slice index out of range: ${index} >= ${meta.length}`);
32
97
  }
33
98
  if (prop === 'length' || prop === '__meta__') {
34
99
  return false;
@@ -38,6 +103,17 @@ function wrapSliceProxy(proxy) {
38
103
  };
39
104
  return new Proxy(proxy, handler);
40
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
+ }
41
117
  // asArray converts a slice to a JavaScript array.
42
118
  export function asArray(slice) {
43
119
  if (slice === null || slice === undefined) {
@@ -58,6 +134,30 @@ export function asArray(slice) {
58
134
  }
59
135
  return [];
60
136
  }
137
+ export function sliceToArray(slice, length, typeHint) {
138
+ if (len(slice) < length) {
139
+ throw new Error(`runtime error: cannot convert slice with length ${len(slice)} to array with length ${length}`);
140
+ }
141
+ if (typeHint === 'byte') {
142
+ return new Uint8Array(asArray(slice).slice(0, length));
143
+ }
144
+ return asArray(slice).slice(0, length);
145
+ }
146
+ export function sliceToArrayPointer(slice, length, typeHint) {
147
+ if (len(slice) < length) {
148
+ throw new Error(`runtime error: cannot convert slice with length ${len(slice)} to array pointer with length ${length}`);
149
+ }
150
+ if (typeHint === 'byte') {
151
+ if (slice instanceof Uint8Array) {
152
+ return varRef(goSlice(slice, 0, length));
153
+ }
154
+ return varRef(goSlice(slice, 0, length));
155
+ }
156
+ if (slice instanceof Uint8Array) {
157
+ return varRef(goSlice(slice, 0, length));
158
+ }
159
+ return varRef(goSlice(slice, 0, length));
160
+ }
61
161
  /**
62
162
  * isComplexSlice checks if a slice is a complex slice (has __meta__ property)
63
163
  */
@@ -68,6 +168,27 @@ function isComplexSlice(slice) {
68
168
  '__meta__' in slice &&
69
169
  slice.__meta__ !== undefined);
70
170
  }
171
+ function normalizeSliceIndex(value) {
172
+ if (value === undefined) {
173
+ return undefined;
174
+ }
175
+ return Number(value);
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
+ }
71
192
  /**
72
193
  * isSliceProxy checks if a slice is a SliceProxy (has __meta__ property)
73
194
  * This is an alias for isComplexSlice for better type hinting
@@ -81,7 +202,7 @@ export function isSliceProxy(slice) {
81
202
  * @param capacity The capacity of the slice (optional).
82
203
  * @returns A new slice.
83
204
  */
84
- export const makeSlice = (length, capacity, typeHint) => {
205
+ export const makeSlice = (length, capacity, typeHint, zeroFactory) => {
85
206
  if (typeHint === 'byte') {
86
207
  const actualCapacity = capacity === undefined ? length : capacity;
87
208
  if (length < 0 || actualCapacity < 0 || length > actualCapacity) {
@@ -91,47 +212,33 @@ export const makeSlice = (length, capacity, typeHint) => {
91
212
  if (actualCapacity === length) {
92
213
  return new Uint8Array(length);
93
214
  }
94
- // If capacity > length, create a SliceProxy backed by a Uint8Array
95
- const backingUint8 = new Uint8Array(actualCapacity);
96
- const backingNumbers = Array.from(backingUint8); // Convert to number[] for backing
97
- const proxyTargetArray = new Array(length);
98
- for (let i = 0; i < length; i++) {
99
- proxyTargetArray[i] = 0; // Initialize with zeros
100
- }
101
- const proxy = proxyTargetArray;
102
- proxy.__meta__ = {
103
- backing: backingNumbers,
104
- offset: 0,
105
- length: length,
106
- capacity: actualCapacity,
107
- };
108
- return wrapSliceProxy(proxy);
215
+ return byteSliceView(new Uint8Array(actualCapacity), 0, length, actualCapacity);
109
216
  }
110
217
  const actualCapacity = capacity === undefined ? length : capacity;
111
218
  if (length < 0 || actualCapacity < 0 || length > actualCapacity) {
112
219
  throw new Error(`Invalid slice length (${length}) or capacity (${actualCapacity})`);
113
220
  }
114
- let zeroVal;
115
- switch (typeHint) {
116
- case 'number':
117
- zeroVal = 0;
118
- break;
119
- case 'boolean':
120
- zeroVal = false;
121
- break;
122
- case 'string':
123
- zeroVal = '';
124
- break;
125
- default:
126
- zeroVal = null; // Default for objects, complex types, or unspecified
127
- }
221
+ const zeroValue = () => {
222
+ if (zeroFactory !== undefined) {
223
+ return zeroFactory();
224
+ }
225
+ switch (typeHint) {
226
+ case 'number':
227
+ return 0;
228
+ case 'boolean':
229
+ return false;
230
+ case 'string':
231
+ return '';
232
+ default:
233
+ return null; // Default for objects, complex types, or unspecified
234
+ }
235
+ };
128
236
  const backingArr = new Array(actualCapacity);
129
- // Initialize the relevant part of the backing array
130
- for (let i = 0; i < length; i++) {
131
- backingArr[i] = zeroVal;
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++) {
240
+ backingArr[i] = zeroValue();
132
241
  }
133
- // The rest of backingArr (from length to actualCapacity-1) remains uninitialized (undefined),
134
- // representing available capacity.
135
242
  // OPTIMIZATION: If length equals capacity, return backing array directly
136
243
  if (length === actualCapacity) {
137
244
  return backingArr;
@@ -140,7 +247,7 @@ export const makeSlice = (length, capacity, typeHint) => {
140
247
  // Its elements up to 'length' should reflect the initialized part of the slice.
141
248
  const proxyTargetArray = new Array(length);
142
249
  for (let i = 0; i < length; i++) {
143
- proxyTargetArray[i] = backingArr[i]; // Or simply zeroVal
250
+ proxyTargetArray[i] = backingArr[i];
144
251
  }
145
252
  const proxy = proxyTargetArray;
146
253
  proxy.__meta__ = {
@@ -152,9 +259,9 @@ export const makeSlice = (length, capacity, typeHint) => {
152
259
  // Create a proper Proxy with the handler for SliceProxy behavior
153
260
  const handler = {
154
261
  get(target, prop) {
155
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
156
- const index = Number(prop);
157
- if (index >= 0 && index < target.__meta__.length) {
262
+ const index = sliceIndexProperty(prop);
263
+ if (index >= 0) {
264
+ if (index < target.__meta__.length) {
158
265
  return target.__meta__.backing[target.__meta__.offset + index];
159
266
  }
160
267
  throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
@@ -168,9 +275,9 @@ export const makeSlice = (length, capacity, typeHint) => {
168
275
  return Reflect.get(target, prop);
169
276
  },
170
277
  set(target, prop, value) {
171
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
172
- const index = Number(prop);
173
- if (index >= 0 && index < target.__meta__.length) {
278
+ const index = sliceIndexProperty(prop);
279
+ if (index >= 0) {
280
+ if (index < target.__meta__.length) {
174
281
  target.__meta__.backing[target.__meta__.offset + index] = value;
175
282
  target[index] = value; // Also update the proxy target for consistency
176
283
  return true;
@@ -187,11 +294,15 @@ export const makeSlice = (length, capacity, typeHint) => {
187
294
  };
188
295
  export function goSlice(// T can be number for Uint8Array case
189
296
  s, low, high, max) {
297
+ s = collectionValue(s);
298
+ low = normalizeSliceIndex(low);
299
+ high = normalizeSliceIndex(high);
300
+ max = normalizeSliceIndex(max);
190
301
  const handler = {
191
302
  get(target, prop) {
192
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
193
- const index = Number(prop);
194
- if (index >= 0 && index < target.__meta__.length) {
303
+ const index = sliceIndexProperty(prop);
304
+ if (index >= 0) {
305
+ if (index < target.__meta__.length) {
195
306
  return target.__meta__.backing[target.__meta__.offset + index];
196
307
  }
197
308
  throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
@@ -214,15 +325,17 @@ s, low, high, max) {
214
325
  return Reflect.get(target, prop);
215
326
  },
216
327
  set(target, prop, value) {
217
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
218
- const index = Number(prop);
219
- if (index >= 0 && index < target.__meta__.length) {
328
+ const index = sliceIndexProperty(prop);
329
+ if (index >= 0) {
330
+ if (index < target.__meta__.length) {
220
331
  target.__meta__.backing[target.__meta__.offset + index] = value;
332
+ target[index] = value;
221
333
  return true;
222
334
  }
223
335
  if (index === target.__meta__.length &&
224
336
  target.__meta__.length < target.__meta__.capacity) {
225
337
  target.__meta__.backing[target.__meta__.offset + index] = value;
338
+ target[index] = value;
226
339
  target.__meta__.length++;
227
340
  return true;
228
341
  }
@@ -235,43 +348,29 @@ s, low, high, max) {
235
348
  },
236
349
  };
237
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;
238
356
  const actualLow = low ?? 0;
239
357
  const actualHigh = high ?? s.length;
240
- if (actualLow < 0 || actualHigh < actualLow || actualHigh > s.length) {
241
- 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}`);
242
363
  }
243
- const subArrayView = s.subarray(actualLow, actualHigh); // This is Uint8Array
364
+ const newLength = actualHigh - actualLow;
244
365
  if (max !== undefined) {
245
- if (max < actualHigh || max > s.length) {
366
+ if (max < actualHigh || max > baseCapacity) {
246
367
  // max is relative to the original s.length (capacity)
247
- 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}`);
248
369
  }
249
- const newLength = subArrayView.length; // actualHigh - actualLow
250
370
  const newCap = max - actualLow; // Capacity of the new slice view
251
- if (newCap !== newLength) {
252
- // Capacity is different from length, so return SliceProxy<number>
253
- // The original s was Uint8Array, so T is effectively 'number' for this path.
254
- const backingNumbers = Array.from(subArrayView); // Convert Uint8Array data to number[]
255
- const proxyTarget = {
256
- __meta__: {
257
- backing: backingNumbers, // number[]
258
- offset: 0, // Offset is 0 because backingNumbers is a direct copy
259
- length: newLength,
260
- capacity: newCap,
261
- },
262
- };
263
- // Explicitly cast to Slice<T> after ensuring T is number for this branch.
264
- return new Proxy(proxyTarget, handler);
265
- }
266
- else {
267
- // newCap === newLength, standard Uint8Array is fine.
268
- return subArrayView; // T is number
269
- }
270
- }
271
- else {
272
- // max is not defined, return the Uint8Array subarray view directly.
273
- return subArrayView; // T is number
371
+ return byteSliceView(backing, baseOffset + actualLow, newLength, newCap);
274
372
  }
373
+ return byteSliceView(backing, baseOffset + actualLow, newLength, baseCapacity - actualLow);
275
374
  }
276
375
  // Handle nil slices - in Go, slicing a nil slice with valid bounds returns nil
277
376
  if (s === null || s === undefined) {
@@ -343,7 +442,7 @@ s, low, high, max) {
343
442
  const newLength = high - low;
344
443
  const newOffset = oldOffset + low;
345
444
  // OPTIMIZATION: If the result would have offset=0 and length=capacity, return backing directly
346
- if (newOffset === 0 && newLength === newCap) {
445
+ if (newOffset === 0 && newLength === newCap && backing.length === newLength) {
347
446
  return backing;
348
447
  }
349
448
  // Create an array-like target with the correct length
@@ -387,9 +486,9 @@ export const arrayToSlice = (arr, depth = 1) => {
387
486
  };
388
487
  const handler = {
389
488
  get(target, prop) {
390
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
391
- const index = Number(prop);
392
- if (index >= 0 && index < target.__meta__.length) {
489
+ const index = sliceIndexProperty(prop);
490
+ if (index >= 0) {
491
+ if (index < target.__meta__.length) {
393
492
  return target.__meta__.backing[target.__meta__.offset + index];
394
493
  }
395
494
  throw new Error(`Slice index out of range: ${index} >= ${target.__meta__.length}`);
@@ -412,9 +511,9 @@ export const arrayToSlice = (arr, depth = 1) => {
412
511
  return Reflect.get(target, prop);
413
512
  },
414
513
  set(target, prop, value) {
415
- if (typeof prop === 'string' && /^\d+$/.test(prop)) {
416
- const index = Number(prop);
417
- if (index >= 0 && index < target.__meta__.length) {
514
+ const index = sliceIndexProperty(prop);
515
+ if (index >= 0) {
516
+ if (index < target.__meta__.length) {
418
517
  target.__meta__.backing[target.__meta__.offset + index] = value;
419
518
  return true;
420
519
  }
@@ -449,23 +548,34 @@ export const arrayToSlice = (arr, depth = 1) => {
449
548
  * @returns The length of the collection.
450
549
  */
451
550
  export const len = (obj) => {
551
+ obj = collectionValue(obj);
452
552
  if (obj === null || obj === undefined) {
453
553
  return 0;
454
554
  }
455
555
  if (typeof obj === 'string') {
456
- return stringLen(obj); // Call new stringLen for strings
556
+ return stringLen(obj);
557
+ }
558
+ if (obj instanceof Uint8Array) {
559
+ return obj.length;
560
+ }
561
+ if (Array.isArray(obj)) {
562
+ const meta = obj.__meta__;
563
+ if (meta !== undefined) {
564
+ return meta.length;
565
+ }
566
+ return obj.length;
457
567
  }
458
568
  if (obj instanceof Map || obj instanceof Set) {
459
569
  return obj.size;
460
570
  }
461
- if (obj instanceof Uint8Array) {
462
- return obj.length;
571
+ if (obj instanceof GoBinaryString) {
572
+ return stringLen(obj);
463
573
  }
464
574
  if (isComplexSlice(obj)) {
465
575
  return obj.__meta__.length;
466
576
  }
467
- if (Array.isArray(obj)) {
468
- return obj.length;
577
+ if (typeof obj.len === 'function') {
578
+ return obj.len();
469
579
  }
470
580
  throw new Error('cannot determine len of this type');
471
581
  };
@@ -475,72 +585,32 @@ export const len = (obj) => {
475
585
  * @returns The capacity of the slice.
476
586
  */
477
587
  export const cap = (obj) => {
588
+ obj = collectionValue(obj);
478
589
  if (obj === null || obj === undefined) {
479
590
  return 0;
480
591
  }
481
- if (obj instanceof Uint8Array) {
482
- return obj.length; // Uint8Array capacity is its length
483
- }
484
592
  if (isComplexSlice(obj)) {
485
593
  return obj.__meta__.capacity;
486
594
  }
595
+ if (obj instanceof Uint8Array) {
596
+ return obj.length; // Uint8Array capacity is its length
597
+ }
487
598
  if (Array.isArray(obj)) {
488
599
  return obj.length;
489
600
  }
601
+ if (typeof obj.cap === 'function') {
602
+ return obj.cap();
603
+ }
490
604
  return 0;
491
605
  };
492
606
  export function append(slice, ...elements) {
493
607
  // 1. Flatten all elements from the varargs `...elements` into `varargsElements`.
494
608
  // Determine if the result should be a Uint8Array.
495
609
  const inputIsUint8Array = slice instanceof Uint8Array;
496
- const appendingUint8Array = elements.some((el) => el instanceof Uint8Array);
497
- const produceUint8Array = inputIsUint8Array ||
498
- appendingUint8Array ||
499
- (slice === null && appendingUint8Array);
610
+ const produceUint8Array = inputIsUint8Array;
500
611
  // If producing Uint8Array, all elements must be numbers and potentially flattened from other Uint8Arrays/number slices.
501
612
  if (produceUint8Array) {
502
- let combinedBytes = [];
503
- // Add bytes from the original slice if it exists and is numeric.
504
- if (inputIsUint8Array) {
505
- combinedBytes.push(...Array.from(slice));
506
- }
507
- else if (slice !== null && slice !== undefined) {
508
- // Original was Slice<number> or number[]
509
- const sliceLen = len(slice);
510
- for (let i = 0; i < sliceLen; i++) {
511
- const val = slice[i];
512
- if (typeof val !== 'number') {
513
- throw new Error('Cannot produce Uint8Array: original slice contains non-number elements.');
514
- }
515
- combinedBytes.push(val);
516
- }
517
- }
518
- // Add bytes from the varargs elements.
519
- // For Uint8Array, elements are always flattened if they are slices/Uint8Arrays.
520
- for (const item of elements) {
521
- if (item instanceof Uint8Array) {
522
- combinedBytes.push(...Array.from(item));
523
- }
524
- else if (isComplexSlice(item) || Array.isArray(item)) {
525
- const itemLen = len(item);
526
- for (let i = 0; i < itemLen; i++) {
527
- const val = item[i];
528
- if (typeof val !== 'number') {
529
- throw new Error('Cannot produce Uint8Array: appended elements contain non-numbers.');
530
- }
531
- combinedBytes.push(val);
532
- }
533
- }
534
- else {
535
- if (typeof item !== 'number') {
536
- throw new Error('Cannot produce Uint8Array: appended elements contain non-numbers.');
537
- }
538
- combinedBytes.push(item);
539
- }
540
- }
541
- const newArr = new Uint8Array(combinedBytes.length);
542
- newArr.set(combinedBytes);
543
- return newArr;
613
+ return appendByteSlice(slice, elements);
544
614
  }
545
615
  // Handle generic Slice<T> (non-Uint8Array result).
546
616
  // In this case, `elements` are treated as individual items to append,
@@ -549,45 +619,44 @@ export function append(slice, ...elements) {
549
619
  if (numAdded === 0) {
550
620
  return slice;
551
621
  }
552
- let originalElements = [];
622
+ let originalElements;
623
+ let oldLength = 0;
553
624
  let oldCapacity;
554
625
  let isOriginalComplex = false;
555
626
  let originalBacking = undefined;
627
+ let originalTarget = undefined;
556
628
  let originalOffset = 0;
557
629
  if (slice === null || slice === undefined) {
558
630
  oldCapacity = 0;
559
631
  }
560
632
  else if (isComplexSlice(slice)) {
561
633
  const meta = slice.__meta__;
562
- for (let i = 0; i < meta.length; i++)
563
- originalElements.push(meta.backing[meta.offset + i]);
634
+ oldLength = meta.length;
564
635
  oldCapacity = meta.capacity;
565
636
  isOriginalComplex = true;
566
637
  originalBacking = meta.backing;
638
+ originalTarget = meta.target;
567
639
  originalOffset = meta.offset;
568
640
  }
569
641
  else {
570
642
  // Simple T[] array
571
643
  originalElements = slice.slice();
572
- oldCapacity = slice.length;
644
+ oldLength = originalElements.length;
645
+ oldCapacity = oldLength;
573
646
  }
574
- const oldLength = originalElements.length;
575
647
  const newLength = oldLength + numAdded;
576
648
  // Case 1: Modify in-place if original was SliceProxy and has enough capacity.
577
649
  if (isOriginalComplex && newLength <= oldCapacity && originalBacking) {
578
650
  for (let i = 0; i < numAdded; i++) {
579
651
  originalBacking[originalOffset + oldLength + i] = elements[i];
580
652
  }
581
- const resultProxy = new Array(newLength);
582
- for (let i = 0; i < newLength; i++)
583
- resultProxy[i] = originalBacking[originalOffset + i];
584
- resultProxy.__meta__ = {
585
- backing: originalBacking,
586
- offset: originalOffset,
587
- length: newLength,
588
- capacity: oldCapacity,
589
- };
590
- 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);
591
660
  }
592
661
  // Case 2: Reallocation is needed.
593
662
  let newCapacity = oldCapacity;
@@ -604,29 +673,88 @@ export function append(slice, ...elements) {
604
673
  newCapacity = newLength;
605
674
  }
606
675
  const newBacking = new Array(newCapacity);
607
- for (let i = 0; i < oldLength; i++) {
608
- 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
+ }
609
685
  }
610
686
  for (let i = 0; i < numAdded; i++) {
611
687
  newBacking[oldLength + i] = elements[i];
612
688
  }
613
- const resultProxy = new Array(newLength);
614
- for (let i = 0; i < newLength; i++)
615
- resultProxy[i] = newBacking[i];
616
- resultProxy.__meta__ = {
617
- backing: newBacking,
618
- offset: 0,
619
- length: newLength,
620
- capacity: newCapacity,
621
- };
622
- 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;
712
+ }
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++;
750
+ }
623
751
  }
624
752
  export function copy(dst, src) {
625
753
  if (dst === null) {
626
754
  return 0;
627
755
  }
628
756
  // Handle string source first
629
- if (typeof src === 'string') {
757
+ if (isGoStringValue(src)) {
630
758
  return copyFromString(dst, src);
631
759
  }
632
760
  if (src === null) {
@@ -661,26 +789,27 @@ export function copy(dst, src) {
661
789
  */
662
790
  function copyFromString(dst, src) {
663
791
  const dstLen = dst instanceof Uint8Array ? dst.length : len(dst);
664
- const count = Math.min(dstLen, src.length);
792
+ const bytes = goStringBytes(src);
793
+ const count = Math.min(dstLen, bytes.length);
665
794
  if (count === 0) {
666
795
  return 0;
667
796
  }
668
797
  if (dst instanceof Uint8Array) {
669
798
  for (let i = 0; i < count; i++) {
670
- dst[i] = src.charCodeAt(i);
799
+ dst[i] = bytes[i];
671
800
  }
672
801
  }
673
802
  else if (isComplexSlice(dst)) {
674
803
  const dstMeta = dst.__meta__;
675
804
  for (let i = 0; i < count; i++) {
676
- const byteVal = src.charCodeAt(i);
805
+ const byteVal = bytes[i];
677
806
  dstMeta.backing[dstMeta.offset + i] = byteVal;
678
807
  dst[i] = byteVal;
679
808
  }
680
809
  }
681
810
  else if (Array.isArray(dst)) {
682
811
  for (let i = 0; i < count; i++) {
683
- dst[i] = src.charCodeAt(i);
812
+ dst[i] = bytes[i];
684
813
  }
685
814
  }
686
815
  return count;
@@ -689,16 +818,9 @@ function copyFromString(dst, src) {
689
818
  * Helper: Copy from Slice<number> to Uint8Array
690
819
  */
691
820
  function copyToUint8Array(dst, src, count) {
692
- if (isComplexSlice(src)) {
693
- const srcMeta = src.__meta__;
694
- for (let i = 0; i < count; i++) {
695
- dst[i] = srcMeta.backing[srcMeta.offset + i];
696
- }
697
- }
698
- else if (Array.isArray(src)) {
699
- for (let i = 0; i < count; i++) {
700
- dst[i] = src[i];
701
- }
821
+ const values = copySliceValues(src, count);
822
+ for (let i = 0; i < count; i++) {
823
+ dst[i] = values[i];
702
824
  }
703
825
  return count;
704
826
  }
@@ -706,16 +828,17 @@ function copyToUint8Array(dst, src, count) {
706
828
  * Helper: Copy from Uint8Array to Slice<T>
707
829
  */
708
830
  function copyFromUint8Array(dst, src, count) {
831
+ const values = Array.from(src.subarray(0, count));
709
832
  if (isComplexSlice(dst)) {
710
833
  const dstMeta = dst.__meta__;
711
834
  for (let i = 0; i < count; i++) {
712
- dstMeta.backing[dstMeta.offset + i] = src[i];
713
- dst[i] = src[i];
835
+ dstMeta.backing[dstMeta.offset + i] = values[i];
836
+ dst[i] = values[i];
714
837
  }
715
838
  }
716
839
  else if (Array.isArray(dst)) {
717
840
  for (let i = 0; i < count; i++) {
718
- dst[i] = src[i];
841
+ dst[i] = values[i];
719
842
  }
720
843
  }
721
844
  return count;
@@ -724,38 +847,36 @@ function copyFromUint8Array(dst, src, count) {
724
847
  * Helper: Copy between two Slice<T> instances
725
848
  */
726
849
  function copyBetweenSlices(dst, src, count) {
850
+ const values = copySliceValues(src, count);
727
851
  if (isComplexSlice(dst)) {
728
852
  const dstMeta = dst.__meta__;
729
- if (isComplexSlice(src)) {
730
- const srcMeta = src.__meta__;
731
- for (let i = 0; i < count; i++) {
732
- dstMeta.backing[dstMeta.offset + i] =
733
- srcMeta.backing[srcMeta.offset + i];
734
- dst[i] = srcMeta.backing[srcMeta.offset + i];
735
- }
736
- }
737
- else if (Array.isArray(src)) {
738
- for (let i = 0; i < count; i++) {
739
- dstMeta.backing[dstMeta.offset + i] = src[i];
740
- dst[i] = src[i];
741
- }
853
+ for (let i = 0; i < count; i++) {
854
+ dstMeta.backing[dstMeta.offset + i] = values[i];
855
+ dst[i] = values[i];
742
856
  }
743
857
  }
744
858
  else if (Array.isArray(dst)) {
745
- if (isComplexSlice(src)) {
746
- const srcMeta = src.__meta__;
747
- for (let i = 0; i < count; i++) {
748
- dst[i] = srcMeta.backing[srcMeta.offset + i];
749
- }
750
- }
751
- else if (Array.isArray(src)) {
752
- for (let i = 0; i < count; i++) {
753
- dst[i] = src[i];
754
- }
859
+ for (let i = 0; i < count; i++) {
860
+ dst[i] = values[i];
755
861
  }
756
862
  }
757
863
  return count;
758
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
+ }
759
880
  /**
760
881
  * Accesses an element at a specific index for various Go-like types (string, slice, array).
761
882
  * Mimics Go's indexing behavior: `myCollection[index]`
@@ -771,7 +892,7 @@ export function index(collection, index) {
771
892
  if (collection === null || collection === undefined) {
772
893
  throw new Error('runtime error: index on nil or undefined collection');
773
894
  }
774
- if (typeof collection === 'string') {
895
+ if (isGoStringValue(collection)) {
775
896
  return indexString(collection, index); // Use the existing indexString for byte access
776
897
  }
777
898
  else if (collection instanceof Uint8Array) {
@@ -794,6 +915,120 @@ export function index(collection, index) {
794
915
  }
795
916
  throw new Error('runtime error: index on unsupported type');
796
917
  }
918
+ /**
919
+ * indexRef returns an addressable reference to a slice or array element.
920
+ */
921
+ export function indexRef(collection, index) {
922
+ if (collection === null || collection === undefined) {
923
+ throw new Error('runtime error: index on nil or undefined collection');
924
+ }
925
+ if (collection instanceof Uint8Array) {
926
+ if (index < 0 || index >= collection.length) {
927
+ throw new Error(`runtime error: index out of range [${index}] with length ${collection.length}`);
928
+ }
929
+ return {
930
+ get value() {
931
+ return collection[index];
932
+ },
933
+ set value(value) {
934
+ collection[index] = value;
935
+ },
936
+ __isVarRef: true,
937
+ __goAddress: () => indexAddress(collection, index),
938
+ __goCollection: collection,
939
+ __goIndex: index,
940
+ };
941
+ }
942
+ if (isComplexSlice(collection)) {
943
+ if (index < 0 || index >= collection.__meta__.length) {
944
+ throw new Error(`runtime error: index out of range [${index}] with length ${collection.__meta__.length}`);
945
+ }
946
+ const backingIndex = collection.__meta__.offset + index;
947
+ return {
948
+ get value() {
949
+ return collection.__meta__.backing[backingIndex];
950
+ },
951
+ set value(value) {
952
+ collection[index] = value;
953
+ },
954
+ __isVarRef: true,
955
+ __goAddress: () => indexAddress(collection, index),
956
+ __goCollection: collection,
957
+ __goIndex: index,
958
+ };
959
+ }
960
+ if (Array.isArray(collection)) {
961
+ if (index < 0 || index >= collection.length) {
962
+ throw new Error(`runtime error: index out of range [${index}] with length ${collection.length}`);
963
+ }
964
+ return {
965
+ get value() {
966
+ return collection[index];
967
+ },
968
+ set value(value) {
969
+ collection[index] = value;
970
+ },
971
+ __isVarRef: true,
972
+ __goAddress: () => indexAddress(collection, index),
973
+ __goCollection: collection,
974
+ __goIndex: index,
975
+ };
976
+ }
977
+ throw new Error('runtime error: index on unsupported type');
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
+ }
992
+ /**
993
+ * indexAddress returns a stable synthetic address for an addressable slice or
994
+ * array element.
995
+ */
996
+ export function indexAddress(collection, index) {
997
+ if (collection === null || collection === undefined) {
998
+ throw new Error('runtime error: index on nil or undefined collection');
999
+ }
1000
+ let backing;
1001
+ let backingIndex;
1002
+ let length;
1003
+ if (collection instanceof Uint8Array) {
1004
+ backing = collection.buffer;
1005
+ backingIndex = collection.byteOffset + index;
1006
+ length = collection.length;
1007
+ }
1008
+ else if (isComplexSlice(collection)) {
1009
+ backing = collection.__meta__.backing;
1010
+ backingIndex = collection.__meta__.offset + index;
1011
+ length = collection.__meta__.length;
1012
+ }
1013
+ else if (Array.isArray(collection)) {
1014
+ backing = collection;
1015
+ backingIndex = index;
1016
+ length = collection.length;
1017
+ }
1018
+ else {
1019
+ throw new Error('runtime error: index on unsupported type');
1020
+ }
1021
+ if (index < 0 || index >= length) {
1022
+ throw new Error(`runtime error: index out of range [${index}] with length ${length}`);
1023
+ }
1024
+ let base = addressBases.get(backing);
1025
+ if (base === undefined) {
1026
+ base = nextAddressBase * addressStride;
1027
+ nextAddressBase++;
1028
+ addressBases.set(backing, base);
1029
+ }
1030
+ return base + backingIndex;
1031
+ }
797
1032
  /**
798
1033
  * Converts a string to an array of Unicode code points (runes).
799
1034
  * @param str The input string.
@@ -802,6 +1037,21 @@ export function index(collection, index) {
802
1037
  export const stringToRunes = (str) => {
803
1038
  return Array.from(str).map((c) => c.codePointAt(0) || 0);
804
1039
  };
1040
+ /**
1041
+ * Returns Go range pairs for a string: UTF-8 byte offset and rune value.
1042
+ * @param str The input string.
1043
+ * @returns Index/rune pairs matching Go's `for i, r := range str`.
1044
+ */
1045
+ export const rangeString = (str) => {
1046
+ const encoder = new TextEncoder();
1047
+ const pairs = [];
1048
+ let offset = 0;
1049
+ for (const char of str) {
1050
+ pairs.push([offset, char.codePointAt(0) || 0]);
1051
+ offset += encoder.encode(char).length;
1052
+ }
1053
+ return pairs;
1054
+ };
805
1055
  /**
806
1056
  * Converts a single-character string to its Unicode code point (rune).
807
1057
  * Used for readable rune constants like $.stringToRune('/') instead of 47.
@@ -840,7 +1090,7 @@ export const byte = (n) => {
840
1090
  * @throws Error if index is out of bounds.
841
1091
  */
842
1092
  export const indexString = (str, index) => {
843
- if (typeof str !== 'string') {
1093
+ if (!isGoStringValue(str)) {
844
1094
  // Bytes - access directly
845
1095
  if (str instanceof Uint8Array) {
846
1096
  if (index < 0 || index >= str.length) {
@@ -857,7 +1107,7 @@ export const indexString = (str, index) => {
857
1107
  }
858
1108
  return str[index];
859
1109
  }
860
- const bytes = new TextEncoder().encode(str);
1110
+ const bytes = goStringBytes(str);
861
1111
  if (index < 0 || index >= bytes.length) {
862
1112
  throw new Error(`runtime error: index out of range [${index}] with length ${bytes.length}`);
863
1113
  }
@@ -870,7 +1120,7 @@ export const indexString = (str, index) => {
870
1120
  * @returns The number of bytes in the UTF-8 representation of the string.
871
1121
  */
872
1122
  export const stringLen = (str) => {
873
- return new TextEncoder().encode(str).length;
1123
+ return goStringBytes(str).length;
874
1124
  };
875
1125
  /**
876
1126
  * Slices a string based on byte indices.
@@ -882,7 +1132,7 @@ export const stringLen = (str) => {
882
1132
  * @throws Error if the slice would create invalid UTF-8.
883
1133
  */
884
1134
  export const sliceString = (str, low, high) => {
885
- const bytes = new TextEncoder().encode(str);
1135
+ const bytes = goStringBytes(str);
886
1136
  const actualLow = low === undefined ? 0 : low;
887
1137
  const actualHigh = high === undefined ? bytes.length : high;
888
1138
  if (actualLow < 0 || actualHigh < actualLow || actualHigh > bytes.length) {
@@ -898,18 +1148,7 @@ export const sliceString = (str, low, high) => {
898
1148
  }
899
1149
  throw new Error(`runtime error: slice bounds out of range [${actualLow}:${actualHigh}] with length ${bytes.length}`);
900
1150
  }
901
- const slicedBytes = bytes.subarray(actualLow, actualHigh);
902
- try {
903
- // Attempt to decode with strict UTF-8 validation
904
- const result = new TextDecoder('utf-8', { fatal: true }).decode(slicedBytes);
905
- return result;
906
- }
907
- catch (e) {
908
- // If we get here, the slice would create invalid UTF-8
909
- // This is a fundamental limitation of JavaScript string handling
910
- throw new Error(`Cannot slice string at byte indices [${actualLow}:${actualHigh}] because it would create invalid UTF-8. ` +
911
- `This is a limitation of JavaScript's string handling.`, { cause: e });
912
- }
1151
+ return goStringFromBytes(bytes.subarray(actualLow, actualHigh));
913
1152
  };
914
1153
  /**
915
1154
  * Converts a Slice<number> (byte array) to a string using TextDecoder.
@@ -922,9 +1161,8 @@ export const bytesToString = (bytes) => {
922
1161
  // If it's already a string, just return it
923
1162
  if (typeof bytes === 'string')
924
1163
  return bytes;
925
- if (bytes instanceof Uint8Array) {
926
- return new TextDecoder().decode(bytes);
927
- }
1164
+ if (bytes instanceof Uint8Array)
1165
+ return goStringFromBytes(bytes);
928
1166
  // Ensure we get a plain number[] for Uint8Array.from
929
1167
  let byteArray;
930
1168
  if (isComplexSlice(bytes)) {
@@ -935,16 +1173,102 @@ export const bytesToString = (bytes) => {
935
1173
  // For simple T[] slices
936
1174
  byteArray = bytes;
937
1175
  }
938
- return new TextDecoder().decode(Uint8Array.from(byteArray));
1176
+ return goStringFromBytes(Uint8Array.from(byteArray));
939
1177
  };
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
+ }
1188
+ }
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
+ }
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;
1255
+ }
1256
+ function bytesToBinaryString(bytes) {
1257
+ const chunkSize = 0x8000;
1258
+ let out = '';
1259
+ for (let i = 0; i < bytes.length; i += chunkSize) {
1260
+ out += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
1261
+ }
1262
+ return out;
1263
+ }
940
1264
  /**
941
1265
  * Converts a string to a Uint8Array (byte slice).
942
1266
  * @param s The input string.
943
1267
  * @returns A Uint8Array representing the UTF-8 bytes of the string.
944
1268
  */
945
1269
  export function stringToBytes(s) {
946
- if (typeof s === 'string') {
947
- return new TextEncoder().encode(s);
1270
+ if (isGoStringValue(s)) {
1271
+ return goStringBytes(s);
948
1272
  }
949
1273
  // Already bytes - normalize to Uint8Array
950
1274
  if (s instanceof Uint8Array) {
@@ -956,6 +1280,57 @@ export function stringToBytes(s) {
956
1280
  // Handle array or slice types
957
1281
  return new Uint8Array(Array.isArray(s) ? s : []);
958
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
+ }
959
1334
  /**
960
1335
  * Handles string() conversion for values that could be either string or []byte.
961
1336
  * Used for generic type parameters with constraint []byte|string.
@@ -966,7 +1341,7 @@ export function genericBytesOrStringToString(value) {
966
1341
  if (value === null || value === undefined) {
967
1342
  return '';
968
1343
  }
969
- if (typeof value === 'string') {
1344
+ if (isGoStringValue(value)) {
970
1345
  return value;
971
1346
  }
972
1347
  return bytesToString(value);
@@ -980,7 +1355,7 @@ export function genericBytesOrStringToString(value) {
980
1355
  * @returns The byte value at the specified index
981
1356
  */
982
1357
  export function indexStringOrBytes(value, index) {
983
- if (typeof value === 'string') {
1358
+ if (isGoStringValue(value)) {
984
1359
  return indexString(value, index);
985
1360
  }
986
1361
  else if (value instanceof Uint8Array) {
@@ -1012,7 +1387,7 @@ export function indexStringOrBytes(value, index) {
1012
1387
  * @returns The sliced value of the same type as input
1013
1388
  */
1014
1389
  export function sliceStringOrBytes(value, low, high, max) {
1015
- if (typeof value === 'string') {
1390
+ if (isGoStringValue(value)) {
1016
1391
  // For strings, use sliceString and ignore max parameter
1017
1392
  return sliceString(value, low, high);
1018
1393
  }