worker

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Feb 21, 2026 License: MIT Imports: 53 Imported by: 0

README

worker

A standalone JavaScript worker runtime for Go, powered by V8.

import "github.com/cryguy/worker"

Features

  • V8-based JavaScript execution with isolate pooling
  • Cloudflare Workers-compatible API surface:
    • KV namespaces
    • R2 storage buckets
    • D1 databases (SQLite)
    • Durable Objects
    • Queue producers
    • Service bindings (worker-to-worker RPC)
    • Cache API
    • Static assets
  • Web standard APIs: fetch, crypto, streams, WebSocket, HTMLRewriter, URL, TextEncoder/Decoder
  • ES module bundling via esbuild
  • Resource limits: memory, execution timeout, fetch count
  • Cron scheduling support

Requirements

  • Go 1.25+
  • CGO enabled (required by V8)
  • Linux or macOS (V8 binaries are platform-specific)

Usage

cfg := worker.EngineConfig{
    PoolSize:         4,
    MemoryLimitMB:    128,
    ExecutionTimeout: 30000,
    MaxFetchRequests: 50,
}

engine := worker.NewEngine(cfg, mySourceLoader)
defer engine.Shutdown()

env := &worker.Env{
    Vars:    map[string]string{"API_KEY": "..."},
    Secrets: map[string]string{"SECRET": "..."},
    KV:      map[string]worker.KVStore{"MY_KV": myKVImpl},
}

result := engine.Execute("site-id", "deploy-key", env, &worker.WorkerRequest{
    Method:  "GET",
    URL:     "https://example.com/",
    Headers: map[string]string{},
})

Interfaces

The runtime is decoupled from storage backends via interfaces. Implement these to provide platform bindings:

  • SourceLoader - Load worker JavaScript source code
  • KVStore - Key-value storage
  • CacheStore - HTTP cache
  • R2Store - Object storage (S3/R2 compatible)
  • DurableObjectStore - Durable Object storage
  • QueueSender - Message queue producer
  • AssetsFetcher - Static asset serving
  • WorkerDispatcher - Service binding dispatch

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DataDir = "./data"

DataDir is the base directory for cached polyfills. Defaults to "./data".

Functions

func BundleWorkerScript

func BundleWorkerScript(deployPath string) (string, error)

BundleWorkerScript uses esbuild to bundle a worker's _worker.js entry point with all its imports into a single self-contained script. This enables ES module import/export support for worker scripts.

If the source doesn't contain any import statements, it's returned as-is to avoid unnecessary processing.

func EnsureUnenv

func EnsureUnenv(dataDir string) (string, error)

EnsureUnenv downloads unenv and its dependencies from the npm registry into {dataDir}/polyfills/node_modules/ if not already present. Returns the path to the unenv package directory.

func ResetUnenvCache

func ResetUnenvCache()

ResetUnenvCache clears the cached unenv path (used in tests).

func ValidateCron

func ValidateCron(expr string) error

ValidateCron checks if a cron expression is a valid 5-field format. Fields: minute(0-59) hour(0-23) day(1-31) month(1-12) weekday(0-6).

func ValidateDatabaseID

func ValidateDatabaseID(id string) error

ValidateDatabaseID rejects database IDs that contain path traversal characters, null bytes, or are empty/too long.

Types

type AssetsFetcher

type AssetsFetcher interface {
	Fetch(req *WorkerRequest) (*WorkerResponse, error)
}

AssetsFetcher is implemented by the static pipeline to handle env.ASSETS.fetch().

type CacheEntry

type CacheEntry struct {
	Status    int
	Headers   string
	Body      []byte
	ExpiresAt *time.Time
}

CacheEntry represents a cached HTTP response (library-owned type, replaces models.CacheEntry).

type CacheStore

type CacheStore interface {
	Match(cacheName, url string) (*CacheEntry, error)
	Put(cacheName, url string, status int, headers string, body []byte, ttl *int) error
	Delete(cacheName, url string) (bool, error)
}

CacheStore backs the Cache API (site-scoped).

type D1Bridge

type D1Bridge struct {
	DatabaseID string
	// contains filtered or unexported fields
}

D1Bridge provides Go methods that back the D1 database JS bindings. Each D1 binding gets its own isolated SQLite database, completely separate from the application's main database.

func NewD1BridgeMemory

func NewD1BridgeMemory(databaseID string) (*D1Bridge, error)

NewD1BridgeMemory creates an in-memory D1Bridge for testing.

func OpenD1Database

func OpenD1Database(dataDir, databaseID string) (*D1Bridge, error)

OpenD1Database opens (or creates) an isolated SQLite database for the given database ID. The file is stored at {dataDir}/d1/{databaseID}.sqlite3.

func (*D1Bridge) Close

func (d *D1Bridge) Close() error

Close closes the underlying database connection.

func (*D1Bridge) Exec

func (d *D1Bridge) Exec(sqlStr string, bindings []interface{}) (*D1ExecResult, error)

Exec runs a SQL statement with optional bindings and returns columns, rows, and metadata.

type D1ExecResult

type D1ExecResult struct {
	Columns []string        `json:"columns"`
	Rows    [][]interface{} `json:"rows"`
	Meta    D1Meta          `json:"meta"`
}

D1ExecResult holds the result of executing a SQL statement.

type D1Meta

type D1Meta struct {
	ChangedDB   bool  `json:"changed_db"`
	Changes     int64 `json:"changes"`
	LastRowID   int64 `json:"last_row_id"`
	RowsRead    int   `json:"rows_read"`
	RowsWritten int   `json:"rows_written"`
}

D1Meta holds metadata about a D1 query execution.

type DurableObjectStore

type DurableObjectStore interface {
	Get(namespace, objectID, key string) (string, error)
	GetMulti(namespace, objectID string, keys []string) (map[string]string, error)
	Put(namespace, objectID, key, valueJSON string) error
	PutMulti(namespace, objectID string, entries map[string]string) error
	Delete(namespace, objectID, key string) error
	DeleteMulti(namespace, objectID string, keys []string) (int, error)
	DeleteAll(namespace, objectID string) error
	List(namespace, objectID, prefix string, limit int, reverse bool) ([]KVPair, error)
}

DurableObjectStore backs Durable Object storage.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine manages per-site worker pools and executes JS worker scripts.

func NewEngine

func NewEngine(cfg EngineConfig, sourceLoader SourceLoader) *Engine

NewEngine creates an Engine with the given configuration and source loader.

func (*Engine) CompileAndCache

func (e *Engine) CompileAndCache(siteID string, deployKey string, source string) ([]byte, error)

CompileAndCache validates that a worker script compiles and stores the source for later pool creation. Returns the source bytes for disk storage.

func (*Engine) EnsureSource

func (e *Engine) EnsureSource(siteID string, deployKey string) error

EnsureSource loads the worker JS source into memory if not already cached. Handles the server restart scenario where in-memory caches are lost.

func (*Engine) Execute

func (e *Engine) Execute(siteID string, deployKey string, env *Env, req *WorkerRequest) (result *WorkerResult)

Execute runs the worker's fetch handler for the given request and returns the result including the response, captured logs, and any error. env must not be nil — the caller is responsible for constructing a fully-wired Env.

func (*Engine) ExecuteScheduled

func (e *Engine) ExecuteScheduled(siteID string, deployKey string, env *Env, cron string) (result *WorkerResult)

ExecuteScheduled runs the worker's scheduled handler for cron triggers.

func (*Engine) ExecuteTail

func (e *Engine) ExecuteTail(siteID string, deployKey string, env *Env, events []TailEvent) (result *WorkerResult)

ExecuteTail runs the worker's tail handler for log forwarding.

func (*Engine) InvalidatePool

func (e *Engine) InvalidatePool(siteID string, deployKey string)

InvalidatePool marks the pool for the given site/deploy as invalid. The next Execute call will create a fresh pool.

func (*Engine) MaxResponseBytes

func (e *Engine) MaxResponseBytes() int

MaxResponseBytes returns the configured maximum response body size.

func (*Engine) Shutdown

func (e *Engine) Shutdown()

Shutdown invalidates all pools and clears all cached sources.

type EngineConfig

type EngineConfig struct {
	PoolSize         int // number of V8 isolates per site pool
	MemoryLimitMB    int // per-isolate memory limit
	ExecutionTimeout int // milliseconds before worker is terminated
	MaxFetchRequests int // max outbound fetches per request
	FetchTimeoutSec  int // per-fetch timeout in seconds
	MaxResponseBytes int // max response body size
	MaxScriptSizeKB  int // max bundled script size
}

EngineConfig holds runtime configuration for the worker engine. This is a library-owned struct that replaces config.WorkerConfig, omitting application-level fields (MaxLogRetention, DataDir).

type Env

type Env struct {
	Vars    map[string]string
	Secrets map[string]string

	// Opt-in bindings — nil means disabled
	KV              map[string]KVStore
	Cache           CacheStore
	Storage         map[string]R2Store
	Queues          map[string]QueueSender
	D1Bindings      map[string]string // binding name -> database ID
	DurableObjects  map[string]DurableObjectStore
	ServiceBindings map[string]ServiceBindingConfig

	// D1 configuration
	D1DataDir string

	// Runtime references
	Assets     AssetsFetcher
	Dispatcher WorkerDispatcher // set by Engine before execution
	SiteID     string           // site isolation key
}

Env holds all bindings passed to the worker as the second argument.

type KVListResult

type KVListResult struct {
	Keys         []map[string]interface{}
	ListComplete bool
	Cursor       string // base64-encoded offset, empty when list is complete
}

KVListResult holds the result of a List operation with pagination info.

type KVPair

type KVPair struct {
	Key   string
	Value string
}

KVPair represents an ordered key-value pair returned by List.

type KVStore

type KVStore interface {
	Get(key string) (string, error)
	GetWithMetadata(key string) (*KVValueWithMetadata, error)
	Put(key, value string, metadata *string, ttl *int) error
	Delete(key string) error
	List(prefix string, limit int, cursor string) (*KVListResult, error)
}

KVStore backs a single KV namespace.

type KVValueWithMetadata

type KVValueWithMetadata struct {
	Value    string
	Metadata *string
}

KVValueWithMetadata holds a value and its associated metadata.

type LogEntry

type LogEntry struct {
	Level   string    `json:"level"`
	Message string    `json:"message"`
	Time    time.Time `json:"time"`
}

LogEntry is a single console.log/warn/error captured from a worker.

type QueueMessageInput

type QueueMessageInput struct {
	Body        string
	ContentType string
}

QueueMessageInput is the Go representation of a batch send item.

type QueueSender

type QueueSender interface {
	Send(body, contentType string) (string, error)
	SendBatch(messages []QueueMessageInput) ([]string, error)
}

QueueSender backs queue message production for a single queue. The queue name and site ID are baked into the implementation.

type R2ListOptions

type R2ListOptions struct {
	Prefix    string
	Delimiter string
	Cursor    string
	Limit     int
}

R2ListOptions configures an R2 list operation.

type R2ListResult

type R2ListResult struct {
	Objects           []R2Object
	Truncated         bool
	Cursor            string
	DelimitedPrefixes []string
}

R2ListResult holds the result of an R2 list operation.

type R2Object

type R2Object struct {
	Key            string
	Size           int64
	ContentType    string
	ETag           string
	LastModified   time.Time
	CustomMetadata map[string]string
}

R2Object holds metadata about an R2/S3-compatible object.

type R2PutOptions

type R2PutOptions struct {
	ContentType    string
	CustomMetadata map[string]string
}

R2PutOptions configures an R2 put operation.

type R2Store

type R2Store interface {
	Get(key string) ([]byte, *R2Object, error)
	Put(key string, data []byte, opts R2PutOptions) (*R2Object, error)
	Delete(keys []string) error
	Head(key string) (*R2Object, error)
	List(opts R2ListOptions) (*R2ListResult, error)
	PresignedGetURL(key string, expiry time.Duration) (string, error)
	PublicURL(key string) (string, error)
}

R2Store backs R2-compatible object storage for a single bucket.

type ServiceBindingBridge

type ServiceBindingBridge struct {
	Dispatcher WorkerDispatcher
	Env        *Env
}

ServiceBindingBridge provides Go methods that back the service binding JS bindings.

func (*ServiceBindingBridge) Fetch

Fetch calls the target worker's fetch handler with the given request. The target worker receives its own environment (not the caller's).

type ServiceBindingConfig

type ServiceBindingConfig struct {
	TargetSiteID    string
	TargetDeployKey string
}

ServiceBindingConfig identifies the target worker for a service binding.

type SourceLoader

type SourceLoader interface {
	GetWorkerScript(siteID, deployKey string) (string, error)
}

SourceLoader retrieves worker JS source code.

type TailEvent

type TailEvent struct {
	ScriptName string     `json:"scriptName"`
	Logs       []LogEntry `json:"logs"`
	Exceptions []string   `json:"exceptions"`
	Outcome    string     `json:"outcome"`
	Timestamp  time.Time  `json:"timestamp"`
}

TailEvent represents a log event forwarded to a tail worker.

type WebSocketHandler

type WebSocketHandler struct {
	// contains filtered or unexported fields
}

WebSocketHandler holds references needed for WebSocket bridging after the initial fetch handler returns a 101 response with a webSocket.

func (*WebSocketHandler) Bridge

func (wsh *WebSocketHandler) Bridge(ctx context.Context, httpConn *websocket.Conn)

Bridge starts the WebSocket message bridge between the HTTP connection and the V8 worker. This method blocks until the WebSocket connection closes or the timeout is reached. The worker is returned to the pool when done.

type WorkerDispatcher

type WorkerDispatcher interface {
	Execute(siteID, deployKey string, env *Env, req *WorkerRequest) *WorkerResult
}

WorkerDispatcher executes a worker (used by service bindings to dispatch to other workers without a direct Engine dependency).

type WorkerRequest

type WorkerRequest struct {
	Method  string
	URL     string
	Headers map[string]string
	Body    []byte
}

WorkerRequest represents an incoming HTTP request to a worker.

type WorkerResponse

type WorkerResponse struct {
	StatusCode   int
	Headers      map[string]string
	Body         []byte
	HasWebSocket bool // true when status is 101 and webSocket was set
}

WorkerResponse represents the HTTP response from a worker.

type WorkerResult

type WorkerResult struct {
	Response  *WorkerResponse
	Logs      []LogEntry
	Error     error
	Duration  time.Duration
	WebSocket *WebSocketHandler // non-nil for WebSocket upgrade responses
}

WorkerResult wraps a response with execution metadata.

Jump to

Keyboard shortcuts

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