Skip to main content

overview

Queues Overview

Balda.js provides a lightweight, provider-agnostic queue abstraction to publish and consume background jobs with a clean, type‑safe API. It ships with first‑class providers for BullMQ and AWS SQS, and allows custom providers.

  • Decorator-based consumers: use @queue/ decorators to subscribe class methods to a topic.
  • Typed topics: declare topics via module augmentation to get end‑to‑end type safety.
  • Simple publishing: call publish(provider, topic, payload) or shortcuts like publish.bullmq/publish.sqs.
  • Autoload handlers: import handlers with glob patterns and start subscribers via the Server.

Core building blocks

  • queue decorator and shortcuts: queue.bullmq, queue.sqs, queue.pgboss.
  • publish function and shortcuts: publish.bullmq, publish.sqs, publish.pgboss.
  • defineQueueConfiguration single entrypoint to configure built-in and custom providers.
  • QueueService (optional) to register and start consumers manually without decorators.

Quick start from server instance

  1. Define your topics once:
declare module 'balda-js' {
export interface QueueTopic {
test: { name: string };
}
}
  1. Create handlers using decorators:
import { queue } from 'balda-js';

export class MyHandler {
@queue.bullmq('test')
async handle(payload: { name: string }) {
// process job
}
}
  1. Start subscribers and publish jobs:
import { Server, publish, defineQueueConfiguration } from 'balda-js';

defineQueueConfiguration({
bullmq: {
connection: { host: '127.0.0.1', username: 'default', password: 'root', db: 0 },
},
});

const server = new Server({ port: 3000, host: '0.0.0.0' });

// Entrypoint to start the registered queues
await server.startRegisteredQueues(['test/queue/schedules/**/*.ts'], () => {
console.log('Queues started');
});

await publish.bullmq('test', { name: 'test' });

Continue with configuration and publishing details in the next sections.

Quick start without server instance

// queue.ts
import { QueueService } from 'balda-js';
import path from 'node:path';

QueueService.massiveImportQueues([path.join(import.meta.dirname, 'src/queues/**/*.ts')])
.then(() => {
QueueService.run().catch((error) => {
console.error('Error starting queues', error);
});
})
.catch((error) => {
console.error('Error importing queues', error);
});

Registration approaches

You can register consumers in two ways:

  • Decorators (recommended for most cases)
  • Static registration via the service class

Static registration example:

import { QueueService } from 'balda-js';

declare module 'balda-js' {
export interface QueueTopic {
test: { name: string };
}
}

QueueService.register(
'PlainHandler.handle',
'test',
async (payload: { name: string }) => {
console.log('Received', payload.name);
},
{ provider: 'bullmq' }
);

// Ensure this file is imported before starting subscribers, e.g. via the same glob patterns