Pagination
The pagination helpers turn three numbers — items per page, total item count, and the current page —
into everything you need to render a paged list: offsets, page counts, the first and last item on a
page, and boundary checks. There are two entry points: the Paginator class and the pagination
factory.
import { pagination, Paginator } from '@0x26e/utils'The pagination factory
pagination(perPage, itemCount) is a one-line shortcut that creates a Paginator, sets the items
per page, and sets the total item count — leaving you to set the page.
function pagination(perPage: number, itemCount: number): PaginatorParameters
| Parameter | Type | Description |
|---|---|---|
perPage | number | The number of items shown on each page. |
itemCount | number | The total number of items across all pages. |
Returns Paginator — a configured instance, ready for .setPage(...).
Worked example
A list of 100 items, 10 per page, viewing page 2:
import { pagination } from '@0x26e/utils'
const page = pagination(10, 100).setPage(2)
page.getPage() // 2
page.getFirstItemOnPage() // 11
page.getLastItemOnPage() // 20
page.getPageCount() // 10
page.getOffset() // 10
page.getCountdownOffset() // 80
page.getLength() // 10
page.getFirstPage() // 1
page.getLastPage() // 10
page.isFirst() // false
page.isLast() // falseUse getOffset() and getLength() to slice your data — they map directly onto a SQL
LIMIT/OFFSET or Array.prototype.slice:
const all = await db.items.count() // 100
const page = pagination(10, all).setPage(2)
const rows = await db.items.findMany({
skip: page.getOffset(), // 10
take: page.getLength(), // 10
})A last-page example shows how getLength shrinks for a partial final page. With 95 items, 10 per
page, page 10 holds only 5 items:
const last = pagination(10, 95).setPage(10)
last.getPageCount() // 10
last.getLength() // 5 (only 5 items on the final page)
last.isLast() // trueThe Paginator class
pagination() is built on the Paginator class. Construct it directly when you want to set values
step by step — every setter returns the instance, so calls chain.
const paginator = new Paginator()
paginator.setPage(2).setItemsPerPage(10).setItemCount(100)
paginator.getPage() // 2
paginator.getFirstItemOnPage() // 11
paginator.getLastItemOnPage() // 20
paginator.getPageCount() // 10
paginator.isFirst() // false
paginator.isLast() // falseBase page and clamping
By default pages are 1-based — the first page is 1. Change this with setBase(...) if your
UI counts from 0. The current page is also clamped to a valid range when itemCount is known, so
asking for a page beyond the last returns the last page's values rather than going out of bounds.
Some getters return null until itemCount is set
Paginator works without a total count, but anything that depends on knowing how many items exist —
getLastPage, getPageCount, getCountdownOffset, and the item count — returns null until you
call setItemCount(...). The pagination() factory always sets it, so they return numbers there.
Setters
Each setter mutates the instance and returns this for chaining.
| Method | Returns | Description |
|---|---|---|
setPage(page: number) | this | Sets the current page number. |
setItemsPerPage(itemsPerPage: number) | this | Sets items per page (floored at 1). |
setItemCount(itemCount?: number | null) | this | Sets the total item count (floored at 0); pass null to clear it. |
setBase(base: number) | this | Sets the base page number (the number of the first page). |
Getters & checks
| Method | Returns | Description |
|---|---|---|
getPage() | number | The current page number (clamped to the valid range when item count is known). |
getBase() | number | The base page number. |
getFirstPage() | number | The first page number (equal to the base). |
getLastPage() | number | null | The last page number, or null if item count is not set. |
getFirstItemOnPage() | number | Sequence number of the first item on the current page (0 when there are no items). |
getLastItemOnPage() | number | Sequence number of the last item on the current page. |
getPageCount() | number | null | Total number of pages, or null if item count is not set. |
getOffset() | number | Absolute index of the first item on the current page (page index × items per page). |
getCountdownOffset() | number | null | Absolute index of the first item counting from the end, or null if item count is not set. |
getLength() | number | Number of items on the current page (less than the page size on a partial final page). |
getItemCount() | number | null | The total number of items, or null if not set. |
getItemsPerPage() | number | The number of items per page. |
isFirst() | boolean | true when the current page is the first page. |
isLast() | boolean | true when the current page is the last page (false if item count is not set). |
getOffset vs getCountdownOffset
getOffset() is the index of the current page's first item counted from the start of the list —
use it for OFFSET. getCountdownOffset() is that same first item counted from the end, which
is handy for "newest first" feeds where you page backwards through a fixed total. On page 2 of 100
items at 10 per page, getOffset() is 10 while getCountdownOffset() is 80.