@projectpac/core-host
v0.6.0
Published
Part of PAC: @projectpac/core-host.
Readme
@projectpac/core-host
Claims ctx.host. The install lifecycle over the plugins tree, the package
source seam, and each plugin's own directory.
It keeps no record of its own. plugins.yml is what is installed, a
plugin's manifest is what its module exports, and what vouched for a fetched
package rides on its row. One truth about the installed set, so nothing has to
be kept in step with it: the registry this replaced listed rows the tree did
not run and missed the ones setup had seeded.
Installing writes a row. Two ways to ask. { package } names something the
node does not have: an enabled package source fetches it into the node's module
directory (<data dir>/modules, an npm prefix), the host reads the manifest out
of the package's own metadata -- executing nothing -- and the row carries what
the source said vouched for the bytes. { source, id } names a module the node
already has, seeded by setup or linked by a dev lane; its caller names the row,
because nothing fetched it and nothing vouches for it.
requireVouched is the one policy. Off by default, because installing code
is the trust decision and a signature says who produced the bytes rather than
whether they are safe. On, a fetched package its source could not verify is
refused, and so is every { source } install.
It does not sit between an installed plugin and the core plugins. A loaded plugin reaches them directly and each one derives its caller, so the host's job ends once an entry exists.
Disabling is enough. Everything a plugin registered is an effect of its
scope, so one flag withdraws its advertisements, routes, served resources, and
workspaces. kill differs only in what a restart does: a killed plugin comes
back, a disabled one does not. A plugin's background work is its own -- a timer
inside one of its effects goes with the rest.
A plugin's directory is the node's, not the host's. dirFor resolves
<data dir>/<id> off the data directory rather than under anything of the
host's: nesting it would make removing the host mean removing everything every
plugin ever kept.
Removing a plugin does not take its directory. The host dispatches
core/removing into the plugin while it is still running and waits, and what
the plugin leaves behind is what a later install of the same id will find --
databases, files, all of it. Clearing it is the plugin's to do, and the signal
is its chance. The cost is that a plugin which ignores the signal leaves a
folder nothing lists; the reason is that a node should not destroy the
principal's own material because a plugin that merely read it was removed.
ctx.self is one service that answers per caller -- see
binding.ts. A service rather than an accessor, because a
plugin declares inject: ["self"] and cordis gates an inject on a service
being available. self rather than plugin because cordis already declares
plugin() on Context.
layer.ts holds two refusals, both about names the node has
already claimed: a plugin id may not collide with a name the node's own state
uses on disk, and a fetched package may not claim a spine service key. The
first is checked at install and again where the directory is created, which is
what covers a row written into the entry file by hand and a row setup named for
the first boot. The second can only run where a manifest is in hand before the
row is written, which is a fetched package; a { source } install that claims
one is refused by the framework when its module loads.
