{"_id":"@chandrafsd/batch-executor","_rev":"3-72112913a535720775d51088716e3f8c","name":"@chandrafsd/batch-executor","dist-tags":{"latest":"1.1.1"},"versions":{"1.0.0":{"name":"@chandrafsd/batch-executor","version":"1.0.0","license":"MIT","_id":"@chandrafsd/batch-executor@1.0.0","maintainers":[{"name":"chandrafsd","email":"santprakash28877@gmail.com"}],"dist":{"shasum":"7ed98bb28a2af19cccb8c2857a0044e2a085d060","tarball":"https://registry.npmjs.org/@chandrafsd/batch-executor/-/batch-executor-1.0.0.tgz","fileCount":4,"integrity":"sha512-oAY/PjdYvasgpSsMXXe6LasLrRkLL1IeWOPu1UlXcPWKDCp9WMvbbTwYnU6cKjnYoXV1TEwQJLEg6dMWN4kQ2w==","signatures":[{"sig":"MEQCIAzEC/n3LFG1n91ypJgIsLFaQcCuaF6pX8aubuapugpLAiBNdqpSJdOF6Irmd07b+S51LaUx/2+wyDTzqbMfVfGlfg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":6087},"main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc -p .","prepare":"npm run build"},"_npmUser":{"name":"chandrafsd","email":"santprakash28877@gmail.com"},"_npmVersion":"10.9.2","description":"A batch executor with concurrency and exponential backoff for async tasks.","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/batch-executor_1.0.0_1764587571942_0.6979247318952664","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@chandrafsd/batch-executor","version":"1.1.0","license":"MIT","_id":"@chandrafsd/batch-executor@1.1.0","maintainers":[{"name":"chandrafsd","email":"santprakash28877@gmail.com"}],"dist":{"shasum":"0f3158348f4788c7b8aec9f02e770cef5c1af521","tarball":"https://registry.npmjs.org/@chandrafsd/batch-executor/-/batch-executor-1.1.0.tgz","fileCount":4,"integrity":"sha512-rVMC8uNlLP+/W7G+AqFgTgB3Qq6EF41WH0Rf9ff2jW9L22PS/J04056gDvYcUcZ5kTYH3MeK0vpvz6Uc2p/EIQ==","signatures":[{"sig":"MEYCIQCeB+Tc9WItjC+Y00icWZ4OKYa/j0icfW/lp+6QhWK7ewIhAKtLFGDX3kmaoVZc2DZTOLsvLey7ZQyx73cYY5IHErxo","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":10085},"main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc -p .","prepare":"npm run build"},"_npmUser":{"name":"chandrafsd","email":"santprakash28877@gmail.com"},"_npmVersion":"10.9.2","description":"A batch executor with concurrency and exponential backoff for async tasks.","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0"},"_npmOperationalInternal":{"tmp":"tmp/batch-executor_1.1.0_1764588127572_0.132543341784219","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@chandrafsd/batch-executor","version":"1.1.1","description":"A batch executor with concurrency and exponential backoff for async tasks.","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc -p .","prepare":"npm run build"},"license":"MIT","devDependencies":{"typescript":"^5.6.0"},"_id":"@chandrafsd/batch-executor@1.1.1","_nodeVersion":"22.14.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-8SbJhdGKbvl7W+LOMtTlOdfqmiqzMLae7Hkfk3LVibdu5eIr3nFVWVJPB/FLDsge9QGIPG0MgXaVBG2/P6UVsg==","shasum":"e01543759a66bffe599f299c4b7378049e0afa03","tarball":"https://registry.npmjs.org/@chandrafsd/batch-executor/-/batch-executor-1.1.1.tgz","fileCount":4,"unpackedSize":10072,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBRoaG2fdEvmXncqlN4wAx/XxZAp9yOFI7J8xD7pwlKkAiEAiyA1H3UXT1DCueHzDcNHQ0Varf6GAYhhXsepwAdeUT0="}]},"_npmUser":{"name":"chandrafsd","email":"santprakash28877@gmail.com"},"directories":{},"maintainers":[{"name":"chandrafsd","email":"santprakash28877@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/batch-executor_1.1.1_1764588213223_0.6325433541765804"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-01T11:12:51.818Z","modified":"2025-12-01T11:23:33.683Z","1.0.0":"2025-12-01T11:12:52.151Z","1.1.0":"2025-12-01T11:22:07.804Z","1.1.1":"2025-12-01T11:23:33.491Z"},"license":"MIT","description":"A batch executor with concurrency and exponential backoff for async tasks.","maintainers":[{"name":"chandrafsd","email":"santprakash28877@gmail.com"}],"readme":"# Batch Executor\n\nA lightweight async batch executor with concurrency control and exponential backoff.\n\n## Installation\n```bash\nnpm install @chandrafsd/batch-executor\n```\n\n## Usage\n\nHere is a real-life example: processing thousands of API calls with retries and exponential backoff.\n\n```ts\nimport { batchExecutor } from \"@chandrafsd/batch-executor\";\n\n// Example: sending notifications to users\nasync function sendNotification(userId: string) {\n  // Fake API call\n  if (Math.random() < 0.3) {\n    throw new Error(`Failed to notify user ${userId}`);\n  }\n  return `Notification sent to ${userId}`;\n}\n\nasync function main() {\n  const users = Array.from({ length: 20 }, (_, i) => `user-${i + 1}`);\n\n  const result = await batchExecutor({\n    items: users,\n    batchSize: 5, // run 5 at a time\n    retryCount: 3, // retry each failed item 3 times\n    backoffMs: 500, // wait 500ms between retries\n    operation: sendNotification,\n  });\n\n  console.log(JSON.stringify(result, null, 2));\n}\n\nmain();\n```\n\n### Example Output\n```json\n[\n  { \"status\": \"fulfilled\", \"value\": \"Notification sent to user-1\" },\n  { \"status\": \"rejected\", \"reason\": \"Failed to notify user-4\" },\n  { \"status\": \"fulfilled\", \"value\": \"Notification sent to user-7\" }\n]\n```\n\nThe results always contain **one entry per item**, showing either success or failure.\n\n\n\n---\n\n# 📘 Why Use `@chandrafsd/batch-executor`?\nReal-world systems often need to process **thousands or millions of async tasks**, such as:\n- Sending notifications or emails\n- Updating records in the database\n- Making API calls with rate-limits\n- Syncing data from external services\n- Processing large datasets in batches\n\nDoing everything in a single `Promise.all()` causes:\n❌ High memory usage  \n❌ API throttling / rate-limit errors  \n❌ Crashes due to unhandled rejections  \n\nThis package solves all of that with:\n### ✅ Batching\n### ✅ Retries\n### ✅ Exponential backoff\n### ✅ Full result tracking using `Promise.allSettled`\n### ✅ Clean and simple API\n\n---\n\n# 🔄 How It Works (Visual Diagram)\n```\nitems[] → split into batches → execute concurrently → retry on failure → return final result per item\n\nExample (batchSize = 3):\n\nItems: [1,2,3,4,5,6,7]\n\nBatch 1 → [1,2,3]\nBatch 2 → [4,5,6]\nBatch 3 → [7]\n\nEach batch runs in parallel, results are collected, failures retry with backoff.\n```\n\n---\n\n# 🧠 Real Life Example 1: Sending Email Notifications\n```ts\nimport { batchExecutor } from \"@chandrafsd/batch-executor\";\n\nasync function sendEmail(email: string) {\n  if (Math.random() < 0.2) throw new Error(`Unable to email: ${email}`);\n  return `Email sent to ${email}`;\n}\n\nasync function run() {\n  const emails = [\n    \"a@test.com\", \"b@test.com\", \"c@test.com\",\n    \"d@test.com\", \"e@test.com\", \"f@test.com\" \n  ];\n\n  const results = await batchExecutor({\n    items: emails,\n    batchSize: 2,\n    retryCount: 3,\n    backoffMs: 300,\n    operation: sendEmail,\n  });\n\n  console.log(results);\n}\n\nrun();\n```\n\n### Output looks like:\n```json\n[\n  { \"status\": \"fulfilled\", \"value\": \"Email sent to a@test.com\" },\n  { \"status\": \"rejected\", \"reason\": \"Unable to email: b@test.com\" },\n  { \"status\": \"fulfilled\", \"value\": \"Email sent to c@test.com\" }\n]\n```\n---\n\n# 🧠 Real Life Example 2: Fetching Data From an API With Rate Limits\n```ts\nasync function fetchUser(userId: number) {\n  const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);\n  if (!response.ok) throw new Error(`Failed to fetch user ${userId}`);\n  return response.json();\n}\n\nconst result = await batchExecutor({\n  items: [1,2,3,4,5,6,7,8,9,10],\n  batchSize: 3,\n  retryCount: 2,\n  backoffMs: 500,\n  operation: fetchUser,\n});\n```\n\n---\n# 🧠 Real Life Example 3: Database Writes in Batches (MongoDB / PostgreSQL)\n```ts\nasync function saveRecord(record) {\n  try {\n    return await db.records.insertOne(record);\n  } catch (err) {\n    throw new Error(`DB write failed for id ${record.id}`);\n  }\n}\n\nawait batchExecutor({\n  items: recordsArray,\n  batchSize: 50,\n  retryCount: 5,\n  backoffMs: 1000,\n  operation: saveRecord,\n});\n```\n\n---\n# 🔧 API Reference\n### `batchExecutor(options)`\n| Option | Type | Required | Description |\n|--------|------|----------|-------------|\n| `items` | `T[]` | ✔️ | List of items to process |\n| `operation` | `(item: T) => Promise<any>` | ✔️ | Async function executed per item |\n| `batchSize` | `number` | ❌ | Default `10` |\n| `retryCount` | `number` | ❌ | Default `3` |\n| `backoffMs` | `number` | ❌ | Default `300` |\n\n### Returns\nAlways returns an array of `Promise.allSettled` results:\n```ts\nArray<{\n  status: \"fulfilled\" | \"rejected\",\n  value?: any,\n  reason?: any,\n}>\n```\n\n---\n\n# 🛠 Installation\n```sh\nnpm install @chandrafsd/batch-executor\n```\n\n# 🚀 Quick Start\n```ts\nimport { batchExecutor } from \"@chandrafsd/batch-executor\";\n\nawait batchExecutor({\n  items: [1,2,3],\n  batchSize: 2,\n  operation: async (x) => x * 2,\n});\n```\n\n---\n\n# ❤️ Contribution\nFeel free to open issues or PRs. This package is designed to help developers avoid complex async loops and retry logic.\n\n---\n\n# 📄 License\nMIT","readmeFilename":"README.md"}