@debriefer/core 2.0.0

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 (98) hide show
  1. package/README.md +86 -0
  2. package/dist/__tests__/base-source.test.d.ts +2 -0
  3. package/dist/__tests__/base-source.test.d.ts.map +1 -0
  4. package/dist/__tests__/base-source.test.js +333 -0
  5. package/dist/__tests__/base-source.test.js.map +1 -0
  6. package/dist/__tests__/batch-runner.test.d.ts +2 -0
  7. package/dist/__tests__/batch-runner.test.d.ts.map +1 -0
  8. package/dist/__tests__/batch-runner.test.js +217 -0
  9. package/dist/__tests__/batch-runner.test.js.map +1 -0
  10. package/dist/__tests__/cache.test.d.ts +2 -0
  11. package/dist/__tests__/cache.test.d.ts.map +1 -0
  12. package/dist/__tests__/cache.test.js +127 -0
  13. package/dist/__tests__/cache.test.js.map +1 -0
  14. package/dist/__tests__/confidence.test.d.ts +2 -0
  15. package/dist/__tests__/confidence.test.d.ts.map +1 -0
  16. package/dist/__tests__/confidence.test.js +81 -0
  17. package/dist/__tests__/confidence.test.js.map +1 -0
  18. package/dist/__tests__/cost-tracker.test.d.ts +2 -0
  19. package/dist/__tests__/cost-tracker.test.d.ts.map +1 -0
  20. package/dist/__tests__/cost-tracker.test.js +149 -0
  21. package/dist/__tests__/cost-tracker.test.js.map +1 -0
  22. package/dist/__tests__/orchestrator.test.d.ts +2 -0
  23. package/dist/__tests__/orchestrator.test.d.ts.map +1 -0
  24. package/dist/__tests__/orchestrator.test.js +751 -0
  25. package/dist/__tests__/orchestrator.test.js.map +1 -0
  26. package/dist/__tests__/rate-limiter.test.d.ts +2 -0
  27. package/dist/__tests__/rate-limiter.test.d.ts.map +1 -0
  28. package/dist/__tests__/rate-limiter.test.js +83 -0
  29. package/dist/__tests__/rate-limiter.test.js.map +1 -0
  30. package/dist/__tests__/reliability.test.d.ts +2 -0
  31. package/dist/__tests__/reliability.test.d.ts.map +1 -0
  32. package/dist/__tests__/reliability.test.js +207 -0
  33. package/dist/__tests__/reliability.test.js.map +1 -0
  34. package/dist/__tests__/synthesizer.test.d.ts +2 -0
  35. package/dist/__tests__/synthesizer.test.d.ts.map +1 -0
  36. package/dist/__tests__/synthesizer.test.js +50 -0
  37. package/dist/__tests__/synthesizer.test.js.map +1 -0
  38. package/dist/__tests__/telemetry.test.d.ts +2 -0
  39. package/dist/__tests__/telemetry.test.d.ts.map +1 -0
  40. package/dist/__tests__/telemetry.test.js +81 -0
  41. package/dist/__tests__/telemetry.test.js.map +1 -0
  42. package/dist/__tests__/types.test.d.ts +2 -0
  43. package/dist/__tests__/types.test.d.ts.map +1 -0
  44. package/dist/__tests__/types.test.js +708 -0
  45. package/dist/__tests__/types.test.js.map +1 -0
  46. package/dist/base-source.d.ts +91 -0
  47. package/dist/base-source.d.ts.map +1 -0
  48. package/dist/base-source.js +144 -0
  49. package/dist/base-source.js.map +1 -0
  50. package/dist/batch-runner.d.ts +40 -0
  51. package/dist/batch-runner.d.ts.map +1 -0
  52. package/dist/batch-runner.js +65 -0
  53. package/dist/batch-runner.js.map +1 -0
  54. package/dist/cache/in-memory.d.ts +26 -0
  55. package/dist/cache/in-memory.d.ts.map +1 -0
  56. package/dist/cache/in-memory.js +51 -0
  57. package/dist/cache/in-memory.js.map +1 -0
  58. package/dist/confidence.d.ts +13 -0
  59. package/dist/confidence.d.ts.map +1 -0
  60. package/dist/confidence.js +29 -0
  61. package/dist/confidence.js.map +1 -0
  62. package/dist/cost-tracker.d.ts +37 -0
  63. package/dist/cost-tracker.d.ts.map +1 -0
  64. package/dist/cost-tracker.js +62 -0
  65. package/dist/cost-tracker.js.map +1 -0
  66. package/dist/index.d.ts +25 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +28 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/orchestrator.d.ts +92 -0
  71. package/dist/orchestrator.d.ts.map +1 -0
  72. package/dist/orchestrator.js +373 -0
  73. package/dist/orchestrator.js.map +1 -0
  74. package/dist/rate-limiter.d.ts +31 -0
  75. package/dist/rate-limiter.d.ts.map +1 -0
  76. package/dist/rate-limiter.js +79 -0
  77. package/dist/rate-limiter.js.map +1 -0
  78. package/dist/reliability.d.ts +49 -0
  79. package/dist/reliability.d.ts.map +1 -0
  80. package/dist/reliability.js +67 -0
  81. package/dist/reliability.js.map +1 -0
  82. package/dist/synthesizer.d.ts +31 -0
  83. package/dist/synthesizer.d.ts.map +1 -0
  84. package/dist/synthesizer.js +47 -0
  85. package/dist/synthesizer.js.map +1 -0
  86. package/dist/telemetry/console.d.ts +7 -0
  87. package/dist/telemetry/console.d.ts.map +1 -0
  88. package/dist/telemetry/console.js +21 -0
  89. package/dist/telemetry/console.js.map +1 -0
  90. package/dist/telemetry/noop.d.ts +7 -0
  91. package/dist/telemetry/noop.d.ts.map +1 -0
  92. package/dist/telemetry/noop.js +12 -0
  93. package/dist/telemetry/noop.js.map +1 -0
  94. package/dist/types.d.ts +417 -0
  95. package/dist/types.d.ts.map +1 -0
  96. package/dist/types.js +102 -0
  97. package/dist/types.js.map +1 -0
  98. package/package.json +46 -0
@@ -0,0 +1,62 @@
1
+ /**
2
+ * BatchCostTracker — tracks costs across a batch enrichment run.
3
+ *
4
+ * Supports per-subject cost limits (e.g., maxCostPerSubject) and a global
5
+ * total cost limit. Also records cost-by-source for reporting.
6
+ */
7
+ export class BatchCostTracker {
8
+ totalCost = 0;
9
+ subjectCosts = new Map();
10
+ costBySource = {};
11
+ maxTotalCost;
12
+ maxCostPerSubject;
13
+ constructor(options) {
14
+ this.maxTotalCost = options?.maxTotalCost;
15
+ this.maxCostPerSubject = options?.maxCostPerSubject;
16
+ }
17
+ /**
18
+ * Add cost to a subject's running total.
19
+ * Returns whether any limit (total or per-subject) is now exceeded.
20
+ */
21
+ addSubjectCost(subjectId, cost) {
22
+ this.totalCost += cost;
23
+ const current = this.subjectCosts.get(subjectId) ?? 0;
24
+ this.subjectCosts.set(subjectId, current + cost);
25
+ return this.isTotalLimitExceeded() || this.isSubjectLimitExceeded(subjectId);
26
+ }
27
+ /** Track cost by source type for reporting. */
28
+ addSourceCost(sourceType, cost) {
29
+ this.costBySource[sourceType] = (this.costBySource[sourceType] ?? 0) + cost;
30
+ }
31
+ /** Get total cost across all subjects. */
32
+ getTotalCost() {
33
+ return this.totalCost;
34
+ }
35
+ /** Get cost for a specific subject. */
36
+ getSubjectCost(subjectId) {
37
+ return this.subjectCosts.get(subjectId) ?? 0;
38
+ }
39
+ /** Check if total limit is exceeded. Returns false when no limit is set. */
40
+ isTotalLimitExceeded() {
41
+ if (this.maxTotalCost === undefined)
42
+ return false;
43
+ return this.totalCost >= this.maxTotalCost;
44
+ }
45
+ /** Check if a specific subject's limit is exceeded. Returns false when no limit is set. */
46
+ isSubjectLimitExceeded(subjectId) {
47
+ if (this.maxCostPerSubject === undefined)
48
+ return false;
49
+ return this.getSubjectCost(subjectId) >= this.maxCostPerSubject;
50
+ }
51
+ /** Get cost breakdown by source type. Returns a shallow copy. */
52
+ getCostBySource() {
53
+ return { ...this.costBySource };
54
+ }
55
+ /** Reset all tracking state. */
56
+ reset() {
57
+ this.totalCost = 0;
58
+ this.subjectCosts.clear();
59
+ this.costBySource = {};
60
+ }
61
+ }
62
+ //# sourceMappingURL=cost-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-tracker.js","sourceRoot":"","sources":["../src/cost-tracker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,OAAO,gBAAgB;IACnB,SAAS,GAAG,CAAC,CAAA;IACb,YAAY,GAAG,IAAI,GAAG,EAA2B,CAAA;IACjD,YAAY,GAA2B,EAAE,CAAA;IAEhC,YAAY,CAAoB;IAChC,iBAAiB,CAAoB;IAEtD,YAAY,OAA+D;QACzE,IAAI,CAAC,YAAY,GAAG,OAAO,EAAE,YAAY,CAAA;QACzC,IAAI,CAAC,iBAAiB,GAAG,OAAO,EAAE,iBAAiB,CAAA;IACrD,CAAC;IAED;;;OAGG;IACH,cAAc,CAAC,SAA0B,EAAE,IAAY;QACrD,IAAI,CAAC,SAAS,IAAI,IAAI,CAAA;QACtB,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACrD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC,CAAA;QAChD,OAAO,IAAI,CAAC,oBAAoB,EAAE,IAAI,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAA;IAC9E,CAAC;IAED,+CAA+C;IAC/C,aAAa,CAAC,UAAkB,EAAE,IAAY;QAC5C,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAA;IAC7E,CAAC;IAED,0CAA0C;IAC1C,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAA;IACvB,CAAC;IAED,uCAAuC;IACvC,cAAc,CAAC,SAA0B;QACvC,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAC9C,CAAC;IAED,4EAA4E;IAC5E,oBAAoB;QAClB,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;YAAE,OAAO,KAAK,CAAA;QACjD,OAAO,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,YAAY,CAAA;IAC5C,CAAC;IAED,2FAA2F;IAC3F,sBAAsB,CAAC,SAA0B;QAC/C,IAAI,IAAI,CAAC,iBAAiB,KAAK,SAAS;YAAE,OAAO,KAAK,CAAA;QACtD,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAA;IACjE,CAAC;IAED,iEAAiE;IACjE,eAAe;QACb,OAAO,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;IACjC,CAAC;IAED,gCAAgC;IAChC,KAAK;QACH,IAAI,CAAC,SAAS,GAAG,CAAC,CAAA;QAClB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAA;QACzB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAA;IACxB,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Debriefer — Multi-source research orchestration engine.
3
+ *
4
+ * Orchestrates data sources with Wikipedia RSP-based reliability scoring,
5
+ * phased execution with early stopping, per-query cost control, and pluggable synthesis.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export { ResearchOrchestrator } from "./orchestrator.js";
10
+ export { BaseResearchSource } from "./base-source.js";
11
+ export type { BaseSourceOptions } from "./base-source.js";
12
+ export { NoopSynthesizer, stripMarkdownCodeFences } from "./synthesizer.js";
13
+ export { ReliabilityTier, RELIABILITY_SCORES, getReliabilityScore, meetsReliabilityThreshold, } from "./reliability.js";
14
+ export { SourceRateLimiter } from "./rate-limiter.js";
15
+ export type { RateLimiterStats } from "./rate-limiter.js";
16
+ export { BatchCostTracker } from "./cost-tracker.js";
17
+ export { ParallelBatchRunner } from "./batch-runner.js";
18
+ export type { BatchProgress, BatchResult, ParallelBatchRunnerOptions } from "./batch-runner.js";
19
+ export { calculateConfidence } from "./confidence.js";
20
+ export { InMemoryCache } from "./cache/in-memory.js";
21
+ export { ConsoleTelemetry } from "./telemetry/console.js";
22
+ export { NoopTelemetry } from "./telemetry/noop.js";
23
+ export type { ResearchSubject, RawFinding, ScoredFinding, MinimalSource, SourcePhaseGroup, SynthesisOptions, SynthesisResult, Synthesizer, DebriefResult, ResearchConfig, CacheProvider, TelemetryProvider, TelemetrySpan, BatchProgressStats, BatchStats, LifecycleHooks, } from "./types.js";
24
+ export { CostLimitExceededError, SourceTimeoutError, SourceAccessBlockedError } from "./types.js";
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAGzD,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAG3E,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAA;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAGrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAGnD,YAAY,EACV,eAAe,EACf,UAAU,EACV,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,aAAa,EACb,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,cAAc,GACf,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Debriefer — Multi-source research orchestration engine.
3
+ *
4
+ * Orchestrates data sources with Wikipedia RSP-based reliability scoring,
5
+ * phased execution with early stopping, per-query cost control, and pluggable synthesis.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ // Core engine
10
+ export { ResearchOrchestrator } from "./orchestrator.js";
11
+ export { BaseResearchSource } from "./base-source.js";
12
+ // Synthesis (ClaudeSynthesizer moved to @debriefer/ai)
13
+ export { NoopSynthesizer, stripMarkdownCodeFences } from "./synthesizer.js";
14
+ // Reliability scoring
15
+ export { ReliabilityTier, RELIABILITY_SCORES, getReliabilityScore, meetsReliabilityThreshold, } from "./reliability.js";
16
+ // Infrastructure
17
+ export { SourceRateLimiter } from "./rate-limiter.js";
18
+ export { BatchCostTracker } from "./cost-tracker.js";
19
+ export { ParallelBatchRunner } from "./batch-runner.js";
20
+ export { calculateConfidence } from "./confidence.js";
21
+ // Cache implementations
22
+ export { InMemoryCache } from "./cache/in-memory.js";
23
+ // Telemetry implementations
24
+ export { ConsoleTelemetry } from "./telemetry/console.js";
25
+ export { NoopTelemetry } from "./telemetry/noop.js";
26
+ // Error types
27
+ export { CostLimitExceededError, SourceTimeoutError, SourceAccessBlockedError } from "./types.js";
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc;AACd,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAGrD,uDAAuD;AACvD,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAE3E,sBAAsB;AACtB,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAA;AAEzB,iBAAiB;AACjB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAErD,wBAAwB;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEpD,4BAA4B;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAsBnD,cAAc;AACd,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Research Orchestrator — the core engine that wires sources, phases,
3
+ * rate limiting, cost tracking, and synthesis into a complete pipeline.
4
+ *
5
+ * Two entry points:
6
+ * - `debrief(subject)` — research a single subject through all phases
7
+ * - `debriefBatch(subjects, hooks)` — research multiple subjects with
8
+ * concurrency, cost limits, and lifecycle hooks
9
+ *
10
+ * Algorithm (per subject):
11
+ * 1. For each phase in order:
12
+ * a. Filter to available sources (isAvailable())
13
+ * b. Execute sources — concurrently via Promise.allSettled() by default,
14
+ * or sequentially (stop at first success) when phase.sequential is true
15
+ * c. Collect successful findings, tag with reliability info → ScoredFinding
16
+ * d. Check early-stop: do we have earlyStopThreshold+ high-quality families?
17
+ * e. Check per-subject cost limit
18
+ * 2. Synthesize all accumulated findings via the injected Synthesizer
19
+ * 3. Return DebriefResult
20
+ */
21
+ import type { ResearchSubject, ResearchConfig, DebriefResult, SourcePhaseGroup, Synthesizer, LifecycleHooks } from "./types.js";
22
+ /**
23
+ * Generic research orchestrator that coordinates source phases, rate limiting,
24
+ * cost tracking, and AI synthesis into a complete research pipeline.
25
+ *
26
+ * @typeParam TSubject - The research subject type (extends ResearchSubject)
27
+ * @typeParam TOutput - The structured output type produced by synthesis
28
+ */
29
+ export declare class ResearchOrchestrator<TSubject extends ResearchSubject, TOutput> {
30
+ private phases;
31
+ private synthesizer;
32
+ private config;
33
+ private rateLimiter;
34
+ private telemetry;
35
+ constructor(phases: SourcePhaseGroup<TSubject>[], synthesizer: Synthesizer<TSubject, TOutput>, config?: ResearchConfig);
36
+ /**
37
+ * Research a single subject through all configured phases.
38
+ *
39
+ * Iterates through phases sequentially. Within each phase, sources run
40
+ * concurrently via Promise.allSettled by default, or sequentially (stopping
41
+ * at first success) when `phase.sequential` is true. Accumulates findings,
42
+ * checks early stopping between phases, then runs synthesis on all collected
43
+ * findings.
44
+ *
45
+ * @param subject - The subject to research
46
+ * @param options - Optional abort signal and lifecycle hooks
47
+ * @returns Complete debrief result with findings, synthesis, and cost data
48
+ */
49
+ debrief(subject: TSubject, options?: {
50
+ signal?: AbortSignal;
51
+ hooks?: LifecycleHooks<TSubject, TOutput>;
52
+ }): Promise<DebriefResult<TOutput>>;
53
+ /**
54
+ * Execute all available sources in a single phase.
55
+ *
56
+ * By default, sources run concurrently via Promise.allSettled(). When
57
+ * `phaseGroup.sequential` is true, sources run one at a time in order,
58
+ * stopping at the first source that returns a non-null finding.
59
+ *
60
+ * Fires onSourceAttempt before each lookup and onSourceComplete after.
61
+ * Returns the phase's findings, attempt/success counts, and cost.
62
+ */
63
+ private executePhase;
64
+ /**
65
+ * Execute sources concurrently via Promise.allSettled().
66
+ */
67
+ private executePhaseConcurrently;
68
+ /**
69
+ * Execute sources sequentially, stopping at the first non-null finding.
70
+ * Used for AI model phases where cheapest-first ordering controls cost.
71
+ */
72
+ private executePhaseSequentially;
73
+ /**
74
+ * Check whether early stopping criteria are met.
75
+ *
76
+ * Returns a reason string if stopping should occur, or null to continue.
77
+ */
78
+ private checkEarlyStop;
79
+ /**
80
+ * Research multiple subjects with bounded concurrency and lifecycle hooks.
81
+ *
82
+ * Uses ParallelBatchRunner for concurrent subject processing with shared
83
+ * rate limiting. Fires lifecycle hooks at each stage for observability:
84
+ * database writes, progress bars, monitoring dashboards, etc.
85
+ *
86
+ * @param subjects - Array of subjects to research
87
+ * @param hooks - Optional lifecycle hooks for progress and monitoring
88
+ * @returns Map of subject ID → DebriefResult
89
+ */
90
+ debriefBatch(subjects: TSubject[], hooks?: LifecycleHooks<TSubject, TOutput>): Promise<Map<string | number, DebriefResult<TOutput>>>;
91
+ }
92
+ //# sourceMappingURL=orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAGd,aAAa,EACb,gBAAgB,EAEhB,WAAW,EACX,cAAc,EAEf,MAAM,YAAY,CAAA;AAanB;;;;;;GAMG;AACH,qBAAa,oBAAoB,CAAC,QAAQ,SAAS,eAAe,EAAE,OAAO;IACzE,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,WAAW,CAAmB;IACtC,OAAO,CAAC,SAAS,CAAmB;gBAGlC,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,EAAE,EACpC,WAAW,EAAE,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,EAC3C,MAAM,GAAE,cAAmB;IAwB7B;;;;;;;;;;;;OAYG;IACG,OAAO,CACX,OAAO,EAAE,QAAQ,EACjB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,KAAK,CAAC,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;KAAE,GAC5E,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAsElC;;;;;;;;;OASG;YACW,YAAY;IA6B1B;;OAEG;YACW,wBAAwB;IAiEtC;;;OAGG;YACW,wBAAwB;IAmEtC;;;;OAIG;IACH,OAAO,CAAC,cAAc;IA6BtB;;;;;;;;;;OAUG;IACG,YAAY,CAChB,QAAQ,EAAE,QAAQ,EAAE,EACpB,KAAK,CAAC,EAAE,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,GACxC,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;CAuGzD"}
@@ -0,0 +1,373 @@
1
+ /**
2
+ * Research Orchestrator — the core engine that wires sources, phases,
3
+ * rate limiting, cost tracking, and synthesis into a complete pipeline.
4
+ *
5
+ * Two entry points:
6
+ * - `debrief(subject)` — research a single subject through all phases
7
+ * - `debriefBatch(subjects, hooks)` — research multiple subjects with
8
+ * concurrency, cost limits, and lifecycle hooks
9
+ *
10
+ * Algorithm (per subject):
11
+ * 1. For each phase in order:
12
+ * a. Filter to available sources (isAvailable())
13
+ * b. Execute sources — concurrently via Promise.allSettled() by default,
14
+ * or sequentially (stop at first success) when phase.sequential is true
15
+ * c. Collect successful findings, tag with reliability info → ScoredFinding
16
+ * d. Check early-stop: do we have earlyStopThreshold+ high-quality families?
17
+ * e. Check per-subject cost limit
18
+ * 2. Synthesize all accumulated findings via the injected Synthesizer
19
+ * 3. Return DebriefResult
20
+ */
21
+ import { SourceRateLimiter } from "./rate-limiter.js";
22
+ import { BatchCostTracker } from "./cost-tracker.js";
23
+ import { ParallelBatchRunner } from "./batch-runner.js";
24
+ import { NoopTelemetry } from "./telemetry/noop.js";
25
+ const DEFAULT_CONFIG = {
26
+ concurrency: 5,
27
+ confidenceThreshold: 0.6,
28
+ reliabilityThreshold: 0.6,
29
+ earlyStopThreshold: 3,
30
+ };
31
+ /**
32
+ * Generic research orchestrator that coordinates source phases, rate limiting,
33
+ * cost tracking, and AI synthesis into a complete research pipeline.
34
+ *
35
+ * @typeParam TSubject - The research subject type (extends ResearchSubject)
36
+ * @typeParam TOutput - The structured output type produced by synthesis
37
+ */
38
+ export class ResearchOrchestrator {
39
+ phases;
40
+ synthesizer;
41
+ config;
42
+ rateLimiter;
43
+ telemetry;
44
+ constructor(phases, synthesizer, config = {}) {
45
+ this.phases = phases;
46
+ this.synthesizer = synthesizer;
47
+ this.config = { ...DEFAULT_CONFIG, ...config };
48
+ this.rateLimiter = new SourceRateLimiter();
49
+ this.telemetry = config.telemetry ?? new NoopTelemetry();
50
+ // Inject infrastructure into all sources
51
+ for (const phase of phases) {
52
+ for (const source of phase.sources) {
53
+ if ("setRateLimiter" in source && typeof source.setRateLimiter === "function") {
54
+ source.setRateLimiter(this.rateLimiter);
55
+ }
56
+ if ("setCache" in source && typeof source.setCache === "function" && config.cache) {
57
+ source.setCache(config.cache);
58
+ }
59
+ if ("setTelemetry" in source && typeof source.setTelemetry === "function") {
60
+ source.setTelemetry(this.telemetry);
61
+ }
62
+ }
63
+ }
64
+ }
65
+ /**
66
+ * Research a single subject through all configured phases.
67
+ *
68
+ * Iterates through phases sequentially. Within each phase, sources run
69
+ * concurrently via Promise.allSettled by default, or sequentially (stopping
70
+ * at first success) when `phase.sequential` is true. Accumulates findings,
71
+ * checks early stopping between phases, then runs synthesis on all collected
72
+ * findings.
73
+ *
74
+ * @param subject - The subject to research
75
+ * @param options - Optional abort signal and lifecycle hooks
76
+ * @returns Complete debrief result with findings, synthesis, and cost data
77
+ */
78
+ async debrief(subject, options) {
79
+ const startTime = Date.now();
80
+ const allFindings = [];
81
+ let totalCostUsd = 0;
82
+ let sourcesAttempted = 0;
83
+ let sourcesSucceeded = 0;
84
+ let stoppedAtPhase;
85
+ const signal = options?.signal;
86
+ const hooks = options?.hooks;
87
+ for (const phaseGroup of this.phases) {
88
+ if (signal?.aborted)
89
+ break;
90
+ const phaseResult = await this.executePhase(subject, phaseGroup, signal, hooks);
91
+ sourcesAttempted += phaseResult.sourcesAttempted;
92
+ sourcesSucceeded += phaseResult.sourcesSucceeded;
93
+ totalCostUsd += phaseResult.costUsd;
94
+ allFindings.push(...phaseResult.findings);
95
+ hooks?.onPhaseComplete?.(subject, phaseGroup.phase, phaseResult.findings);
96
+ const earlyStopReason = this.checkEarlyStop(allFindings, totalCostUsd);
97
+ if (earlyStopReason) {
98
+ stoppedAtPhase = phaseGroup.phase;
99
+ hooks?.onEarlyStop?.(subject, phaseGroup.phase, earlyStopReason);
100
+ if (earlyStopReason === "cost_limit") {
101
+ hooks?.onCostLimitReached?.(subject, totalCostUsd, this.config.costLimits.maxCostPerSubject);
102
+ }
103
+ break;
104
+ }
105
+ }
106
+ // Synthesize all findings
107
+ let synthesisResult = undefined;
108
+ if (allFindings.length > 0) {
109
+ hooks?.onSynthesisStart?.(subject, allFindings.length);
110
+ try {
111
+ synthesisResult = await this.synthesizer.synthesize(subject, allFindings, this.config.synthesis ?? {});
112
+ totalCostUsd += synthesisResult.costUsd;
113
+ hooks?.onSynthesisComplete?.(subject, synthesisResult);
114
+ }
115
+ catch (error) {
116
+ this.telemetry.recordError(error instanceof Error ? error : new Error(String(error)), {
117
+ subject: subject.name,
118
+ phase: "synthesis",
119
+ });
120
+ }
121
+ }
122
+ return {
123
+ subject,
124
+ data: synthesisResult?.data ?? null,
125
+ findings: allFindings,
126
+ synthesisResult,
127
+ totalCostUsd,
128
+ sourcesAttempted,
129
+ sourcesSucceeded,
130
+ stoppedAtPhase,
131
+ durationMs: Date.now() - startTime,
132
+ };
133
+ }
134
+ /**
135
+ * Execute all available sources in a single phase.
136
+ *
137
+ * By default, sources run concurrently via Promise.allSettled(). When
138
+ * `phaseGroup.sequential` is true, sources run one at a time in order,
139
+ * stopping at the first source that returns a non-null finding.
140
+ *
141
+ * Fires onSourceAttempt before each lookup and onSourceComplete after.
142
+ * Returns the phase's findings, attempt/success counts, and cost.
143
+ */
144
+ async executePhase(subject, phaseGroup, signal, hooks) {
145
+ const availableSources = phaseGroup.sources.filter((s) => s.isAvailable());
146
+ if (availableSources.length === 0) {
147
+ return { findings: [], sourcesAttempted: 0, sourcesSucceeded: 0, costUsd: 0 };
148
+ }
149
+ if (phaseGroup.sequential) {
150
+ return this.executePhaseSequentially(subject, availableSources, phaseGroup.phase, signal, hooks);
151
+ }
152
+ return this.executePhaseConcurrently(subject, availableSources, phaseGroup.phase, signal, hooks);
153
+ }
154
+ /**
155
+ * Execute sources concurrently via Promise.allSettled().
156
+ */
157
+ async executePhaseConcurrently(subject, availableSources, phase, signal, hooks) {
158
+ const timeoutSignal = AbortSignal.timeout(120_000);
159
+ const phaseSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
160
+ const results = await Promise.allSettled(availableSources.map(async (source) => {
161
+ hooks?.onSourceAttempt?.(subject, source.name, phase);
162
+ return source.lookup(subject, phaseSignal);
163
+ }));
164
+ const findings = [];
165
+ let costUsd = 0;
166
+ let sourcesSucceeded = 0;
167
+ for (let i = 0; i < results.length; i++) {
168
+ const result = results[i];
169
+ const source = availableSources[i];
170
+ const finding = result.status === "fulfilled" ? result.value : null;
171
+ if (result.status === "rejected") {
172
+ this.telemetry.recordError(result.reason instanceof Error ? result.reason : new Error(String(result.reason)), { source: source.name, subject: subject.name, phase });
173
+ }
174
+ try {
175
+ hooks?.onSourceComplete?.(subject, source.name, finding, finding?.costUsd ?? 0);
176
+ }
177
+ catch (error) {
178
+ this.telemetry.recordError(error instanceof Error ? error : new Error(String(error)), {
179
+ hook: "onSourceComplete",
180
+ source: source.name,
181
+ subject: subject.name,
182
+ phase,
183
+ });
184
+ }
185
+ if (finding) {
186
+ costUsd += finding.costUsd;
187
+ sourcesSucceeded++;
188
+ findings.push({
189
+ ...finding,
190
+ sourceType: source.type,
191
+ sourceName: source.name,
192
+ reliabilityTier: source.reliabilityTier,
193
+ reliabilityScore: source.reliabilityScore,
194
+ });
195
+ }
196
+ }
197
+ return { findings, sourcesAttempted: availableSources.length, sourcesSucceeded, costUsd };
198
+ }
199
+ /**
200
+ * Execute sources sequentially, stopping at the first non-null finding.
201
+ * Used for AI model phases where cheapest-first ordering controls cost.
202
+ */
203
+ async executePhaseSequentially(subject, availableSources, phase, signal, hooks) {
204
+ const timeoutSignal = AbortSignal.timeout(120_000);
205
+ const phaseSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
206
+ const findings = [];
207
+ let costUsd = 0;
208
+ let sourcesAttempted = 0;
209
+ let sourcesSucceeded = 0;
210
+ for (const source of availableSources) {
211
+ if (phaseSignal.aborted)
212
+ break;
213
+ sourcesAttempted++;
214
+ let finding = null;
215
+ try {
216
+ hooks?.onSourceAttempt?.(subject, source.name, phase);
217
+ finding = await source.lookup(subject, phaseSignal);
218
+ }
219
+ catch (error) {
220
+ // Source/hook errors are swallowed — consistent with concurrent path
221
+ // where async callbacks turn throws into rejected promises.
222
+ this.telemetry.recordError(error instanceof Error ? error : new Error(String(error)), {
223
+ source: source.name,
224
+ subject: subject.name,
225
+ phase,
226
+ });
227
+ }
228
+ try {
229
+ hooks?.onSourceComplete?.(subject, source.name, finding, finding?.costUsd ?? 0);
230
+ }
231
+ catch (error) {
232
+ this.telemetry.recordError(error instanceof Error ? error : new Error(String(error)), {
233
+ source: source.name,
234
+ subject: subject.name,
235
+ phase,
236
+ hook: "onSourceComplete",
237
+ });
238
+ }
239
+ if (finding) {
240
+ costUsd += finding.costUsd;
241
+ sourcesSucceeded++;
242
+ findings.push({
243
+ ...finding,
244
+ sourceType: source.type,
245
+ sourceName: source.name,
246
+ reliabilityTier: source.reliabilityTier,
247
+ reliabilityScore: source.reliabilityScore,
248
+ });
249
+ break; // Stop at first success
250
+ }
251
+ }
252
+ return { findings, sourcesAttempted, sourcesSucceeded, costUsd };
253
+ }
254
+ /**
255
+ * Check whether early stopping criteria are met.
256
+ *
257
+ * Returns a reason string if stopping should occur, or null to continue.
258
+ */
259
+ checkEarlyStop(allFindings, totalCostUsd) {
260
+ const confidenceThreshold = this.config.confidenceThreshold ?? DEFAULT_CONFIG.confidenceThreshold;
261
+ const reliabilityThreshold = this.config.reliabilityThreshold ?? DEFAULT_CONFIG.reliabilityThreshold;
262
+ const earlyStopThreshold = this.config.earlyStopThreshold ?? DEFAULT_CONFIG.earlyStopThreshold;
263
+ const highQualityFamilies = new Set(allFindings
264
+ .filter((f) => f.confidence >= confidenceThreshold && f.reliabilityScore >= reliabilityThreshold)
265
+ .map((f) => f.sourceType));
266
+ if (highQualityFamilies.size >= earlyStopThreshold) {
267
+ return `${highQualityFamilies.size} high-quality source families met threshold of ${earlyStopThreshold}`;
268
+ }
269
+ if (this.config.costLimits?.maxCostPerSubject &&
270
+ totalCostUsd >= this.config.costLimits.maxCostPerSubject) {
271
+ return "cost_limit";
272
+ }
273
+ return null;
274
+ }
275
+ /**
276
+ * Research multiple subjects with bounded concurrency and lifecycle hooks.
277
+ *
278
+ * Uses ParallelBatchRunner for concurrent subject processing with shared
279
+ * rate limiting. Fires lifecycle hooks at each stage for observability:
280
+ * database writes, progress bars, monitoring dashboards, etc.
281
+ *
282
+ * @param subjects - Array of subjects to research
283
+ * @param hooks - Optional lifecycle hooks for progress and monitoring
284
+ * @returns Map of subject ID → DebriefResult
285
+ */
286
+ async debriefBatch(subjects, hooks) {
287
+ const startTime = Date.now();
288
+ const concurrency = this.config.concurrency ?? DEFAULT_CONFIG.concurrency;
289
+ const resultMap = new Map();
290
+ const costTracker = this.config.costLimits?.maxTotalCost
291
+ ? new BatchCostTracker({
292
+ maxTotalCost: this.config.costLimits.maxTotalCost,
293
+ })
294
+ : undefined;
295
+ hooks?.onRunStart?.(subjects.length, this.config);
296
+ const runner = new ParallelBatchRunner({
297
+ concurrency,
298
+ onItemComplete: (subject, result, progress) => {
299
+ resultMap.set(subject.id, result);
300
+ if (costTracker) {
301
+ costTracker.addSubjectCost(subject.id, result.totalCostUsd);
302
+ }
303
+ hooks?.onSubjectComplete?.(subject, result);
304
+ // Calculate running total cost across all completed subjects
305
+ const runningCost = costTracker?.getTotalCost() ??
306
+ Array.from(resultMap.values()).reduce((sum, r) => sum + r.totalCostUsd, 0);
307
+ hooks?.onBatchProgress?.({
308
+ completed: progress.completed,
309
+ total: progress.total,
310
+ costUsd: runningCost,
311
+ elapsedMs: Date.now() - startTime,
312
+ });
313
+ },
314
+ onItemError: (subject, error) => {
315
+ // Per-subject errors are not batch failures — the batch continues.
316
+ // Report via onSubjectComplete with null data.
317
+ const errorResult = {
318
+ subject,
319
+ data: null,
320
+ findings: [],
321
+ totalCostUsd: 0,
322
+ sourcesAttempted: 0,
323
+ sourcesSucceeded: 0,
324
+ durationMs: 0,
325
+ };
326
+ resultMap.set(subject.id, errorResult);
327
+ hooks?.onSubjectComplete?.(subject, errorResult);
328
+ this.telemetry.recordError(error, { subject: subject.name, phase: "batch" });
329
+ },
330
+ });
331
+ const batchResults = await runner.run(subjects, async (subject) => {
332
+ // Check total cost limit before starting
333
+ if (costTracker?.isTotalLimitExceeded()) {
334
+ return {
335
+ subject,
336
+ data: null,
337
+ findings: [],
338
+ totalCostUsd: 0,
339
+ sourcesAttempted: 0,
340
+ sourcesSucceeded: 0,
341
+ durationMs: 0,
342
+ };
343
+ }
344
+ hooks?.onSubjectStart?.(subject, resultMap.size, subjects.length);
345
+ return this.debrief(subject, { hooks });
346
+ });
347
+ // Ensure results from cost-limited subjects (which still succeed via
348
+ // onItemComplete) and any edge cases are captured in the map
349
+ for (const entry of batchResults) {
350
+ if (entry.result && !resultMap.has(entry.item.id)) {
351
+ resultMap.set(entry.item.id, entry.result);
352
+ }
353
+ }
354
+ const totalCost = costTracker?.getTotalCost() ??
355
+ Array.from(resultMap.values()).reduce((sum, r) => sum + r.totalCostUsd, 0);
356
+ const succeeded = Array.from(resultMap.values()).filter((r) => r.data !== null).length;
357
+ hooks?.onRunComplete?.({
358
+ completed: resultMap.size,
359
+ total: subjects.length,
360
+ costUsd: totalCost,
361
+ elapsedMs: Date.now() - startTime,
362
+ succeeded,
363
+ failed: resultMap.size - succeeded,
364
+ avgCostPerSubject: resultMap.size > 0 ? totalCost / resultMap.size : 0,
365
+ avgDurationMs: resultMap.size > 0
366
+ ? Array.from(resultMap.values()).reduce((sum, r) => sum + r.durationMs, 0) /
367
+ resultMap.size
368
+ : 0,
369
+ });
370
+ return resultMap;
371
+ }
372
+ }
373
+ //# sourceMappingURL=orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAcH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,MAAM,cAAc,GAAG;IACrB,WAAW,EAAE,CAAC;IACd,mBAAmB,EAAE,GAAG;IACxB,oBAAoB,EAAE,GAAG;IACzB,kBAAkB,EAAE,CAAC;CACb,CAAA;AAEV;;;;;;GAMG;AACH,MAAM,OAAO,oBAAoB;IACvB,MAAM,CAA8B;IACpC,WAAW,CAAgC;IAC3C,MAAM,CAAgB;IACtB,WAAW,CAAmB;IAC9B,SAAS,CAAmB;IAEpC,YACE,MAAoC,EACpC,WAA2C,EAC3C,SAAyB,EAAE;QAE3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;QAC9B,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAA;QAC9C,IAAI,CAAC,WAAW,GAAG,IAAI,iBAAiB,EAAE,CAAA;QAC1C,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,IAAI,aAAa,EAAE,CAAA;QAExD,yCAAyC;QACzC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBACnC,IAAI,gBAAgB,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,cAAc,KAAK,UAAU,EAAE,CAAC;oBAC9E,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;gBACzC,CAAC;gBACD,IAAI,UAAU,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,UAAU,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;oBAClF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;gBAC/B,CAAC;gBACD,IAAI,cAAc,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;oBAC1E,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;gBACrC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,OAAO,CACX,OAAiB,EACjB,OAA6E;QAE7E,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC5B,MAAM,WAAW,GAAoB,EAAE,CAAA;QACvC,IAAI,YAAY,GAAG,CAAC,CAAA;QACpB,IAAI,gBAAgB,GAAG,CAAC,CAAA;QACxB,IAAI,gBAAgB,GAAG,CAAC,CAAA;QACxB,IAAI,cAAkC,CAAA;QAEtC,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,CAAA;QAC9B,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,CAAA;QAE5B,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACrC,IAAI,MAAM,EAAE,OAAO;gBAAE,MAAK;YAE1B,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;YAC/E,gBAAgB,IAAI,WAAW,CAAC,gBAAgB,CAAA;YAChD,gBAAgB,IAAI,WAAW,CAAC,gBAAgB,CAAA;YAChD,YAAY,IAAI,WAAW,CAAC,OAAO,CAAA;YACnC,WAAW,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;YAEzC,KAAK,EAAE,eAAe,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;YAEzE,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;YACtE,IAAI,eAAe,EAAE,CAAC;gBACpB,cAAc,GAAG,UAAU,CAAC,KAAK,CAAA;gBACjC,KAAK,EAAE,WAAW,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,KAAK,EAAE,eAAe,CAAC,CAAA;gBAChE,IAAI,eAAe,KAAK,YAAY,EAAE,CAAC;oBACrC,KAAK,EAAE,kBAAkB,EAAE,CACzB,OAAO,EACP,YAAY,EACZ,IAAI,CAAC,MAAM,CAAC,UAAW,CAAC,iBAAkB,CAC3C,CAAA;gBACH,CAAC;gBACD,MAAK;YACP,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,IAAI,eAAe,GAAG,SAAS,CAAA;QAC/B,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,KAAK,EAAE,gBAAgB,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;YACtD,IAAI,CAAC;gBACH,eAAe,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CACjD,OAAO,EACP,WAAW,EACX,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAC5B,CAAA;gBACD,YAAY,IAAI,eAAe,CAAC,OAAO,CAAA;gBACvC,KAAK,EAAE,mBAAmB,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,CAAA;YACxD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;oBACpF,OAAO,EAAE,OAAO,CAAC,IAAI;oBACrB,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO;YACP,IAAI,EAAE,eAAe,EAAE,IAAI,IAAI,IAAI;YACnC,QAAQ,EAAE,WAAW;YACrB,eAAe;YACf,YAAY;YACZ,gBAAgB;YAChB,gBAAgB;YAChB,cAAc;YACd,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SACnC,CAAA;IACH,CAAC;IAED;;;;;;;;;OASG;IACK,KAAK,CAAC,YAAY,CACxB,OAAiB,EACjB,UAAsC,EACtC,MAA+B,EAC/B,KAAoD;QAOpD,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAA;QAC1E,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,gBAAgB,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;QAC/E,CAAC;QAED,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,wBAAwB,CAClC,OAAO,EACP,gBAAgB,EAChB,UAAU,CAAC,KAAK,EAChB,MAAM,EACN,KAAK,CACN,CAAA;QACH,CAAC;QAED,OAAO,IAAI,CAAC,wBAAwB,CAAC,OAAO,EAAE,gBAAgB,EAAE,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;IAClG,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,wBAAwB,CACpC,OAAiB,EACjB,gBAA2C,EAC3C,KAAa,EACb,MAA+B,EAC/B,KAAoD;QAOpD,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAClD,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAA;QAErF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YACpC,KAAK,EAAE,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YACrD,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;QAC5C,CAAC,CAAC,CACH,CAAA;QAED,MAAM,QAAQ,GAAoB,EAAE,CAAA;QACpC,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,IAAI,gBAAgB,GAAG,CAAC,CAAA;QAExB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAE,CAAA;YAC1B,MAAM,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAE,CAAA;YACnC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAE,MAAM,CAAC,KAA2B,CAAC,CAAC,CAAC,IAAI,CAAA;YAE1F,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBACjC,IAAI,CAAC,SAAS,CAAC,WAAW,CACxB,MAAM,CAAC,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EACjF,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,CACtD,CAAA;YACH,CAAC;YAED,IAAI,CAAC;gBACH,KAAK,EAAE,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,CAAC,CAAC,CAAA;YACjF,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;oBACpF,IAAI,EAAE,kBAAkB;oBACxB,MAAM,EAAE,MAAM,CAAC,IAAI;oBACnB,OAAO,EAAE,OAAO,CAAC,IAAI;oBACrB,KAAK;iBACN,CAAC,CAAA;YACJ,CAAC;YAED,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,IAAI,OAAO,CAAC,OAAO,CAAA;gBAC1B,gBAAgB,EAAE,CAAA;gBAClB,QAAQ,CAAC,IAAI,CAAC;oBACZ,GAAG,OAAO;oBACV,UAAU,EAAE,MAAM,CAAC,IAAI;oBACvB,UAAU,EAAE,MAAM,CAAC,IAAI;oBACvB,eAAe,EAAE,MAAM,CAAC,eAAe;oBACvC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;iBAC1C,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAA;IAC3F,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,wBAAwB,CACpC,OAAiB,EACjB,gBAA2C,EAC3C,KAAa,EACb,MAA+B,EAC/B,KAAoD;QAOpD,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAClD,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAA;QAErF,MAAM,QAAQ,GAAoB,EAAE,CAAA;QACpC,IAAI,OAAO,GAAG,CAAC,CAAA;QACf,IAAI,gBAAgB,GAAG,CAAC,CAAA;QACxB,IAAI,gBAAgB,GAAG,CAAC,CAAA;QAExB,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;YACtC,IAAI,WAAW,CAAC,OAAO;gBAAE,MAAK;YAE9B,gBAAgB,EAAE,CAAA;YAElB,IAAI,OAAO,GAAsB,IAAI,CAAA;YACrC,IAAI,CAAC;gBACH,KAAK,EAAE,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;gBACrD,OAAO,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;YACrD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,qEAAqE;gBACrE,4DAA4D;gBAC5D,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;oBACpF,MAAM,EAAE,MAAM,CAAC,IAAI;oBACnB,OAAO,EAAE,OAAO,CAAC,IAAI;oBACrB,KAAK;iBACN,CAAC,CAAA;YACJ,CAAC;YAED,IAAI,CAAC;gBACH,KAAK,EAAE,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,CAAC,CAAC,CAAA;YACjF,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;oBACpF,MAAM,EAAE,MAAM,CAAC,IAAI;oBACnB,OAAO,EAAE,OAAO,CAAC,IAAI;oBACrB,KAAK;oBACL,IAAI,EAAE,kBAAkB;iBACzB,CAAC,CAAA;YACJ,CAAC;YAED,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,IAAI,OAAO,CAAC,OAAO,CAAA;gBAC1B,gBAAgB,EAAE,CAAA;gBAClB,QAAQ,CAAC,IAAI,CAAC;oBACZ,GAAG,OAAO;oBACV,UAAU,EAAE,MAAM,CAAC,IAAI;oBACvB,UAAU,EAAE,MAAM,CAAC,IAAI;oBACvB,eAAe,EAAE,MAAM,CAAC,eAAe;oBACvC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;iBAC1C,CAAC,CAAA;gBACF,MAAK,CAAC,wBAAwB;YAChC,CAAC;QACH,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAA;IAClE,CAAC;IAED;;;;OAIG;IACK,cAAc,CAAC,WAA4B,EAAE,YAAoB;QACvE,MAAM,mBAAmB,GACvB,IAAI,CAAC,MAAM,CAAC,mBAAmB,IAAI,cAAc,CAAC,mBAAmB,CAAA;QACvE,MAAM,oBAAoB,GACxB,IAAI,CAAC,MAAM,CAAC,oBAAoB,IAAI,cAAc,CAAC,oBAAoB,CAAA;QACzE,MAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC,kBAAkB,IAAI,cAAc,CAAC,kBAAkB,CAAA;QAE9F,MAAM,mBAAmB,GAAG,IAAI,GAAG,CACjC,WAAW;aACR,MAAM,CACL,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,mBAAmB,IAAI,CAAC,CAAC,gBAAgB,IAAI,oBAAoB,CACzF;aACA,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAC5B,CAAA;QAED,IAAI,mBAAmB,CAAC,IAAI,IAAI,kBAAkB,EAAE,CAAC;YACnD,OAAO,GAAG,mBAAmB,CAAC,IAAI,kDAAkD,kBAAkB,EAAE,CAAA;QAC1G,CAAC;QAED,IACE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,iBAAiB;YACzC,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,iBAAiB,EACxD,CAAC;YACD,OAAO,YAAY,CAAA;QACrB,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,YAAY,CAChB,QAAoB,EACpB,KAAyC;QAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,cAAc,CAAC,WAAW,CAAA;QACzE,MAAM,SAAS,GAAG,IAAI,GAAG,EAA2C,CAAA;QAEpE,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY;YACtD,CAAC,CAAC,IAAI,gBAAgB,CAAC;gBACnB,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY;aAClD,CAAC;YACJ,CAAC,CAAC,SAAS,CAAA;QAEb,KAAK,EAAE,UAAU,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAEjD,MAAM,MAAM,GAAG,IAAI,mBAAmB,CAAmC;YACvE,WAAW;YACX,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;gBAC5C,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;gBAEjC,IAAI,WAAW,EAAE,CAAC;oBAChB,WAAW,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;gBAC7D,CAAC;gBAED,KAAK,EAAE,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;gBAE3C,6DAA6D;gBAC7D,MAAM,WAAW,GACf,WAAW,EAAE,YAAY,EAAE;oBAC3B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;gBAE5E,KAAK,EAAE,eAAe,EAAE,CAAC;oBACvB,SAAS,EAAE,QAAQ,CAAC,SAAS;oBAC7B,KAAK,EAAE,QAAQ,CAAC,KAAK;oBACrB,OAAO,EAAE,WAAW;oBACpB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;iBAClC,CAAC,CAAA;YACJ,CAAC;YACD,WAAW,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;gBAC9B,mEAAmE;gBACnE,+CAA+C;gBAC/C,MAAM,WAAW,GAA2B;oBAC1C,OAAO;oBACP,IAAI,EAAE,IAAI;oBACV,QAAQ,EAAE,EAAE;oBACZ,YAAY,EAAE,CAAC;oBACf,gBAAgB,EAAE,CAAC;oBACnB,gBAAgB,EAAE,CAAC;oBACnB,UAAU,EAAE,CAAC;iBACd,CAAA;gBACD,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,WAAW,CAAC,CAAA;gBACtC,KAAK,EAAE,iBAAiB,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;gBAChD,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;YAC9E,CAAC;SACF,CAAC,CAAA;QAEF,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAChE,yCAAyC;YACzC,IAAI,WAAW,EAAE,oBAAoB,EAAE,EAAE,CAAC;gBACxC,OAAO;oBACL,OAAO;oBACP,IAAI,EAAE,IAAI;oBACV,QAAQ,EAAE,EAAE;oBACZ,YAAY,EAAE,CAAC;oBACf,gBAAgB,EAAE,CAAC;oBACnB,gBAAgB,EAAE,CAAC;oBACnB,UAAU,EAAE,CAAC;iBACd,CAAA;YACH,CAAC;YAED,KAAK,EAAE,cAAc,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;YACjE,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QACzC,CAAC,CAAC,CAAA;QAEF,qEAAqE;QACrE,6DAA6D;QAC7D,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;gBAClD,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;YAC5C,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GACb,WAAW,EAAE,YAAY,EAAE;YAC3B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;QAE5E,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,MAAM,CAAA;QAEtF,KAAK,EAAE,aAAa,EAAE,CAAC;YACrB,SAAS,EAAE,SAAS,CAAC,IAAI;YACzB,KAAK,EAAE,QAAQ,CAAC,MAAM;YACtB,OAAO,EAAE,SAAS;YAClB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;YACjC,SAAS;YACT,MAAM,EAAE,SAAS,CAAC,IAAI,GAAG,SAAS;YAClC,iBAAiB,EAAE,SAAS,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACtE,aAAa,EACX,SAAS,CAAC,IAAI,GAAG,CAAC;gBAChB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;oBACxE,SAAS,CAAC,IAAI;gBAChB,CAAC,CAAC,CAAC;SACR,CAAC,CAAA;QAEF,OAAO,SAAS,CAAA;IAClB,CAAC;CACF"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Per-domain async rate limiter shared across all source instances.
3
+ *
4
+ * Uses an async queue per domain to prevent thundering herd — when multiple
5
+ * callers request the same domain simultaneously, they're serialized so each
6
+ * waits the correct delay after the previous one, rather than all sleeping
7
+ * the same amount and firing together.
8
+ *
9
+ * Example: Three sources all query en.wikipedia.org. Without rate limiting,
10
+ * they'd fire simultaneously and risk being blocked. The rate limiter
11
+ * serializes them with configurable delays between requests.
12
+ */
13
+ export interface RateLimiterStats {
14
+ totalRequests: number;
15
+ totalWaitMs: number;
16
+ }
17
+ export declare class SourceRateLimiter {
18
+ private domains;
19
+ private getOrCreateDomain;
20
+ /**
21
+ * Acquire permission to make a request to the given domain.
22
+ * Blocks until minDelayMs has passed since the last request to this domain.
23
+ */
24
+ acquire(domain: string, minDelayMs: number): Promise<void>;
25
+ private processQueue;
26
+ /** Get rate limiting stats per domain */
27
+ getStats(): Map<string, RateLimiterStats>;
28
+ /** Reset all state (useful for testing) */
29
+ reset(): void;
30
+ }
31
+ //# sourceMappingURL=rate-limiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../src/rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAaH,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAiC;IAEhD,OAAO,CAAC,iBAAiB;IAezB;;;OAGG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YASlD,YAAY;IAyB1B,yCAAyC;IACzC,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAWzC,2CAA2C;IAC3C,KAAK,IAAI,IAAI;CAGd"}