Skip to content

Commit

Permalink
chore: regular push (this is torture someone please help)
Browse files Browse the repository at this point in the history
  • Loading branch information
IncognitoTGT committed Sep 21, 2024
1 parent 5759d85 commit 0fa8b8d
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 69 deletions.
73 changes: 38 additions & 35 deletions server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,49 +14,52 @@ const dev = process.env.NODE_ENV !== "production";
if (process.argv.includes("--turbo")) {
process.env.TURBOPACK = "1";
}
const server = createServer();
consola.start(
`✨ Stardust: Starting ${dev ? "development" : "production"} server ${process.env.TURBOPACK ? "With turbopack" : ""}...`,
);
const httpServer = createServer();
const app = next({
dev,
port,
httpServer: server,
httpServer,
hostname: process.env.HOSTNAME,
});
consola.start(`✨ Stardust: Starting ${dev ? "development" : "production"} server...`);
await app.prepare();
const nextRequest = app.getRequestHandler();
const nextUpgrade = app.getUpgradeHandler();
server.on("request", nextRequest);
server.on("upgrade", async (req, socket, head) => {
if (req.url?.startsWith("/websockify") && req.url?.split("/")[2]) {
const cookie = `${req.headers.cookie?.includes("__Secure") ? "__Secure-" : ""}authjs.session-token`;
const token = await getToken({
req: {
headers: req.headers as Record<string, string>,
},
secret: config.auth.secret,
secureCookie: req.headers.cookie?.includes("__Secure"),
salt: cookie,
cookieName: cookie,
});
const [dbSession] = await db
.select()
.from(session)
.where(and(eq(session.userId, token?.id as string), eq(session.id, req.url.split("/")[2])));
if (dbSession) {
const ip = (await docker.getContainer(dbSession.id).inspect()).NetworkSettings.Networks[config.docker.network]
.IPAddress;
const proxy = createProxyMiddleware({
target: `ws://${ip}:5901`,
ws: true,
httpServer
.on("request", nextRequest)
.on("upgrade", async (req, socket, head) => {
if (req.url?.startsWith("/websockify") && req.url?.split("/")[2]) {
const cookie = `${req.headers.cookie?.includes("__Secure") ? "__Secure-" : ""}authjs.session-token`;
const token = await getToken({
req: {
headers: req.headers as Record<string, string>,
},
secret: config.auth.secret,
secureCookie: req.headers.cookie?.includes("__Secure"),
salt: cookie,
cookieName: cookie,
});
proxy.upgrade(req, socket as Socket, head);
const [dbSession] = await db
.select()
.from(session)
.where(and(eq(session.userId, token?.id as string), eq(session.id, req.url.split("/")[2])));
if (dbSession) {
const ip = (await docker.getContainer(dbSession.id).inspect()).NetworkSettings.Networks[config.docker.network]
.IPAddress;
const proxy = createProxyMiddleware({
target: `ws://${ip}:5901`,
ws: true,
});
proxy.upgrade(req, socket as Socket, head);
} else {
socket.end();
}
} else {
socket.end();
nextUpgrade(req, socket, head);
}
} else {
nextUpgrade(req, socket, head);
}
});
server.listen(port, () => {
consola.success(`✨ Stardust: Server listening on ${port}`);
});
})
.listen(port, () => {
consola.success(`✨ Stardust: Server listening on ${port}`);
});
5 changes: 4 additions & 1 deletion src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@
}

body {
@apply bg-background text-foreground;
@apply bg-background text-foreground font-sans;
}
pre, code {
@apply font-mono;
}
}
18 changes: 7 additions & 11 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,21 @@ import { ThemeProvider } from "next-themes";
import { Inter, JetBrains_Mono } from "next/font/google";
import { headers } from "next/headers";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
const inter = Inter({ subsets: ["latin"], variable: "--sans" });
const jetbrains = JetBrains_Mono({ subsets: ["latin"], variable: "--mono" });
const shouldDisplayMetadata = () => {
export function generateMetadata(): Metadata {
const config = getConfig();
return (
const disp = Boolean(
config.metadataUrl &&
(headers().get("x-forwarded-host") ?? headers().get("host"))?.includes(new URL(config.metadataUrl).host)
(headers().get("x-forwarded-host") ?? headers().get("host"))?.includes(new URL(config.metadataUrl).host),
);
};
export function generateMetadata(): Metadata {
return {
title: {
default: "Stardust",
template: "%s | Stardust",
},
description: shouldDisplayMetadata()
? "Stardust is the platform for streaming isolated desktop containers."
: undefined,
openGraph: shouldDisplayMetadata()
description: disp ? "Stardust is the platform for streaming isolated desktop containers." : undefined,
openGraph: disp
? {
title: "Stardust",
description: "Stardust is the platform for streaming isolated desktop containers.",
Expand All @@ -41,7 +37,7 @@ export default function RootLayout({
}>) {
return (
<html lang="en" suppressHydrationWarning>
<body className={`${inter.className} ${jetbrains.variable}`}>
<body className={`${inter.variable} ${jetbrains.variable}`}>
<ThemeProvider
attribute="class"
defaultTheme={getConfig().auth.huDb ? "nord" : "system"}
Expand Down
4 changes: 2 additions & 2 deletions src/app/view/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export default function View({ params }: { params: { slug: string } }) {
useEffect(() => {
const interval = setInterval(() => {
if (connected && document.hasFocus()) fetch(`/api/session/${params.slug}/keepalive`, { method: "POST" });
}, 10000);
}, 60000);
return () => clearInterval(interval);
}, [connected, params.slug]);
useEffect(() => {
Expand Down Expand Up @@ -486,7 +486,7 @@ export default function View({ params }: { params: { slug: string } }) {
},
]}
loader={<Loading text="Connecting" />}
className="absolute z-20 h-screen w-screen overflow-clip"
className="absolute h-screen w-screen overflow-clip"
/>
) : (
<Alert className="w-auto">
Expand Down
41 changes: 34 additions & 7 deletions src/components/xpra/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"use client";
import { cn } from "@/lib/utils";
import { useEffect, useImperativeHandle, useRef, useState } from "react";
import { XpraClient, XpraWindowManager } from "xpra-html5-client";
import type { XpraClientEventEmitters, XpraConnectionOptions } from "xpra-html5-client";
Expand All @@ -10,14 +11,21 @@ export interface Props {
ref?: React.Ref<XpraHandle>;
events?: Partial<XpraClientEventEmitters>;
connectionOptions: [string, Partial<XpraConnectionOptions>];
size?: [number, number];
loader?: React.ReactNode;
className?: string;
}
export default function XpraScreen({ events, connectionOptions, ref, loader, className }: Props) {
export default function XpraScreen({ events, connectionOptions, ref, loader, className, ...props }: Props) {
const xpraRef = useRef<XpraClient | null>(null);
const windowManagerRef = useRef<XpraWindowManager | null>(null);
const divRef = useRef<HTMLDivElement | null>(null);
const [inited, setInited] = useState(false);
const [size, setSize] = useState<[number, number]>(props.size || [window.innerWidth, window.innerHeight]);
useEffect(() => {
const handler = () => setSize([window.innerWidth, window.innerHeight]);
window.addEventListener("resize", handler);
return () => window.removeEventListener("resize", handler);
}, []);
useEffect(() => {
try {
const worker = new Worker(new URL("./workers/main.ts", import.meta.url));
Expand All @@ -28,31 +36,50 @@ export default function XpraScreen({ events, connectionOptions, ref, loader, cla
setInited(true);
})();
if (inited) {
windowManagerRef.current = new XpraWindowManager(xpraRef.current);
windowManagerRef.current?.init();
windowManagerRef.current.setDesktopElement(divRef.current);
if (events) {
for (const [event, fn] of Object.entries(events)) {
xpraRef.current.on(event as keyof XpraClientEventEmitters, fn);
}
}
xpraRef.current.connect(...connectionOptions);

windowManagerRef.current = new XpraWindowManager(xpraRef.current);
windowManagerRef.current?.init();
windowManagerRef.current.setDesktopElement(divRef.current);
windowManagerRef.current.createWindow({
id: 0,
position: [0, 0],
dimension: size,
metadata: {
"window-type": ["NORMAL"],
"class-instance": [],
title: "Desktop",
},
clientProperties: {},
overrideRedirect: false,
});
const win = windowManagerRef.current.getWindow(0);
if (win?.canvas) {
divRef.current?.appendChild(win.canvas);
windowManagerRef.current.maximize(win, [0, 0], size);
windowManagerRef.current.setActiveWindow(0);
}
}
} catch (e) {
xpraRef.current?.emit("error", e as string);
}
return () => {
if (!inited) return;
divRef.current?.querySelector("canvas")?.remove();
if (events) {
for (const [event, fn] of Object.entries(events)) {
xpraRef.current?.off(event as keyof XpraClientEventEmitters, fn);
}
}
xpraRef.current?.disconnect();
xpraRef.current = null;
// windowManagerRef.current = null;
};
}, [events, connectionOptions, inited]);
}, [events, connectionOptions, inited, size]);
useImperativeHandle(ref, () => ({
wm: windowManagerRef.current,
client: xpraRef.current,
Expand All @@ -61,7 +88,7 @@ export default function XpraScreen({ events, connectionOptions, ref, loader, cla
<>
{!inited ? loader || "Loading..." : null}
<div
className={className}
className={cn("[&_canvas]:z-20", className)}
ref={divRef}
onContextMenu={(e) => e.preventDefault()}
onMouseUp={(e) => windowManagerRef.current?.mouseButton(null, e.nativeEvent, false)}
Expand Down
18 changes: 5 additions & 13 deletions src/lib/drizzle/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,14 @@ import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import { getConfig } from "../config";
import * as schema from "./schema";

const drizzleSingleton = () => drizzle(client, { schema });
// biome-ignore lint: this hack is for HMR to stop creating more instances
const client = postgres(getConfig().databaseUrl);
// biome-ignore lint: shadowing is intentional
declare const globalThis: {
db: ReturnType<typeof drizzleSingleton>;
} & typeof global;
const drizzleSingleton = () => drizzle(client, { schema });

const client = postgres(getConfig().databaseUrl);
let db: ReturnType<typeof drizzleSingleton>;
if (process.env.NODE_ENV === "production") {
db = drizzleSingleton();
} else {
if (!globalThis.db) {
globalThis.db = drizzleSingleton();
}
db = globalThis.db;
}
const db = globalThis.db ?? drizzleSingleton();
export { db, client };
if (process.env.NODE_ENV !== "production") globalThis.db = db;
export * from "./schema";
1 change: 1 addition & 0 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const config = {
},
fontFamily: {
mono: ["var(--mono)"],
sans: ["var(--sans)"],
},
},
},
Expand Down

0 comments on commit 0fa8b8d

Please sign in to comment.