A lightweight, Apache Camel-inspired routing and integration library for Node.js. Build robust message processing pipelines with built-in retry mechanisms, error handling, and route composition.
- 🚀 Simple Route Definition: Fluent API for creating message processing routes
- 🔄 Built-in Retry Logic: Configurable retry strategies with custom delays and fallback processors
- 🔗 Route Composition: Chain routes together for complex processing pipelines
- ⚡ Promise-based: Full Promise support for asynchronous operations
- 📦 ES6 Modules: Modern JavaScript with import/export syntax
- 🧪 Well Tested: Comprehensive test suite with 100% coverage
npm install camel-js
- Node.js >= 16.0.0
- npm >= 8.0.0
import camel from 'camel-js';
// Define a simple route
camel
.init('processOrder')
.to(exchange => {
console.log('Processing order:', exchange);
return { ...exchange, processed: true };
})
.end();
// Send a message through the route
const result = await camel.sendMessage('processOrder', { orderId: 123 });
console.log(result); // { orderId: 123, processed: true }
Creates a new route with the specified name.
Adds a processor function to the current route.
Adds a reference to another route in the current route.
Registers the current route as a listener to another route. When the specified route finishes executing, the current route will automatically be triggered with the output of the source route.
Creates a reusable SQS connection configuration that can be referenced by name in fromSQS
calls.
Parameters:
connectionName
(string): Name to reference this connectionconfig
(object): Connection configurationregion
(string): AWS region (default: 'us-east-1')accessKeyId
(string): AWS access key IDsecretAccessKey
(string): AWS secret access keymaxMessages
(number): Maximum messages to receive per poll (default: 10)waitTimeSeconds
(number): Long polling wait time (default: 20)visibilityTimeoutSeconds
(number): Message visibility timeout (default: 30)pollingInterval
(number): Polling interval in milliseconds (default: 1000)
Registers the current route to be triggered by AWS SQS messages. Can use either a connection name or full queue URL.
Parameters:
queueNameOrUrl
(string): Either a connection name (created withcreateSQSConnection
) or full SQS queue URLoptions
(object): Optional overrides for connection settingsqueueUrl
(string): Required when using connection namemaxMessages
(number): Override max messages per pollwaitTimeSeconds
(number): Override long polling wait timevisibilityTimeoutSeconds
(number): Override message visibility timeoutpollingInterval
(number): Override polling interval
Finalizes the current route definition.
Configures error handling for a specific route.
Sets the number of retry attempts.
Sets the delay between retry attempts.
Sets a fallback processor for when all retries fail.
Sends a message through the specified route. Returns a Promise.
import camel from 'camel-js';
// Define processors
const validateProcessor = exchange => {
if (!exchange.orderId) {
throw new Error('Order ID is required');
}
return exchange;
};
const processOrderProcessor = exchange => {
return { ...exchange, status: 'processed', timestamp: new Date() };
};
// Create route
camel
.init('orderProcessing')
.to(validateProcessor)
.to(processOrderProcessor)
.end();
// Process a message
const result = await camel.sendMessage('orderProcessing', { orderId: 123 });
import camel from 'camel-js';
// Define sub-routes
camel
.init('billingRoute')
.to(exchange => ({ ...exchange, billed: true }))
.end();
camel
.init('deliveryRoute')
.to(exchange => ({ ...exchange, delivered: true }))
.end();
// Compose main route
camel
.init('orderRoute')
.to(exchange => ({ ...exchange, orderDate: new Date() }))
.toRoute('billingRoute')
.toRoute('deliveryRoute')
.end();
import camel from 'camel-js';
// Define a source route
camel
.init('dataProcessor')
.to(exchange => {
return { ...exchange, processed: true, timestamp: new Date() };
})
.end();
// Define a listener route that automatically executes when dataProcessor finishes
camel
.init('notificationProcessor')
.from('dataProcessor') // Listen to dataProcessor completion
.to(exchange => {
console.log('Notification sent for:', exchange);
return { ...exchange, notificationSent: true };
})
.end();
// Execute the source route - this will automatically trigger the notification route
const result = await camel.sendMessage('dataProcessor', { message: 'test' });
// The notificationProcessor will automatically execute with the result
import camel from 'camel-js';
// Create a reusable SQS connection
camel.createSQSConnection('myAWSConnection', {
region: 'us-east-1',
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
maxMessages: 5,
waitTimeSeconds: 10,
visibilityTimeoutSeconds: 30,
pollingInterval: 2000
});
// Define a route that processes SQS messages using connection name
camel
.init('sqsProcessor')
.fromSQS('myAWSConnection', {
queueUrl: 'https://sqs.us-east-1.amazonaws.com/123456789012/my-queue'
})
.to(exchange => {
console.log('Processing SQS message:', exchange);
return { ...exchange, processed: true, processedAt: new Date() };
})
.end();
// Another route using the same connection but different queue
camel
.init('sqsProcessor2')
.fromSQS('myAWSConnection', {
queueUrl: 'https://sqs.us-east-1.amazonaws.com/123456789012/another-queue'
})
.to(exchange => {
console.log('Processing from another queue:', exchange);
return { ...exchange, processed: true };
})
.end();
// SQS polling starts automatically when routes are defined
// Messages from the SQS queues will trigger the route processing
import camel from 'camel-js';
// Define a route that might fail
camel
.init('unreliableService')
.to(exchange => {
if (Math.random() < 0.5) {
throw new Error('Service temporarily unavailable');
}
return { ...exchange, processed: true };
})
.end();
// Configure retry strategy
camel
.onException('unreliableService')
.retryRepetitions(3)
.retryDelay(1000)
.fallbackProcessor(error => {
console.error('All retries failed:', error);
return { error: 'Service unavailable', fallback: true };
})
.end();
// Send message (will retry on failure)
const result = await camel.sendMessage('unreliableService', { data: 'test' });
npm test
npm run test-cov
This will run all tests with coverage reporting using c8, which supports ES6 modules.
Basic Coverage Report:
npm run test-cov
HTML Coverage Report:
npx c8 --reporter=html mocha
Text Coverage Report:
npx c8 --reporter=text mocha
Coverage with LCOV output (for CI/CD):
npx c8 --reporter=lcov mocha
- Statements: 97.17%
- Branches: 97.29%
- Functions: 95%
- Lines: 97.17%
camel-js/
├── src/
│ ├── index.js # Main routing logic
│ └── retry.js # Retry mechanism
├── example/
│ ├── app.js # Example application
│ └── processors/ # Example processors
├── test/
│ ├── routeTest.js # Route functionality tests
│ └── retryTest.js # Retry mechanism tests
└── package.json
ISC
Marcelo Cure
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
- Initial release
- Basic routing functionality
- Retry mechanism with configurable strategies
- Route composition support
- ES6 module support