{"id":13459122,"url":"https://github.com/smartprocure/futil-js","last_synced_at":"2025-04-14T22:08:59.544Z","repository":{"id":16861179,"uuid":"80776197","full_name":"smartprocure/futil-js","owner":"smartprocure","description":"F(unctional) util(ities). Resistance is futile.","archived":false,"fork":false,"pushed_at":"2024-05-02T11:24:36.000Z","size":23901,"stargazers_count":1016,"open_issues_count":33,"forks_count":68,"subscribers_count":27,"default_branch":"master","last_synced_at":"2025-04-10T05:05:00.752Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://smartprocure.github.io/futil-js/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smartprocure.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-02-02T22:47:54.000Z","updated_at":"2025-04-05T20:10:31.000Z","dependencies_parsed_at":"2023-02-19T14:00:26.576Z","dependency_job_id":"9190aab9-0ef0-49f9-903f-7b9866fa453a","html_url":"https://github.com/smartprocure/futil-js","commit_stats":{"total_commits":902,"total_committers":40,"mean_commits":22.55,"dds":0.7882483370288248,"last_synced_commit":"1c095fa4da7f4155b27f530969eda611ec8e8dcf"},"previous_names":["futil-js/futil-js","smartprocure/futil-js"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartprocure%2Ffutil-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartprocure%2Ffutil-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartprocure%2Ffutil-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartprocure%2Ffutil-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smartprocure","download_url":"https://codeload.github.com/smartprocure/futil-js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248968914,"owners_count":21191162,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T09:01:05.143Z","updated_at":"2025-04-14T22:08:59.500Z","avatar_url":"https://github.com/smartprocure.png","language":"JavaScript","readme":"\u003e **NOTE** This file is generated from jsdoc, do not edit directly. Instead, run `npm run docs`\n\n\u003ca href='https://smartprocure.github.io/futil-js/'\u003e\u003cimg src='https://user-images.githubusercontent.com/8062245/28718527-796382ac-7374-11e7-98a3-9791223042a4.png' width='200' alt='futil-js'\u003e\u003c/a\u003e\n\n---\n\n[![CircleCI](https://circleci.com/gh/smartprocure/futil-js.svg?style=svg)](https://circleci.com/gh/smartprocure/futil-js)\n[![npm version](https://badge.fury.io/js/futil-js.svg)](https://badge.fury.io/js/futil-js)\n![dependencies](https://david-dm.org/smartprocure/futil-js.svg)\n[![Code Climate](https://codeclimate.com/github/smartprocure/futil-js/badges/gpa.svg)](https://codeclimate.com/github/smartprocure/futil-js)\n[![Coverage Status](https://coveralls.io/repos/github/smartprocure/futil-js/badge.svg?branch=master)](https://coveralls.io/github/smartprocure/futil-js?branch=master)\n[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)\n[![Try futil-js on RunKit](https://badge.runkitcdn.com/futil-js.svg)](https://npm.runkit.com/futil-js)\n\n[![Sauce Test Status](https://saucelabs.com/browser-matrix/futil.svg)](https://saucelabs.com/u/futil)\n\nA collection of F(unctional) Util(ities). Resistance is futile.\n\nMostly, these are generic utilities that could conceivably be part of a library like [lodash/fp](https://github.com/lodash/lodash/wiki/FP-Guide), but for one reason or another are not.\n\n# Docs\n\nhttps://smartprocure.github.io/futil-js/\n\n# Version History/Changelog\n\nSee our [changelog](https://github.com/smartprocure/futil-js/blob/master/CHANGELOG.md)\n\n# Installing\n\n`npm i -S futil`\nor\n`npm i -S futil-js`\n\nThis package requires `lodash/fp`, so make sure that's available in your app.\n\n# Usage\n\n`import * as F from 'futil'`\nor\n`import F from 'futil'`\nor\n`import {x,y,z} from 'futil'`\n\n# API\n\n## Async\n\n### promiseProps\n\n`{ a: Promise, b: Promise} =\u003e Promise\u003c{a: value, b: value}\u003e`\nLike `Promise.all`, but for objects. Polyfill bluebird Promise.props. Takes an object with promise values and returns a promise that resolves with an object with resolved values instead.\n\n### flowAsync\n\n`(f1, f2, ...fn) -\u003e (...args) =\u003e fn(f2(f1(...args)))`\nLike `_.flow`, but supports flowing together async and non async methods.\nIf nothing is async, it _stays synchronous_.\nAlso, it handles awaiting arrays of promises (e.g. from _.map) with `Promise.all` and objects of promises (e.g. from _.mapValues) with `promiseProps`.\nThis method generally solves most issues with using futil/lodash methods asynchronously. It's like magic!\nNOTE: Main gotchas are methods that require early exit like `find` which can't be automatically async-ified. Also does not handle promises for keys.\nUse `F.resolveOnTree` to await more complexly nested promises.\n\n### flowAsyncDeep\n\n`(f1, f2, ...fn) -\u003e (...args) =\u003e fn(f2(f1(...args)))`\nJust like `F.flowAsync`, except it recurses through return values using `F.resolveOnTree` instead of just `Promise.all` or `promise.props`\n_CAUTION_ Just like `resolveOnTree`, this will mutate intermediate results to resolve promises. This is generally safe (and more performant) but might not always be what you expect.\n\n## Function\n\n### maybeCall\n\n`(fn, a, b) -\u003e fn(a, b)`\nIf `fn` is a function, call the function with the passed-in arguments. Otherwise, return `false`.\n\n### callOrReturn\n\n`(fn, a, b) -\u003e fn(a, b)`\nIf `fn` is a function, call the function with the passed-in arguments. Otherwise, return `fn`.\n\n### boundMethod\n\n`(a, Monoid f) -\u003e f[a] :: f a`\nBinds a function of an object to it's object.\n\n### converge\n\n`(f, [g1, g2, ...gn]) -\u003e a -\u003e f([g1(a), g2(a), ...])`\nhttp://ramdajs.com/docs/#converge. Note that `f` is called on the array of the return values of `[g1, g2, ...gn]` rather than applied to it.\n\n### comply (alias: composeApply)\n\n`(f, g) -\u003e x -\u003e f(g(x))(x)`\nA combinator that combines compose and apply. `f` should be a 2 place curried function. Useful for applying comparisons to pairs defined by some one place function, e.g. `var isShorterThanFather = F.comply(isTallerThan, fatherOf)`\n\n### defer\n\nImplement `defer`, ported from bluebird docs and used by debounceAsync\n\n### debounceAsync\n\nA `_.debounce` for async functions that ensure the returned promise is resolved with the result of the execution of the actual call. Using `_.debounce` with `await` or `.then` would result in the earlier calls never returning because they're not executed - the unit tests demonstate it failing with `_.debounce`.\n\n### flurry\n\n`(f1, f2, ...fn) -\u003e f1Arg1 -\u003e f1Arg2 -\u003e ...f1ArgN -\u003e fn(f2(f1))`\nFlurry is combo of flow + curry, preserving the arity of the initial function. See https://github.com/lodash/lodash/issues/3612.\n\n### uncurry\n\n`(arg -\u003e arg -\u003e arg) -\u003e (arg, arg, arg)`\nUncurry allows curried functions to be called with all its arguments at once. Methods curried with lodash or ramda support this call style out of the box, but hand curried methods. This can happen as the result of function composition.\n\n### recurry\n\n`(n, fn) -\u003e fn(arg1, ...argN)`\nResets curry arity. Useful in scenarios where you have a curried function whose arity isn't detectable by a lodash or ramda curry - such as one constructed via function composition.\n\n### mapArgs\n\n`(mapper, fn) -\u003e (...args) -\u003e fn(...args.map(mapper))`\nReturns a function that applies the mapping operation to all of the arguments of a function. Very similar to \\_.overArgs, but runs a single mapper on all of the args args.\n\n## Iterators\n\n### differentLast\n\n`handleItem -\u003e handleLastItem -\u003e iterator`\nCreates an iterator that handles the last item differently for use in any function that passes `(value, index, list)` (e.g. `mapIndexed`, `eachIndexed`, etc). Both the two handlers and the result are iterator functions that take `(value, index, list)`.\n\n## Logic\n\n### overNone\n\n`([f1, f2, ...fn]) -\u003e !f1(x) \u0026\u0026 !f2(x) \u0026\u0026 ...!fn(x)`\nCreates a function that checks if none of the array of predicates passed in returns truthy for `x`\n\n### ifElse\n\n`(condition, onTrue, onFalse, ...x) -\u003e (T(condition)(...x) ? onTrue(...x) : onFalse(...x))`\nhttp://ramdajs.com/docs/#ifElse. The transform function T supports passing a boolean for `condition` as well as any valid argument of `_.iteratee`, e.g. `myBool = applyTest(x); F.ifElse(myBool, doSomething, doSomethingElse);`\n\n### when\n\n`(condition, onTrue, ...x) -\u003e (T(condition)(...x) ? onTrue(...x) : _.identity(...x))`\nhttp://ramdajs.com/docs/#when. `T` extends `_.iteratee` as above.\n\n### unless\n\n`(condition, onFalse, ...x) -\u003e (T(condition)(...x) ? _.identity(...x) : onFalse(...x))`\nhttp://ramdajs.com/docs/#unless. `T` extends `_.iteratee` as above.\n\n### whenTruthy\n\n`when` curried with `Boolean`\n\n### whenExists\n\n`when` curried with `exists`\n\n### unlessTruthy\n\n`unless` curried with `Boolean`\n\n## Collection\n\n### flowMap\n\n`[f1, f2, ...fn] -\u003e _.map(_.flow(fn))`\nMaps a flow of `f1, f2, ...fn` over a collection.\n\n### findApply\n\n`f -\u003e x -\u003e f(find(f, x))`\nA version of `find` that also applies the predicate function to the result. Useful when you have an existing function that you want to apply to a member of a collection that you can best find by applying the same function.\n\n### map\n\n`(a -\u003e b) -\u003e [a] -\u003e [b]`\nMaps a function over an iterable. Works by default for Arrays and Plain Objects.\n\n### deepMap\n\n`(a -\u003e b) -\u003e [a] -\u003e [b]`\nMaps a function over a recursive iterable. Works by default for nested Arrays, nested Plain Objects and mixed nested Arrays and Plain Objects. Also works for any other iterable data type as long as two other values are sent: a mapping function, and a type checker (See the unit tests for deepMap).\n\n### insertAtIndex\n\n`(index, val, array|string) -\u003e array|string`\nInserts value into an array or string at `index`\n\nExample:\n\n```jsx\n(1, '123', 'hi') -\u003e 'h123i'\n```\n\n### compactMap\n\n`(fn, collection) -\u003e collection`\nMaps `fn` over the input collection and compacts the result.\n\n### sizeBy\n\n`(fn, collection) -\u003e number`\nReturns the size of a collection after filtering by `fn`.\n\n## Convert(\\_In)\n\nlodash/fp is great, but sometimes the curry order isn't exactly what you want.\n\nThese methods provide alternative orderings that are sometimes more convenient.\n\nThe idea of `In` methods is to name them by convention, so when ever you need a method that actually takes the collection first (e.g. a `get` where the data is static but the field is dynamic), you can just add `In` to the end (such as `getIn` which takes the object first)\n\n### getIn\n\nJust like `_.get`, but with `{rearg: false}` so the argument order is unchanged from non fp lodash.\n\n### hasIn\n\nJust like `_.has`, but with `{rearg: false}` so the argument order is unchanged from non fp lodash.\n\n### pickIn\n\nJust like `_.pick`, but with `{rearg: false}` so the argument order is unchanged from non fp lodash.\n\n### includesIn\n\nJust like `_.includes`, but with `{rearg: false}` so the argument order is unchanged from non fp lodash.\n\n## Convert(\\_On)\n\nlodash/fp likes to keep things pure, but sometimes JS can get pretty dirty.\n\nThese methods are alternatives for working with data that--for whatever the use case is--needs to be mutable\n\nAny methods that interact with mutable data will use the `On` convention (as it is some action occuring `On` some data)\n\n### extendOn\n\nJust like `_.extend`, but with `{mutable: true}` so it mutates.\n\n### defaultsOn\n\nJust like `_.defaults`, but with `{mutable: true}` so it mutates.\n\n### mergeOn\n\nJust like `_.merge`, but with `{mutable: true}` so it mutates.\n\n### setOn\n\nJust like `_.set`, but with `{mutable: true}` so it mutates.\n\n### unsetOn\n\nJust like `_.unset`, but with `{mutable: true}` so it mutates.\n\n### pullOn\n\nJust like `_.pull`, but with `{mutable: true}` so it mutates.\n\n### updateOn\n\nJust like `_.update`, but with `{mutable: true}` so it mutates.\n\n## Convert(\\_Indexed)\n\nlodash/fp caps iteratees to one argument by default, but sometimes you need the index.\n\nThese methods are uncapped versions of lodash's methods.\n\nAny method with uncapped iteratee arguments will use the `Indexed` convention.\n\n### mapIndexed\n\nJust like `_.map`, but with `{cap: false}` so iteratees are not capped (e.g. indexes are passed).\n\n### findIndexed\n\nJust like `_.find`, but with `{cap: false}` so iteratees are not capped (e.g. indexes are passed).\n\n### eachIndexed\n\nJust like `_.each`, but with `{cap: false}` so iteratees are not capped (e.g. indexes are passed).\n\n### reduceIndexed\n\nJust like `_.reduce`, but with `{cap: false}` so iteratees are not capped (e.g. indexes are passed).\n\n### pickByIndexed\n\nJust like `_.pickBy`, but with `{cap: false}` so iteratees are not capped (e.g. indexes are passed).\n\n### omitByIndexed\n\nJust like `_.omitBy`, but with `{cap: false}` so iteratees are not capped (e.g. indexes are passed).\n\n### mapValuesIndexed\n\nJust like `_.mapValues`, but with `{cap: false}` so iteratees are not capped (e.g. indexes are passed).\n\n## Array\n\n### compactJoin\n\n`joinString -\u003e [string1, string2, ...stringN] -\u003e string1 + joinString + string2 + joinString ... + stringN`\nJoins an array after compacting. Note that due to the underlying behavior of `_.curry` no default `join` value is supported -- you must pass in some string with which to perform the join.\n\n### dotJoin\n\n`[string1, string2, ...stringN] -\u003e string1 + '.' + string2 + '.' ... + stringN`\nCompacts and joins an array with `.`\n\n### dotJoinWith\n\n`filterFunction -\u003e [string1, string2, ...stringN] -\u003e string1 + '.' + string2 + '.' ... + stringN`\nCompacts an array by the provided function, then joins it with `.`\n\n### repeated\n\n`[a] -\u003e [a]`\nReturns an array of elements that are repeated in the array.\n\n### push\n\n`(val, array) -\u003e array`\nReturn `array` with `val` pushed.\n\n### moveIndex\n\n`(from, to, array) -\u003e array`\nMoves a value from one index to another\n\n### mergeRanges\n\n`([[], [], []]) -\u003e [[], []]`\nTakes any number of ranges and return the result of merging them all.\n\nExample:\n\n```jsx\n[[0,7], [3,9], [11,15]] -\u003e [[0,9], [11,15]]\n```\n\n### isSubset\n\n`([a], [a]) -\u003e boolean`\nDetermines if an array is a subset of another array.\n\n### cycle\n\n`[a, b...] -\u003e a -\u003e b`\nCreates a function that takes an element of the original array as argument and returns the next element in the array (with wrapping). Note that (1) This will return the first element of the array for any argument not in the array and (2) due to the behavior of `_.curry` the created function will return a function equivalent to itself if called with no argument.\n\n### arrayToObject\n\n`(k, v, [a]) -\u003e { k(a): v(a) }`\nCreates an object from an array by generating a key/value pair for each element in the array using the key and value mapper functions.\n\n### keysToObject\n\n`(v, [a]) =\u003e { a: v(a) }`\nConverts and array of keys to an object using a predicate\n\n### zipObjectDeepWith\n\nA version of `_.zipObjectDeep` that supports passing a function to determine values intead of an array, which will be invoked for each key.\n\n### flags\n\n`[a, b] -\u003e {a:true, b:true}`\nConverts an array of strings into an object mapping to true. Useful for optimizing `includes`.\n\n### prefixes\n\n`['a', 'b', 'c'] -\u003e [['a'], ['a', 'b'], ['a', 'b', 'c']]`\nReturns a list of all prefixes. Works on strings, too. Implementations must guarantee that the orginal argument has a length property.\n\n### encoder\n\n`string -\u003e {encode: array -\u003e string, decode: string -\u003e array}`\nCreates an object with encode and decode functions for encoding arrays as strings. The input string is used as input for join/split.\n\n### dotEncoder\n\n`{ encode: ['a', 'b'] -\u003e 'a.b', decode: 'a.b' -\u003e ['a', 'b'] }`\nAn encoder using `.` as the separator\n\n### slashEncoder\n\n`{ encode: ['a', 'b'] -\u003e 'a/b', decode: 'a/b' -\u003e ['a', 'b'] }`\nAn encoder using `/` as the separator\n\n### chunkBy\n\n`(([a], a) -\u003e Boolean) -\u003e [a] -\u003e [[a]]`\nTakes a predicate function and an array, and returns an array of arrays where each element has one or more elements of the original array. Similar to Haskell's [groupBy](http://zvon.org/other/haskell/Outputlist/groupBy_f.html).\n\nThe predicate is called with two arguments: the current group, and the current element. If it returns truthy, the element is appended to the current group; otherwise, it's used as the first element in a new group.\n\n### chunkByValue\n\n`f -\u003e [] -\u003e [[], ...]`\n`chunkBy` when the returned value of an iteratee changes\n\n### toggleElementBy\n\n`bool -\u003e value -\u003e list -\u003e newList`\nJust like toggleElement, but takes an iteratee to determine if it should remove or add. This is useful for example in situations where you might have a checkbox that you want to represent membership of a value in a set instead of an implicit toggle. Used by includeLens.\n\n### toggleElement\n\n`(any, array) -\u003e array`\nRemoves an element from an array if it's included in the array, or pushes it in if it doesn't. Immutable (so it's a clone of the array).\n\n### intersperse\n\n`f -\u003e array -\u003e [array[0], f(), array[n], ....)`\nPuts the result of calling `f` in between each element of the array. `f` is a standard lodash iterator taking the value, index, and list. If `f` is not a function, it will treat `f` as the value to intersperse. See https://ramdajs.com/docs/#intersperse.\n\nExample:\n\n```jsx\n// Example with words (toSentence is basically this flowed into a `_.join('')`):\nF.intersperse(\n  differentLast(\n    () =\u003e 'or',\n    () =\u003e 'or perhaps'\n  ),\n  ['first', 'second', 'third']\n)\n// ['first', 'or', 'second', 'or perhaps', 'third']\n\n// Example with React and JSX:\nlet results = [1, 2, 3]\nreturn (\n  \u003cdiv\u003e\n    \u003cb\u003eResults:\u003c/b\u003e\n    \u003cbr /\u003e\n    {_.flow(\n      _.map((x) =\u003e \u003cb\u003e{x}\u003c/b\u003e),\n      F.intersperse(\n        F.differentLast(\n          () =\u003e ', ',\n          () =\u003e ' and '\n        )\n      )\n    )(results)}\n  \u003c/div\u003e\n)\n// Output:\n// **Results:**\n// **1**, **2** and **3**.\n```\n\n**Note:** This works great with the `differentLast` iterator. Also, `intersperse` can be used with JSX components!\n\n### replaceElementBy\n\n`(fn(array_element), value, array) -\u003e array`\nReplaces an element in an array with `value` based on the boolean result of a function `fn`.\n\n### replaceElement\n\n`(target, value, array) -\u003e array`\nReplaces all elements equal to `target` in an array with `value`.\n\n## Object\n\n### singleObject\n\n`(k, v) -\u003e {k: v}`\nCreates an object with a key and value.\n\n### singleObjectR\n\n`(v, k) -\u003e {k: v}`\nFlipped version of `singleObject`.\n\n### chunkObject\n\n`({a, b}) -\u003e [{a}, {b}]`\nBreaks an object into an array of objects with one key each.\n\n### compactObject\n\nRemove properties with falsey values.\n\nExample:\n\n```jsx\n({ a: 1, b: null, c: false }) -\u003e {a:1}\n```\n\n### isEmptyObject\n\nCheck if the variable is an empty object (`{}`).\n\n### isNotEmptyObject\n\nCheck if the variable is **not** an empty object (`{}`).\n\n### stripEmptyObjects\n\nOmit properties whose values are empty objects.\n\nExample:\n\n```jsx\n{ a:1, b:{}, c:2 } -\u003e {a:1, c:2}\n```\n\n**Note:** (_TODO_ rename to `omitEmptyObjects`)\n\n### pickInto\n\n_TODO_\n\n### renameProperty\n\n`sourcePropertyName -\u003e targetPropertyName -\u003e sourceObject -\u003e sourceObject`\nRename a property on an object.\n\nExample:\n\n```jsx\nrenameProperty('a', 'b', { a: 1 }) -\u003e { b: 1 }\n```\n\n### renamePropertyOn\n\n`sourcePropertyName -\u003e targetPropertyName -\u003e sourceObject -\u003e sourceObject`\nRename a property on an object.\n**NOTE**:Mutates the object\n\nExample:\n\n```jsx\nrenamePropertyOn('a', 'b', { a: 1 }) -\u003e { b: 1 }\n```\n\n### popProperty\n\n`k -\u003e { k: v } -\u003e v`\nRemoves a property from an object and returns the removed value.\nLike `F.unsetOn`, but returns the removed value instead of the mutated object. Similar to .pop() on arrays, but for objects.\nSupports nested properties using dot notation.\nNOTE: Mutates the object. If you don't want mutation, you probably want `_.unset` for the object or `_.get` for the value.\n\n### unwind\n\n`k -\u003e { k: [a, b] } -\u003e [{ k: a }, { k: b }]`\nJust like mongo's `$unwind`: produces an array of objects from an object and one of its array-valued properties. Each object is constructed from the original object with the array value replaced by its elements. Unwinding on a nonexistent property or a property whose value is not an array returns an empty array.\n\nExample:\n\n```jsx\nF.unwind('b', [{ a: true, b: [1, 2] }])\n//=\u003e [{ a: true, b: 1 }, { a: true, b: 2 }]\n```\n\n### unwindArray\n\n`k -\u003e [{ k: [a, b] }] -\u003e [{ k: a }, { k: b }]`\nUnwinds an array of objects instead of a single object, as you might expect if you're used to mongo's `$unwind`. Alias for `(key, data) =\u003e _.flatMap(F.unwind(key), data)`\n\nExample:\n\n```jsx\nF.unwindArray('b', [\n  { a: true, b: [1, 2] },\n  { a: false, b: [3, 4] },\n])\n//=\u003e [\n//=\u003e  { a: true, b: 1 },\n//=\u003e  { a: true, b: 2 },\n//=\u003e  { a: false, b: 3 },\n//=\u003e  { a: false, b: 4 },\n//=\u003e ]\n```\n\n### flattenObject\n\nFlatten an object with the paths for keys.\n\nExample:\n\n```jsx\n{ a: { b: { c: 1 } } } =\u003e { 'a.b.c' : 1 }\n```\n\n### unflattenObject\n\nUnlatten an object with the paths for keys.\n\nExample:\n\n```jsx\n{ 'a.b.c' : 1 } =\u003e { a: { b: { c: 1 } } }\n```\n\n### matchesSignature\n\nReturns true if object keys are only elements from signature list. (but does not require all signature keys to be present)\n\n### matchesSome\n\nSimilar to `_.matches`, except it returns true if 1 or more object properties match instead of all of them. See https://github.com/lodash/lodash/issues/3713.\n\n### compareDeep\n\nChecks if an object's property is equal to a value.\n\n### mapProp\n\n_Deprecated in favor of lodash `update`_ Applies a map function at a specific path\n\nExample:\n\n```jsx\nmapProp(double, 'a', {a: 2, b: 1}) -\u003e {a: 4, b: 1}\n```\n\n### getOrReturn\n\n`_.get` that returns the target object if lookup fails\n\n### alias\n\n`_.get` that returns the prop if lookup fails\n\n### aliasIn\n\nFlipped `alias`\n\n### cascade\n\nA `_.get` that takes an array of paths (or functions to return values) and returns the value at the first path that matches. Similar to `_.overSome`, but returns the first result that matches instead of just truthy (and supports a default value)\n\n### cascadeIn\n\nFlipped cascade\n\n### cascadeKey\n\nA `_.get` that takes an array of paths and returns the first path that matched\n\n### cascadePropKey\n\nA `_.get` that takes an array of paths and returns the first path that exists\n\n### cascadeProp\n\nA `_.get` that takes an array of paths and returns the first value that has an existing path\n\n### unkeyBy\n\n`newKey -\u003e {a:x, b:y} -\u003e [{...x, newKey: a}, {...y, newKey: b}]`\nOpposite of `_.keyBy`. Creates an array from an object where the key is merged into the values keyed by `newKey`.\n\nExample:\n\n```jsx\nF.unkeyBy('_key')({ a: { status: true}, b: { status: false }) -\u003e [{ status: true, _key: 'a' }, { status: false, _key: 'b' }]\n```\n\n**Note:** Passing a falsy value other than `undefined` for `newKay` will result in each object key being pushed into its corresponding return array member with itself as value, e.g. `F.unkeyBy('')({ a: { status: true}, b: { status: false }) -\u003e [{ status: true, a: 'a' }, { status: false, b: 'b' }]`. Passing `undefined` will return another instance of F.unkeyBy.\n\n### simpleDiff\n\n`(from, to) -\u003e simpleDiff`\nProduces a simple flattened (see `flattenObject`) diff between two objects. For each (flattened) key, it produced a `from` and a `to` value. Note that this will omit any values that are not present in the deltas object.\n\n### simpleDiffArray\n\n`(from, to) -\u003e [simpleDiffChanges]`\nSame as `simpleDiff`, but produces an array of `{ field, from, to }` objects instead of `{ field: { from, to } }`\n\n### diff\n\n`(from, to) -\u003e diff`\nSame as `simpleDiff`, but also takes in count deleted properties.\n**Note:** We're considering not maintaining this in the long term, so you might probably have more success with any existing library for this purpose.\n\n### diffArray\n\n`(from, to) -\u003e [diffChanges]`\nSame as `simpleDiffArray`, but also takes in count deleted properties.\n**Note:** We're considering not maintaining this in the long term, so you might probably have more success with any existing library for this purpose.\n\n### pickOn\n\nA `_.pick` that mutates the object\n\n### mergeAllArrays\n\nLike `_.mergeAll`, but concats arrays instead of replacing. This is basically the example from the lodash `mergeAllWith` docs.\n\n### invertByArray\n\n`{ a: [x, y, z], b: [x] } -\u003e { x: [a, b], y: [a], z: [a] }`\nSimilar to `_.invert`, but expands arrays instead of converting them to strings before making them keys.\n\n### stampKey\n\n`key -\u003e { a: { x: 1 }, b: { y: 2 } } -\u003e { a: { x: 1, key: 'a' }, b: { y: 2, key: 'b' } }`\nIterates over object properties and stamps their keys on the values in the field name provided.\n\n### omitNil\n\n`_.omitBy` using `_.isNil` as function argument.\n\n### omitNull\n\n`_.omitBy` using `_.isNull` as function argument.\n\n### omitBlank\n\n`_.omitBy` using `F.isBlank` as function argument.\n\n### omitEmpty\n\n`_.omitBy` using `_.isEmpty` as function argument.\n\n### mergeOverAll\n\n`([f, g], ...args) -\u003e {...f(...args), ...g(...args)}`\nComposition of `_.over` and `_.mergeAll`. Takes an array of functions and an arbitrary number of arguments, calls each function with those arguments, and merges the results. Can be called with `mergeOverAll([f, g], x, y)` or `mergeOverAll([f, g])(x, y)`.\n**Note:** For functions that do not return objects, `_.merge`'s behavior is followed: for strings and arrays, the indices will be converted to keys and the result will be merged, and for all other primitives, nothing will be merged.\n\n### mergeOverAllWith\n\n`(customizer, [f, g], ...args) -\u003e {...f(...args), ...g(...args)}`\nA customizable `mergeOverAll` that takes a function of the form `(objValue, srcValue) -\u003e newValue` as its first argument; see [`_.mergeWith`](https://lodash.com/docs/latest#mergeWith). Both the customizer and array of functions can be partially applied.\n\n### mergeOverAllArrays\n\n`([f, g], ...args) -\u003e {...f(...args), ...g(...args)}`\nA customized `mergeOverAll` that applies the array-merging behavior of `mergeAllArrays`.\n\n### getWith\n\n`(x -\u003e y) -\u003e k -\u003e {k: x} -\u003e y`\nLike `_.get`, but accepts a customizer function which is called on the value to transform it before it is returned. Argument order is `(customizer, path, object)`.\n\n### expandObject\n\n`(transform: obj -\u003e newObj) -\u003e obj -\u003e { ...obj, ...newObj }`\nAccepts a transform function and an object. Returns the result of applying the transform function to the object, merged onto the original object. `expandObject(f, obj)` is equivalent to `mergeOverAll([_.identity, f], obj)`.\n\n### expandObjectBy\n\n`key -\u003e (transform: x -\u003e newObj) -\u003e (obj: { key: x }) -\u003e { ...obj, ...newObj }`\nExpands an object by transforming the value at a single key into a new object, and merging the result with the original object. Similar to `expandObject`, but the argument order is `(key, transform, object)`, and the transform function is called on the value at that key instead of on the whole object.\n\n### commonKeys\n\n`(x, y) -\u003e [keys]`\nTakes two objects and returns the keys they have in common\n\n### firstCommonKey\n\n`(x, y) -\u003e key`\nTakes two objects and returns the first key in `y` that x also has\n\n### updateIfExists\n\n`(path, updater, object) -\u003e object`\nLike `_.update`, but does not call the iteratee if the path is missing on the object\n\n### updateIfExistsOn\n\n`(path, updater, object) -\u003e object`\nLike `F.updateOn`, but does not call the iteratee if the path is missing on the object\n_Mutates_ the object\n\n### updatePathsOn\n\n`({ path: transform }, target) -\u003e obj`\nSimilar to ramda's `R.evolve`, but supports lodash iteratees and nested paths.\nApplies transforms to the target object at each path. The transform function is called with the value at that path, and the result is set at that path.\nTransforms are **not** called for paths that do not exist in the target object.\nTransform functions support lodash iteratee shorthand syntax.\nDeep paths are supported by nesting objects and by dotted the keys\n\nNote: _Mutates_ the target object for performance. If you don't want this, use `updatePaths` or clone first.\n\n### updateAllPathsOn\n\n`({ path: transform }, target) -\u003e obj`\nSimilar to ramda's `R.evolve`, but supports lodash iteratees and nested paths.\nApplies transforms to the target object at each path. The transform function is called with the value at that path, and the result is set at that path.\nTransforms **are** called for paths that do not exist in the target object.\nTransform functions support lodash iteratee shorthand syntax.\nDeep paths are supported by nesting objects and by dotted the keys\n\nNote: _Mutates_ the target object for performance. If you don't want this, use `updateAllPaths` or clone first.\n\n### updateAllPaths\n\n`({ path: transform }, target) -\u003e obj`\nSimilar to ramda's `R.evolve`, but supports lodash iteratees and nested paths.\nApplies transforms to the target object at each path. The transform function is called with the value at that path, and the result is set at that path.\nTransforms **are** called for paths that do not exist in the target object.\nTransform functions support lodash iteratee shorthand syntax.\nDeep paths are supported by nesting objects and by dotted the keys\n\n_Note_ Deep clones prior to executing to avoid mutating the target object, but mutates under the hood for performance (while keeping it immutable at the surface). If you're doing this in a place where mutating is safe, you might want `F.updateAllPathsOn` to avoid the `_.deepClone`\n\n### updatePaths\n\n`({ path: transform }, target) -\u003e obj`\nSimilar to ramda's `R.evolve`, but supports lodash iteratees and nested paths.\nApplies transforms to the target object at each path. The transform function is called with the value at that path, and the result is set at that path.\nTransforms are **not** called for paths that do not exist in the target object.\nTransform functions support lodash iteratee shorthand syntax.\nDeep paths are supported by nesting objects and by dotted the keys\n\n_Note_ Deep clones prior to executing to avoid mutating the target object, but mutates under the hood for performance (while keeping it immutable at the surface). If you're doing this in a place where mutating is safe, you might want `F.updatePathsOn` to avoid the `_.deepClone`\n\n### matchesBy\n\n`(criteria: object, object: object) -\u003e boolean`\nTakes a criteria object and an object to test against it, and returns true if all the values in the criteria match the values in the object\nCriteria values can be functions or values to compare against\nSupports dot notation for deep paths\n\n### matchesBySome\n\n`(criteria: object, object: object) -\u003e boolean`\nTakes a criteria object and an object to test against it, and returns true if some of the values in the criteria match the values in the object\nCriteria values can be functions or values to compare against\nSupports dot notation for deep paths\n\n## String\n\n### wrap\n\n`(pre, post, content) -\u003e pre + content + post`\nWraps a string with pre and post unless content is nil (and replaces )\n\n### parens\n\n`'asdf' -\u003e '(asdf)'`\nWraps a string in parenthesis.\n\n### trimStrings\n\nMaps `_.trim` through all the strings of a given object or array.\n\n### autoLabel\n\n`string -\u003e string`\nConverts strings like variable names to labels (generally) suitable for GUIs, including support for acronyms and numbers. It's basically `_.startCase` with acronym and number support.\n\n### autoLabelOption\n\n`string -\u003e {value:string, label:string}`\nCreates a `{value, label}` which applies `autoLabel` the string parameter on puts it on the label property, with the original on the value property. You can also pass in an object with value or with both value and label.\n\n### autoLabelOptions\n\n`[string] -\u003e [{value:string, label:string}]`\nApplies `autoLabelOption` to a collection. Useful for working with option lists like generating select tag options from an array of strings.\n\n### toSentenceWith\n\n`(separator, lastSeparator, array) =\u003e string`\nJust like `toSentence`, but with the ability to override the `separator` and `lastSeparator`\n\nExample:\n\n```jsx\n(' - ', ' or ', ['a', 'b', 'c']) -\u003e 'a - b or c'\n```\n\n### toSentence\n\n`array =\u003e string`\nJoins an array into a human readable string. See https://github.com/epeli/underscore.string#tosentencearray-delimiter-lastdelimiter--string\n\nExample:\n\n```jsx\n['a', 'b', 'c'] -\u003e 'a, b and c'\n```\n\n### uniqueStringWith\n\n`(fn, array) -\u003e string -\u003e string`\nAllows passing a \"cachizer\" function (`array -\u003e object`) to override the way `uniqueString`'s initial array is converted into a cache object. Can be curried to create a custom `uniqueString` function, eg: `let myUniqueString = uniqueStringWith(myFunc)`\n\nLike `uniqueString`, the resulting deduplication function exposes `cache` and `clear()` properties.\n\nExample:\n\n```jsx\nlet uniqueStringStripDigits = uniqueStringWith(\n  _.countBy(_.replace(/(\\d+)$/, ''))\n)\nlet dedupe = uniqueStringStripDigits(['foo', 'foo42', 'foo3000'])\ndedupe('foo') //-\u003e 'foo3'\nuniqueStringWith(_.identity, dedupe.cache)('foo') //-\u003e 'foo4'\n```\n\n### uniqueString\n\n`array -\u003e string -\u003e string`\nReturns a function that takes a string and de-duplicates it against an internal cache. Each time this function is called, the resulting deduplicated string is added to the cache. Exposes `cache` and `clear()` properties to read and clear the cache, respectively.\n\nExample:\n\n```jsx\nlet dedupe = uniqueString()\n_.map(dedupe, ['foo', 'foo', 'foo']) //-\u003e ['foo', 'foo1', 'foo2']\ndedupe.cache //-\u003e { foo: 3, foo1: 1, foo2: 1 }\ndedupe.clear()\ndedupe.cache //-\u003e {}\ndedupe('foo') //-\u003e 'foo'\n```\n\n### crunchWhitespace\n\n`string -\u003e string`\nReplaces whitespace substrings with a single space and trims leading/trailing whitespace\n\n## Regex\n\n### testRegex\n\n`regex -\u003e string -\u003e bool`\nJust like ramda test, creates a function to test a regex on a string.\n\n### makeRegex\n\n`options:string -\u003e string -\u003e regex`\nA curried implementation of `RegExp` construction.\n\n### makeAndTest\n\n`options:string -\u003e string -\u003e (string -\u003e bool)`\nMakes and tests a RegExp with makeRegex and testRegex.\n\n### matchAllWords\n\n`string -\u003e string -\u003e bool`\nReturns true if the second string matches all of the words in the first string.\n\n### matchAnyWord\n\n`string -\u003e string -\u003e bool`\nReturns true if the second string matches any of the words in the first string.\n\n### allMatches\n\n`regex -\u003e string -\u003e [{text: string, start: number, end: number}]`\nReturns an array of matches with start/end data\n\nExample:\n\n```jsx\nF.allMatches(/a/g, 'vuhfaof') -\u003e [ { text: 'a', start: 4, end: 5 } ]\n```\n\n### postings\n\n`regex -\u003e string -\u003e [[number, number]]`\nReturns an array of postings (position ranges) for a regex and string to test, e.g. `F.postings(/a/g, 'vuhfaof') -\u003e [[4, 5]]`\n\n### postingsForWords\n\n`words -\u003e string -\u003e [[[number, number]]]`\nTakes a string of words and a string to test, and returns an array of arrays of postings for each word.\n\nExample:\n\n```jsx\nF.postingsForWords('she lls', 'she sells sea shells')\n// [\n//   [[0, 3], [14, 17]]\n//   [[6, 9], [17, 20]]\n// ]\n```\n\n### highlight\n\n`start -\u003e end -\u003e pattern -\u003e input -\u003e highlightedInput`\nWraps the matches for `pattern` found in `input` with the strings `start` and `end`. The `pattern` argument can either be a string of words to match, or a regular expression.\n\nExample:\n\n```jsx\nlet braceHighlight = F.highlight('{', '}')\nbraceHighlight('l o', 'hello world') //-\u003e \"he{llo} w{o}r{l}d\"\nbraceHighlight(/l+\\w/, 'hello world') //-\u003e \"he{llo} wor{ld}\"\n```\n\n## Math\n\n### greaterThanOne\n\n`number -\u003e bool`\nReturns true if number is greater than one.\n\n## Lang\n\nLanguage level utilities\n\n### isPromise\n\n`x -\u003e bool`\nA utility that checks if the argument passed in is of type promise\n\n### throws\n\nJust throws whatever it is passed.\n\n### tapError\n\nTap error will run the provided function and then throw the first argument. It's like `_.tap` for rethrowing errors.\n\n### exists (alias: isNotNil)\n\nNegated `_.isNil`\n\n### isMultiple\n\n`(Array\u003cT\u003e | string | {length}) -\u003e bool`\nReturns true if the input has a `length` property \u003e 1, such as arrays, strings, or custom objects with a lenth property\n\n### append\n\n`(a, b) =\u003e b + a`\nA curried, flipped `_.add`. The flipping matters for strings, e.g. `F.append('a')('b') -\u003e 'ba'`\n\n### isBlank\n\n`x -\u003e bool`\nDesigned to determine if something has a meaningful value, like a ux version of truthiness. It's false for everything except null, undefined, '', [], and {}. Another way of describing it is that it's the same as falsiness except 0 and false are truthy and {} is falsey. Useful for implementing \"required\" validation rules.\n\n### isNotBlank\n\n`x -\u003e bool`\nOpposite of `isBlank`\n\n### isBlankDeep\n\n`f -\u003e x -\u003e bool`\nRecurses through an object's leaf properties and passes an array of booleans to the combinator, such as `_.some`, `_.every`, and `F.none`\n\n## Lens\n\nA lens is a getter and setter pair. You use them to write code that needs to read _and_ write a value (like a method to flip a boolean switch, or a React component that reads and writes some state) without worrying about the implementation.\n\nFunctions that operate on lenses can handle a few different \"shorthand\" structures. This is similar to lodash's `_.iteratee` (which allows their methods to treat strings, objects, or functions as shorthand predicates)\n\nA lens can be any of these formats:\n\n`({ get, set })`\nAn object with a `get` function and `set` function.\nFound in: MobX \"boxed observables\"\nExample Usage: `F.flip({ get, set })`\n\n`([value, setter])`\nAn array of the `value` and a `setter` function to change it.\nFound in: React's useState hook\nExample Usage: `F.flip([value, setter])`\n\n`(lookup, object)`\nA lookup path and object pair e.g. ('key', object). The lookup path is anything you can pass to `_.get` (so nested paths with `.` or as an array are supported)\nFound in: MobX observable objects, native JS objects\nExample Usage: `F.flip(lookup, object)`\n\n`(x =\u003e {})`\nA function which returns the value when called with no arguments and sets it when called with one.\nFound in: Knockout observables, jQuery plugin APIs\nExample Usage: `F.flip(x =\u003e {})`\n\n`(getter, setter)`\nA getter and setter pair.\nFound in: Anywhere you have a getter and setter function\nExample Usage: `F.flip(getter, setter)`\n\n\u003e Note: Setter methods are generally mutable (unlike Ramda's lenses, for example).\n\nWe've included a few example \"bindings\" on `F.domLens`. These take a lens and return an object that's useful in a DOM context (like React or raw JS). In React terms, they're methods that generate the props you'd use to do two way binding to a lens.\n![lens meme](http://giphygifs.s3.amazonaws.com/media/1jnyRP4DorCh2/giphy.gif)\n\n### functionLens\n\nTakes a value and returns a function lens for that value. Mostly used for testing and mocking purposes.\n\n### objectLens\n\nTakes a value and returns a object lens for that value. Mostly used for testing and mocking purposes.\n\n### set\n\n`propertyValue -\u003e Lens -\u003e object.propertyName`\nSets the value of the lens, regardless of its format\n\n### fnToObj\n\nConverts a function lens an object lens. Mostly used for testing and mocking purposes.\n\n### objToFn\n\nConverts an object lens to a function lens. Mostly used for testing and mocking purposes.\n\n### lensProp\n\n`propertyName -\u003e object -\u003e { get: () -\u003e object.propertyName, set: propertyValue -\u003e object.propertyName }`\nCreates an object lens for a given property on an object. `.get` returns the value at that path and `set` places a new value at that path. Supports deep paths like lodash get/set.\nYou typically won't use this directly since it is supported implicitly.\n\n### lensOf\n\nTakes an object and returns an object with lenses at the values of each path. Basically `mapValues(lensProp)`. Typically you would use the implicit `(key, object)` format instead.\n\n### includeLens\n\n`value -\u003e arrayLens -\u003e includeLens`\nAn include lens represents membership of a value in a set. It takes a value and lens and returns a new lens - kind of like a \"writeable computed\" from MobX or Knockout. The view and set functions allow you to read and write a boolean value for whether or not a value is in an array. If you change to true or false, it will set the underlying array lens with a new array either without the value or with it pushed at the end.\n\n### view\n\n`Lens -\u003e object.propertyName`\nGets the value of the lens, regardless of its format\n\n### views\n\n`Lens -\u003e (() -\u003e object.propertyName)`\nReturns a function that gets the value of the lens, regardless of its format\n\n### sets\n\nCreates a function that will set a lens with the provided value\n\n### setsWith\n\nTakes an iteratee and lens and creates a function that will set a lens with the result of calling the iteratee with the provided value\n\n### flip\n\nTakes a lens and negates its value\n\n### on\n\nReturns a function that will set a lens to `true`\n\n### off\n\nReturns a function that will set a lens to `false`\n\n### domLens.value\n\n`lens -\u003e {value, onChange}`\nTakes a lens and returns a value/onChange pair that views/sets the lens appropriately. `onChange` sets with `e.target.value` (or `e` if that path isn't present).\n\nExample:\n\n```jsx\nlet Component = () =\u003e {\n  let state = React.useState('')\n  return \u003cinput {...F.domLens.value(state)}\u003e\n}\n```\n\n### domLens.checkboxValues\n\n`(value, lens) -\u003e {checked, onChange}`\nCreates an includeLens and maps view to checked and set to `onChange` (set with `e.target.checked` or `e` if that path isn't present)\n\n### domLens.hover\n\n`lens -\u003e { onMouseEnter, onMouseLeave }`\nTakes a lens and returns on onMouseEnter which calls `on` on the lens and onMouseLeave which calls `off`. Models a mapping of \"hovering\" to a boolean.\n\n### domLens.focus\n\n`lens -\u003e { onFocus, onBlur }`\nTakes a lens and returns on onFocus which calls `on` on the lens and onBlur which calls `off`. Models a mapping of \"focusing\" to a boolean.\n\n### domLens.targetBinding\n\n`field -\u003e lens -\u003e {[field], onChange}`\nUtility for building lens consumers like `value` and `checkboxValues`\n\n### domLens.binding\n\n`(field, getValue) -\u003e lens -\u003e {[field], onChange}`\nEven more generic utility than targetBinding which uses `getEventValue` to as the function for a setsWith which is mapped to `onChange`.\n\n### stateLens\n\n`([value, setValue]) -\u003e lens`\nGiven the popularity of React, we decided to include this little helper that converts a `useState` hook call to a lens. Ex: `let lens = stateLens(useState(false))`. You generally won't use this directly since you can pass the `[value, setter]` pair directly to lens functions\n\n## Aspect\n\nAspects provide a functional oriented implementation of Aspect Oriented Programming.\nAn aspect wraps a function and allows you run code at various points like before and after execution.\nNotably, aspects in this library allow you to have a shared state object between aspects and are very useful for automating things like status indicators, etc on functions.\n\nThere is a _lot_ of prior art in the javascript world, but most of it assumes a vaguely object oriented context.\nThe implementation in `futil-js` is done in just 20 lines of code and seems to capture all of the use cases of AOP.\n\n**Note**: To do OO style AOP with this these aspects, just use lodash's `_.update` method and optionally `boundMethod` from `futil` if `this` matters\n\n**Caveat**: While you can and should compose (or `_.flow`) aspects together, don't put non aspects in the middle of the composition. Aspects rely on a `.state` property on the wrapped function that they propagate through, but the chain will break if a non-aspect is mixed in between. Additionally, if you need external access to the state, make sure the aspects are the outer most part of the composition so the `.state` property will be available on the result of the composition.\n\nThere are a few basic aspects included on `F.aspects` (E.g. `var loggedFunc = F.aspect(F.aspects.logs)(func)`) because they seem to be universally useful.\nAll of the provided aspects take an `extend` function to allow customizing the state mutation method (e.g. in mobx, you'd use `extendObservable`).\nIf null, they default to `defaultsOn` from `futil-js` - check the unit tests for example usage.\n\n### aspect\n\n`{options} -\u003e f -\u003e aspectWrapped(f)`\nThe aspect api takes an options object and returns a function which takes a function to wrap.\nThe wrapped function will be decorated with a `state` object and is equivalent to the original function for all arguments.\n\nOptions supports the following parameters:\n\n| Name                                    | Description                                                                                                                         |\n| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |\n| `init: (state) -\u003e ()`                   | A function for setting any inital state requirements. Should mutate the shared state object.                                        |\n| `after: (result, state, params) -\u003e ()`  | Runs after the wrapped function executes and recieves the shared state and the result of the function. Can be async.                |\n| `before: (params, state) -\u003e ()`         | Runs before the wrapped function executes and receves the shared state and the params passed to the wrapped function. Can be async. |\n| `onError: (error, state, params) -\u003e ()` | Runs if the wrapped function throws an error. If you don't throw inside this, it will swallow any errors that happen.               |\n| `always: (state, params) -\u003e ()`         | Runs after the wrapped function whether it throws an error or not, similar to a `Promise.catch`                                     |\n\nExample:\n\n```jsx\nlet exampleAspect = aspect({\n  before: () =\u003e console.log('pre run'),\n  after: () =\u003e console.log('post run'),\n})\nlet f = () =\u003e console.log('run')\nlet wrapped = exampleAspect(f)\nwrapped()\n// Logs to the console:\n// pre run\n// run\n// post run\n```\n\n### aspectSync\n\nThis is a synchronous version of `aspect`, for situations when it's not desirable to `await` a method you're adding aspects to. The API is the same, but things like `onError` won't work if you pass an async function to the aspect.\n\n### aspects.logs\n\nLogs adds a `logs` array to the function state and just pushes in results on each run\n\n### aspects.error\n\nCaptures any exceptions thrown and set it on an `error` error it puts on state\n\n### aspects.errors\n\nCaptures any exceptions thrown and pushes them sequentially into an `errors` array it puts on state\n\n### aspects.status\n\nAdds a `status` property that is set to `processing` before the wrapped function runs and `succeeded` when it's done or `failed` if it threw an exception. Also adds shortcuts on state for `processing`, `succeeded`, and `failed`, which are booleans which are based on the value of `status`. Also adds a `setStatus` method which is used internally to update these properties.\n\n### aspects.deprecate\n\nUtility for marking functions as deprecated - it's just a `before` with a console.warn. Takes the name of thing being deprecated, optionally deprecation version, and optionally an alternative and returns a higher order function which you can wrap deprecated methods in. This is what's used internally to mark deprecations. Includes a partial stack trace as part of the deprecation warning.\n\n### aspects.clearStatus\n\nSets `status` to null after provided timeout (default is 500ms) elapses. If a null timeout is passed, it will never set status to null.\n\n### aspects.concurrency\n\nPrevents a function from running if it's state has `processing` set to true at the time of invocation\n\n### aspects.command\n\nFlows together `status`, `clearStatus`, `concurrency`, and `error`, taking `extend` and `timeout` as optional parameters to construct the aspect\n\n## Tree\n\nAll tree functions take a traversal function so that you can customize how to traverse arbitrary nested structures.\n\n_Note_: Be careful about cyclic structures that can result in infinite loops, such as objects with references to itself. There are cases where you'd intentionally want to visit the same node multiple times, such as traversing a directed acyclic graph (which would work just fine and eventually terminate, but would visit a node once for each parent it has connected to it) - but it's up to the user to be sure you don't create infinite loops.\n\n### isTraversable\n\n`node -\u003e bool`\nA default check if something can be traversed - currently it is arrays and plain objects.\n\n### traverse\n\n`node -\u003e [...childNodes]`\nThe default traversal function used in other tree methods if you don't supply one. It returns false if it's not traversable or empty, and returns the object if it is.\n\n### walk\n\n`traverse -\u003e (pre, post=_.noop) -\u003e tree -\u003e x`\nA depth first search which visits every node returned by `traverse` recursively. Both `pre-order` and `post-order` traversals are supported (and can be mixed freely). `walk` also supports exiting iteration early by returning a truthy value from either the `pre` or `post` functions. The returned value is also the return value of `walk`. The pre, post, and traversal functions are passed the current node as well as the parent stack (where parents[0] is the direct parent).\n\n### walkAsync\n\n`traverse -\u003e (pre, post=_.noop) -\u003e async tree -\u003e x`\nA version of `walk` which supports async traversals.\n\n### transformTree\n\n`traverse -\u003e _iteratee -\u003e tree -\u003e newTree`\nStructure preserving pre-order depth first traversal which clones, mutates, and then returns a tree. Basically `walk` with a `_.cloneDeep` first (similar to a tree map because it preserves structure). `_iteratee` can be any suitable argument to `_.iteratee` https://lodash.com/docs/4.17.5#iteratee\n\n### reduceTree\n\n`traverse -\u003e (accumulator, initialValue, tree) -\u003e x`\nJust like `_.reduce`, but traverses over the tree with the traversal function in `pre-order`.\n\n### writeTreeNode\n\nDefault `writeNode` for `mapTree`. It writes the node to the parent at the given index.\nUsing the traversal function with tree iteratee properties to find children.\n\n### mapTree\n\n`(traverse, writeNode) -\u003e f -\u003e tree -\u003e newTree`\nStructure preserving tree map! `writeNode` informs how to write a single node, but the default will generally work for most cases. The iteratee is passed the standard `node, index, parents, parentIndexes` args and is expected to return a transformed node.\n\n### mapTreeLeaves\n\n`(traverse, writeNode) -\u003e f -\u003e tree -\u003e newTree`\nLike `mapTree`, but only operates on lead nodes. It is a convenience method for `mapTree(next, writeNode)(F.unless(next, mapper), tree)`\n\n### treeToArrayBy\n\n`traverse -\u003e f -\u003e tree -\u003e [f(treeNode), f(treeNode), ...]`\nLike `treeToArray`, but accepts a customizer to process the tree nodes before putting them in an array. The customizer is passed the standard `node, index, parents, parentIndexes` args and is expected to return a transformed node. It's `_.map` for trees - but it's not called treeMap because it does not preserve the structure as you might expect `map` to do. See `mapTree` for that behavior.\n\n### treeToArray\n\n`traverse -\u003e tree -\u003e [treeNode, treeNode, ...]`\nFlattens the tree nodes into an array, simply recording the node values in pre-order traversal.\n\n### leavesBy\n\n`traverse -\u003e f -\u003e tree -\u003e [f(treeNode), f(treeNode), ...]`\nLike `leaves`, but accepts a customizer to process the leaves before putting them in an array.\n\n### leaves\n\n`traverse -\u003e tree -\u003e [treeNodes]`\nReturns an array of the tree nodes that can't be traversed into in `pre-order`.\n\n### treeLookup\n\n`(traverse, buildIteratee) -\u003e ([_iteratee], tree) -\u003e treeNode`\nLooks up a node matching a path, which defaults to lodash `iteratee` but can be customized with buildIteratee. The `_iteratee` members of the array can be any suitable arguments for `_.iteratee` https://lodash.com/docs/4.17.5#iteratee\n\n### keyTreeByWith\n\n`traverse -\u003e transformer -\u003e _iteratee -\u003e tree -\u003e result`\nSimilar to a keyBy (aka groupBy) for trees, but also transforms the grouped values (instead of filtering out tree nodes). The transformer takes three args, the current node, a boolean of if the node matches the current group, and what group is being evaluated for this iteratee. The transformer is called on each node for each grouping. `_iteratee` is any suitable argument to `_.iteratee`, as above.\n\n### treeKeys\n\n`(x, i, xs, is) =\u003e [i, ...is]`\nA utility tree iteratee that returns the stack of node indexes\n\n### treeValues\n\n`(x, i, xs) =\u003e [x, ...xs]`\nA utility tree iteratee that returns the stack of node values\n\n### treePath\n\n`(build, encoder) -\u003e treePathBuilderFunction`\nCreates a path builder for use in `flattenTree`. By default, the builder will look use child indexes and a dotEncoder. Encoder can be an encoding function or a futil `encoder` (an object with encode and decode functions)\n\n### propTreePath\n\n`prop -\u003e treePathBuilderFunction`\nCreates a path builder for use in `flattenTree`, using a slashEncoder and using the specified prop function as an iteratee on each node to determine the keys.\n\n### flattenTree\n\n`traverse -\u003e buildPath -\u003e tree -\u003e result`\nCreates a flat object with a property for each node, using `buildPath` to determine the keys. `buildPath` takes the same arguments as a tree walking iteratee. It will default to a dot tree path.\n\n### findNode\n\n`(traverse) -\u003e (iteratee, tree) -\u003e treeNode`\nFinds the first node matching the iteratee in pre-order traversal. The\niteratee can be any suitable argument to `_.iteratee`\nhttps://lodash.com/docs/4.17.5#iteratee\n\n### resolveOnTree\n\n`(traverse, writeNode) -\u003e tree -\u003e result`\nResolves all Promise nodes of a tree and replaces them with the result of calling `.then`\nExposed on `F.tree` as `resolveOn`\n_CAUTION_ This method mutates the tree passed in. This is generally safe and more performant (and can be intuited from the `On` convention in the name), but it's worth calling out.\n\n### tree\n\n`(traverse, buildIteratee, writeNode) -\u003e { walk, walkAsync, transform, reduce, toArrayBy, toArray, leaves, leavesBy, lookup, keyByWith, traverse, flatten, flatLeaves, map, mapLeaves, resolveOn }`\nTakes a traversal function and returns an object with all of the tree methods pre-applied with the traversal. This is useful if you want to use a few of the tree methods with a custom traversal and can provides a slightly nicer api.\nExposes provided `traverse` function as `traverse`\n","funding_links":[],"categories":["JavaScript","Libraries"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmartprocure%2Ffutil-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmartprocure%2Ffutil-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmartprocure%2Ffutil-js/lists"}