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

foibles

v0.3.0

Published

Composition and mixins and TypeScript classes

Downloads

9,599

Readme

Foibles

npm version Build Status Coverage Status Dependencies

foible. A quirk, idiosyncrasy, or mannerism; unusual habit or way (usage is typically plural), that is slightly strange or silly. Wiktionary

Foibles is a library for composing JavaScript and TypeScript classes using a mixin pattern.

Foibles is available on NPM: npm install foibles

Creating mixins

Mixins are functions that creates a class that have a dynamic super class. This makes it so that things as super work as intended and that mixins can override functions in their parent class.

import { toMixin } from 'foibles';

const SomeMixin = toMixin(base => class MixinClass extends base {
  doMixinStuff() {
    console.log('mixin did stuff');
  }
});

For TypeScript you should also define the type, to enable you to build functions that consume any object with the mixin:

import { Mixin } from 'foibles';

type SomeMixin = Mixin<typeof SomeMixin>;

If you want to extend a specific class you can use typeof BaseClass to do so:

const SomeMixin = toMixin((base: typeof BaseClass) => class extends base {
  ...
})

Creating a base class

To create an extendable class call toExtendable:

import { toExtendable } from 'foibles';

const BaseType = toExtendable(class BaseClass {
  doStuff() {
    console.log('base class did stuff');
  }
});

For TypeScript you should also define the type, to enable you to build functions that consume the base type:

import { Extendable } from 'foibles';

type BaseType = Extendable<typeof BaseType>;

Using mixins

BaseType will be enhanced with a static with function that provides the mixin functionality. To sub class BaseType and at the same time use SomeMixin:

class SubClass extends BaseType.with(SomeMixin) {

  doStuff() {
    // Allow super class to do stuff
    super.doStuff();

    // doMixinStuff was provided via SomeMixin
    this.doMixinStuff();
  }
}

Use instanceof to check if an object has a mixin:

const object = new SubClass();
console.log(object instanceof SubClass);

Note: It's possible to use instanceof only if Symbol.hasInstance is supported. Check compatibility at MDN

Creating a mixin depending on other mixins

This library supports a mixin to depend on other mixins by applying them as needed in the mixin function:

// Define the first mixin
const Debug = toMixin(base => class Debug extends base {
  debug(...args) {
    console.log(...args);
  }
});

// Create a mixin that applies the Debug mixin to base
const Mixin = toMixin(base => class Mixin extends base.with(Debug) {
  ...
});