@tanstack/react-router
Version:
Modern and scalable routing for React applications
1 lines • 4.12 kB
Source Map (JSON)
{"version":3,"file":"renderRouterToStream.cjs","names":[],"sources":["../../../src/ssr/renderRouterToStream.tsx"],"sourcesContent":["import { PassThrough } from 'node:stream'\nimport ReactDOMServer from 'react-dom/server'\nimport { isbot } from 'isbot'\nimport {\n transformPipeableStreamWithRouter,\n transformReadableStreamWithRouter,\n} from '@tanstack/router-core/ssr/server'\nimport type { AnyRouter } from '@tanstack/router-core'\nimport type { ReadableStream } from 'node:stream/web'\nimport type { ReactNode } from 'react'\n\nexport const renderRouterToStream = async ({\n request,\n router,\n responseHeaders,\n children,\n}: {\n request: Request\n router: AnyRouter\n responseHeaders: Headers\n children: ReactNode\n}) => {\n if (typeof ReactDOMServer.renderToReadableStream === 'function') {\n const stream = await ReactDOMServer.renderToReadableStream(children, {\n signal: request.signal,\n nonce: router.options.ssr?.nonce,\n progressiveChunkSize: Number.POSITIVE_INFINITY,\n })\n\n if (isbot(request.headers.get('User-Agent'))) {\n await stream.allReady\n }\n\n const responseStream = transformReadableStreamWithRouter(\n router,\n stream as unknown as ReadableStream,\n )\n return new Response(responseStream as any, {\n status: router.stores.statusCode.state,\n headers: responseHeaders,\n })\n }\n\n if (typeof ReactDOMServer.renderToPipeableStream === 'function') {\n const reactAppPassthrough = new PassThrough()\n\n try {\n const pipeable = ReactDOMServer.renderToPipeableStream(children, {\n nonce: router.options.ssr?.nonce,\n progressiveChunkSize: Number.POSITIVE_INFINITY,\n ...(isbot(request.headers.get('User-Agent'))\n ? {\n onAllReady() {\n pipeable.pipe(reactAppPassthrough)\n },\n }\n : {\n onShellReady() {\n pipeable.pipe(reactAppPassthrough)\n },\n }),\n onError: (error, info) => {\n console.error('Error in renderToPipeableStream:', error, info)\n // Destroy the passthrough stream on error\n if (!reactAppPassthrough.destroyed) {\n reactAppPassthrough.destroy(\n error instanceof Error ? error : new Error(String(error)),\n )\n }\n },\n })\n } catch (e) {\n console.error('Error in renderToPipeableStream:', e)\n reactAppPassthrough.destroy(e instanceof Error ? e : new Error(String(e)))\n }\n\n const responseStream = transformPipeableStreamWithRouter(\n router,\n reactAppPassthrough,\n )\n return new Response(responseStream as any, {\n status: router.stores.statusCode.state,\n headers: responseHeaders,\n })\n }\n\n throw new Error(\n 'No renderToReadableStream or renderToPipeableStream found in react-dom/server. Ensure you are using a version of react-dom that supports streaming.',\n )\n}\n"],"mappings":";;;;;;;AAWA,IAAa,uBAAuB,OAAO,EACzC,SACA,QACA,iBACA,eAMI;AACJ,KAAI,OAAO,iBAAA,QAAe,2BAA2B,YAAY;EAC/D,MAAM,SAAS,MAAM,iBAAA,QAAe,uBAAuB,UAAU;GACnE,QAAQ,QAAQ;GAChB,OAAO,OAAO,QAAQ,KAAK;GAC3B,sBAAsB,OAAO;GAC9B,CAAC;AAEF,OAAA,GAAA,MAAA,OAAU,QAAQ,QAAQ,IAAI,aAAa,CAAC,CAC1C,OAAM,OAAO;EAGf,MAAM,kBAAA,GAAA,iCAAA,mCACJ,QACA,OACD;AACD,SAAO,IAAI,SAAS,gBAAuB;GACzC,QAAQ,OAAO,OAAO,WAAW;GACjC,SAAS;GACV,CAAC;;AAGJ,KAAI,OAAO,iBAAA,QAAe,2BAA2B,YAAY;EAC/D,MAAM,sBAAsB,IAAI,YAAA,aAAa;AAE7C,MAAI;GACF,MAAM,WAAW,iBAAA,QAAe,uBAAuB,UAAU;IAC/D,OAAO,OAAO,QAAQ,KAAK;IAC3B,sBAAsB,OAAO;IAC7B,IAAA,GAAA,MAAA,OAAU,QAAQ,QAAQ,IAAI,aAAa,CAAC,GACxC,EACE,aAAa;AACX,cAAS,KAAK,oBAAoB;OAErC,GACD,EACE,eAAe;AACb,cAAS,KAAK,oBAAoB;OAErC;IACL,UAAU,OAAO,SAAS;AACxB,aAAQ,MAAM,oCAAoC,OAAO,KAAK;AAE9D,SAAI,CAAC,oBAAoB,UACvB,qBAAoB,QAClB,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC,CAC1D;;IAGN,CAAC;WACK,GAAG;AACV,WAAQ,MAAM,oCAAoC,EAAE;AACpD,uBAAoB,QAAQ,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;;EAG5E,MAAM,kBAAA,GAAA,iCAAA,mCACJ,QACA,oBACD;AACD,SAAO,IAAI,SAAS,gBAAuB;GACzC,QAAQ,OAAO,OAAO,WAAW;GACjC,SAAS;GACV,CAAC;;AAGJ,OAAM,IAAI,MACR,sJACD"}