Skip to content
Merged
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
12 changes: 6 additions & 6 deletions .size-limit.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,42 @@
{
"name": "es5-full",
"path": "lib/dist/es5/mod/ts-utils.js",
"limit": "35 kb",
"limit": "37 kb",
"brotli": false,
"running": false
},
{
"name": "es6-full",
"path": "lib/dist/es6/mod/ts-utils.js",
"limit": "33.5 kb",
"limit": "35.5 kb",
"brotli": false,
"running": false
},
{
"name": "es5-full-brotli",
"path": "lib/dist/es5/mod/ts-utils.js",
"limit": "12.5 kb",
"limit": "12.75 kb",
"brotli": true,
"running": false
},
{
"name": "es6-full-brotli",
"path": "lib/dist/es6/mod/ts-utils.js",
"limit": "12 kb",
"limit": "12.5 kb",
"brotli": true,
"running": false
},
{
"name": "es5-zip",
"path": "lib/dist/es5/mod/ts-utils.js",
"limit": "13.5 Kb",
"limit": "14 Kb",
"gzip": true,
"running": false
},
{
"name": "es6-zip",
"path": "lib/dist/es6/mod/ts-utils.js",
"limit": "13.5 Kb",
"limit": "14 Kb",
"gzip": true,
"running": false
},
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
- Adds shared queue logic and callback-argument support across microtask and nextTick scheduling
- Adds `arrConcat` as a dedicated array helper and `fnBindArgs` as a dedicated function helper
- Improves function binding typing with exported `BoundFunction` and updated signatures for `fnBind` / `fnBindArgs`
- [#574](https://github.com/nevware21/ts-utils/pull/574) feat(iterator,array): add iterator collection helpers, split helper modules, and align collection membership semantics
- Added new iterator helpers: `iterMap`, `iterFilter`, `iterTake`, `iterReduce`, `iterSome`, `iterEvery`, `iterToArray`, `iterUnion`, `iterIntersection`, `iterDifference`
- Added `arrToMap` helper in the array module and moved callback/type declarations into `iterator/types`
- Refactored iterator helper implementation/tests into per-function files and updated root exports
- Added NaN regression coverage and switched iterator set-operation membership checks to `arrIncludes` semantics for parity with array helpers

### Bug Fixes

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ Below is a categorized list of all available utilities with direct links to thei
| Error | <code>[createCustomError](https://nevware21.github.io/ts-utils/typedoc/functions/createCustomError.html)(); [isError](https://nevware21.github.io/ts-utils/typedoc/functions/isError.html)(); [throwError](https://nevware21.github.io/ts-utils/typedoc/functions/throwError.html)(); [throwRangeError](https://nevware21.github.io/ts-utils/typedoc/functions/throwRangeError.html)(); [throwTypeError](https://nevware21.github.io/ts-utils/typedoc/functions/throwTypeError.html)(); [throwUnsupported](https://nevware21.github.io/ts-utils/typedoc/functions/throwUnsupported.html)();</code>
| Function | <code>[fnApply](https://nevware21.github.io/ts-utils/typedoc/functions/fnApply.html)(); [fnBind](https://nevware21.github.io/ts-utils/typedoc/functions/fnBind.html)(); [fnBindArgs](https://nevware21.github.io/ts-utils/typedoc/functions/fnBindArgs.html)(); [fnCall](https://nevware21.github.io/ts-utils/typedoc/functions/fnCall.html)(); [createFnDeferredProxy](https://nevware21.github.io/ts-utils/typedoc/functions/createFnDeferredProxy.html)(); [createProxyFuncs](https://nevware21.github.io/ts-utils/typedoc/functions/createProxyFuncs.html)(); [readArgs](https://nevware21.github.io/ts-utils/typedoc/functions/readArgs.html)();</code>
| Idle | <code>[getCancelIdleCallback](https://nevware21.github.io/ts-utils/typedoc/functions/getCancelIdleCallback.html)(); [getIdleCallback](https://nevware21.github.io/ts-utils/typedoc/functions/getIdleCallback.html)(); [hasIdleCallback](https://nevware21.github.io/ts-utils/typedoc/functions/hasIdleCallback.html)(); [setDefaultIdleTimeout](https://nevware21.github.io/ts-utils/typedoc/functions/setDefaultIdleTimeout.html)(); [setDefaultMaxExecutionTime](https://nevware21.github.io/ts-utils/typedoc/functions/setDefaultMaxExecutionTime.html)(); </code>
| Iterator | <code>[createArrayIterator](https://nevware21.github.io/ts-utils/typedoc/functions/createArrayIterator.html)(); [createIterator](https://nevware21.github.io/ts-utils/typedoc/functions/createIterator.html)(); [createIterable](https://nevware21.github.io/ts-utils/typedoc/functions/createIterable.html)(); [createRangeIterator](https://nevware21.github.io/ts-utils/typedoc/functions/createRangeIterator.html)(); [iterForOf](https://nevware21.github.io/ts-utils/typedoc/functions/iterForOf.html)(); [isAsyncIterable](https://nevware21.github.io/ts-utils/typedoc/functions/isAsyncIterable.html)(); [isIterable](https://nevware21.github.io/ts-utils/typedoc/functions/isIterable.html)(); [isIterator](https://nevware21.github.io/ts-utils/typedoc/functions/isIterator.html)(); [makeIterable](https://nevware21.github.io/ts-utils/typedoc/functions/makeIterable.html)(); [arrAppend](https://nevware21.github.io/ts-utils/typedoc/functions/arrAppend.html)(); [arrFrom](https://nevware21.github.io/ts-utils/typedoc/functions/arrFrom.html)();</code>
| Iterator | <code>[createArrayIterator](https://nevware21.github.io/ts-utils/typedoc/functions/createArrayIterator.html)(); [createIterator](https://nevware21.github.io/ts-utils/typedoc/functions/createIterator.html)(); [createIterable](https://nevware21.github.io/ts-utils/typedoc/functions/createIterable.html)(); [createIterableIterator](https://nevware21.github.io/ts-utils/typedoc/functions/createIterableIterator.html)(); [createRangeIterator](https://nevware21.github.io/ts-utils/typedoc/functions/createRangeIterator.html)(); [iterForOf](https://nevware21.github.io/ts-utils/typedoc/functions/iterForOf.html)(); [iterMap](https://nevware21.github.io/ts-utils/typedoc/functions/iterMap.html)(); [iterFilter](https://nevware21.github.io/ts-utils/typedoc/functions/iterFilter.html)(); [iterTake](https://nevware21.github.io/ts-utils/typedoc/functions/iterTake.html)(); [iterReduce](https://nevware21.github.io/ts-utils/typedoc/functions/iterReduce.html)(); [iterSome](https://nevware21.github.io/ts-utils/typedoc/functions/iterSome.html)(); [iterEvery](https://nevware21.github.io/ts-utils/typedoc/functions/iterEvery.html)(); [iterToArray](https://nevware21.github.io/ts-utils/typedoc/functions/iterToArray.html)(); [iterUnion](https://nevware21.github.io/ts-utils/typedoc/functions/iterUnion.html)(); [iterIntersection](https://nevware21.github.io/ts-utils/typedoc/functions/iterIntersection.html)(); [iterDifference](https://nevware21.github.io/ts-utils/typedoc/functions/iterDifference.html)(); [isAsyncIterable](https://nevware21.github.io/ts-utils/typedoc/functions/isAsyncIterable.html)(); [isIterable](https://nevware21.github.io/ts-utils/typedoc/functions/isIterable.html)(); [isIterator](https://nevware21.github.io/ts-utils/typedoc/functions/isIterator.html)(); [makeIterable](https://nevware21.github.io/ts-utils/typedoc/functions/makeIterable.html)(); [arrAppend](https://nevware21.github.io/ts-utils/typedoc/functions/arrAppend.html)(); [arrFrom](https://nevware21.github.io/ts-utils/typedoc/functions/arrFrom.html)(); [arrToMap](https://nevware21.github.io/ts-utils/typedoc/functions/arrToMap.html)();</code>
| Number | <code>[getIntValue](https://nevware21.github.io/ts-utils/typedoc/functions/getIntValue.html)(); [isInteger](https://nevware21.github.io/ts-utils/typedoc/functions/isInteger.html)(); [isIntegerInRange](https://nevware21.github.io/ts-utils/typedoc/functions/isIntegerInRange.html)(); [isFiniteNumber](https://nevware21.github.io/ts-utils/typedoc/functions/isFiniteNumber.html)(); [isNumber](https://nevware21.github.io/ts-utils/typedoc/functions/isNumber.html)();</code>
| Math | <code>[mathAbs](https://nevware21.github.io/ts-utils/typedoc/functions/mathAbs.html)(); [mathAcos](https://nevware21.github.io/ts-utils/typedoc/functions/mathAcos.html)(); [mathAsin](https://nevware21.github.io/ts-utils/typedoc/functions/mathAsin.html)(); [mathAtan](https://nevware21.github.io/ts-utils/typedoc/functions/mathAtan.html)(); [mathAtan2](https://nevware21.github.io/ts-utils/typedoc/functions/mathAtan2.html)(); [mathCeil](https://nevware21.github.io/ts-utils/typedoc/functions/mathCeil.html)(); [mathCos](https://nevware21.github.io/ts-utils/typedoc/functions/mathCos.html)(); [mathExp](https://nevware21.github.io/ts-utils/typedoc/functions/mathExp.html)(); [mathFloor](https://nevware21.github.io/ts-utils/typedoc/functions/mathFloor.html)(); [mathLog](https://nevware21.github.io/ts-utils/typedoc/functions/mathLog.html)(); [mathMax](https://nevware21.github.io/ts-utils/typedoc/functions/mathMax.html)(); [mathMin](https://nevware21.github.io/ts-utils/typedoc/functions/mathMin.html)(); [mathPow](https://nevware21.github.io/ts-utils/typedoc/functions/mathPow.html)(); [mathRandom](https://nevware21.github.io/ts-utils/typedoc/functions/mathRandom.html)(); [mathRound](https://nevware21.github.io/ts-utils/typedoc/functions/mathRound.html)(); [mathSin](https://nevware21.github.io/ts-utils/typedoc/functions/mathSin.html)(); [mathSqrt](https://nevware21.github.io/ts-utils/typedoc/functions/mathSqrt.html)(); [mathTan](https://nevware21.github.io/ts-utils/typedoc/functions/mathTan.html)(); [mathToInt](https://nevware21.github.io/ts-utils/typedoc/functions/mathToInt.html)(); [mathTrunc](https://nevware21.github.io/ts-utils/typedoc/functions/mathTrunc.html)();</code>
| Object | <code>[deepExtend](https://nevware21.github.io/ts-utils/typedoc/functions/deepExtend.html)(); [forEachOwnKey](https://nevware21.github.io/ts-utils/typedoc/functions/forEachOwnKey.html)(); [forEachOwnKeySafe](https://nevware21.github.io/ts-utils/typedoc/functions/forEachOwnKeySafe.html)(); [isObject](https://nevware21.github.io/ts-utils/typedoc/functions/isObject.html)(); [isUnsafePropKey](https://nevware21.github.io/ts-utils/typedoc/functions/isUnsafePropKey.html)(); [isUnsafeTarget](https://nevware21.github.io/ts-utils/typedoc/functions/isUnsafeTarget.html)(); [objAssign](https://nevware21.github.io/ts-utils/typedoc/functions/objAssign.html)(); [objCopyProps](https://nevware21.github.io/ts-utils/typedoc/functions/objCopyProps.html)(); [objCreate](https://nevware21.github.io/ts-utils/typedoc/functions/objCreate.html)(); [objDeepCopy](https://nevware21.github.io/ts-utils/typedoc/functions/objDeepCopy.html)(); [objDeepFreeze](https://nevware21.github.io/ts-utils/typedoc/functions/objDeepFreeze.html)(); [objDefaults](https://nevware21.github.io/ts-utils/typedoc/functions/objDefaults.html)(); [objDefine](https://nevware21.github.io/ts-utils/typedoc/functions/objDefine.html)(); [objDefineAccessors](https://nevware21.github.io/ts-utils/typedoc/functions/objDefineAccessors.html)(); [objDefineGet](https://nevware21.github.io/ts-utils/typedoc/functions/objDefineGet.html)(); [objDefineProp](https://nevware21.github.io/ts-utils/typedoc/functions/objDefineProp.html)(); [objDefineProps](https://nevware21.github.io/ts-utils/typedoc/functions/objDefineProps.html)(); [objDefineProperties](https://nevware21.github.io/ts-utils/typedoc/functions/objDefineProperties.html)(); [objDiff](https://nevware21.github.io/ts-utils/typedoc/functions/objDiff.html)(); [objEntries](https://nevware21.github.io/ts-utils/typedoc/functions/objEntries.html)(); [objExtend](https://nevware21.github.io/ts-utils/typedoc/functions/objExtend.html)(); [objForEachKey](https://nevware21.github.io/ts-utils/typedoc/functions/objForEachKey.html)(); [objForEachKeySafe](https://nevware21.github.io/ts-utils/typedoc/functions/objForEachKeySafe.html)(); [objFreeze](https://nevware21.github.io/ts-utils/typedoc/functions/objFreeze.html)(); [objFromEntries](https://nevware21.github.io/ts-utils/typedoc/functions/objFromEntries.html)(); [objGetOwnPropertyDescriptor](https://nevware21.github.io/ts-utils/typedoc/functions/objGetOwnPropertyDescriptor.html)(); [objGetOwnPropertyDescriptors](https://nevware21.github.io/ts-utils/typedoc/functions/objGetOwnPropertyDescriptors.html)(); [objGetOwnPropertyNames](https://nevware21.github.io/ts-utils/typedoc/functions/objGetOwnPropertyNames.html)(); [objGetOwnPropertySymbols](https://nevware21.github.io/ts-utils/typedoc/functions/objGetOwnPropertySymbols.html)(); [objHasOwn](https://nevware21.github.io/ts-utils/typedoc/functions/objHasOwn.html)(); [objHasOwnProperty](https://nevware21.github.io/ts-utils/typedoc/functions/objHasOwnProperty.html)(); [objIs](https://nevware21.github.io/ts-utils/typedoc/functions/objIs.html)(); [objIsExtensible](https://nevware21.github.io/ts-utils/typedoc/functions/objIsExtensible.html)(); [objIsFrozen](https://nevware21.github.io/ts-utils/typedoc/functions/objIsFrozen.html)(); [objIsSealed](https://nevware21.github.io/ts-utils/typedoc/functions/objIsSealed.html)(); [objKeys](https://nevware21.github.io/ts-utils/typedoc/functions/objKeys.html)(); [objMapValues](https://nevware21.github.io/ts-utils/typedoc/functions/objMapValues.html)(); [objMergeIf](https://nevware21.github.io/ts-utils/typedoc/functions/objMergeIf.html)(); [objOmit](https://nevware21.github.io/ts-utils/typedoc/functions/objOmit.html)(); [objOmitBy](https://nevware21.github.io/ts-utils/typedoc/functions/objOmitBy.html)(); [objPick](https://nevware21.github.io/ts-utils/typedoc/functions/objPick.html)(); [objPickBy](https://nevware21.github.io/ts-utils/typedoc/functions/objPickBy.html)(); [objPreventExtensions](https://nevware21.github.io/ts-utils/typedoc/functions/objPreventExtensions.html)(); [objPropertyIsEnumerable](https://nevware21.github.io/ts-utils/typedoc/functions/objPropertyIsEnumerable.html)(); [objSeal](https://nevware21.github.io/ts-utils/typedoc/functions/objSeal.html)(); [objGetPrototypeOf](https://nevware21.github.io/ts-utils/typedoc/functions/objGetPrototypeOf.html)(); [objSetPrototypeOf](https://nevware21.github.io/ts-utils/typedoc/functions/objSetPrototypeOf.html)(); [objToString](https://nevware21.github.io/ts-utils/typedoc/functions/objToString.html)(); [objValues](https://nevware21.github.io/ts-utils/typedoc/functions/objValues.html)();<br/>[polyObjEntries](https://nevware21.github.io/ts-utils/typedoc/functions/polyObjEntries.html)(); [polyObjIs](https://nevware21.github.io/ts-utils/typedoc/functions/polyObjIs.html)(); [polyObjKeys](https://nevware21.github.io/ts-utils/typedoc/functions/polyObjKeys.html)();</code>
Expand Down
11 changes: 1 addition & 10 deletions docs/feature-backlog.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,9 @@ Notes:

- These are direct language-native wrappers with ES version markers for polyfill candidates
- Other suggestions below are library-level utilities (not direct language features).
- Iterator helpers are intentionally listed as utility suggestions here rather than standard-language mappings.
- Implementations should include ES5 polyfills where applicable for v0.x/v1.x compatibility

### A. Iterator and Collection Helpers (Medium Value)

- `iterMap`, `iterFilter`, `iterTake` – Iterator transformation helpers
- `iterReduce`, `iterSome`, `iterEvery` – Iterator reduction/testing
- `iterToArray` for predictable materialization of iterables / iterators
- `arrToMap` helpers with stable key selection
- lightweight set operations for iterables

### B. Reliability and Tooling (High Value)
### A. Reliability and Tooling (High Value)

- keep bundle-size thresholds justified with measured report
- require test parity for polyfill vs native behavior
Expand Down
59 changes: 59 additions & 0 deletions lib/src/array/arrToMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* @nevware21/ts-utils
* https://github.com/nevware21/ts-utils
*
* Copyright (c) 2026 NevWare21 Solutions LLC
* Licensed under the MIT license.
*/

import { isArrayLike } from "../helpers/base";
import { isUnsafePropKey } from "../object/isUnsafePropKey";
import { iterForOf } from "../iterator/forOf";
import { ArrToMapKeySelectorFn, ArrToMapValueSelectorFn } from "../iterator/types";
import { arrForEach } from "./forEach";

/**
* Creates an object map from array-like, iterator or iterable values.
*
* Keys are generated in stable source order via `keySelector`; later duplicate keys overwrite earlier values.
* Unsafe keys (`__proto__`, `constructor`, `prototype`) are ignored.
* @since 0.15.0
* @group Array
* @example
* ```ts
* const users = [
* { id: "u1", name: "Ada" },
* { id: "u2", name: "Lin" },
* { id: "u1", name: "Ada Updated" }
* ];
*
* arrToMap(users, (value) => value.id, (value) => value.name);
* // { u1: "Ada Updated", u2: "Lin" }
* ```
*/
/*#__NO_SIDE_EFFECTS__*/
export function arrToMap<T>(values: ArrayLike<T> | Iterator<T> | Iterable<T>, keySelector: ArrToMapKeySelectorFn<T>): { [key: string]: T };
/*#__NO_SIDE_EFFECTS__*/
export function arrToMap<T, V>(values: ArrayLike<T> | Iterator<T> | Iterable<T>, keySelector: ArrToMapKeySelectorFn<T>, valueSelector: ArrToMapValueSelectorFn<T, V>): { [key: string]: V };
/*#__NO_SIDE_EFFECTS__*/
export function arrToMap<T, V = T>(values: ArrayLike<T> | Iterator<T> | Iterable<T>, keySelector: ArrToMapKeySelectorFn<T>, valueSelector?: ArrToMapValueSelectorFn<T, V>): { [key: string]: V } {
let result: { [key: string]: V } = {};

function _processValue(value: T, index?: number) {
let valueIndex = index || 0;
let key = keySelector(value, valueIndex);
let keyValue = key + "";
if (!isUnsafePropKey(keyValue)) {
result[keyValue] = valueSelector ? valueSelector(value, valueIndex) : (value as any as V);
}
}

if (isArrayLike(values)) {
arrForEach(values, _processValue);
} else {
iterForOf(values as Iterator<T> | Iterable<T>, _processValue);
}


return result;
}
3 changes: 3 additions & 0 deletions lib/src/funcs/fnBindArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ import { BoundFunction } from "./types";
* bound("!"); // "Hi friend!"
* ```
*/
/*#__NO_SIDE_EFFECTS__*/
export function fnBindArgs<F extends (...args: any[]) => any, T, TArgs extends any[]>(fn: F, thisArg: T, argArray: TArgs): BoundFunction<F, TArgs>;
/*#__NO_SIDE_EFFECTS__*/
export function fnBindArgs<F extends (...args: any[]) => any, T>(fn: F, thisArg: T): F;
/*#__NO_SIDE_EFFECTS__*/
export function fnBindArgs<F extends (...args: any[]) => any, T>(fn: F, thisArg: T, argArray?: any[]): any {
return fn.bind.apply(fn, (argArray ? [ thisArg ].concat(argArray) : [ thisArg ]) as any);
}
4 changes: 4 additions & 0 deletions lib/src/funcs/funcs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ export function fnCall<F extends (...args: any) => any, T>(fn: F, thisArg: T): R
* module2.getX(); // 21
* ```
*/
/*#__NO_SIDE_EFFECTS__*/
export function fnBind<F extends (...args: any[]) => any, T>(fn: F, thisArg: T): F;

/**
Expand Down Expand Up @@ -250,6 +251,7 @@ export function fnBind<F extends (...args: any[]) => any, T>(fn: F, thisArg: T):
* module2.getX(); // 21
* ```
*/
/*#__NO_SIDE_EFFECTS__*/
export function fnBind<F extends (...args: any[]) => any, T, TArgs extends any[]>(fn: F, thisArg: T, ...argArray: TArgs): BoundFunction<F, TArgs>;

/**
Expand All @@ -276,8 +278,10 @@ export function fnBind<F extends (...args: any[]) => any, T, TArgs extends any[]
* bound("friend"); // "Hello friend"
* ```
*/
/*#__NO_SIDE_EFFECTS__*/
export function fnBind<F extends Function, T>(fn: F, thisArg: T, ...argArray: any[]): F;

/*#__NO_SIDE_EFFECTS__*/
export function fnBind<F extends (...args: any[]) => any, T>(fn: F, thisArg: T): any {
return fn.bind.apply(fn, ArrSlice[CALL](arguments, 1) as any);
}
Loading