Package Exports
- @osmium/iterate
- @osmium/iterate/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@osmium/iterate) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@osmium/iterate
A powerful, type-safe iteration library for JavaScript and TypeScript that provides unified iteration over various data types with advanced mapping, parallel processing, and control flow features.
โจ Features
- ๐ Universal Iteration - Iterate over arrays, objects, sets, maps, strings, numbers, and more
- โก Async/Sync Support - Full support for both synchronous and asynchronous operations
- ๐ Parallel Processing - Built-in parallel iteration with configurable limits
- ๐ฏ Type Safety - Full TypeScript support with advanced type inference
- ๐ ๏ธ Advanced Mapping - Transform data while iterating with various mapping strategies
- ๐ฎ Flow Control - Break, skip, repeat, and shift operations during iteration
- ๐ฆ Zero Dependencies - Lightweight and self-contained
- ๐งช Well Tested - 99.24% test coverage with 331+ tests
๐ฆ Installation
npm install @osmium/iterateyarn add @osmium/iteratepnpm add @osmium/iterate๐ Quick Start
import {iterateSync, iterateAsync, iterateParallel} from '@osmium/iterate';
// Synchronous iteration
iterateSync([1, 2, 3], (value, index) => {
console.log(`Item ${index}: ${value}`);
});
// Asynchronous iteration
await iterateAsync([1, 2, 3], async (value, index) => {
const result = await processAsync(value);
console.log(`Processed ${index}: ${result}`);
});
// Parallel processing
await iterateParallel([1, 2, 3], async (value) => {
return await heavyComputation(value);
});๐ Supported Data Types
| Type | Example | Description |
|---|---|---|
| Array | [1, 2, 3] |
Iterate over array elements |
| Object | {a: 1, b: 2} |
Iterate over object key-value pairs |
| Set | new Set([1, 2, 3]) |
Iterate over set values |
| Map | new Map([['a', 1]]) |
Iterate over map entries |
| String | "hello" |
Iterate over each character |
| Number | 5 |
Iterate N times (0 to N-1) |
| Boolean | true |
Infinite iteration until break |
| Iterable | Custom iterables | Any object with Symbol.iterator |
๐ฏ Core Functions
iterateSync(values, callback, map?, mapUndefined?)
Synchronous iteration over any iterable data type.
// Basic iteration
iterateSync([1, 2, 3], (value, index, control) => {
console.log(`${index}: ${value}`);
});
// With mapping to array
const doubled = iterateSync([1, 2, 3], (value) => value * 2, []);
// Result: [2, 4, 6]
// With flow control
iterateSync([1, 2, 3, 4, 5], (value, index, control) => {
if (value === 3) control.break();
console.log(value);
});
// Output: 1, 2iterateAsync(values, callback, map?, mapUndefined?)
Asynchronous iteration with Promise support.
// Async iteration
await iterateAsync([1, 2, 3], async (value, index) => {
const result = await fetch(`/api/data/${value}`);
return await result.json();
});
// With async mapping
const results = await iterateAsync(
['file1.txt', 'file2.txt'],
async (filename) => await readFile(filename),
[]
);iterateParallel(values, callback, map?, mapUndefined?)
Parallel execution of async callbacks (like Promise.all).
// Process all items in parallel
const results = await iterateParallel(
[1, 2, 3, 4, 5],
async (value) => {
await delay(1000); // All delays happen in parallel
return value * 2;
},
[]
);
// Completes in ~1 second instead of ~5 secondsiterateParallelLimit(limit, values, callback)
Parallel execution with concurrency limit.
// Process max 2 items at a time
await iterateParallelLimit(2, urls, async (url) => {
return await fetch(url);
});๐๏ธ Key-First Iteration
All functions have "Keys" variants that pass the index/key as the first parameter:
// Regular: (value, index, control)
iterateSync({a: 1, b: 2}, (value, key) => {
console.log(`${key} = ${value}`);
});
// Keys variant: (key, value, control)
iterateKeysSync({a: 1, b: 2}, (key, value) => {
console.log(`${key} = ${value}`);
});Available functions:
iterateKeysSync/iterateKeysAsynciterateKeys(auto-detect sync/async)iterateKeysParallel
๐ฎ Flow Control
The control parameter provides powerful flow control options:
iterateSync([1, 2, 3, 4, 5], (value, index, control) => {
// Skip current iteration
if (value === 2) {
control.skip();
return;
}
// Repeat current iteration
if (value === 3 && !repeated) {
repeated = true;
control.repeat();
return;
}
// Break out of loop
if (value === 4) {
control.break();
return;
}
// Shift position
control.shift(1); // Move forward by 1
console.log(value);
});Control Methods
| Method | Description |
|---|---|
control.break() |
Exit the iteration immediately |
control.skip() |
Skip to next iteration |
control.repeat() |
Repeat current iteration |
control.shift(n) |
Move position by n steps |
control.key(newKey) |
Set custom mapping key |
control.length |
Get total length of iterable |
๐บ๏ธ Mapping Strategies
Array Mapping
const doubled = iterateSync([1, 2, 3], (x) => x * 2, []);
// Result: [2, 4, 6]Object Mapping
const mapped = iterateSync(
{a: 1, b: 2},
(value, key) => value * 2,
{}
);
// Result: {a: 2, b: 4}Set Mapping
const uniqueDoubled = iterateSync([1, 2, 2, 3], (x) => x * 2, new Set());
// Result: Set {2, 4, 6}Map Mapping
const keyValueMap = iterateSync(
['a', 'b', 'c'],
(value, index) => value.toUpperCase(),
new Map()
);
// Result: Map {'a' => 'A', 'b' => 'B', 'c' => 'C'}Number Mapping (Counter)
const count = iterateSync([1, 2, undefined, 3], (x) => x, 0);
// Result: 3 (counts non-undefined returns)Boolean Mapping (Flag)
const hasEven = iterateSync([1, 3, 4, 5], (x) => x % 2 === 0, false);
// Result: true (flips to true when callback returns truthy)๐ง Advanced Examples
Processing Files in Batches
import {iterateParallelLimit} from '@osmium/iterate';
const files = ['file1.txt', 'file2.txt', /* ... many files ... */];
// Process max 3 files at a time
await iterateParallelLimit(3, files, async (filename) => {
const content = await fs.readFile(filename, 'utf8');
const processed = await processContent(content);
await fs.writeFile(filename.replace('.txt', '.processed.txt'), processed);
});Data Transformation Pipeline
const data = [
{id: 1, name: 'John', age: 25},
{id: 2, name: 'Jane', age: 30},
{id: 3, name: 'Bob', age: 35}
];
// Transform to Map with custom keys
const userMap = iterateSync(
data,
(user, index, control) => {
control.key(`user_${user.id}`);
return {
...user,
isAdult: user.age >= 18
};
},
new Map()
);Infinite Iteration with Break Condition
let counter = 0;
iterateSync(true, (value, index, control) => {
counter++;
console.log(`Iteration ${counter}`);
if (counter >= 10) {
control.break();
}
});Error Handling in Async Iteration
const results = await iterateAsync(
urls,
async (url, index) => {
try {
const response = await fetch(url);
return await response.json();
} catch (error) {
console.error(`Failed to fetch ${url}:`, error);
return null; // Continue with other URLs
}
},
[]
);๐ Utility Functions
seriesPageableRange(start, end, pageSize)
Generate paginated ranges for batch processing:
import {seriesPageableRange} from '@osmium/iterate';
const ranges = seriesPageableRange(0, 100, 10);
// Result: [[0, 9], [10, 19], [20, 29], ..., [90, 99]]
// Use with parallel processing
await iterateParallel(ranges, async ([start, end]) => {
return await processRange(start, end);
});๐ TypeScript Support
Full TypeScript support with advanced type inference:
// Type inference works automatically
const numbers: number[] = [1, 2, 3];
const doubled = iterateSync(numbers, (x) => x * 2, []); // Type: number[]
// Custom types
interface User {
id: number;
name: string;
}
const users: User[] = [{id: 1, name: 'John'}];
const userNames = iterateSync(users, (user) => user.name, []); // Type: string[]โก Performance
- Synchronous operations: Optimized for minimal overhead
- Parallel processing: Efficient batching and concurrency control
- Memory efficient: Streaming-style processing for large datasets
- Type safety: Zero runtime type checking overhead
๐งช Testing
The library has extensive test coverage (99.24%) with 331+ tests covering:
- All data types and edge cases
- Async/sync operations
- Parallel processing
- Error handling
- Type system validation
- Performance scenarios
Run tests:
npm test๐ License
MIT License - see LICENSE file for details.
๐ค Contributing
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
๐ Support
- ๐ Documentation
- ๐ Issue Tracker
- ๐ฌ Discussions
Made with โค๏ธ by Vasiliy Isaichkin