@nitrostack/core 1.0.16 → 1.1.0-beta.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.
Files changed (211) hide show
  1. package/dist/core/app-decorator.d.ts +5 -0
  2. package/dist/core/app-decorator.d.ts.map +1 -1
  3. package/dist/core/app-decorator.js +2 -1
  4. package/dist/core/app-decorator.js.map +1 -1
  5. package/dist/core/builders.d.ts.map +1 -1
  6. package/dist/core/builders.js +2 -0
  7. package/dist/core/builders.js.map +1 -1
  8. package/dist/core/decorators.d.ts +11 -0
  9. package/dist/core/decorators.d.ts.map +1 -1
  10. package/dist/core/decorators.js.map +1 -1
  11. package/dist/core/health/health-checks.resource.d.ts +4 -3
  12. package/dist/core/health/health-checks.resource.d.ts.map +1 -1
  13. package/dist/core/health/health-checks.resource.js +35 -8
  14. package/dist/core/health/health-checks.resource.js.map +1 -1
  15. package/dist/core/health/health.interface.d.ts +40 -0
  16. package/dist/core/health/health.interface.d.ts.map +1 -0
  17. package/dist/core/health/health.interface.js +2 -0
  18. package/dist/core/health/health.interface.js.map +1 -0
  19. package/dist/core/index.d.ts +11 -2
  20. package/dist/core/index.d.ts.map +1 -1
  21. package/dist/core/index.js +9 -1
  22. package/dist/core/index.js.map +1 -1
  23. package/dist/core/interceptors/data-spillover.interceptor.d.ts +30 -0
  24. package/dist/core/interceptors/data-spillover.interceptor.d.ts.map +1 -0
  25. package/dist/core/interceptors/data-spillover.interceptor.js +174 -0
  26. package/dist/core/interceptors/data-spillover.interceptor.js.map +1 -0
  27. package/dist/core/interceptors/interceptor.decorator.d.ts +17 -8
  28. package/dist/core/interceptors/interceptor.decorator.d.ts.map +1 -1
  29. package/dist/core/interceptors/interceptor.decorator.js +36 -11
  30. package/dist/core/interceptors/interceptor.decorator.js.map +1 -1
  31. package/dist/core/interceptors/interceptor.interface.d.ts +4 -0
  32. package/dist/core/interceptors/interceptor.interface.d.ts.map +1 -1
  33. package/dist/core/interceptors/spillover/fs-spillover.store.d.ts +54 -0
  34. package/dist/core/interceptors/spillover/fs-spillover.store.d.ts.map +1 -0
  35. package/dist/core/interceptors/spillover/fs-spillover.store.js +302 -0
  36. package/dist/core/interceptors/spillover/fs-spillover.store.js.map +1 -0
  37. package/dist/core/interceptors/spillover/index.d.ts +6 -0
  38. package/dist/core/interceptors/spillover/index.d.ts.map +1 -0
  39. package/dist/core/interceptors/spillover/index.js +6 -0
  40. package/dist/core/interceptors/spillover/index.js.map +1 -0
  41. package/dist/core/interceptors/spillover/memory-spillover.store.d.ts +25 -0
  42. package/dist/core/interceptors/spillover/memory-spillover.store.d.ts.map +1 -0
  43. package/dist/core/interceptors/spillover/memory-spillover.store.js +115 -0
  44. package/dist/core/interceptors/spillover/memory-spillover.store.js.map +1 -0
  45. package/dist/core/interceptors/spillover/preview-generator.d.ts +7 -0
  46. package/dist/core/interceptors/spillover/preview-generator.d.ts.map +1 -0
  47. package/dist/core/interceptors/spillover/preview-generator.js +79 -0
  48. package/dist/core/interceptors/spillover/preview-generator.js.map +1 -0
  49. package/dist/core/interceptors/spillover/spillover-store.interface.d.ts +20 -0
  50. package/dist/core/interceptors/spillover/spillover-store.interface.d.ts.map +1 -0
  51. package/dist/core/interceptors/spillover/spillover-store.interface.js +2 -0
  52. package/dist/core/interceptors/spillover/spillover-store.interface.js.map +1 -0
  53. package/dist/core/interceptors/spillover/types.d.ts +71 -0
  54. package/dist/core/interceptors/spillover/types.d.ts.map +1 -0
  55. package/dist/core/interceptors/spillover/types.js +12 -0
  56. package/dist/core/interceptors/spillover/types.js.map +1 -0
  57. package/dist/core/protocol/adapter.d.ts +7 -1
  58. package/dist/core/protocol/adapter.d.ts.map +1 -1
  59. package/dist/core/protocol/modern-v2.adapter.d.ts +95 -2
  60. package/dist/core/protocol/modern-v2.adapter.d.ts.map +1 -1
  61. package/dist/core/protocol/modern-v2.adapter.js +688 -157
  62. package/dist/core/protocol/modern-v2.adapter.js.map +1 -1
  63. package/dist/core/server.d.ts +104 -4
  64. package/dist/core/server.d.ts.map +1 -1
  65. package/dist/core/server.js +450 -44
  66. package/dist/core/server.js.map +1 -1
  67. package/dist/core/task.d.ts.map +1 -1
  68. package/dist/core/task.js +8 -7
  69. package/dist/core/task.js.map +1 -1
  70. package/dist/core/tool.d.ts +12 -3
  71. package/dist/core/tool.d.ts.map +1 -1
  72. package/dist/core/tool.js +21 -3
  73. package/dist/core/tool.js.map +1 -1
  74. package/dist/core/transforms/catalog.transform.d.ts +40 -0
  75. package/dist/core/transforms/catalog.transform.d.ts.map +1 -0
  76. package/dist/core/transforms/catalog.transform.js +52 -0
  77. package/dist/core/transforms/catalog.transform.js.map +1 -0
  78. package/dist/core/transforms/code-mode/code-mode.transform.d.ts +75 -0
  79. package/dist/core/transforms/code-mode/code-mode.transform.d.ts.map +1 -0
  80. package/dist/core/transforms/code-mode/code-mode.transform.js +226 -0
  81. package/dist/core/transforms/code-mode/code-mode.transform.js.map +1 -0
  82. package/dist/core/transforms/code-mode/destructive-guard.d.ts +7 -0
  83. package/dist/core/transforms/code-mode/destructive-guard.d.ts.map +1 -0
  84. package/dist/core/transforms/code-mode/destructive-guard.js +18 -0
  85. package/dist/core/transforms/code-mode/destructive-guard.js.map +1 -0
  86. package/dist/core/transforms/code-mode/guest-evaluator.d.ts +17 -0
  87. package/dist/core/transforms/code-mode/guest-evaluator.d.ts.map +1 -0
  88. package/dist/core/transforms/code-mode/guest-evaluator.js +277 -0
  89. package/dist/core/transforms/code-mode/guest-evaluator.js.map +1 -0
  90. package/dist/core/transforms/code-mode/index.d.ts +11 -0
  91. package/dist/core/transforms/code-mode/index.d.ts.map +1 -0
  92. package/dist/core/transforms/code-mode/index.js +11 -0
  93. package/dist/core/transforms/code-mode/index.js.map +1 -0
  94. package/dist/core/transforms/code-mode/ipc-messages.d.ts +31 -0
  95. package/dist/core/transforms/code-mode/ipc-messages.d.ts.map +1 -0
  96. package/dist/core/transforms/code-mode/ipc-messages.js +2 -0
  97. package/dist/core/transforms/code-mode/ipc-messages.js.map +1 -0
  98. package/dist/core/transforms/code-mode/legible-error.d.ts +8 -0
  99. package/dist/core/transforms/code-mode/legible-error.d.ts.map +1 -0
  100. package/dist/core/transforms/code-mode/legible-error.js +17 -0
  101. package/dist/core/transforms/code-mode/legible-error.js.map +1 -0
  102. package/dist/core/transforms/code-mode/quickjs-wasm.provider.d.ts +25 -0
  103. package/dist/core/transforms/code-mode/quickjs-wasm.provider.d.ts.map +1 -0
  104. package/dist/core/transforms/code-mode/quickjs-wasm.provider.js +31 -0
  105. package/dist/core/transforms/code-mode/quickjs-wasm.provider.js.map +1 -0
  106. package/dist/core/transforms/code-mode/sandbox.interface.d.ts +10 -0
  107. package/dist/core/transforms/code-mode/sandbox.interface.d.ts.map +1 -0
  108. package/dist/core/transforms/code-mode/sandbox.interface.js +2 -0
  109. package/dist/core/transforms/code-mode/sandbox.interface.js.map +1 -0
  110. package/dist/core/transforms/code-mode/sandbox.worker.d.ts +2 -0
  111. package/dist/core/transforms/code-mode/sandbox.worker.d.ts.map +1 -0
  112. package/dist/core/transforms/code-mode/sandbox.worker.js +69 -0
  113. package/dist/core/transforms/code-mode/sandbox.worker.js.map +1 -0
  114. package/dist/core/transforms/code-mode/synthetic-tools.d.ts +23 -0
  115. package/dist/core/transforms/code-mode/synthetic-tools.d.ts.map +1 -0
  116. package/dist/core/transforms/code-mode/synthetic-tools.js +112 -0
  117. package/dist/core/transforms/code-mode/synthetic-tools.js.map +1 -0
  118. package/dist/core/transforms/code-mode/types.d.ts +32 -0
  119. package/dist/core/transforms/code-mode/types.d.ts.map +1 -0
  120. package/dist/core/transforms/code-mode/types.js +2 -0
  121. package/dist/core/transforms/code-mode/types.js.map +1 -0
  122. package/dist/core/transforms/code-mode/worker-pool.d.ts +71 -0
  123. package/dist/core/transforms/code-mode/worker-pool.d.ts.map +1 -0
  124. package/dist/core/transforms/code-mode/worker-pool.js +435 -0
  125. package/dist/core/transforms/code-mode/worker-pool.js.map +1 -0
  126. package/dist/core/transforms/index.d.ts +6 -0
  127. package/dist/core/transforms/index.d.ts.map +1 -0
  128. package/dist/core/transforms/index.js +6 -0
  129. package/dist/core/transforms/index.js.map +1 -0
  130. package/dist/core/transforms/search/base-search.transform.d.ts +59 -0
  131. package/dist/core/transforms/search/base-search.transform.d.ts.map +1 -0
  132. package/dist/core/transforms/search/base-search.transform.js +166 -0
  133. package/dist/core/transforms/search/base-search.transform.js.map +1 -0
  134. package/dist/core/transforms/search/bm25-search.transform.d.ts +27 -0
  135. package/dist/core/transforms/search/bm25-search.transform.d.ts.map +1 -0
  136. package/dist/core/transforms/search/bm25-search.transform.js +37 -0
  137. package/dist/core/transforms/search/bm25-search.transform.js.map +1 -0
  138. package/dist/core/transforms/search/bm25.engine.d.ts +46 -0
  139. package/dist/core/transforms/search/bm25.engine.d.ts.map +1 -0
  140. package/dist/core/transforms/search/bm25.engine.js +160 -0
  141. package/dist/core/transforms/search/bm25.engine.js.map +1 -0
  142. package/dist/core/transforms/search/index.d.ts +9 -0
  143. package/dist/core/transforms/search/index.d.ts.map +1 -0
  144. package/dist/core/transforms/search/index.js +9 -0
  145. package/dist/core/transforms/search/index.js.map +1 -0
  146. package/dist/core/transforms/search/regex-match.worker.d.ts +2 -0
  147. package/dist/core/transforms/search/regex-match.worker.d.ts.map +1 -0
  148. package/dist/core/transforms/search/regex-match.worker.js +19 -0
  149. package/dist/core/transforms/search/regex-match.worker.js.map +1 -0
  150. package/dist/core/transforms/search/regex-search.transform.d.ts +41 -0
  151. package/dist/core/transforms/search/regex-search.transform.d.ts.map +1 -0
  152. package/dist/core/transforms/search/regex-search.transform.js +237 -0
  153. package/dist/core/transforms/search/regex-search.transform.js.map +1 -0
  154. package/dist/core/transforms/search/synthetic-tools.d.ts +11 -0
  155. package/dist/core/transforms/search/synthetic-tools.d.ts.map +1 -0
  156. package/dist/core/transforms/search/synthetic-tools.js +76 -0
  157. package/dist/core/transforms/search/synthetic-tools.js.map +1 -0
  158. package/dist/core/transforms/search/tokenizer.d.ts +11 -0
  159. package/dist/core/transforms/search/tokenizer.d.ts.map +1 -0
  160. package/dist/core/transforms/search/tokenizer.js +38 -0
  161. package/dist/core/transforms/search/tokenizer.js.map +1 -0
  162. package/dist/core/transforms/search/tool-serializer.d.ts +6 -0
  163. package/dist/core/transforms/search/tool-serializer.d.ts.map +1 -0
  164. package/dist/core/transforms/search/tool-serializer.js +41 -0
  165. package/dist/core/transforms/search/tool-serializer.js.map +1 -0
  166. package/dist/core/transforms/search/types.d.ts +36 -0
  167. package/dist/core/transforms/search/types.d.ts.map +1 -0
  168. package/dist/core/transforms/search/types.js +2 -0
  169. package/dist/core/transforms/search/types.js.map +1 -0
  170. package/dist/core/transforms/tool-cache-key.d.ts +15 -0
  171. package/dist/core/transforms/tool-cache-key.d.ts.map +1 -0
  172. package/dist/core/transforms/tool-cache-key.js +61 -0
  173. package/dist/core/transforms/tool-cache-key.js.map +1 -0
  174. package/dist/core/transforms/transform.interface.d.ts +34 -0
  175. package/dist/core/transforms/transform.interface.d.ts.map +1 -0
  176. package/dist/core/transforms/transform.interface.js +2 -0
  177. package/dist/core/transforms/transform.interface.js.map +1 -0
  178. package/dist/core/transforms/validate-tool-arguments.d.ts +10 -0
  179. package/dist/core/transforms/validate-tool-arguments.d.ts.map +1 -0
  180. package/dist/core/transforms/validate-tool-arguments.js +62 -0
  181. package/dist/core/transforms/validate-tool-arguments.js.map +1 -0
  182. package/dist/core/transforms/visibility/index.d.ts +3 -0
  183. package/dist/core/transforms/visibility/index.d.ts.map +1 -0
  184. package/dist/core/transforms/visibility/index.js +3 -0
  185. package/dist/core/transforms/visibility/index.js.map +1 -0
  186. package/dist/core/transforms/visibility/session-store.d.ts +132 -0
  187. package/dist/core/transforms/visibility/session-store.d.ts.map +1 -0
  188. package/dist/core/transforms/visibility/session-store.js +330 -0
  189. package/dist/core/transforms/visibility/session-store.js.map +1 -0
  190. package/dist/core/transforms/visibility/visibility.transform.d.ts +42 -0
  191. package/dist/core/transforms/visibility/visibility.transform.d.ts.map +1 -0
  192. package/dist/core/transforms/visibility/visibility.transform.js +109 -0
  193. package/dist/core/transforms/visibility/visibility.transform.js.map +1 -0
  194. package/dist/core/types.d.ts +60 -0
  195. package/dist/core/types.d.ts.map +1 -1
  196. package/dist/testing/index.d.ts.map +1 -1
  197. package/dist/testing/index.js +3 -0
  198. package/dist/testing/index.js.map +1 -1
  199. package/package.json +9 -6
  200. package/dist/core/widget-bundle-paths.d.ts +0 -5
  201. package/dist/core/widget-bundle-paths.d.ts.map +0 -1
  202. package/dist/core/widget-bundle-paths.js +0 -25
  203. package/dist/core/widget-bundle-paths.js.map +0 -1
  204. package/dist/core/widget-html-mime.d.ts +0 -7
  205. package/dist/core/widget-html-mime.d.ts.map +0 -1
  206. package/dist/core/widget-html-mime.js +0 -7
  207. package/dist/core/widget-html-mime.js.map +0 -1
  208. package/dist/core/widget-mime.d.ts +0 -29
  209. package/dist/core/widget-mime.d.ts.map +0 -1
  210. package/dist/core/widget-mime.js +0 -41
  211. package/dist/core/widget-mime.js.map +0 -1
@@ -0,0 +1,302 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ /** Grace period before a leftover temp file is treated as abandoned. */
5
+ const ORPHAN_TEMP_FILE_MAX_AGE_MS = 5 * 60 * 1000;
6
+ /**
7
+ * Filesystem spillover store.
8
+ *
9
+ * Directory mode 0o700 and file mode 0o600 are enforced on Unix. Windows ignores
10
+ * those bits, so a shared temp directory is not private there; set `storageDir`
11
+ * to a directory only this process can read.
12
+ */
13
+ export class FsSpilloverStore {
14
+ storageDir;
15
+ explicitDir;
16
+ maxSizeBytes;
17
+ sweepTimer;
18
+ initialized = false;
19
+ usageReady = false;
20
+ currentSizeBytes = 0;
21
+ /** Serializes saves so two writers cannot both pass the capacity check. */
22
+ writeChain = Promise.resolve();
23
+ constructor(options = {}) {
24
+ this.explicitDir = options.storageDir !== undefined;
25
+ // A fixed name under os.tmpdir() can be planted as a symlink before startup.
26
+ // The default path is created with mkdtemp on first write.
27
+ this.storageDir = options.storageDir ?? '';
28
+ this.maxSizeBytes = options.maxSizeBytes ?? 512 * 1024 * 1024;
29
+ const sweepIntervalMs = (options.sweepIntervalSeconds ?? 120) * 1000;
30
+ this.sweepTimer = setInterval(() => {
31
+ void this.cleanup().catch(() => { });
32
+ }, sweepIntervalMs);
33
+ if (typeof this.sweepTimer.unref === 'function') {
34
+ this.sweepTimer.unref();
35
+ }
36
+ }
37
+ async ensureDir() {
38
+ if (this.initialized)
39
+ return;
40
+ if (!this.explicitDir) {
41
+ this.storageDir = await fs.mkdtemp(path.join(os.tmpdir(), 'nitrostack-spillover-'));
42
+ this.initialized = true;
43
+ return;
44
+ }
45
+ await this.assertRealDirectory(this.storageDir);
46
+ this.initialized = true;
47
+ }
48
+ /**
49
+ * Refuse a symlink. mkdir({ recursive: true }) follows one, and chmod follows
50
+ * it too, so a planted link would receive the spilled files.
51
+ */
52
+ async assertRealDirectory(dir) {
53
+ let stat;
54
+ try {
55
+ stat = await fs.lstat(dir);
56
+ }
57
+ catch (err) {
58
+ const code = err.code;
59
+ if (code !== 'ENOENT')
60
+ throw err;
61
+ await fs.mkdir(dir, { recursive: true, mode: 0o700 });
62
+ stat = await fs.lstat(dir);
63
+ }
64
+ if (stat.isSymbolicLink()) {
65
+ throw new Error(`Spillover directory ${dir} is a symlink. Refusing to write tool output.`);
66
+ }
67
+ if (!stat.isDirectory()) {
68
+ throw new Error(`Spillover directory ${dir} is not a directory.`);
69
+ }
70
+ try {
71
+ await fs.chmod(dir, 0o700);
72
+ }
73
+ catch (err) {
74
+ const message = err instanceof Error ? err.message : String(err);
75
+ throw new Error(`Spillover directory ${dir} is not private (${message}). Refusing to write tool output.`);
76
+ }
77
+ }
78
+ sanitizeId(id) {
79
+ // Defend against directory traversal attacks (e.g. ../../)
80
+ const sanitized = id.replace(/[^a-zA-Z0-9_-]/g, '_');
81
+ return sanitized.length > 0 ? sanitized : 'spillover_id';
82
+ }
83
+ getFilePath(id) {
84
+ return path.join(this.storageDir, `${this.sanitizeId(id)}.json`);
85
+ }
86
+ getStorageDir() {
87
+ return this.storageDir;
88
+ }
89
+ getMaxSizeBytes() {
90
+ return this.maxSizeBytes;
91
+ }
92
+ getCurrentSizeBytes() {
93
+ return this.currentSizeBytes;
94
+ }
95
+ enqueue(fn) {
96
+ const run = this.writeChain.then(fn);
97
+ this.writeChain = run.then(() => undefined, () => undefined);
98
+ return run;
99
+ }
100
+ async save(id, data, mimeType, ttlSeconds, sessionId) {
101
+ return this.enqueue(() => this.writeRecord(id, data, mimeType, ttlSeconds, sessionId));
102
+ }
103
+ async writeRecord(id, data, mimeType, ttlSeconds, sessionId) {
104
+ await this.ensureDir();
105
+ await this.ensureUsage();
106
+ const sizeBytes = Buffer.byteLength(data, 'utf8');
107
+ if (sizeBytes > this.maxSizeBytes) {
108
+ throw new Error(`Spillover payload of ${sizeBytes} bytes exceeds the store limit of ${this.maxSizeBytes} bytes.`);
109
+ }
110
+ const filePath = this.getFilePath(id);
111
+ const existingBytes = await this.fileSize(filePath);
112
+ if (existingBytes > 0)
113
+ this.currentSizeBytes -= existingBytes;
114
+ try {
115
+ while (this.currentSizeBytes + sizeBytes > this.maxSizeBytes) {
116
+ const evicted = await this.evictOldestFile(filePath);
117
+ if (!evicted)
118
+ break;
119
+ }
120
+ if (this.currentSizeBytes + sizeBytes > this.maxSizeBytes) {
121
+ throw new Error(`Spillover store is at capacity (${this.maxSizeBytes} bytes). ` +
122
+ `Raise maxSizeBytes or remove expired payloads.`);
123
+ }
124
+ }
125
+ catch (err) {
126
+ this.currentSizeBytes += existingBytes;
127
+ throw err;
128
+ }
129
+ const now = Date.now();
130
+ const record = {
131
+ // expiresAt is first so cleanup can read it from the file prefix
132
+ // without loading the spilled payload.
133
+ expiresAt: now + ttlSeconds * 1000,
134
+ id,
135
+ mimeType,
136
+ sizeBytes,
137
+ createdAt: now,
138
+ sessionId,
139
+ data,
140
+ };
141
+ const tempPath = `${filePath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
142
+ try {
143
+ await fs.writeFile(tempPath, JSON.stringify(record), { encoding: 'utf8', mode: 0o600 });
144
+ await fs.rename(tempPath, filePath);
145
+ }
146
+ catch (err) {
147
+ this.currentSizeBytes += existingBytes;
148
+ await fs.unlink(tempPath).catch(() => undefined);
149
+ throw err;
150
+ }
151
+ this.currentSizeBytes += await this.fileSize(filePath);
152
+ return record;
153
+ }
154
+ async get(id) {
155
+ await this.ensureDir();
156
+ const filePath = this.getFilePath(id);
157
+ try {
158
+ const content = await fs.readFile(filePath, 'utf8');
159
+ const record = JSON.parse(content);
160
+ if (Date.now() > record.expiresAt) {
161
+ await this.enqueue(() => this.deleteIfStillExpired(id));
162
+ return undefined;
163
+ }
164
+ return record;
165
+ }
166
+ catch {
167
+ return undefined;
168
+ }
169
+ }
170
+ async delete(id) {
171
+ return this.enqueue(() => this.unlinkId(id));
172
+ }
173
+ async unlinkId(id) {
174
+ const filePath = this.getFilePath(id);
175
+ const size = await this.fileSize(filePath);
176
+ try {
177
+ await fs.unlink(filePath);
178
+ if (this.usageReady)
179
+ this.currentSizeBytes = Math.max(0, this.currentSizeBytes - size);
180
+ return true;
181
+ }
182
+ catch {
183
+ return false;
184
+ }
185
+ }
186
+ async deleteIfStillExpired(id) {
187
+ const filePath = this.getFilePath(id);
188
+ const expiresAt = await this.readExpiresAt(filePath);
189
+ if (expiresAt !== undefined && Date.now() <= expiresAt)
190
+ return;
191
+ await this.unlinkId(id);
192
+ }
193
+ async cleanup() {
194
+ return this.enqueue(() => this.cleanupNow());
195
+ }
196
+ async cleanupNow() {
197
+ await this.ensureDir();
198
+ let pruned = 0;
199
+ const now = Date.now();
200
+ try {
201
+ const files = await fs.readdir(this.storageDir);
202
+ for (const file of files) {
203
+ const filePath = path.join(this.storageDir, file);
204
+ // Sweep leftovers from writes interrupted between writeFile and rename;
205
+ // these never carry the plain `.json` suffix and would otherwise accumulate.
206
+ if (file.includes('.json.tmp.')) {
207
+ const stat = await fs.stat(filePath).catch(() => undefined);
208
+ if (stat && now - stat.mtimeMs > ORPHAN_TEMP_FILE_MAX_AGE_MS) {
209
+ await fs.unlink(filePath).catch(() => { });
210
+ if (this.usageReady)
211
+ this.currentSizeBytes = Math.max(0, this.currentSizeBytes - stat.size);
212
+ pruned++;
213
+ }
214
+ continue;
215
+ }
216
+ if (!file.endsWith('.json'))
217
+ continue;
218
+ try {
219
+ const expiresAt = await this.readExpiresAt(filePath);
220
+ if (expiresAt === undefined || now > expiresAt) {
221
+ const size = await this.fileSize(filePath);
222
+ await fs.unlink(filePath);
223
+ if (this.usageReady)
224
+ this.currentSizeBytes = Math.max(0, this.currentSizeBytes - size);
225
+ pruned++;
226
+ }
227
+ }
228
+ catch {
229
+ // Bad/partial file, remove
230
+ const size = await this.fileSize(filePath);
231
+ await fs.unlink(filePath).catch(() => { });
232
+ if (this.usageReady)
233
+ this.currentSizeBytes = Math.max(0, this.currentSizeBytes - size);
234
+ }
235
+ }
236
+ }
237
+ catch {
238
+ /* ignore read errors during cleanup */
239
+ }
240
+ return pruned;
241
+ }
242
+ async ensureUsage() {
243
+ if (this.usageReady)
244
+ return;
245
+ let total = 0;
246
+ const files = await fs.readdir(this.storageDir).catch(() => []);
247
+ for (const file of files) {
248
+ if (!file.endsWith('.json') || file.includes('.json.tmp.'))
249
+ continue;
250
+ total += await this.fileSize(path.join(this.storageDir, file));
251
+ }
252
+ this.currentSizeBytes = total;
253
+ this.usageReady = true;
254
+ }
255
+ async fileSize(filePath) {
256
+ const stat = await fs.stat(filePath).catch(() => undefined);
257
+ return stat?.size ?? 0;
258
+ }
259
+ /** Deletes the oldest payload file, excluding the path about to be replaced. */
260
+ async evictOldestFile(skipPath) {
261
+ const files = await fs.readdir(this.storageDir).catch(() => []);
262
+ let oldest;
263
+ for (const file of files) {
264
+ if (!file.endsWith('.json') || file.includes('.json.tmp.'))
265
+ continue;
266
+ const filePath = path.join(this.storageDir, file);
267
+ if (skipPath && filePath === skipPath)
268
+ continue;
269
+ const stat = await fs.stat(filePath).catch(() => undefined);
270
+ if (!stat)
271
+ continue;
272
+ if (!oldest || stat.mtimeMs < oldest.mtimeMs) {
273
+ oldest = { filePath, mtimeMs: stat.mtimeMs, size: stat.size };
274
+ }
275
+ }
276
+ if (!oldest)
277
+ return false;
278
+ await fs.unlink(oldest.filePath).catch(() => undefined);
279
+ this.currentSizeBytes = Math.max(0, this.currentSizeBytes - oldest.size);
280
+ return true;
281
+ }
282
+ /** First bytes of a record. `expiresAt` is written before the payload. */
283
+ async readExpiresAt(filePath) {
284
+ const fh = await fs.open(filePath, 'r');
285
+ try {
286
+ const buf = Buffer.alloc(96);
287
+ const { bytesRead } = await fh.read(buf, 0, buf.length, 0);
288
+ const head = buf.subarray(0, bytesRead).toString('utf8');
289
+ const match = head.match(/"expiresAt"\s*:\s*(\d+)/);
290
+ if (!match?.[1])
291
+ return undefined;
292
+ return Number(match[1]);
293
+ }
294
+ finally {
295
+ await fh.close();
296
+ }
297
+ }
298
+ async dispose() {
299
+ clearInterval(this.sweepTimer);
300
+ }
301
+ }
302
+ //# sourceMappingURL=fs-spillover.store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-spillover.store.js","sourceRoot":"","sources":["../../../../src/core/interceptors/spillover/fs-spillover.store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export * from './spillover-store.interface.js';
2
+ export * from './memory-spillover.store.js';
3
+ export * from './fs-spillover.store.js';
4
+ export * from './types.js';
5
+ export * from './preview-generator.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/interceptors/spillover/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from './spillover-store.interface.js';
2
+ export * from './memory-spillover.store.js';
3
+ export * from './fs-spillover.store.js';
4
+ export * from './types.js';
5
+ export * from './preview-generator.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/interceptors/spillover/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { SpilloverRecord, SpilloverStore } from './spillover-store.interface.js';
2
+ export interface MemorySpilloverOptions {
3
+ maxSizeBytes?: number;
4
+ sweepIntervalSeconds?: number;
5
+ }
6
+ export declare class MemorySpilloverStore implements SpilloverStore {
7
+ private readonly records;
8
+ private currentSizeBytes;
9
+ private readonly maxSizeBytes;
10
+ private readonly sweepTimer;
11
+ /** Serializes saves so two writers cannot both pass the capacity check. */
12
+ private writeChain;
13
+ constructor(options?: MemorySpilloverOptions);
14
+ save(id: string, data: string, mimeType: string, ttlSeconds: number, sessionId?: string): Promise<SpilloverRecord>;
15
+ private writeRecord;
16
+ get(id: string): Promise<SpilloverRecord | undefined>;
17
+ delete(id: string): Promise<boolean>;
18
+ cleanup(): Promise<number>;
19
+ private evictOldest;
20
+ getMaxSizeBytes(): number;
21
+ getCurrentSizeBytes(): number;
22
+ getRecordCount(): number;
23
+ dispose(): Promise<void>;
24
+ }
25
+ //# sourceMappingURL=memory-spillover.store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-spillover.store.d.ts","sourceRoot":"","sources":["../../../../src/core/interceptors/spillover/memory-spillover.store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAEjF,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,oBAAqB,YAAW,cAAc;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;IAC9D,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;IAC5C,2EAA2E;IAC3E,OAAO,CAAC,UAAU,CAAoC;gBAE1C,OAAO,GAAE,sBAA2B;IAa1C,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;YAS1G,WAAW;IAiDnB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAerD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQpC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAahC,OAAO,CAAC,WAAW;IAWnB,eAAe,IAAI,MAAM;IAIzB,mBAAmB,IAAI,MAAM;IAI7B,cAAc,IAAI,MAAM;IAIlB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAK/B"}
@@ -0,0 +1,115 @@
1
+ export class MemorySpilloverStore {
2
+ records = new Map();
3
+ currentSizeBytes = 0;
4
+ maxSizeBytes;
5
+ sweepTimer;
6
+ /** Serializes saves so two writers cannot both pass the capacity check. */
7
+ writeChain = Promise.resolve();
8
+ constructor(options = {}) {
9
+ this.maxSizeBytes = options.maxSizeBytes ?? 100 * 1024 * 1024;
10
+ const sweepIntervalMs = (options.sweepIntervalSeconds ?? 60) * 1000;
11
+ this.sweepTimer = setInterval(() => {
12
+ this.cleanup().catch(() => { });
13
+ }, sweepIntervalMs);
14
+ if (typeof this.sweepTimer.unref === 'function') {
15
+ this.sweepTimer.unref();
16
+ }
17
+ }
18
+ async save(id, data, mimeType, ttlSeconds, sessionId) {
19
+ const run = this.writeChain.then(() => this.writeRecord(id, data, mimeType, ttlSeconds, sessionId));
20
+ this.writeChain = run.then(() => undefined, () => undefined);
21
+ return run;
22
+ }
23
+ async writeRecord(id, data, mimeType, ttlSeconds, sessionId) {
24
+ // Yield so a second save started in the same turn waits on writeChain
25
+ // instead of reading currentSizeBytes before this insert lands.
26
+ await Promise.resolve();
27
+ const sizeBytes = Buffer.byteLength(data, 'utf8');
28
+ const now = Date.now();
29
+ // Reject before evicting: a record larger than the cap would otherwise clear the
30
+ // entire store and still be admitted, leaving usage above the configured limit.
31
+ if (sizeBytes > this.maxSizeBytes) {
32
+ throw new Error(`Spillover payload of ${sizeBytes} bytes exceeds the store limit of ${this.maxSizeBytes} bytes. ` +
33
+ `Raise maxSizeBytes or use the filesystem spillover driver.`);
34
+ }
35
+ // If updating an existing id, subtract prior size first
36
+ const existing = this.records.get(id);
37
+ if (existing) {
38
+ this.currentSizeBytes -= existing.sizeBytes;
39
+ this.records.delete(id);
40
+ }
41
+ // Evict oldest if adding this record exceeds max memory capacity
42
+ while (this.currentSizeBytes + sizeBytes > this.maxSizeBytes && this.records.size > 0) {
43
+ this.evictOldest();
44
+ }
45
+ const record = {
46
+ expiresAt: now + ttlSeconds * 1000,
47
+ id,
48
+ mimeType,
49
+ sizeBytes,
50
+ createdAt: now,
51
+ sessionId,
52
+ data,
53
+ };
54
+ this.records.set(id, record);
55
+ this.currentSizeBytes += sizeBytes;
56
+ return record;
57
+ }
58
+ async get(id) {
59
+ const record = this.records.get(id);
60
+ if (!record)
61
+ return undefined;
62
+ if (Date.now() > record.expiresAt) {
63
+ await this.delete(id);
64
+ return undefined;
65
+ }
66
+ // Refresh Map insertion order for LRU
67
+ this.records.delete(id);
68
+ this.records.set(id, record);
69
+ return record;
70
+ }
71
+ async delete(id) {
72
+ const record = this.records.get(id);
73
+ if (!record)
74
+ return false;
75
+ this.currentSizeBytes -= record.sizeBytes;
76
+ return this.records.delete(id);
77
+ }
78
+ async cleanup() {
79
+ const now = Date.now();
80
+ let pruned = 0;
81
+ for (const [id, record] of this.records.entries()) {
82
+ if (now > record.expiresAt) {
83
+ this.currentSizeBytes -= record.sizeBytes;
84
+ this.records.delete(id);
85
+ pruned++;
86
+ }
87
+ }
88
+ return pruned;
89
+ }
90
+ evictOldest() {
91
+ const oldestKey = this.records.keys().next().value;
92
+ if (oldestKey !== undefined) {
93
+ const rec = this.records.get(oldestKey);
94
+ if (rec) {
95
+ this.currentSizeBytes -= rec.sizeBytes;
96
+ }
97
+ this.records.delete(oldestKey);
98
+ }
99
+ }
100
+ getMaxSizeBytes() {
101
+ return this.maxSizeBytes;
102
+ }
103
+ getCurrentSizeBytes() {
104
+ return this.currentSizeBytes;
105
+ }
106
+ getRecordCount() {
107
+ return this.records.size;
108
+ }
109
+ async dispose() {
110
+ clearInterval(this.sweepTimer);
111
+ this.records.clear();
112
+ this.currentSizeBytes = 0;
113
+ }
114
+ }
115
+ //# sourceMappingURL=memory-spillover.store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-spillover.store.js","sourceRoot":"","sources":["../../../../src/core/interceptors/spillover/memory-spillover.store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface PreviewResult {
2
+ preview: unknown;
3
+ summary: string;
4
+ totalItems?: number;
5
+ }
6
+ export declare function generatePreview(data: unknown, sizeBytes: number, previewItems?: number, previewChars?: number): PreviewResult;
7
+ //# sourceMappingURL=preview-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-generator.d.ts","sourceRoot":"","sources":["../../../../src/core/interceptors/spillover/preview-generator.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAiCD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,MAAM,EACjB,YAAY,SAAI,EAChB,YAAY,SAAM,GACjB,aAAa,CA6Cf"}
@@ -0,0 +1,79 @@
1
+ function capPreviewValue(value, previewChars) {
2
+ if (value == null || typeof value === 'number' || typeof value === 'boolean') {
3
+ return value;
4
+ }
5
+ if (typeof value === 'string') {
6
+ return value.length > previewChars ? `${value.slice(0, previewChars)}... [truncated]` : value;
7
+ }
8
+ let accounted = 0;
9
+ try {
10
+ const encoded = JSON.stringify(value, (_key, val) => {
11
+ if (typeof val === 'string')
12
+ accounted += val.length;
13
+ else if (val !== undefined)
14
+ accounted += 8;
15
+ if (accounted > previewChars) {
16
+ throw new Error('preview-cap');
17
+ }
18
+ return val;
19
+ });
20
+ if (encoded == null || encoded.length <= previewChars)
21
+ return value;
22
+ return `${encoded.slice(0, previewChars)}... [truncated]`;
23
+ }
24
+ catch (err) {
25
+ if (err instanceof Error && err.message === 'preview-cap')
26
+ return '[truncated]';
27
+ return '[unserializable]';
28
+ }
29
+ }
30
+ function formatBytes(bytes) {
31
+ if (bytes < 1024)
32
+ return `${bytes} B`;
33
+ if (bytes < 1024 * 1024)
34
+ return `${(bytes / 1024).toFixed(1)} KB`;
35
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
36
+ }
37
+ export function generatePreview(data, sizeBytes, previewItems = 3, previewChars = 500) {
38
+ const sizeStr = formatBytes(sizeBytes);
39
+ // 1. Array payload (most common for database queries)
40
+ if (Array.isArray(data)) {
41
+ const totalItems = data.length;
42
+ const preview = data.slice(0, previewItems).map((item) => capPreviewValue(item, previewChars));
43
+ return {
44
+ preview,
45
+ totalItems,
46
+ summary: `Query returned ${totalItems.toLocaleString()} items (${sizeStr})`,
47
+ };
48
+ }
49
+ // 2. String payload (CSV, raw text, HTML)
50
+ if (typeof data === 'string') {
51
+ const preview = data.length > previewChars
52
+ ? `${data.slice(0, previewChars)}... [truncated]`
53
+ : data;
54
+ return {
55
+ preview,
56
+ summary: `Text payload (${sizeStr})`,
57
+ };
58
+ }
59
+ // 3. Plain Object / Dictionary
60
+ if (data && typeof data === 'object') {
61
+ const keys = Object.keys(data);
62
+ const totalItems = keys.length;
63
+ const preview = {};
64
+ for (let i = 0; i < Math.min(keys.length, previewItems); i++) {
65
+ const key = keys[i];
66
+ preview[key] = capPreviewValue(data[key], previewChars);
67
+ }
68
+ return {
69
+ preview,
70
+ totalItems,
71
+ summary: `Object with ${totalItems} top-level fields (${sizeStr})`,
72
+ };
73
+ }
74
+ return {
75
+ preview: data,
76
+ summary: `Dataset payload (${sizeStr})`,
77
+ };
78
+ }
79
+ //# sourceMappingURL=preview-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-generator.js","sourceRoot":"","sources":["../../../../src/core/interceptors/spillover/preview-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface SpilloverRecord {
2
+ id: string;
3
+ data: string;
4
+ mimeType: string;
5
+ sizeBytes: number;
6
+ createdAt: number;
7
+ expiresAt: number;
8
+ /** Session that produced the payload. Absent for stateless writes. */
9
+ sessionId?: string;
10
+ }
11
+ export interface SpilloverStore {
12
+ save(id: string, data: string, mimeType: string, ttlSeconds: number, sessionId?: string): Promise<SpilloverRecord>;
13
+ get(id: string): Promise<SpilloverRecord | undefined>;
14
+ delete(id: string): Promise<boolean>;
15
+ cleanup(): Promise<number>;
16
+ dispose(): Promise<void>;
17
+ /** Byte cap for stored payloads. Absent on custom stores. */
18
+ getMaxSizeBytes?(): number;
19
+ }
20
+ //# sourceMappingURL=spillover-store.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spillover-store.interface.d.ts","sourceRoot":"","sources":["../../../../src/core/interceptors/spillover/spillover-store.interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACnH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC;IACtD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,6DAA6D;IAC7D,eAAe,CAAC,IAAI,MAAM,CAAC;CAC5B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=spillover-store.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spillover-store.interface.js","sourceRoot":"","sources":["../../../../src/core/interceptors/spillover/spillover-store.interface.ts"],"names":[],"mappings":""}