Documentation
¶
Overview ¶
Package playground implements the gnoweb playground feature.
It serves the playground page at /_/play, which opens an editable copy of a package with ?from=<pkgpath> (its source files, one tab each), and the /_/api/eval endpoint the playground and the action page evaluate through.
Index ¶
- Constants
- Variables
- func CopyURL(pkgPath, file string) string
- func InCopy(name string) bool
- func NewPageView(data PlaygroundData) *components.View
- func ParseFrom(domain, from string) *weburl.GnoURL
- func RelPath(domain, p string) string
- type ClientAdapter
- type Deps
- type File
- type Handler
- type Limiter
- type PackageFetcher
- type PlaygroundData
Constants ¶
const MaxCopySourceBytes = 1 << 20
MaxCopySourceBytes caps the sources a copy shows, which the page carries as text.
Variables ¶
var ( ErrEvalTimeout = errors.New("the node did not answer the evaluation in time") )
The errors a ClientAdapter wraps when an eval failed for a reason that says nothing about the expression. serveEval answers them with a generic message, never the transport detail.
var ( ErrPackageNotFound = errors.New("package not found") ErrPackageTooLarge = errors.New("package source is too large to open in the playground") ErrPackageTimeout = errors.New("the node did not send the package in time") )
Errors a PackageFetcher answers with, so the copy page answers as the package's own pages do.
var PageTemplate = template.Must(template.New("").ParseFS(templateFS, "templates/page.html"))
PageTemplate is the standalone playground page. Pre-parsed at init so a misconfigured template surfaces immediately, not on the first request.
Functions ¶
func CopyURL ¶
CopyURL is the playground URL that opens an editable copy of the package at pkgPath, showing file first when set.
func InCopy ¶
InCopy reports whether a copy opens a package's file: its Gno sources and gnomod.toml, without the filetests, of which a package can hold hundreds.
func NewPageView ¶
func NewPageView(data PlaygroundData) *components.View
NewPageView wraps the playground template.
Types ¶
type ClientAdapter ¶
type ClientAdapter interface {
// Eval evaluates expr inside pkgPath through vm/qeval. pkgPath carries
// no domain: the client adds its own.
Eval(ctx context.Context, pkgPath, expr string) ([]byte, error)
}
ClientAdapter is the subset of the gnoweb chain-client interface that the playground feature consumes. Declared locally so feature/playground does not import the gnoweb package; gnoweb's adapter maps its client's errors onto ErrEvalTimeout and ErrEvalUnavailable.
type Deps ¶
type Deps struct {
Client ClientAdapter
Logger *slog.Logger
// Packages reads the package a copy opens.
Packages PackageFetcher
// Domain is the chain domain (e.g. "gno.land").
Domain string
// Limiter bounds the per-client eval rate. Optional; nil disables the
// check.
Limiter Limiter
// Timeout bounds one eval, like the deadline pages render under.
// Zero means defaultEvalTimeout.
Timeout time.Duration
}
Deps gathers the dependencies the playground Handler needs.
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler owns the playground feature state.
func New ¶
New validates required deps and returns a Handler. If empty Domain defaults to "gno.land" and Logger defaults the standard Go library's logger. It panics if Client or Packages is not specified.
func (*Handler) EvalHandler ¶
EvalHandler returns the http.Handler for POST /_/api/eval.
func (*Handler) GetPlaygroundView ¶
GetPlaygroundView serves /_/play: ?from=<pkgpath> opens an editable copy of that package, ?code= a shared snippet, and nothing the default code.
type Limiter ¶
Limiter is the admission check applied to each eval request. It takes the request, not an address: which address to trust depends on which proxies to trust, and that rule belongs with the limiter.
type PackageFetcher ¶
PackageFetcher reads the files of a package InCopy selects, up to MaxCopySourceBytes. It answers the ErrPackage errors for what they name.
type PlaygroundData ¶
type PlaygroundData struct {
// Files is the code the editor opens, one <pre> per file: a package
// copy (?from=), a shared snippet (?code=) or the default code.
Files []File
// From is the copied package's path without its domain (r/demo/foo),
// empty for anything but a copy.
From string
// Domain is the chain domain.
Domain string
// DefaultFile is the filename that should be focused on first load.
DefaultFile string
// Refused says why the ?code= link was not opened, when it was not:
// the page shows the default code, and says so.
Refused string
// Preview is true when Run shows what the copied realm renders,
// instead of the commands that run the code locally.
Preview bool
}
PlaygroundData is the render payload for templates/page.html.