# Taskbuffer Hints ## Task Constraint System (v5.0.0+) — Breaking Changes - **`TaskRunner` removed** — replaced by `TaskManager` + `TaskConstraintGroup` - **`blockingTasks` removed** from `Task` — use `TaskConstraintGroup` with `maxConcurrent: 1` - **`execDelay` removed** from `Task` — use `TaskConstraintGroup` with `cooldownMs` - **`finished` promise removed** from `Task` — no longer needed - **`Task` generic signature**: `Task` (3rd param added for typed data) ### Task.data - `Task` constructor accepts optional `data?: TData` (defaults to `{}`) - Typed data bag accessible as `task.data` ### TaskConstraintGroup - `new TaskConstraintGroup({ name, constraintKeyForExecution, maxConcurrent?, cooldownMs?, shouldExecute? })` - `constraintKeyForExecution(task, input?)` returns a string key (constraint applies) or `null` (skip). Receives both task and runtime input. - `shouldExecute(task, input?)` — optional pre-execution check. Returns `false` to skip (deferred resolves `undefined`). Can be async. - `maxConcurrent` (default: `Infinity`) — max concurrent tasks per key - `cooldownMs` (default: `0`) — minimum ms gap between completions per key - Methods: `getConstraintKey(task, input?)`, `checkShouldExecute(task, input?)`, `canRun(key)`, `acquireSlot(key)`, `releaseSlot(key)`, `getCooldownRemaining(key)`, `getRunningCount(key)`, `reset()` - `ITaskExecution` type exported from index — `{ task, input }` tuple ### TaskManager Constraint Integration - `manager.addConstraintGroup(group)` / `manager.removeConstraintGroup(name)` - `triggerTaskByName()`, `triggerTask()`, `addExecuteRemoveTask()`, cron callbacks all route through `triggerTaskConstrained()` - `triggerTaskConstrained(task, input?)` — evaluates constraints, queues if blocked, drains after completion - Cooldown-blocked entries auto-drain via timer ### Exported from index.ts - `TaskConstraintGroup` class - `ITaskConstraintGroupOptions` type ## Error Handling (v3.6.0+) - `Task` now has `catchErrors` constructor option (default: `false`) - Default behavior: `trigger()` rejects when taskFunction throws (breaking change from pre-3.6) - Set `catchErrors: true` to swallow errors (old behavior) - returns `undefined` on error - Error state tracked via `lastError?: Error`, `errorCount: number`, `clearError()` - `getMetadata()` status uses all four values: `'idle'` | `'running'` | `'completed'` | `'failed'` - All peripheral classes (Taskchain, Taskparallel, BufferRunner, TaskDebounced, TaskManager) have proper error propagation/handling - `console.log` calls replaced with `logger.log()` throughout ## Error Context Improvements - **TaskChain**: Errors now wrap the original with context: chain name, failing task name, and task index. Original error preserved via `.cause` - **BufferRunner**: When `catchErrors: false`, buffered task errors now reject the trigger promise (via `CycleCounter.informOfCycleError`) instead of silently resolving with `undefined` - **TaskChain stubs completed**: `removeTask(task)` returns `boolean`, `shiftTask()` returns `Task | undefined` ## Task Labels (v4.1.0+) - `Task` constructor accepts optional `labels?: Record` - Helper methods: `setLabel(key, value)`, `getLabel(key)`, `removeLabel(key)`, `hasLabel(key, value?)` - `getMetadata()` includes `labels` (shallow copy) - `TaskManager.getTasksByLabel(key, value)` returns matching `Task[]` - `TaskManager.getTasksMetadataByLabel(key, value)` returns matching `ITaskMetadata[]` ## Push-Based Events (v4.1.0+) - `Task.eventSubject`: rxjs `Subject` emitting `'started'`, `'step'`, `'completed'`, `'failed'` events - `TaskManager.taskSubject`: aggregated `Subject` from all added tasks - `TaskManager.removeTask(task)` unsubscribes and removes from map - `TaskManager.stop()` cleans up all event subscriptions - Exported types: `ITaskEvent`, `TTaskEventType` ## Project Structure - Source in `ts/`, web components in `ts_web/` - Tests in `test/` - naming: `*.node.ts`, `*.chromium.ts` (preferred), `*.both.ts` - Note: `*.browser.ts` is deprecated, use `*.chromium.ts` for browser tests - Logger: `ts/taskbuffer.logging.ts` exports `logger` (ConsoleLog from smartlog) - Build: `pnpm build` (tsbuild tsfolders) - Test: `pnpm test` or `tstest test/test.XX.name.ts --verbose` ## Web Components (ts_web/) - Uses `@design.estate/dees-element` with TC39 decorators - Decorators require the `accessor` keyword: ```typescript @property({ type: String }) accessor myProp = 'default'; @state() accessor count = 0; ``` ## Dependencies (as of v4.2.0) - `@design.estate/dees-element` ^2.1.6 - TC39 decorators with `accessor` keyword - `@push.rocks/lik` ^6.2.2 - Data structures - `@push.rocks/smartdelay` ^3.0.5 - Delay utilities - `@push.rocks/smartlog` ^3.1.11 - Logging - `@push.rocks/smartpromise` ^4.2.3 - Promise utilities - `@push.rocks/smartrx` ^3.0.10 - RxJS wrapper - `@push.rocks/smarttime` ^4.1.1 - Time/cron utilities - `@push.rocks/smartunique` ^3.0.9 - Unique ID generation - `@git.zone/tsbuild` ^4.1.2 - Build tool - `@git.zone/tsbundle` ^2.8.3 - Bundler (for browser tests) - `@git.zone/tsrun` ^2.0.1 - TypeScript runner - `@git.zone/tstest` ^3.1.8 - Test runner (supports `.chromium.ts` files) - `@types/node` ^25.2.3 - Node.js type definitions