fix(tests): Update CI workflows, fix tests and refresh README/package metadata

This commit is contained in:
2025-08-26 20:16:47 +00:00
parent 863adb3b8c
commit dc47bc3d2a
20 changed files with 201 additions and 125 deletions

View File

@@ -6,8 +6,8 @@ on:
- '**' - '**'
env: env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci IMAGE: code.foss.global/host.today/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}} NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}} NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}} NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
@@ -26,7 +26,7 @@ jobs:
- name: Install pnpm and npmci - name: Install pnpm and npmci
run: | run: |
pnpm install -g pnpm pnpm install -g pnpm
pnpm install -g @shipzone/npmci pnpm install -g @ship.zone/npmci
- name: Run npm prepare - name: Run npm prepare
run: npmci npm prepare run: npmci npm prepare

View File

@@ -6,8 +6,8 @@ on:
- '*' - '*'
env: env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci IMAGE: code.foss.global/host.today/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}} NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}} NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}} NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
@@ -26,7 +26,7 @@ jobs:
- name: Prepare - name: Prepare
run: | run: |
pnpm install -g pnpm pnpm install -g pnpm
pnpm install -g @shipzone/npmci pnpm install -g @ship.zone/npmci
npmci npm prepare npmci npm prepare
- name: Audit production dependencies - name: Audit production dependencies
@@ -54,7 +54,7 @@ jobs:
- name: Prepare - name: Prepare
run: | run: |
pnpm install -g pnpm pnpm install -g pnpm
pnpm install -g @shipzone/npmci pnpm install -g @ship.zone/npmci
npmci npm prepare npmci npm prepare
- name: Test stable - name: Test stable
@@ -82,7 +82,7 @@ jobs:
- name: Prepare - name: Prepare
run: | run: |
pnpm install -g pnpm pnpm install -g pnpm
pnpm install -g @shipzone/npmci pnpm install -g @ship.zone/npmci
npmci npm prepare npmci npm prepare
- name: Release - name: Release
@@ -104,7 +104,7 @@ jobs:
- name: Prepare - name: Prepare
run: | run: |
pnpm install -g pnpm pnpm install -g pnpm
pnpm install -g @shipzone/npmci pnpm install -g @ship.zone/npmci
npmci npm prepare npmci npm prepare
- name: Code quality - name: Code quality

7
.gitignore vendored
View File

@@ -3,7 +3,6 @@
# artifacts # artifacts
coverage/ coverage/
public/ public/
pages/
# installs # installs
node_modules/ node_modules/
@@ -17,4 +16,8 @@ node_modules/
dist/ dist/
dist_*/ dist_*/
# custom # AI
.claude/
.serena/
#------# custom

View File

@@ -1,6 +1,17 @@
# Changelog # Changelog
## 2025-08-26 - 3.1.9 - fix(tests)
Update CI workflows, fix tests and refresh README/package metadata
- CI: switch Docker image to code.foss.global/host.today/ht-docker-node:npmci and adjust NPMCI_COMPUTED_REPOURL; replace npmci installer package name from @shipzone/npmci to @ship.zone/npmci in Gitea workflows
- Tests: update test imports to use @git.zone/tstest/tapbundle and apply small formatting fixes to test files
- Package metadata: update bugs URL and homepage to code.foss.global, add a pnpm.overrides placeholder in package.json
- .gitignore: add AI/tooling directories (.claude, .serena) and reorganize custom section
- Code style/TS fixes: minor formatting changes across ts sources (trailing commas, line breaks, consistent object/argument commas) and small API surface formatting fixes
- Documentation: whitespace/formatting cleanups in README and add changelog entry for 3.1.8
## 2025-08-26 - 3.1.8 - fix(tests) ## 2025-08-26 - 3.1.8 - fix(tests)
Update test runner and imports, refresh README and package metadata, add project tooling/config files Update test runner and imports, refresh README and package metadata, add project tooling/config files
- Replaced test imports from '@push.rocks/tapbundle' to '@git.zone/tstest/tapbundle' across test files - Replaced test imports from '@push.rocks/tapbundle' to '@git.zone/tstest/tapbundle' across test files
@@ -11,6 +22,7 @@ Update test runner and imports, refresh README and package metadata, add project
- Added development/project tooling and metadata files (.claude settings, .serena project/memories) to aid local development and CI - Added development/project tooling and metadata files (.claude settings, .serena project/memories) to aid local development and CI
## 2024-05-29 - 3.1.7 - maintenance/config ## 2024-05-29 - 3.1.7 - maintenance/config
Updated package metadata and build configuration. Updated package metadata and build configuration.
- Updated package description. - Updated package description.
@@ -18,36 +30,42 @@ Updated package metadata and build configuration.
- Updated npmextra.json githost entries (changes across 2024-03-30, 2024-04-01, 2024-04-14). - Updated npmextra.json githost entries (changes across 2024-03-30, 2024-04-01, 2024-04-14).
## 2023-08-04 - 3.0.15 - feat(Task) ## 2023-08-04 - 3.0.15 - feat(Task)
Tasks can now be blocked by other tasks. Tasks can now be blocked by other tasks.
- Introduced task blocking support in the Task implementation. - Introduced task blocking support in the Task implementation.
- Release contains related maintenance and patch fixes. - Release contains related maintenance and patch fixes.
## 2023-01-07 to 2023-10-20 - 3.0.4..3.1.6 - maintenance ## 2023-01-07 to 2023-10-20 - 3.0.4..3.1.6 - maintenance
Series of patch releases focused on core fixes and stability. Series of patch releases focused on core fixes and stability.
- Numerous core fixes and small adjustments across many patch versions. - Numerous core fixes and small adjustments across many patch versions.
- General maintenance: bug fixes, internal updates and stability improvements. - General maintenance: bug fixes, internal updates and stability improvements.
## 2022-03-25 - 2.1.17 - BREAKING(core) ## 2022-03-25 - 2.1.17 - BREAKING(core)
Switched module format to ESM (breaking). Switched module format to ESM (breaking).
- BREAKING CHANGE: project now uses ESM module format. - BREAKING CHANGE: project now uses ESM module format.
- Release includes the version bump and migration to ESM. - Release includes the version bump and migration to ESM.
## 2019-11-28 - 2.0.16 - feat(taskrunner) ## 2019-11-28 - 2.0.16 - feat(taskrunner)
Introduce a working task runner. Introduce a working task runner.
- Added/activated a working taskrunner implementation. - Added/activated a working taskrunner implementation.
- Improvements to task execution and orchestration. - Improvements to task execution and orchestration.
## 2019-09-05 to 2022-11-14 - 2.0.3..2.1.16 - maintenance ## 2019-09-05 to 2022-11-14 - 2.0.3..2.1.16 - maintenance
Ongoing maintenance and incremental fixes between 2.0.x and 2.1.x series. Ongoing maintenance and incremental fixes between 2.0.x and 2.1.x series.
- Multiple fixes labeled as core maintenance updates. - Multiple fixes labeled as core maintenance updates.
- CI, packaging and small doc/test fixes rolled out across these releases. - CI, packaging and small doc/test fixes rolled out across these releases.
## 2018-08-04 - 2.0.0 - major ## 2018-08-04 - 2.0.0 - major
Major release and scope change with CI/test updates. Major release and scope change with CI/test updates.
- Released 2.0.0 with updated docs. - Released 2.0.0 with updated docs.
@@ -55,6 +73,7 @@ Major release and scope change with CI/test updates.
- CI and testing updates (moved to new tstest), package.json adjustments. - CI and testing updates (moved to new tstest), package.json adjustments.
## 2017-07-12 - 1.0.21 - enhancements ## 2017-07-12 - 1.0.21 - enhancements
Feature additions around task utilities and manager. Feature additions around task utilities and manager.
- Introduced TaskOnce. - Introduced TaskOnce.
@@ -63,18 +82,21 @@ Feature additions around task utilities and manager.
- Documentation and test improvements. - Documentation and test improvements.
## 2016-08-03 - 1.0.6 - types ## 2016-08-03 - 1.0.6 - types
Type and promise improvements. Type and promise improvements.
- Now returns correct Promise types. - Now returns correct Promise types.
- Dependency and typings updates. - Dependency and typings updates.
## 2016-08-01 - 1.0.0 - stable ## 2016-08-01 - 1.0.0 - stable
First stable 1.0.0 release. First stable 1.0.0 release.
- Exported public interfaces. - Exported public interfaces.
- Base API stabilized for 1.x line. - Base API stabilized for 1.x line.
## 2016-05-15 to 2016-05-06 - 0.1.0..0.0.5 - initial features ## 2016-05-15 to 2016-05-06 - 0.1.0..0.0.5 - initial features
Initial implementation of core task primitives and utilities. Initial implementation of core task primitives and utilities.
- Added Taskparallel class to execute tasks in parallel. - Added Taskparallel class to execute tasks in parallel.

View File

@@ -30,9 +30,9 @@
"author": "Lossless GmbH", "author": "Lossless GmbH",
"license": "MIT", "license": "MIT",
"bugs": { "bugs": {
"url": "https://gitlab.com/pushrocks/taskbuffer/issues" "url": "https://code.foss.global/push.rocks/taskbuffer/issues"
}, },
"homepage": "https://code.foss.global/push.rocks/taskbuffer", "homepage": "https://code.foss.global/push.rocks/taskbuffer#readme",
"dependencies": { "dependencies": {
"@push.rocks/lik": "^6.0.5", "@push.rocks/lik": "^6.0.5",
"@push.rocks/smartdelay": "^3.0.5", "@push.rocks/smartdelay": "^3.0.5",
@@ -64,5 +64,8 @@
"browserslist": [ "browserslist": [
"last 1 chrome versions" "last 1 chrome versions"
], ],
"packageManager": "pnpm@10.14.0+sha512.ad27a79641b49c3e481a16a805baa71817a04bbe06a38d17e60e2eaee83f6a146c6a688125f5792e48dd5ba30e7da52a5cda4c3992b9ccf333f9ce223af84748" "packageManager": "pnpm@10.14.0+sha512.ad27a79641b49c3e481a16a805baa71817a04bbe06a38d17e60e2eaee83f6a146c6a688125f5792e48dd5ba30e7da52a5cda4c3992b9ccf333f9ce223af84748",
"pnpm": {
"overrides": {}
}
} }

View File

@@ -29,21 +29,27 @@ In the modern JavaScript ecosystem, managing asynchronous tasks efficiently is c
## Core Concepts 🎓 ## Core Concepts 🎓
### Task ### Task
The fundamental unit of work. A task wraps an asynchronous function and provides powerful execution control. The fundamental unit of work. A task wraps an asynchronous function and provides powerful execution control.
### Taskchain ### Taskchain
Sequential task execution - tasks run one after another, with results passed along the chain. Sequential task execution - tasks run one after another, with results passed along the chain.
### Taskparallel ### Taskparallel
Parallel task execution - multiple tasks run simultaneously for maximum performance. Parallel task execution - multiple tasks run simultaneously for maximum performance.
### TaskManager ### TaskManager
Centralized task scheduling and management using cron expressions. Centralized task scheduling and management using cron expressions.
### TaskDebounced ### TaskDebounced
Debounced task execution - prevents rapid repeated executions, only running after a quiet period. Debounced task execution - prevents rapid repeated executions, only running after a quiet period.
### TaskOnce ### TaskOnce
Singleton task execution - ensures a task runs exactly once, perfect for initialization routines. Singleton task execution - ensures a task runs exactly once, perfect for initialization routines.
## Quick Start 🏁 ## Quick Start 🏁
@@ -59,7 +65,7 @@ const myTask = new Task({
taskFunction: async () => { taskFunction: async () => {
const data = await fetchData(); const data = await fetchData();
return processData(data); return processData(data);
} },
}); });
// Execute the task // Execute the task
@@ -78,7 +84,7 @@ const apiTask = new Task({
}, },
buffered: true, buffered: true,
bufferMax: 3, // Maximum 3 concurrent executions bufferMax: 3, // Maximum 3 concurrent executions
execDelay: 1000 // Wait 1 second between executions execDelay: 1000, // Wait 1 second between executions
}); });
// These will be automatically throttled // These will be automatically throttled
@@ -99,18 +105,18 @@ const fetchTask = new Task({
taskFunction: async () => { taskFunction: async () => {
const response = await fetch('/api/data'); const response = await fetch('/api/data');
return response.json(); return response.json();
} },
}); });
const transformTask = new Task({ const transformTask = new Task({
name: 'TransformData', name: 'TransformData',
taskFunction: async (data) => { taskFunction: async (data) => {
return data.map(item => ({ return data.map((item) => ({
...item, ...item,
processed: true, processed: true,
timestamp: Date.now() timestamp: Date.now(),
})); }));
} },
}); });
const saveTask = new Task({ const saveTask = new Task({
@@ -118,12 +124,12 @@ const saveTask = new Task({
taskFunction: async (transformedData) => { taskFunction: async (transformedData) => {
await database.bulkInsert(transformedData); await database.bulkInsert(transformedData);
return { saved: transformedData.length }; return { saved: transformedData.length };
} },
}); });
const workflow = new Taskchain({ const workflow = new Taskchain({
name: 'DataPipeline', name: 'DataPipeline',
taskArray: [fetchTask, transformTask, saveTask] taskArray: [fetchTask, transformTask, saveTask],
}); });
// Execute the entire chain // Execute the entire chain
@@ -138,18 +144,19 @@ Execute multiple independent tasks simultaneously:
```typescript ```typescript
import { Task, Taskparallel } from '@push.rocks/taskbuffer'; import { Task, Taskparallel } from '@push.rocks/taskbuffer';
const tasks = ['user', 'posts', 'comments'].map(resource => const tasks = ['user', 'posts', 'comments'].map(
(resource) =>
new Task({ new Task({
name: `Fetch${resource}`, name: `Fetch${resource}`,
taskFunction: async () => { taskFunction: async () => {
const data = await fetch(`/api/${resource}`); const data = await fetch(`/api/${resource}`);
return data.json(); return data.json();
} },
}) }),
); );
const parallelFetch = new Taskparallel({ const parallelFetch = new Taskparallel({
taskArray: tasks taskArray: tasks,
}); });
// All tasks execute simultaneously // All tasks execute simultaneously
@@ -168,7 +175,7 @@ const backupTask = new Task({
taskFunction: async () => { taskFunction: async () => {
await performBackup(); await performBackup();
console.log(`Backup completed at ${new Date().toISOString()}`); console.log(`Backup completed at ${new Date().toISOString()}`);
} },
}); });
const manager = new TaskManager(); const manager = new TaskManager();
@@ -197,7 +204,7 @@ const saveTask = new TaskDebounced({
await saveToDatabase(content); await saveToDatabase(content);
console.log('Content saved'); console.log('Content saved');
}, },
debounceTimeInMillis: 2000 // Wait 2 seconds of inactivity debounceTimeInMillis: 2000, // Wait 2 seconds of inactivity
}); });
// Rapid calls will be debounced // Rapid calls will be debounced
@@ -220,7 +227,7 @@ const initTask = new TaskOnce({
await cache.initialize(); await cache.initialize();
await loadConfiguration(); await loadConfiguration();
console.log('System initialized'); console.log('System initialized');
} },
}); });
// Safe to call multiple times - only runs once // Safe to call multiple times - only runs once
@@ -242,7 +249,7 @@ const validationTask = new Task({
throw new Error('Validation failed'); throw new Error('Validation failed');
} }
return data; return data;
} },
}); });
const mainTask = new Task({ const mainTask = new Task({
@@ -251,7 +258,7 @@ const mainTask = new Task({
return await complexProcessing(data); return await complexProcessing(data);
}, },
preTask: validationTask, // Runs before main task preTask: validationTask, // Runs before main task
afterTask: cleanupTask // Runs after main task afterTask: cleanupTask, // Runs after main task
}); });
``` ```
@@ -264,7 +271,7 @@ import { TaskRunner } from '@push.rocks/taskbuffer';
const runner = new TaskRunner({ const runner = new TaskRunner({
name: 'WorkerNode1', name: 'WorkerNode1',
maxConcurrentTasks: 5 maxConcurrentTasks: 5,
}); });
// Register tasks this runner can handle // Register tasks this runner can handle
@@ -282,11 +289,13 @@ Fine-tune concurrent execution behavior:
```typescript ```typescript
const task = new Task({ const task = new Task({
name: 'ResourceIntensive', name: 'ResourceIntensive',
taskFunction: async () => { /* ... */ }, taskFunction: async () => {
/* ... */
},
buffered: true, buffered: true,
bufferMax: 5, // Max 5 concurrent bufferMax: 5, // Max 5 concurrent
execDelay: 100, // 100ms between starts execDelay: 100, // 100ms between starts
timeout: 30000 // 30 second timeout timeout: 30000, // 30 second timeout
}); });
``` ```
@@ -297,14 +306,18 @@ TaskBuffer automatically detects and prevents circular dependencies:
```typescript ```typescript
const taskA = new Task({ const taskA = new Task({
name: 'TaskA', name: 'TaskA',
taskFunction: async () => { /* ... */ }, taskFunction: async () => {
preTask: taskB // This would create a cycle /* ... */
},
preTask: taskB, // This would create a cycle
}); });
const taskB = new Task({ const taskB = new Task({
name: 'TaskB', name: 'TaskB',
taskFunction: async () => { /* ... */ }, taskFunction: async () => {
preTask: taskA // Circular dependency detected! /* ... */
},
preTask: taskA, // Circular dependency detected!
}); });
``` ```
@@ -314,18 +327,19 @@ Create tasks on-the-fly based on runtime conditions:
```typescript ```typescript
const dynamicWorkflow = async (config: Config) => { const dynamicWorkflow = async (config: Config) => {
const tasks = config.steps.map(step => const tasks = config.steps.map(
(step) =>
new Task({ new Task({
name: step.name, name: step.name,
taskFunction: async (input) => { taskFunction: async (input) => {
return await processStep(step, input); return await processStep(step, input);
} },
}) }),
); );
const chain = new Taskchain({ const chain = new Taskchain({
name: 'DynamicWorkflow', name: 'DynamicWorkflow',
taskArray: tasks taskArray: tasks,
}); });
return await chain.trigger(); return await chain.trigger();
@@ -337,7 +351,7 @@ const dynamicWorkflow = async (config: Config) => {
### Task Options ### Task Options
| Option | Type | Description | | Option | Type | Description |
|--------|------|-------------| | -------------- | ---------- | ------------------------------ |
| `name` | `string` | Unique identifier for the task | | `name` | `string` | Unique identifier for the task |
| `taskFunction` | `Function` | Async function to execute | | `taskFunction` | `Function` | Async function to execute |
| `buffered` | `boolean` | Enable buffer management | | `buffered` | `boolean` | Enable buffer management |
@@ -350,7 +364,7 @@ const dynamicWorkflow = async (config: Config) => {
### TaskManager Methods ### TaskManager Methods
| Method | Description | | Method | Description |
|--------|-------------| | ------------------------------- | ------------------------ |
| `addTask(task, cronExpression)` | Add and schedule a task | | `addTask(task, cronExpression)` | Add and schedule a task |
| `removeTask(taskName)` | Remove a scheduled task | | `removeTask(taskName)` | Remove a scheduled task |
| `start()` | Start the scheduler | | `start()` | Start the scheduler |
@@ -360,7 +374,7 @@ const dynamicWorkflow = async (config: Config) => {
### Taskchain Methods ### Taskchain Methods
| Method | Description | | Method | Description |
|--------|-------------| | ----------------------- | ---------------------- |
| `addTask(task)` | Add task to chain | | `addTask(task)` | Add task to chain |
| `removeTask(taskName)` | Remove task from chain | | `removeTask(taskName)` | Remove task from chain |
| `trigger(initialValue)` | Execute the chain | | `trigger(initialValue)` | Execute the chain |
@@ -395,7 +409,7 @@ const robustTask = new Task({
return defaultValue; return defaultValue;
} }
}, },
timeout: 5000 // Fail if takes longer than 5 seconds timeout: 5000, // Fail if takes longer than 5 seconds
}); });
``` ```
@@ -411,7 +425,7 @@ const apiClient = new Task({
}, },
buffered: true, buffered: true,
bufferMax: 10, // 10 requests bufferMax: 10, // 10 requests
execDelay: 100 // Per 100ms = 100 req/s max execDelay: 100, // Per 100ms = 100 req/s max
}); });
``` ```
@@ -425,8 +439,8 @@ const migrationChain = new Taskchain({
schemaUpdateTask, schemaUpdateTask,
dataTransformTask, dataTransformTask,
validationTask, validationTask,
cleanupTask cleanupTask,
] ],
}); });
``` ```
@@ -435,7 +449,7 @@ const migrationChain = new Taskchain({
```typescript ```typescript
const healthMonitor = new TaskManager(); const healthMonitor = new TaskManager();
services.forEach(service => { services.forEach((service) => {
const healthCheck = new Task({ const healthCheck = new Task({
name: `HealthCheck:${service.name}`, name: `HealthCheck:${service.name}`,
taskFunction: async () => { taskFunction: async () => {
@@ -443,7 +457,7 @@ services.forEach(service => {
if (!healthy) { if (!healthy) {
await alertOps(service); await alertOps(service);
} }
} },
}); });
healthMonitor.addAndScheduleTask(healthCheck, '*/1 * * * *'); // Every minute healthMonitor.addAndScheduleTask(healthCheck, '*/1 * * * *'); // Every minute

View File

@@ -49,10 +49,12 @@ tap.test('should execute setup function before the task function', async () => {
const task2 = new taskbuffer.Task({ const task2 = new taskbuffer.Task({
name: 'Task 2', name: 'Task 2',
taskSetup: async () => { taskSetup: async () => {
console.log('this is the setup function for task 2. It should only run once.') console.log(
'this is the setup function for task 2. It should only run once.',
);
return { return {
nice: 'yes', nice: 'yes',
} };
}, },
taskFunction: async (before, setupArg) => { taskFunction: async (before, setupArg) => {
expect(setupArg).toEqual({ nice: 'yes' }); expect(setupArg).toEqual({ nice: 'yes' });

View File

@@ -29,7 +29,7 @@ tap.test('should run the task as expected', async () => {
taskDone.resolve(); taskDone.resolve();
} }
}, },
}) }),
); );
myTaskManager.start(); myTaskManager.start();
await myTaskManager.triggerTaskByName('myTask'); await myTaskManager.triggerTaskByName('myTask');

View File

@@ -16,7 +16,7 @@ tap.test('should execute task when its scheduled', async (tools) => {
taskFunction: async () => { taskFunction: async () => {
console.log('hi'); console.log('hi');
}, },
}) }),
); );
testTaskRunner.addTask( testTaskRunner.addTask(
@@ -25,7 +25,7 @@ tap.test('should execute task when its scheduled', async (tools) => {
console.log('there'); console.log('there');
done.resolve(); done.resolve();
}, },
}) }),
); );
await done.promise; await done.promise;

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@push.rocks/taskbuffer', name: '@push.rocks/taskbuffer',
version: '3.1.8', version: '3.1.9',
description: 'A flexible task management library supporting TypeScript, allowing for task buffering, scheduling, and execution with dependency management.' description: 'A flexible task management library supporting TypeScript, allowing for task buffering, scheduling, and execution with dependency management.'
} }

View File

@@ -13,9 +13,8 @@ export class BufferRunner {
if (!(this.bufferCounter >= this.task.bufferMax)) { if (!(this.bufferCounter >= this.task.bufferMax)) {
this.bufferCounter++; this.bufferCounter++;
} }
const returnPromise: Promise<any> = this.task.cycleCounter.getPromiseForCycle( const returnPromise: Promise<any> =
this.bufferCounter this.task.cycleCounter.getPromiseForCycle(this.bufferCounter);
);
if (!this.task.running) { if (!this.task.running) {
this._run(x); this._run(x);
} }

View File

@@ -26,11 +26,11 @@ export interface IDistributedTaskRequestResult {
export abstract class AbstractDistributedCoordinator { export abstract class AbstractDistributedCoordinator {
public abstract fireDistributedTaskRequest( public abstract fireDistributedTaskRequest(
infoBasis: IDistributedTaskRequest infoBasis: IDistributedTaskRequest,
): Promise<IDistributedTaskRequestResult>; ): Promise<IDistributedTaskRequestResult>;
public abstract updateDistributedTaskRequest( public abstract updateDistributedTaskRequest(
infoBasis: IDistributedTaskRequest infoBasis: IDistributedTaskRequest,
): Promise<void>; ): Promise<void>;
public abstract start(): Promise<void>; public abstract start(): Promise<void>;

View File

@@ -16,7 +16,7 @@ export type TPreOrAfterTaskFunction = () => Task<any>;
export class Task<T = undefined> { export class Task<T = undefined> {
public static extractTask<T = undefined>( public static extractTask<T = undefined>(
preOrAfterTaskArg: Task<T> | TPreOrAfterTaskFunction preOrAfterTaskArg: Task<T> | TPreOrAfterTaskFunction,
): Task<T> { ): Task<T> {
switch (true) { switch (true) {
case !preOrAfterTaskArg: case !preOrAfterTaskArg:
@@ -47,7 +47,7 @@ export class Task<T = undefined> {
public static isTaskTouched<T = undefined>( public static isTaskTouched<T = undefined>(
taskArg: Task<T> | TPreOrAfterTaskFunction, taskArg: Task<T> | TPreOrAfterTaskFunction,
touchedTasksArray: Task<T>[] touchedTasksArray: Task<T>[],
): boolean { ): boolean {
const taskToCheck = Task.extractTask(taskArg); const taskToCheck = Task.extractTask(taskArg);
let result = false; let result = false;
@@ -61,7 +61,7 @@ export class Task<T = undefined> {
public static runTask = async <T>( public static runTask = async <T>(
taskArg: Task<T> | TPreOrAfterTaskFunction, taskArg: Task<T> | TPreOrAfterTaskFunction,
optionsArg: { x?: any; touchedTasksArray?: Task<T>[] } optionsArg: { x?: any; touchedTasksArray?: Task<T>[] },
) => { ) => {
const taskToRun = Task.extractTask(taskArg); const taskToRun = Task.extractTask(taskArg);
const done = plugins.smartpromise.defer(); const done = plugins.smartpromise.defer();
@@ -105,7 +105,10 @@ export class Task<T = undefined> {
const localDeferred = plugins.smartpromise.defer(); const localDeferred = plugins.smartpromise.defer();
localDeferred.promise localDeferred.promise
.then(() => { .then(() => {
if (taskToRun.preTask && !Task.isTaskTouched(taskToRun.preTask, touchedTasksArray)) { if (
taskToRun.preTask &&
!Task.isTaskTouched(taskToRun.preTask, touchedTasksArray)
) {
return Task.runTask(taskToRun.preTask, { x, touchedTasksArray }); return Task.runTask(taskToRun.preTask, { x, touchedTasksArray });
} else { } else {
const done2 = plugins.smartpromise.defer(); const done2 = plugins.smartpromise.defer();
@@ -121,8 +124,14 @@ export class Task<T = undefined> {
} }
}) })
.then((x) => { .then((x) => {
if (taskToRun.afterTask && !Task.isTaskTouched(taskToRun.afterTask, touchedTasksArray)) { if (
return Task.runTask(taskToRun.afterTask, { x: x, touchedTasksArray: touchedTasksArray }); taskToRun.afterTask &&
!Task.isTaskTouched(taskToRun.afterTask, touchedTasksArray)
) {
return Task.runTask(taskToRun.afterTask, {
x: x,
touchedTasksArray: touchedTasksArray,
});
} else { } else {
const done2 = plugins.smartpromise.defer(); const done2 = plugins.smartpromise.defer();
done2.resolve(x); done2.resolve(x);

View File

@@ -27,14 +27,18 @@ export class Taskchain extends Task {
let taskCounter = 0; // counter for iterating async over the taskArray let taskCounter = 0; // counter for iterating async over the taskArray
const iterateTasks = (x: any) => { const iterateTasks = (x: any) => {
if (typeof this.taskArray[taskCounter] !== 'undefined') { if (typeof this.taskArray[taskCounter] !== 'undefined') {
console.log(this.name + ' running: Task' + this.taskArray[taskCounter].name); console.log(
this.name + ' running: Task' + this.taskArray[taskCounter].name,
);
this.taskArray[taskCounter].trigger(x).then((x) => { this.taskArray[taskCounter].trigger(x).then((x) => {
logger.log('info', this.taskArray[taskCounter].name); logger.log('info', this.taskArray[taskCounter].name);
taskCounter++; taskCounter++;
iterateTasks(x); iterateTasks(x);
}); });
} else { } else {
console.log('Taskchain "' + this.name + '" completed successfully'); console.log(
'Taskchain "' + this.name + '" completed successfully',
);
done.resolve(x); done.resolve(x);
} }
}; };

View File

@@ -19,7 +19,9 @@ export class TaskDebounced<T = unknown> extends Task {
}); });
this.taskFunction = optionsArg.taskFunction; this.taskFunction = optionsArg.taskFunction;
this._observableIntake.observable this._observableIntake.observable
.pipe(plugins.smartrx.rxjs.ops.debounceTime(optionsArg.debounceTimeInMillis)) .pipe(
plugins.smartrx.rxjs.ops.debounceTime(optionsArg.debounceTimeInMillis),
)
.subscribe((x) => { .subscribe((x) => {
this.taskFunction(x); this.taskFunction(x);
}); });

View File

@@ -1,6 +1,9 @@
import * as plugins from './taskbuffer.plugins.js'; import * as plugins from './taskbuffer.plugins.js';
import { Task } from './taskbuffer.classes.task.js'; import { Task } from './taskbuffer.classes.task.js';
import { AbstractDistributedCoordinator, type IDistributedTaskRequestResult } from './taskbuffer.classes.distributedcoordinator.js'; import {
AbstractDistributedCoordinator,
type IDistributedTaskRequestResult,
} from './taskbuffer.classes.distributedcoordinator.js';
export interface ICronJob { export interface ICronJob {
cronString: string; cronString: string;
@@ -66,7 +69,10 @@ export class TaskManager {
async (triggerTime: number) => { async (triggerTime: number) => {
this.logTaskState(task); this.logTaskState(task);
if (this.options.distributedCoordinator) { if (this.options.distributedCoordinator) {
const announcementResult = await this.performDistributedConsultation(task, triggerTime); const announcementResult = await this.performDistributedConsultation(
task,
triggerTime,
);
if (!announcementResult.shouldTrigger) { if (!announcementResult.shouldTrigger) {
console.log('Distributed coordinator result: NOT EXECUTING'); console.log('Distributed coordinator result: NOT EXECUTING');
return; return;
@@ -75,7 +81,7 @@ export class TaskManager {
} }
} }
await task.trigger(); await task.trigger();
} },
); );
task.cronJob = cronJob; task.cronJob = cronJob;
} }
@@ -88,7 +94,10 @@ export class TaskManager {
console.log(`Task >>${task.name}<< is ${bufferState}`); console.log(`Task >>${task.name}<< is ${bufferState}`);
} }
private async performDistributedConsultation(task: Task, triggerTime: number): Promise<IDistributedTaskRequestResult> { private async performDistributedConsultation(
task: Task,
triggerTime: number,
): Promise<IDistributedTaskRequestResult> {
console.log('Found a distributed coordinator, performing consultation.'); console.log('Found a distributed coordinator, performing consultation.');
return this.options.distributedCoordinator.fireDistributedTaskRequest({ return this.options.distributedCoordinator.fireDistributedTaskRequest({

View File

@@ -5,7 +5,8 @@ import { Task } from './taskbuffer.classes.task.js';
export class TaskRunner { export class TaskRunner {
public maxParrallelJobs: number = 1; public maxParrallelJobs: number = 1;
public status: 'stopped' | 'running' = 'stopped'; public status: 'stopped' | 'running' = 'stopped';
public runningTasks: plugins.lik.ObjectMap<Task> = new plugins.lik.ObjectMap<Task>(); public runningTasks: plugins.lik.ObjectMap<Task> =
new plugins.lik.ObjectMap<Task>();
public qeuedTasks: Task[] = []; public qeuedTasks: Task[] = [];
constructor() { constructor() {

View File

@@ -6,4 +6,12 @@ import * as smartrx from '@push.rocks/smartrx';
import * as smarttime from '@push.rocks/smarttime'; import * as smarttime from '@push.rocks/smarttime';
import * as smartunique from '@push.rocks/smartunique'; import * as smartunique from '@push.rocks/smartunique';
export { lik, smartlog, smartpromise, smartdelay, smartrx, smarttime, smartunique }; export {
lik,
smartlog,
smartpromise,
smartdelay,
smartrx,
smarttime,
smartunique,
};

View File

@@ -6,9 +6,9 @@
"module": "NodeNext", "module": "NodeNext",
"moduleResolution": "NodeNext", "moduleResolution": "NodeNext",
"esModuleInterop": true, "esModuleInterop": true,
"verbatimModuleSyntax": true "verbatimModuleSyntax": true,
"baseUrl": ".",
"paths": {}
}, },
"exclude": [ "exclude": ["dist_*/**/*.d.ts"]
"dist_*/**/*.d.ts"
]
} }