brilliantsole 0.0.27 → 0.0.29

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 (202) hide show
  1. package/assets/3d/anchor.glb +0 -0
  2. package/assets/3d/coin.glb +0 -0
  3. package/assets/3d/glasses.glb +0 -0
  4. package/assets/audio/bounceMedium.wav +0 -0
  5. package/assets/audio/bounceStrong.wav +0 -0
  6. package/assets/audio/bounceWeak.wav +0 -0
  7. package/assets/audio/coin.wav +0 -0
  8. package/assets/audio/getUp.wav +0 -0
  9. package/assets/audio/grab.wav +0 -0
  10. package/assets/audio/kick.wav +0 -0
  11. package/assets/audio/platterFadeIn old.wav +0 -0
  12. package/assets/audio/platterFadeIn.wav +0 -0
  13. package/assets/audio/platterFadeOut.wav +0 -0
  14. package/assets/audio/punch.wav +0 -0
  15. package/assets/audio/punchSqueak.wav +0 -0
  16. package/assets/audio/purr.wav +0 -0
  17. package/assets/audio/purrFadeOut.wav +0 -0
  18. package/assets/audio/release.wav +0 -0
  19. package/assets/audio/splat.wav +0 -0
  20. package/assets/audio/stomp.wav +0 -0
  21. package/build/brilliantsole.cjs +3091 -741
  22. package/build/brilliantsole.cjs.map +1 -1
  23. package/build/brilliantsole.js +2759 -709
  24. package/build/brilliantsole.js.map +1 -1
  25. package/build/brilliantsole.ls.js +2602 -543
  26. package/build/brilliantsole.ls.js.map +1 -1
  27. package/build/brilliantsole.min.js +1 -1
  28. package/build/brilliantsole.min.js.map +1 -1
  29. package/build/brilliantsole.module.d.ts +295 -65
  30. package/build/brilliantsole.module.js +2749 -710
  31. package/build/brilliantsole.module.js.map +1 -1
  32. package/build/brilliantsole.module.min.d.ts +295 -65
  33. package/build/brilliantsole.module.min.js +1 -1
  34. package/build/brilliantsole.module.min.js.map +1 -1
  35. package/build/brilliantsole.node.module.d.ts +289 -62
  36. package/build/brilliantsole.node.module.js +3080 -742
  37. package/build/brilliantsole.node.module.js.map +1 -1
  38. package/build/dts/BS-output.d.ts +10 -0
  39. package/build/dts/BS.d.ts +21 -8
  40. package/build/dts/CameraManager.d.ts +72 -0
  41. package/build/dts/Device.d.ts +64 -13
  42. package/build/dts/DeviceInformationManager.d.ts +4 -4
  43. package/build/dts/DeviceManager.d.ts +2 -0
  44. package/build/dts/FileTransferManager.d.ts +18 -8
  45. package/build/dts/InformationManager.d.ts +2 -0
  46. package/build/dts/MicrophoneManager.d.ts +88 -0
  47. package/build/dts/TfliteManager.d.ts +22 -2
  48. package/build/dts/WifiManager.d.ts +61 -0
  49. package/build/dts/connection/BaseConnectionManager.d.ts +35 -3
  50. package/build/dts/connection/ClientConnectionManager.d.ts +7 -2
  51. package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +2 -1
  52. package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +1 -0
  53. package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +2 -2
  54. package/build/dts/connection/udp/UDPConnectionManager.d.ts +28 -0
  55. package/build/dts/connection/webSocket/WebSocketConnectionManager.d.ts +25 -0
  56. package/build/dts/devicePair/DevicePair.d.ts +5 -5
  57. package/build/dts/scanner/BaseScanner.d.ts +4 -1
  58. package/build/dts/scanner/NobleScanner.d.ts +2 -1
  59. package/build/dts/sensor/MotionSensorDataManager.d.ts +5 -2
  60. package/build/dts/sensor/SensorDataManager.d.ts +5 -4
  61. package/build/dts/server/BaseClient.d.ts +5 -3
  62. package/build/dts/server/ServerUtils.d.ts +1 -1
  63. package/build/dts/server/websocket/WebSocketUtils.d.ts +1 -1
  64. package/build/dts/utils/AudioUtils.d.ts +2 -0
  65. package/build/dts/utils/Console.d.ts +2 -0
  66. package/build/dts/utils/ThrottleUtils.d.ts +2 -0
  67. package/build/dts/vibration/VibrationManager.d.ts +19 -2
  68. package/build/index.d.ts +292 -62
  69. package/build/index.node.d.ts +286 -59
  70. package/examples/3d/scene.html +19 -5
  71. package/examples/3d-generic/index.html +144 -0
  72. package/examples/3d-generic/script.js +266 -0
  73. package/examples/basic/index.html +267 -17
  74. package/examples/basic/script.js +958 -105
  75. package/examples/camera/barcode-detector.js +109 -0
  76. package/examples/camera/depth-estimation.js +71 -0
  77. package/examples/camera/face-detector.js +119 -0
  78. package/examples/camera/face-landmark.js +111 -0
  79. package/examples/camera/gesture-recognition.js +97 -0
  80. package/examples/camera/hand-landmark.js +74 -0
  81. package/examples/camera/image-segmentation.js +98 -0
  82. package/examples/camera/image-to-text.js +43 -0
  83. package/examples/camera/image-upscale.js +75 -0
  84. package/examples/camera/index.html +129 -0
  85. package/examples/camera/object-detection.js +98 -0
  86. package/examples/camera/pose-landmark.js +60 -0
  87. package/examples/camera/script.js +316 -0
  88. package/examples/camera/utils.js +165 -0
  89. package/examples/camera/yolo-tiny.js +54 -0
  90. package/examples/camera/yolo.js +119 -0
  91. package/examples/edge-impulse/script.js +157 -48
  92. package/examples/edge-impulse-test/README.md +11 -0
  93. package/examples/edge-impulse-test/edge-impulse-standalone.js +7228 -0
  94. package/examples/edge-impulse-test/edge-impulse-standalone.wasm +0 -0
  95. package/examples/edge-impulse-test/index.html +75 -0
  96. package/examples/edge-impulse-test/run-impulse.js +135 -0
  97. package/examples/edge-impulse-test/script.js +200 -0
  98. package/examples/glasses-gestures/README.md +11 -0
  99. package/examples/glasses-gestures/edge-impulse-standalone.js +7228 -0
  100. package/examples/glasses-gestures/edge-impulse-standalone.wasm +0 -0
  101. package/examples/glasses-gestures/index.html +69 -0
  102. package/examples/glasses-gestures/run-impulse.js +135 -0
  103. package/examples/glasses-gestures/script.js +226 -0
  104. package/examples/gloves/edge-impulse-standalone.js +7228 -0
  105. package/examples/gloves/edge-impulse-standalone.wasm +0 -0
  106. package/examples/gloves/index.html +4 -1
  107. package/examples/gloves/run-impulse.js +135 -0
  108. package/examples/gloves/script.js +367 -51
  109. package/examples/graph/script.js +94 -37
  110. package/examples/microphone/gender.js +54 -0
  111. package/examples/microphone/index.html +102 -0
  112. package/examples/microphone/script.js +394 -0
  113. package/examples/microphone/utils.js +45 -0
  114. package/examples/microphone/whisper-realtime.js +166 -0
  115. package/examples/microphone/whisper.js +132 -0
  116. package/examples/punch/index.html +135 -0
  117. package/examples/punch/punch.tflite +0 -0
  118. package/examples/punch/script.js +169 -0
  119. package/examples/server/index.html +98 -22
  120. package/examples/server/script.js +317 -109
  121. package/examples/ukaton-firmware-update/merged-firmware.bin +0 -0
  122. package/examples/utils/aframe/aframe-master.min.js +2 -0
  123. package/examples/utils/aframe/bs-vibration.js +150 -0
  124. package/examples/utils/aframe/force-pushable.js +80 -0
  125. package/examples/utils/aframe/grabbable-anchor.js +46 -0
  126. package/examples/utils/aframe/grabbable-listener.js +31 -0
  127. package/examples/utils/aframe/grabbable-physics-body.js +190 -0
  128. package/examples/utils/aframe/grow-shrink.js +25 -0
  129. package/examples/utils/aframe/hand-punch.js +119 -0
  130. package/examples/utils/aframe/my-obb-collider.js +293 -0
  131. package/examples/utils/aframe/occlude-hand-tracking-controls.js +47 -0
  132. package/examples/utils/aframe/occlude-mesh.js +42 -0
  133. package/examples/utils/aframe/palm-up-detector.js +47 -0
  134. package/examples/utils/aframe/shadow-material.js +20 -0
  135. package/examples/utils/aframe/soft-shadow-light.js +9 -0
  136. package/examples/webxr-2/assets/3d/soccerBall.glb +0 -0
  137. package/examples/webxr-2/assets/audio/shellBounce.wav +0 -0
  138. package/examples/webxr-2/assets/audio/shellHit.wav +0 -0
  139. package/examples/webxr-2/assets/audio/shellKick.wav +0 -0
  140. package/examples/webxr-2/assets/audio/soccerBounce.wav +0 -0
  141. package/examples/webxr-2/assets/audio/soccerKick.mp3 +0 -0
  142. package/examples/webxr-2/assets/images/shellTexture.png +0 -0
  143. package/examples/webxr-2/components/bs-ankle.js +337 -0
  144. package/examples/webxr-2/components/coin.js +84 -0
  145. package/examples/webxr-2/components/custom-wrap.js +17 -0
  146. package/examples/webxr-2/components/goomba.js +3250 -0
  147. package/examples/webxr-2/components/init-shell-material.js +215 -0
  148. package/examples/webxr-2/components/platter.js +172 -0
  149. package/examples/webxr-2/components/shell.js +374 -0
  150. package/examples/webxr-2/components/soccer-ball.js +250 -0
  151. package/examples/webxr-2/components/squashed-goomba.js +249 -0
  152. package/examples/webxr-2/edge-impulse-standalone.js +7228 -0
  153. package/examples/webxr-2/edge-impulse-standalone.wasm +0 -0
  154. package/examples/webxr-2/index.html +996 -0
  155. package/examples/webxr-2/kick.tflite +0 -0
  156. package/examples/webxr-2/kick2.tflite +0 -0
  157. package/examples/webxr-2/run-impulse.js +135 -0
  158. package/examples/webxr-2/script.js +384 -0
  159. package/examples/webxr-3/components/bs-camera.js +65 -0
  160. package/examples/webxr-3/index.html +134 -0
  161. package/examples/webxr-3/script.js +432 -0
  162. package/package.json +2 -1
  163. package/src/.prettierrc +4 -0
  164. package/src/BS.ts +79 -8
  165. package/src/CameraManager.ts +497 -0
  166. package/src/Device.ts +691 -86
  167. package/src/DeviceInformationManager.ts +19 -10
  168. package/src/DeviceManager.ts +85 -25
  169. package/src/FileTransferManager.ts +145 -20
  170. package/src/InformationManager.ts +40 -15
  171. package/src/MicrophoneManager.ts +599 -0
  172. package/src/TfliteManager.ts +171 -25
  173. package/src/WifiManager.ts +323 -0
  174. package/src/connection/BaseConnectionManager.ts +130 -30
  175. package/src/connection/ClientConnectionManager.ts +34 -10
  176. package/src/connection/bluetooth/BluetoothConnectionManager.ts +8 -2
  177. package/src/connection/bluetooth/NobleConnectionManager.ts +147 -41
  178. package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +99 -34
  179. package/src/connection/bluetooth/bluetoothUUIDs.ts +40 -13
  180. package/src/connection/udp/UDPConnectionManager.ts +356 -0
  181. package/src/connection/websocket/WebSocketConnectionManager.ts +282 -0
  182. package/src/devicePair/DevicePair.ts +95 -25
  183. package/src/devicePair/DevicePairPressureSensorDataManager.ts +27 -7
  184. package/src/scanner/BaseScanner.ts +49 -11
  185. package/src/scanner/NobleScanner.ts +76 -14
  186. package/src/sensor/MotionSensorDataManager.ts +21 -6
  187. package/src/sensor/PressureSensorDataManager.ts +37 -8
  188. package/src/sensor/SensorConfigurationManager.ts +73 -22
  189. package/src/sensor/SensorDataManager.ts +109 -23
  190. package/src/server/BaseClient.ts +150 -36
  191. package/src/server/BaseServer.ts +50 -2
  192. package/src/server/ServerUtils.ts +39 -9
  193. package/src/server/udp/UDPServer.ts +73 -22
  194. package/src/server/udp/UDPUtils.ts +9 -2
  195. package/src/server/websocket/WebSocketClient.ts +27 -7
  196. package/src/server/websocket/WebSocketUtils.ts +4 -2
  197. package/src/utils/AudioUtils.ts +65 -0
  198. package/src/utils/Console.ts +62 -9
  199. package/src/utils/ParseUtils.ts +24 -5
  200. package/src/utils/ThrottleUtils.ts +62 -0
  201. package/src/utils/Timer.ts +1 -1
  202. package/src/vibration/VibrationManager.ts +166 -40
@@ -6,10 +6,17 @@ const _console = createConsole("UDPUtils", { log: false });
6
6
  export const pongUDPClientTimeout = 2_000;
7
7
  export const removeUDPClientTimeout = 3_000;
8
8
 
9
- export const UDPServerMessageTypes = ["ping", "pong", "setRemoteReceivePort", "serverMessage"] as const;
9
+ export const UDPServerMessageTypes = [
10
+ "ping",
11
+ "pong",
12
+ "setRemoteReceivePort",
13
+ "serverMessage",
14
+ ] as const;
10
15
  export type UDPServerMessageType = (typeof UDPServerMessageTypes)[number];
11
16
 
12
- export type UDPServerMessage = UDPServerMessageType | Message<UDPServerMessageType>;
17
+ export type UDPServerMessage =
18
+ | UDPServerMessageType
19
+ | Message<UDPServerMessageType>;
13
20
  export function createUDPServerMessage(...messages: UDPServerMessage[]) {
14
21
  _console.log("createUDPServerMessage", ...messages);
15
22
  return createMessage(UDPServerMessageTypes, ...messages);
@@ -1,6 +1,13 @@
1
1
  import { createConsole } from "../../utils/Console.ts";
2
- import { createServerMessage, MessageLike, ServerMessage } from "../ServerUtils.ts";
3
- import { addEventListeners, removeEventListeners } from "../../utils/EventUtils.ts";
2
+ import {
3
+ createServerMessage,
4
+ MessageLike,
5
+ ServerMessage,
6
+ } from "../ServerUtils.ts";
7
+ import {
8
+ addEventListeners,
9
+ removeEventListeners,
10
+ } from "../../utils/EventUtils.ts";
4
11
  import ClientConnectionManager from "../../connection/ClientConnectionManager.ts";
5
12
  import BaseClient, { ServerURL } from "../BaseClient.ts";
6
13
  import type * as ws from "ws";
@@ -93,10 +100,16 @@ class WebSocketClient extends BaseClient {
93
100
  sendMessage(message: MessageLike) {
94
101
  this.assertConnection();
95
102
  this.#webSocket!.send(message);
103
+ this.#pingTimer.restart();
96
104
  }
97
105
 
98
106
  sendServerMessage(...messages: ServerMessage[]) {
99
- this.sendMessage(createWebSocketMessage({ type: "serverMessage", data: createServerMessage(...messages) }));
107
+ this.sendMessage(
108
+ createWebSocketMessage({
109
+ type: "serverMessage",
110
+ data: createServerMessage(...messages),
111
+ })
112
+ );
100
113
  }
101
114
 
102
115
  #sendWebSocketMessage(...messages: WebSocketMessage[]) {
@@ -119,7 +132,7 @@ class WebSocketClient extends BaseClient {
119
132
  }
120
133
  async #onWebSocketMessage(event: ws.MessageEvent) {
121
134
  _console.log("webSocket.message", event);
122
- this.#pingTimer.restart();
135
+ //this.#pingTimer.restart();
123
136
  //@ts-expect-error
124
137
  const arrayBuffer = await event.data.arrayBuffer();
125
138
  const dataView = new DataView(arrayBuffer);
@@ -131,7 +144,8 @@ class WebSocketClient extends BaseClient {
131
144
  this._connectionStatus = "notConnected";
132
145
 
133
146
  Object.entries(this.devices).forEach(([id, device]) => {
134
- const connectionManager = device.connectionManager! as ClientConnectionManager;
147
+ const connectionManager =
148
+ device.connectionManager! as ClientConnectionManager;
135
149
  connectionManager.isConnected = false;
136
150
  });
137
151
 
@@ -143,12 +157,18 @@ class WebSocketClient extends BaseClient {
143
157
  }
144
158
  }
145
159
  #onWebSocketError(event: ws.ErrorEvent) {
146
- _console.error("webSocket.error", event.message);
160
+ _console.error("webSocket.error", event);
147
161
  }
148
162
 
149
163
  // PARSING
150
164
  #parseWebSocketMessage(dataView: DataView) {
151
- parseMessage(dataView, WebSocketMessageTypes, this.#onServerMessage.bind(this), null, true);
165
+ parseMessage(
166
+ dataView,
167
+ WebSocketMessageTypes,
168
+ this.#onServerMessage.bind(this),
169
+ null,
170
+ true
171
+ );
152
172
  }
153
173
 
154
174
  #onServerMessage(messageType: WebSocketMessageType, dataView: DataView) {
@@ -3,13 +3,15 @@ import { createMessage, Message } from "../ServerUtils.ts";
3
3
 
4
4
  const _console = createConsole("WebSocketUtils", { log: false });
5
5
 
6
- export const webSocketPingTimeout = 30_000_000;
6
+ export const webSocketPingTimeout = 30_000;
7
7
  export const webSocketReconnectTimeout = 3_000;
8
8
 
9
9
  export const WebSocketMessageTypes = ["ping", "pong", "serverMessage"] as const;
10
10
  export type WebSocketMessageType = (typeof WebSocketMessageTypes)[number];
11
11
 
12
- export type WebSocketMessage = WebSocketMessageType | Message<WebSocketMessageType>;
12
+ export type WebSocketMessage =
13
+ | WebSocketMessageType
14
+ | Message<WebSocketMessageType>;
13
15
  export function createWebSocketMessage(...messages: WebSocketMessage[]) {
14
16
  _console.log("createWebSocketMessage", ...messages);
15
17
  return createMessage(WebSocketMessageTypes, ...messages);
@@ -0,0 +1,65 @@
1
+ import { createConsole } from "./Console.ts";
2
+
3
+ const _console = createConsole("AudioUtils", { log: true });
4
+
5
+ export function float32ArrayToWav(
6
+ audioData: Float32Array,
7
+ sampleRate: number,
8
+ numChannels: number
9
+ ): Blob {
10
+ const wavBuffer = encodeWAV(audioData, sampleRate, numChannels);
11
+ return new Blob([wavBuffer], { type: "audio/wav" });
12
+ }
13
+
14
+ function encodeWAV(
15
+ interleaved: Float32Array,
16
+ sampleRate: number,
17
+ numChannels: number
18
+ ): ArrayBuffer {
19
+ const buffer = new ArrayBuffer(44 + interleaved.length * 2); // 44 bytes for WAV header
20
+ const view = new DataView(buffer);
21
+
22
+ // RIFF identifier
23
+ writeString(view, 0, "RIFF");
24
+ // File length minus RIFF identifier length and file description length
25
+ view.setUint32(4, 36 + interleaved.length * 2, true);
26
+ // RIFF type
27
+ writeString(view, 8, "WAVE");
28
+ // Format chunk identifier
29
+ writeString(view, 12, "fmt ");
30
+ // Format chunk length
31
+ view.setUint32(16, 16, true);
32
+ // Sample format (raw)
33
+ view.setUint16(20, 1, true);
34
+ // Channel count
35
+ view.setUint16(22, numChannels, true);
36
+ // Sample rate
37
+ view.setUint32(24, sampleRate, true);
38
+ // Byte rate (sample rate * block align)
39
+ view.setUint32(28, sampleRate * numChannels * 2, true);
40
+ // Block align (channel count * bytes per sample)
41
+ view.setUint16(32, numChannels * 2, true);
42
+ // Bits per sample
43
+ view.setUint16(34, 16, true);
44
+ // Data chunk identifier
45
+ writeString(view, 36, "data");
46
+ // Data chunk length
47
+ view.setUint32(40, interleaved.length * 2, true);
48
+
49
+ // Write interleaved audio data
50
+ for (let i = 0; i < interleaved.length; i++) {
51
+ view.setInt16(44 + i * 2, interleaved[i] * 0x7fff, true); // Convert float [-1, 1] to int16
52
+ }
53
+
54
+ return buffer;
55
+ }
56
+
57
+ export function writeString(
58
+ view: DataView,
59
+ offset: number,
60
+ string: string
61
+ ): void {
62
+ for (let i = 0; i < string.length; i++) {
63
+ view.setUint8(offset + i, string.charCodeAt(i));
64
+ }
65
+ }
@@ -1,4 +1,4 @@
1
- import { isInDev, isInLensStudio } from "./environment.ts";
1
+ import { isInDev, isInLensStudio, isInNode } from "./environment.ts";
2
2
 
3
3
  declare var Studio: any | undefined;
4
4
 
@@ -34,6 +34,31 @@ if (isInLensStudio) {
34
34
  __console = console;
35
35
  }
36
36
 
37
+ function getCallerFunctionPath(): string {
38
+ const stack = new Error().stack;
39
+ if (!stack) return "";
40
+
41
+ const lines = stack.split("\n");
42
+ const callerLine = lines[3] || lines[2];
43
+
44
+ const match = callerLine.match(/at (.*?) \(/) || callerLine.match(/at (.*)/);
45
+ if (!match) return "";
46
+
47
+ const fullFn = match[1].trim();
48
+ return `[${fullFn}]`;
49
+ }
50
+
51
+ function wrapWithLocation(fn: LogFunction): LogFunction {
52
+ return (...args: any[]) => {
53
+ if (isInNode) {
54
+ const functionPath = getCallerFunctionPath();
55
+ fn(functionPath, ...args);
56
+ } else {
57
+ fn(...args);
58
+ }
59
+ };
60
+ }
61
+
37
62
  // console.assert not supported in WebBLE
38
63
  if (!__console.assert) {
39
64
  const assert: AssertLogFunction = (condition, ...data) => {
@@ -54,10 +79,18 @@ if (!__console.table) {
54
79
 
55
80
  function emptyFunction() {}
56
81
 
57
- const log: LogFunction = __console.log!.bind(__console);
58
- const warn: LogFunction = __console.warn!.bind(__console);
59
- const error: LogFunction = __console.error!.bind(__console);
60
- const table: LogFunction = __console.table!.bind(__console);
82
+ const log: LogFunction = isInNode
83
+ ? wrapWithLocation(__console.log!.bind(__console))
84
+ : __console.log!.bind(__console);
85
+ const warn: LogFunction = isInNode
86
+ ? wrapWithLocation(__console.warn!.bind(__console))
87
+ : __console.warn!.bind(__console);
88
+ const error: LogFunction = isInNode
89
+ ? wrapWithLocation(__console.error!.bind(__console))
90
+ : __console.error!.bind(__console);
91
+ const table: LogFunction = isInNode
92
+ ? wrapWithLocation(__console.table!.bind(__console))
93
+ : __console.table!.bind(__console);
61
94
  const assert: AssertLogFunction = __console.assert.bind(__console);
62
95
 
63
96
  class Console {
@@ -133,21 +166,41 @@ class Console {
133
166
 
134
167
  /** @throws {Error} if value's type doesn't match */
135
168
  assertTypeWithError(value: any, type: string) {
136
- this.assertWithError(typeof value == type, `value ${value} of type "${typeof value}" not of type "${type}"`);
169
+ this.assertWithError(
170
+ typeof value == type,
171
+ `value ${value} of type "${typeof value}" not of type "${type}"`
172
+ );
137
173
  }
138
174
 
139
175
  /** @throws {Error} if value's type doesn't match */
140
176
  assertEnumWithError(value: string, enumeration: readonly string[]) {
141
- this.assertWithError(enumeration.includes(value), `invalid enum "${value}"`);
177
+ this.assertWithError(
178
+ enumeration.includes(value),
179
+ `invalid enum "${value}"`
180
+ );
181
+ }
182
+
183
+ /** @throws {Error} if value is not within some range */
184
+ assertRangeWithError(name: string, value: number, min: number, max: number) {
185
+ this.assertWithError(
186
+ value >= min && value <= max,
187
+ `${name} ${value} must be within ${min}-${max}`
188
+ );
142
189
  }
143
190
  }
144
191
 
145
- export function createConsole(type: string, levelFlags?: ConsoleLevelFlags): Console {
192
+ export function createConsole(
193
+ type: string,
194
+ levelFlags?: ConsoleLevelFlags
195
+ ): Console {
146
196
  return Console.create(type, levelFlags);
147
197
  }
148
198
 
149
199
  /** @throws {Error} if no console with type is found */
150
- export function setConsoleLevelFlagsForType(type: string, levelFlags: ConsoleLevelFlags) {
200
+ export function setConsoleLevelFlagsForType(
201
+ type: string,
202
+ levelFlags: ConsoleLevelFlags
203
+ ) {
151
204
  Console.setLevelFlagsForType(type, levelFlags);
152
205
  }
153
206
 
@@ -4,10 +4,16 @@ import { textDecoder } from "./Text.ts";
4
4
 
5
5
  const _console = createConsole("ParseUtils", { log: false });
6
6
 
7
- export function parseStringFromDataView(dataView: DataView, byteOffset: number = 0) {
7
+ export function parseStringFromDataView(
8
+ dataView: DataView,
9
+ byteOffset: number = 0
10
+ ) {
8
11
  const stringLength = dataView.getUint8(byteOffset++);
9
12
  const string = textDecoder.decode(
10
- dataView.buffer.slice(dataView.byteOffset + byteOffset, dataView.byteOffset + byteOffset + stringLength)
13
+ dataView.buffer.slice(
14
+ dataView.byteOffset + byteOffset,
15
+ dataView.byteOffset + byteOffset + stringLength
16
+ )
11
17
  );
12
18
  byteOffset += stringLength;
13
19
  return { string, byteOffset };
@@ -16,14 +22,21 @@ export function parseStringFromDataView(dataView: DataView, byteOffset: number =
16
22
  export function parseMessage<MessageType extends string>(
17
23
  dataView: DataView,
18
24
  messageTypes: readonly MessageType[],
19
- callback: (messageType: MessageType, dataView: DataView, context?: any) => void,
25
+ callback: (
26
+ messageType: MessageType,
27
+ dataView: DataView,
28
+ context?: any
29
+ ) => void,
20
30
  context?: any,
21
31
  parseMessageLengthAsUint16: boolean = false
22
32
  ) {
23
33
  let byteOffset = 0;
24
34
  while (byteOffset < dataView.byteLength) {
25
35
  const messageTypeEnum = dataView.getUint8(byteOffset++);
26
- _console.assertWithError(messageTypeEnum in messageTypes, `invalid messageTypeEnum ${messageTypeEnum}`);
36
+ _console.assertWithError(
37
+ messageTypeEnum in messageTypes,
38
+ `invalid messageTypeEnum ${messageTypeEnum}`
39
+ );
27
40
  const messageType = messageTypes[messageTypeEnum];
28
41
 
29
42
  let messageLength: number;
@@ -34,7 +47,13 @@ export function parseMessage<MessageType extends string>(
34
47
  messageLength = dataView.getUint8(byteOffset++);
35
48
  }
36
49
 
37
- _console.log({ messageTypeEnum, messageType, messageLength, dataView, byteOffset });
50
+ _console.log({
51
+ messageTypeEnum,
52
+ messageType,
53
+ messageLength,
54
+ dataView,
55
+ byteOffset,
56
+ });
38
57
 
39
58
  const _dataView = sliceDataView(dataView, byteOffset, messageLength);
40
59
  _console.log({ _dataView });
@@ -0,0 +1,62 @@
1
+ export function throttle<T extends (...args: any[]) => void>(
2
+ fn: T,
3
+ interval: number,
4
+ trailing = false
5
+ ): (...args: Parameters<T>) => void {
6
+ let lastTime = 0;
7
+ let timeout: ReturnType<typeof setTimeout> | null = null;
8
+ let lastArgs: Parameters<T> | null = null;
9
+
10
+ return function (...args: Parameters<T>) {
11
+ const now = Date.now();
12
+ const remaining = interval - (now - lastTime);
13
+
14
+ if (remaining <= 0) {
15
+ if (timeout) {
16
+ clearTimeout(timeout);
17
+ timeout = null;
18
+ }
19
+ lastTime = now;
20
+ fn(...args);
21
+ } else if (trailing) {
22
+ lastArgs = args;
23
+ if (!timeout) {
24
+ timeout = setTimeout(() => {
25
+ lastTime = Date.now();
26
+ timeout = null;
27
+ if (lastArgs) {
28
+ fn(...lastArgs);
29
+ lastArgs = null;
30
+ }
31
+ }, remaining);
32
+ }
33
+ }
34
+ };
35
+ }
36
+
37
+ export function debounce<T extends (...args: any[]) => void>(
38
+ fn: T,
39
+ interval: number,
40
+ callImmediately = false
41
+ ): (...args: Parameters<T>) => void {
42
+ let timeout: ReturnType<typeof setTimeout> | null = null;
43
+
44
+ return function (...args: Parameters<T>) {
45
+ const callNow = callImmediately && !timeout;
46
+
47
+ if (timeout) {
48
+ clearTimeout(timeout);
49
+ }
50
+
51
+ timeout = setTimeout(() => {
52
+ timeout = null;
53
+ if (!callImmediately) {
54
+ fn(...args);
55
+ }
56
+ }, interval);
57
+
58
+ if (callNow) {
59
+ fn(...args);
60
+ }
61
+ };
62
+ }
@@ -52,7 +52,7 @@ class Timer {
52
52
  _console.log("interval already running");
53
53
  return;
54
54
  }
55
- _console.log("starting interval");
55
+ _console.log(`starting interval every ${this.#interval}ms`);
56
56
  this.#intervalId = setInterval(this.#callback, this.#interval);
57
57
  if (immediately) {
58
58
  this.#callback();