Переглянути джерело

tempalte strings & bugfixes

master
peter 4 роки тому
джерело
коміт
d36f2053c3
3 змінених файлів з 67 додано та 67 видалено
  1. 18
    25
      src/Frontend.ts
  2. 24
    27
      src/Utils.ts
  3. 25
    15
      test/Test.ts

+ 18
- 25
src/Frontend.ts Переглянути файл

4
 
4
 
5
 import * as T from './Types'; 
5
 import * as T from './Types'; 
6
 import * as I from './Interfaces';
6
 import * as I from './Interfaces';
7
-import { stripAfterEquals } from './Utils';
7
+import { stripAfterEquals, appendComma } from './Utils';
8
 
8
 
9
 
9
 
10
 
10
 
127
     private callGenerator(fnName: string, fnArgs:string[], sesame?:string): T.AnyFunction{
127
     private callGenerator(fnName: string, fnArgs:string[], sesame?:string): T.AnyFunction{
128
         const headerArgs = fnArgs.join(",")
128
         const headerArgs = fnArgs.join(",")
129
         const argParams = fnArgs.map(stripAfterEquals).join(",")
129
         const argParams = fnArgs.map(stripAfterEquals).join(",")
130
-        if(!sesame)
131
-            return eval( '( () => async ('+headerArgs+') => { return await this.socket.call("'+fnName+'", '+argParams+')} )()' )
132
-        else 
133
-            return eval( '( () => async ('+headerArgs+') => { return await this.socket.call("'+fnName+'", "'+sesame+'", '+argParams+')} )()' )
130
+        sesame = appendComma(sesame)
131
+
132
+        return eval(`async (${headerArgs}) => { return await this.socket.call("${fnName}", ${sesame} ${argParams})}`)
134
     }
133
     }
135
 
134
 
136
     /**
135
     /**
140
      */
139
      */
141
     private frontEndHookGenerator(fnName: string, fnArgs:string[], sesame?:string): T.HookFunction{
140
     private frontEndHookGenerator(fnName: string, fnArgs:string[], sesame?:string): T.HookFunction{
142
         fnArgs.pop()
141
         fnArgs.pop()
143
-        const headerArgs = fnArgs.join(",")
142
+        let headerArgs = fnArgs.join(",")
144
         const argParams = fnArgs.map(stripAfterEquals).join(",")
143
         const argParams = fnArgs.map(stripAfterEquals).join(",")
145
-
146
-        if(!sesame){
147
-            return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
148
-                const r = await this.socket.call("`+fnName+`", `+argParams+`)
149
-                if(r && r.result === 'Success'){
150
-                    this.socket.hook(r.uuid, callback)
151
-                }
152
-                return r
153
-            } )()` )
154
-        }else{
155
-            return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
156
-                const r = await this.socket.call("`+fnName+`", "`+sesame+`", `+argParams+`)
157
-                if(r && r.result === 'Success'){
158
-                    this.socket.hook(r.uuid, callback)
159
-                }
160
-                return r
161
-            } )()` )
162
-        }
144
+        sesame = appendComma(sesame)
145
+        headerArgs = appendComma(headerArgs) 
146
+
147
+        return eval( `
148
+        async (${headerArgs} callback) => {
149
+            const r = await this.socket.call("${fnName}", ${sesame} ${argParams})
150
+            if(r && r.result === 'Success'){
151
+                this.socket.hook(r.uuid, callback)
152
+                this.socket.on('error', e => this.socket.unhook(r.uuid))
153
+            }
154
+            return r
155
+        }`)
163
     }
156
     }
164
-}
157
+}

+ 24
- 27
src/Utils.ts Переглянути файл

10
  * @param owner The owning RPC group's name
10
  * @param owner The owning RPC group's name
11
  * @throws Error on RPC without name property
11
  * @throws Error on RPC without name property
12
  */
12
  */
13
-export const rpcToRpcinfo = <SubResT = {}>(rpc : T.RPC<any, any, SubResT>, owner: string, errorHandler: T.ErrorHandler, sesame?:T.SesameFunction):T.RpcInfo => {
13
+export const rpcToRpcinfo = <SubResT = {}>(socket: I.Socket, rpc : T.RPC<any, any, SubResT>, owner: string, errorHandler: T.ErrorHandler, sesame?:T.SesameFunction):T.RpcInfo => {
14
     switch (typeof rpc){
14
     switch (typeof rpc){
15
         case  "object":
15
         case  "object":
16
             if(rpc['call']){
16
             if(rpc['call']){
19
                     argNames: extractArgs(rpc['call']),
19
                     argNames: extractArgs(rpc['call']),
20
                     type: "Call",
20
                     type: "Call",
21
                     name: rpc.name,
21
                     name: rpc.name,
22
-                    call: sesame?async (_sesame, ...args) => {if(sesame(_sesame)) return await rpc['call'].apply({}, args); throw makeError(rpc.name)}:rpc['call'], // check & remove sesame 
22
+                    call: sesame?async (_sesame, ...args) => {if(sesame(_sesame)) return await rpc['call'].apply({}, args); socket.destroy()}:rpc['call'], // check & remove sesame 
23
                 }
23
                 }
24
             }else{
24
             }else{
25
                 const generator = hookGenerator(<T.HookRPC<any, any, any>>rpc, errorHandler, sesame)
25
                 const generator = hookGenerator(<T.HookRPC<any, any, any>>rpc, errorHandler, sesame)
37
 \nUse 'funtion name(..){ .. }' syntax instead.
37
 \nUse 'funtion name(..){ .. }' syntax instead.
38
 \n
38
 \n
39
 \n<------------OFFENDING RPC:
39
 \n<------------OFFENDING RPC:
40
-\n`+rpc.toString()+`
40
+\n${rpc.toString()}
41
 \n>------------OFFENDING RPC`)
41
 \n>------------OFFENDING RPC`)
42
             return {
42
             return {
43
                 owner : owner,
43
                 owner : owner,
61
     const RPCs = [...exporter.exportRPCs()]
61
     const RPCs = [...exporter.exportRPCs()]
62
 
62
 
63
 
63
 
64
-    return RPCs.map(rpc => rpcToRpcinfo(rpc, owner, errorHandler, sesame))
64
+    return RPCs.map(rpc => rpcToRpcinfo(socket, rpc, owner, errorHandler, sesame))
65
     .map(info => {
65
     .map(info => {
66
         const suffix = makeUnique?"-"+uuidv4().substr(0,4):""
66
         const suffix = makeUnique?"-"+uuidv4().substr(0,4):""
67
         const ret:any = info
67
         const ret:any = info
111
  * @returns A {@link HookFunction}
111
  * @returns A {@link HookFunction}
112
  */
112
  */
113
 const hookGenerator = (rpc:T.HookRPC<any, any, any>, errorHandler: T.ErrorHandler, sesameFn?: T.SesameFunction): T.HookInfo['generator'] => { 
113
 const hookGenerator = (rpc:T.HookRPC<any, any, any>, errorHandler: T.ErrorHandler, sesameFn?: T.SesameFunction): T.HookInfo['generator'] => { 
114
-    const argsArr = extractArgs(rpc.hook)
114
+    let argsArr = extractArgs(rpc.hook)
115
     argsArr.pop() //remove 'callback' from the end
115
     argsArr.pop() //remove 'callback' from the end
116
-    const argsStr = argsArr.join(',')
117
-
118
-    if(sesameFn){
119
-        const args = ['sesame', ...argsArr].join(',')
120
-        return eval(`(socket) => async (`+args+`) => {
121
-            try{
122
-                if(!sesameFn(sesame)) return
123
-                const res = await rpc.hook(`+argsStr+(argsStr.length!==0?',':'')+` (...cbargs) => {
124
-                    if(rpc.onCallback) rpc.onCallback.apply({}, cbargs)
125
-                    socket.call.apply(socket, [res.uuid, ...cbargs])
126
-                })
127
-                return res
128
-            }catch(e){
129
-                errorHandler(socket)(e, rpc.name, [`+args+`])
130
-            }
131
-        }`)
132
-    }
133
-    const args = argsArr.join(',')
134
-    return eval(`(socket) => async (`+args+`) => {
116
+    let callArgs = argsArr.join(',')
117
+
118
+    const args = sesameFn?(['sesame', ...argsArr].join(','))
119
+                         :callArgs
120
+
121
+    callArgs = appendComma(callArgs)
122
+
123
+    //note rpc.hook is the associated RPC, not a socket.hook
124
+    return eval(`
125
+    (socket) => async (${args}) => {
135
         try{
126
         try{
136
-            const res = await rpc.hook(`+args+(args.length!==0?',':'')+` (...cbargs) => {
127
+            if(sesameFn && !sesameFn(sesame)) return
128
+            const res = await rpc.hook(${callArgs} (...cbargs) => {
137
                 if(rpc.onCallback) rpc.onCallback.apply({}, cbargs)
129
                 if(rpc.onCallback) rpc.onCallback.apply({}, cbargs)
138
                 socket.call.apply(socket, [res.uuid, ...cbargs])
130
                 socket.call.apply(socket, [res.uuid, ...cbargs])
139
             })
131
             })
140
             return res
132
             return res
141
         }catch(e){
133
         }catch(e){
142
-            errorHandler(socket)(e, rpc.name, [`+args+`])
134
+            errorHandler(socket)(e, ${rpc.name}, [${args}])
143
         }
135
         }
144
     }`)
136
     }`)
145
 }
137
 }
146
 
138
 
147
 const makeError = (callName: string) => {
139
 const makeError = (callName: string) => {
148
-    return new Error("Unhandled Promise rejection: Call not found: "+callName+". ; Zone: <root> ; Task: Promise.then ; Value: Error: Call not found: "+callName)
140
+    return new Error("Call not found: "+callName+". ; Zone: <root> ; Task: Promise.then ; Value: Error: Call not found: "+callName)
149
 }
141
 }
150
 
142
 
151
 /**
143
 /**
179
         return testSesame === sesame 
171
         return testSesame === sesame 
180
     }
172
     }
181
 }
173
 }
174
+
175
+
176
+export function appendComma(s?:string):string{
177
+    return s?`'${s}',`:"" 
178
+}

+ 25
- 15
test/Test.ts Переглянути файл

48
 describe('RPCServer', () => {
48
 describe('RPCServer', () => {
49
     let server: RPCServer<{ topic: string }, any>
49
     let server: RPCServer<{ topic: string }, any>
50
 
50
 
51
-    before((done) => {
51
+    before(() => {
52
         server = makeServer()
52
         server = makeServer()
53
-        done()
54
     })
53
     })
55
     
54
     
56
-    after(async() => {
57
-        await server.destroy()
55
+    after(() => {
56
+        server.destroy()
58
     })
57
     })
59
 
58
 
60
     it('should be able to use all kinds of RPC definitions', (done) => {
59
     it('should be able to use all kinds of RPC definitions', (done) => {
239
     let server: RPCServer 
238
     let server: RPCServer 
240
     let cb = (...args) => {}
239
     let cb = (...args) => {}
241
 
240
 
242
-    before(async() => {
241
+    before((done) => {
243
         server = new RPCServer(21004, [{
242
         server = new RPCServer(21004, [{
244
             name: "test",
243
             name: "test",
245
             exportRPCs: () => [
244
             exportRPCs: () => [
261
             sesame: (_sesame) => _sesame === 'sesame!' 
260
             sesame: (_sesame) => _sesame === 'sesame!' 
262
         })
261
         })
263
         const sock = new RPCSocket(21004, "localhost")
262
         const sock = new RPCSocket(21004, "localhost")
264
-        client = await sock.connect<SesameTestIfc>('sesame!')
263
+        sock.connect<SesameTestIfc>('sesame!').then(cli => {
264
+            client = cli
265
+            done() 
266
+        })
265
     })
267
     })
266
 
268
 
267
     after(() => {
269
     after(() => {
282
 
284
 
283
     it('should not work without sesame', (done) => {
285
     it('should not work without sesame', (done) => {
284
         const sock = new RPCSocket(21004, "localhost")
286
         const sock = new RPCSocket(21004, "localhost")
285
-        sock.connect<SesameTestIfc>( /* no sesame */).then(async (c) => {
286
-            c.test.checkCandy().then(d => {
287
-                done()
287
+        sock.connect<SesameTestIfc>( /* no sesame */).then(async (cli) => {
288
+            cli.test.checkCandy().then(d => {
289
+                done(d)
288
             }).catch(e => {
290
             }).catch(e => {
289
                 //console.log("EXPECTED CLIENT EXCEPTION", String(e));
291
                 //console.log("EXPECTED CLIENT EXCEPTION", String(e));
290
                 done()
292
                 done()
291
             }).finally(() => {
293
             }).finally(() => {
294
+                cli.destroy()
292
                 sock.destroy()
295
                 sock.destroy()
293
             })
296
             })
294
         })
297
         })
296
 
299
 
297
     it('should fail with wrong sesame', (done) => {
300
     it('should fail with wrong sesame', (done) => {
298
         const sock = new RPCSocket(21004, "localhost")
301
         const sock = new RPCSocket(21004, "localhost")
299
-        sock.connect<SesameTestIfc>('abasd').then(async (c) => {
300
-            c.test.checkCandy().then(d => {
302
+        sock.connect<SesameTestIfc>('abasd').then(async (cli) => {
303
+            cli.test.checkCandy().then(d => {
301
                 done("should not be able to get candy")
304
                 done("should not be able to get candy")
302
             }).catch(e => {
305
             }).catch(e => {
303
                 //console.log("EXPECTED CLIENT EXCEPTION", String(e));
306
                 //console.log("EXPECTED CLIENT EXCEPTION", String(e));
304
                 done()
307
                 done()
305
             }).finally(() => {
308
             }).finally(() => {
306
                 sock.destroy()
309
                 sock.destroy()
310
+                cli.destroy()
307
             })
311
             })
308
         })
312
         })
309
     })
313
     })
323
 
327
 
324
     it('callback should not work without sesame', (done) => {
328
     it('callback should not work without sesame', (done) => {
325
         const sock = new RPCSocket(21004, "localhost")
329
         const sock = new RPCSocket(21004, "localhost")
326
-        sock.connect<SesameTestIfc>( /* no sesame */).then(async (c) => {
327
-            c.test.subscribe((c) => {
330
+        sock.connect<SesameTestIfc>( /* no sesame */).then(async (cli) => {
331
+            cli.test.subscribe((c) => {
328
                 console.log("CALLBACK TRIGGERED UNEXPECTED");
332
                 console.log("CALLBACK TRIGGERED UNEXPECTED");
329
                 
333
                 
330
                 if(c === candy)
334
                 if(c === candy)
333
                 await client.test.checkCandy()
337
                 await client.test.checkCandy()
334
                 if(d == null){
338
                 if(d == null){
335
                     done()
339
                     done()
340
+
336
                 }else
341
                 }else
337
                     done('unexpected valid response '+(d) )
342
                     done('unexpected valid response '+(d) )
338
-                c.destroy()
343
+            }).finally(() => {
344
+                sock.destroy()
339
             })
345
             })
340
         })
346
         })
341
     })
347
     })
342
 })
348
 })
343
 
349
 
344
 
350
 
345
-
346
 describe('Error handling', ()=>{
351
 describe('Error handling', ()=>{
347
     
352
     
348
     let createUser = async( user: {a:any,b:any}) => {
353
     let createUser = async( user: {a:any,b:any}) => {
374
                 done()
379
                 done()
375
             })
380
             })
376
             .finally(() => {
381
             .finally(() => {
382
+                cli.destroy()
377
                 sock.destroy()
383
                 sock.destroy()
378
                 server.destroy()
384
                 server.destroy()
379
             })
385
             })
407
                 done(e)
413
                 done(e)
408
             })
414
             })
409
             .finally(() => {
415
             .finally(() => {
416
+                cli.destroy()
410
                 sock.destroy()
417
                 sock.destroy()
411
                 server.destroy()
418
                 server.destroy()
412
             })
419
             })
414
     })
421
     })
415
 })
422
 })
416
 
423
 
424
+
417
 describe("Errorhandler functionality", ()=>{
425
 describe("Errorhandler functionality", ()=>{
418
     let createUser = async( user: {a:any,b:any}) => {
426
     let createUser = async( user: {a:any,b:any}) => {
419
         throw new Error("BAD BAD BAD")
427
         throw new Error("BAD BAD BAD")
447
                 done(e)
455
                 done(e)
448
             })
456
             })
449
             .finally(() => {
457
             .finally(() => {
458
+                cli.destroy()
450
                 sock.destroy()
459
                 sock.destroy()
451
                 server.destroy()
460
                 server.destroy()
452
             })
461
             })
484
                 done(e)
493
                 done(e)
485
             })
494
             })
486
             .finally(() => {
495
             .finally(() => {
496
+                cli.destroy()
487
                 sock.destroy()
497
                 sock.destroy()
488
                 server.destroy()
498
                 server.destroy()
489
             })
499
             })

Завантаження…
Відмінити
Зберегти