Context Proxy (context-proxy.js)
Examine the isolated process response mock, inter-process communication bindings, and header synchronization.
Key File Location: ./dinou/core/context-proxy.js💡 Overview
To isolate routing environments and dynamic page compilation, Dinou spins up rendering tasks in separate Node.js child processes. Because these processes run in an isolated memory space, Server Components cannot modify the HTTP response object of the parent Express server.
The context-proxy.js utility resolves this separation. It returns a mock response object that exposes standard Express methods (e.g. res.cookie(), res.redirect()). When invoked inside a component, these methods serialize the inputs and send them to the parent process via IPC.
📊 IPC Context Flow
The diagram below traces the communication path between worker threads and the main server:
⚡ Inter-Process Communication
When a Server Component sets a cookie (e.g. `cookies().set('session', id)`), the context proxy intercepts the call and executes the following steps:
- Serialize Arguments: Converts options (like cookie expiry, secure flag, domain path) and arguments into a serializable JSON payload.
- Send Message: Checks if
process.sendis defined. If so, it dispatches an IPC message with typeDINOU_CONTEXT_COMMAND. - Parent Application: The main Express process listens for message events on the child process instance. Upon receiving a command, it applies the changes to the real
resheaders before completing the client response.
⚙️ Complete Code Walkthrough
Below is the full, complete code of context-proxy.js:
// core/context-proxy.js
/**
* Creates a proxy object that intercepts response method calls
* and sends them to the parent process (Express Handler) through IPC.
* @returns {object} The proxy object that simulates the Express response.
*/
function createResponseProxy() {
// Central function to send commands to the parent process
function sendCommand(command, args) {
if (typeof process.send === "function") {
process.send({
type: "DINOU_CONTEXT_COMMAND",
command,
args,
});
} else {
console.warn(
`[Dinou] Attempted to run context command "${command}" outside of a child process.`
);
}
}
return {
// 1. Proxy to delete cookies
clearCookie: (name, options) => {
sendCommand("clearCookie", [name, options]);
},
// 2. Proxy to set cookies
cookie: (name, value, options) => {
sendCommand("cookie", [name, value, options]);
},
// 3. Proxy to set headers
setHeader: (name, value) => {
sendCommand("setHeader", [name, value]);
},
// 4. Proxy to redirect
redirect: (arg1, arg2) => {
if (arg2) {
sendCommand("redirect", [arg1, arg2]); // [status, url]
} else {
sendCommand("redirect", [arg1]); // [url]
}
},
// 5. Proxy for status code
status: (code) => {
sendCommand("status", [code]);
},
};
}
module.exports = {
createResponseProxy,
};