@rangojs/router 0.0.0-experimental.61 → 0.0.0-experimental.63

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 (41) hide show
  1. package/README.md +61 -8
  2. package/dist/bin/rango.js +2 -1
  3. package/dist/vite/index.js +144 -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/index.rsc.ts +3 -1
  11. package/src/index.ts +8 -0
  12. package/src/prerender/store.ts +5 -4
  13. package/src/prerender.ts +138 -77
  14. package/src/reverse.ts +2 -0
  15. package/src/route-definition/dsl-helpers.ts +37 -18
  16. package/src/route-definition/index.ts +3 -0
  17. package/src/route-definition/resolve-handler-use.ts +149 -0
  18. package/src/route-types.ts +11 -0
  19. package/src/router/handler-context.ts +22 -5
  20. package/src/router/match-api.ts +2 -8
  21. package/src/router/match-middleware/cache-lookup.ts +2 -6
  22. package/src/router/prerender-match.ts +104 -8
  23. package/src/router/router-interfaces.ts +4 -0
  24. package/src/router/segment-resolution/fresh.ts +7 -2
  25. package/src/router/segment-resolution/revalidation.ts +10 -5
  26. package/src/router.ts +9 -1
  27. package/src/server/context.ts +5 -1
  28. package/src/static-handler.ts +18 -6
  29. package/src/types/handler-context.ts +12 -2
  30. package/src/types/route-entry.ts +1 -1
  31. package/src/urls/path-helper-types.ts +5 -1
  32. package/src/urls/path-helper.ts +47 -12
  33. package/src/urls/response-types.ts +16 -6
  34. package/src/vite/discovery/bundle-postprocess.ts +30 -33
  35. package/src/vite/discovery/prerender-collection.ts +14 -1
  36. package/src/vite/discovery/state.ts +13 -4
  37. package/src/vite/index.ts +4 -0
  38. package/src/vite/plugin-types.ts +60 -5
  39. package/src/vite/rango.ts +2 -1
  40. package/src/vite/router-discovery.ts +153 -34
  41. package/src/vite/utils/prerender-utils.ts +2 -0
package/README.md CHANGED
@@ -716,10 +716,12 @@ export const BlogPost = Prerender(
716
716
 
717
717
  ### Passthrough for Unknown Params
718
718
 
719
+ Wrap a `Prerender` definition with `Passthrough()` to add a live handler for unknown params at runtime. The build handler runs at build time, the live handler runs at request time for params not in the prerender cache.
720
+
719
721
  ```tsx
720
- import { Prerender } from "@rangojs/router";
722
+ import { Prerender, Passthrough } from "@rangojs/router";
721
723
 
722
- export const ProductPage = Prerender(
724
+ export const ProductPageDef = Prerender(
723
725
  async () => {
724
726
  const featured = await db.getFeaturedProducts();
725
727
  return featured.map((p) => ({ id: p.id }));
@@ -728,16 +730,22 @@ export const ProductPage = Prerender(
728
730
  const product = await db.getProduct(ctx.params.id);
729
731
  return <Product data={product} />;
730
732
  },
731
- { passthrough: true },
732
733
  );
733
- ```
734
734
 
735
- With `passthrough: true`, known params are served from the build-time cache and unknown params fall through to live rendering.
735
+ // In route definition:
736
+ path(
737
+ "/products/:id",
738
+ Passthrough(ProductPageDef, async (ctx) => {
739
+ const product = await ctx.env.DB.getProduct(ctx.params.id);
740
+ return <Product data={product} />;
741
+ }),
742
+ );
743
+ ```
736
744
 
737
- Handlers can also skip individual param sets with `ctx.passthrough()`, deferring them to the live handler at runtime:
745
+ Build handlers can also skip individual param sets with `ctx.passthrough()`, deferring them to the live handler:
738
746
 
739
747
  ```tsx
740
- export const ProductPage = Prerender(
748
+ export const ProductPageDef = Prerender(
741
749
  async () => {
742
750
  const all = await db.getAllProducts();
743
751
  return all.map((p) => ({ id: p.id }));
@@ -747,10 +755,55 @@ export const ProductPage = Prerender(
747
755
  if (!product.published) return ctx.passthrough();
748
756
  return <Product data={product} />;
749
757
  },
750
- { passthrough: true },
751
758
  );
752
759
  ```
753
760
 
761
+ ### Build-Time Environment Bindings
762
+
763
+ Prerender handlers can access platform bindings (KV, D1, R2) at build time when `buildEnv` is configured in the Vite plugin:
764
+
765
+ ```ts
766
+ // vite.config.ts
767
+ import { rango } from "@rangojs/router/vite";
768
+
769
+ rango({ preset: "cloudflare", buildEnv: "auto" });
770
+ ```
771
+
772
+ With `buildEnv: "auto"`, the plugin calls `wrangler.getPlatformProxy()` to provide local bindings. Handlers then access `ctx.env` during build:
773
+
774
+ ```tsx
775
+ export const BlogPosts = Prerender<{ slug: string }>(
776
+ async (ctx) => {
777
+ const rows = await ctx.env.DB.prepare("SELECT slug FROM posts").all();
778
+ return rows.map((r) => ({ slug: r.slug }));
779
+ },
780
+ async (ctx) => {
781
+ const post = await ctx.env.DB.prepare("SELECT * FROM posts WHERE slug = ?")
782
+ .bind(ctx.params.slug)
783
+ .first();
784
+ return <BlogPost post={post} />;
785
+ },
786
+ );
787
+ ```
788
+
789
+ `buildEnv` also accepts a factory function or plain object:
790
+
791
+ ```ts
792
+ // Custom factory
793
+ rango({
794
+ buildEnv: async (ctx) => {
795
+ const { getPlatformProxy } = await import("wrangler");
796
+ const proxy = await getPlatformProxy();
797
+ return { env: proxy.env, dispose: proxy.dispose };
798
+ },
799
+ });
800
+
801
+ // Plain object (Node.js)
802
+ rango({ buildEnv: { DATABASE_URL: process.env.DATABASE_URL } });
803
+ ```
804
+
805
+ Build-time env applies to both production builds and dev on-demand prerender. Without `buildEnv`, accessing `ctx.env` in a Prerender handler throws with a clear error.
806
+
754
807
  ## Theme
755
808
 
756
809
  ### Router Configuration
package/dist/bin/rango.js CHANGED
@@ -218,7 +218,8 @@ function findTsFiles(dir, filter) {
218
218
  for (const entry of entries) {
219
219
  const fullPath = join(dir, entry.name);
220
220
  if (entry.isDirectory()) {
221
- if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
221
+ if (entry.name === "node_modules" || entry.name.startsWith(".") || entry.name === "dist" || entry.name === "build" || entry.name === "coverage")
222
+ continue;
222
223
  results.push(...findTsFiles(fullPath, filter));
223
224
  } else if ((entry.name.endsWith(".ts") || entry.name.endsWith(".tsx") || entry.name.endsWith(".js") || entry.name.endsWith(".jsx")) && !entry.name.includes(".gen.")) {
224
225
  if (filter && !filter(fullPath)) continue;
@@ -1745,7 +1745,7 @@ import { resolve } from "node:path";
1745
1745
  // package.json
1746
1746
  var package_default = {
1747
1747
  name: "@rangojs/router",
1748
- version: "0.0.0-experimental.61",
1748
+ version: "0.0.0-experimental.63",
1749
1749
  description: "Django-inspired RSC router with composable URL patterns",
1750
1750
  keywords: [
1751
1751
  "react",
@@ -3141,6 +3141,8 @@ function createCjsToEsmPlugin() {
3141
3141
  import { createServer as createViteServer } from "vite";
3142
3142
  import { resolve as resolve8 } from "node:path";
3143
3143
  import { readFileSync as readFileSync6 } from "node:fs";
3144
+ import { createRequire } from "node:module";
3145
+ import { pathToFileURL } from "node:url";
3144
3146
 
3145
3147
  // src/vite/plugins/virtual-stub-plugin.ts
3146
3148
  function createVirtualStubPlugin() {
@@ -3324,8 +3326,8 @@ function createDiscoveryState(entryPath, opts) {
3324
3326
  perRouterManifestDataMap: /* @__PURE__ */ new Map(),
3325
3327
  prerenderManifestEntries: null,
3326
3328
  staticManifestEntries: null,
3327
- handlerChunkInfo: null,
3328
- staticHandlerChunkInfo: null,
3329
+ handlerChunkInfoMap: /* @__PURE__ */ new Map(),
3330
+ staticHandlerChunkInfoMap: /* @__PURE__ */ new Map(),
3329
3331
  rscEntryFileName: null,
3330
3332
  resolvedPrerenderModules: void 0,
3331
3333
  resolvedStaticModules: void 0,
@@ -3470,7 +3472,9 @@ function substituteRouteParams(pattern, params, encode = encodeURIComponent) {
3470
3472
  return "";
3471
3473
  });
3472
3474
  if (hadOmittedOptional) {
3475
+ const hadTrailingSlash = pattern.length > 1 && pattern.endsWith("/");
3473
3476
  result = result.replace(/\/\/+/g, "/").replace(/\/+$/, "") || "/";
3477
+ if (hadTrailingSlash && !result.endsWith("/")) result += "/";
3474
3478
  }
3475
3479
  return result;
3476
3480
  }
@@ -3583,11 +3587,12 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3583
3587
  for (const { manifest } of allManifests) {
3584
3588
  if (!manifest.prerenderRoutes) continue;
3585
3589
  const defs = manifest._prerenderDefs || {};
3590
+ const passthroughSet = new Set(manifest.passthroughRoutes || []);
3586
3591
  for (const routeName of manifest.prerenderRoutes) {
3587
3592
  const pattern = manifest.routeManifest[routeName];
3588
3593
  if (!pattern) continue;
3589
3594
  const def = defs[routeName];
3590
- const isPassthroughRoute = !!def?.options?.passthrough;
3595
+ const isPassthroughRoute = passthroughSet.has(routeName);
3591
3596
  const hasDynamic = pattern.includes(":") || pattern.includes("*");
3592
3597
  if (!hasDynamic) {
3593
3598
  entries.push({
@@ -3600,12 +3605,20 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3600
3605
  if (def?.getParams) {
3601
3606
  try {
3602
3607
  const buildVars = {};
3608
+ const buildEnv = state.resolvedBuildEnv;
3603
3609
  const getParamsCtx = {
3604
3610
  build: true,
3611
+ dev: !state.isBuildMode,
3605
3612
  set: ((keyOrVar, value) => {
3606
3613
  contextSet(buildVars, keyOrVar, value);
3607
3614
  }),
3608
- reverse: getParamsReverse
3615
+ reverse: getParamsReverse,
3616
+ get env() {
3617
+ if (buildEnv !== void 0) return buildEnv;
3618
+ throw new Error(
3619
+ "[rsc-router] ctx.env is not available during build-time getParams(). Configure buildEnv in your rango() plugin options to enable build-time env access."
3620
+ );
3621
+ }
3609
3622
  };
3610
3623
  const paramsList = await def.getParams(getParamsCtx);
3611
3624
  const concurrency = def.options?.concurrency ?? 1;
@@ -3684,7 +3697,8 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
3684
3697
  entry.urlPath,
3685
3698
  {},
3686
3699
  entry.buildVars,
3687
- entry.isPassthroughRoute
3700
+ entry.isPassthroughRoute,
3701
+ state.resolvedBuildEnv
3688
3702
  );
3689
3703
  if (!result) continue;
3690
3704
  if (result.passthrough) {
@@ -3808,7 +3822,9 @@ async function renderStaticHandlers(state, rscEnv, registry) {
3808
3822
  const result = await routerInstance.renderStaticSegment(
3809
3823
  def.handler,
3810
3824
  def.$$id,
3811
- def.$$routePrefix
3825
+ def.$$routePrefix,
3826
+ state.resolvedBuildEnv,
3827
+ !state.isBuildMode
3812
3828
  );
3813
3829
  if (result) {
3814
3830
  const hasHandles = Object.keys(result.handles).length > 0;
@@ -4386,48 +4402,45 @@ function postprocessBundle(state) {
4386
4402
  );
4387
4403
  const evictionTargets = [
4388
4404
  {
4389
- info: state.handlerChunkInfo,
4405
+ infos: state.handlerChunkInfoMap.values(),
4390
4406
  fnName: "Prerender",
4391
4407
  brand: "prerenderHandler",
4392
4408
  label: "handler code from RSC bundle"
4393
4409
  },
4394
4410
  {
4395
- info: state.staticHandlerChunkInfo,
4411
+ infos: state.staticHandlerChunkInfoMap.values(),
4396
4412
  fnName: "Static",
4397
4413
  brand: "staticHandler",
4398
4414
  label: "static handler code"
4399
4415
  }
4400
4416
  ];
4401
4417
  for (const target of evictionTargets) {
4402
- if (!target.info) continue;
4403
- const chunkPath = resolve7(
4404
- state.projectRoot,
4405
- "dist/rsc",
4406
- target.info.fileName
4407
- );
4408
- try {
4409
- const code = readFileSync5(chunkPath, "utf-8");
4410
- const result = evictHandlerCode(
4411
- code,
4412
- target.info.exports,
4413
- target.fnName,
4414
- target.brand
4415
- );
4416
- if (result) {
4417
- writeFileSync4(chunkPath, result.code);
4418
- const savedKB = (result.savedBytes / 1024).toFixed(1);
4419
- console.log(
4420
- `[rsc-router] Evicted ${target.label} (${savedKB} KB saved): ${target.info.fileName}`
4418
+ for (const info of target.infos) {
4419
+ const chunkPath = resolve7(state.projectRoot, "dist/rsc", info.fileName);
4420
+ try {
4421
+ const code = readFileSync5(chunkPath, "utf-8");
4422
+ const result = evictHandlerCode(
4423
+ code,
4424
+ info.exports,
4425
+ target.fnName,
4426
+ target.brand
4427
+ );
4428
+ if (result) {
4429
+ writeFileSync4(chunkPath, result.code);
4430
+ const savedKB = (result.savedBytes / 1024).toFixed(1);
4431
+ console.log(
4432
+ `[rsc-router] Evicted ${target.label} (${savedKB} KB saved): ${info.fileName}`
4433
+ );
4434
+ }
4435
+ } catch (replaceErr) {
4436
+ console.warn(
4437
+ `[rsc-router] Failed to evict ${target.label}: ${replaceErr.message}`
4421
4438
  );
4422
4439
  }
4423
- } catch (replaceErr) {
4424
- console.warn(
4425
- `[rsc-router] Failed to evict ${target.label}: ${replaceErr.message}`
4426
- );
4427
4440
  }
4428
4441
  }
4429
- state.handlerChunkInfo = null;
4430
- state.staticHandlerChunkInfo = null;
4442
+ state.handlerChunkInfoMap.clear();
4443
+ state.staticHandlerChunkInfoMap.clear();
4431
4444
  if (hasPrerenderData && existsSync6(rscEntryPath)) {
4432
4445
  const rscCode = readFileSync5(rscEntryPath, "utf-8");
4433
4446
  if (!rscCode.includes("__prerender-manifest.js")) {
@@ -4470,7 +4483,7 @@ function postprocessBundle(state) {
4470
4483
  }
4471
4484
  if (hasStaticData && existsSync6(rscEntryPath)) {
4472
4485
  const rscCode = readFileSync5(rscEntryPath, "utf-8");
4473
- if (!rscCode.includes("__STATIC_MANIFEST")) {
4486
+ if (!rscCode.includes("__static-manifest.js")) {
4474
4487
  try {
4475
4488
  const manifestEntries = [];
4476
4489
  let totalBytes = copyStagedBuildAssets(
@@ -4539,8 +4552,67 @@ async function createTempRscServer(state, options = {}) {
4539
4552
  ]
4540
4553
  });
4541
4554
  }
4555
+ async function resolveBuildEnv(option, factoryCtx) {
4556
+ if (!option) return null;
4557
+ if (option === "auto") {
4558
+ if (factoryCtx.preset !== "cloudflare") {
4559
+ throw new Error(
4560
+ '[rsc-router] buildEnv: "auto" is only supported with preset: "cloudflare". Use a factory function or plain object for other presets.'
4561
+ );
4562
+ }
4563
+ try {
4564
+ const userRequire = createRequire(
4565
+ resolve8(factoryCtx.root, "package.json")
4566
+ );
4567
+ const wranglerPath = userRequire.resolve("wrangler");
4568
+ const { getPlatformProxy } = await import(pathToFileURL(wranglerPath).href);
4569
+ const proxy = await getPlatformProxy();
4570
+ return {
4571
+ env: proxy.env,
4572
+ dispose: proxy.dispose
4573
+ };
4574
+ } catch (err) {
4575
+ throw new Error(
4576
+ `[rsc-router] buildEnv: "auto" requires wrangler to be installed.
4577
+ Install it with: pnpm add -D wrangler
4578
+ ${err.message}`
4579
+ );
4580
+ }
4581
+ }
4582
+ if (typeof option === "function") {
4583
+ return await option(factoryCtx);
4584
+ }
4585
+ return { env: option };
4586
+ }
4587
+ async function acquireBuildEnv(s, command, mode) {
4588
+ const option = s.opts?.buildEnv;
4589
+ if (!option) return false;
4590
+ const result = await resolveBuildEnv(option, {
4591
+ root: s.projectRoot,
4592
+ mode,
4593
+ command,
4594
+ preset: s.opts?.preset ?? "node"
4595
+ });
4596
+ if (!result) return false;
4597
+ s.resolvedBuildEnv = result.env;
4598
+ s.buildEnvDispose = result.dispose ?? null;
4599
+ return true;
4600
+ }
4601
+ async function releaseBuildEnv(s) {
4602
+ if (s.buildEnvDispose) {
4603
+ try {
4604
+ await s.buildEnvDispose();
4605
+ } catch (err) {
4606
+ console.warn(`[rsc-router] buildEnv dispose failed: ${err.message}`);
4607
+ }
4608
+ s.buildEnvDispose = null;
4609
+ }
4610
+ s.resolvedBuildEnv = void 0;
4611
+ }
4542
4612
  function createRouterDiscoveryPlugin(entryPath, opts) {
4543
4613
  const s = createDiscoveryState(entryPath, opts);
4614
+ let viteCommand = "build";
4615
+ let viteMode = "production";
4544
4616
  return {
4545
4617
  name: "@rangojs/router:discovery",
4546
4618
  config() {
@@ -4549,31 +4621,13 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
4549
4621
  __RANGO_DEBUG__: JSON.stringify(!!process.env.INTERNAL_RANGO_DEBUG)
4550
4622
  }
4551
4623
  };
4552
- if (opts?.enableBuildPrerender) {
4553
- config.environments = {
4554
- rsc: {
4555
- build: {
4556
- rollupOptions: {
4557
- output: {
4558
- manualChunks(id) {
4559
- if (s.resolvedPrerenderModules?.has(id)) {
4560
- return "__prerender-handlers";
4561
- }
4562
- if (s.resolvedStaticModules?.has(id)) {
4563
- return "__static-handlers";
4564
- }
4565
- }
4566
- }
4567
- }
4568
- }
4569
- }
4570
- };
4571
- }
4572
4624
  return config;
4573
4625
  },
4574
4626
  configResolved(config) {
4575
4627
  s.projectRoot = config.root;
4576
4628
  s.isBuildMode = config.command === "build";
4629
+ viteCommand = config.command;
4630
+ viteMode = config.mode;
4577
4631
  s.userResolveAlias = config.resolve.alias;
4578
4632
  if (!s.resolvedEntryPath && opts?.routerPathRef?.path) {
4579
4633
  s.resolvedEntryPath = opts.routerPathRef.path;
@@ -4618,6 +4672,8 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
4618
4672
  });
4619
4673
  prerenderTempServer = null;
4620
4674
  }
4675
+ releaseBuildEnv(s).catch(() => {
4676
+ });
4621
4677
  });
4622
4678
  async function getOrCreateTempServer() {
4623
4679
  if (prerenderNodeRegistry) {
@@ -4648,6 +4704,7 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
4648
4704
  if (!rscEnv?.runner) {
4649
4705
  s.devServerOrigin = getDevServerOrigin();
4650
4706
  try {
4707
+ await acquireBuildEnv(s, viteCommand, viteMode);
4651
4708
  const tempRscEnv = await getOrCreateTempServer();
4652
4709
  if (tempRscEnv) {
4653
4710
  await discoverRouters(s, tempRscEnv);
@@ -4663,6 +4720,7 @@ ${err.stack}`
4663
4720
  return;
4664
4721
  }
4665
4722
  try {
4723
+ await acquireBuildEnv(s, viteCommand, viteMode);
4666
4724
  const serverMod = await rscEnv.runner.import(
4667
4725
  "@rangojs/router/server"
4668
4726
  );
@@ -4749,7 +4807,10 @@ ${err.stack}`
4749
4807
  pathname,
4750
4808
  {},
4751
4809
  void 0,
4752
- wantPassthrough
4810
+ wantPassthrough,
4811
+ s.resolvedBuildEnv,
4812
+ true
4813
+ // devMode: check getParams for passthrough routes
4753
4814
  );
4754
4815
  if (!result) continue;
4755
4816
  if (result.passthrough) continue;
@@ -4885,6 +4946,7 @@ ${err.stack}`
4885
4946
  resetStagedBuildAssets(s.projectRoot);
4886
4947
  s.prerenderManifestEntries = null;
4887
4948
  s.staticManifestEntries = null;
4949
+ await acquireBuildEnv(s, viteCommand, viteMode);
4888
4950
  let tempServer = null;
4889
4951
  globalThis.__rscRouterDiscoveryActive = true;
4890
4952
  try {
@@ -4924,6 +4986,7 @@ ${details}`
4924
4986
  if (tempServer) {
4925
4987
  await tempServer.close();
4926
4988
  }
4989
+ await releaseBuildEnv(s);
4927
4990
  }
4928
4991
  },
4929
4992
  // Virtual module: provides the pre-generated route manifest as a JS module
@@ -4966,20 +5029,30 @@ ${details}`
4966
5029
  }
4967
5030
  if (!s.resolvedPrerenderModules?.size && !s.resolvedStaticModules?.size)
4968
5031
  return;
5032
+ s.handlerChunkInfoMap.clear();
5033
+ s.staticHandlerChunkInfoMap.clear();
4969
5034
  for (const [fileName, chunk] of Object.entries(bundle)) {
4970
5035
  if (chunk.type !== "chunk") continue;
4971
- if (fileName.includes("__prerender-handlers") && s.resolvedPrerenderModules?.size) {
5036
+ if (s.resolvedPrerenderModules?.size) {
4972
5037
  const handlers = extractHandlerExportsFromChunk(
4973
5038
  chunk.code,
4974
5039
  s.resolvedPrerenderModules,
4975
5040
  "Prerender",
4976
- true
5041
+ false
4977
5042
  );
4978
5043
  if (handlers.length > 0) {
4979
- s.handlerChunkInfo = { fileName, exports: handlers };
5044
+ const existing = s.handlerChunkInfoMap.get(fileName);
5045
+ if (existing) {
5046
+ existing.exports.push(...handlers);
5047
+ } else {
5048
+ s.handlerChunkInfoMap.set(fileName, {
5049
+ fileName,
5050
+ exports: handlers
5051
+ });
5052
+ }
4980
5053
  }
4981
5054
  }
4982
- if (fileName.includes("__static-handlers") && s.resolvedStaticModules?.size) {
5055
+ if (s.resolvedStaticModules?.size) {
4983
5056
  const handlers = extractHandlerExportsFromChunk(
4984
5057
  chunk.code,
4985
5058
  s.resolvedStaticModules,
@@ -4987,7 +5060,15 @@ ${details}`
4987
5060
  false
4988
5061
  );
4989
5062
  if (handlers.length > 0) {
4990
- s.staticHandlerChunkInfo = { fileName, exports: handlers };
5063
+ const existing = s.staticHandlerChunkInfoMap.get(fileName);
5064
+ if (existing) {
5065
+ existing.exports.push(...handlers);
5066
+ } else {
5067
+ s.staticHandlerChunkInfoMap.set(fileName, {
5068
+ fileName,
5069
+ exports: handlers
5070
+ });
5071
+ }
4991
5072
  }
4992
5073
  }
4993
5074
  }
@@ -5279,7 +5360,8 @@ ${list}`);
5279
5360
  createRouterDiscoveryPlugin(discoveryEntryPath, {
5280
5361
  routerPathRef: discoveryRouterRef,
5281
5362
  enableBuildPrerender: prerenderEnabled,
5282
- staticRouteTypesGeneration: resolvedOptions.staticRouteTypesGeneration
5363
+ buildEnv: options?.buildEnv,
5364
+ preset
5283
5365
  })
5284
5366
  );
5285
5367
  return plugins;