goscript 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/compiler/gotest/testdata/browserapi/browserapi_test.go +36 -0
  2. package/compiler/lowering.go +223 -9
  3. package/compiler/override-registry_test.go +50 -0
  4. package/compiler/protobuf-ts-binding.go +154 -6
  5. package/compiler/protobuf-ts-binding_test.go +7 -2
  6. package/compiler/runtime-contract.go +2 -0
  7. package/compiler/runtime-contract_test.go +1 -0
  8. package/compiler/semantic-model.go +16 -0
  9. package/compiler/semantic-model_test.go +38 -0
  10. package/compiler/skeleton_test.go +473 -15
  11. package/compiler/typescript-emitter.go +4 -0
  12. package/dist/gs/builtin/builtin.js +7 -9
  13. package/dist/gs/builtin/builtin.js.map +1 -1
  14. package/dist/gs/builtin/defer.js +2 -2
  15. package/dist/gs/builtin/hostio.js +5 -5
  16. package/dist/gs/builtin/hostio.js.map +1 -1
  17. package/dist/gs/builtin/map.js +2 -1
  18. package/dist/gs/builtin/map.js.map +1 -1
  19. package/dist/gs/builtin/slice.d.ts +3 -0
  20. package/dist/gs/builtin/slice.js +39 -0
  21. package/dist/gs/builtin/slice.js.map +1 -1
  22. package/dist/gs/builtin/type.js +49 -0
  23. package/dist/gs/builtin/type.js.map +1 -1
  24. package/dist/gs/compress/zlib/index.js +5 -2
  25. package/dist/gs/compress/zlib/index.js.map +1 -1
  26. package/dist/gs/crypto/ecdh/index.js +27 -8
  27. package/dist/gs/crypto/ecdh/index.js.map +1 -1
  28. package/dist/gs/crypto/ed25519/index.js +3 -3
  29. package/dist/gs/crypto/ed25519/index.js.map +1 -1
  30. package/dist/gs/crypto/rand/index.js +6 -3
  31. package/dist/gs/crypto/rand/index.js.map +1 -1
  32. package/dist/gs/embed/index.js +9 -3
  33. package/dist/gs/embed/index.js.map +1 -1
  34. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +1 -0
  35. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +33 -0
  36. package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
  37. package/dist/gs/github.com/mr-tron/base58/base58/index.js +4 -1
  38. package/dist/gs/github.com/mr-tron/base58/base58/index.js.map +1 -1
  39. package/dist/gs/golang.org/x/crypto/scrypt/index.d.ts +2 -0
  40. package/dist/gs/golang.org/x/crypto/scrypt/index.js +39 -0
  41. package/dist/gs/golang.org/x/crypto/scrypt/index.js.map +1 -0
  42. package/dist/gs/hash/fnv/index.js +13 -5
  43. package/dist/gs/hash/fnv/index.js.map +1 -1
  44. package/dist/gs/io/fs/glob.d.ts +3 -3
  45. package/dist/gs/io/fs/glob.js +8 -8
  46. package/dist/gs/io/fs/glob.js.map +1 -1
  47. package/dist/gs/io/fs/readdir.d.ts +2 -2
  48. package/dist/gs/io/fs/readdir.js +13 -74
  49. package/dist/gs/io/fs/readdir.js.map +1 -1
  50. package/dist/gs/io/fs/sub.js +4 -4
  51. package/dist/gs/io/fs/sub.js.map +1 -1
  52. package/dist/gs/io/fs/walk.js +1 -1
  53. package/dist/gs/io/fs/walk.js.map +1 -1
  54. package/dist/gs/maps/iter.js.map +1 -1
  55. package/dist/gs/maps/maps.js.map +1 -1
  56. package/dist/gs/mime/index.js +5 -2
  57. package/dist/gs/mime/index.js.map +1 -1
  58. package/dist/gs/net/http/httptest/index.js +6 -3
  59. package/dist/gs/net/http/httptest/index.js.map +1 -1
  60. package/dist/gs/net/http/index.d.ts +16 -4
  61. package/dist/gs/net/http/index.js +236 -40
  62. package/dist/gs/net/http/index.js.map +1 -1
  63. package/dist/gs/net/http/pprof/index.js.map +1 -1
  64. package/dist/gs/reflect/iter.js +1 -1
  65. package/dist/gs/reflect/iter.js.map +1 -1
  66. package/dist/gs/reflect/type.d.ts +2 -0
  67. package/dist/gs/reflect/type.js +53 -21
  68. package/dist/gs/reflect/type.js.map +1 -1
  69. package/dist/gs/runtime/pprof/index.js.map +1 -1
  70. package/dist/gs/runtime/runtime.js +2 -2
  71. package/dist/gs/runtime/runtime.js.map +1 -1
  72. package/dist/gs/runtime/trace/index.js.map +1 -1
  73. package/dist/gs/slices/slices.d.ts +1 -1
  74. package/dist/gs/slices/slices.js +37 -4
  75. package/dist/gs/slices/slices.js.map +1 -1
  76. package/gs/builtin/builtin.ts +11 -14
  77. package/gs/builtin/defer.ts +2 -2
  78. package/gs/builtin/hostio.ts +5 -5
  79. package/gs/builtin/map.ts +4 -1
  80. package/gs/builtin/slice.test.ts +14 -0
  81. package/gs/builtin/slice.ts +64 -0
  82. package/gs/builtin/type.ts +72 -0
  83. package/gs/bytes/bytes.test.ts +14 -13
  84. package/gs/compress/zlib/index.test.ts +19 -5
  85. package/gs/compress/zlib/index.ts +16 -7
  86. package/gs/context/context.test.ts +3 -1
  87. package/gs/crypto/ecdh/index.test.ts +6 -2
  88. package/gs/crypto/ecdh/index.ts +49 -12
  89. package/gs/crypto/ed25519/index.ts +20 -7
  90. package/gs/crypto/rand/index.ts +6 -3
  91. package/gs/embed/index.test.ts +3 -3
  92. package/gs/embed/index.ts +9 -3
  93. package/gs/fmt/fmt.test.ts +29 -4
  94. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +126 -0
  95. package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +46 -0
  96. package/gs/github.com/mr-tron/base58/base58/index.ts +9 -3
  97. package/gs/github.com/zeebo/blake3/internal/consts/index.test.ts +2 -8
  98. package/gs/golang.org/x/crypto/scrypt/index.test.ts +81 -0
  99. package/gs/golang.org/x/crypto/scrypt/index.ts +54 -0
  100. package/gs/golang.org/x/crypto/scrypt/meta.json +5 -0
  101. package/gs/hash/fnv/index.test.ts +1 -8
  102. package/gs/hash/fnv/index.ts +27 -10
  103. package/gs/io/fs/glob.ts +13 -10
  104. package/gs/io/fs/meta.json +2 -0
  105. package/gs/io/fs/readdir.test.ts +63 -2
  106. package/gs/io/fs/readdir.ts +33 -30
  107. package/gs/io/fs/sub.ts +4 -4
  108. package/gs/io/fs/walk.ts +1 -1
  109. package/gs/maps/iter.ts +9 -9
  110. package/gs/maps/maps.ts +4 -4
  111. package/gs/math/bits/index.test.ts +10 -1
  112. package/gs/mime/index.test.ts +33 -15
  113. package/gs/mime/index.ts +9 -2
  114. package/gs/net/http/httptest/index.test.ts +17 -3
  115. package/gs/net/http/httptest/index.ts +8 -3
  116. package/gs/net/http/index.test.ts +645 -123
  117. package/gs/net/http/index.ts +548 -113
  118. package/gs/net/http/pprof/index.ts +24 -6
  119. package/gs/os/file_unix_js.test.ts +22 -0
  120. package/gs/reflect/iter.ts +4 -2
  121. package/gs/reflect/map.test.ts +56 -1
  122. package/gs/reflect/type.ts +76 -37
  123. package/gs/runtime/pprof/index.test.ts +7 -1
  124. package/gs/runtime/pprof/index.ts +5 -1
  125. package/gs/runtime/runtime.test.ts +7 -0
  126. package/gs/runtime/runtime.ts +2 -4
  127. package/gs/runtime/trace/index.test.ts +9 -1
  128. package/gs/runtime/trace/index.ts +5 -1
  129. package/gs/slices/meta.json +3 -0
  130. package/gs/slices/slices.test.ts +59 -21
  131. package/gs/slices/slices.ts +61 -20
  132. package/gs/strconv/complex.test.ts +17 -3
  133. package/gs/sync/atomic/doc_64.test.ts +2 -9
  134. package/gs/sync/sync.test.ts +18 -8
  135. package/gs/syscall/js/index.test.ts +9 -4
  136. package/package.json +5 -4
@@ -0,0 +1,54 @@
1
+ import * as $ from '@goscript/builtin/index.js'
2
+ import * as errors from '@goscript/errors/index.js'
3
+ import { scryptAsync } from '@noble/hashes/scrypt.js'
4
+
5
+ const maxInt = Number.MAX_SAFE_INTEGER
6
+
7
+ export async function Key(
8
+ password: $.Bytes,
9
+ salt: $.Bytes,
10
+ N: number,
11
+ r: number,
12
+ p: number,
13
+ keyLen: number,
14
+ ): Promise<[$.Bytes, $.GoError]> {
15
+ if (N <= 1 || (N & (N - 1)) !== 0) {
16
+ return [null, errors.New('scrypt: N must be > 1 and a power of 2')]
17
+ }
18
+ if (r <= 0 || p <= 0) {
19
+ return [null, errors.New('scrypt: parameters must be > 0')]
20
+ }
21
+ if (
22
+ r * p >= 1 << 30 ||
23
+ r > maxInt / 128 / p ||
24
+ r > maxInt / 256 ||
25
+ N > maxInt / 128 / r
26
+ ) {
27
+ return [null, errors.New('scrypt: parameters are too large')]
28
+ }
29
+
30
+ try {
31
+ const derived = await scryptAsync(
32
+ $.bytesToUint8Array(password),
33
+ $.bytesToUint8Array(salt),
34
+ {
35
+ N,
36
+ r,
37
+ p,
38
+ dkLen: keyLen,
39
+ asyncTick: 8,
40
+ maxmem: maxInt,
41
+ },
42
+ )
43
+ return [new Uint8Array(derived), null]
44
+ } catch (err) {
45
+ return [null, errors.New(`scrypt: ${errorMessage(err)}`)]
46
+ }
47
+ }
48
+
49
+ function errorMessage(err: unknown): string {
50
+ if (err instanceof Error) {
51
+ return err.message
52
+ }
53
+ return String(err)
54
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "asyncFunctions": {
3
+ "Key": true
4
+ }
5
+ }
@@ -1,14 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest'
2
2
 
3
3
  import * as $ from '../../builtin/index.js'
4
- import {
5
- New128,
6
- New128a,
7
- New32,
8
- New32a,
9
- New64,
10
- New64a,
11
- } from './index.js'
4
+ import { New128, New128a, New32, New32a, New64, New64a } from './index.js'
12
5
 
13
6
  describe('hash/fnv override', () => {
14
7
  it('matches Go FNV sums for hello', async () => {
@@ -65,7 +65,10 @@ class FNV32 {
65
65
  }
66
66
 
67
67
  AppendBinary(prefix: $.Bytes | null): [$.Bytes, $.GoError] {
68
- return [appendBytes($.bytesToUint8Array(prefix), this.magic, be32(this.hash)), null]
68
+ return [
69
+ appendBytes($.bytesToUint8Array(prefix), this.magic, be32(this.hash)),
70
+ null,
71
+ ]
69
72
  }
70
73
 
71
74
  MarshalBinary(): [$.Bytes, $.GoError] {
@@ -136,7 +139,10 @@ class FNV64 {
136
139
  }
137
140
 
138
141
  AppendBinary(prefix: $.Bytes | null): [$.Bytes, $.GoError] {
139
- return [appendBytes($.bytesToUint8Array(prefix), this.magic, be64(this.hash)), null]
142
+ return [
143
+ appendBytes($.bytesToUint8Array(prefix), this.magic, be64(this.hash)),
144
+ null,
145
+ ]
140
146
  }
141
147
 
142
148
  MarshalBinary(): [$.Bytes, $.GoError] {
@@ -185,7 +191,11 @@ class FNV128 {
185
191
  }
186
192
 
187
193
  async Sum(prefix: $.Bytes | null): Promise<$.Bytes> {
188
- return appendBytes($.bytesToUint8Array(prefix), be64(this.high()), be64(this.low()))
194
+ return appendBytes(
195
+ $.bytesToUint8Array(prefix),
196
+ be64(this.high()),
197
+ be64(this.low()),
198
+ )
189
199
  }
190
200
 
191
201
  Reset(): void {
@@ -202,7 +212,12 @@ class FNV128 {
202
212
 
203
213
  AppendBinary(prefix: $.Bytes | null): [$.Bytes, $.GoError] {
204
214
  return [
205
- appendBytes($.bytesToUint8Array(prefix), this.magic, be64(this.high()), be64(this.low())),
215
+ appendBytes(
216
+ $.bytesToUint8Array(prefix),
217
+ this.magic,
218
+ be64(this.high()),
219
+ be64(this.low()),
220
+ ),
206
221
  null,
207
222
  ]
208
223
  }
@@ -217,7 +232,8 @@ class FNV128 {
217
232
  if (err != null) {
218
233
  return err
219
234
  }
220
- this.hash = ((readBE64(state, 4) << 64n) | readBE64(state, 12)) & uint128Mask
235
+ this.hash =
236
+ ((readBE64(state, 4) << 64n) | readBE64(state, 12)) & uint128Mask
221
237
  return null
222
238
  }
223
239
 
@@ -304,11 +320,12 @@ function be64(value: bigint): Uint8Array {
304
320
 
305
321
  function readBE32(bytes: Uint8Array, offset: number): number {
306
322
  return (
307
- ((bytes[offset] << 24) >>> 0) |
308
- (bytes[offset + 1] << 16) |
309
- (bytes[offset + 2] << 8) |
310
- bytes[offset + 3]
311
- ) >>> 0
323
+ (((bytes[offset] << 24) >>> 0) |
324
+ (bytes[offset + 1] << 16) |
325
+ (bytes[offset + 2] << 8) |
326
+ bytes[offset + 3]) >>>
327
+ 0
328
+ )
312
329
  }
313
330
 
314
331
  function readBE64(bytes: Uint8Array, offset: number): bigint {
package/gs/io/fs/glob.ts CHANGED
@@ -60,15 +60,18 @@ $.registerInterfaceType(
60
60
  // If fs implements [GlobFS], Glob calls fs.Glob.
61
61
  // Otherwise, Glob uses [ReadDir] to traverse the directory tree
62
62
  // and look for matches for the pattern.
63
- export function Glob(fsys: FS, pattern: string): [$.Slice<string>, $.GoError] {
64
- return globWithLimit(fsys, pattern, 0)
63
+ export async function Glob(
64
+ fsys: FS,
65
+ pattern: string,
66
+ ): Promise<[$.Slice<string>, $.GoError]> {
67
+ return await globWithLimit(fsys, pattern, 0)
65
68
  }
66
69
 
67
- export function globWithLimit(
70
+ export async function globWithLimit(
68
71
  fsys: FS,
69
72
  pattern: string,
70
73
  depth: number,
71
- ): [$.Slice<string>, $.GoError] {
74
+ ): Promise<[$.Slice<string>, $.GoError]> {
72
75
  let matches: $.Slice<string> = null
73
76
  {
74
77
  // This limit is added to prevent stack exhaustion issues. See
@@ -105,7 +108,7 @@ export function globWithLimit(
105
108
  dir = cleanGlobPath(dir)
106
109
 
107
110
  if (!hasMeta(dir)) {
108
- return glob(fsys, dir, file, null)
111
+ return await glob(fsys, dir, file, null)
109
112
  }
110
113
 
111
114
  // Prevent infinite recursion. See issue 15879.
@@ -113,14 +116,14 @@ export function globWithLimit(
113
116
  return [null, path.ErrBadPattern]
114
117
  }
115
118
 
116
- const [dirs, dirErr] = globWithLimit(fsys, dir, depth + 1)
119
+ const [dirs, dirErr] = await globWithLimit(fsys, dir, depth + 1)
117
120
  if (dirErr != null) {
118
121
  return [null, dirErr]
119
122
  }
120
123
  for (let _i = 0; _i < $.len(dirs); _i++) {
121
124
  const d = dirs![_i]
122
125
  {
123
- const [nextMatches, globErr] = glob(fsys, d, file, matches)
126
+ const [nextMatches, globErr] = await glob(fsys, d, file, matches)
124
127
  matches = nextMatches
125
128
  if (globErr != null) {
126
129
  return [matches, globErr]
@@ -148,15 +151,15 @@ export function cleanGlobPath(path: string): string {
148
151
  // and appends them to matches, returning the updated slice.
149
152
  // If the directory cannot be opened, glob returns the existing matches.
150
153
  // New matches are added in lexicographical order.
151
- export function glob(
154
+ export async function glob(
152
155
  fs: FS,
153
156
  dir: string,
154
157
  pattern: string,
155
158
  matches: $.Slice<string>,
156
- ): [$.Slice<string>, $.GoError] {
159
+ ): Promise<[$.Slice<string>, $.GoError]> {
157
160
  let m = matches
158
161
  {
159
- let [infos, err] = ReadDir(fs, dir)
162
+ let [infos, err] = await ReadDir(fs, dir)
160
163
 
161
164
  // ignore I/O error
162
165
  if (err != null) {
@@ -1,5 +1,7 @@
1
1
  {
2
2
  "asyncFunctions": {
3
+ "Glob": true,
4
+ "ReadDir": true,
3
5
  "WalkDir": true
4
6
  }
5
7
  }
@@ -4,7 +4,7 @@ import * as $ from '@goscript/builtin/index.js'
4
4
  import { File, FileInfo, ReadDir } from './index.js'
5
5
 
6
6
  describe('io/fs ReadDir override', () => {
7
- it('returns a nil entry slice without sorting when directory read fails', () => {
7
+ it('returns a nil entry slice without sorting when directory read fails', async () => {
8
8
  const readErr = $.newError('read failed')
9
9
  const file: File & {
10
10
  ReadDir(n: number): [null, $.GoError]
@@ -23,7 +23,7 @@ describe('io/fs ReadDir override', () => {
23
23
  },
24
24
  }
25
25
 
26
- const [list, err] = ReadDir(
26
+ const [list, err] = await ReadDir(
27
27
  {
28
28
  Open(_name: string): [File, $.GoError] {
29
29
  return [file, null]
@@ -35,4 +35,65 @@ describe('io/fs ReadDir override', () => {
35
35
  expect(list).toBeNull()
36
36
  expect(err).toBe(readErr)
37
37
  })
38
+
39
+ it('awaits async FS.Open fallback implementations', async () => {
40
+ const entries = [
41
+ {
42
+ Name(): string {
43
+ return 'b.txt'
44
+ },
45
+ IsDir(): boolean {
46
+ return false
47
+ },
48
+ Info(): [FileInfo, $.GoError] {
49
+ return [null, null]
50
+ },
51
+ Type(): number {
52
+ return 0
53
+ },
54
+ },
55
+ {
56
+ Name(): string {
57
+ return 'a.txt'
58
+ },
59
+ IsDir(): boolean {
60
+ return false
61
+ },
62
+ Info(): [FileInfo, $.GoError] {
63
+ return [null, null]
64
+ },
65
+ Type(): number {
66
+ return 0
67
+ },
68
+ },
69
+ ]
70
+ const file: File & {
71
+ ReadDir(n: number): Promise<[$.Slice<any>, $.GoError]>
72
+ } = {
73
+ Close(): $.GoError {
74
+ return null
75
+ },
76
+ Read(_p0: Uint8Array): [number, $.GoError] {
77
+ return [0, null]
78
+ },
79
+ Stat(): [FileInfo, $.GoError] {
80
+ return [null, null]
81
+ },
82
+ async ReadDir(_n: number): Promise<[$.Slice<any>, $.GoError]> {
83
+ return [$.arrayToSlice(entries), null]
84
+ },
85
+ }
86
+
87
+ const [list, err] = await ReadDir(
88
+ {
89
+ async Open(_name: string): Promise<[File, $.GoError]> {
90
+ return [file, null]
91
+ },
92
+ },
93
+ 'dir',
94
+ )
95
+
96
+ expect(err).toBeNull()
97
+ expect(list?.map((entry) => entry?.Name())).toEqual(['a.txt', 'b.txt'])
98
+ })
38
99
  })
@@ -17,7 +17,11 @@ export type ReadDirFS =
17
17
  | ({
18
18
  // ReadDir reads the named directory
19
19
  // and returns a list of directory entries sorted by filename.
20
- ReadDir(name: string): [$.Slice<DirEntry>, $.GoError]
20
+ ReadDir(
21
+ name: string,
22
+ ):
23
+ | [$.Slice<DirEntry>, $.GoError]
24
+ | Promise<[$.Slice<DirEntry>, $.GoError]>
21
25
  } & FS)
22
26
 
23
27
  $.registerInterfaceType(
@@ -55,51 +59,50 @@ $.registerInterfaceType(
55
59
  // If fs implements [ReadDirFS], ReadDir calls fs.ReadDir.
56
60
  // Otherwise ReadDir calls fs.Open and uses ReadDir and Close
57
61
  // on the returned file.
58
- export function ReadDir(
62
+ export async function ReadDir(
59
63
  fsys: FS,
60
64
  name: string,
61
- ): [$.Slice<DirEntry>, $.GoError] {
62
- using __defer = new $.DisposableStack()
65
+ ): Promise<[$.Slice<DirEntry>, $.GoError]> {
63
66
  {
64
67
  let { value: fsysTyped, ok: ok } = $.typeAssert<ReadDirFS>(
65
68
  fsys,
66
69
  'ReadDirFS',
67
70
  )
68
71
  if (ok) {
69
- return fsysTyped!.ReadDir(name)
72
+ return await fsysTyped!.ReadDir(name)
70
73
  }
71
74
  }
72
75
 
73
- let [file, err] = fsys!.Open(name)
76
+ let [file, err] = await fsys!.Open(name)
74
77
  if (err != null) {
75
78
  return [null, err]
76
79
  }
77
- __defer.defer(() => {
78
- file!.Close()
79
- })
80
-
81
- let { value: dir, ok: ok } = $.typeAssert<ReadDirFile>(file, 'ReadDirFile')
82
- if (!ok) {
83
- return [
84
- null,
85
- new PathError({
86
- Err: errors.New('not implemented'),
87
- Op: 'readdir',
88
- Path: name,
89
- }),
90
- ]
91
- }
80
+ try {
81
+ let { value: dir, ok: ok } = $.typeAssert<ReadDirFile>(file, 'ReadDirFile')
82
+ if (!ok) {
83
+ return [
84
+ null,
85
+ new PathError({
86
+ Err: errors.New('not implemented'),
87
+ Op: 'readdir',
88
+ Path: name,
89
+ }),
90
+ ]
91
+ }
92
92
 
93
- let list: $.Slice<DirEntry>
94
- ;[list, err] = dir!.ReadDir(-1)
95
- if (list) {
96
- list.sort((a: DirEntry, b: DirEntry): number => {
97
- return $.pointerValue<Exclude<DirEntry, null>>(a)
98
- .Name()
99
- .localeCompare($.pointerValue<Exclude<DirEntry, null>>(b).Name())
100
- })
93
+ let list: $.Slice<DirEntry>
94
+ ;[list, err] = await dir!.ReadDir(-1)
95
+ if (list) {
96
+ list.sort((a: DirEntry, b: DirEntry): number => {
97
+ return $.pointerValue<Exclude<DirEntry, null>>(a)
98
+ .Name()
99
+ .localeCompare($.pointerValue<Exclude<DirEntry, null>>(b).Name())
100
+ })
101
+ }
102
+ return [list, err]
103
+ } finally {
104
+ await file!.Close()
101
105
  }
102
- return [list, err]
103
106
  }
104
107
 
105
108
  class dirInfo {
package/gs/io/fs/sub.ts CHANGED
@@ -164,14 +164,14 @@ class subFS {
164
164
  return [file, f!.fixErr(err)]
165
165
  }
166
166
 
167
- public ReadDir(name: string): [$.Slice<DirEntry>, $.GoError] {
167
+ public async ReadDir(name: string): Promise<[$.Slice<DirEntry>, $.GoError]> {
168
168
  const f = this
169
169
  let [full, err] = f!.fullName('read', name)
170
170
  if (err != null) {
171
171
  return [null, err]
172
172
  }
173
173
  let dir: $.Slice<DirEntry>
174
- ;[dir, err] = ReadDir(f!.fsys, full)
174
+ ;[dir, err] = await ReadDir(f!.fsys, full)
175
175
  return [dir, f!.fixErr(err)]
176
176
  }
177
177
 
@@ -186,7 +186,7 @@ class subFS {
186
186
  return [data, f!.fixErr(err)]
187
187
  }
188
188
 
189
- public Glob(pattern: string): [$.Slice<string>, $.GoError] {
189
+ public async Glob(pattern: string): Promise<[$.Slice<string>, $.GoError]> {
190
190
  const f = this
191
191
  {
192
192
  let [, err] = path.Match(pattern, '')
@@ -198,7 +198,7 @@ class subFS {
198
198
  return [$.arrayToSlice<string>(['.']), null]
199
199
  }
200
200
  let full = f!.dir + '/' + pattern
201
- let [list, err] = Glob(f!.fsys, full)
201
+ let [list, err] = await Glob(f!.fsys, full)
202
202
  for (let i = 0; i < $.len(list); i++) {
203
203
  const name = list![i]
204
204
  {
package/gs/io/fs/walk.ts CHANGED
@@ -39,7 +39,7 @@ export async function walkDir(
39
39
  }
40
40
  }
41
41
 
42
- let [dirs, err] = ReadDir(fsys, name)
42
+ let [dirs, err] = await ReadDir(fsys, name)
43
43
 
44
44
  // Second call, to report ReadDir error.
45
45
  if (err != null) {
package/gs/maps/iter.ts CHANGED
@@ -8,9 +8,9 @@ import * as iter from '@goscript/iter/index.js'
8
8
  export function All<K extends $.Comparable | null, V>(
9
9
  m: Map<K, V> | null,
10
10
  ): iter.Seq2<K, V> {
11
- return (_yield: ((p0: K, p1: V) => iter.YieldResult) | null):
12
- | void
13
- | globalThis.Promise<void> => iteratePairs(m?.entries() ?? [], _yield)
11
+ return (
12
+ _yield: ((p0: K, p1: V) => iter.YieldResult) | null,
13
+ ): void | globalThis.Promise<void> => iteratePairs(m?.entries() ?? [], _yield)
14
14
  }
15
15
 
16
16
  // Keys returns an iterator over keys in m.
@@ -19,9 +19,9 @@ export function All<K extends $.Comparable | null, V>(
19
19
  export function Keys<K extends $.Comparable | null, V>(
20
20
  m: Map<K, V> | null,
21
21
  ): iter.Seq<K> {
22
- return (_yield: ((p0: K) => iter.YieldResult) | null):
23
- | void
24
- | globalThis.Promise<void> => iterateValues(mapKeys(m), _yield)
22
+ return (
23
+ _yield: ((p0: K) => iter.YieldResult) | null,
24
+ ): void | globalThis.Promise<void> => iterateValues(mapKeys(m), _yield)
25
25
  }
26
26
 
27
27
  // Values returns an iterator over values in m.
@@ -30,9 +30,9 @@ export function Keys<K extends $.Comparable | null, V>(
30
30
  export function Values<K extends $.Comparable | null, V>(
31
31
  m: Map<K, V> | null,
32
32
  ): iter.Seq<V> {
33
- return (_yield: ((p0: V) => iter.YieldResult) | null):
34
- | void
35
- | globalThis.Promise<void> => iterateValues(mapValues(m), _yield)
33
+ return (
34
+ _yield: ((p0: V) => iter.YieldResult) | null,
35
+ ): void | globalThis.Promise<void> => iterateValues(mapValues(m), _yield)
36
36
  }
37
37
 
38
38
  // Insert adds the key-value pairs from seq to m.
package/gs/maps/maps.ts CHANGED
@@ -4,10 +4,10 @@ import * as _ from '@goscript/unsafe/index.js'
4
4
 
5
5
  // Equal reports whether two maps contain the same key/value pairs.
6
6
  // Values are compared using ==.
7
- export function Equal<K extends $.Comparable | null, V extends $.Comparable | null>(
8
- m1: Map<K, V>,
9
- m2: Map<K, V>,
10
- ): boolean {
7
+ export function Equal<
8
+ K extends $.Comparable | null,
9
+ V extends $.Comparable | null,
10
+ >(m1: Map<K, V>, m2: Map<K, V>): boolean {
11
11
  if ($.len(m1) != $.len(m2)) {
12
12
  return false
13
13
  }
@@ -1,6 +1,15 @@
1
1
  import { describe, expect, it } from 'vitest'
2
2
 
3
- import { Mul64, Rem, Rem32, Rem64, RotateLeft16, RotateLeft32, RotateLeft64, RotateLeft8 } from './index.js'
3
+ import {
4
+ Mul64,
5
+ Rem,
6
+ Rem32,
7
+ Rem64,
8
+ RotateLeft16,
9
+ RotateLeft32,
10
+ RotateLeft64,
11
+ RotateLeft8,
12
+ } from './index.js'
4
13
 
5
14
  describe('math/bits override', () => {
6
15
  it('returns the full 128-bit product from Mul64', () => {
@@ -22,14 +22,15 @@ describe('mime override', () => {
22
22
  expect(mediaType).toBe('text/plain')
23
23
  expect(params.get('charset')).toBe('utf-8')
24
24
  expect(params.get('format')).toBe('flowed')
25
- const [trailingMediaType, trailingParams, trailingErr] = ParseMediaType('text/plain;')
25
+ const [trailingMediaType, trailingParams, trailingErr] =
26
+ ParseMediaType('text/plain;')
26
27
  expect(trailingErr).toBeNull()
27
28
  expect(trailingMediaType).toBe('text/plain')
28
29
  expect(trailingParams.size).toBe(0)
29
30
 
30
- expect(
31
- FormatMediaType('text/plain', new Map([['charset', 'utf-8']])),
32
- ).toBe('text/plain; charset=utf-8')
31
+ expect(FormatMediaType('text/plain', new Map([['charset', 'utf-8']]))).toBe(
32
+ 'text/plain; charset=utf-8',
33
+ )
33
34
  expect(
34
35
  FormatMediaType('Attachment', new Map([['FileName', 'hello.txt']])),
35
36
  ).toBe('attachment; filename=hello.txt')
@@ -37,10 +38,13 @@ describe('mime override', () => {
37
38
  FormatMediaType('attachment', new Map([['filename', 'foo bar.txt']])),
38
39
  ).toBe('attachment; filename="foo bar.txt"')
39
40
  expect(
40
- FormatMediaType('text/plain', new Map([
41
- ['z', 'last'],
42
- ['a', 'first'],
43
- ])),
41
+ FormatMediaType(
42
+ 'text/plain',
43
+ new Map([
44
+ ['z', 'last'],
45
+ ['a', 'first'],
46
+ ]),
47
+ ),
44
48
  ).toBe('text/plain; a=first; z=last')
45
49
 
46
50
  const encoded = FormatMediaType(
@@ -51,13 +55,17 @@ describe('mime override', () => {
51
55
  const [, encodedParams, encodedErr] = ParseMediaType(encoded)
52
56
  expect(encodedErr).toBeNull()
53
57
  expect(encodedParams.get('filename')).toBe('résumé.txt')
54
- const [, pathParams, pathErr] = ParseMediaType('form-data; filename="C:\\dev\\go.txt"; quoted="a\\"b"')
58
+ const [, pathParams, pathErr] = ParseMediaType(
59
+ 'form-data; filename="C:\\dev\\go.txt"; quoted="a\\"b"',
60
+ )
55
61
  expect(pathErr).toBeNull()
56
62
  expect(pathParams.get('filename')).toBe('C:\\dev\\go.txt')
57
63
  expect(pathParams.get('quoted')).toBe('a"b')
58
64
 
59
65
  expect(TypeByExtension('.json')).toBe('application/json')
60
- expect(AddExtensionType('.goscript', 'text/plain; charset=utf-8')).toBeNull()
66
+ expect(
67
+ AddExtensionType('.goscript', 'text/plain; charset=utf-8'),
68
+ ).toBeNull()
61
69
  const [extensions, extensionErr] = ExtensionsByType('text/plain')
62
70
  expect(extensionErr).toBeNull()
63
71
  expect(extensions).toContain('.goscript')
@@ -66,10 +74,18 @@ describe('mime override', () => {
66
74
  it('reports invalid media parameters', () => {
67
75
  const [, , err] = ParseMediaType('text/plain; broken')
68
76
  expect(err).toBe(ErrInvalidMediaParameter)
69
- expect(ParseMediaType('text/plain; filename=foo bar')[2]).toBe(ErrInvalidMediaParameter)
70
- expect(ParseMediaType('text/plain; filename="unterminated')[2]).toBe(ErrInvalidMediaParameter)
71
- expect(ParseMediaType('text/plain; x=1; x=2')[2]).toBe(ErrInvalidMediaParameter)
72
- expect(ParseMediaType('text/plain; bad[]=x')[2]).toBe(ErrInvalidMediaParameter)
77
+ expect(ParseMediaType('text/plain; filename=foo bar')[2]).toBe(
78
+ ErrInvalidMediaParameter,
79
+ )
80
+ expect(ParseMediaType('text/plain; filename="unterminated')[2]).toBe(
81
+ ErrInvalidMediaParameter,
82
+ )
83
+ expect(ParseMediaType('text/plain; x=1; x=2')[2]).toBe(
84
+ ErrInvalidMediaParameter,
85
+ )
86
+ expect(ParseMediaType('text/plain; bad[]=x')[2]).toBe(
87
+ ErrInvalidMediaParameter,
88
+ )
73
89
  expect(ParseMediaType('text/plain; bad{}=x')[1].get('bad{}')).toBe('x')
74
90
  })
75
91
 
@@ -83,7 +99,9 @@ describe('mime override', () => {
83
99
  expect(qWord).toBe('hello world')
84
100
 
85
101
  const encodedQWord = WordEncoder_Encode(QEncoding, 'utf-8', 'héllo world')
86
- const [header, err] = new WordDecoder().DecodeHeader(`subject ${encodedQWord}`)
102
+ const [header, err] = new WordDecoder().DecodeHeader(
103
+ `subject ${encodedQWord}`,
104
+ )
87
105
  expect(err).toBeNull()
88
106
  expect(header).toBe('subject héllo world')
89
107
  })
package/gs/mime/index.ts CHANGED
@@ -52,7 +52,11 @@ export function FormatMediaType(
52
52
  param instanceof Map ?
53
53
  Array.from(param.entries())
54
54
  : Object.entries(param ?? {})
55
- entries.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
55
+ entries.sort(([a], [b]) =>
56
+ a < b ? -1
57
+ : a > b ? 1
58
+ : 0,
59
+ )
56
60
  for (const [key, value] of entries) {
57
61
  if (!isToken(key)) {
58
62
  return ''
@@ -92,7 +96,10 @@ export function ParseMediaType(
92
96
  if (key.endsWith('*')) {
93
97
  const decoded = decode2231Value(value)
94
98
  if (decoded !== null) {
95
- if (params.has(key.slice(0, -1)) && params.get(key.slice(0, -1)) !== decoded) {
99
+ if (
100
+ params.has(key.slice(0, -1)) &&
101
+ params.get(key.slice(0, -1)) !== decoded
102
+ ) {
96
103
  return ['', new Map(), ErrInvalidMediaParameter]
97
104
  }
98
105
  params.set(key.slice(0, -1), decoded)