npm package: @ristellise/tru.js
Description: Tiny Router Utility. A minimalist, zero-dependency SPA router using URLPattern.
Author: Shinon
Latest version: 1.0.0

# @ristellise/tru.js

**T**iny **R**outer **U**tility.

A minimalist, zero-dependency Single Page Application (SPA) router for vanilla JavaScript. 

`tru.mjs` is an **ES Module-only** library that relies on the browser's native [URLPattern API](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) to handle route matching and the HTML5 History API for navigation. By offloading complex regex parsing to the browser's native engine, `tru.mjs` provides standard, robust routing (e.g., `/users/:id`) in roughly 50 lines of code.

## Installation

Install via npm:

```bash
npm install @ristellise/tru.js
```

Or use it directly in the browser via a CDN:

```html
<script type="module">
  import { createRouter } from 'https://cdn.jsdelivr.net/npm/@ristellise/tru.js/tru.mjs';
</script>
```

## Quick Start

`tru.mjs` uses a fluent, chainable API.

```javascript
import { createRouter } from '@ristellise/tru.js';

const app = document.getElementById('app');
const router = createRouter();

router
  .add('/', () => {
      app.innerHTML = '<h1>Home</h1>';
  })
  .add('/users/:id', (params) => {
      // URLPattern automatically extracts named parameters
      app.innerHTML = `<h1>User Profile: ${params.id}</h1>`;
  })
  .add('*', () => {
      // Catch-all wildcard for 404s
      app.innerHTML = '<h1>404 - Not Found</h1>';
  })
  .start(); // Bootstraps the event listeners and triggers the initial route
```

## How It Works (Link Interception)

When you call `router.start()`, `tru.mjs` attaches a single global click listener to `document.body`. It intercepts clicks on `<a>` tags and routes them via JavaScript, preventing standard browser page reloads.

**Safety Features:**
To prevent breaking native browser behavior, the interceptor will **ignore** the click and let the browser handle it natively if:
* The user holds `Ctrl` or `Cmd` (opening in a new tab).
* The link has `target="_blank"` or `target="_top"`.
* The link points to an external domain (cross-origin).
* The link has a `download` attribute.
* The link has a custom `data-bypass` attribute (e.g., `<a href="/api/logout" data-bypass>Logout</a>`).
* **The route is not registered in the router.** If you link to `/admin` but forgot to `add('/admin')`, the router will gracefully ignore it and let the browser make a hard navigation to the server. *(Note: If you add a catch-all route like `*`, the router will handle everything).*

## API Reference

*   **`createRouter()`**: Factory function that creates and returns a new router instance.
*   **`router.add(pattern, callback)`**: Registers a new route. `pattern` uses standard `URLPattern` syntax (e.g., `/`, `/about`, `/posts/:id`, `/files/*`). `callback` receives a `params` object containing extracted URL parameters.
*   **`router.go(path)`**: Programmatically navigates to a new path.
*   **`router.fallback(callback)`**: Registers a fallback handler for programmatic navigations that fail to match a route.
*   **`router.start()`**: Initializes the router. Attaches `popstate` and click listeners, and executes the callback for the current `window.location.href`.

## Browser Support

`tru.mjs` utilizes the standard **URLPattern API**. This is natively supported in modern Chromium 95+, Firefox 142+, and Safari 26+.

If you need to support older browsers, import the official `urlpattern-polyfill` before initializing the router.

## FAQ / Philosophy

**"Why not just use Vue/React at this point?"**  
Because you shouldn't have to subscribe to an entire framework paradigm, setup a build step, and ship a massive JavaScript bundle just to use a neat feature. `tru.js` (and its companion DOM builder, `tdeb.js`) are designed to be strictly additive utilities, not overarching frameworks.

**"Why not use [Insert Popular Router X]?"**  
Because I identified a specific need I had while coding, realized modern browser APIs (`URLPattern`) had already solved the hardest part of the problem natively, and I just built it anyway. It's 50 lines of code, it has zero dependencies, and I don't have to fight my tools to use it.

## License

MIT