import type { InfinityContext } from "@infinity-beyond/infinity.ts";
import { randomUUID } from "node:crypto";
import { RequestAnalytics } from "@infinity-beyond/modules/analytics/request_analytics.ts";
import { ResponseAnalytics } from "@infinity-beyond/modules/analytics/response_analytics.ts";
import { Entity } from "@infinity-beyond/classes/entity.ts";
import State from "@infinity-beyond/modules/state.ts";
import { CustomEventEmitter } from "@infinity-beyond/classes/custom_event_emitter.ts";
import InfinityHeaders from "@infinity-beyond/modules/networking/infinity_headers.ts";
export class Infinity extends CustomEventEmitter<InfinityEvents> {
readonly app_name: string
constructor(app_name: string) {
super();
this.app_name = app_name;
}
async Middleware(request: Request, ctx: InfinityContext) {
ctx.state.request_id = randomUUID();
ctx.state.request_start_date = new Date();
this.emit('request', request, ctx);
await RequestAnalytics.Process(request, ctx);
const response = await ctx.next();
await ResponseAnalytics.Process(response, ctx)
this.emit('response', response, ctx);
// InfinityHeaders.apply(response.headers, {
// 'x-request-id': ctx.state.request_id,
// 'x-time-taken': (new Date().getTime() - ctx.state.request_start_date.getTime()).toString(),
// }, InfinityHeaders.Default);
// response.headers.delete('x-fresh-uuid');
return response;
}
handshake(request: Request, _ctx: InfinityContext) {
const signature = request.headers.get('sec-websocket-protocol')?.replace(/^SIGNATURE, (.+$)$/, '$1');
if(!signature || signature !== State.SIGNATURE) {
return new Response('Invalid signature', { status: 403 });
}
const { socket, response } = Deno.upgradeWebSocket(request);
const query: Record<string, string> = new URL(request.url).search
?.replace(/^\?/, '')
.split('&')
.reduce((p, query) => {
const [key, value] = query.split('=');
p[key] = value;
return p;
}, {} as Record<string, string>) ?? {};
const { uuid } = query;
if(!uuid) {
socket.close(1, 'No provided uuid');
return new Response('', { status: 403 });
}
socket.onopen = () => {
Entity.__AddWorker(uuid, socket);
}
return response;
}
}
type InfinityEvents = {
request: [request: Request, ctx: InfinityContext],
response: [response: Response, ctx: InfinityContext],
}