jsgar 3.8.8 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/gar.umd.js +54 -1
  2. package/package.json +1 -1
package/dist/gar.umd.js CHANGED
@@ -54,7 +54,8 @@
54
54
  this.scaledHeartbeatTimeoutInterval *= this.timeoutScale;
55
55
  }
56
56
  this.unique_key_and_record_updates = uniqueKeyAndRecordUpdates;
57
- this.version = 650707;
57
+ this.version = 650708;
58
+ this.uuid = GARClient._generateUUID();
58
59
 
59
60
  if (typeof window !== 'undefined' && window.location) {
60
61
  this.application = window.location.href;
@@ -412,6 +413,15 @@
412
413
  }, subscriptionGroup);
413
414
  }
414
415
 
416
+ /**
417
+ * Register handler for JSONCompareExchangeResult message.
418
+ * @param {Function} handler - Callback with (message)
419
+ * @param {number} [subscriptionGroup=0] - The subscription group for callback
420
+ */
421
+ registerCompareExchangeResultHandler(handler, subscriptionGroup = 0) {
422
+ this.registerHandler('JSONCompareExchangeResult', handler, subscriptionGroup);
423
+ }
424
+
415
425
  /**
416
426
  * Register handler for BatchUpdate message.
417
427
  * If a batch handler is registered it is expected to process all the updates in the batch.
@@ -508,6 +518,7 @@
508
518
  version: this.version,
509
519
  heartbeat_timeout_interval: Math.floor(this.scaledHeartbeatTimeoutInterval),
510
520
  unique_key_and_record_updates: this.unique_key_and_record_updates,
521
+ uuid: this.uuid,
511
522
  user: this.user,
512
523
  working_namespace: this.working_namespace
513
524
  }
@@ -758,6 +769,8 @@
758
769
  // New Introduction: do not reset the first-heartbeat promise to avoid racing
759
770
  // with consumers already awaiting it. The existing promise will resolve on
760
771
  // the first Heartbeat observed during the grace period above.
772
+ } else if (msgType === 'JSONCompareExchangeResult') {
773
+ subscriptionGroup = this.activeSubscriptionGroup;
761
774
  } else if (msgType === 'JSONRecordUpdate') {
762
775
  subscriptionGroup = this.activeSubscriptionGroup;
763
776
  const recordId = message.value.record_id;
@@ -1235,6 +1248,34 @@
1235
1248
  this.publishRecordWithIds(keyId, topicId, value);
1236
1249
  }
1237
1250
 
1251
+ /**
1252
+ * Send a compare-exchange using explicit key and topic IDs.
1253
+ * @param {number} keyId - Key ID
1254
+ * @param {number} topicId - Topic ID
1255
+ * @param {any} test - Expected current value (null = expect missing/empty)
1256
+ * @param {any} value - New value to set on match
1257
+ */
1258
+ compareExchangeRecordWithIds(keyId, topicId, test, value) {
1259
+ this.sendMessage({
1260
+ message_type: 'JSONCompareExchange',
1261
+ value: { record_id: { key_id: keyId, topic_id: topicId }, test, value }
1262
+ });
1263
+ }
1264
+
1265
+ /**
1266
+ * Send a compare-exchange using names, converting to local IDs.
1267
+ * @param {string} keyName - Key name
1268
+ * @param {string} topicName - Topic name
1269
+ * @param {any} test - Expected current value (null = expect missing/empty)
1270
+ * @param {any} value - New value to set on match
1271
+ * @param {string|null} [className=null] - Class name
1272
+ */
1273
+ compareExchangeRecord(keyName, topicName, test, value, className = null) {
1274
+ const keyId = this.getAndPossiblyIntroduceKeyId(keyName, className);
1275
+ const topicId = this.getAndPossiblyIntroduceTopicId(topicName);
1276
+ this.compareExchangeRecordWithIds(keyId, topicId, test, value);
1277
+ }
1278
+
1238
1279
  /**
1239
1280
  * Query GAR deployment routing to find servers with matching publications.
1240
1281
  * Mirrors the Python client's route_query implementation.
@@ -1414,6 +1455,18 @@
1414
1455
  }, Math.max(0, Math.floor(timeout * 1000)));
1415
1456
  });
1416
1457
  }
1458
+
1459
+ static _generateUUID() {
1460
+ const bytes = new Uint8Array(16);
1461
+ if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.getRandomValues)
1462
+ globalThis.crypto.getRandomValues(bytes);
1463
+ else
1464
+ require('crypto').randomFillSync(bytes);
1465
+ bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4
1466
+ bytes[8] = (bytes[8] & 0x3f) | 0x80; // variant RFC 4122
1467
+ const view = new DataView(bytes.buffer);
1468
+ return { low: Number(view.getBigUint64(0, true)), high: Number(view.getBigUint64(8, true)) };
1469
+ }
1417
1470
  }
1418
1471
 
1419
1472
  return GARClient;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsgar",
3
- "version": "3.8.8",
3
+ "version": "4.0.1",
4
4
  "description": "A Javascript client for the GAR protocol",
5
5
  "type": "module",
6
6
  "main": "dist/gar.umd.js",