- 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:
Danya H 2024-10-27 14:53:55 +00:00
parent 640adae8a5
commit e2e58e100a
6 changed files with 156 additions and 50 deletions

View File

@ -1,9 +1,20 @@
import { Wrapper } from './wrapper' 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 { export class Browser extends Wrapper {
constructor() { constructor(
super() options: RpcWrapperConfig = {
forceBrowserDevMode: false,
},
) {
super(options)
} }
public _resolveEmitDestination(dataRaw: string) { public _resolveEmitDestination(dataRaw: string) {
@ -65,6 +76,3 @@ class Browser extends Wrapper {
} }
} }
} }
const browser = new Browser()
export { browser }

View File

@ -5,14 +5,19 @@ import {
Events, Events,
RPCEventType, RPCEventType,
RPCState, RPCState,
RpcWrapperConfig,
Utils, Utils,
} from './utils' } from './utils'
class Client extends Wrapper { export class Client extends Wrapper {
private _browser: any = null private _browser: any = null
constructor() { constructor(
super() options: RpcWrapperConfig = {
forceBrowserDevMode: false,
},
) {
super(options)
} }
set browser(browser: any) { set browser(browser: any) {
@ -154,6 +159,3 @@ class Client extends Wrapper {
if (!this._browser) throw new Error(Errors.NO_BROWSER) if (!this._browser) throw new Error(Errors.NO_BROWSER)
} }
} }
const client = new Client()
export { client }

View File

@ -5,19 +5,36 @@ import {
Events, Events,
nativeClientEvents, nativeClientEvents,
nativeServerEvents, nativeServerEvents,
type PlayerMp,
RpcConfig,
RPCEventType, RPCEventType,
RPCState, RPCState,
Utils, Utils,
type PlayerMp,
} from './utils' } from './utils'
import { server } from './server' import { Server } from './server'
import { client } from './client' import { Client } from './client'
import { browser } from './browser' import { Browser } from './browser'
class Rpc extends Wrapper { class Rpc extends Wrapper {
constructor() { private _server: Server
super() 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) if (this.environment_ === Environment.UNKNOWN)
throw new Error(Errors.UNKNOWN_ENVIRONMENT) throw new Error(Errors.UNKNOWN_ENVIRONMENT)
@ -27,7 +44,7 @@ class Rpc extends Wrapper {
async (player: PlayerMp | string, dataRaw: string) => { async (player: PlayerMp | string, dataRaw: string) => {
switch (this.environment_) { switch (this.environment_) {
case Environment.SERVER: case Environment.SERVER:
server._resolveEmitDestination( this._server._resolveEmitDestination(
player as PlayerMp, player as PlayerMp,
dataRaw, dataRaw,
) )
@ -35,12 +52,12 @@ class Rpc extends Wrapper {
case Environment.CLIENT: case Environment.CLIENT:
dataRaw = player as string dataRaw = player as string
client._resolveEmitDestination(dataRaw) this._client._resolveEmitDestination(dataRaw)
break break
case Environment.BROWSER: case Environment.BROWSER:
dataRaw = player as string dataRaw = player as string
browser._resolveEmitDestination(dataRaw) this._browser._resolveEmitDestination(dataRaw)
break break
default: default:
@ -51,6 +68,10 @@ class Rpc extends Wrapper {
) )
} }
set browser(browser: any) {
this._client.browser = browser
}
public register< public register<
CallbackArguments extends unknown[] = unknown[], CallbackArguments extends unknown[] = unknown[],
CallbackReturn extends unknown = unknown, CallbackReturn extends unknown = unknown,
@ -59,6 +80,8 @@ class Rpc extends Wrapper {
eventName: EventName, eventName: EventName,
cb: (...args: CallbackArguments) => CallbackReturn, cb: (...args: CallbackArguments) => CallbackReturn,
): void { ): void {
this.log('register', eventName, cb)
if (this.forceBrowserDevMode_) return
Utils.errorUnknownEnvironment(this.environment_) Utils.errorUnknownEnvironment(this.environment_)
if ( if (
@ -76,6 +99,8 @@ class Rpc extends Wrapper {
public unregister<EventName extends string = string>( public unregister<EventName extends string = string>(
eventName: EventName, eventName: EventName,
): void { ): void {
this.log('unregister', eventName)
if (this.forceBrowserDevMode_) return
Utils.errorUnknownEnvironment(this.environment_) Utils.errorUnknownEnvironment(this.environment_)
delete this.state_[eventName] delete this.state_[eventName]
@ -96,6 +121,20 @@ class Rpc extends Wrapper {
eventNameOrArgs?: string | unknown[], eventNameOrArgs?: string | unknown[],
args?: 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_) Utils.errorUnknownEnvironment(this.environment_)
function _is1StParamPlayer(x: unknown): x is PlayerMp { function _is1StParamPlayer(x: unknown): x is PlayerMp {
@ -105,8 +144,8 @@ class Rpc extends Wrapper {
return typeof x === 'string' return typeof x === 'string'
} }
// client
if (this.environment_ === Environment.CLIENT) { if (this.environment_ === Environment.CLIENT) {
// client
return await this.call( return await this.call(
playerOrEventName as string, playerOrEventName as string,
args as unknown[], args as unknown[],
@ -163,6 +202,9 @@ class Rpc extends Wrapper {
EventName extends string = string, EventName extends string = string,
Return extends unknown = unknown, Return extends unknown = unknown,
>(eventName: EventName, args?: Arguments): Promise<Return> { >(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_) Utils.errorUnknownEnvironment(this.environment_)
const state: RPCState = { const state: RPCState = {
@ -208,6 +250,20 @@ class Rpc extends Wrapper {
eventNameOrArgs?: string | unknown[], eventNameOrArgs?: string | unknown[],
args?: 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_) Utils.errorUnknownEnvironment(this.environment_)
function _is1StParamPlayer(x: unknown): x is PlayerMp { function _is1StParamPlayer(x: unknown): x is PlayerMp {
@ -257,6 +313,9 @@ class Rpc extends Wrapper {
EventName extends string = string, EventName extends string = string,
Return extends unknown = unknown, Return extends unknown = unknown,
>(eventName: EventName, args?: Arguments): Promise<Return> { >(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_) Utils.errorUnknownEnvironment(this.environment_)
let state: RPCState = { let state: RPCState = {
@ -332,6 +391,4 @@ class Rpc extends Wrapper {
}) })
} }
} }
export { Rpc }
const rpc = new Rpc()
export { rpc, client }

View File

@ -5,12 +5,19 @@ import {
type PlayerMp, type PlayerMp,
RPCEventType, RPCEventType,
RPCState, RPCState,
RpcWrapperConfig,
Utils, Utils,
} from './utils' } from './utils'
class Server extends Wrapper { export class Server extends Wrapper {
constructor() { constructor(
super() options: RpcWrapperConfig = {
forceBrowserDevMode: false,
},
) {
super(options)
if (!!options.forceBrowserDevMode) return
mp.events.add( mp.events.add(
Events.SERVER_EVENT_LISTENER, Events.SERVER_EVENT_LISTENER,
@ -84,6 +91,3 @@ class Server extends Wrapper {
} }
} }
} }
const server = new Server()
export { server }

View File

@ -18,6 +18,28 @@ export enum Errors {
EVENT_RESPONSE_TIMEOUT = 'Response was timed out after 10s of inactivity', 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 { export class Utils {
public static getEnvironment(): Environment { public static getEnvironment(): Environment {
if ('joaat' in mp) return Environment.SERVER 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 { export enum RPCEventType {
EVENT = 'event', EVENT = 'event',
RESPONSE = 'response', RESPONSE = 'response',
} }
export type PlayerMp = {
call: (event: string, args?: unknown[]) => void
}
export const nativeClientEvents = new Set([ export const nativeClientEvents = new Set([
'browserCreated', 'browserCreated',
'browserDomReady', 'browserDomReady',

View File

@ -1,9 +1,31 @@
import { Environment, Errors, RPCState, Utils } from './utils' import { Environment, Errors, RPCState, RpcWrapperConfig, Utils } from './utils'
export class Wrapper { export class Wrapper {
protected environment_ = Utils.getEnvironment() protected environment_ = Environment.UNKNOWN
protected state_ = 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.environment_ === Environment.BROWSER ? window : global
}
this.forceBrowserDevMode_ = !!options.forceBrowserDevMode
}
protected verifyEvent_(data: string | RPCState): RPCState { protected verifyEvent_(data: string | RPCState): RPCState {
let rpcData = let rpcData =
@ -30,4 +52,9 @@ export class Wrapper {
throw new Error(errorMessage.join('\n | ')) throw new Error(errorMessage.join('\n | '))
} }
protected log(method: string, eventName: string, ...args: unknown[]): void {
if (this.debug_)
this.console_('RPC | [' + method + '] ' + eventName + ':', ...args)
}
} }