@tonyclaw/llm-inspector 1.10.0 → 1.11.0

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 (74) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/index-BIZeMR5N.js +105 -0
  3. package/.output/public/assets/index-SmtLx1lM.css +1 -0
  4. package/.output/public/assets/main-QfbQ5oBP.js +17 -0
  5. package/.output/server/_libs/@radix-ui/react-use-controllable-state+[...].mjs +1 -1
  6. package/.output/server/_libs/ajv-formats.mjs +18 -18
  7. package/.output/server/_libs/ajv.mjs +6306 -942
  8. package/.output/server/_libs/cookie-es.mjs +21 -7
  9. package/.output/server/_libs/diff.mjs +320 -0
  10. package/.output/server/_libs/floating-ui__core.mjs +17 -18
  11. package/.output/server/_libs/floating-ui__dom.mjs +20 -24
  12. package/.output/server/_libs/floating-ui__react-dom.mjs +28 -55
  13. package/.output/server/_libs/floating-ui__utils.mjs +36 -36
  14. package/.output/server/_libs/h3-v2.mjs +9 -20
  15. package/.output/server/_libs/isbot.mjs +2 -3
  16. package/.output/server/_libs/json-schema-traverse.mjs +90 -1
  17. package/.output/server/_libs/jszip.mjs +28 -28
  18. package/.output/server/_libs/lucide-react.mjs +103 -80
  19. package/.output/server/_libs/mdast-util-from-markdown.mjs +1 -1
  20. package/.output/server/_libs/pako.mjs +13 -13
  21. package/.output/server/_libs/property-information.mjs +1 -13
  22. package/.output/server/_libs/radix-ui__react-collection.mjs +1 -1
  23. package/.output/server/_libs/radix-ui__react-id.mjs +1 -1
  24. package/.output/server/_libs/react-dom.mjs +10 -10
  25. package/.output/server/_libs/react.mjs +44 -44
  26. package/.output/server/_libs/readable-stream.mjs +15 -15
  27. package/.output/server/_libs/rou3.mjs +7 -1
  28. package/.output/server/_libs/safe-buffer.mjs +3 -3
  29. package/.output/server/_libs/semver.mjs +10 -10
  30. package/.output/server/_libs/seroval-plugins.mjs +5 -5
  31. package/.output/server/_libs/seroval.mjs +596 -606
  32. package/.output/server/_libs/srvx.mjs +245 -10
  33. package/.output/server/_libs/swr.mjs +1 -1
  34. package/.output/server/_libs/tailwind-merge.mjs +41 -286
  35. package/.output/server/_libs/tanstack__history.mjs +44 -31
  36. package/.output/server/_libs/tanstack__react-router.mjs +1089 -780
  37. package/.output/server/_libs/tanstack__react-store.mjs +1 -1
  38. package/.output/server/_libs/tanstack__react-virtual.mjs +7 -82
  39. package/.output/server/_libs/tanstack__router-core.mjs +2331 -2226
  40. package/.output/server/_libs/tanstack__virtual-core.mjs +17 -58
  41. package/.output/server/_libs/tiny-invariant.mjs +12 -0
  42. package/.output/server/_libs/tiny-warning.mjs +5 -0
  43. package/.output/server/_libs/ungap__structured-clone.mjs +2 -14
  44. package/.output/server/_libs/use-sync-external-store.mjs +1 -1
  45. package/.output/server/_libs/zod.mjs +207 -505
  46. package/.output/server/_ssr/{index-XyU4WVWt.mjs → index-I_Nx8QEB.mjs} +532 -79
  47. package/.output/server/_ssr/index.mjs +776 -1098
  48. package/.output/server/_ssr/{router-BR4XO8XJ.mjs → router-BVxfVFsb.mjs} +98 -53
  49. package/.output/server/_tanstack-start-manifest_v-Cm2Owszu.mjs +4 -0
  50. package/.output/server/index.mjs +28 -28
  51. package/README.md +1 -1
  52. package/package.json +2 -1
  53. package/src/components/ProxyViewer.tsx +10 -3
  54. package/src/components/ProxyViewerContainer.tsx +6 -0
  55. package/src/components/proxy-viewer/ConversationGroup.tsx +10 -1
  56. package/src/components/proxy-viewer/LogEntry.tsx +114 -5
  57. package/src/components/proxy-viewer/diff/DiffView.tsx +319 -0
  58. package/src/components/proxy-viewer/diff/computeDiff.ts +178 -0
  59. package/src/components/proxy-viewer/diff/index.ts +3 -0
  60. package/src/components/ui/crab-logo.tsx +45 -0
  61. package/src/proxy/config.ts +3 -17
  62. package/src/proxy/dataDir.ts +56 -0
  63. package/src/proxy/formats/anthropic/stream.ts +5 -2
  64. package/src/proxy/formats/jsonSchema.ts +12 -0
  65. package/src/proxy/formats/openai/stream.ts +21 -16
  66. package/src/proxy/handler.ts +15 -5
  67. package/src/proxy/providers.ts +61 -1
  68. package/src/proxy/schemas.ts +42 -0
  69. package/src/proxy/store.ts +6 -23
  70. package/.output/public/assets/index-BFuUQkWu.js +0 -11
  71. package/.output/public/assets/index-F2ojFPJp.css +0 -1
  72. package/.output/public/assets/index-nKnhyW4Y.js +0 -122
  73. package/.output/server/_ssr/empty-plugin-adapters-BFgPZ6_d.mjs +0 -6
  74. package/.output/server/_tanstack-start-manifest_v-DFoSjBkb.mjs +0 -4
@@ -1,20 +1,22 @@
1
+ import { c as createMemoryHistory } from "../_libs/tanstack__history.mjs";
2
+ import { a as rootRouteId, o as getNormalizedURL, p as getOrigin, q as attachRouterServerSsrUtils, u as defineHandlerCallback, v as createSerializationAdapter, w as createRawStreamRPCPlugin, i as isNotFound, b as isRedirect, x as isResolvedRedirect, y as mergeHeaders, z as executeRewriteInput, A as defaultSerovalPlugins, C as makeSerovalPlugin } from "../_libs/tanstack__router-core.mjs";
1
3
  import { AsyncLocalStorage } from "node:async_hooks";
2
4
  import { H as H3Event, t as toResponse } from "../_libs/h3-v2.mjs";
3
- import { y as resolveManifestAssetLink, u as resolveManifestCssLink, k as rootRouteId, z as getNormalizedURL, A as getOrigin, C as normalizeSsrResponse, D as attachRouterServerSsrUtils, E as defineHandlerCallback, F as createSerializationAdapter, G as createRawStreamRPCPlugin, i as invariant, g as isNotFound, m as isRedirect, H as isResolvedRedirect, I as replaceSsrResponse, J as mergeHeaders, K as executeRewriteInput, L as stripSsrResponseBody, M as defaultSerovalPlugins, N as makeSerovalPlugin, s as getScriptPreloadAttrs, O as getStylesheetHref, P as isSsrResponse } from "../_libs/tanstack__router-core.mjs";
4
- import { i as iu, P as Pu, s as su } from "../_libs/seroval.mjs";
5
- import { c as createMemoryHistory } from "../_libs/tanstack__history.mjs";
5
+ import { i as invariant } from "../_libs/tiny-invariant.mjs";
6
+ import { a as au, I as Iu, o as ou } from "../_libs/seroval.mjs";
6
7
  import { j as jsxRuntimeExports } from "../_libs/react.mjs";
7
8
  import { r as renderRouterToStream, R as RouterProvider } from "../_libs/tanstack__react-router.mjs";
9
+ import "../_libs/cookie-es.mjs";
10
+ import "../_libs/seroval-plugins.mjs";
11
+ import "node:stream/web";
12
+ import "node:stream";
8
13
  import "../_libs/rou3.mjs";
9
14
  import "../_libs/srvx.mjs";
10
15
  import "node:http";
11
- import "node:stream";
12
16
  import "node:stream/promises";
13
17
  import "node:https";
14
18
  import "node:http2";
15
- import "../_libs/cookie-es.mjs";
16
- import "../_libs/seroval-plugins.mjs";
17
- import "node:stream/web";
19
+ import "../_libs/tiny-warning.mjs";
18
20
  import "../_libs/react-dom.mjs";
19
21
  import "util";
20
22
  import "async_hooks";
@@ -24,108 +26,20 @@ import "../_libs/isbot.mjs";
24
26
  function StartServer(props) {
25
27
  return /* @__PURE__ */ jsxRuntimeExports.jsx(RouterProvider, { router: props.router });
26
28
  }
27
- var defaultStreamHandler = defineHandlerCallback(({ request, router, responseHeaders }) => renderRouterToStream({
28
- request,
29
- router,
30
- responseHeaders,
31
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(StartServer, { router })
32
- }));
33
- var GLOBAL_EVENT_STORAGE_KEY = /* @__PURE__ */ Symbol.for("tanstack-start:event-storage");
34
- var globalObj$1 = globalThis;
35
- if (!globalObj$1[GLOBAL_EVENT_STORAGE_KEY]) globalObj$1[GLOBAL_EVENT_STORAGE_KEY] = new AsyncLocalStorage();
36
- var eventStorage = globalObj$1[GLOBAL_EVENT_STORAGE_KEY];
37
- function isPromiseLike(value) {
38
- return typeof value.then === "function";
39
- }
40
- function getSetCookieValues(headers) {
41
- const headersWithSetCookie = headers;
42
- if (typeof headersWithSetCookie.getSetCookie === "function") return headersWithSetCookie.getSetCookie();
43
- const value = headers.get("set-cookie");
44
- return value ? [value] : [];
45
- }
46
- function mergeEventResponseHeaders(response, event) {
47
- if (response.ok) return;
48
- const eventSetCookies = getSetCookieValues(event.res.headers);
49
- if (eventSetCookies.length === 0) return;
50
- const responseSetCookies = getSetCookieValues(response.headers);
51
- response.headers.delete("set-cookie");
52
- for (const cookie of responseSetCookies) response.headers.append("set-cookie", cookie);
53
- for (const cookie of eventSetCookies) response.headers.append("set-cookie", cookie);
54
- }
55
- function attachResponseHeaders(value, event) {
56
- if (isPromiseLike(value)) return value.then((resolved) => {
57
- if (resolved instanceof Response) mergeEventResponseHeaders(resolved, event);
58
- return resolved;
59
- });
60
- if (value instanceof Response) mergeEventResponseHeaders(value, event);
61
- return value;
62
- }
63
- function requestHandler(handler) {
64
- return (request, requestOpts) => {
65
- let h3Event;
66
- try {
67
- h3Event = new H3Event(request);
68
- } catch (error) {
69
- if (error instanceof URIError) return new Response(null, {
70
- status: 400,
71
- statusText: "Bad Request"
72
- });
73
- throw error;
74
- }
75
- return toResponse(attachResponseHeaders(eventStorage.run({ h3Event }, () => handler(request, requestOpts)), h3Event), h3Event);
76
- };
77
- }
78
- function getH3Event() {
79
- const event = eventStorage.getStore();
80
- if (!event) throw new Error(`No StartEvent found in AsyncLocalStorage. Make sure you are using the function within the server runtime.`);
81
- return event.h3Event;
82
- }
83
- function getResponse() {
84
- return getH3Event().res;
85
- }
86
- var HEADERS = { TSS_SHELL: "X-TSS_SHELL" };
87
- async function getStartManifest(matchedRoutes) {
88
- const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-DFoSjBkb.mjs");
89
- const startManifest = tsrStartManifest();
90
- let routes = startManifest.routes;
91
- routes[rootRouteId];
92
- const manifestRoutes = {};
93
- for (const k in routes) {
94
- const v = routes[k];
95
- const result = {};
96
- if (v.preloads && v.preloads.length > 0) result.preloads = v.preloads;
97
- if (v.scripts && v.scripts.length > 0) result.scripts = v.scripts;
98
- if (v.css?.length) result.css = v.css;
99
- if (result.preloads || result.scripts || result.css) manifestRoutes[k] = result;
100
- }
101
- return {
102
- ...startManifest.scriptFormat ? { scriptFormat: startManifest.scriptFormat } : {},
103
- ...startManifest.inlineCss ? { inlineCss: startManifest.inlineCss } : {},
104
- routes: manifestRoutes
105
- };
106
- }
107
- const manifest = {};
108
- async function getServerFnById(id, access) {
109
- const serverFnInfo = manifest[id];
110
- if (!serverFnInfo) {
111
- throw new Error("Server function info not found for " + id);
112
- }
113
- const fnModule = serverFnInfo.module ?? await serverFnInfo.importer();
114
- if (!fnModule) {
115
- throw new Error("Server function module not resolved for " + id);
116
- }
117
- const action = fnModule[serverFnInfo.functionName];
118
- if (!action) {
119
- throw new Error("Server function module export not resolved for serverFn ID: " + id);
120
- }
121
- return action;
122
- }
123
- var TSS_FORMDATA_CONTEXT = "__TSS_CONTEXT";
124
- var TSS_SERVER_FUNCTION = /* @__PURE__ */ Symbol.for("TSS_SERVER_FUNCTION");
125
- var X_TSS_SERIALIZED = "x-tss-serialized";
126
- var X_TSS_RAW_RESPONSE = "x-tss-raw";
127
- var TSS_CONTENT_TYPE_FRAMED = "application/x-tss-framed";
128
- var FrameType = {
29
+ const defaultStreamHandler = defineHandlerCallback(
30
+ ({ request, router, responseHeaders }) => renderRouterToStream({
31
+ request,
32
+ router,
33
+ responseHeaders,
34
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(StartServer, { router })
35
+ })
36
+ );
37
+ const TSS_FORMDATA_CONTEXT = "__TSS_CONTEXT";
38
+ const TSS_SERVER_FUNCTION = /* @__PURE__ */ Symbol.for("TSS_SERVER_FUNCTION");
39
+ const X_TSS_SERIALIZED = "x-tss-serialized";
40
+ const X_TSS_RAW_RESPONSE = "x-tss-raw";
41
+ const TSS_CONTENT_TYPE_FRAMED = "application/x-tss-framed";
42
+ const FrameType = {
129
43
  /** Seroval JSON chunk (NDJSON line) */
130
44
  JSON: 0,
131
45
  /** Raw stream data chunk */
@@ -135,47 +49,66 @@ var FrameType = {
135
49
  /** Raw stream error */
136
50
  ERROR: 3
137
51
  };
138
- var FRAME_HEADER_SIZE = 9;
139
- var TSS_CONTENT_TYPE_FRAMED_VERSIONED = `${TSS_CONTENT_TYPE_FRAMED}; v=1`;
52
+ const FRAME_HEADER_SIZE = 9;
53
+ const TSS_FRAMED_PROTOCOL_VERSION = 1;
54
+ const TSS_CONTENT_TYPE_FRAMED_VERSIONED = `${TSS_CONTENT_TYPE_FRAMED}; v=${TSS_FRAMED_PROTOCOL_VERSION}`;
55
+ const GLOBAL_STORAGE_KEY = /* @__PURE__ */ Symbol.for("tanstack-start:start-storage-context");
56
+ const globalObj$1 = globalThis;
57
+ if (!globalObj$1[GLOBAL_STORAGE_KEY]) {
58
+ globalObj$1[GLOBAL_STORAGE_KEY] = new AsyncLocalStorage();
59
+ }
60
+ const startStorage = globalObj$1[GLOBAL_STORAGE_KEY];
61
+ async function runWithStartContext(context, fn) {
62
+ return startStorage.run(context, fn);
63
+ }
64
+ function getStartContext(opts) {
65
+ const context = startStorage.getStore();
66
+ if (!context && opts?.throwIfNotFound !== false) {
67
+ throw new Error(
68
+ `No Start context found in AsyncLocalStorage. Make sure you are using the function within the server runtime.`
69
+ );
70
+ }
71
+ return context;
72
+ }
73
+ const getStartOptions = () => getStartContext().startOptions;
140
74
  function isSafeKey(key) {
141
75
  return key !== "__proto__" && key !== "constructor" && key !== "prototype";
142
76
  }
143
77
  function safeObjectMerge(target, source) {
144
78
  const result = /* @__PURE__ */ Object.create(null);
145
79
  if (target) {
146
- for (const key of Object.keys(target)) if (isSafeKey(key)) result[key] = target[key];
80
+ for (const key of Object.keys(target)) {
81
+ if (isSafeKey(key)) result[key] = target[key];
82
+ }
147
83
  }
148
84
  if (source && typeof source === "object") {
149
- for (const key of Object.keys(source)) if (isSafeKey(key)) result[key] = source[key];
85
+ for (const key of Object.keys(source)) {
86
+ if (isSafeKey(key)) result[key] = source[key];
87
+ }
150
88
  }
151
89
  return result;
152
90
  }
153
91
  function createNullProtoObject(source) {
154
92
  if (!source) return /* @__PURE__ */ Object.create(null);
155
93
  const obj = /* @__PURE__ */ Object.create(null);
156
- for (const key of Object.keys(source)) if (isSafeKey(key)) obj[key] = source[key];
94
+ for (const key of Object.keys(source)) {
95
+ if (isSafeKey(key)) obj[key] = source[key];
96
+ }
157
97
  return obj;
158
98
  }
159
- var GLOBAL_STORAGE_KEY = /* @__PURE__ */ Symbol.for("tanstack-start:start-storage-context");
160
- var globalObj = globalThis;
161
- if (!globalObj[GLOBAL_STORAGE_KEY]) globalObj[GLOBAL_STORAGE_KEY] = new AsyncLocalStorage();
162
- var startStorage = globalObj[GLOBAL_STORAGE_KEY];
163
- async function runWithStartContext(context, fn) {
164
- return startStorage.run(context, fn);
165
- }
166
- function getStartContext(opts) {
167
- const context = startStorage.getStore();
168
- if (!context && opts?.throwIfNotFound !== false) throw new Error(`No Start context found in AsyncLocalStorage. Make sure you are using the function within the server runtime.`);
169
- return context;
170
- }
171
- var getStartOptions = () => getStartContext().startOptions;
172
99
  function flattenMiddlewares(middlewares, maxDepth = 100) {
173
100
  const seen = /* @__PURE__ */ new Set();
174
101
  const flattened = [];
175
102
  const recurse = (middleware, depth) => {
176
- if (depth > maxDepth) throw new Error(`Middleware nesting depth exceeded maximum of ${maxDepth}. Check for circular references.`);
103
+ if (depth > maxDepth) {
104
+ throw new Error(
105
+ `Middleware nesting depth exceeded maximum of ${maxDepth}. Check for circular references.`
106
+ );
107
+ }
177
108
  middleware.forEach((m) => {
178
- if (m.options.middleware) recurse(m.options.middleware, depth + 1);
109
+ if (m.options.middleware) {
110
+ recurse(m.options.middleware, depth + 1);
111
+ }
179
112
  if (!seen.has(m)) {
180
113
  seen.add(m);
181
114
  flattened.push(m);
@@ -185,88 +118,119 @@ function flattenMiddlewares(middlewares, maxDepth = 100) {
185
118
  recurse(middlewares, 0);
186
119
  return flattened;
187
120
  }
188
- var createMiddleware = (options, __opts) => {
189
- const resolvedOptions = {
190
- type: "request",
191
- ...__opts || options
192
- };
193
- return {
194
- options: resolvedOptions,
195
- middleware: (middleware) => {
196
- return createMiddleware({}, Object.assign(resolvedOptions, { middleware }));
197
- },
198
- inputValidator: (inputValidator) => {
199
- return createMiddleware({}, Object.assign(resolvedOptions, { inputValidator }));
200
- },
201
- client: (client) => {
202
- return createMiddleware({}, Object.assign(resolvedOptions, { client }));
203
- },
204
- server: (server2) => {
205
- return createMiddleware({}, Object.assign(resolvedOptions, { server: server2 }));
206
- }
207
- };
208
- };
209
- var innerCreateCsrfMiddleware = (opts = {}) => {
210
- const middleware = createMiddleware().server(async (ctx) => {
211
- const csrfCtx = ctx;
212
- if (opts.filter && !await opts.filter(csrfCtx)) return ctx.next();
213
- if (await isCsrfRequestAllowed(opts, csrfCtx)) return ctx.next();
214
- return getFailureResponse(opts, csrfCtx);
215
- });
216
- return middleware;
217
- };
218
- var createCsrfMiddleware = innerCreateCsrfMiddleware;
219
- async function isCsrfRequestAllowed(opts, ctx) {
220
- const result = await getCsrfRequestValidationResult(opts, ctx);
221
- return result === true || result === void 0 && opts.allowRequestsWithoutOriginCheck === true;
121
+ function getDefaultSerovalPlugins() {
122
+ const start = getStartOptions();
123
+ const adapters = start?.serializationAdapters;
124
+ return [
125
+ ...adapters?.map(makeSerovalPlugin) ?? [],
126
+ ...defaultSerovalPlugins
127
+ ];
128
+ }
129
+ const GLOBAL_EVENT_STORAGE_KEY = /* @__PURE__ */ Symbol.for("tanstack-start:event-storage");
130
+ const globalObj = globalThis;
131
+ if (!globalObj[GLOBAL_EVENT_STORAGE_KEY]) {
132
+ globalObj[GLOBAL_EVENT_STORAGE_KEY] = new AsyncLocalStorage();
133
+ }
134
+ const eventStorage = globalObj[GLOBAL_EVENT_STORAGE_KEY];
135
+ function isPromiseLike(value) {
136
+ return typeof value.then === "function";
222
137
  }
223
- async function getCsrfRequestValidationResult(opts, ctx) {
224
- const fetchSite = ctx.request.headers.get("Sec-Fetch-Site");
225
- if (fetchSite !== null) return matchValue(opts.secFetchSite ?? "same-origin", fetchSite, ctx);
226
- const origin = ctx.request.headers.get("Origin");
227
- if (origin !== null) {
228
- if (opts.origin) return matchValue(opts.origin, origin, ctx);
229
- return origin === new URL(ctx.request.url).origin;
230
- }
231
- const referer = ctx.request.headers.get("Referer");
232
- if (referer === null || opts.referer === false) return;
233
- if (typeof opts.referer === "function") return opts.referer(referer, ctx);
234
- if (opts.origin) {
235
- const refererOrigin = getOriginFromUrl(referer);
236
- return refererOrigin !== void 0 && matchValue(opts.origin, refererOrigin, ctx);
138
+ function getSetCookieValues(headers) {
139
+ const headersWithSetCookie = headers;
140
+ if (typeof headersWithSetCookie.getSetCookie === "function") {
141
+ return headersWithSetCookie.getSetCookie();
237
142
  }
238
- return isRefererSameOrigin(referer, new URL(ctx.request.url).origin);
239
- }
240
- async function matchValue(matcher, value, ctx) {
241
- if (typeof matcher === "function") return matcher(value, ctx);
242
- if (Array.isArray(matcher)) return matcher.includes(value);
243
- return value === matcher;
143
+ const value = headers.get("set-cookie");
144
+ return value ? [value] : [];
244
145
  }
245
- function getOriginFromUrl(url) {
246
- try {
247
- return new URL(url).origin;
248
- } catch {
146
+ function mergeEventResponseHeaders(response, event) {
147
+ if (response.ok) {
148
+ return;
149
+ }
150
+ const eventSetCookies = getSetCookieValues(event.res.headers);
151
+ if (eventSetCookies.length === 0) {
249
152
  return;
250
153
  }
154
+ const responseSetCookies = getSetCookieValues(response.headers);
155
+ response.headers.delete("set-cookie");
156
+ for (const cookie of responseSetCookies) {
157
+ response.headers.append("set-cookie", cookie);
158
+ }
159
+ for (const cookie of eventSetCookies) {
160
+ response.headers.append("set-cookie", cookie);
161
+ }
251
162
  }
252
- function isRefererSameOrigin(referer, requestOrigin) {
253
- if (referer === requestOrigin) return true;
254
- if (!referer.startsWith(requestOrigin)) return false;
255
- if (referer.length === requestOrigin.length) return true;
256
- const code = referer.charCodeAt(requestOrigin.length);
257
- return code === 47 || code === 63 || code === 35;
163
+ function attachResponseHeaders(value, event) {
164
+ if (isPromiseLike(value)) {
165
+ return value.then((resolved) => {
166
+ if (resolved instanceof Response) {
167
+ mergeEventResponseHeaders(resolved, event);
168
+ }
169
+ return resolved;
170
+ });
171
+ }
172
+ if (value instanceof Response) {
173
+ mergeEventResponseHeaders(value, event);
174
+ }
175
+ return value;
258
176
  }
259
- async function getFailureResponse(opts, ctx) {
260
- if (typeof opts.failureResponse === "function") return opts.failureResponse(ctx);
261
- return opts.failureResponse?.clone() ?? new Response("Forbidden", {
262
- status: 403
263
- });
177
+ function requestHandler(handler) {
178
+ return (request, requestOpts) => {
179
+ const h3Event = new H3Event(request);
180
+ const response = eventStorage.run(
181
+ { h3Event },
182
+ () => handler(request, requestOpts)
183
+ );
184
+ return toResponse(attachResponseHeaders(response, h3Event), h3Event);
185
+ };
264
186
  }
265
- function getDefaultSerovalPlugins() {
266
- return [...getStartOptions()?.serializationAdapters?.map(makeSerovalPlugin) ?? [], ...defaultSerovalPlugins];
187
+ function getH3Event() {
188
+ const event = eventStorage.getStore();
189
+ if (!event) {
190
+ throw new Error(
191
+ `No StartEvent found in AsyncLocalStorage. Make sure you are using the function within the server runtime.`
192
+ );
193
+ }
194
+ return event.h3Event;
267
195
  }
268
- var textEncoder = new TextEncoder();
269
- var EMPTY_PAYLOAD = new Uint8Array(0);
196
+ function getResponse() {
197
+ const event = getH3Event();
198
+ return event.res;
199
+ }
200
+ async function getStartManifest(matchedRoutes) {
201
+ const { tsrStartManifest } = await import("../_tanstack-start-manifest_v-Cm2Owszu.mjs");
202
+ const startManifest = tsrStartManifest();
203
+ const rootRoute = startManifest.routes[rootRouteId] = startManifest.routes[rootRouteId] || {};
204
+ rootRoute.assets = rootRoute.assets || [];
205
+ let injectedHeadScripts;
206
+ const manifest2 = {
207
+ routes: Object.fromEntries(
208
+ Object.entries(startManifest.routes).flatMap(([k, v]) => {
209
+ const result = {};
210
+ let hasData = false;
211
+ if (v.preloads && v.preloads.length > 0) {
212
+ result["preloads"] = v.preloads;
213
+ hasData = true;
214
+ }
215
+ if (v.assets && v.assets.length > 0) {
216
+ result["assets"] = v.assets;
217
+ hasData = true;
218
+ }
219
+ if (!hasData) {
220
+ return [];
221
+ }
222
+ return [[k, result]];
223
+ })
224
+ )
225
+ };
226
+ return {
227
+ manifest: manifest2,
228
+ clientEntry: startManifest.clientEntry,
229
+ injectedHeadScripts
230
+ };
231
+ }
232
+ const textEncoder$1 = new TextEncoder();
233
+ const EMPTY_PAYLOAD = new Uint8Array(0);
270
234
  function encodeFrame(type, streamId, payload) {
271
235
  const frame = new Uint8Array(FRAME_HEADER_SIZE + payload.length);
272
236
  frame[0] = type;
@@ -282,7 +246,7 @@ function encodeFrame(type, streamId, payload) {
282
246
  return frame;
283
247
  }
284
248
  function encodeJSONFrame(json) {
285
- return encodeFrame(FrameType.JSON, 0, textEncoder.encode(json));
249
+ return encodeFrame(FrameType.JSON, 0, textEncoder$1.encode(json));
286
250
  }
287
251
  function encodeChunkFrame(streamId, chunk) {
288
252
  return encodeFrame(FrameType.CHUNK, streamId, chunk);
@@ -292,151 +256,162 @@ function encodeEndFrame(streamId) {
292
256
  }
293
257
  function encodeErrorFrame(streamId, error) {
294
258
  const message = error instanceof Error ? error.message : String(error ?? "Unknown error");
295
- return encodeFrame(FrameType.ERROR, streamId, textEncoder.encode(message));
259
+ return encodeFrame(FrameType.ERROR, streamId, textEncoder$1.encode(message));
296
260
  }
297
- function createMultiplexedStream(jsonStream, rawStreams, lateStreamSource) {
298
- let controller;
261
+ function createMultiplexedStream(jsonStream, rawStreams) {
262
+ let activePumps = 1 + rawStreams.size;
263
+ let controllerRef = null;
299
264
  let cancelled = false;
300
- const readers = [];
301
- const enqueue = (frame) => {
302
- if (cancelled) return false;
265
+ const cancelReaders = [];
266
+ const safeEnqueue = (chunk) => {
267
+ if (cancelled || !controllerRef) return;
303
268
  try {
304
- controller.enqueue(frame);
305
- return true;
269
+ controllerRef.enqueue(chunk);
306
270
  } catch {
307
- return false;
308
271
  }
309
272
  };
310
- const errorOutput = (error) => {
311
- if (cancelled) return;
312
- cancelled = true;
273
+ const safeError = (err) => {
274
+ if (cancelled || !controllerRef) return;
313
275
  try {
314
- controller.error(error);
276
+ controllerRef.error(err);
315
277
  } catch {
316
278
  }
317
- for (const reader of readers) reader.cancel().catch(() => {
318
- });
319
279
  };
320
- async function pumpRawStream(streamId, stream) {
321
- const reader = stream.getReader();
322
- readers.push(reader);
280
+ const safeClose = () => {
281
+ if (cancelled || !controllerRef) return;
323
282
  try {
324
- while (!cancelled) {
325
- const { done, value } = await reader.read();
326
- if (done) {
327
- enqueue(encodeEndFrame(streamId));
328
- return;
329
- }
330
- if (!enqueue(encodeChunkFrame(streamId, value))) return;
331
- }
332
- } catch (error) {
333
- enqueue(encodeErrorFrame(streamId, error));
334
- } finally {
335
- reader.releaseLock();
336
- }
337
- }
338
- async function pumpJSON() {
339
- const reader = jsonStream.getReader();
340
- readers.push(reader);
341
- try {
342
- while (!cancelled) {
343
- const { done, value } = await reader.read();
344
- if (done) return;
345
- if (!enqueue(encodeJSONFrame(value))) return;
346
- }
347
- } catch (error) {
348
- errorOutput(error);
349
- throw error;
350
- } finally {
351
- reader.releaseLock();
283
+ controllerRef.close();
284
+ } catch {
352
285
  }
353
- }
354
- async function pumpLateStreams() {
355
- if (!lateStreamSource) return [];
356
- const lateStreamPumps = [];
357
- const reader = lateStreamSource.getReader();
358
- readers.push(reader);
359
- try {
360
- while (!cancelled) {
361
- const { done, value } = await reader.read();
362
- if (done) break;
363
- lateStreamPumps.push(pumpRawStream(value.id, value.stream));
364
- }
365
- } finally {
366
- reader.releaseLock();
286
+ };
287
+ const checkComplete = () => {
288
+ activePumps--;
289
+ if (activePumps === 0) {
290
+ safeClose();
367
291
  }
368
- return lateStreamPumps;
369
- }
292
+ };
370
293
  return new ReadableStream({
371
- async start(ctrl) {
372
- controller = ctrl;
373
- const pumps = [pumpJSON()];
374
- for (const [streamId, stream] of rawStreams) pumps.push(pumpRawStream(streamId, stream));
375
- if (lateStreamSource) pumps.push(pumpLateStreams());
376
- try {
377
- const latePumps = (await Promise.all(pumps)).find(Array.isArray);
378
- if (latePumps && latePumps.length > 0) await Promise.all(latePumps);
379
- if (!cancelled) try {
380
- controller.close();
381
- } catch {
294
+ start(controller) {
295
+ controllerRef = controller;
296
+ cancelReaders.length = 0;
297
+ const pumpJSON = async () => {
298
+ const reader = jsonStream.getReader();
299
+ cancelReaders.push(() => {
300
+ reader.cancel().catch(() => {
301
+ });
302
+ });
303
+ try {
304
+ while (true) {
305
+ const { done, value } = await reader.read();
306
+ if (cancelled) break;
307
+ if (done) break;
308
+ safeEnqueue(encodeJSONFrame(value));
309
+ }
310
+ } catch (error) {
311
+ safeError(error);
312
+ } finally {
313
+ reader.releaseLock();
314
+ checkComplete();
315
+ }
316
+ };
317
+ const pumpRawStream = async (streamId, stream) => {
318
+ const reader = stream.getReader();
319
+ cancelReaders.push(() => {
320
+ reader.cancel().catch(() => {
321
+ });
322
+ });
323
+ try {
324
+ while (true) {
325
+ const { done, value } = await reader.read();
326
+ if (cancelled) break;
327
+ if (done) {
328
+ safeEnqueue(encodeEndFrame(streamId));
329
+ break;
330
+ }
331
+ safeEnqueue(encodeChunkFrame(streamId, value));
332
+ }
333
+ } catch (error) {
334
+ safeEnqueue(encodeErrorFrame(streamId, error));
335
+ } finally {
336
+ reader.releaseLock();
337
+ checkComplete();
382
338
  }
383
- } catch {
339
+ };
340
+ pumpJSON();
341
+ for (const [streamId, stream] of rawStreams) {
342
+ pumpRawStream(streamId, stream);
384
343
  }
385
344
  },
386
345
  cancel() {
387
346
  cancelled = true;
388
- for (const reader of readers) reader.cancel().catch(() => {
389
- });
390
- readers.length = 0;
347
+ controllerRef = null;
348
+ for (const cancelReader of cancelReaders) {
349
+ cancelReader();
350
+ }
351
+ cancelReaders.length = 0;
391
352
  }
392
353
  });
393
354
  }
394
- var serovalPlugins = void 0;
395
- var FORM_DATA_CONTENT_TYPES = ["multipart/form-data", "application/x-www-form-urlencoded"];
396
- var MAX_PAYLOAD_SIZE = 1e6;
397
- var handleServerAction = async ({ request, context, serverFnId }) => {
398
- const methodUpper = request.method.toUpperCase();
355
+ const manifest = {};
356
+ async function getServerFnById(id) {
357
+ const serverFnInfo = manifest[id];
358
+ if (!serverFnInfo) {
359
+ throw new Error("Server function info not found for " + id);
360
+ }
361
+ const fnModule = await serverFnInfo.importer();
362
+ if (!fnModule) {
363
+ console.info("serverFnInfo", serverFnInfo);
364
+ throw new Error("Server function module not resolved for " + id);
365
+ }
366
+ const action = fnModule[serverFnInfo.functionName];
367
+ if (!action) {
368
+ console.info("serverFnInfo", serverFnInfo);
369
+ console.info("fnModule", fnModule);
370
+ throw new Error(
371
+ `Server function module export not resolved for serverFn ID: ${id}`
372
+ );
373
+ }
374
+ return action;
375
+ }
376
+ let serovalPlugins = void 0;
377
+ const textEncoder = new TextEncoder();
378
+ const FORM_DATA_CONTENT_TYPES = [
379
+ "multipart/form-data",
380
+ "application/x-www-form-urlencoded"
381
+ ];
382
+ const MAX_PAYLOAD_SIZE = 1e6;
383
+ const handleServerAction = async ({
384
+ request,
385
+ context,
386
+ serverFnId
387
+ }) => {
388
+ const method = request.method;
389
+ const methodUpper = method.toUpperCase();
390
+ const methodLower = method.toLowerCase();
399
391
  const url = new URL(request.url);
400
392
  const action = await getServerFnById(serverFnId);
401
- if (action.method && methodUpper !== action.method) return new Response(`expected ${action.method} method. Got ${methodUpper}`, {
402
- status: 405,
403
- headers: { Allow: action.method }
404
- });
405
393
  const isServerFn = request.headers.get("x-tsr-serverFn") === "true";
406
- if (!serovalPlugins) serovalPlugins = getDefaultSerovalPlugins();
394
+ if (!serovalPlugins) {
395
+ serovalPlugins = getDefaultSerovalPlugins();
396
+ }
407
397
  const contentType = request.headers.get("Content-Type");
408
398
  function parsePayload(payload) {
409
- return Pu(payload, { plugins: serovalPlugins });
399
+ const parsedPayload = Iu(payload, { plugins: serovalPlugins });
400
+ return parsedPayload;
410
401
  }
411
- return await (async () => {
402
+ const response = await (async () => {
412
403
  try {
413
404
  let serializeResult = function(res2) {
414
405
  let nonStreamingBody = void 0;
415
406
  const alsResponse = getResponse();
416
407
  if (res2 !== void 0) {
417
408
  const rawStreams = /* @__PURE__ */ new Map();
418
- let initialPhase = true;
419
- let lateStreamWriter;
420
- let lateStreamReadable = void 0;
421
- const pendingLateStreams = [];
422
- const plugins = [createRawStreamRPCPlugin((id, stream) => {
423
- if (initialPhase) {
424
- rawStreams.set(id, stream);
425
- return;
426
- }
427
- if (lateStreamWriter) {
428
- lateStreamWriter.write({
429
- id,
430
- stream
431
- }).catch(() => {
432
- });
433
- return;
409
+ const rawStreamPlugin = createRawStreamRPCPlugin(
410
+ (id, stream2) => {
411
+ rawStreams.set(id, stream2);
434
412
  }
435
- pendingLateStreams.push({
436
- id,
437
- stream
438
- });
439
- }), ...serovalPlugins || []];
413
+ );
414
+ const plugins = [rawStreamPlugin, ...serovalPlugins || []];
440
415
  let done = false;
441
416
  const callbacks = {
442
417
  onParse: (value) => {
@@ -449,7 +424,7 @@ var handleServerAction = async ({ request, context, serverFnId }) => {
449
424
  throw error;
450
425
  }
451
426
  };
452
- iu(res2, {
427
+ au(res2, {
453
428
  refs: /* @__PURE__ */ new Map(),
454
429
  plugins,
455
430
  onParse(value) {
@@ -462,57 +437,73 @@ var handleServerAction = async ({ request, context, serverFnId }) => {
462
437
  callbacks.onError(error);
463
438
  }
464
439
  });
465
- initialPhase = false;
466
- if (done && rawStreams.size === 0) return new Response(nonStreamingBody ? JSON.stringify(nonStreamingBody) : void 0, {
467
- status: alsResponse.status,
468
- statusText: alsResponse.statusText,
469
- headers: {
470
- "Content-Type": "application/json",
471
- [X_TSS_SERIALIZED]: "true"
472
- }
473
- });
474
- const { readable, writable } = new TransformStream();
475
- lateStreamReadable = readable;
476
- lateStreamWriter = writable.getWriter();
477
- for (const registration of pendingLateStreams) lateStreamWriter.write(registration).catch(() => {
478
- });
479
- pendingLateStreams.length = 0;
480
- const multiplexedStream = createMultiplexedStream(new ReadableStream({
440
+ if (done && rawStreams.size === 0) {
441
+ return new Response(
442
+ nonStreamingBody ? JSON.stringify(nonStreamingBody) : void 0,
443
+ {
444
+ status: alsResponse.status,
445
+ statusText: alsResponse.statusText,
446
+ headers: {
447
+ "Content-Type": "application/json",
448
+ [X_TSS_SERIALIZED]: "true"
449
+ }
450
+ }
451
+ );
452
+ }
453
+ if (rawStreams.size > 0) {
454
+ const jsonStream = new ReadableStream({
455
+ start(controller) {
456
+ callbacks.onParse = (value) => {
457
+ controller.enqueue(JSON.stringify(value) + "\n");
458
+ };
459
+ callbacks.onDone = () => {
460
+ try {
461
+ controller.close();
462
+ } catch {
463
+ }
464
+ };
465
+ callbacks.onError = (error) => controller.error(error);
466
+ if (nonStreamingBody !== void 0) {
467
+ callbacks.onParse(nonStreamingBody);
468
+ }
469
+ }
470
+ });
471
+ const multiplexedStream = createMultiplexedStream(
472
+ jsonStream,
473
+ rawStreams
474
+ );
475
+ return new Response(multiplexedStream, {
476
+ status: alsResponse.status,
477
+ statusText: alsResponse.statusText,
478
+ headers: {
479
+ "Content-Type": TSS_CONTENT_TYPE_FRAMED_VERSIONED,
480
+ [X_TSS_SERIALIZED]: "true"
481
+ }
482
+ });
483
+ }
484
+ const stream = new ReadableStream({
481
485
  start(controller) {
482
- callbacks.onParse = (value) => {
483
- controller.enqueue(JSON.stringify(value) + "\n");
484
- };
486
+ callbacks.onParse = (value) => controller.enqueue(
487
+ textEncoder.encode(JSON.stringify(value) + "\n")
488
+ );
485
489
  callbacks.onDone = () => {
486
490
  try {
487
491
  controller.close();
488
- } catch {
492
+ } catch (error) {
493
+ controller.error(error);
489
494
  }
490
- lateStreamWriter?.close().catch(() => {
491
- }).finally(() => {
492
- lateStreamWriter = void 0;
493
- });
494
495
  };
495
- callbacks.onError = (error) => {
496
- controller.error(error);
497
- lateStreamWriter?.abort(error).catch(() => {
498
- }).finally(() => {
499
- lateStreamWriter = void 0;
500
- });
501
- };
502
- if (nonStreamingBody !== void 0) callbacks.onParse(nonStreamingBody);
503
- if (done) callbacks.onDone();
504
- },
505
- cancel() {
506
- lateStreamWriter?.abort().catch(() => {
507
- });
508
- lateStreamWriter = void 0;
496
+ callbacks.onError = (error) => controller.error(error);
497
+ if (nonStreamingBody !== void 0) {
498
+ callbacks.onParse(nonStreamingBody);
499
+ }
509
500
  }
510
- }), rawStreams, lateStreamReadable);
511
- return new Response(multiplexedStream, {
501
+ });
502
+ return new Response(stream, {
512
503
  status: alsResponse.status,
513
504
  statusText: alsResponse.statusText,
514
505
  headers: {
515
- "Content-Type": TSS_CONTENT_TYPE_FRAMED_VERSIONED,
506
+ "Content-Type": "application/x-ndjson",
516
507
  [X_TSS_SERIALIZED]: "true"
517
508
  }
518
509
  });
@@ -523,11 +514,13 @@ var handleServerAction = async ({ request, context, serverFnId }) => {
523
514
  });
524
515
  };
525
516
  let res = await (async () => {
526
- if (FORM_DATA_CONTENT_TYPES.some((type) => contentType && contentType.includes(type))) {
527
- if (methodUpper === "GET") {
528
- if (false) ;
529
- invariant();
530
- }
517
+ if (FORM_DATA_CONTENT_TYPES.some(
518
+ (type) => contentType && contentType.includes(type)
519
+ )) {
520
+ invariant(
521
+ methodLower !== "get",
522
+ "GET requests with FormData payloads are not supported"
523
+ );
531
524
  const formData = await request.formData();
532
525
  const serializedContext = formData.get(TSS_FORMDATA_CONTEXT);
533
526
  formData.delete(TSS_FORMDATA_CONTEXT);
@@ -536,54 +529,85 @@ var handleServerAction = async ({ request, context, serverFnId }) => {
536
529
  data: formData,
537
530
  method: methodUpper
538
531
  };
539
- if (typeof serializedContext === "string") try {
540
- const deserializedContext = Pu(JSON.parse(serializedContext), { plugins: serovalPlugins });
541
- if (typeof deserializedContext === "object" && deserializedContext) params.context = safeObjectMerge(deserializedContext, context);
542
- } catch (e) {
543
- if (false) ;
532
+ if (typeof serializedContext === "string") {
533
+ try {
534
+ const parsedContext = JSON.parse(serializedContext);
535
+ const deserializedContext = Iu(parsedContext, {
536
+ plugins: serovalPlugins
537
+ });
538
+ if (typeof deserializedContext === "object" && deserializedContext) {
539
+ params.context = safeObjectMerge(
540
+ context,
541
+ deserializedContext
542
+ );
543
+ }
544
+ } catch (e) {
545
+ if (false) ;
546
+ }
544
547
  }
545
548
  return await action(params);
546
549
  }
547
- if (methodUpper === "GET") {
550
+ if (methodLower === "get") {
548
551
  const payloadParam = url.searchParams.get("payload");
549
- if (payloadParam && payloadParam.length > MAX_PAYLOAD_SIZE) throw new Error("Payload too large");
552
+ if (payloadParam && payloadParam.length > MAX_PAYLOAD_SIZE) {
553
+ throw new Error("Payload too large");
554
+ }
550
555
  const payload2 = payloadParam ? parsePayload(JSON.parse(payloadParam)) : {};
551
- payload2.context = safeObjectMerge(payload2.context, context);
556
+ payload2.context = safeObjectMerge(context, payload2.context);
552
557
  payload2.method = methodUpper;
553
558
  return await action(payload2);
554
559
  }
560
+ if (methodLower !== "post") {
561
+ throw new Error("expected POST method");
562
+ }
555
563
  let jsonPayload;
556
- if (contentType?.includes("application/json")) jsonPayload = await request.json();
564
+ if (contentType?.includes("application/json")) {
565
+ jsonPayload = await request.json();
566
+ }
557
567
  const payload = jsonPayload ? parsePayload(jsonPayload) : {};
558
568
  payload.context = safeObjectMerge(payload.context, context);
559
569
  payload.method = methodUpper;
560
570
  return await action(payload);
561
571
  })();
562
572
  const unwrapped = res.result || res.error;
563
- if (isNotFound(res)) res = isNotFoundResponse(res);
564
- if (!isServerFn) return unwrapped;
573
+ if (isNotFound(res)) {
574
+ res = isNotFoundResponse(res);
575
+ }
576
+ if (!isServerFn) {
577
+ return unwrapped;
578
+ }
565
579
  if (unwrapped instanceof Response) {
566
- if (isRedirect(unwrapped)) return unwrapped;
580
+ if (isRedirect(unwrapped)) {
581
+ return unwrapped;
582
+ }
567
583
  unwrapped.headers.set(X_TSS_RAW_RESPONSE, "true");
568
584
  return unwrapped;
569
585
  }
570
586
  return serializeResult(res);
571
587
  } catch (error) {
572
- if (error instanceof Response) return error;
573
- if (isNotFound(error)) return isNotFoundResponse(error);
588
+ if (error instanceof Response) {
589
+ return error;
590
+ }
591
+ if (isNotFound(error)) {
592
+ return isNotFoundResponse(error);
593
+ }
574
594
  console.info();
575
595
  console.info("Server Fn Error!");
576
596
  console.info();
577
597
  console.error(error);
578
598
  console.info();
579
- const serializedError = JSON.stringify(await Promise.resolve(su(error, {
580
- refs: /* @__PURE__ */ new Map(),
581
- plugins: serovalPlugins
582
- })));
583
- const response = getResponse();
599
+ const serializedError = JSON.stringify(
600
+ await Promise.resolve(
601
+ ou(error, {
602
+ refs: /* @__PURE__ */ new Map(),
603
+ plugins: serovalPlugins
604
+ })
605
+ )
606
+ );
607
+ const response2 = getResponse();
584
608
  return new Response(serializedError, {
585
- status: response.status ?? 500,
586
- statusText: response.statusText,
609
+ status: response2.status ?? 500,
610
+ statusText: response2.statusText,
587
611
  headers: {
588
612
  "Content-Type": "application/json",
589
613
  [X_TSS_SERIALIZED]: "true"
@@ -591,6 +615,7 @@ var handleServerAction = async ({ request, context, serverFnId }) => {
591
615
  });
592
616
  }
593
617
  })();
618
+ return response;
594
619
  };
595
620
  function isNotFoundResponse(error) {
596
621
  const { headers, ...rest } = error;
@@ -602,534 +627,115 @@ function isNotFoundResponse(error) {
602
627
  }
603
628
  });
604
629
  }
605
- var LINK_PARAM_TOKEN_RE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
606
- var PRELOAD_AS_VALUES = /* @__PURE__ */ new Set([
607
- "fetch",
608
- "font",
609
- "image",
610
- "script",
611
- "style",
612
- "track"
613
- ]);
614
- function buildLinkParam(name, value) {
615
- if (value === void 0) return name;
616
- if (LINK_PARAM_TOKEN_RE.test(value)) return `${name}=${value}`;
617
- return `${name}=${JSON.stringify(value)}`;
618
- }
619
- function serializeEarlyHint(hint) {
620
- const parts = [`<${hint.href}>`, buildLinkParam("rel", hint.rel)];
621
- if (hint.as) parts.push(buildLinkParam("as", hint.as));
622
- if (hint.crossOrigin !== void 0) parts.push(buildLinkParam("crossorigin", hint.crossOrigin || void 0));
623
- if (hint.type) parts.push(buildLinkParam("type", hint.type));
624
- if (hint.integrity) parts.push(buildLinkParam("integrity", hint.integrity));
625
- if (hint.referrerPolicy) parts.push(buildLinkParam("referrerpolicy", hint.referrerPolicy));
626
- if (hint.fetchPriority) parts.push(buildLinkParam("fetchpriority", hint.fetchPriority));
627
- return parts.join("; ");
628
- }
629
- function getStringAttr(attrs, name, fallbackName) {
630
- const value = attrs?.[name] ?? (fallbackName ? attrs?.[fallbackName] : void 0);
631
- return typeof value === "string" ? value : void 0;
632
- }
633
- function getPreloadAs(attrs) {
634
- const as = getStringAttr(attrs, "as");
635
- return as && PRELOAD_AS_VALUES.has(as) ? as : void 0;
636
- }
637
- function addEarlyHintFetchAttrs(hint, attrs) {
638
- const crossOrigin = getStringAttr(attrs, "crossOrigin", "crossorigin");
639
- const type = getStringAttr(attrs, "type");
640
- const integrity = getStringAttr(attrs, "integrity");
641
- const referrerPolicy = getStringAttr(attrs, "referrerPolicy", "referrerpolicy");
642
- const fetchPriority = getStringAttr(attrs, "fetchPriority", "fetchpriority");
643
- if (crossOrigin !== void 0) hint.crossOrigin = crossOrigin;
644
- if (type) hint.type = type;
645
- if (integrity) hint.integrity = integrity;
646
- if (referrerPolicy) hint.referrerPolicy = referrerPolicy;
647
- if (fetchPriority) hint.fetchPriority = fetchPriority;
648
- }
649
- function linkAttrsToEarlyHint(attrs) {
650
- const href = getStringAttr(attrs, "href");
651
- const rel = getStringAttr(attrs, "rel");
652
- if (!href || !rel) return void 0;
653
- const relTokens = rel.split(/\s+/);
654
- let hintRel;
655
- let hintAs;
656
- if (relTokens.includes("modulepreload")) {
657
- hintRel = "modulepreload";
658
- hintAs = "script";
659
- } else if (relTokens.includes("stylesheet")) {
660
- hintRel = "preload";
661
- hintAs = "style";
662
- } else if (relTokens.includes("preload")) {
663
- hintAs = getPreloadAs(attrs);
664
- if (!hintAs) return void 0;
665
- hintRel = "preload";
666
- } else if (relTokens.includes("preconnect")) {
667
- hintRel = "preconnect";
668
- hintAs = void 0;
669
- } else if (relTokens.includes("dns-prefetch")) {
670
- hintRel = "dns-prefetch";
671
- hintAs = void 0;
672
- }
673
- if (!hintRel) return void 0;
674
- const hint = {
675
- href,
676
- rel: hintRel
677
- };
678
- if (hintAs) hint.as = hintAs;
679
- addEarlyHintFetchAttrs(hint, attrs);
680
- return hint;
681
- }
682
- function collectStaticHintsFromManifest(manifest2, matchedRoutes) {
683
- const hints = [];
684
- for (const route of matchedRoutes) {
685
- const routeManifest = manifest2.routes[route.id];
686
- if (!routeManifest) continue;
687
- for (const link of routeManifest.preloads ?? []) {
688
- const attrs = getScriptPreloadAttrs(manifest2, link);
689
- const hint = {
690
- href: attrs.href,
691
- rel: attrs.rel,
692
- as: "script"
693
- };
694
- if (attrs.crossOrigin !== void 0) hint.crossOrigin = attrs.crossOrigin;
695
- hints.push(hint);
696
- }
697
- for (const link of routeManifest.css ?? []) {
698
- const stylesheetHref = getStylesheetHref(link);
699
- if (manifest2.inlineCss?.styles[stylesheetHref] !== void 0) continue;
700
- const resolvedLink = resolveManifestCssLink(link);
701
- const hint = {
702
- href: stylesheetHref,
703
- rel: "preload",
704
- as: "style"
705
- };
706
- if (resolvedLink.crossOrigin !== void 0) hint.crossOrigin = resolvedLink.crossOrigin;
707
- hints.push(hint);
708
- }
709
- }
710
- return hints;
711
- }
712
- function collectDynamicHintsFromMatches(matches) {
713
- const hints = [];
714
- for (const match of matches) {
715
- const links = match.links;
716
- if (!Array.isArray(links)) continue;
717
- for (const link of links) {
718
- const hint = linkAttrsToEarlyHint(link);
719
- if (hint) hints.push(hint);
720
- }
721
- }
722
- return hints;
723
- }
724
- function createEarlyHintsEvent(opts) {
725
- const nextHints = [];
726
- const nextLinks = [];
727
- for (const hint of opts.hints) {
728
- const link = serializeEarlyHint(hint);
729
- if (opts.sentLinks.has(link)) continue;
730
- opts.sentLinks.add(link);
731
- opts.sentHints.push(hint);
732
- nextHints.push(hint);
733
- nextLinks.push(link);
734
- }
735
- if (!nextHints.length && opts.phase !== "dynamic") return void 0;
736
- return {
737
- phase: opts.phase,
738
- hints: nextHints,
739
- links: nextLinks,
740
- allHints: opts.sentHints.slice(),
741
- allLinks: Array.from(opts.sentLinks)
742
- };
743
- }
744
- function createResponseLinkHeaderEntries(opts) {
745
- for (const hint of opts.hints) {
746
- const link = serializeEarlyHint(hint);
747
- if (opts.sentLinks.has(link)) continue;
748
- opts.sentLinks.add(link);
749
- opts.entries.push({
750
- phase: opts.phase,
751
- hint,
752
- link
753
- });
754
- }
755
- }
756
- function getResponseLinkHeaderEntries(opts) {
757
- if (!opts.filter) return opts.entries.map((entry) => entry.link);
758
- try {
759
- const links = [];
760
- for (const entry of opts.entries) if (opts.filter(entry)) links.push(entry.link);
761
- return links;
762
- } catch (err) {
763
- console.error("Error filtering response Link headers:", err);
764
- return [];
765
- }
766
- }
767
- function notifyEarlyHints(phase, event, onEarlyHints) {
768
- try {
769
- const result = onEarlyHints(event);
770
- if (result) Promise.resolve(result).catch((err) => {
771
- console.error(`Error sending ${phase} early hints:`, err);
772
- });
773
- } catch (err) {
774
- console.error(`Error sending ${phase} early hints:`, err);
775
- }
776
- }
777
- function getResponseLinkHeaderFilter(responseLinkHeader) {
778
- if (typeof responseLinkHeader !== "object") return;
779
- return responseLinkHeader.filter;
780
- }
781
- function appendResponseLinkHeaders(opts) {
782
- for (const link of getResponseLinkHeaderEntries(opts)) opts.responseHeaders.append("Link", link);
783
- }
784
- function collectResponseLinkHeaderEntries(opts) {
785
- for (let index = 0; index < opts.event.hints.length; index++) opts.entries.push({
786
- phase: opts.phase,
787
- hint: opts.event.hints[index],
788
- link: opts.event.links[index]
789
- });
790
- }
791
- function collectEarlyHintsPhase(opts) {
792
- const event = opts.onEarlyHints ? createEarlyHintsEvent({
793
- phase: opts.phase,
794
- hints: opts.hints,
795
- sentLinks: opts.sentLinks,
796
- sentHints: opts.sentHints
797
- }) : void 0;
798
- if (event) notifyEarlyHints(opts.phase, event, opts.onEarlyHints);
799
- if (!opts.responseLinkHeaderEntries) return;
800
- if (event) {
801
- collectResponseLinkHeaderEntries({
802
- phase: opts.phase,
803
- event,
804
- entries: opts.responseLinkHeaderEntries
805
- });
806
- return;
807
- }
808
- createResponseLinkHeaderEntries({
809
- phase: opts.phase,
810
- hints: opts.hints,
811
- sentLinks: opts.sentLinks,
812
- entries: opts.responseLinkHeaderEntries
813
- });
814
- }
815
- function createEarlyHintsCollector(opts) {
816
- if (!opts?.onEarlyHints && !opts?.responseLinkHeader) return;
817
- const sentLinks = /* @__PURE__ */ new Set();
818
- const sentHints = opts.onEarlyHints ? new Array() : void 0;
819
- const responseLinkHeaderEntries = opts.responseLinkHeader ? new Array() : void 0;
820
- const responseLinkHeaderFilter = getResponseLinkHeaderFilter(opts.responseLinkHeader);
821
- return {
822
- collectStatic: ({ manifest: manifest2, matchedRoutes }) => {
823
- if (!matchedRoutes?.length) return;
824
- collectEarlyHintsPhase({
825
- phase: "static",
826
- hints: collectStaticHintsFromManifest(manifest2, matchedRoutes),
827
- sentLinks,
828
- sentHints,
829
- onEarlyHints: opts.onEarlyHints,
830
- responseLinkHeaderEntries
831
- });
832
- },
833
- collectDynamic: (matches) => {
834
- collectEarlyHintsPhase({
835
- phase: "dynamic",
836
- hints: collectDynamicHintsFromMatches(matches),
837
- sentLinks,
838
- sentHints,
839
- onEarlyHints: opts.onEarlyHints,
840
- responseLinkHeaderEntries
841
- });
842
- },
843
- appendResponseHeaders: (headers) => {
844
- if (!responseLinkHeaderEntries?.length) return;
845
- appendResponseLinkHeaders({
846
- responseHeaders: headers,
847
- entries: responseLinkHeaderEntries,
848
- filter: responseLinkHeaderFilter
849
- });
850
- }
851
- };
852
- }
853
- function normalizeTransformAssetResult(result) {
854
- if (typeof result === "string") return { href: result };
855
- return result;
856
- }
857
- function escapeCssString(value) {
858
- return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\a ").replace(/\r/g, "\\d ").replace(/\f/g, "\\c ");
859
- }
860
- async function transformInlineCssTemplate(options) {
861
- const { strings, urls } = options.template;
862
- if (strings.length !== urls.length + 1) throw new Error(`TanStack Start inlineCss template for ${options.stylesheetHref} is invalid`);
863
- let css = strings[0];
864
- for (let index = 0; index < urls.length; index++) {
865
- const transformed = normalizeTransformAssetResult(await options.transformFn({
866
- kind: "css-url",
867
- url: urls[index],
868
- stylesheetHref: options.stylesheetHref
869
- }));
870
- css += escapeCssString(transformed.href) + strings[index + 1];
871
- }
872
- return css;
873
- }
874
- async function transformInlineCssStyles(inlineCss, transformFn) {
875
- const transformedStyles = {};
876
- const transformedEntries = await Promise.all(Object.entries(inlineCss.styles).map(async ([stylesheetHref, css]) => {
877
- const template = inlineCss.templates?.[stylesheetHref];
878
- return [stylesheetHref, template ? await transformInlineCssTemplate({
879
- stylesheetHref,
880
- template,
881
- transformFn
882
- }) : css];
883
- }));
884
- for (const [stylesheetHref, css] of transformedEntries) transformedStyles[stylesheetHref] = css;
885
- return {
886
- styles: transformedStyles,
887
- ...inlineCss.templates ? { templates: inlineCss.templates } : {}
888
- };
889
- }
890
- function resolveTransformAssetsCrossOrigin(config, kind) {
891
- if (!config) return void 0;
892
- if (typeof config === "string") return config;
893
- return config[kind];
894
- }
895
- function isObjectShorthand(transform) {
896
- return "prefix" in transform;
897
- }
898
- function resolveTransformAssetsConfig(transform) {
630
+ function resolveTransformConfig(transform) {
899
631
  if (typeof transform === "string") {
900
632
  const prefix = transform;
901
633
  return {
902
634
  type: "transform",
903
- transformFn: ({ url }) => ({ href: `${prefix}${url}` }),
635
+ transformFn: ({ url }) => `${prefix}${url}`,
904
636
  cache: true
905
637
  };
906
638
  }
907
- if (typeof transform === "function") return {
908
- type: "transform",
909
- transformFn: transform,
910
- cache: true
911
- };
912
- if (isObjectShorthand(transform)) {
913
- const { prefix, crossOrigin } = transform;
639
+ if (typeof transform === "function") {
914
640
  return {
915
641
  type: "transform",
916
- transformFn: ({ url, kind }) => {
917
- const href = `${prefix}${url}`;
918
- if (kind === "css-url") return { href };
919
- const co = resolveTransformAssetsCrossOrigin(crossOrigin, kind);
920
- return co ? {
921
- href,
922
- crossOrigin: co
923
- } : { href };
924
- },
642
+ transformFn: transform,
925
643
  cache: true
926
644
  };
927
645
  }
928
- if ("createTransform" in transform && transform.createTransform) return {
929
- type: "createTransform",
930
- createTransform: transform.createTransform,
931
- cache: transform.cache !== false
932
- };
646
+ if ("createTransform" in transform && transform.createTransform) {
647
+ return {
648
+ type: "createTransform",
649
+ createTransform: transform.createTransform,
650
+ cache: transform.cache !== false
651
+ };
652
+ }
653
+ const transformFn = typeof transform.transform === "string" ? (({ url }) => `${transform.transform}${url}`) : transform.transform;
933
654
  return {
934
655
  type: "transform",
935
- transformFn: typeof transform.transform === "string" ? (({ url }) => ({ href: `${transform.transform}${url}` })) : transform.transform,
656
+ transformFn,
936
657
  cache: transform.cache !== false
937
658
  };
938
659
  }
939
- function assignManifestLink(link, next) {
940
- if (typeof link === "string") return next.crossOrigin ? next : next.href;
941
- const nextLink = {
942
- ...link,
943
- href: next.href
944
- };
945
- if (next.crossOrigin) nextLink.crossOrigin = next.crossOrigin;
946
- else delete nextLink.crossOrigin;
947
- return nextLink;
948
- }
949
- async function transformManifestAssets(source, transformFn, _opts) {
950
- const manifest2 = structuredClone(source);
951
- const inlineCssEnabled = _opts?.inlineCss !== false;
952
- const scriptTransforms = /* @__PURE__ */ new Map();
953
- const transformScript = (url) => {
954
- const cached = scriptTransforms.get(url);
955
- if (cached) return cached;
956
- const transformed = Promise.resolve(transformFn({
957
- url,
958
- kind: "script"
959
- })).then(normalizeTransformAssetResult);
960
- scriptTransforms.set(url, transformed);
961
- return transformed;
962
- };
963
- if (!inlineCssEnabled) delete manifest2.inlineCss;
964
- else if (manifest2.inlineCss) manifest2.inlineCss = await transformInlineCssStyles(manifest2.inlineCss, transformFn);
965
- for (const route of Object.values(manifest2.routes)) {
966
- if (route.preloads?.length) route.preloads = await Promise.all(route.preloads.map(async (link) => {
967
- const result = await transformScript(resolveManifestAssetLink(link).href);
968
- return assignManifestLink(link, {
969
- href: result.href,
970
- crossOrigin: result.crossOrigin
971
- });
972
- }));
973
- if (route.css?.length && !manifest2.inlineCss) route.css = await Promise.all(route.css.map(async (link) => {
974
- const result = normalizeTransformAssetResult(await transformFn({
975
- url: resolveManifestCssLink(link).href,
976
- kind: "stylesheet"
977
- }));
978
- return assignManifestLink(link, {
979
- href: result.href,
980
- crossOrigin: result.crossOrigin
981
- });
982
- }));
983
- if (route.scripts?.length) for (const script of route.scripts) {
984
- const src = script.attrs?.src;
985
- if (typeof src !== "string") continue;
986
- const result = await transformScript(src);
987
- script.attrs = {
988
- ...script.attrs,
989
- src: result.href
990
- };
991
- if (result.crossOrigin) script.attrs.crossOrigin = result.crossOrigin;
992
- else delete script.attrs.crossOrigin;
993
- }
660
+ function buildClientEntryScriptTag(clientEntry, injectedHeadScripts) {
661
+ const clientEntryLiteral = JSON.stringify(clientEntry);
662
+ let script = `import(${clientEntryLiteral})`;
663
+ if (injectedHeadScripts) {
664
+ script = `${injectedHeadScripts};${script}`;
994
665
  }
995
- return manifest2;
996
- }
997
- function buildManifest(source, opts) {
998
666
  return {
999
- ...source.scriptFormat ? { scriptFormat: source.scriptFormat } : {},
1000
- ...opts?.inlineCss !== false && source.inlineCss ? { inlineCss: structuredClone(source.inlineCss) } : {},
1001
- routes: { ...source.routes }
1002
- };
1003
- }
1004
- function getStaticHandlerInlineCssDefault(handlerInlineCss) {
1005
- if (typeof handlerInlineCss === "function") return;
1006
- return handlerInlineCss ?? true;
1007
- }
1008
- async function resolveInlineCssForRequest(opts) {
1009
- if (opts.requestInlineCss !== void 0) return opts.requestInlineCss;
1010
- if (typeof opts.handlerInlineCss === "function") return await opts.handlerInlineCss({ request: opts.request });
1011
- return opts.handlerInlineCss ?? true;
1012
- }
1013
- function createCachedBaseManifestLoader(loadBaseManifest) {
1014
- let baseManifestPromise;
1015
- return () => {
1016
- if (!baseManifestPromise) baseManifestPromise = loadBaseManifest().catch((error) => {
1017
- baseManifestPromise = void 0;
1018
- throw error;
1019
- });
1020
- return baseManifestPromise;
667
+ tag: "script",
668
+ attrs: {
669
+ type: "module",
670
+ async: true
671
+ },
672
+ children: script
1021
673
  };
1022
674
  }
1023
- function createFinalManifestTransformResolver(transformAssets, opts) {
1024
- const transformConfig = transformAssets !== void 0 ? resolveTransformAssetsConfig(transformAssets) : void 0;
1025
- const cache = transformConfig ? transformConfig.cache : true;
1026
- const warmup = !!transformAssets && typeof transformAssets === "object" && "warmup" in transformAssets && transformAssets.warmup === true;
1027
- let cachedCreateTransformPromise;
1028
- const clearCachedCreateTransform = () => {
1029
- cachedCreateTransformPromise = void 0;
1030
- };
1031
- return {
1032
- cache,
1033
- warmup,
1034
- clearCachedCreateTransform,
1035
- getTransformFn: async (ctx) => {
1036
- if (!transformConfig) return void 0;
1037
- if (transformConfig.type !== "createTransform") return transformConfig.transformFn;
1038
- if (!cache || false) return transformConfig.createTransform(ctx);
1039
- if (!cachedCreateTransformPromise) cachedCreateTransformPromise = Promise.resolve(transformConfig.createTransform(ctx)).catch((error) => {
1040
- clearCachedCreateTransform();
1041
- throw error;
1042
- });
1043
- return cachedCreateTransformPromise;
675
+ function transformManifestUrls(source, transformFn, opts) {
676
+ return (async () => {
677
+ const manifest2 = opts?.clone ? structuredClone(source.manifest) : source.manifest;
678
+ for (const route of Object.values(manifest2.routes)) {
679
+ if (route.preloads) {
680
+ route.preloads = await Promise.all(
681
+ route.preloads.map(
682
+ (url) => Promise.resolve(transformFn({ url, type: "modulepreload" }))
683
+ )
684
+ );
685
+ }
686
+ if (route.assets) {
687
+ for (const asset of route.assets) {
688
+ if (asset.tag === "link" && asset.attrs?.href) {
689
+ asset.attrs.href = await Promise.resolve(
690
+ transformFn({
691
+ url: asset.attrs.href,
692
+ type: "stylesheet"
693
+ })
694
+ );
695
+ }
696
+ }
697
+ }
1044
698
  }
1045
- };
1046
- }
1047
- function createFinalManifestResolver(opts) {
1048
- const finalManifestCache = /* @__PURE__ */ new Map();
1049
- const transformResolver = createFinalManifestTransformResolver(opts.transformAssets);
1050
- const handlerDefaultInlineCss = getStaticHandlerInlineCssDefault(opts.inlineCss);
1051
- const getRequestManifestOptions = async (requestOpts) => {
1052
- const transformFn = await transformResolver.getTransformFn({
1053
- warmup: false,
1054
- request: requestOpts.request
1055
- });
1056
- const inlineCss = await resolveInlineCssForRequest({
1057
- request: requestOpts.request,
1058
- handlerInlineCss: opts.inlineCss,
1059
- requestInlineCss: requestOpts.requestInlineCss
1060
- });
1061
- return {
1062
- getBaseManifest: requestOpts.getBaseManifest,
1063
- transformFn,
1064
- cache: transformResolver.cache,
1065
- inlineCss
1066
- };
1067
- };
1068
- const resolveRequest = async (requestOpts, cache) => {
1069
- return resolveFinalManifest({
1070
- ...await getRequestManifestOptions(requestOpts),
1071
- finalManifestCache: cache
1072
- });
1073
- };
1074
- return {
1075
- warmup: ({ getBaseManifest: getBaseManifest2 }) => warmupFinalManifest({
1076
- enabled: transformResolver.warmup,
1077
- handlerDefaultInlineCss,
1078
- cache: transformResolver.cache,
1079
- finalManifestCache,
1080
- getBaseManifest: getBaseManifest2,
1081
- getTransformFn: () => transformResolver.getTransformFn({ warmup: true }),
1082
- onError: transformResolver.clearCachedCreateTransform
1083
- }),
1084
- resolveCached: (requestOpts) => resolveRequest(requestOpts, finalManifestCache),
1085
- resolveUncached: (requestOpts) => resolveRequest(requestOpts, void 0)
1086
- };
1087
- }
1088
- function getFinalManifestCacheKey(inlineCss) {
1089
- return inlineCss ? "inline-css" : "linked-css";
1090
- }
1091
- function cacheFinalManifestPromise(cachedFinalManifestPromises, cacheKey, promise) {
1092
- const cachedFinalManifestPromise = promise.catch((error) => {
1093
- if (cachedFinalManifestPromises.get(cacheKey) === cachedFinalManifestPromise) cachedFinalManifestPromises.delete(cacheKey);
1094
- throw error;
1095
- });
1096
- cachedFinalManifestPromises.set(cacheKey, cachedFinalManifestPromise);
1097
- return cachedFinalManifestPromise;
1098
- }
1099
- function getOrCreateCachedFinalManifestPromise(cachedFinalManifestPromises, cacheKey, computeFinalManifest) {
1100
- const cachedFinalManifestPromise = cachedFinalManifestPromises.get(cacheKey);
1101
- if (cachedFinalManifestPromise) return cachedFinalManifestPromise;
1102
- return cacheFinalManifestPromise(cachedFinalManifestPromises, cacheKey, Promise.resolve().then(computeFinalManifest));
1103
- }
1104
- async function buildFinalManifest(opts) {
1105
- return opts.transformFn ? await transformManifestAssets(opts.base, opts.transformFn, { inlineCss: opts.inlineCss }) : buildManifest(opts.base, { inlineCss: opts.inlineCss });
699
+ const transformedClientEntry = await Promise.resolve(
700
+ transformFn({
701
+ url: source.clientEntry,
702
+ type: "clientEntry"
703
+ })
704
+ );
705
+ const rootRoute = manifest2.routes[rootRouteId];
706
+ if (rootRoute) {
707
+ rootRoute.assets = rootRoute.assets || [];
708
+ rootRoute.assets.push(
709
+ buildClientEntryScriptTag(
710
+ transformedClientEntry,
711
+ source.injectedHeadScripts
712
+ )
713
+ );
714
+ }
715
+ return manifest2;
716
+ })();
1106
717
  }
1107
- async function resolveFinalManifest(opts) {
1108
- const computeFinalManifest = async () => {
1109
- return buildFinalManifest({
1110
- base: await opts.getBaseManifest(),
1111
- transformFn: opts.transformFn,
1112
- inlineCss: opts.inlineCss
1113
- });
718
+ function buildManifestWithClientEntry(source) {
719
+ const scriptTag = buildClientEntryScriptTag(
720
+ source.clientEntry,
721
+ source.injectedHeadScripts
722
+ );
723
+ const baseRootRoute = source.manifest.routes[rootRouteId];
724
+ const routes = {
725
+ ...source.manifest.routes,
726
+ ...baseRootRoute ? {
727
+ [rootRouteId]: {
728
+ ...baseRootRoute,
729
+ assets: [...baseRootRoute.assets || [], scriptTag]
730
+ }
731
+ } : {}
1114
732
  };
1115
- if (opts.finalManifestCache && (!opts.transformFn || opts.cache)) return getOrCreateCachedFinalManifestPromise(opts.finalManifestCache, getFinalManifestCacheKey(opts.inlineCss), computeFinalManifest);
1116
- return computeFinalManifest();
733
+ return { routes };
1117
734
  }
1118
- function warmupFinalManifest(opts) {
1119
- if (!opts.enabled || opts.handlerDefaultInlineCss === void 0 || !opts.cache) return;
1120
- const inlineCss = opts.handlerDefaultInlineCss;
1121
- const warmupPromise = getOrCreateCachedFinalManifestPromise(opts.finalManifestCache, getFinalManifestCacheKey(inlineCss), async () => {
1122
- const [base, transformFn] = await Promise.all([opts.getBaseManifest(), opts.getTransformFn()]);
1123
- return buildFinalManifest({
1124
- base,
1125
- transformFn,
1126
- inlineCss
1127
- });
1128
- });
1129
- if (opts.onError) warmupPromise.catch(opts.onError);
1130
- return warmupPromise;
1131
- }
1132
- var ServerFunctionSerializationAdapter = createSerializationAdapter({
735
+ const HEADERS = {
736
+ TSS_SHELL: "X-TSS_SHELL"
737
+ };
738
+ const ServerFunctionSerializationAdapter = createSerializationAdapter({
1133
739
  key: "$TSS/serverfn",
1134
740
  test: (v) => {
1135
741
  if (typeof v !== "function") return false;
@@ -1139,44 +745,63 @@ var ServerFunctionSerializationAdapter = createSerializationAdapter({
1139
745
  toSerializable: ({ serverFnMeta }) => ({ functionId: serverFnMeta.id }),
1140
746
  fromSerializable: ({ functionId }) => {
1141
747
  const fn = async (opts, signal) => {
1142
- return (await (await getServerFnById(functionId))(opts ?? {}, signal)).result;
748
+ const serverFn = await getServerFnById(functionId);
749
+ const result = await serverFn(opts ?? {}, signal);
750
+ return result.result;
1143
751
  };
1144
752
  return fn;
1145
753
  }
1146
754
  });
1147
755
  function getStartResponseHeaders(opts) {
1148
- return mergeHeaders({ "Content-Type": "text/html; charset=utf-8" }, ...opts.router.stores.matches.get().map((match) => {
1149
- return match.headers;
1150
- }));
1151
- }
1152
- var entriesPromise;
1153
- var defaultCsrfMiddleware = createCsrfMiddleware({ filter: (ctx) => ctx.handlerType === "serverFn" });
1154
- var getCachedBaseManifest = createCachedBaseManifestLoader(() => getStartManifest());
1155
- var getProdBaseManifest = () => getCachedBaseManifest();
1156
- var getBaseManifest = getProdBaseManifest;
1157
- var createEarlyHintsForRequest = createEarlyHintsCollector;
756
+ const headers = mergeHeaders(
757
+ {
758
+ "Content-Type": "text/html; charset=utf-8"
759
+ },
760
+ ...opts.router.state.matches.map((match) => {
761
+ return match.headers;
762
+ })
763
+ );
764
+ return headers;
765
+ }
766
+ let entriesPromise;
767
+ let baseManifestPromise;
768
+ let cachedFinalManifestPromise;
1158
769
  async function loadEntries() {
1159
- const [routerEntry, startEntry, pluginAdapters] = await Promise.all([
1160
- import("./router-BR4XO8XJ.mjs").then((n) => n.r),
1161
- import("./start-HYkvq4Ni.mjs"),
1162
- import("./empty-plugin-adapters-BFgPZ6_d.mjs")
1163
- ]);
1164
- return {
1165
- routerEntry,
1166
- startEntry,
1167
- pluginAdapters
1168
- };
770
+ const routerEntry = await import("./router-BVxfVFsb.mjs").then((n) => n.r);
771
+ const startEntry = await import("./start-HYkvq4Ni.mjs");
772
+ return { startEntry, routerEntry };
1169
773
  }
1170
774
  function getEntries() {
1171
- if (!entriesPromise) entriesPromise = loadEntries();
775
+ if (!entriesPromise) {
776
+ entriesPromise = loadEntries();
777
+ }
1172
778
  return entriesPromise;
1173
779
  }
1174
- var ROUTER_BASEPATH = "/";
1175
- var SERVER_FN_BASE = "/_serverFn/";
1176
- var IS_PRERENDERING = process.env.TSS_PRERENDERING === "true";
1177
- var IS_SHELL_ENV = process.env.TSS_SHELL === "true";
1178
- var ERR_NO_RESPONSE = "Internal Server Error";
1179
- var ERR_NO_DEFER = "Internal Server Error";
780
+ function getBaseManifest(matchedRoutes) {
781
+ if (!baseManifestPromise) {
782
+ baseManifestPromise = getStartManifest();
783
+ }
784
+ return baseManifestPromise;
785
+ }
786
+ async function resolveManifest(matchedRoutes, transformFn, cache) {
787
+ const base = await getBaseManifest();
788
+ const computeFinalManifest = async () => {
789
+ return transformFn ? await transformManifestUrls(base, transformFn, { clone: !cache }) : buildManifestWithClientEntry(base);
790
+ };
791
+ if (!transformFn || cache) {
792
+ if (!cachedFinalManifestPromise) {
793
+ cachedFinalManifestPromise = computeFinalManifest();
794
+ }
795
+ return cachedFinalManifestPromise;
796
+ }
797
+ return computeFinalManifest();
798
+ }
799
+ const ROUTER_BASEPATH = "/";
800
+ const SERVER_FN_BASE = "/_serverFn/";
801
+ const IS_PRERENDERING = process.env.TSS_PRERENDERING === "true";
802
+ const IS_SHELL_ENV = process.env.TSS_SHELL === "true";
803
+ const ERR_NO_RESPONSE = "Internal Server Error";
804
+ const ERR_NO_DEFER = "Internal Server Error";
1180
805
  function throwRouteHandlerError() {
1181
806
  throw new Error(ERR_NO_RESPONSE);
1182
807
  }
@@ -1187,267 +812,316 @@ function isSpecialResponse(value) {
1187
812
  return value instanceof Response || isRedirect(value);
1188
813
  }
1189
814
  function handleCtxResult(result) {
1190
- if (isSsrResponse(result) || isSpecialResponse(result)) return { response: result };
815
+ if (isSpecialResponse(result)) {
816
+ return { response: result };
817
+ }
1191
818
  return result;
1192
819
  }
1193
- async function executeMiddleware(middlewares, ctx) {
820
+ function executeMiddleware(middlewares, ctx) {
1194
821
  let index = -1;
1195
- let streamResponse;
1196
- const setResponse = (response) => {
1197
- if (isSsrResponse(response)) {
1198
- if (response.serverSsrCleanup === "stream") streamResponse = response;
1199
- ctx.response = response.response;
1200
- return;
1201
- }
1202
- ctx.response = response;
1203
- };
1204
- const disposeStreamResponse = async (reason) => {
1205
- const response = streamResponse;
1206
- if (!response) return;
1207
- streamResponse = void 0;
1208
- const currentResponse = ctx.response;
1209
- if (currentResponse === response.response || currentResponse instanceof Response && response.response.body !== null && currentResponse.body === response.response.body) ctx.response = void 0;
1210
- await response.dispose(reason);
1211
- };
1212
- const getFinalResponse = async () => {
1213
- const response = ctx.response;
1214
- if (!response) throwRouteHandlerError();
1215
- if (!streamResponse) return response;
1216
- if (response === streamResponse.response) return streamResponse;
1217
- if (streamResponse.response.body !== null && response.body === streamResponse.response.body) return {
1218
- ...streamResponse,
1219
- response
1220
- };
1221
- await disposeStreamResponse("middleware response replaced");
1222
- return response;
1223
- };
1224
822
  const next = async (nextCtx) => {
1225
823
  if (nextCtx) {
1226
- if (nextCtx.context) ctx.context = safeObjectMerge(ctx.context, nextCtx.context);
1227
- for (const key of Object.keys(nextCtx)) if (key === "response") setResponse(nextCtx.response);
1228
- else if (key !== "context") ctx[key] = nextCtx[key];
824
+ if (nextCtx.context) {
825
+ ctx.context = safeObjectMerge(ctx.context, nextCtx.context);
826
+ }
827
+ for (const key of Object.keys(nextCtx)) {
828
+ if (key !== "context") {
829
+ ctx[key] = nextCtx[key];
830
+ }
831
+ }
1229
832
  }
1230
833
  index++;
1231
834
  const middleware = middlewares[index];
1232
835
  if (!middleware) return ctx;
1233
836
  let result;
1234
837
  try {
1235
- result = await middleware({
1236
- ...ctx,
1237
- next
1238
- });
838
+ result = await middleware({ ...ctx, next });
1239
839
  } catch (err) {
1240
840
  if (isSpecialResponse(err)) {
1241
- setResponse(err);
841
+ ctx.response = err;
1242
842
  return ctx;
1243
843
  }
1244
- await disposeStreamResponse("middleware error");
1245
844
  throw err;
1246
845
  }
1247
846
  const normalized = handleCtxResult(result);
1248
847
  if (normalized) {
1249
- if (normalized.response !== void 0) setResponse(normalized.response);
1250
- if (normalized.context) ctx.context = safeObjectMerge(ctx.context, normalized.context);
848
+ if (normalized.response !== void 0) {
849
+ ctx.response = normalized.response;
850
+ }
851
+ if (normalized.context) {
852
+ ctx.context = safeObjectMerge(ctx.context, normalized.context);
853
+ }
1251
854
  }
1252
855
  return ctx;
1253
856
  };
1254
- await next();
1255
- return {
1256
- ctx,
1257
- response: await getFinalResponse()
1258
- };
857
+ return next();
1259
858
  }
1260
859
  function handlerToMiddleware(handler, mayDefer = false) {
1261
- if (mayDefer) return handler;
860
+ if (mayDefer) {
861
+ return handler;
862
+ }
1262
863
  return async (ctx) => {
1263
- const response = await handler({
1264
- ...ctx,
1265
- next: throwIfMayNotDefer
1266
- });
1267
- if (!response) throwRouteHandlerError();
864
+ const response = await handler({ ...ctx, next: throwIfMayNotDefer });
865
+ if (!response) {
866
+ throwRouteHandlerError();
867
+ }
1268
868
  return response;
1269
869
  };
1270
870
  }
1271
871
  function createStartHandler(cbOrOptions) {
1272
- const handlerOptions = typeof cbOrOptions === "function" ? {} : cbOrOptions;
1273
872
  const cb = typeof cbOrOptions === "function" ? cbOrOptions : cbOrOptions.handler;
1274
- const finalManifestResolver = createFinalManifestResolver({
1275
- ...handlerOptions
1276
- });
1277
- const resolveManifestForRequest = finalManifestResolver.resolveCached;
1278
- finalManifestResolver.warmup({ getBaseManifest: () => getBaseManifest() });
873
+ const transformAssetUrlsOption = typeof cbOrOptions === "function" ? void 0 : cbOrOptions.transformAssetUrls;
874
+ const warmupTransformManifest = !!transformAssetUrlsOption && typeof transformAssetUrlsOption === "object" && transformAssetUrlsOption.warmup === true;
875
+ const resolvedTransformConfig = transformAssetUrlsOption ? resolveTransformConfig(transformAssetUrlsOption) : void 0;
876
+ const cache = resolvedTransformConfig ? resolvedTransformConfig.cache : true;
877
+ let cachedCreateTransformPromise;
878
+ const getTransformFn = async (opts) => {
879
+ if (!resolvedTransformConfig) return void 0;
880
+ if (resolvedTransformConfig.type === "createTransform") {
881
+ if (cache) {
882
+ if (!cachedCreateTransformPromise) {
883
+ cachedCreateTransformPromise = Promise.resolve(
884
+ resolvedTransformConfig.createTransform(opts)
885
+ );
886
+ }
887
+ return cachedCreateTransformPromise;
888
+ }
889
+ return resolvedTransformConfig.createTransform(opts);
890
+ }
891
+ return resolvedTransformConfig.transformFn;
892
+ };
893
+ if (warmupTransformManifest && cache && true && !cachedFinalManifestPromise) {
894
+ const warmupPromise = (async () => {
895
+ const base = await getBaseManifest();
896
+ const transformFn = await getTransformFn({ warmup: true });
897
+ return transformFn ? await transformManifestUrls(base, transformFn, { clone: false }) : buildManifestWithClientEntry(base);
898
+ })();
899
+ cachedFinalManifestPromise = warmupPromise;
900
+ warmupPromise.catch(() => {
901
+ if (cachedFinalManifestPromise === warmupPromise) {
902
+ cachedFinalManifestPromise = void 0;
903
+ }
904
+ cachedCreateTransformPromise = void 0;
905
+ });
906
+ }
1279
907
  const startRequestResolver = async (request, requestOpts) => {
1280
908
  let router = null;
1281
- let responseOwnsCleanup = false;
909
+ let cbWillCleanup = false;
1282
910
  try {
1283
911
  const { url, handledProtocolRelativeURL } = getNormalizedURL(request.url);
1284
912
  const href = url.pathname + url.search + url.hash;
1285
913
  const origin = getOrigin(request);
1286
- if (handledProtocolRelativeURL) return Response.redirect(url, 308);
914
+ if (handledProtocolRelativeURL) {
915
+ return Response.redirect(url, 308);
916
+ }
1287
917
  const entries = await getEntries();
1288
- const hasStartInstance = !!entries.startEntry.startInstance;
1289
918
  const startOptions = await entries.startEntry.startInstance?.getOptions() || {};
1290
- const { hasPluginAdapters, pluginSerializationAdapters } = entries.pluginAdapters;
1291
919
  const serializationAdapters = [
1292
920
  ...startOptions.serializationAdapters || [],
1293
- ...hasPluginAdapters ? pluginSerializationAdapters : [],
1294
921
  ServerFunctionSerializationAdapter
1295
922
  ];
1296
923
  const requestStartOptions = {
1297
924
  ...startOptions,
1298
- requestMiddleware: hasStartInstance ? startOptions.requestMiddleware : [defaultCsrfMiddleware],
1299
925
  serializationAdapters
1300
926
  };
1301
- const flattenedRequestMiddlewares = requestStartOptions.requestMiddleware ? flattenMiddlewares(requestStartOptions.requestMiddleware) : [];
1302
- const executedRequestMiddlewares = new Set(flattenedRequestMiddlewares);
927
+ const flattenedRequestMiddlewares = startOptions.requestMiddleware ? flattenMiddlewares(startOptions.requestMiddleware) : [];
928
+ const executedRequestMiddlewares = new Set(
929
+ flattenedRequestMiddlewares
930
+ );
1303
931
  const getRouter = async () => {
1304
932
  if (router) return router;
1305
933
  router = await entries.routerEntry.getRouter();
1306
934
  let isShell = IS_SHELL_ENV;
1307
- if (IS_PRERENDERING && !isShell) isShell = request.headers.get(HEADERS.TSS_SHELL) === "true";
1308
- const history = createMemoryHistory({ initialEntries: [href] });
935
+ if (IS_PRERENDERING && !isShell) {
936
+ isShell = request.headers.get(HEADERS.TSS_SHELL) === "true";
937
+ }
938
+ const history = createMemoryHistory({
939
+ initialEntries: [href]
940
+ });
1309
941
  router.update({
1310
942
  history,
1311
943
  isShell,
1312
944
  isPrerendering: IS_PRERENDERING,
1313
945
  origin: router.options.origin ?? origin,
1314
- defaultSsr: requestStartOptions.defaultSsr,
1315
- serializationAdapters: [...requestStartOptions.serializationAdapters, ...router.options.serializationAdapters || []],
946
+ ...{
947
+ defaultSsr: requestStartOptions.defaultSsr,
948
+ serializationAdapters: [
949
+ ...requestStartOptions.serializationAdapters,
950
+ ...router.options.serializationAdapters || []
951
+ ]
952
+ },
1316
953
  basepath: ROUTER_BASEPATH
1317
954
  });
1318
955
  return router;
1319
956
  };
1320
957
  if (SERVER_FN_BASE && url.pathname.startsWith(SERVER_FN_BASE)) {
1321
- if (false) ;
1322
958
  const serverFnId = url.pathname.slice(SERVER_FN_BASE.length).split("/")[0];
1323
- if (!serverFnId) throw new Error("Invalid server action param for serverFnId");
959
+ if (!serverFnId) {
960
+ throw new Error("Invalid server action param for serverFnId");
961
+ }
1324
962
  const serverFnHandler = async ({ context }) => {
1325
- return runWithStartContext({
1326
- getRouter,
1327
- startOptions: requestStartOptions,
1328
- contextAfterGlobalMiddlewares: context,
1329
- request,
1330
- executedRequestMiddlewares,
1331
- handlerType: "serverFn"
1332
- }, () => handleServerAction({
1333
- request,
1334
- context: requestOpts?.context,
1335
- serverFnId
1336
- }));
963
+ return runWithStartContext(
964
+ {
965
+ getRouter,
966
+ startOptions: requestStartOptions,
967
+ contextAfterGlobalMiddlewares: context,
968
+ request,
969
+ executedRequestMiddlewares
970
+ },
971
+ () => handleServerAction({
972
+ request,
973
+ context: requestOpts?.context,
974
+ serverFnId
975
+ })
976
+ );
1337
977
  };
1338
- const { response: middlewareResponse2 } = await executeMiddleware([...flattenedRequestMiddlewares.map((d) => d.options.server), serverFnHandler], {
978
+ const middlewares2 = flattenedRequestMiddlewares.map(
979
+ (d) => d.options.server
980
+ );
981
+ const ctx2 = await executeMiddleware([...middlewares2, serverFnHandler], {
1339
982
  request,
1340
983
  pathname: url.pathname,
1341
- handlerType: "serverFn",
1342
984
  context: createNullProtoObject(requestOpts?.context)
1343
985
  });
1344
- const result = await handleRedirectResponse(middlewareResponse2, request, getRouter);
1345
- responseOwnsCleanup = result.serverSsrCleanup === "stream";
1346
- return result.response;
986
+ return handleRedirectResponse(ctx2.response, request, getRouter);
1347
987
  }
1348
988
  const executeRouter = async (serverContext, matchedRoutes) => {
1349
- const acceptParts = (request.headers.get("Accept") || "*/*").split(",");
1350
- if (!["*/*", "text/html"].some((mimeType) => acceptParts.some((part) => part.trim().startsWith(mimeType)))) return normalizeSsrResponse(Response.json({ error: "Only HTML requests are supported here" }, { status: 500 }));
1351
- const manifest2 = await resolveManifestForRequest({
1352
- request,
1353
- requestInlineCss: requestOpts?.inlineCss,
1354
- getBaseManifest: () => getBaseManifest(matchedRoutes)
1355
- });
1356
- const earlyHints = createEarlyHintsForRequest({
1357
- onEarlyHints: requestOpts?.onEarlyHints,
1358
- responseLinkHeader: requestOpts?.responseLinkHeader
1359
- });
1360
- earlyHints?.collectStatic({
1361
- manifest: manifest2,
1362
- matchedRoutes
1363
- });
989
+ const acceptHeader = request.headers.get("Accept") || "*/*";
990
+ const acceptParts = acceptHeader.split(",");
991
+ const supportedMimeTypes = ["*/*", "text/html"];
992
+ const isSupported = supportedMimeTypes.some(
993
+ (mimeType) => acceptParts.some((part) => part.trim().startsWith(mimeType))
994
+ );
995
+ if (!isSupported) {
996
+ return Response.json(
997
+ { error: "Only HTML requests are supported here" },
998
+ { status: 500 }
999
+ );
1000
+ }
1001
+ const manifest2 = await resolveManifest(
1002
+ matchedRoutes,
1003
+ await getTransformFn({ warmup: false, request }),
1004
+ cache
1005
+ );
1364
1006
  const routerInstance = await getRouter();
1365
1007
  attachRouterServerSsrUtils({
1366
1008
  router: routerInstance,
1367
- manifest: manifest2,
1368
- getRequestAssets: () => getStartContext({ throwIfNotFound: false })?.requestAssets
1009
+ manifest: manifest2
1369
1010
  });
1370
1011
  routerInstance.update({ additionalContext: { serverContext } });
1371
1012
  await routerInstance.load();
1372
- if (routerInstance.state.redirect) return normalizeSsrResponse(routerInstance.state.redirect);
1373
- earlyHints?.collectDynamic(routerInstance.stores.matches.get());
1374
- const ctx = getStartContext({ throwIfNotFound: false });
1375
- await routerInstance.serverSsr.dehydrate({ requestAssets: ctx?.requestAssets });
1376
- const responseHeaders = getStartResponseHeaders({ router: routerInstance });
1377
- earlyHints?.appendResponseHeaders(responseHeaders);
1378
- return normalizeSsrResponse(await cb({
1013
+ if (routerInstance.state.redirect) {
1014
+ return routerInstance.state.redirect;
1015
+ }
1016
+ await routerInstance.serverSsr.dehydrate();
1017
+ const responseHeaders = getStartResponseHeaders({
1018
+ router: routerInstance
1019
+ });
1020
+ cbWillCleanup = true;
1021
+ return cb({
1379
1022
  request,
1380
1023
  router: routerInstance,
1381
1024
  responseHeaders
1382
- }));
1025
+ });
1383
1026
  };
1384
1027
  const requestHandlerMiddleware = async ({ context }) => {
1385
- return runWithStartContext({
1386
- getRouter,
1387
- startOptions: requestStartOptions,
1388
- contextAfterGlobalMiddlewares: context,
1389
- request,
1390
- executedRequestMiddlewares,
1391
- handlerType: "router"
1392
- }, async () => {
1393
- try {
1394
- return await handleServerRoutes({
1395
- getRouter,
1396
- request,
1397
- url,
1398
- executeRouter,
1399
- context,
1400
- executedRequestMiddlewares
1401
- });
1402
- } catch (err) {
1403
- if (err instanceof Response) return err;
1404
- throw err;
1028
+ return runWithStartContext(
1029
+ {
1030
+ getRouter,
1031
+ startOptions: requestStartOptions,
1032
+ contextAfterGlobalMiddlewares: context,
1033
+ request,
1034
+ executedRequestMiddlewares
1035
+ },
1036
+ async () => {
1037
+ try {
1038
+ return await handleServerRoutes({
1039
+ getRouter,
1040
+ request,
1041
+ url,
1042
+ executeRouter,
1043
+ context,
1044
+ executedRequestMiddlewares
1045
+ });
1046
+ } catch (err) {
1047
+ if (err instanceof Response) {
1048
+ return err;
1049
+ }
1050
+ throw err;
1051
+ }
1405
1052
  }
1406
- });
1053
+ );
1407
1054
  };
1408
- const { response: middlewareResponse } = await executeMiddleware([...flattenedRequestMiddlewares.map((d) => d.options.server), requestHandlerMiddleware], {
1409
- request,
1410
- pathname: url.pathname,
1411
- handlerType: "router",
1412
- context: createNullProtoObject(requestOpts?.context)
1413
- });
1414
- const response = await handleRedirectResponse(middlewareResponse, request, getRouter);
1415
- responseOwnsCleanup = response.serverSsrCleanup === "stream";
1416
- return response.response;
1055
+ const middlewares = flattenedRequestMiddlewares.map(
1056
+ (d) => d.options.server
1057
+ );
1058
+ const ctx = await executeMiddleware(
1059
+ [...middlewares, requestHandlerMiddleware],
1060
+ {
1061
+ request,
1062
+ pathname: url.pathname,
1063
+ context: createNullProtoObject(requestOpts?.context)
1064
+ }
1065
+ );
1066
+ return handleRedirectResponse(ctx.response, request, getRouter);
1417
1067
  } finally {
1418
- if (router?.serverSsr && !responseOwnsCleanup) router.serverSsr.cleanup();
1068
+ if (router && !cbWillCleanup) {
1069
+ router.serverSsr?.cleanup();
1070
+ }
1419
1071
  router = null;
1420
1072
  }
1421
1073
  };
1422
1074
  return requestHandler(startRequestResolver);
1423
1075
  }
1424
1076
  async function handleRedirectResponse(response, request, getRouter) {
1425
- const ssrResponse = normalizeSsrResponse(response);
1426
- if (!isRedirect(ssrResponse.response)) return ssrResponse;
1427
- if (isResolvedRedirect(ssrResponse.response)) {
1428
- if (request.headers.get("x-tsr-serverFn") === "true") return replaceSsrResponse(ssrResponse, Response.json({
1429
- ...ssrResponse.response.options,
1430
- isSerializedRedirect: true
1431
- }, { headers: ssrResponse.response.headers }), "redirect response replaced");
1432
- return ssrResponse;
1077
+ if (!isRedirect(response)) {
1078
+ return response;
1433
1079
  }
1434
- const opts = ssrResponse.response.options;
1435
- if (opts.to && typeof opts.to === "string" && !opts.to.startsWith("/")) throw new Error(`Server side redirects must use absolute paths via the 'href' or 'to' options. The redirect() method's "to" property accepts an internal path only. Use the "href" property to provide an external URL. Received: ${JSON.stringify(opts)}`);
1436
- if ([
1437
- "params",
1438
- "search",
1439
- "hash"
1440
- ].some((d) => typeof opts[d] === "function")) throw new Error(`Server side redirects must use static search, params, and hash values and do not support functional values. Received functional values for: ${Object.keys(opts).filter((d) => typeof opts[d] === "function").map((d) => `"${d}"`).join(", ")}`);
1441
- const redirect = (await getRouter()).resolveRedirect(ssrResponse.response);
1442
- if (request.headers.get("x-tsr-serverFn") === "true") return replaceSsrResponse(ssrResponse, Response.json({
1443
- ...ssrResponse.response.options,
1444
- isSerializedRedirect: true
1445
- }, { headers: ssrResponse.response.headers }), "redirect response replaced");
1446
- return replaceSsrResponse(ssrResponse, redirect, "redirect response replaced");
1080
+ if (isResolvedRedirect(response)) {
1081
+ if (request.headers.get("x-tsr-serverFn") === "true") {
1082
+ return Response.json(
1083
+ { ...response.options, isSerializedRedirect: true },
1084
+ { headers: response.headers }
1085
+ );
1086
+ }
1087
+ return response;
1088
+ }
1089
+ const opts = response.options;
1090
+ if (opts.to && typeof opts.to === "string" && !opts.to.startsWith("/")) {
1091
+ throw new Error(
1092
+ `Server side redirects must use absolute paths via the 'href' or 'to' options. The redirect() method's "to" property accepts an internal path only. Use the "href" property to provide an external URL. Received: ${JSON.stringify(opts)}`
1093
+ );
1094
+ }
1095
+ if (["params", "search", "hash"].some(
1096
+ (d) => typeof opts[d] === "function"
1097
+ )) {
1098
+ throw new Error(
1099
+ `Server side redirects must use static search, params, and hash values and do not support functional values. Received functional values for: ${Object.keys(
1100
+ opts
1101
+ ).filter((d) => typeof opts[d] === "function").map((d) => `"${d}"`).join(", ")}`
1102
+ );
1103
+ }
1104
+ const router = await getRouter();
1105
+ const redirect = router.resolveRedirect(response);
1106
+ if (request.headers.get("x-tsr-serverFn") === "true") {
1107
+ return Response.json(
1108
+ { ...response.options, isSerializedRedirect: true },
1109
+ { headers: response.headers }
1110
+ );
1111
+ }
1112
+ return redirect;
1447
1113
  }
1448
- async function handleServerRoutes({ getRouter, request, url, executeRouter, context, executedRequestMiddlewares }) {
1114
+ async function handleServerRoutes({
1115
+ getRouter,
1116
+ request,
1117
+ url,
1118
+ executeRouter,
1119
+ context,
1120
+ executedRequestMiddlewares
1121
+ }) {
1449
1122
  const router = await getRouter();
1450
- const pathname = executeRewriteInput(router.rewrite, url).pathname;
1123
+ const rewrittenUrl = executeRewriteInput(router.rewrite, url);
1124
+ const pathname = rewrittenUrl.pathname;
1451
1125
  const { matchedRoutes, foundRoute, routeParams } = router.getMatchedRoutes(pathname);
1452
1126
  const isExactMatch = foundRoute && routeParams["**"] === void 0;
1453
1127
  const routeMiddlewares = [];
@@ -1455,41 +1129,45 @@ async function handleServerRoutes({ getRouter, request, url, executeRouter, cont
1455
1129
  const serverMiddleware = route.options.server?.middleware;
1456
1130
  if (serverMiddleware) {
1457
1131
  const flattened = flattenMiddlewares(serverMiddleware);
1458
- for (const m of flattened) if (!executedRequestMiddlewares.has(m)) routeMiddlewares.push(m.options.server);
1132
+ for (const m of flattened) {
1133
+ if (!executedRequestMiddlewares.has(m)) {
1134
+ routeMiddlewares.push(m.options.server);
1135
+ }
1136
+ }
1459
1137
  }
1460
1138
  }
1461
1139
  const server2 = foundRoute?.options.server;
1462
- let isHeadFallback = false;
1463
1140
  if (server2?.handlers && isExactMatch) {
1464
1141
  const handlers = typeof server2.handlers === "function" ? server2.handlers({ createHandlers: (d) => d }) : server2.handlers;
1465
1142
  const requestMethod = request.method.toUpperCase();
1466
- const handler = requestMethod === "HEAD" ? handlers["HEAD"] ?? handlers["GET"] ?? handlers["ANY"] : handlers[requestMethod] ?? handlers["ANY"];
1467
- isHeadFallback = requestMethod === "HEAD" && handler !== void 0 && !handlers["HEAD"];
1143
+ const handler = handlers[requestMethod] ?? handlers["ANY"];
1468
1144
  if (handler) {
1469
1145
  const mayDefer = !!foundRoute.options.component;
1470
- if (typeof handler === "function") routeMiddlewares.push(handlerToMiddleware(handler, mayDefer));
1471
- else {
1146
+ if (typeof handler === "function") {
1147
+ routeMiddlewares.push(handlerToMiddleware(handler, mayDefer));
1148
+ } else {
1472
1149
  if (handler.middleware?.length) {
1473
1150
  const handlerMiddlewares = flattenMiddlewares(handler.middleware);
1474
- for (const m of handlerMiddlewares) routeMiddlewares.push(m.options.server);
1151
+ for (const m of handlerMiddlewares) {
1152
+ routeMiddlewares.push(m.options.server);
1153
+ }
1154
+ }
1155
+ if (handler.handler) {
1156
+ routeMiddlewares.push(handlerToMiddleware(handler.handler, mayDefer));
1475
1157
  }
1476
- if (handler.handler) routeMiddlewares.push(handlerToMiddleware(handler.handler, mayDefer));
1477
1158
  }
1478
1159
  }
1479
1160
  }
1480
- routeMiddlewares.push(((ctx2) => executeRouter(ctx2.context, matchedRoutes)));
1481
- const { ctx, response } = await executeMiddleware(routeMiddlewares, {
1161
+ routeMiddlewares.push(
1162
+ (ctx2) => executeRouter(ctx2.context, matchedRoutes)
1163
+ );
1164
+ const ctx = await executeMiddleware(routeMiddlewares, {
1482
1165
  request,
1483
1166
  context,
1484
1167
  params: routeParams,
1485
- pathname,
1486
- handlerType: "router"
1168
+ pathname
1487
1169
  });
1488
- if (isHeadFallback) {
1489
- if (!ctx.response) throwRouteHandlerError();
1490
- return stripSsrResponseBody(await handleRedirectResponse(response, request, getRouter), "HEAD body stripped");
1491
- }
1492
- return normalizeSsrResponse(response);
1170
+ return ctx.response;
1493
1171
  }
1494
1172
  const fetch = createStartHandler(defaultStreamHandler);
1495
1173
  function createServerEntry(entry) {