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

@zzkit/pro-pipe

v0.1.0

Published

`@zzkit/pro-pipe` is a simple library for chaining functions. It supports both synchronous and asynchronous functions, passing context, and breaking the chain when needed.

Downloads

5

Readme

@zzkit/pro-pipe

@zzkit/pro-pipe is a simple library for chaining functions. It supports both synchronous and asynchronous functions, passing context, and breaking the chain when needed.

Installation

npm install @zzkit/pro-pipe

or

yarn add @zzkit/pro-pipe

Why?

When you have a sequence of asynchronous operations with conditions, your code can quickly become complex and hard to follow. It often leads to deeply nested then chains or early returns, making it difficult to maintain. @zzkit/pro-pipe simplifies this by flattening these chains and giving you control over the flow, including breaking out of the sequence when needed.

Without @zzkit/pro-pipe:

initSession().then(() => {
  return getUser().then((user) => {
    if (!user) return getDefaultUser().then((defaultUser) => setUser(defaultUser));
    
    if (user.isGuest) {
      return;
    }
    
    return getUserPreferences(user.id).then((prefs) => {
      if (!prefs) return;
      updateUI(prefs);
    });
  });
});

This pattern of if checks and return statements makes the flow harder to follow, especially as it grows. With @zzkit/pro-pipe, you can replace these return statements with break() for a clearer flow.

With @zzkit/pro-pipe:

pipeWith(
  {},
  initSession,
  getUser,
  (user, ctx) => user || getDefaultUser(),
  (user, ctx) => {
    if (user.isGuest) return ctx.break();
    return user;
  },
  (user) => getUserPreferences(user.id),
  updateUI
)();

In this version, the break() function simplifies the conditional exit, making the pipeline cleaner and easier to understand. If the user is a guest, the pipeline breaks early, avoiding unnecessary operations. This structure is not only more readable but also more efficient.

Usage

Basic Example

Chain multiple functions together:

import { pipe } from '@zzkit/pro-pipe';

const addOne = (x) => x + 1;
const double = (x) => x * 2;
const square = (x) => x * x;

const pipeline = pipe(addOne, double, square);

pipeline(2).then((result) => console.log(result)); // 36

Async Functions

You can mix async and sync functions:

import { pipe } from '@zzkit/pro-pipe';

const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const asyncDouble = async (x) => {
  await delay(100);
  return x * 2;
};

const pipeline = pipe((x) => x + 1, asyncDouble, (x) => x * x);

pipeline(2).then((result) => console.log(result)); // 36

Using Context

Add a context that gets passed between functions:

import { pipeWith } from '@zzkit/pro-pipe';

const pipeline = pipeWith(
  { multiplier: 3 },
  (x) => x + 1,
  (x, ctx) => x * ctx.multiplier,
  (x) => x * x
);

pipeline(2).then((result) => console.log(result)); // 81

Breaking the Chain

You can stop the chain early if needed:

import { pipeWith } from '@zzkit/pro-pipe';

const pipeline = pipeWith(
  {},
  (x) => x + 1,
  (x, ctx) => {
    if (x >= 5) ctx.break();
    return x * 2;
  },
  (x) => x * x
);

pipeline(2).then((result) => console.log(result)); // 36 (no break)
pipeline(4).then((result) => console.log(result)); // 10 (breaks early)

Composing Pipelines

You can nest pipes within pipes:

import { pipe } from '@zzkit/pro-pipe';

const composedPipeline = pipe(
  (x) => x + 1,
  pipe((x) => x * 2, (x) => x * x), // Nested pipe
  (x) => x + 5
);

composedPipeline(2).then((result) => console.log(result)); // 41

License

MIT