fix: browser XRPC calls use window.location.origin, not localhost:3000 Empty string from getAppviewUrl() was falsy, falling back to localhost:3000 which isn't accessible from the browser in production. Also simplified search effect to use mounted flag.

Author: Aaron Steven White
Commit b8127a4fdff54b0e2af6d4d09bdebdc45bb50705
Parent: 3f7801fa14
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
2 files changed +7 -6
@@ -25,7 +25,7 @@ export async function xrpcQuery<T>(
2525 	params?: Record<string, string | number | undefined>
2626 ): Promise<T> {
2727 	const base = getAppviewUrl();
28-	const url = new URL(`/xrpc/${nsid}`, base || 'http://localhost:3000');
28+	const url = new URL(`/xrpc/${nsid}`, base || (typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000'));
2929 
3030 	if (params) {
3131 		for (const [key, value] of Object.entries(params)) {
@@ -65,14 +65,15 @@
6565 	let searchTimer: ReturnType<typeof setTimeout> | null = null;
6666 
6767 	// React to search query changes with debounce
68-	let lastSearchQuery = $state('');
68+	let mounted = false;
69+	onMount(() => { mounted = true; });
6970 	$effect(() => {
7071 		const q = searchQuery;
71-		if (q === lastSearchQuery) return;
72-		lastSearchQuery = q;
72+		if (!mounted) return;
7373 		if (searchTimer) clearTimeout(searchTimer);
74-		searchTimer = setTimeout(() => doSearch(q), 300);
75-		return () => { if (searchTimer) clearTimeout(searchTimer); };
74+		searchTimer = setTimeout(() => {
75+			doSearch(q);
76+		}, 300);
7677 	});
7778 
7879 	async function loadMore() {
cospan · schematic version control on atproto built on AT Protocol