npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

it-al

v1.3.11

Published

A TypeScript iterable utility library providing functional programming utilities for working with iterables as well as a class based interface with an easy chainable and typed API.

Readme

It-al

A TypeScript iterable utility library providing functional programming utilities for working with iterables as well as a class based interface with an easy chainable and typed API.

Installation

npm install it-al

Features

  • 🔄 Lazy Evaluation - Iterator-based operations are efficient and composable
  • 🍛 Currying Support - Most functions support both direct and curried forms
  • 🔗 Method Chaining - Fluent API via Iter and PeekableIter classes
  • 🏷️ Type Safe - Full TypeScript support with proper type inference
  • 🧩 Functional - Supports composition via pipe and apply

Quick Start

import { Iter, map, filter, take } from 'it-al';

// Functional style
const result = pipe([
  map((x: number) => x * 2),
  filter((x: number) => x > 5),
  take(3)
])([1, 2, 3, 4, 5, 6]);

// Method chaining style
const result2 = Iter.from([1, 2, 3, 4, 5, 6])
  .map(x => x * 2)
  .filter(x => x > 5)
  .take(3)
  .toArray();

API Reference

Transformation Functions

| Function | Description | Signature | |----------|-------------|-----------| | map | Transform each item in an iterable | <T, U>(iter: Iterable<T>, fn: IterFn<T, U>) => IterableIterator<U> | | filter | Filter items based on a predicate | <T>(iter: Iterable<T>, fn: IterFn<T>) => IterableIterator<T> | | flat | Flatten nested iterables by depth | <T, D>(iter: Iterable<T>, depth?: D) => IterableIterator<FlatItem<T, D>> | | enumerate | Return index-value pairs | <T>(iter: Iterable<T>) => IterableIterator<[number, T]> | | pluck | Extract a property from each item | <T, K>(iter: Iterable<T>, key: K) => IterableIterator<T[K]> | | tap | Run side effects without modifying items | <T>(iter: Iterable<T>, fn: IterFn<T>) => IterableIterator<T> | | scan | Like reduce but yields intermediate values | <T, U>(iter: Iterable<T>, fn, start?: U) => IterableIterator<U> |

Slicing & Limiting

| Function | Description | Signature | |----------|-------------|-----------| | take | Take first n items | <T>(iter: Iterable<T>, n: number) => IterableIterator<T> | | skip | Skip first n items | <T>(iter: Iterable<T>, n: number) => IterableIterator<T> | | takeWhile | Take items while predicate is true | <T>(iter: Iterable<T>, fn: IterFn<T>) => IterableIterator<T> | | skipWhile | Skip items while predicate is true | <T>(iter: Iterable<T>, fn: IterFn<T>) => IterableIterator<T> | | until | Take items until predicate is true | <T>(iter: Iterable<T>, fn: IterFn<T>) => IterableIterator<T> | | chunk | Split into chunks of size n | <T>(iter: Iterable<T>, n: number) => IterableIterator<T[]> | | windows | Create sliding windows of size n | <T>(iter: Iterable<T>, n: number) => IterableIterator<T[]> |

Aggregation & Reduction

| Function | Description | Signature | |----------|-------------|-----------| | reduce | Reduce to a single value | <T, U>(iter: Iterable<T>, fn, start: U) => U | | sum | Sum all numbers | (iter: Iterable<number>) => number | | product | Multiply all numbers | (iter: Iterable<number>) => number | | average | Average all numbers | (iter: Iterable<number>) => number | | count | Count items | <T>(iter: Iterable<T>) => number | | join | Join items into string | <T>(iter: Iterable<T>, delimiter?: string) => string | | groupBy | Group items by key | <T, U>(iter: Iterable<T>, fn) => Map<U, T[]> |

Searching & Testing

| Function | Description | Signature | |----------|-------------|-----------| | find | Find first matching item | <T>(iter: Iterable<T>, fn: IterFn<T>) => T \| null | | findIndex | Find index of first match | <T>(iter: Iterable<T>, fn: IterFn<T>) => number | | includes | Check if value exists | <T>(iter: Iterable<T>, value: T) => boolean | | some | Test if any item matches | <T>(iter: Iterable<T>, fn: IterFn<T>) => boolean | | every | Test if all items match | <T>(iter: Iterable<T>, fn: IterFn<T>) => boolean | | first | Get first item | <T>(iter: Iterable<T>) => T | | last | Get last item | <T>(iter: Iterable<T>) => T \| undefined | | isEmpty | Check if empty | (iter: Iterable<unknown>) => boolean | | search | Recursively search object | <U>(obj: unknown, fn) => IterableIterator<KeyValuePair<U>> |

Uniqueness & Filtering

| Function | Description | Signature | |----------|-------------|-----------| | uniqueBy | Get unique items by selector | <T>(iter: Iterable<T>, fn: IterFn<T>) => IterableIterator<T> | | partition | Split into passed/failed arrays | <T>(iter: Iterable<T>, fn: IterFn<T>) => [T[], T[]] |

Combining & Zipping

| Function | Description | Signature | |----------|-------------|-----------| | zip | Combine multiple iterables | <I>(...iters: I, stopOnMin?: boolean) => ZipOutput<I> | | unzip | Transpose iterable of arrays | <T>(iter: Iterable<T>) => UnzipOutput<T> |

Generation & Repetition

| Function | Description | Signature | |----------|-------------|-----------| | range | Generate range of numbers | (stop: number, start?: number, step?: number) => IterableIterator<number> | | repeat | Repeat iterable n times | <T>(iter: Iterable<T>, n: number) => IterableIterator<T> | | cycle | Cycle through iterable infinitely | <T>(iter: Iterable<T>) => IterableIterator<T> | | gen | Create infinite generator | <T>(fn: (n: number) => T) => () => IterableIterator<T> |

Object/Entry Operations

| Function | Description | Signature | |----------|-------------|-----------| | entries | Get key-value pairs | <T>(input: T) => IterableIterator<Entry<T>> | | allEntries | Get entries including Symbols | <T>(input: T) => IterableIterator<Entry<T>> | | fromEntries | Create object from entries | <K, V>(iter: Iterable<[K, V]>) => Record<K, V> |

Utilities

| Function | Description | Signature | |----------|-------------|-----------| | pipe | Compose functions left-to-right | <I, O>(fns: Function[]) => (item: I) => O | | apply | Apply functions in order | <I, O>(input: I, fns: Function[]) => O | | peekable | Create peekable iterable | <T>(iter: Iterable<T>) => Peekable<T> | | isIterable | Check if value is iterable | <T>(x: unknown) => x is Iterable<T> | | isNonStringIterable | Check iterable (not string) | <T>(x: unknown) => x is Iterable<T> | | isAsyncIterable | Check if async iterable | <T>(x: unknown) => x is AsyncIterable<T> |

Class-Based API

Iter<T>

Chainable wrapper around iterables providing a fluent API.

Static Methods

| Method | Description | Return Type | |--------|-------------|-------------| | Iter#from(iterable) | Create an Iter from any iterable | Iter<T> | | Iter#safeFrom(maybeIterable?) | Create an Iter from unknown input, returns empty Iter if not iterable | Iter<T> | | Iter#fromAsync(iterable) | Create an Iter from async iterable or promises | Iter<T> | | Iter#fromEntries(obj) | Create an Iter from object entries | Iter<[K, V]> | | Iter#safeFromEntries(obj?) | Create an Iter from object entries, returns empty Iter if null/undefined | Iter<[K, V]> | | Iter#fromRange(stop, start?, step?) | Create an Iter from a numeric range | Iter<number> | | Iter#gen(fn) | Create infinite Iter using generator function | () => Iter<T> | | Iter#zip(iterables, stopOnMin?) | Zip multiple iterables into tuples | Iter<[...]> | | Iter#search(obj, fn, skipAfterYield?) | Recursively search object for matching values | Iter<KeyValuePair<U>> |

Chainable Methods

Returns a new Iter<T> instance for continued chaining.

| Method | Description | |--------|-------------| | Iter#flatMap(fn) | Map and flatten in one step | | Iter#flat(depth?) | Flatten nested iterables | | Iter#map(fn) | Transform each item | | Iter#filter(fn) | Filter items by predicate | | Iter#filterNullish() | Remove null and undefined values | | Iter#unique() | Remove duplicate values | | Iter#enumerate() | Add index to each item as [index, value] | | Iter#uniqueBy(fn) | Remove duplicates by selector function | | Iter#tap(fn) | Run side effects without modifying items | | Iter#scan(fn, start?) | Like reduce but yields intermediate values | | Iter#pluck(key) | Extract property from each item | | Iter#take(n) | Take first n items | | Iter#chunk(n) | Split into chunks of size n | | Iter#skip(n) | Skip first n items | | Iter#takeWhile(fn) | Take items while predicate is true | | Iter#skipWhile(fn) | Skip items while predicate is true | | Iter#until(fn) | Take items until predicate is true | | Iter#windows(size) | Create sliding windows of size n | | Iter#apply(fn) | Apply a function to the iterable | | Iter#peekable() | Convert to PeekableIter | | Iter#repeat(times) | Repeat the iterable n times | | Iter#cycle() | Cycle through iterable infinitely |

Terminal Methods

Consumes the iterator and returns a final value.

| Method | Description | Return Type | |--------|-------------|-------------| | Iter#first() | Get the first item | T | | Iter#last() | Get the last item | T \| undefined | | Iter#find(fn) | Find first item matching predicate | T \| null | | Iter#findIndex(fn) | Find index of first match | number | | Iter#includes(value) | Check if value exists | boolean | | Iter#count() | Count total items | number | | Iter#isEmpty() | Check if iterable is empty | boolean | | Iter#forEach(fn) | Like Array.forEach but for Iter | void | | Iter#reduce(fn, start) | Reduce to single value | U | | Iter#every(fn) | Test if all items match predicate | boolean | | Iter#some(fn) | Test if any item matches predicate | boolean | | Iter#unzip() | Transpose iterable of arrays | UnzipOutput<T> | | Iter#partition(fn) | Split into [passed, failed] arrays | [T[], T[]] | | Iter#join(delimiter?) | Join items into string | string | | Iter#groupBy(fn) | Group items by key | Map<K, T[]> | | Iter#sum() | Sum all numbers | number | | Iter#product() | Multiply all numbers | number | | Iter#average() | Average all numbers | number | | Iter#min() | Find minimum value | T | | Iter#max() | Find maximum value | T | | Iter#collect(collector?) | Collect using custom collector | U | | Iter#toArray() | Collect all items into an array | T[] | | Iter#toSet() | Collect all items into a Set | Set<T> | | Iter#toMap() | Collect entries into a Map | Map<K, V> |

PeekableIter<T>

Extends Iter<T> with the ability to peek at the next value without consuming it.

const iter = PeekableIter.from([1, 2, 3]);
console.log(iter.peek()); // 1 (doesn't consume)
console.log(iter.first()); // 1 (consumes)

Additional Method

| Method | Description | Return Type | |--------|-------------|-------------| | PeekableIter#peek() | Look at next value without consuming it | T \| undefined |

Examples

Currying

import { map, filter, pipe } from 'it-al';

// Curried form
const double = map((x: number) => x * 2);
const isPowerOfTwo = filter((x: number) => Math.sqrt(x, 2) % 1 === 0);

const result = pipe([double, isPowerOfTwo])([1, 2, 3, 4]);
// [2, 4, 8]

Method Chaining

import { Iter } from 'it-al';

const result = Iter.from([1, 2, 3, 4, 5])
  .map(x => x * 2)
  .filter(x => x > 5)
  .take(2)
  .toArray();
// [6, 8]

Lazy Evaluation

import { map, take } from 'it-al';

const expensive = map((x: number) => {
  console.log('Processing:', x);
  return x * 2;
});

// Only processes first 3 items
const result = take(expensive([1, 2, 3, 4, 5, 6, 7, 8]), 3);

for (const _ of result) {}
// Logs: Processing: 1, 2, 3

Working with Infinite Iterators

import { Iter } from 'it-al';

// Generate infinite sequence
const randomNumbers = Iter.gen((n) => Math.random());

// Generates 10 random numbers
const first10 = fibonacci().take(10).toArray();

Grouping and Aggregation

import { Iter } from 'it-al';

const data = [
  { category: 'A', value: 10 },
  { category: 'B', value: 20 },
  { category: 'A', value: 30 },
];

const grouped = Iter.from(data).groupBy(item => item.category);
// Map { 'A' => [{...}, {...}], 'B' => [{...}] }