Browse Source

v 1.3.0 improve pseudointerfaces

master
peter 4 years ago
parent
commit
cc78248e44
8 changed files with 57 additions and 81 deletions
  1. 2
    2
      README.md
  2. 1
    1
      package.json
  3. 1
    1
      src/Backend.ts
  4. 1
    1
      src/Frontend.ts
  5. 5
    5
      src/Interfaces.ts
  6. 25
    21
      src/Types.ts
  7. 3
    10
      test/Test.ts
  8. 19
    40
      test/devtest.ts

+ 2
- 2
README.md View File

107
 This feature is currently still in development and considered **unstable and untested**. Use with caution.
107
 This feature is currently still in development and considered **unstable and untested**. Use with caution.
108
 
108
 
109
 ```typescript
109
 ```typescript
110
-type MyInterface = RPCInterface<{ 
110
+type MyInterface = { 
111
     Group1: { 
111
     Group1: { 
112
         triggerCallbacks: (...args:any[]) => Promise<void>,
112
         triggerCallbacks: (...args:any[]) => Promise<void>,
113
         subscribe: (param:string, callback:Function) => Promise<SubscriptionResponse<{a: string}>>,
113
         subscribe: (param:string, callback:Function) => Promise<SubscriptionResponse<{a: string}>>,
116
     Group2: {
116
     Group2: {
117
         echo: (x:string) => Promise<string>
117
         echo: (x:string) => Promise<string>
118
     }
118
     }
119
-}>
119
+}
120
 ```
120
 ```
121
 Create a client using
121
 Create a client using
122
 ```typescript
122
 ```typescript

+ 1
- 1
package.json View File

1
 {
1
 {
2
   "name": "rpclibrary",
2
   "name": "rpclibrary",
3
-  "version": "1.2.6",
3
+  "version": "1.3.0",
4
   "description": "rpclibrary is a websocket on steroids!",
4
   "description": "rpclibrary is a websocket on steroids!",
5
   "main": "./js/Index.js",
5
   "main": "./js/Index.js",
6
   "repository": {
6
   "repository": {

+ 1
- 1
src/Backend.ts View File

29
      */
29
      */
30
     constructor(
30
     constructor(
31
         private port:number,
31
         private port:number,
32
-        private exporters: I.RPCExporter<T.RPCInterface<InterfaceT>, keyof T.RPCInterface<InterfaceT>, SubResType>[] = [],
32
+        private exporters: I.RPCExporter<T.RPCInterface<InterfaceT>, keyof InterfaceT, SubResType>[] = [],
33
         conf: T.SocketConf =  {}
33
         conf: T.SocketConf =  {}
34
     ){
34
     ){
35
         
35
         

+ 1
- 1
src/Frontend.ts View File

129
      * @param fnName The function name
129
      * @param fnName The function name
130
      * @param fnArgs A string-list of parameters
130
      * @param fnArgs A string-list of parameters
131
      */
131
      */
132
-    private callGenerator(fnName: string, fnArgs:string[]): T.AsyncFunction{
132
+    private callGenerator(fnName: string, fnArgs:string[]): T.AnyFunction{
133
         const headerArgs = fnArgs.join(",")
133
         const headerArgs = fnArgs.join(",")
134
         const argParams = fnArgs.map(stripAfterEquals).join(",")
134
         const argParams = fnArgs.map(stripAfterEquals).join(",")
135
         return eval( '( () => async ('+headerArgs+') => { return await this.socket.call("'+fnName+'", '+argParams+')} )()' )
135
         return eval( '( () => async ('+headerArgs+') => { return await this.socket.call("'+fnName+'", '+argParams+')} )()' )

+ 5
- 5
src/Interfaces.ts View File

2
 import * as I from "./Interfaces"
2
 import * as I from "./Interfaces"
3
 
3
 
4
 /**
4
 /**
5
- * Interface for all classes that may export RPCs
5
+ * Interface for all classes that export RPCs
6
  */
6
  */
7
 export interface RPCExporter<
7
 export interface RPCExporter<
8
-    Ifc extends T.RPCInterface, 
9
-    K extends keyof Ifc, 
8
+    Ifc extends T.RPCInterface,
9
+    Name extends keyof Ifc,
10
     SubresT = {}
10
     SubresT = {}
11
 >{
11
 >{
12
-    name: K
13
-    exportRPCs() : T.RPC<Ifc[K], keyof Ifc[K], SubresT>[]
12
+    name: Name
13
+    exportRPCs() : T.RPCInterfaceArray<Ifc, SubresT>[Name]
14
 }
14
 }
15
 
15
 
16
 /**
16
 /**

+ 25
- 21
src/Types.ts View File

1
 import * as I from "./Interfaces";
1
 import * as I from "./Interfaces";
2
 
2
 
3
-export type AnyFunction = (...any:any)=>any
4
-export type AsyncFunction<Fn extends AnyFunction = AnyFunction> = ReturnType<Fn> extends Promise<any> ? Fn : (...any:Parameters<Fn>) => Promise<ReturnType<Fn>>
5
-export type RPCGroup = { [name in string] : AsyncFunction }
6
-export type RPCInterface<Impl extends RPCInterface = {}> = { [groupName in string]: RPCGroup } & Impl
3
+export type AnyFunction = (...args:any) => any
4
+export type HookFunction<F extends AnyFunction = AnyFunction, SubresT = {}> = (...args: Parameters<F>) => Promise<SubscriptionResponse<SubresT> | ErrorResponse>
7
 
5
 
8
 export type Visibility = "127.0.0.1" | "0.0.0.0"
6
 export type Visibility = "127.0.0.1" | "0.0.0.0"
9
 export type ConnectionHandler = (socket:I.Socket) => void
7
 export type ConnectionHandler = (socket:I.Socket) => void
19
 export type ResponseType = "Subscribe" | "Success" | "Error"
17
 export type ResponseType = "Subscribe" | "Success" | "Error"
20
 export type Outcome = "Success" | "Error"
18
 export type Outcome = "Success" | "Error"
21
 
19
 
22
-
23
 export type Respose<T> = T & { result: Outcome }
20
 export type Respose<T> = T & { result: Outcome }
24
 export type SuccessResponse<T = {}> = Respose<T> & { result: "Success" } 
21
 export type SuccessResponse<T = {}> = Respose<T> & { result: "Success" } 
25
 export type ErrorResponse<T = {}> = Respose<T> & { result: "Error", message?:string }
22
 export type ErrorResponse<T = {}> = Respose<T> & { result: "Error", message?:string }
27
 
24
 
28
 export type RPCType = 'Hook' | 'Unhook' | 'Call'
25
 export type RPCType = 'Hook' | 'Unhook' | 'Call'
29
 
26
 
30
-export type HookT<G extends RPCGroup, K extends keyof G, SubresT> = AsyncFunction<HookFunction<G[K], SubresT>>
31
-export type CallT<G extends RPCGroup, K extends keyof G> = AsyncFunction<G[K]>
27
+export type CallRPC<N, F> = {
28
+    name: N
29
+    call: F
30
+}
32
 
31
 
33
-export type HookRPC<G extends RPCGroup, K extends keyof G, SubresT = {}> = {
34
-    name: K
35
-    hook: HookT<G, K, SubresT>
36
-    onCallback?: CallbackFunction,
32
+export type HookRPC<N, F extends AnyFunction, SubresT = {}> = {
33
+    name: N
34
+    hook: HookFunction<F, SubresT>
35
+    onCallback?: AnyFunction
37
     onClose?: HookCloseFunction<SubresT>
36
     onClose?: HookCloseFunction<SubresT>
38
 }
37
 }
39
 
38
 
40
-export type CallRPC<G extends RPCGroup, K extends keyof G> = {
41
-    name: K
42
-    call: CallT<G,K>
43
-} 
39
+export type RPC<N, F extends AnyFunction, SubresT = {}> = HookRPC<N, F, SubresT> | CallRPC<N,F> | F
44
 
40
 
45
-export type RPC<G extends RPCGroup, Kg extends keyof G, SubresT> = CallRPC<G, Kg> | HookRPC<G, Kg, SubresT>
41
+export type RPCInterface<Impl extends RPCInterface = {}> = {
42
+    [grp in string] : {
43
+        [rpc in string] : AnyFunction
44
+    } 
45
+} & Impl
46
+
47
+export type RPCInterfaceArray<Itfc extends RPCInterface, SubresT = {}> = {
48
+    [grp in keyof Itfc]: Array<
49
+      { [rpc in keyof Itfc[grp]]: RPC<rpc, Itfc[grp][rpc], SubresT> }[keyof Itfc[grp]]
50
+    >
51
+}
46
 
52
 
47
 export type BaseInfo = {
53
 export type BaseInfo = {
48
     name: string,
54
     name: string,
50
     argNames: string[],
56
     argNames: string[],
51
 }
57
 }
52
 
58
 
53
-export type HookInfo<T = {}> = BaseInfo & { 
59
+export type HookInfo<SubresT = {}> = BaseInfo & { 
54
     type: 'Hook', 
60
     type: 'Hook', 
55
-    generator: (socket?:I.Socket) => HookFunction<AnyFunction, T>
61
+    generator: (socket?:I.Socket) => (...args:any) => SubresT
56
 }
62
 }
57
 
63
 
58
 export type CallInfo = BaseInfo & {
64
 export type CallInfo = BaseInfo & {
59
     type: 'Call',
65
     type: 'Call',
60
-    call: AsyncFunction
66
+    call: AnyFunction
61
 }
67
 }
62
 
68
 
63
 export type RpcInfo = HookInfo |  CallInfo
69
 export type RpcInfo = HookInfo |  CallInfo
65
 
71
 
66
 export type OnFunction = (type: 'error' | 'close', f: (e?:any)=>void) => I.Socket
72
 export type OnFunction = (type: 'error' | 'close', f: (e?:any)=>void) => I.Socket
67
 export type HookCloseFunction<T = {}> = (res:SubscriptionResponse<T>, rpc:HookRPC<any, any, T>) => any
73
 export type HookCloseFunction<T = {}> = (res:SubscriptionResponse<T>, rpc:HookRPC<any, any, T>) => any
68
-export type HookFunction<F extends AnyFunction = AnyFunction, SubResT = {}> = AsyncFunction<(...args:Parameters<F>) => SubscriptionResponse<SubResT> | ErrorResponse>
69
-export type CallbackFunction = (callback:AnyFunction, ...args:any) => any

+ 3
- 10
test/Test.ts View File

4
 import * as uuidv4 from "uuid/v4"
4
 import * as uuidv4 from "uuid/v4"
5
 import { RPCSocket } from "../src/Frontend";
5
 import { RPCSocket } from "../src/Frontend";
6
 import { SubscriptionResponse } from "../src/Types";
6
 import { SubscriptionResponse } from "../src/Types";
7
+import { makeSubResponse } from "../src/Utils";
7
 
8
 
8
 const add = (...args:number[]) => {return args.reduce((a,b)=>a+b, 0)}
9
 const add = (...args:number[]) => {return args.reduce((a,b)=>a+b, 0)}
9
 function makeServer(){
10
 function makeServer(){
18
                 name: 'simpleSubscribe',
19
                 name: 'simpleSubscribe',
19
                 hook: async(callback) => {
20
                 hook: async(callback) => {
20
                     subcallback =  callback
21
                     subcallback =  callback
21
-                    return {
22
-                        result: "Success",
23
-                        uuid: uuidv4(),
24
-                        topic: "test"
25
-                    }
22
+                    return makeSubResponse<{topic: string}>({topic: "test"})
26
                 }
23
                 }
27
             },{
24
             },{
28
                 name: 'subscribe',
25
                 name: 'subscribe',
29
                 hook: async (callback) => {
26
                 hook: async (callback) => {
30
                     subcallback = callback
27
                     subcallback = callback
31
-                    return {
32
-                        result: "Success",
33
-                        uuid: uuidv4(),
34
-                        topic: "test"
35
-                    }
28
+                    return makeSubResponse<{topic: string}>({topic: "test"})
36
                 },
29
                 },
37
                 onClose: (res, rpc) => { 
30
                 onClose: (res, rpc) => { 
38
                     console.log("onClose", rpc.name === 'subscribe' && res?"OK":"")
31
                     console.log("onClose", rpc.name === 'subscribe' && res?"OK":"")

+ 19
- 40
test/devtest.ts View File

1
 import { RPCServer } from "../src/Backend";
1
 import { RPCServer } from "../src/Backend";
2
-import { SubscriptionResponse, CallRPC, HookRPC, RPCInterface } from "../src/Types";
2
+import { SubscriptionResponse, RPCInterface } from "../src/Types";
3
 import { RPCSocket } from "../src/Frontend";
3
 import { RPCSocket } from "../src/Frontend";
4
+import { makeSubResponse } from "../src/Utils";
4
 
5
 
5
-type MyInterface = RPCInterface<{ 
6
+type SubresExtension = {a:string}
7
+
8
+type MyInterface = { 
6
     Group1: { 
9
     Group1: { 
7
         triggerCallbacks: (...args:any[]) => Promise<void>,
10
         triggerCallbacks: (...args:any[]) => Promise<void>,
8
-        subscribe: (param:string, callback:Function) => Promise<SubscriptionResponse<{a: string}>>,
11
+        subscribe: (param:string, callback:Function) => Promise<SubscriptionResponse<SubresExtension>>,
9
         unsubscribe: (uuid:string) => Promise<void>
12
         unsubscribe: (uuid:string) => Promise<void>
10
     },
13
     },
11
     Group2: {
14
     Group2: {
12
         echo: (x:string) => Promise<string>
15
         echo: (x:string) => Promise<string>
13
     }
16
     }
14
-}>
15
-
16
-const callbacks:Map<string, Function> = new Map()
17
+}
17
 
18
 
18
-new RPCServer<{a:string}, MyInterface>(20000, 
19
+new RPCServer<SubresExtension, MyInterface>(20000, 
19
     [{
20
     [{
20
-        name: "Group1",
21
-        exportRPCs: () => [
22
-        <HookRPC<MyInterface['Group1'], 'subscribe', {a:string}>>{
21
+        name: 'Group1',
22
+        exportRPCs: () => [{
23
+            name: 'triggerCallbacks',
24
+            call: async () => { /*...*/ }
25
+        },{
23
             name: 'subscribe',
26
             name: 'subscribe',
24
-            hook: async (param, callback) => { const _uuid = ""+Math.random(); console.log(param); callbacks.set(_uuid, callback); return { result: 'Success', a: '3', uuid: _uuid} }
25
-        },
26
-        <CallRPC<MyInterface['Group1'], 'unsubscribe'>>{
27
+            hook: async (param, callback) => { return makeSubResponse<SubresExtension>({a: "test"}) }
28
+        },{
27
             name: 'unsubscribe',
29
             name: 'unsubscribe',
28
-            call: async (uuid) => { callbacks.delete(uuid) }
29
-        },
30
-        <CallRPC<MyInterface['Group1'], 'triggerCallbacks'>>{
31
-            name: 'triggerCallbacks',
32
-            call: async (...args) => { callbacks.forEach(cb => cb.apply({}, args)) }
33
-        }]
34
-    },{
35
-        name: 'Group2',
36
-        exportRPCs: () => [
37
-        <CallRPC<MyInterface['Group2'], 'echo'>>{
38
-            name: 'echo',
39
-            call: async (x) => x
40
-        }]
41
-    }]
42
-)
43
-
44
-new RPCServer<{a:string}, MyInterface>(20001, 
45
-    [{
46
-        name: "Group1",
47
-        exportRPCs: () => []
30
+            call: async(uuid) => { }
31
+        }
32
+    ]
48
     },{
33
     },{
49
         name: 'Group2',
34
         name: 'Group2',
50
         exportRPCs: () => [{
35
         exportRPCs: () => [{
51
             name: 'echo',
36
             name: 'echo',
52
-            call: async (x) => x+" lol"
37
+            call: async (x) => "..."
53
         }]
38
         }]
54
     }]
39
     }]
55
 )
40
 )
65
     })
50
     })
66
 
51
 
67
     await client.Group1.triggerCallbacks("Hello", "World", "Callbacks")
52
     await client.Group1.triggerCallbacks("Hello", "World", "Callbacks")
68
-}))
69
-
70
-RPCSocket.makeSocket<MyInterface>(20001, 'localhost').then((async (client) => {
71
-    console.log(client)
72
-    const r = await client.Group2.echo("hee")
73
-    console.log(r)
74
 }))
53
 }))

Loading…
Cancel
Save