|
| 1 | +import { readdirSync, readFileSync } from 'fs'; |
| 2 | +import { join } from 'path'; |
| 3 | +import { expect, it } from 'vitest'; |
| 4 | +import { createRunner } from '../../../../runner'; |
| 5 | + |
| 6 | +function readBundles(dir: string): string { |
| 7 | + return readdirSync(dir, { withFileTypes: true, recursive: true }) |
| 8 | + .filter(entry => entry.isFile() && /\.m?js$/.test(entry.name)) |
| 9 | + .map(entry => readFileSync(join(entry.parentPath, entry.name), 'utf8')) |
| 10 | + .join('\n'); |
| 11 | +} |
| 12 | + |
| 13 | +// Regression test: orchestrion splices `node:diagnostics_channel` calls into |
| 14 | +// instrumented modules, which only exist server-side. When a worker ships |
| 15 | +// browser assets, Vite produces a `client` bundle next to the server (worker) |
| 16 | +// bundle — and the injected `tracingChannel` calls used to land in the client |
| 17 | +// bundle too, where they throw `X is not a function` in the browser. |
| 18 | +it('injects diagnostics_channel calls into the server bundle only, not the client bundle', async ({ signal }) => { |
| 19 | + const runner = createRunner(__dirname).start(signal); |
| 20 | + |
| 21 | + // Waits for `vite build` + wrangler boot and proves the instrumented worker |
| 22 | + // still runs. |
| 23 | + const response = await runner.makeRequest<string>('get', '/worker'); |
| 24 | + expect(response).toBe('streamText: function'); |
| 25 | + |
| 26 | + // The worker imports `ai`, so the server bundle must actually be |
| 27 | + // instrumented — otherwise a plugin that never runs would also pass. |
| 28 | + const workerBundle = readBundles(join(__dirname, 'dist', 'cloudflare_vite_dc_client_build')); |
| 29 | + expect(workerBundle).toContain('orchestrion:ai:streamText'); |
| 30 | + |
| 31 | + const clientBundle = readBundles(join(__dirname, 'dist', 'client')); |
| 32 | + expect(clientBundle).not.toContain('orchestrion:ai'); |
| 33 | +}); |
0 commit comments