goscript 0.1.3 → 0.1.4
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/cmd/goscript/cmd_compile.go +28 -8
- package/cmd/goscript/cmd_compile_test.go +105 -6
- package/compiler/build-flags.go +9 -10
- package/compiler/gotest/runner_test.go +127 -0
- package/compiler/lowering.go +596 -136
- package/compiler/lowering_bench_test.go +350 -0
- package/compiler/package-graph.go +61 -4
- package/compiler/package-graph_test.go +30 -0
- package/compiler/semantic-model-types.go +8 -0
- package/compiler/semantic-model.go +447 -22
- package/compiler/semantic-model_test.go +138 -0
- package/compiler/skeleton_test.go +948 -14
- package/compiler/typescript-emitter.go +19 -2
- 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.js +5 -0
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +1 -1
- package/dist/gs/builtin/type.js +72 -5
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +3 -3
- package/dist/gs/compress/zlib/index.js +88 -26
- 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/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/starpc/srpc/index.js +118 -6
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/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/io/fs/readdir.js +5 -3
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/io.d.ts +10 -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 +26 -5
- package/dist/gs/math/bits/index.js +13 -24
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +3 -1
- package/dist/gs/net/http/index.js +18 -1
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/types_js.gs.d.ts +6 -2
- package/dist/gs/os/types_js.gs.js +169 -8
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +1 -0
- package/dist/gs/reflect/type.js +80 -51
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/strings/reader.d.ts +1 -1
- package/dist/gs/strings/reader.js +2 -2
- package/dist/gs/strings/reader.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/js/index.js +9 -0
- package/dist/gs/syscall/js/index.js.map +1 -1
- package/dist/gs/testing/testing.js +8 -6
- package/dist/gs/testing/testing.js.map +1 -1
- package/gs/builtin/builtin.ts +25 -2
- package/gs/builtin/runtime-contract.test.ts +45 -0
- package/gs/builtin/slice.ts +7 -0
- package/gs/builtin/type.ts +85 -5
- package/gs/compress/zlib/index.test.ts +97 -0
- package/gs/compress/zlib/index.ts +117 -27
- package/gs/compress/zlib/meta.json +4 -1
- 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/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/starpc/srpc/index.test.ts +8 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +139 -11
- 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/io/fs/readdir.test.ts +38 -0
- package/gs/io/fs/readdir.ts +7 -3
- package/gs/io/io.test.ts +77 -6
- package/gs/io/io.ts +114 -52
- package/gs/io/meta.json +7 -1
- package/gs/math/bits/index.ts +52 -28
- package/gs/net/http/index.test.ts +16 -0
- package/gs/net/http/index.ts +19 -2
- package/gs/os/file_unix_js.test.ts +52 -0
- package/gs/os/meta.json +4 -0
- package/gs/os/readdir.test.ts +56 -0
- package/gs/os/types_js.gs.ts +169 -8
- package/gs/reflect/deepequal.test.ts +10 -1
- package/gs/reflect/type.ts +91 -56
- package/gs/reflect/typefor.test.ts +31 -1
- package/gs/strings/meta.json +5 -2
- package/gs/strings/reader.test.ts +2 -2
- package/gs/strings/reader.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/js/index.test.ts +18 -0
- package/gs/syscall/js/index.ts +12 -0
- package/gs/testing/testing.test.ts +32 -3
- package/gs/testing/testing.ts +13 -10
- package/package.json +1 -1
|
@@ -3,7 +3,11 @@ 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
|
+
}
|
|
8
|
+
|
|
9
|
+
type maybeAsyncWriter = {
|
|
10
|
+
Write(p: $.Bytes): [number, $.GoError] | Promise<[number, $.GoError]>
|
|
7
11
|
}
|
|
8
12
|
|
|
9
13
|
export let ErrChecksum = errors.New('zlib: invalid checksum')
|
|
@@ -22,12 +26,30 @@ export function __goscript_set_ErrHeader(value: $.GoError): void {
|
|
|
22
26
|
ErrHeader = value
|
|
23
27
|
}
|
|
24
28
|
|
|
25
|
-
class zlibReader implements
|
|
29
|
+
class zlibReader implements Resetter {
|
|
30
|
+
private data: Uint8Array = new Uint8Array(0)
|
|
26
31
|
private offset = 0
|
|
32
|
+
private pending:
|
|
33
|
+
| Promise<{ data: Uint8Array | null; err: $.GoError }>
|
|
34
|
+
| null = null
|
|
27
35
|
|
|
28
|
-
constructor(
|
|
36
|
+
constructor(data?: Uint8Array) {
|
|
37
|
+
if (data != null) {
|
|
38
|
+
this.data = data
|
|
39
|
+
}
|
|
40
|
+
}
|
|
29
41
|
|
|
30
|
-
Read(p: $.Bytes): [number, $.GoError] {
|
|
42
|
+
async Read(p: $.Bytes): Promise<[number, $.GoError]> {
|
|
43
|
+
const pending = this.pending
|
|
44
|
+
if (pending != null) {
|
|
45
|
+
this.pending = null
|
|
46
|
+
const result = await pending
|
|
47
|
+
if (result.err != null) {
|
|
48
|
+
return [0, result.err]
|
|
49
|
+
}
|
|
50
|
+
this.data = result.data ?? new Uint8Array(0)
|
|
51
|
+
this.offset = 0
|
|
52
|
+
}
|
|
31
53
|
if (this.offset >= this.data.length) {
|
|
32
54
|
return [0, io.EOF]
|
|
33
55
|
}
|
|
@@ -41,6 +63,26 @@ class zlibReader implements io.ReadCloser {
|
|
|
41
63
|
Close(): $.GoError {
|
|
42
64
|
return null
|
|
43
65
|
}
|
|
66
|
+
|
|
67
|
+
Reset(r: io.Reader | null, dict: $.Bytes | null): $.GoError {
|
|
68
|
+
if (r == null) {
|
|
69
|
+
return errors.New('zlib: nil reader')
|
|
70
|
+
}
|
|
71
|
+
const result = readInflated(r, dict)
|
|
72
|
+
if (result instanceof Promise) {
|
|
73
|
+
this.data = new Uint8Array(0)
|
|
74
|
+
this.offset = 0
|
|
75
|
+
this.pending = result
|
|
76
|
+
return null
|
|
77
|
+
}
|
|
78
|
+
if (result.err != null) {
|
|
79
|
+
return result.err
|
|
80
|
+
}
|
|
81
|
+
this.data = result.data ?? new Uint8Array(0)
|
|
82
|
+
this.offset = 0
|
|
83
|
+
this.pending = null
|
|
84
|
+
return null
|
|
85
|
+
}
|
|
44
86
|
}
|
|
45
87
|
|
|
46
88
|
export class Writer {
|
|
@@ -58,7 +100,7 @@ export class Writer {
|
|
|
58
100
|
return [data.length, null]
|
|
59
101
|
}
|
|
60
102
|
|
|
61
|
-
Close():
|
|
103
|
+
async Close(): Promise<$.GoError> {
|
|
62
104
|
if (this.closed) {
|
|
63
105
|
return null
|
|
64
106
|
}
|
|
@@ -67,7 +109,8 @@ export class Writer {
|
|
|
67
109
|
return errors.New('zlib: nil writer')
|
|
68
110
|
}
|
|
69
111
|
const compressed = deflate(concat(this.chunks))
|
|
70
|
-
const
|
|
112
|
+
const writer = $.pointerValue<maybeAsyncWriter>(this.w)
|
|
113
|
+
const [, err] = await writer.Write(compressed)
|
|
71
114
|
return err
|
|
72
115
|
}
|
|
73
116
|
|
|
@@ -109,21 +152,14 @@ export function NewReader(
|
|
|
109
152
|
|
|
110
153
|
export function NewReaderDict(
|
|
111
154
|
r: io.Reader | null,
|
|
112
|
-
|
|
155
|
+
dict: $.Bytes | null,
|
|
113
156
|
): [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]
|
|
157
|
+
const reader = new zlibReader()
|
|
158
|
+
const err = reader.Reset(r, dict)
|
|
159
|
+
if (err != null) {
|
|
160
|
+
return [null, err]
|
|
126
161
|
}
|
|
162
|
+
return [reader as any, null]
|
|
127
163
|
}
|
|
128
164
|
|
|
129
165
|
function deflate(data: Uint8Array): Uint8Array {
|
|
@@ -168,20 +204,74 @@ function nodeZlib(): any {
|
|
|
168
204
|
throw new Error('compress/zlib: node zlib module unavailable')
|
|
169
205
|
}
|
|
170
206
|
|
|
171
|
-
function
|
|
172
|
-
|
|
173
|
-
|
|
207
|
+
function readInflated(
|
|
208
|
+
r: io.Reader,
|
|
209
|
+
dict: $.Bytes | null,
|
|
210
|
+
):
|
|
211
|
+
| { data: Uint8Array | null; err: $.GoError }
|
|
212
|
+
| Promise<{ data: Uint8Array | null; err: $.GoError }> {
|
|
213
|
+
const chunks: number[] = []
|
|
214
|
+
const buf = $.makeSlice<number>(1, undefined, 'byte')
|
|
215
|
+
while (true) {
|
|
216
|
+
const read = r.Read(buf)
|
|
217
|
+
if (read instanceof Promise) {
|
|
218
|
+
return readInflatedAsync(read, r, buf, chunks, dict)
|
|
219
|
+
}
|
|
220
|
+
const [n, err] = read
|
|
221
|
+
const result = recordCompressedBytes(chunks, buf, n, dict)
|
|
222
|
+
if (result.err == null && result.data != null) {
|
|
223
|
+
return result
|
|
224
|
+
}
|
|
225
|
+
if (err != null) {
|
|
226
|
+
if (err === io.EOF) {
|
|
227
|
+
return result
|
|
228
|
+
}
|
|
229
|
+
return { data: null, err }
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async function readInflatedAsync(
|
|
235
|
+
first: Promise<[number, $.GoError]>,
|
|
236
|
+
r: io.Reader,
|
|
237
|
+
buf: $.Bytes,
|
|
238
|
+
chunks: number[],
|
|
239
|
+
dict: $.Bytes | null,
|
|
240
|
+
): Promise<{ data: Uint8Array | null; err: $.GoError }> {
|
|
241
|
+
let read = await first
|
|
174
242
|
while (true) {
|
|
175
|
-
const [n, err] =
|
|
176
|
-
|
|
177
|
-
|
|
243
|
+
const [n, err] = read
|
|
244
|
+
const result = recordCompressedBytes(chunks, buf, n, dict)
|
|
245
|
+
if (result.err == null && result.data != null) {
|
|
246
|
+
return result
|
|
178
247
|
}
|
|
179
248
|
if (err != null) {
|
|
180
249
|
if (err === io.EOF) {
|
|
181
|
-
return
|
|
250
|
+
return result
|
|
182
251
|
}
|
|
183
|
-
return
|
|
252
|
+
return { data: null, err }
|
|
253
|
+
}
|
|
254
|
+
read = await r.Read(buf)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function recordCompressedBytes(
|
|
259
|
+
chunks: number[],
|
|
260
|
+
buf: $.Bytes,
|
|
261
|
+
n: number,
|
|
262
|
+
dict: $.Bytes | null,
|
|
263
|
+
): { data: Uint8Array | null; err: $.GoError } {
|
|
264
|
+
if (n > 0) {
|
|
265
|
+
chunks.push(...$.bytesToUint8Array($.goSlice(buf, 0, n)))
|
|
266
|
+
}
|
|
267
|
+
const compressed = new Uint8Array(chunks)
|
|
268
|
+
try {
|
|
269
|
+
return { data: inflate(compressed), err: null }
|
|
270
|
+
} catch {
|
|
271
|
+
if (dict != null && $.len(dict) > 0) {
|
|
272
|
+
return { data: null, err: ErrDictionary }
|
|
184
273
|
}
|
|
274
|
+
return { data: null, err: ErrHeader }
|
|
185
275
|
}
|
|
186
276
|
}
|
|
187
277
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto'
|
|
2
2
|
import { describe, expect, it } from 'vitest'
|
|
3
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
3
4
|
|
|
4
|
-
import { New, Sum } from './index.js'
|
|
5
|
+
import { New, Size, Sum } from './index.js'
|
|
5
6
|
|
|
6
7
|
describe('crypto/sha1 override', () => {
|
|
7
8
|
it('matches Node digest', async () => {
|
|
@@ -15,7 +16,23 @@ describe('crypto/sha1 override', () => {
|
|
|
15
16
|
h.Write(new TextEncoder().encode('go'))
|
|
16
17
|
h.Write(new TextEncoder().encode('script'))
|
|
17
18
|
|
|
18
|
-
expect(toHex(await h.Sum(null))).toBe(
|
|
19
|
+
expect(toHex(await h.Sum(null))).toBe(
|
|
20
|
+
nodeHash(new TextEncoder().encode('goscript')),
|
|
21
|
+
)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('appends into spare byte-slice backing', async () => {
|
|
25
|
+
const h = New()
|
|
26
|
+
h.Write(new TextEncoder().encode('abc'))
|
|
27
|
+
|
|
28
|
+
const backing = $.makeSlice<number>(Size, undefined, 'byte')
|
|
29
|
+
const out = await h.Sum($.goSlice(backing, 0, 0))
|
|
30
|
+
expect(out.length).toBe(Size)
|
|
31
|
+
expect(backing[0]).toBe(out[0])
|
|
32
|
+
expect(backing[Size - 1]).toBe(out[Size - 1])
|
|
33
|
+
expect(toHex($.bytesToUint8Array(backing))).toBe(
|
|
34
|
+
nodeHash(new TextEncoder().encode('abc')),
|
|
35
|
+
)
|
|
19
36
|
})
|
|
20
37
|
})
|
|
21
38
|
|
package/gs/crypto/sha1/index.ts
CHANGED
|
@@ -41,7 +41,7 @@ class Digest {
|
|
|
41
41
|
this.canCopyHash ?
|
|
42
42
|
new Uint8Array(this.hash!.copy!().digest())
|
|
43
43
|
: await sum(this.snapshotBytes())
|
|
44
|
-
return appendDigest(
|
|
44
|
+
return appendDigest(b, digest)
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
Reset(): void {
|
|
@@ -92,11 +92,8 @@ async function sum(data: $.Bytes): Promise<Uint8Array> {
|
|
|
92
92
|
return new Uint8Array(digest)
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
function appendDigest(prefix:
|
|
96
|
-
|
|
97
|
-
out.set(prefix)
|
|
98
|
-
out.set(digest, prefix.length)
|
|
99
|
-
return out
|
|
95
|
+
function appendDigest(prefix: $.Bytes, digest: Uint8Array): $.Bytes {
|
|
96
|
+
return $.append(prefix as any, ...digest) as $.Bytes
|
|
100
97
|
}
|
|
101
98
|
|
|
102
99
|
function createNodeHash(): NodeCryptoHash | null {
|
|
@@ -25,11 +25,23 @@ describe('crypto/sha256 override', () => {
|
|
|
25
25
|
)
|
|
26
26
|
})
|
|
27
27
|
|
|
28
|
+
test('streaming digest appends into spare byte-slice backing', async () => {
|
|
29
|
+
const digest = New()
|
|
30
|
+
expect(digest.Write($.stringToBytes('abc'))).toEqual([3, null])
|
|
31
|
+
|
|
32
|
+
const backing = $.makeSlice<number>(Size, undefined, 'byte')
|
|
33
|
+
const out = await digest.Sum($.goSlice(backing, 0, 0))
|
|
34
|
+
expect(out.length).toBe(Size)
|
|
35
|
+
expect(Array.from($.bytesToUint8Array(backing))).toEqual(
|
|
36
|
+
Array.from(await Sum256($.stringToBytes('abc'))),
|
|
37
|
+
)
|
|
38
|
+
})
|
|
39
|
+
|
|
28
40
|
test('sums SHA-224 with host crypto', async () => {
|
|
29
41
|
const sum = await Sum224($.stringToBytes('abc'))
|
|
30
42
|
expect(Array.from(sum)).toEqual([
|
|
31
|
-
35, 9, 125, 34, 52, 5, 216, 34, 134, 66, 164, 119, 189, 162, 85, 179,
|
|
32
|
-
|
|
43
|
+
35, 9, 125, 34, 52, 5, 216, 34, 134, 66, 164, 119, 189, 162, 85, 179, 42,
|
|
44
|
+
173, 188, 228, 189, 160, 179, 247, 227, 108, 157, 167,
|
|
33
45
|
])
|
|
34
46
|
})
|
|
35
47
|
|
|
@@ -44,7 +44,7 @@ class Digest {
|
|
|
44
44
|
this.canCopyHash ?
|
|
45
45
|
new Uint8Array(this.hash!.copy!().digest())
|
|
46
46
|
: await sum(this.algorithm, this.snapshotBytes())
|
|
47
|
-
return appendDigest(
|
|
47
|
+
return appendDigest(b, digest)
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
Reset(): void {
|
|
@@ -112,11 +112,8 @@ async function sum(
|
|
|
112
112
|
return new Uint8Array(digest)
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
function appendDigest(prefix:
|
|
116
|
-
|
|
117
|
-
out.set(prefix)
|
|
118
|
-
out.set(digest, prefix.length)
|
|
119
|
-
return out
|
|
115
|
+
function appendDigest(prefix: $.Bytes, digest: Uint8Array): $.Bytes {
|
|
116
|
+
return $.append(prefix as any, ...digest) as $.Bytes
|
|
120
117
|
}
|
|
121
118
|
|
|
122
119
|
function createNodeHash(algorithm: ShaAlgorithm): NodeCryptoHash | null {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto'
|
|
2
2
|
import { describe, expect, it } from 'vitest'
|
|
3
|
+
import * as $ from '@goscript/builtin/index.js'
|
|
3
4
|
|
|
4
|
-
import { New, Sum384, Sum512, Sum512_224, Sum512_256 } from './index.js'
|
|
5
|
+
import { New, Size, Sum384, Sum512, Sum512_224, Sum512_256 } from './index.js'
|
|
5
6
|
|
|
6
7
|
describe('crypto/sha512 override', () => {
|
|
7
8
|
it('matches Node digests', async () => {
|
|
@@ -18,7 +19,21 @@ describe('crypto/sha512 override', () => {
|
|
|
18
19
|
h.Write(new TextEncoder().encode('go'))
|
|
19
20
|
h.Write(new TextEncoder().encode('script'))
|
|
20
21
|
|
|
21
|
-
expect(toHex(await h.Sum(null))).toBe(
|
|
22
|
+
expect(toHex(await h.Sum(null))).toBe(
|
|
23
|
+
nodeHash('sha512', new TextEncoder().encode('goscript')),
|
|
24
|
+
)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it('appends into spare byte-slice backing', async () => {
|
|
28
|
+
const h = New()
|
|
29
|
+
h.Write(new TextEncoder().encode('abc'))
|
|
30
|
+
|
|
31
|
+
const backing = $.makeSlice<number>(Size, undefined, 'byte')
|
|
32
|
+
const out = await h.Sum($.goSlice(backing, 0, 0))
|
|
33
|
+
expect(out.length).toBe(Size)
|
|
34
|
+
expect(toHex($.bytesToUint8Array(backing))).toBe(
|
|
35
|
+
nodeHash('sha512', new TextEncoder().encode('abc')),
|
|
36
|
+
)
|
|
22
37
|
})
|
|
23
38
|
})
|
|
24
39
|
|
|
@@ -38,7 +38,7 @@ class Digest {
|
|
|
38
38
|
this.canCopyHash ?
|
|
39
39
|
new Uint8Array(this.hash!.copy!().digest())
|
|
40
40
|
: await sum(this.algorithm, this.snapshotBytes())
|
|
41
|
-
return appendDigest(
|
|
41
|
+
return appendDigest(b, digest)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
Reset(): void {
|
|
@@ -123,11 +123,8 @@ async function sum(
|
|
|
123
123
|
return new Uint8Array(digest)
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
function appendDigest(prefix:
|
|
127
|
-
|
|
128
|
-
out.set(prefix)
|
|
129
|
-
out.set(digest, prefix.length)
|
|
130
|
-
return out
|
|
126
|
+
function appendDigest(prefix: $.Bytes, digest: Uint8Array): $.Bytes {
|
|
127
|
+
return $.append(prefix as any, ...digest) as $.Bytes
|
|
131
128
|
}
|
|
132
129
|
|
|
133
130
|
function createNodeHash(algorithm: ShaAlgorithm): NodeCryptoHash | null {
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { cloneStructValue, markAsStructValue } from '@goscript/builtin/index.js'
|
|
4
|
+
import { EOF } from '@goscript/io/index.js'
|
|
5
|
+
import { ReadDir, ReadFile, Stat } from '@goscript/io/fs/index.js'
|
|
6
|
+
|
|
7
|
+
import { FS } from './index.js'
|
|
8
|
+
|
|
9
|
+
describe('embed.FS', () => {
|
|
10
|
+
it('clones embedded files as Go struct values', () => {
|
|
11
|
+
const original = markAsStructValue(
|
|
12
|
+
new FS(new Map([['config-set.bin', new Uint8Array([1, 2, 3])]])),
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
const cloned = cloneStructValue(original)
|
|
16
|
+
const [data, err] = cloned.ReadFile('config-set.bin')
|
|
17
|
+
|
|
18
|
+
expect(err).toBeNull()
|
|
19
|
+
expect(Array.from(data)).toEqual([1, 2, 3])
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('supports io/fs read, stat, and directory APIs', () => {
|
|
23
|
+
const fsys = markAsStructValue(
|
|
24
|
+
new FS(
|
|
25
|
+
new Map([
|
|
26
|
+
['config-set.bin', new Uint8Array([1, 2, 3])],
|
|
27
|
+
['assets/config.json', new Uint8Array([4])],
|
|
28
|
+
]),
|
|
29
|
+
),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
const [data, readErr] = ReadFile(fsys, 'config-set.bin')
|
|
33
|
+
expect(readErr).toBeNull()
|
|
34
|
+
expect(Array.from(data)).toEqual([1, 2, 3])
|
|
35
|
+
data[0] = 9
|
|
36
|
+
const [dataAgain, readAgainErr] = ReadFile(fsys, 'config-set.bin')
|
|
37
|
+
expect(readAgainErr).toBeNull()
|
|
38
|
+
expect(Array.from(dataAgain)).toEqual([1, 2, 3])
|
|
39
|
+
|
|
40
|
+
const [rootEntries, rootErr] = ReadDir(fsys, '.')
|
|
41
|
+
expect(rootErr).toBeNull()
|
|
42
|
+
expect(rootEntries!.map((entry) => entry!.Name())).toEqual([
|
|
43
|
+
'assets',
|
|
44
|
+
'config-set.bin',
|
|
45
|
+
])
|
|
46
|
+
|
|
47
|
+
const [assetInfo, statErr] = Stat(fsys, 'assets')
|
|
48
|
+
expect(statErr).toBeNull()
|
|
49
|
+
expect(assetInfo!.IsDir()).toBe(true)
|
|
50
|
+
|
|
51
|
+
const [assetEntries, assetErr] = ReadDir(fsys, 'assets')
|
|
52
|
+
expect(assetErr).toBeNull()
|
|
53
|
+
expect(assetEntries!.map((entry) => entry!.Name())).toEqual(['config.json'])
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('supports Open file reads and directory iteration', () => {
|
|
57
|
+
const fsys = markAsStructValue(
|
|
58
|
+
new FS(
|
|
59
|
+
new Map([
|
|
60
|
+
['config-set.bin', new Uint8Array([1, 2, 3])],
|
|
61
|
+
['assets/config.json', new Uint8Array([4])],
|
|
62
|
+
]),
|
|
63
|
+
),
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
const [file, openErr] = fsys.Open('config-set.bin')
|
|
67
|
+
expect(openErr).toBeNull()
|
|
68
|
+
const buffer = new Uint8Array(2)
|
|
69
|
+
const [firstRead, firstErr] = file!.Read(buffer)
|
|
70
|
+
expect(firstErr).toBeNull()
|
|
71
|
+
expect(firstRead).toBe(2)
|
|
72
|
+
expect(Array.from(buffer)).toEqual([1, 2])
|
|
73
|
+
const [secondRead, secondErr] = file!.Read(buffer)
|
|
74
|
+
expect(secondErr).toBeNull()
|
|
75
|
+
expect(secondRead).toBe(1)
|
|
76
|
+
expect(Array.from(buffer)).toEqual([3, 2])
|
|
77
|
+
const [eofRead, eofErr] = file!.Read(buffer)
|
|
78
|
+
expect(eofRead).toBe(0)
|
|
79
|
+
expect(eofErr).toBe(EOF)
|
|
80
|
+
|
|
81
|
+
const [dir, dirOpenErr] = fsys.Open('.')
|
|
82
|
+
expect(dirOpenErr).toBeNull()
|
|
83
|
+
const [entries, readDirErr] = dir!.ReadDir(1)
|
|
84
|
+
expect(readDirErr).toBeNull()
|
|
85
|
+
expect(entries!.map((entry) => entry!.Name())).toEqual(['assets'])
|
|
86
|
+
})
|
|
87
|
+
})
|