brilliantsole 0.0.26 → 0.0.28

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 (215) hide show
  1. package/README.md +16 -10
  2. package/assets/3d/anchor.glb +0 -0
  3. package/assets/3d/coin.glb +0 -0
  4. package/assets/3d/glasses.glb +0 -0
  5. package/assets/3d/rightHand.glb +0 -0
  6. package/assets/audio/bounceMedium.wav +0 -0
  7. package/assets/audio/bounceStrong.wav +0 -0
  8. package/assets/audio/bounceWeak.wav +0 -0
  9. package/assets/audio/coin.wav +0 -0
  10. package/assets/audio/getUp.wav +0 -0
  11. package/assets/audio/grab.wav +0 -0
  12. package/assets/audio/kick.wav +0 -0
  13. package/assets/audio/platterFadeIn old.wav +0 -0
  14. package/assets/audio/platterFadeIn.wav +0 -0
  15. package/assets/audio/platterFadeOut.wav +0 -0
  16. package/assets/audio/punch.wav +0 -0
  17. package/assets/audio/punchSqueak.wav +0 -0
  18. package/assets/audio/purr.wav +0 -0
  19. package/assets/audio/purrFadeOut.wav +0 -0
  20. package/assets/audio/release.wav +0 -0
  21. package/assets/audio/splat.wav +0 -0
  22. package/assets/audio/stomp.wav +0 -0
  23. package/assets/images/ukaton-pressure-0.svg +9 -0
  24. package/assets/images/ukaton-pressure-1.svg +9 -0
  25. package/assets/images/ukaton-pressure-10.svg +9 -0
  26. package/assets/images/ukaton-pressure-11.svg +9 -0
  27. package/assets/images/ukaton-pressure-12.svg +9 -0
  28. package/assets/images/ukaton-pressure-13.svg +9 -0
  29. package/assets/images/ukaton-pressure-14.svg +9 -0
  30. package/assets/images/ukaton-pressure-15.svg +9 -0
  31. package/assets/images/ukaton-pressure-2.svg +9 -0
  32. package/assets/images/ukaton-pressure-3.svg +9 -0
  33. package/assets/images/ukaton-pressure-4.svg +9 -0
  34. package/assets/images/ukaton-pressure-5.svg +9 -0
  35. package/assets/images/ukaton-pressure-6.svg +9 -0
  36. package/assets/images/ukaton-pressure-7.svg +9 -0
  37. package/assets/images/ukaton-pressure-8.svg +9 -0
  38. package/assets/images/ukaton-pressure-9.svg +9 -0
  39. package/assets/images/ukaton-right-insole.svg +798 -0
  40. package/build/brilliantsole.cjs +2870 -882
  41. package/build/brilliantsole.cjs.map +1 -1
  42. package/build/brilliantsole.js +2477 -782
  43. package/build/brilliantsole.js.map +1 -1
  44. package/build/brilliantsole.ls.js +2260 -592
  45. package/build/brilliantsole.ls.js.map +1 -1
  46. package/build/brilliantsole.min.js +1 -1
  47. package/build/brilliantsole.min.js.map +1 -1
  48. package/build/brilliantsole.module.d.ts +302 -116
  49. package/build/brilliantsole.module.js +2468 -782
  50. package/build/brilliantsole.module.js.map +1 -1
  51. package/build/brilliantsole.module.min.d.ts +302 -116
  52. package/build/brilliantsole.module.min.js +1 -1
  53. package/build/brilliantsole.module.min.js.map +1 -1
  54. package/build/brilliantsole.node.module.d.ts +295 -113
  55. package/build/brilliantsole.node.module.js +2860 -882
  56. package/build/brilliantsole.node.module.js.map +1 -1
  57. package/build/dts/BS-output.d.ts +10 -0
  58. package/build/dts/BS.d.ts +21 -9
  59. package/build/dts/CameraManager.d.ts +72 -0
  60. package/build/dts/Device.d.ts +53 -16
  61. package/build/dts/DeviceInformationManager.d.ts +4 -4
  62. package/build/dts/DeviceManager.d.ts +3 -0
  63. package/build/dts/FileTransferManager.d.ts +18 -8
  64. package/build/dts/InformationManager.d.ts +8 -5
  65. package/build/dts/TfliteManager.d.ts +22 -2
  66. package/build/dts/WifiManager.d.ts +61 -0
  67. package/build/dts/connection/BaseConnectionManager.d.ts +37 -3
  68. package/build/dts/connection/ClientConnectionManager.d.ts +11 -2
  69. package/build/dts/connection/bluetooth/BluetoothConnectionManager.d.ts +1 -0
  70. package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +3 -1
  71. package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +2 -0
  72. package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +2 -2
  73. package/build/dts/connection/udp/UDPConnectionManager.d.ts +28 -0
  74. package/build/dts/connection/webSocket/WebSocketConnectionManager.d.ts +25 -0
  75. package/build/dts/devicePair/DevicePair.d.ts +14 -10
  76. package/build/dts/devicePair/DevicePairPressureSensorDataManager.d.ts +8 -4
  77. package/build/dts/devicePair/DevicePairSensorDataManager.d.ts +2 -2
  78. package/build/dts/scanner/BaseScanner.d.ts +4 -1
  79. package/build/dts/scanner/NobleScanner.d.ts +2 -1
  80. package/build/dts/sensor/MotionSensorDataManager.d.ts +5 -2
  81. package/build/dts/sensor/SensorDataManager.d.ts +5 -4
  82. package/build/dts/server/BaseClient.d.ts +6 -3
  83. package/build/dts/server/ServerUtils.d.ts +1 -1
  84. package/build/dts/server/websocket/WebSocketUtils.d.ts +1 -1
  85. package/build/dts/utils/CenterOfPressureHelper.d.ts +2 -2
  86. package/build/dts/utils/Console.d.ts +2 -0
  87. package/build/dts/utils/MathUtils.d.ts +2 -0
  88. package/build/dts/utils/ThrottleUtils.d.ts +2 -0
  89. package/build/dts/vibration/VibrationManager.d.ts +19 -2
  90. package/build/index.d.ts +299 -113
  91. package/build/index.node.d.ts +292 -110
  92. package/examples/3d/scene.html +19 -5
  93. package/examples/3d/script.js +90 -17
  94. package/examples/3d-generic/index.html +144 -0
  95. package/examples/3d-generic/script.js +266 -0
  96. package/examples/balance/script.js +2 -1
  97. package/examples/basic/index.html +232 -18
  98. package/examples/basic/script.js +746 -106
  99. package/examples/bottango/index.html +11 -1
  100. package/examples/bottango/script.js +2 -2
  101. package/examples/center-of-pressure/index.html +114 -114
  102. package/examples/center-of-pressure/script.js +1 -1
  103. package/examples/device-pair/index.html +58 -58
  104. package/examples/device-pair/script.js +12 -8
  105. package/examples/edge-impulse/script.js +135 -44
  106. package/examples/edge-impulse-test/README.md +11 -0
  107. package/examples/edge-impulse-test/edge-impulse-standalone.js +7228 -0
  108. package/examples/edge-impulse-test/edge-impulse-standalone.wasm +0 -0
  109. package/examples/edge-impulse-test/index.html +75 -0
  110. package/examples/edge-impulse-test/run-impulse.js +135 -0
  111. package/examples/edge-impulse-test/script.js +200 -0
  112. package/examples/gloves/edge-impulse-standalone.js +7228 -0
  113. package/examples/gloves/edge-impulse-standalone.wasm +0 -0
  114. package/examples/gloves/index.html +119 -0
  115. package/examples/gloves/run-impulse.js +135 -0
  116. package/examples/gloves/scene.html +124 -0
  117. package/examples/gloves/script.js +931 -0
  118. package/examples/graph/index.html +11 -1
  119. package/examples/graph/script.js +94 -37
  120. package/examples/pressure/index.html +180 -12
  121. package/examples/pressure/script.js +144 -7
  122. package/examples/punch/index.html +135 -0
  123. package/examples/punch/punch.tflite +0 -0
  124. package/examples/punch/script.js +169 -0
  125. package/examples/recording/index.html +191 -183
  126. package/examples/server/index.html +109 -23
  127. package/examples/server/script.js +322 -111
  128. package/examples/ukaton-firmware-update/index.html +20 -0
  129. package/examples/ukaton-firmware-update/manifest.json +11 -0
  130. package/examples/ukaton-firmware-update/merged-firmware.bin +0 -0
  131. package/examples/utils/aframe/aframe-master.min.js +2 -0
  132. package/examples/utils/aframe/bs-vibration.js +150 -0
  133. package/examples/utils/aframe/force-pushable.js +80 -0
  134. package/examples/utils/aframe/grabbable-anchor.js +46 -0
  135. package/examples/utils/aframe/grabbable-listener.js +31 -0
  136. package/examples/utils/aframe/grabbable-physics-body.js +190 -0
  137. package/examples/utils/aframe/grow-shrink.js +25 -0
  138. package/examples/utils/aframe/hand-punch.js +119 -0
  139. package/examples/utils/aframe/my-obb-collider.js +293 -0
  140. package/examples/utils/aframe/occlude-hand-tracking-controls.js +47 -0
  141. package/examples/utils/aframe/occlude-mesh.js +42 -0
  142. package/examples/utils/aframe/palm-up-detector.js +47 -0
  143. package/examples/utils/aframe/shadow-material.js +20 -0
  144. package/examples/utils/aframe/soft-shadow-light.js +9 -0
  145. package/examples/webxr/script.js +3 -3
  146. package/examples/webxr-2/assets/3d/soccerBall.glb +0 -0
  147. package/examples/webxr-2/assets/audio/shellBounce.wav +0 -0
  148. package/examples/webxr-2/assets/audio/shellHit.wav +0 -0
  149. package/examples/webxr-2/assets/audio/shellKick.wav +0 -0
  150. package/examples/webxr-2/assets/audio/soccerBounce.wav +0 -0
  151. package/examples/webxr-2/assets/audio/soccerKick.mp3 +0 -0
  152. package/examples/webxr-2/assets/images/shellTexture.png +0 -0
  153. package/examples/webxr-2/components/bs-ankle.js +337 -0
  154. package/examples/webxr-2/components/coin.js +84 -0
  155. package/examples/webxr-2/components/custom-wrap.js +17 -0
  156. package/examples/webxr-2/components/goomba.js +3250 -0
  157. package/examples/webxr-2/components/init-shell-material.js +215 -0
  158. package/examples/webxr-2/components/platter.js +172 -0
  159. package/examples/webxr-2/components/shell.js +374 -0
  160. package/examples/webxr-2/components/soccer-ball.js +250 -0
  161. package/examples/webxr-2/components/squashed-goomba.js +249 -0
  162. package/examples/webxr-2/edge-impulse-standalone.js +7228 -0
  163. package/examples/webxr-2/edge-impulse-standalone.wasm +0 -0
  164. package/examples/webxr-2/index.html +996 -0
  165. package/examples/webxr-2/kick.tflite +0 -0
  166. package/examples/webxr-2/kick2.tflite +0 -0
  167. package/examples/webxr-2/run-impulse.js +135 -0
  168. package/examples/webxr-2/script.js +384 -0
  169. package/package.json +2 -1
  170. package/src/.prettierrc +4 -0
  171. package/src/BS.ts +66 -9
  172. package/src/CameraManager.ts +499 -0
  173. package/src/Device.ts +620 -92
  174. package/src/DeviceInformationManager.ts +22 -11
  175. package/src/DeviceManager.ts +94 -25
  176. package/src/FileTransferManager.ts +146 -21
  177. package/src/FirmwareManager.ts +1 -1
  178. package/src/InformationManager.ts +62 -20
  179. package/src/TfliteManager.ts +172 -26
  180. package/src/WifiManager.ts +323 -0
  181. package/src/connection/BaseConnectionManager.ts +145 -30
  182. package/src/connection/ClientConnectionManager.ts +47 -11
  183. package/src/connection/bluetooth/BluetoothConnectionManager.ts +14 -3
  184. package/src/connection/bluetooth/NobleConnectionManager.ts +155 -42
  185. package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +104 -35
  186. package/src/connection/bluetooth/bluetoothUUIDs.ts +40 -13
  187. package/src/connection/udp/UDPConnectionManager.ts +356 -0
  188. package/src/connection/websocket/WebSocketConnectionManager.ts +282 -0
  189. package/src/devicePair/DevicePair.ts +145 -49
  190. package/src/devicePair/DevicePairPressureSensorDataManager.ts +72 -24
  191. package/src/devicePair/DevicePairSensorDataManager.ts +5 -5
  192. package/src/scanner/BaseScanner.ts +49 -11
  193. package/src/scanner/NobleScanner.ts +81 -17
  194. package/src/sensor/BarometerSensorDataManager.ts +1 -1
  195. package/src/sensor/MotionSensorDataManager.ts +22 -7
  196. package/src/sensor/PressureSensorDataManager.ts +47 -13
  197. package/src/sensor/SensorConfigurationManager.ts +75 -24
  198. package/src/sensor/SensorDataManager.ts +107 -26
  199. package/src/server/BaseClient.ts +192 -37
  200. package/src/server/BaseServer.ts +201 -43
  201. package/src/server/ServerUtils.ts +39 -9
  202. package/src/server/udp/UDPServer.ts +74 -23
  203. package/src/server/udp/UDPUtils.ts +9 -2
  204. package/src/server/websocket/WebSocketClient.ts +30 -9
  205. package/src/server/websocket/WebSocketServer.ts +1 -1
  206. package/src/server/websocket/WebSocketUtils.ts +4 -2
  207. package/src/utils/CenterOfPressureHelper.ts +5 -5
  208. package/src/utils/Console.ts +62 -9
  209. package/src/utils/MathUtils.ts +31 -1
  210. package/src/utils/ParseUtils.ts +25 -6
  211. package/src/utils/ThrottleUtils.ts +62 -0
  212. package/src/utils/Timer.ts +1 -1
  213. package/src/utils/checksum.ts +1 -1
  214. package/src/utils/mcumgr.js +1 -1
  215. package/src/vibration/VibrationManager.ts +166 -40
@@ -1,10 +1,14 @@
1
1
  import { createConsole } from "../utils/Console.ts";
2
- import { VibrationWaveformEffect, VibrationWaveformEffects } from "./VibrationWaveformEffects.ts";
2
+ import {
3
+ VibrationWaveformEffect,
4
+ VibrationWaveformEffects,
5
+ } from "./VibrationWaveformEffects.ts";
3
6
  import { concatenateArrayBuffers } from "../utils/ArrayBufferUtils.ts";
4
- import { SendMessageCallback } from "../Device.ts";
7
+ import Device, { SendMessageCallback } from "../Device.ts";
5
8
  import autoBind from "auto-bind";
9
+ import EventDispatcher from "../utils/EventDispatcher.ts";
6
10
 
7
- const _console = createConsole("VibrationManager");
11
+ const _console = createConsole("VibrationManager", { log: false });
8
12
 
9
13
  export const VibrationLocations = ["front", "rear"] as const;
10
14
  export type VibrationLocation = (typeof VibrationLocations)[number];
@@ -23,9 +27,19 @@ export interface VibrationWaveformSegment {
23
27
  amplitude: number;
24
28
  }
25
29
 
26
- export const VibrationMessageTypes = ["triggerVibration"] as const;
30
+ export const VibrationMessageTypes = [
31
+ "getVibrationLocations",
32
+ "triggerVibration",
33
+ ] as const;
27
34
  export type VibrationMessageType = (typeof VibrationMessageTypes)[number];
28
35
 
36
+ export const VibrationEventTypes = VibrationMessageTypes;
37
+ export type VibrationEventType = (typeof VibrationEventTypes)[number];
38
+
39
+ export interface VibrationEventMessages {
40
+ getVibrationLocations: { vibrationLocations: VibrationLocation[] };
41
+ }
42
+
29
43
  export const MaxNumberOfVibrationWaveformEffectSegments = 8;
30
44
  export const MaxVibrationWaveformSegmentDuration = 2550;
31
45
  export const MaxVibrationWaveformEffectSegmentDelay = 1270;
@@ -38,20 +52,31 @@ interface BaseVibrationConfiguration {
38
52
  locations?: VibrationLocation[];
39
53
  }
40
54
 
41
- export interface VibrationWaveformEffectConfiguration extends BaseVibrationConfiguration {
55
+ export interface VibrationWaveformEffectConfiguration
56
+ extends BaseVibrationConfiguration {
42
57
  type: "waveformEffect";
43
58
  segments: VibrationWaveformEffectSegment[];
44
59
  loopCount?: number;
45
60
  }
46
61
 
47
- export interface VibrationWaveformConfiguration extends BaseVibrationConfiguration {
62
+ export interface VibrationWaveformConfiguration
63
+ extends BaseVibrationConfiguration {
48
64
  type: "waveform";
49
65
  segments: VibrationWaveformSegment[];
50
66
  }
51
67
 
52
- export type VibrationConfiguration = VibrationWaveformEffectConfiguration | VibrationWaveformConfiguration;
68
+ export type VibrationConfiguration =
69
+ | VibrationWaveformEffectConfiguration
70
+ | VibrationWaveformConfiguration;
53
71
 
54
- export type SendVibrationMessageCallback = SendMessageCallback<VibrationMessageType>;
72
+ export type SendVibrationMessageCallback =
73
+ SendMessageCallback<VibrationMessageType>;
74
+
75
+ export type VibrationEventDispatcher = EventDispatcher<
76
+ Device,
77
+ VibrationEventType,
78
+ VibrationEventMessages
79
+ >;
55
80
 
56
81
  class VibrationManager {
57
82
  constructor() {
@@ -59,9 +84,20 @@ class VibrationManager {
59
84
  }
60
85
  sendMessage!: SendVibrationMessageCallback;
61
86
 
87
+ eventDispatcher!: VibrationEventDispatcher;
88
+ get #dispatchEvent() {
89
+ return this.eventDispatcher.dispatchEvent;
90
+ }
91
+ get waitForEvent() {
92
+ return this.eventDispatcher.waitForEvent;
93
+ }
94
+
62
95
  #verifyLocation(location: VibrationLocation) {
63
96
  _console.assertTypeWithError(location, "string");
64
- _console.assertWithError(VibrationLocations.includes(location), `invalid location "${location}"`);
97
+ _console.assertWithError(
98
+ VibrationLocations.includes(location),
99
+ `invalid location "${location}"`
100
+ );
65
101
  }
66
102
  #verifyLocations(locations: VibrationLocation[]) {
67
103
  this.#assertNonEmptyArray(locations);
@@ -78,7 +114,10 @@ class VibrationManager {
78
114
  locationsBitmask |= 1 << locationIndex;
79
115
  });
80
116
  _console.log({ locationsBitmask });
81
- _console.assertWithError(locationsBitmask > 0, `locationsBitmask must not be zero`);
117
+ _console.assertWithError(
118
+ locationsBitmask > 0,
119
+ `locationsBitmask must not be zero`
120
+ );
82
121
  return locationsBitmask;
83
122
  }
84
123
 
@@ -94,13 +133,18 @@ class VibrationManager {
94
133
  );
95
134
  }
96
135
 
97
- #verifyWaveformEffectSegment(waveformEffectSegment: VibrationWaveformEffectSegment) {
136
+ #verifyWaveformEffectSegment(
137
+ waveformEffectSegment: VibrationWaveformEffectSegment
138
+ ) {
98
139
  if (waveformEffectSegment.effect != undefined) {
99
140
  const waveformEffect = waveformEffectSegment.effect;
100
141
  this.#verifyWaveformEffect(waveformEffect);
101
142
  } else if (waveformEffectSegment.delay != undefined) {
102
143
  const { delay } = waveformEffectSegment;
103
- _console.assertWithError(delay >= 0, `delay must be 0ms or greater (got ${delay})`);
144
+ _console.assertWithError(
145
+ delay >= 0,
146
+ `delay must be 0ms or greater (got ${delay})`
147
+ );
104
148
  _console.assertWithError(
105
149
  delay <= MaxVibrationWaveformEffectSegmentDelay,
106
150
  `delay must be ${MaxVibrationWaveformEffectSegmentDelay}ms or less (got ${delay})`
@@ -115,22 +159,28 @@ class VibrationManager {
115
159
  }
116
160
  }
117
161
 
118
- #verifyWaveformEffectSegmentLoopCount(waveformEffectSegmentLoopCount: number) {
162
+ #verifyWaveformEffectSegmentLoopCount(
163
+ waveformEffectSegmentLoopCount: number
164
+ ) {
119
165
  _console.assertTypeWithError(waveformEffectSegmentLoopCount, "number");
120
166
  _console.assertWithError(
121
167
  waveformEffectSegmentLoopCount >= 0,
122
168
  `waveformEffectSegmentLoopCount must be 0 or greater (got ${waveformEffectSegmentLoopCount})`
123
169
  );
124
170
  _console.assertWithError(
125
- waveformEffectSegmentLoopCount <= MaxVibrationWaveformEffectSegmentLoopCount,
171
+ waveformEffectSegmentLoopCount <=
172
+ MaxVibrationWaveformEffectSegmentLoopCount,
126
173
  `waveformEffectSegmentLoopCount must be ${MaxVibrationWaveformEffectSegmentLoopCount} or fewer (got ${waveformEffectSegmentLoopCount})`
127
174
  );
128
175
  }
129
176
 
130
- #verifyWaveformEffectSegments(waveformEffectSegments: VibrationWaveformEffectSegment[]) {
177
+ #verifyWaveformEffectSegments(
178
+ waveformEffectSegments: VibrationWaveformEffectSegment[]
179
+ ) {
131
180
  this.#assertNonEmptyArray(waveformEffectSegments);
132
181
  _console.assertWithError(
133
- waveformEffectSegments.length <= MaxNumberOfVibrationWaveformEffectSegments,
182
+ waveformEffectSegments.length <=
183
+ MaxNumberOfVibrationWaveformEffectSegments,
134
184
  `must have ${MaxNumberOfVibrationWaveformEffectSegments} waveformEffectSegments or fewer (got ${waveformEffectSegments.length})`
135
185
  );
136
186
  waveformEffectSegments.forEach((waveformEffectSegment) => {
@@ -138,14 +188,17 @@ class VibrationManager {
138
188
  });
139
189
  }
140
190
 
141
- #verifyWaveformEffectSequenceLoopCount(waveformEffectSequenceLoopCount: number) {
191
+ #verifyWaveformEffectSequenceLoopCount(
192
+ waveformEffectSequenceLoopCount: number
193
+ ) {
142
194
  _console.assertTypeWithError(waveformEffectSequenceLoopCount, "number");
143
195
  _console.assertWithError(
144
196
  waveformEffectSequenceLoopCount >= 0,
145
197
  `waveformEffectSequenceLoopCount must be 0 or greater (got ${waveformEffectSequenceLoopCount})`
146
198
  );
147
199
  _console.assertWithError(
148
- waveformEffectSequenceLoopCount <= MaxVibrationWaveformEffectSequenceLoopCount,
200
+ waveformEffectSequenceLoopCount <=
201
+ MaxVibrationWaveformEffectSequenceLoopCount,
149
202
  `waveformEffectSequenceLoopCount must be ${MaxVibrationWaveformEffectSequenceLoopCount} or fewer (got ${waveformEffectSequenceLoopCount})`
150
203
  );
151
204
  }
@@ -189,29 +242,37 @@ class VibrationManager {
189
242
  waveformEffectSequenceLoopCount: number = 0
190
243
  ) {
191
244
  this.#verifyWaveformEffectSegments(waveformEffectSegments);
192
- this.#verifyWaveformEffectSequenceLoopCount(waveformEffectSequenceLoopCount);
245
+ this.#verifyWaveformEffectSequenceLoopCount(
246
+ waveformEffectSequenceLoopCount
247
+ );
193
248
 
194
249
  let dataArray = [];
195
250
  let byteOffset = 0;
196
251
 
197
- const hasAtLeast1WaveformEffectWithANonzeroLoopCount = waveformEffectSegments.some((waveformEffectSegment) => {
198
- const { loopCount } = waveformEffectSegment;
199
- return loopCount != undefined && loopCount > 0;
200
- });
252
+ const hasAtLeast1WaveformEffectWithANonzeroLoopCount =
253
+ waveformEffectSegments.some((waveformEffectSegment) => {
254
+ const { loopCount } = waveformEffectSegment;
255
+ return loopCount != undefined && loopCount > 0;
256
+ });
201
257
 
202
258
  const includeAllWaveformEffectSegments =
203
- hasAtLeast1WaveformEffectWithANonzeroLoopCount || waveformEffectSequenceLoopCount != 0;
259
+ hasAtLeast1WaveformEffectWithANonzeroLoopCount ||
260
+ waveformEffectSequenceLoopCount != 0;
204
261
 
205
262
  for (
206
263
  let index = 0;
207
264
  index < waveformEffectSegments.length ||
208
- (includeAllWaveformEffectSegments && index < MaxNumberOfVibrationWaveformEffectSegments);
265
+ (includeAllWaveformEffectSegments &&
266
+ index < MaxNumberOfVibrationWaveformEffectSegments);
209
267
  index++
210
268
  ) {
211
- const waveformEffectSegment = waveformEffectSegments[index] || { effect: "none" };
269
+ const waveformEffectSegment = waveformEffectSegments[index] || {
270
+ effect: "none",
271
+ };
212
272
  if (waveformEffectSegment.effect != undefined) {
213
273
  const waveformEffect = waveformEffectSegment.effect;
214
- dataArray[byteOffset++] = VibrationWaveformEffects.indexOf(waveformEffect);
274
+ dataArray[byteOffset++] =
275
+ VibrationWaveformEffects.indexOf(waveformEffect);
215
276
  } else if (waveformEffectSegment.delay != undefined) {
216
277
  const { delay } = waveformEffectSegment;
217
278
  dataArray[byteOffset++] = (1 << 7) | Math.floor(delay / 10); // set most significant bit to 1
@@ -220,14 +281,17 @@ class VibrationManager {
220
281
  }
221
282
  }
222
283
 
223
- const includeAllWaveformEffectSegmentLoopCounts = waveformEffectSequenceLoopCount != 0;
284
+ const includeAllWaveformEffectSegmentLoopCounts =
285
+ waveformEffectSequenceLoopCount != 0;
224
286
  for (
225
287
  let index = 0;
226
288
  index < waveformEffectSegments.length ||
227
- (includeAllWaveformEffectSegmentLoopCounts && index < MaxNumberOfVibrationWaveformEffectSegments);
289
+ (includeAllWaveformEffectSegmentLoopCounts &&
290
+ index < MaxNumberOfVibrationWaveformEffectSegments);
228
291
  index++
229
292
  ) {
230
- const waveformEffectSegmentLoopCount = waveformEffectSegments[index]?.loopCount || 0;
293
+ const waveformEffectSegmentLoopCount =
294
+ waveformEffectSegments[index]?.loopCount || 0;
231
295
  if (index == 0 || index == 4) {
232
296
  dataArray[byteOffset] = 0;
233
297
  }
@@ -245,12 +309,18 @@ class VibrationManager {
245
309
  _console.log({ dataArray, dataView });
246
310
  return this.#createData(locations, "waveformEffect", dataView);
247
311
  }
248
- #createWaveformData(locations: VibrationLocation[], waveformSegments: VibrationWaveformSegment[]) {
312
+ #createWaveformData(
313
+ locations: VibrationLocation[],
314
+ waveformSegments: VibrationWaveformSegment[]
315
+ ) {
249
316
  this.#verifyWaveformSegments(waveformSegments);
250
317
  const dataView = new DataView(new ArrayBuffer(waveformSegments.length * 2));
251
318
  waveformSegments.forEach((waveformSegment, index) => {
252
319
  dataView.setUint8(index * 2, Math.floor(waveformSegment.amplitude * 127));
253
- dataView.setUint8(index * 2 + 1, Math.floor(waveformSegment.duration / 10));
320
+ dataView.setUint8(
321
+ index * 2 + 1,
322
+ Math.floor(waveformSegment.duration / 10)
323
+ );
254
324
  });
255
325
  _console.log({ dataView });
256
326
  return this.#createData(locations, "waveform", dataView);
@@ -258,27 +328,45 @@ class VibrationManager {
258
328
 
259
329
  #verifyVibrationType(vibrationType: VibrationType) {
260
330
  _console.assertTypeWithError(vibrationType, "string");
261
- _console.assertWithError(VibrationTypes.includes(vibrationType), `invalid vibrationType "${vibrationType}"`);
331
+ _console.assertWithError(
332
+ VibrationTypes.includes(vibrationType),
333
+ `invalid vibrationType "${vibrationType}"`
334
+ );
262
335
  }
263
336
 
264
- #createData(locations: VibrationLocation[], vibrationType: VibrationType, dataView: DataView) {
337
+ #createData(
338
+ locations: VibrationLocation[],
339
+ vibrationType: VibrationType,
340
+ dataView: DataView
341
+ ) {
265
342
  _console.assertWithError(dataView?.byteLength > 0, "no data received");
266
343
  const locationsBitmask = this.#createLocationsBitmask(locations);
267
344
  this.#verifyVibrationType(vibrationType);
268
345
  const vibrationTypeIndex = VibrationTypes.indexOf(vibrationType);
269
346
  _console.log({ locationsBitmask, vibrationTypeIndex, dataView });
270
- const data = concatenateArrayBuffers(locationsBitmask, vibrationTypeIndex, dataView.byteLength, dataView);
347
+ const data = concatenateArrayBuffers(
348
+ locationsBitmask,
349
+ vibrationTypeIndex,
350
+ dataView.byteLength,
351
+ dataView
352
+ );
271
353
  _console.log({ data });
272
354
  return data;
273
355
  }
274
356
 
275
- async triggerVibration(vibrationConfigurations: VibrationConfiguration[], sendImmediately: boolean = true) {
357
+ async triggerVibration(
358
+ vibrationConfigurations: VibrationConfiguration[],
359
+ sendImmediately: boolean = true
360
+ ) {
276
361
  let triggerVibrationData!: ArrayBuffer;
277
362
  vibrationConfigurations.forEach((vibrationConfiguration) => {
278
363
  const { type } = vibrationConfiguration;
279
364
 
280
365
  let { locations } = vibrationConfiguration;
281
- locations = locations || VibrationLocations.slice();
366
+ locations = locations || this.vibrationLocations.slice();
367
+ locations = locations.filter((location) =>
368
+ this.vibrationLocations.includes(location)
369
+ );
282
370
 
283
371
  let arrayBuffer: ArrayBuffer;
284
372
 
@@ -286,7 +374,11 @@ class VibrationManager {
286
374
  case "waveformEffect":
287
375
  {
288
376
  const { segments, loopCount } = vibrationConfiguration;
289
- arrayBuffer = this.#createWaveformEffectsData(locations, segments, loopCount);
377
+ arrayBuffer = this.#createWaveformEffectsData(
378
+ locations,
379
+ segments,
380
+ loopCount
381
+ );
290
382
  }
291
383
  break;
292
384
  case "waveform":
@@ -299,9 +391,43 @@ class VibrationManager {
299
391
  throw Error(`invalid vibration type "${type}"`);
300
392
  }
301
393
  _console.log({ type, arrayBuffer });
302
- triggerVibrationData = concatenateArrayBuffers(triggerVibrationData, arrayBuffer);
394
+ triggerVibrationData = concatenateArrayBuffers(
395
+ triggerVibrationData,
396
+ arrayBuffer
397
+ );
303
398
  });
304
- await this.sendMessage([{ type: "triggerVibration", data: triggerVibrationData }], sendImmediately);
399
+ await this.sendMessage(
400
+ [{ type: "triggerVibration", data: triggerVibrationData }],
401
+ sendImmediately
402
+ );
403
+ }
404
+
405
+ #vibrationLocations: VibrationLocation[] = [];
406
+ get vibrationLocations() {
407
+ return this.#vibrationLocations;
408
+ }
409
+ #onVibrationLocations(vibrationLocations: VibrationLocation[]) {
410
+ this.#vibrationLocations = vibrationLocations;
411
+ _console.log("vibrationLocations", vibrationLocations);
412
+ this.#dispatchEvent("getVibrationLocations", {
413
+ vibrationLocations: this.#vibrationLocations,
414
+ });
415
+ }
416
+
417
+ // MESSAGE
418
+ parseMessage(messageType: VibrationMessageType, dataView: DataView) {
419
+ _console.log({ messageType });
420
+
421
+ switch (messageType) {
422
+ case "getVibrationLocations":
423
+ const vibrationLocations = Array.from(new Uint8Array(dataView.buffer))
424
+ .map((index) => VibrationLocations[index])
425
+ .filter(Boolean);
426
+ this.#onVibrationLocations(vibrationLocations);
427
+ break;
428
+ default:
429
+ throw Error(`uncaught messageType ${messageType}`);
430
+ }
305
431
  }
306
432
  }
307
433