Ark.Paginator (ark v0.13.0)

Copy Markdown View Source

Summary

Functions

Accepts an initial state and a pagination callback and immediately calls the callback with the initial state.

Types

paginator_fun()

@type paginator_fun() :: (state() ->
                      {:cont, Enumerable.t(), state()}
                      | {:halt, Enumerable.t()}
                      | {:error, term()})

state()

@type state() :: term()

Functions

stream(initial_state, callback)

@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 with new_state. Items can be any Enumerable (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 reason is itself an exception struct, it is raised as-is.
    • Otherwise, a Ark.Paginator.CallbackError is raised with reason set on the struct.

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]