#!/bin/sh set -eu APP_ROOT="${APP_ROOT:-/app}" STATE_DIR="${WORK_SERVER_STATE_DIR:-/tmp/work-server-runtime}" LOCK_FILE="$APP_ROOT/package-lock.json" LOCK_HASH_FILE="$STATE_DIR/package-lock.sha256" CHILD_PID="" STOP_REQUESTED="0" RELOAD_REQUESTED="0" mkdir -p "$STATE_DIR" cd "$APP_ROOT" log() { printf '[work-server-supervisor] %s\n' "$*" } ensure_dependencies() { if [ ! -f "$LOCK_FILE" ]; then log "package-lock.json not found; skipping npm ci" return 0 fi CURRENT_HASH=$(sha256sum "$LOCK_FILE" | awk '{print $1}') PREVIOUS_HASH="" if [ -f "$LOCK_HASH_FILE" ]; then PREVIOUS_HASH=$(cat "$LOCK_HASH_FILE") fi if [ ! -d "$APP_ROOT/node_modules" ] || [ "$CURRENT_HASH" != "$PREVIOUS_HASH" ]; then log "installing dependencies" npm ci --legacy-peer-deps printf '%s' "$CURRENT_HASH" >"$LOCK_HASH_FILE" fi } prepare_runtime() { ensure_dependencies log "building latest source" npm run build } start_child() { log "starting server process" npm run start & CHILD_PID=$! } request_reload() { log "reload requested" if prepare_runtime; then RELOAD_REQUESTED="1" if [ -n "$CHILD_PID" ]; then kill -TERM "$CHILD_PID" 2>/dev/null || true fi else log "reload aborted because build failed; keeping current process" fi } request_stop() { STOP_REQUESTED="1" log "shutdown requested" if [ -n "$CHILD_PID" ]; then kill -TERM "$CHILD_PID" 2>/dev/null || true fi } trap 'request_reload' HUP trap 'request_stop' INT TERM prepare_runtime while :; do start_child set +e wait "$CHILD_PID" EXIT_CODE=$? set -e CHILD_PID="" if [ "$STOP_REQUESTED" = "1" ]; then exit "$EXIT_CODE" fi if [ "$RELOAD_REQUESTED" = "1" ]; then RELOAD_REQUESTED="0" continue fi log "server exited unexpectedly with code $EXIT_CODE; restarting in 2 seconds" sleep 2 done