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

classy-js

v2.1.0

Published

A demure class constructor constructor. Extensible, simple, bare.

Downloads

60

Readme

Classy

A simply demure class library.

All Composition: All Class.

Author: Jordan Timmerman (@skorlir)

Built at the Northwestern University WCAS Multimedia Learning Center

Build Status

What is this and Why

Classy is a crazy experiment in just how far you can go, and just how little you really need, to create useful, versatile, extensible class objects in Javascript.

This is the premise:

You don't need prototypes. You don't need class. You don't need super or extend. With a small set of powerful functions for composing simple data structures, you can build anything.

It's a no-class class system. It's simple. It's Classy.

Features

Classy is a composeable class constructor constructor. Anyplace you might imagine yourself using function and prototypes, you can use ClassyClasses instead.

  • ClassyClasses are objects (using Object.create(null))
  • Everything is defined with composition
  • Every feature is a plugin, defined as a composeable function
  • There's no contextual this (powered by Selfish)
  • The syntax is so simple your cat could sit on your keyboard and use it by accident
  var aClass = Classy(function (self) {
      self.field = 'value'
      self.method = function () {}
      // return is implied
  })

Usage

Show me some code

var TrivialClass = Classy(function () {})

TrivialClass()

Is the simplest possible Classy Class.

This will return an Object ({}) that has absolutely no fields or methods, and no prototype.

Adding Features

Composition is first-class in Classy, and everything that Classy does is an application of composition.

Check it out:

// A couple of features we want to mix in
var IsInstance = require('classy-js/core/is-instance')
  , ToString   = require('classy-js/core/to-string')
  , Compose    = require('classy-js/core/compose')

var Classy = require('classy-js')

// We want all our ClassyClasses to have `isInstance`, so let's create
//  a "class medium" for creating ClassyClasses that have it.
var Medium = Classy().use(IsInstance)

// Now we can `define` classes from that Medium
var Animal = Medium.define(function (animal, type) {
  animal.type = type
})

// Equivalently, we could have done:
var Animal = Classy()
  .use(IsInstance)
  .define(function (animal, type) {
    animal.type = type
  })

// But using a Medium makes things a bit cleaner.

// Let's use that Animal class.
var Dog = Medium
  .use(ToString) // You can add another feature to the medium just for Dog
  .define(function (dog, name) {
    dog.name = name
  })
  .use(Compose(Animal, 'Dog'))

// So now Dog is "composed with" Animal.
// Let's add in some Dog actions.

// Dogs can bark
function Bark (dog) {
  dog.bark = function () {
    return dog.name + ' is barking! Woof! Woof!'
  }
}

// They can wag their tails
function WagTail (dog) {
  dog.wagTail = function () {
    return dog.name + ' is wagging his tail!'
  }
}

// Okay, let's compose those into Dog
Dog = Dog.use([ Bark, WagTail, ToString ])
// Notice that we can also add ToString to Dog here
// We added ToString to the Dog _class_, and now we're adding it to
//   every Dog _instance_.

// Let's play around with our new ClassyClasses!

Dog.toString()
// => Dog { toString: fn, isInstance: fn, constructor: function (dog...) {...} }

var fido = Dog('Fido')
// => { name: 'Fido', type: 'Dog', bark: fn, wagTail: fn, toString: fn }

fido.bark()     // => 'Fido is barking! Woof! Woof!'
fido.wagTail()  // => 'Fido is wagging his tail!'
fido.type       // => 'Dog'
fido.toString()
// => { name: 'Fido', type: 'Dog', bark: fn, wagTail: fn, toString: fn }

// We can check instances, too:
Animal.isInstance(fido) // true
Dog.isInstance(fido)    // true
Dog.isInstance(extend({}, fido, { type: 'Cat' }))    // false
Animal.isInstance(extend({}, fido, { type: 'Cat' })) // true

Bare by Default

Because ClassyClasses use Object.create(null) as their basis, classes are entirely bare by default - this is why every feature is a plugin, and why ClassyClasses have no prototypes or this.

Here's an explicit, albeit contrived, example:

var Truth = Classy(function (self) {
 self.life = 42
})

var theTruth = Truth()
// => { life: 42 }

theTruth.prototype
// => undefined

Object.getPrototypeOf(theTruth)
// => null

for (var fact in theTruth) {
 console.log('The Truth is ', fact, '=', theTruth[fact])
}
// [logged]: The Truth is life = 42

[ 'toString', 'valueOf', 'isPrototypeOf', 'hasOwnProperty' ].map(function (junk) {
 if (theTruth[junk]) return junk
})
// => []