diff --git a/rpc/src/index.ts b/rpc/src/index.ts index 82e7c17..180f773 100644 --- a/rpc/src/index.ts +++ b/rpc/src/index.ts @@ -1,7 +1,7 @@ import { RPCInstanceClient } from './core/client' import { RPCInstanceServer } from './core/server' import { RPCInstanceWebview } from './core/webview' -import { RPCError } from './utils/errors' +import { RPCError, unknownEnvironmentMessage } from './utils/errors' import { type RPCConfig, type RPCEnvironment, @@ -10,64 +10,56 @@ import { } from './utils/types' /** - * RPC Factory + * Creates the RPC instance for one environment. Create exactly one per + * environment (server, client, webview) and export it from a local module. + * + * @throws {@link RPCError} `UNKNOWN_ENVIRONMENT` if `config.env` is not + * `'server'`, `'client'` or `'webview'` * * @example - * // returns RPCInstanceServer - * const rpc = new RPCFactory({ env: "server" }).get() - * - * @example - * // returns RPCInstanceClient - * const rpc = new RPCFactory({ env: "client" }).get() - * - * @example - * // returns RPCInstanceWebview - * const rpc = new RPCFactory({ env: "webview" }).get() - * - * @class + * // server/rpc.ts + * import { createRPC } from '@entityseven/fivem-rpc' + * export const rpc = createRPC({ env: 'server' }) */ -class RPCFactory { - private readonly operator: - | RPCInstanceServer - | RPCInstanceClient - | RPCInstanceWebview - - /** - * Instance options - * @param {object} opts - Options - * @param {string} opts.env - Instance environment - * @param {boolean} opts.debug - Show additional logs - */ - constructor(opts: RPCConfig) { - console.log('[RPC] Initializing...') - - switch (opts.env) { - case 'server': - this.operator = new RPCInstanceServer(opts as RPCConfig<'server'>) - break - case 'client': - this.operator = new RPCInstanceClient(opts as RPCConfig<'client'>) - break - case 'webview': - this.operator = new RPCInstanceWebview(opts as RPCConfig<'webview'>) - break - default: - throw new RPCError( - RPCErrors.UNKNOWN_ENVIRONMENT, - RPCErrors.UNKNOWN_ENVIRONMENT, - ) - } - } - - public get(): RPCEnvironmentResolved { - return this.operator as RPCEnvironmentResolved +export function createRPC( + config: RPCConfig, +): RPCEnvironmentResolved { + switch (config.env) { + case 'server': + return new RPCInstanceServer( + config as RPCConfig<'server'>, + ) as RPCEnvironmentResolved + case 'client': + return new RPCInstanceClient( + config as RPCConfig<'client'>, + ) as RPCEnvironmentResolved + case 'webview': + return new RPCInstanceWebview( + config as RPCConfig<'webview'>, + ) as RPCEnvironmentResolved + default: + throw new RPCError( + RPCErrors.UNKNOWN_ENVIRONMENT, + unknownEnvironmentMessage(config.env), + ) } } -export { RPCFactory } -export * from './utils/types' +export type { RPCInstanceClient } from './core/client' +export type { RPCInstanceServer } from './core/server' +export type { RPCInstanceWebview } from './core/webview' export { RPCError, type RPCErrorDetails } from './utils/errors' -export * from './utils/native' -export type * from './core/server' -export type * from './core/client' -export type * from './core/webview' +export { + NATIVE_CLIENT_EVENTS, + NATIVE_CLIENT_NETWORK_EVENTS, + NATIVE_SERVER_EVENTS, +} from './utils/native' +export { + type RPCConfig, + type RPCEnvironment, + RPCErrors, + type RPCNativeClientEvents, + type RPCNativeClientNetworkEvents, + type RPCNativeClientNetworkEventsNames, + type RPCNativeServerEvents, +} from './utils/types' diff --git a/rpc/src/utils/errors.ts b/rpc/src/utils/errors.ts index ab4eb05..73389f1 100644 --- a/rpc/src/utils/errors.ts +++ b/rpc/src/utils/errors.ts @@ -66,6 +66,11 @@ export function notRegisteredMessage( return `No listener for "${event}" on ${receiver}. Register it with rpc.${listenerName(receiver, sender)}("${event}", ...) in ${receiver} code.` } +/** **Internal** */ +export function unknownEnvironmentMessage(env: unknown): string { + return `Unknown env ${JSON.stringify(env)}. Use createRPC({ env: 'server' }), 'client' or 'webview'.` +} + /** **Internal** */ export function unknownNativeMessage(event: string, list: string): string { return `"${event}" is not in ${list}. Events not listed there can be registered with FiveM's on("${event}", ...) directly.` diff --git a/rpc/src/utils/types.ts b/rpc/src/utils/types.ts index 221375a..b42cecb 100644 --- a/rpc/src/utils/types.ts +++ b/rpc/src/utils/types.ts @@ -17,13 +17,15 @@ export type RPCEnvironmentResolved = ? RPCInstanceWebview : never -/** - * `RPCFactory` config. - * - * If environment does not match will throw `RPCErrors.UNKNOWN_ENVIRONMENT` - */ -export type RPCConfig = { +/** `createRPC` config */ +export type RPCConfig = { + /** Environment this instance runs in */ env: T + /** + * Log every registration, call and incoming payload + * + * @defaultValue false + */ debug?: boolean /** * Milliseconds to wait for a response before the call rejects with @@ -103,7 +105,7 @@ export enum RPCEvents { export enum RPCErrors { EVENT_NOT_REGISTERED = 'Event not registered', UNKNOWN_NATIVE = 'Unknown native event', - UNKNOWN_ENVIRONMENT = 'Unknown environment (must be either "server", "client" or "webview")', + UNKNOWN_ENVIRONMENT = 'Unknown environment', TIMEOUT = 'Timed out waiting for response', HANDLER_ERROR = 'Listener threw an error', }