Skip to content

Mrt makes creating simple and complex chained interfaces easy!

License

Notifications You must be signed in to change notification settings

FreeAllMedia/mrt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

149 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

npm version license type Build Status Coverage Status Code Climate bitHound Score bitHound Dependencies npm downloads Source: ECMAScript 6

Overview

MrT is a tool for making simple and complex chained interfaces on javascript libraries.

The resulting syntax is easy-to-read while still being flexible and 100% vanilla-js.

// Example interface for a web server

const webServer = new WebServer()

.public
  .get("/account")
    .action(accountController.list)
  .get("/account/:id")
    .action(accountController.show)

.authenticated
  .authorized("owner", "admin")
    .put("/account/:id")
      .action(accountController.update)
  .authorized("admin")
    .post("/account")
      .action(accountController.create)
    .delete("/account/:id")
      .action(accountController.delete)

.listen(3000);

Installation

The easiest and fastest way to install MrT is through the node package manager:

$ npm install mrt --save

API Guide

.initialize(...constructorArguments)

Whenever one constructor extends another, .super must be called in the extended object's constructor before this can be called.

This can be a gotcha for many developers, so MrT has a built-in pseudo-constructor called .initialize that can be used by extended objects without the need to call .super.

import Component from "mrt";

// Without using initialize
class Person extends Component {
  constructor(name) {
    super(name);
    this.properties("name");
    this.name(name);
  }
}

// Using initialize
class Person extends Component {
  initialize(name) {
    this.properties("name");
    this.name(name);
  }
}

.properties(...propertyNames)

Define a simple chainable property that sets and gets a raw value:

class Person extends Component {
  initialize() {
    this.properties("name");
  }
}

const person = new Person();

person.name("Jana");
person.name(); // "Jana"

.multi

class Person extends Component {
  initialize() {
    this.properties("nicknames").multi;
  }
}

const person = new Person();

person.nicknames("Jana Banana", "Jananana");
person.nicknames(); // ["Jana Banana", "Jananana"]

.aggregate

class Person extends Component {
  initialize() {
    this.properties("nicknames").aggregate;
  }
}

const person = new Person();

person.nicknames("Jana Banana");
person.nicknames("Jananana");
person.nicknames(); // ["Jana Banana", "Jananana"]

.multi.aggregate

class Person extends Component {
  initialize() {
    this.properties("citiesVisited").multi.aggregate;
  }
}

const person = new Person();

person.citiesVisited("Toledo", "OH");
person.citiesVisited("Colorado Springs", "CO");
person.citiesVisited(); // [["Toledo", "OH"], ["Colorado Springs", "CO"]]

.multi.aggregate.flat

class Person extends Component {
  initialize() {
    this.properties("values").multi.aggregate.flat;
  }
}

const person = new Person();

person.values("one", "two");
person.values("three", "four");
person.values(); // [ "one", "two", "three", "four" ]

.merged

class Person extends Component {
  initialize() {
    this.properties("favoriteCities").merged;
  }
}

const person = new Person();

person.mergedValues({"CO": "Colorado Springs", "KS": "Wichita"});
person.mergedValues({"CO": "Boulder"});
person.mergedValues(); // {"CO": "Boulder", "KS": "Wichita"}

.filter(filterFunction)

class Person extends Component {
  initialize() {
    this.properties("favoriteNumber").filter(this.castIntegers);
  }

  castIntegers(value) {
    const newValue = parseInt(value);
    if (newValue) {
      return newValue;
    } else {
      return value;
    }
  }
}

const person = new Person();

person.favoriteNumber("1");
person.favoriteNumber(); // 1

.then(callback)

Call a synchronous callback each time a new value is set on the property

class Person extends Component {
  initialize() {
    this.properties("favoriteNumber").then(this.doSomething);
  }

  doSomething(value) {
    // No returns. Just a simple synchronous callback.
  }
}

const person = new Person();

person.favoriteNumber("1");
person.favoriteNumber(); // 1

.link(linkName, linkConstructor)

A link creates a method which returns a new instance of the provided linkConstructor.

The new instance is given a copy of all methods from the parent link. This is what enables MrT to chain multiple tiers.

import Component from "mrt";

class Car extends Component {
  initialize() {
    this.link("wheel", Wheel);
  }
}

class Wheel extends Component {
  initialize(diameter) {
    this.properties("diameter");
    this.diameter(diameter);
  }
}

const car = new Car();

const wheel1 = car.wheel(10);

car
.wheel(10)
.wheel(10)
.wheel(10);

.getter

import Component from "mrt";

class Car extends Component {
  initialize() {
    this.link("wheel", Wheel).getter;
  }
}

class Wheel extends Component {}

const car = new Car();

const wheel1 = car.wheel;

car
.wheel
.wheel
.wheel;

.inherit(...propertyNames)

import Component from "mrt";

class Car extends Component {
  initialize() {
    this.properties("color");
    this.link("door", Door).inherit("color");
  }
}

class Door extends Component {}

const car = new Car();

car.color("Red");

const door = car.door;

door.color(); // "Red"

.into(collectionName)

import Component from "mrt";

class Car extends Component {
  initialize() {
    this.properties("color");
    this.link("door", Door).into("doors");
  }
}

class Door extends Component {}

const car = new Car();

car
.door
.door;

car.doors.length; // 2

.into(collectionName).key(keyName)

import Component from "mrt";

class Car extends Component {
  initialize() {
    this.properties("color");
    this.link("door", Door).into("doors").key("side");
  }
}

class Door extends Component {
  initialize(side) {
    this.properties("side");
    this.side(side);
  }
}

const car = new Car();

car
.door("left")
.door("right");

car.doors.left; // left door object
car.doors.right; // right door object

.then(thenFunction)

import Component from "mrt";

class Car extends Component {
  initialize() {
    this.properties("color");
    this.link("door", Door).then(newDoor => {
      // Called each time a link is created
    });
  }
}

class Door extends Component {}

const car = new Car();

car
.door()
.door();

.apply(...passedArguments)

import Component from "mrt";

class Car extends Component {
  initialize() {
    this.properties("color");
    this.link("door", Door).apply(this);
  }
}

class Door extends Component {
  initialize(car, color) {
    car; // Automatically passed by .arguments(this) in Car
		color; // "green"
  }
}

const car = new Car();

car.door("green");

About

Mrt makes creating simple and complex chained interfaces easy!

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •