@open-mercato/cache 0.3.2 → 0.4.2-canary-c02407ff85
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,166 +1,152 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
for (const tag of entry.tags) {
|
|
18
|
-
const keys = tagIndex.get(tag);
|
|
19
|
-
if (keys) {
|
|
20
|
-
keys.delete(key);
|
|
21
|
-
if (keys.size === 0) {
|
|
22
|
-
tagIndex.delete(tag);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
1
|
+
function createMemoryStrategy(options) {
|
|
2
|
+
const store = /* @__PURE__ */ new Map();
|
|
3
|
+
const tagIndex = /* @__PURE__ */ new Map();
|
|
4
|
+
const defaultTtl = options?.defaultTtl;
|
|
5
|
+
function isExpired(entry) {
|
|
6
|
+
if (entry.expiresAt === null) return false;
|
|
7
|
+
return Date.now() > entry.expiresAt;
|
|
8
|
+
}
|
|
9
|
+
function cleanupExpiredEntry(key, entry) {
|
|
10
|
+
store.delete(key);
|
|
11
|
+
for (const tag of entry.tags) {
|
|
12
|
+
const keys2 = tagIndex.get(tag);
|
|
13
|
+
if (keys2) {
|
|
14
|
+
keys2.delete(key);
|
|
15
|
+
if (keys2.size === 0) {
|
|
16
|
+
tagIndex.delete(tag);
|
|
25
17
|
}
|
|
18
|
+
}
|
|
26
19
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
20
|
+
}
|
|
21
|
+
function addToTagIndex(key, tags) {
|
|
22
|
+
for (const tag of tags) {
|
|
23
|
+
if (!tagIndex.has(tag)) {
|
|
24
|
+
tagIndex.set(tag, /* @__PURE__ */ new Set());
|
|
25
|
+
}
|
|
26
|
+
tagIndex.get(tag).add(key);
|
|
34
27
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
28
|
+
}
|
|
29
|
+
function removeFromTagIndex(key, tags) {
|
|
30
|
+
for (const tag of tags) {
|
|
31
|
+
const keys2 = tagIndex.get(tag);
|
|
32
|
+
if (keys2) {
|
|
33
|
+
keys2.delete(key);
|
|
34
|
+
if (keys2.size === 0) {
|
|
35
|
+
tagIndex.delete(tag);
|
|
44
36
|
}
|
|
37
|
+
}
|
|
45
38
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return null;
|
|
58
|
-
if (isExpired(entry)) {
|
|
59
|
-
if (options === null || options === void 0 ? void 0 : options.returnExpired) {
|
|
60
|
-
return entry.value;
|
|
61
|
-
}
|
|
62
|
-
cleanupExpiredEntry(key, entry);
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
39
|
+
}
|
|
40
|
+
function matchPattern(key, pattern) {
|
|
41
|
+
const regexPattern = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
42
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
43
|
+
return regex.test(key);
|
|
44
|
+
}
|
|
45
|
+
const get = async (key, options2) => {
|
|
46
|
+
const entry = store.get(key);
|
|
47
|
+
if (!entry) return null;
|
|
48
|
+
if (isExpired(entry)) {
|
|
49
|
+
if (options2?.returnExpired) {
|
|
65
50
|
return entry.value;
|
|
51
|
+
}
|
|
52
|
+
cleanupExpiredEntry(key, entry);
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return entry.value;
|
|
56
|
+
};
|
|
57
|
+
const set = async (key, value, options2) => {
|
|
58
|
+
const oldEntry = store.get(key);
|
|
59
|
+
if (oldEntry) {
|
|
60
|
+
removeFromTagIndex(key, oldEntry.tags);
|
|
61
|
+
}
|
|
62
|
+
const ttl = options2?.ttl ?? defaultTtl;
|
|
63
|
+
const tags = options2?.tags || [];
|
|
64
|
+
const expiresAt = ttl ? Date.now() + ttl : null;
|
|
65
|
+
const entry = {
|
|
66
|
+
key,
|
|
67
|
+
value,
|
|
68
|
+
tags,
|
|
69
|
+
expiresAt,
|
|
70
|
+
createdAt: Date.now()
|
|
66
71
|
};
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
cleanupExpiredEntry(key, entry);
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
|
-
return true;
|
|
96
|
-
};
|
|
97
|
-
const deleteKey = async (key) => {
|
|
98
|
-
const entry = store.get(key);
|
|
99
|
-
if (!entry)
|
|
100
|
-
return false;
|
|
101
|
-
removeFromTagIndex(key, entry.tags);
|
|
102
|
-
return store.delete(key);
|
|
103
|
-
};
|
|
104
|
-
const deleteByTags = async (tags) => {
|
|
105
|
-
const keysToDelete = new Set();
|
|
106
|
-
// Collect all keys that have any of the specified tags
|
|
107
|
-
for (const tag of tags) {
|
|
108
|
-
const keys = tagIndex.get(tag);
|
|
109
|
-
if (keys) {
|
|
110
|
-
for (const key of keys) {
|
|
111
|
-
keysToDelete.add(key);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
// Delete all collected keys
|
|
116
|
-
let deleted = 0;
|
|
117
|
-
for (const key of keysToDelete) {
|
|
118
|
-
const success = await deleteKey(key);
|
|
119
|
-
if (success)
|
|
120
|
-
deleted++;
|
|
121
|
-
}
|
|
122
|
-
return deleted;
|
|
123
|
-
};
|
|
124
|
-
const clear = async () => {
|
|
125
|
-
const size = store.size;
|
|
126
|
-
store.clear();
|
|
127
|
-
tagIndex.clear();
|
|
128
|
-
return size;
|
|
129
|
-
};
|
|
130
|
-
const keys = async (pattern) => {
|
|
131
|
-
const allKeys = Array.from(store.keys());
|
|
132
|
-
if (!pattern)
|
|
133
|
-
return allKeys;
|
|
134
|
-
return allKeys.filter((key) => matchPattern(key, pattern));
|
|
135
|
-
};
|
|
136
|
-
const stats = async () => {
|
|
137
|
-
let expired = 0;
|
|
138
|
-
for (const entry of store.values()) {
|
|
139
|
-
if (isExpired(entry)) {
|
|
140
|
-
expired++;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return { size: store.size, expired };
|
|
144
|
-
};
|
|
145
|
-
const cleanup = async () => {
|
|
146
|
-
let removed = 0;
|
|
147
|
-
for (const [key, entry] of store.entries()) {
|
|
148
|
-
if (isExpired(entry)) {
|
|
149
|
-
cleanupExpiredEntry(key, entry);
|
|
150
|
-
removed++;
|
|
151
|
-
}
|
|
72
|
+
store.set(key, entry);
|
|
73
|
+
addToTagIndex(key, tags);
|
|
74
|
+
};
|
|
75
|
+
const has = async (key) => {
|
|
76
|
+
const entry = store.get(key);
|
|
77
|
+
if (!entry) return false;
|
|
78
|
+
if (isExpired(entry)) {
|
|
79
|
+
cleanupExpiredEntry(key, entry);
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
};
|
|
84
|
+
const deleteKey = async (key) => {
|
|
85
|
+
const entry = store.get(key);
|
|
86
|
+
if (!entry) return false;
|
|
87
|
+
removeFromTagIndex(key, entry.tags);
|
|
88
|
+
return store.delete(key);
|
|
89
|
+
};
|
|
90
|
+
const deleteByTags = async (tags) => {
|
|
91
|
+
const keysToDelete = /* @__PURE__ */ new Set();
|
|
92
|
+
for (const tag of tags) {
|
|
93
|
+
const keys2 = tagIndex.get(tag);
|
|
94
|
+
if (keys2) {
|
|
95
|
+
for (const key of keys2) {
|
|
96
|
+
keysToDelete.add(key);
|
|
152
97
|
}
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
let deleted = 0;
|
|
101
|
+
for (const key of keysToDelete) {
|
|
102
|
+
const success = await deleteKey(key);
|
|
103
|
+
if (success) deleted++;
|
|
104
|
+
}
|
|
105
|
+
return deleted;
|
|
106
|
+
};
|
|
107
|
+
const clear = async () => {
|
|
108
|
+
const size = store.size;
|
|
109
|
+
store.clear();
|
|
110
|
+
tagIndex.clear();
|
|
111
|
+
return size;
|
|
112
|
+
};
|
|
113
|
+
const keys = async (pattern) => {
|
|
114
|
+
const allKeys = Array.from(store.keys());
|
|
115
|
+
if (!pattern) return allKeys;
|
|
116
|
+
return allKeys.filter((key) => matchPattern(key, pattern));
|
|
117
|
+
};
|
|
118
|
+
const stats = async () => {
|
|
119
|
+
let expired = 0;
|
|
120
|
+
for (const entry of store.values()) {
|
|
121
|
+
if (isExpired(entry)) {
|
|
122
|
+
expired++;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { size: store.size, expired };
|
|
126
|
+
};
|
|
127
|
+
const cleanup = async () => {
|
|
128
|
+
let removed = 0;
|
|
129
|
+
for (const [key, entry] of store.entries()) {
|
|
130
|
+
if (isExpired(entry)) {
|
|
131
|
+
cleanupExpiredEntry(key, entry);
|
|
132
|
+
removed++;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return removed;
|
|
136
|
+
};
|
|
137
|
+
return {
|
|
138
|
+
get,
|
|
139
|
+
set,
|
|
140
|
+
has,
|
|
141
|
+
delete: deleteKey,
|
|
142
|
+
deleteByTags,
|
|
143
|
+
clear,
|
|
144
|
+
keys,
|
|
145
|
+
stats,
|
|
146
|
+
cleanup
|
|
147
|
+
};
|
|
166
148
|
}
|
|
149
|
+
export {
|
|
150
|
+
createMemoryStrategy
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/strategies/memory.ts"],
|
|
4
|
+
"sourcesContent": ["import type { CacheStrategy, CacheEntry, CacheGetOptions, CacheSetOptions, CacheValue } from '../types'\n\n/**\n * In-memory cache strategy with tag support\n * Fast but data is lost when process restarts\n */\nexport function createMemoryStrategy(options?: { defaultTtl?: number }): CacheStrategy {\n const store = new Map<string, CacheEntry>()\n const tagIndex = new Map<string, Set<string>>() // tag -> Set of keys\n const defaultTtl = options?.defaultTtl\n\n function isExpired(entry: CacheEntry): boolean {\n if (entry.expiresAt === null) return false\n return Date.now() > entry.expiresAt\n }\n\n function cleanupExpiredEntry(key: string, entry: CacheEntry): void {\n store.delete(key)\n // Remove from tag index\n for (const tag of entry.tags) {\n const keys = tagIndex.get(tag)\n if (keys) {\n keys.delete(key)\n if (keys.size === 0) {\n tagIndex.delete(tag)\n }\n }\n }\n }\n\n function addToTagIndex(key: string, tags: string[]): void {\n for (const tag of tags) {\n if (!tagIndex.has(tag)) {\n tagIndex.set(tag, new Set())\n }\n tagIndex.get(tag)!.add(key)\n }\n }\n\n function removeFromTagIndex(key: string, tags: string[]): void {\n for (const tag of tags) {\n const keys = tagIndex.get(tag)\n if (keys) {\n keys.delete(key)\n if (keys.size === 0) {\n tagIndex.delete(tag)\n }\n }\n }\n }\n\n function matchPattern(key: string, pattern: string): boolean {\n const regexPattern = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&') // Escape special regex chars\n .replace(/\\*/g, '.*') // * matches any characters\n .replace(/\\?/g, '.') // ? matches single character\n const regex = new RegExp(`^${regexPattern}$`)\n return regex.test(key)\n }\n\n const get = async (key: string, options?: CacheGetOptions): Promise<CacheValue | null> => {\n const entry = store.get(key)\n if (!entry) return null\n\n if (isExpired(entry)) {\n if (options?.returnExpired) {\n return entry.value\n }\n cleanupExpiredEntry(key, entry)\n return null\n }\n\n return entry.value\n }\n\n const set = async (key: string, value: CacheValue, options?: CacheSetOptions): Promise<void> => {\n // Remove old entry from tag index if it exists\n const oldEntry = store.get(key)\n if (oldEntry) {\n removeFromTagIndex(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 store.set(key, entry)\n addToTagIndex(key, tags)\n }\n\n const has = async (key: string): Promise<boolean> => {\n const entry = store.get(key)\n if (!entry) return false\n if (isExpired(entry)) {\n cleanupExpiredEntry(key, entry)\n return false\n }\n return true\n }\n\n const deleteKey = async (key: string): Promise<boolean> => {\n const entry = store.get(key)\n if (!entry) return false\n\n removeFromTagIndex(key, entry.tags)\n return store.delete(key)\n }\n\n const deleteByTags = async (tags: string[]): Promise<number> => {\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 = tagIndex.get(tag)\n if (keys) {\n for (const key of keys) {\n keysToDelete.add(key)\n }\n }\n }\n\n // Delete all collected keys\n let deleted = 0\n for (const key of keysToDelete) {\n const success = await deleteKey(key)\n if (success) deleted++\n }\n\n return deleted\n }\n\n const clear = async (): Promise<number> => {\n const size = store.size\n store.clear()\n tagIndex.clear()\n return size\n }\n\n const keys = async (pattern?: string): Promise<string[]> => {\n const allKeys = Array.from(store.keys())\n if (!pattern) return allKeys\n return allKeys.filter((key) => matchPattern(key, pattern))\n }\n\n const stats = async (): Promise<{ size: number; expired: number }> => {\n let expired = 0\n for (const entry of store.values()) {\n if (isExpired(entry)) {\n expired++\n }\n }\n return { size: store.size, expired }\n }\n\n const cleanup = async (): Promise<number> => {\n let removed = 0\n for (const [key, entry] of store.entries()) {\n if (isExpired(entry)) {\n cleanupExpiredEntry(key, entry)\n removed++\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": ["keys", "options"]
|
|
7
|
+
}
|