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

patch-method

v0.3.1

Published

Patch / extend / wrap / hook into class methods in a type-safe way

Downloads

5,283

Readme

patch-method

Build Status npm version Download Total code style: prettier dependencies devDependencies

This package allows you to patch class methods in a fully type-safe way. This is especially useful to create decorators that "mixin" methods.

Usage

patchMethod

Allows you to override any method on a given class. Enforces that the passed methodName actually is a method, and enforces that your hook fn has the same type signature as the original method.

The first argument to fn is a superMethod callback that is bound to the instance of the class. This way you can optionally call the original method implementation and also alter the arguments.

import patchMethod from 'patch-method'

class Foo {
  bar(value: number) {
    console.log(`Received: ${value}`)
    return number
  }
}

patchMethod(Foo, 'bar', function(superMethod, value) {
  console.log(`${this.constructor.name}#bar was called with ${value}.`)
  return superMethod(value + 1)
})

const foo = new Foo()
foo.bar(10)
// => 'Foo#bar was called with 10.'
// => 'Received: 11'
// => 11

beforeMethod

Register a hook to be executed before the original method is run. Gets passed the original arguments the method was called with. The return value of the hook is ignored.

import { beforeMethod } from 'patch-method'

class Foo {
  bar(value: number) {
    return number
  }
}

beforeMethod(Foo, 'bar', function(value) {
  console.log(`${this.constructor.name}#bar was called with ${value}.`)
})

const foo = new Foo()
foo.bar(10)
// => 'Foo#bar was called with 10.'
// => 'Received: 10'
// => 10

afterMethod

Register a hook to be executed right after the original method is run. Gets passed the original arguments the method was called with. Also gets passed the return value of the method as the first parameter. The return value of the hook is ignored.

import { afterMethod } from 'patch-method'

class Foo {
  bar(value: number) {
    return number
  }
}

afterMethod(Foo, 'bar', function(returnValue, value) {
  console.log(`${this.constructor.name}#bar was called with ${value}.`)
})

const foo = new Foo()
foo.bar(10)
// => 'Received: 10'
// => 'Foo#bar was called with 10.'
// => 10

Fallback function

Even though this library guarantees that you can only patch methods that the TypeScript compiler knows about, it can't actually guarantee that the method will exist at run time. For instance, you could be patching an incorrectly typed class, or something might have nuked the method at run time.

If you encounter this problem, you can pass a fourth parameter to the utility functions offered by this libarary. This optional fallback parameter accepts a function that has the same signature as the original super method it would substitute. If the original super method is missing at run time, the fallback function will be called in its place with this bound to the class instance.

class Foo {
  bar!: (value: string) => string
}

patchMethod(
  Foo,
  'bar',
  function(superMethod, value) {
    expect(this).toBeInstanceOf(Foo)
    expect(value).toEqual('test')
    return superMethod(value) + 'called'
  },
  function(value) {
    expect(this).toBeInstanceOf(Foo)
    expect(value).toEqual('test')
    return 'fallback' + value
  }
)

const foo = new Foo()

expect(foo.bar('test')).toEqual('fallbacktestcalled')

Acknowledgements

Many thanks to @dfreeman for his support making this util 100 % type-safe, and to the #e-typescript channel on the Ember Community Discord Discord