mirror of
https://github.com/rilaxik/fivem-rpc.git
synced 2026-09-29 01:30:42 +00:00
feat(rpc): rework shared-types + include as mandatory dep
This commit is contained in:
@@ -12,16 +12,16 @@
|
|||||||
"rpc": {
|
"rpc": {
|
||||||
"name": "@entityseven/fivem-rpc",
|
"name": "@entityseven/fivem-rpc",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@entityseven/fivem-rpc-shared-types": "workspace:^",
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@entityseven/fivem-rpc-shared-types": "workspace:*",
|
|
||||||
"tsdown": "^0.23.0",
|
"tsdown": "^0.23.0",
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@entityseven/fivem-rpc-shared-types": "^1.0.0",
|
|
||||||
"typescript": ">=5",
|
"typescript": ">=5",
|
||||||
},
|
},
|
||||||
"optionalPeers": [
|
"optionalPeers": [
|
||||||
"@entityseven/fivem-rpc-shared-types",
|
|
||||||
"typescript",
|
"typescript",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
+3
-5
@@ -48,18 +48,16 @@
|
|||||||
"prepublishOnly": "bun run build",
|
"prepublishOnly": "bun run build",
|
||||||
"typecheck": "tsc --noEmit"
|
"typecheck": "tsc --noEmit"
|
||||||
},
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@entityseven/fivem-rpc-shared-types": "workspace:^"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@entityseven/fivem-rpc-shared-types": "workspace:*",
|
|
||||||
"tsdown": "^0.23.0"
|
"tsdown": "^0.23.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@entityseven/fivem-rpc-shared-types": "^1.0.0",
|
|
||||||
"typescript": ">=5"
|
"typescript": ">=5"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"@entityseven/fivem-rpc-shared-types": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"optional": true
|
"optional": true
|
||||||
}
|
}
|
||||||
|
|||||||
+43
-56
@@ -17,6 +17,13 @@ import {
|
|||||||
type RPCStateRaw,
|
type RPCStateRaw,
|
||||||
type RPCStateWeb,
|
type RPCStateWeb,
|
||||||
} from '../utils/types'
|
} from '../utils/types'
|
||||||
|
import type {
|
||||||
|
RPCCommandName,
|
||||||
|
RPCEventArgs,
|
||||||
|
RPCEventName,
|
||||||
|
RPCEventResult,
|
||||||
|
RPCListener,
|
||||||
|
} from '../utils/typing'
|
||||||
import { RPCInstanceBase } from './base'
|
import { RPCInstanceBase } from './base'
|
||||||
|
|
||||||
export class RPCInstanceClient extends RPCInstanceBase {
|
export class RPCInstanceClient extends RPCInstanceBase {
|
||||||
@@ -116,63 +123,53 @@ export class RPCInstanceClient extends RPCInstanceBase {
|
|||||||
|
|
||||||
// ===== SERVER =====
|
// ===== SERVER =====
|
||||||
|
|
||||||
public onServer<
|
public onServer<EventName extends RPCEventName<s.RPCEvents_ServerClient>>(
|
||||||
EventName extends keyof s.RPCEvents_ServerClient,
|
|
||||||
CallbackArguments extends Parameters<s.RPCEvents_ServerClient[EventName]>,
|
|
||||||
CallbackReturn extends ReturnType<s.RPCEvents_ServerClient[EventName]>,
|
|
||||||
>(
|
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
cb: (
|
cb: RPCListener<s.RPCEvents_ServerClient, EventName>,
|
||||||
...args: CallbackArguments
|
|
||||||
) => Awaited<CallbackReturn> | Promise<Awaited<CallbackReturn>>,
|
|
||||||
): this {
|
): this {
|
||||||
return this.listen(this._emitterServer, 'onServer', eventName, cb)
|
return this.listen(this._emitterServer, 'onServer', eventName, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
public offServer<EventName extends keyof s.RPCEvents_ServerClient>(
|
public offServer<EventName extends RPCEventName<s.RPCEvents_ServerClient>>(
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
): this {
|
): this {
|
||||||
return this.unlisten(this._emitterServer, 'offServer', eventName)
|
return this.unlisten(this._emitterServer, 'offServer', eventName)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async emitServer<
|
public async emitServer<
|
||||||
EventName extends keyof s.RPCEvents_ClientServer,
|
EventName extends RPCEventName<s.RPCEvents_ClientServer>,
|
||||||
Arguments extends Parameters<s.RPCEvents_ClientServer[EventName]>,
|
>(
|
||||||
Response extends ReturnType<s.RPCEvents_ClientServer[EventName]>,
|
eventName: EventName,
|
||||||
>(eventName: EventName, ...args: Arguments): Promise<Awaited<Response>> {
|
...args: RPCEventArgs<s.RPCEvents_ClientServer, EventName>
|
||||||
|
): Promise<RPCEventResult<s.RPCEvents_ClientServer, EventName>> {
|
||||||
const payload = this.request(eventName, 'server', args, null)
|
const payload = this.request(eventName, 'server', args, null)
|
||||||
|
|
||||||
emitNet(RPCEvents.LISTENER_CLIENT, stringify(payload))
|
emitNet(RPCEvents.LISTENER_CLIENT, stringify(payload))
|
||||||
|
|
||||||
return this._pending.wait<Awaited<Response>>(payload)
|
return this._pending.wait(payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== WEBVIEW =====
|
// ===== WEBVIEW =====
|
||||||
|
|
||||||
public onWebview<
|
public onWebview<EventName extends RPCEventName<s.RPCEvents_WebviewClient>>(
|
||||||
EventName extends keyof s.RPCEvents_WebviewClient,
|
|
||||||
CallbackArguments extends Parameters<s.RPCEvents_WebviewClient[EventName]>,
|
|
||||||
CallbackReturn extends ReturnType<s.RPCEvents_WebviewClient[EventName]>,
|
|
||||||
>(
|
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
cb: (
|
cb: RPCListener<s.RPCEvents_WebviewClient, EventName>,
|
||||||
...args: CallbackArguments
|
|
||||||
) => Awaited<CallbackReturn> | Promise<Awaited<CallbackReturn>>,
|
|
||||||
): this {
|
): this {
|
||||||
return this.listen(this._emitterWeb, 'onWebview', eventName, cb)
|
return this.listen(this._emitterWeb, 'onWebview', eventName, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
public offWebview<EventName extends keyof s.RPCEvents_WebviewClient>(
|
public offWebview<EventName extends RPCEventName<s.RPCEvents_WebviewClient>>(
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
): this {
|
): this {
|
||||||
return this.unlisten(this._emitterWeb, 'offWebview', eventName)
|
return this.unlisten(this._emitterWeb, 'offWebview', eventName)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async emitWebview<
|
public async emitWebview<
|
||||||
EventName extends keyof s.RPCEvents_ClientWebview,
|
EventName extends RPCEventName<s.RPCEvents_ClientWebview>,
|
||||||
Arguments extends Parameters<s.RPCEvents_ClientWebview[EventName]>,
|
>(
|
||||||
Response extends ReturnType<s.RPCEvents_ClientWebview[EventName]>,
|
eventName: EventName,
|
||||||
>(eventName: EventName, ...args: Arguments): Promise<Awaited<Response>> {
|
...args: RPCEventArgs<s.RPCEvents_ClientWebview, EventName>
|
||||||
|
): Promise<RPCEventResult<s.RPCEvents_ClientWebview, EventName>> {
|
||||||
const payload = this.request(eventName, 'webview', args, null)
|
const payload = this.request(eventName, 'webview', args, null)
|
||||||
|
|
||||||
this._sendWebMessage({
|
this._sendWebMessage({
|
||||||
@@ -180,46 +177,36 @@ export class RPCInstanceClient extends RPCInstanceBase {
|
|||||||
data: payload,
|
data: payload,
|
||||||
})
|
})
|
||||||
|
|
||||||
return this._pending.wait<Awaited<Response>>(payload)
|
return this._pending.wait(payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== SELF =====
|
// ===== SELF =====
|
||||||
|
|
||||||
public onSelf<
|
public onSelf<EventName extends RPCEventName<s.RPCEvents_Client>>(
|
||||||
EventName extends keyof s.RPCEvents_Client,
|
|
||||||
CallbackArguments extends Parameters<s.RPCEvents_Client[EventName]>,
|
|
||||||
CallbackReturn extends ReturnType<s.RPCEvents_Client[EventName]>,
|
|
||||||
>(
|
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
cb: (
|
cb: RPCListener<s.RPCEvents_Client, EventName>,
|
||||||
...args: CallbackArguments
|
|
||||||
) => Awaited<CallbackReturn> | Promise<Awaited<CallbackReturn>>,
|
|
||||||
): this {
|
): this {
|
||||||
return this.listen(this._emitterLocal, 'onSelf', eventName, cb)
|
return this.listen(this._emitterLocal, 'onSelf', eventName, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
public offSelf<EventName extends keyof s.RPCEvents_Client>(
|
public offSelf<EventName extends RPCEventName<s.RPCEvents_Client>>(
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
): this {
|
): this {
|
||||||
return this.unlisten(this._emitterLocal, 'offSelf', eventName)
|
return this.unlisten(this._emitterLocal, 'offSelf', eventName)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async emitSelf<
|
public async emitSelf<EventName extends RPCEventName<s.RPCEvents_Client>>(
|
||||||
EventName extends keyof s.RPCEvents_Client,
|
eventName: EventName,
|
||||||
Arguments extends Parameters<s.RPCEvents_Client[EventName]>,
|
...args: RPCEventArgs<s.RPCEvents_Client, EventName>
|
||||||
Response extends ReturnType<s.RPCEvents_Client[EventName]>,
|
): Promise<RPCEventResult<s.RPCEvents_Client, EventName>> {
|
||||||
>(eventName: EventName, ...args: Arguments): Promise<Awaited<Response>> {
|
return this.emitLocal(eventName, args)
|
||||||
return this.emitLocal<Awaited<Response>>(eventName, args)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== OTHER =====
|
// ===== OTHER =====
|
||||||
|
|
||||||
public onCommand<
|
public onCommand<CommandName extends RPCCommandName<s.RPCCommands_Client>>(
|
||||||
CommandName extends s.RPCCommands_Client,
|
|
||||||
CallbackArguments extends unknown[],
|
|
||||||
>(
|
|
||||||
command: CommandName,
|
command: CommandName,
|
||||||
cb: (player: number, args: CallbackArguments, commandRaw: string) => void,
|
cb: (player: number, args: string[], rawCommand: string) => void,
|
||||||
): this {
|
): this {
|
||||||
this.log(`onCommand ${command}`)
|
this.log(`onCommand ${command}`)
|
||||||
|
|
||||||
@@ -228,10 +215,10 @@ export class RPCInstanceClient extends RPCInstanceBase {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
public onNativeEvent<
|
public onNativeEvent<EventName extends keyof RPCNativeClientEvents>(
|
||||||
EventName extends keyof RPCNativeClientEvents,
|
eventName: EventName,
|
||||||
CallbackArguments extends Parameters<RPCNativeClientEvents[EventName]>,
|
cb: (...args: Parameters<RPCNativeClientEvents[EventName]>) => void,
|
||||||
>(eventName: EventName, cb: (...args: CallbackArguments) => void): this {
|
): this {
|
||||||
if (!NATIVE_CLIENT_EVENTS.includes(eventName)) {
|
if (!NATIVE_CLIENT_EVENTS.includes(eventName)) {
|
||||||
throw new RPCError(
|
throw new RPCError(
|
||||||
RPCErrors.UNKNOWN_NATIVE,
|
RPCErrors.UNKNOWN_NATIVE,
|
||||||
@@ -248,10 +235,10 @@ export class RPCInstanceClient extends RPCInstanceBase {
|
|||||||
|
|
||||||
public onNativeNetworkEvent<
|
public onNativeNetworkEvent<
|
||||||
EventName extends keyof RPCNativeClientNetworkEvents,
|
EventName extends keyof RPCNativeClientNetworkEvents,
|
||||||
CallbackArguments extends Parameters<
|
>(
|
||||||
RPCNativeClientNetworkEvents[EventName]
|
eventName: EventName,
|
||||||
>,
|
cb: (...args: Parameters<RPCNativeClientNetworkEvents[EventName]>) => void,
|
||||||
>(eventName: EventName, cb: (...args: CallbackArguments) => void): this {
|
): this {
|
||||||
if (!NATIVE_CLIENT_NETWORK_EVENTS.includes(eventName)) {
|
if (!NATIVE_CLIENT_NETWORK_EVENTS.includes(eventName)) {
|
||||||
throw new RPCError(
|
throw new RPCError(
|
||||||
RPCErrors.UNKNOWN_NATIVE,
|
RPCErrors.UNKNOWN_NATIVE,
|
||||||
|
|||||||
+40
-59
@@ -11,6 +11,13 @@ import {
|
|||||||
type RPCNativeServerEvents,
|
type RPCNativeServerEvents,
|
||||||
type RPCStateRaw,
|
type RPCStateRaw,
|
||||||
} from '../utils/types'
|
} from '../utils/types'
|
||||||
|
import type {
|
||||||
|
RPCCommandName,
|
||||||
|
RPCEventArgs,
|
||||||
|
RPCEventName,
|
||||||
|
RPCEventResult,
|
||||||
|
RPCListener,
|
||||||
|
} from '../utils/typing'
|
||||||
import { RPCInstanceBase } from './base'
|
import { RPCInstanceBase } from './base'
|
||||||
|
|
||||||
export class RPCInstanceServer extends RPCInstanceBase {
|
export class RPCInstanceServer extends RPCInstanceBase {
|
||||||
@@ -68,46 +75,39 @@ export class RPCInstanceServer extends RPCInstanceBase {
|
|||||||
|
|
||||||
// ===== CLIENT =====
|
// ===== CLIENT =====
|
||||||
|
|
||||||
public onClient<
|
public onClient<EventName extends RPCEventName<s.RPCEvents_ClientServer>>(
|
||||||
EventName extends keyof s.RPCEvents_ClientServer,
|
|
||||||
CallbackArguments extends Parameters<s.RPCEvents_ClientServer[EventName]>,
|
|
||||||
CallbackReturn extends ReturnType<s.RPCEvents_ClientServer[EventName]>,
|
|
||||||
>(
|
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
cb: (
|
cb: RPCListener<s.RPCEvents_ClientServer, EventName, [player: number]>,
|
||||||
player: number,
|
|
||||||
...args: CallbackArguments
|
|
||||||
) => Awaited<CallbackReturn> | Promise<Awaited<CallbackReturn>>,
|
|
||||||
): this {
|
): this {
|
||||||
return this.listen(this._emitterClient, 'onClient', eventName, cb)
|
return this.listen(this._emitterClient, 'onClient', eventName, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
public offClient<EventName extends keyof s.RPCEvents_ClientServer>(
|
public offClient<EventName extends RPCEventName<s.RPCEvents_ClientServer>>(
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
): this {
|
): this {
|
||||||
return this.unlisten(this._emitterClient, 'offClient', eventName)
|
return this.unlisten(this._emitterClient, 'offClient', eventName)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async emitClient<
|
public async emitClient<
|
||||||
EventName extends keyof s.RPCEvents_ServerClient,
|
EventName extends RPCEventName<s.RPCEvents_ServerClient>,
|
||||||
Arguments extends Parameters<s.RPCEvents_ServerClient[EventName]>,
|
|
||||||
Response extends ReturnType<s.RPCEvents_ServerClient[EventName]>,
|
|
||||||
>(
|
>(
|
||||||
player: number,
|
player: number,
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
...args: Arguments
|
...args: RPCEventArgs<s.RPCEvents_ServerClient, EventName>
|
||||||
): Promise<Awaited<Response>> {
|
): Promise<RPCEventResult<s.RPCEvents_ServerClient, EventName>> {
|
||||||
const payload = this.request(eventName, 'client', args, player)
|
const payload = this.request(eventName, 'client', args, player)
|
||||||
|
|
||||||
emitNet(RPCEvents.LISTENER_SERVER, player, stringify(payload))
|
emitNet(RPCEvents.LISTENER_SERVER, player, stringify(payload))
|
||||||
|
|
||||||
return this._pending.wait<Awaited<Response>>(payload, player)
|
return this._pending.wait(payload, player)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async emitClientEveryone<
|
public async emitClientEveryone<
|
||||||
EventName extends keyof s.RPCEvents_ServerClient,
|
EventName extends RPCEventName<s.RPCEvents_ServerClient>,
|
||||||
Arguments extends Parameters<s.RPCEvents_ServerClient[EventName]>,
|
>(
|
||||||
>(eventName: EventName, ...args: Arguments): Promise<void> {
|
eventName: EventName,
|
||||||
|
...args: RPCEventArgs<s.RPCEvents_ServerClient, EventName>
|
||||||
|
): Promise<void> {
|
||||||
const payload = this.request(eventName, 'client', args, -1, 'broadcast')
|
const payload = this.request(eventName, 'client', args, -1, 'broadcast')
|
||||||
|
|
||||||
emitNet(RPCEvents.LISTENER_SERVER, -1, stringify(payload))
|
emitNet(RPCEvents.LISTENER_SERVER, -1, stringify(payload))
|
||||||
@@ -115,79 +115,60 @@ export class RPCInstanceServer extends RPCInstanceBase {
|
|||||||
|
|
||||||
// ===== WEBVIEW =====
|
// ===== WEBVIEW =====
|
||||||
|
|
||||||
public onWebview<
|
public onWebview<EventName extends RPCEventName<s.RPCEvents_WebviewServer>>(
|
||||||
EventName extends keyof s.RPCEvents_WebviewServer,
|
|
||||||
CallbackArguments extends Parameters<s.RPCEvents_WebviewServer[EventName]>,
|
|
||||||
CallbackReturn extends ReturnType<s.RPCEvents_WebviewServer[EventName]>,
|
|
||||||
>(
|
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
cb: (
|
cb: RPCListener<s.RPCEvents_WebviewServer, EventName, [player: number]>,
|
||||||
player: number,
|
|
||||||
...args: CallbackArguments
|
|
||||||
) => Awaited<CallbackReturn> | Promise<Awaited<CallbackReturn>>,
|
|
||||||
): this {
|
): this {
|
||||||
return this.listen(this._emitterWeb, 'onWebview', eventName, cb)
|
return this.listen(this._emitterWeb, 'onWebview', eventName, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
public offWebview<EventName extends keyof s.RPCEvents_WebviewServer>(
|
public offWebview<EventName extends RPCEventName<s.RPCEvents_WebviewServer>>(
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
): this {
|
): this {
|
||||||
return this.unlisten(this._emitterWeb, 'offWebview', eventName)
|
return this.unlisten(this._emitterWeb, 'offWebview', eventName)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async emitWebview<
|
public async emitWebview<
|
||||||
EventName extends keyof s.RPCEvents_ServerWebview,
|
EventName extends RPCEventName<s.RPCEvents_ServerWebview>,
|
||||||
Arguments extends Parameters<s.RPCEvents_ServerWebview[EventName]>,
|
|
||||||
Response extends ReturnType<s.RPCEvents_ServerWebview[EventName]>,
|
|
||||||
>(
|
>(
|
||||||
player: number,
|
player: number,
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
...args: Arguments
|
...args: RPCEventArgs<s.RPCEvents_ServerWebview, EventName>
|
||||||
): Promise<Awaited<Response>> {
|
): Promise<RPCEventResult<s.RPCEvents_ServerWebview, EventName>> {
|
||||||
const payload = this.request(eventName, 'webview', args, player)
|
const payload = this.request(eventName, 'webview', args, player)
|
||||||
|
|
||||||
emitNet(RPCEvents.LISTENER_SERVER, player, stringify(payload))
|
emitNet(RPCEvents.LISTENER_SERVER, player, stringify(payload))
|
||||||
|
|
||||||
return this._pending.wait<Awaited<Response>>(payload, player)
|
return this._pending.wait(payload, player)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== SELF =====
|
// ===== SELF =====
|
||||||
|
|
||||||
public onSelf<
|
public onSelf<EventName extends RPCEventName<s.RPCEvents_Server>>(
|
||||||
EventName extends keyof s.RPCEvents_Server,
|
|
||||||
CallbackArguments extends Parameters<s.RPCEvents_Server[EventName]>,
|
|
||||||
CallbackReturn extends ReturnType<s.RPCEvents_Server[EventName]>,
|
|
||||||
>(
|
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
cb: (
|
cb: RPCListener<s.RPCEvents_Server, EventName, [player: number]>,
|
||||||
...args: CallbackArguments
|
|
||||||
) => Awaited<CallbackReturn> | Promise<Awaited<CallbackReturn>>,
|
|
||||||
): this {
|
): this {
|
||||||
return this.listen(this._emitterLocal, 'onSelf', eventName, cb)
|
return this.listen(this._emitterLocal, 'onSelf', eventName, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
public offSelf<EventName extends keyof s.RPCEvents_Server>(
|
public offSelf<EventName extends RPCEventName<s.RPCEvents_Server>>(
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
): this {
|
): this {
|
||||||
return this.unlisten(this._emitterLocal, 'offSelf', eventName)
|
return this.unlisten(this._emitterLocal, 'offSelf', eventName)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async emitSelf<
|
public async emitSelf<EventName extends RPCEventName<s.RPCEvents_Server>>(
|
||||||
EventName extends keyof s.RPCEvents_Server,
|
eventName: EventName,
|
||||||
Arguments extends Parameters<s.RPCEvents_Server[EventName]>,
|
...args: RPCEventArgs<s.RPCEvents_Server, EventName>
|
||||||
Response extends ReturnType<s.RPCEvents_Server[EventName]>,
|
): Promise<RPCEventResult<s.RPCEvents_Server, EventName>> {
|
||||||
>(eventName: EventName, ...args: Arguments): Promise<Awaited<Response>> {
|
return this.emitLocal(eventName, args)
|
||||||
return this.emitLocal<Awaited<Response>>(eventName, args)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== OTHER =====
|
// ===== OTHER =====
|
||||||
|
|
||||||
public onCommand<
|
public onCommand<CommandName extends RPCCommandName<s.RPCCommands_Server>>(
|
||||||
CommandName extends s.RPCCommands_Server,
|
|
||||||
CallbackArguments extends unknown[],
|
|
||||||
>(
|
|
||||||
command: CommandName,
|
command: CommandName,
|
||||||
cb: (player: number, args: CallbackArguments, commandRaw: string) => void,
|
cb: (player: number, args: string[], rawCommand: string) => void,
|
||||||
restricted = false,
|
restricted = false,
|
||||||
): this {
|
): this {
|
||||||
this.log(`onCommand ${command}`)
|
this.log(`onCommand ${command}`)
|
||||||
@@ -197,10 +178,10 @@ export class RPCInstanceServer extends RPCInstanceBase {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
public onNativeEvent<
|
public onNativeEvent<EventName extends keyof RPCNativeServerEvents>(
|
||||||
EventName extends keyof RPCNativeServerEvents,
|
eventName: EventName,
|
||||||
CallbackArguments extends Parameters<RPCNativeServerEvents[EventName]>,
|
cb: (...args: Parameters<RPCNativeServerEvents[EventName]>) => void,
|
||||||
>(eventName: EventName, cb: (...args: CallbackArguments) => void): this {
|
): this {
|
||||||
if (!NATIVE_SERVER_EVENTS.includes(eventName)) {
|
if (!NATIVE_SERVER_EVENTS.includes(eventName)) {
|
||||||
throw new RPCError(
|
throw new RPCError(
|
||||||
RPCErrors.UNKNOWN_NATIVE,
|
RPCErrors.UNKNOWN_NATIVE,
|
||||||
|
|||||||
+33
-44
@@ -9,6 +9,12 @@ import {
|
|||||||
type RPCStateRaw,
|
type RPCStateRaw,
|
||||||
type RPCStateWeb,
|
type RPCStateWeb,
|
||||||
} from '../utils/types'
|
} from '../utils/types'
|
||||||
|
import type {
|
||||||
|
RPCEventArgs,
|
||||||
|
RPCEventName,
|
||||||
|
RPCEventResult,
|
||||||
|
RPCListener,
|
||||||
|
} from '../utils/typing'
|
||||||
import { RPCInstanceBase } from './base'
|
import { RPCInstanceBase } from './base'
|
||||||
|
|
||||||
export class RPCInstanceWebview extends RPCInstanceBase {
|
export class RPCInstanceWebview extends RPCInstanceBase {
|
||||||
@@ -64,93 +70,76 @@ export class RPCInstanceWebview extends RPCInstanceBase {
|
|||||||
|
|
||||||
// ===== CLIENT =====
|
// ===== CLIENT =====
|
||||||
|
|
||||||
public onClient<
|
public onClient<EventName extends RPCEventName<s.RPCEvents_ClientWebview>>(
|
||||||
EventName extends keyof s.RPCEvents_ClientWebview,
|
|
||||||
CallbackArguments extends Parameters<s.RPCEvents_ClientWebview[EventName]>,
|
|
||||||
CallbackReturn extends ReturnType<s.RPCEvents_ClientWebview[EventName]>,
|
|
||||||
>(
|
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
cb: (
|
cb: RPCListener<s.RPCEvents_ClientWebview, EventName>,
|
||||||
...args: CallbackArguments
|
|
||||||
) => Awaited<CallbackReturn> | Promise<Awaited<CallbackReturn>>,
|
|
||||||
): this {
|
): this {
|
||||||
return this.listen(this._emitterClient, 'onClient', eventName, cb)
|
return this.listen(this._emitterClient, 'onClient', eventName, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
public offClient<EventName extends keyof s.RPCEvents_ClientWebview>(
|
public offClient<EventName extends RPCEventName<s.RPCEvents_ClientWebview>>(
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
): this {
|
): this {
|
||||||
return this.unlisten(this._emitterClient, 'offClient', eventName)
|
return this.unlisten(this._emitterClient, 'offClient', eventName)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async emitClient<
|
public async emitClient<
|
||||||
EventName extends keyof s.RPCEvents_WebviewClient,
|
EventName extends RPCEventName<s.RPCEvents_WebviewClient>,
|
||||||
Arguments extends Parameters<s.RPCEvents_WebviewClient[EventName]>,
|
>(
|
||||||
Response extends ReturnType<s.RPCEvents_WebviewClient[EventName]>,
|
eventName: EventName,
|
||||||
>(eventName: EventName, ...args: Arguments): Promise<Awaited<Response>> {
|
...args: RPCEventArgs<s.RPCEvents_WebviewClient, EventName>
|
||||||
|
): Promise<RPCEventResult<s.RPCEvents_WebviewClient, EventName>> {
|
||||||
const payload = this.request(eventName, 'client', args, null)
|
const payload = this.request(eventName, 'client', args, null)
|
||||||
|
|
||||||
return this._request<Awaited<Response>>(payload)
|
return this._request(payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== SERVER =====
|
// ===== SERVER =====
|
||||||
|
|
||||||
public onServer<
|
public onServer<EventName extends RPCEventName<s.RPCEvents_ServerWebview>>(
|
||||||
EventName extends keyof s.RPCEvents_ServerWebview,
|
|
||||||
CallbackArguments extends Parameters<s.RPCEvents_ServerWebview[EventName]>,
|
|
||||||
CallbackReturn extends ReturnType<s.RPCEvents_ServerWebview[EventName]>,
|
|
||||||
>(
|
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
cb: (
|
cb: RPCListener<s.RPCEvents_ServerWebview, EventName>,
|
||||||
...args: CallbackArguments
|
|
||||||
) => Awaited<CallbackReturn> | Promise<Awaited<CallbackReturn>>,
|
|
||||||
): this {
|
): this {
|
||||||
return this.listen(this._emitterServer, 'onServer', eventName, cb)
|
return this.listen(this._emitterServer, 'onServer', eventName, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
public offServer<EventName extends keyof s.RPCEvents_ServerWebview>(
|
public offServer<EventName extends RPCEventName<s.RPCEvents_ServerWebview>>(
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
): RPCInstanceWebview {
|
): this {
|
||||||
return this.unlisten(this._emitterServer, 'offServer', eventName)
|
return this.unlisten(this._emitterServer, 'offServer', eventName)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async emitServer<
|
public async emitServer<
|
||||||
EventName extends keyof s.RPCEvents_WebviewServer,
|
EventName extends RPCEventName<s.RPCEvents_WebviewServer>,
|
||||||
Arguments extends Parameters<s.RPCEvents_WebviewServer[EventName]>,
|
>(
|
||||||
Response extends ReturnType<s.RPCEvents_WebviewServer[EventName]>,
|
eventName: EventName,
|
||||||
>(eventName: EventName, ...args: Arguments): Promise<Awaited<Response>> {
|
...args: RPCEventArgs<s.RPCEvents_WebviewServer, EventName>
|
||||||
|
): Promise<RPCEventResult<s.RPCEvents_WebviewServer, EventName>> {
|
||||||
const payload = this.request(eventName, 'server', args, null)
|
const payload = this.request(eventName, 'server', args, null)
|
||||||
|
|
||||||
return this._request<Awaited<Response>>(payload)
|
return this._request(payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== SELF =====
|
// ===== SELF =====
|
||||||
|
|
||||||
public onSelf<
|
public onSelf<EventName extends RPCEventName<s.RPCEvents_Webview>>(
|
||||||
EventName extends keyof s.RPCEvents_Webview,
|
|
||||||
CallbackArguments extends Parameters<s.RPCEvents_Webview[EventName]>,
|
|
||||||
CallbackReturn extends ReturnType<s.RPCEvents_Webview[EventName]>,
|
|
||||||
>(
|
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
cb: (
|
cb: RPCListener<s.RPCEvents_Webview, EventName>,
|
||||||
...args: CallbackArguments
|
|
||||||
) => Awaited<CallbackReturn> | Promise<Awaited<CallbackReturn>>,
|
|
||||||
): this {
|
): this {
|
||||||
return this.listen(this._emitterLocal, 'onSelf', eventName, cb)
|
return this.listen(this._emitterLocal, 'onSelf', eventName, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
public offSelf<EventName extends keyof s.RPCEvents_Webview>(
|
public offSelf<EventName extends RPCEventName<s.RPCEvents_Webview>>(
|
||||||
eventName: EventName,
|
eventName: EventName,
|
||||||
): this {
|
): this {
|
||||||
return this.unlisten(this._emitterLocal, 'offSelf', eventName)
|
return this.unlisten(this._emitterLocal, 'offSelf', eventName)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async emitSelf<
|
public async emitSelf<EventName extends RPCEventName<s.RPCEvents_Webview>>(
|
||||||
EventName extends keyof s.RPCEvents_Webview,
|
eventName: EventName,
|
||||||
Arguments extends Parameters<s.RPCEvents_Webview[EventName]>,
|
...args: RPCEventArgs<s.RPCEvents_Webview, EventName>
|
||||||
Response extends ReturnType<s.RPCEvents_Webview[EventName]>,
|
): Promise<RPCEventResult<s.RPCEvents_Webview, EventName>> {
|
||||||
>(eventName: EventName, ...args: Arguments): Promise<Awaited<Response>> {
|
return this.emitLocal(eventName, args)
|
||||||
return this.emitLocal<Awaited<Response>>(eventName, args)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== UTILS =====
|
// ===== UTILS =====
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* **Internal** Typing helpers over the event maps of
|
||||||
|
* `@entityseven/fivem-rpc-shared-types`. A map with declarations is typed
|
||||||
|
* strictly; an empty map (nothing declared, or the package not installed)
|
||||||
|
* accepts any name, any arguments and any result.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// oxlint-disable-next-line typescript/no-explicit-any -- loose mode must accept listeners with any parameter types
|
||||||
|
type AnyEvent = (...args: any[]) => any
|
||||||
|
|
||||||
|
/** `true` for `any`, which is what the maps become if the package is missing */
|
||||||
|
type IsAny<T> = 0 extends 1 & T ? true : false
|
||||||
|
|
||||||
|
/** The declared map, or a loose one when nothing is declared */
|
||||||
|
type EventMap<T> =
|
||||||
|
IsAny<T> extends true
|
||||||
|
? Record<string, AnyEvent>
|
||||||
|
: [keyof T] extends [never]
|
||||||
|
? Record<string, AnyEvent>
|
||||||
|
: T
|
||||||
|
|
||||||
|
export type RPCEventName<T> = keyof EventMap<T> & string
|
||||||
|
|
||||||
|
export type RPCEventArgs<
|
||||||
|
T,
|
||||||
|
K extends RPCEventName<T>,
|
||||||
|
> = EventMap<T>[K] extends (...args: infer A extends unknown[]) => unknown
|
||||||
|
? A
|
||||||
|
: never
|
||||||
|
|
||||||
|
export type RPCEventResult<
|
||||||
|
T,
|
||||||
|
K extends RPCEventName<T>,
|
||||||
|
> = EventMap<T>[K] extends (...args: never[]) => infer R ? Awaited<R> : never
|
||||||
|
|
||||||
|
/** Listener for event `K` of map `T`; `Prefix` goes before the event arguments */
|
||||||
|
export type RPCListener<
|
||||||
|
T,
|
||||||
|
K extends RPCEventName<T>,
|
||||||
|
Prefix extends unknown[] = [],
|
||||||
|
> = (
|
||||||
|
...args: [...Prefix, ...RPCEventArgs<T, K>]
|
||||||
|
) => RPCEventResult<T, K> | Promise<RPCEventResult<T, K>>
|
||||||
|
|
||||||
|
export type RPCCommandName<T> = [keyof T] extends [never]
|
||||||
|
? string
|
||||||
|
: keyof T & string
|
||||||
Vendored
+58
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* Event and command declarations for `@entityseven/fivem-rpc`.
|
||||||
|
*
|
||||||
|
* Every interface starts empty: until you declare something in it, the matching
|
||||||
|
* rpc methods accept any name and any arguments. Declare your own by augmenting
|
||||||
|
* this module from any `.d.ts` (or `.ts`) file included in your project:
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // shared/rpc.d.ts
|
||||||
|
* import '@entityseven/fivem-rpc-shared-types'
|
||||||
|
*
|
||||||
|
* declare module '@entityseven/fivem-rpc-shared-types' {
|
||||||
|
* interface RPCEvents_ClientServer {
|
||||||
|
* // name(arguments): value returned by the listener
|
||||||
|
* buyItem(item: string, amount: number): boolean
|
||||||
|
* }
|
||||||
|
* interface RPCCommands_Server {
|
||||||
|
* ban: true
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ===== COMMANDS (names are the keys, values are not used) =====
|
||||||
|
|
||||||
|
/** Commands registered with `rpc.onCommand` on the client */
|
||||||
|
export interface RPCCommands_Client {}
|
||||||
|
|
||||||
|
/** Commands registered with `rpc.onCommand` on the server */
|
||||||
|
export interface RPCCommands_Server {}
|
||||||
|
|
||||||
|
// ===== EVENTS (caller -> receiver) =====
|
||||||
|
|
||||||
|
/** Client -> client: `emitSelf` / `onSelf` on the client */
|
||||||
|
export interface RPCEvents_Client {}
|
||||||
|
|
||||||
|
/** Client -> server: `emitServer` on the client, `onClient` on the server */
|
||||||
|
export interface RPCEvents_ClientServer {}
|
||||||
|
|
||||||
|
/** Client -> webview: `emitWebview` on the client, `onClient` on the webview */
|
||||||
|
export interface RPCEvents_ClientWebview {}
|
||||||
|
|
||||||
|
/** Server -> server: `emitSelf` / `onSelf` on the server */
|
||||||
|
export interface RPCEvents_Server {}
|
||||||
|
|
||||||
|
/** Server -> client: `emitClient` on the server, `onServer` on the client */
|
||||||
|
export interface RPCEvents_ServerClient {}
|
||||||
|
|
||||||
|
/** Server -> webview: `emitWebview` on the server, `onServer` on the webview */
|
||||||
|
export interface RPCEvents_ServerWebview {}
|
||||||
|
|
||||||
|
/** Webview -> webview: `emitSelf` / `onSelf` on the webview */
|
||||||
|
export interface RPCEvents_Webview {}
|
||||||
|
|
||||||
|
/** Webview -> client: `emitClient` on the webview, `onWebview` on the client */
|
||||||
|
export interface RPCEvents_WebviewClient {}
|
||||||
|
|
||||||
|
/** Webview -> server: `emitServer` on the webview, `onWebview` on the server */
|
||||||
|
export interface RPCEvents_WebviewServer {}
|
||||||
@@ -28,12 +28,17 @@
|
|||||||
"directory": "shared-types"
|
"directory": "shared-types"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"types/**/*",
|
"index.d.ts",
|
||||||
"readme.md",
|
"readme.md",
|
||||||
"license.md"
|
"license.md"
|
||||||
],
|
],
|
||||||
"type": "module",
|
"types": "./index.d.ts",
|
||||||
"types": "types/types/index.d.ts",
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./index.d.ts"
|
||||||
|
},
|
||||||
|
"./package.json": "./package.json"
|
||||||
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": ">=5"
|
"typescript": ">=5"
|
||||||
},
|
},
|
||||||
|
|||||||
Vendored
-52
@@ -1,52 +0,0 @@
|
|||||||
declare module '@entityseven/fivem-rpc-shared-types' {
|
|
||||||
// Client commands names
|
|
||||||
export type RPCCommands_Client = ''
|
|
||||||
|
|
||||||
// Server commands names
|
|
||||||
export type RPCCommands_Server = ''
|
|
||||||
|
|
||||||
// Client -> Client events
|
|
||||||
export interface RPCEvents_Client {
|
|
||||||
_(): void
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client -> Server events
|
|
||||||
export interface RPCEvents_ClientServer {
|
|
||||||
_(): void
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client -> Webview events
|
|
||||||
export interface RPCEvents_ClientWebview {
|
|
||||||
_(): void
|
|
||||||
}
|
|
||||||
|
|
||||||
// Server -> Server events
|
|
||||||
export interface RPCEvents_Server {
|
|
||||||
_(): void
|
|
||||||
}
|
|
||||||
|
|
||||||
// Server -> Client events
|
|
||||||
export interface RPCEvents_ServerClient {
|
|
||||||
_(): void
|
|
||||||
}
|
|
||||||
|
|
||||||
// Server -> Server events
|
|
||||||
export interface RPCEvents_ServerWebview {
|
|
||||||
_(): void
|
|
||||||
}
|
|
||||||
|
|
||||||
// Webview -> Webview events
|
|
||||||
export interface RPCEvents_Webview {
|
|
||||||
_(): void
|
|
||||||
}
|
|
||||||
|
|
||||||
// Webview -> Client events
|
|
||||||
export interface RPCEvents_WebviewClient {
|
|
||||||
_(): void
|
|
||||||
}
|
|
||||||
|
|
||||||
// Webview -> Server events
|
|
||||||
export interface RPCEvents_WebviewServer {
|
|
||||||
_(): void
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user