🌜
🌞
stampit

stampit

v4.3.2

Create objects from reusable, composable behaviors.

npm install stampit

README

stampit

Stampit Build Status npm Gitter Twitter Follow UNPKG

Create objects from reusable, composable behaviors

Stampit is a 1.4KB gzipped (or 3K minified) JavaScript module which supports three different kinds of prototypal inheritance (delegation, concatenation, and functional) to let you inherit behavior in a way that is much more powerful and flexible than any other Object Oriented Programming model.

Stamps are standardised composable factory functions. Stampit is a handy implementation of the specification featuring friendly API.

Find many more examples in this series of mini blog posts or on the official website.

Example

import stampit from 'stampit'

const Character = stampit({
  props: {
    name: null,
    health: 100
  },
  init({ name = this.name }) {
    this.name = name
  }
})

const Fighter = Character.compose({ // inheriting
  props: {
    stamina: 100
  },
  init({ stamina = this.stamina }) {
    this.stamina = stamina;    
  },
  methods: {
    fight() {
      console.log(`${this.name} takes a mighty swing!`)
      this.stamina--
    }
  }
})

const Mage = Character.compose({ // inheriting
  props: {
    mana: 100
  },
  init({ mana = this.mana }) {
    this.mana = mana;    
  },
  methods: {
    cast() {
      console.log(`${this.name} casts a fireball!`)
      this.mana--
    }
  }
})

const Paladin = stampit(Mage, Fighter) // as simple as that!

const fighter = Fighter({ name: 'Thumper' })
fighter.fight()
const mage = Mage({ name: 'Zapper' })
mage.cast()
const paladin = Paladin({ name: 'Roland', stamina: 50, mana: 50 })
paladin.fight()
paladin.cast()

console.log(Paladin.compose.properties) // { name: null, health: 100, stamina: 100, mana: 100 }
console.log(Paladin.compose.methods) // { fight: [Function: fight], cast: [Function: cast] }

Status

Install

NPM

Compatibility

Stampit should run fine in any ES5 browser or any node.js.

API

See https://stampit.js.org

What's the Point?

Prototypal OO is great, and JavaScript's capabilities give us some really powerful tools to explore it, but it could be easier to use.

Basic questions like "how do I inherit privileged methods and private data?" and "what are some good alternatives to inheritance hierarchies?" are stumpers for many JavaScript users.

Let's answer both of these questions at the same time.

// Some privileged methods with some private data.
const Availability = stampit({
  init() {
    let isOpen = false; // private

    this.open = function open() {
      isOpen = true;
      return this;
    };
    this.close = function close() {
      isOpen = false;
      return this;
    };
    this.isOpen = function isOpenMethod() {
      return isOpen;
    }
  }
});

// Here's a stamp with public methods, and some state:
const Membership = stampit({
  props: {
    members: {}
  },
  methods: {
    add(member) {
      this.members[member.name] = member;
      return this;
    },
    getMember(name) {
      return this.members[name];
    }
  }
});

// Let's set some defaults:
const Defaults = stampit({
  props: {
    name: "The Saloon",
    specials: "Whisky, Gin, Tequila"
  },
  init({ name, specials }) {
    this.name = name || this.name;
    this.specials = specials || this.specials;
  }
});

// Classical inheritance has nothing on this.
// No parent/child coupling. No deep inheritance hierarchies.
// Just good, clean code reusability.
const Bar = stampit(Defaults, Availability, Membership);

// Create an object instance
const myBar = Bar({ name: "Moe's" });

// Silly, but proves that everything is as it should be.
myBar.add({ name: "Homer" }).open().getMember("Homer");

For more examples see the API or the Fun With Stamps mini-blog series.

Development

Unit tests

npm t

Unit and benchmark tests

env CI=1 npm t

Unit tests in a browser

To run unit tests in a default browser:

npm run browsertest

To run tests in a different browser:

  • Open the ./test/index.html in your browser, and
  • open developer's console. The logs should indicate success.

Publishing to NPM registry

npx cut-release

It will run the cut-release utility which would ask you if you're publishing patch, minor, or major version. Then it will execute npm version, git push and npm publish with proper arguments for you.

Release Notes

4.3.2
By Vasyl Boroviak • Published on March 30, 2021
  • 60 bytes smaller GZIP size 262b89c
  • Fix badge - bundle size c6baa48
  • README refresh: remove bower, use latest data and fancier API 6615a58
  • Simplify one of the build scripts 4a58250

https://github.com/stampit-org/stampit/compare/v4.3.1...v4.3.2

4.3.1
By Vasyl Boroviak • Published on December 4, 2019

This whole release is @PopGoesTheWza work on fixing and improving the d.ts files. See "types": "./types/index.d.ts", line in the package.json and the Pull Requests #348 #350

4.3.0
By Vasyl Boroviak • Published on September 15, 2019

JavaScript getters and setters are now no different to string or Symbol properties. This means that you can have getters in methods, properties, static properties, configuration, etc.

Example:

const HasFullName = compose({
  properties: {
    firstName: "",
    lastName: ""
  },
  methods: {
    get fullName() {
        return this.firstName + " " + this.lastName;
    },
    set fullName(name) {
        var words = name.toString().split(" ");
        this.firstName = words[0] || "";
        this.lastName = words[1] || "";
    }
  }
});

const developer = HasFullName();
developer.fullName = "Vasyl Boroviak";
console.log(developer.firstName); // "Vasyl"
console.log(developer.lastName); // "Boroviak"  
console.log(developer.fullName); // "Vasyl Boroviak"
4.2.0
By Vasyl Boroviak • Published on September 16, 2018

Now you can pass "name" property to stampit. It will automatically give your stamp (aka factory) the name. E.g.

const StripeService = stampit({
  name: "StripeService",
  init(_, {stamp}) {
    console.log("Creating an object from the stamp named", stamp.name);
  }
});

const SomeStamp = StripeService;

console.log(SomeStamp.name); // "StripeService"

See this blog post.

4.1.0
By Vasyl Boroviak • Published on March 8, 2018

The stampit.version is now a string which represents its NPM version. E.g. "4.1.1".

4.0.0
By Vasyl Boroviak • Published on November 9, 2017

To migrate to stampit v4 most likely you won't need to do any changes to your codebase.

Please note that NPM registry do not have stampit v4.0.0, instead use v4.0.2. Sorry about that.

BRAKING CHANGES:

  • Removed the previously deprecated refs. Please, use props instead. (Please note, if you are migrating from stampit v2 to v4 you would need to rename props -> deepProps, and then refs -> props. Sorry for the inconvenience. But it looks like the last rename in stampit's life.)
  • Removed stampit/* utility functions. Please use @stamp/is/stamp instead of stampit/isStamp, @stamp/is/composable instead of stampit/isComposable, and @stamp/compose instead of stampit/compose.
  • The composers are now stored in Stamp.compose.composers metadata instead of Stamp.compose.deepConfiguration.composers. Should you care? Probably not. Good thing is - this makes stampit fully compatible with @stamp/* modules ecosystem.

Other notable changes:

  • Stampit is fully compatible with @stamp/* modules ecosystem now.
  • The .min.js bundle is now twice smaller (2.7KB), the gzipped size is 40% smaller - 1.3KB.
  • We run tests in browsers now too.
  • Fixed few bugs - #317 #304 #68
  • Stampit was rewritten in ES5 which allowed the three items above.
  • Updated all the documentations we have in this repo.
3.2.1
By Vasyl Boroviak • Published on September 4, 2017

The assign implementation didn't work sometimes.

3.2.0
By Vasyl Boroviak • Published on September 1, 2017

Community asked. We replied. Support all ES5-compatible environments!

Basically, we added an internal polyfil to not rely on global Object.assign anymore. This added +100 bytes to the stampit.min.js bundle (or +40 gzipped).

3.1.3
By Vasyl Boroviak • Published on April 30, 2017

The Array.prototype.includes() was not polifilled/traspiled. But stampit was using it. Thus, failing to work in some cases under node v4 and IE environments.

3.1.2
By Vasyl Boroviak • Published on January 25, 2017

The new Composers feature fixes.

  1. The composers array was not deduplicated. Now it is.
  2. In case of stamp.compose() syntax the stamp was never passed to composers. Fixed too.

General

License
MIT
Typescript Types
Built-in
Tree-shakeable
No

Popularity

GitHub Stargazers
3,029
Community Interest
3,249
Number of Forks
104

Maintenance

Commits
10/219/2201
Last Commit
Apr 1, 2021
Open Issues
7
Closed Issues
186
Open Pull Requests
0
Closed Pull Requests
32

Versions

Versions Released
10/219/2201
Latest Version Released
Mar 30, 2021
Current Tags
latest4.3.2
rc3.0.0-rc.11

Contributors

koresar
koresar
Commits: 345
FredyC
FredyC
Commits: 26
javascript-journal
javascript-journal
Commits: 21
ericelliott
ericelliott
Commits: 14
PopGoesTheWza
PopGoesTheWza
Commits: 11
troutowicz
troutowicz
Commits: 7
greenkeeperio-bot
greenkeeperio-bot
Commits: 6
greenkeeper[bot]
greenkeeper[bot]
Commits: 5
JosephClay
JosephClay
Commits: 4
johnthad
johnthad
Commits: 2
unstoppablecarl
unstoppablecarl
Commits: 2
sethlivingston
sethlivingston
Commits: 1
rudolf
rudolf
Commits: 1
nkbt
nkbt
Commits: 1
gitter-badger
gitter-badger
Commits: 1