Guides
Plugins
The official fetch and WebSocket plugins, which run in Go, and writing your own.
A plugin adds a feature in two halves: Go services, and a JavaScript
package whose functions call them. The app uses the Go half with
mygo.Use and imports the JavaScript half from npm.
Official plugins
| Plugin | Go | npm | Gives pages |
|---|---|---|---|
| fetch | github.com/egoist/mygo/plugins/fetch |
@mygo-plugins/fetch |
a fetch that makes HTTP requests from Go: no CORS, any header, streamed bodies, cancellation with AbortSignal |
| websocket | github.com/egoist/mygo/plugins/websocket |
@mygo-plugins/websocket |
a WebSocket whose connections Go makes, with headers on the handshake |
The updater plugin, github.com/egoist/mygo/plugins/updater, is all Go:
it gives the app an update window in the manner of Sparkle, which checks
for updates in the background and offers to install them. See
the update window.
import (
"github.com/egoist/mygo"
"github.com/egoist/mygo/plugins/fetch"
"github.com/egoist/mygo/plugins/websocket"
)
func main() {
mygo.Use(fetch.Plugin, websocket.Plugin)
// ...
}bun add @mygo-plugins/fetch @mygo-plugins/websocketimport { fetch } from "@mygo-plugins/fetch";
import { WebSocket } from "@mygo-plugins/websocket";
const res = await fetch("https://api.example.com/me", {
headers: { authorization: `Bearer ${token}` },
});
const ws = new WebSocket("wss://api.example.com/live", [], {
headers: { authorization: `Bearer ${token}` },
});fetch.Plugin and websocket.Plugin use the default options; fetch.New
and websocket.New take an http.Client (for proxies, cookies, TLS
settings) and an Allow function that decides which requests pages may
make. The packages' READMEs, in the repository's plugins directory, list
the details, and go doc documents the options.
Using a plugin's JavaScript package without its Go half fails with an error
that says to call mygo.Use.
Writing a plugin
The Go half is a mygo.Plugin: a name, a service whose methods pages call,
and an optional Setup that runs when the app uses it:
package clock
// Plugin gives pages the time of the Go side.
var Plugin = mygo.Plugin{Name: "clock", Service: service{}}
type service struct{}
func (service) Now() time.Time { return time.Now() }The service is bound like those of mygo.Bind, with the same rules for its
methods (contexts, channels, errors), but as plugin:<name> and outside the
generated TypeScript client. Its JavaScript package calls it with call of
mygo-runtime, which it lists as a peer dependency, so that it uses the
app's copy (and as a development dependency, for its own builds and tests):
import { call } from "mygo-runtime";
export const now = async () => new Date(await call<string>("plugin:clock.Now"));Only the app's trusted pages may call a plugin, as with every bound method.
mygo.Use panics when a name is taken or the service's methods use types
that cannot cross to JavaScript, so mistakes show at startup.