Live mode — this page may load external map tiles and query remote endpoints; the standard hub is fully self-contained (same cells, no network).

Two more engines that check or derive data rather than query it: JSON Schema draft-07 structural validation (JSONSchema.Validate.fst) and XForms bind recalculation (XForms.Bind.fst), the "spreadsheet half" of XForms — an instance document plus a bind sheet of calculate/constraint/type expressions, recomputed in dependency order. Both run live below.

JSON Schema: accept, then reject#

One schema, required: ["name"]:

personSchema = JSON.stringify({
  type: "object",
  required: ["name"],
  properties: { name: { type: "string" } },
})
schemaAccept = await fn.jsonSchemaValidate(personSchema, JSON.stringify({ name: "Alice" }))

{ valid: true, result: "pass", errors: [] } — {name: "Alice"} has the one required property, of the right type. Drop it:

schemaReject = await fn.jsonSchemaValidate(personSchema, JSON.stringify({}))

{ valid: false, result: "fail", errors: [...] } — the empty object is missing name, so JSONSchema_Validate.validate returns VFail rather than VPass. A schema keyword this validator doesn't yet implement returns a third, distinct outcome, "unsupported" — never silently folded into pass.

XForms: a calculate MIP deriving a leaf#

An instance with two inputs and one derived leaf, and a single bind naming sum's calculate expression:

xformsInstance = "<data><a>2</a><b>3</b><sum>0</sum></data>"
xformsResult = await fn.xformsRecalc(xformsInstance, [{ target: "sum", calculate: "../a + ../b" }])

The recalculated instance carries <sum>5</sum> — ../a + ../b evaluated with the sum leaf itself as the XPath context node, so ../ steps back up to its siblings. XForms_Bind.recalculate topologically sorts binds by which instance nodes their calculate expressions read before running any of them, so a calculate graph with a cycle is rejected as a document error rather than looped forever — there's no bind here that depends on sum itself, but a binds list that did would fail the same way jsonSchemaValidate fails an instance: cleanly, with a reason, not a hang.

Every live cell above is pinned in tests/hub/post29_test.mjs.