UNPKG

kodi-api

Version:

A complete implementation of Kodi JSON-RPC calls in an easy-to-use Javascript/TypeScript client.

97 lines (96 loc) 3.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WebSocketClient = void 0; const rpc_websocket_client_1 = require("rpc-websocket-client"); const uuid_1 = require("uuid"); /** Custom class for web socket interactions with JSON-RPC. */ class WebSocketClient { constructor(options = {}) { const config = { host: 'localhost', port: 9090, closeOnRequest: true, ...options }; this.closeOnRequest = config.closeOnRequest; this.connected = false; this.url = 'ws://' + config.host + ':' + config.port.toString() + '/jsonrpc'; this.nextId = ''; } /** Closely matches the type from Jayson/promise import. */ async request(method, params, id) { if (!this.connected) await this.connect(this.url); if (typeof id === 'string') this.nextId = id; const result = await this.io.call(method, params); if (this.closeOnRequest) await this.disconnect(); return { id: typeof id === 'string' ? id : this.lastId, jsonrpc: '2.0', result }; } /** Custom unique ID function following internal state. */ id() { // If no `nextId` was cached, generate a unique id. if (this.nextId === '') { const id = uuid_1.v4(); this.lastId = id; return id; } // Use the cached id, and reset `nextId` when done. const id = this.nextId; this.lastId = id; this.nextId = ''; return id; } /** Manage custom connection logic. */ async connect(url) { this.io = new rpc_websocket_client_1.RpcWebSocketClient(); this.io.onOpen(() => { this.connected = true; }); this.io.onClose(() => { this.connected = false; }); this.io.customId(() => this.id()); if (typeof url === 'string') { await this.io.connect(url); } else { await this.io.connect(this.url); } if (typeof this.io.ws === 'object') { const onmessage = this.io.ws.onmessage; this.io.ws.onmessage = (e) => { // Handle syntax errors due to intermittent issues with non-string/non-JSON data on Kodi web socket. try { onmessage(e); } catch (err) { for (const handler of this.io.onErrorResponse) { handler(err); } } }; } } /** Manage graceful disconnect from web socket. */ async disconnect() { const close = new Promise((resolve, reject) => { let ioHandler = (e) => { }; if (typeof this.io.ws.onclose === 'function') { ioHandler = this.io.ws.onclose; } this.io.ws.onclose = (e) => { ioHandler(e); resolve(void 0); }; this.io.ws.close(); }); return await close; } } exports.WebSocketClient = WebSocketClient;