//@template-ignore import { VerificationError } from "./ts_base"; //@template-ignore import { type RequestObject, type ResponseObject, ErrorCodes, Logging } from "./ts_service_base"; export class Service { public name: string = null as any; public functions = new Set(); constructor() { } } type ISendMessageCB = (data: any, catchedErr?: Error) => void; export class ServiceProvider { services = new Map>(); addService(service: Service) { this.services.set(service.name, service); Logging.log("SERVER: Adding Service to provider:", service.name); Logging.log("SERVER: Service provides:", [...service.functions.keys()]) } getSession(send: ISendMessageCB, ctx?: Partial): Session { return new Session(this, send, ctx); } } class Session { ctx: Partial; constructor( private provider: ServiceProvider, private _send: ISendMessageCB, ctx?: Partial ) { this.ctx = ctx || {}; } send(data: any, catchedErr?: Error) { Logging.log("SERVER: Sending Message", data) this._send(data, catchedErr); } async onMessage(data: RequestObject) { Logging.log("SERVER: Received Message", data); try { if (!data.method) { if (data.id) { this.send({ jsonrpc: "2.0", id: data.id, error: { code: ErrorCodes.InvalidRequest, message: "No method defined!", }, } as ResponseObject); } return; } const [srvName, fncName] = data.method.split("."); Logging.log("SERVER: Message for", srvName, fncName); const service = this.provider.services.get(srvName); if (!service) { Logging.log("SERVER: Did not find Service"); if (data.id) { this.send({ jsonrpc: "2.0", id: data.id, error: { code: ErrorCodes.MethodNotFound, message: "Service not found!", }, } as ResponseObject); } return; } const fnc = service.functions.has(fncName); if (!fnc) { Logging.log("SERVER: Did not find Function"); if (data.id) { this.send({ jsonrpc: "2.0", id: data.id, error: { code: ErrorCodes.MethodNotFound, message: "Function not found!", }, } as ResponseObject); } return; } let result = await (service as any)["_" + fncName](data.params, this.ctx); if (data.id) { //Request this.send({ jsonrpc: "2.0", id: data.id, result: result, } as ResponseObject); } //else Notification and response is ignored } catch (err) { if (data.id) { this.send( { jsonrpc: "2.0", id: data.id, error: { code: ErrorCodes.InternalError, message: err.message, data: err instanceof VerificationError ? { $: "verification_error", type: err.type, field: err.field, value: err.value } : { $: "unknown_error" }, }, } as ResponseObject, err ); } //TODO: Think about else case } } }