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.

Frontend.ts 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. 'use strict'
  2. var bsock = require('bsock')
  3. import * as T from './Types';
  4. import * as U from './Utils';
  5. import * as I from './Interfaces';
  6. import * as R from './Responses';
  7. export {
  8. T as Types,
  9. U as Utils,
  10. I as Interfaces,
  11. R as Responses
  12. }
  13. //fix args with defaults like "force = true" -> "force"
  14. function stripAfterEquals(str:string){
  15. return str.split("=")[0]
  16. }
  17. export class Client implements I.Socket{
  18. private socket: I.Socket
  19. constructor(public port:number, private server: string, private tls: boolean = false){
  20. }
  21. public hook(name: T.Name, args: T.Arg){
  22. return this.socket.hook(name, args)
  23. }
  24. public unhook(name: T.Name){
  25. return this.socket.unhook(name)
  26. }
  27. public on(type: "error" | "close", f: (e?: any) => void){
  28. return this.socket.on(type, f)
  29. }
  30. public destroy(){
  31. return this.socket.destroy()
  32. }
  33. public close(){
  34. return this.socket.close()
  35. }
  36. public async call (rpcname: T.Name, ...args: T.Any[]) : Promise<T.Any>{
  37. return await this.socket.call.apply(this.socket, [rpcname, ...args])
  38. }
  39. public async fire(rpcname: T.Name, ...args: T.Any[]) : Promise<T.Any>{
  40. return await this.socket.fire.apply(this.socket, [rpcname, ...args])
  41. }
  42. public async connect(){
  43. this.socket = await bsock.connect(this.port, this.server, this.tls)
  44. const info:T.ExtendedRpcInfo[] = await this.info()
  45. info.forEach(i => {
  46. let f: any
  47. switch (i.type) {
  48. case 'Call':
  49. f = this.callGenerator(i.uniqueName, i.argNames)
  50. break
  51. case 'Hook':
  52. f = this.hookGenerator(i.uniqueName, i.argNames)
  53. break
  54. case 'Unhook':
  55. f = this.unhookGenerator(i.uniqueName, i.argNames)
  56. break
  57. }
  58. if(this[i.owner] == null)
  59. this[i.owner] = {}
  60. this[i.owner][i.name] = f
  61. this[i.owner][i.name].bind(this)
  62. })
  63. }
  64. public async info(){
  65. return await this.socket.call('info')
  66. }
  67. private callGenerator(fnName: T.Name, fnArgs:T.Arg[]): T.AsyncFunction{
  68. const headerArgs = fnArgs.join(",")
  69. const argParams = fnArgs.map(stripAfterEquals).join(",")
  70. return eval( '( () => async ('+headerArgs+') => { return await this.socket.call("'+fnName+'", '+argParams+')} )()' )
  71. }
  72. private hookGenerator(fnName: T.Name, fnArgs:T.Arg[]): T.CallbackFunction{
  73. const headerArgs = fnArgs.join(",")
  74. const argParams = fnArgs.map(stripAfterEquals).join(",")
  75. return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
  76. const r = await this.socket.call("`+fnName+`", `+argParams+`)
  77. if(r.uid != null){
  78. this.socket.hook(res.uid, callback)
  79. }
  80. return res
  81. } )()` )
  82. }
  83. private unhookGenerator(fnName: T.Name, fnArgs:T.Arg[]): T.UnhookFunction{
  84. const headerArgs = fnArgs.join(",")
  85. const argParams = fnArgs.map(stripAfterEquals).join(",")
  86. if(fnArgs.length != 1)
  87. console.error("UnhookFunction", fnName, "specified more than one argument: ("+headerArgs+")")
  88. return eval( `( () => async (`+headerArgs+`) => {
  89. const r = await this.socket.call("`+fnName+`", `+argParams+`)
  90. this.socket.unhook(`+argParams+`)
  91. return res
  92. } )()` )
  93. }
  94. }