Initial commit
This commit is contained in:
commit
b35d8687a0
22
.gitignore
vendored
Normal file
22
.gitignore
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# secret files
|
||||||
|
*.secret.*
|
||||||
|
|
||||||
|
# build output
|
||||||
|
/_build
|
||||||
|
|
||||||
|
# elixir dependencies
|
||||||
|
/deps
|
||||||
|
|
||||||
|
# crash dumps
|
||||||
|
erl_crash.dump
|
||||||
|
|
||||||
|
# sqlite databases
|
||||||
|
*.db
|
||||||
|
*.db-shm
|
||||||
|
*.db-wal
|
||||||
|
|
||||||
|
# nix build output
|
||||||
|
/result
|
||||||
|
|
||||||
|
# direnv cache
|
||||||
|
/.direnv
|
27
flake.lock
Normal file
27
flake.lock
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1708407374,
|
||||||
|
"narHash": "sha256-EECzarm+uqnNDCwaGg/ppXCO11qibZ1iigORShkkDf0=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "f33dd27a47ebdf11dc8a5eb05e7c8fbdaf89e73f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
60
flake.nix
Normal file
60
flake.nix
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = {
|
||||||
|
self,
|
||||||
|
nixpkgs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit (self) outputs;
|
||||||
|
|
||||||
|
systems = [
|
||||||
|
"aarch64-linux"
|
||||||
|
"aarch64-darwin"
|
||||||
|
"x86_64-darwin"
|
||||||
|
"x86_64-linux"
|
||||||
|
];
|
||||||
|
|
||||||
|
forAllSystems = nixpkgs.lib.genAttrs systems;
|
||||||
|
|
||||||
|
nixpkgsFor = system: import nixpkgs {inherit system;};
|
||||||
|
in {
|
||||||
|
packages = forAllSystems (system: let
|
||||||
|
pkgs = nixpkgsFor system;
|
||||||
|
|
||||||
|
inherit (pkgs) beamPackages;
|
||||||
|
inherit (beamPackages) mixRelease fetchMixDeps;
|
||||||
|
|
||||||
|
version = "0.1.0";
|
||||||
|
src = ./.;
|
||||||
|
pname = "api.lyte.dev";
|
||||||
|
in {
|
||||||
|
# this-package = mixRelease {
|
||||||
|
# inherit pname version src;
|
||||||
|
# mixFodDeps = fetchMixDeps {
|
||||||
|
# inherit version src;
|
||||||
|
# pname = "mix-deps-${pname}";
|
||||||
|
# hash = pkgs.lib.fakeSha256;
|
||||||
|
# };
|
||||||
|
# buildInputs = with pkgs; [sqlite];
|
||||||
|
# HOME = "$(pwd)";
|
||||||
|
# MIX_XDG = "$HOME";
|
||||||
|
# };
|
||||||
|
|
||||||
|
# default = outputs.packages.${system}.this-package;
|
||||||
|
});
|
||||||
|
|
||||||
|
devShells = forAllSystems (system: let
|
||||||
|
pkgs = nixpkgsFor system;
|
||||||
|
erlang = pkgs.beam.packages.erlang_26;
|
||||||
|
elixir = erlang.elixir_1_16;
|
||||||
|
in {
|
||||||
|
default = pkgs.mkShell {
|
||||||
|
shellHook = "export LOCALE_ARCHIVE=/usr/lib/locale/locale-archive";
|
||||||
|
buildInputs = with pkgs; [erlang_26 elixir elixir-ls watchexec];
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
92
main.ex
Normal file
92
main.ex
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
Application.put_env(:sample, Sfe.Endpoint,
|
||||||
|
http: [ip: {127, 0, 0, 1}, port: 5001],
|
||||||
|
adapter: Bandit.PhoenixAdapter,
|
||||||
|
server: true,
|
||||||
|
live_view: [signing_salt: "aaaaaaaa"],
|
||||||
|
secret_key_base: String.duplicate("a", 64)
|
||||||
|
)
|
||||||
|
|
||||||
|
Mix.install([
|
||||||
|
{:bandit, "~> 1.2"},
|
||||||
|
{:jason, "~> 1.0"},
|
||||||
|
{:phoenix, "~> 1.7.0"},
|
||||||
|
{:phoenix_live_view, "~> 0.19.0"},
|
||||||
|
{:phoenix_pubsub, "~> 2.1"}
|
||||||
|
])
|
||||||
|
|
||||||
|
defmodule Sfe.ErrorView do
|
||||||
|
def render(template, _), do: Phoenix.Controller.status_message_from_template(template)
|
||||||
|
end
|
||||||
|
|
||||||
|
defmodule Sfe.HomeLive do
|
||||||
|
use Phoenix.LiveView, layout: {__MODULE__, :live}
|
||||||
|
|
||||||
|
def mount(_params, _session, socket) do
|
||||||
|
{:ok, assign(socket, :count, 0)}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp phx_vsn, do: Application.spec(:phoenix, :vsn)
|
||||||
|
defp lv_vsn, do: Application.spec(:phoenix_live_view, :vsn)
|
||||||
|
|
||||||
|
def render("live.html", assigns) do
|
||||||
|
~H"""
|
||||||
|
<script src={"https://cdn.jsdelivr.net/npm/phoenix@#{phx_vsn()}/priv/static/phoenix.min.js"}></script>
|
||||||
|
<script src={"https://cdn.jsdelivr.net/npm/phoenix_live_view@#{lv_vsn()}/priv/static/phoenix_live_view.min.js"}></script>
|
||||||
|
<script>
|
||||||
|
let liveSocket = new window.LiveView.LiveSocket("/live", window.Phoenix.Socket)
|
||||||
|
liveSocket.connect()
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
* { font-size: 1.1em; }
|
||||||
|
</style>
|
||||||
|
<%= @inner_content %>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(assigns) do
|
||||||
|
~H"""
|
||||||
|
Multiplayer Counter
|
||||||
|
<%= @count %>
|
||||||
|
<button phx-click="inc">+</button>
|
||||||
|
<button phx-click="dec">-</button>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("inc", _params, socket) do
|
||||||
|
{:noreply, assign(socket, :count, socket.assigns.count + 1)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("dec", _params, socket) do
|
||||||
|
{:noreply, assign(socket, :count, socket.assigns.count - 1)}
|
||||||
|
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: :sample
|
||||||
|
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)
|
27
readme.md
Normal file
27
readme.md
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# Single-File Elixir (`sfe`)
|
||||||
|
|
||||||
|
I love Elixir, but for some reason I can't stand it's default project structure
|
||||||
|
and willingness to spread a hundred things across a hundred files.
|
||||||
|
|
||||||
|
I was inspired by this:
|
||||||
|
|
||||||
|
https://github.com/wojtekmach/mix_install_examples/blob/main/phoenix_live_view.exs
|
||||||
|
|
||||||
|
So I've put this together in a Nix Flake to serve as a decent launch point for
|
||||||
|
quick-and-dirty Elixir applications.
|
||||||
|
|
||||||
|
Here ya go!
|
||||||
|
|
||||||
|
```bash
|
||||||
|
elixir main.ex
|
||||||
|
```
|
||||||
|
|
||||||
|
Or if you want "hot reloading"
|
||||||
|
|
||||||
|
```bash
|
||||||
|
watchexec --filter main.ex --restart 'elixir main.ex'
|
||||||
|
```
|
||||||
|
|
||||||
|
# To Do
|
||||||
|
|
||||||
|
- Look into `:counters` to implement pubsub stuff
|
Loading…
Reference in a new issue