@tanstack/router-core 1.157.11 → 1.157.12

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.
@@ -45,19 +45,19 @@ function createRequestHandler({
45
45
  };
46
46
  }
47
47
  function getRequestHeaders(opts) {
48
- let headers$1 = headers.mergeHeaders(
49
- {
50
- "Content-Type": "text/html; charset=UTF-8"
51
- },
52
- ...opts.router.state.matches.map((match) => {
53
- return match.headers;
54
- })
48
+ const matchHeaders = opts.router.state.matches.map(
49
+ (match) => match.headers
55
50
  );
56
51
  const { redirect } = opts.router.state;
57
52
  if (redirect) {
58
- headers$1 = headers.mergeHeaders(headers$1, redirect.headers);
53
+ matchHeaders.push(redirect.headers);
59
54
  }
60
- return headers$1;
55
+ return headers.mergeHeaders(
56
+ {
57
+ "Content-Type": "text/html; charset=UTF-8"
58
+ },
59
+ ...matchHeaders
60
+ );
61
61
  }
62
62
  exports.createRequestHandler = createRequestHandler;
63
63
  //# sourceMappingURL=createRequestHandler.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"createRequestHandler.cjs","sources":["../../../src/ssr/createRequestHandler.ts"],"sourcesContent":["import { createMemoryHistory } from '@tanstack/history'\nimport { mergeHeaders } from './headers'\nimport {\n attachRouterServerSsrUtils,\n getNormalizedURL,\n getOrigin,\n} from './ssr-server'\nimport type { HandlerCallback } from './handlerCallback'\nimport type { AnyRouter } from '../router'\nimport type { Manifest } from '../manifest'\n\nexport type RequestHandler<TRouter extends AnyRouter> = (\n cb: HandlerCallback<TRouter>,\n) => Promise<Response>\n\nexport function createRequestHandler<TRouter extends AnyRouter>({\n createRouter,\n request,\n getRouterManifest,\n}: {\n createRouter: () => TRouter\n request: Request\n getRouterManifest?: () => Manifest | Promise<Manifest>\n}): RequestHandler<TRouter> {\n return async (cb) => {\n const router = createRouter()\n // Track whether the callback will handle cleanup\n let cbWillCleanup = false\n\n try {\n attachRouterServerSsrUtils({\n router,\n manifest: await getRouterManifest?.(),\n })\n\n // normalizing and sanitizing the pathname here for server, so we always deal with the same format during SSR.\n const url = getNormalizedURL(request.url, 'http://localhost')\n const origin = getOrigin(request)\n const href = url.href.replace(url.origin, '')\n\n // Create a history for the router\n const history = createMemoryHistory({\n initialEntries: [href],\n })\n\n // Update the router with the history and context\n router.update({\n history,\n origin: router.options.origin ?? origin,\n })\n\n await router.load()\n\n await router.serverSsr?.dehydrate()\n\n const responseHeaders = getRequestHeaders({\n router,\n })\n\n // Mark that the callback will handle cleanup\n cbWillCleanup = true\n return cb({\n request,\n router,\n responseHeaders,\n } as any)\n } finally {\n if (!cbWillCleanup) {\n // Clean up router SSR state if the callback won't handle it\n // (e.g., if an error occurred before the callback was invoked).\n // When the callback runs, it handles cleanup (either via transformStreamWithRouter\n // for streaming, or directly in renderRouterToString for non-streaming).\n router.serverSsr?.cleanup()\n }\n }\n }\n}\n\nfunction getRequestHeaders(opts: { router: AnyRouter }): Headers {\n let headers = mergeHeaders(\n {\n 'Content-Type': 'text/html; charset=UTF-8',\n },\n ...opts.router.state.matches.map((match) => {\n return match.headers\n }),\n )\n\n // Handle Redirects\n const { redirect } = opts.router.state\n\n if (redirect) {\n headers = mergeHeaders(headers, redirect.headers)\n }\n\n return headers\n}\n"],"names":["attachRouterServerSsrUtils","getNormalizedURL","getOrigin","history","createMemoryHistory","headers","mergeHeaders"],"mappings":";;;;;AAeO,SAAS,qBAAgD;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AACF,GAI4B;AAC1B,SAAO,OAAO,OAAO;AACnB,UAAM,SAAS,aAAA;AAEf,QAAI,gBAAgB;AAEpB,QAAI;AACFA,2CAA2B;AAAA,QACzB;AAAA,QACA,UAAU,MAAM,oBAAA;AAAA,MAAoB,CACrC;AAGD,YAAM,MAAMC,UAAAA,iBAAiB,QAAQ,KAAK,kBAAkB;AAC5D,YAAM,SAASC,UAAAA,UAAU,OAAO;AAChC,YAAM,OAAO,IAAI,KAAK,QAAQ,IAAI,QAAQ,EAAE;AAG5C,YAAMC,YAAUC,QAAAA,oBAAoB;AAAA,QAClC,gBAAgB,CAAC,IAAI;AAAA,MAAA,CACtB;AAGD,aAAO,OAAO;AAAA,QAAA,SACZD;AAAAA,QACA,QAAQ,OAAO,QAAQ,UAAU;AAAA,MAAA,CAClC;AAED,YAAM,OAAO,KAAA;AAEb,YAAM,OAAO,WAAW,UAAA;AAExB,YAAM,kBAAkB,kBAAkB;AAAA,QACxC;AAAA,MAAA,CACD;AAGD,sBAAgB;AAChB,aAAO,GAAG;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACM;AAAA,IACV,UAAA;AACE,UAAI,CAAC,eAAe;AAKlB,eAAO,WAAW,QAAA;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,MAAsC;AAC/D,MAAIE,YAAUC,QAAAA;AAAAA,IACZ;AAAA,MACE,gBAAgB;AAAA,IAAA;AAAA,IAElB,GAAG,KAAK,OAAO,MAAM,QAAQ,IAAI,CAAC,UAAU;AAC1C,aAAO,MAAM;AAAA,IACf,CAAC;AAAA,EAAA;AAIH,QAAM,EAAE,SAAA,IAAa,KAAK,OAAO;AAEjC,MAAI,UAAU;AACZD,gBAAUC,QAAAA,aAAaD,WAAS,SAAS,OAAO;AAAA,EAClD;AAEA,SAAOA;AACT;;"}
1
+ {"version":3,"file":"createRequestHandler.cjs","sources":["../../../src/ssr/createRequestHandler.ts"],"sourcesContent":["import { createMemoryHistory } from '@tanstack/history'\nimport { mergeHeaders } from './headers'\nimport {\n attachRouterServerSsrUtils,\n getNormalizedURL,\n getOrigin,\n} from './ssr-server'\nimport type { HandlerCallback } from './handlerCallback'\nimport type { AnyHeaders } from './headers'\nimport type { AnyRouter } from '../router'\nimport type { Manifest } from '../manifest'\n\nexport type RequestHandler<TRouter extends AnyRouter> = (\n cb: HandlerCallback<TRouter>,\n) => Promise<Response>\n\nexport function createRequestHandler<TRouter extends AnyRouter>({\n createRouter,\n request,\n getRouterManifest,\n}: {\n createRouter: () => TRouter\n request: Request\n getRouterManifest?: () => Manifest | Promise<Manifest>\n}): RequestHandler<TRouter> {\n return async (cb) => {\n const router = createRouter()\n // Track whether the callback will handle cleanup\n let cbWillCleanup = false\n\n try {\n attachRouterServerSsrUtils({\n router,\n manifest: await getRouterManifest?.(),\n })\n\n // normalizing and sanitizing the pathname here for server, so we always deal with the same format during SSR.\n const url = getNormalizedURL(request.url, 'http://localhost')\n const origin = getOrigin(request)\n const href = url.href.replace(url.origin, '')\n\n // Create a history for the router\n const history = createMemoryHistory({\n initialEntries: [href],\n })\n\n // Update the router with the history and context\n router.update({\n history,\n origin: router.options.origin ?? origin,\n })\n\n await router.load()\n\n await router.serverSsr?.dehydrate()\n\n const responseHeaders = getRequestHeaders({\n router,\n })\n\n // Mark that the callback will handle cleanup\n cbWillCleanup = true\n return cb({\n request,\n router,\n responseHeaders,\n } as any)\n } finally {\n if (!cbWillCleanup) {\n // Clean up router SSR state if the callback won't handle it\n // (e.g., if an error occurred before the callback was invoked).\n // When the callback runs, it handles cleanup (either via transformStreamWithRouter\n // for streaming, or directly in renderRouterToString for non-streaming).\n router.serverSsr?.cleanup()\n }\n }\n }\n}\n\nfunction getRequestHeaders(opts: { router: AnyRouter }): Headers {\n const matchHeaders = opts.router.state.matches.map<AnyHeaders>(\n (match) => match.headers,\n )\n\n // Handle Redirects\n const { redirect } = opts.router.state\n if (redirect) {\n matchHeaders.push(redirect.headers)\n }\n\n return mergeHeaders(\n {\n 'Content-Type': 'text/html; charset=UTF-8',\n },\n ...matchHeaders,\n )\n}\n"],"names":["attachRouterServerSsrUtils","getNormalizedURL","getOrigin","history","createMemoryHistory","mergeHeaders"],"mappings":";;;;;AAgBO,SAAS,qBAAgD;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AACF,GAI4B;AAC1B,SAAO,OAAO,OAAO;AACnB,UAAM,SAAS,aAAA;AAEf,QAAI,gBAAgB;AAEpB,QAAI;AACFA,2CAA2B;AAAA,QACzB;AAAA,QACA,UAAU,MAAM,oBAAA;AAAA,MAAoB,CACrC;AAGD,YAAM,MAAMC,UAAAA,iBAAiB,QAAQ,KAAK,kBAAkB;AAC5D,YAAM,SAASC,UAAAA,UAAU,OAAO;AAChC,YAAM,OAAO,IAAI,KAAK,QAAQ,IAAI,QAAQ,EAAE;AAG5C,YAAMC,YAAUC,QAAAA,oBAAoB;AAAA,QAClC,gBAAgB,CAAC,IAAI;AAAA,MAAA,CACtB;AAGD,aAAO,OAAO;AAAA,QAAA,SACZD;AAAAA,QACA,QAAQ,OAAO,QAAQ,UAAU;AAAA,MAAA,CAClC;AAED,YAAM,OAAO,KAAA;AAEb,YAAM,OAAO,WAAW,UAAA;AAExB,YAAM,kBAAkB,kBAAkB;AAAA,QACxC;AAAA,MAAA,CACD;AAGD,sBAAgB;AAChB,aAAO,GAAG;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACM;AAAA,IACV,UAAA;AACE,UAAI,CAAC,eAAe;AAKlB,eAAO,WAAW,QAAA;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,MAAsC;AAC/D,QAAM,eAAe,KAAK,OAAO,MAAM,QAAQ;AAAA,IAC7C,CAAC,UAAU,MAAM;AAAA,EAAA;AAInB,QAAM,EAAE,SAAA,IAAa,KAAK,OAAO;AACjC,MAAI,UAAU;AACZ,iBAAa,KAAK,SAAS,OAAO;AAAA,EACpC;AAEA,SAAOE,QAAAA;AAAAA,IACL;AAAA,MACE,gBAAgB;AAAA,IAAA;AAAA,IAElB,GAAG;AAAA,EAAA;AAEP;;"}
@@ -11,18 +11,19 @@ function headersInitToObject(headers) {
11
11
  }
12
12
  function toHeadersInstance(init) {
13
13
  if (init instanceof Headers) {
14
- return new Headers(init);
14
+ return init;
15
15
  } else if (Array.isArray(init)) {
16
16
  return new Headers(init);
17
17
  } else if (typeof init === "object") {
18
18
  return new Headers(init);
19
19
  } else {
20
- return new Headers();
20
+ return null;
21
21
  }
22
22
  }
23
23
  function mergeHeaders(...headers) {
24
24
  return headers.reduce((acc, header) => {
25
25
  const headersInstance = toHeadersInstance(header);
26
+ if (!headersInstance) return acc;
26
27
  for (const [key, value] of headersInstance.entries()) {
27
28
  if (key === "set-cookie") {
28
29
  const splitCookies = cookieEs.splitSetCookieString(value);
@@ -1 +1 @@
1
- {"version":3,"file":"headers.cjs","sources":["../../../src/ssr/headers.ts"],"sourcesContent":["import { splitSetCookieString } from 'cookie-es'\nimport type { OutgoingHttpHeaders } from 'node:http2'\n\n// A utility function to turn HeadersInit into an object\nexport function headersInitToObject(\n headers: HeadersInit,\n): Record<keyof OutgoingHttpHeaders, string> {\n const obj: Record<keyof OutgoingHttpHeaders, string> = {}\n const headersInstance = new Headers(headers)\n for (const [key, value] of headersInstance.entries()) {\n obj[key] = value\n }\n return obj\n}\n\ntype AnyHeaders =\n | Headers\n | HeadersInit\n | Record<string, string>\n | Array<[string, string]>\n | OutgoingHttpHeaders\n | undefined\n\n// Helper function to convert various HeaderInit types to a Headers instance\nfunction toHeadersInstance(init: AnyHeaders) {\n if (init instanceof Headers) {\n return new Headers(init)\n } else if (Array.isArray(init)) {\n return new Headers(init)\n } else if (typeof init === 'object') {\n return new Headers(init as HeadersInit)\n } else {\n return new Headers()\n }\n}\n\n// Function to merge headers with proper overrides\nexport function mergeHeaders(...headers: Array<AnyHeaders>) {\n return headers.reduce((acc: Headers, header) => {\n const headersInstance = toHeadersInstance(header)\n for (const [key, value] of headersInstance.entries()) {\n if (key === 'set-cookie') {\n const splitCookies = splitSetCookieString(value)\n splitCookies.forEach((cookie) => acc.append('set-cookie', cookie))\n } else {\n acc.set(key, value)\n }\n }\n return acc\n }, new Headers())\n}\n"],"names":["splitSetCookieString"],"mappings":";;;AAIO,SAAS,oBACd,SAC2C;AAC3C,QAAM,MAAiD,CAAA;AACvD,QAAM,kBAAkB,IAAI,QAAQ,OAAO;AAC3C,aAAW,CAAC,KAAK,KAAK,KAAK,gBAAgB,WAAW;AACpD,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAWA,SAAS,kBAAkB,MAAkB;AAC3C,MAAI,gBAAgB,SAAS;AAC3B,WAAO,IAAI,QAAQ,IAAI;AAAA,EACzB,WAAW,MAAM,QAAQ,IAAI,GAAG;AAC9B,WAAO,IAAI,QAAQ,IAAI;AAAA,EACzB,WAAW,OAAO,SAAS,UAAU;AACnC,WAAO,IAAI,QAAQ,IAAmB;AAAA,EACxC,OAAO;AACL,WAAO,IAAI,QAAA;AAAA,EACb;AACF;AAGO,SAAS,gBAAgB,SAA4B;AAC1D,SAAO,QAAQ,OAAO,CAAC,KAAc,WAAW;AAC9C,UAAM,kBAAkB,kBAAkB,MAAM;AAChD,eAAW,CAAC,KAAK,KAAK,KAAK,gBAAgB,WAAW;AACpD,UAAI,QAAQ,cAAc;AACxB,cAAM,eAAeA,SAAAA,qBAAqB,KAAK;AAC/C,qBAAa,QAAQ,CAAC,WAAW,IAAI,OAAO,cAAc,MAAM,CAAC;AAAA,MACnE,OAAO;AACL,YAAI,IAAI,KAAK,KAAK;AAAA,MACpB;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,IAAI,SAAS;AAClB;;;"}
1
+ {"version":3,"file":"headers.cjs","sources":["../../../src/ssr/headers.ts"],"sourcesContent":["import { splitSetCookieString } from 'cookie-es'\nimport type { OutgoingHttpHeaders } from 'node:http2'\n\n// A utility function to turn HeadersInit into an object\nexport function headersInitToObject(\n headers: HeadersInit,\n): Record<keyof OutgoingHttpHeaders, string> {\n const obj: Record<keyof OutgoingHttpHeaders, string> = {}\n const headersInstance = new Headers(headers)\n for (const [key, value] of headersInstance.entries()) {\n obj[key] = value\n }\n return obj\n}\n\nexport type AnyHeaders =\n | Headers\n | HeadersInit\n | Record<string, string>\n | Array<[string, string]>\n | OutgoingHttpHeaders\n | undefined\n\n// Helper function to convert various HeaderInit types to a Headers instance\nfunction toHeadersInstance(init: AnyHeaders) {\n if (init instanceof Headers) {\n return init\n } else if (Array.isArray(init)) {\n return new Headers(init)\n } else if (typeof init === 'object') {\n return new Headers(init as HeadersInit)\n } else {\n return null\n }\n}\n\n// Function to merge headers with proper overrides\nexport function mergeHeaders(...headers: Array<AnyHeaders>) {\n return headers.reduce((acc: Headers, header) => {\n const headersInstance = toHeadersInstance(header)\n if (!headersInstance) return acc\n for (const [key, value] of headersInstance.entries()) {\n if (key === 'set-cookie') {\n const splitCookies = splitSetCookieString(value)\n splitCookies.forEach((cookie) => acc.append('set-cookie', cookie))\n } else {\n acc.set(key, value)\n }\n }\n return acc\n }, new Headers())\n}\n"],"names":["splitSetCookieString"],"mappings":";;;AAIO,SAAS,oBACd,SAC2C;AAC3C,QAAM,MAAiD,CAAA;AACvD,QAAM,kBAAkB,IAAI,QAAQ,OAAO;AAC3C,aAAW,CAAC,KAAK,KAAK,KAAK,gBAAgB,WAAW;AACpD,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAWA,SAAS,kBAAkB,MAAkB;AAC3C,MAAI,gBAAgB,SAAS;AAC3B,WAAO;AAAA,EACT,WAAW,MAAM,QAAQ,IAAI,GAAG;AAC9B,WAAO,IAAI,QAAQ,IAAI;AAAA,EACzB,WAAW,OAAO,SAAS,UAAU;AACnC,WAAO,IAAI,QAAQ,IAAmB;AAAA,EACxC,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAGO,SAAS,gBAAgB,SAA4B;AAC1D,SAAO,QAAQ,OAAO,CAAC,KAAc,WAAW;AAC9C,UAAM,kBAAkB,kBAAkB,MAAM;AAChD,QAAI,CAAC,gBAAiB,QAAO;AAC7B,eAAW,CAAC,KAAK,KAAK,KAAK,gBAAgB,WAAW;AACpD,UAAI,QAAQ,cAAc;AACxB,cAAM,eAAeA,SAAAA,qBAAqB,KAAK;AAC/C,qBAAa,QAAQ,CAAC,WAAW,IAAI,OAAO,cAAc,MAAM,CAAC;AAAA,MACnE,OAAO;AACL,YAAI,IAAI,KAAK,KAAK;AAAA,MACpB;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,IAAI,SAAS;AAClB;;;"}
@@ -1,5 +1,4 @@
1
1
  import { OutgoingHttpHeaders } from 'node:http2';
2
2
  export declare function headersInitToObject(headers: HeadersInit): Record<keyof OutgoingHttpHeaders, string>;
3
- type AnyHeaders = Headers | HeadersInit | Record<string, string> | Array<[string, string]> | OutgoingHttpHeaders | undefined;
3
+ export type AnyHeaders = Headers | HeadersInit | Record<string, string> | Array<[string, string]> | OutgoingHttpHeaders | undefined;
4
4
  export declare function mergeHeaders(...headers: Array<AnyHeaders>): Headers;
5
- export {};
@@ -43,19 +43,19 @@ function createRequestHandler({
43
43
  };
44
44
  }
45
45
  function getRequestHeaders(opts) {
46
- let headers = mergeHeaders(
47
- {
48
- "Content-Type": "text/html; charset=UTF-8"
49
- },
50
- ...opts.router.state.matches.map((match) => {
51
- return match.headers;
52
- })
46
+ const matchHeaders = opts.router.state.matches.map(
47
+ (match) => match.headers
53
48
  );
54
49
  const { redirect } = opts.router.state;
55
50
  if (redirect) {
56
- headers = mergeHeaders(headers, redirect.headers);
51
+ matchHeaders.push(redirect.headers);
57
52
  }
58
- return headers;
53
+ return mergeHeaders(
54
+ {
55
+ "Content-Type": "text/html; charset=UTF-8"
56
+ },
57
+ ...matchHeaders
58
+ );
59
59
  }
60
60
  export {
61
61
  createRequestHandler
@@ -1 +1 @@
1
- {"version":3,"file":"createRequestHandler.js","sources":["../../../src/ssr/createRequestHandler.ts"],"sourcesContent":["import { createMemoryHistory } from '@tanstack/history'\nimport { mergeHeaders } from './headers'\nimport {\n attachRouterServerSsrUtils,\n getNormalizedURL,\n getOrigin,\n} from './ssr-server'\nimport type { HandlerCallback } from './handlerCallback'\nimport type { AnyRouter } from '../router'\nimport type { Manifest } from '../manifest'\n\nexport type RequestHandler<TRouter extends AnyRouter> = (\n cb: HandlerCallback<TRouter>,\n) => Promise<Response>\n\nexport function createRequestHandler<TRouter extends AnyRouter>({\n createRouter,\n request,\n getRouterManifest,\n}: {\n createRouter: () => TRouter\n request: Request\n getRouterManifest?: () => Manifest | Promise<Manifest>\n}): RequestHandler<TRouter> {\n return async (cb) => {\n const router = createRouter()\n // Track whether the callback will handle cleanup\n let cbWillCleanup = false\n\n try {\n attachRouterServerSsrUtils({\n router,\n manifest: await getRouterManifest?.(),\n })\n\n // normalizing and sanitizing the pathname here for server, so we always deal with the same format during SSR.\n const url = getNormalizedURL(request.url, 'http://localhost')\n const origin = getOrigin(request)\n const href = url.href.replace(url.origin, '')\n\n // Create a history for the router\n const history = createMemoryHistory({\n initialEntries: [href],\n })\n\n // Update the router with the history and context\n router.update({\n history,\n origin: router.options.origin ?? origin,\n })\n\n await router.load()\n\n await router.serverSsr?.dehydrate()\n\n const responseHeaders = getRequestHeaders({\n router,\n })\n\n // Mark that the callback will handle cleanup\n cbWillCleanup = true\n return cb({\n request,\n router,\n responseHeaders,\n } as any)\n } finally {\n if (!cbWillCleanup) {\n // Clean up router SSR state if the callback won't handle it\n // (e.g., if an error occurred before the callback was invoked).\n // When the callback runs, it handles cleanup (either via transformStreamWithRouter\n // for streaming, or directly in renderRouterToString for non-streaming).\n router.serverSsr?.cleanup()\n }\n }\n }\n}\n\nfunction getRequestHeaders(opts: { router: AnyRouter }): Headers {\n let headers = mergeHeaders(\n {\n 'Content-Type': 'text/html; charset=UTF-8',\n },\n ...opts.router.state.matches.map((match) => {\n return match.headers\n }),\n )\n\n // Handle Redirects\n const { redirect } = opts.router.state\n\n if (redirect) {\n headers = mergeHeaders(headers, redirect.headers)\n }\n\n return headers\n}\n"],"names":[],"mappings":";;;AAeO,SAAS,qBAAgD;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AACF,GAI4B;AAC1B,SAAO,OAAO,OAAO;AACnB,UAAM,SAAS,aAAA;AAEf,QAAI,gBAAgB;AAEpB,QAAI;AACF,iCAA2B;AAAA,QACzB;AAAA,QACA,UAAU,MAAM,oBAAA;AAAA,MAAoB,CACrC;AAGD,YAAM,MAAM,iBAAiB,QAAQ,KAAK,kBAAkB;AAC5D,YAAM,SAAS,UAAU,OAAO;AAChC,YAAM,OAAO,IAAI,KAAK,QAAQ,IAAI,QAAQ,EAAE;AAG5C,YAAM,UAAU,oBAAoB;AAAA,QAClC,gBAAgB,CAAC,IAAI;AAAA,MAAA,CACtB;AAGD,aAAO,OAAO;AAAA,QACZ;AAAA,QACA,QAAQ,OAAO,QAAQ,UAAU;AAAA,MAAA,CAClC;AAED,YAAM,OAAO,KAAA;AAEb,YAAM,OAAO,WAAW,UAAA;AAExB,YAAM,kBAAkB,kBAAkB;AAAA,QACxC;AAAA,MAAA,CACD;AAGD,sBAAgB;AAChB,aAAO,GAAG;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACM;AAAA,IACV,UAAA;AACE,UAAI,CAAC,eAAe;AAKlB,eAAO,WAAW,QAAA;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,MAAsC;AAC/D,MAAI,UAAU;AAAA,IACZ;AAAA,MACE,gBAAgB;AAAA,IAAA;AAAA,IAElB,GAAG,KAAK,OAAO,MAAM,QAAQ,IAAI,CAAC,UAAU;AAC1C,aAAO,MAAM;AAAA,IACf,CAAC;AAAA,EAAA;AAIH,QAAM,EAAE,SAAA,IAAa,KAAK,OAAO;AAEjC,MAAI,UAAU;AACZ,cAAU,aAAa,SAAS,SAAS,OAAO;AAAA,EAClD;AAEA,SAAO;AACT;"}
1
+ {"version":3,"file":"createRequestHandler.js","sources":["../../../src/ssr/createRequestHandler.ts"],"sourcesContent":["import { createMemoryHistory } from '@tanstack/history'\nimport { mergeHeaders } from './headers'\nimport {\n attachRouterServerSsrUtils,\n getNormalizedURL,\n getOrigin,\n} from './ssr-server'\nimport type { HandlerCallback } from './handlerCallback'\nimport type { AnyHeaders } from './headers'\nimport type { AnyRouter } from '../router'\nimport type { Manifest } from '../manifest'\n\nexport type RequestHandler<TRouter extends AnyRouter> = (\n cb: HandlerCallback<TRouter>,\n) => Promise<Response>\n\nexport function createRequestHandler<TRouter extends AnyRouter>({\n createRouter,\n request,\n getRouterManifest,\n}: {\n createRouter: () => TRouter\n request: Request\n getRouterManifest?: () => Manifest | Promise<Manifest>\n}): RequestHandler<TRouter> {\n return async (cb) => {\n const router = createRouter()\n // Track whether the callback will handle cleanup\n let cbWillCleanup = false\n\n try {\n attachRouterServerSsrUtils({\n router,\n manifest: await getRouterManifest?.(),\n })\n\n // normalizing and sanitizing the pathname here for server, so we always deal with the same format during SSR.\n const url = getNormalizedURL(request.url, 'http://localhost')\n const origin = getOrigin(request)\n const href = url.href.replace(url.origin, '')\n\n // Create a history for the router\n const history = createMemoryHistory({\n initialEntries: [href],\n })\n\n // Update the router with the history and context\n router.update({\n history,\n origin: router.options.origin ?? origin,\n })\n\n await router.load()\n\n await router.serverSsr?.dehydrate()\n\n const responseHeaders = getRequestHeaders({\n router,\n })\n\n // Mark that the callback will handle cleanup\n cbWillCleanup = true\n return cb({\n request,\n router,\n responseHeaders,\n } as any)\n } finally {\n if (!cbWillCleanup) {\n // Clean up router SSR state if the callback won't handle it\n // (e.g., if an error occurred before the callback was invoked).\n // When the callback runs, it handles cleanup (either via transformStreamWithRouter\n // for streaming, or directly in renderRouterToString for non-streaming).\n router.serverSsr?.cleanup()\n }\n }\n }\n}\n\nfunction getRequestHeaders(opts: { router: AnyRouter }): Headers {\n const matchHeaders = opts.router.state.matches.map<AnyHeaders>(\n (match) => match.headers,\n )\n\n // Handle Redirects\n const { redirect } = opts.router.state\n if (redirect) {\n matchHeaders.push(redirect.headers)\n }\n\n return mergeHeaders(\n {\n 'Content-Type': 'text/html; charset=UTF-8',\n },\n ...matchHeaders,\n )\n}\n"],"names":[],"mappings":";;;AAgBO,SAAS,qBAAgD;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AACF,GAI4B;AAC1B,SAAO,OAAO,OAAO;AACnB,UAAM,SAAS,aAAA;AAEf,QAAI,gBAAgB;AAEpB,QAAI;AACF,iCAA2B;AAAA,QACzB;AAAA,QACA,UAAU,MAAM,oBAAA;AAAA,MAAoB,CACrC;AAGD,YAAM,MAAM,iBAAiB,QAAQ,KAAK,kBAAkB;AAC5D,YAAM,SAAS,UAAU,OAAO;AAChC,YAAM,OAAO,IAAI,KAAK,QAAQ,IAAI,QAAQ,EAAE;AAG5C,YAAM,UAAU,oBAAoB;AAAA,QAClC,gBAAgB,CAAC,IAAI;AAAA,MAAA,CACtB;AAGD,aAAO,OAAO;AAAA,QACZ;AAAA,QACA,QAAQ,OAAO,QAAQ,UAAU;AAAA,MAAA,CAClC;AAED,YAAM,OAAO,KAAA;AAEb,YAAM,OAAO,WAAW,UAAA;AAExB,YAAM,kBAAkB,kBAAkB;AAAA,QACxC;AAAA,MAAA,CACD;AAGD,sBAAgB;AAChB,aAAO,GAAG;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACM;AAAA,IACV,UAAA;AACE,UAAI,CAAC,eAAe;AAKlB,eAAO,WAAW,QAAA;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,MAAsC;AAC/D,QAAM,eAAe,KAAK,OAAO,MAAM,QAAQ;AAAA,IAC7C,CAAC,UAAU,MAAM;AAAA,EAAA;AAInB,QAAM,EAAE,SAAA,IAAa,KAAK,OAAO;AACjC,MAAI,UAAU;AACZ,iBAAa,KAAK,SAAS,OAAO;AAAA,EACpC;AAEA,SAAO;AAAA,IACL;AAAA,MACE,gBAAgB;AAAA,IAAA;AAAA,IAElB,GAAG;AAAA,EAAA;AAEP;"}
@@ -1,5 +1,4 @@
1
1
  import { OutgoingHttpHeaders } from 'node:http2';
2
2
  export declare function headersInitToObject(headers: HeadersInit): Record<keyof OutgoingHttpHeaders, string>;
3
- type AnyHeaders = Headers | HeadersInit | Record<string, string> | Array<[string, string]> | OutgoingHttpHeaders | undefined;
3
+ export type AnyHeaders = Headers | HeadersInit | Record<string, string> | Array<[string, string]> | OutgoingHttpHeaders | undefined;
4
4
  export declare function mergeHeaders(...headers: Array<AnyHeaders>): Headers;
5
- export {};
@@ -9,18 +9,19 @@ function headersInitToObject(headers) {
9
9
  }
10
10
  function toHeadersInstance(init) {
11
11
  if (init instanceof Headers) {
12
- return new Headers(init);
12
+ return init;
13
13
  } else if (Array.isArray(init)) {
14
14
  return new Headers(init);
15
15
  } else if (typeof init === "object") {
16
16
  return new Headers(init);
17
17
  } else {
18
- return new Headers();
18
+ return null;
19
19
  }
20
20
  }
21
21
  function mergeHeaders(...headers) {
22
22
  return headers.reduce((acc, header) => {
23
23
  const headersInstance = toHeadersInstance(header);
24
+ if (!headersInstance) return acc;
24
25
  for (const [key, value] of headersInstance.entries()) {
25
26
  if (key === "set-cookie") {
26
27
  const splitCookies = splitSetCookieString(value);
@@ -1 +1 @@
1
- {"version":3,"file":"headers.js","sources":["../../../src/ssr/headers.ts"],"sourcesContent":["import { splitSetCookieString } from 'cookie-es'\nimport type { OutgoingHttpHeaders } from 'node:http2'\n\n// A utility function to turn HeadersInit into an object\nexport function headersInitToObject(\n headers: HeadersInit,\n): Record<keyof OutgoingHttpHeaders, string> {\n const obj: Record<keyof OutgoingHttpHeaders, string> = {}\n const headersInstance = new Headers(headers)\n for (const [key, value] of headersInstance.entries()) {\n obj[key] = value\n }\n return obj\n}\n\ntype AnyHeaders =\n | Headers\n | HeadersInit\n | Record<string, string>\n | Array<[string, string]>\n | OutgoingHttpHeaders\n | undefined\n\n// Helper function to convert various HeaderInit types to a Headers instance\nfunction toHeadersInstance(init: AnyHeaders) {\n if (init instanceof Headers) {\n return new Headers(init)\n } else if (Array.isArray(init)) {\n return new Headers(init)\n } else if (typeof init === 'object') {\n return new Headers(init as HeadersInit)\n } else {\n return new Headers()\n }\n}\n\n// Function to merge headers with proper overrides\nexport function mergeHeaders(...headers: Array<AnyHeaders>) {\n return headers.reduce((acc: Headers, header) => {\n const headersInstance = toHeadersInstance(header)\n for (const [key, value] of headersInstance.entries()) {\n if (key === 'set-cookie') {\n const splitCookies = splitSetCookieString(value)\n splitCookies.forEach((cookie) => acc.append('set-cookie', cookie))\n } else {\n acc.set(key, value)\n }\n }\n return acc\n }, new Headers())\n}\n"],"names":[],"mappings":";AAIO,SAAS,oBACd,SAC2C;AAC3C,QAAM,MAAiD,CAAA;AACvD,QAAM,kBAAkB,IAAI,QAAQ,OAAO;AAC3C,aAAW,CAAC,KAAK,KAAK,KAAK,gBAAgB,WAAW;AACpD,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAWA,SAAS,kBAAkB,MAAkB;AAC3C,MAAI,gBAAgB,SAAS;AAC3B,WAAO,IAAI,QAAQ,IAAI;AAAA,EACzB,WAAW,MAAM,QAAQ,IAAI,GAAG;AAC9B,WAAO,IAAI,QAAQ,IAAI;AAAA,EACzB,WAAW,OAAO,SAAS,UAAU;AACnC,WAAO,IAAI,QAAQ,IAAmB;AAAA,EACxC,OAAO;AACL,WAAO,IAAI,QAAA;AAAA,EACb;AACF;AAGO,SAAS,gBAAgB,SAA4B;AAC1D,SAAO,QAAQ,OAAO,CAAC,KAAc,WAAW;AAC9C,UAAM,kBAAkB,kBAAkB,MAAM;AAChD,eAAW,CAAC,KAAK,KAAK,KAAK,gBAAgB,WAAW;AACpD,UAAI,QAAQ,cAAc;AACxB,cAAM,eAAe,qBAAqB,KAAK;AAC/C,qBAAa,QAAQ,CAAC,WAAW,IAAI,OAAO,cAAc,MAAM,CAAC;AAAA,MACnE,OAAO;AACL,YAAI,IAAI,KAAK,KAAK;AAAA,MACpB;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,IAAI,SAAS;AAClB;"}
1
+ {"version":3,"file":"headers.js","sources":["../../../src/ssr/headers.ts"],"sourcesContent":["import { splitSetCookieString } from 'cookie-es'\nimport type { OutgoingHttpHeaders } from 'node:http2'\n\n// A utility function to turn HeadersInit into an object\nexport function headersInitToObject(\n headers: HeadersInit,\n): Record<keyof OutgoingHttpHeaders, string> {\n const obj: Record<keyof OutgoingHttpHeaders, string> = {}\n const headersInstance = new Headers(headers)\n for (const [key, value] of headersInstance.entries()) {\n obj[key] = value\n }\n return obj\n}\n\nexport type AnyHeaders =\n | Headers\n | HeadersInit\n | Record<string, string>\n | Array<[string, string]>\n | OutgoingHttpHeaders\n | undefined\n\n// Helper function to convert various HeaderInit types to a Headers instance\nfunction toHeadersInstance(init: AnyHeaders) {\n if (init instanceof Headers) {\n return init\n } else if (Array.isArray(init)) {\n return new Headers(init)\n } else if (typeof init === 'object') {\n return new Headers(init as HeadersInit)\n } else {\n return null\n }\n}\n\n// Function to merge headers with proper overrides\nexport function mergeHeaders(...headers: Array<AnyHeaders>) {\n return headers.reduce((acc: Headers, header) => {\n const headersInstance = toHeadersInstance(header)\n if (!headersInstance) return acc\n for (const [key, value] of headersInstance.entries()) {\n if (key === 'set-cookie') {\n const splitCookies = splitSetCookieString(value)\n splitCookies.forEach((cookie) => acc.append('set-cookie', cookie))\n } else {\n acc.set(key, value)\n }\n }\n return acc\n }, new Headers())\n}\n"],"names":[],"mappings":";AAIO,SAAS,oBACd,SAC2C;AAC3C,QAAM,MAAiD,CAAA;AACvD,QAAM,kBAAkB,IAAI,QAAQ,OAAO;AAC3C,aAAW,CAAC,KAAK,KAAK,KAAK,gBAAgB,WAAW;AACpD,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAWA,SAAS,kBAAkB,MAAkB;AAC3C,MAAI,gBAAgB,SAAS;AAC3B,WAAO;AAAA,EACT,WAAW,MAAM,QAAQ,IAAI,GAAG;AAC9B,WAAO,IAAI,QAAQ,IAAI;AAAA,EACzB,WAAW,OAAO,SAAS,UAAU;AACnC,WAAO,IAAI,QAAQ,IAAmB;AAAA,EACxC,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAGO,SAAS,gBAAgB,SAA4B;AAC1D,SAAO,QAAQ,OAAO,CAAC,KAAc,WAAW;AAC9C,UAAM,kBAAkB,kBAAkB,MAAM;AAChD,QAAI,CAAC,gBAAiB,QAAO;AAC7B,eAAW,CAAC,KAAK,KAAK,KAAK,gBAAgB,WAAW;AACpD,UAAI,QAAQ,cAAc;AACxB,cAAM,eAAe,qBAAqB,KAAK;AAC/C,qBAAa,QAAQ,CAAC,WAAW,IAAI,OAAO,cAAc,MAAM,CAAC;AAAA,MACnE,OAAO;AACL,YAAI,IAAI,KAAK,KAAK;AAAA,MACpB;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,IAAI,SAAS;AAClB;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/router-core",
3
- "version": "1.157.11",
3
+ "version": "1.157.12",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -6,6 +6,7 @@ import {
6
6
  getOrigin,
7
7
  } from './ssr-server'
8
8
  import type { HandlerCallback } from './handlerCallback'
9
+ import type { AnyHeaders } from './headers'
9
10
  import type { AnyRouter } from '../router'
10
11
  import type { Manifest } from '../manifest'
11
12
 
@@ -77,21 +78,20 @@ export function createRequestHandler<TRouter extends AnyRouter>({
77
78
  }
78
79
 
79
80
  function getRequestHeaders(opts: { router: AnyRouter }): Headers {
80
- let headers = mergeHeaders(
81
- {
82
- 'Content-Type': 'text/html; charset=UTF-8',
83
- },
84
- ...opts.router.state.matches.map((match) => {
85
- return match.headers
86
- }),
81
+ const matchHeaders = opts.router.state.matches.map<AnyHeaders>(
82
+ (match) => match.headers,
87
83
  )
88
84
 
89
85
  // Handle Redirects
90
86
  const { redirect } = opts.router.state
91
-
92
87
  if (redirect) {
93
- headers = mergeHeaders(headers, redirect.headers)
88
+ matchHeaders.push(redirect.headers)
94
89
  }
95
90
 
96
- return headers
91
+ return mergeHeaders(
92
+ {
93
+ 'Content-Type': 'text/html; charset=UTF-8',
94
+ },
95
+ ...matchHeaders,
96
+ )
97
97
  }
@@ -13,7 +13,7 @@ export function headersInitToObject(
13
13
  return obj
14
14
  }
15
15
 
16
- type AnyHeaders =
16
+ export type AnyHeaders =
17
17
  | Headers
18
18
  | HeadersInit
19
19
  | Record<string, string>
@@ -24,13 +24,13 @@ type AnyHeaders =
24
24
  // Helper function to convert various HeaderInit types to a Headers instance
25
25
  function toHeadersInstance(init: AnyHeaders) {
26
26
  if (init instanceof Headers) {
27
- return new Headers(init)
27
+ return init
28
28
  } else if (Array.isArray(init)) {
29
29
  return new Headers(init)
30
30
  } else if (typeof init === 'object') {
31
31
  return new Headers(init as HeadersInit)
32
32
  } else {
33
- return new Headers()
33
+ return null
34
34
  }
35
35
  }
36
36
 
@@ -38,6 +38,7 @@ function toHeadersInstance(init: AnyHeaders) {
38
38
  export function mergeHeaders(...headers: Array<AnyHeaders>) {
39
39
  return headers.reduce((acc: Headers, header) => {
40
40
  const headersInstance = toHeadersInstance(header)
41
+ if (!headersInstance) return acc
41
42
  for (const [key, value] of headersInstance.entries()) {
42
43
  if (key === 'set-cookie') {
43
44
  const splitCookies = splitSetCookieString(value)