cursor

package
v0.10.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 6, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidCursor        = errors.New("invalid cursor")
	ErrCursorGeneration     = errors.New("cursor generation mismatch")
	ErrCursorExpired        = errors.New("cursor has expired")
	ErrCursorTenantMismatch = errors.New("cursor tenant mismatch")
)

Functions

func Decode

func Decode[T any](cur string, opts ...DecodeOption) (T, error)

Decode parses an opaque string back into its payload, verifying the configured generation, expiry, and tenant checks. Returns ErrInvalidCursor for a malformed token, ErrCursorGeneration / ErrCursorExpired / ErrCursorTenantMismatch for the corresponding rejections.

The MessagePack structure is checked before decoding: a declared container or payload length longer than the input that remains is ErrInvalidCursor, so decoding allocates at most in proportion to the cursor's size. Bound the cursor's length before calling.

An empty cursor is caller-semantic (first page vs error), so Decode does not special-case it — check for the empty cursor before calling.

func Encode

func Encode[T any](payload T, opts ...EncodeOption) (string, error)

Encode serializes payload into an opaque, URL-safe string via msgpack + base64url, wrapped in an Envelope carrying the configured metadata. The result round-trips through query strings without further escaping.

Types

type DecodeOption

type DecodeOption func(*decodeConfig)

DecodeOption configures Decode.

func ExpectGeneration

func ExpectGeneration(g uint32) DecodeOption

ExpectGeneration rejects a cursor whose generation differs from g with ErrCursorGeneration. Omit to skip the check.

func ExpectTenantHash

func ExpectTenantHash(h uint64) DecodeOption

ExpectTenantHash rejects a cursor whose tenant fingerprint differs from h with ErrCursorTenantMismatch. Omit to skip the check.

func WithDecodeClock

func WithDecodeClock(now func() time.Time) DecodeOption

WithDecodeClock overrides the expiry clock. Default time.Now().UTC.

type EncodeOption

type EncodeOption func(*encodeConfig)

EncodeOption configures Encode.

func WithClock

func WithClock(now func() time.Time) EncodeOption

WithClock overrides the issuance clock. Default time.Now().UTC.

func WithExpiresAt

func WithExpiresAt(unixSec int64) EncodeOption

WithExpiresAt stamps an explicit unix-second expiry, overriding WithTTL. Use when the caller already knows the absolute expiry wall clock.

func WithGeneration

func WithGeneration(g uint32) EncodeOption

WithGeneration stamps the cursor's format generation.

func WithTTL

func WithTTL(ttl time.Duration) EncodeOption

WithTTL sets the cursor to expire ttl after issuance (from the encode clock). A non-positive ttl leaves the cursor with no expiry. Overridden by WithExpiresAt.

func WithTenantHash

func WithTenantHash(h uint64) EncodeOption

WithTenantHash stamps the owning tenant's fingerprint.

type Envelope

type Envelope[T any] struct {
	// Generation is the caller's cursor format version. Checked on Decode via
	// [ExpectGeneration]; a mismatch yields [ErrCursorGeneration].
	Generation uint32 `msgpack:"g,omitempty"`

	// ExpiresAt is the unix-second wall clock after which Decode rejects the
	// cursor with [ErrCursorExpired]. Zero means no expiry.
	ExpiresAt int64 `msgpack:"e,omitempty"`

	// TenantHash is an optional fingerprint of the owning tenant. Checked on
	// Decode via [ExpectTenantHash]; a mismatch yields [ErrCursorTenantMismatch].
	// Zero means unrestricted.
	TenantHash uint64 `msgpack:"h,omitempty"`

	// Payload is the consumer's resume position.
	Payload T `msgpack:"p"`
}

Envelope carries a keyset payload and its format generation. Expiry and tenant metadata retain their established wire meaning.

func DecodeEnvelope

func DecodeEnvelope[T any](cur string, opts ...DecodeOption) (Envelope[T], error)

DecodeEnvelope is Decode that returns the full Envelope rather than only the payload, for consumers that reflect the generation / expiry / tenant metadata back onto their own cursor type. Runs the same checks as Decode.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL