12 Commits

Author SHA1 Message Date
jwetzell 3e51737881 bump version to 1.0.0 2024-10-23 16:48:32 -05:00
jwetzell 3a249ff52d sync package-lock 2024-10-23 16:47:53 -05:00
jwetzell 9273f5a1a5 add examples from README to examples folder 2024-10-23 16:47:24 -05:00
jwetzell 82d4e17ec9 Merge pull request #41 from jwetzell/remove-buffer
replace NodeJS buffer with Uint8Array
2024-10-23 16:47:06 -05:00
jwetzell 8710e75a93 update example in README 2024-10-23 16:46:12 -05:00
jwetzell 4eaedcdfaa replace NodeJS buffer with Uint8Array 2024-10-23 16:38:16 -05:00
jwetzell 90e1bd09a0 Create LICENSE 2024-10-22 08:36:21 -05:00
jwetzell 1358158333 Change license to MIT in package.json 2024-10-22 08:36:00 -05:00
jwetzell 521ef895d8 Merge pull request #39 from jwetzell/dependabot/npm_and_yarn/typescript-5.6.3
Bump typescript from 5.6.2 to 5.6.3
2024-10-21 10:26:37 -05:00
jwetzell d0645d4c93 Merge pull request #40 from jwetzell/dependabot/npm_and_yarn/types/node-22.7.7
Bump @types/node from 22.7.4 to 22.7.7
2024-10-21 10:26:27 -05:00
dependabot[bot] 8d99c0a647 Bump @types/node from 22.7.4 to 22.7.7
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.7.4 to 22.7.7.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-21 12:15:59 +00:00
dependabot[bot] efc69c9345 Bump typescript from 5.6.2 to 5.6.3
Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.6.2 to 5.6.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.6.2...v5.6.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-14 13:05:46 +00:00
40 changed files with 331 additions and 132 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Joel Wetzell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+12 -4
View File
@@ -13,8 +13,16 @@ typesecript implementation of the [PosiStageNet protocol](https://github.com/vyv
const { Decoder } = require('@jwetzell/posistagenet') const { Decoder } = require('@jwetzell/posistagenet')
const decoder = new Decoder() const decoder = new Decoder()
const infoPacketBuffer = Buffer.from('5667348000000c0001000000000000000203010101000b00536572766572204e616d650200118001000d8000000900547261636b65722031','hex') const infoPacketBuffer = new Uint8Array([
const dataPacketBuffer = Buffer.from('5567288000000c00010000000000000002030101010014800100108000000c000000803f0000803f0000803f','hex') 0x56, 0x67, 0x34, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01,
0x01, 0x01, 0x00, 0x0b, 0x00, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x02, 0x00, 0x11,
0x80, 0x01, 0x00, 0x0d, 0x80, 0x00, 0x00, 0x09, 0x00, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x72, 0x20, 0x31,
]);
const dataPacketBuffer = new Uint8Array([
0x55, 0x67, 0x28, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01,
0x01, 0x01, 0x00, 0x14, 0x80, 0x01, 0x00, 0x10, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00,
0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f,
]);
decoder.decode(infoPacketBuffer) decoder.decode(infoPacketBuffer)
decoder.decode(dataPacketBuffer) decoder.decode(dataPacketBuffer)
@@ -49,12 +57,12 @@ const infoPackets = encoder.getInfoPackets(timestamp, trackers)
dataPackets.forEach((dataPacket)=>{ dataPackets.forEach((dataPacket)=>{
console.log('send packet somehow') console.log('send packet somehow')
console.log(dataPacket.toString('hex')) console.log(dataPacket)
}) })
infoPackets.forEach((infoPacket)=>{ infoPackets.forEach((infoPacket)=>{
console.log('send packet somehow') console.log('send packet somehow')
console.log(infoPacket.toString('hex')) console.log(infoPacket)
}) })
``` ```
+23
View File
@@ -0,0 +1,23 @@
const { Decoder } = require('../dist');
const decoder = new Decoder();
const infoPacketBuffer = new Uint8Array([
0x56, 0x67, 0x34, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01,
0x01, 0x01, 0x00, 0x0b, 0x00, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x02, 0x00, 0x11,
0x80, 0x01, 0x00, 0x0d, 0x80, 0x00, 0x00, 0x09, 0x00, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x72, 0x20, 0x31,
]);
const dataPacketBuffer = new Uint8Array([
0x55, 0x67, 0x28, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01,
0x01, 0x01, 0x00, 0x14, 0x80, 0x01, 0x00, 0x10, 0x80, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00,
0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f,
]);
decoder.decode(infoPacketBuffer);
decoder.decode(dataPacketBuffer);
// the system_name from info packets if available
console.log(decoder.system_name);
// map of trackers populated with any data that has been received
// this merges both info and data packet properties into one
console.log(decoder.trackers);
+25
View File
@@ -0,0 +1,25 @@
const { Encoder, Tracker } = require('../dist');
const encoder = new Encoder('Server Name', 2, 3); //server name, version high, version low
const trackers = [];
const tracker = new Tracker(1, 'Tracker 1'); // id, name
tracker.setPos(1.0, 1.0, 1.0); // x, y, z
trackers.push(tracker);
const timestamp = 1;
// these two calls return an array of Buffers due to potential splitting that might take place because of max UDP packet size
const dataPackets = encoder.getDataPackets(timestamp, trackers);
const infoPackets = encoder.getInfoPackets(timestamp, trackers);
dataPackets.forEach((dataPacket) => {
console.log('send packet somehow');
console.log(dataPacket);
});
infoPackets.forEach((infoPacket) => {
console.log('send packet somehow');
console.log(infoPacket);
});
+11 -11
View File
@@ -1,18 +1,18 @@
{ {
"name": "@jwetzell/posistagenet", "name": "@jwetzell/posistagenet",
"version": "0.4.7", "version": "1.0.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@jwetzell/posistagenet", "name": "@jwetzell/posistagenet",
"version": "0.4.7", "version": "1.0.0",
"license": "ISC", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/node": "22.7.4", "@types/node": "22.7.7",
"prettier": "3.3.3", "prettier": "3.3.3",
"rimraf": "6.0.1", "rimraf": "6.0.1",
"typescript": "5.6.2" "typescript": "5.6.3"
} }
}, },
"node_modules/@isaacs/cliui": { "node_modules/@isaacs/cliui": {
@@ -43,9 +43,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.7.4", "version": "22.7.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.7.tgz",
"integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==", "integrity": "sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
@@ -434,9 +434,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.6.2", "version": "5.6.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
"integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
"dev": true, "dev": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
+4 -4
View File
@@ -1,6 +1,6 @@
{ {
"name": "@jwetzell/posistagenet", "name": "@jwetzell/posistagenet",
"version": "0.4.7", "version": "1.0.0",
"description": "", "description": "",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
@@ -20,11 +20,11 @@
"url": "https://jwetzell.com" "url": "https://jwetzell.com"
}, },
"repository": "https://github.com/jwetzell/psn-js", "repository": "https://github.com/jwetzell/psn-js",
"license": "ISC", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/node": "22.7.4", "@types/node": "22.7.7",
"prettier": "3.3.3", "prettier": "3.3.3",
"rimraf": "6.0.1", "rimraf": "6.0.1",
"typescript": "5.6.2" "typescript": "5.6.3"
} }
} }
+1 -1
View File
@@ -47,7 +47,7 @@ export class Decoder {
} }
// TODO(jwetzell): add invalid frame id decoding. Scenario where a frame id is reused before one is complete // TODO(jwetzell): add invalid frame id decoding. Scenario where a frame id is reused before one is complete
decode(packetBuf: Buffer): DataPacketChunk | InfoPacketChunk | undefined { decode(packetBuf: Uint8Array): DataPacketChunk | InfoPacketChunk | undefined {
const packet = Decoders.Packet(packetBuf); const packet = Decoders.Packet(packetBuf);
if (packet === undefined) { if (packet === undefined) {
return packet; return packet;
+5 -4
View File
@@ -1,17 +1,18 @@
import { Chunk } from '../models/chunk'; import { Chunk } from '../models/chunk';
export default (buffer: Buffer, dataDecoder: Function): Chunk => { export default (buffer: Uint8Array, dataDecoder: Function): Chunk => {
let offset = 0; let offset = 0;
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
const chunk: Chunk = {}; const chunk: Chunk = {};
chunk.id = buffer.readUInt16LE(offset); chunk.id = view.getUint16(offset, true);
offset += 2; offset += 2;
// NOTE(jwetzell): this data is split up as 1 bit for has_subchunks and 15 bits for the data_len // NOTE(jwetzell): this data is split up as 1 bit for has_subchunks and 15 bits for the data_len
const combinedLengthAndFlag = buffer.readUInt16LE(offset); const combinedLengthAndFlag = view.getUint16(offset, true);
chunk.has_subchunks = combinedLengthAndFlag > 32768; chunk.has_subchunks = combinedLengthAndFlag > 32768;
chunk.data_len = chunk.has_subchunks ? combinedLengthAndFlag - 32768 : combinedLengthAndFlag; chunk.data_len = chunk.has_subchunks ? combinedLengthAndFlag - 32768 : combinedLengthAndFlag;
offset += 2; offset += 2;
chunk.chunk_data = buffer.subarray(offset, offset + chunk.data_len); chunk.chunk_data = buffer.slice(offset, offset + chunk.data_len);
dataDecoder(chunk); dataDecoder(chunk);
return chunk; return chunk;
+10 -4
View File
@@ -6,17 +6,22 @@ function decodeDataPacketChunk(dataPacketChunk: DataPacketChunk) {
if (dataPacketChunk.has_subchunks && dataPacketChunk.chunk_data && dataPacketChunk.data_len) { if (dataPacketChunk.has_subchunks && dataPacketChunk.chunk_data && dataPacketChunk.data_len) {
let offset = 0; let offset = 0;
while (offset < dataPacketChunk.data_len) { while (offset < dataPacketChunk.data_len) {
const chunkId = dataPacketChunk.chunk_data.readUInt16LE(offset); const view = new DataView(
dataPacketChunk.chunk_data.buffer,
dataPacketChunk.chunk_data.byteOffset,
dataPacketChunk.chunk_data.byteLength
);
const chunkId = view.getUint16(offset, true);
switch (chunkId) { switch (chunkId) {
case 0x0000: case 0x0000:
dataPacketChunk.packet_header = Decoders.PacketHeaderChunk(dataPacketChunk.chunk_data.subarray(offset)); dataPacketChunk.packet_header = Decoders.PacketHeaderChunk(dataPacketChunk.chunk_data.slice(offset));
offset += Constants.CHUNK_HEADER_SIZE; offset += Constants.CHUNK_HEADER_SIZE;
if (dataPacketChunk.packet_header?.data_len) { if (dataPacketChunk.packet_header?.data_len) {
offset += dataPacketChunk.packet_header.data_len; offset += dataPacketChunk.packet_header.data_len;
} }
break; break;
case 0x0001: case 0x0001:
dataPacketChunk.tracker_list = Decoders.DataTrackerListChunk(dataPacketChunk.chunk_data.subarray(offset)); dataPacketChunk.tracker_list = Decoders.DataTrackerListChunk(dataPacketChunk.chunk_data.slice(offset));
offset += Constants.CHUNK_HEADER_SIZE; offset += Constants.CHUNK_HEADER_SIZE;
if (dataPacketChunk.tracker_list.data_len) { if (dataPacketChunk.tracker_list.data_len) {
offset += dataPacketChunk.tracker_list.data_len; offset += dataPacketChunk.tracker_list.data_len;
@@ -29,4 +34,5 @@ function decodeDataPacketChunk(dataPacketChunk: DataPacketChunk) {
} }
} }
export default (buffer: Buffer): DataPacketChunk => Decoders.Chunk(buffer, decodeDataPacketChunk) as DataPacketChunk; export default (buffer: Uint8Array): DataPacketChunk =>
Decoders.Chunk(buffer, decodeDataPacketChunk) as DataPacketChunk;
+2 -2
View File
@@ -6,7 +6,7 @@ function decodeTrackerChunk(trackerChunk: DataTrackerChunk) {
if (trackerChunk.chunk_data && trackerChunk.data_len) { if (trackerChunk.chunk_data && trackerChunk.data_len) {
let offset = 0; let offset = 0;
while (offset < trackerChunk.data_len) { while (offset < trackerChunk.data_len) {
const trackerFieldChunk = Decoders.DataTrackerFieldChunk(trackerChunk.chunk_data.subarray(offset)); const trackerFieldChunk = Decoders.DataTrackerFieldChunk(trackerChunk.chunk_data.slice(offset));
offset += Constants.CHUNK_HEADER_SIZE; offset += Constants.CHUNK_HEADER_SIZE;
if (trackerFieldChunk.data_len) { if (trackerFieldChunk.data_len) {
offset += trackerFieldChunk.data_len; offset += trackerFieldChunk.data_len;
@@ -40,4 +40,4 @@ function decodeTrackerChunk(trackerChunk: DataTrackerChunk) {
} }
} }
export default (buffer: Buffer): DataTrackerChunk => Decoders.Chunk(buffer, decodeTrackerChunk) as DataTrackerChunk; export default (buffer: Uint8Array): DataTrackerChunk => Decoders.Chunk(buffer, decodeTrackerChunk) as DataTrackerChunk;
+21 -6
View File
@@ -5,9 +5,14 @@ import { DataTrackerFieldChunk } from '../../models/data/data-tracker-field-chun
function readXYZ(trackerFieldChunk: DataTrackerFieldChunk, prefix: string = '') { function readXYZ(trackerFieldChunk: DataTrackerFieldChunk, prefix: string = '') {
if (trackerFieldChunk.chunk_data) { if (trackerFieldChunk.chunk_data) {
trackerFieldChunk[`${prefix}x`] = trackerFieldChunk.chunk_data.readFloatLE(0); const view = new DataView(
trackerFieldChunk[`${prefix}y`] = trackerFieldChunk.chunk_data.readFloatLE(4); trackerFieldChunk.chunk_data.buffer,
trackerFieldChunk[`${prefix}z`] = trackerFieldChunk.chunk_data.readFloatLE(8); trackerFieldChunk.chunk_data.byteOffset,
trackerFieldChunk.chunk_data.byteLength
);
trackerFieldChunk[`${prefix}x`] = view.getFloat32(0, true);
trackerFieldChunk[`${prefix}y`] = view.getFloat32(4, true);
trackerFieldChunk[`${prefix}z`] = view.getFloat32(8, true);
} }
} }
function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) { function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) {
@@ -24,7 +29,12 @@ function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) {
break; break;
case 0x0003: case 0x0003:
if (trackerFieldChunk.chunk_data) { if (trackerFieldChunk.chunk_data) {
trackerFieldChunk.validity = trackerFieldChunk.chunk_data.readFloatLE(); const view = new DataView(
trackerFieldChunk.chunk_data.buffer,
trackerFieldChunk.chunk_data.byteOffset,
trackerFieldChunk.chunk_data.byteLength
);
trackerFieldChunk.validity = view.getFloat32(0, true);
} }
break; break;
case 0x0004: case 0x0004:
@@ -35,7 +45,12 @@ function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) {
break; break;
case 0x0006: case 0x0006:
if (trackerFieldChunk.chunk_data) { if (trackerFieldChunk.chunk_data) {
trackerFieldChunk.tracker_timestamp = trackerFieldChunk.chunk_data.readBigUInt64LE(); const view = new DataView(
trackerFieldChunk.chunk_data.buffer,
trackerFieldChunk.chunk_data.byteOffset,
trackerFieldChunk.chunk_data.byteLength
);
trackerFieldChunk.tracker_timestamp = view.getBigUint64(0, true);
} }
break; break;
default: default:
@@ -44,5 +59,5 @@ function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) {
} }
} }
export default (buffer: Buffer): DataTrackerFieldChunk => export default (buffer: Uint8Array): DataTrackerFieldChunk =>
Decoders.Chunk(buffer, decodeTrackerFieldChunk) as DataTrackerFieldChunk; Decoders.Chunk(buffer, decodeTrackerFieldChunk) as DataTrackerFieldChunk;
+2 -2
View File
@@ -9,7 +9,7 @@ function decodeDataTrackerListChunk(dataTrackerListChunk: DataTrackerListChunk)
let offset = 0; let offset = 0;
if (dataTrackerListChunk.chunk_data) { if (dataTrackerListChunk.chunk_data) {
while (offset < dataTrackerListChunk.chunk_data.length) { while (offset < dataTrackerListChunk.chunk_data.length) {
const trackerChunk = Decoders.DataTrackerChunk(dataTrackerListChunk.chunk_data.subarray(offset)); const trackerChunk = Decoders.DataTrackerChunk(dataTrackerListChunk.chunk_data.slice(offset));
offset += Constants.CHUNK_HEADER_SIZE; offset += Constants.CHUNK_HEADER_SIZE;
if (trackerChunk.data_len) { if (trackerChunk.data_len) {
offset += trackerChunk.data_len; offset += trackerChunk.data_len;
@@ -20,5 +20,5 @@ function decodeDataTrackerListChunk(dataTrackerListChunk: DataTrackerListChunk)
} }
} }
} }
export default (buffer: Buffer): DataTrackerListChunk => export default (buffer: Uint8Array): DataTrackerListChunk =>
Decoders.Chunk(buffer, decodeDataTrackerListChunk) as DataTrackerListChunk; Decoders.Chunk(buffer, decodeDataTrackerListChunk) as DataTrackerListChunk;
+11 -5
View File
@@ -6,24 +6,29 @@ function decodeInfoPacketChunk(infoPacketChunk: InfoPacketChunk) {
if (infoPacketChunk.has_subchunks && infoPacketChunk.chunk_data && infoPacketChunk.data_len) { if (infoPacketChunk.has_subchunks && infoPacketChunk.chunk_data && infoPacketChunk.data_len) {
let offset = 0; let offset = 0;
while (offset < infoPacketChunk.data_len) { while (offset < infoPacketChunk.data_len) {
const chunkId = infoPacketChunk.chunk_data.readUInt16LE(offset); const view = new DataView(
infoPacketChunk.chunk_data.buffer,
infoPacketChunk.chunk_data.byteOffset,
infoPacketChunk.chunk_data.byteLength
);
const chunkId = view.getUint16(offset, true);
switch (chunkId) { switch (chunkId) {
case 0x0000: case 0x0000:
infoPacketChunk.packet_header = Decoders.PacketHeaderChunk(infoPacketChunk.chunk_data.subarray(offset)); infoPacketChunk.packet_header = Decoders.PacketHeaderChunk(infoPacketChunk.chunk_data.slice(offset));
offset += Constants.CHUNK_HEADER_SIZE; offset += Constants.CHUNK_HEADER_SIZE;
if (infoPacketChunk.packet_header?.data_len) { if (infoPacketChunk.packet_header?.data_len) {
offset += infoPacketChunk.packet_header.data_len; offset += infoPacketChunk.packet_header.data_len;
} }
break; break;
case 0x0001: case 0x0001:
infoPacketChunk.system_name = Decoders.InfoSystemNameChunk(infoPacketChunk.chunk_data.subarray(offset)); infoPacketChunk.system_name = Decoders.InfoSystemNameChunk(infoPacketChunk.chunk_data.slice(offset));
offset += Constants.CHUNK_HEADER_SIZE; offset += Constants.CHUNK_HEADER_SIZE;
if (infoPacketChunk.system_name?.data_len) { if (infoPacketChunk.system_name?.data_len) {
offset += infoPacketChunk.system_name.data_len; offset += infoPacketChunk.system_name.data_len;
} }
break; break;
case 0x0002: case 0x0002:
infoPacketChunk.tracker_list = Decoders.InfoTrackerListChunk(infoPacketChunk.chunk_data.subarray(offset)); infoPacketChunk.tracker_list = Decoders.InfoTrackerListChunk(infoPacketChunk.chunk_data.slice(offset));
offset += Constants.CHUNK_HEADER_SIZE; offset += Constants.CHUNK_HEADER_SIZE;
if (infoPacketChunk.tracker_list?.data_len) { if (infoPacketChunk.tracker_list?.data_len) {
offset += infoPacketChunk.tracker_list.data_len; offset += infoPacketChunk.tracker_list.data_len;
@@ -36,4 +41,5 @@ function decodeInfoPacketChunk(infoPacketChunk: InfoPacketChunk) {
} }
} }
export default (buffer: Buffer): InfoPacketChunk => Decoders.Chunk(buffer, decodeInfoPacketChunk) as InfoPacketChunk; export default (buffer: Uint8Array): InfoPacketChunk =>
Decoders.Chunk(buffer, decodeInfoPacketChunk) as InfoPacketChunk;
+4 -2
View File
@@ -3,9 +3,11 @@ import { InfoSystemNameChunk } from '../../models/info/info-system-name-chunk';
function decodeSystemNameChunk(systemNameChunk: InfoSystemNameChunk) { function decodeSystemNameChunk(systemNameChunk: InfoSystemNameChunk) {
if (systemNameChunk.chunk_data !== undefined && systemNameChunk.data_len !== undefined) { if (systemNameChunk.chunk_data !== undefined && systemNameChunk.data_len !== undefined) {
systemNameChunk.system_name = systemNameChunk.chunk_data.subarray(0, systemNameChunk.data_len).toString(); systemNameChunk.system_name = new TextDecoder().decode(
systemNameChunk.chunk_data.slice(0, systemNameChunk.data_len)
);
} }
} }
export default (buffer: Buffer): InfoSystemNameChunk => export default (buffer: Uint8Array): InfoSystemNameChunk =>
Decoders.Chunk(buffer, decodeSystemNameChunk) as InfoSystemNameChunk; Decoders.Chunk(buffer, decodeSystemNameChunk) as InfoSystemNameChunk;
+8 -3
View File
@@ -6,10 +6,15 @@ function decodeInfoTrackerChunk(infoTrackerChunk: InfoTrackerChunk) {
if (infoTrackerChunk.has_subchunks && infoTrackerChunk.chunk_data && infoTrackerChunk.data_len) { if (infoTrackerChunk.has_subchunks && infoTrackerChunk.chunk_data && infoTrackerChunk.data_len) {
let offset = 0; let offset = 0;
while (offset < infoTrackerChunk.data_len) { while (offset < infoTrackerChunk.data_len) {
const chunkId = infoTrackerChunk.chunk_data.readUInt16LE(offset); const view = new DataView(
infoTrackerChunk.chunk_data.buffer,
infoTrackerChunk.chunk_data.byteOffset,
infoTrackerChunk.chunk_data.byteLength
);
const chunkId = view.getUint16(offset, true);
switch (chunkId) { switch (chunkId) {
case 0x0000: case 0x0000:
infoTrackerChunk.tracker_name = Decoders.InfoTrackerNameChunk(infoTrackerChunk.chunk_data.subarray(offset)); infoTrackerChunk.tracker_name = Decoders.InfoTrackerNameChunk(infoTrackerChunk.chunk_data.slice(offset));
offset += Constants.CHUNK_HEADER_SIZE; offset += Constants.CHUNK_HEADER_SIZE;
if (infoTrackerChunk.tracker_name?.data_len) { if (infoTrackerChunk.tracker_name?.data_len) {
offset += infoTrackerChunk?.tracker_name?.data_len; offset += infoTrackerChunk?.tracker_name?.data_len;
@@ -23,4 +28,4 @@ function decodeInfoTrackerChunk(infoTrackerChunk: InfoTrackerChunk) {
} }
} }
export default (buffer: Buffer): InfoTrackerChunk => Decoders.Chunk(buffer, decodeInfoTrackerChunk); export default (buffer: Uint8Array): InfoTrackerChunk => Decoders.Chunk(buffer, decodeInfoTrackerChunk);
+2 -2
View File
@@ -8,7 +8,7 @@ function decodeInfoTrackerListChunk(infoTrackerListChunk: InfoTrackerListChunk)
let offset = 0; let offset = 0;
if (infoTrackerListChunk.data_len) { if (infoTrackerListChunk.data_len) {
while (offset < infoTrackerListChunk.data_len) { while (offset < infoTrackerListChunk.data_len) {
const trackerChunk = Decoders.InfoTrackerChunk(infoTrackerListChunk.chunk_data.subarray(offset)); const trackerChunk = Decoders.InfoTrackerChunk(infoTrackerListChunk.chunk_data.slice(offset));
offset += Constants.CHUNK_HEADER_SIZE; offset += Constants.CHUNK_HEADER_SIZE;
if (trackerChunk.data_len) { if (trackerChunk.data_len) {
offset += trackerChunk.data_len; offset += trackerChunk.data_len;
@@ -20,5 +20,5 @@ function decodeInfoTrackerListChunk(infoTrackerListChunk: InfoTrackerListChunk)
} }
} }
} }
export default (buffer: Buffer): InfoTrackerListChunk => export default (buffer: Uint8Array): InfoTrackerListChunk =>
Decoders.Chunk(buffer, decodeInfoTrackerListChunk) as InfoTrackerListChunk; Decoders.Chunk(buffer, decodeInfoTrackerListChunk) as InfoTrackerListChunk;
+4 -2
View File
@@ -3,8 +3,10 @@ import { InfoTrackerNameChunk } from '../../models/info/info-tracker-name-chunk'
function decodeTrackerNameChunk(trackerNameChunk: InfoTrackerNameChunk) { function decodeTrackerNameChunk(trackerNameChunk: InfoTrackerNameChunk) {
if (trackerNameChunk.chunk_data !== undefined && trackerNameChunk.data_len !== undefined) { if (trackerNameChunk.chunk_data !== undefined && trackerNameChunk.data_len !== undefined) {
trackerNameChunk.tracker_name = trackerNameChunk.chunk_data.subarray(0, trackerNameChunk.data_len).toString(); trackerNameChunk.tracker_name = new TextDecoder().decode(
trackerNameChunk.chunk_data.slice(0, trackerNameChunk.data_len)
);
} }
} }
export default (buffer: Buffer): InfoTrackerNameChunk => export default (buffer: Uint8Array): InfoTrackerNameChunk =>
Decoders.Chunk(buffer, decodeTrackerNameChunk) as InfoTrackerNameChunk; Decoders.Chunk(buffer, decodeTrackerNameChunk) as InfoTrackerNameChunk;
+13 -6
View File
@@ -3,12 +3,19 @@ import { PacketHeaderChunk } from '../models/packet-header-chunk';
function decodePacketHeaderChunk(packetHeaderChunk: PacketHeaderChunk) { function decodePacketHeaderChunk(packetHeaderChunk: PacketHeaderChunk) {
if (packetHeaderChunk.chunk_data) { if (packetHeaderChunk.chunk_data) {
packetHeaderChunk.packet_timestamp = packetHeaderChunk.chunk_data.readBigUInt64LE(0); const view = new DataView(
packetHeaderChunk.version_high = packetHeaderChunk.chunk_data.readUInt8(8); packetHeaderChunk.chunk_data.buffer,
packetHeaderChunk.version_low = packetHeaderChunk.chunk_data.readUInt8(9); packetHeaderChunk.chunk_data.byteOffset,
packetHeaderChunk.frame_id = packetHeaderChunk.chunk_data.readUInt8(10); packetHeaderChunk.chunk_data.byteLength
packetHeaderChunk.frame_packet_count = packetHeaderChunk.chunk_data.readUInt8(11); );
packetHeaderChunk.packet_timestamp = view.getBigUint64(0, true);
packetHeaderChunk.version_high = view.getUint8(8);
packetHeaderChunk.version_low = view.getUint8(9);
packetHeaderChunk.frame_id = view.getUint8(10);
packetHeaderChunk.frame_packet_count = view.getUint8(11);
} }
} }
export default (buffer: Buffer): PacketHeaderChunk => Decoders.Chunk(buffer, decodePacketHeaderChunk); export default (buffer: Uint8Array): PacketHeaderChunk => {
return Decoders.Chunk(buffer, decodePacketHeaderChunk);
};
+4 -2
View File
@@ -2,8 +2,10 @@ import { Decoders } from '.';
import { DataPacketChunk } from '../models/data/data-packet-chunk'; import { DataPacketChunk } from '../models/data/data-packet-chunk';
import { InfoPacketChunk } from '../models/info/info-packet-chunk'; import { InfoPacketChunk } from '../models/info/info-packet-chunk';
export default (buffer: Buffer): InfoPacketChunk | DataPacketChunk | undefined => { export default (buffer: Uint8Array): InfoPacketChunk | DataPacketChunk | undefined => {
const chunkId = buffer.readUInt16LE(); const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
const chunkId = view.getUint16(0, true);
switch (chunkId) { switch (chunkId) {
case 0x6756: case 0x6756:
return Decoders.InfoPacketChunk(buffer); return Decoders.InfoPacketChunk(buffer);
+7 -7
View File
@@ -47,14 +47,14 @@ export class Encoder {
const trackerChunks = trackers.map((tracker: Tracker) => tracker.getInfoChunk()); const trackerChunks = trackers.map((tracker: Tracker) => tracker.getInfoChunk());
const infoPackets: Buffer[] = []; const infoPackets: Uint8Array[] = [];
const trackerChunksLists: Buffer[][] = []; const trackerChunksLists: Uint8Array[][] = [];
let currentTrackerList: Buffer[] = []; let currentTrackerList: Uint8Array[] = [];
let currentInfoPacketSize = Constants.PACKET_HEADER_SIZE + systemNameChunk.length + Constants.CHUNK_HEADER_SIZE; let currentInfoPacketSize = Constants.PACKET_HEADER_SIZE + systemNameChunk.length + Constants.CHUNK_HEADER_SIZE;
trackerChunks.forEach((trackerChunk: Buffer) => { trackerChunks.forEach((trackerChunk: Uint8Array) => {
if (currentInfoPacketSize + trackerChunk.length > Constants.MAX_UDP_PACKET_SIZE) { if (currentInfoPacketSize + trackerChunk.length > Constants.MAX_UDP_PACKET_SIZE) {
trackerChunksLists.push(currentTrackerList); trackerChunksLists.push(currentTrackerList);
currentTrackerList = []; currentTrackerList = [];
@@ -95,10 +95,10 @@ export class Encoder {
} }
const allTrackerChunks = trackers.map((tracker) => tracker.getDataChunk()); const allTrackerChunks = trackers.map((tracker) => tracker.getDataChunk());
const dataPackets: Buffer[] = []; const dataPackets: Uint8Array[] = [];
const trackerChunksLists: Buffer[][] = []; const trackerChunksLists: Uint8Array[][] = [];
let currentTrackerList: Buffer[] = []; let currentTrackerList: Uint8Array[] = [];
let currentDataPacketSize = Constants.PACKET_HEADER_SIZE + Constants.CHUNK_HEADER_SIZE; let currentDataPacketSize = Constants.PACKET_HEADER_SIZE + Constants.CHUNK_HEADER_SIZE;
+10 -5
View File
@@ -1,4 +1,4 @@
export default (id: number, chunkData: Buffer, hasSubchunks: boolean): Buffer => { export default (id: number, chunkData: Uint8Array, hasSubchunks: boolean): Uint8Array => {
if (!Number.isInteger(id)) { if (!Number.isInteger(id)) {
throw new Error('chunk id must be an integer'); throw new Error('chunk id must be an integer');
} }
@@ -11,10 +11,15 @@ export default (id: number, chunkData: Buffer, hasSubchunks: boolean): Buffer =>
throw new Error('chunkData can not be greater than 32767 bytes'); throw new Error('chunkData can not be greater than 32767 bytes');
} }
const header = Buffer.alloc(4); const header = new DataView(new ArrayBuffer(4));
header.writeUInt16LE(id); header.setUint16(0, id, true);
const hasSubChunksBit = (hasSubchunks ? 1 : 0) << 15; const hasSubChunksBit = (hasSubchunks ? 1 : 0) << 15;
header.writeUInt16LE(hasSubChunksBit + chunkData.length, 2); header.setUint16(2, hasSubChunksBit + chunkData.length, true);
return Buffer.concat([header, chunkData]); const headerBytes = new Uint8Array(header.buffer);
const bytes = new Uint8Array(headerBytes.length + chunkData.length);
bytes.set(headerBytes);
bytes.set(chunkData, headerBytes.length);
return bytes;
}; };
+6 -2
View File
@@ -1,3 +1,7 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (packetHeaderChunk: Buffer, trackerListChunk: Buffer): Buffer => export default (packetHeaderChunk: Uint8Array, trackerListChunk: Uint8Array): Uint8Array => {
chunk(0x6755, Buffer.concat([packetHeaderChunk, trackerListChunk]), true); const chunkData = new Uint8Array(packetHeaderChunk.length + trackerListChunk.length);
chunkData.set(packetHeaderChunk);
chunkData.set(trackerListChunk, packetHeaderChunk.length);
return chunk(0x6755, chunkData, true);
};
@@ -1,9 +1,9 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (x: number, y: number, z: number): Buffer => { export default (x: number, y: number, z: number): Uint8Array => {
const buf = Buffer.alloc(12); const buf = new DataView(new ArrayBuffer(12));
buf.writeFloatLE(x); buf.setFloat32(0, x, true);
buf.writeFloatLE(y, 4); buf.setFloat32(4, y, true);
buf.writeFloatLE(z, 8); buf.setFloat32(8, z, true);
return chunk(0x0004, buf, false); return chunk(0x0004, new Uint8Array(buf.buffer), false);
}; };
+18 -2
View File
@@ -1,4 +1,20 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (trackerId: number, fieldChunks: Buffer[]): Buffer => export default (trackerId: number, fieldChunks: Uint8Array[]): Uint8Array => {
chunk(trackerId, Buffer.concat(fieldChunks), fieldChunks.length > 0); let fieldChunksTotalLength = 0;
fieldChunks.forEach((fieldChunk) => {
fieldChunksTotalLength += fieldChunk.length;
});
const fieldChunksBytes = new Uint8Array(fieldChunksTotalLength);
let offset = 0;
fieldChunks.forEach((fieldChunk) => {
fieldChunksBytes.set(fieldChunk, offset);
offset += fieldChunk.length;
});
return chunk(trackerId, fieldChunksBytes, fieldChunks.length > 0);
};
+18 -1
View File
@@ -1,3 +1,20 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (trackerChunks: Buffer[]) => chunk(0x0001, Buffer.concat(trackerChunks), true); export default (trackerChunks: Uint8Array[]) => {
let trackerChunksTotalLength = 0;
trackerChunks.forEach((trackerChunk) => {
trackerChunksTotalLength += trackerChunk.length;
});
const trackerChunksBytes = new Uint8Array(trackerChunksTotalLength);
let offset = 0;
trackerChunks.forEach((trackerChunk) => {
trackerChunksBytes.set(trackerChunk, offset);
offset += trackerChunk.length;
});
return chunk(0x0001, trackerChunksBytes, true);
};
+7 -6
View File
@@ -1,9 +1,10 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (x: number, y: number, z: number): Buffer => { export default (x: number, y: number, z: number): Uint8Array => {
const buf = Buffer.alloc(12); const buf = new DataView(new ArrayBuffer(12));
buf.writeFloatLE(x);
buf.writeFloatLE(y, 4); buf.setFloat32(0, x, true);
buf.writeFloatLE(z, 8); buf.setFloat32(4, y, true);
return chunk(0x0002, buf, false); buf.setFloat32(8, z, true);
return chunk(0x0002, new Uint8Array(buf.buffer), false);
}; };
+8 -6
View File
@@ -1,9 +1,11 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (x: number, y: number, z: number): Buffer => { export default (x: number, y: number, z: number): Uint8Array => {
const buf = Buffer.alloc(12); const buf = new DataView(new ArrayBuffer(12));
buf.writeFloatLE(x);
buf.writeFloatLE(y, 4); buf.setFloat32(0, x, true);
buf.writeFloatLE(z, 8); buf.setFloat32(4, y, true);
return chunk(0x0000, buf, false); buf.setFloat32(8, z, true);
return chunk(0x0000, new Uint8Array(buf.buffer), false);
}; };
@@ -1,9 +1,11 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (x: number, y: number, z: number): Buffer => { export default (x: number, y: number, z: number): Uint8Array => {
const buf = Buffer.alloc(12); const buf = new DataView(new ArrayBuffer(12));
buf.writeFloatLE(x);
buf.writeFloatLE(y, 4); buf.setFloat32(0, x, true);
buf.writeFloatLE(z, 8); buf.setFloat32(4, y, true);
return chunk(0x0001, buf, false); buf.setFloat32(8, z, true);
return chunk(0x0001, new Uint8Array(buf.buffer), false);
}; };
@@ -1,7 +1,7 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (validity: number): Buffer => { export default (validity: number): Uint8Array => {
const buf = Buffer.alloc(4); const buf = new DataView(new ArrayBuffer(4));
buf.writeFloatLE(validity); buf.setFloat32(0, validity, true);
return chunk(0x0003, buf, false); return chunk(0x0003, new Uint8Array(buf.buffer), false);
}; };
@@ -1,7 +1,7 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (timestamp: bigint): Buffer => { export default (timestamp: bigint): Uint8Array => {
const buf = Buffer.alloc(8); const buf = new DataView(new ArrayBuffer(8));
buf.writeBigUInt64LE(BigInt(timestamp)); buf.setBigUint64(0, BigInt(timestamp), true);
return chunk(0x0006, buf, false); return chunk(0x0006, new Uint8Array(buf.buffer), false);
}; };
@@ -1,9 +1,11 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (x: number, y: number, z: number): Buffer => { export default (x: number, y: number, z: number): Uint8Array => {
const buf = Buffer.alloc(12); const buf = new DataView(new ArrayBuffer(12));
buf.writeFloatLE(x);
buf.writeFloatLE(y, 4); buf.setFloat32(0, x, true);
buf.writeFloatLE(z, 8); buf.setFloat32(4, y, true);
return chunk(0x0005, buf, false); buf.setFloat32(8, z, true);
return chunk(0x0005, new Uint8Array(buf.buffer), false);
}; };
+12 -2
View File
@@ -1,4 +1,14 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (packetHeaderChunk: Buffer, systemNameChunk: Buffer, trackerListChunk: Buffer): Buffer => export default (
chunk(0x6756, Buffer.concat([packetHeaderChunk, systemNameChunk, trackerListChunk]), true); packetHeaderChunk: Uint8Array,
systemNameChunk: Uint8Array,
trackerListChunk: Uint8Array
): Uint8Array => {
const chunkData = new Uint8Array(packetHeaderChunk.length + systemNameChunk.length + trackerListChunk.length);
chunkData.set(packetHeaderChunk);
chunkData.set(systemNameChunk, packetHeaderChunk.length);
chunkData.set(trackerListChunk, packetHeaderChunk.length + systemNameChunk.length);
return chunk(0x6756, chunkData, true);
};
+1 -1
View File
@@ -1,3 +1,3 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (systemName: string): Buffer => chunk(0x0001, Buffer.from(systemName), false); export default (systemName: string): Uint8Array => chunk(0x0001, new TextEncoder().encode(systemName), false);
+2 -1
View File
@@ -1,3 +1,4 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (trackerId: number, trackerNameChunk: Buffer): Buffer => chunk(trackerId, trackerNameChunk, true); export default (trackerId: number, trackerNameChunk: Uint8Array): Uint8Array =>
chunk(trackerId, trackerNameChunk, true);
+17 -1
View File
@@ -1,3 +1,19 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (trackerChunks: Buffer[]): Buffer => chunk(0x0002, Buffer.concat(trackerChunks), true); export default (trackerChunks: Uint8Array[]): Uint8Array => {
let trackerChunksTotalLength = 0;
trackerChunks.forEach((trackerChunk) => {
trackerChunksTotalLength += trackerChunk.length;
});
const trackerChunksBytes = new Uint8Array(trackerChunksTotalLength);
let offset = 0;
trackerChunks.forEach((trackerChunk) => {
trackerChunksBytes.set(trackerChunk, offset);
offset += trackerChunk.length;
});
return chunk(0x0002, trackerChunksBytes, true);
};
+1 -1
View File
@@ -1,3 +1,3 @@
import chunk from '../chunk'; import chunk from '../chunk';
export default (trackerName: string) => chunk(0x0000, Buffer.from(trackerName), false); export default (trackerName: string) => chunk(0x0000, new TextEncoder().encode(trackerName), false);
+8 -8
View File
@@ -6,7 +6,7 @@ export default (
versionLow: number, versionLow: number,
frameId: number, frameId: number,
framePacketCount: number framePacketCount: number
): Buffer => { ): Uint8Array => {
if (!Number.isInteger(versionHigh)) { if (!Number.isInteger(versionHigh)) {
throw new Error('version high must be an integer'); throw new Error('version high must be an integer');
} }
@@ -33,12 +33,12 @@ export default (
throw new Error('frame packet count must be >= 0 and <= 255'); throw new Error('frame packet count must be >= 0 and <= 255');
} }
const packetHeader = Buffer.alloc(12); const packetHeader = new DataView(new ArrayBuffer(12));
packetHeader.writeBigUInt64LE(BigInt(timestamp)); packetHeader.setBigUint64(0, BigInt(timestamp), true);
packetHeader.writeUint8(versionHigh, 8); packetHeader.setUint8(8, versionHigh);
packetHeader.writeUint8(versionLow, 9); packetHeader.setUint8(9, versionLow);
packetHeader.writeUint8(frameId, 10); packetHeader.setUint8(10, frameId);
packetHeader.writeUint8(framePacketCount, 11); packetHeader.setUint8(11, framePacketCount);
return chunk(0x0000, packetHeader, false); return chunk(0x0000, new Uint8Array(packetHeader.buffer), false);
}; };
+1 -1
View File
@@ -2,5 +2,5 @@ export interface Chunk {
id?: number; id?: number;
has_subchunks?: boolean; has_subchunks?: boolean;
data_len?: number; data_len?: number;
chunk_data?: Buffer; chunk_data?: Uint8Array;
} }
+1 -1
View File
@@ -1,5 +1,5 @@
import { Chunk } from '../chunk'; import { Chunk } from '../chunk';
export interface DataTrackerFieldChunk extends Chunk { export interface DataTrackerFieldChunk extends Chunk {
[key: string]: number | bigint | number[] | Buffer | undefined | boolean; [key: string]: number | bigint | number[] | Uint8Array | undefined | boolean;
} }
+1 -1
View File
@@ -61,7 +61,7 @@ export class Tracker {
} }
getDataChunk() { getDataChunk() {
const fieldChunks: Buffer[] = []; const fieldChunks: Uint8Array[] = [];
if (this.pos) { if (this.pos) {
fieldChunks.push(dataTrackerPosChunk(...this.pos)); fieldChunks.push(dataTrackerPosChunk(...this.pos));