@nanolink/mirrors 1.1.74 → 1.1.76
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/README.md +40 -0
- package/dist/MirrorSync.d.ts +8 -0
- package/dist/MirrorSync.js +29 -1
- package/dist/MirrorSync.js.map +1 -1
- package/dist/data64.d.ts +24 -0
- package/dist/data64.js +71 -0
- package/dist/data64.js.map +1 -0
- package/dist/decoders.d.ts +11 -0
- package/dist/decoders.js +23 -0
- package/dist/decoders.js.map +1 -0
- package/dist/definitions/mirrors.d.ts +1 -0
- package/dist/definitions/mirrors.js +1 -0
- package/dist/definitions/mirrors.js.map +1 -1
- package/dist/definitions/opsubscriptions/contained.d.ts +1 -1
- package/dist/definitions/opsubscriptions/contained.js +1 -0
- package/dist/definitions/opsubscriptions/contained.js.map +1 -1
- package/dist/definitions/opsubscriptions/gpsstate.d.ts +1 -1
- package/dist/definitions/opsubscriptions/gpsstate.js +2 -2
- package/dist/definitions/opsubscriptions/index.d.ts +1 -0
- package/dist/definitions/opsubscriptions/index.js +1 -0
- package/dist/definitions/opsubscriptions/index.js.map +1 -1
- package/dist/definitions/opsubscriptions/lostposition.d.ts +1 -1
- package/dist/definitions/opsubscriptions/lostposition.js +1 -1
- package/dist/definitions/opsubscriptions/stateLinks.d.ts +1 -1
- package/dist/definitions/opsubscriptions/stateLinks.js +1 -1
- package/dist/definitions/opsubscriptions/stateRefLinks.d.ts +1 -1
- package/dist/definitions/opsubscriptions/stateRefLinks.js +1 -1
- package/dist/definitions/opsubscriptions/trackerstate.d.ts +1 -1
- package/dist/definitions/opsubscriptions/trackerstate.js +2 -2
- package/dist/definitions/opsubscriptions/triproutes.d.ts +1 -0
- package/dist/definitions/opsubscriptions/triproutes.js +12 -0
- package/dist/definitions/opsubscriptions/triproutes.js.map +1 -0
- package/dist/definitions/opsubscriptions/trips.d.ts +1 -1
- package/dist/definitions/opsubscriptions/trips.js +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/triproute.d.ts +52 -0
- package/dist/triproute.js +135 -0
- package/dist/triproute.js.map +1 -0
- package/dist-compat/index.js +205 -10
- package/dist-compat/index.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ReadonlyMapView } from './DelegateMap';
|
|
2
|
+
/** One position of a trip's route; `speed` is null when the device reported none. */
|
|
3
|
+
export interface RoutePoint {
|
|
4
|
+
stamp: number;
|
|
5
|
+
longitude: number;
|
|
6
|
+
latitude: number;
|
|
7
|
+
speed: number | null;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* One chunk of the route of one trip, keyed `<vid>/<tripStart>/<chunk>`,
|
|
11
|
+
* as the `tripRoutes` mirror holds it.
|
|
12
|
+
*/
|
|
13
|
+
export interface TripRouteItem {
|
|
14
|
+
id: string;
|
|
15
|
+
trackerVID: string;
|
|
16
|
+
tripStart: number;
|
|
17
|
+
chunk: number;
|
|
18
|
+
points: RoutePoint[];
|
|
19
|
+
opVersion: string;
|
|
20
|
+
deleted: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface TripRouteKey {
|
|
23
|
+
trackerVID: string;
|
|
24
|
+
tripStart: number;
|
|
25
|
+
chunk: number;
|
|
26
|
+
}
|
|
27
|
+
/** The mirror key of a chunk: `<vid>/<tripStart>/<chunk>`. */
|
|
28
|
+
export declare function tripRouteKey(trackerVID: string, tripStart: number, chunk: number): string;
|
|
29
|
+
/** The parts of a mirror key, or null when it is not a trip route key. */
|
|
30
|
+
export declare function parseTripRouteKey(id: string): TripRouteKey | null;
|
|
31
|
+
/**
|
|
32
|
+
* The route of one trip: the points of its contiguous chunks from 0, in
|
|
33
|
+
* order, stopping at the first chunk the mirror does not hold.
|
|
34
|
+
*/
|
|
35
|
+
export declare function tripRoute(mirror: ReadonlyMapView<string, any>, trackerVID: string, tripStart: number): RoutePoint[];
|
|
36
|
+
/**
|
|
37
|
+
* Reads a zigzag varint (Go's binary.Varint): LEB128 unsigned, then
|
|
38
|
+
* even -> n/2, odd -> -(n+1)/2.
|
|
39
|
+
*/
|
|
40
|
+
export declare function readVarint(bytes: Uint8Array, offset: number): {
|
|
41
|
+
value: number;
|
|
42
|
+
offset: number;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Decodes a statetriproute record. The value is `[version: 12][count: u16]`
|
|
46
|
+
* and, with a count above 0, the first point absolute (stamp int64 LE,
|
|
47
|
+
* longitude and latitude int32 LE at 1e-7 degrees, speed uint16 LE at
|
|
48
|
+
* 0.1 km/h, 65535 for none) followed by every further point as four zigzag
|
|
49
|
+
* varints: the deltas of the stamp, the longitude, the latitude and the
|
|
50
|
+
* speed, in the same units. The key is `<vid>/<tripStart>/<chunk>`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function decodeTripRouteRecord(key: string, value: Uint8Array): TripRouteItem;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.tripRouteKey = tripRouteKey;
|
|
4
|
+
exports.parseTripRouteKey = parseTripRouteKey;
|
|
5
|
+
exports.tripRoute = tripRoute;
|
|
6
|
+
exports.readVarint = readVarint;
|
|
7
|
+
exports.decodeTripRouteRecord = decodeTripRouteRecord;
|
|
8
|
+
const decoders_1 = require("./decoders");
|
|
9
|
+
const KEY = /^([^/]+)\/(-?\d+)\/(\d+)$/;
|
|
10
|
+
const ROUTE_SPEED_NONE = 65535;
|
|
11
|
+
const ROUTE_COORD_UNIT = 1e7;
|
|
12
|
+
const ROUTE_SPEED_UNIT = 10;
|
|
13
|
+
const HEX = '0123456789abcdef';
|
|
14
|
+
/** The mirror key of a chunk: `<vid>/<tripStart>/<chunk>`. */
|
|
15
|
+
function tripRouteKey(trackerVID, tripStart, chunk) {
|
|
16
|
+
return `${trackerVID}/${tripStart}/${chunk}`;
|
|
17
|
+
}
|
|
18
|
+
/** The parts of a mirror key, or null when it is not a trip route key. */
|
|
19
|
+
function parseTripRouteKey(id) {
|
|
20
|
+
const m = KEY.exec(id);
|
|
21
|
+
if (!m)
|
|
22
|
+
return null;
|
|
23
|
+
return { trackerVID: m[1], tripStart: Number(m[2]), chunk: Number(m[3]) };
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The route of one trip: the points of its contiguous chunks from 0, in
|
|
27
|
+
* order, stopping at the first chunk the mirror does not hold.
|
|
28
|
+
*/
|
|
29
|
+
function tripRoute(mirror, trackerVID, tripStart) {
|
|
30
|
+
const points = [];
|
|
31
|
+
for (let chunk = 0;; chunk++) {
|
|
32
|
+
const item = mirror.get(tripRouteKey(trackerVID, tripStart, chunk));
|
|
33
|
+
if (!item || !Array.isArray(item.points))
|
|
34
|
+
break;
|
|
35
|
+
for (const p of item.points)
|
|
36
|
+
points.push(p);
|
|
37
|
+
}
|
|
38
|
+
return points;
|
|
39
|
+
}
|
|
40
|
+
function hex(bytes, start, end) {
|
|
41
|
+
let s = '';
|
|
42
|
+
for (let i = start; i < end; i++)
|
|
43
|
+
s += HEX[bytes[i] >> 4] + HEX[bytes[i] & 15];
|
|
44
|
+
return s;
|
|
45
|
+
}
|
|
46
|
+
/** int64 LE as a number: two uint32 halves, lo + hi * 2^32 (hi signed). */
|
|
47
|
+
function int64(view, offset) {
|
|
48
|
+
return view.getInt32(offset + 4, true) * 4294967296 + view.getUint32(offset, true);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Reads a zigzag varint (Go's binary.Varint): LEB128 unsigned, then
|
|
52
|
+
* even -> n/2, odd -> -(n+1)/2.
|
|
53
|
+
*/
|
|
54
|
+
function readVarint(bytes, offset) {
|
|
55
|
+
let result = 0;
|
|
56
|
+
let scale = 1;
|
|
57
|
+
let at = offset;
|
|
58
|
+
for (;;) {
|
|
59
|
+
if (at >= bytes.length)
|
|
60
|
+
throw new Error('truncated statetriproute varint');
|
|
61
|
+
const byte = bytes[at++];
|
|
62
|
+
result += (byte & 0x7f) * scale;
|
|
63
|
+
if ((byte & 0x80) === 0)
|
|
64
|
+
break;
|
|
65
|
+
scale *= 128;
|
|
66
|
+
if (scale > Math.pow(2, 56))
|
|
67
|
+
throw new Error('statetriproute varint too long');
|
|
68
|
+
}
|
|
69
|
+
const signed = result % 2 === 0 ? result / 2 : -(result + 1) / 2;
|
|
70
|
+
return { value: signed, offset: at };
|
|
71
|
+
}
|
|
72
|
+
function routePoint(stamp, lon, lat, speed) {
|
|
73
|
+
return {
|
|
74
|
+
stamp,
|
|
75
|
+
longitude: lon / ROUTE_COORD_UNIT,
|
|
76
|
+
latitude: lat / ROUTE_COORD_UNIT,
|
|
77
|
+
speed: speed === ROUTE_SPEED_NONE ? null : speed / ROUTE_SPEED_UNIT,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Decodes a statetriproute record. The value is `[version: 12][count: u16]`
|
|
82
|
+
* and, with a count above 0, the first point absolute (stamp int64 LE,
|
|
83
|
+
* longitude and latitude int32 LE at 1e-7 degrees, speed uint16 LE at
|
|
84
|
+
* 0.1 km/h, 65535 for none) followed by every further point as four zigzag
|
|
85
|
+
* varints: the deltas of the stamp, the longitude, the latitude and the
|
|
86
|
+
* speed, in the same units. The key is `<vid>/<tripStart>/<chunk>`.
|
|
87
|
+
*/
|
|
88
|
+
function decodeTripRouteRecord(key, value) {
|
|
89
|
+
const parsed = parseTripRouteKey(key);
|
|
90
|
+
if (!parsed)
|
|
91
|
+
throw new Error(`invalid statetriproute key: ${key}`);
|
|
92
|
+
if (value.length < 14)
|
|
93
|
+
throw new Error(`statetriproute record too short: ${value.length}`);
|
|
94
|
+
const view = new DataView(value.buffer, value.byteOffset, value.byteLength);
|
|
95
|
+
const count = view.getUint16(12, true);
|
|
96
|
+
const points = [];
|
|
97
|
+
let offset = 14;
|
|
98
|
+
if (count > 0) {
|
|
99
|
+
if (value.length < 32)
|
|
100
|
+
throw new Error('truncated statetriproute first point');
|
|
101
|
+
let stamp = int64(view, 14);
|
|
102
|
+
let lon = view.getInt32(22, true);
|
|
103
|
+
let lat = view.getInt32(26, true);
|
|
104
|
+
let speed = view.getUint16(30, true);
|
|
105
|
+
points.push(routePoint(stamp, lon, lat, speed));
|
|
106
|
+
offset = 32;
|
|
107
|
+
for (let i = 1; i < count; i++) {
|
|
108
|
+
const dStamp = readVarint(value, offset);
|
|
109
|
+
const dLon = readVarint(value, dStamp.offset);
|
|
110
|
+
const dLat = readVarint(value, dLon.offset);
|
|
111
|
+
const dSpeed = readVarint(value, dLat.offset);
|
|
112
|
+
offset = dSpeed.offset;
|
|
113
|
+
stamp += dStamp.value;
|
|
114
|
+
lon += dLon.value;
|
|
115
|
+
lat += dLat.value;
|
|
116
|
+
speed += dSpeed.value;
|
|
117
|
+
if (speed < 0 || speed > ROUTE_SPEED_NONE)
|
|
118
|
+
throw new Error(`statetriproute point ${i} speed out of range`);
|
|
119
|
+
points.push(routePoint(stamp, lon, lat, speed));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (offset !== value.length)
|
|
123
|
+
throw new Error(`statetriproute has ${value.length - offset} trailing bytes`);
|
|
124
|
+
return {
|
|
125
|
+
id: key,
|
|
126
|
+
trackerVID: parsed.trackerVID,
|
|
127
|
+
tripStart: parsed.tripStart,
|
|
128
|
+
chunk: parsed.chunk,
|
|
129
|
+
points,
|
|
130
|
+
opVersion: hex(value, 0, 12),
|
|
131
|
+
deleted: false,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
(0, decoders_1.registerDecoder)('tripRoutes', decodeTripRouteRecord);
|
|
135
|
+
//# sourceMappingURL=triproute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triproute.js","sourceRoot":"","sources":["../src/triproute.ts"],"names":[],"mappings":"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"}
|
package/dist-compat/index.js
CHANGED
|
@@ -71,13 +71,75 @@ __export(index_exports, {
|
|
|
71
71
|
SubscriptionClient: () => SubscriptionClient_default,
|
|
72
72
|
Subscriptions: () => Subscriptions,
|
|
73
73
|
TempSubscriptions: () => TempSubscriptions2,
|
|
74
|
+
decodeTripRouteRecord: () => decodeTripRouteRecord,
|
|
74
75
|
draftMirrors: () => draftMirrors,
|
|
75
|
-
exposedMirrors: () => exposedMirrors
|
|
76
|
+
exposedMirrors: () => exposedMirrors,
|
|
77
|
+
getDecoder: () => getDecoder,
|
|
78
|
+
parseTripRouteKey: () => parseTripRouteKey,
|
|
79
|
+
registerDecoder: () => registerDecoder,
|
|
80
|
+
tripRoute: () => tripRoute,
|
|
81
|
+
tripRouteKey: () => tripRouteKey
|
|
76
82
|
});
|
|
77
83
|
module.exports = __toCommonJS(index_exports);
|
|
78
84
|
|
|
79
85
|
// src/MirrorSync.ts
|
|
80
86
|
var import_eventemitter3 = __toESM(require("eventemitter3"));
|
|
87
|
+
|
|
88
|
+
// src/data64.ts
|
|
89
|
+
function base64ToBytes(data64) {
|
|
90
|
+
if (typeof Buffer !== "undefined" && typeof Buffer.from === "function") {
|
|
91
|
+
const buf = Buffer.from(data64, "base64");
|
|
92
|
+
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
93
|
+
}
|
|
94
|
+
if (typeof atob !== "function") throw new Error("data64: no base64 decoder available");
|
|
95
|
+
const binary = atob(data64);
|
|
96
|
+
const out = new Uint8Array(binary.length);
|
|
97
|
+
for (let i = 0; i < binary.length; i++) out[i] = binary.charCodeAt(i);
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
function utf8(bytes) {
|
|
101
|
+
if (typeof TextDecoder !== "undefined") return new TextDecoder().decode(bytes);
|
|
102
|
+
if (typeof Buffer !== "undefined") return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("utf8");
|
|
103
|
+
let s = "";
|
|
104
|
+
for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);
|
|
105
|
+
return s;
|
|
106
|
+
}
|
|
107
|
+
function readFrames(bytes) {
|
|
108
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
109
|
+
const frames = [];
|
|
110
|
+
let at = 0;
|
|
111
|
+
while (at < bytes.length) {
|
|
112
|
+
if (at + 2 > bytes.length) throw new Error(`data64: truncated key length at ${at}`);
|
|
113
|
+
const keyLength = view.getUint16(at, true);
|
|
114
|
+
at += 2;
|
|
115
|
+
if (at + keyLength + 2 > bytes.length) throw new Error(`data64: truncated key at ${at}`);
|
|
116
|
+
const key = utf8(bytes.subarray(at, at + keyLength));
|
|
117
|
+
at += keyLength;
|
|
118
|
+
const valueLength = view.getUint16(at, true);
|
|
119
|
+
at += 2;
|
|
120
|
+
if (at + valueLength > bytes.length) throw new Error(`data64: truncated value for '${key}' at ${at}`);
|
|
121
|
+
frames.push({ key, value: bytes.subarray(at, at + valueLength) });
|
|
122
|
+
at += valueLength;
|
|
123
|
+
}
|
|
124
|
+
return frames;
|
|
125
|
+
}
|
|
126
|
+
function decodeData64Frames(data64) {
|
|
127
|
+
return readFrames(base64ToBytes(data64));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/decoders.ts
|
|
131
|
+
var decoders = /* @__PURE__ */ new Map();
|
|
132
|
+
function registerDecoder(rootField, decoder) {
|
|
133
|
+
decoders.set(rootField, decoder);
|
|
134
|
+
}
|
|
135
|
+
function getDecoder(rootField) {
|
|
136
|
+
return decoders.get(rootField);
|
|
137
|
+
}
|
|
138
|
+
function decodeData64(data64, decoder) {
|
|
139
|
+
return decodeData64Frames(data64).map((f) => decoder(f.key, f.value));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/MirrorSync.ts
|
|
81
143
|
var MirrorSync = class extends import_eventemitter3.default {
|
|
82
144
|
constructor(client, options) {
|
|
83
145
|
super();
|
|
@@ -250,7 +312,11 @@ var MirrorSync = class extends import_eventemitter3.default {
|
|
|
250
312
|
break;
|
|
251
313
|
}
|
|
252
314
|
case "UPDATED" /* UPDATED */:
|
|
253
|
-
this.applyUpdated(msg.data);
|
|
315
|
+
if (msg.data !== void 0 && msg.data !== null) this.applyUpdated(msg.data);
|
|
316
|
+
if (typeof msg.data64 === "string") {
|
|
317
|
+
const items = this.decodeData64(firstKey, msg.data64);
|
|
318
|
+
if (items) this.applyUpdated(items);
|
|
319
|
+
}
|
|
254
320
|
break;
|
|
255
321
|
case "DELETED" /* DELETED */:
|
|
256
322
|
this.applyDeleted(msg.deleteId, msg.deleteVersion, msg.deleteOpVersion);
|
|
@@ -292,6 +358,26 @@ var MirrorSync = class extends import_eventemitter3.default {
|
|
|
292
358
|
this.subscribeInternal(this.currentVersion, this.currentOpVersion);
|
|
293
359
|
}, 0);
|
|
294
360
|
}
|
|
361
|
+
/**
|
|
362
|
+
* Decodes a `data64` frame through the decoder registered for the root
|
|
363
|
+
* field. No decoder, or a record that does not decode: emits 'error' and
|
|
364
|
+
* returns undefined so the frame is skipped; never throws.
|
|
365
|
+
*/
|
|
366
|
+
decodeData64(rootField, data64) {
|
|
367
|
+
const decoder = getDecoder(rootField);
|
|
368
|
+
if (!decoder) {
|
|
369
|
+
this.l("no data64 decoder", { rootField });
|
|
370
|
+
this.emit("error", new Error(`No data64 decoder registered for root field '${rootField}'`));
|
|
371
|
+
return void 0;
|
|
372
|
+
}
|
|
373
|
+
try {
|
|
374
|
+
return decodeData64(data64, decoder);
|
|
375
|
+
} catch (err) {
|
|
376
|
+
this.l("data64 decode failed", { rootField, err });
|
|
377
|
+
this.emit("error", err);
|
|
378
|
+
return void 0;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
295
381
|
normalizeItems(data) {
|
|
296
382
|
if (!data) return [];
|
|
297
383
|
return Array.isArray(data) ? data : [data];
|
|
@@ -2558,12 +2644,13 @@ var contained = `subscription contained($opVersion: String) {
|
|
|
2558
2644
|
opVersion
|
|
2559
2645
|
}
|
|
2560
2646
|
deleteId
|
|
2647
|
+
deleteOpVersion
|
|
2561
2648
|
}
|
|
2562
2649
|
}`;
|
|
2563
2650
|
|
|
2564
2651
|
// src/definitions/opsubscriptions/gpsstate.ts
|
|
2565
2652
|
var gpsState = `subscription gpsState($opVersion: String) {
|
|
2566
|
-
stateGPSBulk(
|
|
2653
|
+
stateGPSBulk(opversion: $opVersion) {
|
|
2567
2654
|
type
|
|
2568
2655
|
data {
|
|
2569
2656
|
id
|
|
@@ -2577,7 +2664,7 @@ var gpsState = `subscription gpsState($opVersion: String) {
|
|
|
2577
2664
|
opVersion
|
|
2578
2665
|
}
|
|
2579
2666
|
deleteId
|
|
2580
|
-
|
|
2667
|
+
deleteOpVersion
|
|
2581
2668
|
}
|
|
2582
2669
|
}`;
|
|
2583
2670
|
|
|
@@ -2595,7 +2682,7 @@ var lostposition = `subscription lostPosition($opVersion: String) {
|
|
|
2595
2682
|
opVersion
|
|
2596
2683
|
}
|
|
2597
2684
|
deleteId
|
|
2598
|
-
|
|
2685
|
+
deleteOpVersion
|
|
2599
2686
|
}
|
|
2600
2687
|
}`;
|
|
2601
2688
|
|
|
@@ -2614,7 +2701,7 @@ var stateLinks = `subscription stateLink($opVersion: String) {
|
|
|
2614
2701
|
closed
|
|
2615
2702
|
}
|
|
2616
2703
|
deleteId
|
|
2617
|
-
|
|
2704
|
+
deleteOpVersion
|
|
2618
2705
|
}
|
|
2619
2706
|
}`;
|
|
2620
2707
|
|
|
@@ -2631,13 +2718,13 @@ var stateRefLinks = `subscription stateReflink($opVersion: String) {
|
|
|
2631
2718
|
opVersion
|
|
2632
2719
|
}
|
|
2633
2720
|
deleteId
|
|
2634
|
-
|
|
2721
|
+
deleteOpVersion
|
|
2635
2722
|
}
|
|
2636
2723
|
}`;
|
|
2637
2724
|
|
|
2638
2725
|
// src/definitions/opsubscriptions/trackerstate.ts
|
|
2639
2726
|
var trackerState = `subscription trackerState($opVersion: String) {
|
|
2640
|
-
trackerStateBulk(
|
|
2727
|
+
trackerStateBulk(opversion: $opVersion) {
|
|
2641
2728
|
type
|
|
2642
2729
|
data {
|
|
2643
2730
|
id
|
|
@@ -2650,7 +2737,17 @@ var trackerState = `subscription trackerState($opVersion: String) {
|
|
|
2650
2737
|
opVersion
|
|
2651
2738
|
}
|
|
2652
2739
|
deleteId
|
|
2653
|
-
|
|
2740
|
+
deleteOpVersion
|
|
2741
|
+
}
|
|
2742
|
+
}`;
|
|
2743
|
+
|
|
2744
|
+
// src/definitions/opsubscriptions/triproutes.ts
|
|
2745
|
+
var tripRoutes = `subscription tripRoutes($opVersion: String, $trackerVIDs: [String!]) {
|
|
2746
|
+
tripRoutes(opversion: $opVersion, trackerVIDs: $trackerVIDs) {
|
|
2747
|
+
type
|
|
2748
|
+
data64
|
|
2749
|
+
deleteId
|
|
2750
|
+
deleteOpVersion
|
|
2654
2751
|
}
|
|
2655
2752
|
}`;
|
|
2656
2753
|
|
|
@@ -2678,7 +2775,7 @@ var trips2 = `subscription stateTrips($opVersion: String) {
|
|
|
2678
2775
|
opVersion
|
|
2679
2776
|
}
|
|
2680
2777
|
deleteId
|
|
2681
|
-
|
|
2778
|
+
deleteOpVersion
|
|
2682
2779
|
}
|
|
2683
2780
|
}`;
|
|
2684
2781
|
|
|
@@ -2840,6 +2937,7 @@ var OpSubscriptions = {
|
|
|
2840
2937
|
stateLinks,
|
|
2841
2938
|
stateRefLinks,
|
|
2842
2939
|
trackerState,
|
|
2940
|
+
tripRoutes,
|
|
2843
2941
|
trips3: trips2
|
|
2844
2942
|
};
|
|
2845
2943
|
var RequiredMirrors = {
|
|
@@ -3202,6 +3300,103 @@ function draftMirrors() {
|
|
|
3202
3300
|
);
|
|
3203
3301
|
}
|
|
3204
3302
|
|
|
3303
|
+
// src/triproute.ts
|
|
3304
|
+
var KEY = /^([^/]+)\/(-?\d+)\/(\d+)$/;
|
|
3305
|
+
var ROUTE_SPEED_NONE = 65535;
|
|
3306
|
+
var ROUTE_COORD_UNIT = 1e7;
|
|
3307
|
+
var ROUTE_SPEED_UNIT = 10;
|
|
3308
|
+
var HEX = "0123456789abcdef";
|
|
3309
|
+
function tripRouteKey(trackerVID, tripStart, chunk) {
|
|
3310
|
+
return `${trackerVID}/${tripStart}/${chunk}`;
|
|
3311
|
+
}
|
|
3312
|
+
function parseTripRouteKey(id) {
|
|
3313
|
+
const m = KEY.exec(id);
|
|
3314
|
+
if (!m) return null;
|
|
3315
|
+
return { trackerVID: m[1], tripStart: Number(m[2]), chunk: Number(m[3]) };
|
|
3316
|
+
}
|
|
3317
|
+
function tripRoute(mirror, trackerVID, tripStart) {
|
|
3318
|
+
const points = [];
|
|
3319
|
+
for (let chunk = 0; ; chunk++) {
|
|
3320
|
+
const item = mirror.get(tripRouteKey(trackerVID, tripStart, chunk));
|
|
3321
|
+
if (!item || !Array.isArray(item.points)) break;
|
|
3322
|
+
for (const p of item.points) points.push(p);
|
|
3323
|
+
}
|
|
3324
|
+
return points;
|
|
3325
|
+
}
|
|
3326
|
+
function hex(bytes, start, end) {
|
|
3327
|
+
let s = "";
|
|
3328
|
+
for (let i = start; i < end; i++) s += HEX[bytes[i] >> 4] + HEX[bytes[i] & 15];
|
|
3329
|
+
return s;
|
|
3330
|
+
}
|
|
3331
|
+
function int64(view, offset) {
|
|
3332
|
+
return view.getInt32(offset + 4, true) * 4294967296 + view.getUint32(offset, true);
|
|
3333
|
+
}
|
|
3334
|
+
function readVarint(bytes, offset) {
|
|
3335
|
+
let result = 0;
|
|
3336
|
+
let scale = 1;
|
|
3337
|
+
let at = offset;
|
|
3338
|
+
for (; ; ) {
|
|
3339
|
+
if (at >= bytes.length) throw new Error("truncated statetriproute varint");
|
|
3340
|
+
const byte = bytes[at++];
|
|
3341
|
+
result += (byte & 127) * scale;
|
|
3342
|
+
if ((byte & 128) === 0) break;
|
|
3343
|
+
scale *= 128;
|
|
3344
|
+
if (scale > 2 ** 56) throw new Error("statetriproute varint too long");
|
|
3345
|
+
}
|
|
3346
|
+
const signed = result % 2 === 0 ? result / 2 : -(result + 1) / 2;
|
|
3347
|
+
return { value: signed, offset: at };
|
|
3348
|
+
}
|
|
3349
|
+
function routePoint(stamp, lon, lat, speed) {
|
|
3350
|
+
return {
|
|
3351
|
+
stamp,
|
|
3352
|
+
longitude: lon / ROUTE_COORD_UNIT,
|
|
3353
|
+
latitude: lat / ROUTE_COORD_UNIT,
|
|
3354
|
+
speed: speed === ROUTE_SPEED_NONE ? null : speed / ROUTE_SPEED_UNIT
|
|
3355
|
+
};
|
|
3356
|
+
}
|
|
3357
|
+
function decodeTripRouteRecord(key, value) {
|
|
3358
|
+
const parsed = parseTripRouteKey(key);
|
|
3359
|
+
if (!parsed) throw new Error(`invalid statetriproute key: ${key}`);
|
|
3360
|
+
if (value.length < 14) throw new Error(`statetriproute record too short: ${value.length}`);
|
|
3361
|
+
const view = new DataView(value.buffer, value.byteOffset, value.byteLength);
|
|
3362
|
+
const count = view.getUint16(12, true);
|
|
3363
|
+
const points = [];
|
|
3364
|
+
let offset = 14;
|
|
3365
|
+
if (count > 0) {
|
|
3366
|
+
if (value.length < 32) throw new Error("truncated statetriproute first point");
|
|
3367
|
+
let stamp = int64(view, 14);
|
|
3368
|
+
let lon = view.getInt32(22, true);
|
|
3369
|
+
let lat = view.getInt32(26, true);
|
|
3370
|
+
let speed = view.getUint16(30, true);
|
|
3371
|
+
points.push(routePoint(stamp, lon, lat, speed));
|
|
3372
|
+
offset = 32;
|
|
3373
|
+
for (let i = 1; i < count; i++) {
|
|
3374
|
+
const dStamp = readVarint(value, offset);
|
|
3375
|
+
const dLon = readVarint(value, dStamp.offset);
|
|
3376
|
+
const dLat = readVarint(value, dLon.offset);
|
|
3377
|
+
const dSpeed = readVarint(value, dLat.offset);
|
|
3378
|
+
offset = dSpeed.offset;
|
|
3379
|
+
stamp += dStamp.value;
|
|
3380
|
+
lon += dLon.value;
|
|
3381
|
+
lat += dLat.value;
|
|
3382
|
+
speed += dSpeed.value;
|
|
3383
|
+
if (speed < 0 || speed > ROUTE_SPEED_NONE) throw new Error(`statetriproute point ${i} speed out of range`);
|
|
3384
|
+
points.push(routePoint(stamp, lon, lat, speed));
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
if (offset !== value.length) throw new Error(`statetriproute has ${value.length - offset} trailing bytes`);
|
|
3388
|
+
return {
|
|
3389
|
+
id: key,
|
|
3390
|
+
trackerVID: parsed.trackerVID,
|
|
3391
|
+
tripStart: parsed.tripStart,
|
|
3392
|
+
chunk: parsed.chunk,
|
|
3393
|
+
points,
|
|
3394
|
+
opVersion: hex(value, 0, 12),
|
|
3395
|
+
deleted: false
|
|
3396
|
+
};
|
|
3397
|
+
}
|
|
3398
|
+
registerDecoder("tripRoutes", decodeTripRouteRecord);
|
|
3399
|
+
|
|
3205
3400
|
// src/index.ts
|
|
3206
3401
|
var Connection = class extends SubscriptionClient_default {
|
|
3207
3402
|
constructor() {
|