stuff
This commit is contained in:
parent
396b81929a
commit
20d49560e9
125
index.mjs
125
index.mjs
|
@ -17,7 +17,6 @@ import wisp from "wisp-server-node";
|
|||
|
||||
const surgeConfigPath = path.resolve("surge.config.json");
|
||||
const isSurgedRun = process.argv.includes("--surged");
|
||||
let startTime = Date.now();
|
||||
|
||||
function applySurgeAndRestartIfNeeded() {
|
||||
if (isSurgedRun) {
|
||||
|
@ -48,20 +47,13 @@ applySurgeAndRestartIfNeeded();
|
|||
if (global.gc) {
|
||||
setInterval(() => {
|
||||
const { heapUsed, heapTotal } = process.memoryUsage();
|
||||
if (heapTotal > 0 && heapUsed / heapTotal > 0.7) global.gc();
|
||||
}, 60000);
|
||||
if (heapTotal > 0 && heapUsed / heapTotal > 0.8) global.gc();
|
||||
}, 120000);
|
||||
}
|
||||
|
||||
import "./others/scaler.mjs";
|
||||
import "./others/warmup.mjs";
|
||||
|
||||
const cache = new LRUCache({
|
||||
maxSize: 1000,
|
||||
ttl: 60_000,
|
||||
allowStale: false,
|
||||
sizeCalculation: (value, key) => Buffer.byteLength(value) + Buffer.byteLength(key)
|
||||
});
|
||||
|
||||
const port = parseInt(process.env.PORT || "3000", 10);
|
||||
|
||||
function logInfo(msg) {
|
||||
|
@ -80,9 +72,7 @@ process.on("uncaughtException", err => logError(`Unhandled Exception: ${err}`));
|
|||
process.on("unhandledRejection", reason => logError(`Unhandled Rejection: ${reason}`));
|
||||
|
||||
if (cluster.isPrimary) {
|
||||
const cpus = os.cpus().length;
|
||||
const workers = Math.max(1, cpus - 1);
|
||||
|
||||
const workers = Math.max(1, os.cpus().length - 1);
|
||||
logInfo(`Master: forking ${workers} workers`);
|
||||
|
||||
for (let i = 0; i < workers; i++) {
|
||||
|
@ -108,18 +98,26 @@ if (cluster.isPrimary) {
|
|||
const __dirname = process.cwd();
|
||||
const publicPath = path.join(__dirname, "public");
|
||||
const app = express();
|
||||
let latencySamples = [];
|
||||
|
||||
const cache = new LRUCache({
|
||||
max: 500,
|
||||
ttl: 60_000,
|
||||
allowStale: false
|
||||
});
|
||||
|
||||
const latencySamples = new Array(200);
|
||||
|
||||
app.use(compression({ level: 4, memLevel: 4, threshold: 1024 }));
|
||||
|
||||
app.use((req, res, next) => {
|
||||
if (req.path.startsWith("/api/")) return next();
|
||||
const key = req.originalUrl;
|
||||
const val = cache.get(key);
|
||||
if (val) {
|
||||
res.setHeader("X-Cache", "HIT");
|
||||
return res.send(val);
|
||||
}
|
||||
res.sendResponse = res.send.bind(res);
|
||||
res.sendResponse = res.send;
|
||||
res.send = body => {
|
||||
cache.set(key, body);
|
||||
res.setHeader("X-Cache", "MISS");
|
||||
|
@ -128,13 +126,12 @@ if (cluster.isPrimary) {
|
|||
next();
|
||||
});
|
||||
|
||||
const staticOpts = { maxAge: "7d", immutable: true };
|
||||
const staticOpts = { maxAge: "7d", immutable: true, etag: false };
|
||||
app.use("/baremux/", express.static(baremuxPath, staticOpts));
|
||||
app.use("/epoxy/", express.static(epoxyPath, staticOpts));
|
||||
app.use("/libcurl/", express.static(libcurlPath, staticOpts));
|
||||
app.use(express.static(publicPath, staticOpts));
|
||||
app.use("/wah/", express.static(uvPath, staticOpts));
|
||||
app.use(express.json());
|
||||
|
||||
const sendHtml = file => (_req, res) => res.sendFile(path.join(publicPath, file));
|
||||
|
||||
|
@ -144,75 +141,40 @@ if (cluster.isPrimary) {
|
|||
app.get("/resent", (_req, res) => res.sendFile(path.join(publicPath, "resent", "index.html")));
|
||||
|
||||
app.get("/api/info", (_req, res) => {
|
||||
try {
|
||||
const average = latencySamples.length
|
||||
? latencySamples.reduce((a, b) => a + b, 0) / latencySamples.length
|
||||
: 0;
|
||||
let speed = "Medium";
|
||||
if (average < 200) speed = "Fast";
|
||||
else if (average > 500) speed = "Slow";
|
||||
const cpus = os.cpus();
|
||||
const totalMem = os.totalmem() / 1024 / 1024 / 1024;
|
||||
res.json({
|
||||
speed,
|
||||
averageLatency: average.toFixed(2),
|
||||
specs: `${cpus[0].model} + ${cpus.length} CPU Cores + ${totalMem.toFixed(1)}GB of RAM`,
|
||||
startTime,
|
||||
samples: latencySamples.length,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
} catch {
|
||||
res.status(500).json({ error: "Internal error" });
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/api/latest-commit", async (_req, res) => {
|
||||
try {
|
||||
const ghRes = await fetch(
|
||||
"https://api.github.com/repos/xojw/waves/commits?per_page=1",
|
||||
{
|
||||
headers: {
|
||||
"User-Agent": "waves-app",
|
||||
Accept: "application/vnd.github.v3+json"
|
||||
}
|
||||
}
|
||||
);
|
||||
if (!ghRes.ok) return res.status(ghRes.status).json({ error: "GitHub API error" });
|
||||
|
||||
const commits = await ghRes.json();
|
||||
const updates = commits.map(c => ({
|
||||
sha: c.sha.slice(0, 7),
|
||||
message: c.commit.message.split("\n")[0],
|
||||
author: c.commit.author.name,
|
||||
date: c.commit.author.date
|
||||
}));
|
||||
|
||||
res.json({ repo: "xojw/waves", updates });
|
||||
} catch {
|
||||
res.status(500).json({ error: "Internal server error" });
|
||||
}
|
||||
const validSamples = latencySamples.filter(s => s !== undefined);
|
||||
const average = validSamples.length ? validSamples.reduce((a, b) => a + b, 0) / validSamples.length : 0;
|
||||
res.json({
|
||||
speed: average < 200 ? "Fast" : average > 500 ? "Slow" : "Medium",
|
||||
averageLatency: average.toFixed(2),
|
||||
timestamp: Date.now()
|
||||
});
|
||||
});
|
||||
|
||||
app.use((_req, res) => res.status(404).sendFile(path.join(publicPath, "404.html")));
|
||||
|
||||
const server = createServer(app);
|
||||
server.keepAliveTimeout = 0;
|
||||
server.headersTimeout = 0;
|
||||
server.keepAliveTimeout = 5000;
|
||||
server.headersTimeout = 10000;
|
||||
|
||||
const pingWSS = new WebSocket.Server({
|
||||
noServer: true,
|
||||
maxPayload: 4 * 1024 * 1024,
|
||||
maxPayload: 16384,
|
||||
perMessageDeflate: false
|
||||
});
|
||||
|
||||
pingWSS.on("connection", (ws, req) => {
|
||||
const remote = req.socket.remoteAddress || "unknown";
|
||||
let lat = [];
|
||||
const interval = setInterval(() => {
|
||||
const lat = [];
|
||||
let sampleIndex = 0;
|
||||
|
||||
const sendPing = () => {
|
||||
if (ws.readyState === WebSocket.OPEN) {
|
||||
ws.send(JSON.stringify({ type: "ping", timestamp: Date.now() }));
|
||||
}
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
const pingInterval = setInterval(sendPing, 500);
|
||||
sendPing();
|
||||
|
||||
ws.on("message", msg => {
|
||||
try {
|
||||
|
@ -220,21 +182,19 @@ if (cluster.isPrimary) {
|
|||
if (data.type === "pong" && data.timestamp) {
|
||||
const d = Date.now() - data.timestamp;
|
||||
lat.push(d);
|
||||
if (lat.length > 5) lat.shift();
|
||||
latencySamples.push(d);
|
||||
if (latencySamples.length > 100) latencySamples.shift();
|
||||
ws.send(JSON.stringify({ type: "latency", latency: d }));
|
||||
if (lat.length > 10) lat.shift();
|
||||
|
||||
latencySamples[sampleIndex % latencySamples.length] = d;
|
||||
sampleIndex = (sampleIndex + 1) % latencySamples.length;
|
||||
|
||||
ws.send(JSON.stringify({ type: "latency", latency: d }), { compress: false });
|
||||
}
|
||||
} catch (e) {
|
||||
logError(`Ping error: ${e}`);
|
||||
}
|
||||
} catch {}
|
||||
});
|
||||
|
||||
ws.on("close", () => {
|
||||
clearInterval(interval);
|
||||
const avg = lat.length
|
||||
? (lat.reduce((a, b) => a + b) / lat.length).toFixed(2)
|
||||
: 0;
|
||||
clearInterval(pingInterval);
|
||||
const avg = lat.length ? (lat.reduce((a, b) => a + b) / lat.length).toFixed(2) : 0;
|
||||
logInfo(`WS ${remote} closed. Avg: ${avg}ms`);
|
||||
});
|
||||
});
|
||||
|
@ -247,12 +207,11 @@ if (cluster.isPrimary) {
|
|||
} else if (req.url.startsWith("/w/")) {
|
||||
wisp.routeRequest(req, sock, head);
|
||||
} else {
|
||||
sock.end();
|
||||
sock.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
server.on("error", err => logError(`Worker error: ${err}`));
|
||||
|
||||
server.listen(0, () => logSuccess(`Worker ${process.pid} ready`));
|
||||
|
||||
process.on("message", (msg, conn) => {
|
||||
|
|
|
@ -114,10 +114,10 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="pingDisplay"><i class="fa-regular fa-wifi"></i> Ping: Connecting...</div>
|
||||
<div id="pingDisplay"><i class="fas fa-satellite-dish"></i> Ping: Connecting...</div>
|
||||
<div id="greeting"></div>
|
||||
<iframe id="cool-iframe" class="iframe"></iframe>
|
||||
<div id="lastest-commit">Loading latest commit</div>
|
||||
<div id="hi">Hii,</div>
|
||||
|
||||
<div id="copyright">
|
||||
<i class="fa-regular fa-copyright"></i> 2025
|
||||
|
|
|
@ -55,7 +55,7 @@ body {
|
|||
color: #ffffff;
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
margin: 1px 80px 0 10px;
|
||||
margin: 1px 75px 0 10px;
|
||||
white-space: nowrap;
|
||||
cursor: default;
|
||||
transition: all 0.3s ease;
|
||||
|
@ -88,7 +88,7 @@ body {
|
|||
.home-navbar .favicon {
|
||||
width: 28px;
|
||||
height: 24px;
|
||||
margin-right: -10px;
|
||||
margin-right: -9px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
@ -114,8 +114,8 @@ body {
|
|||
|
||||
.home-navbar i {
|
||||
color: #ffffff;
|
||||
margin-right: -15px;
|
||||
margin-left: 115px;
|
||||
margin-right: -19px;
|
||||
margin-left: 119px;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
|
@ -590,14 +590,14 @@ body {
|
|||
animation: fadeOut 0.3s ease-in-out forwards;
|
||||
}
|
||||
|
||||
#lastest-commit {
|
||||
#hi {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
z-index: 9999;
|
||||
background-color: #08080894;
|
||||
border: 1px solid #ffffff21;
|
||||
color: #cfcfcf;
|
||||
color: #aaaaaa;
|
||||
font-weight: 540;
|
||||
transition: all 0.3s ease;
|
||||
cursor: default;
|
||||
|
@ -606,6 +606,10 @@ body {
|
|||
font-size: 14px;
|
||||
}
|
||||
|
||||
#hi:hover {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
#copyright {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
|
|
|
@ -141,6 +141,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
updateDecodedSearchInput();
|
||||
}
|
||||
|
||||
function generateSubject() {
|
||||
const subjects = ['math', 'science', 'history', 'art', 'programming', 'philosophy'];
|
||||
const randomSubject = subjects[Math.floor(Math.random() * subjects.length)];
|
||||
try {
|
||||
history.replaceState({}, '', `/learning?subject=${randomSubject}`);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function setupIframeNavigationListeners() {
|
||||
try {
|
||||
const iframeWindow = iframe.contentWindow;
|
||||
|
@ -209,6 +217,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
}
|
||||
}
|
||||
setupIframeNavigationListeners();
|
||||
generateSubject();
|
||||
if (navbarToggle && navbarToggle.checked && navBar) {
|
||||
navBar.style.display = 'block';
|
||||
}
|
||||
|
@ -467,19 +476,3 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
window.APP.decodeUrl = decodeUrl;
|
||||
window.APP.normalizeUrl = normalizeUrl;
|
||||
});
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const res = await fetch('/api/latest-commit');
|
||||
const {
|
||||
updates
|
||||
} = await res.json();
|
||||
const u = updates[0];
|
||||
const commitUrl = `https://github.com/xojw/waves/commit/${u.sha}`;
|
||||
document.getElementById('lastest-commit').innerHTML =
|
||||
`<a href="${commitUrl}" class="hover-link" target="_blank" rel="noopener noreferrer"><i class="fa-solid fa-code-commit"></i> ${u.sha}</a>`;
|
||||
} catch {
|
||||
document.getElementById('lastest-commit').textContent =
|
||||
'Failed to load lastest commit';
|
||||
}
|
||||
})();
|
|
@ -1,6 +1,7 @@
|
|||
window.onload = function() {
|
||||
const storedName = localStorage.getItem('userName');
|
||||
const path = window.location.pathname;
|
||||
|
||||
if (!storedName) {
|
||||
document.getElementById('overlay').style.display = 'block';
|
||||
document.getElementById('namePrompt').style.display = 'block';
|
||||
|
@ -12,20 +13,27 @@ window.onload = function() {
|
|||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const welcomeMsg = getWelcomeMessage(storedName);
|
||||
const iconType = getIconType(path);
|
||||
const iconType = getIconType(path);
|
||||
showToast(welcomeMsg, 'success', iconType);
|
||||
|
||||
const greetingElement = document.getElementById('greeting');
|
||||
if (greetingElement) {
|
||||
updateGreeting(storedName);
|
||||
}
|
||||
|
||||
updateHi(storedName);
|
||||
};
|
||||
|
||||
function submitName() {
|
||||
const name = document.getElementById('userName').value.trim();
|
||||
if (!name) return;
|
||||
|
||||
localStorage.setItem('userName', name);
|
||||
updateGreeting(name);
|
||||
updateHi(name);
|
||||
|
||||
document.getElementById('namePrompt').classList.add('fade-out');
|
||||
showToast(`Hey, ${name}! Welcome to Waves!`, 'success', 'wave');
|
||||
setTimeout(() => {
|
||||
|
@ -52,8 +60,7 @@ function getIconType(path) {
|
|||
}
|
||||
|
||||
const generalGreetings = [
|
||||
{ text: 'Welcome aboard', icon: '<i class="fa-regular fa-rocket"></i>', suffix: '!' },
|
||||
{ text: 'Hii', icon: '<i class="fa-regular fa-hand-wave"></i>', suffix: '!!' },
|
||||
{ text: 'Have fun', icon: '<i class="fa-regular fa-party-horn"></i>', suffix: '!' },
|
||||
{ text: 'Hope you enjoy Waves', icon: '<i class="fa-solid fa-heart"></i>', suffix: ' <3' },
|
||||
{ text: 'Consider joining our Discord (discord.gg/ire)', icon: '<i class="fa-solid fa-smile"></i>', suffix: '!' },
|
||||
{ text: 'How you doing today', icon: '<i class="fa-regular fa-question"></i>', suffix: '?' }
|
||||
|
@ -67,21 +74,18 @@ timeGreetings.push(
|
|||
{ text: 'Enjoy your morning', icon: '<i class="fa-regular fa-mug-hot"></i>', suffix: '!' },
|
||||
{ text: 'Your day starts here', icon: '<i class="fa-regular fa-star"></i>', suffix: '!' }
|
||||
);
|
||||
|
||||
timeGreetings.push(
|
||||
{ text: 'Good afternoon', icon: '<i class="fa-regular fa-leaf"></i>', suffix: '!' },
|
||||
{ text: 'Hope your day is going well', icon: '<i class="fa-regular fa-coffee"></i>', suffix: '.' },
|
||||
{ text: 'Keep up the pace', icon: '<i class="fa-regular fa-book"></i>', suffix: '!' },
|
||||
{ text: 'Stay on track today', icon: '<i class="fa-regular fa-sun"></i>', suffix: '.' }
|
||||
);
|
||||
|
||||
timeGreetings.push(
|
||||
{ text: 'Good evening', icon: '<i class="fa-regular fa-cloud-moon"></i>', suffix: '!' },
|
||||
{ text: 'Time to unwind', icon: '<i class="fa-regular fa-fire"></i>', suffix: '.' },
|
||||
{ text: 'Evening’s here—relax', icon: '<i class="fa-regular fa-star"></i>', suffix: '.' },
|
||||
{ text: 'Breathe and recharge', icon: '<i class="fa-regular fa-moon"></i>', suffix: '…' }
|
||||
);
|
||||
|
||||
timeGreetings.push(
|
||||
{ text: 'Good night', icon: '<i class="fa-regular fa-bed"></i>', suffix: '!' },
|
||||
{ text: 'Rest well', icon: '<i class="fa-regular fa-blanket"></i>', suffix: '.' },
|
||||
|
@ -93,6 +97,7 @@ function getGreeting() {
|
|||
const now = new Date();
|
||||
const hour = now.getHours();
|
||||
let pool = [];
|
||||
|
||||
if (hour >= 5 && hour < 12) {
|
||||
pool = timeGreetings.slice(0, 4);
|
||||
} else if (hour < 17) {
|
||||
|
@ -102,41 +107,50 @@ function getGreeting() {
|
|||
} else {
|
||||
pool = timeGreetings.slice(12, 16);
|
||||
}
|
||||
|
||||
if (Math.random() < 0.5) {
|
||||
pool = generalGreetings;
|
||||
}
|
||||
const choice = pool[Math.floor(Math.random() * pool.length)];
|
||||
return { text: choice.text, icon: choice.icon, suffix: choice.suffix };
|
||||
|
||||
return pool[Math.floor(Math.random() * pool.length)];
|
||||
}
|
||||
|
||||
function updateGreeting(name) {
|
||||
const { text, icon, suffix } = getGreeting();
|
||||
const el = document.getElementById('greeting');
|
||||
if (!el) return;
|
||||
if (text === 'Hope you enjoy Waves') {
|
||||
el.innerHTML = `${icon} ${text}, ${name}${suffix}`;
|
||||
} else {
|
||||
el.innerHTML = `${icon} ${text}, ${name}${suffix}`;
|
||||
}
|
||||
|
||||
el.innerHTML = `${icon} ${text}, ${name}${suffix}`;
|
||||
el.style.opacity = 1;
|
||||
}
|
||||
|
||||
function updateHi(name) {
|
||||
const hiEl = document.getElementById('hi');
|
||||
if (hiEl) {
|
||||
hiEl.textContent = `Hii, ${name}!!`;
|
||||
}
|
||||
}
|
||||
|
||||
function showToast(message, type = 'success', iconType = 'wave') {
|
||||
const toast = document.createElement('div');
|
||||
toast.className = `toast show ${type}`;
|
||||
|
||||
const icons = {
|
||||
success: '<i class="fas fa-check-circle" style="margin-right: 8px;"></i>',
|
||||
error: '<i class="fas fa-times-circle" style="margin-right: 8px;"></i>',
|
||||
info: '<i class="fas fa-info-circle" style="margin-right: 8px;"></i>',
|
||||
error: '<i class="fas fa-times-circle" style="margin-right: 8px;"></i>',
|
||||
info: '<i class="fas fa-info-circle" style="margin-right: 8px;"></i>',
|
||||
warning: '<i class="fas fa-exclamation-triangle" style="margin-right: 8px;"></i>',
|
||||
wave: '<i class="fa-regular fa-hand-wave" style="margin-right: 8px;"></i>',
|
||||
game: '<i class="fa-regular fa-gamepad" style="margin-right: 8px;"></i>',
|
||||
apps: '<i class="fa-regular fa-th" style="margin-right: 8px;"></i>'
|
||||
wave: '<i class="fa-regular fa-hand-wave" style="margin-right: 8px;"></i>',
|
||||
game: '<i class="fa-regular fa-gamepad" style="margin-right: 8px;"></i>',
|
||||
apps: '<i class="fa-regular fa-th" style="margin-right: 8px;"></i>'
|
||||
};
|
||||
|
||||
toast.innerHTML = `${icons[iconType] || icons.wave}${message}`;
|
||||
|
||||
const progressBar = document.createElement('div');
|
||||
progressBar.className = 'progress-bar';
|
||||
toast.appendChild(progressBar);
|
||||
|
||||
const closeBtn = document.createElement('button');
|
||||
closeBtn.className = 'toast-close';
|
||||
closeBtn.innerHTML = '<i class="fas fa-xmark" style="margin-left: 8px; font-size: 0.8em;"></i>';
|
||||
|
@ -145,7 +159,9 @@ function showToast(message, type = 'success', iconType = 'wave') {
|
|||
setTimeout(() => toast.remove(), 500);
|
||||
});
|
||||
toast.appendChild(closeBtn);
|
||||
|
||||
document.body.appendChild(toast);
|
||||
|
||||
setTimeout(() => {
|
||||
toast.classList.add('hide');
|
||||
setTimeout(() => toast.remove(), 500);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
ws = new WebSocket(wsUrl);
|
||||
|
||||
ws.onopen = function() {
|
||||
pingDisplay.innerHTML = '<i class="fas fa-wifi"></i> Ping: Waiting...';
|
||||
pingDisplay.innerHTML = '<i class="fas fa-satellite-dish"></i> Ping: Waiting...';
|
||||
};
|
||||
|
||||
ws.onmessage = function(event) {
|
||||
|
@ -23,7 +23,7 @@
|
|||
}));
|
||||
}
|
||||
if (data.type === "latency" && typeof data.latency === "number") {
|
||||
pingDisplay.innerHTML = '<i class="fa-solid fa-wifi"></i> Ping: ' + '~' + data.latency + 'ms';
|
||||
pingDisplay.innerHTML = '<i class="fas fa-satellite-dish"></i> ' + 'Ping: ' + '~' + data.latency + 'ms';
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Error parsing message:", err);
|
||||
|
@ -31,11 +31,11 @@
|
|||
};
|
||||
|
||||
ws.onerror = function() {
|
||||
pingDisplay.innerHTML = '<i class="fa-regular fa-wifi"></i> Ping: Error';
|
||||
pingDisplay.innerHTML = '<i class="fas fa-satellite-dish"></i> Ping: Error';
|
||||
};
|
||||
|
||||
ws.onclose = function() {
|
||||
pingDisplay.innerHTML = '<i class="fa-regular fa-wifi"></i> Ping: Disconnected';
|
||||
pingDisplay.innerHTML = '<i class="fas fa-satellite-dish"></i> Ping: Disconnected';
|
||||
setTimeout(createWebSocket, 1000);
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user