@flight-framework/router 0.0.2 → 0.0.4
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 +488 -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,488 @@
|
|
|
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
|
-
|
|
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
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Features](#features)
|
|
8
|
+
- [Installation](#installation)
|
|
9
|
+
- [Quick Start](#quick-start)
|
|
10
|
+
- [Prefetch Strategies](#prefetch-strategies)
|
|
11
|
+
- [Smart Prefetching](#smart-prefetching)
|
|
12
|
+
- [Intercepting Routes](#intercepting-routes)
|
|
13
|
+
- [Programmatic Prefetching](#programmatic-prefetching)
|
|
14
|
+
- [Prefetch Queue](#prefetch-queue)
|
|
15
|
+
- [React Hooks](#react-hooks)
|
|
16
|
+
- [Programmatic Navigation](#programmatic-navigation)
|
|
17
|
+
- [Route Matching](#route-matching)
|
|
18
|
+
- [Link Component](#link-component)
|
|
19
|
+
- [Framework Integration](#framework-integration)
|
|
20
|
+
- [SSR Support](#ssr-support)
|
|
21
|
+
- [Browser Support](#browser-support)
|
|
22
|
+
- [License](#license)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
- Multiple prefetch strategies (none, intent, render, viewport, idle)
|
|
29
|
+
- Network-aware smart prefetching (respects Save-Data and connection speed)
|
|
30
|
+
- Intercepting routes with modal support
|
|
31
|
+
- Prefetch queue with concurrency control
|
|
32
|
+
- SSR-safe implementation
|
|
33
|
+
- Framework-agnostic with React adapters
|
|
34
|
+
- TypeScript-first design
|
|
35
|
+
- IntersectionObserver for viewport prefetching
|
|
36
|
+
- Zero external dependencies
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install @flight-framework/router
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
### With React
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import { RouterProvider, Link, useRouter } from '@flight-framework/router';
|
|
54
|
+
|
|
55
|
+
function App() {
|
|
56
|
+
return (
|
|
57
|
+
<RouterProvider initialPath={url}>
|
|
58
|
+
<Navigation />
|
|
59
|
+
<Content />
|
|
60
|
+
</RouterProvider>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function Navigation() {
|
|
65
|
+
return (
|
|
66
|
+
<nav>
|
|
67
|
+
<Link href="/">Home</Link>
|
|
68
|
+
<Link href="/docs" prefetch="intent">Docs</Link>
|
|
69
|
+
<Link href="/about">About</Link>
|
|
70
|
+
</nav>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function Content() {
|
|
75
|
+
const { path, navigate } = useRouter();
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<main>
|
|
79
|
+
<p>Current path: {path}</p>
|
|
80
|
+
<button onClick={() => navigate('/dashboard')}>
|
|
81
|
+
Go to Dashboard
|
|
82
|
+
</button>
|
|
83
|
+
</main>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Prefetch Strategies
|
|
91
|
+
|
|
92
|
+
Flight Router supports multiple prefetch strategies to optimize navigation performance:
|
|
93
|
+
|
|
94
|
+
| Strategy | Behavior | Best For |
|
|
95
|
+
|----------|----------|----------|
|
|
96
|
+
| `'none'` | No prefetching (default) | Low-priority links |
|
|
97
|
+
| `'intent'` | Prefetch on hover/focus | Most navigation links |
|
|
98
|
+
| `'render'` | Prefetch immediately | Critical paths (checkout) |
|
|
99
|
+
| `'viewport'` | Prefetch when visible | Mobile, infinite scroll |
|
|
100
|
+
| `'idle'` | Prefetch when browser is idle | Background preloading |
|
|
101
|
+
|
|
102
|
+
### Usage Examples
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
// No prefetching (default)
|
|
106
|
+
<Link href="/docs">Docs</Link>
|
|
107
|
+
<Link href="/docs" prefetch="none">Docs</Link>
|
|
108
|
+
|
|
109
|
+
// Prefetch on hover/focus (recommended for most cases)
|
|
110
|
+
<Link href="/docs" prefetch="intent">Docs</Link>
|
|
111
|
+
<Link href="/docs" prefetch>Docs</Link> // boolean true = "intent"
|
|
112
|
+
|
|
113
|
+
// Prefetch immediately when link renders
|
|
114
|
+
<Link href="/checkout" prefetch="render">Checkout</Link>
|
|
115
|
+
|
|
116
|
+
// Prefetch when link enters viewport (good for mobile)
|
|
117
|
+
<Link href="/products" prefetch="viewport">Products</Link>
|
|
118
|
+
|
|
119
|
+
// Prefetch when browser is idle
|
|
120
|
+
<Link href="/settings" prefetch="idle">Settings</Link>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Smart Prefetching
|
|
126
|
+
|
|
127
|
+
Network-aware prefetching that respects user preferences and connection quality.
|
|
128
|
+
|
|
129
|
+
### Features
|
|
130
|
+
|
|
131
|
+
- Respects `Save-Data` header (users on limited data plans)
|
|
132
|
+
- Detects connection type (2G, 3G, 4G)
|
|
133
|
+
- Configurable minimum network requirements
|
|
134
|
+
- Automatic throttling on slow connections
|
|
135
|
+
|
|
136
|
+
### API
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import {
|
|
140
|
+
smartPrefetch,
|
|
141
|
+
shouldSkipPrefetch,
|
|
142
|
+
canPrefetchOnNetwork,
|
|
143
|
+
} from '@flight-framework/router';
|
|
144
|
+
|
|
145
|
+
// Respects network conditions automatically
|
|
146
|
+
smartPrefetch('/dashboard');
|
|
147
|
+
|
|
148
|
+
// Check if prefetching should be skipped
|
|
149
|
+
if (shouldSkipPrefetch()) {
|
|
150
|
+
console.log('Skipping due to network conditions');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Custom network requirements
|
|
154
|
+
const canPrefetch = canPrefetchOnNetwork({
|
|
155
|
+
respectSaveData: true, // Skip if Save-Data enabled
|
|
156
|
+
respectSlowNetwork: true, // Skip on 2G/slow-2G
|
|
157
|
+
minEffectiveType: '3g', // Minimum 3G required
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Configuration
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
smartPrefetch('/page', {
|
|
165
|
+
respectSaveData: true, // Default: true
|
|
166
|
+
respectSlowNetwork: true, // Default: true
|
|
167
|
+
minEffectiveType: '3g', // Default: '3g'
|
|
168
|
+
priority: 'high', // Optional priority override
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Intercepting Routes
|
|
175
|
+
|
|
176
|
+
Render routes in modals while preserving URL state. Perfect for photo galleries, user profiles, and detail views.
|
|
177
|
+
|
|
178
|
+
### React Integration
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
import {
|
|
182
|
+
InterceptedRouteProvider,
|
|
183
|
+
useInterceptedRoute,
|
|
184
|
+
} from '@flight-framework/router';
|
|
185
|
+
|
|
186
|
+
// Wrap your layout
|
|
187
|
+
function RootLayout({ children }) {
|
|
188
|
+
return (
|
|
189
|
+
<InterceptedRouteProvider>
|
|
190
|
+
{children}
|
|
191
|
+
<ModalRenderer />
|
|
192
|
+
</InterceptedRouteProvider>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Render intercepted content in a modal
|
|
197
|
+
function ModalRenderer() {
|
|
198
|
+
const intercepted = useInterceptedRoute();
|
|
199
|
+
|
|
200
|
+
if (!intercepted) return null;
|
|
201
|
+
|
|
202
|
+
return (
|
|
203
|
+
<Dialog open onClose={intercepted.dismiss}>
|
|
204
|
+
<intercepted.Component />
|
|
205
|
+
<button onClick={intercepted.navigateToPage}>
|
|
206
|
+
View Full Page
|
|
207
|
+
</button>
|
|
208
|
+
</Dialog>
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Intercepted Route State
|
|
214
|
+
|
|
215
|
+
| Property | Type | Description |
|
|
216
|
+
|----------|------|-------------|
|
|
217
|
+
| `Component` | `() => unknown` | The component to render |
|
|
218
|
+
| `pathname` | `string` | The intercepted URL path |
|
|
219
|
+
| `params` | `Record<string, string>` | Route parameters |
|
|
220
|
+
| `dismiss()` | `() => void` | Go back (close modal) |
|
|
221
|
+
| `navigateToPage()` | `() => void` | Navigate to actual page |
|
|
222
|
+
|
|
223
|
+
### Additional Hooks
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
import {
|
|
227
|
+
useInterceptedRoute,
|
|
228
|
+
useSetInterceptedRoute,
|
|
229
|
+
useIsIntercepting,
|
|
230
|
+
} from '@flight-framework/router';
|
|
231
|
+
|
|
232
|
+
// Check if currently intercepting
|
|
233
|
+
const isIntercepting = useIsIntercepting();
|
|
234
|
+
|
|
235
|
+
// Programmatically set intercepted state (for router integration)
|
|
236
|
+
const setIntercepted = useSetInterceptedRoute();
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Programmatic Prefetching
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
import {
|
|
245
|
+
prefetch,
|
|
246
|
+
prefetchAll,
|
|
247
|
+
prefetchWhenIdle,
|
|
248
|
+
isPrefetched,
|
|
249
|
+
clearPrefetchCache,
|
|
250
|
+
} from '@flight-framework/router';
|
|
251
|
+
|
|
252
|
+
// Basic prefetch
|
|
253
|
+
prefetch('/docs');
|
|
254
|
+
|
|
255
|
+
// High priority prefetch
|
|
256
|
+
prefetch('/checkout', { priority: 'high' });
|
|
257
|
+
|
|
258
|
+
// Prefetch with data loaders
|
|
259
|
+
prefetch('/products', { includeData: true });
|
|
260
|
+
|
|
261
|
+
// Prefetch multiple pages
|
|
262
|
+
prefetchAll(['/page1', '/page2', '/page3']);
|
|
263
|
+
|
|
264
|
+
// Prefetch when browser is idle
|
|
265
|
+
prefetchWhenIdle('/dashboard');
|
|
266
|
+
|
|
267
|
+
// Check if already prefetched
|
|
268
|
+
if (!isPrefetched('/docs')) {
|
|
269
|
+
prefetch('/docs');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Clear prefetch cache (useful for testing)
|
|
273
|
+
clearPrefetchCache();
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Prefetch Queue
|
|
279
|
+
|
|
280
|
+
Control concurrent prefetch requests to avoid overwhelming the network:
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
import { PrefetchQueue } from '@flight-framework/router';
|
|
284
|
+
|
|
285
|
+
// Create queue with max 3 concurrent prefetches
|
|
286
|
+
const queue = new PrefetchQueue(3);
|
|
287
|
+
|
|
288
|
+
// Add URLs to queue
|
|
289
|
+
queue.add('/page1');
|
|
290
|
+
queue.add('/page2', { priority: 'high' });
|
|
291
|
+
queue.addAll(['/page3', '/page4', '/page5']);
|
|
292
|
+
|
|
293
|
+
// Control queue
|
|
294
|
+
queue.pause(); // Stop processing
|
|
295
|
+
queue.resume(); // Continue processing
|
|
296
|
+
queue.clear(); // Remove pending items
|
|
297
|
+
|
|
298
|
+
// Check state
|
|
299
|
+
console.log(queue.pending); // Items waiting
|
|
300
|
+
console.log(queue.activeCount); // Currently prefetching
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## React Hooks
|
|
306
|
+
|
|
307
|
+
```tsx
|
|
308
|
+
import {
|
|
309
|
+
useRouter,
|
|
310
|
+
useParams,
|
|
311
|
+
useSearchParams,
|
|
312
|
+
usePathname,
|
|
313
|
+
} from '@flight-framework/router';
|
|
314
|
+
|
|
315
|
+
// Get current path and navigation functions
|
|
316
|
+
const { path, searchParams, navigate, back, forward } = useRouter();
|
|
317
|
+
|
|
318
|
+
// Get route parameters (from dynamic routes like [slug])
|
|
319
|
+
const { slug } = useParams<{ slug: string }>();
|
|
320
|
+
|
|
321
|
+
// Get and set search params
|
|
322
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
323
|
+
|
|
324
|
+
// Get current pathname
|
|
325
|
+
const pathname = usePathname();
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## Programmatic Navigation
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
import { navigate, prefetch } from '@flight-framework/router';
|
|
334
|
+
|
|
335
|
+
// Navigate to a path
|
|
336
|
+
navigate('/docs');
|
|
337
|
+
|
|
338
|
+
// Replace history instead of push
|
|
339
|
+
navigate('/login', { replace: true });
|
|
340
|
+
|
|
341
|
+
// Navigate without scrolling to top
|
|
342
|
+
navigate('/next-page', { scroll: false });
|
|
343
|
+
|
|
344
|
+
// Pass state data
|
|
345
|
+
navigate('/dashboard', { state: { from: '/login' } });
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Route Matching
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
import { matchRoute, parseParams, generatePath } from '@flight-framework/router';
|
|
354
|
+
|
|
355
|
+
// Check if a path matches a pattern
|
|
356
|
+
const { matched, params } = matchRoute('/docs/routing', '/docs/:slug');
|
|
357
|
+
// matched: true, params: { slug: 'routing' }
|
|
358
|
+
|
|
359
|
+
// Parse params from a path
|
|
360
|
+
const params = parseParams('/blog/2024/my-post', '/blog/:year/:slug');
|
|
361
|
+
// { year: '2024', slug: 'my-post' }
|
|
362
|
+
|
|
363
|
+
// Generate a path from pattern and params
|
|
364
|
+
const path = generatePath('/docs/:slug', { slug: 'api-routes' });
|
|
365
|
+
// '/docs/api-routes'
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## Link Component
|
|
371
|
+
|
|
372
|
+
### Props
|
|
373
|
+
|
|
374
|
+
| Prop | Type | Default | Description |
|
|
375
|
+
|------|------|---------|-------------|
|
|
376
|
+
| `href` | `string` | required | Target URL path |
|
|
377
|
+
| `prefetch` | `boolean \| PrefetchStrategy` | `'none'` | Prefetch strategy |
|
|
378
|
+
| `replace` | `boolean` | `false` | Replace history entry |
|
|
379
|
+
| `scroll` | `boolean` | `true` | Scroll to top on navigate |
|
|
380
|
+
| `target` | `string` | - | Link target (_blank, etc) |
|
|
381
|
+
| `className` | `string` | - | CSS class |
|
|
382
|
+
| `aria-label` | `string` | - | Accessibility label |
|
|
383
|
+
|
|
384
|
+
### PrefetchPageLinks Component
|
|
385
|
+
|
|
386
|
+
For proactive prefetching based on user behavior:
|
|
387
|
+
|
|
388
|
+
```tsx
|
|
389
|
+
import { PrefetchPageLinks } from '@flight-framework/router';
|
|
390
|
+
|
|
391
|
+
function SearchResults({ results }) {
|
|
392
|
+
return (
|
|
393
|
+
<>
|
|
394
|
+
{results.map(result => (
|
|
395
|
+
<div key={result.id}>
|
|
396
|
+
<PrefetchPageLinks page={result.url} />
|
|
397
|
+
<Link href={result.url}>{result.title}</Link>
|
|
398
|
+
</div>
|
|
399
|
+
))}
|
|
400
|
+
</>
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Framework Integration
|
|
408
|
+
|
|
409
|
+
### Vue
|
|
410
|
+
|
|
411
|
+
```vue
|
|
412
|
+
<script setup>
|
|
413
|
+
import { useLinkProps } from '@flight-framework/router';
|
|
414
|
+
|
|
415
|
+
const docsLink = useLinkProps('/docs', { prefetch: 'intent' });
|
|
416
|
+
</script>
|
|
417
|
+
|
|
418
|
+
<template>
|
|
419
|
+
<a v-bind="docsLink">Documentation</a>
|
|
420
|
+
</template>
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Vanilla JavaScript
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
import { createLink, prefetch } from '@flight-framework/router';
|
|
427
|
+
|
|
428
|
+
const link = createLink({
|
|
429
|
+
href: '/docs',
|
|
430
|
+
children: 'Documentation',
|
|
431
|
+
prefetch: 'intent',
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
document.body.appendChild(link);
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## SSR Support
|
|
440
|
+
|
|
441
|
+
The router is SSR-safe. Pass the initial path from your server:
|
|
442
|
+
|
|
443
|
+
```tsx
|
|
444
|
+
// entry-server.tsx
|
|
445
|
+
export function render(url: string) {
|
|
446
|
+
return renderToString(
|
|
447
|
+
<RouterProvider initialPath={url}>
|
|
448
|
+
<App />
|
|
449
|
+
</RouterProvider>
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
## Browser Support
|
|
457
|
+
|
|
458
|
+
| Feature | Chrome | Firefox | Safari | Edge |
|
|
459
|
+
|---------|--------|---------|--------|------|
|
|
460
|
+
| Prefetch | All | All | All | All |
|
|
461
|
+
| Viewport (IntersectionObserver) | 51+ | 55+ | 12.1+ | 15+ |
|
|
462
|
+
| Network Information API | 61+ | No | No | 79+ |
|
|
463
|
+
| requestIdleCallback | 47+ | 55+ | No | 79+ |
|
|
464
|
+
| fetchPriority | 101+ | No | No | 101+ |
|
|
465
|
+
|
|
466
|
+
Features gracefully degrade when APIs are unavailable.
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
## TypeScript
|
|
471
|
+
|
|
472
|
+
Full TypeScript support with exported types:
|
|
473
|
+
|
|
474
|
+
```typescript
|
|
475
|
+
import type {
|
|
476
|
+
PrefetchStrategy,
|
|
477
|
+
PrefetchOptions,
|
|
478
|
+
SmartPrefetchOptions,
|
|
479
|
+
InterceptedRouteState,
|
|
480
|
+
InterceptedRouteContextValue,
|
|
481
|
+
} from '@flight-framework/router';
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## License
|
|
487
|
+
|
|
488
|
+
MIT
|