@workglow/storage 0.0.102 → 0.0.104

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/browser.js CHANGED
@@ -1031,7 +1031,14 @@ class InMemoryKvStorage extends KvViaTabularStorage {
1031
1031
  }
1032
1032
  }
1033
1033
  // src/queue/InMemoryQueueStorage.ts
1034
- import { createServiceToken as createServiceToken9, EventEmitter as EventEmitter3, makeFingerprint as makeFingerprint4, sleep, uuid4 as uuid42 } from "@workglow/util";
1034
+ import {
1035
+ createServiceToken as createServiceToken9,
1036
+ EventEmitter as EventEmitter3,
1037
+ getLogger,
1038
+ makeFingerprint as makeFingerprint4,
1039
+ sleep,
1040
+ uuid4 as uuid42
1041
+ } from "@workglow/util";
1035
1042
 
1036
1043
  // src/queue/IQueueStorage.ts
1037
1044
  import { createServiceToken as createServiceToken8 } from "@workglow/util";
@@ -1125,11 +1132,23 @@ class InMemoryQueueStorage {
1125
1132
  await sleep(0);
1126
1133
  const job = this.jobQueue.find((j) => j.id === id && this.matchesPrefixes(j));
1127
1134
  if (!job) {
1128
- console.warn("Job not found for progress update", id);
1135
+ const jobWithAnyPrefix = this.jobQueue.find((j) => j.id === id);
1136
+ getLogger().warn("Job not found for progress update", {
1137
+ id,
1138
+ reason: jobWithAnyPrefix ? "prefix_mismatch" : "missing",
1139
+ existingStatus: jobWithAnyPrefix?.status,
1140
+ queueName: this.queueName,
1141
+ prefixValues: this.prefixValues
1142
+ });
1129
1143
  return;
1130
1144
  }
1131
1145
  if (job.status === JobStatus.COMPLETED || job.status === JobStatus.FAILED) {
1132
- console.warn("Job already completed or failed for progress update", id);
1146
+ getLogger().warn("Job already completed or failed for progress update", {
1147
+ id,
1148
+ status: job.status,
1149
+ completedAt: job.completed_at,
1150
+ error: job.error
1151
+ });
1133
1152
  return;
1134
1153
  }
1135
1154
  const oldJob = { ...job };
@@ -1675,6 +1694,81 @@ class InMemoryVectorStorage extends InMemoryTabularStorage {
1675
1694
  return topResults;
1676
1695
  }
1677
1696
  }
1697
+ // src/credentials/EncryptedKvCredentialStore.ts
1698
+ import { decrypt, encrypt } from "@workglow/util";
1699
+
1700
+ class EncryptedKvCredentialStore {
1701
+ kv;
1702
+ passphrase;
1703
+ keyCache = new Map;
1704
+ constructor(kv, passphrase) {
1705
+ this.kv = kv;
1706
+ this.passphrase = passphrase;
1707
+ if (!passphrase) {
1708
+ throw new Error("EncryptedKvCredentialStore requires a non-empty passphrase.");
1709
+ }
1710
+ }
1711
+ async get(key) {
1712
+ const raw = await this.kv.get(key);
1713
+ if (!raw)
1714
+ return;
1715
+ if (raw.expiresAt && new Date(raw.expiresAt) <= new Date) {
1716
+ await this.kv.delete(key);
1717
+ return;
1718
+ }
1719
+ return decrypt(raw.encrypted, raw.iv, this.passphrase, this.keyCache);
1720
+ }
1721
+ async put(key, value, options) {
1722
+ const now = new Date;
1723
+ const existing = await this.kv.get(key);
1724
+ const { encrypted, iv } = await encrypt(value, this.passphrase, this.keyCache);
1725
+ const stored = {
1726
+ encrypted,
1727
+ iv,
1728
+ label: options?.label ?? existing?.label,
1729
+ provider: options?.provider ?? existing?.provider,
1730
+ createdAt: existing?.createdAt ?? now.toISOString(),
1731
+ updatedAt: now.toISOString(),
1732
+ expiresAt: options?.expiresAt ? options.expiresAt.toISOString() : existing?.expiresAt
1733
+ };
1734
+ await this.kv.put(key, stored);
1735
+ }
1736
+ async delete(key) {
1737
+ const exists = await this.kv.get(key) !== undefined;
1738
+ if (exists) {
1739
+ await this.kv.delete(key);
1740
+ }
1741
+ return exists;
1742
+ }
1743
+ async has(key) {
1744
+ const raw = await this.kv.get(key);
1745
+ if (!raw)
1746
+ return false;
1747
+ if (raw.expiresAt && new Date(raw.expiresAt) <= new Date) {
1748
+ await this.kv.delete(key);
1749
+ return false;
1750
+ }
1751
+ return true;
1752
+ }
1753
+ async keys() {
1754
+ const all = await this.kv.getAll();
1755
+ if (!all)
1756
+ return [];
1757
+ const now = new Date;
1758
+ const result = [];
1759
+ for (const entry of all) {
1760
+ if (entry.value.expiresAt && new Date(entry.value.expiresAt) <= now) {
1761
+ await this.kv.delete(entry.key);
1762
+ continue;
1763
+ }
1764
+ result.push(entry.key);
1765
+ }
1766
+ return result;
1767
+ }
1768
+ async deleteAll() {
1769
+ await this.kv.deleteAll();
1770
+ }
1771
+ }
1678
1772
  // src/tabular/IndexedDbTabularStorage.ts
1679
1773
  import {
1680
1774
  createServiceToken as createServiceToken12,
@@ -4740,6 +4834,105 @@ class SupabaseRateLimiterStorage {
4740
4834
  throw nextError;
4741
4835
  }
4742
4836
  }
4837
+ // src/vector/IndexedDbVectorStorage.ts
4838
+ import { cosineSimilarity as cosineSimilarity2, createServiceToken as createServiceToken21 } from "@workglow/util";
4839
+ var IDB_VECTOR_REPOSITORY = createServiceToken21("storage.vectorRepository.indexedDb");
4840
+ function matchesFilter2(metadata, filter) {
4841
+ for (const [key, value] of Object.entries(filter)) {
4842
+ if (metadata[key] !== value) {
4843
+ return false;
4844
+ }
4845
+ }
4846
+ return true;
4847
+ }
4848
+ function textRelevance2(text, query) {
4849
+ const textLower = text.toLowerCase();
4850
+ const queryLower = query.toLowerCase();
4851
+ const queryWords = queryLower.split(/\s+/).filter((w) => w.length > 0);
4852
+ if (queryWords.length === 0) {
4853
+ return 0;
4854
+ }
4855
+ let matches = 0;
4856
+ for (const word of queryWords) {
4857
+ if (textLower.includes(word)) {
4858
+ matches++;
4859
+ }
4860
+ }
4861
+ return matches / queryWords.length;
4862
+ }
4863
+
4864
+ class IndexedDbVectorStorage extends IndexedDbTabularStorage {
4865
+ vectorDimensions;
4866
+ VectorType;
4867
+ vectorPropertyName;
4868
+ metadataPropertyName;
4869
+ constructor(table = "vectors", schema, primaryKeyNames, indexes = [], dimensions, VectorType = Float32Array, migrationOptions = {}, clientProvidedKeys = "if-missing") {
4870
+ super(table, schema, primaryKeyNames, indexes, migrationOptions, clientProvidedKeys);
4871
+ this.vectorDimensions = dimensions;
4872
+ this.VectorType = VectorType;
4873
+ const vectorProp = getVectorProperty(schema);
4874
+ if (!vectorProp) {
4875
+ throw new Error("Schema must have a property with type array and format TypedArray");
4876
+ }
4877
+ this.vectorPropertyName = vectorProp;
4878
+ this.metadataPropertyName = getMetadataProperty(schema);
4879
+ }
4880
+ getVectorDimensions() {
4881
+ return this.vectorDimensions;
4882
+ }
4883
+ async similaritySearch(query, options = {}) {
4884
+ const { topK = 10, filter, scoreThreshold = 0 } = options;
4885
+ const results = [];
4886
+ const allEntities = await this.getAll() || [];
4887
+ for (const entity of allEntities) {
4888
+ const vector = entity[this.vectorPropertyName];
4889
+ const metadata = this.metadataPropertyName ? entity[this.metadataPropertyName] : {};
4890
+ if (filter && !matchesFilter2(metadata, filter)) {
4891
+ continue;
4892
+ }
4893
+ const score = cosineSimilarity2(query, vector);
4894
+ if (score < scoreThreshold) {
4895
+ continue;
4896
+ }
4897
+ results.push({
4898
+ ...entity,
4899
+ score
4900
+ });
4901
+ }
4902
+ results.sort((a, b) => b.score - a.score);
4903
+ const topResults = results.slice(0, topK);
4904
+ return topResults;
4905
+ }
4906
+ async hybridSearch(query, options) {
4907
+ const { topK = 10, filter, scoreThreshold = 0, textQuery, vectorWeight = 0.7 } = options;
4908
+ if (!textQuery || textQuery.trim().length === 0) {
4909
+ return this.similaritySearch(query, { topK, filter, scoreThreshold });
4910
+ }
4911
+ const results = [];
4912
+ const allEntities = await this.getAll() || [];
4913
+ for (const entity of allEntities) {
4914
+ const vector = entity[this.vectorPropertyName];
4915
+ const metadata = this.metadataPropertyName ? entity[this.metadataPropertyName] : {};
4916
+ if (filter && !matchesFilter2(metadata, filter)) {
4917
+ continue;
4918
+ }
4919
+ const vectorScore = cosineSimilarity2(query, vector);
4920
+ const metadataText = Object.values(metadata).join(" ").toLowerCase();
4921
+ const textScore = textRelevance2(metadataText, textQuery);
4922
+ const combinedScore = vectorWeight * vectorScore + (1 - vectorWeight) * textScore;
4923
+ if (combinedScore < scoreThreshold) {
4924
+ continue;
4925
+ }
4926
+ results.push({
4927
+ ...entity,
4928
+ score: combinedScore
4929
+ });
4930
+ }
4931
+ results.sort((a, b) => b.score - a.score);
4932
+ const topResults = results.slice(0, topK);
4933
+ return topResults;
4934
+ }
4935
+ }
4743
4936
  export {
4744
4937
  registerTabularRepository,
4745
4938
  isSearchCondition,
@@ -4770,6 +4963,7 @@ export {
4770
4963
  KvStorage,
4771
4964
  KV_REPOSITORY,
4772
4965
  JobStatus,
4966
+ IndexedDbVectorStorage,
4773
4967
  IndexedDbTabularStorage,
4774
4968
  IndexedDbRateLimiterStorage,
4775
4969
  IndexedDbQueueStorage,
@@ -4783,11 +4977,13 @@ export {
4783
4977
  IN_MEMORY_QUEUE_STORAGE,
4784
4978
  INDEXED_DB_RATE_LIMITER_STORAGE,
4785
4979
  INDEXED_DB_QUEUE_STORAGE,
4980
+ IDB_VECTOR_REPOSITORY,
4786
4981
  IDB_TABULAR_REPOSITORY,
4787
4982
  IDB_KV_REPOSITORY,
4788
4983
  HybridSubscriptionManager,
4789
4984
  HuggingFaceTabularStorage,
4790
4985
  HF_TABULAR_REPOSITORY,
4986
+ EncryptedKvCredentialStore,
4791
4987
  DefaultKeyValueSchema,
4792
4988
  DefaultKeyValueKey,
4793
4989
  CachedTabularStorage,
@@ -4795,4 +4991,4 @@ export {
4795
4991
  BaseTabularStorage
4796
4992
  };
4797
4993
 
4798
- //# debugId=B7E554C36B7CCFEF64756E2164756E21
4994
+ //# debugId=6C77B36216FE8BAE64756E2164756E21