# `Plushie.Data`
[🔗](https://github.com/plushie-ui/plushie-elixir/blob/v0.7.2/lib/plushie/data.ex#L1)

Query pipeline for in-memory record collections. Pure functions
supporting filter, search, sort, group, and pagination.

All operations are applied in order: filter, search, sort, then paginate.
Grouping is applied to the paginated results. Repeated `:filter` and
repeated `:search` entries compose in keyword-list order as successive
narrowing steps within their stage.

Each pipeline step creates intermediate list copies. For small to moderate
collections (up to a few thousand records) this is fine. For very large
datasets, consider filtering or paginating at the data source (database
query, API call) rather than loading everything into memory.

## Example

    records = [
      %{name: "Alice", age: 30},
      %{name: "Bob", age: 25},
      %{name: "Carol", age: 35}
    ]

    result = Plushie.Data.query(records,
      filter: &(&1.age > 24),
      sort: {:asc, :name},
      page: 1,
      page_size: 10
    )

    result.entries
    #=> [%{name: "Alice", age: 30}, %{name: "Bob", age: 25}, %{name: "Carol", age: 35}]
    result.total
    #=> 3

# `result`

```elixir
@type result() :: %{
  entries: [map()],
  total: non_neg_integer(),
  page: pos_integer(),
  page_size: pos_integer(),
  groups: %{optional(term()) =&gt; [map()]} | nil
}
```

Query result with paginated entries, total count, and optional grouping.

# `query`

```elixir
@spec query(records :: [map()], opts :: keyword()) :: result()
```

Queries a list of records with optional filtering, searching, sorting,
grouping, and pagination.

## Options

- `:filter` - a function `(record -> boolean)` to filter records. Repeated
  `:filter` entries are applied in keyword-list order.
- `:search` - a `{fields, query_string}` tuple. `fields` is a list of
  map keys to search; `query_string` is case-insensitive substring-matched.
  Repeated `:search` entries are applied in keyword-list order.
- `:sort` - a `{direction, field}` tuple or list of tuples.
  Direction is `:asc` or `:desc`. Field is a map key.
- `:group` - a map key to group paginated results by.
- `:page` - page number (1-based). Default: 1.
- `:page_size` - records per page. Default: 25.

Returns a result map with `:entries`, `:total`, `:page`, and `:page_size`.
If `:group` is specified, `:groups` is also included.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
