@j0hanz/fetch-url-mcp 1.10.22 → 1.10.24
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/http/native.d.ts.map +1 -1
- package/dist/http/native.js +85 -66
- package/dist/lib/core.d.ts.map +1 -1
- package/dist/lib/core.js +38 -14
- package/dist/lib/dom-prep.d.ts.map +1 -1
- package/dist/lib/dom-prep.js +81 -100
- package/dist/lib/fetch-pipeline.d.ts +2 -2
- package/dist/lib/fetch-pipeline.d.ts.map +1 -1
- package/dist/lib/fetch-pipeline.js +8 -4
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js +43 -34
- package/dist/lib/task-handlers.js +1 -1
- package/dist/lib/url.d.ts +3 -0
- package/dist/lib/url.d.ts.map +1 -1
- package/dist/lib/url.js +45 -53
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +2 -1
- package/dist/tasks/execution.d.ts.map +1 -1
- package/dist/tasks/execution.js +1 -1
- package/dist/tasks/manager.d.ts +1 -17
- package/dist/tasks/manager.d.ts.map +1 -1
- package/dist/tasks/manager.js +27 -49
- package/dist/tasks/registry.d.ts +18 -0
- package/dist/tasks/registry.d.ts.map +1 -0
- package/dist/tasks/registry.js +28 -0
- package/dist/tools/fetch-url.d.ts +7 -6
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +108 -106
- package/dist/transform/html-translators.d.ts +1 -1
- package/dist/transform/html-translators.d.ts.map +1 -1
- package/dist/transform/html-translators.js +301 -320
- package/dist/transform/metadata.d.ts.map +1 -1
- package/dist/transform/metadata.js +5 -10
- package/dist/transform/next-flight.d.ts.map +1 -1
- package/dist/transform/next-flight.js +131 -63
- package/dist/transform/title-policy.d.ts +1 -3
- package/dist/transform/title-policy.d.ts.map +1 -1
- package/dist/transform/title-policy.js +3 -8
- package/dist/transform/transform.d.ts.map +1 -1
- package/dist/transform/transform.js +2 -4
- package/dist/transform/worker-pool.d.ts +1 -0
- package/dist/transform/worker-pool.d.ts.map +1 -1
- package/dist/transform/worker-pool.js +29 -35
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../src/http/native.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../src/http/native.ts"],"names":[],"mappings":"AAgoCA,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAC/C,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CA0DD"}
|
package/dist/http/native.js
CHANGED
|
@@ -157,15 +157,14 @@ class McpSessionGateway {
|
|
|
157
157
|
const method = typeof body.method === 'string' ? body.method : null;
|
|
158
158
|
const isInitializedMethod = method !== null && isInitializedNotification(method);
|
|
159
159
|
const isInitNotification = isInitializedMethod && body.id === undefined;
|
|
160
|
-
const sessionId = getMcpSessionId(ctx.req);
|
|
161
160
|
if (isInitializedMethod && !isInitNotification) {
|
|
162
161
|
sendError(ctx.res, -32600, 'notifications/initialized must be sent as a notification', 400, requestId);
|
|
163
162
|
return null;
|
|
164
163
|
}
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
164
|
+
const sessionState = this.getOptionalAuthenticatedSession(ctx, requestId);
|
|
165
|
+
if (!sessionState)
|
|
166
|
+
return null;
|
|
167
|
+
const { sessionId, session } = sessionState;
|
|
169
168
|
if (!this.ensurePostSessionAccess({
|
|
170
169
|
ctx,
|
|
171
170
|
sessionId,
|
|
@@ -248,14 +247,25 @@ class McpSessionGateway {
|
|
|
248
247
|
this.store.touch(sessionId);
|
|
249
248
|
return session.transport;
|
|
250
249
|
}
|
|
251
|
-
|
|
252
|
-
const sessionId =
|
|
250
|
+
getOptionalAuthenticatedSession(ctx, requestId = null) {
|
|
251
|
+
const sessionId = getMcpSessionId(ctx.req);
|
|
253
252
|
if (!sessionId)
|
|
254
|
-
return null;
|
|
253
|
+
return { sessionId: null, session: undefined };
|
|
255
254
|
const authFingerprint = buildAuthFingerprint(ctx.auth);
|
|
256
255
|
const session = this.getAuthenticatedSessionById(sessionId, authFingerprint, ctx.res, requestId);
|
|
257
256
|
if (!session)
|
|
258
257
|
return null;
|
|
258
|
+
return { sessionId, session };
|
|
259
|
+
}
|
|
260
|
+
getRequiredAuthenticatedSession(ctx, requestId = null, options) {
|
|
261
|
+
const state = this.getOptionalAuthenticatedSession(ctx, requestId);
|
|
262
|
+
if (!state)
|
|
263
|
+
return null;
|
|
264
|
+
const { sessionId, session } = state;
|
|
265
|
+
if (!sessionId || !session) {
|
|
266
|
+
sendError(ctx.res, -32600, 'Missing session ID', 400, requestId);
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
259
269
|
if (!this.ensureSessionProtocolVersion(ctx, session))
|
|
260
270
|
return null;
|
|
261
271
|
if (options?.requireInitialized && !session.protocolInitialized) {
|
|
@@ -264,13 +274,6 @@ class McpSessionGateway {
|
|
|
264
274
|
}
|
|
265
275
|
return { sessionId, session };
|
|
266
276
|
}
|
|
267
|
-
getRequiredSessionId(req, res, requestId = null) {
|
|
268
|
-
const sessionId = getMcpSessionId(req);
|
|
269
|
-
if (sessionId)
|
|
270
|
-
return sessionId;
|
|
271
|
-
sendError(res, -32600, 'Missing session ID', 400, requestId);
|
|
272
|
-
return null;
|
|
273
|
-
}
|
|
274
277
|
getAuthenticatedSessionById(sessionId, authFingerprint, res, requestId = null) {
|
|
275
278
|
const session = this.store.get(sessionId);
|
|
276
279
|
if (!session) {
|
|
@@ -296,50 +299,29 @@ class McpSessionGateway {
|
|
|
296
299
|
if (sessionId)
|
|
297
300
|
this.store.touch(sessionId);
|
|
298
301
|
}
|
|
299
|
-
|
|
300
|
-
const authFingerprint = buildAuthFingerprint(ctx.auth);
|
|
301
|
-
if (!authFingerprint) {
|
|
302
|
-
sendError(ctx.res, -32603, 'Missing auth context', 500, requestId);
|
|
303
|
-
return null;
|
|
304
|
-
}
|
|
305
|
-
if (!this.reserveCapacity(ctx.res, requestId))
|
|
306
|
-
return null;
|
|
307
|
-
const tracker = createSlotTracker(this.store);
|
|
308
|
-
const newSessionId = randomUUID();
|
|
309
|
-
let sessionServer;
|
|
310
|
-
try {
|
|
311
|
-
sessionServer = await this.createSessionServer();
|
|
312
|
-
}
|
|
313
|
-
catch (error) {
|
|
314
|
-
tracker.releaseSlot();
|
|
315
|
-
throw error;
|
|
316
|
-
}
|
|
317
|
-
const transportImpl = new StreamableHTTPServerTransport({
|
|
318
|
-
sessionIdGenerator: () => newSessionId,
|
|
319
|
-
});
|
|
320
|
-
const unpublishedSession = {
|
|
321
|
-
server: sessionServer,
|
|
322
|
-
transport: transportImpl,
|
|
323
|
-
};
|
|
302
|
+
createSessionInitTimeout(sessionId, tracker, unpublishedSession) {
|
|
324
303
|
const initTimeout = setTimeout(() => {
|
|
325
|
-
const session = this.store.get(
|
|
304
|
+
const session = this.store.get(sessionId);
|
|
326
305
|
if (session) {
|
|
327
306
|
if (session.protocolInitialized) {
|
|
328
|
-
this.clearSessionInitTimeout(
|
|
307
|
+
this.clearSessionInitTimeout(sessionId);
|
|
329
308
|
return;
|
|
330
309
|
}
|
|
331
|
-
this.cleanupSessionRecord(
|
|
310
|
+
this.cleanupSessionRecord(sessionId, 'session-init-timeout');
|
|
332
311
|
return;
|
|
333
312
|
}
|
|
334
313
|
tracker.releaseSlot();
|
|
335
314
|
void teardownUnregisteredSessionResources(unpublishedSession, 'session-init-timeout');
|
|
336
315
|
}, config.server.sessionInitTimeoutMs);
|
|
337
316
|
initTimeout.unref();
|
|
317
|
+
return initTimeout;
|
|
318
|
+
}
|
|
319
|
+
async connectTransport(sessionServer, transportImpl, initTimeout, tracker, unpublishedSession, sessionId) {
|
|
338
320
|
const connectState = { transportClosed: false };
|
|
339
321
|
transportImpl.onclose = () => {
|
|
340
322
|
connectState.transportClosed = true;
|
|
341
323
|
clearTimeout(initTimeout);
|
|
342
|
-
this.sessionInitTimeouts.delete(
|
|
324
|
+
this.sessionInitTimeouts.delete(sessionId);
|
|
343
325
|
tracker.releaseSlot();
|
|
344
326
|
};
|
|
345
327
|
try {
|
|
@@ -352,8 +334,37 @@ class McpSessionGateway {
|
|
|
352
334
|
void teardownUnregisteredSessionResources(unpublishedSession, 'session-connect-failed');
|
|
353
335
|
throw err;
|
|
354
336
|
}
|
|
337
|
+
return !connectState.transportClosed;
|
|
338
|
+
}
|
|
339
|
+
async createNewSession(ctx, requestId, negotiatedProtocolVersion) {
|
|
340
|
+
const authFingerprint = buildAuthFingerprint(ctx.auth);
|
|
341
|
+
if (!authFingerprint) {
|
|
342
|
+
sendError(ctx.res, -32603, 'Missing auth context', 500, requestId);
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
if (!this.reserveCapacity(ctx.res, requestId))
|
|
346
|
+
return null;
|
|
347
|
+
const tracker = createSlotTracker(this.store);
|
|
348
|
+
const newSessionId = randomUUID();
|
|
349
|
+
let sessionServer;
|
|
350
|
+
try {
|
|
351
|
+
sessionServer = await this.createSessionServer();
|
|
352
|
+
}
|
|
353
|
+
catch (error) {
|
|
354
|
+
tracker.releaseSlot();
|
|
355
|
+
throw error;
|
|
356
|
+
}
|
|
357
|
+
const transportImpl = new StreamableHTTPServerTransport({
|
|
358
|
+
sessionIdGenerator: () => newSessionId,
|
|
359
|
+
});
|
|
360
|
+
const unpublishedSession = {
|
|
361
|
+
server: sessionServer,
|
|
362
|
+
transport: transportImpl,
|
|
363
|
+
};
|
|
364
|
+
const initTimeout = this.createSessionInitTimeout(newSessionId, tracker, unpublishedSession);
|
|
365
|
+
const isConnected = await this.connectTransport(sessionServer, transportImpl, initTimeout, tracker, unpublishedSession, newSessionId);
|
|
355
366
|
tracker.releaseSlot();
|
|
356
|
-
if (
|
|
367
|
+
if (!isConnected) {
|
|
357
368
|
void teardownUnregisteredSessionResources(unpublishedSession, 'session-closed-during-connect');
|
|
358
369
|
return null;
|
|
359
370
|
}
|
|
@@ -533,29 +544,36 @@ class HttpDispatcher {
|
|
|
533
544
|
// ---------------------------------------------------------------------------
|
|
534
545
|
// Body parse error responses
|
|
535
546
|
// ---------------------------------------------------------------------------
|
|
547
|
+
const DEFAULT_BODY_ERROR = {
|
|
548
|
+
statusCode: 400,
|
|
549
|
+
mcpCode: -32700,
|
|
550
|
+
mcpMsg: 'Parse error',
|
|
551
|
+
restMsg: 'Invalid JSON',
|
|
552
|
+
};
|
|
553
|
+
const BODY_PARSE_ERRORS = {
|
|
554
|
+
'payload-too-large': {
|
|
555
|
+
statusCode: 413,
|
|
556
|
+
mcpCode: -32600,
|
|
557
|
+
mcpMsg: 'Request body too large',
|
|
558
|
+
restMsg: 'Payload too large',
|
|
559
|
+
},
|
|
560
|
+
'read-failed': {
|
|
561
|
+
statusCode: 400,
|
|
562
|
+
mcpCode: -32600,
|
|
563
|
+
mcpMsg: 'Request body read failed',
|
|
564
|
+
restMsg: 'Invalid JSON',
|
|
565
|
+
},
|
|
566
|
+
default: DEFAULT_BODY_ERROR,
|
|
567
|
+
};
|
|
536
568
|
function sendBodyParseError(ctx, bodyErrorKind, rawReq) {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
sendError(ctx.res, -32600, 'Request body read failed', 400, null);
|
|
545
|
-
}
|
|
546
|
-
break;
|
|
547
|
-
case 'invalid-json':
|
|
548
|
-
default:
|
|
549
|
-
sendError(ctx.res, -32700, 'Parse error', 400, null);
|
|
550
|
-
break;
|
|
569
|
+
const errorDef = BODY_PARSE_ERRORS[bodyErrorKind ?? 'default'] ?? DEFAULT_BODY_ERROR;
|
|
570
|
+
if (bodyErrorKind !== 'read-failed' || !rawReq.destroyed) {
|
|
571
|
+
if (ctx.url.pathname === '/mcp') {
|
|
572
|
+
sendError(ctx.res, errorDef.mcpCode, errorDef.mcpMsg, errorDef.statusCode, null);
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
575
|
+
sendJson(ctx.res, errorDef.statusCode, { error: errorDef.restMsg });
|
|
551
576
|
}
|
|
552
|
-
}
|
|
553
|
-
else {
|
|
554
|
-
sendJson(ctx.res, bodyErrorKind === 'payload-too-large' ? 413 : 400, {
|
|
555
|
-
error: bodyErrorKind === 'payload-too-large'
|
|
556
|
-
? 'Payload too large'
|
|
557
|
-
: 'Invalid JSON',
|
|
558
|
-
});
|
|
559
577
|
}
|
|
560
578
|
drainRequest(rawReq);
|
|
561
579
|
}
|
|
@@ -619,6 +637,7 @@ class HttpRequestPipeline {
|
|
|
619
637
|
return false;
|
|
620
638
|
}
|
|
621
639
|
if (!this.rateLimiter.check(ctx)) {
|
|
640
|
+
sendJson(ctx.res, 429, { error: 'Too Many Requests' });
|
|
622
641
|
drainRequest(rawReq);
|
|
623
642
|
return false;
|
|
624
643
|
}
|
package/dist/lib/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/core.js
CHANGED
|
@@ -584,10 +584,14 @@ class InMemoryCacheStore {
|
|
|
584
584
|
const now = Date.now();
|
|
585
585
|
const expiresAtMs = now + this.ttlMs;
|
|
586
586
|
const entrySize = content.length;
|
|
587
|
+
const isUpdate = this.entries.has(cacheKey);
|
|
588
|
+
if (isUpdate) {
|
|
589
|
+
this.delete(cacheKey);
|
|
590
|
+
}
|
|
587
591
|
const capacity = this.ensureCapacity(cacheKey, entrySize);
|
|
588
592
|
if (!capacity.ok)
|
|
589
593
|
return;
|
|
590
|
-
let listChanged = !
|
|
594
|
+
let listChanged = !isUpdate || capacity.listChanged;
|
|
591
595
|
const entry = {
|
|
592
596
|
url: metadata.url,
|
|
593
597
|
content,
|
|
@@ -596,9 +600,6 @@ class InMemoryCacheStore {
|
|
|
596
600
|
expiresAtMs,
|
|
597
601
|
...(metadata.title ? { title: metadata.title } : {}),
|
|
598
602
|
};
|
|
599
|
-
if (this.entries.has(cacheKey)) {
|
|
600
|
-
this.delete(cacheKey);
|
|
601
|
-
}
|
|
602
603
|
this.entries.set(cacheKey, entry);
|
|
603
604
|
this.currentBytes += entrySize;
|
|
604
605
|
// Eviction (LRU: first insertion-order key) - Count based
|
|
@@ -1080,23 +1081,46 @@ class SessionCleanupLoop {
|
|
|
1080
1081
|
});
|
|
1081
1082
|
}
|
|
1082
1083
|
}
|
|
1084
|
+
const closePromise = Promise.allSettled([
|
|
1085
|
+
session.transport.close(),
|
|
1086
|
+
session.server.close(),
|
|
1087
|
+
]);
|
|
1088
|
+
let timeoutId;
|
|
1089
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
1090
|
+
timeoutId = setTimeout(() => {
|
|
1091
|
+
reject(new Error('Session close timed out'));
|
|
1092
|
+
}, 5000);
|
|
1093
|
+
timeoutId.unref();
|
|
1094
|
+
});
|
|
1083
1095
|
try {
|
|
1084
|
-
|
|
1096
|
+
const [transportResult, serverResult] = await Promise.race([
|
|
1097
|
+
closePromise,
|
|
1098
|
+
timeoutPromise,
|
|
1099
|
+
]);
|
|
1100
|
+
if (transportResult.status === 'rejected') {
|
|
1101
|
+
this.logCloseFailure('transport', transportResult.reason);
|
|
1102
|
+
}
|
|
1103
|
+
if (serverResult.status === 'rejected') {
|
|
1104
|
+
this.logCloseFailure('server', serverResult.reason);
|
|
1105
|
+
}
|
|
1085
1106
|
}
|
|
1086
1107
|
catch (error) {
|
|
1087
|
-
logWarn('
|
|
1108
|
+
logWarn('Session close operation failed or timed out', {
|
|
1088
1109
|
error: getErrorMessage(error),
|
|
1089
1110
|
});
|
|
1090
1111
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
if (transportResult.status === 'rejected') {
|
|
1096
|
-
this.logCloseFailure('transport', transportResult.reason);
|
|
1112
|
+
finally {
|
|
1113
|
+
if (timeoutId) {
|
|
1114
|
+
clearTimeout(timeoutId);
|
|
1115
|
+
}
|
|
1097
1116
|
}
|
|
1098
|
-
|
|
1099
|
-
|
|
1117
|
+
try {
|
|
1118
|
+
unregisterMcpSessionServer(sessionId);
|
|
1119
|
+
}
|
|
1120
|
+
catch (error) {
|
|
1121
|
+
logWarn('Failed to unregister session server', {
|
|
1122
|
+
error: getErrorMessage(error),
|
|
1123
|
+
});
|
|
1100
1124
|
}
|
|
1101
1125
|
}
|
|
1102
1126
|
logCloseFailure(target, error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom-prep.d.ts","sourceRoot":"","sources":["../../src/lib/dom-prep.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"dom-prep.d.ts","sourceRoot":"","sources":["../../src/lib/dom-prep.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAilB9D,eAAO,MAAM,sBAAsB,QAAmB,CAAC;AAyCvD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CA6B9D;AAuBD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAY/D;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,CASR;AA0CD,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAG5D;AA0RD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CA2BjE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAE1D;AAWD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAQ3D;AAuDD,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,IAAI,CAON;AA4BD,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,QAAQ,EACnB,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,MAAM,CAcR;AA0ED,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,MAAM,GAAG,QAAQ,GAChC,MAAM,CAaR;AA8KD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,QAAQ,GACjB,QAAQ,GAAG,IAAI,CAsBjB"}
|
package/dist/lib/dom-prep.js
CHANGED
|
@@ -257,16 +257,11 @@ function isInteractive(element, role) {
|
|
|
257
257
|
return (element.hasAttribute('data-accordion-item') ||
|
|
258
258
|
element.hasAttribute('data-radix-collection-item'));
|
|
259
259
|
}
|
|
260
|
-
function
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
return true;
|
|
266
|
-
if (current.getAttribute('role') === 'main')
|
|
267
|
-
return true;
|
|
268
|
-
current = current.parentElement;
|
|
269
|
-
}
|
|
260
|
+
function isPrimaryContent(element, checkDescendants = false) {
|
|
261
|
+
if (element.closest('article,main,[role="main"]'))
|
|
262
|
+
return true;
|
|
263
|
+
if (checkDescendants && element.querySelector('article,main,[role="main"]'))
|
|
264
|
+
return true;
|
|
270
265
|
return false;
|
|
271
266
|
}
|
|
272
267
|
function isLinkDenseNavigation(element, checkContainedNav = false) {
|
|
@@ -285,7 +280,7 @@ function shouldPreserve(element, tagName) {
|
|
|
285
280
|
// Check Dialog
|
|
286
281
|
const role = element.getAttribute('role');
|
|
287
282
|
if (role === 'dialog' || role === 'alertdialog') {
|
|
288
|
-
if (
|
|
283
|
+
if (isPrimaryContent(element))
|
|
289
284
|
return true;
|
|
290
285
|
const textLen = (element.textContent || '').length;
|
|
291
286
|
if (textLen > DIALOG_MIN_CHARS_FOR_PRESERVATION)
|
|
@@ -304,7 +299,7 @@ function shouldPreserve(element, tagName) {
|
|
|
304
299
|
}
|
|
305
300
|
// Check Aside — preserve only if it looks like article content, not navigation
|
|
306
301
|
if (tagName === 'aside') {
|
|
307
|
-
if (!
|
|
302
|
+
if (!isPrimaryContent(element))
|
|
308
303
|
return false;
|
|
309
304
|
return !isLinkDenseNavigation(element, true);
|
|
310
305
|
}
|
|
@@ -318,60 +313,6 @@ function removeNodes(nodes) {
|
|
|
318
313
|
}
|
|
319
314
|
}
|
|
320
315
|
}
|
|
321
|
-
// Checks if the element itself or any of its ancestors contain primary content indicators (article, main, role=main).
|
|
322
|
-
function containsPrimaryContent(element) {
|
|
323
|
-
const tag = element.tagName.toLowerCase();
|
|
324
|
-
if (tag === 'article' || tag === 'main')
|
|
325
|
-
return true;
|
|
326
|
-
if (element.getAttribute('role') === 'main')
|
|
327
|
-
return true;
|
|
328
|
-
return element.querySelector('article,main,[role="main"]') !== null;
|
|
329
|
-
}
|
|
330
|
-
function isPromoMatch(className, id, element, context) {
|
|
331
|
-
if (!context.promoEnabled)
|
|
332
|
-
return false;
|
|
333
|
-
const aggTest = context.promoMatchers.aggressive.test(className) ||
|
|
334
|
-
context.promoMatchers.aggressive.test(id);
|
|
335
|
-
if (aggTest)
|
|
336
|
-
return !isWithinPrimaryContent(element);
|
|
337
|
-
// Base test must match and be outside primary content to be considered noise
|
|
338
|
-
if (!context.promoMatchers.base.test(className) &&
|
|
339
|
-
!context.promoMatchers.base.test(id))
|
|
340
|
-
return false;
|
|
341
|
-
return !containsPrimaryContent(element);
|
|
342
|
-
}
|
|
343
|
-
function isStructuralNoise(tagName, interactive, context) {
|
|
344
|
-
return context.structuralTags.has(tagName) && !interactive;
|
|
345
|
-
}
|
|
346
|
-
function isNavigationNoise(tagName, role, className, id, context) {
|
|
347
|
-
if (!context.flags.navFooter)
|
|
348
|
-
return false;
|
|
349
|
-
// Always-noise tags (nav, footer)
|
|
350
|
-
if (ALWAYS_NOISE_TAGS.has(tagName))
|
|
351
|
-
return true;
|
|
352
|
-
// Header with navigation role or noise class/id
|
|
353
|
-
if (tagName === 'header' &&
|
|
354
|
-
((role !== null && NAVIGATION_ROLES.has(role)) ||
|
|
355
|
-
HEADER_NOISE_PATTERN.test(`${className} ${id}`)))
|
|
356
|
-
return true;
|
|
357
|
-
// Aside elements
|
|
358
|
-
if (tagName === 'aside')
|
|
359
|
-
return true;
|
|
360
|
-
// Navigation roles (except aside+complementary)
|
|
361
|
-
if (role !== null &&
|
|
362
|
-
NAVIGATION_ROLES.has(role) &&
|
|
363
|
-
(tagName !== 'aside' || role !== 'complementary'))
|
|
364
|
-
return true;
|
|
365
|
-
return false;
|
|
366
|
-
}
|
|
367
|
-
function isHiddenNoise(hidden, interactive) {
|
|
368
|
-
return hidden && !interactive;
|
|
369
|
-
}
|
|
370
|
-
function isPositionalNoise(className, element) {
|
|
371
|
-
return (FIXED_OR_HIGH_Z_PATTERN.test(className) &&
|
|
372
|
-
(element.textContent || '').trim().length <
|
|
373
|
-
NAV_FOOTER_MIN_CHARS_FOR_PRESERVATION);
|
|
374
|
-
}
|
|
375
316
|
function isNoiseElement(element, context) {
|
|
376
317
|
const tagName = element.tagName.toLowerCase();
|
|
377
318
|
const role = element.getAttribute('role');
|
|
@@ -382,16 +323,45 @@ function isNoiseElement(element, context) {
|
|
|
382
323
|
const hidden = element.hasAttribute('hidden') ||
|
|
383
324
|
element.getAttribute('aria-hidden') === 'true' ||
|
|
384
325
|
(style !== null && HIDDEN_STYLE_REGEX.test(style));
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
if (isNavigationNoise(tagName, role, className, id, context))
|
|
326
|
+
// 1. Structural Noise
|
|
327
|
+
if (context.structuralTags.has(tagName) && !interactive)
|
|
388
328
|
return true;
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
329
|
+
// 2. Navigation / Layout Noise
|
|
330
|
+
if (context.flags.navFooter) {
|
|
331
|
+
if (ALWAYS_NOISE_TAGS.has(tagName))
|
|
332
|
+
return true;
|
|
333
|
+
if (tagName === 'header' &&
|
|
334
|
+
((role !== null && NAVIGATION_ROLES.has(role)) ||
|
|
335
|
+
HEADER_NOISE_PATTERN.test(`${className} ${id}`)))
|
|
336
|
+
return true;
|
|
337
|
+
if (tagName === 'aside')
|
|
338
|
+
return true;
|
|
339
|
+
if (role !== null &&
|
|
340
|
+
NAVIGATION_ROLES.has(role) &&
|
|
341
|
+
(tagName !== 'aside' || role !== 'complementary'))
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
// 3. Hidden Noise
|
|
345
|
+
if (hidden && !interactive)
|
|
392
346
|
return true;
|
|
393
|
-
|
|
347
|
+
// 4. Positional Noise
|
|
348
|
+
if (FIXED_OR_HIGH_Z_PATTERN.test(className) &&
|
|
349
|
+
(element.textContent || '').trim().length <
|
|
350
|
+
NAV_FOOTER_MIN_CHARS_FOR_PRESERVATION) {
|
|
394
351
|
return true;
|
|
352
|
+
}
|
|
353
|
+
// 5. Promo/Advert Noise
|
|
354
|
+
if (context.promoEnabled) {
|
|
355
|
+
const aggTest = context.promoMatchers.aggressive.test(className) ||
|
|
356
|
+
context.promoMatchers.aggressive.test(id);
|
|
357
|
+
if (aggTest && !isPrimaryContent(element))
|
|
358
|
+
return true;
|
|
359
|
+
if (context.promoMatchers.base.test(className) ||
|
|
360
|
+
context.promoMatchers.base.test(id)) {
|
|
361
|
+
if (!isPrimaryContent(element, true))
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
395
365
|
return false;
|
|
396
366
|
}
|
|
397
367
|
function stripHeadingWrapperDivs(h) {
|
|
@@ -459,25 +429,16 @@ function isHeadingPermalinkAnchor(anchor) {
|
|
|
459
429
|
return ((ariaHidden === 'true' || tabindex === '-1') &&
|
|
460
430
|
text.length <= MAX_PERMALINK_TEXT_LENGTH);
|
|
461
431
|
}
|
|
462
|
-
function getDirectRows(section) {
|
|
463
|
-
return Array.from(section.children).filter((child) => child.tagName === 'TR');
|
|
464
|
-
}
|
|
465
|
-
function getDirectCells(row) {
|
|
466
|
-
return Array.from(row.children).filter((child) => child.tagName === 'TH' || child.tagName === 'TD');
|
|
467
|
-
}
|
|
468
432
|
function hoistNestedRows(table) {
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
insertAfter = nestedRow;
|
|
479
|
-
}
|
|
480
|
-
}
|
|
433
|
+
const nestedRows = table.querySelectorAll('td tr, th tr');
|
|
434
|
+
// Iterate backwards to preserve the original document order when inserting after the parent row
|
|
435
|
+
for (let i = nestedRows.length - 1; i >= 0; i--) {
|
|
436
|
+
const nestedRow = nestedRows[i];
|
|
437
|
+
if (nestedRow?.closest('table') !== table)
|
|
438
|
+
continue;
|
|
439
|
+
const parentRow = nestedRow.parentElement?.closest('tr');
|
|
440
|
+
if (parentRow && parentRow !== nestedRow) {
|
|
441
|
+
parentRow.after(nestedRow);
|
|
481
442
|
}
|
|
482
443
|
}
|
|
483
444
|
}
|
|
@@ -961,7 +922,27 @@ export function runDocsControlPass(document) {
|
|
|
961
922
|
stripPromoLinks(document);
|
|
962
923
|
separateAdjacentInlineElements(document);
|
|
963
924
|
}
|
|
925
|
+
const PHRASING_PARENTS = new Set([
|
|
926
|
+
'P',
|
|
927
|
+
'LI',
|
|
928
|
+
'TD',
|
|
929
|
+
'TH',
|
|
930
|
+
'DD',
|
|
931
|
+
'SPAN',
|
|
932
|
+
'LABEL',
|
|
933
|
+
'FIGCAPTION',
|
|
934
|
+
'BLOCKQUOTE',
|
|
935
|
+
]);
|
|
936
|
+
function unwrapInlineButtons(document) {
|
|
937
|
+
for (const btn of document.querySelectorAll('button')) {
|
|
938
|
+
const parent = btn.parentElement;
|
|
939
|
+
if (!parent || !PHRASING_PARENTS.has(parent.tagName))
|
|
940
|
+
continue;
|
|
941
|
+
btn.replaceWith(...Array.from(btn.childNodes));
|
|
942
|
+
}
|
|
943
|
+
}
|
|
964
944
|
function runStructuralNoisePass(document, signal) {
|
|
945
|
+
unwrapInlineButtons(document);
|
|
965
946
|
stripNoise(document, signal);
|
|
966
947
|
}
|
|
967
948
|
function runCodeExamplePass(document) {
|
|
@@ -1203,21 +1184,21 @@ function passesContentRatioGate(articleTextLength, document) {
|
|
|
1203
1184
|
return (originalLength < MIN_HTML_LENGTH_FOR_GATE ||
|
|
1204
1185
|
articleTextLength / originalLength >= MIN_CONTENT_RATIO);
|
|
1205
1186
|
}
|
|
1206
|
-
|
|
1187
|
+
const DATA_IMG_PATTERN = /<img\b[^>]*\bsrc\s*=\s*["']?data:/gi;
|
|
1188
|
+
function countRealImages(htmlOrDoc) {
|
|
1189
|
+
if (typeof htmlOrDoc === 'string') {
|
|
1190
|
+
const total = htmlOrDoc.match(/<img\b/gi)?.length ?? 0;
|
|
1191
|
+
const dataImages = htmlOrDoc.match(DATA_IMG_PATTERN)?.length ?? 0;
|
|
1192
|
+
return total - dataImages;
|
|
1193
|
+
}
|
|
1207
1194
|
let count = 0;
|
|
1208
|
-
for (const img of
|
|
1195
|
+
for (const img of htmlOrDoc.querySelectorAll('img')) {
|
|
1209
1196
|
const src = img.getAttribute('src') ?? '';
|
|
1210
1197
|
if (!src.startsWith('data:'))
|
|
1211
1198
|
count++;
|
|
1212
1199
|
}
|
|
1213
1200
|
return count;
|
|
1214
1201
|
}
|
|
1215
|
-
const DATA_IMG_PATTERN = /<img\b[^>]*\bsrc\s*=\s*["']?data:/gi;
|
|
1216
|
-
function countRealImagesFromHtml(html) {
|
|
1217
|
-
const total = html.match(/<img\b/gi)?.length ?? 0;
|
|
1218
|
-
const dataImages = html.match(DATA_IMG_PATTERN)?.length ?? 0;
|
|
1219
|
-
return total - dataImages;
|
|
1220
|
-
}
|
|
1221
1202
|
function passesRetentionRulesFromHtml(originalDoc, articleHtml) {
|
|
1222
1203
|
return RETENTION_RULES.every(({ selector, pattern, minThreshold, ratio }) => {
|
|
1223
1204
|
// Exclude lazy-loaded placeholder images (data: URI src) from the
|
|
@@ -1231,7 +1212,7 @@ function passesRetentionRulesFromHtml(originalDoc, articleHtml) {
|
|
|
1231
1212
|
// For images, also exclude data: URIs from the article count to
|
|
1232
1213
|
// align with the denominator's real-image filtering.
|
|
1233
1214
|
const articleCount = selector === 'img'
|
|
1234
|
-
?
|
|
1215
|
+
? countRealImages(articleHtml)
|
|
1235
1216
|
: (articleHtml.match(pattern)?.length ?? 0);
|
|
1236
1217
|
return articleCount / original >= ratio;
|
|
1237
1218
|
});
|
|
@@ -42,7 +42,7 @@ export type MarkdownPipelineResult = MarkdownTransformResult & {
|
|
|
42
42
|
export declare function parseCachedMarkdownResult(cached: string): MarkdownPipelineResult | undefined;
|
|
43
43
|
export declare const markdownTransform: (input: FetchTransformInput, url: string, signal?: AbortSignal) => Promise<MarkdownPipelineResult>;
|
|
44
44
|
export declare function serializeMarkdownResult(result: MarkdownPipelineResult): string;
|
|
45
|
-
interface
|
|
45
|
+
interface MarkdownFetchOptions {
|
|
46
46
|
readonly url: string;
|
|
47
47
|
readonly signal?: AbortSignal;
|
|
48
48
|
readonly cacheVary?: Record<string, unknown> | string;
|
|
@@ -55,7 +55,7 @@ interface SharedFetchOptions {
|
|
|
55
55
|
interface SharedFetchDeps {
|
|
56
56
|
readonly executeFetchPipeline?: typeof executeFetchPipeline;
|
|
57
57
|
}
|
|
58
|
-
export declare function performSharedFetch(options:
|
|
58
|
+
export declare function performSharedFetch(options: MarkdownFetchOptions, deps?: SharedFetchDeps): Promise<{
|
|
59
59
|
pipeline: PipelineResult<MarkdownPipelineResult>;
|
|
60
60
|
inlineResult: InlineContentResult;
|
|
61
61
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-pipeline.d.ts","sourceRoot":"","sources":["../../src/lib/fetch-pipeline.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAgBrE,OAAO,EAA6B,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AACD,UAAU,mBAAmB;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;
|
|
1
|
+
{"version":3,"file":"fetch-pipeline.d.ts","sourceRoot":"","sources":["../../src/lib/fetch-pipeline.ts"],"names":[],"mappings":"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"}
|