@utaba/deep-memory-storage-cosmosdb 0.6.0 → 0.8.0

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/index.cjs CHANGED
@@ -672,12 +672,19 @@ async function updateEntity(conn, repositoryId, entityId, updates) {
672
672
  bindings[paramName] = value;
673
673
  propParts.push(`.property('${key}', ${paramName})`);
674
674
  };
675
+ const dropProp = (key) => {
676
+ propParts.push(`.sideEffect(properties('${key}').drop())`);
677
+ };
678
+ if (updates.entityType !== void 0) addProp("entityType", updates.entityType);
675
679
  if (updates.label !== void 0) addProp("entityLabel", updates.label);
676
680
  if (updates.slug !== void 0) addProp("slug", updates.slug);
677
- if (updates.summary !== void 0) addProp("summary", updates.summary);
681
+ if (updates.summary === null) dropProp("summary");
682
+ else if (updates.summary !== void 0) addProp("summary", updates.summary);
678
683
  if (updates.properties !== void 0) addProp("properties", JSON.stringify(updates.properties));
679
- if (updates.data !== void 0) addProp("data", updates.data);
680
- if (updates.dataFormat !== void 0) addProp("dataFormat", updates.dataFormat);
684
+ if (updates.data === null) dropProp("data");
685
+ else if (updates.data !== void 0) addProp("data", updates.data);
686
+ if (updates.dataFormat === null) dropProp("dataFormat");
687
+ else if (updates.dataFormat !== void 0) addProp("dataFormat", updates.dataFormat);
681
688
  if (updates.embedding !== void 0) addProp("embedding", JSON.stringify(updates.embedding));
682
689
  addProp("modifiedBy", updates.provenance.modifiedBy);
683
690
  addProp("modifiedByType", updates.provenance.modifiedByType);
@@ -725,9 +732,37 @@ async function findEntities(conn, repositoryId, query) {
725
732
  });
726
733
  filterClause += `.has('entityType', within(${typeParams.join(", ")}))`;
727
734
  }
728
- if (query.searchTerm) {
729
- bindings["searchTerm"] = query.searchTerm.toLowerCase();
730
- filterClause += ".has('slug', containing(searchTerm))";
735
+ const hasPropertyFilter = query.properties != null && Object.keys(query.properties).length > 0;
736
+ const needsClientFilter = Boolean(query.searchTerm) || hasPropertyFilter;
737
+ if (needsClientFilter) {
738
+ const dataResult2 = await conn.submit(
739
+ `g.V()${filterClause}.valueMap(true)`,
740
+ bindings
741
+ );
742
+ let items2 = dataResult2.items.map(entityFromGremlin);
743
+ if (query.searchTerm) {
744
+ const term = query.searchTerm.toLowerCase();
745
+ items2 = items2.filter(
746
+ (e) => e.label.toLowerCase().includes(term) || e.slug.toLowerCase().includes(term) || e.summary != null && e.summary.toLowerCase().includes(term)
747
+ );
748
+ }
749
+ if (hasPropertyFilter) {
750
+ items2 = items2.filter((entity) => {
751
+ for (const [key, value] of Object.entries(query.properties)) {
752
+ if (entity.properties[key] !== value) return false;
753
+ }
754
+ return true;
755
+ });
756
+ }
757
+ const total2 = items2.length;
758
+ const paged = items2.slice(query.offset, query.offset + query.limit);
759
+ return {
760
+ items: paged,
761
+ total: total2,
762
+ hasMore: query.offset + query.limit < total2,
763
+ limit: query.limit,
764
+ offset: query.offset
765
+ };
731
766
  }
732
767
  const countResult = await conn.submit(
733
768
  `g.V()${filterClause}.count()`,
@@ -740,15 +775,7 @@ async function findEntities(conn, repositoryId, query) {
740
775
  `g.V()${filterClause}.range(rangeStart, rangeEnd).valueMap(true)`,
741
776
  bindings
742
777
  );
743
- let items = dataResult.items.map(entityFromGremlin);
744
- if (query.properties && Object.keys(query.properties).length > 0) {
745
- items = items.filter((entity) => {
746
- for (const [key, value] of Object.entries(query.properties)) {
747
- if (entity.properties[key] !== value) return false;
748
- }
749
- return true;
750
- });
751
- }
778
+ const items = dataResult.items.map(entityFromGremlin);
752
779
  return {
753
780
  items,
754
781
  total,
@@ -1485,6 +1512,45 @@ var CosmosDbProvider = class {
1485
1512
  this.assertValidRepositoryId(repositoryId);
1486
1513
  return deleteEntity(this.conn, repositoryId, entityId);
1487
1514
  }
1515
+ async deleteEntities(repositoryId, ids) {
1516
+ if (ids.length === 0) return { deleted: [], notFound: [] };
1517
+ this.assertValidRepositoryId(repositoryId);
1518
+ const deleted = [];
1519
+ const CHUNK = 100;
1520
+ for (let i = 0; i < ids.length; i += CHUNK) {
1521
+ const chunk = ids.slice(i, i + CHUNK);
1522
+ const bindings = { rid: repositoryId };
1523
+ const idParams = [];
1524
+ for (let j = 0; j < chunk.length; j++) {
1525
+ const p = `id${j}`;
1526
+ bindings[p] = chunk[j];
1527
+ idParams.push(p);
1528
+ }
1529
+ const withinExpr = `P.within(${idParams.join(", ")})`;
1530
+ const existResult = await this.conn.submit(
1531
+ `g.V().has('repositoryId', rid).has('id', ${withinExpr}).has('entityType').values('id')`,
1532
+ bindings
1533
+ );
1534
+ const found = existResult.items;
1535
+ if (found.length > 0) {
1536
+ const dropBindings = { rid: repositoryId };
1537
+ const dropIdParams = [];
1538
+ for (let j = 0; j < found.length; j++) {
1539
+ const p = `did${j}`;
1540
+ dropBindings[p] = found[j];
1541
+ dropIdParams.push(p);
1542
+ }
1543
+ const dropWithinExpr = `P.within(${dropIdParams.join(", ")})`;
1544
+ await this.conn.submit(
1545
+ `g.V().has('repositoryId', rid).has('id', ${dropWithinExpr}).has('entityType').drop()`,
1546
+ dropBindings
1547
+ );
1548
+ deleted.push(...found);
1549
+ }
1550
+ }
1551
+ const deletedSet = new Set(deleted);
1552
+ return { deleted, notFound: ids.filter((id) => !deletedSet.has(id)) };
1553
+ }
1488
1554
  async deleteEntitiesByType(repositoryId, entityType) {
1489
1555
  this.assertValidRepositoryId(repositoryId);
1490
1556
  return deleteEntitiesByType(this.conn, repositoryId, entityType);
@@ -1510,6 +1576,42 @@ var CosmosDbProvider = class {
1510
1576
  this.assertValidRepositoryId(repositoryId);
1511
1577
  return deleteRelationship(this.conn, repositoryId, relationshipId);
1512
1578
  }
1579
+ async deleteRelationships(repositoryId, ids) {
1580
+ if (ids.length === 0) return { deleted: [], notFound: [] };
1581
+ this.assertValidRepositoryId(repositoryId);
1582
+ const deleted = [];
1583
+ const CHUNK = 100;
1584
+ for (let i = 0; i < ids.length; i += CHUNK) {
1585
+ const chunk = ids.slice(i, i + CHUNK);
1586
+ const bindings = { rid: repositoryId };
1587
+ const idParams = [];
1588
+ for (let j = 0; j < chunk.length; j++) {
1589
+ const p = `id${j}`;
1590
+ bindings[p] = chunk[j];
1591
+ idParams.push(p);
1592
+ }
1593
+ const withinExpr = `P.within(${idParams.join(", ")})`;
1594
+ const existResult = await this.conn.submit(
1595
+ `g.E().has('repositoryId', rid).has('id', ${withinExpr}).values('id')`,
1596
+ bindings
1597
+ );
1598
+ const found = existResult.items;
1599
+ if (found.length > 0) {
1600
+ await cosmosRestBatchDelete(
1601
+ this.getRestEndpoint(),
1602
+ this.config.key,
1603
+ this.config.database,
1604
+ this.config.container,
1605
+ repositoryId,
1606
+ found,
1607
+ this.config.rejectUnauthorized ?? true
1608
+ );
1609
+ deleted.push(...found);
1610
+ }
1611
+ }
1612
+ const deletedSet = new Set(deleted);
1613
+ return { deleted, notFound: ids.filter((id) => !deletedSet.has(id)) };
1614
+ }
1513
1615
  async deleteRelationshipsByType(repositoryId, relationshipType) {
1514
1616
  this.assertValidRepositoryId(repositoryId);
1515
1617
  return deleteRelationshipsByType(this.conn, repositoryId, relationshipType);
@@ -1723,6 +1825,32 @@ async function cosmosRestPut(restBase, key, urlPath, resourceLink, resourceType,
1723
1825
  const text = await response.text();
1724
1826
  throw new Error(`CosmosDB REST ${response.status}: ${text}`);
1725
1827
  }
1828
+ async function cosmosRestBatchDelete(restBase, key, database, container, partitionKeyValue, ids, rejectUnauthorized) {
1829
+ const resourceLink = `dbs/${database}/colls/${container}`;
1830
+ const date = (/* @__PURE__ */ new Date()).toUTCString();
1831
+ const token = cosmosAuthToken("post", "docs", resourceLink, date, key);
1832
+ if (!rejectUnauthorized) {
1833
+ process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0";
1834
+ }
1835
+ const ops = ids.map((id) => ({ operationType: "Delete", id }));
1836
+ const response = await fetch(`${restBase}/${resourceLink}/docs`, {
1837
+ method: "POST",
1838
+ headers: {
1839
+ "Authorization": token,
1840
+ "x-ms-version": "2020-07-15",
1841
+ "x-ms-date": date,
1842
+ "Content-Type": "application/json",
1843
+ "x-ms-documentdb-partitionkey": JSON.stringify([partitionKeyValue]),
1844
+ "x-ms-cosmos-is-batch-request": "true",
1845
+ "x-ms-cosmos-batch-atomic": "true"
1846
+ },
1847
+ body: JSON.stringify(ops)
1848
+ });
1849
+ if (response.status !== 200 && response.status !== 207) {
1850
+ const text = await response.text();
1851
+ throw new import_deep_memory5.ProviderError(`CosmosDB batch delete failed (${response.status}): ${text}`);
1852
+ }
1853
+ }
1726
1854
  // Annotate the CommonJS export names for ESM import in node:
1727
1855
  0 && (module.exports = {
1728
1856
  CosmosDbConnection,