Artifacts & Bindings - XTP Internals
Artifacts
XTP stores Host- and Guest-generated plugins as a series of versions of a single "artifact." This allows XTP to maintain a history of a single plugin over time, as the author pushes new versions (or "yanks" bad versions.)
XTP Artifacts function akin to language-specific package managers, like npm
or
cargo
. Artifacts have a compound identifier that bakes in the extension point
id, type of artifact, owner of artifact, and a unique name for that artifact.
This identifier lets XTP assert certain useful facts about the artifact: who can
see it, what can it be used for, and which Extension Point schema it is intended
to satisfy.
An artifact is created (or updated) by the act of running xtp plugin push
. The
Extension Point id, current logged-in user, and name
field of the xtp.toml
are use to identify the artifact. This artifact version is tagged as the
intended "latest" version. As part of the plugin pushing process, XTP runs
validations against the artifact: first XTP built-in schema checks, followed by
any host-configured simulation tests. Once these tests complete successfully,
the artifact's "validated" tag will point at the newly-validated version. Any
"bindings" that refer to that artifact will be updated to point at the new
content.
Bindings
Bindings are the artifacts the host will see when their application queries a given extension point and guest. The data structure that hosts see when requesting bindings looks like this:
{
"blur": {
"id": "ext_01j29hxk3mfpq8ad68ha6hbsex/plugin/usr_01j29hxk3jeh594yxdr6ge618c/blur",
"contentAddress": "3vMIJEz1Y5bI0-GWhoQUuR90PCQAmYboWsKC2diep-c",
"updatedAt": "2024-07-01T00:00:00.000Z"
},
"sharpen": {
"id": "ext_01j29hxk3mfpq8ad68ha6hbsex/plugin/usr_01j29hxk3jeh594yxdr6ge618c/sharpen",
"contentAddress": "rMih78nuWJV5G-tzkvfAcHndsLC5E8jwRwI-rn8MB1o",
"updatedAt": "2024-05-01T00:31:00.000Z"
}
}
The contentAddress
and updatedAt
fields reflect the address at which hosts
can request the plugin data from XTP and the time that plugin data was validated
respectively.
The plugin data can be retrieved via an authenticated call to
GET /api/v1/c/<content address>
.
Binding content
Bindings represent a subscription to the latest "validated" version of an artifact and can be made in advance of a valid version of the plugin artifact (or indeed, of the plugin artifact itself.)
In those cases, the Host would simply see the id
of the incoming plugin
without any updatedAt
or contentAddress
content (or null values.). In the
below example, there is no valid version of blur
:
{
"blur": {
"id": "ext_01j29hxk3mfpq8ad68ha6hbsex/plugin/usr_01j29hxk3jeh594yxdr6ge618c/blur"
},
"sharpen": {
"id": "ext_01j29hxk3mfpq8ad68ha6hbsex/plugin/usr_01j29hxk3jeh594yxdr6ge618c/sharpen",
"contentAddress": "rMih78nuWJV5G-tzkvfAcHndsLC5E8jwRwI-rn8MB1o",
"updatedAt": "2024-05-01T00:31:00.000Z"
}
}
Hosts are expected to select a binding name according to their application's
needs. Some hosts may require a specific name, some hosts may assign special
meaning to the name, and some hosts may not care. Hosts that do not specify a
specific binding name will receive the latest valid binding -- no matter the
name -- determined by the "updatedAt"
field.
It's currently the responsibility of the host to inform the guest what the expectations around binding names are. In the future XTP may offer ready-made workflows. If you have a specific need, let us know on Discord!
Binding aliases
Guests generally won't have to think about the difference between the two, but
bindings allow a plugin to be advertised to the host under a name different than
the plugin's name. This distinction is similar to how imports work in languages
like Python and JavaScript -- compare import { foo } from 'bar'
to
import { foo as myFoo } from 'bar'
. Most of the time, using the exported name
locally is fine, but sometimes you can't, so you have to be able to "alias" or
"rebind" it. This is a forward-looking XTP feature, predicting a future where
guests can bind plugins written by third-party authors.
{
"myFoo": {
"id": "ext_01j29hxk3mfpq8ad68ha6hbsex/plugin/usr_01j29hxk3jeh594yxdr6ge618c/foo",
"contentAddress": "3vMIJEz1Y5bI0-GWhoQUuR90PCQAmYboWsKC2diep-c",
"updatedAt": "2024-07-01T00:00:00.000Z"
}
}
Plugin authors can control binding aliases via xtp plugin push --as <alias>
or
xtp binding --name <name>
. By default, bindings are assigned to the name of
the plugin.