@rangojs/router 0.0.0-experimental.57 → 0.0.0-experimental.57005a2b
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 +76 -18
- package/dist/bin/rango.js +2 -1
- package/dist/vite/index.js +507 -192
- package/dist/vite/index.js.bak +5448 -0
- package/package.json +3 -3
- package/skills/handler-use/SKILL.md +362 -0
- package/skills/intercept/SKILL.md +20 -0
- package/skills/layout/SKILL.md +22 -0
- package/skills/middleware/SKILL.md +32 -3
- package/skills/migrate-nextjs/SKILL.md +560 -0
- package/skills/migrate-react-router/SKILL.md +764 -0
- package/skills/parallel/SKILL.md +59 -0
- package/skills/prerender/SKILL.md +110 -68
- package/skills/rango/SKILL.md +24 -22
- package/skills/route/SKILL.md +24 -0
- package/src/__internal.ts +1 -1
- package/src/browser/navigation-bridge.ts +21 -2
- package/src/browser/navigation-client.ts +34 -6
- package/src/browser/partial-update.ts +14 -2
- package/src/browser/prefetch/cache.ts +16 -6
- package/src/browser/prefetch/fetch.ts +60 -4
- package/src/browser/react/Link.tsx +25 -2
- package/src/browser/react/use-handle.ts +9 -58
- package/src/browser/scroll-restoration.ts +10 -8
- package/src/browser/segment-reconciler.ts +36 -14
- package/src/build/generate-manifest.ts +3 -6
- package/src/build/route-trie.ts +50 -24
- package/src/build/route-types/scan-filter.ts +8 -1
- package/src/client.tsx +84 -230
- package/src/handle.ts +40 -0
- package/src/index.rsc.ts +3 -1
- package/src/index.ts +46 -6
- package/src/prerender/store.ts +5 -4
- package/src/prerender.ts +138 -77
- package/src/reverse.ts +25 -1
- package/src/route-definition/dsl-helpers.ts +194 -32
- package/src/route-definition/helpers-types.ts +61 -14
- package/src/route-definition/index.ts +3 -0
- package/src/route-definition/resolve-handler-use.ts +149 -0
- package/src/route-types.ts +18 -0
- package/src/router/content-negotiation.ts +100 -1
- package/src/router/handler-context.ts +46 -6
- package/src/router/lazy-includes.ts +5 -5
- package/src/router/loader-resolution.ts +147 -19
- package/src/router/manifest.ts +12 -7
- package/src/router/match-api.ts +124 -189
- package/src/router/match-middleware/cache-lookup.ts +24 -7
- package/src/router/match-middleware/segment-resolution.ts +53 -0
- package/src/router/match-result.ts +82 -4
- package/src/router/navigation-snapshot.ts +182 -0
- package/src/router/prerender-match.ts +108 -8
- package/src/router/preview-match.ts +30 -102
- package/src/router/request-classification.ts +310 -0
- package/src/router/route-snapshot.ts +245 -0
- package/src/router/router-interfaces.ts +11 -0
- package/src/router/segment-resolution/fresh.ts +59 -2
- package/src/router/segment-resolution/revalidation.ts +79 -6
- package/src/router.ts +13 -1
- package/src/rsc/handler.ts +468 -377
- package/src/rsc/loader-fetch.ts +23 -3
- package/src/rsc/progressive-enhancement.ts +10 -2
- package/src/rsc/rsc-rendering.ts +5 -1
- package/src/rsc/server-action.ts +6 -0
- package/src/rsc/ssr-setup.ts +1 -1
- package/src/rsc/types.ts +1 -0
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +122 -0
- package/src/segment-system.tsx +11 -61
- package/src/server/context.ts +40 -4
- package/src/server/handle-store.ts +19 -0
- package/src/server/request-context.ts +125 -3
- package/src/static-handler.ts +18 -6
- package/src/types/handler-context.ts +12 -2
- package/src/types/loader-types.ts +32 -4
- package/src/types/route-entry.ts +12 -1
- package/src/types/segments.ts +1 -1
- package/src/urls/include-helper.ts +24 -14
- package/src/urls/path-helper-types.ts +39 -6
- package/src/urls/path-helper.ts +47 -12
- package/src/urls/response-types.ts +16 -6
- package/src/use-loader.tsx +77 -5
- package/src/vite/discovery/bundle-postprocess.ts +30 -33
- package/src/vite/discovery/prerender-collection.ts +128 -74
- package/src/vite/discovery/state.ts +13 -4
- package/src/vite/index.ts +4 -0
- package/src/vite/plugin-types.ts +60 -5
- package/src/vite/plugins/expose-id-utils.ts +12 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +30 -0
- package/src/vite/plugins/expose-internal-ids.ts +257 -40
- package/src/vite/plugins/refresh-cmd.ts +88 -26
- package/src/vite/rango.ts +2 -1
- package/src/vite/router-discovery.ts +178 -37
- package/src/vite/utils/prerender-utils.ts +37 -5
|
@@ -319,6 +319,39 @@ export async function resolveLoadersOnlyWithRevalidation<TEnv>(
|
|
|
319
319
|
const childBelongsToRoute = belongsToRoute || entry.type === "route";
|
|
320
320
|
for (const layoutEntry of entry.layout) {
|
|
321
321
|
await collectEntryLoaders(layoutEntry, childBelongsToRoute);
|
|
322
|
+
// Inherit route loaders for orphan layouts with parallels.
|
|
323
|
+
// Resolve directly — do NOT re-enter collectEntryLoaders with the
|
|
324
|
+
// route entry, as that would re-iterate route.layout and loop.
|
|
325
|
+
if (
|
|
326
|
+
entry.type === "route" &&
|
|
327
|
+
entry.loader &&
|
|
328
|
+
entry.loader.length > 0 &&
|
|
329
|
+
Object.keys(layoutEntry.parallel).length > 0
|
|
330
|
+
) {
|
|
331
|
+
const inherited = await resolveLoadersWithRevalidation(
|
|
332
|
+
entry,
|
|
333
|
+
context,
|
|
334
|
+
childBelongsToRoute,
|
|
335
|
+
clientSegmentIds,
|
|
336
|
+
prevParams,
|
|
337
|
+
request,
|
|
338
|
+
prevUrl,
|
|
339
|
+
nextUrl,
|
|
340
|
+
routeKey,
|
|
341
|
+
deps,
|
|
342
|
+
actionContext,
|
|
343
|
+
layoutEntry.shortCode,
|
|
344
|
+
stale,
|
|
345
|
+
);
|
|
346
|
+
for (const seg of inherited.segments) {
|
|
347
|
+
if (!seenIds.has(seg.id)) {
|
|
348
|
+
seenIds.add(seg.id);
|
|
349
|
+
seg._inherited = true;
|
|
350
|
+
allLoaderSegments.push(seg);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
allMatchedIds.push(...inherited.matchedIds);
|
|
354
|
+
}
|
|
322
355
|
}
|
|
323
356
|
}
|
|
324
357
|
|
|
@@ -688,13 +721,20 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
|
|
|
688
721
|
return staticComponent;
|
|
689
722
|
}
|
|
690
723
|
const routeEntry = entry as Extract<EntryData, { type: "route" }>;
|
|
724
|
+
// For Passthrough routes at runtime, use the live handler instead of
|
|
725
|
+
// the build handler. At build time (context.build === true), always
|
|
726
|
+
// use the build handler from routeEntry.handler.
|
|
727
|
+
const handler =
|
|
728
|
+
!context.build && routeEntry.liveHandler
|
|
729
|
+
? routeEntry.liveHandler
|
|
730
|
+
: routeEntry.handler;
|
|
691
731
|
if (!routeEntry.loading) {
|
|
692
|
-
const result = handleHandlerResult(await
|
|
732
|
+
const result = handleHandlerResult(await handler(context));
|
|
693
733
|
doneHandler();
|
|
694
734
|
return result;
|
|
695
735
|
}
|
|
696
736
|
if (!actionContext) {
|
|
697
|
-
const result = handleHandlerResult(
|
|
737
|
+
const result = handleHandlerResult(handler(context));
|
|
698
738
|
if (result instanceof Promise) {
|
|
699
739
|
result.finally(doneHandler).catch(() => {});
|
|
700
740
|
const tracked = deps.trackHandler(result, {
|
|
@@ -717,9 +757,7 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
|
|
|
717
757
|
debugLog("segment.action", "resolving action route with awaited value", {
|
|
718
758
|
entryId: entry.id,
|
|
719
759
|
});
|
|
720
|
-
const actionResult = handleHandlerResult(
|
|
721
|
-
await routeEntry.handler(context),
|
|
722
|
-
);
|
|
760
|
+
const actionResult = handleHandlerResult(await handler(context));
|
|
723
761
|
doneHandler();
|
|
724
762
|
return {
|
|
725
763
|
content: Promise.resolve(actionResult),
|
|
@@ -835,6 +873,7 @@ export async function resolveSegmentWithRevalidation<TEnv>(
|
|
|
835
873
|
deps,
|
|
836
874
|
actionContext,
|
|
837
875
|
stale,
|
|
876
|
+
entry,
|
|
838
877
|
);
|
|
839
878
|
segments.push(...orphanResult.segments);
|
|
840
879
|
matchedIds.push(...orphanResult.matchedIds);
|
|
@@ -946,6 +985,8 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
|
|
|
946
985
|
deps: SegmentResolutionDeps<TEnv>,
|
|
947
986
|
actionContext?: ActionContext,
|
|
948
987
|
stale?: boolean,
|
|
988
|
+
/** Parent route entry — its loaders are inherited so parallel slots can access them. */
|
|
989
|
+
parentRouteEntry?: EntryData,
|
|
949
990
|
): Promise<SegmentRevalidationResult> {
|
|
950
991
|
invariant(
|
|
951
992
|
orphan.type === "layout" || orphan.type === "cache",
|
|
@@ -973,6 +1014,37 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
|
|
|
973
1014
|
segments.push(...loaderResult.segments);
|
|
974
1015
|
matchedIds.push(...loaderResult.matchedIds);
|
|
975
1016
|
|
|
1017
|
+
// Inherit parent route's loaders so parallel slots inside this layout
|
|
1018
|
+
// can access them via useLoader(). See resolveOrphanLayout in fresh.ts.
|
|
1019
|
+
if (
|
|
1020
|
+
parentRouteEntry &&
|
|
1021
|
+
parentRouteEntry.loader &&
|
|
1022
|
+
parentRouteEntry.loader.length > 0 &&
|
|
1023
|
+
Object.keys(orphan.parallel).length > 0
|
|
1024
|
+
) {
|
|
1025
|
+
const inheritedResult = await resolveLoadersWithRevalidation(
|
|
1026
|
+
parentRouteEntry,
|
|
1027
|
+
context,
|
|
1028
|
+
belongsToRoute,
|
|
1029
|
+
clientSegmentIds,
|
|
1030
|
+
prevParams,
|
|
1031
|
+
request,
|
|
1032
|
+
prevUrl,
|
|
1033
|
+
nextUrl,
|
|
1034
|
+
routeKey,
|
|
1035
|
+
deps,
|
|
1036
|
+
actionContext,
|
|
1037
|
+
orphan.shortCode,
|
|
1038
|
+
stale,
|
|
1039
|
+
);
|
|
1040
|
+
// Tag as inherited so buildMatchResult can deduplicate when safe
|
|
1041
|
+
for (const s of inheritedResult.segments) {
|
|
1042
|
+
s._inherited = true;
|
|
1043
|
+
}
|
|
1044
|
+
segments.push(...inheritedResult.segments);
|
|
1045
|
+
matchedIds.push(...inheritedResult.matchedIds);
|
|
1046
|
+
}
|
|
1047
|
+
|
|
976
1048
|
// Handler-first: resolve orphan layout handler before its parallels
|
|
977
1049
|
// so ctx.set() values are visible to parallel children.
|
|
978
1050
|
matchedIds.push(orphan.shortCode);
|
|
@@ -1059,6 +1131,7 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
|
|
|
1059
1131
|
);
|
|
1060
1132
|
|
|
1061
1133
|
if (!resolvedParallelEntries.has(parallelEntry.id)) {
|
|
1134
|
+
// shortCodeOverride must match the parent layout, not the parallel entry.
|
|
1062
1135
|
const loaderResult = await resolveLoadersWithRevalidation(
|
|
1063
1136
|
parallelEntry,
|
|
1064
1137
|
context,
|
|
@@ -1071,7 +1144,7 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
|
|
|
1071
1144
|
routeKey,
|
|
1072
1145
|
deps,
|
|
1073
1146
|
actionContext,
|
|
1074
|
-
|
|
1147
|
+
orphan.shortCode,
|
|
1075
1148
|
stale,
|
|
1076
1149
|
);
|
|
1077
1150
|
segments.push(...loaderResult.segments);
|
package/src/router.ts
CHANGED
|
@@ -625,6 +625,8 @@ export function createRouter<TEnv = any>(
|
|
|
625
625
|
params: Record<string, string>,
|
|
626
626
|
buildVars?: Record<string, any>,
|
|
627
627
|
isPassthroughRoute?: boolean,
|
|
628
|
+
buildEnv?: TEnv,
|
|
629
|
+
devMode?: boolean,
|
|
628
630
|
) {
|
|
629
631
|
return _matchForPrerender(
|
|
630
632
|
pathname,
|
|
@@ -632,6 +634,8 @@ export function createRouter<TEnv = any>(
|
|
|
632
634
|
prerenderDeps,
|
|
633
635
|
buildVars,
|
|
634
636
|
isPassthroughRoute,
|
|
637
|
+
buildEnv,
|
|
638
|
+
devMode,
|
|
635
639
|
);
|
|
636
640
|
}
|
|
637
641
|
|
|
@@ -639,12 +643,16 @@ export function createRouter<TEnv = any>(
|
|
|
639
643
|
handler: Function,
|
|
640
644
|
handlerId: string,
|
|
641
645
|
routeName?: string,
|
|
646
|
+
buildEnv?: TEnv,
|
|
647
|
+
devMode?: boolean,
|
|
642
648
|
) {
|
|
643
649
|
return _renderStaticSegment<TEnv>(
|
|
644
650
|
handler,
|
|
645
651
|
handlerId,
|
|
646
652
|
mergedRouteMap,
|
|
647
653
|
routeName,
|
|
654
|
+
buildEnv,
|
|
655
|
+
devMode,
|
|
648
656
|
);
|
|
649
657
|
}
|
|
650
658
|
|
|
@@ -748,7 +756,7 @@ export function createRouter<TEnv = any>(
|
|
|
748
756
|
if (entry.type === "route" && entry.isPrerender) {
|
|
749
757
|
if (!prerenderRouteKeys) prerenderRouteKeys = new Set();
|
|
750
758
|
prerenderRouteKeys.add(name);
|
|
751
|
-
if (entry.
|
|
759
|
+
if (entry.isPassthrough === true) {
|
|
752
760
|
if (!passthroughRouteKeys) passthroughRouteKeys = new Set();
|
|
753
761
|
passthroughRouteKeys.add(name);
|
|
754
762
|
}
|
|
@@ -1025,6 +1033,10 @@ export function createRouter<TEnv = any>(
|
|
|
1025
1033
|
};
|
|
1026
1034
|
})(),
|
|
1027
1035
|
|
|
1036
|
+
// Low-level route matching for request classification
|
|
1037
|
+
findMatch: (pathname: string, metricsStore?: any) =>
|
|
1038
|
+
findMatch(pathname, metricsStore),
|
|
1039
|
+
|
|
1028
1040
|
// Debug utility for manifest inspection
|
|
1029
1041
|
debugManifest: () => buildDebugManifest<TEnv>(routesEntries),
|
|
1030
1042
|
};
|