Files
open-gsio/packages/server/server.ts
geoffsee 497eb22ad8 change semantics
Update README deployment steps and add deploy:secrets script to package.json

update local inference script and README

update lockfile

reconfigure package scripts for development

update test execution

pass server tests

Update README with revised Bun commands and workspace details

remove pnpm package manager designator

create bun server
2025-06-04 18:45:08 -04:00

93 lines
3.6 KiB
TypeScript

// import Server from "./packages/server/index.ts";
import {BunSqliteKVNamespace} from "./storage/BunSqliteKVNamespace";
import {readdir} from 'node:fs/promises';
import type { RequestLike } from "itty-router";
import {config} from "dotenv";
import Server from ".";
import DurableObjectLocal from "./ServerCoordinatorBun";
const router = Server.Router();
config({ path: ['../../.dev.vars'] })
export default {
port: 3003,
fetch: async (request: RequestLike, env: { [key: string]: any; }, ctx: any) =>{
console.log("[trace] request: ", request.method, request.url, "headers: ", request.headers.get("referer"), "body: ", request.body, "env: ", env, "ctx: ", ctx, "")
env["SERVER_COORDINATOR"] = DurableObjectLocal
env["ASSETS"] = assetHandler.ASSETS
env["EVENTSOURCE_HOST"] = process.env.EVENTSOURCE_HOST
env["GROQ_API_KEY"] = process.env.GROQ_API_KEY
env["ANTHROPIC_API_KEY"] = process.env.ANTHROPIC_API_KEY
env["FIREWORKS_API_KEY"] = process.env.FIREWORKS_API_KEY
env["XAI_API_KEY"] = process.env.XAI_API_KEY
env["CEREBRAS_API_KEY"] = process.env.CEREBRAS_API_KEY
env["CLOUDFLARE_API_KEY"] = process.env.CLOUDFLARE_API_KEY
env["CLOUDFLARE_ACCOUNT_ID"] = process.env.CLOUDFLARE_ACCOUNT_ID
env["KV_STORAGE"] = new BunSqliteKVNamespace("open-gsio")
try {
const controller = new AbortController();
const timeout = new Promise((_, reject) =>
setTimeout(() => {
controller.abort();
reject(new Error('Request timeout after 5s'));
}, 5000)
);
return await Promise.race([
router.fetch(request, env, ctx),
timeout
]);
} catch (e) {
console.error("Error handling request:", e);
return new Response("Server Error", { status: 500 });
}
}
}
const assetHandler = {
ASSETS: {
/**
* Fetches the requested static asset from local dist
*
* @param {Request} request - The incoming Fetch API Request object.
* @returns {Promise<Response>} A Promise that resolves with the Response for the requested asset,
* or a 404 Response if the asset is not found or an error occurs.
*/
async fetch(request: Request): Promise<Response> {
// Serialize incoming request URL
const originalUrl = new URL(request.url);
const url = new URL(request.url);
// List all files in the public directory
const PUBLIC_DIR = '../client/public/';
const publicFiles = await readdir(PUBLIC_DIR, {recursive: true});
// Get the filename from pathname and remove any path traversal attempts
const filename = url.pathname.split('/').pop()?.replace(/\.\./g, '') || '';
const isStatic = publicFiles.some(file => file === filename);
if (url.pathname === "/") {
url.pathname = "/index.html";
} else if (isStatic) {
url.pathname = `/static${url.pathname}`;
}
const dist = "../client/dist/client"
try {
return new Response(Bun.file(`${dist}${url.pathname}`));
} catch (error) {
// Log the error with the original requested path
console.error(`Error reading asset from path ${originalUrl.pathname}:`, error);
return new Response('Asset not found on disk', { status: 404 });
}
}
}
}