Platform-neutral TypeScript shared by the web app and, later, the iOS app: languages, input validation, Zod schemas for AI requests and results, Crossfire and Sparring logic, and the Edge Function error reader. Files keep their old src/lib/ relative paths, and each old path is now a one-line re-export, so web imports did not change.
Code here must run in a browser and in React Native without changes:
- No DOM globals: no
window,document,localStorage,sessionStorage,navigator, orlocation. Take a value or a small interface as a parameter instead, ascrossfire/storage.tsdoes withStorageLike. - No React, no web-only libraries (stores, i18n bindings, the Supabase client, analytics, UI kits).
- No
import.meta, and no Deno oresm.shspecifiers. - Plain TypeScript. The only dependency is
zod, at the same range as the root.
tsconfig.json has no DOM library, and ESLint rejects browser globals and web-only imports here. src/globals.d.ts declares the few runtime globals both platforms have that the ES library lacks; add to it only what package code uses.
src/contract/ re-exports the request contracts in supabase/functions/_shared/ so package code has one import path for them. Those files stay where the Edge Functions import them.
- Move or write the file under
src/, importing siblings by relative path (never@/). - If web code already imports it from
src/lib/, leaveexport * from '@debatelab/core/<path>';at the old path. - Run
npm run typecheckandnpm run lintfrom the repository root.