Skip to content

Commit 6f7a10e

Browse files
committed
fix:Minimalize requests to listRepositories with debounce
1 parent 79b58da commit 6f7a10e

File tree

1 file changed

+42
-23
lines changed

1 file changed

+42
-23
lines changed

src/lib/components/git/repositories.svelte

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import { page } from '$app/state';
2424
import Card from '../card.svelte';
2525
import SkeletonRepoList from './skeletonRepoList.svelte';
26-
import { onMount, untrack } from 'svelte';
26+
import { onMount, untrack, onDestroy } from 'svelte';
2727
2828
let {
2929
action = $bindable('select'),
@@ -48,10 +48,46 @@
4848
let isLoadingRepositories = $state(null);
4949
let installationsMap = $state(null);
5050
51+
// Debounce and race condition handling
52+
let searchTimeout: ReturnType<typeof setTimeout> | null = null;
53+
let currentRequestId = 0;
54+
let lastResolvedRequestId = 0;
55+
5156
onMount(() => {
5257
loadInstallations();
5358
});
5459
60+
$effect(() => {
61+
if (selectedInstallation && search !== undefined) {
62+
if (searchTimeout) {
63+
clearTimeout(searchTimeout);
64+
}
65+
searchTimeout = setTimeout(() => {
66+
if (selectedInstallation) {
67+
isLoadingRepositories = true;
68+
const requestId = ++currentRequestId;
69+
loadRepositories(selectedInstallation, search)
70+
.then(() => {
71+
if (requestId > lastResolvedRequestId) {
72+
lastResolvedRequestId = requestId;
73+
isLoadingRepositories = false;
74+
}
75+
})
76+
.catch(() => {
77+
if (requestId > lastResolvedRequestId) {
78+
lastResolvedRequestId = requestId;
79+
isLoadingRepositories = false;
80+
}
81+
});
82+
}
83+
}, 300);
84+
}
85+
});
86+
87+
onDestroy(() => {
88+
if (searchTimeout) clearTimeout(searchTimeout);
89+
});
90+
5591
async function loadInstallations() {
5692
if (installationList) {
5793
if (installationList.installations.length) {
@@ -71,7 +107,7 @@
71107
.vcs.listInstallations();
72108
if (installations.length) {
73109
if (!selectedInstallation) {
74-
untrack(() => (selectedInstallation = installationList.installations[0].$id));
110+
untrack(() => (selectedInstallation = installations[0].$id));
75111
}
76112
installation.set(installations.find((entry) => entry.$id === selectedInstallation));
77113
}
@@ -80,22 +116,6 @@
80116
}
81117
82118
async function loadRepositories(installationId: string, search: string) {
83-
if (
84-
!$repositories ||
85-
$repositories.installationId !== installationId ||
86-
$repositories.search !== search
87-
) {
88-
await fetchRepos(installationId, search);
89-
}
90-
91-
if ($repositories.repositories.length && action === 'select') {
92-
selectedRepository = $repositories.repositories[0].id;
93-
$repository = $repositories.repositories[0];
94-
}
95-
return $repositories.repositories;
96-
}
97-
98-
async function fetchRepos(installationId: string, search: string) {
99119
if (product === 'functions') {
100120
$repositories.repositories = (
101121
(await sdk
@@ -117,9 +137,9 @@
117137
)) as unknown as Models.ProviderRepositoryFrameworkList
118138
).frameworkProviderRepositories;
119139
}
120-
121140
$repositories.search = search;
122141
$repositories.installationId = installationId;
142+
return $repositories.repositories;
123143
}
124144
125145
selectedRepository;
@@ -168,10 +188,9 @@
168188
installationsMap.find((entry) => entry.$id === selectedInstallation)
169189
);
170190

171-
isLoadingRepositories = true;
172-
loadRepositories(selectedInstallation, search).then(() => {
173-
isLoadingRepositories = false;
174-
});
191+
if (searchTimeout) {
192+
clearTimeout(searchTimeout);
193+
}
175194
}}
176195
bind:value={selectedInstallation} />
177196
<InputSearch

0 commit comments

Comments
 (0)