@reckona/mreact-router 0.0.1

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 (139) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +101 -0
  3. package/dist/actions.d.ts +43 -0
  4. package/dist/actions.d.ts.map +1 -0
  5. package/dist/actions.js +577 -0
  6. package/dist/actions.js.map +1 -0
  7. package/dist/adapters/aws-lambda.d.ts +45 -0
  8. package/dist/adapters/aws-lambda.d.ts.map +1 -0
  9. package/dist/adapters/aws-lambda.js +168 -0
  10. package/dist/adapters/aws-lambda.js.map +1 -0
  11. package/dist/adapters/cloudflare.d.ts +94 -0
  12. package/dist/adapters/cloudflare.d.ts.map +1 -0
  13. package/dist/adapters/cloudflare.js +390 -0
  14. package/dist/adapters/cloudflare.js.map +1 -0
  15. package/dist/adapters/devtools.d.ts +4 -0
  16. package/dist/adapters/devtools.d.ts.map +1 -0
  17. package/dist/adapters/devtools.js +5 -0
  18. package/dist/adapters/devtools.js.map +1 -0
  19. package/dist/adapters/edge.d.ts +9 -0
  20. package/dist/adapters/edge.d.ts.map +1 -0
  21. package/dist/adapters/edge.js +53 -0
  22. package/dist/adapters/edge.js.map +1 -0
  23. package/dist/adapters/node.d.ts +26 -0
  24. package/dist/adapters/node.d.ts.map +1 -0
  25. package/dist/adapters/node.js +64 -0
  26. package/dist/adapters/node.js.map +1 -0
  27. package/dist/adapters/static.d.ts +10 -0
  28. package/dist/adapters/static.d.ts.map +1 -0
  29. package/dist/adapters/static.js +34 -0
  30. package/dist/adapters/static.js.map +1 -0
  31. package/dist/assets.d.ts +18 -0
  32. package/dist/assets.d.ts.map +1 -0
  33. package/dist/assets.js +67 -0
  34. package/dist/assets.js.map +1 -0
  35. package/dist/build.d.ts +36 -0
  36. package/dist/build.d.ts.map +1 -0
  37. package/dist/build.js +322 -0
  38. package/dist/build.js.map +1 -0
  39. package/dist/cache.d.ts +54 -0
  40. package/dist/cache.d.ts.map +1 -0
  41. package/dist/cache.js +221 -0
  42. package/dist/cache.js.map +1 -0
  43. package/dist/cli.d.ts +3 -0
  44. package/dist/cli.d.ts.map +1 -0
  45. package/dist/cli.js +37 -0
  46. package/dist/cli.js.map +1 -0
  47. package/dist/client.d.ts +105 -0
  48. package/dist/client.d.ts.map +1 -0
  49. package/dist/client.js +1268 -0
  50. package/dist/client.js.map +1 -0
  51. package/dist/config.d.ts +27 -0
  52. package/dist/config.d.ts.map +1 -0
  53. package/dist/config.js +44 -0
  54. package/dist/config.js.map +1 -0
  55. package/dist/cookies.d.ts +14 -0
  56. package/dist/cookies.d.ts.map +1 -0
  57. package/dist/cookies.js +69 -0
  58. package/dist/cookies.js.map +1 -0
  59. package/dist/csp.d.ts +6 -0
  60. package/dist/csp.d.ts.map +1 -0
  61. package/dist/csp.js +70 -0
  62. package/dist/csp.js.map +1 -0
  63. package/dist/dev-server.d.ts +16 -0
  64. package/dist/dev-server.d.ts.map +1 -0
  65. package/dist/dev-server.js +103 -0
  66. package/dist/dev-server.js.map +1 -0
  67. package/dist/http.d.ts +23 -0
  68. package/dist/http.d.ts.map +1 -0
  69. package/dist/http.js +106 -0
  70. package/dist/http.js.map +1 -0
  71. package/dist/i18n.d.ts +15 -0
  72. package/dist/i18n.d.ts.map +1 -0
  73. package/dist/i18n.js +61 -0
  74. package/dist/i18n.js.map +1 -0
  75. package/dist/import-policy.d.ts +30 -0
  76. package/dist/import-policy.d.ts.map +1 -0
  77. package/dist/import-policy.js +105 -0
  78. package/dist/import-policy.js.map +1 -0
  79. package/dist/index.d.ts +60 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +34 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/logger.d.ts +47 -0
  84. package/dist/logger.d.ts.map +1 -0
  85. package/dist/logger.js +60 -0
  86. package/dist/logger.js.map +1 -0
  87. package/dist/module-runner.d.ts +9 -0
  88. package/dist/module-runner.d.ts.map +1 -0
  89. package/dist/module-runner.js +112 -0
  90. package/dist/module-runner.js.map +1 -0
  91. package/dist/native-escape.d.ts +2 -0
  92. package/dist/native-escape.d.ts.map +1 -0
  93. package/dist/native-escape.js +43 -0
  94. package/dist/native-escape.js.map +1 -0
  95. package/dist/native-route-matcher.d.ts +5 -0
  96. package/dist/native-route-matcher.d.ts.map +1 -0
  97. package/dist/native-route-matcher.js +91 -0
  98. package/dist/native-route-matcher.js.map +1 -0
  99. package/dist/navigation.d.ts +25 -0
  100. package/dist/navigation.d.ts.map +1 -0
  101. package/dist/navigation.js +125 -0
  102. package/dist/navigation.js.map +1 -0
  103. package/dist/prerender-store.d.ts +37 -0
  104. package/dist/prerender-store.d.ts.map +1 -0
  105. package/dist/prerender-store.js +158 -0
  106. package/dist/prerender-store.js.map +1 -0
  107. package/dist/render.d.ts +26 -0
  108. package/dist/render.d.ts.map +1 -0
  109. package/dist/render.js +1688 -0
  110. package/dist/render.js.map +1 -0
  111. package/dist/route-path.d.ts +2 -0
  112. package/dist/route-path.d.ts.map +1 -0
  113. package/dist/route-path.js +5 -0
  114. package/dist/route-path.js.map +1 -0
  115. package/dist/route-source.d.ts +9 -0
  116. package/dist/route-source.d.ts.map +1 -0
  117. package/dist/route-source.js +44 -0
  118. package/dist/route-source.js.map +1 -0
  119. package/dist/routes.d.ts +38 -0
  120. package/dist/routes.d.ts.map +1 -0
  121. package/dist/routes.js +168 -0
  122. package/dist/routes.js.map +1 -0
  123. package/dist/serve.d.ts +63 -0
  124. package/dist/serve.d.ts.map +1 -0
  125. package/dist/serve.js +445 -0
  126. package/dist/serve.js.map +1 -0
  127. package/dist/session.d.ts +25 -0
  128. package/dist/session.d.ts.map +1 -0
  129. package/dist/session.js +104 -0
  130. package/dist/session.js.map +1 -0
  131. package/dist/vite-config.d.ts +8 -0
  132. package/dist/vite-config.d.ts.map +1 -0
  133. package/dist/vite-config.js +17 -0
  134. package/dist/vite-config.js.map +1 -0
  135. package/dist/vite.d.ts +25 -0
  136. package/dist/vite.d.ts.map +1 -0
  137. package/dist/vite.js +150 -0
  138. package/dist/vite.js.map +1 -0
  139. package/package.json +91 -0
@@ -0,0 +1,168 @@
1
+ import { Buffer } from "node:buffer";
2
+ import { emitRouterLog, logDurationMs, logError, logNow, requestLogFields, } from "../logger.js";
3
+ import { renderBuiltAppRequest, resolveRequestHost, } from "../serve.js";
4
+ export function createAwsLambdaRequestHandler(options) {
5
+ return async (event) => {
6
+ const startedAt = logNow();
7
+ const request = eventToRequest(event, options);
8
+ const logFields = requestLogFields(request, "aws-lambda");
9
+ emitRouterLog(options.logger, "info", {
10
+ ...logFields,
11
+ type: "router:request:start",
12
+ });
13
+ try {
14
+ const response = await renderBuiltAppRequest({
15
+ outDir: options.outDir,
16
+ importPolicy: options.importPolicy,
17
+ logger: options.logger,
18
+ prerenderStore: options.prerenderStore,
19
+ request,
20
+ routeCache: options.routeCache,
21
+ serverActions: options.serverActions,
22
+ ...(options.sinkStrategy === undefined ? {} : { sinkStrategy: options.sinkStrategy }),
23
+ });
24
+ emitRouterLog(options.logger, "info", {
25
+ ...logFields,
26
+ durationMs: logDurationMs(startedAt),
27
+ status: response.status,
28
+ type: "router:request:end",
29
+ });
30
+ return responseToLambdaResult(response);
31
+ }
32
+ catch (error) {
33
+ emitRouterLog(options.logger, "error", {
34
+ ...logFields,
35
+ durationMs: logDurationMs(startedAt),
36
+ error: logError(error),
37
+ type: "router:request:error",
38
+ });
39
+ const payload = options.errorHandler
40
+ ? options.errorHandler(error)
41
+ : { body: "Internal Server Error", status: 500 };
42
+ return {
43
+ body: payload.body,
44
+ headers: {
45
+ "content-type": "text/plain; charset=utf-8",
46
+ ...payload.headers,
47
+ },
48
+ isBase64Encoded: false,
49
+ statusCode: payload.status,
50
+ };
51
+ }
52
+ };
53
+ }
54
+ function eventToRequest(event, options) {
55
+ const headers = eventHeaders(event);
56
+ const rawHost = firstForwardedValue(headers.get("x-forwarded-host")) ?? headers.get("host");
57
+ const host = resolveRequestHost({
58
+ allowedHosts: options.allowedHosts,
59
+ fallbackHost: options.hostname ?? "lambda.local",
60
+ rawHost: rawHost ?? undefined,
61
+ });
62
+ const protocol = firstForwardedValue(headers.get("x-forwarded-proto")) ?? "https";
63
+ const rawPath = event.rawPath === undefined || event.rawPath === "" ? "/" : event.rawPath;
64
+ const rawQueryString = event.rawQueryString === undefined || event.rawQueryString === ""
65
+ ? ""
66
+ : `?${event.rawQueryString}`;
67
+ const method = event.requestContext?.http?.method ?? "GET";
68
+ const init = {
69
+ headers,
70
+ method,
71
+ };
72
+ if (method !== "GET" && method !== "HEAD" && event.body !== undefined) {
73
+ init.body =
74
+ event.isBase64Encoded === true ? Buffer.from(event.body, "base64") : event.body;
75
+ }
76
+ return new Request(`${protocol}://${host}${rawPath}${rawQueryString}`, init);
77
+ }
78
+ function eventHeaders(event) {
79
+ const headers = new Headers();
80
+ for (const [name, value] of Object.entries(event.headers ?? {})) {
81
+ if (value !== undefined) {
82
+ headers.set(name, value);
83
+ }
84
+ }
85
+ if (event.cookies !== undefined && event.cookies.length > 0 && !headers.has("cookie")) {
86
+ headers.set("cookie", event.cookies.join("; "));
87
+ }
88
+ return headers;
89
+ }
90
+ async function responseToLambdaResult(response) {
91
+ const headers = {};
92
+ response.headers.forEach((value, key) => {
93
+ if (key !== "set-cookie") {
94
+ headers[key] = value;
95
+ }
96
+ });
97
+ const cookies = responseCookies(response.headers);
98
+ if (response.body === null) {
99
+ return {
100
+ body: "",
101
+ ...(cookies.length === 0 ? {} : { cookies }),
102
+ headers,
103
+ isBase64Encoded: false,
104
+ statusCode: response.status,
105
+ };
106
+ }
107
+ const bytes = new Uint8Array(await response.arrayBuffer());
108
+ const contentType = response.headers.get("content-type");
109
+ const text = isTextContentType(contentType);
110
+ return {
111
+ body: text ? new TextDecoder().decode(bytes) : Buffer.from(bytes).toString("base64"),
112
+ ...(cookies.length === 0 ? {} : { cookies }),
113
+ headers,
114
+ isBase64Encoded: !text,
115
+ statusCode: response.status,
116
+ };
117
+ }
118
+ function firstForwardedValue(value) {
119
+ const first = value?.split(",")[0]?.trim();
120
+ return first === undefined || first === "" ? undefined : first;
121
+ }
122
+ function responseCookies(headers) {
123
+ const maybeHeaders = headers;
124
+ if (typeof maybeHeaders.getSetCookie === "function") {
125
+ return maybeHeaders.getSetCookie();
126
+ }
127
+ const raw = headers.get("set-cookie");
128
+ return raw === null ? [] : splitSetCookieHeader(raw);
129
+ }
130
+ function splitSetCookieHeader(header) {
131
+ const cookies = [];
132
+ let start = 0;
133
+ let inExpires = false;
134
+ for (let index = 0; index < header.length; index += 1) {
135
+ const remaining = header.slice(index).toLowerCase();
136
+ if (remaining.startsWith("expires=")) {
137
+ inExpires = true;
138
+ index += "expires=".length - 1;
139
+ continue;
140
+ }
141
+ const char = header[index];
142
+ if (char === ";") {
143
+ inExpires = false;
144
+ continue;
145
+ }
146
+ if (char === "," && !inExpires) {
147
+ cookies.push(header.slice(start, index).trim());
148
+ start = index + 1;
149
+ }
150
+ }
151
+ cookies.push(header.slice(start).trim());
152
+ return cookies.filter((cookie) => cookie.length > 0);
153
+ }
154
+ function isTextContentType(contentType) {
155
+ if (contentType === null) {
156
+ return true;
157
+ }
158
+ const type = contentType.toLowerCase().split(";")[0]?.trim() ?? "";
159
+ return (type.startsWith("text/") ||
160
+ type === "application/json" ||
161
+ type === "application/javascript" ||
162
+ type === "application/x-javascript" ||
163
+ type === "application/xml" ||
164
+ type === "application/x-www-form-urlencoded" ||
165
+ type.endsWith("+json") ||
166
+ type.endsWith("+xml"));
167
+ }
168
+ //# sourceMappingURL=aws-lambda.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws-lambda.js","sourceRoot":"","sources":["../../src/adapters/aws-lambda.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ import type { BuiltServerManifest } from "../build.js";
2
+ import type { ClientRouteManifestEntry } from "../client.js";
3
+ import { type AppRouterLogger } from "../logger.js";
4
+ import type { AppRoute } from "../routes.js";
5
+ import type { AppRouterPrerenderStore } from "../serve.js";
6
+ export interface CloudflareExecutionContext {
7
+ passThroughOnException(): void;
8
+ waitUntil(promise: Promise<unknown>): void;
9
+ }
10
+ export interface CloudflareAssetLoader<Env = unknown> {
11
+ fetch?: ((pathname: string, request: Request, env: Env, context: CloudflareExecutionContext) => Response | Promise<Response | undefined> | undefined) | undefined;
12
+ }
13
+ export interface CloudflareRenderContext<Env = unknown> {
14
+ clientManifest: CloudflareClientManifest;
15
+ context: CloudflareExecutionContext;
16
+ env: Env;
17
+ serverManifest: BuiltServerManifest;
18
+ }
19
+ export interface CloudflareRequestHandlerOptions<Env = unknown> {
20
+ assets?: CloudflareAssetLoader<Env> | undefined;
21
+ clientManifest: CloudflareClientManifest;
22
+ logger?: AppRouterLogger | undefined;
23
+ onError?: ((error: unknown, request: Request, env: Env, context: CloudflareExecutionContext) => Response | Promise<Response>) | undefined;
24
+ render?: ((request: Request, context: CloudflareRenderContext<Env>) => Response | Promise<Response>) | undefined;
25
+ serverManifest: BuiltServerManifest;
26
+ }
27
+ export interface CloudflareRequestHandler<Env = unknown> {
28
+ fetch(request: Request, env: Env, context: CloudflareExecutionContext): Promise<Response>;
29
+ }
30
+ export interface CloudflareBuiltRouteRenderContext<Env = unknown> extends CloudflareRenderContext<Env> {
31
+ params: Record<string, string>;
32
+ route: AppRoute;
33
+ }
34
+ export interface CloudflareRouteModuleLoaderContext<Env = unknown> extends CloudflareBuiltRouteRenderContext<Env> {
35
+ request: Request;
36
+ }
37
+ export interface CloudflareRouteModuleComponentProps<Data = unknown, Env = unknown> extends CloudflareBuiltRouteRenderContext<Env> {
38
+ data: Data;
39
+ request: Request;
40
+ }
41
+ export type CloudflareRouteModuleComponent<Data = unknown, Env = unknown> = (props: CloudflareRouteModuleComponentProps<Data, Env>) => Response | string | PromiseLike<Response | string>;
42
+ export interface CloudflareRouteModule<Data = unknown, Env = unknown> {
43
+ App?: CloudflareRouteModuleComponent<Data, Env> | undefined;
44
+ default?: CloudflareRouteModuleComponent<Data, Env> | undefined;
45
+ loader?: ((context: CloudflareRouteModuleLoaderContext<Env>) => Data | PromiseLike<Data>) | undefined;
46
+ }
47
+ export type CloudflareRouteModuleRegistry<Env = unknown> = Record<string, CloudflareRouteModule<unknown, Env> | (() => CloudflareRouteModule<unknown, Env> | PromiseLike<CloudflareRouteModule<unknown, Env>>)>;
48
+ export interface CloudflareRouteModuleRendererOptions<Env = unknown> {
49
+ document?: ((context: CloudflareRouteModuleComponentProps<unknown, Env> & {
50
+ body: string;
51
+ modulePreload: string;
52
+ }) => Response | string | PromiseLike<Response | string>) | undefined;
53
+ modules: CloudflareRouteModuleRegistry<Env>;
54
+ }
55
+ export type CloudflareRouteModuleGlob<Env = unknown> = Record<string, CloudflareRouteModule<unknown, Env> | (() => CloudflareRouteModule<unknown, Env> | PromiseLike<CloudflareRouteModule<unknown, Env>>)>;
56
+ export interface CollectCloudflareRouteModulesOptions {
57
+ manifest: BuiltServerManifest;
58
+ }
59
+ export interface CloudflareBuiltRequestHandlerOptions<Env = unknown> extends Omit<CloudflareRequestHandlerOptions<Env>, "render"> {
60
+ renderRoute?: ((request: Request, context: CloudflareBuiltRouteRenderContext<Env>) => Response | Promise<Response>) | undefined;
61
+ }
62
+ export interface CloudflareClientManifest {
63
+ routes: ClientRouteManifestEntry[];
64
+ }
65
+ export interface CloudflareAssetBinding {
66
+ fetch(request: Request): Response | Promise<Response>;
67
+ }
68
+ export interface CloudflareStaticAssetLoaderOptions<Env = unknown> {
69
+ binding: CloudflareAssetBinding | ((env: Env) => CloudflareAssetBinding | Promise<CloudflareAssetBinding | undefined> | undefined);
70
+ clientManifest: CloudflareClientManifest;
71
+ extraPaths?: readonly string[] | undefined;
72
+ prefix?: string | undefined;
73
+ }
74
+ export interface CloudflareCache {
75
+ delete(request: Request | string): boolean | Promise<boolean>;
76
+ match(request: Request | string): Response | Promise<Response | undefined> | undefined;
77
+ put(request: Request | string, response: Response): void | Promise<void>;
78
+ }
79
+ export interface CloudflarePrerenderStoreOptions {
80
+ cache: CloudflareCache;
81
+ keyOrigin?: string | undefined;
82
+ keyPrefix?: string | undefined;
83
+ }
84
+ export declare function createCloudflareRequestHandler<Env = unknown>(options: CloudflareRequestHandlerOptions<Env>): CloudflareRequestHandler<Env>;
85
+ export declare function createCloudflareBuiltRequestHandler<Env = unknown>(options: CloudflareBuiltRequestHandlerOptions<Env>): CloudflareRequestHandler<Env>;
86
+ export declare function createCloudflareRouteModuleRenderer<Env = unknown>(options: CloudflareRouteModuleRendererOptions<Env>): NonNullable<CloudflareBuiltRequestHandlerOptions<Env>["renderRoute"]>;
87
+ export declare function collectCloudflareRouteModules<Env = unknown>(glob: CloudflareRouteModuleGlob<Env>, options: CollectCloudflareRouteModulesOptions): CloudflareRouteModuleRegistry<Env>;
88
+ export declare function createCloudflareStaticAssetLoader<Env = unknown>(options: CloudflareStaticAssetLoaderOptions<Env>): CloudflareAssetLoader<Env>;
89
+ export declare function cloudflareClientAssetPaths(manifest: CloudflareClientManifest, options?: {
90
+ extraPaths?: readonly string[] | undefined;
91
+ prefix?: string | undefined;
92
+ }): Set<string>;
93
+ export declare function createCloudflarePrerenderStore(options: CloudflarePrerenderStoreOptions): AppRouterPrerenderStore;
94
+ //# sourceMappingURL=cloudflare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../src/adapters/cloudflare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,390 @@
1
+ import { emitRouterLog, logDurationMs, logError, logNow, requestLogFields, } from "../logger.js";
2
+ import { normalizeRoutePath } from "../route-path.js";
3
+ import { emitRouterDevtoolsEvent } from "./devtools.js";
4
+ import { escapeHtmlAttribute } from "@reckona/mreact-shared/html-escape";
5
+ const clientPrefix = "/_mreact/client/";
6
+ const defaultPrerenderCacheOrigin = "https://mreact.local";
7
+ const defaultPrerenderCachePrefix = "/_mreact/prerender";
8
+ export function createCloudflareRequestHandler(options) {
9
+ return {
10
+ async fetch(request, env, context) {
11
+ const startedAt = logNow();
12
+ try {
13
+ return await handleCloudflareRequest(options, request, env, context);
14
+ }
15
+ catch (error) {
16
+ const logFields = requestLogFields(request, "cloudflare");
17
+ emitRouterDevtoolsEvent({
18
+ method: request.method,
19
+ type: "router:request:error",
20
+ url: request.url,
21
+ });
22
+ emitRouterLog(options.logger, "error", {
23
+ ...logFields,
24
+ durationMs: logDurationMs(startedAt),
25
+ error: logError(error),
26
+ type: "router:request:error",
27
+ });
28
+ return options.onError === undefined
29
+ ? new Response("Internal Server Error", {
30
+ headers: { "content-type": "text/plain; charset=utf-8" },
31
+ status: 500,
32
+ })
33
+ : await options.onError(error, request, env, context);
34
+ }
35
+ },
36
+ };
37
+ }
38
+ export function createCloudflareBuiltRequestHandler(options) {
39
+ return createCloudflareRequestHandler({
40
+ ...options,
41
+ render(request, context) {
42
+ const matched = matchCloudflareRoute(options.serverManifest.routes, new URL(request.url).pathname);
43
+ if (matched === undefined || options.renderRoute === undefined) {
44
+ return new Response("Not Found", { status: 404 });
45
+ }
46
+ return options.renderRoute(request, {
47
+ ...context,
48
+ params: matched.params,
49
+ route: matched.route,
50
+ });
51
+ },
52
+ });
53
+ }
54
+ export function createCloudflareRouteModuleRenderer(options) {
55
+ return async (request, context) => {
56
+ const module = await loadCloudflareRouteModule(options.modules, context.route.file);
57
+ if (module === undefined) {
58
+ return new Response(`No Cloudflare route module registered for ${context.route.file}.`, {
59
+ headers: { "content-type": "text/plain; charset=utf-8" },
60
+ status: 500,
61
+ });
62
+ }
63
+ const component = module.default ?? module.App;
64
+ if (component === undefined) {
65
+ return new Response(`No Cloudflare page component registered for ${context.route.file}.`, {
66
+ headers: { "content-type": "text/plain; charset=utf-8" },
67
+ status: 500,
68
+ });
69
+ }
70
+ const loaderContext = {
71
+ ...context,
72
+ request,
73
+ };
74
+ const data = module.loader === undefined ? undefined : await module.loader(loaderContext);
75
+ const props = {
76
+ ...context,
77
+ data,
78
+ request,
79
+ };
80
+ const rendered = await component(props);
81
+ if (rendered instanceof Response) {
82
+ return rendered;
83
+ }
84
+ const modulePreload = cloudflareModulePreloadTag(context.clientManifest, context.route.path);
85
+ const documented = options.document === undefined
86
+ ? defaultCloudflareDocument(rendered, modulePreload)
87
+ : await options.document({
88
+ ...props,
89
+ body: rendered,
90
+ modulePreload,
91
+ });
92
+ return documented instanceof Response
93
+ ? documented
94
+ : new Response(documented, {
95
+ headers: { "content-type": "text/html; charset=utf-8" },
96
+ });
97
+ };
98
+ }
99
+ export function collectCloudflareRouteModules(glob, options) {
100
+ const requiredRoutes = options.manifest.routes.filter((route) => cloudflareRouteRequiresModule(route, options.manifest));
101
+ const matchedKeys = new Set();
102
+ const modules = {};
103
+ for (const route of requiredRoutes) {
104
+ const match = Object.entries(glob).find(([key]) => cloudflareRouteGlobKeyMatchesRoute(key, route.file));
105
+ if (match === undefined) {
106
+ throw new Error(`Missing Cloudflare route module for ${route.file}.`);
107
+ }
108
+ const [key, module] = match;
109
+ matchedKeys.add(key);
110
+ modules[route.file] = module;
111
+ }
112
+ const extraKeys = Object.keys(glob).filter((key) => !matchedKeys.has(key));
113
+ if (extraKeys.length > 0) {
114
+ throw new Error(`Extra Cloudflare route module entries: ${extraKeys.join(", ")}.`);
115
+ }
116
+ return modules;
117
+ }
118
+ export function createCloudflareStaticAssetLoader(options) {
119
+ const prefix = normalizeAssetPrefix(options.prefix ?? clientPrefix);
120
+ const allowedPaths = cloudflareClientAssetPaths(options.clientManifest, {
121
+ extraPaths: options.extraPaths,
122
+ prefix,
123
+ });
124
+ return {
125
+ async fetch(pathname, request, env) {
126
+ if (!allowedPaths.has(pathname)) {
127
+ return undefined;
128
+ }
129
+ const binding = typeof options.binding === "function" ? await options.binding(env) : options.binding;
130
+ if (binding === undefined) {
131
+ return undefined;
132
+ }
133
+ const assetUrl = new URL(request.url);
134
+ assetUrl.pathname = pathname;
135
+ assetUrl.search = "";
136
+ return await binding.fetch(new Request(assetUrl, request));
137
+ },
138
+ };
139
+ }
140
+ export function cloudflareClientAssetPaths(manifest, options = {}) {
141
+ const prefix = normalizeAssetPrefix(options.prefix ?? clientPrefix);
142
+ const paths = new Set([`${prefix}manifest.json`]);
143
+ for (const route of manifest.routes) {
144
+ for (const asset of [route.script, route.sourceMap]) {
145
+ const path = safeClientAssetPath(prefix, asset);
146
+ if (path !== undefined) {
147
+ paths.add(path);
148
+ }
149
+ }
150
+ }
151
+ for (const extraPath of options.extraPaths ?? []) {
152
+ const path = safeClientAssetPath(prefix, extraPath);
153
+ if (path !== undefined) {
154
+ paths.add(path);
155
+ }
156
+ }
157
+ return paths;
158
+ }
159
+ export function createCloudflarePrerenderStore(options) {
160
+ return {
161
+ async delete(path) {
162
+ await options.cache.delete(prerenderCacheRequest(options, path));
163
+ },
164
+ async get(path) {
165
+ const response = await options.cache.match(prerenderCacheRequest(options, path));
166
+ if (response === undefined) {
167
+ return undefined;
168
+ }
169
+ return (await response.json());
170
+ },
171
+ async set(path, entry) {
172
+ await options.cache.put(prerenderCacheRequest(options, path), Response.json(entry, {
173
+ headers: { "cache-control": "no-store" },
174
+ }));
175
+ },
176
+ };
177
+ }
178
+ async function handleCloudflareRequest(options, request, env, context) {
179
+ const startedAt = logNow();
180
+ const logFields = requestLogFields(request, "cloudflare");
181
+ emitRouterLog(options.logger, "info", {
182
+ ...logFields,
183
+ type: "router:request:start",
184
+ });
185
+ emitRouterDevtoolsEvent({
186
+ method: request.method,
187
+ type: "router:request:start",
188
+ url: request.url,
189
+ });
190
+ const url = new URL(request.url);
191
+ if (url.pathname.startsWith(clientPrefix)) {
192
+ const response = await options.assets?.fetch?.(url.pathname, request, env, context);
193
+ const assetResponse = response ?? new Response("Not Found", { status: 404 });
194
+ emitRouterLog(options.logger, "info", {
195
+ ...logFields,
196
+ durationMs: logDurationMs(startedAt),
197
+ status: assetResponse.status,
198
+ type: "router:request:end",
199
+ });
200
+ return assetResponse;
201
+ }
202
+ const staticResponse = prerenderedResponse(options.serverManifest.prerenderedRoutes, normalizeRoutePath(url.pathname), request.method);
203
+ if (staticResponse !== undefined) {
204
+ emitRouterDevtoolsEvent({
205
+ method: request.method,
206
+ status: staticResponse.status,
207
+ type: "router:request:end",
208
+ url: request.url,
209
+ });
210
+ emitRouterLog(options.logger, "info", {
211
+ ...logFields,
212
+ durationMs: logDurationMs(startedAt),
213
+ status: staticResponse.status,
214
+ type: "router:request:end",
215
+ });
216
+ return staticResponse;
217
+ }
218
+ if (options.render === undefined) {
219
+ const notFoundResponse = new Response("Not Found", { status: 404 });
220
+ emitRouterLog(options.logger, "info", {
221
+ ...logFields,
222
+ durationMs: logDurationMs(startedAt),
223
+ status: notFoundResponse.status,
224
+ type: "router:request:end",
225
+ });
226
+ return notFoundResponse;
227
+ }
228
+ const response = await options.render(request, {
229
+ clientManifest: options.clientManifest,
230
+ context,
231
+ env,
232
+ serverManifest: options.serverManifest,
233
+ });
234
+ emitRouterDevtoolsEvent({
235
+ method: request.method,
236
+ status: response.status,
237
+ type: "router:request:end",
238
+ url: request.url,
239
+ });
240
+ emitRouterLog(options.logger, "info", {
241
+ ...logFields,
242
+ durationMs: logDurationMs(startedAt),
243
+ status: response.status,
244
+ type: "router:request:end",
245
+ });
246
+ return response;
247
+ }
248
+ function prerenderedResponse(prerenderedRoutes, path, method) {
249
+ if (method !== "GET" && method !== "HEAD") {
250
+ return undefined;
251
+ }
252
+ const prerendered = prerenderedRoutes?.[path];
253
+ if (prerendered === undefined) {
254
+ return undefined;
255
+ }
256
+ return new Response(method === "HEAD" ? null : prerendered.html, {
257
+ headers: prerendered.headers,
258
+ status: prerendered.status,
259
+ });
260
+ }
261
+ function cloudflareRouteRequiresModule(route, manifest) {
262
+ return (route.kind === "page" &&
263
+ (route.segments.some((segment) => segment.kind !== "static") ||
264
+ manifest.prerenderedRoutes?.[route.path] === undefined));
265
+ }
266
+ function cloudflareRouteGlobKeyMatchesRoute(key, routeFile) {
267
+ const normalizedKey = normalizeCloudflareRouteModulePath(key);
268
+ const normalizedRoute = normalizeCloudflareRouteModulePath(routeFile);
269
+ return (normalizedKey === normalizedRoute ||
270
+ normalizedKey.endsWith(`/${normalizedRoute}`));
271
+ }
272
+ function normalizeCloudflareRouteModulePath(path) {
273
+ const withoutPrefix = path
274
+ .replace(/\\/g, "/")
275
+ .replace(/^\.\//, "")
276
+ .replace(/^\/+/, "");
277
+ return withoutPrefix.replace(/\.(?:mjs|js|ts|tsx)$/, "");
278
+ }
279
+ function matchCloudflareRoute(routes, pathname) {
280
+ const normalizedPath = normalizeRoutePath(pathname);
281
+ const pathSegments = normalizedPath === "/" ? [] : normalizedPath.slice(1).split("/");
282
+ for (const route of routes) {
283
+ const params = {};
284
+ const catchAllIndex = route.segments.findIndex((segment) => segment.kind === "catch-all");
285
+ if (catchAllIndex === -1 && route.segments.length !== pathSegments.length) {
286
+ continue;
287
+ }
288
+ if (catchAllIndex !== -1 && pathSegments.length < catchAllIndex + 1) {
289
+ continue;
290
+ }
291
+ let matched = true;
292
+ for (const [index, segment] of route.segments.entries()) {
293
+ const value = pathSegments[index];
294
+ if (value === undefined) {
295
+ matched = false;
296
+ break;
297
+ }
298
+ if (segment.kind === "static") {
299
+ if (segment.value !== value) {
300
+ matched = false;
301
+ break;
302
+ }
303
+ continue;
304
+ }
305
+ if (segment.kind === "dynamic") {
306
+ const decoded = safeDecodePathSegment(value);
307
+ if (decoded === undefined) {
308
+ matched = false;
309
+ break;
310
+ }
311
+ params[segment.name] = decoded;
312
+ continue;
313
+ }
314
+ const decodedParts = [];
315
+ for (const part of pathSegments.slice(index)) {
316
+ const decoded = safeDecodePathSegment(part);
317
+ if (decoded === undefined) {
318
+ matched = false;
319
+ break;
320
+ }
321
+ decodedParts.push(decoded);
322
+ }
323
+ params[segment.name] = decodedParts.join("/");
324
+ break;
325
+ }
326
+ if (matched) {
327
+ return { params, route };
328
+ }
329
+ }
330
+ return undefined;
331
+ }
332
+ function safeDecodePathSegment(segment) {
333
+ try {
334
+ return decodeURIComponent(segment);
335
+ }
336
+ catch {
337
+ return undefined;
338
+ }
339
+ }
340
+ function normalizeAssetPrefix(prefix) {
341
+ const withLeadingSlash = prefix.startsWith("/") ? prefix : `/${prefix}`;
342
+ return withLeadingSlash.endsWith("/") ? withLeadingSlash : `${withLeadingSlash}/`;
343
+ }
344
+ function safeClientAssetPath(prefix, asset) {
345
+ if (asset === undefined || asset === "" || asset.startsWith("/") || asset.includes("\\")) {
346
+ return undefined;
347
+ }
348
+ const segments = asset.split("/");
349
+ if (segments.some((segment) => unsafeAssetSegment(segment))) {
350
+ return undefined;
351
+ }
352
+ return `${prefix}${segments.join("/")}`;
353
+ }
354
+ function unsafeAssetSegment(segment) {
355
+ if (segment === "" || segment === "." || segment === "..") {
356
+ return true;
357
+ }
358
+ try {
359
+ const decoded = decodeURIComponent(segment);
360
+ return decoded === "." || decoded === ".." || decoded.includes("/") || decoded.includes("\\");
361
+ }
362
+ catch {
363
+ return true;
364
+ }
365
+ }
366
+ async function loadCloudflareRouteModule(modules, file) {
367
+ const entry = modules[file];
368
+ return typeof entry === "function" ? await entry() : entry;
369
+ }
370
+ function cloudflareModulePreloadTag(manifest, routePath) {
371
+ const script = manifest.routes.find((route) => route.path === routePath)?.script;
372
+ return script === undefined
373
+ ? ""
374
+ : `<link rel="modulepreload" href="/_mreact/client/${escapeHtmlAttribute(script)}">`;
375
+ }
376
+ function defaultCloudflareDocument(body, modulePreload) {
377
+ return `<!DOCTYPE html>${modulePreload}<html><head></head><body>${body}</body></html>`;
378
+ }
379
+ function prerenderCacheRequest(options, path) {
380
+ const origin = options.keyOrigin ?? defaultPrerenderCacheOrigin;
381
+ const prefix = options.keyPrefix ?? defaultPrerenderCachePrefix;
382
+ const normalizedPath = normalizeRoutePath(path.startsWith("/") ? path : `/${path}`);
383
+ const url = new URL(`${normalizePrerenderPrefix(prefix)}${normalizedPath}`, origin);
384
+ return new Request(url, { method: "GET" });
385
+ }
386
+ function normalizePrerenderPrefix(prefix) {
387
+ const withLeadingSlash = prefix.startsWith("/") ? prefix : `/${prefix}`;
388
+ return withLeadingSlash.replace(/\/+$/, "");
389
+ }
390
+ //# sourceMappingURL=cloudflare.js.map