D-James-GH / cached_query

Simple caching for flutter apps
MIT License
55 stars 10 forks source link

Store page boundaries and keys in infinite queries #53

Open clragon opened 1 week ago

clragon commented 1 week ago

Is your feature request related to a problem? Please describe.

Currently, InfiniteQueryState holds a List<T>, which makes it impossible to determine which items belong to which page and to track their corresponding keys. We can therefore no longer distinguish pages.

Describe the solution you'd like

I propose changing the InfiniteQueryState to hold a List<List<T>> instead of a List<T> to better organize items by page. Additionally, InfiniteQueryState should maintain a List<Arg> to track the keys associated with each page.

This approach would allow us to know both:

This is very similar to how React Query handles infinite queries. While using a Map might seem like an obvious solution, since LinkedHashmap is ordered, presume we are using bidirectional pagination, inserting a new page at the start would become difficult, especially since we cannot know the sorting order of arbitrary keys. Using two arrays where indexes associate items is therefore more manageable.

Additional context

A practical use case for this is managing headers or scroll bar page indicators, where it’s necessary to know the boundaries of each page and their respective keys.

This is a breaking change. However, it would be possible, and I would recommend this too, to implement a Getter on the InfiniteQueryState that returns a flattened version of the pages array. This could make this an unbreaking change, or at minimum make migration easier.

D-James-GH commented 1 week ago

I think the datatype of InfiniteQueryState should remain the same (List<T>). Currently each item in the list is a "page". Each page doesn't necessarily have to be a list (eg multiple posts). Imagine a situation where a page could be single item, like a page of a document/pdf. It's up to the user of the package to pass in the correct type of the page (which is usually a List<SomeModel>.

I don't see a problem with storing the result of getNextArg along with the page, this could be a useful enhancement.

clragon commented 1 week ago

Youre right that is a much better idea, and it prompted me to double check!

interface InfiniteData<TData, TPageParam = unknown> {
    pages: Array<TData>;
    pageParams: Array<TPageParam>;
}

React Query does in fact not opinionate whether the Result is a nested list, this is simply what we get when we define it as such. In that case I would be perfectly fine with just an additionally array of keys and no alteration to the List<T> type.