Summary
Functions
Accepts an initial state and a pagination callback and immediately calls the callback with the initial state.
Types
@type paginator_fun() :: (state() -> {:cont, Enumerable.t(), state()} | {:halt, Enumerable.t()} | {:error, term()})
@type state() :: term()
Functions
@spec stream(state(), paginator_fun()) :: {:ok, Enumerable.t()} | {:error, term()}
Accepts an initial state and a pagination callback and immediately calls the callback with the initial state.
The callback receives the current state and must return one of:
{:cont, items, new_state}: Yields items into the stream and continues pagination withnew_state. Items can be anyEnumerable(list or stream).{:halt, items}: Yields a final set of items and stops. The callback will not be called again. Useful when the current response already signals it was the last page, so no extra request is needed.{:error, reason}: Stops pagination with an error.
Return shapes
{:ok, stream}when the first call returns{:cont, items, new_state}. The stream lazily concatenates the items from this and all following pages.{:ok, items}when the first call returns{:halt, items}. No stream is built; pagination ends immediately and the items are returned as-is.{:error, reason}when the first call returns{:error, reason}. The callback's error tuple is returned unchanged.
Error handling
Errors are surfaced differently depending on when they happen:
- On the first call,
{:error, reason}is returned as a tagged tuple so that initial failures (auth, network, bad config) can be handled without exception machinery. - On subsequent calls, the error is raised, since a stream has no way to
surface an error tuple to its consumer:
- If
reasonis itself an exception struct, it is raised as-is. - Otherwise, a
Ark.Paginator.CallbackErroris raised withreasonset on the struct.
- If
Example
iex> pages = %{1 => [1, 2, 3], 2 => [98, 99, 100]}
iex> {:ok, stream} =
...> Ark.Paginator.stream(1, fn page ->
...> case Map.get(pages, page, []) do
...> [] -> {:halt, []}
...> items -> {:cont, items, page + 1}
...> end
...> end)
iex> Enum.to_list(stream)
[1, 2, 3, 98, 99, 100]