Documentation
¶
Overview ¶
Package pluginrt runs magpie's built-in plugins: the parts of magpie not everyone needs (Lxxyx on X: "功能太多了"), each one a package under plugins/ that registers a Manifest. The runtime applies the ones the user has on (plugins.yml, see config.go) in the order their Requires and Provides make, and disposes of what each registered, in reverse, when it is turned off. One that fails or panics is FAILED and the rest run on.
The runtime is core: it never imports a plugin, and a plugin never imports another (TestPluginsImportOnlyCore). Plugins reach each other only through the services they Provide.
Index ¶
- Constants
- Variables
- func Compatible(want string) bool
- func KeepFresh(ctx context.Context, every time.Duration, also ...string)
- func Path() string
- func Register(m Manifest)
- func Set(id string, on bool) error
- func SetConfig(id string, config map[string]any) error
- func SetPreset(preset string) error
- func Settle(newInstall bool) (bool, error)
- type Composed
- type Ctx
- type File
- type Manifest
- type Part
- type Property
- type Row
- type Runtime
- type Schema
- type Source
- type State
- type Status
Constants ¶
const ( PresetEssentials = "essentials" PresetAll = "all" )
Presets a plugins.yml can name.
const API = "1.0"
API is the host API plugins are written against. A plugin's Manifest.API is a caret range ("^1", "^1.2"): the same major, and a minor no newer than this one's. One that doesn't match isn't applied.
Variables ¶
var Core = []string{"settings", "providers", "gateway", "window"}
Core are the services magpie itself provides, which a plugin may Require without another plugin providing them.
Functions ¶
func Compatible ¶
Compatible is whether a plugin written for the caret range want runs on this host's API. An empty range is "^1".
func KeepFresh ¶ added in v0.1.1243
KeepFresh refreshes the process's runtime (Refresh) as it starts and whenever plugins.yml, or one of also (a file an InUse reads), changes, until ctx ends. The process serving the gateway runs it: the window or `magpie plugin builtin` in another process may turn a plugin on or off, and what a plugin registers with the gateway (an observer) follows without a restart.
func Register ¶
func Register(m Manifest)
Register adds a built-in plugin; plugins call it from init. Two with one id is a programming error.
func Set ¶
Set turns plugin id on or off as the user's own choice, keeping the rest of plugins.yml as it was. A plugins.yml that doesn't parse is not written over: the user fixes it, or removes it.
func SetConfig ¶ added in v0.1.1228
SetConfig sets plugin id's settings in config as the user's own, keeping its others and the rest of plugins.yml as they were. Only what its settings' schema allows is taken: a key it doesn't have, or a value of the wrong kind or out of range, is refused and nothing is written.
Types ¶
type Composed ¶
type Composed struct {
ID string `json:"id" yaml:"id"`
Enabled bool `json:"enabled" yaml:"enabled"`
Source Source `json:"source" yaml:"source"`
Chosen bool `json:"chosen" yaml:"chosen"` // plugins.yml's say, before what is in use
InUse int `json:"inUse" yaml:"inUse,omitempty"`
Config map[string]any `json:"config,omitempty" yaml:"config,omitempty"`
Sources map[string]Source `json:"configSources,omitempty" yaml:"configSources,omitempty"`
}
Composed is one plugin as plugins.yml and its use make it.
type Ctx ¶
type Ctx struct {
ID string
Config map[string]any // the composed config, read only
// contains filtered or unexported fields
}
Ctx is what a plugin's Apply is handed. Everything registered through it is undone when the plugin is turned off, in reverse.
func (*Ctx) Contribute ¶
Contribute puts a part in the window while the plugin is active.
func (*Ctx) OnDispose ¶
func (c *Ctx) OnDispose(f func())
OnDispose runs f when the plugin is turned off or magpie stops.
type File ¶
type File struct {
Preset string `yaml:"preset,omitempty"`
Plugins []Row `yaml:"plugins,omitempty"`
}
File is plugins.yml as written.
type Manifest ¶
type Manifest struct {
ID string
API string // the host API range it is written for, "^1"
// Requires are services it can't run without; Provides those it gives
// others ("router.strategy/groups")
Requires, Provides []string
// Essential plugins are on in the Essentials preset a new install
// starts with; every built-in is on for a magpie that ran before
Essential bool
// Name and Sub say what it is, in English; the window translates them
Name, Sub string
// One and Many say what of it is in use, of 1 or of {n}
One, Many string
// InUse counts what the user has made with it (groups, warm-ups, items
// given to agents). One in use stays on whatever plugins.yml says: off,
// its things would go on working with nowhere to see or change them.
// An error counts as in use: unknown is never unused.
InUse func() (int, error)
// Apply registers the plugin's parts; nil is a plugin of parts only
// (Contribute) that does nothing else
Apply func(*Ctx) error
// Parts are the window's parts it is, by slot: "nav.page" sessions,
// "settings.section" otel, "part" groups (whatever the page marks
// data-feature="<id>"). The runtime contributes them before Apply.
Parts []Part
// Defaults is its config before plugins.yml's preset and rows
Defaults map[string]any
// Settings is a struct of its settings, their defaults its values
// (schema.go): the window draws their form, and SetConfig takes only
// what it allows. Register adds them to Defaults.
Settings any
// Client are its files in the window, under assets/plugins/<id>/: its
// scripts register its parts with the window's kernel (kernel.js), its
// i18n.js says its words in each language, and a .css is its styles.
// TestBuiltinClientsLoaded holds the page to loading each.
Client []string
// contains filtered or unexported fields
}
Manifest is a built-in plugin: what it is, what it needs and gives, and Apply, which registers its parts through the Ctx.
type Part ¶
type Part struct{ Slot, Key string }
Part is one thing a plugin puts in the window: a Slot and a Key in it.
type Property ¶ added in v0.1.1228
type Property struct {
Type string `json:"type"` // boolean, integer, number, string
Title string `json:"title"`
Description string `json:"description,omitempty"`
Enum []any `json:"enum,omitempty"`
Minimum *float64 `json:"minimum,omitempty"`
Maximum *float64 `json:"maximum,omitempty"`
Default any `json:"default"`
}
Property is one setting.
type Row ¶
type Row struct {
ID string `yaml:"id"`
Enabled *bool `yaml:"enabled,omitempty"`
Config map[string]any `yaml:"config,omitempty"`
}
Row is the user's own say about one plugin: only what they set.
type Runtime ¶
type Runtime struct {
// contains filtered or unexported fields
}
Runtime applies the plugins that are on and keeps what each registered.
func Running ¶
func Running() *Runtime
Running is the process's runtime, nil before the first Refresh.
func (*Runtime) Reconcile ¶
Reconcile brings the runtime to on: each plugin wanted and not active is applied, once what it requires is provided; each active one no longer wanted is disposed, with whatever requires a service it provided. on says, by id, whether a plugin is wanted; config is each one's composed config.
type Schema ¶ added in v0.1.1228
type Schema struct {
Type string `json:"type"` // "object"
Properties map[string]*Property `json:"properties"`
Order []string `json:"x-order"`
}
Schema is a plugin's settings as JSON Schema says an object: the window draws a form from it. Order is the fields' order, as JSON keeps no order of an object's keys.
type State ¶
type State string
State is where a plugin is in its life.
const ( Off State = "off" // turned off in plugins.yml Pending State = "pending" // on, waiting for a service no active plugin provides Active State = "active" // applied Failed State = "failed" // Apply returned an error or panicked Disposed State = "disposed" // turned off at run time, its parts gone )
type Status ¶
type Status struct {
ID string `json:"id"`
State State `json:"state"`
// Why says what kept it from Active: the service it waits for, the
// error it failed with, the API it wants
Why string `json:"why,omitempty"`
Parts []Part `json:"parts,omitempty"`
}
Status is one plugin as it runs now.