Chat with websockets
+ +
+
+
+
+
+ diff --git a/priv/static/chat.html b/priv/static/chat.html new file mode 100644 index 0000000..895393b --- /dev/null +++ b/priv/static/chat.html @@ -0,0 +1,100 @@ + + +
+ + blocks that do not have a block as an ancestor
+ *
+ * ie the `inline code`
+ */
+code:not(pre *) {
+ border-radius: 6px;
+ border: 1px solid var(--lgray1);
+ padding-left: 3px;
+ padding-right: 3px;
+ padding-top: 1px;
+ padding-bottom: 1px;
+ background: var(--lgreen1);
+}
+
+/* this is specifically for ```fenced blocks``` */
+pre {
+ border-radius: 6px;
+ border: 1px solid var(--lgray1);
+ padding: 5px;
+ background: var(--lgreen1);
+ overflow: scroll;
+}
+
+/* All `unfenced` or ```fenced``` blocks */
+code {
+ font-family: Liberation Mono, Roboto Mono, monospace;
+ color: var(--dgreen1);
+}
diff --git a/priv/static/ws-test-echo.html b/priv/static/ws-test-echo.html
new file mode 100644
index 0000000..2c3d47d
--- /dev/null
+++ b/priv/static/ws-test-echo.html
@@ -0,0 +1,65 @@
+
+
+
+
+ Websockets echo test
+
+
+
+
+ Websockets echo test
+
+
+
+
+
+
+
+
+
+
diff --git a/src/fd_static_cache.erl b/src/fd_static_cache.erl
new file mode 100644
index 0000000..472f705
--- /dev/null
+++ b/src/fd_static_cache.erl
@@ -0,0 +1,120 @@
+% @doc static file cache
+-module(fd_static_cache).
+
+-behavior(gen_server).
+
+-export([
+ start_link/0,
+ query/1, set/2, unset/1,
+ %%---
+ %% everything below here runs in process context
+ %%--
+ %% gen_server callbacks
+ init/1, handle_call/3, handle_cast/2, handle_info/2,
+ code_change/3, terminate/2
+]).
+
+-include("$zx_include/zx_logger.hrl").
+
+-type context() :: wfc_eval_context:context().
+
+-record(s,
+ {cookies = #{} :: #{Cookie :: binary() := context()}}).
+% -type state() :: #s{}.
+
+
+%%--------------------------------
+%% api (runs in context of caller)
+%%--------------------------------
+
+-spec start_link() -> {ok, pid()} | {error, term()}.
+start_link() ->
+ gen_server:start_link({local, ?MODULE}, ?MODULE, none, []).
+
+
+
+-spec query(Cookie) -> {ok, Context} | error
+ when Cookie :: binary(),
+ Context :: context().
+
+query(Cookie) ->
+ gen_server:call(?MODULE, {query, Cookie}).
+
+
+
+-spec set(Cookie, Context) -> ok
+ when Cookie :: binary(),
+ Context :: context().
+
+set(Cookie, Context) ->
+ gen_server:cast(?MODULE, {set, Cookie, Context}).
+
+
+-spec unset(Cookie) -> ok
+ when Cookie :: binary().
+
+unset(Cookie) ->
+ gen_server:cast(?MODULE, {unset, Cookie}).
+
+
+%%----------------------
+%% gen-server bs
+%%----------------------
+
+
+
+init(none) ->
+ log(info, "starting fd_cache"),
+ InitState = #s{},
+ {ok, InitState}.
+
+
+handle_call({query, Cookie}, _, State) ->
+ Result = do_query(Cookie, State),
+ {reply, Result, State};
+handle_call(Unexpected, From, State) ->
+ tell("~tp: unexpected call from ~tp: ~tp", [?MODULE, Unexpected, From]),
+ {noreply, State}.
+
+
+handle_cast({set, Cookie, Context}, State) ->
+ NewState = do_set(Cookie, Context, State),
+ {noreply, NewState};
+handle_cast({unset, Cookie}, State) ->
+ NewState = do_unset(Cookie, State),
+ {noreply, NewState};
+handle_cast(Unexpected, State) ->
+ tell("~tp: unexpected cast: ~tp", [?MODULE, Unexpected]),
+ {noreply, State}.
+
+
+handle_info(Unexpected, State) ->
+ tell("~tp: unexpected info: ~tp", [?MODULE, Unexpected]),
+ {noreply, State}.
+
+
+code_change(_, State, _) ->
+ {ok, State}.
+
+terminate(_, _) ->
+ ok.
+
+
+%%---------------------
+%% doers
+%%---------------------
+
+do_set(Cookie, Context, State = #s{cookies = Cookies}) ->
+ NewCookies = maps:put(Cookie, Context, Cookies),
+ NewState = State#s{cookies = NewCookies},
+ NewState.
+
+
+do_unset(Cookie, State = #s{cookies = Cookies}) ->
+ NewCookies = maps:remove(Cookie, Cookies),
+ NewState = State#s{cookies = NewCookies},
+ NewState.
+
+
+do_query(Cookie, _State = #s{cookies = Cookies}) ->
+ maps:find(Cookie, Cookies).