UNPKG

@duncte123/obs-websocket-js

Version:
98 lines (83 loc) 3.24 kB
const Socket = require('./Socket'); const Status = require('./Status'); const debug = require('debug')('obs-websocket-js:Core'); let requestCounter = 0; function generateMessageId() { return String(requestCounter++); } class OBSWebSocket extends Socket { /** * Generic Socket request method. Returns a promise. * Generates a messageId internally and will override any passed in the args. * Note that the requestType here is pre-marshaling and currently must match exactly what the websocket plugin is expecting. * * @param {String} requestType obs-websocket plugin expected request type. * @param {Object} [args={}] request arguments. * @return {Promise} Promise, passes the plugin response object. */ send(requestType, args = {}) { args = args || {}; return new Promise((resolve, reject) => { const messageId = generateMessageId(); let rejectReason; if (!requestType) { rejectReason = Status.REQUEST_TYPE_NOT_SPECIFIED; } if (args && (typeof args !== 'object' || args === null || Array.isArray(args))) { rejectReason = Status.ARGS_NOT_OBJECT; } if (!this._connected) { rejectReason = Status.NOT_CONNECTED; } // Assign a temporary event listener for this particular messageId to uniquely identify the response. this.once(`obs:internal:message:id-${messageId}`, (err, data) => { if (err) { debug('[send:reject] %o', err); reject(err); } else { debug('[send:resolve] %o', data); resolve(data); } }); // If we don't have a reason to fail fast, send the request to the socket. if (!rejectReason) { args['request-type'] = requestType; args['message-id'] = messageId; // Submit the request to the websocket. debug('[send] %s %s %o', messageId, requestType, args); try { this._socket.send(JSON.stringify(args)); } catch (_) { // TODO: Consider inspecting the exception thrown to gleam some relevant info and pass that on. rejectReason = Status.SOCKET_EXCEPTION; } } // If the socket call was unsuccessful or bypassed, simulate its resolution. if (rejectReason) { this.emit(`obs:internal:message:id-${messageId}`, rejectReason); } }); } /** * Generic Socket request method. Handles callbacks. * Internally calls `send` (which is promise-based). See `send`'s docs for more details. * * @param {String} requestType obs-websocket plugin expected request type. * @param {Object} [args={}] request arguments. * @param {Function} callback Optional. callback(err, data) */ sendCallback(requestType, args = {}, callback) { // eslint-disable-line default-param-last // Allow the `args` argument to be omitted. if (callback === undefined && typeof args === 'function') { callback = args; args = {}; } // Perform the actual request, using `send`. this.send(requestType, args).then((...response) => { callback(null, ...response); }).catch(error => { callback(error); }); } } module.exports = OBSWebSocket;