import ServiceMessage, { deserialize_ServiceMessage, serialize_ServiceMessage} from "./servicemessage"; import { IStream, IStreamCallback, Stream } from "./service_base"; export type { IStream, IStreamCallback }; export { Stream }; interface IServiceFunction { istream: boolean; input: (data: Uint8Array) => any; rstream: boolean; ret: (data: any) => Uint8Array; } export type IMessageCallback = (packet: Uint8Array) => void; export class Service { public name: string = null as any; protected functions = new Map(); protected calls = new Map void>(); constructor(private provider: ServiceProvider, name: string) { this.name = name; this.provider.services.set(name, this); } onMessage(msg: ServiceMessage) { const msgid = msg.id; const call = this.calls.get(msgid); if (call) { call(msg); } } protected sendMessage(msg: ServiceMessage) { this.provider.sendMessage(msg); } } export class ServiceProvider { services = new Map(); constructor(private sendPacket: IMessageCallback) {} onPacket(msg: Uint8Array) { const decoded = deserialize_ServiceMessage(msg); const serv = this.services.get(decoded.service); if (serv) { serv.onMessage(decoded); } } sendMessage(msg: ServiceMessage) { this.sendPacket(serialize_ServiceMessage(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)); };