Files
Native-Router-Vue/docs/routeless-origins.md

4.9 KiB
Raw Permalink Blame History

Routeless origins architecture

The v2 experiment lives in packages/core-v2 and its physical test application lives in apps/origins-demo.

State model

The scene contains:

  • stable, flat Vue component nodes;
  • linked mounted-instance history entries;
  • temporary directed operation edges.

It does not contain an active route or current view.

For overlapping operations:

Nodes:       X, Y, Z
Edges:       X → Y
             Y → Z

Each edge records its own progress, velocity, outcome, choreography, and source/target keys.

Coordinate composition

Suppose A is X→Y and B is Y→Z:

visual(X) = A.source
visual(Y) = A.target × B.source
visual(Z) = A.target × B.target

An optional frame effect is included on both sides of an edge:

visual(Y) = A.frame × A.target × B.frame × B.source
visual(Z) = A.frame × A.target × B.frame × B.target

The implementation emits these operations as one combined transform on each flat host. This has the visual semantics of nested coordinate frames without reparenting Vue component VNodes.

Completion

Committing a forward X→Y:

  1. Keeps X mounted but marks it parked, inert, and visually hidden.
  2. Places Y in X's former visual graph position.
  3. Removes the X→Y edge.
  4. Leaves any Y→Z edge and all mounted descendants intact.

Committing Y→Z before X→Y is also valid. Z replaces Y as the target of the still-running X edge, after which X→Y effectively becomes X→Z. The unit suite covers both completion orders.

Committing back from Y to X reveals the existing X node and removes Y. It does not construct X again from its recipe. Cancelling a forward edge restores its source and removes the newly created target branch; cancelling a back edge re-parks its retained target.

Committing a replace from Y to Z creates Z but links it directly to Y's previous entry:

Before: X (parked) ← Y (visible)
After:  X (parked) ← Z (visible)

Y remains mounted while the operation is interactive and is removed only on commit. Cancelling removes Z and restores Y, making replacement one atomic operation rather than a visible back followed by a forward push.

Connected partial presentations

Most committed pushes collapse their temporary operation edge and park the retained source. A choreography with persistAtRest: true instead keeps its progress-1 effects as a settled coordinate relationship:

Page (exposed, inert) → Drawer (active)

This supports partial destinations without copying or remounting either Vue component. For a two-thirds drawer, the settled source effect translates the page right by two thirds, while the target finishes at its identity position. The page's left third therefore remains physically visible in the final third of the viewport.

Settled relationships are not live operations and are omitted from the public operation diagnostics. Beginning back temporarily suspends the relationship and lets a reciprocal close choreography start at the same endpoints. A cancelled close restores the settled edge; a committed close removes the drawer and returns the page to its normal root position.

Interaction

Gesture recognition is declared within each component through OriginGesture or useOriginGesture(). The injected scene-node key determines the origin. Recognition never asks a coordinator which view is active.

The immutable gesture builder separates optional pointer-down policy (.from), movement recognition (.to), release policy (.complete), navigation intent (.navigate), and visual choreography (.animate). A chain that begins at .to is valid and admits pointer-down anywhere on its host.

At pointer release, the operation decides synchronously whether it will commit or cancel. Its spring may continue afterward. A retained target can therefore originate another routine while the preceding spring is still visible.

Nested scenes

An OriginScene may be rendered inside a view owned by another scene. The nearest injected node scope makes carousel or deck gestures operate on the nested scene, with local measurements and retained history.

Gesture ownership between nested scenes is currently selected at pointer-down. An eligible child stops propagation even if its later navigation factory declines. Parent fallback therefore requires the child to reserve a non-matching .from region; automatic delayed arbitration remains future gesture-arena work.

Retained history

Each pushed node stores the key of its mounted previous entry. The chain is local to that origin context rather than a URL:

X (parked) ← Y (parked) ← Z (visible)

Back targets the previous node key directly. A node is unmounted only when a committed back operation pops it, a forward operation is cancelled, or the current entry is successfully replaced, or the whole scene is destroyed. Because the same DOM survives parking, nested scroll positions and component-local state survive without <KeepAlive>.