@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/bun.js CHANGED
@@ -1032,7 +1032,14 @@ class InMemoryKvStorage extends KvViaTabularStorage {
1032
1032
  }
1033
1033
  }
1034
1034
  // src/queue/InMemoryQueueStorage.ts
1035
- import { createServiceToken as createServiceToken9, EventEmitter as EventEmitter3, makeFingerprint as makeFingerprint4, sleep, uuid4 as uuid42 } from "@workglow/util";
1035
+ import {
1036
+ createServiceToken as createServiceToken9,
1037
+ EventEmitter as EventEmitter3,
1038
+ getLogger,
1039
+ makeFingerprint as makeFingerprint4,
1040
+ sleep,
1041
+ uuid4 as uuid42
1042
+ } from "@workglow/util";
1036
1043
 
1037
1044
  // src/queue/IQueueStorage.ts
1038
1045
  import { createServiceToken as createServiceToken8 } from "@workglow/util";
@@ -1126,11 +1133,23 @@ class InMemoryQueueStorage {
1126
1133
  await sleep(0);
1127
1134
  const job = this.jobQueue.find((j) => j.id === id && this.matchesPrefixes(j));
1128
1135
  if (!job) {
1129
- console.warn("Job not found for progress update", id);
1136
+ const jobWithAnyPrefix = this.jobQueue.find((j) => j.id === id);
1137
+ getLogger().warn("Job not found for progress update", {
1138
+ id,
1139
+ reason: jobWithAnyPrefix ? "prefix_mismatch" : "missing",
1140
+ existingStatus: jobWithAnyPrefix?.status,
1141
+ queueName: this.queueName,
1142
+ prefixValues: this.prefixValues
1143
+ });
1130
1144
  return;
1131
1145
  }
1132
1146
  if (job.status === JobStatus.COMPLETED || job.status === JobStatus.FAILED) {
1133
- console.warn("Job already completed or failed for progress update", id);
1147
+ getLogger().warn("Job already completed or failed for progress update", {
1148
+ id,
1149
+ status: job.status,
1150
+ completedAt: job.completed_at,
1151
+ error: job.error
1152
+ });
1134
1153
  return;
1135
1154
  }
1136
1155
  const oldJob = { ...job };
@@ -1676,6 +1695,81 @@ class InMemoryVectorStorage extends InMemoryTabularStorage {
1676
1695
  return topResults;
1677
1696
  }
1678
1697
  }
1698
+ // src/credentials/EncryptedKvCredentialStore.ts
1699
+ import { decrypt, encrypt } from "@workglow/util";
1700
+
1701
+ class EncryptedKvCredentialStore {
1702
+ kv;
1703
+ passphrase;
1704
+ keyCache = new Map;
1705
+ constructor(kv, passphrase) {
1706
+ this.kv = kv;
1707
+ this.passphrase = passphrase;
1708
+ if (!passphrase) {
1709
+ throw new Error("EncryptedKvCredentialStore requires a non-empty passphrase.");
1710
+ }
1711
+ }
1712
+ async get(key) {
1713
+ const raw = await this.kv.get(key);
1714
+ if (!raw)
1715
+ return;
1716
+ if (raw.expiresAt && new Date(raw.expiresAt) <= new Date) {
1717
+ await this.kv.delete(key);
1718
+ return;
1719
+ }
1720
+ return decrypt(raw.encrypted, raw.iv, this.passphrase, this.keyCache);
1721
+ }
1722
+ async put(key, value, options) {
1723
+ const now = new Date;
1724
+ const existing = await this.kv.get(key);
1725
+ const { encrypted, iv } = await encrypt(value, this.passphrase, this.keyCache);
1726
+ const stored = {
1727
+ encrypted,
1728
+ iv,
1729
+ label: options?.label ?? existing?.label,
1730
+ provider: options?.provider ?? existing?.provider,
1731
+ createdAt: existing?.createdAt ?? now.toISOString(),
1732
+ updatedAt: now.toISOString(),
1733
+ expiresAt: options?.expiresAt ? options.expiresAt.toISOString() : existing?.expiresAt
1734
+ };
1735
+ await this.kv.put(key, stored);
1736
+ }
1737
+ async delete(key) {
1738
+ const exists = await this.kv.get(key) !== undefined;
1739
+ if (exists) {
1740
+ await this.kv.delete(key);
1741
+ }
1742
+ return exists;
1743
+ }
1744
+ async has(key) {
1745
+ const raw = await this.kv.get(key);
1746
+ if (!raw)
1747
+ return false;
1748
+ if (raw.expiresAt && new Date(raw.expiresAt) <= new Date) {
1749
+ await this.kv.delete(key);
1750
+ return false;
1751
+ }
1752
+ return true;
1753
+ }
1754
+ async keys() {
1755
+ const all = await this.kv.getAll();
1756
+ if (!all)
1757
+ return [];
1758
+ const now = new Date;
1759
+ const result = [];
1760
+ for (const entry of all) {
1761
+ if (entry.value.expiresAt && new Date(entry.value.expiresAt) <= now) {
1762
+ await this.kv.delete(entry.key);
1763
+ continue;
1764
+ }
1765
+ result.push(entry.key);
1766
+ }
1767
+ return result;
1768
+ }
1769
+ async deleteAll() {
1770
+ await this.kv.deleteAll();
1771
+ }
1772
+ }
1679
1773
  // src/tabular/FsFolderTabularStorage.ts
1680
1774
  import {
1681
1775
  createServiceToken as createServiceToken12,
@@ -7089,6 +7183,105 @@ class IndexedDbQueueStorage {
7089
7183
  }
7090
7184
  }
7091
7185
  }
7186
+ // src/vector/IndexedDbVectorStorage.ts
7187
+ import { cosineSimilarity as cosineSimilarity4, createServiceToken as createServiceToken31 } from "@workglow/util";
7188
+ var IDB_VECTOR_REPOSITORY = createServiceToken31("storage.vectorRepository.indexedDb");
7189
+ function matchesFilter3(metadata, filter) {
7190
+ for (const [key, value] of Object.entries(filter)) {
7191
+ if (metadata[key] !== value) {
7192
+ return false;
7193
+ }
7194
+ }
7195
+ return true;
7196
+ }
7197
+ function textRelevance2(text, query) {
7198
+ const textLower = text.toLowerCase();
7199
+ const queryLower = query.toLowerCase();
7200
+ const queryWords = queryLower.split(/\s+/).filter((w) => w.length > 0);
7201
+ if (queryWords.length === 0) {
7202
+ return 0;
7203
+ }
7204
+ let matches = 0;
7205
+ for (const word of queryWords) {
7206
+ if (textLower.includes(word)) {
7207
+ matches++;
7208
+ }
7209
+ }
7210
+ return matches / queryWords.length;
7211
+ }
7212
+
7213
+ class IndexedDbVectorStorage extends IndexedDbTabularStorage {
7214
+ vectorDimensions;
7215
+ VectorType;
7216
+ vectorPropertyName;
7217
+ metadataPropertyName;
7218
+ constructor(table = "vectors", schema, primaryKeyNames, indexes = [], dimensions, VectorType = Float32Array, migrationOptions = {}, clientProvidedKeys = "if-missing") {
7219
+ super(table, schema, primaryKeyNames, indexes, migrationOptions, clientProvidedKeys);
7220
+ this.vectorDimensions = dimensions;
7221
+ this.VectorType = VectorType;
7222
+ const vectorProp = getVectorProperty(schema);
7223
+ if (!vectorProp) {
7224
+ throw new Error("Schema must have a property with type array and format TypedArray");
7225
+ }
7226
+ this.vectorPropertyName = vectorProp;
7227
+ this.metadataPropertyName = getMetadataProperty(schema);
7228
+ }
7229
+ getVectorDimensions() {
7230
+ return this.vectorDimensions;
7231
+ }
7232
+ async similaritySearch(query, options = {}) {
7233
+ const { topK = 10, filter, scoreThreshold = 0 } = options;
7234
+ const results = [];
7235
+ const allEntities = await this.getAll() || [];
7236
+ for (const entity of allEntities) {
7237
+ const vector = entity[this.vectorPropertyName];
7238
+ const metadata = this.metadataPropertyName ? entity[this.metadataPropertyName] : {};
7239
+ if (filter && !matchesFilter3(metadata, filter)) {
7240
+ continue;
7241
+ }
7242
+ const score = cosineSimilarity4(query, vector);
7243
+ if (score < scoreThreshold) {
7244
+ continue;
7245
+ }
7246
+ results.push({
7247
+ ...entity,
7248
+ score
7249
+ });
7250
+ }
7251
+ results.sort((a, b) => b.score - a.score);
7252
+ const topResults = results.slice(0, topK);
7253
+ return topResults;
7254
+ }
7255
+ async hybridSearch(query, options) {
7256
+ const { topK = 10, filter, scoreThreshold = 0, textQuery, vectorWeight = 0.7 } = options;
7257
+ if (!textQuery || textQuery.trim().length === 0) {
7258
+ return this.similaritySearch(query, { topK, filter, scoreThreshold });
7259
+ }
7260
+ const results = [];
7261
+ const allEntities = await this.getAll() || [];
7262
+ for (const entity of allEntities) {
7263
+ const vector = entity[this.vectorPropertyName];
7264
+ const metadata = this.metadataPropertyName ? entity[this.metadataPropertyName] : {};
7265
+ if (filter && !matchesFilter3(metadata, filter)) {
7266
+ continue;
7267
+ }
7268
+ const vectorScore = cosineSimilarity4(query, vector);
7269
+ const metadataText = Object.values(metadata).join(" ").toLowerCase();
7270
+ const textScore = textRelevance2(metadataText, textQuery);
7271
+ const combinedScore = vectorWeight * vectorScore + (1 - vectorWeight) * textScore;
7272
+ if (combinedScore < scoreThreshold) {
7273
+ continue;
7274
+ }
7275
+ results.push({
7276
+ ...entity,
7277
+ score: combinedScore
7278
+ });
7279
+ }
7280
+ results.sort((a, b) => b.score - a.score);
7281
+ const topResults = results.slice(0, topK);
7282
+ return topResults;
7283
+ }
7284
+ }
7092
7285
  export {
7093
7286
  registerTabularRepository,
7094
7287
  isSearchCondition,
@@ -7135,6 +7328,7 @@ export {
7135
7328
  KvStorage,
7136
7329
  KV_REPOSITORY,
7137
7330
  JobStatus,
7331
+ IndexedDbVectorStorage,
7138
7332
  IndexedDbTabularStorage,
7139
7333
  IndexedDbRateLimiterStorage,
7140
7334
  IndexedDbQueueStorage,
@@ -7148,6 +7342,7 @@ export {
7148
7342
  IN_MEMORY_QUEUE_STORAGE,
7149
7343
  INDEXED_DB_RATE_LIMITER_STORAGE,
7150
7344
  INDEXED_DB_QUEUE_STORAGE,
7345
+ IDB_VECTOR_REPOSITORY,
7151
7346
  IDB_TABULAR_REPOSITORY,
7152
7347
  IDB_KV_REPOSITORY,
7153
7348
  HybridSubscriptionManager,
@@ -7159,6 +7354,7 @@ export {
7159
7354
  FS_FOLDER_TABULAR_REPOSITORY,
7160
7355
  FS_FOLDER_KV_REPOSITORY,
7161
7356
  FS_FOLDER_JSON_KV_REPOSITORY,
7357
+ EncryptedKvCredentialStore,
7162
7358
  DefaultKeyValueSchema,
7163
7359
  DefaultKeyValueKey,
7164
7360
  CachedTabularStorage,
@@ -7166,4 +7362,4 @@ export {
7166
7362
  BaseTabularStorage
7167
7363
  };
7168
7364
 
7169
- //# debugId=E57950E289D1321964756E2164756E21
7365
+ //# debugId=9D4931947389417A64756E2164756E21