@naturalcycles/js-lib
Standard library for universal (browser + Node.js) javascript

Design
Inspired by Lodash,
bluebird,
promise-fun and other useful small packages.
Designed to play well with the rest of opinionated "Natural Cycles JS Platform" (link pending). This
package is the lowest-level production dependency (not devDependency
) of the Platform. Almost
everything else depends on it.
All functions in this package are exported in index.ts
(flat), no namespacing is used. So, to
avoid conflicts and "global import namespace" pollution , all functions are prefixed with an
underscore (e.g _.pick
becomes _pick
), with some exceptions (later). Promise functions are
prefixed with p
, e.g pMap
.
Decorators are _prefixed and PascalCased (e.g @_Debounce
).
_
is to be consistent with other naming in this package. PascalCase is to distinguish decorators from similar functions that are not decorators. Example:\_debounce
is a function (lodash-based),\_Debounce
is a decorator (used as@\_Debounce
).
PascalCase convention follows Angular/Ionic convention (but doesn't follow TypeScript documentation
convention; we had to pick one).
Interfaces and Classes are named as usual (no prefix, PascalCase, e.g AppError
).
Q: Why not just use lodash?
A:
- We believe Lodash is outdated (many functions are pre-ES6 / obsolete by ES6).
- Because it has so many outdated functions - its size is bigger, and solutions to tree-shake exist,
but complicated.
- First-class TypeScript support (all code in this repo is TypeScript).
This package is intended to be 0-dependency, "not bloated", tree-shakeable. Supported by reasonably
modern Browsers and Node.js latest LTS.
To fulfil that requirement it exports ESM version (for Browsers) as es2015, to support Browsers that
don't natively support async/await (es2017).
Exports default CJS version for Node as es2017 (with native async/await, for better performance,
async stack-traces, etc).
Mutation
All function does NOT mutate the arguments by default.
Many functions support "mutation flag", which can be set to true
to perform a mutation.
For example:
const obj = { a: 'a', b: 'b' }
const obj2 = _pick(obj, ['a'])
_pick(obj, ['a'], true)
Highlights
API
Promise utils
Inspired by bluebird and Sindre's
promise-fun packages.
"Copy-pasted" (with small adjustments) here, because:
-
Bluebird is outdated (pre-ES6)
-
p-*
packages are amazing, but not all of them are needed. Some of them are very much needed
though.
-
To fix issues with Types. Here, everything is TypeScript, so, first class support and sync.
-
To fix issues with IDE auto-imports, which is still quite bad for "default exported" packages.
Downside is that (as every fork) we lose "auto-update" possibility from these packages. We believe
it's not as bad, because packages imported here have mature API and stability (example: pMap).
pMap
Based on https://github.com/sindresorhus/p-map
pProps
Based on https://github.com/sindresorhus/p-props
pFilter
Based on https://github.com/sindresorhus/p-filter
pDefer
Allows to create a "ResolvablePromise", which is a normal native Promise (so, can be awaited, etc),
extended with .resolve()
and .reject()
methods, so you can control it. Similar to jQuery's
Deferred, or RxJS's Subject (which is both an Observable and allows to emit values).
pRetry
Based on https://github.com/sindresorhus/p-retry
pDelay
Based on https://github.com/sindresorhus/delay
pHang
pState
pBatch
Object
_pick
Inspired by Lodash's _.pick.
_pick({ a: 'a', b: 'b', c: 'c' }, ['a', 'b'])
_pick({ a: 'a', b: 'b', c: 'c' }, ['a'])
_pick({ a: 'a', b: 'b', c: 'c' }, ['d'])
_pick({ a: 'a', b: 'b', c: 'c' }, [])
const obj = { a: 'a', b: 'b', c: 'c' }
const obj2 = _pick(obj, ['a'], true)
obj === obj2
_omit
Inspired by Lodash's _.omit. The opposite of _pick
.
_omit({ a: 'a', b: 'b', c: 'c' }, ['a', 'b'])
_omit({ a: 'a', b: 'b', c: 'c' }, ['a'])
_omit({ a: 'a', b: 'b', c: 'c' }, ['d'])
_omit({ a: 'a', b: 'b', c: 'c' }, [])
const obj = { a: 'a', b: 'b', c: 'c' }
const obj2 = _omit(obj, ['a', 'b'], true)
obj === obj2
_mask
Similar to _omit
, but supports deep object access via dot-notation (a.b
). Supports "mutation
flag" argument.
const obj = {
a: 'a',
b: {
b1: 'b1',
b2: 'b2',
},
}
_mask(obj, ['b.b1'])
_mask(obj, ['b.b1'], true)
_filterFalsyValues
_filterUndefinedValues
_filterObject
_mapKeys
_mapValues
_mapObject
_objectNullValuesToUndefined
_deepCopy
_isPrimitive
_merge
_deepTrim
_sortObjectDeep
_unset
_getKeyByValue
_invert
_invertMap
_get
_set
_has
_deepEquals
_stringMapValues
Needed due to https://github.com/microsoft/TypeScript/issues/13778
Only affects typings, no runtime effect.
_stringMapEntries
Needed due to https://github.com/microsoft/TypeScript/issues/13778
Only affects typings, no runtime effect.
Array
_range
_chunk
_flatten
_flattenDeep
_uniq
_uniqBy
_by
_sortBy
_findLast
Like .find()
, but tries to find an element from the END of the array.
_takeWhile, _takeRightWhile, _dropWhile, _dropRightWhile
const a = [1, 2, 3, 4, 5, 2, 1]
_takeWhile(a, r => r <= 3)
_takeRightWhile(a, r => r <= 3)
_dropWhile(a, r => r <= 3)
_dropRightWhile(a, r => r <= 3)
_countBy
_countBy(['a', 'aa', 'aaa', 'aaa', 'aaaa'], r => r.length)
_intersection
Inspired by Lodash's _.intersection.
_intersection([2, 1], [2, 3])
_intersection([1], [2])
_intersection()
_intersection([1])
_difference
Inspired by Lodash's _.difference
_difference([2, 1], [2, 3])
_difference([1], [2])
_difference([1], [1])
_difference([1])
String
_capitalize
_upperFirst
_lowerFirst
_split
_substringBefore
_substringBeforeLast
_substringAfter
_substringAfterLast
_truncate
_truncateMiddle
Number
_inRange
_inRange(-10, 1, 5)
_inRange(1, 1, 5)
_inRange(3, 1, 5)
_inRange(5, 1, 5)
_inRange(7, 1, 5)
Json
_jsonParseIfPossible
_stringifyAny
Time
_ms
_since
_debounce
_throttle
Math
_randomInt
SimpleMovingAverage
Units
_kb, _mb, _gb, _hb
Decorators
@_Debounce
@_Throttle
@_LogMethod
@_Memo
@_Retry
Error utils
AggregatedError
_tryCatch
AppError
HttpError
ErrorObject
HttpErrorResponse
_anyToAppError
_anyToErrorObject
_anyToErrorMessage
_errorToErrorObject
_errorObjectToAppError
_errorObjectToHttpError
_appErrorToErrorObject
_appErrorToHttpError
_isHttpErrorResponse
_isHttpErrorObject
_isErrorObject
Types
Things that should exist in type-fest, but don't (yet).
StringMap
const m: StringMap = { a: 'a' }
const m: StringMap<number> = { a: 5 }
Packaging
engines.node >= Node.js LTS
main: dist/index.js
: commonjs, es2017 - targeting Node.jsmodule: dist-esm/index.js
: esm, es2015 - targeting Browserstypes: dist/index.d.ts
: typescript types/src
folder with source *.ts
files included