Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize memory usage #16

Merged
merged 2 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This package provides a thin wrapper around [goja](https://github.com/dop251/goj
* AMD-style modules using the built-in [Almond module loader](https://github.com/requirejs/almond).
* Custom Typescript version registration with built-in support for versions 3.8.3, 3.9.9, 4.1.2, 4.1.3, 4.1.4, 4.1.5, 4.2.2, 4.2.3, 4.2.4, and 4.7.2.
* 90%+ test coverage
* Used in production world-wide (sponsoring company has evaluated over 1 billion scripts using this runtime)

## Installation

Expand Down
29 changes: 14 additions & 15 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ type TranspileOptionFunc func(*Config)

// Config defines the behavior of the typescript compiler.
type Config struct {
CompileOptions map[string]interface{}
TypescriptSource *goja.Program
Runtime *goja.Runtime
CompileOptions map[string]interface{}
TypescriptVersion string
Registry versions.Registry
Runtime *goja.Runtime

// If a module is exported by the typescript compiler, this is the name the module will be called
ModuleName string
Expand Down Expand Up @@ -58,26 +59,24 @@ func (c *Config) Initialize() error {
// typescript source code.s
func NewDefaultConfig() *Config {
return &Config{
Runtime: goja.New(),
CompileOptions: nil,
TypescriptSource: versions.DefaultRegistry.MustGet("v4.9.3"),
ModuleName: "default",
Runtime: goja.New(),
CompileOptions: nil,
TypescriptVersion: "v4.9.3",
Registry: versions.NewRegistry(),
ModuleName: "default",
}
}

// WithVersion loads the provided tagged typescript source from the default registry
func WithVersion(tag string) TranspileOptionFunc {
func WithRegistry(registry versions.Registry) TranspileOptionFunc {
return func(config *Config) {
config.TypescriptSource = versions.DefaultRegistry.MustGet(tag)
config.Registry = registry
}
}

// WithTypescriptSource configures a Typescript source from the provided typescript source string which
// is compiled by goja when the config is initialized. This function will panic if the Typescript source
// is invalid.
func WithTypescriptSource(src string) TranspileOptionFunc {
// WithVersion loads the provided tagged typescript source from the default registry
func WithVersion(tag string) TranspileOptionFunc {
return func(config *Config) {
config.TypescriptSource = goja.MustCompile("", src, true)
config.TypescriptVersion = tag
}
}

Expand Down
116 changes: 40 additions & 76 deletions config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ package typescript
import (
"fmt"
"github.com/clarkmcc/go-typescript/versions"
_ "github.com/clarkmcc/go-typescript/versions/v3.8.3"
_ "github.com/clarkmcc/go-typescript/versions/v3.9.9"
_ "github.com/clarkmcc/go-typescript/versions/v4.1.2"
_ "github.com/clarkmcc/go-typescript/versions/v4.1.3"
_ "github.com/clarkmcc/go-typescript/versions/v4.1.4"
_ "github.com/clarkmcc/go-typescript/versions/v4.1.5"
_ "github.com/clarkmcc/go-typescript/versions/v4.2.2"
v423 "github.com/clarkmcc/go-typescript/versions/v4.2.3"
_ "github.com/clarkmcc/go-typescript/versions/v4.2.4"
_ "github.com/clarkmcc/go-typescript/versions/v4.7.2"
v3_8_3 "github.com/clarkmcc/go-typescript/versions/v3.8.3"
v3_9_9 "github.com/clarkmcc/go-typescript/versions/v3.9.9"
v4_1_2 "github.com/clarkmcc/go-typescript/versions/v4.1.2"
v4_1_3 "github.com/clarkmcc/go-typescript/versions/v4.1.3"
v4_1_4 "github.com/clarkmcc/go-typescript/versions/v4.1.4"
v4_1_5 "github.com/clarkmcc/go-typescript/versions/v4.1.5"
v4_2_2 "github.com/clarkmcc/go-typescript/versions/v4.2.2"
v4_2_3 "github.com/clarkmcc/go-typescript/versions/v4.2.3"
v4_2_4 "github.com/clarkmcc/go-typescript/versions/v4.2.4"
v4_7_2 "github.com/clarkmcc/go-typescript/versions/v4.7.2"
v4_9_3 "github.com/clarkmcc/go-typescript/versions/v4.9.3"
"github.com/stretchr/testify/require"
"testing"
)
Expand All @@ -26,82 +27,45 @@ func TestConfig_Initialize(t *testing.T) {
}

func TestVersionLoading(t *testing.T) {
t.Run("v3.8.3", func(t *testing.T) {
output, err := TranspileString("let a: number = 10;", WithVersion("v3.8.3"))
require.NoError(t, err)
require.Equal(t, "var a = 10;", output)
})
t.Run("v3.9.9", func(t *testing.T) {
output, err := TranspileString("let a: number = 10;", WithVersion("v3.9.9"))
require.NoError(t, err)
require.Equal(t, "var a = 10;", output)
})
t.Run("v4.1.2", func(t *testing.T) {
output, err := TranspileString("let a: number = 10;", WithVersion("v4.1.2"))
require.NoError(t, err)
require.Equal(t, "var a = 10;", output)
})
t.Run("v4.1.3", func(t *testing.T) {
output, err := TranspileString("let a: number = 10;", WithVersion("v4.1.3"))
require.NoError(t, err)
require.Equal(t, "var a = 10;", output)
})
t.Run("v4.1.4", func(t *testing.T) {
output, err := TranspileString("let a: number = 10;", WithVersion("v4.1.4"))
require.NoError(t, err)
require.Equal(t, "var a = 10;", output)
})
t.Run("v4.1.5", func(t *testing.T) {
output, err := TranspileString("let a: number = 10;", WithVersion("v4.1.5"))
require.NoError(t, err)
require.Equal(t, "var a = 10;", output)
})
t.Run("v4.2.2", func(t *testing.T) {
output, err := TranspileString("let a: number = 10;", WithVersion("v4.2.2"))
require.NoError(t, err)
require.Equal(t, "var a = 10;", output)
})
t.Run("v4.2.3", func(t *testing.T) {
output, err := TranspileString("let a: number = 10;", WithVersion("v4.2.3"))
require.NoError(t, err)
require.Equal(t, "var a = 10;", output)
})
t.Run("v4.2.4", func(t *testing.T) {
output, err := TranspileString("let a: number = 10;", WithVersion("v4.2.4"))
require.NoError(t, err)
require.Equal(t, "var a = 10;", output)
})
t.Run("v4.7.2", func(t *testing.T) {
output, err := TranspileString("let a: number = 10;", WithVersion("v4.7.2"))
require.NoError(t, err)
require.Equal(t, "var a = 10;", output)
})
}

func TestCustomRegistry(t *testing.T) {
registry := versions.NewRegistry()
registry.MustRegister("v4.2.3", v423.Source)

output, err := TranspileString("let a: number = 10;", func(config *Config) {
config.TypescriptSource = registry.MustGet("v4.2.3")
})
require.NoError(t, err)
require.Equal(t, "var a = 10;", output)
sources := map[string]string{
"v3.8.3": v3_8_3.Source,
"v3.9.9": v3_9_9.Source,
"v4.1.2": v4_1_2.Source,
"v4.1.3": v4_1_3.Source,
"v4.1.4": v4_1_4.Source,
"v4.1.5": v4_1_5.Source,
"v4.2.2": v4_2_2.Source,
"v4.2.3": v4_2_3.Source,
"v4.2.4": v4_2_4.Source,
"v4.7.2": v4_7_2.Source,
"v4.9.3": v4_9_3.Source,
}

for tag, source := range sources {
registry.Register(tag, source)
}

for tag, _ := range sources {
t.Run(tag, func(t *testing.T) {
output, err := TranspileString("let a: number = 10;", WithRegistry(registry), WithVersion(tag))
require.NoError(t, err)
require.Equal(t, "var a = 10;", output)
})
}
}

func TestWithModuleName(t *testing.T) {
registry := versions.NewRegistry()
registry.Register("v4.9.3", v4_9_3.Source)
output, err := TranspileString("let a: number = 10;",
WithModuleName("myModuleName"),
WithRegistry(registry),
WithVersion("v4.9.3"),
WithCompileOptions(map[string]interface{}{
"module": "amd",
}))
require.NoError(t, err)
require.Contains(t, output, "define(\"myModuleName\"")
}

func TestWithTypescriptSource(t *testing.T) {
output, err := TranspileString("let a: number = 10;",
WithTypescriptSource(v423.Source))
require.NoError(t, err)
require.Equal(t, "var a = 10;", output)
}
2 changes: 1 addition & 1 deletion evaluate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strings"

"github.com/clarkmcc/go-typescript/packages"
_ "github.com/clarkmcc/go-typescript/versions/v4.7.2"
_ "github.com/clarkmcc/go-typescript/versions/v4.9.3"
"github.com/dop251/goja"
)

Expand Down
9 changes: 9 additions & 0 deletions evaluate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"errors"
"fmt"
"github.com/clarkmcc/go-typescript/versions"
v4_9_3 "github.com/clarkmcc/go-typescript/versions/v4.9.3"
"github.com/dop251/goja"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand All @@ -24,6 +26,9 @@ var (
)

func TestEvaluateCtx(t *testing.T) {
registry := versions.NewRegistry()
registry.Register("v4.9.3", v4_9_3.Source)

// This test hits a lot of things:
// #1 - We test that we can load the almond AMD module loader
// #2 - We test that we can load our own 'evaluate before' script that declares an AMD module
Expand All @@ -33,6 +38,8 @@ func TestEvaluateCtx(t *testing.T) {
result, err := EvaluateCtx(context.Background(), strings.NewReader(script),
WithAlmondModuleLoader(),
WithTranspile(),
WithTranspileOptions(WithRegistry(registry),
WithVersion("v4.9.3")),
WithEvaluateBefore(strings.NewReader(amdModuleScript)),
WithTranspileOptions(func(config *Config) {
config.Verbose = true
Expand Down Expand Up @@ -100,6 +107,8 @@ func TestEvaluateCtx(t *testing.T) {
s1 := "let a: number = 10"
_, err := Evaluate(strings.NewReader(s1),
WithTranspile(),
WithTranspileOptions(WithRegistry(registry),
WithVersion("v4.9.3")),
WithScriptPreTranspileHook(func(s2 string) (string, error) {
assert.Equal(t, s1, s2)
return s2, nil
Expand Down
11 changes: 10 additions & 1 deletion examples/typescript_amd_modules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,26 @@ import (
_ "embed"
"fmt"
"github.com/clarkmcc/go-typescript"
"github.com/clarkmcc/go-typescript/versions"
v4_9_3 "github.com/clarkmcc/go-typescript/versions/v4.9.3"
"strings"
)

//go:embed javascript-example-module.js
var module string

func ExampleTypescriptAMDModule() {
registry := versions.NewRegistry()
registry.Register("v4.9.3", v4_9_3.Source)

result, err := typescript.Evaluate(strings.NewReader(`import { multiply } from 'myModule'; multiply(5, 5)`),
typescript.WithTranspile(),
typescript.WithAlmondModuleLoader(),
typescript.WithEvaluateBefore(strings.NewReader(module)))
typescript.WithEvaluateBefore(strings.NewReader(module)),
typescript.WithTranspileOptions(
typescript.WithRegistry(registry),
typescript.WithVersion("v4.9.3"),
))
if err != nil {
panic(err)
}
Expand Down
10 changes: 9 additions & 1 deletion examples/typescript_context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
_ "embed"
"fmt"
"github.com/clarkmcc/go-typescript"
"github.com/clarkmcc/go-typescript/versions"
v4_9_3 "github.com/clarkmcc/go-typescript/versions/v4.9.3"
"strings"
)

Expand All @@ -15,7 +17,13 @@ func ExampleContext() {
ctx, cancel := context.WithCancel(context.Background())
cancel()

_, err := typescript.TranspileCtx(ctx, strings.NewReader(script3))
registry := versions.NewRegistry()
registry.Register("v4.9.3", v4_9_3.Source)

_, err := typescript.TranspileCtx(ctx,
strings.NewReader(script3),
typescript.WithRegistry(registry),
typescript.WithVersion("v4.9.3"))
if err == nil {
panic("expected error")
}
Expand Down
10 changes: 9 additions & 1 deletion examples/typescript_evaluate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@ import (
_ "embed"
"fmt"
"github.com/clarkmcc/go-typescript"
"github.com/clarkmcc/go-typescript/versions"
v4_9_3 "github.com/clarkmcc/go-typescript/versions/v4.9.3"
"strings"
)

//go:embed typescript-example.ts
var script2 string

func ExampleTypescriptEvaluate() {
registry := versions.NewRegistry()
registry.Register("v4.9.3", v4_9_3.Source)

// Transpile the typescript and return evaluated result
result, err := typescript.Evaluate(strings.NewReader(script2), typescript.WithTranspile())
result, err := typescript.Evaluate(strings.NewReader(script2), typescript.WithTranspile(), typescript.WithTranspileOptions(
typescript.WithRegistry(registry),
typescript.WithVersion("v4.9.3"),
))
if err != nil {
panic(err)
}
Expand Down
7 changes: 6 additions & 1 deletion examples/typescript_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
_ "embed"
"fmt"
"github.com/clarkmcc/go-typescript"
"github.com/clarkmcc/go-typescript/versions"
v4_9_3 "github.com/clarkmcc/go-typescript/versions/v4.9.3"
"strings"
)

Expand All @@ -24,8 +26,11 @@ var me = new Person("John Doe");
me.greet();`

func ExampleTranspile() {
registry := versions.NewRegistry()
registry.Register("v4.9.3", v4_9_3.Source)

// Only transpile the typescript and return transpiled Javascript, don't evaluate
transpiled, err := typescript.TranspileString(script1)
transpiled, err := typescript.TranspileString(script1, typescript.WithRegistry(registry), typescript.WithVersion("v4.9.3"))
if err != nil {
panic(err)
}
Expand Down
6 changes: 5 additions & 1 deletion transpiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ func TranspileCtx(ctx context.Context, script io.Reader, opts ...TranspileOption
if err != nil {
return "", fmt.Errorf("initializing config: %w", err)
}
_, err = cfg.Runtime.RunProgram(cfg.TypescriptSource)
src, err := cfg.Registry.Get(cfg.TypescriptVersion)
if err != nil {
return "", fmt.Errorf("getting typescript source: %w", err)
}
_, err = cfg.Runtime.RunProgram(src)
if err != nil {
return "", fmt.Errorf("running typescript compiler: %w", err)
}
Expand Down
Loading
Loading