rage-framework/rpc/src/client.ts
Danya H 2bcced5a56 upd rpc
- added more comments
2024-10-27 15:39:13 +00:00

176 lines
4.8 KiB
TypeScript

import { Wrapper } from './wrapper'
import {
Environment,
Errors,
Events,
RPCEventType,
RPCState,
RpcWrapperConfig,
Utils,
} from './utils'
/**
* NOT INTENDED FOR OUT-OF-CONTEXT USE
*/
export class Client extends Wrapper {
private _browser: any = null
constructor(
options: RpcWrapperConfig = {
forceBrowserDevMode: false,
},
) {
super(options)
}
set browser(browser: any) {
this._browser = browser
}
/**
* NOT INTENDED FOR OUT-OF-CONTEXT USE
*/
public _resolveEmitDestination(dataRaw: string) {
const state = Utils.prepareExecution(dataRaw)
switch (state.calledTo) {
case Environment.SERVER:
this.emitServer(dataRaw)
break
case Environment.BROWSER:
this.emitBrowser(dataRaw)
break
case Environment.CLIENT:
this.emit(state)
break
default:
this.triggerError_(state, Errors.UNKNOWN_ENVIRONMENT)
break
}
}
// called to client
private async emit(state: RPCState) {
this.errorNoBrowser()
// check availability
state = this.verifyEvent_(state)
if (state.knownError) {
this.triggerError_(state, state.knownError)
}
// execute + generate response
const responseEventName = Utils.generateResponseEventName(state.uuid)
const response = await this.state_[state.eventName](
...(Array.isArray(state.data) ? state.data : []),
)
const responseState: RPCState = {
uuid: Utils.generateUUID(),
eventName: state.eventName,
calledFrom: state.calledTo,
calledTo: state.calledFrom,
knownError: undefined,
data: response,
type: RPCEventType.RESPONSE,
}
// send response
switch (state.calledFrom) {
case Environment.CLIENT:
try {
mp.events.call(
responseEventName,
Utils.prepareTransfer(responseState),
)
} catch (e) {
void e
}
break
case Environment.SERVER:
try {
mp.events.callRemote(
responseEventName,
Utils.prepareTransfer(responseState),
)
} catch (e) {
void e
}
break
case Environment.BROWSER:
try {
this._browser.call(
responseEventName,
Utils.prepareTransfer(responseState),
)
} catch (e) {
void e
}
break
}
}
// called to server
private emitServer(dataRaw: string) {
this.errorNoBrowser()
const state = Utils.prepareExecution(dataRaw)
// if event is called from browser we will forward response through client via this
if (state.calledFrom === Environment.BROWSER) {
const responseEventName = Utils.generateResponseEventName(
state.uuid,
)
const timeout = setTimeout(() => {
clearTimeout(timeout)
mp.events.remove(responseEventName)
}, 10000)
mp.events.add(responseEventName, (responseDataRaw: string) => {
this._browser.call(responseEventName, responseDataRaw)
clearTimeout(timeout)
mp.events.remove(responseEventName)
})
}
mp.events.callRemote(Events.SERVER_EVENT_LISTENER, dataRaw)
}
// called to browser
private emitBrowser(dataRaw: string) {
this.errorNoBrowser()
const state = Utils.prepareExecution(dataRaw)
// if event is called from server we will forward response through client via this
if (state.calledFrom === Environment.SERVER) {
const responseEventName = Utils.generateResponseEventName(
state.uuid,
)
const timeout = setTimeout(() => {
clearTimeout(timeout)
mp.events.remove(responseEventName)
}, 10000)
mp.events.add(responseEventName, (responseDataRaw: string) => {
mp.events.callRemote(responseEventName, responseDataRaw)
clearTimeout(timeout)
mp.events.remove(responseEventName)
})
}
this._browser.call(Events.LOCAL_EVENT_LISTENER, dataRaw)
}
private errorNoBrowser() {
if (!this._browser) throw new Error(Errors.NO_BROWSER)
}
}