From 2ebe0e90d011ab3bea2c299986101450ec2cc4ec Mon Sep 17 00:00:00 2001 From: scott Date: Wed, 8 Apr 2026 12:28:18 -0700 Subject: [PATCH] Add CLAUDE.md, switch to static adapter for nginx deployment - CLAUDE.md: build commands, architecture overview, coordinate systems, WASM rebuild instructions for future development sessions - Switch from adapter-auto to adapter-static with SPA fallback (outputs to build/ directory for nginx serving) - Install @sveltejs/adapter-static dependency Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 53 ++++++++++++++++++++++++++++++++++++++ frontend/package-lock.json | 27 ++++++++----------- frontend/package.json | 3 ++- frontend/svelte.config.js | 10 +++---- 4 files changed, 70 insertions(+), 23 deletions(-) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..82b7810 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,53 @@ +# Mass Driver — Interplanetary Relay Network Simulator + +## Project Structure +Rust workspace + SvelteKit frontend compiled to WASM. + +``` +crates/ + orbital-mechanics/ — Pure Rust: Kepler solver, Lambert solver, orbit propagation, Lagrange points + mass-driver-core/ — Station placement, transfer matrix computation, Dijkstra routing + mass-driver-wasm/ — Thin wasm-bindgen wrapper exposing core to JS + mass-driver-backend/ — Axum cache server (Postgres) +frontend/ — SvelteKit + Threlte (Three.js) + Canvas2D +``` + +## Build Commands + +```bash +# Rust tests +cargo test + +# Build WASM (required before frontend) +cd crates/mass-driver-wasm && wasm-pack build --target web --release + +# Frontend dev server +cd frontend && npm run dev -- --port 5173 + +# Frontend production build +cd frontend && npx vite build + +# Backend (needs DATABASE_URL env var) +cargo run -p mass-driver-backend +``` + +## Key Architecture +- Orbital mechanics runs in WASM (Rust compiled to WebAssembly) +- Frontend loads WASM on mount, calls it every animation frame for body positions +- Route computation: Lambert solver → transfer matrix → time-expanded graph → Dijkstra +- 2D view: Canvas2D with manual drawing. 3D view: Threlte (Svelte Three.js wrapper) +- Positions in AU (ecliptic coords), converted to screen pixels (2D) or Three.js units (3D) +- Ecliptic→Three.js mapping: X→X, Y→-Z, Z→Y (Three.js is Y-up) + +## WASM Rebuild +After changing any Rust code in orbital-mechanics, mass-driver-core, or mass-driver-wasm: +```bash +cd crates/mass-driver-wasm && wasm-pack build --target web --release +``` +The frontend links to the WASM pkg via `file:../crates/mass-driver-wasm/pkg` in package.json. + +## Coordinate Systems +- Rust returns positions in AU, ecliptic frame (X=vernal equinox, Y=90° in ecliptic, Z=north pole) +- Lambert solver works in km (positions × AU_KM constant) +- 2D canvas: AU mapped to pixels via zoom factor +- 3D scene: 1 AU = 50 Three.js units, Y-up convention diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 5ebe4d6..b521a93 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,6 +8,7 @@ "name": "frontend", "version": "0.0.1", "dependencies": { + "@sveltejs/adapter-static": "^3.0.10", "@threlte/core": "^8.5.8", "@threlte/extras": "^9.14.5", "@threlte/flex": "^2.2.2", @@ -506,7 +507,6 @@ "version": "1.0.0-next.29", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", - "dev": true, "license": "MIT" }, "node_modules/@rollup/plugin-virtual": { @@ -894,7 +894,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", - "dev": true, "license": "MIT" }, "node_modules/@sveltejs/acorn-typescript": { @@ -916,11 +915,19 @@ "@sveltejs/kit": "^2.0.0" } }, + "node_modules/@sveltejs/adapter-static": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.10.tgz", + "integrity": "sha512-7D9lYFWJmB7zxZyTE/qxjksvMqzMuYrrsyh1f4AlZqeZeACPRySjbC3aFiY55wb1tWUaKOQG9PVbm74JcN2Iew==", + "license": "MIT", + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, "node_modules/@sveltejs/kit": { "version": "2.57.0", "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.57.0.tgz", "integrity": "sha512-TMiqCTy9ZW4KBHvmTgeWU/hF6jcFpeMgR+9ekE06uhhGnbUZ7wpIY6l1Uk4ThRzlWYJnCVfzmtVNaHaDjaSiSg==", - "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.0.0", @@ -962,7 +969,6 @@ "version": "6.2.4", "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.4.tgz", "integrity": "sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==", - "dev": true, "license": "MIT", "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", @@ -983,7 +989,6 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-5.0.2.tgz", "integrity": "sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig==", - "dev": true, "license": "MIT", "dependencies": { "obug": "^2.1.0" @@ -1619,7 +1624,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", - "dev": true, "license": "MIT" }, "node_modules/@types/estree": { @@ -1767,7 +1771,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -1777,7 +1780,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -1949,7 +1951,6 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -2272,7 +2273,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -2300,7 +2300,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", - "dev": true, "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" @@ -2446,14 +2445,12 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.0.tgz", "integrity": "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==", - "dev": true, "license": "MIT" }, "node_modules/sirv": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", - "dev": true, "license": "MIT", "dependencies": { "@polka/url": "^1.0.0-next.24", @@ -2614,7 +2611,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -2663,7 +2659,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -2788,7 +2784,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz", "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==", - "dev": true, "license": "MIT", "workspaces": [ "tests/deps/*", diff --git a/frontend/package.json b/frontend/package.json index e21a6bb..37ebc56 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -24,11 +24,12 @@ "vite": "^7.3.1" }, "dependencies": { - "mass-driver-wasm": "file:../crates/mass-driver-wasm/pkg", + "@sveltejs/adapter-static": "^3.0.10", "@threlte/core": "^8.5.8", "@threlte/extras": "^9.14.5", "@threlte/flex": "^2.2.2", "astronomy-engine": "^2.1.19", + "mass-driver-wasm": "file:../crates/mass-driver-wasm/pkg", "postprocessing": "^6.39.0", "three": "^0.183.2", "vite-plugin-top-level-await": "^1.6.0", diff --git a/frontend/svelte.config.js b/frontend/svelte.config.js index 0c3412e..b011777 100644 --- a/frontend/svelte.config.js +++ b/frontend/svelte.config.js @@ -1,16 +1,14 @@ -import adapter from '@sveltejs/adapter-auto'; +import adapter from '@sveltejs/adapter-static'; /** @type {import('@sveltejs/kit').Config} */ const config = { compilerOptions: { - // Force runes mode for the project, except for libraries. Can be removed in svelte 6. runes: ({ filename }) => (filename.split(/[/\\]/).includes('node_modules') ? undefined : true) }, kit: { - // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. - // If your environment is not supported, or you settled on a specific environment, switch out the adapter. - // See https://svelte.dev/docs/kit/adapters for more information about adapters. - adapter: adapter() + adapter: adapter({ + fallback: 'index.html', + }), } };