@cyanheads/pubmed-mcp-server 2.10.17 → 2.10.19

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 (105) hide show
  1. package/AGENTS.md +12 -14
  2. package/CLAUDE.md +12 -14
  3. package/Dockerfile +77 -36
  4. package/README.md +86 -109
  5. package/changelog/2.10.x/2.10.17.md +1 -1
  6. package/changelog/2.10.x/2.10.18.md +14 -0
  7. package/changelog/2.10.x/2.10.19.md +42 -0
  8. package/dist/config/server-config.d.ts.map +1 -1
  9. package/dist/config/server-config.js +7 -3
  10. package/dist/config/server-config.js.map +1 -1
  11. package/dist/mcp-server/resources/definitions/database-info.resource.d.ts +43 -1
  12. package/dist/mcp-server/resources/definitions/database-info.resource.d.ts.map +1 -1
  13. package/dist/mcp-server/resources/definitions/database-info.resource.js +2 -0
  14. package/dist/mcp-server/resources/definitions/database-info.resource.js.map +1 -1
  15. package/dist/mcp-server/tools/definitions/_visible-text.d.ts +19 -0
  16. package/dist/mcp-server/tools/definitions/_visible-text.d.ts.map +1 -0
  17. package/dist/mcp-server/tools/definitions/_visible-text.js +22 -0
  18. package/dist/mcp-server/tools/definitions/_visible-text.js.map +1 -0
  19. package/dist/mcp-server/tools/definitions/convert-ids.tool.d.ts +11 -4
  20. package/dist/mcp-server/tools/definitions/convert-ids.tool.d.ts.map +1 -1
  21. package/dist/mcp-server/tools/definitions/convert-ids.tool.js +1 -1
  22. package/dist/mcp-server/tools/definitions/convert-ids.tool.js.map +1 -1
  23. package/dist/mcp-server/tools/definitions/fetch-articles.tool.d.ts +20 -7
  24. package/dist/mcp-server/tools/definitions/fetch-articles.tool.d.ts.map +1 -1
  25. package/dist/mcp-server/tools/definitions/fetch-articles.tool.js +40 -5
  26. package/dist/mcp-server/tools/definitions/fetch-articles.tool.js.map +1 -1
  27. package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.d.ts +11 -4
  28. package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.d.ts.map +1 -1
  29. package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.js +18 -1
  30. package/dist/mcp-server/tools/definitions/fetch-fulltext.tool.js.map +1 -1
  31. package/dist/mcp-server/tools/definitions/find-related.tool.d.ts.map +1 -1
  32. package/dist/mcp-server/tools/definitions/find-related.tool.js +39 -10
  33. package/dist/mcp-server/tools/definitions/find-related.tool.js.map +1 -1
  34. package/dist/mcp-server/tools/definitions/format-citations.tool.d.ts +11 -4
  35. package/dist/mcp-server/tools/definitions/format-citations.tool.d.ts.map +1 -1
  36. package/dist/mcp-server/tools/definitions/lookup-citation.tool.d.ts +16 -15
  37. package/dist/mcp-server/tools/definitions/lookup-citation.tool.d.ts.map +1 -1
  38. package/dist/mcp-server/tools/definitions/lookup-citation.tool.js +40 -22
  39. package/dist/mcp-server/tools/definitions/lookup-citation.tool.js.map +1 -1
  40. package/dist/mcp-server/tools/definitions/lookup-mesh.tool.d.ts +13 -6
  41. package/dist/mcp-server/tools/definitions/lookup-mesh.tool.d.ts.map +1 -1
  42. package/dist/mcp-server/tools/definitions/lookup-mesh.tool.js +8 -8
  43. package/dist/mcp-server/tools/definitions/lookup-mesh.tool.js.map +1 -1
  44. package/dist/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.d.ts +2 -2
  45. package/dist/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.d.ts.map +1 -1
  46. package/dist/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.js +1 -1
  47. package/dist/mcp-server/tools/definitions/pubmed-europepmc-fetch.tool.js.map +1 -1
  48. package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.d.ts +19 -5
  49. package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.d.ts.map +1 -1
  50. package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.js +37 -7
  51. package/dist/mcp-server/tools/definitions/pubmed-europepmc-search.tool.js.map +1 -1
  52. package/dist/mcp-server/tools/definitions/search-articles.tool.d.ts +40 -18
  53. package/dist/mcp-server/tools/definitions/search-articles.tool.d.ts.map +1 -1
  54. package/dist/mcp-server/tools/definitions/search-articles.tool.js +193 -43
  55. package/dist/mcp-server/tools/definitions/search-articles.tool.js.map +1 -1
  56. package/dist/mcp-server/tools/definitions/spell-check.tool.d.ts +13 -6
  57. package/dist/mcp-server/tools/definitions/spell-check.tool.d.ts.map +1 -1
  58. package/dist/mcp-server/tools/definitions/spell-check.tool.js +8 -8
  59. package/dist/mcp-server/tools/definitions/spell-check.tool.js.map +1 -1
  60. package/dist/services/error-contracts.d.ts +42 -71
  61. package/dist/services/error-contracts.d.ts.map +1 -1
  62. package/dist/services/error-contracts.js +43 -75
  63. package/dist/services/error-contracts.js.map +1 -1
  64. package/dist/services/europe-pmc/api-client.d.ts +8 -2
  65. package/dist/services/europe-pmc/api-client.d.ts.map +1 -1
  66. package/dist/services/europe-pmc/api-client.js +13 -8
  67. package/dist/services/europe-pmc/api-client.js.map +1 -1
  68. package/dist/services/europe-pmc/europe-pmc-service.d.ts +43 -14
  69. package/dist/services/europe-pmc/europe-pmc-service.d.ts.map +1 -1
  70. package/dist/services/europe-pmc/europe-pmc-service.js +165 -85
  71. package/dist/services/europe-pmc/europe-pmc-service.js.map +1 -1
  72. package/dist/services/europe-pmc/request-queue.d.ts +11 -27
  73. package/dist/services/europe-pmc/request-queue.d.ts.map +1 -1
  74. package/dist/services/europe-pmc/request-queue.js +17 -104
  75. package/dist/services/europe-pmc/request-queue.js.map +1 -1
  76. package/dist/services/europe-pmc/types.d.ts +6 -1
  77. package/dist/services/europe-pmc/types.d.ts.map +1 -1
  78. package/dist/services/ncbi/api-client.d.ts.map +1 -1
  79. package/dist/services/ncbi/api-client.js +2 -3
  80. package/dist/services/ncbi/api-client.js.map +1 -1
  81. package/dist/services/ncbi/ncbi-service.d.ts +2 -1
  82. package/dist/services/ncbi/ncbi-service.d.ts.map +1 -1
  83. package/dist/services/ncbi/ncbi-service.js +67 -20
  84. package/dist/services/ncbi/ncbi-service.js.map +1 -1
  85. package/dist/services/ncbi/parsing/article-parser.d.ts +15 -1
  86. package/dist/services/ncbi/parsing/article-parser.d.ts.map +1 -1
  87. package/dist/services/ncbi/parsing/article-parser.js +29 -0
  88. package/dist/services/ncbi/parsing/article-parser.js.map +1 -1
  89. package/dist/services/ncbi/response-handler.d.ts.map +1 -1
  90. package/dist/services/ncbi/response-handler.js +22 -19
  91. package/dist/services/ncbi/response-handler.js.map +1 -1
  92. package/dist/services/ncbi/types.d.ts +33 -0
  93. package/dist/services/ncbi/types.d.ts.map +1 -1
  94. package/dist/services/openalex/api-client.d.ts.map +1 -1
  95. package/dist/services/openalex/api-client.js +6 -7
  96. package/dist/services/openalex/api-client.js.map +1 -1
  97. package/dist/services/openalex/openalex-service.d.ts +11 -1
  98. package/dist/services/openalex/openalex-service.d.ts.map +1 -1
  99. package/dist/services/openalex/openalex-service.js +18 -11
  100. package/dist/services/openalex/openalex-service.js.map +1 -1
  101. package/dist/services/unpaywall/unpaywall-service.d.ts.map +1 -1
  102. package/dist/services/unpaywall/unpaywall-service.js +1 -3
  103. package/dist/services/unpaywall/unpaywall-service.js.map +1 -1
  104. package/package.json +6 -5
  105. package/server.json +3 -3
@@ -7,9 +7,17 @@
7
7
  * from the same `ORDERED_XML_PARSER_OPTIONS` NCBI's ordered parser uses, so
8
8
  * `parsePmcArticle` consumes the result without modification.
9
9
  *
10
+ * Every call runs as a retry loop around the shared request queue: each attempt
11
+ * re-enters the queue and waits out its start gap, and a backoff sleep holds no
12
+ * concurrency slot, so callers backing off never stall the calls behind them.
13
+ *
10
14
  * A search's retry boundary covers fetch and response classification, so
11
15
  * Europe PMC's intermittent empty `{ version }` envelope is retried like an
12
16
  * HTTP outage; only a sort or cursor that explains it is reported as bad input.
17
+ * Europe PMC answers an unreadable cursor with the HTTP 503 it uses for an
18
+ * outage, so a 503 on a caller-supplied cursor is checked against the first
19
+ * page of the same query, and the cursor is blamed only when a retry draws
20
+ * the 503 again while that first page was served.
13
21
  * A search reports the effective query Europe PMC echoes back, or — with no
14
22
  * echo — the source-filtered query it sent.
15
23
  *
@@ -19,9 +27,9 @@
19
27
  *
20
28
  * @module src/services/europe-pmc/europe-pmc-service
21
29
  */
30
+ import { type Pacer } from '@cyanheads/mcp-ts-core/utils';
22
31
  import type { JatsNode } from '../ncbi/parsing/pmc-xml-helpers.js';
23
32
  import { EuropePmcApiClient } from './api-client.js';
24
- import { EuropePmcRequestQueue } from './request-queue.js';
25
33
  import type { EuropePmcFullTextResult, EuropePmcRecordRef, EuropePmcRelatedResult, EuropePmcSearchHit, EuropePmcSearchParams, EuropePmcSearchResult, EuropePmcSource } from './types.js';
26
34
  /**
27
35
  * Facade over the Europe PMC REST API:
@@ -31,14 +39,15 @@ import type { EuropePmcFullTextResult, EuropePmcRecordRef, EuropePmcRelatedResul
31
39
  * - `citations()` / `references()` — EPMC's link graph for a PubMed article.
32
40
  *
33
41
  * All honor `ctx.signal` for cancellation and retry transient failures with
34
- * capped exponential backoff plus jitter.
42
+ * capped exponential backoff plus jitter, each attempt paced through the shared
43
+ * request queue.
35
44
  */
36
45
  export declare class EuropePmcService {
37
46
  private readonly client;
38
47
  private readonly queue;
39
48
  private readonly maxRetries;
40
49
  private readonly orderedXmlParser;
41
- constructor(client: EuropePmcApiClient, queue: EuropePmcRequestQueue, maxRetries: number);
50
+ constructor(client: EuropePmcApiClient, queue: Pacer, maxRetries: number);
42
51
  /**
43
52
  * Search Europe PMC. Cursor-based pagination — pass `cursorMark: '*'` (or
44
53
  * omit) for the first page; pass the returned `nextCursorMark` for the next.
@@ -46,12 +55,26 @@ export declare class EuropePmcService {
46
55
  * The retry boundary covers the fetch and the response classification
47
56
  * together, so an empty envelope retries like any other transient failure
48
57
  * rather than surfacing after the loop has already returned. (#159)
58
+ *
59
+ * The first HTTP 503 on a caller-supplied cursor draws one probe of the same
60
+ * query's first page, and the cursor is retried either way: one 503 is not
61
+ * enough to tell a bad cursor from a transient outage. A later 503 fails the
62
+ * search at once as non-retryable input only when that probe was served;
63
+ * otherwise it goes on through the ordinary retry path. A 503 with no retry
64
+ * left is never probed, since nothing could use the answer. (#180)
49
65
  */
50
66
  search(params: EuropePmcSearchParams): Promise<EuropePmcSearchResult>;
67
+ /**
68
+ * Whether Europe PMC serves the first page of the search in `params`: one
69
+ * request (`cursorMark: '*'`, `pageSize: 1`), paced like any other, with no
70
+ * retries of its own. Any failure reads as not served — except the caller's
71
+ * cancellation, which propagates.
72
+ */
73
+ private firstPageServed;
51
74
  /**
52
75
  * One search attempt: fetch, parse, and classify the body. `isLastAttempt`
53
- * lets an empty envelope that has persisted through the whole retry budget
54
- * be attributed to a caller-supplied cursor.
76
+ * lets an empty envelope on the last attempt the retry budget allows be
77
+ * attributed to a caller-supplied cursor.
55
78
  */
56
79
  private searchOnce;
57
80
  /**
@@ -117,16 +140,22 @@ export declare class EuropePmcService {
117
140
  */
118
141
  parseFullTextXml(xml: string): JatsNode | undefined;
119
142
  /**
120
- * Retry wrapper for transient errors. Mirrors NCBI's `withRetry` minus the
121
- * service-level deadline — EPMC requests are cheaper individually and the
122
- * caller (typically `ctx.signal`) bounds the total chain. `execute` receives
123
- * the zero-based attempt index. On exhaustion the last error keeps its code
124
- * and an upstream `retryAfter`, so a 429 still tells the caller how long to
125
- * wait. Only a `ServiceUnavailable` gains `europepmc_unreachable` and its hint;
126
- * a `Timeout` or `RateLimited` keeps its code with no reason, as the NCBI
127
- * service reports them.
143
+ * Runs one Europe PMC call: a retry loop around the shared request queue, so
144
+ * every attempt re-queues and is re-paced, and a backoff sleep holds no queue
145
+ * slot. No service-level deadline — Europe PMC requests are cheap individually
146
+ * and the caller's signal (typically `ctx.signal`) bounds the total chain; that
147
+ * signal reaches the queue wait and the backoff sleep. `execute` receives the
148
+ * one-based attempt number.
149
+ *
150
+ * `reclassify`, when given, sees each failed attempt after its queue slot is
151
+ * released and before the retry decision, with the attempt's signal and its
152
+ * one-based number. The error it returns is the one the loop judges, so it
153
+ * can end the retries by returning a non-transient error.
154
+ *
155
+ * A caller abort rethrows the caller's own reason; an exhausted failure is
156
+ * reshaped by {@link toServiceError}, after the loop.
128
157
  */
129
- private withRetry;
158
+ private runPaced;
130
159
  }
131
160
  /**
132
161
  * Initialize the Europe PMC service when enabled. Safe to call regardless of
@@ -1 +1 @@
1
- {"version":3,"file":"europe-pmc-service.d.ts","sourceRoot":"","sources":["../../../src/services/europe-pmc/europe-pmc-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAiBH,OAAO,KAAK,EAAE,QAAQ,EAAgB,MAAM,4CAA4C,CAAC;AAEzF,OAAO,EAAoB,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EACV,uBAAuB,EAEvB,kBAAkB,EAElB,sBAAsB,EACtB,kBAAkB,EAClB,qBAAqB,EAErB,qBAAqB,EACrB,eAAe,EAChB,MAAM,YAAY,CAAC;AAqEpB;;;;;;;;;GASG;AACH,qBAAa,gBAAgB;IAIzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAL7B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAY;IAE7C,YACmB,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE,qBAAqB,EAC5B,UAAU,EAAE,MAAM,EAQpC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAWpE;IAED;;;;OAIG;YACW,UAAU;IAwHxB;;;;;;;;;;OAUG;IACG,YAAY,CAChB,IAAI,EAAE,SAAS,kBAAkB,EAAE,EACnC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAQ/B;IAED;;;;;;;OAOG;IACG,WAAW,CACf,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,uBAAuB,CAAC,CAgBlC;IAED;;;;;;;;;;OAUG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,sBAAsB,CAAC,CAQjC;IAED;;;;;;;;;;OAUG;IACH,UAAU,CACR,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,sBAAsB,CAAC,CAQjC;IAED;;;;;OAKG;YACW,iBAAiB;IAsE/B;;;;;;;;OAQG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CA8BlD;IAED;;;;;;;;;OASG;YACW,SAAS;CAkDxB;AAMD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAyB3C;AAED,6EAA6E;AAC7E,wBAAgB,mBAAmB,IAAI,gBAAgB,GAAG,SAAS,CAElE"}
1
+ {"version":3,"file":"europe-pmc-service.d.ts","sourceRoot":"","sources":["../../../src/services/europe-pmc/europe-pmc-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AASH,OAAO,EAGL,KAAK,KAAK,EAGX,MAAM,8BAA8B,CAAC;AAMtC,OAAO,KAAK,EAAE,QAAQ,EAAgB,MAAM,4CAA4C,CAAC;AAEzF,OAAO,EAAoB,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEvE,OAAO,KAAK,EACV,uBAAuB,EAEvB,kBAAkB,EAElB,sBAAsB,EACtB,kBAAkB,EAClB,qBAAqB,EAErB,qBAAqB,EACrB,eAAe,EAChB,MAAM,YAAY,CAAC;AAsGpB;;;;;;;;;;GAUG;AACH,qBAAa,gBAAgB;IAIzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAL7B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAY;IAE7C,YACmB,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,MAAM,EAQpC;IAED;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA+BpE;IAED;;;;;OAKG;YACW,eAAe;IAgB7B;;;;OAIG;YACW,UAAU;IAyHxB;;;;;;;;;;OAUG;IACG,YAAY,CAChB,IAAI,EAAE,SAAS,kBAAkB,EAAE,EACnC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAQ/B;IAED;;;;;;;OAOG;IACG,WAAW,CACf,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,uBAAuB,CAAC,CASlC;IAED;;;;;;;;;;OAUG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,sBAAsB,CAAC,CAQjC;IAED;;;;;;;;;;OAUG;IACH,UAAU,CACR,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,sBAAsB,CAAC,CAQjC;IAED;;;;;OAKG;YACW,iBAAiB;IAkE/B;;;;;;;;OAQG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CA4BlD;IAED;;;;;;;;;;;;;;;OAeG;YACW,QAAQ;CA8CvB;AAMD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAyB3C;AAED,6EAA6E;AAC7E,wBAAgB,mBAAmB,IAAI,gBAAgB,GAAG,SAAS,CAElE"}
@@ -7,9 +7,17 @@
7
7
  * from the same `ORDERED_XML_PARSER_OPTIONS` NCBI's ordered parser uses, so
8
8
  * `parsePmcArticle` consumes the result without modification.
9
9
  *
10
+ * Every call runs as a retry loop around the shared request queue: each attempt
11
+ * re-enters the queue and waits out its start gap, and a backoff sleep holds no
12
+ * concurrency slot, so callers backing off never stall the calls behind them.
13
+ *
10
14
  * A search's retry boundary covers fetch and response classification, so
11
15
  * Europe PMC's intermittent empty `{ version }` envelope is retried like an
12
16
  * HTTP outage; only a sort or cursor that explains it is reported as bad input.
17
+ * Europe PMC answers an unreadable cursor with the HTTP 503 it uses for an
18
+ * outage, so a 503 on a caller-supplied cursor is checked against the first
19
+ * page of the same query, and the cursor is blamed only when a retry draws
20
+ * the 503 again while that first page was served.
13
21
  * A search reports the effective query Europe PMC echoes back, or — with no
14
22
  * echo — the source-filtered query it sent.
15
23
  *
@@ -19,33 +27,45 @@
19
27
  *
20
28
  * @module src/services/europe-pmc/europe-pmc-service
21
29
  */
22
- import { internalError, JsonRpcErrorCode, McpError, serializationError, serviceUnavailable, validationError, } from '@cyanheads/mcp-ts-core/errors';
23
- import { defaultIsTransient, logger, requestContextService } from '@cyanheads/mcp-ts-core/utils';
30
+ import { JsonRpcErrorCode, McpError, serializationError, serviceUnavailable, validationError, } from '@cyanheads/mcp-ts-core/errors';
31
+ import { defaultIsTransient, logger, requestContextService, withRetry, } from '@cyanheads/mcp-ts-core/utils';
24
32
  // biome-ignore lint/suspicious/noDeprecatedImports: staying on in-tree XMLValidator — see ncbi/response-handler.ts
25
33
  import { XMLParser, XMLValidator } from 'fast-xml-parser';
26
34
  import { getServerConfig } from '../../config/server-config.js';
27
- import { recoveryFor } from '../error-contracts.js';
28
35
  import { ORDERED_XML_PARSER_OPTIONS } from '../ncbi/parsing/ordered-xml-parser-options.js';
29
36
  import { ensureArray } from '../ncbi/parsing/xml-helpers.js';
30
37
  import { buildSearchQuery, EuropePmcApiClient } from './api-client.js';
31
- import { EuropePmcRequestQueue } from './request-queue.js';
38
+ import { createEuropePmcRequestQueue } from './request-queue.js';
39
+ /** Ceiling on one backoff sleep, so a high retry count cannot grow it without bound. */
32
40
  const MAX_BACKOFF_MS = 30_000;
33
- function abortableSleep(ms, signal) {
34
- if (!signal)
35
- return new Promise((r) => setTimeout(r, ms));
36
- if (signal.aborted)
37
- return Promise.reject(signal.reason);
38
- return new Promise((resolve, reject) => {
39
- const onAbort = () => {
40
- clearTimeout(timer);
41
- reject(signal.reason);
42
- };
43
- const timer = setTimeout(() => {
44
- signal.removeEventListener('abort', onAbort);
45
- resolve();
46
- }, ms);
47
- signal.addEventListener('abort', onAbort, { once: true });
48
- });
41
+ /**
42
+ * Retry gate: the framework's transient set, narrowed to `McpError`s. The client
43
+ * classifies every upstream failure, so a plain `Error` reaching the loop is a defect
44
+ * or a response that cannot parse — retrying it only repeats it.
45
+ */
46
+ const isTransient = (error) => error instanceof McpError && defaultIsTransient(error);
47
+ /**
48
+ * Reshapes an error whose retries ran out: the last attempt's code and message with
49
+ * the attempt count appended, `label`, `attempts`, and the upstream `retryAfter`, so a
50
+ * 429 still tells the caller how long to wait. Only a `ServiceUnavailable` gains
51
+ * `europepmc_unreachable`; a `Timeout` or `RateLimited` keeps its code with no
52
+ * reason, as the OpenAlex service reports them. Anything never retried — a
53
+ * non-transient failure, or a `Retry-After` longer than the backoff cap — passes
54
+ * through unchanged.
55
+ */
56
+ function toServiceError(error, label) {
57
+ if (!(error instanceof McpError) || typeof error.data?.retryAttempts !== 'number')
58
+ return error;
59
+ const last = error.cause instanceof McpError ? error.cause : error;
60
+ const attempts = error.data.retryAttempts;
61
+ return new McpError(error.code, `${last.message} (failed after ${attempts} attempt${attempts === 1 ? '' : 's'})`, {
62
+ ...(error.code === JsonRpcErrorCode.ServiceUnavailable && {
63
+ reason: 'europepmc_unreachable',
64
+ }),
65
+ label,
66
+ attempts,
67
+ ...(last.data?.retryAfter !== undefined && { retryAfter: last.data.retryAfter }),
68
+ }, { cause: last });
49
69
  }
50
70
  /**
51
71
  * Europe PMC lookup clause for one record addressed by `source` + EPMC id.
@@ -69,6 +89,15 @@ function recordLookupQuery({ epmcId, source }) {
69
89
  const extIdClause = `(EXT_ID:${epmcId} AND SRC:${source})`;
70
90
  return source === 'PMC' ? `${extIdClause} OR (PMCID:${epmcId})` : extIdClause;
71
91
  }
92
+ /**
93
+ * The caller's cursor when it asks for a page past the first. `*` and an
94
+ * exactly-empty cursor both read as the first page upstream.
95
+ */
96
+ function callerCursor({ cursorMark }) {
97
+ return cursorMark && cursorMark !== '*' ? cursorMark : undefined;
98
+ }
99
+ /** Next step for a cursor Europe PMC cannot read, whichever way it signals that. */
100
+ const CURSOR_RECOVERY_HINT = "Pass the previous response's `nextCursorMark` verbatim as `cursorMark`, or `*` to restart from the first page.";
72
101
  /** The sort fields Europe PMC documents. */
73
102
  const DOCUMENTED_SORT_FIELDS = new Set(['P_PDATE_D', 'CITED', 'AUTH_FIRST', 'PUB_YEAR']);
74
103
  /**
@@ -99,7 +128,8 @@ function sortExplainsEnvelope(sort) {
99
128
  * - `citations()` / `references()` — EPMC's link graph for a PubMed article.
100
129
  *
101
130
  * All honor `ctx.signal` for cancellation and retry transient failures with
102
- * capped exponential backoff plus jitter.
131
+ * capped exponential backoff plus jitter, each attempt paced through the shared
132
+ * request queue.
103
133
  */
104
134
  export class EuropePmcService {
105
135
  client;
@@ -124,14 +154,60 @@ export class EuropePmcService {
124
154
  * The retry boundary covers the fetch and the response classification
125
155
  * together, so an empty envelope retries like any other transient failure
126
156
  * rather than surfacing after the loop has already returned. (#159)
157
+ *
158
+ * The first HTTP 503 on a caller-supplied cursor draws one probe of the same
159
+ * query's first page, and the cursor is retried either way: one 503 is not
160
+ * enough to tell a bad cursor from a transient outage. A later 503 fails the
161
+ * search at once as non-retryable input only when that probe was served;
162
+ * otherwise it goes on through the ordinary retry path. A 503 with no retry
163
+ * left is never probed, since nothing could use the answer. (#180)
127
164
  */
128
165
  search(params) {
129
- return this.queue.enqueue(() => this.withRetry((attempt) => this.searchOnce(params, attempt === this.maxRetries), 'search', params.signal), 'search', params.signal);
166
+ const cursorMark = callerCursor(params);
167
+ let firstPage = 'unknown';
168
+ return this.runPaced('search', params.signal, (attempt) => this.searchOnce(params, attempt === this.maxRetries + 1), cursorMark === undefined
169
+ ? undefined
170
+ : async (error, signal, attempt) => {
171
+ if (!(error instanceof McpError) || error.data?.status !== 503)
172
+ return error;
173
+ if (firstPage === 'unknown') {
174
+ if (attempt <= this.maxRetries) {
175
+ firstPage = (await this.firstPageServed(params, signal)) ? 'served' : 'failed';
176
+ }
177
+ return error;
178
+ }
179
+ if (firstPage === 'failed')
180
+ return error;
181
+ return validationError(`Europe PMC answered cursorMark "${cursorMark}" with HTTP 503 twice but served the first page of the same query — the cursor is most likely invalid or expired.`, {
182
+ reason: 'europepmc_invalid_input',
183
+ cursorMark,
184
+ status: 503,
185
+ retryable: false,
186
+ recovery: { hint: CURSOR_RECOVERY_HINT },
187
+ }, { cause: error });
188
+ });
189
+ }
190
+ /**
191
+ * Whether Europe PMC serves the first page of the search in `params`: one
192
+ * request (`cursorMark: '*'`, `pageSize: 1`), paced like any other, with no
193
+ * retries of its own. Any failure reads as not served — except the caller's
194
+ * cancellation, which propagates.
195
+ */
196
+ async firstPageServed(params, signal) {
197
+ try {
198
+ await this.queue.run(() => this.searchOnce({ ...params, cursorMark: '*', pageSize: 1, signal }, false), { signal });
199
+ return true;
200
+ }
201
+ catch (error) {
202
+ if (signal.aborted)
203
+ throw error;
204
+ return false;
205
+ }
130
206
  }
131
207
  /**
132
208
  * One search attempt: fetch, parse, and classify the body. `isLastAttempt`
133
- * lets an empty envelope that has persisted through the whole retry budget
134
- * be attributed to a caller-supplied cursor.
209
+ * lets an empty envelope on the last attempt the retry budget allows be
210
+ * attributed to a caller-supplied cursor.
135
211
  */
136
212
  async searchOnce(params, isLastAttempt) {
137
213
  const text = await this.client.search(params);
@@ -143,7 +219,6 @@ export class EuropePmcService {
143
219
  throw serializationError('Failed to parse Europe PMC search JSON response.', {
144
220
  reason: 'europepmc_invalid_response',
145
221
  responseSnippet: text.substring(0, 200),
146
- ...recoveryFor('europepmc_invalid_response'),
147
222
  }, { cause: error });
148
223
  }
149
224
  /**
@@ -155,6 +230,7 @@ export class EuropePmcService {
155
230
  if (errMsg) {
156
231
  throw validationError(`Europe PMC rejected the request: ${errMsg}`, {
157
232
  reason: 'europepmc_invalid_input',
233
+ retryable: false,
158
234
  epmcErrCode: parsed.errCode,
159
235
  epmcErrMsg: errMsg,
160
236
  recovery: { hint: `Europe PMC reported: "${errMsg}". Fix the input and retry.` },
@@ -168,25 +244,28 @@ export class EuropePmcService {
168
244
  *
169
245
  * - A sort that EPMC rejects every time (see `sortExplainsEnvelope`) fails
170
246
  * fast as non-retryable input — retrying only adds backoff.
171
- * - A non-default cursor that draws it on every attempt is most likely
172
- * invalid or expired; EPMC rejects a malformed cursor every time.
247
+ * - A non-default cursor that draws it on the last attempt the retry budget
248
+ * allows is most likely invalid or expired; EPMC rejects a malformed
249
+ * cursor every time. Earlier attempts may have failed another way.
173
250
  * - Otherwise it is intermittent upstream noise — valid requests, with or
174
251
  * without a documented sort, draw it on a fraction of calls and succeed
175
252
  * when repeated — so it is thrown as a transient `europepmc_unreachable`
176
253
  * for the retry loop, and never names the caller's input. (#159)
177
254
  *
178
255
  * Each throw keeps the diagnosis (message) apart from the next step
179
- * (recovery hint): the framework mirrors `data.recovery.hint` into
180
- * `content[]`, and one string passed as both renders byte-identical
181
- * Error:/Recovery: blocks. (#75)
256
+ * (recovery hint): the framework renders `data.recovery.hint` in
257
+ * `content[]` as a `Recovery:` line only when the message does not already
258
+ * contain it, so one string passed as both would leave the caller the
259
+ * diagnosis and no separate next step. (#75)
182
260
  */
183
261
  if (parsed.hitCount === undefined &&
184
262
  parsed.request === undefined &&
185
263
  parsed.resultList === undefined) {
186
- const cursorMark = params.cursorMark && params.cursorMark !== '*' ? params.cursorMark : undefined;
264
+ const cursorMark = callerCursor(params);
187
265
  if (params.sort && sortExplainsEnvelope(params.sort)) {
188
266
  throw validationError(`Europe PMC silently rejected the request — most likely the sort "${params.sort}", which needs a documented field and an asc/desc direction.`, {
189
267
  reason: 'europepmc_invalid_input',
268
+ retryable: false,
190
269
  sort: params.sort,
191
270
  ...(cursorMark && { cursorMark }),
192
271
  responseSnippet: text.substring(0, 200),
@@ -196,16 +275,15 @@ export class EuropePmcService {
196
275
  });
197
276
  }
198
277
  if (cursorMark && isLastAttempt) {
199
- throw validationError(`Europe PMC answered every attempt for cursorMark "${cursorMark}" with an empty response — the cursor is most likely invalid or expired.`, {
278
+ throw validationError(`Europe PMC answered the last attempt for cursorMark "${cursorMark}" with an empty response — the cursor is most likely invalid or expired.`, {
200
279
  reason: 'europepmc_invalid_input',
280
+ retryable: false,
201
281
  cursorMark,
202
282
  responseSnippet: text.substring(0, 200),
203
- recovery: {
204
- hint: 'Restart from the first page with `cursorMark: "*"`, or pass the exact `nextCursorMark` from the previous response.',
205
- },
283
+ recovery: { hint: CURSOR_RECOVERY_HINT },
206
284
  });
207
285
  }
208
- throw serviceUnavailable('Europe PMC returned an empty response with no hit count or result list.', { reason: 'europepmc_unreachable', ...recoveryFor('europepmc_unreachable') });
286
+ throw serviceUnavailable('Europe PMC returned an empty response with no hit count or result list.', { reason: 'europepmc_unreachable' });
209
287
  }
210
288
  const hits = ensureArray(parsed.resultList?.result);
211
289
  // Without an echo, report the query actually sent — source filter included —
@@ -256,7 +334,7 @@ export class EuropePmcService {
256
334
  * publishes no fullTextXML (404 or empty body).
257
335
  */
258
336
  async fullTextXml(epmcId, source, signal) {
259
- const outcome = await this.queue.enqueue(() => this.withRetry(() => this.client.fullTextXml(epmcId, signal), `fullTextXml(${epmcId})`, signal), `fullTextXml(${epmcId})`, signal);
337
+ const outcome = await this.runPaced(`fullTextXml(${epmcId})`, signal, () => this.client.fullTextXml(epmcId, signal));
260
338
  if (outcome.kind === 'not-available') {
261
339
  return { kind: 'not-available', reason: outcome.reason };
262
340
  }
@@ -297,7 +375,7 @@ export class EuropePmcService {
297
375
  * upstream row count and the PubMed-addressable set they actually get back.
298
376
  */
299
377
  async fetchRelatedLinks(fetch, kind, pmid, extractRecords, signal) {
300
- const text = await this.queue.enqueue(() => this.withRetry(fetch, `${kind}(${pmid})`, signal), `${kind}(${pmid})`, signal);
378
+ const text = await this.runPaced(`${kind}(${pmid})`, signal, fetch);
301
379
  let parsed;
302
380
  try {
303
381
  parsed = JSON.parse(text);
@@ -306,7 +384,6 @@ export class EuropePmcService {
306
384
  throw serializationError(`Failed to parse Europe PMC ${kind} JSON response.`, {
307
385
  reason: 'europepmc_invalid_response',
308
386
  responseSnippet: text.substring(0, 200),
309
- ...recoveryFor('europepmc_invalid_response'),
310
387
  }, { cause: error });
311
388
  }
312
389
  /**
@@ -319,6 +396,7 @@ export class EuropePmcService {
319
396
  if (errMsg) {
320
397
  throw validationError(`Europe PMC rejected the ${kind} request: ${errMsg}`, {
321
398
  reason: 'europepmc_invalid_input',
399
+ retryable: false,
322
400
  epmcErrCode: parsed.errCode,
323
401
  epmcErrMsg: errMsg,
324
402
  recovery: { hint: `Europe PMC reported: "${errMsg}". Fix the input and retry.` },
@@ -363,7 +441,6 @@ export class EuropePmcService {
363
441
  throw serializationError('Received invalid XML from Europe PMC.', {
364
442
  reason: 'europepmc_invalid_response',
365
443
  responseSnippet: xml.substring(0, 200),
366
- ...recoveryFor('europepmc_invalid_response'),
367
444
  });
368
445
  }
369
446
  let parsed;
@@ -376,7 +453,6 @@ export class EuropePmcService {
376
453
  reason: 'europepmc_invalid_response',
377
454
  parserError,
378
455
  responseSnippet: xml.substring(0, 200),
379
- ...recoveryFor('europepmc_invalid_response'),
380
456
  }, { cause: error });
381
457
  }
382
458
  if (!Array.isArray(parsed))
@@ -385,53 +461,57 @@ export class EuropePmcService {
385
461
  return nodes.find((n) => 'article' in n);
386
462
  }
387
463
  /**
388
- * Retry wrapper for transient errors. Mirrors NCBI's `withRetry` minus the
389
- * service-level deadline — EPMC requests are cheaper individually and the
390
- * caller (typically `ctx.signal`) bounds the total chain. `execute` receives
391
- * the zero-based attempt index. On exhaustion the last error keeps its code
392
- * and an upstream `retryAfter`, so a 429 still tells the caller how long to
393
- * wait. Only a `ServiceUnavailable` gains `europepmc_unreachable` and its hint;
394
- * a `Timeout` or `RateLimited` keeps its code with no reason, as the NCBI
395
- * service reports them.
464
+ * Runs one Europe PMC call: a retry loop around the shared request queue, so
465
+ * every attempt re-queues and is re-paced, and a backoff sleep holds no queue
466
+ * slot. No service-level deadline — Europe PMC requests are cheap individually
467
+ * and the caller's signal (typically `ctx.signal`) bounds the total chain; that
468
+ * signal reaches the queue wait and the backoff sleep. `execute` receives the
469
+ * one-based attempt number.
470
+ *
471
+ * `reclassify`, when given, sees each failed attempt after its queue slot is
472
+ * released and before the retry decision, with the attempt's signal and its
473
+ * one-based number. The error it returns is the one the loop judges, so it
474
+ * can end the retries by returning a non-transient error.
475
+ *
476
+ * A caller abort rethrows the caller's own reason; an exhausted failure is
477
+ * reshaped by {@link toServiceError}, after the loop.
396
478
  */
397
- async withRetry(execute, label, signal) {
398
- for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
479
+ async runPaced(label, signal, execute, reclassify) {
480
+ let attempt = 0;
481
+ try {
482
+ return await withRetry(({ signal: attemptSignal }) => {
483
+ const current = ++attempt;
484
+ return this.queue
485
+ .run(() => execute(current), { signal: attemptSignal })
486
+ .catch(async (failure) => {
487
+ const error = reclassify
488
+ ? await reclassify(failure, attemptSignal, current)
489
+ : failure;
490
+ if (current <= this.maxRetries && isTransient(error)) {
491
+ logger.warning(`Europe PMC ${label} failed on attempt ${current} of ${this.maxRetries + 1}.`, requestContextService.createRequestContext({
492
+ operation: 'EuropePmcRetry',
493
+ additionalContext: {
494
+ label,
495
+ attempt: current,
496
+ error: error instanceof Error ? error.message : String(error),
497
+ },
498
+ }));
499
+ }
500
+ throw error;
501
+ });
502
+ }, {
503
+ maxRetries: this.maxRetries,
504
+ maxDelayMs: MAX_BACKOFF_MS,
505
+ isTransient,
506
+ operation: `Europe PMC ${label}`,
507
+ ...(signal && { signal }),
508
+ });
509
+ }
510
+ catch (error) {
399
511
  if (signal?.aborted)
400
512
  throw signal.reason;
401
- try {
402
- return await execute(attempt);
403
- }
404
- catch (error) {
405
- if (signal?.aborted)
406
- throw signal.reason;
407
- if (!(error instanceof McpError))
408
- throw error;
409
- if (!defaultIsTransient(error))
410
- throw error;
411
- if (attempt < this.maxRetries) {
412
- const baseDelay = Math.min(1000 * 2 ** attempt, MAX_BACKOFF_MS);
413
- const jitter = baseDelay * (0.75 + 0.5 * Math.random());
414
- const retryDelay = Math.round(jitter);
415
- logger.warning(`Europe PMC ${label} failed. Retrying (${attempt + 1}/${this.maxRetries}) in ${retryDelay}ms.`, requestContextService.createRequestContext({
416
- operation: 'EuropePmcRetry',
417
- additionalContext: { label, attempt: attempt + 1, retryDelay },
418
- }));
419
- await abortableSleep(retryDelay, signal);
420
- continue;
421
- }
422
- const attempts = this.maxRetries + 1;
423
- throw new McpError(error.code, `${error.message} (failed after ${attempts} attempts)`, {
424
- ...(error.code === JsonRpcErrorCode.ServiceUnavailable && {
425
- reason: 'europepmc_unreachable',
426
- ...recoveryFor('europepmc_unreachable'),
427
- }),
428
- label,
429
- attempts,
430
- ...(error.data?.retryAfter !== undefined && { retryAfter: error.data.retryAfter }),
431
- }, { cause: error });
432
- }
513
+ throw toServiceError(error, label);
433
514
  }
434
- throw internalError('Europe PMC request failed after all retries.', { label });
435
515
  }
436
516
  }
437
517
  // ─── Init / Accessor ────────────────────────────────────────────────────────
@@ -451,7 +531,7 @@ export function initEuropePmcService() {
451
531
  timeoutMs: config.europepmcTimeoutMs,
452
532
  ...(config.europepmcEmail && { email: config.europepmcEmail }),
453
533
  });
454
- const queue = new EuropePmcRequestQueue(config.europepmcRequestDelayMs);
534
+ const queue = createEuropePmcRequestQueue(config.europepmcRequestDelayMs);
455
535
  _service = new EuropePmcService(client, queue, config.europepmcMaxRetries);
456
536
  logger.info('Europe PMC service initialized.', requestContextService.createRequestContext({
457
537
  operation: 'EuropePmcInit',
@@ -1 +1 @@
1
- {"version":3,"file":"europe-pmc-service.js","sourceRoot":"","sources":["../../../src/services/europe-pmc/europe-pmc-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"europe-pmc-service.js","sourceRoot":"","sources":["../../../src/services/europe-pmc/europe-pmc-service.ts"],"names":[],"mappings":"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"}
@@ -1,33 +1,17 @@
1
1
  /**
2
- * @fileoverview Rate-limited request scheduler for Europe PMC calls. Caps
3
- * concurrent in-flight requests and enforces a minimum start-gap between
4
- * dispatches to stay polite with EBI's infrastructure. Independent rate
5
- * domain from NCBI's queue — Europe PMC runs on a different host with its
6
- * own limits.
2
+ * @fileoverview Request queue for Europe PMC calls, built on the framework pacer.
3
+ * Caps concurrent in-flight requests and spaces request starts to stay polite with
4
+ * EBI's infrastructure, and releases a waiting caller the moment its signal aborts.
5
+ * Each retry attempt re-enters the queue, so a backoff sleep holds no slot and every
6
+ * attempt waits out the start gap. Independent rate domain from NCBI's queue —
7
+ * Europe PMC runs on a different host with its own limits.
7
8
  * @module src/services/europe-pmc/request-queue
8
9
  */
10
+ import { type Pacer } from '@cyanheads/mcp-ts-core/utils';
9
11
  /**
10
- * Schedules Europe PMC requests against two independent ceilings:
11
- *
12
- * - **Throughput** (`minStartGapMs`): minimum delay between two consecutive
13
- * dispatch times. Defaults to 200ms to be polite with EBI.
14
- * - **Concurrency** (`maxConcurrent`): maximum simultaneous in-flight
15
- * requests. Decouples concurrency from rate so slow upstream responses
16
- * don't block new dispatches.
17
- *
18
- * Enqueue accepts an optional `AbortSignal` so callers can bound their total
19
- * time inside the scheduler — when the signal fires, a still-waiting task
20
- * rejects immediately instead of sitting behind a saturated worker.
12
+ * Creates the pacer every Europe PMC call runs through. No queue-depth cap and no
13
+ * wait budget: a caller waits for its turn rather than being shed, so the pacer never
14
+ * rejects on its own — only the caller's signal ends a wait early.
21
15
  */
22
- export declare class EuropePmcRequestQueue {
23
- private readonly waiters;
24
- private readonly minStartGapMs;
25
- private readonly maxConcurrent;
26
- private inFlight;
27
- private lastStartTime;
28
- private nextDispatchTimer;
29
- constructor(minStartGapMs: number, maxConcurrent?: number);
30
- enqueue<T>(task: () => Promise<T>, label: string, signal?: AbortSignal): Promise<T>;
31
- private tryDispatch;
32
- }
16
+ export declare function createEuropePmcRequestQueue(minStartGapMs: number): Pacer;
33
17
  //# sourceMappingURL=request-queue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"request-queue.d.ts","sourceRoot":"","sources":["../../../src/services/europe-pmc/request-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAeH;;;;;;;;;;;;GAYG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,iBAAiB,CAA4C;IAErE,YAAY,aAAa,EAAE,MAAM,EAAE,aAAa,GAAE,MAA+B,EAGhF;IAED,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CA6BlF;IAED,OAAO,CAAC,WAAW;CAwDpB"}
1
+ {"version":3,"file":"request-queue.d.ts","sourceRoot":"","sources":["../../../src/services/europe-pmc/request-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAQvE;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,MAAM,GAAG,KAAK,CAExE"}