@reckona/mreact-router 0.0.81 → 0.0.83

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 (81) hide show
  1. package/README.md +2 -0
  2. package/dist/adapters/aws-lambda.d.ts.map +1 -1
  3. package/dist/adapters/aws-lambda.js +17 -22
  4. package/dist/adapters/aws-lambda.js.map +1 -1
  5. package/dist/build.d.ts.map +1 -1
  6. package/dist/build.js +3 -1
  7. package/dist/build.js.map +1 -1
  8. package/dist/client-route-inference.d.ts +2 -0
  9. package/dist/client-route-inference.d.ts.map +1 -0
  10. package/dist/client-route-inference.js +2 -0
  11. package/dist/client-route-inference.js.map +1 -0
  12. package/dist/client.d.ts +2 -1
  13. package/dist/client.d.ts.map +1 -1
  14. package/dist/client.js +89 -24
  15. package/dist/client.js.map +1 -1
  16. package/dist/layout-composer.d.ts +24 -0
  17. package/dist/layout-composer.d.ts.map +1 -0
  18. package/dist/layout-composer.js +83 -0
  19. package/dist/layout-composer.js.map +1 -0
  20. package/dist/metadata.d.ts +9 -0
  21. package/dist/metadata.d.ts.map +1 -0
  22. package/dist/metadata.js +419 -0
  23. package/dist/metadata.js.map +1 -0
  24. package/dist/middleware.d.ts +22 -0
  25. package/dist/middleware.d.ts.map +1 -0
  26. package/dist/middleware.js +94 -0
  27. package/dist/middleware.js.map +1 -0
  28. package/dist/module-runner.d.ts +2 -2
  29. package/dist/module-runner.d.ts.map +1 -1
  30. package/dist/module-runner.js +1 -1
  31. package/dist/module-runner.js.map +1 -1
  32. package/dist/navigation-runtime.d.ts +2 -0
  33. package/dist/navigation-runtime.d.ts.map +1 -0
  34. package/dist/navigation-runtime.js +2 -0
  35. package/dist/navigation-runtime.js.map +1 -0
  36. package/dist/preload-policy.d.ts +24 -0
  37. package/dist/preload-policy.d.ts.map +1 -0
  38. package/dist/preload-policy.js +45 -0
  39. package/dist/preload-policy.js.map +1 -0
  40. package/dist/render.d.ts +1 -3
  41. package/dist/render.d.ts.map +1 -1
  42. package/dist/render.js +32 -676
  43. package/dist/render.js.map +1 -1
  44. package/dist/route-hydration-contract.d.ts +11 -0
  45. package/dist/route-hydration-contract.d.ts.map +1 -0
  46. package/dist/route-hydration-contract.js +21 -0
  47. package/dist/route-hydration-contract.js.map +1 -0
  48. package/dist/route-module-loader.d.ts +10 -0
  49. package/dist/route-module-loader.d.ts.map +1 -0
  50. package/dist/route-module-loader.js +61 -0
  51. package/dist/route-module-loader.js.map +1 -0
  52. package/dist/routes.js +6 -0
  53. package/dist/routes.js.map +1 -1
  54. package/dist/serve.d.ts +13 -0
  55. package/dist/serve.d.ts.map +1 -1
  56. package/dist/serve.js +63 -28
  57. package/dist/serve.js.map +1 -1
  58. package/dist/server-action-inference.d.ts.map +1 -1
  59. package/dist/server-action-inference.js +37 -1
  60. package/dist/server-action-inference.js.map +1 -1
  61. package/dist/vite.d.ts.map +1 -1
  62. package/dist/vite.js +2 -1
  63. package/dist/vite.js.map +1 -1
  64. package/package.json +11 -11
  65. package/src/adapters/aws-lambda.ts +21 -28
  66. package/src/build.ts +9 -6
  67. package/src/client-route-inference.ts +18 -0
  68. package/src/client.ts +124 -24
  69. package/src/layout-composer.ts +142 -0
  70. package/src/metadata.ts +578 -0
  71. package/src/middleware.ts +153 -0
  72. package/src/module-runner.ts +3 -2
  73. package/src/navigation-runtime.ts +16 -0
  74. package/src/preload-policy.ts +89 -0
  75. package/src/render.ts +75 -986
  76. package/src/route-hydration-contract.ts +22 -0
  77. package/src/route-module-loader.ts +95 -0
  78. package/src/routes.ts +8 -0
  79. package/src/serve.ts +110 -29
  80. package/src/server-action-inference.ts +49 -0
  81. package/src/vite.ts +6 -4
@@ -0,0 +1,153 @@
1
+ export interface RouteMiddlewareControl {
2
+ skip?: boolean | readonly string[];
3
+ }
4
+
5
+ export interface MiddlewareModule {
6
+ config?: {
7
+ id?: string | undefined;
8
+ matcher?: string | RegExp | readonly string[] | undefined;
9
+ };
10
+ default?: unknown;
11
+ middleware?: unknown;
12
+ }
13
+
14
+ export interface StaticMiddlewareConfig {
15
+ hasMatcher: boolean;
16
+ id?: string | undefined;
17
+ matcher?: string | readonly string[] | undefined;
18
+ }
19
+
20
+ export function shouldSkipMiddleware(
21
+ config: Pick<NonNullable<MiddlewareModule["config"]>, "id"> | undefined,
22
+ control: RouteMiddlewareControl | undefined,
23
+ ): boolean {
24
+ if (control?.skip === true) {
25
+ return true;
26
+ }
27
+
28
+ if (!Array.isArray(control?.skip)) {
29
+ return false;
30
+ }
31
+
32
+ return typeof config?.id === "string" && control.skip.includes(config.id);
33
+ }
34
+
35
+ export function parseStaticMiddlewareConfig(code: string): StaticMiddlewareConfig {
36
+ const configBody = /\bexport\s+const\s+config\s*=\s*\{(?<body>[\s\S]*?)\}\s*;?/.exec(code)
37
+ ?.groups?.body;
38
+
39
+ if (configBody === undefined) {
40
+ return { hasMatcher: false };
41
+ }
42
+
43
+ const id = /\bid\s*:\s*["'](?<id>[^"']+)["']/.exec(configBody)?.groups?.id;
44
+ const stringMatcher = /\bmatcher\s*:\s*["'](?<matcher>[^"']+)["']/.exec(configBody)?.groups
45
+ ?.matcher;
46
+
47
+ if (stringMatcher !== undefined) {
48
+ return {
49
+ hasMatcher: true,
50
+ ...(id === undefined ? {} : { id }),
51
+ matcher: stringMatcher,
52
+ };
53
+ }
54
+
55
+ const matcherArray = /\bmatcher\s*:\s*\[(?<items>[\s\S]*?)\]/.exec(configBody)?.groups?.items;
56
+
57
+ if (matcherArray !== undefined) {
58
+ return {
59
+ hasMatcher: true,
60
+ ...(id === undefined ? {} : { id }),
61
+ matcher: Array.from(
62
+ matcherArray.matchAll(/["'](?<matcher>[^"']+)["']/g),
63
+ (match) => match.groups?.matcher,
64
+ ).filter((matcher): matcher is string => matcher !== undefined),
65
+ };
66
+ }
67
+
68
+ return {
69
+ hasMatcher: /\bmatcher\s*:/.test(configBody),
70
+ ...(id === undefined ? {} : { id }),
71
+ };
72
+ }
73
+
74
+ export function middlewareMatches(config: MiddlewareModule["config"], pathname: string): boolean {
75
+ const matcher = config?.matcher;
76
+
77
+ if (matcher === undefined) {
78
+ return true;
79
+ }
80
+
81
+ if (matcher instanceof RegExp) {
82
+ return matcher.test(pathname);
83
+ }
84
+
85
+ if (Array.isArray(matcher)) {
86
+ return matcher.some((item) => middlewarePatternMatches(item, pathname));
87
+ }
88
+
89
+ return typeof matcher === "string" && middlewarePatternMatches(matcher, pathname);
90
+ }
91
+
92
+ export function parseRouteMiddlewareControl(code: string): RouteMiddlewareControl | undefined {
93
+ if (!/\bexport\s+const\s+middleware\s*=/.test(code)) {
94
+ return undefined;
95
+ }
96
+
97
+ if (/\bmiddleware\s*=\s*\{[\s\S]*?\bskip\s*:\s*true\b/.test(code)) {
98
+ return { skip: true };
99
+ }
100
+
101
+ const skipArray = /\bmiddleware\s*=\s*\{[\s\S]*?\bskip\s*:\s*\[([\s\S]*?)\]/.exec(code);
102
+
103
+ if (skipArray === null) {
104
+ return undefined;
105
+ }
106
+
107
+ const ids = Array.from(
108
+ skipArray[1]?.matchAll(/["']([^"']+)["']/g) ?? [],
109
+ (match) => match[1],
110
+ ).filter((id) => id !== undefined);
111
+
112
+ return ids.length === 0 ? undefined : { skip: ids };
113
+ }
114
+
115
+ export function mergeRouteMiddlewareControls(
116
+ controls: readonly (RouteMiddlewareControl | undefined)[],
117
+ ): RouteMiddlewareControl | undefined {
118
+ const skippedIds = new Set<string>();
119
+
120
+ for (const control of controls) {
121
+ if (control?.skip === true) {
122
+ return { skip: true };
123
+ }
124
+
125
+ if (Array.isArray(control?.skip)) {
126
+ for (const id of control.skip) {
127
+ skippedIds.add(id);
128
+ }
129
+ }
130
+ }
131
+
132
+ return skippedIds.size === 0 ? undefined : { skip: [...skippedIds] };
133
+ }
134
+
135
+ function middlewarePatternMatches(pattern: string, pathname: string): boolean {
136
+ if (pattern === pathname) {
137
+ return true;
138
+ }
139
+
140
+ if (pattern.endsWith("/:path*")) {
141
+ const prefix = pattern.slice(0, -"/:path*".length);
142
+
143
+ return pathname === prefix || pathname.startsWith(`${prefix}/`);
144
+ }
145
+
146
+ if (pattern.endsWith("*")) {
147
+ const prefix = pattern.slice(0, -1);
148
+
149
+ return pathname.startsWith(prefix);
150
+ }
151
+
152
+ return false;
153
+ }
@@ -2,7 +2,8 @@ import { createHash } from "node:crypto";
2
2
  import { readFile } from "node:fs/promises";
3
3
  import { dirname, join, sep } from "node:path";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
5
- import { formatDiagnostic, type ServerOutputMode } from "@reckona/mreact-compiler";
5
+ import { formatDiagnostic } from "@reckona/mreact-compiler";
6
+ import type { ServerOutputMode } from "@reckona/mreact-shared/compiler-contract";
6
7
  import { transformCompilerModuleContext } from "@reckona/mreact-compiler/internal";
7
8
  import { runnerImport, type InlineConfig, type PluginOption } from "vite";
8
9
  import { resolveWorkspacePackageFile } from "./workspace-packages.js";
@@ -26,7 +27,7 @@ import {
26
27
  formatClientRouteInferenceDiagnostic,
27
28
  inferClientRouteModule,
28
29
  type ClientRouteInferenceCache,
29
- } from "./client.js";
30
+ } from "./client-route-inference.js";
30
31
  import { vitePluginsCacheKey } from "./vite-plugin-cache-key.js";
31
32
 
32
33
  const runnerConfig = {
@@ -0,0 +1,16 @@
1
+ export {
2
+ buildClientRouteBatchOutput,
3
+ buildClientRouteBundle,
4
+ buildClientRouteEntrySource,
5
+ buildClientRouteOutput,
6
+ buildNavigationRuntimeBundle,
7
+ clientScriptForPath,
8
+ hydrationMarkerParts,
9
+ navigationRuntimeScriptForDev,
10
+ routeIdForPath,
11
+ withHydrationMarkers,
12
+ withRouteMarkers,
13
+ type BuildClientRouteBatchOutput,
14
+ type BuildClientRouteBatchRouteOutput,
15
+ type BuildClientRouteOutputOptions,
16
+ } from "./client.js";
@@ -0,0 +1,89 @@
1
+ import type {
2
+ BuiltAppRuntimePreloadMode,
3
+ BuiltAppRuntimePreloadStrategy,
4
+ } from "./serve.js";
5
+
6
+ export type BuiltAppRuntimePreloadWait =
7
+ | "background"
8
+ | "before-render"
9
+ | "first-request";
10
+
11
+ export type BuiltAppRuntimeDefaultPreloadMode = "all" | "middleware";
12
+
13
+ export type BuiltAppRuntimePreloadInput =
14
+ | BuiltAppRuntimePreloadMode
15
+ | (BuiltAppRuntimePreloadStrategy & {
16
+ wait?: BuiltAppRuntimePreloadWait | undefined;
17
+ })
18
+ | undefined;
19
+
20
+ export type NormalizedBuiltAppRuntimePreloadStrategy = BuiltAppRuntimePreloadStrategy & {
21
+ wait: BuiltAppRuntimePreloadWait;
22
+ };
23
+
24
+ export interface BuiltAppRuntimePreloadArtifactPlan
25
+ extends NormalizedBuiltAppRuntimePreloadStrategy {
26
+ includeRenderModules: boolean;
27
+ loadAllArtifacts: boolean;
28
+ middlewareArtifacts?: { includeRender: boolean } | undefined;
29
+ routeArtifacts?: { includeRender: boolean; includeShells: boolean } | undefined;
30
+ shouldPreload: boolean;
31
+ }
32
+
33
+ export function normalizeBuiltAppRuntimePreloadStrategy(
34
+ strategy: BuiltAppRuntimePreloadInput,
35
+ defaultMode: BuiltAppRuntimeDefaultPreloadMode = "all",
36
+ ): NormalizedBuiltAppRuntimePreloadStrategy {
37
+ if (strategy === undefined) {
38
+ return { mode: defaultMode, wait: "background" };
39
+ }
40
+
41
+ if (typeof strategy === "string") {
42
+ return { mode: strategy, wait: "background" };
43
+ }
44
+
45
+ return {
46
+ mode: strategy.mode,
47
+ ...(strategy.routes === undefined ? {} : { routes: strategy.routes }),
48
+ wait: strategy.wait ?? "background",
49
+ };
50
+ }
51
+
52
+ export function builtAppRuntimePreloadPlan(
53
+ strategy: BuiltAppRuntimePreloadInput,
54
+ defaultMode: BuiltAppRuntimeDefaultPreloadMode = "all",
55
+ ): BuiltAppRuntimePreloadArtifactPlan {
56
+ const normalized = normalizeBuiltAppRuntimePreloadStrategy(strategy, defaultMode);
57
+
58
+ if (normalized.mode === "none") {
59
+ return {
60
+ ...normalized,
61
+ includeRenderModules: false,
62
+ loadAllArtifacts: false,
63
+ shouldPreload: false,
64
+ };
65
+ }
66
+
67
+ if (normalized.mode === "all") {
68
+ return {
69
+ ...normalized,
70
+ includeRenderModules: true,
71
+ loadAllArtifacts: true,
72
+ shouldPreload: true,
73
+ };
74
+ }
75
+
76
+ const requestOnly = normalized.mode === "hot-route-requests";
77
+
78
+ return {
79
+ ...normalized,
80
+ includeRenderModules: !requestOnly,
81
+ loadAllArtifacts: false,
82
+ middlewareArtifacts: { includeRender: !requestOnly },
83
+ routeArtifacts: {
84
+ includeRender: !requestOnly,
85
+ includeShells: !requestOnly,
86
+ },
87
+ shouldPreload: true,
88
+ };
89
+ }