Skip to content

Use built-in pagination instead of paginator - #88

Open
ianmacartney wants to merge 2 commits into
mainfrom
ian/built-in-paginate
Open

ianmacartney wants to merge 2 commits into
mainfrom
ian/built-in-paginate

Conversation

@ianmacartney

@ianmacartney ianmacartney commented Oct 15, 2026 •

Copy link
Copy Markdown
Member
  • src/component/lib.ts: listMetadata now uses built-in ctx.db.query("metadata").withIndex("bucket", ...).paginate(...) instead of paginator from convex-helpers/server/pagination. Return shape is unchanged (paginationReturnValidator already allows splitCursor/pageStatus).
  • convex-helpers stays in package.json because asyncMap is still imported.
  • devDependency convex-test temporarily points at https://pkg.pr.new/convex-test@163, which enforces the one-.paginate()-per-transaction rule, until a real release.

Notes:

  • Depends on the upcoming Convex backend release that lets components call .paginate() once per transaction (shared across the app function and nested component calls). An app calling listMetadata (via R2.listMetadata or the generated clientApi().listMetadata) in a transaction that already paginated, or calling it twice in one transaction, will get an error.
  • Cursor format changes: paginator cursors were JSON arrays, built-in cursors are opaque strings. Cursors held by clients across the deploy won't be valid. The component does not persist cursors.

Separate fix: listMetadata dropped endCursor (existed before this PR)

clientApi().listMetadata accepted paginationOpts but forwarded only numItems and cursor to the component. endCursor was dropped, so pages from usePaginatedQuery could shift, leaving gaps or overlaps between pages. This bug existed before this PR; the paginator version had it too.

  • Component API change (additive): lib.listMetadata takes new optional args endCursor (string | null), maximumRowsRead and maximumBytesRead, and passes them to .paginate(). src/component/_generated/component.ts was regenerated with npm run build:codegen.
  • R2.listMetadata(ctx, limit?, cursor?, opts?) takes a new optional fourth argument { endCursor?, maximumRowsRead?, maximumBytesRead? }.
  • clientApi().listMetadata forwards those fields from paginationOpts.
  • Added src/component/lib.test.ts, which checks that endCursor ends the page at that cursor whatever limit is.

Switch listMetadata to ctx.db.query(...).paginate(). Temporarily
install convex-test from pkg.pr.new (convex-test#163).
@pkg-pr-new

pkg-pr-new Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@convex-dev/r2@88

commit: a66f123

listMetadata previously dropped paginationOpts.endCursor, so pages from
usePaginatedQuery could shift. Add optional endCursor, maximumRowsRead
and maximumBytesRead args to the component's listMetadata and forward
them from the client.
@ianmacartney
ianmacartney marked this pull request as ready for review October 15, 2026 04:36
@ianmacartney

Copy link
Copy Markdown
Member Author

Hold until 10/22.

@coderabbitai

coderabbitai Bot commented Oct 15, 2026

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: get-convex/coderabbit/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 98c178b6-79c1-407b-950c-441e05fcd8f3
📥 Commits

Reviewing files that changed from the base of the PR and between e70ed03 and a66f123.

⛔ Files ignored due to path filters: 2
  • package-lock.json is excluded by !**/package-lock.json
  • src/component/_generated/component.ts is excluded by !**/_generated/**
📒 Files selected for processing: 4
  • package.json
  • src/client/index.ts
  • src/component/lib.test.ts
  • src/component/lib.ts

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Walkthrough

R2.listMetadata now accepts endCursor, maximumRowsRead, and maximumBytesRead. The client API forwards these values to the component query, which passes them to the database’s native paginate method instead of using the helper paginator. A new test checks the initial page, an endCursor result, and retrieval of the remaining records with a continuation cursor.

Sequence Diagram(s)

sequenceDiagram
  participant clientApi
  participant R2listMetadata
  participant componentListMetadata
  participant database
  clientApi->>R2listMetadata: Forward pagination options
  R2listMetadata->>componentListMetadata: Pass endCursor and read limits
  componentListMetadata->>database: Call paginate with pagination options
Loading

Priority: ➖ Normal

Change: Refactor

Merge Risk: ⚪ Minimal · up to a66f1

The pagination change is mergeable after normal checks; no actionable risk remains identified.

Pre-merge checks: Passed 4
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly summarizes the primary change: replacing the existing paginator with built-in pagination for listMetadata.
Description check Passed The description is directly related to the changeset. It explains the pagination implementation, API updates, endCursor fix, dependency change, compatibility constraints, and cursor behavior.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant