|
| 1 | +# Cedar Phase 5 — Implementation Handoff Note |
| 2 | + |
| 3 | +**Date**: 2026-05-05 |
| 4 | +**Status**: Phase 5 implementation is functionally complete. Build passes, tests pass. |
| 5 | +**Open architectural question**: Vite Environment API alignment. |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## What was implemented today |
| 10 | + |
| 11 | +### Workstream 1: Single-Listener Dev Server |
| 12 | + |
| 13 | +- Created `packages/vite/src/apiDevMiddleware.ts` — Vite SSR dev server with inline fetch-native API dispatch. Loads functions via `ssrLoadModule`, handles GraphQL Yoga, wraps legacy Lambda handlers. |
| 14 | +- Updated `packages/vite/src/cedar-unified-dev.ts` — one Vite dev server on a single visible port. API requests intercepted via `configureServer` middleware and dispatched through `@whatwg-node/server`'s `createServerAdapter` (public API), which handles the full `IncomingMessage → Request → Response → ServerResponse` cycle. |
| 15 | +- **Removed**: `apiDevServer.ts` (Phase 4 Fastify-based dev server) and `cedarDevDispatcherPlugin` (Phase 4 plugin that was never installed). |
| 16 | + |
| 17 | +### Workstream 2: buildApp() with Declared Environments |
| 18 | + |
| 19 | +- Created `packages/vite/src/buildApp.ts` — `buildCedarApp()` uses Vite's `createBuilder().buildApp()` with declared `client` and `api` environments. |
| 20 | +- Updated `packages/cli/src/commands/build/buildHandler.ts` — default (non-streaming-SSR) build path uses `buildCedarApp()`. Falls back to legacy separate builds when streaming SSR is enabled. |
| 21 | +- Updated build tests to reflect unified task names. |
| 22 | + |
| 23 | +### Cleanup |
| 24 | + |
| 25 | +- Removed dead code (`apiDevServer.ts`, `cedarDevDispatcherPlugin` file and export). |
| 26 | +- Removed `./apiDevServer` from `packages/vite/package.json` exports. |
| 27 | +- Updated planning docs (`phase-5-detailed-plan.md`, `integration-plan-refined.md`, `project-overview.md`) to reflect actual implementation. |
| 28 | + |
| 29 | +--- |
| 30 | + |
| 31 | +## Test Results |
| 32 | + |
| 33 | +- ✅ All 90 Vite package tests pass |
| 34 | +- ✅ All 17 relevant CLI tests pass (build + dev) |
| 35 | +- ✅ Both `@cedarjs/vite` and `@cedarjs/cli` build successfully |
| 36 | + |
| 37 | +--- |
| 38 | + |
| 39 | +## Important Architectural Insight (for tomorrow) |
| 40 | + |
| 41 | +Our current implementation uses the **Vite 5-style manual middleware pattern**: |
| 42 | + |
| 43 | +- `cedar-unified-dev.ts` creates one Vite dev server |
| 44 | +- `apiDevMiddleware.ts` creates a **second** internal Vite SSR dev server (`createServer({ configFile: false, middlewareMode: true })`) |
| 45 | +- Middleware delegates to a cached `createServerAdapter(apiHandler)` instance, which internally handles the `IncomingMessage → Request → Response → ServerResponse` cycle |
| 46 | + |
| 47 | +**Vite 6+ recommends the Environment API pattern** for full-stack frameworks: |
| 48 | + |
| 49 | +- Define `api` as a **declared Vite environment** in the dev server config |
| 50 | +- Use `createFetchableDevEnvironment` for Fetch-native runtimes |
| 51 | +- The environment's `handleRequest(Request)` returns `Response` |
| 52 | +- Middleware calls `server.environments.api.dispatchFetch(request)` |
| 53 | +- For module loading: `transformRequest(url)` returns transformed code; the runtime evaluates it |
| 54 | + |
| 55 | +**Key difference**: `FetchableDevEnvironment` does NOT have `runner.import()` (that's `RunnableDevEnvironment`). The Fetchable model is "Vite transforms, your runtime executes" via `environment.transformRequest(url)`. |
| 56 | + |
| 57 | +**Open question**: ~~Should Cedar refactor to `FetchableDevEnvironment`?~~ **Answer: No, not for the default Node path.** |
| 58 | + |
| 59 | +After reading [vitejs/vite Discussion #18191](https://github.com/vitejs/vite/discussions/18191), the picture is clear: |
| 60 | + |
| 61 | +- `FetchableDevEnvironment` is designed for **non-Node runtimes** (Cloudflare Workers, Deno, Bun edge) where the app code runs in a different process/runtime than the Vite dev server. |
| 62 | +- Vite explicitly decided **NOT** to make the default SSR environment a `FetchableDevEnvironment`. The default SSR path is `RunnableDevEnvironment` (with `.import()` / `.runner`). |
| 63 | +- `transformRequest(url)` is **not mentioned** in the discussion as a module-loading replacement. |
| 64 | +- Our current approach (`createServer({ middlewareMode: true })` + `ssrLoadModule`) is functionally equivalent to `RunnableDevEnvironment` and is the correct pattern for Node. |
| 65 | + |
| 66 | +**Conclusion**: Cedar's current implementation is architecturally sound for Node. `FetchableDevEnvironment` would only be needed if Cedar wants to support **dev-mode simulation of edge runtimes** (e.g. running API code in `workerd` locally to match Cloudflare Workers production). |
| 67 | + |
| 68 | +**Reference**: See `docs/implementation-plans/universal-deploy-phase-5-detailed-plan.md` and `docs/implementation-plans/universal-deploy-integration-plan-refined.md` for updated Phase 5 descriptions. |
| 69 | + |
| 70 | +--- |
| 71 | + |
| 72 | +## Next Steps (suggested) |
| 73 | + |
| 74 | +1. Validate the single-listener dev server in `local-testing-project` (`cedar dev --ud`) |
| 75 | +2. Validate `cedar build` produces correct output for both web and API |
| 76 | +3. Decide whether to refactor to `FetchableDevEnvironment` or keep current approach |
| 77 | +4. If keeping current approach: add documentation explaining the architectural choice |
| 78 | +5. If refactoring: design module execution layer for `transformRequest` output |
| 79 | + |
| 80 | +--- |
| 81 | + |
| 82 | +## Files Changed Today |
| 83 | + |
| 84 | +- `packages/vite/src/apiDevMiddleware.ts` (new) |
| 85 | +- `packages/vite/src/cedar-unified-dev.ts` (refactored) |
| 86 | +- `packages/vite/src/buildApp.ts` (new) |
| 87 | +- `packages/vite/src/build/build.ts` (updated) |
| 88 | +- `packages/vite/src/index.ts` (removed exports) |
| 89 | +- `packages/vite/package.json` (removed `./apiDevServer` export) |
| 90 | +- `packages/cli/src/commands/build/buildHandler.ts` (refactored) |
| 91 | +- `packages/cli/src/commands/build/__tests__/build.test.ts` (updated) |
| 92 | +- `docs/implementation-plans/universal-deploy-phase-5-detailed-plan.md` (updated) |
| 93 | +- `docs/implementation-plans/universal-deploy-integration-plan-refined.md` (updated) |
| 94 | +- `docs/implementation-docs/2026-03-26-cedarjs-project-overview.md` (updated) |
| 95 | +- Deleted: `packages/vite/src/apiDevServer.ts` |
| 96 | +- Deleted: `packages/vite/src/plugins/vite-plugin-cedar-dev-dispatcher.ts` |
0 commit comments