{"_id":"@avatijs/batch-scheduler","_rev":"2-a6d91703419c8d9e000617c3496c20cd","name":"@avatijs/batch-scheduler","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@avatijs/batch-scheduler","version":"0.1.0","keywords":["avati","scheduler","batch","task-queue","priority-queue","async","typescript"],"author":{"url":"https://khaled.ee/","name":"Khaled Sameer","email":"khaled.smq@hotmail.com"},"license":"MIT","_id":"@avatijs/batch-scheduler@0.1.0","maintainers":[{"name":"khaledsqm","email":"khaled.smq@hotmail.com"}],"homepage":"https://avati.io/","bugs":{"url":"https://github.com/KhaledSMQ/avati/issues","email":"khaled.smq@hotmail.com"},"dist":{"shasum":"62a899445998dbaa639ded9c59105fef19f3122f","tarball":"https://registry.npmjs.org/@avatijs/batch-scheduler/-/batch-scheduler-0.1.0.tgz","fileCount":20,"integrity":"sha512-Fl0E8k0t5goPwTLwF+Z7j+1w7RxncDWR6eC/qnCjIeat1k6v7Lo3JJldyOK4cDiMw76WDnQu6/zI+PZ8c4TLfw==","signatures":[{"sig":"MEYCIQDwtmkTqbrhOrKsmtsjH3n28tfEOdc7LGc31SYpcSZYOAIhAJijzgOxGMbyXqhRM+tmXpuhsYtgX4r7gOSxN8jqlabO","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":299993},"main":"dist/index.cjs.js","types":"dist/types/index.d.ts","unpkg":"dist/index.umd.min.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs.js"}},"gitHead":"06f436ce05d719c22e6cf884747c7c3deaa8f423","scripts":{"build":"npm run clean && npm run build:types && npm run build:dev && npm run build:packages","clean":"rimraf dist","watch":"webpack --mode=development --watch","build:dev":"webpack --mode development --config-name umd --config-name esm --config-name cjs","build:types":"tsc --emitDeclarationOnly --outDir dist/types","watch:slient":"webpack --mode=development --watch --silent","build:packages":"webpack --mode production --config-name umd --config-name esm --config-name cjs"},"_npmUser":{"name":"khaledsqm","email":"khaled.smq@hotmail.com"},"jsdelivr":"dist/index.umd.min.js","repository":{"url":"git+https://github.com/KhaledSMQ/avati.git","type":"git","directory":"packages/batch-scheduler"},"_npmVersion":"10.9.0","description":"Batch scheduler package part of Avati project","directories":{},"_nodeVersion":"20.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/batch-scheduler_0.1.0_1732050783403_0.2011556704401778","host":"s3://npm-registry-packages"}},"0.1.1":{"name":"@avatijs/batch-scheduler","version":"0.1.1","keywords":["avati","scheduler","batch","task-queue","priority-queue","async","typescript"],"author":{"url":"https://khaled.ee/","name":"Khaled Sameer","email":"khaled.smq@hotmail.com"},"license":"MIT","_id":"@avatijs/batch-scheduler@0.1.1","maintainers":[{"name":"khaledsqm","email":"khaled.smq@hotmail.com"}],"homepage":"https://avati.io/","bugs":{"url":"https://github.com/KhaledSMQ/avati/issues","email":"khaled.smq@hotmail.com"},"dist":{"shasum":"76170d5d028baa7d25bc2a8f5be383a94cbced77","tarball":"https://registry.npmjs.org/@avatijs/batch-scheduler/-/batch-scheduler-0.1.1.tgz","fileCount":19,"integrity":"sha512-H/g1/DY9N2HGY6di2DU/s1MmgvQXSdmm4uQe/raDNGrWSgiOUhdWDCxhJO+m0E4M6Jkmsp/jFiTTzxmrHeuj/g==","signatures":[{"sig":"MEYCIQC7OPD2lFM7NyhYluROCC8PRaC26VX+Z0hLkrBcizUgKgIhAIRm+no56LYlflQuDzRu0zrgOXcZGUI/vyBPm3VJTAnU","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":216961},"main":"./dist/index.cjs.js","types":"./dist/index.d.ts","unpkg":"./dist/index.umd.min.js","module":"./dist/index.esm.js","browser":"./dist/index.umd.js","engines":{"node":">=14.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.esm.js","require":"./dist/index.cjs.js"}},"gitHead":"046f58e86c44b85957dab58b31053f1f9e453721","scripts":{"lint":"eslint . --ext .ts","test":"jest","build":"npm run clean && npm run build:types && npm run build:dev && npm run build:packages","clean":"rimraf dist","watch":"webpack --mode=development --watch","build:dev":"webpack --mode development --config-name umd --config-name esm --config-name cjs","typecheck":"tsc --noEmit","build:types":"tsc --emitDeclarationOnly --outDir dist/types","watch:slient":"webpack --mode=development --watch --silent","build:packages":"webpack --mode production --config-name umd --config-name esm --config-name cjs","prepublishOnly":"npm run build"},"_npmUser":{"name":"khaledsqm","email":"khaled.smq@hotmail.com"},"jsdelivr":"./dist/index.umd.min.js","repository":{"url":"git+https://github.com/KhaledSMQ/avati.git","type":"git","directory":"packages/batch-scheduler"},"_npmVersion":"10.9.0","description":"Batch scheduler package part of Avati project","directories":{},"sideEffects":false,"_nodeVersion":"20.14.0","publishConfig":{"access":"public"},"typesVersions":{"*":{"*":["dist/index.d.ts"]}},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/batch-scheduler_0.1.1_1732055400448_0.6460708631889951","host":"s3://npm-registry-packages"}},"0.1.2":{"name":"@avatijs/batch-scheduler","version":"0.1.2","description":"Batch scheduler package part of Avati project","main":"./dist/index.cjs.js","module":"./dist/index.esm.js","types":"./dist/index.d.ts","browser":"./dist/index.umd.js","unpkg":"./dist/index.umd.min.js","jsdelivr":"./dist/index.umd.min.js","exports":{".":{"require":"./dist/index.cjs.js","import":"./dist/index.esm.js","types":"./dist/index.d.ts"}},"sideEffects":false,"engines":{"node":">=18.20.5"},"typesVersions":{"*":{"*":["dist/index.d.ts"]}},"scripts":{"build":"npm run clean && npm run build:types && npm run build:prod","build:dev":"webpack --mode development --progress","build:prod":"webpack --mode production","build:types":"tsc --emitDeclarationOnly","watch":"webpack --mode=development --watch","watch:silent":"webpack --mode=development --watch --silent","clean":"rimraf dist","prepublishOnly":"npm run build","test":"jest --config jest.config.js","typecheck":"tsc --noEmit","size":"webpack --mode production --json > stats.json && webpack-bundle-analyzer stats.json","analyze:deps":"madge --circular --extensions ts ./src/index.ts","size:check":"bundlesize","size:watch":"bundlesize --watch","size:compression":"bundlesize --compression","check-deps":"depcheck --config .depcheckrc","analyze":"npm run analyze:size && npm run analyze:deps && npm run analyze:duplicates","analyze:size":"webpack --mode production --json > stats.json && webpack-bundle-analyzer stats.json","analyze:detailed":"webpack --config webpack.analysis.config.js","analyze:duplicates":"jscpd src","analyze:why":"webpack --mode production --display-reasons","analyze:tree":"webpack --mode production --display-used-exports","analyze:modules":"webpack --mode production --display-modules","analyze:full":"webpack --mode production --stats detailed"},"author":{"name":"Khaled Sameer","email":"khaled.smq@hotmail.com","url":"https://khaled.ee/"},"homepage":"https://avati.io/","bugs":{"url":"https://github.com/KhaledSMQ/avati/issues","email":"khaled.smq@hotmail.com"},"repository":{"type":"git","url":"git+https://github.com/KhaledSMQ/avati.git","directory":"packages/batch-scheduler"},"license":"MIT","publishConfig":{"access":"public"},"keywords":["avati","scheduler","batch","task-queue","priority-queue","async","typescript"],"devDependencies":{"@types/jest":"^29.5.14","@types/node":"^22.9.1","@typescript-eslint/eslint-plugin":"^8.15.0","@typescript-eslint/parser":"^8.15.0","bundlesize":"^0.18.2","depcheck":"^1.4.7","dependency-cruiser":"^16.6.0","eslint":"^8.57.1","jest":"^29.7.0","jscpd":"^4.0.5","madge":"^8.0.0","rimraf":"^6.0.1","source-map-explorer":"^2.5.3","terser-webpack-plugin":"^5.3.10","ts-jest":"^29.2.5","ts-loader":"^9.5.1","typescript":"^5.6.3","webpack":"^5.96.1","webpack-bundle-analyzer":"^4.10.2","webpack-cli":"^5.1.4"},"_id":"@avatijs/batch-scheduler@0.1.2","gitHead":"45902cf3fc3c657b7e7d4055600c78870d4dbabb","_nodeVersion":"20.14.0","_npmVersion":"10.9.0","dist":{"integrity":"sha512-ScNjTbalzvOq6nu1nShjKjWalnV0gloUAMz0eQXXaH+fP//Bql/NV/SA77y/JO5FTvp22k02R1rNMXEJi5wgbw==","shasum":"6c5808ea4582553a095f4a29d0470b5735140bc0","tarball":"https://registry.npmjs.org/@avatijs/batch-scheduler/-/batch-scheduler-0.1.2.tgz","fileCount":16,"unpackedSize":86990,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGvrdG1Vi8SnEhbviGZpdhoGJBrHPVzV7gWtoqAMNM1AAiBsNvlspDD0pFXJzgMJoTUbcFd03588cALAIdPBn5oBQQ=="}]},"_npmUser":{"name":"khaledsqm","email":"khaled.smq@hotmail.com"},"directories":{},"maintainers":[{"name":"khaledsqm","email":"khaled.smq@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/batch-scheduler_0.1.2_1732354236434_0.9391034732906205"},"_hasShrinkwrap":false}},"time":{"created":"2024-11-19T21:13:03.051Z","modified":"2024-11-23T09:30:36.796Z","0.1.0":"2024-11-19T21:13:03.687Z","0.1.1":"2024-11-19T22:30:00.652Z","0.1.2":"2024-11-23T09:30:36.611Z"},"bugs":{"url":"https://github.com/KhaledSMQ/avati/issues","email":"khaled.smq@hotmail.com"},"author":{"name":"Khaled Sameer","email":"khaled.smq@hotmail.com","url":"https://khaled.ee/"},"license":"MIT","homepage":"https://avati.io/","keywords":["avati","scheduler","batch","task-queue","priority-queue","async","typescript"],"repository":{"type":"git","url":"git+https://github.com/KhaledSMQ/avati.git","directory":"packages/batch-scheduler"},"description":"Batch scheduler package part of Avati project","maintainers":[{"name":"khaledsqm","email":"khaled.smq@hotmail.com"}],"readme":"# BatchScheduler\n\n## About BatchScheduler\n\nBatchScheduler is an elegant and powerful task scheduling library for JavaScript/TypeScript applications. It provides a simple yet flexible API for managing and executing tasks in batches with support for:\n\n- Task prioritization\n- Batching contexts\n- Task cancellation\n- Error handling\n- Async/await support\n- Zero dependencies\n\n## Installation\n\nYou can install the package via npm:\n\n```bash\nnpm install @avatijs/batch-scheduler\n```\n\nOr using yarn:\n\n```bash\nyarn add @avatijs/batch-scheduler\n```\n\n## Basic Usage\n\n```typescript\nimport { BatchScheduler } from '@avatijs/batch-scheduler';\n\n// Get the scheduler instance\nconst scheduler = BatchScheduler.getInstance();\n\n// Schedule a simple task\nscheduler.schedule(() => {\n    console.log('Task executed');\n});\n\n// Schedule a high-priority task\nscheduler.schedule(() => {\n    console.log('High-priority task');\n}, { priority: 10 });\n\n// Schedule an async task\nscheduler.schedule(async () => {\n    await someAsyncOperation();\n    console.log('Async task completed');\n});\n```\n\n## Batching Operations\n\nUse batching to group multiple tasks together:\n\n```typescript\nimport { batchUpdates } from '@avatijs/batch-scheduler';\n\nbatchUpdates(() => {\n    // All tasks scheduled here will be executed together\n    scheduler.schedule(() => console.log('Task 1'));\n    scheduler.schedule(() => console.log('Task 2'));\n    scheduler.schedule(() => console.log('Task 3'));\n});\n```\n\n## Task Cancellation\n\nTasks can be cancelled before execution using cancellation tokens:\n\n```typescript\nconst token = scheduler.createCancellationToken();\n\nscheduler.schedule(() => {\n    console.log('This task may be cancelled');\n}, { cancellationToken: token });\n\n// Cancel the task before it executes\ntoken.cancel();\n```\n\n## Error Handling\n\nHandle task errors gracefully:\n\n```typescript\nscheduler.schedule(() => {\n    throw new Error('Task failed');\n}, {\n    onError: (error) => {\n        console.error('Handled task error:', error);\n    },\n});\n```\n\n## Advanced Features\n\n### Priority System\n\nTasks with higher priority values are executed first:\n\n```typescript\nscheduler.schedule(task1, { priority: 1 });  // Executed third\nscheduler.schedule(task2, { priority: 5 });  // Executed second\nscheduler.schedule(task3, { priority: 10 }); // Executed first\n```\n\n### Manual Batch Control\n\nFor fine-grained control over batching:\n\n```typescript\nscheduler.startBatch();\n\n// Schedule multiple tasks\nscheduler.schedule(task1);\nscheduler.schedule(task2);\n\n// Other operations...\n\nscheduler.endBatch(); // Tasks are executed\n```\n\n### Immediate Processing\n\nForce immediate processing of all pending tasks:\n\n```typescript\nscheduler.flush();\n```\n\n### Cleanup\n\nProperly shutdown the scheduler when needed:\n\n```typescript\nscheduler.shutdown();\n```\n \n\n## Do's and Don'ts\n\n### Do's ✅\n\n#### Do: Use Batching for Related Operations\n\n```typescript\n// Good: Group related UI updates\nbatchUpdates(() => {\n    scheduler.schedule(() => updateHeader());\n    scheduler.schedule(() => updateSidebar());\n    scheduler.schedule(() => updateFooter());\n});\n```\n\n#### Do: Handle Errors Appropriately\n\n```typescript\n// Good: Proper error handling\nscheduler.schedule(\n    async () => {\n        await fetchUserData();\n    },\n    {\n        onError: (error) => {\n            logger.error('Failed to fetch user data:', error);\n            showErrorNotification();\n        }\n    }\n);\n```\n\n#### Do: Use Priorities for Important Tasks\n\n```typescript\n// Good: Critical updates get higher priority\nscheduler.schedule(\n    () => updateCriticalMetrics(),\n    { priority: 10 }\n);\n\nscheduler.schedule(\n    () => updateNonCriticalUI(),\n    { priority: 1 }\n);\n```\n\n#### Do: Clean Up Resources\n\n```typescript\n// Good: Proper cleanup on component unmount\nclass Component {\n    private token = scheduler.createCancellationToken();\n\n    scheduleTask() {\n        scheduler.schedule(\n            () => this.updateData(),\n            { cancellationToken: this.token }\n        );\n    }\n\n    cleanup() {\n        this.token.cancel();\n    }\n}\n```\n\n### Don'ts ❌\n\n#### Don't: Create Multiple Scheduler Instances\n\n```typescript\n// Bad: Creating multiple instances\nconst scheduler1 = new BatchScheduler(); // ❌\nconst scheduler2 = new BatchScheduler(); // ❌\n\n// Good: Use singleton instance\nconst scheduler = BatchScheduler.getInstance(); // ✅\n```\n\n#### Don't: Nest Batch Operations\n\n```typescript\n// Bad: Nesting batch operations\nbatchUpdates(() => {\n    scheduler.schedule(() => task1());\n    \n    batchUpdates(() => {  // ❌ Nested batch\n        scheduler.schedule(() => task2());\n    });\n});\n\n// Good: Flatten batch operations\nbatchUpdates(() => {\n    scheduler.schedule(() => task1());\n    scheduler.schedule(() => task2());\n});\n```\n\n#### Don't: Use Long-Running Tasks Without Consideration\n\n```typescript\n// Bad: Long-running synchronous task\nscheduler.schedule(() => {\n    while(heavyComputation()) { } // ❌ Blocks the thread\n});\n\n// Good: Break up or make async\nscheduler.schedule(async () => {\n    const chunks = splitIntoChunks(data);\n    for (const chunk of chunks) {\n        await processChunk(chunk);\n    }\n});\n```\n\n#### Don't: Ignore Task Cancellation\n\n```typescript\n// Bad: Not handling cancellation\nscheduler.schedule(async () => {\n    const data = await fetchData();  // ❌ Continues even if cancelled\n    processData(data);\n});\n\n// Good: Check cancellation status\nconst token = scheduler.createCancellationToken();\nscheduler.schedule(async () => {\n    if (token.isCancelled) return;\n    const data = await fetchData();\n    if (token.isCancelled) return;\n    processData(data);\n}, { cancellationToken: token });\n```\n\n#### Don't: Use Flush in Batch Context\n\n```typescript\n// Bad: Flushing within batch\nbatchUpdates(() => {\n    scheduler.schedule(() => task1());\n    scheduler.flush();  // ❌ Throws error\n});\n\n// Good: Flush outside batch\nbatchUpdates(() => {\n    scheduler.schedule(() => task1());\n});\nscheduler.flush();  // ✅\n```\n\n### Best Practices 🎯\n\n1. **Task Size**: Keep tasks small and focused\n2. **Error Handling**: Always provide error handlers for critical tasks\n3. **Priorities**: Use priorities sparingly and meaningfully\n4. **Cancellation**: Implement cancellation for long-running or resource-intensive tasks\n5. **Batching**: Group related tasks that should be executed together\n6. **Async Operations**: Prefer async operations for I/O or long-running tasks\n7. **Cleanup**: Always clean up by cancelling pending tasks when appropriate\n---\n## API Reference\n\n### BatchScheduler Class\n\n#### Static Methods\n\n- `getInstance(): BatchScheduler`\n    - Returns the singleton instance of BatchScheduler\n\n#### Instance Methods\n\n- `schedule(task: TaskFunction, options?: TaskOptions): void`\n    - Schedules a task for execution\n    - Options include `priority`, `onError`, and `cancellationToken`\n\n- `startBatch(): void`\n    - Begins a new batching context\n\n- `endBatch(): void`\n    - Ends the current batching context\n\n- `flush(): void`\n    - Immediately processes all pending tasks\n\n- `shutdown(): void`\n    - Cancels all pending tasks and prevents new scheduling\n\n- `createCancellationToken(): CancellationToken`\n    - Creates a new cancellation token\n\n### Helper Functions\n\n- `batchUpdates<T>(fn: () => T): T`\n    - Executes a function within a batching context\n---\n\n\n## Changelog\n\nPlease see [CHANGELOG](./CHANGELOG.md) for more information what has changed recently.\n\n## Contributing\n\nI welcome contributions from developers of all experience levels. If you have an idea, found a bug, or want to improve something, I encourage you to get involved!\n\n### How to Contribute\n1. Read [Contributing Guide](https://github.com/KhaledSMQ/avati/blob/master/Contributing.md) for details on how to get started.\n2. Fork the repository and make your changes.\n3. Submit a pull request, and we’ll review it as soon as possible.\n\n## License\n\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/KhaledSMQ/avati/blob/master/LICENSE)\n\nAvati is open-source and distributed under the [MIT License](https://github.com/KhaledSMQ/avati/blob/master/LICENSE).\n\n---\n<div align=\"center\">\n\n[![Follow on Twitter](https://img.shields.io/twitter/follow/KhaledSMQ.svg?style=social)](https://x.com/khaledsmq_)\n[![Follow on LinkedIn](https://img.shields.io/badge/LinkedIn-Connect-blue.svg)](https://www.linkedin.com/in/khaledsmq/)\n[![Follow on Medium](https://img.shields.io/badge/Medium-Follow-black.svg)](https://medium.com/@khaled.smq)\n[![Made with ❤️](https://img.shields.io/badge/Made%20with-❤️-red.svg)](https://github.com/KhaledSMQ)\n[![Star on GitHub](https://img.shields.io/github/stars/KhaledSMQ/avati.svg?style=social)](https://github.com/KhaledSMQ/avati/stargazers)\n[![Follow on GitHub](https://img.shields.io/github/followers/KhaledSMQ.svg?style=social&label=Follow)](https://github.com/KhaledSMQ)\n\n</div>\n","readmeFilename":"README.md"}