You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Utils.ts 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import * as uuid from "uuid/v4"
  2. import * as T from "./Types";
  3. import * as I from "./Interfaces";
  4. export const rpcToRpcinfo = (rpc : T.RPC, owner: T.Owner):T.RpcInfo => {
  5. switch(rpc.type){
  6. case "Call" :
  7. return {
  8. owner: owner,
  9. argNames: extractArgs(rpc.call),
  10. type: rpc.type,
  11. name: rpc.name,
  12. call: rpc.call,
  13. }
  14. case "Unhook" :
  15. return {
  16. owner: owner,
  17. argNames: extractArgs(rpc.unhook),
  18. type: rpc.type,
  19. name: rpc.name,
  20. unhook: rpc.unhook,
  21. }
  22. case "Hook" :
  23. const generator = hookGenerator(rpc)
  24. return {
  25. owner: owner,
  26. argNames: extractArgs(generator(undefined)),
  27. type: rpc.type,
  28. name: rpc.name,
  29. unhook: rpc.unhook,
  30. generator: generator,
  31. }
  32. }
  33. }
  34. export function rpcHooker(socket: I.Socket, exporter:I.Exporter, makeUnique = true):T.ExtendedRpcInfo[]{
  35. const owner = exporter.name
  36. const RPCs = [...exporter.publicRPCs(), ...exporter.localRPCs()]
  37. const suffix = makeUnique?"-"+uuid().substr(0,4):""
  38. return RPCs.map(rpc => rpcToRpcinfo(rpc, owner))
  39. .map(info => {
  40. const ret:any = info
  41. ret.uniqueName = info.name+suffix
  42. switch(info.type){
  43. case "Hook":
  44. socket.hook(ret.uniqueName, info.generator(socket))
  45. break;
  46. case "Unhook":
  47. socket.hook(ret.uniqueName, info.unhook)
  48. break;
  49. case "Call":
  50. socket.hook(ret.uniqueName, info.call)
  51. break;
  52. }
  53. socket.on('close', () => socket.unhook(info.name))
  54. return ret
  55. })
  56. }
  57. const hookGenerator = (rpc:T.HookRPC): T.HookInfo['generator'] => {
  58. const argsArr = extractArgs(rpc.clbk)
  59. argsArr.pop()
  60. const args = argsArr.join(',')
  61. return eval(`(socket) => async (`+args+`) => {
  62. const res = await rpc.clbk(`+args+(args.length!==0?',':'')+` (x) => {
  63. socket.call(res.uid, x)
  64. })
  65. if(res.result == 'Success'){
  66. socket.on('close', async () => {
  67. const unhookRes = await rpc.unhook(res.uid)
  68. console.log("Specific close handler for", rpc.name, res.uid, unhookRes)
  69. })
  70. }
  71. return res
  72. }`)
  73. }
  74. const extractArgs = (f:Function):T.Arg[] => {
  75. let fn = String(f)
  76. let args = fn.substr(0, fn.indexOf(")"))
  77. args = args.substr(fn.indexOf("(")+1)
  78. let ret = args.split(",")
  79. return ret
  80. }