@cloudcome/utils-core 1.20.0 → 1.21.0
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/README.md +71 -72
- package/dist/array.cjs.map +1 -1
- package/dist/array.mjs.map +1 -1
- package/dist/async.cjs.map +1 -1
- package/dist/async.mjs.map +1 -1
- package/dist/cache.cjs.map +1 -1
- package/dist/cache.mjs.map +1 -1
- package/dist/color.cjs.map +1 -1
- package/dist/color.mjs.map +1 -1
- package/dist/date.cjs.map +1 -1
- package/dist/date.mjs.map +1 -1
- package/dist/dict.cjs +1 -1
- package/dist/dict.cjs.map +1 -1
- package/dist/dict.mjs +1 -1
- package/dist/dict.mjs.map +1 -1
- package/dist/easing.cjs +1 -2
- package/dist/easing.cjs.map +1 -1
- package/dist/easing.mjs +1 -2
- package/dist/easing.mjs.map +1 -1
- package/dist/emitter.cjs.map +1 -1
- package/dist/emitter.mjs.map +1 -1
- package/dist/env.cjs.map +1 -1
- package/dist/env.mjs.map +1 -1
- package/dist/error.cjs.map +1 -1
- package/dist/error.mjs.map +1 -1
- package/dist/exception.cjs.map +1 -1
- package/dist/exception.mjs.map +1 -1
- package/dist/function.cjs +33 -0
- package/dist/function.cjs.map +1 -1
- package/dist/function.d.ts +34 -0
- package/dist/function.mjs +33 -1
- package/dist/function.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/object/get-set.d.ts +1 -25
- package/dist/object.cjs.map +1 -1
- package/dist/object.mjs.map +1 -1
- package/dist/promise.cjs.map +1 -1
- package/dist/promise.mjs.map +1 -1
- package/dist/qs.cjs.map +1 -1
- package/dist/qs.mjs.map +1 -1
- package/dist/regexp.cjs.map +1 -1
- package/dist/regexp.mjs.map +1 -1
- package/dist/string2.cjs.map +1 -1
- package/dist/string2.mjs.map +1 -1
- package/dist/time.cjs.map +1 -1
- package/dist/time.mjs.map +1 -1
- package/dist/timer.cjs +76 -32
- package/dist/timer.cjs.map +1 -1
- package/dist/timer.d.ts +130 -25
- package/dist/timer.mjs +76 -32
- package/dist/timer.mjs.map +1 -1
- package/dist/tree.cjs.map +1 -1
- package/dist/tree.mjs.map +1 -1
- package/dist/try.cjs.map +1 -1
- package/dist/try.mjs.map +1 -1
- package/dist/type.cjs.map +1 -1
- package/dist/type.mjs.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/url.cjs +1 -1
- package/dist/url.cjs.map +1 -1
- package/dist/url.mjs +1 -1
- package/dist/url.mjs.map +1 -1
- package/package.json +6 -6
package/dist/tree.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree.cjs","names":[],"sources":["../src/tree.ts"],"sourcesContent":["import { arrayEach } from './array';\nimport { isArray, isNullish, isUndefined } from './type';\nimport type { AnyObject } from './types';\n\n/**\n * 表示深度遍历中的节点对象,包含子节点列表。\n */\nexport type TreeItem = AnyObject & {\n /**\n * 子节点列表。\n */\n children?: TreeItem[];\n};\n\n/**\n * 表示深度遍历中的节点列表。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TreeList<I extends TreeItem> = I[];\n\n/**\n * 表示深度遍历中的遍历器状态。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TreeWalker<I extends TreeItem> = {\n /**\n * 当前层级的节点列表。\n */\n list: TreeList<I>;\n\n /**\n * 当前节点的父节点,如果为根节点则为 `null`。\n */\n parent: I | null;\n\n /**\n * 当前节点的层级,从 1 开始计数。\n */\n level: number;\n\n /**\n * 从根节点到当前节点的路径。\n */\n path: TreeList<I>;\n};\n\n/**\n * 表示深度遍历中的节点信息。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TreeInfo<I extends TreeItem> = TreeWalker<I> & {\n /**\n * 当前节点。\n */\n item: I;\n\n /**\n * 当前节点在 `list` 中的索引。\n */\n index: number;\n};\n\n/**\n * 深度遍历的同步迭代器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param info - 当前节点的信息。\n * @returns 如果返回 `false`,则提前终止遍历。\n */\nexport type TreeEachIterator<I extends TreeItem> = (\n info: TreeInfo<I>,\n) => false | unknown;\n\n/**\n * 深度遍历的异步迭代器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param info - 当前节点的信息。\n * @returns 如果返回 `false`,则提前终止遍历。\n */\nexport type TreeEachIteratorAsync<I extends TreeItem> = (\n info: TreeInfo<I>,\n) => Promise<boolean | unknown>;\n\n/**\n * 深度遍历的同步遍历器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param walker - 遍历器状态。\n * @returns 遍历结果。\n */\nexport type TreeWalk<I extends TreeItem> = (walker: TreeWalker<I>) => unknown;\n\n/**\n * 深度遍历的异步遍历器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param walker - 遍历器状态。\n * @returns 异步遍历结果。\n */\nexport type TreeWalkAsync<I extends TreeItem> = (\n walker: TreeWalker<I>,\n) => Promise<unknown>;\n\n/**\n * 深度遍历数组中的每个元素,并对每个元素执行提供的回调函数。\n *\n * @param treeList - 要遍历的深度数组。\n * @param iterator - 对每个元素执行的回调函数。如果回调函数返回 `false`,则提前终止遍历。\n * @param breadthFist - 是否使用广度优先遍历,默认为 `false`(深度优先)。\n * @returns 无返回值。\n *\n * @example\n * ```typescript\n * const treeList = [\n * { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * { value: 4 }\n * ];\n *\n * treeEach(treeList, (item) => {\n * console.log(item.value);\n * if (item.value === 2) return false; // 提前终止遍历\n * });\n * ```\n */\nexport function treeEach<I extends TreeItem = TreeItem>(\n treeList: TreeList<I>,\n iterator: TreeEachIterator<I>,\n breadthFist = false,\n): void {\n const treeInfoList: TreeInfo<I>[] = [];\n let returnFalse = false;\n\n const iterate = (info: TreeInfo<I>) => {\n if (iterator(info) === false) {\n returnFalse = true;\n return false;\n }\n };\n\n const next = (info: TreeInfo<I>, walk: TreeWalk<I>) => {\n const { item, level } = info;\n const { children } = item;\n\n if (isArray(children)) {\n returnFalse =\n walk({\n ...info,\n parent: item,\n list: children as TreeList<I>,\n level: level + 1,\n }) === false;\n }\n };\n\n const walk: TreeWalk<I> = (walker) => {\n const { list, parent, path } = walker;\n\n const path2 = [...path];\n while (\n parent !== null &&\n path2.length > 0 &&\n path2[path2.length - 1] !== parent\n ) {\n path2.pop();\n }\n\n arrayEach(list, (item, index) => {\n if (returnFalse) return false;\n\n const info: TreeInfo<I> = {\n ...walker,\n item,\n index,\n path: [...path2, item],\n };\n\n // 广度优先\n if (breadthFist) {\n treeInfoList.push(info);\n }\n // 深度优先\n else {\n iterate(info);\n if (returnFalse) return false;\n next(info, walk);\n }\n });\n\n if (breadthFist) {\n while (!returnFalse) {\n const info = treeInfoList.shift();\n if (!info) break;\n\n iterate(info);\n if (returnFalse) break;\n\n // 内部也会进入 walk\n next(info, walk);\n }\n }\n\n return !returnFalse;\n };\n\n walk({\n list: treeList,\n level: 1,\n parent: null,\n path: [],\n });\n}\n\n/**\n * 在深度数组中查找满足条件的第一个节点信息。\n *\n * @param treeList - 要查找的深度数组。\n * @param predicate - 判断节点是否满足条件的回调函数。\n * @param breadthFist - 是否使用广度优先查找,默认为 `false`(深度优先)。\n * @returns 如果找到满足条件的节点,则返回该节点的信息;否则返回 `undefined`。\n *\n * @example\n * ```typescript\n * const treeList = [\n * { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * { value: 4 }\n * ];\n *\n * const found = treeFind(treeList, (info) => info.item.value === 3);\n * console.log(found);\n * // {\n * // item: { value: 3 },\n * // index: 1,\n * // list: [{ value: 2 }, { value: 3 }],\n * // parent: { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * // level: 2,\n * // path: [{ value: 1, children: [{ value: 2 }, { value: 3 }] }, { value: 3 }]\n * // }\n * ```\n */\nexport function treeFind<I extends TreeItem>(\n treeList: TreeList<I>,\n predicate: (info: TreeInfo<I>) => boolean,\n breadthFist = false,\n): TreeInfo<I> | undefined {\n let found: TreeInfo<I> | undefined;\n\n treeEach(\n treeList,\n (info) => {\n if (predicate(info)) {\n found = info;\n return false;\n }\n },\n breadthFist,\n );\n\n return found;\n}\n\n/**\n * 将深度嵌套的树形结构扁平化为一维数组,并对每个节点执行指定的转换函数。\n *\n * @template I - 树节点的类型,必须继承自 `TreeItem`。\n * @template T - 转换后的数据类型。\n * @param {TreeList<I>} deepList - 要扁平化的深度嵌套树形结构。\n * @param {(info: TreeInfo<I>) => T} flatten - 对每个节点执行的转换函数,返回转换后的数据。\n * @param {boolean} [breadthFist=false] - 是否使用广度优先遍历,默认为 `false`(深度优先)。\n * @returns {T[]} - 转换后的一维数组。\n * @example\n * ```typescript\n * const treeList = [\n * { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * { value: 4 }\n * ];\n *\n * const flattened = deepFlat(treeList, (info) => info.item.value);\n * console.log(flattened); // [1, 2, 3, 4]\n * ```\n */\nexport function deepFlat<I extends TreeItem, T>(\n deepList: TreeList<I>,\n flatten: (info: TreeInfo<I>) => T,\n breadthFist = false,\n): T[] {\n const list2: T[] = [];\n\n treeEach(\n deepList,\n (info) => {\n list2.push(flatten(info));\n },\n breadthFist,\n );\n\n return list2;\n}\n\ntype FromItemInfo<I> = {\n selfKey: unknown;\n parentKey: unknown;\n item: I;\n index: number;\n};\n\nexport type TreeFromOptions<I extends TreeItem> = {\n getSelfKey: (item: I, index: number) => unknown;\n getParentKey: (item: I, index: number) => unknown;\n appendChild: (parentInfo: FromItemInfo<I>, info: FromItemInfo<I>) => unknown;\n};\n\n/**\n * 从扁平列表构建树形结构。\n *\n * @template I - 节点对象的类型,必须继承自 `AnyObject`。\n * @param {I[]} list - 扁平化的节点列表。\n * @param {TreeFromOptions<I>} options - 构建树形结构的配置选项。\n * @param {function} options.getSelfKey - 获取节点自身唯一标识的函数。\n * @param {function} options.getParentKey - 获取节点父节点唯一标识的函数。\n * @param {function} options.appendChild - 将子节点添加到父节点的函数。\n * @returns {I | undefined} - 构建的树形结构的根节点,如果未找到根节点则返回 `undefined`。\n *\n * @example\n * ```typescript\n * const list = [\n * { id: 1, parentId: null, name: 'Root' },\n * { id: 2, parentId: 1, name: 'Child 1' },\n * { id: 3, parentId: 1, name: 'Child 2' }\n * ];\n *\n * const tree = treeFrom(list, {\n * getSelfKey: (item) => item.id,\n * getParentKey: (item) => item.parentId,\n * appendChild: (parent, info) => {\n * if (!parent.children) parent.children = [];\n * parent.children.push(info.item);\n * }\n * });\n *\n * console.log(tree);\n * // {\n * // id: 1,\n * // parentId: null,\n * // name: 'Root',\n * // children: [\n * // { id: 2, parentId: 1, name: 'Child 1' },\n * // { id: 3, parentId: 1, name: 'Child 2' }\n * // ]\n * // }\n * ```\n */\nexport function treeFrom<I extends TreeItem>(\n list: I[],\n options: TreeFromOptions<I>,\n): TreeList<I> | undefined {\n const keyMap = new Map<unknown, FromItemInfo<I>>();\n const freeSet = new Set<FromItemInfo<I>>();\n const roots: TreeList<I> = [];\n\n // 分配节点\n const assign = (info: FromItemInfo<I>, isFirst = false) => {\n const { parentKey, item } = info;\n\n // 父级指向为空\n if (isNullish(parentKey)) {\n roots.push(item);\n }\n // 父级指向不为空\n else {\n const parent = keyMap.get(parentKey);\n\n // 未找到父级节点\n if (isUndefined(parent)) {\n // 游离节点\n if (isFirst) freeSet.add(info);\n }\n // 已找到父级节点\n else {\n options.appendChild(parent, info);\n }\n }\n };\n\n // 构建 map\n arrayEach(list, (item, index) => {\n const selfKey = options.getSelfKey(item, index);\n const parentKey = options.getParentKey(item, index);\n\n if (isNullish(selfKey)) return;\n\n const info = { selfKey, parentKey, item, index };\n keyMap.set(selfKey, info);\n\n assign(info, true);\n });\n\n // 处理游离节点\n for (const info of freeSet.values()) {\n assign(info);\n }\n\n return roots;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAgIA,SAAgB,SACd,UACA,UACA,cAAc,OACR;CACN,MAAM,eAA8B,EAAE;CACtC,IAAI,cAAc;CAElB,MAAM,WAAW,SAAsB;EACrC,IAAI,SAAS,KAAK,KAAK,OAAO;GAC5B,cAAc;GACd,OAAO;;;CAIX,MAAM,QAAQ,MAAmB,SAAsB;EACrD,MAAM,EAAE,MAAM,UAAU;EACxB,MAAM,EAAE,aAAa;EAErB,IAAI,aAAA,QAAQ,SAAS,EACnB,cACE,KAAK;GACH,GAAG;GACH,QAAQ;GACR,MAAM;GACN,OAAO,QAAQ;GAChB,CAAC,KAAK;;CAIb,MAAM,QAAqB,WAAW;EACpC,MAAM,EAAE,MAAM,QAAQ,SAAS;EAE/B,MAAM,QAAQ,CAAC,GAAG,KAAK;EACvB,OACE,WAAW,QACX,MAAM,SAAS,KACf,MAAM,MAAM,SAAS,OAAO,QAE5B,MAAM,KAAK;EAGb,cAAA,UAAU,OAAO,MAAM,UAAU;GAC/B,IAAI,aAAa,OAAO;GAExB,MAAM,OAAoB;IACxB,GAAG;IACH;IACA;IACA,MAAM,CAAC,GAAG,OAAO,KAAK;IACvB;GAGD,IAAI,aACF,aAAa,KAAK,KAAK;QAGpB;IACH,QAAQ,KAAK;IACb,IAAI,aAAa,OAAO;IACxB,KAAK,MAAM,KAAK;;IAElB;EAEF,IAAI,aACF,OAAO,CAAC,aAAa;GACnB,MAAM,OAAO,aAAa,OAAO;GACjC,IAAI,CAAC,MAAM;GAEX,QAAQ,KAAK;GACb,IAAI,aAAa;GAGjB,KAAK,MAAM,KAAK;;EAIpB,OAAO,CAAC;;CAGV,KAAK;EACH,MAAM;EACN,OAAO;EACP,QAAQ;EACR,MAAM,EAAE;EACT,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BJ,SAAgB,SACd,UACA,WACA,cAAc,OACW;CACzB,IAAI;CAEJ,SACE,WACC,SAAS;EACR,IAAI,UAAU,KAAK,EAAE;GACnB,QAAQ;GACR,OAAO;;IAGX,YACD;CAED,OAAO;;;;;;;;;;;;;;;;;;;;;;AAuBT,SAAgB,SACd,UACA,SACA,cAAc,OACT;CACL,MAAM,QAAa,EAAE;CAErB,SACE,WACC,SAAS;EACR,MAAM,KAAK,QAAQ,KAAK,CAAC;IAE3B,YACD;CAED,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDT,SAAgB,SACd,MACA,SACyB;CACzB,MAAM,yBAAS,IAAI,KAA+B;CAClD,MAAM,0BAAU,IAAI,KAAsB;CAC1C,MAAM,QAAqB,EAAE;CAG7B,MAAM,UAAU,MAAuB,UAAU,UAAU;EACzD,MAAM,EAAE,WAAW,SAAS;EAG5B,IAAI,aAAA,UAAU,UAAU,EACtB,MAAM,KAAK,KAAK;OAGb;GACH,MAAM,SAAS,OAAO,IAAI,UAAU;GAGpC,IAAI,aAAA,YAAY,OAAO;QAEjB,SAAS,QAAQ,IAAI,KAAK;UAI9B,QAAQ,YAAY,QAAQ,KAAK;;;CAMvC,cAAA,UAAU,OAAO,MAAM,UAAU;EAC/B,MAAM,UAAU,QAAQ,WAAW,MAAM,MAAM;EAC/C,MAAM,YAAY,QAAQ,aAAa,MAAM,MAAM;EAEnD,IAAI,aAAA,UAAU,QAAQ,EAAE;EAExB,MAAM,OAAO;GAAE;GAAS;GAAW;GAAM;GAAO;EAChD,OAAO,IAAI,SAAS,KAAK;EAEzB,OAAO,MAAM,KAAK;GAClB;CAGF,KAAK,MAAM,QAAQ,QAAQ,QAAQ,EACjC,OAAO,KAAK;CAGd,OAAO"}
|
|
1
|
+
{"version":3,"file":"tree.cjs","names":[],"sources":["../src/tree.ts"],"sourcesContent":["import { arrayEach } from './array';\nimport { isArray, isNullish, isUndefined } from './type';\nimport type { AnyObject } from './types';\n\n/**\n * 表示深度遍历中的节点对象,包含子节点列表。\n */\nexport type TreeItem = AnyObject & {\n /**\n * 子节点列表。\n */\n children?: TreeItem[];\n};\n\n/**\n * 表示深度遍历中的节点列表。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TreeList<I extends TreeItem> = I[];\n\n/**\n * 表示深度遍历中的遍历器状态。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TreeWalker<I extends TreeItem> = {\n /**\n * 当前层级的节点列表。\n */\n list: TreeList<I>;\n\n /**\n * 当前节点的父节点,如果为根节点则为 `null`。\n */\n parent: I | null;\n\n /**\n * 当前节点的层级,从 1 开始计数。\n */\n level: number;\n\n /**\n * 从根节点到当前节点的路径。\n */\n path: TreeList<I>;\n};\n\n/**\n * 表示深度遍历中的节点信息。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TreeInfo<I extends TreeItem> = TreeWalker<I> & {\n /**\n * 当前节点。\n */\n item: I;\n\n /**\n * 当前节点在 `list` 中的索引。\n */\n index: number;\n};\n\n/**\n * 深度遍历的同步迭代器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param info - 当前节点的信息。\n * @returns 如果返回 `false`,则提前终止遍历。\n */\nexport type TreeEachIterator<I extends TreeItem> = (info: TreeInfo<I>) => false | unknown;\n\n/**\n * 深度遍历的异步迭代器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param info - 当前节点的信息。\n * @returns 如果返回 `false`,则提前终止遍历。\n */\nexport type TreeEachIteratorAsync<I extends TreeItem> = (info: TreeInfo<I>) => Promise<boolean | unknown>;\n\n/**\n * 深度遍历的同步遍历器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param walker - 遍历器状态。\n * @returns 遍历结果。\n */\nexport type TreeWalk<I extends TreeItem> = (walker: TreeWalker<I>) => unknown;\n\n/**\n * 深度遍历的异步遍历器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param walker - 遍历器状态。\n * @returns 异步遍历结果。\n */\nexport type TreeWalkAsync<I extends TreeItem> = (walker: TreeWalker<I>) => Promise<unknown>;\n\n/**\n * 深度遍历数组中的每个元素,并对每个元素执行提供的回调函数。\n *\n * @param treeList - 要遍历的深度数组。\n * @param iterator - 对每个元素执行的回调函数。如果回调函数返回 `false`,则提前终止遍历。\n * @param breadthFist - 是否使用广度优先遍历,默认为 `false`(深度优先)。\n * @returns 无返回值。\n *\n * @example\n * ```typescript\n * const treeList = [\n * { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * { value: 4 }\n * ];\n *\n * treeEach(treeList, (item) => {\n * console.log(item.value);\n * if (item.value === 2) return false; // 提前终止遍历\n * });\n * ```\n */\nexport function treeEach<I extends TreeItem = TreeItem>(\n treeList: TreeList<I>,\n iterator: TreeEachIterator<I>,\n breadthFist = false,\n): void {\n const treeInfoList: TreeInfo<I>[] = [];\n let returnFalse = false;\n\n const iterate = (info: TreeInfo<I>) => {\n if (iterator(info) === false) {\n returnFalse = true;\n return false;\n }\n };\n\n const next = (info: TreeInfo<I>, walk: TreeWalk<I>) => {\n const { item, level } = info;\n const { children } = item;\n\n if (isArray(children)) {\n returnFalse =\n walk({\n ...info,\n parent: item,\n list: children as TreeList<I>,\n level: level + 1,\n }) === false;\n }\n };\n\n const walk: TreeWalk<I> = (walker) => {\n const { list, parent, path } = walker;\n\n const path2 = [...path];\n while (parent !== null && path2.length > 0 && path2[path2.length - 1] !== parent) {\n path2.pop();\n }\n\n arrayEach(list, (item, index) => {\n if (returnFalse) return false;\n\n const info: TreeInfo<I> = {\n ...walker,\n item,\n index,\n path: [...path2, item],\n };\n\n // 广度优先\n if (breadthFist) {\n treeInfoList.push(info);\n }\n // 深度优先\n else {\n iterate(info);\n if (returnFalse) return false;\n next(info, walk);\n }\n });\n\n if (breadthFist) {\n while (!returnFalse) {\n const info = treeInfoList.shift();\n if (!info) break;\n\n iterate(info);\n if (returnFalse) break;\n\n // 内部也会进入 walk\n next(info, walk);\n }\n }\n\n return !returnFalse;\n };\n\n walk({\n list: treeList,\n level: 1,\n parent: null,\n path: [],\n });\n}\n\n/**\n * 在深度数组中查找满足条件的第一个节点信息。\n *\n * @param treeList - 要查找的深度数组。\n * @param predicate - 判断节点是否满足条件的回调函数。\n * @param breadthFist - 是否使用广度优先查找,默认为 `false`(深度优先)。\n * @returns 如果找到满足条件的节点,则返回该节点的信息;否则返回 `undefined`。\n *\n * @example\n * ```typescript\n * const treeList = [\n * { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * { value: 4 }\n * ];\n *\n * const found = treeFind(treeList, (info) => info.item.value === 3);\n * console.log(found);\n * // {\n * // item: { value: 3 },\n * // index: 1,\n * // list: [{ value: 2 }, { value: 3 }],\n * // parent: { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * // level: 2,\n * // path: [{ value: 1, children: [{ value: 2 }, { value: 3 }] }, { value: 3 }]\n * // }\n * ```\n */\nexport function treeFind<I extends TreeItem>(\n treeList: TreeList<I>,\n predicate: (info: TreeInfo<I>) => boolean,\n breadthFist = false,\n): TreeInfo<I> | undefined {\n let found: TreeInfo<I> | undefined;\n\n treeEach(\n treeList,\n (info) => {\n if (predicate(info)) {\n found = info;\n return false;\n }\n },\n breadthFist,\n );\n\n return found;\n}\n\n/**\n * 将深度嵌套的树形结构扁平化为一维数组,并对每个节点执行指定的转换函数。\n *\n * @template I - 树节点的类型,必须继承自 `TreeItem`。\n * @template T - 转换后的数据类型。\n * @param {TreeList<I>} deepList - 要扁平化的深度嵌套树形结构。\n * @param {(info: TreeInfo<I>) => T} flatten - 对每个节点执行的转换函数,返回转换后的数据。\n * @param {boolean} [breadthFist=false] - 是否使用广度优先遍历,默认为 `false`(深度优先)。\n * @returns {T[]} - 转换后的一维数组。\n * @example\n * ```typescript\n * const treeList = [\n * { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * { value: 4 }\n * ];\n *\n * const flattened = deepFlat(treeList, (info) => info.item.value);\n * console.log(flattened); // [1, 2, 3, 4]\n * ```\n */\nexport function deepFlat<I extends TreeItem, T>(\n deepList: TreeList<I>,\n flatten: (info: TreeInfo<I>) => T,\n breadthFist = false,\n): T[] {\n const list2: T[] = [];\n\n treeEach(\n deepList,\n (info) => {\n list2.push(flatten(info));\n },\n breadthFist,\n );\n\n return list2;\n}\n\ntype FromItemInfo<I> = {\n selfKey: unknown;\n parentKey: unknown;\n item: I;\n index: number;\n};\n\nexport type TreeFromOptions<I extends TreeItem> = {\n getSelfKey: (item: I, index: number) => unknown;\n getParentKey: (item: I, index: number) => unknown;\n appendChild: (parentInfo: FromItemInfo<I>, info: FromItemInfo<I>) => unknown;\n};\n\n/**\n * 从扁平列表构建树形结构。\n *\n * @template I - 节点对象的类型,必须继承自 `AnyObject`。\n * @param {I[]} list - 扁平化的节点列表。\n * @param {TreeFromOptions<I>} options - 构建树形结构的配置选项。\n * @param {function} options.getSelfKey - 获取节点自身唯一标识的函数。\n * @param {function} options.getParentKey - 获取节点父节点唯一标识的函数。\n * @param {function} options.appendChild - 将子节点添加到父节点的函数。\n * @returns {I | undefined} - 构建的树形结构的根节点,如果未找到根节点则返回 `undefined`。\n *\n * @example\n * ```typescript\n * const list = [\n * { id: 1, parentId: null, name: 'Root' },\n * { id: 2, parentId: 1, name: 'Child 1' },\n * { id: 3, parentId: 1, name: 'Child 2' }\n * ];\n *\n * const tree = treeFrom(list, {\n * getSelfKey: (item) => item.id,\n * getParentKey: (item) => item.parentId,\n * appendChild: (parent, info) => {\n * if (!parent.children) parent.children = [];\n * parent.children.push(info.item);\n * }\n * });\n *\n * console.log(tree);\n * // {\n * // id: 1,\n * // parentId: null,\n * // name: 'Root',\n * // children: [\n * // { id: 2, parentId: 1, name: 'Child 1' },\n * // { id: 3, parentId: 1, name: 'Child 2' }\n * // ]\n * // }\n * ```\n */\nexport function treeFrom<I extends TreeItem>(list: I[], options: TreeFromOptions<I>): TreeList<I> | undefined {\n const keyMap = new Map<unknown, FromItemInfo<I>>();\n const freeSet = new Set<FromItemInfo<I>>();\n const roots: TreeList<I> = [];\n\n // 分配节点\n const assign = (info: FromItemInfo<I>, isFirst = false) => {\n const { parentKey, item } = info;\n\n // 父级指向为空\n if (isNullish(parentKey)) {\n roots.push(item);\n }\n // 父级指向不为空\n else {\n const parent = keyMap.get(parentKey);\n\n // 未找到父级节点\n if (isUndefined(parent)) {\n // 游离节点\n if (isFirst) freeSet.add(info);\n }\n // 已找到父级节点\n else {\n options.appendChild(parent, info);\n }\n }\n };\n\n // 构建 map\n arrayEach(list, (item, index) => {\n const selfKey = options.getSelfKey(item, index);\n const parentKey = options.getParentKey(item, index);\n\n if (isNullish(selfKey)) return;\n\n const info = { selfKey, parentKey, item, index };\n keyMap.set(selfKey, info);\n\n assign(info, true);\n });\n\n // 处理游离节点\n for (const info of freeSet.values()) {\n assign(info);\n }\n\n return roots;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA0HA,SAAgB,SACd,UACA,UACA,cAAc,OACR;CACN,MAAM,eAA8B,EAAE;CACtC,IAAI,cAAc;CAElB,MAAM,WAAW,SAAsB;EACrC,IAAI,SAAS,KAAK,KAAK,OAAO;GAC5B,cAAc;GACd,OAAO;;;CAIX,MAAM,QAAQ,MAAmB,SAAsB;EACrD,MAAM,EAAE,MAAM,UAAU;EACxB,MAAM,EAAE,aAAa;EAErB,IAAI,aAAA,QAAQ,SAAS,EACnB,cACE,KAAK;GACH,GAAG;GACH,QAAQ;GACR,MAAM;GACN,OAAO,QAAQ;GAChB,CAAC,KAAK;;CAIb,MAAM,QAAqB,WAAW;EACpC,MAAM,EAAE,MAAM,QAAQ,SAAS;EAE/B,MAAM,QAAQ,CAAC,GAAG,KAAK;EACvB,OAAO,WAAW,QAAQ,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,OAAO,QACxE,MAAM,KAAK;EAGb,cAAA,UAAU,OAAO,MAAM,UAAU;GAC/B,IAAI,aAAa,OAAO;GAExB,MAAM,OAAoB;IACxB,GAAG;IACH;IACA;IACA,MAAM,CAAC,GAAG,OAAO,KAAK;IACvB;GAGD,IAAI,aACF,aAAa,KAAK,KAAK;QAGpB;IACH,QAAQ,KAAK;IACb,IAAI,aAAa,OAAO;IACxB,KAAK,MAAM,KAAK;;IAElB;EAEF,IAAI,aACF,OAAO,CAAC,aAAa;GACnB,MAAM,OAAO,aAAa,OAAO;GACjC,IAAI,CAAC,MAAM;GAEX,QAAQ,KAAK;GACb,IAAI,aAAa;GAGjB,KAAK,MAAM,KAAK;;EAIpB,OAAO,CAAC;;CAGV,KAAK;EACH,MAAM;EACN,OAAO;EACP,QAAQ;EACR,MAAM,EAAE;EACT,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BJ,SAAgB,SACd,UACA,WACA,cAAc,OACW;CACzB,IAAI;CAEJ,SACE,WACC,SAAS;EACR,IAAI,UAAU,KAAK,EAAE;GACnB,QAAQ;GACR,OAAO;;IAGX,YACD;CAED,OAAO;;;;;;;;;;;;;;;;;;;;;;AAuBT,SAAgB,SACd,UACA,SACA,cAAc,OACT;CACL,MAAM,QAAa,EAAE;CAErB,SACE,WACC,SAAS;EACR,MAAM,KAAK,QAAQ,KAAK,CAAC;IAE3B,YACD;CAED,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDT,SAAgB,SAA6B,MAAW,SAAsD;CAC5G,MAAM,yBAAS,IAAI,KAA+B;CAClD,MAAM,0BAAU,IAAI,KAAsB;CAC1C,MAAM,QAAqB,EAAE;CAG7B,MAAM,UAAU,MAAuB,UAAU,UAAU;EACzD,MAAM,EAAE,WAAW,SAAS;EAG5B,IAAI,aAAA,UAAU,UAAU,EACtB,MAAM,KAAK,KAAK;OAGb;GACH,MAAM,SAAS,OAAO,IAAI,UAAU;GAGpC,IAAI,aAAA,YAAY,OAAO;QAEjB,SAAS,QAAQ,IAAI,KAAK;UAI9B,QAAQ,YAAY,QAAQ,KAAK;;;CAMvC,cAAA,UAAU,OAAO,MAAM,UAAU;EAC/B,MAAM,UAAU,QAAQ,WAAW,MAAM,MAAM;EAC/C,MAAM,YAAY,QAAQ,aAAa,MAAM,MAAM;EAEnD,IAAI,aAAA,UAAU,QAAQ,EAAE;EAExB,MAAM,OAAO;GAAE;GAAS;GAAW;GAAM;GAAO;EAChD,OAAO,IAAI,SAAS,KAAK;EAEzB,OAAO,MAAM,KAAK;GAClB;CAGF,KAAK,MAAM,QAAQ,QAAQ,QAAQ,EACjC,OAAO,KAAK;CAGd,OAAO"}
|
package/dist/tree.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree.mjs","names":[],"sources":["../src/tree.ts"],"sourcesContent":["import { arrayEach } from './array';\nimport { isArray, isNullish, isUndefined } from './type';\nimport type { AnyObject } from './types';\n\n/**\n * 表示深度遍历中的节点对象,包含子节点列表。\n */\nexport type TreeItem = AnyObject & {\n /**\n * 子节点列表。\n */\n children?: TreeItem[];\n};\n\n/**\n * 表示深度遍历中的节点列表。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TreeList<I extends TreeItem> = I[];\n\n/**\n * 表示深度遍历中的遍历器状态。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TreeWalker<I extends TreeItem> = {\n /**\n * 当前层级的节点列表。\n */\n list: TreeList<I>;\n\n /**\n * 当前节点的父节点,如果为根节点则为 `null`。\n */\n parent: I | null;\n\n /**\n * 当前节点的层级,从 1 开始计数。\n */\n level: number;\n\n /**\n * 从根节点到当前节点的路径。\n */\n path: TreeList<I>;\n};\n\n/**\n * 表示深度遍历中的节点信息。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TreeInfo<I extends TreeItem> = TreeWalker<I> & {\n /**\n * 当前节点。\n */\n item: I;\n\n /**\n * 当前节点在 `list` 中的索引。\n */\n index: number;\n};\n\n/**\n * 深度遍历的同步迭代器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param info - 当前节点的信息。\n * @returns 如果返回 `false`,则提前终止遍历。\n */\nexport type TreeEachIterator<I extends TreeItem> = (\n info: TreeInfo<I>,\n) => false | unknown;\n\n/**\n * 深度遍历的异步迭代器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param info - 当前节点的信息。\n * @returns 如果返回 `false`,则提前终止遍历。\n */\nexport type TreeEachIteratorAsync<I extends TreeItem> = (\n info: TreeInfo<I>,\n) => Promise<boolean | unknown>;\n\n/**\n * 深度遍历的同步遍历器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param walker - 遍历器状态。\n * @returns 遍历结果。\n */\nexport type TreeWalk<I extends TreeItem> = (walker: TreeWalker<I>) => unknown;\n\n/**\n * 深度遍历的异步遍历器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param walker - 遍历器状态。\n * @returns 异步遍历结果。\n */\nexport type TreeWalkAsync<I extends TreeItem> = (\n walker: TreeWalker<I>,\n) => Promise<unknown>;\n\n/**\n * 深度遍历数组中的每个元素,并对每个元素执行提供的回调函数。\n *\n * @param treeList - 要遍历的深度数组。\n * @param iterator - 对每个元素执行的回调函数。如果回调函数返回 `false`,则提前终止遍历。\n * @param breadthFist - 是否使用广度优先遍历,默认为 `false`(深度优先)。\n * @returns 无返回值。\n *\n * @example\n * ```typescript\n * const treeList = [\n * { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * { value: 4 }\n * ];\n *\n * treeEach(treeList, (item) => {\n * console.log(item.value);\n * if (item.value === 2) return false; // 提前终止遍历\n * });\n * ```\n */\nexport function treeEach<I extends TreeItem = TreeItem>(\n treeList: TreeList<I>,\n iterator: TreeEachIterator<I>,\n breadthFist = false,\n): void {\n const treeInfoList: TreeInfo<I>[] = [];\n let returnFalse = false;\n\n const iterate = (info: TreeInfo<I>) => {\n if (iterator(info) === false) {\n returnFalse = true;\n return false;\n }\n };\n\n const next = (info: TreeInfo<I>, walk: TreeWalk<I>) => {\n const { item, level } = info;\n const { children } = item;\n\n if (isArray(children)) {\n returnFalse =\n walk({\n ...info,\n parent: item,\n list: children as TreeList<I>,\n level: level + 1,\n }) === false;\n }\n };\n\n const walk: TreeWalk<I> = (walker) => {\n const { list, parent, path } = walker;\n\n const path2 = [...path];\n while (\n parent !== null &&\n path2.length > 0 &&\n path2[path2.length - 1] !== parent\n ) {\n path2.pop();\n }\n\n arrayEach(list, (item, index) => {\n if (returnFalse) return false;\n\n const info: TreeInfo<I> = {\n ...walker,\n item,\n index,\n path: [...path2, item],\n };\n\n // 广度优先\n if (breadthFist) {\n treeInfoList.push(info);\n }\n // 深度优先\n else {\n iterate(info);\n if (returnFalse) return false;\n next(info, walk);\n }\n });\n\n if (breadthFist) {\n while (!returnFalse) {\n const info = treeInfoList.shift();\n if (!info) break;\n\n iterate(info);\n if (returnFalse) break;\n\n // 内部也会进入 walk\n next(info, walk);\n }\n }\n\n return !returnFalse;\n };\n\n walk({\n list: treeList,\n level: 1,\n parent: null,\n path: [],\n });\n}\n\n/**\n * 在深度数组中查找满足条件的第一个节点信息。\n *\n * @param treeList - 要查找的深度数组。\n * @param predicate - 判断节点是否满足条件的回调函数。\n * @param breadthFist - 是否使用广度优先查找,默认为 `false`(深度优先)。\n * @returns 如果找到满足条件的节点,则返回该节点的信息;否则返回 `undefined`。\n *\n * @example\n * ```typescript\n * const treeList = [\n * { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * { value: 4 }\n * ];\n *\n * const found = treeFind(treeList, (info) => info.item.value === 3);\n * console.log(found);\n * // {\n * // item: { value: 3 },\n * // index: 1,\n * // list: [{ value: 2 }, { value: 3 }],\n * // parent: { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * // level: 2,\n * // path: [{ value: 1, children: [{ value: 2 }, { value: 3 }] }, { value: 3 }]\n * // }\n * ```\n */\nexport function treeFind<I extends TreeItem>(\n treeList: TreeList<I>,\n predicate: (info: TreeInfo<I>) => boolean,\n breadthFist = false,\n): TreeInfo<I> | undefined {\n let found: TreeInfo<I> | undefined;\n\n treeEach(\n treeList,\n (info) => {\n if (predicate(info)) {\n found = info;\n return false;\n }\n },\n breadthFist,\n );\n\n return found;\n}\n\n/**\n * 将深度嵌套的树形结构扁平化为一维数组,并对每个节点执行指定的转换函数。\n *\n * @template I - 树节点的类型,必须继承自 `TreeItem`。\n * @template T - 转换后的数据类型。\n * @param {TreeList<I>} deepList - 要扁平化的深度嵌套树形结构。\n * @param {(info: TreeInfo<I>) => T} flatten - 对每个节点执行的转换函数,返回转换后的数据。\n * @param {boolean} [breadthFist=false] - 是否使用广度优先遍历,默认为 `false`(深度优先)。\n * @returns {T[]} - 转换后的一维数组。\n * @example\n * ```typescript\n * const treeList = [\n * { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * { value: 4 }\n * ];\n *\n * const flattened = deepFlat(treeList, (info) => info.item.value);\n * console.log(flattened); // [1, 2, 3, 4]\n * ```\n */\nexport function deepFlat<I extends TreeItem, T>(\n deepList: TreeList<I>,\n flatten: (info: TreeInfo<I>) => T,\n breadthFist = false,\n): T[] {\n const list2: T[] = [];\n\n treeEach(\n deepList,\n (info) => {\n list2.push(flatten(info));\n },\n breadthFist,\n );\n\n return list2;\n}\n\ntype FromItemInfo<I> = {\n selfKey: unknown;\n parentKey: unknown;\n item: I;\n index: number;\n};\n\nexport type TreeFromOptions<I extends TreeItem> = {\n getSelfKey: (item: I, index: number) => unknown;\n getParentKey: (item: I, index: number) => unknown;\n appendChild: (parentInfo: FromItemInfo<I>, info: FromItemInfo<I>) => unknown;\n};\n\n/**\n * 从扁平列表构建树形结构。\n *\n * @template I - 节点对象的类型,必须继承自 `AnyObject`。\n * @param {I[]} list - 扁平化的节点列表。\n * @param {TreeFromOptions<I>} options - 构建树形结构的配置选项。\n * @param {function} options.getSelfKey - 获取节点自身唯一标识的函数。\n * @param {function} options.getParentKey - 获取节点父节点唯一标识的函数。\n * @param {function} options.appendChild - 将子节点添加到父节点的函数。\n * @returns {I | undefined} - 构建的树形结构的根节点,如果未找到根节点则返回 `undefined`。\n *\n * @example\n * ```typescript\n * const list = [\n * { id: 1, parentId: null, name: 'Root' },\n * { id: 2, parentId: 1, name: 'Child 1' },\n * { id: 3, parentId: 1, name: 'Child 2' }\n * ];\n *\n * const tree = treeFrom(list, {\n * getSelfKey: (item) => item.id,\n * getParentKey: (item) => item.parentId,\n * appendChild: (parent, info) => {\n * if (!parent.children) parent.children = [];\n * parent.children.push(info.item);\n * }\n * });\n *\n * console.log(tree);\n * // {\n * // id: 1,\n * // parentId: null,\n * // name: 'Root',\n * // children: [\n * // { id: 2, parentId: 1, name: 'Child 1' },\n * // { id: 3, parentId: 1, name: 'Child 2' }\n * // ]\n * // }\n * ```\n */\nexport function treeFrom<I extends TreeItem>(\n list: I[],\n options: TreeFromOptions<I>,\n): TreeList<I> | undefined {\n const keyMap = new Map<unknown, FromItemInfo<I>>();\n const freeSet = new Set<FromItemInfo<I>>();\n const roots: TreeList<I> = [];\n\n // 分配节点\n const assign = (info: FromItemInfo<I>, isFirst = false) => {\n const { parentKey, item } = info;\n\n // 父级指向为空\n if (isNullish(parentKey)) {\n roots.push(item);\n }\n // 父级指向不为空\n else {\n const parent = keyMap.get(parentKey);\n\n // 未找到父级节点\n if (isUndefined(parent)) {\n // 游离节点\n if (isFirst) freeSet.add(info);\n }\n // 已找到父级节点\n else {\n options.appendChild(parent, info);\n }\n }\n };\n\n // 构建 map\n arrayEach(list, (item, index) => {\n const selfKey = options.getSelfKey(item, index);\n const parentKey = options.getParentKey(item, index);\n\n if (isNullish(selfKey)) return;\n\n const info = { selfKey, parentKey, item, index };\n keyMap.set(selfKey, info);\n\n assign(info, true);\n });\n\n // 处理游离节点\n for (const info of freeSet.values()) {\n assign(info);\n }\n\n return roots;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAgIA,SAAgB,SACd,UACA,UACA,cAAc,OACR;CACN,MAAM,eAA8B,EAAE;CACtC,IAAI,cAAc;CAElB,MAAM,WAAW,SAAsB;EACrC,IAAI,SAAS,KAAK,KAAK,OAAO;GAC5B,cAAc;GACd,OAAO;;;CAIX,MAAM,QAAQ,MAAmB,SAAsB;EACrD,MAAM,EAAE,MAAM,UAAU;EACxB,MAAM,EAAE,aAAa;EAErB,IAAI,QAAQ,SAAS,EACnB,cACE,KAAK;GACH,GAAG;GACH,QAAQ;GACR,MAAM;GACN,OAAO,QAAQ;GAChB,CAAC,KAAK;;CAIb,MAAM,QAAqB,WAAW;EACpC,MAAM,EAAE,MAAM,QAAQ,SAAS;EAE/B,MAAM,QAAQ,CAAC,GAAG,KAAK;EACvB,OACE,WAAW,QACX,MAAM,SAAS,KACf,MAAM,MAAM,SAAS,OAAO,QAE5B,MAAM,KAAK;EAGb,UAAU,OAAO,MAAM,UAAU;GAC/B,IAAI,aAAa,OAAO;GAExB,MAAM,OAAoB;IACxB,GAAG;IACH;IACA;IACA,MAAM,CAAC,GAAG,OAAO,KAAK;IACvB;GAGD,IAAI,aACF,aAAa,KAAK,KAAK;QAGpB;IACH,QAAQ,KAAK;IACb,IAAI,aAAa,OAAO;IACxB,KAAK,MAAM,KAAK;;IAElB;EAEF,IAAI,aACF,OAAO,CAAC,aAAa;GACnB,MAAM,OAAO,aAAa,OAAO;GACjC,IAAI,CAAC,MAAM;GAEX,QAAQ,KAAK;GACb,IAAI,aAAa;GAGjB,KAAK,MAAM,KAAK;;EAIpB,OAAO,CAAC;;CAGV,KAAK;EACH,MAAM;EACN,OAAO;EACP,QAAQ;EACR,MAAM,EAAE;EACT,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BJ,SAAgB,SACd,UACA,WACA,cAAc,OACW;CACzB,IAAI;CAEJ,SACE,WACC,SAAS;EACR,IAAI,UAAU,KAAK,EAAE;GACnB,QAAQ;GACR,OAAO;;IAGX,YACD;CAED,OAAO;;;;;;;;;;;;;;;;;;;;;;AAuBT,SAAgB,SACd,UACA,SACA,cAAc,OACT;CACL,MAAM,QAAa,EAAE;CAErB,SACE,WACC,SAAS;EACR,MAAM,KAAK,QAAQ,KAAK,CAAC;IAE3B,YACD;CAED,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDT,SAAgB,SACd,MACA,SACyB;CACzB,MAAM,yBAAS,IAAI,KAA+B;CAClD,MAAM,0BAAU,IAAI,KAAsB;CAC1C,MAAM,QAAqB,EAAE;CAG7B,MAAM,UAAU,MAAuB,UAAU,UAAU;EACzD,MAAM,EAAE,WAAW,SAAS;EAG5B,IAAI,UAAU,UAAU,EACtB,MAAM,KAAK,KAAK;OAGb;GACH,MAAM,SAAS,OAAO,IAAI,UAAU;GAGpC,IAAI,YAAY,OAAO;QAEjB,SAAS,QAAQ,IAAI,KAAK;UAI9B,QAAQ,YAAY,QAAQ,KAAK;;;CAMvC,UAAU,OAAO,MAAM,UAAU;EAC/B,MAAM,UAAU,QAAQ,WAAW,MAAM,MAAM;EAC/C,MAAM,YAAY,QAAQ,aAAa,MAAM,MAAM;EAEnD,IAAI,UAAU,QAAQ,EAAE;EAExB,MAAM,OAAO;GAAE;GAAS;GAAW;GAAM;GAAO;EAChD,OAAO,IAAI,SAAS,KAAK;EAEzB,OAAO,MAAM,KAAK;GAClB;CAGF,KAAK,MAAM,QAAQ,QAAQ,QAAQ,EACjC,OAAO,KAAK;CAGd,OAAO"}
|
|
1
|
+
{"version":3,"file":"tree.mjs","names":[],"sources":["../src/tree.ts"],"sourcesContent":["import { arrayEach } from './array';\nimport { isArray, isNullish, isUndefined } from './type';\nimport type { AnyObject } from './types';\n\n/**\n * 表示深度遍历中的节点对象,包含子节点列表。\n */\nexport type TreeItem = AnyObject & {\n /**\n * 子节点列表。\n */\n children?: TreeItem[];\n};\n\n/**\n * 表示深度遍历中的节点列表。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TreeList<I extends TreeItem> = I[];\n\n/**\n * 表示深度遍历中的遍历器状态。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TreeWalker<I extends TreeItem> = {\n /**\n * 当前层级的节点列表。\n */\n list: TreeList<I>;\n\n /**\n * 当前节点的父节点,如果为根节点则为 `null`。\n */\n parent: I | null;\n\n /**\n * 当前节点的层级,从 1 开始计数。\n */\n level: number;\n\n /**\n * 从根节点到当前节点的路径。\n */\n path: TreeList<I>;\n};\n\n/**\n * 表示深度遍历中的节点信息。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TreeInfo<I extends TreeItem> = TreeWalker<I> & {\n /**\n * 当前节点。\n */\n item: I;\n\n /**\n * 当前节点在 `list` 中的索引。\n */\n index: number;\n};\n\n/**\n * 深度遍历的同步迭代器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param info - 当前节点的信息。\n * @returns 如果返回 `false`,则提前终止遍历。\n */\nexport type TreeEachIterator<I extends TreeItem> = (info: TreeInfo<I>) => false | unknown;\n\n/**\n * 深度遍历的异步迭代器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param info - 当前节点的信息。\n * @returns 如果返回 `false`,则提前终止遍历。\n */\nexport type TreeEachIteratorAsync<I extends TreeItem> = (info: TreeInfo<I>) => Promise<boolean | unknown>;\n\n/**\n * 深度遍历的同步遍历器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param walker - 遍历器状态。\n * @returns 遍历结果。\n */\nexport type TreeWalk<I extends TreeItem> = (walker: TreeWalker<I>) => unknown;\n\n/**\n * 深度遍历的异步遍历器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param walker - 遍历器状态。\n * @returns 异步遍历结果。\n */\nexport type TreeWalkAsync<I extends TreeItem> = (walker: TreeWalker<I>) => Promise<unknown>;\n\n/**\n * 深度遍历数组中的每个元素,并对每个元素执行提供的回调函数。\n *\n * @param treeList - 要遍历的深度数组。\n * @param iterator - 对每个元素执行的回调函数。如果回调函数返回 `false`,则提前终止遍历。\n * @param breadthFist - 是否使用广度优先遍历,默认为 `false`(深度优先)。\n * @returns 无返回值。\n *\n * @example\n * ```typescript\n * const treeList = [\n * { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * { value: 4 }\n * ];\n *\n * treeEach(treeList, (item) => {\n * console.log(item.value);\n * if (item.value === 2) return false; // 提前终止遍历\n * });\n * ```\n */\nexport function treeEach<I extends TreeItem = TreeItem>(\n treeList: TreeList<I>,\n iterator: TreeEachIterator<I>,\n breadthFist = false,\n): void {\n const treeInfoList: TreeInfo<I>[] = [];\n let returnFalse = false;\n\n const iterate = (info: TreeInfo<I>) => {\n if (iterator(info) === false) {\n returnFalse = true;\n return false;\n }\n };\n\n const next = (info: TreeInfo<I>, walk: TreeWalk<I>) => {\n const { item, level } = info;\n const { children } = item;\n\n if (isArray(children)) {\n returnFalse =\n walk({\n ...info,\n parent: item,\n list: children as TreeList<I>,\n level: level + 1,\n }) === false;\n }\n };\n\n const walk: TreeWalk<I> = (walker) => {\n const { list, parent, path } = walker;\n\n const path2 = [...path];\n while (parent !== null && path2.length > 0 && path2[path2.length - 1] !== parent) {\n path2.pop();\n }\n\n arrayEach(list, (item, index) => {\n if (returnFalse) return false;\n\n const info: TreeInfo<I> = {\n ...walker,\n item,\n index,\n path: [...path2, item],\n };\n\n // 广度优先\n if (breadthFist) {\n treeInfoList.push(info);\n }\n // 深度优先\n else {\n iterate(info);\n if (returnFalse) return false;\n next(info, walk);\n }\n });\n\n if (breadthFist) {\n while (!returnFalse) {\n const info = treeInfoList.shift();\n if (!info) break;\n\n iterate(info);\n if (returnFalse) break;\n\n // 内部也会进入 walk\n next(info, walk);\n }\n }\n\n return !returnFalse;\n };\n\n walk({\n list: treeList,\n level: 1,\n parent: null,\n path: [],\n });\n}\n\n/**\n * 在深度数组中查找满足条件的第一个节点信息。\n *\n * @param treeList - 要查找的深度数组。\n * @param predicate - 判断节点是否满足条件的回调函数。\n * @param breadthFist - 是否使用广度优先查找,默认为 `false`(深度优先)。\n * @returns 如果找到满足条件的节点,则返回该节点的信息;否则返回 `undefined`。\n *\n * @example\n * ```typescript\n * const treeList = [\n * { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * { value: 4 }\n * ];\n *\n * const found = treeFind(treeList, (info) => info.item.value === 3);\n * console.log(found);\n * // {\n * // item: { value: 3 },\n * // index: 1,\n * // list: [{ value: 2 }, { value: 3 }],\n * // parent: { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * // level: 2,\n * // path: [{ value: 1, children: [{ value: 2 }, { value: 3 }] }, { value: 3 }]\n * // }\n * ```\n */\nexport function treeFind<I extends TreeItem>(\n treeList: TreeList<I>,\n predicate: (info: TreeInfo<I>) => boolean,\n breadthFist = false,\n): TreeInfo<I> | undefined {\n let found: TreeInfo<I> | undefined;\n\n treeEach(\n treeList,\n (info) => {\n if (predicate(info)) {\n found = info;\n return false;\n }\n },\n breadthFist,\n );\n\n return found;\n}\n\n/**\n * 将深度嵌套的树形结构扁平化为一维数组,并对每个节点执行指定的转换函数。\n *\n * @template I - 树节点的类型,必须继承自 `TreeItem`。\n * @template T - 转换后的数据类型。\n * @param {TreeList<I>} deepList - 要扁平化的深度嵌套树形结构。\n * @param {(info: TreeInfo<I>) => T} flatten - 对每个节点执行的转换函数,返回转换后的数据。\n * @param {boolean} [breadthFist=false] - 是否使用广度优先遍历,默认为 `false`(深度优先)。\n * @returns {T[]} - 转换后的一维数组。\n * @example\n * ```typescript\n * const treeList = [\n * { value: 1, children: [{ value: 2 }, { value: 3 }] },\n * { value: 4 }\n * ];\n *\n * const flattened = deepFlat(treeList, (info) => info.item.value);\n * console.log(flattened); // [1, 2, 3, 4]\n * ```\n */\nexport function deepFlat<I extends TreeItem, T>(\n deepList: TreeList<I>,\n flatten: (info: TreeInfo<I>) => T,\n breadthFist = false,\n): T[] {\n const list2: T[] = [];\n\n treeEach(\n deepList,\n (info) => {\n list2.push(flatten(info));\n },\n breadthFist,\n );\n\n return list2;\n}\n\ntype FromItemInfo<I> = {\n selfKey: unknown;\n parentKey: unknown;\n item: I;\n index: number;\n};\n\nexport type TreeFromOptions<I extends TreeItem> = {\n getSelfKey: (item: I, index: number) => unknown;\n getParentKey: (item: I, index: number) => unknown;\n appendChild: (parentInfo: FromItemInfo<I>, info: FromItemInfo<I>) => unknown;\n};\n\n/**\n * 从扁平列表构建树形结构。\n *\n * @template I - 节点对象的类型,必须继承自 `AnyObject`。\n * @param {I[]} list - 扁平化的节点列表。\n * @param {TreeFromOptions<I>} options - 构建树形结构的配置选项。\n * @param {function} options.getSelfKey - 获取节点自身唯一标识的函数。\n * @param {function} options.getParentKey - 获取节点父节点唯一标识的函数。\n * @param {function} options.appendChild - 将子节点添加到父节点的函数。\n * @returns {I | undefined} - 构建的树形结构的根节点,如果未找到根节点则返回 `undefined`。\n *\n * @example\n * ```typescript\n * const list = [\n * { id: 1, parentId: null, name: 'Root' },\n * { id: 2, parentId: 1, name: 'Child 1' },\n * { id: 3, parentId: 1, name: 'Child 2' }\n * ];\n *\n * const tree = treeFrom(list, {\n * getSelfKey: (item) => item.id,\n * getParentKey: (item) => item.parentId,\n * appendChild: (parent, info) => {\n * if (!parent.children) parent.children = [];\n * parent.children.push(info.item);\n * }\n * });\n *\n * console.log(tree);\n * // {\n * // id: 1,\n * // parentId: null,\n * // name: 'Root',\n * // children: [\n * // { id: 2, parentId: 1, name: 'Child 1' },\n * // { id: 3, parentId: 1, name: 'Child 2' }\n * // ]\n * // }\n * ```\n */\nexport function treeFrom<I extends TreeItem>(list: I[], options: TreeFromOptions<I>): TreeList<I> | undefined {\n const keyMap = new Map<unknown, FromItemInfo<I>>();\n const freeSet = new Set<FromItemInfo<I>>();\n const roots: TreeList<I> = [];\n\n // 分配节点\n const assign = (info: FromItemInfo<I>, isFirst = false) => {\n const { parentKey, item } = info;\n\n // 父级指向为空\n if (isNullish(parentKey)) {\n roots.push(item);\n }\n // 父级指向不为空\n else {\n const parent = keyMap.get(parentKey);\n\n // 未找到父级节点\n if (isUndefined(parent)) {\n // 游离节点\n if (isFirst) freeSet.add(info);\n }\n // 已找到父级节点\n else {\n options.appendChild(parent, info);\n }\n }\n };\n\n // 构建 map\n arrayEach(list, (item, index) => {\n const selfKey = options.getSelfKey(item, index);\n const parentKey = options.getParentKey(item, index);\n\n if (isNullish(selfKey)) return;\n\n const info = { selfKey, parentKey, item, index };\n keyMap.set(selfKey, info);\n\n assign(info, true);\n });\n\n // 处理游离节点\n for (const info of freeSet.values()) {\n assign(info);\n }\n\n return roots;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA0HA,SAAgB,SACd,UACA,UACA,cAAc,OACR;CACN,MAAM,eAA8B,EAAE;CACtC,IAAI,cAAc;CAElB,MAAM,WAAW,SAAsB;EACrC,IAAI,SAAS,KAAK,KAAK,OAAO;GAC5B,cAAc;GACd,OAAO;;;CAIX,MAAM,QAAQ,MAAmB,SAAsB;EACrD,MAAM,EAAE,MAAM,UAAU;EACxB,MAAM,EAAE,aAAa;EAErB,IAAI,QAAQ,SAAS,EACnB,cACE,KAAK;GACH,GAAG;GACH,QAAQ;GACR,MAAM;GACN,OAAO,QAAQ;GAChB,CAAC,KAAK;;CAIb,MAAM,QAAqB,WAAW;EACpC,MAAM,EAAE,MAAM,QAAQ,SAAS;EAE/B,MAAM,QAAQ,CAAC,GAAG,KAAK;EACvB,OAAO,WAAW,QAAQ,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,OAAO,QACxE,MAAM,KAAK;EAGb,UAAU,OAAO,MAAM,UAAU;GAC/B,IAAI,aAAa,OAAO;GAExB,MAAM,OAAoB;IACxB,GAAG;IACH;IACA;IACA,MAAM,CAAC,GAAG,OAAO,KAAK;IACvB;GAGD,IAAI,aACF,aAAa,KAAK,KAAK;QAGpB;IACH,QAAQ,KAAK;IACb,IAAI,aAAa,OAAO;IACxB,KAAK,MAAM,KAAK;;IAElB;EAEF,IAAI,aACF,OAAO,CAAC,aAAa;GACnB,MAAM,OAAO,aAAa,OAAO;GACjC,IAAI,CAAC,MAAM;GAEX,QAAQ,KAAK;GACb,IAAI,aAAa;GAGjB,KAAK,MAAM,KAAK;;EAIpB,OAAO,CAAC;;CAGV,KAAK;EACH,MAAM;EACN,OAAO;EACP,QAAQ;EACR,MAAM,EAAE;EACT,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BJ,SAAgB,SACd,UACA,WACA,cAAc,OACW;CACzB,IAAI;CAEJ,SACE,WACC,SAAS;EACR,IAAI,UAAU,KAAK,EAAE;GACnB,QAAQ;GACR,OAAO;;IAGX,YACD;CAED,OAAO;;;;;;;;;;;;;;;;;;;;;;AAuBT,SAAgB,SACd,UACA,SACA,cAAc,OACT;CACL,MAAM,QAAa,EAAE;CAErB,SACE,WACC,SAAS;EACR,MAAM,KAAK,QAAQ,KAAK,CAAC;IAE3B,YACD;CAED,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDT,SAAgB,SAA6B,MAAW,SAAsD;CAC5G,MAAM,yBAAS,IAAI,KAA+B;CAClD,MAAM,0BAAU,IAAI,KAAsB;CAC1C,MAAM,QAAqB,EAAE;CAG7B,MAAM,UAAU,MAAuB,UAAU,UAAU;EACzD,MAAM,EAAE,WAAW,SAAS;EAG5B,IAAI,UAAU,UAAU,EACtB,MAAM,KAAK,KAAK;OAGb;GACH,MAAM,SAAS,OAAO,IAAI,UAAU;GAGpC,IAAI,YAAY,OAAO;QAEjB,SAAS,QAAQ,IAAI,KAAK;UAI9B,QAAQ,YAAY,QAAQ,KAAK;;;CAMvC,UAAU,OAAO,MAAM,UAAU;EAC/B,MAAM,UAAU,QAAQ,WAAW,MAAM,MAAM;EAC/C,MAAM,YAAY,QAAQ,aAAa,MAAM,MAAM;EAEnD,IAAI,UAAU,QAAQ,EAAE;EAExB,MAAM,OAAO;GAAE;GAAS;GAAW;GAAM;GAAO;EAChD,OAAO,IAAI,SAAS,KAAK;EAEzB,OAAO,MAAM,KAAK;GAClB;CAGF,KAAK,MAAM,QAAQ,QAAQ,QAAQ,EACjC,OAAO,KAAK;CAGd,OAAO"}
|
package/dist/try.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"try.cjs","names":[],"sources":["../src/try/curry.ts","../src/try/callback.ts","../src/try/function.ts","../src/try/promise.ts","../src/try/main.ts"],"sourcesContent":["export type Callback<T = void> = (
|
|
1
|
+
{"version":3,"file":"try.cjs","names":[],"sources":["../src/try/curry.ts","../src/try/callback.ts","../src/try/function.ts","../src/try/promise.ts","../src/try/main.ts"],"sourcesContent":["export type Callback<T = void> = (err: null | undefined | undefined | Error, res: T) => unknown;\n\nexport type CallbackFunction0<T = void> = (callback: Callback<T>) => unknown;\nexport type CallbackFunction1<A, T = void> = (a: A, callback: Callback<T>) => unknown;\nexport type CallbackFunction2<A, B, T = void> = (a: A, b: B, callback: Callback<T>) => unknown;\nexport type CallbackFunction3<A, B, C, T = void> = (a: A, b: B, c: C, callback: Callback<T>) => unknown;\nexport type CallbackFunction4<A, B, C, D, T = void> = (a: A, b: B, c: C, d: D, callback: Callback<T>) => unknown;\nexport type CallbackFunction5<A, B, C, D, E, T = void> = (\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n callback: Callback<T>,\n) => unknown;\nexport type CallbackFunction6<A, B, C, D, E, F, T = void> = (\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n f: F,\n callback: Callback<T>,\n) => unknown;\n\nexport type CallbackCurried<T> = (callback: Callback<T>) => unknown;\n\nexport function callbackCurry<T = void>(cf: CallbackFunction0<T>): CallbackCurried<T>;\nexport function callbackCurry<A, T = void>(cf: CallbackFunction1<A, T>, a: A): CallbackCurried<T>;\nexport function callbackCurry<A, B, T = void>(cf: CallbackFunction2<A, B, T>, a: A, b: B): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, T = void>(\n cf: CallbackFunction3<A, B, C, T>,\n a: A,\n b: B,\n c: C,\n): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, D, T = void>(\n cf: CallbackFunction4<A, B, C, D, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, D, E, T = void>(\n cf: CallbackFunction5<A, B, C, D, E, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, D, E, F, T = void>(\n cf: CallbackFunction6<A, B, C, D, E, F, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n f: F,\n): CallbackCurried<T>;\nexport function callbackCurry(cf: unknown, ...args: unknown[]): CallbackCurried<unknown> {\n return function callbackCurried(callback: Callback<unknown>) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n cf.apply(this, [...args, callback]);\n };\n}\n","import { errorNormalize } from '@/error';\nimport type {\n CallbackFunction0,\n CallbackFunction1,\n CallbackFunction2,\n CallbackFunction3,\n CallbackFunction4,\n CallbackFunction5,\n CallbackFunction6,\n} from './curry';\nimport { callbackCurry } from './curry';\nimport type { FlattenReturn } from './types';\n\nexport function tryCallback(cf: CallbackFunction0): Promise<FlattenReturn>;\nexport function tryCallback<T = void>(cf: CallbackFunction0<T>): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, T = void>(cf: CallbackFunction1<A, T>, a: A): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, T = void>(cf: CallbackFunction2<A, B, T>, a: A, b: B): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, T = void>(\n cf: CallbackFunction3<A, B, C, T>,\n a: A,\n b: B,\n c: C,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, D, T = void>(\n cf: CallbackFunction4<A, B, C, D>,\n a: A,\n b: B,\n c: C,\n d: D,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, D, E, T = void>(\n cf: CallbackFunction5<A, B, C, D, E, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, D, E, F, T = void>(\n cf: CallbackFunction6<A, B, C, D, E, F, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n f: F,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback(cf: unknown, ...args: unknown[]): Promise<FlattenReturn<unknown>> {\n return new Promise((resolve) => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n callbackCurry.apply(this, [cf, ...args])((err, res) => {\n if (err) {\n resolve([errorNormalize(err), undefined] as const);\n } else {\n resolve([undefined, res] as const);\n }\n });\n });\n}\n","import { errorNormalize } from '@/error';\nimport type { FlattenReturn } from './types';\n\nexport type SyncFunction<T> = () => T;\n\nexport function trySync<T>(syncFn: SyncFunction<T>): FlattenReturn<T> {\n try {\n return [undefined, syncFn()] as const;\n } catch (err) {\n return [errorNormalize(err), undefined] as const;\n }\n}\n\nexport type AsyncFunction<T> = () => Promise<T>;\n\nexport function tryAsync<T>(asyncFn: AsyncFunction<T>): Promise<FlattenReturn<T>> {\n return asyncFn().then(\n (res) => [undefined, res] as const,\n (err) => [errorNormalize(err), undefined] as const,\n );\n}\n","import { errorNormalize } from '@/error';\nimport type { FlattenReturn } from './types';\n\nexport function tryPromise<T>(promise: PromiseLike<T>): PromiseLike<FlattenReturn<T>> {\n return promise.then(\n (res) => [undefined, res] as const,\n (err) => [errorNormalize(err), undefined] as const,\n );\n}\n","import { isAsyncFunction } from '@/type';\nimport { tryCallback } from './callback';\nimport type { CallbackFunction0 } from './curry';\nimport { type AsyncFunction, type SyncFunction, tryAsync, trySync } from './function';\nimport { tryPromise } from './promise';\nimport type { FlattenReturn } from './types';\n\nexport type FlattenAble<T> = SyncFunction<T> | AsyncFunction<T> | CallbackFunction0<T> | PromiseLike<T>;\n\n// 注意顺序 AsyncFunction > SyncFunction > CallbackFunction0 > PromiseLike\n// 需要先匹配 AsyncFunction,否则会把入参当做同步函数\nexport function tryFlatten<T>(flattenAble: AsyncFunction<T>): Promise<FlattenReturn<T>>;\nexport function tryFlatten<T>(flattenAble: SyncFunction<T>): FlattenReturn<T>;\nexport function tryFlatten<T>(flattenAble: CallbackFunction0<T> | PromiseLike<T>): Promise<FlattenReturn<T>>;\nexport function tryFlatten<T>(flattenAble: FlattenAble<T>): unknown {\n if ('then' in flattenAble) {\n return tryPromise<T>(flattenAble);\n }\n\n // SyncFunction | AsyncFunction\n if (flattenAble.length === 0) {\n if (isAsyncFunction(flattenAble)) return tryAsync<T>(flattenAble as AsyncFunction<T>);\n return trySync<T>(flattenAble as SyncFunction<T>);\n }\n\n return tryCallback<T>(flattenAble);\n}\n"],"mappings":";;;;AA4DA,SAAgB,cAAc,IAAa,GAAG,MAA2C;CACvF,OAAO,SAAS,gBAAgB,UAA6B;EAG3D,GAAG,MAAM,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC;;;;;ACjBvC,SAAgB,YAAY,IAAa,GAAG,MAAkD;CAC5F,OAAO,IAAI,SAAS,YAAY;EAG9B,cAAc,MAAM,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,EAAE,KAAK,QAAQ;GACrD,IAAI,KACF,QAAQ,CAAC,cAAA,eAAe,IAAI,EAAE,KAAA,EAAU,CAAU;QAElD,QAAQ,CAAC,KAAA,GAAW,IAAI,CAAU;IAEpC;GACF;;;;ACrDJ,SAAgB,QAAW,QAA2C;CACpE,IAAI;EACF,OAAO,CAAC,KAAA,GAAW,QAAQ,CAAC;UACrB,KAAK;EACZ,OAAO,CAAC,cAAA,eAAe,IAAI,EAAE,KAAA,EAAU;;;AAM3C,SAAgB,SAAY,SAAsD;CAChF,OAAO,SAAS,CAAC,MACd,QAAQ,CAAC,KAAA,GAAW,IAAI,GACxB,QAAQ,CAAC,cAAA,eAAe,IAAI,EAAE,KAAA,EAAU,CAC1C;;;;AChBH,SAAgB,WAAc,SAAwD;CACpF,OAAO,QAAQ,MACZ,QAAQ,CAAC,KAAA,GAAW,IAAI,GACxB,QAAQ,CAAC,cAAA,eAAe,IAAI,EAAE,KAAA,EAAU,CAC1C;;;;ACOH,SAAgB,WAAc,aAAsC;CAClE,IAAI,UAAU,aACZ,OAAO,WAAc,YAAY;CAInC,IAAI,YAAY,WAAW,GAAG;EAC5B,IAAI,aAAA,gBAAgB,YAAY,EAAE,OAAO,SAAY,YAAgC;EACrF,OAAO,QAAW,YAA+B;;CAGnD,OAAO,YAAe,YAAY"}
|
package/dist/try.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"try.mjs","names":[],"sources":["../src/try/curry.ts","../src/try/callback.ts","../src/try/function.ts","../src/try/promise.ts","../src/try/main.ts"],"sourcesContent":["export type Callback<T = void> = (
|
|
1
|
+
{"version":3,"file":"try.mjs","names":[],"sources":["../src/try/curry.ts","../src/try/callback.ts","../src/try/function.ts","../src/try/promise.ts","../src/try/main.ts"],"sourcesContent":["export type Callback<T = void> = (err: null | undefined | undefined | Error, res: T) => unknown;\n\nexport type CallbackFunction0<T = void> = (callback: Callback<T>) => unknown;\nexport type CallbackFunction1<A, T = void> = (a: A, callback: Callback<T>) => unknown;\nexport type CallbackFunction2<A, B, T = void> = (a: A, b: B, callback: Callback<T>) => unknown;\nexport type CallbackFunction3<A, B, C, T = void> = (a: A, b: B, c: C, callback: Callback<T>) => unknown;\nexport type CallbackFunction4<A, B, C, D, T = void> = (a: A, b: B, c: C, d: D, callback: Callback<T>) => unknown;\nexport type CallbackFunction5<A, B, C, D, E, T = void> = (\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n callback: Callback<T>,\n) => unknown;\nexport type CallbackFunction6<A, B, C, D, E, F, T = void> = (\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n f: F,\n callback: Callback<T>,\n) => unknown;\n\nexport type CallbackCurried<T> = (callback: Callback<T>) => unknown;\n\nexport function callbackCurry<T = void>(cf: CallbackFunction0<T>): CallbackCurried<T>;\nexport function callbackCurry<A, T = void>(cf: CallbackFunction1<A, T>, a: A): CallbackCurried<T>;\nexport function callbackCurry<A, B, T = void>(cf: CallbackFunction2<A, B, T>, a: A, b: B): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, T = void>(\n cf: CallbackFunction3<A, B, C, T>,\n a: A,\n b: B,\n c: C,\n): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, D, T = void>(\n cf: CallbackFunction4<A, B, C, D, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, D, E, T = void>(\n cf: CallbackFunction5<A, B, C, D, E, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n): CallbackCurried<T>;\nexport function callbackCurry<A, B, C, D, E, F, T = void>(\n cf: CallbackFunction6<A, B, C, D, E, F, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n f: F,\n): CallbackCurried<T>;\nexport function callbackCurry(cf: unknown, ...args: unknown[]): CallbackCurried<unknown> {\n return function callbackCurried(callback: Callback<unknown>) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n cf.apply(this, [...args, callback]);\n };\n}\n","import { errorNormalize } from '@/error';\nimport type {\n CallbackFunction0,\n CallbackFunction1,\n CallbackFunction2,\n CallbackFunction3,\n CallbackFunction4,\n CallbackFunction5,\n CallbackFunction6,\n} from './curry';\nimport { callbackCurry } from './curry';\nimport type { FlattenReturn } from './types';\n\nexport function tryCallback(cf: CallbackFunction0): Promise<FlattenReturn>;\nexport function tryCallback<T = void>(cf: CallbackFunction0<T>): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, T = void>(cf: CallbackFunction1<A, T>, a: A): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, T = void>(cf: CallbackFunction2<A, B, T>, a: A, b: B): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, T = void>(\n cf: CallbackFunction3<A, B, C, T>,\n a: A,\n b: B,\n c: C,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, D, T = void>(\n cf: CallbackFunction4<A, B, C, D>,\n a: A,\n b: B,\n c: C,\n d: D,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, D, E, T = void>(\n cf: CallbackFunction5<A, B, C, D, E, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback<A, B, C, D, E, F, T = void>(\n cf: CallbackFunction6<A, B, C, D, E, F, T>,\n a: A,\n b: B,\n c: C,\n d: D,\n e: E,\n f: F,\n): Promise<FlattenReturn<T>>;\nexport function tryCallback(cf: unknown, ...args: unknown[]): Promise<FlattenReturn<unknown>> {\n return new Promise((resolve) => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n callbackCurry.apply(this, [cf, ...args])((err, res) => {\n if (err) {\n resolve([errorNormalize(err), undefined] as const);\n } else {\n resolve([undefined, res] as const);\n }\n });\n });\n}\n","import { errorNormalize } from '@/error';\nimport type { FlattenReturn } from './types';\n\nexport type SyncFunction<T> = () => T;\n\nexport function trySync<T>(syncFn: SyncFunction<T>): FlattenReturn<T> {\n try {\n return [undefined, syncFn()] as const;\n } catch (err) {\n return [errorNormalize(err), undefined] as const;\n }\n}\n\nexport type AsyncFunction<T> = () => Promise<T>;\n\nexport function tryAsync<T>(asyncFn: AsyncFunction<T>): Promise<FlattenReturn<T>> {\n return asyncFn().then(\n (res) => [undefined, res] as const,\n (err) => [errorNormalize(err), undefined] as const,\n );\n}\n","import { errorNormalize } from '@/error';\nimport type { FlattenReturn } from './types';\n\nexport function tryPromise<T>(promise: PromiseLike<T>): PromiseLike<FlattenReturn<T>> {\n return promise.then(\n (res) => [undefined, res] as const,\n (err) => [errorNormalize(err), undefined] as const,\n );\n}\n","import { isAsyncFunction } from '@/type';\nimport { tryCallback } from './callback';\nimport type { CallbackFunction0 } from './curry';\nimport { type AsyncFunction, type SyncFunction, tryAsync, trySync } from './function';\nimport { tryPromise } from './promise';\nimport type { FlattenReturn } from './types';\n\nexport type FlattenAble<T> = SyncFunction<T> | AsyncFunction<T> | CallbackFunction0<T> | PromiseLike<T>;\n\n// 注意顺序 AsyncFunction > SyncFunction > CallbackFunction0 > PromiseLike\n// 需要先匹配 AsyncFunction,否则会把入参当做同步函数\nexport function tryFlatten<T>(flattenAble: AsyncFunction<T>): Promise<FlattenReturn<T>>;\nexport function tryFlatten<T>(flattenAble: SyncFunction<T>): FlattenReturn<T>;\nexport function tryFlatten<T>(flattenAble: CallbackFunction0<T> | PromiseLike<T>): Promise<FlattenReturn<T>>;\nexport function tryFlatten<T>(flattenAble: FlattenAble<T>): unknown {\n if ('then' in flattenAble) {\n return tryPromise<T>(flattenAble);\n }\n\n // SyncFunction | AsyncFunction\n if (flattenAble.length === 0) {\n if (isAsyncFunction(flattenAble)) return tryAsync<T>(flattenAble as AsyncFunction<T>);\n return trySync<T>(flattenAble as SyncFunction<T>);\n }\n\n return tryCallback<T>(flattenAble);\n}\n"],"mappings":";;;AA4DA,SAAgB,cAAc,IAAa,GAAG,MAA2C;CACvF,OAAO,SAAS,gBAAgB,UAA6B;EAG3D,GAAG,MAAM,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC;;;;;ACjBvC,SAAgB,YAAY,IAAa,GAAG,MAAkD;CAC5F,OAAO,IAAI,SAAS,YAAY;EAG9B,cAAc,MAAM,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,EAAE,KAAK,QAAQ;GACrD,IAAI,KACF,QAAQ,CAAC,eAAe,IAAI,EAAE,KAAA,EAAU,CAAU;QAElD,QAAQ,CAAC,KAAA,GAAW,IAAI,CAAU;IAEpC;GACF;;;;ACrDJ,SAAgB,QAAW,QAA2C;CACpE,IAAI;EACF,OAAO,CAAC,KAAA,GAAW,QAAQ,CAAC;UACrB,KAAK;EACZ,OAAO,CAAC,eAAe,IAAI,EAAE,KAAA,EAAU;;;AAM3C,SAAgB,SAAY,SAAsD;CAChF,OAAO,SAAS,CAAC,MACd,QAAQ,CAAC,KAAA,GAAW,IAAI,GACxB,QAAQ,CAAC,eAAe,IAAI,EAAE,KAAA,EAAU,CAC1C;;;;AChBH,SAAgB,WAAc,SAAwD;CACpF,OAAO,QAAQ,MACZ,QAAQ,CAAC,KAAA,GAAW,IAAI,GACxB,QAAQ,CAAC,eAAe,IAAI,EAAE,KAAA,EAAU,CAC1C;;;;ACOH,SAAgB,WAAc,aAAsC;CAClE,IAAI,UAAU,aACZ,OAAO,WAAc,YAAY;CAInC,IAAI,YAAY,WAAW,GAAG;EAC5B,IAAI,gBAAgB,YAAY,EAAE,OAAO,SAAY,YAAgC;EACrF,OAAO,QAAW,YAA+B;;CAGnD,OAAO,YAAe,YAAY"}
|
package/dist/type.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type.cjs","names":[],"sources":["../src/type.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"type.cjs","names":[],"sources":["../src/type.ts"],"sourcesContent":["import type { AnyArray, AnyAsyncFunction, AnyFunction, AnyObject } from './types';\n\n/**\n * 获取未知类型的类型名称\n * @param unknown - 未知类型的值\n * @returns 类型名称字符串\n */\nexport function typeIs(\n unknown: unknown,\n):\n | 'string'\n | 'number'\n | 'boolean'\n | 'object'\n | 'array'\n | 'function'\n | 'null'\n | 'undefined'\n | 'symbol'\n | 'bigint'\n | 'error'\n | 'promise'\n | string {\n return Object.prototype.toString.call(unknown).slice(8, -1).toLowerCase();\n}\n\n/**\n * 检查值是否为字符串\n * @param unknown - 未知类型的值\n * @returns 如果值为字符串则返回 true,否则返回 false\n */\nexport function isString(unknown: unknown): unknown is string {\n return typeof unknown === 'string';\n}\n\n/**\n * 检查值是否为布尔值\n * @param unknown - 未知类型的值\n * @returns 如果值为布尔值则返回 true,否则返回 false\n */\nexport function isBoolean(unknown: unknown): unknown is boolean {\n return typeof unknown === 'boolean';\n}\n\n/**\n * 检查值是否为符号\n * @param unknown - 未知类型的值\n * @returns 如果值为符号则返回 true,否则返回 false\n */\nexport function isSymbol(unknown: unknown): unknown is symbol {\n return typeof unknown === 'symbol';\n}\n\n/**\n * 检查值是否为大整数\n * @param unknown - 未知类型的值\n * @returns 如果值为大整数则返回 true,否则返回 false\n */\nexport function isBigInt(unknown: unknown): unknown is bigint {\n return typeof unknown === 'bigint';\n}\n\n/**\n * 检查值是否为数字\n * @param unknown - 未知类型的值\n * @returns 如果值为数字且不是 NaN 则返回 true,否则返回 false\n */\nexport function isNumber(unknown: unknown): unknown is number {\n return typeof unknown === 'number' && !Number.isNaN(unknown);\n}\n\n/**\n * 检查值是否为 undefined\n * @param unknown - 未知类型的值\n * @returns 如果值为 undefined 则返回 true,否则返回 false\n */\nexport function isUndefined(unknown: unknown): unknown is undefined {\n return typeof unknown === 'undefined';\n}\n\n/**\n * 检查值是否为 void\n * @param unknown - 未知类型的值\n * @returns 如果值为 undefined 则返回 true,否则返回 false\n */\n// biome-ignore lint/suspicious/noConfusingVoidType: 必须使用 void 类型断言\nexport function isVoid(unknown: unknown): unknown is void {\n return isUndefined(unknown);\n}\n\n/**\n * 永不执行,用于 switch-case/if-else 类型断言\n * @param unknown - 永远不会执行的值\n */\nexport function isNever(_unknown: never) {\n //\n}\n\n/**\n * 检查值是否为 null\n * @param unknown - 未知类型的值\n * @returns 如果值为 null 则返回 true,否则返回 false\n */\nexport function isNull(unknown: unknown): unknown is null {\n return unknown === null;\n}\n\n/**\n * 检查值是否为 nullish(null 或 undefined 或 void)\n * @param unknown - 未知类型的值\n * @returns 如果值为 null 或 undefined 或 void 则返回 true,否则返回 false\n */\nexport function isNullish(unknown: unknown): unknown is null | undefined | undefined {\n return isNull(unknown) || isUndefined(unknown) || isVoid(unknown);\n}\n\n/**\n * 检查值是否为原始类型(null 或 非对象)\n * @param unknown - 未知类型的值\n * @returns 如果值为原始类型则返回 true,否则返回 false\n */\nexport function isPrimitive(\n unknown: unknown,\n): unknown is string | number | boolean | symbol | bigint | null | undefined {\n return isNull(unknown) || !(typeof unknown === 'object' || typeof unknown === 'function');\n}\n\n/**\n * 检查值是否为对象,但要注意,此时的对象类型是包含了数组和函数\n * @param unknown - 未知类型的值\n * @returns 如果值为对象则返回 true,否则返回 false\n */\nexport function isObject(unknown: unknown): unknown is AnyObject {\n return typeIs(unknown) === 'object';\n}\n\n/**\n * 检查值是否为数组\n * @param unknown - 未知类型的值\n * @returns 如果值为数组则返回 true,否则返回 false\n */\nexport function isArray(unknown: unknown): unknown is AnyArray {\n return Array.isArray(unknown);\n}\n\n/**\n * 检查值是否为函数\n * @param unknown - 未知类型的值\n * @returns 如果值为函数则返回 true,否则返回 false\n */\nexport function isFunction(unknown: unknown): unknown is AnyFunction {\n return typeof unknown === 'function';\n}\n\n/**\n * 检查值是否为异步函数\n * @param unknown - 需要检查的值\n * @returns 如果值为异步函数则返回 true,否则返回 false\n * @example\n * ```typescript\n * async function example() {}\n *\n * isAsyncFunction(example); // true\n * isAsyncFunction(() => {}); // false\n * ```\n */\nexport function isAsyncFunction(unknown: unknown): unknown is AnyAsyncFunction {\n return isFunction(unknown) && unknown.constructor.name === 'AsyncFunction';\n}\n\n/**\n * 检查值是否为 Error 类型\n * @param unknown - 未知类型的值\n * @returns 如果值为 Error 类型则返回 true,否则返回 false\n */\nexport function isError(unknown: unknown): unknown is Error {\n return unknown instanceof Error;\n}\n\n/**\n * 检查值是否为 Promise 类型\n * @param unknown - 未知类型的值\n * @returns 如果值为 Promise 类型则返回 true,否则返回 false\n */\nexport function isPromise<T>(unknown: unknown): unknown is Promise<T> {\n return typeIs(unknown) === 'promise';\n}\n\n/**\n * 检查值是否为 Date 类型\n * @param unknown - 未知类型的值\n * @returns 如果值为 Date 类型则返回 true,否则返回 false\n */\nexport function isDate(unknown: unknown): unknown is Date {\n return unknown instanceof Date;\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,OACd,SAcS;CACT,OAAO,OAAO,UAAU,SAAS,KAAK,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC,aAAa;;;;;;;AAQ3E,SAAgB,SAAS,SAAqC;CAC5D,OAAO,OAAO,YAAY;;;;;;;AAQ5B,SAAgB,UAAU,SAAsC;CAC9D,OAAO,OAAO,YAAY;;;;;;;AAQ5B,SAAgB,SAAS,SAAqC;CAC5D,OAAO,OAAO,YAAY;;;;;;;AAQ5B,SAAgB,SAAS,SAAqC;CAC5D,OAAO,OAAO,YAAY;;;;;;;AAQ5B,SAAgB,SAAS,SAAqC;CAC5D,OAAO,OAAO,YAAY,YAAY,CAAC,OAAO,MAAM,QAAQ;;;;;;;AAQ9D,SAAgB,YAAY,SAAwC;CAClE,OAAO,OAAO,YAAY;;;;;;;AAS5B,SAAgB,OAAO,SAAmC;CACxD,OAAO,YAAY,QAAQ;;;;;;AAO7B,SAAgB,QAAQ,UAAiB;;;;;;AASzC,SAAgB,OAAO,SAAmC;CACxD,OAAO,YAAY;;;;;;;AAQrB,SAAgB,UAAU,SAA2D;CACnF,OAAO,OAAO,QAAQ,IAAI,YAAY,QAAQ,IAAI,OAAO,QAAQ;;;;;;;AAQnE,SAAgB,YACd,SAC2E;CAC3E,OAAO,OAAO,QAAQ,IAAI,EAAE,OAAO,YAAY,YAAY,OAAO,YAAY;;;;;;;AAQhF,SAAgB,SAAS,SAAwC;CAC/D,OAAO,OAAO,QAAQ,KAAK;;;;;;;AAQ7B,SAAgB,QAAQ,SAAuC;CAC7D,OAAO,MAAM,QAAQ,QAAQ;;;;;;;AAQ/B,SAAgB,WAAW,SAA0C;CACnE,OAAO,OAAO,YAAY;;;;;;;;;;;;;;AAe5B,SAAgB,gBAAgB,SAA+C;CAC7E,OAAO,WAAW,QAAQ,IAAI,QAAQ,YAAY,SAAS;;;;;;;AAQ7D,SAAgB,QAAQ,SAAoC;CAC1D,OAAO,mBAAmB;;;;;;;AAQ5B,SAAgB,UAAa,SAAyC;CACpE,OAAO,OAAO,QAAQ,KAAK;;;;;;;AAQ7B,SAAgB,OAAO,SAAmC;CACxD,OAAO,mBAAmB"}
|
package/dist/type.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type.mjs","names":[],"sources":["../src/type.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"type.mjs","names":[],"sources":["../src/type.ts"],"sourcesContent":["import type { AnyArray, AnyAsyncFunction, AnyFunction, AnyObject } from './types';\n\n/**\n * 获取未知类型的类型名称\n * @param unknown - 未知类型的值\n * @returns 类型名称字符串\n */\nexport function typeIs(\n unknown: unknown,\n):\n | 'string'\n | 'number'\n | 'boolean'\n | 'object'\n | 'array'\n | 'function'\n | 'null'\n | 'undefined'\n | 'symbol'\n | 'bigint'\n | 'error'\n | 'promise'\n | string {\n return Object.prototype.toString.call(unknown).slice(8, -1).toLowerCase();\n}\n\n/**\n * 检查值是否为字符串\n * @param unknown - 未知类型的值\n * @returns 如果值为字符串则返回 true,否则返回 false\n */\nexport function isString(unknown: unknown): unknown is string {\n return typeof unknown === 'string';\n}\n\n/**\n * 检查值是否为布尔值\n * @param unknown - 未知类型的值\n * @returns 如果值为布尔值则返回 true,否则返回 false\n */\nexport function isBoolean(unknown: unknown): unknown is boolean {\n return typeof unknown === 'boolean';\n}\n\n/**\n * 检查值是否为符号\n * @param unknown - 未知类型的值\n * @returns 如果值为符号则返回 true,否则返回 false\n */\nexport function isSymbol(unknown: unknown): unknown is symbol {\n return typeof unknown === 'symbol';\n}\n\n/**\n * 检查值是否为大整数\n * @param unknown - 未知类型的值\n * @returns 如果值为大整数则返回 true,否则返回 false\n */\nexport function isBigInt(unknown: unknown): unknown is bigint {\n return typeof unknown === 'bigint';\n}\n\n/**\n * 检查值是否为数字\n * @param unknown - 未知类型的值\n * @returns 如果值为数字且不是 NaN 则返回 true,否则返回 false\n */\nexport function isNumber(unknown: unknown): unknown is number {\n return typeof unknown === 'number' && !Number.isNaN(unknown);\n}\n\n/**\n * 检查值是否为 undefined\n * @param unknown - 未知类型的值\n * @returns 如果值为 undefined 则返回 true,否则返回 false\n */\nexport function isUndefined(unknown: unknown): unknown is undefined {\n return typeof unknown === 'undefined';\n}\n\n/**\n * 检查值是否为 void\n * @param unknown - 未知类型的值\n * @returns 如果值为 undefined 则返回 true,否则返回 false\n */\n// biome-ignore lint/suspicious/noConfusingVoidType: 必须使用 void 类型断言\nexport function isVoid(unknown: unknown): unknown is void {\n return isUndefined(unknown);\n}\n\n/**\n * 永不执行,用于 switch-case/if-else 类型断言\n * @param unknown - 永远不会执行的值\n */\nexport function isNever(_unknown: never) {\n //\n}\n\n/**\n * 检查值是否为 null\n * @param unknown - 未知类型的值\n * @returns 如果值为 null 则返回 true,否则返回 false\n */\nexport function isNull(unknown: unknown): unknown is null {\n return unknown === null;\n}\n\n/**\n * 检查值是否为 nullish(null 或 undefined 或 void)\n * @param unknown - 未知类型的值\n * @returns 如果值为 null 或 undefined 或 void 则返回 true,否则返回 false\n */\nexport function isNullish(unknown: unknown): unknown is null | undefined | undefined {\n return isNull(unknown) || isUndefined(unknown) || isVoid(unknown);\n}\n\n/**\n * 检查值是否为原始类型(null 或 非对象)\n * @param unknown - 未知类型的值\n * @returns 如果值为原始类型则返回 true,否则返回 false\n */\nexport function isPrimitive(\n unknown: unknown,\n): unknown is string | number | boolean | symbol | bigint | null | undefined {\n return isNull(unknown) || !(typeof unknown === 'object' || typeof unknown === 'function');\n}\n\n/**\n * 检查值是否为对象,但要注意,此时的对象类型是包含了数组和函数\n * @param unknown - 未知类型的值\n * @returns 如果值为对象则返回 true,否则返回 false\n */\nexport function isObject(unknown: unknown): unknown is AnyObject {\n return typeIs(unknown) === 'object';\n}\n\n/**\n * 检查值是否为数组\n * @param unknown - 未知类型的值\n * @returns 如果值为数组则返回 true,否则返回 false\n */\nexport function isArray(unknown: unknown): unknown is AnyArray {\n return Array.isArray(unknown);\n}\n\n/**\n * 检查值是否为函数\n * @param unknown - 未知类型的值\n * @returns 如果值为函数则返回 true,否则返回 false\n */\nexport function isFunction(unknown: unknown): unknown is AnyFunction {\n return typeof unknown === 'function';\n}\n\n/**\n * 检查值是否为异步函数\n * @param unknown - 需要检查的值\n * @returns 如果值为异步函数则返回 true,否则返回 false\n * @example\n * ```typescript\n * async function example() {}\n *\n * isAsyncFunction(example); // true\n * isAsyncFunction(() => {}); // false\n * ```\n */\nexport function isAsyncFunction(unknown: unknown): unknown is AnyAsyncFunction {\n return isFunction(unknown) && unknown.constructor.name === 'AsyncFunction';\n}\n\n/**\n * 检查值是否为 Error 类型\n * @param unknown - 未知类型的值\n * @returns 如果值为 Error 类型则返回 true,否则返回 false\n */\nexport function isError(unknown: unknown): unknown is Error {\n return unknown instanceof Error;\n}\n\n/**\n * 检查值是否为 Promise 类型\n * @param unknown - 未知类型的值\n * @returns 如果值为 Promise 类型则返回 true,否则返回 false\n */\nexport function isPromise<T>(unknown: unknown): unknown is Promise<T> {\n return typeIs(unknown) === 'promise';\n}\n\n/**\n * 检查值是否为 Date 类型\n * @param unknown - 未知类型的值\n * @returns 如果值为 Date 类型则返回 true,否则返回 false\n */\nexport function isDate(unknown: unknown): unknown is Date {\n return unknown instanceof Date;\n}\n"],"mappings":";;;;;;AAOA,SAAgB,OACd,SAcS;CACT,OAAO,OAAO,UAAU,SAAS,KAAK,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC,aAAa;;;;;;;AAQ3E,SAAgB,SAAS,SAAqC;CAC5D,OAAO,OAAO,YAAY;;;;;;;AAQ5B,SAAgB,UAAU,SAAsC;CAC9D,OAAO,OAAO,YAAY;;;;;;;AAQ5B,SAAgB,SAAS,SAAqC;CAC5D,OAAO,OAAO,YAAY;;;;;;;AAQ5B,SAAgB,SAAS,SAAqC;CAC5D,OAAO,OAAO,YAAY;;;;;;;AAQ5B,SAAgB,SAAS,SAAqC;CAC5D,OAAO,OAAO,YAAY,YAAY,CAAC,OAAO,MAAM,QAAQ;;;;;;;AAQ9D,SAAgB,YAAY,SAAwC;CAClE,OAAO,OAAO,YAAY;;;;;;;AAS5B,SAAgB,OAAO,SAAmC;CACxD,OAAO,YAAY,QAAQ;;;;;;AAO7B,SAAgB,QAAQ,UAAiB;;;;;;AASzC,SAAgB,OAAO,SAAmC;CACxD,OAAO,YAAY;;;;;;;AAQrB,SAAgB,UAAU,SAA2D;CACnF,OAAO,OAAO,QAAQ,IAAI,YAAY,QAAQ,IAAI,OAAO,QAAQ;;;;;;;AAQnE,SAAgB,YACd,SAC2E;CAC3E,OAAO,OAAO,QAAQ,IAAI,EAAE,OAAO,YAAY,YAAY,OAAO,YAAY;;;;;;;AAQhF,SAAgB,SAAS,SAAwC;CAC/D,OAAO,OAAO,QAAQ,KAAK;;;;;;;AAQ7B,SAAgB,QAAQ,SAAuC;CAC7D,OAAO,MAAM,QAAQ,QAAQ;;;;;;;AAQ/B,SAAgB,WAAW,SAA0C;CACnE,OAAO,OAAO,YAAY;;;;;;;;;;;;;;AAe5B,SAAgB,gBAAgB,SAA+C;CAC7E,OAAO,WAAW,QAAQ,IAAI,QAAQ,YAAY,SAAS;;;;;;;AAQ7D,SAAgB,QAAQ,SAAoC;CAC1D,OAAO,mBAAmB;;;;;;;AAQ5B,SAAgB,UAAa,SAAyC;CACpE,OAAO,OAAO,QAAQ,KAAK;;;;;;;AAQ7B,SAAgB,OAAO,SAAmC;CACxD,OAAO,mBAAmB"}
|
package/dist/types.d.ts
CHANGED
|
@@ -151,5 +151,5 @@ export type HasProperty<T, K> = K extends keyof T ? true : false;
|
|
|
151
151
|
* type Result3 = Exact<{ a: 1 }, { a: 1; b: 2 }>; // never
|
|
152
152
|
* ```
|
|
153
153
|
*/
|
|
154
|
-
export type Exact<T, Shape> = T extends Shape ? Exclude<keyof T, keyof Shape> extends never ? T : never : never;
|
|
154
|
+
export type Exact<T, Shape> = T extends Shape ? (Exclude<keyof T, keyof Shape> extends never ? T : never) : never;
|
|
155
155
|
export {};
|
package/dist/url.cjs
CHANGED
package/dist/url.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.cjs","names":[],"sources":["../src/url.ts"],"sourcesContent":["/**\n * URL 元信息\n */\nexport type UrlMeta = {\n /**\n * 协议部分,包含冒号,例如 \"https:\"。\n */\n protocol: string;\n /**\n * 主机部分,包括主机名和端口。\n */\n host: string;\n /**\n * 主机名部分。\n */\n hostname: string;\n /**\n * 端口部分。\n */\n port: string;\n /**\n * 路径部分。\n */\n pathname: string;\n /**\n * 查询字符串部分。\n */\n search: string;\n /**\n * 哈希部分。\n */\n hash: string;\n /**\n * 用户名部分。\n */\n username: string;\n /**\n * 密码部分。\n */\n password: string;\n};\n\n/**\n * 解析 URL 字符串为组件对象。\n * @param url - 需要解析的 URL 字符串。\n * @returns 包含解析后 URL 组件的对象。\n */\nexport function urlParse(url: string): UrlMeta {\n let result: URL | null = null;\n\n try {\n // 添加 globalThis 是便于对接外部环境 URL 的自行实现\n // 例如在 uni-app、微信小程序等运行环境。\n result = new globalThis.URL(url);\n } catch
|
|
1
|
+
{"version":3,"file":"url.cjs","names":[],"sources":["../src/url.ts"],"sourcesContent":["/**\n * URL 元信息\n */\nexport type UrlMeta = {\n /**\n * 协议部分,包含冒号,例如 \"https:\"。\n */\n protocol: string;\n /**\n * 主机部分,包括主机名和端口。\n */\n host: string;\n /**\n * 主机名部分。\n */\n hostname: string;\n /**\n * 端口部分。\n */\n port: string;\n /**\n * 路径部分。\n */\n pathname: string;\n /**\n * 查询字符串部分。\n */\n search: string;\n /**\n * 哈希部分。\n */\n hash: string;\n /**\n * 用户名部分。\n */\n username: string;\n /**\n * 密码部分。\n */\n password: string;\n};\n\n/**\n * 解析 URL 字符串为组件对象。\n * @param url - 需要解析的 URL 字符串。\n * @returns 包含解析后 URL 组件的对象。\n */\nexport function urlParse(url: string): UrlMeta {\n let result: URL | null = null;\n\n try {\n // 添加 globalThis 是便于对接外部环境 URL 的自行实现\n // 例如在 uni-app、微信小程序等运行环境。\n result = new globalThis.URL(url);\n } catch {\n // ignore\n }\n\n const protocol = result?.protocol || '';\n const host = result?.host || '';\n\n return {\n protocol,\n host,\n hostname: result?.hostname || '',\n port: result?.port || '',\n pathname: result?.pathname || '',\n search: result?.search || '',\n hash: result?.hash || '',\n username: result?.username || '',\n password: result?.password || '',\n };\n}\n\n/**\n * 将 UrlMeta 对象转换回 URL 字符串。\n * @param url - 需要转换的 UrlMeta 对象。\n * @returns 转换后的 URL 字符串。\n */\nexport function urlStringify(url: UrlMeta) {\n const { protocol, hostname, port, pathname, search, hash, username, password } = url;\n return [\n protocol ? `${protocol}//` : '',\n username && password ? `${username}:${password}@` : '',\n hostname,\n port ? `:${port}` : '',\n pathname,\n search,\n hash,\n ]\n .filter(Boolean)\n .join('');\n}\n"],"mappings":";;;;;;;AA+CA,SAAgB,SAAS,KAAsB;CAC7C,IAAI,SAAqB;CAEzB,IAAI;EAGF,SAAS,IAAI,WAAW,IAAI,IAAI;SAC1B;CAOR,OAAO;EACL,UAJe,QAAQ,YAAY;EAKnC,MAJW,QAAQ,QAAQ;EAK3B,UAAU,QAAQ,YAAY;EAC9B,MAAM,QAAQ,QAAQ;EACtB,UAAU,QAAQ,YAAY;EAC9B,QAAQ,QAAQ,UAAU;EAC1B,MAAM,QAAQ,QAAQ;EACtB,UAAU,QAAQ,YAAY;EAC9B,UAAU,QAAQ,YAAY;EAC/B;;;;;;;AAQH,SAAgB,aAAa,KAAc;CACzC,MAAM,EAAE,UAAU,UAAU,MAAM,UAAU,QAAQ,MAAM,UAAU,aAAa;CACjF,OAAO;EACL,WAAW,GAAG,SAAS,MAAM;EAC7B,YAAY,WAAW,GAAG,SAAS,GAAG,SAAS,KAAK;EACpD;EACA,OAAO,IAAI,SAAS;EACpB;EACA;EACA;EACD,CACE,OAAO,QAAQ,CACf,KAAK,GAAG"}
|
package/dist/url.mjs
CHANGED
package/dist/url.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.mjs","names":[],"sources":["../src/url.ts"],"sourcesContent":["/**\n * URL 元信息\n */\nexport type UrlMeta = {\n /**\n * 协议部分,包含冒号,例如 \"https:\"。\n */\n protocol: string;\n /**\n * 主机部分,包括主机名和端口。\n */\n host: string;\n /**\n * 主机名部分。\n */\n hostname: string;\n /**\n * 端口部分。\n */\n port: string;\n /**\n * 路径部分。\n */\n pathname: string;\n /**\n * 查询字符串部分。\n */\n search: string;\n /**\n * 哈希部分。\n */\n hash: string;\n /**\n * 用户名部分。\n */\n username: string;\n /**\n * 密码部分。\n */\n password: string;\n};\n\n/**\n * 解析 URL 字符串为组件对象。\n * @param url - 需要解析的 URL 字符串。\n * @returns 包含解析后 URL 组件的对象。\n */\nexport function urlParse(url: string): UrlMeta {\n let result: URL | null = null;\n\n try {\n // 添加 globalThis 是便于对接外部环境 URL 的自行实现\n // 例如在 uni-app、微信小程序等运行环境。\n result = new globalThis.URL(url);\n } catch
|
|
1
|
+
{"version":3,"file":"url.mjs","names":[],"sources":["../src/url.ts"],"sourcesContent":["/**\n * URL 元信息\n */\nexport type UrlMeta = {\n /**\n * 协议部分,包含冒号,例如 \"https:\"。\n */\n protocol: string;\n /**\n * 主机部分,包括主机名和端口。\n */\n host: string;\n /**\n * 主机名部分。\n */\n hostname: string;\n /**\n * 端口部分。\n */\n port: string;\n /**\n * 路径部分。\n */\n pathname: string;\n /**\n * 查询字符串部分。\n */\n search: string;\n /**\n * 哈希部分。\n */\n hash: string;\n /**\n * 用户名部分。\n */\n username: string;\n /**\n * 密码部分。\n */\n password: string;\n};\n\n/**\n * 解析 URL 字符串为组件对象。\n * @param url - 需要解析的 URL 字符串。\n * @returns 包含解析后 URL 组件的对象。\n */\nexport function urlParse(url: string): UrlMeta {\n let result: URL | null = null;\n\n try {\n // 添加 globalThis 是便于对接外部环境 URL 的自行实现\n // 例如在 uni-app、微信小程序等运行环境。\n result = new globalThis.URL(url);\n } catch {\n // ignore\n }\n\n const protocol = result?.protocol || '';\n const host = result?.host || '';\n\n return {\n protocol,\n host,\n hostname: result?.hostname || '',\n port: result?.port || '',\n pathname: result?.pathname || '',\n search: result?.search || '',\n hash: result?.hash || '',\n username: result?.username || '',\n password: result?.password || '',\n };\n}\n\n/**\n * 将 UrlMeta 对象转换回 URL 字符串。\n * @param url - 需要转换的 UrlMeta 对象。\n * @returns 转换后的 URL 字符串。\n */\nexport function urlStringify(url: UrlMeta) {\n const { protocol, hostname, port, pathname, search, hash, username, password } = url;\n return [\n protocol ? `${protocol}//` : '',\n username && password ? `${username}:${password}@` : '',\n hostname,\n port ? `:${port}` : '',\n pathname,\n search,\n hash,\n ]\n .filter(Boolean)\n .join('');\n}\n"],"mappings":";;;;;;AA+CA,SAAgB,SAAS,KAAsB;CAC7C,IAAI,SAAqB;CAEzB,IAAI;EAGF,SAAS,IAAI,WAAW,IAAI,IAAI;SAC1B;CAOR,OAAO;EACL,UAJe,QAAQ,YAAY;EAKnC,MAJW,QAAQ,QAAQ;EAK3B,UAAU,QAAQ,YAAY;EAC9B,MAAM,QAAQ,QAAQ;EACtB,UAAU,QAAQ,YAAY;EAC9B,QAAQ,QAAQ,UAAU;EAC1B,MAAM,QAAQ,QAAQ;EACtB,UAAU,QAAQ,YAAY;EAC9B,UAAU,QAAQ,YAAY;EAC/B;;;;;;;AAQH,SAAgB,aAAa,KAAc;CACzC,MAAM,EAAE,UAAU,UAAU,MAAM,UAAU,QAAQ,MAAM,UAAU,aAAa;CACjF,OAAO;EACL,WAAW,GAAG,SAAS,MAAM;EAC7B,YAAY,WAAW,GAAG,SAAS,GAAG,SAAS,KAAK;EACpD;EACA,OAAO,IAAI,SAAS;EACpB;EACA;EACA;EACD,CACE,OAAO,QAAQ,CACf,KAAK,GAAG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcome/utils-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.21.0",
|
|
4
4
|
"description": "cloudcome core utils",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -265,16 +265,16 @@
|
|
|
265
265
|
"node": ">=22"
|
|
266
266
|
},
|
|
267
267
|
"keywords": [
|
|
268
|
-
"utils",
|
|
269
268
|
"cloudcome",
|
|
269
|
+
"utils",
|
|
270
|
+
"utils-browser",
|
|
270
271
|
"utils-core",
|
|
271
|
-
"utils-
|
|
272
|
+
"utils-node",
|
|
272
273
|
"utils-react",
|
|
273
274
|
"utils-uni",
|
|
274
|
-
"utils-
|
|
275
|
-
"utils-browser"
|
|
275
|
+
"utils-vue"
|
|
276
276
|
],
|
|
277
|
-
"homepage": "https://github.
|
|
277
|
+
"homepage": "https://cloudcome.github.io/utils/",
|
|
278
278
|
"license": "MIT",
|
|
279
279
|
"author": "云淡然 <hi@ydr.me> (https://ydr.me/)",
|
|
280
280
|
"repository": {
|