jsgar 4.13.2 → 4.13.4
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 +61 -20
- package/gar.js +61 -20
- package/package.json +1 -1
package/dist/gar.umd.js
CHANGED
|
@@ -1179,7 +1179,9 @@
|
|
|
1179
1179
|
* @param {Object} opts - Named subscription options (fields below).
|
|
1180
1180
|
* @param {string} opts.name - Subscription name
|
|
1181
1181
|
* @param {string} [opts.subscriptionMode='Streaming'] - Subscription mode
|
|
1182
|
-
* @param {string|Array<string>|null} [keyName=null] - Key name(s)
|
|
1182
|
+
* @param {string|Array<string>|Array<number>|null} [keyName=null] - Key name(s), matched
|
|
1183
|
+
* exactly via a synthesized key_filter alternation (keys are NOT created by
|
|
1184
|
+
* subscribing); an array of integers passes through as the wire key_id_list
|
|
1183
1185
|
* @param {string|Array<string>|null} [topicName=null] - Topic name(s)
|
|
1184
1186
|
* @param {string|Array<string>|null} [className=null] - Class name(s)
|
|
1185
1187
|
* @param {string|null} [keyFilter=null] - Key filter regex (cannot use with keyName)
|
|
@@ -1258,16 +1260,24 @@
|
|
|
1258
1260
|
referencingClasses = referencingClassList;
|
|
1259
1261
|
}
|
|
1260
1262
|
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
//
|
|
1263
|
+
// Convert keyName to array. Subscribing must NOT create keys: names are no longer
|
|
1264
|
+
// introduced to build a key_id_list (the old behavior materialized every named key on
|
|
1265
|
+
// the server). Names become an exact-match alternation key_filter instead — the server
|
|
1266
|
+
// recognizes the literal-alternation shape and builds a trie, skipping the full
|
|
1267
|
+
// regex->DFA compilation. An array of integers passes through as key_id_list verbatim
|
|
1268
|
+
// (the caller already holds real key ids).
|
|
1264
1269
|
let keyNames = [];
|
|
1265
1270
|
if (typeof keyName === 'string') {
|
|
1266
1271
|
keyNames = [keyName];
|
|
1267
1272
|
} else if (Array.isArray(keyName)) {
|
|
1268
1273
|
keyNames = keyName;
|
|
1269
1274
|
}
|
|
1270
|
-
|
|
1275
|
+
let keyIdList = [];
|
|
1276
|
+
if (keyNames.length > 0 && keyNames.every(Number.isInteger)) {
|
|
1277
|
+
keyIdList = keyNames;
|
|
1278
|
+
} else if (keyNames.length > 0) {
|
|
1279
|
+
keyFilter = keyNames.map(GARClient.escapeRegex).join('|');
|
|
1280
|
+
}
|
|
1271
1281
|
|
|
1272
1282
|
// Convert topicName to array
|
|
1273
1283
|
let topicNames = [];
|
|
@@ -1541,27 +1551,48 @@
|
|
|
1541
1551
|
}
|
|
1542
1552
|
|
|
1543
1553
|
/**
|
|
1544
|
-
*
|
|
1554
|
+
* Remove a single class from a key by sending a KeyIntroduction with deleted_class set, if the
|
|
1555
|
+
* key exists in the localKeyMap. Safe to call multiple times. The key may still exist on the
|
|
1556
|
+
* server in other classes, so the localKeyMap entry is preserved. Careful: every record that
|
|
1557
|
+
* applied to className but to no remaining class is deleted.
|
|
1545
1558
|
* @param {string} keyName - Key name
|
|
1546
|
-
* @param {string
|
|
1547
|
-
*
|
|
1548
|
-
*
|
|
1549
|
-
*
|
|
1550
|
-
*
|
|
1559
|
+
* @param {string} className - Class to remove from the key
|
|
1560
|
+
* @param {string|Array<string>|null} [downgradeToClassList=null] - If set, populates
|
|
1561
|
+
* key_introduction::class_list in the same message — the classes the key should apply to
|
|
1562
|
+
* alongside the removal. A single key_introduction may both add classes (class_list) and
|
|
1563
|
+
* remove one (deleted_class).
|
|
1551
1564
|
*/
|
|
1552
|
-
|
|
1565
|
+
deleteClass(keyName, className, downgradeToClassList = null) {
|
|
1553
1566
|
const keyId = this.localKeyMap.get(keyName);
|
|
1554
1567
|
if (keyId === undefined) return;
|
|
1568
|
+
const value = { key_id: keyId, name: keyName, deleted_class: className };
|
|
1569
|
+
if (downgradeToClassList) {
|
|
1570
|
+
value.class_list = typeof downgradeToClassList === 'string'
|
|
1571
|
+
? downgradeToClassList.split(/\s+/).filter(Boolean)
|
|
1572
|
+
: downgradeToClassList;
|
|
1573
|
+
}
|
|
1574
|
+
this.sendMessage({ message_type: 'KeyIntroduction', value });
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
/**
|
|
1578
|
+
* Delete a key by name if it exists in the localKeyMap. Safe to call multiple times.
|
|
1579
|
+
* @param {string} keyName - Key name
|
|
1580
|
+
* @param {string|null} [className=null] - If set, delegates to deleteClass (KeyIntroduction
|
|
1581
|
+
* with deleted_class set); the key may still exist on the server in other classes and the
|
|
1582
|
+
* localKeyMap entry is preserved. If unset, sends DeleteKey to remove the key entirely and
|
|
1583
|
+
* forgets the local id so a future getAndPossiblyIntroduceKeyId(keyName) re-introduces with
|
|
1584
|
+
* a fresh id.
|
|
1585
|
+
*/
|
|
1586
|
+
deleteKey(keyName, className = null) {
|
|
1555
1587
|
if (className) {
|
|
1556
|
-
this.
|
|
1557
|
-
|
|
1558
|
-
value: { key_id: keyId, name: keyName, deleted_class: className },
|
|
1559
|
-
});
|
|
1560
|
-
} else {
|
|
1561
|
-
this.publishDeleteKey(keyId);
|
|
1562
|
-
// Forget the local id so future re-introduction allocates a new one.
|
|
1563
|
-
this.localKeyMap.delete(keyName);
|
|
1588
|
+
this.deleteClass(keyName, className);
|
|
1589
|
+
return;
|
|
1564
1590
|
}
|
|
1591
|
+
const keyId = this.localKeyMap.get(keyName);
|
|
1592
|
+
if (keyId === undefined) return;
|
|
1593
|
+
this.publishDeleteKey(keyId);
|
|
1594
|
+
// Forget the local id so future re-introduction allocates a new one.
|
|
1595
|
+
this.localKeyMap.delete(keyName);
|
|
1565
1596
|
}
|
|
1566
1597
|
|
|
1567
1598
|
/**
|
|
@@ -1849,6 +1880,16 @@
|
|
|
1849
1880
|
});
|
|
1850
1881
|
}
|
|
1851
1882
|
|
|
1883
|
+
/**
|
|
1884
|
+
* Escape TRS-regex metacharacters so `name` matches literally (TRS regexes match the
|
|
1885
|
+
* whole string, so an escaped name is an exact-match alternative in a key_filter).
|
|
1886
|
+
* @param {string} name
|
|
1887
|
+
* @returns {string}
|
|
1888
|
+
*/
|
|
1889
|
+
static escapeRegex(name) {
|
|
1890
|
+
return String(name).replace(/[\\.^$|?*+()[\]{}]/g, '\\$&');
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1852
1893
|
static _generateUUID() {
|
|
1853
1894
|
const bytes = new Uint8Array(16);
|
|
1854
1895
|
if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.getRandomValues)
|
package/gar.js
CHANGED
|
@@ -1172,7 +1172,9 @@ class GARClient {
|
|
|
1172
1172
|
* @param {Object} opts - Named subscription options (fields below).
|
|
1173
1173
|
* @param {string} opts.name - Subscription name
|
|
1174
1174
|
* @param {string} [opts.subscriptionMode='Streaming'] - Subscription mode
|
|
1175
|
-
* @param {string|Array<string>|null} [keyName=null] - Key name(s)
|
|
1175
|
+
* @param {string|Array<string>|Array<number>|null} [keyName=null] - Key name(s), matched
|
|
1176
|
+
* exactly via a synthesized key_filter alternation (keys are NOT created by
|
|
1177
|
+
* subscribing); an array of integers passes through as the wire key_id_list
|
|
1176
1178
|
* @param {string|Array<string>|null} [topicName=null] - Topic name(s)
|
|
1177
1179
|
* @param {string|Array<string>|null} [className=null] - Class name(s)
|
|
1178
1180
|
* @param {string|null} [keyFilter=null] - Key filter regex (cannot use with keyName)
|
|
@@ -1251,16 +1253,24 @@ class GARClient {
|
|
|
1251
1253
|
referencingClasses = referencingClassList;
|
|
1252
1254
|
}
|
|
1253
1255
|
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
//
|
|
1256
|
+
// Convert keyName to array. Subscribing must NOT create keys: names are no longer
|
|
1257
|
+
// introduced to build a key_id_list (the old behavior materialized every named key on
|
|
1258
|
+
// the server). Names become an exact-match alternation key_filter instead — the server
|
|
1259
|
+
// recognizes the literal-alternation shape and builds a trie, skipping the full
|
|
1260
|
+
// regex->DFA compilation. An array of integers passes through as key_id_list verbatim
|
|
1261
|
+
// (the caller already holds real key ids).
|
|
1257
1262
|
let keyNames = [];
|
|
1258
1263
|
if (typeof keyName === 'string') {
|
|
1259
1264
|
keyNames = [keyName];
|
|
1260
1265
|
} else if (Array.isArray(keyName)) {
|
|
1261
1266
|
keyNames = keyName;
|
|
1262
1267
|
}
|
|
1263
|
-
|
|
1268
|
+
let keyIdList = [];
|
|
1269
|
+
if (keyNames.length > 0 && keyNames.every(Number.isInteger)) {
|
|
1270
|
+
keyIdList = keyNames;
|
|
1271
|
+
} else if (keyNames.length > 0) {
|
|
1272
|
+
keyFilter = keyNames.map(GARClient.escapeRegex).join('|');
|
|
1273
|
+
}
|
|
1264
1274
|
|
|
1265
1275
|
// Convert topicName to array
|
|
1266
1276
|
let topicNames = [];
|
|
@@ -1534,27 +1544,48 @@ class GARClient {
|
|
|
1534
1544
|
}
|
|
1535
1545
|
|
|
1536
1546
|
/**
|
|
1537
|
-
*
|
|
1547
|
+
* Remove a single class from a key by sending a KeyIntroduction with deleted_class set, if the
|
|
1548
|
+
* key exists in the localKeyMap. Safe to call multiple times. The key may still exist on the
|
|
1549
|
+
* server in other classes, so the localKeyMap entry is preserved. Careful: every record that
|
|
1550
|
+
* applied to className but to no remaining class is deleted.
|
|
1538
1551
|
* @param {string} keyName - Key name
|
|
1539
|
-
* @param {string
|
|
1540
|
-
*
|
|
1541
|
-
*
|
|
1542
|
-
*
|
|
1543
|
-
*
|
|
1552
|
+
* @param {string} className - Class to remove from the key
|
|
1553
|
+
* @param {string|Array<string>|null} [downgradeToClassList=null] - If set, populates
|
|
1554
|
+
* key_introduction::class_list in the same message — the classes the key should apply to
|
|
1555
|
+
* alongside the removal. A single key_introduction may both add classes (class_list) and
|
|
1556
|
+
* remove one (deleted_class).
|
|
1544
1557
|
*/
|
|
1545
|
-
|
|
1558
|
+
deleteClass(keyName, className, downgradeToClassList = null) {
|
|
1546
1559
|
const keyId = this.localKeyMap.get(keyName);
|
|
1547
1560
|
if (keyId === undefined) return;
|
|
1561
|
+
const value = { key_id: keyId, name: keyName, deleted_class: className };
|
|
1562
|
+
if (downgradeToClassList) {
|
|
1563
|
+
value.class_list = typeof downgradeToClassList === 'string'
|
|
1564
|
+
? downgradeToClassList.split(/\s+/).filter(Boolean)
|
|
1565
|
+
: downgradeToClassList;
|
|
1566
|
+
}
|
|
1567
|
+
this.sendMessage({ message_type: 'KeyIntroduction', value });
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
/**
|
|
1571
|
+
* Delete a key by name if it exists in the localKeyMap. Safe to call multiple times.
|
|
1572
|
+
* @param {string} keyName - Key name
|
|
1573
|
+
* @param {string|null} [className=null] - If set, delegates to deleteClass (KeyIntroduction
|
|
1574
|
+
* with deleted_class set); the key may still exist on the server in other classes and the
|
|
1575
|
+
* localKeyMap entry is preserved. If unset, sends DeleteKey to remove the key entirely and
|
|
1576
|
+
* forgets the local id so a future getAndPossiblyIntroduceKeyId(keyName) re-introduces with
|
|
1577
|
+
* a fresh id.
|
|
1578
|
+
*/
|
|
1579
|
+
deleteKey(keyName, className = null) {
|
|
1548
1580
|
if (className) {
|
|
1549
|
-
this.
|
|
1550
|
-
|
|
1551
|
-
value: { key_id: keyId, name: keyName, deleted_class: className },
|
|
1552
|
-
});
|
|
1553
|
-
} else {
|
|
1554
|
-
this.publishDeleteKey(keyId);
|
|
1555
|
-
// Forget the local id so future re-introduction allocates a new one.
|
|
1556
|
-
this.localKeyMap.delete(keyName);
|
|
1581
|
+
this.deleteClass(keyName, className);
|
|
1582
|
+
return;
|
|
1557
1583
|
}
|
|
1584
|
+
const keyId = this.localKeyMap.get(keyName);
|
|
1585
|
+
if (keyId === undefined) return;
|
|
1586
|
+
this.publishDeleteKey(keyId);
|
|
1587
|
+
// Forget the local id so future re-introduction allocates a new one.
|
|
1588
|
+
this.localKeyMap.delete(keyName);
|
|
1558
1589
|
}
|
|
1559
1590
|
|
|
1560
1591
|
/**
|
|
@@ -1842,6 +1873,16 @@ class GARClient {
|
|
|
1842
1873
|
});
|
|
1843
1874
|
}
|
|
1844
1875
|
|
|
1876
|
+
/**
|
|
1877
|
+
* Escape TRS-regex metacharacters so `name` matches literally (TRS regexes match the
|
|
1878
|
+
* whole string, so an escaped name is an exact-match alternative in a key_filter).
|
|
1879
|
+
* @param {string} name
|
|
1880
|
+
* @returns {string}
|
|
1881
|
+
*/
|
|
1882
|
+
static escapeRegex(name) {
|
|
1883
|
+
return String(name).replace(/[\\.^$|?*+()[\]{}]/g, '\\$&');
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1845
1886
|
static _generateUUID() {
|
|
1846
1887
|
const bytes = new Uint8Array(16);
|
|
1847
1888
|
if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.getRandomValues)
|