Skip to main content

Module cursor

Module cursor 

Expand description

Opaque keyset-cursor encoding shared by generated list routes and hand-written CursorPageInput/CursorPage<T> procedures (docs/design/cursor-pagination.md).

A cursor is base64url(json({"o": <order>, "v": [<value>|null, ..]})): the effective sort order it was minted for and the last row’s value for each ordering column (primary-key tiebreaker last), each rendered as the same wire string a ?field__gt= filter would carry. It is not signed: the server never trusts it for anything a caller could not already express as a filter — the decoded values re-enter the normal typed filter path and are ANDed with the read policy.

Constants§

MAX_CURSOR_LEN
Upper bound on an accepted cursor’s length in characters. Cursors are attacker-controlled input; this bounds decode work before any parsing.

Functions§

cursor_scalar
Render one ordering-column value as its cursor wire string through serde (DateTime → RFC 3339, Uuid → hyphenated, numbers → decimal). None for SQL NULL. Arrays/objects are not orderable scalars.
decode_cursor
Decode and validate a cursor against the order the request resolved to. Every failure is a CratestackError::BadRequest (RPC invalid_argument): oversized, not base64url/JSON, minted for a different order, or carrying the wrong number of values.
encode_cursor
Mint a cursor for order (the canonical effective sort, e.g. "-createdAt,id") from the last row’s per-column wire values; None is SQL NULL.