QORMQORM v0.8.4 api Get started

Navigation

A QORM app can have many scenes (scenes/*.json, each {"type":"scene","id":...}). The entry in the manifest is shown first; the navigate action step moves between them, with a back stack.

// actions/openProfile.json — go to a scene
{ "type": "action", "id": "openProfile",
  "steps": [ { "type": "navigate", "to": "profile" } ] }

// actions/back.json — return to the previous scene
{ "type": "action", "id": "back",
  "steps": [ { "type": "navigate", "back": true } ] }

or the current one is a no-op.

action moves the human's view too (and vice versa). A desktop window may pin a specific scene with ?scene=<id>.

Page transition

Switching scenes plays a coordinated, iOS-style transition automatically: the incoming scene slides in from the edge while the outgoing one parallax-slides the other way (less far) and dims, giving depth. navigate slides forward; back reverses it. Each scene is treated as an opaque block during the slide, so scenes without their own background don't bleed through each other.

See examples/navigation.

Route guards

A scene can declare the precondition for entering it. The guard runs on every entry path — an action's navigate step, a browser Back/Forward, a deep link straight into the scene, and the initial entry scene — so a protected route cannot be reached by spelling a URL, and the check lives in one place instead of being repeated in every navigating action.

// scenes/dashboard.json
{ "type": "scene", "id": "dashboard",
  "guard": {
    "condition": "{{ state.user != null }}",
    "redirect": "login",
    "params": { "next": "{{ 'dashboard' }}" }
  },
  "root": { ... } }

viewport.*, route.*, state.computed.*). Truthy = enter.

target's {{ route.* }}. Without a redirect the navigation is simply refused (you stay where you are) — which also means it cannot protect the entry scene, so the loader warns.

scene refuses the navigation rather than looping; the loader warns about a redirect cycle at load time.

data never fires for a visitor who was refused the page. A guard redirect REPLACES the current frame rather than pushing one, so Back never returns to a scene you were denied.

See examples/derived.