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

lodasync

v1.0.7

Published

Functional async utility functions for clean code

Downloads

431

Readme

Lodasync

npm Travis (.org) Coveralls github

Lodasync is an asynchronous functional programing utility library heavily inspired by lodash/fp. It has no dependencies, is lightweight, has a strong focus on performance, and is fully tested and documented.

Why Lodasync?

Lodasync makes asynchronous JavaScript easier by taking the hassle out of working with promises, arrays, and asynchronous callbacks.

  • Work with promises the way you work with synchronous code
  • Do not re-invent the wheel and rely on fully tested and documented code
  • Use functions that are performance oriented, don't waste time benchmarking yourself
import { filterAsync } from 'lodasync'
 
const users = await filterAsync(async(user) => {
  // => use async code! 🎉
}, getUsers())

Table of contents

Getting started

Install Lodasync using npm.

npm i lodasync

In Node.js and in a browser:

import { 
  mapAsync, 
  flowAsync, 
  filterAsync, 
  flatMapAsync, 
  uniqByAsync, 
  getAsync, 
} from 'lodasync'

// Some async function
const getUser = async(id) => db('users').where('id', id) 

// Write async code like you write synchronous code
const users = await mapAsync(getUser, ['user-1-id', 'user-2-id'])

// Pass promises as arguments to any method
const users = await mapAsync(getUser, await getUserIds()) // Don't ❌
const users = await mapAsync(getUser, getUserIds()) // Do ✅

// And even array of promises
const users = await mapAsync(getUser, [await promiseId1, await promiseId2]) // Don't ❌
const users = await mapAsync(getUser, [promiseId1, promiseId2]) // Do ✅

// Callback arguments are always resolved
const users = await filterAsync(async(userId) => isAdmin(await userId), [promiseId1, promiseId2]) // Don't ❌
const users = await filterAsync(isAdmin, [promiseId1, promiseId2]) // Do ✅

// Returned array elements are always resolved
const users = await mapAsync(getUser, ['user-1-id', 'user-2-id'])
const name = (await users[0]).name // Don't ❌
const name = users[0].name // Do ✅

// All methods are curried
const getUsers = mapAsync(getUser)
const users = await getUsers(['user-1-id', 'user-2-id'])

// Curry is useful for chaining
const authors = await flowAsync(
  mapAsync(getArticle),
  filterAsync(isPublished),
  flatMapAsync(getAuthors),
  uniqByAsync(getAsync('id')),
)(['article-1-id', 'article-2-id', /*...*/])

Note on parallelism

Callbacks are always called in parallel on all elements to maximize speed. This also includes methods like findAsync or findIndexAsync, even tho their synchronous counterpart stops on the first match.

API

everyAsync(callback, collection)

Implementation of native Array.prototype.every().

filterAsync(callback, collection)

Implementation of native Array.prototype.filter().

findAsync(callback, collection)

Implementation of native Array.prototype.find().

findIndexAsync(callback, collection)

Implementation of native Array.prototype.findIndex().

flatMapAsync(callback, collection)

Implementation of native Array.prototype.flatMap().

flowAsync(...callbacks)

Creates a function that returns the result of invoking all callbacks in series, where each successive invocation is supplied the return value of the previous.

Note that callbacks do not have to be asynchronous, you can mix synchronous and asynchronous code.

Example

const getUserIds = async() => { /*...*/ }
const getUser = async(id) => { /*...*/ }
const isAuthorized = async(user) => { /*...*/ }

const getAuthorizedUsers = flowAsync(
  mapAsync(getUser), 
  filterAsync(isAuthorized),
)

const authorizedUsers = await getAuthorizedUsers(getUserIds())

forEachAsync(callback, collection)

Iterate over an array in parallel.

Arguments

  • callback
    A function that is invoked for each element. It takes the following arguments:
    • element
      The current element in the collection.
    • index
      The index of the current element in the collection.
    • collection
      The collection.
  • collection
    The collection to iterate over.

Return value

Always returns undefined.

Example

await forEachAsync(inviteUser, getUsers())

getAsync(path, object)

Gets the value at path of object.

Arguments

  • path
    An array of keys, or a string that should be split on dots. When its a string, path does not support the array notation [index], use the dot notation instead .index
  • object
    The object from which to get the property.

Return value

The resolved value.

Example

const article = {
 authors: Promise.resolve([
   {
     name: Promise.resolve('John'),
   },
   {
     name: Promise.resolve('Carol'),
   },
  ]),
}

await getAsync('authors.0.name', article) // => 'John'
await getAsync(['author', 0, 'name'], article) // => 'John'

// Often used to get an object key of a promise
const name = await getUser().then(user => user.name) // Don't ❌
const name = await getAsync('name', getUser()) // Do ✅

// Or as an iteratee
const names = await mapAsync(getAsync('name'), getUsers())

getOrAsync(defaultValue, path, object)

Works like getAsync with a custom defaultValue when the resolved value is undefined.

groupByAsync(callback, collection)

Creates an object composed of keys generated from the results of running each element of collection thru callback. The order of grouped values is determined by the order they occur in collection. The corresponding value of each key is an array of elements responsible for generating the key.

Arguments

  • callback
    A function that should return a key for each element. It takes the following arguments:
    • element
      The current element in the collection.
    • index
      The index of the current element in the collection.
    • collection
      The collection.
  • collection
    The collection to iterate over.

Return value

The composed aggregate object.

Example

const getFirstName = async(user) => { /*...*/ }

await groupByAsync(getFirstName, [john1, carol1, john2])
// => { John: [john1, john2], Carol: [carol1] }

mapAsync(callback, collection)

Implementation of native Array.prototype.map().

maxByAsync(callback, collection)

Computes the maximum value of collection by invoking callback for each element to generate the criterion by which the value is ranked.

Arguments

  • callback
    A function that should return a criterion for each element. It takes the following arguments:
    • element
      The current element in the collection.
    • index
      The index of the current element in the collection.
    • collection
      The collection.
  • collection
    The collection to iterate over.

Return value

The maximum value of collection, undefined if the collection is empty.

Example

const getItemPrice = async(item) => { /*...*/ }

await maxByAsync(getItemPrice, [item1, item2, item3])
// => item3

minByAsync(callback, collection)

Computes the minimum value of collection by invoking callback for each element to generate the criterion by which the value is ranked.

Arguments

  • callback
    A function that should return a criterion for each element. It takes the following arguments:
    • element
      The current element in the collection.
    • index
      The index of the current element in the collection.
    • collection
      The collection.
  • collection
    The collection to iterate over.

Return value

The minimum value of collection, undefined if the collection is empty.

Example

const getItemPrice = async(item) => { /*...*/ }

await minByAsync(getItemPrice, [item1, item2, item3])
// => item2

propsAsync(object)

Returns a promise that resolves when all values of object are resolved. Mostly used for parallelism.

Example

// This is run sequentially
const user = await getUser(userId)
const article = await getArticle(articleId)
const comment = await getComment(commentId)

// This is run in parallel
const { user, article, comment } = await propsAsync({
  user: getUser(userId),
  article: getArticle(articleId),
  comment: getComment(commentId),
})

reduceAsync(callback, initialValue, collection)

Implementation of native Array.prototype.reduce().

someAsync(callback, collection)

Implementation of native Array.prototype.some().

sortByAsync(callback, collection)

Sorts collection by invoking callback for each element to generate the criterion by which the value is ranked. This method performs a stable sort, that is, it preserves the original sort order of equal elements.

The criterion can be

  • a number: using number comparison
  • a string: using string comparison
  • Infinity: always sorted at the end
  • -Infinity: always sorted at the beginning

Arguments

  • callback
    A function that should return a criterion for each element. It takes the following arguments:
    • element
      The current element in the collection.
    • index
      The index of the current element in the collection.
    • collection
      The collection.
  • collection
    The collection to iterate over.

Return value

The sorted collection.

Example

const getItemPrice = async(item) => { /*...*/ }

await sortByAsync(getItemPrice, [item7, item2, item3])
// => [item2, item3, item7]

uniqByAsync(callback, collection)

Creates a duplicate-free version of collection. callback is invoked for each element to generate the criterion by which uniqueness is computed. Only the first occurrence of each element is kept. The order of result values is determined by the order they occur in the array.

Arguments

  • callback
    A function that should return a criterion for each element. It takes the following arguments:
    • element
      The current element in the collection.
    • index
      The index of the current element in the collection.
    • collection
      The collection.
  • collection
    The collection to iterate over.

Return value

The new duplicate free collection.

Example

const getUserId = async(user) => { /*...*/ }

await uniqByAsync(getUserId, [user10, user7, user10])
// => [user10, user7]