@iyuo/context

The TypeScript ecosystem for an object. It allows to add processing plugins to it.


Keywords
context, typescript
License
Apache-2.0
Install
npm install @iyuo/context@1.3.4

Documentation

context

NPM version License Twitter

The TypeScript ecosystem for an object. It allows to add processing plugins to it.

Install

Node:

https://nodei.co/npm/@iyuo/context.png?downloads=true&downloadRank=true&stars=true

npm install @iyuo/context

Browser

<script src="//iyuo.github.io/context/dist/context.min.js"></script>

Import package to the project

TypeScript:

import { Context, pluginize, lsh, rsh } from "@iyuo/context";

or JavaScript:

var iyuo = require("@iyuo/context");
var Context = iyuo.Context;
var pluginize = iyuo.pluginize;
var lsh = iyuo.lsh;
var rsh = iyuo.rsh;

Documentation

Link: https://iyuo.github.io/context/docs/index.html

Demo

See, how it's working: https://runkit.com/lopatnov/context-demo

Test it with a runkit: https://npm.runkit.com/@iyuo/context

Plugins

Example

function sum(this: number[]): number {
   return this.reduce((previousValue: number, currentValue: number): number => {
     return previousValue + currentValue;
   }, 0);
}

var numbers = new Context([1, 2, 3, 4, 5]);
var takeSum = numbers.make(sum);
console.log(takeSum); // 15

Use cases

class Context<TContext>

//A sample of a Context<TContext> class, this is the object Context<string>

let myContextSample = new Context("A sample context");
console.log(myContextSample);

/*
Context
  _context: "A sample context"
  _use: []
*/

context(): TContext

// Gets the context from a wrapper

var sys = new Context({ hello: 'world' });
console.log(sys.context()); // Object {hello: "world"}

var arr = new Context([1, 2, 3]);
console.log(arr.context()); // [1, 2, 3]

change(context: TContext): Context

// Change current context to a new one

var arr = new Context([1, 2, 3]);
var changed = arr.change([4,5,6]);
console.log( arr === changed ); // true
console.log( arr.context() ); // [4,5,6]

var sys = new Context({ hello: 'world' });
console.log(sys.change({hello: 'friends'}).context()); //{hello: "friends"}

use(...args: any[]): Context

// Adds arguments of plugins execution

function dialog(useQ, useA) {
   this.q(`${useQ} Hi, how are you doing?`);
   this.a(`${useA} Fine.`);
   this.q(`${useA} How's it going?`);
   this.a(`${useQ} Good`);
}

var space = new Context({
   q: (msg) => { console.log(`Q: ${msg}`) },
   a: (msg) => { console.log(`A: ${msg}`) }
});

space.use('Tom', 'Lisa').make(dialog);
/*
"Q: Tom Hi, how are you doing?"
"A: Lisa Fine."
"Q: Lisa How's it going?"
"A: Tom Good"
*/

space.use('Ann').use('Nina').make(dialog);
/*
"Q: Ann Hi, how are you doing?"
"A: Nina Fine."
"Q: Nina How's it going?"
"A: Ann Good"
*/

useArray(use: any[]): Context

// Uses "use" parameter for arguments of plugins execution instead of current Context class property _use.

function strategy(teamA, teamB) {
    return function(behavior1, behavior2, behaviorDefault) {
        switch(this(teamA,teamB)) {
            case 1:
                return behavior1();
            case -1:
                return behavior2();
            default:
                return behaviorDefault();
        }
    }
}

function strategy1() {
    console.log('This is strategy1');
    return 1;
}

function strategy2() {
    console.log('This is strategy2');
    return 2;
}

function strategy3() {
    console.log('This is strategy3');
    return 3;
}

var space = new Context(function compare(a,b){
  var diff = a - b;
  return diff === 0 ? 0 : (diff > 0 ? 1 : -1);
});

space.useArray([strategy1, strategy2, strategy3]).make(strategy(3,4)); // "This is strategy2"
space.useArray([strategy1, strategy2, strategy3]).make(strategy(100,50)) // "This is strategy1"
space.useArray([strategy1, strategy2, strategy3]).make(strategy(100,100)) // "This is strategy3"

//The same with .use()
space.use(strategy1, strategy2, strategy3).make(strategy(3,4)); // "This is strategy2"
space.use(strategy1).use(strategy2, strategy3).make(strategy(100,50)) // "This is strategy1"
space.use(strategy1).use(strategy2).use(strategy3).make(strategy(100,100)) // "This is strategy3"

//Note that useArray replaces use functions before

tasks(...plugins: IPlugin<TContext, void>[]): Context

// Execute plugins functions the tasks for a context

function or() {
 this.or = this.a | this.b;
}

function and() {
 this.and = this.a & this.b;
}

function xor() {
 this.xor = this.a ^ this.b;
}

var tasksDemo = new Context({a: true, b: false});
tasksDemo.tasks(or, and, xor);

console.log(tasksDemo.context());
/*
   Object
   a: true
   b: false
   and: 0
   or: 1
   xor: 1
*/

console.log(new Context({a: true, b: true}).tasks(and, xor).context());
/*
   Object
   a: true
   b: true
   and: 1
   xor: 0
*/

task(plugin: IPlugin<TContext, void>, ...use: any[]): Context

// Execute plugin with params

function not(comment) {
 console.log(`${comment}: ${!this.value}`);
 this.not = !this.value;
}

var taskDemo = new Context({value: false});
taskDemo.task(not, 'not this equals'); // "not this equals: true"

console.log(taskDemo.context()); // Object {not: true, value: false}

taskDemo.task(not, 'Repeat not 1'); // "Repeat not 1: true"
taskDemo.task(not, 'Repeat not 2'); // "Repeat not 2: true"

taskDemo.task(not, 'Same not task 1').task(not, 'Same not task 2');
/*
"Same not task 1: true"
"Same not task 2: true"
*/

make(plugin: IPlugin<TContext, TResult>, ...use: any[]): TResult

// Execute plugin function and return the result of plugin processing

function sum() {
   return this.reduce((previousValue, currentValue) => {
     return previousValue + currentValue;
   }, 0);
}

function avg() {
   return this.reduce((previousValue, currentValue) => {
     return previousValue + currentValue;
   }, 0) / this.length;
}

var numbers = new Context([1, 2, 3, 4, 5]);
var takeSum = numbers.make(sum);
var takeAvg = numbers.make(avg);

console.log(takeSum); // 15
console.log(takeAvg); // 3

map(plugin: IPlugin<TContext, TMappedContext>, ...use: any[]): Context

// Executes plugin and make new context, based on the plugin result

function increment() {
 return this + 1;
}

function makeArray() {
 let arr = [];
 for (var i = 0; i < this; i++) {
    arr.push(i + 1);
 }
 return arr;
}

var num = new Context(10);

var incremented = num
    .map(increment)
    .map(increment)
    .map(increment)
    .map(increment)
    .context();
console.log(incremented); // 14
    
var arrContext = num.map(increment).map(makeArray).context();
console.log(arrContext); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

var makedArr = num.map(increment).map(increment).make(makeArray);
console.log(makedArr); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

scope(plugin: IScope<TContext, TResult>, ...use: any[]): TResult

// Execute IScope processing plugin
// where 
// IScope = (this: Context<TContext>, context: TContext, use: any[]): TResult');

function switchContextUse(context, use) {
    return new Context(use).use(context);
}

function eachFunc() {
    for (var index in this) {
        var f = this[index];
        if (f instanceof Function) {
            f.apply(this, arguments);
        }
    }
}

var c = new Context([1,2,3,4,5]);
var resultOfSwitch = c
   .use(function(){ console.log('A: ', this, arguments) })
   .use(function(){ console.log('B: ', this, arguments) })
   .scope(switchContextUse)
   .task(eachFunc);
/*
"A: " [function(), function()] Arguments {0: [1, 2, 3, 4, 5]}
"B: " [function(), function()] Arguments {0: [1, 2, 3, 4, 5]}
*/

console.log(resultOfSwitch);
/*
Context {_context: [function(), function()], _use: [[1, 2, 3, 4, 5]]}
*/

console.log(c);
/*
Context {_context: [1, 2, 3, 4, 5], _use: [function(), function()]}
*/

pluginize<TContext, TResult>(plugin: IPlugin<TContext, TResult>): IPlugin<TContext, TResult>

// Converts a function to a context ecosystem plugin.

function addFunction(n) {
    var arr = [];
    for (var i = 0; i < this.length; i++) {
        arr.push(this[i] + n);
    }
    return arr;
}

var add = pluginize(addFunction);

var x = new Context([1,2,3,4,5]);

//You can use
console.log(x.map(addFunction, 10).context());

//But better looks
console.log(x.map(add(10)).context());

/*
[11, 12, 13, 14, 15]
*/

lsh<TContext, TResult>(func: (context: TContext, ...args: any[]) => TResult): IPlugin<TContext, TResult>

// Moves a first argument to a function context. This is conversion from a function to context based function.

function sub(a,b) {
  return a - b;
}

var s = lsh(sub);
console.log(s.call(10, 5)); // 5

var ss = s.bind(100);
console.log(ss(33)); // 67

rsh<TContext, TResult>(plugin: IPlugin<TContext, TResult>): (context: TContext, ...args: any[]) => TResult

// Moves a function context to a first argument. This is conversion from context based function to a function.

function stringify() {
  return '' + this;
}

var s = rsh(stringify);
console.log(s(12345)); // "12345"

Rights and Agreements

License Apache-2.0

Copyright 2019 Oleksandr Lopatnov