UNPKG

@ryanuo/utils

Version:

提供多种实用工具函数,涵盖算法、浏览器操作、网络请求等多个领域

2 lines (1 loc) 12.7 kB
"use strict";const S=require("dayjs"),n=require("query-string"),decimal_js=require("decimal.js");function _interopDefaultCompat(e){return e&&typeof e=="object"&&"default"in e?e.default:e}const S__default=_interopDefaultCompat(S),n__default=_interopDefaultCompat(n),toString=e=>Object.prototype.toString.call(e);function getTypeName(e){return toString(e).slice(8,-1).toLowerCase()}function numberToFixed(e,t=4){return e===0||Number.isNaN(e)?0:Number(e.toFixed(t))}function deepClone(e){if(e===null||typeof e!="object")return e;if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return new RegExp(e.source,e.flags);if(Array.isArray(e))return e.map(r=>deepClone(r));const t={};for(const r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=deepClone(e[r]));return t}function isBoolean(e){return typeof e=="boolean"}function isNumber(e){return typeof e=="number"&&!Number.isNaN(e)}const isFunction=e=>typeof e=="function",isString=e=>typeof e=="string",isObject=e=>toString(e)==="[object Object]",isEmptyObject=e=>isObject(e)&&Object.keys(e).length===0,isUndefined=e=>toString(e)==="[object Undefined]",isNull=e=>toString(e)==="[object Null]",isRegExp=e=>toString(e)==="[object RegExp]",isDate=e=>toString(e)==="[object Date]";function isBrowser(){return typeof window<"u"&&typeof document<"u"}function getUuid(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function curry(e){return function t(...r){return r.length>=e.length?e(...r):function(...o){const s=[...r,...o];return t(...s)}}}function safeJSONParse(e){try{return JSON.parse(e)}catch{return null}}function debounce(e,t,r=!1){let o=null;return(...s)=>{o!==null&&window.clearTimeout(o),r&&o===null&&e(...s),o=window.setTimeout(()=>{r||e(...s),o=null},t)}}function throttle(e,t,r=!0){let o=0,s=null;return(...p)=>{const x=Date.now(),y=x-o,v=()=>{e(...p),o=x};r&&y>=t?v():s===null&&(s=window.setTimeout(()=>{(!r||y<t)&&v(),s=null},r?t-y:t))}}function dateFormat(e,t="YYYY-MM-dd"){if(!isDate(e))throw new TypeError("Parameter must be a valid Date.");const r=e.getFullYear().toString(),o={Y:4,y:2,M:2,d:2,H:2,h:2,m:2,s:2,S:3,q:1},s={"Y+":()=>r,"y+":x=>r.slice(-x.length),"M+":(e.getMonth()+1).toString(),"d+":e.getDate().toString(),"H+":e.getHours().toString(),"h+":()=>(e.getHours()%12||12).toString(),"m+":e.getMinutes().toString(),"s+":e.getSeconds().toString(),"q+":Math.floor((e.getMonth()+3)/3).toString(),"S+":e.getMilliseconds().toString()};let p;for(const x in s)p=t.match(new RegExp(x,"g")),p?.forEach(y=>{const v=x.charAt(0),N=o[v]||y.length,D=s[x],E=isFunction(s[x])?D(y):D;t=t.replace(y,E.toString().padStart(Math.max(y.length,N),"0"))});return t}const dayjs=S__default;function manageClasses(e,t,r){r.forEach(o=>e.classList[t](o))}function onceEventListener(e,t,r){const o=s=>{r(s),e.removeEventListener(t,o)};e.addEventListener(t,o)}function isMobile(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}async function copyToClipboard(e){try{return await navigator.clipboard.writeText(e),!0}catch{const t=document.createElement("textarea");if(t.value=e,document.body.appendChild(t),t.select(),!document?.execCommand)return!1;const r=document?.execCommand("copy");return document.body.removeChild(t),r}}function enterFullScreen(e,t="click"){const r=document.querySelectorAll(e);if(r.length===0){console.error(`No elements found for selector ${e}`);return}if(!document.fullscreenEnabled){console.error("Your browser does not support fullscreen mode");return}r.forEach(o=>{o.addEventListener(t,async()=>{try{document.documentElement.requestFullscreen?await document.documentElement.requestFullscreen():"webkitRequestFullscreen"in document.documentElement?document.documentElement.webkitRequestFullscreen():"msRequestFullscreen"in document.documentElement&&document.documentElement.msRequestFullscreen()}catch(s){console.error("Failed to enter fullscreen:",s)}})})}function a$2(e="local"){return e==="local"?localStorage:sessionStorage}function c(e,t){if(!t)return e;const r=new Date().getTime();return{value:e,expires:r+t}}function g$1(e){return!e||typeof e!="object"?e:"expires"in e&&"value"in e?new Date().getTime()>e.expires?null:e.value:e}const u={get(e,t={}){try{const{storage:r="local"}=t,o=a$2(r),s=o.getItem(e);if(!s)return null;const p=safeJSONParse(s),x=g$1(p);return x===null&&o.removeItem(e),x}catch{return null}},set(e,t,r={}){try{const{storage:o="local",expires:s}=r,p=a$2(o),x=c(t,s);return p.setItem(e,JSON.stringify(x)),!0}catch{return!1}},remove(e,t={}){const{storage:r="local"}=t;a$2(r).removeItem(e)},clear(e={}){const{storage:t="local"}=e;a$2(t).clear()}};function getUrlParams(e=window.location.search){return e?n__default.parseUrl(e).query:{}}function getUrlParamsString(e,t){return`${t||window.location.href}${isEmptyObject(e)?"":"?"}${n__default.stringify(e)}`}async function downloadFile(e,t,r={}){try{const o=await fetch(e,r);if(!o.ok)throw new Error(`\u4E0B\u8F7D\u5931\u8D25: HTTP\u72B6\u6001\u7801 ${o.status} ${o.statusText}`);if(!t){const y=o.headers.get("content-disposition");if(y){const v=y.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);v&&v[1]&&(t=v[1].replace(/['"]/g,""))}t||(t=e.split("/").pop()||"downloaded-file")}const s=await o.blob(),p=URL.createObjectURL(s),x=document.createElement("a");x.href=p,x.download=t,document.body.appendChild(x),x.click(),setTimeout(()=>{document.body.removeChild(x),URL.revokeObjectURL(p)},100)}catch(o){throw console.error("\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25:",o),o instanceof Error?new Error(`\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25: ${o.message}`):new Error("\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25: \u53D1\u751F\u672A\u77E5\u9519\u8BEF")}}function bubbleSort(e){const t=e.length;for(let r=0;r<t-1;r++)for(let o=0;o<t-1-r;o++)e[o]>e[o+1]&&([e[o],e[o+1]]=[e[o+1],e[o]]);return e}function quickSort(e){if(e.length<=1)return e;const t=e[0],r=e.filter(s=>s<t),o=e.filter(s=>s>t);return[...quickSort(r),t,...quickSort(o)]}function binarySearch(e,t){let r=0,o=e.length-1;for(;r<=o;){const s=Math.floor((r+o)/2);if(e[s]===t)return s;e[s]<t?r=s+1:o=s-1}return-1}function isPrime(e){if(e<=1)return!1;for(let t=2;t<=Math.sqrt(e);t++)if(e%t===0)return!1;return!0}function fibonacciDP(e){const t=[0,1];for(let r=2;r<=e;r++)t[r]=t[r-1]+t[r-2];return t[e]}function fibonacciRecursive(e){return e<0?0:e<=1?e:fibonacciRecursive(e-1)+fibonacciRecursive(e-2)}const decimal=decimal_js.Decimal;decimal.set({precision:20,rounding:decimal_js.Decimal.ROUND_HALF_UP});function preciseAdd(...e){return e.reduce((t,r)=>t.plus(new decimal_js.Decimal(r)),new decimal_js.Decimal(0))}function preciseSub(e,t,...r){let o=new decimal_js.Decimal(e).minus(new decimal_js.Decimal(t));for(const s of r)o=o.minus(new decimal_js.Decimal(s));return o}function preciseMul(...e){return e.length===0?new decimal_js.Decimal(0):e.reduce((t,r)=>t.times(new decimal_js.Decimal(r)),new decimal_js.Decimal(1))}function preciseDiv(e,t,...r){let o=new decimal_js.Decimal(e).dividedBy(new decimal_js.Decimal(t));for(const s of r)o=o.dividedBy(new decimal_js.Decimal(s));return o}function roundTo(e,t=2){if(t<0)throw new Error("Decimal places must be a non-negative integer");return new decimal_js.Decimal(e).toDecimalPlaces(t)}function compare(e,t){return new decimal_js.Decimal(e).comparedTo(new decimal_js.Decimal(t))}function calculatePercentage(e,t,r){if(Number(t)===0)return"NaN";const{decimalPlaces:o=2,isSymbol:s=!1}=r||{};return s?`${preciseDiv(e,t).times(100).toFixed(o)}%`:preciseDiv(e,t).times(100).toFixed(o)}class CalculatorChain{value;constructor(t){this.value=new decimal_js.Decimal(t)}add(t){return this.value=this.value.plus(new decimal_js.Decimal(t)),this}sub(t){return this.value=this.value.minus(new decimal_js.Decimal(t)),this}mul(t){return this.value=this.value.times(new decimal_js.Decimal(t)),this}div(t){if(Number(t)===0)throw new Error("Cannot divide by zero");return this.value=this.value.dividedBy(new decimal_js.Decimal(t)),this}round(t=2){return this.value.toDecimalPlaces(t)}}function formatCurrency(e,t="CNY",r="zh-CN"){if(Number.isNaN(e))throw new Error("Invalid amount");return new Intl.NumberFormat(r,{style:"currency",currency:t}).format(e)}function a$1(e){if(!/^#(?:[0-9a-f]{6}|[0-9a-f]{8})$/i.test(e))throw new Error("Invalid hex color");const t=Number.parseInt(e.slice(1,3),16),r=Number.parseInt(e.slice(3,5),16),o=Number.parseInt(e.slice(5,7),16),s=e.length>7?Number.parseInt(e.slice(7,9),16)/255:1;return{r:t,g:r,b:o,a:s}}function i({r:e,g:t,b:r,a:o=1}){if(e<0||e>255)throw new Error("Invalid red value");if(t<0||t>255)throw new Error("Invalid green value");if(r<0||r>255)throw new Error("Invalid blue value");if(o<0||o>1)throw new Error("Invalid alpha value");const s=p=>Math.round(p).toString(16).padStart(2,"0");return`#${s(e)}${s(t)}${s(r)}${o<1?s(o*255):""}`}function b(e,t,r){if(!/^#(?:[0-9a-f]{6}|[0-9a-f]{8})$/i.test(e))throw new Error("Invalid hex color");if(r<0||r>1)throw new Error("Invalid t value");const o=a$1(e),s=a$1(t);return i({r:o.r+(s.r-o.r)*r,g:o.g+(s.g-o.g)*r,b:o.b+(s.b-o.b)*r,a:o.a+(s.a-o.a)*r})}async function g(e,t={},r=5e3){const o=new AbortController,s=setTimeout(()=>o.abort(),r);try{const p=await fetch(e,{...t,signal:o.signal});return clearTimeout(s),p}catch(p){throw clearTimeout(s),new Error(`\u8BF7\u6C42\u8D85\u65F6\u6216\u5931\u8D25: ${p.message}`)}}async function m(e,t,r,o={}){const s={method:e,headers:{"Content-Type":"application/json",...o}};r&&(s.body=JSON.stringify(r));const p=await g(t,s);if(!p.ok)throw new Error(`HTTP\u9519\u8BEF ${p.status}`);return p.json()}async function w(e,t=5){const r=[],o=new Set;for(const s of e){const p=s().then(x=>{r.push(x),o.delete(p)});o.add(p),o.size>=t&&await Promise.race(o)}return await Promise.all(o),r}async function d(){try{return(await m("GET","https://api.ipify.org?format=json")).ip}catch{return"unknown"}}async function f(e,t){const r=await new Promise((o,s)=>{const p=indexedDB.open(e,1);p.onupgradeneeded=()=>{p.result.createObjectStore(t)},p.onsuccess=()=>o(p.result),p.onerror=s});return{async get(o){return new Promise(s=>{const p=r.transaction(t,"readonly").objectStore(t).get(o);p.onsuccess=()=>s(p.result),p.onerror=()=>s(void 0)})},async set(o,s){return new Promise((p,x)=>{const y=r.transaction(t,"readwrite").objectStore(t).put(s,o);y.onsuccess=()=>p(),y.onerror=x})}}}function l$1(){return new Promise(e=>{if(navigator.onLine!==void 0)e(navigator.onLine);else{const t=new Image;t.onload=()=>e(!0),t.onerror=()=>e(!1),t.src=`https://www.google.com/favicon.ico?${Date.now()}`}})}function a(e,t,r){if(r===0)throw new Error("division by zero");return e.map(o=>(o-t)/r)}function h(e){const t=Math.min(...e),r=Math.max(...e);return t===r?e.map(()=>0):e.map(o=>(o-t)/(r-t))}function l(e){if(e.length===1)return e[0];const t=e.length,r=Array.from({length:t},(D,E)=>E),o=e,s=r.reduce((D,E)=>D+E,0)/t,p=o.reduce((D,E)=>D+E,0)/t,x=r.reduce((D,E,F)=>D+(E-s)*(o[F]-p),0),y=r.reduce((D,E)=>D+(E-s)**2,0),v=x/y,N=p-v*s;return v*t+N}exports.CalculatorChain=CalculatorChain,exports.binarySearch=binarySearch,exports.bubbleSort=bubbleSort,exports.calculatePercentage=calculatePercentage,exports.checkNetworkStatus=l$1,exports.compare=compare,exports.copyToClipboard=copyToClipboard,exports.curry=curry,exports.dateFormat=dateFormat,exports.dayjs=dayjs,exports.debounce=debounce,exports.decimal=decimal,exports.deepClone=deepClone,exports.downloadFile=downloadFile,exports.enterFullScreen=enterFullScreen,exports.fetchWithTimeout=g,exports.fibonacciDP=fibonacciDP,exports.fibonacciRecursive=fibonacciRecursive,exports.formatCurrency=formatCurrency,exports.getClientIP=d,exports.getIndexedDBCache=f,exports.getTypeName=getTypeName,exports.getUrlParams=getUrlParams,exports.getUrlParamsString=getUrlParamsString,exports.getUuid=getUuid,exports.hexToRgba=a$1,exports.isBoolean=isBoolean,exports.isBrowser=isBrowser,exports.isDate=isDate,exports.isEmptyObject=isEmptyObject,exports.isFunction=isFunction,exports.isMobile=isMobile,exports.isNull=isNull,exports.isNumber=isNumber,exports.isObject=isObject,exports.isPrime=isPrime,exports.isRegExp=isRegExp,exports.isString=isString,exports.isUndefined=isUndefined,exports.lerpColor=b,exports.linearRegression=l,exports.manageClasses=manageClasses,exports.normalizeData=a,exports.normalizeMinMax=h,exports.numberToFixed=numberToFixed,exports.onceEventListener=onceEventListener,exports.parallelRequests=w,exports.preciseAdd=preciseAdd,exports.preciseDiv=preciseDiv,exports.preciseMul=preciseMul,exports.preciseSub=preciseSub,exports.quickSort=quickSort,exports.request=m,exports.rgbaToHex=i,exports.roundTo=roundTo,exports.safeJSONParse=safeJSONParse,exports.safeStorage=u,exports.throttle=throttle,exports.toString=toString;