@push.rocks/taskbuffer 3.1.8 → 3.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/readme.md CHANGED
@@ -29,21 +29,27 @@ In the modern JavaScript ecosystem, managing asynchronous tasks efficiently is c
29
29
  ## Core Concepts 🎓
30
30
 
31
31
  ### Task
32
+
32
33
  The fundamental unit of work. A task wraps an asynchronous function and provides powerful execution control.
33
34
 
34
35
  ### Taskchain
36
+
35
37
  Sequential task execution - tasks run one after another, with results passed along the chain.
36
38
 
37
39
  ### Taskparallel
40
+
38
41
  Parallel task execution - multiple tasks run simultaneously for maximum performance.
39
42
 
40
43
  ### TaskManager
44
+
41
45
  Centralized task scheduling and management using cron expressions.
42
46
 
43
47
  ### TaskDebounced
48
+
44
49
  Debounced task execution - prevents rapid repeated executions, only running after a quiet period.
45
50
 
46
51
  ### TaskOnce
52
+
47
53
  Singleton task execution - ensures a task runs exactly once, perfect for initialization routines.
48
54
 
49
55
  ## Quick Start 🏁
@@ -59,13 +65,329 @@ const myTask = new Task({
59
65
  taskFunction: async () => {
60
66
  const data = await fetchData();
61
67
  return processData(data);
62
- }
68
+ },
63
69
  });
64
70
 
65
71
  // Execute the task
66
72
  const result = await myTask.trigger();
67
73
  ```
68
74
 
75
+ ## TypeScript Generics Support 🔬
76
+
77
+ TaskBuffer leverages TypeScript's powerful generics system for complete type safety across your task chains and workflows.
78
+
79
+ ### Generic Task Functions
80
+
81
+ Tasks support generic type parameters for both input and output types:
82
+
83
+ ```typescript
84
+ import { Task, ITaskFunction } from '@push.rocks/taskbuffer';
85
+
86
+ // Define typed interfaces
87
+ interface UserData {
88
+ id: string;
89
+ name: string;
90
+ email: string;
91
+ }
92
+
93
+ interface ProcessedUser {
94
+ userId: string;
95
+ displayName: string;
96
+ normalized: boolean;
97
+ }
98
+
99
+ // Create strongly typed tasks
100
+ const processUserTask = new Task<UserData, ProcessedUser>({
101
+ name: 'ProcessUser',
102
+ taskFunction: async (user: UserData): Promise<ProcessedUser> => {
103
+ return {
104
+ userId: user.id,
105
+ displayName: user.name.toUpperCase(),
106
+ normalized: true
107
+ };
108
+ }
109
+ });
110
+
111
+ // Type safety enforced at compile time
112
+ const result: ProcessedUser = await processUserTask.trigger({
113
+ id: '123',
114
+ name: 'John Doe',
115
+ email: 'john@example.com'
116
+ });
117
+ ```
118
+
119
+ ### Generic Setup Values
120
+
121
+ Tasks can accept setup values through generics, perfect for configuration:
122
+
123
+ ```typescript
124
+ interface TaskConfig {
125
+ apiEndpoint: string;
126
+ retryCount: number;
127
+ timeout: number;
128
+ }
129
+
130
+ const configuredTask = new Task<TaskConfig>({
131
+ name: 'ConfiguredTask',
132
+ taskSetup: async () => ({
133
+ apiEndpoint: 'https://api.example.com',
134
+ retryCount: 3,
135
+ timeout: 5000
136
+ }),
137
+ taskFunction: async (data: any, setupValue: TaskConfig) => {
138
+ // setupValue is fully typed!
139
+ for (let i = 0; i < setupValue.retryCount; i++) {
140
+ try {
141
+ return await fetchWithTimeout(
142
+ setupValue.apiEndpoint,
143
+ setupValue.timeout
144
+ );
145
+ } catch (error) {
146
+ if (i === setupValue.retryCount - 1) throw error;
147
+ }
148
+ }
149
+ }
150
+ });
151
+ ```
152
+
153
+ ### Type-Safe Task Chains
154
+
155
+ Chain tasks with preserved type flow:
156
+
157
+ ```typescript
158
+ // Each task knows its input and output types
159
+ const fetchTask = new Task<void, UserData[]>({
160
+ name: 'FetchUsers',
161
+ taskFunction: async (): Promise<UserData[]> => {
162
+ return await api.getUsers();
163
+ }
164
+ });
165
+
166
+ const filterTask = new Task<UserData[], UserData[]>({
167
+ name: 'FilterActive',
168
+ taskFunction: async (users: UserData[]): Promise<UserData[]> => {
169
+ return users.filter(user => user.isActive);
170
+ }
171
+ });
172
+
173
+ const mapTask = new Task<UserData[], ProcessedUser[]>({
174
+ name: 'MapToProcessed',
175
+ taskFunction: async (users: UserData[]): Promise<ProcessedUser[]> => {
176
+ return users.map(transformUser);
177
+ }
178
+ });
179
+
180
+ // Type safety flows through the chain
181
+ const chain = new Taskchain({
182
+ name: 'UserPipeline',
183
+ taskArray: [fetchTask, filterTask, mapTask]
184
+ });
185
+
186
+ const finalResult: ProcessedUser[] = await chain.trigger();
187
+ ```
188
+
189
+ ## Buffer Behavior Deep Dive 🌊
190
+
191
+ The buffer system in TaskBuffer provides intelligent control over concurrent executions, preventing system overload while maximizing throughput.
192
+
193
+ ### How Buffering Works
194
+
195
+ When a task is buffered, TaskBuffer manages a queue of executions:
196
+
197
+ ```typescript
198
+ const bufferedTask = new Task({
199
+ name: 'BufferedOperation',
200
+ taskFunction: async (data) => {
201
+ console.log(`Processing: ${data}`);
202
+ await simulateWork();
203
+ return `Processed: ${data}`;
204
+ },
205
+ buffered: true,
206
+ bufferMax: 3 // Maximum 3 concurrent executions
207
+ });
208
+
209
+ // Trigger 10 executions rapidly
210
+ for (let i = 0; i < 10; i++) {
211
+ bufferedTask.trigger(`Item ${i}`);
212
+ }
213
+
214
+ // What happens:
215
+ // 1. First 3 tasks start immediately
216
+ // 2. Items 4-10 are queued
217
+ // 3. As each task completes, next queued item starts
218
+ // 4. Never more than 3 tasks running simultaneously
219
+ ```
220
+
221
+ ### Buffer Truncation Behavior
222
+
223
+ When buffer limit is reached, new calls are intelligently managed:
224
+
225
+ ```typescript
226
+ const truncatingTask = new Task({
227
+ name: 'TruncatingBuffer',
228
+ taskFunction: async (data) => {
229
+ await processData(data);
230
+ },
231
+ buffered: true,
232
+ bufferMax: 5 // Maximum 5 in buffer
233
+ });
234
+
235
+ // Rapid fire 100 calls
236
+ for (let i = 0; i < 100; i++) {
237
+ truncatingTask.trigger(`Data ${i}`);
238
+ }
239
+
240
+ // Buffer behavior:
241
+ // - First 5 calls: Added to buffer and start processing
242
+ // - Calls 6-100: Each overwrites the 5th buffer slot
243
+ // - Result: Only processes items 0,1,2,3, and 99 (last one)
244
+ // - This prevents memory overflow in high-frequency scenarios
245
+ ```
246
+
247
+ ### Advanced Buffer Strategies
248
+
249
+ #### 1. **Sliding Window Buffer**
250
+ Perfect for real-time data processing where only recent items matter:
251
+
252
+ ```typescript
253
+ const slidingWindowTask = new Task({
254
+ name: 'SlidingWindow',
255
+ taskFunction: async (data) => {
256
+ return await analyzeRecentData(data);
257
+ },
258
+ buffered: true,
259
+ bufferMax: 10, // Keep last 10 items
260
+ execDelay: 100 // Process every 100ms
261
+ });
262
+
263
+ // In a real-time stream scenario
264
+ dataStream.on('data', (chunk) => {
265
+ slidingWindowTask.trigger(chunk);
266
+ // Older items automatically dropped when buffer full
267
+ });
268
+ ```
269
+
270
+ #### 2. **Throttled Buffer**
271
+ Combine buffering with execution delays for rate limiting:
272
+
273
+ ```typescript
274
+ const apiRateLimiter = new Task({
275
+ name: 'RateLimitedAPI',
276
+ taskFunction: async (request) => {
277
+ return await api.call(request);
278
+ },
279
+ buffered: true,
280
+ bufferMax: 10, // Max 10 queued requests
281
+ execDelay: 1000 // 1 second between executions
282
+ });
283
+
284
+ // Requests are queued and executed at 1/second
285
+ // Prevents API rate limit violations
286
+ ```
287
+
288
+ #### 3. **Priority Buffer** (Custom Implementation)
289
+ Implement priority queuing with buffer management:
290
+
291
+ ```typescript
292
+ class PriorityBufferedTask extends Task {
293
+ private priorityQueue: Array<{data: any, priority: number}> = [];
294
+
295
+ constructor(options) {
296
+ super({
297
+ ...options,
298
+ taskFunction: async (item) => {
299
+ // Process based on priority
300
+ return await this.processByPriority(item);
301
+ }
302
+ });
303
+ }
304
+
305
+ triggerWithPriority(data: any, priority: number) {
306
+ if (this.priorityQueue.length >= this.bufferMax) {
307
+ // Remove lowest priority item if buffer full
308
+ this.priorityQueue.sort((a, b) => b.priority - a.priority);
309
+ this.priorityQueue.pop();
310
+ }
311
+ this.priorityQueue.push({data, priority});
312
+ this.priorityQueue.sort((a, b) => b.priority - a.priority);
313
+ return this.trigger(this.priorityQueue.shift());
314
+ }
315
+ }
316
+ ```
317
+
318
+ ### Buffer Monitoring
319
+
320
+ Track buffer utilization and performance:
321
+
322
+ ```typescript
323
+ const monitoredTask = new Task({
324
+ name: 'MonitoredBuffer',
325
+ taskFunction: async (data) => {
326
+ const startTime = Date.now();
327
+ const result = await processData(data);
328
+ console.log(`Processing time: ${Date.now() - startTime}ms`);
329
+ console.log(`Buffer utilization: ${monitoredTask.bufferRunner.bufferCounter}/${monitoredTask.bufferMax}`);
330
+ return result;
331
+ },
332
+ buffered: true,
333
+ bufferMax: 20
334
+ });
335
+
336
+ // Monitor buffer saturation
337
+ setInterval(() => {
338
+ const utilization = (monitoredTask.bufferRunner.bufferCounter / monitoredTask.bufferMax) * 100;
339
+ if (utilization > 80) {
340
+ console.warn(`Buffer near capacity: ${utilization.toFixed(1)}%`);
341
+ }
342
+ }, 1000);
343
+ ```
344
+
345
+ ### Buffer Best Practices
346
+
347
+ 1. **Choose appropriate buffer sizes**:
348
+ - I/O operations: 5-10 concurrent
349
+ - CPU-intensive: Number of cores
350
+ - API calls: Based on rate limits
351
+
352
+ 2. **Handle buffer overflow gracefully**:
353
+ ```typescript
354
+ const task = new Task({
355
+ taskFunction: async (data) => {
356
+ try {
357
+ return await process(data);
358
+ } catch (error) {
359
+ if (error.code === 'BUFFER_OVERFLOW') {
360
+ // Implement backoff strategy
361
+ await delay(1000);
362
+ return task.trigger(data);
363
+ }
364
+ throw error;
365
+ }
366
+ },
367
+ buffered: true,
368
+ bufferMax: 10
369
+ });
370
+ ```
371
+
372
+ 3. **Monitor and adjust dynamically**:
373
+ ```typescript
374
+ // Adjust buffer size based on system load
375
+ const adaptiveTask = new Task({
376
+ name: 'AdaptiveBuffer',
377
+ taskFunction: async (data) => {
378
+ const cpuLoad = await getSystemLoad();
379
+ if (cpuLoad > 0.8) {
380
+ adaptiveTask.bufferMax = Math.max(2, adaptiveTask.bufferMax - 1);
381
+ } else if (cpuLoad < 0.5) {
382
+ adaptiveTask.bufferMax = Math.min(20, adaptiveTask.bufferMax + 1);
383
+ }
384
+ return await process(data);
385
+ },
386
+ buffered: true,
387
+ bufferMax: 10
388
+ });
389
+ ```
390
+
69
391
  ### Buffered Execution (Rate Limiting)
70
392
 
71
393
  Perfect for API calls or database operations that need throttling:
@@ -78,7 +400,7 @@ const apiTask = new Task({
78
400
  },
79
401
  buffered: true,
80
402
  bufferMax: 3, // Maximum 3 concurrent executions
81
- execDelay: 1000 // Wait 1 second between executions
403
+ execDelay: 1000, // Wait 1 second between executions
82
404
  });
83
405
 
84
406
  // These will be automatically throttled
@@ -99,18 +421,18 @@ const fetchTask = new Task({
99
421
  taskFunction: async () => {
100
422
  const response = await fetch('/api/data');
101
423
  return response.json();
102
- }
424
+ },
103
425
  });
104
426
 
105
427
  const transformTask = new Task({
106
428
  name: 'TransformData',
107
429
  taskFunction: async (data) => {
108
- return data.map(item => ({
430
+ return data.map((item) => ({
109
431
  ...item,
110
432
  processed: true,
111
- timestamp: Date.now()
433
+ timestamp: Date.now(),
112
434
  }));
113
- }
435
+ },
114
436
  });
115
437
 
116
438
  const saveTask = new Task({
@@ -118,12 +440,12 @@ const saveTask = new Task({
118
440
  taskFunction: async (transformedData) => {
119
441
  await database.bulkInsert(transformedData);
120
442
  return { saved: transformedData.length };
121
- }
443
+ },
122
444
  });
123
445
 
124
446
  const workflow = new Taskchain({
125
447
  name: 'DataPipeline',
126
- taskArray: [fetchTask, transformTask, saveTask]
448
+ taskArray: [fetchTask, transformTask, saveTask],
127
449
  });
128
450
 
129
451
  // Execute the entire chain
@@ -138,18 +460,19 @@ Execute multiple independent tasks simultaneously:
138
460
  ```typescript
139
461
  import { Task, Taskparallel } from '@push.rocks/taskbuffer';
140
462
 
141
- const tasks = ['user', 'posts', 'comments'].map(resource =>
142
- new Task({
143
- name: `Fetch${resource}`,
144
- taskFunction: async () => {
145
- const data = await fetch(`/api/${resource}`);
146
- return data.json();
147
- }
148
- })
463
+ const tasks = ['user', 'posts', 'comments'].map(
464
+ (resource) =>
465
+ new Task({
466
+ name: `Fetch${resource}`,
467
+ taskFunction: async () => {
468
+ const data = await fetch(`/api/${resource}`);
469
+ return data.json();
470
+ },
471
+ }),
149
472
  );
150
473
 
151
474
  const parallelFetch = new Taskparallel({
152
- taskArray: tasks
475
+ taskArray: tasks,
153
476
  });
154
477
 
155
478
  // All tasks execute simultaneously
@@ -168,7 +491,7 @@ const backupTask = new Task({
168
491
  taskFunction: async () => {
169
492
  await performBackup();
170
493
  console.log(`Backup completed at ${new Date().toISOString()}`);
171
- }
494
+ },
172
495
  });
173
496
 
174
497
  const manager = new TaskManager();
@@ -197,7 +520,7 @@ const saveTask = new TaskDebounced({
197
520
  await saveToDatabase(content);
198
521
  console.log('Content saved');
199
522
  },
200
- debounceTimeInMillis: 2000 // Wait 2 seconds of inactivity
523
+ debounceTimeInMillis: 2000, // Wait 2 seconds of inactivity
201
524
  });
202
525
 
203
526
  // Rapid calls will be debounced
@@ -220,7 +543,7 @@ const initTask = new TaskOnce({
220
543
  await cache.initialize();
221
544
  await loadConfiguration();
222
545
  console.log('System initialized');
223
- }
546
+ },
224
547
  });
225
548
 
226
549
  // Safe to call multiple times - only runs once
@@ -242,7 +565,7 @@ const validationTask = new Task({
242
565
  throw new Error('Validation failed');
243
566
  }
244
567
  return data;
245
- }
568
+ },
246
569
  });
247
570
 
248
571
  const mainTask = new Task({
@@ -250,8 +573,8 @@ const mainTask = new Task({
250
573
  taskFunction: async (data) => {
251
574
  return await complexProcessing(data);
252
575
  },
253
- preTask: validationTask, // Runs before main task
254
- afterTask: cleanupTask // Runs after main task
576
+ preTask: validationTask, // Runs before main task
577
+ afterTask: cleanupTask, // Runs after main task
255
578
  });
256
579
  ```
257
580
 
@@ -264,7 +587,7 @@ import { TaskRunner } from '@push.rocks/taskbuffer';
264
587
 
265
588
  const runner = new TaskRunner({
266
589
  name: 'WorkerNode1',
267
- maxConcurrentTasks: 5
590
+ maxConcurrentTasks: 5,
268
591
  });
269
592
 
270
593
  // Register tasks this runner can handle
@@ -282,11 +605,13 @@ Fine-tune concurrent execution behavior:
282
605
  ```typescript
283
606
  const task = new Task({
284
607
  name: 'ResourceIntensive',
285
- taskFunction: async () => { /* ... */ },
608
+ taskFunction: async () => {
609
+ /* ... */
610
+ },
286
611
  buffered: true,
287
- bufferMax: 5, // Max 5 concurrent
288
- execDelay: 100, // 100ms between starts
289
- timeout: 30000 // 30 second timeout
612
+ bufferMax: 5, // Max 5 concurrent
613
+ execDelay: 100, // 100ms between starts
614
+ timeout: 30000, // 30 second timeout
290
615
  });
291
616
  ```
292
617
 
@@ -297,14 +622,18 @@ TaskBuffer automatically detects and prevents circular dependencies:
297
622
  ```typescript
298
623
  const taskA = new Task({
299
624
  name: 'TaskA',
300
- taskFunction: async () => { /* ... */ },
301
- preTask: taskB // This would create a cycle
625
+ taskFunction: async () => {
626
+ /* ... */
627
+ },
628
+ preTask: taskB, // This would create a cycle
302
629
  });
303
630
 
304
631
  const taskB = new Task({
305
632
  name: 'TaskB',
306
- taskFunction: async () => { /* ... */ },
307
- preTask: taskA // Circular dependency detected!
633
+ taskFunction: async () => {
634
+ /* ... */
635
+ },
636
+ preTask: taskA, // Circular dependency detected!
308
637
  });
309
638
  ```
310
639
 
@@ -314,20 +643,21 @@ Create tasks on-the-fly based on runtime conditions:
314
643
 
315
644
  ```typescript
316
645
  const dynamicWorkflow = async (config: Config) => {
317
- const tasks = config.steps.map(step =>
318
- new Task({
319
- name: step.name,
320
- taskFunction: async (input) => {
321
- return await processStep(step, input);
322
- }
323
- })
646
+ const tasks = config.steps.map(
647
+ (step) =>
648
+ new Task({
649
+ name: step.name,
650
+ taskFunction: async (input) => {
651
+ return await processStep(step, input);
652
+ },
653
+ }),
324
654
  );
325
-
655
+
326
656
  const chain = new Taskchain({
327
657
  name: 'DynamicWorkflow',
328
- taskArray: tasks
658
+ taskArray: tasks,
329
659
  });
330
-
660
+
331
661
  return await chain.trigger();
332
662
  };
333
663
  ```
@@ -336,35 +666,35 @@ const dynamicWorkflow = async (config: Config) => {
336
666
 
337
667
  ### Task Options
338
668
 
339
- | Option | Type | Description |
340
- |--------|------|-------------|
341
- | `name` | `string` | Unique identifier for the task |
342
- | `taskFunction` | `Function` | Async function to execute |
343
- | `buffered` | `boolean` | Enable buffer management |
344
- | `bufferMax` | `number` | Maximum concurrent executions |
345
- | `execDelay` | `number` | Delay between executions (ms) |
346
- | `timeout` | `number` | Task timeout (ms) |
347
- | `preTask` | `Task` | Task to run before |
348
- | `afterTask` | `Task` | Task to run after |
669
+ | Option | Type | Description |
670
+ | -------------- | ---------- | ------------------------------ |
671
+ | `name` | `string` | Unique identifier for the task |
672
+ | `taskFunction` | `Function` | Async function to execute |
673
+ | `buffered` | `boolean` | Enable buffer management |
674
+ | `bufferMax` | `number` | Maximum concurrent executions |
675
+ | `execDelay` | `number` | Delay between executions (ms) |
676
+ | `timeout` | `number` | Task timeout (ms) |
677
+ | `preTask` | `Task` | Task to run before |
678
+ | `afterTask` | `Task` | Task to run after |
349
679
 
350
680
  ### TaskManager Methods
351
681
 
352
- | Method | Description |
353
- |--------|-------------|
354
- | `addTask(task, cronExpression)` | Add and schedule a task |
355
- | `removeTask(taskName)` | Remove a scheduled task |
356
- | `start()` | Start the scheduler |
357
- | `stop()` | Stop the scheduler |
358
- | `getStats()` | Get execution statistics |
682
+ | Method | Description |
683
+ | ------------------------------- | ------------------------ |
684
+ | `addTask(task, cronExpression)` | Add and schedule a task |
685
+ | `removeTask(taskName)` | Remove a scheduled task |
686
+ | `start()` | Start the scheduler |
687
+ | `stop()` | Stop the scheduler |
688
+ | `getStats()` | Get execution statistics |
359
689
 
360
690
  ### Taskchain Methods
361
691
 
362
- | Method | Description |
363
- |--------|-------------|
364
- | `addTask(task)` | Add task to chain |
365
- | `removeTask(taskName)` | Remove task from chain |
366
- | `trigger(initialValue)` | Execute the chain |
367
- | `reset()` | Reset chain state |
692
+ | Method | Description |
693
+ | ----------------------- | ---------------------- |
694
+ | `addTask(task)` | Add task to chain |
695
+ | `removeTask(taskName)` | Remove task from chain |
696
+ | `trigger(initialValue)` | Execute the chain |
697
+ | `reset()` | Reset chain state |
368
698
 
369
699
  ## Performance Tips 🏎️
370
700
 
@@ -385,17 +715,17 @@ const robustTask = new Task({
385
715
  } catch (error) {
386
716
  // Log error
387
717
  console.error(`Task failed: ${error.message}`);
388
-
718
+
389
719
  // Optionally retry
390
720
  if (error.retryable) {
391
721
  return await riskyOperation(input);
392
722
  }
393
-
723
+
394
724
  // Or return default value
395
725
  return defaultValue;
396
726
  }
397
727
  },
398
- timeout: 5000 // Fail if takes longer than 5 seconds
728
+ timeout: 5000, // Fail if takes longer than 5 seconds
399
729
  });
400
730
  ```
401
731
 
@@ -410,8 +740,8 @@ const apiClient = new Task({
410
740
  return await fetch(`https://api.example.com${endpoint}`);
411
741
  },
412
742
  buffered: true,
413
- bufferMax: 10, // 10 requests
414
- execDelay: 100 // Per 100ms = 100 req/s max
743
+ bufferMax: 10, // 10 requests
744
+ execDelay: 100, // Per 100ms = 100 req/s max
415
745
  });
416
746
  ```
417
747
 
@@ -425,8 +755,8 @@ const migrationChain = new Taskchain({
425
755
  schemaUpdateTask,
426
756
  dataTransformTask,
427
757
  validationTask,
428
- cleanupTask
429
- ]
758
+ cleanupTask,
759
+ ],
430
760
  });
431
761
  ```
432
762
 
@@ -435,7 +765,7 @@ const migrationChain = new Taskchain({
435
765
  ```typescript
436
766
  const healthMonitor = new TaskManager();
437
767
 
438
- services.forEach(service => {
768
+ services.forEach((service) => {
439
769
  const healthCheck = new Task({
440
770
  name: `HealthCheck:${service.name}`,
441
771
  taskFunction: async () => {
@@ -443,9 +773,9 @@ services.forEach(service => {
443
773
  if (!healthy) {
444
774
  await alertOps(service);
445
775
  }
446
- }
776
+ },
447
777
  });
448
-
778
+
449
779
  healthMonitor.addAndScheduleTask(healthCheck, '*/1 * * * *'); // Every minute
450
780
  });
451
781
  ```
@@ -476,7 +806,7 @@ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) f
476
806
 
477
807
  ## License and Legal Information
478
808
 
479
- This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
809
+ This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
480
810
 
481
811
  **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
482
812
 
@@ -491,4 +821,4 @@ Registered at District court Bremen HRB 35230 HB, Germany
491
821
 
492
822
  For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
493
823
 
494
- By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
824
+ By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/taskbuffer',
6
- version: '3.1.8',
6
+ version: '3.1.10',
7
7
  description: 'A flexible task management library supporting TypeScript, allowing for task buffering, scheduling, and execution with dependency management.'
8
8
  }