goscript 0.0.50 → 0.0.52

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 (63) hide show
  1. package/compiler/analysis.go +513 -325
  2. package/compiler/compiler.go +39 -6
  3. package/compiler/expr-call-async.go +90 -23
  4. package/compiler/expr.go +0 -44
  5. package/compiler/sanitize.go +1 -2
  6. package/compiler/spec-struct.go +3 -3
  7. package/compiler/spec.go +0 -21
  8. package/compiler/stmt-assign.go +0 -6
  9. package/compiler/stmt-select.go +52 -1
  10. package/compiler/type-assert.go +6 -6
  11. package/compiler/type.go +3 -3
  12. package/dist/gs/builtin/builtin.d.ts +0 -1
  13. package/dist/gs/builtin/builtin.js +0 -9
  14. package/dist/gs/builtin/builtin.js.map +1 -1
  15. package/dist/gs/builtin/channel.d.ts +5 -3
  16. package/dist/gs/builtin/channel.js +14 -17
  17. package/dist/gs/builtin/channel.js.map +1 -1
  18. package/dist/gs/context/context.js +2 -2
  19. package/dist/gs/context/context.js.map +1 -1
  20. package/dist/gs/runtime/runtime.d.ts +1 -1
  21. package/dist/gs/runtime/runtime.js +1 -1
  22. package/dist/gs/syscall/constants.d.ts +24 -0
  23. package/dist/gs/syscall/constants.js +27 -0
  24. package/dist/gs/syscall/constants.js.map +1 -0
  25. package/dist/gs/syscall/env.d.ts +6 -0
  26. package/dist/gs/syscall/env.js +43 -0
  27. package/dist/gs/syscall/env.js.map +1 -0
  28. package/dist/gs/syscall/errors.d.ts +111 -0
  29. package/dist/gs/syscall/errors.js +547 -0
  30. package/dist/gs/syscall/errors.js.map +1 -0
  31. package/dist/gs/syscall/fs.d.ts +29 -0
  32. package/dist/gs/syscall/fs.js +53 -0
  33. package/dist/gs/syscall/fs.js.map +1 -0
  34. package/dist/gs/syscall/index.d.ts +6 -80
  35. package/dist/gs/syscall/index.js +12 -168
  36. package/dist/gs/syscall/index.js.map +1 -1
  37. package/dist/gs/syscall/rawconn.d.ts +7 -0
  38. package/dist/gs/syscall/rawconn.js +19 -0
  39. package/dist/gs/syscall/rawconn.js.map +1 -0
  40. package/dist/gs/syscall/types.d.ts +12 -0
  41. package/dist/gs/syscall/types.js +2 -0
  42. package/dist/gs/syscall/types.js.map +1 -0
  43. package/dist/gs/time/time.d.ts +2 -2
  44. package/dist/gs/time/time.js +12 -9
  45. package/dist/gs/time/time.js.map +1 -1
  46. package/go.mod +1 -1
  47. package/gs/builtin/builtin.ts +0 -11
  48. package/gs/builtin/channel.ts +39 -17
  49. package/gs/context/context.ts +6 -2
  50. package/gs/context/meta.json +16 -0
  51. package/gs/runtime/runtime.ts +1 -1
  52. package/gs/syscall/constants.ts +29 -0
  53. package/gs/syscall/env.ts +47 -0
  54. package/gs/syscall/errors.ts +658 -0
  55. package/gs/syscall/fs.ts +62 -0
  56. package/gs/syscall/index.ts +12 -207
  57. package/gs/syscall/rawconn.ts +23 -0
  58. package/gs/syscall/types.ts +18 -0
  59. package/gs/time/meta.json +6 -0
  60. package/gs/time/time.ts +16 -13
  61. package/gs/unicode/meta.json +24 -0
  62. package/package.json +1 -1
  63. package/gs/unicode/unicode.go +0 -38
@@ -88,7 +88,7 @@ export interface SelectCase<T> {
88
88
  channel: Channel<any> | ChannelRef<any> | null // Allow null and ChannelRef
89
89
  value?: any // Value to send for send cases
90
90
  // Optional handlers for when this case is selected
91
- onSelected?: (result: SelectResult<T>) => Promise<void>
91
+ onSelected?: (result: SelectResult<T>) => Promise<any>
92
92
  }
93
93
 
94
94
  /**
@@ -99,14 +99,14 @@ export interface SelectCase<T> {
99
99
  * @param hasDefault Whether there is a default case
100
100
  * @returns A promise that resolves with the result of the selected case
101
101
  */
102
- export async function selectStatement<T>(
102
+ export async function selectStatement<T, V = void>(
103
103
  cases: SelectCase<T>[],
104
104
  hasDefault: boolean = false,
105
- ): Promise<void> {
105
+ ): Promise<[boolean, V]> {
106
106
  if (cases.length === 0 && !hasDefault) {
107
107
  // Go spec: If there are no cases, the select statement blocks forever.
108
108
  // Emulate blocking forever with a promise that never resolves.
109
- return new Promise<void>(() => {}) // Promise never resolves
109
+ return new Promise<[boolean, V]>(() => {}) // Promise never resolves
110
110
  }
111
111
 
112
112
  // 1. Check for ready (non-blocking) operations
@@ -143,19 +143,23 @@ export async function selectStatement<T>(
143
143
  selectedCase.id,
144
144
  )
145
145
  if (selectedCase.onSelected) {
146
- await selectedCase.onSelected(result as SelectResult<T>) // Await the handler
146
+ const handlerResult = await selectedCase.onSelected(
147
+ result as SelectResult<T>,
148
+ )
149
+ return [handlerResult !== undefined, handlerResult as V]
147
150
  }
148
151
  } else {
149
152
  const result = await selectedCase.channel.selectReceive(selectedCase.id)
150
153
  if (selectedCase.onSelected) {
151
- await selectedCase.onSelected(result) // Await the handler
154
+ const handlerResult = await selectedCase.onSelected(result)
155
+ return [handlerResult !== undefined, handlerResult as V]
152
156
  }
153
157
  }
154
158
  } else {
155
159
  // This case should ideally not happen if channel is required for non-default cases
156
160
  console.error('Selected case without a channel:', selectedCase)
157
161
  }
158
- return // Return after executing a ready case
162
+ return [false, undefined as V] // Return after executing a ready case
159
163
  }
160
164
 
161
165
  // 2. If no operations are ready and there's a default case, select default
@@ -164,13 +168,14 @@ export async function selectStatement<T>(
164
168
  const defaultCase = cases.find((c) => c.id === -1)
165
169
  if (defaultCase && defaultCase.onSelected) {
166
170
  // Execute the onSelected handler for the default case
167
- await defaultCase.onSelected({
171
+ const handlerResult = await defaultCase.onSelected({
168
172
  value: undefined,
169
173
  ok: false,
170
174
  id: -1,
171
- } as SelectResult<T>) // Await the handler
175
+ } as SelectResult<T>)
176
+ return [handlerResult !== undefined, handlerResult as V]
172
177
  }
173
- return // Return after executing the default case
178
+ return [false, undefined as V] // Return after executing the default case
174
179
  }
175
180
 
176
181
  // 3. If no operations are ready and no default case, block until one is ready
@@ -190,16 +195,19 @@ export async function selectStatement<T>(
190
195
  // If all non-default cases have nil channels, we effectively block forever
191
196
  if (blockingPromises.length === 0) {
192
197
  // No valid channels to operate on, block forever (unless there's a default)
193
- return new Promise<void>(() => {}) // Promise never resolves
198
+ return new Promise<[boolean, V]>(() => {}) // Promise never resolves
194
199
  }
195
200
 
196
201
  const result = await Promise.race(blockingPromises)
197
202
  // Execute onSelected handler for the selected case
198
203
  const selectedCase = cases.find((c) => c.id === result.id)
199
204
  if (selectedCase && selectedCase.onSelected) {
200
- await selectedCase.onSelected(result) // Await the handler
205
+ const handlerResult = await selectedCase.onSelected(result)
206
+ return [handlerResult !== undefined, handlerResult as V]
201
207
  }
208
+
202
209
  // No explicit return needed here, as the function will implicitly return after the await
210
+ return [false, undefined as V]
203
211
  }
204
212
 
205
213
  /**
@@ -259,18 +267,32 @@ export async function chanRecvWithOk<T>(
259
267
  * @param direction Optional direction for the channel. Default is 'both' (bidirectional).
260
268
  * @returns A new channel instance or channel reference.
261
269
  */
262
- export const makeChannel = <T>(
270
+ export function makeChannel<T>(
271
+ bufferSize: number,
272
+ zeroValue: T,
273
+ direction: 'send',
274
+ ): SendOnlyChannelRef<T>
275
+ export function makeChannel<T>(
276
+ bufferSize: number,
277
+ zeroValue: T,
278
+ direction: 'receive',
279
+ ): ReceiveOnlyChannelRef<T>
280
+ export function makeChannel<T>(
281
+ bufferSize: number,
282
+ zeroValue: T,
283
+ direction?: 'both',
284
+ ): Channel<T>
285
+ export function makeChannel<T>(
263
286
  bufferSize: number,
264
287
  zeroValue: T,
265
288
  direction: 'send' | 'receive' | 'both' = 'both',
266
- ): Channel<T> | ChannelRef<T> => {
289
+ ): Channel<T> | ChannelRef<T> {
267
290
  const channel = new BufferedChannel<T>(bufferSize, zeroValue)
268
291
 
269
- // Wrap the channel with the appropriate ChannelRef based on direction
270
292
  if (direction === 'send') {
271
- return new SendOnlyChannelRef<T>(channel) as ChannelRef<T>
293
+ return new SendOnlyChannelRef<T>(channel)
272
294
  } else if (direction === 'receive') {
273
- return new ReceiveOnlyChannelRef<T>(channel) as ChannelRef<T>
295
+ return new ReceiveOnlyChannelRef<T>(channel)
274
296
  } else {
275
297
  return channel
276
298
  }
@@ -343,7 +343,7 @@ export function WithTimeout(
343
343
  parent: Context,
344
344
  timeout: number,
345
345
  ): [ContextNonNil, CancelFunc] {
346
- return WithDeadline(parent, new Date(Date.now() + timeout))
346
+ return WithDeadline(parent, new Date(Date.now() + timeout / 1000000))
347
347
  }
348
348
 
349
349
  // WithTimeoutCause is like WithTimeout but also sets the cause
@@ -352,7 +352,11 @@ export function WithTimeoutCause(
352
352
  timeout: number,
353
353
  cause: $.GoError,
354
354
  ): [ContextNonNil, CancelFunc] {
355
- return WithDeadlineCause(parent, new Date(Date.now() + timeout), cause)
355
+ return WithDeadlineCause(
356
+ parent,
357
+ new Date(Date.now() + timeout / 1000000),
358
+ cause,
359
+ )
356
360
  }
357
361
 
358
362
  // WithValue returns a copy of parent with the value associated with key
@@ -0,0 +1,16 @@
1
+ {
2
+ "asyncMethods": {
3
+ "Background": false,
4
+ "TODO": false,
5
+ "WithCancel": false,
6
+ "WithCancelCause": false,
7
+ "WithDeadline": false,
8
+ "WithDeadlineCause": false,
9
+ "WithTimeout": false,
10
+ "WithTimeoutCause": false,
11
+ "WithValue": false,
12
+ "WithoutCancel": false,
13
+ "Cause": false,
14
+ "AfterFunc": false
15
+ }
16
+ }
@@ -3,7 +3,7 @@ export const GOOS = 'js'
3
3
  export const GOARCH = 'wasm'
4
4
 
5
5
  // Version returns the Go version as a string
6
- export const GOVERSION = 'go1.24.3'
6
+ export const GOVERSION = 'go1.24.4'
7
7
  export function Version(): string {
8
8
  return GOVERSION
9
9
  }
@@ -0,0 +1,29 @@
1
+ // Essential syscall constants
2
+ export const O_RDONLY = 0
3
+ export const O_WRONLY = 1
4
+ export const O_RDWR = 2
5
+ export const O_APPEND = 8
6
+ export const O_CREATE = 64
7
+ export const O_EXCL = 128
8
+ export const O_SYNC = 256
9
+ export const O_TRUNC = 512
10
+
11
+ export const Stdin = 0
12
+ export const Stdout = 1
13
+ export const Stderr = 2
14
+
15
+ export const SIGINT = 2
16
+ export const SIGTERM = 15
17
+
18
+ // File mode constants
19
+ export const S_IFMT = 0o170000
20
+ export const S_IFREG = 0o100000
21
+ export const S_IFDIR = 0o040000
22
+ export const S_IFLNK = 0o120000
23
+ export const S_IFBLK = 0o060000
24
+ export const S_IFCHR = 0o020000
25
+ export const S_IFIFO = 0o010000
26
+ export const S_IFSOCK = 0o140000
27
+ export const S_ISUID = 0o004000
28
+ export const S_ISGID = 0o002000
29
+ export const S_ISVTX = 0o001000
@@ -0,0 +1,47 @@
1
+ import * as $ from '@goscript/builtin/index.js'
2
+
3
+ // Environment variable functions using Node.js/browser APIs
4
+ export function Getenv(key: string): [string, boolean] {
5
+ if (typeof process !== 'undefined' && process.env) {
6
+ const value = process.env[key]
7
+ return value !== undefined ? [value, true] : ['', false]
8
+ }
9
+ return ['', false]
10
+ }
11
+
12
+ export function Setenv(key: string, value: string): $.GoError {
13
+ if (typeof process !== 'undefined' && process.env) {
14
+ process.env[key] = value
15
+ return null
16
+ }
17
+ return { Error: () => 'setenv not supported' }
18
+ }
19
+
20
+ export function Unsetenv(key: string): $.GoError {
21
+ if (typeof process !== 'undefined' && process.env) {
22
+ delete process.env[key]
23
+ return null
24
+ }
25
+ return { Error: () => 'unsetenv not supported' }
26
+ }
27
+
28
+ export function Clearenv(): void {
29
+ if (typeof process !== 'undefined' && process.env) {
30
+ for (const key in process.env) {
31
+ delete process.env[key]
32
+ }
33
+ }
34
+ }
35
+
36
+ export function Environ(): $.Slice<string> {
37
+ if (typeof process !== 'undefined' && process.env) {
38
+ const env: string[] = []
39
+ for (const [key, value] of Object.entries(process.env)) {
40
+ if (value !== undefined) {
41
+ env.push(`${key}=${value}`)
42
+ }
43
+ }
44
+ return $.arrayToSlice(env)
45
+ }
46
+ return $.arrayToSlice([])
47
+ }