Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .scripts/postbuild.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,15 @@ create_compat_alias() {
}

# Create root exports
for module in array server error compat fp function math map object predicate promise set string util; do
for module in array server error compat fp function iterator math map object predicate promise set string util; do
create_root_export $module
done

# Create nested fp/iterator export shim
mkdir -p fp
echo "export * from './dist/fp/iterator';" > fp/iterator.d.ts
echo "module.exports = require('./dist/fp/iterator');" > fp/iterator.js

# Create compat directory
mkdir -p compat

Expand Down
25 changes: 25 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
"./compat": "./src/compat/index.ts",
"./error": "./src/error/index.ts",
"./fp": "./src/fp/index.ts",
"./fp/iterator": "./src/fp/iterator/index.ts",
"./function": "./src/function/index.ts",
"./iterator": "./src/iterator/index.ts",
"./map": "./src/map/index.ts",
"./math": "./src/math/index.ts",
"./object": "./src/object/index.ts",
Expand All @@ -39,7 +41,10 @@
"compat.js",
"error.js",
"fp.js",
"fp/iterator.js",
"fp/iterator.d.ts",
"function.js",
"iterator.js",
"map.js",
"math.js",
"object.js",
Expand Down Expand Up @@ -180,6 +185,16 @@
"default": "./dist/fp/index.js"
}
},
"./fp/iterator": {
"import": {
"types": "./dist/fp/iterator/index.d.mts",
"default": "./dist/fp/iterator/index.mjs"
},
"require": {
"types": "./dist/fp/iterator/index.d.ts",
"default": "./dist/fp/iterator/index.js"
}
},
"./function": {
"import": {
"types": "./dist/function/index.d.mts",
Expand All @@ -190,6 +205,16 @@
"default": "./dist/function/index.js"
}
},
"./iterator": {
"import": {
"types": "./dist/iterator/index.d.mts",
"default": "./dist/iterator/index.mjs"
},
"require": {
"types": "./dist/iterator/index.d.ts",
"default": "./dist/iterator/index.js"
}
},
"./map": {
"import": {
"types": "./dist/map/index.d.mts",
Expand Down
22 changes: 22 additions & 0 deletions src/fp/iterator/chunk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { chunk as chunkIterator } from '../../iterator/chunk.ts';

/**
* Creates a function that lazily groups the elements of an iterator into arrays
* of length `size`, for use with {@link pipe}. The final chunk may be shorter.
*
* @template T - The type of elements produced by the source iterator.
* @param size - The length of each chunk; must be an integer greater than zero.
* @returns A function mapping an `Iterator<T>` to a lazy `IteratorObject<T[]>`.
* @throws {Error} Throws an error if `size` is not an integer greater than zero.
*
* @example
* import { pipe } from 'es-toolkit/fp';
* import { chunk, toArray } from 'es-toolkit/fp/iterator';
*
* pipe([1, 2, 3, 4, 5].values(), chunk(2), toArray()); // => [[1, 2], [3, 4], [5]]
*/
export function chunk<T>(size: number): (source: Iterator<T>) => IteratorObject<T[], undefined> {
return function chunkInIterator(source: Iterator<T>): IteratorObject<T[], undefined> {
return chunkIterator(source, size);
};
}
23 changes: 23 additions & 0 deletions src/fp/iterator/count.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { count as countIterator } from '../../iterator/count.ts';

/**
* Creates a function that consumes an iterator and returns the number of
* elements it produces, for use as the terminal step of a {@link pipe}.
*
* This is a terminal operation: it pulls every element, so it must not be used
* on an infinite iterator.
*
* @template T - The type of elements produced by the source iterator.
* @returns A function mapping an `Iterator<T>` to its element count.
*
* @example
* import { pipe } from 'es-toolkit/fp';
* import { filter, count } from 'es-toolkit/fp/iterator';
*
* pipe([1, 2, 3, 4].values(), filter(x => x % 2 === 0), count()); // => 2
*/
export function count<T>(): (source: Iterator<T>) => number {
return function countInIterator(source: Iterator<T>): number {
return countIterator(source);
};
}
21 changes: 21 additions & 0 deletions src/fp/iterator/drop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Creates a function that lazily skips the first `count` elements of an iterator
* and yields the rest, for use with {@link pipe}. It delegates to the native
* `Iterator.prototype.drop`.
*
* @template T - The type of elements produced by the source iterator.
* @param count - The number of elements to skip; must be a non-negative integer.
* @returns A function mapping an `Iterator<T>` to a lazy `IteratorObject<T>`.
* @throws {RangeError} Throws if `count` is negative or `NaN` (native behavior).
*
* @example
* import { pipe } from 'es-toolkit/fp';
* import { drop } from 'es-toolkit/fp/iterator';
*
* pipe([1, 2, 3, 4, 5].values(), drop(2)).toArray(); // => [3, 4, 5]
*/
export function drop<T>(count: number): (source: Iterator<T>) => IteratorObject<T, undefined> {
return function dropInIterator(source: Iterator<T>): IteratorObject<T, undefined> {
return Iterator.from(source).drop(count);
};
}
23 changes: 23 additions & 0 deletions src/fp/iterator/dropWhile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { dropWhile as dropWhileIterator } from '../../iterator/dropWhile.ts';

/**
* Creates a function that lazily skips elements of an iterator while `shouldDrop`
* returns truthy, then yields the rest, for use with {@link pipe}.
*
* @template T - The type of elements produced by the source iterator.
* @param shouldDrop - Called with `(value, index)`; elements are skipped while it returns truthy.
* @returns A function mapping an `Iterator<T>` to a lazy `IteratorObject<T>`.
*
* @example
* import { pipe } from 'es-toolkit/fp';
* import { dropWhile, toArray } from 'es-toolkit/fp/iterator';
*
* pipe([1, 2, 3, 1].values(), dropWhile(x => x < 3), toArray()); // => [3, 1]
*/
export function dropWhile<T>(
shouldDrop: (value: T, index: number) => boolean
): (source: Iterator<T>) => IteratorObject<T, undefined> {
return function dropWhileInIterator(source: Iterator<T>): IteratorObject<T, undefined> {
return dropWhileIterator(source, shouldDrop);
};
}
21 changes: 21 additions & 0 deletions src/fp/iterator/every.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Creates a function that consumes an iterator until `predicate` returns falsy
* and reports whether every element matched, for use as the terminal step of a
* {@link pipe}. It delegates to the native `Iterator.prototype.every` and stops
* pulling at the first non-match.
*
* @template T - The type of elements produced by the source iterator.
* @param predicate - Called with `(value, index)`; falsy short-circuits to `false`.
* @returns A function mapping an `Iterator<T>` to a boolean.
*
* @example
* import { pipe } from 'es-toolkit/fp';
* import { every } from 'es-toolkit/fp/iterator';
*
* pipe([2, 4, 6].values(), every(x => x % 2 === 0)); // => true
*/
export function every<T>(predicate: (value: T, index: number) => unknown): (source: Iterator<T>) => boolean {
return function everyInIterator(source: Iterator<T>): boolean {
return Iterator.from(source).every(predicate);
};
}
47 changes: 47 additions & 0 deletions src/fp/iterator/filter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Creates a function that lazily keeps the elements of an iterator for which
* `predicate` returns truthy, narrowing the element type when `predicate` is a
* type guard. For use with {@link pipe}. It delegates to the native
* `Iterator.prototype.filter`.
*
* @template T - The type of elements produced by the source iterator.
* @template S - The narrowed element type when `predicate` is a type guard.
* @param predicate - Called with `(value, index)`; truthy keeps the element.
* @returns A function mapping an `Iterator<T>` to a lazy `IteratorObject<S>`.
*
* @example
* import { pipe } from 'es-toolkit/fp';
* import { filter } from 'es-toolkit/fp/iterator';
*
* pipe([1, 2, 3, 4].values(), filter(x => x % 2 === 0)).toArray(); // => [2, 4]
*/
export function filter<T, S extends T>(
predicate: (value: T, index: number) => value is S
): (source: Iterator<T>) => IteratorObject<S, undefined>;

/**
* Creates a function that lazily keeps the elements of an iterator for which
* `predicate` returns truthy, for use with {@link pipe}. It delegates to the
* native `Iterator.prototype.filter`.
*
* @template T - The type of elements produced by the source iterator.
* @param predicate - Called with `(value, index)`; truthy keeps the element.
* @returns A function mapping an `Iterator<T>` to a lazy `IteratorObject<T>`.
*
* @example
* import { pipe } from 'es-toolkit/fp';
* import { filter } from 'es-toolkit/fp/iterator';
*
* pipe([1, 2, 3, 4].values(), filter(x => x % 2 === 0)).toArray(); // => [2, 4]
*/
export function filter<T>(
predicate: (value: T, index: number) => unknown
): (source: Iterator<T>) => IteratorObject<T, undefined>;

export function filter<T>(
predicate: (value: T, index: number) => unknown
): (source: Iterator<T>) => IteratorObject<T, undefined> {
return function filterInIterator(source: Iterator<T>): IteratorObject<T, undefined> {
return Iterator.from(source).filter(predicate) as IteratorObject<T, undefined>;
};
}
21 changes: 21 additions & 0 deletions src/fp/iterator/find.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Creates a function that consumes an iterator until `predicate` returns truthy
* and returns that element (or `undefined` if none match), for use as the
* terminal step of a {@link pipe}. It delegates to the native
* `Iterator.prototype.find` and stops pulling at the first match.
*
* @template T - The type of elements produced by the source iterator.
* @param predicate - Called with `(value, index)`; truthy selects the element.
* @returns A function mapping an `Iterator<T>` to the matching element or `undefined`.
*
* @example
* import { pipe } from 'es-toolkit/fp';
* import { find } from 'es-toolkit/fp/iterator';
*
* pipe([1, 2, 3, 4].values(), find(x => x > 2)); // => 3
*/
export function find<T>(predicate: (value: T, index: number) => unknown): (source: Iterator<T>) => T | undefined {
return function findInIterator(source: Iterator<T>): T | undefined {
return Iterator.from(source).find(predicate);
};
}
23 changes: 23 additions & 0 deletions src/fp/iterator/flatMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Creates a function that lazily maps each element of an iterator to an iterable
* (or iterator) and flattens the results one level, for use with {@link pipe}.
* It delegates to the native `Iterator.prototype.flatMap`.
*
* @template T - The type of elements produced by the source iterator.
* @template U - The type of elements produced by the result.
* @param callback - Called with `(value, index)`; returns the iterable to flatten in.
* @returns A function mapping an `Iterator<T>` to a lazy `IteratorObject<U>`.
*
* @example
* import { pipe } from 'es-toolkit/fp';
* import { flatMap } from 'es-toolkit/fp/iterator';
*
* pipe([1, 2].values(), flatMap(x => [x, x * 10])).toArray(); // => [1, 10, 2, 20]
*/
export function flatMap<T, U>(
callback: (value: T, index: number) => Iterator<U, unknown, undefined> | Iterable<U, unknown, undefined>
): (source: Iterator<T>) => IteratorObject<U, undefined> {
return function flatMapInIterator(source: Iterator<T>): IteratorObject<U, undefined> {
return Iterator.from(source).flatMap(callback);
};
}
23 changes: 23 additions & 0 deletions src/fp/iterator/forEach.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Creates a function that consumes an iterator and runs `callback` for each
* element, for use as the terminal step of a {@link pipe}. It delegates to the
* native `Iterator.prototype.forEach`.
*
* This is a terminal operation: it pulls every element, so it must not be used
* on an infinite iterator.
*
* @template T - The type of elements produced by the source iterator.
* @param callback - Called with `(value, index)` for each element.
* @returns A function mapping an `Iterator<T>` to `void`.
*
* @example
* import { pipe } from 'es-toolkit/fp';
* import { forEach } from 'es-toolkit/fp/iterator';
*
* pipe([1, 2, 3].values(), forEach(x => console.log(x))); // logs 1, 2, 3
*/
export function forEach<T>(callback: (value: T, index: number) => void): (source: Iterator<T>) => void {
return function forEachInIterator(source: Iterator<T>): void {
Iterator.from(source).forEach(callback);
};
}
22 changes: 22 additions & 0 deletions src/fp/iterator/head.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { head as headIterator } from '../../iterator/head.ts';

/**
* Creates a function that returns the first element of an iterator (or
* `undefined` if it is empty), for use as the terminal step of a {@link pipe}.
* It pulls a single element and then stops, so it is safe on an infinite
* iterator.
*
* @template T - The type of elements produced by the source iterator.
* @returns A function mapping an `Iterator<T>` to its first element or `undefined`.
*
* @example
* import { pipe } from 'es-toolkit/fp';
* import { filter, head } from 'es-toolkit/fp/iterator';
*
* pipe([1, 2, 3, 4].values(), filter(x => x % 2 === 0), head()); // => 2
*/
export function head<T>(): (source: Iterator<T>) => T | undefined {
return function headInIterator(source: Iterator<T>): T | undefined {
return headIterator(source);
};
}
Loading
Loading