Initial Commit
This commit is contained in:
92
packages/foundation/data/pagination/README.md
Normal file
92
packages/foundation/data/pagination/README.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# @suaveplan/pagination - Universal pagination primitives: cursor, offset, keyset strategies with adapters, iterators, and type-safe request/response shapes.
|
||||
|
||||
## Summary
|
||||
|
||||
Universal pagination primitives for cursor-based, offset-based, and keyset-based (seek) pagination strategies. The package covers the full pagination surface: request normalisation, response envelope construction, opaque cursor and page-token encoding, async iterators that drain pages automatically, a pluggable adapter interface for any data source, and optional OpenTelemetry instrumentation. All three strategies share the same error hierarchy and Zod schemas so they compose cleanly in multi-strategy APIs.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [adapters](./src/adapters/database-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [database-adapter](./src/adapters/database-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [cursor](./src/cursor/cursor.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [cursor-pagination](./src/cursor/cursor-pagination.md) — The `cursor-pagination` module provides base64url cursor encoding/decoding and adapter-backed forward/backward fetch op…
|
||||
- [cursor](./src/cursor/cursor.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [codes](./src/errors/codes.md) — Defines and registers all stable error codes for the `@suaveplan/pagination` package using `defineCodes` from `@suavepl…
|
||||
- [pagination-error](./src/errors/pagination-error.md) — `PaginationError` is the structured error base class for all failures originating within `@suaveplan/pagination`. It ex…
|
||||
- [helpers](./src/helpers/helpers.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [helpers](./src/helpers/helpers.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [keyset](./src/keyset/keyset-pagination.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [keyset-pagination](./src/keyset/keyset-pagination.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [offset](./src/offset/offset.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [offset](./src/offset/offset.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [otel](./src/otel/pagination-otel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [pagination-otel](./src/otel/pagination-otel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [tokens](./src/tokens/page-tokens.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [page-tokens](./src/tokens/page-tokens.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
<!-- end:auto-docs --> - [database-adapter](./src/adapters/database-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_- [cursor](./src/cursor/cursor.md) — <!-- begin:auto-docs --> _(no submodules)_- [cursor-pagination](./src/cursor/cursor-pagination.md) — The `cursor-pagination` module provides base64url cursor encoding/decoding and adapter-backed forward/backward fetch op…
|
||||
- [cursor](./src/cursor/cursor.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes.md) — Defines and registers all stable error codes for the `@suaveplan/pagination` package using `defineCodes` from `@suavepl…
|
||||
- [pagination-error](./src/errors/pagination-error.md) — `PaginationError` is the structured error base class for all failures originating within `@suaveplan/pagination`. It ex…
|
||||
- [helpers](./src/helpers/helpers.md) — <!-- begin:auto-docs --> _(no submodules)_- [helpers](./src/helpers/helpers.md) — <!-- begin:auto-docs --> _(no submodules)_- [keyset](./src/keyset/keyset-pagination.md) — <!-- begin:auto-docs --> _(no submodules)_- [keyset-pagination](./src/keyset/keyset-pagination.md) — <!-- begin:auto-docs --> _(no submodules)_- [offset](./src/offset/offset.md) — <!-- begin:auto-docs --> _(no submodules)_- [offset](./src/offset/offset.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/pagination-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [pagination-otel](./src/otel/pagination-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [tokens](./src/tokens/page-tokens.md) — <!-- begin:auto-docs --> _(no submodules)_- [page-tokens](./src/tokens/page-tokens.md) — <!-- begin:auto-docs --> _(no submodules)_- [database-adapter](./src/adapters/database-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_- [cursor](./src/cursor/cursor.md) — <!-- begin:auto-docs --> _(no submodules)_- [cursor-pagination](./src/cursor/cursor-pagination.md) — The `cursor-pagination` module provides base64url cursor encoding/decoding and adapter-backed forward/backward fetch op…
|
||||
- [cursor](./src/cursor/cursor.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes.md) — Defines and registers all stable error codes for the `@suaveplan/pagination` package using `defineCodes` from `@suavepl…
|
||||
- [pagination-error](./src/errors/pagination-error.md) — `PaginationError` is the structured error base class for all failures originating within `@suaveplan/pagination`. It ex…
|
||||
- [helpers](./src/helpers/helpers.md) — <!-- begin:auto-docs --> _(no submodules)_- [helpers](./src/helpers/helpers.md) — <!-- begin:auto-docs --> _(no submodules)_- [keyset](./src/keyset/keyset-pagination.md) — <!-- begin:auto-docs --> _(no submodules)_- [keyset-pagination](./src/keyset/keyset-pagination.md) — <!-- begin:auto-docs --> _(no submodules)_- [offset](./src/offset/offset.md) — <!-- begin:auto-docs --> _(no submodules)_- [offset](./src/offset/offset.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/pagination-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [pagination-otel](./src/otel/pagination-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [tokens](./src/tokens/page-tokens.md) — <!-- begin:auto-docs --> _(no submodules)_- [page-tokens](./src/tokens/page-tokens.md) — <!-- begin:auto-docs --> _(no submodules)_- [database-adapter](./src/adapters/database-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_- [cursor](./src/cursor/cursor.md) — <!-- begin:auto-docs --> _(no submodules)_- [cursor-pagination](./src/cursor/cursor-pagination.md) — The `cursor-pagination` module provides base64url cursor encoding/decoding and adapter-backed forward/backward fetch op…
|
||||
- [cursor](./src/cursor/cursor.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes.md) — Defines and registers all stable error codes for the `@suaveplan/pagination` package using `defineCodes` from `@suavepl…
|
||||
- [pagination-error](./src/errors/pagination-error.md) — `PaginationError` is the structured error base class for all failures originating within `@suaveplan/pagination`. It ex…
|
||||
- [helpers](./src/helpers/helpers.md) — <!-- begin:auto-docs --> _(no submodules)_- [helpers](./src/helpers/helpers.md) — <!-- begin:auto-docs --> _(no submodules)_- [keyset](./src/keyset/keyset-pagination.md) — <!-- begin:auto-docs --> _(no submodules)_- [keyset-pagination](./src/keyset/keyset-pagination.md) — <!-- begin:auto-docs --> _(no submodules)_- [offset](./src/offset/offset.md) — <!-- begin:auto-docs --> _(no submodules)_- [offset](./src/offset/offset.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/pagination-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [pagination-otel](./src/otel/pagination-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [tokens](./src/tokens/page-tokens.md) — <!-- begin:auto-docs --> _(no submodules)_- [page-tokens](./src/tokens/page-tokens.md) — <!-- begin:auto-docs --> _(no submodules)_- [database-adapter](./src/adapters/database-adapter.md) — <!-- begin:auto-docs --> _(no submodules)_- [cursor](./src/cursor/cursor.md) — <!-- begin:auto-docs --> _(no submodules)_ - [cursor-pagination](./src/cursor/cursor-pagination.md) — The `cursor-pagination` module provides base64url cursor encoding/decoding and adapter-backed forward/backward fetch op…
|
||||
- [cursor](./src/cursor/cursor.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes.md) — Defines and registers all stable error codes for the `@suaveplan/pagination` package using `defineCodes` from `@suavepl…
|
||||
- [pagination-error](./src/errors/pagination-error.md) — `PaginationError` is the structured error base class for all failures originating within `@suaveplan/pagination`. It ex…
|
||||
- [helpers](./src/helpers/helpers.md) — <!-- begin:auto-docs --> _(no submodules)_ - [helpers](./src/helpers/helpers.md) — <!-- begin:auto-docs --> _(no submodules)_- [keyset](./src/keyset/keyset-pagination.md) — <!-- begin:auto-docs --> _(no submodules)_ - [keyset-pagination](./src/keyset/keyset-pagination.md) — <!-- begin:auto-docs --> _(no submodules)_- [offset](./src/offset/offset.md) — <!-- begin:auto-docs --> _(no submodules)_ - [offset](./src/offset/offset.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/pagination-otel.md) — <!-- begin:auto-docs --> _(no submodules)_ - [pagination-otel](./src/otel/pagination-otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [tokens](./src/tokens/page-tokens.md) — <!-- begin:auto-docs --> _(no submodules)_ - [page-tokens](./src/tokens/page-tokens.md) — <!-- begin:auto-docs --> _(no submodules)_
|
||||
## Install
|
||||
|
||||
```bash
|
||||
bun add @suaveplan/pagination
|
||||
```
|
||||
|
||||
## Quick start
|
||||
|
||||
```ts
|
||||
import { paginateArray } from "@suaveplan/pagination/offset";
|
||||
import { cursorPaginateArray } from "@suaveplan/pagination/cursor";
|
||||
import { createOffsetIterator, collectAll } from "@suaveplan/pagination/helpers";
|
||||
|
||||
// Offset: slice page 2, 10 items per page
|
||||
const items = Array.from({ length: 50 }, (_, i) => ({ id: i + 1 }));
|
||||
const page2 = paginateArray(items, 2, 10);
|
||||
// page2.data → items 11–20
|
||||
// page2.meta.totalPages → 5, page2.meta.hasNext → true
|
||||
|
||||
// Cursor: paginate an in-memory array by item.id
|
||||
const users = [{ id: "a" }, { id: "b" }, { id: "c" }, { id: "d" }];
|
||||
const first = cursorPaginateArray(users, { limit: 2 }, (u) => u.id);
|
||||
// first.meta.endCursor → "b", first.meta.hasNextPage → true
|
||||
const second = cursorPaginateArray(
|
||||
users,
|
||||
{ cursor: first.meta.endCursor ?? undefined, limit: 2 },
|
||||
(u) => u.id
|
||||
);
|
||||
// second.data → [{ id: "c" }, { id: "d" }]
|
||||
|
||||
// Helpers: drain all pages into a flat array
|
||||
const iter = createOffsetIterator(
|
||||
(page, limit) => Promise.resolve(paginateArray(items, page, limit)),
|
||||
{ limit: 10 }
|
||||
);
|
||||
const all = await collectAll(iter); // → all 50 items
|
||||
```
|
||||
|
||||
## Modules
|
||||
|
||||
| Module | Description |
|
||||
|--------|-------------|
|
||||
| [src/cursor/cursor.md](src/cursor/cursor.md) | In-memory cursor pagination building blocks: `cursorPaginateArray`, `createEdges`, `createConnection`, `calculateCursorMeta`, `normalizeCursorRequest` |
|
||||
| [src/cursor/cursor-pagination.md](src/cursor/cursor-pagination.md) | Adapter-backed cursor pagination: `encodeCursor`, `decodeCursor`, `validateCursor`, `fetchAfter`, `fetchBefore` |
|
||||
| [src/offset/offset.md](src/offset/offset.md) | Offset/page-number pagination: `paginateArray`, `normalizeOffsetRequest`, `calculateOffsetMeta`, `pageToOffset`, `offsetToPage`, `getPageRange`, `estimateTotalCount` |
|
||||
| [src/keyset/keyset-pagination.md](src/keyset/keyset-pagination.md) | Seek-based keyset pagination: `keysetPaginate`, `fetchKeysetPage`, `encodeKeysetCursor`, `decodeKeysetCursor`, `extractSortKeys` |
|
||||
| [src/helpers/helpers.md](src/helpers/helpers.md) | Higher-order iteration utilities: `createOffsetIterator`, `createCursorIterator`, `collectAll`, `collectUpTo`, `mapPaginated`, `mergeOffsetResponses` |
|
||||
| [src/adapters/database-adapter.md](src/adapters/database-adapter.md) | `PaginationAdapter` interface, `MemoryPaginationAdapter`, and `createMemoryAdapter` factory |
|
||||
| [src/tokens/page-tokens.md](src/tokens/page-tokens.md) | Opaque page tokens with sort and filter metadata: `createCursorToken`, `createOffsetToken`, `encodePageToken`, `decodePageToken`, `hashFilters`, `validateTokenFilter` |
|
||||
| [src/otel/pagination-otel.md](src/otel/pagination-otel.md) | OTel instrumentation: `getPaginationInstruments` with request counter, page-size histogram, and encode/decode histogram; graceful no-op fallback |
|
||||
| [src/errors/pagination-error.md](src/errors/pagination-error.md) | `PaginationError` — structured error class extending `SuaveplanError` with `PAGINATION.*` codes |
|
||||
| [src/errors/codes.md](src/errors/codes.md) | `PAGINATION_CODES` constant and `PaginationCode` union type |
|
||||
|
||||
Reference in New Issue
Block a user