diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 35924b0..1accd87 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,7 @@ jobs: - name: Continuous Integration run: | + rebar3 xref rebar3 as test ci - name: Check if build left artifacts diff --git a/README.md b/README.md index 9b97331..453ca98 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ example project. % connects to the server via WebSocket. mount(#{assigns := Assigns} = Socket) -> Count = maps:get(count, Assigns, 0), - {ok, arizona_socket:assign(count, Count, Socket)}. + {ok, arizona_socket:put_assign(count, Count, Socket)}. % render/1 is called by the route to compile the template. % Macros substitutes variables. @@ -117,10 +117,10 @@ render(Macros0) -> % Handle client events. handle_event(<<"incr">>, #{}, #{assigns := Assigns} = Socket) -> Count = maps:get(count, Assigns) + 1, - {noreply, arizona_socket:assign(count, Count, Socket)}; + {noreply, arizona_socket:put_assign(count, Count, Socket)}; handle_event(<<"decr">>, #{}, #{assigns := Assigns} = Socket) -> Count = maps:get(count, Assigns) - 1, - {noreply, arizona_socket:assign(count, Count, Socket)}. + {noreply, arizona_socket:put_assign(count, Count, Socket)}. %% -------------------------------------------------------------------- %% Component functions. diff --git a/include/arizona.hrl b/include/arizona.hrl index a18836a..3dbe387 100644 --- a/include/arizona.hrl +++ b/include/arizona.hrl @@ -1,4 +1,3 @@ --define(ARIZONA_LIVEVIEW(Str), (begin - {ok, Tree} = arizona_live_view:parse_str(Str, Macros), - Tree -end)). +-define(ARIZONA_LIVEVIEW(Macros, Str), ( + arizona_live_view:parse_str(Str, Macros) +)). diff --git a/src/arizona.erl b/src/arizona.erl new file mode 100644 index 0000000..9ceec8a --- /dev/null +++ b/src/arizona.erl @@ -0,0 +1,4 @@ +-module(arizona). + +-opaque payload() :: map(). +-export_type([payload/0]). diff --git a/src/arizona_live_view.erl b/src/arizona_live_view.erl index 3edbb76..110e605 100644 --- a/src/arizona_live_view.erl +++ b/src/arizona_live_view.erl @@ -32,12 +32,16 @@ Live view. -export([mount/2]). -export([handle_event/4]). -%% TODO: Real types. --type socket() :: map(). --type macros() :: map(). --type tree() :: list(). --type event() :: binary(). --type payload() :: map(). +-export([put_macro/3]). +-ignore_xref([put_macro/3]). +-export([get_macro/3]). +-ignore_xref([get_macro/3]). + +-opaque macros() :: map(). +-export_type([macros/0]). + +-opaque tree() :: list(). +-export_type([tree/0]). %% Macros -define(PERSIST_KEY, ?MODULE). @@ -46,14 +50,14 @@ Live view. %% Callbacks. %% -------------------------------------------------------------------- --callback mount(socket()) -> - {ok, socket()}. +-callback mount(arizona_socket:t()) -> + {ok, arizona_socket:t()}. -callback render(macros()) -> tree(). --callback handle_event(event(), payload(), socket()) -> - {noreply, socket()}. +-callback handle_event(EventName :: binary(), arizona:payload(), arizona_socket:t()) -> + {noreply, arizona_socket:t()}. -optional_callbacks([handle_event/3]). @@ -61,9 +65,31 @@ Live view. %% API funtions. %% -------------------------------------------------------------------- +-spec put_macro(Key, Value, Macros) -> Macros + when Key :: atom(), + Value :: term(), + Macros :: macros(). +put_macro(Key, Value, Macros) -> + Macros#{ + Key => maps:get(Key, Macros, Value) + }. + +-spec get_macro(Key, Macros, Default) -> Got + when Key :: atom(), + Macros :: macros(), + Default :: term(), + Got :: term(). +get_macro(Key, Macros, Default) -> + maps:get(Key, Macros, Default). + +-spec parse_str(Str, Macros) -> Parsed + when Str :: string() | binary(), + Macros :: macros(), + Parsed :: tree(). parse_str(Str, Macros) -> {ok, Tokens, _EndLocation} = arizona_tpl_scan:string(Str), - arizona_tpl_parse:parse_exprs(Tokens, Macros). + {ok, Parsed} = arizona_tpl_parse:parse_exprs(Tokens, Macros), + Parsed. compile(Mod, Fun, Macros) -> arizona_tpl_compile:compile({Mod, Fun, Macros}). @@ -109,7 +135,7 @@ parse_str_test() -> % Start parse_str support. render(Macros) -> - ?ARIZONA_LIVEVIEW(""" + ?ARIZONA_LIVEVIEW(Macros, """

{_@title}

<.arizona_live_view:counter/> @@ -117,7 +143,7 @@ render(Macros) -> """). counter(Macros) -> - ?ARIZONA_LIVEVIEW(""" + ?ARIZONA_LIVEVIEW(Macros, """
{_@count}
diff --git a/src/arizona_socket.erl b/src/arizona_socket.erl index fb2afb6..d29f8a6 100644 --- a/src/arizona_socket.erl +++ b/src/arizona_socket.erl @@ -24,13 +24,20 @@ Components state. %% API functions. -export([new/3]). --export([assign/2]). --ignore_xref([assign/2]). --export([assign/3]). --ignore_xref([assign/3]). +-export([put_assign/2]). +-ignore_xref([put_assign/2]). +-export([put_assign/3]). +-ignore_xref([put_assign/3]). +-export([get_assign/2]). +-ignore_xref([get_assign/2]). +-export([get_assign/3]). +-ignore_xref([get_assign/3]). -export([push_event/3]). -export([prune/1]). +-opaque t() :: map(). +-export_type([t/0]). + %% -------------------------------------------------------------------- %% API functions. %% -------------------------------------------------------------------- @@ -44,10 +51,15 @@ new(Id, View, Assigns) -> changes => #{} }. -assign(Map, Socket) -> - maps:fold(fun assign/3, Socket, Map). +put_assign(Map, Socket) -> + maps:fold(fun put_assign/3, Socket, Map). -assign(Key, Value, #{assigns := Assigns, changes := Changes} = Socket) -> +-spec put_assign(Key, Value, Socket) -> Socket + when Key :: atom(), + Value :: term(), + Socket :: t(). +put_assign(Key, Value, Socket) -> + #{assigns := Assigns, changes := Changes} = Socket, case Assigns of #{Key := Value} -> Socket; @@ -58,6 +70,23 @@ assign(Key, Value, #{assigns := Assigns, changes := Changes} = Socket) -> } end. +-spec get_assign(Key, Socket) -> Got + when Key :: atom(), + Socket :: t(), + Got :: term(). +get_assign(Key, Socket) -> + #{assigns := Assigns} = Socket, + maps:get(Key, Assigns). + +-spec get_assign(Key, Socket, Default) -> Got + when Key :: atom(), + Socket :: t(), + Default :: term(), + Got :: term(). +get_assign(Key, Socket, Default) -> + #{assigns := Assigns} = Socket, + maps:get(Key, Assigns, Default). + push_event(Name, Payload, #{events := Events} = Socket) -> Socket#{events => [[Name, Payload] | Events]}. diff --git a/test/arizona_live_view_SUITE.erl b/test/arizona_live_view_SUITE.erl index b7b9ce2..04eefdc 100644 --- a/test/arizona_live_view_SUITE.erl +++ b/test/arizona_live_view_SUITE.erl @@ -64,7 +64,7 @@ mount(Socket) -> {ok, Socket}. render(Macros) -> - ?ARIZONA_LIVEVIEW(~s""" + ?ARIZONA_LIVEVIEW(Macros, ~s"""