UNPKG

xkeys-webhid

Version:

An npm module for interfacing with the X-keys panels in a browser

102 lines 4.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setupXkeysPanel = exports.getOpenedXKeysPanels = exports.requestXkeysPanels = void 0; const core_1 = require("@xkeys-lib/core"); const web_hid_wrapper_1 = require("./web-hid-wrapper"); const globalConnectListener_1 = require("./globalConnectListener"); /** Prompts the user for which X-keys panel to select */ async function requestXkeysPanels() { const allDevices = await navigator.hid.requestDevice({ filters: [ { vendorId: core_1.XKEYS_VENDOR_ID, }, ], }); const newDevices = allDevices.filter(isValidXkeysUsage); if (newDevices.length > 0) globalConnectListener_1.GlobalConnectListener.notifyConnectedDevice(); // A fix for when the 'connect' event isn't fired return newDevices; } exports.requestXkeysPanels = requestXkeysPanels; /** * Reopen previously selected devices. * The browser remembers what the user previously allowed your site to access, and this will open those without the request dialog */ async function getOpenedXKeysPanels() { const allDevices = await navigator.hid.getDevices(); return allDevices.filter(isValidXkeysUsage); } exports.getOpenedXKeysPanels = getOpenedXKeysPanels; function isValidXkeysUsage(device) { if (device.vendorId !== core_1.XKEYS_VENDOR_ID) return false; return !!device.collections.find((collection) => { var _a; if (collection.usagePage !== 12) return false; // Check the write-length of the device is > 20 return !!((_a = collection.outputReports) === null || _a === void 0 ? void 0 : _a.find((report) => { var _a; return !!((_a = report.items) === null || _a === void 0 ? void 0 : _a.find((item) => { var _a; return (_a = item.reportCount) !== null && _a !== void 0 ? _a : 0 > 20; })); })); }); } /** Sets up a connection to a HID device (the X-keys panel) */ async function setupXkeysPanel(browserDevice) { var _a; if (!((_a = browserDevice === null || browserDevice === void 0 ? void 0 : browserDevice.collections) === null || _a === void 0 ? void 0 : _a.length)) throw Error(`device collections is empty`); if (!isValidXkeysUsage(browserDevice)) throw new Error(`Device has incorrect usage/interface`); if (!browserDevice.productId) throw Error(`Device has no productId!`); const vendorId = browserDevice.vendorId; const productId = browserDevice.productId; if (!browserDevice.opened) { await browserDevice.open(); } const deviceWrap = new web_hid_wrapper_1.WebHIDDevice(browserDevice); const xkeys = new core_1.XKeys(deviceWrap, { product: browserDevice.productName, vendorId: vendorId, productId: productId, interface: null, // todo: Check what to use here (collection.usage?) }, undefined); // Setup listener for disconnect: globalConnectListener_1.GlobalConnectListener.listenForDisconnectOnce(browserDevice, () => { xkeys._handleDeviceDisconnected().catch((e) => { console.error(`Xkeys: Error handling disconnect:`, e); }); }); let alreadyRejected = false; try { await new Promise((resolve, reject) => { const markRejected = (e) => { reject(e); alreadyRejected = true; }; const xkeysStopgapErrorHandler = (e) => { if (alreadyRejected) { console.error(`Xkeys: Error emitted after setup already rejected:`, e); return; } markRejected(e); }; // Handle all error events until the instance is returned xkeys.on('error', xkeysStopgapErrorHandler); // Wait for the device to initialize: xkeys .init() .then(() => { resolve(); xkeys.removeListener('error', xkeysStopgapErrorHandler); }) .catch(markRejected); }); return xkeys; } catch (e) { await deviceWrap.close(); throw e; } } exports.setupXkeysPanel = setupXkeysPanel; //# sourceMappingURL=methods.js.map