diff --git a/.gitignore b/.gitignore index ea0e15f..3613e55 100644 --- a/.gitignore +++ b/.gitignore @@ -36,5 +36,6 @@ result # Nix files result -/.elixir_ls/ -/.elixir-tools/ +.elixir_ls/ +.elixir-tools/ +.lexical/ diff --git a/README.md b/README.md index 33d405b..50a1e8f 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,90 @@ config :supabase, Make sure to set the environment variables `SUPABASE_BASE_URL` and `SUPABASE_API_KEY`. +## Manually starting Clients + +If you want to manually manage Clients, firstly you need to disable the config: + +```elixir +import Config + +config :supabase_potion, manage_clients: false +``` + +Then you need to start the Clients managements processes, that consists on: +- `Supabase.ClientSupervisor`: a DynamicSupervisor to manage multiple Supabase clients +- `Supabase.ClientRegistry`: a Registry to easily find a Supabase client + +You can start them on your application startup, often on your `MyApp.Application`: + +```elixir +defmodule MyApp.Application do + use Application + + @impl true + def start(_type, _args) do + children = [ + # rest of your Supervisor's children... + # is recommended to start registry **before** + # the Supervsior + Supabase.ClientRegistry + Supabase.ClientSupervisor + ] + end + + # rest of module... +end +``` + +Now you can start to initialize Clients! as pointed on [Staring a Client](#starting-a-client) section. + +However, maybe you can full control of your Supabase Clients, then, you can start Clients individually on your application startup, like: + +```elixir +defmodule MyApp.Application do + use Application + + @impl true + def start(_type, _args) do + supabase_config = supabase_client_config() + supabase_opts = [name: MyApp.SupabaseClient, client_info: supabase_config] + + children = [ + # rest of your Supervisor's children... + {Supabase.Client, supabase_opts} + ] + end + + defp supabase_client_config do + %{ + # you can skip the `conn` config if you already set on config.exs + conn: %{ + api_key: "my-super-secret-api-key", + base_url: "https://my-project-id.supabase.co", + access_token: "my-scoped-access-token", + }, + db: %{schema: "my-schema"} # default to "public", + # global headers to be used on Supabase API requests + global: %{headers: %{"content-type": "application/json"}}, + auth: %{ + # below are the defaults values + auto_refresh_token: true, + debug: false, + detect_session_in_url: true, + flow_type: :implicit, + persist_session: true, + storage: "my-storage", + storage_key: "my-storage-key" + } + } + end + + # rest of module... +end +``` + +#### TODO + ### How to find my Supabase base URL? You can find your Supabase base URL in the Settings page of your project. diff --git a/config/config.exs b/config/config.exs index eb32525..401c9b3 100644 --- a/config/config.exs +++ b/config/config.exs @@ -2,6 +2,7 @@ import Config if config_env() == :dev do config :supabase_potion, + manage_clients: true, supabase_base_url: System.get_env("SUPABASE_URL"), supabase_api_key: System.get_env("SUPABASE_KEY") end diff --git a/lib/supabase.ex b/lib/supabase.ex index 6f1f3c5..7be2236 100644 --- a/lib/supabase.ex +++ b/lib/supabase.ex @@ -8,7 +8,7 @@ defmodule Supabase do def deps do [ - {:supabase_potion, "~> 0.1"} + {:supabase_potion, "~> 0.3"} ] end @@ -110,13 +110,13 @@ defmodule Supabase do @typep changeset :: Ecto.Changeset.t() - @spec init_client(params) :: {:ok, pid} | {:error, changeset} + @spec init_client(name :: atom, params) :: {:ok, pid} | {:error, changeset} when params: Client.params() - def init_client(%{} = opts) do + def init_client(name, opts \\ %{}) do conn = Map.get(opts, :conn, %{}) opts = maybe_merge_config_from_application(conn, opts) - with {:ok, opts} <- Client.parse(opts) do + with {:ok, opts} <- Client.parse(Map.put(opts, :name, name)) do name = ClientRegistry.named(opts.name) client_opts = [name: name, client_info: opts] ClientSupervisor.start_child({Client, client_opts}) @@ -125,11 +125,11 @@ defmodule Supabase do _ -> Client.parse(opts) end - def init_client!(%{} = opts) do + def init_client!(name, %{} = opts \\ %{}) do conn = Map.get(opts, :conn, %{}) opts = maybe_merge_config_from_application(conn, opts) - case init_client(opts) do + case init_client(name, opts) do {:ok, pid} -> pid {:error, changeset} -> raise Ecto.InvalidChangesetError, changeset: changeset, action: :init end diff --git a/lib/supabase/application.ex b/lib/supabase/application.ex index 240aad2..6cb70e7 100644 --- a/lib/supabase/application.ex +++ b/lib/supabase/application.ex @@ -7,12 +7,7 @@ defmodule Supabase.Application do @impl true def start(_start_type, _args) do - children = [ - {Finch, @finch_opts}, - if(manage_clients?(), do: Supabase.ClientSupervisor), - if(manage_clients?(), do: Supabase.ClientRegistry) - ] - + children = [{Finch, @finch_opts}, (if manage_clients?(), do: Supabase.Supervisor)] opts = [strategy: :one_for_one, name: Supabase.Supervisor] children @@ -21,6 +16,6 @@ defmodule Supabase.Application do end defp manage_clients? do - Application.get_env(:supabase, :manage_clients, true) + Application.get_env(:supabase_potion, :manage_clients, true) end end diff --git a/lib/supabase/client.ex b/lib/supabase/client.ex index 8591302..5ae8f14 100644 --- a/lib/supabase/client.ex +++ b/lib/supabase/client.ex @@ -92,7 +92,6 @@ defmodule Supabase.Client do } @type params :: %{ - name: atom, conn: Conn.params(), db: Db.params(), global: Global.params(), diff --git a/lib/supabase/supervisor.ex b/lib/supabase/supervisor.ex new file mode 100644 index 0000000..db5b313 --- /dev/null +++ b/lib/supabase/supervisor.ex @@ -0,0 +1,18 @@ +defmodule Supabase.Supervisor do + use Supervisor + + def start_link(opts \\ []) do + Supervisor.start_link(__MODULE__, opts) + end + + @impl true + def init(opts) do + name = Keyword.get(opts, :name, Supabase.Supervisor) + strategy = Keyword.get(opts, :strategy, :one_for_one) + opts = [name: name, strategy: strategy] + children = [Supabase.ClientRegistry, Supabase.ClientSupervisor] + + Supervisor.init(children, opts) + end + +end diff --git a/mix.exs b/mix.exs index cf10dbb..9a0b793 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule Supabase.Potion.MixProject do use Mix.Project - @version "0.3.2" + @version "0.3.3" @source_url "https://github.com/zoedsoupe/supabase" def project do