@@ -71,15 +71,15 @@ onMounted(() => {
7171 }, 300 )
7272})
7373
74- // Infinite scroll state
74+ // Infinite scroll / pagination state
7575const pageSize = 25
76- const loadedPages = ref (2 )
77- const isLoadingMore = ref (false )
78-
79- // Pagination state for table view
8076const currentPage = ref (1 )
81- watch (currentPage , page => {
82- loadedPages .value = Math .max (loadedPages .value , page + 1 )
77+
78+ // Calculate how many results we need based on current page and preferred page size
79+ const requestedSize = computed (() => {
80+ const numericPrefSize = preferredPageSize .value === ' all' ? 250 : preferredPageSize .value
81+ // Always fetch at least enough for the current page
82+ return Math .max (pageSize , currentPage .value * numericPrefSize )
8383})
8484
8585// Get initial page from URL (for scroll restoration on reload)
@@ -88,53 +88,44 @@ const initialPage = computed(() => {
8888 return Number .isNaN (p ) ? 1 : Math .max (1 , p )
8989})
9090
91- // Initialize loaded pages from URL on mount
91+ // Initialize current page from URL on mount
9292onMounted (() => {
9393 if (initialPage .value > 1 ) {
94- // Load enough pages to show the initial page
95- loadedPages .value = initialPage .value
94+ currentPage .value = initialPage .value
9695 }
9796})
9897
99- // fetch all pages up to current
100- const { data : results, status } = useNpmSearch (query , () => ({
101- size: pageSize * loadedPages .value ,
102- from: 0 ,
98+ // Use incremental search with client-side caching
99+ const {
100+ data : results,
101+ status,
102+ isLoadingMore,
103+ hasMore,
104+ fetchMore,
105+ } = useNpmSearch (query , () => ({
106+ size: requestedSize .value ,
107+ incremental: true ,
103108}))
104109
105- // Keep track of previous results to show while loading
106- // Use useState so the value persists from SSR to client hydration
110+ // Track previous query for UI continuity
107111const previousQuery = useState (' search-previous-query' , () => query .value )
108- const cachedResults = ref (results .value )
109-
110- // Update cached results smartly
111- watch ([results , query ], ([newResults , newQuery ]) => {
112- if (newResults ) {
113- cachedResults .value = newResults
114- previousQuery .value = newQuery
115- isLoadingMore .value = false
116- }
117- })
118112
119- // Determine if we should show previous results while loading
120- // (when new query is a continuation of the old one)
121- const isQueryContinuation = computed (() => {
122- const current = query .value .toLowerCase ()
123- const previous = previousQuery .value .toLowerCase ()
124- return previous && current .startsWith (previous )
125- })
113+ // Update previous query when results change
114+ watch (
115+ () => results .value ,
116+ newResults => {
117+ if (newResults && newResults .objects .length > 0 ) {
118+ previousQuery .value = query .value
119+ }
120+ },
121+ )
126122
127123const resultsMatchQuery = computed (() => {
128124 return previousQuery .value === query .value
129125})
130126
131- // Show cached results while loading if it's a continuation query
132- const rawVisibleResults = computed (() => {
133- if (status .value === ' pending' && isQueryContinuation .value && cachedResults .value ) {
134- return cachedResults .value
135- }
136- return results .value
137- })
127+ // Results to display (directly from incremental search)
128+ const rawVisibleResults = computed (() => results .value )
138129
139130// Settings for platform package filtering
140131const { settings } = useSettings ()
@@ -229,37 +220,30 @@ function handleSortChange(option: SortOption) {
229220const showSearching = computed (() => {
230221 // Don't show during initial page load (view transition)
231222 if (! hasInteracted .value ) return false
232- // Don't show if we're displaying cached results
233- if (status .value === ' pending' && isQueryContinuation .value && cachedResults .value ) return false
234- // Show if pending on first page
235- return status .value === ' pending' && loadedPages .value === 1
223+ // Show if pending and no results yet
224+ return status .value === ' pending' && displayResults .value .length === 0
236225})
237226
238227const totalPages = computed (() => {
239228 if (! visibleResults .value ) return 0
240229 return Math .ceil (visibleResults .value .total / pageSize )
241230})
242231
243- const hasMore = computed (() => {
244- return loadedPages .value < totalPages .value
245- })
246-
247232// Load more when triggered by infinite scroll
248- function loadMore() {
233+ async function loadMore() {
249234 if (isLoadingMore .value || ! hasMore .value ) return
250-
251- isLoadingMore .value = true
252- loadedPages .value ++
235+ // Increase requested size to trigger fetch
236+ currentPage .value ++
237+ await fetchMore ( requestedSize .value )
253238}
254239
255240// Update URL when page changes from scrolling
256241function handlePageChange(page : number ) {
257242 updateUrlPage (page )
258243}
259244
260- // Reset pages when query changes
245+ // Reset page when query changes
261246watch (query , () => {
262- loadedPages .value = 1
263247 currentPage .value = 1
264248 hasInteracted .value = true
265249})
@@ -967,7 +951,7 @@ defineOgImageComponent('Default', {
967951 heading-level =" h2"
968952 show-publisher
969953 :has-more =" hasMore"
970- :is-loading =" isLoadingMore || (status === 'pending' && loadedPages > 1) "
954+ :is-loading =" isLoadingMore"
971955 :page-size =" preferredPageSize"
972956 :initial-page =" initialPage"
973957 :view-mode =" viewMode"
0 commit comments