{"_id":"@bunnix/router","_rev":"3-f9b1f2f31733cfe27d9c951a1485ea02","name":"@bunnix/router","dist-tags":{"latest":"0.10.0"},"versions":{"0.9.0":{"name":"@bunnix/router","version":"0.9.0","author":{"name":"@bunnix"},"license":"ISC","_id":"@bunnix/router@0.9.0","maintainers":[{"name":"morissonmaciel","email":"morissonmaciel@gmail.com"}],"dist":{"shasum":"b41301000555fa2b85ac196cd4abdf3f102b7934","tarball":"https://registry.npmjs.org/@bunnix/router/-/router-0.9.0.tgz","fileCount":16,"integrity":"sha512-7RLIw526fH9SofkXNAYVVWjw2EjRhPkOyb0X12j1pN6ipXYCm+tEfU0b39OB5pDMMKY45zP+Ght1XrRbzcyaDg==","signatures":[{"sig":"MEQCIGkWuz1XeiMcgLW7m84K5P90tZoLc8vtF9Om8ShUZodTAiBE49nn0I1T+LILDpt/dMeITJCjShZ4tZ9EA9P61SqHZA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44483},"main":"./index.mjs","type":"module","types":"./@types/index.d.ts","module":"./index.mjs","exports":{".":{"types":"./@types/index.d.ts","import":"./index.mjs"},"./@types":{"types":"./@types/index.d.ts"}},"gitHead":"1965e6706b3a93a2b5ad652815a7ca8c6657d5ee","scripts":{"test":"node --test --import ./tests/setup-dom.mjs"},"_npmUser":{"name":"morissonmaciel","email":"morissonmaciel@gmail.com"},"_npmVersion":"10.8.2","description":"Bunnix Router: decentralized, context-aware routing for Bunnix","directories":{},"_nodeVersion":"20.19.6","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^26.0.0","@bunnix/core":"0.9.0"},"peerDependencies":{"@bunnix/core":"^0.9.0"},"_npmOperationalInternal":{"tmp":"tmp/router_0.9.0_1768358228423_0.6943699387005382","host":"s3://npm-registry-packages-npm-production"}},"0.9.1":{"name":"@bunnix/router","version":"0.9.1","author":{"name":"@bunnix"},"license":"ISC","_id":"@bunnix/router@0.9.1","maintainers":[{"name":"morissonmaciel","email":"morissonmaciel@gmail.com"}],"dist":{"shasum":"ceb648071ad07ccb1a8fa4c21fc5b7a33b44f556","tarball":"https://registry.npmjs.org/@bunnix/router/-/router-0.9.1.tgz","fileCount":16,"integrity":"sha512-k6m2v5uAkNgO8KMjDQ0i5BeyH/hpQuOFXHIqXj7gLdGFZT1XOxZ2qm/MpiPChTtGTBqgxTGSvMR7RCbNwr2Tnw==","signatures":[{"sig":"MEUCIQDk35VvAJ46Hn4j7qiI9Pivrd0RtFQMf2p0h3vEPo23FwIgHbBi/f04dIyClEyNa8+e2hn/HXBt9/SxHPX9vn42EXU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50234},"main":"./index.mjs","type":"module","types":"./@types/index.d.ts","module":"./index.mjs","exports":{".":{"types":"./@types/index.d.ts","import":"./index.mjs"},"./@types":{"types":"./@types/index.d.ts"}},"gitHead":"9bcd161b208a4b74b90f36ca7506033bdce30983","scripts":{"test":"node --test --import ./tests/setup-dom.mjs"},"_npmUser":{"name":"morissonmaciel","email":"morissonmaciel@gmail.com"},"_npmVersion":"10.8.2","description":"Bunnix Router: decentralized, context-aware routing for Bunnix","directories":{},"_nodeVersion":"20.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^26.0.0","@bunnix/core":"0.9.0"},"peerDependencies":{"@bunnix/core":"^0.9.0"},"_npmOperationalInternal":{"tmp":"tmp/router_0.9.1_1770408893809_0.5451669653059072","host":"s3://npm-registry-packages-npm-production"}},"0.10.0":{"name":"@bunnix/router","version":"0.10.0","description":"Bunnix Router: decentralized, context-aware routing for Bunnix","license":"ISC","author":{"name":"@bunnix"},"publishConfig":{"access":"public"},"type":"module","main":"./index.mjs","module":"./index.mjs","types":"./@types/index.d.ts","exports":{".":{"types":"./@types/index.d.ts","import":"./index.mjs"},"./@types":{"types":"./@types/index.d.ts"}},"scripts":{"test":"node --test --import ./tests/setup-dom.mjs"},"peerDependencies":{"@bunnix/core":"^0.10.0"},"devDependencies":{"@bunnix/core":"0.10.0","jsdom":"^26.0.0"},"_id":"@bunnix/router@0.10.0","gitHead":"3c81f4a30cf3c8410444fd525effb9b466b3fa45","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-0miKycO+XVCW4TpL8GRjCgfjtZPBDGyASYCdOgcUYAABOIMkCyIyaHDM04DyFN2lVc5qXzNxGyIPTFJHqOnz7g==","shasum":"8344404dd474f0c2620f1d059b6611884764d787","tarball":"https://registry.npmjs.org/@bunnix/router/-/router-0.10.0.tgz","fileCount":16,"unpackedSize":50237,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBoZzkh/qpAxLLMJB0zgsS7c0Ba2ZAs+cMGUSJZRVBYRAiBReqdLLra/1aA/ZYexi2/SAq2UHE1tzjPC2svwpNB1ow=="}]},"_npmUser":{"name":"morissonmaciel","email":"morissonmaciel@gmail.com"},"directories":{},"maintainers":[{"name":"morissonmaciel","email":"morissonmaciel@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/router_0.10.0_1778073040907_0.266019248964253"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-14T02:37:08.321Z","modified":"2026-05-06T13:10:41.168Z","0.9.0":"2026-01-14T02:37:08.587Z","0.9.1":"2026-02-06T20:14:53.980Z","0.10.0":"2026-05-06T13:10:41.046Z"},"author":{"name":"@bunnix"},"license":"ISC","description":"Bunnix Router: decentralized, context-aware routing for Bunnix","maintainers":[{"name":"morissonmaciel","email":"morissonmaciel@gmail.com"}],"readme":"# Bunnix Router\n\nA decentralized, context-aware routing solution for the Bunnix framework.\n\n## Key Features\n\n- **Route Groups**: Organize routes with shared policies and layouts.\n- **Policies**: Centralize guard logic with `RoutePolicy`.\n- **Scoped Navigation**: Navigation is injected into components and layouts.\n- **Dynamic Parameters**: Parse URL segments like `:id` automatically.\n- **Layout Support**: Persistent layouts with `routerOutlet`.\n\n## Bootstrap\nTo enable routing, you must wrap your root component in the `BrowserRouter` when calling the render function.\n\n```javascript\nimport Bunnix from '@bunnix/core';\nimport { BrowserRouter } from '@bunnix/router';\nimport App from './App.js';\n\nBunnix.render(\n    <BrowserRouter>\n        <App />\n    </BrowserRouter>,\n    document.getElementById('root')\n);\n```\n\n## Example Usage\n\n### Setting up the Router\n```javascript\nimport Bunnix from '@bunnix/core';\nimport { RouterRoot, RouteGroup, Route, Link } from '@bunnix/router';\n\nconst App = () => (\n    <RouterRoot>\n        <RouteGroup root layout={AppLayout}>\n            <Route path=\"/\" component={Home} />\n            <Route path=\"/user/:id\" component={UserProfile} />\n        </RouteGroup>\n        <Route notFound component={NotFound} />\n    </RouterRoot>\n);\n```\n\n### Router Context Helper\n\n```javascript\nimport { useRouterContext } from '@bunnix/router';\n\nconst appContext = useRouterContext({\n    user: null,\n    permissions: []\n});\n```\n\n### Policies\nPolicies run before rendering and can redirect.\n\n```javascript\nimport { RouterRoot, RouteGroup, RoutePolicy, Route } from '@bunnix/router';\n\nconst App = () => (\n    <RouterRoot>\n        <RouteGroup rootPath=\"/account\">\n            <Route path=\"/account\" component={Account} />\n            <RoutePolicy handler={({ context, navigation }) => {\n                if (!context.user) navigation.replace('/login');\n            }} />\n        </RouteGroup>\n    </RouterRoot>\n);\n```\n\n### Layouts & Router Outlet\nLayouts allow you to wrap your routes with persistent UI (like navbars or sidebars). A layout component receives two special props: `routerOutlet` and `navigation`.\n\n```javascript\nimport { Link } from '@bunnix/router';\n\n/**\n * @param {Function} props.routerOutlet - A function that returns the matched route content.\n * @param {Object} props.navigation - Reactive navigation state for the active group.\n */\nfunction AppLayout({ routerOutlet, navigation }) {\n    return Bunnix('div', { class: 'layout' }, [\n        Bunnix('p', [`Current path: ${navigation.get().path}`]),\n        Bunnix('nav', [\n            Link({ to: '/', navigation }, 'Home'),\n            Link({ to: '/form', navigation }, 'Form')\n        ]),\n        Bunnix('main', [\n            // Call the outlet to render the matched route component\n            routerOutlet()\n        ])\n    ]);\n}\n```\n\n#### With vs Without Layout\n- **With Layout**: The `RouteGroup` renders the layout component. The matched route is **not** visible until you call `props.routerOutlet()` inside the layout's VDOM.\n- **Without Layout**: The matched route component renders directly as its only content.\n\n\n### Consuming Navigation\nMatched route components receive unwrapped `navigation` values. Layouts receive reactive navigation state.\n\n```javascript\nfunction Home({ navigation }) {\n    return Bunnix('div', [\n        Bunnix('h1', 'Home Page'),\n        Bunnix('button', { \n            click: () => navigation.push('/user/123') \n        }, 'View User')\n    ]);\n}\n```\n\n### Navigation Object Reference\n\nFor matched route components:\n- `navigation.push(path)`: Navigates to a new URL.\n- `navigation.replace(path)`: Replaces the current history entry.\n- `navigation.back(fallback?)`: Goes back in history or to the fallback (defaults to `rootPath`).\n- `navigation.path`: Current path string.\n- `navigation.params`: Current route params.\n- `navigation.currentGroup`: Current group root path.\n\nFor layout components:\n- `navigation.get()`: Returns `{ path, params, currentGroup }`.\n- `navigation.subscribe(cb)`: Subscribes to path/params/group changes.\n- `navigation.map(fn)`: Creates a derived state from navigation state.\n- `navigation.push(path)`, `navigation.replace(path)`, `navigation.back(fallback?)`.\n\n## Components\n\n- `BrowserRouter`: The root container for your routing tree.\n- `RouterRoot`: Defines the router tree.\n- `RouteGroup`: Defines grouped routes with layouts and policies.\n- `RoutePolicy`: Guards for group routes.\n- `Link`: A helper component for declarative navigation: `Link({ to: '/path', navigation }, 'Label')`.\n\n## IntelliSense\n\nFor best auto-completion in IDEs, prefer named imports from `@bunnix/router`:\n\n```javascript\nimport { BrowserRouter, RouterRoot, RouteGroup, RoutePolicy, Route, Link } from '@bunnix/router';\n```\n\nThe `Router` proxy export supports runtime aliases, but named imports provide stronger static completion.\n","readmeFilename":"README.md"}