before rewrite to have callbacks as FIRST parameter
This commit is contained in:
+16
-10
@@ -4,7 +4,7 @@ import { PromiseIOClient, defaultClientConfig } from './PromiseIO/Client'
|
|||||||
import * as T from './Types';
|
import * as T from './Types';
|
||||||
import * as I from './Interfaces';
|
import * as I from './Interfaces';
|
||||||
import { stripAfterEquals, appendComma } from './Utils';
|
import { stripAfterEquals, appendComma } from './Utils';
|
||||||
import { DESTROY_PREFIX, SOCKET_NOT_CONNECTED, UNKNOWN_RPC_IDENTIFIER, USER_DEFINED_TIMEOUT } from './Strings';
|
import { CALLBACK_NAME, DESTROY_PREFIX, SOCKET_NOT_CONNECTED, UNKNOWN_RPC_IDENTIFIER, USER_DEFINED_TIMEOUT } from './Strings';
|
||||||
import { DeserializerFactory } from './Decorator';
|
import { DeserializerFactory } from './Decorator';
|
||||||
DeserializerFactory
|
DeserializerFactory
|
||||||
|
|
||||||
@@ -21,12 +21,12 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
|
|||||||
|
|
||||||
private socket: I.Socket
|
private socket: I.Socket
|
||||||
private handlers: {
|
private handlers: {
|
||||||
[name in string]: T.AnyFunction[]
|
[name in string]: T.GenericFunction[]
|
||||||
} = {
|
} = {
|
||||||
error: [],
|
error: [],
|
||||||
close: []
|
close: []
|
||||||
}
|
}
|
||||||
private hooks: { [name in string]: T.AnyFunction } = {}
|
private hooks: { [name in string]: T.GenericFunction } = {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -82,7 +82,7 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
|
|||||||
* @param type 'error' or 'close'
|
* @param type 'error' or 'close'
|
||||||
* @param f The listener to attach
|
* @param f The listener to attach
|
||||||
*/
|
*/
|
||||||
public on(type: string, f: T.AnyFunction) {
|
public on(type: string, f: T.GenericFunction) {
|
||||||
if (!this.socket) {
|
if (!this.socket) {
|
||||||
if (!this.handlers[type])
|
if (!this.handlers[type])
|
||||||
this.handlers[type] = []
|
this.handlers[type] = []
|
||||||
@@ -166,7 +166,7 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
|
|||||||
v.forEach(h => this.socket.on(k, h))
|
v.forEach(h => this.socket.on(k, h))
|
||||||
})
|
})
|
||||||
|
|
||||||
Object.entries(this.hooks).forEach((kv: [string, T.AnyFunction]) => {
|
Object.entries(this.hooks).forEach((kv: [string, T.GenericFunction]) => {
|
||||||
this.socket.hook(kv[0], kv[1])
|
this.socket.hook(kv[0], kv[1])
|
||||||
})
|
})
|
||||||
const info: T.ExtendedRpcInfo[] = await this.info(sesame)
|
const info: T.ExtendedRpcInfo[] = await this.info(sesame)
|
||||||
@@ -205,7 +205,7 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
|
|||||||
* @param fnName The function name
|
* @param fnName The function name
|
||||||
* @param fnArgs A string-list of parameters
|
* @param fnArgs A string-list of parameters
|
||||||
*/
|
*/
|
||||||
private callGenerator(fnName: string, fnArgs: string[], sesame?: string): T.AnyFunction {
|
private callGenerator(fnName: string, fnArgs: string[], sesame?: string): T.GenericFunction {
|
||||||
const headerArgs = fnArgs.join(",")
|
const headerArgs = fnArgs.join(",")
|
||||||
const argParams = fnArgs.map(stripAfterEquals).join(",")
|
const argParams = fnArgs.map(stripAfterEquals).join(",")
|
||||||
sesame = appendComma(sesame)
|
sesame = appendComma(sesame)
|
||||||
@@ -221,7 +221,7 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
|
|||||||
* @param fnName The function name
|
* @param fnName The function name
|
||||||
* @param fnArgs A string-list of parameters
|
* @param fnArgs A string-list of parameters
|
||||||
*/
|
*/
|
||||||
private frontEndHookGenerator(fnName: string, fnArgs: string[], sesame?: string): T.HookFunction {
|
private frontEndHookGenerator(fnName: string, fnArgs: string[], sesame?: string): T.GenericFunction {
|
||||||
|
|
||||||
if (sesame)
|
if (sesame)
|
||||||
fnArgs.shift()
|
fnArgs.shift()
|
||||||
@@ -234,16 +234,22 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
|
|||||||
const destroy_prefix = DESTROY_PREFIX
|
const destroy_prefix = DESTROY_PREFIX
|
||||||
|
|
||||||
const frontendHookStr = `
|
const frontendHookStr = `
|
||||||
async (${headerArgs} $__callback__$) => {
|
async (${headerArgs} ${CALLBACK_NAME}) => {
|
||||||
const r = await this.call("${fnName}", ${sesame} ${argParams})
|
const r = await this.call("${fnName}", ${sesame} ${argParams})
|
||||||
try{
|
try{
|
||||||
if(r){
|
if(r){
|
||||||
if(r.uuid){
|
if(r.uuid){
|
||||||
$__callback__$['destroy'] = () => {
|
${CALLBACK_NAME}['destroy'] = () => {
|
||||||
this.socket.fire(destroy_prefix+r.uuid)
|
this.socket.fire(destroy_prefix+r.uuid)
|
||||||
this.socket.unhook(r.uuid)
|
this.socket.unhook(r.uuid)
|
||||||
}
|
}
|
||||||
this.socket.hook(r.uuid, $__callback__$)
|
${CALLBACK_NAME} = ${CALLBACK_NAME}.bind({
|
||||||
|
destroy: ${CALLBACK_NAME}['destroy']
|
||||||
|
})
|
||||||
|
|
||||||
|
this.socket.hook(r.uuid, (...args) => {
|
||||||
|
${CALLBACK_NAME}.apply(${CALLBACK_NAME}, args.map(deserializer.from))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return deserializer.from(r.return)
|
return deserializer.from(r.return)
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
+2
-2
@@ -15,10 +15,10 @@ export interface Socket {
|
|||||||
id?: string
|
id?: string
|
||||||
bind: (name: string, listener: T.PioBindListener) => void
|
bind: (name: string, listener: T.PioBindListener) => void
|
||||||
hook: (rpcname: string, handler: T.PioHookListener) => void
|
hook: (rpcname: string, handler: T.PioHookListener) => void
|
||||||
unhook: (rpcname: string, listener?:T.AnyFunction) => void
|
unhook: (rpcname: string, listener?:T.GenericFunction) => void
|
||||||
call: (rpcname: string, ...args: any[]) => Promise<any>
|
call: (rpcname: string, ...args: any[]) => Promise<any>
|
||||||
fire: (rpcname: string, ...args: any[]) => Promise<any>
|
fire: (rpcname: string, ...args: any[]) => Promise<any>
|
||||||
on: (type: string, f: T.AnyFunction)=>any
|
on: (type: string, f: T.GenericFunction)=>any
|
||||||
emit: (eventName: string, ...args: any[]) => void
|
emit: (eventName: string, ...args: any[]) => void
|
||||||
close(): void
|
close(): void
|
||||||
}
|
}
|
||||||
@@ -14,3 +14,4 @@ RPC did not provide a name.
|
|||||||
\n>------------OFFENDING RPC`
|
\n>------------OFFENDING RPC`
|
||||||
export const CLASSNAME_ATTRIBUTE = "$__CLASSNAME__$"
|
export const CLASSNAME_ATTRIBUTE = "$__CLASSNAME__$"
|
||||||
export const DESTROY_PREFIX = "$__DESTROY__$_"
|
export const DESTROY_PREFIX = "$__DESTROY__$_"
|
||||||
|
export const CALLBACK_NAME = "$__CALLBACK__$"
|
||||||
+48
-42
@@ -1,12 +1,28 @@
|
|||||||
import * as I from "./Interfaces";
|
import * as I from "./Interfaces";
|
||||||
import { RPCSocket } from "./Frontend";
|
import { RPCSocket } from "./Frontend";
|
||||||
import { PromiseIO } from "./PromiseIO/Server";
|
|
||||||
|
|
||||||
export type PioBindListener = (...args: any) => void
|
export type PioBindListener = (...args: any) => void
|
||||||
export type PioHookListener = AnyFunction
|
export type PioHookListener = GenericFunction
|
||||||
|
|
||||||
|
export type GenericFunction<Parameters extends any[] = any[], Result = any> = {(...args: Parameters): Result}
|
||||||
|
|
||||||
|
export type BackendHook<Func extends GenericFunction> =
|
||||||
|
GenericFunction<
|
||||||
|
[
|
||||||
|
...Head<Parameters<Func>>,
|
||||||
|
GenericFunction<
|
||||||
|
Parameters<
|
||||||
|
AsFunction<
|
||||||
|
Last<Parameters<Func>>
|
||||||
|
>
|
||||||
|
>,
|
||||||
|
void
|
||||||
|
>
|
||||||
|
],
|
||||||
|
ReturnType<Func>
|
||||||
|
>
|
||||||
|
|
||||||
|
|
||||||
export type AnyFunction = (...args: any[]) => any
|
|
||||||
export type HookFunction = AnyFunction
|
|
||||||
export type AccessFilter<InterfaceT extends RPCInterface = RPCInterface> = (sesame: string | undefined, exporter: I.RPCExporter<InterfaceT, keyof InterfaceT>) => Promise<boolean> | boolean
|
export type AccessFilter<InterfaceT extends RPCInterface = RPCInterface> = (sesame: string | undefined, exporter: I.RPCExporter<InterfaceT, keyof InterfaceT>) => Promise<boolean> | boolean
|
||||||
export type Visibility = "127.0.0.1" | "0.0.0.0"
|
export type Visibility = "127.0.0.1" | "0.0.0.0"
|
||||||
export type ConnectionHandler = (socket: I.Socket) => void
|
export type ConnectionHandler = (socket: I.Socket) => void
|
||||||
@@ -45,24 +61,23 @@ export type ErrorResponse<T = {}> = Respose<T> & { result: "Error", message?: st
|
|||||||
|
|
||||||
export type RPCType = 'Hook' | 'Unhook' | 'Call'
|
export type RPCType = 'Hook' | 'Unhook' | 'Call'
|
||||||
|
|
||||||
export type CallRPC<Name, Func extends AnyFunction> = {
|
export type CallRPC<Name, Func extends GenericFunction> = {
|
||||||
name: Name
|
name: Name
|
||||||
call: Func
|
call: Func
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type HookRPC<Name, Func extends GenericFunction> = {
|
||||||
export type HookRPC<Name, Func extends AnyFunction> = {
|
|
||||||
name: Name
|
name: Name
|
||||||
hook: AnyFunction
|
hook: BackendHook<Func>
|
||||||
onCallback?: AnyFunction
|
onCallback?: GenericFunction
|
||||||
onDestroy?: HookCloseFunction<ReturnType<Func> extends Promise<infer T> ? T : ReturnType<Func>>
|
onDestroy?: HookCloseFunction<ReturnType<Func> extends Promise<infer T> ? T : ReturnType<Func>>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RPC<Name, Func extends AnyFunction> = HookRPC<Name, Func> | CallRPC<Name, Func> | Func
|
export type RPC<Name, Func extends GenericFunction> = HookRPC<Name, Func> | CallRPC<Name, Func> | Func
|
||||||
|
|
||||||
export type RPCInterface<Impl extends RPCInterface = {}> = {
|
export type RPCInterface<Impl extends RPCInterface = {}> = {
|
||||||
[grp in string]: {
|
[grp in string]: {
|
||||||
[rpc in string]: AnyFunction
|
[rpc in string]: GenericFunction
|
||||||
}
|
}
|
||||||
} & Impl
|
} & Impl
|
||||||
|
|
||||||
@@ -89,7 +104,7 @@ export type HookInfo<SubresT = {}> = BaseInfo & {
|
|||||||
|
|
||||||
export type CallInfo = BaseInfo & {
|
export type CallInfo = BaseInfo & {
|
||||||
type: 'Call',
|
type: 'Call',
|
||||||
call: AnyFunction
|
call: GenericFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RpcInfo = HookInfo | CallInfo
|
export type RpcInfo = HookInfo | CallInfo
|
||||||
@@ -99,39 +114,30 @@ export type OnFunction = <T extends "error" | "close">(type: T, f: FrontEndHandl
|
|||||||
export type HookCloseFunction<T> = (res: T, rpc: HookRPC<any, any>) => any
|
export type HookCloseFunction<T> = (res: T, rpc: HookRPC<any, any>) => any
|
||||||
|
|
||||||
|
|
||||||
export type AsyncIfc<Ifc extends RPCInterface> = { [grp in keyof Ifc]: { [rpcname in keyof Ifc[grp]]: AsyncAnyFunction<Ifc[grp][rpcname]> } }
|
export type AsyncIfc<Ifc extends RPCInterface> = { [grp in keyof Ifc]: { [rpcname in keyof Ifc[grp]]: AsyncGenericFunction<Ifc[grp][rpcname]> } }
|
||||||
|
|
||||||
export type AsyncAnyFunction<F extends AnyFunction = AnyFunction> = F extends (...args: Parameters<F>) => infer R
|
export type AsyncGenericFunction<F extends GenericFunction = GenericFunction> = F extends (...args: Parameters<F>) => infer R
|
||||||
? ((...args: Parameters<F>) => R extends Promise<any> ? R : Promise<R>)
|
? ((...args: Parameters<F>) => R extends Promise<any> ? R : Promise<R>)
|
||||||
: Promise<any>
|
: Promise<any>
|
||||||
|
|
||||||
type DYN_PARAM<
|
|
||||||
A = void,
|
|
||||||
B = void,
|
|
||||||
C = void,
|
|
||||||
D = void,
|
|
||||||
E = void,
|
|
||||||
F = void,
|
|
||||||
G = void,
|
|
||||||
H = void,
|
|
||||||
> = H extends void ?
|
|
||||||
G extends void ?
|
|
||||||
F extends void ?
|
|
||||||
E extends void ?
|
|
||||||
D extends void ?
|
|
||||||
C extends void ?
|
|
||||||
B extends void ?
|
|
||||||
A extends void ?
|
|
||||||
[]
|
|
||||||
: [A]
|
|
||||||
: [A,B]
|
|
||||||
:[A,B,C]
|
|
||||||
:[A,B,C,D]
|
|
||||||
:[A,B,C,D,E]
|
|
||||||
:[A,B,C,D,E,F]
|
|
||||||
:[A,B,C,D,E,F,G]
|
|
||||||
:[A,B,C,D,E,F,G,H]
|
|
||||||
|
|
||||||
type Destroyable = { destroy: () => void }
|
type Destroyable = { destroy: () => void }
|
||||||
export type Callback<A0 = void, A1 = void, A2 = void, A3 = void, A4 = void, A5 = void, A6 = void, A7 = void> =
|
export type Callback<Params extends any[] = []> =
|
||||||
(this: Destroyable, ...args: DYN_PARAM<A0, A1, A2, A3, A4, A5, A6, A7>) => void
|
(this: Destroyable, ...args: Params) => void
|
||||||
|
|
||||||
|
type AsFunction<F> = F extends GenericFunction ? F : GenericFunction
|
||||||
|
|
||||||
|
type Last<Tuple extends any[]> = Tuple[ Subtract<Length<Tuple>, 1> ]
|
||||||
|
type Head<T extends any[]> = T extends [ ...infer Head, any ] ? Head : any[]
|
||||||
|
type Tail<T extends any[]> = T extends [any, ...infer Tail] ? Tail: []
|
||||||
|
|
||||||
|
type Length<T extends any[]> =
|
||||||
|
T extends { length: infer L } ? L : never;
|
||||||
|
|
||||||
|
type BuildTuple<L extends number, T extends any[] = []> =
|
||||||
|
T extends { length: L } ? T : BuildTuple<L, [...T, any]>;
|
||||||
|
|
||||||
|
type Subtract<A extends number, B extends number> =
|
||||||
|
BuildTuple<A> extends [...(infer U), ...BuildTuple<B>]
|
||||||
|
? Length<U>
|
||||||
|
: never;
|
||||||
+4
-2
@@ -76,7 +76,7 @@ export function rpcHooker(socket: I.Socket, exporter: I.RPCExporter<any, any>, e
|
|||||||
* Decorate an RPC with the error handler
|
* Decorate an RPC with the error handler
|
||||||
* @param rpcFunction the function to decorate
|
* @param rpcFunction the function to decorate
|
||||||
*/
|
*/
|
||||||
const callGenerator = (rpcName: string, $__socket__$: I.Socket, rpcFunction: T.AnyFunction, errorHandler: T.ErrorHandler): T.AnyFunction => {
|
const callGenerator = (rpcName: string, $__socket__$: I.Socket, rpcFunction: T.GenericFunction, errorHandler: T.ErrorHandler): T.GenericFunction => {
|
||||||
const argsArr = extractArgs(rpcFunction)
|
const argsArr = extractArgs(rpcFunction)
|
||||||
const args = argsArr.join(',')
|
const args = argsArr.join(',')
|
||||||
const argsStr = argsArr.map(stripAfterEquals).join(',')
|
const argsStr = argsArr.map(stripAfterEquals).join(',')
|
||||||
@@ -108,6 +108,7 @@ export function stripAfterEquals(str: string): string {
|
|||||||
* @returns A {@link HookFunction}
|
* @returns A {@link HookFunction}
|
||||||
*/
|
*/
|
||||||
const hookGenerator = (rpc: T.HookRPC<any, any>, errorHandler: T.ErrorHandler, sesameFn?: T.SesameFunction, injectSocket?: boolean): T.HookInfo['generator'] => {
|
const hookGenerator = (rpc: T.HookRPC<any, any>, errorHandler: T.ErrorHandler, sesameFn?: T.SesameFunction, injectSocket?: boolean): T.HookInfo['generator'] => {
|
||||||
|
const deserializer = DeserializerFactory
|
||||||
let argsArr = extractArgs(rpc.hook)
|
let argsArr = extractArgs(rpc.hook)
|
||||||
argsArr.pop() //remove callback param
|
argsArr.pop() //remove callback param
|
||||||
|
|
||||||
@@ -124,6 +125,7 @@ const hookGenerator = (rpc: T.HookRPC<any, any>, errorHandler: T.ErrorHandler, s
|
|||||||
const uuid = uuidv4()
|
const uuid = uuidv4()
|
||||||
const res = await rpc.hook(${callArgs} (...cbargs) => {
|
const res = await rpc.hook(${callArgs} (...cbargs) => {
|
||||||
${rpc.onCallback ? `rpc.onCallback.apply({}, cbargs)` : ``}
|
${rpc.onCallback ? `rpc.onCallback.apply({}, cbargs)` : ``}
|
||||||
|
cbargs = cbargs.map(deserializer.makeDeserializable)
|
||||||
$__socket__$.call.apply($__socket__$, [uuid, ...cbargs])
|
$__socket__$.call.apply($__socket__$, [uuid, ...cbargs])
|
||||||
})
|
})
|
||||||
${rpc.onDestroy ? `$__socket__$.bind(destroy_prefix+uuid, () => {
|
${rpc.onDestroy ? `$__socket__$.bind(destroy_prefix+uuid, () => {
|
||||||
@@ -247,7 +249,7 @@ export const makePioSocket = (socket: any): I.Socket => {
|
|||||||
res(undefined)
|
res(undefined)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
unhook: (name: string, listener?: T.AnyFunction) => {
|
unhook: (name: string, listener?: T.GenericFunction) => {
|
||||||
if (listener) {
|
if (listener) {
|
||||||
socket.removeListener(name, listener)
|
socket.removeListener(name, listener)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+74
-33
@@ -1,7 +1,7 @@
|
|||||||
import { describe, it } from "mocha";
|
import { describe, it } from "mocha";
|
||||||
import { RPCServer, RPCSocket, Serializable } from '../Index'
|
import { RPCServer, RPCSocket, Serializable } from '../Index'
|
||||||
import { RPCExporter, Socket } from "../src/Interfaces";
|
import { RPCExporter, Socket } from "../src/Interfaces";
|
||||||
import { ConnectedSocket, Callback } from "../src/Types";
|
import { ConnectedSocket, Callback, GenericFunction } from "../src/Types";
|
||||||
import * as log from 'why-is-node-running';
|
import * as log from 'why-is-node-running';
|
||||||
import * as http from 'http';
|
import * as http from 'http';
|
||||||
import * as express from 'express';
|
import * as express from 'express';
|
||||||
@@ -9,7 +9,7 @@ import * as fetch from 'node-fetch';
|
|||||||
import { PromiseIO } from "../src/PromiseIO/Server";
|
import { PromiseIO } from "../src/PromiseIO/Server";
|
||||||
import { PromiseIOClient } from "../src/PromiseIO/Client";
|
import { PromiseIOClient } from "../src/PromiseIO/Client";
|
||||||
import { assert, expect } from 'chai';
|
import { assert, expect } from 'chai';
|
||||||
import { USER_DEFINED_TIMEOUT } from "../src/Strings";
|
import { CLASSNAME_ATTRIBUTE, USER_DEFINED_TIMEOUT } from "../src/Strings";
|
||||||
var should = require('chai').should();
|
var should = require('chai').should();
|
||||||
var chai = require("chai");
|
var chai = require("chai");
|
||||||
var chaiAsPromised = require("chai-as-promised");
|
var chaiAsPromised = require("chai-as-promised");
|
||||||
@@ -614,7 +614,7 @@ type topicDTO = { topic: string; }
|
|||||||
type SesameTestIfc = {
|
type SesameTestIfc = {
|
||||||
test: {
|
test: {
|
||||||
checkCandy: () => Promise<string>
|
checkCandy: () => Promise<string>
|
||||||
subscribe: (callback: Callback<string>) => Promise<topicDTO>
|
subscribe: (callback: Callback<[string]>) => Promise<topicDTO>
|
||||||
manyParams: <A = string, B = number, C = boolean, D = Object>(a: A, b: B, c: C, d: D) => Promise<[A, B, C, D]>
|
manyParams: <A = string, B = number, C = boolean, D = Object>(a: A, b: B, c: C, d: D) => Promise<[A, B, C, D]>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1034,22 +1034,53 @@ describe("class (de-)serialization", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let myServer: RPCServer;
|
const verifyObject = (obj: any) => {
|
||||||
let mySocket: RPCSocket;
|
expect(obj).to.be.an.instanceOf(TestClass)
|
||||||
|
expect(obj.aString).to.be.a('string')
|
||||||
|
expect(obj.aNumber).to.be.a('number')
|
||||||
|
expect(obj.aObject).to.be.a('object')
|
||||||
|
expect(obj.aObject.x).to.be.a('string')
|
||||||
|
expect(obj.aObject.y).to.be.undefined
|
||||||
|
expect(obj.aObject.sub).to.be.an.instanceOf(SubClass)
|
||||||
|
expect(obj.aClassObject).to.be.an.instanceOf(SubClass)
|
||||||
|
expect(obj).to.not.have.key(CLASSNAME_ATTRIBUTE)
|
||||||
|
expect(obj.aObject.sub).to.not.have.key(CLASSNAME_ATTRIBUTE)
|
||||||
|
expect(obj.aClassObject).to.not.have.key(CLASSNAME_ATTRIBUTE)
|
||||||
|
expect(obj.returnOK()).to.be.equal('OK')
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("Responses", () => {
|
||||||
|
type TestIfc = {
|
||||||
|
Test: {
|
||||||
|
returnClass: () => Promise<TestClass>
|
||||||
|
classCallback: (callback: Callback<[TestClass]>) => Promise<TestClass>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let myServer: RPCServer<TestIfc>;
|
||||||
|
let mySocket: ConnectedSocket<TestIfc>;
|
||||||
|
|
||||||
before(function (done) {
|
before(function (done) {
|
||||||
myServer = new RPCServer([{
|
myServer = new RPCServer<TestIfc>([{
|
||||||
name: "Test",
|
name: "Test",
|
||||||
RPCs: [
|
RPCs: [
|
||||||
function returnClass(){
|
async function returnClass() {
|
||||||
return new TestClass()
|
return new TestClass()
|
||||||
|
}, {
|
||||||
|
name: "classCallback",
|
||||||
|
hook: async function (callback) {
|
||||||
|
setTimeout(_ => callback(new TestClass()), 250)
|
||||||
|
return new TestClass()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}])
|
}])
|
||||||
myServer.listen(8084)
|
myServer.listen(8084)
|
||||||
|
|
||||||
mySocket = new RPCSocket(8084, 'localhost')
|
new RPCSocket<TestIfc>(8084, 'localhost').connect().then(connsock => {
|
||||||
mySocket.connect().then(() => done())
|
mySocket = connsock
|
||||||
|
done()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
after(function (done) {
|
after(function (done) {
|
||||||
@@ -1059,33 +1090,43 @@ describe("class (de-)serialization", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
it("receives class in call response", async () => {
|
it("receives class object in call response", async () => {
|
||||||
const obj: TestClass = await mySocket['Test'].returnClass()
|
const obj: TestClass = await mySocket['Test'].returnClass()
|
||||||
|
verifyObject(obj)
|
||||||
expect(obj).to.be.an.instanceOf(TestClass)
|
|
||||||
expect(obj.aString).to.be.a('string')
|
|
||||||
expect(obj.aNumber).to.be.a('number')
|
|
||||||
expect(obj.aObject).to.be.a('object')
|
|
||||||
expect(obj.aObject.x).to.be.a('string')
|
|
||||||
expect(obj.aObject.y).to.be.undefined
|
|
||||||
expect(obj.aObject.sub).to.be.an.instanceOf(SubClass)
|
|
||||||
expect(obj.aClassObject).to.be.an.instanceOf(SubClass)
|
|
||||||
|
|
||||||
expect(obj.returnOK()).to.be.equal('OK')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it("receives class in hook response", async () => {
|
it("receives class object in hook response", async function () {
|
||||||
const obj: TestClass = await mySocket['Test'].returnClass()
|
const obj: TestClass = await mySocket.Test.classCallback(noop)
|
||||||
|
verifyObject(obj)
|
||||||
|
})
|
||||||
|
|
||||||
expect(obj).to.be.an.instanceOf(TestClass)
|
it("receives class object in callback", function (done) {
|
||||||
expect(obj.aString).to.be.a('string')
|
mySocket.Test.classCallback(function (cbValue) {
|
||||||
expect(obj.aNumber).to.be.a('number')
|
verifyObject(cbValue)
|
||||||
expect(obj.aObject).to.be.a('object')
|
done()
|
||||||
expect(obj.aObject.x).to.be.a('string')
|
}).then(verifyObject)
|
||||||
expect(obj.aObject.y).to.be.undefined
|
})
|
||||||
expect(obj.aObject.sub).to.be.an.instanceOf(SubClass)
|
})
|
||||||
expect(obj.aClassObject).to.be.an.instanceOf(SubClass)
|
describe("Parameters", () => {
|
||||||
|
it("Class object in call", function(done){
|
||||||
expect(obj.returnOK()).to.be.equal('OK')
|
const server = new RPCServer([
|
||||||
|
{
|
||||||
|
name: "Test",
|
||||||
|
RPCs: [
|
||||||
|
function callWithClass(testObj: TestClass){
|
||||||
|
verifyObject(testObj)
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]).listen(8086)
|
||||||
|
|
||||||
|
new RPCSocket(8086, 'localhost').connect().then(sock => {
|
||||||
|
sock['Test'].callWithClass(new TestClass()).then(_ => {
|
||||||
|
sock.close()
|
||||||
|
server.close()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Reference in New Issue
Block a user