UNPKG

@tanstack/react-router

Version:

Modern and scalable routing for React applications

1 lines • 6.41 kB
{"version":3,"file":"renderRouterToStream.cjs","names":["ReactDOMServer","transformReadableStreamWithRouter","waitForRequest","createSsrStreamResponse","getSsrStatus","PassThrough","Readable"],"sources":["../../../src/ssr/renderRouterToStream.tsx"],"sourcesContent":["import { PassThrough, Readable } from 'node:stream'\nimport ReactDOMServer from 'react-dom/server'\nimport { isbot } from 'isbot'\nimport {\n createSsrStreamResponse,\n getSsrStatus,\n transformReadableStreamWithRouter,\n waitForRequest,\n} from '@tanstack/router-core/ssr/server'\nimport type { AnyRouter } from '@tanstack/router-core'\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 const signal = request.signal\n if (signal.aborted) {\n router.serverSsr?.cleanup()\n throw signal.reason\n }\n let rendererTeardown = false\n const bot = isbot(request.headers.get('User-Agent'))\n const onError =\n (\n renderer: string,\n ): ReactDOMServer.RenderToPipeableStreamOptions['onError'] =>\n (error, info) => {\n if (!rendererTeardown && !signal.aborted) {\n console.error(`Error in ${renderer}:`, error, info)\n }\n }\n\n try {\n if (typeof ReactDOMServer.renderToReadableStream === 'function') {\n const stream = await ReactDOMServer.renderToReadableStream(children, {\n signal,\n nonce: router.options.ssr?.nonce,\n progressiveChunkSize: Number.POSITIVE_INFINITY,\n onError: onError('renderToReadableStream'),\n })\n // The transform owns the reader and bounds bot readiness by its lifetime.\n const rendererAbort = bot ? new AbortController() : undefined\n const responseStream = transformReadableStreamWithRouter(router, stream, {\n rendererSafePoint: 'script-close',\n signal,\n onAbort: (reason) => {\n rendererTeardown = true\n rendererAbort?.abort(reason)\n },\n })\n if (rendererAbort) {\n await waitForRequest(stream.allReady, rendererAbort.signal)\n }\n return createSsrStreamResponse(\n router,\n new Response(responseStream, {\n status: getSsrStatus(router),\n headers: responseHeaders,\n }),\n )\n }\n\n if (typeof ReactDOMServer.renderToPipeableStream === 'function') {\n const reactAppPassthrough = new PassThrough()\n let pipeable:\n | ReturnType<typeof ReactDOMServer.renderToPipeableStream>\n | undefined\n let resolveReady!: () => void\n const ready = new Promise<void>((resolve) => {\n resolveReady = resolve\n })\n const rendererAbort = new AbortController()\n const abortPipeable = (reason?: unknown) => {\n if (rendererTeardown) {\n return\n }\n rendererTeardown = true\n rendererAbort.abort(reason)\n try {\n pipeable?.abort(reason)\n } catch {\n // ignore — React may throw if already aborted/finished\n }\n }\n try {\n pipeable = ReactDOMServer.renderToPipeableStream(children, {\n nonce: router.options.ssr?.nonce,\n progressiveChunkSize: Number.POSITIVE_INFINITY,\n ...(bot\n ? { onAllReady: resolveReady }\n : { onShellReady: resolveReady }),\n onError: onError('renderToPipeableStream'),\n onShellError: (error) => rendererAbort.abort(error),\n })\n const responseStream = transformReadableStreamWithRouter(\n router,\n Readable.toWeb(reactAppPassthrough),\n {\n rendererSafePoint: 'script-close',\n signal,\n onAbort: abortPipeable,\n },\n )\n\n await waitForRequest(ready, rendererAbort.signal)\n pipeable.pipe(reactAppPassthrough)\n\n return createSsrStreamResponse(\n router,\n new Response(responseStream, {\n status: getSsrStatus(router),\n headers: responseHeaders,\n }),\n )\n } catch (error) {\n abortPipeable(error)\n throw error\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 } catch (error) {\n router.serverSsr?.cleanup()\n throw error\n }\n}\n"],"mappings":";;;;;;;AAYA,IAAa,uBAAuB,OAAO,EACzC,SACA,QACA,iBACA,eAMI;CACJ,MAAM,SAAS,QAAQ;CACvB,IAAI,OAAO,SAAS;EAClB,OAAO,WAAW,QAAQ;EAC1B,MAAM,OAAO;CACf;CACA,IAAI,mBAAmB;CACvB,MAAM,OAAA,GAAM,MAAA,MAAA,CAAM,QAAQ,QAAQ,IAAI,YAAY,CAAC;CACnD,MAAM,WAEF,cAED,OAAO,SAAS;EACf,IAAI,CAAC,oBAAoB,CAAC,OAAO,SAC/B,QAAQ,MAAM,YAAY,SAAS,IAAI,OAAO,IAAI;CAEtD;CAEF,IAAI;EACF,IAAI,OAAOA,iBAAAA,QAAe,2BAA2B,YAAY;GAC/D,MAAM,SAAS,MAAMA,iBAAAA,QAAe,uBAAuB,UAAU;IACnE;IACA,OAAO,OAAO,QAAQ,KAAK;IAC3B,sBAAsB,OAAO;IAC7B,SAAS,QAAQ,wBAAwB;GAC3C,CAAC;GAED,MAAM,gBAAgB,MAAM,IAAI,gBAAgB,IAAI,KAAA;GACpD,MAAM,kBAAA,GAAiBC,iCAAAA,kCAAAA,CAAkC,QAAQ,QAAQ;IACvE,mBAAmB;IACnB;IACA,UAAU,WAAW;KACnB,mBAAmB;KACnB,eAAe,MAAM,MAAM;IAC7B;GACF,CAAC;GACD,IAAI,eACF,OAAA,GAAMC,iCAAAA,eAAAA,CAAe,OAAO,UAAU,cAAc,MAAM;GAE5D,QAAA,GAAOC,iCAAAA,wBAAAA,CACL,QACA,IAAI,SAAS,gBAAgB;IAC3B,SAAA,GAAQC,iCAAAA,aAAAA,CAAa,MAAM;IAC3B,SAAS;GACX,CAAC,CACH;EACF;EAEA,IAAI,OAAOJ,iBAAAA,QAAe,2BAA2B,YAAY;GAC/D,MAAM,sBAAsB,IAAIK,YAAAA,YAAY;GAC5C,IAAI;GAGJ,IAAI;GACJ,MAAM,QAAQ,IAAI,SAAe,YAAY;IAC3C,eAAe;GACjB,CAAC;GACD,MAAM,gBAAgB,IAAI,gBAAgB;GAC1C,MAAM,iBAAiB,WAAqB;IAC1C,IAAI,kBACF;IAEF,mBAAmB;IACnB,cAAc,MAAM,MAAM;IAC1B,IAAI;KACF,UAAU,MAAM,MAAM;IACxB,QAAQ,CAER;GACF;GACA,IAAI;IACF,WAAWL,iBAAAA,QAAe,uBAAuB,UAAU;KACzD,OAAO,OAAO,QAAQ,KAAK;KAC3B,sBAAsB,OAAO;KAC7B,GAAI,MACA,EAAE,YAAY,aAAa,IAC3B,EAAE,cAAc,aAAa;KACjC,SAAS,QAAQ,wBAAwB;KACzC,eAAe,UAAU,cAAc,MAAM,KAAK;IACpD,CAAC;IACD,MAAM,kBAAA,GAAiBC,iCAAAA,kCAAAA,CACrB,QACAK,YAAAA,SAAS,MAAM,mBAAmB,GAClC;KACE,mBAAmB;KACnB;KACA,SAAS;IACX,CACF;IAEA,OAAA,GAAMJ,iCAAAA,eAAAA,CAAe,OAAO,cAAc,MAAM;IAChD,SAAS,KAAK,mBAAmB;IAEjC,QAAA,GAAOC,iCAAAA,wBAAAA,CACL,QACA,IAAI,SAAS,gBAAgB;KAC3B,SAAA,GAAQC,iCAAAA,aAAAA,CAAa,MAAM;KAC3B,SAAS;IACX,CAAC,CACH;GACF,SAAS,OAAO;IACd,cAAc,KAAK;IACnB,MAAM;GACR;EACF;EAEA,MAAM,IAAI,MACR,qJACF;CACF,SAAS,OAAO;EACd,OAAO,WAAW,QAAQ;EAC1B,MAAM;CACR;AACF"}