@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.
Files changed (44) hide show
  1. package/dist/http/native.d.ts.map +1 -1
  2. package/dist/http/native.js +85 -66
  3. package/dist/lib/core.d.ts.map +1 -1
  4. package/dist/lib/core.js +38 -14
  5. package/dist/lib/dom-prep.d.ts.map +1 -1
  6. package/dist/lib/dom-prep.js +81 -100
  7. package/dist/lib/fetch-pipeline.d.ts +2 -2
  8. package/dist/lib/fetch-pipeline.d.ts.map +1 -1
  9. package/dist/lib/fetch-pipeline.js +8 -4
  10. package/dist/lib/http.d.ts.map +1 -1
  11. package/dist/lib/http.js +43 -34
  12. package/dist/lib/task-handlers.js +1 -1
  13. package/dist/lib/url.d.ts +3 -0
  14. package/dist/lib/url.d.ts.map +1 -1
  15. package/dist/lib/url.js +45 -53
  16. package/dist/lib/utils.d.ts.map +1 -1
  17. package/dist/lib/utils.js +2 -1
  18. package/dist/tasks/execution.d.ts.map +1 -1
  19. package/dist/tasks/execution.js +1 -1
  20. package/dist/tasks/manager.d.ts +1 -17
  21. package/dist/tasks/manager.d.ts.map +1 -1
  22. package/dist/tasks/manager.js +27 -49
  23. package/dist/tasks/registry.d.ts +18 -0
  24. package/dist/tasks/registry.d.ts.map +1 -0
  25. package/dist/tasks/registry.js +28 -0
  26. package/dist/tools/fetch-url.d.ts +7 -6
  27. package/dist/tools/fetch-url.d.ts.map +1 -1
  28. package/dist/tools/fetch-url.js +108 -106
  29. package/dist/transform/html-translators.d.ts +1 -1
  30. package/dist/transform/html-translators.d.ts.map +1 -1
  31. package/dist/transform/html-translators.js +301 -320
  32. package/dist/transform/metadata.d.ts.map +1 -1
  33. package/dist/transform/metadata.js +5 -10
  34. package/dist/transform/next-flight.d.ts.map +1 -1
  35. package/dist/transform/next-flight.js +131 -63
  36. package/dist/transform/title-policy.d.ts +1 -3
  37. package/dist/transform/title-policy.d.ts.map +1 -1
  38. package/dist/transform/title-policy.js +3 -8
  39. package/dist/transform/transform.d.ts.map +1 -1
  40. package/dist/transform/transform.js +2 -4
  41. package/dist/transform/worker-pool.d.ts +1 -0
  42. package/dist/transform/worker-pool.d.ts.map +1 -1
  43. package/dist/transform/worker-pool.js +29 -35
  44. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../src/http/native.ts"],"names":[],"mappings":"AAokCA,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"}
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"}
@@ -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 authFingerprint = buildAuthFingerprint(ctx.auth);
166
- const session = sessionId
167
- ? (this.getAuthenticatedSessionById(sessionId, authFingerprint, ctx.res, requestId) ?? undefined)
168
- : undefined;
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
- getRequiredAuthenticatedSession(ctx, requestId = null, options) {
252
- const sessionId = this.getRequiredSessionId(ctx.req, ctx.res, requestId);
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
- async createNewSession(ctx, requestId, negotiatedProtocolVersion) {
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(newSessionId);
304
+ const session = this.store.get(sessionId);
326
305
  if (session) {
327
306
  if (session.protocolInitialized) {
328
- this.clearSessionInitTimeout(newSessionId);
307
+ this.clearSessionInitTimeout(sessionId);
329
308
  return;
330
309
  }
331
- this.cleanupSessionRecord(newSessionId, 'session-init-timeout');
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(newSessionId);
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 (connectState.transportClosed) {
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
- if (ctx.url.pathname === '/mcp') {
538
- switch (bodyErrorKind) {
539
- case 'payload-too-large':
540
- sendError(ctx.res, -32600, 'Request body too large', 413, null);
541
- break;
542
- case 'read-failed':
543
- if (!rawReq.destroyed) {
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
  }
@@ -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 = !this.entries.has(cacheKey) || capacity.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
- unregisterMcpSessionServer(sessionId);
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('Failed to unregister session server', {
1108
+ logWarn('Session close operation failed or timed out', {
1088
1109
  error: getErrorMessage(error),
1089
1110
  });
1090
1111
  }
1091
- const [transportResult, serverResult] = await Promise.allSettled([
1092
- session.transport.close(),
1093
- session.server.close(),
1094
- ]);
1095
- if (transportResult.status === 'rejected') {
1096
- this.logCloseFailure('transport', transportResult.reason);
1112
+ finally {
1113
+ if (timeoutId) {
1114
+ clearTimeout(timeoutId);
1115
+ }
1097
1116
  }
1098
- if (serverResult.status === 'rejected') {
1099
- this.logCloseFailure('server', serverResult.reason);
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;AA6oB9D,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;AAkCD,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;AA+KD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,QAAQ,GACjB,QAAQ,GAAG,IAAI,CAsBjB"}
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"}
@@ -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 isWithinPrimaryContent(element) {
261
- let current = element;
262
- while (current) {
263
- const tagName = current.tagName.toLowerCase();
264
- if (tagName === 'article' || tagName === 'main')
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 (isWithinPrimaryContent(element))
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 (!isWithinPrimaryContent(element))
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
- if (isStructuralNoise(tagName, interactive, context))
386
- return true;
387
- if (isNavigationNoise(tagName, role, className, id, context))
326
+ // 1. Structural Noise
327
+ if (context.structuralTags.has(tagName) && !interactive)
388
328
  return true;
389
- if (isHiddenNoise(hidden, interactive))
390
- return true;
391
- if (isPositionalNoise(className, element))
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
- if (isPromoMatch(className, id, element, context))
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 sections = Array.from(table.querySelectorAll('thead,tbody,tfoot'));
470
- for (const section of sections) {
471
- const rows = getDirectRows(section);
472
- for (const row of rows) {
473
- let insertAfter = row;
474
- for (const cell of getDirectCells(row)) {
475
- const nestedRows = Array.from(cell.querySelectorAll('tr')).filter((nested) => nested.closest('table') === table);
476
- for (const nestedRow of nestedRows) {
477
- insertAfter.after(nestedRow);
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
- function countRealImages(doc) {
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 doc.querySelectorAll('img')) {
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
- ? countRealImagesFromHtml(articleHtml)
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 SharedFetchOptions {
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: SharedFetchOptions, deps?: SharedFetchDeps): Promise<{
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":"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"}
1
+ {"version":3,"file":"fetch-pipeline.d.ts","sourceRoot":"","sources":["../../src/lib/fetch-pipeline.ts"],"names":[],"mappings":"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"}