fix: auth persistence on refresh, import page pagination + popularity sort - Fix logout on refresh: frontend auth store now falls back to server-side session cookie when IndexedDB is empty - Fix build: add missing <section> tag in profile page - Import page: sorted by star count, cursor-based pagination with "Load more", separate "Your Repos" / "All Repos" tabs when logged in, both tabs searchable - Backend: add sort=popular param to repo.list endpoint

Author: Aaron Steven White
Commit b80edca5f1bd4ab2fea5786d7972aa8ce00e2729
Parent: a8310753f6
Structural diff unavailable

These commits were pushed via plain git push, so no pre-parsed schemas are available. Install git-remote-cospan and re-push via panproto:// to see scope-level changes, breaking change detection, and semantic diffs.

brew install panproto/tap/git-remote-cospan
8 files changed +293 -96
@@ -32,6 +32,7 @@ interface RawRepoListResponse {
3232 export async function listRepos(params?: {
3333 	did?: string;
3434 	source?: string;
35+	sort?: string;
3536 	limit?: number;
3637 	cursor?: string;
3738 }): Promise<RepoListResponse> {
@@ -9,6 +9,13 @@ interface AuthState {
99 	loading: boolean;
1010 }
1111 
12+export interface ServerUser {
13+	did: string;
14+	handle?: string;
15+	displayName?: string;
16+	avatar?: string;
17+}
18+
1219 let state = $state<AuthState>({
1320 	authenticated: false,
1421 	loading: true,
@@ -16,7 +23,7 @@ let state = $state<AuthState>({
1623 
1724 let initialized = false;
1825 
19-export async function initAuth(): Promise<void> {
26+export async function initAuth(serverUser?: ServerUser | null): Promise<void> {
2027 	if (initialized || typeof window === 'undefined') return;
2128 	initialized = true;
2229 
@@ -31,12 +38,34 @@ export async function initAuth(): Promise<void> {
3138 				avatar: result.avatar,
3239 				loading: false,
3340 			};
41+		} else if (serverUser) {
42+			// IndexedDB session lost but server cookie still valid
43+			state = {
44+				authenticated: true,
45+				did: serverUser.did,
46+				handle: serverUser.handle,
47+				displayName: serverUser.displayName,
48+				avatar: serverUser.avatar,
49+				loading: false,
50+			};
3451 		} else {
3552 			state = { authenticated: false, loading: false };
3653 		}
3754 	} catch (e) {
3855 		console.error('Auth init failed:', e);
39-		state = { authenticated: false, loading: false };
56+		// Fall back to server session if available
57+		if (serverUser) {
58+			state = {
59+				authenticated: true,
60+				did: serverUser.did,
61+				handle: serverUser.handle,
62+				displayName: serverUser.displayName,
63+				avatar: serverUser.avatar,
64+				loading: false,
65+			};
66+		} else {
67+			state = { authenticated: false, loading: false };
68+		}
4069 	}
4170 }
4271 
@@ -4,11 +4,11 @@
44 	import Header from '$lib/components/layout/Header.svelte';
55 	import { initAuth, getAuth } from '$lib/stores/auth.svelte';
66 
7-	let { children } = $props();
7+	let { children, data } = $props();
88 	let auth = $derived(getAuth());
99 
1010 	onMount(() => {
11-		initAuth();
11+		initAuth(data.user);
1212 	});
1313 </script>
1414 
@@ -9,6 +9,7 @@
99 	<title>{data.profile?.displayName ?? data.profile?.handle ?? data.did} · Cospan</title>
1010 </svelte:head>
1111 
12+<section>
1213 	<!-- Repositories tab content (default) -->
1314 	{#if data.repos.items.length === 0}
1415 		<EmptyState icon="folder" message="No repositories yet." />
@@ -1,13 +1,14 @@
11 import type { PageServerLoad } from './$types';
22 import { listRepos } from '$lib/api/repo.js';
33 
4-export const load: PageServerLoad = async ({ url }) => {
5-	const protocol = url.searchParams.get('protocol') ?? undefined;
4+export const load: PageServerLoad = async ({ url, locals }) => {
5+	const cursor = url.searchParams.get('cursor') ?? undefined;
6+	const userDid = (locals as any).user?.did;
67 
78 	try {
8-		const repos = await listRepos({ limit: 50, source: 'tangled', protocol } as any);
9-		return { repos, protocol: protocol ?? null };
9+		const repos = await listRepos({ limit: 30, source: 'tangled', sort: 'popular', cursor });
10+		return { repos, userDid: userDid ?? null };
1011 	} catch {
11-		return { repos: { items: [], cursor: null }, protocol: protocol ?? null };
12+		return { repos: { items: [], cursor: null }, userDid: userDid ?? null };
1213 	}
1314 };
cospan · schematic version control on atproto built on AT Protocol