UNPKG

@tanstack/router-core

Version:

Modern and scalable routing for React applications

1 lines 5.27 kB
{"version":3,"file":"createRequestHandler.cjs","names":[],"sources":["../../../src/ssr/createRequestHandler.ts"],"sourcesContent":["import { createServerHistory } from '@tanstack/history'\nimport { _getRenderedMatches } from '../load-client'\nimport { waitForReason as waitForRequest } from '../await-signal'\nimport { mergeHeaders } from './headers'\nimport {\n attachRouterServerSsrUtils,\n getNormalizedURL,\n getOrigin,\n} from './ssr-server'\nimport {\n bindSsrResponseToRequest,\n disposeSsrResponse,\n isSsrResponse,\n} from './handlerCallback'\nimport type { HandlerCallback } from './handlerCallback'\nimport type { AnyHeaders } from './headers'\nimport type { AnyRouter } from '../router'\nimport type { ServerManifest } from '../manifest'\n\nexport type RequestHandler<TRouter extends AnyRouter> = (\n cb: HandlerCallback<TRouter>,\n) => Promise<Response>\n\nexport { waitForRequest }\n\nfunction createLateResponseDisposer(signal: AbortSignal) {\n return (result: unknown) => {\n if (result instanceof Response || isSsrResponse(result)) {\n disposeSsrResponse(result, signal.reason)\n }\n }\n}\n\nexport function createRequestHandler<TRouter extends AnyRouter>({\n createRouter,\n request,\n getRouterManifest,\n}: {\n createRouter: () => TRouter\n request: Request\n getRouterManifest?: () => ServerManifest | Promise<ServerManifest>\n}): RequestHandler<TRouter> {\n return async (cb) => {\n const signal = request.signal\n signal.throwIfAborted()\n const manifest = getRouterManifest\n ? await waitForRequest(getRouterManifest(), signal)\n : undefined\n signal.throwIfAborted()\n const router = createRouter()\n let responseOwnsCleanup = false\n\n try {\n attachRouterServerSsrUtils({\n router,\n manifest,\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 = createServerHistory(href)\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 _signal: signal,\n })\n signal.throwIfAborted()\n\n const result = router._serverResult\n if (result?.type === 'redirect') {\n return result.redirect\n }\n\n await router.serverSsr?.dehydrate({ signal })\n signal.throwIfAborted()\n\n const responseHeaders = getRequestHeaders({\n router,\n })\n\n signal.throwIfAborted()\n const disposeLate = createLateResponseDisposer(signal)\n const response = await waitForRequest(\n cb({\n request,\n router,\n responseHeaders,\n }),\n signal,\n disposeLate,\n disposeLate,\n )\n const ssrResponse = bindSsrResponseToRequest(router, response, signal)\n signal.throwIfAborted()\n responseOwnsCleanup = ssrResponse.serverSsrCleanup === 'stream'\n return ssrResponse.response\n } finally {\n if (!responseOwnsCleanup) {\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 // Transformed streaming response bodies clean up when consumed/cancelled.\n router.serverSsr?.cleanup()\n }\n }\n }\n}\n\nfunction getRequestHeaders(opts: { router: AnyRouter }): Headers {\n const matchHeaders: Array<AnyHeaders> = []\n for (const match of _getRenderedMatches(opts.router.stores.matches.get())) {\n matchHeaders.push(match.headers)\n }\n\n return mergeHeaders(\n {\n 'Content-Type': 'text/html; charset=UTF-8',\n },\n ...matchHeaders,\n )\n}\n"],"mappings":";;;;;;;AAyBA,SAAS,2BAA2B,QAAqB;CACvD,QAAQ,WAAoB;EAC1B,IAAI,kBAAkB,YAAY,wBAAA,cAAc,MAAM,GACpD,wBAAA,mBAAmB,QAAQ,OAAO,MAAM;CAE5C;AACF;AAEA,SAAgB,qBAAgD,EAC9D,cACA,SACA,qBAK0B;CAC1B,OAAO,OAAO,OAAO;EACnB,MAAM,SAAS,QAAQ;EACvB,OAAO,eAAe;EACtB,MAAM,WAAW,oBACb,MAAM,qBAAA,cAAe,kBAAkB,GAAG,MAAM,IAChD,KAAA;EACJ,OAAO,eAAe;EACtB,MAAM,SAAS,aAAa;EAC5B,IAAI,sBAAsB;EAE1B,IAAI;GACF,mBAAA,2BAA2B;IACzB;IACA;GACF,CAAC;GAGD,MAAM,EAAE,QAAQ,mBAAA,iBAAiB,QAAQ,KAAK,kBAAkB;GAChE,MAAM,SAAS,mBAAA,UAAU,OAAO;GAIhC,MAAM,WAAA,GAAA,kBAAA,qBAHO,IAAI,KAAK,QAAQ,IAAI,QAAQ,EAGN,CAAI;GAGxC,OAAO,OAAO;IACZ;IACA,QAAQ,OAAO,QAAQ,UAAU;GACnC,CAAC;GAED,MAAM,OAAO,KAAK,EAChB,SAAS,OACX,CAAC;GACD,OAAO,eAAe;GAEtB,MAAM,SAAS,OAAO;GACtB,IAAI,QAAQ,SAAS,YACnB,OAAO,OAAO;GAGhB,MAAM,OAAO,WAAW,UAAU,EAAE,OAAO,CAAC;GAC5C,OAAO,eAAe;GAEtB,MAAM,kBAAkB,kBAAkB,EACxC,OACF,CAAC;GAED,OAAO,eAAe;GACtB,MAAM,cAAc,2BAA2B,MAAM;GAWrD,MAAM,cAAc,wBAAA,yBAAyB,QAAQ,MAV9B,qBAAA,cACrB,GAAG;IACD;IACA;IACA;GACF,CAAC,GACD,QACA,aACA,WACF,GAC+D,MAAM;GACrE,OAAO,eAAe;GACtB,sBAAsB,YAAY,qBAAqB;GACvD,OAAO,YAAY;EACrB,UAAU;GACR,IAAI,CAAC,qBAIH,OAAO,WAAW,QAAQ;EAE9B;CACF;AACF;AAEA,SAAS,kBAAkB,MAAsC;CAC/D,MAAM,eAAkC,CAAC;CACzC,KAAK,MAAM,SAAS,oBAAA,oBAAoB,KAAK,OAAO,OAAO,QAAQ,IAAI,CAAC,GACtE,aAAa,KAAK,MAAM,OAAO;CAGjC,OAAO,gBAAA,aACL,EACE,gBAAgB,2BAClB,GACA,GAAG,YACL;AACF"}