The thing works!

This commit is contained in:
Daniel Flanagan 2024-02-20 22:06:00 -06:00
parent 48a4c97a02
commit 0f1131b406
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4
5 changed files with 118 additions and 41 deletions

View file

@ -53,7 +53,7 @@
in { in {
default = pkgs.mkShell { default = pkgs.mkShell {
shellHook = "export LOCALE_ARCHIVE=/usr/lib/locale/locale-archive"; shellHook = "export LOCALE_ARCHIVE=/usr/lib/locale/locale-archive";
buildInputs = with pkgs; [erlang_26 elixir elixir-ls watchexec]; buildInputs = with pkgs; [inotify-tools erlang_26 elixir elixir-ls watchexec];
}; };
}); });
}; };

98
main.ex
View file

@ -1,8 +1,12 @@
# config
counter = :counters.new(1, []) counter = :counters.new(1, [])
Application.put_env(:sfe, Sfe.Endpoint, Application.put_env(:sfe, Sfe.Endpoint,
http: [ip: {127, 0, 0, 1}, port: 5001], http: [ip: {127, 0, 0, 1}, port: 5001],
pubsub_server: Sfe.PubSub,
adapter: Bandit.PhoenixAdapter, adapter: Bandit.PhoenixAdapter,
debug_errors: true,
code_reloader: true,
server: true, server: true,
live_view: [signing_salt: "aaaaaaaa"], live_view: [signing_salt: "aaaaaaaa"],
secret_key_base: String.duplicate("a", 64) secret_key_base: String.duplicate("a", 64)
@ -10,26 +14,69 @@ Application.put_env(:sfe, Sfe.Endpoint,
Application.put_env(:sfe, Sfe.HomeLive, counter_ref: counter) Application.put_env(:sfe, Sfe.HomeLive, counter_ref: counter)
Mix.install([ # application
{:bandit, "~> 1.2"}, defmodule Sfe do
{:jason, "~> 1.0"}, defmodule Application do
{:phoenix, "~> 1.7.0"}, use Elixir.Application
{:phoenix_live_view, "~> 0.19.0"},
{:phoenix_pubsub, "~> 2.1"}
])
require Logger
defmodule Sfe.ErrorView do def start(_type, _args) do
Logger.debug("Sfe starting...")
children = [
Sfe.Endpoint,
{Phoenix.PubSub, name: Sfe.PubSub}
]
opts = [strategy: :one_for_one, name: Sfe.Supervisor]
Supervisor.start_link(children, opts)
end
end
defmodule ErrorView do
def render(template, _), do: Phoenix.Controller.status_message_from_template(template) def render(template, _), do: Phoenix.Controller.status_message_from_template(template)
end end
defmodule Router do
use Phoenix.Router
import Phoenix.LiveView.Router
pipeline :browser do
plug(:accepts, ["html"])
end
scope "/", Sfe do
pipe_through(:browser)
live("/", HomeLive, :index)
end
end
defmodule Endpoint do
use Phoenix.Endpoint, otp_app: :sfe
if code_reloading? do
socket("/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket)
plug(Phoenix.LiveReloader)
plug(Phoenix.CodeReloader)
end
socket("/live", Phoenix.LiveView.Socket)
plug(Sfe.Router)
end
end
defmodule Sfe.HomeLive do defmodule Sfe.HomeLive do
use Phoenix.LiveView, layout: {__MODULE__, :live} use Phoenix.LiveView, layout: {__MODULE__, :live}
@topic "counter"
defp counter_ref(), do: Application.get_env(:sfe, __MODULE__)[:counter_ref] defp counter_ref(), do: Application.get_env(:sfe, __MODULE__)[:counter_ref]
defp counter_value(), do: :counters.get(counter_ref(), 1) defp counter_value(), do: :counters.get(counter_ref(), 1)
def mount(_params, _session, socket) do def mount(_params, _session, socket) do
Sfe.Endpoint.subscribe(@topic)
{:ok, assign(socket, :count, counter_value())} {:ok, assign(socket, :count, counter_value())}
end end
@ -70,37 +117,12 @@ defmodule Sfe.HomeLive do
counter_value(socket) counter_value(socket)
end end
def handle_info(%{topic: "counter", event: "counter", payload: cval}, socket) do
{:noreply, assign(socket, :count, cval)}
end
defp counter_value(socket) do defp counter_value(socket) do
Sfe.Endpoint.broadcast_from(self(), @topic, "counter", counter_value())
{:noreply, assign(socket, :count, counter_value())} {:noreply, assign(socket, :count, counter_value())}
end end
end end
defmodule Sfe.Router do
use Phoenix.Router
import Phoenix.LiveView.Router
pipeline :browser do
plug(:accepts, ["html"])
end
scope "/", Sfe do
pipe_through(:browser)
live("/", HomeLive, :index)
end
end
defmodule Sfe.Endpoint do
use Phoenix.Endpoint, otp_app: :sfe
socket("/live", Phoenix.LiveView.Socket)
plug(Sfe.Router)
end
children = [
Sfe.Endpoint,
{Phoenix.PubSub, name: :my_pubsub}
]
{:ok, _} = Supervisor.start_link(children, strategy: :one_for_one)
Process.sleep(:infinity)

31
mix.exs Normal file
View file

@ -0,0 +1,31 @@
defmodule Sfe.MixProject do
use Mix.Project
def project(),
do: [
app: :sfe,
version: "0.1.0",
elixir: "~> 1.16",
elixirc_paths: ["main.ex"],
compilers: Mix.compilers(),
start_permanent: Mix.env() == :prod,
elixirc_options: [warnings_as_errors: true],
deps: deps()
]
def application(),
do: [
mod: {Sfe.Application, []}
]
defp deps(),
do: [
# {:credo, "~> 1.6", only: [:dev, :test], runtime: false},
{:bandit, "~> 1.2"},
{:jason, "~> 1.0"},
{:phoenix, "~> 1.7"},
{:phoenix_live_view, "~> 0.19.0"},
{:phoenix_live_reload, "~> 1.4", only: :dev},
{:phoenix_pubsub, "~> 2.1"}
]
end

20
mix.lock Normal file
View file

@ -0,0 +1,20 @@
%{
"bandit": {:hex, :bandit, "1.2.2", "569fe5d0efb107c9af37a1e37e25ce2ceec293101a2d4bc512876fc3207192b5", [:mix], [{:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "2f89adb7281c78d4e75733e0a9e1b24f46f84d2993963d6fa57d0eafadec5f03"},
"castore": {:hex, :castore, "1.0.5", "9eeebb394cc9a0f3ae56b813459f990abb0a3dedee1be6b27fdb50301930502f", [:mix], [], "hexpm", "8d7c597c3e4a64c395980882d4bca3cebb8d74197c590dc272cfd3b6a6310578"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"},
"phoenix": {:hex, :phoenix, "1.7.11", "1d88fc6b05ab0c735b250932c4e6e33bfa1c186f76dcf623d8dd52f07d6379c7", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "b1ec57f2e40316b306708fe59b92a16b9f6f4bf50ccfa41aa8c7feb79e0ec02a"},
"phoenix_html": {:hex, :phoenix_html, "3.3.3", "380b8fb45912b5638d2f1d925a3771b4516b9a78587249cabe394e0a5d579dc9", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "923ebe6fec6e2e3b3e569dfbdc6560de932cd54b000ada0208b5f45024bdd76c"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.4.1", "2aff698f5e47369decde4357ba91fc9c37c6487a512b41732818f2204a8ef1d3", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "9bffb834e7ddf08467fe54ae58b5785507aaba6255568ae22b4d46e2bb3615ab"},
"phoenix_live_view": {:hex, :phoenix_live_view, "0.19.5", "6e730595e8e9b8c5da230a814e557768828fd8dfeeb90377d2d8dbb52d4ec00a", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b2eaa0dd3cfb9bd7fb949b88217df9f25aed915e986a28ad5c8a0d054e7ca9d3"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"},
"phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"},
"plug": {:hex, :plug, "1.15.3", "712976f504418f6dff0a3e554c40d705a9bcf89a7ccef92fc6a5ef8f16a30a97", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cc4365a3c010a56af402e0809208873d113e9c38c401cabd88027ef4f5c01fd2"},
"plug_crypto": {:hex, :plug_crypto, "2.0.0", "77515cc10af06645abbfb5e6ad7a3e9714f805ae118fa1a70205f80d2d70fe73", [:mix], [], "hexpm", "53695bae57cc4e54566d993eb01074e4d894b65a3766f1c43e2c61a1b0f45ea9"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"thousand_island": {:hex, :thousand_island, "1.3.2", "bc27f9afba6e1a676dd36507d42e429935a142cf5ee69b8e3f90bff1383943cd", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0e085b93012cd1057b378fce40cbfbf381ff6d957a382bfdd5eca1a98eec2535"},
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
"websock_adapter": {:hex, :websock_adapter, "0.5.5", "9dfeee8269b27e958a65b3e235b7e447769f66b5b5925385f5a569269164a210", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "4b977ba4a01918acbf77045ff88de7f6972c2a009213c515a445c48f224ffce9"},
}

View file

@ -10,7 +10,11 @@ https://github.com/wojtekmach/mix_install_examples/blob/main/phoenix_live_view.e
So I've put this together in a Nix Flake to serve as a decent launch point for So I've put this together in a Nix Flake to serve as a decent launch point for
quick-and-dirty Elixir applications. quick-and-dirty Elixir applications.
Here ya go! `mix.exs` is necessary for locking dependencies as used by Nix's `mixFodDeps`
and is used for nice things like code reloading by Phoenix, so not _quite_ as
"single file" as my inspiration.
So here ya go!
```bash ```bash
elixir main.ex elixir main.ex