Skip to content

@lastshotlabs/slingshot-mail

npm install @lastshotlabs/slingshot-mail

Creates a durable, Redis-backed mail queue powered by BullMQ.

Requires bullmq and ioredis as installed dependencies — both are optional peers. The queue tests the Redis connection eagerly on start() to surface misconfiguration at startup rather than at first delivery attempt.

Non-retryable failures (e.g. provider-rejected messages) are wrapped in BullMQ.UnrecoverableError so they bypass BullMQ’s built-in retry backoff and are dead-lettered immediately. The original MailSendError context (statusCode, providerError) is preserved and forwarded to onDeadLetter.

function createBullMQMailQueue(config: BullMQMailQueueConfig): MailQueue

Source: packages/slingshot-mail/src/queues/bullmq.ts

Creates the slingshot-mail plugin for event-driven transactional email delivery.

Validates the config and adapter shapes at construction time (fail-fast). Mail delivery is entirely event-driven — subscribe to SlingshotEventMap keys via config.subscriptions and the plugin dispatches templated emails automatically when those events fire.

function createMailPlugin(rawConfig: MailPluginConfig): SlingshotPlugin

Source: packages/slingshot-mail/src/plugin.ts

Creates an in-process, non-durable mail queue for development and testing.

Jobs are held in memory and processed inline - no external dependencies required. This queue is not suitable for production: all pending jobs are lost on process restart. Use createBullMQMailQueue for durable, Redis-backed delivery.

Remarks: Prints a startup warning to console.warn to make the non-durable nature visible. The warning is intentional and should not be suppressed.

function createMemoryQueue(config?: MailQueueConfig): MailQueue

Source: packages/slingshot-mail/src/queues/memory.ts

Maximum milliseconds a single HTTP send may run before the request is aborted with a retryable timeout error. Default: 30000.

function createPostmarkProvider(config: PostmarkConfig): MailProvider

Source: packages/slingshot-mail/src/providers/postmark.ts

A static HTML template with optional {{variable}} interpolation placeholders.

Variable syntax: {{key}} - all values are coerced to strings safely. Missing keys render as empty strings rather than throwing.

function createRawHtmlRenderer(config: RawHtmlRendererConfig): MailRenderer

Source: packages/slingshot-mail/src/renderers/rawHtml.ts

Creates a MailRenderer backed by @react-email/render.

Components are plain React functional components that receive the dataMapper output as props. @react-email/render is loaded lazily on first render - install it as a peer dependency. Plain-text extraction is attempted via render(..., { plainText: true }); if it fails the text body is omitted with a warning.

Remarks: Components must be synchronous. Async server components are not supported by @react-email/render.

function createReactEmailRenderer(config: ReactEmailRendererConfig): MailRenderer

Source: packages/slingshot-mail/src/renderers/reactEmail.ts

Maximum milliseconds a single HTTP send may run before the request is aborted with a retryable timeout error. Default: 30000.

function createResendProvider(config: ResendConfig): MailProvider

Source: packages/slingshot-mail/src/providers/resend.ts

Maximum milliseconds a single HTTP send may run before the request is aborted with a retryable timeout error. Default: 30000.

function createSendgridProvider(config: SendgridConfig): MailProvider

Source: packages/slingshot-mail/src/providers/sendgrid.ts

Maximum milliseconds a single SDK send may run before the request is aborted with a retryable timeout error. Default: 30000.

function createSesProvider(config: SesConfig): MailProvider

Source: packages/slingshot-mail/src/providers/ses.ts

Declarative binding from a bus event to a mail template.

When the bus emits event, the plugin resolves the recipient via recipientMapper, renders template with data from dataMapper, and enqueues a delivery.

Source: packages/slingshot-mail/src/types/config.ts

Thrown at plugin startup when a subscription’s template cannot be found in the configured renderer. Lets callers fail fast instead of waiting for the first matching event to fire at runtime.

async function validateSubscriptionTemplates(config: MailPluginConfig): Promise<void>

Source: packages/slingshot-mail/src/lib/subscriptionWiring.ts

Consecutive-failure circuit breaker for outbound mail provider calls.

Mirrors the shape of slingshot-search’s typesense breaker and the slingshot-assets S3 breaker so operational behaviour stays uniform across production-track packages. The intent is to fail fast during sustained provider outages rather than let queue workers thrash against a degraded upstream.

Source: packages/slingshot-mail/src/lib/circuitBreaker.ts

An email address, expressed either as a bare address string or a structured object.

Source: packages/slingshot-mail/src/types/provider.ts

Thrown at plugin startup when a subscription’s template cannot be found in the configured renderer. Lets callers fail fast instead of waiting for the first matching event to fire at runtime.

Source: packages/slingshot-mail/src/lib/subscriptionWiring.ts

Consecutive-failure circuit breaker for outbound mail provider calls.

Mirrors the shape of slingshot-search’s typesense breaker and the slingshot-assets S3 breaker so operational behaviour stays uniform across production-track packages. The intent is to fail fast during sustained provider outages rather than let queue workers thrash against a degraded upstream.

Source: packages/slingshot-mail/src/lib/circuitBreaker.ts

Consecutive-failure circuit breaker for outbound mail provider calls.

Mirrors the shape of slingshot-search’s typesense breaker and the slingshot-assets S3 breaker so operational behaviour stays uniform across production-track packages. The intent is to fail fast during sustained provider outages rather than let queue workers thrash against a degraded upstream.

Source: packages/slingshot-mail/src/lib/circuitBreaker.ts

Consecutive-failure circuit breaker for outbound mail provider calls.

Mirrors the shape of slingshot-search’s typesense breaker and the slingshot-assets S3 breaker so operational behaviour stays uniform across production-track packages. The intent is to fail fast during sustained provider outages rather than let queue workers thrash against a degraded upstream.

Source: packages/slingshot-mail/src/lib/circuitBreaker.ts

A single mail delivery job tracked by the queue.

Exposed to onDeadLetter callbacks so callers can inspect what failed and why.

Source: packages/slingshot-mail/src/types/queue.ts

An email address, expressed either as a bare address string or a structured object.

Source: packages/slingshot-mail/src/types/provider.ts

An email address, expressed either as a bare address string or a structured object.

Source: packages/slingshot-mail/src/types/provider.ts

A single mail delivery job tracked by the queue.

Exposed to onDeadLetter callbacks so callers can inspect what failed and why.

Source: packages/slingshot-mail/src/types/queue.ts

A single mail delivery job tracked by the queue.

Exposed to onDeadLetter callbacks so callers can inspect what failed and why.

Source: packages/slingshot-mail/src/types/queue.ts

Declarative binding from a bus event to a mail template.

When the bus emits event, the plugin resolves the recipient via recipientMapper, renders template with data from dataMapper, and enqueues a delivery.

Source: packages/slingshot-mail/src/types/config.ts

A static HTML template with optional {{variable}} interpolation placeholders.

Variable syntax: {{key}} - all values are coerced to strings safely. Missing keys render as empty strings rather than throwing.

Source: packages/slingshot-mail/src/renderers/rawHtml.ts

An email address, expressed either as a bare address string or a structured object.

Source: packages/slingshot-mail/src/types/provider.ts

An email address, expressed either as a bare address string or a structured object.

Source: packages/slingshot-mail/src/types/provider.ts

Declarative binding from a bus event to a mail template.

When the bus emits event, the plugin resolves the recipient via recipientMapper, renders template with data from dataMapper, and enqueues a delivery.

Source: packages/slingshot-mail/src/types/config.ts