@fictjs/router 0.4.0 → 0.5.1
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 +1 -1
- package/dist/index.cjs +370 -181
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -8
- package/dist/index.d.ts +15 -8
- package/dist/index.js +360 -175
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
- package/src/accessor-utils.ts +22 -0
- package/src/components.tsx +50 -451
- package/src/context.ts +161 -42
- package/src/lazy.tsx +29 -14
- package/src/link.tsx +58 -17
- package/src/router-internals.ts +33 -0
- package/src/router-provider.ts +388 -0
package/dist/index.cjs
CHANGED
|
@@ -100,11 +100,30 @@ __export(index_exports, {
|
|
|
100
100
|
module.exports = __toCommonJS(index_exports);
|
|
101
101
|
|
|
102
102
|
// src/components.tsx
|
|
103
|
-
var
|
|
104
|
-
var
|
|
103
|
+
var import_runtime3 = require("@fictjs/runtime");
|
|
104
|
+
var import_advanced3 = require("@fictjs/runtime/advanced");
|
|
105
|
+
|
|
106
|
+
// src/accessor-utils.ts
|
|
107
|
+
function wrapAccessor(fn) {
|
|
108
|
+
const wrapped = ((...args) => {
|
|
109
|
+
if (args.length === 0) return wrapped;
|
|
110
|
+
return fn(...args);
|
|
111
|
+
});
|
|
112
|
+
return wrapped;
|
|
113
|
+
}
|
|
114
|
+
function wrapValue(value) {
|
|
115
|
+
const wrapped = (() => value);
|
|
116
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
117
|
+
const primitive = value;
|
|
118
|
+
wrapped.toString = () => String(primitive);
|
|
119
|
+
wrapped.valueOf = () => primitive;
|
|
120
|
+
}
|
|
121
|
+
return wrapped;
|
|
122
|
+
}
|
|
105
123
|
|
|
106
124
|
// src/context.ts
|
|
107
125
|
var import_runtime = require("@fictjs/runtime");
|
|
126
|
+
var import_advanced = require("@fictjs/runtime/advanced");
|
|
108
127
|
|
|
109
128
|
// src/utils.ts
|
|
110
129
|
function normalizePath(path) {
|
|
@@ -433,23 +452,76 @@ function isBrowser() {
|
|
|
433
452
|
}
|
|
434
453
|
|
|
435
454
|
// src/context.ts
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
455
|
+
function readAccessor(value) {
|
|
456
|
+
return typeof value === "function" ? value() : value;
|
|
457
|
+
}
|
|
458
|
+
var activeRouter = (0, import_advanced.createSignal)(null);
|
|
459
|
+
var activeRouterStack = [];
|
|
460
|
+
function pushActiveRouter(router) {
|
|
461
|
+
activeRouterStack.push(router);
|
|
462
|
+
(0, import_runtime.batch)(() => {
|
|
463
|
+
activeRouter(router);
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
function popActiveRouter(router) {
|
|
467
|
+
const index = activeRouterStack.lastIndexOf(router);
|
|
468
|
+
if (index >= 0) {
|
|
469
|
+
activeRouterStack.splice(index, 1);
|
|
470
|
+
}
|
|
471
|
+
(0, import_runtime.batch)(() => {
|
|
472
|
+
activeRouter(activeRouterStack[activeRouterStack.length - 1] ?? null);
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
var defaultLocation = {
|
|
476
|
+
pathname: "/",
|
|
477
|
+
search: "",
|
|
478
|
+
hash: "",
|
|
479
|
+
state: null,
|
|
480
|
+
key: "default"
|
|
481
|
+
};
|
|
482
|
+
var defaultNavigate = wrapAccessor(((toOrDelta) => {
|
|
483
|
+
const router = activeRouter();
|
|
484
|
+
if (!router) {
|
|
447
485
|
console.warn("[fict-router] No router found. Wrap your app in a <Router>");
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
const navigate = readAccessor(router.navigate);
|
|
489
|
+
if (typeof toOrDelta === "number") {
|
|
490
|
+
return navigate(toOrDelta);
|
|
491
|
+
}
|
|
492
|
+
return navigate(toOrDelta);
|
|
493
|
+
}));
|
|
494
|
+
var defaultResolvePath = wrapAccessor((to) => {
|
|
495
|
+
const router = activeRouter();
|
|
496
|
+
if (router) {
|
|
497
|
+
return readAccessor(router.resolvePath)(to);
|
|
498
|
+
}
|
|
499
|
+
return typeof to === "string" ? to : to.pathname || "/";
|
|
500
|
+
});
|
|
501
|
+
var defaultRouterContext = {
|
|
502
|
+
location: () => {
|
|
503
|
+
const router = activeRouter();
|
|
504
|
+
return router ? readAccessor(router.location) : defaultLocation;
|
|
505
|
+
},
|
|
506
|
+
params: () => {
|
|
507
|
+
const router = activeRouter();
|
|
508
|
+
return router ? readAccessor(router.params) : {};
|
|
509
|
+
},
|
|
510
|
+
matches: () => {
|
|
511
|
+
const router = activeRouter();
|
|
512
|
+
return router ? readAccessor(router.matches) : [];
|
|
513
|
+
},
|
|
514
|
+
navigate: defaultNavigate,
|
|
515
|
+
isRouting: () => {
|
|
516
|
+
const router = activeRouter();
|
|
517
|
+
return router ? readAccessor(router.isRouting) : false;
|
|
448
518
|
},
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
519
|
+
pendingLocation: () => {
|
|
520
|
+
const router = activeRouter();
|
|
521
|
+
return router ? readAccessor(router.pendingLocation) : null;
|
|
522
|
+
},
|
|
523
|
+
base: wrapValue(""),
|
|
524
|
+
resolvePath: defaultResolvePath
|
|
453
525
|
};
|
|
454
526
|
var RouterContext = (0, import_runtime.createContext)(defaultRouterContext);
|
|
455
527
|
RouterContext.displayName = "RouterContext";
|
|
@@ -460,17 +532,50 @@ var defaultRouteContext = {
|
|
|
460
532
|
match: () => void 0,
|
|
461
533
|
data: () => void 0,
|
|
462
534
|
outlet: () => null,
|
|
463
|
-
resolvePath: (to) => typeof to === "string" ? to : to.pathname || "/"
|
|
535
|
+
resolvePath: wrapAccessor((to) => typeof to === "string" ? to : to.pathname || "/")
|
|
464
536
|
};
|
|
465
537
|
var RouteContext = (0, import_runtime.createContext)(defaultRouteContext);
|
|
466
538
|
RouteContext.displayName = "RouteContext";
|
|
467
539
|
function useRoute() {
|
|
468
540
|
return (0, import_runtime.useContext)(RouteContext);
|
|
469
541
|
}
|
|
542
|
+
var activeBeforeLeave = (0, import_advanced.createSignal)(null);
|
|
543
|
+
var activeBeforeLeaveStack = [];
|
|
544
|
+
function pushActiveBeforeLeave(context) {
|
|
545
|
+
activeBeforeLeaveStack.push(context);
|
|
546
|
+
(0, import_runtime.batch)(() => {
|
|
547
|
+
activeBeforeLeave(context);
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
function popActiveBeforeLeave(context) {
|
|
551
|
+
const index = activeBeforeLeaveStack.lastIndexOf(context);
|
|
552
|
+
if (index >= 0) {
|
|
553
|
+
activeBeforeLeaveStack.splice(index, 1);
|
|
554
|
+
}
|
|
555
|
+
(0, import_runtime.batch)(() => {
|
|
556
|
+
activeBeforeLeave(activeBeforeLeaveStack[activeBeforeLeaveStack.length - 1] ?? null);
|
|
557
|
+
});
|
|
558
|
+
}
|
|
470
559
|
var defaultBeforeLeaveContext = {
|
|
471
|
-
addHandler: (
|
|
472
|
-
|
|
473
|
-
|
|
560
|
+
addHandler: wrapAccessor((handler) => {
|
|
561
|
+
const context = activeBeforeLeave();
|
|
562
|
+
if (context) {
|
|
563
|
+
return readAccessor(
|
|
564
|
+
context.addHandler
|
|
565
|
+
)(handler);
|
|
566
|
+
}
|
|
567
|
+
return () => {
|
|
568
|
+
};
|
|
569
|
+
}),
|
|
570
|
+
confirm: wrapAccessor((to, from) => {
|
|
571
|
+
const context = activeBeforeLeave();
|
|
572
|
+
if (context) {
|
|
573
|
+
return readAccessor(
|
|
574
|
+
context.confirm
|
|
575
|
+
)(to, from);
|
|
576
|
+
}
|
|
577
|
+
return Promise.resolve(true);
|
|
578
|
+
})
|
|
474
579
|
};
|
|
475
580
|
var BeforeLeaveContext = (0, import_runtime.createContext)(defaultBeforeLeaveContext);
|
|
476
581
|
BeforeLeaveContext.displayName = "BeforeLeaveContext";
|
|
@@ -485,27 +590,28 @@ var RouteErrorContext = (0, import_runtime.createContext)(defaultRouteErrorConte
|
|
|
485
590
|
RouteErrorContext.displayName = "RouteErrorContext";
|
|
486
591
|
function useNavigate() {
|
|
487
592
|
const router = useRouter();
|
|
488
|
-
return router.navigate;
|
|
593
|
+
return readAccessor(router.navigate);
|
|
489
594
|
}
|
|
490
595
|
function useLocation() {
|
|
491
596
|
const router = useRouter();
|
|
492
|
-
return router.location;
|
|
597
|
+
return () => readAccessor(router.location);
|
|
493
598
|
}
|
|
494
599
|
function useParams() {
|
|
495
600
|
const router = useRouter();
|
|
496
|
-
return router.params;
|
|
601
|
+
return () => readAccessor(router.params);
|
|
497
602
|
}
|
|
498
603
|
function useSearchParams() {
|
|
499
604
|
const router = useRouter();
|
|
500
605
|
const getSearchParams = () => {
|
|
501
|
-
const location = router.location
|
|
606
|
+
const location = readAccessor(router.location);
|
|
502
607
|
return new URLSearchParams(location.search);
|
|
503
608
|
};
|
|
504
609
|
const setSearchParams = (params, options) => {
|
|
505
610
|
const searchParams = params instanceof URLSearchParams ? params : new URLSearchParams(params);
|
|
506
611
|
const search = searchParams.toString();
|
|
507
|
-
const location = router.location
|
|
508
|
-
router.navigate
|
|
612
|
+
const location = readAccessor(router.location);
|
|
613
|
+
const navigate = readAccessor(router.navigate);
|
|
614
|
+
navigate(
|
|
509
615
|
{
|
|
510
616
|
pathname: location.pathname,
|
|
511
617
|
search: search ? "?" + search : "",
|
|
@@ -514,23 +620,23 @@ function useSearchParams() {
|
|
|
514
620
|
{ replace: options?.replace }
|
|
515
621
|
);
|
|
516
622
|
};
|
|
517
|
-
return [getSearchParams, setSearchParams];
|
|
623
|
+
return [getSearchParams, wrapAccessor(setSearchParams)];
|
|
518
624
|
}
|
|
519
625
|
function useMatches() {
|
|
520
626
|
const router = useRouter();
|
|
521
|
-
return router.matches;
|
|
627
|
+
return () => readAccessor(router.matches);
|
|
522
628
|
}
|
|
523
629
|
function useIsRouting() {
|
|
524
630
|
const router = useRouter();
|
|
525
|
-
return router.isRouting;
|
|
631
|
+
return () => readAccessor(router.isRouting);
|
|
526
632
|
}
|
|
527
633
|
function usePendingLocation() {
|
|
528
634
|
const router = useRouter();
|
|
529
|
-
return router.pendingLocation;
|
|
635
|
+
return () => readAccessor(router.pendingLocation);
|
|
530
636
|
}
|
|
531
637
|
function useRouteData() {
|
|
532
638
|
const route = useRoute();
|
|
533
|
-
return route.data;
|
|
639
|
+
return () => readAccessor(route.data);
|
|
534
640
|
}
|
|
535
641
|
function useRouteError() {
|
|
536
642
|
const errorContext = (0, import_runtime.useContext)(RouteErrorContext);
|
|
@@ -538,20 +644,23 @@ function useRouteError() {
|
|
|
538
644
|
return errorContext.error;
|
|
539
645
|
}
|
|
540
646
|
const route = useRoute();
|
|
541
|
-
|
|
647
|
+
const routeError = route.error;
|
|
648
|
+
if (routeError === void 0) return void 0;
|
|
649
|
+
return readAccessor(routeError);
|
|
542
650
|
}
|
|
543
651
|
function useResolvedPath(to) {
|
|
544
652
|
const route = useRoute();
|
|
545
653
|
return () => {
|
|
546
654
|
const target = typeof to === "function" ? to() : to;
|
|
547
|
-
|
|
655
|
+
const resolvePath2 = readAccessor(route.resolvePath);
|
|
656
|
+
return resolvePath2(target);
|
|
548
657
|
};
|
|
549
658
|
}
|
|
550
659
|
function useMatch(path) {
|
|
551
660
|
const router = useRouter();
|
|
552
661
|
return () => {
|
|
553
662
|
const targetPath = typeof path === "function" ? path() : path;
|
|
554
|
-
const matches = router.matches
|
|
663
|
+
const matches = readAccessor(router.matches);
|
|
555
664
|
for (const match of matches) {
|
|
556
665
|
if (match.pattern === targetPath || match.pathname === targetPath) {
|
|
557
666
|
return match;
|
|
@@ -564,6 +673,7 @@ function useHref(to) {
|
|
|
564
673
|
const router = useRouter();
|
|
565
674
|
return () => {
|
|
566
675
|
const target = typeof to === "function" ? to() : to;
|
|
676
|
+
const base = readAccessor(router.base);
|
|
567
677
|
let pathname;
|
|
568
678
|
let search = "";
|
|
569
679
|
let hash = "";
|
|
@@ -587,16 +697,17 @@ function useHref(to) {
|
|
|
587
697
|
}
|
|
588
698
|
let resolved;
|
|
589
699
|
if (pathname === "") {
|
|
590
|
-
const currentPathname = router.location
|
|
591
|
-
const normalizedBase =
|
|
700
|
+
const currentPathname = readAccessor(router.location).pathname;
|
|
701
|
+
const normalizedBase = base === "/" || base === "" ? "" : base;
|
|
592
702
|
if (normalizedBase && !currentPathname.startsWith(normalizedBase)) {
|
|
593
703
|
return currentPathname + search + hash;
|
|
594
704
|
}
|
|
595
|
-
resolved = stripBasePath(currentPathname,
|
|
705
|
+
resolved = stripBasePath(currentPathname, base);
|
|
596
706
|
} else {
|
|
597
|
-
|
|
707
|
+
const resolvePath2 = readAccessor(router.resolvePath);
|
|
708
|
+
resolved = resolvePath2(pathname);
|
|
598
709
|
}
|
|
599
|
-
const baseHref = prependBasePath(resolved,
|
|
710
|
+
const baseHref = prependBasePath(resolved, base);
|
|
600
711
|
return baseHref + search + hash;
|
|
601
712
|
};
|
|
602
713
|
}
|
|
@@ -604,12 +715,14 @@ function useIsActive(to, options) {
|
|
|
604
715
|
const router = useRouter();
|
|
605
716
|
return () => {
|
|
606
717
|
const target = typeof to === "function" ? to() : to;
|
|
607
|
-
const
|
|
608
|
-
const
|
|
609
|
-
|
|
718
|
+
const resolvePath2 = readAccessor(router.resolvePath);
|
|
719
|
+
const resolvedTargetPath = resolvePath2(target);
|
|
720
|
+
const currentPath = readAccessor(router.location).pathname;
|
|
721
|
+
const base = readAccessor(router.base);
|
|
722
|
+
if (base && currentPath !== base && !currentPath.startsWith(base + "/")) {
|
|
610
723
|
return false;
|
|
611
724
|
}
|
|
612
|
-
const currentPathWithoutBase = stripBasePath(currentPath,
|
|
725
|
+
const currentPathWithoutBase = stripBasePath(currentPath, base);
|
|
613
726
|
if (options?.end) {
|
|
614
727
|
return currentPathWithoutBase === resolvedTargetPath;
|
|
615
728
|
}
|
|
@@ -1089,6 +1202,38 @@ function createStaticHistory(url) {
|
|
|
1089
1202
|
};
|
|
1090
1203
|
}
|
|
1091
1204
|
|
|
1205
|
+
// src/router-internals.ts
|
|
1206
|
+
var import_meta = {};
|
|
1207
|
+
var isDevEnv = typeof import_meta !== "undefined" && import_meta.env?.DEV === true || typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
|
|
1208
|
+
var didWarnBaseMismatch = false;
|
|
1209
|
+
function hasBasePrefix(pathname, base) {
|
|
1210
|
+
if (!base) return true;
|
|
1211
|
+
return pathname === base || pathname.startsWith(base + "/");
|
|
1212
|
+
}
|
|
1213
|
+
function stripBaseOrWarn(pathname, base) {
|
|
1214
|
+
if (!base) return pathname;
|
|
1215
|
+
if (!hasBasePrefix(pathname, base)) {
|
|
1216
|
+
if (isDevEnv && !didWarnBaseMismatch) {
|
|
1217
|
+
didWarnBaseMismatch = true;
|
|
1218
|
+
console.warn(
|
|
1219
|
+
`[fict-router] Location "${pathname}" does not start with base "${base}". No routes matched.`
|
|
1220
|
+
);
|
|
1221
|
+
}
|
|
1222
|
+
return null;
|
|
1223
|
+
}
|
|
1224
|
+
return stripBasePath(pathname, base);
|
|
1225
|
+
}
|
|
1226
|
+
function stripBaseIfPresent(pathname, base) {
|
|
1227
|
+
if (!base) return pathname;
|
|
1228
|
+
if (!hasBasePrefix(pathname, base)) return pathname;
|
|
1229
|
+
return stripBasePath(pathname, base);
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
// src/router-provider.ts
|
|
1233
|
+
var import_runtime2 = require("@fictjs/runtime");
|
|
1234
|
+
var import_advanced2 = require("@fictjs/runtime/advanced");
|
|
1235
|
+
var import_jsx_runtime = require("@fictjs/runtime/jsx-runtime");
|
|
1236
|
+
|
|
1092
1237
|
// src/scroll.ts
|
|
1093
1238
|
var scrollPositions = /* @__PURE__ */ new Map();
|
|
1094
1239
|
var MAX_STORED_POSITIONS = 100;
|
|
@@ -1211,35 +1356,7 @@ function configureScrollRestoration(options) {
|
|
|
1211
1356
|
defaultScrollRestoration = createScrollRestoration(options);
|
|
1212
1357
|
}
|
|
1213
1358
|
|
|
1214
|
-
// src/
|
|
1215
|
-
var import_jsx_runtime = require("fict/jsx-runtime");
|
|
1216
|
-
var import_meta = {};
|
|
1217
|
-
var isDevEnv = typeof import_meta !== "undefined" && import_meta.env?.DEV === true || typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
|
|
1218
|
-
var didWarnBaseMismatch = false;
|
|
1219
|
-
function hasBasePrefix(pathname, base) {
|
|
1220
|
-
if (!base) return true;
|
|
1221
|
-
return pathname === base || pathname.startsWith(base + "/");
|
|
1222
|
-
}
|
|
1223
|
-
function stripBaseOrWarn(pathname, base) {
|
|
1224
|
-
if (!base) return pathname;
|
|
1225
|
-
if (!hasBasePrefix(pathname, base)) {
|
|
1226
|
-
if (isDevEnv && !didWarnBaseMismatch) {
|
|
1227
|
-
didWarnBaseMismatch = true;
|
|
1228
|
-
console.warn(
|
|
1229
|
-
`[fict-router] Location "${pathname}" does not start with base "${base}". No routes matched.`
|
|
1230
|
-
);
|
|
1231
|
-
}
|
|
1232
|
-
return null;
|
|
1233
|
-
}
|
|
1234
|
-
return stripBasePath(pathname, base);
|
|
1235
|
-
}
|
|
1236
|
-
function stripBaseIfPresent(pathname, base) {
|
|
1237
|
-
if (!base) return pathname;
|
|
1238
|
-
if (hasBasePrefix(pathname, base)) {
|
|
1239
|
-
return stripBasePath(pathname, base);
|
|
1240
|
-
}
|
|
1241
|
-
return pathname;
|
|
1242
|
-
}
|
|
1359
|
+
// src/router-provider.ts
|
|
1243
1360
|
function createRouterState(history2, routes, base = "") {
|
|
1244
1361
|
const normalizedBase = normalizePath(base);
|
|
1245
1362
|
const baseForStrip = normalizedBase === "/" ? "" : normalizedBase;
|
|
@@ -1252,10 +1369,10 @@ function createRouterState(history2, routes, base = "") {
|
|
|
1252
1369
|
};
|
|
1253
1370
|
const initialLocation = history2.location;
|
|
1254
1371
|
const initialMatches = matchWithBase(initialLocation.pathname);
|
|
1255
|
-
const locationSignal = (0,
|
|
1256
|
-
const matchesSignal = (0,
|
|
1257
|
-
const isRoutingSignal = (0,
|
|
1258
|
-
const pendingLocationSignal = (0,
|
|
1372
|
+
const locationSignal = (0, import_advanced2.createSignal)(initialLocation);
|
|
1373
|
+
const matchesSignal = (0, import_advanced2.createSignal)(initialMatches);
|
|
1374
|
+
const isRoutingSignal = (0, import_advanced2.createSignal)(false);
|
|
1375
|
+
const pendingLocationSignal = (0, import_advanced2.createSignal)(null);
|
|
1259
1376
|
const beforeLeaveHandlers = /* @__PURE__ */ new Set();
|
|
1260
1377
|
let navigationToken = 0;
|
|
1261
1378
|
const beforeLeave = {
|
|
@@ -1266,7 +1383,7 @@ function createRouterState(history2, routes, base = "") {
|
|
|
1266
1383
|
async confirm(to, from) {
|
|
1267
1384
|
if (beforeLeaveHandlers.size === 0) return true;
|
|
1268
1385
|
const currentToken = ++navigationToken;
|
|
1269
|
-
let defaultPrevented =
|
|
1386
|
+
let defaultPrevented = true;
|
|
1270
1387
|
let retryRequested = false;
|
|
1271
1388
|
let forceRetry = false;
|
|
1272
1389
|
const event = {
|
|
@@ -1363,9 +1480,11 @@ function createRouterState(history2, routes, base = "") {
|
|
|
1363
1480
|
}
|
|
1364
1481
|
const targetLocation = createLocation(locationSpec, finalState, toKey);
|
|
1365
1482
|
(0, import_runtime2.untrack)(async () => {
|
|
1483
|
+
if (beforeLeaveHandlers.size > 0) {
|
|
1484
|
+
pendingLocationSignal(targetLocation);
|
|
1485
|
+
}
|
|
1366
1486
|
const canNavigate = await beforeLeave.confirm(targetLocation, currentLocation);
|
|
1367
1487
|
if (!canNavigate) {
|
|
1368
|
-
pendingLocationSignal(null);
|
|
1369
1488
|
return;
|
|
1370
1489
|
}
|
|
1371
1490
|
(0, import_runtime2.batch)(() => {
|
|
@@ -1431,6 +1550,17 @@ function RouterProvider(props) {
|
|
|
1431
1550
|
props.base
|
|
1432
1551
|
);
|
|
1433
1552
|
(0, import_runtime2.onCleanup)(cleanup);
|
|
1553
|
+
const beforeLeaveContext = {
|
|
1554
|
+
addHandler: wrapAccessor(beforeLeave.addHandler),
|
|
1555
|
+
confirm: wrapAccessor(beforeLeave.confirm)
|
|
1556
|
+
};
|
|
1557
|
+
const resolvePathFn = (to) => {
|
|
1558
|
+
const location = state().location;
|
|
1559
|
+
const currentPathWithoutBase = stripBaseOrWarn(location.pathname, normalizedBase) || "/";
|
|
1560
|
+
const rawTargetPath = typeof to === "string" ? to : to.pathname || "/";
|
|
1561
|
+
const targetPath = rawTargetPath.startsWith("/") ? stripBaseIfPresent(rawTargetPath, normalizedBase) : rawTargetPath;
|
|
1562
|
+
return resolvePath(currentPathWithoutBase, targetPath);
|
|
1563
|
+
};
|
|
1434
1564
|
const routerContext = {
|
|
1435
1565
|
location: () => state().location,
|
|
1436
1566
|
params: () => {
|
|
@@ -1442,30 +1572,41 @@ function RouterProvider(props) {
|
|
|
1442
1572
|
return allParams;
|
|
1443
1573
|
},
|
|
1444
1574
|
matches: () => state().matches,
|
|
1445
|
-
navigate,
|
|
1575
|
+
navigate: wrapAccessor(navigate),
|
|
1446
1576
|
isRouting: () => state().isRouting,
|
|
1447
1577
|
pendingLocation: () => state().pendingLocation,
|
|
1448
|
-
base: normalizedBase,
|
|
1449
|
-
resolvePath: (
|
|
1450
|
-
const location = state().location;
|
|
1451
|
-
const currentPathWithoutBase = stripBaseOrWarn(location.pathname, normalizedBase) || "/";
|
|
1452
|
-
const rawTargetPath = typeof to === "string" ? to : to.pathname || "/";
|
|
1453
|
-
const targetPath = rawTargetPath.startsWith("/") ? stripBaseIfPresent(rawTargetPath, normalizedBase) : rawTargetPath;
|
|
1454
|
-
return resolvePath(currentPathWithoutBase, targetPath);
|
|
1455
|
-
}
|
|
1578
|
+
base: wrapValue(normalizedBase),
|
|
1579
|
+
resolvePath: wrapAccessor(resolvePathFn)
|
|
1456
1580
|
};
|
|
1457
|
-
|
|
1581
|
+
pushActiveRouter(routerContext);
|
|
1582
|
+
pushActiveBeforeLeave(beforeLeaveContext);
|
|
1583
|
+
(0, import_runtime2.onCleanup)(() => {
|
|
1584
|
+
popActiveBeforeLeave(beforeLeaveContext);
|
|
1585
|
+
popActiveRouter(routerContext);
|
|
1586
|
+
});
|
|
1587
|
+
const RouterContextProvider = RouterContext.Provider;
|
|
1588
|
+
const BeforeLeaveProvider = BeforeLeaveContext.Provider;
|
|
1589
|
+
return (0, import_jsx_runtime.jsx)(RouterContextProvider, {
|
|
1590
|
+
value: routerContext,
|
|
1591
|
+
children: (0, import_jsx_runtime.jsx)(BeforeLeaveProvider, {
|
|
1592
|
+
value: beforeLeaveContext,
|
|
1593
|
+
children: props.children
|
|
1594
|
+
})
|
|
1595
|
+
});
|
|
1458
1596
|
}
|
|
1597
|
+
|
|
1598
|
+
// src/components.tsx
|
|
1599
|
+
var import_jsx_runtime2 = require("fict/jsx-runtime");
|
|
1459
1600
|
function Router(props) {
|
|
1460
1601
|
const history2 = props.history || createBrowserHistory();
|
|
1461
1602
|
const routes = extractRoutes(props.children);
|
|
1462
|
-
return /* @__PURE__ */ (0,
|
|
1603
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RouterProvider, { history: history2, routes, base: props.base, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Routes, { children: props.children }) });
|
|
1463
1604
|
}
|
|
1464
1605
|
function HashRouter(props) {
|
|
1465
1606
|
const hashOptions = props.hashType ? { hashType: props.hashType } : void 0;
|
|
1466
1607
|
const history2 = createHashHistory(hashOptions);
|
|
1467
1608
|
const routes = extractRoutes(props.children);
|
|
1468
|
-
return /* @__PURE__ */ (0,
|
|
1609
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RouterProvider, { history: history2, routes, base: props.base, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Routes, { children: props.children }) });
|
|
1469
1610
|
}
|
|
1470
1611
|
function MemoryRouter(props) {
|
|
1471
1612
|
const memoryOptions = {};
|
|
@@ -1479,12 +1620,12 @@ function MemoryRouter(props) {
|
|
|
1479
1620
|
Object.keys(memoryOptions).length > 0 ? memoryOptions : void 0
|
|
1480
1621
|
);
|
|
1481
1622
|
const routes = extractRoutes(props.children);
|
|
1482
|
-
return /* @__PURE__ */ (0,
|
|
1623
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RouterProvider, { history: history2, routes, base: props.base, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Routes, { children: props.children }) });
|
|
1483
1624
|
}
|
|
1484
1625
|
function StaticRouter(props) {
|
|
1485
1626
|
const history2 = createStaticHistory(props.url);
|
|
1486
1627
|
const routes = extractRoutes(props.children);
|
|
1487
|
-
return /* @__PURE__ */ (0,
|
|
1628
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RouterProvider, { history: history2, routes, base: props.base, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Routes, { children: props.children }) });
|
|
1488
1629
|
}
|
|
1489
1630
|
function Routes(props) {
|
|
1490
1631
|
const router = useRouter();
|
|
@@ -1492,10 +1633,12 @@ function Routes(props) {
|
|
|
1492
1633
|
const routes = extractRoutes(props.children);
|
|
1493
1634
|
const compiledRoutes = routes.map((r) => compileRoute(r));
|
|
1494
1635
|
const branches = createBranches(compiledRoutes);
|
|
1495
|
-
const currentMatches = (0,
|
|
1496
|
-
const
|
|
1497
|
-
const
|
|
1498
|
-
const
|
|
1636
|
+
const currentMatches = (0, import_runtime3.createMemo)(() => {
|
|
1637
|
+
const pendingLocation = readAccessor(router.pendingLocation);
|
|
1638
|
+
const location = pendingLocation ?? readAccessor(router.location);
|
|
1639
|
+
const parentMatch = readAccessor(parentRoute.match);
|
|
1640
|
+
const base = readAccessor(router.base);
|
|
1641
|
+
const locationPath = stripBaseOrWarn(location.pathname, base);
|
|
1499
1642
|
if (locationPath == null) return [];
|
|
1500
1643
|
let basePath = "/";
|
|
1501
1644
|
if (parentMatch) {
|
|
@@ -1504,24 +1647,22 @@ function Routes(props) {
|
|
|
1504
1647
|
const relativePath = locationPath.startsWith(basePath) ? locationPath.slice(basePath.length) || "/" : locationPath;
|
|
1505
1648
|
return matchRoutes(branches, relativePath) || [];
|
|
1506
1649
|
});
|
|
1507
|
-
|
|
1650
|
+
const matches = currentMatches();
|
|
1651
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: matches.length > 0 ? renderMatches(matches, 0) : null });
|
|
1508
1652
|
}
|
|
1509
1653
|
function renderMatches(matches, index) {
|
|
1510
|
-
if (index >= matches.length) {
|
|
1511
|
-
return null;
|
|
1512
|
-
}
|
|
1513
1654
|
const match = matches[index];
|
|
1514
1655
|
const route = match.route;
|
|
1515
1656
|
const router = useRouter();
|
|
1516
|
-
const dataState = (0,
|
|
1657
|
+
const dataState = (0, import_advanced3.createSignal)({
|
|
1517
1658
|
data: void 0,
|
|
1518
1659
|
error: void 0,
|
|
1519
1660
|
loading: !!route.preload
|
|
1520
1661
|
});
|
|
1521
1662
|
let preloadToken = 0;
|
|
1522
1663
|
if (route.preload) {
|
|
1523
|
-
(0,
|
|
1524
|
-
const location = router.location
|
|
1664
|
+
(0, import_runtime3.createEffect)(() => {
|
|
1665
|
+
const location = readAccessor(router.location);
|
|
1525
1666
|
const preloadArgs = {
|
|
1526
1667
|
params: match.params,
|
|
1527
1668
|
location,
|
|
@@ -1540,17 +1681,7 @@ function renderMatches(matches, index) {
|
|
|
1540
1681
|
});
|
|
1541
1682
|
});
|
|
1542
1683
|
}
|
|
1543
|
-
const
|
|
1544
|
-
match: () => match,
|
|
1545
|
-
data: () => dataState().data,
|
|
1546
|
-
error: () => dataState().error,
|
|
1547
|
-
outlet: () => renderMatches(matches, index + 1),
|
|
1548
|
-
resolvePath: (to) => {
|
|
1549
|
-
const basePath = match.pathname;
|
|
1550
|
-
const targetPath = typeof to === "string" ? to : to.pathname || "/";
|
|
1551
|
-
return resolvePath(basePath, targetPath);
|
|
1552
|
-
}
|
|
1553
|
-
};
|
|
1684
|
+
const outletNode = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Outlet, {});
|
|
1554
1685
|
const renderContent = () => {
|
|
1555
1686
|
const state = dataState();
|
|
1556
1687
|
if (state.error !== void 0 && route.errorElement) {
|
|
@@ -1561,26 +1692,39 @@ function renderMatches(matches, index) {
|
|
|
1561
1692
|
}
|
|
1562
1693
|
if (route.component) {
|
|
1563
1694
|
const Component = route.component;
|
|
1564
|
-
return /* @__PURE__ */ (0,
|
|
1565
|
-
}
|
|
1695
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Component, { params: match.params, location: readAccessor(router.location), data: state.data, children: outletNode });
|
|
1696
|
+
}
|
|
1697
|
+
if (route.element) {
|
|
1566
1698
|
return route.element;
|
|
1567
|
-
}
|
|
1568
|
-
|
|
1699
|
+
}
|
|
1700
|
+
if (route.children) {
|
|
1701
|
+
return outletNode;
|
|
1569
1702
|
}
|
|
1570
1703
|
return null;
|
|
1571
1704
|
};
|
|
1572
|
-
|
|
1705
|
+
const routeContext = {
|
|
1706
|
+
match: () => match,
|
|
1707
|
+
data: () => dataState().data,
|
|
1708
|
+
error: () => dataState().error,
|
|
1709
|
+
outlet: () => index + 1 < matches.length ? renderMatches(matches, index + 1) : null,
|
|
1710
|
+
resolvePath: wrapAccessor((to) => {
|
|
1711
|
+
const basePath = match.pathname;
|
|
1712
|
+
const targetPath = typeof to === "string" ? to : to.pathname || "/";
|
|
1713
|
+
return resolvePath(basePath, targetPath);
|
|
1714
|
+
})
|
|
1715
|
+
};
|
|
1716
|
+
let content = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RouteContext.Provider, { value: routeContext, children: renderContent() });
|
|
1573
1717
|
if (route.errorElement) {
|
|
1574
|
-
content = /* @__PURE__ */ (0,
|
|
1575
|
-
|
|
1718
|
+
content = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1719
|
+
import_runtime3.ErrorBoundary,
|
|
1576
1720
|
{
|
|
1577
|
-
fallback: (err, reset) => /* @__PURE__ */ (0,
|
|
1721
|
+
fallback: (err, reset) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RouteErrorContext.Provider, { value: { error: err, reset }, children: route.errorElement }),
|
|
1578
1722
|
children: content
|
|
1579
1723
|
}
|
|
1580
1724
|
);
|
|
1581
1725
|
}
|
|
1582
1726
|
if (route.loadingElement) {
|
|
1583
|
-
content = /* @__PURE__ */ (0,
|
|
1727
|
+
content = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_runtime3.Suspense, { fallback: route.loadingElement, children: content });
|
|
1584
1728
|
}
|
|
1585
1729
|
return content;
|
|
1586
1730
|
}
|
|
@@ -1589,11 +1733,11 @@ function Route(_props) {
|
|
|
1589
1733
|
}
|
|
1590
1734
|
function Outlet() {
|
|
1591
1735
|
const route = useRoute();
|
|
1592
|
-
return
|
|
1736
|
+
return readAccessor(route.outlet);
|
|
1593
1737
|
}
|
|
1594
1738
|
function Navigate(props) {
|
|
1595
1739
|
const router = useRouter();
|
|
1596
|
-
(0,
|
|
1740
|
+
(0, import_runtime3.createEffect)(() => {
|
|
1597
1741
|
router.navigate(props.to, {
|
|
1598
1742
|
replace: props.replace ?? true,
|
|
1599
1743
|
state: props.state
|
|
@@ -1603,7 +1747,7 @@ function Navigate(props) {
|
|
|
1603
1747
|
}
|
|
1604
1748
|
function Redirect(props) {
|
|
1605
1749
|
const router = useRouter();
|
|
1606
|
-
(0,
|
|
1750
|
+
(0, import_runtime3.createEffect)(() => {
|
|
1607
1751
|
router.navigate(props.to, {
|
|
1608
1752
|
replace: props.push !== true,
|
|
1609
1753
|
// Replace by default, push only if explicitly requested
|
|
@@ -1633,7 +1777,7 @@ function extractRoutes(children) {
|
|
|
1633
1777
|
routeDef.loadingElement = props.loadingElement;
|
|
1634
1778
|
if (props.children) routeDef.children = extractRoutes(props.children);
|
|
1635
1779
|
routes.push(routeDef);
|
|
1636
|
-
} else if (vnode.type ===
|
|
1780
|
+
} else if (vnode.type === import_runtime3.Fragment && vnode.props?.children) {
|
|
1637
1781
|
routes.push(...extractRoutes(vnode.props.children));
|
|
1638
1782
|
}
|
|
1639
1783
|
}
|
|
@@ -1646,28 +1790,42 @@ function createRouter(routes, options) {
|
|
|
1646
1790
|
return {
|
|
1647
1791
|
Router: (props) => {
|
|
1648
1792
|
const history2 = options?.history || createBrowserHistory();
|
|
1649
|
-
return /* @__PURE__ */ (0,
|
|
1793
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RouterProvider, { history: history2, routes, base: options?.base, children: props.children || /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Routes, { children: routesToElements(routes) }) });
|
|
1650
1794
|
}
|
|
1651
1795
|
};
|
|
1652
1796
|
}
|
|
1653
1797
|
function routesToElements(routes) {
|
|
1654
|
-
return /* @__PURE__ */ (0,
|
|
1798
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: routes.map((route, i) => {
|
|
1655
1799
|
const routeProps = { key: route.key || `route-${i}` };
|
|
1656
1800
|
if (route.path !== void 0) routeProps.path = route.path;
|
|
1657
1801
|
if (route.component !== void 0) routeProps.component = route.component;
|
|
1658
1802
|
if (route.element !== void 0) routeProps.element = route.element;
|
|
1659
1803
|
if (route.index !== void 0) routeProps.index = route.index;
|
|
1660
1804
|
if (route.children) routeProps.children = routesToElements(route.children);
|
|
1661
|
-
return /* @__PURE__ */ (0,
|
|
1805
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Route, { ...routeProps });
|
|
1662
1806
|
}) });
|
|
1663
1807
|
}
|
|
1664
1808
|
|
|
1665
1809
|
// src/link.tsx
|
|
1666
|
-
var
|
|
1667
|
-
var
|
|
1810
|
+
var import_runtime4 = require("@fictjs/runtime");
|
|
1811
|
+
var import_internal = require("@fictjs/runtime/internal");
|
|
1812
|
+
var import_jsx_runtime3 = require("fict/jsx-runtime");
|
|
1813
|
+
var createSpreadRef = (props) => {
|
|
1814
|
+
let current = null;
|
|
1815
|
+
return (el) => {
|
|
1816
|
+
if (!el) {
|
|
1817
|
+
current = null;
|
|
1818
|
+
return;
|
|
1819
|
+
}
|
|
1820
|
+
if (el === current) return;
|
|
1821
|
+
current = el;
|
|
1822
|
+
(0, import_internal.spread)(el, props, false, true);
|
|
1823
|
+
};
|
|
1824
|
+
};
|
|
1668
1825
|
function Link(props) {
|
|
1669
1826
|
const router = useRouter();
|
|
1670
1827
|
const href = useHref(() => props.to);
|
|
1828
|
+
const getHrefValue = () => readAccessor(readAccessor(href));
|
|
1671
1829
|
let preloadTriggered = false;
|
|
1672
1830
|
const handleClick = (event) => {
|
|
1673
1831
|
if (props.onClick) {
|
|
@@ -1692,7 +1850,7 @@ function Link(props) {
|
|
|
1692
1850
|
const triggerPreload = () => {
|
|
1693
1851
|
if (preloadTriggered || props.disabled || props.prefetch === "none") return;
|
|
1694
1852
|
preloadTriggered = true;
|
|
1695
|
-
const hrefValue =
|
|
1853
|
+
const hrefValue = getHrefValue();
|
|
1696
1854
|
if (typeof window !== "undefined" && window.dispatchEvent) {
|
|
1697
1855
|
window.dispatchEvent(
|
|
1698
1856
|
new CustomEvent("fict-router:preload", {
|
|
@@ -1705,14 +1863,16 @@ function Link(props) {
|
|
|
1705
1863
|
if (props.prefetch === "intent" || props.prefetch === void 0) {
|
|
1706
1864
|
triggerPreload();
|
|
1707
1865
|
}
|
|
1708
|
-
const
|
|
1866
|
+
const propsRecord = props;
|
|
1867
|
+
const onMouseEnter = propsRecord.onMouseEnter;
|
|
1709
1868
|
if (onMouseEnter) onMouseEnter(event);
|
|
1710
1869
|
};
|
|
1711
1870
|
const handleFocus = (event) => {
|
|
1712
1871
|
if (props.prefetch === "intent" || props.prefetch === void 0) {
|
|
1713
1872
|
triggerPreload();
|
|
1714
1873
|
}
|
|
1715
|
-
const
|
|
1874
|
+
const propsRecord = props;
|
|
1875
|
+
const onFocus = propsRecord.onFocus;
|
|
1716
1876
|
if (onFocus) onFocus(event);
|
|
1717
1877
|
};
|
|
1718
1878
|
const {
|
|
@@ -1725,20 +1885,24 @@ function Link(props) {
|
|
|
1725
1885
|
prefetch,
|
|
1726
1886
|
disabled,
|
|
1727
1887
|
onClick: _onClick,
|
|
1888
|
+
onMouseEnter: _onMouseEnter,
|
|
1889
|
+
onFocus: _onFocus,
|
|
1728
1890
|
children,
|
|
1729
1891
|
...anchorProps
|
|
1730
1892
|
} = props;
|
|
1893
|
+
const anchorRef = createSpreadRef(anchorProps);
|
|
1894
|
+
const spanRef = createSpreadRef(anchorProps);
|
|
1731
1895
|
if (disabled) {
|
|
1732
|
-
return /* @__PURE__ */ (0,
|
|
1896
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { ref: spanRef, children });
|
|
1733
1897
|
}
|
|
1734
1898
|
if (prefetch === "render") {
|
|
1735
1899
|
triggerPreload();
|
|
1736
1900
|
}
|
|
1737
|
-
return /* @__PURE__ */ (0,
|
|
1901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1738
1902
|
"a",
|
|
1739
1903
|
{
|
|
1740
|
-
|
|
1741
|
-
href:
|
|
1904
|
+
ref: anchorRef,
|
|
1905
|
+
href: getHrefValue(),
|
|
1742
1906
|
onClick: handleClick,
|
|
1743
1907
|
onMouseEnter: handleMouseEnter,
|
|
1744
1908
|
onFocus: handleFocus,
|
|
@@ -1750,12 +1914,14 @@ function NavLink(props) {
|
|
|
1750
1914
|
const router = useRouter();
|
|
1751
1915
|
const isActive = useIsActive(() => props.to, { end: props.end });
|
|
1752
1916
|
const href = useHref(() => props.to);
|
|
1917
|
+
const getHrefValue = () => readAccessor(readAccessor(href));
|
|
1753
1918
|
const pendingLocation = usePendingLocation();
|
|
1754
1919
|
const computeIsPending = () => {
|
|
1755
1920
|
const pending = pendingLocation();
|
|
1756
1921
|
if (!pending) return false;
|
|
1757
|
-
const resolvedHref =
|
|
1758
|
-
const
|
|
1922
|
+
const resolvedHref = getHrefValue();
|
|
1923
|
+
const base = readAccessor(router.base);
|
|
1924
|
+
const baseToStrip = base === "/" ? "" : base;
|
|
1759
1925
|
const pendingPathWithoutBase = stripBasePath(pending.pathname, baseToStrip);
|
|
1760
1926
|
const parsed = parseURL(resolvedHref);
|
|
1761
1927
|
const targetPathWithoutBase = stripBasePath(parsed.pathname, baseToStrip);
|
|
@@ -1767,9 +1933,9 @@ function NavLink(props) {
|
|
|
1767
1933
|
const getRenderProps = () => ({
|
|
1768
1934
|
isActive: isActive(),
|
|
1769
1935
|
isPending: computeIsPending(),
|
|
1770
|
-
isTransitioning: router.isRouting
|
|
1936
|
+
isTransitioning: readAccessor(router.isRouting)
|
|
1771
1937
|
});
|
|
1772
|
-
const computedClassName = (0,
|
|
1938
|
+
const computedClassName = (0, import_runtime4.createMemo)(() => {
|
|
1773
1939
|
const renderProps = getRenderProps();
|
|
1774
1940
|
const classes = [];
|
|
1775
1941
|
if (typeof props.className === "function") {
|
|
@@ -1786,7 +1952,7 @@ function NavLink(props) {
|
|
|
1786
1952
|
}
|
|
1787
1953
|
return classes.join(" ") || void 0;
|
|
1788
1954
|
});
|
|
1789
|
-
const computedStyle = (0,
|
|
1955
|
+
const computedStyle = (0, import_runtime4.createMemo)(() => {
|
|
1790
1956
|
const renderProps = getRenderProps();
|
|
1791
1957
|
const style = {};
|
|
1792
1958
|
if (typeof props.style === "function") {
|
|
@@ -1803,14 +1969,14 @@ function NavLink(props) {
|
|
|
1803
1969
|
}
|
|
1804
1970
|
return Object.keys(style).length > 0 ? style : void 0;
|
|
1805
1971
|
});
|
|
1806
|
-
const computedChildren = (0,
|
|
1972
|
+
const computedChildren = (0, import_runtime4.createMemo)(() => {
|
|
1807
1973
|
const renderProps = getRenderProps();
|
|
1808
1974
|
if (typeof props.children === "function") {
|
|
1809
1975
|
return props.children(renderProps);
|
|
1810
1976
|
}
|
|
1811
1977
|
return props.children;
|
|
1812
1978
|
});
|
|
1813
|
-
const ariaCurrent = (0,
|
|
1979
|
+
const ariaCurrent = (0, import_runtime4.createMemo)(() => {
|
|
1814
1980
|
const renderProps = getRenderProps();
|
|
1815
1981
|
if (!renderProps.isActive) return void 0;
|
|
1816
1982
|
return props["aria-current"] || "page";
|
|
@@ -1856,18 +2022,30 @@ function NavLink(props) {
|
|
|
1856
2022
|
"aria-current": _ariaCurrent,
|
|
1857
2023
|
...anchorProps
|
|
1858
2024
|
} = props;
|
|
2025
|
+
const anchorRef = createSpreadRef(anchorProps);
|
|
2026
|
+
const spanRef = createSpreadRef(anchorProps);
|
|
1859
2027
|
if (disabled) {
|
|
1860
|
-
|
|
2028
|
+
const disabledClassName = computedClassName();
|
|
2029
|
+
const disabledStyle = computedStyle();
|
|
2030
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
2031
|
+
"span",
|
|
2032
|
+
{
|
|
2033
|
+
ref: spanRef,
|
|
2034
|
+
...disabledClassName !== void 0 ? { class: disabledClassName } : {},
|
|
2035
|
+
...disabledStyle !== void 0 ? { style: disabledStyle } : {},
|
|
2036
|
+
children: computedChildren()
|
|
2037
|
+
}
|
|
2038
|
+
);
|
|
1861
2039
|
}
|
|
1862
2040
|
const finalClassName = computedClassName();
|
|
1863
2041
|
const finalStyle = computedStyle();
|
|
1864
2042
|
const finalAriaCurrent = ariaCurrent();
|
|
1865
|
-
return /* @__PURE__ */ (0,
|
|
2043
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1866
2044
|
"a",
|
|
1867
2045
|
{
|
|
1868
|
-
|
|
1869
|
-
href:
|
|
1870
|
-
...finalClassName !== void 0 ? {
|
|
2046
|
+
ref: anchorRef,
|
|
2047
|
+
href: getHrefValue(),
|
|
2048
|
+
...finalClassName !== void 0 ? { class: finalClassName } : {},
|
|
1871
2049
|
...finalStyle !== void 0 ? { style: finalStyle } : {},
|
|
1872
2050
|
...finalAriaCurrent !== void 0 ? { "aria-current": finalAriaCurrent } : {},
|
|
1873
2051
|
onClick: handleClick,
|
|
@@ -1888,7 +2066,7 @@ function Form(props) {
|
|
|
1888
2066
|
event.preventDefault();
|
|
1889
2067
|
const formData = new FormData(form);
|
|
1890
2068
|
const method2 = props.method?.toUpperCase() || "GET";
|
|
1891
|
-
const actionUrl = props.action || router.location
|
|
2069
|
+
const actionUrl = props.action || readAccessor(router.location).pathname;
|
|
1892
2070
|
if (method2 === "GET") {
|
|
1893
2071
|
const searchParams = new URLSearchParams();
|
|
1894
2072
|
formData.forEach((value, key) => {
|
|
@@ -1963,11 +2141,12 @@ function Form(props) {
|
|
|
1963
2141
|
onSubmit: _onSubmit,
|
|
1964
2142
|
...formProps
|
|
1965
2143
|
} = props;
|
|
2144
|
+
const formRef = createSpreadRef(formProps);
|
|
1966
2145
|
const htmlMethod = method && ["get", "post"].includes(method) ? method : void 0;
|
|
1967
|
-
return /* @__PURE__ */ (0,
|
|
2146
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1968
2147
|
"form",
|
|
1969
2148
|
{
|
|
1970
|
-
|
|
2149
|
+
ref: formRef,
|
|
1971
2150
|
...action2 !== void 0 ? { action: action2 } : {},
|
|
1972
2151
|
...htmlMethod !== void 0 ? { method: htmlMethod } : {},
|
|
1973
2152
|
onSubmit: handleSubmit,
|
|
@@ -1977,8 +2156,8 @@ function Form(props) {
|
|
|
1977
2156
|
}
|
|
1978
2157
|
|
|
1979
2158
|
// src/data.ts
|
|
1980
|
-
var
|
|
1981
|
-
var
|
|
2159
|
+
var import_runtime5 = require("@fictjs/runtime");
|
|
2160
|
+
var import_advanced4 = require("@fictjs/runtime/advanced");
|
|
1982
2161
|
var CACHE_DURATION = 3 * 60 * 1e3;
|
|
1983
2162
|
var PRELOAD_CACHE_DURATION = 5 * 1e3;
|
|
1984
2163
|
var MAX_CACHE_SIZE = 500;
|
|
@@ -2031,9 +2210,9 @@ function query(fn, name) {
|
|
|
2031
2210
|
return () => cached.result;
|
|
2032
2211
|
}
|
|
2033
2212
|
}
|
|
2034
|
-
const resultSignal = (0,
|
|
2035
|
-
const errorSignal = (0,
|
|
2036
|
-
const loadingSignal = (0,
|
|
2213
|
+
const resultSignal = (0, import_advanced4.createSignal)(cached?.result);
|
|
2214
|
+
const errorSignal = (0, import_advanced4.createSignal)(void 0);
|
|
2215
|
+
const loadingSignal = (0, import_advanced4.createSignal)(true);
|
|
2037
2216
|
const promise = Promise.resolve(fn(...args)).then((result) => {
|
|
2038
2217
|
const entry = {
|
|
2039
2218
|
timestamp: Date.now(),
|
|
@@ -2043,13 +2222,13 @@ function query(fn, name) {
|
|
|
2043
2222
|
};
|
|
2044
2223
|
queryCache.set(cacheKey, entry);
|
|
2045
2224
|
evictOldestEntries();
|
|
2046
|
-
(0,
|
|
2225
|
+
(0, import_runtime5.batch)(() => {
|
|
2047
2226
|
resultSignal(result);
|
|
2048
2227
|
loadingSignal(false);
|
|
2049
2228
|
});
|
|
2050
2229
|
return result;
|
|
2051
2230
|
}).catch((error) => {
|
|
2052
|
-
(0,
|
|
2231
|
+
(0, import_runtime5.batch)(() => {
|
|
2053
2232
|
errorSignal(error);
|
|
2054
2233
|
loadingSignal(false);
|
|
2055
2234
|
});
|
|
@@ -2118,7 +2297,7 @@ function action(fn, name) {
|
|
|
2118
2297
|
function getAction(url) {
|
|
2119
2298
|
return actionRegistry.get(url);
|
|
2120
2299
|
}
|
|
2121
|
-
var activeSubmissions = (0,
|
|
2300
|
+
var activeSubmissions = (0, import_advanced4.createSignal)(/* @__PURE__ */ new Map());
|
|
2122
2301
|
function useSubmission(actionOrUrl) {
|
|
2123
2302
|
const url = typeof actionOrUrl === "string" ? actionOrUrl : actionOrUrl.url;
|
|
2124
2303
|
return () => {
|
|
@@ -2173,10 +2352,10 @@ function createPreload(fn) {
|
|
|
2173
2352
|
};
|
|
2174
2353
|
}
|
|
2175
2354
|
function createResource(source, fetcher) {
|
|
2176
|
-
const dataSignal = (0,
|
|
2177
|
-
const loadingSignal = (0,
|
|
2178
|
-
const errorSignal = (0,
|
|
2179
|
-
const latestSignal = (0,
|
|
2355
|
+
const dataSignal = (0, import_advanced4.createSignal)(void 0);
|
|
2356
|
+
const loadingSignal = (0, import_advanced4.createSignal)(true);
|
|
2357
|
+
const errorSignal = (0, import_advanced4.createSignal)(void 0);
|
|
2358
|
+
const latestSignal = (0, import_advanced4.createSignal)(void 0);
|
|
2180
2359
|
let currentSource;
|
|
2181
2360
|
let fetchId = 0;
|
|
2182
2361
|
const doFetch = async (s, id) => {
|
|
@@ -2185,7 +2364,7 @@ function createResource(source, fetcher) {
|
|
|
2185
2364
|
try {
|
|
2186
2365
|
const result = await fetcher(s);
|
|
2187
2366
|
if (id === fetchId) {
|
|
2188
|
-
(0,
|
|
2367
|
+
(0, import_runtime5.batch)(() => {
|
|
2189
2368
|
dataSignal(result);
|
|
2190
2369
|
latestSignal(result);
|
|
2191
2370
|
loadingSignal(false);
|
|
@@ -2195,7 +2374,7 @@ function createResource(source, fetcher) {
|
|
|
2195
2374
|
return void 0;
|
|
2196
2375
|
} catch (err) {
|
|
2197
2376
|
if (id === fetchId) {
|
|
2198
|
-
(0,
|
|
2377
|
+
(0, import_runtime5.batch)(() => {
|
|
2199
2378
|
errorSignal(err);
|
|
2200
2379
|
loadingSignal(false);
|
|
2201
2380
|
});
|
|
@@ -2203,7 +2382,7 @@ function createResource(source, fetcher) {
|
|
|
2203
2382
|
return void 0;
|
|
2204
2383
|
}
|
|
2205
2384
|
};
|
|
2206
|
-
(0,
|
|
2385
|
+
(0, import_runtime5.createEffect)(() => {
|
|
2207
2386
|
const s = source();
|
|
2208
2387
|
if (s !== currentSource) {
|
|
2209
2388
|
currentSource = s;
|
|
@@ -2229,21 +2408,25 @@ function cleanupDataUtilities() {
|
|
|
2229
2408
|
}
|
|
2230
2409
|
|
|
2231
2410
|
// src/lazy.tsx
|
|
2232
|
-
var
|
|
2233
|
-
var
|
|
2234
|
-
var
|
|
2411
|
+
var import_runtime6 = require("@fictjs/runtime");
|
|
2412
|
+
var import_advanced5 = require("@fictjs/runtime/advanced");
|
|
2413
|
+
var import_jsx_runtime4 = require("fict/jsx-runtime");
|
|
2235
2414
|
function lazy(loader) {
|
|
2236
2415
|
let cachedComponent = null;
|
|
2237
2416
|
let loadPromise = null;
|
|
2238
2417
|
const LazyComponent = (props) => {
|
|
2239
|
-
|
|
2418
|
+
let isMounted = true;
|
|
2419
|
+
(0, import_runtime6.onCleanup)(() => {
|
|
2420
|
+
isMounted = false;
|
|
2421
|
+
});
|
|
2422
|
+
const state = (0, import_advanced5.createSignal)({
|
|
2240
2423
|
component: cachedComponent,
|
|
2241
2424
|
error: null,
|
|
2242
2425
|
loading: !cachedComponent
|
|
2243
2426
|
});
|
|
2244
2427
|
if (cachedComponent) {
|
|
2245
2428
|
const CachedComponent = cachedComponent;
|
|
2246
|
-
return /* @__PURE__ */ (0,
|
|
2429
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CachedComponent, { ...props });
|
|
2247
2430
|
}
|
|
2248
2431
|
if (!loadPromise) {
|
|
2249
2432
|
loadPromise = loader().then((module2) => {
|
|
@@ -2253,9 +2436,13 @@ function lazy(loader) {
|
|
|
2253
2436
|
});
|
|
2254
2437
|
}
|
|
2255
2438
|
loadPromise.then((component) => {
|
|
2256
|
-
|
|
2439
|
+
if (isMounted) {
|
|
2440
|
+
state({ component, error: null, loading: false });
|
|
2441
|
+
}
|
|
2257
2442
|
}).catch((error) => {
|
|
2258
|
-
|
|
2443
|
+
if (isMounted) {
|
|
2444
|
+
state({ component: null, error, loading: false });
|
|
2445
|
+
}
|
|
2259
2446
|
});
|
|
2260
2447
|
const currentState = state();
|
|
2261
2448
|
if (currentState.error) {
|
|
@@ -2265,10 +2452,11 @@ function lazy(loader) {
|
|
|
2265
2452
|
throw loadPromise;
|
|
2266
2453
|
}
|
|
2267
2454
|
const LoadedComponent = currentState.component;
|
|
2268
|
-
return /* @__PURE__ */ (0,
|
|
2455
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LoadedComponent, { ...props });
|
|
2269
2456
|
};
|
|
2270
|
-
|
|
2271
|
-
|
|
2457
|
+
const lazyComp = LazyComponent;
|
|
2458
|
+
lazyComp.__lazy = true;
|
|
2459
|
+
lazyComp.__preload = () => {
|
|
2272
2460
|
if (!loadPromise) {
|
|
2273
2461
|
loadPromise = loader().then((module2) => {
|
|
2274
2462
|
const component = "default" in module2 ? module2.default : module2;
|
|
@@ -2288,7 +2476,8 @@ function preloadLazy(component) {
|
|
|
2288
2476
|
return Promise.resolve();
|
|
2289
2477
|
}
|
|
2290
2478
|
function isLazyComponent(component) {
|
|
2291
|
-
|
|
2479
|
+
const comp = component;
|
|
2480
|
+
return !!(comp && typeof comp === "function" && comp.__lazy);
|
|
2292
2481
|
}
|
|
2293
2482
|
function lazyRoute(config) {
|
|
2294
2483
|
const LazyComponent = lazy(config.component);
|