refinable.js api    home    ex    api    docs    thy    arch    repo

This article is partially unfinished. You are welcome to create pull requests to help completing this article.

API Documentation

This page introduces APIs of refinable function. The documentation is divided into multiple parts to follows features of refinable functions from construction of refinable functions to extension, mutation, exportation, inheritance, and invocation. Note that the Self sign used in method call defines subfunctions or sub refinable functions.

Note: Currently some of APIs are not fully implemented and possibly unstable for test and use. This banner will be removed when a stable release is made.

Contents

Refinable Class

The constructor function takes no argument.

Returns a new behavior instance that will be the subject of further manipulation.

var Refinable = require('refinable');

var DBQuery = new Refinable();

Refinable Object

This section introduces standard refinement API of refinable functions object for an extension, mutation, Exportation, inheritance, and invocation of refinable functions.

Function Extension

Function extension part demonstrates function extension by implementing RESTful API for a business object called ArticleBO. The final flow of this object is following.

All method of function extension has eventually equivalent functionality which is extension however they used differently by the meaning of the order of refinement. For example, the add method used by extending function from scratch and before and after method utilizes relative extension from arbitrary points of the function. prepend is useful to add top-level operation like validation.

inputFormatting - authCheck - cacheCheck - readQuery - httpResp

Refinable.add(…args)

Adds new sub-behavior.

The argument can be either

Returns a new behavior instance that will be the subject of further manipulation.

//the add method serially adds sub functions to implement API
//RESULT: cacheCheck - readQuery
ArticleBO.write = new Refinable().add(cacheCheck).add(readQuery);

Refinable.prepend(…args)

Prepend new refinable functions

//the prepend method put given sub functions from beginning part of refinable functions
//RESULT: inputFormatting - cacheCheck - readQuery
ArticleBO.write.prepend(inputFormatting);

Refinable.Self.before(…args)

Add new behavior before specified subfunctions

//before method is works like before advice
//RESULT: inputFormatting - authCheck - cacheCheck - readQuery
ArticleBO.write.cacheCheck.before(authCheck);

Refinable.Self.after(…args)

Add new behavior after specified behavior

@param {Function|Object} New function or behavior object.
@param {String} name of behavior (if function name does not exist)
@return {Refinable} for chaining

//before method is works like after advice
//RESULT: inputFormatting - authCheck - cacheCheck - readQuery - httpResp
WriteDBQuery.write.readQuery.after(httpResp);

Function Inheritance

Function inheritance enables extends and mutates refinable function into different directions by making a distinguished copy of refinable functions. Inheritance is made by calling new method of refinable functions.

Refinable.new(…args)

Create inherited behavior. The inherited behavior is deep clone of parent behavior and does not reference or link any property

var ReadDBQuery = DBQuery.new();
var WriteDBQuery = DBQuery.new();

Function Mutation

Function mutation is opposite concept of function extension, it mutates subfunctions members of refinable function to modify its behavior. In object-oriented programming community, mutation means any form of changes as a contrast to immutability. In refinable functions, mutations mean the same replacement, deletion, wrapped and bound its subfunction.

In this part, we demonstrate the extension of function by an inherited instance of ArticleBO for to make ArticlePhotoBO which has following flow.

fileSizeChecker(exifFormatting) - authCheck.bind('photo-authority') - readQuery - httpResp

Refinable.Self.update(…args)

Update specified behavior with given behavior

@param {Function|Object} New function or behavior object.
@return {Refinable} for chaining

//update method replaces specifies sub functions
ArticlePhotoBO.write = ArticleBO.write.new().inputFormatting.update(exifFormatting)

Refinable.Self.map(…args)

Wrap specified behavior with given function-returning function

ArticlePhotoBO.write.exifFormatting.map(() => { return (exifFormatting) => { fileSizeChecker(exifFormatting) } })

Refinable.Self.around(…args)

Alias of Refinable.Self.map(…args).

Refinable.Self.delete()

Delete specified behavior, this function takes no argument

Below example deletes auth sub-behavior from ReadDBQuery

//the delete method removes specifified sub function in this case cacheChekcer for images upload API
ArticlePhotoBO.write.cacheChecker.delete();

Refinable.Self.bind(…args)

Delete specified behavior, this function takes no argument

Below example deletes auth sub-behavior from ReadDBQuery

//bound authority for photo for auth checking of using API
ArticlePhotoBO.write.authCheck.bind('photo-authority');

Refinable.assign(…args)

Apply traits to behavior Traits means set of object-independent, composable behavior Traits override existing sub-behavior with given sub-behavior by name

The below examples shows publicApiTraits embodies traits of behavior that, remove all auth module, which of course affects all sub-behavior originated from WriteDBQuery.

var publicApiTraits = { auth: null };

ArticlePhotoBO.write.assign(publicApiTraits);

Refinable.defineMethod(…args)

Define new method for performing refinement of sub-behavior contained array directly

//similar to Refinable.assign, in this example create custom method
//for deleting all authentication-related module
//classified as 'auth' for first three characters f sub function name
Formula.defineMethod('deleteAuth', function () {
  var self = this;
  this.behaviorStore.behaviors.forEach(function (behavior) {
    if (behavior.name.slice(0, 3) === 'auth') {
      self.delete.apply({name: behavior.name, behaviorStore: self.behaviorStore});
      // or by using private API
      //self.behaviorStore.deleteBehavior(behavior.name);
    }
  });
});

Function Exportation

Function exportation is used as delegating final refinement of function to the user; this is especially useful for providing reusing refinable functions for commonalities containers like cross-cutting concerns and allows the user to freely refine rest of behavior.

Exporting functions is directly related to information hiding principle of object-oriented programming by allowing refinable function-based object and modules as a distributable package. T

Refinable.asEntry()

Export refinable functions as around advice

//defines read API archetypes by deleting query
//by calling exportation method, refinable functions internally calls new()
var WriteAPI = ArticleBO.new().readQuery.delete().cacheCheck.asEntry();
//module.exports = WriteAPI

//in library consumer side
WriteAPI.compose(writeQuery)

Refinable.Self.asAround()

Alias of Refinable.Self.asEntry.

Refinable.Self.asBefore()

Export refinable functions as before advice

//equovalently functioning code for asEntry
var WriteAPI = ArticleBO.new().readQuery.delete().httpResp.asBefore();
WriteAPI.compose(writeQuery)

Refinable.Self.asAfter()

Export refinable functions as after advice

var WriteAPI = ArticleBO.new().readQuery.delete().cacheCheck.asAfter();
WriteAPI.compose(writeQuery)

Function Invocation

Refinable.exec(…args)

Execute refinable function by serially invokes internal subfunctions.

var ReadDBQuery.exec({userID: 14});

Refinable.catch(…args)

Catch errors while invoking promise

var ReadDBQuery.exec({userID: 14}).catch(() => { return http.res(500) });


Made by hiunEdit this page on GitHub