revert: drop vite middleware, add watch build instead
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
"packageManager": "pnpm@10.33.0",
|
||||
"scripts": {
|
||||
"dev": "tsx packages/cli/src/bin.ts",
|
||||
"dev:ui": "pnpm --filter @hai/dashboard dev",
|
||||
"build": "pnpm -r build",
|
||||
"typecheck": "pnpm -r typecheck"
|
||||
},
|
||||
|
||||
@@ -25,7 +25,7 @@ export async function runDashboard(port: number, opts: { engine?: boolean; open?
|
||||
});
|
||||
|
||||
// Start the web server with AI merge wired in
|
||||
const app = await createServer(store, { onMerge, dev: true });
|
||||
const app = createServer(store, { onMerge });
|
||||
|
||||
// Clean shutdown for file watcher when engine is not active
|
||||
if (!opts.engine) {
|
||||
|
||||
@@ -8,21 +8,21 @@
|
||||
"scripts": {
|
||||
"build": "vite build && tsc",
|
||||
"build:client": "vite build",
|
||||
"dev:client": "vite",
|
||||
"dev": "vite build --watch",
|
||||
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.app.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hai/core": "workspace:*",
|
||||
"@vitejs/plugin-react": "^4.3.0",
|
||||
"express": "^5.1.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"vite": "^6.0.0"
|
||||
"react-dom": "^19.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^5.0.0",
|
||||
"@types/react": "^19.0.0",
|
||||
"@types/react-dom": "^19.0.0",
|
||||
"typescript": "^5.7.0"
|
||||
"@vitejs/plugin-react": "^4.3.0",
|
||||
"typescript": "^5.7.0",
|
||||
"vite": "^6.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import express from "express";
|
||||
import { join, dirname } from "node:path";
|
||||
import { existsSync } from "node:fs";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import type { TaskStore, MergeResult } from "@hai/core";
|
||||
import { createApiRoutes } from "./routes.js";
|
||||
@@ -14,51 +13,31 @@ export interface ServerOptions {
|
||||
onMerge?: (taskId: string) => Promise<MergeResult>;
|
||||
/** Maximum concurrent worktrees / execution slots (default 2) */
|
||||
maxConcurrent?: number;
|
||||
/** Enable Vite dev server with HMR (default: false) */
|
||||
dev?: boolean;
|
||||
}
|
||||
|
||||
export async function createServer(store: TaskStore, options?: ServerOptions) {
|
||||
export function createServer(store: TaskStore, options?: ServerOptions) {
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
|
||||
// SSE endpoint (before Vite middleware so it's not intercepted)
|
||||
// Serve built React app
|
||||
const clientDir = existsSync(join(__dirname, "..", "dist", "client"))
|
||||
? join(__dirname, "..", "dist", "client")
|
||||
: existsSync(join(__dirname, "..", "client"))
|
||||
? join(__dirname, "..", "client")
|
||||
: join(__dirname, "..", "public");
|
||||
|
||||
app.use(express.static(clientDir));
|
||||
|
||||
// SSE endpoint
|
||||
app.get("/api/events", createSSE(store));
|
||||
|
||||
// REST API
|
||||
app.use("/api", createApiRoutes(store, options));
|
||||
|
||||
if (options?.dev) {
|
||||
// Dev mode: Vite middleware with HMR
|
||||
const { createServer: createViteServer } = await import("vite");
|
||||
const appDir = join(__dirname, "..", "app");
|
||||
const vite = await createViteServer({
|
||||
root: appDir,
|
||||
server: { middlewareMode: true },
|
||||
appType: "custom",
|
||||
});
|
||||
app.use(vite.middlewares);
|
||||
|
||||
// SPA fallback — serve index.html through Vite's transform pipeline
|
||||
app.use(async (_req, res) => {
|
||||
const htmlPath = join(appDir, "index.html");
|
||||
let html = await readFile(htmlPath, "utf-8");
|
||||
html = await vite.transformIndexHtml(_req.originalUrl, html);
|
||||
res.status(200).set({ "Content-Type": "text/html" }).end(html);
|
||||
});
|
||||
} else {
|
||||
// Production: serve pre-built static files
|
||||
const clientDir = existsSync(join(__dirname, "..", "dist", "client"))
|
||||
? join(__dirname, "..", "dist", "client")
|
||||
: existsSync(join(__dirname, "..", "client"))
|
||||
? join(__dirname, "..", "client")
|
||||
: join(__dirname, "..", "public");
|
||||
|
||||
app.use(express.static(clientDir));
|
||||
app.get("/{*splat}", (_req, res) => {
|
||||
res.sendFile(join(clientDir, "index.html"));
|
||||
});
|
||||
}
|
||||
// SPA fallback
|
||||
app.get("/{*splat}", (_req, res) => {
|
||||
res.sendFile(join(clientDir, "index.html"));
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
12
pnpm-lock.yaml
generated
12
pnpm-lock.yaml
generated
@@ -48,9 +48,6 @@ importers:
|
||||
'@hai/core':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
'@vitejs/plugin-react':
|
||||
specifier: ^4.3.0
|
||||
version: 4.7.0(vite@6.4.1(@types/node@25.5.0)(tsx@4.21.0)(yaml@2.8.3))
|
||||
express:
|
||||
specifier: ^5.1.0
|
||||
version: 5.2.1
|
||||
@@ -60,9 +57,6 @@ importers:
|
||||
react-dom:
|
||||
specifier: ^19.0.0
|
||||
version: 19.2.4(react@19.2.4)
|
||||
vite:
|
||||
specifier: ^6.0.0
|
||||
version: 6.4.1(@types/node@25.5.0)(tsx@4.21.0)(yaml@2.8.3)
|
||||
devDependencies:
|
||||
'@types/express':
|
||||
specifier: ^5.0.0
|
||||
@@ -73,9 +67,15 @@ importers:
|
||||
'@types/react-dom':
|
||||
specifier: ^19.0.0
|
||||
version: 19.2.3(@types/react@19.2.14)
|
||||
'@vitejs/plugin-react':
|
||||
specifier: ^4.3.0
|
||||
version: 4.7.0(vite@6.4.1(@types/node@25.5.0)(tsx@4.21.0)(yaml@2.8.3))
|
||||
typescript:
|
||||
specifier: ^5.7.0
|
||||
version: 5.9.3
|
||||
vite:
|
||||
specifier: ^6.0.0
|
||||
version: 6.4.1(@types/node@25.5.0)(tsx@4.21.0)(yaml@2.8.3)
|
||||
|
||||
packages/engine:
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user