feat rpc
- architecture tweaks for scalability - added option for global debug logs - added option for cef debug mode to run in browser only
This commit is contained in:
		
							parent
							
								
									640adae8a5
								
							
						
					
					
						commit
						e2e58e100a
					
				| @ -1,9 +1,20 @@ | ||||
| import { Wrapper } from './wrapper' | ||||
| import { Environment, Events, RPCEventType, RPCState, Utils } from './utils' | ||||
| import { | ||||
|     Environment, | ||||
|     Events, | ||||
|     RPCEventType, | ||||
|     RPCState, | ||||
|     RpcWrapperConfig, | ||||
|     Utils, | ||||
| } from './utils' | ||||
| 
 | ||||
| class Browser extends Wrapper { | ||||
|     constructor() { | ||||
|         super() | ||||
| export class Browser extends Wrapper { | ||||
|     constructor( | ||||
|         options: RpcWrapperConfig = { | ||||
|             forceBrowserDevMode: false, | ||||
|         }, | ||||
|     ) { | ||||
|         super(options) | ||||
|     } | ||||
| 
 | ||||
|     public _resolveEmitDestination(dataRaw: string) { | ||||
| @ -65,6 +76,3 @@ class Browser extends Wrapper { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| const browser = new Browser() | ||||
| export { browser } | ||||
|  | ||||
| @ -5,14 +5,19 @@ import { | ||||
|     Events, | ||||
|     RPCEventType, | ||||
|     RPCState, | ||||
|     RpcWrapperConfig, | ||||
|     Utils, | ||||
| } from './utils' | ||||
| 
 | ||||
| class Client extends Wrapper { | ||||
| export class Client extends Wrapper { | ||||
|     private _browser: any = null | ||||
| 
 | ||||
|     constructor() { | ||||
|         super() | ||||
|     constructor( | ||||
|         options: RpcWrapperConfig = { | ||||
|             forceBrowserDevMode: false, | ||||
|         }, | ||||
|     ) { | ||||
|         super(options) | ||||
|     } | ||||
| 
 | ||||
|     set browser(browser: any) { | ||||
| @ -154,6 +159,3 @@ class Client extends Wrapper { | ||||
|         if (!this._browser) throw new Error(Errors.NO_BROWSER) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| const client = new Client() | ||||
| export { client } | ||||
|  | ||||
| @ -5,19 +5,36 @@ import { | ||||
|     Events, | ||||
|     nativeClientEvents, | ||||
|     nativeServerEvents, | ||||
|     type PlayerMp, | ||||
|     RpcConfig, | ||||
|     RPCEventType, | ||||
|     RPCState, | ||||
|     Utils, | ||||
|     type PlayerMp, | ||||
| } from './utils' | ||||
| 
 | ||||
| import { server } from './server' | ||||
| import { client } from './client' | ||||
| import { browser } from './browser' | ||||
| import { Server } from './server' | ||||
| import { Client } from './client' | ||||
| import { Browser } from './browser' | ||||
| 
 | ||||
| class Rpc extends Wrapper { | ||||
|     constructor() { | ||||
|         super() | ||||
|     private _server: Server | ||||
|     private _client: Client | ||||
|     private _browser: Browser | ||||
| 
 | ||||
|     constructor( | ||||
|         options: RpcConfig = { | ||||
|             forceBrowserDevMode: false, | ||||
|             debugLogs: false, | ||||
|         }, | ||||
|     ) { | ||||
|         super(options) | ||||
| 
 | ||||
|         this._server = new Server(options) | ||||
|         this._client = new Client(options) | ||||
|         this._browser = new Browser(options) | ||||
|         this.debug_ = !!options.debugLogs | ||||
| 
 | ||||
|         if (options.forceBrowserDevMode) return | ||||
| 
 | ||||
|         if (this.environment_ === Environment.UNKNOWN) | ||||
|             throw new Error(Errors.UNKNOWN_ENVIRONMENT) | ||||
| @ -27,7 +44,7 @@ class Rpc extends Wrapper { | ||||
|             async (player: PlayerMp | string, dataRaw: string) => { | ||||
|                 switch (this.environment_) { | ||||
|                     case Environment.SERVER: | ||||
|                         server._resolveEmitDestination( | ||||
|                         this._server._resolveEmitDestination( | ||||
|                             player as PlayerMp, | ||||
|                             dataRaw, | ||||
|                         ) | ||||
| @ -35,12 +52,12 @@ class Rpc extends Wrapper { | ||||
| 
 | ||||
|                     case Environment.CLIENT: | ||||
|                         dataRaw = player as string | ||||
|                         client._resolveEmitDestination(dataRaw) | ||||
|                         this._client._resolveEmitDestination(dataRaw) | ||||
|                         break | ||||
| 
 | ||||
|                     case Environment.BROWSER: | ||||
|                         dataRaw = player as string | ||||
|                         browser._resolveEmitDestination(dataRaw) | ||||
|                         this._browser._resolveEmitDestination(dataRaw) | ||||
|                         break | ||||
| 
 | ||||
|                     default: | ||||
| @ -51,6 +68,10 @@ class Rpc extends Wrapper { | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     set browser(browser: any) { | ||||
|         this._client.browser = browser | ||||
|     } | ||||
| 
 | ||||
|     public register< | ||||
|         CallbackArguments extends unknown[] = unknown[], | ||||
|         CallbackReturn extends unknown = unknown, | ||||
| @ -59,6 +80,8 @@ class Rpc extends Wrapper { | ||||
|         eventName: EventName, | ||||
|         cb: (...args: CallbackArguments) => CallbackReturn, | ||||
|     ): void { | ||||
|         this.log('register', eventName, cb) | ||||
|         if (this.forceBrowserDevMode_) return | ||||
|         Utils.errorUnknownEnvironment(this.environment_) | ||||
| 
 | ||||
|         if ( | ||||
| @ -76,6 +99,8 @@ class Rpc extends Wrapper { | ||||
|     public unregister<EventName extends string = string>( | ||||
|         eventName: EventName, | ||||
|     ): void { | ||||
|         this.log('unregister', eventName) | ||||
|         if (this.forceBrowserDevMode_) return | ||||
|         Utils.errorUnknownEnvironment(this.environment_) | ||||
| 
 | ||||
|         delete this.state_[eventName] | ||||
| @ -96,6 +121,20 @@ class Rpc extends Wrapper { | ||||
|         eventNameOrArgs?: string | unknown[], | ||||
|         args?: unknown[], | ||||
|     ) { | ||||
|         _is1StParamPlayer(playerOrEventName) | ||||
|             ? this.log( | ||||
|                   'callClient', | ||||
|                   eventNameOrArgs as string, | ||||
|                   playerOrEventName, | ||||
|                   eventNameOrArgs, | ||||
|                   args, | ||||
|               ) | ||||
|             : this.log( | ||||
|                   'callClient', | ||||
|                   playerOrEventName as string, | ||||
|                   eventNameOrArgs, | ||||
|               ) | ||||
|         if (this.forceBrowserDevMode_) return | ||||
|         Utils.errorUnknownEnvironment(this.environment_) | ||||
| 
 | ||||
|         function _is1StParamPlayer(x: unknown): x is PlayerMp { | ||||
| @ -105,8 +144,8 @@ class Rpc extends Wrapper { | ||||
|             return typeof x === 'string' | ||||
|         } | ||||
| 
 | ||||
|         // client
 | ||||
|         if (this.environment_ === Environment.CLIENT) { | ||||
|             // client
 | ||||
|             return await this.call( | ||||
|                 playerOrEventName as string, | ||||
|                 args as unknown[], | ||||
| @ -163,6 +202,9 @@ class Rpc extends Wrapper { | ||||
|         EventName extends string = string, | ||||
|         Return extends unknown = unknown, | ||||
|     >(eventName: EventName, args?: Arguments): Promise<Return> { | ||||
|         this.log('callServer', eventName, args) | ||||
|         if (this.forceBrowserDevMode_) | ||||
|             return undefined as unknown as Promise<Return> | ||||
|         Utils.errorUnknownEnvironment(this.environment_) | ||||
| 
 | ||||
|         const state: RPCState = { | ||||
| @ -208,6 +250,20 @@ class Rpc extends Wrapper { | ||||
|         eventNameOrArgs?: string | unknown[], | ||||
|         args?: unknown[], | ||||
|     ) { | ||||
|         _is1StParamPlayer(playerOrEventName) | ||||
|             ? this.log( | ||||
|                   'DEV callClient', | ||||
|                   eventNameOrArgs as string, | ||||
|                   playerOrEventName, | ||||
|                   eventNameOrArgs, | ||||
|                   args, | ||||
|               ) | ||||
|             : this.log( | ||||
|                   'DEV callClient', | ||||
|                   playerOrEventName as string, | ||||
|                   eventNameOrArgs, | ||||
|               ) | ||||
|         if (this.forceBrowserDevMode_) return | ||||
|         Utils.errorUnknownEnvironment(this.environment_) | ||||
| 
 | ||||
|         function _is1StParamPlayer(x: unknown): x is PlayerMp { | ||||
| @ -257,6 +313,9 @@ class Rpc extends Wrapper { | ||||
|         EventName extends string = string, | ||||
|         Return extends unknown = unknown, | ||||
|     >(eventName: EventName, args?: Arguments): Promise<Return> { | ||||
|         this.log('call', eventName, args) | ||||
|         if (this.forceBrowserDevMode_) | ||||
|             return undefined as unknown as Promise<Return> | ||||
|         Utils.errorUnknownEnvironment(this.environment_) | ||||
| 
 | ||||
|         let state: RPCState = { | ||||
| @ -332,6 +391,4 @@ class Rpc extends Wrapper { | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| const rpc = new Rpc() | ||||
| export { rpc, client } | ||||
| export { Rpc } | ||||
|  | ||||
| @ -5,12 +5,19 @@ import { | ||||
|     type PlayerMp, | ||||
|     RPCEventType, | ||||
|     RPCState, | ||||
|     RpcWrapperConfig, | ||||
|     Utils, | ||||
| } from './utils' | ||||
| 
 | ||||
| class Server extends Wrapper { | ||||
|     constructor() { | ||||
|         super() | ||||
| export class Server extends Wrapper { | ||||
|     constructor( | ||||
|         options: RpcWrapperConfig = { | ||||
|             forceBrowserDevMode: false, | ||||
|         }, | ||||
|     ) { | ||||
|         super(options) | ||||
| 
 | ||||
|         if (!!options.forceBrowserDevMode) return | ||||
| 
 | ||||
|         mp.events.add( | ||||
|             Events.SERVER_EVENT_LISTENER, | ||||
| @ -84,6 +91,3 @@ class Server extends Wrapper { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| const server = new Server() | ||||
| export { server } | ||||
|  | ||||
| @ -18,6 +18,28 @@ export enum Errors { | ||||
|     EVENT_RESPONSE_TIMEOUT = 'Response was timed out after 10s of inactivity', | ||||
| } | ||||
| 
 | ||||
| export type RPCState = { | ||||
|     eventName: string | ||||
|     uuid: string | ||||
|     calledFrom: Environment | ||||
|     calledTo: Environment | ||||
|     knownError?: string | ||||
|     data?: any | ||||
|     type: RPCEventType | ||||
| } | ||||
| 
 | ||||
| export type PlayerMp = { | ||||
|     call: (event: string, args?: unknown[]) => void | ||||
| } | ||||
| 
 | ||||
| export interface RpcWrapperConfig { | ||||
|     forceBrowserDevMode?: boolean | ||||
| } | ||||
| 
 | ||||
| export interface RpcConfig extends RpcWrapperConfig { | ||||
|     debugLogs?: boolean | ||||
| } | ||||
| 
 | ||||
| export class Utils { | ||||
|     public static getEnvironment(): Environment { | ||||
|         if ('joaat' in mp) return Environment.SERVER | ||||
| @ -67,25 +89,11 @@ export class Utils { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export type RPCState = { | ||||
|     eventName: string | ||||
|     uuid: string | ||||
|     calledFrom: Environment | ||||
|     calledTo: Environment | ||||
|     knownError?: string | ||||
|     data?: any | ||||
|     type: RPCEventType | ||||
| } | ||||
| 
 | ||||
| export enum RPCEventType { | ||||
|     EVENT = 'event', | ||||
|     RESPONSE = 'response', | ||||
| } | ||||
| 
 | ||||
| export type PlayerMp = { | ||||
|     call: (event: string, args?: unknown[]) => void | ||||
| } | ||||
| 
 | ||||
| export const nativeClientEvents = new Set([ | ||||
|     'browserCreated', | ||||
|     'browserDomReady', | ||||
|  | ||||
| @ -1,9 +1,31 @@ | ||||
| import { Environment, Errors, RPCState, Utils } from './utils' | ||||
| import { Environment, Errors, RPCState, RpcWrapperConfig, Utils } from './utils' | ||||
| 
 | ||||
| export class Wrapper { | ||||
|     protected environment_ = Utils.getEnvironment() | ||||
|     protected state_ = | ||||
|         this.environment_ === Environment.BROWSER ? window : global | ||||
|     protected environment_ = Environment.UNKNOWN | ||||
|     protected state_: any | ||||
|     protected console_ = | ||||
|         this.environment_ === Environment.CLIENT | ||||
|             ? mp.console.logInfo | ||||
|             : console.log | ||||
|     protected debug_ = false | ||||
|     protected forceBrowserDevMode_ = false | ||||
| 
 | ||||
|     constructor( | ||||
|         options: RpcWrapperConfig = { | ||||
|             forceBrowserDevMode: false, | ||||
|         }, | ||||
|     ) { | ||||
|         if (options.forceBrowserDevMode) { | ||||
|             this.environment_ = Environment.UNKNOWN | ||||
|             this.state_ = window | ||||
|         } else { | ||||
|             this.environment_ = Utils.getEnvironment() | ||||
|             this.state_ = | ||||
|                 this.environment_ === Environment.BROWSER ? window : global | ||||
|         } | ||||
| 
 | ||||
|         this.forceBrowserDevMode_ = !!options.forceBrowserDevMode | ||||
|     } | ||||
| 
 | ||||
|     protected verifyEvent_(data: string | RPCState): RPCState { | ||||
|         let rpcData = | ||||
| @ -30,4 +52,9 @@ export class Wrapper { | ||||
| 
 | ||||
|         throw new Error(errorMessage.join('\n | ')) | ||||
|     } | ||||
| 
 | ||||
|     protected log(method: string, eventName: string, ...args: unknown[]): void { | ||||
|         if (this.debug_) | ||||
|             this.console_('RPC | [' + method + '] ' + eventName + ':', ...args) | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user