@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 +273 -137
- package/dist/index.d.ts +267 -16
- package/dist/index.js +399 -55
- package/package.json +48 -48
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -1,137 +1,273 @@
|
|
|
1
|
-
# @flight-framework/router
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
##
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
```tsx
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|