modelfusion 0.135.0 → 0.136.0

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/node/index.cjs ADDED
@@ -0,0 +1,184 @@
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/node/index.ts
31
+ var node_exports = {};
32
+ __export(node_exports, {
33
+ FileCache: () => FileCache
34
+ });
35
+ module.exports = __toCommonJS(node_exports);
36
+
37
+ // src/core/cache/FileCache.ts
38
+ var fs = __toESM(require("fs"), 1);
39
+ var path = __toESM(require("path"), 1);
40
+ var crypto = __toESM(require("crypto"), 1);
41
+ var FileCache = class {
42
+ /**
43
+ * The directory where the cache files are stored.
44
+ * @type {string}
45
+ */
46
+ cacheDir;
47
+ /**
48
+ * The default lifespan of a cached item, in milliseconds.
49
+ * Cached items older than this value will be evicted.
50
+ * @type {number}
51
+ */
52
+ expiresIn = 24 * 60 * 60 * 1e3;
53
+ // 1 day in milliseconds
54
+ /**
55
+ * The maximum allowed size of the cache, in bytes.
56
+ * If the cache exceeds this size, some items will be evicted.
57
+ * @type {number}
58
+ */
59
+ maxCacheSize = 0.5 * 1024 * 1024 * 1024;
60
+ // 0.5 GB
61
+ /**
62
+ * Constructor for the FileCache class.
63
+ * It creates the cache directory if it doesn't exist.
64
+ * @param {object} options - The options for the cache.
65
+ * @param {string} options.cacheDir - The directory where the cache files are stored.
66
+ * @param {number} options.expiresIn - The lifespan of a cached item, in milliseconds.
67
+ * @param {number} options.maxCacheSize - The maximum allowed size of the cache, in bytes.
68
+ */
69
+ constructor({
70
+ expiresIn = 24 * 60 * 60 * 1e3,
71
+ // 1 day in milliseconds
72
+ cacheDir = path.resolve(process.cwd(), ".cache"),
73
+ // Default cache directory is './cache'
74
+ maxCacheSize = 0.5 * 1024 * 1024 * 1024
75
+ // Default max cache size is 0.5 GB
76
+ } = {}) {
77
+ this.expiresIn = expiresIn;
78
+ this.cacheDir = cacheDir;
79
+ this.maxCacheSize = maxCacheSize;
80
+ if (!fs.existsSync(this.cacheDir)) {
81
+ fs.mkdirSync(this.cacheDir, { recursive: true });
82
+ }
83
+ }
84
+ /**
85
+ * Hashes the key for a cache item.
86
+ * The key is an object with properties `functionType`, `functionId`, and `input`.
87
+ * The hash is used as the filename for the cache item.
88
+ * @param {object} key - The key for the cache item.
89
+ * @returns {string} The hash of the key.
90
+ */
91
+ hashKey(key) {
92
+ const keyString = JSON.stringify(key);
93
+ const hash = crypto.createHash("sha256");
94
+ hash.update(keyString);
95
+ return hash.digest("hex");
96
+ }
97
+ /**
98
+ * Looks up a value in the cache.
99
+ * If the value is found and is not expired, it is returned.
100
+ * If the value is not found or is expired, null is returned.
101
+ * @param {object} key - The key for the cache item.
102
+ * @returns {Promise<object|null>} The cached value, or null if the value is not found or is expired.
103
+ */
104
+ async lookupValue(key) {
105
+ const filePath = path.join(this.cacheDir, this.hashKey(key));
106
+ return new Promise((resolve2, reject) => {
107
+ fs.readFile(filePath, "utf8", (err, data) => {
108
+ if (err) {
109
+ if (err.code === "ENOENT") {
110
+ resolve2(null);
111
+ } else {
112
+ reject(err);
113
+ }
114
+ } else {
115
+ const parsedData = JSON.parse(data);
116
+ if (Date.now() - parsedData.time > this.expiresIn) {
117
+ fs.unlink(filePath, (err2) => {
118
+ if (err2) {
119
+ reject(err2);
120
+ } else {
121
+ resolve2(null);
122
+ }
123
+ });
124
+ } else {
125
+ resolve2(parsedData.value);
126
+ }
127
+ }
128
+ });
129
+ });
130
+ }
131
+ /**
132
+ * Stores a value in the cache.
133
+ * The value is stored with the current time, so it can be expired later.
134
+ * @param {object} key - The key for the cache item.
135
+ * @param {unknown} value - The value to store.
136
+ * @returns {Promise<void>}
137
+ */
138
+ async storeValue(key, value) {
139
+ const filePath = path.join(this.cacheDir, this.hashKey(key));
140
+ const data = { value, time: Date.now() };
141
+ return new Promise((resolve2, reject) => {
142
+ fs.writeFile(filePath, JSON.stringify(data), "utf8", (err) => {
143
+ if (err) {
144
+ reject(err);
145
+ } else {
146
+ this.checkCacheSize().then(resolve2).catch(reject);
147
+ }
148
+ });
149
+ });
150
+ }
151
+ /**
152
+ * Checks the total size of the cache.
153
+ * If the cache is too large, it evicts the oldest items until the total cache size is within the limit.
154
+ *
155
+ * @returns {Promise<void>} A promise that resolves when the cache size check (and possible eviction) is complete.
156
+ */
157
+ async checkCacheSize() {
158
+ const files = await fs.promises.readdir(this.cacheDir);
159
+ let totalSize = 0;
160
+ const fileDetails = [];
161
+ for (const file of files) {
162
+ const stats = await fs.promises.stat(path.join(this.cacheDir, file));
163
+ totalSize += stats.size;
164
+ fileDetails.push({ file, stats });
165
+ }
166
+ if (totalSize > this.maxCacheSize) {
167
+ fileDetails.sort(
168
+ (a, b) => a.stats.mtime.getTime() - b.stats.mtime.getTime()
169
+ );
170
+ for (const { file, stats } of fileDetails) {
171
+ if (totalSize <= this.maxCacheSize) {
172
+ break;
173
+ }
174
+ await fs.promises.unlink(path.join(this.cacheDir, file));
175
+ totalSize -= stats.size;
176
+ }
177
+ }
178
+ }
179
+ };
180
+ // Annotate the CommonJS export names for ESM import in node:
181
+ 0 && (module.exports = {
182
+ FileCache
183
+ });
184
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/node/index.ts","../../src/core/cache/FileCache.ts"],"sourcesContent":["export * from \"../core/cache/FileCache\";\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as crypto from \"crypto\";\n\nimport { Cache } from \"./Cache\";\n\n/**\n * FileCache class implements the Cache interface.\n * It provides a file-based cache with TTL and size-based eviction strategies.\n */\nexport class FileCache implements Cache {\n /**\n * The directory where the cache files are stored.\n * @type {string}\n */\n cacheDir;\n\n /**\n * The default lifespan of a cached item, in milliseconds.\n * Cached items older than this value will be evicted.\n * @type {number}\n */\n expiresIn = 24 * 60 * 60 * 1000; // 1 day in milliseconds\n\n /**\n * The maximum allowed size of the cache, in bytes.\n * If the cache exceeds this size, some items will be evicted.\n * @type {number}\n */\n maxCacheSize = 0.5 * 1024 * 1024 * 1024; // 0.5 GB\n\n /**\n * Constructor for the FileCache class.\n * It creates the cache directory if it doesn't exist.\n * @param {object} options - The options for the cache.\n * @param {string} options.cacheDir - The directory where the cache files are stored.\n * @param {number} options.expiresIn - The lifespan of a cached item, in milliseconds.\n * @param {number} options.maxCacheSize - The maximum allowed size of the cache, in bytes.\n */\n constructor({\n expiresIn = 24 * 60 * 60 * 1000, // 1 day in milliseconds\n cacheDir = path.resolve(process.cwd(), \".cache\"), // Default cache directory is './cache'\n maxCacheSize = 0.5 * 1024 * 1024 * 1024, // Default max cache size is 0.5 GB\n } = {}) {\n this.expiresIn = expiresIn;\n this.cacheDir = cacheDir;\n this.maxCacheSize = maxCacheSize;\n if (!fs.existsSync(this.cacheDir)) {\n fs.mkdirSync(this.cacheDir, { recursive: true });\n }\n }\n\n /**\n * Hashes the key for a cache item.\n * The key is an object with properties `functionType`, `functionId`, and `input`.\n * The hash is used as the filename for the cache item.\n * @param {object} key - The key for the cache item.\n * @returns {string} The hash of the key.\n */\n private hashKey(key: {\n functionType: string;\n functionId?: string | undefined;\n input: unknown;\n }) {\n const keyString = JSON.stringify(key);\n const hash = crypto.createHash(\"sha256\");\n hash.update(keyString);\n return hash.digest(\"hex\");\n }\n\n /**\n * Looks up a value in the cache.\n * If the value is found and is not expired, it is returned.\n * If the value is not found or is expired, null is returned.\n * @param {object} key - The key for the cache item.\n * @returns {Promise<object|null>} The cached value, or null if the value is not found or is expired.\n */\n async lookupValue(key: {\n functionType: string;\n functionId?: string | undefined;\n input: unknown;\n }): Promise<object | null> {\n const filePath = path.join(this.cacheDir, this.hashKey(key));\n return new Promise((resolve, reject) => {\n fs.readFile(filePath, \"utf8\", (err, data) => {\n if (err) {\n if (err.code === \"ENOENT\") {\n resolve(null); // File not found, resolve with null\n } else {\n reject(err); // Other error, reject promise\n }\n } else {\n const parsedData = JSON.parse(data);\n if (Date.now() - parsedData.time > this.expiresIn) {\n // If the item is too old, delete the file and return a cache miss\n fs.unlink(filePath, (err) => {\n if (err) {\n reject(err);\n } else {\n resolve(null);\n }\n });\n } else {\n resolve(parsedData.value); // File found and not expired, resolve with data\n }\n }\n });\n });\n }\n\n /**\n * Stores a value in the cache.\n * The value is stored with the current time, so it can be expired later.\n * @param {object} key - The key for the cache item.\n * @param {unknown} value - The value to store.\n * @returns {Promise<void>}\n */\n async storeValue(\n key: {\n functionType: string;\n functionId?: string | undefined;\n input: unknown;\n },\n value: unknown\n ): Promise<void> {\n const filePath = path.join(this.cacheDir, this.hashKey(key));\n const data = { value, time: Date.now() }; // Include the current time in the stored data\n return new Promise((resolve, reject) => {\n fs.writeFile(filePath, JSON.stringify(data), \"utf8\", (err) => {\n if (err) {\n reject(err); // Error writing file, reject promise\n } else {\n this.checkCacheSize().then(resolve).catch(reject); // Check the cache size after writing the file\n }\n });\n });\n }\n\n /**\n * Checks the total size of the cache.\n * If the cache is too large, it evicts the oldest items until the total cache size is within the limit.\n *\n * @returns {Promise<void>} A promise that resolves when the cache size check (and possible eviction) is complete.\n */\n private async checkCacheSize(): Promise<void> {\n const files = await fs.promises.readdir(this.cacheDir);\n let totalSize = 0;\n const fileDetails: { file: string; stats: fs.Stats }[] = [];\n\n // Get the size and stats for each file\n for (const file of files) {\n const stats = await fs.promises.stat(path.join(this.cacheDir, file));\n totalSize += stats.size;\n fileDetails.push({ file, stats });\n }\n\n // If the cache is too large, delete the oldest files until it's small enough\n if (totalSize > this.maxCacheSize) {\n // Sort the files by modification time, oldest first\n fileDetails.sort(\n (a, b) => a.stats.mtime.getTime() - b.stats.mtime.getTime()\n );\n\n // Delete files until the cache is small enough\n for (const { file, stats } of fileDetails) {\n if (totalSize <= this.maxCacheSize) {\n break;\n }\n await fs.promises.unlink(path.join(this.cacheDir, file));\n totalSize -= stats.size;\n }\n }\n }\n}\n"],"mappings":"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","names":["resolve","err"]}
@@ -0,0 +1,92 @@
1
+ interface Cache {
2
+ lookupValue(key: {
3
+ functionType: string;
4
+ functionId?: string | undefined;
5
+ input: unknown;
6
+ }): Promise<object | null>;
7
+ storeValue(key: {
8
+ functionType: string;
9
+ functionId?: string | undefined;
10
+ input: unknown;
11
+ }, value: unknown): Promise<void>;
12
+ }
13
+
14
+ /**
15
+ * FileCache class implements the Cache interface.
16
+ * It provides a file-based cache with TTL and size-based eviction strategies.
17
+ */
18
+ declare class FileCache implements Cache {
19
+ /**
20
+ * The directory where the cache files are stored.
21
+ * @type {string}
22
+ */
23
+ cacheDir: string;
24
+ /**
25
+ * The default lifespan of a cached item, in milliseconds.
26
+ * Cached items older than this value will be evicted.
27
+ * @type {number}
28
+ */
29
+ expiresIn: number;
30
+ /**
31
+ * The maximum allowed size of the cache, in bytes.
32
+ * If the cache exceeds this size, some items will be evicted.
33
+ * @type {number}
34
+ */
35
+ maxCacheSize: number;
36
+ /**
37
+ * Constructor for the FileCache class.
38
+ * It creates the cache directory if it doesn't exist.
39
+ * @param {object} options - The options for the cache.
40
+ * @param {string} options.cacheDir - The directory where the cache files are stored.
41
+ * @param {number} options.expiresIn - The lifespan of a cached item, in milliseconds.
42
+ * @param {number} options.maxCacheSize - The maximum allowed size of the cache, in bytes.
43
+ */
44
+ constructor({ expiresIn, // 1 day in milliseconds
45
+ cacheDir, // Default cache directory is './cache'
46
+ maxCacheSize, }?: {
47
+ expiresIn?: number | undefined;
48
+ cacheDir?: string | undefined;
49
+ maxCacheSize?: number | undefined;
50
+ });
51
+ /**
52
+ * Hashes the key for a cache item.
53
+ * The key is an object with properties `functionType`, `functionId`, and `input`.
54
+ * The hash is used as the filename for the cache item.
55
+ * @param {object} key - The key for the cache item.
56
+ * @returns {string} The hash of the key.
57
+ */
58
+ private hashKey;
59
+ /**
60
+ * Looks up a value in the cache.
61
+ * If the value is found and is not expired, it is returned.
62
+ * If the value is not found or is expired, null is returned.
63
+ * @param {object} key - The key for the cache item.
64
+ * @returns {Promise<object|null>} The cached value, or null if the value is not found or is expired.
65
+ */
66
+ lookupValue(key: {
67
+ functionType: string;
68
+ functionId?: string | undefined;
69
+ input: unknown;
70
+ }): Promise<object | null>;
71
+ /**
72
+ * Stores a value in the cache.
73
+ * The value is stored with the current time, so it can be expired later.
74
+ * @param {object} key - The key for the cache item.
75
+ * @param {unknown} value - The value to store.
76
+ * @returns {Promise<void>}
77
+ */
78
+ storeValue(key: {
79
+ functionType: string;
80
+ functionId?: string | undefined;
81
+ input: unknown;
82
+ }, value: unknown): Promise<void>;
83
+ /**
84
+ * Checks the total size of the cache.
85
+ * If the cache is too large, it evicts the oldest items until the total cache size is within the limit.
86
+ *
87
+ * @returns {Promise<void>} A promise that resolves when the cache size check (and possible eviction) is complete.
88
+ */
89
+ private checkCacheSize;
90
+ }
91
+
92
+ export { FileCache };
@@ -0,0 +1,92 @@
1
+ interface Cache {
2
+ lookupValue(key: {
3
+ functionType: string;
4
+ functionId?: string | undefined;
5
+ input: unknown;
6
+ }): Promise<object | null>;
7
+ storeValue(key: {
8
+ functionType: string;
9
+ functionId?: string | undefined;
10
+ input: unknown;
11
+ }, value: unknown): Promise<void>;
12
+ }
13
+
14
+ /**
15
+ * FileCache class implements the Cache interface.
16
+ * It provides a file-based cache with TTL and size-based eviction strategies.
17
+ */
18
+ declare class FileCache implements Cache {
19
+ /**
20
+ * The directory where the cache files are stored.
21
+ * @type {string}
22
+ */
23
+ cacheDir: string;
24
+ /**
25
+ * The default lifespan of a cached item, in milliseconds.
26
+ * Cached items older than this value will be evicted.
27
+ * @type {number}
28
+ */
29
+ expiresIn: number;
30
+ /**
31
+ * The maximum allowed size of the cache, in bytes.
32
+ * If the cache exceeds this size, some items will be evicted.
33
+ * @type {number}
34
+ */
35
+ maxCacheSize: number;
36
+ /**
37
+ * Constructor for the FileCache class.
38
+ * It creates the cache directory if it doesn't exist.
39
+ * @param {object} options - The options for the cache.
40
+ * @param {string} options.cacheDir - The directory where the cache files are stored.
41
+ * @param {number} options.expiresIn - The lifespan of a cached item, in milliseconds.
42
+ * @param {number} options.maxCacheSize - The maximum allowed size of the cache, in bytes.
43
+ */
44
+ constructor({ expiresIn, // 1 day in milliseconds
45
+ cacheDir, // Default cache directory is './cache'
46
+ maxCacheSize, }?: {
47
+ expiresIn?: number | undefined;
48
+ cacheDir?: string | undefined;
49
+ maxCacheSize?: number | undefined;
50
+ });
51
+ /**
52
+ * Hashes the key for a cache item.
53
+ * The key is an object with properties `functionType`, `functionId`, and `input`.
54
+ * The hash is used as the filename for the cache item.
55
+ * @param {object} key - The key for the cache item.
56
+ * @returns {string} The hash of the key.
57
+ */
58
+ private hashKey;
59
+ /**
60
+ * Looks up a value in the cache.
61
+ * If the value is found and is not expired, it is returned.
62
+ * If the value is not found or is expired, null is returned.
63
+ * @param {object} key - The key for the cache item.
64
+ * @returns {Promise<object|null>} The cached value, or null if the value is not found or is expired.
65
+ */
66
+ lookupValue(key: {
67
+ functionType: string;
68
+ functionId?: string | undefined;
69
+ input: unknown;
70
+ }): Promise<object | null>;
71
+ /**
72
+ * Stores a value in the cache.
73
+ * The value is stored with the current time, so it can be expired later.
74
+ * @param {object} key - The key for the cache item.
75
+ * @param {unknown} value - The value to store.
76
+ * @returns {Promise<void>}
77
+ */
78
+ storeValue(key: {
79
+ functionType: string;
80
+ functionId?: string | undefined;
81
+ input: unknown;
82
+ }, value: unknown): Promise<void>;
83
+ /**
84
+ * Checks the total size of the cache.
85
+ * If the cache is too large, it evicts the oldest items until the total cache size is within the limit.
86
+ *
87
+ * @returns {Promise<void>} A promise that resolves when the cache size check (and possible eviction) is complete.
88
+ */
89
+ private checkCacheSize;
90
+ }
91
+
92
+ export { FileCache };
package/node/index.js ADDED
@@ -0,0 +1,147 @@
1
+ // src/core/cache/FileCache.ts
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ import * as crypto from "crypto";
5
+ var FileCache = class {
6
+ /**
7
+ * The directory where the cache files are stored.
8
+ * @type {string}
9
+ */
10
+ cacheDir;
11
+ /**
12
+ * The default lifespan of a cached item, in milliseconds.
13
+ * Cached items older than this value will be evicted.
14
+ * @type {number}
15
+ */
16
+ expiresIn = 24 * 60 * 60 * 1e3;
17
+ // 1 day in milliseconds
18
+ /**
19
+ * The maximum allowed size of the cache, in bytes.
20
+ * If the cache exceeds this size, some items will be evicted.
21
+ * @type {number}
22
+ */
23
+ maxCacheSize = 0.5 * 1024 * 1024 * 1024;
24
+ // 0.5 GB
25
+ /**
26
+ * Constructor for the FileCache class.
27
+ * It creates the cache directory if it doesn't exist.
28
+ * @param {object} options - The options for the cache.
29
+ * @param {string} options.cacheDir - The directory where the cache files are stored.
30
+ * @param {number} options.expiresIn - The lifespan of a cached item, in milliseconds.
31
+ * @param {number} options.maxCacheSize - The maximum allowed size of the cache, in bytes.
32
+ */
33
+ constructor({
34
+ expiresIn = 24 * 60 * 60 * 1e3,
35
+ // 1 day in milliseconds
36
+ cacheDir = path.resolve(process.cwd(), ".cache"),
37
+ // Default cache directory is './cache'
38
+ maxCacheSize = 0.5 * 1024 * 1024 * 1024
39
+ // Default max cache size is 0.5 GB
40
+ } = {}) {
41
+ this.expiresIn = expiresIn;
42
+ this.cacheDir = cacheDir;
43
+ this.maxCacheSize = maxCacheSize;
44
+ if (!fs.existsSync(this.cacheDir)) {
45
+ fs.mkdirSync(this.cacheDir, { recursive: true });
46
+ }
47
+ }
48
+ /**
49
+ * Hashes the key for a cache item.
50
+ * The key is an object with properties `functionType`, `functionId`, and `input`.
51
+ * The hash is used as the filename for the cache item.
52
+ * @param {object} key - The key for the cache item.
53
+ * @returns {string} The hash of the key.
54
+ */
55
+ hashKey(key) {
56
+ const keyString = JSON.stringify(key);
57
+ const hash = crypto.createHash("sha256");
58
+ hash.update(keyString);
59
+ return hash.digest("hex");
60
+ }
61
+ /**
62
+ * Looks up a value in the cache.
63
+ * If the value is found and is not expired, it is returned.
64
+ * If the value is not found or is expired, null is returned.
65
+ * @param {object} key - The key for the cache item.
66
+ * @returns {Promise<object|null>} The cached value, or null if the value is not found or is expired.
67
+ */
68
+ async lookupValue(key) {
69
+ const filePath = path.join(this.cacheDir, this.hashKey(key));
70
+ return new Promise((resolve2, reject) => {
71
+ fs.readFile(filePath, "utf8", (err, data) => {
72
+ if (err) {
73
+ if (err.code === "ENOENT") {
74
+ resolve2(null);
75
+ } else {
76
+ reject(err);
77
+ }
78
+ } else {
79
+ const parsedData = JSON.parse(data);
80
+ if (Date.now() - parsedData.time > this.expiresIn) {
81
+ fs.unlink(filePath, (err2) => {
82
+ if (err2) {
83
+ reject(err2);
84
+ } else {
85
+ resolve2(null);
86
+ }
87
+ });
88
+ } else {
89
+ resolve2(parsedData.value);
90
+ }
91
+ }
92
+ });
93
+ });
94
+ }
95
+ /**
96
+ * Stores a value in the cache.
97
+ * The value is stored with the current time, so it can be expired later.
98
+ * @param {object} key - The key for the cache item.
99
+ * @param {unknown} value - The value to store.
100
+ * @returns {Promise<void>}
101
+ */
102
+ async storeValue(key, value) {
103
+ const filePath = path.join(this.cacheDir, this.hashKey(key));
104
+ const data = { value, time: Date.now() };
105
+ return new Promise((resolve2, reject) => {
106
+ fs.writeFile(filePath, JSON.stringify(data), "utf8", (err) => {
107
+ if (err) {
108
+ reject(err);
109
+ } else {
110
+ this.checkCacheSize().then(resolve2).catch(reject);
111
+ }
112
+ });
113
+ });
114
+ }
115
+ /**
116
+ * Checks the total size of the cache.
117
+ * If the cache is too large, it evicts the oldest items until the total cache size is within the limit.
118
+ *
119
+ * @returns {Promise<void>} A promise that resolves when the cache size check (and possible eviction) is complete.
120
+ */
121
+ async checkCacheSize() {
122
+ const files = await fs.promises.readdir(this.cacheDir);
123
+ let totalSize = 0;
124
+ const fileDetails = [];
125
+ for (const file of files) {
126
+ const stats = await fs.promises.stat(path.join(this.cacheDir, file));
127
+ totalSize += stats.size;
128
+ fileDetails.push({ file, stats });
129
+ }
130
+ if (totalSize > this.maxCacheSize) {
131
+ fileDetails.sort(
132
+ (a, b) => a.stats.mtime.getTime() - b.stats.mtime.getTime()
133
+ );
134
+ for (const { file, stats } of fileDetails) {
135
+ if (totalSize <= this.maxCacheSize) {
136
+ break;
137
+ }
138
+ await fs.promises.unlink(path.join(this.cacheDir, file));
139
+ totalSize -= stats.size;
140
+ }
141
+ }
142
+ }
143
+ };
144
+ export {
145
+ FileCache
146
+ };
147
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/cache/FileCache.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as crypto from \"crypto\";\n\nimport { Cache } from \"./Cache\";\n\n/**\n * FileCache class implements the Cache interface.\n * It provides a file-based cache with TTL and size-based eviction strategies.\n */\nexport class FileCache implements Cache {\n /**\n * The directory where the cache files are stored.\n * @type {string}\n */\n cacheDir;\n\n /**\n * The default lifespan of a cached item, in milliseconds.\n * Cached items older than this value will be evicted.\n * @type {number}\n */\n expiresIn = 24 * 60 * 60 * 1000; // 1 day in milliseconds\n\n /**\n * The maximum allowed size of the cache, in bytes.\n * If the cache exceeds this size, some items will be evicted.\n * @type {number}\n */\n maxCacheSize = 0.5 * 1024 * 1024 * 1024; // 0.5 GB\n\n /**\n * Constructor for the FileCache class.\n * It creates the cache directory if it doesn't exist.\n * @param {object} options - The options for the cache.\n * @param {string} options.cacheDir - The directory where the cache files are stored.\n * @param {number} options.expiresIn - The lifespan of a cached item, in milliseconds.\n * @param {number} options.maxCacheSize - The maximum allowed size of the cache, in bytes.\n */\n constructor({\n expiresIn = 24 * 60 * 60 * 1000, // 1 day in milliseconds\n cacheDir = path.resolve(process.cwd(), \".cache\"), // Default cache directory is './cache'\n maxCacheSize = 0.5 * 1024 * 1024 * 1024, // Default max cache size is 0.5 GB\n } = {}) {\n this.expiresIn = expiresIn;\n this.cacheDir = cacheDir;\n this.maxCacheSize = maxCacheSize;\n if (!fs.existsSync(this.cacheDir)) {\n fs.mkdirSync(this.cacheDir, { recursive: true });\n }\n }\n\n /**\n * Hashes the key for a cache item.\n * The key is an object with properties `functionType`, `functionId`, and `input`.\n * The hash is used as the filename for the cache item.\n * @param {object} key - The key for the cache item.\n * @returns {string} The hash of the key.\n */\n private hashKey(key: {\n functionType: string;\n functionId?: string | undefined;\n input: unknown;\n }) {\n const keyString = JSON.stringify(key);\n const hash = crypto.createHash(\"sha256\");\n hash.update(keyString);\n return hash.digest(\"hex\");\n }\n\n /**\n * Looks up a value in the cache.\n * If the value is found and is not expired, it is returned.\n * If the value is not found or is expired, null is returned.\n * @param {object} key - The key for the cache item.\n * @returns {Promise<object|null>} The cached value, or null if the value is not found or is expired.\n */\n async lookupValue(key: {\n functionType: string;\n functionId?: string | undefined;\n input: unknown;\n }): Promise<object | null> {\n const filePath = path.join(this.cacheDir, this.hashKey(key));\n return new Promise((resolve, reject) => {\n fs.readFile(filePath, \"utf8\", (err, data) => {\n if (err) {\n if (err.code === \"ENOENT\") {\n resolve(null); // File not found, resolve with null\n } else {\n reject(err); // Other error, reject promise\n }\n } else {\n const parsedData = JSON.parse(data);\n if (Date.now() - parsedData.time > this.expiresIn) {\n // If the item is too old, delete the file and return a cache miss\n fs.unlink(filePath, (err) => {\n if (err) {\n reject(err);\n } else {\n resolve(null);\n }\n });\n } else {\n resolve(parsedData.value); // File found and not expired, resolve with data\n }\n }\n });\n });\n }\n\n /**\n * Stores a value in the cache.\n * The value is stored with the current time, so it can be expired later.\n * @param {object} key - The key for the cache item.\n * @param {unknown} value - The value to store.\n * @returns {Promise<void>}\n */\n async storeValue(\n key: {\n functionType: string;\n functionId?: string | undefined;\n input: unknown;\n },\n value: unknown\n ): Promise<void> {\n const filePath = path.join(this.cacheDir, this.hashKey(key));\n const data = { value, time: Date.now() }; // Include the current time in the stored data\n return new Promise((resolve, reject) => {\n fs.writeFile(filePath, JSON.stringify(data), \"utf8\", (err) => {\n if (err) {\n reject(err); // Error writing file, reject promise\n } else {\n this.checkCacheSize().then(resolve).catch(reject); // Check the cache size after writing the file\n }\n });\n });\n }\n\n /**\n * Checks the total size of the cache.\n * If the cache is too large, it evicts the oldest items until the total cache size is within the limit.\n *\n * @returns {Promise<void>} A promise that resolves when the cache size check (and possible eviction) is complete.\n */\n private async checkCacheSize(): Promise<void> {\n const files = await fs.promises.readdir(this.cacheDir);\n let totalSize = 0;\n const fileDetails: { file: string; stats: fs.Stats }[] = [];\n\n // Get the size and stats for each file\n for (const file of files) {\n const stats = await fs.promises.stat(path.join(this.cacheDir, file));\n totalSize += stats.size;\n fileDetails.push({ file, stats });\n }\n\n // If the cache is too large, delete the oldest files until it's small enough\n if (totalSize > this.maxCacheSize) {\n // Sort the files by modification time, oldest first\n fileDetails.sort(\n (a, b) => a.stats.mtime.getTime() - b.stats.mtime.getTime()\n );\n\n // Delete files until the cache is small enough\n for (const { file, stats } of fileDetails) {\n if (totalSize <= this.maxCacheSize) {\n break;\n }\n await fs.promises.unlink(path.join(this.cacheDir, file));\n totalSize -= stats.size;\n }\n }\n }\n}\n"],"mappings":"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","names":["resolve","err"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "modelfusion",
3
3
  "description": "The TypeScript library for building AI applications.",
4
- "version": "0.135.0",
4
+ "version": "0.136.0",
5
5
  "author": "Lars Grammel",
6
6
  "license": "MIT",
7
7
  "keywords": [
@@ -48,6 +48,12 @@
48
48
  "import": "./internal/index.js",
49
49
  "module": "./internal/index.js",
50
50
  "require": "./internal/index.cjs"
51
+ },
52
+ "./node": {
53
+ "types": "./node/index.d.ts",
54
+ "import": "./node/index.js",
55
+ "module": "./node/index.js",
56
+ "require": "./node/index.cjs"
51
57
  }
52
58
  },
53
59
  "scripts": {