buttplug 3.1.1 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/.eslintrc.js +13 -8
  2. package/CHANGELOG.md +23 -0
  3. package/README.md +24 -25
  4. package/dist/main/src/client/ButtplugBrowserWebsocketClientConnector.d.ts +13 -16
  5. package/dist/main/src/client/ButtplugBrowserWebsocketClientConnector.js +23 -52
  6. package/dist/main/src/client/ButtplugBrowserWebsocketClientConnector.js.map +1 -1
  7. package/dist/main/src/client/ButtplugClientConnectorException.d.ts +11 -11
  8. package/dist/main/src/client/ButtplugClientConnectorException.js +41 -41
  9. package/dist/main/src/client/ButtplugClientDevice.d.ts +67 -67
  10. package/dist/main/src/client/ButtplugClientDevice.js +325 -324
  11. package/dist/main/src/client/ButtplugClientDevice.js.map +1 -1
  12. package/dist/main/src/client/ButtplugNodeWebsocketClientConnector.d.ts +18 -18
  13. package/dist/main/src/client/ButtplugNodeWebsocketClientConnector.js +19 -19
  14. package/dist/main/src/client/Client.d.ts +41 -40
  15. package/dist/main/src/client/Client.js +241 -235
  16. package/dist/main/src/client/Client.js.map +1 -1
  17. package/dist/main/src/client/IButtplugClientConnector.d.ts +16 -16
  18. package/dist/main/src/client/IButtplugClientConnector.js +9 -9
  19. package/dist/main/src/core/Exceptions.d.ts +36 -36
  20. package/dist/main/src/core/Exceptions.js +106 -106
  21. package/dist/main/src/core/Logging.d.ts +112 -112
  22. package/dist/main/src/core/Logging.js +170 -170
  23. package/dist/main/src/core/Logging.js.map +1 -1
  24. package/dist/main/src/core/MessageUtils.d.ts +10 -9
  25. package/dist/main/src/core/MessageUtils.js +64 -58
  26. package/dist/main/src/core/MessageUtils.js.map +1 -1
  27. package/dist/main/src/core/Messages.d.ts +275 -275
  28. package/dist/main/src/core/Messages.js +429 -429
  29. package/dist/main/src/core/Messages.js.map +1 -1
  30. package/dist/main/src/index.d.ts +18 -18
  31. package/dist/main/src/index.js +34 -34
  32. package/dist/main/src/utils/ButtplugBrowserWebsocketConnector.d.ts +22 -22
  33. package/dist/main/src/utils/ButtplugBrowserWebsocketConnector.js +95 -95
  34. package/dist/main/src/utils/ButtplugMessageSorter.d.ts +19 -19
  35. package/dist/main/src/utils/ButtplugMessageSorter.js +81 -81
  36. package/dist/main/src/utils/Utils.d.ts +1 -1
  37. package/dist/main/src/utils/Utils.js +7 -7
  38. package/dist/web/buttplug.js +38 -7126
  39. package/dist/web/buttplug.mjs +2258 -0
  40. package/dist/web/client/ButtplugBrowserWebsocketClientConnector.d.ts +13 -0
  41. package/dist/web/client/ButtplugClientConnectorException.d.ts +11 -0
  42. package/dist/web/client/ButtplugClientDevice.d.ts +67 -0
  43. package/dist/web/client/ButtplugNodeWebsocketClientConnector.d.ts +18 -0
  44. package/dist/web/client/Client.d.ts +41 -0
  45. package/dist/web/client/IButtplugClientConnector.d.ts +16 -0
  46. package/dist/web/core/Exceptions.d.ts +36 -0
  47. package/dist/web/core/Logging.d.ts +112 -0
  48. package/dist/web/core/MessageUtils.d.ts +10 -0
  49. package/dist/web/core/Messages.d.ts +274 -0
  50. package/dist/web/index.d.ts +18 -0
  51. package/dist/web/utils/ButtplugBrowserWebsocketConnector.d.ts +22 -0
  52. package/dist/web/utils/ButtplugMessageSorter.d.ts +19 -0
  53. package/dist/web/utils/Utils.d.ts +1 -0
  54. package/package.json +23 -53
  55. package/src/client/ButtplugBrowserWebsocketClientConnector.ts +2 -24
  56. package/src/client/ButtplugClientDevice.ts +5 -4
  57. package/src/client/Client.ts +17 -10
  58. package/src/client/IButtplugClientConnector.ts +4 -4
  59. package/src/core/MessageUtils.ts +9 -1
  60. package/src/utils/ButtplugBrowserWebsocketConnector.ts +12 -12
  61. package/vite.config.ts +26 -0
  62. package/.github/FUNDING.yml +0 -5
  63. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -17
  64. package/.github/workflows/docs.yaml +0 -29
  65. package/azure-pipelines.yml +0 -19
  66. package/dist/web/buttplug.min.js +0 -3
  67. package/dist/web/buttplug.min.js.LICENSE.txt +0 -31
  68. package/dist/web/buttplug.min.js.map +0 -1
  69. package/jest-puppeteer.config.js +0 -5
  70. package/rollup.config.js +0 -55
  71. package/util/convert_device_config.js +0 -6
@@ -1,325 +1,326 @@
1
- /*!
2
- * Buttplug JS Source Code File - Visit https://buttplug.io for more info about
3
- * the project. Licensed under the BSD 3-Clause license. See LICENSE file in the
4
- * project root for full license information.
5
- *
6
- * @copyright Copyright (c) Nonpolynomial Labs LLC. All rights reserved.
7
- */
8
- 'use strict';
9
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- var desc = Object.getOwnPropertyDescriptor(m, k);
12
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
- desc = { enumerable: true, get: function() { return m[k]; } };
14
- }
15
- Object.defineProperty(o, k2, desc);
16
- }) : (function(o, m, k, k2) {
17
- if (k2 === undefined) k2 = k;
18
- o[k2] = m[k];
19
- }));
20
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
- Object.defineProperty(o, "default", { enumerable: true, value: v });
22
- }) : function(o, v) {
23
- o["default"] = v;
24
- });
25
- var __importStar = (this && this.__importStar) || function (mod) {
26
- if (mod && mod.__esModule) return mod;
27
- var result = {};
28
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
29
- __setModuleDefault(result, mod);
30
- return result;
31
- };
32
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
33
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
34
- return new (P || (P = Promise))(function (resolve, reject) {
35
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
36
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
37
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
38
- step((generator = generator.apply(thisArg, _arguments || [])).next());
39
- });
40
- };
41
- Object.defineProperty(exports, "__esModule", { value: true });
42
- exports.ButtplugClientDevice = void 0;
43
- const Messages = __importStar(require("../core/Messages"));
44
- const Exceptions_1 = require("../core/Exceptions");
45
- const eventemitter3_1 = require("eventemitter3");
46
- /**
47
- * Represents an abstract device, capable of taking certain kinds of messages.
48
- */
49
- class ButtplugClientDevice extends eventemitter3_1.EventEmitter {
50
- /**
51
- * Return the name of the device.
52
- */
53
- get name() {
54
- return this._deviceInfo.DeviceName;
55
- }
56
- /**
57
- * Return the user set name of the device.
58
- */
59
- get displayName() {
60
- return this._deviceInfo.DeviceDisplayName;
61
- }
62
- /**
63
- * Return the index of the device.
64
- */
65
- get index() {
66
- return this._deviceInfo.DeviceIndex;
67
- }
68
- /**
69
- * Return the index of the device.
70
- */
71
- get messageTimingGap() {
72
- return this._deviceInfo.DeviceMessageTimingGap;
73
- }
74
- /**
75
- * Return a list of message types the device accepts.
76
- */
77
- get messageAttributes() {
78
- return this._deviceInfo.DeviceMessages;
79
- }
80
- static fromMsg(msg, sendClosure) {
81
- return new ButtplugClientDevice(msg, sendClosure);
82
- }
83
- /**
84
- * @param _index Index of the device, as created by the device manager.
85
- * @param _name Name of the device.
86
- * @param allowedMsgs Buttplug messages the device can receive.
87
- */
88
- constructor(_deviceInfo, _sendClosure) {
89
- super();
90
- this._deviceInfo = _deviceInfo;
91
- this._sendClosure = _sendClosure;
92
- // Map of messages and their attributes (feature count, etc...)
93
- this.allowedMsgs = new Map();
94
- _deviceInfo.DeviceMessages.update();
95
- }
96
- send(msg) {
97
- return __awaiter(this, void 0, void 0, function* () {
98
- // Assume we're getting the closure from ButtplugClient, which does all of
99
- // the index/existence/connection/message checks for us.
100
- return yield this._sendClosure(this, msg);
101
- });
102
- }
103
- sendExpectOk(msg) {
104
- return __awaiter(this, void 0, void 0, function* () {
105
- const response = yield this.send(msg);
106
- switch (response.constructor) {
107
- case Messages.Ok:
108
- return;
109
- case Messages.Error:
110
- throw Exceptions_1.ButtplugError.FromError(response);
111
- default:
112
- throw new Exceptions_1.ButtplugMessageError(`Message type ${response.constructor} not handled by SendMsgExpectOk`);
113
- }
114
- });
115
- }
116
- scalar(scalar) {
117
- return __awaiter(this, void 0, void 0, function* () {
118
- if (Array.isArray(scalar)) {
119
- yield this.sendExpectOk(new Messages.ScalarCmd(scalar, this.index));
120
- }
121
- else {
122
- yield this.sendExpectOk(new Messages.ScalarCmd([scalar], this.index));
123
- }
124
- });
125
- }
126
- scalarCommandBuilder(speed, actuator) {
127
- var _a;
128
- return __awaiter(this, void 0, void 0, function* () {
129
- const scalarAttrs = (_a = this.messageAttributes.ScalarCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.ActuatorType === actuator);
130
- if (!scalarAttrs || scalarAttrs.length === 0) {
131
- throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no ${actuator} capabilities`);
132
- }
133
- const cmds = [];
134
- if (typeof speed === 'number') {
135
- scalarAttrs.forEach((x) => cmds.push(new Messages.ScalarSubcommand(x.Index, speed, actuator)));
136
- }
137
- else if (Array.isArray(speed)) {
138
- if (speed.length > scalarAttrs.length) {
139
- throw new Exceptions_1.ButtplugDeviceError(`${speed.length} commands send to a device with ${scalarAttrs.length} vibrators`);
140
- }
141
- scalarAttrs.forEach((x, i) => {
142
- cmds.push(new Messages.ScalarSubcommand(x.Index, speed[i], actuator));
143
- });
144
- }
145
- else {
146
- throw new Exceptions_1.ButtplugDeviceError(`${actuator} can only take numbers or arrays of numbers.`);
147
- }
148
- yield this.scalar(cmds);
149
- });
150
- }
151
- get vibrateAttributes() {
152
- var _a, _b;
153
- return ((_b = (_a = this.messageAttributes.ScalarCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.ActuatorType === Messages.ActuatorType.Vibrate)) !== null && _b !== void 0 ? _b : []);
154
- }
155
- vibrate(speed) {
156
- return __awaiter(this, void 0, void 0, function* () {
157
- yield this.scalarCommandBuilder(speed, Messages.ActuatorType.Vibrate);
158
- });
159
- }
160
- get oscillateAttributes() {
161
- var _a, _b;
162
- return ((_b = (_a = this.messageAttributes.ScalarCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.ActuatorType === Messages.ActuatorType.Oscillate)) !== null && _b !== void 0 ? _b : []);
163
- }
164
- oscillate(speed) {
165
- return __awaiter(this, void 0, void 0, function* () {
166
- yield this.scalarCommandBuilder(speed, Messages.ActuatorType.Oscillate);
167
- });
168
- }
169
- get rotateAttributes() {
170
- var _a;
171
- return (_a = this.messageAttributes.RotateCmd) !== null && _a !== void 0 ? _a : [];
172
- }
173
- rotate(values, clockwise) {
174
- return __awaiter(this, void 0, void 0, function* () {
175
- const rotateAttrs = this.messageAttributes.RotateCmd;
176
- if (!rotateAttrs || rotateAttrs.length === 0) {
177
- throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no Rotate capabilities`);
178
- }
179
- let msg;
180
- if (typeof values === 'number') {
181
- msg = Messages.RotateCmd.Create(this.index, new Array(rotateAttrs.length).fill([values, clockwise]));
182
- }
183
- else if (Array.isArray(values)) {
184
- msg = Messages.RotateCmd.Create(this.index, values);
185
- }
186
- else {
187
- throw new Exceptions_1.ButtplugDeviceError('SendRotateCmd can only take a number and boolean, or an array of number/boolean tuples');
188
- }
189
- yield this.sendExpectOk(msg);
190
- });
191
- }
192
- get linearAttributes() {
193
- var _a;
194
- return (_a = this.messageAttributes.RotateCmd) !== null && _a !== void 0 ? _a : [];
195
- }
196
- linear(values, duration) {
197
- return __awaiter(this, void 0, void 0, function* () {
198
- const linearAttrs = this.messageAttributes.LinearCmd;
199
- if (!linearAttrs || linearAttrs.length === 0) {
200
- throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no Linear capabilities`);
201
- }
202
- let msg;
203
- if (typeof values === 'number') {
204
- msg = Messages.LinearCmd.Create(this.index, new Array(linearAttrs.length).fill([values, duration]));
205
- }
206
- else if (Array.isArray(values)) {
207
- msg = Messages.LinearCmd.Create(this.index, values);
208
- }
209
- else {
210
- throw new Exceptions_1.ButtplugDeviceError('SendLinearCmd can only take a number and number, or an array of number/number tuples');
211
- }
212
- yield this.sendExpectOk(msg);
213
- });
214
- }
215
- sensorRead(sensorIndex, sensorType) {
216
- return __awaiter(this, void 0, void 0, function* () {
217
- const response = yield this.send(new Messages.SensorReadCmd(this.index, sensorIndex, sensorType));
218
- switch (response.constructor) {
219
- case Messages.SensorReading:
220
- return response.Data;
221
- case Messages.Error:
222
- throw Exceptions_1.ButtplugError.FromError(response);
223
- default:
224
- throw new Exceptions_1.ButtplugMessageError(`Message type ${response.constructor} not handled by sensorRead`);
225
- }
226
- });
227
- }
228
- get hasBattery() {
229
- var _a;
230
- const batteryAttrs = (_a = this.messageAttributes.SensorReadCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.SensorType === Messages.SensorType.Battery);
231
- return batteryAttrs !== undefined && batteryAttrs.length > 0;
232
- }
233
- battery() {
234
- var _a;
235
- return __awaiter(this, void 0, void 0, function* () {
236
- if (!this.hasBattery) {
237
- throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no Battery capabilities`);
238
- }
239
- const batteryAttrs = (_a = this.messageAttributes.SensorReadCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.SensorType === Messages.SensorType.Battery);
240
- // Find the battery sensor, we'll need its index.
241
- const result = yield this.sensorRead(batteryAttrs[0].Index, Messages.SensorType.Battery);
242
- return result[0] / 100.0;
243
- });
244
- }
245
- get hasRssi() {
246
- var _a;
247
- const rssiAttrs = (_a = this.messageAttributes.SensorReadCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.SensorType === Messages.SensorType.RSSI);
248
- return rssiAttrs !== undefined && rssiAttrs.length === 0;
249
- }
250
- rssi() {
251
- var _a;
252
- return __awaiter(this, void 0, void 0, function* () {
253
- if (!this.hasRssi) {
254
- throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no RSSI capabilities`);
255
- }
256
- const rssiAttrs = (_a = this.messageAttributes.SensorReadCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.SensorType === Messages.SensorType.RSSI);
257
- // Find the battery sensor, we'll need its index.
258
- const result = yield this.sensorRead(rssiAttrs[0].Index, Messages.SensorType.RSSI);
259
- return result[0];
260
- });
261
- }
262
- rawRead(endpoint, expectedLength, timeout) {
263
- return __awaiter(this, void 0, void 0, function* () {
264
- if (!this.messageAttributes.RawReadCmd) {
265
- throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw read capabilities`);
266
- }
267
- if (this.messageAttributes.RawReadCmd.Endpoints.indexOf(endpoint) === -1) {
268
- throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw readable endpoint ${endpoint}`);
269
- }
270
- const response = yield this.send(new Messages.RawReadCmd(this.index, endpoint, expectedLength, timeout));
271
- switch (response.constructor) {
272
- case Messages.RawReading:
273
- return new Uint8Array(response.Data);
274
- case Messages.Error:
275
- throw Exceptions_1.ButtplugError.FromError(response);
276
- default:
277
- throw new Exceptions_1.ButtplugMessageError(`Message type ${response.constructor} not handled by rawRead`);
278
- }
279
- });
280
- }
281
- rawWrite(endpoint, data, writeWithResponse) {
282
- return __awaiter(this, void 0, void 0, function* () {
283
- if (!this.messageAttributes.RawWriteCmd) {
284
- throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw write capabilities`);
285
- }
286
- if (this.messageAttributes.RawWriteCmd.Endpoints.indexOf(endpoint) === -1) {
287
- throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw writable endpoint ${endpoint}`);
288
- }
289
- yield this.sendExpectOk(new Messages.RawWriteCmd(this.index, endpoint, data, writeWithResponse));
290
- });
291
- }
292
- rawSubscribe(endpoint) {
293
- return __awaiter(this, void 0, void 0, function* () {
294
- if (!this.messageAttributes.RawSubscribeCmd) {
295
- throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw subscribe capabilities`);
296
- }
297
- if (this.messageAttributes.RawSubscribeCmd.Endpoints.indexOf(endpoint) === -1) {
298
- throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw subscribable endpoint ${endpoint}`);
299
- }
300
- yield this.sendExpectOk(new Messages.RawSubscribeCmd(this.index, endpoint));
301
- });
302
- }
303
- rawUnsubscribe(endpoint) {
304
- return __awaiter(this, void 0, void 0, function* () {
305
- // This reuses raw subscribe's info.
306
- if (!this.messageAttributes.RawSubscribeCmd) {
307
- throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw unsubscribe capabilities`);
308
- }
309
- if (this.messageAttributes.RawSubscribeCmd.Endpoints.indexOf(endpoint) === -1) {
310
- throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw unsubscribable endpoint ${endpoint}`);
311
- }
312
- yield this.sendExpectOk(new Messages.RawUnsubscribeCmd(this.index, endpoint));
313
- });
314
- }
315
- stop() {
316
- return __awaiter(this, void 0, void 0, function* () {
317
- yield this.sendExpectOk(new Messages.StopDeviceCmd(this.index));
318
- });
319
- }
320
- emitDisconnected() {
321
- this.emit('deviceremoved');
322
- }
323
- }
324
- exports.ButtplugClientDevice = ButtplugClientDevice;
1
+ /*!
2
+ * Buttplug JS Source Code File - Visit https://buttplug.io for more info about
3
+ * the project. Licensed under the BSD 3-Clause license. See LICENSE file in the
4
+ * project root for full license information.
5
+ *
6
+ * @copyright Copyright (c) Nonpolynomial Labs LLC. All rights reserved.
7
+ */
8
+ 'use strict';
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || function (mod) {
26
+ if (mod && mod.__esModule) return mod;
27
+ var result = {};
28
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
29
+ __setModuleDefault(result, mod);
30
+ return result;
31
+ };
32
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
33
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
34
+ return new (P || (P = Promise))(function (resolve, reject) {
35
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
36
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
37
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
38
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
39
+ });
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.ButtplugClientDevice = void 0;
43
+ const Messages = __importStar(require("../core/Messages"));
44
+ const Exceptions_1 = require("../core/Exceptions");
45
+ const eventemitter3_1 = require("eventemitter3");
46
+ const MessageUtils_1 = require("../core/MessageUtils");
47
+ /**
48
+ * Represents an abstract device, capable of taking certain kinds of messages.
49
+ */
50
+ class ButtplugClientDevice extends eventemitter3_1.EventEmitter {
51
+ /**
52
+ * Return the name of the device.
53
+ */
54
+ get name() {
55
+ return this._deviceInfo.DeviceName;
56
+ }
57
+ /**
58
+ * Return the user set name of the device.
59
+ */
60
+ get displayName() {
61
+ return this._deviceInfo.DeviceDisplayName;
62
+ }
63
+ /**
64
+ * Return the index of the device.
65
+ */
66
+ get index() {
67
+ return this._deviceInfo.DeviceIndex;
68
+ }
69
+ /**
70
+ * Return the index of the device.
71
+ */
72
+ get messageTimingGap() {
73
+ return this._deviceInfo.DeviceMessageTimingGap;
74
+ }
75
+ /**
76
+ * Return a list of message types the device accepts.
77
+ */
78
+ get messageAttributes() {
79
+ return this._deviceInfo.DeviceMessages;
80
+ }
81
+ static fromMsg(msg, sendClosure) {
82
+ return new ButtplugClientDevice(msg, sendClosure);
83
+ }
84
+ /**
85
+ * @param _index Index of the device, as created by the device manager.
86
+ * @param _name Name of the device.
87
+ * @param allowedMsgs Buttplug messages the device can receive.
88
+ */
89
+ constructor(_deviceInfo, _sendClosure) {
90
+ super();
91
+ this._deviceInfo = _deviceInfo;
92
+ this._sendClosure = _sendClosure;
93
+ // Map of messages and their attributes (feature count, etc...)
94
+ this.allowedMsgs = new Map();
95
+ _deviceInfo.DeviceMessages.update();
96
+ }
97
+ send(msg) {
98
+ return __awaiter(this, void 0, void 0, function* () {
99
+ // Assume we're getting the closure from ButtplugClient, which does all of
100
+ // the index/existence/connection/message checks for us.
101
+ return yield this._sendClosure(this, msg);
102
+ });
103
+ }
104
+ sendExpectOk(msg) {
105
+ return __awaiter(this, void 0, void 0, function* () {
106
+ const response = yield this.send(msg);
107
+ switch ((0, MessageUtils_1.getMessageClassFromMessage)(response)) {
108
+ case Messages.Ok:
109
+ return;
110
+ case Messages.Error:
111
+ throw Exceptions_1.ButtplugError.FromError(response);
112
+ default:
113
+ throw new Exceptions_1.ButtplugMessageError(`Message type ${response.constructor} not handled by SendMsgExpectOk`);
114
+ }
115
+ });
116
+ }
117
+ scalar(scalar) {
118
+ return __awaiter(this, void 0, void 0, function* () {
119
+ if (Array.isArray(scalar)) {
120
+ yield this.sendExpectOk(new Messages.ScalarCmd(scalar, this.index));
121
+ }
122
+ else {
123
+ yield this.sendExpectOk(new Messages.ScalarCmd([scalar], this.index));
124
+ }
125
+ });
126
+ }
127
+ scalarCommandBuilder(speed, actuator) {
128
+ var _a;
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ const scalarAttrs = (_a = this.messageAttributes.ScalarCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.ActuatorType === actuator);
131
+ if (!scalarAttrs || scalarAttrs.length === 0) {
132
+ throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no ${actuator} capabilities`);
133
+ }
134
+ const cmds = [];
135
+ if (typeof speed === 'number') {
136
+ scalarAttrs.forEach((x) => cmds.push(new Messages.ScalarSubcommand(x.Index, speed, actuator)));
137
+ }
138
+ else if (Array.isArray(speed)) {
139
+ if (speed.length > scalarAttrs.length) {
140
+ throw new Exceptions_1.ButtplugDeviceError(`${speed.length} commands send to a device with ${scalarAttrs.length} vibrators`);
141
+ }
142
+ scalarAttrs.forEach((x, i) => {
143
+ cmds.push(new Messages.ScalarSubcommand(x.Index, speed[i], actuator));
144
+ });
145
+ }
146
+ else {
147
+ throw new Exceptions_1.ButtplugDeviceError(`${actuator} can only take numbers or arrays of numbers.`);
148
+ }
149
+ yield this.scalar(cmds);
150
+ });
151
+ }
152
+ get vibrateAttributes() {
153
+ var _a, _b;
154
+ return ((_b = (_a = this.messageAttributes.ScalarCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.ActuatorType === Messages.ActuatorType.Vibrate)) !== null && _b !== void 0 ? _b : []);
155
+ }
156
+ vibrate(speed) {
157
+ return __awaiter(this, void 0, void 0, function* () {
158
+ yield this.scalarCommandBuilder(speed, Messages.ActuatorType.Vibrate);
159
+ });
160
+ }
161
+ get oscillateAttributes() {
162
+ var _a, _b;
163
+ return ((_b = (_a = this.messageAttributes.ScalarCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.ActuatorType === Messages.ActuatorType.Oscillate)) !== null && _b !== void 0 ? _b : []);
164
+ }
165
+ oscillate(speed) {
166
+ return __awaiter(this, void 0, void 0, function* () {
167
+ yield this.scalarCommandBuilder(speed, Messages.ActuatorType.Oscillate);
168
+ });
169
+ }
170
+ get rotateAttributes() {
171
+ var _a;
172
+ return (_a = this.messageAttributes.RotateCmd) !== null && _a !== void 0 ? _a : [];
173
+ }
174
+ rotate(values, clockwise) {
175
+ return __awaiter(this, void 0, void 0, function* () {
176
+ const rotateAttrs = this.messageAttributes.RotateCmd;
177
+ if (!rotateAttrs || rotateAttrs.length === 0) {
178
+ throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no Rotate capabilities`);
179
+ }
180
+ let msg;
181
+ if (typeof values === 'number') {
182
+ msg = Messages.RotateCmd.Create(this.index, new Array(rotateAttrs.length).fill([values, clockwise]));
183
+ }
184
+ else if (Array.isArray(values)) {
185
+ msg = Messages.RotateCmd.Create(this.index, values);
186
+ }
187
+ else {
188
+ throw new Exceptions_1.ButtplugDeviceError('SendRotateCmd can only take a number and boolean, or an array of number/boolean tuples');
189
+ }
190
+ yield this.sendExpectOk(msg);
191
+ });
192
+ }
193
+ get linearAttributes() {
194
+ var _a;
195
+ return (_a = this.messageAttributes.LinearCmd) !== null && _a !== void 0 ? _a : [];
196
+ }
197
+ linear(values, duration) {
198
+ return __awaiter(this, void 0, void 0, function* () {
199
+ const linearAttrs = this.messageAttributes.LinearCmd;
200
+ if (!linearAttrs || linearAttrs.length === 0) {
201
+ throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no Linear capabilities`);
202
+ }
203
+ let msg;
204
+ if (typeof values === 'number') {
205
+ msg = Messages.LinearCmd.Create(this.index, new Array(linearAttrs.length).fill([values, duration]));
206
+ }
207
+ else if (Array.isArray(values)) {
208
+ msg = Messages.LinearCmd.Create(this.index, values);
209
+ }
210
+ else {
211
+ throw new Exceptions_1.ButtplugDeviceError('SendLinearCmd can only take a number and number, or an array of number/number tuples');
212
+ }
213
+ yield this.sendExpectOk(msg);
214
+ });
215
+ }
216
+ sensorRead(sensorIndex, sensorType) {
217
+ return __awaiter(this, void 0, void 0, function* () {
218
+ const response = yield this.send(new Messages.SensorReadCmd(this.index, sensorIndex, sensorType));
219
+ switch ((0, MessageUtils_1.getMessageClassFromMessage)(response)) {
220
+ case Messages.SensorReading:
221
+ return response.Data;
222
+ case Messages.Error:
223
+ throw Exceptions_1.ButtplugError.FromError(response);
224
+ default:
225
+ throw new Exceptions_1.ButtplugMessageError(`Message type ${response.constructor} not handled by sensorRead`);
226
+ }
227
+ });
228
+ }
229
+ get hasBattery() {
230
+ var _a;
231
+ const batteryAttrs = (_a = this.messageAttributes.SensorReadCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.SensorType === Messages.SensorType.Battery);
232
+ return batteryAttrs !== undefined && batteryAttrs.length > 0;
233
+ }
234
+ battery() {
235
+ var _a;
236
+ return __awaiter(this, void 0, void 0, function* () {
237
+ if (!this.hasBattery) {
238
+ throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no Battery capabilities`);
239
+ }
240
+ const batteryAttrs = (_a = this.messageAttributes.SensorReadCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.SensorType === Messages.SensorType.Battery);
241
+ // Find the battery sensor, we'll need its index.
242
+ const result = yield this.sensorRead(batteryAttrs[0].Index, Messages.SensorType.Battery);
243
+ return result[0] / 100.0;
244
+ });
245
+ }
246
+ get hasRssi() {
247
+ var _a;
248
+ const rssiAttrs = (_a = this.messageAttributes.SensorReadCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.SensorType === Messages.SensorType.RSSI);
249
+ return rssiAttrs !== undefined && rssiAttrs.length === 0;
250
+ }
251
+ rssi() {
252
+ var _a;
253
+ return __awaiter(this, void 0, void 0, function* () {
254
+ if (!this.hasRssi) {
255
+ throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no RSSI capabilities`);
256
+ }
257
+ const rssiAttrs = (_a = this.messageAttributes.SensorReadCmd) === null || _a === void 0 ? void 0 : _a.filter((x) => x.SensorType === Messages.SensorType.RSSI);
258
+ // Find the battery sensor, we'll need its index.
259
+ const result = yield this.sensorRead(rssiAttrs[0].Index, Messages.SensorType.RSSI);
260
+ return result[0];
261
+ });
262
+ }
263
+ rawRead(endpoint, expectedLength, timeout) {
264
+ return __awaiter(this, void 0, void 0, function* () {
265
+ if (!this.messageAttributes.RawReadCmd) {
266
+ throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw read capabilities`);
267
+ }
268
+ if (this.messageAttributes.RawReadCmd.Endpoints.indexOf(endpoint) === -1) {
269
+ throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw readable endpoint ${endpoint}`);
270
+ }
271
+ const response = yield this.send(new Messages.RawReadCmd(this.index, endpoint, expectedLength, timeout));
272
+ switch ((0, MessageUtils_1.getMessageClassFromMessage)(response)) {
273
+ case Messages.RawReading:
274
+ return new Uint8Array(response.Data);
275
+ case Messages.Error:
276
+ throw Exceptions_1.ButtplugError.FromError(response);
277
+ default:
278
+ throw new Exceptions_1.ButtplugMessageError(`Message type ${response.constructor} not handled by rawRead`);
279
+ }
280
+ });
281
+ }
282
+ rawWrite(endpoint, data, writeWithResponse) {
283
+ return __awaiter(this, void 0, void 0, function* () {
284
+ if (!this.messageAttributes.RawWriteCmd) {
285
+ throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw write capabilities`);
286
+ }
287
+ if (this.messageAttributes.RawWriteCmd.Endpoints.indexOf(endpoint) === -1) {
288
+ throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw writable endpoint ${endpoint}`);
289
+ }
290
+ yield this.sendExpectOk(new Messages.RawWriteCmd(this.index, endpoint, data, writeWithResponse));
291
+ });
292
+ }
293
+ rawSubscribe(endpoint) {
294
+ return __awaiter(this, void 0, void 0, function* () {
295
+ if (!this.messageAttributes.RawSubscribeCmd) {
296
+ throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw subscribe capabilities`);
297
+ }
298
+ if (this.messageAttributes.RawSubscribeCmd.Endpoints.indexOf(endpoint) === -1) {
299
+ throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw subscribable endpoint ${endpoint}`);
300
+ }
301
+ yield this.sendExpectOk(new Messages.RawSubscribeCmd(this.index, endpoint));
302
+ });
303
+ }
304
+ rawUnsubscribe(endpoint) {
305
+ return __awaiter(this, void 0, void 0, function* () {
306
+ // This reuses raw subscribe's info.
307
+ if (!this.messageAttributes.RawSubscribeCmd) {
308
+ throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw unsubscribe capabilities`);
309
+ }
310
+ if (this.messageAttributes.RawSubscribeCmd.Endpoints.indexOf(endpoint) === -1) {
311
+ throw new Exceptions_1.ButtplugDeviceError(`Device ${this.name} has no raw unsubscribable endpoint ${endpoint}`);
312
+ }
313
+ yield this.sendExpectOk(new Messages.RawUnsubscribeCmd(this.index, endpoint));
314
+ });
315
+ }
316
+ stop() {
317
+ return __awaiter(this, void 0, void 0, function* () {
318
+ yield this.sendExpectOk(new Messages.StopDeviceCmd(this.index));
319
+ });
320
+ }
321
+ emitDisconnected() {
322
+ this.emit('deviceremoved');
323
+ }
324
+ }
325
+ exports.ButtplugClientDevice = ButtplugClientDevice;
325
326
  //# sourceMappingURL=ButtplugClientDevice.js.map