From 29597daba1e63e85512a7174feb4e7b7e80561fc Mon Sep 17 00:00:00 2001 From: Phil Kunz Date: Mon, 9 Sep 2019 23:58:32 +0200 Subject: [PATCH] fix(core): update --- package-lock.json | 5 +++ package.json | 1 + test/test.expressserver.ts | 2 +- test/test.ts | 28 +++++++++++-- ts/smartsocket.classes.smartsocket.ts | 20 ++++----- ts/smartsocket.classes.smartsocketclient.ts | 12 +++--- ts/smartsocket.classes.socketconnection.ts | 6 +-- ts/smartsocket.classes.socketfunction.ts | 46 +++++++++++---------- ts/smartsocket.classes.socketrequest.ts | 32 +++++++------- ts/smartsocket.classes.socketrole.ts | 4 +- ts/smartsocket.plugins.ts | 20 +++++++-- 11 files changed, 109 insertions(+), 67 deletions(-) diff --git a/package-lock.json b/package-lock.json index 12db9a6..147c5cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,11 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@apiglobal/typedrequest-interfaces": { + "version": "1.0.7", + "resolved": "https://verdaccio.lossless.one/@apiglobal%2ftypedrequest-interfaces/-/typedrequest-interfaces-1.0.7.tgz", + "integrity": "sha512-yPl0UcLFMwSQL7bK52wVjkgvadC+x2YS3+7T15V1A1dXNxa96yd4WX1fqcKqwnBrvYexq/8FaxWGi98tZ0oNwg==" + }, "@babel/code-frame": { "version": "7.5.5", "resolved": "https://verdaccio.lossless.one/@babel%2fcode-frame/-/code-frame-7.5.5.tgz", diff --git a/package.json b/package.json index 1d4e000..fd8aae0 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ }, "homepage": "https://gitlab.com/pushrocks/smartsocket#README", "dependencies": { + "@apiglobal/typedrequest-interfaces": "^1.0.7", "@pushrocks/lik": "^3.0.11", "@pushrocks/smartdelay": "^2.0.3", "@pushrocks/smartexpress": "^3.0.40", diff --git a/test/test.expressserver.ts b/test/test.expressserver.ts index 4e11948..e032e89 100644 --- a/test/test.expressserver.ts +++ b/test/test.expressserver.ts @@ -11,7 +11,7 @@ import smartsocket = require('../ts/index'); let testSmartsocket: smartsocket.Smartsocket; let testSmartsocketClient: smartsocket.SmartsocketClient; let testSocketRole1: smartsocket.SocketRole; -let testSocketFunction1: smartsocket.SocketFunction; +let testSocketFunction1: smartsocket.SocketFunction; let myseServer: smartexpress.Server; const testConfig = { diff --git a/test/test.ts b/test/test.ts index 8d67ba9..c3b840f 100644 --- a/test/test.ts +++ b/test/test.ts @@ -11,8 +11,28 @@ let testSmartsocket: smartsocket.Smartsocket; let testSmartsocketClient: smartsocket.SmartsocketClient; let testSocketConnection: smartsocket.SocketConnection; let testSocketRole1: smartsocket.SocketRole; -let testSocketFunctionForServer: smartsocket.SocketFunction; -let testSocketFunctionClient: smartsocket.SocketFunction; +let testSocketFunctionForServer: smartsocket.SocketFunction; +let testSocketFunctionClient: smartsocket.SocketFunction; + +export interface IReqResClient { + method: 'testFunction1'; + request: { + value1: string; + }; + response: { + value1: string; + } +} + +export interface IReqResServer { + method: 'testFunction2'; + request: { + hi: string; + }; + response: { + hi: string + } +} const testConfig = { port: 3000 @@ -78,7 +98,7 @@ tap.test('2 clients should connect in parallel', async () => { }); tap.test('should be able to make a functionCall from client to server', async () => { - const response = await testSmartsocketClient.serverCall('testFunction1', { + const response = await testSmartsocketClient.serverCall('testFunction1', { value1: 'hello' }); console.log(response); @@ -86,7 +106,7 @@ tap.test('should be able to make a functionCall from client to server', async () }); tap.test('should be able to make a functionCall from server to client', async () => { - const response = await testSmartsocket.clientCall( + const response = await testSmartsocket.clientCall( 'testFunction2', { hi: 'hi there from server' diff --git a/ts/smartsocket.classes.smartsocket.ts b/ts/smartsocket.classes.smartsocket.ts index 5b299aa..7da229f 100644 --- a/ts/smartsocket.classes.smartsocket.ts +++ b/ts/smartsocket.classes.smartsocket.ts @@ -3,7 +3,7 @@ import * as plugins from './smartsocket.plugins'; // classes import { Objectmap } from '@pushrocks/lik'; import { SocketConnection } from './smartsocket.classes.socketconnection'; -import { ISocketFunctionCall, SocketFunction } from './smartsocket.classes.socketfunction'; +import { ISocketFunctionCallDataRequest, SocketFunction, ISocketFunctionCallDataResponse } from './smartsocket.classes.socketfunction'; import { SocketRequest } from './smartsocket.classes.socketrequest'; import { SocketRole } from './smartsocket.classes.socketrole'; import { SocketServer } from './smartsocket.classes.socketserver'; @@ -20,8 +20,8 @@ export class Smartsocket { public io: SocketIO.Server; public socketConnections = new Objectmap(); public socketRoles = new Objectmap(); - public socketFunctions = new Objectmap(); - public socketRequests = new Objectmap(); + public socketFunctions = new Objectmap>(); + public socketRequests = new Objectmap>(); private socketServer = new SocketServer(this); @@ -69,12 +69,12 @@ export class Smartsocket { /** * allows call to specific client. */ - public async clientCall( - functionNameArg: string, - dataArg: any, + public async clientCall( + functionNameArg: T['method'], + dataArg: T['request'], targetSocketConnectionArg: SocketConnection - ) { - const socketRequest = new SocketRequest(this, { + ): Promise { + const socketRequest = new SocketRequest(this, { funcCallData: { funcDataArg: dataArg, funcName: functionNameArg @@ -83,7 +83,7 @@ export class Smartsocket { shortId: plugins.shortid.generate(), side: 'requesting' }); - const response: ISocketFunctionCall = await socketRequest.dispatch(); + const response: ISocketFunctionCallDataResponse = await socketRequest.dispatch(); const result = response.funcDataArg; return result; } @@ -98,7 +98,7 @@ export class Smartsocket { return; } - public addSocketFunction(socketFunction: SocketFunction) { + public addSocketFunction(socketFunction: SocketFunction) { this.socketFunctions.add(socketFunction); } diff --git a/ts/smartsocket.classes.smartsocketclient.ts b/ts/smartsocket.classes.smartsocketclient.ts index 945785a..e08bd13 100644 --- a/ts/smartsocket.classes.smartsocketclient.ts +++ b/ts/smartsocket.classes.smartsocketclient.ts @@ -1,7 +1,7 @@ import * as plugins from './smartsocket.plugins'; import { SocketConnection } from './smartsocket.classes.socketconnection'; -import { ISocketFunctionCall, SocketFunction } from './smartsocket.classes.socketfunction'; +import { ISocketFunctionCallDataRequest, SocketFunction } from './smartsocket.classes.socketfunction'; import { ISocketRequestDataObject, SocketRequest } from './smartsocket.classes.socketrequest'; import { SocketRole } from './smartsocket.classes.socketrole'; @@ -23,8 +23,8 @@ export class SmartsocketClient { public serverUrl: string; public serverPort: number; - public socketFunctions = new plugins.lik.Objectmap(); - public socketRequests = new plugins.lik.Objectmap(); + public socketFunctions = new plugins.lik.Objectmap>(); + public socketRequests = new plugins.lik.Objectmap>(); public socketRoles = new plugins.lik.Objectmap(); constructor(optionsArg: ISmartsocketClientOptions) { @@ -37,7 +37,7 @@ export class SmartsocketClient { }); } - public addSocketFunction(socketFunction: SocketFunction) { + public addSocketFunction(socketFunction: SocketFunction) { this.socketFunctions.add(socketFunction); this.socketRole.allowedFunctions.add(socketFunction); } @@ -88,9 +88,9 @@ export class SmartsocketClient { * @param functionNameArg * @param dataArg */ - public async serverCall(functionNameArg: string, dataArg: any): Promise { + public async serverCall(functionNameArg: T['method'], dataArg: T['request']): Promise { const done = plugins.smartpromise.defer(); - const socketRequest = new SocketRequest(this, { + const socketRequest = new SocketRequest(this, { side: 'requesting', originSocketConnection: this.socketConnection, shortId: plugins.shortid.generate(), diff --git a/ts/smartsocket.classes.socketconnection.ts b/ts/smartsocket.classes.socketconnection.ts index 7f28716..739ae44 100644 --- a/ts/smartsocket.classes.socketconnection.ts +++ b/ts/smartsocket.classes.socketconnection.ts @@ -115,10 +115,10 @@ export class SocketConnection { public listenToFunctionRequests() { const done = plugins.smartpromise.defer(); if (this.authenticated) { - this.socket.on('function', (dataArg: ISocketRequestDataObject) => { + this.socket.on('function', (dataArg: ISocketRequestDataObject) => { // check if requested function is available to the socket's scope plugins.smartlog.defaultLogger.log('info', 'function request received'); - const referencedFunction: SocketFunction = this.role.allowedFunctions.find( + const referencedFunction: SocketFunction = this.role.allowedFunctions.find( socketFunctionArg => { return socketFunctionArg.name === dataArg.funcCallData.funcName; } @@ -139,7 +139,7 @@ export class SocketConnection { ); } }); - this.socket.on('functionResponse', (dataArg: ISocketRequestDataObject) => { + this.socket.on('functionResponse', (dataArg: ISocketRequestDataObject) => { plugins.smartlog.defaultLogger.log( 'info', `received response for request with id ${dataArg.shortId}` diff --git a/ts/smartsocket.classes.socketfunction.ts b/ts/smartsocket.classes.socketfunction.ts index 35bafd2..356f005 100644 --- a/ts/smartsocket.classes.socketfunction.ts +++ b/ts/smartsocket.classes.socketfunction.ts @@ -12,36 +12,44 @@ import { SmartsocketClient } from './smartsocket.classes.smartsocketclient'; /** * interface of the contructor options of class SocketFunction */ -export interface ISocketFunctionConstructorOptions { +export interface ISocketFunctionConstructorOptions { funcName: string; - funcDef: TFuncDef; + funcDef: TFuncDef; allowedRoles: SocketRole[]; // all roles that are allowed to execute a SocketFunction } /** * interface of the Socket Function call, in other words the object that routes a call to a function */ -export interface ISocketFunctionCall { - funcName: string; - funcDataArg: any; +export interface ISocketFunctionCallDataRequest { + funcName: T['method']; + funcDataArg: T['request']; +} + +/** + * interface of the Socket Function call, in other words the object that routes a call to a function + */ +export interface ISocketFunctionCallDataResponse { + funcName: T['method']; + funcDataArg: T['response']; } /** * interface for function definition of SocketFunction */ -export type TFuncDef = (dataArg: any, connectionArg: SocketConnection) => PromiseLike; +export type TFuncDef = (dataArg: T['request'], connectionArg: SocketConnection) => PromiseLike; // export classes /** * class that respresents a function that can be transparently called using a SocketConnection */ -export class SocketFunction { +export class SocketFunction { // STATIC - public static getSocketFunctionByName( + public static getSocketFunctionByName( smartsocketRefArg: Smartsocket | SmartsocketClient, functionNameArg: string - ): SocketFunction { + ): SocketFunction { return smartsocketRefArg.socketFunctions.find(socketFunctionArg => { return socketFunctionArg.name === functionNameArg; }); @@ -49,13 +57,13 @@ export class SocketFunction { // INSTANCE public name: string; - public funcDef: TFuncDef; + public funcDef: TFuncDef; public roles: SocketRole[]; /** * the constructor for SocketFunction */ - constructor(optionsArg: ISocketFunctionConstructorOptions) { + constructor(optionsArg: ISocketFunctionConstructorOptions) { this.name = optionsArg.funcName; this.funcDef = optionsArg.funcDef; this.roles = optionsArg.allowedRoles; @@ -67,20 +75,16 @@ export class SocketFunction { /** * invokes the function of this SocketFunction */ - public invoke(dataArg: ISocketFunctionCall, socketConnectionArg: SocketConnection): Promise { - const done = plugins.smartpromise.defer(); + public async invoke(dataArg: ISocketFunctionCallDataRequest, socketConnectionArg: SocketConnection): Promise> { if (dataArg.funcName === this.name) { - this.funcDef(dataArg.funcDataArg, socketConnectionArg).then((resultData: any) => { - const funcResponseData: ISocketFunctionCall = { - funcName: this.name, - funcDataArg: resultData - }; - done.resolve(funcResponseData); - }); + const funcResponseData: ISocketFunctionCallDataResponse = { + funcName: this.name, + funcDataArg: await this.funcDef(dataArg.funcDataArg, socketConnectionArg) + }; + return funcResponseData; } else { throw new Error("SocketFunction.name does not match the data argument's .name!"); } - return done.promise; } /** diff --git a/ts/smartsocket.classes.socketrequest.ts b/ts/smartsocket.classes.socketrequest.ts index 0376ce5..a15126d 100644 --- a/ts/smartsocket.classes.socketrequest.ts +++ b/ts/smartsocket.classes.socketrequest.ts @@ -1,7 +1,7 @@ import * as plugins from './smartsocket.plugins'; // import interfaces -import { SocketFunction, ISocketFunctionCall } from './smartsocket.classes.socketfunction'; +import { SocketFunction, ISocketFunctionCallDataRequest, ISocketFunctionCallDataResponse } from './smartsocket.classes.socketfunction'; // import classes import { Objectmap } from '@pushrocks/lik'; @@ -17,29 +17,29 @@ export type TSocketRequestSide = 'requesting' | 'responding'; /** * interface of constructor of class SocketRequest */ -export interface ISocketRequestConstructorOptions { +export interface ISocketRequestConstructorOptions { side: TSocketRequestSide; originSocketConnection: SocketConnection; shortId: string; - funcCallData?: ISocketFunctionCall; + funcCallData?: ISocketFunctionCallDataRequest; } /** * request object that is sent initially and may or may not receive a response */ -export interface ISocketRequestDataObject { - funcCallData: ISocketFunctionCall; +export interface ISocketRequestDataObject { + funcCallData: ISocketFunctionCallDataRequest | ISocketFunctionCallDataResponse; shortId: string; responseTimeout?: number; } // export classes -export class SocketRequest { +export class SocketRequest { // STATIC public static getSocketRequestById( smartsocketRef: Smartsocket | SmartsocketClient, shortIdArg: string - ): SocketRequest { + ): SocketRequest { return smartsocketRef.socketRequests.find(socketRequestArg => { return socketRequestArg.shortid === shortIdArg; }); @@ -50,14 +50,14 @@ export class SocketRequest { public side: TSocketRequestSide; public shortid: string; public originSocketConnection: SocketConnection; - public funcCallData: ISocketFunctionCall; - public done = plugins.smartpromise.defer(); + public funcCallData: ISocketFunctionCallDataRequest; + public done = plugins.smartpromise.defer>(); public smartsocketRef: Smartsocket | SmartsocketClient; constructor( smartsocketRefArg: Smartsocket | SmartsocketClient, - optionsArg: ISocketRequestConstructorOptions + optionsArg: ISocketRequestConstructorOptions ) { this.smartsocketRef = smartsocketRefArg; this.side = optionsArg.side; @@ -72,8 +72,8 @@ export class SocketRequest { /** * dispatches a socketrequest from the requesting to the receiving side */ - public dispatch(): Promise { - const requestData: ISocketRequestDataObject = { + public dispatch(): Promise> { + const requestData: ISocketRequestDataObject = { funcCallData: this.funcCallData, shortId: this.shortid }; @@ -84,7 +84,7 @@ export class SocketRequest { /** * handles the response that is received by the requesting side */ - public handleResponse(responseDataArg: ISocketRequestDataObject) { + public async handleResponse(responseDataArg: ISocketRequestDataObject) { plugins.smartlog.defaultLogger.log('info', 'handling response!'); this.done.resolve(responseDataArg.funcCallData); this.smartsocketRef.socketRequests.remove(this); @@ -96,7 +96,7 @@ export class SocketRequest { * creates the response on the responding side */ public async createResponse(): Promise { - const targetSocketFunction: SocketFunction = SocketFunction.getSocketFunctionByName( + const targetSocketFunction: SocketFunction = SocketFunction.getSocketFunctionByName( this.smartsocketRef, this.funcCallData.funcName ); @@ -112,11 +112,11 @@ export class SocketRequest { plugins.smartlog.defaultLogger.log('info', `invoking ${targetSocketFunction.name}`); targetSocketFunction.invoke(this.funcCallData, this.originSocketConnection).then(resultData => { plugins.smartlog.defaultLogger.log('info', 'got resultData. Sending it to requesting party.'); - const requestData: ISocketRequestDataObject = { + const responseData: ISocketRequestDataObject = { funcCallData: resultData, shortId: this.shortid }; - this.originSocketConnection.socket.emit('functionResponse', requestData); + this.originSocketConnection.socket.emit('functionResponse', responseData); this.smartsocketRef.socketRequests.remove(this); }); } diff --git a/ts/smartsocket.classes.socketrole.ts b/ts/smartsocket.classes.socketrole.ts index dde78af..c8a08fe 100644 --- a/ts/smartsocket.classes.socketrole.ts +++ b/ts/smartsocket.classes.socketrole.ts @@ -42,7 +42,7 @@ export class SocketRole { // INSTANCE public name: string; public passwordHash: string; - public allowedFunctions = new Objectmap(); + public allowedFunctions = new Objectmap>(); constructor(optionsArg: ISocketRoleOptions) { this.name = optionsArg.name; this.passwordHash = optionsArg.passwordHash; @@ -52,7 +52,7 @@ export class SocketRole { * adds the socketfunction to the socketrole * @param socketFunctionArg */ - public addSocketFunction(socketFunctionArg: SocketFunction) { + public addSocketFunction(socketFunctionArg: SocketFunction) { this.allowedFunctions.add(socketFunctionArg); } } diff --git a/ts/smartsocket.plugins.ts b/ts/smartsocket.plugins.ts index 90b8243..dbdcb59 100644 --- a/ts/smartsocket.plugins.ts +++ b/ts/smartsocket.plugins.ts @@ -1,12 +1,16 @@ +// apiglobal scope +import * as typedrequestInterfaces from '@apiglobal/typedrequest-interfaces'; + +export {typedrequestInterfaces}; + +// pushrocks scope import * as lik from '@pushrocks/lik'; import * as smartlog from '@pushrocks/smartlog'; import * as smarthash from '@pushrocks/smarthash'; import * as smartdelay from '@pushrocks/smartdelay'; import * as smartexpress from '@pushrocks/smartexpress'; import * as smartpromise from '@pushrocks/smartpromise'; -import * as shortid from 'shortid'; -import socketIo from 'socket.io'; -import socketIoClient from 'socket.io-client'; + export { lik, @@ -14,7 +18,15 @@ export { smarthash, smartdelay, smartexpress, - smartpromise, + smartpromise +}; + +// third party scope +import * as shortid from 'shortid'; +import socketIo from 'socket.io'; +import socketIoClient from 'socket.io-client'; + +export { shortid, socketIo, socketIoClient