Uses: npx server to serve nextjs static build

This commit is contained in:
sauravniraula 2025-05-12 22:05:14 +05:45
parent 744a96455f
commit c3f520b789
No known key found for this signature in database
GPG key ID: 60FCC1B5A5E83326
12 changed files with 70 additions and 25 deletions

View file

@ -6,7 +6,7 @@
---
![Demo](resources/readme/demo.gif)
![Demo](readme_assets/demo.gif)
## ✨ More Freedom with AI Presentations
@ -21,25 +21,25 @@
## Features
### 1. Add prompt, select number of slides and language
![Demo](resources/readme/images/prompting.png)
![Demo](readme_assets/images/prompting.png)
### 2. Select theme
![Demo](resources/readme/images/select-theme.png)
![Demo](readme_assets/images/select-theme.png)
### 3. Review and edit outline
![Demo](resources/readme/images/outline.png)
![Demo](readme_assets/images/outline.png)
### 4. Select theme
![Demo](resources/readme/images/select-theme.png)
![Demo](readme_assets/images/select-theme.png)
### 5. Present on app
![Demo](resources/readme/images/present.png)
![Demo](readme_assets/images/present.png)
### 6. Change theme
![Demo](resources/readme/images/change-theme.png)
![Demo](readme_assets/images/change-theme.png)
### 7. Export presentation as PDF and PPTX
![Demo](resources/readme/images/export-presentation.png)
![Demo](readme_assets/images/export-presentation.png)
## License

View file

@ -2,9 +2,9 @@ require("dotenv").config();
import { app, BrowserWindow } from "electron";
import path from "path";
import { findUnusedPorts, killProcess, setupEnv, setUserConfig } from "./utils";
import { startFastApiServer } from "./utils/servers";
import { startFastApiServer, startNextJsServer } from "./utils/servers";
import { ChildProcessByStdio } from "child_process";
import { baseDir, fastapiDir, isDev, tempDir, userConfigPath, userDataDir } from "./utils/constants";
import { baseDir, fastapiDir, isDev, localhost, nextjsDir, tempDir, userConfigPath, userDataDir } from "./utils/constants";
import { setupIpcHandlers } from "./ipc";
var win: BrowserWindow | undefined;
@ -23,7 +23,7 @@ const createWindow = () => {
});
};
async function startServers(fastApiPort: number) {
async function startServers(fastApiPort: number, nextjsPort: number) {
try {
fastApiProcess = await startFastApiServer(
fastapiDir,
@ -40,6 +40,17 @@ async function startServers(fastApiPort: number) {
},
isDev,
);
nextjsProcess = await startNextJsServer(
nextjsDir,
nextjsPort,
{
NEXT_PUBLIC_FAST_API: process.env.NEXT_PUBLIC_FAST_API,
TEMP_DIRECTORY: process.env.TEMP_DIRECTORY,
NEXT_PUBLIC_URL: process.env.NEXT_PUBLIC_URL,
NEXT_PUBLIC_USER_CONFIG_PATH: process.env.NEXT_PUBLIC_USER_CONFIG_PATH,
},
isDev,
)
} catch (error) {
console.error("Server startup error:", error);
}
@ -65,17 +76,15 @@ app.whenReady().then(async () => {
GOOGLE_API_KEY: process.env.GOOGLE_API_KEY,
})
const [fastApiPort] = await findUnusedPorts();
console.log(`FastAPI port: ${fastApiPort}`);
const [fastApiPort, nextjsPort] = await findUnusedPorts();
console.log(`FastAPI port: ${fastApiPort}, NextJS port: ${nextjsPort}`);
//? Setup environment variables to be used in the preload.ts file
//? Setup environment variables to be used in the preloads
setupEnv(fastApiPort);
setupIpcHandlers();
await startServers(fastApiPort);
//? Load the NextJS UI
win?.loadFile(path.join(baseDir, "resources/nextjs/index.html"));
await startServers(fastApiPort, nextjsPort);
win?.loadURL(`${localhost}:${nextjsPort}`);
});
app.on("window-all-closed", async () => {

View file

@ -48,8 +48,9 @@ export function killProcess(pid: number) {
})
}
export async function findUnusedPorts(startPort: number = 40000, count: number = 1): Promise<number[]> {
export async function findUnusedPorts(startPort: number = 40000, count: number = 2): Promise<number[]> {
const ports: number[] = [];
console.log(`Finding ${count} unused ports starting from ${startPort}`);
const isPortAvailable = (port: number): Promise<boolean> => {
return new Promise((resolve) => {

View file

@ -37,4 +37,39 @@ export async function startFastApiServer(
// Wait for FastAPI server to start
await execAsync(`npx wait-on ${localhost}:${port}/docs`);
return fastApiProcess;
}
}
export async function startNextJsServer(
directory: string,
port: number,
env: NextJsEnv,
isDev: boolean,
) {
// Start NextJS development server
const startCommand = isDev ? [
"npm",
["run", "dev", "--", "-p", port.toString()],
] : [
"npx",
["-y", "serve", "-p", port.toString()],
];
const nextjsProcess = spawn(
startCommand[0] as string,
startCommand[1] as string[],
{
cwd: directory,
stdio: ["inherit", "pipe", "pipe"],
env: { ...process.env, ...env },
}
);
nextjsProcess.stdout.on("data", (data: any) => {
console.log(`NextJS: ${data}`);
});
nextjsProcess.stderr.on("data", (data: any) => {
console.error(`NextJS Error: ${data}`);
});
// Wait for NextJS server to start
await execAsync(`npx wait-on ${localhost}:${port}`);
return nextjsProcess;
}

View file

@ -9,14 +9,14 @@
"email": "contact@presenton.ai"
},
"scripts": {
"dev": "tsc && electron --gtk-version=3 .",
"dev": "rm -rf app_dist && tsc && electron --gtk-version=3 .",
"setup:env": "npm install && cd servers/fastapi && poetry install && cd ../../servers/nextjs && npm install",
"build:ts": "tsc",
"build:ts": "rm -rf app_dist && tsc",
"build:css": "tailwindcss -i ./resources/ui/assets/css/tailwind.import.css -o ./resources/ui/assets/css/tailwind.css --watch",
"build:nextjs": "rm -rf resources/nextjs && cd servers/nextjs && npm run build && cp -r out ../../.resources/nextjs",
"build:nextjs": "rm -rf resources/nextjs && cd servers/nextjs && npm run build && mv out ../../resources/nextjs",
"build:fastapi": "rm -rf resources/fastapi && cd servers/fastapi && .venv/bin/pyinstaller --distpath ../../resources server.spec",
"build:electron": "tsc && node build.js",
"clean:build": "rm -rf resources/nextjs && rm -rf resources/fastapi"
"build:electron": "rm -rf app_dist && tsc && node build.js",
"clean:build": "rm -rf resources/nextjs && rm -rf resources/fastapi && rm -rf app_dist"
},
"devDependencies": {
"electron": "^36.1.0",

View file

Before

Width:  |  Height:  |  Size: 5.7 MiB

After

Width:  |  Height:  |  Size: 5.7 MiB

View file

Before

Width:  |  Height:  |  Size: 532 KiB

After

Width:  |  Height:  |  Size: 532 KiB

View file

Before

Width:  |  Height:  |  Size: 583 KiB

After

Width:  |  Height:  |  Size: 583 KiB

View file

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

View file

Before

Width:  |  Height:  |  Size: 514 KiB

After

Width:  |  Height:  |  Size: 514 KiB

View file

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

View file

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB