context
The TypeScript ecosystem for an object. It allows to add processing plugins to it.
Install
Node:
npm install @iyuo/context
<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