# Network Service `os/NetworkService.ts` is the device-like network surface. Apps and OS services that need to talk to external HTTP servers must go through it instead of calling `fetch()` directly. Same-origin static asset fetches (e.g. `loader.ts` loading bundled JSON via `new URL('./posts.json', import.meta.url)`) are an explicit exception — the gateway is only for cross-origin traffic. ## API ```ts import { netFetch, netJson, netText } from '@/os/NetworkService'; await netFetch(input, init?); // → Response await netJson(input, init?); // → T (auto JSON.parse; throws on non-2xx) await netText(input, init?); // → string ``` | Helper | Behavior | |---|---| | `netFetch` | Returns the raw `Response`. Caller handles body and status. | | `netJson(...)` | Calls `netFetch`, throws on `!res.ok` (error message includes the response text's first 200 chars for diagnostics), otherwise `res.json()`. | | `netText(...)` | Same as `netJson` but returns text. | `init` is the standard `RequestInit` plus one extra option: ```ts interface NetFetchOptions extends RequestInit { forceGateway?: boolean; // route through the local gateway even for same-origin URLs } ``` ## URL routing `netFetch` inspects the URL to decide whether to hit the gateway: | URL shape | Route | |---|---| | Relative path (`/foo`, `data/index.ts`) | Same-origin direct `fetch` (no gateway). | | Path under `/api/gw/...` | Direct (already gateway). | | Absolute `http(s)://...` | Gateway. | | `forceGateway: true` | Gateway, even for same-origin URLs (useful when you want cookie-jar behavior on a relative endpoint). | Image / video resources should be loaded with `` / `