import { error, redirect } from '@sveltejs/kit'; import { createApiClient, extractErrorCode } from '$lib/shared/api.server'; import { getErrorMessage } from '$lib/shared/errors'; import { parsePanZoomParams, INITIAL_VIEW } from '$lib/person/genealogy/panZoom'; export async function load({ fetch, url }) { const api = createApiClient(fetch); const result = await api.GET('/api/network'); if (result.response.status === 401) throw redirect(302, '/login'); if (!result.response.ok) { throw error(result.response.status, getErrorMessage(extractErrorCode(result.error))); } // A fresh visit (no shared pan/zoom state) lands at the readable INITIAL_VIEW // (z=3). When a link carries a zoom param we honour it, sanitising server-side // so a crafted link (?z=Infinity, ?cx=NaN) degrades to a safe view before // reaching layout geometry (Nora #692). const initialView = url.searchParams.has('z') ? parsePanZoomParams({ cx: url.searchParams.get('cx'), cy: url.searchParams.get('cy'), z: url.searchParams.get('z') }) : INITIAL_VIEW; const network = result.data!; return { nodes: network.nodes ?? [], edges: network.edges ?? [], initialView }; }