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

hook-fn

v1.0.6

Published

A library which provides pre-execution and post-execution hooks both as a decorator and as a higher-order function.

Downloads

1,265

Readme

What is it?

This is an implementation (usable both as a decorator and as a higher-order function) that can be used to hook into a function execution and allows you to do something before and after such execution.
It can be used both with sync and async functions.

How do I install it?

You can install it by using the following command:

npm install hook-fn

How do I use it?

As a decorator

import { Hook } from 'hook-fn';

class MyClass {
  @Hook({
    before: ({context, args, target, propertyKey, descriptor}) => {
      console.log('Before');
    },
    after: ({context, args, target, propertyKey, descriptor, result}) => {
      console.log('After');
    },
  })
  public myMethod(): void {
    console.log('Hello World!');
  }
}

As a higher-order function

import { hook } from 'hook-fn';

const testFn = function (str) {
  return str;
};

const mockFn = hook({
    before: ({context, args}) => {
      console.log('Before');
  },
    after: ({context, args, result}) => {
    console.log('After');
  }
});

const mockedTestFn = mockFn(testFn);

mockedTestFn('hello world');

A consideration about async functions

When wrapping an async function with hook-fn, be aware that the after hook is executed immediately after the function execution (without waiting for the Promise fulfillment), so a Promise will be passed to the result argument, despite its resolution or rejection.
If you want to execute something after the async function is resolved or rejected, you can use the then or catch methods of the returned promise.

import { hook } from 'hook-fn';

const testFn = async function (str) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(str);
    }, 1000);
  });
};

const mockFn = hook({
  before: ({context, args}) => {
    console.log('Before');
  },
  after: ({context, args, result}) => {
    result.then((res) => {
      console.log('After');
    });
  }
});

const mockedTestFn = mockFn(testFn);

mockedTestFn('hello world');

How does it work?

Decorator

The decorator will provide two functions to be executed before and after the method to which it is applied.
It expects an object with the following properties:

  • before: A function to be executed before the method to which it is applied. Defaults to a function that does nothing. It will be called with the following parameters:
    • context: The context of the method to which it is applied
    • args: The arguments passed to the method to which it is applied
    • target: The method to which it is applied
    • propertyKey: The name of the method to which it is applied
    • descriptor: The descriptor of the method to which it is applied.
  • after: A function to be executed after the method to which it is applied. Defaults to a function that does nothing. It will be called with the following parameters:
    • context: The context of the method to which it is applied
    • args: The arguments passed to the method to which it is applied
    • target: The method to which it is applied
    • propertyKey: The name of the method to which it is applied
    • descriptor: The descriptor of the method to which it is applied.
    • result: The result of the method to which it is applied. If the method is async, it will be a Promise.

Higher-order function

The higher-order function will provide two functions to be executed before and after the method to which it is applied.
It expects an object with the following properties:

  • before: A function to be executed before the method to which it is applied. It will be called with the following parameters:
    • context: The context of the method to which it is applied
    • args: The arguments passed to the method to which it is applied
  • after: A function to be executed after the method to which it is applied. It will be called with the following parameters:
    • context: The context of the method to which it is applied
    • args: The arguments passed to the method to which it is applied
    • result: The result of the method to which it is applied. If the method is async, it will be a Promise.

Other Info

Why didn't we use bind in the Hook context passed to the before and after functions?

We could have used bind to provide the context to the functions, but we prefered not to do so because it would have needed the developers using our library to know about the context of the method to which it is applied and the implications of using bind in such a way.

Tests

You can run the tests by using the following command:

npm test