UNPKG

@elgato-stream-deck/tcp

Version:

An npm module for interfacing with select Elgato Stream Deck devices in node over tcp

106 lines 3.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StreamDeckTcpDiscoveryService = void 0; const bonjour_service_1 = require("@julusian/bonjour-service"); const events_1 = require("events"); const constants_js_1 = require("./constants.js"); const core_1 = require("@elgato-stream-deck/core"); const core_2 = require("@elgato-stream-deck/core"); function convertService(service) { if (!service.addresses || service.addresses.length === 0) return null; const dt = Number(service.txt.dt); if (isNaN(dt)) return null; if (dt === 215) { // This should be a Stream Deck Network Dock // The implementation isn't ideal, but it works well enough and avoids a breaking change to the types return { address: service.addresses[0], port: service.port, name: service.name, vendorId: core_2.VENDOR_ID, productId: 0xffff, // This doesn't have a product id, but we need to set it to something serialNumber: service.txt.sn, modelType: core_1.DeviceModelType.NETWORK_DOCK, modelId: core_1.DeviceModelId.NETWORK_DOCK, modelName: core_1.MODEL_NAMES[core_1.DeviceModelId.NETWORK_DOCK], isPrimary: true, }; } // Get and parse the vendor and product id const vendorId = Number(service.txt.vid); const productId = Number(service.txt.pid); if (isNaN(vendorId) || isNaN(productId)) return null; // Find the corresponding model const model = core_2.DEVICE_MODELS.find((model) => core_2.VENDOR_ID === vendorId && model.productIds.includes(productId)); if (!model) return null; return { address: service.addresses[0], port: service.port, name: service.name, vendorId, productId, serialNumber: service.txt.sn, modelType: model.type, modelId: model.id, modelName: model.productName, isPrimary: model.hasNativeTcp, }; } class StreamDeckTcpDiscoveryService extends events_1.EventEmitter { #server; #browser; #queryInterval; constructor(options) { super(); this.#server = new bonjour_service_1.Bonjour(); this.#browser = this.#server.find({ type: 'elg', protocol: 'tcp', }); this.#browser.on('up', (service) => this.#emitUp(service)); this.#browser.on('down', (service) => this.#emitDown(service)); this.#browser.on('srv-update', (newService, existingService) => { this.#emitDown(existingService); this.#emitUp(newService); }); const queryInterval = options?.queryInterval ?? constants_js_1.DEFAULT_MDNS_QUERY_INTERVAL; if (queryInterval >= 0) { this.#queryInterval = setInterval(() => this.query(), queryInterval); } } get knownStreamDecks() { return this.#browser.services.map(convertService).filter((svc) => !!svc); } #emitDown(service) { const serviceDefinition = convertService(service); if (!serviceDefinition) return; this.emit('down', serviceDefinition); } #emitUp(service) { const serviceDefinition = convertService(service); if (!serviceDefinition) return; this.emit('up', serviceDefinition); } /** * Broadcast the query to the network */ query() { // Tell the browser to resend the query this.#browser.update(); // Tell the browser to expire any services that haven't been seen in a while this.#browser.expire(); } destroy() { if (this.#queryInterval) clearInterval(this.#queryInterval); this.#server.destroy(); } } exports.StreamDeckTcpDiscoveryService = StreamDeckTcpDiscoveryService; //# sourceMappingURL=discoveryService.js.map