goscript 0.1.3 → 0.2.0
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 +5 -2
- package/cmd/go_js_wasm_exec/main.go +201 -0
- package/cmd/go_js_wasm_exec/main_test.go +83 -0
- package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +35 -8
- package/cmd/goscript/cmd-test.go +14 -0
- package/cmd/goscript/cmd-test_test.go +1 -1
- package/cmd/goscript/cmd_compile_test.go +105 -6
- package/compiler/build-flags.go +9 -10
- package/compiler/compile-request.go +12 -9
- package/compiler/compliance_test.go +0 -1
- package/compiler/config.go +2 -0
- package/compiler/gotest/request.go +28 -0
- package/compiler/gotest/runner.go +353 -27
- package/compiler/gotest/runner_test.go +400 -1
- package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
- package/compiler/gotest/testdata/browserapi/go.mod +3 -0
- package/compiler/lowered-program.go +24 -17
- package/compiler/lowering.go +988 -263
- package/compiler/lowering_bench_test.go +364 -0
- package/compiler/override-facts.go +15 -0
- package/compiler/override-parity-verifier.go +450 -0
- package/compiler/override-parity.go +122 -0
- package/compiler/override-registry_test.go +559 -0
- package/compiler/package-graph.go +61 -4
- package/compiler/package-graph_test.go +30 -0
- package/compiler/protobuf-ts-binding.go +514 -0
- package/compiler/protobuf-ts-binding_test.go +172 -0
- package/compiler/semantic-model-types.go +17 -4
- package/compiler/semantic-model.go +709 -72
- package/compiler/semantic-model_test.go +219 -0
- package/compiler/service.go +20 -1
- package/compiler/skeleton_test.go +1008 -20
- package/compiler/typescript-emitter.go +147 -15
- package/dist/gs/builtin/builtin.d.ts +2 -2
- package/dist/gs/builtin/builtin.js +20 -0
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +2 -1
- package/dist/gs/builtin/slice.js +34 -4
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +14 -6
- package/dist/gs/builtin/type.js +224 -64
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +11 -0
- package/dist/gs/builtin/varRef.js +57 -2
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +1 -1
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +1 -1
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +13 -6
- package/dist/gs/compress/zlib/index.js +131 -35
- package/dist/gs/compress/zlib/index.js.map +1 -1
- package/dist/gs/crypto/sha1/index.js +2 -5
- package/dist/gs/crypto/sha1/index.js.map +1 -1
- package/dist/gs/crypto/sha256/index.js +2 -5
- package/dist/gs/crypto/sha256/index.js.map +1 -1
- package/dist/gs/crypto/sha512/index.js +2 -5
- package/dist/gs/crypto/sha512/index.js.map +1 -1
- package/dist/gs/embed/index.d.ts +6 -0
- package/dist/gs/embed/index.js +210 -5
- package/dist/gs/embed/index.js.map +1 -1
- package/dist/gs/encoding/json/index.d.ts +114 -0
- package/dist/gs/encoding/json/index.js +544 -36
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +3 -3
- package/dist/gs/fmt/fmt.js +29 -16
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +100 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +564 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
- package/dist/gs/github.com/pkg/errors/errors.js +54 -30
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/go/scanner/index.d.ts +2 -0
- package/dist/gs/go/scanner/index.js +29 -5
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.js +22 -6
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/index.d.ts +6 -0
- package/dist/gs/hash/index.js +20 -0
- package/dist/gs/hash/index.js.map +1 -1
- package/dist/gs/internal/goarch/index.d.ts +43 -3
- package/dist/gs/internal/goarch/index.js +42 -10
- package/dist/gs/internal/goarch/index.js.map +1 -1
- package/dist/gs/io/fs/fs.js +26 -14
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/fs/readdir.js +8 -4
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/fs/sub.js +8 -1
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/io.d.ts +12 -6
- package/dist/gs/io/io.js +87 -42
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +31 -5
- package/dist/gs/math/bits/index.js +29 -28
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/mime/index.d.ts +16 -0
- package/dist/gs/mime/index.js +315 -6
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/httptest/index.d.ts +12 -0
- package/dist/gs/net/http/httptest/index.js +85 -6
- package/dist/gs/net/http/httptest/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +303 -6
- package/dist/gs/net/http/index.js +1615 -58
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/dir_unix.gs.js +1 -1
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +1 -1
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/exec.gs.d.ts +1 -0
- package/dist/gs/os/exec.gs.js +4 -8
- package/dist/gs/os/exec.gs.js.map +1 -1
- package/dist/gs/os/exec_posix.gs.js +1 -1
- package/dist/gs/os/exec_posix.gs.js.map +1 -1
- package/dist/gs/os/index.d.ts +1 -1
- package/dist/gs/os/index.js +1 -1
- package/dist/gs/os/index.js.map +1 -1
- package/dist/gs/os/proc.gs.d.ts +4 -0
- package/dist/gs/os/proc.gs.js +12 -6
- package/dist/gs/os/proc.gs.js.map +1 -1
- package/dist/gs/os/root_js.gs.js +1 -1
- package/dist/gs/os/root_js.gs.js.map +1 -1
- package/dist/gs/os/types.gs.js +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.d.ts +6 -2
- package/dist/gs/os/types_js.gs.js +170 -9
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.js +1 -1
- package/dist/gs/os/types_unix.gs.js.map +1 -1
- package/dist/gs/path/path.js +11 -7
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +5 -4
- package/dist/gs/reflect/index.js +4 -3
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js +15 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +26 -6
- package/dist/gs/reflect/type.js +1498 -279
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +14 -6
- package/dist/gs/reflect/types.js +35 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +1 -0
- package/dist/gs/reflect/value.js +83 -41
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +4 -140
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/pprof/index.d.ts +8 -2
- package/dist/gs/runtime/pprof/index.js +50 -30
- package/dist/gs/runtime/pprof/index.js.map +1 -1
- package/dist/gs/runtime/runtime.js +5 -4
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.js +5 -19
- package/dist/gs/runtime/trace/index.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.js +1 -1
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/complex.gs.d.ts +3 -0
- package/dist/gs/strconv/complex.gs.js +148 -0
- package/dist/gs/strconv/complex.gs.js.map +1 -0
- package/dist/gs/strconv/index.d.ts +1 -0
- package/dist/gs/strconv/index.js +1 -0
- package/dist/gs/strconv/index.js.map +1 -1
- package/dist/gs/strings/builder.js +1 -1
- package/dist/gs/strings/reader.d.ts +1 -1
- package/dist/gs/strings/reader.js +11 -7
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/replace.js +15 -7
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.d.ts +5 -0
- package/dist/gs/strings/strings.js +57 -5
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.js +9 -9
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/atomic/value.gs.js +2 -2
- package/dist/gs/sync/atomic/value.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +2 -1
- package/dist/gs/sync/sync.js +37 -16
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/env.js +22 -14
- package/dist/gs/syscall/env.js.map +1 -1
- package/dist/gs/syscall/js/index.js +9 -0
- package/dist/gs/syscall/js/index.js.map +1 -1
- package/dist/gs/testing/testing.js +59 -15
- package/dist/gs/testing/testing.js.map +1 -1
- package/dist/gs/time/time.d.ts +24 -1
- package/dist/gs/time/time.js +43 -3
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unique/index.js +7 -1
- package/dist/gs/unique/index.js.map +1 -1
- package/go.mod +3 -3
- package/go.sum +16 -0
- package/gs/builtin/builtin.ts +25 -2
- package/gs/builtin/runtime-contract.test.ts +260 -18
- package/gs/builtin/slice.ts +51 -4
- package/gs/builtin/type.ts +310 -63
- package/gs/builtin/varRef.ts +85 -2
- package/gs/bytes/buffer.gs.ts +1 -1
- package/gs/bytes/reader.gs.ts +1 -1
- package/gs/compress/zlib/index.test.ts +159 -1
- package/gs/compress/zlib/index.ts +164 -37
- package/gs/compress/zlib/meta.json +4 -1
- package/gs/compress/zlib/parity.json +51 -0
- package/gs/crypto/sha1/index.test.ts +19 -2
- package/gs/crypto/sha1/index.ts +3 -6
- package/gs/crypto/sha256/index.test.ts +14 -2
- package/gs/crypto/sha256/index.ts +3 -6
- package/gs/crypto/sha512/index.test.ts +17 -2
- package/gs/crypto/sha512/index.ts +3 -6
- package/gs/embed/index.test.ts +87 -0
- package/gs/embed/index.ts +229 -5
- package/gs/encoding/json/index.test.ts +360 -6
- package/gs/encoding/json/index.ts +679 -38
- package/gs/encoding/json/parity.json +81 -0
- package/gs/fmt/fmt.test.ts +41 -3
- package/gs/fmt/fmt.ts +40 -17
- package/gs/fmt/meta.json +6 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +211 -3
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +857 -1
- package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
- package/gs/github.com/pkg/errors/errors.ts +54 -30
- package/gs/go/scanner/index.test.ts +39 -56
- package/gs/go/scanner/index.ts +33 -5
- package/gs/go/scanner/parity.json +27 -0
- package/gs/go/token/index.ts +22 -6
- package/gs/hash/index.test.ts +20 -33
- package/gs/hash/index.ts +28 -0
- package/gs/hash/parity.json +21 -0
- package/gs/internal/goarch/index.test.ts +32 -0
- package/gs/internal/goarch/index.ts +45 -13
- package/gs/internal/goarch/parity.json +144 -0
- package/gs/io/fs/fs.ts +26 -14
- package/gs/io/fs/readdir.test.ts +38 -0
- package/gs/io/fs/readdir.ts +8 -4
- package/gs/io/fs/sub.ts +8 -1
- package/gs/io/io.test.ts +77 -6
- package/gs/io/io.ts +115 -52
- package/gs/io/meta.json +7 -1
- package/gs/io/parity.json +162 -0
- package/gs/math/bits/index.test.ts +14 -1
- package/gs/math/bits/index.ts +75 -32
- package/gs/math/bits/parity.json +156 -0
- package/gs/mime/index.test.ts +90 -0
- package/gs/mime/index.ts +369 -6
- package/gs/mime/parity.json +36 -0
- package/gs/net/http/httptest/index.test.ts +98 -2
- package/gs/net/http/httptest/index.ts +101 -6
- package/gs/net/http/httptest/parity.json +15 -0
- package/gs/net/http/index.test.ts +797 -12
- package/gs/net/http/index.ts +1874 -136
- package/gs/net/http/meta.json +16 -1
- package/gs/net/http/parity.json +193 -0
- package/gs/os/dir_unix.gs.ts +1 -1
- package/gs/os/error.gs.ts +1 -1
- package/gs/os/exec.gs.ts +4 -8
- package/gs/os/exec_posix.gs.ts +1 -1
- package/gs/os/file_unix_js.test.ts +52 -0
- package/gs/os/index.test.ts +9 -0
- package/gs/os/index.ts +1 -0
- package/gs/os/meta.json +4 -0
- package/gs/os/parity.json +9 -0
- package/gs/os/proc.gs.ts +18 -5
- package/gs/os/proc.test.ts +26 -0
- package/gs/os/readdir.test.ts +56 -0
- package/gs/os/root_js.gs.ts +1 -1
- package/gs/os/types.gs.ts +1 -1
- package/gs/os/types_js.gs.ts +170 -9
- package/gs/os/types_unix.gs.ts +1 -1
- package/gs/path/path.ts +11 -7
- package/gs/reflect/deepequal.test.ts +10 -1
- package/gs/reflect/field.test.ts +37 -15
- package/gs/reflect/function-types.test.ts +518 -22
- package/gs/reflect/index.ts +8 -6
- package/gs/reflect/map.ts +20 -0
- package/gs/reflect/meta.json +6 -4
- package/gs/reflect/parity.json +234 -0
- package/gs/reflect/sliceat.test.ts +156 -0
- package/gs/reflect/structof.test.ts +401 -0
- package/gs/reflect/type.ts +1980 -365
- package/gs/reflect/typefor.test.ts +540 -10
- package/gs/reflect/types.ts +43 -18
- package/gs/reflect/value.ts +105 -45
- package/gs/reflect/visiblefields.ts +5 -168
- package/gs/runtime/parity.json +24 -0
- package/gs/runtime/pprof/index.test.ts +29 -7
- package/gs/runtime/pprof/index.ts +56 -30
- package/gs/runtime/pprof/parity.json +27 -0
- package/gs/runtime/runtime.test.ts +3 -1
- package/gs/runtime/runtime.ts +4 -3
- package/gs/runtime/trace/index.test.ts +5 -3
- package/gs/runtime/trace/index.ts +8 -20
- package/gs/runtime/trace/parity.json +36 -0
- package/gs/strconv/atoi.gs.ts +1 -1
- package/gs/strconv/complex.gs.ts +174 -0
- package/gs/strconv/complex.test.ts +65 -0
- package/gs/strconv/index.ts +1 -0
- package/gs/strconv/parity.json +120 -0
- package/gs/strings/builder.ts +1 -1
- package/gs/strings/meta.json +5 -2
- package/gs/strings/parity.json +186 -0
- package/gs/strings/reader.test.ts +2 -2
- package/gs/strings/reader.ts +11 -7
- package/gs/strings/replace.ts +15 -7
- package/gs/strings/strings.test.ts +22 -2
- package/gs/strings/strings.ts +64 -6
- package/gs/sync/atomic/type.gs.ts +9 -9
- package/gs/sync/atomic/value.gs.ts +2 -2
- package/gs/sync/meta.json +1 -0
- package/gs/sync/sync.test.ts +41 -1
- package/gs/sync/sync.ts +41 -16
- package/gs/syscall/env.ts +29 -14
- package/gs/syscall/js/index.test.ts +18 -0
- package/gs/syscall/js/index.ts +12 -0
- package/gs/testing/testing.test.ts +99 -3
- package/gs/testing/testing.ts +95 -24
- package/gs/time/parity.json +225 -0
- package/gs/time/time.test.ts +20 -2
- package/gs/time/time.ts +49 -7
- package/gs/unique/index.ts +7 -1
- package/package.json +4 -2
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -814
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -31
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1233
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
- /package/compiler/{wasm_api.go → wasm-api.go} +0 -0
package/gs/builtin/varRef.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export interface OwnedPointerHandle<T = unknown> {
|
|
2
|
+
readonly __goOwnedPointer: true
|
|
3
|
+
__goAddress: () => number
|
|
4
|
+
__goRef: () => VarRef<T>
|
|
5
|
+
__goSlice?: (length: number) => unknown
|
|
6
|
+
}
|
|
7
|
+
|
|
1
8
|
/**
|
|
2
9
|
* VarRef represents a Go variable which can be referred to by other variables.
|
|
3
10
|
*
|
|
@@ -12,6 +19,51 @@ export type VarRef<T> = {
|
|
|
12
19
|
__goAddress?: () => number
|
|
13
20
|
__goCollection?: unknown
|
|
14
21
|
__goIndex?: number
|
|
22
|
+
__goPointer?: OwnedPointerHandle<T>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const pointerAddressStride = 0x100000000
|
|
26
|
+
const pointerAddresses = new WeakMap<object, number>()
|
|
27
|
+
const fieldPointerAddresses = new WeakMap<
|
|
28
|
+
object,
|
|
29
|
+
globalThis.Map<PropertyKey, number>
|
|
30
|
+
>()
|
|
31
|
+
let nextPointerAddress = 1
|
|
32
|
+
|
|
33
|
+
function pointerAddress(value: object): number {
|
|
34
|
+
let address = pointerAddresses.get(value)
|
|
35
|
+
if (address === undefined) {
|
|
36
|
+
address = nextPointerAddress * pointerAddressStride
|
|
37
|
+
nextPointerAddress++
|
|
38
|
+
pointerAddresses.set(value, address)
|
|
39
|
+
}
|
|
40
|
+
return address
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function fieldPointerAddress(target: object, key: PropertyKey): number {
|
|
44
|
+
let addresses = fieldPointerAddresses.get(target)
|
|
45
|
+
if (addresses === undefined) {
|
|
46
|
+
addresses = new globalThis.Map<PropertyKey, number>()
|
|
47
|
+
fieldPointerAddresses.set(target, addresses)
|
|
48
|
+
}
|
|
49
|
+
let address = addresses.get(key)
|
|
50
|
+
if (address === undefined) {
|
|
51
|
+
address = nextPointerAddress * pointerAddressStride
|
|
52
|
+
nextPointerAddress++
|
|
53
|
+
addresses.set(key, address)
|
|
54
|
+
}
|
|
55
|
+
return address
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function refPointer<T>(
|
|
59
|
+
ref: VarRef<T>,
|
|
60
|
+
address: () => number,
|
|
61
|
+
): OwnedPointerHandle<T> {
|
|
62
|
+
return {
|
|
63
|
+
__goOwnedPointer: true,
|
|
64
|
+
__goAddress: address,
|
|
65
|
+
__goRef: () => ref,
|
|
66
|
+
}
|
|
15
67
|
}
|
|
16
68
|
|
|
17
69
|
/** Wrap a non-null T in a variable reference. */
|
|
@@ -19,7 +71,10 @@ export function varRef<T>(v: T): VarRef<T> {
|
|
|
19
71
|
// We create a new object wrapper for every varRef call to ensure
|
|
20
72
|
// distinct pointer identity, crucial for pointer comparisons (p1 == p2).
|
|
21
73
|
// The __isVarRef marker allows the reflect system to identify this as a pointer type.
|
|
22
|
-
|
|
74
|
+
const ref: VarRef<T> = { value: v, __isVarRef: true }
|
|
75
|
+
ref.__goAddress = () => pointerAddress(ref)
|
|
76
|
+
ref.__goPointer = refPointer(ref, ref.__goAddress)
|
|
77
|
+
return ref
|
|
23
78
|
}
|
|
24
79
|
|
|
25
80
|
/** Create a variable reference to an object field. */
|
|
@@ -27,7 +82,8 @@ export function fieldRef<T extends object, K extends keyof T>(
|
|
|
27
82
|
target: T,
|
|
28
83
|
key: K,
|
|
29
84
|
): VarRef<T[K]> {
|
|
30
|
-
|
|
85
|
+
const address = () => fieldPointerAddress(target, key)
|
|
86
|
+
const ref: VarRef<T[K]> = {
|
|
31
87
|
get value(): T[K] {
|
|
32
88
|
return target[key]
|
|
33
89
|
},
|
|
@@ -35,7 +91,10 @@ export function fieldRef<T extends object, K extends keyof T>(
|
|
|
35
91
|
target[key] = value
|
|
36
92
|
},
|
|
37
93
|
__isVarRef: true,
|
|
94
|
+
__goAddress: address,
|
|
38
95
|
}
|
|
96
|
+
ref.__goPointer = refPointer(ref, address)
|
|
97
|
+
return ref
|
|
39
98
|
}
|
|
40
99
|
|
|
41
100
|
/** Check if a value is a VarRef (pointer) */
|
|
@@ -43,6 +102,30 @@ export function isVarRef(v: unknown): v is VarRef<unknown> {
|
|
|
43
102
|
return v !== null && typeof v === 'object' && (v as any).__isVarRef === true
|
|
44
103
|
}
|
|
45
104
|
|
|
105
|
+
export function isOwnedPointerHandle(
|
|
106
|
+
value: unknown,
|
|
107
|
+
): value is OwnedPointerHandle {
|
|
108
|
+
return (
|
|
109
|
+
value !== null &&
|
|
110
|
+
typeof value === 'object' &&
|
|
111
|
+
(value as { __goOwnedPointer?: unknown }).__goOwnedPointer === true
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function ownedPointerFromRef<T>(
|
|
116
|
+
ref: VarRef<T>,
|
|
117
|
+
): OwnedPointerHandle<T> | undefined {
|
|
118
|
+
return ref.__goPointer
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function ownedPointerAddress(pointer: OwnedPointerHandle): number {
|
|
122
|
+
return pointer.__goAddress()
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function ownedPointerRef<T>(pointer: OwnedPointerHandle<T>): VarRef<T> {
|
|
126
|
+
return pointer.__goRef()
|
|
127
|
+
}
|
|
128
|
+
|
|
46
129
|
/** Dereference a variable reference, throws on null → simulates Go panic. */
|
|
47
130
|
export function unref<T>(b: VarRef<T>): T {
|
|
48
131
|
if (b === null) {
|
package/gs/bytes/buffer.gs.ts
CHANGED
|
@@ -549,7 +549,7 @@ export class Buffer {
|
|
|
549
549
|
new Buffer(),
|
|
550
550
|
[{ name: "Bytes", args: [], returns: [{ type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }] }, { name: "AvailableBuffer", args: [], returns: [{ type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }] }, { name: "String", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "string" } }] }, { name: "empty", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "boolean" } }] }, { name: "Len", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Cap", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Available", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Truncate", args: [{ name: "n", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [] }, { name: "Reset", args: [], returns: [] }, { name: "tryGrowByReslice", args: [{ name: "n", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Basic, name: "boolean" } }] }, { name: "grow", args: [{ name: "n", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Grow", args: [{ name: "n", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [] }, { name: "Write", args: [{ name: "p", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "WriteString", args: [{ name: "s", type: { kind: $.TypeKind.Basic, name: "string" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadFrom", args: [{ name: "r", type: "Reader" }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "WriteTo", args: [{ name: "w", type: "Writer" }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "WriteByte", args: [{ name: "c", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "WriteRune", args: [{ name: "r", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "Read", args: [{ name: "p", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "Next", args: [{ name: "n", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }] }, { name: "ReadByte", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadRune", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "UnreadRune", args: [], returns: [{ type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "UnreadByte", args: [], returns: [{ type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadBytes", args: [{ name: "delim", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "readSlice", args: [{ name: "delim", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadString", args: [{ name: "delim", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "string" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }],
|
|
551
551
|
Buffer,
|
|
552
|
-
{"buf": { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } }, "off": { kind: $.TypeKind.Basic, name: "number" }, "lastRead": "readOp"}
|
|
552
|
+
[{ name: "buf", key: "buf", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }, { name: "off", key: "off", type: { kind: $.TypeKind.Basic, name: "number" } }, { name: "lastRead", key: "lastRead", type: "readOp" }]
|
|
553
553
|
);
|
|
554
554
|
}
|
|
555
555
|
|
package/gs/bytes/reader.gs.ts
CHANGED
|
@@ -221,7 +221,7 @@ export class Reader {
|
|
|
221
221
|
new Reader(),
|
|
222
222
|
[{ name: "Len", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Size", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }] }, { name: "Read", args: [{ name: "b", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadAt", args: [{ name: "b", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }, { name: "off", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadByte", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "UnreadByte", args: [], returns: [{ type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "ReadRune", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "UnreadRune", args: [], returns: [{ type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "Seek", args: [{ name: "offset", type: { kind: $.TypeKind.Basic, name: "number" } }, { name: "whence", type: { kind: $.TypeKind.Basic, name: "number" } }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "WriteTo", args: [{ name: "w", type: "Writer" }], returns: [{ type: { kind: $.TypeKind.Basic, name: "number" } }, { type: { kind: $.TypeKind.Interface, name: 'GoError', methods: [{ name: 'Error', args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: 'string' } }] }] } }] }, { name: "Reset", args: [{ name: "b", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }], returns: [] }],
|
|
223
223
|
Reader,
|
|
224
|
-
{"s": { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } }, "i": { kind: $.TypeKind.Basic, name: "number" }, "prevRune": { kind: $.TypeKind.Basic, name: "number" }}
|
|
224
|
+
[{ name: "s", key: "s", type: { kind: $.TypeKind.Slice, elemType: { kind: $.TypeKind.Basic, name: "number" } } }, { name: "i", key: "i", type: { kind: $.TypeKind.Basic, name: "number" } }, { name: "prevRune", key: "prevRune", type: { kind: $.TypeKind.Basic, name: "number" } }]
|
|
225
225
|
);
|
|
226
226
|
}
|
|
227
227
|
|
|
@@ -4,9 +4,43 @@ import * as $ from '@goscript/builtin/index.js'
|
|
|
4
4
|
import * as bytes from '@goscript/bytes/index.js'
|
|
5
5
|
import * as io from '@goscript/io/index.js'
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
BestCompression,
|
|
9
|
+
BestSpeed,
|
|
10
|
+
DefaultCompression,
|
|
11
|
+
ErrChecksum,
|
|
12
|
+
ErrDictionary,
|
|
13
|
+
HuffmanOnly,
|
|
14
|
+
NewReader,
|
|
15
|
+
NewReaderDict,
|
|
16
|
+
NewWriter,
|
|
17
|
+
NewWriterLevel,
|
|
18
|
+
NewWriterLevelDict,
|
|
19
|
+
NoCompression,
|
|
20
|
+
} from './index.js'
|
|
8
21
|
|
|
9
22
|
describe('compress/zlib override', () => {
|
|
23
|
+
test('exports flate compression level constants', () => {
|
|
24
|
+
expect(NoCompression).toBe(0)
|
|
25
|
+
expect(BestSpeed).toBe(1)
|
|
26
|
+
expect(BestCompression).toBe(9)
|
|
27
|
+
expect(DefaultCompression).toBe(-1)
|
|
28
|
+
expect(HuffmanOnly).toBe(-2)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test('rejects invalid compression levels', () => {
|
|
32
|
+
const buf = $.markAsStructValue(new bytes.Buffer())
|
|
33
|
+
|
|
34
|
+
expect(NewWriterLevel(buf, HuffmanOnly)[1]).toBeNull()
|
|
35
|
+
expect(NewWriterLevel(buf, BestCompression)[1]).toBeNull()
|
|
36
|
+
expect(NewWriterLevel(buf, HuffmanOnly - 1)[1]?.Error()).toBe(
|
|
37
|
+
'zlib: invalid compression level: -3',
|
|
38
|
+
)
|
|
39
|
+
expect(NewWriterLevelDict(buf, BestCompression + 1, null)[1]?.Error()).toBe(
|
|
40
|
+
'zlib: invalid compression level: 10',
|
|
41
|
+
)
|
|
42
|
+
})
|
|
43
|
+
|
|
10
44
|
test('round trips bytes through writer and reader', async () => {
|
|
11
45
|
const input = $.stringToBytes('hello compressed world')
|
|
12
46
|
const buf = $.markAsStructValue(new bytes.Buffer())
|
|
@@ -25,4 +59,128 @@ describe('compress/zlib override', () => {
|
|
|
25
59
|
expect(readErr).toBeNull()
|
|
26
60
|
expect($.bytesToString(out)).toBe('hello compressed world')
|
|
27
61
|
})
|
|
62
|
+
|
|
63
|
+
test('reader implements resettable zlib reader contract', async () => {
|
|
64
|
+
const first = $.markAsStructValue(new bytes.Buffer())
|
|
65
|
+
const firstWriter = NewWriter(first)
|
|
66
|
+
expect(firstWriter.Write($.stringToBytes('first stream'))[1]).toBeNull()
|
|
67
|
+
expect(await firstWriter.Close()).toBeNull()
|
|
68
|
+
|
|
69
|
+
const second = $.markAsStructValue(new bytes.Buffer())
|
|
70
|
+
const secondWriter = NewWriter(second)
|
|
71
|
+
expect(secondWriter.Write($.stringToBytes('second stream'))[1]).toBeNull()
|
|
72
|
+
expect(await secondWriter.Close()).toBeNull()
|
|
73
|
+
|
|
74
|
+
const readerInterface = $.registerInterfaceType(
|
|
75
|
+
'compress/zlib.testReader',
|
|
76
|
+
null,
|
|
77
|
+
[
|
|
78
|
+
{ name: 'Close', args: [], returns: [{ type: 'error' }] },
|
|
79
|
+
{
|
|
80
|
+
name: 'Read',
|
|
81
|
+
args: [
|
|
82
|
+
{
|
|
83
|
+
name: 'p',
|
|
84
|
+
type: {
|
|
85
|
+
kind: $.TypeKind.Slice,
|
|
86
|
+
elemType: { kind: $.TypeKind.Basic, name: 'uint8' },
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
returns: [{ type: 'int' }, { type: 'error' }],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'Reset',
|
|
94
|
+
args: [{ type: 'io.Reader' }, { type: '[]byte' }],
|
|
95
|
+
returns: [{ type: 'error' }],
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
const [reader, readerErr] = NewReader(bytes.NewReader(first.Bytes()))
|
|
101
|
+
expect(readerErr).toBeNull()
|
|
102
|
+
const [zlibReader, ok] = $.typeAssertTuple<
|
|
103
|
+
io.ReadCloser & {
|
|
104
|
+
Reset(r: io.Reader | null, dict: $.Bytes | null): $.GoError
|
|
105
|
+
}
|
|
106
|
+
>(reader, readerInterface)
|
|
107
|
+
expect(ok).toBe(true)
|
|
108
|
+
|
|
109
|
+
const [firstOut, firstReadErr] = await io.ReadAll(zlibReader)
|
|
110
|
+
expect(firstReadErr).toBeNull()
|
|
111
|
+
expect($.bytesToString(firstOut)).toBe('first stream')
|
|
112
|
+
|
|
113
|
+
expect(zlibReader.Reset(bytes.NewReader(second.Bytes()), null)).toBeNull()
|
|
114
|
+
const [secondOut, secondReadErr] = await io.ReadAll(zlibReader)
|
|
115
|
+
expect(secondReadErr).toBeNull()
|
|
116
|
+
expect($.bytesToString(secondOut)).toBe('second stream')
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
test('writer and reader honor preset dictionaries', async () => {
|
|
120
|
+
const dict = $.stringToBytes('hello dictionary')
|
|
121
|
+
const compressed = $.markAsStructValue(new bytes.Buffer())
|
|
122
|
+
const [writer, writerErr] = NewWriterLevelDict(compressed, DefaultCompression, dict)
|
|
123
|
+
expect(writerErr).toBeNull()
|
|
124
|
+
expect(writer!.Write($.stringToBytes('hello dictionary payload'))[1]).toBeNull()
|
|
125
|
+
expect(await writer!.Close()).toBeNull()
|
|
126
|
+
|
|
127
|
+
const [missingDictReader, missingDictErr] = NewReader(bytes.NewReader(compressed.Bytes()))
|
|
128
|
+
expect(missingDictReader).toBeNull()
|
|
129
|
+
expect(missingDictErr).toBe(ErrDictionary)
|
|
130
|
+
|
|
131
|
+
const [reader, readerErr] = NewReaderDict(bytes.NewReader(compressed.Bytes()), dict)
|
|
132
|
+
expect(readerErr).toBeNull()
|
|
133
|
+
const [out, readErr] = await io.ReadAll(reader!)
|
|
134
|
+
expect(readErr).toBeNull()
|
|
135
|
+
expect($.bytesToString(out)).toBe('hello dictionary payload')
|
|
136
|
+
|
|
137
|
+
const [, wrongDictErr] = NewReaderDict(bytes.NewReader(compressed.Bytes()), $.stringToBytes('wrong dictionary'))
|
|
138
|
+
expect(wrongDictErr).toBe(ErrDictionary)
|
|
139
|
+
|
|
140
|
+
const corrupt = Uint8Array.from(compressed.Bytes())
|
|
141
|
+
corrupt[corrupt.length - 1] ^= 0xff
|
|
142
|
+
const [, corruptErr] = NewReaderDict(bytes.NewReader(corrupt), dict)
|
|
143
|
+
expect(corruptErr).toBe(ErrChecksum)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
test('reader reset accepts async generated readers', async () => {
|
|
147
|
+
const compressed = $.markAsStructValue(new bytes.Buffer())
|
|
148
|
+
const writer = NewWriter(compressed)
|
|
149
|
+
expect(writer.Write($.stringToBytes('async source stream'))[1]).toBeNull()
|
|
150
|
+
expect(await writer.Close()).toBeNull()
|
|
151
|
+
|
|
152
|
+
const source = bytes.NewReader(compressed.Bytes())
|
|
153
|
+
const asyncReader = {
|
|
154
|
+
async Read(p: $.Bytes): Promise<[number, $.GoError]> {
|
|
155
|
+
await Promise.resolve()
|
|
156
|
+
return source.Read(p)
|
|
157
|
+
},
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const [reader, readerErr] = NewReader(asyncReader as io.Reader)
|
|
161
|
+
expect(readerErr).toBeNull()
|
|
162
|
+
const [out, readErr] = await io.ReadAll(reader!)
|
|
163
|
+
expect(readErr).toBeNull()
|
|
164
|
+
expect($.bytesToString(out)).toBe('async source stream')
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
test('Close awaits pointer-wrapped generated writers', async () => {
|
|
168
|
+
const chunks: number[] = []
|
|
169
|
+
const sink = {
|
|
170
|
+
async Write(p: $.Bytes): Promise<[number, $.GoError]> {
|
|
171
|
+
await Promise.resolve()
|
|
172
|
+
chunks.push(...Array.from(p ?? []))
|
|
173
|
+
return [$.len(p), null]
|
|
174
|
+
},
|
|
175
|
+
}
|
|
176
|
+
const writer = NewWriter(
|
|
177
|
+
$.interfaceValue($.varRef(sink), '*zlib.asyncWriter'),
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
const [written, writeErr] = writer.Write($.stringToBytes('async zlib sink'))
|
|
181
|
+
expect(writeErr).toBeNull()
|
|
182
|
+
expect(written).toBe('async zlib sink'.length)
|
|
183
|
+
expect(await writer.Close()).toBeNull()
|
|
184
|
+
expect(chunks.length).toBeGreaterThan(0)
|
|
185
|
+
})
|
|
28
186
|
})
|
|
@@ -3,13 +3,25 @@ import * as errors from '@goscript/errors/index.js'
|
|
|
3
3
|
import * as io from '@goscript/io/index.js'
|
|
4
4
|
|
|
5
5
|
export type Resetter = {
|
|
6
|
-
Reset(r: io.Reader | null, dict: $.Bytes | null):
|
|
6
|
+
Reset(r: io.Reader | null, dict: $.Bytes | null): $.GoError
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
type maybeAsyncWriter = {
|
|
10
|
+
Write(p: $.Bytes): [number, $.GoError] | Promise<[number, $.GoError]>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const NoCompression = 0
|
|
14
|
+
export const BestSpeed = 1
|
|
15
|
+
export const BestCompression = 9
|
|
16
|
+
export const DefaultCompression = -1
|
|
17
|
+
export const HuffmanOnly = -2
|
|
18
|
+
|
|
9
19
|
export let ErrChecksum = errors.New('zlib: invalid checksum')
|
|
10
20
|
export let ErrDictionary = errors.New('zlib: invalid dictionary')
|
|
11
21
|
export let ErrHeader = errors.New('zlib: invalid header')
|
|
12
22
|
|
|
23
|
+
type nodeZlibError = Error & { code?: unknown }
|
|
24
|
+
|
|
13
25
|
export function __goscript_set_ErrChecksum(value: $.GoError): void {
|
|
14
26
|
ErrChecksum = value
|
|
15
27
|
}
|
|
@@ -22,12 +34,30 @@ export function __goscript_set_ErrHeader(value: $.GoError): void {
|
|
|
22
34
|
ErrHeader = value
|
|
23
35
|
}
|
|
24
36
|
|
|
25
|
-
class zlibReader implements
|
|
37
|
+
class zlibReader implements Resetter {
|
|
38
|
+
private data: Uint8Array = new Uint8Array(0)
|
|
26
39
|
private offset = 0
|
|
40
|
+
private pending:
|
|
41
|
+
| Promise<{ data: Uint8Array | null; err: $.GoError }>
|
|
42
|
+
| null = null
|
|
27
43
|
|
|
28
|
-
constructor(
|
|
44
|
+
constructor(data?: Uint8Array) {
|
|
45
|
+
if (data != null) {
|
|
46
|
+
this.data = data
|
|
47
|
+
}
|
|
48
|
+
}
|
|
29
49
|
|
|
30
|
-
Read(p: $.Bytes): [number, $.GoError] {
|
|
50
|
+
async Read(p: $.Bytes): Promise<[number, $.GoError]> {
|
|
51
|
+
const pending = this.pending
|
|
52
|
+
if (pending != null) {
|
|
53
|
+
this.pending = null
|
|
54
|
+
const result = await pending
|
|
55
|
+
if (result.err != null) {
|
|
56
|
+
return [0, result.err]
|
|
57
|
+
}
|
|
58
|
+
this.data = result.data ?? new Uint8Array(0)
|
|
59
|
+
this.offset = 0
|
|
60
|
+
}
|
|
31
61
|
if (this.offset >= this.data.length) {
|
|
32
62
|
return [0, io.EOF]
|
|
33
63
|
}
|
|
@@ -41,13 +71,37 @@ class zlibReader implements io.ReadCloser {
|
|
|
41
71
|
Close(): $.GoError {
|
|
42
72
|
return null
|
|
43
73
|
}
|
|
74
|
+
|
|
75
|
+
Reset(r: io.Reader | null, dict: $.Bytes | null): $.GoError {
|
|
76
|
+
if (r == null) {
|
|
77
|
+
return errors.New('zlib: nil reader')
|
|
78
|
+
}
|
|
79
|
+
const result = readInflated(r, dict)
|
|
80
|
+
if (result instanceof Promise) {
|
|
81
|
+
this.data = new Uint8Array(0)
|
|
82
|
+
this.offset = 0
|
|
83
|
+
this.pending = result
|
|
84
|
+
return null
|
|
85
|
+
}
|
|
86
|
+
if (result.err != null) {
|
|
87
|
+
return result.err
|
|
88
|
+
}
|
|
89
|
+
this.data = result.data ?? new Uint8Array(0)
|
|
90
|
+
this.offset = 0
|
|
91
|
+
this.pending = null
|
|
92
|
+
return null
|
|
93
|
+
}
|
|
44
94
|
}
|
|
45
95
|
|
|
46
96
|
export class Writer {
|
|
47
97
|
private chunks: Uint8Array[] = []
|
|
48
98
|
private closed = false
|
|
49
99
|
|
|
50
|
-
constructor(
|
|
100
|
+
constructor(
|
|
101
|
+
private w: io.Writer | null,
|
|
102
|
+
private dict: $.Bytes | null = null,
|
|
103
|
+
private level = DefaultCompression,
|
|
104
|
+
) {}
|
|
51
105
|
|
|
52
106
|
Write(p: $.Bytes): [number, $.GoError] {
|
|
53
107
|
if (this.closed) {
|
|
@@ -58,7 +112,7 @@ export class Writer {
|
|
|
58
112
|
return [data.length, null]
|
|
59
113
|
}
|
|
60
114
|
|
|
61
|
-
Close():
|
|
115
|
+
async Close(): Promise<$.GoError> {
|
|
62
116
|
if (this.closed) {
|
|
63
117
|
return null
|
|
64
118
|
}
|
|
@@ -66,8 +120,9 @@ export class Writer {
|
|
|
66
120
|
if (this.w == null) {
|
|
67
121
|
return errors.New('zlib: nil writer')
|
|
68
122
|
}
|
|
69
|
-
const compressed = deflate(concat(this.chunks))
|
|
70
|
-
const
|
|
123
|
+
const compressed = deflate(concat(this.chunks), this.dict, this.level)
|
|
124
|
+
const writer = $.pointerValue<maybeAsyncWriter>(this.w)
|
|
125
|
+
const [, err] = await writer.Write(compressed)
|
|
71
126
|
return err
|
|
72
127
|
}
|
|
73
128
|
|
|
@@ -88,17 +143,23 @@ export function NewWriter(w: io.Writer | null): Writer {
|
|
|
88
143
|
|
|
89
144
|
export function NewWriterLevel(
|
|
90
145
|
w: io.Writer | null,
|
|
91
|
-
|
|
146
|
+
level: number,
|
|
92
147
|
): [Writer | null, $.GoError] {
|
|
93
|
-
|
|
148
|
+
if (level < HuffmanOnly || level > BestCompression) {
|
|
149
|
+
return [null, errors.New(`zlib: invalid compression level: ${level}`)]
|
|
150
|
+
}
|
|
151
|
+
return [new Writer(w, null, level), null]
|
|
94
152
|
}
|
|
95
153
|
|
|
96
154
|
export function NewWriterLevelDict(
|
|
97
155
|
w: io.Writer | null,
|
|
98
|
-
|
|
156
|
+
level: number,
|
|
99
157
|
_dict: $.Bytes | null,
|
|
100
158
|
): [Writer | null, $.GoError] {
|
|
101
|
-
|
|
159
|
+
if (level < HuffmanOnly || level > BestCompression) {
|
|
160
|
+
return [null, errors.New(`zlib: invalid compression level: ${level}`)]
|
|
161
|
+
}
|
|
162
|
+
return [new Writer(w, _dict, level), null]
|
|
102
163
|
}
|
|
103
164
|
|
|
104
165
|
export function NewReader(
|
|
@@ -109,31 +170,35 @@ export function NewReader(
|
|
|
109
170
|
|
|
110
171
|
export function NewReaderDict(
|
|
111
172
|
r: io.Reader | null,
|
|
112
|
-
|
|
173
|
+
dict: $.Bytes | null,
|
|
113
174
|
): [io.ReadCloser | null, $.GoError] {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (readErr != null) {
|
|
119
|
-
return [null, readErr]
|
|
120
|
-
}
|
|
121
|
-
try {
|
|
122
|
-
const out = inflate($.bytesToUint8Array(data))
|
|
123
|
-
return [new zlibReader(out), null]
|
|
124
|
-
} catch {
|
|
125
|
-
return [null, ErrHeader]
|
|
175
|
+
const reader = new zlibReader()
|
|
176
|
+
const err = reader.Reset(r, dict)
|
|
177
|
+
if (err != null) {
|
|
178
|
+
return [null, err]
|
|
126
179
|
}
|
|
180
|
+
return [reader as any, null]
|
|
127
181
|
}
|
|
128
182
|
|
|
129
|
-
function deflate(data: Uint8Array): Uint8Array {
|
|
183
|
+
function deflate(data: Uint8Array, dict: $.Bytes | null, level: number): Uint8Array {
|
|
130
184
|
const zlib = nodeZlib()
|
|
131
|
-
|
|
185
|
+
const opts: Record<string, unknown> = {}
|
|
186
|
+
if (dict != null && $.len(dict) > 0) {
|
|
187
|
+
opts.dictionary = $.bytesToUint8Array(dict)
|
|
188
|
+
}
|
|
189
|
+
if (level === HuffmanOnly) {
|
|
190
|
+
opts.strategy = zlib.constants?.Z_HUFFMAN_ONLY
|
|
191
|
+
opts.level = DefaultCompression
|
|
192
|
+
} else {
|
|
193
|
+
opts.level = level
|
|
194
|
+
}
|
|
195
|
+
return new Uint8Array(zlib.deflateSync(data, opts))
|
|
132
196
|
}
|
|
133
197
|
|
|
134
|
-
function inflate(data: Uint8Array): Uint8Array {
|
|
198
|
+
function inflate(data: Uint8Array, dict: $.Bytes | null): Uint8Array {
|
|
135
199
|
const zlib = nodeZlib()
|
|
136
|
-
|
|
200
|
+
const opts = dict != null && $.len(dict) > 0 ? { dictionary: $.bytesToUint8Array(dict) } : undefined
|
|
201
|
+
return new Uint8Array(zlib.inflateSync(data, opts))
|
|
137
202
|
}
|
|
138
203
|
|
|
139
204
|
function nodeZlib(): any {
|
|
@@ -168,23 +233,85 @@ function nodeZlib(): any {
|
|
|
168
233
|
throw new Error('compress/zlib: node zlib module unavailable')
|
|
169
234
|
}
|
|
170
235
|
|
|
171
|
-
function
|
|
172
|
-
|
|
173
|
-
|
|
236
|
+
function readInflated(
|
|
237
|
+
r: io.Reader,
|
|
238
|
+
dict: $.Bytes | null,
|
|
239
|
+
):
|
|
240
|
+
| { data: Uint8Array | null; err: $.GoError }
|
|
241
|
+
| Promise<{ data: Uint8Array | null; err: $.GoError }> {
|
|
242
|
+
const chunks: number[] = []
|
|
243
|
+
const buf = $.makeSlice<number>(1, undefined, 'byte')
|
|
174
244
|
while (true) {
|
|
175
|
-
const
|
|
176
|
-
if (
|
|
177
|
-
|
|
245
|
+
const read = r.Read(buf)
|
|
246
|
+
if (read instanceof Promise) {
|
|
247
|
+
return readInflatedAsync(read, r, buf, chunks, dict)
|
|
248
|
+
}
|
|
249
|
+
const [n, err] = read
|
|
250
|
+
const result = recordCompressedBytes(chunks, buf, n, dict)
|
|
251
|
+
if (result.err == null && result.data != null) {
|
|
252
|
+
return result
|
|
178
253
|
}
|
|
179
254
|
if (err != null) {
|
|
180
255
|
if (err === io.EOF) {
|
|
181
|
-
return
|
|
256
|
+
return result
|
|
182
257
|
}
|
|
183
|
-
return
|
|
258
|
+
return { data: null, err }
|
|
184
259
|
}
|
|
185
260
|
}
|
|
186
261
|
}
|
|
187
262
|
|
|
263
|
+
async function readInflatedAsync(
|
|
264
|
+
first: Promise<[number, $.GoError]>,
|
|
265
|
+
r: io.Reader,
|
|
266
|
+
buf: $.Bytes,
|
|
267
|
+
chunks: number[],
|
|
268
|
+
dict: $.Bytes | null,
|
|
269
|
+
): Promise<{ data: Uint8Array | null; err: $.GoError }> {
|
|
270
|
+
let read = await first
|
|
271
|
+
while (true) {
|
|
272
|
+
const [n, err] = read
|
|
273
|
+
const result = recordCompressedBytes(chunks, buf, n, dict)
|
|
274
|
+
if (result.err == null && result.data != null) {
|
|
275
|
+
return result
|
|
276
|
+
}
|
|
277
|
+
if (err != null) {
|
|
278
|
+
if (err === io.EOF) {
|
|
279
|
+
return result
|
|
280
|
+
}
|
|
281
|
+
return { data: null, err }
|
|
282
|
+
}
|
|
283
|
+
read = await r.Read(buf)
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function recordCompressedBytes(
|
|
288
|
+
chunks: number[],
|
|
289
|
+
buf: $.Bytes,
|
|
290
|
+
n: number,
|
|
291
|
+
dict: $.Bytes | null,
|
|
292
|
+
): { data: Uint8Array | null; err: $.GoError } {
|
|
293
|
+
if (n > 0) {
|
|
294
|
+
chunks.push(...$.bytesToUint8Array($.goSlice(buf, 0, n)))
|
|
295
|
+
}
|
|
296
|
+
const compressed = new Uint8Array(chunks)
|
|
297
|
+
try {
|
|
298
|
+
return { data: inflate(compressed, dict), err: null }
|
|
299
|
+
} catch (err) {
|
|
300
|
+
return { data: null, err: classifyInflateError(err) }
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function classifyInflateError(err: unknown): $.GoError {
|
|
305
|
+
const zerr = err instanceof Error ? err as nodeZlibError : null
|
|
306
|
+
if (zerr?.code === 'Z_NEED_DICT') {
|
|
307
|
+
return ErrDictionary
|
|
308
|
+
}
|
|
309
|
+
if (zerr?.code === 'Z_DATA_ERROR' && zerr.message.includes('incorrect data check')) {
|
|
310
|
+
return ErrChecksum
|
|
311
|
+
}
|
|
312
|
+
return ErrHeader
|
|
313
|
+
}
|
|
314
|
+
|
|
188
315
|
function concat(chunks: Uint8Array[]): Uint8Array {
|
|
189
316
|
let total = 0
|
|
190
317
|
for (const chunk of chunks) {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"strict": true,
|
|
4
|
+
"symbols": {
|
|
5
|
+
"BestCompression": {
|
|
6
|
+
"status": "real"
|
|
7
|
+
},
|
|
8
|
+
"BestSpeed": {
|
|
9
|
+
"status": "real"
|
|
10
|
+
},
|
|
11
|
+
"DefaultCompression": {
|
|
12
|
+
"status": "real"
|
|
13
|
+
},
|
|
14
|
+
"ErrChecksum": {
|
|
15
|
+
"status": "real"
|
|
16
|
+
},
|
|
17
|
+
"ErrDictionary": {
|
|
18
|
+
"status": "real"
|
|
19
|
+
},
|
|
20
|
+
"ErrHeader": {
|
|
21
|
+
"status": "real"
|
|
22
|
+
},
|
|
23
|
+
"HuffmanOnly": {
|
|
24
|
+
"status": "real"
|
|
25
|
+
},
|
|
26
|
+
"NewReader": {
|
|
27
|
+
"status": "real"
|
|
28
|
+
},
|
|
29
|
+
"NewReaderDict": {
|
|
30
|
+
"status": "real"
|
|
31
|
+
},
|
|
32
|
+
"NewWriter": {
|
|
33
|
+
"status": "real"
|
|
34
|
+
},
|
|
35
|
+
"NewWriterLevel": {
|
|
36
|
+
"status": "real"
|
|
37
|
+
},
|
|
38
|
+
"NewWriterLevelDict": {
|
|
39
|
+
"status": "real"
|
|
40
|
+
},
|
|
41
|
+
"NoCompression": {
|
|
42
|
+
"status": "real"
|
|
43
|
+
},
|
|
44
|
+
"Resetter": {
|
|
45
|
+
"status": "real"
|
|
46
|
+
},
|
|
47
|
+
"Writer": {
|
|
48
|
+
"status": "real"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|