#!/usr/bin/env bash set -Eeuo pipefail IFS=$'\n\t' ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" log() { echo "[bff:dev] $*" } kill_tree() { local pid="$1" if [ -z "${pid:-}" ]; then return 0; fi if kill -0 "$pid" >/dev/null 2>&1; then kill "$pid" >/dev/null 2>&1 || true # Give it a moment to exit gracefully sleep 0.2 || true kill -9 "$pid" >/dev/null 2>&1 || true fi } PID_BUILD="" PID_ALIAS="" PID_NODE="" cleanup() { log "Stopping dev processes..." kill_tree "$PID_NODE" kill_tree "$PID_ALIAS" kill_tree "$PID_BUILD" } trap cleanup EXIT trap 'exit 130' INT trap 'exit 143' TERM cd "$ROOT_DIR" log "Starting TypeScript build watcher (tsc --watch)..." pnpm run -s dev:build:watch & PID_BUILD=$! # Wait for initial output to exist MAIN_FILE="$ROOT_DIR/dist/main.js" WAIT_SECS="${BFF_BUILD_WAIT_SECS:-180}" log "Waiting for initial build output: $MAIN_FILE (timeout: ${WAIT_SECS}s)" loops=$((WAIT_SECS * 4)) for ((i=1; i<=loops; i++)); do if [ -f "$MAIN_FILE" ]; then break fi sleep 0.25 if ! kill -0 "$PID_BUILD" >/dev/null 2>&1; then log "Build watcher exited unexpectedly." exit 1 fi done if [ ! -f "$MAIN_FILE" ]; then log "Timed out waiting for $MAIN_FILE" log "Tip: if this keeps happening, run: pnpm -C \"$ROOT_DIR\" run build" exit 1 fi log "Rewriting path aliases in dist (tsc-alias)..." pnpm run -s dev:alias log "Starting alias rewriter watcher (tsc-alias -w)..." pnpm run -s dev:alias:watch & PID_ALIAS=$! RUN_SCRIPT="${BFF_NODE_RUN_SCRIPT:-dev:run:watch}" log "Starting Node runtime watcher ($RUN_SCRIPT)..." pnpm run -s "$RUN_SCRIPT" & PID_NODE=$! # If any process exits, stop the rest (compatible with bash 3.2) while true; do for pid in "$PID_BUILD" "$PID_ALIAS" "$PID_NODE"; do if ! kill -0 "$pid" 2>/dev/null; then wait "$pid" 2>/dev/null || true exit_code=$? log "A dev process exited (code=$exit_code). Shutting down." exit "$exit_code" fi done sleep 1 done