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 🙏

© 2025 – Pkg Stats / Ryan Hefner

xt

v0.3.3

Published

Lightweight prototype extend library

Readme

_xt

Super lightweight prototype extend library
No class or static keywords
No heavy thousands of clones
No heavy magic this.super()
just prototype inheritance

_xt.extend(A, B)

assign to constructor A a new instance of function B as its prototype

(new A) instanceof B === true

_xt.extend(A, B, C)

assign to constructor A a new instance of function B as its prototype

(new A) instanceof B === true

assign to the new instance of B, a singleton instance of C as its prototype and store it in A._xxt

(new A) instanceof C === true
A._xxt instanceof C === true

_xt.extend(A, B, C);
_xt.extend(A2, B2, C);
//the expressions below are true
A2._xxt === A._xxt
A2._xxt.constructor === A._xxt.constructor === C

if B and C set a property object called options, the prototype of A will have the merged options of C into B. We could have called it 'static'.

var A = function(){};
var C = function(){
  this.options = {
    option1: true,
    option2: true
  }
_xt.extend(A, function(){
  this.options = {
    option1: false,
    option3: true
  }
}, C);

(new A).options => 
{
  option1: false,
  option2: true,
  option3: true
}

new A does not call C as constructor. You have to do it manually, this is also true for instance methods.

var A = function(){
  A._xxt.constructor.apply(this, arguments);
};
var C = function(){
  this.which = function(){
    return C._xxt.method.call(this) + 'c';
  };
};
_xt.extend(A, function(){
  this.which = function(){
    return A._xxt.method.call(this) + 'a';
  };
}, C);

(new A).which() === 'ca';

This is not magic as the super() method you can see in other libs
But it's fast.

_xt.extend(A, B, C, D, E)

Like

_xt.extend(A, B, C)

But it mixins in A.prototype the D and E objects or prototypes if D and E are functions.

var D = function(){
  this.d = true;
}
_xt.extend(D, function(){
  this.beCareful = true;
  this.isD = function(){
    return true;
  }
});
_xt.extend(A, B, C, D);
var a = new A();

//the expressions below are true
a instanceof C
!(a instanceof D)
a.isD()
a.beCareful
a.d === undefined

You probably want a.d to be true but the mixins constructors are not automatically called. We must modify A to call all its mixins constructors.

var A = function(){
  _xt.constructMixins(this);
}

(new A).d === true

This works because _xt.mixin stores each mixin in an array (this._mixins). ConstructMixins is useful when you have a deep inheritance with many mixins attached. For more granularity, this works as well:

var A = function(){
  D.constructor.call(this);
}

You should be careful when using mixins because the mixin is attached to a prototype potentially used by many others instances. For example, _xt.Notifier is a very simple pubsub constructor which uses an object to store the event handlers.

_xt.Notifier = function(){ this._events = {} };

_xt.extend(A, Pa, null, _xt.Notifier);
_xt.extend(B, Pb, A);
_xt.extend(C, Pc, A);
var a = new A, b = new B, c = new C;

The following is true but you don't want it

a._events === b._events === c._events

Because b.attachEvent('change', bChangeHandler) attach the handler to the change event of a, b and c
a.fireEvent('change') will execute bChangeHandler which is probably not the right behavior
You must think if the constructors should or should not be called.

_xt.mixin(A, [B, C, ..])

Equivalent to

_xt.extend(A, Pa, null, B, C, ...)

See the doc above

_xt.constructMixins(obj)

Call the constructor of each mixin attached to obj passing obj as 'this'. The mixins are stored in obj._mixins.

_xt.merge(obj, obj2, obj3, ...)

Assign all the enumerable properties of obj2, obj3, ... to obj. The replacement is from right to left. It is not a clone.

obj1.x = 1;
obj2.x = 2;
obj3.x = 3;
obj3.prop = { merged: false };
_xt.merge(obj1, obj2, obj3);
obj1.prop.merged = false;
//expressions below are true
obj1.x === 3;
obj3.prop === obj1.prop;
obj3.merged = false;

_xt.mergeProp(obj, propPath, propValue)

Merge a path ('prop1.subProp1.subProp2') in obj and set the propValue so that obj.prop1.subProp1.subProp2 === propValue If propValue and obj[propPath] are both objects, they are merged with _xt.merge, else the value is replaced or created.

_xt.append(obj, obj2, obj3, ...)

Equivalent to _xt.merge(obj, obj2, obj3, ...) but don't replace props if they already exist.

_xt.spliceArgs(args, i, j, obj)

Equivalent to Array.prototype.splice, but for an 'arguments' object

_xt.Notifier

this.attachEvent(name, handler)

Attach to the event called 'name' the handler 'handler'

this.attachEvents(obj)

Attach each event in obj

this.fireEvent(name)

Fire the event called 'name'

this.detachEvent(name, [handler])

if handler, remove the handler to the event called 'name' otherwise, remove the event