Jido.Chat.StateAdapter behaviour (Jido Chat v1.0.0)

Copy Markdown View Source

Behavior and helpers for pluggable chat state storage.

State adapters own subscriptions, dedupe windows, and per-thread / per-channel state maps. The default adapter keeps everything in memory, but adapters may persist state elsewhere as long as they can expose a normalized snapshot.

Summary

Functions

Returns channel state map from adapter-managed state.

Returns the canonical empty snapshot.

Returns true when a message dedupe key has already been seen.

Force-releases a lock regardless of owner and returns pending entries.

Initializes adapter state from a normalized snapshot.

Attempts to acquire a concurrency lock for the given key and owner.

Records a new dedupe key and trims state to the requested limit.

Normalizes maps, lists, and map-sets into the canonical state snapshot shape.

Writes channel state map into adapter-managed state.

Writes thread state map into adapter-managed state.

Releases a held lock and returns any queued/debounced pending entries.

Returns a normalized snapshot for adapter-managed state.

Adds a subscribed thread id to adapter-managed state.

Returns true when the thread is subscribed in adapter-managed state.

Returns thread state map from adapter-managed state.

Removes a subscribed thread id from adapter-managed state.

Types

dedupe_key()

@type dedupe_key() :: {atom(), String.t()}

lock_result()

@type lock_result() :: :acquired | :queued | :debounced | :busy

release_result()

@type release_result() :: {:released, [map()]} | {:error, :not_owner}

snapshot()

@type snapshot() :: %{
  subscriptions: MapSet.t(String.t()),
  dedupe: MapSet.t(dedupe_key()),
  dedupe_order: [dedupe_key()],
  thread_state: %{optional(String.t()) => map()},
  channel_state: %{optional(String.t()) => map()},
  locks: %{optional(String.t()) => map()},
  pending_locks: %{optional(String.t()) => [map()]}
}

state()

@type state() :: term()

Callbacks

channel_state(state, t)

@callback channel_state(state(), String.t()) :: map()

duplicate?(state, dedupe_key)

@callback duplicate?(state(), dedupe_key()) :: boolean()

force_release_lock(state, t)

@callback force_release_lock(state(), String.t()) :: {{:released, [map()]}, state()}

init(snapshot, keyword)

@callback init(
  snapshot(),
  keyword()
) :: state()

lock(state, t, t, atom, map)

@callback lock(state(), String.t(), String.t(), atom(), map()) :: {lock_result(), state()}

mark_dedupe(state, dedupe_key, pos_integer)

@callback mark_dedupe(state(), dedupe_key(), pos_integer()) :: state()

put_channel_state(state, t, map)

@callback put_channel_state(state(), String.t(), map()) :: state()

put_thread_state(state, t, map)

@callback put_thread_state(state(), String.t(), map()) :: state()

release_lock(state, t, t)

@callback release_lock(state(), String.t(), String.t()) :: {release_result(), state()}

snapshot(state)

@callback snapshot(state()) :: snapshot() | map()

subscribe(state, t)

@callback subscribe(state(), String.t()) :: state()

subscribed?(state, t)

@callback subscribed?(state(), String.t()) :: boolean()

thread_state(state, t)

@callback thread_state(state(), String.t()) :: map()

unsubscribe(state, t)

@callback unsubscribe(state(), String.t()) :: state()

Functions

channel_state(adapter_module, state, channel_id)

@spec channel_state(module(), state(), String.t()) :: map()

Returns channel state map from adapter-managed state.

default_snapshot()

@spec default_snapshot() :: snapshot()

Returns the canonical empty snapshot.

duplicate?(adapter_module, state, key)

@spec duplicate?(module(), state(), dedupe_key()) :: boolean()

Returns true when a message dedupe key has already been seen.

force_release_lock(adapter_module, state, key)

@spec force_release_lock(module(), state(), String.t()) ::
  {{:released, [map()]}, state()}

Force-releases a lock regardless of owner and returns pending entries.

init(adapter_module, snapshot, opts \\ [])

@spec init(module(), map(), keyword()) :: state()

Initializes adapter state from a normalized snapshot.

lock(adapter_module, state, key, owner, strategy, metadata \\ %{})

@spec lock(module(), state(), String.t(), String.t(), atom(), map()) ::
  {lock_result(), state()}

Attempts to acquire a concurrency lock for the given key and owner.

mark_dedupe(adapter_module, state, key, limit)

@spec mark_dedupe(module(), state(), dedupe_key(), pos_integer()) :: state()

Records a new dedupe key and trims state to the requested limit.

normalize_snapshot(snapshot)

@spec normalize_snapshot(map()) :: snapshot()

Normalizes maps, lists, and map-sets into the canonical state snapshot shape.

put_channel_state(adapter_module, state, channel_id, value)

@spec put_channel_state(module(), state(), String.t(), map()) :: state()

Writes channel state map into adapter-managed state.

put_thread_state(adapter_module, state, thread_id, value)

@spec put_thread_state(module(), state(), String.t(), map()) :: state()

Writes thread state map into adapter-managed state.

release_lock(adapter_module, state, key, owner)

@spec release_lock(module(), state(), String.t(), String.t()) ::
  {release_result(), state()}

Releases a held lock and returns any queued/debounced pending entries.

snapshot(adapter_module, state)

@spec snapshot(module(), state()) :: snapshot()

Returns a normalized snapshot for adapter-managed state.

subscribe(adapter_module, state, thread_id)

@spec subscribe(module(), state(), String.t()) :: state()

Adds a subscribed thread id to adapter-managed state.

subscribed?(adapter_module, state, thread_id)

@spec subscribed?(module(), state(), String.t()) :: boolean()

Returns true when the thread is subscribed in adapter-managed state.

thread_state(adapter_module, state, thread_id)

@spec thread_state(module(), state(), String.t()) :: map()

Returns thread state map from adapter-managed state.

unsubscribe(adapter_module, state, thread_id)

@spec unsubscribe(module(), state(), String.t()) :: state()

Removes a subscribed thread id from adapter-managed state.