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.
- package/assets/3d/anchor.glb +0 -0
- package/assets/3d/coin.glb +0 -0
- package/assets/3d/glasses.glb +0 -0
- package/assets/audio/bounceMedium.wav +0 -0
- package/assets/audio/bounceStrong.wav +0 -0
- package/assets/audio/bounceWeak.wav +0 -0
- package/assets/audio/coin.wav +0 -0
- package/assets/audio/getUp.wav +0 -0
- package/assets/audio/grab.wav +0 -0
- package/assets/audio/kick.wav +0 -0
- package/assets/audio/platterFadeIn old.wav +0 -0
- package/assets/audio/platterFadeIn.wav +0 -0
- package/assets/audio/platterFadeOut.wav +0 -0
- package/assets/audio/punch.wav +0 -0
- package/assets/audio/punchSqueak.wav +0 -0
- package/assets/audio/purr.wav +0 -0
- package/assets/audio/purrFadeOut.wav +0 -0
- package/assets/audio/release.wav +0 -0
- package/assets/audio/splat.wav +0 -0
- package/assets/audio/stomp.wav +0 -0
- package/build/brilliantsole.cjs +3091 -741
- package/build/brilliantsole.cjs.map +1 -1
- package/build/brilliantsole.js +2759 -709
- package/build/brilliantsole.js.map +1 -1
- package/build/brilliantsole.ls.js +2602 -543
- package/build/brilliantsole.ls.js.map +1 -1
- package/build/brilliantsole.min.js +1 -1
- package/build/brilliantsole.min.js.map +1 -1
- package/build/brilliantsole.module.d.ts +295 -65
- package/build/brilliantsole.module.js +2749 -710
- package/build/brilliantsole.module.js.map +1 -1
- package/build/brilliantsole.module.min.d.ts +295 -65
- package/build/brilliantsole.module.min.js +1 -1
- package/build/brilliantsole.module.min.js.map +1 -1
- package/build/brilliantsole.node.module.d.ts +289 -62
- package/build/brilliantsole.node.module.js +3080 -742
- package/build/brilliantsole.node.module.js.map +1 -1
- package/build/dts/BS-output.d.ts +10 -0
- package/build/dts/BS.d.ts +21 -8
- package/build/dts/CameraManager.d.ts +72 -0
- package/build/dts/Device.d.ts +64 -13
- package/build/dts/DeviceInformationManager.d.ts +4 -4
- package/build/dts/DeviceManager.d.ts +2 -0
- package/build/dts/FileTransferManager.d.ts +18 -8
- package/build/dts/InformationManager.d.ts +2 -0
- package/build/dts/MicrophoneManager.d.ts +88 -0
- package/build/dts/TfliteManager.d.ts +22 -2
- package/build/dts/WifiManager.d.ts +61 -0
- package/build/dts/connection/BaseConnectionManager.d.ts +35 -3
- package/build/dts/connection/ClientConnectionManager.d.ts +7 -2
- package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +2 -1
- package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +1 -0
- package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +2 -2
- package/build/dts/connection/udp/UDPConnectionManager.d.ts +28 -0
- package/build/dts/connection/webSocket/WebSocketConnectionManager.d.ts +25 -0
- package/build/dts/devicePair/DevicePair.d.ts +5 -5
- package/build/dts/scanner/BaseScanner.d.ts +4 -1
- package/build/dts/scanner/NobleScanner.d.ts +2 -1
- package/build/dts/sensor/MotionSensorDataManager.d.ts +5 -2
- package/build/dts/sensor/SensorDataManager.d.ts +5 -4
- package/build/dts/server/BaseClient.d.ts +5 -3
- package/build/dts/server/ServerUtils.d.ts +1 -1
- package/build/dts/server/websocket/WebSocketUtils.d.ts +1 -1
- package/build/dts/utils/AudioUtils.d.ts +2 -0
- package/build/dts/utils/Console.d.ts +2 -0
- package/build/dts/utils/ThrottleUtils.d.ts +2 -0
- package/build/dts/vibration/VibrationManager.d.ts +19 -2
- package/build/index.d.ts +292 -62
- package/build/index.node.d.ts +286 -59
- package/examples/3d/scene.html +19 -5
- package/examples/3d-generic/index.html +144 -0
- package/examples/3d-generic/script.js +266 -0
- package/examples/basic/index.html +267 -17
- package/examples/basic/script.js +958 -105
- package/examples/camera/barcode-detector.js +109 -0
- package/examples/camera/depth-estimation.js +71 -0
- package/examples/camera/face-detector.js +119 -0
- package/examples/camera/face-landmark.js +111 -0
- package/examples/camera/gesture-recognition.js +97 -0
- package/examples/camera/hand-landmark.js +74 -0
- package/examples/camera/image-segmentation.js +98 -0
- package/examples/camera/image-to-text.js +43 -0
- package/examples/camera/image-upscale.js +75 -0
- package/examples/camera/index.html +129 -0
- package/examples/camera/object-detection.js +98 -0
- package/examples/camera/pose-landmark.js +60 -0
- package/examples/camera/script.js +316 -0
- package/examples/camera/utils.js +165 -0
- package/examples/camera/yolo-tiny.js +54 -0
- package/examples/camera/yolo.js +119 -0
- package/examples/edge-impulse/script.js +157 -48
- package/examples/edge-impulse-test/README.md +11 -0
- package/examples/edge-impulse-test/edge-impulse-standalone.js +7228 -0
- package/examples/edge-impulse-test/edge-impulse-standalone.wasm +0 -0
- package/examples/edge-impulse-test/index.html +75 -0
- package/examples/edge-impulse-test/run-impulse.js +135 -0
- package/examples/edge-impulse-test/script.js +200 -0
- package/examples/glasses-gestures/README.md +11 -0
- package/examples/glasses-gestures/edge-impulse-standalone.js +7228 -0
- package/examples/glasses-gestures/edge-impulse-standalone.wasm +0 -0
- package/examples/glasses-gestures/index.html +69 -0
- package/examples/glasses-gestures/run-impulse.js +135 -0
- package/examples/glasses-gestures/script.js +226 -0
- package/examples/gloves/edge-impulse-standalone.js +7228 -0
- package/examples/gloves/edge-impulse-standalone.wasm +0 -0
- package/examples/gloves/index.html +4 -1
- package/examples/gloves/run-impulse.js +135 -0
- package/examples/gloves/script.js +367 -51
- package/examples/graph/script.js +94 -37
- package/examples/microphone/gender.js +54 -0
- package/examples/microphone/index.html +102 -0
- package/examples/microphone/script.js +394 -0
- package/examples/microphone/utils.js +45 -0
- package/examples/microphone/whisper-realtime.js +166 -0
- package/examples/microphone/whisper.js +132 -0
- package/examples/punch/index.html +135 -0
- package/examples/punch/punch.tflite +0 -0
- package/examples/punch/script.js +169 -0
- package/examples/server/index.html +98 -22
- package/examples/server/script.js +317 -109
- package/examples/ukaton-firmware-update/merged-firmware.bin +0 -0
- package/examples/utils/aframe/aframe-master.min.js +2 -0
- package/examples/utils/aframe/bs-vibration.js +150 -0
- package/examples/utils/aframe/force-pushable.js +80 -0
- package/examples/utils/aframe/grabbable-anchor.js +46 -0
- package/examples/utils/aframe/grabbable-listener.js +31 -0
- package/examples/utils/aframe/grabbable-physics-body.js +190 -0
- package/examples/utils/aframe/grow-shrink.js +25 -0
- package/examples/utils/aframe/hand-punch.js +119 -0
- package/examples/utils/aframe/my-obb-collider.js +293 -0
- package/examples/utils/aframe/occlude-hand-tracking-controls.js +47 -0
- package/examples/utils/aframe/occlude-mesh.js +42 -0
- package/examples/utils/aframe/palm-up-detector.js +47 -0
- package/examples/utils/aframe/shadow-material.js +20 -0
- package/examples/utils/aframe/soft-shadow-light.js +9 -0
- package/examples/webxr-2/assets/3d/soccerBall.glb +0 -0
- package/examples/webxr-2/assets/audio/shellBounce.wav +0 -0
- package/examples/webxr-2/assets/audio/shellHit.wav +0 -0
- package/examples/webxr-2/assets/audio/shellKick.wav +0 -0
- package/examples/webxr-2/assets/audio/soccerBounce.wav +0 -0
- package/examples/webxr-2/assets/audio/soccerKick.mp3 +0 -0
- package/examples/webxr-2/assets/images/shellTexture.png +0 -0
- package/examples/webxr-2/components/bs-ankle.js +337 -0
- package/examples/webxr-2/components/coin.js +84 -0
- package/examples/webxr-2/components/custom-wrap.js +17 -0
- package/examples/webxr-2/components/goomba.js +3250 -0
- package/examples/webxr-2/components/init-shell-material.js +215 -0
- package/examples/webxr-2/components/platter.js +172 -0
- package/examples/webxr-2/components/shell.js +374 -0
- package/examples/webxr-2/components/soccer-ball.js +250 -0
- package/examples/webxr-2/components/squashed-goomba.js +249 -0
- package/examples/webxr-2/edge-impulse-standalone.js +7228 -0
- package/examples/webxr-2/edge-impulse-standalone.wasm +0 -0
- package/examples/webxr-2/index.html +996 -0
- package/examples/webxr-2/kick.tflite +0 -0
- package/examples/webxr-2/kick2.tflite +0 -0
- package/examples/webxr-2/run-impulse.js +135 -0
- package/examples/webxr-2/script.js +384 -0
- package/examples/webxr-3/components/bs-camera.js +65 -0
- package/examples/webxr-3/index.html +134 -0
- package/examples/webxr-3/script.js +432 -0
- package/package.json +2 -1
- package/src/.prettierrc +4 -0
- package/src/BS.ts +79 -8
- package/src/CameraManager.ts +497 -0
- package/src/Device.ts +691 -86
- package/src/DeviceInformationManager.ts +19 -10
- package/src/DeviceManager.ts +85 -25
- package/src/FileTransferManager.ts +145 -20
- package/src/InformationManager.ts +40 -15
- package/src/MicrophoneManager.ts +599 -0
- package/src/TfliteManager.ts +171 -25
- package/src/WifiManager.ts +323 -0
- package/src/connection/BaseConnectionManager.ts +130 -30
- package/src/connection/ClientConnectionManager.ts +34 -10
- package/src/connection/bluetooth/BluetoothConnectionManager.ts +8 -2
- package/src/connection/bluetooth/NobleConnectionManager.ts +147 -41
- package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +99 -34
- package/src/connection/bluetooth/bluetoothUUIDs.ts +40 -13
- package/src/connection/udp/UDPConnectionManager.ts +356 -0
- package/src/connection/websocket/WebSocketConnectionManager.ts +282 -0
- package/src/devicePair/DevicePair.ts +95 -25
- package/src/devicePair/DevicePairPressureSensorDataManager.ts +27 -7
- package/src/scanner/BaseScanner.ts +49 -11
- package/src/scanner/NobleScanner.ts +76 -14
- package/src/sensor/MotionSensorDataManager.ts +21 -6
- package/src/sensor/PressureSensorDataManager.ts +37 -8
- package/src/sensor/SensorConfigurationManager.ts +73 -22
- package/src/sensor/SensorDataManager.ts +109 -23
- package/src/server/BaseClient.ts +150 -36
- package/src/server/BaseServer.ts +50 -2
- package/src/server/ServerUtils.ts +39 -9
- package/src/server/udp/UDPServer.ts +73 -22
- package/src/server/udp/UDPUtils.ts +9 -2
- package/src/server/websocket/WebSocketClient.ts +27 -7
- package/src/server/websocket/WebSocketUtils.ts +4 -2
- package/src/utils/AudioUtils.ts +65 -0
- package/src/utils/Console.ts +62 -9
- package/src/utils/ParseUtils.ts +24 -5
- package/src/utils/ThrottleUtils.ts +62 -0
- package/src/utils/Timer.ts +1 -1
- 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 = [
|
|
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 =
|
|
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 {
|
|
3
|
-
|
|
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(
|
|
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 =
|
|
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
|
|
160
|
+
_console.error("webSocket.error", event);
|
|
147
161
|
}
|
|
148
162
|
|
|
149
163
|
// PARSING
|
|
150
164
|
#parseWebSocketMessage(dataView: DataView) {
|
|
151
|
-
parseMessage(
|
|
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 =
|
|
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 =
|
|
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
|
+
}
|
package/src/utils/Console.ts
CHANGED
|
@@ -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 =
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
200
|
+
export function setConsoleLevelFlagsForType(
|
|
201
|
+
type: string,
|
|
202
|
+
levelFlags: ConsoleLevelFlags
|
|
203
|
+
) {
|
|
151
204
|
Console.setLevelFlagsForType(type, levelFlags);
|
|
152
205
|
}
|
|
153
206
|
|
package/src/utils/ParseUtils.ts
CHANGED
|
@@ -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(
|
|
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(
|
|
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: (
|
|
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(
|
|
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({
|
|
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
|
+
}
|
package/src/utils/Timer.ts
CHANGED
|
@@ -52,7 +52,7 @@ class Timer {
|
|
|
52
52
|
_console.log("interval already running");
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
-
_console.log(
|
|
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();
|