This commit is contained in:
parent
ad23ab1907
commit
a65ee6fe67
15 changed files with 564 additions and 466 deletions
44
biome.json
Normal file
44
biome.json
Normal file
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
||||
"vcs": {
|
||||
"enabled": true,
|
||||
"clientKind": "git",
|
||||
"useIgnoreFile": false
|
||||
},
|
||||
"files": {
|
||||
"ignoreUnknown": true,
|
||||
"ignore": []
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentStyle": "tab",
|
||||
"lineEnding": "lf"
|
||||
},
|
||||
"organizeImports": {
|
||||
"enabled": true
|
||||
},
|
||||
"css": {
|
||||
"formatter": {
|
||||
"indentStyle": "tab",
|
||||
"lineEnding": "lf"
|
||||
}
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true,
|
||||
"correctness": {
|
||||
"noUnusedImports": "error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"quoteStyle": "double",
|
||||
"indentStyle": "tab",
|
||||
"lineEnding": "lf",
|
||||
"jsxQuoteStyle": "double",
|
||||
"semicolons": "always"
|
||||
}
|
||||
}
|
||||
}
|
2
bun.lock
2
bun.lock
|
@ -9,7 +9,7 @@
|
|||
"tsx-dom": "latest",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@biomejs/biome": "^1.9.4",
|
||||
"@types/bun": "latest",
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
60
index.ts
60
index.ts
|
@ -1,19 +1,20 @@
|
|||
import { build, serve, gzipSync, file, gc } from "bun";
|
||||
import { file, gc, serve } from "bun";
|
||||
|
||||
import Backend from "./src/back"
|
||||
import Backend from "./src/back";
|
||||
|
||||
import pkg from "./package.json";
|
||||
|
||||
|
||||
let heartrate = 0;
|
||||
let lanyard = {};
|
||||
|
||||
require("node:fs/promises").rm("./dist", { recursive: true, force: true }).catch(() => {
|
||||
require("node:fs/promises")
|
||||
.rm("./dist", { recursive: true, force: true })
|
||||
.catch(() => {
|
||||
// ignore
|
||||
});
|
||||
|
||||
if (!Backend.development) {
|
||||
await Backend.build()
|
||||
await Backend.build();
|
||||
}
|
||||
|
||||
const server = serve({
|
||||
|
@ -22,7 +23,7 @@ const server = serve({
|
|||
await Backend.postAnalytics(req, server);
|
||||
|
||||
if (Backend.development) {
|
||||
await Backend.build()
|
||||
await Backend.build();
|
||||
}
|
||||
|
||||
return await Backend.Responses.file(file("./dist/index.html"));
|
||||
|
@ -37,18 +38,18 @@ const server = serve({
|
|||
},
|
||||
|
||||
"/api/server": () => {
|
||||
const string = JSON.stringify(process)
|
||||
const data = JSON.parse(string)
|
||||
const string = JSON.stringify(process);
|
||||
const data = JSON.parse(string);
|
||||
|
||||
// clear possibly data that could be sensitive
|
||||
data.env = {}
|
||||
data.env = {};
|
||||
|
||||
data.availableMemory = process.availableMemory()
|
||||
data.constrainedMemory = process.constrainedMemory()
|
||||
data.cpuUsage = process.cpuUsage()
|
||||
data.memoryUsage = process.memoryUsage()
|
||||
data.uptime = process.uptime()
|
||||
data.package = pkg
|
||||
data.availableMemory = process.availableMemory();
|
||||
data.constrainedMemory = process.constrainedMemory();
|
||||
data.cpuUsage = process.cpuUsage();
|
||||
data.memoryUsage = process.memoryUsage();
|
||||
data.uptime = process.uptime();
|
||||
data.package = pkg;
|
||||
|
||||
return Backend.Responses.json({ data });
|
||||
},
|
||||
|
@ -64,13 +65,13 @@ const server = serve({
|
|||
return Response.redirect("/");
|
||||
},
|
||||
"/api/gc": async () => {
|
||||
gc(true)
|
||||
gc(true);
|
||||
|
||||
return Backend.Responses.ok();
|
||||
},
|
||||
"/api/headers": async (req) => {
|
||||
return Backend.Responses.json({ ...req.headers.toJSON() });
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
fetch: async (request, server) => {
|
||||
|
@ -86,22 +87,33 @@ const server = serve({
|
|||
ws.send(JSON.stringify({ type: "lanyard", data: lanyard }), true);
|
||||
|
||||
ws.subscribe("hyperate");
|
||||
ws.send(JSON.stringify({ type: "hyperate", data: { hr: heartrate } }), true);
|
||||
ws.send(
|
||||
JSON.stringify({ type: "hyperate", data: { hr: heartrate } }),
|
||||
true,
|
||||
);
|
||||
},
|
||||
message: async (ws, message) => {
|
||||
ws.send(JSON.stringify({ type: "echo", data: message }), true)
|
||||
}
|
||||
ws.send(JSON.stringify({ type: "echo", data: message }), true);
|
||||
},
|
||||
},
|
||||
development: Backend.development,
|
||||
port: 2056
|
||||
port: 2056,
|
||||
});
|
||||
|
||||
new Backend.Sockets.Hyperate((data) => {
|
||||
heartrate = data;
|
||||
server.publish("hyperate", JSON.stringify({ type: "hyperate", data: { hr: heartrate } }), true);
|
||||
})
|
||||
server.publish(
|
||||
"hyperate",
|
||||
JSON.stringify({ type: "hyperate", data: { hr: heartrate } }),
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
new Backend.Sockets.Lanyard((data) => {
|
||||
lanyard = data;
|
||||
server.publish("lanyard", JSON.stringify({ type: "lanyard", data: lanyard }), true);
|
||||
server.publish(
|
||||
"lanyard",
|
||||
JSON.stringify({ type: "lanyard", data: lanyard }),
|
||||
true,
|
||||
);
|
||||
});
|
|
@ -3,10 +3,12 @@
|
|||
"module": "index.ts",
|
||||
"scripts": {
|
||||
"dev": "NODE_ENV=development bun run --hot . --watch",
|
||||
"start": "bun run ."
|
||||
"start": "bun run .",
|
||||
"lint": "bunx biome ci . --verbose",
|
||||
"lint:fix": "bunx biome check --fix"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@biomejs/biome": "^1.9.4",
|
||||
"@types/bun": "latest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import ReconnectingWebSocket from 'reconnecting-websocket';
|
||||
import ReconnectingWebSocket from "reconnecting-websocket";
|
||||
|
||||
export default class {
|
||||
private _socket: ReconnectingWebSocket;
|
||||
|
@ -7,7 +7,9 @@ export default class {
|
|||
private _callback: (data: number) => void;
|
||||
|
||||
constructor(callback: (data: number) => void) {
|
||||
this._socket = new ReconnectingWebSocket("wss://app.hyperate.io/socket/websocket?token=wv39nM6iyrNJulvpmMQrimYPIXy2dVrYRjkuHpbRapKT2VSh65ngDGHdCdCtmEN9")
|
||||
this._socket = new ReconnectingWebSocket(
|
||||
"wss://app.hyperate.io/socket/websocket?token=wv39nM6iyrNJulvpmMQrimYPIXy2dVrYRjkuHpbRapKT2VSh65ngDGHdCdCtmEN9",
|
||||
);
|
||||
this._keepAlive = null;
|
||||
this._interval = null;
|
||||
this._callback = callback;
|
||||
|
@ -15,7 +17,7 @@ export default class {
|
|||
this._socket.binaryType = "arraybuffer";
|
||||
|
||||
this._socket.onopen = () => {
|
||||
console.log("Hyperate socket opened")
|
||||
console.log("Hyperate socket opened");
|
||||
|
||||
this._socket.send(
|
||||
JSON.stringify({
|
||||
|
@ -36,7 +38,7 @@ export default class {
|
|||
}),
|
||||
);
|
||||
}, 10000);
|
||||
}
|
||||
};
|
||||
|
||||
this._socket.onmessage = ({ data }: MessageEvent) => {
|
||||
data = JSON.parse(data);
|
||||
|
@ -48,7 +50,7 @@ export default class {
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this._socket.onerror = () => {
|
||||
console.error("Hyperate socket error");
|
||||
|
@ -60,7 +62,7 @@ export default class {
|
|||
clearInterval(this._interval);
|
||||
this._interval = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this._socket.onclose = () => {
|
||||
console.log("Hyperate socket closed");
|
||||
|
@ -72,8 +74,7 @@ export default class {
|
|||
clearInterval(this._interval);
|
||||
this._interval = null;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private heartbeat() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import ReconnectingWebSocket from 'reconnecting-websocket';
|
||||
import ReconnectingWebSocket from "reconnecting-websocket";
|
||||
|
||||
export default class {
|
||||
private _socket: ReconnectingWebSocket;
|
||||
|
@ -6,40 +6,46 @@ export default class {
|
|||
private _callback: (data: { [key: string]: string }) => void;
|
||||
|
||||
constructor(callback: (data: { [key: string]: string }) => void) {
|
||||
this._socket = new ReconnectingWebSocket("wss://lanyard.creations.works/socket")
|
||||
this._socket = new ReconnectingWebSocket(
|
||||
"wss://lanyard.creations.works/socket",
|
||||
);
|
||||
this._keepAlive = null;
|
||||
this._callback = callback;
|
||||
|
||||
this._socket.binaryType = "arraybuffer";
|
||||
|
||||
this._socket.onopen = () => {
|
||||
console.log("Lanyard socket opened")
|
||||
}
|
||||
console.log("Lanyard socket opened");
|
||||
};
|
||||
|
||||
this._socket.onmessage = ({ data }: MessageEvent) => {
|
||||
data = JSON.parse(data);
|
||||
|
||||
switch (data.op) {
|
||||
case 0: {
|
||||
this._callback(data.d)
|
||||
this._callback(data.d);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
this._socket.send(JSON.stringify({
|
||||
this._socket.send(
|
||||
JSON.stringify({
|
||||
op: 2,
|
||||
d: {
|
||||
subscribe_to_id: "1273447359417942128"
|
||||
}
|
||||
}))
|
||||
subscribe_to_id: "1273447359417942128",
|
||||
},
|
||||
}),
|
||||
);
|
||||
this._keepAlive = setInterval(() => {
|
||||
this._socket.send(JSON.stringify({
|
||||
op: 3
|
||||
}))
|
||||
}, data.d.heartbeat_interval)
|
||||
this._socket.send(
|
||||
JSON.stringify({
|
||||
op: 3,
|
||||
}),
|
||||
);
|
||||
}, data.d.heartbeat_interval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this._socket.onerror = () => {
|
||||
console.error("Lanyard socket error");
|
||||
|
@ -47,7 +53,7 @@ export default class {
|
|||
clearInterval(this._keepAlive);
|
||||
this._keepAlive = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this._socket.onclose = () => {
|
||||
console.log("Lanyard socket closed");
|
||||
|
@ -55,7 +61,6 @@ export default class {
|
|||
clearInterval(this._keepAlive);
|
||||
this._keepAlive = null;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
|
@ -5,23 +5,26 @@ const development = process.env.NODE_ENV === "development";
|
|||
|
||||
const build = async () => {
|
||||
return await Bun.build({
|
||||
entrypoints: ['./src/front/index.html'],
|
||||
outdir: './dist',
|
||||
entrypoints: ["./src/front/index.html"],
|
||||
outdir: "./dist",
|
||||
minify: !development,
|
||||
sourcemap: (development ? "inline" : "none"),
|
||||
sourcemap: development ? "inline" : "none",
|
||||
splitting: true,
|
||||
publicPath: "/assets/",
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const respOptions = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Cache-Control": "no-cache",
|
||||
"Content-Encoding": "gzip",
|
||||
}
|
||||
}
|
||||
const okResp = new Response(Bun.gzipSync(JSON.stringify({ data: "ok" })), respOptions)
|
||||
},
|
||||
};
|
||||
const okResp = new Response(
|
||||
Bun.gzipSync(JSON.stringify({ data: "ok" })),
|
||||
respOptions,
|
||||
);
|
||||
const Responses = {
|
||||
ok: () => {
|
||||
return okResp.clone();
|
||||
|
@ -35,12 +38,15 @@ const Responses = {
|
|||
"Content-Type": file.type,
|
||||
"Cache-Control": "public, max-age=31536000",
|
||||
"Content-Encoding": "gzip",
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const postAnalytics = async (req: Request | Bun.BunRequest, server: Bun.Server) => {
|
||||
const postAnalytics = async (
|
||||
req: Request | Bun.BunRequest,
|
||||
server: Bun.Server,
|
||||
) => {
|
||||
return await fetch("https://plausible.creations.works/api/event", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
|
@ -50,7 +56,9 @@ const postAnalytics = async (req: Request | Bun.BunRequest, server: Bun.Server)
|
|||
req.headers.get("CF-Connecting-IP") ||
|
||||
req.headers.get("X-Real-IP") ||
|
||||
req.headers.get("X-Forwarded-For")?.split(",")[0] ||
|
||||
(typeof server.requestIP(req) === "string" ? server.requestIP(req) : (server.requestIP(req)?.address || ""))
|
||||
(typeof server.requestIP(req) === "string"
|
||||
? server.requestIP(req)
|
||||
: server.requestIP(req)?.address || ""),
|
||||
),
|
||||
},
|
||||
body: JSON.stringify({
|
||||
|
@ -58,14 +66,14 @@ const postAnalytics = async (req: Request | Bun.BunRequest, server: Bun.Server)
|
|||
name: "pageview",
|
||||
url: req.url,
|
||||
referrer: req.headers.get("referer") || "",
|
||||
})
|
||||
})
|
||||
}
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
Sockets: {
|
||||
Hyperate,
|
||||
Lanyard
|
||||
Lanyard,
|
||||
},
|
||||
Responses,
|
||||
build,
|
||||
|
|
|
@ -25,9 +25,11 @@
|
|||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 2147483648;
|
||||
background: linear-gradient(to bottom,
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent 50%,
|
||||
rgba(0, 0, 0, 0.3) 51%);
|
||||
rgba(0, 0, 0, 0.3) 51%
|
||||
);
|
||||
background-size: 100% 6px;
|
||||
animation: scanlines 2s steps(30) infinite;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,27 @@
|
|||
import Lanyard from './components/Lanyard';
|
||||
import Hyperate from './components/Hyperate';
|
||||
import Hyperate from "./components/Hyperate";
|
||||
import Lanyard from "./components/Lanyard";
|
||||
|
||||
export default () => {
|
||||
return <div class="app">
|
||||
return (
|
||||
<div class="app">
|
||||
<p>seth> cat ./about.txt</p>
|
||||
<p>A Dedicated Backend Developer,<br />with a passion for high-fidelity audio,<br />gaming, and web development.</p>
|
||||
<p>
|
||||
A Dedicated Backend Developer,
|
||||
<br />
|
||||
with a passion for high-fidelity audio,
|
||||
<br />
|
||||
gaming, and web development.
|
||||
</p>
|
||||
|
||||
<p>seth> curl /tmp/discord-ipc</p>
|
||||
<p><Lanyard /></p>
|
||||
<p>
|
||||
<Lanyard />
|
||||
</p>
|
||||
|
||||
<p>seth> cat /tmp/heartrate</p>
|
||||
<p><Hyperate /></p>
|
||||
<p>
|
||||
<Hyperate />
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
@ -40,10 +40,10 @@ class Socket extends EventTarget {
|
|||
}
|
||||
|
||||
emitLanyard(lanyard: object) {
|
||||
this.dispatchEvent(new CustomEvent('lanyard', { detail: lanyard }));
|
||||
this.dispatchEvent(new CustomEvent("lanyard", { detail: lanyard }));
|
||||
}
|
||||
emitHyperate(heartRate: number) {
|
||||
this.dispatchEvent(new CustomEvent('hyperate', { detail: heartRate }));
|
||||
this.dispatchEvent(new CustomEvent("hyperate", { detail: heartRate }));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,13 +5,15 @@ import socket from "../../Socket";
|
|||
export default () => {
|
||||
const paragraph = createRef<HTMLParagraphElement>();
|
||||
|
||||
socket.addEventListener('hyperate', (event: Event) => {
|
||||
socket.addEventListener("hyperate", (event: Event) => {
|
||||
const heartRate = (event as CustomEvent).detail;
|
||||
if (paragraph.current) {
|
||||
paragraph.current.innerText = `${heartRate} BPM`;
|
||||
}
|
||||
});
|
||||
return <div>
|
||||
return (
|
||||
<div>
|
||||
<p ref={paragraph}>0 BPM</p>
|
||||
</div>;
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { createRef } from "tsx-dom";
|
||||
import { highlightAll } from "@speed-highlight/core";
|
||||
import { createRef } from "tsx-dom";
|
||||
|
||||
import socket from "../../Socket";
|
||||
|
||||
|
@ -8,14 +8,14 @@ const statusTypes: { [key: string]: string } = {
|
|||
idle: "rgb(150, 150, 0)",
|
||||
dnd: "rgb(150, 0, 0)",
|
||||
offline: "rgb(150, 150, 150)",
|
||||
}
|
||||
};
|
||||
|
||||
const gradientTypes: { [key: string]: string } = {
|
||||
online: "rgba(0, 150, 0, 0.1)",
|
||||
idle: "rgba(150, 150, 0, 0.1)",
|
||||
dnd: "rgba(150, 0, 0, 0.1)",
|
||||
offline: "rgba(150, 150, 150, 0.1)",
|
||||
}
|
||||
};
|
||||
const activityTypes: { [key: number]: string } = {
|
||||
0: "Playing",
|
||||
1: "Streaming",
|
||||
|
@ -23,37 +23,46 @@ const activityTypes: { [key: number]: string } = {
|
|||
3: "Watching",
|
||||
4: "Custom Status",
|
||||
5: "Competing in",
|
||||
}
|
||||
};
|
||||
|
||||
const stringify = (data: { [key: string]: string }) => {
|
||||
return JSON.stringify(data, null, 2)
|
||||
}
|
||||
return JSON.stringify(data, null, 2);
|
||||
};
|
||||
|
||||
export default () => {
|
||||
const code = createRef<HTMLDivElement>();
|
||||
|
||||
socket.addEventListener('lanyard', (event: Event) => {
|
||||
socket.addEventListener("lanyard", (event: Event) => {
|
||||
const lanyard = (event as CustomEvent).detail;
|
||||
document.body.style = `--status-color: ${statusTypes[lanyard.discord_status]}; --gradient-color: ${gradientTypes[lanyard.discord_status]};`;
|
||||
if (code.current) {
|
||||
code.current.innerHTML = stringify({
|
||||
status: lanyard.discord_status,
|
||||
activities: lanyard.activities.map((act: {
|
||||
type: number, name: string, details: string, state: string
|
||||
activities: lanyard.activities.map(
|
||||
(act: {
|
||||
type: number;
|
||||
name: string;
|
||||
details: string;
|
||||
state: string;
|
||||
}) => {
|
||||
return [
|
||||
...new Set([
|
||||
activityTypes[act.type],
|
||||
act.name,
|
||||
act.details,
|
||||
act.state
|
||||
])
|
||||
].filter(n => n)
|
||||
}),
|
||||
act.state,
|
||||
]),
|
||||
].filter((n) => n);
|
||||
},
|
||||
),
|
||||
});
|
||||
}
|
||||
highlightAll();
|
||||
});
|
||||
|
||||
return <div class="shj-lang-json" ref={code}>{"{}"}</div>
|
||||
}
|
||||
return (
|
||||
<div class="shj-lang-json" ref={code}>
|
||||
{"{}"}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -13,8 +13,12 @@ body {
|
|||
}
|
||||
|
||||
body {
|
||||
color: #DEDEDE;
|
||||
text-shadow: 0 0 5px #C8C8C8;
|
||||
background: radial-gradient(at bottom right, var(--gradient-color, rgba(150, 150, 150, 0.1)) 0%, rgba(0, 0, 0, 1) 100%);
|
||||
color: #dedede;
|
||||
text-shadow: 0 0 5px #c8c8c8;
|
||||
background: radial-gradient(
|
||||
at bottom right,
|
||||
var(--gradient-color, rgba(150, 150, 150, 0.1)) 0%,
|
||||
rgba(0, 0, 0, 1) 100%
|
||||
);
|
||||
display: flex;
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import "tsx-dom";
|
||||
|
||||
import App from './App';
|
||||
import App from "./App";
|
||||
|
||||
document.body.appendChild(<App />);
|
||||
|
||||
// You're garbage, let me collect you.
|
||||
fetch("/api/gc")
|
||||
fetch("/api/gc");
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
// Environment setup & latest features
|
||||
"lib": [
|
||||
"ESNext",
|
||||
"DOM",
|
||||
],
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
|
|
Loading…
Add table
Reference in a new issue