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