@ybgnb/utils 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/error/common-error.d.ts +8 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/result/biz-result.d.ts +17 -0
- package/dist/core/result/exec-biz.d.ts +6 -0
- package/dist/core/types/helpers.d.ts +54 -0
- package/dist/core/types/physical.d.ts +16 -0
- package/dist/core/utils/array.d.ts +12 -0
- package/dist/core/utils/error.d.ts +22 -0
- package/dist/core/utils/fetch.d.ts +13 -0
- package/dist/core/utils/function.d.ts +28 -0
- package/dist/core/utils/github.d.ts +31 -0
- package/dist/core/utils/number/format.d.ts +19 -0
- package/dist/core/utils/random.d.ts +28 -0
- package/dist/core/utils/serialize.d.ts +23 -0
- package/dist/core/utils/sleep.d.ts +13 -0
- package/dist/core/utils/time.d.ts +19 -0
- package/dist/core/utils/type.d.ts +9 -0
- package/dist/core/utils/url.d.ts +36 -0
- package/dist/core.d.ts +2 -0
- package/dist/core.js +299 -0
- package/dist/core.js.map +1 -0
- package/dist/core.umd.cjs +2 -0
- package/dist/core.umd.cjs.map +1 -0
- package/dist/dom/index.d.ts +6 -0
- package/dist/dom/utils/color.d.ts +32 -0
- package/dist/dom/utils/css.d.ts +4 -0
- package/dist/dom/utils/img.d.ts +14 -0
- package/dist/dom/utils/network.d.ts +25 -0
- package/dist/dom/utils/page.d.ts +10 -0
- package/dist/dom/utils/scroll.d.ts +13 -0
- package/dist/dom.d.ts +2 -0
- package/dist/dom.js +134 -0
- package/dist/dom.js.map +1 -0
- package/dist/dom.umd.cjs +2 -0
- package/dist/dom.umd.cjs.map +1 -0
- package/dist/node/index.d.ts +8 -0
- package/dist/node/utils/env.d.ts +6 -0
- package/dist/node/utils/file/base.d.ts +20 -0
- package/dist/node/utils/file/delete.d.ts +12 -0
- package/dist/node/utils/file/download.d.ts +4 -0
- package/dist/node/utils/file/find.d.ts +14 -0
- package/dist/node/utils/file/json.d.ts +20 -0
- package/dist/node/utils/file/size.d.ts +19 -0
- package/dist/node/utils/win/cmd.d.ts +21 -0
- package/dist/node/utils/win/copy.d.ts +4 -0
- package/dist/node/utils/win/explorer.d.ts +5 -0
- package/dist/node/utils/win/regedit.d.ts +17 -0
- package/dist/node.d.ts +2 -0
- package/dist/node.js +201 -0
- package/dist/node.js.map +1 -0
- package/dist/node.umd.cjs +2 -0
- package/dist/node.umd.cjs.map +1 -0
- package/package.json +23 -12
- package/dist/index.d.ts +0 -416
- package/dist/index.js +0 -336
- package/dist/index.js.map +0 -1
- package/dist/index.umd.cjs +0 -2
- package/dist/index.umd.cjs.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`node:fs/promises`);c=s(c,1);let l=require(`node:path`);l=s(l,1);let u=require(`node:child_process`),d=require(`iconv-lite`);d=s(d,1);function f(){let e={};for(let t in process.env)e[t]=process.env[t];return e}async function p(e){try{return(await c.default.stat(e)).isFile()}catch{return!1}}async function m(e,t){try{return c.default.access(e,t),!0}catch{return!1}}async function h(e){c.default.mkdir(e,{recursive:!0})}async function g(e){await c.default.mkdir(e,{recursive:!0})}function _(e){return typeof e==`object`&&!!e&&`code`in e&&e.code===`ENOENT`}async function v(e){let t=[],n=await c.default.readdir(e,{withFileTypes:!0});for(let r of n){let n=l.default.join(e,r.name);r.isDirectory()?(t.push(...await v(n)),await c.default.rmdir(n)):await c.default.unlink(n),t.push(n)}return t}async function y(e){return(await Promise.allSettled(e.map(async e=>(await c.default.unlink(e),e)))).filter(e=>e.status===`fulfilled`).map(e=>e.value)}async function b(e){if(!await p(e))throw Error(`文件不存在`);let t=await c.default.readFile(l.default.resolve(e),`utf-8`);return JSON.parse(t)}async function x(e,t){let n=`${e}.tmp.${Date.now()}`,r=JSON.stringify(t,null,2);await c.default.writeFile(n,r,`utf-8`),await c.default.rename(n,e)}async function S(e,t){let n=t(await b(e));return await x(e,n),n}async function C(e,t){try{let t=await c.default.readFile(e,`utf-8`);return JSON.parse(t)}catch(n){if(!_(n))throw n;let r=await t();return await g(l.default.dirname(e)),await c.default.writeFile(e,JSON.stringify(r,null,2),`utf-8`),r}}function w(e,t,n,r=``){if(!Number.isFinite(e))return{size:0,unit:``,text:r};let i=e,a=0;for(;i>=t&&a<n.length-1;)i/=t,a++;return{size:i,unit:n[a],text:`${i.toFixed(2).replace(/\.?0+$/,``)} ${n[a]}`}}function T(e,t=``){let{size:n,unit:r,text:i}=w(e,1024,[`KB`,`MB`,`GB`],t);if(i===t)return t;let a=Math.floor(n),o;return o=a>99?0:a>9?1:2,`${Math.round(n*10**o)/10**o} ${r}`}async function E(e){try{return(await c.default.stat(e)).size}catch{return 0}}async function D(e){try{return(await c.default.lstat(e)).size}catch{return 0}}async function O(e){let t;try{t=await c.default.readdir(e,{withFileTypes:!0})}catch{return 0}let n=[];for(let r of t){let t=l.default.join(e,r.name);if(r.isDirectory()){n.push(O(t));continue}if(r.isSymbolicLink()){n.push(D(t));continue}n.push(E(t))}return(await Promise.allSettled(n)).reduce((e,t)=>e+(t.status===`fulfilled`?t.value:0),0)}async function k(e){try{let t=await c.default.stat(e);return t.isDirectory()?await O(e)/1024:t.size/1024}catch{return 0}}function A(e){let t=Error(e??`操作已取消`);return t.name=`AbortError`,t}async function j(e,t){return new Promise((n,r)=>{if(t?.signal?.aborted)throw A();let i=null,a=(0,u.exec)(`${e}`,{encoding:`buffer`},(e,a,o)=>{let s=d.decode(a,`cp936`),c=d.decode(o,`cp936`);i&&t?.signal?.removeEventListener(`abort`,i);let l=e?Number(e.code??0):0;(t?.codeIsSuccess?!t.codeIsSuccess(l):l!==0)?r(Error(`命令行执行出错 (${l}): ${c||s}`)):n(s)}),o;i=()=>{a.kill(`SIGTERM`),o=setTimeout(()=>{a.kill(`SIGKILL`)},3e3),r(A())},t?.signal&&t.signal.addEventListener(`abort`,i),a.on(`close`,()=>{o!==void 0&&clearTimeout(o),t?.signal?.removeEventListener(`abort`,i)})})}async function M(e,t,n){let r=l.default.resolve(e),i=l.default.resolve(t),a;await p(e)?(a=`copy "${r}" "${i}"`,await j(a,{signal:n})):(a=`robocopy "${r}" "${i}" /E /NFL /NDL /NJH /NJS /NC /NS /NP`,await j(a,{codeIsSuccess:e=>e<8,signal:n}))}async function N(e){e=l.default.resolve(e),(await c.stat(e)).isDirectory()?await j(`start "" "${e}"`):await j(`start "" explorer /select,"${e}"`)}async function P(e){return j(`taskkill /f /im regedit.exe & REG ADD "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit" /v "LastKey" /d "${e}" /f & regedit`)}async function F(e,t){t=l.default.resolve(t),await g(e),await j(`reg export "${e}" "${t}" /y`,void 0)}async function I(e,t){await j(`reg import "${l.default.resolve(t)}"`,void 0)}exports.copyFile=M,exports.deleteFiles=y,exports.emptyDirectory=v,exports.ensureDir=g,exports.ensureDirSync=h,exports.existsFile=m,exports.exportRegedit=F,exports.formatFileSizeFromKB=T,exports.getDirSize=O,exports.getEnv=f,exports.getFileSizeKB=k,exports.importRegedit=I,exports.isFile=p,exports.isFileNotFoundError=_,exports.openRegedit=P,exports.readJSONFile=b,exports.readOrInitJSON=C,exports.showInExplorer=N,exports.updateJSON=S,exports.writeJSONFile=x;
|
|
2
|
+
//# sourceMappingURL=node.umd.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.umd.cjs","names":[],"sources":["../src/node/utils/env.ts","../src/node/utils/file/base.ts","../src/node/utils/file/delete.ts","../src/node/utils/file/json.ts","../src/core/utils/number/format.ts","../src/node/utils/file/size.ts","../src/core/utils/error.ts","../src/node/utils/win/cmd.ts","../src/node/utils/win/copy.ts","../src/node/utils/win/explorer.ts","../src/node/utils/win/regedit.ts"],"sourcesContent":["/**\n * 获取环境变量\n */\nexport function getEnv(): { [p: string]: string } {\n const env: { [p: string]: string } = {}\n for (const envKey in process.env) {\n env[envKey] = process.env[envKey] as string\n }\n return env\n}\n","import fs from 'node:fs/promises'\n\n/**\n * 判断路径是否是文件\n */\nexport async function isFile(filePath: string) {\n try {\n return (await fs.stat(filePath)).isFile()\n } catch {\n return false\n }\n}\n\n/**\n * 判断文件是否存在\n */\nexport async function existsFile(file: string, mode?: number) {\n try {\n fs.access(file, mode)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * 确保目录存在\n */\nexport async function ensureDirSync(dirPath: string) {\n fs.mkdir(dirPath, { recursive: true })\n}\n\n/**\n * 确保目录存在\n */\nexport async function ensureDir(dirPath: string) {\n await fs.mkdir(dirPath, { recursive: true })\n}\n\n/**\n * 判断错误是否为文件不存在\n */\nexport function isFileNotFoundError(error: unknown): boolean {\n return (\n typeof error === 'object' && error !== null && 'code' in error && (error as NodeJS.ErrnoException).code === 'ENOENT'\n )\n}\n","import fs from 'node:fs/promises'\nimport path from 'node:path'\n\n/**\n * 删除指定目录下的所有文件和子目录(保留指定目录)\n * @param dir 目标目录路径\n * @return 成功删除的文件或目录路径数组\n */\nexport async function emptyDirectory(dir: string) {\n const deletedPaths: string[] = []\n // 读取目录中的所有文件和子目录\n const entries = await fs.readdir(dir, { withFileTypes: true })\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name)\n if (entry.isDirectory()) {\n // 如果是目录,递归删除其内容\n deletedPaths.push(...(await emptyDirectory(fullPath)))\n // 删除空目录\n await fs.rmdir(fullPath)\n } else {\n // 如果是文件,删除文件\n await fs.unlink(fullPath)\n }\n deletedPaths.push(fullPath)\n }\n return deletedPaths\n}\n\n/**\n * 删除文件(不删除目录)\n * @param paths 文件路径列表\n * @returns 成功删除的文件路径数组\n */\nexport async function deleteFiles(paths: string[]): Promise<string[]> {\n const results = await Promise.allSettled(\n paths.map(async (file) => {\n await fs.unlink(file)\n return file\n }),\n )\n\n return results.filter((r): r is PromiseFulfilledResult<string> => r.status === 'fulfilled').map((r) => r.value)\n}\n","import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { isFileNotFoundError, ensureDir, isFile } from './base.js'\n\n/**\n * 读取 JSON 文件\n */\nexport async function readJSONFile<T>(filePath: string): Promise<T> {\n if (!(await isFile(filePath))) {\n throw new Error('文件不存在')\n }\n const jsonRaw = await fs.readFile(path.resolve(filePath), 'utf-8')\n return JSON.parse(jsonRaw) as T\n}\n\n/**\n * 将数据原子写入 JSON 文件(先写临时文件再替换)\n */\nexport async function writeJSONFile<T>(file: string, data: T): Promise<void> {\n const tempFile = `${file}.tmp.${Date.now()}`\n const jsonContent = JSON.stringify(data, null, 2)\n await fs.writeFile(tempFile, jsonContent, 'utf-8')\n // 直接替换(会覆原文件)\n await fs.rename(tempFile, file)\n}\n\n/**\n * 读取 JSON 文件,修改后写回(原子操作)\n */\nexport async function updateJSON<T>(file: string, updater: (oldData: T) => T): Promise<T> {\n const oldData = await readJSONFile<T>(file)\n const newData = updater(oldData)\n await writeJSONFile(file, newData)\n return newData\n}\n\n/**\n * 从文件读取 JSON,若文件不存在则调用 initData 初始化并写入\n *\n * @param file 文件绝对路径或相对路径\n * @param initData 返回要写入的数据的异步函数\n * @returns 解析后的数据\n */\nexport async function readOrInitJSON<T>(file: string, initData: () => Promise<T>): Promise<T> {\n try {\n const content = await fs.readFile(file, 'utf-8')\n // 解析 JSON,若失败则抛出错误(不会误判为“不存在”)\n return JSON.parse(content) as T\n } catch (error) {\n // 文件不存在等其他错误要透传\n if (!isFileNotFoundError(error)) {\n throw error\n }\n // 文件不存在,生成初始数据\n const data = await initData()\n // 确保目录存在\n await ensureDir(path.dirname(file))\n // 写入文件,格式化 JSON\n await fs.writeFile(file, JSON.stringify(data, null, 2), 'utf-8')\n return data\n }\n}\n","/**\n * 格式化后的单位数据(如文件大小)\n */\nexport interface FormattedUnitSize {\n /** 换算后该单位的数值(未四舍五入) */\n size: number\n /** 单位名称,如 'MB' */\n unit: string\n /** 显示文本:数值四舍五入保留两位小数 + 单位,如 '1.50 MB' */\n text: string\n}\n\n/**\n * 按进制自动格式化单位\n * @param value 数值\n * @param base 进制(1024 / 1000)\n * @param units 单位列表\n * @param invalidText 无效值返回文本\n */\nexport function formatUnitSize(value: number, base: number, units: string[], invalidText = ''): FormattedUnitSize {\n if (!Number.isFinite(value)) {\n return { size: 0, unit: '', text: invalidText }\n }\n\n let size = value\n let unitIndex = 0\n\n while (size >= base && unitIndex < units.length - 1) {\n size /= base\n unitIndex++\n }\n\n return {\n size,\n unit: units[unitIndex],\n text: `${size.toFixed(2).replace(/\\.?0+$/, '')} ${units[unitIndex]}`,\n }\n}\n","import { formatUnitSize } from '../../../core/utils/number/format.js'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\n\n/**\n * 将 KB 文件大小格式化为字符串\n * @param sizeKB 文件大小(单位:KB)\n * @param invalidText 输入无效时返回文本\n */\nexport function formatFileSizeFromKB(sizeKB: number, invalidText: string = '') {\n const { size, unit, text } = formatUnitSize(sizeKB, 1024, ['KB', 'MB', 'GB'], invalidText)\n\n if (text === invalidText) {\n return invalidText\n }\n\n // 整数部分\n const integerPart = Math.floor(size)\n\n // 根据整数位数动态控制小数位\n let fractionDigits: number\n // 整数位 >= 3:不保留小数\n if (integerPart > 99) fractionDigits = 0\n // 整数位 = 2:保留 1 位小数\n else if (integerPart > 9) fractionDigits = 1\n // 整数位 = 1:保留 2 位小数\n else fractionDigits = 2\n\n const rounded = Math.round(size * 10 ** fractionDigits) / 10 ** fractionDigits\n return `${rounded} ${unit}`\n}\n\n/**\n * 获取单个文件的大小(字节)\n * @param filePath 文件路径\n * @returns 文件大小,读取失败返回 0\n */\nasync function getFileSize(filePath: string): Promise<number> {\n try {\n const stat = await fs.stat(filePath)\n return stat.size\n } catch {\n // 权限不足或文件不存在时忽略,当作 0\n return 0\n }\n}\n\n/**\n * 获取符号链接自身的大小(指向路径的字符串长度,不是目标文件大小)\n */\nasync function getSymbolicLinkSize(linkPath: string): Promise<number> {\n try {\n const stat = await fs.lstat(linkPath)\n return stat.size\n } catch {\n return 0\n }\n}\n\n/**\n * 获取目录总大小(字节),递归统计所有子文件\n * 符号链接:只计算链接文件本身的大小,不跟随指向目录\n * 权限错误:跳过该文件/目录,大小计为 0\n * @param dir 目录路径\n * @returns 总字节数\n */\nexport async function getDirSize(dir: string): Promise<number> {\n let entries\n try {\n entries = await fs.readdir(dir, { withFileTypes: true })\n } catch {\n // 无法读取目录时忽略,计为 0\n return 0\n }\n\n const tasks: Promise<number>[] = []\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name)\n\n // 目录:递归\n if (entry.isDirectory()) {\n tasks.push(getDirSize(fullPath))\n continue\n }\n\n // 符号链接:只计算链接自身大小(不跟随)\n if (entry.isSymbolicLink()) {\n tasks.push(getSymbolicLinkSize(fullPath))\n continue\n }\n\n // 普通文件\n tasks.push(getFileSize(fullPath))\n }\n\n const results = await Promise.allSettled(tasks)\n return results.reduce((total, result) => {\n return total + (result.status === 'fulfilled' ? result.value : 0)\n }, 0)\n}\n\n/**\n * 获取文件/文件夹大小\n * @param filePath 文件/文件夹路径\n */\nexport async function getFileSizeKB(filePath: string) {\n try {\n const stat = await fs.stat(filePath)\n if (stat.isDirectory()) {\n return (await getDirSize(filePath)) / 1024\n } else {\n return stat.size / 1024\n }\n } catch {\n return 0\n }\n}\n","import { CommonError } from '../error/common-error.js'\n\n/**\n * 是否为取消操作的错误\n */\nexport function isCanceledError(err: unknown): boolean {\n if (!(err instanceof Error)) return false\n\n return err.name === 'AbortError' || err.name === 'CanceledError' || ('code' in err && err.code === 'ERR_CANCELED')\n}\n\n/**\n * 创建取消错误\n * @param msg\n */\nexport function createAbortError(msg?: string): Error {\n const error = new Error(msg ?? '操作已取消')\n error.name = 'AbortError'\n return error\n}\n\n/**\n * 是否为通用错误对象\n */\nexport function isCommonError(error: unknown): error is CommonError {\n return error instanceof CommonError || (error instanceof Error && error.name === 'CommonError')\n}\n\n/**\n * 给错误消息添加前缀(空格隔开)\n */\nfunction prefixError(error: Error, prefix?: string): Error {\n if (!prefix) return error\n\n error.message = `${prefix} ${error.message}`\n return error\n}\n\n/**\n * 转换到通用异常\n */\nexport function convertToCommonError(error: unknown, prefix?: string) {\n if (isCommonError(error)) {\n return prefixError(error, prefix)\n }\n return new CommonError(`${prefix} ${getErrorMessage(error)}`, error)\n}\n\n/**\n * 获取异常信息\n */\nexport function getErrorMessage(error: unknown): string {\n if (typeof error === 'string') {\n return error\n }\n if (error instanceof Error) {\n return error.message\n }\n if (error && typeof error === 'object' && 'message' in error && typeof error.message === 'string') {\n return error.message\n }\n return String(error) ?? '未知错误'\n}\n","import { createAbortError } from '../../../core/index.js'\nimport { exec } from 'node:child_process'\nimport * as iconv from 'iconv-lite'\n\n/**\n * 命令执行的选项\n */\ninterface ExecOptions {\n /**\n * 判断结果码是否成功\n * @param number 结果码\n */\n codeIsSuccess?: (number: number) => boolean\n /**\n * 终止信号\n */\n signal?: AbortSignal\n}\n\n/**\n * 执行 windows 的命令\n * @param cmd 命令\n * @param options 执行选项\n */\nexport async function execWinCmd(cmd: string, options?: ExecOptions) {\n return new Promise<string>((resolve, reject) => {\n // 前置检查:如果 signal 已终止,直接拒绝\n if (options?.signal?.aborted) {\n throw createAbortError()\n }\n let abortHandler: (() => void) | null = null\n\n const child = exec(`${cmd}`, { encoding: 'buffer' }, (error, stdout, stderr) => {\n const stdoutStr = iconv.decode(stdout, 'cp936')\n const stderrStr = iconv.decode(stderr, 'cp936')\n\n // 清理 abort 监听\n if (abortHandler) {\n options?.signal?.removeEventListener('abort', abortHandler)\n }\n\n const exitCode = error ? Number((error as NodeJS.ErrnoException).code ?? 0) : 0\n if (options?.codeIsSuccess ? !options.codeIsSuccess(exitCode) : exitCode !== 0) {\n reject(new Error(`命令行执行出错 (${exitCode}): ${stderrStr || stdoutStr}`))\n } else {\n resolve(stdoutStr)\n }\n })\n // 进程取消后超时响应的处理定时器\n let timeout: ReturnType<typeof setTimeout>\n // 定义 abort 处理函数\n abortHandler = () => {\n // 请求终止,进程可拒绝或延迟\n child.kill('SIGTERM')\n timeout = setTimeout(() => {\n child.kill('SIGKILL')\n }, 3000)\n reject(createAbortError())\n }\n // 注册 abort 监听\n if (options?.signal) {\n options.signal.addEventListener('abort', abortHandler)\n }\n\n // 进程意外终止处理\n child.on('close', () => {\n if (timeout !== undefined) clearTimeout(timeout)\n options?.signal?.removeEventListener('abort', abortHandler)\n })\n })\n}\n","import path from 'node:path'\nimport { execWinCmd } from './cmd.js'\nimport { isFile } from '../file/base.js'\n\n/**\n * 文件拷贝工具,支持文件或文件夹\n */\nexport async function copyFile(source: string, destination: string, signal?: AbortSignal) {\n const src = path.resolve(source)\n const dest = path.resolve(destination)\n\n let command: string\n\n if (await isFile(source)) {\n // 文件用 copy 命令\n command = `copy \"${src}\" \"${dest}\"`\n await execWinCmd(command, { signal: signal })\n } else {\n // 文件夹用 robocopy\n command = `robocopy \"${src}\" \"${dest}\" /E /NFL /NDL /NJH /NJS /NC /NS /NP`\n await execWinCmd(command, {\n codeIsSuccess: (number) => number < 8,\n signal: signal,\n })\n }\n}\n","import path from 'node:path'\nimport * as fs from 'node:fs/promises'\nimport { execWinCmd } from './cmd.js'\n\n/**\n * 打开资源管理器并定位到目录或者文件\n * @param fileOrDir 定位的目录或文件\n */\nexport async function showInExplorer(fileOrDir: string) {\n fileOrDir = path.resolve(fileOrDir)\n if ((await fs.stat(fileOrDir)).isDirectory()) {\n await execWinCmd(`start \"\" \"${fileOrDir}\"`)\n } else {\n await execWinCmd(`start \"\" explorer /select,\"${fileOrDir}\"`)\n }\n}\n","import { execWinCmd } from './cmd.js'\nimport path from 'node:path'\nimport { ensureDir } from '../file/base.js'\n\n/**\n * 打开注册表\n * @param path 显示的路径\n */\nexport async function openRegedit(path: string) {\n return execWinCmd(\n `taskkill /f /im regedit.exe & REG ADD \"HKCU\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Applets\\\\Regedit\" /v \"LastKey\" /d \"${path}\" /f & regedit`,\n )\n}\n\n/**\n * 导出注册表\n * @param regPath 注册表路径\n * @param filePath 导出的文件路径\n */\nexport async function exportRegedit(regPath: string, filePath: string) {\n filePath = path.resolve(filePath)\n await ensureDir(regPath)\n await execWinCmd(`reg export \"${regPath}\" \"${filePath}\" /y`, undefined)\n}\n\n/**\n * 导入注册表\n * @param regPath 注册表路径\n * @param filePath 导入的文件路径\n */\nexport async function importRegedit(regPath: string, filePath: string) {\n await execWinCmd(`reg import \"${path.resolve(filePath)}\"`, undefined)\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,28 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ybgnb/utils",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"author": "hzhilong",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "自用工具库",
|
|
7
7
|
"type": "module",
|
|
8
|
-
"main": "./dist/
|
|
9
|
-
"module": "./dist/
|
|
10
|
-
"types": "./dist/
|
|
8
|
+
"main": "./dist/core.umd.cjs",
|
|
9
|
+
"module": "./dist/core.js",
|
|
10
|
+
"types": "./dist/core.d.ts",
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
13
|
-
"types": "./dist/
|
|
14
|
-
"import": "./dist/
|
|
15
|
-
"require": "./dist/
|
|
13
|
+
"types": "./dist/core.d.ts",
|
|
14
|
+
"import": "./dist/core.js",
|
|
15
|
+
"require": "./dist/core.umd.cjs"
|
|
16
|
+
},
|
|
17
|
+
"./dom": {
|
|
18
|
+
"types": "./dist/dom.d.ts",
|
|
19
|
+
"import": "./dist/dom.js",
|
|
20
|
+
"require": "./dist/dom.umd.cjs"
|
|
21
|
+
},
|
|
22
|
+
"./node": {
|
|
23
|
+
"types": "./dist/node.d.ts",
|
|
24
|
+
"import": "./dist/node.js",
|
|
25
|
+
"require": "./dist/node.umd.cjs"
|
|
16
26
|
}
|
|
17
27
|
},
|
|
18
28
|
"files": [
|
|
19
29
|
"dist"
|
|
20
30
|
],
|
|
21
31
|
"scripts": {
|
|
22
|
-
"check": "tsc --
|
|
32
|
+
"check": "tsc --build --noEmit",
|
|
23
33
|
"lint": "eslint . --fix",
|
|
24
34
|
"format": "prettier --write .",
|
|
25
|
-
"barrelsby": "
|
|
35
|
+
"barrelsby": "barrelsby -c barrelsby.json & tsx scripts/revise-index.ts",
|
|
26
36
|
"build": "vite build --mode library",
|
|
27
37
|
"npm login": "npm login",
|
|
28
38
|
"npm publish": "npm publish --access public"
|
|
@@ -39,8 +49,9 @@
|
|
|
39
49
|
"bugs": {
|
|
40
50
|
"url": "https://github.com/hzhilong/ybgnb-js/issues"
|
|
41
51
|
},
|
|
42
|
-
"homepage": "https://github.com/hzhilong/ybgnb-js#readme",
|
|
52
|
+
"homepage": "https://github.com/hzhilong/ybgnb-js/tree/main/utils#readme",
|
|
43
53
|
"devDependencies": {
|
|
54
|
+
"@types/node": "^25.6.0",
|
|
44
55
|
"barrelsby": "^2.8.1",
|
|
45
56
|
"eslint": "^9.39.4",
|
|
46
57
|
"eslint-config-prettier": "^10.1.8",
|
|
@@ -51,7 +62,7 @@
|
|
|
51
62
|
"vite": "^8.0.8",
|
|
52
63
|
"vite-plugin-dts": "^4.5.4"
|
|
53
64
|
},
|
|
54
|
-
"
|
|
55
|
-
"
|
|
65
|
+
"optionalDependencies": {
|
|
66
|
+
"iconv-lite": "^0.7.2"
|
|
56
67
|
}
|
|
57
68
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,416 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 中止异常
|
|
3
|
-
*/
|
|
4
|
-
export declare class AbortError extends CommonError {
|
|
5
|
-
constructor();
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* 任意方法
|
|
10
|
-
*/
|
|
11
|
-
export declare type AnyFn = (...args: any[]) => any;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* 业务执行结果
|
|
15
|
-
*/
|
|
16
|
-
export declare class BizResult<T> {
|
|
17
|
-
success: boolean;
|
|
18
|
-
msg: string;
|
|
19
|
-
data?: T;
|
|
20
|
-
constructor(success: boolean, msg: string, data?: T);
|
|
21
|
-
static createSuccess<T>(data: T): BizResult<T>;
|
|
22
|
-
static createFail<T>(msg?: string, data?: T): BizResult<T>;
|
|
23
|
-
static createError<T>(e: unknown): BizResult<T>;
|
|
24
|
-
/**
|
|
25
|
-
* 展开成Promise
|
|
26
|
-
*/
|
|
27
|
-
toPromise(): Promise<void>;
|
|
28
|
-
toPromise<T>(): Promise<T>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* 将数组分块为指定大小的多个子数组
|
|
33
|
-
* @param arr 原数组
|
|
34
|
-
* @param size 每个块的长度
|
|
35
|
-
* @example chunk([1,2,3,4,5], 2) => [[1,2],[3,4],[5]]
|
|
36
|
-
*/
|
|
37
|
-
export declare function chunk<T>(arr: T[], size: number): T[][];
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 通用异常
|
|
41
|
-
*/
|
|
42
|
-
export declare class CommonError extends Error {
|
|
43
|
-
message: string;
|
|
44
|
-
rawError?: Error;
|
|
45
|
-
constructor(message: string, rawError?: Error);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* 转换到通用异常
|
|
50
|
-
* @param error 异常
|
|
51
|
-
* @param preMsg 前置提示 `${preMsg}${error.message}`
|
|
52
|
-
*/
|
|
53
|
-
export declare function convertToCommonError(error: unknown, preMsg?: string): CommonError;
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* 编码 URL 参数
|
|
57
|
-
* @param params 查询参数
|
|
58
|
-
*/
|
|
59
|
-
export declare function encodeURLParams(params: QueryParams): string;
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* 执行业务(自动包裹BuResult)
|
|
63
|
-
* @param run 执行方法
|
|
64
|
-
*/
|
|
65
|
-
export declare const execBiz: <T>(run: () => Promise<T>) => Promise<BizResult<T>>;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* 提取getter属性
|
|
69
|
-
*/
|
|
70
|
-
export declare type ExtractGetterProperties<T> = {
|
|
71
|
-
[K in keyof T as K extends `get${infer Rest}` ? Uncapitalize<Rest> : never]: T[K] extends (...args: any[]) => Promise<infer R> ? R : never;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* 提取所有函数 key
|
|
76
|
-
*/
|
|
77
|
-
export declare type FunctionKeys<T> = {
|
|
78
|
-
[K in keyof T]: T[K] extends AnyFn ? K : never;
|
|
79
|
-
}[keyof T];
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* 获取异常信息
|
|
83
|
-
*/
|
|
84
|
-
export declare function getErrorMessage(error: unknown): string;
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* 格式化时间为 2020-02-02 20:20:20 的字符串
|
|
88
|
-
* @param date 需要格式化的时间,为空则获取当前时间
|
|
89
|
-
*/
|
|
90
|
-
export declare function getFormattedDate(date?: Date): string;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* 格式化时间为 2020-02-02 20:20:20 的字符串
|
|
94
|
-
* @param date 需要格式化的时间,为空则获取当前时间
|
|
95
|
-
*/
|
|
96
|
-
export declare function getFormattedDateTime(date?: Date): string;
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* 格式化时间为 20:20:20 的字符串
|
|
100
|
-
* @param date 需要格式化的时间,为空则获取当前时间
|
|
101
|
-
*/
|
|
102
|
-
export declare function getFormattedTime(date?: Date): string;
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* 从 <img> 元素获取图片字节数据(ArrayBuffer)
|
|
106
|
-
* @param img 已加载的 <img> 元素
|
|
107
|
-
* @param type 图片类型,可选(默认 png)
|
|
108
|
-
*/
|
|
109
|
-
export declare function getImageArrayBuffer(img: HTMLImageElement, type?: string): Promise<ArrayBuffer>;
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* 等待加载完成并获取字节数据
|
|
113
|
-
*/
|
|
114
|
-
export declare function getImgArrayBufferAfterLoad(img: HTMLImageElement, type?: string): Promise<ArrayBuffer>;
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* 获取网络信息
|
|
118
|
-
*/
|
|
119
|
-
export declare function getNetworkInfo(): NetworkState;
|
|
120
|
-
|
|
121
|
-
/** github 仓库信息 */
|
|
122
|
-
export declare interface GithubRepository {
|
|
123
|
-
/** 仓库所有者(用户或组织名) */
|
|
124
|
-
owner: string;
|
|
125
|
-
/** 仓库名称 */
|
|
126
|
-
repo: string;
|
|
127
|
-
/** 分支名称 */
|
|
128
|
-
branch: string;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* 将十六进制颜色转换为 RGB
|
|
133
|
-
*/
|
|
134
|
-
export declare const hexToRgb: (hex: string) => {
|
|
135
|
-
r: number;
|
|
136
|
-
g: number;
|
|
137
|
-
b: number;
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* 滚动元素到屏幕中心
|
|
142
|
-
* @param el
|
|
143
|
-
*/
|
|
144
|
-
export declare function humanScrollElIntoCenter(el: HTMLElement): Promise<void>;
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* 模拟人类手感滚动到指定位置
|
|
148
|
-
*/
|
|
149
|
-
export declare function humanScrollTo(targetX: number, targetY: number): Promise<void>;
|
|
150
|
-
|
|
151
|
-
/** URL query 中必须编码的保留字符 (RFC 3986) */
|
|
152
|
-
export declare const invalidCharRegex: RegExp;
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* 判断是否为通用异常
|
|
156
|
-
*/
|
|
157
|
-
export declare function isCommonError(error: unknown): error is CommonError;
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* 是否为空数组
|
|
161
|
-
* @param data
|
|
162
|
-
*/
|
|
163
|
-
export declare function isEmptyArr(data: unknown): boolean;
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* 判断字符串是否为有效的 HTTP/HTTPS URL
|
|
167
|
-
* @param path - 待检测的字符串
|
|
168
|
-
*/
|
|
169
|
-
export declare function isHttpUrl(path: string): boolean;
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* 提取 T 中所有值类型为 V 的键
|
|
173
|
-
*/
|
|
174
|
-
export declare type KeysMatching<T, V> = {
|
|
175
|
-
[K in keyof T]: T[K] extends V ? K : never;
|
|
176
|
-
}[keyof T];
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* 用元组限制长度
|
|
180
|
-
*/
|
|
181
|
-
export declare type MaxLengthArray<T, N extends number> = T[] & {
|
|
182
|
-
length: N;
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
*
|
|
187
|
-
*/
|
|
188
|
-
/**
|
|
189
|
-
* 合并查询参数
|
|
190
|
-
* @param urlSearchParams url解析后查询参数
|
|
191
|
-
* @param params 单独传的查询参数
|
|
192
|
-
*/
|
|
193
|
-
export declare function mergeQueryParams(urlSearchParams: URLSearchParams, params?: QueryParams): QueryParams;
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* 提取所有方法
|
|
197
|
-
*/
|
|
198
|
-
export declare type MethodKeys<T> = {
|
|
199
|
-
[K in keyof T]-?: T[K] extends AnyFn ? K : never;
|
|
200
|
-
}[keyof T];
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* 方法参数类型
|
|
204
|
-
*/
|
|
205
|
-
export declare type MethodParams<T> = T extends (...args: infer P) => any ? P : never;
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* 方法返回类型
|
|
209
|
-
*/
|
|
210
|
-
export declare type MethodReturn<T> = T extends (...args: any[]) => infer R ? R : never;
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* 生成 CSS `color-mix()` 函数的字符串表示,用于动态计算两种颜色的混合结果
|
|
214
|
-
*
|
|
215
|
-
* @param {string} color1 - 参与混合的第一种颜色(支持 CSS 合法颜色值,如 HEX、RGB、HSL 等)
|
|
216
|
-
* @param {string} color2 - 参与混合的第二种颜色
|
|
217
|
-
* @param {number} percentage - 主颜色(color1)在混合中的占比(百分比数值,范围 0-100)
|
|
218
|
-
* @param {'srgb' | 'hsl'} [colorSpace='srgb'] - 色彩空间选项:
|
|
219
|
-
* - `'srgb'`: 标准 RGB 色彩空间(默认)
|
|
220
|
-
* - `'hsl'`: 色相-饱和度-明度色彩空间
|
|
221
|
-
* @param {number} [percentage2] - 可选参数:副颜色(color2)的独立占比。
|
|
222
|
-
* 若未提供,则自动计算为 `100 - percentage`
|
|
223
|
-
* @returns {string} 可直接用于 CSS 的 `color-mix()` 函数字符串(如 `color-mix(in srgb, red 30%, blue 70%)`)
|
|
224
|
-
*
|
|
225
|
-
* @example
|
|
226
|
-
* // 基础用法(自动计算互补占比)
|
|
227
|
-
* mixColor('red', 'blue', 30)
|
|
228
|
-
* // 返回: "color-mix(in srgb, red 30%, blue 70%)"
|
|
229
|
-
*
|
|
230
|
-
* @example
|
|
231
|
-
* // 显式指定双占比 + HSL 色彩空间
|
|
232
|
-
* mixColor('#ff0000', '#0000ff', 40, 'hsl', 60)
|
|
233
|
-
* // 返回: "color-mix(in hsl, #ff0000 40%, #0000ff 60%)"
|
|
234
|
-
*/
|
|
235
|
-
export declare const mixColor: (color1: string, color2: string, percentage: number, colorSpace?: "srgb" | "hsl", percentage2?: number) => string;
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* 网络信息
|
|
239
|
-
*/
|
|
240
|
-
export declare interface NetworkInfo extends EventTarget {
|
|
241
|
-
downlink: number;
|
|
242
|
-
rtt: number;
|
|
243
|
-
effectiveType: 'slow-2g' | '2g' | '3g' | '4g';
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* 网络状态
|
|
248
|
-
* - 'offline': 无网络
|
|
249
|
-
* - 'online': 在线但不支持 NetworkInformation API
|
|
250
|
-
* - NetworkInformation: 含详细网络信息
|
|
251
|
-
*/
|
|
252
|
-
export declare type NetworkState = 'offline' | Omit<NetworkInfo, keyof EventTarget> | 'online';
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* 监听网络状态变化
|
|
256
|
-
* @param listener 监听器
|
|
257
|
-
* @returns 成功监听时返回解绑函数
|
|
258
|
-
*/
|
|
259
|
-
export declare function onNetworkChange(listener: (info: NetworkState) => void): () => void;
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* 监听页面可见性变化(兼容旧的IE/Chrome)
|
|
263
|
-
* @param listener 监听器
|
|
264
|
-
* @returns 成功监听时返回解绑函数
|
|
265
|
-
*/
|
|
266
|
-
export declare function onVisibilityChange(listener: VisibilityChangeListener): (() => void) | null;
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* 已解析的 url
|
|
270
|
-
*/
|
|
271
|
-
export declare interface ParsedUrl {
|
|
272
|
-
baseUrl: string;
|
|
273
|
-
searchParams: URLSearchParams;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* 从 url 解析 github 仓库信息
|
|
278
|
-
* @param repositoryUrl 仓库 URL(支持带有git+前缀、具体文件路径)
|
|
279
|
-
*/
|
|
280
|
-
export declare function parseGithubRepo(repositoryUrl: string): GithubRepository;
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* 解析 url
|
|
284
|
-
* @param url
|
|
285
|
-
*/
|
|
286
|
-
export declare function parseUrl(url: string): ParsedUrl;
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* 物理像素的点位
|
|
290
|
-
*/
|
|
291
|
-
export declare interface PhysicalPoint {
|
|
292
|
-
x: number;
|
|
293
|
-
y: number;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* 物理像素的区域数据
|
|
298
|
-
*/
|
|
299
|
-
export declare interface PhysicalRect {
|
|
300
|
-
x: number;
|
|
301
|
-
y: number;
|
|
302
|
-
width: number;
|
|
303
|
-
height: number;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
/**
|
|
307
|
-
* 设置异常信息的前置提示
|
|
308
|
-
* @param error 异常
|
|
309
|
-
* @param preMsg 前置信息 `${preMsg}${error.message}`
|
|
310
|
-
*/
|
|
311
|
-
export declare function prependErrorMessage(error: CommonError, preMsg?: string): CommonError;
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* 将数字范围按批次处理,每个批次调用一次异步函数
|
|
315
|
-
*
|
|
316
|
-
* @param start - 起始值(包含)
|
|
317
|
-
* @param end - 结束值(包含)
|
|
318
|
-
* @param batchSize - 每批最大元素个数
|
|
319
|
-
* @param processor - 处理单批数字数组的异步函数
|
|
320
|
-
*
|
|
321
|
-
* @example
|
|
322
|
-
* // 分批处理 1..10,每批最多 3 个数字
|
|
323
|
-
* await processRangeInBatches(1, 10, 3, async (batch) => {
|
|
324
|
-
* console.log(batch) // 输出: [1,2,3], [4,5,6], [7,8,9], [10]
|
|
325
|
-
* })
|
|
326
|
-
*/
|
|
327
|
-
export declare function processRangeInBatches(start: number, end: number, batchSize: number, processor: (batch: number[]) => Promise<void>): Promise<void>;
|
|
328
|
-
|
|
329
|
-
/** 查询参数 */
|
|
330
|
-
export declare type QueryParams = Record<string, string | number | boolean | null | undefined>;
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* 获取 1~n 的随机数
|
|
334
|
-
*/
|
|
335
|
-
export declare function random1ToN(n: number): number;
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* 获取 [min, max) 的随机浮点数
|
|
339
|
-
*/
|
|
340
|
-
export declare function randomFloat(min: number, max: number): number;
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* 获取 [min, max] 的随机整数
|
|
344
|
-
*/
|
|
345
|
-
export declare function randomInt(min: number, max: number): number;
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* 至少包含一个字段
|
|
349
|
-
*/
|
|
350
|
-
export declare type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> & {
|
|
351
|
-
[K in Keys]: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
|
|
352
|
-
}[Keys];
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
* 随机运行参数
|
|
356
|
-
* @param fns
|
|
357
|
-
* @param maxCount 最多执行次数(1 ~ fns.length)
|
|
358
|
-
*/
|
|
359
|
-
export declare function runRandomFunctions(fns: Array<() => void>, maxCount?: number): void;
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* 从数组中随机取若干项,不可重复
|
|
363
|
-
*/
|
|
364
|
-
export declare function sample<T>(arr: T[], count: number): T[];
|
|
365
|
-
|
|
366
|
-
/**
|
|
367
|
-
* 从数组中获取随机项
|
|
368
|
-
*/
|
|
369
|
-
export declare function sampleOne<T>(arr: T[]): T;
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* 从数组中随机取若干项,可重复
|
|
373
|
-
*/
|
|
374
|
-
export declare function sampleWithReplacement<T>(arr: T[], count: number): T[];
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* 设置 html 根元素的 css 变量
|
|
378
|
-
*/
|
|
379
|
-
export declare const setCssVar: (k: string, v: string) => void;
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* 数组洗牌
|
|
383
|
-
*/
|
|
384
|
-
export declare function shuffle<T>(arr: T[]): T[];
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
* 支持取消的 sleep
|
|
388
|
-
* @param ms 延迟毫秒数
|
|
389
|
-
* @param signal 取消信号
|
|
390
|
-
*/
|
|
391
|
-
export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* 支持取消的随机 sleep
|
|
395
|
-
* @param minMS 最小延迟毫秒数
|
|
396
|
-
* @param maxMS 最大延迟毫秒数
|
|
397
|
-
* @param signal 取消信号
|
|
398
|
-
*/
|
|
399
|
-
export declare function sleepRandom(minMS: number, maxMS: number, signal?: AbortSignal): Promise<void>;
|
|
400
|
-
|
|
401
|
-
/** 可见性改变的监听器 */
|
|
402
|
-
export declare interface VisibilityChangeListener {
|
|
403
|
-
(hidden: boolean): void;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* 等待滚动
|
|
408
|
-
*/
|
|
409
|
-
export declare function waitScrollTo(targetX: number, targetY: number): Promise<void>;
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
* 等待 <img> 加载完成
|
|
413
|
-
*/
|
|
414
|
-
export declare function whenImageLoaded(img: HTMLImageElement): Promise<HTMLImageElement>;
|
|
415
|
-
|
|
416
|
-
export { }
|