@harperfast/harper 5.0.2 → 5.0.3

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 (62) hide show
  1. package/bin/cliOperations.js +6 -4
  2. package/bin/copyDb.ts +208 -0
  3. package/bin/restart.js +8 -7
  4. package/bin/run.js +2 -1
  5. package/dist/bin/cliOperations.js +6 -4
  6. package/dist/bin/cliOperations.js.map +1 -1
  7. package/dist/bin/copyDb.d.ts +1 -0
  8. package/dist/bin/copyDb.js +197 -0
  9. package/dist/bin/copyDb.js.map +1 -1
  10. package/dist/bin/restart.js +8 -7
  11. package/dist/bin/restart.js.map +1 -1
  12. package/dist/bin/run.js +3 -1
  13. package/dist/bin/run.js.map +1 -1
  14. package/dist/resources/DatabaseTransaction.js +17 -2
  15. package/dist/resources/DatabaseTransaction.js.map +1 -1
  16. package/dist/resources/RecordEncoder.d.ts +1 -1
  17. package/dist/resources/RecordEncoder.js +2 -2
  18. package/dist/resources/RecordEncoder.js.map +1 -1
  19. package/dist/resources/ResourceInterface.d.ts +1 -1
  20. package/dist/resources/RocksIndexStore.d.ts +14 -7
  21. package/dist/resources/RocksIndexStore.js +19 -12
  22. package/dist/resources/RocksIndexStore.js.map +1 -1
  23. package/dist/resources/Table.js +43 -28
  24. package/dist/resources/Table.js.map +1 -1
  25. package/dist/resources/databases.js +18 -14
  26. package/dist/resources/databases.js.map +1 -1
  27. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +2 -1
  28. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +14 -12
  29. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
  30. package/dist/security/certificateVerification/ocspVerification.js +1 -1
  31. package/dist/security/certificateVerification/ocspVerification.js.map +1 -1
  32. package/dist/security/keys.js +7 -7
  33. package/dist/security/keys.js.map +1 -1
  34. package/dist/server/itc/serverHandlers.js +0 -4
  35. package/dist/server/itc/serverHandlers.js.map +1 -1
  36. package/dist/utility/hdbTerms.d.ts +1 -0
  37. package/dist/utility/hdbTerms.js +1 -0
  38. package/dist/utility/hdbTerms.js.map +1 -1
  39. package/dist/utility/install/installer.js +11 -8
  40. package/dist/utility/install/installer.js.map +1 -1
  41. package/package.json +1 -1
  42. package/resources/DatabaseTransaction.ts +19 -2
  43. package/resources/RecordEncoder.ts +2 -2
  44. package/resources/ResourceInterface.ts +1 -1
  45. package/resources/RocksIndexStore.ts +20 -15
  46. package/resources/Table.ts +38 -24
  47. package/resources/databases.ts +29 -14
  48. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +44 -23
  49. package/security/certificateVerification/ocspVerification.ts +1 -1
  50. package/security/keys.js +7 -7
  51. package/server/itc/serverHandlers.js +0 -4
  52. package/studio/web/assets/{index-f5-e8ocl.js → index-CxTavHFE.js} +5 -5
  53. package/studio/web/assets/{index-f5-e8ocl.js.map → index-CxTavHFE.js.map} +1 -1
  54. package/studio/web/assets/{index.lazy-CCd1vMot.js → index.lazy-CfiR1tvq.js} +2 -2
  55. package/studio/web/assets/{index.lazy-CCd1vMot.js.map → index.lazy-CfiR1tvq.js.map} +1 -1
  56. package/studio/web/assets/{profile-gjpePJuu.js → profile-C-uokAal.js} +2 -2
  57. package/studio/web/assets/{profile-gjpePJuu.js.map → profile-C-uokAal.js.map} +1 -1
  58. package/studio/web/assets/{status-CmoVx0A5.js → status-D6xeT4ss.js} +2 -2
  59. package/studio/web/assets/{status-CmoVx0A5.js.map → status-D6xeT4ss.js.map} +1 -1
  60. package/studio/web/index.html +1 -1
  61. package/utility/hdbTerms.ts +1 -0
  62. package/utility/install/installer.js +14 -10
@@ -1424,23 +1424,35 @@ export function makeTable(options) {
1424
1424
  */
1425
1425
  static evict(id, existingRecord, existingVersion) {
1426
1426
  let entry;
1427
- if (hasSourceGet || audit) {
1428
- if (!existingRecord) return;
1429
- entry = primaryStore.getEntry(id);
1430
- if (!entry || !existingRecord) return;
1431
- if (entry.version !== existingVersion) return;
1432
- }
1433
- if (hasSourceGet) {
1434
- // if there is a resolution in-progress, abandon the eviction
1435
- if (primaryStore.hasLock(id, entry.version)) return;
1427
+ let transaction = txnForContext({ transaction: new DatabaseTransaction() }).getReadTxn();
1428
+ let options = { transaction };
1429
+ try {
1430
+ if (hasSourceGet || audit) {
1431
+ if (!existingRecord) return;
1432
+ entry = primaryStore.getEntry(id, options);
1433
+ if (!entry || !existingRecord) return;
1434
+ if (entry.version !== existingVersion) return;
1435
+ }
1436
+ if (hasSourceGet) {
1437
+ // if there is a resolution in-progress, abandon the eviction
1438
+ if (primaryStore.hasLock(id, entry.version)) return;
1439
+ }
1440
+ // evictions never go in the audit log, so we can not record a deletion entry for the eviction
1441
+ // as there is no corresponding audit entry and it would never get cleaned up. So we must simply
1442
+ // removed the entry entirely, but first cleanup indices
1443
+ if (primaryStore.ifVersion) {
1444
+ // lmdb
1445
+ primaryStore.ifVersion?.(id, existingVersion, () => {
1446
+ updateIndices(id, existingRecord, null);
1447
+ });
1448
+ return removeEntry(primaryStore, entry ?? primaryStore.getEntry(id), existingVersion);
1449
+ } else {
1450
+ updateIndices(id, existingRecord, null, options);
1451
+ return removeEntry(primaryStore, entry ?? primaryStore.getEntry(id), options);
1452
+ }
1453
+ } finally {
1454
+ return transaction.commit();
1436
1455
  }
1437
- primaryStore.ifVersion?.(id, existingVersion, () => {
1438
- updateIndices(id, existingRecord, null);
1439
- });
1440
- // evictions never go in the audit log, so we can not record a deletion entry for the eviction
1441
- // as there is no corresponding audit entry and it would never get cleaned up. So we must simply
1442
- // removed the entry entirely
1443
- return removeEntry(primaryStore, entry ?? primaryStore.getEntry(id), existingVersion);
1444
1456
  }
1445
1457
  /**
1446
1458
  * This is intended to acquire a lock on a record from the whole cluster.
@@ -1951,9 +1963,10 @@ export function makeTable(options) {
1951
1963
  context.lastModified = existingEntry.version;
1952
1964
  TableResource._updateResource(this, existingEntry);
1953
1965
  }
1954
- if (precedesExistingVersion(txnTime, existingEntry, options?.nodeId) <= 0) return; // a newer record exists locally
1955
- updateIndices(id, existingRecord);
1956
- logger.trace?.(`Deleting record with id: ${id}, txn timestamp: ${new Date(txnTime).toISOString()}`);
1966
+ if (precedesExistingVersion(txnTime, existingEntry, options?.nodeId) < 0) {
1967
+ return;
1968
+ } // a newer record exists locally
1969
+ updateIndices(id, existingRecord, null, transaction && { transaction });
1957
1970
  if (audit || trackDeletes) {
1958
1971
  updateRecord(
1959
1972
  id,
@@ -3511,6 +3524,7 @@ export function makeTable(options) {
3511
3524
  // determine what index values need to be removed and added
3512
3525
  let valuesToAdd = getIndexedValues(value, indexNulls) as any[];
3513
3526
  let valuesToRemove = getIndexedValues(existingValue, indexNulls) as any[];
3527
+ let isLMDB = !!index.prefetch;
3514
3528
  if (valuesToRemove?.length > 0) {
3515
3529
  // put this in a conditional so we can do a faster version for new records
3516
3530
  // determine the changes/diff from new values and old values
@@ -3527,18 +3541,18 @@ export function makeTable(options) {
3527
3541
  })
3528
3542
  : [];
3529
3543
  valuesToRemove = Array.from(setToRemove);
3530
- if ((valuesToRemove.length > 0 || valuesToAdd.length > 0) && LMDB_PREFETCH_WRITES) {
3544
+ if (isLMDB && (valuesToRemove.length > 0 || valuesToAdd.length > 0) && LMDB_PREFETCH_WRITES) {
3531
3545
  // prefetch any values that have been removed or added
3532
3546
  const valuesToPrefetch = valuesToRemove.concat(valuesToAdd).map((v) => ({ key: v, value: id }));
3533
- index.prefetch?.(valuesToPrefetch, noop);
3547
+ index.prefetch(valuesToPrefetch, noop);
3534
3548
  }
3535
3549
  //if the update cleared out the attribute value we need to delete it from the index
3536
3550
  for (let i = 0, l = valuesToRemove.length; i < l; i++) {
3537
3551
  index.remove(valuesToRemove[i], id, options);
3538
3552
  }
3539
- } else if (valuesToAdd?.length > 0 && LMDB_PREFETCH_WRITES) {
3553
+ } else if (isLMDB && valuesToAdd?.length > 0 && LMDB_PREFETCH_WRITES) {
3540
3554
  // no old values, just new
3541
- index.prefetch?.(
3555
+ index.prefetch(
3542
3556
  valuesToAdd.map((v) => ({ key: v, value: id })),
3543
3557
  noop
3544
3558
  );
@@ -4124,7 +4138,7 @@ export function makeTable(options) {
4124
4138
  // don't do anything if the version has changed
4125
4139
  return;
4126
4140
  }
4127
- updateIndices(id, existingRecord, updatedRecord);
4141
+ updateIndices(id, existingRecord, updatedRecord, transaction && { transaction });
4128
4142
  if (updatedRecord) {
4129
4143
  if (existingEntry) {
4130
4144
  context.previousResidency = TableResource.getResidencyRecord(existingEntry.residencyId);
@@ -120,9 +120,13 @@ function openRocksDatabase(path: string, options: RocksDatabaseOptions & { dupSo
120
120
  }
121
121
  let db: RocksRootDatabase;
122
122
  if (options.dupSort) {
123
- db = RocksDatabase.open(new RocksIndexStore(path, options)) as RocksDatabaseEx;
123
+ db = new RocksIndexStore(path, options).open() as RocksDatabaseEx;
124
124
  } else {
125
125
  db = RocksDatabase.open(path, options) as RocksDatabaseEx;
126
+ // the RocksDB put and remove return promises, which masks thrown errors in non-awaiting calls to put/remove,
127
+ // making them unsafe to replace LMDB methods, which will synchronously throw errors if there is a problem
128
+ db.put = db.putSync;
129
+ db.remove = db.removeSync;
126
130
  db.encoder.name = options.name;
127
131
  }
128
132
  db.env = {};
@@ -386,18 +390,18 @@ function initStores(
386
390
  ) {
387
391
  const envInit = new OpenEnvironmentObject(path, false);
388
392
  const internalDbiInit = createOpenDBIObject(false);
389
- let dbisStore = rootStore.dbisDb;
390
- if (!dbisStore) {
393
+ let attributesDbi = rootStore.dbisDb;
394
+ if (!attributesDbi) {
391
395
  if (rootStore instanceof RocksDatabase) {
392
- dbisStore = openRocksDatabase(rootStore.path, {
396
+ attributesDbi = openRocksDatabase(rootStore.path, {
393
397
  ...internalDbiInit,
394
398
  disableWAL: false,
395
399
  name: INTERNAL_DBIS_NAME,
396
400
  }) as RocksDatabaseEx;
397
401
  } else {
398
- dbisStore = rootStore.openDB(INTERNAL_DBIS_NAME, internalDbiInit);
402
+ attributesDbi = rootStore.openDB(INTERNAL_DBIS_NAME, internalDbiInit);
399
403
  }
400
- rootStore.dbisDb = dbisStore;
404
+ rootStore.dbisDb = attributesDbi;
401
405
  }
402
406
 
403
407
  let auditStore = rootStore.auditStore;
@@ -428,7 +432,7 @@ function initStores(
428
432
  definedTables.rootStore = rootStore;
429
433
  const tablesToLoad = new Map<string, any>();
430
434
 
431
- for (const result of dbisStore.getRange({ start: false })) {
435
+ for (const result of attributesDbi.getRange({ start: false })) {
432
436
  const { key, value } = result as { key: string; value: any };
433
437
  let [tableName, attribute_name] = key.toString().split('/');
434
438
  if (attribute_name === '') {
@@ -489,16 +493,16 @@ function initStores(
489
493
  } else {
490
494
  tableId = primaryAttribute.tableId;
491
495
  if (tableId) {
492
- if (tableId >= (dbisStore.getSync(NEXT_TABLE_ID) || 0)) {
493
- dbisStore.putSync(NEXT_TABLE_ID, tableId + 1);
496
+ if (tableId >= (attributesDbi.getSync(NEXT_TABLE_ID) || 0)) {
497
+ attributesDbi.putSync(NEXT_TABLE_ID, tableId + 1);
494
498
  logger.info(`Updating next table id (it was out of sync) to ${tableId + 1} for ${tableName}`);
495
499
  }
496
500
  } else {
497
- primaryAttribute.tableId = tableId = dbisStore.getSync(NEXT_TABLE_ID);
501
+ primaryAttribute.tableId = tableId = attributesDbi.getSync(NEXT_TABLE_ID);
498
502
  if (!tableId) tableId = 1;
499
503
  logger.debug(`Table {tableName} missing an id, assigning {tableId}`);
500
- dbisStore.putSync(NEXT_TABLE_ID, tableId + 1);
501
- dbisStore.putSync(primaryAttribute.key, primaryAttribute);
504
+ attributesDbi.putSync(NEXT_TABLE_ID, tableId + 1);
505
+ attributesDbi.putSync(primaryAttribute.key, primaryAttribute);
502
506
  }
503
507
  const dbiInit = createOpenDBIObject(!primaryAttribute.isPrimaryKey, primaryAttribute.isPrimaryKey);
504
508
  dbiInit.compression = primaryAttribute.compression;
@@ -544,7 +548,18 @@ function initStores(
544
548
  const attribute = attributes.find((attribute) => attribute.name === existingAttribute.name);
545
549
  if (!attribute) {
546
550
  if (existingAttribute.isPrimaryKey) {
547
- logger.error('Unable to remove existing primary key attribute', existingAttribute);
551
+ logger.error(
552
+ new Error('Unable to remove existing primary key attribute'),
553
+ existingAttribute,
554
+ 'from attributes',
555
+ existingAttributes,
556
+ 'in',
557
+ tableName,
558
+ 'requesting new attribute list',
559
+ attributes,
560
+ 'full metadata list',
561
+ Array.from(attributesDbi.getRange({ start: false }))
562
+ );
548
563
  continue;
549
564
  }
550
565
  if (existingAttribute.indexed) {
@@ -581,7 +596,7 @@ function initStores(
581
596
  indices,
582
597
  attributes,
583
598
  schemaDefined: primaryAttribute.schemaDefined,
584
- dbisDB: dbisStore,
599
+ dbisDB: attributesDbi,
585
600
  })
586
601
  );
587
602
  table.schemaVersion = 1;
@@ -142,7 +142,14 @@ export class HierarchicalNavigableSmallWorld {
142
142
  // For each level from top to bottom
143
143
  while (currentLevel > level) {
144
144
  // Search for closest neighbors at current level
145
- const neighbors = this.searchLayer(vector, entryPointId, entryPoint, this.efConstruction, currentLevel);
145
+ const neighbors = this.searchLayer(
146
+ vector,
147
+ entryPointId,
148
+ entryPoint,
149
+ this.efConstruction,
150
+ currentLevel,
151
+ options
152
+ );
146
153
 
147
154
  if (neighbors.length > 0) {
148
155
  entryPointId = neighbors[0].id; // closest neighbor becomes new entry point
@@ -157,7 +164,7 @@ export class HierarchicalNavigableSmallWorld {
157
164
 
158
165
  // Connect the new element to neighbors at its level and below
159
166
  for (let l = Math.min(level, currentLevel); l >= 0; l--) {
160
- let neighbors = this.searchLayer(vector, entryPointId, entryPoint, this.efConstruction, l);
167
+ let neighbors = this.searchLayer(vector, entryPointId, entryPoint, this.efConstruction, l, options);
161
168
  neighbors = neighbors.slice(0, this.M << 1) as SearchResults;
162
169
 
163
170
  if (neighbors.length === 0 && l === 0) {
@@ -336,16 +343,16 @@ export class HierarchicalNavigableSmallWorld {
336
343
  this.indexStore.put(id, updatedNode, options);
337
344
  }
338
345
  for (const [key, vector] of needsReindexing) {
339
- this.index(key, vector, vector);
346
+ this.index(key, vector, vector, options);
340
347
  }
341
348
  this.checkSymmetry(nodeId, this.indexStore.getSync(nodeId, options), options);
342
349
  }
343
350
 
344
- private getEntryPoint() {
351
+ private getEntryPoint(options: { transaction?: any } = {}) {
345
352
  // Get entry point
346
- const entryPointId = this.indexStore.getSync(ENTRY_POINT);
353
+ const entryPointId = this.indexStore.getSync(ENTRY_POINT, options);
347
354
  if (entryPointId === undefined) return;
348
- const node = this.indexStore.getSync(entryPointId);
355
+ const node = this.indexStore.getSync(entryPointId, options);
349
356
  return { id: entryPointId, ...node };
350
357
  }
351
358
 
@@ -359,6 +366,7 @@ export class HierarchicalNavigableSmallWorld {
359
366
  * @param ef
360
367
  * @param level
361
368
  * @param distanceFunction
369
+ * @param options
362
370
  * @private
363
371
  */
364
372
  private searchLayer(
@@ -367,6 +375,7 @@ export class HierarchicalNavigableSmallWorld {
367
375
  entryPoint: any,
368
376
  ef: number,
369
377
  level: number,
378
+ options: { transaction?: any } = {},
370
379
  distanceFunction = this.distance
371
380
  ): SearchResults {
372
381
  const visited = new Set([entryPointId]);
@@ -396,7 +405,7 @@ export class HierarchicalNavigableSmallWorld {
396
405
  if (visited.has(neighborId) || neighborId === undefined) continue;
397
406
  visited.add(neighborId);
398
407
 
399
- const neighbor = this.indexStore.getSync(neighborId);
408
+ const neighbor = this.indexStore.getSync(neighborId, options);
400
409
  if (!neighbor) continue;
401
410
  this.nodesVisitedCount++;
402
411
  const distance = distanceFunction(queryVector, neighbor.vector);
@@ -429,19 +438,22 @@ export class HierarchicalNavigableSmallWorld {
429
438
  * @param comparator
430
439
  * @param context
431
440
  */
432
- search({
433
- target,
434
- value,
435
- descending,
436
- distance,
437
- comparator,
438
- }: {
439
- target: number[];
440
- value: number;
441
- descending: boolean;
442
- distance: string;
443
- comparator: string;
444
- }) {
441
+ search(
442
+ {
443
+ target,
444
+ value,
445
+ descending,
446
+ distance,
447
+ comparator,
448
+ }: {
449
+ target: number[];
450
+ value: number;
451
+ descending: boolean;
452
+ distance: string;
453
+ comparator: string;
454
+ },
455
+ context: any
456
+ ) {
445
457
  let limit = 0; // zero is ignored, only used if set below
446
458
  switch (comparator) {
447
459
  case 'lt':
@@ -462,14 +474,23 @@ export class HierarchicalNavigableSmallWorld {
462
474
  if (!target) throw new ClientError('A target vector must be provided for an HNSW query');
463
475
  if (!Array.isArray(target)) throw new ClientError('The target vector must be an array');
464
476
 
465
- let entryPoint = this.getEntryPoint();
477
+ const options = context.transaction; // should have a nested RocksDB transaction
478
+ let entryPoint = this.getEntryPoint(options);
466
479
  if (!entryPoint) return [];
467
480
  let entryPointId = entryPoint.id;
468
481
  let results: Candidate[] = [];
469
482
  // For each level from top to bottom
470
483
  for (let l = entryPoint.level; l >= 0; l--) {
471
484
  // Search for closest neighbors at current level
472
- results = this.searchLayer(target, entryPointId, entryPoint, this.efConstructionSearch, l, distanceFunction);
485
+ results = this.searchLayer(
486
+ target,
487
+ entryPointId,
488
+ entryPoint,
489
+ this.efConstructionSearch,
490
+ l,
491
+ options,
492
+ distanceFunction
493
+ );
473
494
 
474
495
  if (results.length > 0) {
475
496
  const neighbor = results[0]; // closest neighbor becomes new entry point
@@ -500,7 +521,7 @@ export class HierarchicalNavigableSmallWorld {
500
521
  // verify that the connection is symmetrical
501
522
  const symmetrical = neighborNode[l]?.find(({ id: nid }) => nid == id);
502
523
  if (!symmetrical) {
503
- logger.info?.('asymmetry detected', neighborNode[l]);
524
+ logger.info?.('asymmetry detected', neighborNode[l], 'does not have', id);
504
525
  }
505
526
  }
506
527
  l++;
@@ -95,7 +95,7 @@ export async function verifyOCSP(
95
95
  method: cached.method || 'ocsp',
96
96
  };
97
97
  } catch (error) {
98
- logger.error?.(`OCSP verification error: ${error}`);
98
+ logger.error?.(`OCSP verification error:`, error);
99
99
 
100
100
  // Check failure mode
101
101
  if (config.failureMode === 'fail-closed') {
package/security/keys.js CHANGED
@@ -125,7 +125,7 @@ function getCertTable() {
125
125
  }
126
126
 
127
127
  async function getReplicationCert() {
128
- const SNICallback = createTLSSelector('operations-api');
128
+ const SNICallback = createTLSSelector('replication');
129
129
  const secureTarget = {
130
130
  secureContexts: null,
131
131
  setSecureContext: (_ctx) => {},
@@ -238,7 +238,7 @@ function loadCertificates() {
238
238
 
239
239
  promise = certificateTable.put({
240
240
  name: certCn,
241
- uses: config.uses ?? ['https', ...(configKey.includes('operations') ? ['operations'] : [])],
241
+ uses: config.uses ?? [configKey.includes('operations') ? ['operations-api'] : []],
242
242
  ciphers: config.ciphers,
243
243
  certificate: certificatePem,
244
244
  private_key_name,
@@ -351,7 +351,7 @@ function certExtensions() {
351
351
  async function createCertificateTable(cert, caCert) {
352
352
  await setCertTable({
353
353
  name: getThisNodeName(),
354
- uses: ['https', 'wss'],
354
+ uses: ['replication'],
355
355
  certificate: cert,
356
356
  private_key_name: 'privateKey.pem',
357
357
  is_authority: false,
@@ -360,7 +360,7 @@ async function createCertificateTable(cert, caCert) {
360
360
 
361
361
  await setCertTable({
362
362
  name: caCert.subject.getField('CN').value,
363
- uses: ['https', 'wss'],
363
+ uses: [],
364
364
  certificate: pki.certificateToPem(caCert),
365
365
  private_key_name: 'privateKey.pem',
366
366
  is_authority: true,
@@ -600,7 +600,7 @@ async function reviewSelfSignedCert() {
600
600
 
601
601
  await setCertTable({
602
602
  name: hdbCa.subject.getField('CN').value,
603
- uses: ['https'],
603
+ uses: [],
604
604
  certificate: pki.certificateToPem(hdbCa),
605
605
  private_key_name: keyName,
606
606
  is_authority: true,
@@ -621,7 +621,7 @@ async function reviewSelfSignedCert() {
621
621
  const newPublicCert = await generateCertificates(pki.privateKeyFromPem(caAndKey.private_key), publicKey, hdbCa);
622
622
  await setCertTable({
623
623
  name: certName,
624
- uses: ['https', 'operations', 'wss'],
624
+ uses: ['replication'],
625
625
  certificate: newPublicCert,
626
626
  is_authority: false,
627
627
  private_key_name: caAndKey.ca.private_key_name,
@@ -755,7 +755,7 @@ function createTLSSelector(type, mtlsOptions) {
755
755
  }
756
756
  let quality = cert.is_self_signed ? 1 : 3;
757
757
  // prefer operations certificates for operations API
758
- if (cert.uses?.includes(type)) quality += 1;
758
+ if (cert.uses?.includes(type)) quality += 3;
759
759
 
760
760
  const private_key = getPrivateKeyByName(cert.private_key_name);
761
761
 
@@ -46,10 +46,6 @@ async function schemaHandler(event) {
46
46
  */
47
47
  async function syncSchemaMetadata(msg) {
48
48
  try {
49
- // reset current read transactions to ensure that we are getting the very latest data
50
- harperBridge.resetReadTxn(hdbTerms.SYSTEM_SCHEMA_NAME, hdbTerms.SYSTEM_TABLE_NAMES.TABLE_TABLE_NAME);
51
- harperBridge.resetReadTxn(hdbTerms.SYSTEM_SCHEMA_NAME, hdbTerms.SYSTEM_TABLE_NAMES.ATTRIBUTE_TABLE_NAME);
52
- harperBridge.resetReadTxn(hdbTerms.SYSTEM_SCHEMA_NAME, hdbTerms.SYSTEM_TABLE_NAMES.SCHEMA_TABLE_NAME);
53
49
  // TODO: Eventually should indicate which database/table changed so we don't have to scan everything
54
50
  let databases = resetDatabases();
55
51
  if (msg.table && msg.database)