jsgar 4.0.3 → 4.0.5

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.
Files changed (3) hide show
  1. package/dist/gar.umd.js +19 -9
  2. package/gar.js +19 -9
  3. package/package.json +1 -1
package/dist/gar.umd.js CHANGED
@@ -39,9 +39,10 @@
39
39
  * @param {boolean} [allowSelfSignedCertificate=false] - Allow self-signed certificates
40
40
  * @param {string} [logLevel='INFO'] - Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
41
41
  * @param {boolean} [uniqueKeyAndRecordUpdates=false] - Only one update per key/record
42
+ * @param {string} [token=null] - Token for authenticated connections (appended as ?token= query param)
42
43
  */
43
- constructor(wsEndpoint, user, working_namespace = null, heartbeatTimeoutInterval = 4000, allowSelfSignedCertificate = false, logLevel = 'INFO', uniqueKeyAndRecordUpdates = false) {
44
- this.wsEndpoint = wsEndpoint;
44
+ constructor(wsEndpoint, user, working_namespace = null, heartbeatTimeoutInterval = 4000, allowSelfSignedCertificate = false, logLevel = 'INFO', uniqueKeyAndRecordUpdates = false, token = null) {
45
+ this.wsEndpoint = token ? `${wsEndpoint}${wsEndpoint.includes('?') ? '&' : '?'}token=${token}` : wsEndpoint;
45
46
  this.websocket = null;
46
47
  this.messageQueue = [];
47
48
  this.connected = false;
@@ -218,9 +219,18 @@
218
219
  this._receiveMessages();
219
220
 
220
221
  } catch (e) {
221
- this.log('ERROR', `WebSocket connection failed: ${e.message}. Reconnecting in ${this.reconnectDelay / 1000} seconds...`);
222
222
  this.connected = false;
223
223
  this.websocket = null;
224
+ // 401 is a permanent auth rejection — retrying won't help
225
+ if (e.message && e.message.includes('401')) {
226
+ this.log('ERROR', `WebSocket connection rejected (401 Unauthorized)`);
227
+ this.running = false;
228
+ if (this._firstHeartbeatReject) {
229
+ this._firstHeartbeatReject(new Error('Connection rejected (401 Unauthorized)'));
230
+ }
231
+ break;
232
+ }
233
+ this.log('ERROR', `WebSocket connection failed: ${e.message}. Reconnecting in ${this.reconnectDelay / 1000} seconds...`);
224
234
  await new Promise(resolve => setTimeout(resolve, this.reconnectDelay));
225
235
  }
226
236
  }
@@ -679,13 +689,13 @@
679
689
  * @private
680
690
  */
681
691
  _resetFirstHeartbeatLatch() {
682
- let resolved = false;
683
- this._firstHeartbeatPromise = new Promise((resolve) => {
692
+ let settled = false;
693
+ this._firstHeartbeatPromise = new Promise((resolve, reject) => {
684
694
  this._firstHeartbeatResolve = (value) => {
685
- if (!resolved) {
686
- resolved = true;
687
- resolve(value);
688
- }
695
+ if (!settled) { settled = true; resolve(value); }
696
+ };
697
+ this._firstHeartbeatReject = (err) => {
698
+ if (!settled) { settled = true; reject(err); }
689
699
  };
690
700
  });
691
701
  }
package/gar.js CHANGED
@@ -33,9 +33,10 @@ class GARClient {
33
33
  * @param {boolean} [allowSelfSignedCertificate=false] - Allow self-signed certificates
34
34
  * @param {string} [logLevel='INFO'] - Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
35
35
  * @param {boolean} [uniqueKeyAndRecordUpdates=false] - Only one update per key/record
36
+ * @param {string} [token=null] - Token for authenticated connections (appended as ?token= query param)
36
37
  */
37
- constructor(wsEndpoint, user, working_namespace = null, heartbeatTimeoutInterval = 4000, allowSelfSignedCertificate = false, logLevel = 'INFO', uniqueKeyAndRecordUpdates = false) {
38
- this.wsEndpoint = wsEndpoint;
38
+ constructor(wsEndpoint, user, working_namespace = null, heartbeatTimeoutInterval = 4000, allowSelfSignedCertificate = false, logLevel = 'INFO', uniqueKeyAndRecordUpdates = false, token = null) {
39
+ this.wsEndpoint = token ? `${wsEndpoint}${wsEndpoint.includes('?') ? '&' : '?'}token=${token}` : wsEndpoint;
39
40
  this.websocket = null;
40
41
  this.messageQueue = [];
41
42
  this.connected = false;
@@ -212,9 +213,18 @@ class GARClient {
212
213
  this._receiveMessages();
213
214
 
214
215
  } catch (e) {
215
- this.log('ERROR', `WebSocket connection failed: ${e.message}. Reconnecting in ${this.reconnectDelay / 1000} seconds...`);
216
216
  this.connected = false;
217
217
  this.websocket = null;
218
+ // 401 is a permanent auth rejection — retrying won't help
219
+ if (e.message && e.message.includes('401')) {
220
+ this.log('ERROR', `WebSocket connection rejected (401 Unauthorized)`);
221
+ this.running = false;
222
+ if (this._firstHeartbeatReject) {
223
+ this._firstHeartbeatReject(new Error('Connection rejected (401 Unauthorized)'));
224
+ }
225
+ break;
226
+ }
227
+ this.log('ERROR', `WebSocket connection failed: ${e.message}. Reconnecting in ${this.reconnectDelay / 1000} seconds...`);
218
228
  await new Promise(resolve => setTimeout(resolve, this.reconnectDelay));
219
229
  }
220
230
  }
@@ -673,13 +683,13 @@ class GARClient {
673
683
  * @private
674
684
  */
675
685
  _resetFirstHeartbeatLatch() {
676
- let resolved = false;
677
- this._firstHeartbeatPromise = new Promise((resolve) => {
686
+ let settled = false;
687
+ this._firstHeartbeatPromise = new Promise((resolve, reject) => {
678
688
  this._firstHeartbeatResolve = (value) => {
679
- if (!resolved) {
680
- resolved = true;
681
- resolve(value);
682
- }
689
+ if (!settled) { settled = true; resolve(value); }
690
+ };
691
+ this._firstHeartbeatReject = (err) => {
692
+ if (!settled) { settled = true; reject(err); }
683
693
  };
684
694
  });
685
695
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsgar",
3
- "version": "4.0.3",
3
+ "version": "4.0.5",
4
4
  "description": "A Javascript client for the GAR protocol",
5
5
  "type": "module",
6
6
  "main": "dist/gar.umd.js",