1
0
forked from baron/baron-sso
Files
baron-sso/userfront/scripts/dev-server.sh

163 lines
4.5 KiB
Bash

#!/usr/bin/env sh
set -eu
cd /workspace
/bin/sh ./scripts/sync_userfront_locales.sh
cd /workspace/userfront
USERFRONT_INTERNAL_PORT="${USERFRONT_INTERNAL_PORT:-5000}"
USERFRONT_FLUTTER_RUN_FLAGS="${USERFRONT_FLUTTER_RUN_FLAGS:---debug}"
USERFRONT_BOOT_WARMUP_ATTEMPTS="${USERFRONT_BOOT_WARMUP_ATTEMPTS:-120}"
USERFRONT_BOOT_WARMUP_INTERVAL_SECONDS="${USERFRONT_BOOT_WARMUP_INTERVAL_SECONDS:-0.5}"
USERFRONT_BOOT_WARMUP_LOCALES="${USERFRONT_BOOT_WARMUP_LOCALES:-ko en}"
USERFRONT_BOOT_WARMUP_VIEWPORTS="${USERFRONT_BOOT_WARMUP_VIEWPORTS:-mobile:390 desktop:1440}"
warm_get() {
path="$1"
locale="$2"
viewport="$3"
width="${viewport#*:}"
if [ "$width" = "$viewport" ]; then
width=""
fi
wget -qO- \
--header="Accept-Language: $locale" \
--header="Viewport-Width: $width" \
"http://127.0.0.1:${USERFRONT_INTERNAL_PORT}${path}" >/dev/null 2>&1
}
wait_for_userfront_build() {
flutter_pid="$1"
attempt=1
while [ "$attempt" -le "$USERFRONT_BOOT_WARMUP_ATTEMPTS" ]; do
if [ -f "build/web/index.html" ]; then
return 0
fi
if ! kill -0 "$flutter_pid" 2>/dev/null; then
echo "[userfront-boot] warmup skipped because flutter exited before build/web/index.html was ready" >&2
return 1
fi
attempt=$((attempt + 1))
sleep "$USERFRONT_BOOT_WARMUP_INTERVAL_SECONDS"
done
echo "[userfront-boot] warmup skipped after ${USERFRONT_BOOT_WARMUP_ATTEMPTS} build readiness attempts" >&2
return 1
}
reset_userfront_service_worker() {
cat > build/web/flutter_service_worker.js <<'EOF'
self.addEventListener("install", (event) => {
self.skipWaiting();
});
self.addEventListener("activate", (event) => {
event.waitUntil(
(async () => {
if (self.caches) {
const keys = await self.caches.keys();
await Promise.all(
keys
.filter(
(key) =>
key.indexOf("baron-userfront-") === 0 ||
key.indexOf("flutter-app-cache") === 0,
)
.map((key) => self.caches.delete(key)),
);
}
await self.registration.unregister();
const clients = await self.clients.matchAll({
type: "window",
includeUncontrolled: true,
});
await Promise.all(clients.map((client) => client.navigate(client.url)));
})(),
);
});
EOF
}
warm_userfront_once() {
flutter_pid="$1"
attempt=1
started_at="$(date +%s)"
if ! wait_for_userfront_build "$flutter_pid"; then
return 0
fi
reset_userfront_service_worker
while [ "$attempt" -le "$USERFRONT_BOOT_WARMUP_ATTEMPTS" ]; do
if wget -qO- "http://127.0.0.1:${USERFRONT_INTERNAL_PORT}/flutter_bootstrap.js" >/dev/null 2>&1; then
break
fi
if ! kill -0 "$flutter_pid" 2>/dev/null; then
echo "[userfront-boot] warmup skipped because flutter exited before readiness" >&2
return 0
fi
attempt=$((attempt + 1))
sleep "$USERFRONT_BOOT_WARMUP_INTERVAL_SECONDS"
done
if [ "$attempt" -gt "$USERFRONT_BOOT_WARMUP_ATTEMPTS" ]; then
echo "[userfront-boot] warmup skipped after ${USERFRONT_BOOT_WARMUP_ATTEMPTS} readiness attempts" >&2
return 0
fi
echo "[userfront-boot] one-shot warmup starting locales=\"${USERFRONT_BOOT_WARMUP_LOCALES}\" viewports=\"${USERFRONT_BOOT_WARMUP_VIEWPORTS}\"" >&2
for locale in $USERFRONT_BOOT_WARMUP_LOCALES; do
for viewport in $USERFRONT_BOOT_WARMUP_VIEWPORTS; do
warm_get "/${locale}/signin" "$locale" "$viewport" || true
done
done
for asset in \
/ \
/flutter_bootstrap.js \
/main.dart.mjs \
/main.dart.wasm \
/canvaskit/skwasm.js \
/canvaskit/skwasm.wasm \
/canvaskit/skwasm_heavy.js \
/canvaskit/skwasm_heavy.wasm \
/assets/AssetManifest.bin.json \
/assets/FontManifest.json
do
wget -qO- "http://127.0.0.1:${USERFRONT_INTERNAL_PORT}${asset}" >/dev/null 2>&1 || true
done
finished_at="$(date +%s)"
elapsed_seconds=$((finished_at - started_at))
echo "[userfront-boot] one-shot warmup completed in ${elapsed_seconds}s" >&2
}
set -- flutter run \
-d web-server \
--web-hostname 0.0.0.0 \
--web-port "${USERFRONT_INTERNAL_PORT}" \
--wasm \
--dart-define=BACKEND_URL="${BACKEND_URL:-}" \
--dart-define=CLIENT_LOG_DEBUG="${CLIENT_LOG_DEBUG:-false}" \
--dart-define=APP_ENV="${APP_ENV:-dev}" \
--dart-define=USERFRONT_URL="${USERFRONT_URL:-}" \
${USERFRONT_FLUTTER_RUN_FLAGS} \
--no-web-resources-cdn
"$@" &
flutter_pid="$!"
terminate() {
kill "$flutter_pid" 2>/dev/null || true
wait "$flutter_pid" 2>/dev/null || true
}
trap terminate INT TERM
warm_userfront_once "$flutter_pid"
wait "$flutter_pid"