client

package module
v0.3.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 16, 2025 License: MIT Imports: 13 Imported by: 0

README

tinywasm

Project Badges

Go package for intelligent WebAssembly compilation with automatic file detection and 3-mode compiler system.

Features

  • 3-Mode Compiler System: Large ("L"), Medium ("M"), Small ("S")
  • DevTUI Integration: FieldHandler interface for interactive mode switching
  • Smart file detection via prefixes (frontend/backend separation)
  • Triple compiler support: Go standard (fast dev), TinyGo debug (-opt=1), TinyGo production (-opt=z)
  • VS Code auto-configuration for WASM development
  • Dual Output Architecture: WASM binaries in src/web/public/, watchable JS in src/web/ui/js/

Quick Start

// Basic usage
config := tinywasm.NewConfig() // Pre-configured with defaults
config.SourceDir = "src/cmd/webclient"
config.OutputDir = "src/web/public"
config.WasmExecJsOutputDir = "src/web/ui/js"

tw := tinywasm.New(config)
tw.NewFileEvent("src/cmd/webclient/main.go", ".go", "src/cmd/webclient/main.go", "write")

// DevTUI Integration - 3 Mode System
fmt.Println("Current mode:", tw.Value()) // "L" (coding / large build)

// New API: Change now reports progress via a channel instead of returning (msg, err).
// Create and consume a progress channel before calling Change to avoid blocking.
progress := make(chan string)
go func() {
	for p := range progress {
		fmt.Println("Status:", p)
	}
}()
tw.Change("M", progress) // Switch to medium (debug) mode; messages arrive on the progress channel

// Advanced configuration
config := &tinywasm.Config{
    AppRootDir:          "/path/to/project",
    SourceDir:           "src/cmd/webclient",
    OutputDir:           "src/web/public",
    WasmExecJsOutputDir: "src/web/ui/js",
    MainInputFile:       "main.go",
    OutputName:          "main",
	BuildLargeSizeShortcut:   "L",  // Customizable shortcuts (default: L = Large/fast with go)
	BuildMediumSizeShortcut:    "M",
	BuildSmallSizeShortcut: "S",
    Logger:              logger,
}

DevTUI FieldHandler Interface

TinyWasm implements the DevTUI FieldHandler interface for interactive development:

// DevTUI Integration
label := tw.Label()           // "Compiler Mode"
current := tw.Value()         // Current mode shortcut ("L", "M", "S")
canEdit := tw.Editable()      // true
timeout := tw.Timeout()       // 0 (no timeout)

// Interactive mode change with the new Change API
// Change now has signature: Change(newValue string, progress chan<- string)
// All validation messages, warnings (e.g. auto-compilation failed) and success
// messages are sent through the provided channel. The channel is closed when
// the operation completes.
progress := make(chan string)
go func() {
	for p := range progress {
		// Handle progress messages (show in TUI, log, etc.)
		fmt.Println("Progress:", p)
	}
}()
tw.Change("M", progress)
// No return values; read errors and status from the progress channel above.

VS Code Integration

Auto-creates .vscode/settings.json with WASM environment:

{"gopls": {"env": {"GOOS": "js", "GOARCH": "wasm"}}}

API

Core:

  • New(config *Config) *TinyWasm
  • NewConfig() *Config - Pre-configured with sensible defaults
  • NewFileEvent(fileName, ext, path, event string) error
  • ShouldCompileToWasm(fileName, path string) bool

DevTUI FieldHandler Interface:

  • Label() string - Returns "Compiler Mode"
  • Value() string - Current mode shortcut ("L", "M", "S")
  • Editable() bool - Returns true (field is editable)
  • Change(newValue string, progress chan<- string) - Switch compiler mode and report progress via the provided channel. Validation errors, auto-compilation warnings and success messages are sent to the channel; the implemention closes the channel when finished.
  • Timeout() time.Duration - Returns 0 (no timeout)

Legacy Compiler Methods (deprecated):

  • TinyGoCompiler() bool - Use Value() instead
  • SetTinyGoCompiler(bool) error - Use Change() instead
  • VerifyTinyGoInstallation() error

Utils:

  • MainInputFileRelativePath() string
  • UnobservedFiles() []string
  • JavascriptForInitializing() (string, error)

Config

type Config struct {
	AppRootDir          string        // application root directory (absolute), defaults to "."
	SourceDir           string        // directory containing Go source (relative) eg: "src/cmd/webclient"
	OutputDir           string        // directory for WASM binary output (relative) eg: "src/web/public"
	WasmExecJsOutputDir string        // directory for watchable JS runtime (relative) eg: "src/web/ui/js"
	MainInputFile       string        // main input file for WASM compilation (default: "main.go")
	OutputName          string        // output name for WASM file (default: "main")
	Logger              func(message ...any) // For logging output to external systems (e.g., TUI, console)

	// NEW: Shortcut configuration (default: "f", "b", "m")
	BuildLargeSizeShortcut    string // "L" (large/fast) compile fast with go
	BuildMediumSizeShortcut     string // "M" (medium/debug) compile with tinygo debug
	BuildSmallSizeShortcut string // "S" (small/minimal) compile with tinygo minimal binary size

	// gobuild integration fields
	Callback           func(error)     // Optional callback for async compilation
	CompilingArguments func() []string // Build arguments for compilation (e.g., ldflags)

	// DisableWasmExecJsOutput prevents automatic creation of wasm_exec.js file
	// Useful when embedding wasm_exec.js content inline (e.g., Cloudflare Pages Advanced Mode)
	DisableWasmExecJsOutput bool
}

// Pre-configured constructor (recommended)
func NewConfig() *Config

Dual Output Architecture

TinyWasm produces two types of outputs that serve different purposes in the build pipeline:

1. WASM Binary Output (OutputDir)
  • Location: src/web/public/main.wasm
  • Purpose: Final compiled WebAssembly binary loaded by the browser
  • Consumed by: Browser at runtime
  • Modes: All three compilation modes produce output here
2. Watchable JavaScript Output (WasmExecJsOutputDir)
  • Location: src/web/ui/js/wasm_exec.js
  • Purpose: Mode-specific JavaScript runtime that:
    • Informs external tools about the current compilation mode (Go vs TinyGo)
    • Triggers file watchers to reload the browser when mode changes
    • Gets compiled together with other JavaScript by external asset bundlers
  • Consumed by: File watchers (e.g., devwatch) and asset bundlers (e.g., assetmin)
  • Important: TinyWasm's only responsibility is writing the correct wasm_exec.js according to the active mode. External tools handle final bundling.
Why Two Separate Directories?
  1. Separation of Concerns: Runtime assets vs. build-time integration
  2. Build Pipeline Integration: File watchers track wasm_exec.js changes
  3. No Dev/Prod States: All modes use the same directories
  4. Mode Transparency: External tools detect mode changes via wasm_exec.js

Mode Switching

// Example usage with the new channel-based Change API:
progress := make(chan string)
go func() {
	for p := range progress {
		fmt.Println(p)
	}
}()
tw.Change("S", progress) // production mode with TinyGo -opt=z

// Repeat for other modes as needed (always provide and consume a progress channel)
// tw.Change("M", progress)
// tw.Change("L", progress)

Requirements

  • Go 1.20+
  • TinyGo (optional, required for debug/production modes)
  • DevTUI (optional, for interactive development)

Benefits:

  • 🎯 3 optimized modes instead of binary choice
  • 🔧 DevTUI integration for interactive development
  • 📦 Smaller debug builds with TinyGo -opt=1
  • Auto-recompilation on mode switch
  • 🛠️ Better error handling with validation
  • 🏗️ Dual output architecture for better build pipeline integration

Contributing

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {

	// AppRootDir specifies the application root directory (absolute).
	// e.g., "/home/user/project". If empty, defaults to "." to preserve existing behavior.
	AppRootDir string

	// SourceDir specifies the directory containing the Go source for the webclient (relative to AppRootDir).
	// e.g., "src/cmd/webclient"
	SourceDir string

	// OutputDir specifies the directory for WASM and related assets (relative to AppRootDir).
	// e.g., "src/web/public"
	OutputDir string

	WasmExecJsOutputDir string // output dir for wasm_exec.js file (relative) eg: "src/web/ui/js", "theme/js"
	MainInputFile       string // main input file for WASM compilation (default: "main.wasm.go")
	OutputName          string // output name for WASM file (default: "main")
	Logger              func(message ...any)

	BuildLargeSizeShortcut  string // "L" (Large) compile with go
	BuildMediumSizeShortcut string // "M" (Medium) compile with tinygo debug
	BuildSmallSizeShortcut  string // "S" (Small) compile with tinygo minimal binary size

	// gobuild integration fields
	Callback           func(error)     // Optional callback for async compilation
	CompilingArguments func() []string // Build arguments for compilation (e.g., ldflags)

	// DisableWasmExecJsOutput prevents automatic creation of wasm_exec.js file
	// Useful when embedding wasm_exec.js content inline (e.g., Cloudflare Pages Advanced Mode)
	DisableWasmExecJsOutput bool

	Store            Store  // Key-Value store for state persistence
	OnWasmExecChange func() // Callback for wasm_exec.js changes
	// contains filtered or unexported fields
}

Config holds configuration for WASM compilation

func NewConfig

func NewConfig() *Config

NewConfig creates a TinyWasm Config with sensible defaults

type ParameterMetadata

type ParameterMetadata struct {
	Name        string
	Description string
	Required    bool
	Type        string
	EnumValues  []string
	Default     any
}

ParameterMetadata describes a tool parameter

type Store added in v0.3.7

type Store interface {
	Get(key string) (string, error)
	Set(key, value string) error
}

Store defines the interface for a key-value storage system used to persist the compiler state (e.g. current mode).

type TinyWasm added in v0.3.7

type TinyWasm struct {
	*Config
	// contains filtered or unexported fields
}

TinyWasm provides WebAssembly compilation capabilities with 3-mode compiler selection

func New

func New(c *Config) *TinyWasm

New creates a new TinyWasm instance with the provided configuration Timeout is set to 40 seconds maximum as TinyGo compilation can be slow Default values: MainInputFile in Config defaults to "main.wasm.go"

func (*TinyWasm) Change added in v0.3.7

func (w *TinyWasm) Change(newValue string, progress chan<- string)

Change updates the compiler mode for TinyWasm and reports progress via the provided channel. Implements the HandlerEdit interface: Change(newValue string, progress chan<- string) NOTE: The caller (devtui) is responsible for closing the progress channel, NOT the handler.

func (*TinyWasm) ClearJavaScriptCache added in v0.3.7

func (h *TinyWasm) ClearJavaScriptCache()

ClearJavaScriptCache clears both cached JavaScript strings to force regeneration

func (*TinyWasm) CreateDefaultWasmFileClientIfNotExist added in v0.3.7

func (t *TinyWasm) CreateDefaultWasmFileClientIfNotExist() *TinyWasm

CreateDefaultWasmFileClientIfNotExist creates a default WASM main.go file from the embedded markdown template It never overwrites an existing file and returns the TinyWasm instance for method chaining.

func (*TinyWasm) GetLastOperationID added in v0.3.7

func (w *TinyWasm) GetLastOperationID() string

func (*TinyWasm) GetMCPToolsMetadata added in v0.3.7

func (w *TinyWasm) GetMCPToolsMetadata() []ToolMetadata

GetMCPToolsMetadata returns metadata for all TinyWasm MCP tools

func (*TinyWasm) GetTinyGoVersion added in v0.3.7

func (t *TinyWasm) GetTinyGoVersion() (string, error)

GetTinyGoVersion returns the installed TinyGo version

func (*TinyWasm) GetWasmExecJsPathGo added in v0.3.7

func (w *TinyWasm) GetWasmExecJsPathGo() (string, error)

GetWasmExecJsPathGo returns the path to Go's wasm_exec.js file

func (*TinyWasm) GetWasmExecJsPathTinyGo added in v0.3.7

func (w *TinyWasm) GetWasmExecJsPathTinyGo() (string, error)

GetWasmExecJsPathTinyGo returns the path to TinyGo's wasm_exec.js file

func (*TinyWasm) JavascriptForInitializing added in v0.3.7

func (h *TinyWasm) JavascriptForInitializing(customizations ...string) (js string, err error)

JavascriptForInitializing returns the JavaScript code needed to initialize WASM.

Parameters (variadic):

  • customizations[0]: Custom header string to prepend to wasm_exec.js content. If not provided, defaults to "// TinyWasm: mode=<current_mode>\n"
  • customizations[1]: Custom footer string to append after wasm_exec.js content. If not provided, defaults to WebAssembly initialization code with fetch and instantiate.

Examples:

  • JavascriptForInitializing() - Uses default header and footer
  • JavascriptForInitializing("// Custom Header\n") - Custom header, default footer
  • JavascriptForInitializing("// Custom Header\n", "console.log('loaded');") - Both custom

func (*TinyWasm) Label added in v0.3.7

func (w *TinyWasm) Label() string

Label returns the field label for DevTUI display

func (*TinyWasm) MainInputFileRelativePath added in v0.3.7

func (w *TinyWasm) MainInputFileRelativePath() string

MainInputFileRelativePath returns the relative path to the main WASM input file (e.g. "main.wasm.go").

func (*TinyWasm) MainOutputFileAbsolutePath added in v0.3.7

func (w *TinyWasm) MainOutputFileAbsolutePath() string

MainOutputFileAbsolutePath returns the absolute path to the main WASM output file (e.g. "main.wasm").

func (*TinyWasm) Name added in v0.3.7

func (w *TinyWasm) Name() string

Name returns the name of the WASM project

func (*TinyWasm) NewFileEvent added in v0.3.7

func (w *TinyWasm) NewFileEvent(fileName, extension, filePath, event string) error

NewFileEvent handles file events for WASM compilation with automatic project detection fileName: name of the file (e.g., main.wasm.go) extension: file extension (e.g., .go) filePath: full path to the file (e.g., ./home/userName/ProjectName/web/public/main.wasm.go) event: type of file event (e.g., create, remove, write, rename)

func (*TinyWasm) OutputRelativePath added in v0.3.7

func (w *TinyWasm) OutputRelativePath() string

OutputRelativePath returns the RELATIVE path to the final output file eg: "deploy/edgeworker/app.wasm" (relative to AppRootDir) This is used by file watchers to identify output files that should be ignored. The returned path always uses forward slashes (/) for consistency across platforms.

func (*TinyWasm) RecompileMainWasm added in v0.3.7

func (w *TinyWasm) RecompileMainWasm() error

RecompileMainWasm recompiles the main WASM file if it exists

func (*TinyWasm) SetLastOperationID added in v0.3.7

func (w *TinyWasm) SetLastOperationID(id string)

func (*TinyWasm) Shortcuts added in v0.3.7

func (w *TinyWasm) Shortcuts() []map[string]string

func (*TinyWasm) ShouldCompileToWasm added in v0.3.7

func (w *TinyWasm) ShouldCompileToWasm(fileName, filePath string) bool

ShouldCompileToWasm determines if a file should trigger WASM compilation

func (*TinyWasm) SupportedExtensions added in v0.3.7

func (w *TinyWasm) SupportedExtensions() []string

func (*TinyWasm) TinyGoCompiler added in v0.3.7

func (w *TinyWasm) TinyGoCompiler() bool

TinyGoCompiler returns if TinyGo compiler should be used (dynamic based on configuration)

func (*TinyWasm) UnobservedFiles added in v0.3.7

func (w *TinyWasm) UnobservedFiles() []string

UnobservedFiles returns files that should not be watched for changes e.g: main.wasm

func (*TinyWasm) Value added in v0.3.7

func (w *TinyWasm) Value() string

Value returns the current compiler mode shortcut (c, d, or p)

func (*TinyWasm) VerifyTinyGoInstallation added in v0.3.7

func (t *TinyWasm) VerifyTinyGoInstallation() error

VerifyTinyGoInstallation checks if TinyGo is properly installed

func (*TinyWasm) VerifyTinyGoProjectCompatibility added in v0.3.7

func (w *TinyWasm) VerifyTinyGoProjectCompatibility()

VerifyTinyGoProjectCompatibility checks if the project is compatible with TinyGo compilation

func (*TinyWasm) VisualStudioCodeWasmEnvConfig added in v0.3.7

func (w *TinyWasm) VisualStudioCodeWasmEnvConfig()

VisualStudioCodeWasmEnvConfig automatically creates and configures VS Code settings for WASM development. This method resolves the "could not import syscall/js" error by setting proper environment variables in .vscode/settings.json file. On Windows, the .vscode directory is made hidden for a cleaner project view. This configuration enables VS Code's Go extension to properly recognize WASM imports and provide accurate IntelliSense, error detection, and code completion for syscall/js and other WASM-specific packages.

func (*TinyWasm) WasmExecJsOutputPath added in v0.3.7

func (w *TinyWasm) WasmExecJsOutputPath() string

WasmExecJsOutputPath returns the output path for wasm_exec.js

func (*TinyWasm) WasmProjectTinyGoJsUse added in v0.3.7

func (w *TinyWasm) WasmProjectTinyGoJsUse(mode ...string) (isWasmProject bool, useTinyGo bool)

WasmProjectTinyGoJsUse returns dynamic state based on current configuration

type ToolExecutor

type ToolExecutor func(args map[string]any, progress chan<- any)

ToolExecutor defines how a tool should be executed Channel accepts string messages (no binary data in tinywasm)

type ToolMetadata

type ToolMetadata struct {
	Name        string
	Description string
	Parameters  []ParameterMetadata
	Execute     ToolExecutor // Execution function
}

ToolMetadata provides MCP tool configuration metadata

Directories

Path Synopsis
benchmark
shared command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL