@darkiceinteractive/mcp-conductor 2.0.0-alpha.1 → 3.0.0-beta.2

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.
Files changed (276) hide show
  1. package/README.md +35 -5
  2. package/dist/bin/cli.d.ts +20 -0
  3. package/dist/bin/cli.d.ts.map +1 -0
  4. package/dist/bin/cli.js +260 -0
  5. package/dist/bin/cli.js.map +1 -0
  6. package/dist/bridge/http-server.d.ts +35 -0
  7. package/dist/bridge/http-server.d.ts.map +1 -1
  8. package/dist/bridge/http-server.js +51 -2
  9. package/dist/bridge/http-server.js.map +1 -1
  10. package/dist/bridge/index.d.ts +1 -0
  11. package/dist/bridge/index.d.ts.map +1 -1
  12. package/dist/bridge/index.js +1 -0
  13. package/dist/bridge/index.js.map +1 -1
  14. package/dist/bridge/pool.d.ts +95 -0
  15. package/dist/bridge/pool.d.ts.map +1 -0
  16. package/dist/bridge/pool.js +384 -0
  17. package/dist/bridge/pool.js.map +1 -0
  18. package/dist/cache/cache.d.ts +64 -0
  19. package/dist/cache/cache.d.ts.map +1 -0
  20. package/dist/cache/cache.js +209 -0
  21. package/dist/cache/cache.js.map +1 -0
  22. package/dist/cache/delta.d.ts +32 -0
  23. package/dist/cache/delta.d.ts.map +1 -0
  24. package/dist/cache/delta.js +131 -0
  25. package/dist/cache/delta.js.map +1 -0
  26. package/dist/cache/disk.d.ts +65 -0
  27. package/dist/cache/disk.d.ts.map +1 -0
  28. package/dist/cache/disk.js +238 -0
  29. package/dist/cache/disk.js.map +1 -0
  30. package/dist/cache/index.d.ts +53 -0
  31. package/dist/cache/index.d.ts.map +1 -0
  32. package/dist/cache/index.js +12 -0
  33. package/dist/cache/index.js.map +1 -0
  34. package/dist/cache/key.d.ts +44 -0
  35. package/dist/cache/key.d.ts.map +1 -0
  36. package/dist/cache/key.js +83 -0
  37. package/dist/cache/key.js.map +1 -0
  38. package/dist/cache/lru.d.ts +57 -0
  39. package/dist/cache/lru.d.ts.map +1 -0
  40. package/dist/cache/lru.js +112 -0
  41. package/dist/cache/lru.js.map +1 -0
  42. package/dist/cache/policy.d.ts +34 -0
  43. package/dist/cache/policy.d.ts.map +1 -0
  44. package/dist/cache/policy.js +95 -0
  45. package/dist/cache/policy.js.map +1 -0
  46. package/dist/cli/commands/doctor.d.ts +33 -0
  47. package/dist/cli/commands/doctor.d.ts.map +1 -0
  48. package/dist/cli/commands/doctor.js +135 -0
  49. package/dist/cli/commands/doctor.js.map +1 -0
  50. package/dist/cli/commands/export-servers.d.ts +22 -0
  51. package/dist/cli/commands/export-servers.d.ts.map +1 -0
  52. package/dist/cli/commands/export-servers.js +45 -0
  53. package/dist/cli/commands/export-servers.js.map +1 -0
  54. package/dist/cli/commands/import-servers.d.ts +57 -0
  55. package/dist/cli/commands/import-servers.d.ts.map +1 -0
  56. package/dist/cli/commands/import-servers.js +137 -0
  57. package/dist/cli/commands/import-servers.js.map +1 -0
  58. package/dist/cli/commands/routing.d.ts +34 -0
  59. package/dist/cli/commands/routing.d.ts.map +1 -0
  60. package/dist/cli/commands/routing.js +60 -0
  61. package/dist/cli/commands/routing.js.map +1 -0
  62. package/dist/cli/commands/test-server.d.ts +34 -0
  63. package/dist/cli/commands/test-server.d.ts.map +1 -0
  64. package/dist/cli/commands/test-server.js +86 -0
  65. package/dist/cli/commands/test-server.js.map +1 -0
  66. package/dist/cli/daemon.d.ts +60 -0
  67. package/dist/cli/daemon.d.ts.map +1 -0
  68. package/dist/cli/daemon.js +244 -0
  69. package/dist/cli/daemon.js.map +1 -0
  70. package/dist/cli/replay.d.ts +16 -0
  71. package/dist/cli/replay.d.ts.map +1 -0
  72. package/dist/cli/replay.js +89 -0
  73. package/dist/cli/replay.js.map +1 -0
  74. package/dist/cli/wizard/setup.d.ts +12 -0
  75. package/dist/cli/wizard/setup.d.ts.map +1 -0
  76. package/dist/cli/wizard/setup.js +71 -0
  77. package/dist/cli/wizard/setup.js.map +1 -0
  78. package/dist/config/defaults.d.ts.map +1 -1
  79. package/dist/config/defaults.js +4 -1
  80. package/dist/config/defaults.js.map +1 -1
  81. package/dist/config/schema.d.ts +34 -0
  82. package/dist/config/schema.d.ts.map +1 -1
  83. package/dist/daemon/client.d.ts +99 -0
  84. package/dist/daemon/client.d.ts.map +1 -0
  85. package/dist/daemon/client.js +292 -0
  86. package/dist/daemon/client.js.map +1 -0
  87. package/dist/daemon/discovery.d.ts +50 -0
  88. package/dist/daemon/discovery.d.ts.map +1 -0
  89. package/dist/daemon/discovery.js +104 -0
  90. package/dist/daemon/discovery.js.map +1 -0
  91. package/dist/daemon/index.d.ts +16 -0
  92. package/dist/daemon/index.d.ts.map +1 -0
  93. package/dist/daemon/index.js +11 -0
  94. package/dist/daemon/index.js.map +1 -0
  95. package/dist/daemon/sandbox-api.d.ts +45 -0
  96. package/dist/daemon/sandbox-api.d.ts.map +1 -0
  97. package/dist/daemon/sandbox-api.js +74 -0
  98. package/dist/daemon/sandbox-api.js.map +1 -0
  99. package/dist/daemon/server.d.ts +65 -0
  100. package/dist/daemon/server.d.ts.map +1 -0
  101. package/dist/daemon/server.js +373 -0
  102. package/dist/daemon/server.js.map +1 -0
  103. package/dist/daemon/shared-kv.d.ts +81 -0
  104. package/dist/daemon/shared-kv.d.ts.map +1 -0
  105. package/dist/daemon/shared-kv.js +215 -0
  106. package/dist/daemon/shared-kv.js.map +1 -0
  107. package/dist/daemon/shared-lock.d.ts +71 -0
  108. package/dist/daemon/shared-lock.d.ts.map +1 -0
  109. package/dist/daemon/shared-lock.js +119 -0
  110. package/dist/daemon/shared-lock.js.map +1 -0
  111. package/dist/hub/mcp-hub.d.ts +23 -0
  112. package/dist/hub/mcp-hub.d.ts.map +1 -1
  113. package/dist/hub/mcp-hub.js +34 -1
  114. package/dist/hub/mcp-hub.js.map +1 -1
  115. package/dist/index.js +7 -0
  116. package/dist/index.js.map +1 -1
  117. package/dist/observability/anomaly.d.ts +67 -0
  118. package/dist/observability/anomaly.d.ts.map +1 -0
  119. package/dist/observability/anomaly.js +141 -0
  120. package/dist/observability/anomaly.js.map +1 -0
  121. package/dist/observability/cost-predictor.d.ts +49 -0
  122. package/dist/observability/cost-predictor.d.ts.map +1 -0
  123. package/dist/observability/cost-predictor.js +145 -0
  124. package/dist/observability/cost-predictor.js.map +1 -0
  125. package/dist/observability/hot-path.d.ts +49 -0
  126. package/dist/observability/hot-path.d.ts.map +1 -0
  127. package/dist/observability/hot-path.js +125 -0
  128. package/dist/observability/hot-path.js.map +1 -0
  129. package/dist/observability/index.d.ts +10 -0
  130. package/dist/observability/index.d.ts.map +1 -0
  131. package/dist/observability/index.js +10 -0
  132. package/dist/observability/index.js.map +1 -0
  133. package/dist/observability/replay.d.ts +104 -0
  134. package/dist/observability/replay.d.ts.map +1 -0
  135. package/dist/observability/replay.js +239 -0
  136. package/dist/observability/replay.js.map +1 -0
  137. package/dist/registry/built-in-recommendations.d.ts +54 -0
  138. package/dist/registry/built-in-recommendations.d.ts.map +1 -0
  139. package/dist/registry/built-in-recommendations.js +65 -0
  140. package/dist/registry/built-in-recommendations.js.map +1 -0
  141. package/dist/registry/events.d.ts +26 -0
  142. package/dist/registry/events.d.ts.map +1 -0
  143. package/dist/registry/events.js +22 -0
  144. package/dist/registry/events.js.map +1 -0
  145. package/dist/registry/index.d.ts +159 -0
  146. package/dist/registry/index.d.ts.map +1 -0
  147. package/dist/registry/index.js +12 -0
  148. package/dist/registry/index.js.map +1 -0
  149. package/dist/registry/registry.d.ts +87 -0
  150. package/dist/registry/registry.d.ts.map +1 -0
  151. package/dist/registry/registry.js +294 -0
  152. package/dist/registry/registry.js.map +1 -0
  153. package/dist/registry/snapshot.d.ts +42 -0
  154. package/dist/registry/snapshot.d.ts.map +1 -0
  155. package/dist/registry/snapshot.js +71 -0
  156. package/dist/registry/snapshot.js.map +1 -0
  157. package/dist/registry/typegen.d.ts +48 -0
  158. package/dist/registry/typegen.d.ts.map +1 -0
  159. package/dist/registry/typegen.js +200 -0
  160. package/dist/registry/typegen.js.map +1 -0
  161. package/dist/registry/validator.d.ts +23 -0
  162. package/dist/registry/validator.d.ts.map +1 -0
  163. package/dist/registry/validator.js +50 -0
  164. package/dist/registry/validator.js.map +1 -0
  165. package/dist/reliability/breaker.d.ts +57 -0
  166. package/dist/reliability/breaker.d.ts.map +1 -0
  167. package/dist/reliability/breaker.js +130 -0
  168. package/dist/reliability/breaker.js.map +1 -0
  169. package/dist/reliability/errors.d.ts +78 -0
  170. package/dist/reliability/errors.d.ts.map +1 -0
  171. package/dist/reliability/errors.js +160 -0
  172. package/dist/reliability/errors.js.map +1 -0
  173. package/dist/reliability/gateway.d.ts +88 -0
  174. package/dist/reliability/gateway.d.ts.map +1 -0
  175. package/dist/reliability/gateway.js +180 -0
  176. package/dist/reliability/gateway.js.map +1 -0
  177. package/dist/reliability/index.d.ts +20 -0
  178. package/dist/reliability/index.d.ts.map +1 -0
  179. package/dist/reliability/index.js +16 -0
  180. package/dist/reliability/index.js.map +1 -0
  181. package/dist/reliability/profile.d.ts +49 -0
  182. package/dist/reliability/profile.d.ts.map +1 -0
  183. package/dist/reliability/profile.js +58 -0
  184. package/dist/reliability/profile.js.map +1 -0
  185. package/dist/reliability/retry.d.ts +39 -0
  186. package/dist/reliability/retry.d.ts.map +1 -0
  187. package/dist/reliability/retry.js +51 -0
  188. package/dist/reliability/retry.js.map +1 -0
  189. package/dist/reliability/timeout.d.ts +34 -0
  190. package/dist/reliability/timeout.d.ts.map +1 -0
  191. package/dist/reliability/timeout.js +53 -0
  192. package/dist/reliability/timeout.js.map +1 -0
  193. package/dist/runtime/executor.d.ts.map +1 -1
  194. package/dist/runtime/executor.js +122 -14
  195. package/dist/runtime/executor.js.map +1 -1
  196. package/dist/runtime/findtool/embed.d.ts +28 -0
  197. package/dist/runtime/findtool/embed.d.ts.map +1 -0
  198. package/dist/runtime/findtool/embed.js +85 -0
  199. package/dist/runtime/findtool/embed.js.map +1 -0
  200. package/dist/runtime/findtool/index.d.ts +52 -0
  201. package/dist/runtime/findtool/index.d.ts.map +1 -0
  202. package/dist/runtime/findtool/index.js +78 -0
  203. package/dist/runtime/findtool/index.js.map +1 -0
  204. package/dist/runtime/findtool/vector-index.d.ts +53 -0
  205. package/dist/runtime/findtool/vector-index.d.ts.map +1 -0
  206. package/dist/runtime/findtool/vector-index.js +71 -0
  207. package/dist/runtime/findtool/vector-index.js.map +1 -0
  208. package/dist/runtime/helpers/budget.d.ts +27 -0
  209. package/dist/runtime/helpers/budget.d.ts.map +1 -0
  210. package/dist/runtime/helpers/budget.js +103 -0
  211. package/dist/runtime/helpers/budget.js.map +1 -0
  212. package/dist/runtime/helpers/compact.d.ts +32 -0
  213. package/dist/runtime/helpers/compact.d.ts.map +1 -0
  214. package/dist/runtime/helpers/compact.js +93 -0
  215. package/dist/runtime/helpers/compact.js.map +1 -0
  216. package/dist/runtime/helpers/delta.d.ts +45 -0
  217. package/dist/runtime/helpers/delta.d.ts.map +1 -0
  218. package/dist/runtime/helpers/delta.js +116 -0
  219. package/dist/runtime/helpers/delta.js.map +1 -0
  220. package/dist/runtime/helpers/index.d.ts +16 -0
  221. package/dist/runtime/helpers/index.d.ts.map +1 -0
  222. package/dist/runtime/helpers/index.js +13 -0
  223. package/dist/runtime/helpers/index.js.map +1 -0
  224. package/dist/runtime/helpers/summarize.d.ts +24 -0
  225. package/dist/runtime/helpers/summarize.d.ts.map +1 -0
  226. package/dist/runtime/helpers/summarize.js +124 -0
  227. package/dist/runtime/helpers/summarize.js.map +1 -0
  228. package/dist/runtime/helpers/worker-preload.d.ts +25 -0
  229. package/dist/runtime/helpers/worker-preload.d.ts.map +1 -0
  230. package/dist/runtime/helpers/worker-preload.js +223 -0
  231. package/dist/runtime/helpers/worker-preload.js.map +1 -0
  232. package/dist/runtime/index.d.ts +1 -0
  233. package/dist/runtime/index.d.ts.map +1 -1
  234. package/dist/runtime/index.js +1 -0
  235. package/dist/runtime/index.js.map +1 -1
  236. package/dist/runtime/pool/index.d.ts +11 -0
  237. package/dist/runtime/pool/index.d.ts.map +1 -0
  238. package/dist/runtime/pool/index.js +8 -0
  239. package/dist/runtime/pool/index.js.map +1 -0
  240. package/dist/runtime/pool/recycle.d.ts +44 -0
  241. package/dist/runtime/pool/recycle.d.ts.map +1 -0
  242. package/dist/runtime/pool/recycle.js +50 -0
  243. package/dist/runtime/pool/recycle.js.map +1 -0
  244. package/dist/runtime/pool/worker-pool.d.ts +77 -0
  245. package/dist/runtime/pool/worker-pool.d.ts.map +1 -0
  246. package/dist/runtime/pool/worker-pool.js +216 -0
  247. package/dist/runtime/pool/worker-pool.js.map +1 -0
  248. package/dist/runtime/pool/worker.d.ts +80 -0
  249. package/dist/runtime/pool/worker.d.ts.map +1 -0
  250. package/dist/runtime/pool/worker.js +324 -0
  251. package/dist/runtime/pool/worker.js.map +1 -0
  252. package/dist/server/mcp-server.d.ts +3 -0
  253. package/dist/server/mcp-server.d.ts.map +1 -1
  254. package/dist/server/mcp-server.js +457 -3
  255. package/dist/server/mcp-server.js.map +1 -1
  256. package/dist/server/passthrough-registrar.d.ts +123 -0
  257. package/dist/server/passthrough-registrar.d.ts.map +1 -0
  258. package/dist/server/passthrough-registrar.js +199 -0
  259. package/dist/server/passthrough-registrar.js.map +1 -0
  260. package/dist/skills/skills-engine.d.ts +9 -1
  261. package/dist/skills/skills-engine.d.ts.map +1 -1
  262. package/dist/skills/skills-engine.js +20 -3
  263. package/dist/skills/skills-engine.js.map +1 -1
  264. package/dist/utils/index.d.ts +1 -0
  265. package/dist/utils/index.d.ts.map +1 -1
  266. package/dist/utils/index.js +1 -0
  267. package/dist/utils/index.js.map +1 -1
  268. package/dist/utils/tokenize.d.ts +55 -0
  269. package/dist/utils/tokenize.d.ts.map +1 -0
  270. package/dist/utils/tokenize.js +205 -0
  271. package/dist/utils/tokenize.js.map +1 -0
  272. package/dist/version.d.ts +3 -3
  273. package/dist/version.d.ts.map +1 -1
  274. package/dist/version.js +3 -3
  275. package/dist/version.js.map +1 -1
  276. package/package.json +13 -3
@@ -0,0 +1,238 @@
1
+ /**
2
+ * Persistent disk cache tier using CBOR encoding (cbor-x).
3
+ *
4
+ * Layout on disk:
5
+ * <diskDir>/<sha256-prefix-2>/<full-argsHash>.cbor
6
+ *
7
+ * TTL enforcement is the responsibility of the caller (CacheLayer). DiskCache
8
+ * returns entries regardless of TTL so that stale-while-revalidate can be
9
+ * handled at the CacheLayer level.
10
+ *
11
+ * Parallel writes are safe: each key maps to a unique path; writes are
12
+ * atomic via a temp-file rename pattern.
13
+ *
14
+ * @module cache/disk
15
+ */
16
+ import { readFile, writeFile, mkdir, readdir, stat, unlink, rename } from 'node:fs/promises';
17
+ import { join, dirname } from 'node:path';
18
+ import { encode as cborEncode, decode as cborDecode } from 'cbor-x';
19
+ import { logger } from '../utils/index.js';
20
+ const ROTATION_TARGET_RATIO = 0.8;
21
+ export class DiskCache {
22
+ diskDir;
23
+ maxDiskBytes;
24
+ hits = 0;
25
+ misses = 0;
26
+ bytesOnDisk = 0;
27
+ ready;
28
+ constructor(options) {
29
+ this.diskDir = options.diskDir;
30
+ this.maxDiskBytes = options.maxDiskBytes ?? 2 * 1024 * 1024 * 1024;
31
+ this.ready = mkdir(this.diskDir, { recursive: true }).then(() => undefined);
32
+ }
33
+ async ensureReady() {
34
+ await this.ready;
35
+ }
36
+ entryPath(argsHash) {
37
+ const prefix = argsHash.substring(0, 2);
38
+ return join(this.diskDir, prefix, `${argsHash}.cbor`);
39
+ }
40
+ /**
41
+ * Read an entry from disk.
42
+ * Returns null only on genuine miss or read errors — TTL is NOT enforced here.
43
+ * CacheLayer is responsible for staleness decisions (enabling SWR to work).
44
+ */
45
+ async get(argsHash) {
46
+ await this.ensureReady();
47
+ const path = this.entryPath(argsHash);
48
+ try {
49
+ const buf = await readFile(path);
50
+ const entry = cborDecode(buf);
51
+ this.hits++;
52
+ return {
53
+ value: entry.value,
54
+ storedAt: entry.storedAt,
55
+ source: 'disk',
56
+ staleness: Date.now() - entry.storedAt,
57
+ ttlMs: entry.ttlMs,
58
+ };
59
+ }
60
+ catch (err) {
61
+ if (err.code !== 'ENOENT') {
62
+ logger.debug('DiskCache: read error', { path, error: String(err) });
63
+ }
64
+ this.misses++;
65
+ return null;
66
+ }
67
+ }
68
+ /**
69
+ * Write an entry to disk atomically (write to .tmp then rename).
70
+ * Triggers rotation when over maxDiskBytes.
71
+ */
72
+ async set(argsHash, entry) {
73
+ await this.ensureReady();
74
+ const path = this.entryPath(argsHash);
75
+ const tmpPath = `${path}.tmp.${process.pid}`;
76
+ await mkdir(dirname(path), { recursive: true });
77
+ const buf = cborEncode(entry);
78
+ await writeFile(tmpPath, buf);
79
+ await rename(tmpPath, path);
80
+ this.bytesOnDisk += buf.byteLength;
81
+ if (this.bytesOnDisk > this.maxDiskBytes) {
82
+ this.rotate().catch((err) => logger.warn('DiskCache: rotation error', { error: String(err) }));
83
+ }
84
+ }
85
+ async delete(argsHash) {
86
+ await this.ensureReady();
87
+ const path = this.entryPath(argsHash);
88
+ try {
89
+ const s = await stat(path);
90
+ await unlink(path);
91
+ this.bytesOnDisk = Math.max(0, this.bytesOnDisk - s.size);
92
+ return true;
93
+ }
94
+ catch {
95
+ return false;
96
+ }
97
+ }
98
+ async invalidateByPrefix(serverToolPrefix) {
99
+ await this.ensureReady();
100
+ return this.scanAndDelete(async (entry, filePath) => {
101
+ const entryKey = `${entry.server}:${entry.tool}`;
102
+ const normalizedPrefix = serverToolPrefix.endsWith(':')
103
+ ? serverToolPrefix.slice(0, -1)
104
+ : serverToolPrefix;
105
+ // Match: entryKey starts with prefix (handles server-only and server:tool prefixes)
106
+ if (entryKey.startsWith(normalizedPrefix)) {
107
+ try {
108
+ const s = await stat(filePath);
109
+ await unlink(filePath);
110
+ this.bytesOnDisk = Math.max(0, this.bytesOnDisk - s.size);
111
+ return true;
112
+ }
113
+ catch {
114
+ return false;
115
+ }
116
+ }
117
+ return false;
118
+ });
119
+ }
120
+ async invalidateServer(server) {
121
+ await this.ensureReady();
122
+ return this.scanAndDelete(async (entry, filePath) => {
123
+ if (entry.server === server) {
124
+ try {
125
+ const s = await stat(filePath);
126
+ await unlink(filePath);
127
+ this.bytesOnDisk = Math.max(0, this.bytesOnDisk - s.size);
128
+ return true;
129
+ }
130
+ catch {
131
+ return false;
132
+ }
133
+ }
134
+ return false;
135
+ });
136
+ }
137
+ async clear() {
138
+ await this.ensureReady();
139
+ await this.scanAndDelete(async (_entry, filePath) => {
140
+ try {
141
+ await unlink(filePath);
142
+ return true;
143
+ }
144
+ catch {
145
+ return false;
146
+ }
147
+ });
148
+ this.bytesOnDisk = 0;
149
+ }
150
+ get approximateBytesOnDisk() { return this.bytesOnDisk; }
151
+ getCounters() { return { hits: this.hits, misses: this.misses }; }
152
+ async scanAndDelete(predicate) {
153
+ let count = 0;
154
+ let prefixDirs;
155
+ try {
156
+ prefixDirs = await readdir(this.diskDir);
157
+ }
158
+ catch {
159
+ return 0;
160
+ }
161
+ await Promise.all(prefixDirs.map(async (prefix) => {
162
+ const prefixPath = join(this.diskDir, prefix);
163
+ let files;
164
+ try {
165
+ const s = await stat(prefixPath);
166
+ if (!s.isDirectory())
167
+ return;
168
+ files = await readdir(prefixPath);
169
+ }
170
+ catch {
171
+ return;
172
+ }
173
+ await Promise.all(files.filter((f) => f.endsWith('.cbor')).map(async (f) => {
174
+ const filePath = join(prefixPath, f);
175
+ try {
176
+ const buf = await readFile(filePath);
177
+ const entry = cborDecode(buf);
178
+ const deleted = await predicate(entry, filePath);
179
+ if (deleted)
180
+ count++;
181
+ }
182
+ catch { /* corrupt — skip */ }
183
+ }));
184
+ }));
185
+ return count;
186
+ }
187
+ async rotate() {
188
+ const target = Math.floor(this.maxDiskBytes * ROTATION_TARGET_RATIO);
189
+ if (this.bytesOnDisk <= target)
190
+ return;
191
+ const entries = [];
192
+ let prefixDirs;
193
+ try {
194
+ prefixDirs = await readdir(this.diskDir);
195
+ }
196
+ catch {
197
+ return;
198
+ }
199
+ await Promise.all(prefixDirs.map(async (prefix) => {
200
+ const prefixPath = join(this.diskDir, prefix);
201
+ let files;
202
+ try {
203
+ const s = await stat(prefixPath);
204
+ if (!s.isDirectory())
205
+ return;
206
+ files = await readdir(prefixPath);
207
+ }
208
+ catch {
209
+ return;
210
+ }
211
+ await Promise.all(files.filter((f) => f.endsWith('.cbor')).map(async (f) => {
212
+ const filePath = join(prefixPath, f);
213
+ try {
214
+ const s = await stat(filePath);
215
+ const buf = await readFile(filePath);
216
+ const entry = cborDecode(buf);
217
+ entries.push({ filePath, storedAt: entry.storedAt, size: s.size });
218
+ }
219
+ catch { /* skip */ }
220
+ }));
221
+ }));
222
+ entries.sort((a, b) => a.storedAt - b.storedAt);
223
+ let freed = 0;
224
+ const toFree = this.bytesOnDisk - target;
225
+ for (const e of entries) {
226
+ if (freed >= toFree)
227
+ break;
228
+ try {
229
+ await unlink(e.filePath);
230
+ freed += e.size;
231
+ this.bytesOnDisk = Math.max(0, this.bytesOnDisk - e.size);
232
+ }
233
+ catch { /* concurrent delete — ok */ }
234
+ }
235
+ logger.debug('DiskCache: rotated', { freedBytes: freed });
236
+ }
237
+ }
238
+ //# sourceMappingURL=disk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disk.js","sourceRoot":"","sources":["../../src/cache/disk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Public API for the MCP Conductor cache layer.
3
+ * Three-tier cache: in-memory LRU → persistent CBOR disk → delta encoding.
4
+ * @module cache
5
+ */
6
+ export interface CacheKey {
7
+ server: string;
8
+ tool: string;
9
+ argsHash: string;
10
+ }
11
+ export interface CacheHit {
12
+ value: unknown;
13
+ storedAt: number;
14
+ source: 'memory' | 'disk';
15
+ staleness: number;
16
+ }
17
+ export interface CacheStats {
18
+ memoryHits: number;
19
+ diskHits: number;
20
+ misses: number;
21
+ evictions: number;
22
+ bytesInMemory: number;
23
+ bytesOnDisk: number;
24
+ }
25
+ export interface DeltaResult {
26
+ unchanged: boolean;
27
+ added?: unknown[];
28
+ removed?: unknown[];
29
+ modified?: Array<{
30
+ before: unknown;
31
+ after: unknown;
32
+ }>;
33
+ full?: unknown;
34
+ }
35
+ export interface CacheLayerOptions {
36
+ registry: import('../registry/registry.js').ToolRegistry;
37
+ diskDir?: string;
38
+ maxMemoryBytes?: number;
39
+ maxDiskBytes?: number;
40
+ staleWhileRevalidate?: boolean;
41
+ policies?: import('./policy.js').ServerPolicies;
42
+ }
43
+ export { CacheLayer } from './cache.js';
44
+ export type { ExtendedCacheHit } from './cache.js';
45
+ export { MemoryLru } from './lru.js';
46
+ export type { LruOptions, LruEntry } from './lru.js';
47
+ export { DiskCache } from './disk.js';
48
+ export type { DiskCacheOptions, DiskEntry, DiskCacheHit } from './disk.js';
49
+ export { stableJsonStringify, hashArgs, buildCacheKey, cacheKeyToString, parseCacheKey } from './key.js';
50
+ export { resolveTtl, isCacheable, defaultTtlForName, DEFAULT_TTL_MS } from './policy.js';
51
+ export type { ServerPolicies } from './policy.js';
52
+ export { computeDelta, deepEqual } from './delta.js';
53
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACtD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,yBAAyB,EAAE,YAAY,CAAC;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,aAAa,EAAE,cAAc,CAAC;CACjD;AAED,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzG,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzF,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Public API for the MCP Conductor cache layer.
3
+ * Three-tier cache: in-memory LRU → persistent CBOR disk → delta encoding.
4
+ * @module cache
5
+ */
6
+ export { CacheLayer } from './cache.js';
7
+ export { MemoryLru } from './lru.js';
8
+ export { DiskCache } from './disk.js';
9
+ export { stableJsonStringify, hashArgs, buildCacheKey, cacheKeyToString, parseCacheKey } from './key.js';
10
+ export { resolveTtl, isCacheable, defaultTtlForName, DEFAULT_TTL_MS } from './policy.js';
11
+ export { computeDelta, deepEqual } from './delta.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyCH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzG,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEzF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Content-addressed cache key derivation.
3
+ *
4
+ * Keys are stable across process restarts: the same args always produce the
5
+ * same hash regardless of JS object-key insertion order. Schema-normalised
6
+ * args (via the registry validator) are used so that semantically-equivalent
7
+ * calls with differently-ordered properties hash identically.
8
+ *
9
+ * Format: `${server}:${tool}:${sha256hex(stableJsonStringify(args))}`
10
+ *
11
+ * @module cache/key
12
+ */
13
+ import type { CacheKey } from './index.js';
14
+ /**
15
+ * Stable JSON stringify — sorts object keys recursively so that key ordering
16
+ * differences between calls do not produce different hashes.
17
+ *
18
+ * Handles:
19
+ * - Objects (sorted keys)
20
+ * - Arrays (order preserved — array order IS semantically meaningful)
21
+ * - Primitives (null, boolean, number, string, undefined → JSON-serialised)
22
+ * - Circular references: throws, same as JSON.stringify
23
+ */
24
+ export declare function stableJsonStringify(value: unknown): string;
25
+ /**
26
+ * SHA-256 hex digest of a stable-stringified value.
27
+ * The returned string is always 64 hex characters.
28
+ */
29
+ export declare function hashArgs(args: unknown): string;
30
+ /**
31
+ * Build a structured CacheKey from server, tool, and args.
32
+ */
33
+ export declare function buildCacheKey(server: string, tool: string, args: unknown): CacheKey;
34
+ /**
35
+ * Serialise a CacheKey to the string format used on disk and in memory maps.
36
+ * Format: `${server}:${tool}:${argsHash}`
37
+ */
38
+ export declare function cacheKeyToString(key: CacheKey): string;
39
+ /**
40
+ * Parse a stringified cache key back to a CacheKey struct.
41
+ * Returns null when the format is invalid.
42
+ */
43
+ export declare function parseCacheKey(str: string): CacheKey | null;
44
+ //# sourceMappingURL=key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key.d.ts","sourceRoot":"","sources":["../../src/cache/key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE1D;AAkBD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAG9C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,CAEnF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAEtD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAgB1D"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Content-addressed cache key derivation.
3
+ *
4
+ * Keys are stable across process restarts: the same args always produce the
5
+ * same hash regardless of JS object-key insertion order. Schema-normalised
6
+ * args (via the registry validator) are used so that semantically-equivalent
7
+ * calls with differently-ordered properties hash identically.
8
+ *
9
+ * Format: `${server}:${tool}:${sha256hex(stableJsonStringify(args))}`
10
+ *
11
+ * @module cache/key
12
+ */
13
+ import { createHash } from 'node:crypto';
14
+ /**
15
+ * Stable JSON stringify — sorts object keys recursively so that key ordering
16
+ * differences between calls do not produce different hashes.
17
+ *
18
+ * Handles:
19
+ * - Objects (sorted keys)
20
+ * - Arrays (order preserved — array order IS semantically meaningful)
21
+ * - Primitives (null, boolean, number, string, undefined → JSON-serialised)
22
+ * - Circular references: throws, same as JSON.stringify
23
+ */
24
+ export function stableJsonStringify(value) {
25
+ return JSON.stringify(sortObjectKeys(value));
26
+ }
27
+ function sortObjectKeys(value) {
28
+ if (value === null || value === undefined)
29
+ return value;
30
+ if (typeof value !== 'object')
31
+ return value;
32
+ if (Array.isArray(value)) {
33
+ return value.map(sortObjectKeys);
34
+ }
35
+ const sorted = {};
36
+ const keys = Object.keys(value).sort();
37
+ for (const k of keys) {
38
+ sorted[k] = sortObjectKeys(value[k]);
39
+ }
40
+ return sorted;
41
+ }
42
+ /**
43
+ * SHA-256 hex digest of a stable-stringified value.
44
+ * The returned string is always 64 hex characters.
45
+ */
46
+ export function hashArgs(args) {
47
+ const str = stableJsonStringify(args ?? {});
48
+ return createHash('sha256').update(str, 'utf8').digest('hex');
49
+ }
50
+ /**
51
+ * Build a structured CacheKey from server, tool, and args.
52
+ */
53
+ export function buildCacheKey(server, tool, args) {
54
+ return { server, tool, argsHash: hashArgs(args) };
55
+ }
56
+ /**
57
+ * Serialise a CacheKey to the string format used on disk and in memory maps.
58
+ * Format: `${server}:${tool}:${argsHash}`
59
+ */
60
+ export function cacheKeyToString(key) {
61
+ return `${key.server}:${key.tool}:${key.argsHash}`;
62
+ }
63
+ /**
64
+ * Parse a stringified cache key back to a CacheKey struct.
65
+ * Returns null when the format is invalid.
66
+ */
67
+ export function parseCacheKey(str) {
68
+ // Key has exactly 3 segments: server, tool, and a 64-char hex hash.
69
+ // Tool names may contain underscores; server names should not contain colons.
70
+ const firstColon = str.indexOf(':');
71
+ if (firstColon < 0)
72
+ return null;
73
+ const hashStart = str.lastIndexOf(':');
74
+ if (hashStart <= firstColon)
75
+ return null;
76
+ const server = str.substring(0, firstColon);
77
+ const tool = str.substring(firstColon + 1, hashStart);
78
+ const argsHash = str.substring(hashStart + 1);
79
+ if (!server || !tool || argsHash.length !== 64)
80
+ return null;
81
+ return { server, tool, argsHash };
82
+ }
83
+ //# sourceMappingURL=key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key.js","sourceRoot":"","sources":["../../src/cache/key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAE5C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACnC,CAAC;IAED,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClE,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,CAAC,CAAC,CAAC,GAAG,cAAc,CAAE,KAAiC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAa;IACpC,MAAM,GAAG,GAAG,mBAAmB,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC5C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,IAAY,EAAE,IAAa;IACvE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAa;IAC5C,OAAO,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,oEAAoE;IACpE,8EAA8E;IAC9E,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAEhC,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,SAAS,IAAI,UAAU;QAAE,OAAO,IAAI,CAAC;IAEzC,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IAE9C,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,MAAM,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAE5D,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AACpC,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * In-memory LRU cache tier.
3
+ *
4
+ * Wraps `lru-cache` with byte-aware eviction. TTL is enforced manually via
5
+ * storedAt + ttlMs fields rather than lru-cache's built-in TTL, so that
6
+ * tests using vi.useFakeTimers() work correctly (lru-cache's internal TTL
7
+ * uses the real clock bypassing the fake timer).
8
+ *
9
+ * @module cache/lru
10
+ */
11
+ import type { CacheHit } from './index.js';
12
+ export interface LruEntry {
13
+ value: unknown;
14
+ storedAt: number;
15
+ ttlMs: number;
16
+ }
17
+ export interface LruOptions {
18
+ /** Maximum total byte size of all cached values (default: 100 MB). */
19
+ maxMemoryBytes?: number;
20
+ }
21
+ export declare class MemoryLru {
22
+ private cache;
23
+ private evictions;
24
+ private hits;
25
+ private misses;
26
+ constructor(options?: LruOptions);
27
+ /**
28
+ * Retrieve an entry. Returns null on miss or TTL expiry.
29
+ */
30
+ get(key: string): CacheHit | null;
31
+ /**
32
+ * Store a value. ttlMs of 0 means store without TTL expiry.
33
+ */
34
+ set(key: string, value: unknown, ttlMs: number): void;
35
+ /** Delete a single key. Returns true if the key existed. */
36
+ delete(key: string): boolean;
37
+ /**
38
+ * Delete all keys matching a prefix.
39
+ * Returns the count of deleted entries.
40
+ */
41
+ invalidateByPrefix(prefix: string): number;
42
+ /** Remove all entries. */
43
+ clear(): void;
44
+ /** Current total byte estimate across all entries. */
45
+ get bytesUsed(): number;
46
+ /** Number of entries currently held. */
47
+ get size(): number;
48
+ /** Expose counters for CacheStats aggregation. */
49
+ getCounters(): {
50
+ hits: number;
51
+ misses: number;
52
+ evictions: number;
53
+ };
54
+ /** Reset hit/miss/eviction counters (useful in tests). */
55
+ resetCounters(): void;
56
+ }
57
+ //# sourceMappingURL=lru.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lru.d.ts","sourceRoot":"","sources":["../../src/cache/lru.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAWD,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;gBAEP,OAAO,GAAE,UAAe;IAgBpC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAwBjC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKrD,4DAA4D;IAC5D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5B;;;OAGG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAW1C,0BAA0B;IAC1B,KAAK,IAAI,IAAI;IAIb,sDAAsD;IACtD,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,wCAAwC;IACxC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,kDAAkD;IAClD,WAAW,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAIlE,0DAA0D;IAC1D,aAAa,IAAI,IAAI;CAKtB"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * In-memory LRU cache tier.
3
+ *
4
+ * Wraps `lru-cache` with byte-aware eviction. TTL is enforced manually via
5
+ * storedAt + ttlMs fields rather than lru-cache's built-in TTL, so that
6
+ * tests using vi.useFakeTimers() work correctly (lru-cache's internal TTL
7
+ * uses the real clock bypassing the fake timer).
8
+ *
9
+ * @module cache/lru
10
+ */
11
+ import { LRUCache } from 'lru-cache';
12
+ /** Estimate the serialised byte size of a value. */
13
+ function estimateBytes(value) {
14
+ try {
15
+ return Buffer.byteLength(JSON.stringify(value) ?? 'null', 'utf8');
16
+ }
17
+ catch {
18
+ return 0;
19
+ }
20
+ }
21
+ export class MemoryLru {
22
+ cache;
23
+ evictions = 0;
24
+ hits = 0;
25
+ misses = 0;
26
+ constructor(options = {}) {
27
+ const maxSize = options.maxMemoryBytes ?? 100 * 1024 * 1024; // 100 MB
28
+ this.cache = new LRUCache({
29
+ maxSize,
30
+ sizeCalculation: (entry) => {
31
+ return Math.max(1, estimateBytes(entry.value));
32
+ },
33
+ allowStale: false,
34
+ updateAgeOnGet: true,
35
+ dispose: () => {
36
+ this.evictions++;
37
+ },
38
+ });
39
+ }
40
+ /**
41
+ * Retrieve an entry. Returns null on miss or TTL expiry.
42
+ */
43
+ get(key) {
44
+ const entry = this.cache.get(key);
45
+ if (!entry) {
46
+ this.misses++;
47
+ return null;
48
+ }
49
+ // Manual TTL check so fake timers work in tests
50
+ const now = Date.now();
51
+ if (entry.ttlMs > 0 && now - entry.storedAt > entry.ttlMs) {
52
+ this.cache.delete(key);
53
+ this.misses++;
54
+ return null;
55
+ }
56
+ this.hits++;
57
+ return {
58
+ value: entry.value,
59
+ storedAt: entry.storedAt,
60
+ source: 'memory',
61
+ staleness: now - entry.storedAt,
62
+ };
63
+ }
64
+ /**
65
+ * Store a value. ttlMs of 0 means store without TTL expiry.
66
+ */
67
+ set(key, value, ttlMs) {
68
+ const entry = { value, storedAt: Date.now(), ttlMs };
69
+ this.cache.set(key, entry);
70
+ }
71
+ /** Delete a single key. Returns true if the key existed. */
72
+ delete(key) {
73
+ return this.cache.delete(key);
74
+ }
75
+ /**
76
+ * Delete all keys matching a prefix.
77
+ * Returns the count of deleted entries.
78
+ */
79
+ invalidateByPrefix(prefix) {
80
+ let count = 0;
81
+ for (const key of this.cache.keys()) {
82
+ if (key.startsWith(prefix)) {
83
+ this.cache.delete(key);
84
+ count++;
85
+ }
86
+ }
87
+ return count;
88
+ }
89
+ /** Remove all entries. */
90
+ clear() {
91
+ this.cache.clear();
92
+ }
93
+ /** Current total byte estimate across all entries. */
94
+ get bytesUsed() {
95
+ return this.cache.calculatedSize ?? 0;
96
+ }
97
+ /** Number of entries currently held. */
98
+ get size() {
99
+ return this.cache.size;
100
+ }
101
+ /** Expose counters for CacheStats aggregation. */
102
+ getCounters() {
103
+ return { hits: this.hits, misses: this.misses, evictions: this.evictions };
104
+ }
105
+ /** Reset hit/miss/eviction counters (useful in tests). */
106
+ resetCounters() {
107
+ this.hits = 0;
108
+ this.misses = 0;
109
+ this.evictions = 0;
110
+ }
111
+ }
112
+ //# sourceMappingURL=lru.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lru.js","sourceRoot":"","sources":["../../src/cache/lru.ts"],"names":[],"mappings":"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"}