10. Processing model
Contents of DESL 0.2
- 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. (DESL 0.2) For ahierarchysurface: every type a role names is an element type and every attribute it names an attribute of that type, the levels' type contains itself and the entries' type, each label attribute is on every type of itson, andcollapsedis on the levels' and the entries' types. Every type amentionsfacet names is an element type. Acounterrule'smarkis astringattribute of the document. Every key ofpersistence.settingsis a block every binding declares inregistration.blocks, a list'stype,keyandvalueare a type and its attributes, and a state'sattributeis an attribute of each type of itsof. - 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.