Browse Source

fix subscribe+sesame

master
peter 4 years ago
parent
commit
ae843d341e
5 changed files with 90 additions and 33 deletions
  1. 1
    1
      package.json
  2. 0
    1
      src/Backend.ts
  3. 12
    5
      src/Frontend.ts
  4. 20
    18
      src/Utils.ts
  5. 57
    8
      test/Test.ts

+ 1
- 1
package.json View File

1
 {
1
 {
2
   "name": "rpclibrary",
2
   "name": "rpclibrary",
3
-  "version": "1.5.1",
3
+  "version": "1.5.2",
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": {

+ 0
- 1
src/Backend.ts View File

37
         if(!conf.visibility) this.visibility = "127.0.0.1"        
37
         if(!conf.visibility) this.visibility = "127.0.0.1"        
38
         
38
         
39
         if(conf.sesame){
39
         if(conf.sesame){
40
-            console.log("Setting Sesame")
41
             this.sesame = U.makeSesameFunction(conf.sesame)
40
             this.sesame = U.makeSesameFunction(conf.sesame)
42
         }
41
         }
43
 
42
 

+ 12
- 5
src/Frontend.ts View File

106
                     f = this.callGenerator(i.uniqueName, i.argNames, sesame)    
106
                     f = this.callGenerator(i.uniqueName, i.argNames, sesame)    
107
                     break                
107
                     break                
108
                 case 'Hook':
108
                 case 'Hook':
109
-                    f = this.hookGenerator(i.uniqueName, i.argNames, sesame)                    
109
+                    f = this.frontEndHookGenerator(i.uniqueName, i.argNames, sesame)                    
110
                     break
110
                     break
111
             }
111
             }
112
             if(this[i.owner] == null)
112
             if(this[i.owner] == null)
143
      * @param fnName The function name
143
      * @param fnName The function name
144
      * @param fnArgs A string-list of parameters
144
      * @param fnArgs A string-list of parameters
145
      */
145
      */
146
-    private hookGenerator(fnName: string, fnArgs:string[], sesame?:string): T.HookFunction{
146
+    private frontEndHookGenerator(fnName: string, fnArgs:string[], sesame?:string): T.HookFunction{
147
+        fnArgs.pop()
147
         const headerArgs = fnArgs.join(",")
148
         const headerArgs = fnArgs.join(",")
148
         const argParams = fnArgs.map(stripAfterEquals).join(",")
149
         const argParams = fnArgs.map(stripAfterEquals).join(",")
150
+
149
         if(!sesame){
151
         if(!sesame){
150
-            return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
152
+            const headerArgs = fnArgs.join(",")
153
+            const argParams = fnArgs.map(stripAfterEquals).join(",")
154
+
155
+            const f = eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
151
                 const r = await this.socket.call("`+fnName+`", `+argParams+`)
156
                 const r = await this.socket.call("`+fnName+`", `+argParams+`)
152
-                if(r.result === 'Success'){
157
+                if(r && r.result === 'Success'){
153
                     this.socket.hook(r.uuid, callback)
158
                     this.socket.hook(r.uuid, callback)
154
                 }
159
                 }
155
                 return r
160
                 return r
156
             } )()` )
161
             } )()` )
162
+            return f
157
         }else{
163
         }else{
164
+
158
             return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
165
             return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
159
                 const r = await this.socket.call("`+fnName+`", "`+sesame+`", `+argParams+`)
166
                 const r = await this.socket.call("`+fnName+`", "`+sesame+`", `+argParams+`)
160
-                if(r.result === 'Success'){
167
+                if(r && r.result === 'Success'){
161
                     this.socket.hook(r.uuid, callback)
168
                     this.socket.hook(r.uuid, callback)
162
                 }
169
                 }
163
                 return r
170
                 return r

+ 20
- 18
src/Utils.ts View File

82
     })
82
     })
83
 }
83
 }
84
 /**
84
 /**
85
- * Utility function to generate {@link HookFunction} from a RPC
85
+ * Utility function to generate {@link HookFunction} from a RPC for backend
86
  * @param rpc The RPC to transform
86
  * @param rpc The RPC to transform
87
  * @returns A {@link HookFunction}
87
  * @returns A {@link HookFunction}
88
  */
88
  */
89
-const hookGenerator = (rpc:T.HookRPC<any, any, any>, sesame?:T.SesameFunction): T.HookInfo['generator'] => { 
89
+const hookGenerator = (rpc:T.HookRPC<any, any, any>, sesameFn?: T.SesameFunction): T.HookInfo['generator'] => { 
90
     const argsArr = extractArgs(rpc.hook)
90
     const argsArr = extractArgs(rpc.hook)
91
-    if(sesame){
92
-        const _sesame = argsArr.shift()
93
-        if(!sesame(_sesame!)){
94
-            throw new Error('Bad sesame')
95
-        }
96
-    }
97
     argsArr.pop() //remove 'callback' from the end
91
     argsArr.pop() //remove 'callback' from the end
98
-    const args = argsArr.join(',')
92
+    const argsStr = argsArr.join(',')
99
 
93
 
100
-    return eval(`(socket) => async (`+args+`) => { 
94
+    if(sesameFn){
95
+        const args = ['sesame', ...argsArr].join(',')
96
+        const f =  eval(`(socket) => async (`+args+`) => {
97
+            if(!sesameFn(sesame)) return
98
+            const res = await rpc.hook(`+argsStr+(argsStr.length!==0?',':'')+` (...cbargs) => {
99
+                if(rpc.onCallback) rpc.onCallback.apply({}, cbargs)
100
+                socket.call.apply(socket, [res.uuid, ...cbargs])
101
+            })
102
+            return res
103
+        }`)
104
+        return f
105
+    }
106
+    const args = argsArr.join(',')
107
+    return eval(`(socket) => async (`+args+`) => {
101
         const res = await rpc.hook(`+args+(args.length!==0?',':'')+` (...cbargs) => {
108
         const res = await rpc.hook(`+args+(args.length!==0?',':'')+` (...cbargs) => {
102
             if(rpc.onCallback) rpc.onCallback.apply({}, cbargs)
109
             if(rpc.onCallback) rpc.onCallback.apply({}, cbargs)
103
             socket.call.apply(socket, [res.uuid, ...cbargs])
110
             socket.call.apply(socket, [res.uuid, ...cbargs])
104
         })
111
         })
105
-        if(res.result === 'Success'){
106
-            if(rpc.onClose){
107
-                socket.on('close', async () => {
108
-                    rpc.onClose(res, rpc)
109
-                })
110
-            }
111
-        }
112
         return res
112
         return res
113
     }`)
113
     }`)
114
 }
114
 }
115
 
115
 
116
+
116
 /**
117
 /**
117
  * Extract a string list of parameters from a function
118
  * Extract a string list of parameters from a function
118
  * @param f The source function
119
  * @param f The source function
134
     }
135
     }
135
 }
136
 }
136
 
137
 
138
+
137
 export function makeSesameFunction (sesame : T.SesameFunction | string) : T.SesameFunction {
139
 export function makeSesameFunction (sesame : T.SesameFunction | string) : T.SesameFunction {
138
     if(typeof sesame === 'function'){
140
     if(typeof sesame === 'function'){
139
         return sesame
141
         return sesame
142
     return (testSesame : string) => {
144
     return (testSesame : string) => {
143
         return testSesame === sesame 
145
         return testSesame === sesame 
144
     }
146
     }
145
-}
147
+}

+ 57
- 8
test/Test.ts View File

1
-import { describe, it } from "mocha";
1
+import { describe, it, Func } from "mocha";
2
 
2
 
3
 import { RPCServer, RPCSocket, SubscriptionResponse, makeSubResponse } from '../Index'
3
 import { RPCServer, RPCSocket, SubscriptionResponse, makeSubResponse } from '../Index'
4
 import * as uuidv4 from "uuid/v4"
4
 import * as uuidv4 from "uuid/v4"
226
 })
226
 })
227
 
227
 
228
 
228
 
229
-type SesameTestIfc = { test: { checkCandy: ()=>Promise<string>} }
229
+type SesameTestIfc = { 
230
+    test: { 
231
+        checkCandy: ()=>Promise<string>
232
+        subscribe: (callback) => Promise<SubscriptionResponse<{ topic: string; }>>
233
+    } 
234
+}
230
 
235
 
231
 describe('Sesame should unlock the socket', () => {
236
 describe('Sesame should unlock the socket', () => {
232
     let candy = "OK"
237
     let candy = "OK"
233
     let client: RPCSocket & SesameTestIfc
238
     let client: RPCSocket & SesameTestIfc
234
-    let server: RPCServer<{topic: string}, SesameTestIfc> 
239
+    let server: RPCServer 
240
+    let cb = (...args) => {}
235
 
241
 
236
     before(async() => {
242
     before(async() => {
237
-        server = new RPCServer<{ topic: string }, SesameTestIfc>(20004, [{
243
+        server = new RPCServer(20004, [{
238
             name: "test",
244
             name: "test",
239
             exportRPCs: () => [
245
             exportRPCs: () => [
240
-                async function checkCandy():Promise<string> { return candy },
246
+                {
247
+                    name: 'subscribe',
248
+                    hook: async(callback) => {
249
+                        cb = callback
250
+                        return <SubscriptionResponse>{
251
+                            result: "Success",
252
+                            uuid: uuidv4(),
253
+                            topic: 'test'
254
+                        }
255
+                    }
256
+                },
257
+                async function checkCandy():Promise<string> { cb(candy); cb=()=>{}; return candy },
241
             ]}
258
             ]}
242
         ],{
259
         ],{
243
             sesame: (_sesame) => _sesame === 'sesame!' 
260
             sesame: (_sesame) => _sesame === 'sesame!' 
251
         server.destroy()
268
         server.destroy()
252
     })
269
     })
253
 
270
 
271
+    it('should work with sesame', (done) => {
272
+        client.test.checkCandy().then(c => done())
273
+    })
274
+
254
     it('should not work without sesame', (done) => {
275
     it('should not work without sesame', (done) => {
255
         const sock = new RPCSocket(20004, "localhost")
276
         const sock = new RPCSocket(20004, "localhost")
256
         sock.connect<SesameTestIfc>( /* no sesame */).then(async (c) => {
277
         sock.connect<SesameTestIfc>( /* no sesame */).then(async (c) => {
264
         })
285
         })
265
     })
286
     })
266
 
287
 
267
-    it('should work with sesame', (done) => {
268
-        client.test.checkCandy().then(c => done())
288
+    it('callback should work with sesame', (done) => {
289
+        client.test.subscribe((c) => {
290
+            if(c === candy){
291
+                done()
292
+            }
293
+        }).then(d => {
294
+            if(d.result !== 'Success')
295
+                done('expected valid response')
296
+
297
+            client.test.checkCandy()
298
+        })
299
+    })
300
+
301
+    it('callback should not work without sesame', (done) => {
302
+        const sock = new RPCSocket(20004, "localhost")
303
+        sock.connect<SesameTestIfc>( /* no sesame */).then(async (c) => {
304
+            c.test.subscribe((c) => {
305
+                console.log("CALLBACK TRIGGERED UNEXPECTED");
306
+                
307
+                if(c === candy)
308
+                    done("super not")
309
+            }).then(async d => {
310
+                await client.test.checkCandy()
311
+                if(d == null){
312
+                    done()
313
+                }else
314
+                    done('unexpected valid response '+(d) )
315
+                c.destroy()
316
+            })
317
+        })
269
     })
318
     })
270
-})
319
+})

Loading…
Cancel
Save