@j0hanz/superfetch 2.4.12 → 2.4.13
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/dist/cache.d.ts +0 -4
- package/dist/cache.js +0 -18
- package/dist/config.d.ts +1 -0
- package/dist/config.js +4 -3
- package/dist/markdown-cleanup.d.ts +0 -5
- package/dist/markdown-cleanup.js +0 -25
- package/dist/observability.d.ts +0 -2
- package/dist/observability.js +1 -11
- package/dist/tasks.d.ts +2 -2
- package/dist/tasks.js +1 -15
- package/dist/tools.d.ts +0 -1
- package/dist/tools.js +1 -1
- package/dist/transform.js +8 -1
- package/package.json +1 -1
package/dist/cache.d.ts
CHANGED
|
@@ -41,10 +41,6 @@ export declare function get(cacheKey: string | null): CacheEntry | undefined;
|
|
|
41
41
|
export declare function set(cacheKey: string | null, content: string, metadata: CacheEntryMetadata): void;
|
|
42
42
|
export declare function keys(): readonly string[];
|
|
43
43
|
export declare function isEnabled(): boolean;
|
|
44
|
-
export declare function getRecentCachedUrls(): {
|
|
45
|
-
url: string;
|
|
46
|
-
title?: string;
|
|
47
|
-
}[];
|
|
48
44
|
export declare function registerCachedContentResource(server: McpServer, serverIcons?: McpIcon[]): void;
|
|
49
45
|
export declare function generateSafeFilename(url: string, title?: string, hashFallback?: string, extension?: string): string;
|
|
50
46
|
export declare function handleDownload(res: ServerResponse, namespace: string, hash: string): void;
|
package/dist/cache.js
CHANGED
|
@@ -273,24 +273,6 @@ export function keys() {
|
|
|
273
273
|
export function isEnabled() {
|
|
274
274
|
return store.isEnabled();
|
|
275
275
|
}
|
|
276
|
-
export function getRecentCachedUrls() {
|
|
277
|
-
const cacheKeys = store.keys();
|
|
278
|
-
const maxResults = 20;
|
|
279
|
-
const results = [];
|
|
280
|
-
for (let i = 0; i < Math.min(cacheKeys.length, maxResults); i++) {
|
|
281
|
-
const key = cacheKeys[i];
|
|
282
|
-
if (!key)
|
|
283
|
-
continue;
|
|
284
|
-
const entry = store.get(key);
|
|
285
|
-
if (entry) {
|
|
286
|
-
results.push({
|
|
287
|
-
url: entry.url,
|
|
288
|
-
...(entry.title ? { title: entry.title } : {}),
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
return results;
|
|
293
|
-
}
|
|
294
276
|
/* -------------------------------------------------------------------------------------------------
|
|
295
277
|
* MCP cached content resource (superfetch://cache/markdown/{urlHash})
|
|
296
278
|
* ------------------------------------------------------------------------------------------------- */
|
package/dist/config.d.ts
CHANGED
package/dist/config.js
CHANGED
|
@@ -103,7 +103,7 @@ const SIZE_LIMITS = {
|
|
|
103
103
|
TEN_MB: 10 * 1024 * 1024,
|
|
104
104
|
};
|
|
105
105
|
const TIMEOUT = {
|
|
106
|
-
DEFAULT_FETCH_TIMEOUT_MS: 15000,
|
|
106
|
+
DEFAULT_FETCH_TIMEOUT_MS: parseInteger(process.env.FETCH_TIMEOUT_MS, 15000, 1000, 60000),
|
|
107
107
|
DEFAULT_SESSION_TTL_MS: 30 * 60 * 1000,
|
|
108
108
|
DEFAULT_TRANSFORM_TIMEOUT_MS: parseInteger(process.env.TRANSFORM_TIMEOUT_MS, 30000, 5000, 120000),
|
|
109
109
|
};
|
|
@@ -202,6 +202,7 @@ export const config = {
|
|
|
202
202
|
timeoutMs: TIMEOUT.DEFAULT_TRANSFORM_TIMEOUT_MS,
|
|
203
203
|
stageWarnRatio: parseFloat(process.env.TRANSFORM_STAGE_WARN_RATIO ?? '0.5'),
|
|
204
204
|
metadataFormat: parseTransformMetadataFormat(process.env.TRANSFORM_METADATA_FORMAT),
|
|
205
|
+
maxWorkerScale: parseInteger(process.env.TRANSFORM_WORKER_MAX_SCALE, 4, 1, 16),
|
|
205
206
|
},
|
|
206
207
|
tools: {
|
|
207
208
|
enabled: parseList(process.env.ENABLED_TOOLS ?? 'fetch-url'),
|
|
@@ -268,8 +269,8 @@ export const config = {
|
|
|
268
269
|
auth: buildAuthConfig(baseUrl),
|
|
269
270
|
rateLimit: {
|
|
270
271
|
enabled: true,
|
|
271
|
-
maxRequests: 100,
|
|
272
|
-
windowMs: 60000,
|
|
272
|
+
maxRequests: parseInteger(process.env.RATE_LIMIT_MAX, 100, 1, 10000),
|
|
273
|
+
windowMs: parseInteger(process.env.RATE_LIMIT_WINDOW_MS, 60000, 1000, 3600000),
|
|
273
274
|
cleanupIntervalMs: 60000,
|
|
274
275
|
},
|
|
275
276
|
runtime: runtimeState,
|
|
@@ -5,8 +5,3 @@ export declare function addSourceToMarkdown(content: string, url: string): strin
|
|
|
5
5
|
export declare function isRawTextContent(content: string): boolean;
|
|
6
6
|
export declare function isLikelyHtmlContent(content: string): boolean;
|
|
7
7
|
export declare function buildMetadataFooter(metadata?: MetadataBlock, fallbackUrl?: string): string;
|
|
8
|
-
/**
|
|
9
|
-
* Promote standalone lines that look like headings to proper markdown headings.
|
|
10
|
-
* Fence-aware: never modifies content inside fenced code blocks.
|
|
11
|
-
*/
|
|
12
|
-
export declare function promoteOrphanHeadings(markdown: string): string;
|
package/dist/markdown-cleanup.js
CHANGED
|
@@ -503,28 +503,3 @@ export function buildMetadataFooter(metadata, fallbackUrl) {
|
|
|
503
503
|
}
|
|
504
504
|
return lines.join('\n');
|
|
505
505
|
}
|
|
506
|
-
/* -------------------------------------------------------------------------------------------------
|
|
507
|
-
* Heading promotion (fence-aware)
|
|
508
|
-
* ------------------------------------------------------------------------------------------------- */
|
|
509
|
-
/**
|
|
510
|
-
* Promote standalone lines that look like headings to proper markdown headings.
|
|
511
|
-
* Fence-aware: never modifies content inside fenced code blocks.
|
|
512
|
-
*/
|
|
513
|
-
export function promoteOrphanHeadings(markdown) {
|
|
514
|
-
if (!markdown)
|
|
515
|
-
return '';
|
|
516
|
-
const lines = markdown.split('\n');
|
|
517
|
-
const result = [];
|
|
518
|
-
const state = initialFenceState();
|
|
519
|
-
for (let i = 0; i < lines.length; i += 1) {
|
|
520
|
-
const line = lines[i] ?? '';
|
|
521
|
-
const prevLine = i > 0 ? (lines[i - 1] ?? '') : '';
|
|
522
|
-
if (state.inFence || isFenceStart(line)) {
|
|
523
|
-
result.push(line);
|
|
524
|
-
advanceFenceState(line, state);
|
|
525
|
-
continue;
|
|
526
|
-
}
|
|
527
|
-
result.push(orphanHeadingPromoter.processLine(line, prevLine));
|
|
528
|
-
}
|
|
529
|
-
return result.join('\n');
|
|
530
|
-
}
|
package/dist/observability.d.ts
CHANGED
|
@@ -8,12 +8,10 @@ interface RequestContext {
|
|
|
8
8
|
export declare function setMcpServer(server: McpServer): void;
|
|
9
9
|
export declare function runWithRequestContext<T>(context: RequestContext, fn: () => T): T;
|
|
10
10
|
export declare function getRequestId(): string | undefined;
|
|
11
|
-
export declare function getSessionId(): string | undefined;
|
|
12
11
|
export declare function getOperationId(): string | undefined;
|
|
13
12
|
export declare function logInfo(message: string, meta?: LogMetadata): void;
|
|
14
13
|
export declare function logDebug(message: string, meta?: LogMetadata): void;
|
|
15
14
|
export declare function logWarn(message: string, meta?: LogMetadata): void;
|
|
16
15
|
export declare function logError(message: string, error?: Error | LogMetadata): void;
|
|
17
16
|
export declare function redactUrl(rawUrl: string): string;
|
|
18
|
-
export declare function redactHeaders(headers: Record<string, unknown>): Record<string, unknown>;
|
|
19
17
|
export {};
|
package/dist/observability.js
CHANGED
|
@@ -11,7 +11,7 @@ export function runWithRequestContext(context, fn) {
|
|
|
11
11
|
export function getRequestId() {
|
|
12
12
|
return requestContext.getStore()?.requestId;
|
|
13
13
|
}
|
|
14
|
-
|
|
14
|
+
function getSessionId() {
|
|
15
15
|
return requestContext.getStore()?.sessionId;
|
|
16
16
|
}
|
|
17
17
|
export function getOperationId() {
|
|
@@ -102,13 +102,3 @@ export function redactUrl(rawUrl) {
|
|
|
102
102
|
return rawUrl;
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
|
-
export function redactHeaders(headers) {
|
|
106
|
-
const redacted = { ...headers };
|
|
107
|
-
const sensitiveKeys = ['authorization', 'cookie', 'set-cookie', 'x-api-key'];
|
|
108
|
-
for (const key of Object.keys(redacted)) {
|
|
109
|
-
if (sensitiveKeys.includes(key.toLowerCase())) {
|
|
110
|
-
redacted[key] = '[REDACTED]';
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return redacted;
|
|
114
|
-
}
|
package/dist/tasks.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export interface CreateTaskResult {
|
|
|
31
31
|
};
|
|
32
32
|
_meta?: Record<string, unknown>;
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
declare class TaskManager {
|
|
35
35
|
private tasks;
|
|
36
36
|
private waiters;
|
|
37
37
|
createTask(options?: CreateTaskOptions, statusMessage?: string, ownerKey?: string): TaskState;
|
|
@@ -46,7 +46,6 @@ export declare class TaskManager {
|
|
|
46
46
|
tasks: TaskState[];
|
|
47
47
|
nextCursor?: string;
|
|
48
48
|
};
|
|
49
|
-
cleanupExpiredTasks(): number;
|
|
50
49
|
waitForTerminalTask(taskId: string, ownerKey: string, signal?: AbortSignal): Promise<TaskState | undefined>;
|
|
51
50
|
private notifyWaiters;
|
|
52
51
|
private isExpired;
|
|
@@ -54,3 +53,4 @@ export declare class TaskManager {
|
|
|
54
53
|
private decodeCursor;
|
|
55
54
|
}
|
|
56
55
|
export declare const taskManager: TaskManager;
|
|
56
|
+
export {};
|
package/dist/tasks.js
CHANGED
|
@@ -12,7 +12,7 @@ const TERMINAL_STATUSES = new Set([
|
|
|
12
12
|
function isTerminalStatus(status) {
|
|
13
13
|
return TERMINAL_STATUSES.has(status);
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
class TaskManager {
|
|
16
16
|
tasks = new Map();
|
|
17
17
|
waiters = new Map();
|
|
18
18
|
createTask(options, statusMessage = 'Task started', ownerKey = DEFAULT_OWNER_KEY) {
|
|
@@ -93,20 +93,6 @@ export class TaskManager {
|
|
|
93
93
|
const nextCursor = nextIndex < allTasks.length ? this.encodeCursor(nextIndex) : undefined;
|
|
94
94
|
return nextCursor ? { tasks: page, nextCursor } : { tasks: page };
|
|
95
95
|
}
|
|
96
|
-
// Helper to check if task is expired and could be cleaned up
|
|
97
|
-
// In a real implementation, this would be called by a periodic job
|
|
98
|
-
cleanupExpiredTasks() {
|
|
99
|
-
const now = Date.now();
|
|
100
|
-
let count = 0;
|
|
101
|
-
for (const [id, task] of this.tasks.entries()) {
|
|
102
|
-
const created = new Date(task.createdAt).getTime();
|
|
103
|
-
if (now - created > task.ttl) {
|
|
104
|
-
this.tasks.delete(id);
|
|
105
|
-
count++;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return count;
|
|
109
|
-
}
|
|
110
96
|
async waitForTerminalTask(taskId, ownerKey, signal) {
|
|
111
97
|
const task = this.getTask(taskId, ownerKey);
|
|
112
98
|
if (!task)
|
package/dist/tools.d.ts
CHANGED
|
@@ -72,7 +72,6 @@ export interface ToolHandlerExtra {
|
|
|
72
72
|
sendNotification?: (notification: ProgressNotification) => Promise<void>;
|
|
73
73
|
}
|
|
74
74
|
export declare const FETCH_URL_TOOL_NAME = "fetch-url";
|
|
75
|
-
export declare const FETCH_URL_TOOL_DESCRIPTION: string;
|
|
76
75
|
interface ProgressReporter {
|
|
77
76
|
report: (progress: number, message: string) => Promise<void>;
|
|
78
77
|
}
|
package/dist/tools.js
CHANGED
|
@@ -46,7 +46,7 @@ const fetchUrlOutputSchema = z.strictObject({
|
|
|
46
46
|
.describe('Error message if the request failed'),
|
|
47
47
|
});
|
|
48
48
|
export const FETCH_URL_TOOL_NAME = 'fetch-url';
|
|
49
|
-
|
|
49
|
+
const FETCH_URL_TOOL_DESCRIPTION = `
|
|
50
50
|
Fetches a webpage and converts it to clean Markdown format optimized for LLM context.
|
|
51
51
|
|
|
52
52
|
This tool is useful for:
|
package/dist/transform.js
CHANGED
|
@@ -984,7 +984,7 @@ const workerMessageSchema = z.discriminatedUnion('type', [
|
|
|
984
984
|
}),
|
|
985
985
|
]);
|
|
986
986
|
const POOL_MIN_WORKERS = 2;
|
|
987
|
-
const POOL_MAX_WORKERS =
|
|
987
|
+
const POOL_MAX_WORKERS = config.transform.maxWorkerScale;
|
|
988
988
|
const POOL_SCALE_THRESHOLD = 0.5;
|
|
989
989
|
const DEFAULT_TIMEOUT_MS = config.transform.timeoutMs;
|
|
990
990
|
class WorkerPool {
|
|
@@ -1029,6 +1029,13 @@ class WorkerPool {
|
|
|
1029
1029
|
getCapacity() {
|
|
1030
1030
|
return this.capacity;
|
|
1031
1031
|
}
|
|
1032
|
+
resize(size) {
|
|
1033
|
+
const newCapacity = Math.max(this.minCapacity, Math.min(size, this.maxCapacity));
|
|
1034
|
+
if (newCapacity === this.capacity)
|
|
1035
|
+
return;
|
|
1036
|
+
this.capacity = newCapacity;
|
|
1037
|
+
this.drainQueue();
|
|
1038
|
+
}
|
|
1032
1039
|
async close() {
|
|
1033
1040
|
if (this.closed)
|
|
1034
1041
|
return;
|
package/package.json
CHANGED