diff --git a/src/server/apps.ts b/src/server/apps.ts index 3af2a33..c640fef 100644 --- a/src/server/apps.ts +++ b/src/server/apps.ts @@ -1,5 +1,8 @@ import type { Subprocess } from 'bun' -import { existsSync, readdirSync, readFileSync, writeFileSync, watch } from 'fs' +import { + existsSync, readdirSync, readFileSync, writeFileSync, + statSync, watch +} from 'fs' import { join } from 'path' import type { App as SharedApp, AppState, LogLine } from '../shared/types' @@ -208,9 +211,8 @@ export const stopApp = (dir: string) => { } const watchAppsDir = () => { - watch(APPS_DIR, { recursive: true }, (_event, filename) => { + watch(APPS_DIR, { recursive: true }, (event, filename) => { if (!filename) return - if (!filename.includes('/')) return // Extract the app directory name from the path (e.g., "myapp/package.json" -> "myapp") const dir = filename.split('/')[0]! @@ -230,6 +232,13 @@ const watchAppsDir = () => { const app = _apps.get(dir)! + // check if app was deleted + if (!isDir(join(APPS_DIR, dir))) { + _apps.delete(dir) + update() + return + } + // Only care about package.json changes for existing apps if (!filename.endsWith('package.json')) return @@ -256,6 +265,7 @@ const watchAppsDir = () => { app.state = 'invalid' update() } + if (!error && app.state === 'invalid') { app.state = 'stopped' update() @@ -263,6 +273,14 @@ const watchAppsDir = () => { }) } +function isDir(path: string): boolean { + try { + return statSync(path).isDirectory() + } catch { + return false + } +} + export const initApps = () => { discoverApps() runApps()