mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-03-21 18:04:39 -05:00
Switch to renderToPipeableStream API
Closes #1152 Did something weird to remove errors on /plans
This commit is contained in:
parent
6061c9672a
commit
78d55fc896
|
|
@ -30,6 +30,7 @@ module.exports = {
|
|||
"@typescript-eslint/no-unsafe-argument": 0,
|
||||
"@typescript-eslint/no-non-null-assertion": 0,
|
||||
"@typescript-eslint/no-explicit-any": 0,
|
||||
"@typescript-eslint/unbound-method": 0,
|
||||
"react/prop-types": 0,
|
||||
"@typescript-eslint/no-restricted-imports": [
|
||||
"error",
|
||||
|
|
|
|||
|
|
@ -1,32 +1,125 @@
|
|||
import { PassThrough } from "stream";
|
||||
|
||||
import type { EntryContext } from "@remix-run/node";
|
||||
import { Response } from "@remix-run/node";
|
||||
import { RemixServer } from "@remix-run/react";
|
||||
import { I18nextProvider } from "react-i18next";
|
||||
import { renderToString } from "react-dom/server";
|
||||
import isbot from "isbot";
|
||||
import { renderToPipeableStream } from "react-dom/server";
|
||||
import cron from "node-cron";
|
||||
import { updatePatreonData } from "./modules/patreon";
|
||||
import { i18Instance } from "./modules/i18n";
|
||||
import { I18nextProvider } from "react-i18next";
|
||||
|
||||
export default async function handleRequest(
|
||||
const ABORT_DELAY = 5000;
|
||||
|
||||
const handleRequest = (
|
||||
request: Request,
|
||||
responseStatusCode: number,
|
||||
responseHeaders: Headers,
|
||||
remixContext: EntryContext
|
||||
) {
|
||||
const i18n = await i18Instance(request, remixContext);
|
||||
) =>
|
||||
isbot(request.headers.get("user-agent"))
|
||||
? handleBotRequest(
|
||||
request,
|
||||
responseStatusCode,
|
||||
responseHeaders,
|
||||
remixContext
|
||||
)
|
||||
: handleBrowserRequest(
|
||||
request,
|
||||
responseStatusCode,
|
||||
responseHeaders,
|
||||
remixContext
|
||||
);
|
||||
export default handleRequest;
|
||||
|
||||
const markup = renderToString(
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<RemixServer context={remixContext} url={request.url} />
|
||||
</I18nextProvider>
|
||||
);
|
||||
const handleBotRequest = (
|
||||
request: Request,
|
||||
responseStatusCode: number,
|
||||
responseHeaders: Headers,
|
||||
remixContext: EntryContext
|
||||
) =>
|
||||
new Promise((resolve, reject) => {
|
||||
let didError = false;
|
||||
|
||||
responseHeaders.set("Content-Type", "text/html");
|
||||
void i18Instance(request, remixContext).then((i18n) => {
|
||||
const { pipe, abort } = renderToPipeableStream(
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<RemixServer context={remixContext} url={request.url} />
|
||||
</I18nextProvider>,
|
||||
{
|
||||
onAllReady: () => {
|
||||
const body = new PassThrough();
|
||||
|
||||
return new Response("<!DOCTYPE html>" + markup, {
|
||||
status: responseStatusCode,
|
||||
headers: responseHeaders,
|
||||
responseHeaders.set("Content-Type", "text/html");
|
||||
|
||||
resolve(
|
||||
new Response(body, {
|
||||
headers: responseHeaders,
|
||||
status: didError ? 500 : responseStatusCode,
|
||||
})
|
||||
);
|
||||
|
||||
pipe(body);
|
||||
},
|
||||
onShellError: (error: unknown) => {
|
||||
reject(error);
|
||||
},
|
||||
onError: (error: unknown) => {
|
||||
didError = true;
|
||||
|
||||
console.error(error);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
setTimeout(abort, ABORT_DELAY);
|
||||
});
|
||||
});
|
||||
|
||||
const handleBrowserRequest = (
|
||||
request: Request,
|
||||
responseStatusCode: number,
|
||||
responseHeaders: Headers,
|
||||
remixContext: EntryContext
|
||||
) =>
|
||||
new Promise((resolve, reject) => {
|
||||
let didError = false;
|
||||
|
||||
void i18Instance(request, remixContext).then((i18n) => {
|
||||
const { pipe, abort } = renderToPipeableStream(
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<RemixServer context={remixContext} url={request.url} />
|
||||
</I18nextProvider>,
|
||||
{
|
||||
onShellReady: () => {
|
||||
const body = new PassThrough();
|
||||
|
||||
responseHeaders.set("Content-Type", "text/html");
|
||||
|
||||
resolve(
|
||||
new Response(body, {
|
||||
headers: responseHeaders,
|
||||
status: didError ? 500 : responseStatusCode,
|
||||
})
|
||||
);
|
||||
|
||||
pipe(body);
|
||||
},
|
||||
onShellError: (error: unknown) => {
|
||||
reject(error);
|
||||
},
|
||||
onError: (error: unknown) => {
|
||||
didError = true;
|
||||
|
||||
console.error(error);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
setTimeout(abort, ABORT_DELAY);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// example from https://github.com/BenMcH/remix-rss/blob/main/app/entry.server.tsx
|
||||
declare global {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { lazy, Suspense } from "react";
|
|||
import type { LinksFunction } from "@remix-run/node";
|
||||
import styles from "~/styles/plans.css";
|
||||
import type { SendouRouteHandle } from "~/utils/remix";
|
||||
import { useIsMounted } from "~/hooks/useIsMounted";
|
||||
|
||||
export const handle: SendouRouteHandle = {
|
||||
i18n: ["weapons"],
|
||||
|
|
@ -14,9 +15,9 @@ export const links: LinksFunction = () => {
|
|||
const Planner = lazy(() => import("~/components/Planner"));
|
||||
|
||||
export default function MapPlannerPage() {
|
||||
return (
|
||||
<Suspense fallback={<div className="plans__placeholder" />}>
|
||||
<Planner />
|
||||
</Suspense>
|
||||
);
|
||||
const isMounted = useIsMounted();
|
||||
|
||||
if (!isMounted) return <div className="plans__placeholder" />;
|
||||
|
||||
return <Planner />;
|
||||
}
|
||||
|
|
|
|||
14
package-lock.json
generated
14
package-lock.json
generated
|
|
@ -23,6 +23,7 @@
|
|||
"i18next-browser-languagedetector": "^6.1.5",
|
||||
"i18next-fs-backend": "^1.1.5",
|
||||
"i18next-http-backend": "^1.4.4",
|
||||
"isbot": "^3.6.5",
|
||||
"just-capitalize": "^3.1.1",
|
||||
"just-clone": "^6.1.1",
|
||||
"just-random-integer": "^4.1.1",
|
||||
|
|
@ -10050,6 +10051,14 @@
|
|||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"node_modules/isbot": {
|
||||
"version": "3.6.5",
|
||||
"resolved": "https://registry.npmjs.org/isbot/-/isbot-3.6.5.tgz",
|
||||
"integrity": "sha512-BchONELXt6yMad++BwGpa0oQxo/uD0keL7N15cYVf0A1oMIoNQ79OqeYdPMFWDrNhCqCbRuw9Y9F3QBjvAxZ5g==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
|
|
@ -24062,6 +24071,11 @@
|
|||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"isbot": {
|
||||
"version": "3.6.5",
|
||||
"resolved": "https://registry.npmjs.org/isbot/-/isbot-3.6.5.tgz",
|
||||
"integrity": "sha512-BchONELXt6yMad++BwGpa0oQxo/uD0keL7N15cYVf0A1oMIoNQ79OqeYdPMFWDrNhCqCbRuw9Y9F3QBjvAxZ5g=="
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
"i18next-browser-languagedetector": "^6.1.5",
|
||||
"i18next-fs-backend": "^1.1.5",
|
||||
"i18next-http-backend": "^1.4.4",
|
||||
"isbot": "^3.6.5",
|
||||
"just-capitalize": "^3.1.1",
|
||||
"just-clone": "^6.1.1",
|
||||
"just-random-integer": "^4.1.1",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user