Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

Frontend.ts 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. 'use strict'
  2. import bsock = require('bsock');
  3. import * as T from './Types';
  4. import * as I from './Interfaces';
  5. //fix args with defaults like "force = true" -> "force"
  6. function stripAfterEquals(str:string){
  7. return str.split("=")[0]
  8. }
  9. export class RPCSocket implements I.Socket{
  10. private socket: I.Socket
  11. constructor(public port:number, private server: string, private tls: boolean = false){
  12. Object.defineProperty(this, 'socket', {value: undefined, writable: true})
  13. }
  14. public hook(name: T.Name, handler: (...args:any[]) => any | Promise<any>){
  15. return this.socket.hook(name, handler)
  16. }
  17. public unhook(name: T.Name){
  18. return this.socket.unhook(name)
  19. }
  20. public on(type: "error" | "close", f: (e?: any) => void){
  21. return this.socket.on(type, f)
  22. }
  23. public destroy(){
  24. return this.socket.destroy()
  25. }
  26. public close(){
  27. return this.socket.close()
  28. }
  29. public async call (rpcname: T.Name, ...args: T.Any[]) : Promise<T.Any>{
  30. return await this.socket.call.apply(this.socket, [rpcname, ...args])
  31. }
  32. public async fire(rpcname: T.Name, ...args: T.Any[]) : Promise<T.Any>{
  33. return await this.socket.fire.apply(this.socket, [rpcname, ...args])
  34. }
  35. public async connect(){
  36. this.socket = await bsock.connect(this.port, this.server, this.tls)
  37. const info:T.ExtendedRpcInfo[] = await this.info()
  38. info.forEach(i => {
  39. let f: any
  40. switch (i.type) {
  41. case 'Call':
  42. f = this.callGenerator(i.uniqueName, i.argNames)
  43. break
  44. case 'Hook':
  45. f = this.hookGenerator(i.uniqueName, i.argNames)
  46. break
  47. }
  48. if(this[i.owner] == null)
  49. this[i.owner] = {}
  50. this[i.owner][i.name] = f
  51. this[i.owner][i.name].bind(this)
  52. })
  53. }
  54. public async info(){
  55. return await this.socket.call('info')
  56. }
  57. private callGenerator(fnName: T.Name, fnArgs:T.Arg[]): T.AsyncFunction{
  58. const headerArgs = fnArgs.join(",")
  59. const argParams = fnArgs.map(stripAfterEquals).join(",")
  60. return eval( '( () => async ('+headerArgs+') => { return await this.socket.call("'+fnName+'", '+argParams+')} )()' )
  61. }
  62. private hookGenerator(fnName: T.Name, fnArgs:T.Arg[]): T.HookFunction{
  63. const headerArgs = fnArgs.join(",")
  64. const argParams = fnArgs.map(stripAfterEquals).join(",")
  65. return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
  66. const r = await this.socket.call("`+fnName+`", `+argParams+`)
  67. if(r.result === 'Success'){
  68. this.socket.hook(r.uuid, callback)
  69. }
  70. return r
  71. } )()` )
  72. }
  73. }