brilliantsole 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +21 -0
- package/build/brilliantsole.cjs +5957 -0
- package/build/brilliantsole.cjs.map +1 -0
- package/build/brilliantsole.js +5448 -0
- package/build/brilliantsole.js.map +1 -0
- package/build/brilliantsole.ls.js +4872 -0
- package/build/brilliantsole.ls.js.map +1 -0
- package/build/brilliantsole.min.js +6 -0
- package/build/brilliantsole.min.js.map +1 -0
- package/build/brilliantsole.module.d.ts +908 -0
- package/build/brilliantsole.module.js +5412 -0
- package/build/brilliantsole.module.js.map +1 -0
- package/build/brilliantsole.module.min.d.ts +908 -0
- package/build/brilliantsole.module.min.js +6 -0
- package/build/brilliantsole.module.min.js.map +1 -0
- package/build/brilliantsole.node.module.d.ts +908 -0
- package/build/brilliantsole.node.module.js +5906 -0
- package/build/brilliantsole.node.module.js.map +1 -0
- package/build/dts/BS.d.ts +25 -0
- package/build/dts/Device.d.ts +136 -0
- package/build/dts/DeviceInformationManager.d.ts +56 -0
- package/build/dts/DeviceManager.d.ts +67 -0
- package/build/dts/FileTransferManager.d.ts +84 -0
- package/build/dts/FirmwareManager.d.ts +71 -0
- package/build/dts/InformationManager.d.ts +66 -0
- package/build/dts/TfliteManager.d.ts +92 -0
- package/build/dts/connection/BaseConnectionManager.d.ts +59 -0
- package/build/dts/connection/ClientConnectionManager.d.ts +23 -0
- package/build/dts/connection/WebSocketClientConnectionManager.d.ts +23 -0
- package/build/dts/connection/bluetooth/BluetoothConnectionManager.d.ts +10 -0
- package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +42 -0
- package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +20 -0
- package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +14 -0
- package/build/dts/connection/webSocket/ClientConnectionManager.d.ts +23 -0
- package/build/dts/connection/webSocket/WebSocketClientConnectionManager.d.ts +23 -0
- package/build/dts/devicePair/DevicePair.d.ts +60 -0
- package/build/dts/devicePair/DevicePairPressureSensorDataManager.d.ts +25 -0
- package/build/dts/devicePair/DevicePairSensorDataManager.d.ts +33 -0
- package/build/dts/scanner/BaseScanner.d.ts +66 -0
- package/build/dts/scanner/NobleScanner.d.ts +17 -0
- package/build/dts/scanner/Scanner.d.ts +3 -0
- package/build/dts/sensor/BarometerSensorDataManager.d.ts +16 -0
- package/build/dts/sensor/MotionSensorDataManager.d.ts +69 -0
- package/build/dts/sensor/PressureSensorDataManager.d.ts +36 -0
- package/build/dts/sensor/SensorConfigurationManager.d.ts +44 -0
- package/build/dts/sensor/SensorDataManager.d.ts +40 -0
- package/build/dts/server/BaseClient.d.ts +85 -0
- package/build/dts/server/BaseServer.d.ts +48 -0
- package/build/dts/server/ServerUtils.d.ts +23 -0
- package/build/dts/server/udp/UDPServer.d.ts +11 -0
- package/build/dts/server/udp/UDPUtils.d.ts +9 -0
- package/build/dts/server/websocket/WebSocketClient.d.ts +17 -0
- package/build/dts/server/websocket/WebSocketServer.d.ts +13 -0
- package/build/dts/server/websocket/WebSocketUtils.d.ts +9 -0
- package/build/dts/utils/ArrayBufferUtils.d.ts +7 -0
- package/build/dts/utils/ArrayUtils.d.ts +2 -0
- package/build/dts/utils/CenterOfPressureHelper.d.ts +15 -0
- package/build/dts/utils/Console.d.ts +34 -0
- package/build/dts/utils/EventDispatcher.d.ts +50 -0
- package/build/dts/utils/EventUtils.d.ts +6 -0
- package/build/dts/utils/MathUtils.d.ts +21 -0
- package/build/dts/utils/ParseUtils.d.ts +5 -0
- package/build/dts/utils/RangeHelper.d.ts +8 -0
- package/build/dts/utils/Text.d.ts +6 -0
- package/build/dts/utils/Timer.d.ts +14 -0
- package/build/dts/utils/TypeScriptUtils.d.ts +19 -0
- package/build/dts/utils/cbor.d.ts +6 -0
- package/build/dts/utils/checksum.d.ts +3 -0
- package/build/dts/utils/environment.d.ts +13 -0
- package/build/dts/utils/mcumgr.d.ts +88 -0
- package/build/dts/utils/stringUtils.d.ts +2 -0
- package/build/dts/vibration/VibrationManager.d.ts +45 -0
- package/build/dts/vibration/VibrationWaveformEffects.d.ts +2 -0
- package/build/index.d.ts +908 -0
- package/build/index.node.d.ts +908 -0
- package/examples/3d/index.html +109 -0
- package/examples/3d/scene.html +57 -0
- package/examples/3d/script.js +419 -0
- package/examples/balance/index.html +138 -0
- package/examples/balance/script.js +243 -0
- package/examples/basic/index.html +327 -0
- package/examples/basic/script.js +1093 -0
- package/examples/center-of-pressure/index.html +132 -0
- package/examples/center-of-pressure/script.js +207 -0
- package/examples/device-pair/index.html +72 -0
- package/examples/device-pair/script.js +187 -0
- package/examples/edge-impulse/index.html +94 -0
- package/examples/edge-impulse/script.js +1033 -0
- package/examples/graph/index.html +83 -0
- package/examples/graph/script.js +469 -0
- package/examples/machine-learning/index.html +366 -0
- package/examples/machine-learning/script.js +1774 -0
- package/examples/pressure/index.html +145 -0
- package/examples/pressure/script.js +201 -0
- package/examples/recording/index.html +187 -0
- package/examples/recording/script.js +736 -0
- package/examples/server/index.html +266 -0
- package/examples/server/script.js +925 -0
- package/examples/utils/aframe/fingertip-button-component.js +201 -0
- package/examples/utils/aframe/fingertip-collider-target-component.js +102 -0
- package/examples/utils/aframe/fingertip-colliders-component.js +147 -0
- package/examples/utils/three/three.module.min.js +24846 -0
- package/examples/webxr/index.html +221 -0
- package/examples/webxr/script.js +1127 -0
- package/package.json +83 -0
- package/src/BS.ts +68 -0
- package/src/Device.ts +734 -0
- package/src/DeviceInformationManager.ts +146 -0
- package/src/DeviceManager.ts +354 -0
- package/src/FileTransferManager.ts +452 -0
- package/src/FirmwareManager.ts +357 -0
- package/src/InformationManager.ts +283 -0
- package/src/TfliteManager.ts +450 -0
- package/src/connection/BaseConnectionManager.ts +255 -0
- package/src/connection/ClientConnectionManager.ts +120 -0
- package/src/connection/bluetooth/BluetoothConnectionManager.ts +34 -0
- package/src/connection/bluetooth/NobleConnectionManager.ts +302 -0
- package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +269 -0
- package/src/connection/bluetooth/bluetoothUUIDs.ts +218 -0
- package/src/devicePair/DevicePair.ts +253 -0
- package/src/devicePair/DevicePairPressureSensorDataManager.ts +82 -0
- package/src/devicePair/DevicePairSensorDataManager.ts +90 -0
- package/src/scanner/BaseScanner.ts +189 -0
- package/src/scanner/NobleScanner.ts +195 -0
- package/src/scanner/Scanner.ts +16 -0
- package/src/sensor/BarometerSensorDataManager.ts +41 -0
- package/src/sensor/MotionSensorDataManager.ts +151 -0
- package/src/sensor/PressureSensorDataManager.ts +112 -0
- package/src/sensor/SensorConfigurationManager.ts +177 -0
- package/src/sensor/SensorDataManager.ts +166 -0
- package/src/server/BaseClient.ts +368 -0
- package/src/server/BaseServer.ts +344 -0
- package/src/server/ServerUtils.ts +93 -0
- package/src/server/udp/UDPServer.ts +229 -0
- package/src/server/udp/UDPUtils.ts +20 -0
- package/src/server/websocket/WebSocketClient.ts +179 -0
- package/src/server/websocket/WebSocketServer.ts +184 -0
- package/src/server/websocket/WebSocketUtils.ts +20 -0
- package/src/utils/ArrayBufferUtils.ts +88 -0
- package/src/utils/ArrayUtils.ts +15 -0
- package/src/utils/CenterOfPressureHelper.ts +39 -0
- package/src/utils/Console.ts +156 -0
- package/src/utils/EventDispatcher.ts +153 -0
- package/src/utils/EventUtils.ts +41 -0
- package/src/utils/MathUtils.ts +53 -0
- package/src/utils/ParseUtils.ts +46 -0
- package/src/utils/RangeHelper.ts +38 -0
- package/src/utils/Text.ts +30 -0
- package/src/utils/Timer.ts +72 -0
- package/src/utils/TypeScriptUtils.ts +22 -0
- package/src/utils/cbor.js +429 -0
- package/src/utils/checksum.ts +41 -0
- package/src/utils/environment.ts +46 -0
- package/src/utils/mcumgr.js +444 -0
- package/src/utils/stringUtils.ts +11 -0
- package/src/vibration/VibrationManager.ts +308 -0
- package/src/vibration/VibrationWaveformEffects.ts +128 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { createConsole } from "./Console.ts";
|
|
2
|
+
|
|
3
|
+
const _console = createConsole("EventDispatcher", { log: false });
|
|
4
|
+
|
|
5
|
+
export type EventMap<
|
|
6
|
+
Target extends any,
|
|
7
|
+
EventType extends string,
|
|
8
|
+
EventMessages extends Partial<Record<EventType, any>>
|
|
9
|
+
> = {
|
|
10
|
+
[T in keyof EventMessages]: { type: T; target: Target; message: EventMessages[T] };
|
|
11
|
+
};
|
|
12
|
+
export type EventListenerMap<
|
|
13
|
+
Target extends any,
|
|
14
|
+
EventType extends string,
|
|
15
|
+
EventMessages extends Partial<Record<EventType, any>>
|
|
16
|
+
> = {
|
|
17
|
+
[T in keyof EventMessages]: (event: { type: T; target: Target; message: EventMessages[T] }) => void;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type Event<
|
|
21
|
+
Target extends any,
|
|
22
|
+
EventType extends string,
|
|
23
|
+
EventMessages extends Partial<Record<EventType, any>>
|
|
24
|
+
> = EventMap<Target, EventType, EventMessages>[keyof EventMessages];
|
|
25
|
+
|
|
26
|
+
type SpecificEvent<
|
|
27
|
+
Target extends any,
|
|
28
|
+
EventType extends string,
|
|
29
|
+
EventMessages extends Partial<Record<EventType, any>>,
|
|
30
|
+
SpecificEventType extends EventType
|
|
31
|
+
> = { type: SpecificEventType; target: Target; message: EventMessages[SpecificEventType] };
|
|
32
|
+
|
|
33
|
+
export type BoundEventListeners<
|
|
34
|
+
Target extends any,
|
|
35
|
+
EventType extends string,
|
|
36
|
+
EventMessages extends Partial<Record<EventType, any>>
|
|
37
|
+
> = {
|
|
38
|
+
[SpecificEventType in keyof EventMessages]?: (
|
|
39
|
+
// @ts-expect-error
|
|
40
|
+
event: SpecificEvent<Target, EventType, EventMessages, SpecificEventType>
|
|
41
|
+
) => void;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
class EventDispatcher<
|
|
45
|
+
Target extends any,
|
|
46
|
+
EventType extends string,
|
|
47
|
+
EventMessages extends Partial<Record<EventType, any>>
|
|
48
|
+
> {
|
|
49
|
+
private listeners: {
|
|
50
|
+
[T in EventType]?: {
|
|
51
|
+
listener: (event: { type: T; target: Target; message: EventMessages[T] }) => void;
|
|
52
|
+
once?: boolean;
|
|
53
|
+
shouldRemove?: boolean;
|
|
54
|
+
}[];
|
|
55
|
+
} = {};
|
|
56
|
+
|
|
57
|
+
constructor(private target: Target, private validEventTypes: readonly EventType[]) {
|
|
58
|
+
this.addEventListener = this.addEventListener.bind(this);
|
|
59
|
+
this.removeEventListener = this.removeEventListener.bind(this);
|
|
60
|
+
this.dispatchEvent = this.dispatchEvent.bind(this);
|
|
61
|
+
this.waitForEvent = this.waitForEvent.bind(this);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private isValidEventType(type: any): type is EventType {
|
|
65
|
+
return this.validEventTypes.includes(type);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private updateEventListeners(type: EventType) {
|
|
69
|
+
if (!this.listeners[type]) return;
|
|
70
|
+
this.listeners[type] = this.listeners[type]!.filter((listenerObj) => {
|
|
71
|
+
if (listenerObj.shouldRemove) {
|
|
72
|
+
_console.log(`removing "${type}" eventListener`, listenerObj);
|
|
73
|
+
}
|
|
74
|
+
return !listenerObj.shouldRemove;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
addEventListener<T extends EventType>(
|
|
79
|
+
type: T,
|
|
80
|
+
listener: (event: { type: T; target: Target; message: EventMessages[T] }) => void,
|
|
81
|
+
options: { once?: boolean } = { once: false }
|
|
82
|
+
): void {
|
|
83
|
+
if (!this.isValidEventType(type)) {
|
|
84
|
+
throw new Error(`Invalid event type: ${type}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!this.listeners[type]) {
|
|
88
|
+
this.listeners[type] = [];
|
|
89
|
+
_console.log(`creating "${type}" listeners array`, this.listeners[type]!);
|
|
90
|
+
}
|
|
91
|
+
_console.log(`adding "${type}" listener`, listener, options);
|
|
92
|
+
this.listeners[type]!.push({ listener, once: options.once });
|
|
93
|
+
|
|
94
|
+
_console.log(`currently have ${this.listeners[type]!.length} "${type}" listeners`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
removeEventListener<T extends EventType>(
|
|
98
|
+
type: T,
|
|
99
|
+
listener: (event: { type: T; target: Target; message: EventMessages[T] }) => void
|
|
100
|
+
): void {
|
|
101
|
+
if (!this.isValidEventType(type)) {
|
|
102
|
+
throw new Error(`Invalid event type: ${type}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!this.listeners[type]) return;
|
|
106
|
+
|
|
107
|
+
_console.log(`removing "${type}" listener...`, listener);
|
|
108
|
+
this.listeners[type]!.forEach((listenerObj) => {
|
|
109
|
+
const isListenerToRemove = listenerObj.listener === listener;
|
|
110
|
+
if (isListenerToRemove) {
|
|
111
|
+
_console.log(`flagging "${type}" listener`, listener);
|
|
112
|
+
listenerObj.shouldRemove = true;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
this.updateEventListeners(type);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
dispatchEvent<T extends EventType>(type: T, message: EventMessages[T]): void {
|
|
120
|
+
if (!this.isValidEventType(type)) {
|
|
121
|
+
throw new Error(`Invalid event type: ${type}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (!this.listeners[type]) return;
|
|
125
|
+
|
|
126
|
+
this.listeners[type]!.forEach((listenerObj) => {
|
|
127
|
+
if (listenerObj.shouldRemove) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
_console.log(`dispatching "${type}" listener`, listenerObj);
|
|
132
|
+
listenerObj.listener({ type, target: this.target, message });
|
|
133
|
+
|
|
134
|
+
if (listenerObj.once) {
|
|
135
|
+
_console.log(`flagging "${type}" listener`, listenerObj);
|
|
136
|
+
listenerObj.shouldRemove = true;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
this.updateEventListeners(type);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
waitForEvent<T extends EventType>(type: T): Promise<{ type: T; target: Target; message: EventMessages[T] }> {
|
|
143
|
+
return new Promise((resolve) => {
|
|
144
|
+
const onceListener = (event: { type: T; target: Target; message: EventMessages[T] }) => {
|
|
145
|
+
resolve(event);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
this.addEventListener(type, onceListener, { once: true });
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export default EventDispatcher;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createConsole } from "./Console.ts";
|
|
2
|
+
import { spacesToPascalCase } from "./stringUtils.ts";
|
|
3
|
+
|
|
4
|
+
const _console = createConsole("EventUtils", { log: false });
|
|
5
|
+
|
|
6
|
+
type BoundEventListeners = { [eventType: string]: EventListener };
|
|
7
|
+
export type BoundGenericEventListeners = { [eventType: string]: Function };
|
|
8
|
+
|
|
9
|
+
export function bindEventListeners(
|
|
10
|
+
eventTypes: readonly string[],
|
|
11
|
+
boundEventListeners: BoundGenericEventListeners,
|
|
12
|
+
target: any
|
|
13
|
+
) {
|
|
14
|
+
_console.log("bindEventListeners", { eventTypes, boundEventListeners, target });
|
|
15
|
+
eventTypes.forEach((eventType) => {
|
|
16
|
+
const _eventType = `_on${spacesToPascalCase(eventType)}`;
|
|
17
|
+
_console.assertWithError(target[_eventType], `no event "${_eventType}" found in target`);
|
|
18
|
+
_console.log(`binding eventType "${eventType}" as ${_eventType} from target`, target);
|
|
19
|
+
const boundEvent = target[_eventType].bind(target);
|
|
20
|
+
target[_eventType] = boundEvent;
|
|
21
|
+
boundEventListeners[eventType] = boundEvent;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function addEventListeners(target: any, boundEventListeners: BoundGenericEventListeners) {
|
|
26
|
+
let addEventListener = target.addEventListener || target.addListener || target.on || target.AddEventListener;
|
|
27
|
+
_console.assertWithError(addEventListener, "no add listener function found for target");
|
|
28
|
+
addEventListener = addEventListener.bind(target);
|
|
29
|
+
Object.entries(boundEventListeners).forEach(([eventType, eventListener]) => {
|
|
30
|
+
addEventListener(eventType, eventListener);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function removeEventListeners(target: any, boundEventListeners: BoundGenericEventListeners) {
|
|
35
|
+
let removeEventListener = target.removeEventListener || target.removeListener || target.RemoveEventListener;
|
|
36
|
+
_console.assertWithError(removeEventListener, "no remove listener function found for target");
|
|
37
|
+
removeEventListener = removeEventListener.bind(target);
|
|
38
|
+
Object.entries(boundEventListeners).forEach(([eventType, eventListener]) => {
|
|
39
|
+
removeEventListener(eventType, eventListener);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { createConsole } from "./Console.ts";
|
|
2
|
+
|
|
3
|
+
const _console = createConsole("MathUtils", { log: true });
|
|
4
|
+
|
|
5
|
+
export function getInterpolation(value: number, min: number, max: number, span: number) {
|
|
6
|
+
if (span == undefined) {
|
|
7
|
+
span = max - min;
|
|
8
|
+
}
|
|
9
|
+
return (value - min) / span;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const Uint16Max = 2 ** 16;
|
|
13
|
+
|
|
14
|
+
function removeLower2Bytes(number: number) {
|
|
15
|
+
const lower2Bytes = number % Uint16Max;
|
|
16
|
+
return number - lower2Bytes;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const timestampThreshold = 60_000;
|
|
20
|
+
|
|
21
|
+
export function parseTimestamp(dataView: DataView, byteOffset: number) {
|
|
22
|
+
const now = Date.now();
|
|
23
|
+
const nowWithoutLower2Bytes = removeLower2Bytes(now);
|
|
24
|
+
const lower2Bytes = dataView.getUint16(byteOffset, true);
|
|
25
|
+
let timestamp = nowWithoutLower2Bytes + lower2Bytes;
|
|
26
|
+
if (Math.abs(now - timestamp) > timestampThreshold) {
|
|
27
|
+
_console.log("correcting timestamp delta");
|
|
28
|
+
timestamp += Uint16Max * Math.sign(now - timestamp);
|
|
29
|
+
}
|
|
30
|
+
return timestamp;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface Vector2 {
|
|
34
|
+
x: number;
|
|
35
|
+
y: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface Vector3 extends Vector2 {
|
|
39
|
+
z: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface Quaternion {
|
|
43
|
+
x: number;
|
|
44
|
+
y: number;
|
|
45
|
+
z: number;
|
|
46
|
+
w: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface Euler {
|
|
50
|
+
heading: number;
|
|
51
|
+
pitch: number;
|
|
52
|
+
roll: number;
|
|
53
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { sliceDataView } from "./ArrayBufferUtils.ts";
|
|
2
|
+
import { createConsole } from "./Console.ts";
|
|
3
|
+
import { textDecoder } from "./Text.ts";
|
|
4
|
+
|
|
5
|
+
const _console = createConsole("ParseUtils", { log: true });
|
|
6
|
+
|
|
7
|
+
export function parseStringFromDataView(dataView: DataView, byteOffset: number = 0) {
|
|
8
|
+
const stringLength = dataView.getUint8(byteOffset++);
|
|
9
|
+
const string = textDecoder.decode(
|
|
10
|
+
dataView.buffer.slice(dataView.byteOffset + byteOffset, dataView.byteOffset + byteOffset + stringLength)
|
|
11
|
+
);
|
|
12
|
+
byteOffset += stringLength;
|
|
13
|
+
return { string, byteOffset };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function parseMessage<MessageType extends string>(
|
|
17
|
+
dataView: DataView,
|
|
18
|
+
messageTypes: readonly MessageType[],
|
|
19
|
+
callback: (messageType: MessageType, dataView: DataView, context?: any) => void,
|
|
20
|
+
context?: any,
|
|
21
|
+
parseMessageLengthAsUint16: boolean = false
|
|
22
|
+
) {
|
|
23
|
+
let byteOffset = 0;
|
|
24
|
+
while (byteOffset < dataView.byteLength) {
|
|
25
|
+
const messageTypeEnum = dataView.getUint8(byteOffset++);
|
|
26
|
+
_console.assertWithError(messageTypeEnum in messageTypes, `invalid messageTypeEnum ${messageTypeEnum}`);
|
|
27
|
+
const messageType = messageTypes[messageTypeEnum];
|
|
28
|
+
|
|
29
|
+
let messageLength: number;
|
|
30
|
+
if (parseMessageLengthAsUint16) {
|
|
31
|
+
messageLength = dataView.getUint16(byteOffset, true);
|
|
32
|
+
byteOffset += 2;
|
|
33
|
+
} else {
|
|
34
|
+
messageLength = dataView.getUint8(byteOffset++);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
_console.log({ messageTypeEnum, messageType, messageLength, dataView, byteOffset });
|
|
38
|
+
|
|
39
|
+
const _dataView = sliceDataView(dataView, byteOffset, messageLength);
|
|
40
|
+
_console.log({ _dataView });
|
|
41
|
+
|
|
42
|
+
callback(messageType, _dataView, context);
|
|
43
|
+
|
|
44
|
+
byteOffset += messageLength;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { getInterpolation } from "./MathUtils.ts";
|
|
2
|
+
|
|
3
|
+
interface Range {
|
|
4
|
+
min: number;
|
|
5
|
+
max: number;
|
|
6
|
+
span: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const initialRange: Range = { min: Infinity, max: -Infinity, span: 0 };
|
|
10
|
+
|
|
11
|
+
class RangeHelper {
|
|
12
|
+
#range: Range = Object.assign({}, initialRange);
|
|
13
|
+
|
|
14
|
+
reset() {
|
|
15
|
+
Object.assign(this.#range, initialRange);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
update(value: number) {
|
|
19
|
+
this.#range.min = Math.min(value, this.#range.min);
|
|
20
|
+
this.#range.max = Math.max(value, this.#range.max);
|
|
21
|
+
this.#range.span = this.#range.max - this.#range.min;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getNormalization(value: number, weightByRange: boolean) {
|
|
25
|
+
let normalization = getInterpolation(value, this.#range.min, this.#range.max, this.#range.span);
|
|
26
|
+
if (weightByRange) {
|
|
27
|
+
normalization *= this.#range.span;
|
|
28
|
+
}
|
|
29
|
+
return normalization || 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
updateAndGetNormalization(value: number, weightByRange: boolean) {
|
|
33
|
+
this.update(value);
|
|
34
|
+
return this.getNormalization(value, weightByRange);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default RangeHelper;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var _TextEncoder;
|
|
2
|
+
if (typeof TextEncoder == "undefined") {
|
|
3
|
+
_TextEncoder = class {
|
|
4
|
+
encode(string: string) {
|
|
5
|
+
const encoding = Array.from(string).map((char) => char.charCodeAt(0));
|
|
6
|
+
return Uint8Array.from(encoding);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
} else {
|
|
10
|
+
_TextEncoder = TextEncoder;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
var _TextDecoder;
|
|
14
|
+
if (typeof TextDecoder == "undefined") {
|
|
15
|
+
_TextDecoder = class {
|
|
16
|
+
decode(data: ArrayBuffer) {
|
|
17
|
+
const byteArray = Array.from(new Uint8Array(data));
|
|
18
|
+
return byteArray
|
|
19
|
+
.map((value) => {
|
|
20
|
+
return String.fromCharCode(value);
|
|
21
|
+
})
|
|
22
|
+
.join("");
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
} else {
|
|
26
|
+
_TextDecoder = TextDecoder;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const textEncoder = new _TextEncoder();
|
|
30
|
+
export const textDecoder = new _TextDecoder();
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createConsole } from "./Console.ts";
|
|
2
|
+
|
|
3
|
+
const _console = createConsole("Timer", { log: false });
|
|
4
|
+
|
|
5
|
+
export async function wait(delay: number) {
|
|
6
|
+
_console.log(`waiting for ${delay} ms`);
|
|
7
|
+
return new Promise((resolve: Function) => {
|
|
8
|
+
setTimeout(() => resolve(), delay);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
class Timer {
|
|
13
|
+
#callback!: Function;
|
|
14
|
+
get callback() {
|
|
15
|
+
return this.#callback;
|
|
16
|
+
}
|
|
17
|
+
set callback(newCallback) {
|
|
18
|
+
_console.assertTypeWithError(newCallback, "function");
|
|
19
|
+
_console.log({ newCallback });
|
|
20
|
+
this.#callback = newCallback;
|
|
21
|
+
if (this.isRunning) {
|
|
22
|
+
this.restart();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#interval!: number;
|
|
27
|
+
get interval() {
|
|
28
|
+
return this.#interval;
|
|
29
|
+
}
|
|
30
|
+
set interval(newInterval) {
|
|
31
|
+
_console.assertTypeWithError(newInterval, "number");
|
|
32
|
+
_console.assertWithError(newInterval > 0, "interval must be above 0");
|
|
33
|
+
_console.log({ newInterval });
|
|
34
|
+
this.#interval = newInterval;
|
|
35
|
+
if (this.isRunning) {
|
|
36
|
+
this.restart();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
constructor(callback: Function, interval: number) {
|
|
41
|
+
this.interval = interval;
|
|
42
|
+
this.callback = callback;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
#intervalId: number | undefined;
|
|
46
|
+
get isRunning() {
|
|
47
|
+
return this.#intervalId != undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
start() {
|
|
51
|
+
if (this.isRunning) {
|
|
52
|
+
_console.log("interval already running");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
_console.log("starting interval");
|
|
56
|
+
this.#intervalId = setInterval(this.#callback, this.#interval);
|
|
57
|
+
}
|
|
58
|
+
stop() {
|
|
59
|
+
if (!this.isRunning) {
|
|
60
|
+
_console.log("interval already not running");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
_console.log("stopping interval");
|
|
64
|
+
clearInterval(this.#intervalId);
|
|
65
|
+
this.#intervalId = undefined;
|
|
66
|
+
}
|
|
67
|
+
restart() {
|
|
68
|
+
this.stop();
|
|
69
|
+
this.start();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export default Timer;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type ValueOf<T> = T[keyof T];
|
|
2
|
+
export type KeyOf<T> = keyof T;
|
|
3
|
+
|
|
4
|
+
export type AddProperty<T, Key extends string, Value> = T & { [K in Key]: Value };
|
|
5
|
+
export type AddPropertyToInterfaceValues<Interface, Key extends string, Value> = {
|
|
6
|
+
[_ in keyof Interface]: AddProperty<Interface[_], Key, Value>;
|
|
7
|
+
};
|
|
8
|
+
export type AddKeysAsPropertyToInterface<Interface, Key extends string> = {
|
|
9
|
+
[Value in keyof Interface]: AddProperty<Interface[Value], Key, Value>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type ExtendInterfaceValues<Interface, T> = {
|
|
13
|
+
[Key in keyof Interface]: Interface[Key] & T;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type CapitalizeFirstLetter<S extends string> = S extends `${infer First}${infer Rest}`
|
|
17
|
+
? `${Uppercase<First>}${Rest}`
|
|
18
|
+
: S;
|
|
19
|
+
export type AddPrefix<P extends string, S extends string> = `${P}${CapitalizeFirstLetter<S>}`;
|
|
20
|
+
export type AddPrefixToInterfaceKeys<Interface, P extends string> = {
|
|
21
|
+
[Key in keyof Interface as `${AddPrefix<P, Key & string>}`]: Interface[Key];
|
|
22
|
+
};
|