Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce arizona.erl and move (opaque) types inside it #104

Merged
merged 3 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:

- name: Continuous Integration
run: |
rebar3 xref
williamthome marked this conversation as resolved.
Show resolved Hide resolved
rebar3 as test ci

- name: Check if build left artifacts
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
7 changes: 3 additions & 4 deletions include/arizona.hrl
Original file line number Diff line number Diff line change
@@ -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)
williamthome marked this conversation as resolved.
Show resolved Hide resolved
)).
4 changes: 4 additions & 0 deletions src/arizona.erl
williamthome marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-module(arizona).

-opaque payload() :: map().
-export_type([payload/0]).
52 changes: 39 additions & 13 deletions src/arizona_live_view.erl
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand All @@ -46,24 +50,46 @@ 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]).

%% --------------------------------------------------------------------
%% 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}).
Expand Down Expand Up @@ -109,15 +135,15 @@ parse_str_test() ->
% Start parse_str support.

render(Macros) ->
?ARIZONA_LIVEVIEW("""
?ARIZONA_LIVEVIEW(Macros, """
<main :stateful>
<h1>{_@title}</h1>
<.arizona_live_view:counter/>
</main>
""").

counter(Macros) ->
?ARIZONA_LIVEVIEW("""
?ARIZONA_LIVEVIEW(Macros, """
<div :stateful>
<div>{_@count}</div>
<button type="button">Increment</button>
Expand Down
43 changes: 36 additions & 7 deletions src/arizona_socket.erl
Original file line number Diff line number Diff line change
Expand Up @@ -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.
%% --------------------------------------------------------------------
Expand All @@ -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;
Expand All @@ -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]}.

Expand Down
2 changes: 1 addition & 1 deletion test/arizona_live_view_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ mount(Socket) ->
{ok, Socket}.

render(Macros) ->
?ARIZONA_LIVEVIEW(~s"""
?ARIZONA_LIVEVIEW(Macros, ~s"""
<html>
<head>
</head>
Expand Down