{"id":26042561,"url":"https://github.com/drmats/js-toolbox","last_synced_at":"2025-04-10T05:35:11.522Z","repository":{"id":55976035,"uuid":"132446836","full_name":"drmats/js-toolbox","owner":"drmats","description":"Library of useful JS utilities.","archived":false,"fork":false,"pushed_at":"2024-02-27T11:45:07.000Z","size":2404,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T06:51:51.443Z","etag":null,"topics":["array","async","codec","es6","func","javascript","math","string","struct","type","typescript","utils"],"latest_commit_sha":null,"homepage":"https://drmats.github.io/js-toolbox/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/drmats.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2018-05-07T10:47:59.000Z","updated_at":"2024-03-05T10:22:09.000Z","dependencies_parsed_at":"2024-06-21T03:52:11.911Z","dependency_job_id":"c14c97c2-e816-4a44-be6e-a3f7a75ac0fa","html_url":"https://github.com/drmats/js-toolbox","commit_stats":null,"previous_names":[],"tags_count":93,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drmats%2Fjs-toolbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drmats%2Fjs-toolbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drmats%2Fjs-toolbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drmats%2Fjs-toolbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/drmats","download_url":"https://codeload.github.com/drmats/js-toolbox/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248163862,"owners_count":21058037,"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":["array","async","codec","es6","func","javascript","math","string","struct","type","typescript","utils"],"created_at":"2025-03-07T16:34:09.276Z","updated_at":"2025-04-10T05:35:11.492Z","avatar_url":"https://github.com/drmats.png","language":"TypeScript","readme":"# js-toolbox\n\nUseful JavaScript utilities (with TypeScript typings).\n\n[![npm version](https://img.shields.io/npm/v/@xcmats/js-toolbox.svg)](https://www.npmjs.com/package/@xcmats/js-toolbox)\n[![npm license](https://img.shields.io/npm/l/@xcmats/js-toolbox.svg)](https://www.npmjs.com/package/@xcmats/js-toolbox)\n[![GitHub top language](https://img.shields.io/github/languages/top/drmats/js-toolbox.svg)](https://github.com/drmats/js-toolbox)\n[![GitHub code size](https://img.shields.io/github/languages/code-size/drmats/js-toolbox.svg)](https://github.com/drmats/js-toolbox)\n[![GitHub tag](https://img.shields.io/github/tag/drmats/js-toolbox.svg)](https://github.com/drmats/js-toolbox)\n\n```bash\n$ npm i @xcmats/js-toolbox\n```\n\nWorks in [node.js](https://nodejs.org/) and browser environments\n(use [webpack](https://webpack.js.org/) or [Rollup](https://rollupjs.org/)\nto bundle it with your project).\n\n\u003cbr /\u003e\n\n\n\n\n## index\n\n* [documentation](#documentation)\n* [play in your browser](#play-in-your-browser)\n* [use the package](#use-the-package)\n    - [install](#install)\n    - [play in node.js](#play-in-nodejs)\n    - [example use in ES6 modules code](#example-use-in-es6-modules-code)\n* [use the source](#use-the-source)\n* [namespaces](#namespaces)\n    - [array](#array-utilities)\n    - [async](#asynchronous-programming-helpers)\n    - [codec](#typedarray-codersdecoders)\n    - [func](#functional-programming-tools)\n    - [math](#basic-math)\n    - [string](#string-utilities)\n    - [struct](#data-structure-manipulation-tools)\n    - [type](#type-helpers)\n    - [utils](#uncategorized-utilities)\n* [examples](#examples)\n    - [array manipulation](#array-manipulation)\n    - [asynchronous programming](#asynchronous-programming)\n    - [base64 encoding and decoding](#base64-encoding-and-decoding)\n    - [hex encoding and decoding](#hex-encoding-and-decoding)\n    - [byte array manipulation](#byte-array-manipulation)\n    - [functional programming](#functional-programming)\n    - [simple math](#simple-math)\n    - [operating on strings](#operating-on-strings)\n    - [data structure manipulation](#data-structure-manipulation)\n    - [type primitives](#type-primitives)\n* [notes](#notes)\n* [license](#license)\n\n\u003cbr /\u003e\n\n\n\n\n## documentation\n\n\u003e [API Reference](https://drmats.github.io/js-toolbox/)\n\n\u003cbr /\u003e\n\n\n\n\n## play in your browser\n\n\u003e [RunKit with @xcmats/js-toolbox](https://npm.runkit.com/@xcmats/js-toolbox)\n\n* list member functions ([link](https://runkit.com/embed/r1c9vte7yz3b)):\n\n    ```javascript\n    var jsToolbox = require(\"@xcmats/js-toolbox\")\n\n    Object.keys(jsToolbox).sort()\n    ```\n\n    \u003e ```javascript\n    \u003e [ \"Y\",\n    \u003e   \"access\",\n    \u003e   \"add\",\n    \u003e   \"ap\",\n    \u003e   \"app\",\n    \u003e   \"array\",\n    \u003e   \"arrayDifference\",\n    \u003e   \"arrayIntersection\",\n    \u003e   \"arrayIsSubset\",\n    \u003e   \"arraySetEqual\",\n    \u003e   \"asciiLetters\",\n    \u003e   \"asciiLowercase\",\n    \u003e   \"asciiUppercase\",\n    \u003e   \"assign\",\n    \u003e   \"async\",\n    \u003e   \"asyncMap\",\n    \u003e   \"asyncRace\",\n    \u003e   \"asyncReduce\",\n    \u003e   \"asyncRepeat\",\n    \u003e   \"average\",\n    \u003e   \"b64ToHex\",\n    \u003e   ... ]\n    \u003e ```\n\n* play with `shuffle` and `range` ([link](https://runkit.com/embed/pdk4lfc4ul51)):\n\n    ```javascript\n    jsToolbox.shuffle(jsToolbox.range(16))\n    ```\n\n    \u003e ```javascript\n    \u003e [ 14, 12, 15, 8, 13, 4, 5, 6, 1, 7, 10, 0, 2, 3, 9, 11 ]\n    \u003e ```\n\n* do all other things shown in **examples** section below\n\n\u003cbr /\u003e\n\n\n\n\n## use the package\n\n### install\n\n```bash\n$ mkdir playground\n$ cd playground/\n$ npm init\n...\n$ npm i @xcmats/js-toolbox\n...\n```\n\n\u003cbr /\u003e\n\n\n### play in node.js\n\n```bash\n$ node\n\u003e\n```\n\n```javascript\nt = require(\"@xcmats/js-toolbox\")\n```\n\n\u003e ```javascript\n\u003e { ...\n\u003e array:\n\u003e  { ... },\n\u003e ...\n\u003e utils:\n\u003e  { ... } }\n\u003e ```\n\n\u003cbr /\u003e\n\n\n### example use in ES6 modules code\n\n```javascript\nimport { range } from \"@xcmats/js-toolbox/array\";\nimport { stringToB64 } from \"@xcmats/js-toolbox/codec\";\nimport { flow } from \"@xcmats/js-toolbox/func\";\nimport { random } from \"@xcmats/js-toolbox/string\";\n\nconst b64stringify = flow(\n    JSON.stringify,\n    stringToB64,\n);\n\nlet spam = b64stringify({\n    tenNumbers: range(10),\n    randomLetters: random(20),\n});\n\nconsole.log(\"Stringified and b64-encoded object: \", spam);\n```\n\n\u003cbr /\u003e\n\n\n\n\n## use the source\n\n```bash\n$ git clone git@github.com:drmats/js-toolbox.git\nCloning into 'js-toolbox'...\n$ cd js-toolbox\n$ npm i\n$ npm start\nCopying type declarations and module configs ...\nOK.\nGenerating type declarations from .ts files.\nCompiling for 'commonjs' ...\nSuccessfully compiled 47 files with Babel (1709ms).\n\u003e\n```\n\n\u003cbr /\u003e\n\n\n\n\n## namespaces\n\nIf you're experimenting via _RunKit_ then prepend all namespaces with \"`jsToolbox.`\"\nand if you're experimenting inside _node.js console_ with _npm_ package (as described\nabove) then prepend all namespaces with \"`t.`\". If you're using the source\nand have launched _node.js_ session via `npm start` then you're good to go\n( [`¯\\_(ツ)_/¯`](https://i.imgur.com/Bw6D5zZ.gif) ).\n\n\n### **array** utilities\n\n```javascript\narray\n```\n\n\u003e ```javascript\n\u003e { append: [Function: append],\n\u003e   countBy: [Function: countBy],\n\u003e   difference: [Function: difference],\n\u003e   draw: [Function: draw],\n\u003e   drop: [Function: drop],\n\u003e   dropLast: [Function: dropLast],\n\u003e   findDuplicates: [Function: findDuplicates],\n\u003e   flatten: [Function: flatten],\n\u003e   head: [Function: head],\n\u003e   init: [Function: init],\n\u003e   intersection: [Function: intersection],\n\u003e   isContinuous: [Function: isContinuous],\n\u003e   isSorted: [Function: isSorted],\n\u003e   isSubset: [Function: isSubset],\n\u003e   last: [Function: last],\n\u003e   range: [Function: range],\n\u003e   removeDuplicates: [Function],\n\u003e   setEqual: [Function: setEqual],\n\u003e   shuffle: [Function: shuffle],\n\u003e   sparse: [Function: sparse],\n\u003e   tail: [Function: tail],\n\u003e   take: [Function: take],\n\u003e   takeEvery: [Function: takeEvery],\n\u003e   takeLast: [Function: takeLast],\n\u003e   zipWith: [Function: zipWith],\n\u003e   zip: [Function] }\n\u003e ```\n\n\n### **asynchronous programming** helpers\n\n```javascript\nasync\n```\n\n\u003e ```javascript\n\u003e { ap: [Function ap],\n\u003e   bind: [Function bind],\n\u003e   cancellable: [Function: cancellable],\n\u003e   createMutex: [Function: createMutex],\n\u003e   createTimedBarrier: [Function: createTimedBarrier],\n\u003e   delay: [Function: delay],\n\u003e   interval: [Function: interval],\n\u003e   liftr: [Function: liftr],\n\u003e   map: [Function: map],\n\u003e   parMap: [Function: parMap],\n\u003e   promisePool: [Function: promisePool],\n\u003e   race: [Function: race],\n\u003e   rbind: [Function: rbind],\n\u003e   reduce: [Function: reduce],\n\u003e   repeat: [Function: repeat],\n\u003e   timeout: [Function: timeout],\n\u003e   unit: [Function: unit] }\n\u003e ```\n\n\n### **[TypedArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray)** coders/decoders\n\n```javascript\ncodec\n```\n\n\u003e ```javascript\n\u003e { concatBytes: [Function: concatBytes],\n\u003e   compareBytes: [Function: compareBytes],\n\u003e   stringToBytes: [Function],\n\u003e   bytesToString: [Function],\n\u003e   csv: [Function],\n\u003e   hexToBytes: [Function: hexToBytes],\n\u003e   bytesToHex: [Function: bytesToHex],\n\u003e   b64dec: [Function],\n\u003e   b64enc: [Function],\n\u003e   b64ToString: [Function],\n\u003e   stringToB64: [Function],\n\u003e   b64ToHex: [Function],\n\u003e   hexToB64: [Function],\n\u003e   random: [AsyncFunction],\n\u003e   timestamp: [Function: timestamp] }\n\u003e ```\n\n\n### **functional programming tools**\n\n```javascript\nfunc\n```\n\n\u003e ```javascript\n\u003e { app: [Function: app],\n\u003e   choose: [Function: choose],\n\u003e   compose: [Function: compose],\n\u003e   curry: [Function: curry],\n\u003e   curryN: [Function: curryN],\n\u003e   curryThunk: [Function: curryThunk],\n\u003e   flow: [Function: flow],\n\u003e   handleException: [Function: handleException],\n\u003e   identity: [Function: identity],\n\u003e   lazyish: [Function: lazyish],\n\u003e   locker: [Function: locker],\n\u003e   local: [Function: local],\n\u003e   partial: [Function: partial],\n\u003e   pipe: [Function: pipe],\n\u003e   rearg: [Function: rearg],\n\u003e   Y: [Function: Y] }\n\u003e ```\n\n\n### basic **math**\n\n```javascript\nmath\n```\n\n\u003e ```javascript\n\u003e { add: [Function],\n\u003e   average: [Function: average],\n\u003e   clamp: [Function: clamp],\n\u003e   dec: [Function],\n\u003e   degrees: [Function],\n\u003e   div: [Function],\n\u003e   inc: [Function],\n\u003e   interpolate: [Function],\n\u003e   inv: [Function],\n\u003e   log10: [Function: log10],\n\u003e   log2: [Function: log2],\n\u003e   mod: [Function],\n\u003e   mul: [Function],\n\u003e   neg: [Function],\n\u003e   pow: [Function],\n\u003e   product: [Function: product],\n\u003e   radians: [Function],\n\u003e   randomInt: [Function: randomInt],\n\u003e   remainder: [Function],\n\u003e   roundIfClose: [Function: roundIfClose],\n\u003e   sub: [Function],\n\u003e   sum: [Function: sum] }\n\u003e ```\n\n\n### **option monad**\n\n```javascript\noption\n```\n\n\u003e ```javascript\n\u003e { bind: [Function: bind],\n\u003e   hasValue: [Function: hasValue],\n\u003e   JUST: [Function: JUST],\n\u003e   NOTHING: { [Symbol(__maybe)]: false },\n\u003e   optionalize: [Function: optionalize],\n\u003e   rbind: [Function: rbind] }\n\u003e ```\n\n\n### **string** utilities\n\n```javascript\nstring\n```\n\n\u003e ```javascript\n\u003e { asciiLetters: [Function: asciiLetters],\n\u003e   asciiLowercase: [Function: asciiLowercase],\n\u003e   asciiUppercase: [Function: asciiUppercase],\n\u003e   big: [Function],\n\u003e   camelToPascal: [Function: camelToPascal],\n\u003e   camelToSnake: [Function: camelToSnake],\n\u003e   capitalize: [Function: capitalize],\n\u003e   digits: [Function: digits],\n\u003e   ellipsis: { [Function: ellipsis] BEGIN: 0, MIDDLE: 1, END: 2 },\n\u003e   empty: [Function: empty],\n\u003e   space: [Function: space],\n\u003e   nl: [Function: nl],\n\u003e   tab: [Function: tab],\n\u003e   padLeft: [Function: padLeft],\n\u003e   padRight: [Function: padRight],\n\u003e   pascalToCamel: [Function: pascalToCamel],\n\u003e   pascalToSnake: [Function: pascalToSnake],\n\u003e   quote: [Function: quote],\n\u003e   random: [Function: random],\n\u003e   shorten: { [Function: shorten] BEGIN: 0, MIDDLE: 1, END: 2 },\n\u003e   snakeToCamel: [Function: snakeToCamel],\n\u003e   snakeToPascal: [Function: snakeToPascal],\n\u003e   wrap: [Function: wrap] }\n\u003e ```\n\n\n### data structure manipulation tools\n\n```javascript\nstruct\n```\n\n\u003e ```javascript\n\u003e { access: [Function: access],\n\u003e   assign: [Function: assign],\n\u003e   clone: [Function],\n\u003e   hashAccessor: [Function: hashAccessor],\n\u003e   keyAccessor: [Function: keyAccessor],\n\u003e   dfs: [Function: dfs],\n\u003e   dict: [Function: dict],\n\u003e   isBasicData: [Function: isBasicData],\n\u003e   isBasicDataOrUndefined: [Function: isBasicDataOrUndefined],\n\u003e   objectMap: [Function: objectMap],\n\u003e   objectReduce: [Function: objectReduce],\n\u003e   rewrite: [Function: rewrite],\n\u003e   swap: [Function: swap] }\n\u003e ```\n\n\n### **type** helpers\n\n```javascript\ntype\n```\n\n\u003e ```javascript\n\u003e { isArray: [Function: isArray],\n\u003e   isBoolean: [Function: isBoolean],\n\u003e   isDate: [Function: isDate],\n\u003e   isFunction: [Function: isFunction],\n\u003e   isNumber: [Function: isNumber],\n\u003e   isObject: [Function: isObject],\n\u003e   isRegExp: [Function: isRegExp],\n\u003e   isString: [Function: isString],\n\u003e   lazyNullishCoalesce: [Function: lazyNullishCoalesce],\n\u003e   maxInt: 9007199254740991,\n\u003e   minInt: -9007199254740991,\n\u003e   nullToUndefined: [Function: nullToUndefined],\n\u003e   toBool: [Function: toBool],\n\u003e   undefinedToNull: [Function: undefinedToNull] }\n\u003e ```\n\n\n### uncategorized **utilities**\n\n```javascript\nutils\n```\n\n\u003e ```javascript\n\u003e { btquote: [Function: btquote],\n\u003e   devEnv: [Function: devEnv],\n\u003e   getLibConfig: [Function: getLibConfig],\n\u003e   getProcess: [Function: getProcess],\n\u003e   isBrowser: [Function: isBrowser],\n\u003e   rgb: [Function: rgb],\n\u003e   rgba: [Function: rgba],\n\u003e   run: [Function: run],\n\u003e   timing: [Function: timing],\n\u003e   timeUnit: { ... },\n\u003e   to_: [Function: to_],\n\u003e   url: [Function: url] }\n\u003e ```\n\n\u003cbr /\u003e\n\n\n\n\n## examples\n\n### array manipulation\n\n* Find the lenghts of the words in a given sentence\n    and count how many of them exists in each length group.\n\n    ```javascript\n    array.countBy(\n        'exemplo plus quam ratione vivimus'.split(' '),\n        w =\u003e w.length,\n    );\n    ```\n\n    \u003e ```javascript\n    \u003e { '4': 2, '7': 3 }\n    \u003e ```\n\n\n* Choose a random element from a given `array`\n    (or a random character from a given `string`).\n\n    ```javascript\n    array.draw(string.asciiLetters());\n    ```\n\n    \u003e ```javascript\n    \u003e 'S'\n    \u003e ```\n\n\n* Find duplicates in a given `array`.\n\n    ```javascript\n    array.findDuplicates(['one', 'two', 'one', 'six', 'two', 'two']);\n    ```\n\n    \u003e ```javascript\n    \u003e [ 'one', 'two' ]\n    \u003e ```\n\n\n* Flatten passed `array`, i.e. transform\n    `[[1, 2,], ..., [3, 4,],]` to `[1, 2, ..., 3, 4,]`.\n\n    ```javascript\n    array.flatten(Object.entries({ a: 'b', c: 'd', e: 'f' }));\n    ```\n\n    \u003e ```javascript\n    \u003e [ 'a', 'b', 'c', 'd', 'e', 'f' ]\n    \u003e ```\n\n\n* Return a list containing an arithmetic progression.\n    `range(i, j)` returns `[i, i+1, i+2, ..., j-1]`.\n    Possible invocations are: `range(stop)`, `range(start, stop)`,\n    `range(start, stop, step)`. When `start` is omitted it defaults to `0`.\n    When `step` is given, it specifies the increment (or decrement).\n\n    ```javascript\n    array.range(10);\n    ```\n\n    \u003e ```javascript\n    \u003e [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\n    \u003e ```\n\n    ```javascript\n    array.range(-128, -256, -16);\n    ```\n\n    \u003e ```javascript\n    \u003e [ -128, -144, -160, -176, -192, -208, -224, -240 ]\n    \u003e ```\n\n\n* Randomly shuffle all elements in the given `array` (Durstenfeld's\n    modification to the Fisher-Yates shuffle algorithm).\n    The operation is taken in-place.\n\n    ```javascript\n    array.shuffle(array.range(12));\n    ```\n\n    \u003e ```javascript\n    \u003e [ 9, 7, 0, 8, 2, 10, 3, 1, 11, 4, 5, 6 ]\n    \u003e ```\n\n\n* Generate sparse array of distinct integers.\n    `sparse(stop, size)` returns `array` of `size` distinct\n    integers in range `[0..stop-1]`.\n    `sparse(start, stop, size)` returns `array` of `size` distinct\n    integers in range `[start..stop-1]`.\n\n    ```javascript\n    array.sparse(1024, 8);\n    ```\n\n    \u003e ```javascript\n    \u003e [ 6, 34, 170, 422, 530, 643, 855, 862 ]\n    \u003e ```\n\n\n* \"Zip\" given arrays using provided `f` operator.\n\n    ```javascript\n    array.zipWith((a, b) =\u003e a + b) ([1, 2, 3, 4], [10, 20, 30, 40]);\n    ```\n\n    \u003e ```javascript\n    \u003e [ 11, 22, 33, 44 ]\n    \u003e ```\n\n\n* Take every 3rd element from a given array.\n\n    ```javascript\n    array.takeEvery(3) ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);\n    ```\n\n    \u003e ```javascript\n    \u003e [0, 3, 6, 9]\n    \u003e ```\n\n\u003cbr /\u003e\n\n\n### asynchronous programming\n\n* Delay current async execution by `time` miliseconds.\n\n    ```javascript\n    (async () =\u003e {\n        await async.delay();\n        console.log('Hello ...');\n        await async.delay();\n        console.log('... world');\n    }) ();\n    ```\n\n    \u003e ```javascript\n    \u003e Promise { \u003cpending\u003e }\n    \u003e Hello ...\n    \u003e ... world\n    \u003e ```\n\n\n* Invoke a sequence of asynchronous operations on an array of elements.\n\n    ```javascript\n    (async () =\u003e {\n        let x = await async.map(\n            array.range(10),\n            (x) =\u003e async.timeout(() =\u003e {\n                console.log(4*x);\n                return 4*x;\n            }, array.head(array.sparse(1000, 1))),\n        );\n        console.log(`Result: ${x}`);\n    }) ();\n    ```\n\n    \u003e ```javascript\n    \u003e Promise { \u003cpending\u003e }\n    \u003e 0\n    \u003e 4\n    \u003e 8\n    \u003e 12\n    \u003e 16\n    \u003e 20\n    \u003e 24\n    \u003e 28\n    \u003e 32\n    \u003e 36\n    \u003e Result: 0,4,8,12,16,20,24,28,32,36\n    \u003e ```\n\n\n* Paralelly execute operation on each element of the array.\n\n    ```javascript\n    (async () =\u003e {\n        let x = await async.parMap(\n            array.range(10),\n            (x) =\u003e async.timeout(() =\u003e {\n                console.log(4*x);\n                return 4*x;\n            }, array.head(array.sparse(1000, 1))),\n        );\n        console.log(`Result: ${x}`);\n    }) ()\n    ```\n\n    \u003e ```javascript\n    \u003e Promise { \u003cpending\u003e }\n    \u003e 24\n    \u003e 8\n    \u003e 16\n    \u003e 12\n    \u003e 28\n    \u003e 20\n    \u003e 0\n    \u003e 36\n    \u003e 32\n    \u003e 4\n    \u003e Result: 0,4,8,12,16,20,24,28,32,36\n    \u003e ```\n\n\n* Accumulate value over an array of elements using asynchronous operation.\n\n    ```javascript\n    (async () =\u003e {\n        let x = await async.reduce(\n            array.range(10),\n            (acc, x) =\u003e async.timeout(() =\u003e {\n                console.log(acc+x);\n                return acc+x;\n            }, 100*x),\n        );\n        console.log(`Accumulated value: ${x}`);\n    }) ()\n    ```\n\n    \u003e ```javascript\n    \u003e Promise { \u003cpending\u003e }\n    \u003e 0\n    \u003e 1\n    \u003e 3\n    \u003e 6\n    \u003e 10\n    \u003e 15\n    \u003e 21\n    \u003e 28\n    \u003e 36\n    \u003e 45\n    \u003e Accumulated value: 45\n    \u003e ```\n\n\u003cbr /\u003e\n\n\n### base64 encoding and decoding\n\n* Convert UTF-8 string into an array of bytes.\n\n    ```javascript\n    codec.stringToBytes('Koń: 🐎');\n    ```\n\n    \u003e ```javascript\n    \u003e Uint8Array [ 75, 111, 197, 132, 58, 32, 240, 159, 144, 142 ]\n    \u003e ```\n\n\n* Convert array of bytes into a UTF-8 string.\n\n    ```javascript\n    data = Uint8Array.from([70, 111, 120, 58, 32, 240, 159, 166, 138]);\n    ```\n\n    \u003e ```javascript\n    \u003e Uint8Array [ 70, 111, 120, 58, 32, 240, 159, 166, 138 ]\n    \u003e ```\n\n    ```javascript\n    codec.bytesToString(data);\n    ```\n\n    \u003e```javascript\n    \u003e'Fox: 🦊'\n    \u003e```\n\n\n* Encode given byte array to Base64.\n    **Base64 encoding in _browser_ and _node.js_.**\n\n    ```javascript\n    data = Uint8Array.from([240, 159, 142, 169, 240, 159, 144, 176]);\n    ```\n\n    \u003e ```javascript\n    \u003e Uint8Array [ 240, 159, 142, 169, 240, 159, 144, 176 ]\n    \u003e ```\n\n    ```javascript\n    codec.b64enc(data);\n    ```\n\n    \u003e ```javascript\n    \u003e '8J+OqfCfkLA='\n    \u003e ```\n\n\n* Decode given Base64 string to byte array.\n    **Base64 decoding in _browser_ and _node.js_.**\n\n    ```javascript\n    data = codec.b64dec('8J+OqfCfkLA=');\n    ```\n\n    \u003e ```javascript\n    \u003e Uint8Array [ 240, 159, 142, 169, 240, 159, 144, 176 ]\n    \u003e ```\n\n    ```javascript\n    codec.bytesToString(data);\n    ```\n\n    \u003e ```javascript\n    \u003e '🎩🐰'\n    \u003e ```\n\n\u003cbr /\u003e\n\n\n### hex encoding and decoding\n\n* Convert hex-encoded string to a byte representation.\n\n    ```javascript\n    codec.hexToBytes('cabafa87');\n    ```\n\n    \u003e ```javascript\n    \u003e Uint8Array [ 202, 186, 250, 135 ]\n    \u003e ```\n\n    ```javascript\n    codec.hexToBytes('0x1234567890ABCDEF');\n    ```\n\n    \u003e ```javascript\n    \u003e Uint8Array [ 18, 52, 86, 120, 144, 171, 205, 239 ]\n    \u003e ```\n\n\n* Convert byte representation to a hex-encoded string.\n\n    ```javascript\n    codec.bytesToHex(Uint8Array.from([31, 63, 127, 255]));\n    ```\n\n    \u003e ```javascript\n    \u003e '1f3f7fff'\n    \u003e ```\n\n\u003cbr /\u003e\n\n\n### byte array manipulation\n\n* Concatenate contents of a given byte arrays.\n\n    ```javascript\n    codec.concatBytes(\n        Uint8Array.from([255, 255, 0, 0]),\n        codec.stringToBytes('🌍'),\n        Uint8Array.from([128, 64]),\n    );\n    ```\n\n    \u003e ```javascript\n    \u003e Uint8Array [ 255, 255, 0, 0, 240, 159, 140, 141, 128, 64 ]\n    \u003e ```\n\n\n* Compare two byte arrays.\n\n    ```javascript\n    codec.compareBytes(\n        codec.stringToBytes('𝓬𝓸𝓭𝓮'.normalize('NFC')),\n        codec.stringToBytes('𝐜𝐨𝐝𝐞'.normalize('NFC')),\n    );\n    ```\n\n    \u003e ```javascript\n    \u003e false\n    \u003e ```\n\n    ```javascript\n    codec.compareBytes(codec.hexToBytes('0xFF'), Uint8Array.from([255]));\n    ```\n\n    \u003e ```javascript\n    \u003e true\n    \u003e ```\n\n\u003cbr /\u003e\n\n\n### functional programming\n\n* Function composition.\n\n    ```javascript\n    func.compose(\n        string.quote,\n        string.shorten,\n    ) (\n        \"When I find myself in times of trouble\",\n        20, string.shorten.END,\n    );\n    ```\n\n    \u003e ```javascript\n    \u003e '\"When I find myself …\"'\n    \u003e ```\n\n    ```javascript\n    stringToHex = func.flow(codec.stringToBytes, codec.bytesToHex);\n    ```\n\n    \u003e ```javascript\n    \u003e [Function]\n    \u003e ```\n\n    ```javascript\n    stringToHex('Kaboom! 💥');\n    ```\n\n    \u003e ```javascript\n    \u003e '4b61626f6f6d2120f09f92a5'\n    \u003e ```\n\n    ```javascript\n    func.pipe('4b61626f6f6d2120f09f92a5') (\n        codec.hexToBytes, codec.bytesToString\n    );\n    ```\n\n    \u003e ```javascript\n    \u003e 'Kaboom! 💥'\n    \u003e ```\n\n\n* Translate the evaluation of function `f` taking multiple arguments\n    into an evaluation of sequence of functions, each with a single argument.\n\n    ```javascript\n    addition = (a, b, c) =\u003e a + b + c;\n    ```\n\n    \u003e ```javascript\n    \u003e [Function: addition]\n    \u003e ```\n\n    ```javascript\n    func.curry(addition) (1) (2) (3);\n    ```\n\n    \u003e ```javascript\n    \u003e 6\n    \u003e ```\n\n\n * Function arguments rearrangement.\n\n    ```javascript\n    console.log('a', 'b', 'c', 'd', 'e');\n    ```\n\n    \u003e ```javascript\n    \u003e a b c d e\n    \u003e ```\n\n    ```javascript\n    revConsole = rearg(console.log) (4, 3, 2, 1, 0);\n    revConsole('a', 'b', 'c', 'd', 'e');\n    ```\n\n    \u003e ```javascript\n    \u003e e d c b a\n    \u003e ```\n\n    ```javascript\n    revConsole('f') ('g', 'h') ('i') ('j');\n    ```\n\n    \u003e ```javascript\n    \u003e j i h g f\n    \u003e ```\n\n\n* Y-combinator - returns fixed point of a higher-order function passed as `f`.\n    **Anonymous recursion in Javascript**.\n\n    ```javascript\n    factorial = func.Y((r) =\u003e (n) =\u003e n \u003c= 0  ?  1  :  n * r(n - 1));\n    ```\n\n    \u003e ```javascript\n    \u003e [Function]\n    \u003e ```\n\n    ```javascript\n    factorial(5);\n    ```\n\n    \u003e ```javascript\n    \u003e 120\n    \u003e ```\n\n\u003cbr /\u003e\n\n\n### simple math\n\n* Compute mathematical average of array of numbers.\n\n    ```javascript\n    math.average([1, 2, 3, 4, 5]);\n    ```\n\n    \u003e ```javascript\n    \u003e 3\n    \u003e ```\n\n\n* Base 2 logarithm.\n\n    ```javascript\n    math.log2(2**32);\n    ```\n\n    \u003e ```javascript\n    \u003e 32\n    \u003e ```\n\n\n* Base 10 logarithm.\n\n    ```javascript\n    math.log10(1e9);\n    ```\n\n    \u003e ```javascript\n    \u003e 9\n    \u003e ```\n\n\n* Sum of numbers in passed `array`.\n\n    ```javascript\n    math.sum([5, 6, 7, 8, 9, 10]);\n    ```\n\n    \u003e ```javascript\n    \u003e 45\n    \u003e ```\n\n\u003cbr /\u003e\n\n\n### operating on strings\n\n* Allocate a **big** string (of size `2^n`).\n\n    ```javascript\n    string.big(5);\n    ```\n\n    \u003e ```javascript\n    \u003e 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'\n    \u003e ```\n\n\n* Convert `camelText` to `snake_text`.\n\n    ```javascript\n    string.camelToSnake('someNightsIStayUpCashingInMyBadLuck');\n    ```\n\n    \u003e ```javascript\n    \u003e 'some_nights_i_stay_up_cashing_in_my_bad_luck'\n    \u003e ```\n\n\n* Quote text.\n\n    ```javascript\n    string.quote('div', '\u003c\u003e');\n    ```\n\n    \u003e ```javascript\n    \u003e '\u003cdiv\u003e'\n    \u003e ```\n\n\n* Construct random string of desired length.\n\n    ```javascript\n    string.random(16);\n    ```\n\n    \u003e ```javascript\n    \u003e 'MxWGe8MoOss0yUAP'\n    \u003e ```\n\n\n* Shorten a given string to the desired length.\n\n    ```javascript\n    string.shorten('abcdefghijklmnopqrstuvwxyz', 15);\n    ```\n\n    \u003e ```javascript\n    \u003e 'abcdefg…tuvwxyz'\n    \u003e ```\n\n    ```javascript\n    string.shorten(\n        'To be, or not to be, that is the question',\n        20,\n        string.shorten.END,\n    );\n    ```\n\n    \u003e ```javascript\n    \u003e 'To be, or not to be…'\n    \u003e ```\n\n\n* Convert `snake_text` to `camelText`.\n\n    ```javascript\n    string.snakeToCamel('some_nights_i_call_it_a_draw');\n    ```\n\n    \u003e ```javascript\n    \u003e 'someNightsICallItADraw'\n    \u003e ```\n\n\u003cbr /\u003e\n\n\n### data structure manipulation\n\n* Apply `path` to an object.\n\n    ```javascript\n    struct.access({ a: { b: { c: 42 } } }, ['a', 'b', 'c']);\n    ```\n\n    \u003e ```javascript\n    \u003e 42\n    \u003e ```\n\n\n* Construct `Object` from the result of `Object.entries()` call.\n    `entries = [[k1, v1,], ..., [kn, vn,]]`\n\n    ```javascript\n    struct.dict([['a', 'b'], ['c', 'd'], ['e', 'f']]);\n    ```\n\n    \u003e ```javascript\n    \u003e { a: 'b', c: 'd', e: 'f' }\n    \u003e ```\n\n\n* Shallow map (iteration) on objects.\n\n    ```javascript\n    struct.objectMap(\n        { what: 'od', i: '?rof dnats' },\n        ([k, v,]) =\u003e [\n            string.capitalize(k),\n            v.split('').reverse().join(''),\n        ],\n    );\n    ```\n\n    \u003e ```javascript\n    \u003e { What: 'do', I: 'stand for?' }\n    \u003e ```\n\n\n* Swap keys with values in a given `Object`.\n\n    ```javascript\n    struct.swap({ a: 'b', c: 'd', e: 'f' });\n    ```\n\n    \u003e ```javascript\n    \u003e { b: 'a', d: 'c', f: 'e' }\n    \u003e ```\n\n\u003c/br\u003e\n\n\n### type primitives\n\n* Determine if a given value is a proper `Number`\n    (not `NaN` and not `Infinity`).\n\n    ```javascript\n    [type.isNumber(NaN), type.isNumber(-Infinity), type.isNumber(1234.5678)]\n    ```\n\n    \u003e ```javascript\n    \u003e [ false, false, true ]\n    \u003e ```\n\n\n* Determine if a given value is an `Object`\n    (not `null`, not `undefined` and not `Array`).\n\n    ```javascript\n    [type.isObject(null), type.isObject([]), type.isObject({})]\n    ```\n\n    \u003e ```javascript\n    \u003e [ false, false, true ]\n    \u003e ```\n\n\u003cbr /\u003e\n\n\n\n\n## notes\n\nThis library is suitable to use in server and browser environments\nand it is being used as such.\nGo ahead and [file an issue](https://github.com/drmats/js-toolbox/issues/new)\nor [submit a fresh PR](https://github.com/drmats/js-toolbox/pulls)\nif you found a bug 🐞.\n\n\u003c/br\u003e\n\n\n\n\n## support\n\nYou can support this project via [stellar][stellar] network:\n\n* Payment address: [xcmats*keybase.io][xcmatspayment]\n* Stellar account ID: [`GBYUN4PMACWBJ2CXVX2KID3WQOONPKZX2UL4J6ODMIRFCYOB3Z3C44UZ`][addressproof]\n\n\u003cbr /\u003e\n\n\n\n\n## license\n\n**js-toolbox** is released under the Apache License, Version 2.0. See the\n[LICENSE](https://github.com/drmats/js-toolbox/blob/master/LICENSE)\nfor more details.\n\n\n\n\n[stellar]: https://learn.stellar.org\n[xcmatspayment]: https://keybase.io/xcmats\n[addressproof]: https://keybase.io/xcmats/sigchain#d0999a36b501c4818c15cf813f5a53da5bfe437875d92262be8d285bbb67614e22\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrmats%2Fjs-toolbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrmats%2Fjs-toolbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrmats%2Fjs-toolbox/lists"}