@tonyclaw/llm-inspector 1.11.0 → 1.11.2

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 (57) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/index-BpKPXEcb.css +1 -0
  3. package/.output/public/assets/index-Chp_30CP.js +11 -0
  4. package/.output/public/assets/index-DLvqlFS9.js +130 -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 +941 -6305
  8. package/.output/server/_libs/cookie-es.mjs +7 -21
  9. package/.output/server/_libs/floating-ui__core.mjs +18 -17
  10. package/.output/server/_libs/floating-ui__dom.mjs +24 -20
  11. package/.output/server/_libs/floating-ui__react-dom.mjs +55 -28
  12. package/.output/server/_libs/floating-ui__utils.mjs +36 -36
  13. package/.output/server/_libs/h3-v2.mjs +20 -9
  14. package/.output/server/_libs/isbot.mjs +3 -2
  15. package/.output/server/_libs/json-schema-traverse.mjs +1 -90
  16. package/.output/server/_libs/jszip.mjs +28 -28
  17. package/.output/server/_libs/mdast-util-from-markdown.mjs +1 -1
  18. package/.output/server/_libs/pako.mjs +13 -13
  19. package/.output/server/_libs/property-information.mjs +13 -1
  20. package/.output/server/_libs/radix-ui__react-collection.mjs +1 -1
  21. package/.output/server/_libs/radix-ui__react-id.mjs +1 -1
  22. package/.output/server/_libs/react-dom.mjs +10 -10
  23. package/.output/server/_libs/react.mjs +44 -44
  24. package/.output/server/_libs/readable-stream.mjs +15 -15
  25. package/.output/server/_libs/rou3.mjs +1 -7
  26. package/.output/server/_libs/safe-buffer.mjs +3 -3
  27. package/.output/server/_libs/semver.mjs +10 -10
  28. package/.output/server/_libs/seroval-plugins.mjs +5 -5
  29. package/.output/server/_libs/seroval.mjs +606 -596
  30. package/.output/server/_libs/srvx.mjs +10 -245
  31. package/.output/server/_libs/swr.mjs +1 -1
  32. package/.output/server/_libs/tailwind-merge.mjs +286 -41
  33. package/.output/server/_libs/tanstack__history.mjs +31 -44
  34. package/.output/server/_libs/tanstack__react-router.mjs +780 -1089
  35. package/.output/server/_libs/tanstack__react-store.mjs +1 -1
  36. package/.output/server/_libs/tanstack__react-virtual.mjs +82 -7
  37. package/.output/server/_libs/tanstack__router-core.mjs +2223 -2328
  38. package/.output/server/_libs/tanstack__virtual-core.mjs +58 -17
  39. package/.output/server/_libs/ungap__structured-clone.mjs +14 -2
  40. package/.output/server/_libs/use-sync-external-store.mjs +1 -1
  41. package/.output/server/_libs/zod.mjs +503 -205
  42. package/.output/server/_ssr/empty-plugin-adapters-BFgPZ6_d.mjs +6 -0
  43. package/.output/server/_ssr/{index-I_Nx8QEB.mjs → index-CYuV1ljD.mjs} +8 -8
  44. package/.output/server/_ssr/index.mjs +1098 -776
  45. package/.output/server/_ssr/{router-BVxfVFsb.mjs → router-e-RbjELX.mjs} +4 -6
  46. package/.output/server/_tanstack-start-manifest_v-C5P5lsG5.mjs +4 -0
  47. package/.output/server/index.mjs +21 -21
  48. package/package.json +1 -1
  49. package/src/components/providers/ProvidersPanel.tsx +4 -2
  50. package/src/components/providers/SettingsDialog.tsx +2 -1
  51. package/src/proxy/dataDir.ts +1 -1
  52. package/.output/public/assets/index-BIZeMR5N.js +0 -105
  53. package/.output/public/assets/index-SmtLx1lM.css +0 -1
  54. package/.output/public/assets/main-QfbQ5oBP.js +0 -17
  55. package/.output/server/_libs/tiny-invariant.mjs +0 -12
  56. package/.output/server/_libs/tiny-warning.mjs +0 -5
  57. package/.output/server/_tanstack-start-manifest_v-Cm2Owszu.mjs +0 -4
@@ -1,22 +1,20 @@
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";
3
1
  import { AsyncLocalStorage } from "node:async_hooks";
4
2
  import { H as H3Event, t as toResponse } from "../_libs/h3-v2.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";
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";
7
6
  import { j as jsxRuntimeExports } from "../_libs/react.mjs";
8
7
  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";
13
8
  import "../_libs/rou3.mjs";
14
9
  import "../_libs/srvx.mjs";
15
10
  import "node:http";
11
+ import "node:stream";
16
12
  import "node:stream/promises";
17
13
  import "node:https";
18
14
  import "node:http2";
19
- import "../_libs/tiny-warning.mjs";
15
+ import "../_libs/cookie-es.mjs";
16
+ import "../_libs/seroval-plugins.mjs";
17
+ import "node:stream/web";
20
18
  import "../_libs/react-dom.mjs";
21
19
  import "util";
22
20
  import "async_hooks";
@@ -26,20 +24,108 @@ import "../_libs/isbot.mjs";
26
24
  function StartServer(props) {
27
25
  return /* @__PURE__ */ jsxRuntimeExports.jsx(RouterProvider, { router: props.router });
28
26
  }
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 = {
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-C5P5lsG5.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 = {
43
129
  /** Seroval JSON chunk (NDJSON line) */
44
130
  JSON: 0,
45
131
  /** Raw stream data chunk */
@@ -49,66 +135,47 @@ const FrameType = {
49
135
  /** Raw stream error */
50
136
  ERROR: 3
51
137
  };
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;
138
+ var FRAME_HEADER_SIZE = 9;
139
+ var TSS_CONTENT_TYPE_FRAMED_VERSIONED = `${TSS_CONTENT_TYPE_FRAMED}; v=1`;
74
140
  function isSafeKey(key) {
75
141
  return key !== "__proto__" && key !== "constructor" && key !== "prototype";
76
142
  }
77
143
  function safeObjectMerge(target, source) {
78
144
  const result = /* @__PURE__ */ Object.create(null);
79
145
  if (target) {
80
- for (const key of Object.keys(target)) {
81
- if (isSafeKey(key)) result[key] = target[key];
82
- }
146
+ for (const key of Object.keys(target)) if (isSafeKey(key)) result[key] = target[key];
83
147
  }
84
148
  if (source && typeof source === "object") {
85
- for (const key of Object.keys(source)) {
86
- if (isSafeKey(key)) result[key] = source[key];
87
- }
149
+ for (const key of Object.keys(source)) if (isSafeKey(key)) result[key] = source[key];
88
150
  }
89
151
  return result;
90
152
  }
91
153
  function createNullProtoObject(source) {
92
154
  if (!source) return /* @__PURE__ */ Object.create(null);
93
155
  const obj = /* @__PURE__ */ Object.create(null);
94
- for (const key of Object.keys(source)) {
95
- if (isSafeKey(key)) obj[key] = source[key];
96
- }
156
+ for (const key of Object.keys(source)) if (isSafeKey(key)) obj[key] = source[key];
97
157
  return obj;
98
158
  }
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;
99
172
  function flattenMiddlewares(middlewares, maxDepth = 100) {
100
173
  const seen = /* @__PURE__ */ new Set();
101
174
  const flattened = [];
102
175
  const recurse = (middleware, depth) => {
103
- if (depth > maxDepth) {
104
- throw new Error(
105
- `Middleware nesting depth exceeded maximum of ${maxDepth}. Check for circular references.`
106
- );
107
- }
176
+ if (depth > maxDepth) throw new Error(`Middleware nesting depth exceeded maximum of ${maxDepth}. Check for circular references.`);
108
177
  middleware.forEach((m) => {
109
- if (m.options.middleware) {
110
- recurse(m.options.middleware, depth + 1);
111
- }
178
+ if (m.options.middleware) recurse(m.options.middleware, depth + 1);
112
179
  if (!seen.has(m)) {
113
180
  seen.add(m);
114
181
  flattened.push(m);
@@ -118,119 +185,88 @@ function flattenMiddlewares(middlewares, maxDepth = 100) {
118
185
  recurse(middlewares, 0);
119
186
  return flattened;
120
187
  }
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";
137
- }
138
- function getSetCookieValues(headers) {
139
- const headersWithSetCookie = headers;
140
- if (typeof headersWithSetCookie.getSetCookie === "function") {
141
- return headersWithSetCookie.getSetCookie();
142
- }
143
- const value = headers.get("set-cookie");
144
- return value ? [value] : [];
145
- }
146
- function mergeEventResponseHeaders(response, event) {
147
- if (response.ok) {
148
- return;
149
- }
150
- const eventSetCookies = getSetCookieValues(event.res.headers);
151
- if (eventSetCookies.length === 0) {
152
- return;
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
- }
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;
162
222
  }
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
- });
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;
171
230
  }
172
- if (value instanceof Response) {
173
- mergeEventResponseHeaders(value, event);
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);
174
237
  }
175
- return value;
238
+ return isRefererSameOrigin(referer, new URL(ctx.request.url).origin);
176
239
  }
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
- };
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;
186
244
  }
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
- );
245
+ function getOriginFromUrl(url) {
246
+ try {
247
+ return new URL(url).origin;
248
+ } catch {
249
+ return;
193
250
  }
194
- return event.h3Event;
195
251
  }
196
- function getResponse() {
197
- const event = getH3Event();
198
- return event.res;
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;
199
258
  }
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
- };
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
+ });
231
264
  }
232
- const textEncoder$1 = new TextEncoder();
233
- const EMPTY_PAYLOAD = new Uint8Array(0);
265
+ function getDefaultSerovalPlugins() {
266
+ return [...getStartOptions()?.serializationAdapters?.map(makeSerovalPlugin) ?? [], ...defaultSerovalPlugins];
267
+ }
268
+ var textEncoder = new TextEncoder();
269
+ var EMPTY_PAYLOAD = new Uint8Array(0);
234
270
  function encodeFrame(type, streamId, payload) {
235
271
  const frame = new Uint8Array(FRAME_HEADER_SIZE + payload.length);
236
272
  frame[0] = type;
@@ -246,7 +282,7 @@ function encodeFrame(type, streamId, payload) {
246
282
  return frame;
247
283
  }
248
284
  function encodeJSONFrame(json) {
249
- return encodeFrame(FrameType.JSON, 0, textEncoder$1.encode(json));
285
+ return encodeFrame(FrameType.JSON, 0, textEncoder.encode(json));
250
286
  }
251
287
  function encodeChunkFrame(streamId, chunk) {
252
288
  return encodeFrame(FrameType.CHUNK, streamId, chunk);
@@ -256,162 +292,151 @@ function encodeEndFrame(streamId) {
256
292
  }
257
293
  function encodeErrorFrame(streamId, error) {
258
294
  const message = error instanceof Error ? error.message : String(error ?? "Unknown error");
259
- return encodeFrame(FrameType.ERROR, streamId, textEncoder$1.encode(message));
295
+ return encodeFrame(FrameType.ERROR, streamId, textEncoder.encode(message));
260
296
  }
261
- function createMultiplexedStream(jsonStream, rawStreams) {
262
- let activePumps = 1 + rawStreams.size;
263
- let controllerRef = null;
297
+ function createMultiplexedStream(jsonStream, rawStreams, lateStreamSource) {
298
+ let controller;
264
299
  let cancelled = false;
265
- const cancelReaders = [];
266
- const safeEnqueue = (chunk) => {
267
- if (cancelled || !controllerRef) return;
300
+ const readers = [];
301
+ const enqueue = (frame) => {
302
+ if (cancelled) return false;
268
303
  try {
269
- controllerRef.enqueue(chunk);
304
+ controller.enqueue(frame);
305
+ return true;
270
306
  } catch {
307
+ return false;
271
308
  }
272
309
  };
273
- const safeError = (err) => {
274
- if (cancelled || !controllerRef) return;
310
+ const errorOutput = (error) => {
311
+ if (cancelled) return;
312
+ cancelled = true;
275
313
  try {
276
- controllerRef.error(err);
314
+ controller.error(error);
277
315
  } catch {
278
316
  }
317
+ for (const reader of readers) reader.cancel().catch(() => {
318
+ });
279
319
  };
280
- const safeClose = () => {
281
- if (cancelled || !controllerRef) return;
320
+ async function pumpRawStream(streamId, stream) {
321
+ const reader = stream.getReader();
322
+ readers.push(reader);
282
323
  try {
283
- controllerRef.close();
284
- } catch {
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();
285
336
  }
286
- };
287
- const checkComplete = () => {
288
- activePumps--;
289
- if (activePumps === 0) {
290
- safeClose();
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();
291
352
  }
292
- };
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();
367
+ }
368
+ return lateStreamPumps;
369
+ }
293
370
  return new ReadableStream({
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();
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 {
338
382
  }
339
- };
340
- pumpJSON();
341
- for (const [streamId, stream] of rawStreams) {
342
- pumpRawStream(streamId, stream);
383
+ } catch {
343
384
  }
344
385
  },
345
386
  cancel() {
346
387
  cancelled = true;
347
- controllerRef = null;
348
- for (const cancelReader of cancelReaders) {
349
- cancelReader();
350
- }
351
- cancelReaders.length = 0;
388
+ for (const reader of readers) reader.cancel().catch(() => {
389
+ });
390
+ readers.length = 0;
352
391
  }
353
392
  });
354
393
  }
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();
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();
391
399
  const url = new URL(request.url);
392
400
  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
+ });
393
405
  const isServerFn = request.headers.get("x-tsr-serverFn") === "true";
394
- if (!serovalPlugins) {
395
- serovalPlugins = getDefaultSerovalPlugins();
396
- }
406
+ if (!serovalPlugins) serovalPlugins = getDefaultSerovalPlugins();
397
407
  const contentType = request.headers.get("Content-Type");
398
408
  function parsePayload(payload) {
399
- const parsedPayload = Iu(payload, { plugins: serovalPlugins });
400
- return parsedPayload;
409
+ return Pu(payload, { plugins: serovalPlugins });
401
410
  }
402
- const response = await (async () => {
411
+ return await (async () => {
403
412
  try {
404
413
  let serializeResult = function(res2) {
405
414
  let nonStreamingBody = void 0;
406
415
  const alsResponse = getResponse();
407
416
  if (res2 !== void 0) {
408
417
  const rawStreams = /* @__PURE__ */ new Map();
409
- const rawStreamPlugin = createRawStreamRPCPlugin(
410
- (id, stream2) => {
411
- rawStreams.set(id, stream2);
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;
412
434
  }
413
- );
414
- const plugins = [rawStreamPlugin, ...serovalPlugins || []];
435
+ pendingLateStreams.push({
436
+ id,
437
+ stream
438
+ });
439
+ }), ...serovalPlugins || []];
415
440
  let done = false;
416
441
  const callbacks = {
417
442
  onParse: (value) => {
@@ -424,7 +449,7 @@ const handleServerAction = async ({
424
449
  throw error;
425
450
  }
426
451
  };
427
- au(res2, {
452
+ iu(res2, {
428
453
  refs: /* @__PURE__ */ new Map(),
429
454
  plugins,
430
455
  onParse(value) {
@@ -437,73 +462,57 @@ const handleServerAction = async ({
437
462
  callbacks.onError(error);
438
463
  }
439
464
  });
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({
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({
485
481
  start(controller) {
486
- callbacks.onParse = (value) => controller.enqueue(
487
- textEncoder.encode(JSON.stringify(value) + "\n")
488
- );
482
+ callbacks.onParse = (value) => {
483
+ controller.enqueue(JSON.stringify(value) + "\n");
484
+ };
489
485
  callbacks.onDone = () => {
490
486
  try {
491
487
  controller.close();
492
- } catch (error) {
493
- controller.error(error);
488
+ } catch {
494
489
  }
490
+ lateStreamWriter?.close().catch(() => {
491
+ }).finally(() => {
492
+ lateStreamWriter = void 0;
493
+ });
495
494
  };
496
- callbacks.onError = (error) => controller.error(error);
497
- if (nonStreamingBody !== void 0) {
498
- callbacks.onParse(nonStreamingBody);
499
- }
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;
500
509
  }
501
- });
502
- return new Response(stream, {
510
+ }), rawStreams, lateStreamReadable);
511
+ return new Response(multiplexedStream, {
503
512
  status: alsResponse.status,
504
513
  statusText: alsResponse.statusText,
505
514
  headers: {
506
- "Content-Type": "application/x-ndjson",
515
+ "Content-Type": TSS_CONTENT_TYPE_FRAMED_VERSIONED,
507
516
  [X_TSS_SERIALIZED]: "true"
508
517
  }
509
518
  });
@@ -514,13 +523,11 @@ const handleServerAction = async ({
514
523
  });
515
524
  };
516
525
  let res = await (async () => {
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
- );
526
+ if (FORM_DATA_CONTENT_TYPES.some((type) => contentType && contentType.includes(type))) {
527
+ if (methodUpper === "GET") {
528
+ if (false) ;
529
+ invariant();
530
+ }
524
531
  const formData = await request.formData();
525
532
  const serializedContext = formData.get(TSS_FORMDATA_CONTEXT);
526
533
  formData.delete(TSS_FORMDATA_CONTEXT);
@@ -529,85 +536,54 @@ const handleServerAction = async ({
529
536
  data: formData,
530
537
  method: methodUpper
531
538
  };
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
- }
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) ;
547
544
  }
548
545
  return await action(params);
549
546
  }
550
- if (methodLower === "get") {
547
+ if (methodUpper === "GET") {
551
548
  const payloadParam = url.searchParams.get("payload");
552
- if (payloadParam && payloadParam.length > MAX_PAYLOAD_SIZE) {
553
- throw new Error("Payload too large");
554
- }
549
+ if (payloadParam && payloadParam.length > MAX_PAYLOAD_SIZE) throw new Error("Payload too large");
555
550
  const payload2 = payloadParam ? parsePayload(JSON.parse(payloadParam)) : {};
556
- payload2.context = safeObjectMerge(context, payload2.context);
551
+ payload2.context = safeObjectMerge(payload2.context, context);
557
552
  payload2.method = methodUpper;
558
553
  return await action(payload2);
559
554
  }
560
- if (methodLower !== "post") {
561
- throw new Error("expected POST method");
562
- }
563
555
  let jsonPayload;
564
- if (contentType?.includes("application/json")) {
565
- jsonPayload = await request.json();
566
- }
556
+ if (contentType?.includes("application/json")) jsonPayload = await request.json();
567
557
  const payload = jsonPayload ? parsePayload(jsonPayload) : {};
568
558
  payload.context = safeObjectMerge(payload.context, context);
569
559
  payload.method = methodUpper;
570
560
  return await action(payload);
571
561
  })();
572
562
  const unwrapped = res.result || res.error;
573
- if (isNotFound(res)) {
574
- res = isNotFoundResponse(res);
575
- }
576
- if (!isServerFn) {
577
- return unwrapped;
578
- }
563
+ if (isNotFound(res)) res = isNotFoundResponse(res);
564
+ if (!isServerFn) return unwrapped;
579
565
  if (unwrapped instanceof Response) {
580
- if (isRedirect(unwrapped)) {
581
- return unwrapped;
582
- }
566
+ if (isRedirect(unwrapped)) return unwrapped;
583
567
  unwrapped.headers.set(X_TSS_RAW_RESPONSE, "true");
584
568
  return unwrapped;
585
569
  }
586
570
  return serializeResult(res);
587
571
  } catch (error) {
588
- if (error instanceof Response) {
589
- return error;
590
- }
591
- if (isNotFound(error)) {
592
- return isNotFoundResponse(error);
593
- }
572
+ if (error instanceof Response) return error;
573
+ if (isNotFound(error)) return isNotFoundResponse(error);
594
574
  console.info();
595
575
  console.info("Server Fn Error!");
596
576
  console.info();
597
577
  console.error(error);
598
578
  console.info();
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();
579
+ const serializedError = JSON.stringify(await Promise.resolve(su(error, {
580
+ refs: /* @__PURE__ */ new Map(),
581
+ plugins: serovalPlugins
582
+ })));
583
+ const response = getResponse();
608
584
  return new Response(serializedError, {
609
- status: response2.status ?? 500,
610
- statusText: response2.statusText,
585
+ status: response.status ?? 500,
586
+ statusText: response.statusText,
611
587
  headers: {
612
588
  "Content-Type": "application/json",
613
589
  [X_TSS_SERIALIZED]: "true"
@@ -615,7 +591,6 @@ const handleServerAction = async ({
615
591
  });
616
592
  }
617
593
  })();
618
- return response;
619
594
  };
620
595
  function isNotFoundResponse(error) {
621
596
  const { headers, ...rest } = error;
@@ -627,115 +602,534 @@ function isNotFoundResponse(error) {
627
602
  }
628
603
  });
629
604
  }
630
- function resolveTransformConfig(transform) {
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) {
631
899
  if (typeof transform === "string") {
632
900
  const prefix = transform;
633
901
  return {
634
902
  type: "transform",
635
- transformFn: ({ url }) => `${prefix}${url}`,
903
+ transformFn: ({ url }) => ({ href: `${prefix}${url}` }),
636
904
  cache: true
637
905
  };
638
906
  }
639
- if (typeof transform === "function") {
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;
640
914
  return {
641
915
  type: "transform",
642
- transformFn: 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
+ },
643
925
  cache: true
644
926
  };
645
927
  }
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;
928
+ if ("createTransform" in transform && transform.createTransform) return {
929
+ type: "createTransform",
930
+ createTransform: transform.createTransform,
931
+ cache: transform.cache !== false
932
+ };
654
933
  return {
655
934
  type: "transform",
656
- transformFn,
935
+ transformFn: typeof transform.transform === "string" ? (({ url }) => ({ href: `${transform.transform}${url}` })) : transform.transform,
657
936
  cache: transform.cache !== false
658
937
  };
659
938
  }
660
- function buildClientEntryScriptTag(clientEntry, injectedHeadScripts) {
661
- const clientEntryLiteral = JSON.stringify(clientEntry);
662
- let script = `import(${clientEntryLiteral})`;
663
- if (injectedHeadScripts) {
664
- script = `${injectedHeadScripts};${script}`;
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
+ }
665
994
  }
995
+ return manifest2;
996
+ }
997
+ function buildManifest(source, opts) {
666
998
  return {
667
- tag: "script",
668
- attrs: {
669
- type: "module",
670
- async: true
671
- },
672
- children: script
999
+ ...source.scriptFormat ? { scriptFormat: source.scriptFormat } : {},
1000
+ ...opts?.inlineCss !== false && source.inlineCss ? { inlineCss: structuredClone(source.inlineCss) } : {},
1001
+ routes: { ...source.routes }
673
1002
  };
674
1003
  }
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
- }
698
- }
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
- );
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;
1021
+ };
1022
+ }
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;
714
1044
  }
715
- return manifest2;
716
- })();
1045
+ };
717
1046
  }
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
- } : {}
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)
732
1086
  };
733
- return { routes };
734
1087
  }
735
- const HEADERS = {
736
- TSS_SHELL: "X-TSS_SHELL"
737
- };
738
- const ServerFunctionSerializationAdapter = createSerializationAdapter({
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 });
1106
+ }
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
+ });
1114
+ };
1115
+ if (opts.finalManifestCache && (!opts.transformFn || opts.cache)) return getOrCreateCachedFinalManifestPromise(opts.finalManifestCache, getFinalManifestCacheKey(opts.inlineCss), computeFinalManifest);
1116
+ return computeFinalManifest();
1117
+ }
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({
739
1133
  key: "$TSS/serverfn",
740
1134
  test: (v) => {
741
1135
  if (typeof v !== "function") return false;
@@ -745,63 +1139,44 @@ const ServerFunctionSerializationAdapter = createSerializationAdapter({
745
1139
  toSerializable: ({ serverFnMeta }) => ({ functionId: serverFnMeta.id }),
746
1140
  fromSerializable: ({ functionId }) => {
747
1141
  const fn = async (opts, signal) => {
748
- const serverFn = await getServerFnById(functionId);
749
- const result = await serverFn(opts ?? {}, signal);
750
- return result.result;
1142
+ return (await (await getServerFnById(functionId))(opts ?? {}, signal)).result;
751
1143
  };
752
1144
  return fn;
753
1145
  }
754
1146
  });
755
1147
  function getStartResponseHeaders(opts) {
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;
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;
769
1158
  async function loadEntries() {
770
- const routerEntry = await import("./router-BVxfVFsb.mjs").then((n) => n.r);
771
- const startEntry = await import("./start-HYkvq4Ni.mjs");
772
- return { startEntry, routerEntry };
1159
+ const [routerEntry, startEntry, pluginAdapters] = await Promise.all([
1160
+ import("./router-e-RbjELX.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
+ };
773
1169
  }
774
1170
  function getEntries() {
775
- if (!entriesPromise) {
776
- entriesPromise = loadEntries();
777
- }
1171
+ if (!entriesPromise) entriesPromise = loadEntries();
778
1172
  return entriesPromise;
779
1173
  }
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";
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";
805
1180
  function throwRouteHandlerError() {
806
1181
  throw new Error(ERR_NO_RESPONSE);
807
1182
  }
@@ -812,316 +1187,267 @@ function isSpecialResponse(value) {
812
1187
  return value instanceof Response || isRedirect(value);
813
1188
  }
814
1189
  function handleCtxResult(result) {
815
- if (isSpecialResponse(result)) {
816
- return { response: result };
817
- }
1190
+ if (isSsrResponse(result) || isSpecialResponse(result)) return { response: result };
818
1191
  return result;
819
1192
  }
820
- function executeMiddleware(middlewares, ctx) {
1193
+ async function executeMiddleware(middlewares, ctx) {
821
1194
  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
+ };
822
1224
  const next = async (nextCtx) => {
823
1225
  if (nextCtx) {
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
- }
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];
832
1229
  }
833
1230
  index++;
834
1231
  const middleware = middlewares[index];
835
1232
  if (!middleware) return ctx;
836
1233
  let result;
837
1234
  try {
838
- result = await middleware({ ...ctx, next });
1235
+ result = await middleware({
1236
+ ...ctx,
1237
+ next
1238
+ });
839
1239
  } catch (err) {
840
1240
  if (isSpecialResponse(err)) {
841
- ctx.response = err;
1241
+ setResponse(err);
842
1242
  return ctx;
843
1243
  }
1244
+ await disposeStreamResponse("middleware error");
844
1245
  throw err;
845
1246
  }
846
1247
  const normalized = handleCtxResult(result);
847
1248
  if (normalized) {
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
- }
1249
+ if (normalized.response !== void 0) setResponse(normalized.response);
1250
+ if (normalized.context) ctx.context = safeObjectMerge(ctx.context, normalized.context);
854
1251
  }
855
1252
  return ctx;
856
1253
  };
857
- return next();
1254
+ await next();
1255
+ return {
1256
+ ctx,
1257
+ response: await getFinalResponse()
1258
+ };
858
1259
  }
859
1260
  function handlerToMiddleware(handler, mayDefer = false) {
860
- if (mayDefer) {
861
- return handler;
862
- }
1261
+ if (mayDefer) return handler;
863
1262
  return async (ctx) => {
864
- const response = await handler({ ...ctx, next: throwIfMayNotDefer });
865
- if (!response) {
866
- throwRouteHandlerError();
867
- }
1263
+ const response = await handler({
1264
+ ...ctx,
1265
+ next: throwIfMayNotDefer
1266
+ });
1267
+ if (!response) throwRouteHandlerError();
868
1268
  return response;
869
1269
  };
870
1270
  }
871
1271
  function createStartHandler(cbOrOptions) {
1272
+ const handlerOptions = typeof cbOrOptions === "function" ? {} : cbOrOptions;
872
1273
  const cb = typeof cbOrOptions === "function" ? cbOrOptions : cbOrOptions.handler;
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
- }
1274
+ const finalManifestResolver = createFinalManifestResolver({
1275
+ ...handlerOptions
1276
+ });
1277
+ const resolveManifestForRequest = finalManifestResolver.resolveCached;
1278
+ finalManifestResolver.warmup({ getBaseManifest: () => getBaseManifest() });
907
1279
  const startRequestResolver = async (request, requestOpts) => {
908
1280
  let router = null;
909
- let cbWillCleanup = false;
1281
+ let responseOwnsCleanup = false;
910
1282
  try {
911
1283
  const { url, handledProtocolRelativeURL } = getNormalizedURL(request.url);
912
1284
  const href = url.pathname + url.search + url.hash;
913
1285
  const origin = getOrigin(request);
914
- if (handledProtocolRelativeURL) {
915
- return Response.redirect(url, 308);
916
- }
1286
+ if (handledProtocolRelativeURL) return Response.redirect(url, 308);
917
1287
  const entries = await getEntries();
1288
+ const hasStartInstance = !!entries.startEntry.startInstance;
918
1289
  const startOptions = await entries.startEntry.startInstance?.getOptions() || {};
1290
+ const { hasPluginAdapters, pluginSerializationAdapters } = entries.pluginAdapters;
919
1291
  const serializationAdapters = [
920
1292
  ...startOptions.serializationAdapters || [],
1293
+ ...hasPluginAdapters ? pluginSerializationAdapters : [],
921
1294
  ServerFunctionSerializationAdapter
922
1295
  ];
923
1296
  const requestStartOptions = {
924
1297
  ...startOptions,
1298
+ requestMiddleware: hasStartInstance ? startOptions.requestMiddleware : [defaultCsrfMiddleware],
925
1299
  serializationAdapters
926
1300
  };
927
- const flattenedRequestMiddlewares = startOptions.requestMiddleware ? flattenMiddlewares(startOptions.requestMiddleware) : [];
928
- const executedRequestMiddlewares = new Set(
929
- flattenedRequestMiddlewares
930
- );
1301
+ const flattenedRequestMiddlewares = requestStartOptions.requestMiddleware ? flattenMiddlewares(requestStartOptions.requestMiddleware) : [];
1302
+ const executedRequestMiddlewares = new Set(flattenedRequestMiddlewares);
931
1303
  const getRouter = async () => {
932
1304
  if (router) return router;
933
1305
  router = await entries.routerEntry.getRouter();
934
1306
  let isShell = IS_SHELL_ENV;
935
- if (IS_PRERENDERING && !isShell) {
936
- isShell = request.headers.get(HEADERS.TSS_SHELL) === "true";
937
- }
938
- const history = createMemoryHistory({
939
- initialEntries: [href]
940
- });
1307
+ if (IS_PRERENDERING && !isShell) isShell = request.headers.get(HEADERS.TSS_SHELL) === "true";
1308
+ const history = createMemoryHistory({ initialEntries: [href] });
941
1309
  router.update({
942
1310
  history,
943
1311
  isShell,
944
1312
  isPrerendering: IS_PRERENDERING,
945
1313
  origin: router.options.origin ?? origin,
946
- ...{
947
- defaultSsr: requestStartOptions.defaultSsr,
948
- serializationAdapters: [
949
- ...requestStartOptions.serializationAdapters,
950
- ...router.options.serializationAdapters || []
951
- ]
952
- },
1314
+ defaultSsr: requestStartOptions.defaultSsr,
1315
+ serializationAdapters: [...requestStartOptions.serializationAdapters, ...router.options.serializationAdapters || []],
953
1316
  basepath: ROUTER_BASEPATH
954
1317
  });
955
1318
  return router;
956
1319
  };
957
1320
  if (SERVER_FN_BASE && url.pathname.startsWith(SERVER_FN_BASE)) {
1321
+ if (false) ;
958
1322
  const serverFnId = url.pathname.slice(SERVER_FN_BASE.length).split("/")[0];
959
- if (!serverFnId) {
960
- throw new Error("Invalid server action param for serverFnId");
961
- }
1323
+ if (!serverFnId) throw new Error("Invalid server action param for serverFnId");
962
1324
  const serverFnHandler = async ({ context }) => {
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
- );
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
+ }));
977
1337
  };
978
- const middlewares2 = flattenedRequestMiddlewares.map(
979
- (d) => d.options.server
980
- );
981
- const ctx2 = await executeMiddleware([...middlewares2, serverFnHandler], {
1338
+ const { response: middlewareResponse2 } = await executeMiddleware([...flattenedRequestMiddlewares.map((d) => d.options.server), serverFnHandler], {
982
1339
  request,
983
1340
  pathname: url.pathname,
1341
+ handlerType: "serverFn",
984
1342
  context: createNullProtoObject(requestOpts?.context)
985
1343
  });
986
- return handleRedirectResponse(ctx2.response, request, getRouter);
1344
+ const result = await handleRedirectResponse(middlewareResponse2, request, getRouter);
1345
+ responseOwnsCleanup = result.serverSsrCleanup === "stream";
1346
+ return result.response;
987
1347
  }
988
1348
  const executeRouter = async (serverContext, matchedRoutes) => {
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
- );
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
+ });
1006
1364
  const routerInstance = await getRouter();
1007
1365
  attachRouterServerSsrUtils({
1008
1366
  router: routerInstance,
1009
- manifest: manifest2
1367
+ manifest: manifest2,
1368
+ getRequestAssets: () => getStartContext({ throwIfNotFound: false })?.requestAssets
1010
1369
  });
1011
1370
  routerInstance.update({ additionalContext: { serverContext } });
1012
1371
  await routerInstance.load();
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({
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({
1022
1379
  request,
1023
1380
  router: routerInstance,
1024
1381
  responseHeaders
1025
- });
1382
+ }));
1026
1383
  };
1027
1384
  const requestHandlerMiddleware = async ({ context }) => {
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
- }
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;
1052
1405
  }
1053
- );
1406
+ });
1054
1407
  };
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);
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;
1067
1417
  } finally {
1068
- if (router && !cbWillCleanup) {
1069
- router.serverSsr?.cleanup();
1070
- }
1418
+ if (router?.serverSsr && !responseOwnsCleanup) router.serverSsr.cleanup();
1071
1419
  router = null;
1072
1420
  }
1073
1421
  };
1074
1422
  return requestHandler(startRequestResolver);
1075
1423
  }
1076
1424
  async function handleRedirectResponse(response, request, getRouter) {
1077
- if (!isRedirect(response)) {
1078
- return response;
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;
1079
1433
  }
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;
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");
1113
1447
  }
1114
- async function handleServerRoutes({
1115
- getRouter,
1116
- request,
1117
- url,
1118
- executeRouter,
1119
- context,
1120
- executedRequestMiddlewares
1121
- }) {
1448
+ async function handleServerRoutes({ getRouter, request, url, executeRouter, context, executedRequestMiddlewares }) {
1122
1449
  const router = await getRouter();
1123
- const rewrittenUrl = executeRewriteInput(router.rewrite, url);
1124
- const pathname = rewrittenUrl.pathname;
1450
+ const pathname = executeRewriteInput(router.rewrite, url).pathname;
1125
1451
  const { matchedRoutes, foundRoute, routeParams } = router.getMatchedRoutes(pathname);
1126
1452
  const isExactMatch = foundRoute && routeParams["**"] === void 0;
1127
1453
  const routeMiddlewares = [];
@@ -1129,45 +1455,41 @@ async function handleServerRoutes({
1129
1455
  const serverMiddleware = route.options.server?.middleware;
1130
1456
  if (serverMiddleware) {
1131
1457
  const flattened = flattenMiddlewares(serverMiddleware);
1132
- for (const m of flattened) {
1133
- if (!executedRequestMiddlewares.has(m)) {
1134
- routeMiddlewares.push(m.options.server);
1135
- }
1136
- }
1458
+ for (const m of flattened) if (!executedRequestMiddlewares.has(m)) routeMiddlewares.push(m.options.server);
1137
1459
  }
1138
1460
  }
1139
1461
  const server2 = foundRoute?.options.server;
1462
+ let isHeadFallback = false;
1140
1463
  if (server2?.handlers && isExactMatch) {
1141
1464
  const handlers = typeof server2.handlers === "function" ? server2.handlers({ createHandlers: (d) => d }) : server2.handlers;
1142
1465
  const requestMethod = request.method.toUpperCase();
1143
- const handler = handlers[requestMethod] ?? handlers["ANY"];
1466
+ const handler = requestMethod === "HEAD" ? handlers["HEAD"] ?? handlers["GET"] ?? handlers["ANY"] : handlers[requestMethod] ?? handlers["ANY"];
1467
+ isHeadFallback = requestMethod === "HEAD" && handler !== void 0 && !handlers["HEAD"];
1144
1468
  if (handler) {
1145
1469
  const mayDefer = !!foundRoute.options.component;
1146
- if (typeof handler === "function") {
1147
- routeMiddlewares.push(handlerToMiddleware(handler, mayDefer));
1148
- } else {
1470
+ if (typeof handler === "function") routeMiddlewares.push(handlerToMiddleware(handler, mayDefer));
1471
+ else {
1149
1472
  if (handler.middleware?.length) {
1150
1473
  const handlerMiddlewares = flattenMiddlewares(handler.middleware);
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));
1474
+ for (const m of handlerMiddlewares) routeMiddlewares.push(m.options.server);
1157
1475
  }
1476
+ if (handler.handler) routeMiddlewares.push(handlerToMiddleware(handler.handler, mayDefer));
1158
1477
  }
1159
1478
  }
1160
1479
  }
1161
- routeMiddlewares.push(
1162
- (ctx2) => executeRouter(ctx2.context, matchedRoutes)
1163
- );
1164
- const ctx = await executeMiddleware(routeMiddlewares, {
1480
+ routeMiddlewares.push(((ctx2) => executeRouter(ctx2.context, matchedRoutes)));
1481
+ const { ctx, response } = await executeMiddleware(routeMiddlewares, {
1165
1482
  request,
1166
1483
  context,
1167
1484
  params: routeParams,
1168
- pathname
1485
+ pathname,
1486
+ handlerType: "router"
1169
1487
  });
1170
- return ctx.response;
1488
+ if (isHeadFallback) {
1489
+ if (!ctx.response) throwRouteHandlerError();
1490
+ return stripSsrResponseBody(await handleRedirectResponse(response, request, getRouter), "HEAD body stripped");
1491
+ }
1492
+ return normalizeSsrResponse(response);
1171
1493
  }
1172
1494
  const fetch = createStartHandler(defaultStreamHandler);
1173
1495
  function createServerEntry(entry) {