From 558f04567a43563e590683e76fdde9e7c4f0c76e Mon Sep 17 00:00:00 2001 From: Danya H Date: Mon, 28 Sep 2026 00:00:15 +0100 Subject: [PATCH] chore(rpc): promote Wrapper to BaseInstance --- rpc/src/core/{wrapper.ts => base.ts} | 115 +++++++++++++++------- rpc/src/core/client.ts | 139 ++++++-------------------- rpc/src/core/server.ts | 142 +++++---------------------- rpc/src/core/webview.ts | 118 ++++------------------ rpc/src/index.ts | 7 +- rpc/src/utils/emitter.ts | 2 +- 6 files changed, 156 insertions(+), 367 deletions(-) rename rpc/src/core/{wrapper.ts => base.ts} (60%) diff --git a/rpc/src/core/wrapper.ts b/rpc/src/core/base.ts similarity index 60% rename from rpc/src/core/wrapper.ts rename to rpc/src/core/base.ts index c964e6e..5bd4dc6 100644 --- a/rpc/src/core/wrapper.ts +++ b/rpc/src/core/base.ts @@ -1,9 +1,10 @@ -import { Emitter } from '../utils/emitter' +import { Emitter, type Handler } from '../utils/emitter' import { handlerErrorMessage, notRegisteredMessage, RPCError, } from '../utils/errors' +import { generateUUID } from '../utils/funcs' import { Pending } from '../utils/pending' import { type RPCConfig, @@ -12,21 +13,84 @@ import { type RPCState, } from '../utils/types' -export class Wrapper { - protected env: RPCEnvironment - protected _emitterLocal: Emitter - protected _pending: Pending - protected debug: boolean - protected console: Console +/** Shared plumbing of the server, client and webview instances */ +export class RPCInstanceBase { + protected readonly env: RPCEnvironment + protected readonly debug: boolean + protected readonly _emitterLocal = new Emitter() + protected readonly _pending: Pending constructor(cfg: RPCConfig) { this.env = cfg.env - this._emitterLocal = new Emitter() - this._pending = new Pending(cfg.timeout ?? 5000) this.debug = cfg.debug ?? false - this.console = console + this._pending = new Pending(cfg.timeout ?? 5000) } + // ===== LISTENERS ===== + + /** Registers `cb` for `event` on `emitter`; `method` is only used for logs */ + protected listen( + emitter: Emitter, + method: string, + event: string, + cb: Handler, + ): this { + this.log(`${method} ${event}`) + emitter.on(event, cb) + return this + } + + protected unlisten(emitter: Emitter, method: string, event: string): this { + this.log(`${method} ${event}`) + emitter.off(event) + return this + } + + // ===== OUTGOING ===== + + /** Builds an event payload sent from this environment to `to` */ + protected request( + event: string, + to: RPCEnvironment, + args: unknown[], + player: number | null, + ): RPCState { + return { + event, + uuid: generateUUID(), + calledFrom: this.env, + calledTo: to, + error: null, + data: args, + player, + type: 'event', + } + } + + /** Calls a listener registered with `onSelf` in this environment */ + protected emitLocal(event: string, args: unknown[]): Promise { + this.log(`emitSelf ${event}`) + if (!this._emitterLocal.has(event)) { + throw new RPCError( + RPCErrors.EVENT_NOT_REGISTERED, + notRegisteredMessage(event, this.env, this.env), + { event, uuid: '', from: this.env, to: this.env }, + ) + } + return this._emitterLocal.emit(event, ...args) + } + + /** Settles the call waiting for `response`; ignores late or unexpected ones */ + protected settle(response: RPCState): void { + const found = response.error + ? this._pending.reject(response.uuid, RPCError.fromResponse(response)) + : this._pending.resolve(response.uuid, response.data?.[0]) + + if (!found) this.logIgnored(response) + } + + // ===== INCOMING ===== + /** * Runs the listener for `request` and builds the response to send back. * Never throws: a missing listener or a thrown error ends up in `error`. @@ -57,7 +121,7 @@ export class Wrapper { return this.response(request, [data], null) } catch (e) { // keep the stack visible where the listener lives - this.console.error(e) + console.error(e) return this.errorResponse( request, new RPCError( @@ -83,32 +147,17 @@ export class Wrapper { }) } - /** Settles the call waiting for `response`; ignores late or unexpected ones */ - protected settle(response: RPCState): void { - const found = response.error - ? this._pending.reject(response.uuid, RPCError.fromResponse(response)) - : this._pending.resolve(response.uuid, response.data?.[0]) + // ===== LOGS ===== - if (!found) this.logIgnored(response) - } - - /** Throws if no local listener is registered for `event` */ - protected assertListener(emitter: Emitter, event: string): void { - if (!emitter.has(event)) { - throw new RPCError( - RPCErrors.EVENT_NOT_REGISTERED, - notRegisteredMessage(event, this.env, this.env), - { event, uuid: '', from: this.env, to: this.env }, - ) - } + /** Debug-only log, prefixed with the environment */ + protected log(message: string): void { + if (this.debug) console.log(`[RPC]:${this.env}:${message}`) } protected logIgnored(response: RPCState): void { - if (this.debug) { - this.console.log( - `[RPC]:ignored response ${response.event} ${response.uuid} (no pending call, possibly timed out)`, - ) - } + this.log( + `ignored response ${response.event} ${response.uuid} (no pending call, possibly timed out)`, + ) } private response( diff --git a/rpc/src/core/client.ts b/rpc/src/core/client.ts index 5dfc835..fde135b 100644 --- a/rpc/src/core/client.ts +++ b/rpc/src/core/client.ts @@ -2,7 +2,7 @@ import type * as s from '@entityseven/fivem-rpc-shared-types' import { Emitter } from '../utils/emitter' import { RPCError } from '../utils/errors' -import { generateUUID, parse, stringify, stringifyWeb } from '../utils/funcs' +import { parse, stringify, stringifyWeb } from '../utils/funcs' import { NATIVE_CLIENT_EVENTS, NATIVE_CLIENT_NETWORK_EVENTS, @@ -17,9 +17,9 @@ import { type RPCStateRaw, type RPCStateWeb, } from '../utils/types' -import { Wrapper } from './wrapper' +import { RPCInstanceBase } from './base' -export class RPCInstanceClient extends Wrapper { +export class RPCInstanceClient extends RPCInstanceBase { private readonly _emitterServer: Emitter private readonly _emitterWeb: Emitter @@ -29,7 +29,7 @@ export class RPCInstanceClient extends Wrapper { this._emitterServer = new Emitter() this._emitterWeb = new Emitter() - this.console.log('[RPC] Initialized Client') + console.log('[RPC] Initialized Client') onNet(RPCEvents.LISTENER_SERVER, this._handleServer.bind(this)) RegisterNuiCallbackType(RPCEvents.LISTENER_WEB) @@ -55,11 +55,9 @@ export class RPCInstanceClient extends Wrapper { } const payload = parse(payloadRaw) - if (this.debug) { - this.console.log( - `[RPC]:client:accepted ${payload.type} ${payload.event} from ${payload.calledFrom}`, - ) - } + this.log( + `accepted ${payload.type} ${payload.event} from ${payload.calledFrom}`, + ) if (payload.type === 'event') { if (payload.calledTo === 'client') { @@ -88,11 +86,9 @@ export class RPCInstanceClient extends Wrapper { } private async _handleWeb(payload: RPCState): Promise { - if (this.debug) { - this.console.log( - `[RPC]:client:accepted ${payload.type} ${payload.event} from ${payload.calledFrom}`, - ) - } + this.log( + `accepted ${payload.type} ${payload.event} from ${payload.calledFrom}`, + ) if (payload.type === 'event') { if (payload.calledTo === 'client') { @@ -134,25 +130,13 @@ export class RPCInstanceClient extends Wrapper { ...args: CallbackArguments ) => Awaited | Promise>, ): this { - if (this.debug) { - this.console.log(`[RPC]:onServer ${eventName}`) - } - - this._emitterServer.on(eventName, cb) - - return this + return this.listen(this._emitterServer, 'onServer', eventName, cb) } public offServer( eventName: EventName, ): this { - if (this.debug) { - this.console.log(`[RPC]:offServer ${eventName}`) - } - - this._emitterServer.off(eventName) - - return this + return this.unlisten(this._emitterServer, 'offServer', eventName) } public async emitServer< @@ -160,16 +144,12 @@ export class RPCInstanceClient extends Wrapper { Arguments extends Parameters, Response extends ReturnType, >(eventName: EventName, ...args: Arguments): Promise> { - const payload: RPCState = { - event: eventName, - uuid: generateUUID(), - calledFrom: 'client', - calledTo: 'server', - error: null, - data: args.length ? args : null, - player: GetPlayerServerId(PlayerId()), - type: 'event', - } + const payload = this.request( + eventName, + 'server', + args, + GetPlayerServerId(PlayerId()), + ) emitNet(RPCEvents.LISTENER_CLIENT, stringify(payload)) @@ -188,25 +168,13 @@ export class RPCInstanceClient extends Wrapper { ...args: CallbackArguments ) => Awaited | Promise>, ): this { - if (this.debug) { - this.console.log(`[RPC]:onWebview ${eventName}`) - } - - this._emitterWeb.on(eventName, cb) - - return this + return this.listen(this._emitterWeb, 'onWebview', eventName, cb) } public offWebview( eventName: EventName, ): this { - if (this.debug) { - this.console.log(`[RPC]:offWebview ${eventName}`) - } - - this._emitterWeb.off(eventName) - - return this + return this.unlisten(this._emitterWeb, 'offWebview', eventName) } public async emitWebview< @@ -214,16 +182,7 @@ export class RPCInstanceClient extends Wrapper { Arguments extends Parameters, Response extends ReturnType, >(eventName: EventName, ...args: Arguments): Promise> { - const payload: RPCState = { - event: eventName, - uuid: generateUUID(), - calledFrom: 'client', - calledTo: 'webview', - error: null, - data: args.length ? args : null, - player: PlayerId(), - type: 'event', - } + const payload = this.request(eventName, 'webview', args, PlayerId()) this._sendWebMessage({ origin: RPCEvents.LISTENER_CLIENT, @@ -245,25 +204,13 @@ export class RPCInstanceClient extends Wrapper { ...args: CallbackArguments ) => Awaited | Promise>, ): this { - if (this.debug) { - this.console.log(`[RPC]:onSelf ${eventName}`) - } - - this._emitterLocal.on(eventName, cb) - - return this + return this.listen(this._emitterLocal, 'onSelf', eventName, cb) } public offSelf( eventName: EventName, ): this { - if (this.debug) { - this.console.log(`[RPC]:offSelf ${eventName}`) - } - - this._emitterLocal.off(eventName) - - return this + return this.unlisten(this._emitterLocal, 'offSelf', eventName) } public async emitSelf< @@ -271,29 +218,7 @@ export class RPCInstanceClient extends Wrapper { Arguments extends Parameters, Response extends ReturnType, >(eventName: EventName, ...args: Arguments): Promise> { - const payload: RPCState = { - event: eventName, - uuid: generateUUID(), - calledFrom: 'client', - calledTo: 'client', - error: null, - data: args.length ? args : null, - player: null, - type: 'event', - } - - if (this.debug) { - this.console.log( - `[RPC]:accepted ${payload.event} from ${payload.calledFrom}`, - ) - } - - this.assertListener(this._emitterLocal, payload.event) - - return await this._emitterLocal.emit>( - payload.event, - ...(payload.data && payload.data.length > 0 ? payload.data : []), - ) + return this.emitLocal>(eventName, args) } // ===== OTHER ===== @@ -305,9 +230,7 @@ export class RPCInstanceClient extends Wrapper { command: CommandName, cb: (player: number, args: CallbackArguments, commandRaw: string) => void, ): this { - if (this.debug) { - this.console.log(`[RPC]:onCommand ${command}`) - } + this.log(`onCommand ${command}`) RegisterCommand(command, cb, false) @@ -322,9 +245,7 @@ export class RPCInstanceClient extends Wrapper { throw new RPCError(RPCErrors.UNKNOWN_NATIVE, RPCErrors.UNKNOWN_NATIVE) } - if (this.debug) { - this.console.log(`[RPC]:onNativeEvent ${eventName}`) - } + this.log(`onNativeEvent ${eventName}`) on(eventName, cb) @@ -341,9 +262,7 @@ export class RPCInstanceClient extends Wrapper { throw new RPCError(RPCErrors.UNKNOWN_NATIVE, RPCErrors.UNKNOWN_NATIVE) } - if (this.debug) { - this.console.log(`[RPC]:onNativeNetworkEvent ${eventName}`) - } + this.log(`onNativeNetworkEvent ${eventName}`) on(eventName, cb) @@ -351,9 +270,7 @@ export class RPCInstanceClient extends Wrapper { } public setWebviewFocus(hasFocus: boolean, hasCursor: boolean): this { - if (this.debug) { - this.console.log(`[RPC]:setWebviewFocus ${hasFocus} ${hasCursor}`) - } + this.log(`setWebviewFocus ${hasFocus} ${hasCursor}`) SetNuiFocus(hasFocus, hasCursor) diff --git a/rpc/src/core/server.ts b/rpc/src/core/server.ts index 8a55d2d..cb7f103 100644 --- a/rpc/src/core/server.ts +++ b/rpc/src/core/server.ts @@ -2,19 +2,18 @@ import type * as s from '@entityseven/fivem-rpc-shared-types' import { Emitter } from '../utils/emitter' import { RPCError } from '../utils/errors' -import { generateUUID, parse, stringify } from '../utils/funcs' +import { parse, stringify } from '../utils/funcs' import { NATIVE_SERVER_EVENTS } from '../utils/native' import { type RPCConfig, RPCErrors, RPCEvents, type RPCNativeServerEvents, - type RPCState, type RPCStateRaw, } from '../utils/types' -import { Wrapper } from './wrapper' +import { RPCInstanceBase } from './base' -export class RPCInstanceServer extends Wrapper { +export class RPCInstanceServer extends RPCInstanceBase { private readonly _emitterClient: Emitter private readonly _emitterWeb: Emitter @@ -24,7 +23,7 @@ export class RPCInstanceServer extends Wrapper { this._emitterClient = new Emitter() this._emitterWeb = new Emitter() - this.console.log('[RPC] Initialized Server') + console.log('[RPC] Initialized Server') onNet(RPCEvents.LISTENER_CLIENT, this._handleClient.bind(this)) onNet(RPCEvents.LISTENER_WEB, this._handleWeb.bind(this)) @@ -40,17 +39,15 @@ export class RPCInstanceServer extends Wrapper { } const payload = parse(payloadRaw) - if (this.debug) { - this.console.log( - `[RPC]:server:accepted ${payload.type} ${payload.event} from ${payload.calledFrom}`, - ) - } + this.log( + `accepted ${payload.type} ${payload.event} from ${payload.calledFrom}`, + ) if (payload.calledFrom === 'client') { if (payload.type === 'event') { if (payload.player === null || payload.player === -1) { // nobody to reply to, the caller times out - this.console.error( + console.error( new RPCError( RPCErrors.NO_PLAYER, `${RPCErrors.NO_PLAYER}: "${payload.event}" from ${payload.calledFrom}`, @@ -81,17 +78,15 @@ export class RPCInstanceServer extends Wrapper { } const payload = parse(payloadRaw) - if (this.debug) { - this.console.log( - `[RPC]:server:accepted ${payload.type} ${payload.event} from ${payload.calledFrom}`, - ) - } + this.log( + `accepted ${payload.type} ${payload.event} from ${payload.calledFrom}`, + ) if (payload.calledFrom === 'webview') { if (payload.type === 'event') { if (payload.player === null || payload.player === -1) { // nobody to reply to, the caller times out - this.console.error( + console.error( new RPCError( RPCErrors.NO_PLAYER, `${RPCErrors.NO_PLAYER}: "${payload.event}" from ${payload.calledFrom}`, @@ -127,25 +122,13 @@ export class RPCInstanceServer extends Wrapper { ...args: CallbackArguments ) => Awaited | Promise>, ): this { - if (this.debug) { - this.console.log(`[RPC]:onClient ${eventName}`) - } - - this._emitterClient.on(eventName, cb) - - return this + return this.listen(this._emitterClient, 'onClient', eventName, cb) } public offClient( eventName: EventName, ): this { - if (this.debug) { - this.console.log(`[RPC]:offClient ${eventName}`) - } - - this._emitterClient.off(eventName) - - return this + return this.unlisten(this._emitterClient, 'offClient', eventName) } public async emitClient< @@ -157,16 +140,7 @@ export class RPCInstanceServer extends Wrapper { eventName: EventName, ...args: Arguments ): Promise> { - const payload: RPCState = { - event: eventName, - uuid: generateUUID(), - calledFrom: 'server', - calledTo: 'client', - error: null, - data: args.length ? args : null, - player: player, - type: 'event', - } + const payload = this.request(eventName, 'client', args, player) emitNet(RPCEvents.LISTENER_SERVER, player, stringify(payload)) @@ -177,16 +151,7 @@ export class RPCInstanceServer extends Wrapper { EventName extends keyof s.RPCEvents_ServerClient, Arguments extends Parameters, >(eventName: EventName, ...args: Arguments): Promise { - const payload: RPCState = { - event: eventName, - uuid: generateUUID(), - calledFrom: 'server', - calledTo: 'client', - error: null, - data: args.length ? args : null, - player: -1, - type: 'event', - } + const payload = this.request(eventName, 'client', args, -1) emitNet(RPCEvents.LISTENER_SERVER, -1, stringify(payload)) } @@ -204,25 +169,13 @@ export class RPCInstanceServer extends Wrapper { ...args: CallbackArguments ) => Awaited | Promise>, ): this { - if (this.debug) { - this.console.log(`[RPC]:onWebview ${eventName}`) - } - - this._emitterWeb.on(eventName, cb) - - return this + return this.listen(this._emitterWeb, 'onWebview', eventName, cb) } public offWebview( eventName: EventName, ): this { - if (this.debug) { - this.console.log(`[RPC]:offWebview ${eventName}`) - } - - this._emitterWeb.off(eventName) - - return this + return this.unlisten(this._emitterWeb, 'offWebview', eventName) } public async emitWebview< @@ -234,16 +187,7 @@ export class RPCInstanceServer extends Wrapper { eventName: EventName, ...args: Arguments ): Promise> { - const payload: RPCState = { - event: eventName, - uuid: generateUUID(), - calledFrom: 'server', - calledTo: 'webview', - error: null, - data: args.length ? args : null, - player: player, - type: 'event', - } + const payload = this.request(eventName, 'webview', args, player) emitNet(RPCEvents.LISTENER_SERVER, player, stringify(payload)) @@ -262,25 +206,13 @@ export class RPCInstanceServer extends Wrapper { ...args: CallbackArguments ) => Awaited | Promise>, ): this { - if (this.debug) { - this.console.log(`[RPC]:onSelf ${eventName}`) - } - - this._emitterLocal.on(eventName, cb) - - return this + return this.listen(this._emitterLocal, 'onSelf', eventName, cb) } public offSelf( eventName: EventName, ): this { - if (this.debug) { - this.console.log(`[RPC]:offSelf ${eventName}`) - } - - this._emitterLocal.off(eventName) - - return this + return this.unlisten(this._emitterLocal, 'offSelf', eventName) } public async emitSelf< @@ -288,29 +220,7 @@ export class RPCInstanceServer extends Wrapper { Arguments extends Parameters, Response extends ReturnType, >(eventName: EventName, ...args: Arguments): Promise> { - const payload: RPCState = { - event: eventName, - uuid: generateUUID(), - calledFrom: 'server', - calledTo: 'server', - error: null, - data: args.length ? args : null, - player: null, - type: 'event', - } - - if (this.debug) { - this.console.log( - `[RPC]:accepted ${payload.event} from ${payload.calledFrom}`, - ) - } - - this.assertListener(this._emitterLocal, payload.event) - - return await this._emitterLocal.emit>( - payload.event, - ...(payload.data && payload.data.length > 0 ? payload.data : []), - ) + return this.emitLocal>(eventName, args) } // ===== OTHER ===== @@ -323,9 +233,7 @@ export class RPCInstanceServer extends Wrapper { cb: (player: number, args: CallbackArguments, commandRaw: string) => void, restricted = false, ): this { - if (this.debug) { - this.console.log(`[RPC]:onCommand ${command}`) - } + this.log(`onCommand ${command}`) RegisterCommand(command, cb, restricted) @@ -340,9 +248,7 @@ export class RPCInstanceServer extends Wrapper { throw new RPCError(RPCErrors.UNKNOWN_NATIVE, RPCErrors.UNKNOWN_NATIVE) } - if (this.debug) { - this.console.log(`[RPC]:onNativeEvent ${eventName}`) - } + this.log(`onNativeEvent ${eventName}`) on(eventName, cb) diff --git a/rpc/src/core/webview.ts b/rpc/src/core/webview.ts index 4de4616..b3ff380 100644 --- a/rpc/src/core/webview.ts +++ b/rpc/src/core/webview.ts @@ -1,7 +1,7 @@ import type * as s from '@entityseven/fivem-rpc-shared-types' import { Emitter } from '../utils/emitter' -import { generateUUID, stringify } from '../utils/funcs' +import { stringify } from '../utils/funcs' import { RPCEvents, type RPCConfig, @@ -9,9 +9,9 @@ import { type RPCStateRaw, type RPCStateWeb, } from '../utils/types' -import { Wrapper } from './wrapper' +import { RPCInstanceBase } from './base' -export class RPCInstanceWebview extends Wrapper { +export class RPCInstanceWebview extends RPCInstanceBase { private readonly _emitterClient: Emitter private readonly _emitterServer: Emitter @@ -21,7 +21,7 @@ export class RPCInstanceWebview extends Wrapper { this._emitterClient = new Emitter() this._emitterServer = new Emitter() - this.console.log('[RPC] Initialized Webview') + console.log('[RPC] Initialized Webview') window.addEventListener('message', (e: MessageEvent) => { if (e.data.origin === RPCEvents.LISTENER_CLIENT) { @@ -36,11 +36,9 @@ export class RPCInstanceWebview extends Wrapper { // ===== HANDLERS ===== private async _handleClient(payload: RPCState) { - if (this.debug) { - this.console.log( - `[RPC]:webview:accepted ${payload.type} ${payload.event} from ${payload.calledFrom}`, - ) - } + this.log( + `accepted ${payload.type} ${payload.event} from ${payload.calledFrom}`, + ) if (payload.calledFrom === 'client' && payload.type === 'event') { const response = await this.dispatch(this._emitterClient, payload) @@ -50,11 +48,9 @@ export class RPCInstanceWebview extends Wrapper { } private async _handleServer(payload: RPCState) { - if (this.debug) { - this.console.log( - `[RPC]:webview:accepted ${payload.type} ${payload.event} from ${payload.calledFrom}`, - ) - } + this.log( + `accepted ${payload.type} ${payload.event} from ${payload.calledFrom}`, + ) if (payload.calledFrom === 'server' && payload.type === 'event') { const response = await this.dispatch(this._emitterServer, payload) @@ -75,25 +71,13 @@ export class RPCInstanceWebview extends Wrapper { ...args: CallbackArguments ) => Awaited | Promise>, ): this { - if (this.debug) { - this.console.log(`[RPC]:onClient ${eventName}`) - } - - this._emitterClient.on(eventName, cb) - - return this + return this.listen(this._emitterClient, 'onClient', eventName, cb) } public offClient( eventName: EventName, ): this { - if (this.debug) { - this.console.log(`[RPC]:offClient ${eventName}`) - } - - this._emitterClient.off(eventName) - - return this + return this.unlisten(this._emitterClient, 'offClient', eventName) } public async emitClient< @@ -101,16 +85,7 @@ export class RPCInstanceWebview extends Wrapper { Arguments extends Parameters, Response extends ReturnType, >(eventName: EventName, ...args: Arguments): Promise> { - const payload: RPCState = { - event: eventName, - uuid: generateUUID(), - calledFrom: 'webview', - calledTo: 'client', - error: null, - data: args.length ? args : null, - player: null, - type: 'event', - } + const payload = this.request(eventName, 'client', args, null) return this._request>(payload) } @@ -127,25 +102,13 @@ export class RPCInstanceWebview extends Wrapper { ...args: CallbackArguments ) => Awaited | Promise>, ): this { - if (this.debug) { - this.console.log(`[RPC]:onServer ${eventName}`) - } - - this._emitterServer.on(eventName, cb) - - return this + return this.listen(this._emitterServer, 'onServer', eventName, cb) } public offServer( eventName: EventName, ): RPCInstanceWebview { - if (this.debug) { - this.console.log(`[RPC]:offServer ${eventName}`) - } - - this._emitterServer.off(eventName) - - return this + return this.unlisten(this._emitterServer, 'offServer', eventName) } public async emitServer< @@ -153,16 +116,7 @@ export class RPCInstanceWebview extends Wrapper { Arguments extends Parameters, Response extends ReturnType, >(eventName: EventName, ...args: Arguments): Promise> { - const payload: RPCState = { - event: eventName, - uuid: generateUUID(), - calledFrom: 'webview', - calledTo: 'server', - error: null, - data: args.length ? args : null, - player: null, - type: 'event', - } + const payload = this.request(eventName, 'server', args, null) return this._request>(payload) } @@ -179,25 +133,13 @@ export class RPCInstanceWebview extends Wrapper { ...args: CallbackArguments ) => Awaited | Promise>, ): this { - if (this.debug) { - this.console.log(`[RPC]:onSelf ${eventName}`) - } - - this._emitterLocal.on(eventName, cb) - - return this + return this.listen(this._emitterLocal, 'onSelf', eventName, cb) } public offSelf( eventName: EventName, ): this { - if (this.debug) { - this.console.log(`[RPC]:offSelf ${eventName}`) - } - - this._emitterLocal.off(eventName) - - return this + return this.unlisten(this._emitterLocal, 'offSelf', eventName) } public async emitSelf< @@ -205,29 +147,7 @@ export class RPCInstanceWebview extends Wrapper { Arguments extends Parameters, Response extends ReturnType, >(eventName: EventName, ...args: Arguments): Promise> { - const payload: RPCState = { - event: eventName, - uuid: generateUUID(), - calledFrom: 'webview', - calledTo: 'webview', - error: null, - data: args.length ? args : null, - player: null, - type: 'event', - } - - if (this.debug) { - this.console.log( - `[RPC]:accepted ${payload.event} from ${payload.calledFrom}`, - ) - } - - this.assertListener(this._emitterLocal, payload.event) - - return await this._emitterLocal.emit>( - payload.event, - ...(payload.data && payload.data.length > 0 ? payload.data : []), - ) + return this.emitLocal>(eventName, args) } // ===== UTILS ===== diff --git a/rpc/src/index.ts b/rpc/src/index.ts index e67b16f..82e7c17 100644 --- a/rpc/src/index.ts +++ b/rpc/src/index.ts @@ -1,7 +1,6 @@ import { RPCInstanceClient } from './core/client' import { RPCInstanceServer } from './core/server' import { RPCInstanceWebview } from './core/webview' -import { Wrapper } from './core/wrapper' import { RPCError } from './utils/errors' import { type RPCConfig, @@ -27,7 +26,7 @@ import { * * @class */ -class RPCFactory extends Wrapper { +class RPCFactory { private readonly operator: | RPCInstanceServer | RPCInstanceClient @@ -40,9 +39,7 @@ class RPCFactory extends Wrapper { * @param {boolean} opts.debug - Show additional logs */ constructor(opts: RPCConfig) { - super(opts) - - this.console.log('[RPC] Initializing...') + console.log('[RPC] Initializing...') switch (opts.env) { case 'server': diff --git a/rpc/src/utils/emitter.ts b/rpc/src/utils/emitter.ts index 76a9882..e3c9623 100644 --- a/rpc/src/utils/emitter.ts +++ b/rpc/src/utils/emitter.ts @@ -4,7 +4,7 @@ import { RPCErrors } from './types' * Accepts any callback. Argument types are enforced by the typed `on*`/`emit*` * methods that wrap the emitter, not here. */ -type Handler = (...args: never[]) => unknown +export type Handler = (...args: never[]) => unknown /** One handler per event: registering an event again replaces its handler. */ export class Emitter {