@react-router/dev 0.0.0-experimental-345f1da12 → 0.0.0-experimental-d312c78a4

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/dist/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * @react-router/dev v0.0.0-experimental-345f1da12
3
+ * @react-router/dev v0.0.0-experimental-d312c78a4
4
4
  *
5
5
  * Copyright (c) Remix Software Inc.
6
6
  *
@@ -317,6 +317,7 @@ async function resolveConfig({
317
317
  basename: basename2,
318
318
  buildDirectory: userBuildDirectory,
319
319
  buildEnd,
320
+ future: userFuture,
320
321
  prerender,
321
322
  serverBuildFile,
322
323
  serverBundles,
@@ -389,7 +390,8 @@ async function resolveConfig({
389
390
  );
390
391
  }
391
392
  let future = {
392
- unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false
393
+ unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false,
394
+ unstable_routeChunks: userFuture?.unstable_routeChunks ?? false
393
395
  };
394
396
  let reactRouterConfig = deepFreeze({
395
397
  appDirectory,
@@ -586,67 +588,137 @@ var init_config = __esm({
586
588
  }
587
589
  });
588
590
 
591
+ // typegen/paths.ts
592
+ function getTypesDir(ctx) {
593
+ return Path2.join(ctx.rootDirectory, ".react-router/types");
594
+ }
595
+ function getTypesPath(ctx, route) {
596
+ return Path2.join(
597
+ getTypesDir(ctx),
598
+ Path2.relative(ctx.rootDirectory, ctx.config.appDirectory),
599
+ Path2.dirname(route.file),
600
+ "+types/" + Pathe.filename(route.file) + ".ts"
601
+ );
602
+ }
603
+ var Path2, Pathe;
604
+ var init_paths = __esm({
605
+ "typegen/paths.ts"() {
606
+ "use strict";
607
+ Path2 = __toESM(require("pathe"));
608
+ Pathe = __toESM(require("pathe/utils"));
609
+ }
610
+ });
611
+
589
612
  // typegen/generate.ts
590
- function generate(route) {
613
+ function generate(ctx, route) {
614
+ const lineage = getRouteLineage(ctx.config.routes, route);
615
+ const urlpath = lineage.map((route2) => route2.path).join("/");
616
+ const typesPath = getTypesPath(ctx, route);
617
+ const parents = lineage.slice(0, -1);
618
+ const parentTypeImports = parents.map((parent, i) => {
619
+ const rel = Path3.relative(
620
+ Path3.dirname(typesPath),
621
+ getTypesPath(ctx, parent)
622
+ );
623
+ const indent = i === 0 ? "" : " ".repeat(2);
624
+ let source = noExtension(rel);
625
+ if (!source.startsWith("../")) source = "./" + source;
626
+ return `${indent}import type { Info as Parent${i} } from "${source}.js"`;
627
+ }).join("\n");
591
628
  return import_dedent.default`
592
629
  // React Router generated types for route:
593
630
  // ${route.file}
594
631
 
595
- import type { RouteExports, Routes } from "react-router/types";
632
+ import type * as T from "react-router/route-module"
596
633
 
597
- type RouteId = "${route.id}"
598
- export type Info = Routes[RouteId];
634
+ ${parentTypeImports}
599
635
 
600
- type Exports = RouteExports[RouteId];
636
+ type Module = typeof import("../${Pathe2.filename(route.file)}.js")
637
+
638
+ export type Info = {
639
+ parents: [${parents.map((_, i) => `Parent${i}`).join(", ")}],
640
+ id: "${route.id}"
641
+ file: "${route.file}"
642
+ path: "${route.path}"
643
+ params: {${formatParamProperties(
644
+ urlpath
645
+ )}} & { [key: string]: string | undefined }
646
+ module: Module
647
+ loaderData: T.CreateLoaderData<Module>
648
+ actionData: T.CreateActionData<Module>
649
+ }
601
650
 
602
651
  export namespace Route {
603
- export type LinkDescriptors = Exports["links"]["return"];
604
- export type LinksFunction = () => LinkDescriptors;
652
+ export type LinkDescriptors = T.LinkDescriptors
653
+ export type LinksFunction = () => LinkDescriptors
605
654
 
606
- export type MetaArgs = Exports["meta"]["args"];
607
- export type MetaDescriptors = Exports["meta"]["return"];
608
- export type MetaFunction = (args: MetaArgs) => MetaDescriptors;
655
+ export type MetaArgs = T.CreateMetaArgs<Info>
656
+ export type MetaDescriptors = T.MetaDescriptors
657
+ export type MetaFunction = (args: MetaArgs) => MetaDescriptors
609
658
 
610
- export type HeadersArgs = Exports["headers"]["args"];
611
- export type HeadersFunction = (args: HeadersArgs) => Headers | HeadersInit;
659
+ export type HeadersArgs = T.HeadersArgs
660
+ export type HeadersFunction = (args: HeadersArgs) => Headers | HeadersInit
612
661
 
613
- export type LoaderArgs = Exports["loader"]["args"];
614
- export type ClientLoaderArgs = Exports["clientLoader"]["args"];
615
- export type ActionArgs = Exports["action"]["args"];
616
- export type ClientActionArgs = Exports["clientAction"]["args"];
662
+ export type LoaderArgs = T.CreateServerLoaderArgs<Info>
663
+ export type ClientLoaderArgs = T.CreateClientLoaderArgs<Info>
664
+ export type ActionArgs = T.CreateServerActionArgs<Info>
665
+ export type ClientActionArgs = T.CreateClientActionArgs<Info>
617
666
 
618
- export type HydrateFallbackProps = Exports["HydrateFallback"]["args"];
619
- export type ComponentProps = Exports["default"]["args"];
620
- export type ErrorBoundaryProps = Exports["ErrorBoundary"]["args"];
667
+ export type HydrateFallbackProps = T.CreateHydrateFallbackProps<Info>
668
+ export type ComponentProps = T.CreateComponentProps<Info>
669
+ export type ErrorBoundaryProps = T.CreateErrorBoundaryProps<Info>
621
670
  }
622
671
  `;
623
672
  }
624
- var import_dedent;
625
- var init_generate = __esm({
626
- "typegen/generate.ts"() {
627
- "use strict";
628
- import_dedent = __toESM(require("dedent"));
673
+ function getRouteLineage(routes2, route) {
674
+ const result = [];
675
+ while (route) {
676
+ result.push(route);
677
+ if (!route.parentId) break;
678
+ route = routes2[route.parentId];
629
679
  }
630
- });
631
-
632
- // typegen/paths.ts
633
- function getTypesDir(ctx) {
634
- return Path2.join(ctx.rootDirectory, ".react-router/types");
680
+ result.reverse();
681
+ return result;
635
682
  }
636
- function getTypesPath(ctx, route) {
637
- return Path2.join(
638
- getTypesDir(ctx),
639
- Path2.relative(ctx.rootDirectory, ctx.config.appDirectory),
640
- Path2.dirname(route.file),
641
- "+types/" + Pathe.filename(route.file) + ".ts"
642
- );
683
+ function formatParamProperties(urlpath) {
684
+ const params = parseParams(urlpath);
685
+ const properties = Object.entries(params).map(([name, values]) => {
686
+ if (values.length === 1) {
687
+ const isOptional = values[0];
688
+ return isOptional ? `"${name}"?: string` : `"${name}": string`;
689
+ }
690
+ const items = values.map(
691
+ (isOptional) => isOptional ? "string | undefined" : "string"
692
+ );
693
+ return `"${name}": [${items.join(", ")}]`;
694
+ });
695
+ return properties.join("; ");
643
696
  }
644
- var Path2, Pathe;
645
- var init_paths = __esm({
646
- "typegen/paths.ts"() {
697
+ function parseParams(urlpath) {
698
+ const result = {};
699
+ let segments = urlpath.split("/");
700
+ segments.forEach((segment) => {
701
+ const match = segment.match(/^:([\w-]+)(\?)?/);
702
+ if (!match) return;
703
+ const param = match[1];
704
+ const isOptional = match[2] !== void 0;
705
+ result[param] ??= [];
706
+ result[param].push(isOptional);
707
+ return;
708
+ });
709
+ const hasSplat = segments.at(-1) === "*";
710
+ if (hasSplat) result["*"] = [false];
711
+ return result;
712
+ }
713
+ var import_dedent, Path3, Pathe2, noExtension;
714
+ var init_generate = __esm({
715
+ "typegen/generate.ts"() {
647
716
  "use strict";
648
- Path2 = __toESM(require("pathe"));
649
- Pathe = __toESM(require("pathe/utils"));
717
+ import_dedent = __toESM(require("dedent"));
718
+ Path3 = __toESM(require("pathe"));
719
+ Pathe2 = __toESM(require("pathe/utils"));
720
+ init_paths();
721
+ noExtension = (path10) => Path3.join(Path3.dirname(path10), Pathe2.filename(path10));
650
722
  }
651
723
  });
652
724
 
@@ -693,100 +765,22 @@ async function createContext2({
693
765
  config
694
766
  };
695
767
  }
696
- function asJS(path10) {
697
- return path10.replace(/\.(js|ts)x?$/, ".js");
698
- }
699
- function formatRoute({ id, path: path10, file, parentId }) {
700
- return [
701
- `"${id}": {`,
702
- ` parentId: ${JSON.stringify(parentId)}`,
703
- ` path: ${JSON.stringify(path10)}`,
704
- ` module: typeof import("./app/${asJS(file)}")`,
705
- `}`
706
- ].map((line) => ` ${line}`).join("\n");
707
- }
708
768
  async function writeAll(ctx) {
709
- let routes2 = Object.values(ctx.config.routes);
710
- let pathsToParams = /* @__PURE__ */ new Map();
711
- for (let route of routes2) {
712
- if (route.path === void 0) continue;
713
- let lineage = getRouteLineage(ctx.config.routes, route);
714
- let path10 = lineage.filter((route2) => route2.path !== void 0).map((route2) => route2.path).join("/");
715
- if (path10 === "") path10 = "/";
716
- pathsToParams.set(path10, parseParams(path10));
717
- }
718
- let formattedPaths = `type Paths = {`;
719
- for (let [path10, params] of pathsToParams.entries()) {
720
- let formattedParams = Object.entries(params).map(
721
- ([param, required]) => `"${param}"${required ? "" : "?"}: string`
722
- );
723
- let formattedEntry = `"${path10}": {${formattedParams.join(",")}},
724
- `;
725
- formattedPaths += formattedEntry;
726
- }
727
- formattedPaths += `}`;
728
769
  const typegenDir = getTypesDir(ctx);
729
770
  import_node_fs2.default.rmSync(typegenDir, { recursive: true, force: true });
730
- const newTypes = Path3.join(typegenDir, "routes.ts");
731
- import_node_fs2.default.mkdirSync(Path3.dirname(newTypes), { recursive: true });
732
- import_node_fs2.default.writeFileSync(
733
- newTypes,
734
- formattedPaths + `
735
-
736
- type Routes = {
737
- ${routes2.map(formatRoute).join("\n")}
738
- }
739
-
740
- ` + import_dedent2.default`
741
- declare module "react-router/types" {
742
- interface Register {
743
- paths: Paths
744
- routes: Routes
745
- }
746
- }
747
-
748
- export {}
749
- `
750
- );
751
771
  Object.values(ctx.config.routes).forEach((route) => {
752
772
  const typesPath = getTypesPath(ctx, route);
753
- const content = generate(route);
754
- import_node_fs2.default.mkdirSync(Path3.dirname(typesPath), { recursive: true });
773
+ const content = generate(ctx, route);
774
+ import_node_fs2.default.mkdirSync(Path4.dirname(typesPath), { recursive: true });
755
775
  import_node_fs2.default.writeFileSync(typesPath, content);
756
776
  });
757
777
  }
758
- function getRouteLineage(routes2, route) {
759
- const result = [];
760
- while (route) {
761
- result.push(route);
762
- if (!route.parentId) break;
763
- route = routes2[route.parentId];
764
- }
765
- result.reverse();
766
- return result;
767
- }
768
- function parseParams(urlpath) {
769
- const result = {};
770
- let segments = urlpath.split("/");
771
- segments.forEach((segment) => {
772
- const match = segment.match(/^:([\w-]+)(\?)?/);
773
- if (!match) return;
774
- const param = match[1];
775
- const isRequired = match[2] === void 0;
776
- result[param] ||= isRequired;
777
- return;
778
- });
779
- const hasSplat = segments.at(-1) === "*";
780
- if (hasSplat) result["*"] = true;
781
- return result;
782
- }
783
- var import_node_fs2, import_dedent2, Path3, import_picocolors2;
778
+ var import_node_fs2, Path4, import_picocolors2;
784
779
  var init_typegen = __esm({
785
780
  "typegen/index.ts"() {
786
781
  "use strict";
787
782
  import_node_fs2 = __toESM(require("fs"));
788
- import_dedent2 = __toESM(require("dedent"));
789
- Path3 = __toESM(require("pathe"));
783
+ Path4 = __toESM(require("pathe"));
790
784
  import_picocolors2 = __toESM(require("picocolors"));
791
785
  init_config();
792
786
  init_generate();
@@ -875,12 +869,43 @@ var init_remove_exports = __esm({
875
869
  }
876
870
  });
877
871
 
872
+ // vite/cache.ts
873
+ var init_cache = __esm({
874
+ "vite/cache.ts"() {
875
+ "use strict";
876
+ }
877
+ });
878
+
879
+ // vite/route-chunks.ts
880
+ var routeChunkExportNames, routeChunkNames, routeChunkQueryStringPrefix, routeChunkQueryStrings;
881
+ var init_route_chunks = __esm({
882
+ "vite/route-chunks.ts"() {
883
+ "use strict";
884
+ init_invariant();
885
+ init_cache();
886
+ init_babel();
887
+ routeChunkExportNames = [
888
+ "clientAction",
889
+ "clientLoader",
890
+ "HydrateFallback"
891
+ ];
892
+ routeChunkNames = ["main", ...routeChunkExportNames];
893
+ routeChunkQueryStringPrefix = "?route-chunk=";
894
+ routeChunkQueryStrings = {
895
+ main: `${routeChunkQueryStringPrefix}main`,
896
+ clientAction: `${routeChunkQueryStringPrefix}clientAction`,
897
+ clientLoader: `${routeChunkQueryStringPrefix}clientLoader`,
898
+ HydrateFallback: `${routeChunkQueryStringPrefix}HydrateFallback`
899
+ };
900
+ }
901
+ });
902
+
878
903
  // vite/with-props.ts
879
- var import_dedent3, vmod;
904
+ var import_dedent2, vmod;
880
905
  var init_with_props = __esm({
881
906
  "vite/with-props.ts"() {
882
907
  "use strict";
883
- import_dedent3 = __toESM(require("dedent"));
908
+ import_dedent2 = __toESM(require("dedent"));
884
909
  init_babel();
885
910
  init_virtual_module();
886
911
  vmod = create("with-props");
@@ -970,6 +995,7 @@ var init_plugin = __esm({
970
995
  init_resolve_file_url();
971
996
  init_combine_urls();
972
997
  init_remove_exports();
998
+ init_route_chunks();
973
999
  init_vite();
974
1000
  init_config();
975
1001
  init_with_props();
@@ -991,7 +1017,7 @@ var init_plugin = __esm({
991
1017
  "config",
992
1018
  "defaults"
993
1019
  );
994
- defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename2) => path6.join(defaultEntriesDir, filename2));
1020
+ defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename3) => path6.join(defaultEntriesDir, filename3));
995
1021
  invariant(defaultEntries.length > 0, "No default entries found");
996
1022
  REACT_REFRESH_HEADER = `
997
1023
  import RefreshRuntime from "${virtualHmrRuntime.id}";
@@ -1548,8 +1574,8 @@ async function checkForEntry(rootDirectory, appDirectory, entries2) {
1548
1574
  let entryPath = path9.resolve(appDirectory, entry);
1549
1575
  let exists = await import_fs_extra2.default.pathExists(entryPath);
1550
1576
  if (exists) {
1551
- let relative7 = path9.relative(rootDirectory, entryPath);
1552
- console.error(import_picocolors7.default.red(`Entry file ${relative7} already exists.`));
1577
+ let relative8 = path9.relative(rootDirectory, entryPath);
1578
+ console.error(import_picocolors7.default.red(`Entry file ${relative8} already exists.`));
1553
1579
  return process.exit(1);
1554
1580
  }
1555
1581
  }
package/dist/config.d.ts CHANGED
@@ -38,6 +38,10 @@ type ServerBundlesBuildManifest = BaseBuildManifest & {
38
38
  type ServerModuleFormat = "esm" | "cjs";
39
39
  interface FutureConfig {
40
40
  unstable_optimizeDeps: boolean;
41
+ /**
42
+ * Automatically split route modules into multiple chunks when possible.
43
+ */
44
+ unstable_routeChunks?: boolean | "enforce";
41
45
  }
42
46
  type BuildManifest = DefaultBuildManifest | ServerBundlesBuildManifest;
43
47
  type BuildEndHook = (args: {
@@ -129,7 +133,7 @@ type ResolvedReactRouterConfig = Readonly<{
129
133
  /**
130
134
  * Enabled future flags
131
135
  */
132
- future: FutureConfig;
136
+ future: Required<FutureConfig>;
133
137
  /**
134
138
  * An array of URLs to prerender to HTML files at build time. Can also be a
135
139
  * function returning an array to dynamically generate URLs.
package/dist/config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v0.0.0-experimental-345f1da12
2
+ * @react-router/dev v0.0.0-experimental-d312c78a4
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
package/dist/routes.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v0.0.0-experimental-345f1da12
2
+ * @react-router/dev v0.0.0-experimental-d312c78a4
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -23,6 +23,7 @@ const enqueueUpdate = debounce(async () => {
23
23
  `[react-router:hmr] No module update found for route ${route.id}`
24
24
  );
25
25
  }
26
+
26
27
  let routeModule = {
27
28
  ...imported,
28
29
  // react-refresh takes care of updating these in-place,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v0.0.0-experimental-345f1da12
2
+ * @react-router/dev v0.0.0-experimental-d312c78a4
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *