@workglow/indexeddb 0.3.38 → 0.3.40

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.
@@ -311,11 +311,7 @@ async function dropIndexedDbTable(tableName) {
311
311
  return deleteIndexedDbTable(tableName);
312
312
  }
313
313
  // src/storage/IndexedDbKvStorage.ts
314
- import {
315
- DefaultKeyValueKey,
316
- DefaultKeyValueSchema,
317
- KvViaTabularStorage
318
- } from "@workglow/storage";
314
+ import { DefaultKeyValueKey, DefaultKeyValueSchema, KvViaTabularStorage } from "@workglow/storage";
319
315
  import { createServiceToken as createServiceToken2 } from "@workglow/util";
320
316
 
321
317
  // src/storage/IndexedDbTabularStorage.ts
@@ -324,9 +320,12 @@ import {
324
320
  HybridSubscriptionManager,
325
321
  isSearchCondition,
326
322
  isSearchInCondition,
323
+ matchesEqualityCriterion,
324
+ matchesInequalityCriterion,
327
325
  normalizeCriterion,
328
326
  pickCoveringIndex,
329
- safeEmit
327
+ safeEmit,
328
+ StorageUnsupportedError
330
329
  } from "@workglow/storage";
331
330
  import { createServiceToken, deepEqual as deepEqual2, makeFingerprint, uuid4 } from "@workglow/util";
332
331
 
@@ -904,7 +903,7 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
904
903
  recordToStore = { ...recordToStore, [keyName]: request.result };
905
904
  }
906
905
  }
907
- this.events.emit("put", recordToStore);
906
+ safeEmit(this.events, "put", recordToStore);
908
907
  resolve(recordToStore);
909
908
  };
910
909
  transaction.oncomplete = () => {
@@ -1003,11 +1002,11 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
1003
1002
  request.onerror = () => reject(request.error);
1004
1003
  request.onsuccess = () => {
1005
1004
  if (!request.result) {
1006
- this.events.emit("get", key, undefined);
1005
+ safeEmit(this.events, "get", key, undefined);
1007
1006
  resolve(undefined);
1008
1007
  return;
1009
1008
  }
1010
- this.events.emit("get", key, request.result);
1009
+ safeEmit(this.events, "get", key, request.result);
1011
1010
  resolve(request.result);
1012
1011
  };
1013
1012
  });
@@ -1063,7 +1062,7 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
1063
1062
  const request = store.delete(this.getIndexedKey(key));
1064
1063
  request.onerror = () => reject(request.error);
1065
1064
  request.onsuccess = () => {
1066
- this.events.emit("delete", key);
1065
+ safeEmit(this.events, "delete", key);
1067
1066
  resolve();
1068
1067
  };
1069
1068
  transaction.oncomplete = () => {
@@ -1079,7 +1078,7 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
1079
1078
  const request = store.clear();
1080
1079
  request.onerror = () => reject(request.error);
1081
1080
  request.onsuccess = () => {
1082
- this.events.emit("clearall");
1081
+ safeEmit(this.events, "clearall");
1083
1082
  resolve();
1084
1083
  };
1085
1084
  transaction.oncomplete = () => {
@@ -1101,7 +1100,8 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
1101
1100
  if (this.cursorSafeIndexes)
1102
1101
  return this.cursorSafeIndexes;
1103
1102
  const required = new Set(this.schema.required ?? []);
1104
- this.cursorSafeIndexes = [...this.indexes, ...this.uniqueIndexes].filter((columns) => columns.every((column) => required.has(String(column))));
1103
+ const properties = this.schema.properties;
1104
+ this.cursorSafeIndexes = [...this.indexes, ...this.uniqueIndexes].filter((columns) => columns.every((column) => required.has(String(column)) && !schemaAdmitsNull(properties[String(column)])));
1105
1105
  return this.cursorSafeIndexes;
1106
1106
  }
1107
1107
  createIndexedRange(store, criteria) {
@@ -1220,12 +1220,16 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
1220
1220
  continue;
1221
1221
  }
1222
1222
  const { operator, value } = normalized;
1223
- if (operator !== "=" && (recordValue === null || recordValue === undefined)) {
1223
+ if (operator !== "=" && operator !== "!=" && (recordValue === null || recordValue === undefined)) {
1224
1224
  return false;
1225
1225
  }
1226
1226
  switch (operator) {
1227
1227
  case "=":
1228
- if (recordValue !== value)
1228
+ if (!matchesEqualityCriterion(recordValue, value))
1229
+ return false;
1230
+ break;
1231
+ case "!=":
1232
+ if (!matchesInequalityCriterion(recordValue, value))
1229
1233
  return false;
1230
1234
  break;
1231
1235
  case "<":
@@ -1261,7 +1265,7 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
1261
1265
  const transaction = db.transaction(this.table, "readwrite");
1262
1266
  const store = transaction.objectStore(this.table);
1263
1267
  transaction.oncomplete = () => {
1264
- this.events.emit("delete", this.deleteIdentity(criteria));
1268
+ safeEmit(this.events, "delete", this.deleteIdentity(criteria));
1265
1269
  this.hybridManager?.notifyLocalChange();
1266
1270
  resolve();
1267
1271
  };
@@ -1347,8 +1351,14 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
1347
1351
  if (isSearchInCondition(criterion))
1348
1352
  return;
1349
1353
  if (isSearchCondition(criterion)) {
1350
- return criterion.operator === "=" ? criterion.value : undefined;
1354
+ if (criterion.operator !== "=")
1355
+ return;
1356
+ if (criterion.value === null)
1357
+ return;
1358
+ return criterion.value;
1351
1359
  }
1360
+ if (criterion === null)
1361
+ return;
1352
1362
  return criterion;
1353
1363
  }
1354
1364
  compareByOrder(a, b, options) {
@@ -1450,7 +1460,7 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
1450
1460
  finalResults = finalResults.slice(0, options.limit);
1451
1461
  }
1452
1462
  const result = finalResults.length > 0 ? finalResults : undefined;
1453
- this.events.emit("query", criteria, result);
1463
+ safeEmit(this.events, "query", criteria, result);
1454
1464
  resolve(result);
1455
1465
  return;
1456
1466
  }
@@ -1462,7 +1472,7 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
1462
1472
  results.push(record);
1463
1473
  if (indexedQuery.appliedLimit && results.length === options?.limit) {
1464
1474
  const result = results.length > 0 ? results : undefined;
1465
- this.events.emit("query", criteria, result);
1475
+ safeEmit(this.events, "query", criteria, result);
1466
1476
  resolve(result);
1467
1477
  return;
1468
1478
  }
@@ -1491,6 +1501,13 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
1491
1501
  selectColumns: options.select.map(String),
1492
1502
  primaryKeyColumns: this.primaryKeyColumns().map(String)
1493
1503
  });
1504
+ for (const col of picked.keyPath) {
1505
+ const criterion = criteria[col];
1506
+ const isNullEquality = isSearchCondition(criterion) ? criterion.operator === "=" && criterion.value === null : criterion === null;
1507
+ if (isNullEquality) {
1508
+ throw new StorageUnsupportedError(`A null equality criterion on indexed column "${col}" (IndexedDB omits ` + `null-valued records from an index, so an index scan can never reach ` + `them — use query() instead)`, "IndexedDbTabularStorage");
1509
+ }
1510
+ }
1494
1511
  const db = await this.getDb();
1495
1512
  return new Promise((resolve, reject) => {
1496
1513
  const tx = db.transaction(this.table, "readonly");
@@ -1506,8 +1523,12 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
1506
1523
  if (isSearchCondition(c)) {
1507
1524
  if (c.operator !== "=")
1508
1525
  break;
1526
+ if (c.value === null)
1527
+ break;
1509
1528
  prefix.push(c.value);
1510
1529
  } else {
1530
+ if (c === null)
1531
+ break;
1511
1532
  prefix.push(c);
1512
1533
  }
1513
1534
  }
@@ -1613,12 +1634,29 @@ class IndexedDbTabularStorage extends BaseTabularStorage {
1613
1634
  this.db?.close();
1614
1635
  }
1615
1636
  }
1637
+ function schemaAdmitsNull(typeDef) {
1638
+ if (typeDef === undefined)
1639
+ return false;
1640
+ if (typeof typeDef === "boolean")
1641
+ return typeDef;
1642
+ if (typeDef.type === "null")
1643
+ return true;
1644
+ if (Array.isArray(typeDef.type))
1645
+ return typeDef.type.includes("null");
1646
+ const branches = typeDef.anyOf ?? typeDef.oneOf;
1647
+ if (Array.isArray(branches)) {
1648
+ return branches.some((branch) => typeof branch !== "boolean" && branch.type === "null");
1649
+ }
1650
+ return false;
1651
+ }
1616
1652
  function compareWithOperator(a, op, b) {
1617
1653
  const av = a;
1618
1654
  const bv = b;
1619
1655
  switch (op) {
1620
1656
  case "=":
1621
- return av === bv;
1657
+ return matchesEqualityCriterion(av, bv);
1658
+ case "!=":
1659
+ return matchesInequalityCriterion(av, bv);
1622
1660
  case "<":
1623
1661
  return av !== null && av !== undefined && av < bv;
1624
1662
  case "<=":
@@ -1645,10 +1683,10 @@ class IndexedDbKvStorage extends KvViaTabularStorage {
1645
1683
  // src/storage/IndexedDbVectorStorage.ts
1646
1684
  import {
1647
1685
  assertVectorShape,
1686
+ emitSimilaritySearch,
1648
1687
  getMetadataProperty,
1649
1688
  getVectorProperty,
1650
1689
  matchesFilter,
1651
- safeEmit as safeEmit2,
1652
1690
  validateVectorEntities
1653
1691
  } from "@workglow/storage";
1654
1692
  import { createServiceToken as createServiceToken3 } from "@workglow/util";
@@ -1702,9 +1740,7 @@ class IndexedDbVectorStorage extends IndexedDbTabularStorage {
1702
1740
  });
1703
1741
  }
1704
1742
  results.sort((a, b) => b.score - a.score);
1705
- const topResults = results.slice(0, topK);
1706
- safeEmit2(this.events, "similaritySearch", query, topResults);
1707
- return topResults;
1743
+ return emitSimilaritySearch(this.events, query, results.slice(0, topK));
1708
1744
  }
1709
1745
  }
1710
1746
  export {
@@ -1724,4 +1760,4 @@ export {
1724
1760
  IDB_KV_REPOSITORY
1725
1761
  };
1726
1762
 
1727
- //# debugId=DA162F737BD6A01964756E2164756E21
1763
+ //# debugId=CD6EC5A9A562618C64756E2164756E21