@open-mercato/cache 0.3.2 → 0.4.2-canary-b8ab8f2d43
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/.test-cache.json +4 -0
- package/build.mjs +61 -0
- package/dist/errors.js +12 -8
- package/dist/errors.js.map +7 -0
- package/dist/index.js +16 -7
- package/dist/index.js.map +7 -0
- package/dist/service.js +240 -287
- package/dist/service.js.map +7 -0
- package/dist/strategies/jsonfile.js +179 -194
- package/dist/strategies/jsonfile.js.map +7 -0
- package/dist/strategies/memory.js +143 -157
- package/dist/strategies/memory.js.map +7 -0
- package/dist/strategies/redis.js +292 -359
- package/dist/strategies/redis.js.map +7 -0
- package/dist/strategies/sqlite.js +164 -191
- package/dist/strategies/sqlite.js.map +7 -0
- package/dist/tenantContext.js +10 -6
- package/dist/tenantContext.js.map +7 -0
- package/dist/types.js +1 -1
- package/dist/types.js.map +7 -0
- package/jest.config.cjs +19 -0
- package/package.json +40 -12
- package/src/__tests__/memory.strategy.test.ts +15 -7
- package/tsconfig.build.json +9 -1
- package/tsconfig.json +4 -7
- package/watch.mjs +6 -0
- package/dist/errors.d.ts +0 -7
- package/dist/errors.d.ts.map +0 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.d.ts.map +0 -1
- package/dist/service.d.ts +0 -40
- package/dist/service.d.ts.map +0 -1
- package/dist/strategies/jsonfile.d.ts +0 -10
- package/dist/strategies/jsonfile.d.ts.map +0 -1
- package/dist/strategies/memory.d.ts +0 -9
- package/dist/strategies/memory.d.ts.map +0 -1
- package/dist/strategies/redis.d.ts +0 -5
- package/dist/strategies/redis.d.ts.map +0 -1
- package/dist/strategies/sqlite.d.ts +0 -13
- package/dist/strategies/sqlite.d.ts.map +0 -1
- package/dist/tenantContext.d.ts +0 -4
- package/dist/tenantContext.d.ts.map +0 -1
- package/dist/types.d.ts +0 -86
- package/dist/types.d.ts.map +0 -1
- package/jest.config.js +0 -19
|
@@ -1,205 +1,190 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
import path from
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const cacheFile = filePath || process.env.CACHE_JSON_FILE_PATH || '.cache.json';
|
|
11
|
-
const dir = path.dirname(cacheFile);
|
|
12
|
-
function ensureDir() {
|
|
13
|
-
if (!fs.existsSync(dir)) {
|
|
14
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
function readData() {
|
|
18
|
-
ensureDir();
|
|
19
|
-
if (!fs.existsSync(cacheFile)) {
|
|
20
|
-
return { entries: {}, tagIndex: {} };
|
|
21
|
-
}
|
|
22
|
-
try {
|
|
23
|
-
const content = fs.readFileSync(cacheFile, 'utf8');
|
|
24
|
-
return JSON.parse(content);
|
|
25
|
-
}
|
|
26
|
-
catch (_a) {
|
|
27
|
-
return { entries: {}, tagIndex: {} };
|
|
28
|
-
}
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
function createJsonFileStrategy(filePath, options) {
|
|
4
|
+
const defaultTtl = options?.defaultTtl;
|
|
5
|
+
const cacheFile = filePath || process.env.CACHE_JSON_FILE_PATH || ".cache.json";
|
|
6
|
+
const dir = path.dirname(cacheFile);
|
|
7
|
+
function ensureDir() {
|
|
8
|
+
if (!fs.existsSync(dir)) {
|
|
9
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
29
10
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
11
|
+
}
|
|
12
|
+
function readData() {
|
|
13
|
+
ensureDir();
|
|
14
|
+
if (!fs.existsSync(cacheFile)) {
|
|
15
|
+
return { entries: {}, tagIndex: {} };
|
|
33
16
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
17
|
+
try {
|
|
18
|
+
const content = fs.readFileSync(cacheFile, "utf8");
|
|
19
|
+
return JSON.parse(content);
|
|
20
|
+
} catch {
|
|
21
|
+
return { entries: {}, tagIndex: {} };
|
|
38
22
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
23
|
+
}
|
|
24
|
+
function writeData(data) {
|
|
25
|
+
ensureDir();
|
|
26
|
+
fs.writeFileSync(cacheFile, JSON.stringify(data, null, 2), "utf8");
|
|
27
|
+
}
|
|
28
|
+
function isExpired(entry) {
|
|
29
|
+
if (entry.expiresAt === null) return false;
|
|
30
|
+
return Date.now() > entry.expiresAt;
|
|
31
|
+
}
|
|
32
|
+
function matchPattern(key, pattern) {
|
|
33
|
+
const regexPattern = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
34
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
35
|
+
return regex.test(key);
|
|
36
|
+
}
|
|
37
|
+
function addToTagIndex(data, key, tags) {
|
|
38
|
+
for (const tag of tags) {
|
|
39
|
+
if (!data.tagIndex[tag]) {
|
|
40
|
+
data.tagIndex[tag] = [];
|
|
41
|
+
}
|
|
42
|
+
if (!data.tagIndex[tag].includes(key)) {
|
|
43
|
+
data.tagIndex[tag].push(key);
|
|
44
|
+
}
|
|
46
45
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
46
|
+
}
|
|
47
|
+
function removeFromTagIndex(data, key, tags) {
|
|
48
|
+
for (const tag of tags) {
|
|
49
|
+
if (data.tagIndex[tag]) {
|
|
50
|
+
data.tagIndex[tag] = data.tagIndex[tag].filter((k) => k !== key);
|
|
51
|
+
if (data.tagIndex[tag].length === 0) {
|
|
52
|
+
delete data.tagIndex[tag];
|
|
55
53
|
}
|
|
54
|
+
}
|
|
56
55
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
const get = async (key, options) => {
|
|
68
|
-
const data = readData();
|
|
69
|
-
const entry = data.entries[key];
|
|
70
|
-
if (!entry)
|
|
71
|
-
return null;
|
|
72
|
-
if (isExpired(entry)) {
|
|
73
|
-
if (options === null || options === void 0 ? void 0 : options.returnExpired) {
|
|
74
|
-
return entry.value;
|
|
75
|
-
}
|
|
76
|
-
// Clean up expired entry
|
|
77
|
-
removeFromTagIndex(data, key, entry.tags);
|
|
78
|
-
delete data.entries[key];
|
|
79
|
-
writeData(data);
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
56
|
+
}
|
|
57
|
+
const get = async (key, options2) => {
|
|
58
|
+
const data = readData();
|
|
59
|
+
const entry = data.entries[key];
|
|
60
|
+
if (!entry) return null;
|
|
61
|
+
if (isExpired(entry)) {
|
|
62
|
+
if (options2?.returnExpired) {
|
|
82
63
|
return entry.value;
|
|
64
|
+
}
|
|
65
|
+
removeFromTagIndex(data, key, entry.tags);
|
|
66
|
+
delete data.entries[key];
|
|
67
|
+
writeData(data);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
return entry.value;
|
|
71
|
+
};
|
|
72
|
+
const set = async (key, value, options2) => {
|
|
73
|
+
const data = readData();
|
|
74
|
+
const oldEntry = data.entries[key];
|
|
75
|
+
if (oldEntry) {
|
|
76
|
+
removeFromTagIndex(data, key, oldEntry.tags);
|
|
77
|
+
}
|
|
78
|
+
const ttl = options2?.ttl ?? defaultTtl;
|
|
79
|
+
const tags = options2?.tags || [];
|
|
80
|
+
const expiresAt = ttl ? Date.now() + ttl : null;
|
|
81
|
+
const entry = {
|
|
82
|
+
key,
|
|
83
|
+
value,
|
|
84
|
+
tags,
|
|
85
|
+
expiresAt,
|
|
86
|
+
createdAt: Date.now()
|
|
83
87
|
};
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const entry = data.entries[key];
|
|
122
|
-
if (!entry)
|
|
123
|
-
return false;
|
|
88
|
+
data.entries[key] = entry;
|
|
89
|
+
addToTagIndex(data, key, tags);
|
|
90
|
+
writeData(data);
|
|
91
|
+
};
|
|
92
|
+
const has = async (key) => {
|
|
93
|
+
const data = readData();
|
|
94
|
+
const entry = data.entries[key];
|
|
95
|
+
if (!entry) return false;
|
|
96
|
+
if (isExpired(entry)) {
|
|
97
|
+
removeFromTagIndex(data, key, entry.tags);
|
|
98
|
+
delete data.entries[key];
|
|
99
|
+
writeData(data);
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
return true;
|
|
103
|
+
};
|
|
104
|
+
const deleteKey = async (key) => {
|
|
105
|
+
const data = readData();
|
|
106
|
+
const entry = data.entries[key];
|
|
107
|
+
if (!entry) return false;
|
|
108
|
+
removeFromTagIndex(data, key, entry.tags);
|
|
109
|
+
delete data.entries[key];
|
|
110
|
+
writeData(data);
|
|
111
|
+
return true;
|
|
112
|
+
};
|
|
113
|
+
const deleteByTags = async (tags) => {
|
|
114
|
+
const data = readData();
|
|
115
|
+
const keysToDelete = /* @__PURE__ */ new Set();
|
|
116
|
+
for (const tag of tags) {
|
|
117
|
+
const keys2 = data.tagIndex[tag] || [];
|
|
118
|
+
for (const key of keys2) {
|
|
119
|
+
keysToDelete.add(key);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const key of keysToDelete) {
|
|
123
|
+
const entry = data.entries[key];
|
|
124
|
+
if (entry) {
|
|
124
125
|
removeFromTagIndex(data, key, entry.tags);
|
|
125
126
|
delete data.entries[key];
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
removeFromTagIndex(data, key, entry.tags);
|
|
186
|
-
delete data.entries[key];
|
|
187
|
-
removed++;
|
|
188
|
-
}
|
|
189
|
-
if (removed > 0) {
|
|
190
|
-
writeData(data);
|
|
191
|
-
}
|
|
192
|
-
return removed;
|
|
193
|
-
};
|
|
194
|
-
return {
|
|
195
|
-
get,
|
|
196
|
-
set,
|
|
197
|
-
has,
|
|
198
|
-
delete: deleteKey,
|
|
199
|
-
deleteByTags,
|
|
200
|
-
clear,
|
|
201
|
-
keys,
|
|
202
|
-
stats,
|
|
203
|
-
cleanup,
|
|
204
|
-
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
writeData(data);
|
|
130
|
+
return keysToDelete.size;
|
|
131
|
+
};
|
|
132
|
+
const clear = async () => {
|
|
133
|
+
const data = readData();
|
|
134
|
+
const size = Object.keys(data.entries).length;
|
|
135
|
+
writeData({ entries: {}, tagIndex: {} });
|
|
136
|
+
return size;
|
|
137
|
+
};
|
|
138
|
+
const keys = async (pattern) => {
|
|
139
|
+
const data = readData();
|
|
140
|
+
const allKeys = Object.keys(data.entries);
|
|
141
|
+
if (!pattern) return allKeys;
|
|
142
|
+
return allKeys.filter((key) => matchPattern(key, pattern));
|
|
143
|
+
};
|
|
144
|
+
const stats = async () => {
|
|
145
|
+
const data = readData();
|
|
146
|
+
const allEntries = Object.values(data.entries);
|
|
147
|
+
let expired = 0;
|
|
148
|
+
for (const entry of allEntries) {
|
|
149
|
+
if (isExpired(entry)) {
|
|
150
|
+
expired++;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return { size: allEntries.length, expired };
|
|
154
|
+
};
|
|
155
|
+
const cleanup = async () => {
|
|
156
|
+
const data = readData();
|
|
157
|
+
let removed = 0;
|
|
158
|
+
const keysToRemove = [];
|
|
159
|
+
for (const [key, entry] of Object.entries(data.entries)) {
|
|
160
|
+
if (isExpired(entry)) {
|
|
161
|
+
keysToRemove.push(key);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
for (const key of keysToRemove) {
|
|
165
|
+
const entry = data.entries[key];
|
|
166
|
+
removeFromTagIndex(data, key, entry.tags);
|
|
167
|
+
delete data.entries[key];
|
|
168
|
+
removed++;
|
|
169
|
+
}
|
|
170
|
+
if (removed > 0) {
|
|
171
|
+
writeData(data);
|
|
172
|
+
}
|
|
173
|
+
return removed;
|
|
174
|
+
};
|
|
175
|
+
return {
|
|
176
|
+
get,
|
|
177
|
+
set,
|
|
178
|
+
has,
|
|
179
|
+
delete: deleteKey,
|
|
180
|
+
deleteByTags,
|
|
181
|
+
clear,
|
|
182
|
+
keys,
|
|
183
|
+
stats,
|
|
184
|
+
cleanup
|
|
185
|
+
};
|
|
205
186
|
}
|
|
187
|
+
export {
|
|
188
|
+
createJsonFileStrategy
|
|
189
|
+
};
|
|
190
|
+
//# sourceMappingURL=jsonfile.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/strategies/jsonfile.ts"],
|
|
4
|
+
"sourcesContent": ["import type { CacheStrategy, CacheEntry, CacheGetOptions, CacheSetOptions, CacheValue } from '../types'\nimport fs from 'node:fs'\nimport path from 'node:path'\n\n/**\n * JSON file cache strategy with tag support\n * Persistent across process restarts, stored in JSON files\n * Simple and requires no external dependencies, but not suitable for high-performance scenarios\n */\nexport function createJsonFileStrategy(filePath?: string, options?: { defaultTtl?: number }): CacheStrategy {\n const defaultTtl = options?.defaultTtl\n const cacheFile = filePath || process.env.CACHE_JSON_FILE_PATH || '.cache.json'\n const dir = path.dirname(cacheFile)\n\n type StorageData = {\n entries: Record<string, CacheEntry>\n tagIndex: Record<string, string[]> // tag -> array of keys\n }\n\n function ensureDir(): void {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n }\n\n function readData(): StorageData {\n ensureDir()\n if (!fs.existsSync(cacheFile)) {\n return { entries: {}, tagIndex: {} }\n }\n try {\n const content = fs.readFileSync(cacheFile, 'utf8')\n return JSON.parse(content) as StorageData\n } catch {\n return { entries: {}, tagIndex: {} }\n }\n }\n\n function writeData(data: StorageData): void {\n ensureDir()\n fs.writeFileSync(cacheFile, JSON.stringify(data, null, 2), 'utf8')\n }\n\n function isExpired(entry: CacheEntry): boolean {\n if (entry.expiresAt === null) return false\n return Date.now() > entry.expiresAt\n }\n\n function matchPattern(key: string, pattern: string): boolean {\n const regexPattern = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*/g, '.*')\n .replace(/\\?/g, '.')\n const regex = new RegExp(`^${regexPattern}$`)\n return regex.test(key)\n }\n\n function addToTagIndex(data: StorageData, key: string, tags: string[]): void {\n for (const tag of tags) {\n if (!data.tagIndex[tag]) {\n data.tagIndex[tag] = []\n }\n if (!data.tagIndex[tag].includes(key)) {\n data.tagIndex[tag].push(key)\n }\n }\n }\n\n function removeFromTagIndex(data: StorageData, key: string, tags: string[]): void {\n for (const tag of tags) {\n if (data.tagIndex[tag]) {\n data.tagIndex[tag] = data.tagIndex[tag].filter((k) => k !== key)\n if (data.tagIndex[tag].length === 0) {\n delete data.tagIndex[tag]\n }\n }\n }\n }\n\n const get = async (key: string, options?: CacheGetOptions): Promise<CacheValue | null> => {\n const data = readData()\n const entry = data.entries[key]\n\n if (!entry) return null\n\n if (isExpired(entry)) {\n if (options?.returnExpired) {\n return entry.value\n }\n // Clean up expired entry\n removeFromTagIndex(data, key, entry.tags)\n delete data.entries[key]\n writeData(data)\n return null\n }\n\n return entry.value\n }\n\n const set = async (key: string, value: CacheValue, options?: CacheSetOptions): Promise<void> => {\n const data = readData()\n\n // Remove old entry from tag index if it exists\n const oldEntry = data.entries[key]\n if (oldEntry) {\n removeFromTagIndex(data, key, oldEntry.tags)\n }\n\n const ttl = options?.ttl ?? defaultTtl\n const tags = options?.tags || []\n const expiresAt = ttl ? Date.now() + ttl : null\n\n const entry: CacheEntry = {\n key,\n value,\n tags,\n expiresAt,\n createdAt: Date.now(),\n }\n\n data.entries[key] = entry\n addToTagIndex(data, key, tags)\n\n writeData(data)\n }\n\n const has = async (key: string): Promise<boolean> => {\n const data = readData()\n const entry = data.entries[key]\n\n if (!entry) return false\n\n if (isExpired(entry)) {\n removeFromTagIndex(data, key, entry.tags)\n delete data.entries[key]\n writeData(data)\n return false\n }\n\n return true\n }\n\n const deleteKey = async (key: string): Promise<boolean> => {\n const data = readData()\n const entry = data.entries[key]\n\n if (!entry) return false\n\n removeFromTagIndex(data, key, entry.tags)\n delete data.entries[key]\n writeData(data)\n\n return true\n }\n\n const deleteByTags = async (tags: string[]): Promise<number> => {\n const data = readData()\n const keysToDelete = new Set<string>()\n\n // Collect all keys that have any of the specified tags\n for (const tag of tags) {\n const keys = data.tagIndex[tag] || []\n for (const key of keys) {\n keysToDelete.add(key)\n }\n }\n\n // Delete all collected keys\n for (const key of keysToDelete) {\n const entry = data.entries[key]\n if (entry) {\n removeFromTagIndex(data, key, entry.tags)\n delete data.entries[key]\n }\n }\n\n writeData(data)\n return keysToDelete.size\n }\n\n const clear = async (): Promise<number> => {\n const data = readData()\n const size = Object.keys(data.entries).length\n\n writeData({ entries: {}, tagIndex: {} })\n\n return size\n }\n\n const keys = async (pattern?: string): Promise<string[]> => {\n const data = readData()\n const allKeys = Object.keys(data.entries)\n\n if (!pattern) return allKeys\n\n return allKeys.filter((key) => matchPattern(key, pattern))\n }\n\n const stats = async (): Promise<{ size: number; expired: number }> => {\n const data = readData()\n const allEntries = Object.values(data.entries)\n\n let expired = 0\n for (const entry of allEntries) {\n if (isExpired(entry)) {\n expired++\n }\n }\n\n return { size: allEntries.length, expired }\n }\n\n const cleanup = async (): Promise<number> => {\n const data = readData()\n let removed = 0\n\n const keysToRemove: string[] = []\n for (const [key, entry] of Object.entries(data.entries)) {\n if (isExpired(entry)) {\n keysToRemove.push(key)\n }\n }\n\n for (const key of keysToRemove) {\n const entry = data.entries[key]\n removeFromTagIndex(data, key, entry.tags)\n delete data.entries[key]\n removed++\n }\n\n if (removed > 0) {\n writeData(data)\n }\n\n return removed\n }\n\n return {\n get,\n set,\n has,\n delete: deleteKey,\n deleteByTags,\n clear,\n keys,\n stats,\n cleanup,\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["options", "keys"]
|
|
7
|
+
}
|