Documentation
¶
Overview ¶
Package server provides the dev server with HTTP serving, file watching, and WebSocket live reload.
Index ¶
- type APIError
- type APIResponse
- type APIServer
- type ChangeKind
- type DevServer
- type FileChange
- type Hub
- func (h *Hub) Broadcast(msg ReloadMessage) int
- func (h *Hub) ClearPendingError()
- func (h *Hub) ClearPendingReload()
- func (h *Hub) ClientCount() int
- func (h *Hub) HandleWS(w http.ResponseWriter, r *http.Request)
- func (h *Hub) SetPendingError(msg *ReloadMessage)
- func (h *Hub) SetPendingReload(msg *ReloadMessage)
- type Options
- type RebuildResult
- type Rebuilder
- type ReloadMessage
- type ReloadType
- type Watcher
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APIError ¶
type APIError struct {
Code string `json:"code"`
Message string `json:"message"`
File string `json:"file,omitempty"`
}
APIError represents a structured error in the response.
type APIResponse ¶
type APIResponse struct {
Success bool `json:"success"`
Data any `json:"data,omitempty"`
Error *APIError `json:"error,omitempty"`
}
APIResponse is the standard JSON envelope.
type APIServer ¶
type APIServer struct {
// contains filtered or unexported fields
}
APIServer serves the IPC JSON API for the desktop app.
func NewAPIServer ¶
func NewAPIServer(pm *project.ProjectManager, hub *project.EventHub) *APIServer
NewAPIServer creates a new API server.
type ChangeKind ¶
type ChangeKind string
ChangeKind classifies a file system change.
const ( ChangeContent ChangeKind = "content" ChangeTemplate ChangeKind = "template" ChangeCSS ChangeKind = "css" ChangeConfig ChangeKind = "config" ChangeStatic ChangeKind = "static" )
type DevServer ¶
type DevServer struct {
// contains filtered or unexported fields
}
DevServer runs the development HTTP server with live reload.
func (*DevServer) Ready ¶
Ready reports the actual bound port: the port is sent once after the listener binds, then the channel is closed. If Start fails or the server is stopped before binding, the channel is closed without a value.
func (*DevServer) Start ¶
Start binds the listener, runs the initial build, starts the file watcher, and serves HTTP. It blocks until the server is stopped. The listener is bound up front so Ready() reports the actual port immediately; connections arriving before the initial build finishes queue in the accept backlog.
type FileChange ¶
type FileChange struct {
Path string
Paths []string // all changed file paths in the batch (populated for content changes)
Kind ChangeKind
DetectedAt time.Time // when fsnotify first reported this change
}
FileChange represents a detected filesystem change.
type Hub ¶
type Hub struct {
// contains filtered or unexported fields
}
Hub manages WebSocket client connections and broadcasts reload messages.
func (*Hub) Broadcast ¶
func (h *Hub) Broadcast(msg ReloadMessage) int
Broadcast sends a reload message to all connected WebSocket clients. Returns the number of clients that received the message.
func (*Hub) ClearPendingError ¶
func (h *Hub) ClearPendingError()
ClearPendingError removes the stored build error after a successful rebuild.
func (*Hub) ClearPendingReload ¶
func (h *Hub) ClearPendingReload()
ClearPendingReload removes the stored reload message.
func (*Hub) ClientCount ¶
ClientCount returns the number of connected WebSocket clients.
func (*Hub) HandleWS ¶
func (h *Hub) HandleWS(w http.ResponseWriter, r *http.Request)
HandleWS upgrades an HTTP connection to WebSocket and registers the client.
func (*Hub) SetPendingError ¶
func (h *Hub) SetPendingError(msg *ReloadMessage)
SetPendingError stores a build error to replay to newly connecting clients.
func (*Hub) SetPendingReload ¶
func (h *Hub) SetPendingReload(msg *ReloadMessage)
SetPendingReload stores a successful reload message to replay to newly connecting clients that missed the original broadcast.
type Options ¶
type Options struct {
ProjectDir string
OutputDir string
Host string
Port int
LiveReload bool
Version string
BasePath string // normalized: "/docs/" or "/"
BuilderFactory func() *build.SiteBuilder
ThemeDevDirs []string // external dirs to watch as ChangeTemplate (for --theme-dev)
}
Options configures the dev server.
type RebuildResult ¶
type RebuildResult struct {
Success bool
Duration time.Duration
PageCount int
Warnings []engine.ValidationWarning
Error error
}
RebuildResult holds the outcome of a rebuild attempt.
type Rebuilder ¶
type Rebuilder struct {
// contains filtered or unexported fields
}
Rebuilder wraps SiteBuilder for dev-mode rebuilds. It persists the builder across content/static changes and only creates a new one when config or templates change.
Coalescing: if a rebuild is already running, incoming requests are stored as a single pending change (latest wins). When the active rebuild finishes, the pending change triggers exactly one follow-up rebuild. This prevents cascading queued rebuilds when editors emit rapid successive save events.
func NewRebuilder ¶
func NewRebuilder(factory func() *build.SiteBuilder, projectDir string) *Rebuilder
NewRebuilder creates a Rebuilder with the given factory function. The factory is called on the first build and whenever config/template changes require a fresh SiteBuilder.
func (*Rebuilder) Rebuild ¶
func (r *Rebuilder) Rebuild(change FileChange) *RebuildResult
Rebuild runs a site build and returns the result. Config or template changes create a fresh builder (full re-init). Content or static changes reuse the existing builder (template engine skips Load).
If a rebuild is already in progress, the change is stored as pending and this call returns nil (the caller should skip logging/broadcasting). When the active rebuild finishes, it picks up the pending change automatically and runs it before returning the final result.
func (*Rebuilder) SetOnResult ¶
func (r *Rebuilder) SetOnResult(fn func(FileChange, *RebuildResult))
SetOnResult registers a callback invoked after each completed rebuild. For coalesced rebuilds, the callback is invoked once with the final result only.
type ReloadMessage ¶
type ReloadMessage struct {
Type ReloadType `json:"type"`
Path string `json:"path,omitempty"`
Error string `json:"error,omitempty"`
File string `json:"file,omitempty"`
Line int `json:"line,omitempty"`
Col int `json:"col,omitempty"`
Frame string `json:"frame,omitempty"`
ChangedAt int64 `json:"changedAt,omitempty"` // Unix millis when the file change was first detected
}
ReloadMessage is sent to browsers over WebSocket.
func ToReloadMessage ¶
func ToReloadMessage(change FileChange, result *RebuildResult, projectDir string) ReloadMessage
ToReloadMessage converts a file change and rebuild result into a ReloadMessage suitable for broadcasting to connected browsers.
type ReloadType ¶
type ReloadType string
ReloadType classifies what kind of reload to perform.
const ( ReloadFull ReloadType = "reload" ReloadCSS ReloadType = "css" ReloadError ReloadType = "error" ReloadWarning ReloadType = "warning" )
type Watcher ¶
type Watcher struct {
// contains filtered or unexported fields
}
Watcher monitors project directories for changes and triggers a callback.
func NewWatcher ¶
func NewWatcher(projectDir, outputDir string, debounce time.Duration, onChange func([]FileChange)) *Watcher
NewWatcher creates a file watcher for the given project directory. outputDir is the build output directory (absolute or relative); changes under it are ignored so a build's own writes don't trigger a rebuild loop.
func (*Watcher) AddExternalDir ¶
func (w *Watcher) AddExternalDir(dir string, kind ChangeKind)
AddExternalDir registers a directory outside the project tree to watch. All changes under it are classified with the given kind. Must be called before Start().