goscript 0.0.45 โ†’ 0.0.48

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 CHANGED
@@ -9,594 +9,288 @@
9
9
  [DeepWiki Widget]: https://img.shields.io/badge/DeepWiki-aperturerobotics%2Fgoscript-blue.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAyCAYAAAAnWDnqAAAAAXNSR0IArs4c6QAAA05JREFUaEPtmUtyEzEQhtWTQyQLHNak2AB7ZnyXZMEjXMGeK/AIi+QuHrMnbChYY7MIh8g01fJoopFb0uhhEqqcbWTp06/uv1saEDv4O3n3dV60RfP947Mm9/SQc0ICFQgzfc4CYZoTPAswgSJCCUJUnAAoRHOAUOcATwbmVLWdGoH//PB8mnKqScAhsD0kYP3j/Yt5LPQe2KvcXmGvRHcDnpxfL2zOYJ1mFwrryWTz0advv1Ut4CJgf5uhDuDj5eUcAUoahrdY/56ebRWeraTjMt/00Sh3UDtjgHtQNHwcRGOC98BJEAEymycmYcWwOprTgcB6VZ5JK5TAJ+fXGLBm3FDAmn6oPPjR4rKCAoJCal2eAiQp2x0vxTPB3ALO2CRkwmDy5WohzBDwSEFKRwPbknEggCPB/imwrycgxX2NzoMCHhPkDwqYMr9tRcP5qNrMZHkVnOjRMWwLCcr8ohBVb1OMjxLwGCvjTikrsBOiA6fNyCrm8V1rP93iVPpwaE+gO0SsWmPiXB+jikdf6SizrT5qKasx5j8ABbHpFTx+vFXp9EnYQmLx02h1QTTrl6eDqxLnGjporxl3NL3agEvXdT0WmEost648sQOYAeJS9Q7bfUVoMGnjo4AZdUMQku50McDcMWcBPvr0SzbTAFDfvJqwLzgxwATnCgnp4wDl6Aa+Ax283gghmj+vj7feE2KBBRMW3FzOpLOADl0Isb5587h/U4gGvkt5v60Z1VLG8BhYjbzRwyQZemwAd6cCR5/XFWLYZRIMpX39AR0tjaGGiGzLVyhse5C9RKC6ai42ppWPKiBagOvaYk8lO7DajerabOZP46Lby5wKjw1HCRx7p9sVMOWGzb/vA1hwiWc6jm3MvQDTogQkiqIhJV0nBQBTU+3okKCFDy9WwferkHjtxib7t3xIUQtHxnIwtx4mpg26/HfwVNVDb4oI9RHmx5WGelRVlrtiw43zboCLaxv46AZeB3IlTkwouebTr1y2NjSpHz68WNFjHvupy3q8TFn3Hos2IAk4Ju5dCo8B3wP7VPr/FGaKiG+T+v+TQqIrOqMTL1VdWV1DdmcbO8KXBz6esmYWYKPwDL5b5FA1a0hwapHiom0r/cKaoqr+27/XcrS5UwSMbQAAAABJRU5ErkJggg==
10
10
  [DeepWiki]: https://deepwiki.com/aperturerobotics/goscript
11
11
 
12
- ## Introduction
12
+ ## What is GoScript?
13
13
 
14
- GoScript is a Go to TypeScript compiler / translater.
15
-
16
- It works on translating Go to TypeScript on the AST level.
17
-
18
- For detailed information on the compiler's design, refer to the [design document](./design/DESIGN.md).
14
+ GoScript is a **Go to TypeScript compiler** that translates Go code to TypeScript at the AST level. Perfect for sharing algorithms and business logic between Go backends and TypeScript frontends.
19
15
 
20
16
  > Right now goscript looks pretty cool if you problem is "I want this self-sufficient algorithm be available in Go and JS runtimes". gopherjs's ambition, however, has always been "any valid Go program can run in a browser". There is a lot that goes on in gopherjs that is necessary for supporting the standard library, which goes beyond cross-language translation.
21
17
  >
22
18
  > — [nevkontakte](https://gophers.slack.com/archives/C039C0R2T/p1745870396945719), developer of [GopherJS](https://github.com/gopherjs/gopherjs)
23
19
 
24
- GoScript intends to compile a subset of the Go language to TypeScript in a
25
- non-spec-compliant way. It is intended only for bringing over high-level logic
26
- from Go to TypeScript, so not all programs will work correctly:
20
+ ### ๐ŸŽฏ Why GoScript?
27
21
 
28
- - Numbers (ints) use the "number" type in JavaScript is different than Go int32.
29
- - Pointer arithmetic (uintptr) and unsafe are not supported
30
- - Reflection is not supported
31
- - Complex numbers are not supported
22
+ **Write once, run everywhere.** Share your Go algorithms, business logic, and data structures seamlessly between your backend and frontend without maintaining two codebases.
32
23
 
33
- If you are OK with these limitations, GoScript is for you!
24
+ โœ… **Perfect for:**
25
+ - Sharing business logic between Go services and web apps
26
+ - Porting Go algorithms to run in browsers
27
+ - Building TypeScript libraries from existing Go code
28
+ - Full-stack teams that love Go's simplicity
34
29
 
35
- ## Usage
30
+ โš ๏ธ **What's supported:**
31
+ GoScript compiles a powerful subset of Go:
32
+ - Structs, interfaces, methods, and functions
33
+ - Channels and goroutines (translated to async/await)
34
+ - Slices, maps, and most built-in types
35
+ - Basic reflection support
36
+ - Standard control flow (if, for, switch, etc.)
36
37
 
37
- ### Command Line
38
+ **Current limitations:**
39
+ - Uses JavaScript `number` type (64-bit float, not Go's int types)
40
+ - No pointer arithmetic (`uintptr`) or `unsafe` package
41
+ - No complex numbers
42
+ - Limited standard library (growing rapidly)
38
43
 
39
- After installing the `goscript` npm package, the `goscript` command line tool is available. You can run it directly or within your `package.json` scripts.
44
+ If you're building algorithms, business logic, or data processing code, GoScript has you covered! ๐Ÿš€
40
45
 
41
- Compile a package using the CLI tool:
46
+ ๐Ÿ“– **Learn more:** [Design document](./design/DESIGN.md) | [Compliance tests](./compliance/COMPLIANCE.md)
42
47
 
48
+ ## ๐Ÿš€ Get Started in 2 Minutes
49
+
50
+ ### Installation
51
+
52
+ **Option 1: Go Install**
43
53
  ```bash
44
- goscript compile \
45
- --package "my/package" \
46
- --output ./output
54
+ go install github.com/aperturerobotics/goscript/cmd/goscript@latest
47
55
  ```
48
56
 
49
- For example, to compile the simple example from the project root:
50
-
57
+ **Option 2: NPM**
51
58
  ```bash
52
- goscript compile --package ./example/simple --output ./output
59
+ npm install -g goscript
53
60
  ```
54
- Or within the `example/simple` directory:
61
+
62
+ ### Your First Compilation
55
63
 
56
64
  ```bash
57
- cd example/simple
58
- goscript compile --package . --output ./output
65
+ # Compile your Go package to TypeScript
66
+ goscript compile --package . --output ./dist
59
67
  ```
60
68
 
61
- ### As a Library
69
+ ## ๐Ÿ’ก See It In Action
62
70
 
63
- You can also use the compiler directly within your Go code. Here's a basic example:
71
+ ### Example: User Management
64
72
 
73
+ **Go Code** (`user.go`):
65
74
  ```go
66
75
  package main
67
76
 
68
- import (
69
- "context"
70
- "log"
71
-
72
- "github.com/aperturerobotics/goscript/compiler"
73
- "github.com/sirupsen/logrus"
74
- )
75
-
76
- func main() {
77
- // Initialize logger (optional)
78
- logger := logrus.New()
79
- logger.SetLevel(logrus.DebugLevel) // Adjust log level as needed
80
- le := logrus.NewEntry(logger)
77
+ type User struct {
78
+ ID int `json:"id"`
79
+ Name string `json:"name"`
80
+ Email string `json:"email"`
81
+ }
81
82
 
82
- // Configure the compiler
83
- conf := &compiler.Config{
84
- OutputPath: "./ts_output", // Directory for generated TypeScript files
85
- }
86
- if err := conf.Validate(); err != nil {
87
- log.Fatalf("invalid compiler config: %v", err)
88
- }
83
+ func (u *User) IsValid() bool {
84
+ return u.Name != "" && u.Email != ""
85
+ }
89
86
 
90
- // Create a new compiler instance
91
- comp, err := compiler.NewCompiler(conf, le, nil) // Pass nil for default package loading options
92
- if err != nil {
93
- log.Fatalf("failed to create compiler: %v", err)
94
- }
87
+ func NewUser(id int, name, email string) *User {
88
+ return &User{ID: id, Name: name, Email: email}
89
+ }
95
90
 
96
- // Compile the desired Go package(s)
97
- // Replace "." with the specific Go import path of the package you want to compile
98
- if _, err := comp.CompilePackages(context.Background(), "your/go/package/path"); err != nil {
99
- log.Fatalf("compilation failed: %v", err)
91
+ func FindUserByEmail(users []*User, email string) *User {
92
+ for _, user := range users {
93
+ if user.Email == email {
94
+ return user
95
+ }
100
96
  }
101
-
102
- log.Println("Compilation successful!")
97
+ return nil
103
98
  }
104
-
105
99
  ```
106
100
 
107
- This example initializes the compiler, creates a compiler instance, and then calls `CompilePackages` to translate the specified Go package into TypeScript files in the output directory.
108
-
109
- ### TypeScript API
110
-
111
- You can also use GoScript programmatically within your Node.js projects.
112
-
113
- **Installation:**
114
-
101
+ **Compile it:**
115
102
  ```bash
116
- npm install goscript
117
- # or
118
- yarn add goscript
103
+ goscript compile --package . --output ./dist
119
104
  ```
120
105
 
121
- **Usage:**
122
-
106
+ **Generated TypeScript** (`user.ts`):
123
107
  ```typescript
124
- import { compile } from 'goscript';
125
- import * as path from 'path';
126
-
127
- async function runCompilation() {
128
- const exampleDir = path.resolve(__dirname, 'path/to/your/go/project'); // Adjust path accordingly
129
- const outputDir = path.join(exampleDir, 'ts_output');
130
-
131
- try {
132
- await compile({
133
- pkg: '.', // Compile the package in the exampleDir
134
- dir: exampleDir,
135
- output: outputDir,
136
- // Optional: specify path to goscript CLI if not in PATH or using go run
137
- // goscriptPath: '/path/to/goscript/executable'
138
- });
139
- console.log(`Compilation successful! Output in ${outputDir}`);
140
- } catch (error) {
141
- console.error('Compilation failed:', error);
108
+ export class User {
109
+ public ID: number = 0
110
+ public Name: string = ""
111
+ public Email: string = ""
112
+
113
+ public IsValid(): boolean {
114
+ const u = this
115
+ return u.Name !== "" && u.Email !== ""
142
116
  }
143
- }
144
117
 
145
- runCompilation();
146
- ```
118
+ constructor(init?: Partial<User>) {
119
+ if (init) Object.assign(this, init)
120
+ }
121
+ }
147
122
 
148
- This example imports the `compile` function, configures it to compile a Go package located in `exampleDir`, and outputs the TypeScript files to `outputDir`.
123
+ export function NewUser(id: number, name: string, email: string): User {
124
+ return new User({ ID: id, Name: name, Email: email })
125
+ }
149
126
 
150
- ## Roadmap
127
+ export function FindUserByEmail(users: User[], email: string): User | null {
128
+ for (let user of users) {
129
+ if (user.Email === email) {
130
+ return user
131
+ }
132
+ }
133
+ return null
134
+ }
135
+ ```
151
136
 
152
- Check [the compliance tests](./compliance/COMPLIANCE.md) for implementation progress.
137
+ **Use in your frontend:**
138
+ ```typescript
139
+ import { NewUser, FindUserByEmail } from '@goscript/myapp/user'
153
140
 
154
- - [X] Simple programs compile & run
155
- - [X] Compliance for basic language features complete
156
- - [X] Function coloring and async logic
157
- - [X] Work our way up to more complex programs
158
- - [ ] Implement most of the Go standard library
159
- - [ ] Generate init() function to recursively initialize packages
160
- - [ ] Tooling to integrate with typescript compiler
161
- - [ ] "go test" implementation with Go -> Ts transformation
162
- - vitest
163
- - [ ] performance testing
164
- - [ ] examples of calling Go code from TypeScript
141
+ // Same logic, now in TypeScript!
142
+ const users = [
143
+ NewUser(1, "Alice", "alice@example.com"),
144
+ NewUser(2, "Bob", "bob@example.com")
145
+ ]
165
146
 
166
- ## Generated Code
147
+ const alice = FindUserByEmail(users, "alice@example.com")
148
+ console.log(alice?.IsValid()) // true
149
+ ```
167
150
 
168
- Below is a simple example of how code is generated:
151
+ ### Example: Async Processing with Channels
169
152
 
153
+ **Go Code:**
170
154
  ```go
171
- package main
172
-
173
- // MyStruct demonstrates a simple struct with public and private fields.
174
- // It will be converted into a TypeScript class by goscript.
175
- type MyStruct struct {
176
- // MyInt is a public integer field, initialized to zero.
177
- MyInt int
178
- // MyString is a public string field, initialized to empty string.
179
- MyString string
180
- // myBool is a private boolean field, initialized to false.
181
- myBool bool
182
- }
183
-
184
- // GetMyString returns the MyString field.
185
- func (m *MyStruct) GetMyString() string {
186
- return m.MyString
155
+ func ProcessMessages(messages []string) chan string {
156
+ results := make(chan string, len(messages))
157
+
158
+ for _, msg := range messages {
159
+ go func(m string) {
160
+ // Simulate processing
161
+ processed := "โœ“ " + m
162
+ results <- processed
163
+ }(msg)
164
+ }
165
+
166
+ return results
187
167
  }
168
+ ```
188
169
 
189
- // GetMyBool returns the myBool field.
190
- func (m *MyStruct) GetMyBool() bool {
191
- return m.myBool
170
+ **Generated TypeScript:**
171
+ ```typescript
172
+ export function ProcessMessages(messages: string[]): $.Channel<string> {
173
+ let results = $.makeChannel<string>(messages.length, "")
174
+
175
+ for (let msg of messages) {
176
+ queueMicrotask(async (m: string) => {
177
+ let processed = "โœ“ " + m
178
+ await results.send(processed)
179
+ })(msg)
180
+ }
181
+
182
+ return results
192
183
  }
184
+ ```
193
185
 
194
- // NewMyStruct creates a new MyStruct instance.
195
- func NewMyStruct(s string) MyStruct {
196
- return MyStruct{MyString: s}
197
- }
186
+ **Use with async/await:**
187
+ ```typescript
188
+ import { ProcessMessages } from '@goscript/myapp/processor'
198
189
 
199
- func vals() (int, int) {
200
- return 1, 2
190
+ async function handleMessages() {
191
+ const channel = ProcessMessages(["hello", "world", "goscript"])
192
+
193
+ // Receive processed messages
194
+ for (let i = 0; i < 3; i++) {
195
+ const result = await channel.receive()
196
+ console.log(result) // "โœ“ hello", "โœ“ world", "โœ“ goscript"
197
+ }
201
198
  }
199
+ ```
202
200
 
203
- func main() {
204
- println("Hello from GoScript example!")
205
-
206
- // Basic arithmetic
207
- a, b := 10, 3
208
- println("Addition:", a+b, "Subtraction:", a-b, "Multiplication:", a*b, "Division:", a/b, "Modulo:", a%b)
209
-
210
- // Boolean logic and comparisons
211
- println("Logic &&:", true && false, "||:", true || false, "!:!", !true)
212
- println("Comparisons:", a == b, a != b, a < b, a > b, a <= b, a >= b)
213
-
214
- // string(rune) conversion
215
- var r rune = 'X'
216
- s := string(r)
217
- println("string('X'):", s)
201
+ ## ๐Ÿ› ๏ธ Integration & Usage
218
202
 
219
- var r2 rune = 121 // 'y'
220
- s2 := string(r2)
221
- println("string(121):", s2)
203
+ ### Command Line
222
204
 
223
- var r3 rune = 0x221A // 'โˆš'
224
- s3 := string(r3)
225
- println("string(0x221A):", s3)
205
+ ```bash
206
+ goscript compile --package ./my-go-code --output ./dist
207
+ ```
226
208
 
227
- // Arrays
228
- arr := [3]int{1, 2, 3}
229
- println("Array elements:", arr[0], arr[1], arr[2])
209
+ **Options:**
210
+ - `--package <path>` - Go package to compile (default: ".")
211
+ - `--output <dir>` - Output directory for TypeScript files
230
212
 
231
- // Slices - Basic initialization and access
232
- slice := []int{4, 5, 6}
233
- println("Slice elements:", slice[0], slice[1], slice[2])
234
- println("Slice length:", len(slice), "capacity:", cap(slice))
235
-
236
- sliceWithCap := make([]int, 3, 5)
237
- println("\nSlice created with make([]int, 3, 5):")
238
- println("Length:", len(sliceWithCap), "Capacity:", cap(sliceWithCap))
239
-
240
- println("\nAppend and capacity growth:")
241
- growingSlice := make([]int, 0, 2)
242
- println("Initial - Length:", len(growingSlice), "Capacity:", cap(growingSlice))
243
-
244
- for i := 1; i <= 4; i++ {
245
- growingSlice = append(growingSlice, i)
246
- println("After append", i, "- Length:", len(growingSlice), "Capacity:", cap(growingSlice))
247
- }
248
-
249
- println("\nSlicing operations and shared backing arrays:")
250
- original := []int{10, 20, 30, 40, 50}
251
- println("Original slice - Length:", len(original), "Capacity:", cap(original))
252
-
253
- slice1 := original[1:3]
254
- println("slice1 := original[1:3] - Values:", slice1[0], slice1[1])
255
- println("slice1 - Length:", len(slice1), "Capacity:", cap(slice1))
256
-
257
- slice2 := original[1:3:4]
258
- println("slice2 := original[1:3:4] - Values:", slice2[0], slice2[1])
259
- println("slice2 - Length:", len(slice2), "Capacity:", cap(slice2))
260
-
261
- println("\nShared backing arrays:")
262
- slice1[0] = 999
263
- println("After slice1[0] = 999:")
264
- println("original[1]:", original[1], "slice1[0]:", slice1[0], "slice2[0]:", slice2[0])
265
-
266
- sum := 0
267
- for idx, val := range slice {
268
- sum += val
269
- println("Range idx:", idx, "val:", val)
270
- }
271
- println("Range sum:", sum)
213
+ ### Programmatic API
272
214
 
273
- // Basic for loop
274
- prod := 1
275
- for i := 1; i <= 3; i++ {
276
- prod *= i
277
- }
278
- println("Product via for:", prod)
279
-
280
- // Struct, pointers, copy independence
281
- instance := NewMyStruct("go-script")
282
- println("instance.MyString:", instance.GetMyString())
283
- instance.MyInt = 42
284
- copyInst := instance
285
- copyInst.MyInt = 7
286
- println("instance.MyInt:", instance.MyInt, "copyInst.MyInt:", copyInst.MyInt)
287
-
288
- // Pointer initialization and dereference assignment
289
- ptr := new(MyStruct)
290
- ptr.MyInt = 9
291
- println("ptr.MyInt:", ptr.MyInt)
292
- deref := *ptr
293
- deref.MyInt = 8
294
- println("After deref assign, ptr.MyInt:", ptr.MyInt, "deref.MyInt:", deref.MyInt)
295
-
296
- // Method calls on pointer receiver
297
- ptr.myBool = true
298
- println("ptr.GetMyBool():", ptr.GetMyBool())
299
-
300
- // Composite literal assignment
301
- comp := MyStruct{MyInt: 100, MyString: "composite", myBool: false}
302
- println("comp fields:", comp.MyInt, comp.GetMyString(), comp.GetMyBool())
303
-
304
- // Multiple return values and blank identifier
305
- x, _ := vals()
306
- _, y := vals()
307
- println("vals x:", x, "y:", y)
308
-
309
- // If/else
310
- if a > b {
311
- println("If branch: a>b")
312
- } else {
313
- println("Else branch: a<=b")
314
- }
215
+ **Go:**
216
+ ```go
217
+ import "github.com/aperturerobotics/goscript/compiler"
315
218
 
316
- // Switch statement
317
- switch a {
318
- case 10:
319
- println("Switch case 10")
320
- default:
321
- println("Switch default")
322
- }
219
+ conf := &compiler.Config{OutputPath: "./dist"}
220
+ comp, err := compiler.NewCompiler(conf, logger, nil)
221
+ _, err = comp.CompilePackages(ctx, "your/package/path")
222
+ ```
323
223
 
324
- // Goroutines and Channels
325
- println("\nGoroutines and Channels:")
326
- ch := make(chan string)
327
- go func() {
328
- println("Goroutine: Sending message")
329
- ch <- "Hello from goroutine!"
330
- }()
331
-
332
- msg := <-ch
333
- println("Main goroutine: Received message:", msg)
334
-
335
- // Select statement
336
- println("\nSelect statement:")
337
- selectCh := make(chan string)
338
- go func() {
339
- selectCh <- "Message from select goroutine!"
340
- }()
341
- anotherCh := make(chan string)
342
- select {
343
- case selectMsg := <-selectCh:
344
- println("Select received:", selectMsg)
345
- case anotherMsg := <-anotherCh: // Add another case
346
- println("Select received from another channel:", anotherMsg)
347
- }
224
+ **Node.js:**
225
+ ```typescript
226
+ import { compile } from 'goscript'
348
227
 
349
- // Function Literals
350
- println("\nFunction Literals:")
351
- add := func(x, y int) int {
352
- return x + y
353
- }
354
- sum = add(5, 7)
355
- println("Function literal result:", sum)
356
- }
228
+ await compile({
229
+ pkg: './my-go-package',
230
+ output: './dist'
231
+ })
357
232
  ```
358
233
 
359
- Generated with `goscript compile .`:
234
+ ### Frontend Frameworks
360
235
 
236
+ **React + GoScript:**
361
237
  ```typescript
362
- import * as $ from "@goscript/builtin"
363
-
364
- class MyStruct {
365
- // MyInt is a public integer field, initialized to zero.
366
- public MyInt: number = 0
367
- // MyString is a public string field, initialized to empty string.
368
- public MyString: string = ""
369
- // myBool is a private boolean field, initialized to false.
370
- private myBool: boolean = false
371
-
372
- // GetMyString returns the MyString field.
373
- public GetMyString(): string {
374
- const m = this
375
- return m.MyString
376
- }
238
+ import { NewCalculator } from '@goscript/myapp/calculator'
377
239
 
378
- // GetMyBool returns the myBool field.
379
- public GetMyBool(): boolean {
380
- const m = this
381
- return m.myBool
240
+ function CalculatorApp() {
241
+ const [calc] = useState(() => NewCalculator())
242
+
243
+ const handleAdd = () => {
244
+ const result = calc.Add(5, 3)
245
+ setResult(result)
382
246
  }
383
247
 
384
- constructor(init?: Partial<MyStruct>) { if (init) Object.assign(this, init as any) }
385
- public clone(): MyStruct { return Object.assign(Object.create(MyStruct.prototype) as MyStruct, this) }
248
+ return <button onClick={handleAdd}>Add 5 + 3</button>
386
249
  }
250
+ ```
387
251
 
388
- // NewMyStruct creates a new MyStruct instance.
389
- export function NewMyStruct(s: string): MyStruct {
390
- return new MyStruct({ MyString: s })
391
- }
252
+ **Vue + GoScript:**
253
+ ```vue
254
+ <script setup lang="ts">
255
+ import { NewUser, FindUserByEmail } from '@goscript/myapp/user'
256
+
257
+ const users = ref([
258
+ NewUser(1, "Alice", "alice@example.com")
259
+ ])
392
260
 
393
- function vals(): [number, number] {
394
- return [1, 2]
261
+ const searchUser = (email: string) => {
262
+ return FindUserByEmail(users.value, email)
395
263
  }
264
+ </script>
265
+ ```
396
266
 
397
- export async function main(): Promise<void> {
398
- console.log("Hello from GoScript example!")
399
-
400
- // Basic arithmetic
401
- let a = 10
402
- let b = 3
403
- console.log("Addition:", a + b, "Subtraction:", a - b, "Multiplication:", a * b, "Division:", a / b, "Modulo:", a % b)
404
-
405
- // Boolean logic and comparisons
406
- console.log("Logic &&:", true && false, "||:", true || false, "!:!", !true)
407
- console.log("Comparisons:", a == b, a != b, a < b, a > b, a <= b, a >= b)
408
-
409
- // string(rune) conversion
410
- let r: number = 'X'
411
- let s = String.fromCharCode(r)
412
- console.log("string('X'):", s)
413
-
414
- // 'y'
415
- let r2: number = 121
416
- let s2 = String.fromCharCode(r2)
417
- console.log("string(121):", s2)
418
-
419
- // 'โˆš'
420
- let r3: number = 0x221A
421
- let s3 = String.fromCharCode(r3)
422
- console.log("string(0x221A):", s3)
423
-
424
- // Arrays
425
- let arr = $.arrayToSlice([1, 2, 3])
426
- console.log("Array elements:", arr![0], arr![1], arr![2])
427
-
428
- // Slices - Basic initialization and access
429
- let slice = $.arrayToSlice([4, 5, 6])
430
- console.log("Slice elements:", slice![0], slice![1], slice![2])
431
- console.log("Slice length:", $.len(slice), "capacity:", $.cap(slice))
432
-
433
- let sliceWithCap = $.makeSlice<number>(3, 5)
434
- console.log("\nSlice created with make([]int, 3, 5):")
435
- console.log("Length:", $.len(sliceWithCap), "Capacity:", $.cap(sliceWithCap))
436
-
437
- console.log("\nAppend and capacity growth:")
438
- let growingSlice = $.makeSlice<number>(0, 2)
439
- console.log("Initial - Length:", $.len(growingSlice), "Capacity:", $.cap(growingSlice))
440
-
441
- for (let i = 1; i <= 4; i++) {
442
- growingSlice = $.append(growingSlice, i)
443
- console.log("After append", i, "- Length:", $.len(growingSlice), "Capacity:", $.cap(growingSlice))
444
- }
267
+ ## ๐Ÿš€ What's Next?
445
268
 
446
- console.log("\nSlicing operations and shared backing arrays:")
447
- let original = $.arrayToSlice([10, 20, 30, 40, 50])
448
- console.log("Original slice - Length:", $.len(original), "Capacity:", $.cap(original))
449
-
450
- let slice1 = $.goSlice(original, 1, 3)
451
- console.log("slice1 := original[1:3] - Values:", slice1![0], slice1![1])
452
- console.log("slice1 - Length:", $.len(slice1), "Capacity:", $.cap(slice1))
453
-
454
- let slice2 = $.goSlice(original, 1, 3, 4)
455
- console.log("slice2 := original[1:3:4] - Values:", slice2![0], slice2![1])
456
- console.log("slice2 - Length:", $.len(slice2), "Capacity:", $.cap(slice2))
457
-
458
- console.log("\nShared backing arrays:")
459
- slice1![0] = 999
460
- console.log("After slice1[0] = 999:")
461
- console.log("original[1]:", original![1], "slice1[0]:", slice1![0], "slice2[0]:", slice2![0])
462
-
463
- let sum = 0
464
- for (let idx = 0; idx < slice.length; idx++) {
465
- const val = slice[idx]
466
- {
467
- sum += val
468
- console.log("Range idx:", idx, "val:", val)
469
- }
470
- }
471
- console.log("Range sum:", sum)
269
+ **Current Status:**
270
+ - โœ… Core language features (structs, methods, interfaces)
271
+ - โœ… Async/await for goroutines and channels
272
+ - โœ… Basic reflection support
273
+ - โœ… Most control flow and data types
472
274
 
473
- // Basic for loop
474
- let prod = 1
475
- for (let i = 1; i <= 3; i++) {
476
- prod *= i
477
- }
478
- console.log("Product via for:", prod)
479
-
480
- // Struct, pointers, copy independence
481
- let instance = NewMyStruct("go-script").clone()
482
- console.log("instance.MyString:", instance.GetMyString())
483
- instance.MyInt = 42
484
- let copyInst = instance.clone()
485
- copyInst.MyInt = 7
486
- console.log("instance.MyInt:", instance.MyInt, "copyInst.MyInt:", copyInst.MyInt)
487
-
488
- // Pointer initialization and dereference assignment
489
- let ptr = new MyStruct()
490
- ptr.MyInt = 9
491
- console.log("ptr.MyInt:", ptr.MyInt)
492
- let deref = ptr.clone()
493
- deref.MyInt = 8
494
- console.log("After deref assign, ptr.MyInt:", ptr.MyInt, "deref.MyInt:", deref.MyInt)
495
-
496
- // Method calls on pointer receiver
497
- ptr.myBool = true
498
- console.log("ptr.GetMyBool():", ptr.GetMyBool())
499
-
500
- // Composite literal assignment
501
- let comp = new MyStruct({ MyInt: 100, MyString: "composite", myBool: false }).clone()
502
- console.log("comp fields:", comp.MyInt, comp.GetMyString(), comp.GetMyBool())
503
-
504
- // Multiple return values and blank identifier
505
- let [x, ] = vals()
506
- let [, y] = vals()
507
- console.log("vals x:", x, "y:", y)
508
-
509
- // If/else
510
- if (a > b) {
511
- console.log("If branch: a>b")
512
- } else {
513
- console.log("Else branch: a<=b")
514
- }
275
+ **Coming Soon:**
276
+ - ๐Ÿ“ฆ Expanded standard library
277
+ - ๐Ÿงช Go test โ†’ TypeScript test conversion
278
+ - โšก Performance optimizations
279
+ - ๐Ÿ”ง Better tooling integration
515
280
 
516
- // Switch statement
517
- switch (a) {
518
- case 10:
519
- console.log("Switch case 10")
520
- break
521
- default:
522
- console.log("Switch default")
523
- break
524
- }
281
+ Check our [compliance tests](./compliance/COMPLIANCE.md) for detailed progress.
525
282
 
526
- // Goroutines and Channels
527
- console.log("\nGoroutines and Channels:")
528
- let ch = $.makeChannel<string>(0, "")
529
- queueMicrotask(async () => {
530
- {
531
- console.log("Goroutine: Sending message")
532
- await ch.send("Hello from goroutine!")
533
- }
534
- })
283
+ ## ๐Ÿค Real-World Use Cases
535
284
 
536
- let msg = await ch.receive()
537
- console.log("Main goroutine: Received message:", msg)
285
+ **Fintech:** Share complex financial calculations between Go services and trading dashboards
538
286
 
539
- // Select statement
540
- console.log("\nSelect statement:")
541
- let selectCh = $.makeChannel<string>(0, "")
542
- queueMicrotask(async () => {
543
- {
544
- await selectCh.send("Message from select goroutine!")
545
- }
546
- })
547
- let anotherCh = $.makeChannel<string>(0, "")
548
-
549
- // Add another case
550
- await $.selectStatement([
551
- {
552
- id: 0,
553
- isSend: false,
554
- channel: selectCh,
555
- onSelected: async (result) => {
556
- const selectMsg = result.value
557
- console.log("Select received:", selectMsg)
558
- }
559
- },
560
- {
561
- id: 1,
562
- isSend: false,
563
- channel: anotherCh,
564
- onSelected: async (result) => {
565
- const anotherMsg = result.value
566
- console.log("Select received from another channel:", anotherMsg)
567
- }
568
- },
569
- ], false)
570
-
571
- // Function Literals
572
- console.log("\nFunction Literals:")
573
- let add = (x: number, y: number): number => {
574
- return x + y
575
- }
576
- sum = add(5, 7)
577
- console.log("Function literal result:", sum)
578
- }
579
- ```
287
+ **Gaming:** Run the same game logic on servers and in browser clients
580
288
 
581
- Code is compiled with `GOARCH=js` and uses a 32-bit environment similar to wasm.
289
+ **Data Processing:** Use identical algorithms for backend ETL and frontend analytics
582
290
 
583
- All Go import paths are prefixed with `@goscript/` and can be imported in TypeScript:
291
+ **Validation:** Keep business rules consistent across your entire stack
584
292
 
585
- ```typescript
586
- import { MyAsyncFunction, MyStruct } from '@goscript/github.com/myorg/mypackage';
587
-
588
- // Example of importing and using a compiled Go async function
589
- async function runGoCode() {
590
- // Call an async function compiled from Go
591
- const result = await MyAsyncFunction("input data");
592
- console.log("Result from Go async function:", result);
593
-
594
- // You can still use synchronous types and functions
595
- let myThing = new MyStruct();
596
- myThing.GetMyString();
597
- runGoCode();
598
- }
599
- ```
293
+ Ready to eliminate code duplication? [Get started now](#-get-started-in-2-minutes) ๐Ÿš€
600
294
 
601
295
  ## License
602
296