runtime

package
v1.7.8-553 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2026 License: Apache-2.0 Imports: 75 Imported by: 0

README

Runtime Package (pkg/runtime)

This package contains embeddable runtime features for Duso scripts. These features can be used:

  1. In the CLI - Registered by cmd/duso/main.go via pkg/cli/ wrappers
  2. In embedded Go applications - Used directly or wrapped as custom functions
  3. In custom distributions - Bundled into custom Duso binaries

Features Provided

HTTP Server

Type: HTTPServerValue

Create HTTP servers for handling requests. Routes are defined as Duso scripts.

// Direct Go usage
server := &runtime.HTTPServerValue{
    Port: 8080,
    Timeout: 30 * time.Second,
}
server.ListenAndServe()

// Via CLI wrapper (pkg/cli/http_server.go)
// Available in Duso scripts as: http_server({port = 8080})
HTTP Client

Type: HTTPClientValue

Make HTTP requests with built-in connection pooling.

// Direct Go usage
client, _ := runtime.NewHTTPClient(map[string]any{
    "timeout": 30.0,
})
response, _ := client.Send(map[string]any{
    "method": "GET",
    "url": "https://example.com",
})

// Via CLI wrapper (pkg/cli/http.go)
// Available in Duso scripts as: fetch("url", {timeout = 10})
Datastore

Type: DatastoreValue

Thread-safe in-memory key-value store with optional persistence. Perfect for coordinating work across concurrent scripts.

// Direct Go usage
store := runtime.GetDatastore("myapp", map[string]any{
    "persist": "data.json",
})
store.Set("counter", 0)
store.Increment("counter", 1)

// Via CLI wrapper (pkg/cli/datastore.go)
// Available in Duso scripts as: datastore("myapp", {persist = "data.json"})

Features:

  • Atomic operations (Set, Get, Increment, Append, Delete)
  • Condition variables (Wait, WaitFor)
  • Disk persistence (optional)
  • Per-namespace isolation
  • Global registry for cross-script coordination
Goroutine Context Management

Type: RequestContext

Store request-scoped context in goroutine-local storage. Used by spawn() and run() functions.

gid := runtime.GetGoroutineID()
ctx, exists := runtime.GetRequestContext(gid)
if exists {
    // Access request-specific data
}

runtime.SetRequestContextWithData(gid, &runtime.RequestContext{}, data)
defer runtime.ClearRequestContext(gid)

Use Cases:

  • HTTP request handling (route context)
  • Spawned script context (parent-child data passing)
  • Run/parallel execution (isolated contexts)

Package Organization

Files
  • datastore.go - Thread-safe coordination primitive
  • http_server.go - HTTP server implementation
  • http_client.go - HTTP client implementation
  • goroutine_context.go - Request context storage
  • metrics.go - Runtime metrics/monitoring
Key Types
  • DatastoreValue - Namespace-scoped key-value store
  • HTTPServerValue - HTTP server with route handling
  • HTTPClientValue - HTTP client with connection pooling
  • RequestContext - Request-scoped data container

For Embedded Applications

If you're embedding Duso and want runtime features:

import "github.com/duso-org/duso/pkg/cli"

interp := script.NewInterpreter(false)

// This registers runtime features as script functions
cli.RegisterFunctions(interp, cli.RegisterOptions{
    ScriptDir: "/path/to/scripts",
})

// Now scripts can use:
// - http_server() and fetch()
// - datastore()
// - spawn() and run()
// - context()
result, err := interp.Execute(`
    store = datastore("myapp")
    store.set("data", 42)
`)
Option 2: Direct Go Usage
import "github.com/duso-org/duso/pkg/runtime"

// Create and use datastore directly
store := runtime.GetDatastore("myapp", map[string]any{
    "persist": "data.json",
})
store.Set("key", "value")

// Create HTTP server directly
server := &runtime.HTTPServerValue{
    Port: 8080,
}
// ... configure routes, start server
Option 3: Wrap for Script Use
// Create custom wrapper function
interp.RegisterFunction("my_store", func(args map[string]any) (any, error) {
    namespace := args["0"].(string)
    store := runtime.GetDatastore(namespace, map[string]any{})

    // Return object with methods
    return map[string]any{
        "get": func(args map[string]any) (any, error) {
            key := args["0"].(string)
            return store.Get(key)
        },
        "set": func(args map[string]any) (any, error) {
            key := args["0"].(string)
            val := args["1"]
            return nil, store.Set(key, val)
        },
    }, nil
})

// Use in script
result, _ := interp.Execute(`
    s = my_store("test")
    s.set("x", 10)
    print(s.get("x"))
`)

Design Principles

  1. Embeddable - No dependencies on CLI or file I/O
  2. Concurrent - Safe for use across goroutines
  3. Flexible - Can be used directly in Go or wrapped for scripts
  4. Observable - Integrates with Duso's error handling and call stacks
  5. Persistent - Optional disk persistence for coordination

Thread Safety

All runtime types are thread-safe:

  • Datastore: Uses sync.RWMutex and sync.Cond for safe concurrent access
  • HTTP Client: Connection pooling is thread-safe
  • HTTP Server: Request handlers run in separate goroutines
  • Goroutine Context: Uses sync.Map for safe concurrent access

See Also

Documentation

Index

Constants

View Source
const (
	VAL_NIL      = script.VAL_NIL
	VAL_NUMBER   = script.VAL_NUMBER
	VAL_STRING   = script.VAL_STRING
	VAL_BOOL     = script.VAL_BOOL
	VAL_ARRAY    = script.VAL_ARRAY
	VAL_OBJECT   = script.VAL_OBJECT
	VAL_FUNCTION = script.VAL_FUNCTION
)

Value type constants

Variables

View Source
var (
	NewNil              = script.NewNil
	NewNumber           = script.NewNumber
	NewString           = script.NewString
	NewBool             = script.NewBool
	NewArray            = script.NewArray
	NewObject           = script.NewObject
	NewGoFunction       = script.NewGoFunction
	NewEnvironment      = script.NewEnvironment
	NewEvaluator        = script.NewEvaluator
	NewChildEnvironment = script.NewChildEnvironment
)

Value constructors

View Source
var (
	InterfaceToValue = script.InterfaceToValue
	ValueToInterface = script.ValueToInterface
	ArgKey           = script.ArgKey
)

Value conversion functions

View Source
var (
	IsInteger   = core.IsInteger
	DeepCopyAny = script.DeepCopyAny
)

Core utility functions

View Source
var (
	RegisterBuiltin = script.RegisterBuiltin
	CopyBuiltins    = script.CopyBuiltins
)

Registry functions

View Source
var ResolvePath func(string) string

ResolvePath is set by the host (CLI) to resolve special path prefixes. Handles /EMBED/, /STORE/, /HERE/, /CWD/, bare paths, and absolute paths. Set by cli.RegisterFunctions() during initialization.

Functions

func ClearContextGetter

func ClearContextGetter(gid uint64)

ClearContextGetter removes a context getter from goroutine-local storage

func ClearRequestContext

func ClearRequestContext(gid uint64)

ClearRequestContext removes a request context from goroutine-local storage

func CloseAllConnections

func CloseAllConnections()

CloseAllConnections closes all active WebSocket connections Used during server shutdown to ensure Ctrl+C interrupts waiting connections

func GetArg

func GetArg(args map[string]any, index int, name string) any

GetArg retrieves an argument by name or position (0-indexed) Checks named arg first, then positional

func GetContext

func GetContext(gid uint64) any

GetContext calls the appropriate getter for the current goroutine's context

func GetDatastoreCount

func GetDatastoreCount() int

GetDatastoreCount returns the number of registered datastores Used by system metrics to report datastore count

func GetGoroutineID

func GetGoroutineID() uint64

GetGoroutineID extracts the current goroutine ID from the stack trace

func GracefulShutdown

func GracefulShutdown()

GracefulShutdown closes WebSockets, drains every running HTTP server, then flushes every datastore. It returns when all of that is done, and returns immediately on any call after the first has completed.

func IncrementRunProcs

func IncrementRunProcs()

IncrementRunProcs increments the run process counter

func IncrementSpawnProcs

func IncrementSpawnProcs() int64

IncrementSpawnProcs returns the next unique spawn process ID

func InitExecAllowlist

func InitExecAllowlist() error

InitExecAllowlist reads -allow-exec from the sys datastore and resolves it. Called once at startup, before any script runs. A returned error is fatal: an operator who asked for a command that isn't there wants to hear about it now, not at 3am when the handler first fires.

func IsWebSocketUpgrade

func IsWebSocketUpgrade(r *http.Request) bool

IsWebSocketUpgrade checks if the request is a WebSocket upgrade request

func RegisterBuiltins

func RegisterBuiltins()

RegisterBuiltins registers all builtin functions in the global script registry. This is called once at startup before any scripts are executed.

func RegisterConnection

func RegisterConnection(conn *WebSocketConnection)

RegisterConnection adds a connection to the global registry

func SetContextGetter

func SetContextGetter(gid uint64, getter ContextGetter)

SetContextGetter stores a context getter function in goroutine-local storage The getter will be called by context() builtin to retrieve context data lazily

func SetInterpreter

func SetInterpreter(interp *script.Interpreter)

SetInterpreter sets the global interpreter instance for use by builtins

func SetRequestContextWithData

func SetRequestContextWithData(gid uint64, ctx *RequestContext, spawnedData any)

SetRequestContextWithData stores a request context with optional spawned context data

func ShutdownAllDatastores

func ShutdownAllDatastores()

ShutdownAllDatastores flushes every registered datastore: WAL synced and closed, then a final snapshot for any store configured to persist.

Without this, a store configured with persist but no persist_interval never writes its file at all - the snapshot ticker only runs when an interval is set, so the only other writer is an explicit save().

func ShutdownComplete

func ShutdownComplete() <-chan struct{}

ShutdownComplete is closed once every server has drained and every datastore has flushed.

func ShutdownRequested

func ShutdownRequested() <-chan struct{}

ShutdownRequested is closed when shutdown begins. A blocked http_server waits on it instead of handling signals itself, so there is one signal owner.

func SignalInterrupt

func SignalInterrupt()

SignalInterrupt closes the interrupt channel to wake up all blocked read operations This is called when Ctrl+C or similar signals are received

func UnregisterConnection

func UnregisterConnection(connID string)

UnregisterConnection removes a connection from the global registry

func WebSocketHandler

func WebSocketHandler(upgradeHandler func(*WebSocketConnection, *http.Request) error) http.Handler

WebSocketHandler creates an http.Handler that performs WebSocket upgrade and calls the provided upgrade handler

Types

type BreakpointError

type BreakpointError = script.BreakpointError

Type aliases to avoid script. prefix throughout runtime builtins

type CORSConfig

type CORSConfig struct {
	Enabled          bool
	AllowedOrigins   []string // ["*"] or specific origins
	AllowedMethods   []string
	AllowedHeaders   []string
	AllowCredentials bool
	MaxAge           int
}

CORSConfig holds CORS (Cross-Origin Resource Sharing) settings

type CallFrame

type CallFrame = script.CallFrame

Type aliases to avoid script. prefix throughout runtime builtins

type ContextGetter

type ContextGetter func() any

ContextGetter is a function that returns a RequestContext (or any object with matching interface) for the current execution. Returns nil if no context is available.

func GetContextGetter

func GetContextGetter(gid uint64) (ContextGetter, bool)

GetContextGetter retrieves a context getter function from goroutine-local storage

type DatastoreValue

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

DatastoreValue represents an in-memory thread-safe key/value store scoped to a specific namespace. Multiple scripts can access the same store by using the same namespace. Optionally persists to JSON and/or WAL.

func GetDatastore

func GetDatastore(namespace string, config map[string]any) *DatastoreValue

GetDatastore returns or creates a namespaced datastore with optional persistence config

func (*DatastoreValue) Clear

func (ds *DatastoreValue) Clear() error

Clear removes all keys from the store

func (*DatastoreValue) Count

func (ds *DatastoreValue) Count(evaluator *Evaluator, predicateFn Value) (float64, error)

Count returns the number of entries for which the predicate returns a truthy value. Like Select but counts instead of collecting — avoids building/copying a result array. Predicate receives (key, value); truthy returns are counted, falsy (nil/false/0/"") are not.

func (*DatastoreValue) Delete

func (ds *DatastoreValue) Delete(key string) (any, error)

WaitFor blocks until predicate(value) returns true For array values, predicate receives the array length as a number Predicate is a Duso function that takes one argument and returns a boolean Timeout is optional (pass 0 for no timeout) Returns the current value of the key after the predicate is true, or error on timeout Delete removes a key from the store and returns the deleted value (or nil if key didn't exist)

func (*DatastoreValue) Exists

func (ds *DatastoreValue) Exists(key string) bool

Exists checks if a key exists in the datastore (thread-safe)

func (*DatastoreValue) Expire

func (ds *DatastoreValue) Expire(key string, ttlSeconds float64) error

Expire sets a time-to-live (TTL) for a key in seconds The key will be automatically deleted when the TTL expires Calling expire() on an existing key resets the TTL Returns error if the key doesn't exist

func (*DatastoreValue) Get

func (ds *DatastoreValue) Get(key string) (any, error)

Get retrieves a value by key (thread-safe)

func (*DatastoreValue) Increment

func (ds *DatastoreValue) Increment(key string, delta float64) (any, error)

Increment atomically increments a numeric value by delta Creates the key with value delta if it doesn't exist

func (*DatastoreValue) Keys

func (ds *DatastoreValue) Keys() []string

Keys returns a slice of all keys in the datastore

func (*DatastoreValue) Load

func (ds *DatastoreValue) Load() error

Load explicitly loads the datastore from disk (JSON)

func (*DatastoreValue) Pop

func (ds *DatastoreValue) Pop(key string) (any, error)

Pop atomically removes and returns the last element from an array Returns error if key doesn't exist or is not an array. Returns nil if array is empty.

func (*DatastoreValue) PopWait

func (ds *DatastoreValue) PopWait(procCtx context.Context, key string, timeout time.Duration) (any, error)

PopWait atomically removes and returns the last element from an array Blocks until array has items or timeout expires Returns nil if timeout exceeded and array is still empty Returns error if key exists but is not an array

func (*DatastoreValue) Push

func (ds *DatastoreValue) Push(key string, item any) (float64, error)

Push atomically pushes an item to an array Creates the array if key doesn't exist. Returns new array length. Returns error if key exists but is not an array.

func (*DatastoreValue) Rename

func (ds *DatastoreValue) Rename(oldKey, newKey string) error

Rename atomically renames a key (moves value to new key, deletes old key) Returns error if oldKey doesn't exist or if newKey already exists

func (*DatastoreValue) Save

func (ds *DatastoreValue) Save() error

Save explicitly saves the datastore to disk (JSON)

func (*DatastoreValue) Select

func (ds *DatastoreValue) Select(evaluator *Evaluator, predicateFn Value, max int) ([]any, error)

Select queries the datastore by running a predicate function on each key-value pair. The predicate receives (key, value) and returns: - nil to exclude this entry - any non-nil value to include it in the results Results are deep-copied to isolate from datastore mutations. Snapshot keys at start, then lock per-key during iteration for minimal blocking. Returns error if the predicate throws. Select runs predicate on each key/value, collecting non-nil returns. If max > 0, iteration stops as soon as max results are collected. Map iteration order is non-deterministic, so with max > 0 you get *any* matching entries, not a deterministic "first N".

func (*DatastoreValue) Set

func (ds *DatastoreValue) Set(key string, value any) error

Set stores a value by key (thread-safe)

func (*DatastoreValue) SetOnce

func (ds *DatastoreValue) SetOnce(key string, value any) (bool, error)

SetOnce stores a value by key only if the key doesn't already exist (thread-safe) Returns true if the value was set, false if the key already existed Useful for caching patterns where multiple concurrent requests might try to set the same key

Returns an error separately from the false result: "the key already existed" and "this write was rejected" are different outcomes, and collapsing them into one bool hides a failed write behind an ordinary-looking cache miss.

func (*DatastoreValue) Shift

func (ds *DatastoreValue) Shift(key string) (any, error)

Shift atomically removes and returns the first element from an array Returns error if key doesn't exist or is not an array. Returns nil if array is empty.

func (*DatastoreValue) ShiftWait

func (ds *DatastoreValue) ShiftWait(procCtx context.Context, key string, timeout time.Duration) (any, error)

ShiftWait atomically removes and returns the first element from an array Blocks until array has items or timeout expires Returns nil if timeout exceeded and array is still empty Returns error if key exists but is not an array

func (*DatastoreValue) Shutdown

func (ds *DatastoreValue) Shutdown() error

Shutdown stops the auto-save ticker and expiry ticker, and saves final state

func (*DatastoreValue) Swap

func (ds *DatastoreValue) Swap(key string, newValue any) (any, error)

Swap atomically exchanges a key's value for a new value (thread-safe) Returns the old value that was at the key Useful for consuming inboxes or implementing atomic exchange patterns

func (*DatastoreValue) Unshift

func (ds *DatastoreValue) Unshift(key string, item any) (float64, error)

Unshift atomically prepends an item to an array Creates the array if key doesn't exist. Returns new array length. Returns error if key exists but is not an array.

func (*DatastoreValue) Update

func (ds *DatastoreValue) Update(key string, updates any) (any, error)

Update atomically reads, deep merges updates into an object, and returns the updated object Creates an empty object if key doesn't exist Returns error if key exists but is not an object Supports nil values to delete keys from the object (shallow deletion only)

func (*DatastoreValue) Wait

func (ds *DatastoreValue) Wait(procCtx context.Context, key string, expectedValue any, hasExpectedValue bool, timeout time.Duration) (any, error)

For array values, this means waiting for length to change (new append) If expectedValue is provided, waits until key equals that value Timeout is optional (pass 0 for no timeout) Returns the current value of the key after the condition is met, or error on timeout

func (*DatastoreValue) WaitWithPredicate

func (ds *DatastoreValue) WaitWithPredicate(procCtx context.Context, evaluator *Evaluator, key string, predicateFn Value, timeout time.Duration) (any, error)

Wait blocks until the key changes (if no expectedValue) or equals expectedValue (if provided) If expectedValue is nil (omitted), waits for ANY change to the key WaitWithPredicate waits until a predicate function returns true for the key's value The predicate is called with the current value and should return true when condition is met Timeout is optional (pass 0 for no timeout) Returns the current value of the key after the predicate returns true, or error on timeout

type DusoError

type DusoError = script.DusoError

Type aliases to avoid script. prefix throughout runtime builtins

type EncryptedValue

type EncryptedValue struct {
	Data any
}

EncryptedValue is a wrapper for gob encoding/decoding encrypted data

type Environment

type Environment = script.Environment

Type aliases to avoid script. prefix throughout runtime builtins

type Evaluator

type Evaluator = script.Evaluator

Type aliases to avoid script. prefix throughout runtime builtins

type ExitExecution

type ExitExecution = script.ExitExecution

Exception types

type ExpiryEntry

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

ExpiryEntry represents a key and its expiration time in the min-heap

type ExpiryHeap

type ExpiryHeap []ExpiryEntry

ExpiryHeap implements container/heap.Interface for a min-heap sorted by expiryTime

func (ExpiryHeap) Len

func (h ExpiryHeap) Len() int

func (ExpiryHeap) Less

func (h ExpiryHeap) Less(i, j int) bool

func (*ExpiryHeap) Pop

func (h *ExpiryHeap) Pop() any

func (*ExpiryHeap) Push

func (h *ExpiryHeap) Push(x any)

func (ExpiryHeap) Swap

func (h ExpiryHeap) Swap(i, j int)

type GoFunction

type GoFunction = script.GoFunction

Type aliases to avoid script. prefix throughout runtime builtins

type HTTPClientValue

type HTTPClientValue struct {
	BaseURL string            // Optional base URL for relative requests
	Headers map[string]string // Default headers for all requests
	Config  map[string]any    // Full config map (base_url, timeout, etc)
	// contains filtered or unexported fields
}

HTTPClientValue represents a stateful HTTP client in Duso. It wraps Go's net/http.Client and provides methods for sending requests.

func NewHTTPClient

func NewHTTPClient(config map[string]any) (*HTTPClientValue, error)

NewHTTPClient creates a new HTTP client from Duso configuration.

func (*HTTPClientValue) Close

func (hc *HTTPClientValue) Close() error

Close closes the HTTP client's idle connections (for cleanup).

func (*HTTPClientValue) Send

func (hc *HTTPClientValue) Send(requestObj map[string]any) (map[string]any, error)

Send executes an HTTP request and returns a response object. Request object structure: {method, url, body, headers, query} Response object structure: {status, body, headers}

type HTTPServerValue

type HTTPServerValue struct {
	Port                    int
	Address                 string // bind address (default "0.0.0.0")
	TLSEnabled              bool
	CertFile                string
	KeyFile                 string
	CertReloadInterval      time.Duration   // How often to re-check cert_file/key_file for renewals (default: 24h)
	Timeout                 time.Duration   // Socket-level read/write timeout
	RequestHandlerTimeout   time.Duration   // Handler script execution timeout
	ShowDirectoryListing    bool            // Show directory listing when no default file found
	DefaultFiles            []string        // Default filenames to try in order (e.g., index.html, index.md)
	CacheControl            string          // Default Cache-Control header (e.g., "no-cache, no-store, must-revalidate")
	CORS                    CORSConfig      // CORS configuration
	JWT                     JWTConfig       // JWT configuration
	Upload                  UploadConfig    // Upload configuration
	WebSocket               WebSocketConfig // WebSocket configuration
	MaxWebSocketConnections int             // Max concurrent WebSocket connections (0 = unlimited)
	MaxBodySize             int64           // Max request body size in bytes (default: 10MB)
	MaxHeaderSize           int64           // Max per-header size in bytes (default: 8KB)
	MaxHeaders              int             // Max number of headers (default: 100)
	MaxFormFields           int             // Max form fields in multipart (default: 1000)
	IdleTimeout             time.Duration   // Idle connection timeout (default: 120s)
	AccessLog               bool            // Enable access logging to stderr (default: true)
	StaticCacheControl      string          // Cache-Control header for static files (default: "public, max-age=3600")

	Interpreter *script.Interpreter // Interpreter for getting current script path
	FileReader  func(string) ([]byte, error)
	FileStatter func(string) int64                     // Returns mtime, 0 if error
	DirReader   func(string) ([]map[string]any, error) // Lists directory contents, supports /EMBED/ and /STORE/
	// contains filtered or unexported fields
}

HTTPServerValue represents an HTTP server in Duso. It manages routes and spawns handler scripts for incoming requests.

func (*HTTPServerValue) Route

func (s *HTTPServerValue) Route(methodArg any, path, handlerPath string, handlerCode *script.Program) error

Route registers a new route (thread-safe). method can be: string ("GET", "get", "", "*"), nil, or []string for multiple methods

func (*HTTPServerValue) Start

func (s *HTTPServerValue) Start() error

Start is a convenience method that calls StartWithContext(nil) for compatibility with existing code

func (*HTTPServerValue) StartWithContext

func (s *HTTPServerValue) StartWithContext(procCtx context.Context) error

Start launches the HTTP server and blocks until the process receives a termination signal. This allows the script to handle cleanup code after the server stops. Returns an error if the server fails to bind to the port.

func (*HTTPServerValue) StaticRoute

func (s *HTTPServerValue) StaticRoute(path, staticDir string) error

StaticRoute registers a static file route (thread-safe). Serves files from staticDir for requests matching the path prefix.

type JWTConfig

type JWTConfig struct {
	Enabled         bool
	Secret          string // HS256 secret
	RS256PrivateKey string // PEM-encoded RSA private key for signing
	RS256PublicKey  string // PEM-encoded RSA public key for verification
	Required        bool
}

JWTConfig holds JWT (JSON Web Token) settings

type RequestContext

type RequestContext struct {
	Request *http.Request       // HTTP request (if HTTP handler), nil otherwise
	Writer  http.ResponseWriter // HTTP response writer (if HTTP handler), nil otherwise
	Data    any                 // Generic context data (used by spawn/run)

	PathParams      map[string]any               // Extracted path parameters from route pattern (e.g., {id: "123"})
	Frame           *script.InvocationFrame      // Root invocation frame for this context
	ExitChan        chan any                     // Channel to receive exit value from script
	FileReader      func(string) ([]byte, error) // File reader function (for serving files in responses)
	ResponseData    map[string]any               // Response data to be sent (set by response helpers)
	JWTSecret       string                       // JWT secret for HS256 signing/verification (HTTP context only)
	RS256PrivateKey string                       // PEM-encoded RSA private key for RS256 signing (HTTP context only)
	RS256PublicKey  string                       // PEM-encoded RSA public key for RS256 verification (HTTP context only)
	CacheControl    string                       // Default Cache-Control header for response helpers (HTTP context only)
	MaxBodySize     int64                        // Max request body size in bytes (HTTP context only)
	MaxFormFields   int                          // Max form fields in multipart (HTTP context only)
	Upload          UploadConfig                 // Upload configuration (HTTP context only)
	WSConnection    any                          // WebSocket connection (if WebSocket handler), nil otherwise
	// contains filtered or unexported fields
}

RequestContext holds context data for a handler script Used for HTTP requests, WebSocket connections, spawn() calls, run() calls - anything that needs context

func GetRequestContext

func GetRequestContext(gid uint64) (*RequestContext, bool)

GetRequestContext retrieves a request context from goroutine-local storage

func (*RequestContext) GetRequest

func (rc *RequestContext) GetRequest() any

GetRequest returns the request data for the context() builtin For spawn/run contexts, returns the Data field as-is For HTTP contexts, returns parsed HTTP request data. The HTTP branch builds script Values directly and returns a *ValueRef so the builtin return path skips a second deep conversion of the whole object.

func (*RequestContext) GetResponse

func (rc *RequestContext) GetResponse() map[string]any

GetResponse returns an object with response helper methods for use in HTTP handler scripts This is HTTP-specific and includes sign_jwt if JWT is configured

func (*RequestContext) GetWSConnection

func (rc *RequestContext) GetWSConnection() map[string]any

GetWSConnection returns the WebSocket connection object for use in handlers

func (*RequestContext) SendResponse

func (rc *RequestContext) SendResponse(data map[string]any) error

SendResponse stores response data for handler processing (instead of writing immediately, uses same path as exit() via sendHTTPResponse)

type Route

type Route struct {
	Method      string
	Path        string
	HandlerPath string
	HandlerCode *script.Program // Pre-parsed code to execute (if provided via parse())
	ScriptDir   string          // Directory of the script that registered this route (for handler path resolution)
	PathParams  []string        // Parameter names extracted from path pattern (e.g., ["id", "token"])
	PathRegex   *regexp.Regexp  // Compiled regex for matching (nil if no params)
	IsStatic    bool            // True if this is a static file route
	StaticDir   string          // Directory to serve files from (for static routes)
	IsWebSocket bool            // True if this is a WebSocket route (Method == "WS")
}

Route represents a registered HTTP route

type ScriptFunction

type ScriptFunction = script.ScriptFunction

Type aliases to avoid script. prefix throughout runtime builtins

type StringReader

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

StringReader is a simple reader for strings.

func (*StringReader) Read

func (sr *StringReader) Read(p []byte) (n int, err error)

type UploadConfig

type UploadConfig struct {
	Enabled bool
	MaxSize int64         // max bytes per file
	Timeout time.Duration // reserved for future dedicated upload timeout
}

UploadConfig holds file upload settings

type Value

type Value = script.Value

Type aliases to avoid script. prefix throughout runtime builtins

type ValueRef

type ValueRef = script.ValueRef

Type aliases to avoid script. prefix throughout runtime builtins

type WALEntry

type WALEntry struct {
	Key   string
	Value any
}

WALEntry represents a key-value write in the Write-Ahead Log

type WebSocketConfig

type WebSocketConfig struct {
	ReadQueueSize        int
	WriteQueueSize       int
	DefaultReadTimeout   time.Duration
	IdleTimeout          time.Duration // 0 = no idle disconnect
	MaxMessageSize       int64         // 0 = unlimited
	MaxMessagesPerSecond int           // 0 = unlimited
}

WebSocketConfig holds configuration for WebSocket connections

func DefaultWebSocketConfig

func DefaultWebSocketConfig() WebSocketConfig

DefaultWebSocketConfig returns sensible defaults

type WebSocketConnection

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

WebSocketConnection represents an active WebSocket connection in Duso

func GetConnection

func GetConnection(connID string) *WebSocketConnection

GetConnection retrieves a connection by ID

func NewWebSocketClientConnection

func NewWebSocketClientConnection(urlStr string, headers map[string]string) (*WebSocketConnection, error)

NewWebSocketClientConnection creates a client WebSocket connection

func NewWebSocketClientConnectionWithConfig

func NewWebSocketClientConnectionWithConfig(urlStr string, headers map[string]string, config WebSocketConfig) (*WebSocketConnection, error)

NewWebSocketClientConnectionWithConfig creates a client connection with custom config

func NewWebSocketConnection

func NewWebSocketConnection(ws *websocket.Conn) *WebSocketConnection

NewWebSocketConnection creates a new WebSocket connection wrapper (server-side)

func NewWebSocketConnectionWithConfig

func NewWebSocketConnectionWithConfig(ws *websocket.Conn, config WebSocketConfig) *WebSocketConnection

NewWebSocketConnectionWithConfig creates a connection with custom config

func (*WebSocketConnection) Accept

func (wsc *WebSocketConnection) Accept() error

Accept accepts the WebSocket connection (protocol handshake already done by upgrade)

func (*WebSocketConnection) Close

func (wsc *WebSocketConnection) Close() error

Close closes the WebSocket connection

func (*WebSocketConnection) ID

func (wsc *WebSocketConnection) ID() string

ID returns the unique identifier for this connection

func (*WebSocketConnection) IsConnected

func (wsc *WebSocketConnection) IsConnected() bool

IsConnected returns whether the connection is still open

func (*WebSocketConnection) Read

func (wsc *WebSocketConnection) Read(timeout *time.Duration) (string, error)

Read checks the read queue, blocking with optional timeout if empty Returns message string on success (including empty string), error on disconnect If timeout is specified and expires, returns ("", nil) to indicate timeout

func (*WebSocketConnection) Write

func (wsc *WebSocketConnection) Write(message string) any

Write queues a message to the write queue Returns number of bytes queued, or nil if queue is full

Directories

Path Synopsis
Package markdown is a CommonMark-compliant markdown parser/renderer purpose-built as a small, dependency-free replacement for goldmark.
Package markdown is a CommonMark-compliant markdown parser/renderer purpose-built as a small, dependency-free replacement for goldmark.

Jump to

Keyboard shortcuts

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