@beenotung/tslib
Version:
utils library in Typescript
313 lines (312 loc) • 7.58 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.deepGetProp = deepGetProp;
exports.hasProp = hasProp;
exports.checkedGetProp = checkedGetProp;
exports.getPropWithDefault = getPropWithDefault;
exports.first_non_null = first_non_null;
exports.ifNull = ifNull;
exports.ifNullF = ifNullF;
exports.ifNullFAsync = ifNullFAsync;
exports.bindFunction = bindFunction;
exports.caseLookup = caseLookup;
exports.caseFunctionLookup = caseFunctionLookup;
exports.deepCall = deepCall;
exports.objForEach = objForEach;
exports.objMap = objMap;
exports.objFilter = objFilter;
exports.objToArray = objToArray;
exports.objValues = objValues;
exports.argsToArray = argsToArray;
exports.concatArgs = concatArgs;
exports.copyArray = copyArray;
exports.copyToArray = copyToArray;
exports.genFunction = genFunction;
exports.isDefined = isDefined;
exports.notDefined = notDefined;
exports.isNumber = isNumber;
exports.toNumber = toNumber;
exports.forI = forI;
exports.mapI = mapI;
exports.repeatI = repeatI;
exports.tryApply = tryApply;
exports.tryCall = tryCall;
exports.tryWithDefault = tryWithDefault;
exports.chainObject = chainObject;
exports._if = _if;
exports.applyIf = applyIf;
exports.cast = cast;
exports.equals = equals;
exports.not_equals = not_equals;
exports.another = another;
/**
* Created by beenotung on 12/26/16.
*/
const defer_1 = require("./async/defer");
function deepGetProp(name, o) {
if (o[name]) {
return o[name];
}
const xs = name.split('.');
if (xs.length === 1) {
const message = `key '${name}' not found in object`;
console.warn(message, { name, o });
throw new TypeError(message);
}
const topLevelName = xs.shift();
const nextLevelName = xs.join('.');
return deepGetProp(nextLevelName, o[topLevelName]);
}
function hasProp(k, o) {
if (typeof o[k] !== 'undefined') {
return true;
}
if (Array.isArray(o)) {
return o.indexOf(k) !== -1;
}
return Object.keys(o).filter(x => x === k).length !== 0;
}
function checkedGetProp(k, o) {
if (hasProp(k, o)) {
return o[k];
}
else {
throw new TypeError(`property '${k}' does not exist in the object.`);
}
}
function getPropWithDefault(v, k, o) {
if (hasProp(k, o)) {
return o[k];
}
else {
return v;
}
}
function first_non_null(...args) {
for (const arg of args) {
if (arg) {
return arg;
}
}
return null;
}
/* return b if a is null or undefined (or false) */
function ifNull(a, b) {
return a ? a : b;
}
function ifNullF(a, f) {
return a ? a : f();
}
/**
* @remark won't flatten a
* */
async function ifNullFAsync(a, f) {
/* not using Promise.resolve(a) directly to avoid flattening a when a is a promise */
const defer = (0, defer_1.createDefer)();
if (a) {
defer.resolve(a);
}
else {
f().then(x => defer.resolve(x));
}
return defer.promise;
}
function bindFunction(f) {
const res = f.bind(f);
res.prototype = f.prototype;
return res;
}
function caseLookup(cases, target) {
const xss = cases.filter(xs => xs[0] === target);
if (xss.length === 1) {
return xss[0][1];
}
else {
throw new Error('expect only 1 match, number of match:' + xss.length);
}
}
function caseFunctionLookup(cases, target) {
return caseLookup(cases, target)();
}
function deepCall(f) {
while (typeof f === 'function') {
f = f();
}
return f;
}
function objForEach(f) {
return o => Object.keys(o).forEach(x => f(o[x], x, o));
}
function objMap(f) {
return o => Object.keys(o).map(x => f(o[x], x, o));
}
function objFilter(f) {
return o => Object.keys(o)
.filter(x => f(o[x], x, o))
.map(x => o[x]);
}
function objToArray(o) {
const xs = Object.keys(o);
const res = new Array(xs.length);
xs.forEach((x, i) => (res[i] = [o[x], x]));
return res;
}
function objValues(o) {
return Object.keys(o).map(x => o[x]);
}
function argsToArray(args) {
const len = args.length;
const res = new Array(len);
for (let i = 0; i < len; i++) {
res[i] = args[i];
}
return res;
}
/**
* take all from as ++ take some from args
* */
function concatArgs(as, args, offsetArgs = 0, nArgs = args.length) {
const na = as.length;
const res = new Array(na + nArgs);
let offset = 0;
for (; offset < na; offset++) {
res[offset] = as[offset];
}
for (let i = 0; i < nArgs; i++) {
res[offset + offsetArgs + i] = args[i];
}
return res;
}
function copyArray(xs, offset = 0, count = xs.length) {
const res = new Array(count);
for (let i = 0; i < count; i++) {
res[i] = xs[offset + i];
}
return res;
}
function copyToArray(dest, destOffset = 0, src, srcOffset = 0, count = src.length) {
for (let i = 0; i < count; i++) {
dest[destOffset + i] = src[srcOffset + i];
}
return dest;
}
const nFuncs = [];
function genFunction(n, f) {
if (n < 1) {
return function func0() {
return f.apply(null, arguments);
};
}
let genFunc = nFuncs[n];
if (!genFunc) {
genFunc = function (f) {
const func = function () {
return f.apply(null, arguments);
};
Object.defineProperty(func, 'name', { value: 'func' + n });
Object.defineProperty(func, 'length', { value: n });
let args = 'a0';
for (let i = 1; i < n; i++) {
args += ', a' + i;
}
const code = `function func${n}(${args}) {
return f.apply(null, arguments);
}`;
func.toString = () => code;
return func;
};
nFuncs[n] = genFunc;
}
return genFunc(f);
}
function isDefined(a) {
return a !== null && a !== void 0;
}
function notDefined(a) {
return !isDefined(a);
}
function isNumber(i) {
return Number.isFinite(+i) && i !== '';
}
function toNumber(i) {
if (!isNumber(i)) {
const str = JSON.stringify(i);
throw new TypeError(`expect number string, but got \`${str}\` of type ${typeof i}`);
}
return +i;
}
/**
* @param f: consumer function
* @param end: ending (exclusive)
* @param start: offset (inclusive)
* */
function forI(f, end, start = 0) {
for (let i = start; i < end; i++) {
f(i);
}
}
function mapI(f, size) {
const res = new Array(size);
forI(i => (res[i] = f(i)), size, 0);
return res;
}
function repeatI(f, size) {
return mapI(f, size);
}
/** apply the function without throwing exception */
function tryApply(f, args) {
try {
return f(...args);
}
catch (e) {
console.error(e);
}
}
/** call the function without throwing exception */
function tryCall(f, ...args) {
try {
return f(...args);
}
catch (e) {
console.error(e);
}
}
function tryWithDefault(f, defaultValue, args = []) {
try {
return f(...args);
}
catch (e) {
return defaultValue;
}
}
function chainObject(a) {
const res = (f) => {
f(a);
return res;
};
return res;
}
function _if(f) {
return b => {
if (b) {
f();
}
};
}
function applyIf(a, f) {
if (a) {
return f(a);
}
}
function cast(o) {
return o;
}
function equals(a, b) {
return a === b;
}
function not_equals(a, b) {
return a !== b;
}
function another(a, b, compare) {
return compare === a ? b : compare === b ? a : compare;
}