goscript 0.0.23 → 0.0.25

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 (94) hide show
  1. package/README.md +2 -2
  2. package/cmd/goscript/cmd_compile.go +18 -2
  3. package/compiler/analysis.go +74 -132
  4. package/compiler/analysis_test.go +220 -0
  5. package/compiler/assignment.go +37 -43
  6. package/compiler/builtin_test.go +90 -0
  7. package/compiler/compiler.go +307 -22
  8. package/compiler/composite-lit.go +108 -43
  9. package/compiler/config.go +7 -3
  10. package/compiler/config_test.go +6 -33
  11. package/compiler/decl.go +7 -1
  12. package/compiler/expr-call.go +212 -2
  13. package/compiler/expr-selector.go +66 -41
  14. package/compiler/expr-star.go +57 -65
  15. package/compiler/expr-type.go +1 -1
  16. package/compiler/expr-value.go +1 -1
  17. package/compiler/expr.go +125 -20
  18. package/compiler/field.go +4 -4
  19. package/compiler/primitive.go +11 -10
  20. package/compiler/spec-struct.go +3 -3
  21. package/compiler/spec-value.go +75 -29
  22. package/compiler/spec.go +9 -3
  23. package/compiler/stmt-assign.go +36 -2
  24. package/compiler/stmt-for.go +11 -0
  25. package/compiler/stmt-range.go +314 -1
  26. package/compiler/stmt.go +52 -0
  27. package/compiler/type.go +83 -15
  28. package/dist/gs/builtin/builtin.d.ts +9 -0
  29. package/dist/gs/builtin/builtin.js +46 -0
  30. package/dist/gs/builtin/builtin.js.map +1 -0
  31. package/dist/gs/builtin/channel.d.ts +193 -0
  32. package/dist/gs/builtin/channel.js +471 -0
  33. package/dist/gs/builtin/channel.js.map +1 -0
  34. package/dist/gs/builtin/defer.d.ts +38 -0
  35. package/dist/gs/builtin/defer.js +54 -0
  36. package/dist/gs/builtin/defer.js.map +1 -0
  37. package/dist/gs/builtin/index.d.ts +1 -0
  38. package/dist/gs/builtin/index.js +2 -0
  39. package/dist/gs/builtin/index.js.map +1 -0
  40. package/dist/gs/builtin/io.d.ts +16 -0
  41. package/dist/gs/builtin/io.js +15 -0
  42. package/dist/gs/builtin/io.js.map +1 -0
  43. package/dist/gs/builtin/map.d.ts +33 -0
  44. package/dist/gs/builtin/map.js +44 -0
  45. package/dist/gs/builtin/map.js.map +1 -0
  46. package/dist/gs/builtin/slice.d.ts +173 -0
  47. package/dist/gs/builtin/slice.js +799 -0
  48. package/dist/gs/builtin/slice.js.map +1 -0
  49. package/dist/gs/builtin/type.d.ts +203 -0
  50. package/dist/gs/builtin/type.js +744 -0
  51. package/dist/gs/builtin/type.js.map +1 -0
  52. package/dist/gs/builtin/varRef.d.ts +14 -0
  53. package/dist/gs/builtin/varRef.js +14 -0
  54. package/dist/gs/builtin/varRef.js.map +1 -0
  55. package/dist/gs/cmp/index.d.ts +4 -0
  56. package/dist/gs/cmp/index.js +27 -0
  57. package/dist/gs/cmp/index.js.map +1 -0
  58. package/dist/gs/context/context.d.ts +26 -0
  59. package/dist/gs/context/context.js +305 -0
  60. package/dist/gs/context/context.js.map +1 -0
  61. package/dist/gs/context/index.d.ts +1 -0
  62. package/dist/gs/context/index.js +2 -0
  63. package/dist/gs/context/index.js.map +1 -0
  64. package/dist/gs/internal/goarch/index.d.ts +6 -0
  65. package/dist/gs/internal/goarch/index.js +14 -0
  66. package/dist/gs/internal/goarch/index.js.map +1 -0
  67. package/dist/gs/iter/index.d.ts +1 -0
  68. package/dist/gs/iter/index.js +2 -0
  69. package/dist/gs/iter/index.js.map +1 -0
  70. package/dist/gs/iter/iter.d.ts +4 -0
  71. package/dist/gs/iter/iter.js +91 -0
  72. package/dist/gs/iter/iter.js.map +1 -0
  73. package/dist/gs/math/bits/index.d.ts +47 -0
  74. package/dist/gs/math/bits/index.js +298 -0
  75. package/dist/gs/math/bits/index.js.map +1 -0
  76. package/dist/gs/runtime/index.d.ts +1 -0
  77. package/dist/gs/runtime/index.js +2 -0
  78. package/dist/gs/runtime/index.js.map +1 -0
  79. package/dist/gs/runtime/runtime.d.ts +41 -0
  80. package/dist/gs/runtime/runtime.js +158 -0
  81. package/dist/gs/runtime/runtime.js.map +1 -0
  82. package/dist/gs/slices/index.d.ts +1 -0
  83. package/dist/gs/slices/index.js +2 -0
  84. package/dist/gs/slices/index.js.map +1 -0
  85. package/dist/gs/slices/slices.d.ts +8 -0
  86. package/dist/gs/slices/slices.js +20 -0
  87. package/dist/gs/slices/slices.js.map +1 -0
  88. package/dist/gs/time/index.d.ts +1 -0
  89. package/dist/gs/time/index.js +2 -0
  90. package/dist/gs/time/index.js.map +1 -0
  91. package/dist/gs/time/time.d.ts +57 -0
  92. package/dist/gs/time/time.js +208 -0
  93. package/dist/gs/time/time.js.map +1 -0
  94. package/package.json +3 -2
package/compiler/stmt.go CHANGED
@@ -28,6 +28,8 @@ import (
28
28
  // - Go statements (`ast.GoStmt`): `WriteStmtGo`.
29
29
  // - Select statements (`ast.SelectStmt`): `WriteStmtSelect`.
30
30
  // - Branch statements (`ast.BranchStmt`): `WriteStmtBranch`.
31
+ // - Type switch statements (`ast.TypeSwitchStmt`): `WriteStmtTypeSwitch`.
32
+ // - Labeled statements (`ast.LabeledStmt`): `WriteStmtLabeled`.
31
33
  //
32
34
  // If an unknown statement type is encountered, it returns an error.
33
35
  func (c *GoToTSCompiler) WriteStmt(a ast.Stmt) error {
@@ -109,6 +111,10 @@ func (c *GoToTSCompiler) WriteStmt(a ast.Stmt) error {
109
111
  if err := c.WriteStmtTypeSwitch(exp); err != nil {
110
112
  return fmt.Errorf("failed to write type switch statement: %w", err)
111
113
  }
114
+ case *ast.LabeledStmt:
115
+ if err := c.WriteStmtLabeled(exp); err != nil {
116
+ return fmt.Errorf("failed to write labeled statement: %w", err)
117
+ }
112
118
  default:
113
119
  return errors.Errorf("unknown statement: %#v\n", a)
114
120
  }
@@ -292,6 +298,37 @@ func (c *GoToTSCompiler) WriteStmtGo(exp *ast.GoStmt) error {
292
298
  c.tsw.WriteLiterally(")")
293
299
  c.tsw.WriteLine("")
294
300
 
301
+ c.tsw.Indent(-1)
302
+ c.tsw.WriteLine("})") // Close the queueMicrotask callback and the statement
303
+ case *ast.TypeAssertExpr:
304
+ // Handle type assertion expressions: go x.(func())()
305
+ // We assume this is always synchronous (no async function returned by type assertion)
306
+ c.tsw.WriteLiterally("queueMicrotask(() => {")
307
+
308
+ c.tsw.Indent(1)
309
+ c.tsw.WriteLine("")
310
+
311
+ // Write the type assertion call
312
+ if err := c.WriteTypeAssertExpr(fun); err != nil {
313
+ return fmt.Errorf("failed to write type assertion expression in goroutine: %w", err)
314
+ }
315
+
316
+ // Add non-null assertion since mustTypeAssert throws on failure rather than returning null
317
+ c.tsw.WriteLiterally("!")
318
+
319
+ // Write the function arguments
320
+ c.tsw.WriteLiterally("(")
321
+ for i, arg := range callExpr.Args {
322
+ if i != 0 {
323
+ c.tsw.WriteLiterally(", ")
324
+ }
325
+ if err := c.WriteValueExpr(arg); err != nil {
326
+ return fmt.Errorf("failed to write argument %d in goroutine type assertion function call: %w", i, err)
327
+ }
328
+ }
329
+ c.tsw.WriteLiterally(")")
330
+ c.tsw.WriteLine("")
331
+
295
332
  c.tsw.Indent(-1)
296
333
  c.tsw.WriteLine("})") // Close the queueMicrotask callback and the statement
297
334
  default:
@@ -790,3 +827,18 @@ func (c *GoToTSCompiler) WriteStmtDefer(exp *ast.DeferStmt) error {
790
827
 
791
828
  return nil
792
829
  }
830
+
831
+ // WriteStmtLabeled handles labeled statements (ast.LabeledStmt), such as "label: statement".
832
+ // In TypeScript, this translates to "label: statement" directly.
833
+ func (c *GoToTSCompiler) WriteStmtLabeled(stmt *ast.LabeledStmt) error {
834
+ // Write the label name followed by a colon
835
+ c.tsw.WriteLiterally(stmt.Label.Name)
836
+ c.tsw.WriteLiterally(": ")
837
+
838
+ // Write the labeled statement
839
+ if err := c.WriteStmt(stmt.Stmt); err != nil {
840
+ return fmt.Errorf("failed to write labeled statement: %w", err)
841
+ }
842
+
843
+ return nil
844
+ }
package/compiler/type.go CHANGED
@@ -16,7 +16,7 @@ const (
16
16
  GoTypeContextGeneral GoTypeContext = iota
17
17
  // GoTypeContextFunctionReturn is used when translating types for function return values.
18
18
  // In this context, pointer-to-struct types become `ClassName | null` instead of
19
- // `$.Box<ClassName> | null` because function return values cannot be addressed.
19
+ // `$.VarRef<ClassName> | null` because function return values cannot be addressed.
20
20
  GoTypeContextFunctionReturn
21
21
  )
22
22
 
@@ -27,7 +27,7 @@ const (
27
27
  // The context parameter controls how certain types (especially pointers) are handled:
28
28
  // - GoTypeContextGeneral: Standard type translation
29
29
  // - GoTypeContextFunctionReturn: Special handling for function return types where
30
- // pointer-to-struct types become `ClassName | null` instead of `$.Box<ClassName> | null`
30
+ // pointer-to-struct types become `ClassName | null` instead of `$.VarRef<ClassName> | null`
31
31
  //
32
32
  // It handles nil types as 'any' with a comment, and dispatches to appropriate
33
33
  // type-specific writers for all other recognized Go types.
@@ -47,7 +47,7 @@ func (c *GoToTSCompiler) WriteGoType(typ types.Type, context GoTypeContext) {
47
47
  if context == GoTypeContextFunctionReturn {
48
48
  c.writePointerTypeForFunctionReturn(t)
49
49
  } else {
50
- c.WritePointerType(t)
50
+ c.WritePointerType(t, context)
51
51
  }
52
52
  case *types.Slice:
53
53
  c.WriteSliceType(t)
@@ -68,6 +68,15 @@ func (c *GoToTSCompiler) WriteGoType(typ types.Type, context GoTypeContext) {
68
68
  case *types.TypeParam:
69
69
  // For type parameters, write the type parameter name (e.g., "T", "K", etc.)
70
70
  c.tsw.WriteLiterally(t.Obj().Name())
71
+ case *types.Union:
72
+ // Handle union types (e.g., string | []byte)
73
+ for i := 0; i < t.Len(); i++ {
74
+ if i > 0 {
75
+ c.tsw.WriteLiterally(" | ")
76
+ }
77
+ term := t.Term(i)
78
+ c.WriteGoType(term.Type(), context)
79
+ }
71
80
  default:
72
81
  // For other types, just write "any" and add a comment
73
82
  c.tsw.WriteLiterally("any")
@@ -78,7 +87,7 @@ func (c *GoToTSCompiler) WriteGoType(typ types.Type, context GoTypeContext) {
78
87
  // writePointerTypeForFunctionReturn translates a Go pointer type (*T) to its TypeScript
79
88
  // equivalent for function return types. Unlike WritePointerType, this function
80
89
  // handles pointer-to-struct types specially: they become `ClassName | null` instead
81
- // of `$.Box<ClassName> | null` because function return values cannot be addressed.
90
+ // of `$.VarRef<ClassName> | null` because function return values cannot be addressed.
82
91
  func (c *GoToTSCompiler) writePointerTypeForFunctionReturn(t *types.Pointer) {
83
92
  elemType := t.Elem()
84
93
 
@@ -93,8 +102,8 @@ func (c *GoToTSCompiler) writePointerTypeForFunctionReturn(t *types.Pointer) {
93
102
  c.WriteGoType(elemType, GoTypeContextFunctionReturn)
94
103
  c.tsw.WriteLiterally(" | null")
95
104
  } else {
96
- // For pointer-to-primitive in function returns, still use boxing
97
- c.tsw.WriteLiterally("$.Box<")
105
+ // For pointer-to-primitive in function returns, still use varRefing
106
+ c.tsw.WriteLiterally("$.VarRef<")
98
107
  c.WriteGoType(elemType, GoTypeContextFunctionReturn)
99
108
  c.tsw.WriteLiterally("> | null")
100
109
  }
@@ -202,7 +211,8 @@ func (c *GoToTSCompiler) WriteBasicType(t *types.Basic) {
202
211
 
203
212
  // WriteNamedType translates a Go named type to its TypeScript equivalent.
204
213
  // It specially handles the error interface as $.GoError, and uses the original
205
- // type name for other named types. For generic types, it includes type arguments.
214
+ // type name for other named types. For imported types, it writes the qualified
215
+ // name using the import alias found from the analysis imports. For generic types, it includes type arguments.
206
216
  func (c *GoToTSCompiler) WriteNamedType(t *types.Named) {
207
217
  // Check if the named type is the error interface
208
218
  if iface, ok := t.Underlying().(*types.Interface); ok && iface.String() == "interface{Error() string}" {
@@ -210,7 +220,40 @@ func (c *GoToTSCompiler) WriteNamedType(t *types.Named) {
210
220
  return
211
221
  }
212
222
 
213
- // Use Obj().Name() for the original defined name
223
+ // Check if this type is from an imported package
224
+ typePkg := t.Obj().Pkg()
225
+ if typePkg != nil && typePkg != c.pkg.Types {
226
+ // This type is from an imported package, find the import alias
227
+ typePkgPath := typePkg.Path()
228
+
229
+ // Try to find the import alias by matching the package path
230
+ for importAlias, _ := range c.analysis.Imports {
231
+ // The importAlias could be either the explicit alias or the default package name
232
+ // If it's the default package name, it should match the last segment of the path
233
+ defaultPkgName := packageNameFromGoPath(typePkgPath)
234
+ if importAlias == defaultPkgName || importAlias == typePkgPath {
235
+ // Write the qualified name: importAlias.TypeName
236
+ c.tsw.WriteLiterally(importAlias)
237
+ c.tsw.WriteLiterally(".")
238
+ c.tsw.WriteLiterally(t.Obj().Name())
239
+
240
+ // For generic types, include type arguments
241
+ if t.TypeArgs() != nil && t.TypeArgs().Len() > 0 {
242
+ c.tsw.WriteLiterally("<")
243
+ for i := 0; i < t.TypeArgs().Len(); i++ {
244
+ if i > 0 {
245
+ c.tsw.WriteLiterally(", ")
246
+ }
247
+ c.WriteGoType(t.TypeArgs().At(i), GoTypeContextGeneral)
248
+ }
249
+ c.tsw.WriteLiterally(">")
250
+ }
251
+ return
252
+ }
253
+ }
254
+ }
255
+
256
+ // Use Obj().Name() for the original defined name (local types or unmatched imports)
214
257
  c.tsw.WriteLiterally(t.Obj().Name())
215
258
 
216
259
  // For generic types, include type arguments
@@ -227,11 +270,36 @@ func (c *GoToTSCompiler) WriteNamedType(t *types.Named) {
227
270
  }
228
271
 
229
272
  // WritePointerType translates a Go pointer type (*T) to its TypeScript equivalent.
230
- // It generates $.Box<T_ts> | null, where T_ts is the translated element type.
231
- func (c *GoToTSCompiler) WritePointerType(t *types.Pointer) {
232
- c.tsw.WriteLiterally("$.Box<")
233
- c.WriteGoType(t.Elem(), GoTypeContextGeneral)
234
- c.tsw.WriteLiterally("> | null") // Pointers are always nullable
273
+ func (c *GoToTSCompiler) WritePointerType(t *types.Pointer, context GoTypeContext) {
274
+ elemGoType := t.Elem()
275
+ underlyingElemGoType := elemGoType.Underlying()
276
+
277
+ // Handle pointers to functions: *func(...) -> func(...) | null
278
+ if _, isSignature := underlyingElemGoType.(*types.Signature); isSignature {
279
+ c.WriteGoType(elemGoType, context) // Write the function signature itself, pass context
280
+ c.tsw.WriteLiterally(" | null") // Function pointers are nullable
281
+ return
282
+ }
283
+
284
+ // Handle pointers to structs or interfaces: *MyStruct -> MyStruct | null
285
+ _, isStruct := underlyingElemGoType.(*types.Struct)
286
+ _, isInterface := underlyingElemGoType.(*types.Interface)
287
+
288
+ if isStruct || isInterface {
289
+ // For pointers to structs or interfaces, the TS type is StructName | null or InterfaceName | null.
290
+ // This aligns with VAR_REFS.md and JS/TS object reference semantics.
291
+ // TODO If the target variable is boxed, we have to wrap with VarRef as well?
292
+ c.WriteGoType(elemGoType, context) // Write the struct/interface type directly, pass context
293
+ c.tsw.WriteLiterally(" | null")
294
+ } else {
295
+ // For pointers to other types (primitives, slices, maps, other pointers like **MyStruct),
296
+ // they are generally represented as $.VarRef<T_ts> | null.
297
+ // Example: *int -> $.VarRef<number> | null
298
+ // Example: **MyStruct -> $.VarRef<MyStruct | null> | null (recursive call handles inner part)
299
+ c.tsw.WriteLiterally("$.VarRef<")
300
+ c.WriteGoType(elemGoType, context) // Translate element type, pass context
301
+ c.tsw.WriteLiterally("> | null") // Pointers are always nullable
302
+ }
235
303
  }
236
304
 
237
305
  // WriteSliceType translates a Go slice type ([]T) to its TypeScript equivalent.
@@ -363,7 +431,7 @@ func (c *GoToTSCompiler) WriteSignatureType(t *types.Signature) {
363
431
 
364
432
  // Use parameter name if available, otherwise use p0, p1, etc.
365
433
  if param.Name() != "" {
366
- c.tsw.WriteLiterally(param.Name())
434
+ c.tsw.WriteLiterally(c.sanitizeIdentifier(param.Name()))
367
435
  } else {
368
436
  c.tsw.WriteLiterallyf("p%d", i)
369
437
  }
@@ -458,7 +526,7 @@ func (c *GoToTSCompiler) writeInterfaceStructure(iface *types.Interface, astNode
458
526
  if paramName == "" || paramName == "_" {
459
527
  paramName = fmt.Sprintf("_p%d", j)
460
528
  }
461
- c.tsw.WriteLiterally(paramName)
529
+ c.tsw.WriteLiterally(c.sanitizeIdentifier(paramName))
462
530
  c.tsw.WriteLiterally(": ")
463
531
  c.WriteGoType(paramVar.Type(), GoTypeContextGeneral) // Recursive call for param type
464
532
  }
@@ -0,0 +1,9 @@
1
+ export * from './varRef.js';
2
+ export * from './channel.js';
3
+ export * from './defer.js';
4
+ export * from './io.js';
5
+ export * from './map.js';
6
+ export * from './slice.js';
7
+ export * from './type.js';
8
+ export declare function copy<T>(dst: T[], src: T[]): number;
9
+ export declare function multiplyDuration(duration: any, multiplier: number): any;
@@ -0,0 +1,46 @@
1
+ export * from './varRef.js';
2
+ export * from './channel.js';
3
+ export * from './defer.js';
4
+ export * from './io.js';
5
+ export * from './map.js';
6
+ export * from './slice.js';
7
+ export * from './type.js';
8
+ // Copy is the Go builtin function that copies the contents of one slice to another.
9
+ // It returns the number of elements copied.
10
+ export function copy(dst, src) {
11
+ const n = Math.min(dst.length, src.length);
12
+ for (let i = 0; i < n; i++) {
13
+ dst[i] = src[i];
14
+ }
15
+ return n;
16
+ }
17
+ // Duration multiplication helper for time package operations
18
+ // Handles expressions like time.Hour * 24
19
+ export function multiplyDuration(duration, multiplier) {
20
+ // Check if duration has a multiply method (like our Duration class)
21
+ if (duration && typeof duration.multiply === 'function') {
22
+ return duration.multiply(multiplier);
23
+ }
24
+ // Check if duration has a valueOf method for numeric operations
25
+ if (duration && typeof duration.valueOf === 'function') {
26
+ const numValue = duration.valueOf();
27
+ // Return an object with the same structure but multiplied value
28
+ if (typeof numValue === 'number') {
29
+ // Try to create a new instance of the same type
30
+ if (duration.constructor) {
31
+ return new duration.constructor(numValue * multiplier);
32
+ }
33
+ // Fallback: return a simple object with valueOf
34
+ return {
35
+ valueOf: () => numValue * multiplier,
36
+ toString: () => (numValue * multiplier).toString() + "ns"
37
+ };
38
+ }
39
+ }
40
+ // Fallback for simple numeric values
41
+ if (typeof duration === 'number') {
42
+ return duration * multiplier;
43
+ }
44
+ throw new Error(`Cannot multiply duration of type ${typeof duration}`);
45
+ }
46
+ //# sourceMappingURL=builtin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../../gs/builtin/builtin.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AAEzB,oFAAoF;AACpF,4CAA4C;AAC5C,MAAM,UAAU,IAAI,CAAI,GAAQ,EAAE,GAAQ;IACxC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,6DAA6D;AAC7D,0CAA0C;AAC1C,MAAM,UAAU,gBAAgB,CAAC,QAAa,EAAE,UAAkB;IAChE,oEAAoE;IACpE,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QACxD,OAAO,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAED,gEAAgE;IAChE,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QACvD,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;QACpC,gEAAgE;QAChE,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,gDAAgD;YAChD,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;gBACzB,OAAO,IAAI,QAAQ,CAAC,WAAW,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC;YACzD,CAAC;YACD,gDAAgD;YAChD,OAAO;gBACL,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,GAAG,UAAU;gBACpC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC,QAAQ,EAAE,GAAG,IAAI;aAC1D,CAAC;QACJ,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,QAAQ,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,oCAAoC,OAAO,QAAQ,EAAE,CAAC,CAAC;AACzE,CAAC"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Represents the result of a channel receive operation with 'ok' value
3
+ */
4
+ export interface ChannelReceiveResult<T> {
5
+ value: T;
6
+ ok: boolean;
7
+ }
8
+ /**
9
+ * Represents a result from a select operation
10
+ */
11
+ export interface SelectResult<T> {
12
+ value: T;
13
+ ok: boolean;
14
+ id: number;
15
+ }
16
+ /**
17
+ * Represents a Go channel in TypeScript.
18
+ * Supports asynchronous sending and receiving of values.
19
+ */
20
+ export interface Channel<T> {
21
+ /**
22
+ * Sends a value to the channel.
23
+ * Returns a promise that resolves when the value is accepted by the channel.
24
+ * @param value The value to send.
25
+ */
26
+ send(value: T): Promise<void>;
27
+ /**
28
+ * Receives a value from the channel.
29
+ * Returns a promise that resolves with the received value.
30
+ * If the channel is closed, it throws an error.
31
+ */
32
+ receive(): Promise<T>;
33
+ /**
34
+ * Receives a value from the channel along with a boolean indicating
35
+ * whether the channel is still open.
36
+ * Returns a promise that resolves with {value, ok}.
37
+ * - If channel is open and has data: {value: <data>, ok: true}
38
+ * - If channel is closed and empty: {value: <zero value>, ok: false}
39
+ * - If channel is closed but has remaining buffered data: {value: <data>, ok: true}
40
+ */
41
+ receiveWithOk(): Promise<ChannelReceiveResult<T>>;
42
+ /**
43
+ * Closes the channel.
44
+ * No more values can be sent to a closed channel.
45
+ * Receive operations on a closed channel return the zero value and ok=false.
46
+ */
47
+ close(): void;
48
+ /**
49
+ * Used in select statements to create a receive operation promise.
50
+ * @param id An identifier for this case in the select statement
51
+ * @returns Promise that resolves when this case is selected
52
+ */
53
+ selectReceive(id: number): Promise<SelectResult<T>>;
54
+ /**
55
+ * Used in select statements to create a send operation promise.
56
+ * @param value The value to send
57
+ * @param id An identifier for this case in the select statement
58
+ * @returns Promise that resolves when this case is selected
59
+ */
60
+ selectSend(value: T, id: number): Promise<SelectResult<boolean>>;
61
+ /**
62
+ * Checks if the channel has data ready to be received without blocking.
63
+ * Used for non-blocking select operations.
64
+ */
65
+ canReceiveNonBlocking(): boolean;
66
+ /**
67
+ * Checks if the channel can accept a send operation without blocking.
68
+ * Used for non-blocking select operations.
69
+ */
70
+ canSendNonBlocking(): boolean;
71
+ }
72
+ /**
73
+ * Represents a case in a select statement.
74
+ */
75
+ export interface SelectCase<T> {
76
+ id: number;
77
+ isSend: boolean;
78
+ channel: Channel<any> | ChannelRef<any> | null;
79
+ value?: any;
80
+ onSelected?: (result: SelectResult<T>) => Promise<void>;
81
+ }
82
+ /**
83
+ * Helper for 'select' statements. Takes an array of select cases
84
+ * and resolves when one of them completes, following Go's select rules.
85
+ *
86
+ * @param cases Array of SelectCase objects
87
+ * @param hasDefault Whether there is a default case
88
+ * @returns A promise that resolves with the result of the selected case
89
+ */
90
+ export declare function selectStatement<T>(cases: SelectCase<T>[], hasDefault?: boolean): Promise<void>;
91
+ /**
92
+ * Helper function for channel send operations that handles nil channels correctly.
93
+ * In Go, sending to a nil channel blocks forever.
94
+ * @param channel The channel to send to (can be null)
95
+ * @param value The value to send
96
+ * @returns Promise that never resolves if channel is null, otherwise delegates to channel.send()
97
+ */
98
+ export declare function chanSend<T>(channel: Channel<T> | ChannelRef<T> | null, value: T): Promise<void>;
99
+ /**
100
+ * Helper function for channel receive operations that handles nil channels correctly.
101
+ * In Go, receiving from a nil channel blocks forever.
102
+ * @param channel The channel to receive from (can be null)
103
+ * @returns Promise that never resolves if channel is null, otherwise delegates to channel.receive()
104
+ */
105
+ export declare function chanRecv<T>(channel: Channel<T> | ChannelRef<T> | null): Promise<T>;
106
+ /**
107
+ * Helper function for channel receive operations with ok value that handles nil channels correctly.
108
+ * In Go, receiving from a nil channel blocks forever.
109
+ * @param channel The channel to receive from (can be null)
110
+ * @returns Promise that never resolves if channel is null, otherwise delegates to channel.receiveWithOk()
111
+ */
112
+ export declare function chanRecvWithOk<T>(channel: Channel<T> | ChannelRef<T> | null): Promise<ChannelReceiveResult<T>>;
113
+ /**
114
+ * Creates a new channel with the specified buffer size and zero value.
115
+ * @param bufferSize The size of the channel buffer. If 0, creates an unbuffered channel.
116
+ * @param zeroValue The zero value for the channel's element type.
117
+ * @param direction Optional direction for the channel. Default is 'both' (bidirectional).
118
+ * @returns A new channel instance or channel reference.
119
+ */
120
+ export declare const makeChannel: <T>(bufferSize: number, zeroValue: T, direction?: "send" | "receive" | "both") => Channel<T> | ChannelRef<T>;
121
+ /**
122
+ * Represents a reference to a channel with a specific direction.
123
+ */
124
+ export interface ChannelRef<T> {
125
+ /**
126
+ * The underlying channel
127
+ */
128
+ channel: Channel<T>;
129
+ /**
130
+ * The direction of this channel reference
131
+ */
132
+ direction: 'send' | 'receive' | 'both';
133
+ send(value: T): Promise<void>;
134
+ receive(): Promise<T>;
135
+ receiveWithOk(): Promise<ChannelReceiveResult<T>>;
136
+ close(): void;
137
+ canSendNonBlocking(): boolean;
138
+ canReceiveNonBlocking(): boolean;
139
+ selectSend(value: T, id: number): Promise<SelectResult<boolean>>;
140
+ selectReceive(id: number): Promise<SelectResult<T>>;
141
+ }
142
+ /**
143
+ * A bidirectional channel reference.
144
+ */
145
+ export declare class BidirectionalChannelRef<T> implements ChannelRef<T> {
146
+ channel: Channel<T>;
147
+ direction: 'both';
148
+ constructor(channel: Channel<T>);
149
+ send(value: T): Promise<void>;
150
+ receive(): Promise<T>;
151
+ receiveWithOk(): Promise<ChannelReceiveResult<T>>;
152
+ close(): void;
153
+ canSendNonBlocking(): boolean;
154
+ canReceiveNonBlocking(): boolean;
155
+ selectSend(value: T, id: number): Promise<SelectResult<boolean>>;
156
+ selectReceive(id: number): Promise<SelectResult<T>>;
157
+ }
158
+ /**
159
+ * A send-only channel reference.
160
+ */
161
+ export declare class SendOnlyChannelRef<T> implements ChannelRef<T> {
162
+ channel: Channel<T>;
163
+ direction: 'send';
164
+ constructor(channel: Channel<T>);
165
+ send(value: T): Promise<void>;
166
+ close(): void;
167
+ canSendNonBlocking(): boolean;
168
+ selectSend(value: T, id: number): Promise<SelectResult<boolean>>;
169
+ receive(): Promise<T>;
170
+ receiveWithOk(): Promise<ChannelReceiveResult<T>>;
171
+ canReceiveNonBlocking(): boolean;
172
+ selectReceive(id: number): Promise<SelectResult<T>>;
173
+ }
174
+ /**
175
+ * A receive-only channel reference.
176
+ */
177
+ export declare class ReceiveOnlyChannelRef<T> implements ChannelRef<T> {
178
+ channel: Channel<T>;
179
+ direction: 'receive';
180
+ constructor(channel: Channel<T>);
181
+ receive(): Promise<T>;
182
+ receiveWithOk(): Promise<ChannelReceiveResult<T>>;
183
+ canReceiveNonBlocking(): boolean;
184
+ selectReceive(id: number): Promise<SelectResult<T>>;
185
+ send(value: T): Promise<void>;
186
+ close(): void;
187
+ canSendNonBlocking(): boolean;
188
+ selectSend(value: T, id: number): Promise<SelectResult<boolean>>;
189
+ }
190
+ /**
191
+ * Creates a new channel reference with the specified direction.
192
+ */
193
+ export declare function makeChannelRef<T>(channel: Channel<T>, direction: 'send' | 'receive' | 'both'): ChannelRef<T>;