From 14e0b361032b50cd84c5a8081ebb56c843ea5bb2 Mon Sep 17 00:00:00 2001 From: Jordon Leach Date: Sat, 23 Nov 2024 10:07:15 -0500 Subject: [PATCH] Refactor lawndon-pi build and deployment (#22) * Refactor builds * Refactor lawndon-pi build and deployment --- .github/workflows/build-lawndon.yaml | 108 ++++++++++ .github/workflows/build-lawndon.yml | 82 ------- .github/workflows/{tests.yml => tests.yaml} | 12 +- pi/Dockerfile.server | 27 +++ pi/Dockerfile.ui | 22 ++ pi/docker-compose.yaml | 28 +++ pi/package.json | 3 +- pi/server/.env.dev | 2 + pi/server/.env.prod | 2 + pi/server/eslint.config.js | 1 - pi/server/package.json | 8 +- pi/server/pnpm-lock.yaml | 58 +++-- pi/server/src/server.ts | 38 ++-- pi/server/tsconfig.json | 7 +- pi/ui/env.d.ts | 2 + pi/ui/nginx.conf | 63 ++++++ pi/ui/package.json | 16 +- pi/ui/pnpm-lock.yaml | 228 ++++++++++---------- pi/ui/src/components/UWBVisualization.vue | 36 ++-- pi/ui/src/main.ts | 3 +- 20 files changed, 465 insertions(+), 281 deletions(-) create mode 100644 .github/workflows/build-lawndon.yaml delete mode 100644 .github/workflows/build-lawndon.yml rename .github/workflows/{tests.yml => tests.yaml} (86%) create mode 100644 pi/Dockerfile.server create mode 100644 pi/Dockerfile.ui create mode 100644 pi/docker-compose.yaml create mode 100644 pi/server/.env.dev create mode 100644 pi/server/.env.prod create mode 100644 pi/ui/nginx.conf diff --git a/.github/workflows/build-lawndon.yaml b/.github/workflows/build-lawndon.yaml new file mode 100644 index 0000000..4aa849b --- /dev/null +++ b/.github/workflows/build-lawndon.yaml @@ -0,0 +1,108 @@ +name: Build Lawndon + +on: + workflow_dispatch: + release: + types: [released] + +jobs: + build-lawndon: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Arduino cli + uses: arduino/setup-arduino-cli@v2 + + - name: Install libraries + run: | + arduino-cli lib install IBusBM Servo + + - name: Compile Lawndon + uses: arduino/compile-sketches@v1 + with: + fqbn: "arduino:avr:mega" + libraries: | + - name: IBusBM + - name: Servo + sketch-paths: | + - ./lawndon + enable-warnings-report: true + verbose: false + cli-compile-flags: | + - --export-binaries + + - name: Package build + if: startsWith(github.ref, 'refs/tags/') + run: | + for dir in ./lawndon/build/*; do + if [ -d "${dir}" ]; then + tar -czvf "${dir}.tar.gz" -C "${dir}" . + fi + done + + - name: Release build + uses: softprops/action-gh-release@v2 + if: startsWith(github.ref, 'refs/tags/') + with: + files: | + lawndon/build/*.tar.gz + + build-lawndon-pi: + runs-on: ubuntu-latest + needs: build-lawndon + env: + WORKING_DIR: ./pi + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up QEMU for multi-platform builds + uses: docker/setup-qemu-action@v3 + with: + platforms: linux/amd64,linux/arm64 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + buildkitd-flags: --allow-insecure-entitlement security.insecure + install: true + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push server image + uses: docker/build-push-action@v4 + working-directory: ${{ env.WORKING_DIR }} + with: + context: . + file: ./Dockerfile.server + push: true + platforms: linux/amd64,linux/arm64 + tags: | + ghcr.io/${{ github.repository_owner }}/lawndon-pi-server:${{ github.ref_name }} + ghcr.io/${{ github.repository_owner }}/lawndon-pi-server:${{ github.sha }} + + - name: Build and push UI image + uses: docker/build-push-action@v4 + working-directory: ${{ env.WORKING_DIR }} + with: + context: . + file: ./Dockerfile.ui + push: true + platforms: linux/amd64,linux/arm64 + tags: | + ghcr.io/${{ github.repository_owner }}/lawndon-pi-ui:${{ github.ref_name }} + ghcr.io/${{ github.repository_owner }}/lawndon-pi-ui:${{ github.sha }} diff --git a/.github/workflows/build-lawndon.yml b/.github/workflows/build-lawndon.yml deleted file mode 100644 index e1844b9..0000000 --- a/.github/workflows/build-lawndon.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: Build Lawndon - -on: - workflow_dispatch: - release: - types: [released] - -jobs: - build-lawndon: - runs-on: ubuntu-latest - permissions: - contents: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Install Arduino cli - uses: arduino/setup-arduino-cli@v2 - - - name: Install libraries - run: | - arduino-cli lib install IBusBM Servo - - - name: Compile Lawndon - uses: arduino/compile-sketches@v1 - with: - fqbn: "arduino:avr:mega" - libraries: | - - name: IBusBM - - name: Servo - sketch-paths: | - - ./lawndon - enable-warnings-report: true - verbose: false - cli-compile-flags: | - - --export-binaries - - - name: Package build - if: startsWith(github.ref, 'refs/tags/') - run: | - for dir in ./lawndon/build/*; do - if [ -d "${dir}" ]; then - tar -czvf "${dir}.tar.gz" -C "${dir}" . - fi - done - - - name: Release build - uses: softprops/action-gh-release@v2 - if: startsWith(github.ref, 'refs/tags/') - with: - files: | - lawndon/build/*.tar.gz - - build-lawndon-pi: - runs-on: ubuntu-latest - needs: build-lawndon - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: 9 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '22' - - - name: Package application - working-directory: ./pi - run: | - bash package.sh - - - name: Upload release assets - uses: softprops/action-gh-release@v2 - if: startsWith(github.ref, 'refs/tags/') - with: - files: | - ./pi/lawndon-pi.tar.gz \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yaml similarity index 86% rename from .github/workflows/tests.yml rename to .github/workflows/tests.yaml index 087b8f0..5a08d4b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yaml @@ -8,7 +8,7 @@ on: - cron: "0 4 * * 4" jobs: - build-lawndon: + build-lawndon-test: runs-on: ubuntu-latest steps: - name: Checkout repository @@ -41,7 +41,7 @@ jobs: cli-compile-flags: | - --export-binaries - package-lawndon-pi: + build-lawndon-pi-test: runs-on: ubuntu-latest env: WORKING_DIR: ./pi @@ -79,12 +79,12 @@ jobs: run: | pnpm build:server - - name: Run package script + - name: Test Docker build for Server working-directory: ${{ env.WORKING_DIR }} run: | - ./package.sh + docker build --no-cache --file ./Dockerfile.server --tag lawndon-pi-server-test . - - name: Verify package contents + - name: Test Docker build for UI working-directory: ${{ env.WORKING_DIR }} run: | - tar -df lawndon-pi.tar.gz lawndon-pi + docker build --no-cache --file ./Dockerfile.ui --tag lawndon-pi-ui-test . diff --git a/pi/Dockerfile.server b/pi/Dockerfile.server new file mode 100644 index 0000000..02becf6 --- /dev/null +++ b/pi/Dockerfile.server @@ -0,0 +1,27 @@ +# Build stage +FROM node:22-alpine AS build +WORKDIR /usr/src/app + +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +ENV NODE_ENV=production +ENV CONFIG_PATH=/usr/src/app/config + +RUN corepack enable +COPY server/package*.json ./ +RUN pnpm install + +COPY server ./server +WORKDIR /usr/src/app/server +RUN pnpm build + +# Runtime stage +FROM node:22-alpine +WORKDIR /usr/src/app + +COPY --from=build /usr/src/app/server/dist ./dist +COPY --from=build /usr/src/app/server/node_modules ./node_modules +COPY config ./config + +EXPOSE 5000 8080 +CMD ["node", "dist/server.js"] diff --git a/pi/Dockerfile.ui b/pi/Dockerfile.ui new file mode 100644 index 0000000..c05bd32 --- /dev/null +++ b/pi/Dockerfile.ui @@ -0,0 +1,22 @@ +# Build stage +FROM node:22-alpine AS build +WORKDIR /usr/src/app + +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +ENV VITE_NODE_ENV=production + +RUN corepack enable +COPY ui/package*.json ./ +RUN pnpm install + +COPY ui ./ui +WORKDIR /usr/src/app/ui +RUN pnpm build + +# Runtime stage +FROM nginx:alpine +COPY --from=build /usr/src/app/ui/dist /usr/share/nginx/html + +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/pi/docker-compose.yaml b/pi/docker-compose.yaml new file mode 100644 index 0000000..e92adc4 --- /dev/null +++ b/pi/docker-compose.yaml @@ -0,0 +1,28 @@ +services: + server: + image: ghcr.io/jordojordo/lawndon-pi-server:latest + environment: + NODE_ENV: production + CONFIG_PATH: /usr/src/app/config + ports: + - "5000:5000" # WebSocket and API + - "8080:8080" # ESP32 module communication + volumes: + - ./config:/usr/src/app/config:ro # Mount config for anchor positions + networks: + - app_network + + ui: + image: ghcr.io/jordojordo/uwb-ui:latest + environment: + VITE_NODE_ENV: production + ports: + - "80:80" # Expose UI + depends_on: + - server + networks: + - app_network + +networks: + app_network: + driver: bridge diff --git a/pi/package.json b/pi/package.json index cd43688..6fd29c9 100644 --- a/pi/package.json +++ b/pi/package.json @@ -2,6 +2,7 @@ "name": "lawndon-pi", "version": "0.1.0", "private": true, + "type": "module", "scripts": { "install:ui": "pnpm install --prefix ui", "install:server": "pnpm install --prefix server", @@ -10,7 +11,7 @@ "start": "node server/dist/server.js", "dev": "concurrently -k -n SERVER,UI \"pnpm dev:server\" \"pnpm dev:ui\"", "dev:ui": "pnpm --prefix ui dev", - "dev:server": "NODE_ENV=development pnpm --prefix server dev" + "dev:server": "pnpm --prefix server dev" }, "packageManager": "pnpm@9.14.2", "devDependencies": { diff --git a/pi/server/.env.dev b/pi/server/.env.dev new file mode 100644 index 0000000..999e070 --- /dev/null +++ b/pi/server/.env.dev @@ -0,0 +1,2 @@ +NODE_ENV="development" +CONFIG_PATH="../../config" diff --git a/pi/server/.env.prod b/pi/server/.env.prod new file mode 100644 index 0000000..3ede221 --- /dev/null +++ b/pi/server/.env.prod @@ -0,0 +1,2 @@ +NODE_ENV="production" +CONFIG_PATH="../config" diff --git a/pi/server/eslint.config.js b/pi/server/eslint.config.js index 8d54878..ebb590c 100644 --- a/pi/server/eslint.config.js +++ b/pi/server/eslint.config.js @@ -36,7 +36,6 @@ export default [ 'newline-per-chained-call': ['warn', { 'ignoreChainWithDepth': 4 }], 'no-caller': 'warn', 'no-cond-assign': ['warn', 'except-parens'], - 'no-console': 'warn', 'no-debugger': 'warn', 'no-eq-null': 'warn', 'no-eval': 'warn', diff --git a/pi/server/package.json b/pi/server/package.json index 7e3f98a..baef2a1 100644 --- a/pi/server/package.json +++ b/pi/server/package.json @@ -2,12 +2,12 @@ "name": "uwb-server", "version": "0.1.0", "description": "", - "main": "src/server.js", + "main": "dist/server.js", "type": "module", "scripts": { "start": "node dist/server.js", "build": "tsc --outDir dist", - "dev": "nodemon --watch src --ext ts --exec 'node --loader ts-node/esm ./src/server.ts'", + "dev": "NODE_ENV=development nodemon --watch src --ext ts --exec 'node --loader ts-node/esm ./src/server.ts'", "lint": "npx eslint .", "format": "npx eslint . --fix" }, @@ -17,14 +17,16 @@ "packageManager": "pnpm@9.14.2", "dependencies": { "cors": "^2.8.5", + "dotenv": "^16.4.5", "express": "^4.21.1", "mathjs": "^14.0.0", "socket.io": "^4.8.1" }, "devDependencies": { "@types/cors": "^2.8.17", + "@types/dotenv": "^8.2.3", "@types/express": "^5.0.0", - "@types/node": "^22.9.1", + "@types/node": "^22.9.3", "eslint": "^9.15.0", "globals": "^15.12.0", "http-proxy-middleware": "^3.0.3", diff --git a/pi/server/pnpm-lock.yaml b/pi/server/pnpm-lock.yaml index 145967a..c33915a 100644 --- a/pi/server/pnpm-lock.yaml +++ b/pi/server/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: cors: specifier: ^2.8.5 version: 2.8.5 + dotenv: + specifier: ^16.4.5 + version: 16.4.5 express: specifier: ^4.21.1 version: 4.21.1 @@ -24,12 +27,15 @@ importers: '@types/cors': specifier: ^2.8.17 version: 2.8.17 + '@types/dotenv': + specifier: ^8.2.3 + version: 8.2.3 '@types/express': specifier: ^5.0.0 version: 5.0.0 '@types/node': - specifier: ^22.9.1 - version: 22.9.1 + specifier: ^22.9.3 + version: 22.9.3 eslint: specifier: ^9.15.0 version: 9.15.0 @@ -44,10 +50,10 @@ importers: version: 3.1.7 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@22.9.1)(typescript@5.7.2) + version: 10.9.2(@types/node@22.9.3)(typescript@5.7.2) ts-node-dev: specifier: ^2.0.0 - version: 2.0.0(@types/node@22.9.1)(typescript@5.7.2) + version: 2.0.0(@types/node@22.9.3)(typescript@5.7.2) typescript: specifier: ^5.7.2 version: 5.7.2 @@ -153,6 +159,10 @@ packages: '@types/cors@2.8.17': resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} + '@types/dotenv@8.2.3': + resolution: {integrity: sha512-g2FXjlDX/cYuc5CiQvyU/6kkbP1JtmGzh0obW50zD7OKeILVL0NSpPWLXVfqoAGQjom2/SLLx9zHq0KXvD6mbw==} + deprecated: This is a stub types definition. dotenv provides its own type definitions, so you do not need this installed. + '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} @@ -174,8 +184,8 @@ packages: '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - '@types/node@22.9.1': - resolution: {integrity: sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==} + '@types/node@22.9.3': + resolution: {integrity: sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw==} '@types/qs@6.9.17': resolution: {integrity: sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==} @@ -360,6 +370,10 @@ packages: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + dynamic-dedupe@0.3.0: resolution: {integrity: sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==} @@ -1141,23 +1155,27 @@ snapshots: '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.9.1 + '@types/node': 22.9.3 '@types/connect@3.4.38': dependencies: - '@types/node': 22.9.1 + '@types/node': 22.9.3 '@types/cookie@0.4.1': {} '@types/cors@2.8.17': dependencies: - '@types/node': 22.9.1 + '@types/node': 22.9.3 + + '@types/dotenv@8.2.3': + dependencies: + dotenv: 16.4.5 '@types/estree@1.0.6': {} '@types/express-serve-static-core@5.0.1': dependencies: - '@types/node': 22.9.1 + '@types/node': 22.9.3 '@types/qs': 6.9.17 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -1173,13 +1191,13 @@ snapshots: '@types/http-proxy@1.17.15': dependencies: - '@types/node': 22.9.1 + '@types/node': 22.9.3 '@types/json-schema@7.0.15': {} '@types/mime@1.3.5': {} - '@types/node@22.9.1': + '@types/node@22.9.3': dependencies: undici-types: 6.19.8 @@ -1190,12 +1208,12 @@ snapshots: '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.9.1 + '@types/node': 22.9.3 '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 22.9.1 + '@types/node': 22.9.3 '@types/send': 0.17.4 '@types/strip-bom@3.0.0': {} @@ -1363,6 +1381,8 @@ snapshots: diff@4.0.2: {} + dotenv@16.4.5: {} + dynamic-dedupe@0.3.0: dependencies: xtend: 4.0.2 @@ -1379,7 +1399,7 @@ snapshots: dependencies: '@types/cookie': 0.4.1 '@types/cors': 2.8.17 - '@types/node': 22.9.1 + '@types/node': 22.9.3 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.7.2 @@ -1997,7 +2017,7 @@ snapshots: tree-kill@1.2.2: {} - ts-node-dev@2.0.0(@types/node@22.9.1)(typescript@5.7.2): + ts-node-dev@2.0.0(@types/node@22.9.3)(typescript@5.7.2): dependencies: chokidar: 3.6.0 dynamic-dedupe: 0.3.0 @@ -2007,7 +2027,7 @@ snapshots: rimraf: 2.7.1 source-map-support: 0.5.21 tree-kill: 1.2.2 - ts-node: 10.9.2(@types/node@22.9.1)(typescript@5.7.2) + ts-node: 10.9.2(@types/node@22.9.3)(typescript@5.7.2) tsconfig: 7.0.0 typescript: 5.7.2 transitivePeerDependencies: @@ -2015,14 +2035,14 @@ snapshots: - '@swc/wasm' - '@types/node' - ts-node@10.9.2(@types/node@22.9.1)(typescript@5.7.2): + ts-node@10.9.2(@types/node@22.9.3)(typescript@5.7.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 22.9.1 + '@types/node': 22.9.3 acorn: 8.14.0 acorn-walk: 8.3.4 arg: 4.1.3 diff --git a/pi/server/src/server.ts b/pi/server/src/server.ts index b41691e..377773f 100644 --- a/pi/server/src/server.ts +++ b/pi/server/src/server.ts @@ -3,11 +3,9 @@ import { createServer } from 'http'; import { Server } from 'socket.io'; import net from 'net'; import { fileURLToPath } from 'url'; -import { dirname } from 'path'; -import path from 'path'; +import { resolve, join, dirname } from 'path'; import cors from 'cors'; - const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); @@ -17,38 +15,28 @@ const io = new Server(httpServer, { cors: { origin: '*' }, }); -const PORT = 5000; +const PORT = process.env.PORT || 5000; +const TCP_PORT = process.env.TCP_PORT || 8080; + +const CONFIG_PATH = process.env.CONFIG_PATH || resolve(__dirname, '../../config'); + app.use(cors()); // Allow all origins app.get('/api/config', (req, res) => { - res.sendFile(path.join(__dirname, '../../config/anchorPositions.json')); -}); - -// Proxy to Vite dev server in development -if (process.env.NODE_ENV === 'development') { - const { createProxyMiddleware } = await import('http-proxy-middleware'); + const configPath = join(CONFIG_PATH, 'anchorPositions.json'); - app.use( - '/', - createProxyMiddleware({ - target: 'http://localhost:5173', - changeOrigin: true, - ws: true, - }) - ); -} else { - // Serve static files in production - app.use(express.static(path.join(__dirname, '../../ui'))); - app.get('/', (req, res) => { - res.sendFile(path.join(__dirname, '../../ui/index.html')); + res.sendFile(configPath, (err) => { + if (err) { + console.error('Error sending file:', err); + res.status(500).send('Error loading configuration file.'); + } }); -} +}); io.on('connection', (socket) => { console.log('A client connected'); }); -const TCP_PORT = 8080; const tcpServer = net.createServer((socket) => { console.log('UWB data source connected'); diff --git a/pi/server/tsconfig.json b/pi/server/tsconfig.json index 8edc27d..a8c0293 100644 --- a/pi/server/tsconfig.json +++ b/pi/server/tsconfig.json @@ -10,8 +10,11 @@ "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitAny": true, - "skipLibCheck": true + "skipLibCheck": true, + "paths": { + "@src/*": ["./src/*"], + } }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] -} +} \ No newline at end of file diff --git a/pi/ui/env.d.ts b/pi/ui/env.d.ts index 81486fe..27abeaf 100644 --- a/pi/ui/env.d.ts +++ b/pi/ui/env.d.ts @@ -1,6 +1,8 @@ // / interface ImportMetaEnv { + readonly VITE_NODE_ENV: string; + readonly VITE_BACKEND_URL: string; readonly BASE_URL: string; readonly PROD: boolean } diff --git a/pi/ui/nginx.conf b/pi/ui/nginx.conf new file mode 100644 index 0000000..dbd9288 --- /dev/null +++ b/pi/ui/nginx.conf @@ -0,0 +1,63 @@ +user nginx; +worker_processes 1; +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + keepalive_timeout 65; + + server { + listen 80; + server_name localhost; + + location / { + root /app; + index index.html; + try_files $uri $uri/ /index.html; + } + + location /api { + proxy_pass http://server:5000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + access_log /var/log/nginx/api_access.log main; + } + + location /ws/ { + proxy_pass http://server:5000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + access_log /var/log/nginx/websocket_access.log main; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } +} \ No newline at end of file diff --git a/pi/ui/package.json b/pi/ui/package.json index 1e48912..1d55e56 100644 --- a/pi/ui/package.json +++ b/pi/ui/package.json @@ -4,7 +4,7 @@ "private": true, "type": "module", "scripts": { - "dev": "vite", + "dev": "NODE_ENV=development vite", "build": "run-p type-check \"build-only {@}\" --", "preview": "vite preview", "build-only": "vite build", @@ -16,24 +16,24 @@ "d3": "^7.9.0", "pinia": "^2.2.6", "socket.io-client": "^4.8.1", - "vue": "^3.5.12", + "vue": "^3.5.13", "vue-router": "^4.4.5" }, "devDependencies": { "@tsconfig/node22": "^22.0.0", "@types/d3": "^7.4.3", - "@types/node": "^22.9.1", - "@vitejs/plugin-vue": "^5.1.4", + "@types/node": "^22.9.3", + "@vitejs/plugin-vue": "^5.2.0", "@vue/eslint-config-prettier": "^10.1.0", "@vue/eslint-config-typescript": "^14.1.3", "@vue/tsconfig": "^0.6.0", - "eslint": "^9.14.0", - "eslint-plugin-vue": "^9.30.0", + "eslint": "^9.15.0", + "eslint-plugin-vue": "^9.31.0", "npm-run-all2": "^7.0.1", "prettier": "^3.3.3", "typescript": "~5.6.3", - "vite": "^5.4.10", - "vite-plugin-vue-devtools": "^7.5.4", + "vite": "^5.4.11", + "vite-plugin-vue-devtools": "^7.6.4", "vue-tsc": "^2.1.10" }, "packageManager": "pnpm@9.14.2" diff --git a/pi/ui/pnpm-lock.yaml b/pi/ui/pnpm-lock.yaml index 9845b25..2634cac 100644 --- a/pi/ui/pnpm-lock.yaml +++ b/pi/ui/pnpm-lock.yaml @@ -18,7 +18,7 @@ importers: specifier: ^4.8.1 version: 4.8.1 vue: - specifier: ^3.5.12 + specifier: ^3.5.13 version: 3.5.13(typescript@5.6.3) vue-router: specifier: ^4.4.5 @@ -31,11 +31,11 @@ importers: specifier: ^7.4.3 version: 7.4.3 '@types/node': - specifier: ^22.9.1 - version: 22.9.1 + specifier: ^22.9.3 + version: 22.9.3 '@vitejs/plugin-vue': - specifier: ^5.1.4 - version: 5.2.0(vite@5.4.11(@types/node@22.9.1))(vue@3.5.13(typescript@5.6.3)) + specifier: ^5.2.0 + version: 5.2.0(vite@5.4.11(@types/node@22.9.3))(vue@3.5.13(typescript@5.6.3)) '@vue/eslint-config-prettier': specifier: ^10.1.0 version: 10.1.0(eslint@9.15.0)(prettier@3.3.3) @@ -46,10 +46,10 @@ importers: specifier: ^0.6.0 version: 0.6.0(typescript@5.6.3)(vue@3.5.13(typescript@5.6.3)) eslint: - specifier: ^9.14.0 + specifier: ^9.15.0 version: 9.15.0 eslint-plugin-vue: - specifier: ^9.30.0 + specifier: ^9.31.0 version: 9.31.0(eslint@9.15.0) npm-run-all2: specifier: ^7.0.1 @@ -61,11 +61,11 @@ importers: specifier: ~5.6.3 version: 5.6.3 vite: - specifier: ^5.4.10 - version: 5.4.11(@types/node@22.9.1) + specifier: ^5.4.11 + version: 5.4.11(@types/node@22.9.3) vite-plugin-vue-devtools: - specifier: ^7.5.4 - version: 7.6.4(rollup@4.27.3)(vite@5.4.11(@types/node@22.9.1))(vue@3.5.13(typescript@5.6.3)) + specifier: ^7.6.4 + version: 7.6.4(rollup@4.27.4)(vite@5.4.11(@types/node@22.9.3))(vue@3.5.13(typescript@5.6.3)) vue-tsc: specifier: ^2.1.10 version: 2.1.10(typescript@5.6.3) @@ -453,93 +453,93 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.27.3': - resolution: {integrity: sha512-EzxVSkIvCFxUd4Mgm4xR9YXrcp976qVaHnqom/Tgm+vU79k4vV4eYTjmRvGfeoW8m9LVcsAy/lGjcgVegKEhLQ==} + '@rollup/rollup-android-arm-eabi@4.27.4': + resolution: {integrity: sha512-2Y3JT6f5MrQkICUyRVCw4oa0sutfAsgaSsb0Lmmy1Wi2y7X5vT9Euqw4gOsCyy0YfKURBg35nhUKZS4mDcfULw==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.27.3': - resolution: {integrity: sha512-LJc5pDf1wjlt9o/Giaw9Ofl+k/vLUaYsE2zeQGH85giX2F+wn/Cg8b3c5CDP3qmVmeO5NzwVUzQQxwZvC2eQKw==} + '@rollup/rollup-android-arm64@4.27.4': + resolution: {integrity: sha512-wzKRQXISyi9UdCVRqEd0H4cMpzvHYt1f/C3CoIjES6cG++RHKhrBj2+29nPF0IB5kpy9MS71vs07fvrNGAl/iA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.27.3': - resolution: {integrity: sha512-OuRysZ1Mt7wpWJ+aYKblVbJWtVn3Cy52h8nLuNSzTqSesYw1EuN6wKp5NW/4eSre3mp12gqFRXOKTcN3AI3LqA==} + '@rollup/rollup-darwin-arm64@4.27.4': + resolution: {integrity: sha512-PlNiRQapift4LNS8DPUHuDX/IdXiLjf8mc5vdEmUR0fF/pyy2qWwzdLjB+iZquGr8LuN4LnUoSEvKRwjSVYz3Q==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.27.3': - resolution: {integrity: sha512-xW//zjJMlJs2sOrCmXdB4d0uiilZsOdlGQIC/jjmMWT47lkLLoB1nsNhPUcnoqyi5YR6I4h+FjBpILxbEy8JRg==} + '@rollup/rollup-darwin-x64@4.27.4': + resolution: {integrity: sha512-o9bH2dbdgBDJaXWJCDTNDYa171ACUdzpxSZt+u/AAeQ20Nk5x+IhA+zsGmrQtpkLiumRJEYef68gcpn2ooXhSQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.27.3': - resolution: {integrity: sha512-58E0tIcwZ+12nK1WiLzHOD8I0d0kdrY/+o7yFVPRHuVGY3twBwzwDdTIBGRxLmyjciMYl1B/U515GJy+yn46qw==} + '@rollup/rollup-freebsd-arm64@4.27.4': + resolution: {integrity: sha512-NBI2/i2hT9Q+HySSHTBh52da7isru4aAAo6qC3I7QFVsuhxi2gM8t/EI9EVcILiHLj1vfi+VGGPaLOUENn7pmw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.27.3': - resolution: {integrity: sha512-78fohrpcVwTLxg1ZzBMlwEimoAJmY6B+5TsyAZ3Vok7YabRBUvjYTsRXPTjGEvv/mfgVBepbW28OlMEz4w8wGA==} + '@rollup/rollup-freebsd-x64@4.27.4': + resolution: {integrity: sha512-wYcC5ycW2zvqtDYrE7deary2P2UFmSh85PUpAx+dwTCO9uw3sgzD6Gv9n5X4vLaQKsrfTSZZ7Z7uynQozPVvWA==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.27.3': - resolution: {integrity: sha512-h2Ay79YFXyQi+QZKo3ISZDyKaVD7uUvukEHTOft7kh00WF9mxAaxZsNs3o/eukbeKuH35jBvQqrT61fzKfAB/Q==} + '@rollup/rollup-linux-arm-gnueabihf@4.27.4': + resolution: {integrity: sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.27.3': - resolution: {integrity: sha512-Sv2GWmrJfRY57urktVLQ0VKZjNZGogVtASAgosDZ1aUB+ykPxSi3X1nWORL5Jk0sTIIwQiPH7iE3BMi9zGWfkg==} + '@rollup/rollup-linux-arm-musleabihf@4.27.4': + resolution: {integrity: sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.27.3': - resolution: {integrity: sha512-FPoJBLsPW2bDNWjSrwNuTPUt30VnfM8GPGRoLCYKZpPx0xiIEdFip3dH6CqgoT0RnoGXptaNziM0WlKgBc+OWQ==} + '@rollup/rollup-linux-arm64-gnu@4.27.4': + resolution: {integrity: sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.27.3': - resolution: {integrity: sha512-TKxiOvBorYq4sUpA0JT+Fkh+l+G9DScnG5Dqx7wiiqVMiRSkzTclP35pE6eQQYjP4Gc8yEkJGea6rz4qyWhp3g==} + '@rollup/rollup-linux-arm64-musl@4.27.4': + resolution: {integrity: sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.27.3': - resolution: {integrity: sha512-v2M/mPvVUKVOKITa0oCFksnQQ/TqGrT+yD0184/cWHIu0LoIuYHwox0Pm3ccXEz8cEQDLk6FPKd1CCm+PlsISw==} + '@rollup/rollup-linux-powerpc64le-gnu@4.27.4': + resolution: {integrity: sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.27.3': - resolution: {integrity: sha512-LdrI4Yocb1a/tFVkzmOE5WyYRgEBOyEhWYJe4gsDWDiwnjYKjNs7PS6SGlTDB7maOHF4kxevsuNBl2iOcj3b4A==} + '@rollup/rollup-linux-riscv64-gnu@4.27.4': + resolution: {integrity: sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.27.3': - resolution: {integrity: sha512-d4wVu6SXij/jyiwPvI6C4KxdGzuZOvJ6y9VfrcleHTwo68fl8vZC5ZYHsCVPUi4tndCfMlFniWgwonQ5CUpQcA==} + '@rollup/rollup-linux-s390x-gnu@4.27.4': + resolution: {integrity: sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.27.3': - resolution: {integrity: sha512-/6bn6pp1fsCGEY5n3yajmzZQAh+mW4QPItbiWxs69zskBzJuheb3tNynEjL+mKOsUSFK11X4LYF2BwwXnzWleA==} + '@rollup/rollup-linux-x64-gnu@4.27.4': + resolution: {integrity: sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.27.3': - resolution: {integrity: sha512-nBXOfJds8OzUT1qUreT/en3eyOXd2EH5b0wr2bVB5999qHdGKkzGzIyKYaKj02lXk6wpN71ltLIaQpu58YFBoQ==} + '@rollup/rollup-linux-x64-musl@4.27.4': + resolution: {integrity: sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.27.3': - resolution: {integrity: sha512-ogfbEVQgIZOz5WPWXF2HVb6En+kWzScuxJo/WdQTqEgeyGkaa2ui5sQav9Zkr7bnNCLK48uxmmK0TySm22eiuw==} + '@rollup/rollup-win32-arm64-msvc@4.27.4': + resolution: {integrity: sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.27.3': - resolution: {integrity: sha512-ecE36ZBMLINqiTtSNQ1vzWc5pXLQHlf/oqGp/bSbi7iedcjcNb6QbCBNG73Euyy2C+l/fn8qKWEwxr+0SSfs3w==} + '@rollup/rollup-win32-ia32-msvc@4.27.4': + resolution: {integrity: sha512-KtwEJOaHAVJlxV92rNYiG9JQwQAdhBlrjNRp7P9L8Cb4Rer3in+0A+IPhJC9y68WAi9H0sX4AiG2NTsVlmqJeQ==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.27.3': - resolution: {integrity: sha512-vliZLrDmYKyaUoMzEbMTg2JkerfBjn03KmAw9CykO0Zzkzoyd7o3iZNam/TpyWNjNT+Cz2iO3P9Smv2wgrR+Eg==} + '@rollup/rollup-win32-x64-msvc@4.27.4': + resolution: {integrity: sha512-3j4jx1TppORdTAoBJRd+/wJRGCPC0ETWkXOecJ6PPZLj6SptXkrXcNqdj0oclbKML6FkQltdz7bBA3rUSirZug==} cpu: [x64] os: [win32] @@ -651,8 +651,8 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@22.9.1': - resolution: {integrity: sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==} + '@types/node@22.9.3': + resolution: {integrity: sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw==} '@typescript-eslint/eslint-plugin@8.15.0': resolution: {integrity: sha512-+zkm9AR1Ds9uLWN3fkoeXgFppaQ+uEVtfOV62dDmsy9QCNqlRHWNEck4yarvRNrvRcHQLGfqBNui3cimoz8XAg==} @@ -1086,8 +1086,8 @@ packages: delaunator@5.0.1: resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} - electron-to-chromium@1.5.63: - resolution: {integrity: sha512-ddeXKuY9BHo/mw145axlyWjlJ1UBt4WK3AlvkT7W2AbqfRQoacVoRUCF6wL3uIx/8wT9oLKXzI+rFqHHscByaA==} + electron-to-chromium@1.5.64: + resolution: {integrity: sha512-IXEuxU+5ClW2IGEYFC2T7szbyVgehupCWQe5GNh+H065CD6U6IFN0s4KeAMFGNmQolRU4IV7zGBWSYMmZ8uuqQ==} engine.io-client@6.6.2: resolution: {integrity: sha512-TAr+NKeoVTjEVW8P3iHguO1LO6RlUz9O5Y8o7EY0fU+gY1NYqas7NN3slpFtbXEsLMHk0h90fJMfKjRkQ0qUIw==} @@ -1604,8 +1604,8 @@ packages: robust-predicates@3.0.2: resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} - rollup@4.27.3: - resolution: {integrity: sha512-SLsCOnlmGt9VoZ9Ek8yBK8tAdmPHeppkw+Xa7yDlCEhDTvwYei03JlWo1fdc7YTfLZ4tD8riJCUyAgTbszk1fQ==} + rollup@4.27.4: + resolution: {integrity: sha512-RLKxqHEMjh/RGLsDxAEsaLO3mWgyoU6x9w6n1ikAzet4B3gI2/3yP6PWY2p9QzRTh6MfEIXB3MwsOY0Iv3vNrw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -2237,66 +2237,66 @@ snapshots: '@polka/url@1.0.0-next.28': {} - '@rollup/pluginutils@5.1.3(rollup@4.27.3)': + '@rollup/pluginutils@5.1.3(rollup@4.27.4)': dependencies: '@types/estree': 1.0.6 estree-walker: 2.0.2 picomatch: 4.0.2 optionalDependencies: - rollup: 4.27.3 + rollup: 4.27.4 - '@rollup/rollup-android-arm-eabi@4.27.3': + '@rollup/rollup-android-arm-eabi@4.27.4': optional: true - '@rollup/rollup-android-arm64@4.27.3': + '@rollup/rollup-android-arm64@4.27.4': optional: true - '@rollup/rollup-darwin-arm64@4.27.3': + '@rollup/rollup-darwin-arm64@4.27.4': optional: true - '@rollup/rollup-darwin-x64@4.27.3': + '@rollup/rollup-darwin-x64@4.27.4': optional: true - '@rollup/rollup-freebsd-arm64@4.27.3': + '@rollup/rollup-freebsd-arm64@4.27.4': optional: true - '@rollup/rollup-freebsd-x64@4.27.3': + '@rollup/rollup-freebsd-x64@4.27.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.27.3': + '@rollup/rollup-linux-arm-gnueabihf@4.27.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.27.3': + '@rollup/rollup-linux-arm-musleabihf@4.27.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.27.3': + '@rollup/rollup-linux-arm64-gnu@4.27.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.27.3': + '@rollup/rollup-linux-arm64-musl@4.27.4': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.27.3': + '@rollup/rollup-linux-powerpc64le-gnu@4.27.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.27.3': + '@rollup/rollup-linux-riscv64-gnu@4.27.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.27.3': + '@rollup/rollup-linux-s390x-gnu@4.27.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.27.3': + '@rollup/rollup-linux-x64-gnu@4.27.4': optional: true - '@rollup/rollup-linux-x64-musl@4.27.3': + '@rollup/rollup-linux-x64-musl@4.27.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.27.3': + '@rollup/rollup-win32-arm64-msvc@4.27.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.27.3': + '@rollup/rollup-win32-ia32-msvc@4.27.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.27.3': + '@rollup/rollup-win32-x64-msvc@4.27.4': optional: true '@socket.io/component-emitter@3.1.2': {} @@ -2426,7 +2426,7 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/node@22.9.1': + '@types/node@22.9.3': dependencies: undici-types: 6.19.8 @@ -2512,9 +2512,9 @@ snapshots: '@typescript-eslint/types': 8.15.0 eslint-visitor-keys: 4.2.0 - '@vitejs/plugin-vue@5.2.0(vite@5.4.11(@types/node@22.9.1))(vue@3.5.13(typescript@5.6.3))': + '@vitejs/plugin-vue@5.2.0(vite@5.4.11(@types/node@22.9.3))(vue@3.5.13(typescript@5.6.3))': dependencies: - vite: 5.4.11(@types/node@22.9.1) + vite: 5.4.11(@types/node@22.9.3) vue: 3.5.13(typescript@5.6.3) '@volar/language-core@2.4.10': @@ -2596,14 +2596,14 @@ snapshots: '@vue/devtools-api@6.6.4': {} - '@vue/devtools-core@7.6.4(vite@5.4.11(@types/node@22.9.1))(vue@3.5.13(typescript@5.6.3))': + '@vue/devtools-core@7.6.4(vite@5.4.11(@types/node@22.9.3))(vue@3.5.13(typescript@5.6.3))': dependencies: '@vue/devtools-kit': 7.6.4 '@vue/devtools-shared': 7.6.4 mitt: 3.0.1 nanoid: 3.3.7 pathe: 1.1.2 - vite-hot-client: 0.2.3(vite@5.4.11(@types/node@22.9.1)) + vite-hot-client: 0.2.3(vite@5.4.11(@types/node@22.9.3)) vue: 3.5.13(typescript@5.6.3) transitivePeerDependencies: - vite @@ -2732,7 +2732,7 @@ snapshots: browserslist@4.24.2: dependencies: caniuse-lite: 1.0.30001683 - electron-to-chromium: 1.5.63 + electron-to-chromium: 1.5.64 node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.2) @@ -2948,7 +2948,7 @@ snapshots: dependencies: robust-predicates: 3.0.2 - electron-to-chromium@1.5.63: {} + electron-to-chromium@1.5.64: {} engine.io-client@6.6.2: dependencies: @@ -3443,28 +3443,28 @@ snapshots: robust-predicates@3.0.2: {} - rollup@4.27.3: + rollup@4.27.4: dependencies: '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.27.3 - '@rollup/rollup-android-arm64': 4.27.3 - '@rollup/rollup-darwin-arm64': 4.27.3 - '@rollup/rollup-darwin-x64': 4.27.3 - '@rollup/rollup-freebsd-arm64': 4.27.3 - '@rollup/rollup-freebsd-x64': 4.27.3 - '@rollup/rollup-linux-arm-gnueabihf': 4.27.3 - '@rollup/rollup-linux-arm-musleabihf': 4.27.3 - '@rollup/rollup-linux-arm64-gnu': 4.27.3 - '@rollup/rollup-linux-arm64-musl': 4.27.3 - '@rollup/rollup-linux-powerpc64le-gnu': 4.27.3 - '@rollup/rollup-linux-riscv64-gnu': 4.27.3 - '@rollup/rollup-linux-s390x-gnu': 4.27.3 - '@rollup/rollup-linux-x64-gnu': 4.27.3 - '@rollup/rollup-linux-x64-musl': 4.27.3 - '@rollup/rollup-win32-arm64-msvc': 4.27.3 - '@rollup/rollup-win32-ia32-msvc': 4.27.3 - '@rollup/rollup-win32-x64-msvc': 4.27.3 + '@rollup/rollup-android-arm-eabi': 4.27.4 + '@rollup/rollup-android-arm64': 4.27.4 + '@rollup/rollup-darwin-arm64': 4.27.4 + '@rollup/rollup-darwin-x64': 4.27.4 + '@rollup/rollup-freebsd-arm64': 4.27.4 + '@rollup/rollup-freebsd-x64': 4.27.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.27.4 + '@rollup/rollup-linux-arm-musleabihf': 4.27.4 + '@rollup/rollup-linux-arm64-gnu': 4.27.4 + '@rollup/rollup-linux-arm64-musl': 4.27.4 + '@rollup/rollup-linux-powerpc64le-gnu': 4.27.4 + '@rollup/rollup-linux-riscv64-gnu': 4.27.4 + '@rollup/rollup-linux-s390x-gnu': 4.27.4 + '@rollup/rollup-linux-x64-gnu': 4.27.4 + '@rollup/rollup-linux-x64-musl': 4.27.4 + '@rollup/rollup-win32-arm64-msvc': 4.27.4 + '@rollup/rollup-win32-ia32-msvc': 4.27.4 + '@rollup/rollup-win32-x64-msvc': 4.27.4 fsevents: 2.3.3 run-applescript@7.0.0: {} @@ -3585,14 +3585,14 @@ snapshots: util-deprecate@1.0.2: {} - vite-hot-client@0.2.3(vite@5.4.11(@types/node@22.9.1)): + vite-hot-client@0.2.3(vite@5.4.11(@types/node@22.9.3)): dependencies: - vite: 5.4.11(@types/node@22.9.1) + vite: 5.4.11(@types/node@22.9.3) - vite-plugin-inspect@0.8.8(rollup@4.27.3)(vite@5.4.11(@types/node@22.9.1)): + vite-plugin-inspect@0.8.8(rollup@4.27.4)(vite@5.4.11(@types/node@22.9.3)): dependencies: '@antfu/utils': 0.7.10 - '@rollup/pluginutils': 5.1.3(rollup@4.27.3) + '@rollup/pluginutils': 5.1.3(rollup@4.27.4) debug: 4.3.7 error-stack-parser-es: 0.1.5 fs-extra: 11.2.0 @@ -3600,28 +3600,28 @@ snapshots: perfect-debounce: 1.0.0 picocolors: 1.1.1 sirv: 3.0.0 - vite: 5.4.11(@types/node@22.9.1) + vite: 5.4.11(@types/node@22.9.3) transitivePeerDependencies: - rollup - supports-color - vite-plugin-vue-devtools@7.6.4(rollup@4.27.3)(vite@5.4.11(@types/node@22.9.1))(vue@3.5.13(typescript@5.6.3)): + vite-plugin-vue-devtools@7.6.4(rollup@4.27.4)(vite@5.4.11(@types/node@22.9.3))(vue@3.5.13(typescript@5.6.3)): dependencies: - '@vue/devtools-core': 7.6.4(vite@5.4.11(@types/node@22.9.1))(vue@3.5.13(typescript@5.6.3)) + '@vue/devtools-core': 7.6.4(vite@5.4.11(@types/node@22.9.3))(vue@3.5.13(typescript@5.6.3)) '@vue/devtools-kit': 7.6.4 '@vue/devtools-shared': 7.6.4 execa: 8.0.1 sirv: 3.0.0 - vite: 5.4.11(@types/node@22.9.1) - vite-plugin-inspect: 0.8.8(rollup@4.27.3)(vite@5.4.11(@types/node@22.9.1)) - vite-plugin-vue-inspector: 5.2.0(vite@5.4.11(@types/node@22.9.1)) + vite: 5.4.11(@types/node@22.9.3) + vite-plugin-inspect: 0.8.8(rollup@4.27.4)(vite@5.4.11(@types/node@22.9.3)) + vite-plugin-vue-inspector: 5.2.0(vite@5.4.11(@types/node@22.9.3)) transitivePeerDependencies: - '@nuxt/kit' - rollup - supports-color - vue - vite-plugin-vue-inspector@5.2.0(vite@5.4.11(@types/node@22.9.1)): + vite-plugin-vue-inspector@5.2.0(vite@5.4.11(@types/node@22.9.3)): dependencies: '@babel/core': 7.26.0 '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.0) @@ -3632,17 +3632,17 @@ snapshots: '@vue/compiler-dom': 3.5.13 kolorist: 1.8.0 magic-string: 0.30.13 - vite: 5.4.11(@types/node@22.9.1) + vite: 5.4.11(@types/node@22.9.3) transitivePeerDependencies: - supports-color - vite@5.4.11(@types/node@22.9.1): + vite@5.4.11(@types/node@22.9.3): dependencies: esbuild: 0.21.5 postcss: 8.4.49 - rollup: 4.27.3 + rollup: 4.27.4 optionalDependencies: - '@types/node': 22.9.1 + '@types/node': 22.9.3 fsevents: 2.3.3 vscode-uri@3.0.8: {} diff --git a/pi/ui/src/components/UWBVisualization.vue b/pi/ui/src/components/UWBVisualization.vue index c6ffc0b..217ec07 100644 --- a/pi/ui/src/components/UWBVisualization.vue +++ b/pi/ui/src/components/UWBVisualization.vue @@ -4,18 +4,19 @@ import * as d3 from 'd3'; import { Socket } from 'socket.io-client'; interface AnchorData { - A: string; // Anchor ID - R: string; // Range + A: string // Anchor ID + R: string // Range } interface AnchorConfig { - anchors: string[]; - distances: { [key: string]: number }; + anchors: string[] + distances: { [key: string]: number } } export default defineComponent({ name: 'UWBVisualization', setup() { + const backendUrl = import.meta.env.VITE_BACKEND_URL || 'http://localhost:5000'; const socket = inject('socket') as Socket; const uwbData = ref([]); @@ -24,7 +25,7 @@ export default defineComponent({ const anchorIDs = ref([]); // D3 variables - let svg: d3.Selection; // eslint-disable-line + let svg: d3.Selection // eslint-disable-line const width = 600; const height = 400; const padding = 20; // Padding around the visualization @@ -36,7 +37,7 @@ export default defineComponent({ const scalingFactor = 50; // Adjust to control visualization size onMounted(() => { - fetch('/api/config') + fetch(`${ backendUrl }/api/config`) .then((response) => response.json()) .then((configData: AnchorConfig) => { console.log('## configData:', configData); @@ -72,7 +73,6 @@ export default defineComponent({ return; } - positions[ids[0]] = [0, 0]; // First anchor at (0, 0) const d1 = getDistance(ids[0], ids[1]) * scalingFactor; @@ -92,11 +92,7 @@ export default defineComponent({ } function getDistance(id1: string, id2: string): number { - return ( - anchorDistances.value[`${ id1 }-${ id2 }`] || - anchorDistances.value[`${ id2 }-${ id1 }`] || - 0 - ); + return anchorDistances.value[`${ id1 }-${ id2 }`] || anchorDistances.value[`${ id2 }-${ id1 }`] || 0; } function updateScales(tagPosition?: [number, number]) { @@ -129,11 +125,13 @@ export default defineComponent({ const anchors = Object.entries(anchorPositions.value) as [string, [number, number]][]; // Bind data to anchor circles - const anchorCircles = svg.selectAll('.anchor') + const anchorCircles = svg + .selectAll('.anchor') .data(anchors, (d) => d[0]); // Enter selection - anchorCircles.enter() + anchorCircles + .enter() .append('circle') .attr('class', 'anchor') .attr('r', 5) @@ -146,11 +144,13 @@ export default defineComponent({ anchorCircles.exit().remove(); // Bind data to anchor labels - const anchorLabels = svg.selectAll('.anchor-label') + const anchorLabels = svg + .selectAll('.anchor-label') .data(anchors, (d) => d[0]); // Enter selection - anchorLabels.enter() + anchorLabels + .enter() .append('text') .attr('class', 'anchor-label') .attr('font-size', '12px') @@ -214,10 +214,9 @@ export default defineComponent({ drawTag(tagX, tagY); } - function calculateTagPosition( positions: [number, number][], - distances: number[] + distances: number[], ): [number, number] { if (positions.length < 3) { console.error('At least three anchors are required.'); @@ -279,7 +278,6 @@ export default defineComponent({ } } - return {}; }, }); diff --git a/pi/ui/src/main.ts b/pi/ui/src/main.ts index ef2b5f2..57cfd44 100644 --- a/pi/ui/src/main.ts +++ b/pi/ui/src/main.ts @@ -9,7 +9,8 @@ import router from './router'; const app = createApp(App); -const socket: Socket = io('http://0.0.0.0:5000', { transports: ['websocket'] }); +const backendUrl = import.meta.env.VITE_BACKEND_URL || 'http://localhost:5000'; +const socket: Socket = io(backendUrl, { transports: ['websocket'] }); app.provide('socket', socket);