@llmops/core 0.1.4 → 0.1.5-beta.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/dist/index.cjs +493 -0
- package/dist/index.d.cts +183 -1
- package/dist/index.d.mts +183 -1
- package/dist/index.mjs +489 -2
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
const require_db = require('./db-C9-M-kdS.cjs');
|
|
2
2
|
let __llmops_gateway = require("@llmops/gateway");
|
|
3
3
|
__llmops_gateway = require_db.__toESM(__llmops_gateway);
|
|
4
|
+
let node_fs_promises = require("node:fs/promises");
|
|
5
|
+
node_fs_promises = require_db.__toESM(node_fs_promises);
|
|
6
|
+
let node_path = require("node:path");
|
|
7
|
+
node_path = require_db.__toESM(node_path);
|
|
4
8
|
let __better_auth_utils_random = require("@better-auth/utils/random");
|
|
5
9
|
let node_crypto = require("node:crypto");
|
|
6
10
|
|
|
@@ -465,6 +469,491 @@ function validateLLMOpsConfig(config) {
|
|
|
465
469
|
return result.data;
|
|
466
470
|
}
|
|
467
471
|
|
|
472
|
+
//#endregion
|
|
473
|
+
//#region src/cache/types.ts
|
|
474
|
+
/** Time constants in milliseconds for convenience */
|
|
475
|
+
const MS = {
|
|
476
|
+
"1_MINUTE": 60 * 1e3,
|
|
477
|
+
"5_MINUTES": 300 * 1e3,
|
|
478
|
+
"10_MINUTES": 600 * 1e3,
|
|
479
|
+
"30_MINUTES": 1800 * 1e3,
|
|
480
|
+
"1_HOUR": 3600 * 1e3,
|
|
481
|
+
"6_HOURS": 360 * 60 * 1e3,
|
|
482
|
+
"12_HOURS": 720 * 60 * 1e3,
|
|
483
|
+
"1_DAY": 1440 * 60 * 1e3,
|
|
484
|
+
"7_DAYS": 10080 * 60 * 1e3,
|
|
485
|
+
"30_DAYS": 720 * 60 * 60 * 1e3
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
//#endregion
|
|
489
|
+
//#region src/cache/backends/memory.ts
|
|
490
|
+
var MemoryCacheBackend = class {
|
|
491
|
+
cache = /* @__PURE__ */ new Map();
|
|
492
|
+
stats = {
|
|
493
|
+
hits: 0,
|
|
494
|
+
misses: 0,
|
|
495
|
+
sets: 0,
|
|
496
|
+
deletes: 0,
|
|
497
|
+
size: 0,
|
|
498
|
+
expired: 0
|
|
499
|
+
};
|
|
500
|
+
cleanupInterval;
|
|
501
|
+
maxSize;
|
|
502
|
+
constructor(maxSize = 1e4, cleanupIntervalMs = 6e4) {
|
|
503
|
+
this.maxSize = maxSize;
|
|
504
|
+
this.startCleanup(cleanupIntervalMs);
|
|
505
|
+
}
|
|
506
|
+
startCleanup(intervalMs) {
|
|
507
|
+
this.cleanupInterval = setInterval(() => {
|
|
508
|
+
this.cleanup();
|
|
509
|
+
}, intervalMs);
|
|
510
|
+
}
|
|
511
|
+
getFullKey(key, namespace) {
|
|
512
|
+
return namespace ? `${namespace}:${key}` : key;
|
|
513
|
+
}
|
|
514
|
+
isExpired(entry) {
|
|
515
|
+
return entry.expiresAt !== void 0 && entry.expiresAt <= Date.now();
|
|
516
|
+
}
|
|
517
|
+
evictIfNeeded() {
|
|
518
|
+
if (this.cache.size >= this.maxSize) {
|
|
519
|
+
const entries = Array.from(this.cache.entries());
|
|
520
|
+
entries.sort((a, b) => a[1].createdAt - b[1].createdAt);
|
|
521
|
+
const toRemove = Math.floor(this.maxSize * .1);
|
|
522
|
+
for (let i = 0; i < toRemove && i < entries.length; i++) this.cache.delete(entries[i][0]);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
async get(key, namespace) {
|
|
526
|
+
const fullKey = this.getFullKey(key, namespace);
|
|
527
|
+
const entry = this.cache.get(fullKey);
|
|
528
|
+
if (!entry) {
|
|
529
|
+
this.stats.misses++;
|
|
530
|
+
return null;
|
|
531
|
+
}
|
|
532
|
+
if (this.isExpired(entry)) {
|
|
533
|
+
this.cache.delete(fullKey);
|
|
534
|
+
this.stats.expired++;
|
|
535
|
+
this.stats.misses++;
|
|
536
|
+
return null;
|
|
537
|
+
}
|
|
538
|
+
this.stats.hits++;
|
|
539
|
+
return entry;
|
|
540
|
+
}
|
|
541
|
+
async set(key, value, options = {}) {
|
|
542
|
+
const fullKey = this.getFullKey(key, options.namespace);
|
|
543
|
+
const now = Date.now();
|
|
544
|
+
const entry = {
|
|
545
|
+
value,
|
|
546
|
+
createdAt: now,
|
|
547
|
+
expiresAt: options.ttl ? now + options.ttl : void 0,
|
|
548
|
+
metadata: options.metadata
|
|
549
|
+
};
|
|
550
|
+
this.evictIfNeeded();
|
|
551
|
+
this.cache.set(fullKey, entry);
|
|
552
|
+
this.stats.sets++;
|
|
553
|
+
this.stats.size = this.cache.size;
|
|
554
|
+
}
|
|
555
|
+
async delete(key, namespace) {
|
|
556
|
+
const fullKey = this.getFullKey(key, namespace);
|
|
557
|
+
const deleted = this.cache.delete(fullKey);
|
|
558
|
+
if (deleted) {
|
|
559
|
+
this.stats.deletes++;
|
|
560
|
+
this.stats.size = this.cache.size;
|
|
561
|
+
}
|
|
562
|
+
return deleted;
|
|
563
|
+
}
|
|
564
|
+
async clear(namespace) {
|
|
565
|
+
if (namespace) {
|
|
566
|
+
const prefix = `${namespace}:`;
|
|
567
|
+
const keysToDelete = Array.from(this.cache.keys()).filter((key) => key.startsWith(prefix));
|
|
568
|
+
for (const key of keysToDelete) this.cache.delete(key);
|
|
569
|
+
this.stats.deletes += keysToDelete.length;
|
|
570
|
+
} else {
|
|
571
|
+
this.stats.deletes += this.cache.size;
|
|
572
|
+
this.cache.clear();
|
|
573
|
+
}
|
|
574
|
+
this.stats.size = this.cache.size;
|
|
575
|
+
}
|
|
576
|
+
async has(key, namespace) {
|
|
577
|
+
const fullKey = this.getFullKey(key, namespace);
|
|
578
|
+
const entry = this.cache.get(fullKey);
|
|
579
|
+
if (!entry) return false;
|
|
580
|
+
if (this.isExpired(entry)) {
|
|
581
|
+
this.cache.delete(fullKey);
|
|
582
|
+
this.stats.expired++;
|
|
583
|
+
return false;
|
|
584
|
+
}
|
|
585
|
+
return true;
|
|
586
|
+
}
|
|
587
|
+
async keys(namespace) {
|
|
588
|
+
const allKeys = Array.from(this.cache.keys());
|
|
589
|
+
if (namespace) {
|
|
590
|
+
const prefix = `${namespace}:`;
|
|
591
|
+
return allKeys.filter((key) => key.startsWith(prefix)).map((key) => key.substring(prefix.length));
|
|
592
|
+
}
|
|
593
|
+
return allKeys;
|
|
594
|
+
}
|
|
595
|
+
async getStats(namespace) {
|
|
596
|
+
if (namespace) {
|
|
597
|
+
const prefix = `${namespace}:`;
|
|
598
|
+
const namespaceKeys = Array.from(this.cache.keys()).filter((key) => key.startsWith(prefix));
|
|
599
|
+
let expired = 0;
|
|
600
|
+
for (const key of namespaceKeys) {
|
|
601
|
+
const entry = this.cache.get(key);
|
|
602
|
+
if (entry && this.isExpired(entry)) expired++;
|
|
603
|
+
}
|
|
604
|
+
return {
|
|
605
|
+
...this.stats,
|
|
606
|
+
size: namespaceKeys.length,
|
|
607
|
+
expired
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
return { ...this.stats };
|
|
611
|
+
}
|
|
612
|
+
async cleanup() {
|
|
613
|
+
let expiredCount = 0;
|
|
614
|
+
for (const [key, entry] of this.cache.entries()) if (this.isExpired(entry)) {
|
|
615
|
+
this.cache.delete(key);
|
|
616
|
+
expiredCount++;
|
|
617
|
+
}
|
|
618
|
+
if (expiredCount > 0) {
|
|
619
|
+
this.stats.expired += expiredCount;
|
|
620
|
+
this.stats.size = this.cache.size;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
async close() {
|
|
624
|
+
if (this.cleanupInterval) {
|
|
625
|
+
clearInterval(this.cleanupInterval);
|
|
626
|
+
this.cleanupInterval = void 0;
|
|
627
|
+
}
|
|
628
|
+
this.cache.clear();
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
//#endregion
|
|
633
|
+
//#region src/cache/backends/file.ts
|
|
634
|
+
/**
|
|
635
|
+
* @file src/cache/backends/file.ts
|
|
636
|
+
* File-based cache backend implementation
|
|
637
|
+
*/
|
|
638
|
+
var FileCacheBackend = class {
|
|
639
|
+
cacheFile;
|
|
640
|
+
data = {};
|
|
641
|
+
saveTimer;
|
|
642
|
+
cleanupInterval;
|
|
643
|
+
loaded = false;
|
|
644
|
+
loadPromise;
|
|
645
|
+
stats = {
|
|
646
|
+
hits: 0,
|
|
647
|
+
misses: 0,
|
|
648
|
+
sets: 0,
|
|
649
|
+
deletes: 0,
|
|
650
|
+
size: 0,
|
|
651
|
+
expired: 0
|
|
652
|
+
};
|
|
653
|
+
saveInterval;
|
|
654
|
+
constructor(dataDir = "data", fileName = "cache.json", saveIntervalMs = 1e3, cleanupIntervalMs = 6e4) {
|
|
655
|
+
this.cacheFile = node_path.join(process.cwd(), dataDir, fileName);
|
|
656
|
+
this.saveInterval = saveIntervalMs;
|
|
657
|
+
this.loadPromise = this.loadCache();
|
|
658
|
+
this.loadPromise.then(() => {
|
|
659
|
+
this.startCleanup(cleanupIntervalMs);
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
/** Ensure cache is loaded before any operation */
|
|
663
|
+
async ensureLoaded() {
|
|
664
|
+
if (!this.loaded) await this.loadPromise;
|
|
665
|
+
}
|
|
666
|
+
async ensureDataDir() {
|
|
667
|
+
const dir = node_path.dirname(this.cacheFile);
|
|
668
|
+
try {
|
|
669
|
+
await node_fs_promises.mkdir(dir, { recursive: true });
|
|
670
|
+
} catch {}
|
|
671
|
+
}
|
|
672
|
+
async loadCache() {
|
|
673
|
+
try {
|
|
674
|
+
const content = await node_fs_promises.readFile(this.cacheFile, "utf-8");
|
|
675
|
+
this.data = JSON.parse(content);
|
|
676
|
+
this.updateStats();
|
|
677
|
+
this.loaded = true;
|
|
678
|
+
} catch {
|
|
679
|
+
this.data = {};
|
|
680
|
+
this.loaded = true;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
async saveCache() {
|
|
684
|
+
try {
|
|
685
|
+
await this.ensureDataDir();
|
|
686
|
+
await node_fs_promises.writeFile(this.cacheFile, JSON.stringify(this.data, null, 2));
|
|
687
|
+
} catch {}
|
|
688
|
+
}
|
|
689
|
+
scheduleSave() {
|
|
690
|
+
if (this.saveTimer) clearTimeout(this.saveTimer);
|
|
691
|
+
this.saveTimer = setTimeout(() => {
|
|
692
|
+
this.saveCache();
|
|
693
|
+
this.saveTimer = void 0;
|
|
694
|
+
}, this.saveInterval);
|
|
695
|
+
}
|
|
696
|
+
startCleanup(intervalMs) {
|
|
697
|
+
this.cleanupInterval = setInterval(() => {
|
|
698
|
+
this.cleanup();
|
|
699
|
+
}, intervalMs);
|
|
700
|
+
}
|
|
701
|
+
isExpired(entry) {
|
|
702
|
+
return entry.expiresAt !== void 0 && entry.expiresAt <= Date.now();
|
|
703
|
+
}
|
|
704
|
+
updateStats() {
|
|
705
|
+
let totalSize = 0;
|
|
706
|
+
let totalExpired = 0;
|
|
707
|
+
for (const namespace of Object.values(this.data)) for (const entry of Object.values(namespace)) {
|
|
708
|
+
totalSize++;
|
|
709
|
+
if (this.isExpired(entry)) totalExpired++;
|
|
710
|
+
}
|
|
711
|
+
this.stats.size = totalSize;
|
|
712
|
+
this.stats.expired = totalExpired;
|
|
713
|
+
}
|
|
714
|
+
getNamespaceData(namespace = "default") {
|
|
715
|
+
if (!this.data[namespace]) this.data[namespace] = {};
|
|
716
|
+
return this.data[namespace];
|
|
717
|
+
}
|
|
718
|
+
async get(key, namespace) {
|
|
719
|
+
await this.ensureLoaded();
|
|
720
|
+
const namespaceData = this.getNamespaceData(namespace);
|
|
721
|
+
const entry = namespaceData[key];
|
|
722
|
+
if (!entry) {
|
|
723
|
+
this.stats.misses++;
|
|
724
|
+
return null;
|
|
725
|
+
}
|
|
726
|
+
if (this.isExpired(entry)) {
|
|
727
|
+
delete namespaceData[key];
|
|
728
|
+
this.stats.expired++;
|
|
729
|
+
this.stats.misses++;
|
|
730
|
+
this.scheduleSave();
|
|
731
|
+
return null;
|
|
732
|
+
}
|
|
733
|
+
this.stats.hits++;
|
|
734
|
+
return entry;
|
|
735
|
+
}
|
|
736
|
+
async set(key, value, options = {}) {
|
|
737
|
+
await this.ensureLoaded();
|
|
738
|
+
const namespace = options.namespace || "default";
|
|
739
|
+
const namespaceData = this.getNamespaceData(namespace);
|
|
740
|
+
const now = Date.now();
|
|
741
|
+
namespaceData[key] = {
|
|
742
|
+
value,
|
|
743
|
+
createdAt: now,
|
|
744
|
+
expiresAt: options.ttl ? now + options.ttl : void 0,
|
|
745
|
+
metadata: options.metadata
|
|
746
|
+
};
|
|
747
|
+
this.stats.sets++;
|
|
748
|
+
this.updateStats();
|
|
749
|
+
this.scheduleSave();
|
|
750
|
+
}
|
|
751
|
+
async delete(key, namespace) {
|
|
752
|
+
const namespaceData = this.getNamespaceData(namespace);
|
|
753
|
+
const existed = key in namespaceData;
|
|
754
|
+
if (existed) {
|
|
755
|
+
delete namespaceData[key];
|
|
756
|
+
this.stats.deletes++;
|
|
757
|
+
this.updateStats();
|
|
758
|
+
this.scheduleSave();
|
|
759
|
+
}
|
|
760
|
+
return existed;
|
|
761
|
+
}
|
|
762
|
+
async clear(namespace) {
|
|
763
|
+
if (namespace) {
|
|
764
|
+
const namespaceData = this.getNamespaceData(namespace);
|
|
765
|
+
const count = Object.keys(namespaceData).length;
|
|
766
|
+
this.data[namespace] = {};
|
|
767
|
+
this.stats.deletes += count;
|
|
768
|
+
} else {
|
|
769
|
+
const totalCount = Object.values(this.data).reduce((sum, ns) => sum + Object.keys(ns).length, 0);
|
|
770
|
+
this.data = {};
|
|
771
|
+
this.stats.deletes += totalCount;
|
|
772
|
+
}
|
|
773
|
+
this.updateStats();
|
|
774
|
+
this.scheduleSave();
|
|
775
|
+
}
|
|
776
|
+
async has(key, namespace) {
|
|
777
|
+
const namespaceData = this.getNamespaceData(namespace);
|
|
778
|
+
const entry = namespaceData[key];
|
|
779
|
+
if (!entry) return false;
|
|
780
|
+
if (this.isExpired(entry)) {
|
|
781
|
+
delete namespaceData[key];
|
|
782
|
+
this.stats.expired++;
|
|
783
|
+
this.scheduleSave();
|
|
784
|
+
return false;
|
|
785
|
+
}
|
|
786
|
+
return true;
|
|
787
|
+
}
|
|
788
|
+
async keys(namespace) {
|
|
789
|
+
if (namespace) {
|
|
790
|
+
const namespaceData = this.getNamespaceData(namespace);
|
|
791
|
+
return Object.keys(namespaceData);
|
|
792
|
+
}
|
|
793
|
+
const allKeys = [];
|
|
794
|
+
for (const namespaceData of Object.values(this.data)) allKeys.push(...Object.keys(namespaceData));
|
|
795
|
+
return allKeys;
|
|
796
|
+
}
|
|
797
|
+
async getStats(namespace) {
|
|
798
|
+
if (namespace) {
|
|
799
|
+
const namespaceData = this.getNamespaceData(namespace);
|
|
800
|
+
const keys = Object.keys(namespaceData);
|
|
801
|
+
let expired = 0;
|
|
802
|
+
for (const key of keys) {
|
|
803
|
+
const entry = namespaceData[key];
|
|
804
|
+
if (this.isExpired(entry)) expired++;
|
|
805
|
+
}
|
|
806
|
+
return {
|
|
807
|
+
...this.stats,
|
|
808
|
+
size: keys.length,
|
|
809
|
+
expired
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
this.updateStats();
|
|
813
|
+
return { ...this.stats };
|
|
814
|
+
}
|
|
815
|
+
async cleanup() {
|
|
816
|
+
let expiredCount = 0;
|
|
817
|
+
let hasChanges = false;
|
|
818
|
+
for (const [, namespaceData] of Object.entries(this.data)) for (const [key, entry] of Object.entries(namespaceData)) if (this.isExpired(entry)) {
|
|
819
|
+
delete namespaceData[key];
|
|
820
|
+
expiredCount++;
|
|
821
|
+
hasChanges = true;
|
|
822
|
+
}
|
|
823
|
+
if (hasChanges) {
|
|
824
|
+
this.stats.expired += expiredCount;
|
|
825
|
+
this.updateStats();
|
|
826
|
+
this.scheduleSave();
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
/** Wait for the cache to be ready (file loaded) */
|
|
830
|
+
async waitForReady() {
|
|
831
|
+
await this.loadPromise;
|
|
832
|
+
}
|
|
833
|
+
async close() {
|
|
834
|
+
if (this.saveTimer) {
|
|
835
|
+
clearTimeout(this.saveTimer);
|
|
836
|
+
await this.saveCache();
|
|
837
|
+
}
|
|
838
|
+
if (this.cleanupInterval) {
|
|
839
|
+
clearInterval(this.cleanupInterval);
|
|
840
|
+
this.cleanupInterval = void 0;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
//#endregion
|
|
846
|
+
//#region src/cache/service.ts
|
|
847
|
+
/**
|
|
848
|
+
* @file src/cache/service.ts
|
|
849
|
+
* Unified cache service with pluggable backends
|
|
850
|
+
*/
|
|
851
|
+
var CacheService = class {
|
|
852
|
+
backend;
|
|
853
|
+
defaultTtl;
|
|
854
|
+
constructor(config) {
|
|
855
|
+
this.defaultTtl = config.defaultTtl;
|
|
856
|
+
this.backend = this.createBackend(config);
|
|
857
|
+
}
|
|
858
|
+
createBackend(config) {
|
|
859
|
+
switch (config.backend) {
|
|
860
|
+
case "memory": return new MemoryCacheBackend(config.maxSize, config.cleanupInterval);
|
|
861
|
+
case "file": return new FileCacheBackend(config.dataDir, config.fileName, config.saveInterval, config.cleanupInterval);
|
|
862
|
+
default: throw new Error(`Unsupported cache backend: ${config.backend}`);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
/** Get a value from the cache */
|
|
866
|
+
async get(key, namespace) {
|
|
867
|
+
const entry = await this.backend.get(key, namespace);
|
|
868
|
+
return entry ? entry.value : null;
|
|
869
|
+
}
|
|
870
|
+
/** Get the full cache entry (with metadata) */
|
|
871
|
+
async getEntry(key, namespace) {
|
|
872
|
+
return this.backend.get(key, namespace);
|
|
873
|
+
}
|
|
874
|
+
/** Set a value in the cache */
|
|
875
|
+
async set(key, value, options = {}) {
|
|
876
|
+
const finalOptions = {
|
|
877
|
+
...options,
|
|
878
|
+
ttl: options.ttl ?? this.defaultTtl
|
|
879
|
+
};
|
|
880
|
+
await this.backend.set(key, value, finalOptions);
|
|
881
|
+
}
|
|
882
|
+
/** Set a value with TTL in seconds (convenience method) */
|
|
883
|
+
async setWithTtl(key, value, ttlSeconds, namespace) {
|
|
884
|
+
await this.set(key, value, {
|
|
885
|
+
ttl: ttlSeconds * 1e3,
|
|
886
|
+
namespace
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
/** Delete a value from the cache */
|
|
890
|
+
async delete(key, namespace) {
|
|
891
|
+
return this.backend.delete(key, namespace);
|
|
892
|
+
}
|
|
893
|
+
/** Check if a key exists in the cache */
|
|
894
|
+
async has(key, namespace) {
|
|
895
|
+
return this.backend.has(key, namespace);
|
|
896
|
+
}
|
|
897
|
+
/** Get all keys in a namespace */
|
|
898
|
+
async keys(namespace) {
|
|
899
|
+
return this.backend.keys(namespace);
|
|
900
|
+
}
|
|
901
|
+
/** Clear all entries in a namespace (or all entries if no namespace) */
|
|
902
|
+
async clear(namespace) {
|
|
903
|
+
await this.backend.clear(namespace);
|
|
904
|
+
}
|
|
905
|
+
/** Get cache statistics */
|
|
906
|
+
async getStats(namespace) {
|
|
907
|
+
return this.backend.getStats(namespace);
|
|
908
|
+
}
|
|
909
|
+
/** Manually trigger cleanup of expired entries */
|
|
910
|
+
async cleanup() {
|
|
911
|
+
await this.backend.cleanup();
|
|
912
|
+
}
|
|
913
|
+
/** Wait for the backend to be ready */
|
|
914
|
+
async waitForReady() {
|
|
915
|
+
if ("waitForReady" in this.backend) await this.backend.waitForReady();
|
|
916
|
+
}
|
|
917
|
+
/** Close the cache and cleanup resources */
|
|
918
|
+
async close() {
|
|
919
|
+
await this.backend.close();
|
|
920
|
+
}
|
|
921
|
+
/** Get or set pattern - get value, or compute and cache it if not found */
|
|
922
|
+
async getOrSet(key, factory, options = {}) {
|
|
923
|
+
const existing = await this.get(key, options.namespace);
|
|
924
|
+
if (existing !== null) return existing;
|
|
925
|
+
const value = await factory();
|
|
926
|
+
await this.set(key, value, options);
|
|
927
|
+
return value;
|
|
928
|
+
}
|
|
929
|
+
/** Increment a numeric value (simulated atomic operation) */
|
|
930
|
+
async increment(key, delta = 1, options = {}) {
|
|
931
|
+
const newValue = (await this.get(key, options.namespace) || 0) + delta;
|
|
932
|
+
await this.set(key, newValue, options);
|
|
933
|
+
return newValue;
|
|
934
|
+
}
|
|
935
|
+
/** Set multiple values at once */
|
|
936
|
+
async setMany(entries, defaultOptions = {}) {
|
|
937
|
+
const promises = entries.map(({ key, value, options }) => this.set(key, value, {
|
|
938
|
+
...defaultOptions,
|
|
939
|
+
...options
|
|
940
|
+
}));
|
|
941
|
+
await Promise.all(promises);
|
|
942
|
+
}
|
|
943
|
+
/** Get multiple values at once */
|
|
944
|
+
async getMany(keys, namespace) {
|
|
945
|
+
const promises = keys.map(async (key) => ({
|
|
946
|
+
key,
|
|
947
|
+
value: await this.get(key, namespace)
|
|
948
|
+
}));
|
|
949
|
+
return Promise.all(promises);
|
|
950
|
+
}
|
|
951
|
+
/** Get the underlying backend (for advanced use cases) */
|
|
952
|
+
getBackend() {
|
|
953
|
+
return this.backend;
|
|
954
|
+
}
|
|
955
|
+
};
|
|
956
|
+
|
|
468
957
|
//#endregion
|
|
469
958
|
//#region src/utils/id.ts
|
|
470
959
|
const generateId = (size) => {
|
|
@@ -1387,6 +1876,10 @@ const createDataLayer = async (db) => {
|
|
|
1387
1876
|
};
|
|
1388
1877
|
|
|
1389
1878
|
//#endregion
|
|
1879
|
+
exports.CacheService = CacheService;
|
|
1880
|
+
exports.FileCacheBackend = FileCacheBackend;
|
|
1881
|
+
exports.MS = MS;
|
|
1882
|
+
exports.MemoryCacheBackend = MemoryCacheBackend;
|
|
1390
1883
|
exports.SCHEMA_METADATA = require_db.SCHEMA_METADATA;
|
|
1391
1884
|
exports.SupportedProviders = SupportedProviders;
|
|
1392
1885
|
exports.chatCompletionCreateParamsBaseSchema = chatCompletionCreateParamsBaseSchema;
|
package/dist/index.d.cts
CHANGED
|
@@ -1323,6 +1323,188 @@ declare const variantJsonDataSchema: z.ZodObject<{
|
|
|
1323
1323
|
}, z.core.$strip>;
|
|
1324
1324
|
type VariantJsonData = z.infer<typeof variantJsonDataSchema>;
|
|
1325
1325
|
//#endregion
|
|
1326
|
+
//#region src/cache/types.d.ts
|
|
1327
|
+
/**
|
|
1328
|
+
* @file src/cache/types.ts
|
|
1329
|
+
* Type definitions for the unified cache system
|
|
1330
|
+
*/
|
|
1331
|
+
interface CacheEntry<T = unknown> {
|
|
1332
|
+
value: T;
|
|
1333
|
+
expiresAt?: number;
|
|
1334
|
+
createdAt: number;
|
|
1335
|
+
metadata?: Record<string, unknown>;
|
|
1336
|
+
}
|
|
1337
|
+
interface CacheOptions {
|
|
1338
|
+
/** Time to live in milliseconds */
|
|
1339
|
+
ttl?: number;
|
|
1340
|
+
/** Cache namespace for organization */
|
|
1341
|
+
namespace?: string;
|
|
1342
|
+
/** Additional metadata */
|
|
1343
|
+
metadata?: Record<string, unknown>;
|
|
1344
|
+
}
|
|
1345
|
+
interface CacheStats {
|
|
1346
|
+
hits: number;
|
|
1347
|
+
misses: number;
|
|
1348
|
+
sets: number;
|
|
1349
|
+
deletes: number;
|
|
1350
|
+
size: number;
|
|
1351
|
+
expired: number;
|
|
1352
|
+
}
|
|
1353
|
+
interface CacheBackend {
|
|
1354
|
+
get<T = unknown>(key: string, namespace?: string): Promise<CacheEntry<T> | null>;
|
|
1355
|
+
set<T = unknown>(key: string, value: T, options?: CacheOptions): Promise<void>;
|
|
1356
|
+
delete(key: string, namespace?: string): Promise<boolean>;
|
|
1357
|
+
clear(namespace?: string): Promise<void>;
|
|
1358
|
+
has(key: string, namespace?: string): Promise<boolean>;
|
|
1359
|
+
keys(namespace?: string): Promise<string[]>;
|
|
1360
|
+
getStats(namespace?: string): Promise<CacheStats>;
|
|
1361
|
+
/** Remove expired entries */
|
|
1362
|
+
cleanup(): Promise<void>;
|
|
1363
|
+
/** Cleanup resources */
|
|
1364
|
+
close(): Promise<void>;
|
|
1365
|
+
}
|
|
1366
|
+
type CacheBackendType = 'memory' | 'file';
|
|
1367
|
+
interface BaseCacheConfig {
|
|
1368
|
+
backend: CacheBackendType;
|
|
1369
|
+
/** Default TTL in milliseconds */
|
|
1370
|
+
defaultTtl?: number;
|
|
1371
|
+
/** Cleanup interval in milliseconds */
|
|
1372
|
+
cleanupInterval?: number;
|
|
1373
|
+
}
|
|
1374
|
+
interface MemoryCacheConfig extends BaseCacheConfig {
|
|
1375
|
+
backend: 'memory';
|
|
1376
|
+
/** Maximum number of entries */
|
|
1377
|
+
maxSize?: number;
|
|
1378
|
+
}
|
|
1379
|
+
interface FileCacheConfig extends BaseCacheConfig {
|
|
1380
|
+
backend: 'file';
|
|
1381
|
+
/** Data directory path */
|
|
1382
|
+
dataDir?: string;
|
|
1383
|
+
/** Cache file name */
|
|
1384
|
+
fileName?: string;
|
|
1385
|
+
/** Debounce save interval in milliseconds */
|
|
1386
|
+
saveInterval?: number;
|
|
1387
|
+
}
|
|
1388
|
+
type CacheConfig = MemoryCacheConfig | FileCacheConfig;
|
|
1389
|
+
/** Time constants in milliseconds for convenience */
|
|
1390
|
+
declare const MS: {
|
|
1391
|
+
readonly '1_MINUTE': number;
|
|
1392
|
+
readonly '5_MINUTES': number;
|
|
1393
|
+
readonly '10_MINUTES': number;
|
|
1394
|
+
readonly '30_MINUTES': number;
|
|
1395
|
+
readonly '1_HOUR': number;
|
|
1396
|
+
readonly '6_HOURS': number;
|
|
1397
|
+
readonly '12_HOURS': number;
|
|
1398
|
+
readonly '1_DAY': number;
|
|
1399
|
+
readonly '7_DAYS': number;
|
|
1400
|
+
readonly '30_DAYS': number;
|
|
1401
|
+
};
|
|
1402
|
+
//#endregion
|
|
1403
|
+
//#region src/cache/backends/memory.d.ts
|
|
1404
|
+
declare class MemoryCacheBackend implements CacheBackend {
|
|
1405
|
+
private cache;
|
|
1406
|
+
private stats;
|
|
1407
|
+
private cleanupInterval?;
|
|
1408
|
+
private maxSize;
|
|
1409
|
+
constructor(maxSize?: number, cleanupIntervalMs?: number);
|
|
1410
|
+
private startCleanup;
|
|
1411
|
+
private getFullKey;
|
|
1412
|
+
private isExpired;
|
|
1413
|
+
private evictIfNeeded;
|
|
1414
|
+
get<T = unknown>(key: string, namespace?: string): Promise<CacheEntry<T> | null>;
|
|
1415
|
+
set<T = unknown>(key: string, value: T, options?: CacheOptions): Promise<void>;
|
|
1416
|
+
delete(key: string, namespace?: string): Promise<boolean>;
|
|
1417
|
+
clear(namespace?: string): Promise<void>;
|
|
1418
|
+
has(key: string, namespace?: string): Promise<boolean>;
|
|
1419
|
+
keys(namespace?: string): Promise<string[]>;
|
|
1420
|
+
getStats(namespace?: string): Promise<CacheStats>;
|
|
1421
|
+
cleanup(): Promise<void>;
|
|
1422
|
+
close(): Promise<void>;
|
|
1423
|
+
}
|
|
1424
|
+
//#endregion
|
|
1425
|
+
//#region src/cache/backends/file.d.ts
|
|
1426
|
+
declare class FileCacheBackend implements CacheBackend {
|
|
1427
|
+
private cacheFile;
|
|
1428
|
+
private data;
|
|
1429
|
+
private saveTimer?;
|
|
1430
|
+
private cleanupInterval?;
|
|
1431
|
+
private loaded;
|
|
1432
|
+
private loadPromise;
|
|
1433
|
+
private stats;
|
|
1434
|
+
private saveInterval;
|
|
1435
|
+
constructor(dataDir?: string, fileName?: string, saveIntervalMs?: number, cleanupIntervalMs?: number);
|
|
1436
|
+
/** Ensure cache is loaded before any operation */
|
|
1437
|
+
private ensureLoaded;
|
|
1438
|
+
private ensureDataDir;
|
|
1439
|
+
private loadCache;
|
|
1440
|
+
private saveCache;
|
|
1441
|
+
private scheduleSave;
|
|
1442
|
+
private startCleanup;
|
|
1443
|
+
private isExpired;
|
|
1444
|
+
private updateStats;
|
|
1445
|
+
private getNamespaceData;
|
|
1446
|
+
get<T = unknown>(key: string, namespace?: string): Promise<CacheEntry<T> | null>;
|
|
1447
|
+
set<T = unknown>(key: string, value: T, options?: CacheOptions): Promise<void>;
|
|
1448
|
+
delete(key: string, namespace?: string): Promise<boolean>;
|
|
1449
|
+
clear(namespace?: string): Promise<void>;
|
|
1450
|
+
has(key: string, namespace?: string): Promise<boolean>;
|
|
1451
|
+
keys(namespace?: string): Promise<string[]>;
|
|
1452
|
+
getStats(namespace?: string): Promise<CacheStats>;
|
|
1453
|
+
cleanup(): Promise<void>;
|
|
1454
|
+
/** Wait for the cache to be ready (file loaded) */
|
|
1455
|
+
waitForReady(): Promise<void>;
|
|
1456
|
+
close(): Promise<void>;
|
|
1457
|
+
}
|
|
1458
|
+
//#endregion
|
|
1459
|
+
//#region src/cache/service.d.ts
|
|
1460
|
+
declare class CacheService {
|
|
1461
|
+
private backend;
|
|
1462
|
+
private defaultTtl?;
|
|
1463
|
+
constructor(config: CacheConfig);
|
|
1464
|
+
private createBackend;
|
|
1465
|
+
/** Get a value from the cache */
|
|
1466
|
+
get<T = unknown>(key: string, namespace?: string): Promise<T | null>;
|
|
1467
|
+
/** Get the full cache entry (with metadata) */
|
|
1468
|
+
getEntry<T = unknown>(key: string, namespace?: string): Promise<CacheEntry<T> | null>;
|
|
1469
|
+
/** Set a value in the cache */
|
|
1470
|
+
set<T = unknown>(key: string, value: T, options?: CacheOptions): Promise<void>;
|
|
1471
|
+
/** Set a value with TTL in seconds (convenience method) */
|
|
1472
|
+
setWithTtl<T = unknown>(key: string, value: T, ttlSeconds: number, namespace?: string): Promise<void>;
|
|
1473
|
+
/** Delete a value from the cache */
|
|
1474
|
+
delete(key: string, namespace?: string): Promise<boolean>;
|
|
1475
|
+
/** Check if a key exists in the cache */
|
|
1476
|
+
has(key: string, namespace?: string): Promise<boolean>;
|
|
1477
|
+
/** Get all keys in a namespace */
|
|
1478
|
+
keys(namespace?: string): Promise<string[]>;
|
|
1479
|
+
/** Clear all entries in a namespace (or all entries if no namespace) */
|
|
1480
|
+
clear(namespace?: string): Promise<void>;
|
|
1481
|
+
/** Get cache statistics */
|
|
1482
|
+
getStats(namespace?: string): Promise<CacheStats>;
|
|
1483
|
+
/** Manually trigger cleanup of expired entries */
|
|
1484
|
+
cleanup(): Promise<void>;
|
|
1485
|
+
/** Wait for the backend to be ready */
|
|
1486
|
+
waitForReady(): Promise<void>;
|
|
1487
|
+
/** Close the cache and cleanup resources */
|
|
1488
|
+
close(): Promise<void>;
|
|
1489
|
+
/** Get or set pattern - get value, or compute and cache it if not found */
|
|
1490
|
+
getOrSet<T = unknown>(key: string, factory: () => Promise<T> | T, options?: CacheOptions): Promise<T>;
|
|
1491
|
+
/** Increment a numeric value (simulated atomic operation) */
|
|
1492
|
+
increment(key: string, delta?: number, options?: CacheOptions): Promise<number>;
|
|
1493
|
+
/** Set multiple values at once */
|
|
1494
|
+
setMany<T = unknown>(entries: Array<{
|
|
1495
|
+
key: string;
|
|
1496
|
+
value: T;
|
|
1497
|
+
options?: CacheOptions;
|
|
1498
|
+
}>, defaultOptions?: CacheOptions): Promise<void>;
|
|
1499
|
+
/** Get multiple values at once */
|
|
1500
|
+
getMany<T = unknown>(keys: string[], namespace?: string): Promise<Array<{
|
|
1501
|
+
key: string;
|
|
1502
|
+
value: T | null;
|
|
1503
|
+
}>>;
|
|
1504
|
+
/** Get the underlying backend (for advanced use cases) */
|
|
1505
|
+
getBackend(): CacheBackend;
|
|
1506
|
+
}
|
|
1507
|
+
//#endregion
|
|
1326
1508
|
//#region src/utils/logger.d.ts
|
|
1327
1509
|
declare const logger: pino.Logger<never, boolean>;
|
|
1328
1510
|
//#endregion
|
|
@@ -2114,4 +2296,4 @@ declare const createDataLayer: (db: Kysely<Database>) => Promise<{
|
|
|
2114
2296
|
}[]>;
|
|
2115
2297
|
}>;
|
|
2116
2298
|
//#endregion
|
|
2117
|
-
export { type AnthropicProviderConfig, type AnyProviderConfig, type AuthConfig, AutoMigrateConfig, type AzureAIProviderConfig, type AzureOpenAIProviderConfig, type BaseProviderConfig, type BasicAuthConfig, type BedrockProviderConfig, ChatCompletionCreateParamsBase, Config, ConfigVariant, ConfigVariantsTable, ConfigsTable, type CortexProviderConfig, Database, DatabaseConnection, DatabaseOptions, DatabaseType, Environment, EnvironmentSecret, EnvironmentSecretsTable, EnvironmentsTable, type FireworksAIProviderConfig, type GoogleProviderConfig, type HuggingFaceProviderConfig, Insertable, LLMOpsClient, LLMOpsConfig, type LLMOpsConfigInput, MigrationOptions, MigrationResult, type MistralAIProviderConfig, type OpenAIProviderConfig, type OracleProviderConfig, Prettify, type ProviderConfigMap, type ProvidersConfig, SCHEMA_METADATA, type SagemakerProviderConfig, Selectable, type StabilityAIProviderConfig, SupportedProviders, TableName, TargetingRule, TargetingRulesTable, Updateable, type ValidatedLLMOpsConfig, Variant, VariantJsonData, VariantVersion, VariantVersionsTable, VariantsTable, type VertexAIProviderConfig, type WorkersAIProviderConfig, WorkspaceSettings, WorkspaceSettingsTable, chatCompletionCreateParamsBaseSchema, configVariantsSchema, configsSchema, createDataLayer, createDatabase, createDatabaseFromConnection, detectDatabaseType, environmentSecretsSchema, environmentsSchema, gateway, generateId, getMigrations, llmopsConfigSchema, logger, matchType, parsePartialTableData, parseTableData, runAutoMigrations, schemas, targetingRulesSchema, validateLLMOpsConfig, validatePartialTableData, validateTableData, variantJsonDataSchema, variantVersionsSchema, variantsSchema, workspaceSettingsSchema };
|
|
2299
|
+
export { type AnthropicProviderConfig, type AnyProviderConfig, type AuthConfig, AutoMigrateConfig, type AzureAIProviderConfig, type AzureOpenAIProviderConfig, BaseCacheConfig, type BaseProviderConfig, type BasicAuthConfig, type BedrockProviderConfig, CacheBackend, CacheBackendType, CacheConfig, CacheEntry, CacheOptions, CacheService, CacheStats, ChatCompletionCreateParamsBase, Config, ConfigVariant, ConfigVariantsTable, ConfigsTable, type CortexProviderConfig, Database, DatabaseConnection, DatabaseOptions, DatabaseType, Environment, EnvironmentSecret, EnvironmentSecretsTable, EnvironmentsTable, FileCacheBackend, FileCacheConfig, type FireworksAIProviderConfig, type GoogleProviderConfig, type HuggingFaceProviderConfig, Insertable, LLMOpsClient, LLMOpsConfig, type LLMOpsConfigInput, MS, MemoryCacheBackend, MemoryCacheConfig, MigrationOptions, MigrationResult, type MistralAIProviderConfig, type OpenAIProviderConfig, type OracleProviderConfig, Prettify, type ProviderConfigMap, type ProvidersConfig, SCHEMA_METADATA, type SagemakerProviderConfig, Selectable, type StabilityAIProviderConfig, SupportedProviders, TableName, TargetingRule, TargetingRulesTable, Updateable, type ValidatedLLMOpsConfig, Variant, VariantJsonData, VariantVersion, VariantVersionsTable, VariantsTable, type VertexAIProviderConfig, type WorkersAIProviderConfig, WorkspaceSettings, WorkspaceSettingsTable, chatCompletionCreateParamsBaseSchema, configVariantsSchema, configsSchema, createDataLayer, createDatabase, createDatabaseFromConnection, detectDatabaseType, environmentSecretsSchema, environmentsSchema, gateway, generateId, getMigrations, llmopsConfigSchema, logger, matchType, parsePartialTableData, parseTableData, runAutoMigrations, schemas, targetingRulesSchema, validateLLMOpsConfig, validatePartialTableData, validateTableData, variantJsonDataSchema, variantVersionsSchema, variantsSchema, workspaceSettingsSchema };
|