10. Processing model
Contents of DESL 0.1
- Parse the JSON; reject duplicate keys.
- Check the version:
deslmajor version supported. - Validate against
desl.schema.json#/$defs/Specification. - Resolve names: every type, enumeration, operation and function named exists; every type the surface names is an element type of the metamodel, and every attribute it names is an attribute of the type it is named for;
columns.options.typeandcells.itemsare among the children of the columns' and the cells' types; each value type'skeyis an attribute of the cells' type, or of the items' type withmany; every binding inpersistence.bindingsexists, and every ruletypein it names an element type or a key oftypeMap. - Check what the schema cannot: reserved attribute names (2.2), a positional create into an unordered parent (8.2), identity expressions that read other ids (5.3.2), functions that call themselves (3.3), and every other MUST of this document.
- Compile CEL: parse and type-check every expression in its context (9.3), and estimate its cost against
language.limits.celCost.
A validator reports every problem with the JSON Pointer of its location, a severity (error makes the specification unusable; warning does not) and a message.
A host opens a document as FBL section 14.2 says, with the binding of section 5.1 its claims choose, and builds the model in this order:
- read the elements in reading order: the order of their first bytes in the body, which is document order; report
std.unreadableEntry,std.missingIdandstd.duplicateIdas they occur; - give an element without a usable id a new id under
missing: "assign", held in memory and written with the next edit, or treat it as ephemeral undermissing: "ephemeral", and treat every second and later holder of a duplicated id as ephemeral (5.3.4); - compute the derived ids (5.3.2), parents before children, letting references follow;
- evaluate the constraints with
livetiming and lay out the surface.
Unknown content is kept: an entry the binding cannot read stays in the body, byte for byte, and is reported (6.5).
Every gesture, operation or quick change of a cell is one transaction:
- apply the operation's actions to a working state of the model (8.2);
- recompute derived ids, and rewrite every reference to an id that changed (5.3.2);
- check the constraints with enforcement
prevent: a violation rolls the transaction back, and its message is the refusal (6.4); - plan the changes as one edit of the body, by the binding's splices (FBL section 6.4); an edit FBL refuses rolls the transaction back with FBL's refusal;
- commit, as one undo step, and evaluate the
liveconstraints.
Transactions are atomic: all of their effects apply or none. Undo and redo restore the body as it was before and after the step, and the model is read from it again. A step that changes two documents is one transaction over both (5.4).
A body is written by FBL's splices (FBL section 6.6), keeping every byte the transaction did not change. With blockSaveOn: "error", a host MUST ask before writing a document that has errors, and MUST still let it be written.