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

rotery

v0.4.0

Published

A utility library for iterative processes, with asynchronous support, type safety, and functional programming style.

Downloads

437

Readme

Rotery

A utility library for iterative processes, with asynchronous support, type safety, and functional programming style.

Installation

npm i rotery
yarn add rotery
pnpm add rotery

Then in .js or .ts

import * as Rt from 'rotery'; // tree-shaking supported!

Usage

import * as Rt from 'rotery';
import { dataAccess } from './some-asynchronous-data-access.js';

const result = await Rt.pipe(
    userIds,
    // Process each unit of 100 ids in parallel.
    Rt.chunk.sync(100),
    Rt.map.async(async ids => await dataAccess.findUsersByIds(ids)),
    Rt.flatten.async,
    Rt.filter.async(user => user.age >= 20),
    // Find first 10 matched items, then abort rest iterative process.
    Rt.take.async(10),
    Rt.accumulate.async,
);

Features

  • Utility functions (including map, filter, reduce) for Iterators and AsyncIterators.
  • Explicit lazy evaluation by JavaScript iterator feature.
  • Type safe function currying and type safe function composition.
  • Controllable asynchronous iterative processes in both parallel and serial, even with specified concurrency.

Want more general utility functions?

Rotery doesn't have utilities for non-iterative processes. For more general utility, Remeda is the first choice you may want.

Rotery is greatly inspired by Remeda's features: overridden "data-first" and "data-last" functions, "lazy evaluation", and "type-safe" function pipelining.

You can smoothly use Remeda with Rotery combined, because Rotery has compatible pipelining system with Remeda!

Throttling (concurrent async processes)

throttle allows asynchronous processes to be run in a specified level of concurrency.

The results are generated asynchronously in the order of completion, not in the order of input (the first completed result will be emitted first). Please keep in mind that the order of results differs from the order of input.

const responses = await Rt.pipe(
    urls,
    Rt.map.sync(async url => {
        const response = await fetch(url);
        return await response.json();
    }),
    Rt.throttle(5), // This maintains up to 5 concurrent HTTP fetch requests.
    Rt.accumulate.async, // The results are ordered by the completion time.
);

With Node.js stream

You can create Transform stream instances from functions.

import { Transform } from 'node:stream';
import { pipeline } from 'node:stream/promises';
import * as Rt from 'rotery';

const findDataFromDb = Transform.from(
    Rt.compose(
        Rt.map.async(async id => await db.find(id)),
        Rt.filter.async(data => data.value >= 20),
    ),
);

await pipeline(incomingIdStream, findDataFromDb, outgoingDataStream);