runtime

package
v0.1.0-alpha.56 Latest Latest
Warning

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

Go to latest
Published: Aug 28, 2026 License: MIT Imports: 36 Imported by: 0

Documentation

Overview

Package runtime provides GoBeyond's Node-free production HTTP server.

Index

Constants

View Source
const (
	// EnvStaticDir names the environment variable pointing at the built
	// static directory (dist/static). Preview and origin servers use it when
	// CloudFront/S3 is not in front of the process.
	EnvStaticDir = "GOBEYOND_STATIC_DIR"
	// EnvDeploymentKind is injected by the hosting platform. Preview sites
	// receive platform-owned crawler policy regardless of customer assets.
	EnvDeploymentKind = "GOBEYOND_DEPLOYMENT_KIND"
)
View Source
const DefaultStaticMaxEntries = 128

DefaultStaticMaxEntries is the residency entry bound for static entry stores. Plan stores use residency.DefaultMaxEntries; both share the package's byte and idle defaults.

View Source
const HostedRuntimeEnv = "GOBEYOND_HOSTED_RUNTIME"

HostedRuntimeEnv disables the single-origin host admission fallback. The GoBeyond platform performs authoritative host admission before forwarding a request to a customer runtime, and a deployment may serve several assigned domains from one long-lived process. Customer applications must not set this themselves when they are directly internet-facing.

View Source
const PlatformOriginEnv = "GOBEYOND_PLATFORM_ORIGIN"

PlatformOriginEnv is the reserved origin used for the transparent route-miss fallback. Hosted adapters set it to the authenticated internal platform ingress; local development normally leaves it unset.

Variables

This section is empty.

Functions

func FetchOriginFromEnv

func FetchOriginFromEnv() (gb.Fetcher, error)

FetchOriginFromEnv configures the hosted fallback from the reserved platform environment. An unset value is valid and disables fallback, which is the expected local-development behavior.

func LoadContracts

func LoadContracts(path string) (*codegen.Document, error)

LoadContracts reads the build's value-contract document, which a server needs as Config.Contracts before any route may cache its props.

func LoadProxyPolicy

func LoadProxyPolicy(filename, buildID string) (*gb.ProxyPolicy, error)

LoadProxyPolicy loads the immutable deployment artifact emitted by the GoBeyond build. Missing artifacts are allowed only for legacy/custom local runtimes during the transition; new builds always emit one.

func NewPlatformOriginFetcher

func NewPlatformOriginFetcher(origin string, client *http.Client) (gb.Fetcher, error)

NewPlatformOriginFetcher creates the trusted origin transport used by gb.Fetch after same-slot route classification reports a miss.

func ProxyPolicyHandler

func ProxyPolicyHandler(proxyPolicy *gb.ProxyPolicy, next http.Handler) http.Handler

ProxyPolicyHandler applies the immutable build policy before the wrapped origin handler, including when that handler is StaticFiles. It is a platform/origin routing concern, not the authored Go middleware hook. Reserved GoBeyond paths remain outside customer policy.

func StaticFiles

func StaticFiles(directory string, next http.Handler) http.Handler

StaticFiles serves build artifacts and public files from directory (typically GOBEYOND_STATIC_DIR), then falls through to next for everything else.

Content-addressed build paths under /_gobeyond/builds/.../assets|manifest|static get Cache-Control: public, max-age=31536000, immutable. Non-hashed public/ files are served without that header. Compressible responses (JS, CSS, SVG, JSON, HTML, source maps) are gzip-compressed when the client accepts gzip, matching document/API gzip in Server.ServeHTTP.

An empty directory disables static serving and returns next unchanged.

func StaticFilesFromEnv

func StaticFilesFromEnv(next http.Handler) http.Handler

StaticFilesFromEnv is StaticFiles(os.Getenv(EnvStaticDir), next).

Types

type APIRoute

type APIRoute struct {
	Route   router.Route
	Methods map[string]gb.Handler
}

type Action

type Action struct {
	ID      string
	MaxBody int64
	// contains filtered or unexported fields
}

func RegisterAction

func RegisterAction[Input, Output any](
	id string,
	decode func(json.RawMessage) (Input, error),
	validateOutput func(Output) error,
	handler func(*gb.ActionContext, Input) (Output, error),
) Action

RegisterAction binds a generated input decoder and output validator to a typed application handler. The decoder runs before application code and the validator runs before a successful result can cross the HTTP boundary.

type Config

type Config struct {
	BuildID             string
	PublicOrigin        string
	ResolvePublicOrigin PublicOriginResolver
	AllowedHosts        []string
	BrowserAssets       *browserassets.Manifest
	Pages               []PageRoute
	Actions             []Action
	APIs                []APIRoute
	// Middleware is the one authored Go request hook discovered from the
	// application's root middleware.go. It is applied to documents, APIs,
	// actions, and runtime payloads, but not health, static, or image routes.
	Middleware gb.Middleware
	// ProxyPolicy is the validated build artifact shared by the origin and the
	// platform edge. It runs before route classification, including static and
	// image dispatch, while reserved GoBeyond paths remain outside it.
	ProxyPolicy *gb.ProxyPolicy
	// FetchOrigin is the trusted platform-origin fallback used by gb.Fetch
	// when the current build has no matching local route. It is intentionally
	// injected by hosted adapters; application code never selects the fallback
	// transport.
	FetchOrigin   gb.Fetcher
	CSRF          *security.CSRF
	Logger        *slog.Logger
	Deadlines     gb.DeadlinePolicy
	MaxHeaderSize int
	ImageLoader   imageopt.Loader
	// Cache installs the request-time cache (cache.Load, cache.Revalidate*).
	// Leave it nil to run without one: loaders then compute every value. The
	// server owns Cache.BuildID - it must be empty or equal to Config.BuildID,
	// so one build can never read another build's cached shapes - and defaults
	// Cache.Store to a bounded in-process L1, which is the degraded mode of a
	// deployment with no shared cache endpoint configured.
	Cache *cache.RuntimeConfig
	// Contracts is the build's value-contract document. Route caching needs
	// it: cached props cross JSON, and only the contract says which strings
	// were renderplan.SafeHTML before they did, so decoding without it would
	// either lose the trust marker or restore it blindly. A server with a
	// cache and a route that sets Revalidate must supply it. When nil and
	// Static is set, it defaults to Static.Contracts().
	Contracts *codegen.Document
	// PlanStore supplies render plans on demand for pages that omit an
	// inline Plan. New verifies membership per page and that the
	// store's build ID equals BuildID exactly; the decode itself is deferred
	// to the first request that must render the route. An inline
	// PageRoute.Plan always wins over the store.
	PlanStore PlanStore
	// Static supplies packaged static page data on demand for pages that
	// ship neither inline Static data nor a loader. Its build ID must be
	// empty (build-agnostic adapters such as the eager StaticStore) or equal
	// BuildID.
	Static StaticEntries
}

type LoadedPage

type LoadedPage struct {
	Kind            gb.ResultKind  `json:"kind"`
	Props           any            `json:"props,omitempty"`
	Metadata        gb.Metadata    `json:"metadata,omitempty"`
	Status          int            `json:"status,omitempty"`
	Headers         http.Header    `json:"headers,omitempty"`
	Cache           gb.CachePolicy `json:"cache"`
	RedirectTo      string         `json:"redirectTo,omitempty"`
	ErrorCode       string         `json:"errorCode,omitempty"`
	Message         string         `json:"message,omitempty"`
	CacheGeneration string         `json:"cacheGeneration,omitempty"`
}

func FromPageResult

func FromPageResult[T any](result gb.PageResult[T]) LoadedPage

FromPageResult converts the public route-authoring result into the runtime representation consumed by the server. Route packages should return gb.PageResult so they do not need to import this package.

type LoadedPageEntry

type LoadedPageEntry struct {
	Params map[string]any
	Page   LoadedPage
}

type PackPlanStore

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

PackPlanStore is the pack-backed PlanStore: an open render-plan pack (.gbp) behind a bounded residency cache. Opening validates the container header and index only; a route's plan is read, digest-verified, and parsed the first time a request needs it, then stays resident subject to the cache's entry, byte, and idle bounds. The application owns Close.

func OpenPlanStore

func OpenPlanStore(path string, opts ...StoreOption) (*PackPlanStore, error)

OpenPlanStore opens the render-plan pack at path. Without options the residency cache uses the plan defaults: 64 entries, 32 MiB estimated decoded bytes, 10 minute idle expiry.

func (*PackPlanStore) BuildID

func (s *PackPlanStore) BuildID() string

func (*PackPlanStore) Close

func (s *PackPlanStore) Close() error

Close releases the residency cache and the underlying pack file.

func (*PackPlanStore) Has

func (s *PackPlanStore) Has(routeID string) bool

func (*PackPlanStore) Plan

func (s *PackPlanStore) Plan(ctx context.Context, routeID string) (*renderplan.Plan, error)

Plan returns the decoded render plan for routeID, loading it through the residency cache on a miss. Concurrent requests for the same route share one decode.

func (*PackPlanStore) Stats

func (s *PackPlanStore) Stats() residency.Stats

Stats snapshots the residency cache behind the store.

func (*PackPlanStore) Trim

func (s *PackPlanStore) Trim(targetBytes int64)

Trim evicts resident plans until estimated bytes are at or below targetBytes. Plans already handed to in-flight requests remain valid.

type PackStaticStore

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

PackStaticStore is the pack-backed StaticEntries: an open static-entry pack (.gbs) plus the build's value contracts, behind a bounded residency cache. Entries are decoded on first use - props re-marked as SafeHTML through the contracts exactly like the eager LoadStaticStore path - and stay resident subject to the cache bounds. The application owns Close.

func OpenStaticStore

func OpenStaticStore(path, contractsPath string, opts ...StoreOption) (*PackStaticStore, error)

OpenStaticStore opens the static-entry pack at path together with the value-contract document at contractsPath. Without options the residency cache uses the static defaults: 128 entries, 32 MiB estimated decoded bytes, 10 minute idle expiry.

func (*PackStaticStore) BuildID

func (s *PackStaticStore) BuildID() string

func (*PackStaticStore) Close

func (s *PackStaticStore) Close() error

Close releases the residency cache and the underlying pack file.

func (*PackStaticStore) Contracts

func (s *PackStaticStore) Contracts() *codegen.Document

Contracts returns the value-contract document the entries were packaged against, so New can default Config.Contracts from the store.

func (*PackStaticStore) Entry

func (s *PackStaticStore) Entry(ctx context.Context, routeID string, params map[string]string) (LoadedPage, bool, error)

Entry returns the packaged page for (routeID, params), loading it through the residency cache on a miss. A key absent from the pack index is a plain miss - (LoadedPage{}, false, nil) - so the caller can render its packaged not-found shape; pack read and decode failures are errors.

func (*PackStaticStore) Has

func (s *PackStaticStore) Has(routeID string) bool

Has reports whether the pack carries at least one entry for routeID.

func (*PackStaticStore) Stats

func (s *PackStaticStore) Stats() residency.Stats

Stats snapshots the residency cache behind the store.

func (*PackStaticStore) Trim

func (s *PackStaticStore) Trim(targetBytes int64)

Trim evicts resident entries until estimated bytes are at or below targetBytes. Entries already handed to in-flight requests remain valid.

type PageLoader

type PageLoader func(*gb.PageContext) (LoadedPage, error)

type PageRoute

type PageRoute struct {
	Route  router.Route
	Plan   *renderplan.Plan
	Load   PageLoader
	Static *LoadedPage
	// Revalidate is how long the origin may reuse this route's loaded props,
	// metadata, status, and kind for one URL, from definePage({ revalidate }).
	// Zero leaves the route uncached. It is route metadata, deliberately not
	// part of gb.CachePolicy: CachePolicy is the HTTP edge header the loader
	// returns, this is how often the Go origin re-runs the loader. A route
	// that sets both should derive the edge policy from this window
	// (gb.PublicRevalidate) rather than letting the two drift apart.
	Revalidate time.Duration
	// Tags are the route's invalidation handles, from definePage({ tags }).
	// cache.RevalidateTag on any of them drops this route's cached entries;
	// cache.RevalidatePath drops one URL's entry without them.
	Tags         []string
	Indexable    bool
	ClientScript string
	Styles       []string
}

type PlanStore

type PlanStore interface {
	BuildID() string
	Has(routeID string) bool
	Plan(ctx context.Context, routeID string) (*renderplan.Plan, error)
}

PlanStore supplies render plans on demand for pages whose PageRoute.Plan is nil. New checks Has for every such page and rejects a store whose BuildID differs from Config.BuildID, so a request that reaches Plan can trust the answer belongs to this build. Plan is called only when a document must actually render - after loaders, redirects, and error short-circuits - never at New.

type PublicOriginResolver

type PublicOriginResolver func(*http.Request) (string, error)

PublicOriginResolver resolves the canonical absolute origin for a request. It is useful behind trusted reverse proxies and custom-domain front doors. Resolvers must reject hosts they do not recognize.

type Server

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

func New

func New(config Config) (*Server, error)

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request)

type StaticEntries

type StaticEntries interface {
	BuildID() string
	Has(routeID string) bool
	Entry(ctx context.Context, routeID string, params map[string]string) (LoadedPage, bool, error)
	Contracts() *codegen.Document
}

StaticEntries supplies packaged static page data on demand for pages that ship neither inline Static data nor a loader. BuildID may be empty for build-agnostic adapters (the eager JSON StaticStore); a non-empty BuildID must equal Config.BuildID. Entry returns ok=false without error when the route is known but no entry was packaged for the given params; pack-level failures surface as errors. Contracts returns the value-contract document the entries were packaged against, which New adopts as Config.Contracts when the caller supplied none.

type StaticStore

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

StaticStore is the startup-loaded, packaged build data used for soft navigation and for static pages promoted to the Go origin by middleware.

func LoadStaticStore

func LoadStaticStore(buildPath, contractsPath string) (*StaticStore, error)

func (*StaticStore) BuildID

func (s *StaticStore) BuildID() string

BuildID identifies the eager store as build-agnostic: the JSON artifact carries no build header, so New accepts it alongside any Config.BuildID.

func (*StaticStore) Contracts

func (s *StaticStore) Contracts() *codegen.Document

Contracts returns the value-contract document this store was built from, so a server that already packages static data does not have to read and parse the same file twice to enable route caching.

func (*StaticStore) Entry

func (s *StaticStore) Entry(_ context.Context, routeID string, params map[string]string) (LoadedPage, bool, error)

Entry returns the packaged page for (routeID, params). Everything is already decoded at load time, so the context is unused.

func (*StaticStore) Has

func (s *StaticStore) Has(routeID string) bool

Has reports whether the store carries at least one entry for routeID.

func (*StaticStore) Loader

func (s *StaticStore) Loader(routeID string) PageLoader

type StoreOption

type StoreOption func(*residency.Options)

StoreOption adjusts the residency cache behind a pack-backed store opened by OpenPlanStore or OpenStaticStore.

func WithResidencyOptions

func WithResidencyOptions(options residency.Options) StoreOption

WithResidencyOptions replaces the store's residency cache options. Zero fields keep the residency package defaults.

Jump to

Keyboard shortcuts

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