One newest-first page of lightweight durable run summaries.
Run pagination uses the immutable (started_at, run_id) pair as a stable
keyset. A backend reads at most one row beyond the requested limit and passes
those already ordered candidates to new/3, which centralizes trimming and
cursor derivation across storage implementations. Ordering and cursor
exclusivity are storage-behaviour contracts; this value does not revalidate
trusted backend output.
Summary
Functions
Builds a page from newest-first candidates containing at most limit + 1 rows.
Types
@type cursor() :: {DateTime.t(), String.t()}
Cursor selecting runs strictly older than this immutable key.
@type t() :: %Docket.RunPage{ has_more?: boolean(), next_before: cursor() | nil, runs: [Docket.RunSummary.t()] }
Functions
@spec new([Docket.RunSummary.t()], cursor() | nil, pos_integer()) :: t()
Builds a page from newest-first candidates containing at most limit + 1 rows.
The extra candidate determines has_more? and is not returned. The next
cursor is the last returned run's (started_at, id) key. An empty page keeps
the supplied cursor, matching the cursor-preserving semantics of
Docket.EventPage.