diff --git a/examples/playground/server.js b/examples/playground/server.js index 89006f58..279d6547 100644 --- a/examples/playground/server.js +++ b/examples/playground/server.js @@ -1,5 +1,5 @@ import chalk from "chalk"; -import { remixFastify } from "@mcansh/remix-fastify"; +import { reactRouterFastify } from "@mcansh/remix-fastify/react-router"; import { installGlobals } from "@remix-run/node"; import { fastify } from "fastify"; import sourceMapSupport from "source-map-support"; @@ -14,7 +14,7 @@ app.post("/api/echo", async (request, reply) => { reply.send(request.body); }); -await app.register(remixFastify, { +await app.register(reactRouterFastify, { getLoadContext(request, reply) { return { loadContextName: "Logan" }; }, diff --git a/examples/playground/vite.config.ts.timestamp-1731715104505-f49232386f5ef.mjs b/examples/playground/vite.config.ts.timestamp-1731715104505-f49232386f5ef.mjs new file mode 100644 index 00000000..dac114ce --- /dev/null +++ b/examples/playground/vite.config.ts.timestamp-1731715104505-f49232386f5ef.mjs @@ -0,0 +1,12 @@ +// vite.config.ts +import { vitePlugin as remix } from "file:///Users/lmcansh/remix-fastify/node_modules/.pnpm/@remix-run+dev@2.10.0_@remix-run+react@2.14.0_react-dom@19.0.0-rc-100dfd7dab-20240701_react@1_fdtw53wollluzaehojg7fjacfe/node_modules/@remix-run/dev/dist/index.js"; +import { defineConfig } from "file:///Users/lmcansh/remix-fastify/node_modules/.pnpm/vite@5.4.9_@types+node@22.7.7_lightningcss@1.26.0/node_modules/vite/dist/node/index.js"; +import tsconfigPaths from "file:///Users/lmcansh/remix-fastify/node_modules/.pnpm/vite-tsconfig-paths@5.0.1_typescript@5.6.3_vite@5.4.9_@types+node@22.7.7_lightningcss@1.26.0_/node_modules/vite-tsconfig-paths/dist/index.js"; +import tailwindcss from "file:///Users/lmcansh/remix-fastify/node_modules/.pnpm/@tailwindcss+vite@4.0.0-alpha.28_vite@5.4.9_@types+node@22.7.7_lightningcss@1.26.0_/node_modules/@tailwindcss/vite/dist/index.mjs"; +var vite_config_default = defineConfig({ + plugins: [remix(), tsconfigPaths(), tailwindcss()] +}); +export { + vite_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvVXNlcnMvbG1jYW5zaC9yZW1peC1mYXN0aWZ5L2V4YW1wbGVzL3BsYXlncm91bmRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIi9Vc2Vycy9sbWNhbnNoL3JlbWl4LWZhc3RpZnkvZXhhbXBsZXMvcGxheWdyb3VuZC92aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vVXNlcnMvbG1jYW5zaC9yZW1peC1mYXN0aWZ5L2V4YW1wbGVzL3BsYXlncm91bmQvdml0ZS5jb25maWcudHNcIjtpbXBvcnQgeyB2aXRlUGx1Z2luIGFzIHJlbWl4IH0gZnJvbSBcIkByZW1peC1ydW4vZGV2XCI7XG5pbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tIFwidml0ZVwiO1xuaW1wb3J0IHRzY29uZmlnUGF0aHMgZnJvbSBcInZpdGUtdHNjb25maWctcGF0aHNcIjtcbmltcG9ydCB0YWlsd2luZGNzcyBmcm9tIFwiQHRhaWx3aW5kY3NzL3ZpdGVcIjtcblxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcbiAgcGx1Z2luczogW3JlbWl4KCksIHRzY29uZmlnUGF0aHMoKSwgdGFpbHdpbmRjc3MoKV0sXG59KTtcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBa1UsU0FBUyxjQUFjLGFBQWE7QUFDdFcsU0FBUyxvQkFBb0I7QUFDN0IsT0FBTyxtQkFBbUI7QUFDMUIsT0FBTyxpQkFBaUI7QUFFeEIsSUFBTyxzQkFBUSxhQUFhO0FBQUEsRUFDMUIsU0FBUyxDQUFDLE1BQU0sR0FBRyxjQUFjLEdBQUcsWUFBWSxDQUFDO0FBQ25ELENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg== diff --git a/examples/react-router/server.js b/examples/react-router/server.js index bb72cf8e..ce5b5f7a 100644 --- a/examples/react-router/server.js +++ b/examples/react-router/server.js @@ -1,5 +1,5 @@ import chalk from "chalk"; -import { remixFastify } from "@mcansh/remix-fastify"; +import { reactRouterFastify } from "@mcansh/remix-fastify/react-router"; import { fastify } from "fastify"; import sourceMapSupport from "source-map-support"; import getPort, { portNumbers } from "get-port"; @@ -8,9 +8,7 @@ sourceMapSupport.install(); let app = fastify(); -await app.register(remixFastify, { - virtualModule: "virtual:react-router/server-build", -}); +await app.register(reactRouterFastify); const desiredPort = Number(process.env.PORT) || 3000; const portToUse = await getPort({ diff --git a/packages/remix-fastify/package.json b/packages/remix-fastify/package.json index c061b92a..9b96c655 100644 --- a/packages/remix-fastify/package.json +++ b/packages/remix-fastify/package.json @@ -1,7 +1,7 @@ { "name": "@mcansh/remix-fastify", "version": "4.0.1", - "description": "Fastify server request handler for Remix", + "description": "Fastify server request handler for Remix and React Router", "repository": "mcansh/remix-fastify", "license": "MIT", "author": "Logan McAnsh (https://mcan.sh)", @@ -11,6 +11,7 @@ "keywords": [ "remix", "remix-run", + "react-router", "fastify" ], "funding": [ @@ -25,6 +26,14 @@ ".": { "require": "./dist/index.cjs", "import": "./dist/index.js" + }, + "./react-router": { + "require": "./dist/react-router.cjs", + "import": "./dist/react-router.js" + }, + "./remix": { + "require": "./dist/remix.cjs", + "import": "./dist/remix.js" } }, "main": "./dist/index.cjs", @@ -35,10 +44,18 @@ "dist", "package.json", "README.md", - "LICENSE" + "LICENSE", + "react-router.cjs", + "react-router.d.cts", + "react-router.d.ts", + "react-router.js", + "remix.cjs", + "remix.d.cts", + "remix.d.ts", + "remix.js" ], "scripts": { - "prepublishOnly": "npm run build && cp ../../LICENSE LICENSE && publint && attw $(npm pack)", + "prepublishOnly": "npm run build && cp ../../LICENSE LICENSE && publint && attw --pack", "typecheck": "tsc", "dev": "tsup --watch", "build": "tsup", @@ -52,18 +69,20 @@ "pretty-cache-header": "^1.0.0" }, "devDependencies": { + "@react-router/node": "7.0.0-pre.5", "@remix-run/node": "^2.13.1", "@types/node": "^22.7.7", "@typescript/lib-dom": "npm:@types/web@^0.0.174", "fastify": "^5.0.0", "node-mocks-http": "^1.16.1", + "react-router": "^7.0.0-pre.5", "typescript": "^5.6.3", "vite": "^5.4.9" }, "peerDependencies": { "@remix-run/node": "^2.0.0", "fastify": "^3.29.0 || ^4.0.0 || ^5.0.0", - "react-router": "*", + "react-router": ">=7.0.0 || >=7.0.0.pre", "vite": "^5.0.0" }, "peerDependenciesMeta": { diff --git a/packages/remix-fastify/react-router.cjs b/packages/remix-fastify/react-router.cjs new file mode 100644 index 00000000..47ee9f5e --- /dev/null +++ b/packages/remix-fastify/react-router.cjs @@ -0,0 +1 @@ +module.exports = require("./dist/react-router"); \ No newline at end of file diff --git a/packages/remix-fastify/react-router.d.cts b/packages/remix-fastify/react-router.d.cts new file mode 100644 index 00000000..7a56c995 --- /dev/null +++ b/packages/remix-fastify/react-router.d.cts @@ -0,0 +1 @@ +export type * from "./dist/react-router"; \ No newline at end of file diff --git a/packages/remix-fastify/react-router.d.ts b/packages/remix-fastify/react-router.d.ts new file mode 100644 index 00000000..7a56c995 --- /dev/null +++ b/packages/remix-fastify/react-router.d.ts @@ -0,0 +1 @@ +export type * from "./dist/react-router"; \ No newline at end of file diff --git a/packages/remix-fastify/react-router.js b/packages/remix-fastify/react-router.js new file mode 100644 index 00000000..ecf83428 --- /dev/null +++ b/packages/remix-fastify/react-router.js @@ -0,0 +1 @@ +export * from "./dist/react-router"; \ No newline at end of file diff --git a/packages/remix-fastify/remix.cjs b/packages/remix-fastify/remix.cjs new file mode 100644 index 00000000..a76c0656 --- /dev/null +++ b/packages/remix-fastify/remix.cjs @@ -0,0 +1 @@ +module.exports = require("./dist/remix"); \ No newline at end of file diff --git a/packages/remix-fastify/remix.d.cts b/packages/remix-fastify/remix.d.cts new file mode 100644 index 00000000..862ee82f --- /dev/null +++ b/packages/remix-fastify/remix.d.cts @@ -0,0 +1 @@ +export type * from "./dist/remix"; \ No newline at end of file diff --git a/packages/remix-fastify/remix.d.ts b/packages/remix-fastify/remix.d.ts new file mode 100644 index 00000000..862ee82f --- /dev/null +++ b/packages/remix-fastify/remix.d.ts @@ -0,0 +1 @@ +export type * from "./dist/remix"; \ No newline at end of file diff --git a/packages/remix-fastify/remix.js b/packages/remix-fastify/remix.js new file mode 100644 index 00000000..f3a40695 --- /dev/null +++ b/packages/remix-fastify/remix.js @@ -0,0 +1 @@ +export * from "./dist/remix"; \ No newline at end of file diff --git a/packages/remix-fastify/src/index.ts b/packages/remix-fastify/src/index.ts index 1079e0a7..f38a0d93 100644 --- a/packages/remix-fastify/src/index.ts +++ b/packages/remix-fastify/src/index.ts @@ -1,4 +1,6 @@ -export type { GetLoadContextFunction, RequestHandler } from "./server"; -export { createRequestHandler } from "./server"; -export { remixFastify } from "./plugin"; -export type { RemixFastifyOptions } from "./plugin"; +export type { + GetLoadContextFunction, + RequestHandler, + RemixFastifyOptions, +} from "./remix"; +export { createRequestHandler, remixFastify } from "./remix"; diff --git a/packages/remix-fastify/src/plugin.ts b/packages/remix-fastify/src/plugins/index.ts similarity index 74% rename from packages/remix-fastify/src/plugin.ts rename to packages/remix-fastify/src/plugins/index.ts index bcadb0ba..ea0b80b0 100644 --- a/packages/remix-fastify/src/plugin.ts +++ b/packages/remix-fastify/src/plugins/index.ts @@ -1,15 +1,19 @@ +import type { FastifyInstance } from "fastify"; + import path from "node:path"; import url from "node:url"; -import fp from "fastify-plugin"; import type { InlineConfig, ViteDevServer } from "vite"; import fastifyStatic, { type FastifyStaticOptions } from "@fastify/static"; import { cacheHeader } from "pretty-cache-header"; -import type { ServerBuild } from "@remix-run/node"; - -import { createRequestHandler } from "./server"; -import type { HttpServer, GetLoadContextFunction } from "./server"; +import type { GetLoadContextFunction, HttpServer } from "../shared"; +import type { CreateRequestHandlerFunction as RRCreateRequestHandlerFunction } from "../servers/react-router"; +import type { CreateRequestHandlerFunction as RemixCreateRequestHandlerFunction } from "../servers/remix"; -export type RemixFastifyOptions = { +export type PluginOptions< + Server extends HttpServer = HttpServer, + AppLoadContext = unknown, + ServerBuild = unknown, +> = { /** * The base path for the Remix app. * match the `basename` in your Vite config. @@ -35,7 +39,7 @@ export type RemixFastifyOptions = { * You can think of this as an escape hatch that allows you to pass * environment/platform-specific values through to your loader/action. */ - getLoadContext?: GetLoadContextFunction; + getLoadContext: GetLoadContextFunction; mode?: string; /** * Options to pass to the Vite server in development. @@ -67,28 +71,40 @@ export type RemixFastifyOptions = { productionServerBuild?: | ServerBuild | (() => ServerBuild | Promise); - virtualModule?: + + /** + * The virtual module to load in development. + */ + virtualModule: | "virtual:remix/server-build" | "virtual:react-router/server-build"; }; -export const remixFastify = fp( - async ( - fastify, - { - basename = "/", - buildDirectory = "build", - serverBuildFile = "index.js", - getLoadContext, - mode = process.env.NODE_ENV, - viteOptions, - fastifyStaticOptions, - assetCacheControl = { public: true, maxAge: "1 year", immutable: true }, - defaultCacheControl = { public: true, maxAge: "1 hour" }, - productionServerBuild, - virtualModule = "virtual:remix/server-build", - }, - ) => { +export function createPlugin( + fastify: FastifyInstance, + { + basename = "/", + buildDirectory = "build", + serverBuildFile = "index.js", + getLoadContext, + mode = process.env.NODE_ENV, + viteOptions, + fastifyStaticOptions, + assetCacheControl = { public: true, maxAge: "1 year", immutable: true }, + defaultCacheControl = { public: true, maxAge: "1 hour" }, + productionServerBuild, + virtualModule, + }: PluginOptions, + // TODO: look if importing the function as a type requires the peer dependency + createRequestHandler: + | RemixCreateRequestHandlerFunction + | RRCreateRequestHandlerFunction, +) { + console.log(`inside createPlugin`); + + return async () => { + console.log(`inside createPlugin async`); + let cwd = process.env.REMIX_ROOT ?? process.cwd(); let vite: ViteDevServer | undefined; @@ -113,9 +129,11 @@ export const remixFastify = fp( ); let SERVER_BUILD_URL = url.pathToFileURL(SERVER_BUILD).href; - let remixHandler = createRequestHandler({ + let handler = createRequestHandler({ mode, + // @ts-expect-error - fix this getLoadContext, + // @ts-expect-error - fix this build: vite ? () => vite.ssrLoadModule(virtualModule) : (productionServerBuild ?? (() => import(SERVER_BUILD_URL))), @@ -139,6 +157,7 @@ export const remixFastify = fp( serveDotFiles: true, lastModified: true, setHeaders(res, filepath) { + console.log({ filepath }); let isAsset = filepath.startsWith(ASSET_DIR); res.setHeader( "cache-control", @@ -161,15 +180,10 @@ export const remixFastify = fp( }); childServer.all("*", (request, reply) => { - remixHandler(request, reply); + handler(request, reply); }); }, { prefix: basename }, ); - }, - { - // replaced with the package name during build - name: process.env.__PACKAGE_NAME__, - fastify: process.env.__FASTIFY_VERSION__, - }, -); + }; +} diff --git a/packages/remix-fastify/src/plugins/react-router.ts b/packages/remix-fastify/src/plugins/react-router.ts new file mode 100644 index 00000000..bb30a9dd --- /dev/null +++ b/packages/remix-fastify/src/plugins/react-router.ts @@ -0,0 +1,30 @@ +import fp from "fastify-plugin"; + +import type { HttpServer } from "../shared"; +import type { AppLoadContext, ServerBuild } from "react-router"; +import { createRequestHandler } from "../servers/react-router"; +import { createPlugin, type PluginOptions } from "."; + +export type ReactRouterFastifyOptions = Omit< + PluginOptions, + "virtualModule" +>; + +export const reactRouterFastify = fp( + async (fastify, options) => { + let plugin = createPlugin( + fastify, + { + ...options, + virtualModule: "virtual:react-router/server-build", + }, + createRequestHandler, + ); + return plugin(); + }, + { + // replaced with the package name during build + name: process.env.__PACKAGE_NAME__, + fastify: process.env.__FASTIFY_VERSION__, + }, +); diff --git a/packages/remix-fastify/src/plugins/remix.ts b/packages/remix-fastify/src/plugins/remix.ts new file mode 100644 index 00000000..de4e5b64 --- /dev/null +++ b/packages/remix-fastify/src/plugins/remix.ts @@ -0,0 +1,30 @@ +import fp from "fastify-plugin"; +import type { AppLoadContext, ServerBuild } from "@remix-run/node"; + +import { createRequestHandler } from "../servers/remix"; +import type { HttpServer } from "../shared"; +import { createPlugin, type PluginOptions } from "."; + +export type RemixFastifyOptions = Omit< + PluginOptions, + "virtualModule" +>; + +export const remixFastify = fp( + async (fastify, options) => { + let plugin = createPlugin( + fastify, + { + ...options, + virtualModule: "virtual:remix/server-build", + }, + createRequestHandler, + ); + return plugin(); + }, + { + // replaced with the package name during build + name: process.env.__PACKAGE_NAME__, + fastify: process.env.__FASTIFY_VERSION__, + }, +); diff --git a/packages/remix-fastify/src/react-router.ts b/packages/remix-fastify/src/react-router.ts new file mode 100644 index 00000000..8c396db9 --- /dev/null +++ b/packages/remix-fastify/src/react-router.ts @@ -0,0 +1,12 @@ +import type { AppLoadContext } from "react-router"; +import type { + HttpServer, + GetLoadContextFunction as SharedGetLoadContextFunction, +} from "./shared"; +export type { RequestHandler } from "./shared"; +export { createRequestHandler } from "./servers/react-router"; +export { reactRouterFastify } from "./plugins/react-router"; +export type { ReactRouterFastifyOptions } from "./plugins/react-router"; + +export type GetLoadContextFunction = + SharedGetLoadContextFunction; diff --git a/packages/remix-fastify/src/remix.ts b/packages/remix-fastify/src/remix.ts new file mode 100644 index 00000000..05f3f039 --- /dev/null +++ b/packages/remix-fastify/src/remix.ts @@ -0,0 +1,12 @@ +import type { AppLoadContext } from "@remix-run/node"; +import type { + HttpServer, + GetLoadContextFunction as SharedGetLoadContextFunction, +} from "./shared"; +export type { RequestHandler } from "./shared"; +export { createRequestHandler } from "./servers/remix"; +export { remixFastify } from "./plugins/remix"; +export type { RemixFastifyOptions } from "./plugins/remix"; + +export type GetLoadContextFunction = + SharedGetLoadContextFunction; diff --git a/packages/remix-fastify/src/servers/react-router.ts b/packages/remix-fastify/src/servers/react-router.ts new file mode 100644 index 00000000..c7bdf71d --- /dev/null +++ b/packages/remix-fastify/src/servers/react-router.ts @@ -0,0 +1,55 @@ +import type { + FastifyRequest, + FastifyReply, + RouteGenericInterface, +} from "fastify"; +import { createRequestHandler as createRemixRequestHandler } from "react-router"; +import type { AppLoadContext, ServerBuild } from "react-router"; +import { createReadableStreamFromReadable } from "@react-router/node"; +import { createRequestInit, getUrl, sendResponse } from "../shared"; +import type { + HttpServer, + RequestHandler, + GetLoadContextFunction as GenericGetLoadContextFunction, +} from "../shared"; + +export type CreateRequestHandlerFunction = typeof createRequestHandler; +export type GetLoadContextFunction = + GenericGetLoadContextFunction; + +/** + * Returns a request handler for Fastify that serves the response using Remix. + */ +export function createRequestHandler({ + build, + getLoadContext, + mode = process.env.NODE_ENV, +}: { + build: ServerBuild | (() => ServerBuild | Promise); + getLoadContext?: GetLoadContextFunction; + mode?: string; +}): RequestHandler { + let handleRequest = createRemixRequestHandler(build, mode); + + return async (request, reply) => { + let remixRequest = createRequest(request, reply); + let loadContext = await getLoadContext?.(request, reply); + let response = await handleRequest(remixRequest, loadContext); + return sendResponse(reply, response); + }; +} + +function createRequest( + request: FastifyRequest, + reply: FastifyReply, +): Request { + let url = getUrl(request); + let init = createRequestInit(request, reply); + + if (request.method !== "GET" && request.method !== "HEAD") { + init.body = createReadableStreamFromReadable(request.raw); + init.duplex = "half"; + } + + return new Request(url, init); +} diff --git a/packages/remix-fastify/src/servers/remix.ts b/packages/remix-fastify/src/servers/remix.ts new file mode 100644 index 00000000..3d0150c7 --- /dev/null +++ b/packages/remix-fastify/src/servers/remix.ts @@ -0,0 +1,57 @@ +import type { + FastifyRequest, + FastifyReply, + RouteGenericInterface, +} from "fastify"; +import type { AppLoadContext, ServerBuild } from "@remix-run/node"; +import { + createRequestHandler as createRemixRequestHandler, + createReadableStreamFromReadable, +} from "@remix-run/node"; +import { createRequestInit, getUrl, sendResponse } from "../shared"; +import type { + GetLoadContextFunction as GenericGetLoadContextFunction, + HttpServer, + RequestHandler, +} from "../shared"; + +export type CreateRequestHandlerFunction = typeof createRequestHandler; +export type GetLoadContextFunction = + GenericGetLoadContextFunction; + +/** + * Returns a request handler for Fastify that serves the response using Remix. + */ +export function createRequestHandler({ + build, + getLoadContext, + mode = process.env.NODE_ENV, +}: { + build: ServerBuild | (() => ServerBuild | Promise); + getLoadContext?: GetLoadContextFunction; + mode?: string; +}): RequestHandler { + let handleRequest = createRemixRequestHandler(build, mode); + + return async (request, reply) => { + let remixRequest = createRequest(request, reply); + let loadContext = await getLoadContext?.(request, reply); + let response = await handleRequest(remixRequest, loadContext); + return sendResponse(reply, response); + }; +} + +function createRequest( + request: FastifyRequest, + reply: FastifyReply, +): Request { + let url = getUrl(request); + let init = createRequestInit(request, reply); + + if (request.method !== "GET" && request.method !== "HEAD") { + init.body = createReadableStreamFromReadable(request.raw); + init.duplex = "half"; + } + + return new Request(url, init); +} diff --git a/packages/remix-fastify/src/server.ts b/packages/remix-fastify/src/shared.ts similarity index 71% rename from packages/remix-fastify/src/server.ts rename to packages/remix-fastify/src/shared.ts index 3b900faa..ce2eb600 100644 --- a/packages/remix-fastify/src/server.ts +++ b/packages/remix-fastify/src/shared.ts @@ -3,17 +3,12 @@ import type * as http from "node:http"; import type * as http2 from "node:http2"; import type * as https from "node:https"; import type { - FastifyRequest, FastifyReply, - RawRequestDefaultExpression, + FastifyRequest, RawReplyDefaultExpression, + RawRequestDefaultExpression, RouteGenericInterface, } from "fastify"; -import type { AppLoadContext, ServerBuild } from "@remix-run/node"; -import { - createRequestHandler as createRemixRequestHandler, - createReadableStreamFromReadable, -} from "@remix-run/node"; export type HttpServer = | http.Server @@ -24,6 +19,11 @@ export type HttpServer = export type HttpRequest = RawRequestDefaultExpression; export type HttpResponse = RawReplyDefaultExpression; +export type RequestHandler = ( + request: FastifyRequest, + reply: FastifyReply, +) => Promise; + /** * A function that returns the value to use as `context` in route `loader` and * `action` functions. @@ -31,40 +31,14 @@ export type HttpResponse = RawReplyDefaultExpression; * You can think of this as an escape hatch that allows you to pass * environment/platform-specific values through to your loader/action. */ -export type GetLoadContextFunction = ( +export type GetLoadContextFunction< + Server extends HttpServer, + AppLoadContext, +> = ( request: FastifyRequest, reply: FastifyReply, ) => Promise | AppLoadContext; -export type RequestHandler = ( - request: FastifyRequest, - reply: FastifyReply, -) => Promise; - -/** - * Returns a request handler for Fastify that serves the response using Remix. - */ -export function createRequestHandler({ - build, - getLoadContext, - mode = process.env.NODE_ENV, -}: { - build: ServerBuild | (() => ServerBuild | Promise); - getLoadContext?: GetLoadContextFunction; - mode?: string; -}): RequestHandler { - let handleRequest = createRemixRequestHandler(build, mode); - - return async (request, reply) => { - let remixRequest = createRemixRequest(request, reply); - let loadContext = await getLoadContext?.(request, reply); - - let response = await handleRequest(remixRequest, loadContext); - - return sendRemixResponse(reply, response); - }; -} - export function createRemixHeaders( requestHeaders: FastifyRequest["headers"], ): Headers { @@ -94,12 +68,10 @@ export function getUrl( return url; } -export function createRemixRequest( +export function createRequestInit( request: FastifyRequest, reply: FastifyReply, -): Request { - let url = getUrl(request); - +): RequestInit { let controller: AbortController | null = new AbortController(); let init: RequestInit = { @@ -115,15 +87,10 @@ export function createRemixRequest( reply.raw.on("finish", () => (controller = null)); reply.raw.on("close", () => controller?.abort()); - if (request.method !== "GET" && request.method !== "HEAD") { - init.body = createReadableStreamFromReadable(request.raw); - init.duplex = "half"; - } - - return new Request(url, init); + return init; } -export async function sendRemixResponse( +export async function sendResponse( reply: FastifyReply, nodeResponse: Response, ): Promise { @@ -152,7 +119,6 @@ function responseToReadable(response: Response): Readable | null { readable.push(Buffer.from(result.value)); } else { readable.push(null); - return; } }; diff --git a/packages/remix-fastify/tsup.config.ts b/packages/remix-fastify/tsup.config.ts index bd523861..ab514f00 100644 --- a/packages/remix-fastify/tsup.config.ts +++ b/packages/remix-fastify/tsup.config.ts @@ -1,16 +1,24 @@ +import Fsp from "node:fs/promises"; +import Path from "node:path"; import { defineConfig } from "tsup"; import pkg from "./package.json"; export default defineConfig(() => { return { - entry: ["src/index.ts"], + entry: { + index: "./src/index.ts", + remix: "./src/remix.ts", + "react-router": "./src/react-router.ts", + }, sourcemap: true, tsconfig: "./tsconfig.json", dts: true, + clean: true, format: ["cjs", "esm"], cjsInterop: true, - splitting: true, + splitting: false, + bundle: true, platform: "node", skipNodeModulesBundle: true, treeshake: true, @@ -20,5 +28,24 @@ export default defineConfig(() => { pkg.peerDependencies.fastify, ), }, + async onSuccess() { + let subPaths = ["remix", "react-router"]; + + // generate root re-exports for each sub-path + for (let subPath of subPaths) { + let cjs = js`module.exports = require("./dist/${subPath}");`; + let esm = js`export * from "./dist/${subPath}";`; + let dts = js`export type * from "./dist/${subPath}";`; + + await Promise.all([ + Fsp.writeFile(`${subPath}.cjs`, cjs), + Fsp.writeFile(`${subPath}.js`, esm), + Fsp.writeFile(`${subPath}.d.ts`, dts), + Fsp.writeFile(`${subPath}.d.cts`, dts), + ]); + } + }, }; }); + +let js = String.raw; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2d379f23..353a4062 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,7 +24,7 @@ importers: version: 6.0.1 '@remix-run/eslint-config': specifier: latest - version: 2.13.1(eslint@9.13.0(jiti@2.3.3))(react@18.3.1)(typescript@5.6.3) + version: 2.14.0(eslint@9.13.0(jiti@2.3.3))(react@18.3.1)(typescript@5.6.3) '@types/npmcli__package-json': specifier: ^4.0.4 version: 4.0.4 @@ -90,13 +90,13 @@ importers: version: link:../../packages/remix-fastify '@remix-run/css-bundle': specifier: latest - version: 2.13.1 + version: 2.14.0 '@remix-run/node': specifier: latest - version: 2.13.1(typescript@5.6.3) + version: 2.14.0(typescript@5.6.3) '@remix-run/react': specifier: latest - version: 2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + version: 2.14.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) chalk: specifier: ^5.3.0 version: 5.3.0 @@ -124,7 +124,7 @@ importers: devDependencies: '@remix-run/dev': specifier: '*' - version: 2.9.0(@remix-run/react@2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@types/node@22.7.7)(lightningcss@1.26.0)(ts-node@10.9.2(@types/node@22.7.7)(typescript@5.6.3))(typescript@5.6.3)(vite@5.4.9(@types/node@22.7.7)(lightningcss@1.26.0)) + version: 2.9.0(@remix-run/react@2.14.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@types/node@22.7.7)(lightningcss@1.26.0)(ts-node@10.9.2(@types/node@22.7.7)(typescript@5.6.3))(typescript@5.6.3)(vite@5.4.9(@types/node@22.7.7)(lightningcss@1.26.0)) '@remix-run/eslint-config': specifier: '*' version: 2.9.0(eslint@8.57.0)(react@18.3.1)(typescript@5.6.3) @@ -157,10 +157,10 @@ importers: version: link:../../packages/remix-fastify '@remix-run/node': specifier: latest - version: 2.13.1(typescript@5.6.3) + version: 2.14.0(typescript@5.6.3) '@remix-run/react': specifier: latest - version: 2.13.1(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701)(typescript@5.6.3) + version: 2.14.0(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701)(typescript@5.6.3) chalk: specifier: ^5.3.0 version: 5.3.0 @@ -188,7 +188,7 @@ importers: version: 9.0.2 '@remix-run/dev': specifier: '*' - version: 2.10.0(@remix-run/react@2.13.1(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701)(typescript@5.6.3))(@types/node@22.7.7)(lightningcss@1.26.0)(ts-node@10.9.2(@types/node@22.7.7)(typescript@5.6.3))(typescript@5.6.3)(vite@5.4.9(@types/node@22.7.7)(lightningcss@1.26.0)) + version: 2.10.0(@remix-run/react@2.14.0(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701)(typescript@5.6.3))(@types/node@22.7.7)(lightningcss@1.26.0)(ts-node@10.9.2(@types/node@22.7.7)(typescript@5.6.3))(typescript@5.6.3)(vite@5.4.9(@types/node@22.7.7)(lightningcss@1.26.0)) '@remix-run/eslint-config': specifier: '*' version: 2.9.0(eslint@8.57.0)(react@19.0.0-rc-100dfd7dab-20240701)(typescript@5.6.3) @@ -318,13 +318,13 @@ importers: version: link:../../packages/remix-fastify '@remix-run/node': specifier: latest - version: 2.13.1(typescript@5.6.3) + version: 2.14.0(typescript@5.6.3) '@remix-run/react': specifier: latest - version: 2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + version: 2.14.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@remix-run/server-runtime': specifier: latest - version: 2.13.1(typescript@5.6.3) + version: 2.14.0(typescript@5.6.3) chalk: specifier: ^5.3.0 version: 5.3.0 @@ -352,7 +352,7 @@ importers: devDependencies: '@remix-run/dev': specifier: '*' - version: 2.9.0(@remix-run/react@2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@types/node@22.7.7)(lightningcss@1.26.0)(ts-node@10.9.2(@types/node@22.7.7)(typescript@5.6.3))(typescript@5.6.3)(vite@5.4.9(@types/node@22.7.7)(lightningcss@1.26.0)) + version: 2.9.0(@remix-run/react@2.14.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@types/node@22.7.7)(lightningcss@1.26.0)(ts-node@10.9.2(@types/node@22.7.7)(typescript@5.6.3))(typescript@5.6.3)(vite@5.4.9(@types/node@22.7.7)(lightningcss@1.26.0)) '@remix-run/eslint-config': specifier: '*' version: 2.9.0(eslint@8.57.0)(react@18.3.1)(typescript@5.6.3) @@ -398,10 +398,10 @@ importers: pretty-cache-header: specifier: ^1.0.0 version: 1.0.0 - react-router: - specifier: '*' - version: 6.27.0(react@19.0.0-rc-100dfd7dab-20240701) devDependencies: + '@react-router/node': + specifier: 7.0.0-pre.5 + version: 7.0.0-pre.5(react-router@7.0.0-pre.5(react-dom@18.3.1(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701))(typescript@5.6.3) '@remix-run/node': specifier: ^2.13.1 version: 2.13.1(typescript@5.6.3) @@ -417,6 +417,9 @@ importers: node-mocks-http: specifier: ^1.16.1 version: 1.16.1(@types/express@4.17.21)(@types/node@22.7.7) + react-router: + specifier: ^7.0.0-pre.5 + version: 7.0.0-pre.5(react-dom@18.3.1(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701) typescript: specifier: ^5.6.3 version: 5.6.3 @@ -1696,6 +1699,16 @@ packages: typescript: optional: true + '@react-router/node@7.0.0-pre.5': + resolution: {integrity: sha512-meYaoDNs2F31v6BRGFikPCtoJ0VZfi7MTdlooc1wgxD/uO+GcV2i3RPLrvt2hXyDE59guz62Q73h+SiUlFMfeA==} + engines: {node: '>=20.0.0'} + peerDependencies: + react-router: 7.0.0-pre.5 + typescript: ^5.1.0 + peerDependenciesMeta: + typescript: + optional: true + '@react-router/serve@7.0.0-pre.4': resolution: {integrity: sha512-Zh76x3X20PU7vt0t2DADsQxvpjcLxY29pJ/nF/uPG1KU+MwWM/EuQfIHWvKjng9FnlCgTKzYMjUu8essQpZKaw==} engines: {node: '>=20.0.0'} @@ -1703,8 +1716,8 @@ packages: peerDependencies: react-router: 7.0.0-pre.4 - '@remix-run/css-bundle@2.13.1': - resolution: {integrity: sha512-ukams+HcEaovitySAmH2Q8Gg8c6A3fKr5RJEpAn0NYk1Cc2t0fH05GVAGToOgtWeFeOUjREXAqk3+C76o0cHkg==} + '@remix-run/css-bundle@2.14.0': + resolution: {integrity: sha512-ihdLzO3UUAbdTkBQ/jl9rEmhFKzUA8eEAvvpjdkumipoKkiOsjqAFV62FAMf7mrKNBCv7UeoIOm6XHV9Io2DZg==} engines: {node: '>=18.0.0'} '@remix-run/dev@2.10.0': @@ -1747,9 +1760,10 @@ packages: wrangler: optional: true - '@remix-run/eslint-config@2.13.1': - resolution: {integrity: sha512-UNWRHYa++pWrO6qxNI9z7KrmD0/wncWjS36TujoPmlnVDQ2pKIhNZwBi6otJQIuI8TdUPBZstJNgRJ0TWYok6A==} + '@remix-run/eslint-config@2.14.0': + resolution: {integrity: sha512-/wBt/AVgBMNw8HWifSha/7dwaGudmyWo7FB7M+LKloZPZc+XR60cMqKSXJeWwJTo+pic++4V1GhQnKc+Cx3GyA==} engines: {node: '>=18.0.0'} + deprecated: Will no longer be maintained in React Router v7 peerDependencies: eslint: ^8.0.0 react: ^18.0.0 @@ -1761,6 +1775,7 @@ packages: '@remix-run/eslint-config@2.9.0': resolution: {integrity: sha512-y86wPR+l/SlhSoobs2RPeuRIP0OJ3wKZNpGDtId+QN7Kc3XswZipAxBlVspTk23x8aweNOSqoqMI0xfEkrGt5Q==} engines: {node: '>=18.0.0'} + deprecated: Will no longer be maintained in React Router v7 peerDependencies: eslint: ^8.0.0 react: ^18.0.0 @@ -1778,8 +1793,17 @@ packages: typescript: optional: true - '@remix-run/react@2.13.1': - resolution: {integrity: sha512-kZevCoKMz0ZDOOzTnG95yfM7M9ju38FkWNY1wtxCy+NnUJYrmTerGQtiBsJgMzYD6i29+w4EwoQsdqys7DmMSg==} + '@remix-run/node@2.14.0': + resolution: {integrity: sha512-ou16LMJYv0ElIToZ6dDqaLjv1T3iBEwuJTBahveEA8NkkACIWODJ2fgUYf1UKLMKHVdHjNImLzS37HdSZY0Q6g==} + engines: {node: '>=18.0.0'} + peerDependencies: + typescript: ^5.1.0 + peerDependenciesMeta: + typescript: + optional: true + + '@remix-run/react@2.14.0': + resolution: {integrity: sha512-uQcy5gxazHtpislgonx2dwRuR/CbvYUeguQxDgawd+dAyoglK2rFx58+F6Kj0Vjw6v/iuvxibA/lEAiAaB4ZmQ==} engines: {node: '>=18.0.0'} peerDependencies: react: ^18.0.0 @@ -1789,12 +1813,12 @@ packages: typescript: optional: true - '@remix-run/router@1.20.0': - resolution: {integrity: sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==} + '@remix-run/router@1.21.0': + resolution: {integrity: sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==} engines: {node: '>=14.0.0'} - '@remix-run/server-runtime@2.13.1': - resolution: {integrity: sha512-2DfBPRcHKVzE4bCNsNkKB50BhCCKF73x+jiS836OyxSIAL+x0tguV2AEjmGXefEXc5AGGzoxkus0AUUEYa29Vg==} + '@remix-run/server-runtime@2.14.0': + resolution: {integrity: sha512-9Th9UzDaoFFBD7zA5mRI1KT8JktFLN4ij9jPygrKBhG/kYmNIvhcMtq9VyjcbMvFK5natTyhOhrrKRIHtijD4w==} engines: {node: '>=18.0.0'} peerDependencies: typescript: ^5.1.0 @@ -5448,15 +5472,15 @@ packages: resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} engines: {node: '>=0.10.0'} - react-router-dom@6.27.0: - resolution: {integrity: sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==} + react-router-dom@6.28.0: + resolution: {integrity: sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' - react-router@6.27.0: - resolution: {integrity: sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==} + react-router@6.28.0: + resolution: {integrity: sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' @@ -5471,6 +5495,16 @@ packages: react-dom: optional: true + react-router@7.0.0-pre.5: + resolution: {integrity: sha512-UGrqwmlTubhrtUzIu1WYb1z9FVeCqGi9RdywwjFrSQqIDTPjn7g5PPuFAS6pbVuj81VRI7HVzaljpzKXPDnfEQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true + react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -7958,6 +7992,16 @@ snapshots: optionalDependencies: typescript: 5.6.3 + '@react-router/node@7.0.0-pre.5(react-router@7.0.0-pre.5(react-dom@18.3.1(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701))(typescript@5.6.3)': + dependencies: + '@web3-storage/multipart-parser': 1.0.0 + react-router: 7.0.0-pre.5(react-dom@18.3.1(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701) + source-map-support: 0.5.21 + stream-slice: 0.1.2 + undici: 6.20.1 + optionalDependencies: + typescript: 5.6.3 + '@react-router/serve@7.0.0-pre.4(react-router@7.0.0-pre.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.3)': dependencies: '@react-router/express': 7.0.0-pre.4(express@4.19.2)(react-router@7.0.0-pre.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.6.3) @@ -7972,9 +8016,9 @@ snapshots: - supports-color - typescript - '@remix-run/css-bundle@2.13.1': {} + '@remix-run/css-bundle@2.14.0': {} - '@remix-run/dev@2.10.0(@remix-run/react@2.13.1(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701)(typescript@5.6.3))(@types/node@22.7.7)(lightningcss@1.26.0)(ts-node@10.9.2(@types/node@22.7.7)(typescript@5.6.3))(typescript@5.6.3)(vite@5.4.9(@types/node@22.7.7)(lightningcss@1.26.0))': + '@remix-run/dev@2.10.0(@remix-run/react@2.14.0(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701)(typescript@5.6.3))(@types/node@22.7.7)(lightningcss@1.26.0)(ts-node@10.9.2(@types/node@22.7.7)(typescript@5.6.3))(typescript@5.6.3)(vite@5.4.9(@types/node@22.7.7)(lightningcss@1.26.0))': dependencies: '@babel/core': 7.24.0 '@babel/generator': 7.23.6 @@ -7986,10 +8030,10 @@ snapshots: '@babel/types': 7.24.0 '@mdx-js/mdx': 2.3.0 '@npmcli/package-json': 4.0.1 - '@remix-run/node': 2.13.1(typescript@5.6.3) - '@remix-run/react': 2.13.1(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701)(typescript@5.6.3) - '@remix-run/router': 1.20.0 - '@remix-run/server-runtime': 2.13.1(typescript@5.6.3) + '@remix-run/node': 2.14.0(typescript@5.6.3) + '@remix-run/react': 2.14.0(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701)(typescript@5.6.3) + '@remix-run/router': 1.21.0 + '@remix-run/server-runtime': 2.14.0(typescript@5.6.3) '@types/mdx': 2.0.11 '@vanilla-extract/integration': 6.5.0(@types/node@22.7.7)(lightningcss@1.26.0) arg: 5.0.2 @@ -8048,7 +8092,7 @@ snapshots: - ts-node - utf-8-validate - '@remix-run/dev@2.9.0(@remix-run/react@2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@types/node@22.7.7)(lightningcss@1.26.0)(ts-node@10.9.2(@types/node@22.7.7)(typescript@5.6.3))(typescript@5.6.3)(vite@5.4.9(@types/node@22.7.7)(lightningcss@1.26.0))': + '@remix-run/dev@2.9.0(@remix-run/react@2.14.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@types/node@22.7.7)(lightningcss@1.26.0)(ts-node@10.9.2(@types/node@22.7.7)(typescript@5.6.3))(typescript@5.6.3)(vite@5.4.9(@types/node@22.7.7)(lightningcss@1.26.0))': dependencies: '@babel/core': 7.24.0 '@babel/generator': 7.23.6 @@ -8060,10 +8104,10 @@ snapshots: '@babel/types': 7.24.0 '@mdx-js/mdx': 2.3.0 '@npmcli/package-json': 4.0.1 - '@remix-run/node': 2.13.1(typescript@5.6.3) - '@remix-run/react': 2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) - '@remix-run/router': 1.20.0 - '@remix-run/server-runtime': 2.13.1(typescript@5.6.3) + '@remix-run/node': 2.14.0(typescript@5.6.3) + '@remix-run/react': 2.14.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@remix-run/router': 1.21.0 + '@remix-run/server-runtime': 2.14.0(typescript@5.6.3) '@types/mdx': 2.0.11 '@vanilla-extract/integration': 6.5.0(@types/node@22.7.7)(lightningcss@1.26.0) arg: 5.0.2 @@ -8122,7 +8166,7 @@ snapshots: - ts-node - utf-8-validate - '@remix-run/eslint-config@2.13.1(eslint@9.13.0(jiti@2.3.3))(react@18.3.1)(typescript@5.6.3)': + '@remix-run/eslint-config@2.14.0(eslint@9.13.0(jiti@2.3.3))(react@18.3.1)(typescript@5.6.3)': dependencies: '@babel/core': 7.25.8 '@babel/eslint-parser': 7.25.8(@babel/core@7.25.8)(eslint@9.13.0(jiti@2.3.3)) @@ -8206,7 +8250,19 @@ snapshots: '@remix-run/node@2.13.1(typescript@5.6.3)': dependencies: - '@remix-run/server-runtime': 2.13.1(typescript@5.6.3) + '@remix-run/server-runtime': 2.14.0(typescript@5.6.3) + '@remix-run/web-fetch': 4.4.2 + '@web3-storage/multipart-parser': 1.0.0 + cookie-signature: 1.2.1 + source-map-support: 0.5.21 + stream-slice: 0.1.2 + undici: 6.14.1 + optionalDependencies: + typescript: 5.6.3 + + '@remix-run/node@2.14.0(typescript@5.6.3)': + dependencies: + '@remix-run/server-runtime': 2.14.0(typescript@5.6.3) '@remix-run/web-fetch': 4.4.2 '@web3-storage/multipart-parser': 1.0.0 cookie-signature: 1.2.1 @@ -8216,35 +8272,35 @@ snapshots: optionalDependencies: typescript: 5.6.3 - '@remix-run/react@2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': + '@remix-run/react@2.14.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@remix-run/router': 1.20.0 - '@remix-run/server-runtime': 2.13.1(typescript@5.6.3) + '@remix-run/router': 1.21.0 + '@remix-run/server-runtime': 2.14.0(typescript@5.6.3) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-router: 6.27.0(react@18.3.1) - react-router-dom: 6.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-router: 6.28.0(react@18.3.1) + react-router-dom: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) turbo-stream: 2.4.0 optionalDependencies: typescript: 5.6.3 - '@remix-run/react@2.13.1(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701)(typescript@5.6.3)': + '@remix-run/react@2.14.0(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701)(typescript@5.6.3)': dependencies: - '@remix-run/router': 1.20.0 - '@remix-run/server-runtime': 2.13.1(typescript@5.6.3) + '@remix-run/router': 1.21.0 + '@remix-run/server-runtime': 2.14.0(typescript@5.6.3) react: 19.0.0-rc-100dfd7dab-20240701 react-dom: 19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701) - react-router: 6.27.0(react@19.0.0-rc-100dfd7dab-20240701) - react-router-dom: 6.27.0(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701) + react-router: 6.28.0(react@19.0.0-rc-100dfd7dab-20240701) + react-router-dom: 6.28.0(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701) turbo-stream: 2.4.0 optionalDependencies: typescript: 5.6.3 - '@remix-run/router@1.20.0': {} + '@remix-run/router@1.21.0': {} - '@remix-run/server-runtime@2.13.1(typescript@5.6.3)': + '@remix-run/server-runtime@2.14.0(typescript@5.6.3)': dependencies: - '@remix-run/router': 1.20.0 + '@remix-run/router': 1.21.0 '@types/cookie': 0.6.0 '@web3-storage/multipart-parser': 1.0.0 cookie: 0.6.0 @@ -12803,6 +12859,13 @@ snapshots: react: 18.3.1 scheduler: 0.23.2 + react-dom@18.3.1(react@19.0.0-rc-100dfd7dab-20240701): + dependencies: + loose-envify: 1.4.0 + react: 19.0.0-rc-100dfd7dab-20240701 + scheduler: 0.23.2 + optional: true + react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701): dependencies: react: 19.0.0-rc-100dfd7dab-20240701 @@ -12814,28 +12877,28 @@ snapshots: react-refresh@0.14.0: {} - react-router-dom@6.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-router-dom@6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@remix-run/router': 1.20.0 + '@remix-run/router': 1.21.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-router: 6.27.0(react@18.3.1) + react-router: 6.28.0(react@18.3.1) - react-router-dom@6.27.0(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701): + react-router-dom@6.28.0(react-dom@19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701): dependencies: - '@remix-run/router': 1.20.0 + '@remix-run/router': 1.21.0 react: 19.0.0-rc-100dfd7dab-20240701 react-dom: 19.0.0-rc-100dfd7dab-20240701(react@19.0.0-rc-100dfd7dab-20240701) - react-router: 6.27.0(react@19.0.0-rc-100dfd7dab-20240701) + react-router: 6.28.0(react@19.0.0-rc-100dfd7dab-20240701) - react-router@6.27.0(react@18.3.1): + react-router@6.28.0(react@18.3.1): dependencies: - '@remix-run/router': 1.20.0 + '@remix-run/router': 1.21.0 react: 18.3.1 - react-router@6.27.0(react@19.0.0-rc-100dfd7dab-20240701): + react-router@6.28.0(react@19.0.0-rc-100dfd7dab-20240701): dependencies: - '@remix-run/router': 1.20.0 + '@remix-run/router': 1.21.0 react: 19.0.0-rc-100dfd7dab-20240701 react-router@7.0.0-pre.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): @@ -12850,6 +12913,18 @@ snapshots: optionalDependencies: react-dom: 18.3.1(react@18.3.1) + react-router@7.0.0-pre.5(react-dom@18.3.1(react@19.0.0-rc-100dfd7dab-20240701))(react@19.0.0-rc-100dfd7dab-20240701): + dependencies: + '@types/cookie': 0.6.0 + '@web3-storage/multipart-parser': 1.0.0 + cookie: 1.0.1 + react: 19.0.0-rc-100dfd7dab-20240701 + set-cookie-parser: 2.6.0 + source-map: 0.7.4 + turbo-stream: 2.4.0 + optionalDependencies: + react-dom: 18.3.1(react@19.0.0-rc-100dfd7dab-20240701) + react@18.3.1: dependencies: loose-envify: 1.4.0 diff --git a/render.yaml b/render.yaml index 894d9e39..43373167 100644 --- a/render.yaml +++ b/render.yaml @@ -45,4 +45,3 @@ services: - ./packages/**/* buildCommand: corepack enable && pnpm i && pnpm run build startCommand: cd examples/react-router && pnpm run start -