scmJS docs

How a plugin works

A plugin is one TypeScript (or JavaScript) file with an activate(api) export, sitting in a public repository next to a plugin.json. Nothing has to be installed and there is no build step to start with: the editor fetches your source, transpiles it in the browser and calls activate with the whole API. Writing a plugin below is the file itself; this is what the editor does around it, and what it promises while your code runs.

What the editor does for you#

The contract#

npm i -D @scm-js/plugin-api is the whole toolchain — one generated index.d.ts, types only, nothing to configure (Writing a plugin has the file that uses it).

The package's major is the API version and its minor moves when the declarations do, so ^1 is a range you can write and mean. Your manifest's "api": N is the version you need; a host offering an older one refuses to load you rather than failing halfway through activate. It is 1 today, and additions do not move it — a new call appearing on api never breaks a plugin that does not use it, so PLUGIN_API_VERSION is reserved for a change that would.

What you write in#

What your users are told about you#

A plugin runs in the page with the page's privileges. It can read and change the open map, read and write the files stored in the map archive, read and write the editor's own browser storage, and make network requests. There is no sandbox, the install screen says so in those words, and it is the same trust a browser extension asks for. Three things follow that are worth writing for:

For the same reason, ship your dist/plugin.js unminified. What the confirmation dialog offers a user is your repository, and a plugin they cannot read is a plugin they cannot judge.

How the editor finds your code#

The spec is the address a user pastes into Manage Plugins, or that a registry lists:

Spec
github:owner/repo The default branch — fine for a private experiment, but see the pinning note above.
github:owner/repo@v1.2 A tag, a branch or a commit. This is what a registry lists and what a default names.
github:owner/repo@v1.2/plugins/mine A folder inside a repository, for several plugins in one.
https://github.com/owner/repo/tree/v1.2/plugins/mine The same, as the URL a user copies out of their address bar.
https://…/plugin.json A manifest anywhere — GitLab, your own host, a gist.
https://…/plugin.ts An entry file with no manifest; one is synthesised from the file name.
http://localhost:3000/ A directory holding plugin.json. This is how you develop one: serve your working copy and add it.

What loads is the manifest's build when it has one, and its entry otherwise. A build ends the story in one fetch — no compiler, no walking your imports — and is the only way to use an npm dependency; the source path is the shortest way to start. entry stays in the manifest either way, because it is what a person reads and what loads for a repository that publishes no build.

Getting yours listed#

Plugins ▸ Browse Plugins… reads registries: one JSON file holding an entry per plugin — the spec to install, plus the fields that plugin's own plugin.json carries, so a whole list arrives in one request. The project's own is scm-js/registry, generated from the organisation itself: every repository named plugin-… or carrying both the scmjs and plugin topics, described by the plugin.json at its newest version tag (an untagged repository falls back to its default branch), refreshed hourly and within about a minute of a plugin repository saying it changed. Listing there is opt-out.

For a plugin outside the organisation, open a pull request against that repository's plugins.json; its README has the shape of an entry. Nothing about being listed is privileged — any URL serving a file of that shape is a registry, and a user can add one under Sources. A registry decides what is offered, never what is trusted: installing from a Browse row goes through exactly the same confirmation, the same manifest fetch and the same pinning as an address pasted by hand.

Five plugins are defaults — the editor lists them from the start and they are compiled into the build, so a fresh install has them with no network at all. They are ordinary plugins from their own repositories, each pinned to a tag; being a default buys nothing else. Which five, and how that works, is under Host side.

scmJS 0.1.0 · Generated from the repository. StarCraft and Brood War are trademarks of Blizzard Entertainment; this project ships none of their data.