Skip to content

refactor: extract shared apiClient and vectorMath utilities - #4

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1784376240-refactor-shared-utils
Open

refactor: extract shared apiClient and vectorMath utilities#4
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1784376240-refactor-shared-utils

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

Summary

Two verbatim-duplicated code patterns were factored into shared utilities. Pure refactor — no behavior change.

1. Frontend HTTP client — the exact same request<T>() helper (plus API_BASE constant and phyverse-token localStorage/Bearer header handling) was copy-pasted in authApi.ts, aiConfigApi.ts, and cloudApi.ts, with the token/header block duplicated again in sendAiChat. Extracted into src/shared/utils/apiClient.ts:

export const API_BASE = import.meta.env.VITE_API_BASE_URL ?? '/api'
export const TOKEN_KEY = 'phyverse-token'
export function getStoredToken(): string | null
export function buildAuthHeaders(base?): Record<string,string>   // Content-Type + Bearer
export async function apiRequest<T>(path, options?): Promise<T>   // fetch + json + !ok -> throw

The three api modules now just call apiRequest(...); sendAiChat uses buildAuthHeaders(). AuthProvider.tsx now imports TOKEN_KEY / getStoredToken instead of redefining the token key literal.

2. Vector math in experiment data collectorsMath.sqrt(v.x*v.x + v.y*v.y + v.z*v.z) and its horizontal sqrt(x²+z²) / sqrt(dx²+dz²) variants were repeated across ~8 mechanics experiments. Extracted into src/shared/utils/vectorMath.ts:

magnitude(v: Vec3Like): number            // sqrt(x²+y²+z²)
magnitudeXZ(v: {x,z}): number             // sqrt(x²+z²)
distanceXZ(a, b): number                  // horizontal distance between two points

Applied to centripetalForce, curvilinearMotion, energyConservation, motionComposition, freeFall, tickerTimer, newtonSecondLaw, galileoIncline. Rapier's translation()/linvel() return {x,y,z} objects that satisfy the helper signatures, so call sites collapse e.g. to return magnitude(ball.rigidBody.linvel()).

Notes

  • tsc -b passes; ESLint is clean on all touched files.
  • Preexisting (not touched here): ESLint errors in api/ai/chat.ts, AiAgentPanel.tsx, sandboxStore.ts, and a broken vitest/jsdom setup in this environment (native binding / ESM resolution) — both unrelated to this refactor.

Link to Devin session: https://app.devin.ai/sessions/cee3bacf2df6421f8934c4bafc857a60
Requested by: @Zyz555444

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@CodeSky0 CodeSky0 self-assigned this Jul 18, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
phyverse Ready Ready Preview, Comment Jul 18, 2026 12:05pm

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

✅ Runtime test — PR #4 (shared apiClient + vectorMath refactor)

Tested locally (Vite dev server). This is a behavior-preserving refactor; verified both extracted utilities at runtime.

apiClient (auth flow) — verified in-browser
Submitting the Sign In modal produced a correctly-formed request via the shared client:

{ "url": "/api/auth/login", "method": "POST",
  "headers": { "Content-Type": "application/json" },
  "body": "{\"email\":\"test@example.com\",\"password\":\"password123\"}" }

With a token in localStorage (phyverse-token), buildAuthHeaders adds Authorization: Bearer <token>. Backend absent → 404 (expected/acceptable; request shape is correct).
auth 404

vectorMath collectors — verified against a real headless Rapier sim (expand)

Ran the actual MECH-03/MECH-15 setup() + collectors against a stepped PhysicsWorld:

  • Free Fall: speed = magnitude(linvel) exactly equals |vy|; height 5.0→4.21, vy 0→−3.92.
  • Centripetal: radius=1.200 (distanceXZ), speed=1.999 (magnitude), ω=1.666 (magnitudeXZ/distanceXZ), F=1.665 = m·ω²·r ✓.
⚠️ Environment caveat + landing page

Rapier WASM is unstable in this test env (getObject(...).now is not a function during Vite pre-bundle; dispose() crash on reload; Node 20.18.1 < Vite's 20.19+). This blocked capturing live readouts in the 3D UI, so vectorMath was verified via the headless sim above. The scene does render and the ball physically falls on a good load.
landing

Tested by Devin — see session for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant