diff --git a/CLAUDE.md b/CLAUDE.md index 4cc1a21..bf06c0b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,6 +22,9 @@ JARL ("JARL: Atomic Routing Library") is a controlled-component router for React - `infra/` — AWS CDK app provisioning the hosting for jarl.randomdev.co.uk. Also a separate npm project, kept out of the workspaces so it is never published: `infra/README.md`. +A new atom's name says what it returns: `*RouteAtom` if its value is a `RouteAtom`, `*Atom` +otherwise. See `packages/jarl-atoms/DESIGN-NOTES.md`. + The two packages are deliberately separate import paths: `jarl-react` does **not** re-export `jarl-atoms`. Consumers get route atoms from `jarl-atoms` and the React bindings from `jarl-react`, so the framework boundary stays visible and `jarl-atoms` is usable on its own. diff --git a/README.md b/README.md index 47b288d..60f0e5d 100644 --- a/README.md +++ b/README.md @@ -16,30 +16,30 @@ wanted something that did just this job extremely well, but without getting in t dictating application structure, and without forcing route matching logic into the component tree itself, where it never seemed to belong. JARL builds that mapping out of composable atoms using [jotai](https://jotai.org/) under the hood: each route is its own atom, with a link to a -parent atom and so on up to the [`rootAtom`](/api/jarl-atoms#rootatom); each one matching a -piece of the URL (normally a path segment) and telling you both whether it *currently* matches, +parent atom and so on up to the [`rootRoute`](/api/jarl-atoms#rootroute); each one matching a +piece of the URL (normally a path segment) and telling you both whether it _currently_ matches, as well as **how to build a URL _to_ that route** based on a given state. Routing decisions in your application then decompose to very simple logic based on the current states of these atoms; a simple `switch` statement or series of `if`s is enough to decide what components to -render, and navigation can be performed by *calling the atom setter*. (Convenience components +render, and navigation can be performed by _calling the atom setter_. (Convenience components like [``](/api/jarl-react#route) and [``](/api/jarl-react#switch) and of course the ubiquitous [``](/api/jarl-react#link) are of course provided in the React package, if you want to build more compositionally; they all just accept atoms for parameters instead of type-unsafe strings.) Because each route atom is an independent, subscribable unit of jotai state, a component that -reads one only re-renders when *that atom's* derived value actually changes - it turns out this +reads one only re-renders when _that atom's_ derived value actually changes - it turns out this is incredibly efficient. ## Features -* Map URLs directly to state (and back again) - the URL becomes the source of truth -* Composable route atoms - build nested/dynamic routes out of small, independent pieces -* Framework-agnostic core (`jarl-atoms`) with lightweight React bindings (`jarl-react`) -* Full querystring matching support -* Resolve promises during routing (via jotai's own async atoms) and redirect if required -* SSR/SSG-safe: the resolved location atom is hydratable per-render on the server -* And much more... +- Map URLs directly to state (and back again) - the URL becomes the source of truth +- Composable route atoms - build nested/dynamic routes out of small, independent pieces +- Framework-agnostic core (`jarl-atoms`) with lightweight React bindings (`jarl-react`) +- Full querystring matching support +- Resolve promises during routing (via jotai's own async atoms) and redirect if required +- SSR/SSG-safe: the resolved location atom is hydratable per-render on the server +- And much more... ## Concrete Example @@ -54,9 +54,9 @@ Declare some route atoms: ```ts // routes.ts -import { rootAtom, staticRouteAtom, paramRouteAtom } from "jarl-atoms"; +import { rootRoute, staticRouteAtom, paramRouteAtom } from "jarl-atoms"; -export const homeRoute = rootAtom; +export const homeRoute = rootRoute; export const aboutRoute = staticRouteAtom("about"); export const productsRoute = staticRouteAtom("products"); // The `productId` segment is bound into `values` when this route matches: @@ -75,7 +75,7 @@ import App from "./App"; createRoot(document.getElementById("root")!).render( - + , ); ``` @@ -110,7 +110,9 @@ import { Link } from "jarl-react"; const MainMenu = () => (