precursor

Cloning made easy.

Usage no npm install needed!

<script type="module">
  import precursor from 'https://cdn.skypack.dev/precursor';
</script>

README

Precursor Build Status

Precursor is the JavaScript that could have been.

Usage

Let's start with an example. We'll create a function that draws a circle on a canvas.

var Draw = Precursor.clone;

Draw.lazy(function canvas() {
  return document.createElement('canvas');
});

Draw.lazy(function ctx() {
  return this.canvas.getContext('2d');
});

Mutating Methods

  • Precursor.def( fn )
  • Precursor.getter( fn )
  • Precursor.lazy( fn )
  • Precursor.flag( name, properties )

Cloning Methods

  • Precursor.with()
  • Precursor.clone
  • Precursor.tap()
  • Precursor.promise()
  • Precursor.then()
  • Precursor.catch()

#def( namedFunction )

def is used to assign non-enumerable functions. Values can be assigned with #def( name, value ).

#getter( namedFunction )

Similar to def except getters are called without parenthesis:

var Invoice = Precursor.clone;

Invoice.getter(function isDue() {
  return this.dueDate < new Date();
});

var invoice = Invoice.set({dueDate: new Date(2020)})

invoice.isDue === false;

#lazy( namedFunction )

lazy is just like getter, but it re-assigns itself as the return value of the passed function.

#with( attributes )

Create a clone with the passed attributes appended:

var person = Precursor.with({
  first_name: "John",
  last_name: "Doe"
});

#flag( name, attributes )

flag is a shortcut for creating a getter that returns a clone with attributes appended:

var Order = Precursor.clone;

Order.flag('asShipped', {status: 'shipped'});
Order.flag('asDelivered', {status: 'delivered'});

var order1 = Order.asShipped;
var order2 = order1.asDelivered;

order1.status === 'shipped';
order2.status === 'delivered';

#clone

#tap( fn )

tap creates a clone, applies fn to it, and then returns it. The clone is also passed as the first argument.

Precursor.tap(function(clone) {
  this === clone;
});

#promise( fn )

Precursor promises require an ES6-compatible window.Promise object. Alternatively, you can set your own: Precursor.def('Promise', RSVP.Promise). Precursor promises are lazy: fn isn't invoked until #then() has been called on a clone.

#then( onResolved, onRejected )

#catch( onRejected )