@owlmeans/web-router-react-router 0.1.18-rc.9 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,128 @@
1
+ # @owlmeans/web-router-react-router
2
+
3
+ React Router as an opt-in OwlMeans routing plugin. `@owlmeans/router` is a plugin host that picks
4
+ the active `RouterPlugin` by priority cascade; `@owlmeans/web-client` and `@owlmeans/web-panel`
5
+ register the default OwlMeans in-browser plugin (`@owlmeans/web-router`, priority 0). This package
6
+ registers a react-router plugin at priority 100, so one `appendReactRouter(context)` call in an app's
7
+ `makeContext` switches that app's routing to `createBrowserRouter` with react-router's provider,
8
+ outlet and hooks — route and entrypoint declarations stay unchanged. Use it only when an app
9
+ specifically needs react-router (an existing react-router codebase, a library that expects its
10
+ context); otherwise keep the default plugin and do not install this package. Server-side rendering
11
+ or React Native routing is a plugin of its own, not this one. The `web-router-react-router` skill
12
+ covers this package; the `router-plugins` skill covers the plugin model.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ bun add @owlmeans/web-router-react-router@^0.1.18 react-router
18
+ ```
19
+
20
+ Peer dependencies: `react` and `react-router@^8.4.0`.
21
+
22
+ ## Concepts
23
+
24
+ - **Router host** — the `RouterService` from `@owlmeans/router`, registered on the context as
25
+ `router-service` and reached through `context.router()`. Its facade (`compile`, `provider`,
26
+ `outlet`, `useParams`, `useLocation`, `useNavigate`, `useSearchParams`) delegates to the active
27
+ plugin.
28
+ - **Cascade** — plugins are sorted by `priority` (higher first); the first whose `match(env)` is
29
+ truthy wins. This plugin's `match` always returns `true`, so at priority 100 it wins over the
30
+ default browser plugin in every environment.
31
+ - **Alias** — the plugin registers as `'react-router'` (`REACT_ROUTER`); registering the same alias
32
+ again replaces it, so calling `appendReactRouter` twice is harmless.
33
+ - **Neutral routes** — the `RouteObject` tree produced from entrypoints uses react-router-compatible
34
+ paths, so both plugins consume the same tree.
35
+
36
+ ## Usage
37
+
38
+ ### 1. Switch an app to react-router
39
+
40
+ Call it after the layer context factory, which has already registered the default plugin.
41
+
42
+ ```typescript
43
+ import { makeContext as makePanelContext } from '@owlmeans/web-panel'
44
+ import type { AppConfig, AppContext } from '@owlmeans/web-panel'
45
+ import { appendReactRouter } from '@owlmeans/web-router-react-router'
46
+
47
+ export const makeContext = <C extends AppConfig, T extends AppContext<C>>(cfg: C): T => {
48
+ const context = makePanelContext<C, T>(cfg)
49
+ appendReactRouter<C, T>(context) // priority 100 beats the default plugin's 0
50
+
51
+ return context
52
+ }
53
+ ```
54
+
55
+ `<App>` and `<PanelApp>` need no `provide` prop: without it they compile routes through the active
56
+ plugin (`context.router().compile`).
57
+
58
+ ### 2. Use the hooks through the facade
59
+
60
+ Application code keeps using the OwlMeans facade, not react-router imports, so switching the plugin
61
+ back needs no code changes.
62
+
63
+ ```tsx
64
+ import { useContext } from '@owlmeans/client'
65
+
66
+ export const ProjectHeader = () => {
67
+ const context = useContext()
68
+ const { projectId } = context.router().useParams<{ projectId: string }>()
69
+ const [search] = context.router().useSearchParams()
70
+
71
+ return <h1>{projectId} — {search.get('tab') ?? 'overview'}</h1>
72
+ }
73
+ ```
74
+
75
+ ### 3. Register the plugin object directly
76
+
77
+ `makeReactRouterPlugin()` returns the plugin for a host you manage yourself — a custom router
78
+ service, or a test that wants a fixed plugin.
79
+
80
+ ```typescript
81
+ import { ensureRouterService } from '@owlmeans/router'
82
+ import { makeReactRouterPlugin, REACT_ROUTER } from '@owlmeans/web-router-react-router'
83
+
84
+ const router = ensureRouterService(context)
85
+ router.registerPlugin(makeReactRouterPlugin())
86
+ router.plugin().alias === REACT_ROUTER // true
87
+ ```
88
+
89
+ ## API
90
+
91
+ | Symbol | Kind | Purpose |
92
+ |---|---|---|
93
+ | `appendReactRouter(ctx)` | function | `ensureRouterService(ctx).registerPlugin(makeReactRouterPlugin())`; returns the same context |
94
+ | `makeReactRouterPlugin()` | function → `RouterPlugin` | The plugin object (below) |
95
+ | `REACT_ROUTER` | const | `'react-router'` — the plugin alias |
96
+ | `REACT_ROUTER_PRIORITY` | const | `100` — above the default plugin's `0` |
97
+
98
+ ### The plugin
99
+
100
+ | Member | Value |
101
+ |---|---|
102
+ | `alias` / `priority` / `mode` | `'react-router'` / `100` / `'browser'` |
103
+ | `match` | `() => true` |
104
+ | `compile(routes)` | `createBrowserRouter(routes)` |
105
+ | `provider()` / `outlet()` | react-router's `RouterProvider` / `Outlet` |
106
+ | `useParams`, `useLocation`, `useNavigate`, `useSearchParams` | react-router's hooks of the same name |
107
+
108
+ ## Common pitfalls
109
+
110
+ - Calling `appendReactRouter` before the layer factory is harmless for the cascade (priority decides,
111
+ not order), but it must run on the same context the app renders.
112
+ - The plugin is browser-only (`createBrowserRouter`, `match` always true). An SSR or native
113
+ environment needs its own plugin at a higher priority with an environment-specific `match`.
114
+ - Importing react-router hooks directly in application code ties it to this plugin; go through
115
+ `context.router()` or `@owlmeans/client`'s `useNavigate` instead.
116
+ - `react-router` is a peer dependency — install it in the app, matching `^8.4.0`.
117
+
118
+ ## Related packages
119
+
120
+ - [`@owlmeans/router`](../router) — the plugin host, `RouterPlugin` contract and `ensureRouterService`
121
+ - [`@owlmeans/web-router`](../web-router) — the default OwlMeans in-browser plugin (priority 0)
122
+ - [`@owlmeans/web-client`](../web-client) — registers the default plugin and renders `<App>`
123
+ - [`@owlmeans/web-panel`](../web-panel) — the panel layer factory and `<PanelApp>`
124
+ - [`@owlmeans/client`](../client) — `useContext` and the entrypoint-aware `useNavigate`
125
+
1
126
  <!-- owlmeans:agent-guidance:start -->
2
127
  ## Agent guidance
3
128
 
@@ -6,7 +131,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
6
131
  your project's skill store (`.agents/skills/`):
7
132
 
8
133
  ```sh
9
- npx @owlmeans/agent-skills@^0.1.18-rc.13
134
+ npx @owlmeans/agent-skills@^0.1.18
10
135
  ```
11
136
 
12
137
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
- "schemaVersion": 2,
2
+ "schemaVersion": 3,
3
3
  "package": "@owlmeans/web-router-react-router",
4
- "version": "0.1.18-rc.9",
5
- "generatedAt": "2026-09-10T18:54:42.495Z",
4
+ "version": "0.1.18",
5
+ "generatedAt": "2026-10-28T00:31:34.731Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/web-router-react-router
9
9
 
10
10
  **Layer:** Web (React), build level L2
11
- **Install:** `"@owlmeans/web-router-react-router": "^0.1.18-rc.9"` in `dependencies`
11
+ **Install:** `"@owlmeans/web-router-react-router": "^0.1.18"` in `dependencies`
12
12
 
13
13
  The React Router v8 mechanic as an OwlMeans routing plugin. react-router is **opt-in**: OwlMeans
14
14
  in-browser routing is the default, and you add this plugin only when you specifically want
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/web-router-react-router",
3
- "version": "0.1.18-rc.9",
3
+ "version": "0.1.18",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -22,19 +22,19 @@
22
22
  },
23
23
  "peerDependencies": {
24
24
  "react": "*",
25
- "react-router": "^8.3.0"
25
+ "react-router": "^8.4.0"
26
26
  },
27
27
  "devDependencies": {
28
- "@owlmeans/dep-config": "workspace:*",
29
- "@types/node": "^26.1.0",
30
- "@types/react": "^19.2.17",
28
+ "@owlmeans/dep-config": "^0.1.18",
29
+ "@types/node": "^26.6.4",
30
+ "@types/react": "^19.3.0",
31
31
  "nodemon": "^3.1.14",
32
- "react-router": "^8.3.0",
32
+ "react-router": "^8.4.0",
33
33
  "typescript": "^7.0.2"
34
34
  },
35
35
  "dependencies": {
36
- "@owlmeans/context": "^0.1.18-rc.9",
37
- "@owlmeans/router": "^0.1.18-rc.9"
36
+ "@owlmeans/context": "^0.1.18",
37
+ "@owlmeans/router": "^0.1.18"
38
38
  },
39
39
  "publishConfig": {
40
40
  "access": "public"