Scrawn.js
Advanced Usage
Advanced patterns, optimization techniques, and best practices
Overview
This guide covers advanced usage patterns, optimization techniques, and best practices for production deployments with Scrawn.js.
Batch Processing
When tracking multiple events, use Promise.all for better performance:
import { Scrawn } from '@scrawn/core';
const scrawn = new Scrawn({
apiKey: process.env.SCRAWN_KEY as `scrn_${string}`,
baseURL: process.env.SCRAWN_BASE_URL || 'http://localhost:8069',
});
// Track multiple events in parallel
const events = [
{ userId: 'user-1', debitAmount: 100 },
{ userId: 'user-2', debitAmount: 200 },
{ userId: 'user-3', debitAmount: 150 },
];
await Promise.all(
events.map(event => scrawn.sdkCallEventConsumer(event))
);Async Event Tracking Pattern
In persistent servers, await after the response so that the response isn't dependent on the billing call.
app.post('/api/generate', async (req, res) => {
await scrawn.sdkCallEventConsumer({
userId: req.user.id,
debitAmount: 100,
});
// Start tracking (don't await yet)
const trackingPromise = scrawn.sdkCallEventConsumer({
userId: req.user.id,
debitAmount: 100,
});
// Do your work
const result = await generateContent(req.body.prompt);
res.json({ result });
// Wait for tracking to complete
await trackingPromise;
});Queue-Based Processing
For high-throughput scenarios, use a queue to decouple tracking from request handling:
import Queue from 'bull';
const usageQueue = new Queue('usage-tracking', {
redis: process.env.REDIS_URL,
});
// Producer: Add to queue
app.post('/api/action', async (req, res) => {
// Queue the event
await usageQueue.add({
userId: req.user.id,
debitAmount: 10,
});
// Process request immediately
const result = await doWork(req.body);
res.json({ result, queued: true });
});
// Consumer: Process queue in background
usageQueue.process(async (job) => {
const { userId, debitAmount } = job.data;
await scrawn.sdkCallEventConsumer({ userId, debitAmount });
});Graceful Error Handling
Allow your app to continue functioning even if tracking fails:
async function trackUsageGracefully(userId: string, debitAmount: number) {
try {
await scrawn.sdkCallEventConsumer({ userId, debitAmount });
} catch (error) {
// Log error but don't block request
console.error('Failed to track usage:', error);
// Optional: Queue for later retry
await queueForRetry({ userId, debitAmount, error });
}
}Reuse SDK Instance
Always create the SDK instance once and reuse it:
import { Scrawn } from '@scrawn/core';
export const scrawn = new Scrawn({
apiKey: process.env.SCRAWN_KEY as `scrn_${string}`,
baseURL: process.env.SCRAWN_BASE_URL || 'http://localhost:8069',
});import { scrawn } from '@/lib/scrawn';
// Use the shared instance
await scrawn.sdkCallEventConsumer({ userId: 'user-123', debitAmount: 10 });