@rangojs/router 0.0.0-experimental.62 → 0.0.0-experimental.64

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.
Files changed (50) hide show
  1. package/README.md +61 -8
  2. package/dist/bin/rango.js +2 -1
  3. package/dist/vite/index.js +142 -62
  4. package/dist/vite/index.js.bak +5448 -0
  5. package/package.json +14 -15
  6. package/skills/prerender/SKILL.md +110 -68
  7. package/src/__internal.ts +1 -1
  8. package/src/build/generate-manifest.ts +3 -6
  9. package/src/build/route-types/scan-filter.ts +8 -1
  10. package/src/client.tsx +2 -56
  11. package/src/index.rsc.ts +3 -1
  12. package/src/index.ts +8 -0
  13. package/src/prerender/store.ts +5 -4
  14. package/src/prerender.ts +138 -77
  15. package/src/route-definition/dsl-helpers.ts +42 -19
  16. package/src/route-definition/helpers-types.ts +4 -1
  17. package/src/route-definition/index.ts +3 -0
  18. package/src/route-definition/resolve-handler-use.ts +149 -0
  19. package/src/route-types.ts +11 -0
  20. package/src/router/content-negotiation.ts +100 -1
  21. package/src/router/handler-context.ts +20 -5
  22. package/src/router/match-api.ts +124 -189
  23. package/src/router/match-middleware/cache-lookup.ts +2 -6
  24. package/src/router/navigation-snapshot.ts +182 -0
  25. package/src/router/prerender-match.ts +104 -8
  26. package/src/router/preview-match.ts +30 -102
  27. package/src/router/request-classification.ts +310 -0
  28. package/src/router/route-snapshot.ts +245 -0
  29. package/src/router/router-interfaces.ts +11 -0
  30. package/src/router/segment-resolution/fresh.ts +44 -2
  31. package/src/router/segment-resolution/revalidation.ts +53 -5
  32. package/src/router.ts +13 -1
  33. package/src/rsc/handler.ts +456 -373
  34. package/src/rsc/ssr-setup.ts +1 -1
  35. package/src/server/context.ts +5 -1
  36. package/src/server/request-context.ts +7 -0
  37. package/src/static-handler.ts +18 -6
  38. package/src/types/handler-context.ts +12 -2
  39. package/src/types/route-entry.ts +1 -1
  40. package/src/urls/path-helper-types.ts +9 -2
  41. package/src/urls/path-helper.ts +47 -12
  42. package/src/urls/response-types.ts +16 -6
  43. package/src/use-loader.tsx +73 -4
  44. package/src/vite/discovery/bundle-postprocess.ts +30 -33
  45. package/src/vite/discovery/prerender-collection.ts +14 -1
  46. package/src/vite/discovery/state.ts +13 -4
  47. package/src/vite/index.ts +4 -0
  48. package/src/vite/plugin-types.ts +60 -5
  49. package/src/vite/rango.ts +2 -1
  50. package/src/vite/router-discovery.ts +153 -34
@@ -319,6 +319,19 @@ 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
+ if (
324
+ entry.type === "route" &&
325
+ entry.loader &&
326
+ entry.loader.length > 0 &&
327
+ Object.keys(layoutEntry.parallel).length > 0
328
+ ) {
329
+ await collectEntryLoaders(
330
+ entry,
331
+ childBelongsToRoute,
332
+ layoutEntry.shortCode,
333
+ );
334
+ }
322
335
  }
323
336
  }
324
337
 
@@ -688,13 +701,20 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
688
701
  return staticComponent;
689
702
  }
690
703
  const routeEntry = entry as Extract<EntryData, { type: "route" }>;
704
+ // For Passthrough routes at runtime, use the live handler instead of
705
+ // the build handler. At build time (context.build === true), always
706
+ // use the build handler from routeEntry.handler.
707
+ const handler =
708
+ !context.build && routeEntry.liveHandler
709
+ ? routeEntry.liveHandler
710
+ : routeEntry.handler;
691
711
  if (!routeEntry.loading) {
692
- const result = handleHandlerResult(await routeEntry.handler(context));
712
+ const result = handleHandlerResult(await handler(context));
693
713
  doneHandler();
694
714
  return result;
695
715
  }
696
716
  if (!actionContext) {
697
- const result = handleHandlerResult(routeEntry.handler(context));
717
+ const result = handleHandlerResult(handler(context));
698
718
  if (result instanceof Promise) {
699
719
  result.finally(doneHandler).catch(() => {});
700
720
  const tracked = deps.trackHandler(result, {
@@ -717,9 +737,7 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
717
737
  debugLog("segment.action", "resolving action route with awaited value", {
718
738
  entryId: entry.id,
719
739
  });
720
- const actionResult = handleHandlerResult(
721
- await routeEntry.handler(context),
722
- );
740
+ const actionResult = handleHandlerResult(await handler(context));
723
741
  doneHandler();
724
742
  return {
725
743
  content: Promise.resolve(actionResult),
@@ -835,6 +853,7 @@ export async function resolveSegmentWithRevalidation<TEnv>(
835
853
  deps,
836
854
  actionContext,
837
855
  stale,
856
+ entry,
838
857
  );
839
858
  segments.push(...orphanResult.segments);
840
859
  matchedIds.push(...orphanResult.matchedIds);
@@ -946,6 +965,8 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
946
965
  deps: SegmentResolutionDeps<TEnv>,
947
966
  actionContext?: ActionContext,
948
967
  stale?: boolean,
968
+ /** Parent route entry — its loaders are inherited so parallel slots can access them. */
969
+ parentRouteEntry?: EntryData,
949
970
  ): Promise<SegmentRevalidationResult> {
950
971
  invariant(
951
972
  orphan.type === "layout" || orphan.type === "cache",
@@ -973,6 +994,33 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
973
994
  segments.push(...loaderResult.segments);
974
995
  matchedIds.push(...loaderResult.matchedIds);
975
996
 
997
+ // Inherit parent route's loaders so parallel slots inside this layout
998
+ // can access them via useLoader(). See resolveOrphanLayout in fresh.ts.
999
+ if (
1000
+ parentRouteEntry &&
1001
+ parentRouteEntry.loader &&
1002
+ parentRouteEntry.loader.length > 0 &&
1003
+ Object.keys(orphan.parallel).length > 0
1004
+ ) {
1005
+ const inheritedResult = await resolveLoadersWithRevalidation(
1006
+ parentRouteEntry,
1007
+ context,
1008
+ belongsToRoute,
1009
+ clientSegmentIds,
1010
+ prevParams,
1011
+ request,
1012
+ prevUrl,
1013
+ nextUrl,
1014
+ routeKey,
1015
+ deps,
1016
+ actionContext,
1017
+ orphan.shortCode,
1018
+ stale,
1019
+ );
1020
+ segments.push(...inheritedResult.segments);
1021
+ matchedIds.push(...inheritedResult.matchedIds);
1022
+ }
1023
+
976
1024
  // Handler-first: resolve orphan layout handler before its parallels
977
1025
  // so ctx.set() values are visible to parallel children.
978
1026
  matchedIds.push(orphan.shortCode);
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.prerenderDef?.options?.passthrough === true) {
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
  };