# `Runic.Workflow.Accumulator`
[🔗](https://github.com/zblanco/runic/blob/main/lib/workflow/accumulator.ex#L1)

Accumulator components aggregate values over time using a reducer function.

## Options

- `:mergeable` - When `true`, indicates this accumulator's reducer has CRDT-like
  properties (commutative, idempotent, associative) and is safe for parallel merge
  without ordering guarantees. Defaults to `false`.

## Example

    # A counter is mergeable (addition is commutative and associative)
    accumulator(
      init: fn -> 0 end,
      reducer: fn value, acc -> acc + value end,
      mergeable: true
    )

    # A list accumulator is NOT mergeable (order matters)
    accumulator(
      init: fn -> [] end,
      reducer: fn value, acc -> [value | acc] end,
      mergeable: false
    )

## Runtime Context

Accumulators can reference external runtime values via `context/1` in their
reducer function. When detected, the reducer is rewritten to arity-3
`(value, acc, meta_ctx)` and values are resolved from the workflow's `run_context`.

    Runic.accumulator(0, fn x, state -> state + x * context(:factor) end,
      name: :scaled
    )

Use `context/2` to provide defaults:

    Runic.accumulator(0, fn x, state -> state + x * context(:factor, default: 1) end,
      name: :scaled
    )

# `t`

```elixir
@type t() :: %Runic.Workflow.Accumulator{
  closure: term(),
  hash: term(),
  init: term(),
  inputs: term(),
  mergeable: term(),
  meta_refs: term(),
  name: term(),
  outputs: term(),
  reduce_hash: term(),
  reducer: term()
}
```

# `has_meta_refs?`

```elixir
@spec has_meta_refs?(t()) :: boolean()
```

Returns whether this accumulator has meta references (e.g., `context/1`)
that need to be resolved during the prepare phase.

---

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