Every Riven plugin that communicates with an external HTTP API does so through a class that extendsDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/rivenmedia/riven-ts/llms.txt
Use this file to discover all available pages before exploring further.
BaseDataSource. Under the hood it layers a BullMQ job queue on top of Apollo’s RESTDataSource, giving every outgoing request automatic retry logic, exponential backoff, HTTP response caching via KeyvAdapter, and rate-limit awareness — without any extra boilerplate in your plugin code.
How BaseDataSource works
When your code callsthis.get(...) or this.post(...), the base class:
- Checks the Keyv HTTP cache. If a valid cached response exists the request is served immediately, bypassing the queue entirely.
- Otherwise, enqueues a
FetchJobInputjob on the plugin’s dedicated BullMQ queue (<pluginSymbol>-<ClassName>-fetch-queue). - The worker picks up the job (respecting
concurrencyand anyrateLimiterOptions) and performs the real HTTP fetch via Apollo’sRESTDataSource. - On a
429response the worker callsqueue.rateLimit(waitMs)and throwsWorker.RateLimitError(), which pauses the queue until theRetry-Afterinterval elapses. - On any other retryable status code the job is retried up to
requestAttemptstimes with exponential backoff (jitter ±50 %). - Fatal status codes cause the job to be returned immediately with
success: falseinstead of retrying.
The BullMQ worker is I/O-bound, which is why
concurrency defaults to 200. If your API is latency-sensitive or frequently times out, lower this value.Extending BaseDataSource
The validate() method
validate() is one of two abstract members on BaseDataSource — along with baseURL. Riven calls it at plugin startup (and on explicit health-check queries) to confirm the plugin can reach its API. Return true to signal success, false to signal a transient failure that may be retried, or throw a FatalValidationError when the credentials are permanently wrong. The return type is Promisable<boolean> (from type-fest), so you may return a plain boolean or a Promise<boolean>.
Configuration reference
BaseDataSource is instantiated by the Riven core automatically when your plugin is registered. You never call new MyAPI(config) yourself in production code. The config object type is:
The parsed, frozen settings object produced by
PluginSettings.get(YourSchema). Available as this.settings inside the class.The unique symbol from your
pluginConfig.name. Used to namespace the BullMQ queue.Maximum number of in-flight HTTP requests the worker processes simultaneously. Override the
protected readonly concurrency field on your subclass to change it.How many times a failing job is retried before being marked as failed.
Base delay in milliseconds for exponential backoff between retries. Actual delay is
delay * 2^attempt ± 50 % jitter.BullMQ Redis connection options, injected by the framework.
Winston logger instance, injected by the framework. Available as
this.logger.Status code behaviour
Retryable (non-fatal)
408, 425, 429, 500, 502, 503, 504 — the job is retried up to requestAttempts times using exponential backoff.Fatal (no retry)
Any other
4xx or 5xx — the job returns success: false immediately without consuming any retry attempts.Rate limiting
SetrateLimiterOptions on your subclass to engage BullMQ’s built-in rate limiter:
429 Too Many Requests, BaseDataSource automatically reads the Retry-After response header (as either seconds or an HTTP date), calls this.queue.rateLimit(waitMs), and throws Worker.RateLimitError(). The queue pauses and all pending jobs wait the correct duration before resuming.
HTTP caching
HTTP responses that include standard cache headers (Cache-Control, ETag, Last-Modified) are stored in Keyv automatically by the Apollo layer. On the next matching request BaseDataSource detects the cached entry and short-circuits the queue, returning the cached response without creating a BullMQ job at all.
BullMQ job context
Inside any event hook or DataSource method you can access the current BullMQ job and token via thedataSourceContext AsyncLocalStorage store:
Real-world example: CometAPI
The Comet scraper plugin shows a completeBaseDataSource subclass in production:
CometSettings schema supplies url (the instance base URL), which becomes this.settings.url — set via the RIVEN_PLUGIN_SETTING__REPO_PLUGIN_COMET__url environment variable.