This commit is contained in:
Daniel Flanagan 2023-11-10 14:57:20 -06:00
commit de2dcd0cf6
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4
11 changed files with 2194 additions and 0 deletions

5
.cargo/config.toml Normal file
View file

@ -0,0 +1,5 @@
[build]
target = "wasm32-wasi"
[target.wasm32-wasi]
runner = "lunatic"

1
.envrc Normal file
View file

@ -0,0 +1 @@
use flake

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/target
/.direnv

1858
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

19
Cargo.toml Normal file
View file

@ -0,0 +1,19 @@
[package]
name = "lyrics-smslv"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
lunatic = "0.13.1"
serde = "1.0.192"
submillisecond = "0.4.1"
submillisecond-live-view = "0.4.1"
[profile.release]
strip = true
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"

138
flake.lock Normal file
View file

@ -0,0 +1,138 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1681202837,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"naersk": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1698153314,
"narHash": "sha256-TunvZMCxXHvU6fz5kq3XTLfojIvTDlbFGfPUFtwCU5o=",
"owner": "nix-community",
"repo": "naersk",
"rev": "06a99941d72e2202ed62b8aa08b9869817fea56f",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "master",
"repo": "naersk",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1697915759,
"narHash": "sha256-WyMj5jGcecD+KC8gEs+wFth1J1wjisZf8kVZH13f1Zo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "51d906d2341c9e866e48c2efcaac0f2d70bfd43e",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"naersk": "naersk",
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay",
"utils": "utils"
}
},
"rust-overlay": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1699409596,
"narHash": "sha256-L3g1smIol3dGTxkUQOlNShJtZLvjLzvtbaeTRizwZBU=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "58240e1ac627cef3ea30c7732fedfb4f51afd8e7",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"utils": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

55
flake.nix Normal file
View file

@ -0,0 +1,55 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
utils.url = "github:numtide/flake-utils";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
naersk = {
url = "github:nix-community/naersk/master";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = inputs @ {self, ...}:
inputs.utils.lib.eachDefaultSystem (system: let
pkgs = import inputs.nixpkgs {
inherit system;
overlays = [
(import inputs.rust-overlay)
];
};
toolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
naersk = pkgs.callPackage inputs.naersk {
cargo = toolchain;
rustc = toolchain;
};
in {
packages.default = naersk.buildPackage {
src = ./.;
};
formatter = pkgs.alejandra;
checks = {
inherit (self.packages.${system}) default;
# TODO: clippy and other checks?
};
devShell = with pkgs;
mkShell {
buildInputs = [
toolchain
lunatic
rustfmt
pre-commit
rustPackages.clippy
rust-analyzer
];
RUST_SRC_PATH = rustPlatform.rustLibSrc;
};
});
}

2
index.html Normal file
View file

@ -0,0 +1,2 @@
sup
<div id="app"></div>

15
readme.md Normal file
View file

@ -0,0 +1,15 @@
# Why
I think something like this is the fuuuuuture. A Rust-core, almost-erlang
runtime for wasm has so many insane possibilities and possible promises that
it's impossible to ignore.
However, this tiny counter example currently uses ~150MB of memory on my machine.
With space optimizations, I still end up at ~122MB.
I think I value being small too much. Or perhaps the runtime does indeed provide a huge featureset.
- What does wasmtime/wasi include? (wastime is roughtly a 30MB binary -- 28MB stripped)
- What does lunatic include? (29MB, 22MB stripped)
- What all does submillisecond and sms_live include? (probably not much since the wasm bytecode is 1.2MB, but even that is pretty large IMO)

3
rust-toolchain.toml Normal file
View file

@ -0,0 +1,3 @@
[toolchain]
channel = "1.73.0"
targets = ["wasm32-wasi"]

96
src/main.rs Normal file
View file

@ -0,0 +1,96 @@
use lunatic::supervisor::{Supervisor, SupervisorConfig, SupervisorStrategy};
use serde::{Deserialize, Serialize};
use submillisecond::{router, static_router, Application};
use submillisecond_live_view::prelude::*;
use lunatic::abstract_process;
use lunatic::ap::{Config, ProcessRef};
pub struct Counter(i64);
#[abstract_process(visibility = pub)]
impl Counter {
#[init]
fn init(_: Config<Self>, start: i64) -> Result<Self, ()> {
Ok(Self(start))
}
#[handle_message]
fn increment(&mut self) {
self.0 += 1;
}
#[handle_message]
fn decrement(&mut self) {
self.0 -= 1;
}
#[handle_request]
fn count(&self) -> i64 {
self.0
}
}
struct Sup;
impl Supervisor for Sup {
type Arg = ();
// Start 1 child and monitor it for failures.
type Children = (Counter,);
fn init(config: &mut SupervisorConfig<Self>, _: ()) {
config.set_strategy(SupervisorStrategy::OneForOne);
config.children_args(((0, Some(String::from("global_counter"))),));
}
}
fn main() -> std::io::Result<()> {
let mut supconf = SupervisorConfig::default();
Sup::init(&mut supconf, ());
Application::new(router! {
"/" => CounterView::handler("index.html", "#app")
"/static" => static_router!("./static")
})
.serve("127.0.0.1:3000")
}
#[derive(Clone, Serialize, Deserialize)]
struct CounterView {
global_counter: ProcessRef<Counter>,
}
impl LiveView for CounterView {
type Events = (Increment, Decrement);
fn mount(_uri: Uri, _socket: Option<Socket>) -> Self {
let global_counter = ProcessRef::<Counter>::lookup(&"global_counter").unwrap();
Self { global_counter }
}
fn render(&self) -> Rendered {
html! {
button @click=(Increment) { "Increment" }
button @click=(Decrement) { "Decrement" }
p { "Count is " (self.global_counter.count()) }
}
}
}
#[derive(Deserialize)]
struct Increment {}
impl LiveViewEvent<Increment> for CounterView {
fn handle(state: &mut Self, _event: Increment) {
state.global_counter.increment()
}
}
#[derive(Deserialize)]
struct Decrement {}
impl LiveViewEvent<Decrement> for CounterView {
fn handle(state: &mut Self, _event: Decrement) {
state.global_counter.decrement()
}
}