diff --git a/AGENTS.md b/AGENTS.md index 4b0ec4b..37d0f8d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,10 +1,10 @@ -# N-Savant Routing Library +# Svelte Router Routing Library ## Library Architecture Overview ### Routing Universes Concept -The @wjfe/n-savant routing library supports simultaneous path and hash routing through "routing universes": +The @svelte-router/core routing library supports simultaneous path and hash routing through "routing universes": - **Path Routing** (`hash: false`): Uses URL pathname - **Single Hash Routing** (`hash: true`): Uses URL hash as a single path (e.g., `#/path/to/route`) @@ -601,7 +601,7 @@ This pattern provides: import { init, type Hash } from "$lib/index.js"; import { describe, test, expect, beforeAll, afterAll, beforeEach } from "vitest"; import { render } from "@testing-library/svelte"; -import { RouterEngine } from "$lib/core/RouterEngine.svelte.js"; +import { RouterEngine } from "$lib/kernel/RouterEngine.svelte.js"; import { getRouterContextKey } from "../Router/Router.svelte"; import { createRawSnippet } from "svelte"; import { flushSync } from "svelte"; // For Svelte 5 reactivity testing diff --git a/README.md b/README.md index ded8589..79fa0aa 100644 --- a/README.md +++ b/README.md @@ -1,89 +1,62 @@ -# N-Savant Logo   @wjfe/n-savant +# Svelte Router Logo  @svelte-router/core -> The client-side router for Svelte v5 SPA's that invented multi hash routing. +> Next-level routing for Svelte and Sveltekit. [REPL Demo](https://svelte.dev/playground/d273d356947e48c0822a65402fd06fac) -## Features +[Full Documentation @ Hashnode Space](https://wjfe-n-savant.hashnode.space) -> **📝 Small and Unique!** +> **🚧 IMPORTANT NOTICE** +> +> We're in the process of re-branding the package as `@svelte-router/core`. This document has been updated to reflect +> this (future) new package name. In the meantime, continue using the soon-to-be-deprecated package name, +> `@wjfe/n-savant` when installing or importing. +> +> If you need to import stuff from `@svelte-router/core/kernel`, in the old package the path is `@wjfe/n-savant/core`. > -> + Less than **1,450** lines of code, including TypeScript typing. -> + Always-on path and hash routing. Simultaneous and independent routing modes. -> + The router that invented multi hash routing. -> + **NEW!** Supports Sveltekit (via [@wjfe/n-savant-sk](https://github.com/WJSoftware/wjfe-n-savant-sk)) +> The full online documentation has already been updated, but the URL's cannot be changed. Alas, we'll have to deploy +> our own docs and stop using Hashnode Space. +## Features + ++ **Always-on path and hash routing**: Simultaneous, independent and always-on routing modes. ++ **Multi hash routing**: Doing micro-frontends? Routing tabs or dialogs using the URL? Have as many paths as needed. ++ **Sveltekit support**: Add hash routing on top of Sveltekit's path routing Via +[@svelte-router/kit](https://github.com/WJSoftware/svelte-router-kit) + **Electron support**: Works with Electron (all routing modes) + **Reactivity-based**: All data is reactive, reducing the need for events and imperative programming. -+ **Always-on path and hash routing**: Add routers that use the URL's path name or the URL's hash value in the same -application. Both routing modes are possible simultaneously. -+ **Multi-hash routing**: This is the first router in the world to do this: You can create named paths in the hash -value of the URL and create router hierarchies that use a specific named path. - -### `` Component - -+ **Multi-matching routes**: All routes are evaluated, which is useful to mount micro-frontends. -+ **Base paths**: Specify base paths that are inherited by routes and nesting routers. -+ **Nesting routers**: Add child routers inside routers for fine-grained control. -+ **Liberty**: Place anything anywhere inside. No child restrictions. - -### `` Component - -+ **Exact path matching**: Exact match by default; specify the rest parameter to relax the condition. -+ **Path as string or regular expression**: Define paths however's best for you. -+ **Route parameters**: Define route parameters inside string paths or regular expression paths. -+ **Rest parameter**: Collect "the rest" of the path. -+ **Optional parameters**: Parameters may be specified as optional. -+ **Additional matching logic**: Add a predicate function to further restrict a route's matching ability. -+ **Path is optional**: Forgo path specification entirely and handle route matching entirely with code. -+ **Superb Intellisense**: The route parameters are strongly typed when defining them inside a string path. -+ **Disconnected UI pieces**: Repeat route keys in `Route` components to show disconnected pieces of UI for a given -route's key. - -### `` Component - -+ **Non-matching content**: Show users something when there are no matching routes. -+ **Disconnected content**: Add as many `Fallback` components as needed in various places. - -### `` Component - -+ **Drop-in replacement**: Exchange `` tags with `` tags and you're done.[^1] -+ **Specify state**: Set history state upon hyperlink click. -+ **Active state based on route key**: Automatically set active state and `aria-current` by specifying the route's key. -+ **Replace or push**: Select the method for pushing state. -+ **Preserve query string**: Opt in to preserve existing query string values. -+ **Shallow routing**: [This Sveltekit](https://svelte.dev/docs/kit/shallow-routing) document explains the concept. -[^1]: For hyperlink components that only specify a hash and are converted to hash-routing `` components, remove -the pound sign (`#`) from the href. +**Components**: -### `` Component ++ `` ++ `` ++ `` ++ `` ++ `` ++ `` -+ **Centralize `` configuration**: Configures a special context that all `` components follow. +**Reactive Data**: -### `` Component ++ `location.url` ++ `location.hashPaths` ++ `location.getState()` ++ `RouterEngine.routes` ++ `RouterEngine.routeStatus` -+ **Tracing Information**: Drop it inside a router to display its route status data, including the internal regular -expressions that are generated from string path patterns. -+ **Specify a specific router**: Ability to give it a specific router engine object, allowing tracing of router engine -objects created in code. -+ **Track child routers**: See and traverse the router hierarchy. +All data is a Svelte signal. Add routes dynamically or reactively, change route conditions on the fly, and more pieces +of user interface on-demand, etc. All works reactively. -### `location` Global Object +### Two Library Modes -+ **Reactive URL**: URL object that's always in sync with the browser's URL. -+ **Reactive state**: Reactive state property that's always in sync with the history state. -+ **Reactive hash paths**: Reactive dictionary object for all hash paths. -+ **Programatic navigation**: Use the the `navigate()` method to trigger navigation programatically. +Most people only need the normal or "lite" version. Use the full version to battle/counter foreign routers +(micro-frontend scenarios, most likely). #### In Full Mode... -+ **Cancellable `beforeNavigate` event**: Get notified of navigation events, and cancel when appropriate. -+ **`navigationCancelled` event**: Get notified whenever navigation is cancelled. + **History API interception**: Gain control over the history object to avoid external code/routers from de-synchronizing state. -+ **Micro-frontends**: Full mode's features are great for micro-frontend scenarios where other routers (from -potentially other technologies) might interfere with the router's functionality. ++ **Cancellable `beforeNavigate` event**: Get notified of navigation events, and cancel when appropriate. ++ **`navigationCancelled` event**: Get notified whenever navigation is cancelled. ## Quickstart @@ -95,37 +68,48 @@ potentially other technologies) might interfere with the router's functionality. ### Install the package ```bash -npm i @wjfe/n-savant +npm i @svelte-router/core ``` ### Initialize the Library ```typescript // In your main.ts, or somewhere BEFORE any routers are created: -import { init } from "@wjfe/n-savant"; +import { init } from "@svelte-router/core"; -// Default: Lite mode, implicit path routing, no router hierarchy tracing, single hash mode. -init(); +/* +Default: + +- Lite mode +- Implicit path routing +- No router hierarchy tracing +- Single hash mode +- Log to console. +*/ +init(); // Or use initFull() for full-mode. -// If all you care about is (traditional) hash routing, the recommendation is to change the implicit mode: +// Common case: "I just need good, old-fashioned hash routing." init({ implicitMode: 'hash' }); ``` #### Electron Variant -In Electron, we must immediately navigate to the homepage (or your preferred initial route) right after initializing if you use path routing: +In Electron, we must immediately navigate to the homepage (or your preferred initial route) right after initializing +if you use path routing: ```typescript -import { init, location } from "@wjfe/n-savant"; +import { init, location } from "@svelte-router/core"; init(); location.goTo('/'); ``` -For applications that also run in the browser, condition the navigation to Electron only. See the [Electron page](https://wjfe-n-savant.hashnode.space/wjfe-n-savant/introduction/electron-support) online for more details. - > **⚠️ Important:** Hash routing doesn't require this extra navigation step. +For applications that also run in the browser, condition the navigation to Electron only. See the +[Electron page](https://wjfe-n-savant.hashnode.space/wjfe-n-savant/introduction/electron-support) online for more +details. + ### Define the Routes ``s are added inside ``s. ``s can be nested inside other ``s. ``s can render @@ -133,7 +117,7 @@ For applications that also run in the browser, condition the navigation to Elect ```svelte @@ -165,7 +149,7 @@ functionality. Still, this is not mandatory. ```svelte