From 45366ddde5e7f81eb14fa58b06c9b694739c510c Mon Sep 17 00:00:00 2001 From: PJ Date: Mon, 1 Jun 2026 16:43:50 +0530 Subject: [PATCH] feat(bundler): optional RuntimeFile prepends a runtime-entry import via stdin --- internal/bundler/bundler.go | 54 ++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/internal/bundler/bundler.go b/internal/bundler/bundler.go index b26dca6..0916f07 100644 --- a/internal/bundler/bundler.go +++ b/internal/bundler/bundler.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "path/filepath" "strings" esbuild "github.com/evanw/esbuild/pkg/api" @@ -13,9 +14,14 @@ import ( type Options struct { EntryFile string - Defines map[string]string - Aliases map[string]string - Sourcemap bool + // RuntimeFile, when set, is imported BEFORE the spec via a stdin entry so + // the bundle installs __sanderlingNextAction__ / __sanderlingExtractors__ + // (the goja runtime entry wires the shared picker). Empty bundles the spec + // alone, as the bundle-check tool and unit fixtures do. + RuntimeFile string + Defines map[string]string + Aliases map[string]string + Sourcemap bool } type Result struct { @@ -45,18 +51,36 @@ func Bundle(options Options) (Result, error) { sourcemap = esbuild.SourceMapInline } - output := esbuild.Build(esbuild.BuildOptions{ - EntryPoints: []string{options.EntryFile}, - Bundle: true, - Format: esbuild.FormatIIFE, - Target: esbuild.ES2020, - Platform: esbuild.PlatformNeutral, - Define: defines, - Alias: options.Aliases, - Sourcemap: sourcemap, - Write: false, - LogLevel: esbuild.LogLevelSilent, - }) + buildOptions := esbuild.BuildOptions{ + Bundle: true, + Format: esbuild.FormatIIFE, + Target: esbuild.ES2020, + Platform: esbuild.PlatformNeutral, + Define: defines, + Alias: options.Aliases, + Sourcemap: sourcemap, + Write: false, + LogLevel: esbuild.LogLevelSilent, + } + if options.RuntimeFile == "" { + buildOptions.EntryPoints = []string{options.EntryFile} + } else { + runtimeAbs, err := filepath.Abs(options.RuntimeFile) + if err != nil { + return Result{}, fmt.Errorf("runtime path: %w", err) + } + specAbs, err := filepath.Abs(options.EntryFile) + if err != nil { + return Result{}, fmt.Errorf("entry path: %w", err) + } + buildOptions.Stdin = &esbuild.StdinOptions{ + Contents: fmt.Sprintf("import %q;\nimport %q;\n", runtimeAbs, specAbs), + ResolveDir: filepath.Dir(specAbs), + Loader: esbuild.LoaderTS, + } + } + + output := esbuild.Build(buildOptions) if len(output.Errors) > 0 { var messages []string