A comprehensive TypeScript/JavaScript SDK for self-hosted infrastructure services. Built for production with BullMQ, Redis, and MinIO.
- π¦ Queue Management - Background jobs with BullMQ
- β‘ Cache - High-performance caching with Redis
- π Object Storage - S3-compatible storage with MinIO
- π Event Bus - Pub/Sub messaging with Redis
- π‘οΈ Rate Limiting - Sliding window rate limiting
- π Distributed Locking - Redis-based distributed locks
- π€ Session Management - Secure session storage
npm install @omed0/infra-kit
npm install --save bullmq ioredis minio
# or
pnpm add @omed0/infra-kit
pnpm add -D bullmq ioredis minio
# or
bun add @omed0/infra-kit
bun add -D bullmq ioredis minioimport { initConfig } from "@omed0/infra-kit";
// Programmatic configuration
initConfig({
redis: {
host: "localhost",
port: 6379,
password: "your-password",
},
storage: {
endPoint: "localhost",
port: 9000,
accessKey: "minioadmin",
secretKey: "minioadmin",
},
});
// Or from environment variables
import { initFromEnv } from "@omed0/infra-kit";
initFromEnv();Queue Management
import { addJob, processJobs } from "@omed0/infra-kit/queue";
// Add a job
await addJob(
"emails",
"send-welcome",
{
to: "user@example.com",
subject: "Welcome!",
},
{
delay: 5000,
attempts: 3,
}
);
// Process jobs
processJobs(
"emails",
async (job) => {
console.log("Sending email:", job.data);
// Send email logic
return { sent: true };
},
{ concurrency: 5 }
);Cache
import { setCache, getCache } from "@omed0/infra-kit/cache";
// Set with TTL
await setCache("user:123", { name: "John", email: "john@example.com" }, 3600);
// Get
const user = await getCache("user:123");
console.log(user?.name);Object Storage
import { uploadFile, getDownloadUrl } from "@omed0/infra-kit/storage";
// Upload file
await uploadFile("uploads", "images/photo.jpg", "/tmp/photo.jpg");
// Get presigned download URL
const url = await getDownloadUrl("uploads", "images/photo.jpg", 3600);Event Bus
import { publish, subscribe } from "@omed0/infra-kit/events";
// Subscribe
await subscribe("user.created", (data) => {
console.log("New user:", data);
});
// Publish
await publish("user.created", {
userId: "123",
email: "user@example.com",
});Rate Limiting
import { checkRateLimit } from "@omed0/infra-kit/rate-limit";
const result = await checkRateLimit("user:123", {
limit: 100,
window: 60,
key: "api-requests",
});
if (!result.allowed) {
throw new Error(`Rate limit exceeded. Retry in ${result.retryAfter}ms`);
}Distributed Locking
import { withLock } from "@omed0/infra-kit/lock";
await withLock(
"critical-section",
async () => {
// Critical work here
console.log("Locked section");
},
{ ttl: 30000 }
);Session Management
import { setSession, getSession } from "@omed0/infra-kit/session";
// Create session
await setSession(
"sess_123",
{
userId: "456",
email: "user@example.com",
},
{ ttl: 3600 }
);
// Get session
const session = await getSession("sess_123");# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=your-password
REDIS_DB=0
# Storage (MinIO/S3)
S3_ENDPOINT=localhost
S3_PORT=9000
S3_ACCESS_KEY=minioadmin
S3_SECRET_KEY=minioadmin
S3_USE_SSL=falseaddJob(queueName, jobName, data, options)- Add a jobaddBulkJobs(queueName, jobs)- Add multiple jobsscheduleJob(queueName, jobName, data, repeatOptions)- Schedule recurring jobprocessJobs(queueName, processor, options)- Process jobsgetQueueMetrics(queueName)- Get queue statscleanQueue(queueName, grace, limit, type)- Clean old jobspauseQueue(queueName)/resumeQueue(queueName)- Control queue
setCache(key, value, ttl)- Set cache entrygetCache(key)- Get cache entrydeleteCache(key)- Delete entryhasCache(key)- Check if existsincrement(key, amount)/decrement(key, amount)- Atomic operationsgetMany(keys)/setMany(entries)- Bulk operationsclearCache()- Clear all cache
uploadFile(bucket, objectName, filePath, metadata)- Upload filedownloadFile(bucket, objectName, filePath)- Download filedeleteObject(bucket, objectName)- Delete objectlistObjects(bucket, prefix, recursive)- List objectsgetUploadUrl(bucket, objectName, expiry)- Presigned upload URLgetDownloadUrl(bucket, objectName, expiry)- Presigned download URL
publish(channel, data)- Publish eventsubscribe(channel, handler)- Subscribe to eventssubscribeMany(channels, handler)- Subscribe to multiple channelsunsubscribe(channel)- Unsubscribe from channel
checkRateLimit(identifier, options)- Check and consume rate limitpeekRateLimit(identifier, options)- Check without consumingresetRateLimit(identifier, key)- Reset limitscreateRateLimiter(options)- Create reusable limiter
acquireLock(key, options)- Acquire lockreleaseLock(key, token)- Release lockextendLock(key, token, ttl)- Extend lock TTLwithLock(key, fn, options)- Execute with lock
setSession(sessionId, data, options)- Create/update sessiongetSession(sessionId)- Get session dataupdateSession(sessionId, data, options)- Merge updatedeleteSession(sessionId)- Delete sessionrefreshSession(sessionId, ttl)- Refresh TTL
Use this docker-compose.yml for local development:
services:
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
minio:
image: bitnami/minio:latest
ports:
- "9000:9000"
- "9001:9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
volumes:
- minio_data:/data
volumes:
redis_data:
minio_data:Import specific modules for better tree-shaking:
import { addJob } from "@omed0/infra-kit/queue";
import { setCache } from "@omed0/infra-kit/cache";
import { uploadFile } from "@omed0/infra-kit/storage";
import { publish } from "@omed0/infra-kit/events";
import { checkRateLimit } from "@omed0/infra-kit/rate-limit";
import { acquireLock } from "@omed0/infra-kit/lock";
import { setSession } from "@omed0/infra-kit/session";Full TypeScript support with type definitions included.
import type { Config, RateLimitResult } from "@omed0/infra-kit";MIT Β© Omed0
Contributions welcome! Please read our Contributing Guide and open an issue or PR.
- π Documentation
- π Issues
- π¬ Discussions
- π¦ npm Package