From e005675bb8fa5684b200285373e94de9d3e9c9ee Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Tue, 2 Dec 2025 23:44:36 -0500 Subject: [PATCH] nix + web stuff --- flake.lock | 100 +++++++++++++++++++++ flake.nix | 225 ++++++++++++++++++++++++++++++++++++++++++++++++ src/math_app.rs | 15 ++-- 3 files changed, 333 insertions(+), 7 deletions(-) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..267e6e4 --- /dev/null +++ b/flake.lock @@ -0,0 +1,100 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1764517877, + "narHash": "sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "2d293cbfa5a793b4c50d17c05ef9e385b90edf6c", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay", + "simon-egui": "simon-egui" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1764729618, + "narHash": "sha256-z4RA80HCWv2los1KD346c+PwNPzMl79qgl7bCVgz8X0=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "52764074a85145d5001bf0aa30cb71936e9ad5b8", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "simon-egui": { + "flake": false, + "locked": { + "lastModified": 1764730109, + "narHash": "sha256-vNETC0oq6tKJKF8KOGQKKIWRom38m0RwGgi3MPBrRx8=", + "owner": "Titaniumtown", + "repo": "egui", + "rev": "b63c21d70150f1b414370f0f9a8af56e886662f4", + "type": "github" + }, + "original": { + "owner": "Titaniumtown", + "repo": "egui", + "rev": "b63c21d70150f1b414370f0f9a8af56e886662f4", + "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" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..cc7f042 --- /dev/null +++ b/flake.nix @@ -0,0 +1,225 @@ +{ + description = "YTBN Graphing Software - Web-compatible graphing calculator"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + simon-egui = { + url = "github:Titaniumtown/egui/b63c21d70150f1b414370f0f9a8af56e886662f4"; + flake = false; + }; + }; + + outputs = { self, nixpkgs, flake-utils, rust-overlay, simon-egui }: + flake-utils.lib.eachDefaultSystem (system: + let + overlays = [ (import rust-overlay) ]; + pkgs = import nixpkgs { + inherit system overlays; + }; + + # Use nightly rust with wasm32 target + rustToolchain = pkgs.rust-bin.nightly."2025-05-01".default.override { + targets = [ "wasm32-unknown-unknown" ]; + }; + + rustPlatform = pkgs.makeRustPlatform { + cargo = rustToolchain; + rustc = rustToolchain; + }; + + # Build wasm-bindgen-cli matching the version in Cargo.lock (0.2.106) + wasm-bindgen-cli = rustPlatform.buildRustPackage rec { + pname = "wasm-bindgen-cli"; + version = "0.2.106"; + + src = pkgs.fetchCrate { + inherit pname version; + hash = "sha256-M6WuGl7EruNopHZbqBpucu4RWz44/MSdv6f0zkYw+44="; + }; + + cargoHash = "sha256-ElDatyOwdKwHg3bNH/1pcxKI7LXkhsotlDPQjiLHBwA="; + + nativeBuildInputs = [ pkgs.pkg-config ]; + buildInputs = [ pkgs.openssl ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ + pkgs.curl + pkgs.darwin.apple_sdk.frameworks.Security + ]; + + # Tests require network access + doCheck = false; + }; + + # Create a combined source with the main project and dependencies + combinedSrc = pkgs.stdenv.mkDerivation { + name = "ytbn-combined-src"; + phases = [ "installPhase" ]; + installPhase = '' + mkdir -p $out/integral_site_rust + mkdir -p $out/simon-egui + + cp -r ${./.}/* $out/integral_site_rust/ + cp -r ${simon-egui}/* $out/simon-egui/ + + chmod -R u+w $out + ''; + }; + + # Build the wasm library using rustPlatform + wasmLib = rustPlatform.buildRustPackage { + pname = "ytbn-graphing-software-wasm"; + version = "0.1.0"; + + src = combinedSrc; + sourceRoot = "${combinedSrc.name}/integral_site_rust"; + + cargoLock = { + lockFile = ./Cargo.lock; + outputHashes = { + "egui_plot-0.34.0" = "sha256-lk0yeljsvkHzF0eLD5llQ+05DycPqG2jGzhBvQ0X6Qw="; + }; + }; + + nativeBuildInputs = with pkgs; [ + python3Packages.fonttools + pkg-config + clang + ]; + + buildInputs = with pkgs; [ + openssl + zstd + ]; + + buildPhase = '' + runHook preBuild + + export HOME=$TMPDIR + + cargo build \ + --release \ + --lib \ + --target wasm32-unknown-unknown + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + mkdir -p $out/lib + cp target/wasm32-unknown-unknown/release/*.wasm $out/lib/ + runHook postInstall + ''; + + doCheck = false; + }; + + # Final web package with wasm-bindgen processing + ytbn-graphing-software-web = pkgs.stdenv.mkDerivation { + pname = "ytbn-graphing-software-web"; + version = "0.1.0"; + + src = ./.; + + nativeBuildInputs = [ + wasm-bindgen-cli + pkgs.binaryen + ]; + + buildPhase = '' + runHook preBuild + + # Generate JS bindings + wasm-bindgen ${wasmLib}/lib/ytbn_graphing_software.wasm \ + --out-dir out \ + --out-name ytbn_graphing_software \ + --target web \ + --no-typescript + + # Optimize wasm (enable features used by modern rust wasm targets) + wasm-opt out/ytbn_graphing_software_bg.wasm \ + -O2 --fast-math \ + --enable-bulk-memory \ + --enable-nontrapping-float-to-int \ + --enable-sign-ext \ + --enable-mutable-globals \ + -o out/ytbn_graphing_software_bg.wasm + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out + + # Copy wasm and js files + cp out/ytbn_graphing_software_bg.wasm $out/ + cp out/ytbn_graphing_software.js $out/ + + # Copy static web assets + cp www/index.html $out/ + cp www/manifest.json $out/ + cp www/sw.js $out/ + + # Copy logo + cp assets/logo.svg $out/ + + runHook postInstall + ''; + + meta = with pkgs.lib; { + description = "Web-compatible graphing calculator similar to Desmos"; + homepage = "https://github.com/Titaniumtown/YTBN-Graphing-Software"; + license = licenses.agpl3Only; + platforms = platforms.all; + }; + }; + in + { + packages = { + default = ytbn-graphing-software-web; + web = ytbn-graphing-software-web; + wasm = wasmLib; + }; + + devShells.default = pkgs.mkShell { + nativeBuildInputs = with pkgs; [ + rustToolchain + wasm-bindgen-cli + binaryen + python3Packages.fonttools + rust-analyzer + pkg-config + clang + + # Runtime deps for native builds + libxkbcommon + libGL + wayland + xorg.libX11 + xorg.libXcursor + xorg.libXi + ]; + + buildInputs = with pkgs; [ + openssl + zstd + ]; + + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath (with pkgs; [ + libxkbcommon + libGL + wayland + xorg.libX11 + xorg.libXcursor + xorg.libXi + ]); + }; + } + ); +} diff --git a/src/math_app.rs b/src/math_app.rs index 01ca817..02d6db0 100644 --- a/src/math_app.rs +++ b/src/math_app.rs @@ -202,15 +202,16 @@ impl MathApp { #[cfg(target_arch = "wasm32")] { tracing::info!("Setting decompression cache"); - let commit: crate::misc::HashBytes = const { - unsafe { - std::mem::transmute::<&str, crate::misc::HashBytes>(build::SHORT_COMMIT) - } - }; - let saved_data = commit.hashed_storage_create(data); + // Convert SHORT_COMMIT string to fixed-size byte array + let commit_bytes = build::SHORT_COMMIT.as_bytes(); + let mut commit: crate::misc::HashBytes = [0u8; crate::misc::HASH_LENGTH]; + let len = commit_bytes.len().min(crate::misc::HASH_LENGTH); + commit[..len].copy_from_slice(&commit_bytes[..len]); + + let saved_data = crate::misc::hashed_storage_create(commit, &data); tracing::info!("Bytes: {}", saved_data.len()); get_localstorage() - .set_item(DATA_NAME, saved_data) + .set_item(DATA_NAME, &saved_data) .expect("failed to set local storage cache"); }