Monzo.Pagination (monzo_client v1.0.0)

Copy Markdown View Source

Generic, lazy pagination built on Stream.resource/3 for Monzo list endpoints that are ordered oldest-first and support a since cursor plus a page limit.

Summary

Functions

Builds a lazy Stream that walks every page of a paginated endpoint, yielding individual items.

Functions

stream(fetch_page, cursor_fun, opts \\ [])

@spec stream(
  (String.t() | nil, pos_integer() -> {:ok, [item]} | {:error, term()}),
  (item -> String.t() | nil),
  keyword()
) :: Enumerable.t()
when item: term()

Builds a lazy Stream that walks every page of a paginated endpoint, yielding individual items.

fetch_page is called with since (a cursor string or nil) and limit, and must return {:ok, items} or {:error, reason}. The last item's cursor_fun.(item) becomes the next page's since value. A page shorter than limit (or empty) ends the stream.

If fetch_page returns an error, the stream halts and raises that error via Stream.resource/3's natural propagation - wrap consumption in try/rescue or use Enum.reduce_while/3 if you need to handle paging errors without an exception. Most callers will simply use Enum.to_list/1, Enum.take/2, or a for comprehension.

Example

fetch_page = fn since, limit ->
  Monzo.Transactions.list(client, %{account_id: account_id, since: since, limit: limit})
end

Monzo.Pagination.stream(fetch_page, &Monzo.Transaction.cursor_value/1, page_size: 100)
|> Enum.each(fn tx -> IO.inspect(tx.id) end)