jsgar 3.8.3 → 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.
- package/dist/gar.umd.js +68 -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 =
|
|
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;
|
|
@@ -903,6 +916,7 @@
|
|
|
903
916
|
* @param {number} [snapshotSizeLimit=0] - Limit snapshot size
|
|
904
917
|
* @param {number} [nagleInterval=0] - Nagle interval in milliseconds
|
|
905
918
|
* @param {number} [limit=0] - Limits records in initial snapshot (0 = all)
|
|
919
|
+
* @param {string|Array<string>|null} [referencingClassList=null] - Referencing class name(s); if provided, include referencing keys and records per proto.gar subscribe.referencing_class_list
|
|
906
920
|
*/
|
|
907
921
|
subscribe(
|
|
908
922
|
name,
|
|
@@ -924,7 +938,8 @@
|
|
|
924
938
|
subscriptionSet = null,
|
|
925
939
|
snapshotSizeLimit = 0,
|
|
926
940
|
nagleInterval = 0,
|
|
927
|
-
limit = 0
|
|
941
|
+
limit = 0,
|
|
942
|
+
referencingClassList = null
|
|
928
943
|
) {
|
|
929
944
|
// Validate mutually exclusive parameters
|
|
930
945
|
if (keyName && (keyFilter || excludeKeyFilter)) {
|
|
@@ -948,6 +963,14 @@
|
|
|
948
963
|
classList = className;
|
|
949
964
|
}
|
|
950
965
|
|
|
966
|
+
// Normalize referencingClassList to an array
|
|
967
|
+
let referencingClasses = null;
|
|
968
|
+
if (typeof referencingClassList === 'string') {
|
|
969
|
+
referencingClasses = referencingClassList.split(/\s+/).filter(Boolean);
|
|
970
|
+
} else if (Array.isArray(referencingClassList)) {
|
|
971
|
+
referencingClasses = referencingClassList;
|
|
972
|
+
}
|
|
973
|
+
|
|
951
974
|
let singleClass = Array.isArray(classList) && classList.length === 1 ? classList[0] : null;
|
|
952
975
|
|
|
953
976
|
// Convert keyName to array
|
|
@@ -1014,6 +1037,9 @@
|
|
|
1014
1037
|
if (classList) {
|
|
1015
1038
|
valueDict.class_list = classList;
|
|
1016
1039
|
}
|
|
1040
|
+
if (referencingClasses && referencingClasses.length > 0) {
|
|
1041
|
+
valueDict.referencing_class_list = referencingClasses;
|
|
1042
|
+
}
|
|
1017
1043
|
if (keyFilter) {
|
|
1018
1044
|
valueDict.key_filter = keyFilter;
|
|
1019
1045
|
}
|
|
@@ -1222,6 +1248,34 @@
|
|
|
1222
1248
|
this.publishRecordWithIds(keyId, topicId, value);
|
|
1223
1249
|
}
|
|
1224
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
|
+
|
|
1225
1279
|
/**
|
|
1226
1280
|
* Query GAR deployment routing to find servers with matching publications.
|
|
1227
1281
|
* Mirrors the Python client's route_query implementation.
|
|
@@ -1401,6 +1455,18 @@
|
|
|
1401
1455
|
}, Math.max(0, Math.floor(timeout * 1000)));
|
|
1402
1456
|
});
|
|
1403
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
|
+
}
|
|
1404
1470
|
}
|
|
1405
1471
|
|
|
1406
1472
|
return GARClient;
|