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.
- package/README.md +267 -255
- package/cmd/goscript/cmd-test.go +286 -0
- package/cmd/goscript/cmd-test_test.go +76 -0
- package/cmd/goscript/cmd_compile.go +9 -0
- package/cmd/goscript/main.go +1 -0
- package/compiler/build-flags.go +38 -0
- package/compiler/compile-request.go +33 -0
- package/compiler/compiler.go +1 -1
- package/compiler/compliance_test.go +0 -10
- package/compiler/config.go +2 -0
- package/compiler/gotest/owner.go +24 -0
- package/compiler/gotest/package-result.go +69 -0
- package/compiler/gotest/request.go +210 -0
- package/compiler/gotest/result.go +28 -0
- package/compiler/gotest/runner.go +1225 -0
- package/compiler/gotest/runner_test.go +1271 -0
- package/compiler/gotest/test.go +9 -0
- package/compiler/index.test.ts +1 -1
- package/compiler/lowered-program.go +80 -21
- package/compiler/lowering.go +6754 -602
- package/compiler/override-facts.go +357 -0
- package/compiler/override-registry.go +52 -190
- package/compiler/override-registry_test.go +182 -0
- package/compiler/package-graph.go +50 -27
- package/compiler/package-graph_test.go +99 -9
- package/compiler/package-test-function.go +9 -0
- package/compiler/package-test-graph-package.go +40 -0
- package/compiler/package-test-graph-variant.go +129 -0
- package/compiler/package-test-graph.go +112 -0
- package/compiler/package-test-graph_test.go +202 -0
- package/compiler/runtime-contract.go +229 -29
- package/compiler/runtime-contract_test.go +44 -30
- package/compiler/semantic-model-types.go +25 -6
- package/compiler/semantic-model.go +819 -74
- package/compiler/semantic-model_test.go +104 -0
- package/compiler/service.go +10 -4
- package/compiler/skeleton_test.go +2777 -524
- package/compiler/tsworkspace/owner-process-unix_test.go +72 -0
- package/compiler/tsworkspace/owner.go +342 -0
- package/compiler/tsworkspace/owner_test.go +93 -0
- package/compiler/tsworkspace/result.go +17 -0
- package/compiler/tsworkspace/tool-process-other.go +14 -0
- package/compiler/tsworkspace/tool-process-unix.go +19 -0
- package/compiler/typescript-emitter.go +576 -86
- package/compiler/wasm/compile.go +1 -1
- package/compiler/wasm/compile_test.go +61 -11
- package/compiler/wasm_api.go +172 -7
- package/dist/gs/builtin/builtin.d.ts +40 -3
- package/dist/gs/builtin/builtin.js +430 -22
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/channel.d.ts +32 -10
- package/dist/gs/builtin/channel.js +119 -25
- package/dist/gs/builtin/channel.js.map +1 -1
- package/dist/gs/builtin/defer.d.ts +1 -0
- package/dist/gs/builtin/defer.js +12 -2
- package/dist/gs/builtin/defer.js.map +1 -1
- package/dist/gs/builtin/hostio.d.ts +9 -0
- package/dist/gs/builtin/hostio.js +25 -0
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/map.js +40 -6
- package/dist/gs/builtin/map.js.map +1 -1
- package/dist/gs/builtin/print.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +64 -10
- package/dist/gs/builtin/slice.js +619 -244
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +7 -2
- package/dist/gs/builtin/type.js +128 -29
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +7 -0
- package/dist/gs/builtin/varRef.js +23 -0
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +74 -70
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/iter.gs.js +13 -13
- package/dist/gs/bytes/iter.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +20 -18
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +26 -0
- package/dist/gs/compress/zlib/index.js +168 -0
- package/dist/gs/compress/zlib/index.js.map +1 -0
- package/dist/gs/context/context.d.ts +6 -5
- package/dist/gs/context/context.js +17 -12
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/crypto/ecdh/index.d.ts +52 -0
- package/dist/gs/crypto/ecdh/index.js +226 -0
- package/dist/gs/crypto/ecdh/index.js.map +1 -0
- package/dist/gs/crypto/ed25519/index.d.ts +34 -0
- package/dist/gs/crypto/ed25519/index.js +160 -0
- package/dist/gs/crypto/ed25519/index.js.map +1 -0
- package/dist/gs/crypto/internal/constanttime/index.d.ts +4 -0
- package/dist/gs/crypto/internal/constanttime/index.js +18 -0
- package/dist/gs/crypto/internal/constanttime/index.js.map +1 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.d.ts +1 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.js +2 -0
- package/dist/gs/crypto/internal/fips140deps/byteorder/index.js.map +1 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.d.ts +1 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.js +2 -0
- package/dist/gs/crypto/internal/fips140deps/godebug/index.js.map +1 -0
- package/dist/gs/crypto/rand/index.d.ts +2 -0
- package/dist/gs/crypto/rand/index.js +85 -0
- package/dist/gs/crypto/rand/index.js.map +1 -1
- package/dist/gs/crypto/sha256/index.d.ts +8 -0
- package/dist/gs/crypto/sha256/index.js +118 -0
- package/dist/gs/crypto/sha256/index.js.map +1 -0
- package/dist/gs/crypto/sha512/index.d.ts +14 -0
- package/dist/gs/crypto/sha512/index.js +129 -0
- package/dist/gs/crypto/sha512/index.js.map +1 -0
- package/dist/gs/embed/index.d.ts +7 -0
- package/dist/gs/embed/index.js +16 -0
- package/dist/gs/embed/index.js.map +1 -0
- package/dist/gs/encoding/json/index.d.ts +4 -0
- package/dist/gs/encoding/json/index.js +33 -0
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/errors/errors.d.ts +4 -0
- package/dist/gs/errors/errors.js +108 -4
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +4 -4
- package/dist/gs/fmt/fmt.js +42 -11
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +37 -2
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +245 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +189 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +861 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +217 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +814 -0
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +20 -0
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js +134 -0
- package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.js.map +1 -1
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.d.ts +3 -0
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js +50 -0
- package/dist/gs/github.com/hack-pad/safejs/internal/catch/index.js.map +1 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.d.ts +9 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js +72 -0
- package/dist/gs/github.com/klauspost/compress/internal/le/index.js.map +1 -0
- package/dist/gs/github.com/mr-tron/base58/base58/index.d.ts +27 -0
- package/dist/gs/github.com/mr-tron/base58/base58/index.js +172 -0
- package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.d.ts +21 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js +22 -0
- package/dist/gs/github.com/zeebo/blake3/internal/consts/index.js.map +1 -0
- package/dist/gs/go/internal/scannerhooks/index.d.ts +3 -0
- package/dist/gs/go/internal/scannerhooks/index.js +5 -0
- package/dist/gs/go/internal/scannerhooks/index.js.map +1 -0
- package/dist/gs/go/scanner/index.d.ts +13 -0
- package/dist/gs/go/scanner/index.js +35 -0
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.d.ts +156 -0
- package/dist/gs/go/token/index.js +507 -4
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/fnv/index.d.ts +57 -0
- package/dist/gs/hash/fnv/index.js +299 -0
- package/dist/gs/hash/fnv/index.js.map +1 -0
- package/dist/gs/hash/index.d.ts +17 -0
- package/dist/gs/hash/index.js +94 -0
- package/dist/gs/hash/index.js.map +1 -0
- package/dist/gs/internal/abi/index.d.ts +4 -0
- package/dist/gs/internal/abi/index.js +10 -0
- package/dist/gs/internal/abi/index.js.map +1 -1
- package/dist/gs/internal/bytealg/index.d.ts +2 -0
- package/dist/gs/internal/bytealg/index.js +14 -0
- package/dist/gs/internal/bytealg/index.js.map +1 -1
- package/dist/gs/internal/byteorder/index.d.ts +8 -2
- package/dist/gs/internal/byteorder/index.js +56 -25
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/internal/godebug/index.d.ts +12 -0
- package/dist/gs/internal/godebug/index.js +30 -0
- package/dist/gs/internal/godebug/index.js.map +1 -0
- package/dist/gs/io/fs/index.d.ts +1 -0
- package/dist/gs/io/fs/index.js +1 -0
- package/dist/gs/io/fs/index.js.map +1 -1
- package/dist/gs/io/fs/readlink.d.ts +8 -0
- package/dist/gs/io/fs/readlink.js +60 -0
- package/dist/gs/io/fs/readlink.js.map +1 -0
- package/dist/gs/io/fs/walk.d.ts +3 -3
- package/dist/gs/io/fs/walk.js +7 -7
- package/dist/gs/io/fs/walk.js.map +1 -1
- package/dist/gs/io/io.d.ts +40 -6
- package/dist/gs/io/io.js +151 -26
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/iter/iter.d.ts +3 -2
- package/dist/gs/iter/iter.js.map +1 -1
- package/dist/gs/maps/iter.d.ts +5 -5
- package/dist/gs/maps/iter.js +48 -21
- package/dist/gs/maps/iter.js.map +1 -1
- package/dist/gs/maps/maps.d.ts +6 -6
- package/dist/gs/maps/maps.js +1 -1
- package/dist/gs/maps/maps.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +13 -4
- package/dist/gs/math/bits/index.js +70 -48
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/math/const.gs.d.ts +5 -5
- package/dist/gs/math/const.gs.js +4 -4
- package/dist/gs/math/const.gs.js.map +1 -1
- package/dist/gs/mime/index.d.ts +1 -0
- package/dist/gs/mime/index.js +52 -0
- package/dist/gs/mime/index.js.map +1 -0
- package/dist/gs/net/http/httptest/index.d.ts +30 -0
- package/dist/gs/net/http/httptest/index.js +101 -0
- package/dist/gs/net/http/httptest/index.js.map +1 -0
- package/dist/gs/net/http/index.d.ts +131 -0
- package/dist/gs/net/http/index.js +307 -0
- package/dist/gs/net/http/index.js.map +1 -0
- package/dist/gs/net/http/pprof/index.d.ts +8 -0
- package/dist/gs/net/http/pprof/index.js +59 -0
- package/dist/gs/net/http/pprof/index.js.map +1 -0
- package/dist/gs/os/dir_unix.gs.js +2 -2
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +9 -7
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.js +95 -15
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/path/filepath/match.js +165 -3
- package/dist/gs/path/filepath/match.js.map +1 -1
- package/dist/gs/path/filepath/path.d.ts +8 -4
- package/dist/gs/path/filepath/path.js +192 -8
- package/dist/gs/path/filepath/path.js.map +1 -1
- package/dist/gs/path/path.d.ts +4 -1
- package/dist/gs/path/path.js +16 -4
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +4 -3
- package/dist/gs/reflect/index.js +3 -2
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/iter.js +2 -2
- package/dist/gs/reflect/iter.js.map +1 -1
- package/dist/gs/reflect/map.js +29 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +31 -9
- package/dist/gs/reflect/type.js +536 -43
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +1 -0
- package/dist/gs/reflect/types.js +3 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +4 -1
- package/dist/gs/reflect/value.js +39 -1
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +1 -1
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/debug/index.d.ts +41 -0
- package/dist/gs/runtime/debug/index.js +66 -0
- package/dist/gs/runtime/debug/index.js.map +1 -0
- package/dist/gs/runtime/pprof/index.d.ts +20 -0
- package/dist/gs/runtime/pprof/index.js +85 -0
- package/dist/gs/runtime/pprof/index.js.map +1 -0
- package/dist/gs/runtime/runtime.d.ts +35 -3
- package/dist/gs/runtime/runtime.js +72 -0
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.d.ts +19 -0
- package/dist/gs/runtime/trace/index.js +64 -0
- package/dist/gs/runtime/trace/index.js.map +1 -0
- package/dist/gs/slices/slices.d.ts +42 -8
- package/dist/gs/slices/slices.js +425 -11
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/sort/slice.gs.d.ts +5 -3
- package/dist/gs/sort/slice.gs.js +60 -22
- package/dist/gs/sort/slice.gs.js.map +1 -1
- package/dist/gs/sort/sort.gs.d.ts +4 -4
- package/dist/gs/sort/sort.gs.js +11 -8
- package/dist/gs/sort/sort.gs.js.map +1 -1
- package/dist/gs/strings/builder.d.ts +1 -1
- package/dist/gs/strings/builder.js +29 -19
- package/dist/gs/strings/builder.js.map +1 -1
- package/dist/gs/strings/iter.js +140 -75
- package/dist/gs/strings/iter.js.map +1 -1
- package/dist/gs/strings/replace.js +2 -2
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.js +52 -6
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.d.ts +9 -8
- package/dist/gs/sync/atomic/type.gs.js +0 -2
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +8 -3
- package/dist/gs/sync/sync.js +66 -11
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/constants.d.ts +36 -24
- package/dist/gs/syscall/constants.js +12 -0
- package/dist/gs/syscall/constants.js.map +1 -1
- package/dist/gs/syscall/errors.d.ts +117 -111
- package/dist/gs/syscall/errors.js +45 -0
- package/dist/gs/syscall/errors.js.map +1 -1
- package/dist/gs/syscall/fs.d.ts +37 -0
- package/dist/gs/syscall/fs.js +102 -0
- package/dist/gs/syscall/fs.js.map +1 -1
- package/dist/gs/syscall/js/index.d.ts +90 -0
- package/dist/gs/syscall/js/index.js +383 -0
- package/dist/gs/syscall/js/index.js.map +1 -0
- package/dist/gs/syscall/types.d.ts +26 -1
- package/dist/gs/syscall/types.js +45 -1
- package/dist/gs/syscall/types.js.map +1 -1
- package/dist/gs/testing/index.d.ts +1 -0
- package/dist/gs/testing/index.js +2 -0
- package/dist/gs/testing/index.js.map +1 -0
- package/dist/gs/testing/testing.d.ts +78 -0
- package/dist/gs/testing/testing.js +318 -0
- package/dist/gs/testing/testing.js.map +1 -0
- package/dist/gs/time/time.d.ts +41 -4
- package/dist/gs/time/time.js +227 -36
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/unicode.d.ts +23 -1
- package/dist/gs/unicode/unicode.js +79 -10
- package/dist/gs/unicode/unicode.js.map +1 -1
- package/dist/gs/unicode/utf8/utf8.d.ts +4 -4
- package/dist/gs/unicode/utf8/utf8.js +24 -11
- package/dist/gs/unicode/utf8/utf8.js.map +1 -1
- package/dist/gs/unique/index.d.ts +11 -0
- package/dist/gs/unique/index.js +76 -0
- package/dist/gs/unique/index.js.map +1 -0
- package/go.mod +8 -8
- package/go.sum +14 -14
- package/gs/builtin/builtin.ts +585 -27
- package/gs/builtin/channel.ts +183 -29
- package/gs/builtin/defer.ts +13 -2
- package/gs/builtin/hostio.test.ts +1 -0
- package/gs/builtin/hostio.ts +38 -0
- package/gs/builtin/map.ts +46 -6
- package/gs/builtin/print.ts +12 -3
- package/gs/builtin/runtime-contract.test.ts +383 -10
- package/gs/builtin/slice.test.ts +70 -0
- package/gs/builtin/slice.ts +785 -265
- package/gs/builtin/type.ts +160 -41
- package/gs/builtin/varRef.ts +40 -1
- package/gs/bytes/buffer.gs.ts +74 -70
- package/gs/bytes/iter.gs.ts +13 -14
- package/gs/bytes/meta.json +8 -3
- package/gs/bytes/reader.gs.ts +20 -19
- package/gs/compress/zlib/index.test.ts +28 -0
- package/gs/compress/zlib/index.ts +200 -0
- package/gs/compress/zlib/meta.json +3 -0
- package/gs/context/context.test.ts +71 -0
- package/gs/context/context.ts +30 -29
- package/gs/crypto/ecdh/index.test.ts +43 -0
- package/gs/crypto/ecdh/index.ts +274 -0
- package/gs/crypto/ed25519/index.test.ts +41 -0
- package/gs/crypto/ed25519/index.ts +238 -0
- package/gs/crypto/ed25519/meta.json +13 -0
- package/gs/crypto/internal/constanttime/index.test.ts +25 -0
- package/gs/crypto/internal/constanttime/index.ts +22 -0
- package/gs/crypto/internal/fips140deps/byteorder/index.ts +1 -0
- package/gs/crypto/internal/fips140deps/godebug/index.ts +1 -0
- package/gs/crypto/rand/index.test.ts +89 -1
- package/gs/crypto/rand/index.ts +103 -1
- package/gs/crypto/rand/meta.json +4 -1
- package/gs/crypto/sha256/index.test.ts +78 -0
- package/gs/crypto/sha256/index.ts +150 -0
- package/gs/crypto/sha256/meta.json +9 -0
- package/gs/crypto/sha512/index.test.ts +31 -0
- package/gs/crypto/sha512/index.ts +161 -0
- package/gs/crypto/sha512/meta.json +11 -0
- package/gs/embed/index.ts +20 -0
- package/gs/embed/meta.json +5 -0
- package/gs/encoding/json/index.test.ts +39 -3
- package/gs/encoding/json/index.ts +45 -3
- package/gs/errors/errors.test.ts +85 -0
- package/gs/errors/errors.ts +132 -4
- package/gs/fmt/fmt.test.ts +3 -1
- package/gs/fmt/fmt.ts +55 -19
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +128 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +342 -4
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +180 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +1084 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +31 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +1233 -0
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +46 -0
- package/gs/github.com/aperturerobotics/util/conc/index.test.ts +30 -0
- package/gs/github.com/aperturerobotics/util/conc/index.ts +172 -0
- package/gs/github.com/aperturerobotics/util/conc/meta.json +9 -0
- package/gs/github.com/aperturerobotics/wasivm/wazero/kernel/runtime/browser/browser.ts +1 -4
- package/gs/github.com/hack-pad/safejs/internal/catch/index.test.ts +35 -0
- package/gs/github.com/hack-pad/safejs/internal/catch/index.ts +65 -0
- package/gs/github.com/hack-pad/safejs/internal/catch/meta.json +9 -0
- package/gs/github.com/klauspost/compress/internal/le/index.test.ts +37 -0
- package/gs/github.com/klauspost/compress/internal/le/index.ts +115 -0
- package/gs/github.com/mr-tron/base58/base58/index.test.ts +70 -0
- package/gs/github.com/mr-tron/base58/base58/index.ts +231 -0
- package/gs/github.com/mr-tron/base58/base58/meta.json +3 -0
- package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +46 -0
- package/gs/github.com/zeebo/blake3/internal/consts/index.ts +26 -0
- package/gs/go/internal/scannerhooks/index.test.ts +14 -0
- package/gs/go/internal/scannerhooks/index.ts +9 -0
- package/gs/go/scanner/index.test.ts +22 -0
- package/gs/go/scanner/index.ts +47 -0
- package/gs/go/token/index.test.ts +47 -1
- package/gs/go/token/index.ts +583 -4
- package/gs/hash/fnv/index.test.ts +67 -0
- package/gs/hash/fnv/index.ts +351 -0
- package/gs/hash/fnv/meta.json +3 -0
- package/gs/hash/index.test.ts +37 -0
- package/gs/hash/index.ts +118 -0
- package/gs/hash/meta.json +5 -0
- package/gs/internal/abi/index.test.ts +18 -0
- package/gs/internal/abi/index.ts +14 -0
- package/gs/internal/bytealg/index.test.ts +18 -0
- package/gs/internal/bytealg/index.ts +16 -0
- package/gs/internal/byteorder/index.test.ts +39 -0
- package/gs/internal/byteorder/index.ts +100 -27
- package/gs/internal/godebug/index.test.ts +16 -0
- package/gs/internal/godebug/index.ts +35 -0
- package/gs/io/fs/index.ts +1 -0
- package/gs/io/fs/meta.json +5 -0
- package/gs/io/fs/readlink.test.ts +43 -0
- package/gs/io/fs/readlink.ts +69 -0
- package/gs/io/fs/walk.test.ts +61 -0
- package/gs/io/fs/walk.ts +17 -9
- package/gs/io/io.ts +177 -31
- package/gs/io/meta.json +10 -2
- package/gs/iter/iter.ts +8 -2
- package/gs/maps/iter.ts +75 -26
- package/gs/maps/maps.test.ts +23 -0
- package/gs/maps/maps.ts +13 -11
- package/gs/math/bits/index.test.ts +20 -0
- package/gs/math/bits/index.ts +107 -64
- package/gs/math/const.gs.test.ts +11 -5
- package/gs/math/const.gs.ts +5 -6
- package/gs/mime/index.ts +60 -0
- package/gs/net/http/httptest/index.test.ts +53 -0
- package/gs/net/http/httptest/index.ts +120 -0
- package/gs/net/http/index.test.ts +148 -0
- package/gs/net/http/index.ts +432 -0
- package/gs/net/http/meta.json +6 -0
- package/gs/net/http/pprof/index.test.ts +47 -0
- package/gs/net/http/pprof/index.ts +65 -0
- package/gs/os/dir_unix.gs.ts +2 -3
- package/gs/os/error.gs.ts +9 -10
- package/gs/os/error.test.ts +41 -0
- package/gs/os/file_unix_js.test.ts +55 -0
- package/gs/os/tempfile.gs.test.ts +37 -10
- package/gs/os/types_js.gs.ts +96 -17
- package/gs/path/filepath/match.test.ts +31 -12
- package/gs/path/filepath/match.ts +181 -3
- package/gs/path/filepath/meta.json +6 -0
- package/gs/path/filepath/path.test.ts +80 -0
- package/gs/path/filepath/path.ts +244 -11
- package/gs/path/path.ts +20 -5
- package/gs/reflect/field.test.ts +63 -0
- package/gs/reflect/index.ts +5 -1
- package/gs/reflect/iter.ts +2 -2
- package/gs/reflect/map.test.ts +42 -1
- package/gs/reflect/map.ts +39 -0
- package/gs/reflect/type.ts +728 -65
- package/gs/reflect/typefor.test.ts +100 -0
- package/gs/reflect/types.ts +3 -1
- package/gs/reflect/value.ts +50 -1
- package/gs/reflect/visiblefields.ts +1 -1
- package/gs/runtime/debug/index.test.ts +45 -0
- package/gs/runtime/debug/index.ts +96 -0
- package/gs/runtime/pprof/index.test.ts +36 -0
- package/gs/runtime/pprof/index.ts +104 -0
- package/gs/runtime/pprof/meta.json +6 -0
- package/gs/runtime/runtime.test.ts +19 -0
- package/gs/runtime/runtime.ts +98 -3
- package/gs/runtime/trace/index.test.ts +45 -0
- package/gs/runtime/trace/index.ts +97 -0
- package/gs/runtime/trace/meta.json +7 -0
- package/gs/slices/meta.json +2 -1
- package/gs/slices/slices.test.ts +180 -0
- package/gs/slices/slices.ts +502 -15
- package/gs/sort/meta.json +7 -0
- package/gs/sort/slice.gs.ts +85 -26
- package/gs/sort/slice.test.ts +40 -0
- package/gs/sort/sort.gs.ts +16 -13
- package/gs/strings/builder.test.ts +8 -0
- package/gs/strings/builder.ts +33 -20
- package/gs/strings/iter.test.ts +5 -7
- package/gs/strings/iter.ts +146 -71
- package/gs/strings/replace.test.ts +1 -4
- package/gs/strings/replace.ts +6 -6
- package/gs/strings/strings.test.ts +4 -0
- package/gs/strings/strings.ts +54 -6
- package/gs/sync/atomic/type.gs.ts +13 -14
- package/gs/sync/meta.json +3 -1
- package/gs/sync/sync.test.ts +69 -1
- package/gs/sync/sync.ts +72 -13
- package/gs/syscall/constants.ts +39 -24
- package/gs/syscall/errors.ts +165 -112
- package/gs/syscall/fs.ts +195 -0
- package/gs/syscall/js/index.ts +485 -0
- package/gs/syscall/js/meta.json +4 -0
- package/gs/syscall/net.test.ts +111 -0
- package/gs/syscall/types.ts +63 -2
- package/gs/testing/index.ts +1 -0
- package/gs/testing/meta.json +5 -0
- package/gs/testing/testing.test.ts +146 -0
- package/gs/testing/testing.ts +399 -0
- package/gs/time/meta.json +2 -2
- package/gs/time/time.test.ts +110 -0
- package/gs/time/time.ts +309 -57
- package/gs/unicode/unicode.test.ts +36 -0
- package/gs/unicode/unicode.ts +115 -9
- package/gs/unicode/utf8/utf8.test.ts +13 -0
- package/gs/unicode/utf8/utf8.ts +28 -16
- package/gs/unique/index.ts +98 -0
- package/package.json +3 -2
package/gs/builtin/slice.ts
CHANGED
|
@@ -1,3 +1,61 @@
|
|
|
1
|
+
import { isVarRef, varRef, type VarRef } from './varRef.js'
|
|
2
|
+
|
|
3
|
+
export class GoBinaryString extends String {
|
|
4
|
+
readonly bytes: Uint8Array
|
|
5
|
+
|
|
6
|
+
constructor(bytes: Uint8Array) {
|
|
7
|
+
super(bytesToBinaryString(bytes))
|
|
8
|
+
this.bytes = bytes.slice()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
toString(): string {
|
|
12
|
+
return bytesToBinaryString(this.bytes)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
valueOf(): string {
|
|
16
|
+
return this.toString()
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
[Symbol.toPrimitive](): string {
|
|
20
|
+
return this.toString()
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type GoStringValue = string | GoBinaryString
|
|
25
|
+
type GoStringBytes = GoStringValue | Slice<number> | Uint8Array
|
|
26
|
+
|
|
27
|
+
function isGoStringValue(value: unknown): value is GoStringValue {
|
|
28
|
+
return typeof value === 'string' || value instanceof GoBinaryString
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function goStringBytes(str: GoStringValue): Uint8Array {
|
|
32
|
+
if (str instanceof GoBinaryString) {
|
|
33
|
+
return str.bytes.slice()
|
|
34
|
+
}
|
|
35
|
+
return new TextEncoder().encode(str)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function goStringComparableBytes(value: GoStringBytes): Uint8Array {
|
|
39
|
+
if (isGoStringValue(value)) {
|
|
40
|
+
return goStringBytes(value)
|
|
41
|
+
}
|
|
42
|
+
if (value instanceof Uint8Array) {
|
|
43
|
+
return value
|
|
44
|
+
}
|
|
45
|
+
if (value === null || value === undefined) {
|
|
46
|
+
return new Uint8Array(0)
|
|
47
|
+
}
|
|
48
|
+
return Uint8Array.from(asArray(value))
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function goStringFromBytes(bytes: Uint8Array): string {
|
|
52
|
+
try {
|
|
53
|
+
return new TextDecoder('utf-8', { fatal: true }).decode(bytes)
|
|
54
|
+
} catch {
|
|
55
|
+
return new GoBinaryString(bytes) as unknown as string
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
1
59
|
/**
|
|
2
60
|
* GoSliceObject contains metadata for complex slice views
|
|
3
61
|
*/
|
|
@@ -6,8 +64,13 @@ interface GoSliceObject<T> {
|
|
|
6
64
|
offset: number // Offset into the backing array
|
|
7
65
|
length: number // Length of the slice
|
|
8
66
|
capacity: number // Capacity of the slice
|
|
67
|
+
target?: T[] // Materialized proxy target for JS array operations
|
|
9
68
|
}
|
|
10
69
|
|
|
70
|
+
const addressStride = 0x100000000
|
|
71
|
+
let nextAddressBase = 1
|
|
72
|
+
const addressBases = new WeakMap<object, number>()
|
|
73
|
+
|
|
11
74
|
/**
|
|
12
75
|
* SliceProxy is a proxy object for complex slices
|
|
13
76
|
*/
|
|
@@ -15,6 +78,25 @@ export type SliceProxy<T> = T[] & {
|
|
|
15
78
|
__meta__: GoSliceObject<T>
|
|
16
79
|
}
|
|
17
80
|
|
|
81
|
+
type ByteSlice = Uint8Array & {
|
|
82
|
+
__meta__?: GoSliceObject<number>
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function sliceIndexProperty(prop: string | symbol): number {
|
|
86
|
+
if (typeof prop !== 'string' || prop.length === 0) {
|
|
87
|
+
return -1
|
|
88
|
+
}
|
|
89
|
+
let index = 0
|
|
90
|
+
for (let i = 0; i < prop.length; i++) {
|
|
91
|
+
const digit = prop.charCodeAt(i) - 48
|
|
92
|
+
if (digit < 0 || digit > 9) {
|
|
93
|
+
return -1
|
|
94
|
+
}
|
|
95
|
+
index = index * 10 + digit
|
|
96
|
+
}
|
|
97
|
+
return index
|
|
98
|
+
}
|
|
99
|
+
|
|
18
100
|
/**
|
|
19
101
|
* Slice<T> is a union type that is either a plain array or a proxy
|
|
20
102
|
* null represents the nil state.
|
|
@@ -32,39 +114,41 @@ export type Slice<T> =
|
|
|
32
114
|
* and route it through the backing array.
|
|
33
115
|
*/
|
|
34
116
|
function wrapSliceProxy<T>(proxy: SliceProxy<T>): SliceProxy<T> {
|
|
117
|
+
const meta = proxy.__meta__
|
|
118
|
+
meta.target = proxy
|
|
35
119
|
const handler = {
|
|
36
120
|
get(target: any, prop: string | symbol): any {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (index
|
|
40
|
-
return
|
|
121
|
+
const index = sliceIndexProperty(prop)
|
|
122
|
+
if (index >= 0) {
|
|
123
|
+
if (index < meta.length) {
|
|
124
|
+
return meta.backing[meta.offset + index]
|
|
41
125
|
}
|
|
42
126
|
throw new Error(
|
|
43
|
-
`Slice index out of range: ${index} >= ${
|
|
127
|
+
`Slice index out of range: ${index} >= ${meta.length}`,
|
|
44
128
|
)
|
|
45
129
|
}
|
|
46
130
|
|
|
47
131
|
if (prop === 'length') {
|
|
48
|
-
return
|
|
132
|
+
return meta.length
|
|
49
133
|
}
|
|
50
134
|
|
|
51
135
|
if (prop === '__meta__') {
|
|
52
|
-
return
|
|
136
|
+
return meta
|
|
53
137
|
}
|
|
54
138
|
|
|
55
139
|
return Reflect.get(target, prop)
|
|
56
140
|
},
|
|
57
141
|
|
|
58
142
|
set(target: any, prop: string | symbol, value: any): boolean {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (index
|
|
62
|
-
|
|
143
|
+
const index = sliceIndexProperty(prop)
|
|
144
|
+
if (index >= 0) {
|
|
145
|
+
if (index < meta.length) {
|
|
146
|
+
meta.backing[meta.offset + index] = value
|
|
63
147
|
target[index] = value // Also update the proxy target for consistency
|
|
64
148
|
return true
|
|
65
149
|
}
|
|
66
150
|
throw new Error(
|
|
67
|
-
`Slice index out of range: ${index} >= ${
|
|
151
|
+
`Slice index out of range: ${index} >= ${meta.length}`,
|
|
68
152
|
)
|
|
69
153
|
}
|
|
70
154
|
|
|
@@ -79,6 +163,24 @@ function wrapSliceProxy<T>(proxy: SliceProxy<T>): SliceProxy<T> {
|
|
|
79
163
|
return new Proxy(proxy, handler) as SliceProxy<T>
|
|
80
164
|
}
|
|
81
165
|
|
|
166
|
+
function sliceProxyFromBacking<T>(
|
|
167
|
+
backing: T[],
|
|
168
|
+
offset: number,
|
|
169
|
+
length: number,
|
|
170
|
+
capacity: number,
|
|
171
|
+
target?: T[],
|
|
172
|
+
): SliceProxy<T> {
|
|
173
|
+
const proxyTargetArray = (target ?? new Array<T>(length)) as SliceProxy<T>
|
|
174
|
+
proxyTargetArray.length = length
|
|
175
|
+
if (target === undefined) {
|
|
176
|
+
for (let i = 0; i < length; i++) {
|
|
177
|
+
proxyTargetArray[i] = backing[offset + i]
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
proxyTargetArray.__meta__ = { backing, offset, length, capacity }
|
|
181
|
+
return wrapSliceProxy(proxyTargetArray)
|
|
182
|
+
}
|
|
183
|
+
|
|
82
184
|
// asArray converts a slice to a JavaScript array.
|
|
83
185
|
export function asArray<T>(slice: Slice<T>): T[] {
|
|
84
186
|
if (slice === null || slice === undefined) {
|
|
@@ -104,6 +206,48 @@ export function asArray<T>(slice: Slice<T>): T[] {
|
|
|
104
206
|
return []
|
|
105
207
|
}
|
|
106
208
|
|
|
209
|
+
export function sliceToArray<T>(
|
|
210
|
+
slice: Slice<T> | Uint8Array,
|
|
211
|
+
length: number,
|
|
212
|
+
typeHint?: string,
|
|
213
|
+
): T[] | Uint8Array {
|
|
214
|
+
if (len(slice) < length) {
|
|
215
|
+
throw new Error(
|
|
216
|
+
`runtime error: cannot convert slice with length ${len(slice)} to array with length ${length}`,
|
|
217
|
+
)
|
|
218
|
+
}
|
|
219
|
+
if (typeHint === 'byte') {
|
|
220
|
+
return new Uint8Array(
|
|
221
|
+
asArray(slice as Slice<T>).slice(0, length) as number[],
|
|
222
|
+
)
|
|
223
|
+
}
|
|
224
|
+
return asArray(slice as Slice<T>).slice(0, length)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export function sliceToArrayPointer<T>(
|
|
228
|
+
slice: Slice<T> | Uint8Array,
|
|
229
|
+
length: number,
|
|
230
|
+
typeHint?: string,
|
|
231
|
+
): VarRef<T[] | Uint8Array> {
|
|
232
|
+
if (len(slice) < length) {
|
|
233
|
+
throw new Error(
|
|
234
|
+
`runtime error: cannot convert slice with length ${len(slice)} to array pointer with length ${length}`,
|
|
235
|
+
)
|
|
236
|
+
}
|
|
237
|
+
if (typeHint === 'byte') {
|
|
238
|
+
if (slice instanceof Uint8Array) {
|
|
239
|
+
return varRef(goSlice(slice, 0, length) as unknown as Uint8Array)
|
|
240
|
+
}
|
|
241
|
+
return varRef(
|
|
242
|
+
goSlice(slice as Slice<T>, 0, length) as unknown as Uint8Array,
|
|
243
|
+
)
|
|
244
|
+
}
|
|
245
|
+
if (slice instanceof Uint8Array) {
|
|
246
|
+
return varRef(goSlice(slice, 0, length) as unknown as T[])
|
|
247
|
+
}
|
|
248
|
+
return varRef(goSlice(slice, 0, length) as T[])
|
|
249
|
+
}
|
|
250
|
+
|
|
107
251
|
/**
|
|
108
252
|
* isComplexSlice checks if a slice is a complex slice (has __meta__ property)
|
|
109
253
|
*/
|
|
@@ -117,6 +261,35 @@ function isComplexSlice<T>(slice: Slice<T>): slice is SliceProxy<T> {
|
|
|
117
261
|
)
|
|
118
262
|
}
|
|
119
263
|
|
|
264
|
+
function normalizeSliceIndex(value: number | undefined): number | undefined {
|
|
265
|
+
if (value === undefined) {
|
|
266
|
+
return undefined
|
|
267
|
+
}
|
|
268
|
+
return Number(value)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function byteSliceMeta(slice: Uint8Array): GoSliceObject<number> | undefined {
|
|
272
|
+
return (slice as ByteSlice).__meta__
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function byteSliceView(
|
|
276
|
+
backing: Uint8Array,
|
|
277
|
+
offset: number,
|
|
278
|
+
length: number,
|
|
279
|
+
capacity: number,
|
|
280
|
+
): Uint8Array {
|
|
281
|
+
const view = backing.subarray(offset, offset + length) as ByteSlice
|
|
282
|
+
if (capacity !== length) {
|
|
283
|
+
view.__meta__ = {
|
|
284
|
+
backing: backing as unknown as number[],
|
|
285
|
+
offset,
|
|
286
|
+
length,
|
|
287
|
+
capacity,
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return view
|
|
291
|
+
}
|
|
292
|
+
|
|
120
293
|
/**
|
|
121
294
|
* isSliceProxy checks if a slice is a SliceProxy (has __meta__ property)
|
|
122
295
|
* This is an alias for isComplexSlice for better type hinting
|
|
@@ -135,6 +308,7 @@ export const makeSlice = <T>(
|
|
|
135
308
|
length: number,
|
|
136
309
|
capacity?: number,
|
|
137
310
|
typeHint?: string,
|
|
311
|
+
zeroFactory?: () => T,
|
|
138
312
|
): Slice<T> => {
|
|
139
313
|
if (typeHint === 'byte') {
|
|
140
314
|
const actualCapacity = capacity === undefined ? length : capacity
|
|
@@ -149,24 +323,7 @@ export const makeSlice = <T>(
|
|
|
149
323
|
return new Uint8Array(length) as Slice<T>
|
|
150
324
|
}
|
|
151
325
|
|
|
152
|
-
|
|
153
|
-
const backingUint8 = new Uint8Array(actualCapacity)
|
|
154
|
-
const backingNumbers = Array.from(backingUint8) as T[] // Convert to number[] for backing
|
|
155
|
-
|
|
156
|
-
const proxyTargetArray = new Array<T>(length)
|
|
157
|
-
for (let i = 0; i < length; i++) {
|
|
158
|
-
proxyTargetArray[i] = 0 as T // Initialize with zeros
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const proxy = proxyTargetArray as SliceProxy<T>
|
|
162
|
-
proxy.__meta__ = {
|
|
163
|
-
backing: backingNumbers,
|
|
164
|
-
offset: 0,
|
|
165
|
-
length: length,
|
|
166
|
-
capacity: actualCapacity,
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return wrapSliceProxy(proxy) as Slice<T>
|
|
326
|
+
return byteSliceView(new Uint8Array(actualCapacity), 0, length, actualCapacity) as Slice<T>
|
|
170
327
|
}
|
|
171
328
|
|
|
172
329
|
const actualCapacity = capacity === undefined ? length : capacity
|
|
@@ -176,28 +333,28 @@ export const makeSlice = <T>(
|
|
|
176
333
|
)
|
|
177
334
|
}
|
|
178
335
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
336
|
+
const zeroValue = (): T => {
|
|
337
|
+
if (zeroFactory !== undefined) {
|
|
338
|
+
return zeroFactory()
|
|
339
|
+
}
|
|
340
|
+
switch (typeHint) {
|
|
341
|
+
case 'number':
|
|
342
|
+
return 0 as T
|
|
343
|
+
case 'boolean':
|
|
344
|
+
return false as T
|
|
345
|
+
case 'string':
|
|
346
|
+
return '' as T
|
|
347
|
+
default:
|
|
348
|
+
return null as T // Default for objects, complex types, or unspecified
|
|
349
|
+
}
|
|
192
350
|
}
|
|
193
351
|
|
|
194
352
|
const backingArr = new Array<T>(actualCapacity)
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
|
|
353
|
+
// Go zero-initializes the whole backing array. Elements beyond len become
|
|
354
|
+
// observable when a slice is resliced up to cap.
|
|
355
|
+
for (let i = 0; i < actualCapacity; i++) {
|
|
356
|
+
backingArr[i] = zeroValue()
|
|
198
357
|
}
|
|
199
|
-
// The rest of backingArr (from length to actualCapacity-1) remains uninitialized (undefined),
|
|
200
|
-
// representing available capacity.
|
|
201
358
|
|
|
202
359
|
// OPTIMIZATION: If length equals capacity, return backing array directly
|
|
203
360
|
if (length === actualCapacity) {
|
|
@@ -208,7 +365,7 @@ export const makeSlice = <T>(
|
|
|
208
365
|
// Its elements up to 'length' should reflect the initialized part of the slice.
|
|
209
366
|
const proxyTargetArray = new Array<T>(length)
|
|
210
367
|
for (let i = 0; i < length; i++) {
|
|
211
|
-
proxyTargetArray[i] = backingArr[i]
|
|
368
|
+
proxyTargetArray[i] = backingArr[i]
|
|
212
369
|
}
|
|
213
370
|
|
|
214
371
|
const proxy = proxyTargetArray as SliceProxy<T>
|
|
@@ -222,9 +379,9 @@ export const makeSlice = <T>(
|
|
|
222
379
|
// Create a proper Proxy with the handler for SliceProxy behavior
|
|
223
380
|
const handler = {
|
|
224
381
|
get(target: any, prop: string | symbol): any {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (index
|
|
382
|
+
const index = sliceIndexProperty(prop)
|
|
383
|
+
if (index >= 0) {
|
|
384
|
+
if (index < target.__meta__.length) {
|
|
228
385
|
return target.__meta__.backing[target.__meta__.offset + index]
|
|
229
386
|
}
|
|
230
387
|
throw new Error(
|
|
@@ -244,9 +401,9 @@ export const makeSlice = <T>(
|
|
|
244
401
|
},
|
|
245
402
|
|
|
246
403
|
set(target: any, prop: string | symbol, value: any): boolean {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (index
|
|
404
|
+
const index = sliceIndexProperty(prop)
|
|
405
|
+
if (index >= 0) {
|
|
406
|
+
if (index < target.__meta__.length) {
|
|
250
407
|
target.__meta__.backing[target.__meta__.offset + index] = value
|
|
251
408
|
target[index] = value // Also update the proxy target for consistency
|
|
252
409
|
return true
|
|
@@ -296,11 +453,16 @@ export function goSlice<T>( // T can be number for Uint8Array case
|
|
|
296
453
|
high?: number,
|
|
297
454
|
max?: number,
|
|
298
455
|
): Slice<T> {
|
|
456
|
+
s = collectionValue(s) as Slice<T> | Uint8Array
|
|
457
|
+
low = normalizeSliceIndex(low)
|
|
458
|
+
high = normalizeSliceIndex(high)
|
|
459
|
+
max = normalizeSliceIndex(max)
|
|
460
|
+
|
|
299
461
|
const handler = {
|
|
300
462
|
get(target: any, prop: string | symbol): any {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
if (index
|
|
463
|
+
const index = sliceIndexProperty(prop)
|
|
464
|
+
if (index >= 0) {
|
|
465
|
+
if (index < target.__meta__.length) {
|
|
304
466
|
return target.__meta__.backing[target.__meta__.offset + index]
|
|
305
467
|
}
|
|
306
468
|
throw new Error(
|
|
@@ -335,10 +497,11 @@ export function goSlice<T>( // T can be number for Uint8Array case
|
|
|
335
497
|
},
|
|
336
498
|
|
|
337
499
|
set(target: any, prop: string | symbol, value: any): boolean {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
if (index
|
|
500
|
+
const index = sliceIndexProperty(prop)
|
|
501
|
+
if (index >= 0) {
|
|
502
|
+
if (index < target.__meta__.length) {
|
|
341
503
|
target.__meta__.backing[target.__meta__.offset + index] = value
|
|
504
|
+
target[index] = value
|
|
342
505
|
return true
|
|
343
506
|
}
|
|
344
507
|
if (
|
|
@@ -346,6 +509,7 @@ export function goSlice<T>( // T can be number for Uint8Array case
|
|
|
346
509
|
target.__meta__.length < target.__meta__.capacity
|
|
347
510
|
) {
|
|
348
511
|
target.__meta__.backing[target.__meta__.offset + index] = value
|
|
512
|
+
target[index] = value
|
|
349
513
|
target.__meta__.length++
|
|
350
514
|
return true
|
|
351
515
|
}
|
|
@@ -363,54 +527,51 @@ export function goSlice<T>( // T can be number for Uint8Array case
|
|
|
363
527
|
}
|
|
364
528
|
|
|
365
529
|
if (s instanceof Uint8Array) {
|
|
530
|
+
const meta = byteSliceMeta(s)
|
|
531
|
+
const metaBacking = meta?.backing as unknown
|
|
532
|
+
const backing =
|
|
533
|
+
metaBacking instanceof Uint8Array ? metaBacking : s
|
|
534
|
+
const baseOffset = meta?.offset ?? 0
|
|
535
|
+
const baseCapacity = meta?.capacity ?? s.length
|
|
366
536
|
const actualLow = low ?? 0
|
|
367
537
|
const actualHigh = high ?? s.length
|
|
368
538
|
|
|
369
|
-
if (
|
|
539
|
+
if (
|
|
540
|
+
actualLow < 0 ||
|
|
541
|
+
actualHigh < actualLow ||
|
|
542
|
+
actualLow > baseCapacity ||
|
|
543
|
+
actualHigh > baseCapacity
|
|
544
|
+
) {
|
|
370
545
|
throw new Error(
|
|
371
|
-
`Invalid slice indices: low ${actualLow}, high ${actualHigh} for Uint8Array
|
|
546
|
+
`Invalid slice indices: low ${actualLow}, high ${actualHigh} for Uint8Array with capacity ${baseCapacity}`,
|
|
372
547
|
)
|
|
373
548
|
}
|
|
374
549
|
|
|
375
|
-
const
|
|
550
|
+
const newLength = actualHigh - actualLow
|
|
376
551
|
|
|
377
552
|
if (max !== undefined) {
|
|
378
|
-
if (max < actualHigh || max >
|
|
553
|
+
if (max < actualHigh || max > baseCapacity) {
|
|
379
554
|
// max is relative to the original s.length (capacity)
|
|
380
555
|
throw new Error(
|
|
381
|
-
`Invalid max index: ${max}. Constraints: low ${actualLow} <= high ${actualHigh} <= max <=
|
|
556
|
+
`Invalid max index: ${max}. Constraints: low ${actualLow} <= high ${actualHigh} <= max <= capacity ${baseCapacity}`,
|
|
382
557
|
)
|
|
383
558
|
}
|
|
384
559
|
|
|
385
|
-
const newLength = subArrayView.length // actualHigh - actualLow
|
|
386
560
|
const newCap = max - actualLow // Capacity of the new slice view
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
const proxyTarget = {
|
|
394
|
-
__meta__: {
|
|
395
|
-
backing: backingNumbers, // number[]
|
|
396
|
-
offset: 0, // Offset is 0 because backingNumbers is a direct copy
|
|
397
|
-
length: newLength,
|
|
398
|
-
capacity: newCap,
|
|
399
|
-
},
|
|
400
|
-
}
|
|
401
|
-
// Explicitly cast to Slice<T> after ensuring T is number for this branch.
|
|
402
|
-
return new Proxy(
|
|
403
|
-
proxyTarget,
|
|
404
|
-
handler,
|
|
405
|
-
) as unknown as SliceProxy<number> as Slice<T>
|
|
406
|
-
} else {
|
|
407
|
-
// newCap === newLength, standard Uint8Array is fine.
|
|
408
|
-
return subArrayView as Slice<T> // T is number
|
|
409
|
-
}
|
|
410
|
-
} else {
|
|
411
|
-
// max is not defined, return the Uint8Array subarray view directly.
|
|
412
|
-
return subArrayView as Slice<T> // T is number
|
|
561
|
+
return byteSliceView(
|
|
562
|
+
backing,
|
|
563
|
+
baseOffset + actualLow,
|
|
564
|
+
newLength,
|
|
565
|
+
newCap,
|
|
566
|
+
) as Slice<T>
|
|
413
567
|
}
|
|
568
|
+
|
|
569
|
+
return byteSliceView(
|
|
570
|
+
backing,
|
|
571
|
+
baseOffset + actualLow,
|
|
572
|
+
newLength,
|
|
573
|
+
baseCapacity - actualLow,
|
|
574
|
+
) as Slice<T>
|
|
414
575
|
}
|
|
415
576
|
|
|
416
577
|
// Handle nil slices - in Go, slicing a nil slice with valid bounds returns nil
|
|
@@ -501,7 +662,7 @@ export function goSlice<T>( // T can be number for Uint8Array case
|
|
|
501
662
|
const newOffset = oldOffset + low
|
|
502
663
|
|
|
503
664
|
// OPTIMIZATION: If the result would have offset=0 and length=capacity, return backing directly
|
|
504
|
-
if (newOffset === 0 && newLength === newCap) {
|
|
665
|
+
if (newOffset === 0 && newLength === newCap && backing.length === newLength) {
|
|
505
666
|
return backing as Slice<T>
|
|
506
667
|
}
|
|
507
668
|
|
|
@@ -555,9 +716,9 @@ export const arrayToSlice = <T>(
|
|
|
555
716
|
|
|
556
717
|
const handler = {
|
|
557
718
|
get(target: any, prop: string | symbol): any {
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
if (index
|
|
719
|
+
const index = sliceIndexProperty(prop)
|
|
720
|
+
if (index >= 0) {
|
|
721
|
+
if (index < target.__meta__.length) {
|
|
561
722
|
return target.__meta__.backing[target.__meta__.offset + index]
|
|
562
723
|
}
|
|
563
724
|
throw new Error(
|
|
@@ -592,9 +753,9 @@ export const arrayToSlice = <T>(
|
|
|
592
753
|
},
|
|
593
754
|
|
|
594
755
|
set(target: any, prop: string | symbol, value: any): boolean {
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
if (index
|
|
756
|
+
const index = sliceIndexProperty(prop)
|
|
757
|
+
if (index >= 0) {
|
|
758
|
+
if (index < target.__meta__.length) {
|
|
598
759
|
target.__meta__.backing[target.__meta__.offset + index] = value
|
|
599
760
|
return true
|
|
600
761
|
}
|
|
@@ -639,37 +800,51 @@ export const arrayToSlice = <T>(
|
|
|
639
800
|
*/
|
|
640
801
|
export const len = <T = unknown, V = unknown>(
|
|
641
802
|
obj:
|
|
642
|
-
|
|
|
803
|
+
| GoStringValue
|
|
643
804
|
| Array<T>
|
|
644
805
|
| Slice<T>
|
|
645
806
|
| Map<T, V>
|
|
646
807
|
| Set<T>
|
|
647
808
|
| Uint8Array
|
|
809
|
+
| { len(): number }
|
|
648
810
|
| null
|
|
649
811
|
| undefined,
|
|
650
812
|
): number => {
|
|
813
|
+
obj = collectionValue(obj) as typeof obj
|
|
651
814
|
if (obj === null || obj === undefined) {
|
|
652
815
|
return 0
|
|
653
816
|
}
|
|
654
817
|
|
|
655
818
|
if (typeof obj === 'string') {
|
|
656
|
-
return stringLen(obj)
|
|
819
|
+
return stringLen(obj)
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
if (obj instanceof Uint8Array) {
|
|
823
|
+
return obj.length
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
if (Array.isArray(obj)) {
|
|
827
|
+
const meta = (obj as unknown as SliceProxy<T>).__meta__
|
|
828
|
+
if (meta !== undefined) {
|
|
829
|
+
return meta.length
|
|
830
|
+
}
|
|
831
|
+
return obj.length
|
|
657
832
|
}
|
|
658
833
|
|
|
659
834
|
if (obj instanceof Map || obj instanceof Set) {
|
|
660
835
|
return obj.size
|
|
661
836
|
}
|
|
662
837
|
|
|
663
|
-
if (obj instanceof
|
|
664
|
-
return obj
|
|
838
|
+
if (obj instanceof GoBinaryString) {
|
|
839
|
+
return stringLen(obj)
|
|
665
840
|
}
|
|
666
841
|
|
|
667
|
-
if (isComplexSlice(obj)) {
|
|
668
|
-
return obj.__meta__.length
|
|
842
|
+
if (isComplexSlice(obj as any)) {
|
|
843
|
+
return (obj as unknown as SliceProxy<T>).__meta__.length
|
|
669
844
|
}
|
|
670
845
|
|
|
671
|
-
if (
|
|
672
|
-
return obj.
|
|
846
|
+
if (typeof (obj as any).len === 'function') {
|
|
847
|
+
return (obj as { len(): number }).len()
|
|
673
848
|
}
|
|
674
849
|
|
|
675
850
|
throw new Error('cannot determine len of this type')
|
|
@@ -680,23 +855,30 @@ export const len = <T = unknown, V = unknown>(
|
|
|
680
855
|
* @param obj The slice.
|
|
681
856
|
* @returns The capacity of the slice.
|
|
682
857
|
*/
|
|
683
|
-
export const cap = <T>(
|
|
858
|
+
export const cap = <T>(
|
|
859
|
+
obj: Slice<T> | Uint8Array | { cap(): number } | null | undefined,
|
|
860
|
+
): number => {
|
|
861
|
+
obj = collectionValue(obj) as typeof obj
|
|
684
862
|
if (obj === null || obj === undefined) {
|
|
685
863
|
return 0
|
|
686
864
|
}
|
|
687
865
|
|
|
688
|
-
if (obj
|
|
689
|
-
return obj
|
|
866
|
+
if (isComplexSlice(obj as any)) {
|
|
867
|
+
return (obj as SliceProxy<T>).__meta__.capacity
|
|
690
868
|
}
|
|
691
869
|
|
|
692
|
-
if (
|
|
693
|
-
return obj.
|
|
870
|
+
if (obj instanceof Uint8Array) {
|
|
871
|
+
return obj.length // Uint8Array capacity is its length
|
|
694
872
|
}
|
|
695
873
|
|
|
696
874
|
if (Array.isArray(obj)) {
|
|
697
875
|
return obj.length
|
|
698
876
|
}
|
|
699
877
|
|
|
878
|
+
if (typeof (obj as any).cap === 'function') {
|
|
879
|
+
return (obj as { cap(): number }).cap()
|
|
880
|
+
}
|
|
881
|
+
|
|
700
882
|
return 0
|
|
701
883
|
}
|
|
702
884
|
|
|
@@ -711,6 +893,7 @@ export const cap = <T>(obj: Slice<T> | Uint8Array): number => {
|
|
|
711
893
|
export function append(slice: Uint8Array, ...elements: any[]): Uint8Array
|
|
712
894
|
// Overload for null slice with number elements - returns number slice (Bytes compatible)
|
|
713
895
|
export function append(slice: null, ...elements: number[]): Slice<number>
|
|
896
|
+
export function append<T>(slice: null, ...elements: T[]): Slice<T>
|
|
714
897
|
export function append<T>(slice: Slice<T>, ...elements: any[]): Slice<T>
|
|
715
898
|
export function append<T>(
|
|
716
899
|
slice: Slice<T> | Uint8Array | null,
|
|
@@ -719,59 +902,11 @@ export function append<T>(
|
|
|
719
902
|
// 1. Flatten all elements from the varargs `...elements` into `varargsElements`.
|
|
720
903
|
// Determine if the result should be a Uint8Array.
|
|
721
904
|
const inputIsUint8Array = slice instanceof Uint8Array
|
|
722
|
-
const
|
|
723
|
-
const produceUint8Array =
|
|
724
|
-
inputIsUint8Array ||
|
|
725
|
-
appendingUint8Array ||
|
|
726
|
-
(slice === null && appendingUint8Array)
|
|
905
|
+
const produceUint8Array = inputIsUint8Array
|
|
727
906
|
|
|
728
907
|
// If producing Uint8Array, all elements must be numbers and potentially flattened from other Uint8Arrays/number slices.
|
|
729
908
|
if (produceUint8Array) {
|
|
730
|
-
|
|
731
|
-
// Add bytes from the original slice if it exists and is numeric.
|
|
732
|
-
if (inputIsUint8Array) {
|
|
733
|
-
combinedBytes.push(...Array.from(slice as Uint8Array))
|
|
734
|
-
} else if (slice !== null && slice !== undefined) {
|
|
735
|
-
// Original was Slice<number> or number[]
|
|
736
|
-
const sliceLen = len(slice)
|
|
737
|
-
for (let i = 0; i < sliceLen; i++) {
|
|
738
|
-
const val = (slice as any)[i]
|
|
739
|
-
if (typeof val !== 'number') {
|
|
740
|
-
throw new Error(
|
|
741
|
-
'Cannot produce Uint8Array: original slice contains non-number elements.',
|
|
742
|
-
)
|
|
743
|
-
}
|
|
744
|
-
combinedBytes.push(val)
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
// Add bytes from the varargs elements.
|
|
748
|
-
// For Uint8Array, elements are always flattened if they are slices/Uint8Arrays.
|
|
749
|
-
for (const item of elements) {
|
|
750
|
-
if (item instanceof Uint8Array) {
|
|
751
|
-
combinedBytes.push(...Array.from(item))
|
|
752
|
-
} else if (isComplexSlice(item) || Array.isArray(item)) {
|
|
753
|
-
const itemLen = len(item as Slice<any>)
|
|
754
|
-
for (let i = 0; i < itemLen; i++) {
|
|
755
|
-
const val = (item as any)[i]
|
|
756
|
-
if (typeof val !== 'number') {
|
|
757
|
-
throw new Error(
|
|
758
|
-
'Cannot produce Uint8Array: appended elements contain non-numbers.',
|
|
759
|
-
)
|
|
760
|
-
}
|
|
761
|
-
combinedBytes.push(val)
|
|
762
|
-
}
|
|
763
|
-
} else {
|
|
764
|
-
if (typeof item !== 'number') {
|
|
765
|
-
throw new Error(
|
|
766
|
-
'Cannot produce Uint8Array: appended elements contain non-numbers.',
|
|
767
|
-
)
|
|
768
|
-
}
|
|
769
|
-
combinedBytes.push(item)
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
const newArr = new Uint8Array(combinedBytes.length)
|
|
773
|
-
newArr.set(combinedBytes)
|
|
774
|
-
return newArr as any
|
|
909
|
+
return appendByteSlice(slice as Uint8Array, elements) as any
|
|
775
910
|
}
|
|
776
911
|
|
|
777
912
|
// Handle generic Slice<T> (non-Uint8Array result).
|
|
@@ -783,28 +918,30 @@ export function append<T>(
|
|
|
783
918
|
return slice as any
|
|
784
919
|
}
|
|
785
920
|
|
|
786
|
-
let originalElements: T[]
|
|
921
|
+
let originalElements: T[] | undefined
|
|
922
|
+
let oldLength = 0
|
|
787
923
|
let oldCapacity: number
|
|
788
924
|
let isOriginalComplex = false
|
|
789
925
|
let originalBacking: T[] | undefined = undefined
|
|
926
|
+
let originalTarget: T[] | undefined = undefined
|
|
790
927
|
let originalOffset = 0
|
|
791
928
|
|
|
792
929
|
if (slice === null || slice === undefined) {
|
|
793
930
|
oldCapacity = 0
|
|
794
931
|
} else if (isComplexSlice(slice)) {
|
|
795
932
|
const meta = slice.__meta__
|
|
796
|
-
|
|
797
|
-
originalElements.push(meta.backing[meta.offset + i])
|
|
933
|
+
oldLength = meta.length
|
|
798
934
|
oldCapacity = meta.capacity
|
|
799
935
|
isOriginalComplex = true
|
|
800
936
|
originalBacking = meta.backing
|
|
937
|
+
originalTarget = meta.target
|
|
801
938
|
originalOffset = meta.offset
|
|
802
939
|
} else {
|
|
803
940
|
// Simple T[] array
|
|
804
941
|
originalElements = (slice as T[]).slice()
|
|
805
|
-
|
|
942
|
+
oldLength = originalElements.length
|
|
943
|
+
oldCapacity = oldLength
|
|
806
944
|
}
|
|
807
|
-
const oldLength = originalElements.length
|
|
808
945
|
const newLength = oldLength + numAdded
|
|
809
946
|
|
|
810
947
|
// Case 1: Modify in-place if original was SliceProxy and has enough capacity.
|
|
@@ -812,16 +949,19 @@ export function append<T>(
|
|
|
812
949
|
for (let i = 0; i < numAdded; i++) {
|
|
813
950
|
originalBacking[originalOffset + oldLength + i] = elements[i] as T
|
|
814
951
|
}
|
|
815
|
-
const
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
offset: originalOffset,
|
|
821
|
-
length: newLength,
|
|
822
|
-
capacity: oldCapacity,
|
|
952
|
+
const target = originalTarget
|
|
953
|
+
if (target !== undefined) {
|
|
954
|
+
for (let i = 0; i < numAdded; i++) {
|
|
955
|
+
target[oldLength + i] = elements[i] as T
|
|
956
|
+
}
|
|
823
957
|
}
|
|
824
|
-
return
|
|
958
|
+
return sliceProxyFromBacking(
|
|
959
|
+
originalBacking,
|
|
960
|
+
originalOffset,
|
|
961
|
+
newLength,
|
|
962
|
+
oldCapacity,
|
|
963
|
+
target,
|
|
964
|
+
) as any
|
|
825
965
|
}
|
|
826
966
|
|
|
827
967
|
// Case 2: Reallocation is needed.
|
|
@@ -838,22 +978,87 @@ export function append<T>(
|
|
|
838
978
|
}
|
|
839
979
|
|
|
840
980
|
const newBacking = new Array<T>(newCapacity)
|
|
841
|
-
|
|
842
|
-
|
|
981
|
+
if (isOriginalComplex && originalBacking) {
|
|
982
|
+
for (let i = 0; i < oldLength; i++) {
|
|
983
|
+
newBacking[i] = originalBacking[originalOffset + i]
|
|
984
|
+
}
|
|
985
|
+
} else if (originalElements !== undefined) {
|
|
986
|
+
for (let i = 0; i < oldLength; i++) {
|
|
987
|
+
newBacking[i] = originalElements[i]
|
|
988
|
+
}
|
|
843
989
|
}
|
|
844
990
|
for (let i = 0; i < numAdded; i++) {
|
|
845
991
|
newBacking[oldLength + i] = elements[i] as T
|
|
846
992
|
}
|
|
847
993
|
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
994
|
+
return sliceProxyFromBacking(newBacking, 0, newLength, newCapacity) as any
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
function appendByteSlice(slice: Uint8Array, elements: any[]): Uint8Array {
|
|
998
|
+
const meta = byteSliceMeta(slice)
|
|
999
|
+
const metaBacking = meta?.backing as unknown
|
|
1000
|
+
const backing =
|
|
1001
|
+
metaBacking instanceof Uint8Array ? metaBacking : slice
|
|
1002
|
+
const offset = meta?.offset ?? 0
|
|
1003
|
+
const oldLength = slice.length
|
|
1004
|
+
const oldCapacity = meta?.capacity ?? oldLength
|
|
1005
|
+
let added = 0
|
|
1006
|
+
for (const item of elements) {
|
|
1007
|
+
added += byteElementLength(item)
|
|
1008
|
+
}
|
|
1009
|
+
const newLength = oldLength + added
|
|
1010
|
+
if (newLength <= oldCapacity) {
|
|
1011
|
+
const view = byteSliceView(backing, offset, newLength, oldCapacity)
|
|
1012
|
+
writeByteElements(view, oldLength, elements)
|
|
1013
|
+
return view
|
|
1014
|
+
}
|
|
1015
|
+
const next = new Uint8Array(newLength)
|
|
1016
|
+
next.set(slice)
|
|
1017
|
+
writeByteElements(next, oldLength, elements)
|
|
1018
|
+
return next
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
function byteElementLength(item: any): number {
|
|
1022
|
+
if (item instanceof Uint8Array) {
|
|
1023
|
+
return item.length
|
|
1024
|
+
}
|
|
1025
|
+
if (isComplexSlice(item) || Array.isArray(item)) {
|
|
1026
|
+
return len(item as Slice<any>)
|
|
1027
|
+
}
|
|
1028
|
+
if (typeof item !== 'number') {
|
|
1029
|
+
throw new Error('Cannot produce Uint8Array: appended elements contain non-numbers.')
|
|
1030
|
+
}
|
|
1031
|
+
return 1
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
function writeByteElements(dst: Uint8Array, offset: number, elements: any[]): void {
|
|
1035
|
+
let cursor = offset
|
|
1036
|
+
for (const item of elements) {
|
|
1037
|
+
if (item instanceof Uint8Array) {
|
|
1038
|
+
dst.set(item, cursor)
|
|
1039
|
+
cursor += item.length
|
|
1040
|
+
continue
|
|
1041
|
+
}
|
|
1042
|
+
if (isComplexSlice(item) || Array.isArray(item)) {
|
|
1043
|
+
const itemLen = len(item as Slice<any>)
|
|
1044
|
+
for (let i = 0; i < itemLen; i++) {
|
|
1045
|
+
const value = (item as any)[i]
|
|
1046
|
+
if (typeof value !== 'number') {
|
|
1047
|
+
throw new Error(
|
|
1048
|
+
'Cannot produce Uint8Array: appended elements contain non-numbers.',
|
|
1049
|
+
)
|
|
1050
|
+
}
|
|
1051
|
+
dst[cursor] = value
|
|
1052
|
+
cursor++
|
|
1053
|
+
}
|
|
1054
|
+
continue
|
|
1055
|
+
}
|
|
1056
|
+
if (typeof item !== 'number') {
|
|
1057
|
+
throw new Error('Cannot produce Uint8Array: appended elements contain non-numbers.')
|
|
1058
|
+
}
|
|
1059
|
+
dst[cursor] = item
|
|
1060
|
+
cursor++
|
|
855
1061
|
}
|
|
856
|
-
return wrapSliceProxy(resultProxy) as any
|
|
857
1062
|
}
|
|
858
1063
|
|
|
859
1064
|
/**
|
|
@@ -868,14 +1073,14 @@ export function copy<T>(dst: Slice<T>, src: Slice<T>): number
|
|
|
868
1073
|
export function copy<T>(dst: Slice<T>, src: string): number
|
|
869
1074
|
export function copy<T>(
|
|
870
1075
|
dst: Slice<T> | Uint8Array,
|
|
871
|
-
src: Slice<T> | Uint8Array |
|
|
1076
|
+
src: Slice<T> | Uint8Array | GoStringValue,
|
|
872
1077
|
): number {
|
|
873
1078
|
if (dst === null) {
|
|
874
1079
|
return 0
|
|
875
1080
|
}
|
|
876
1081
|
|
|
877
1082
|
// Handle string source first
|
|
878
|
-
if (
|
|
1083
|
+
if (isGoStringValue(src)) {
|
|
879
1084
|
return copyFromString(dst, src)
|
|
880
1085
|
}
|
|
881
1086
|
|
|
@@ -916,9 +1121,13 @@ export function copy<T>(
|
|
|
916
1121
|
/**
|
|
917
1122
|
* Helper: Copy from string to any destination type
|
|
918
1123
|
*/
|
|
919
|
-
function copyFromString<T>(
|
|
1124
|
+
function copyFromString<T>(
|
|
1125
|
+
dst: Slice<T> | Uint8Array,
|
|
1126
|
+
src: GoStringValue,
|
|
1127
|
+
): number {
|
|
920
1128
|
const dstLen = dst instanceof Uint8Array ? dst.length : len(dst)
|
|
921
|
-
const
|
|
1129
|
+
const bytes = goStringBytes(src)
|
|
1130
|
+
const count = Math.min(dstLen, bytes.length)
|
|
922
1131
|
|
|
923
1132
|
if (count === 0) {
|
|
924
1133
|
return 0
|
|
@@ -926,18 +1135,18 @@ function copyFromString<T>(dst: Slice<T> | Uint8Array, src: string): number {
|
|
|
926
1135
|
|
|
927
1136
|
if (dst instanceof Uint8Array) {
|
|
928
1137
|
for (let i = 0; i < count; i++) {
|
|
929
|
-
dst[i] =
|
|
1138
|
+
dst[i] = bytes[i]
|
|
930
1139
|
}
|
|
931
1140
|
} else if (isComplexSlice(dst)) {
|
|
932
1141
|
const dstMeta = dst.__meta__
|
|
933
1142
|
for (let i = 0; i < count; i++) {
|
|
934
|
-
const byteVal =
|
|
1143
|
+
const byteVal = bytes[i]
|
|
935
1144
|
dstMeta.backing[dstMeta.offset + i] = byteVal as unknown as T
|
|
936
1145
|
;(dst as any)[i] = byteVal
|
|
937
1146
|
}
|
|
938
1147
|
} else if (Array.isArray(dst)) {
|
|
939
1148
|
for (let i = 0; i < count; i++) {
|
|
940
|
-
dst[i] =
|
|
1149
|
+
dst[i] = bytes[i] as unknown as T
|
|
941
1150
|
}
|
|
942
1151
|
}
|
|
943
1152
|
|
|
@@ -952,15 +1161,9 @@ function copyToUint8Array(
|
|
|
952
1161
|
src: Slice<number>,
|
|
953
1162
|
count: number,
|
|
954
1163
|
): number {
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
dst[i] = srcMeta.backing[srcMeta.offset + i]
|
|
959
|
-
}
|
|
960
|
-
} else if (Array.isArray(src)) {
|
|
961
|
-
for (let i = 0; i < count; i++) {
|
|
962
|
-
dst[i] = src[i]
|
|
963
|
-
}
|
|
1164
|
+
const values = copySliceValues(src, count)
|
|
1165
|
+
for (let i = 0; i < count; i++) {
|
|
1166
|
+
dst[i] = values[i]
|
|
964
1167
|
}
|
|
965
1168
|
return count
|
|
966
1169
|
}
|
|
@@ -973,15 +1176,16 @@ function copyFromUint8Array<T>(
|
|
|
973
1176
|
src: Uint8Array,
|
|
974
1177
|
count: number,
|
|
975
1178
|
): number {
|
|
1179
|
+
const values = Array.from(src.subarray(0, count))
|
|
976
1180
|
if (isComplexSlice(dst)) {
|
|
977
1181
|
const dstMeta = dst.__meta__
|
|
978
1182
|
for (let i = 0; i < count; i++) {
|
|
979
|
-
dstMeta.backing[dstMeta.offset + i] =
|
|
980
|
-
;(dst as any)[i] =
|
|
1183
|
+
dstMeta.backing[dstMeta.offset + i] = values[i] as unknown as T
|
|
1184
|
+
;(dst as any)[i] = values[i]
|
|
981
1185
|
}
|
|
982
1186
|
} else if (Array.isArray(dst)) {
|
|
983
1187
|
for (let i = 0; i < count; i++) {
|
|
984
|
-
dst[i] =
|
|
1188
|
+
dst[i] = values[i] as unknown as T
|
|
985
1189
|
}
|
|
986
1190
|
}
|
|
987
1191
|
return count
|
|
@@ -995,37 +1199,36 @@ function copyBetweenSlices<T>(
|
|
|
995
1199
|
src: Slice<T>,
|
|
996
1200
|
count: number,
|
|
997
1201
|
): number {
|
|
1202
|
+
const values = copySliceValues(src, count)
|
|
998
1203
|
if (isComplexSlice(dst)) {
|
|
999
1204
|
const dstMeta = dst.__meta__
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
for (let i = 0; i < count; i++) {
|
|
1004
|
-
dstMeta.backing[dstMeta.offset + i] =
|
|
1005
|
-
srcMeta.backing[srcMeta.offset + i]
|
|
1006
|
-
;(dst as any)[i] = srcMeta.backing[srcMeta.offset + i]
|
|
1007
|
-
}
|
|
1008
|
-
} else if (Array.isArray(src)) {
|
|
1009
|
-
for (let i = 0; i < count; i++) {
|
|
1010
|
-
dstMeta.backing[dstMeta.offset + i] = src[i]
|
|
1011
|
-
;(dst as any)[i] = src[i]
|
|
1012
|
-
}
|
|
1205
|
+
for (let i = 0; i < count; i++) {
|
|
1206
|
+
dstMeta.backing[dstMeta.offset + i] = values[i]
|
|
1207
|
+
;(dst as any)[i] = values[i]
|
|
1013
1208
|
}
|
|
1014
1209
|
} else if (Array.isArray(dst)) {
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
for (let i = 0; i < count; i++) {
|
|
1018
|
-
dst[i] = srcMeta.backing[srcMeta.offset + i]
|
|
1019
|
-
}
|
|
1020
|
-
} else if (Array.isArray(src)) {
|
|
1021
|
-
for (let i = 0; i < count; i++) {
|
|
1022
|
-
dst[i] = src[i]
|
|
1023
|
-
}
|
|
1210
|
+
for (let i = 0; i < count; i++) {
|
|
1211
|
+
dst[i] = values[i]
|
|
1024
1212
|
}
|
|
1025
1213
|
}
|
|
1026
1214
|
return count
|
|
1027
1215
|
}
|
|
1028
1216
|
|
|
1217
|
+
function copySliceValues<T>(src: Slice<T>, count: number): T[] {
|
|
1218
|
+
const values = new Array<T>(count)
|
|
1219
|
+
if (isComplexSlice(src)) {
|
|
1220
|
+
const srcMeta = src.__meta__
|
|
1221
|
+
for (let i = 0; i < count; i++) {
|
|
1222
|
+
values[i] = srcMeta.backing[srcMeta.offset + i]
|
|
1223
|
+
}
|
|
1224
|
+
} else if (Array.isArray(src)) {
|
|
1225
|
+
for (let i = 0; i < count; i++) {
|
|
1226
|
+
values[i] = src[i]
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
return values
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1029
1232
|
/**
|
|
1030
1233
|
* Accesses an element at a specific index for various Go-like types (string, slice, array).
|
|
1031
1234
|
* Mimics Go's indexing behavior: `myCollection[index]`
|
|
@@ -1038,14 +1241,14 @@ function copyBetweenSlices<T>(
|
|
|
1038
1241
|
* @throws Error if index is out of bounds or type is unsupported.
|
|
1039
1242
|
*/
|
|
1040
1243
|
export function index<T>(
|
|
1041
|
-
collection:
|
|
1244
|
+
collection: GoStringValue | Slice<T> | T[],
|
|
1042
1245
|
index: number,
|
|
1043
1246
|
): T | number {
|
|
1044
1247
|
if (collection === null || collection === undefined) {
|
|
1045
1248
|
throw new Error('runtime error: index on nil or undefined collection')
|
|
1046
1249
|
}
|
|
1047
1250
|
|
|
1048
|
-
if (
|
|
1251
|
+
if (isGoStringValue(collection)) {
|
|
1049
1252
|
return indexString(collection, index) // Use the existing indexString for byte access
|
|
1050
1253
|
} else if (collection instanceof Uint8Array) {
|
|
1051
1254
|
if (index < 0 || index >= collection.length) {
|
|
@@ -1072,6 +1275,151 @@ export function index<T>(
|
|
|
1072
1275
|
throw new Error('runtime error: index on unsupported type')
|
|
1073
1276
|
}
|
|
1074
1277
|
|
|
1278
|
+
/**
|
|
1279
|
+
* indexRef returns an addressable reference to a slice or array element.
|
|
1280
|
+
*/
|
|
1281
|
+
export function indexRef<T>(
|
|
1282
|
+
collection: Slice<T> | T[] | Uint8Array,
|
|
1283
|
+
index: number,
|
|
1284
|
+
): VarRef<T> {
|
|
1285
|
+
if (collection === null || collection === undefined) {
|
|
1286
|
+
throw new Error('runtime error: index on nil or undefined collection')
|
|
1287
|
+
}
|
|
1288
|
+
if (collection instanceof Uint8Array) {
|
|
1289
|
+
if (index < 0 || index >= collection.length) {
|
|
1290
|
+
throw new Error(
|
|
1291
|
+
`runtime error: index out of range [${index}] with length ${collection.length}`,
|
|
1292
|
+
)
|
|
1293
|
+
}
|
|
1294
|
+
return {
|
|
1295
|
+
get value() {
|
|
1296
|
+
return collection[index] as T
|
|
1297
|
+
},
|
|
1298
|
+
set value(value: T) {
|
|
1299
|
+
collection[index] = value as number
|
|
1300
|
+
},
|
|
1301
|
+
__isVarRef: true,
|
|
1302
|
+
__goAddress: () => indexAddress(collection, index),
|
|
1303
|
+
__goCollection: collection,
|
|
1304
|
+
__goIndex: index,
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
if (isComplexSlice(collection)) {
|
|
1308
|
+
if (index < 0 || index >= collection.__meta__.length) {
|
|
1309
|
+
throw new Error(
|
|
1310
|
+
`runtime error: index out of range [${index}] with length ${collection.__meta__.length}`,
|
|
1311
|
+
)
|
|
1312
|
+
}
|
|
1313
|
+
const backingIndex = collection.__meta__.offset + index
|
|
1314
|
+
return {
|
|
1315
|
+
get value() {
|
|
1316
|
+
return collection.__meta__.backing[backingIndex]
|
|
1317
|
+
},
|
|
1318
|
+
set value(value: T) {
|
|
1319
|
+
collection[index] = value
|
|
1320
|
+
},
|
|
1321
|
+
__isVarRef: true,
|
|
1322
|
+
__goAddress: () => indexAddress(collection, index),
|
|
1323
|
+
__goCollection: collection,
|
|
1324
|
+
__goIndex: index,
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
if (Array.isArray(collection)) {
|
|
1328
|
+
if (index < 0 || index >= collection.length) {
|
|
1329
|
+
throw new Error(
|
|
1330
|
+
`runtime error: index out of range [${index}] with length ${collection.length}`,
|
|
1331
|
+
)
|
|
1332
|
+
}
|
|
1333
|
+
return {
|
|
1334
|
+
get value() {
|
|
1335
|
+
return collection[index]
|
|
1336
|
+
},
|
|
1337
|
+
set value(value: T) {
|
|
1338
|
+
collection[index] = value
|
|
1339
|
+
},
|
|
1340
|
+
__isVarRef: true,
|
|
1341
|
+
__goAddress: () => indexAddress(collection, index),
|
|
1342
|
+
__goCollection: collection,
|
|
1343
|
+
__goIndex: index,
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
throw new Error('runtime error: index on unsupported type')
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
/**
|
|
1350
|
+
* arrayPointerFromIndexRef turns &slice[i] into a pointer to an N-element array
|
|
1351
|
+
* view. This models unsafe conversions such as (*[64]byte)(unsafe.Pointer(&b[0]))
|
|
1352
|
+
* for packages that immediately slice or index the resulting array pointer.
|
|
1353
|
+
*/
|
|
1354
|
+
export function arrayPointerFromIndexRef<T>(
|
|
1355
|
+
ref: VarRef<T>,
|
|
1356
|
+
length: number,
|
|
1357
|
+
): VarRef<Slice<T> | T[] | Uint8Array> {
|
|
1358
|
+
const collection = ref.__goCollection as
|
|
1359
|
+
| Slice<T>
|
|
1360
|
+
| T[]
|
|
1361
|
+
| Uint8Array
|
|
1362
|
+
| undefined
|
|
1363
|
+
if (collection === undefined) {
|
|
1364
|
+
throw new Error(
|
|
1365
|
+
'unsafe array pointer requires an indexed collection reference',
|
|
1366
|
+
)
|
|
1367
|
+
}
|
|
1368
|
+
const index = ref.__goIndex ?? 0
|
|
1369
|
+
return varRef(
|
|
1370
|
+
goSlice(collection as any, index, index + length) as
|
|
1371
|
+
| Slice<T>
|
|
1372
|
+
| T[]
|
|
1373
|
+
| Uint8Array,
|
|
1374
|
+
)
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
/**
|
|
1378
|
+
* indexAddress returns a stable synthetic address for an addressable slice or
|
|
1379
|
+
* array element.
|
|
1380
|
+
*/
|
|
1381
|
+
export function indexAddress<T>(
|
|
1382
|
+
collection: Slice<T> | T[] | Uint8Array,
|
|
1383
|
+
index: number,
|
|
1384
|
+
): number {
|
|
1385
|
+
if (collection === null || collection === undefined) {
|
|
1386
|
+
throw new Error('runtime error: index on nil or undefined collection')
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
let backing: object
|
|
1390
|
+
let backingIndex: number
|
|
1391
|
+
let length: number
|
|
1392
|
+
if (collection instanceof Uint8Array) {
|
|
1393
|
+
backing = collection.buffer
|
|
1394
|
+
backingIndex = collection.byteOffset + index
|
|
1395
|
+
length = collection.length
|
|
1396
|
+
} else if (isComplexSlice(collection)) {
|
|
1397
|
+
backing = collection.__meta__.backing
|
|
1398
|
+
backingIndex = collection.__meta__.offset + index
|
|
1399
|
+
length = collection.__meta__.length
|
|
1400
|
+
} else if (Array.isArray(collection)) {
|
|
1401
|
+
backing = collection
|
|
1402
|
+
backingIndex = index
|
|
1403
|
+
length = collection.length
|
|
1404
|
+
} else {
|
|
1405
|
+
throw new Error('runtime error: index on unsupported type')
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
if (index < 0 || index >= length) {
|
|
1409
|
+
throw new Error(
|
|
1410
|
+
`runtime error: index out of range [${index}] with length ${length}`,
|
|
1411
|
+
)
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
let base = addressBases.get(backing)
|
|
1415
|
+
if (base === undefined) {
|
|
1416
|
+
base = nextAddressBase * addressStride
|
|
1417
|
+
nextAddressBase++
|
|
1418
|
+
addressBases.set(backing, base)
|
|
1419
|
+
}
|
|
1420
|
+
return base + backingIndex
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1075
1423
|
/**
|
|
1076
1424
|
* Converts a string to an array of Unicode code points (runes).
|
|
1077
1425
|
* @param str The input string.
|
|
@@ -1081,6 +1429,22 @@ export const stringToRunes = (str: string): number[] => {
|
|
|
1081
1429
|
return Array.from(str).map((c) => c.codePointAt(0) || 0)
|
|
1082
1430
|
}
|
|
1083
1431
|
|
|
1432
|
+
/**
|
|
1433
|
+
* Returns Go range pairs for a string: UTF-8 byte offset and rune value.
|
|
1434
|
+
* @param str The input string.
|
|
1435
|
+
* @returns Index/rune pairs matching Go's `for i, r := range str`.
|
|
1436
|
+
*/
|
|
1437
|
+
export const rangeString = (str: string): Array<[number, number]> => {
|
|
1438
|
+
const encoder = new TextEncoder()
|
|
1439
|
+
const pairs: Array<[number, number]> = []
|
|
1440
|
+
let offset = 0
|
|
1441
|
+
for (const char of str) {
|
|
1442
|
+
pairs.push([offset, char.codePointAt(0) || 0])
|
|
1443
|
+
offset += encoder.encode(char).length
|
|
1444
|
+
}
|
|
1445
|
+
return pairs
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1084
1448
|
/**
|
|
1085
1449
|
* Converts a single-character string to its Unicode code point (rune).
|
|
1086
1450
|
* Used for readable rune constants like $.stringToRune('/') instead of 47.
|
|
@@ -1122,10 +1486,10 @@ export const byte = (n: number): number => {
|
|
|
1122
1486
|
* @throws Error if index is out of bounds.
|
|
1123
1487
|
*/
|
|
1124
1488
|
export const indexString = (
|
|
1125
|
-
str:
|
|
1489
|
+
str: GoStringValue | import('./builtin.js').Bytes,
|
|
1126
1490
|
index: number,
|
|
1127
1491
|
): number => {
|
|
1128
|
-
if (
|
|
1492
|
+
if (!isGoStringValue(str)) {
|
|
1129
1493
|
// Bytes - access directly
|
|
1130
1494
|
if (str instanceof Uint8Array) {
|
|
1131
1495
|
if (index < 0 || index >= str.length) {
|
|
@@ -1148,7 +1512,7 @@ export const indexString = (
|
|
|
1148
1512
|
}
|
|
1149
1513
|
return str[index]
|
|
1150
1514
|
}
|
|
1151
|
-
const bytes =
|
|
1515
|
+
const bytes = goStringBytes(str)
|
|
1152
1516
|
if (index < 0 || index >= bytes.length) {
|
|
1153
1517
|
throw new Error(
|
|
1154
1518
|
`runtime error: index out of range [${index}] with length ${bytes.length}`,
|
|
@@ -1163,8 +1527,8 @@ export const indexString = (
|
|
|
1163
1527
|
* @param str The string.
|
|
1164
1528
|
* @returns The number of bytes in the UTF-8 representation of the string.
|
|
1165
1529
|
*/
|
|
1166
|
-
export const stringLen = (str:
|
|
1167
|
-
return
|
|
1530
|
+
export const stringLen = (str: GoStringValue): number => {
|
|
1531
|
+
return goStringBytes(str).length
|
|
1168
1532
|
}
|
|
1169
1533
|
|
|
1170
1534
|
/**
|
|
@@ -1177,11 +1541,11 @@ export const stringLen = (str: string): number => {
|
|
|
1177
1541
|
* @throws Error if the slice would create invalid UTF-8.
|
|
1178
1542
|
*/
|
|
1179
1543
|
export const sliceString = (
|
|
1180
|
-
str:
|
|
1544
|
+
str: GoStringValue,
|
|
1181
1545
|
low?: number,
|
|
1182
1546
|
high?: number,
|
|
1183
1547
|
): string => {
|
|
1184
|
-
const bytes =
|
|
1548
|
+
const bytes = goStringBytes(str)
|
|
1185
1549
|
const actualLow = low === undefined ? 0 : low
|
|
1186
1550
|
const actualHigh = high === undefined ? bytes.length : high
|
|
1187
1551
|
|
|
@@ -1203,21 +1567,7 @@ export const sliceString = (
|
|
|
1203
1567
|
)
|
|
1204
1568
|
}
|
|
1205
1569
|
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
try {
|
|
1209
|
-
// Attempt to decode with strict UTF-8 validation
|
|
1210
|
-
const result = new TextDecoder('utf-8', { fatal: true }).decode(slicedBytes)
|
|
1211
|
-
return result
|
|
1212
|
-
} catch (e: unknown) {
|
|
1213
|
-
// If we get here, the slice would create invalid UTF-8
|
|
1214
|
-
// This is a fundamental limitation of JavaScript string handling
|
|
1215
|
-
throw new Error(
|
|
1216
|
-
`Cannot slice string at byte indices [${actualLow}:${actualHigh}] because it would create invalid UTF-8. ` +
|
|
1217
|
-
`This is a limitation of JavaScript's string handling.`,
|
|
1218
|
-
{ cause: e },
|
|
1219
|
-
)
|
|
1220
|
-
}
|
|
1570
|
+
return goStringFromBytes(bytes.subarray(actualLow, actualHigh))
|
|
1221
1571
|
}
|
|
1222
1572
|
|
|
1223
1573
|
/**
|
|
@@ -1231,9 +1581,7 @@ export const bytesToString = (
|
|
|
1231
1581
|
if (bytes === null) return ''
|
|
1232
1582
|
// If it's already a string, just return it
|
|
1233
1583
|
if (typeof bytes === 'string') return bytes
|
|
1234
|
-
if (bytes instanceof Uint8Array)
|
|
1235
|
-
return new TextDecoder().decode(bytes)
|
|
1236
|
-
}
|
|
1584
|
+
if (bytes instanceof Uint8Array) return goStringFromBytes(bytes)
|
|
1237
1585
|
// Ensure we get a plain number[] for Uint8Array.from
|
|
1238
1586
|
let byteArray: number[]
|
|
1239
1587
|
if (isComplexSlice(bytes)) {
|
|
@@ -1246,7 +1594,114 @@ export const bytesToString = (
|
|
|
1246
1594
|
// For simple T[] slices
|
|
1247
1595
|
byteArray = bytes
|
|
1248
1596
|
}
|
|
1249
|
-
return
|
|
1597
|
+
return goStringFromBytes(Uint8Array.from(byteArray)) as string
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
export function stringEqual(
|
|
1601
|
+
left: GoStringBytes,
|
|
1602
|
+
right: GoStringBytes,
|
|
1603
|
+
): boolean {
|
|
1604
|
+
const leftBytes = goStringComparableBytes(left)
|
|
1605
|
+
const rightBytes = goStringComparableBytes(right)
|
|
1606
|
+
if (leftBytes.length !== rightBytes.length) {
|
|
1607
|
+
return false
|
|
1608
|
+
}
|
|
1609
|
+
for (let i = 0; i < leftBytes.length; i++) {
|
|
1610
|
+
if (leftBytes[i] !== rightBytes[i]) {
|
|
1611
|
+
return false
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
return true
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
export function stringCompare(
|
|
1618
|
+
left: GoStringBytes,
|
|
1619
|
+
right: GoStringBytes,
|
|
1620
|
+
): number {
|
|
1621
|
+
if (!isGoStringValue(left) && !isGoStringValue(right)) {
|
|
1622
|
+
const leftBytes = byteStringView(left)
|
|
1623
|
+
const rightBytes = byteStringView(right)
|
|
1624
|
+
const leftLen = leftBytes.length
|
|
1625
|
+
const rightLen = rightBytes.length
|
|
1626
|
+
const sharedLen = Math.min(leftLen, rightLen)
|
|
1627
|
+
for (let i = 0; i < sharedLen; i++) {
|
|
1628
|
+
const diff =
|
|
1629
|
+
(leftBytes.backing[leftBytes.offset + i] ?? 0) -
|
|
1630
|
+
(rightBytes.backing[rightBytes.offset + i] ?? 0)
|
|
1631
|
+
if (diff !== 0) {
|
|
1632
|
+
return diff
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
return leftLen - rightLen
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
const leftBytes = goStringComparableBytes(left)
|
|
1639
|
+
const rightBytes = goStringComparableBytes(right)
|
|
1640
|
+
const sharedLen = Math.min(leftBytes.length, rightBytes.length)
|
|
1641
|
+
for (let i = 0; i < sharedLen; i++) {
|
|
1642
|
+
const diff = leftBytes[i] - rightBytes[i]
|
|
1643
|
+
if (diff !== 0) {
|
|
1644
|
+
return diff
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
return leftBytes.length - rightBytes.length
|
|
1648
|
+
}
|
|
1649
|
+
|
|
1650
|
+
type ByteStringView = {
|
|
1651
|
+
backing: ArrayLike<number>
|
|
1652
|
+
offset: number
|
|
1653
|
+
length: number
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
function byteStringView(value: GoStringBytes): ByteStringView {
|
|
1657
|
+
value = collectionValue(value) as GoStringBytes
|
|
1658
|
+
if (value === null || value === undefined) {
|
|
1659
|
+
return { backing: [], offset: 0, length: 0 }
|
|
1660
|
+
}
|
|
1661
|
+
if (value instanceof Uint8Array) {
|
|
1662
|
+
return { backing: value, offset: 0, length: value.length }
|
|
1663
|
+
}
|
|
1664
|
+
if (Array.isArray(value)) {
|
|
1665
|
+
const meta = (value as unknown as SliceProxy<number>).__meta__
|
|
1666
|
+
if (meta !== undefined) {
|
|
1667
|
+
return {
|
|
1668
|
+
backing: meta.backing,
|
|
1669
|
+
offset: meta.offset,
|
|
1670
|
+
length: meta.length,
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
return { backing: value, offset: 0, length: value.length }
|
|
1674
|
+
}
|
|
1675
|
+
const meta = (value as unknown as SliceProxy<number>).__meta__
|
|
1676
|
+
return {
|
|
1677
|
+
backing: meta.backing,
|
|
1678
|
+
offset: meta.offset,
|
|
1679
|
+
length: meta.length,
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
function collectionValue(value: unknown): unknown {
|
|
1684
|
+
if (isVarRef(value)) {
|
|
1685
|
+
return collectionValue(value.value)
|
|
1686
|
+
}
|
|
1687
|
+
if (
|
|
1688
|
+
typeof value === 'object' &&
|
|
1689
|
+
value !== null &&
|
|
1690
|
+
typeof (value as { __goType?: unknown }).__goType === 'string' &&
|
|
1691
|
+
'__goValue' in value
|
|
1692
|
+
) {
|
|
1693
|
+
return collectionValue((value as { __goValue: unknown }).__goValue)
|
|
1694
|
+
}
|
|
1695
|
+
return value
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
function bytesToBinaryString(bytes: Uint8Array): string {
|
|
1699
|
+
const chunkSize = 0x8000
|
|
1700
|
+
let out = ''
|
|
1701
|
+
for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
1702
|
+
out += String.fromCharCode(...bytes.subarray(i, i + chunkSize))
|
|
1703
|
+
}
|
|
1704
|
+
return out
|
|
1250
1705
|
}
|
|
1251
1706
|
|
|
1252
1707
|
/**
|
|
@@ -1255,10 +1710,10 @@ export const bytesToString = (
|
|
|
1255
1710
|
* @returns A Uint8Array representing the UTF-8 bytes of the string.
|
|
1256
1711
|
*/
|
|
1257
1712
|
export function stringToBytes(
|
|
1258
|
-
s:
|
|
1713
|
+
s: GoStringValue | import('./builtin.js').Bytes,
|
|
1259
1714
|
): Uint8Array {
|
|
1260
|
-
if (
|
|
1261
|
-
return
|
|
1715
|
+
if (isGoStringValue(s)) {
|
|
1716
|
+
return goStringBytes(s)
|
|
1262
1717
|
}
|
|
1263
1718
|
// Already bytes - normalize to Uint8Array
|
|
1264
1719
|
if (s instanceof Uint8Array) {
|
|
@@ -1271,6 +1726,71 @@ export function stringToBytes(
|
|
|
1271
1726
|
return new Uint8Array(Array.isArray(s) ? s : [])
|
|
1272
1727
|
}
|
|
1273
1728
|
|
|
1729
|
+
type StringHeaderData = {
|
|
1730
|
+
kind: 'string'
|
|
1731
|
+
value: string
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
export function stringHeaderRef(s: VarRef<string>): VarRef<{
|
|
1735
|
+
Data: StringHeaderData
|
|
1736
|
+
Len: number
|
|
1737
|
+
}> {
|
|
1738
|
+
return varRef({
|
|
1739
|
+
get Data(): StringHeaderData {
|
|
1740
|
+
return { kind: 'string', value: s.value }
|
|
1741
|
+
},
|
|
1742
|
+
set Data(_value: StringHeaderData) {},
|
|
1743
|
+
get Len(): number {
|
|
1744
|
+
return stringToBytes(s.value).length
|
|
1745
|
+
},
|
|
1746
|
+
set Len(_value: number) {},
|
|
1747
|
+
})
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
export function sliceHeaderRef(b: VarRef<Slice<number>>): VarRef<{
|
|
1751
|
+
Data: StringHeaderData | null
|
|
1752
|
+
Len: number
|
|
1753
|
+
Cap: number
|
|
1754
|
+
}> {
|
|
1755
|
+
let data: StringHeaderData | null = null
|
|
1756
|
+
let length = 0
|
|
1757
|
+
let capacity = 0
|
|
1758
|
+
const refresh = () => {
|
|
1759
|
+
if (data === null) {
|
|
1760
|
+
return
|
|
1761
|
+
}
|
|
1762
|
+
const bytes = stringToBytes(data.value)
|
|
1763
|
+
const out = makeSlice<number>(length, Math.max(capacity, length), 'byte')
|
|
1764
|
+
if (out !== null) {
|
|
1765
|
+
copy(out, goSlice(bytes, 0, Math.min(length, bytes.length)))
|
|
1766
|
+
}
|
|
1767
|
+
b.value = out
|
|
1768
|
+
}
|
|
1769
|
+
return varRef({
|
|
1770
|
+
get Data(): StringHeaderData | null {
|
|
1771
|
+
return data
|
|
1772
|
+
},
|
|
1773
|
+
set Data(value: StringHeaderData | null) {
|
|
1774
|
+
data = value
|
|
1775
|
+
refresh()
|
|
1776
|
+
},
|
|
1777
|
+
get Len(): number {
|
|
1778
|
+
return length
|
|
1779
|
+
},
|
|
1780
|
+
set Len(value: number) {
|
|
1781
|
+
length = value
|
|
1782
|
+
refresh()
|
|
1783
|
+
},
|
|
1784
|
+
get Cap(): number {
|
|
1785
|
+
return capacity
|
|
1786
|
+
},
|
|
1787
|
+
set Cap(value: number) {
|
|
1788
|
+
capacity = value
|
|
1789
|
+
refresh()
|
|
1790
|
+
},
|
|
1791
|
+
})
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1274
1794
|
/**
|
|
1275
1795
|
* Handles string() conversion for values that could be either string or []byte.
|
|
1276
1796
|
* Used for generic type parameters with constraint []byte|string.
|
|
@@ -1283,8 +1803,8 @@ export function genericBytesOrStringToString(
|
|
|
1283
1803
|
if (value === null || value === undefined) {
|
|
1284
1804
|
return ''
|
|
1285
1805
|
}
|
|
1286
|
-
if (
|
|
1287
|
-
return value
|
|
1806
|
+
if (isGoStringValue(value)) {
|
|
1807
|
+
return value as string
|
|
1288
1808
|
}
|
|
1289
1809
|
return bytesToString(value)
|
|
1290
1810
|
}
|
|
@@ -1298,10 +1818,10 @@ export function genericBytesOrStringToString(
|
|
|
1298
1818
|
* @returns The byte value at the specified index
|
|
1299
1819
|
*/
|
|
1300
1820
|
export function indexStringOrBytes(
|
|
1301
|
-
value:
|
|
1821
|
+
value: GoStringValue | import('./builtin.js').Bytes,
|
|
1302
1822
|
index: number,
|
|
1303
1823
|
): number {
|
|
1304
|
-
if (
|
|
1824
|
+
if (isGoStringValue(value)) {
|
|
1305
1825
|
return indexString(value, index)
|
|
1306
1826
|
} else if (value instanceof Uint8Array) {
|
|
1307
1827
|
// For Uint8Array, direct access returns the byte value
|
|
@@ -1337,9 +1857,9 @@ export function indexStringOrBytes(
|
|
|
1337
1857
|
* @returns The sliced value of the same type as input
|
|
1338
1858
|
*/
|
|
1339
1859
|
export function sliceStringOrBytes<
|
|
1340
|
-
T extends
|
|
1860
|
+
T extends GoStringValue | import('./builtin.js').Bytes,
|
|
1341
1861
|
>(value: T, low?: number, high?: number, max?: number): T {
|
|
1342
|
-
if (
|
|
1862
|
+
if (isGoStringValue(value)) {
|
|
1343
1863
|
// For strings, use sliceString and ignore max parameter
|
|
1344
1864
|
return sliceString(value, low, high) as T
|
|
1345
1865
|
} else {
|