//@template-ignore import { VerificationError } from "./ts_base"; //@template-ignore import { type RequestObject, type ResponseObject, ErrorCodes, Logging } from "./ts_service_base"; export type IMessageCallback = (data: any) => void; export type ResponseListener = { ok: (response:any)=>void; err: (error: Error)=>void; } export class Service { public _name: string = null as any; constructor(protected _provider: ServiceProvider, name: string) { this._name = name; this._provider.services.set(name, this); } } export class ServiceProvider { services = new Map(); requests = new Map(); constructor(private sendPacket: IMessageCallback) {} onPacket(msg: RequestObject | ResponseObject) { Logging.log("CLIENT: Received message:", msg); if("method" in msg) { if(msg.id){ Logging.log("CLIENT: Determined type is Request"); // Request, which are not supported by client, so ignore return; } else { Logging.log("CLIENT: Determined type is Notification"); //Notification. Send to Notification handler const [srvName, fncName] = msg.method.split("."); let service = this.services.get(srvName) if(!service) { Logging.log("CLIENT: Did not find Service wanted by Notification!", srvName); } else { //TODO: Implement Event thingy (or so :)) } } } else { Logging.log("CLIENT: Determined type is Response"); // Response let resListener = this.requests.get(msg.id); if(!resListener) return; // Ignore wrong responses if(msg.error) { if(msg.error.data && msg.error.data.$ == "verification_error") { resListener.err(new VerificationError(msg.error.data.type, msg.error.data.field, msg.error.data.value)) } else { resListener.err(new Error(msg.error.message)); } } else { resListener.ok(msg.result); } } } sendMessage(msg: RequestObject, res?: ResponseListener) { Logging.log("CLIENT: Sending Messgage", msg); if(msg.id) { this.requests.set(msg.id, res); } this.sendPacket(msg) } } declare var require: any; export const getRandomBytes = ( typeof self !== "undefined" && (self.crypto || (self as any).msCrypto) ? function () { // Browsers var crypto = self.crypto || (self as any).msCrypto; var QUOTA = 65536; return function (n: number) { var a = new Uint8Array(n); for (var i = 0; i < n; i += QUOTA) { crypto.getRandomValues( a.subarray(i, i + Math.min(n - i, QUOTA)) ); } return a; }; } : function () { // Node return require("crypto").randomBytes; } )() as (cnt: number) => Uint8Array; export const getRandomID = (length: number) => { return btoa(String.fromCharCode.apply(null, getRandomBytes(length) as any)); };