@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.
Files changed (93) hide show
  1. package/README.md +76 -18
  2. package/dist/bin/rango.js +2 -1
  3. package/dist/vite/index.js +507 -192
  4. package/dist/vite/index.js.bak +5448 -0
  5. package/package.json +3 -3
  6. package/skills/handler-use/SKILL.md +362 -0
  7. package/skills/intercept/SKILL.md +20 -0
  8. package/skills/layout/SKILL.md +22 -0
  9. package/skills/middleware/SKILL.md +32 -3
  10. package/skills/migrate-nextjs/SKILL.md +560 -0
  11. package/skills/migrate-react-router/SKILL.md +764 -0
  12. package/skills/parallel/SKILL.md +59 -0
  13. package/skills/prerender/SKILL.md +110 -68
  14. package/skills/rango/SKILL.md +24 -22
  15. package/skills/route/SKILL.md +24 -0
  16. package/src/__internal.ts +1 -1
  17. package/src/browser/navigation-bridge.ts +21 -2
  18. package/src/browser/navigation-client.ts +34 -6
  19. package/src/browser/partial-update.ts +14 -2
  20. package/src/browser/prefetch/cache.ts +16 -6
  21. package/src/browser/prefetch/fetch.ts +60 -4
  22. package/src/browser/react/Link.tsx +25 -2
  23. package/src/browser/react/use-handle.ts +9 -58
  24. package/src/browser/scroll-restoration.ts +10 -8
  25. package/src/browser/segment-reconciler.ts +36 -14
  26. package/src/build/generate-manifest.ts +3 -6
  27. package/src/build/route-trie.ts +50 -24
  28. package/src/build/route-types/scan-filter.ts +8 -1
  29. package/src/client.tsx +84 -230
  30. package/src/handle.ts +40 -0
  31. package/src/index.rsc.ts +3 -1
  32. package/src/index.ts +46 -6
  33. package/src/prerender/store.ts +5 -4
  34. package/src/prerender.ts +138 -77
  35. package/src/reverse.ts +25 -1
  36. package/src/route-definition/dsl-helpers.ts +194 -32
  37. package/src/route-definition/helpers-types.ts +61 -14
  38. package/src/route-definition/index.ts +3 -0
  39. package/src/route-definition/resolve-handler-use.ts +149 -0
  40. package/src/route-types.ts +18 -0
  41. package/src/router/content-negotiation.ts +100 -1
  42. package/src/router/handler-context.ts +46 -6
  43. package/src/router/lazy-includes.ts +5 -5
  44. package/src/router/loader-resolution.ts +147 -19
  45. package/src/router/manifest.ts +12 -7
  46. package/src/router/match-api.ts +124 -189
  47. package/src/router/match-middleware/cache-lookup.ts +24 -7
  48. package/src/router/match-middleware/segment-resolution.ts +53 -0
  49. package/src/router/match-result.ts +82 -4
  50. package/src/router/navigation-snapshot.ts +182 -0
  51. package/src/router/prerender-match.ts +108 -8
  52. package/src/router/preview-match.ts +30 -102
  53. package/src/router/request-classification.ts +310 -0
  54. package/src/router/route-snapshot.ts +245 -0
  55. package/src/router/router-interfaces.ts +11 -0
  56. package/src/router/segment-resolution/fresh.ts +59 -2
  57. package/src/router/segment-resolution/revalidation.ts +79 -6
  58. package/src/router.ts +13 -1
  59. package/src/rsc/handler.ts +468 -377
  60. package/src/rsc/loader-fetch.ts +23 -3
  61. package/src/rsc/progressive-enhancement.ts +10 -2
  62. package/src/rsc/rsc-rendering.ts +5 -1
  63. package/src/rsc/server-action.ts +6 -0
  64. package/src/rsc/ssr-setup.ts +1 -1
  65. package/src/rsc/types.ts +1 -0
  66. package/src/segment-content-promise.ts +67 -0
  67. package/src/segment-loader-promise.ts +122 -0
  68. package/src/segment-system.tsx +11 -61
  69. package/src/server/context.ts +40 -4
  70. package/src/server/handle-store.ts +19 -0
  71. package/src/server/request-context.ts +125 -3
  72. package/src/static-handler.ts +18 -6
  73. package/src/types/handler-context.ts +12 -2
  74. package/src/types/loader-types.ts +32 -4
  75. package/src/types/route-entry.ts +12 -1
  76. package/src/types/segments.ts +1 -1
  77. package/src/urls/include-helper.ts +24 -14
  78. package/src/urls/path-helper-types.ts +39 -6
  79. package/src/urls/path-helper.ts +47 -12
  80. package/src/urls/response-types.ts +16 -6
  81. package/src/use-loader.tsx +77 -5
  82. package/src/vite/discovery/bundle-postprocess.ts +30 -33
  83. package/src/vite/discovery/prerender-collection.ts +128 -74
  84. package/src/vite/discovery/state.ts +13 -4
  85. package/src/vite/index.ts +4 -0
  86. package/src/vite/plugin-types.ts +60 -5
  87. package/src/vite/plugins/expose-id-utils.ts +12 -0
  88. package/src/vite/plugins/expose-ids/handler-transform.ts +30 -0
  89. package/src/vite/plugins/expose-internal-ids.ts +257 -40
  90. package/src/vite/plugins/refresh-cmd.ts +88 -26
  91. package/src/vite/rango.ts +2 -1
  92. package/src/vite/router-discovery.ts +178 -37
  93. 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 routeEntry.handler(context));
732
+ const result = handleHandlerResult(await handler(context));
693
733
  doneHandler();
694
734
  return result;
695
735
  }
696
736
  if (!actionContext) {
697
- const result = handleHandlerResult(routeEntry.handler(context));
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
- undefined,
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.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
  };