@flight-framework/router 0.0.2 → 0.0.3

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,137 +1,273 @@
1
- # @flight-framework/router
2
-
3
- Client-side routing primitives for Flight Framework.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @flight-framework/router
9
- ```
10
-
11
- ## Usage
12
-
13
- ### With React
14
-
15
- ```tsx
16
- import { RouterProvider, Link, useRouter } from '@flight-framework/router';
17
-
18
- // Wrap your app
19
- function App() {
20
- return (
21
- <RouterProvider initialPath={url}>
22
- <Navigation />
23
- <Content />
24
- </RouterProvider>
25
- );
26
- }
27
-
28
- // Use Link for navigation
29
- function Navigation() {
30
- return (
31
- <nav>
32
- <Link href="/">Home</Link>
33
- <Link href="/docs" prefetch>Docs</Link>
34
- <Link href="/about">About</Link>
35
- </nav>
36
- );
37
- }
38
-
39
- // Use hooks to access router state
40
- function Content() {
41
- const { path, navigate } = useRouter();
42
-
43
- return (
44
- <main>
45
- <p>Current path: {path}</p>
46
- <button onClick={() => navigate('/dashboard')}>
47
- Go to Dashboard
48
- </button>
49
- </main>
50
- );
51
- }
52
- ```
53
-
54
- ### Hooks
55
-
56
- ```tsx
57
- // Get current path and navigation functions
58
- const { path, searchParams, navigate, back, forward } = useRouter();
59
-
60
- // Get route parameters (from dynamic routes like [slug])
61
- const { slug } = useParams<{ slug: string }>();
62
-
63
- // Get and set search params
64
- const [searchParams, setSearchParams] = useSearchParams();
65
-
66
- // Get current pathname
67
- const pathname = usePathname();
68
- ```
69
-
70
- ### Programmatic Navigation
71
-
72
- ```ts
73
- import { navigate, prefetch } from '@flight-framework/router';
74
-
75
- // Navigate to a path
76
- navigate('/docs');
77
-
78
- // Replace history instead of push
79
- navigate('/login', { replace: true });
80
-
81
- // Navigate without scrolling to top
82
- navigate('/next-page', { scroll: false });
83
-
84
- // Pass state data
85
- navigate('/dashboard', { state: { from: '/login' } });
86
-
87
- // Prefetch a route
88
- prefetch('/heavy-page');
89
- ```
90
-
91
- ### Route Matching
92
-
93
- ```ts
94
- import { matchRoute, parseParams, generatePath } from '@flight-framework/router';
95
-
96
- // Check if a path matches a pattern
97
- const { matched, params } = matchRoute('/docs/routing', '/docs/:slug');
98
- // matched: true, params: { slug: 'routing' }
99
-
100
- // Parse params from a path
101
- const params = parseParams('/blog/2024/my-post', '/blog/:year/:slug');
102
- // { year: '2024', slug: 'my-post' }
103
-
104
- // Generate a path from pattern and params
105
- const path = generatePath('/docs/:slug', { slug: 'api-routes' });
106
- // '/docs/api-routes'
107
- ```
108
-
109
- ### Link Props
110
-
111
- | Prop | Type | Default | Description |
112
- |------|------|---------|-------------|
113
- | `href` | `string` | required | Target URL path |
114
- | `prefetch` | `boolean` | `false` | Prefetch target on hover |
115
- | `replace` | `boolean` | `false` | Replace history entry |
116
- | `scroll` | `boolean` | `true` | Scroll to top on navigate |
117
- | `target` | `string` | - | Link target (_blank, etc) |
118
- | `className` | `string` | - | CSS class |
119
-
120
- ## SSR Support
121
-
122
- The router is SSR-safe. Pass the initial path from your server:
123
-
124
- ```tsx
125
- // entry-server.tsx
126
- export function render(url: string) {
127
- return renderToString(
128
- <RouterProvider initialPath={url}>
129
- <App />
130
- </RouterProvider>
131
- );
132
- }
133
- ```
134
-
135
- ## License
136
-
137
- MIT
1
+ # @flight-framework/router
2
+
3
+ Universal client-side routing primitives for Flight Framework. Zero external dependencies. Works with any UI framework.
4
+
5
+ ## Features
6
+
7
+ - Multiple prefetch strategies (none, intent, render, viewport)
8
+ - SSR-safe implementation
9
+ - Framework-agnostic with React adapters
10
+ - TypeScript-first design
11
+ - IntersectionObserver for viewport prefetching
12
+ - Backwards compatible API
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @flight-framework/router
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ### With React
23
+
24
+ ```tsx
25
+ import { RouterProvider, Link, useRouter } from '@flight-framework/router';
26
+
27
+ function App() {
28
+ return (
29
+ <RouterProvider initialPath={url}>
30
+ <Navigation />
31
+ <Content />
32
+ </RouterProvider>
33
+ );
34
+ }
35
+
36
+ function Navigation() {
37
+ return (
38
+ <nav>
39
+ <Link href="/">Home</Link>
40
+ <Link href="/docs" prefetch="intent">Docs</Link>
41
+ <Link href="/about">About</Link>
42
+ </nav>
43
+ );
44
+ }
45
+
46
+ function Content() {
47
+ const { path, navigate } = useRouter();
48
+
49
+ return (
50
+ <main>
51
+ <p>Current path: {path}</p>
52
+ <button onClick={() => navigate('/dashboard')}>
53
+ Go to Dashboard
54
+ </button>
55
+ </main>
56
+ );
57
+ }
58
+ ```
59
+
60
+ ## Prefetch Strategies
61
+
62
+ Flight Router supports multiple prefetch strategies to optimize navigation performance:
63
+
64
+ | Strategy | Behavior | Best For |
65
+ |----------|----------|----------|
66
+ | `'none'` | No prefetching (default) | Low-priority links |
67
+ | `'intent'` | Prefetch on hover/focus | Most navigation links |
68
+ | `'render'` | Prefetch immediately | Critical paths (checkout) |
69
+ | `'viewport'` | Prefetch when visible | Mobile, infinite scroll |
70
+
71
+ ### Usage Examples
72
+
73
+ ```tsx
74
+ // No prefetching (default)
75
+ <Link href="/docs">Docs</Link>
76
+ <Link href="/docs" prefetch="none">Docs</Link>
77
+
78
+ // Prefetch on hover/focus (recommended for most cases)
79
+ <Link href="/docs" prefetch="intent">Docs</Link>
80
+ <Link href="/docs" prefetch>Docs</Link> // boolean true = "intent"
81
+
82
+ // Prefetch immediately when link renders
83
+ <Link href="/checkout" prefetch="render">Checkout</Link>
84
+
85
+ // Prefetch when link enters viewport (good for mobile)
86
+ <Link href="/products" prefetch="viewport">Products</Link>
87
+ ```
88
+
89
+ ## Programmatic Prefetching
90
+
91
+ ```typescript
92
+ import {
93
+ prefetch,
94
+ prefetchAll,
95
+ prefetchWhenIdle,
96
+ isPrefetched,
97
+ } from '@flight-framework/router';
98
+
99
+ // Basic prefetch
100
+ prefetch('/docs');
101
+
102
+ // High priority prefetch
103
+ prefetch('/checkout', { priority: 'high' });
104
+
105
+ // Prefetch with data loaders
106
+ prefetch('/products', { includeData: true });
107
+
108
+ // Prefetch multiple pages
109
+ prefetchAll(['/page1', '/page2', '/page3']);
110
+
111
+ // Prefetch when browser is idle
112
+ prefetchWhenIdle('/dashboard');
113
+
114
+ // Check if already prefetched
115
+ if (!isPrefetched('/docs')) {
116
+ prefetch('/docs');
117
+ }
118
+ ```
119
+
120
+ ## PrefetchPageLinks Component
121
+
122
+ For proactive prefetching based on user behavior (search results, autocomplete):
123
+
124
+ ```tsx
125
+ import { PrefetchPageLinks } from '@flight-framework/router';
126
+
127
+ function SearchResults({ results }) {
128
+ return (
129
+ <>
130
+ {results.map(result => (
131
+ <div key={result.id}>
132
+ {/* Prefetch as soon as result renders */}
133
+ <PrefetchPageLinks page={result.url} />
134
+ <Link href={result.url}>{result.title}</Link>
135
+ </div>
136
+ ))}
137
+ </>
138
+ );
139
+ }
140
+ ```
141
+
142
+ ## Hooks
143
+
144
+ ```tsx
145
+ // Get current path and navigation functions
146
+ const { path, searchParams, navigate, back, forward } = useRouter();
147
+
148
+ // Get route parameters (from dynamic routes like [slug])
149
+ const { slug } = useParams<{ slug: string }>();
150
+
151
+ // Get and set search params
152
+ const [searchParams, setSearchParams] = useSearchParams();
153
+
154
+ // Get current pathname
155
+ const pathname = usePathname();
156
+ ```
157
+
158
+ ## Programmatic Navigation
159
+
160
+ ```typescript
161
+ import { navigate, prefetch } from '@flight-framework/router';
162
+
163
+ // Navigate to a path
164
+ navigate('/docs');
165
+
166
+ // Replace history instead of push
167
+ navigate('/login', { replace: true });
168
+
169
+ // Navigate without scrolling to top
170
+ navigate('/next-page', { scroll: false });
171
+
172
+ // Pass state data
173
+ navigate('/dashboard', { state: { from: '/login' } });
174
+ ```
175
+
176
+ ## Route Matching
177
+
178
+ ```typescript
179
+ import { matchRoute, parseParams, generatePath } from '@flight-framework/router';
180
+
181
+ // Check if a path matches a pattern
182
+ const { matched, params } = matchRoute('/docs/routing', '/docs/:slug');
183
+ // matched: true, params: { slug: 'routing' }
184
+
185
+ // Parse params from a path
186
+ const params = parseParams('/blog/2024/my-post', '/blog/:year/:slug');
187
+ // { year: '2024', slug: 'my-post' }
188
+
189
+ // Generate a path from pattern and params
190
+ const path = generatePath('/docs/:slug', { slug: 'api-routes' });
191
+ // '/docs/api-routes'
192
+ ```
193
+
194
+ ## Link Props
195
+
196
+ | Prop | Type | Default | Description |
197
+ |------|------|---------|-------------|
198
+ | `href` | `string` | required | Target URL path |
199
+ | `prefetch` | `boolean \| PrefetchStrategy` | `'none'` | Prefetch strategy |
200
+ | `replace` | `boolean` | `false` | Replace history entry |
201
+ | `scroll` | `boolean` | `true` | Scroll to top on navigate |
202
+ | `target` | `string` | - | Link target (_blank, etc) |
203
+ | `className` | `string` | - | CSS class |
204
+ | `aria-label` | `string` | - | Accessibility label |
205
+
206
+ ## Vue Integration
207
+
208
+ ```vue
209
+ <script setup>
210
+ import { useLinkProps } from '@flight-framework/router';
211
+
212
+ const docsLink = useLinkProps('/docs', { prefetch: 'intent' });
213
+ </script>
214
+
215
+ <template>
216
+ <a v-bind="docsLink">Documentation</a>
217
+ </template>
218
+ ```
219
+
220
+ ## Vanilla JavaScript
221
+
222
+ ```typescript
223
+ import { createLink, prefetch } from '@flight-framework/router';
224
+
225
+ const link = createLink({
226
+ href: '/docs',
227
+ children: 'Documentation',
228
+ prefetch: 'intent',
229
+ });
230
+
231
+ document.body.appendChild(link);
232
+ ```
233
+
234
+ ## SSR Support
235
+
236
+ The router is SSR-safe. Pass the initial path from your server:
237
+
238
+ ```tsx
239
+ // entry-server.tsx
240
+ export function render(url: string) {
241
+ return renderToString(
242
+ <RouterProvider initialPath={url}>
243
+ <App />
244
+ </RouterProvider>
245
+ );
246
+ }
247
+ ```
248
+
249
+ ## Build Integration
250
+
251
+ For optimal prefetching, Flight generates a route manifest during build that maps routes to their JS modules. This enables `prefetch` to preload the correct chunks.
252
+
253
+ ```typescript
254
+ // flight.config.ts
255
+ export default defineConfig({
256
+ router: {
257
+ // Generates __FLIGHT_MANIFEST__ at build time
258
+ generateManifest: true,
259
+ },
260
+ });
261
+ ```
262
+
263
+ ## Browser Support
264
+
265
+ | Feature | Chrome | Firefox | Safari | Edge |
266
+ |---------|--------|---------|--------|------|
267
+ | Prefetch | All | All | All | All |
268
+ | Viewport (IntersectionObserver) | 51+ | 55+ | 12.1+ | 15+ |
269
+ | fetchPriority | 101+ | No | No | 101+ |
270
+
271
+ ## License
272
+
273
+ MIT