# `Concord`
[🔗](https://github.com/gsmlg-dev/concord/blob/main/lib/concord.ex#L1)

Public API for the Concord distributed key-value store.

Concord is a CP (Consistent + Partition-tolerant) distributed KV store
built on the Raft consensus algorithm via the `ra` library.

## Examples

    iex> Concord.put("user:123", %{name: "Alice"})
    :ok

    iex> Concord.get("user:123")
    {:ok, %{name: "Alice"}}

    iex> Concord.delete("user:123")
    :ok

# `delete`

Deletes a key from the cluster.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)

# `delete_if`

Conditionally deletes a key only if it matches the expected value.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:token` - Authentication token (required if auth is enabled)

## Examples

    # Only delete if current value matches
    Concord.delete_if("lock", expected: "my_lock_id")
    # => :ok

    # Fails if value doesn't match
    Concord.delete_if("lock", expected: "different_id")
    # => {:error, :condition_failed}

    # Delete with predicate
    Concord.delete_if("temp:file",
      condition: fn value -> value.created_at < cutoff_time end
    )

# `delete_many`

Deletes multiple keys from the cluster atomically.

Either all operations succeed or all fail together.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:token` - Authentication token (required if auth is enabled)

## Examples
    iex> Concord.delete_many(["key1", "key2"])
    {:ok, %{"key1" => :ok, "key2" => :ok}}

# `get`

Retrieves a value by key from the cluster.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:consistency` - Read consistency level (default: :leader)
  - `:eventual` - Fastest, may return stale data (reads from any node)
  - `:leader` - Balanced, reads from leader node
  - `:strong` - Linearizable reads with heartbeat verification (slowest)

# `get_all`

Returns all key-value pairs in the store.
Use sparingly on large datasets.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:consistency` - Read consistency level (default: :leader)

# `get_all_with_ttl`

Returns all key-value pairs with their TTL information.
Use sparingly on large datasets.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:consistency` - Read consistency level (default: :leader)

## Examples
    iex> Concord.get_all_with_ttl(token: "token")
    {:ok, %{"key1" => %{value: "val1", ttl: 3600}, "key2" => %{value: "val2", ttl: nil}}}

# `get_many`

Retrieves multiple values by key from the cluster.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:consistency` - Read consistency level (default: :leader)

## Examples
    iex> Concord.get_many(["key1", "key2"])
    {:ok, %{"key1" => {:ok, "value1"}, "key2" => {:error, :not_found}}}

# `get_with_ttl`

Gets a value along with its remaining TTL.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:consistency` - Read consistency level (default: :leader)

## Examples
    iex> Concord.get_with_ttl("cache:user:123")
    {:ok, {%{data: "value"}, 1800}}

# `list`

Lists keys matching a prefix or range selector.

See `Concord.KV.list/1`.

# `members`

Returns cluster members information.

# `prefix_scan`

Returns key-value pairs for all keys starting with the given prefix.

Uses an efficient server-side scan on the ordered ETS table, avoiding
loading all keys into memory. O(log N + K) where K is the number of
matching keys.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:consistency` - Read consistency level (default: :leader)

## Examples
    iex> Concord.prefix_scan("user:")
    {:ok, [{"user:1", %{name: "Alice"}}, {"user:2", %{name: "Bob"}}]}

# `put`

Stores a key-value pair in the cluster.

Values are automatically compressed if they exceed the configured size threshold
(default: 1KB). Compression is transparent and values are automatically
decompressed when retrieved.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:ttl` - Time-to-live in seconds (default: nil for no expiration)
- `:compress` - Override automatic compression (true/false)

# `put_if`

Conditionally updates a key only if it matches the expected value (compare-and-swap).

This provides atomic conditional updates, useful for implementing locks, counters,
and other concurrent data structures.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:ttl` - Time-to-live in seconds for the new value
- `:compress` - Override automatic compression (true/false)

## Examples

    # Only update if current value matches
    Concord.put_if("counter", 1, expected: 0)
    # => :ok

    # Fails if value doesn't match
    Concord.put_if("counter", 2, expected: 0)
    # => {:error, :condition_failed}

    # Conditional update with predicate
    Concord.put_if("config", new_config,
      condition: fn old_value -> old_value.version < new_config.version end
    )

# `put_many`

Stores multiple key-value pairs in the cluster atomically.

Either all operations succeed or all fail together.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:token` - Authentication token (required if auth is enabled)

## Examples
    iex> Concord.put_many([{"key1", "value1"}, {"key2", "value2"}])
    {:ok, %{"key1" => :ok, "key2" => :ok}}

# `put_many_with_ttl`

Stores multiple key-value pairs with a TTL atomically.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:token` - Authentication token (required if auth is enabled)

## Examples
    iex> Concord.put_many_with_ttl([{"key1", "value1"}, {"key2", "value2"}], 3600)
    {:ok, %{"key1" => :ok, "key2" => :ok}}

# `put_with_ttl`

Stores a key-value pair with an explicit TTL in seconds.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:token` - Authentication token (required if auth is enabled)

## Examples
    iex> Concord.put_with_ttl("cache:user:123", %{data: "value"}, 3600)
    :ok

# `revision`

Returns the current cluster revision.

See `Concord.KV.revision/1`.

# `status`

Returns cluster status information.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:consistency` - Read consistency level (default: :leader)

# `touch`

Extends the TTL of an existing key by the specified number of seconds.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:token` - Authentication token (required if auth is enabled)

## Examples
    iex> Concord.touch("cache:user:123", 1800)
    :ok

# `touch_many`

Extends the TTL of multiple keys atomically.

Either all operations succeed or all fail together.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:token` - Authentication token (required if auth is enabled)

## Examples
    iex> Concord.touch_many([{"key1", 1800}, {"key2", 3600}])
    {:ok, %{"key1" => :ok, "key2" => :ok}}

# `ttl`

Gets the remaining TTL for a key in seconds.

Returns nil if the key has no expiration.
Returns {:error, :not_found} if the key doesn't exist or has expired.

## Options
- `:timeout` - Operation timeout in milliseconds (default: 5000)
- `:consistency` - Read consistency level (default: :leader)

## Examples
    iex> Concord.ttl("cache:user:123")
    {:ok, 1800}

# `txn`

Commits a transaction atomically.

See `Concord.Txn.commit/2`.

