Status: backlog Priority: P1 Created: 2026-02-17 Owner: conductor
The current ui_routes.cljc has three architectural problems identified in the
routing design discussion:
history volatile, route-table-atom, and fixed session-id prevent
multiple routing charts and composable routing.establish-route-params-node both stores params AND syncs URLs.
undo-url-change manipulates browser history directly.routes only discovers targets in its own
children, so (route-to! app :deeply/nested) doesn't work across istate boundaries.This spec creates a new com.fulcrologic.statecharts.integration.fulcro.ui-routing2
namespace that copies needed functions from ui_routes, removes all history/URL concerns,
adds composable routing via :route/reachable declarations, and parameterizes session IDs.
The old namespace is left untouched.
route-to!, active-leaf-routes, route-denied?, etc.) accept
session-id as a parameter (with a sensible default or required arg)establish-route-params-node stores params from event data only — no URL readingundo-url-change, apply-external-route, or state-for-path in this nsroute_history.cljc or route_url.cljcroutes helper does NOT generate transitions for :event/external-route-change
(that's the external layer's job to send route-to.* events):route/reachableistate accepts a :route/reachable set of keywords — the transitive set of route
targets reachable through the invoked child chartroutes reads :route/reachable from istate children and generates cross-chart
transitions that target the istate and store a ::pending-child-route in the data modelistate passes ::pending-child-route through invoke params to the child chartroutes on-entry checks for an initial route in its data/params and
raises the corresponding route-to.* event to self-routeistate within an istate cascades correctlyreachable-targets helper that analyzes a chart and returns the set of all
route target keywords (for generating the :route/reachable declaration)rstate — route state with on-entry that initializes component and patches parent queryistate — invoked route state (enhanced with reachable support)routes — generates direct transitions and wraps with denied-routing guardrouting-regions — parallel wrapper with routing-info stateinitialize-route! — ident resolution cascade (unchanged)update-parent-query! — dynamic query patching (unchanged)busy? / record-failed-route! / override-route! — event-based denied routingui-current-subroute / ui-parallel-route — render helpers (parameterized session-id)route-to! — sends route-to.* event (parameterized session-id)route-to-event-name — keyword derivation (unchanged)record-failed-route!/override-route! pair
already does this — generalize it so auth guards can use the same mechanism.routes guard system should support multiple denial reasons (busy, not-authenticated)
via a :route/guard option that returns nil (allow) or a keyword reasonintegration/fulcro/ui_routing2.cljc — main namespaceintegration/fulcro/ui_routes.cljc — NOT modified, source for copyingintegration/fulcro/ui_routes_options.cljc — may reuse or copy optionsCopy and clean up the core routing functions:
rstate, routes, routing-regions, istate (without reachable support yet)initialize-route!, update-parent-query!, replace-join!busy?, record-failed-route!, override-route!, clear-override!routing-info-stateroute-to!, route-to-event-nameui-current-subroute, ui-parallel-routeStrip out: history, route-table-atom, undo-url-change, apply-external-route,
state-for-path, URL reading from establish-route-params-node.
Parameterize session-id on all API functions.
Simplify establish-route-params-node to:
(ops/assign [:routing/parameters id] (select-keys event-data params))
Add :route/reachable support:
routes' find-targets to walk into :route/reachable sets::pending-child-route storageistate to read ::pending-child-route and pass via invoke paramsroutes on-entryreachable-targets helper functionExtract the bookmark/replay mechanism:
busy? to a :route/guard fn returning nil or denial-reason keywordbusy? for backward compatibility(fn [env data] (when-not (authenticated? env data) :not-authenticated))record-failed-route! / override-route! mechanism works for any denialrstate on-entry initializes component and patches query (test with mock Fulcro app)routes generates direct transitions for all child targetsbusy? guard prevents routing when component is busyrecord-failed-route! saves event, override-route! replays itroute-to! accepts session-id parameterroutes generates cross-chart transitions from :route/reachableistate forwards pending child route via invoke paramsreachable-targets correctly computes transitive target setprocess-event!:route/guard returning :not-authenticated triggers denial flowCan you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |