import { Headers, Request, RequestInitObject, DatagramInitObject, Datagram, Response, ResponseInit, Message, MessageInit, MessageInitObject, ResponseInitObject } from "./datagram-types.js" export function isResponse(d: DatagramInitObject): d is Response { let hasReqno = typeof ((d as any).reqno) !== "undefined"; let hasStatus = typeof ((d as any).status) !== "undefined"; return hasStatus || (hasReqno && !isRequest(d)); } export function isRequest(d: DatagramInitObject): d is Request { // let hasMethod = typeof ((d as any).method) !== "undefined"; // let hasPath = typeof ((d as any).path) !== "undefined"; // return hasPath || hasMethod; return (d as any).request == true; } export abstract class CDatagram implements Datagram { public from: string; public to: string; public port: string; public headers: Headers; public body: any; public trail: string[] = [] static fromInit(init: DatagramInitObject) { if (isResponse(init)) { return new CResponse(init); } if (isRequest(init)) { return new CRequest(init); } return new CMessage(init); } constructor(init: DatagramInitObject) { this.from = init.from ?? ""; this.to = init.to ?? ""; this.port = init.port ?? "default"; this.headers = init.headers ?? {} this.body = init.body; } text(): Promise { return Promise.resolve("todo"); } arrayBuffer(): Promise { return Promise.resolve(new ArrayBuffer(0)); } json(): Promise { return Promise.resolve({}); } blob(): Promise { return Promise.resolve(new Blob()); } formData(): Promise { return Promise.resolve(new FormData()); } } export function isAsyncIterable(obj: any): obj is AsyncIterable { return typeof (obj) == "object" && obj !== null && Symbol.asyncIterator in obj; } export class CResponse extends CDatagram implements Response { public status: number; reqno: number; final: boolean; bias: string | null; static initToInitObj(init: ResponseInit): ResponseInitObject { let obj: ResponseInitObject; if (typeof (init) == "string") { obj = { body: init }; } else if (isAsyncIterable(init)) { obj = { body: init }; } else { obj = init as ResponseInitObject; } return obj; } static initObjToResponse(init: ResponseInitObject): Response { let ret: Response = { from: init.from ?? "", to: init.to ?? "", port: init.port ?? "default", headers: init.headers ?? {}, body: init.body, reqno: init.reqno ?? -1, status: init.status ?? 200, final: (init.final == true) ?? !isAsyncIterable(init.body), trail: [] } return ret; } constructor(init: ResponseInitObject, req?: Request) { super(init); if (req) { this.from = req.to; this.to = req.from; this.reqno = req.reqno ?? -1; } else { this.reqno = init.reqno ?? -1; } this.bias = init.bias ?? null; this.status = init.status ?? 200; this.final = (init.final == true) ?? !isAsyncIterable(init.body); } } export class CMessage extends CDatagram implements Message { path: string; method: string; constructor(message: MessageInitObject) { super(message); this.path = message.path ?? "" this.method = message.method ?? "GET" } asInit(): MessageInit { let init: any = {}; if (this.method !== "GET") { init.method = this.method; } init.body = this.body; if (this.from !== "anonymous") { init.from = this.from; } init.to = this.to; init.path = this.path; return init; } } export class CRequest extends CMessage implements Request { request: true = true; reqno: number; url: string | undefined; constructor(init: RequestInitObject) { super(init); this.url = init.url; this.reqno = init.reqno ?? -1; } } export function DatagramShort(datagram: Datagram, big: boolean = false) { let json = JSON.stringify(datagram.body) ?? ""; let body: string = (big ? json : json.substring(0, 20) as any).replaceAll('"', "`"); if (isRequest(datagram)) { let to = datagram.to == "external" ? "external:" + datagram.url ?? "" : datagram.to; return `request ${datagram.reqno} from ${datagram.from} to ${to} '${datagram.method} ${datagram.path}' '${body}'`; } else if (isResponse(datagram)) { return `response${datagram.final ? "" : " nonfinal"} ${datagram.reqno} from ${datagram.from} to ${datagram.to} '${datagram.status} ${body}'`; } return `message from ${datagram.from} to ${datagram.to} '${(datagram as Message).path} ${body}'`; }