Files
vercel/packages/remix/server-node.mjs
Nathan Rajlich 0bbb06daa7 [remix] Support "regions", "memory" and "maxDuration" in static config (#9442)
Apply the `regions` configuration (for both Edge and Node) and `memory`/`maxDuration` (only for Node) in a page's static config export, i.e.

```js
export const config = { runtime: 'edge', regions: ['iad1'] }

// or for Node
export const config = { runtime: 'nodejs', regions: ['iad1'], maxDuration: 5, memory: 3008 }
```

Similar to `runtime`, these config values can be inherited from a parent layout route to apply to all sub-routes. Routes with common config settings get placed into a common server bundle, meaning that there may now be more than 2 functions created (previously was one Edge, one Node), allowing for more granularity between the server build bundles.
2023-03-01 21:45:10 +00:00

77 lines
1.9 KiB
JavaScript

import {
AbortController as NodeAbortController,
createRequestHandler as createRemixRequestHandler,
Headers as NodeHeaders,
Request as NodeRequest,
writeReadableStreamToWritable,
installGlobals,
} from '@remix-run/node';
installGlobals();
import build from '@remix-run/dev/server-build';
const handleRequest = createRemixRequestHandler(build, process.env.NODE_ENV);
function createRemixHeaders(requestHeaders) {
const headers = new NodeHeaders();
for (const key in requestHeaders) {
const header = requestHeaders[key];
// set-cookie is an array (maybe others)
if (Array.isArray(header)) {
for (const value of header) {
headers.append(key, value);
}
} else {
headers.append(key, header);
}
}
return headers;
}
function createRemixRequest(req, res) {
const host = req.headers['x-forwarded-host'] || req.headers['host'];
const protocol = req.headers['x-forwarded-proto'] || 'https';
const url = new URL(req.url, `${protocol}://${host}`);
// Abort action/loaders once we can no longer write a response
const controller = new NodeAbortController();
res.on('close', () => controller.abort());
const init = {
method: req.method,
headers: createRemixHeaders(req.headers),
signal: controller.signal,
};
if (req.method !== 'GET' && req.method !== 'HEAD') {
init.body = req;
}
return new NodeRequest(url.href, init);
}
async function sendRemixResponse(res, nodeResponse) {
res.statusMessage = nodeResponse.statusText;
let multiValueHeaders = nodeResponse.headers.raw();
res.writeHead(
nodeResponse.status,
nodeResponse.statusText,
multiValueHeaders
);
if (nodeResponse.body) {
await writeReadableStreamToWritable(nodeResponse.body, res);
} else {
res.end();
}
}
export default async (req, res) => {
const request = createRemixRequest(req, res);
const response = await handleRequest(request);
await sendRemixResponse(res, response);
};