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

pipe-debug

v0.1.7

Published

pipeline debugging and performance measuring microtool

Downloads

19

Readme

pipe-debug

Why it's useful

Array method chaining

When you're doing stuff like this:

const output = myArray
  .map(addSomeComputedProperty)
  .map(andDoSomeOtherThing)
  .reduce(onlyTheOriginalAuthorUnderstands)
  .sort()
  .reverse();

Add .map(debugArray()) between those statements to get some console.log output for what the values are at that point. You can also add labels or custom callbacks.

const output = myArray
  .map(addSomeComputedProperty)
+ .map(debugArray()) // console.log the value at this point in the chain
  .map(andDoSomeOtherThing)
+ .map(debugArray('ziltoid')) // console.log an object: `{ ziltoid: theValueAtThisPoint }`
  .reduce(onlyTheOriginalAuthorUnderstands)
+ .map(debugArray(customLogger)) // override everything with your own custom logger
  .sort()
  .reverse();

You can turn it off globally with setDebugMode(false).

Ramda's pipe/compose and Lodash's flow

Works as you would expect, same as above except you use debugPipe.

const addOne = add(1);
const simpleArray = pipe(
  debugPipe(), // just console.logs the value
  map(addOne),
  debugPipe('end'), // console.logs `{ end: theValue }`
  map(addOne),
  debugPipe(customLogger), // sends the value to a custom logger
)([1, 2, 3, 4, 5]);

Actual debugger lines

In the above examples where you see customLogger, consider that you can pass something like this:

pipe(
...
  debugPipe(() => { debugger; }),
...
)()

or this

array
...
  .map(debugArray(() => { debugger; }))
...

Now, if you're one of those cool-kids that has a debugger actually working in your project, you can add breakpoints in this way.

Performance Metrics

But simple logging isn't all this can do. It also can track the time it takes for each portion of your pipe, if you're doing pipeline style.

const output = pipe(
  () => [1, 2, 3],
  startTimings('bigDataProcessingJob'),
  map(add(1)),
  debugPipe('first addition'),
  map(multiply(10)),
  debugPipe('second addition'),
  endTimings(),
)()

This outputs a performance report with the milliseconds between each step:

{
  "bigDataProcessingJob": [
    { "first addition": 123.4 },
    { "second addition": 567.8 },
  ]
}

Frequently Asked Questions

Q: Isn't this like ramda/tap or rxjs/tap?

A: Yes, it is similar. The difference for me is that it's already wired up and ready for the debugging workflow, complete with labels for ease of use. Combine that with the performance and timing capabilities, and it's suddenly worth creating this package.

Q: What's the test coverage for this like?

A: 100%. Now, I haven't (yet?) instituted istanbul to prove it.

Q: How many dependencies are there?

A: Zero.

Q: Are there TypeScript types?

A: You betcha.

Q: how can I turn a bunch of statements off all at once without having to comment them out or remove them?

A: just use setDebugMode to false. Don't worry, it short circuits so aside from the cost of the function closure and the single if statement at the beginning of the function source, there should be no performance impact.

Q: Are you using Date.now() for the performance timings.

A: Nah. performance.now() is where it's at. This is also the reason why node v8.5.0 and above is required.

Q: What's the history of this code?

A: I've been using it for years, actually, and finally decided that instead of copy/pasta'ing it on various projects to just publish an npm for it.

Q: is "performant" a word

A: sure, why not?

Caveats

  1. This tool is intended for inspection and debugging only. If you mutate the data in your custom callback... well... then I wish you the best in your future endeavors, haha. I could use TypeScript to try to make this harder to accidentally do, but opted not to because there are so many existing APIs (including most of lib.dom, for example) that don't use Readonly<> and readonly, even if the functions don't actually mutate.