Changelog — Helpers by version
v3.0.4 (Latest)
Section titled “v3.0.4 (Latest)”| Function | Category | Description |
|---|---|---|
createMutex | promise | Creates a mutex: a lock allowing at most one holder at a time, queueing excess `acquire()` callers in FIFO order. A createSemaphore with a single permit. A factory function rather than a class, matching this package’s other stateful helpers (`debounce`, `throttle`): the returned object closes over an internal semaphore. Typical use: deduplicating concurrent callers of a non-reentrant operation, e.g. making sure only one in-flight token-refresh call happens at a time while others wait for it. |
createSemaphore | promise | Creates a semaphore limiting concurrent access to `permits` holders at a time, queueing excess `acquire()` callers in FIFO order (first to call `acquire` is first granted a permit when one frees up). A factory function rather than a class, matching this package’s other stateful helpers (`debounce`, `throttle`): the returned object closes over its internal queue/counter. Use for concurrency limiting, e.g. rate-limiting calls to an external API. For mutual-exclusion (at most one holder), see createMutex, which is a semaphore with one permit. |
filterAsync | array | The async counterpart to `Array.prototype.filter`: runs `predicate` for every item and resolves to the items whose predicate was truthy, in their original relative order. `predicate` runs for every item up front (respecting `concurrency`) before any filtering happens — unlike the sync `.filter()`, there’s no short-circuiting, since every predicate call may already be in flight by the time an earlier one resolves. |
forEachAsync | array | The async counterpart to `Array.prototype.forEach`: runs `fn` for every item for its side effects, discarding any return value. Prefer mapAsync when you need the results — this only exists to signal that intent clearly, same as the sync `forEach`/`map` pair. |
mapAsync | array | The async counterpart to `Array.prototype.map`: applies `fn` to every item and resolves to an array of the results, in input order — regardless of which call finishes first. `Array.prototype.map(asyncFn)` alone doesn’t do this: it returns an array of *unresolved* promises (`Promise |
v3.0.3
Section titled “v3.0.3”| Function | Category | Description |
|---|---|---|
camelCaseKeys | object | Recursively transforms every key of a plain object (including keys nested inside arrays and nested objects) to camelCase. Handles snake_case, kebab-case, PascalCase, and space-separated keys. Non-plain-object values (arrays’ items aside) — `Date`, `Map`, `Set`, class instances, primitives — are left untouched, only their position is walked into. An entry whose transformed key is a prototype-polluting string (`__proto__`, `constructor`, `prototype`) is silently skipped, same as the rest of `@helpers4/object`. |
countBy | map | Groups the entries of a Map by a derived key and counts how many fall into each group. |
countBy | set | Groups the values of a Set by a derived key and counts how many fall into each group. |
every | map | Checks if every entry of a Map satisfies the predicate. Short-circuits on the first mismatch. |
filter | map | Creates a new Map containing only the entries for which the predicate returns true. |
filter | set | Creates a new Set containing only the values for which the predicate returns true. |
findKey | map | Returns the first key of a Map whose entry satisfies the predicate, in insertion order. |
findValue | map | Returns the first value of a Map whose entry satisfies the predicate, in insertion order. |
hasValue | map | Checks whether a value exists anywhere in a Map (`Map.prototype.has` checks keys, not values). Uses `Object.is`-style equality (via `===`, with `NaN` matching `NaN`). |
isBrowser | guard | Checks whether the code is currently running in a browser-like environment (`window` and `window.document` both defined). Note: some hybrid test environments (e.g. happy-dom, jsdom) define both `window` and Node’s `process` at the same time — this only reports on `window`‘s presence, it does not imply `isNode` is false. Use both together if you need to distinguish a real browser from a DOM-emulating Node test environment. |
isJSON | guard | Checks whether a value is a string containing valid, parseable JSON text. Distinct from isJSONValue, which checks an already-parsed runtime value’s *shape* — this checks a *string* before you parse it. Pairs naturally with `@helpers4/object`‘s `safeJsonParse`, which is the safe-parse counterpart once you know the string is valid — this helper reuses it internally rather than re-implementing the parse/catch itself. |
isJSONArray | guard | Checks whether a value is an array whose every element is a valid JSON value (see isJSONValue). |
isJSONObject | guard | Checks whether a value is a plain object whose every own value is a valid JSON value (see isJSONValue). |
isJSONValue | guard | Checks whether a value is composed entirely of JSON-representable types: `string`, finite `number`, `boolean`, `null`, arrays of JSON values, or plain objects of JSON values. `undefined`, functions, symbols, `NaN`/`Infinity`, and non-plain objects (`Date`, `Map`, `Set`, class instances…) all return `false`, since none survive a real `JSON.stringify` / `JSON.parse` round-trip unchanged. Circular references also return `false` for the same reason, instead of recursing forever. |
isLength | guard | Checks whether a value is a valid array-like `length`: a non-negative safe integer (`0 <= value <= Number.MAX_SAFE_INTEGER`). |
isNode | guard | Checks whether the code is currently running in a Node.js-like environment (`process.versions.node` is defined — also true in Electron’s Node context). Note: some hybrid test environments (e.g. happy-dom, jsdom) define both `window` and Node’s `process` at the same time — this only reports on `process.versions.node`‘s presence, it does not imply `isBrowser` is false. Use both together if you need to distinguish plain Node.js from a DOM-emulating Node test environment. |
kebabCaseKeys | object | Recursively transforms every key of a plain object (including keys nested inside arrays and nested objects) to kebab-case. Handles snake_case, camelCase, PascalCase, and space-separated keys. Non-plain-object values — `Date`, `Map`, `Set`, class instances, primitives — are left untouched, only their position is walked into. An entry whose transformed key is a prototype-polluting string (`__proto__`, `constructor`, `prototype`) is silently skipped, same as the rest of `@helpers4/object`. |
map | set | Creates a new Set with each value transformed by a function. If two values transform to the same result, duplicates collapse — the returned Set may be smaller than the input. |
mapDeep | object | Recursively transforms the keys and/or values of a plain object — the deep counterpart to map, which only transforms the top level. Descends into nested plain objects and arrays of them; `Date`, `Map`, `Set`, class instances, and primitives are left untouched (only their position is walked into, matching cloneDeep’s notion of what counts as a plain-data node worth recursing into). Both callbacks are optional and default to identity (no transformation). `mapKey` is called with the *original* key and value (before any recursive value transform); `mapValue` receives the already-recursed value. Entries whose mapped key is a prototype-polluting string (`__proto__`, `constructor`, `prototype`) are silently skipped, same as map. Array elements also go through `mapValue` (with their stringified index as `key`, since arrays have no property keys of their own) — so values inside a plain array, not just object properties, get transformed too. `mapKey` is never called for array elements, since there is no key to rename. |
mapKeys | map | Creates a new Map with the same values but with each key transformed by a function. If two entries derive the same new key, the later one (in insertion order) wins. |
mapValues | map | Creates a new Map with the same keys but with each value transformed by a function. |
meanBy | array | Calculates the arithmetic mean of numbers derived from each item of an array via an iteratee. Returns `NaN` for an empty array, `null`, or `undefined` — matching sumBy, which treats `null`/`undefined` as empty rather than throwing. Pairs with sumBy for aggregate operations. |
median | array | Calculates the median (middle value) of an array of numbers. For an even-length array, returns the average of the two middle values. Returns `NaN` for an empty array. Does not mutate the input array. The median is the 50th percentile — this delegates to it rather than duplicating its sort/interpolation logic. |
pascalCaseKeys | object | Recursively transforms every key of a plain object (including keys nested inside arrays and nested objects) to PascalCase. Handles camelCase, snake_case, kebab-case, and space-separated keys. Non-plain-object values — `Date`, `Map`, `Set`, class instances, primitives — are left untouched, only their position is walked into. An entry whose transformed key is a prototype-polluting string (`__proto__`, `constructor`, `prototype`) is silently skipped, same as the rest of `@helpers4/object`. |
percentile | array | Calculates the p-th percentile of an array of numbers using linear interpolation between the closest ranks. Returns `NaN` for an empty array. Does not mutate the input array. |
reduce | map | Reduces a Map to a single value by applying a function to each entry, in insertion order. |
snakeCaseKeys | object | Recursively transforms every key of a plain object (including keys nested inside arrays and nested objects) to snake_case. Handles camelCase, PascalCase, kebab-case, and space-separated keys. Non-plain-object values — `Date`, `Map`, `Set`, class instances, primitives — are left untouched, only their position is walked into. An entry whose transformed key is a prototype-polluting string (`__proto__`, `constructor`, `prototype`) is silently skipped, same as the rest of `@helpers4/object`. |
some | map | Checks if at least one entry of a Map satisfies the predicate. Short-circuits on the first match. |
sortKeys | object | Creates a new object with the same entries as the input, but with its own keys sorted. Shallow only — nested objects are copied as-is, their keys are not re-sorted. Key order matters for things like `JSON.stringify` diffs and snapshot stability; this does not change equality (`{a:1,b:2}` and `{b:2,a:1}` are already equal), just iteration/serialization order. Note: integer-index-like keys (`“0”`, `“1”`, `“42”`…) are always iterated first, in numeric order, by the JS engine itself — no object key ordering can override that language behavior. A prototype-polluting key (`__proto__`, `constructor`, `prototype`) is silently skipped, same as the rest of `@helpers4/object`. |
sumBy | array | Calculates the sum of numbers derived from each item of an array via an iteratee. `null` and `undefined` are treated as empty arrays and return `0`. |
titleCaseKeys | object | Recursively transforms every key of a plain object (including keys nested inside arrays and nested objects) to Title Case. Handles camelCase, snake_case, kebab-case, and space-separated keys. Non-plain-object values — `Date`, `Map`, `Set`, class instances, primitives — are left untouched, only their position is walked into. An entry whose transformed key is a prototype-polluting string (`__proto__`, `constructor`, `prototype`) is silently skipped, same as the rest of `@helpers4/object`. Note: unlike the other `*CaseKeys` variants, `titleCase` joins words with spaces (e.g. `‘User Name’`) — those keys are only usable via bracket access (`obj[‘User Name’]`), not dot notation. Useful for display-facing structures (form labels, table headers), not wire formats. |
toMapByKey | map | Builds a Map from an iterable of items, keyed by a derived key. When two items derive the same key, the later item wins (last-write-wins, matching `Map.prototype.set` semantics). Named `toMapByKey`, not `keyBy` (lodash’s name for the same idea) — lodash’s `_.keyBy` returns a plain object, not a `Map`; the `to |
toMapByKey | set | Builds a Map from a Set, keyed by a derived key. When two values derive the same key, the later value (in iteration order) wins (last-write-wins, matching `Map.prototype.set`). Named `toMapByKey`, not `keyBy` (lodash’s name for the same idea) — lodash’s `_.keyBy` returns a plain object, not a `Map`; the `to |
v3.0.2
Section titled “v3.0.2”| Function | Category | Description |
|---|---|---|
parallelSettle | promise | Runs an array of async functions with a concurrency limit, partitioning the outcomes instead of rejecting on the first failure — parallel with settle’s fulfilled/rejected split. Takes functions (not already-created promises, unlike settle) so it controls *when* each one starts: that’s what makes the concurrency limit meaningful. At most `concurrency` functions run at any time; as soon as one settles, the next queued function starts. |
v3.0.1
Section titled “v3.0.1”| Function | Category | Description |
|---|---|---|
DEFAULT_PERCENTAGE_TIERS | ci | Default tiers, geared towards coverage/quality-gate style percentages. Follows shields.io color conventions: brightgreen >= 100, green >= 90, yellow >= 80, orange >= 60. |
formatProgressBar | string | Formats a value as a text progress bar, repeating `filledChar`/`emptyChar` across `width` cells proportional to `value / max`. `value` is clamped to `[0, max]` before computing the ratio — out-of-range values (negative, above `max`) produce an empty or fully-filled bar instead of throwing. Non-finite `max` (`NaN`, `Infinity`) is treated as `0`, yielding an empty bar. |
incrementPrerelease | version | Increments the prerelease portion of a semantic version — the semantics `npm version prerelease —preid |
percentageToTier | ci | Maps a numeric percentage to a tier (icon, color, label) using configurable thresholds. Tiers are matched by their highest `min` that is `<= value`; a `value` below every tier’s `min` (e.g. a negative percentage, or custom tiers that don’t cover down to 0) falls back to the tier with the lowest `min` — there’s always a match as long as `tiers` is non-empty. |
v3.0.0
Section titled “v3.0.0”| Function | Category | Description |
|---|---|---|
argbToRgb | color | Converts a 32-bit packed ARGB integer (as used by e.g. Chromium’s `Local State` profile `background_color` field) into a CSS `rgb()` string. The alpha byte (top 8 bits) is read but discarded — the result is always opaque. |
Brand | type | Brands a base type `T` with a phantom tag `B` to create a nominal type. Two `Brand<string, ‘UserId’>` and `Brand<string, ‘Email’>` are structurally identical strings at runtime, but TypeScript treats them as distinct types at the call site — preventing accidental mix-ups. Use a const-assertion cast at the creation boundary: ```ts type UserId = Brand<string, ‘UserId’>; const toUserId = (s: string): UserId => s as UserId; ``` |
clone | object | Creates a shallow copy of a value — one level deep, unlike cloneDeep. Unlike a plain `{ …value }` spread, this correctly reconstructs `Date`, `Map`, `Set`, and arrays instead of producing an empty (or wrong-shaped) plain object for them. Primitives are returned as-is. Any other object (including class instances not listed above) has its own enumerable string keys shallow-copied into a plain object — the same fallback `cloneDeep` uses, so the two stay consistent for types neither one special-cases. |
combineSortFns | array | Chains multiple sort functions into a single comparator: the first function decides the order unless it reports a tie (`0`), in which case the next function is tried, and so on. Lets you compose comparators of different kinds — e.g. a boolean-property comparator from createSortByBooleanFn followed by a string-property comparator from `createSortByStringFn` — which a single multi-key call cannot express, since that coerces every key to the same comparison type. |
createSortByBooleanFn | array | Creates a sort function for objects by a boolean property. Values are coerced with `Boolean()` before comparing, so `null`, `undefined`, `0`, and `”` behave as `false`, and any other truthy value behaves as `true`. |
dedent | string | Strips the common leading whitespace from every line of a multi-line string, and trims a single leading/trailing blank line if present. Lets you write readable, indented multi-line strings in source code (typically template literals) without that indentation leaking into the output. |
DeepGet | type | Resolves the value type at a given `Path` within `T`. Returns `unknown` when any key in `Path` is not present in the corresponding level of `T`. An empty path resolves to `T` itself. A path segment that goes through an optional property keeps the result nullable (`V | undefined`) instead of degrading to `unknown`. |
DeepSet | type | Produces the type of `T` after replacing the value at `Path` with `V`. When a key in `Path` is absent from the corresponding level of `T`, that level (and everything below it) is added as a new field instead of resolving to `never` — mirroring how `set()` creates intermediate objects at runtime. |
escapeRegExp | string | Escapes regular expression metacharacters (`. * + ? ^ $ { } ( ) | [ ] \`) in a string so it can be safely embedded in a `RegExp` pattern. Use this before building a `RegExp` from untrusted or dynamic input — without it, characters like `.` or `(` change the pattern’s meaning instead of being matched literally. |
flatten | object | Flattens a nested object into a single-level object whose keys are the dot-notation path to each leaf value. The inverse of unflatten. Only **plain objects** are recursed into — arrays, `Date`, `Map`, `RegExp`, class instances, and empty plain objects `{}` are kept as opaque leaf values. This keeps `flatten`/`unflatten` a clean, invertible pair: arrays can’t be losslessly told apart from plain objects once reduced to dotted keys, so this implementation doesn’t attempt it. Caveat shared by every dotted-path flattening scheme: a key that itself contains a literal `.` is indistinguishable from real nesting once flattened (`{ ‘a.b’: 1 }` and `{ a: { b: 1 } }` both produce `{ ‘a.b’: 1 }`). |
hexToRgb | color | Parses a hex color string (`#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa` — the leading `#` is optional) into its RGB(A) channels. |
hslToRgb | color | Converts an HSL(A) color into RGB(A). |
isCssColor | guard | Checks whether a value is a syntactically-safe, plain CSS color: a hex color (`#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`), a functional notation (`rgb()`, `rgba()`, `hsl()`, `hsla()`), or a single-word named color (`red`, `rebeccapurple`). Intended to sanitize a color value before interpolating it into inline `style`/`cssText` — it does not implement the full CSS color grammar or validate named colors against the real keyword list, it only rejects characters (`{`, `}`, `;`, “) or shapes that could smuggle extra CSS declarations into the surrounding rule. |
isSet | guard | Checks if a value is a Set instance. |
isWeakMap | guard | Checks if a value is a WeakMap instance. |
isWeakSet | guard | Checks if a value is a WeakSet instance. |
KeysOfType | type | Extracts the keys of `T` whose values extend `V`. Optional properties are matched by their non-nullable value type, so an optional `string` property still counts as a `string` key. |
Nullable | type | Adds `null` to a type (`T | null`). Useful as a shorthand when explicit nullability should be expressed in function signatures or generic constraints. |
Nullish | type | Adds `null` and `undefined` to a type (`T | null | undefined`). Alias of Maybe. |
omitBy | object | Creates a new object without the own enumerable entries for which `predicate` returns `true`. Complements omit for when the keys to remove aren’t known ahead of time — `omit` takes an explicit key list, `omitBy` takes a predicate. |
OmitByValue | type | Constructs a type by omitting all entries of `T` whose values extend `V`. Optional properties are matched by their non-nullable value type, so an optional `string` property is omitted the same as a required one. |
OptionalKeys | type | Extracts the optional keys of an object type `T`. |
parseDuration | date | Parses a compact duration string (as produced by formatDuration, e.g. `“1h 23m 45s”`) back into milliseconds. Accepts any combination/order of `h`/`m`/`s` segments, with or without spaces between them (`“1h30m”` and `“1h 30m”` both work). A single leading `-` negates the whole duration, matching `formatDuration`‘s output. Returns `null` when no valid segment is found. |
parsePropertyPath | object | Parses a dot/bracket-notation property path into an array of string/number key segments — the same notation accepted by get and set. - Dot separators (`.`) split segments; each segment becomes a string key. - Bracket indices (`[n]`) become number keys. - A leading `.` is treated as “current level” and stripped before parsing, so `.[0]` ≡ `[0]` and `.a.b` ≡ `a.b`. - Empty string (or a bare `.`) returns `[”]` (addresses the `”` key on the root object). - Consecutive dots (`a..b`) produce an empty-string segment: `[‘a’, ”, ‘b’]`. Results are cached (up to 500 distinct path strings, oldest evicted first) since real-world callers tend to reuse a small, fixed set of literal paths. |
pickBy | object | Creates a new object with only the own enumerable entries for which `predicate` returns `true`. Complements pick for when the keys to keep aren’t known ahead of time — `pick` takes an explicit key list, `pickBy` takes a predicate. |
PickByValue | type | Constructs a type by picking all entries of `T` whose values extend `V`. Optional properties are matched by their non-nullable value type, so an optional `string` property is picked the same as a required one. |
Prettify | type | Flattens an intersection type into a single readable object type. IDE tooltips for intersections like `A & B & C` often show the raw intersection instead of the resolved shape. Wrapping with `Prettify` forces TypeScript to expand and display the fully-resolved type. Distributes over unions, so each member is prettified independently instead of collapsing to their shared keys. |
removeDiacritics | string | Removes diacritical marks (accents) from a string, e.g. `‘café’` → `‘cafe’`. Works by Unicode-decomposing each character into its base letter plus combining marks (`‘é’` → `‘e’` + a combining acute accent), then stripping the marks. Same technique already used internally by `slugify`. |
replaceOrAppend | array | Returns a new array with the first item matching `predicate` replaced by `item` — or `item` appended at the end if no match is found. The common “upsert into a list” pattern. |
RequiredKeys | type | Extracts the required (non-optional) keys of an object type `T`. |
rgbToHex | color | Converts an RGB(A) color into a hex color string. `r`/`g`/`b` are clamped to 0-255 and rounded to the nearest integer before formatting. The alpha channel is only appended (as `#rrggbbaa`) when it is below 1 — fully opaque colors format as the plain 6-digit `#rrggbb`. |
rgbToHsl | color | Converts an RGB(A) color into HSL(A). `h`/`s`/`l` are rounded to 1 decimal place to avoid floating-point noise. |
settle | promise | Runs an array of promises concurrently and partitions the outcomes instead of rejecting on the first failure, unlike `Promise.all`. Built on top of `Promise.allSettled`, but returns fulfilled values and rejection reasons already split apart so callers don’t need to inspect `status` themselves. No concurrency limit, and none is possible here: `promises` are already-constructed `Promise` objects, and a promise starts running the moment it’s created — by the time `settle` receives the array, every promise in it is already in flight. There is nothing left to throttle. If you need to cap how many run at once (e.g. many file reads or requests), use parallelSettle instead, which takes functions (`() => Promise |
symmetricDifference | array | Returns the symmetric difference between two arrays: items present in exactly one of the two arrays (in either, but not both). `null` and `undefined` are treated as empty arrays. |
toggle | array | Returns a new array with `item` removed if present, or appended if absent — the common “toggle a selection” pattern. By default, presence is checked with `SameValueZero` equality (like `Array.prototype.includes`). Pass `key` to compare by a derived identity instead — useful for toggling objects by id rather than by reference. |
unary | function | Creates a function that calls `fn` with only its first argument, discarding any others. Prevents the classic footgun where a callback expecting extra positional arguments is passed directly to `Array.prototype.map`: `[‘1’, ‘2’, ‘3’].map(parseInt)` silently passes the array index as `parseInt`‘s radix argument, producing `[1, NaN, NaN]`. |
unescapeHtml | string | Unescapes the HTML entities `&`, `<`, `>`, `”`, and `'` back to `&`, `<`, `>`, `”`, and `’`. This is the exact inverse of escapeHtml — it only recognizes the five entities that function produces, not the full HTML entity set (no ` `, no numeric code points beyond `'`, etc.). |
unflatten | object | Rebuilds a nested object from a single-level object whose keys are dot-notation paths. The inverse of flatten. Uses set internally, so intermediate nodes are always created as plain objects (never arrays — see flatten’s doc for why), and any key segment equal to `__proto__`, `constructor`, or `prototype` is silently rejected (same prototype-pollution guard as `set`). |
UnionToIntersection | type | Converts a union type to an intersection type: `A | B | C` → `A & B & C`. Uses conditional-type distribution and the contravariant position of a function parameter to collapse the union into an intersection. |
unset | object | Removes the value at a dot/bracket-notation path or explicit key array, mutating the object in place. Uses the same path syntax as get/set. A missing intermediate segment is a no-op (nothing to remove), not an error. As with `set`, any path containing a string segment equal to `__proto__`, `constructor`, or `prototype` is rejected and the object is returned unchanged. The removed key stops appearing in `Object.keys`/`for…in` — unlike setting it to `undefined`, which would keep the key present. |
update | object | Updates the value at a path by applying a function to its current value, creating intermediate objects as needed. Equivalent to `set(obj, path, updater(get(obj, path)))` in a single call. Uses the same path syntax and type-inference rules as get and set — see those for the full behavior (string vs. `PropertyKey[]` paths, prototype-pollution guarding, etc.). |
ValueOf | type | Produces a union of all value types of an object type `T`. |
Looking for older releases? See the v2 changelog.