@mantra-ai/core 0.4.1 → 0.4.3

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 (34) hide show
  1. package/dist/discovery/ranking.d.ts +19 -3
  2. package/dist/discovery/ranking.d.ts.map +1 -1
  3. package/dist/discovery/ranking.js +54 -13
  4. package/dist/discovery/ranking.js.map +1 -1
  5. package/dist/discovery/registry.d.ts.map +1 -1
  6. package/dist/discovery/registry.js +4 -1
  7. package/dist/discovery/registry.js.map +1 -1
  8. package/dist/discovery/types.d.ts +7 -4
  9. package/dist/discovery/types.d.ts.map +1 -1
  10. package/dist/index.d.ts +6 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +8 -3
  13. package/dist/index.js.map +1 -1
  14. package/dist/sources/crossref/client.d.ts +70 -0
  15. package/dist/sources/crossref/client.d.ts.map +1 -1
  16. package/dist/sources/crossref/client.js +190 -3
  17. package/dist/sources/crossref/client.js.map +1 -1
  18. package/dist/sources/crossref/provider.d.ts +20 -0
  19. package/dist/sources/crossref/provider.d.ts.map +1 -0
  20. package/dist/sources/crossref/provider.js +39 -0
  21. package/dist/sources/crossref/provider.js.map +1 -0
  22. package/dist/sources/opencitations/citation-graph-provider.d.ts +28 -0
  23. package/dist/sources/opencitations/citation-graph-provider.d.ts.map +1 -0
  24. package/dist/sources/opencitations/citation-graph-provider.js +136 -0
  25. package/dist/sources/opencitations/citation-graph-provider.js.map +1 -0
  26. package/dist/sources/opencitations/client.d.ts +29 -0
  27. package/dist/sources/opencitations/client.d.ts.map +1 -0
  28. package/dist/sources/opencitations/client.js +108 -0
  29. package/dist/sources/opencitations/client.js.map +1 -0
  30. package/package.json +1 -1
  31. package/dist/sources/semantic-scholar/citation-graph-provider.d.ts +0 -19
  32. package/dist/sources/semantic-scholar/citation-graph-provider.d.ts.map +0 -1
  33. package/dist/sources/semantic-scholar/citation-graph-provider.js +0 -91
  34. package/dist/sources/semantic-scholar/citation-graph-provider.js.map +0 -1
@@ -6,15 +6,31 @@ import type { DiscoverCandidateCore, DiscoverSourceKind } from "./types";
6
6
  * - Mantra FTS: BM25 rank (negative float, lower = better match)
7
7
  * - Zotero: match-location score (negative int, e.g. -15 for title match)
8
8
  * - Semantic Scholar: position in relevance-ordered results (0-based index)
9
+ * - Crossref: raw relevance score (positive float, higher = better match)
9
10
  * - null score: treated as 0.5 (neutral)
10
11
  */
11
12
  export declare function normalizeScore(raw: number | null, sourceKind: DiscoverSourceKind, opts?: {
12
13
  resultCount?: number;
14
+ maxRawScore?: number;
13
15
  }): number;
14
16
  /**
15
- * Merge candidates from multiple sources.
16
- * Primary key: normalized DOI.
17
- * Secondary key: normalized title (for DOI-less papers, min 10 chars).
17
+ * Merge candidates from multiple sources into a deduplicated list.
18
+ *
19
+ * Dedup strategy:
20
+ * 1. DOI is the primary key: all candidates sharing the same normalized DOI
21
+ * are merged into one entry.
22
+ * 2. For DOI-less candidates, normalized title (≥10 chars) is the secondary key.
23
+ * Title-keyed entries that match a DOI-keyed entry are reconciled against it
24
+ * via a pre-built reverse index (normalizedTitle → doiKey), giving O(1)
25
+ * lookups instead of scanning byDoi for each title entry.
26
+ * 3. Candidates without a usable DOI or title fall into `unkeyed` and pass
27
+ * through unmerged.
28
+ *
29
+ * Invariants:
30
+ * - DOI dedup is always preferred over title dedup.
31
+ * - When multiple DOI-keyed entries share the same normalized title, the first
32
+ * encountered DOI candidate wins (Map insertion-order behavior).
33
+ * - Output order: [...byDoi.values(), ...unkeyed].
18
34
  */
19
35
  export declare function mergeCandidates(candidates: DiscoverCandidateCore[]): DiscoverCandidateCore[];
20
36
  export interface RankOpts {
@@ -1 +1 @@
1
- {"version":3,"file":"ranking.d.ts","sourceRoot":"","sources":["../../src/discovery/ranking.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAkBzE;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,GAAG,IAAI,EAClB,UAAU,EAAE,kBAAkB,EAC9B,IAAI,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9B,MAAM,CA+BR;AAiGD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,qBAAqB,EAAE,GAClC,qBAAqB,EAAE,CAiDzB;AAID,MAAM,WAAW,QAAQ;IACvB,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,qBAAqB,EAAE,EACnC,IAAI,CAAC,EAAE,QAAQ,GACd,qBAAqB,EAAE,CA0BzB"}
1
+ {"version":3,"file":"ranking.d.ts","sourceRoot":"","sources":["../../src/discovery/ranking.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAkBzE;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,GAAG,IAAI,EAClB,UAAU,EAAE,kBAAkB,EAC9B,IAAI,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACpD,MAAM,CAuCR;AAiGD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,qBAAqB,EAAE,GAClC,qBAAqB,EAAE,CAyDzB;AAID,MAAM,WAAW,QAAQ;IACvB,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,qBAAqB,EAAE,EACnC,IAAI,CAAC,EAAE,QAAQ,GACd,qBAAqB,EAAE,CAoCzB"}
@@ -15,6 +15,7 @@ const CITATION_SATURATION = 10_000;
15
15
  * - Mantra FTS: BM25 rank (negative float, lower = better match)
16
16
  * - Zotero: match-location score (negative int, e.g. -15 for title match)
17
17
  * - Semantic Scholar: position in relevance-ordered results (0-based index)
18
+ * - Crossref: raw relevance score (positive float, higher = better match)
18
19
  * - null score: treated as 0.5 (neutral)
19
20
  */
20
21
  export function normalizeScore(raw, sourceKind, opts) {
@@ -39,6 +40,14 @@ export function normalizeScore(raw, sourceKind, opts) {
39
40
  const count = opts?.resultCount ?? 20;
40
41
  return Math.min(1, raw / Math.max(1, count));
41
42
  }
43
+ case "crossref": {
44
+ // Crossref returns a positive relevance score (higher = better).
45
+ // Normalize as 1 - (score / maxScoreInBatch) so top result → ~0.
46
+ const max = opts?.maxRawScore;
47
+ if (max == null || max <= 0)
48
+ return 0.5;
49
+ return Math.max(0, Math.min(1, 1 - raw / max));
50
+ }
42
51
  default: {
43
52
  // Unknown source: assume raw is already roughly 0–1 or treat as neutral.
44
53
  if (raw >= 0 && raw <= 1)
@@ -131,9 +140,23 @@ function bestRawScore(a, b) {
131
140
  return Math.min(a, b);
132
141
  }
133
142
  /**
134
- * Merge candidates from multiple sources.
135
- * Primary key: normalized DOI.
136
- * Secondary key: normalized title (for DOI-less papers, min 10 chars).
143
+ * Merge candidates from multiple sources into a deduplicated list.
144
+ *
145
+ * Dedup strategy:
146
+ * 1. DOI is the primary key: all candidates sharing the same normalized DOI
147
+ * are merged into one entry.
148
+ * 2. For DOI-less candidates, normalized title (≥10 chars) is the secondary key.
149
+ * Title-keyed entries that match a DOI-keyed entry are reconciled against it
150
+ * via a pre-built reverse index (normalizedTitle → doiKey), giving O(1)
151
+ * lookups instead of scanning byDoi for each title entry.
152
+ * 3. Candidates without a usable DOI or title fall into `unkeyed` and pass
153
+ * through unmerged.
154
+ *
155
+ * Invariants:
156
+ * - DOI dedup is always preferred over title dedup.
157
+ * - When multiple DOI-keyed entries share the same normalized title, the first
158
+ * encountered DOI candidate wins (Map insertion-order behavior).
159
+ * - Output order: [...byDoi.values(), ...unkeyed].
137
160
  */
138
161
  export function mergeCandidates(candidates) {
139
162
  const byDoi = new Map();
@@ -166,17 +189,26 @@ export function mergeCandidates(candidates) {
166
189
  }
167
190
  unkeyed.push(c);
168
191
  }
169
- // Cross-check: title-keyed entries that also match a DOI-keyed entry
192
+ // Build a reverse index: normalizedTitle doi key for O(1) cross-check lookups.
193
+ // Preserves first-insertion semantics (first DOI candidate wins for duplicate normalized titles).
194
+ const doiByNormalizedTitle = new Map();
195
+ for (const [doiKey, doiCandidate] of byDoi) {
196
+ if (!doiCandidate.title)
197
+ continue;
198
+ const nt = normalizeTitle(doiCandidate.title);
199
+ if (!doiByNormalizedTitle.has(nt)) {
200
+ doiByNormalizedTitle.set(nt, doiKey);
201
+ }
202
+ }
203
+ // Cross-check: title-keyed entries that also match a DOI-keyed entry.
204
+ // O(1) lookup via the pre-built normalized-title index.
170
205
  for (const [titleKey, titleCandidate] of byTitle) {
171
- let merged = false;
172
- for (const [, doiCandidate] of byDoi) {
173
- if (doiCandidate.title && normalizeTitle(doiCandidate.title) === titleKey) {
174
- byDoi.set(doiCandidate.doi.toLowerCase(), mergeTwo(doiCandidate, titleCandidate));
175
- merged = true;
176
- break;
177
- }
206
+ const doiKey = doiByNormalizedTitle.get(titleKey);
207
+ if (doiKey !== undefined) {
208
+ const doiCandidate = byDoi.get(doiKey);
209
+ byDoi.set(doiKey, mergeTwo(doiCandidate, titleCandidate));
178
210
  }
179
- if (!merged) {
211
+ else {
180
212
  unkeyed.push(titleCandidate);
181
213
  }
182
214
  }
@@ -189,10 +221,19 @@ export function mergeCandidates(candidates) {
189
221
  * 3. Sort ascending (lower = better). Deterministic tiebreak by title.
190
222
  */
191
223
  export function rankCandidates(candidates, opts) {
224
+ // Pre-compute max raw score for Crossref candidates (Option B normalization)
225
+ const crossrefScores = candidates
226
+ .filter((c) => c.sources[0] === "crossref" && c.score != null)
227
+ .map((c) => c.score);
228
+ const crossrefMaxScore = crossrefScores.length > 0
229
+ ? Math.max(...crossrefScores)
230
+ : undefined;
192
231
  const scored = candidates.map((c) => {
193
232
  // Use the first source for normalization context
194
233
  const primarySource = c.sources[0] ?? "unknown";
195
- const normalized = normalizeScore(c.score, primarySource);
234
+ const normalized = normalizeScore(c.score, primarySource, {
235
+ maxRawScore: crossrefMaxScore,
236
+ });
196
237
  // Boosts are subtracted (lower = better)
197
238
  const finalScore = normalized -
198
239
  localBoost(c) -
@@ -1 +1 @@
1
- {"version":3,"file":"ranking.js","sourceRoot":"","sources":["../../src/discovery/ranking.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ranking.js","sourceRoot":"","sources":["../../src/discovery/ranking.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/discovery/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAA0B;IAE3C,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAI1C,4DAA4D;IAC5D,YAAY,CAAC,MAAM,CAAC,EAAE;QACpB,UAAU,CAAC,EAAE,kBAAkB,CAAC;QAChC,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,GAAG,gBAAgB,EAAE;IAetB;;;;;OAKG;IACG,SAAS,CACb,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,oBAAoB,CAAC;IA0ChC;;;;;OAKG;IACG,UAAU,CACd,UAAU,EAAE,qBAAqB,EAAE,GAClC,OAAO,CAAC;QAAE,UAAU,EAAE,qBAAqB,EAAE,CAAC;QAAC,MAAM,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC;CAoB7E"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/discovery/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAA0B;IAE3C,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAI1C,4DAA4D;IAC5D,YAAY,CAAC,MAAM,CAAC,EAAE;QACpB,UAAU,CAAC,EAAE,kBAAkB,CAAC;QAChC,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,GAAG,gBAAgB,EAAE;IAetB;;;;;OAKG;IACG,SAAS,CACb,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,oBAAoB,CAAC;IA6ChC;;;;;OAKG;IACG,UAAU,CACd,UAAU,EAAE,qBAAqB,EAAE,GAClC,OAAO,CAAC;QAAE,UAAU,EAAE,qBAAqB,EAAE,CAAC;QAAC,MAAM,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC;CAoB7E"}
@@ -28,9 +28,12 @@ export class ProviderRegistry {
28
28
  */
29
29
  async searchAll(query, opts) {
30
30
  const searchProviders = this.getProviders({ capability: "search" });
31
+ // localOnly and remoteOnly are mutually exclusive; localOnly takes precedence.
31
32
  const active = opts?.localOnly
32
33
  ? searchProviders.filter((p) => p.isLocal)
33
- : searchProviders;
34
+ : opts?.remoteOnly
35
+ ? searchProviders.filter((p) => !p.isLocal)
36
+ : searchProviders;
34
37
  const local = [];
35
38
  const remote = [];
36
39
  const errors = [];
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/discovery/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/discovery/registry.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@ export type DiscoverCapability = "search" | "augment";
10
10
  * Extensible source identifier.
11
11
  * Built-in kinds are listed here; providers may add new ones.
12
12
  */
13
- export type DiscoverSourceKind = "mantra" | "zotero" | "pdf-index" | "semantic-scholar" | "semantic-scholar-citation-graph" | (string & {});
13
+ export type DiscoverSourceKind = "mantra" | "zotero" | "pdf-index" | "semantic-scholar" | "crossref" | "opencitations-citation-graph" | (string & {});
14
14
  /**
15
15
  * Tracks which seed paper(s) led to a candidate during citation-graph expansion.
16
16
  */
@@ -41,11 +41,11 @@ export interface DiscoverCandidateCore {
41
41
  zoteroKey?: string | null;
42
42
  /** Resolved local PDF path — set by PDF index augmenter or Zotero. */
43
43
  pdfPath?: string | null;
44
- /** Semantic Scholar paper ID. */
44
+ /** Semantic Scholar paper ID (legacy, kept for backward compat). */
45
45
  semanticScholarId?: string | null;
46
- /** Total citation count. */
46
+ /** Total citation count (from Crossref is-referenced-by-count or S2). */
47
47
  citationCount?: number | null;
48
- /** Influential citation count (Semantic Scholar). */
48
+ /** Influential citation count (Semantic Scholar only, legacy). */
49
49
  influentialCitationCount?: number | null;
50
50
  /** Short abstract or snippet. */
51
51
  abstractSnippet?: string | null;
@@ -88,7 +88,10 @@ export interface DiscoverProvider {
88
88
  }
89
89
  export interface RegistrySearchOpts {
90
90
  limit?: number;
91
+ /** Only run local providers (Mantra, Zotero, PDF index). */
91
92
  localOnly?: boolean;
93
+ /** Only run remote providers (Crossref, citation graph, etc.). */
94
+ remoteOnly?: boolean;
92
95
  }
93
96
  export interface RegistrySearchResult {
94
97
  local: DiscoverCandidateCore[];
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/discovery/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,8BAA8B;AAC9B,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAItD;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,kBAAkB,GAClB,iCAAiC,GACjC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAIlB;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,QAAQ,EAAE,YAAY,GAAG,UAAU,CAAC;CACrC;AAID;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpB,mDAAmD;IACnD,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAE9B,mEAAmE;IACnE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAIrB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAIxB,iCAAiC;IACjC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,4BAA4B;IAC5B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,qDAAqD;IACrD,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,iCAAiC;IACjC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAIpB,mFAAmF;IACnF,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B;AAID,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,0CAA0C;IAC1C,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;IAExC,iCAAiC;IACjC,QAAQ,CAAC,YAAY,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAErD,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAEnF;;;;OAIG;IACH,OAAO,CAAC,CAAC,UAAU,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;CACjF;AAID,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAID,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC/B,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/discovery/types.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -22,8 +22,12 @@ export type { DiscoverCapability, DiscoverSourceKind, DiscoverCandidateCore, Dis
22
22
  export { ProviderRegistry } from "./discovery/registry";
23
23
  export { normalizeScore, mergeCandidates, rankCandidates, } from "./discovery/ranking";
24
24
  export type { RankOpts } from "./discovery/ranking";
25
- export { SemanticScholarProvider } from "./sources/semantic-scholar/provider";
26
- export { SemanticScholarCitationGraphProvider } from "./sources/semantic-scholar/citation-graph-provider";
25
+ export { CrossrefProvider } from "./sources/crossref/provider";
26
+ export { crossrefWorkToCandidate } from "./sources/crossref/provider";
27
+ export { searchWorks as crossrefSearchWorks, getWorkByDoi as crossrefGetWorkByDoi, batchHydrateByDois as crossrefBatchHydrate, } from "./sources/crossref/client";
28
+ export type { CrossrefWork, CrossrefAuthor, CrossrefSearchResponse, } from "./sources/crossref/client";
29
+ export { OpenCitationsCitationGraphProvider } from "./sources/opencitations/citation-graph-provider";
30
+ export { getReferences as cociGetReferences, getCitations as cociGetCitations, } from "./sources/opencitations/client";
27
31
  export { searchPapers as s2SearchPapers, getPaperDetails as s2GetPaperDetails, getPaperReferences as s2GetPaperReferences, getPaperCitations as s2GetPaperCitations, } from "./sources/semantic-scholar/client";
28
32
  export type { S2Paper, S2Author, S2ExternalIds, S2SearchResponse, S2CitationEdge, S2CitationResponse, S2ClientOpts, } from "./sources/semantic-scholar/client";
29
33
  export type { PaperDigest, HypothesisSet, Hypothesis } from "./analysis/schemas";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -20,9 +20,14 @@ export { createWorkId } from "./works/util/work-id";
20
20
  export { NormalizedDocSchema, SectionCategoryEnum, } from "./normalization/normalized-doc-schema";
21
21
  export { ProviderRegistry } from "./discovery/registry";
22
22
  export { normalizeScore, mergeCandidates, rankCandidates, } from "./discovery/ranking";
23
- // ── Sources: Semantic Scholar ────────────────────────────────────
24
- export { SemanticScholarProvider } from "./sources/semantic-scholar/provider";
25
- export { SemanticScholarCitationGraphProvider } from "./sources/semantic-scholar/citation-graph-provider";
23
+ // ── Sources: Crossref (discovery) ────────────────────────────────
24
+ export { CrossrefProvider } from "./sources/crossref/provider";
25
+ export { crossrefWorkToCandidate } from "./sources/crossref/provider";
26
+ export { searchWorks as crossrefSearchWorks, getWorkByDoi as crossrefGetWorkByDoi, batchHydrateByDois as crossrefBatchHydrate, } from "./sources/crossref/client";
27
+ // ── Sources: OpenCitations (citation graph) ─────────────────────
28
+ export { OpenCitationsCitationGraphProvider } from "./sources/opencitations/citation-graph-provider";
29
+ export { getReferences as cociGetReferences, getCitations as cociGetCitations, } from "./sources/opencitations/client";
30
+ // ── Sources: Semantic Scholar (legacy, retained for ingest paths) ──
26
31
  export { searchPapers as s2SearchPapers, getPaperDetails as s2GetPaperDetails, getPaperReferences as s2GetPaperReferences, getPaperCitations as s2GetPaperCitations, } from "./sources/semantic-scholar/client";
27
32
  export { PaperDigestSchema, HypothesisSetSchema } from "./analysis/schemas";
28
33
  export { extractFindings } from "./analysis/extract-findings";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AAEjC,sEAAsE;AACtE,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AAEjC,sEAAsE;AACtE,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAsCrE,sEAAsE;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAIzC,OAAO,EACL,YAAY,EACZ,SAAS,EACT,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAEvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,sEAAsE;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,sEAAsE;AACtE,OAAO,EACL,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,uCAAuC,CAAC;AAe/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,qBAAqB,CAAC;AAG7B,oEAAoE;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,oCAAoC,EAAE,MAAM,oDAAoD,CAAC;AAC1G,OAAO,EACL,YAAY,IAAI,cAAc,EAC9B,eAAe,IAAI,iBAAiB,EACpC,kBAAkB,IAAI,oBAAoB,EAC1C,iBAAiB,IAAI,mBAAmB,GACzC,MAAM,mCAAmC,CAAC;AAa3C,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AAEjC,sEAAsE;AACtE,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AAEjC,sEAAsE;AACtE,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAsCrE,sEAAsE;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAIzC,OAAO,EACL,YAAY,EACZ,SAAS,EACT,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAEvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,sEAAsE;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,sEAAsE;AACtE,OAAO,EACL,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,uCAAuC,CAAC;AAe/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,qBAAqB,CAAC;AAG7B,oEAAoE;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EACL,WAAW,IAAI,mBAAmB,EAClC,YAAY,IAAI,oBAAoB,EACpC,kBAAkB,IAAI,oBAAoB,GAC3C,MAAM,2BAA2B,CAAC;AAOnC,mEAAmE;AACnE,OAAO,EAAE,kCAAkC,EAAE,MAAM,iDAAiD,CAAC;AACrG,OAAO,EACL,aAAa,IAAI,iBAAiB,EAClC,YAAY,IAAI,gBAAgB,GACjC,MAAM,gCAAgC,CAAC;AAExC,sEAAsE;AACtE,OAAO,EACL,YAAY,IAAI,cAAc,EAC9B,eAAe,IAAI,iBAAiB,EACpC,kBAAkB,IAAI,oBAAoB,EAC1C,iBAAiB,IAAI,mBAAmB,GACzC,MAAM,mCAAmC,CAAC;AAa3C,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -1,3 +1,73 @@
1
+ /**
2
+ * Typed client for the Crossref REST API.
3
+ *
4
+ * Free, no API key required. Uses the polite pool via `mailto` parameter
5
+ * for better rate limits.
6
+ *
7
+ * @see https://api.crossref.org/swagger-ui/index.html
8
+ */
1
9
  import type { AdapterResult } from "../../works/types";
10
+ export interface CrossrefWork {
11
+ DOI: string;
12
+ title?: string[];
13
+ author?: CrossrefAuthor[];
14
+ "published-print"?: CrossrefDate;
15
+ "published-online"?: CrossrefDate;
16
+ published?: CrossrefDate;
17
+ "container-title"?: string[];
18
+ score?: number;
19
+ "is-referenced-by-count"?: number;
20
+ "references-count"?: number;
21
+ abstract?: string;
22
+ URL?: string;
23
+ "reference"?: CrossrefReference[];
24
+ }
25
+ export interface CrossrefAuthor {
26
+ given?: string;
27
+ family?: string;
28
+ name?: string;
29
+ }
30
+ export interface CrossrefDate {
31
+ "date-parts"?: number[][];
32
+ }
33
+ export interface CrossrefReference {
34
+ DOI?: string;
35
+ key?: string;
36
+ }
37
+ export interface CrossrefSearchResponse {
38
+ total: number;
39
+ items: CrossrefWork[];
40
+ }
41
+ /** Extract the best publication year from a Crossref work. */
42
+ export declare function extractYear(work: CrossrefWork): number | null;
43
+ /** Format authors into a single string. */
44
+ export declare function formatAuthors(authors?: CrossrefAuthor[]): string | null;
45
+ /** Extract first title from the title array. */
46
+ export declare function extractTitle(work: CrossrefWork): string | null;
47
+ /** Extract venue/journal name. */
48
+ export declare function extractVenue(work: CrossrefWork): string | null;
49
+ /** Truncate abstract to a snippet. */
50
+ export declare function extractAbstract(work: CrossrefWork): string | null;
51
+ /**
52
+ * Fetch a single Crossref work by DOI (existing ingest pathway).
53
+ */
2
54
  export declare function fetchCrossrefWorkByDoi(doi: string): Promise<AdapterResult<any>>;
55
+ /**
56
+ * Search for works by keyword query.
57
+ * Results are sorted by Crossref relevance score (descending).
58
+ */
59
+ export declare function searchWorks(query: string, opts?: {
60
+ limit?: number;
61
+ offset?: number;
62
+ mailto?: string;
63
+ }): Promise<AdapterResult<CrossrefSearchResponse>>;
64
+ /**
65
+ * Fetch a single Crossref work by DOI as a typed CrossrefWork.
66
+ */
67
+ export declare function getWorkByDoi(doi: string): Promise<AdapterResult<CrossrefWork>>;
68
+ /**
69
+ * Fetch metadata for multiple DOIs in batches with bounded concurrency.
70
+ * Returns a DOI-keyed map. Missing/failed DOIs are silently omitted.
71
+ */
72
+ export declare function batchHydrateByDois(dois: string[]): Promise<Map<string, CrossrefWork>>;
3
73
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/sources/crossref/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAGtD,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAiB7B"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/sources/crossref/client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAkBvD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;IAC1B,iBAAiB,CAAC,EAAE,YAAY,CAAC;IACjC,kBAAkB,CAAC,EAAE,YAAY,CAAC;IAClC,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAwCD,8DAA8D;AAC9D,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAO7D;AAED,2CAA2C;AAC3C,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,cAAc,EAAE,GAAG,MAAM,GAAG,IAAI,CAUvE;AAED,gDAAgD;AAChD,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAE9D;AAED,kCAAkC;AAClC,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAE9D;AAED,sCAAsC;AACtC,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAMjE;AAID;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAiB7B;AAID;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1D,OAAO,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC,CAuChD;AAID;;GAEG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAiBtC;AAID;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAyBpC"}
@@ -1,8 +1,98 @@
1
- // Crossref returns deeply nested, untyped JSON — keep as `any` at the adapter boundary
1
+ /**
2
+ * Typed client for the Crossref REST API.
3
+ *
4
+ * Free, no API key required. Uses the polite pool via `mailto` parameter
5
+ * for better rate limits.
6
+ *
7
+ * @see https://api.crossref.org/swagger-ui/index.html
8
+ */
9
+ const BASE_URL = "https://api.crossref.org";
10
+ /** Max retries on 429 / 5xx before giving up. */
11
+ const MAX_RETRIES = 2;
12
+ /** Request timeout in ms. */
13
+ const REQUEST_TIMEOUT_MS = 15_000;
14
+ /** Max concurrent requests for batch operations. */
15
+ const BATCH_CONCURRENCY = 5;
16
+ /** Chunk size for batch DOI lookups. */
17
+ const BATCH_CHUNK_SIZE = 20;
18
+ // ── Helpers ──────────────────────────────────────────────────────────
19
+ const HEADERS = {
20
+ Accept: "application/json",
21
+ };
22
+ async function fetchWithRetry(url) {
23
+ let lastError;
24
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
25
+ try {
26
+ const res = await fetch(url, {
27
+ headers: HEADERS,
28
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
29
+ });
30
+ if ((res.status === 429 || res.status >= 500) && attempt < MAX_RETRIES) {
31
+ await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)));
32
+ continue;
33
+ }
34
+ return res;
35
+ }
36
+ catch (e) {
37
+ lastError = e;
38
+ if (attempt < MAX_RETRIES) {
39
+ await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)));
40
+ continue;
41
+ }
42
+ }
43
+ }
44
+ throw lastError ?? new Error("fetchWithRetry exhausted");
45
+ }
46
+ // ── Parsing helpers ──────────────────────────────────────────────────
47
+ /** Extract the best publication year from a Crossref work. */
48
+ export function extractYear(work) {
49
+ const dateParts = work.published?.["date-parts"]?.[0] ??
50
+ work["published-online"]?.["date-parts"]?.[0] ??
51
+ work["published-print"]?.["date-parts"]?.[0];
52
+ const year = dateParts?.[0];
53
+ return typeof year === "number" && year > 0 ? year : null;
54
+ }
55
+ /** Format authors into a single string. */
56
+ export function formatAuthors(authors) {
57
+ if (!authors || authors.length === 0)
58
+ return null;
59
+ return authors
60
+ .map((a) => {
61
+ if (a.name)
62
+ return a.name;
63
+ if (a.family && a.given)
64
+ return `${a.given} ${a.family}`;
65
+ return a.family ?? a.given ?? null;
66
+ })
67
+ .filter(Boolean)
68
+ .join(", ") || null;
69
+ }
70
+ /** Extract first title from the title array. */
71
+ export function extractTitle(work) {
72
+ return work.title?.[0] ?? null;
73
+ }
74
+ /** Extract venue/journal name. */
75
+ export function extractVenue(work) {
76
+ return work["container-title"]?.[0] ?? null;
77
+ }
78
+ /** Truncate abstract to a snippet. */
79
+ export function extractAbstract(work) {
80
+ if (!work.abstract)
81
+ return null;
82
+ // Crossref abstracts may contain JATS XML tags — strip them
83
+ const plain = work.abstract.replace(/<[^>]+>/g, "").trim();
84
+ if (!plain)
85
+ return null;
86
+ return plain.length > 200 ? plain.slice(0, 197) + "..." : plain;
87
+ }
88
+ // ── Public API: existing ingest adapter ──────────────────────────────
89
+ /**
90
+ * Fetch a single Crossref work by DOI (existing ingest pathway).
91
+ */
2
92
  export async function fetchCrossrefWorkByDoi(doi) {
3
- const url = `https://api.crossref.org/works/${encodeURIComponent(doi)}`;
93
+ const url = `${BASE_URL}/works/${encodeURIComponent(doi)}`;
4
94
  try {
5
- const res = await fetch(url, { headers: { Accept: "application/json" } });
95
+ const res = await fetchWithRetry(url);
6
96
  if (!res.ok) {
7
97
  const status = res.status;
8
98
  if (status === 404)
@@ -21,4 +111,101 @@ export async function fetchCrossrefWorkByDoi(doi) {
21
111
  return { ok: false, reason: "network_error" };
22
112
  }
23
113
  }
114
+ // ── Public API: discovery search ─────────────────────────────────────
115
+ /**
116
+ * Search for works by keyword query.
117
+ * Results are sorted by Crossref relevance score (descending).
118
+ */
119
+ export async function searchWorks(query, opts) {
120
+ const rows = Math.min(opts?.limit ?? 20, 100);
121
+ const offset = opts?.offset ?? 0;
122
+ const params = new URLSearchParams({
123
+ query,
124
+ rows: String(rows),
125
+ offset: String(offset),
126
+ sort: "relevance",
127
+ order: "desc",
128
+ });
129
+ if (opts?.mailto)
130
+ params.set("mailto", opts.mailto);
131
+ const url = `${BASE_URL}/works?${params}`;
132
+ try {
133
+ const res = await fetchWithRetry(url);
134
+ if (!res.ok) {
135
+ const status = res.status;
136
+ if (status === 400)
137
+ return { ok: false, status, reason: "not_found" };
138
+ if (status === 429)
139
+ return { ok: false, status, reason: "rate_limited" };
140
+ return { ok: false, status, reason: "upstream_error" };
141
+ }
142
+ const data = await res.json();
143
+ const message = data?.message;
144
+ if (!message)
145
+ return { ok: false, reason: "upstream_error" };
146
+ return {
147
+ ok: true,
148
+ data: {
149
+ total: message["total-results"] ?? 0,
150
+ items: (message.items ?? []),
151
+ },
152
+ };
153
+ }
154
+ catch {
155
+ return { ok: false, reason: "network_error" };
156
+ }
157
+ }
158
+ // ── Public API: typed single-work fetch ──────────────────────────────
159
+ /**
160
+ * Fetch a single Crossref work by DOI as a typed CrossrefWork.
161
+ */
162
+ export async function getWorkByDoi(doi) {
163
+ const url = `${BASE_URL}/works/${encodeURIComponent(doi)}`;
164
+ try {
165
+ const res = await fetchWithRetry(url);
166
+ if (!res.ok) {
167
+ const status = res.status;
168
+ if (status === 404)
169
+ return { ok: false, status, reason: "not_found" };
170
+ if (status === 429)
171
+ return { ok: false, status, reason: "rate_limited" };
172
+ return { ok: false, status, reason: "upstream_error" };
173
+ }
174
+ const data = await res.json();
175
+ const work = data?.message;
176
+ if (!work?.DOI)
177
+ return { ok: false, reason: "not_found" };
178
+ return { ok: true, data: work };
179
+ }
180
+ catch {
181
+ return { ok: false, reason: "network_error" };
182
+ }
183
+ }
184
+ // ── Public API: batch DOI hydration ──────────────────────────────────
185
+ /**
186
+ * Fetch metadata for multiple DOIs in batches with bounded concurrency.
187
+ * Returns a DOI-keyed map. Missing/failed DOIs are silently omitted.
188
+ */
189
+ export async function batchHydrateByDois(dois) {
190
+ const results = new Map();
191
+ if (dois.length === 0)
192
+ return results;
193
+ // Deduplicate and normalize
194
+ const uniqueDois = [...new Set(dois.map((d) => d.toLowerCase()))];
195
+ // Process in chunks with bounded concurrency
196
+ for (let i = 0; i < uniqueDois.length; i += BATCH_CHUNK_SIZE) {
197
+ const chunk = uniqueDois.slice(i, i + BATCH_CHUNK_SIZE);
198
+ const promises = chunk.map(async (doi) => {
199
+ const result = await getWorkByDoi(doi);
200
+ if (result.ok) {
201
+ results.set(doi.toLowerCase(), result.data);
202
+ }
203
+ });
204
+ // Run chunk with bounded concurrency
205
+ for (let j = 0; j < promises.length; j += BATCH_CONCURRENCY) {
206
+ await Promise.allSettled(promises.slice(j, j + BATCH_CONCURRENCY));
207
+ }
208
+ }
209
+ return results;
210
+ }
24
211
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/sources/crossref/client.ts"],"names":[],"mappings":"AAEA,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,GAAW;IAEX,MAAM,GAAG,GAAG,kCAAkC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;IACxE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;YAC1B,IAAI,MAAM,KAAK,GAAG;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;YACtE,IAAI,MAAM,KAAK,GAAG;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;YACzE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;QACzD,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAI,IAAY,EAAE,OAAO,IAAI,IAAI,CAAC;QAC/C,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QACxD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAChD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/sources/crossref/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Crossref discovery provider.
3
+ *
4
+ * Adapts the Crossref API client to the DiscoverProvider interface.
5
+ */
6
+ import type { DiscoverCandidateCore, DiscoverProvider, DiscoverSearchOpts } from "../../discovery/types";
7
+ import { type CrossrefWork } from "./client";
8
+ /**
9
+ * Map a CrossrefWork to a DiscoverCandidateCore.
10
+ * Preserves the raw Crossref relevance score for ranking normalization.
11
+ */
12
+ export declare function crossrefWorkToCandidate(work: CrossrefWork): DiscoverCandidateCore;
13
+ export declare class CrossrefProvider implements DiscoverProvider {
14
+ readonly name = "Crossref";
15
+ readonly sourceKind: "crossref";
16
+ readonly capabilities: readonly ["search"];
17
+ readonly isLocal = false;
18
+ search(query: string, opts?: DiscoverSearchOpts): Promise<DiscoverCandidateCore[]>;
19
+ }
20
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/sources/crossref/provider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAOL,KAAK,YAAY,EAClB,MAAM,UAAU,CAAC;AAElB;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,YAAY,GACjB,qBAAqB,CAavB;AAED,qBAAa,gBAAiB,YAAW,gBAAgB;IACvD,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,UAAU,EAAG,UAAU,CAAU;IAC1C,QAAQ,CAAC,YAAY,sBAAuB;IAC5C,QAAQ,CAAC,OAAO,SAAS;IAEnB,MAAM,CACV,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,qBAAqB,EAAE,CAAC;CAapC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Crossref discovery provider.
3
+ *
4
+ * Adapts the Crossref API client to the DiscoverProvider interface.
5
+ */
6
+ import { searchWorks, extractTitle, extractYear, formatAuthors, extractVenue, extractAbstract, } from "./client";
7
+ /**
8
+ * Map a CrossrefWork to a DiscoverCandidateCore.
9
+ * Preserves the raw Crossref relevance score for ranking normalization.
10
+ */
11
+ export function crossrefWorkToCandidate(work) {
12
+ return {
13
+ doi: work.DOI ?? null,
14
+ title: extractTitle(work),
15
+ authors: formatAuthors(work.author),
16
+ year: extractYear(work),
17
+ sources: ["crossref"],
18
+ score: work.score ?? null,
19
+ citationCount: work["is-referenced-by-count"] ?? null,
20
+ abstractSnippet: extractAbstract(work),
21
+ venue: extractVenue(work),
22
+ url: work.URL ?? null,
23
+ };
24
+ }
25
+ export class CrossrefProvider {
26
+ name = "Crossref";
27
+ sourceKind = "crossref";
28
+ capabilities = ["search"];
29
+ isLocal = false;
30
+ async search(query, opts) {
31
+ const limit = opts?.limit ?? 20;
32
+ const result = await searchWorks(query, { limit });
33
+ if (!result.ok) {
34
+ throw new Error(`Crossref search failed: ${result.reason}${result.status ? ` (${result.status})` : ""}`);
35
+ }
36
+ return result.data.items.map((work) => crossrefWorkToCandidate(work));
37
+ }
38
+ }
39
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/sources/crossref/provider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,aAAa,EACb,YAAY,EACZ,eAAe,GAEhB,MAAM,UAAU,CAAC;AAElB;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,IAAkB;IAElB,OAAO;QACL,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,IAAI;QACrB,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC;QACzB,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QACnC,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC;QACvB,OAAO,EAAE,CAAC,UAAU,CAAC;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI;QACzB,aAAa,EAAE,IAAI,CAAC,wBAAwB,CAAC,IAAI,IAAI;QACrD,eAAe,EAAE,eAAe,CAAC,IAAI,CAAC;QACtC,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC;QACzB,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,IAAI;KACtB,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,gBAAgB;IAClB,IAAI,GAAG,UAAU,CAAC;IAClB,UAAU,GAAG,UAAmB,CAAC;IACjC,YAAY,GAAG,CAAC,QAAQ,CAAU,CAAC;IACnC,OAAO,GAAG,KAAK,CAAC;IAEzB,KAAK,CAAC,MAAM,CACV,KAAa,EACb,IAAyB;QAEzB,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QAEhC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAEnD,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,2BAA2B,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACxF,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC;IACxE,CAAC;CACF"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * OpenCitations COCI citation-graph discovery provider.
3
+ *
4
+ * Expands from a set of seed DOIs by fetching their references (bibliography)
5
+ * and citations (downstream work) via OpenCitations, then hydrates metadata
6
+ * from Crossref before returning deduplicated candidates.
7
+ *
8
+ * Fetch budget:
9
+ * - PER_SEED_LIMIT caps the per-direction result count per seed to guard
10
+ * against prolific seeds flooding the accumulator.
11
+ * - A global `budget = limit × BUDGET_MULTIPLIER` unique non-seed DOIs are
12
+ * accumulated before the outer seed loop is stopped, providing slack for
13
+ * seed exclusions and dedup losses while avoiding fetching far more data
14
+ * than the requested limit.
15
+ * - Only `limit` entries from the accumulated set are sent to Crossref
16
+ * hydration, so hydration cost is always proportional to requested output.
17
+ */
18
+ import type { DiscoverCandidateCore, DiscoverProvider, DiscoverSearchOpts } from "../../discovery/types";
19
+ export declare class OpenCitationsCitationGraphProvider implements DiscoverProvider {
20
+ readonly name = "OpenCitations Citation Graph";
21
+ readonly sourceKind: "opencitations-citation-graph";
22
+ readonly capabilities: readonly ["search"];
23
+ readonly isLocal = false;
24
+ private seedDois;
25
+ constructor(seedDois: string[]);
26
+ search(_query: string, opts?: DiscoverSearchOpts): Promise<DiscoverCandidateCore[]>;
27
+ }
28
+ //# sourceMappingURL=citation-graph-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"citation-graph-provider.d.ts","sourceRoot":"","sources":["../../../src/sources/opencitations/citation-graph-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAEnB,MAAM,uBAAuB,CAAC;AAwB/B,qBAAa,kCAAmC,YAAW,gBAAgB;IACzE,QAAQ,CAAC,IAAI,kCAAkC;IAC/C,QAAQ,CAAC,UAAU,EAAG,8BAA8B,CAAU;IAC9D,QAAQ,CAAC,YAAY,sBAAuB;IAC5C,QAAQ,CAAC,OAAO,SAAS;IAEzB,OAAO,CAAC,QAAQ,CAAW;gBAEf,QAAQ,EAAE,MAAM,EAAE;IAIxB,MAAM,CACV,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,qBAAqB,EAAE,CAAC;CAuFpC"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * OpenCitations COCI citation-graph discovery provider.
3
+ *
4
+ * Expands from a set of seed DOIs by fetching their references (bibliography)
5
+ * and citations (downstream work) via OpenCitations, then hydrates metadata
6
+ * from Crossref before returning deduplicated candidates.
7
+ *
8
+ * Fetch budget:
9
+ * - PER_SEED_LIMIT caps the per-direction result count per seed to guard
10
+ * against prolific seeds flooding the accumulator.
11
+ * - A global `budget = limit × BUDGET_MULTIPLIER` unique non-seed DOIs are
12
+ * accumulated before the outer seed loop is stopped, providing slack for
13
+ * seed exclusions and dedup losses while avoiding fetching far more data
14
+ * than the requested limit.
15
+ * - Only `limit` entries from the accumulated set are sent to Crossref
16
+ * hydration, so hydration cost is always proportional to requested output.
17
+ */
18
+ import { getReferences, getCitations } from "./client";
19
+ import { batchHydrateByDois, extractTitle, extractYear, formatAuthors, extractVenue, extractAbstract, } from "../crossref/client";
20
+ /** Max concurrent seed expansions to avoid burst traffic. */
21
+ const MAX_CONCURRENCY = 3;
22
+ /** Max results per direction per seed (guards against very prolific seeds). */
23
+ const PER_SEED_LIMIT = 50;
24
+ /**
25
+ * Multiplier applied to `opts.limit` to set the global unique-candidate budget.
26
+ * Provides slack for seed exclusions and dedup losses before the final slice.
27
+ */
28
+ const BUDGET_MULTIPLIER = 3;
29
+ export class OpenCitationsCitationGraphProvider {
30
+ name = "OpenCitations Citation Graph";
31
+ sourceKind = "opencitations-citation-graph";
32
+ capabilities = ["search"];
33
+ isLocal = false;
34
+ seedDois;
35
+ constructor(seedDois) {
36
+ this.seedDois = seedDois;
37
+ }
38
+ async search(_query, opts) {
39
+ if (this.seedDois.length === 0)
40
+ return [];
41
+ const limit = opts?.limit ?? 20;
42
+ // Global budget: stop fanout once this many unique non-seed DOIs are
43
+ // accumulated — avoids fetching far more data than the final limit needs.
44
+ const budget = limit * BUDGET_MULTIPLIER;
45
+ const seedDoiSet = new Set(this.seedDois.map((d) => d.toLowerCase()));
46
+ // Accumulate deduplicated non-seed DOIs and their seed origins inline
47
+ // during fanout — no intermediate collection pass needed.
48
+ const doiMap = new Map();
49
+ for (let i = 0; i < this.seedDois.length; i += MAX_CONCURRENCY) {
50
+ // Early-stop: enough unique candidates collected; skip remaining seeds.
51
+ if (doiMap.size >= budget)
52
+ break;
53
+ const batch = this.seedDois.slice(i, i + MAX_CONCURRENCY);
54
+ const requests = [];
55
+ for (const doi of batch) {
56
+ requests.push({
57
+ doi,
58
+ relation: "references",
59
+ promise: getReferences(doi),
60
+ });
61
+ requests.push({
62
+ doi,
63
+ relation: "cited-by",
64
+ promise: getCitations(doi),
65
+ });
66
+ }
67
+ const results = await Promise.allSettled(requests.map((r) => r.promise));
68
+ for (let j = 0; j < results.length; j++) {
69
+ const result = results[j];
70
+ const req = requests[j];
71
+ if (result.status === "fulfilled" && result.value.ok) {
72
+ const dois = result.value.data;
73
+ for (const doi of dois.slice(0, PER_SEED_LIMIT)) {
74
+ const key = doi.toLowerCase();
75
+ // Exclude seed papers from results
76
+ if (seedDoiSet.has(key))
77
+ continue;
78
+ const existing = doiMap.get(key);
79
+ if (existing) {
80
+ const originKey = `${req.doi.toLowerCase()}:${req.relation}`;
81
+ if (!existing.origins.some((o) => `${o.doi.toLowerCase()}:${o.relation}` === originKey)) {
82
+ existing.origins.push({ doi: req.doi, relation: req.relation });
83
+ }
84
+ }
85
+ else {
86
+ doiMap.set(key, {
87
+ doi,
88
+ origins: [{ doi: req.doi, relation: req.relation }],
89
+ });
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }
95
+ // Slice to limit before hydration so only chosen entries incur Crossref cost.
96
+ const entries = [...doiMap.values()].slice(0, limit);
97
+ if (entries.length === 0)
98
+ return [];
99
+ // Hydrate metadata from Crossref
100
+ const doisToHydrate = entries.map((e) => e.doi);
101
+ const hydrated = await batchHydrateByDois(doisToHydrate);
102
+ // Map to candidates
103
+ return entries.map(({ doi, origins }, i) => {
104
+ const work = hydrated.get(doi.toLowerCase());
105
+ return workToCandidate(doi, work, origins, i);
106
+ });
107
+ }
108
+ }
109
+ function workToCandidate(doi, work, origins, position) {
110
+ if (!work) {
111
+ // Minimal candidate when Crossref hydration missed
112
+ return {
113
+ doi,
114
+ title: null,
115
+ authors: null,
116
+ year: null,
117
+ sources: ["opencitations-citation-graph"],
118
+ score: position,
119
+ seedOrigins: origins,
120
+ };
121
+ }
122
+ return {
123
+ doi: work.DOI ?? doi,
124
+ title: extractTitle(work),
125
+ authors: formatAuthors(work.author),
126
+ year: extractYear(work),
127
+ sources: ["opencitations-citation-graph"],
128
+ score: position,
129
+ citationCount: work["is-referenced-by-count"] ?? null,
130
+ abstractSnippet: extractAbstract(work),
131
+ venue: extractVenue(work),
132
+ url: work.URL ?? null,
133
+ seedOrigins: origins,
134
+ };
135
+ }
136
+ //# sourceMappingURL=citation-graph-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"citation-graph-provider.js","sourceRoot":"","sources":["../../../src/sources/opencitations/citation-graph-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Typed client for the OpenCitations COCI REST API.
3
+ *
4
+ * Free, no API key required, no rate limits documented.
5
+ * Returns citation edges by DOI in both directions.
6
+ *
7
+ * @see https://opencitations.net/index/coci/api/v1
8
+ */
9
+ import type { AdapterResult } from "../../works/types";
10
+ /** A single citation edge from COCI. */
11
+ export interface CociCitation {
12
+ /** DOI of the citing paper. */
13
+ citing: string;
14
+ /** DOI of the cited paper. */
15
+ cited: string;
16
+ /** Creation date of the citation record (YYYY-MM-DD). */
17
+ creation?: string;
18
+ }
19
+ /**
20
+ * Get papers referenced by a given paper (its bibliography).
21
+ * Returns deduplicated, normalized DOIs of cited papers.
22
+ */
23
+ export declare function getReferences(doi: string): Promise<AdapterResult<string[]>>;
24
+ /**
25
+ * Get papers that cite a given paper.
26
+ * Returns deduplicated, normalized DOIs of citing papers.
27
+ */
28
+ export declare function getCitations(doi: string): Promise<AdapterResult<string[]>>;
29
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/sources/opencitations/client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAYvD,wCAAwC;AACxC,MAAM,WAAW,YAAY;IAC3B,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA2DD;;;GAGG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAmBlC;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAmBlC"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Typed client for the OpenCitations COCI REST API.
3
+ *
4
+ * Free, no API key required, no rate limits documented.
5
+ * Returns citation edges by DOI in both directions.
6
+ *
7
+ * @see https://opencitations.net/index/coci/api/v1
8
+ */
9
+ const BASE_URL = "https://opencitations.net/index/coci/api/v1";
10
+ /** Max retries on 5xx before giving up. */
11
+ const MAX_RETRIES = 2;
12
+ /** Request timeout in ms. */
13
+ const REQUEST_TIMEOUT_MS = 15_000;
14
+ // ── Helpers ──────────────────────────────────────────────────────────
15
+ async function fetchWithRetry(url) {
16
+ let lastError;
17
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
18
+ try {
19
+ const res = await fetch(url, {
20
+ headers: { Accept: "application/json" },
21
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
22
+ });
23
+ if (res.status >= 500 && attempt < MAX_RETRIES) {
24
+ await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)));
25
+ continue;
26
+ }
27
+ return res;
28
+ }
29
+ catch (e) {
30
+ lastError = e;
31
+ if (attempt < MAX_RETRIES) {
32
+ await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)));
33
+ continue;
34
+ }
35
+ }
36
+ }
37
+ throw lastError ?? new Error("fetchWithRetry exhausted");
38
+ }
39
+ /** Normalize a DOI to lowercase, trimmed. */
40
+ function normalizeDoi(doi) {
41
+ return doi.trim().toLowerCase();
42
+ }
43
+ /** Extract DOIs from COCI edges, filtering out empty/invalid values. */
44
+ function extractDois(edges, field) {
45
+ const seen = new Set();
46
+ const result = [];
47
+ for (const edge of edges) {
48
+ const raw = edge[field];
49
+ if (!raw)
50
+ continue;
51
+ const doi = normalizeDoi(raw);
52
+ if (!doi || seen.has(doi))
53
+ continue;
54
+ seen.add(doi);
55
+ result.push(doi);
56
+ }
57
+ return result;
58
+ }
59
+ // ── Public API ───────────────────────────────────────────────────────
60
+ /**
61
+ * Get papers referenced by a given paper (its bibliography).
62
+ * Returns deduplicated, normalized DOIs of cited papers.
63
+ */
64
+ export async function getReferences(doi) {
65
+ const url = `${BASE_URL}/references/${encodeURIComponent(doi)}`;
66
+ try {
67
+ const res = await fetchWithRetry(url);
68
+ if (!res.ok) {
69
+ const status = res.status;
70
+ if (status === 404)
71
+ return { ok: false, status, reason: "not_found" };
72
+ if (status === 429)
73
+ return { ok: false, status, reason: "rate_limited" };
74
+ return { ok: false, status, reason: "upstream_error" };
75
+ }
76
+ const edges = (await res.json());
77
+ // References: papers cited by the query DOI → extract "cited" field
78
+ return { ok: true, data: extractDois(edges, "cited") };
79
+ }
80
+ catch {
81
+ return { ok: false, reason: "network_error" };
82
+ }
83
+ }
84
+ /**
85
+ * Get papers that cite a given paper.
86
+ * Returns deduplicated, normalized DOIs of citing papers.
87
+ */
88
+ export async function getCitations(doi) {
89
+ const url = `${BASE_URL}/citations/${encodeURIComponent(doi)}`;
90
+ try {
91
+ const res = await fetchWithRetry(url);
92
+ if (!res.ok) {
93
+ const status = res.status;
94
+ if (status === 404)
95
+ return { ok: false, status, reason: "not_found" };
96
+ if (status === 429)
97
+ return { ok: false, status, reason: "rate_limited" };
98
+ return { ok: false, status, reason: "upstream_error" };
99
+ }
100
+ const edges = (await res.json());
101
+ // Citations: papers that cite the query DOI → extract "citing" field
102
+ return { ok: true, data: extractDois(edges, "citing") };
103
+ }
104
+ catch {
105
+ return { ok: false, reason: "network_error" };
106
+ }
107
+ }
108
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/sources/opencitations/client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mantra-ai/core",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,19 +0,0 @@
1
- /**
2
- * Semantic Scholar citation-graph discovery provider.
3
- *
4
- * Expands from a set of seed DOIs by fetching their references (bibliography)
5
- * and citations (downstream work), then returns deduplicated candidates.
6
- */
7
- import type { DiscoverCandidateCore, DiscoverProvider, DiscoverSearchOpts } from "../../discovery/types";
8
- import { type S2ClientOpts } from "./client";
9
- export declare class SemanticScholarCitationGraphProvider implements DiscoverProvider {
10
- readonly name = "Semantic Scholar Citation Graph";
11
- readonly sourceKind: "semantic-scholar-citation-graph";
12
- readonly capabilities: readonly ["search"];
13
- readonly isLocal = false;
14
- private clientOpts;
15
- private seedDois;
16
- constructor(seedDois: string[], clientOpts?: S2ClientOpts);
17
- search(_query: string, opts?: DiscoverSearchOpts): Promise<DiscoverCandidateCore[]>;
18
- }
19
- //# sourceMappingURL=citation-graph-provider.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"citation-graph-provider.d.ts","sourceRoot":"","sources":["../../../src/sources/semantic-scholar/citation-graph-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAEnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,UAAU,CAAC;AAgBlB,qBAAa,oCAAqC,YAAW,gBAAgB;IAC3E,QAAQ,CAAC,IAAI,qCAAqC;IAClD,QAAQ,CAAC,UAAU,EAAG,iCAAiC,CAAU;IACjE,QAAQ,CAAC,YAAY,sBAAuB;IAC5C,QAAQ,CAAC,OAAO,SAAS;IAEzB,OAAO,CAAC,UAAU,CAAe;IACjC,OAAO,CAAC,QAAQ,CAAW;gBAEf,QAAQ,EAAE,MAAM,EAAE,EAAE,UAAU,CAAC,EAAE,YAAY;IAKnD,MAAM,CACV,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,qBAAqB,EAAE,CAAC;CA0EpC"}
@@ -1,91 +0,0 @@
1
- /**
2
- * Semantic Scholar citation-graph discovery provider.
3
- *
4
- * Expands from a set of seed DOIs by fetching their references (bibliography)
5
- * and citations (downstream work), then returns deduplicated candidates.
6
- */
7
- import { getPaperReferences, getPaperCitations, } from "./client";
8
- import { s2PaperToCandidate } from "./provider";
9
- /** Max concurrent seed expansions to avoid rate-limit bursts. */
10
- const MAX_CONCURRENCY = 3;
11
- /** Max results per direction per seed. */
12
- const PER_SEED_LIMIT = 50;
13
- export class SemanticScholarCitationGraphProvider {
14
- name = "Semantic Scholar Citation Graph";
15
- sourceKind = "semantic-scholar-citation-graph";
16
- capabilities = ["search"];
17
- isLocal = false;
18
- clientOpts;
19
- seedDois;
20
- constructor(seedDois, clientOpts) {
21
- this.seedDois = seedDois;
22
- this.clientOpts = clientOpts ?? {};
23
- }
24
- async search(_query, opts) {
25
- if (this.seedDois.length === 0)
26
- return [];
27
- const limit = opts?.limit ?? 20;
28
- // Fan out across seeds with bounded concurrency, tagging each result
29
- const allTagged = [];
30
- const seedDoiSet = new Set(this.seedDois.map((d) => d.toLowerCase()));
31
- for (let i = 0; i < this.seedDois.length; i += MAX_CONCURRENCY) {
32
- const batch = this.seedDois.slice(i, i + MAX_CONCURRENCY);
33
- // Build tagged request pairs: [refs-doi1, cites-doi1, refs-doi2, ...]
34
- const requests = [];
35
- for (const doi of batch) {
36
- requests.push({
37
- doi,
38
- relation: "references",
39
- promise: getPaperReferences(`DOI:${doi}`, { ...this.clientOpts, limit: PER_SEED_LIMIT }),
40
- });
41
- requests.push({
42
- doi,
43
- relation: "cited-by",
44
- promise: getPaperCitations(`DOI:${doi}`, { ...this.clientOpts, limit: PER_SEED_LIMIT }),
45
- });
46
- }
47
- const results = await Promise.allSettled(requests.map((r) => r.promise));
48
- for (let j = 0; j < results.length; j++) {
49
- const result = results[j];
50
- const req = requests[j];
51
- if (result.status === "fulfilled" && result.value.ok) {
52
- for (const paper of result.value.data) {
53
- allTagged.push({ paper, seedDoi: req.doi, relation: req.relation });
54
- }
55
- }
56
- }
57
- }
58
- // Deduplicate by S2 paperId, collecting seed origins per paper
59
- const paperMap = new Map();
60
- for (const { paper, seedDoi, relation } of allTagged) {
61
- // Exclude seed papers from results
62
- const paperDoi = paper.externalIds?.DOI?.toLowerCase();
63
- if (paperDoi && seedDoiSet.has(paperDoi))
64
- continue;
65
- const existing = paperMap.get(paper.paperId);
66
- if (existing) {
67
- // Add this origin if not already tracked
68
- const originKey = `${seedDoi.toLowerCase()}:${relation}`;
69
- if (!existing.origins.some((o) => `${o.doi.toLowerCase()}:${o.relation}` === originKey)) {
70
- existing.origins.push({ doi: seedDoi, relation });
71
- }
72
- }
73
- else {
74
- paperMap.set(paper.paperId, {
75
- paper,
76
- origins: [{ doi: seedDoi, relation }],
77
- });
78
- }
79
- }
80
- // Map to candidates, scored by position (will be re-ranked by core)
81
- const entries = [...paperMap.values()].slice(0, limit);
82
- const candidates = entries.map(({ paper, origins }, i) => {
83
- const c = s2PaperToCandidate(paper, i);
84
- c.sources = ["semantic-scholar-citation-graph"];
85
- c.seedOrigins = origins;
86
- return c;
87
- });
88
- return candidates;
89
- }
90
- }
91
- //# sourceMappingURL=citation-graph-provider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"citation-graph-provider.js","sourceRoot":"","sources":["../../../src/sources/semantic-scholar/citation-graph-provider.ts"],"names":[],"mappings":"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"}