11. Persistence plugins
Contents of FBL 0.1
Some formats are too intricate to declare: projecting Turtle triples onto cards and rows, evaluating MSBuild with its imports and wildcards, parsing SPARQL. For them a binding's reader is a persistence plugin:
{ "reader": { "plugin": "net.etalii.adp.w3c.turtle", "version": "^0.1.0" } }
The plugin is declared in the DISL specification's plugins with provides: ["persistenceFormat"] (DISL §13.1); args are validated against its declaration. Everything else in the binding is declared and done by the host exactly as for a declared reader: claims and routing, the registration, several readings, folder recognition and watching, templates, history, drift and saving. A format FBL can declare SHOULD be bound rather than read by a plugin.
A plugin implements these operations, stated as data exchanged so that each host binds them to its own plugin mechanism:
| Operation | Receives | Delivers |
|---|---|---|
read |
The body's bytes (a file body), or for a folder subject the relative path and bytes of every file the file rules select; the binding's args. |
The elements and relations: type, id, parent and slot, attribute values; for each, the source span of the entry and of every writable value (file, byte range); the findings, with source locations; and whether the body is unreadable as a whole. |
plan |
The current bytes, the last read result, and one model change: add, set, remove or move an element or relation. |
The splices that realise it, each {operation, file, start, end, text} with an operation from section 6.1; or a refusal with the sentence the host shows. |
template |
The new body's name and the template placeholders (section 13). | The bytes of a new body. Only asked when the binding has no template.text. |
watch |
The last read result (folder subjects, optional). |
The paths the reading depends on beyond the file rules; the host watches them too. |
The host, not the plugin, applies splices to bytes and saves them atomically; keeps the history and undoes with inverse splices or snapshots; checks drift; watches the body and calls read again after external changes; stores view data in the registration; routes files; and shares one open body between readings. A plugin-backed body therefore behaves exactly as a declared one: byte-preserving writes, exact undo, drift refusal, several readings, folder subjects.
readMUST NOT fail on content: problems are findings, and an unreadable body is reported as such (section 7).readandplanMUST be deterministic: the same bytes and change give the same result, in every host's implementation of the plugin.- Splices from
planMUST change only the bytes the change concerns, MUST name their operation truthfully, and MUST follow the new-text rules of section 6.3 where they apply to the format. - A plugin MUST NOT write files, keep its own undo history, or store view data. A read-only binding's plugin is never asked to
plan. - A plugin MAY report findings about anything in the body, with DISL's source location and
subject; the host shows them like any other finding.
| Format | Tool types | Why a plugin |
|---|---|---|
| Turtle and N-Triples | W3C RDF, OWL, SHACL, SKOS | Terms span tokens, prefixes compress IRIs, and one IRI yields several elements; the projection is code. |
| SPARQL 1.1 | SPARQL query | A recursive grammar projected onto scopes; read-only. |
.sln, .slnx, MSBuild projects |
.NET dependency graph | Wildcards, imports and central package management are evaluated; read-only. |
| Ansible project folders | Ansible structure | YAML and INI inventories, task directives and role resolution; read-only. |
| Helm chart folders | Helm chart | Templates are scanned as lines, not YAML, and includes resolved; read-only. |
| Azure Pipelines template expansion | Azure DevOps pipeline | Following template: references and unwrapping ${{ }} expressions is evaluation; the rest of the file could be declared. |