README.md

# Globals

Globals is a module that provides ETS backed global state storage with PubSub capabilities.

How this is different from other PubSub implementations:

- Support PubSub patterns and value storage together
- keys can be any() term such as atoms, strings, tuples, etc.
- Application starts `Globals` automatically no additional Supervision tree entry required
- Support for `depends_on` for variable dependencies
- `await` and `update_await` for awaiting async updates

## Usage

### Simple key value storage:

```elixir
Globals.set(:key, "value")
Globals.get(:key)
```

### PubSub pattern:

```elixir
Globals.subscribe(:key)
Globals.put(:key, "value")
receive do
  {:update, :key, "value"} -> :ok
end
:ok
```

### Caching and PubSub within an Ecto / Phoenix LiveView context:

Especially in LiveView apps it's important to keep track of state changes and provide a live updating UI. Globals provides a simple way to do this.

```elixir
def MyApp.Repo do
  use Ecto.Repo, otp_app: :my_app

  def init() do
    Globals.register(:complex_query, fn ->
      query("SELECT SUM(age) FROM users GROUP BY city")
  end)

  def insert(user_name, user_age, user_city) do
    Repo.query("INSERT INTO users (name, age, city) VALUES (?, ?, ?)", [user_name, user_age, user_city])
    Globals.update(:complex_query)
  end
end

def MyAppWeb.LiveView do
  def mount() do
    Globals.subscribe(:complex_query)
    {:ok, assign(socket, :complex_query, Globals.await(:complex_query))}
  end

  def handle_info({:update, :complex_query, value}, socket) do
    {:noreply, assign(socket, :complex_query, value)}
  end

  def render(assigns) do
    ~H"""
    ... render ...
    """
  end
end
```

## Installation

The package can be installed by adding `globals` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:globals, "~> 1.0"}
  ]
end
```

The docs can be found at <https://hexdocs.pm/globals>.