Format shit

This commit is contained in:
MotorTruck1221 2025-05-04 23:57:30 -06:00
parent a78ab8e1b2
commit 5f640d8e06
No known key found for this signature in database
GPG key ID: 08F417E2B8B61EA4
21 changed files with 338 additions and 298 deletions

View file

@ -1,8 +1,8 @@
import { defineConfig } from 'astro/config'; import { defineConfig } from "astro/config";
import type { Plugin } from 'vite'; import type { Plugin } from "vite";
import wisp from "wisp-server-node"; import wisp from "wisp-server-node";
import node from '@astrojs/node'; import node from "@astrojs/node";
import tailwindcss from '@tailwindcss/vite'; import tailwindcss from "@tailwindcss/vite";
import icon from "astro-icon"; import icon from "astro-icon";
import { viteStaticCopy } from "vite-plugin-static-copy"; import { viteStaticCopy } from "vite-plugin-static-copy";
import playformCompress from "@playform/compress"; import playformCompress from "@playform/compress";
@ -15,13 +15,13 @@ import { baremuxPath } from "@mercuryworkshop/bare-mux/node";
const viteWispServer = (): Plugin => { const viteWispServer = (): Plugin => {
return { return {
name: 'vite-wisp-server', name: "vite-wisp-server",
configureServer(server) { configureServer(server) {
server.httpServer?.on('upgrade', (req, socket, head) => { server.httpServer?.on("upgrade", (req, socket, head) => {
req.url.startsWith('/wisp') ? wisp.routeRequest(req, socket, head) : undefined req.url.startsWith("/wisp") ? wisp.routeRequest(req, socket, head) : undefined;
}) });
} }
} };
}; };
export default defineConfig({ export default defineConfig({
@ -35,10 +35,26 @@ export default defineConfig({
viteStaticCopy({ viteStaticCopy({
targets: [ targets: [
{ src: `${uvPath}/**/*`.replace(/\\/g, "/"), dest: "vu", overwrite: false }, { src: `${uvPath}/**/*`.replace(/\\/g, "/"), dest: "vu", overwrite: false },
{ src: `${scramjetPath}/**/*`.replace(/\\/g, "/"), dest: "marcs", overwrite: false }, {
{ src: `${baremuxPath}/**/*`.replace(/\\/g, "/"), dest: "erab", overwrite: false }, src: `${scramjetPath}/**/*`.replace(/\\/g, "/"),
{ src: `${epoxyPath}/**/*`.replace(/\\/g, "/"), dest: "epoxy", overwrite: false }, dest: "marcs",
{ src: `${libcurlPath}/**/*`.replace(/\\/g, "/"), dest: "libcurl", overwrite: false } overwrite: false
},
{
src: `${baremuxPath}/**/*`.replace(/\\/g, "/"),
dest: "erab",
overwrite: false
},
{
src: `${epoxyPath}/**/*`.replace(/\\/g, "/"),
dest: "epoxy",
overwrite: false
},
{
src: `${libcurlPath}/**/*`.replace(/\\/g, "/"),
dest: "libcurl",
overwrite: false
}
] ]
}) })
] ]
@ -53,8 +69,8 @@ export default defineConfig({
SVG: true SVG: true
}) })
], ],
output: 'server', output: "server",
adapter: node({ adapter: node({
mode: 'middleware' mode: "middleware"
}) })
}); });

View file

@ -1,41 +1,40 @@
{ {
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"vcs": { "vcs": {
"enabled": false, "enabled": false,
"clientKind": "git", "clientKind": "git",
"useIgnoreFile": false "useIgnoreFile": false
}, },
"files": { "files": {
"ignore": ["**/dist/**", ".github/**"], "ignore": ["**/dist/**", ".github/**"],
"include": ["**/**", "server/**"] "include": ["**/**", "server/**"]
}, },
"formatter": { "formatter": {
"enabled": true, "enabled": true,
"indentStyle": "space", "indentStyle": "space",
"indendWidth": 4, "indentWidth": 4,
"lineWidth": 100, "lineWidth": 100,
"ignore": ["pnpm-lock.yaml", "package.json"] "ignore": ["pnpm-lock.yaml", "package.json"]
}, },
"organizeImports": { "organizeImports": {
"enabled": true "enabled": true
}, },
"linter": { "linter": {
"enabled": false "enabled": false
}, },
"javascript": { "javascript": {
"formatter": { "formatter": {
"trailingCommas": "none" "trailingCommas": "none",
"quoteStyle": "double", "quoteStyle": "double",
"semicolons": "always" "semicolons": "always"
} }
}, },
"json": { "json": {
"parser": { "parser": {
"allowComments": true, "allowComments": true,
"allowTrailingCommas": true "allowTrailingCommas": true
}, },
"formatter": { "formatter": {
"indentSyle": "space",
"trailingCommas": "none" "trailingCommas": "none"
} }
} }

View file

@ -1,7 +1,7 @@
importScripts( importScripts(
"/vu/uv.bundle.js", "/vu/uv.bundle.js",
"/vu/uv.config.js", "/vu/uv.config.js",
"/marcs/scramjet.shared.js", "/marcs/scramjet.shared.js",
"/marcs/scramjet.worker.js" "/marcs/scramjet.worker.js"
); );
importScripts(__uv$config.sw || "/vu/uv.sw.js"); importScripts(__uv$config.sw || "/vu/uv.sw.js");
@ -15,11 +15,9 @@ self.addEventListener("fetch", function (event) {
await sj.loadConfig(); await sj.loadConfig();
if (event.request.url.startsWith(location.origin + __uv$config.prefix)) { if (event.request.url.startsWith(location.origin + __uv$config.prefix)) {
return await uv.fetch(event); return await uv.fetch(event);
} } else if (sj.route(event)) {
else if (sj.route(event)) {
return await sj.fetch(event); return await sj.fetch(event);
} } else {
else {
return await fetch(event.request); return await fetch(event.request);
} }
})() })()

View file

@ -1,20 +1,19 @@
import Fastify, { FastifyReply, FastifyRequest } from 'fastify'; import Fastify, { FastifyReply, FastifyRequest } from "fastify";
import fastifyMiddie from '@fastify/middie'; import fastifyMiddie from "@fastify/middie";
import fastifyStatic from '@fastify/static'; import fastifyStatic from "@fastify/static";
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from "node:url";
//@ts-ignore this is created at runtime. No types associated w/it //@ts-ignore this is created at runtime. No types associated w/it
import { handler as astroHandler } from "../dist/server/entry.mjs"; import { handler as astroHandler } from "../dist/server/entry.mjs";
const app = Fastify({ const app = Fastify({
logger: true, logger: true,
ignoreDuplicateSlashes: true, ignoreDuplicateSlashes: true,
ignoreTrailingSlash: true, ignoreTrailingSlash: true
}); });
await app.register(fastifyStatic, { await app.register(fastifyStatic, {
root: fileURLToPath(new URL('../dist/client', import.meta.url)) root: fileURLToPath(new URL("../dist/client", import.meta.url))
}); });
await app.register(fastifyMiddie); await app.register(fastifyMiddie);

View file

@ -1,104 +1,104 @@
[ [
{ {
"splash": "Join our community! https://discord.gg/qsXnhSPtAK" "splash": "Join our community! https://discord.gg/qsXnhSPtAK"
}, },
{ {
"splash": "Browse safely!" "splash": "Browse safely!"
}, },
{ {
"splash": "Access with ease!" "splash": "Access with ease!"
}, },
{ {
"splash": "Stay secure online!" "splash": "Stay secure online!"
}, },
{ {
"splash": "New updates available!" "splash": "New updates available!"
}, },
{ {
"splash": "Surf anonymously!" "splash": "Surf anonymously!"
}, },
{ {
"splash": "Unlock the web!" "splash": "Unlock the web!"
}, },
{ {
"splash": "Don't miss out!" "splash": "Don't miss out!"
}, },
{ {
"splash": "Fast and reliable!" "splash": "Fast and reliable!"
}, },
{ {
"splash": "Enjoy your privacy!" "splash": "Enjoy your privacy!"
}, },
{ {
"splash": "Let's get started!" "splash": "Let's get started!"
}, },
{ {
"splash": "Protect your data!" "splash": "Protect your data!"
}, },
{ {
"splash": "Freedom online!" "splash": "Freedom online!"
}, },
{ {
"splash": "Navigate freely!" "splash": "Navigate freely!"
}, },
{ {
"splash": "Your web, your rules!" "splash": "Your web, your rules!"
}, },
{ {
"splash": "Stay anonymous!" "splash": "Stay anonymous!"
}, },
{ {
"splash": "Access anything!" "splash": "Access anything!"
}, },
{ {
"splash": "Fast and secure!" "splash": "Fast and secure!"
}, },
{ {
"splash": "Browse without limits!" "splash": "Browse without limits!"
}, },
{ {
"splash": "Private and secure!" "splash": "Private and secure!"
}, },
{ {
"splash": "Keep your data safe!" "splash": "Keep your data safe!"
}, },
{ {
"splash": "Connect globally!" "splash": "Connect globally!"
}, },
{ {
"splash": "No boundaries!" "splash": "No boundaries!"
}, },
{ {
"splash": "Web freedom!" "splash": "Web freedom!"
}, },
{ {
"splash": "Stay private!" "splash": "Stay private!"
}, },
{ {
"splash": "Anonymous browsing!" "splash": "Anonymous browsing!"
}, },
{ {
"splash": "Secure access!" "splash": "Secure access!"
}, },
{ {
"splash": "Fast connections!" "splash": "Fast connections!"
}, },
{ {
"splash": "Unrestricted access!" "splash": "Unrestricted access!"
}, },
{ {
"splash": "Surf the web freely!" "splash": "Surf the web freely!"
}, },
{ {
"splash": "Your privacy matters!" "splash": "Your privacy matters!"
}, },
{ {
"splash": "Always connected!" "splash": "Always connected!"
}, },
{ {
"splash": "Web without limits!" "splash": "Web without limits!"
}, },
{ {
"splash": "Explore the internet!" "splash": "Explore the internet!"
} }
] ]

View file

@ -2,7 +2,7 @@
import { Icon } from "astro-icon/components"; import { Icon } from "astro-icon/components";
import type { SettingsProps as Props } from "@utils/types.ts"; import type { SettingsProps as Props } from "@utils/types.ts";
const { active } = Astro.props; const { active } = Astro.props;
--- ---
<div class="h-full w-full flex flex-col font-inter p-4 pl-8 pt-8 gap-2"> <div class="h-full w-full flex flex-col font-inter p-4 pl-8 pt-8 gap-2">
<a href="/settings/" class=`gap-2 px-4 py-2 rounded-lg h-10 w-full text-sm font-medium transition-colors items-center justify-start inline-flex ${active === "proxy" ? 'bg-(--secondary) hover:bg-(--secondary)/[0.8]' : 'bg-(--background) hover:bg-(--accent)'}`> <a href="/settings/" class=`gap-2 px-4 py-2 rounded-lg h-10 w-full text-sm font-medium transition-colors items-center justify-start inline-flex ${active === "proxy" ? 'bg-(--secondary) hover:bg-(--secondary)/[0.8]' : 'bg-(--background) hover:bg-(--accent)'}`>

View file

@ -1,10 +1,10 @@
--- ---
import { Icon } from 'astro-icon/components'; import { Icon } from "astro-icon/components";
interface Props { interface Props {
id: string; id: string;
text: string; text: string;
icon?: string icon?: string;
} }
const { id, text, icon } = Astro.props; const { id, text, icon } = Astro.props;
--- ---

View file

@ -10,7 +10,7 @@ interface Props {
imageSrc: string; imageSrc: string;
text: string; text: string;
id: string; id: string;
}; }
const { imageSrc, text, id, link } = Astro.props; const { imageSrc, text, id, link } = Astro.props;
--- ---

4
src/global.d.ts vendored
View file

@ -1,7 +1,7 @@
declare global { declare global {
interface Window { interface Window {
__uv: any; __uv: any;
$scramjet: any; $scramjet: any;
} }
} }
export {}; export {};

View file

@ -8,11 +8,15 @@ import Header from "@components/Header.astro";
import "@styles/global.css"; import "@styles/global.css";
import "@styles/default.css"; import "@styles/default.css";
readdir(pathJoin(import.meta.dirname, '..', 'styles', 'themes'), { encoding: 'utf-8' }, (err, files) => { readdir(
files.forEach(async (name) => { pathJoin(import.meta.dirname, "..", "styles", "themes"),
await import(`../styles/themes/${name.replace('.css', '')}.css`) { encoding: "utf-8" },
}); (err, files) => {
}); files.forEach(async (name) => {
await import(`../styles/themes/${name.replace(".css", "")}.css`);
});
}
);
--- ---
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">

View file

@ -8,12 +8,14 @@ import Input from "@components/ui/Input.astro";
import Button from "@components/ui/Button.astro"; import Button from "@components/ui/Button.astro";
import { type DropdownOptions } from "@utils/types"; import { type DropdownOptions } from "@utils/types";
const Themes: DropdownOptions[] = [{ name: 'Default', value: 'default' }]; const Themes: DropdownOptions[] = [{ name: "Default", value: "default" }];
const files = await readdir(pathJoin(import.meta.dirname, '..', '..', 'styles', 'themes'), { encoding: 'utf-8' }); const files = await readdir(pathJoin(import.meta.dirname, "..", "..", "styles", "themes"), {
encoding: "utf-8"
});
files.forEach((name) => { files.forEach((name) => {
Themes.push({ Themes.push({
name: name.toLowerCase().charAt(0).toUpperCase() + name.slice(1).replace('.css', ''), name: name.toLowerCase().charAt(0).toUpperCase() + name.slice(1).replace(".css", ""),
value: name.toLowerCase().replace('.css', '') value: name.toLowerCase().replace(".css", "")
}); });
}); });
--- ---

View file

@ -5,9 +5,9 @@ import Input from "@components/ui/Input.astro";
import Button from "@components/ui/Button.astro"; import Button from "@components/ui/Button.astro";
import { SearchEngines, type DropdownOptions } from "@utils/types"; import { SearchEngines, type DropdownOptions } from "@utils/types";
const SearchEngineOptions: DropdownOptions[] = []; const SearchEngineOptions: DropdownOptions[] = [];
Object.keys(SearchEngines).forEach((k) => SearchEngineOptions.push( Object.keys(SearchEngines).forEach((k) =>
{ name: k, value: SearchEngines[k] } SearchEngineOptions.push({ name: k, value: SearchEngines[k] })
)); );
--- ---
<SettingsLayout active="proxy" title="Proxy"> <SettingsLayout active="proxy" title="Proxy">
<div class="w-full flex-grow"> <div class="w-full flex-grow">

View file

@ -1,17 +1,17 @@
--- ---
import Layout from '@layouts/Layout.astro'; import Layout from "@layouts/Layout.astro";
import { Icon } from 'astro-icon/components' import { Icon } from "astro-icon/components";
import splash from "@assets/splash.json"; import splash from "@assets/splash.json";
const genSplash = (): String => { const genSplash = (): String => {
const idx = Math.floor(Math.random() * splash.length); const idx = Math.floor(Math.random() * splash.length);
return splash[idx].splash; return splash[idx].splash;
} };
const randomSplash = genSplash(); const randomSplash = genSplash();
const link = Astro.url.searchParams.get('redir'); const link = Astro.url.searchParams.get("redir");
--- ---
<Layout> <Layout>

View file

@ -1,7 +1,7 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap'); @import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap");
@import "tailwindcss"; @import "tailwindcss";
@theme { @theme {
--font-inter: "Inter", sans-serif --font-inter: "Inter", sans-serif;
} }

View file

@ -18,4 +18,4 @@
--destructive: hsl(2 82% 30%); --destructive: hsl(2 82% 30%);
--destructive-foreground: hsl(2 82% 90%); --destructive-foreground: hsl(2 82% 90%);
--ring: hsl(223 42% 57%); --ring: hsl(223 42% 57%);
} }

View file

@ -18,4 +18,4 @@
--destructive: hsl(5 92% 45%); --destructive: hsl(5 92% 45%);
--destructive-foreground: hsl(0 0% 100%); --destructive-foreground: hsl(0 0% 100%);
--ring: hsl(167 100% 50%); --ring: hsl(167 100% 50%);
} }

View file

@ -2,35 +2,35 @@ import { BareMuxConnection } from "@mercuryworkshop/bare-mux";
import { StoreManager } from "./storage"; import { StoreManager } from "./storage";
const createScript = (src: string, defer?: boolean) => { const createScript = (src: string, defer?: boolean) => {
const script = document.createElement('script') as HTMLScriptElement; const script = document.createElement("script") as HTMLScriptElement;
script.src = src; script.src = src;
if (defer) script.defer = defer; if (defer) script.defer = defer;
return document.body.appendChild(script); return document.body.appendChild(script);
} };
/** /**
* This class automatically sets up and handles lots of stuff for us. * This class automatically sets up and handles lots of stuff for us.
* *
* It registers/fixes errors with SW reg * It registers/fixes errors with SW reg
* It creates our bareMux worker * It creates our bareMux worker
* And other stuff. * And other stuff.
* *
* @example * @example
* import { SW } from "@utils/proxy.ts"; * import { SW } from "@utils/proxy.ts";
* const handler = new SW(); * const handler = new SW();
* //Consume the methods * //Consume the methods
* // Or if an instance is already running * // Or if an instance is already running
* import { SW } from "@utils/proxy.ts"; * import { SW } from "@utils/proxy.ts";
* const handler = SW.getInstance(); * const handler = SW.getInstance();
* //Consume the methods * //Consume the methods
*/ */
class SW { class SW {
#baremuxConn?: BareMuxConnection; #baremuxConn?: BareMuxConnection;
#scramjetController?: ScramjetController; #scramjetController?: ScramjetController;
#serviceWorker?: ServiceWorkerRegistration; #serviceWorker?: ServiceWorkerRegistration;
#storageManager: StoreManager<"radius||settings">; #storageManager: StoreManager<"radius||settings">;
static #instance = new Set(); static #instance = new Set();
static *getInstance() { static *getInstance() {
for (const val of SW.#instance.keys()) { for (const val of SW.#instance.keys()) {
yield val as SW; yield val as SW;
@ -38,41 +38,59 @@ class SW {
} }
#search(input: string, template: string) { #search(input: string, template: string) {
try { return new URL(input).toString() } catch (_) {}; try {
return new URL(input).toString();
} catch (_) {}
try { try {
const url = new URL(`http://${input}`); const url = new URL(`http://${input}`);
if (url.hostname.includes(".")) return url.toString(); if (url.hostname.includes(".")) return url.toString();
} catch (_) {}; } catch (_) {}
return template.replace("%s", encodeURIComponent(input)); return template.replace("%s", encodeURIComponent(input));
} }
encodeURL(string: string): string { encodeURL(string: string): string {
const proxy = this.#storageManager.getVal("proxy") as 'uv' | 'sj'; const proxy = this.#storageManager.getVal("proxy") as "uv" | "sj";
const input = this.#search(string, this.#storageManager.getVal('searchEngine')); const input = this.#search(string, this.#storageManager.getVal("searchEngine"));
return proxy === 'uv' ? `${__uv$config.prefix}${__uv$config.encodeUrl!(input)}` : this.#scramjetController!.encodeUrl(input) return proxy === "uv"
? `${__uv$config.prefix}${__uv$config.encodeUrl!(input)}`
: this.#scramjetController!.encodeUrl(input);
} }
async setTransport(transport?: 'epoxy' | 'libcurl', get?: boolean) { async setTransport(transport?: "epoxy" | "libcurl", get?: boolean) {
console.log('Setting transport'); console.log("Setting transport");
if (get) return this.#storageManager.getVal('transport'); if (get) return this.#storageManager.getVal("transport");
this.#storageManager.setVal("transport", transport || this.#storageManager.getVal("transport") || 'epoxy'); this.#storageManager.setVal(
switch(transport) { "transport",
case 'epoxy': { transport || this.#storageManager.getVal("transport") || "epoxy"
await this.#baremuxConn!.setTransport("/epoxy/index.mjs", [ { wisp: this.#storageManager.getVal('wispServer') }]); );
switch (transport) {
case "epoxy": {
await this.#baremuxConn!.setTransport("/epoxy/index.mjs", [
{ wisp: this.#storageManager.getVal("wispServer") }
]);
} }
case 'libcurl': { case "libcurl": {
await this.#baremuxConn!.setTransport("/libcurl/index.mjs", [ { wisp: this.#storageManager.getVal('wispServer') }]); await this.#baremuxConn!.setTransport("/libcurl/index.mjs", [
{ wisp: this.#storageManager.getVal("wispServer") }
]);
} }
default: { default: {
await this.#baremuxConn!.setTransport("/epoxy/index.mjs", [ { wisp: this.#storageManager.getVal('wispServer') }]); await this.#baremuxConn!.setTransport("/epoxy/index.mjs", [
{ wisp: this.#storageManager.getVal("wispServer") }
]);
} }
} }
} }
async wispServer(wispServer?: string, set?: true) { async wispServer(wispServer?: string, set?: true) {
this.#storageManager.setVal("wispServer", wispServer || this.#storageManager.getVal('wispServer') || (location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/wisp/"); this.#storageManager.setVal(
"wispServer",
wispServer ||
this.#storageManager.getVal("wispServer") ||
(location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/wisp/"
);
if (set) await this.setTransport(); if (set) await this.setTransport();
} }
@ -82,22 +100,25 @@ class SW {
const checkScripts = (): Promise<void> => { const checkScripts = (): Promise<void> => {
return new Promise((resolve) => { return new Promise((resolve) => {
const t = setInterval(() => { const t = setInterval(() => {
if (typeof __uv$config !== 'undefined' && typeof ScramjetController !== 'undefined') { if (
typeof __uv$config !== "undefined" &&
typeof ScramjetController !== "undefined"
) {
clearInterval(t); clearInterval(t);
resolve(); resolve();
} }
}); });
}); });
}; };
createScript('/vu/uv.bundle.js', true); createScript("/vu/uv.bundle.js", true);
createScript('/vu/uv.config.js', true); createScript("/vu/uv.config.js", true);
createScript('/marcs/scramjet.controller.js', true); createScript("/marcs/scramjet.controller.js", true);
checkScripts().then(async () => { checkScripts().then(async () => {
this.#baremuxConn = new BareMuxConnection("/erab/worker.js"); this.#baremuxConn = new BareMuxConnection("/erab/worker.js");
await this.setTransport(); await this.setTransport();
this.#scramjetController = new ScramjetController({ this.#scramjetController = new ScramjetController({
prefix: '/~/scramjet/', prefix: "/~/scramjet/",
files: { files: {
wasm: "/marcs/scramjet.wasm.wasm", wasm: "/marcs/scramjet.wasm.wasm",
worker: "/marcs/scramjet.worker.js", worker: "/marcs/scramjet.worker.js",
@ -109,19 +130,20 @@ class SW {
rewriterLogs: false rewriterLogs: false
} }
}); });
if ("serviceWorker" in navigator) { if ("serviceWorker" in navigator) {
await this.#scramjetController.init(); await this.#scramjetController.init();
navigator.serviceWorker.ready.then(async (reg) => { navigator.serviceWorker.ready.then(async (reg) => {
console.log('SW ready to go!'); console.log("SW ready to go!");
this.#serviceWorker = reg; this.#serviceWorker = reg;
}); });
navigator.serviceWorker.register("/sw.js", { scope: '/' }); navigator.serviceWorker.register("/sw.js", { scope: "/" });
} } else {
else { throw new Error(
throw new Error('Your browser is not supported! This website uses Service Workers heavily.'); "Your browser is not supported! This website uses Service Workers heavily."
);
} }
}); });
}; }
} }
export { SW }; export { SW };

View file

@ -3,37 +3,37 @@ import { BareMuxConnection } from "@mercuryworkshop/bare-mux";
import { SW } from "@utils/proxy.ts"; import { SW } from "@utils/proxy.ts";
import { SearchEngines } from "./types"; import { SearchEngines } from "./types";
/** /**
* The settings class * The settings class
* Initializes it's own StorageManager, and handles everything within the class itself * Initializes it's own StorageManager, and handles everything within the class itself
* *
* @example * @example
* // Create a new Settings instance (needs to be done only once) * // Create a new Settings instance (needs to be done only once)
* import { Settings } from "@utils/settings.ts"; * import { Settings } from "@utils/settings.ts";
* const settings = new Settings(); * const settings = new Settings();
* //Consume any of the methods with: * //Consume any of the methods with:
* settings.methodName(); * settings.methodName();
* *
* // Most of the time, you'll want to get the running instance this can be done with * // Most of the time, you'll want to get the running instance this can be done with
* import { Settings } from "@utils/settings.ts"; * import { Settings } from "@utils/settings.ts";
* const settings = await Settings.getInstance(); * const settings = await Settings.getInstance();
* //Consume any of the methods with: * //Consume any of the methods with:
* settings.methodName(); * settings.methodName();
*/ */
class Settings { class Settings {
// Our own internal StorageManager so things never interfere // Our own internal StorageManager so things never interfere
#storageManager: StoreManager<"radius||settings">; #storageManager: StoreManager<"radius||settings">;
static #instance = new Set(); static #instance = new Set();
/** /**
* Method to get the current or other Settings instance(s) * Method to get the current or other Settings instance(s)
* *
* *
* @example * @example
* const settings = await Settings.getInstance(); * const settings = await Settings.getInstance();
* // Consume the other methods * // Consume the other methods
*/ */
static async getInstance() { static async getInstance() {
function *get() { function* get() {
for (const instance of Settings.#instance.keys()) { for (const instance of Settings.#instance.keys()) {
yield instance!; yield instance!;
} }
@ -47,50 +47,50 @@ class Settings {
resolve(true); resolve(true);
} }
}, 100); }, 100);
}) });
} };
await ready(); await ready();
return get().next().value! as Settings; return get().next().value! as Settings;
} }
/** /**
* Set's the theme either to the current theme OR to a new one * Set's the theme either to the current theme OR to a new one
* *
* @example * @example
* // Retrieve the Settings instance * // Retrieve the Settings instance
* const settings = await Settings.getInstance(); * const settings = await Settings.getInstance();
* *
* // Consume the method * // Consume the method
* settings.theme() // Whatever value is in localstorage at the time * settings.theme() // Whatever value is in localstorage at the time
* settings.theme('theme name') // A new theme based off of the class name * settings.theme('theme name') // A new theme based off of the class name
*/ */
theme(theme?: string) { theme(theme?: string) {
this.#storageManager.setVal('theme', theme || this.#storageManager.getVal('theme')); this.#storageManager.setVal("theme", theme || this.#storageManager.getVal("theme"));
theme === 'default' theme === "default"
? document.documentElement.className = 'default' ? (document.documentElement.className = "default")
: document.documentElement.className = theme || this.#storageManager.getVal('theme'); : (document.documentElement.className = theme || this.#storageManager.getVal("theme"));
} }
proxy(prox?: 'uv' | 'sj') { proxy(prox?: "uv" | "sj") {
this.#storageManager.setVal('proxy', prox || 'uv'); this.#storageManager.setVal("proxy", prox || "uv");
} }
searchEngine(engine?: string) { searchEngine(engine?: string) {
this.#storageManager.setVal('searchEngine', engine || SearchEngines.DuckDuckGo); this.#storageManager.setVal("searchEngine", engine || SearchEngines.DuckDuckGo);
} }
async *#init() { async *#init() {
yield this.theme(this.#storageManager.getVal('theme') || 'default'); yield this.theme(this.#storageManager.getVal("theme") || "default");
} }
constructor() { constructor() {
this.#storageManager = new StoreManager("radius||settings"); this.#storageManager = new StoreManager("radius||settings");
Settings.#instance.add(this); Settings.#instance.add(this);
(async() => { (async () => {
for await (const _ of this.#init()); for await (const _ of this.#init());
})(); })();
} }
} }
export { Settings } export { Settings };

View file

@ -14,4 +14,4 @@ class StoreManager<Prefix extends string> {
} }
} }
export { StoreManager } export { StoreManager };

View file

@ -1,7 +1,7 @@
import type { Props } from "astro"; import type { Props } from "astro";
interface SettingsProps extends Props { interface SettingsProps extends Props {
active: 'appearance' | 'credits' | 'links' | 'proxy'; active: "appearance" | "credits" | "links" | "proxy";
title: string; title: string;
} }
@ -14,7 +14,7 @@ type DropdownOptions = {
const SearchEngines: Record<string, string> = { const SearchEngines: Record<string, string> = {
DuckDuckGo: "https://duckduckgo.com/?q=%s", DuckDuckGo: "https://duckduckgo.com/?q=%s",
Google: "https://google.com/search?q=%s", Google: "https://google.com/search?q=%s",
Bing: "https://bing.com/search?q=%s", Bing: "https://bing.com/search?q=%s"
}; };
export { type SettingsProps, type DropdownOptions, SearchEngines }; export { type SettingsProps, type DropdownOptions, SearchEngines };

View file

@ -1,16 +1,16 @@
{ {
"extends": "astro/tsconfigs/strict", "extends": "astro/tsconfigs/strict",
"include": [".astro/types.d.ts", "**/*"], "include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist", "server"], "exclude": ["dist", "server"],
"compilerOptions": { "compilerOptions": {
"moduleResolution": "bundler", "moduleResolution": "bundler",
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@components/*": ["src/components/*"], "@components/*": ["src/components/*"],
"@layouts/*": ["src/layouts/*"], "@layouts/*": ["src/layouts/*"],
"@utils/*": ["src/utils/*"], "@utils/*": ["src/utils/*"],
"@assets/*": ["src/assets/*"], "@assets/*": ["src/assets/*"],
"@styles/*": ["src/styles/*"] "@styles/*": ["src/styles/*"]
}
} }
}
} }