-
-
Notifications
You must be signed in to change notification settings - Fork 502
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
feat(core): add cursor-based pagination via em.findByCursor()
#3975
Conversation
TODO: - [ ] more tests - [ ] how to handle relations? - [ ] docs
Codecov ReportBase: 99.66% // Head: 99.64% // Decreases project coverage by
📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more Additional details and impacted files@@ Coverage Diff @@
## v6 #3975 +/- ##
==========================================
- Coverage 99.66% 99.64% -0.02%
==========================================
Files 215 216 +1
Lines 13683 13833 +150
Branches 3208 3256 +48
==========================================
+ Hits 13637 13784 +147
- Misses 44 47 +3
Partials 2 2
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
https://opensource.huntersofbook.com/global/relay-cursor Great, now I can use it directly with graphql and the library I wrote. Thank you Martin |
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
…o-orm#3975) As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
…o-orm#3975) As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
This is a wonderful feature. Just a quick feedback @B4nan : in most API I have used with cursor based, the totalCount is not returned (what we are interested is only knowing if there is a next or prev page), which avoids a potentially costly SQL count. What about removing the count by default, and add an optional |
I am not sure if this should be disabled by default, but I am open to having an option to control it. |
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with `limit` and `offset`, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can use `em.findByCursor()` to access those options. Under the hood, it will call `em.find()` and `em.count()` just like the `em.findAndCount()` method, but will use the cursor options instead. Supports `before`, `after`, `first` and `last` options while disallowing `limit` and `offset`. Explicit `orderBy` option is required. Use `first` and `after` for forward pagination, or `last` and `before` for backward pagination. - `first` and `last` are numbers and serve as an alternative to `offset`, those options are mutually exclusive, use only one at a time - `before` and `after` specify the previous cursor value, it can be one of the: - `Cursor` instance - opaque string provided by `startCursor/endCursor` properties - POJO/entity instance ```ts const currentCursor = await em.findByCursor(User, {}, { first: 10, after: previousCursor, // cursor instance orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor = await em.findByCursor(User, {}, { first: 10, after: currentCursor.endCursor, // opaque string orderBy: { id: 'desc' }, }); // to fetch next page const nextCursor2 = await em.findByCursor(User, {}, { first: 10, after: { id: lastSeenId }, // entity-like POJO orderBy: { id: 'desc' }, }); ``` The `Cursor` object provides following interface: ```ts Cursor<User> { items: [ User { ... }, User { ... }, User { ... }, ... ], totalCount: 50, length: 10, startCursor: 'WzRd', endCursor: 'WzZd', hasPrevPage: true, hasNextPage: true, } ```
As an alternative to the offset based pagination with
limit
andoffset
, we can paginate based on a cursor. A cursor is an opaque string that defines specific place in ordered entity graph. You can useem.findByCursor()
to access those options. Under the hood, it will callem.find()
andem.count()
just like theem.findAndCount()
method, but will use the cursor options instead.Supports
before
,after
,first
andlast
options while disallowinglimit
andoffset
. ExplicitorderBy
option is required.Use
first
andafter
for forward pagination, orlast
andbefore
for backward pagination.first
andlast
are numbers and serve as an alternative tooffset
, those options are mutually exclusive, use only one at a timebefore
andafter
specify the previous cursor value, it can be one of the:Cursor
instancestartCursor/endCursor
propertiesThe
Cursor
object provides following interface: