npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@xcmats/js-toolbox

v0.16.4

Published

Useful JS utilities.

Downloads

2,398

Readme

js-toolbox

Useful JavaScript utilities (with TypeScript typings).

npm version npm license GitHub top language GitHub code size GitHub tag

$ npm i @xcmats/js-toolbox

Works in node.js and browser environments (use webpack or Rollup to bundle it with your project).

index

documentation

API Reference

play in your browser

RunKit with @xcmats/js-toolbox

  • list member functions (link):

    var jsToolbox = require("@xcmats/js-toolbox")
    
    Object.keys(jsToolbox).sort()
    [ "Y",
      "access",
      "add",
      "ap",
      "app",
      "array",
      "arrayDifference",
      "arrayIntersection",
      "arrayIsSubset",
      "arraySetEqual",
      "asciiLetters",
      "asciiLowercase",
      "asciiUppercase",
      "assign",
      "async",
      "asyncMap",
      "asyncRace",
      "asyncReduce",
      "asyncRepeat",
      "average",
      "b64ToHex",
      ... ]
  • play with shuffle and range (link):

    jsToolbox.shuffle(jsToolbox.range(16))
    [ 14, 12, 15, 8, 13, 4, 5, 6, 1, 7, 10, 0, 2, 3, 9, 11 ]
  • do all other things shown in examples section below

use the package

install

$ mkdir playground
$ cd playground/
$ npm init
...
$ npm i @xcmats/js-toolbox
...

play in node.js

$ node
>
t = require("@xcmats/js-toolbox")
{ ...
array:
 { ... },
...
utils:
 { ... } }

example use in ES6 modules code

import { range } from "@xcmats/js-toolbox/array";
import { stringToB64 } from "@xcmats/js-toolbox/codec";
import { flow } from "@xcmats/js-toolbox/func";
import { random } from "@xcmats/js-toolbox/string";

const b64stringify = flow(
    JSON.stringify,
    stringToB64,
);

let spam = b64stringify({
    tenNumbers: range(10),
    randomLetters: random(20),
});

console.log("Stringified and b64-encoded object: ", spam);

use the source

$ git clone [email protected]:drmats/js-toolbox.git
Cloning into 'js-toolbox'...
$ cd js-toolbox
$ npm i
$ npm start
Copying type declarations and module configs ...
OK.
Generating type declarations from .ts files.
Compiling for 'commonjs' ...
Successfully compiled 47 files with Babel (1709ms).
>

namespaces

If you're experimenting via RunKit then prepend all namespaces with "jsToolbox." and if you're experimenting inside node.js console with npm package (as described above) then prepend all namespaces with "t.". If you're using the source and have launched node.js session via npm start then you're good to go ( ¯\_(ツ)_/¯ ).

array utilities

array
{ append: [Function: append],
  countBy: [Function: countBy],
  difference: [Function: difference],
  draw: [Function: draw],
  drop: [Function: drop],
  dropLast: [Function: dropLast],
  findDuplicates: [Function: findDuplicates],
  flatten: [Function: flatten],
  head: [Function: head],
  init: [Function: init],
  intersection: [Function: intersection],
  isContinuous: [Function: isContinuous],
  isSorted: [Function: isSorted],
  isSubset: [Function: isSubset],
  last: [Function: last],
  range: [Function: range],
  removeDuplicates: [Function],
  setEqual: [Function: setEqual],
  shuffle: [Function: shuffle],
  sparse: [Function: sparse],
  tail: [Function: tail],
  take: [Function: take],
  takeEvery: [Function: takeEvery],
  takeLast: [Function: takeLast],
  zipWith: [Function: zipWith],
  zip: [Function] }

asynchronous programming helpers

async
{ ap: [Function ap],
  bind: [Function bind],
  cancellable: [Function: cancellable],
  createMutex: [Function: createMutex],
  createTimedBarrier: [Function: createTimedBarrier],
  delay: [Function: delay],
  interval: [Function: interval],
  liftr: [Function: liftr],
  map: [Function: map],
  parMap: [Function: parMap],
  promisePool: [Function: promisePool],
  race: [Function: race],
  rbind: [Function: rbind],
  reduce: [Function: reduce],
  repeat: [Function: repeat],
  timeout: [Function: timeout],
  unit: [Function: unit] }

TypedArray coders/decoders

codec
{ concatBytes: [Function: concatBytes],
  compareBytes: [Function: compareBytes],
  stringToBytes: [Function],
  bytesToString: [Function],
  csv: [Function],
  hexToBytes: [Function: hexToBytes],
  bytesToHex: [Function: bytesToHex],
  b64dec: [Function],
  b64enc: [Function],
  b64ToString: [Function],
  stringToB64: [Function],
  b64ToHex: [Function],
  hexToB64: [Function],
  random: [AsyncFunction],
  timestamp: [Function: timestamp] }

functional programming tools

func
{ app: [Function: app],
  choose: [Function: choose],
  compose: [Function: compose],
  curry: [Function: curry],
  curryN: [Function: curryN],
  curryThunk: [Function: curryThunk],
  flow: [Function: flow],
  handleException: [Function: handleException],
  identity: [Function: identity],
  lazyish: [Function: lazyish],
  locker: [Function: locker],
  local: [Function: local],
  partial: [Function: partial],
  pipe: [Function: pipe],
  rearg: [Function: rearg],
  Y: [Function: Y] }

basic math

math
{ add: [Function],
  average: [Function: average],
  clamp: [Function: clamp],
  dec: [Function],
  degrees: [Function],
  div: [Function],
  inc: [Function],
  interpolate: [Function],
  inv: [Function],
  log10: [Function: log10],
  log2: [Function: log2],
  mod: [Function],
  mul: [Function],
  neg: [Function],
  pow: [Function],
  product: [Function: product],
  radians: [Function],
  randomInt: [Function: randomInt],
  remainder: [Function],
  roundIfClose: [Function: roundIfClose],
  sub: [Function],
  sum: [Function: sum] }

option monad

option
{ bind: [Function: bind],
  hasValue: [Function: hasValue],
  JUST: [Function: JUST],
  NOTHING: { [Symbol(__maybe)]: false },
  optionalize: [Function: optionalize],
  rbind: [Function: rbind] }

string utilities

string
{ asciiLetters: [Function: asciiLetters],
  asciiLowercase: [Function: asciiLowercase],
  asciiUppercase: [Function: asciiUppercase],
  big: [Function],
  camelToPascal: [Function: camelToPascal],
  camelToSnake: [Function: camelToSnake],
  capitalize: [Function: capitalize],
  digits: [Function: digits],
  ellipsis: { [Function: ellipsis] BEGIN: 0, MIDDLE: 1, END: 2 },
  empty: [Function: empty],
  space: [Function: space],
  nl: [Function: nl],
  tab: [Function: tab],
  padLeft: [Function: padLeft],
  padRight: [Function: padRight],
  pascalToCamel: [Function: pascalToCamel],
  pascalToSnake: [Function: pascalToSnake],
  quote: [Function: quote],
  random: [Function: random],
  shorten: { [Function: shorten] BEGIN: 0, MIDDLE: 1, END: 2 },
  snakeToCamel: [Function: snakeToCamel],
  snakeToPascal: [Function: snakeToPascal],
  wrap: [Function: wrap] }

data structure manipulation tools

struct
{ access: [Function: access],
  assign: [Function: assign],
  clone: [Function],
  hashAccessor: [Function: hashAccessor],
  keyAccessor: [Function: keyAccessor],
  dfs: [Function: dfs],
  dict: [Function: dict],
  isBasicData: [Function: isBasicData],
  isBasicDataOrUndefined: [Function: isBasicDataOrUndefined],
  objectMap: [Function: objectMap],
  objectReduce: [Function: objectReduce],
  rewrite: [Function: rewrite],
  swap: [Function: swap] }

type helpers

type
{ isArray: [Function: isArray],
  isBoolean: [Function: isBoolean],
  isDate: [Function: isDate],
  isFunction: [Function: isFunction],
  isNumber: [Function: isNumber],
  isObject: [Function: isObject],
  isRegExp: [Function: isRegExp],
  isString: [Function: isString],
  lazyNullishCoalesce: [Function: lazyNullishCoalesce],
  maxInt: 9007199254740991,
  minInt: -9007199254740991,
  nullToUndefined: [Function: nullToUndefined],
  toBool: [Function: toBool],
  undefinedToNull: [Function: undefinedToNull] }

uncategorized utilities

utils
{ btquote: [Function: btquote],
  devEnv: [Function: devEnv],
  getLibConfig: [Function: getLibConfig],
  getProcess: [Function: getProcess],
  isBrowser: [Function: isBrowser],
  rgb: [Function: rgb],
  rgba: [Function: rgba],
  run: [Function: run],
  timing: [Function: timing],
  timeUnit: { ... },
  to_: [Function: to_],
  url: [Function: url] }

examples

array manipulation

  • Find the lenghts of the words in a given sentence and count how many of them exists in each length group.

    array.countBy(
        'exemplo plus quam ratione vivimus'.split(' '),
        w => w.length,
    );
    { '4': 2, '7': 3 }
  • Choose a random element from a given array (or a random character from a given string).

    array.draw(string.asciiLetters());
    'S'
  • Find duplicates in a given array.

    array.findDuplicates(['one', 'two', 'one', 'six', 'two', 'two']);
    [ 'one', 'two' ]
  • Flatten passed array, i.e. transform [[1, 2,], ..., [3, 4,],] to [1, 2, ..., 3, 4,].

    array.flatten(Object.entries({ a: 'b', c: 'd', e: 'f' }));
    [ 'a', 'b', 'c', 'd', 'e', 'f' ]
  • Return a list containing an arithmetic progression. range(i, j) returns [i, i+1, i+2, ..., j-1]. Possible invocations are: range(stop), range(start, stop), range(start, stop, step). When start is omitted it defaults to 0. When step is given, it specifies the increment (or decrement).

    array.range(10);
    [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
    array.range(-128, -256, -16);
    [ -128, -144, -160, -176, -192, -208, -224, -240 ]
  • Randomly shuffle all elements in the given array (Durstenfeld's modification to the Fisher-Yates shuffle algorithm). The operation is taken in-place.

    array.shuffle(array.range(12));
    [ 9, 7, 0, 8, 2, 10, 3, 1, 11, 4, 5, 6 ]
  • Generate sparse array of distinct integers. sparse(stop, size) returns array of size distinct integers in range [0..stop-1]. sparse(start, stop, size) returns array of size distinct integers in range [start..stop-1].

    array.sparse(1024, 8);
    [ 6, 34, 170, 422, 530, 643, 855, 862 ]
  • "Zip" given arrays using provided f operator.

    array.zipWith((a, b) => a + b) ([1, 2, 3, 4], [10, 20, 30, 40]);
    [ 11, 22, 33, 44 ]
  • Take every 3rd element from a given array.

    array.takeEvery(3) ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
    [0, 3, 6, 9]

asynchronous programming

  • Delay current async execution by time miliseconds.

    (async () => {
        await async.delay();
        console.log('Hello ...');
        await async.delay();
        console.log('... world');
    }) ();
    Promise { <pending> }
    Hello ...
    ... world
  • Invoke a sequence of asynchronous operations on an array of elements.

    (async () => {
        let x = await async.map(
            array.range(10),
            (x) => async.timeout(() => {
                console.log(4*x);
                return 4*x;
            }, array.head(array.sparse(1000, 1))),
        );
        console.log(`Result: ${x}`);
    }) ();
    Promise { <pending> }
    0
    4
    8
    12
    16
    20
    24
    28
    32
    36
    Result: 0,4,8,12,16,20,24,28,32,36
  • Paralelly execute operation on each element of the array.

    (async () => {
        let x = await async.parMap(
            array.range(10),
            (x) => async.timeout(() => {
                console.log(4*x);
                return 4*x;
            }, array.head(array.sparse(1000, 1))),
        );
        console.log(`Result: ${x}`);
    }) ()
    Promise { <pending> }
    24
    8
    16
    12
    28
    20
    0
    36
    32
    4
    Result: 0,4,8,12,16,20,24,28,32,36
  • Accumulate value over an array of elements using asynchronous operation.

    (async () => {
        let x = await async.reduce(
            array.range(10),
            (acc, x) => async.timeout(() => {
                console.log(acc+x);
                return acc+x;
            }, 100*x),
        );
        console.log(`Accumulated value: ${x}`);
    }) ()
    Promise { <pending> }
    0
    1
    3
    6
    10
    15
    21
    28
    36
    45
    Accumulated value: 45

base64 encoding and decoding

  • Convert UTF-8 string into an array of bytes.

    codec.stringToBytes('Koń: 🐎');
    Uint8Array [ 75, 111, 197, 132, 58, 32, 240, 159, 144, 142 ]
  • Convert array of bytes into a UTF-8 string.

    data = Uint8Array.from([70, 111, 120, 58, 32, 240, 159, 166, 138]);
    Uint8Array [ 70, 111, 120, 58, 32, 240, 159, 166, 138 ]
    codec.bytesToString(data);
    'Fox: 🦊'
  • Encode given byte array to Base64. Base64 encoding in browser and node.js.

    data = Uint8Array.from([240, 159, 142, 169, 240, 159, 144, 176]);
    Uint8Array [ 240, 159, 142, 169, 240, 159, 144, 176 ]
    codec.b64enc(data);
    '8J+OqfCfkLA='
  • Decode given Base64 string to byte array. Base64 decoding in browser and node.js.

    data = codec.b64dec('8J+OqfCfkLA=');
    Uint8Array [ 240, 159, 142, 169, 240, 159, 144, 176 ]
    codec.bytesToString(data);
    '🎩🐰'

hex encoding and decoding

  • Convert hex-encoded string to a byte representation.

    codec.hexToBytes('cabafa87');
    Uint8Array [ 202, 186, 250, 135 ]
    codec.hexToBytes('0x1234567890ABCDEF');
    Uint8Array [ 18, 52, 86, 120, 144, 171, 205, 239 ]
  • Convert byte representation to a hex-encoded string.

    codec.bytesToHex(Uint8Array.from([31, 63, 127, 255]));
    '1f3f7fff'

byte array manipulation

  • Concatenate contents of a given byte arrays.

    codec.concatBytes(
        Uint8Array.from([255, 255, 0, 0]),
        codec.stringToBytes('🌍'),
        Uint8Array.from([128, 64]),
    );
    Uint8Array [ 255, 255, 0, 0, 240, 159, 140, 141, 128, 64 ]
  • Compare two byte arrays.

    codec.compareBytes(
        codec.stringToBytes('𝓬𝓸𝓭𝓮'.normalize('NFC')),
        codec.stringToBytes('𝐜𝐨𝐝𝐞'.normalize('NFC')),
    );
    false
    codec.compareBytes(codec.hexToBytes('0xFF'), Uint8Array.from([255]));
    true

functional programming

  • Function composition.

    func.compose(
        string.quote,
        string.shorten,
    ) (
        "When I find myself in times of trouble",
        20, string.shorten.END,
    );
    '"When I find myself …"'
    stringToHex = func.flow(codec.stringToBytes, codec.bytesToHex);
    [Function]
    stringToHex('Kaboom! 💥');
    '4b61626f6f6d2120f09f92a5'
    func.pipe('4b61626f6f6d2120f09f92a5') (
        codec.hexToBytes, codec.bytesToString
    );
    'Kaboom! 💥'
  • Translate the evaluation of function f taking multiple arguments into an evaluation of sequence of functions, each with a single argument.

    addition = (a, b, c) => a + b + c;
    [Function: addition]
    func.curry(addition) (1) (2) (3);
    6
  • Function arguments rearrangement.

    console.log('a', 'b', 'c', 'd', 'e');
    a b c d e
    revConsole = rearg(console.log) (4, 3, 2, 1, 0);
    revConsole('a', 'b', 'c', 'd', 'e');
    e d c b a
    revConsole('f') ('g', 'h') ('i') ('j');
    j i h g f
  • Y-combinator - returns fixed point of a higher-order function passed as f. Anonymous recursion in Javascript.

    factorial = func.Y((r) => (n) => n <= 0  ?  1  :  n * r(n - 1));
    [Function]
    factorial(5);
    120

simple math

  • Compute mathematical average of array of numbers.

    math.average([1, 2, 3, 4, 5]);
    3
  • Base 2 logarithm.

    math.log2(2**32);
    32
  • Base 10 logarithm.

    math.log10(1e9);
    9
  • Sum of numbers in passed array.

    math.sum([5, 6, 7, 8, 9, 10]);
    45

operating on strings

  • Allocate a big string (of size 2^n).

    string.big(5);
    'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
  • Convert camelText to snake_text.

    string.camelToSnake('someNightsIStayUpCashingInMyBadLuck');
    'some_nights_i_stay_up_cashing_in_my_bad_luck'
  • Quote text.

    string.quote('div', '<>');
    '<div>'
  • Construct random string of desired length.

    string.random(16);
    'MxWGe8MoOss0yUAP'
  • Shorten a given string to the desired length.

    string.shorten('abcdefghijklmnopqrstuvwxyz', 15);
    'abcdefg…tuvwxyz'
    string.shorten(
        'To be, or not to be, that is the question',
        20,
        string.shorten.END,
    );
    'To be, or not to be…'
  • Convert snake_text to camelText.

    string.snakeToCamel('some_nights_i_call_it_a_draw');
    'someNightsICallItADraw'

data structure manipulation

  • Apply path to an object.

    struct.access({ a: { b: { c: 42 } } }, ['a', 'b', 'c']);
    42
  • Construct Object from the result of Object.entries() call. entries = [[k1, v1,], ..., [kn, vn,]]

    struct.dict([['a', 'b'], ['c', 'd'], ['e', 'f']]);
    { a: 'b', c: 'd', e: 'f' }
  • Shallow map (iteration) on objects.

    struct.objectMap(
        { what: 'od', i: '?rof dnats' },
        ([k, v,]) => [
            string.capitalize(k),
            v.split('').reverse().join(''),
        ],
    );
    { What: 'do', I: 'stand for?' }
  • Swap keys with values in a given Object.

    struct.swap({ a: 'b', c: 'd', e: 'f' });
    { b: 'a', d: 'c', f: 'e' }

type primitives

  • Determine if a given value is a proper Number (not NaN and not Infinity).

    [type.isNumber(NaN), type.isNumber(-Infinity), type.isNumber(1234.5678)]
    [ false, false, true ]
  • Determine if a given value is an Object (not null, not undefined and not Array).

    [type.isObject(null), type.isObject([]), type.isObject({})]
    [ false, false, true ]

notes

This library is suitable to use in server and browser environments and it is being used as such. Go ahead and file an issue or submit a fresh PR if you found a bug 🐞.

support

You can support this project via stellar network:

license

js-toolbox is released under the Apache License, Version 2.0. See the LICENSE for more details.