@auxilium/datalynk-client 1.3.21 → 1.4.0

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/dist/api.d.ts CHANGED
@@ -9,6 +9,7 @@ import { ApiCall, Slice } from './slice';
9
9
  import { Socket } from './socket';
10
10
  import { Superuser } from './superuser';
11
11
  import { WebRtc } from './webrtc';
12
+ import { Gps, GpsOptions } from './gps';
12
13
  export type JwtPayload = {
13
14
  aud: string;
14
15
  email: string;
@@ -45,6 +46,8 @@ export type ApiOptions = {
45
46
  serviceWorker?: string;
46
47
  /** Disable sockets with false or override socket URL */
47
48
  socket?: false | string;
49
+ /** GPS live tracking over socket-server/Redis */
50
+ gps?: GpsOptions;
48
51
  /** WebRTC TURN server URL */
49
52
  webrtc?: {
50
53
  /** Additional ICE servers */
@@ -122,6 +125,8 @@ export declare class Api {
122
125
  readonly pwa: PWA;
123
126
  /** Socket */
124
127
  readonly socket: Socket;
128
+ /** GPS */
129
+ readonly gps: Gps;
125
130
  /** Superuser */
126
131
  readonly superuser: Superuser;
127
132
  /** WebRTC */
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
package/dist/gps.d.ts ADDED
@@ -0,0 +1,124 @@
1
+ import { Api } from './api';
2
+ import { Unsubscribe } from './socket';
3
+ /** GPS connection options */
4
+ export type GpsOptions = false | {
5
+ /**
6
+ * Start browser GPS automatically after a token is available.
7
+ * Set false when an app already owns GPS collection and only wants api.gps.send(...).
8
+ */
9
+ autoStart?: boolean;
10
+ /** Dedicated GPS socket URL override. Defaults to the standard socket-server URL */
11
+ socketUrl?: string;
12
+ /** Slice used by socket-server GPS storage */
13
+ slice: number | string;
14
+ /** Field key used by socket-server GPS storage. Default is coords */
15
+ field?: string;
16
+ /**
17
+ * Stable tracking ID for the object/person/vehicle being tracked.
18
+ *
19
+ * If omitted, datalynk-client generates a unique tracker ID for this Gps
20
+ * instance. The default tracking ID is intentionally not based on sessionId,
21
+ * because one logged-in session/device may start more than one active tracker.
22
+ */
23
+ trackingId?: string;
24
+ /** Stable device ID. Default is stored in localStorage */
25
+ deviceId?: string;
26
+ /** Human-readable label passed through to listeners */
27
+ label?: string;
28
+ /** Source/app label passed through to listeners */
29
+ source?: string;
30
+ /** Send a heartbeat even when the GPS position has not changed. Default is 5000 */
31
+ heartbeatMs?: number;
32
+ /** Minimum movement before sending a non-heartbeat update. Default is 3 */
33
+ minDistanceMeters?: number;
34
+ /** Do not send non-heartbeat positions worse than this accuracy. Default is 200 */
35
+ maxAccuracyMeters?: number;
36
+ /** Use browser high-accuracy GPS. Default is true */
37
+ highAccuracy?: boolean;
38
+ /** Browser geolocation timeout. Default is 10000 */
39
+ timeoutMs?: number;
40
+ /** Reject GPS fixes older than this. Default is 4000 */
41
+ maxStaleMs?: number;
42
+ /** Restart watchPosition if no fresh fix arrives. Default is 60000 */
43
+ watchdogMs?: number;
44
+ };
45
+ export type GpsPositionPayload = {
46
+ lat: number;
47
+ lng: number;
48
+ accuracy: number | null;
49
+ altitude: number | null;
50
+ altitudeAccuracy: number | null;
51
+ heading: number | null;
52
+ speed: number | null;
53
+ timestamp: string;
54
+ timestampMs: number;
55
+ };
56
+ export type GpsManualPositionPayload = Omit<Partial<GpsPositionPayload>, 'lat' | 'lng' | 'timestampMs'> & {
57
+ lat?: number | string;
58
+ lng?: number | string;
59
+ lon?: number | string;
60
+ latitude?: number | string;
61
+ longitude?: number | string;
62
+ timestampMs?: number | string;
63
+ };
64
+ export type GpsListenOptions = {
65
+ slice?: number | string;
66
+ field?: string;
67
+ includeTrails?: boolean;
68
+ trailLimit?: number;
69
+ };
70
+ export type GpsListener = (event: any) => any;
71
+ /** Browser/manual GPS sender backed by socket-server Redis GPS storage */
72
+ export declare class Gps {
73
+ private readonly api;
74
+ private deviceId;
75
+ private heartbeat?;
76
+ private lastFixAt;
77
+ private lastPosition?;
78
+ private lastSentAt;
79
+ private lastSentPosition?;
80
+ private pendingPayloads;
81
+ private retryWatchdog?;
82
+ private seq;
83
+ private sessionId;
84
+ private socket?;
85
+ private trackerId;
86
+ private started;
87
+ private unsubs;
88
+ private watchId?;
89
+ private watchStartedAt;
90
+ readonly options?: Exclude<GpsOptions, false>;
91
+ constructor(api: Api, options?: GpsOptions);
92
+ /** Start sharing browser GPS to socket-server */
93
+ start(): void;
94
+ /** Stop sharing GPS and close the dedicated GPS socket */
95
+ stop(): void;
96
+ /** Send a raw GPS message. Useful when an app already has its own GPS engine */
97
+ send(position: GpsManualPositionPayload, extra?: any): void;
98
+ /** Listen to GPS updates for the configured slice/field */
99
+ listen(callback: GpsListener, options?: GpsListenOptions): Unsubscribe;
100
+ private bindResumeEvents;
101
+ private connectSocket;
102
+ private createId;
103
+ private flushPendingPayloads;
104
+ private getClientDetails;
105
+ private getOrCreateDeviceId;
106
+ private getTrackingId;
107
+ private isFresh;
108
+ private metersBetween;
109
+ private normalizeNullableNumber;
110
+ private normalizeOptionalNumber;
111
+ private normalizePosition;
112
+ private onPosition;
113
+ private onPositionError;
114
+ private restartWatch;
115
+ private sendPayload;
116
+ private sendPosition;
117
+ private serializePosition;
118
+ private shouldSendPosition;
119
+ private startHeartbeat;
120
+ private startWatch;
121
+ private startWatchdog;
122
+ private startWhenAuthenticated;
123
+ }
124
+ //# sourceMappingURL=gps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gps.d.ts","sourceRoot":"","sources":["../src/gps.ts"],"names":[],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -2158,10 +2158,12 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2158
2158
  var _a, _b;
2159
2159
  if (this.onlinePrompt) window.removeEventListener("online", this.onlinePrompt);
2160
2160
  if ((_a = this.api.options.offline) == null ? void 0 : _a.length) window.removeEventListener("online", this.onlinePrompt = () => this.handleLogin(spoke, options));
2161
- const urlToken = new URLSearchParams(location.search).get("datalynkToken");
2161
+ const urlParams = new URLSearchParams(location.search);
2162
+ const urlToken = urlParams.getAll("datalynkToken").filter(Boolean).pop();
2162
2163
  if (urlToken) {
2163
2164
  this.api.token = urlToken;
2164
- location.href = location.href.replace(/datalynkToken=.*?(&|$)/gm, "");
2165
+ urlParams.delete("datalynkToken");
2166
+ location.href = location.pathname + (urlParams.toString() ? "?" + urlParams.toString() : "") + location.hash;
2165
2167
  } else if (this.api.token && !this.api.expired) {
2166
2168
  if (((_b = this.api.jwtPayload) == null ? void 0 : _b.realm) != spoke) {
2167
2169
  this.api.token = null;
@@ -3772,7 +3774,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
3772
3774
  } });
3773
3775
  }
3774
3776
  }
3775
- const version = "1.3.21";
3777
+ const version = "1.4.0";
3776
3778
  class WebRtc {
3777
3779
  constructor(api) {
3778
3780
  __publicField(this, "ice");
@@ -3893,6 +3895,360 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
3893
3895
  return session;
3894
3896
  }
3895
3897
  }
3898
+ class Gps {
3899
+ constructor(api, options) {
3900
+ __publicField(this, "deviceId");
3901
+ __publicField(this, "heartbeat");
3902
+ __publicField(this, "lastFixAt", 0);
3903
+ __publicField(this, "lastPosition");
3904
+ __publicField(this, "lastSentAt", 0);
3905
+ __publicField(this, "lastSentPosition");
3906
+ __publicField(this, "pendingPayloads", []);
3907
+ __publicField(this, "retryWatchdog");
3908
+ __publicField(this, "seq", 0);
3909
+ __publicField(this, "sessionId");
3910
+ __publicField(this, "socket");
3911
+ __publicField(this, "trackerId");
3912
+ __publicField(this, "started", false);
3913
+ __publicField(this, "unsubs", []);
3914
+ __publicField(this, "watchId");
3915
+ __publicField(this, "watchStartedAt", 0);
3916
+ __publicField(this, "options");
3917
+ __publicField(this, "onPosition", (position) => {
3918
+ if (!this.options) return;
3919
+ if (!this.isFresh(position)) return;
3920
+ this.lastFixAt = Date.now();
3921
+ this.lastPosition = position;
3922
+ if (this.shouldSendPosition(position, false)) this.sendPosition(position, false);
3923
+ });
3924
+ __publicField(this, "onPositionError", (error) => {
3925
+ console.warn("Datalynk GPS error:", error.message);
3926
+ });
3927
+ this.api = api;
3928
+ if (options === false || options == null) return;
3929
+ this.options = {
3930
+ autoStart: true,
3931
+ field: "coords",
3932
+ heartbeatMs: 5e3,
3933
+ minDistanceMeters: 3,
3934
+ maxAccuracyMeters: 200,
3935
+ highAccuracy: true,
3936
+ timeoutMs: 1e4,
3937
+ maxStaleMs: 4e3,
3938
+ watchdogMs: 6e4,
3939
+ ...options
3940
+ };
3941
+ this.deviceId = this.options.deviceId || this.getOrCreateDeviceId();
3942
+ this.sessionId = this.createId();
3943
+ this.trackerId = this.options.trackingId || this.createId();
3944
+ if (this.options.autoStart !== false) this.startWhenAuthenticated();
3945
+ }
3946
+ /** Start sharing browser GPS to socket-server */
3947
+ start() {
3948
+ if (!this.options) throw new Error("Datalynk GPS is not configured");
3949
+ if (this.started) return;
3950
+ if (!this.api.token) throw new Error("Datalynk GPS cannot start before login");
3951
+ if (typeof navigator == "undefined" || !navigator.geolocation) throw new Error("Browser geolocation is not available");
3952
+ this.started = true;
3953
+ this.connectSocket();
3954
+ this.startWatch();
3955
+ this.startHeartbeat();
3956
+ this.startWatchdog();
3957
+ this.bindResumeEvents();
3958
+ }
3959
+ /** Stop sharing GPS and close the dedicated GPS socket */
3960
+ stop() {
3961
+ var _a;
3962
+ this.started = false;
3963
+ if (this.watchId != null && typeof navigator != "undefined") navigator.geolocation.clearWatch(this.watchId);
3964
+ this.watchId = void 0;
3965
+ if (this.heartbeat) clearInterval(this.heartbeat);
3966
+ this.heartbeat = void 0;
3967
+ if (this.retryWatchdog) clearInterval(this.retryWatchdog);
3968
+ this.retryWatchdog = void 0;
3969
+ this.unsubs.forEach((unsub) => unsub());
3970
+ this.unsubs = [];
3971
+ this.pendingPayloads = [];
3972
+ (_a = this.socket) == null ? void 0 : _a.close();
3973
+ this.socket = void 0;
3974
+ }
3975
+ /** Send a raw GPS message. Useful when an app already has its own GPS engine */
3976
+ send(position, extra = {}) {
3977
+ if (!this.options) throw new Error("Datalynk GPS is not configured");
3978
+ if (!this.api.token) throw new Error("Datalynk GPS cannot send before login");
3979
+ this.connectSocket();
3980
+ this.sendPayload({
3981
+ ...extra,
3982
+ position: this.normalizePosition(position)
3983
+ });
3984
+ }
3985
+ /** Listen to GPS updates for the configured slice/field */
3986
+ listen(callback, options = {}) {
3987
+ if (!this.options) throw new Error("Datalynk GPS is not configured");
3988
+ if (!this.api.token) throw new Error("Datalynk GPS cannot listen before login");
3989
+ this.connectSocket();
3990
+ const request = {
3991
+ gpsListen: {
3992
+ slice: options.slice || this.options.slice,
3993
+ field: options.field || this.options.field || "coords",
3994
+ includeTrails: options.includeTrails ?? false,
3995
+ trailLimit: options.trailLimit ?? 0
3996
+ }
3997
+ };
3998
+ return this.socket.addListener((event) => {
3999
+ var _a, _b;
4000
+ const payload = event;
4001
+ const gps = ((_a = payload == null ? void 0 : payload.data) == null ? void 0 : _a.gps) || (payload == null ? void 0 : payload.gps);
4002
+ if ((payload == null ? void 0 : payload.type) == "sliceEvents" && ((_b = payload == null ? void 0 : payload.data) == null ? void 0 : _b.type) == "gps.position" && gps) callback(gps);
4003
+ else if ((payload == null ? void 0 : payload.type) == "gps.position" && gps) callback(gps);
4004
+ else if ((payload == null ? void 0 : payload.type) == "gpsListen" || (payload == null ? void 0 : payload.gpsListen)) callback(payload);
4005
+ }, () => this.socket.send(request));
4006
+ }
4007
+ bindResumeEvents() {
4008
+ if (typeof window == "undefined" || typeof document == "undefined") return;
4009
+ const restart = () => {
4010
+ if (!this.started) return;
4011
+ if (document.visibilityState && document.visibilityState !== "visible") return;
4012
+ this.restartWatch();
4013
+ };
4014
+ window.addEventListener("focus", restart);
4015
+ window.addEventListener("pageshow", restart);
4016
+ document.addEventListener("visibilitychange", restart);
4017
+ this.unsubs.push(() => {
4018
+ window.removeEventListener("focus", restart);
4019
+ window.removeEventListener("pageshow", restart);
4020
+ document.removeEventListener("visibilitychange", restart);
4021
+ });
4022
+ }
4023
+ connectSocket() {
4024
+ if (!this.options || this.socket) return;
4025
+ if (!this.api.token) throw new Error("Datalynk GPS socket cannot connect before login");
4026
+ this.socket = new Socket(this.api, { url: this.options.socketUrl });
4027
+ this.unsubs.push(this.socket.addListener(() => {
4028
+ }, () => this.flushPendingPayloads()));
4029
+ }
4030
+ createId() {
4031
+ if (typeof crypto != "undefined" && crypto.randomUUID) return crypto.randomUUID();
4032
+ return `${Date.now()}-${Math.random().toString(16).slice(2)}`;
4033
+ }
4034
+ flushPendingPayloads() {
4035
+ var _a;
4036
+ if (!((_a = this.socket) == null ? void 0 : _a.open)) return;
4037
+ while (this.pendingPayloads.length) {
4038
+ this.socket.send(this.pendingPayloads.shift());
4039
+ }
4040
+ }
4041
+ getClientDetails() {
4042
+ if (typeof navigator == "undefined") return {};
4043
+ return {
4044
+ userAgent: navigator.userAgent,
4045
+ language: navigator.language,
4046
+ platform: navigator.platform,
4047
+ vendor: navigator.vendor,
4048
+ screen: typeof screen == "undefined" ? void 0 : {
4049
+ width: screen.width,
4050
+ height: screen.height,
4051
+ pixelRatio: typeof devicePixelRatio == "undefined" ? void 0 : devicePixelRatio
4052
+ },
4053
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
4054
+ };
4055
+ }
4056
+ getOrCreateDeviceId() {
4057
+ const key = "datalynk-gps-device-id";
4058
+ if (typeof localStorage != "undefined") {
4059
+ const existing = localStorage.getItem(key);
4060
+ if (existing) return existing;
4061
+ const id = this.createId();
4062
+ localStorage.setItem(key, id);
4063
+ return id;
4064
+ }
4065
+ return this.createId();
4066
+ }
4067
+ getTrackingId() {
4068
+ var _a;
4069
+ if (!this.options) return this.trackerId || this.createId();
4070
+ if (this.options.trackingId) return this.options.trackingId;
4071
+ const uid = (_a = this.api.jwtPayload) == null ? void 0 : _a.uid;
4072
+ return uid ? `user:${uid}:tracker:${this.trackerId}` : `device:${this.deviceId}:tracker:${this.trackerId}`;
4073
+ }
4074
+ isFresh(position) {
4075
+ if (!this.options) return false;
4076
+ if (this.lastPosition && position.timestamp <= this.lastPosition.timestamp) return false;
4077
+ return Date.now() - position.timestamp <= (this.options.maxStaleMs || 4e3);
4078
+ }
4079
+ metersBetween(a, b) {
4080
+ const earthRadius = 6371e3;
4081
+ const lat1 = a.coords.latitude * Math.PI / 180;
4082
+ const lat2 = b.coords.latitude * Math.PI / 180;
4083
+ const dLat = (b.coords.latitude - a.coords.latitude) * Math.PI / 180;
4084
+ const dLng = (b.coords.longitude - a.coords.longitude) * Math.PI / 180;
4085
+ const x = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLng / 2) * Math.sin(dLng / 2);
4086
+ return earthRadius * 2 * Math.atan2(Math.sqrt(x), Math.sqrt(1 - x));
4087
+ }
4088
+ normalizeNullableNumber(value, field) {
4089
+ if (value == null || value === "") return null;
4090
+ const number = Number(value);
4091
+ if (!Number.isFinite(number)) throw new Error(`GPS ${field} must be a valid number`);
4092
+ return number;
4093
+ }
4094
+ normalizeOptionalNumber(value, field) {
4095
+ if (value == null || value === "") return void 0;
4096
+ const number = Number(value);
4097
+ if (!Number.isFinite(number)) throw new Error(`GPS ${field} must be a valid number`);
4098
+ return number;
4099
+ }
4100
+ normalizePosition(position) {
4101
+ const lat = Number(position.lat ?? position.latitude);
4102
+ const lng = Number(position.lng ?? position.lon ?? position.longitude);
4103
+ if (!Number.isFinite(lat) || lat < -90 || lat > 90) {
4104
+ throw new Error("GPS position must include a valid lat/latitude between -90 and 90");
4105
+ }
4106
+ if (!Number.isFinite(lng) || lng < -180 || lng > 180) {
4107
+ throw new Error("GPS position must include a valid lng/lon/longitude between -180 and 180");
4108
+ }
4109
+ const accuracy = this.normalizeNullableNumber(position.accuracy, "accuracy");
4110
+ if (accuracy != null && accuracy < 0) throw new Error("GPS accuracy must be zero or greater");
4111
+ const altitude = this.normalizeNullableNumber(position.altitude, "altitude");
4112
+ const altitudeAccuracy = this.normalizeNullableNumber(position.altitudeAccuracy, "altitudeAccuracy");
4113
+ if (altitudeAccuracy != null && altitudeAccuracy < 0) throw new Error("GPS altitudeAccuracy must be zero or greater");
4114
+ const heading = this.normalizeNullableNumber(position.heading, "heading");
4115
+ if (heading != null && (heading < 0 || heading >= 360)) throw new Error("GPS heading must be between 0 and 360");
4116
+ const speed = this.normalizeNullableNumber(position.speed, "speed");
4117
+ if (speed != null && speed < 0) throw new Error("GPS speed must be zero or greater");
4118
+ const timestampMs = this.normalizeOptionalNumber(position.timestampMs, "timestampMs") ?? Date.now();
4119
+ if (timestampMs <= 0) throw new Error("GPS timestampMs must be greater than zero");
4120
+ let timestamp = position.timestamp;
4121
+ if (timestamp) {
4122
+ const parsed = Date.parse(timestamp);
4123
+ if (!Number.isFinite(parsed)) throw new Error("GPS timestamp must be a valid date string");
4124
+ } else {
4125
+ timestamp = new Date(timestampMs).toISOString();
4126
+ }
4127
+ return {
4128
+ lat,
4129
+ lng,
4130
+ accuracy,
4131
+ altitude,
4132
+ altitudeAccuracy,
4133
+ heading,
4134
+ speed,
4135
+ timestamp,
4136
+ timestampMs
4137
+ };
4138
+ }
4139
+ restartWatch() {
4140
+ if (!this.options || !this.started || typeof navigator == "undefined" || !navigator.geolocation) return;
4141
+ if (this.watchId != null) navigator.geolocation.clearWatch(this.watchId);
4142
+ this.watchId = void 0;
4143
+ this.startWatch();
4144
+ }
4145
+ sendPayload(payload) {
4146
+ var _a, _b;
4147
+ if (!this.options) return;
4148
+ this.connectSocket();
4149
+ const message = {
4150
+ gps: {
4151
+ slice: this.options.slice,
4152
+ field: this.options.field || "coords",
4153
+ trackingId: this.getTrackingId(),
4154
+ trackerId: this.trackerId,
4155
+ sessionId: this.sessionId,
4156
+ deviceId: this.deviceId,
4157
+ seq: ++this.seq,
4158
+ client: this.getClientDetails(),
4159
+ sentAt: (/* @__PURE__ */ new Date()).toISOString(),
4160
+ gpsTimestamp: ((_a = payload.position) == null ? void 0 : _a.timestamp) || null,
4161
+ label: this.options.label,
4162
+ source: this.options.source,
4163
+ ...payload
4164
+ }
4165
+ };
4166
+ if (!((_b = this.socket) == null ? void 0 : _b.open)) {
4167
+ this.pendingPayloads.push(message);
4168
+ this.pendingPayloads = this.pendingPayloads.slice(-25);
4169
+ return;
4170
+ }
4171
+ this.socket.send(message);
4172
+ }
4173
+ sendPosition(position, force) {
4174
+ this.sendPayload({
4175
+ force,
4176
+ position: this.serializePosition(position)
4177
+ });
4178
+ this.lastSentPosition = position;
4179
+ this.lastSentAt = Date.now();
4180
+ }
4181
+ serializePosition(position) {
4182
+ return {
4183
+ lat: position.coords.latitude,
4184
+ lng: position.coords.longitude,
4185
+ accuracy: position.coords.accuracy,
4186
+ altitude: position.coords.altitude,
4187
+ altitudeAccuracy: position.coords.altitudeAccuracy,
4188
+ heading: position.coords.heading,
4189
+ speed: position.coords.speed,
4190
+ timestamp: new Date(position.timestamp).toISOString(),
4191
+ timestampMs: position.timestamp
4192
+ };
4193
+ }
4194
+ shouldSendPosition(position, force) {
4195
+ if (!this.options) return false;
4196
+ if (force) return true;
4197
+ const accuracy = Number(position.coords.accuracy || 0);
4198
+ if (accuracy && accuracy > (this.options.maxAccuracyMeters || 200)) return false;
4199
+ if (!this.lastSentPosition) return true;
4200
+ const movedMeters = this.metersBetween(this.lastSentPosition, position);
4201
+ const accuracyImproved = Number(position.coords.accuracy || 999999) < Number(this.lastSentPosition.coords.accuracy || 999999);
4202
+ const heartbeatDue = Date.now() - this.lastSentAt >= (this.options.heartbeatMs || 5e3);
4203
+ return movedMeters >= (this.options.minDistanceMeters || 3) || accuracyImproved || heartbeatDue;
4204
+ }
4205
+ startHeartbeat() {
4206
+ if (!this.options || this.heartbeat) return;
4207
+ this.heartbeat = setInterval(() => {
4208
+ if (!this.started || !this.lastPosition) return;
4209
+ this.sendPosition(this.lastPosition, true);
4210
+ }, this.options.heartbeatMs || 5e3);
4211
+ }
4212
+ startWatch() {
4213
+ if (!this.options || this.watchId != null) return;
4214
+ this.watchStartedAt = Date.now();
4215
+ this.watchId = navigator.geolocation.watchPosition(this.onPosition, this.onPositionError, {
4216
+ enableHighAccuracy: this.options.highAccuracy !== false,
4217
+ maximumAge: 0,
4218
+ timeout: this.options.timeoutMs || 1e4
4219
+ });
4220
+ }
4221
+ startWatchdog() {
4222
+ if (!this.options || this.retryWatchdog) return;
4223
+ this.retryWatchdog = setInterval(() => {
4224
+ if (!this.started) return;
4225
+ const lastActivity = this.lastFixAt || this.watchStartedAt;
4226
+ if (lastActivity && Date.now() - lastActivity >= (this.options.watchdogMs || 6e4)) this.restartWatch();
4227
+ }, Math.min(this.options.watchdogMs || 6e4, 15e3));
4228
+ }
4229
+ startWhenAuthenticated() {
4230
+ if (!this.options) return;
4231
+ if (this.api.token) {
4232
+ setTimeout(() => {
4233
+ try {
4234
+ this.start();
4235
+ } catch (error) {
4236
+ console.warn("Datalynk GPS auto-start failed:", error);
4237
+ }
4238
+ }, 0);
4239
+ return;
4240
+ }
4241
+ const sub = this.api.token$.subscribe((token) => {
4242
+ if (!token || this.started || !this.options || this.options.autoStart === false) return;
4243
+ try {
4244
+ this.start();
4245
+ } catch (error) {
4246
+ console.warn("Datalynk GPS auto-start failed:", error);
4247
+ }
4248
+ });
4249
+ this.unsubs.push(() => sub.unsubscribe());
4250
+ }
4251
+ }
3896
4252
  const _Api = class _Api {
3897
4253
  /**
3898
4254
  * Connect to Datalynk & send requests
@@ -3931,6 +4287,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
3931
4287
  __publicField(this, "pwa");
3932
4288
  /** Socket */
3933
4289
  __publicField(this, "socket");
4290
+ /** GPS */
4291
+ __publicField(this, "gps");
3934
4292
  /** Superuser */
3935
4293
  __publicField(this, "superuser");
3936
4294
  /** WebRTC */
@@ -3976,6 +4334,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
3976
4334
  });
3977
4335
  }
3978
4336
  this.socket = new Socket(this, { url: options.socket });
4337
+ this.gps = new Gps(this, options.gps);
3979
4338
  this.auth = new Auth(this);
3980
4339
  this.files = new Files(this);
3981
4340
  this.pdf = new Pdf(this);
@@ -4281,6 +4640,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4281
4640
  exports2.ApiCall = ApiCall;
4282
4641
  exports2.Auth = Auth;
4283
4642
  exports2.Files = Files;
4643
+ exports2.Gps = Gps;
4284
4644
  exports2.LoginPrompt = LoginPrompt;
4285
4645
  exports2.PWA = PWA;
4286
4646
  exports2.Pdf = Pdf;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './api';
2
2
  export * from './auth';
3
3
  export * from './files';
4
+ export * from './gps';
4
5
  export * from './login-prompt';
5
6
  export * from './meta';
6
7
  export * from './pdf';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC"}
package/dist/index.mjs CHANGED
@@ -2154,10 +2154,12 @@ class Auth {
2154
2154
  var _a, _b;
2155
2155
  if (this.onlinePrompt) window.removeEventListener("online", this.onlinePrompt);
2156
2156
  if ((_a = this.api.options.offline) == null ? void 0 : _a.length) window.removeEventListener("online", this.onlinePrompt = () => this.handleLogin(spoke, options));
2157
- const urlToken = new URLSearchParams(location.search).get("datalynkToken");
2157
+ const urlParams = new URLSearchParams(location.search);
2158
+ const urlToken = urlParams.getAll("datalynkToken").filter(Boolean).pop();
2158
2159
  if (urlToken) {
2159
2160
  this.api.token = urlToken;
2160
- location.href = location.href.replace(/datalynkToken=.*?(&|$)/gm, "");
2161
+ urlParams.delete("datalynkToken");
2162
+ location.href = location.pathname + (urlParams.toString() ? "?" + urlParams.toString() : "") + location.hash;
2161
2163
  } else if (this.api.token && !this.api.expired) {
2162
2164
  if (((_b = this.api.jwtPayload) == null ? void 0 : _b.realm) != spoke) {
2163
2165
  this.api.token = null;
@@ -3768,7 +3770,7 @@ class Superuser {
3768
3770
  } });
3769
3771
  }
3770
3772
  }
3771
- const version = "1.3.21";
3773
+ const version = "1.4.0";
3772
3774
  class WebRtc {
3773
3775
  constructor(api) {
3774
3776
  __publicField(this, "ice");
@@ -3889,6 +3891,360 @@ class WebRtc {
3889
3891
  return session;
3890
3892
  }
3891
3893
  }
3894
+ class Gps {
3895
+ constructor(api, options) {
3896
+ __publicField(this, "deviceId");
3897
+ __publicField(this, "heartbeat");
3898
+ __publicField(this, "lastFixAt", 0);
3899
+ __publicField(this, "lastPosition");
3900
+ __publicField(this, "lastSentAt", 0);
3901
+ __publicField(this, "lastSentPosition");
3902
+ __publicField(this, "pendingPayloads", []);
3903
+ __publicField(this, "retryWatchdog");
3904
+ __publicField(this, "seq", 0);
3905
+ __publicField(this, "sessionId");
3906
+ __publicField(this, "socket");
3907
+ __publicField(this, "trackerId");
3908
+ __publicField(this, "started", false);
3909
+ __publicField(this, "unsubs", []);
3910
+ __publicField(this, "watchId");
3911
+ __publicField(this, "watchStartedAt", 0);
3912
+ __publicField(this, "options");
3913
+ __publicField(this, "onPosition", (position) => {
3914
+ if (!this.options) return;
3915
+ if (!this.isFresh(position)) return;
3916
+ this.lastFixAt = Date.now();
3917
+ this.lastPosition = position;
3918
+ if (this.shouldSendPosition(position, false)) this.sendPosition(position, false);
3919
+ });
3920
+ __publicField(this, "onPositionError", (error) => {
3921
+ console.warn("Datalynk GPS error:", error.message);
3922
+ });
3923
+ this.api = api;
3924
+ if (options === false || options == null) return;
3925
+ this.options = {
3926
+ autoStart: true,
3927
+ field: "coords",
3928
+ heartbeatMs: 5e3,
3929
+ minDistanceMeters: 3,
3930
+ maxAccuracyMeters: 200,
3931
+ highAccuracy: true,
3932
+ timeoutMs: 1e4,
3933
+ maxStaleMs: 4e3,
3934
+ watchdogMs: 6e4,
3935
+ ...options
3936
+ };
3937
+ this.deviceId = this.options.deviceId || this.getOrCreateDeviceId();
3938
+ this.sessionId = this.createId();
3939
+ this.trackerId = this.options.trackingId || this.createId();
3940
+ if (this.options.autoStart !== false) this.startWhenAuthenticated();
3941
+ }
3942
+ /** Start sharing browser GPS to socket-server */
3943
+ start() {
3944
+ if (!this.options) throw new Error("Datalynk GPS is not configured");
3945
+ if (this.started) return;
3946
+ if (!this.api.token) throw new Error("Datalynk GPS cannot start before login");
3947
+ if (typeof navigator == "undefined" || !navigator.geolocation) throw new Error("Browser geolocation is not available");
3948
+ this.started = true;
3949
+ this.connectSocket();
3950
+ this.startWatch();
3951
+ this.startHeartbeat();
3952
+ this.startWatchdog();
3953
+ this.bindResumeEvents();
3954
+ }
3955
+ /** Stop sharing GPS and close the dedicated GPS socket */
3956
+ stop() {
3957
+ var _a;
3958
+ this.started = false;
3959
+ if (this.watchId != null && typeof navigator != "undefined") navigator.geolocation.clearWatch(this.watchId);
3960
+ this.watchId = void 0;
3961
+ if (this.heartbeat) clearInterval(this.heartbeat);
3962
+ this.heartbeat = void 0;
3963
+ if (this.retryWatchdog) clearInterval(this.retryWatchdog);
3964
+ this.retryWatchdog = void 0;
3965
+ this.unsubs.forEach((unsub) => unsub());
3966
+ this.unsubs = [];
3967
+ this.pendingPayloads = [];
3968
+ (_a = this.socket) == null ? void 0 : _a.close();
3969
+ this.socket = void 0;
3970
+ }
3971
+ /** Send a raw GPS message. Useful when an app already has its own GPS engine */
3972
+ send(position, extra = {}) {
3973
+ if (!this.options) throw new Error("Datalynk GPS is not configured");
3974
+ if (!this.api.token) throw new Error("Datalynk GPS cannot send before login");
3975
+ this.connectSocket();
3976
+ this.sendPayload({
3977
+ ...extra,
3978
+ position: this.normalizePosition(position)
3979
+ });
3980
+ }
3981
+ /** Listen to GPS updates for the configured slice/field */
3982
+ listen(callback, options = {}) {
3983
+ if (!this.options) throw new Error("Datalynk GPS is not configured");
3984
+ if (!this.api.token) throw new Error("Datalynk GPS cannot listen before login");
3985
+ this.connectSocket();
3986
+ const request = {
3987
+ gpsListen: {
3988
+ slice: options.slice || this.options.slice,
3989
+ field: options.field || this.options.field || "coords",
3990
+ includeTrails: options.includeTrails ?? false,
3991
+ trailLimit: options.trailLimit ?? 0
3992
+ }
3993
+ };
3994
+ return this.socket.addListener((event) => {
3995
+ var _a, _b;
3996
+ const payload = event;
3997
+ const gps = ((_a = payload == null ? void 0 : payload.data) == null ? void 0 : _a.gps) || (payload == null ? void 0 : payload.gps);
3998
+ if ((payload == null ? void 0 : payload.type) == "sliceEvents" && ((_b = payload == null ? void 0 : payload.data) == null ? void 0 : _b.type) == "gps.position" && gps) callback(gps);
3999
+ else if ((payload == null ? void 0 : payload.type) == "gps.position" && gps) callback(gps);
4000
+ else if ((payload == null ? void 0 : payload.type) == "gpsListen" || (payload == null ? void 0 : payload.gpsListen)) callback(payload);
4001
+ }, () => this.socket.send(request));
4002
+ }
4003
+ bindResumeEvents() {
4004
+ if (typeof window == "undefined" || typeof document == "undefined") return;
4005
+ const restart = () => {
4006
+ if (!this.started) return;
4007
+ if (document.visibilityState && document.visibilityState !== "visible") return;
4008
+ this.restartWatch();
4009
+ };
4010
+ window.addEventListener("focus", restart);
4011
+ window.addEventListener("pageshow", restart);
4012
+ document.addEventListener("visibilitychange", restart);
4013
+ this.unsubs.push(() => {
4014
+ window.removeEventListener("focus", restart);
4015
+ window.removeEventListener("pageshow", restart);
4016
+ document.removeEventListener("visibilitychange", restart);
4017
+ });
4018
+ }
4019
+ connectSocket() {
4020
+ if (!this.options || this.socket) return;
4021
+ if (!this.api.token) throw new Error("Datalynk GPS socket cannot connect before login");
4022
+ this.socket = new Socket(this.api, { url: this.options.socketUrl });
4023
+ this.unsubs.push(this.socket.addListener(() => {
4024
+ }, () => this.flushPendingPayloads()));
4025
+ }
4026
+ createId() {
4027
+ if (typeof crypto != "undefined" && crypto.randomUUID) return crypto.randomUUID();
4028
+ return `${Date.now()}-${Math.random().toString(16).slice(2)}`;
4029
+ }
4030
+ flushPendingPayloads() {
4031
+ var _a;
4032
+ if (!((_a = this.socket) == null ? void 0 : _a.open)) return;
4033
+ while (this.pendingPayloads.length) {
4034
+ this.socket.send(this.pendingPayloads.shift());
4035
+ }
4036
+ }
4037
+ getClientDetails() {
4038
+ if (typeof navigator == "undefined") return {};
4039
+ return {
4040
+ userAgent: navigator.userAgent,
4041
+ language: navigator.language,
4042
+ platform: navigator.platform,
4043
+ vendor: navigator.vendor,
4044
+ screen: typeof screen == "undefined" ? void 0 : {
4045
+ width: screen.width,
4046
+ height: screen.height,
4047
+ pixelRatio: typeof devicePixelRatio == "undefined" ? void 0 : devicePixelRatio
4048
+ },
4049
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
4050
+ };
4051
+ }
4052
+ getOrCreateDeviceId() {
4053
+ const key = "datalynk-gps-device-id";
4054
+ if (typeof localStorage != "undefined") {
4055
+ const existing = localStorage.getItem(key);
4056
+ if (existing) return existing;
4057
+ const id = this.createId();
4058
+ localStorage.setItem(key, id);
4059
+ return id;
4060
+ }
4061
+ return this.createId();
4062
+ }
4063
+ getTrackingId() {
4064
+ var _a;
4065
+ if (!this.options) return this.trackerId || this.createId();
4066
+ if (this.options.trackingId) return this.options.trackingId;
4067
+ const uid = (_a = this.api.jwtPayload) == null ? void 0 : _a.uid;
4068
+ return uid ? `user:${uid}:tracker:${this.trackerId}` : `device:${this.deviceId}:tracker:${this.trackerId}`;
4069
+ }
4070
+ isFresh(position) {
4071
+ if (!this.options) return false;
4072
+ if (this.lastPosition && position.timestamp <= this.lastPosition.timestamp) return false;
4073
+ return Date.now() - position.timestamp <= (this.options.maxStaleMs || 4e3);
4074
+ }
4075
+ metersBetween(a, b) {
4076
+ const earthRadius = 6371e3;
4077
+ const lat1 = a.coords.latitude * Math.PI / 180;
4078
+ const lat2 = b.coords.latitude * Math.PI / 180;
4079
+ const dLat = (b.coords.latitude - a.coords.latitude) * Math.PI / 180;
4080
+ const dLng = (b.coords.longitude - a.coords.longitude) * Math.PI / 180;
4081
+ const x = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLng / 2) * Math.sin(dLng / 2);
4082
+ return earthRadius * 2 * Math.atan2(Math.sqrt(x), Math.sqrt(1 - x));
4083
+ }
4084
+ normalizeNullableNumber(value, field) {
4085
+ if (value == null || value === "") return null;
4086
+ const number = Number(value);
4087
+ if (!Number.isFinite(number)) throw new Error(`GPS ${field} must be a valid number`);
4088
+ return number;
4089
+ }
4090
+ normalizeOptionalNumber(value, field) {
4091
+ if (value == null || value === "") return void 0;
4092
+ const number = Number(value);
4093
+ if (!Number.isFinite(number)) throw new Error(`GPS ${field} must be a valid number`);
4094
+ return number;
4095
+ }
4096
+ normalizePosition(position) {
4097
+ const lat = Number(position.lat ?? position.latitude);
4098
+ const lng = Number(position.lng ?? position.lon ?? position.longitude);
4099
+ if (!Number.isFinite(lat) || lat < -90 || lat > 90) {
4100
+ throw new Error("GPS position must include a valid lat/latitude between -90 and 90");
4101
+ }
4102
+ if (!Number.isFinite(lng) || lng < -180 || lng > 180) {
4103
+ throw new Error("GPS position must include a valid lng/lon/longitude between -180 and 180");
4104
+ }
4105
+ const accuracy = this.normalizeNullableNumber(position.accuracy, "accuracy");
4106
+ if (accuracy != null && accuracy < 0) throw new Error("GPS accuracy must be zero or greater");
4107
+ const altitude = this.normalizeNullableNumber(position.altitude, "altitude");
4108
+ const altitudeAccuracy = this.normalizeNullableNumber(position.altitudeAccuracy, "altitudeAccuracy");
4109
+ if (altitudeAccuracy != null && altitudeAccuracy < 0) throw new Error("GPS altitudeAccuracy must be zero or greater");
4110
+ const heading = this.normalizeNullableNumber(position.heading, "heading");
4111
+ if (heading != null && (heading < 0 || heading >= 360)) throw new Error("GPS heading must be between 0 and 360");
4112
+ const speed = this.normalizeNullableNumber(position.speed, "speed");
4113
+ if (speed != null && speed < 0) throw new Error("GPS speed must be zero or greater");
4114
+ const timestampMs = this.normalizeOptionalNumber(position.timestampMs, "timestampMs") ?? Date.now();
4115
+ if (timestampMs <= 0) throw new Error("GPS timestampMs must be greater than zero");
4116
+ let timestamp = position.timestamp;
4117
+ if (timestamp) {
4118
+ const parsed = Date.parse(timestamp);
4119
+ if (!Number.isFinite(parsed)) throw new Error("GPS timestamp must be a valid date string");
4120
+ } else {
4121
+ timestamp = new Date(timestampMs).toISOString();
4122
+ }
4123
+ return {
4124
+ lat,
4125
+ lng,
4126
+ accuracy,
4127
+ altitude,
4128
+ altitudeAccuracy,
4129
+ heading,
4130
+ speed,
4131
+ timestamp,
4132
+ timestampMs
4133
+ };
4134
+ }
4135
+ restartWatch() {
4136
+ if (!this.options || !this.started || typeof navigator == "undefined" || !navigator.geolocation) return;
4137
+ if (this.watchId != null) navigator.geolocation.clearWatch(this.watchId);
4138
+ this.watchId = void 0;
4139
+ this.startWatch();
4140
+ }
4141
+ sendPayload(payload) {
4142
+ var _a, _b;
4143
+ if (!this.options) return;
4144
+ this.connectSocket();
4145
+ const message = {
4146
+ gps: {
4147
+ slice: this.options.slice,
4148
+ field: this.options.field || "coords",
4149
+ trackingId: this.getTrackingId(),
4150
+ trackerId: this.trackerId,
4151
+ sessionId: this.sessionId,
4152
+ deviceId: this.deviceId,
4153
+ seq: ++this.seq,
4154
+ client: this.getClientDetails(),
4155
+ sentAt: (/* @__PURE__ */ new Date()).toISOString(),
4156
+ gpsTimestamp: ((_a = payload.position) == null ? void 0 : _a.timestamp) || null,
4157
+ label: this.options.label,
4158
+ source: this.options.source,
4159
+ ...payload
4160
+ }
4161
+ };
4162
+ if (!((_b = this.socket) == null ? void 0 : _b.open)) {
4163
+ this.pendingPayloads.push(message);
4164
+ this.pendingPayloads = this.pendingPayloads.slice(-25);
4165
+ return;
4166
+ }
4167
+ this.socket.send(message);
4168
+ }
4169
+ sendPosition(position, force) {
4170
+ this.sendPayload({
4171
+ force,
4172
+ position: this.serializePosition(position)
4173
+ });
4174
+ this.lastSentPosition = position;
4175
+ this.lastSentAt = Date.now();
4176
+ }
4177
+ serializePosition(position) {
4178
+ return {
4179
+ lat: position.coords.latitude,
4180
+ lng: position.coords.longitude,
4181
+ accuracy: position.coords.accuracy,
4182
+ altitude: position.coords.altitude,
4183
+ altitudeAccuracy: position.coords.altitudeAccuracy,
4184
+ heading: position.coords.heading,
4185
+ speed: position.coords.speed,
4186
+ timestamp: new Date(position.timestamp).toISOString(),
4187
+ timestampMs: position.timestamp
4188
+ };
4189
+ }
4190
+ shouldSendPosition(position, force) {
4191
+ if (!this.options) return false;
4192
+ if (force) return true;
4193
+ const accuracy = Number(position.coords.accuracy || 0);
4194
+ if (accuracy && accuracy > (this.options.maxAccuracyMeters || 200)) return false;
4195
+ if (!this.lastSentPosition) return true;
4196
+ const movedMeters = this.metersBetween(this.lastSentPosition, position);
4197
+ const accuracyImproved = Number(position.coords.accuracy || 999999) < Number(this.lastSentPosition.coords.accuracy || 999999);
4198
+ const heartbeatDue = Date.now() - this.lastSentAt >= (this.options.heartbeatMs || 5e3);
4199
+ return movedMeters >= (this.options.minDistanceMeters || 3) || accuracyImproved || heartbeatDue;
4200
+ }
4201
+ startHeartbeat() {
4202
+ if (!this.options || this.heartbeat) return;
4203
+ this.heartbeat = setInterval(() => {
4204
+ if (!this.started || !this.lastPosition) return;
4205
+ this.sendPosition(this.lastPosition, true);
4206
+ }, this.options.heartbeatMs || 5e3);
4207
+ }
4208
+ startWatch() {
4209
+ if (!this.options || this.watchId != null) return;
4210
+ this.watchStartedAt = Date.now();
4211
+ this.watchId = navigator.geolocation.watchPosition(this.onPosition, this.onPositionError, {
4212
+ enableHighAccuracy: this.options.highAccuracy !== false,
4213
+ maximumAge: 0,
4214
+ timeout: this.options.timeoutMs || 1e4
4215
+ });
4216
+ }
4217
+ startWatchdog() {
4218
+ if (!this.options || this.retryWatchdog) return;
4219
+ this.retryWatchdog = setInterval(() => {
4220
+ if (!this.started) return;
4221
+ const lastActivity = this.lastFixAt || this.watchStartedAt;
4222
+ if (lastActivity && Date.now() - lastActivity >= (this.options.watchdogMs || 6e4)) this.restartWatch();
4223
+ }, Math.min(this.options.watchdogMs || 6e4, 15e3));
4224
+ }
4225
+ startWhenAuthenticated() {
4226
+ if (!this.options) return;
4227
+ if (this.api.token) {
4228
+ setTimeout(() => {
4229
+ try {
4230
+ this.start();
4231
+ } catch (error) {
4232
+ console.warn("Datalynk GPS auto-start failed:", error);
4233
+ }
4234
+ }, 0);
4235
+ return;
4236
+ }
4237
+ const sub = this.api.token$.subscribe((token) => {
4238
+ if (!token || this.started || !this.options || this.options.autoStart === false) return;
4239
+ try {
4240
+ this.start();
4241
+ } catch (error) {
4242
+ console.warn("Datalynk GPS auto-start failed:", error);
4243
+ }
4244
+ });
4245
+ this.unsubs.push(() => sub.unsubscribe());
4246
+ }
4247
+ }
3892
4248
  const _Api = class _Api {
3893
4249
  /**
3894
4250
  * Connect to Datalynk & send requests
@@ -3927,6 +4283,8 @@ const _Api = class _Api {
3927
4283
  __publicField(this, "pwa");
3928
4284
  /** Socket */
3929
4285
  __publicField(this, "socket");
4286
+ /** GPS */
4287
+ __publicField(this, "gps");
3930
4288
  /** Superuser */
3931
4289
  __publicField(this, "superuser");
3932
4290
  /** WebRTC */
@@ -3972,6 +4330,7 @@ const _Api = class _Api {
3972
4330
  });
3973
4331
  }
3974
4332
  this.socket = new Socket(this, { url: options.socket });
4333
+ this.gps = new Gps(this, options.gps);
3975
4334
  this.auth = new Auth(this);
3976
4335
  this.files = new Files(this);
3977
4336
  this.pdf = new Pdf(this);
@@ -4278,6 +4637,7 @@ export {
4278
4637
  ApiCall,
4279
4638
  Auth,
4280
4639
  Files,
4640
+ Gps,
4281
4641
  LoginPrompt,
4282
4642
  PWA,
4283
4643
  Pdf,
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@auxilium/datalynk-client",
3
3
  "description": "Datalynk client library",
4
4
  "repository": "https://gitlab.auxiliumgroup.com/auxilium/datalynk/datalynk-client",
5
- "version": "1.3.21",
5
+ "version": "1.4.0",
6
6
  "author": "Zak Timson <zaktimson@gmail.com>",
7
7
  "private": false,
8
8
  "main": "./dist/index.cjs",