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/dist/gs/builtin/slice.js
CHANGED
|
@@ -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
|
-
|
|
9
|
-
|
|
10
|
-
if (index
|
|
11
|
-
return
|
|
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} >= ${
|
|
78
|
+
throw new Error(`Slice index out of range: ${index} >= ${meta.length}`);
|
|
14
79
|
}
|
|
15
80
|
if (prop === 'length') {
|
|
16
|
-
return
|
|
81
|
+
return meta.length;
|
|
17
82
|
}
|
|
18
83
|
if (prop === '__meta__') {
|
|
19
|
-
return
|
|
84
|
+
return meta;
|
|
20
85
|
}
|
|
21
86
|
return Reflect.get(target, prop);
|
|
22
87
|
},
|
|
23
88
|
set(target, prop, value) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (index
|
|
27
|
-
|
|
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} >= ${
|
|
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
|
-
|
|
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
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
-
//
|
|
130
|
-
|
|
131
|
-
|
|
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];
|
|
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
|
-
|
|
156
|
-
|
|
157
|
-
if (index
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
if (index
|
|
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
|
-
|
|
193
|
-
|
|
194
|
-
if (index
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
if (index
|
|
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 ||
|
|
241
|
-
|
|
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
|
|
364
|
+
const newLength = actualHigh - actualLow;
|
|
244
365
|
if (max !== undefined) {
|
|
245
|
-
if (max < actualHigh || max >
|
|
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 <=
|
|
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
|
-
|
|
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
|
-
|
|
391
|
-
|
|
392
|
-
if (index
|
|
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
|
-
|
|
416
|
-
|
|
417
|
-
if (index
|
|
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);
|
|
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
|
|
462
|
-
return obj
|
|
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 (
|
|
468
|
-
return obj.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
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
|
-
|
|
608
|
-
|
|
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
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
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 (
|
|
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
|
|
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] =
|
|
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 =
|
|
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] =
|
|
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
|
-
|
|
693
|
-
|
|
694
|
-
|
|
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] =
|
|
713
|
-
dst[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] =
|
|
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
|
-
|
|
730
|
-
|
|
731
|
-
|
|
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
|
-
|
|
746
|
-
|
|
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 (
|
|
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 (
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
|
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 (
|
|
947
|
-
return
|
|
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 (
|
|
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 (
|
|
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 (
|
|
1390
|
+
if (isGoStringValue(value)) {
|
|
1016
1391
|
// For strings, use sliceString and ignore max parameter
|
|
1017
1392
|
return sliceString(value, low, high);
|
|
1018
1393
|
}
|