an-basic
Version:
a basic extensible struct which provide atomic operation
147 lines (123 loc) • 5.56 kB
JavaScript
'use strict';
const isInArray = (array, item) => {
for (let elem of array) if(item === elem) return true;
return false;
};
const getArrayIndex = (array, item) => {
for (let index = array.length - 1; index >= 0; index --) if(array[index] === item) return index;
return false;
};
const getNextFnId = (array, fnId) => array[getArrayIndex(array, fnId) + 1];
class ian {
constructor () {
this.fns = {
fnHeap: {},
fnHeapNameStack: [],
fnHeapNamePointer:{
beginFnHeapName: undefined,
thisFnHeapName:undefined
}
};
this.args = {
argPool:{},
argPoolNamePointer:{
thisArgPoolName: undefined
}
};
}
_setFnHeapNamePointer (type, fnHeapName) {
if(!this.fns.fnHeap.hasOwnProperty(fnHeapName)) throw new Error(`${fnHeapName} is not in fnHeap: ${this.fns.fnHeap}`);
this.fns.fnHeapNamePointer[type+'FnHeapName'] = fnHeapName;
return this;
}
_getFnHeapNamePointer (type) {
const fnHeapType = type + 'FnHeapName';
if(this.fns.fnHeapNamePointer[fnHeapType] === undefined) throw new Error(`${fnHeapType} is not defined!`);
return this.fns.fnHeapNamePointer[fnHeapType];
}
_setToFnHeap (fnHeapName, ...fnHeapValue) {
for (let fn of fnHeapValue) if(typeof fn !== 'function') throw new TypeError('The value of fnHeapValue which as a parameter in _setToFnHeap() must be a function!');
this.fns.fnHeap[fnHeapName] = fnHeapValue;
this._setFnHeapNamePointer('this', fnHeapName);
return this;
}
_pendToFnHeap (fnHeapName, mode, ...fnHeapValue) {
if(!this.fns.fnHeap.hasOwnProperty(fnHeapName)) throw new Error(`${fnHeapName} is not in fnHeap: ${this.fns.fnHeap}`);
for (let fn of fnHeapValue) if(typeof fn !== 'function') throw new TypeError('The value of fnHeapValue which as a parameter in _pendToFnHeap() must be a function!');
fnHeapName = fnHeapName === undefined?this._getFnHeapNamePointer('this'):fnHeapName;
this.fns.fnHeap = mode === 'pre'?fnHeapValue.concat(this.fns.fnHeap[fnHeapName]):this.fns.fnHeap[fnHeapName].concat(fnHeapName);
return this;
}
_go (fnArray) {
if(!Array.isArray(fnArray)) throw new TypeError(`${fnArray} is not an Array as a parameter in _go()!`);
if(fnArray.length === 0) throw new Error('There are no data in fnArray which as a parameter in _go()!');
const result = Promise.resolve();
for (let fn of fnArray) result.then((reply) => fn(...reply));
return result;
}
_setArgPoolNamePointer (type, argPoolName) {
if(!this.args.argPool.hasOwnProperty(argPoolName)) throw new Error(`${argPoolName} is not in argPool: ${this.args.argPool}`);
this.args.argPoolNamePointer[type+'ArgPoolName'] = argPoolName;
return this;
}
_addArgPoolNamePointer (type, argPoolName) {
if(argPoolName !== undefined && !this.args.argPool.hasOwnProperty(argPoolName)) throw new Error(`${argPoolName} is not in argPool: ${this.args.argPool}`);
this.args.argPoolNamePointer[type+'ArgPoolName'] = argPoolName;
return this;
}
_getArgPoolNamePointer (type) {
const argPoolType = type + 'ArgPoolName';
if(this.args.argPoolNamePointer[argPoolType] === undefined) throw new Error(`${argPoolType} is not defined!`);
return this.args.argPoolNamePointer[argPoolType];
}
_setToArgPool (argPoolName, ...argPoolValue) {
this.args.argPool[argPoolName] = argPoolValue;
this._setArgPoolNamePointer('this', argPoolName);
return this;
}
_appendToArgPool (argPoolName, ...argPoolValue) {
if(!this.args.argPool.hasOwnProperty(argPoolName)) throw new Error(`${argPoolName} is not in argPool: ${this.args.argPool}`);
argPoolName = argPoolName === undefined?this._getArgPoolNamePointer('this'):argPoolName;
this.args.argPool.concat(argPoolValue);
return this;
}
mount (fn) {
const fnHeapName = this.fns.fnHeapNameStack.length;
this._setToFnHeap(fnHeapName, fn);
this.fns.fnHeapNameStack.push(fnHeapName);
return this;
}
getThisFnName () {
try {
return this._getFnHeapNamePointer('this');
}catch (e) {
if(!this.fns.fnHeapNameStack.length) throw new Error('There are no function in fnHeapNameStack!');
return this.fns.fnHeapNameStack[0];
}
}
setThisFnName (fnHeapName) {
return this._setFnHeapNamePointer('this', fnHeapName);
}
getBeginFnName () {
try {
return this._getFnHeapNamePointer('begin');
}catch (e) {
if(!this.fns.fnHeapNameStack.length) throw new Error('There are no function in fnHeapNameStack!');
return this.fns.fnHeapNameStack[0];
}
}
setFnName (fnHeapName) {
const thisFnHeapName = this.getThisFnName();
const fnHeap = this.fns.fnHeap;
Object.assign(fnHeap, {[fnHeapName]: fnHeap[thisFnHeapName]});
this.fns.fnHeapNameStack[getArrayIndex(this.fns.fnHeapNameStack, thisFnHeapName)] = fnHeapName;
delete fnHeap[thisFnHeapName];
this.setThisFnName(fnHeapName);
return this;
}
run (beginFnHeapName) {
beginFnHeapName = beginFnHeapName || this.getBeginFnName();
return this._go(this.fns.fnHeap[beginFnHeapName]);
}
}
module.exports = ian;