Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(rsc): Remove Node RSC worker #11449

Merged
merged 1 commit into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
chore(rsc): Remove Node RSC worker
  • Loading branch information
Tobbe committed Sep 6, 2024
commit 91910c751a7396fd1214db1ea20636e9a04cf9de
14 changes: 6 additions & 8 deletions packages/vite/src/rsc/rscRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { createElement } from 'react'

import { renderToReadableStream } from 'react-server-dom-webpack/server.edge'

import type { ServerAuthState } from '@redwoodjs/auth/dist/AuthProvider/ServerAuthProvider.js'
import { getPaths } from '@redwoodjs/project-config'

import type { RscFetchProps } from '../../../router/src/rsc/ClientRouter.tsx'
Expand All @@ -17,15 +16,14 @@ export type RenderInput = {
props: RscFetchProps | Record<string, unknown>
rsaId?: string | undefined
args?: unknown[] | undefined
serverState: {
headersInit: Record<string, string>
fullUrl: string
serverAuthState: ServerAuthState
}
}

let absoluteClientEntries: Record<string, string> = {}

export function renderRscToStream(input: RenderInput): Promise<ReadableStream> {
return input.rscId ? renderRsc(input) : executeRsa(input)
}

async function loadServerFile(filePath: string) {
console.log('rscRenderer.ts loadServerFile filePath', filePath)
return import(`file://${filePath}`)
Expand Down Expand Up @@ -111,7 +109,7 @@ function getBundlerConfig() {
return bundlerConfig
}

export async function renderRsc(input: RenderInput): Promise<ReadableStream> {
async function renderRsc(input: RenderInput): Promise<ReadableStream> {
if (input.rsaId || !input.args) {
throw new Error(
"Unexpected input. Can't request both RSCs and execute RSAs at the same time.",
Expand Down Expand Up @@ -149,7 +147,7 @@ function isSerializedFormData(data?: unknown): data is SerializedFormData {
return !!data && (data as SerializedFormData)?.__formData__
}

export async function executeRsa(input: RenderInput): Promise<ReadableStream> {
async function executeRsa(input: RenderInput): Promise<ReadableStream> {
console.log('executeRsa input', input)

if (!input.rsaId || !input.args) {
Expand Down
30 changes: 6 additions & 24 deletions packages/vite/src/rsc/rscRequestHandler.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Readable } from 'node:stream'

import * as DefaultFetchAPI from '@whatwg-node/fetch'
import { normalizeNodeRequest } from '@whatwg-node/server'
import busboy from 'busboy'
Expand All @@ -10,7 +12,6 @@ import type { HTTPMethod } from 'find-my-way'
import type { ViteDevServer } from 'vite'

import type { RscFetchProps } from '@redwoodjs/router/RscRouter'
import { getAuthState, getRequestHeaders } from '@redwoodjs/server-store'
import type { Middleware } from '@redwoodjs/web/dist/server/middleware'

import {
Expand All @@ -19,10 +20,9 @@ import {
} from '../bundled/react-server-dom-webpack.server.js'
import { hasStatusCode } from '../lib/StatusError.js'
import { invoke } from '../middleware/invokeMiddleware.js'
import { getFullUrlForFlightRequest } from '../utils.js'

import { renderRscToStream } from './rscRenderer.js'
import { sendRscFlightToStudio } from './rscStudioHandlers.js'
import { renderRsc } from './rscWorkerCommunication.js'

const BASE_PATH = '/rw-rsc/'

Expand Down Expand Up @@ -188,27 +188,11 @@ export function createRscRequestHandler(
}

try {
// We construct the URL for the flight request from props
// e.g. http://localhost:8910/rw-rsc/__rwjs__Routes?props=location={pathname:"/about",search:"?foo=bar""}
// becomes http://localhost:8910/about?foo=bar
// In the component, getting location would otherwise be at the rw-rsc URL
const fullUrl = getFullUrlForFlightRequest(req, props)
const readable = await renderRscToStream({ rscId, props, rsaId, args })

const pipeable = renderRsc({
rscId,
props,
rsaId,
args,
// Pass the serverState from server to the worker
// Inside the worker, we'll use this to re-initalize the server state (because workers are stateless)
serverState: {
headersInit: Object.fromEntries(getRequestHeaders().entries()),
serverAuthState: getAuthState(),
fullUrl,
},
})
Readable.fromWeb(readable).pipe(res)

// TODO (RSC): Can we reuse `pipeable` here somehow?
// TODO (RSC): Can we reuse `readable` here somehow?
await sendRscFlightToStudio({
rscId,
props,
Expand All @@ -221,8 +205,6 @@ export function createRscRequestHandler(

// TODO (RSC): See if we can/need to do more error handling here
// pipeable.on(handleError)

pipeable.pipe(res)
} catch (e) {
handleError(e)
}
Expand Down
48 changes: 16 additions & 32 deletions packages/vite/src/rsc/rscStudioHandlers.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import http from 'node:http'
import type { PassThrough } from 'node:stream'
import type { ReadableStream } from 'node:stream/web'

import type { Request } from 'express'

import { getConfig, getRawConfig } from '@redwoodjs/project-config'
import { getAuthState, getRequestHeaders } from '@redwoodjs/server-store'

import { getFullUrlForFlightRequest } from '../utils.js'

import { renderRscToStream } from './rscRenderer.js'
import type { RenderInput } from './rscRenderer.js'
import { renderRsc } from './rscWorkerCommunication.js'

const isTest = () => {
return process.env.NODE_ENV === 'test'
Expand All @@ -36,24 +33,21 @@ const getStudioPort = () => {
}

const processRenderRscStream = async (
pipeable: PassThrough,
readable: ReadableStream,
): Promise<string> => {
return new Promise((resolve, reject) => {
const chunks = [] as any

pipeable.on('data', (chunk: any) => {
chunks.push(chunk)
})
const chunks: Uint8Array[] = []

pipeable.on('end', () => {
const resultBuffer = Buffer.concat(chunks)
const resultString = resultBuffer.toString('utf-8')
resolve(resultString)
const writable = new WritableStream({
write(chunk) {
chunks.push(chunk)
},
close() {
resolve(Buffer.concat(chunks).toString('utf8'))
},
})

pipeable.on('error', (error) => {
reject(error)
})
readable.pipeTo(writable).catch((error) => reject(error))
})
}

Expand Down Expand Up @@ -100,11 +94,11 @@ const postFlightToStudio = (payload: string, metadata: Record<string, any>) => {
}

const createStudioFlightHandler = (
pipeable: PassThrough,
readable: ReadableStream,
metadata: Record<string, any>,
) => {
if (shouldSendToStudio()) {
processRenderRscStream(pipeable)
processRenderRscStream(readable)
.then((payload) => {
console.debug('Sending RSC Rendered stream to Studio')
postFlightToStudio(payload, metadata)
Expand Down Expand Up @@ -136,21 +130,11 @@ export const sendRscFlightToStudio = async (input: StudioRenderInput) => {
const startedAt = Date.now()
const start = performance.now()

// We construct the URL for the flight request from props
// e.g. http://localhost:8910/rw-rsc/__rwjs__Routes?props=location={pathname:"/about",search:"?foo=bar""}
// becomes http://localhost:8910/about?foo=bar
const fullUrl = getFullUrlForFlightRequest(req, props)

const pipeable = renderRsc({
const readable = await renderRscToStream({
rscId,
props,
rsaId,
args,
serverState: {
headersInit: Object.fromEntries(getRequestHeaders().entries()),
serverAuthState: getAuthState(),
fullUrl,
},
})
const endedAt = Date.now()
const end = performance.now()
Expand Down Expand Up @@ -178,7 +162,7 @@ export const sendRscFlightToStudio = async (input: StudioRenderInput) => {
}

// send rendered request to Studio
createStudioFlightHandler(pipeable as PassThrough, metadata)
createStudioFlightHandler(readable, metadata)
} catch (e) {
if (e instanceof Error) {
console.error('An error occurred rendering RSC and sending to Studio:', e)
Expand Down
114 changes: 0 additions & 114 deletions packages/vite/src/rsc/rscWorker.ts

This file was deleted.

Loading
Loading