goscript 0.0.69 → 0.0.71

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.
@@ -0,0 +1,46 @@
1
+ //go:build js && wasm
2
+
3
+ package main
4
+
5
+ import (
6
+ "syscall/js"
7
+
8
+ "github.com/aperturerobotics/goscript/compiler/wasm"
9
+ )
10
+
11
+ func main() {
12
+ // Register the compile function as a global JavaScript function
13
+ js.Global().Set("goscriptCompile", js.FuncOf(compileWrapper))
14
+
15
+ // Keep the program running
16
+ select {}
17
+ }
18
+
19
+ // compileWrapper wraps the compile function for JavaScript interop
20
+ func compileWrapper(this js.Value, args []js.Value) interface{} {
21
+ if len(args) < 1 {
22
+ return map[string]interface{}{
23
+ "error": "missing source code argument",
24
+ "output": "",
25
+ }
26
+ }
27
+
28
+ source := args[0].String()
29
+ packageName := "main"
30
+ if len(args) > 1 {
31
+ packageName = args[1].String()
32
+ }
33
+
34
+ output, err := wasm.CompileSource(source, packageName)
35
+ if err != nil {
36
+ return map[string]interface{}{
37
+ "error": err.Error(),
38
+ "output": "",
39
+ }
40
+ }
41
+
42
+ return map[string]interface{}{
43
+ "error": "",
44
+ "output": output,
45
+ }
46
+ }
@@ -0,0 +1,12 @@
1
+ // Package wasm provides a WASM-friendly API for compiling Go source code to TypeScript.
2
+ package wasm
3
+
4
+ import (
5
+ "github.com/aperturerobotics/goscript/compiler"
6
+ )
7
+
8
+ // CompileSource compiles Go source code to TypeScript.
9
+ // It takes the source code as a string and returns the generated TypeScript.
10
+ func CompileSource(source string, packageName string) (string, error) {
11
+ return compiler.CompileSourceToTypeScript(source, packageName)
12
+ }
@@ -0,0 +1,160 @@
1
+ package compiler
2
+
3
+ import (
4
+ "bytes"
5
+ "fmt"
6
+ "go/ast"
7
+ "go/importer"
8
+ "go/parser"
9
+ "go/token"
10
+ "go/types"
11
+ "io"
12
+
13
+ "golang.org/x/tools/go/packages"
14
+ )
15
+
16
+ // CompileSourceToTypeScript compiles Go source code directly to TypeScript.
17
+ // This is a WASM-friendly API that bypasses filesystem operations.
18
+ // It takes the source code as a string and returns the generated TypeScript.
19
+ func CompileSourceToTypeScript(source string, packageName string) (string, error) {
20
+ if packageName == "" {
21
+ packageName = "main"
22
+ }
23
+
24
+ // Create a new file set for position information
25
+ fset := token.NewFileSet()
26
+
27
+ // Parse the source code
28
+ astFile, err := parser.ParseFile(fset, "main.go", source, parser.ParseComments)
29
+ if err != nil {
30
+ return "", fmt.Errorf("parse error: %w", err)
31
+ }
32
+
33
+ // Create type checker configuration with a custom importer
34
+ var typeErrors []error
35
+ conf := types.Config{
36
+ Importer: &wasmImporter{
37
+ defaultImporter: importer.Default(),
38
+ cache: make(map[string]*types.Package),
39
+ },
40
+ Error: func(err error) {
41
+ // Collect errors but don't fail immediately
42
+ typeErrors = append(typeErrors, err)
43
+ },
44
+ }
45
+
46
+ // Type check the package
47
+ info := &types.Info{
48
+ Types: make(map[ast.Expr]types.TypeAndValue),
49
+ Defs: make(map[*ast.Ident]types.Object),
50
+ Uses: make(map[*ast.Ident]types.Object),
51
+ Implicits: make(map[ast.Node]types.Object),
52
+ Selections: make(map[*ast.SelectorExpr]*types.Selection),
53
+ Scopes: make(map[ast.Node]*types.Scope),
54
+ Instances: make(map[*ast.Ident]types.Instance),
55
+ }
56
+
57
+ pkg, _ := conf.Check(packageName, fset, []*ast.File{astFile}, info)
58
+ // We continue even with type check errors for playground flexibility
59
+
60
+ // Create a packages.Package compatible structure
61
+ pkgData := &packages.Package{
62
+ ID: packageName,
63
+ Name: astFile.Name.Name,
64
+ PkgPath: packageName,
65
+ Fset: fset,
66
+ Syntax: []*ast.File{astFile},
67
+ Types: pkg,
68
+ TypesInfo: info,
69
+ CompiledGoFiles: []string{"main.go"},
70
+ }
71
+
72
+ // Create an empty map for all packages (we only have one)
73
+ allPackages := map[string]*packages.Package{
74
+ packageName: pkgData,
75
+ }
76
+
77
+ // Perform package-level analysis
78
+ packageAnalysis := AnalyzePackageImports(pkgData)
79
+ analysis := AnalyzePackageFiles(pkgData, allPackages)
80
+
81
+ // Create a buffer to capture the output
82
+ var buf bytes.Buffer
83
+
84
+ // Create the file compiler
85
+ fileCompiler := &FileCompiler{
86
+ compilerConfig: &Config{},
87
+ pkg: pkgData,
88
+ ast: astFile,
89
+ fullPath: "main.go",
90
+ Analysis: analysis,
91
+ PackageAnalysis: packageAnalysis,
92
+ }
93
+
94
+ // Compile to the buffer
95
+ if err := fileCompiler.CompileToWriter(&buf); err != nil {
96
+ return "", fmt.Errorf("compilation error: %w", err)
97
+ }
98
+
99
+ return buf.String(), nil
100
+ }
101
+
102
+ // CompileToWriter compiles the Go file and writes TypeScript to the given writer.
103
+ // This is used for WASM compilation where we don't want file I/O.
104
+ func (c *FileCompiler) CompileToWriter(w io.Writer) error {
105
+ f := c.ast
106
+
107
+ c.codeWriter = NewTSCodeWriter(w)
108
+
109
+ // Pass analysis to compiler
110
+ goWriter := NewGoToTSCompiler(c.codeWriter, c.pkg, c.Analysis, c.fullPath)
111
+
112
+ // Add import for the goscript runtime using namespace import and alias
113
+ c.codeWriter.WriteLinef("import * as $ from %q", "@goscript/builtin/index.js")
114
+
115
+ c.codeWriter.WriteLine("") // Add a newline after imports
116
+
117
+ if err := goWriter.WriteDecls(f.Decls); err != nil {
118
+ return fmt.Errorf("failed to write declarations: %w", err)
119
+ }
120
+
121
+ return nil
122
+ }
123
+
124
+ // wasmImporter provides import resolution for WASM compilation.
125
+ // It wraps the default importer and provides stubs for common packages.
126
+ type wasmImporter struct {
127
+ defaultImporter types.Importer
128
+ cache map[string]*types.Package
129
+ }
130
+
131
+ func (i *wasmImporter) Import(path string) (*types.Package, error) {
132
+ if pkg, ok := i.cache[path]; ok {
133
+ return pkg, nil
134
+ }
135
+
136
+ // Try the default importer first (works for stdlib packages)
137
+ pkg, err := i.defaultImporter.Import(path)
138
+ if err == nil {
139
+ i.cache[path] = pkg
140
+ return pkg, nil
141
+ }
142
+
143
+ // For unknown packages, create an empty stub package
144
+ // This allows compilation to proceed even if dependencies aren't available
145
+ stubPkg := types.NewPackage(path, pathToName(path))
146
+ stubPkg.MarkComplete()
147
+ i.cache[path] = stubPkg
148
+ return stubPkg, nil
149
+ }
150
+
151
+ // pathToName extracts a package name from an import path
152
+ func pathToName(path string) string {
153
+ // Find the last component of the path
154
+ for i := len(path) - 1; i >= 0; i-- {
155
+ if path[i] == '/' {
156
+ return path[i+1:]
157
+ }
158
+ }
159
+ return path
160
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "goscript",
3
3
  "description": "Go to TypeScript transpiler",
4
- "version": "0.0.69",
4
+ "version": "0.0.71",
5
5
  "author": {
6
6
  "name": "Aperture Robotics LLC.",
7
7
  "email": "support@aperture.us",