server

package module
v0.2.28 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: MIT Imports: 20 Imported by: 1

README

tinywasm/server

Short summary

  • server provides a specialized HTTP server handler for TinyWASM applications.
  • It operates in two execution modes:
    1. Internal (Default): Runs a lightweight net/http server within the application process, routed via httpd.NewRouter. Best for development speed and zero-file generation start.
    2. External: Generates a standalone main Go file, compiles it, and runs it as a separate process. Best for customization and production-like validation.
  • It also supports two compilation modes: In-Memory (default) and On-Disk.
  • It seamlessly handles the transition between execution modes via SetExternalServerMode.
  • The httpd subpackage (github.com/tinywasm/server/httpd) is the batteries-included router.Router adapter used internally and available for production use (see below).

Public API (types and functions)

  • func New() *ServerHandler — creates a handler with default Config (AppRootDir: ".", SourceDir/OutputDir: "web", AppPort: "8080"). Configure it with the setters below (fluent methods return *ServerHandler where noted).

  • type ServerHandler

    • Setters:
      • SetAppRootDir(dir string)
      • SetSourceDir(dir string)
      • SetOutputDir(dir string)
      • SetPublicDir(dir string) *ServerHandler
      • SetMainInputFile(name string)
      • SetPort(port string) / Port() string
      • SetHTTPS(enabled bool) *ServerHandler
      • SetLogger(fn func(...any)) *ServerHandler
      • SetExitChan(ch chan bool) *ServerHandler
      • SetOpenBrowser(fn func(port string, https bool)) *ServerHandler
      • SetStore(s Store) *ServerHandler
      • SetUI(ui UI) *ServerHandler
      • SetBeforeExternalServerStart(fn func() error) *ServerHandler — hook invoked synchronously before every external-mode start.
      • SetGitIgnoreAdd(fn func(string) error) *ServerHandler
      • SetCompileArgs(fn func() []string)
      • SetRunArgs(fn func() []string)
      • SetDisableGlobalCleanup(disable bool)
    • Routing:
      • RegisterRoutes(fn func(router.Router)) — appends a route-registration callback (using github.com/tinywasm/router's Router contract). Call before StartServer. Used by both Internal and External modes.
    • Lifecycle:
      • StartServer(wg *sync.WaitGroup) — starts the server (async).
      • StopServer() error
      • RestartServer() error
      • SetExternalServerMode(external bool) error — switches between Internal and External execution modes. When switching to External, it generates files (if missing), compiles, and starts the process. Cannot switch back to Internal.
      • NewFileEvent(fileName, extension, filePath, event string) error — handles hot-reloads (recompiles external server or no-op for internal).
      • MainInputFileRelativePath() string
      • UnobservedFiles() []string

Notes and behaviour

  • Routes Registration: Use RegisterRoutes to register handlers via the router.Router contract (e.g., r.Get("/path", handler)) so they work immediately in Internal mode and are carried over to External mode.
  • Port Management: When switching modes, the handler automatically waits for the port to be free before starting the new strategy.

Minimal usage example

package main

import (
    "fmt"
    "os"
    "sync"

    "github.com/tinywasm/router"
    "github.com/tinywasm/server"
)

func main() {
    handler := server.New()
    handler.SetAppRootDir(".")
    handler.SetLogger(func(messages ...any) { fmt.Fprintln(os.Stdout, messages...) })

    handler.RegisterRoutes(func(r router.Router) {
        r.Get("/hello", func(ctx router.Context) {
            fmt.Fprint(ctx, "Hello from Internal Server!")
        })
    })

    var wg sync.WaitGroup
    wg.Add(1)
    go handler.StartServer(&wg)
    wg.Wait()

    // To switch to external mode later:
    // handler.SetExternalServerMode(true)
}

httpd subpackage

github.com/tinywasm/server/httpd implements router.Router/router.Context on top of net/http, with production batteries built in: gzip, no-cache headers, static file serving, TLS (AutoCert/custom cert/DevTLS), a /health endpoint, an optional /_routes JSON listing, and closed-by-default RBAC enforcement (Config.Authn for global identity, Config.Authorize for per-route Requires(resource, action) checks; routes must opt into Public() to allow anonymous access).

s := httpd.New(httpd.Config{
    Port:   "8080",
    Health: true,
})
s.Mount(myAPIModule) // github.com/tinywasm/router.APIModule
if err := s.ListenAndServe(); err != nil {
    log.Fatal(err)
}

Handler() returns the fully wired http.Handler (static files, batteries, routes, RBAC) without opening a port, for use with httptest. See docs/ARCHITECTURE.md for design details.

Contributing

Documentation

Index

Constants

View Source
const (
	StoreKeyExternalServer = "server_external_mode"
	EnvKeyServerPort       = "SERVER_PORT"
	EnvKeyServerHttps      = "SERVER_HTTPS"
)
View Source
const DefaultNoRoutesMsg = "<h3>No routes registered in In-Memory Server</h3>"

Variables

View Source
var ErrUnsupportedEvent = errors.New("server: unsupported file event, no rebuild triggered")
View Source
var TestMode bool

TestMode is a global flag to indicate the server is running in a test environment. This is used to disable aggressive cleanups and other disruptive behaviors.

Functions

func WaitForPortListening added in v0.1.64

func WaitForPortListening(port string, timeout time.Duration, https bool) bool

WaitForPortListening waits until the port is accepting HTTP or HTTPS connections (server is ready)

Types

type Config

type Config struct {
	AppRootDir                  string               // e.g., /home/user/project (application root directory)
	SourceDir                   string               // directory location of main.go e.g., src/cmd/appserver (relative to AppRootDir)
	OutputDir                   string               // compilation and execution directory e.g., deploy/appserver (relative to AppRootDir)
	PublicDir                   string               // default public dir for generated server (e.g., src/web/public)
	MainInputFile               string               // main input file name (default: "main.go", can be "server.go", etc.)
	ArgumentsForCompilingServer func() []string      // e.g., []string{"-X 'main.version=v1.0.0'"}
	ArgumentsToRunServer        func() []string      // e.g., []string{"dev"}
	AppPort                     string               // e.g., 8080
	Https                       bool                 // true if HTTPS is enabled
	DisableGlobalCleanup        bool                 // If true, disables global cleanup in gorun during restarts
	Logger                      func(message ...any) // Logger function
	ExitChan                    chan bool            // Global channel to signal shutdown
	OpenBrowser                 func(port string, https bool)
	Store                       Store                    // Persistent storage for modes
	UI                          UI                       // UI for refresh notifications
	BeforeExternalServerStart   func() error             // Called synchronously before external strategy starts
	GitIgnoreAdd                func(entry string) error // Callback to add entries to .gitignore
}

type ServerHandler

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

func New

func New() *ServerHandler

New creates a new ServerHandler with default configuration.

func (*ServerHandler) Change added in v0.1.28

func (h *ServerHandler) Change(newValue string)

Change implements HandlerSelection.Change

func (*ServerHandler) CreateTemplateServer added in v0.1.16

func (h *ServerHandler) CreateTemplateServer() error

CreateTemplateServer switches from Internal to External mode. It generates the server files (if not present), compiles, and runs them. This implements the transition from "Internal" to "External" mode.

func (*ServerHandler) Label added in v0.1.28

func (h *ServerHandler) Label() string

Label implements HandlerSelection.Label

func (*ServerHandler) MainInputFileRelativePath

func (h *ServerHandler) MainInputFileRelativePath() string

MainInputFileRelativePath returns the path relative to AppRootDir (e.g., "src/cmd/appserver/main.go")

func (*ServerHandler) Name added in v0.1.21

func (h *ServerHandler) Name() string

func (*ServerHandler) NewFileEvent

func (h *ServerHandler) NewFileEvent(fileName, extension, filePath, event string) error

event: create,write,remove,rename

func (*ServerHandler) Options added in v0.2.25

func (h *ServerHandler) Options() []map[string]string

Options implements HandlerSelection.Options

func (*ServerHandler) Port added in v0.2.20

func (h *ServerHandler) Port() string

Port returns the current server port. Safe for concurrent use with SetPort.

func (*ServerHandler) RefreshUI added in v0.1.28

func (h *ServerHandler) RefreshUI()

func (*ServerHandler) RegisterRoutes added in v0.2.0

func (h *ServerHandler) RegisterRoutes(fn func(router.Router))

RegisterRoutes appends fn to the internal route list. Call before StartServer.

func (*ServerHandler) Restart added in v0.1.46

func (h *ServerHandler) Restart() error

Restart restarts the server. It delegates to the current strategy's Restart method.

func (*ServerHandler) RestartServer

func (h *ServerHandler) RestartServer() error

func (*ServerHandler) SetAppRootDir added in v0.2.0

func (h *ServerHandler) SetAppRootDir(dir string)

SetAppRootDir sets the application root directory

func (*ServerHandler) SetBeforeExternalServerStart added in v0.2.16

func (h *ServerHandler) SetBeforeExternalServerStart(fn func() error) *ServerHandler

SetBeforeExternalServerStart registers a function invoked synchronously BEFORE strategy.Start in every external-mode StartServer call. Returning a non-nil error aborts the transition: strategy.Start is NOT invoked and the error is logged.

Idempotency: the hook fires on every external-mode StartServer, not only on the internal→external transition (external mode is sticky, persisted via the Store). Implementations must be safe to invoke N times.

RestartServer does NOT invoke this hook.

func (*ServerHandler) SetCompileArgs added in v0.2.0

func (h *ServerHandler) SetCompileArgs(fn func() []string)

SetCompileArgs sets the arguments for compiling the server

func (*ServerHandler) SetDisableGlobalCleanup added in v0.2.0

func (h *ServerHandler) SetDisableGlobalCleanup(disable bool)

SetDisableGlobalCleanup enables or disables global cleanup

func (*ServerHandler) SetExitChan added in v0.2.0

func (h *ServerHandler) SetExitChan(ch chan bool) *ServerHandler

SetExitChan sets the exit channel

func (*ServerHandler) SetExternalServerMode added in v0.1.19

func (h *ServerHandler) SetExternalServerMode(external bool) error

SetExternalServerMode switches between Internal and External server strategies. When switching to External, it also: 1. Generates server template files if they don't exist 2. Compiles the server 3. Starts the external process

func (*ServerHandler) SetGitIgnoreAdd added in v0.2.0

func (h *ServerHandler) SetGitIgnoreAdd(fn func(string) error) *ServerHandler

SetGitIgnoreAdd sets the callback to add entries to .gitignore

func (*ServerHandler) SetHTTPS added in v0.2.0

func (h *ServerHandler) SetHTTPS(enabled bool) *ServerHandler

SetHTTPS enables or disables HTTPS

func (*ServerHandler) SetLog added in v0.1.21

func (h *ServerHandler) SetLog(fn func(...any))

SetLog implements devtui.Loggable

func (*ServerHandler) SetLogger added in v0.2.0

func (h *ServerHandler) SetLogger(fn func(...any)) *ServerHandler

SetLogger sets the logger function

func (*ServerHandler) SetMainInputFile added in v0.2.0

func (h *ServerHandler) SetMainInputFile(name string)

SetMainInputFile sets the main input file name

func (*ServerHandler) SetOpenBrowser added in v0.2.0

func (h *ServerHandler) SetOpenBrowser(fn func(port string, https bool)) *ServerHandler

SetOpenBrowser sets the open browser function

func (*ServerHandler) SetOutputDir added in v0.2.0

func (h *ServerHandler) SetOutputDir(dir string)

SetOutputDir sets the output directory relative to AppRootDir

func (*ServerHandler) SetPort added in v0.2.0

func (h *ServerHandler) SetPort(port string)

SetPort sets the server port

func (*ServerHandler) SetPublicDir added in v0.2.0

func (h *ServerHandler) SetPublicDir(dir string) *ServerHandler

SetPublicDir sets the public directory

func (*ServerHandler) SetRunArgs added in v0.2.0

func (h *ServerHandler) SetRunArgs(fn func() []string)

SetRunArgs sets the arguments for running the server

func (*ServerHandler) SetSourceDir added in v0.2.0

func (h *ServerHandler) SetSourceDir(dir string)

SetSourceDir sets the source directory relative to AppRootDir

func (*ServerHandler) SetStore added in v0.2.0

func (h *ServerHandler) SetStore(s Store) *ServerHandler

SetStore sets the persistent store

func (*ServerHandler) SetUI added in v0.2.0

func (h *ServerHandler) SetUI(ui UI) *ServerHandler

SetUI sets the UI interface

func (*ServerHandler) StartServer

func (h *ServerHandler) StartServer(wg *sync.WaitGroup)

StartServer initiates the server using the current strategy (In-Memory or External)

func (*ServerHandler) StopServer added in v0.1.24

func (h *ServerHandler) StopServer() error

StopServer stops the server and waits for the port to be released.

func (*ServerHandler) SupportedExtensions

func (h *ServerHandler) SupportedExtensions() []string

func (*ServerHandler) UnobservedFiles

func (h *ServerHandler) UnobservedFiles() []string

UnobservedFiles returns the list of files that should not be tracked by file watchers

func (*ServerHandler) Value added in v0.1.28

func (h *ServerHandler) Value() string

Value implements HandlerSelection.Value

type ServerStrategy added in v0.1.16

type ServerStrategy interface {
	Start(wg *sync.WaitGroup) error
	Stop() error
	Restart() error
	HandleFileEvent(fileName, extension, filePath, event string) error
	Name() string
}

type Store added in v0.1.19

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

Store defines the minimal interface for persistent storage

type UI added in v0.1.19

type UI interface {
	RefreshUI()
}

UI defines the minimal interface for UI interaction

Directories

Path Synopsis
tests
web command

Jump to

Keyboard shortcuts

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