You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vizality/renderer/src/api/RPC.js

182 lines
4.7 KiB

/**
* The RPC API
* @module RPC
* @memberof API
* @namespace API.RPC
* @version 1.0.0
*/
/**
* @typedef DiscordRpcEvent
* @todo Dig into Discord's more complex selectors (seem to be mongo-ish).
* @todo Document validation field
* @property {string} scope RPC scope required
* @property {function(object): void} handler RPC event handler
* @property {any|undefined} validation Validator for incoming data
*/
import { getCaller } from '@vizality/util/file';
import { API } from '@vizality/entities';
let scopes = {};
let events = {};
let commands = {};
/**
* @extends API
* @extends Events
*/
export default class RPC extends API {
constructor () {
super();
this.scopes = {};
this.events = {};
this.commands = {};
}
/**
* Shuts down the API, removing all listeners and stored objects.
*/
stop () {
this.unregisterAllScopes();
this.unregisterAllEvents();
this.unregisterAllCommands();
this.removeAllListeners();
delete vizality.api.rpc;
}
/**
* Registers a scope.
* @param {string} scopeId Scope ID
* @param {function(string): boolean} grant Grant method. Receives the origin as first argument
* @emits RPC#scopeAdd
*/
registerScope (scopeId, grant) {
try {
if (!scopeId) {
throw new Error('RPC scope must contain a valid ID!');
}
if (this.scopes[scopeId]) {
throw new Error(`RPC scope ID "${scopeId}" is already registered!`);
}
this.scopes[scopeId] = {};
this.scopes[scopeId].caller = getCaller();
this.scopes[scopeId].grant = grant;
this.emit('scopeAdd', scopeId);
} catch (err) {
return this.error(err);
}
}
/**
* Registers an event.
* @param {DiscordRpcEvent} event Event properties
* @emits RPC#eventAdd
*/
registerEvent (event) {
try {
if (!event?.id) {
throw new Error('RPC command must contain a valid ID!');
}
// @todo Ask AAGaming about other properties
if (this.events[event.id]) {
throw new Error(`RPC event ID "${event.id}" is already registered!`);
}
// eslint-disable-next-line no-empty-function
if (!event.handler) event.handler = () => {};
event.caller = getCaller();
this.events[event.id] = event;
this.emit('eventAdd', event.id);
} catch (err) {
return this.error(err);
}
}
/**
* Registers a command.
* @param {DiscordRpcEvent} command Command properties
* @emits RPC#eventAdd
*/
registerCommand (command) {
try {
if (!command?.id) {
throw new Error('RPC command must contain a valid ID!');
}
if (!command.scope) {
throw new Error(`RPC command ID "${command.id} cannot be registered without a valid scope!`);
}
if (!command.handler || typeof command.handler !== 'function') {
throw new Error(`RPC command ID "${command.id} cannot be registered without a valid handler!`);
}
if (this.commands[command.id]) {
throw new Error(`RPC command ID "${command.id}" is already registered!`);
}
command.caller = getCaller();
this.commands[command.id] = command;
this.emit('commandAdd', command.id);
} catch (err) {
return this.error(err);
}
}
/**
* Unregisters a scope.
* @param {string} scopeId Scope ID
* @emits RPC#scopeRemove
*/
unregisterScope (scopeId) {
try {
if (!scopeId) {
throw new Error(`Invalid RPC scope ID provided!`);
}
if (!this.scopes[scopeId]) {
throw new Error(`RPC scope ID "${scopeId}" is not registered, so it cannot be unregistered!`);
}
delete this.scopes[scopeId];
this.emit('scopeRemove', scopeId);
} catch (err) {
return this.error(err);
}
}
/**
* Unregisters an event.
* @param {string} eventId Event ID
* @emits RPC#eventRemove
*/
unregisterEvent (eventId) {
try {
if (!eventId) {
throw new Error(`Invalid RPC event ID provided!`);
}
if (!this.events[eventId]) {
throw new Error(`RPC event ID "${eventId}" is not registered, so it cannot be unregistered!`);
}
delete this.events[eventId];
this.emit('eventRemove', eventId);
} catch (err) {
return this.error(err);
}
}
/**
* Unregisters a command.
* @param {string} commandId Command ID
* @emits RPC#commandRemove
*/
unregisterCommand (commandId) {
try {
if (!commandId) {
throw new Error(`Invalid RPC command ID provided!`);
}
if (!this.commands[commandId]) {
throw new Error(`RPC command ID "${commandId}" is not registered, so it cannot be unregistered!`);
}
delete this.commands[commandId];
this.emit('commandRemove', commandId);
} catch (err) {
return this.error(err);
}
}
}