@lov3kaizen/agentsea-embeddings 0.5.1
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/LICENSE +21 -0
- package/README.md +475 -0
- package/dist/caching/index.d.mts +286 -0
- package/dist/caching/index.d.ts +286 -0
- package/dist/caching/index.js +1005 -0
- package/dist/caching/index.mjs +27 -0
- package/dist/chunk-3KM32UQK.mjs +207 -0
- package/dist/chunk-DJAURHAS.mjs +1117 -0
- package/dist/chunk-NBHIRTJT.mjs +895 -0
- package/dist/chunk-QAITLJ2E.mjs +259 -0
- package/dist/chunk-TER262ST.mjs +877 -0
- package/dist/chunk-VPSMDBHH.mjs +957 -0
- package/dist/chunking/index.d.mts +1 -0
- package/dist/chunking/index.d.ts +1 -0
- package/dist/chunking/index.js +1408 -0
- package/dist/chunking/index.mjs +37 -0
- package/dist/embedding.types-CCgPVxt1.d.mts +102 -0
- package/dist/embedding.types-CCgPVxt1.d.ts +102 -0
- package/dist/index-CeG6God2.d.mts +297 -0
- package/dist/index-DMaQRn2w.d.mts +172 -0
- package/dist/index-DMaQRn2w.d.ts +172 -0
- package/dist/index-DWddsKRi.d.ts +297 -0
- package/dist/index.d.mts +647 -0
- package/dist/index.d.ts +647 -0
- package/dist/index.js +5259 -0
- package/dist/index.mjs +1028 -0
- package/dist/providers/index.d.mts +2 -0
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.js +1235 -0
- package/dist/providers/index.mjs +32 -0
- package/dist/stores/index.d.mts +298 -0
- package/dist/stores/index.d.ts +298 -0
- package/dist/stores/index.js +1178 -0
- package/dist/stores/index.mjs +26 -0
- package/package.json +102 -0
|
@@ -0,0 +1,1005 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/caching/index.ts
|
|
31
|
+
var caching_exports = {};
|
|
32
|
+
__export(caching_exports, {
|
|
33
|
+
BaseCache: () => BaseCache,
|
|
34
|
+
MemoryCache: () => MemoryCache,
|
|
35
|
+
RedisCache: () => RedisCache,
|
|
36
|
+
SQLiteCache: () => SQLiteCache,
|
|
37
|
+
TieredCache: () => TieredCache,
|
|
38
|
+
createCache: () => createCache,
|
|
39
|
+
createMemoryCache: () => createMemoryCache,
|
|
40
|
+
createRedisCache: () => createRedisCache,
|
|
41
|
+
createSQLiteCache: () => createSQLiteCache,
|
|
42
|
+
createStandardTieredCache: () => createStandardTieredCache,
|
|
43
|
+
createTieredCache: () => createTieredCache
|
|
44
|
+
});
|
|
45
|
+
module.exports = __toCommonJS(caching_exports);
|
|
46
|
+
|
|
47
|
+
// src/core/utils.ts
|
|
48
|
+
var import_crypto = require("crypto");
|
|
49
|
+
function contentHash(text, algorithm = "sha256") {
|
|
50
|
+
return (0, import_crypto.createHash)(algorithm).update(text).digest("hex");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// src/caching/BaseCache.ts
|
|
54
|
+
var BaseCache = class {
|
|
55
|
+
/** Cache options */
|
|
56
|
+
options;
|
|
57
|
+
/** Cache statistics */
|
|
58
|
+
stats;
|
|
59
|
+
constructor(options = {}) {
|
|
60
|
+
this.options = {
|
|
61
|
+
defaultTTL: options.defaultTTL ?? 0,
|
|
62
|
+
maxEntries: options.maxEntries ?? 1e5,
|
|
63
|
+
maxSizeBytes: options.maxSizeBytes ?? 1024 * 1024 * 1024,
|
|
64
|
+
// 1GB
|
|
65
|
+
keyPrefix: options.keyPrefix ?? "emb",
|
|
66
|
+
compression: options.compression ?? false,
|
|
67
|
+
compressionThreshold: options.compressionThreshold ?? 1024
|
|
68
|
+
};
|
|
69
|
+
this.stats = this.createInitialStats();
|
|
70
|
+
}
|
|
71
|
+
createInitialStats() {
|
|
72
|
+
return {
|
|
73
|
+
entries: 0,
|
|
74
|
+
sizeBytes: 0,
|
|
75
|
+
hits: 0,
|
|
76
|
+
misses: 0,
|
|
77
|
+
hitRate: 0,
|
|
78
|
+
gets: 0,
|
|
79
|
+
sets: 0,
|
|
80
|
+
deletes: 0,
|
|
81
|
+
evictions: 0,
|
|
82
|
+
avgGetLatencyMs: 0,
|
|
83
|
+
avgSetLatencyMs: 0
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Generate cache key from text and model
|
|
88
|
+
*/
|
|
89
|
+
generateKey(text, model) {
|
|
90
|
+
const hash = contentHash(`${model}:${text}`);
|
|
91
|
+
return `${this.options.keyPrefix}:${model}:${hash}`;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Lookup with timing and stats
|
|
95
|
+
*/
|
|
96
|
+
async lookup(key) {
|
|
97
|
+
const startTime = performance.now();
|
|
98
|
+
this.stats.gets++;
|
|
99
|
+
const entry = await this.get(key);
|
|
100
|
+
const latencyMs = performance.now() - startTime;
|
|
101
|
+
this.stats.avgGetLatencyMs = (this.stats.avgGetLatencyMs * (this.stats.gets - 1) + latencyMs) / this.stats.gets;
|
|
102
|
+
if (entry) {
|
|
103
|
+
this.stats.hits++;
|
|
104
|
+
this.updateHitRate();
|
|
105
|
+
return { hit: true, entry, latencyMs };
|
|
106
|
+
} else {
|
|
107
|
+
this.stats.misses++;
|
|
108
|
+
this.updateHitRate();
|
|
109
|
+
return { hit: false, latencyMs };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Batch lookup
|
|
114
|
+
*/
|
|
115
|
+
async lookupBatch(keys) {
|
|
116
|
+
const startTime = performance.now();
|
|
117
|
+
const hits = /* @__PURE__ */ new Map();
|
|
118
|
+
const misses = [];
|
|
119
|
+
for (const key of keys) {
|
|
120
|
+
const result = await this.lookup(key);
|
|
121
|
+
if (result.hit && result.entry) {
|
|
122
|
+
hits.set(key, result.entry);
|
|
123
|
+
} else {
|
|
124
|
+
misses.push(key);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
hits,
|
|
129
|
+
misses,
|
|
130
|
+
hitRate: keys.length > 0 ? hits.size / keys.length : 0,
|
|
131
|
+
latencyMs: performance.now() - startTime
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Store with timing and stats
|
|
136
|
+
*/
|
|
137
|
+
async store(key, result, model, ttl) {
|
|
138
|
+
const startTime = performance.now();
|
|
139
|
+
this.stats.sets++;
|
|
140
|
+
const entry = {
|
|
141
|
+
key,
|
|
142
|
+
vector: result.vector,
|
|
143
|
+
text: result.text,
|
|
144
|
+
model,
|
|
145
|
+
dimensions: result.dimensions,
|
|
146
|
+
tokenCount: result.tokenCount,
|
|
147
|
+
createdAt: Date.now(),
|
|
148
|
+
accessedAt: Date.now(),
|
|
149
|
+
accessCount: 0,
|
|
150
|
+
ttl: ttl ?? this.options.defaultTTL ?? 0
|
|
151
|
+
};
|
|
152
|
+
await this.set(key, entry);
|
|
153
|
+
const latencyMs = performance.now() - startTime;
|
|
154
|
+
this.stats.avgSetLatencyMs = (this.stats.avgSetLatencyMs * (this.stats.sets - 1) + latencyMs) / this.stats.sets;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Store batch of results
|
|
158
|
+
*/
|
|
159
|
+
async storeBatch(entries, ttl) {
|
|
160
|
+
for (const entry of entries) {
|
|
161
|
+
await this.store(entry.key, entry.result, entry.model, ttl);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get cache statistics
|
|
166
|
+
*/
|
|
167
|
+
getStats() {
|
|
168
|
+
return { ...this.stats };
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Reset statistics
|
|
172
|
+
*/
|
|
173
|
+
resetStats() {
|
|
174
|
+
this.stats = this.createInitialStats();
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Update hit rate
|
|
178
|
+
*/
|
|
179
|
+
updateHitRate() {
|
|
180
|
+
const total = this.stats.hits + this.stats.misses;
|
|
181
|
+
this.stats.hitRate = total > 0 ? this.stats.hits / total : 0;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Cleanup expired/old entries
|
|
185
|
+
*/
|
|
186
|
+
async cleanup(options) {
|
|
187
|
+
const startTime = performance.now();
|
|
188
|
+
const dryRun = options?.dryRun ?? false;
|
|
189
|
+
const now = Date.now();
|
|
190
|
+
let removed = 0;
|
|
191
|
+
let freedBytes = 0;
|
|
192
|
+
const keys = await this.keys();
|
|
193
|
+
for (const key of keys) {
|
|
194
|
+
const entry = await this.get(key);
|
|
195
|
+
if (!entry) continue;
|
|
196
|
+
let shouldRemove = false;
|
|
197
|
+
if (options?.removeExpired && entry.ttl > 0) {
|
|
198
|
+
if (entry.createdAt + entry.ttl * 1e3 < now) {
|
|
199
|
+
shouldRemove = true;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (options?.olderThan) {
|
|
203
|
+
if (entry.createdAt < now - options.olderThan * 1e3) {
|
|
204
|
+
shouldRemove = true;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (options?.notAccessedSince) {
|
|
208
|
+
if (entry.accessedAt < now - options.notAccessedSince * 1e3) {
|
|
209
|
+
shouldRemove = true;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (options?.model && entry.model !== options.model) {
|
|
213
|
+
shouldRemove = false;
|
|
214
|
+
}
|
|
215
|
+
if (options?.version && entry.version !== options.version) {
|
|
216
|
+
shouldRemove = false;
|
|
217
|
+
}
|
|
218
|
+
if (shouldRemove && !dryRun) {
|
|
219
|
+
const size = this.estimateEntrySize(entry);
|
|
220
|
+
await this.delete(key);
|
|
221
|
+
removed++;
|
|
222
|
+
freedBytes += size;
|
|
223
|
+
this.stats.evictions++;
|
|
224
|
+
} else if (shouldRemove) {
|
|
225
|
+
removed++;
|
|
226
|
+
freedBytes += this.estimateEntrySize(entry);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
removed,
|
|
231
|
+
freedBytes,
|
|
232
|
+
durationMs: performance.now() - startTime,
|
|
233
|
+
dryRun
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Export cache contents
|
|
238
|
+
*/
|
|
239
|
+
async export() {
|
|
240
|
+
const keys = await this.keys();
|
|
241
|
+
const entries = [];
|
|
242
|
+
for (const key of keys) {
|
|
243
|
+
const entry = await this.get(key);
|
|
244
|
+
if (entry) {
|
|
245
|
+
entries.push(entry);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return {
|
|
249
|
+
version: "1.0",
|
|
250
|
+
exportedAt: Date.now(),
|
|
251
|
+
totalEntries: entries.length,
|
|
252
|
+
entries
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Import cache contents
|
|
257
|
+
*/
|
|
258
|
+
async import(data, options) {
|
|
259
|
+
let imported = 0;
|
|
260
|
+
let skipped = 0;
|
|
261
|
+
for (let i = 0; i < data.entries.length; i++) {
|
|
262
|
+
const entry = data.entries[i];
|
|
263
|
+
if (options?.validate) {
|
|
264
|
+
if (!entry.key || !entry.vector || !entry.model) {
|
|
265
|
+
skipped++;
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
const exists = await this.has(entry.key);
|
|
270
|
+
if (exists) {
|
|
271
|
+
if (options?.skipExisting) {
|
|
272
|
+
skipped++;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
if (!options?.updateExisting) {
|
|
276
|
+
skipped++;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
await this.set(entry.key, entry);
|
|
281
|
+
imported++;
|
|
282
|
+
if (options?.onProgress) {
|
|
283
|
+
options.onProgress({ imported, total: data.entries.length });
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return { imported, skipped };
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Estimate entry size in bytes
|
|
290
|
+
*/
|
|
291
|
+
estimateEntrySize(entry) {
|
|
292
|
+
const vectorSize = entry.vector.length * 4;
|
|
293
|
+
const textSize = (entry.text?.length ?? 0) * 2;
|
|
294
|
+
const overheadSize = 200;
|
|
295
|
+
return vectorSize + textSize + overheadSize;
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// src/caching/MemoryCache.ts
|
|
300
|
+
var import_lru_cache = require("lru-cache");
|
|
301
|
+
var MemoryCache = class extends BaseCache {
|
|
302
|
+
backendType = "memory";
|
|
303
|
+
cache;
|
|
304
|
+
constructor(options = {}) {
|
|
305
|
+
super(options);
|
|
306
|
+
this.cache = new import_lru_cache.LRUCache({
|
|
307
|
+
max: options.maxEntries ?? 1e5,
|
|
308
|
+
maxSize: options.maxSizeBytes ?? 1024 * 1024 * 1024,
|
|
309
|
+
sizeCalculation: (entry) => this.estimateEntrySize(entry),
|
|
310
|
+
ttl: options.maxAge ?? 0,
|
|
311
|
+
updateAgeOnGet: options.updateAgeOnGet ?? true,
|
|
312
|
+
allowStale: options.staleWhileRevalidate ? true : false
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
async get(key) {
|
|
316
|
+
const entry = this.cache.get(key);
|
|
317
|
+
if (entry) {
|
|
318
|
+
entry.accessedAt = Date.now();
|
|
319
|
+
entry.accessCount++;
|
|
320
|
+
}
|
|
321
|
+
return Promise.resolve(entry);
|
|
322
|
+
}
|
|
323
|
+
set(key, entry) {
|
|
324
|
+
const ttl = entry.ttl > 0 ? entry.ttl * 1e3 : void 0;
|
|
325
|
+
this.cache.set(key, entry, { ttl });
|
|
326
|
+
this.stats.entries = this.cache.size;
|
|
327
|
+
return Promise.resolve();
|
|
328
|
+
}
|
|
329
|
+
has(key) {
|
|
330
|
+
return Promise.resolve(this.cache.has(key));
|
|
331
|
+
}
|
|
332
|
+
async delete(key) {
|
|
333
|
+
const existed = this.cache.has(key);
|
|
334
|
+
this.cache.delete(key);
|
|
335
|
+
this.stats.deletes++;
|
|
336
|
+
this.stats.entries = this.cache.size;
|
|
337
|
+
return Promise.resolve(existed);
|
|
338
|
+
}
|
|
339
|
+
clear() {
|
|
340
|
+
this.cache.clear();
|
|
341
|
+
this.stats.entries = 0;
|
|
342
|
+
return Promise.resolve();
|
|
343
|
+
}
|
|
344
|
+
size() {
|
|
345
|
+
return Promise.resolve(this.cache.size);
|
|
346
|
+
}
|
|
347
|
+
keys() {
|
|
348
|
+
return Promise.resolve(Array.from(this.cache.keys()));
|
|
349
|
+
}
|
|
350
|
+
async close() {
|
|
351
|
+
this.cache.clear();
|
|
352
|
+
return Promise.resolve();
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Get memory usage info
|
|
356
|
+
*/
|
|
357
|
+
getMemoryInfo() {
|
|
358
|
+
return {
|
|
359
|
+
entries: this.cache.size,
|
|
360
|
+
calculatedSize: this.cache.calculatedSize,
|
|
361
|
+
maxSize: this.cache.max
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Prune stale entries
|
|
366
|
+
*/
|
|
367
|
+
prune() {
|
|
368
|
+
this.cache.purgeStale();
|
|
369
|
+
this.stats.entries = this.cache.size;
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
function createMemoryCache(options) {
|
|
373
|
+
return new MemoryCache(options);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// src/caching/RedisCache.ts
|
|
377
|
+
var RedisCache = class extends BaseCache {
|
|
378
|
+
backendType = "redis";
|
|
379
|
+
client = null;
|
|
380
|
+
config;
|
|
381
|
+
connected = false;
|
|
382
|
+
constructor(options) {
|
|
383
|
+
super(options);
|
|
384
|
+
this.config = options;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Connect to Redis
|
|
388
|
+
*/
|
|
389
|
+
async connect() {
|
|
390
|
+
if (this.connected) return;
|
|
391
|
+
try {
|
|
392
|
+
const { Redis } = await import("ioredis");
|
|
393
|
+
if (this.config.url) {
|
|
394
|
+
this.client = new Redis(this.config.url, {
|
|
395
|
+
connectTimeout: this.config.connectTimeout ?? 1e4,
|
|
396
|
+
commandTimeout: this.config.commandTimeout ?? 5e3,
|
|
397
|
+
lazyConnect: false
|
|
398
|
+
});
|
|
399
|
+
} else if (this.config.cluster && this.config.clusterNodes) {
|
|
400
|
+
const { Cluster } = await import("ioredis");
|
|
401
|
+
this.client = new Cluster(this.config.clusterNodes, {
|
|
402
|
+
redisOptions: {
|
|
403
|
+
password: this.config.password
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
} else if (this.config.sentinel) {
|
|
407
|
+
this.client = new Redis({
|
|
408
|
+
sentinels: this.config.sentinel.sentinels,
|
|
409
|
+
name: this.config.sentinel.master,
|
|
410
|
+
password: this.config.password
|
|
411
|
+
});
|
|
412
|
+
} else {
|
|
413
|
+
this.client = new Redis({
|
|
414
|
+
host: this.config.host ?? "localhost",
|
|
415
|
+
port: this.config.port ?? 6379,
|
|
416
|
+
password: this.config.password,
|
|
417
|
+
db: this.config.db ?? 0,
|
|
418
|
+
connectTimeout: this.config.connectTimeout ?? 1e4,
|
|
419
|
+
commandTimeout: this.config.commandTimeout ?? 5e3
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
await this.client.ping();
|
|
423
|
+
this.connected = true;
|
|
424
|
+
} catch (error) {
|
|
425
|
+
throw new Error(
|
|
426
|
+
`Failed to connect to Redis: ${error.message}`
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Ensure connected
|
|
432
|
+
*/
|
|
433
|
+
async ensureConnected() {
|
|
434
|
+
if (!this.connected || !this.client) {
|
|
435
|
+
await this.connect();
|
|
436
|
+
}
|
|
437
|
+
if (!this.client) {
|
|
438
|
+
throw new Error("Redis client not initialized");
|
|
439
|
+
}
|
|
440
|
+
return this.client;
|
|
441
|
+
}
|
|
442
|
+
async get(key) {
|
|
443
|
+
const client = await this.ensureConnected();
|
|
444
|
+
const data = await client.get(this.prefixKey(key));
|
|
445
|
+
if (!data) return void 0;
|
|
446
|
+
try {
|
|
447
|
+
const entry = JSON.parse(data);
|
|
448
|
+
entry.accessedAt = Date.now();
|
|
449
|
+
entry.accessCount++;
|
|
450
|
+
client.set(this.prefixKey(key), JSON.stringify(entry)).catch(() => {
|
|
451
|
+
});
|
|
452
|
+
return entry;
|
|
453
|
+
} catch {
|
|
454
|
+
return void 0;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
async set(key, entry) {
|
|
458
|
+
const client = await this.ensureConnected();
|
|
459
|
+
const data = JSON.stringify(entry);
|
|
460
|
+
const options = {};
|
|
461
|
+
if (entry.ttl > 0) {
|
|
462
|
+
options.EX = entry.ttl;
|
|
463
|
+
} else if (this.config.defaultTTL && this.config.defaultTTL > 0) {
|
|
464
|
+
options.EX = this.config.defaultTTL;
|
|
465
|
+
}
|
|
466
|
+
await client.set(this.prefixKey(key), data, options);
|
|
467
|
+
this.stats.entries++;
|
|
468
|
+
}
|
|
469
|
+
async has(key) {
|
|
470
|
+
const client = await this.ensureConnected();
|
|
471
|
+
const exists = await client.exists(this.prefixKey(key));
|
|
472
|
+
return exists > 0;
|
|
473
|
+
}
|
|
474
|
+
async delete(key) {
|
|
475
|
+
const client = await this.ensureConnected();
|
|
476
|
+
const deleted = await client.del(this.prefixKey(key));
|
|
477
|
+
if (deleted > 0) {
|
|
478
|
+
this.stats.deletes++;
|
|
479
|
+
this.stats.entries = Math.max(0, this.stats.entries - 1);
|
|
480
|
+
}
|
|
481
|
+
return deleted > 0;
|
|
482
|
+
}
|
|
483
|
+
async clear() {
|
|
484
|
+
const client = await this.ensureConnected();
|
|
485
|
+
const keys = await client.keys(this.prefixKey("*"));
|
|
486
|
+
if (keys.length > 0) {
|
|
487
|
+
await client.del(...keys);
|
|
488
|
+
}
|
|
489
|
+
this.stats.entries = 0;
|
|
490
|
+
}
|
|
491
|
+
async size() {
|
|
492
|
+
const client = await this.ensureConnected();
|
|
493
|
+
const keys = await client.keys(this.prefixKey("*"));
|
|
494
|
+
return keys.length;
|
|
495
|
+
}
|
|
496
|
+
async keys() {
|
|
497
|
+
const client = await this.ensureConnected();
|
|
498
|
+
const keys = await client.keys(this.prefixKey("*"));
|
|
499
|
+
const prefix = this.prefixKey("");
|
|
500
|
+
return keys.map((k) => k.slice(prefix.length));
|
|
501
|
+
}
|
|
502
|
+
async close() {
|
|
503
|
+
if (this.client) {
|
|
504
|
+
await this.client.quit();
|
|
505
|
+
this.client = null;
|
|
506
|
+
this.connected = false;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Add prefix to key
|
|
511
|
+
*/
|
|
512
|
+
prefixKey(key) {
|
|
513
|
+
const prefix = this.config.keyPrefix ?? this.options.keyPrefix ?? "emb";
|
|
514
|
+
return `${prefix}:${key}`;
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Check if connected
|
|
518
|
+
*/
|
|
519
|
+
isConnected() {
|
|
520
|
+
return this.connected;
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
function createRedisCache(options) {
|
|
524
|
+
return new RedisCache(options);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// src/caching/SQLiteCache.ts
|
|
528
|
+
var SQLiteCache = class extends BaseCache {
|
|
529
|
+
backendType = "sqlite";
|
|
530
|
+
db = null;
|
|
531
|
+
config;
|
|
532
|
+
initialized = false;
|
|
533
|
+
vacuumCounter = 0;
|
|
534
|
+
constructor(options = {}) {
|
|
535
|
+
super(options);
|
|
536
|
+
this.config = {
|
|
537
|
+
dbPath: options.dbPath ?? "./embeddings_cache.db",
|
|
538
|
+
inMemory: options.inMemory ?? false,
|
|
539
|
+
walMode: options.walMode ?? true,
|
|
540
|
+
busyTimeout: options.busyTimeout ?? 5e3,
|
|
541
|
+
autoVacuum: options.autoVacuum ?? true,
|
|
542
|
+
vacuumInterval: options.vacuumInterval ?? 1e3,
|
|
543
|
+
...options
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Initialize database
|
|
548
|
+
*/
|
|
549
|
+
async init() {
|
|
550
|
+
if (this.initialized) return;
|
|
551
|
+
try {
|
|
552
|
+
const Database = (await import("better-sqlite3")).default;
|
|
553
|
+
const dbPath = this.config.inMemory ? ":memory:" : this.config.dbPath;
|
|
554
|
+
this.db = new Database(dbPath);
|
|
555
|
+
if (this.config.walMode) {
|
|
556
|
+
this.db.exec("PRAGMA journal_mode = WAL");
|
|
557
|
+
}
|
|
558
|
+
if (this.config.busyTimeout) {
|
|
559
|
+
this.db.exec(`PRAGMA busy_timeout = ${this.config.busyTimeout}`);
|
|
560
|
+
}
|
|
561
|
+
this.db.exec(`
|
|
562
|
+
CREATE TABLE IF NOT EXISTS embeddings (
|
|
563
|
+
key TEXT PRIMARY KEY,
|
|
564
|
+
vector BLOB NOT NULL,
|
|
565
|
+
text TEXT,
|
|
566
|
+
model TEXT NOT NULL,
|
|
567
|
+
dimensions INTEGER NOT NULL,
|
|
568
|
+
token_count INTEGER NOT NULL,
|
|
569
|
+
created_at INTEGER NOT NULL,
|
|
570
|
+
accessed_at INTEGER NOT NULL,
|
|
571
|
+
access_count INTEGER DEFAULT 0,
|
|
572
|
+
ttl INTEGER DEFAULT 0,
|
|
573
|
+
version TEXT,
|
|
574
|
+
metadata TEXT
|
|
575
|
+
)
|
|
576
|
+
`);
|
|
577
|
+
this.db.exec(`
|
|
578
|
+
CREATE INDEX IF NOT EXISTS idx_model ON embeddings(model);
|
|
579
|
+
CREATE INDEX IF NOT EXISTS idx_created_at ON embeddings(created_at);
|
|
580
|
+
CREATE INDEX IF NOT EXISTS idx_accessed_at ON embeddings(accessed_at);
|
|
581
|
+
`);
|
|
582
|
+
this.initialized = true;
|
|
583
|
+
} catch (error) {
|
|
584
|
+
throw new Error(
|
|
585
|
+
`Failed to initialize SQLite: ${error.message}`
|
|
586
|
+
);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Ensure initialized
|
|
591
|
+
*/
|
|
592
|
+
async ensureInitialized() {
|
|
593
|
+
if (!this.initialized || !this.db) {
|
|
594
|
+
await this.init();
|
|
595
|
+
}
|
|
596
|
+
if (!this.db) {
|
|
597
|
+
throw new Error("SQLite database not initialized");
|
|
598
|
+
}
|
|
599
|
+
return this.db;
|
|
600
|
+
}
|
|
601
|
+
async get(key) {
|
|
602
|
+
const db = await this.ensureInitialized();
|
|
603
|
+
const stmt = db.prepare(`
|
|
604
|
+
SELECT * FROM embeddings WHERE key = ?
|
|
605
|
+
`);
|
|
606
|
+
const row = stmt.get(key);
|
|
607
|
+
if (!row) return void 0;
|
|
608
|
+
const ttl = row.ttl;
|
|
609
|
+
if (ttl > 0) {
|
|
610
|
+
const createdAt = row.created_at;
|
|
611
|
+
if (Date.now() > createdAt + ttl * 1e3) {
|
|
612
|
+
await this.delete(key);
|
|
613
|
+
return void 0;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
const updateStmt = db.prepare(`
|
|
617
|
+
UPDATE embeddings
|
|
618
|
+
SET accessed_at = ?, access_count = access_count + 1
|
|
619
|
+
WHERE key = ?
|
|
620
|
+
`);
|
|
621
|
+
updateStmt.run(Date.now(), key);
|
|
622
|
+
const vectorBuffer = row.vector;
|
|
623
|
+
const vector = Array.from(new Float32Array(vectorBuffer.buffer));
|
|
624
|
+
return {
|
|
625
|
+
key: row.key,
|
|
626
|
+
vector,
|
|
627
|
+
text: row.text,
|
|
628
|
+
model: row.model,
|
|
629
|
+
dimensions: row.dimensions,
|
|
630
|
+
tokenCount: row.token_count,
|
|
631
|
+
createdAt: row.created_at,
|
|
632
|
+
accessedAt: Date.now(),
|
|
633
|
+
accessCount: row.access_count + 1,
|
|
634
|
+
ttl,
|
|
635
|
+
version: row.version,
|
|
636
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : void 0
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
async set(key, entry) {
|
|
640
|
+
const db = await this.ensureInitialized();
|
|
641
|
+
const vectorBuffer = Buffer.from(new Float32Array(entry.vector).buffer);
|
|
642
|
+
const stmt = db.prepare(`
|
|
643
|
+
INSERT OR REPLACE INTO embeddings
|
|
644
|
+
(key, vector, text, model, dimensions, token_count, created_at, accessed_at, access_count, ttl, version, metadata)
|
|
645
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
646
|
+
`);
|
|
647
|
+
stmt.run(
|
|
648
|
+
entry.key,
|
|
649
|
+
vectorBuffer,
|
|
650
|
+
entry.text,
|
|
651
|
+
entry.model,
|
|
652
|
+
entry.dimensions,
|
|
653
|
+
entry.tokenCount,
|
|
654
|
+
entry.createdAt,
|
|
655
|
+
entry.accessedAt,
|
|
656
|
+
entry.accessCount,
|
|
657
|
+
entry.ttl,
|
|
658
|
+
entry.version,
|
|
659
|
+
entry.metadata ? JSON.stringify(entry.metadata) : null
|
|
660
|
+
);
|
|
661
|
+
this.stats.entries++;
|
|
662
|
+
this.maybeVacuum();
|
|
663
|
+
}
|
|
664
|
+
async has(key) {
|
|
665
|
+
const db = await this.ensureInitialized();
|
|
666
|
+
const stmt = db.prepare("SELECT 1 FROM embeddings WHERE key = ?");
|
|
667
|
+
return !!stmt.get(key);
|
|
668
|
+
}
|
|
669
|
+
async delete(key) {
|
|
670
|
+
const db = await this.ensureInitialized();
|
|
671
|
+
const stmt = db.prepare("DELETE FROM embeddings WHERE key = ?");
|
|
672
|
+
const result = stmt.run(key);
|
|
673
|
+
if (result.changes > 0) {
|
|
674
|
+
this.stats.deletes++;
|
|
675
|
+
this.stats.entries = Math.max(0, this.stats.entries - 1);
|
|
676
|
+
}
|
|
677
|
+
return result.changes > 0;
|
|
678
|
+
}
|
|
679
|
+
async clear() {
|
|
680
|
+
const db = await this.ensureInitialized();
|
|
681
|
+
db.exec("DELETE FROM embeddings");
|
|
682
|
+
this.stats.entries = 0;
|
|
683
|
+
}
|
|
684
|
+
async size() {
|
|
685
|
+
const db = await this.ensureInitialized();
|
|
686
|
+
const stmt = db.prepare("SELECT COUNT(*) as count FROM embeddings");
|
|
687
|
+
const row = stmt.get();
|
|
688
|
+
return row.count;
|
|
689
|
+
}
|
|
690
|
+
async keys() {
|
|
691
|
+
const db = await this.ensureInitialized();
|
|
692
|
+
const stmt = db.prepare("SELECT key FROM embeddings");
|
|
693
|
+
const rows = stmt.all();
|
|
694
|
+
return rows.map((r) => r.key);
|
|
695
|
+
}
|
|
696
|
+
async close() {
|
|
697
|
+
if (this.db) {
|
|
698
|
+
this.db.close();
|
|
699
|
+
this.db = null;
|
|
700
|
+
this.initialized = false;
|
|
701
|
+
}
|
|
702
|
+
return Promise.resolve();
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* Maybe run vacuum
|
|
706
|
+
*/
|
|
707
|
+
maybeVacuum() {
|
|
708
|
+
if (!this.config.autoVacuum) return;
|
|
709
|
+
this.vacuumCounter++;
|
|
710
|
+
if (this.vacuumCounter >= (this.config.vacuumInterval ?? 1e3)) {
|
|
711
|
+
this.vacuumCounter = 0;
|
|
712
|
+
this.vacuum().catch(() => {
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Run vacuum
|
|
718
|
+
*/
|
|
719
|
+
async vacuum() {
|
|
720
|
+
const db = await this.ensureInitialized();
|
|
721
|
+
db.exec("VACUUM");
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Remove expired entries
|
|
725
|
+
*/
|
|
726
|
+
async removeExpired() {
|
|
727
|
+
const db = await this.ensureInitialized();
|
|
728
|
+
const now = Date.now();
|
|
729
|
+
const stmt = db.prepare(`
|
|
730
|
+
DELETE FROM embeddings
|
|
731
|
+
WHERE ttl > 0 AND (created_at + ttl * 1000) < ?
|
|
732
|
+
`);
|
|
733
|
+
const result = stmt.run(now);
|
|
734
|
+
return result.changes;
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
function createSQLiteCache(options) {
|
|
738
|
+
return new SQLiteCache(options);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
// src/caching/TieredCache.ts
|
|
742
|
+
var TieredCache = class extends BaseCache {
|
|
743
|
+
backendType = "tiered";
|
|
744
|
+
tiers = [];
|
|
745
|
+
writeThrough;
|
|
746
|
+
promoteOnHit;
|
|
747
|
+
constructor(options) {
|
|
748
|
+
super(options);
|
|
749
|
+
this.writeThrough = options.writeThrough ?? true;
|
|
750
|
+
this.promoteOnHit = options.promoteOnHit ?? true;
|
|
751
|
+
this.initializeTiers(options.tiers);
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Initialize cache tiers
|
|
755
|
+
*/
|
|
756
|
+
initializeTiers(tierConfigs) {
|
|
757
|
+
const sorted = [...tierConfigs].sort((a, b) => a.priority - b.priority);
|
|
758
|
+
for (const config of sorted) {
|
|
759
|
+
let cache;
|
|
760
|
+
switch (config.type) {
|
|
761
|
+
case "memory":
|
|
762
|
+
cache = new MemoryCache(config.options);
|
|
763
|
+
break;
|
|
764
|
+
case "redis":
|
|
765
|
+
cache = new RedisCache(config.options);
|
|
766
|
+
break;
|
|
767
|
+
case "sqlite":
|
|
768
|
+
cache = new SQLiteCache(config.options);
|
|
769
|
+
break;
|
|
770
|
+
default:
|
|
771
|
+
continue;
|
|
772
|
+
}
|
|
773
|
+
this.tiers.push({
|
|
774
|
+
name: config.name,
|
|
775
|
+
cache,
|
|
776
|
+
priority: config.priority
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
/**
|
|
781
|
+
* Initialize all tier connections
|
|
782
|
+
*/
|
|
783
|
+
async init() {
|
|
784
|
+
for (const tier of this.tiers) {
|
|
785
|
+
if (tier.cache instanceof RedisCache) {
|
|
786
|
+
await tier.cache.connect();
|
|
787
|
+
} else if (tier.cache instanceof SQLiteCache) {
|
|
788
|
+
await tier.cache.init();
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
async get(key) {
|
|
793
|
+
let foundEntry;
|
|
794
|
+
let foundTierIndex = -1;
|
|
795
|
+
for (let i = 0; i < this.tiers.length; i++) {
|
|
796
|
+
const entry = await this.tiers[i].cache.get(key);
|
|
797
|
+
if (entry) {
|
|
798
|
+
foundEntry = entry;
|
|
799
|
+
foundTierIndex = i;
|
|
800
|
+
break;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
if (foundEntry && foundTierIndex > 0 && this.promoteOnHit) {
|
|
804
|
+
for (let i = 0; i < foundTierIndex; i++) {
|
|
805
|
+
await this.tiers[i].cache.set(key, foundEntry);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
return foundEntry;
|
|
809
|
+
}
|
|
810
|
+
async set(key, entry) {
|
|
811
|
+
if (this.writeThrough) {
|
|
812
|
+
for (const tier of this.tiers) {
|
|
813
|
+
await tier.cache.set(key, entry);
|
|
814
|
+
}
|
|
815
|
+
} else {
|
|
816
|
+
if (this.tiers.length > 0) {
|
|
817
|
+
await this.tiers[0].cache.set(key, entry);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
this.stats.entries++;
|
|
821
|
+
}
|
|
822
|
+
async has(key) {
|
|
823
|
+
for (const tier of this.tiers) {
|
|
824
|
+
if (await tier.cache.has(key)) {
|
|
825
|
+
return true;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
return false;
|
|
829
|
+
}
|
|
830
|
+
async delete(key) {
|
|
831
|
+
let deleted = false;
|
|
832
|
+
for (const tier of this.tiers) {
|
|
833
|
+
if (await tier.cache.delete(key)) {
|
|
834
|
+
deleted = true;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
if (deleted) {
|
|
838
|
+
this.stats.deletes++;
|
|
839
|
+
this.stats.entries = Math.max(0, this.stats.entries - 1);
|
|
840
|
+
}
|
|
841
|
+
return deleted;
|
|
842
|
+
}
|
|
843
|
+
async clear() {
|
|
844
|
+
for (const tier of this.tiers) {
|
|
845
|
+
await tier.cache.clear();
|
|
846
|
+
}
|
|
847
|
+
this.stats.entries = 0;
|
|
848
|
+
}
|
|
849
|
+
async size() {
|
|
850
|
+
if (this.tiers.length === 0) return 0;
|
|
851
|
+
return this.tiers[this.tiers.length - 1].cache.size();
|
|
852
|
+
}
|
|
853
|
+
async keys() {
|
|
854
|
+
const allKeys = /* @__PURE__ */ new Set();
|
|
855
|
+
for (const tier of this.tiers) {
|
|
856
|
+
const keys = await tier.cache.keys();
|
|
857
|
+
for (const key of keys) {
|
|
858
|
+
allKeys.add(key);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
return Array.from(allKeys);
|
|
862
|
+
}
|
|
863
|
+
async close() {
|
|
864
|
+
for (const tier of this.tiers) {
|
|
865
|
+
await tier.cache.close();
|
|
866
|
+
}
|
|
867
|
+
this.tiers = [];
|
|
868
|
+
}
|
|
869
|
+
/**
|
|
870
|
+
* Override lookup to track tier hits
|
|
871
|
+
*/
|
|
872
|
+
async lookup(key) {
|
|
873
|
+
const startTime = performance.now();
|
|
874
|
+
this.stats.gets++;
|
|
875
|
+
let foundEntry;
|
|
876
|
+
let foundTierName;
|
|
877
|
+
let foundTierIndex = -1;
|
|
878
|
+
for (let i = 0; i < this.tiers.length; i++) {
|
|
879
|
+
const entry = await this.tiers[i].cache.get(key);
|
|
880
|
+
if (entry) {
|
|
881
|
+
foundEntry = entry;
|
|
882
|
+
foundTierName = this.tiers[i].name;
|
|
883
|
+
foundTierIndex = i;
|
|
884
|
+
break;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
const latencyMs = performance.now() - startTime;
|
|
888
|
+
this.stats.avgGetLatencyMs = (this.stats.avgGetLatencyMs * (this.stats.gets - 1) + latencyMs) / this.stats.gets;
|
|
889
|
+
if (foundEntry) {
|
|
890
|
+
this.stats.hits++;
|
|
891
|
+
this.updateHitRate();
|
|
892
|
+
if (foundTierIndex > 0 && this.promoteOnHit) {
|
|
893
|
+
for (let i = 0; i < foundTierIndex; i++) {
|
|
894
|
+
await this.tiers[i].cache.set(key, foundEntry);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
return { hit: true, entry: foundEntry, tier: foundTierName, latencyMs };
|
|
898
|
+
} else {
|
|
899
|
+
this.stats.misses++;
|
|
900
|
+
this.updateHitRate();
|
|
901
|
+
return { hit: false, latencyMs };
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
/**
|
|
905
|
+
* Get statistics for all tiers
|
|
906
|
+
*/
|
|
907
|
+
getTierStats() {
|
|
908
|
+
const tierStats = {};
|
|
909
|
+
for (const tier of this.tiers) {
|
|
910
|
+
tierStats[tier.name] = tier.cache.getStats();
|
|
911
|
+
}
|
|
912
|
+
return tierStats;
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Get cache from specific tier
|
|
916
|
+
*/
|
|
917
|
+
getTier(name) {
|
|
918
|
+
return this.tiers.find((t) => t.name === name)?.cache;
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* Get all tier names
|
|
922
|
+
*/
|
|
923
|
+
getTierNames() {
|
|
924
|
+
return this.tiers.map((t) => t.name);
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Override getStats to include tier stats
|
|
928
|
+
*/
|
|
929
|
+
getStats() {
|
|
930
|
+
const stats = super.getStats();
|
|
931
|
+
return {
|
|
932
|
+
...stats,
|
|
933
|
+
tierStats: this.getTierStats()
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
};
|
|
937
|
+
function createTieredCache(options) {
|
|
938
|
+
return new TieredCache(options);
|
|
939
|
+
}
|
|
940
|
+
function createStandardTieredCache(options) {
|
|
941
|
+
const tiers = [
|
|
942
|
+
{
|
|
943
|
+
name: "memory",
|
|
944
|
+
type: "memory",
|
|
945
|
+
options: {
|
|
946
|
+
maxEntries: options?.memoryMaxEntries ?? 1e4
|
|
947
|
+
},
|
|
948
|
+
priority: 1
|
|
949
|
+
}
|
|
950
|
+
];
|
|
951
|
+
if (options?.useRedis && options.redisUrl) {
|
|
952
|
+
tiers.push({
|
|
953
|
+
name: "redis",
|
|
954
|
+
type: "redis",
|
|
955
|
+
options: {
|
|
956
|
+
url: options.redisUrl
|
|
957
|
+
},
|
|
958
|
+
priority: 2
|
|
959
|
+
});
|
|
960
|
+
} else {
|
|
961
|
+
tiers.push({
|
|
962
|
+
name: "sqlite",
|
|
963
|
+
type: "sqlite",
|
|
964
|
+
options: {
|
|
965
|
+
dbPath: options?.persistentPath ?? "./embeddings_cache.db"
|
|
966
|
+
},
|
|
967
|
+
priority: 2
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
return new TieredCache({
|
|
971
|
+
tiers,
|
|
972
|
+
writeThrough: true,
|
|
973
|
+
promoteOnHit: true
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// src/caching/index.ts
|
|
978
|
+
function createCache(type, options) {
|
|
979
|
+
switch (type) {
|
|
980
|
+
case "memory":
|
|
981
|
+
return new MemoryCache(options);
|
|
982
|
+
case "redis":
|
|
983
|
+
return new RedisCache(options);
|
|
984
|
+
case "sqlite":
|
|
985
|
+
return new SQLiteCache(options);
|
|
986
|
+
case "tiered":
|
|
987
|
+
return new TieredCache(options);
|
|
988
|
+
default:
|
|
989
|
+
return new MemoryCache(options);
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
993
|
+
0 && (module.exports = {
|
|
994
|
+
BaseCache,
|
|
995
|
+
MemoryCache,
|
|
996
|
+
RedisCache,
|
|
997
|
+
SQLiteCache,
|
|
998
|
+
TieredCache,
|
|
999
|
+
createCache,
|
|
1000
|
+
createMemoryCache,
|
|
1001
|
+
createRedisCache,
|
|
1002
|
+
createSQLiteCache,
|
|
1003
|
+
createStandardTieredCache,
|
|
1004
|
+
createTieredCache
|
|
1005
|
+
});
|