- Notifications
You must be signed in to change notification settings - Fork 59
paginator: manual pagination with familiar syntax #337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
ianmacartney left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some thoughts:
- is it expected to pass in paginationOpts? I suspect we'll not use all those values, just the cursor & numItems? If so, I'd say let's unify the options so everything is in one spot.
- It's fine to require schema always if it makes the types easier - I suspect advanced usage (almost) always uses an index - and it's an easy auto-import param.
- syntax dream:
await paginator(ctx, schema) .query(table) .withIndex(index, q => q.eq(field, value)) .order("desc") .filter((doc) => doc[field] !== value) .paginate(opts)Could this be possible by returning types like
OrderedQuery<..> & { filter?: (doc: DocumentByName<DataModel, T>) => Promise<boolean>, paginate(opts: { cursor: string | null, numItems: number, endCursor?: string }) }? I suspect it'd be pretty tough, but that would be an amazing drop-in replacement option (modulo filter types).
| * If not provided, the page will end when it reaches `options.opts.numItems`. | ||
| * @argument options.filter The filter is optional, and it's a post-filter | ||
| * like the convex-helpers `filter()`, so a sparse predicate may result | ||
| * in small or empty pages. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * in small or empty pages. | |
| * in small or empty pages, though a best effort is made to retrieve `numItems`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm not sure what "best effort" means there. we look at numItems documents and then apply the filter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh interesting. I thought we tried with some limit to fill numItems. If we're truly just fetching numItems then why offer filter at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as a convenience to make it easy to switch from the native syntax, and because the filter() convex-helper doesn't compose with this helper
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had assumed it would work harder to ensure it returned numItems so I'd rather snip it and just suggest folks do
(await getPageOfQuery(ctx, ...)).filter(doc => doc.isGood)This also means that the type of paginator(ctx, schema, tableName) could just be the same as db.query (and just throw at runtime for unimplemented functions) since all the syntax would conform as a subset.
heh PaginationOptions only has those two fields: cursor and numItems (the other fields are internal so they're not in the typescript) |
| Interesting - the thing is that when I click through to see what the heck is in there, I end up looking at the type that includes the internal fields. Maybe I'm using it wrong, but I often click through when I see opaque types like PaginationOptions b/c auto-complete doesn't do much until you have something you can start tab-completing …On Mon, Nov 4, 2024 at 8:35 PM Lee Danilek ***@***.***> wrote: is it expected to pass in paginationOpts? I suspect we'll not use all those values, just the cursor & numItems heh PaginationOptions only has those two fields: cursor and numItems (the other fields are internal so they're not in the typescript) — Reply to this email directly, view it on GitHub <#337 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AACZQW34L5QQOEPAATCZQGLZ7A4IXAVCNFSM6AAAAABRDD4CWSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINJWGIYTIMZRGM> . You are receiving this because your review was requested.Message ID: ***@***.***> |
Makes sense. I was also confused why |
Tradeoffs of requiring schema:
I like the syntax you suggest. I'll try it. |
| btw i think the type inference might work better if i pass in the db directly instead of a full ctx. Thoughts? |
yeah I've found that to be true. One pro of passing in schema is you can pull the data model from that more reliably than |
Co-authored-by: Ian Macartney <ian@convex.dev>
Co-authored-by: Ian Macartney <ian@convex.dev>
…nvex/convex-helpers into lee/get-page-non-reactive
Co-authored-by: Ian Macartney <ian@convex.dev>
ianmacartney left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very nice!
| }).index("abc", ["a", "b", "c"]), | ||
| }); | ||
| | ||
| type DataModel = DataModelFromSchemaDefinition<typeof schema>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like this is unused according to github?
Co-authored-by: Ian Macartney <ian@convex.dev>
Co-authored-by: Ian Macartney <ian@convex.dev>
Create a new convex-helpers function
paginatorthat complementsgetPage.See the README and the docstring for usage details.
I would like to ship this so we can recommend it for customers running into the limitations of
.paginatewithout teaching them the new concept of IndexKeys. In particular I want to use it in themigrationscomponent and suggest component authors use it in their components.By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.