Skip to content

Commit

Permalink
[chore] comb type specs
Browse files Browse the repository at this point in the history
  • Loading branch information
asakura committed Oct 24, 2023
1 parent 92418f8 commit 5e2cf2e
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 14 deletions.
18 changes: 10 additions & 8 deletions lib/mixpanel.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
defmodule Mixpanel do
use Application

alias Mixpanel.Client

@moduledoc """
Elixir client for the Mixpanel API.
"""
Expand Down Expand Up @@ -36,15 +38,15 @@ defmodule Mixpanel do
required if you are making requests from your backend. If `:ip` is absent,
Mixpanel will ignore the IP address of the request.
"""
@spec track(String.t(), map, keyword) :: :ok
@spec track(Client.event(), Client.properties(), keyword) :: :ok
def track(event, properties \\ %{}, opts \\ []) do
properties =
properties
|> track_put_time(Keyword.get(opts, :time))
|> track_put_distinct_id(Keyword.get(opts, :distinct_id))
|> track_put_ip(Keyword.get(opts, :ip))

Mixpanel.Client.track(event, properties)
Client.track(event, properties)

:ok
end
Expand Down Expand Up @@ -90,23 +92,23 @@ defmodule Mixpanel do
property of the profile. Otherwise, Mixpanel will add a "Last Seen" property
associated with the current time for all $set, $append, and $add operations.
"""
@spec engage(String.t(), String.t(), map, keyword) :: :ok
@spec engage(Client.distinct_id(), String.t(), map, keyword) :: :ok
def engage(distinct_id, operation, value \\ %{}, opts \\ []) do
distinct_id
|> build_engage_event(operation, value, opts)
|> Mixpanel.Client.engage()
|> Client.engage()

:ok
end

@spec batch_engage([{String.t(), String.t(), map}], keyword) :: :ok
@spec batch_engage([{Client.distinct_id(), String.t(), map}], keyword) :: :ok
def batch_engage(list, opts \\ []) do
events =
for {distinct_id, operation, value} <- list do
build_engage_event(distinct_id, operation, value, opts)
end

Mixpanel.Client.engage(events)
Client.engage(events)

:ok
end
Expand Down Expand Up @@ -149,8 +151,8 @@ defmodule Mixpanel do
* `distinct_id` - The current ID of the user.
"""
@spec create_alias(String.t(), String.t()) :: :ok
@spec create_alias(Client.alias_id(), Client.distinct_id()) :: :ok
def create_alias(alias_id, distinct_id) do
Mixpanel.Client.create_alias(alias_id, distinct_id)
Client.create_alias(alias_id, distinct_id)
end
end
54 changes: 48 additions & 6 deletions lib/mixpanel/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,45 @@ defmodule Mixpanel.Client do

require Logger

@type token :: String.t()
@type active :: boolean
@type base_url :: String.t()
@type option :: {:token, token} | {:active, active} | {:base_url, base_url}
@type init_args :: [option | GenServer.option(), ...]
@type state :: %{
required(:token) => token,
required(:active) => active,
required(:base_url) => base_url
}

@type event :: String.t() | map
@type properties :: map
@type alias_id :: String.t()
@type distinct_id :: String.t()

@base_url "https://api.mixpanel.com"
@track_endpoint "/track"
@engage_endpoint "/engage"
@alias_endpoint "/track#identity-create-alias"
@max_attempts 3

@spec start_link(keyword) :: :ignore | {:error, any} | {:ok, pid}
@spec start_link(init_args) :: :ignore | {:error, any} | {:ok, pid}
def start_link(init_args) do
{opts, gen_server_opts} = Keyword.split(init_args, [:token, :active, :base_url])

GenServer.start_link(__MODULE__, opts, gen_server_opts)
end

@spec child_spec(init_args) :: %{
id: __MODULE__,
start: {__MODULE__, :start_link, [init_args, ...]}
}
def child_spec(init_args) do
init_args =
init_args
|> Keyword.put_new(:name, __MODULE__)
|> Keyword.put_new(:base_url, @base_url)
|> Keyword.put_new(:active, true)

%{
id: __MODULE__,
Expand All @@ -37,7 +58,7 @@ defmodule Mixpanel.Client do
See `Mixpanel.track/3`
"""
@spec track(String.t(), map) :: :ok
@spec track(event, properties) :: :ok
def track(event, properties) do
GenServer.cast(__MODULE__, {:track, event, properties})
end
Expand All @@ -47,7 +68,7 @@ defmodule Mixpanel.Client do
See `Mixpanel.engage/4`.
"""
@spec engage(map | [map]) :: :ok
@spec engage(event | [event]) :: :ok
def engage(event) do
GenServer.cast(__MODULE__, {:engage, event})
end
Expand All @@ -57,15 +78,34 @@ defmodule Mixpanel.Client do
See `Mixpanel.create_alias/2`.
"""
@spec create_alias(String.t(), String.t()) :: :ok
@spec create_alias(alias_id, distinct_id) :: :ok
def create_alias(alias, distinct_id) do
GenServer.cast(__MODULE__, {:create_alias, alias, distinct_id})
end

def init(config) do
{:ok, Enum.into(config, %{})}
@impl GenServer
@spec init([option, ...]) :: {:ok, state}
def init(opts) do
token = Keyword.fetch!(opts, :token)
active = Keyword.fetch!(opts, :active)
base_url = Keyword.fetch!(opts, :base_url)

{:ok,
%{
token: token,
active: active,
base_url: base_url
}}
end

@spec handle_cast(
{:track, event, properties}
| {:engage, event}
| {:create_alias, alias_id, distinct_id},
state
) :: {:noreply, state}

@impl GenServer
def handle_cast({:track, event, properties}, %{token: token, active: true} = state) do
data =
%{event: event, properties: Map.put(properties, :token, token)}
Expand All @@ -85,6 +125,7 @@ defmodule Mixpanel.Client do
{:noreply, state}
end

@impl GenServer
def handle_cast({:engage, event}, %{token: token, active: true} = state) do
data =
event
Expand All @@ -103,6 +144,7 @@ defmodule Mixpanel.Client do
{:noreply, state}
end

@impl GenServer
def handle_cast({:create_alias, alias, distinct_id}, %{token: token, active: true} = state) do
data =
%{
Expand Down

0 comments on commit 5e2cf2e

Please sign in to comment.