# 🚀 ThreadTS Universal

[![npm version](https://badge.fury.io/js/threadts-universal.svg)](https://badge.fury.io/js/threadts-universal)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.4+-blue.svg)](https://www.typescriptlang.org/)
[![🚀 CI/CD Pipeline](https://github.com/JosunLP/ThreadTS-Universal/actions/workflows/ci-cd.yml/badge.svg)](https://github.com/JosunLP/ThreadTS-Universal/actions/workflows/ci-cd.yml)
[![CodeQL](https://github.com/JosunLP/ThreadTS-Universal/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/JosunLP/ThreadTS-Universal/actions/workflows/github-code-scanning/codeql)

**The definitive universal TypeScript library that makes true parallelism as effortless as async/await across all JavaScript ecosystems.**

```typescript
import threadts from 'threadts-universal';

// Transform any function into parallel execution with one line
const result = await threadts.run((x) => x * 2, 42);
console.log(result); // 84

// Full Array API support with parallel execution
const found = await threadts.find([1, 2, 3, 4, 5], (x) => x > 3);
console.log(found); // 4
```

## ✨ Features

### 🎯 **One-Command Paradigm**

- **Single-line API**: `await threadts.run(fn, data)` → instant parallel execution
- **Zero-Config**: Intelligent defaults with infinite customization layers
- **Quantum Performance**: Sub-5ms overhead vs handwritten worker wrappers

### 🌍 **Universal Compatibility**

- **Browser**: Web Workers, OffscreenCanvas, Transferable Objects
- **Node.js**: Worker Threads, Cluster Mode, Native Addons
- **Deno**: Web Workers with permissions sandboxing
- **Bun**: Optimized worker implementation
- **Identical API**: Same code works everywhere

### ⚡ **Advanced Features**

- **Auto-scaling Pools**: From 1 to ∞ workers based on load
- **Full Array API**: `map`, `filter`, `reduce`, `reduceRight`, `find`, `findIndex`, `some`, `every`, `forEach`, `flatMap`, `groupBy`, `partition`, `count`, `indexOf`, `lastIndexOf`, `at`, `slice`, `concat`, `range`, `repeat`, `unique`, `uniqueBy`, `chunk`, `zip`
- **ES2023+ Immutable Methods**: `findLast`, `findLastIndex`, `toSorted`, `toReversed`, `withElement`, `toSpliced`, `groupByObject` - all methods that don't mutate the original array
- **Enhanced Pipeline API**: Fluent chaining with lazy evaluation
  - Intermediate: `map`, `filter`, `flatMap`, `take`, `skip`, `chunk`, `tap`, `peek`, `window`, `unique`, `distinct`, `reverse`, `sort`, `zip`, `zipWith`, `interleave`, `compact`, `flatten`, `shuffle`, `sample`, `dropWhile`, `takeWhile`, `slicePipe`, `concatPipe`, `rotate`, `truthy`, `falsy`
  - Terminal: `reduce`, `forEach`, `find`, `findIndex`, `findLast`, `findLastIndex`, `some`, `every`, `count`, `groupBy`, `partition`, `first`, `last`, `isEmpty`, `sum`, `average`, `min`, `max`, `join`, `includes`
  - Collectors: `toArray()`, `toSet()`, `toMap()`
- **Progress Tracking**: Real-time progress monitoring
- **Intelligent Caching**: Automatic result caching with `@memoize` and `@cache` decorators
- **Priority Queues**: High/Normal/Low priority execution
- **Timeout & Cancellation**: AbortController integration
- **Decorator Suite**: `@parallelMethod()`, `@retry()`, `@rateLimit()`, `@timeout()`, `@debounce()`, `@throttle()`, `@logged()`, `@cache()`, `@concurrent()`, `@circuitBreaker()`, `@measure()`, `@validate()`, `@lazy()`
- **Custom Decorators**: Utilities for creating your own decorators (`createMethodDecorator`, `createMethodDecoratorWithClass`, `createClassDecorator`)
- **Monitoring**: Built-in performance monitoring, health checks, and error handling

## 🚀 Quick Start

### Installation

```bash
bun add threadts-universal
```

```bash
# alternativ mit npm
npm install threadts-universal
```

### Basic Usage

```typescript
import threadts from 'threadts-universal';

// Simple parallel execution
const doubled = await threadts.run((x) => x * 2, 21);

// Complex calculations
const fibonacci = await threadts.run((n) => {
  if (n <= 1) return n;
  let a = 0,
    b = 1;
  for (let i = 2; i <= n; i++) {
    [a, b] = [b, a + b];
  }
  return b;
}, 40);

// Parallel array processing
const squares = await threadts.map([1, 2, 3, 4, 5], (x) => x * x);
// Result: [1, 4, 9, 16, 25]

// Find elements in parallel
const firstMatch = await threadts.find([1, 2, 3, 4, 5], (x) => x > 3);
// Result: 4

// Check conditions across array
const hasEven = await threadts.some([1, 3, 5, 6], (x) => x % 2 === 0);
// Result: true

// Group and partition data
const [evens, odds] = await threadts.partition(
  [1, 2, 3, 4, 5],
  (x) => x % 2 === 0
);
// evens: [2, 4], odds: [1, 3, 5]

// Pipeline API for chained operations
const result = await threadts
  .pipe([1, 2, 3, 4, 5])
  .map((x) => x * 2)
  .filter((x) => x > 4)
  .reduce((acc, x) => acc + x, 0)
  .execute();
// Result: 24
```

### Method Decorators

```typescript
import {
  parallelMethod,
  memoize,
  retry,
  rateLimit,
  timeout,
  debounce,
} from 'threadts-universal';

class DataProcessor {
  @parallelMethod()
  async processLargeDataset(data: number[]): Promise<number[]> {
    return data.map((x) => x * x * x);
  }

  @parallelMethod({ timeout: 5000, priority: 'high' })
  async criticalCalculation(input: ComplexData): Promise<Result> {
    // Heavy computation automatically runs in worker
    return heavyProcessing(input);
  }

  @memoize(100) // Cache up to 100 results
  async expensiveComputation(input: string): Promise<Result> {
    return computeResult(input);
  }

  @retry(3, 1000) // 3 attempts with exponential backoff
  async unreliableOperation(): Promise<void> {
    await callExternalService();
  }

  @rateLimit(10) // Max 10 calls per second
  async rateLimitedAPI(): Promise<Data> {
    return fetchFromAPI();
  }
}
```

## 📚 API Reference

### Core Methods

#### `threadts.run<T>(fn, data?, options?): Promise<T>`

Executes a function in a worker thread.

```typescript
const result = await threadts.run(
  (data: { x: number; y: number }) => data.x + data.y,
  { x: 10, y: 20 },
  {
    timeout: 5000,
    priority: 'high',
    transferable: [], // For transferable objects
  }
);
```

#### `threadts.parallel<T>(tasks): Promise<T[]>`

Executes multiple functions in parallel.

```typescript
const results = await threadts.parallel([
  { fn: (x) => x * 2, data: 5 },
  { fn: (x) => x * 3, data: 7 },
  { fn: (x) => x * 4, data: 9 },
]);
// Results: [10, 21, 36]
```

#### `threadts.map<T, R>(array, fn, options?): Promise<R[]>`

Maps an array through a function in parallel.

```typescript
const results = await threadts.map(
  [1, 2, 3, 4, 5],
  (x, index) => ({ value: x * x, index }),
  { batchSize: 2 }
);
```

#### `threadts.filter<T>(array, fn, options?): Promise<T[]>`

Filters an array in parallel.

```typescript
const evens = await threadts.filter(
  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
  (x) => x % 2 === 0
);
```

#### `threadts.reduce<T, R>(array, fn, initialValue, options?): Promise<R>`

Reduces an array in parallel (for associative operations).

```typescript
const sum = await threadts.reduce(
  [1, 2, 3, 4, 5],
  (acc, curr) => acc + curr,
  0
);
```

#### `threadts.reduceRight<T, R>(array, fn, initialValue, options?): Promise<R>`

Reduces an array from right to left.

```typescript
const result = await threadts.reduceRight(
  ['a', 'b', 'c'],
  (acc, item) => acc + item,
  ''
);
// Result: 'cba'
```

#### `threadts.find<T>(array, predicate, options?): Promise<T | undefined>`

Finds the first element that satisfies the predicate (processes in parallel batches).

```typescript
const found = await threadts.find([1, 2, 3, 4, 5], (x) => x > 3);
// Result: 4
```

#### `threadts.findIndex<T>(array, predicate, options?): Promise<number>`

Finds the index of the first element that satisfies the predicate.

```typescript
const index = await threadts.findIndex([1, 2, 3, 4, 5], (x) => x > 3);
// Result: 3
```

#### `threadts.some<T>(array, predicate, options?): Promise<boolean>`

Tests whether at least one element satisfies the predicate.

```typescript
const hasEven = await threadts.some([1, 3, 5, 6, 7], (x) => x % 2 === 0);
// Result: true
```

#### `threadts.every<T>(array, predicate, options?): Promise<boolean>`

Tests whether all elements satisfy the predicate.

```typescript
const allPositive = await threadts.every([1, 2, 3, 4, 5], (x) => x > 0);
// Result: true
```

#### `threadts.forEach<T>(array, fn, options?): Promise<void>`

Iterates over an array in parallel (like Array.forEach but parallel).

```typescript
await threadts.forEach([1, 2, 3], (x) => {
  console.log(x);
});
```

#### `threadts.flatMap<T, R>(array, fn, options?): Promise<R[]>`

Maps each element to an array and flattens the result.

```typescript
const result = await threadts.flatMap([1, 2, 3], (x) => [x, x * 2]);
// Result: [1, 2, 2, 4, 3, 6]
```

#### `threadts.groupBy<T, K>(array, keyFn, options?): Promise<Map<K, T[]>>`

Groups array elements by a key returned from the function.

```typescript
const grouped = await threadts.groupBy(
  [
    { type: 'a', value: 1 },
    { type: 'b', value: 2 },
    { type: 'a', value: 3 },
  ],
  (item) => item.type
);
// Map { 'a' => [{type: 'a', value: 1}, {type: 'a', value: 3}], 'b' => [{type: 'b', value: 2}] }
```

#### `threadts.partition<T>(array, predicate, options?): Promise<[T[], T[]]>`

Partitions an array into two arrays based on a predicate.

```typescript
const [evens, odds] = await threadts.partition(
  [1, 2, 3, 4, 5],
  (x) => x % 2 === 0
);
// evens: [2, 4], odds: [1, 3, 5]
```

#### `threadts.count<T>(array, predicate, options?): Promise<number>`

Counts elements that satisfy a predicate. More efficient than `filter().length`.

```typescript
const count = await threadts.count([1, 2, 3, 4, 5], (x) => x > 2);
// Result: 3
```

### Extended Array Operations

ThreadTS Universal provides a comprehensive set of array operations beyond the standard JavaScript Array API. These operations are optimized for parallel execution and can be accessed both as instance methods and through the `getArrayOps()` factory.

#### `threadts.indexOf<T>(array, searchElement, fromIndex?, options?): Promise<number>`

Finds the first index of an element in the array.

```typescript
const index = await threadts.indexOf([1, 2, 3, 2, 1], 2);
// Result: 1

const indexFrom = await threadts.indexOf([1, 2, 3, 2, 1], 2, 2);
// Result: 3
```

#### `threadts.lastIndexOf<T>(array, searchElement, fromIndex?, options?): Promise<number>`

Finds the last index of an element in the array.

```typescript
const index = await threadts.lastIndexOf([1, 2, 3, 2, 1], 2);
// Result: 3
```

#### `threadts.at<T>(array, index, options?): Promise<T | undefined>`

Returns the element at the specified index, supporting negative indices.

```typescript
const last = await threadts.at([1, 2, 3, 4, 5], -1);
// Result: 5

const second = await threadts.at([1, 2, 3, 4, 5], 1);
// Result: 2
```

#### `threadts.slice<T>(array, start?, end?, options?): Promise<T[]>`

Extracts a section of the array.

```typescript
const middle = await threadts.slice([1, 2, 3, 4, 5], 1, 4);
// Result: [2, 3, 4]

const fromEnd = await threadts.slice([1, 2, 3, 4, 5], -2);
// Result: [4, 5]
```

#### `threadts.concat<T>(array, ...items): Promise<T[]>`

Concatenates arrays or values.

```typescript
const combined = await threadts.concat([1, 2], [3, 4], 5);
// Result: [1, 2, 3, 4, 5]
```

#### `threadts.range(start, end, step?, options?): Promise<number[]>`

Generates an array of numbers in a specified range.

```typescript
const numbers = await threadts.range(0, 10, 2);
// Result: [0, 2, 4, 6, 8]

const countdown = await threadts.range(5, 0, -1);
// Result: [5, 4, 3, 2, 1]
```

#### `threadts.repeat<T>(value, count, options?): Promise<T[]>`

Creates an array with the value repeated n times.

```typescript
const repeated = await threadts.repeat('x', 5);
// Result: ['x', 'x', 'x', 'x', 'x']
```

#### `threadts.unique<T>(array, options?): Promise<T[]>`

Returns an array with duplicate values removed.

```typescript
const unique = await threadts.unique([1, 2, 2, 3, 3, 3]);
// Result: [1, 2, 3]
```

#### `threadts.uniqueBy<T, K>(array, keyFn, options?): Promise<T[]>`

Returns unique elements based on a key function.

```typescript
const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 1, name: 'Alice Clone' },
];
const uniqueById = await threadts.uniqueBy(users, (u) => u.id);
// Result: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
```

#### `threadts.chunk<T>(array, size, options?): Promise<T[][]>`

Splits an array into chunks of the specified size.

```typescript
const chunks = await threadts.chunk([1, 2, 3, 4, 5], 2);
// Result: [[1, 2], [3, 4], [5]]
```

#### `threadts.zip<T, U>(array1, array2, options?): Promise<[T, U][]>`

Combines two arrays element-wise into pairs.

```typescript
const zipped = await threadts.zip(['a', 'b', 'c'], [1, 2, 3]);
// Result: [['a', 1], ['b', 2], ['c', 3]]
```

### ES2023+ Immutable Array Methods

ThreadTS Universal provides full support for ES2023+ immutable array methods. These methods return new arrays instead of mutating the original, making them ideal for functional programming patterns.

#### `threadts.findLast<T>(array, predicate, options?): Promise<T | undefined>`

Finds the **last** element that satisfies the predicate (searches from end).

```typescript
const result = await threadts.findLast([1, 2, 3, 4, 5], (x) => x < 4);
// Result: 3 (the last number less than 4)

const noMatch = await threadts.findLast([1, 2, 3], (x) => x > 10);
// Result: undefined
```

#### `threadts.findLastIndex<T>(array, predicate, options?): Promise<number>`

Finds the index of the **last** element that satisfies the predicate.

```typescript
const index = await threadts.findLastIndex([1, 2, 3, 2, 1], (x) => x === 2);
// Result: 3 (the last occurrence of 2)

const notFound = await threadts.findLastIndex([1, 2, 3], (x) => x > 10);
// Result: -1
```

#### `threadts.toSorted<T>(array, compareFn?, options?): Promise<T[]>`

Returns a **new sorted array** without mutating the original.

```typescript
const original = [3, 1, 4, 1, 5];
const sorted = await threadts.toSorted(original);
// sorted: [1, 1, 3, 4, 5]
// original: [3, 1, 4, 1, 5] (unchanged!)

// With custom comparator (descending)
const descending = await threadts.toSorted([3, 1, 4], (a, b) => b - a);
// Result: [4, 3, 1]
```

#### `threadts.toReversed<T>(array, options?): Promise<T[]>`

Returns a **new reversed array** without mutating the original.

```typescript
const original = [1, 2, 3];
const reversed = await threadts.toReversed(original);
// reversed: [3, 2, 1]
// original: [1, 2, 3] (unchanged!)
```

#### `threadts.withElement<T>(array, index, value, options?): Promise<T[]>`

Returns a **new array** with the element at the given index replaced.

```typescript
const original = [1, 2, 3];
const updated = await threadts.withElement(original, 1, 10);
// updated: [1, 10, 3]
// original: [1, 2, 3] (unchanged!)

// Supports negative indices
const lastReplaced = await threadts.withElement([1, 2, 3], -1, 99);
// Result: [1, 2, 99]
```

#### `threadts.toSpliced<T>(array, start, deleteCount?, ...items): Promise<T[]>`

Returns a **new array** with elements removed, replaced, or added at a given index.

```typescript
const original = [1, 2, 3, 4];

// Remove and insert
const spliced = await threadts.toSpliced(original, 1, 2, 10, 20);
// spliced: [1, 10, 20, 4]
// original: [1, 2, 3, 4] (unchanged!)

// Delete only
const deleted = await threadts.toSpliced([1, 2, 3, 4], 1, 2);
// Result: [1, 4]

// Insert only
const inserted = await threadts.toSpliced([1, 2, 3], 1, 0, 99);
// Result: [1, 99, 2, 3]
```

#### `threadts.groupByObject<T, K>(array, keyFn, options?): Promise<Partial<Record<K, T[]>>>`

Groups elements into a plain object based on a key function (similar to `Object.groupBy`).

```typescript
const items = [
  { type: 'fruit', name: 'apple' },
  { type: 'vegetable', name: 'carrot' },
  { type: 'fruit', name: 'banana' },
];
const grouped = await threadts.groupByObject(items, (item) => item.type);
// Result: {
//   fruit: [{ type: 'fruit', name: 'apple' }, { type: 'fruit', name: 'banana' }],
//   vegetable: [{ type: 'vegetable', name: 'carrot' }]
// }
```

#### Using the Array Operations Factory

For advanced use cases, you can access all array operations through the factory:

```typescript
// Get array operations bound to the current ThreadTS instance
const arrayOps = threadts.getArrayOps();

// Use operations directly
const index = await arrayOps.indexOf([1, 2, 3], 2);
const unique = await arrayOps.unique([1, 1, 2, 2, 3]);
const chunks = await arrayOps.chunk([1, 2, 3, 4, 5, 6], 2);

// ES2023+ operations
const sorted = await arrayOps.toSorted([3, 1, 2]);
const reversed = await arrayOps.toReversed([1, 2, 3]);
const lastMatch = await arrayOps.findLast([1, 2, 3, 2], (x) => x === 2);

// Available operations:
// indexOf, lastIndexOf, at, slice, concat, fill, includes, join,
// reverse, sort, range, repeat, zip, unzip, unique, uniqueBy, flat, chunk,
// findLast, findLastIndex, toSorted, toReversed, withElement, toSpliced, groupByObject
```

#### `threadts.batch(tasks, batchSize?): Promise<TaskResult[]>`

Executes multiple tasks as a batch with configurable batch size.

```typescript
const results = await threadts.batch(
  [
    { fn: (x) => x * 2, data: 5 },
    { fn: (x) => x + 1, data: 10 },
  ],
  2 // Process 2 tasks at a time
);
```

### Pipeline API

The Pipeline API provides a fluent interface for chaining parallel operations with lazy evaluation.

```typescript
// Chain multiple operations
const result = await threadts
  .pipe([1, 2, 3, 4, 5])
  .map((x) => x * 2)
  .filter((x) => x > 4)
  .reduce((acc, x) => acc + x, 0)
  .execute();
// Result: 24 (6 + 8 + 10)

// Using flatMap in pipeline
const flattened = await threadts
  .pipe([1, 2, 3])
  .flatMap((x) => [x, x * 10])
  .filter((x) => x > 5)
  .toArray();
// Result: [10, 20, 30]

// Terminal operations: reduce, forEach, find, some, every, count
const hasLarge = await threadts
  .pipe([1, 2, 3, 4, 5])
  .map((x) => x * 2)
  .some((x) => x > 8)
  .execute();
// Result: true

// Using take, skip, and chunk
const paginated = await threadts
  .pipe([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  .skip(2)
  .take(5)
  .execute();
// Result: [3, 4, 5, 6, 7]

const chunks = await threadts.pipe([1, 2, 3, 4, 5]).chunk(2).execute();
// Result: [[1, 2], [3, 4], [5]]

// Using tap for debugging/side-effects
const result = await threadts
  .pipe([1, 2, 3])
  .tap((x) => console.log('Processing:', x))
  .map((x) => x * 2)
  .execute();
// Logs: Processing: 1, Processing: 2, Processing: 3
// Result: [2, 4, 6]

// Using window for sliding windows
const windows = await threadts.pipe([1, 2, 3, 4, 5]).window(3).execute();
// Result: [[1, 2, 3], [2, 3, 4], [3, 4, 5]]

const windowsWithStep = await threadts
  .pipe([1, 2, 3, 4, 5, 6])
  .window(2, 2) // size=2, step=2
  .execute();
// Result: [[1, 2], [3, 4], [5, 6]]

// Using unique, reverse, and sort
const processed = await threadts
  .pipe([3, 1, 2, 1, 3])
  .unique()
  .sort((a, b) => a - b)
  .execute();
// Result: [1, 2, 3]

// Aggregation operations
const sum = await threadts.pipe([1, 2, 3, 4, 5]).sum().execute();
// Result: 15

const avg = await threadts.pipe([1, 2, 3, 4, 5]).average().execute();
// Result: 3

const max = await threadts.pipe([3, 1, 4, 1, 5]).max().execute();
// Result: 5

// First and last elements
const first = await threadts
  .pipe([1, 2, 3])
  .filter((x) => x > 1)
  .first()
  .execute();
// Result: 2

// Collect to different data structures
const set = await threadts.pipe([1, 2, 2, 3]).toSet();
// Result: Set { 1, 2, 3 }

const map = await threadts.pipe(users).toMap((user) => user.id);
// Result: Map { id1 => user1, id2 => user2, ... }

// GroupBy and Partition in pipeline
const grouped = await threadts
  .pipe(users)
  .groupBy((user) => user.role)
  .execute();
// Result: Map { 'admin' => [...], 'user' => [...] }

const [admins, regular] = await threadts
  .pipe(users)
  .partition((user) => user.role === 'admin')
  .execute();
```

#### New Pipeline Operations (v2.1.0+)

```typescript
// Distinct - remove duplicates by key
const items = [{ id: 1 }, { id: 2 }, { id: 1 }, { id: 3 }];
const uniqueById = await threadts
  .pipe(items)
  .distinct((item) => item.id)
  .execute();
// Result: [{ id: 1 }, { id: 2 }, { id: 3 }]

// Zip - combine two arrays element-wise
const names = ['Alice', 'Bob', 'Charlie'];
const ages = [25, 30, 35];
const zipped = await threadts.pipe(names).zip(ages).execute();
// Result: [['Alice', 25], ['Bob', 30], ['Charlie', 35]]

// ZipWith - combine with a custom function
const combined = await threadts
  .pipe(names)
  .zipWith(ages, (name, age) => `${name} is ${age}`)
  .execute();
// Result: ['Alice is 25', 'Bob is 30', 'Charlie is 35']

// Interleave - alternate elements from two arrays
const letters = ['a', 'b', 'c'];
const numbers = [1, 2, 3];
const interleaved = await threadts.pipe(letters).interleave(numbers).execute();
// Result: ['a', 1, 'b', 2, 'c', 3]

// Compact - remove null and undefined values
const sparse = [1, null, 2, undefined, 3];
const compacted = await threadts.pipe(sparse).compact().execute();
// Result: [1, 2, 3]

// Flatten - flatten nested arrays
const nested = [[1, 2], [3, 4], [5]];
const flattened = await threadts.pipe(nested).flatten().execute();
// Result: [1, 2, 3, 4, 5]

const deepNested = [[[1]], [[2]], [[3]]];
const deepFlattened = await threadts.pipe(deepNested).flatten(2).execute();
// Result: [1, 2, 3]

// Shuffle - randomly shuffle elements
const ordered = [1, 2, 3, 4, 5];
const shuffled = await threadts.pipe(ordered).shuffle().execute();
// Result: [3, 1, 5, 2, 4] (random order)

// Sample - get random sample of n elements
const sampled = await threadts.pipe(ordered).sample(3).execute();
// Result: [2, 4, 1] (3 random elements)

// DropWhile - drop elements while predicate is true
const sequence = [1, 2, 3, 10, 4, 5];
const dropped = await threadts
  .pipe(sequence)
  .dropWhile((x) => x < 5)
  .execute();
// Result: [10, 4, 5]

// TakeWhile - take elements while predicate is true
const taken = await threadts
  .pipe(sequence)
  .takeWhile((x) => x < 5)
  .execute();
// Result: [1, 2, 3]

// Peek - debug helper (alias for tap)
const peeked = await threadts
  .pipe([1, 2, 3])
  .peek((x) => console.log('Value:', x))
  .map((x) => x * 2)
  .execute();
// Logs: Value: 1, Value: 2, Value: 3
// Result: [2, 4, 6]

// Join - join elements into string (terminal)
const sentence = await threadts.pipe(['Hello', 'World']).join(' ').execute();
// Result: 'Hello World'

// Includes - check if element exists (terminal)
const hasThree = await threadts.pipe([1, 2, 3, 4]).includes(3).execute();
// Result: true

// SlicePipe - extract a portion of the array
const sliced = await threadts.pipe([1, 2, 3, 4, 5]).slicePipe(1, 4).execute();
// Result: [2, 3, 4]

// ConcatPipe - concatenate with another array
const concatenated = await threadts
  .pipe([1, 2])
  .concatPipe([3, 4, 5])
  .execute();
// Result: [1, 2, 3, 4, 5]

// Rotate - rotate array elements by n positions
const rotatedRight = await threadts.pipe([1, 2, 3, 4, 5]).rotate(2).execute();
// Result: [4, 5, 1, 2, 3]

const rotatedLeft = await threadts.pipe([1, 2, 3, 4, 5]).rotate(-2).execute();
// Result: [3, 4, 5, 1, 2]

// Truthy - filter to only truthy values
const truthyOnly = await threadts
  .pipe([0, 1, '', 'hello', null, true, false])
  .truthy()
  .execute();
// Result: [1, 'hello', true]

// Falsy - filter to only falsy values
const falsyOnly = await threadts
  .pipe([0, 1, '', 'hello', null, true, false])
  .falsy()
  .execute();
// Result: [0, '', null, false]
```

### Advanced Features

#### Progress Tracking

```typescript
const result = await threadts.execute((data) => {
  // Emit progress updates
  for (let i = 0; i < 100; i++) {
    postMessage({ progress: i, message: `Processing ${i}%` });
    // Heavy work here
  }
  return finalResult;
}, inputData);
```

#### Transferable Objects

```typescript
const buffer = new ArrayBuffer(1024 * 1024);
const result = await threadts.run(
  (buffer) => {
    // Process buffer in worker
    const view = new Uint8Array(buffer);
    // ... processing
    return processedData;
  },
  buffer,
  { transferable: [buffer] }
);
```

#### Pool Management

```typescript
// Resize worker pool
await threadts.resize(8);

// Get pool statistics
const stats = threadts.getStats();
console.log(stats);
// {
//   activeWorkers: 2,
//   idleWorkers: 6,
//   queuedTasks: 0,
//   completedTasks: 150,
//   averageExecutionTime: 45.2
// }

// Get/Update configuration
const config = threadts.getConfig();
threadts.updateConfig({ timeout: 10000, debug: true });

// Check platform and support
console.log(threadts.getPlatform()); // 'node', 'browser', 'deno', 'bun'
console.log(threadts.isSupported()); // true if workers are supported

// Cleanup
await threadts.terminate(); // Terminate instance
await ThreadTS.terminateAll(); // Terminate all instances
```

### Decorators

#### `@parallelMethod(options?)`

Automatically parallelizes method execution.

```typescript
import { parallelMethod } from 'threadts-universal';

class ImageProcessor {
  @parallelMethod({ cacheResults: true, timeout: 5000 })
  async applyFilter(imageData: ImageData, filter: Filter): Promise<ImageData> {
    // Automatically runs in worker thread
    return processImage(imageData, filter);
  }
}
```

**Options:**

- `timeout`: Maximum execution time in milliseconds
- `priority`: Execution priority ('low', 'normal', 'high')
- `maxRetries`: Number of retry attempts on failure
- `poolSize`: Custom worker pool size
- `cacheResults`: Enable result caching

#### `@memoize(maxCacheSize?)`

Caches method results with LRU eviction policy.

```typescript
@memoize(100) // Cache up to 100 unique results
async expensiveComputation(input: string): Promise<Result> {
  return computeResult(input);
}
```

#### `@retry(maxAttempts?, baseDelay?)`

Retry logic with exponential backoff.

```typescript
@retry(3, 1000) // 3 attempts, starting with 1s delay
async unreliableOperation(): Promise<void> {
  await callExternalService();
}
```

#### `@rateLimit(callsPerSecond?)`

Limits method call frequency.

```typescript
@rateLimit(10) // Max 10 calls per second
async apiCall(): Promise<Data> {
  return fetchFromAPI();
}
```

#### `@timeout(ms?)`

Automatically rejects if execution exceeds the specified timeout.

```typescript
@timeout(5000) // Reject after 5 seconds
async longRunningTask(): Promise<Result> {
  return performTask();
}
```

#### `@debounce(ms?)`

Delays execution until no calls have been made for the specified duration.

```typescript
@debounce(300) // Wait 300ms after last call
async handleInput(value: string): Promise<void> {
  await saveToServer(value);
}
```

#### `@throttle(ms?)`

Ensures the method is called at most once per specified interval.

```typescript
@throttle(1000) // At most once per second
async trackEvent(event: Event): Promise<void> {
  await sendAnalytics(event);
}
```

#### `@logged(options?)`

Logs method calls, arguments, results, and execution time.

```typescript
@logged({ logArgs: true, logResult: true })
async processData(data: Data): Promise<Result> {
  return transform(data);
}
// Logs: [ClassName.processData] Starting with args: [...]
// Logs: [ClassName.processData] Completed in 45ms. Result: {...}
```

#### `@parallelBatch(batchSize?)`

Processes array data in parallel batches.

```typescript
@parallelBatch(4)
async processBatch(items: Item[]): Promise<Result[]> {
  return items.map(processItem);
}
```

#### `@parallelMap()`

Parallel map operation on array input.

```typescript
@parallelMap()
async processItems(items: Item[]): Promise<Result[]> {
  return items.map(transform);
}
```

#### Decorator Summary

```typescript
// Parallelization
@parallelMethod() // Parallelize method execution
@parallelBatch(4) // Process arrays in batches of 4
@parallelMap() // Parallel map over array

// Caching
@memoize(100) // LRU cache with 100 entries
@cache(60000, 50) // TTL cache: 60s expiry, max 50 entries

// Reliability
@retry(3, 1000) // Retry up to 3 times with exponential backoff
@timeout(5000) // Timeout after 5 seconds
@circuitBreaker({ failureThreshold: 5, resetTimeout: 30000 }) // Circuit breaker pattern

// Rate Control
@rateLimit(10) // Max 10 calls per second
@debounce(300) // Debounce with 300ms delay
@throttle(1000) // Throttle to once per second
@concurrent(3) // Limit to 3 concurrent executions

// Observability
@logged() // Log execution details
@measure() // Collect timing statistics

// Validation & Initialization
@validate([...validators]) // Validate arguments
@lazy() // Lazy initialization (execute only once)
```

#### `@cache(ttlMs?, maxSize?)`

Caches method results with TTL (Time To Live) support.

```typescript
@cache(30000, 50) // Cache for 30 seconds, max 50 entries
async fetchData(id: string): Promise<Data> {
  return await api.getData(id);
}
// Clear cache: this.fetchData.clearCache()
```

#### `@concurrent(maxConcurrent?)`

Limits concurrent executions of a method.

```typescript
@concurrent(3) // Max 3 concurrent executions
async processFile(path: string): Promise<void> {
  await heavyFileOperation(path);
}
```

#### `@circuitBreaker(options?)`

Implements the circuit breaker pattern for fault tolerance.

```typescript
@circuitBreaker({
  failureThreshold: 5,  // Open circuit after 5 failures
  resetTimeout: 30000,  // Try again after 30 seconds
  halfOpenRequests: 1   // Allow 1 test request in half-open state
})
async callExternalApi(): Promise<Data> {
  return await externalApi.getData();
}
// Check state: this.callExternalApi.getState()
// Reset: this.callExternalApi.reset()
```

#### `@measure()`

Collects timing statistics across multiple calls.

```typescript
@measure()
async compute(data: number[]): Promise<number> {
  return data.reduce((a, b) => a + b, 0);
}
// Get stats: this.compute.getStats()
// Returns: { count, min, max, avg, median, p95, p99 }
```

#### `@validate(validators)`

Validates method arguments before execution.

```typescript
@validate([
  (id) => typeof id === 'string' && id.length > 0,
  (data) => data && typeof data.name === 'string'
])
async updateUser(id: string, data: UserData): Promise<void> {
  await api.updateUser(id, data);
}
```

#### `@lazy()`

Lazy initialization - method executes only once.

```typescript
@lazy()
async loadConfig(): Promise<Config> {
  return await fetchConfig(); // Only called once, result cached forever
}
// Reset: this.loadConfig.reset()
```

### Creating Custom Decorators

ThreadTS provides utility functions for creating your own decorators that work with both legacy (`experimentalDecorators`) and Stage-3 decorator syntax:

```typescript
import {
  createMethodDecorator,
  createMethodDecoratorWithClass,
  createClassDecorator,
  isAsyncFunction,
  ensureAsync,
} from 'threadts-universal';

// Simple method decorator
function logExecution() {
  return createMethodDecorator((originalMethod, methodName) => {
    return async function (...args: unknown[]) {
      console.log(`Calling ${methodName}`);
      const result = await originalMethod.apply(this, args);
      console.log(`${methodName} returned:`, result);
      return result;
    } as typeof originalMethod;
  });
}

// Decorator with class name for observability
function auditLog() {
  return createMethodDecoratorWithClass((method, methodName, className) => {
    return async function (...args: unknown[]) {
      console.log(`[${className}.${methodName}] called with:`, args);
      return method.apply(this, args);
    } as typeof method;
  });
}

// Class decorator
function singleton() {
  const instances = new Map();
  return createClassDecorator((OriginalClass, className) => {
    return class extends OriginalClass {
      constructor(...args: unknown[]) {
        if (instances.has(className)) {
          return instances.get(className);
        }
        super(...args);
        instances.set(className, this);
      }
    } as typeof OriginalClass;
  });
}

// Usage
class MyService {
  @logExecution()
  async process(data: string): Promise<string> {
    return data.toUpperCase();
  }

  @auditLog()
  async save(item: Item): Promise<void> {
    // Logs: [MyService.save] called with: [...]
    await db.save(item);
  }
}
```

### Event System

```typescript
// Listen to task completion events
threadts.on('task-complete', ({ taskId, result, duration }) => {
  console.log(`Task ${taskId} completed in ${duration}ms`);
});

// Listen to task errors
threadts.on('task-error', ({ taskId, error, duration }) => {
  console.error(`Task ${taskId} failed: ${error}`);
});

// Listen to pool resize events
threadts.on('pool-resize', ({ oldSize, newSize }) => {
  console.log(`Pool resized from ${oldSize} to ${newSize}`);
});

// Remove event listener
threadts.off('task-complete', listener);
```

### Monitoring & Diagnostics

```typescript
import {
  PerformanceMonitor,
  HealthMonitor,
  ErrorHandler,
} from 'threadts-universal';

// Performance Monitoring
const perfMonitor = new PerformanceMonitor();
perfMonitor.startMonitoring(2000); // Check every 2 seconds
const metrics = perfMonitor.collectMetrics();

// Health Monitoring
const healthMonitor = new HealthMonitor();
healthMonitor.startHealthMonitoring(5000); // Check every 5 seconds
const health = await healthMonitor.performHealthCheck();
console.log(health.overall); // 'healthy', 'degraded', or 'unhealthy'

// Error Handling with auto-recovery
const errorHandler = new ErrorHandler();
const result = await errorHandler.executeWithRetry(
  'operation-name',
  async () => riskyOperation(),
  { platform: 'node', workerCount: 4 }
);
```

## 🌟 Platform-Specific Features

### Browser

- **OffscreenCanvas**: GPU-intensive graphics processing
- **Web Locks**: Worker coordination and synchronization
- **Transferable Objects**: Zero-copy operations
- **Safari Polyfills**: Automatic fallback detection

### Node.js

- **Worker Threads**: CPU-intensive task processing
- **Resource Limits**: Memory control per worker
- **Cluster Mode**: Multi-core utilization
- **Native Addons**: Performance optimization hooks

```typescript
// Node.js specific resource limits
const result = await threadts.run(heavyTask, data, {
  resourceLimits: {
    maxOldGenerationSizeMb: 128,
    maxYoungGenerationSizeMb: 64,
    codeRangeSizeMb: 16,
    stackSizeMb: 4,
  },
  workerName: 'heavy-worker',
  trackResources: true,
});
```

### Deno

- **Permission Sandboxing**: Secure worker execution
- **TypeScript Native**: Zero-config TypeScript support
- **Web Standards**: Modern web API compatibility

```typescript
// Deno specific permissions
const result = await threadts.run(task, data, {
  denoPermissions: {
    net: ['api.example.com'],
    read: ['/data'],
    env: true,
    hrtime: true,
  },
});
```

### Bun

- **Ultra-fast Startup**: Optimized worker creation
- **Native Performance**: Maximum speed execution
- **High Precision Timing**: Microsecond accuracy

```typescript
// Bun specific options
const result = await threadts.run(task, data, {
  bunOptions: {
    name: 'compute-worker',
    highPrecisionTiming: true,
    forceGC: true,
  },
});
```

## 📊 Performance

ThreadTS Universal provides quantum-level performance with sub-5ms overhead:

```typescript
// Benchmark: Fibonacci(40) calculation
const iterations = 1000;

// Sequential execution: ~2.3s
// ThreadTS parallel: ~0.6s (4 cores)
// Overhead: < 5ms per operation
```

### Performance Benchmarks

| Operation             | Data Size   | Time   | Throughput      |
| --------------------- | ----------- | ------ | --------------- |
| Image Processing      | 1920x1080   | ~50ms  | ~40k pixels/ms  |
| JSON Transformation   | 10k records | ~30ms  | ~300 records/ms |
| Cryptographic Hashing | 1k items    | ~15ms  | ~65 hashes/ms   |
| Array Map             | 100k items  | ~200ms | ~500k items/s   |

## 🔧 Configuration

### Pool Configuration

```typescript
import { ThreadTS } from 'threadts-universal';

const threadts = ThreadTS.getInstance({
  poolSize: 8, // Number of workers
  timeout: 30000, // Default timeout in ms
  retries: 2, // Default retry attempts
  autoResize: true, // Auto-scale pool
  debug: false, // Enable debug logging
  maxQueueSize: 1000, // Max queued tasks
  workerIdleTimeout: 60000, // Worker idle timeout
  taskPriority: 'normal', // Default priority
});
```

### Platform Detection

```typescript
import {
  detectPlatform,
  supportsWorkerThreads,
  getOptimalThreadCount,
  getMemoryInfo,
} from 'threadts-universal';

console.log('Platform:', detectPlatform()); // 'node', 'browser', 'deno', 'bun'
console.log('Worker Support:', supportsWorkerThreads());
console.log('Optimal Threads:', getOptimalThreadCount());
console.log('Memory:', getMemoryInfo());
```

## 🧪 Testing

```bash
# Run all tests
bun run test

# Browser tests
bun run test:browser

# Node.js tests
bun run test:node

# Performance benchmarks
bun run benchmark:all
```

## 🏗️ Project Architecture

ThreadTS Universal follows a modular, OOP-first architecture designed for maintainability and extensibility.

### Directory Structure

```text
src/
├── index.ts              # Main entry point (auto-detects platform)
├── browser.ts            # Browser-specific entry
├── node.ts               # Node.js-specific entry
├── types.ts              # TypeScript type definitions
│
├── core/
│   ├── threadts.ts       # Main ThreadTS class (singleton pattern)
│   ├── pipeline.ts       # Pipeline & TerminalPipeline classes
│   ├── pipeline-operations.ts  # Pipeline operation handlers
│   └── array-operations.ts     # Extended array operations factory
│
├── adapters/
│   ├── base.ts           # Abstract WorkerAdapter base class
│   ├── browser.ts        # Web Worker adapter
│   ├── node.ts           # Worker Threads adapter
│   ├── deno.ts           # Deno Worker adapter
│   └── bun.ts            # Bun Worker adapter
│
├── decorators/
│   ├── index.ts          # Re-exports all decorators
│   ├── parallel.ts       # @parallelMethod, @parallelClass, @parallelBatch, @parallelMap
│   ├── caching.ts        # @memoize, @cache, @lazy
│   ├── flow-control.ts   # @retry, @timeout, @rateLimit, @debounce, @throttle, @concurrent, @circuitBreaker
│   └── observability.ts  # @logged, @measure, @validate
│
├── monitoring/
│   ├── error-handler.ts  # Centralized error handling
│   ├── health.ts         # Health checks and diagnostics
│   └── performance.ts    # Performance monitoring
│
├── pool/
│   └── manager.ts        # Worker pool management
│
└── utils/
    ├── platform.ts       # Platform detection utilities
    ├── serialization.ts  # Data serialization helpers
    └── validation.ts     # Input validation utilities
```

### Decorator Modules

Decorators are organized by category for better maintainability:

| Module             | Decorators                                                                                     | Purpose                       |
| ------------------ | ---------------------------------------------------------------------------------------------- | ----------------------------- |
| `parallel.ts`      | `@parallelMethod`, `@parallelClass`, `@parallel`, `@parallelBatch`, `@parallelMap`             | Parallel execution            |
| `caching.ts`       | `@memoize`, `@cache`, `@lazy`                                                                  | Caching & memoization         |
| `flow-control.ts`  | `@retry`, `@timeout`, `@rateLimit`, `@debounce`, `@throttle`, `@concurrent`, `@circuitBreaker` | Flow control & resilience     |
| `observability.ts` | `@logged`, `@measure`, `@validate`                                                             | Logging, metrics & validation |

All decorators are re-exported from `decorators/index.ts` for convenient imports:

```typescript
// Import individual decorators
import { parallelMethod, memoize, retry, logged } from 'threadts-universal';

// Or import all from specific category
import { memoize, cache, lazy } from 'threadts-universal/decorators/caching';
```

### Core Classes

#### ThreadTS (Singleton)

The main class managing worker pools and task execution:

```typescript
// Always use getInstance() - ThreadTS is a singleton
const threadts = ThreadTS.getInstance({ poolSize: 4 });

// Methods are chainable where appropriate
await threadts.run(fn, data);
await threadts.map(array, fn);
await threadts.pipe(array).filter(fn).map(fn).execute();
```

#### Pipeline & TerminalPipeline

Fluent API for data processing with lazy evaluation:

```typescript
// Pipeline provides intermediate operations (lazy)
const pipeline = threadts
  .pipe(data)
  .filter((x) => x > 0) // Returns Pipeline
  .map((x) => x * 2) // Returns Pipeline
  .sort((a, b) => a - b); // Returns Pipeline

// Terminal operations execute the pipeline
const result = await pipeline.execute(); // Returns TerminalPipeline
const array = await pipeline.toArray(); // Executes and returns array
const sum = await pipeline.sum().execute(); // Aggregation
```

### Adapter Pattern

Platform-specific worker implementations extend the abstract `WorkerAdapter`:

```typescript
abstract class WorkerAdapter {
  abstract createWorker(taskFn: Function, data: unknown): void;
  abstract terminate(): Promise<void>;
  abstract postMessage(message: unknown): void;
  // ... common interface
}

// Platform adapters
class BrowserWorkerAdapter extends WorkerAdapter {
  /* Web Worker */
}
class NodeWorkerAdapter extends WorkerAdapter {
  /* Worker Threads */
}
class DenoWorkerAdapter extends WorkerAdapter {
  /* Deno Worker */
}
class BunWorkerAdapter extends WorkerAdapter {
  /* Bun Worker */
}
```

## 🤝 Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

### Development Setup

```bash
git clone https://github.com/JosunLP/ThreadTS-Universal.git
cd universal
bun install
bun run build
bun run test
```

## 📄 License

MIT License - see [LICENSE](LICENSE) file for details.

## 🌟 Why ThreadTS Universal?

### Before ThreadTS

```typescript
// Complex worker setup
const worker = new Worker('worker.js');
worker.postMessage(data);
worker.onmessage = (event) => {
  const result = event.data;
  // Handle result...
};
worker.onerror = (error) => {
  // Handle error...
};
```

### With ThreadTS

```typescript
// One line parallel execution
const result = await threadts.run(fn, data);

// Full Array API
const found = await threadts.find(array, predicate);
const all = await threadts.every(array, test);
const any = await threadts.some(array, test);
```

### The ThreadTS Advantage

- ✅ **Universal**: Same API across all platforms
- ✅ **Simple**: One-line parallel execution
- ✅ **Complete**: Full Array API (map, filter, reduce, find, some, every)
- ✅ **Fast**: Sub-5ms overhead
- ✅ **Smart**: Auto-scaling, caching, priorities
- ✅ **Safe**: Built-in error handling, retries, and timeouts
- ✅ **Observable**: Monitoring, health checks, and events
- ✅ **Modern**: TypeScript-first with full type safety

---

**Make parallel computing as simple as writing synchronous code. Experience the future of JavaScript parallelism with ThreadTS Universal.**

[![Star on GitHub](https://img.shields.io/github/stars/JosunLP/ThreadTS-Universal?style=social)](https://github.com/JosunLP/ThreadTS-Universal)
