Iterall: JavaScript Iterables for All Environments
Iterall is a minimalist, zero-dependency utility library designed to enable the use of JavaScript Iterables and AsyncIterables across all JavaScript environments, including older versions of Internet Explorer. It provides crucial helpers for libraries that wish to accept various iterable inputs (like Arrays, Maps, Sets, NodeLists, TypedArrays, or custom data structures) instead of being limited to only Arrays. The current stable version is 1.3.0, and the project maintains a steady release cadence with improvements to TypeScript definitions and async iterator support. Its key differentiators include its tiny footprint (under 1KB gzipped), its 'library for libraries' approach, and its robust compatibility with both modern and legacy JavaScript runtimes through its intelligent fallback mechanism for `Symbol.iterator`.
Common errors
-
TypeError: 'Symbol.iterator' is not defined
cause Attempting to iterate over a custom object or non-native iterable in an older JavaScript environment without leveraging `iterall`'s polyfill utilities, leading to the absence of the `Symbol.iterator` global.fixUse `iterall.forEach(myIterable, callback)` or `iterall.isIterable(myIterable)` to ensure compatibility across all environments, as `iterall` handles the fallback to `@@iterator`. -
SyntaxError: Cannot use import statement outside a module
cause Using `import ... from 'iterall'` syntax in a Node.js environment configured for CommonJS (e.g., without `"type": "module"` in `package.json` or a transpiler like Babel).fixChange your import statements to CommonJS `require` syntax: `const { forEach } = require('iterall');` or configure your Node.js project or build pipeline to support ESM. -
Module not found: Error: Can't resolve 'iterall'
cause A bundler (like Webpack) is failing to resolve the `iterall` package, potentially due to incorrect pathing or module resolution configuration, especially concerning its `.mjs` files.fixVerify `iterall` is correctly installed in `node_modules`. If using a bundler, ensure its configuration supports resolving `.mjs` files (e.g., `resolve.extensions` in Webpack should include `'.mjs'`).
Warnings
- gotcha Iterall's primary value is in providing polyfills and fallbacks for Iteration Protocols in older JavaScript environments (pre-ES2015 or limited browser support). If you are strictly targeting modern ES2015+ environments that fully support `Symbol.iterator`, you might be able to use native iteration directly without `iterall`.
- gotcha For optimal tree-shaking and better ESM compatibility with bundlers like Rollup or Webpack, `iterall` has published `.mjs` files since `v1.2.0`. Ensure your build configuration is set up to resolve `.mjs` files correctly, especially in dual CommonJS/ESM setups.
- gotcha Early versions of `forAwaitEach` (before v1.1.2) had a memory leak issue, and v1.1.2 introduced a fix for this. Subsequently, v1.1.3 fixed an issue where errors within `forAwaitEach` were not caught.
Install
-
npm install iterall -
yarn add iterall -
pnpm add iterall
Imports
- isCollection
const isCollection = require('iterall').isCollection;import { isCollection } from 'iterall'; - forEach
const forEach = require('iterall').forEach;import { forEach } from 'iterall'; - forAwaitEach
const forAwaitEach = require('iterall').forAwaitEach;import { forAwaitEach } from 'iterall';
Quickstart
import { isCollection, forEach, forAwaitEach } from 'iterall';
// Example 1: Handling various synchronous collections
function processCollection(data) {
if (isCollection(data)) {
forEach(data, (item, index) => {
console.log(`Sync Item ${index}: ${item}`);
});
console.log('Finished synchronous iteration.');
} else {
console.log('Input is not a recognized collection.');
}
}
processCollection([1, 2, 3]);
processCollection(new Set(['a', 'b']));
// Example 2: Handling asynchronous iterables
async function* asyncGenerator() {
yield 'hello';
await new Promise(resolve => setTimeout(resolve, 100));
yield 'world';
}
async function processAsyncIterable(asyncData) {
console.log('Starting asynchronous iteration...');
await forAwaitEach(asyncData, (item, index) => {
console.log(`Async Item ${index}: ${item}`);
});
console.log('Finished asynchronous iteration.');
}
processAsyncIterable(asyncGenerator());