UNPKG

wsp-toolkit

Version:
690 lines (651 loc) 15.9 kB
// src/functions/and/and.ts function and(...conditions) { for (const expr of conditions) { if (typeof expr === "function" && !expr()) return false; if (expr === false) return false; } return true; } // src/functions/concatMap/index.ts var concatMap = (f, ...xs) => { const result = []; for (let x of xs) { if (Array.isArray(x)) { for (let i of x) { result.push(f(i)); } } else { result.push(f(x)); } } return result; }; // src/functions/curry/curry.ts var curry = (fn) => { const curry2 = (...args) => { if (args.length >= fn.length) { return fn(...args); } return curry2.bind(null, ...args); }; return curry2; }; // src/functions/isNil/index.ts function isNil(x) { return x === null || x === void 0; } // src/functions/throttle/throttle.ts function throttle(fn, wait, opts = {}) { const { maxWait = wait, leading = false, trailing = true } = opts || {}; let timerId; let lastInvokeTime = null; function reset() { timerId = null; lastInvokeTime = null; } function throttled(...args) { clearTimeout(timerId); const now = Date.now(); if (isNil(lastInvokeTime)) { if (leading) { fn(...args); } lastInvokeTime = now; } if (now - lastInvokeTime >= maxWait && maxWait !== 0) { lastInvokeTime = now; fn(...args); } else { timerId = setTimeout(() => { reset(); if (!trailing) return; fn(...args); }, wait); } } return throttled; } // src/functions/debounce/debounce.ts function debounce(func, wait, opts = {}) { return throttle(func, wait, { leading: opts.leading, trailing: opts.trailing, maxWait: 0 }); } // src/functions/decimalLength/index.ts var decimalLength = (x) => { const str = typeof x === "string" ? x : x.toString(); const idx = str.indexOf("."); if (idx === -1) return 0; return str.length - idx - 1; }; // src/functions/identity/identity.ts function identity(x) { return x; } // src/functions/isExist/isExist.ts function isExist(x) { return x != null; } // src/functions/typeOf/typeOf.ts function typeOf(x) { const type = Object.prototype.toString.call(x); return type.replace(/\[\w+ (\w+)]/, "$1"); } // src/functions/isEmpty/isEmpty.ts function isEmpty(x) { if (isNil(x)) return true; if (typeof x === "string") { return x.length === 0; } if (Array.isArray(x)) { return x.length === 0; } if (typeOf(x) === "Object") { return Object.keys(x).length === 0; } if (typeOf(x) === "FormData") { const isDone = x.keys().next().done; return isExist(isDone) ? isDone : true; } return false; } // src/functions/isIterable/index.ts var isIterable = (x) => { return isExist(x) && typeof x[Symbol.iterator] === "function"; }; // src/internal/isNumber/isNumber.ts function isNumber(x) { return typeof x === "number"; } // src/functions/isSafeNum/isSafeNum.ts function isSafeNum(x) { if (x == null) return false; return isNumber(x) && isFinite(x) && Number.MIN_SAFE_INTEGER <= x && x <= Number.MAX_SAFE_INTEGER; } // src/functions/iterative/index.ts function iterative(fn) { return function(subject, ...rest) { if (isIterable(subject)) { const ret = []; for (let obj of subject) { ret.push(fn(obj, ...rest)); } return ret; } return fn(subject, ...rest); }; } // src/functions/at/at.ts var at = curry((index, xs) => { return xs[index < 0 ? xs.length + index : index]; }); // src/functions/last/index.ts function last(xs) { return at(-1, xs); } // src/functions/matrixTo/matrixTo.ts function matrixTo(matrixStr) { const arr = matrixStr.replace("matrix(", "").replace(")", "").split(",").map((x) => Number(x)); const cos = arr[0], sin = arr[1], tan = sin / cos, rotate = Math.atan(tan) * 180 / Math.PI, scale = cos / Math.cos(Math.PI / 180 * rotate); return { x: arr[4], y: arr[5], scale, rotate }; } // src/functions/once/once.ts function once(fn) { let done = false; let result; return (a) => { if (done) return result; done = true; result = fn(a); return result; }; } // src/functions/or/or.ts function or(...conditions) { for (const expr of conditions) { if (typeof expr === "function" && expr()) return true; if (expr === true) return true; } return false; } // src/functions/pipe/pipe.ts function pipe(...fns) { return (...args) => { let res = args; for (let fn of fns) { res = [fn(...res)]; } return res[0]; }; } // src/internal/propStrToList/propStrToList.ts function propStrToList(props) { const res = []; const leftBrackets = []; const quotations = []; let text = ""; const isInt = (token) => /^\d+$/.test(token); const isQuotation = (x) => [`'`, `"`].includes(x); const last2 = (xs) => xs[xs.length - 1]; const initToken = (isBraceMatching) => { if (!isEmpty(text) || isBraceMatching === true) { if (isInt(text)) { res.push(parseInt(text)); } else { res.push(text); } } text = ""; }; for (let alpha of props) { if (isQuotation(alpha)) { if (last2(quotations) === alpha) { quotations.pop(); initToken(true); continue; } initToken(); quotations.push(alpha); continue; } if (alpha === "[" && isEmpty(quotations)) { initToken(); leftBrackets.push(alpha); continue; } if (alpha === "]" && isEmpty(quotations)) { const leftBracket = leftBrackets.pop(); if (isNil(leftBracket)) { throw new SyntaxError("Unexpected token ']'"); } initToken(); continue; } if (alpha === ".") { if (isEmpty(leftBrackets) && isEmpty(quotations)) { initToken(); continue; } } text += alpha; } initToken(); if (!isEmpty(leftBrackets)) { throw new SyntaxError("\u62EC\u53F7\u6570\u91CF\u4E0D\u5339\u914D"); } if (!isEmpty(quotations)) { throw new SyntaxError("\u5F15\u53F7\u6570\u91CF\u4E0D\u5339\u914D"); } return res; } // src/functions/prop/index.ts var prop = curry( (props, subject) => { if (typeof props === "string") { props = propStrToList(props); } if (!Array.isArray(props)) { props = [props]; } return props.reduce((res, key) => { if (isNil(res)) return; return res[key]; }, subject); } ); // src/functions/sleep/sleep.ts function sleep(ms) { return new Promise((resolve) => { setTimeout(() => resolve(ms), ms); }); } // src/functions/splitIntegerDecimal/splitIntegerDecimal.ts function splitIntegerDecimal(amount) { if (isSafeNum(amount)) { amount = amount.toString(); } const res = [amount, ""]; if (typeof amount !== "string") { return res; } const match = amount.match(/\.(\d+)$/); const pointIndex = match && isExist(match.index) ? match.index : -1; const hasOnlyPoint = amount.indexOf(".") === pointIndex; if (!hasOnlyPoint || match && typeof match[1] !== "string") return res; const isDecimal = match ? isSafeNum(parseInt(match[1])) : false; if (!isDecimal) return res; res[0] = amount.substring(0, pointIndex); res[1] = amount.substring(pointIndex + 1, amount.length); return res; } // src/functions/toArray/toArray.ts function toArray(x) { if (Array.isArray(x)) return x; if (isNil(x)) return []; if (isNumber(x) || typeOf(x) === "Boolean") { return [x]; } if (isIterable(x)) { return Array.from(x); } return []; } // src/functions/toggle/toggle.ts function toggle(fns) { const endIndex = fns.length - 1; let crtIndex = 0; return function(args) { const fn = fns[crtIndex]; crtIndex += 1; if (crtIndex > endIndex) { crtIndex = 0; } return typeof fn === "function" ? fn(args) : fn; }; } // src/functions/toNumberStr/index.ts var numberMap = { "0": true, "1": true, "2": true, "3": true, "4": true, "5": true, "6": true, "7": true, "8": true, "9": true }; var legalCharMap = { "-": true, "+": true, ".": true }; function toNumberStr(x) { if (typeof x === "number") return String(x); if (typeof x === "boolean") return x ? "1" : "0"; if (Array.isArray(x)) { return toNumberStr(x.flat(Infinity).join("")); } if (typeof x !== "string") return isEmpty(x) ? "0" : "1"; let symbol = ""; let res = ""; let resType = 0 /* unknown */; let pointIndex = -1; let nonzeroEnd = 0; const initResType = (char) => { switch (char) { case "-": symbol = symbol ? "" : "-"; return; case "+": symbol = symbol ? symbol : ""; return; case ".": resType = 6 /* floatDot */; res = "0."; pointIndex = 1; return; case "0": resType = 4 /* zero */; res = char; return; } if (numberMap[char]) { resType = 1 /* int */; res += char; } }; for (let l of x) { if (!(legalCharMap[l] || numberMap[l])) continue; if (resType === 0 /* unknown */) { initResType(l); continue; } switch (resType) { // @ts-ignore "0" 这里能走进去,ts错误检查 case 4 /* zero */: if (l === "0") continue; if (l === ".") { resType = 5 /* zeroDot */; pointIndex = res.length; res += l; } else if (numberMap[l]) { resType = 1 /* int */; res = l; } continue; // "0." case 5 /* zeroDot */: if (l === "0") { resType = 3 /* floatZeroDecimal */; res += l; } else if (numberMap[l]) { resType = 2 /* float */; res += l; nonzeroEnd = res.length; } continue; // "[1-9]+\d*" case 1 /* int */: if (l === ".") { resType = 6 /* floatDot */; pointIndex = res.length; res += l; } else if (numberMap[l]) { res += l; } continue; // "\d+\." case 6 /* floatDot */: if (l === "0") { resType = 3 /* floatZeroDecimal */; res += l; } else if (numberMap[l]) { resType = 2 /* float */; res += l; nonzeroEnd = res.length; } continue; // 小数部分全部为0 case 3 /* floatZeroDecimal */: if (l === "0") { res += l; } else if (numberMap[l]) { resType = 2 /* float */; res += l; nonzeroEnd = res.length; } continue; case 2 /* float */: if (numberMap[l]) { res += l; if (l !== "0") { nonzeroEnd = res.length; } } } } if (resType === 5 /* zeroDot */) return symbol ? "0" : "-0"; if (resType === 3 /* floatZeroDecimal */ || resType === 6 /* floatDot */) return `${symbol}${res.slice(0, pointIndex)}`; if (resType === 2 /* float */) return `${symbol}${res.slice(0, nonzeroEnd)}`; return isEmpty(res) || resType === 0 /* unknown */ ? `${symbol}0` : `${symbol}${res}`; } // src/functions/treeEach/index.ts function treeEach(xs, fn, options) { const { childKey = "children", filterNull = true, filterEmpty = true, startLeaf = false } = options || {}; if (!Array.isArray(xs)) return []; const each = (list, level, parent) => { return list.reduce((result, value, index, array) => { let children = isExist(value) ? value[childKey] : null; if (startLeaf && Array.isArray(children)) { children = each(children, level + 1, value); } const newItem = fn(value, index, array, level, parent); if (!startLeaf && Array.isArray(children)) { children = each(children, level + 1, value); } if (typeof newItem === "object" && isExist(newItem)) { if (isNil(children) && filterNull) { Reflect.deleteProperty(newItem, childKey); } else if (isExist(children) && isEmpty(children) && filterEmpty) { Reflect.deleteProperty(newItem, childKey); } else { newItem[childKey] = children; } } else if (filterNull && isNil(newItem)) { return result; } result.push(newItem); return result; }, []); }; return each(xs, 0, null); } // src/functions/unique/unique.ts function unique(arr, property) { if (!property) { return [...new Set(arr)]; } const record = /* @__PURE__ */ new Map(); const result = []; for (let crt of arr) { const val = typeof property === "function" ? property(crt) : typeof crt === "object" && isExist(crt) ? prop(property, crt) : crt; if (record.get(val)) { continue; } record.set(val, true); result.push(crt); } return result; } // src/functions/zip/index.ts var zip = (...xs) => { const r = []; let nple = []; const length = Math.min.apply( null, xs.map((x) => x.length) ); for (let i = 0; i < length; i++) { xs.forEach((x) => nple.push(x[i])); r.push(nple); nple = []; } return r; }; // src/functions/zipWith/index.ts var zipWidth = (op, ...xs) => zip(...xs).map((x) => x.reduce(op)); // src/functions/ifElse/index.ts var ifElse = (condition, onTrue, onFalse) => { return (arg) => { if (condition(arg)) { return onTrue(arg); } else { return onFalse(arg); } }; }; // src/functions/toPromiseTuple/index.ts function toPromiseTuple(promise, errorExt) { return promise.then((data) => [null, data]).catch((err) => { if (errorExt) { const parsedError = Object.assign({}, err, errorExt); return [parsedError, void 0]; } return [err, void 0]; }); } // src/functions/promiseTry/index.ts async function promiseTry(func, ...args) { return new Promise((resolve) => { resolve(func(...args)); }); } // src/functions/when/index.ts var when = curry( (pred, whenTrueFn, x) => { return pred(x) ? whenTrueFn(x) : x; } ); // src/functions/clamp/clamp.ts function clamp(min, max, val) { return Math.max(min, Math.min(max, val)); } // src/functions/emptyFn/index.ts function emptyFn() { } // src/struct/Vector/Vector.ts function pointSub(a, b) { return { x: a.x - b.x, y: a.y - b.y }; } function getLength(v) { const x = Math.abs(v.x); const y = Math.abs(v.y); return Math.sqrt(x * x + y * y); } function getDirection(v1, v2) { const res = v1.x * v2.y - v2.x * v1.y; if (res === 0) return 0; return res > 0 ? 1 : -1; } function getAngle(v1, v2) { const direction = getDirection(v1, v2); const len1 = v1.getLength(); const len2 = v2.getLength(); const mr = len1 * len2; if (mr === 0) return 0; const dot = v1.x * v2.x + v1.y * v2.y; let r = dot / mr; if (r > 1) r = 1; if (r < -1) r = -1; const res = Math.acos(r) * direction * 180 / Math.PI; return res === 0 ? 0 : res; } function getScale(v1, v2) { return v2.getLength() / v1.getLength(); } var Vector = class _Vector { constructor(a, b) { a = a || { x: 0, y: 0 }; b = b || { x: 0, y: 0 }; const { x, y } = pointSub(a, b); this.x = x; this.y = y; } static of(a, b) { return new _Vector(a, b); } // 获取向量模 getLength() { return getLength(this); } // 获取旋转角度 getAngle(vector) { return getAngle(this, vector); } // 获取旋转方向 getDirection(vector) { return getDirection(this, vector); } // 获取缩放比例 getScale(vector) { return getScale(this, vector); } }; export { Vector, and, at, clamp, concatMap, curry, debounce, decimalLength, emptyFn, identity, ifElse, isEmpty, isExist, isIterable, isNil, isSafeNum, iterative, last, matrixTo, once, or, pipe, promiseTry, prop, sleep, splitIntegerDecimal, throttle, toArray, toNumberStr, toPromiseTuple, toggle, treeEach, typeOf, unique, when, zip, zipWidth };