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

mchammer

v1.1.4

Published

Sort-of-immutable objects

Downloads

10

Readme

MC Hammer

NPM version Build Status Coverage Status

This is a really simple library for creating sort-of-immutable data structures in Javascript. It's called "MC Hammer" because you "can't touch this". Why might you want to use it? Mainly because you are interested in referential transparency and want something to remind you about immutability.

This library does not provide deep immutability of built-ins like seamless-immutable or a rich API like Immutable. What it gives you is an easy way to create and (non-destructively) update objects that have read-only properties and methods.

Installation

This library is available through NPM or Bower and it is packaged as a UMD bundle.

npm install mchammer

or

bower install mchammer

and if you are using node/commonjs

var Model = require('mchammer').Model,
	Foo = Model()

or AMD

define(['mchammer'], function (mchammer)
{
	var Foo = mchammer.Model()
})

or neither

var Foo = mchammer.Model()

Basics

You create a model by defining what properties are allowed and their defaults as well as any methods.

var Model = require('mchammer').Model

var Writer = Model(
{
	fields: {
		name: 'Unknown',
		number_of_books: 0,
		something: 'Derp!'
	},
	
	methods: {
		say_something: function ()
		{
			return this.something
		}
	}
})

Then you can create instances of the new model, specifying only the properties that have a value different from the defaults.

var writer = new Writer(
{
	name: 'Stephen King',
	number_of_books: 54
})

console.log(writer.name) // "Stephen King"
console.log(writer.something) // "Derp!"
writer.say_something() // "Derp!"

You can't change any of the properties.

writer.something = 'Boo!' // TypeError("Cannot assign to read only property 'something' of [object Object]")

But you can easily create a modified copy by specifying the properties you want to change

var the_real_writer = writer.update({ something: 'Boo!' })
the_real_writer.say_something() // 'Boo!'

Fields

To define the fields a Model has, use the fields options.

var Foo = Model({ fields: { name: 'Steve' } }),
	foo = new Foo()
console.log(foo.name) // 'Steve'

Fields can also be functions, in which case they are transformers for whatever value is passed in during instantiation, including undefined.

var Foo = Model({ fields: { name: function (x) { return (x ? 'Steve '+x : 'Nameless') } } }),
	foo1 = new Foo(),
	foo2 = new Foo({ name: 'Blobface' })

console.log(foo1.name) // 'Nameless'
console.log(foo2.name) // 'Steve Blobface'

Fields are immutable. Don't bother trying to set them.

foo2.name = 'Andrea Blobface' // TypeError("Cannot assign to read only property 'name' of [object Object]")

Also, if you didn't define a field when you created the model, you can't do it later.

var Foo = Model(),
	foo1 = new Foo(),
	foo2 = new Foo({ stuff: 'things' }) // Error('Unknown field "stuff"'),
	foo3 = foo1.update({ skidoo: 23 }) // Error('Unknown field "skidoo"')

Inheritance

Existing models can be extended.

var Model = require('mchammer').Model

var Instrument = Model(
{
	fields: {
		sound: '...'
	},
	
	methods: {
		play: function ()
		{
			return this.sound
		}
	}
})

var Guitar = Model.extend(Instrument,
{
	fields: {
		sound: 'Twang Twang'
	}
})

var Martin = Model.extend(Guitar)

var martin_guitar = new Martin()
martin_guitar.play() // 'Twang Twang'
martin_guitar.constructor == Martin // true
Model.is_instance(martin_guitar, Martin) // true
Model.is_instance(martin_guitar, Instrument) // true

Comparisons

You can Deeply compare two Model instances like so

var SweetMove = Model({
		fields: {
			name: 'spin',
			danger_level: 1
		}
	}),
	spin = new SweetMove(),
	twirl = new SweetMove(),
	cartwheel = new SweetMove({ name: 'cartwheel', danger_level: 5 })

spin.equals(twirl) // true
spin.equals(cartwheel) // false

You can also compare only based on a subset of properties, like this:

var backbend = new SweetMove({ name: 'backbend', danger_level: 5 })
cartwheel.equals(backbend) // false
cartwheel.equals(backbend, ['danger_level']) // true

Contributing

If you see an open issue you want to tackle, be my guest. If you have a problem or feature suggestion, please create a new issue. Thanks!