@voltras/node-sdk 0.1.0

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 (203) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +272 -0
  3. package/dist/cjs/bluetooth/adapters/base.js +116 -0
  4. package/dist/cjs/bluetooth/adapters/base.js.map +1 -0
  5. package/dist/cjs/bluetooth/adapters/index.js +58 -0
  6. package/dist/cjs/bluetooth/adapters/index.js.map +1 -0
  7. package/dist/cjs/bluetooth/adapters/native.js +473 -0
  8. package/dist/cjs/bluetooth/adapters/native.js.map +1 -0
  9. package/dist/cjs/bluetooth/adapters/node.js +228 -0
  10. package/dist/cjs/bluetooth/adapters/node.js.map +1 -0
  11. package/dist/cjs/bluetooth/adapters/types.js +11 -0
  12. package/dist/cjs/bluetooth/adapters/types.js.map +1 -0
  13. package/dist/cjs/bluetooth/adapters/web-bluetooth-base.js +187 -0
  14. package/dist/cjs/bluetooth/adapters/web-bluetooth-base.js.map +1 -0
  15. package/dist/cjs/bluetooth/adapters/web.js +112 -0
  16. package/dist/cjs/bluetooth/adapters/web.js.map +1 -0
  17. package/dist/cjs/bluetooth/controllers/scanner-controller.js +145 -0
  18. package/dist/cjs/bluetooth/controllers/scanner-controller.js.map +1 -0
  19. package/dist/cjs/bluetooth/index.js +27 -0
  20. package/dist/cjs/bluetooth/index.js.map +1 -0
  21. package/dist/cjs/bluetooth/models/connection.js +68 -0
  22. package/dist/cjs/bluetooth/models/connection.js.map +1 -0
  23. package/dist/cjs/bluetooth/models/device.js +26 -0
  24. package/dist/cjs/bluetooth/models/device.js.map +1 -0
  25. package/dist/cjs/bluetooth/models/environment.js +106 -0
  26. package/dist/cjs/bluetooth/models/environment.js.map +1 -0
  27. package/dist/cjs/errors.js +167 -0
  28. package/dist/cjs/errors.js.map +1 -0
  29. package/dist/cjs/index.js +116 -0
  30. package/dist/cjs/index.js.map +1 -0
  31. package/dist/cjs/react/hooks.js +262 -0
  32. package/dist/cjs/react/hooks.js.map +1 -0
  33. package/dist/cjs/react/index.js +18 -0
  34. package/dist/cjs/react/index.js.map +1 -0
  35. package/dist/cjs/sdk/index.js +14 -0
  36. package/dist/cjs/sdk/index.js.map +1 -0
  37. package/dist/cjs/sdk/types.js +8 -0
  38. package/dist/cjs/sdk/types.js.map +1 -0
  39. package/dist/cjs/sdk/voltra-client.js +632 -0
  40. package/dist/cjs/sdk/voltra-client.js.map +1 -0
  41. package/dist/cjs/sdk/voltra-manager.js +419 -0
  42. package/dist/cjs/sdk/voltra-manager.js.map +1 -0
  43. package/dist/cjs/shared/index.js +12 -0
  44. package/dist/cjs/shared/index.js.map +1 -0
  45. package/dist/cjs/shared/utils.js +51 -0
  46. package/dist/cjs/shared/utils.js.map +1 -0
  47. package/dist/cjs/voltra/index.js +56 -0
  48. package/dist/cjs/voltra/index.js.map +1 -0
  49. package/dist/cjs/voltra/models/connection.js +68 -0
  50. package/dist/cjs/voltra/models/connection.js.map +1 -0
  51. package/dist/cjs/voltra/models/device-filter.js +28 -0
  52. package/dist/cjs/voltra/models/device-filter.js.map +1 -0
  53. package/dist/cjs/voltra/models/device.js +152 -0
  54. package/dist/cjs/voltra/models/device.js.map +1 -0
  55. package/dist/cjs/voltra/models/telemetry/frame.js +46 -0
  56. package/dist/cjs/voltra/models/telemetry/frame.js.map +1 -0
  57. package/dist/cjs/voltra/models/telemetry/index.js +14 -0
  58. package/dist/cjs/voltra/models/telemetry/index.js.map +1 -0
  59. package/dist/cjs/voltra/protocol/commands.js +230 -0
  60. package/dist/cjs/voltra/protocol/commands.js.map +1 -0
  61. package/dist/cjs/voltra/protocol/constants.js +136 -0
  62. package/dist/cjs/voltra/protocol/constants.js.map +1 -0
  63. package/dist/cjs/voltra/protocol/data/chains.json +830 -0
  64. package/dist/cjs/voltra/protocol/data/eccentric.json +1598 -0
  65. package/dist/cjs/voltra/protocol/data/protocol.json +54 -0
  66. package/dist/cjs/voltra/protocol/data/weights.json +62 -0
  67. package/dist/cjs/voltra/protocol/index.js +25 -0
  68. package/dist/cjs/voltra/protocol/index.js.map +1 -0
  69. package/dist/cjs/voltra/protocol/telemetry-decoder.js +146 -0
  70. package/dist/cjs/voltra/protocol/telemetry-decoder.js.map +1 -0
  71. package/dist/esm/bluetooth/adapters/base.js +112 -0
  72. package/dist/esm/bluetooth/adapters/base.js.map +1 -0
  73. package/dist/esm/bluetooth/adapters/index.js +51 -0
  74. package/dist/esm/bluetooth/adapters/index.js.map +1 -0
  75. package/dist/esm/bluetooth/adapters/native.js +469 -0
  76. package/dist/esm/bluetooth/adapters/native.js.map +1 -0
  77. package/dist/esm/bluetooth/adapters/node.js +191 -0
  78. package/dist/esm/bluetooth/adapters/node.js.map +1 -0
  79. package/dist/esm/bluetooth/adapters/types.js +10 -0
  80. package/dist/esm/bluetooth/adapters/types.js.map +1 -0
  81. package/dist/esm/bluetooth/adapters/web-bluetooth-base.js +183 -0
  82. package/dist/esm/bluetooth/adapters/web-bluetooth-base.js.map +1 -0
  83. package/dist/esm/bluetooth/adapters/web.js +108 -0
  84. package/dist/esm/bluetooth/adapters/web.js.map +1 -0
  85. package/dist/esm/bluetooth/controllers/scanner-controller.js +141 -0
  86. package/dist/esm/bluetooth/controllers/scanner-controller.js.map +1 -0
  87. package/dist/esm/bluetooth/index.js +17 -0
  88. package/dist/esm/bluetooth/index.js.map +1 -0
  89. package/dist/esm/bluetooth/models/connection.js +63 -0
  90. package/dist/esm/bluetooth/models/connection.js.map +1 -0
  91. package/dist/esm/bluetooth/models/device.js +22 -0
  92. package/dist/esm/bluetooth/models/device.js.map +1 -0
  93. package/dist/esm/bluetooth/models/environment.js +101 -0
  94. package/dist/esm/bluetooth/models/environment.js.map +1 -0
  95. package/dist/esm/errors.js +155 -0
  96. package/dist/esm/errors.js.map +1 -0
  97. package/dist/esm/index.js +72 -0
  98. package/dist/esm/index.js.map +1 -0
  99. package/dist/esm/react/hooks.js +257 -0
  100. package/dist/esm/react/hooks.js.map +1 -0
  101. package/dist/esm/react/index.js +12 -0
  102. package/dist/esm/react/index.js.map +1 -0
  103. package/dist/esm/sdk/index.js +9 -0
  104. package/dist/esm/sdk/index.js.map +1 -0
  105. package/dist/esm/sdk/types.js +7 -0
  106. package/dist/esm/sdk/types.js.map +1 -0
  107. package/dist/esm/sdk/voltra-client.js +628 -0
  108. package/dist/esm/sdk/voltra-client.js.map +1 -0
  109. package/dist/esm/sdk/voltra-manager.js +415 -0
  110. package/dist/esm/sdk/voltra-manager.js.map +1 -0
  111. package/dist/esm/shared/index.js +5 -0
  112. package/dist/esm/shared/index.js.map +1 -0
  113. package/dist/esm/shared/utils.js +45 -0
  114. package/dist/esm/shared/utils.js.map +1 -0
  115. package/dist/esm/voltra/index.js +26 -0
  116. package/dist/esm/voltra/index.js.map +1 -0
  117. package/dist/esm/voltra/models/connection.js +63 -0
  118. package/dist/esm/voltra/models/connection.js.map +1 -0
  119. package/dist/esm/voltra/models/device-filter.js +23 -0
  120. package/dist/esm/voltra/models/device-filter.js.map +1 -0
  121. package/dist/esm/voltra/models/device.js +148 -0
  122. package/dist/esm/voltra/models/device.js.map +1 -0
  123. package/dist/esm/voltra/models/telemetry/frame.js +40 -0
  124. package/dist/esm/voltra/models/telemetry/frame.js.map +1 -0
  125. package/dist/esm/voltra/models/telemetry/index.js +7 -0
  126. package/dist/esm/voltra/models/telemetry/index.js.map +1 -0
  127. package/dist/esm/voltra/protocol/commands.js +224 -0
  128. package/dist/esm/voltra/protocol/commands.js.map +1 -0
  129. package/dist/esm/voltra/protocol/constants.js +130 -0
  130. package/dist/esm/voltra/protocol/constants.js.map +1 -0
  131. package/dist/esm/voltra/protocol/data/chains.json +830 -0
  132. package/dist/esm/voltra/protocol/data/eccentric.json +1598 -0
  133. package/dist/esm/voltra/protocol/data/protocol.json +54 -0
  134. package/dist/esm/voltra/protocol/data/weights.json +62 -0
  135. package/dist/esm/voltra/protocol/index.js +9 -0
  136. package/dist/esm/voltra/protocol/index.js.map +1 -0
  137. package/dist/esm/voltra/protocol/telemetry-decoder.js +140 -0
  138. package/dist/esm/voltra/protocol/telemetry-decoder.js.map +1 -0
  139. package/dist/types/bluetooth/adapters/base.d.ts +85 -0
  140. package/dist/types/bluetooth/adapters/base.d.ts.map +1 -0
  141. package/dist/types/bluetooth/adapters/index.d.ts +35 -0
  142. package/dist/types/bluetooth/adapters/index.d.ts.map +1 -0
  143. package/dist/types/bluetooth/adapters/native.d.ts +109 -0
  144. package/dist/types/bluetooth/adapters/native.d.ts.map +1 -0
  145. package/dist/types/bluetooth/adapters/node.d.ts +91 -0
  146. package/dist/types/bluetooth/adapters/node.d.ts.map +1 -0
  147. package/dist/types/bluetooth/adapters/types.d.ts +102 -0
  148. package/dist/types/bluetooth/adapters/types.d.ts.map +1 -0
  149. package/dist/types/bluetooth/adapters/web-bluetooth-base.d.ts +90 -0
  150. package/dist/types/bluetooth/adapters/web-bluetooth-base.d.ts.map +1 -0
  151. package/dist/types/bluetooth/adapters/web.d.ts +57 -0
  152. package/dist/types/bluetooth/adapters/web.d.ts.map +1 -0
  153. package/dist/types/bluetooth/controllers/scanner-controller.d.ts +93 -0
  154. package/dist/types/bluetooth/controllers/scanner-controller.d.ts.map +1 -0
  155. package/dist/types/bluetooth/index.d.ts +14 -0
  156. package/dist/types/bluetooth/index.d.ts.map +1 -0
  157. package/dist/types/bluetooth/models/connection.d.ts +37 -0
  158. package/dist/types/bluetooth/models/connection.d.ts.map +1 -0
  159. package/dist/types/bluetooth/models/device.d.ts +25 -0
  160. package/dist/types/bluetooth/models/device.d.ts.map +1 -0
  161. package/dist/types/bluetooth/models/environment.d.ts +45 -0
  162. package/dist/types/bluetooth/models/environment.d.ts.map +1 -0
  163. package/dist/types/errors.d.ts +113 -0
  164. package/dist/types/errors.d.ts.map +1 -0
  165. package/dist/types/index.d.ts +55 -0
  166. package/dist/types/index.d.ts.map +1 -0
  167. package/dist/types/react/hooks.d.ts +130 -0
  168. package/dist/types/react/hooks.d.ts.map +1 -0
  169. package/dist/types/react/index.d.ts +12 -0
  170. package/dist/types/react/index.d.ts.map +1 -0
  171. package/dist/types/sdk/index.d.ts +11 -0
  172. package/dist/types/sdk/index.d.ts.map +1 -0
  173. package/dist/types/sdk/types.d.ts +104 -0
  174. package/dist/types/sdk/types.d.ts.map +1 -0
  175. package/dist/types/sdk/voltra-client.d.ts +221 -0
  176. package/dist/types/sdk/voltra-client.d.ts.map +1 -0
  177. package/dist/types/sdk/voltra-manager.d.ts +226 -0
  178. package/dist/types/sdk/voltra-manager.d.ts.map +1 -0
  179. package/dist/types/shared/index.d.ts +5 -0
  180. package/dist/types/shared/index.d.ts.map +1 -0
  181. package/dist/types/shared/utils.d.ts +25 -0
  182. package/dist/types/shared/utils.d.ts.map +1 -0
  183. package/dist/types/voltra/index.d.ts +13 -0
  184. package/dist/types/voltra/index.d.ts.map +1 -0
  185. package/dist/types/voltra/models/connection.d.ts +37 -0
  186. package/dist/types/voltra/models/connection.d.ts.map +1 -0
  187. package/dist/types/voltra/models/device-filter.d.ts +19 -0
  188. package/dist/types/voltra/models/device-filter.d.ts.map +1 -0
  189. package/dist/types/voltra/models/device.d.ts +105 -0
  190. package/dist/types/voltra/models/device.d.ts.map +1 -0
  191. package/dist/types/voltra/models/telemetry/frame.d.ts +41 -0
  192. package/dist/types/voltra/models/telemetry/frame.d.ts.map +1 -0
  193. package/dist/types/voltra/models/telemetry/index.d.ts +8 -0
  194. package/dist/types/voltra/models/telemetry/index.d.ts.map +1 -0
  195. package/dist/types/voltra/protocol/commands.d.ts +99 -0
  196. package/dist/types/voltra/protocol/commands.d.ts.map +1 -0
  197. package/dist/types/voltra/protocol/constants.d.ts +103 -0
  198. package/dist/types/voltra/protocol/constants.d.ts.map +1 -0
  199. package/dist/types/voltra/protocol/index.d.ts +9 -0
  200. package/dist/types/voltra/protocol/index.d.ts.map +1 -0
  201. package/dist/types/voltra/protocol/telemetry-decoder.d.ts +45 -0
  202. package/dist/types/voltra/protocol/telemetry-decoder.d.ts.map +1 -0
  203. package/package.json +111 -0
@@ -0,0 +1,415 @@
1
+ /**
2
+ * VoltraManager
3
+ *
4
+ * Main entry point for the Voltra SDK. Handles device discovery and connection.
5
+ * Returns VoltraClient instances for controlling individual devices.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { VoltraManager } from '@voltras/node-sdk';
10
+ *
11
+ * const manager = new VoltraManager();
12
+ *
13
+ * // Scan for devices
14
+ * const devices = await manager.scan();
15
+ *
16
+ * // Connect to a device (returns a VoltraClient)
17
+ * const client = await manager.connect(devices[0]);
18
+ *
19
+ * // Or connect by name (scans + connects in one step)
20
+ * const client = await manager.connectByName('VTR-123456');
21
+ *
22
+ * // Use the client
23
+ * await client.setWeight(50);
24
+ * client.onFrame((frame) => console.log(frame.position));
25
+ *
26
+ * // Cleanup
27
+ * manager.dispose();
28
+ * ```
29
+ */
30
+ import { filterVoltraDevices } from '../voltra/models/device-filter';
31
+ import { BLE } from '../voltra/protocol/constants';
32
+ import { VoltraClient } from './voltra-client';
33
+ /**
34
+ * Main entry point for the Voltra SDK.
35
+ */
36
+ export class VoltraManager {
37
+ constructor(options = {}) {
38
+ // Connected devices
39
+ this.clients = new Map();
40
+ this.clientUnsubscribes = new Map();
41
+ // Discovered devices (from last scan)
42
+ this.discoveredDevices = [];
43
+ // Scanning state
44
+ this._isScanning = false;
45
+ this.scanAdapter = null;
46
+ // Event listeners
47
+ this.listeners = new Set();
48
+ // Disposed flag
49
+ this.disposed = false;
50
+ this.clientOptions = options.clientOptions ?? {};
51
+ if (options.adapterFactory) {
52
+ // Use provided factory
53
+ this.adapterFactory = options.adapterFactory;
54
+ this.platform = options.platform ?? 'web';
55
+ }
56
+ else if (options.platform) {
57
+ // Use specified platform
58
+ this.platform = options.platform;
59
+ this.adapterFactory = this.createAdapterFactory(options.platform);
60
+ }
61
+ else {
62
+ // Auto-detect platform
63
+ this.platform = this.detectPlatform();
64
+ this.adapterFactory = this.createAdapterFactory(this.platform);
65
+ }
66
+ }
67
+ // ===========================================================================
68
+ // Static Factory Methods
69
+ // ===========================================================================
70
+ /**
71
+ * Create a manager for web browsers.
72
+ */
73
+ static forWeb(options) {
74
+ return new VoltraManager({ ...options, platform: 'web' });
75
+ }
76
+ /**
77
+ * Create a manager for Node.js.
78
+ */
79
+ static forNode(options) {
80
+ return new VoltraManager({ ...options, platform: 'node' });
81
+ }
82
+ /**
83
+ * Create a manager for React Native.
84
+ * Note: Prefer importing from '@voltras/node-sdk/native' instead.
85
+ */
86
+ static forNative(options) {
87
+ return new VoltraManager({ ...options, platform: 'native' });
88
+ }
89
+ // ===========================================================================
90
+ // Public Getters
91
+ // ===========================================================================
92
+ /**
93
+ * Get all connected device IDs.
94
+ */
95
+ get connectedDeviceIds() {
96
+ return Array.from(this.clients.keys());
97
+ }
98
+ /**
99
+ * Get number of connected devices.
100
+ */
101
+ get connectedCount() {
102
+ return this.clients.size;
103
+ }
104
+ /**
105
+ * Check if scanning is in progress.
106
+ */
107
+ get isScanning() {
108
+ return this._isScanning;
109
+ }
110
+ /**
111
+ * Get devices discovered in last scan.
112
+ */
113
+ get devices() {
114
+ return [...this.discoveredDevices];
115
+ }
116
+ // ===========================================================================
117
+ // Device Access
118
+ // ===========================================================================
119
+ /**
120
+ * Get a connected device client by ID.
121
+ */
122
+ getClient(deviceId) {
123
+ return this.clients.get(deviceId);
124
+ }
125
+ /**
126
+ * Get all connected device clients.
127
+ */
128
+ getAllClients() {
129
+ return Array.from(this.clients.values());
130
+ }
131
+ /**
132
+ * Check if a device is connected.
133
+ */
134
+ isConnected(deviceId) {
135
+ return this.clients.has(deviceId);
136
+ }
137
+ // ===========================================================================
138
+ // Discovery
139
+ // ===========================================================================
140
+ /**
141
+ * Scan for Voltra devices.
142
+ *
143
+ * @param options Scan options
144
+ * @returns Array of discovered Voltra devices
145
+ */
146
+ async scan(options = {}) {
147
+ this.ensureNotDisposed();
148
+ const { timeout = 10000, filterVoltra = true } = options;
149
+ this._isScanning = true;
150
+ this.emit({ type: 'scanStarted' });
151
+ try {
152
+ // Create adapter for scanning if needed
153
+ if (!this.scanAdapter) {
154
+ this.scanAdapter = this.adapterFactory();
155
+ }
156
+ const devices = await this.scanAdapter.scan(timeout);
157
+ this.discoveredDevices = filterVoltra ? filterVoltraDevices(devices) : devices;
158
+ this.emit({ type: 'scanStopped', devices: this.discoveredDevices });
159
+ return this.discoveredDevices;
160
+ }
161
+ finally {
162
+ this._isScanning = false;
163
+ }
164
+ }
165
+ // ===========================================================================
166
+ // Connection
167
+ // ===========================================================================
168
+ /**
169
+ * Connect to a Voltra device.
170
+ *
171
+ * @param device Device to connect to
172
+ * @returns VoltraClient for the connected device
173
+ */
174
+ async connect(device) {
175
+ this.ensureNotDisposed();
176
+ // Check if already connected
177
+ if (this.clients.has(device.id)) {
178
+ return this.clients.get(device.id);
179
+ }
180
+ // Create new adapter and client
181
+ const adapter = this.adapterFactory();
182
+ const client = new VoltraClient({
183
+ ...this.clientOptions,
184
+ adapter,
185
+ });
186
+ try {
187
+ await client.connect(device);
188
+ // Store client
189
+ this.clients.set(device.id, client);
190
+ // Subscribe to client events
191
+ const unsubscribe = client.subscribe((event) => {
192
+ this.handleClientEvent(device.id, event);
193
+ });
194
+ this.clientUnsubscribes.set(device.id, unsubscribe);
195
+ // Emit connected event
196
+ this.emit({
197
+ type: 'deviceConnected',
198
+ deviceId: device.id,
199
+ deviceName: device.name ?? null,
200
+ client,
201
+ });
202
+ return client;
203
+ }
204
+ catch (error) {
205
+ client.dispose();
206
+ throw error;
207
+ }
208
+ }
209
+ /**
210
+ * Scan for a device by name and connect to it.
211
+ * This is a convenience method that combines scan() and connect().
212
+ *
213
+ * @param namePattern Name or partial name to search for
214
+ * @param options Connection options
215
+ * @returns VoltraClient for the connected device
216
+ * @throws Error if no matching device is found
217
+ *
218
+ * @example
219
+ * ```typescript
220
+ * // Connect to device containing "VTR-123" in its name
221
+ * const client = await manager.connectByName('VTR-123');
222
+ *
223
+ * // Connect to exact name match
224
+ * const client = await manager.connectByName('VTR-123456', { matchMode: 'exact' });
225
+ * ```
226
+ */
227
+ async connectByName(namePattern, options = {}) {
228
+ this.ensureNotDisposed();
229
+ const { matchMode = 'contains', timeout = 10000, filterVoltra = true } = options;
230
+ // Scan for devices
231
+ const devices = await this.scan({ timeout, filterVoltra });
232
+ // Find matching device
233
+ const device = devices.find((d) => {
234
+ if (!d.name)
235
+ return false;
236
+ switch (matchMode) {
237
+ case 'exact':
238
+ return d.name === namePattern;
239
+ case 'startsWith':
240
+ return d.name.startsWith(namePattern);
241
+ case 'contains':
242
+ default:
243
+ return d.name.includes(namePattern);
244
+ }
245
+ });
246
+ if (!device) {
247
+ throw new Error(`No Voltra device found matching "${namePattern}". ` +
248
+ `Found ${devices.length} device(s): ${devices.map((d) => d.name ?? d.id).join(', ') || 'none'}`);
249
+ }
250
+ return this.connect(device);
251
+ }
252
+ /**
253
+ * Connect to the first available Voltra device.
254
+ * Convenience method for single-device scenarios.
255
+ *
256
+ * @param options Scan options
257
+ * @returns VoltraClient for the connected device
258
+ * @throws Error if no devices are found
259
+ */
260
+ async connectFirst(options = {}) {
261
+ const devices = await this.scan(options);
262
+ if (devices.length === 0) {
263
+ throw new Error('No Voltra devices found. Make sure your device is powered on.');
264
+ }
265
+ return this.connect(devices[0]);
266
+ }
267
+ /**
268
+ * Disconnect a specific device.
269
+ */
270
+ async disconnect(deviceId) {
271
+ const client = this.clients.get(deviceId);
272
+ if (!client)
273
+ return;
274
+ const unsubscribe = this.clientUnsubscribes.get(deviceId);
275
+ unsubscribe?.();
276
+ this.clientUnsubscribes.delete(deviceId);
277
+ await client.disconnect();
278
+ client.dispose();
279
+ this.clients.delete(deviceId);
280
+ this.emit({ type: 'deviceDisconnected', deviceId });
281
+ }
282
+ /**
283
+ * Disconnect all devices.
284
+ */
285
+ async disconnectAll() {
286
+ const deviceIds = Array.from(this.clients.keys());
287
+ await Promise.all(deviceIds.map((id) => this.disconnect(id)));
288
+ }
289
+ // ===========================================================================
290
+ // Event Subscriptions
291
+ // ===========================================================================
292
+ /**
293
+ * Subscribe to manager events.
294
+ */
295
+ subscribe(listener) {
296
+ this.listeners.add(listener);
297
+ return () => this.listeners.delete(listener);
298
+ }
299
+ /**
300
+ * Subscribe to device connected events.
301
+ */
302
+ onDeviceConnected(callback) {
303
+ const listener = (event) => {
304
+ if (event.type === 'deviceConnected') {
305
+ callback(event.client, event.deviceId, event.deviceName);
306
+ }
307
+ };
308
+ this.listeners.add(listener);
309
+ return () => this.listeners.delete(listener);
310
+ }
311
+ /**
312
+ * Subscribe to device disconnected events.
313
+ */
314
+ onDeviceDisconnected(callback) {
315
+ const listener = (event) => {
316
+ if (event.type === 'deviceDisconnected') {
317
+ callback(event.deviceId);
318
+ }
319
+ };
320
+ this.listeners.add(listener);
321
+ return () => this.listeners.delete(listener);
322
+ }
323
+ // ===========================================================================
324
+ // Lifecycle
325
+ // ===========================================================================
326
+ /**
327
+ * Dispose of the manager and all connected devices.
328
+ */
329
+ dispose() {
330
+ if (this.disposed)
331
+ return;
332
+ this.disposed = true;
333
+ this.disconnectAll().catch(() => { });
334
+ this.listeners.clear();
335
+ this.clientUnsubscribes.clear();
336
+ this.scanAdapter = null;
337
+ }
338
+ // ===========================================================================
339
+ // Private Methods
340
+ // ===========================================================================
341
+ detectPlatform() {
342
+ // Check for browser environment
343
+ if (typeof window !== 'undefined' &&
344
+ typeof navigator !== 'undefined' &&
345
+ 'bluetooth' in navigator) {
346
+ return 'web';
347
+ }
348
+ // Check for Node.js environment
349
+ if (typeof process !== 'undefined' && process.versions?.node) {
350
+ return 'node';
351
+ }
352
+ // Default to native (React Native)
353
+ // Note: This fallback may not work well - users should specify platform
354
+ return 'native';
355
+ }
356
+ createAdapterFactory(platform) {
357
+ switch (platform) {
358
+ case 'web':
359
+ return () => {
360
+ // Dynamic import to avoid bundling issues
361
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
362
+ const { WebBLEAdapter } = require('../bluetooth/adapters/web');
363
+ return new WebBLEAdapter({ ble: BLE });
364
+ };
365
+ case 'node':
366
+ return () => {
367
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
368
+ const { NodeBLEAdapter } = require('../bluetooth/adapters/node');
369
+ return new NodeBLEAdapter({ ble: BLE });
370
+ };
371
+ case 'native':
372
+ return () => {
373
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
374
+ const { NativeBLEAdapter } = require('../bluetooth/adapters/native');
375
+ return new NativeBLEAdapter({ ble: BLE });
376
+ };
377
+ default:
378
+ throw new Error(`Unknown platform: ${platform}`);
379
+ }
380
+ }
381
+ handleClientEvent(deviceId, event) {
382
+ switch (event.type) {
383
+ case 'disconnected':
384
+ if (this.clients.has(deviceId)) {
385
+ const unsubscribe = this.clientUnsubscribes.get(deviceId);
386
+ unsubscribe?.();
387
+ this.clientUnsubscribes.delete(deviceId);
388
+ const client = this.clients.get(deviceId);
389
+ client?.dispose();
390
+ this.clients.delete(deviceId);
391
+ this.emit({ type: 'deviceDisconnected', deviceId });
392
+ }
393
+ break;
394
+ case 'error':
395
+ this.emit({ type: 'deviceError', deviceId, error: event.error });
396
+ break;
397
+ }
398
+ }
399
+ emit(event) {
400
+ this.listeners.forEach((listener) => {
401
+ try {
402
+ listener(event);
403
+ }
404
+ catch (e) {
405
+ console.error('[VoltraManager] Event listener error:', e);
406
+ }
407
+ });
408
+ }
409
+ ensureNotDisposed() {
410
+ if (this.disposed) {
411
+ throw new Error('Manager has been disposed');
412
+ }
413
+ }
414
+ }
415
+ //# sourceMappingURL=voltra-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voltra-manager.js","sourceRoot":"","sources":["../../../src/sdk/voltra-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Shared Utilities
3
+ */
4
+ export { delay, hexToBytes, bytesToHex, bytesEqual } from './utils';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/shared/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Shared Utilities
3
+ *
4
+ * Common utilities used across SDK modules.
5
+ */
6
+ /**
7
+ * Delay execution for a specified duration.
8
+ * @param ms Duration in milliseconds
9
+ */
10
+ export function delay(ms) {
11
+ return new Promise((resolve) => setTimeout(resolve, ms));
12
+ }
13
+ /**
14
+ * Convert hex string to Uint8Array.
15
+ * @param hex Hex string (e.g., "48656c6c6f")
16
+ */
17
+ export function hexToBytes(hex) {
18
+ const bytes = new Uint8Array(hex.length / 2);
19
+ for (let i = 0; i < bytes.length; i++) {
20
+ bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
21
+ }
22
+ return bytes;
23
+ }
24
+ /**
25
+ * Convert Uint8Array to hex string.
26
+ * @param bytes Byte array
27
+ */
28
+ export function bytesToHex(bytes) {
29
+ return Array.from(bytes)
30
+ .map((b) => b.toString(16).padStart(2, '0'))
31
+ .join('');
32
+ }
33
+ /**
34
+ * Check if two byte arrays are equal.
35
+ */
36
+ export function bytesEqual(a, b) {
37
+ if (a.length !== b.length)
38
+ return false;
39
+ for (let i = 0; i < a.length; i++) {
40
+ if (a[i] !== b[i])
41
+ return false;
42
+ }
43
+ return true;
44
+ }
45
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/shared/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,UAAU,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,KAAiB;IAC1C,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;SACrB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SAC3C,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,CAAa,EAAE,CAAa;IACrD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Voltra Domain
3
+ *
4
+ * Voltra device management, telemetry processing, and workout control.
5
+ */
6
+ // =============================================================================
7
+ // Models
8
+ // =============================================================================
9
+ // Device model
10
+ export { VoltraDevice, DEFAULT_SETTINGS, } from './models/device';
11
+ // Connection model
12
+ export { isValidVoltraTransition, VoltraConnectionStateModel, } from './models/connection';
13
+ // Device filter
14
+ export { VOLTRA_DEVICE_PREFIX, isVoltraDevice, filterVoltraDevices } from './models/device-filter';
15
+ // Telemetry models
16
+ export { createFrame, isActivePhase, isConcentricPhase, isEccentricPhase, } from './models/telemetry';
17
+ // =============================================================================
18
+ // Protocol
19
+ // =============================================================================
20
+ // Command builders
21
+ export { WeightCommands, ChainsCommands, EccentricCommands, } from './protocol/commands';
22
+ // Protocol constants
23
+ export { MessageTypes, TelemetryOffsets, Timing, Auth, Init, Workout, BLE, MovementPhase, PhaseNames, } from './protocol/constants';
24
+ // Telemetry decoder (low-level)
25
+ export { decodeNotification, decodeTelemetryFrame, encodeTelemetryFrame, identifyMessageType, } from './protocol/telemetry-decoder';
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/voltra/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gFAAgF;AAChF,SAAS;AACT,gFAAgF;AAEhF,eAAe;AACf,OAAO,EACL,YAAY,EACZ,gBAAgB,GAIjB,MAAM,iBAAiB,CAAC;AAEzB,mBAAmB;AACnB,OAAO,EAEL,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAE7B,gBAAgB;AAChB,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAEnG,mBAAmB;AACnB,OAAO,EAEL,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAE5B,gFAAgF;AAChF,WAAW;AACX,gFAAgF;AAEhF,mBAAmB;AACnB,OAAO,EACL,cAAc,EACd,cAAc,EACd,iBAAiB,GAElB,MAAM,qBAAqB,CAAC;AAE7B,qBAAqB;AACrB,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,GAAG,EACH,aAAa,EACb,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,gCAAgC;AAChC,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,GAGpB,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Voltra Connection Model
3
+ *
4
+ * Voltra-specific connection state that includes the authentication step.
5
+ */
6
+ /**
7
+ * Valid state transitions for Voltra connection.
8
+ */
9
+ const VALID_VOLTRA_TRANSITIONS = {
10
+ disconnected: ['connecting'],
11
+ connecting: ['authenticating', 'disconnected'],
12
+ authenticating: ['connected', 'disconnected'],
13
+ connected: ['disconnected'],
14
+ };
15
+ /**
16
+ * Check if a Voltra state transition is valid.
17
+ */
18
+ export function isValidVoltraTransition(from, to) {
19
+ return VALID_VOLTRA_TRANSITIONS[from].includes(to);
20
+ }
21
+ /**
22
+ * Voltra connection state model with validation.
23
+ */
24
+ export class VoltraConnectionStateModel {
25
+ constructor() {
26
+ this._state = 'disconnected';
27
+ }
28
+ get state() {
29
+ return this._state;
30
+ }
31
+ get isConnected() {
32
+ return this._state === 'connected';
33
+ }
34
+ get isConnecting() {
35
+ return this._state === 'connecting' || this._state === 'authenticating';
36
+ }
37
+ get isDisconnected() {
38
+ return this._state === 'disconnected';
39
+ }
40
+ /**
41
+ * Transition to a new state.
42
+ * @throws Error if transition is invalid
43
+ */
44
+ transitionTo(newState) {
45
+ if (!isValidVoltraTransition(this._state, newState)) {
46
+ throw new Error(`Invalid connection state transition: ${this._state} -> ${newState}`);
47
+ }
48
+ this._state = newState;
49
+ }
50
+ /**
51
+ * Force set state (for reconnection scenarios).
52
+ */
53
+ forceState(state) {
54
+ this._state = state;
55
+ }
56
+ /**
57
+ * Reset to disconnected state.
58
+ */
59
+ reset() {
60
+ this._state = 'disconnected';
61
+ }
62
+ }
63
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../../../src/voltra/models/connection.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH;;GAEG;AACH,MAAM,wBAAwB,GAA2D;IACvF,YAAY,EAAE,CAAC,YAAY,CAAC;IAC5B,UAAU,EAAE,CAAC,gBAAgB,EAAE,cAAc,CAAC;IAC9C,cAAc,EAAE,CAAC,WAAW,EAAE,cAAc,CAAC;IAC7C,SAAS,EAAE,CAAC,cAAc,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACrC,IAA2B,EAC3B,EAAyB;IAEzB,OAAO,wBAAwB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,0BAA0B;IAAvC;QACU,WAAM,GAA0B,cAAc,CAAC;IA0CzD,CAAC;IAxCC,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC;IACrC,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,MAAM,KAAK,YAAY,IAAI,IAAI,CAAC,MAAM,KAAK,gBAAgB,CAAC;IAC1E,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,MAAM,KAAK,cAAc,CAAC;IACxC,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,QAA+B;QAC1C,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,wCAAwC,IAAI,CAAC,MAAM,OAAO,QAAQ,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,KAA4B;QACrC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC;IAC/B,CAAC;CACF"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Voltra Device Filter
3
+ *
4
+ * Utility functions for filtering Voltra devices from BLE scan results.
5
+ */
6
+ import { BLE } from '../protocol/constants';
7
+ /**
8
+ * Voltra device name prefix.
9
+ */
10
+ export const VOLTRA_DEVICE_PREFIX = BLE.DEVICE_NAME_PREFIX;
11
+ /**
12
+ * Check if a device is a Voltra device.
13
+ */
14
+ export function isVoltraDevice(device) {
15
+ return device.name?.startsWith(VOLTRA_DEVICE_PREFIX) ?? false;
16
+ }
17
+ /**
18
+ * Filter Voltra devices from a list.
19
+ */
20
+ export function filterVoltraDevices(devices) {
21
+ return devices.filter(isVoltraDevice);
22
+ }
23
+ //# sourceMappingURL=device-filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-filter.js","sourceRoot":"","sources":["../../../../src/voltra/models/device-filter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAE5C;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC,kBAAkB,CAAC;AAE3D;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAwB;IACrD,OAAO,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,oBAAoB,CAAC,IAAI,KAAK,CAAC;AAChE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA2B;IAC7D,OAAO,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AACxC,CAAC"}