diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..61fe440 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1761597516, + "narHash": "sha256-wxX7u6D2rpkJLWkZ2E932SIvDJW8+ON/0Yy8+a5vsDU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "daf6dc47aa4b44791372d6139ab7b25269184d55", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..0e43f05 --- /dev/null +++ b/flake.nix @@ -0,0 +1,130 @@ +{ + description = "plebsaber.stream SvelteKit application"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; + }; + + outputs = { self, nixpkgs }: let + inherit (nixpkgs.lib) genAttrs; + systems = [ "x86_64-linux" "aarch64-linux" ]; + forAllSystems = genAttrs systems; + + mkPackage = pkgs: + pkgs.buildNpmPackage { + pname = "plebsaber-stream"; + version = "0.0.1"; + src = pkgs.lib.cleanSourceWith { + src = ./.; + filter = path: type: + !(pkgs.lib.hasInfix "/.git/" path) + && !(pkgs.lib.hasInfix "/node_modules/" path) + && !(pkgs.lib.hasInfix "/.svelte-kit/" path); + }; + + nodejs = pkgs.nodejs_22; + npmDepsHash = "sha256-q2C2NBxjVoxA6XFEMjGZcHAujp5OTiz7llhq3aRFiY0="; + npmBuildScript = "build"; + NODE_OPTIONS = "--dns-result-order=ipv4first"; + + nativeBuildInputs = [ pkgs.makeWrapper ]; + + installPhase = '' + runHook preInstall + mkdir -p $out/app + cp -r build $out/app/ + makeWrapper ${pkgs.nodejs_22}/bin/node $out/bin/plebsaber-stream \ + --set NODE_ENV production \ + --add-flags "$out/app/build/index.js" + runHook postInstall + ''; + + meta = { + description = "plebsaber.stream SvelteKit application"; + mainProgram = "plebsaber-stream"; + }; + }; + in rec { + packages = forAllSystems (system: let + pkgs = import nixpkgs { inherit system; }; + pkg = mkPackage pkgs; + in { + plebsaber-stream = pkg; + default = pkg; + }); + + overlays.default = final: prev: { + plebsaber-stream = self.packages.${prev.stdenv.hostPlatform.system}.plebsaber-stream; + }; + + nixosModules.default = { config, lib, pkgs, ... }: + let + inherit (lib) mkEnableOption mkIf mkOption types; + cfg = config.services.plebsaber-stream; + system = pkgs.stdenv.hostPlatform.system; + defaultPackage = self.packages.${system}.plebsaber-stream; + in { + options.services.plebsaber-stream = { + enable = mkEnableOption "plebsaber.stream SvelteKit service"; + + package = mkOption { + type = types.package; + default = defaultPackage; + defaultText = "self.packages.${system}.plebsaber-stream"; + description = "Derivation that provides the plebsaber.stream server."; + }; + + port = mkOption { + type = types.port; + default = 8037; + description = "HTTP listen port for the Node server."; + }; + + stateDirectory = mkOption { + type = types.str; + default = "plebsaber-stream"; + description = "Name of the state directory managed by systemd."; + }; + + environment = mkOption { + type = types.attrsOf types.str; + default = {}; + description = "Additional environment variables for the service."; + }; + + environmentFile = mkOption { + type = types.nullOr types.path; + default = null; + description = "Optional environment file consumed by systemd."; + }; + }; + + config = mkIf cfg.enable { + systemd.services.plebsaber-stream = { + description = "plebsaber.stream SvelteKit service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; + + environment = { + NODE_ENV = "production"; + PORT = builtins.toString cfg.port; + } // cfg.environment; + + serviceConfig = { + Type = "simple"; + ExecStart = "${cfg.package}/bin/plebsaber-stream"; + DynamicUser = true; + StateDirectory = cfg.stateDirectory; + WorkingDirectory = "/var/lib/${cfg.stateDirectory}"; + Restart = "on-failure"; + RestartSec = 3; + } // lib.optionalAttrs (cfg.environmentFile != null) { + EnvironmentFile = cfg.environmentFile; + }; + }; + }; + }; + }; +} + diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index da54164..1181a08 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -23,7 +23,7 @@ Gitea Source code - Built with SvelteKit, and joy + Built with SvelteKit, and ❤️ diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 9f775dd..953ebb8 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -16,9 +16,9 @@
- +
Tool
-
BeatLeader Compare
+
Compare PlayerHistories
A vs B: songs A played that B has not
diff --git a/src/routes/guides/beatleader-auth/+page.server.ts b/src/routes/guides/beatleader-auth/+page.server.ts deleted file mode 100644 index 5455d3e..0000000 --- a/src/routes/guides/beatleader-auth/+page.server.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { dev } from '$app/environment'; -import { error } from '@sveltejs/kit'; -import type { PageServerLoad } from './$types'; - -export const load: PageServerLoad = async () => { - if (!dev) { - throw error(404, 'Not found'); - } - - return {}; -}; - diff --git a/src/routes/guides/beatleader-auth/+page.svelte b/src/routes/guides/beatleader-auth/+page.svelte index 0772504..cd763d7 100644 --- a/src/routes/guides/beatleader-auth/+page.svelte +++ b/src/routes/guides/beatleader-auth/+page.svelte @@ -30,7 +30,7 @@ For this app, I explored three ways to access your BeatLeader data: Steam, OAuth, or a website‑style session.

- I wanted tools like Compare Players to show unranked star ratings when your BeatLeader account is a supporter and ShowAllRatings is enabled. That turns out to not be possible without implementing Steam ticket handling using the Steamworks SDK. The rest of the notes here were written before I realized that. + I wanted tools like Compare Players to show unranked star ratings when your BeatLeader account is a supporter and ShowAllRatings is enabled. That turns out to not be possible without implementing Steam ticket handling using the Steamworks SDK. The rest of the notes here were written before I realized that.

@@ -97,7 +97,7 @@
  • scp:offline_access to refresh your session without re‑prompting (optional).
  • - You can still login with OAuth when needed: Login with BeatLeader (OAuth) + You can still login with OAuth when needed: Login with BeatLeader (OAuth)

    After OAuth login, we attempt to enable ShowAllRatings automatically. If your BL account is not a supporter, BL will ignore it. @@ -142,7 +142,7 @@

    OAuth App Setup (for developers)

    1. - Configure BeatLeader OAuth credentials here: BL OAuth Setup. + Configure BeatLeader OAuth credentials here: BL OAuth Setup. If you already have credentials, you can paste them there.