43 lines
1.4 KiB
Plaintext
43 lines
1.4 KiB
Plaintext
---
|
|
title: Adapter and pagination
|
|
description: Implement cancellable search requests and return mergeable grouped pages.
|
|
order: 20
|
|
toc:
|
|
- id: implement-adapter
|
|
title: Implement the adapter
|
|
- id: group-results
|
|
title: Group results
|
|
- id: paginate
|
|
title: Paginate
|
|
---
|
|
|
|
## Implement the adapter {#implement-adapter}
|
|
|
|
`SearchAdapter` is the package's only data dependency:
|
|
|
|
```ts
|
|
const searchAdapter: SearchAdapter = {
|
|
async search({ cursor, query, signal }) {
|
|
const response = await fetch(
|
|
`/api/search?q=${encodeURIComponent(query)}&cursor=${cursor ?? ""}`,
|
|
{ signal }
|
|
)
|
|
|
|
if (!response.ok) throw new Error("Search request failed")
|
|
return response.json()
|
|
},
|
|
}
|
|
```
|
|
|
|
Pass `signal` to the underlying request so an older response cannot replace a newer query.
|
|
|
|
## Group results {#group-results}
|
|
|
|
Each `SearchPage` contains `SearchResultGroup` values. Keep a group's `id` stable between pages and each item's `id` stable inside its group. Search uses both identifiers to merge results and remove duplicates.
|
|
|
|
Use `payload` for application data and `icon` or `image` to customize result presentation.
|
|
|
|
## Paginate {#paginate}
|
|
|
|
Return `nextCursor` when another page is available; return `null` or omit it at the end. The surface only displays “Load more” while a cursor exists. A cursor can be a string or number and is passed back to the adapter unchanged.
|