@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/dist/index.js
CHANGED
|
@@ -104,26 +104,192 @@ if (typeof globalThis !== "undefined") {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
// src/
|
|
107
|
+
// src/prefetch.ts
|
|
108
108
|
var isBrowser2 = typeof window !== "undefined";
|
|
109
|
+
var supportsIntersectionObserver = isBrowser2 && "IntersectionObserver" in window;
|
|
110
|
+
var prefetchedUrls = /* @__PURE__ */ new Set();
|
|
111
|
+
var prefetchingUrls = /* @__PURE__ */ new Set();
|
|
112
|
+
var viewportObservers = /* @__PURE__ */ new Map();
|
|
113
|
+
function prefetch(href, options = {}) {
|
|
114
|
+
if (!isBrowser2) return;
|
|
115
|
+
const {
|
|
116
|
+
priority = "auto",
|
|
117
|
+
includeModules = true,
|
|
118
|
+
includeData = false
|
|
119
|
+
} = options;
|
|
120
|
+
const url = normalizeUrl(href);
|
|
121
|
+
if (prefetchedUrls.has(url) || prefetchingUrls.has(url)) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
prefetchingUrls.add(url);
|
|
125
|
+
createPrefetchLink(url, "document", priority);
|
|
126
|
+
if (includeModules) {
|
|
127
|
+
prefetchModules(url, priority);
|
|
128
|
+
}
|
|
129
|
+
if (includeData) {
|
|
130
|
+
prefetchData(url, priority);
|
|
131
|
+
}
|
|
132
|
+
prefetchedUrls.add(url);
|
|
133
|
+
prefetchingUrls.delete(url);
|
|
134
|
+
}
|
|
135
|
+
function prefetchAll(hrefs, options = {}) {
|
|
136
|
+
for (const href of hrefs) {
|
|
137
|
+
prefetch(href, options);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function isPrefetched(href) {
|
|
141
|
+
return prefetchedUrls.has(normalizeUrl(href));
|
|
142
|
+
}
|
|
143
|
+
function clearPrefetchCache() {
|
|
144
|
+
prefetchedUrls.clear();
|
|
145
|
+
prefetchingUrls.clear();
|
|
146
|
+
}
|
|
147
|
+
function createPrefetchLink(href, as, priority) {
|
|
148
|
+
if (!isBrowser2) return null;
|
|
149
|
+
const existing = document.querySelector(
|
|
150
|
+
`link[rel="prefetch"][href="${href}"], link[rel="modulepreload"][href="${href}"]`
|
|
151
|
+
);
|
|
152
|
+
if (existing) return existing;
|
|
153
|
+
const link = document.createElement("link");
|
|
154
|
+
if (as === "script") {
|
|
155
|
+
link.rel = "modulepreload";
|
|
156
|
+
} else {
|
|
157
|
+
link.rel = "prefetch";
|
|
158
|
+
link.as = as;
|
|
159
|
+
}
|
|
160
|
+
link.href = href;
|
|
161
|
+
if (priority !== "auto" && "fetchPriority" in link) {
|
|
162
|
+
link.fetchPriority = priority;
|
|
163
|
+
}
|
|
164
|
+
if (priority === "low" && "requestIdleCallback" in window) {
|
|
165
|
+
window.requestIdleCallback(() => {
|
|
166
|
+
document.head.appendChild(link);
|
|
167
|
+
});
|
|
168
|
+
} else {
|
|
169
|
+
document.head.appendChild(link);
|
|
170
|
+
}
|
|
171
|
+
return link;
|
|
172
|
+
}
|
|
173
|
+
function prefetchModules(href, priority) {
|
|
174
|
+
const manifest = window.__FLIGHT_MANIFEST__;
|
|
175
|
+
if (!manifest?.routes) return;
|
|
176
|
+
const routeModules = manifest.routes[href];
|
|
177
|
+
if (!routeModules) return;
|
|
178
|
+
for (const module of routeModules) {
|
|
179
|
+
createPrefetchLink(module, "script", priority);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function prefetchData(href, priority) {
|
|
183
|
+
const dataUrl = `/_flight/data${href === "/" ? "/index" : href}.json`;
|
|
184
|
+
createPrefetchLink(dataUrl, "fetch", priority);
|
|
185
|
+
}
|
|
186
|
+
var sharedObserver = null;
|
|
187
|
+
var observerCallbacks = /* @__PURE__ */ new Map();
|
|
188
|
+
function getViewportObserver() {
|
|
189
|
+
if (!supportsIntersectionObserver) return null;
|
|
190
|
+
if (!sharedObserver) {
|
|
191
|
+
sharedObserver = new IntersectionObserver(
|
|
192
|
+
(entries) => {
|
|
193
|
+
for (const entry of entries) {
|
|
194
|
+
if (entry.isIntersecting) {
|
|
195
|
+
const callback = observerCallbacks.get(entry.target);
|
|
196
|
+
if (callback) {
|
|
197
|
+
callback();
|
|
198
|
+
sharedObserver?.unobserve(entry.target);
|
|
199
|
+
observerCallbacks.delete(entry.target);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
// Start prefetching when link is 25% visible or within 100px of viewport
|
|
206
|
+
rootMargin: "100px",
|
|
207
|
+
threshold: 0.25
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
return sharedObserver;
|
|
212
|
+
}
|
|
213
|
+
function observeForPrefetch(element, href) {
|
|
214
|
+
if (!supportsIntersectionObserver) {
|
|
215
|
+
return () => {
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
const observer = getViewportObserver();
|
|
219
|
+
if (!observer) return () => {
|
|
220
|
+
};
|
|
221
|
+
const callback = () => {
|
|
222
|
+
prefetch(href, { priority: "low" });
|
|
223
|
+
};
|
|
224
|
+
observerCallbacks.set(element, callback);
|
|
225
|
+
observer.observe(element);
|
|
226
|
+
const cleanup = () => {
|
|
227
|
+
observer.unobserve(element);
|
|
228
|
+
observerCallbacks.delete(element);
|
|
229
|
+
viewportObservers.delete(element);
|
|
230
|
+
};
|
|
231
|
+
viewportObservers.set(element, cleanup);
|
|
232
|
+
return cleanup;
|
|
233
|
+
}
|
|
234
|
+
function setupIntentPrefetch(element, href) {
|
|
235
|
+
if (!isBrowser2) return () => {
|
|
236
|
+
};
|
|
237
|
+
let prefetchTriggered = false;
|
|
238
|
+
const handleIntent = () => {
|
|
239
|
+
if (!prefetchTriggered) {
|
|
240
|
+
prefetchTriggered = true;
|
|
241
|
+
prefetch(href, { priority: "auto" });
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
element.addEventListener("mouseenter", handleIntent, { passive: true });
|
|
245
|
+
element.addEventListener("focus", handleIntent, { passive: true });
|
|
246
|
+
element.addEventListener("touchstart", handleIntent, { passive: true });
|
|
247
|
+
return () => {
|
|
248
|
+
element.removeEventListener("mouseenter", handleIntent);
|
|
249
|
+
element.removeEventListener("focus", handleIntent);
|
|
250
|
+
element.removeEventListener("touchstart", handleIntent);
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function normalizeUrl(href) {
|
|
254
|
+
if (isBrowser2 && !href.startsWith("http")) {
|
|
255
|
+
try {
|
|
256
|
+
const url = new URL(href, window.location.origin);
|
|
257
|
+
return url.pathname + url.search;
|
|
258
|
+
} catch {
|
|
259
|
+
return href;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return href;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// src/link.ts
|
|
266
|
+
var isBrowser3 = typeof window !== "undefined";
|
|
109
267
|
function handleLinkClick(href, options, event) {
|
|
110
268
|
if (event && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {
|
|
111
269
|
return;
|
|
112
270
|
}
|
|
271
|
+
if (event && event.button !== 0) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
113
274
|
event?.preventDefault();
|
|
114
275
|
const { navigate: navigate2 } = getRouterContext();
|
|
115
276
|
navigate2(href, options);
|
|
116
277
|
}
|
|
117
278
|
function isExternalUrl(href) {
|
|
118
279
|
if (!href) return false;
|
|
119
|
-
return href.startsWith("http://") || href.startsWith("https://") || href.startsWith("//") || href.startsWith("mailto:") || href.startsWith("tel:");
|
|
280
|
+
return href.startsWith("http://") || href.startsWith("https://") || href.startsWith("//") || href.startsWith("mailto:") || href.startsWith("tel:") || href.startsWith("javascript:") || href.startsWith("#");
|
|
281
|
+
}
|
|
282
|
+
function normalizePrefetchStrategy(prefetchProp) {
|
|
283
|
+
if (prefetchProp === true) {
|
|
284
|
+
return "intent";
|
|
285
|
+
}
|
|
286
|
+
if (prefetchProp === false || prefetchProp === void 0) {
|
|
287
|
+
return "none";
|
|
288
|
+
}
|
|
289
|
+
return prefetchProp;
|
|
120
290
|
}
|
|
121
291
|
function prefetchRoute(href) {
|
|
122
|
-
|
|
123
|
-
const link = document.createElement("link");
|
|
124
|
-
link.rel = "prefetch";
|
|
125
|
-
link.href = href;
|
|
126
|
-
document.head.appendChild(link);
|
|
292
|
+
prefetch(href);
|
|
127
293
|
}
|
|
128
294
|
var Link = null;
|
|
129
295
|
if (typeof globalThis !== "undefined") {
|
|
@@ -137,58 +303,196 @@ if (typeof globalThis !== "undefined") {
|
|
|
137
303
|
className,
|
|
138
304
|
target,
|
|
139
305
|
rel,
|
|
140
|
-
prefetch:
|
|
306
|
+
prefetch: prefetchProp = "none",
|
|
141
307
|
replace = false,
|
|
142
308
|
scroll = true,
|
|
143
309
|
onClick,
|
|
310
|
+
"aria-label": ariaLabel,
|
|
144
311
|
...props
|
|
145
312
|
}) {
|
|
146
313
|
const linkRef = useRef(null);
|
|
147
314
|
const isExternal = isExternalUrl(href);
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
315
|
+
const prefetchStrategy = normalizePrefetchStrategy(prefetchProp);
|
|
316
|
+
const handleClick = useCallback(
|
|
317
|
+
(e) => {
|
|
318
|
+
if (onClick) {
|
|
319
|
+
onClick(e);
|
|
320
|
+
if (e.defaultPrevented) return;
|
|
321
|
+
}
|
|
322
|
+
if (isExternal || target === "_blank") return;
|
|
323
|
+
handleLinkClick(href, { replace, scroll }, e);
|
|
324
|
+
},
|
|
325
|
+
[href, isExternal, target, replace, scroll, onClick]
|
|
326
|
+
);
|
|
156
327
|
useEffect(() => {
|
|
157
|
-
if (
|
|
328
|
+
if (isExternal || !isBrowser3 || prefetchStrategy === "none") {
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
158
331
|
const link = linkRef.current;
|
|
159
332
|
if (!link) return;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
link.removeEventListener("focus", doPrefetch);
|
|
172
|
-
};
|
|
173
|
-
}, [href, prefetch2, isExternal]);
|
|
333
|
+
switch (prefetchStrategy) {
|
|
334
|
+
case "render":
|
|
335
|
+
prefetch(href, { priority: "low" });
|
|
336
|
+
break;
|
|
337
|
+
case "viewport":
|
|
338
|
+
return observeForPrefetch(link, href);
|
|
339
|
+
case "intent":
|
|
340
|
+
default:
|
|
341
|
+
return setupIntentPrefetch(link, href);
|
|
342
|
+
}
|
|
343
|
+
}, [href, prefetchStrategy, isExternal]);
|
|
174
344
|
const computedRel = isExternal && target === "_blank" ? rel || "noopener noreferrer" : rel;
|
|
175
|
-
return React.createElement(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
345
|
+
return React.createElement(
|
|
346
|
+
"a",
|
|
347
|
+
{
|
|
348
|
+
ref: linkRef,
|
|
349
|
+
href,
|
|
350
|
+
className,
|
|
351
|
+
target,
|
|
352
|
+
rel: computedRel,
|
|
353
|
+
"aria-label": ariaLabel,
|
|
354
|
+
onClick: handleClick,
|
|
355
|
+
...props
|
|
356
|
+
},
|
|
357
|
+
children
|
|
358
|
+
);
|
|
184
359
|
};
|
|
185
360
|
}
|
|
186
361
|
} catch {
|
|
187
362
|
}
|
|
188
363
|
}
|
|
364
|
+
function createLink(props) {
|
|
365
|
+
const {
|
|
366
|
+
href,
|
|
367
|
+
children,
|
|
368
|
+
className,
|
|
369
|
+
target,
|
|
370
|
+
rel,
|
|
371
|
+
prefetch: prefetchProp = "none",
|
|
372
|
+
replace = false,
|
|
373
|
+
scroll = true
|
|
374
|
+
} = props;
|
|
375
|
+
const anchor = document.createElement("a");
|
|
376
|
+
anchor.href = href;
|
|
377
|
+
anchor.className = className || "";
|
|
378
|
+
if (target) anchor.target = target;
|
|
379
|
+
if (rel) anchor.rel = rel;
|
|
380
|
+
if (typeof children === "string") {
|
|
381
|
+
anchor.textContent = children;
|
|
382
|
+
}
|
|
383
|
+
const isExternal = isExternalUrl(href);
|
|
384
|
+
const prefetchStrategy = normalizePrefetchStrategy(prefetchProp);
|
|
385
|
+
if (!isExternal && target !== "_blank") {
|
|
386
|
+
anchor.addEventListener("click", (e) => {
|
|
387
|
+
handleLinkClick(href, { replace, scroll }, e);
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
if (!isExternal && prefetchStrategy !== "none") {
|
|
391
|
+
switch (prefetchStrategy) {
|
|
392
|
+
case "render":
|
|
393
|
+
prefetch(href, { priority: "low" });
|
|
394
|
+
break;
|
|
395
|
+
case "viewport":
|
|
396
|
+
observeForPrefetch(anchor, href);
|
|
397
|
+
break;
|
|
398
|
+
case "intent":
|
|
399
|
+
default:
|
|
400
|
+
setupIntentPrefetch(anchor, href);
|
|
401
|
+
break;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return anchor;
|
|
405
|
+
}
|
|
406
|
+
function useLinkProps(href, options = {}) {
|
|
407
|
+
const { replace = false, scroll = true, prefetch: prefetchProp = "none" } = options;
|
|
408
|
+
const isExternal = isExternalUrl(href);
|
|
409
|
+
const prefetchStrategy = normalizePrefetchStrategy(prefetchProp);
|
|
410
|
+
const result = {
|
|
411
|
+
href,
|
|
412
|
+
onClick: (e) => {
|
|
413
|
+
if (!isExternal) {
|
|
414
|
+
handleLinkClick(href, { replace, scroll }, e);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
if (prefetchStrategy === "intent" && !isExternal) {
|
|
419
|
+
let prefetched = false;
|
|
420
|
+
const doPrefetch = () => {
|
|
421
|
+
if (!prefetched) {
|
|
422
|
+
prefetched = true;
|
|
423
|
+
prefetch(href);
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
result.onMouseenter = doPrefetch;
|
|
427
|
+
result.onFocus = doPrefetch;
|
|
428
|
+
}
|
|
429
|
+
if (prefetchStrategy === "render" && !isExternal && isBrowser3) {
|
|
430
|
+
prefetch(href, { priority: "low" });
|
|
431
|
+
}
|
|
432
|
+
return result;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// src/prefetch-links.ts
|
|
436
|
+
var isBrowser4 = typeof window !== "undefined";
|
|
437
|
+
var PrefetchPageLinks = null;
|
|
438
|
+
if (typeof globalThis !== "undefined") {
|
|
439
|
+
try {
|
|
440
|
+
const React = globalThis.React;
|
|
441
|
+
if (React?.createElement && "useEffect" in React) {
|
|
442
|
+
const { useEffect, useState } = React;
|
|
443
|
+
PrefetchPageLinks = function FlightPrefetchPageLinks({
|
|
444
|
+
page,
|
|
445
|
+
options = {}
|
|
446
|
+
}) {
|
|
447
|
+
const [shouldRender, setShouldRender] = useState(false);
|
|
448
|
+
useEffect(() => {
|
|
449
|
+
if (!isBrowser4) return;
|
|
450
|
+
if (isPrefetched(page)) {
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
prefetch(page, {
|
|
454
|
+
priority: "low",
|
|
455
|
+
includeModules: true,
|
|
456
|
+
...options
|
|
457
|
+
});
|
|
458
|
+
setShouldRender(false);
|
|
459
|
+
}, [page, options]);
|
|
460
|
+
return null;
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
} catch {
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
function prefetchPages(pages, options = {}) {
|
|
467
|
+
if (!isBrowser4) return;
|
|
468
|
+
for (const page of pages) {
|
|
469
|
+
if (!isPrefetched(page)) {
|
|
470
|
+
prefetch(page, {
|
|
471
|
+
priority: "low",
|
|
472
|
+
...options
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
function prefetchWhenIdle(page, options = {}) {
|
|
478
|
+
if (!isBrowser4) return;
|
|
479
|
+
const doPrefetch = () => {
|
|
480
|
+
if (!isPrefetched(page)) {
|
|
481
|
+
prefetch(page, {
|
|
482
|
+
priority: "low",
|
|
483
|
+
...options
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
if ("requestIdleCallback" in window) {
|
|
488
|
+
window.requestIdleCallback(doPrefetch, { timeout: 3e3 });
|
|
489
|
+
} else {
|
|
490
|
+
setTimeout(doPrefetch, 100);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
189
493
|
|
|
190
494
|
// src/hooks.ts
|
|
191
|
-
var
|
|
495
|
+
var isBrowser5 = typeof window !== "undefined";
|
|
192
496
|
var useParams = () => ({});
|
|
193
497
|
var useSearchParams = () => [new URLSearchParams(), () => {
|
|
194
498
|
}];
|
|
@@ -210,10 +514,10 @@ if (typeof globalThis !== "undefined") {
|
|
|
210
514
|
};
|
|
211
515
|
useSearchParams = function useFlightSearchParams() {
|
|
212
516
|
const [searchParams, setSearchParamsState] = useState(
|
|
213
|
-
() =>
|
|
517
|
+
() => isBrowser5 ? new URLSearchParams(window.location.search) : new URLSearchParams()
|
|
214
518
|
);
|
|
215
519
|
useEffect(() => {
|
|
216
|
-
if (!
|
|
520
|
+
if (!isBrowser5) return;
|
|
217
521
|
const handleChange = () => {
|
|
218
522
|
setSearchParamsState(new URLSearchParams(window.location.search));
|
|
219
523
|
};
|
|
@@ -221,7 +525,7 @@ if (typeof globalThis !== "undefined") {
|
|
|
221
525
|
return () => window.removeEventListener("popstate", handleChange);
|
|
222
526
|
}, []);
|
|
223
527
|
const setSearchParams = useCallback((newParams) => {
|
|
224
|
-
if (!
|
|
528
|
+
if (!isBrowser5) return;
|
|
225
529
|
let params;
|
|
226
530
|
if (newParams instanceof URLSearchParams) {
|
|
227
531
|
params = newParams;
|
|
@@ -245,7 +549,7 @@ if (typeof globalThis !== "undefined") {
|
|
|
245
549
|
const { path } = getRouterContext();
|
|
246
550
|
const [pathname, setPathname] = useState(path);
|
|
247
551
|
useEffect(() => {
|
|
248
|
-
if (!
|
|
552
|
+
if (!isBrowser5) return;
|
|
249
553
|
const handleChange = () => {
|
|
250
554
|
setPathname(window.location.pathname);
|
|
251
555
|
};
|
|
@@ -260,20 +564,11 @@ if (typeof globalThis !== "undefined") {
|
|
|
260
564
|
}
|
|
261
565
|
|
|
262
566
|
// src/navigate.ts
|
|
263
|
-
var
|
|
567
|
+
var isBrowser6 = typeof window !== "undefined";
|
|
264
568
|
function navigate(to, options = {}) {
|
|
265
569
|
const { navigate: routerNavigate } = getRouterContext();
|
|
266
570
|
routerNavigate(to, options);
|
|
267
571
|
}
|
|
268
|
-
function prefetch(href) {
|
|
269
|
-
if (!isBrowser4) return;
|
|
270
|
-
const existing = document.querySelector(`link[rel="prefetch"][href="${href}"]`);
|
|
271
|
-
if (existing) return;
|
|
272
|
-
const link = document.createElement("link");
|
|
273
|
-
link.rel = "prefetch";
|
|
274
|
-
link.href = href;
|
|
275
|
-
document.head.appendChild(link);
|
|
276
|
-
}
|
|
277
572
|
function patternToRegex(pattern) {
|
|
278
573
|
const paramNames = [];
|
|
279
574
|
let regexStr = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\\\[\.\.\.(\w+)\\\]/g, (_, name) => {
|
|
@@ -308,14 +603,63 @@ function parseParams(pathname, pattern) {
|
|
|
308
603
|
const { params } = matchRoute(pathname, pattern);
|
|
309
604
|
return params;
|
|
310
605
|
}
|
|
606
|
+
function findRoute(pathname, routes) {
|
|
607
|
+
for (const route of routes) {
|
|
608
|
+
const { matched, params } = matchRoute(pathname, route.path);
|
|
609
|
+
if (matched) {
|
|
610
|
+
return {
|
|
611
|
+
route,
|
|
612
|
+
params,
|
|
613
|
+
pathname
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
return null;
|
|
618
|
+
}
|
|
619
|
+
function generatePath(pattern, params = {}) {
|
|
620
|
+
let path = pattern;
|
|
621
|
+
path = path.replace(/\[(\w+)\]/g, (_, name) => {
|
|
622
|
+
return params[name] || "";
|
|
623
|
+
});
|
|
624
|
+
path = path.replace(/:(\w+)/g, (_, name) => {
|
|
625
|
+
return params[name] || "";
|
|
626
|
+
});
|
|
627
|
+
return path;
|
|
628
|
+
}
|
|
629
|
+
function isActive(pattern) {
|
|
630
|
+
const { path } = getRouterContext();
|
|
631
|
+
const { matched } = matchRoute(path, pattern);
|
|
632
|
+
return matched;
|
|
633
|
+
}
|
|
634
|
+
function redirect(url) {
|
|
635
|
+
if (isBrowser6) {
|
|
636
|
+
window.location.href = url;
|
|
637
|
+
}
|
|
638
|
+
throw new Error(`Redirect to: ${url}`);
|
|
639
|
+
}
|
|
311
640
|
export {
|
|
312
641
|
Link,
|
|
642
|
+
PrefetchPageLinks,
|
|
313
643
|
RouterContext,
|
|
314
644
|
RouterProvider,
|
|
645
|
+
clearPrefetchCache,
|
|
646
|
+
createLink,
|
|
647
|
+
findRoute,
|
|
648
|
+
generatePath,
|
|
649
|
+
isActive,
|
|
650
|
+
isPrefetched,
|
|
315
651
|
matchRoute,
|
|
316
652
|
navigate,
|
|
653
|
+
observeForPrefetch,
|
|
317
654
|
parseParams,
|
|
318
655
|
prefetch,
|
|
656
|
+
prefetchAll,
|
|
657
|
+
prefetchPages,
|
|
658
|
+
prefetchRoute,
|
|
659
|
+
prefetchWhenIdle,
|
|
660
|
+
redirect,
|
|
661
|
+
setupIntentPrefetch,
|
|
662
|
+
useLinkProps,
|
|
319
663
|
useParams,
|
|
320
664
|
usePathname,
|
|
321
665
|
useRouter,
|
package/package.json
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
{
|
|
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
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@flight-framework/router",
|
|
3
|
+
"version": "0.0.4",
|
|
4
|
+
"description": "Agnostic client-side routing primitives for Flight Framework",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
20
|
+
"dev": "tsup src/index.ts --format esm --dts --watch"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"flight",
|
|
24
|
+
"router",
|
|
25
|
+
"spa",
|
|
26
|
+
"navigation",
|
|
27
|
+
"ssr"
|
|
28
|
+
],
|
|
29
|
+
"author": "Flight Framework",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/EliosLT/Flight-framework",
|
|
34
|
+
"directory": "packages/router"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"tsup": "^8.0.0",
|
|
38
|
+
"typescript": "^5.3.0"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"react": ">=18.0.0"
|
|
42
|
+
},
|
|
43
|
+
"peerDependenciesMeta": {
|
|
44
|
+
"react": {
|
|
45
|
+
"optional": true
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024-2026 Flight Contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|