diff --git a/packages/plugin-rsc/AGENTS.md b/packages/plugin-rsc/AGENTS.md index db4b0097e..8da5507e1 100644 --- a/packages/plugin-rsc/AGENTS.md +++ b/packages/plugin-rsc/AGENTS.md @@ -11,12 +11,21 @@ Before creating or changing a conventional RSC example, use [`examples/starter-e ## Quick Reference for AI Agents -### Essential Commands +### Fresh Worktree Setup ```bash -# inside packages/plugin-rsc directory -pnpm build # build package +# from the repository root +pnpm install +pnpm build +``` + +Run the full workspace build before RSC E2E tests because examples use other workspace packages, such as `@vitejs/plugin-react`. + +### Package Commands + +```bash +# inside packages/plugin-rsc pnpm tsc # typecheck -pnpm test # Run unit tests -pnpm test-e2e # Run e2e tests +pnpm test --run # run unit tests +pnpm test-e2e # run E2E tests ``` diff --git a/packages/plugin-rsc/CONTRIBUTING.md b/packages/plugin-rsc/CONTRIBUTING.md index 3102292e6..b16ab9d89 100644 --- a/packages/plugin-rsc/CONTRIBUTING.md +++ b/packages/plugin-rsc/CONTRIBUTING.md @@ -41,8 +41,12 @@ Use colocated unit tests for self-contained transforms and utilities. ## Development Workflow ```bash -# Build packages -pnpm dev # pnpm -C packages/plugin-rsc dev +# Install and build from the repository root +pnpm install +pnpm build + +# Watch the RSC package during development +pnpm -C packages/plugin-rsc dev # Type check pnpm -C packages/plugin-rsc tsc diff --git a/packages/plugin-rsc/e2e/fixture.ts b/packages/plugin-rsc/e2e/fixture.ts index e67650676..9e95cdb68 100644 --- a/packages/plugin-rsc/e2e/fixture.ts +++ b/packages/plugin-rsc/e2e/fixture.ts @@ -23,7 +23,7 @@ function runCli(options: { command: string; label?: string } & SpawnOptions) { console.log(styleText('magenta', label), data.toString()) }) const done = new Promise((resolve) => { - child.on('exit', (code) => { + child.on('close', (code) => { if (code !== 0 && code !== 143 && process.platform !== 'win32') { console.log(styleText('magenta', `${label}`), `exit code ${code}`) } @@ -32,15 +32,42 @@ function runCli(options: { command: string; label?: string } & SpawnOptions) { }) async function findPort(): Promise { - let stdout = '' - return new Promise((resolve) => { - child.stdout!.on('data', (data) => { - stdout += stripVTControlCharacters(String(data)) - const match = stdout.match(/http:\/\/localhost:(\d+)/) + let portOutput = '' + return new Promise((resolve, reject) => { + function cleanup() { + child.stdout!.off('data', onData) + child.off('close', onClose) + child.off('error', onError) + } + + function onData(data: Buffer) { + portOutput += stripVTControlCharacters(String(data)) + const match = portOutput.match(/http:\/\/localhost:(\d+)/) if (match) { + cleanup() resolve(Number(match[1])) } - }) + } + + function onClose(code: number | null, signal: NodeJS.Signals | null) { + cleanup() + const details = stderr.trim() || stdout.trim() + reject( + new Error( + `${label} exited with ${code ?? signal ?? 'unknown status'} before publishing a port` + + (details ? `\n${details}` : ''), + ), + ) + } + + function onError(error: Error) { + cleanup() + reject(error) + } + + child.stdout!.on('data', onData) + child.on('close', onClose) + child.on('error', onError) }) }