Files
OwnCord/Client/tauri-client/CLAUDE.md
T
J3vbandClaude 9df0e63b5f build: toolchain and dependency upgrades (TypeScript 6, Node 24 CI, Vite 8, Vitest 4, Go/Rust deps) (#1401)
* build(client): upgrade TypeScript to 6.0.3

Staging step toward TypeScript 7 (the native compiler), which needs its
7.1 stable API before typescript-eslint and Stryker's typescript-checker
can run on it. TS 6 is the JS-based bridge release that aligns config
defaults with 7.

Two fallout fixes:
- tsconfig.e2e.json: TS 6 defaults "types" to [] instead of every
  installed @types package, so the Playwright layer's Node globals
  (process, Buffer) need an explicit "types": ["node"].
- media-visibility.test.ts: TS 6's DOM lib adds scrollMargin to
  IntersectionObserver, so the mock grows the property.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lw5KEz6gdD816Wxmm4A3Bn

* build(server): bump chi to 5.3.2, modernc.org/sqlite to 1.57.0, toolchain to go1.26.7

Go 1.27 deliberately deferred until 1.27.1 lands.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lw5KEz6gdD816Wxmm4A3Bn

* build(tauri): bump tokio-tungstenite to 0.30, refresh Cargo.lock

In-range lockfile refresh via cargo update; tungstenite 0.29/0.30 changes
are client-API-neutral (header handling, server-side handshake hardening).

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lw5KEz6gdD816Wxmm4A3Bn

* build(client): upgrade vite 8, vitest 4, jsdom 30, stryker 10 + minors

- vite 6 -> 8: Rolldown requires the function form of manualChunks;
  __dirname -> import.meta.dirname in configs
- vitest 3 -> 4: browser provider moved to @vitest/browser-playwright;
  vi.fn() mocks now need explicit signatures (typed throughout tests);
  constructor mocks use function impls; restoreAllMocks no longer resets
  vi.fn state; matchMedia spies replaced with vi.stubGlobal
- jsdom 29 -> 30: one internal bookkeeping abort listener per signal,
  listener-count regression tests adjusted (leak detection retained)
- stryker 9 -> 10, @types/node 20 -> 24, eslint/oxlint/livekit-client minors
- tsconfigs: explicit "types" now that TS6/vitest4 stop injecting
  @types/node ambiently; build config keeps Node globals out of src/

Validated: tsc (main/build/e2e), eslint, oxlint, knip, prettier,
unit+integration (5196 tests), browser suite, vite build, stryker dry run.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lw5KEz6gdD816Wxmm4A3Bn

* ci: move Node 20 (EOL 2026-04-30) to Node 24 LTS

The jsdom suite runs on modern Node without --no-experimental-webstorage:
tests/setup.ts already replaces the shadowed localStorage with an
in-memory shim. Client CLAUDE.md gotcha updated accordingly.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lw5KEz6gdD816Wxmm4A3Bn

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-08-22 06:48:58 +02:00

2.0 KiB

OwnCord Client (Tauri v2)

TypeScript frontend (Vite, vanilla TS — no React/Vue) plus a deliberately thin Rust backend in src-tauri/ for native APIs only. LiveKit handles voice/video.

Layout

  • src/stores/ observable stores · src/lib/ protocol, WS, voice, E2EE · src/pages/, src/components/ UI
  • src/lib/protocolTypes.ts and src/generated/ are generated — see the root CLAUDE.md
  • tests/unit, tests/integration (vitest, jsdom) · tests/e2e (Playwright) · tests/browser (vitest browser mode)

Gotchas

  • Node's native Web Storage (Node 22+) shadows jsdom's localStorage; tests/setup.ts replaces it with an in-memory shim, so the suite runs on modern Node without --no-experimental-webstorage. If storage tests fail en masse, suspect that shim before your change. CI pins Node 24.
  • src/lib/dispatcher.ts is the single WS-event entry point into the stores: server events reach domain stores only through a ws.on(...) subscription registered there. Other modules do register their own ws.on(...) handlers for page-local UI (main.ts, MainPage.ts, ChannelController.ts — ringing, overlays, slow-mode timers); that is fine as long as they only read store state. Writing a store from one of those handlers is the violation, and local/no-store-write-in-ws-on now fails the build on it.
  • Voice sessions are superseded, not cancelled. LiveKitSession re-entry points check whether a newer attempt owns the shared state before tearing anything down, so cleanup in an aborted path must be scoped to that attempt's own room — a global leaveVoice() there kills the live session.
  • Voice E2EE is key-holder based with TOFU identity pinning. Anything touching livekitE2EE.ts or identity.ts must preserve the epoch/keypair staleness guards and must never report an unverified peer as verified.
  • Do not run npm run tauri build locally; the desktop build is CI-only.
  • Formatting is prettier-enforced; match the surrounding code rather than reasoning about style.