@cloudcome/utils-core 1.1.0 → 1.1.1

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.
Files changed (292) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/LICENSE +21 -0
  3. package/package.json +279 -1
  4. package/src/array.ts +312 -0
  5. package/src/async.ts +379 -0
  6. package/src/base64.ts +20 -0
  7. package/src/cache.ts +146 -0
  8. package/{dist/color/contrast.d.ts → src/color/contrast.ts} +12 -2
  9. package/src/color/distance.ts +28 -0
  10. package/src/color/helpers.ts +23 -0
  11. package/src/color/hex-hsl.ts +11 -0
  12. package/{dist/color/hex-hsv.d.ts → src/color/hex-hsv.ts} +11 -3
  13. package/{dist/color/hex-hwb.d.ts → src/color/hex-hwb.ts} +11 -3
  14. package/src/color/hex-rgb.ts +39 -0
  15. package/{dist/color/hsl-lighten.d.ts → src/color/hsl-lighten.ts} +7 -2
  16. package/{dist/color/hsv-brighten.d.ts → src/color/hsv-brighten.ts} +7 -2
  17. package/{dist/color/luminance.d.ts → src/color/luminance.ts} +9 -2
  18. package/{dist/color/mix.d.ts → src/color/mix.ts} +10 -2
  19. package/src/color/rgb-hsl.ts +53 -0
  20. package/{dist/color/rgb-hsv.d.ts → src/color/rgb-hsv.ts} +30 -3
  21. package/src/color/rgb-hwb.ts +56 -0
  22. package/{dist/color/rgb-lab.d.ts → src/color/rgb-lab.ts} +11 -3
  23. package/src/color/rgb-whiter.ts +22 -0
  24. package/src/color/rgb-xyz.ts +62 -0
  25. package/{dist/color/types.d.ts → src/color/types.ts} +12 -30
  26. package/{dist/color/xyz-lab.d.ts → src/color/xyz-lab.ts} +32 -3
  27. package/src/crypto/md5.mjs +357 -0
  28. package/src/crypto/sha1.mjs +300 -0
  29. package/src/crypto/sha256.mjs +310 -0
  30. package/src/crypto/sha512.mjs +459 -0
  31. package/{dist/crypto.d.ts → src/crypto.ts} +20 -4
  32. package/src/date/const.ts +6 -0
  33. package/src/date/core.ts +162 -0
  34. package/src/date/days.ts +51 -0
  35. package/{dist/date/is.d.ts → src/date/is.ts} +102 -8
  36. package/src/date/relative.ts +92 -0
  37. package/src/date/start-end.ts +246 -0
  38. package/src/date/timezone.ts +220 -0
  39. package/src/date/weeks.ts +100 -0
  40. package/src/dts/global.d.ts +27 -0
  41. package/src/easing.ts +166 -0
  42. package/src/emitter.ts +117 -0
  43. package/src/enum.ts +171 -0
  44. package/{dist/env.d.ts → src/env.ts} +30 -6
  45. package/{dist/error.d.ts → src/error.ts} +12 -3
  46. package/src/exception.ts +68 -0
  47. package/src/fn.ts +197 -0
  48. package/src/index.ts +1 -0
  49. package/src/number.ts +236 -0
  50. package/{dist/object/each.d.ts → src/object/each.ts} +23 -3
  51. package/src/object/get-set.ts +273 -0
  52. package/src/object/is.ts +128 -0
  53. package/src/object/merge.ts +180 -0
  54. package/{dist/object/process.d.ts → src/object/process.ts} +38 -4
  55. package/src/path.ts +188 -0
  56. package/{dist/promise.d.ts → src/promise.ts} +67 -6
  57. package/{dist/qs.d.ts → src/qs.ts} +60 -3
  58. package/src/regexp.ts +156 -0
  59. package/src/string.ts +146 -0
  60. package/src/time/from.ts +57 -0
  61. package/src/time/to.ts +106 -0
  62. package/{dist/timer.mjs → src/timer.ts} +124 -17
  63. package/{dist/tree.d.ts → src/tree.ts} +225 -41
  64. package/{dist/type.d.ts → src/type.ts} +96 -20
  65. package/{dist/types.d.ts → src/types.ts} +33 -12
  66. package/src/unique.ts +77 -0
  67. package/src/url.ts +93 -0
  68. package/src/version.ts +71 -0
  69. package/test/array.test.ts +332 -0
  70. package/test/async-real.test.ts +39 -0
  71. package/test/async.test.ts +375 -0
  72. package/test/base64.test.ts +32 -0
  73. package/test/cache.test.ts +83 -0
  74. package/test/color.test.ts +163 -0
  75. package/test/crypto.test.ts +34 -0
  76. package/test/date-tz.test.ts +206 -0
  77. package/test/date.test.ts +353 -0
  78. package/test/easing.test.ts +33 -0
  79. package/test/emitter.test.ts +71 -0
  80. package/test/enum.test.ts +113 -0
  81. package/test/env.test.ts +69 -0
  82. package/test/error.test.ts +58 -0
  83. package/test/exception.test.ts +43 -0
  84. package/test/fn.test.ts +263 -0
  85. package/test/helpers.ts +23 -0
  86. package/test/index.test.ts +6 -0
  87. package/test/number.test.ts +213 -0
  88. package/test/object.test.ts +309 -0
  89. package/test/path.test.ts +156 -0
  90. package/test/promise.test.ts +199 -0
  91. package/test/qs.test.ts +79 -0
  92. package/test/regexp.test.ts +97 -0
  93. package/test/string.test.ts +150 -0
  94. package/test/time.test.ts +214 -0
  95. package/test/timer.test.ts +114 -0
  96. package/test/tree.test.ts +348 -0
  97. package/test/type.test.ts +226 -0
  98. package/test/unique.test.ts +71 -0
  99. package/test/url.test.ts +136 -0
  100. package/test/version.test.ts +52 -0
  101. package/tsconfig.json +31 -0
  102. package/vite.config.mts +114 -0
  103. package/dist/array.cjs +0 -129
  104. package/dist/array.cjs.map +0 -1
  105. package/dist/array.d.ts +0 -171
  106. package/dist/array.mjs +0 -129
  107. package/dist/array.mjs.map +0 -1
  108. package/dist/async.cjs +0 -219
  109. package/dist/async.cjs.map +0 -1
  110. package/dist/async.d.ts +0 -137
  111. package/dist/async.mjs +0 -219
  112. package/dist/async.mjs.map +0 -1
  113. package/dist/base64.cjs +0 -16
  114. package/dist/base64.cjs.map +0 -1
  115. package/dist/base64.d.ts +0 -7
  116. package/dist/base64.mjs +0 -16
  117. package/dist/base64.mjs.map +0 -1
  118. package/dist/cache.cjs +0 -79
  119. package/dist/cache.cjs.map +0 -1
  120. package/dist/cache.d.ts +0 -90
  121. package/dist/cache.mjs +0 -79
  122. package/dist/cache.mjs.map +0 -1
  123. package/dist/color/distance.d.ts +0 -8
  124. package/dist/color/helpers.d.ts +0 -2
  125. package/dist/color/hex-hsl.d.ts +0 -3
  126. package/dist/color/hex-rgb.d.ts +0 -18
  127. package/dist/color/rgb-hsl.d.ts +0 -23
  128. package/dist/color/rgb-hwb.d.ts +0 -29
  129. package/dist/color/rgb-whiter.d.ts +0 -12
  130. package/dist/color/rgb-xyz.d.ts +0 -22
  131. package/dist/color.cjs +0 -250
  132. package/dist/color.cjs.map +0 -1
  133. package/dist/color.mjs +0 -250
  134. package/dist/color.mjs.map +0 -1
  135. package/dist/const.cjs +0 -14
  136. package/dist/const.cjs.map +0 -1
  137. package/dist/const.mjs +0 -15
  138. package/dist/const.mjs.map +0 -1
  139. package/dist/core.cjs +0 -250
  140. package/dist/core.cjs.map +0 -1
  141. package/dist/core.mjs +0 -251
  142. package/dist/core.mjs.map +0 -1
  143. package/dist/crypto/md5.d.mts +0 -1
  144. package/dist/crypto/sha1.d.mts +0 -1
  145. package/dist/crypto/sha256.d.mts +0 -1
  146. package/dist/crypto/sha512.d.mts +0 -1
  147. package/dist/crypto.cjs +0 -812
  148. package/dist/crypto.cjs.map +0 -1
  149. package/dist/crypto.mjs +0 -812
  150. package/dist/crypto.mjs.map +0 -1
  151. package/dist/date/const.d.ts +0 -6
  152. package/dist/date/core.d.ts +0 -52
  153. package/dist/date/days.d.ts +0 -23
  154. package/dist/date/relative.d.ts +0 -44
  155. package/dist/date/start-end.d.ts +0 -73
  156. package/dist/date/timezone.d.ts +0 -67
  157. package/dist/date/weeks.d.ts +0 -72
  158. package/dist/date.cjs +0 -239
  159. package/dist/date.cjs.map +0 -1
  160. package/dist/date.mjs +0 -241
  161. package/dist/date.mjs.map +0 -1
  162. package/dist/dict.cjs +0 -2
  163. package/dist/dict.cjs.map +0 -1
  164. package/dist/dict.mjs +0 -2
  165. package/dist/dict.mjs.map +0 -1
  166. package/dist/each.cjs +0 -18
  167. package/dist/each.cjs.map +0 -1
  168. package/dist/each.mjs +0 -19
  169. package/dist/each.mjs.map +0 -1
  170. package/dist/easing.cjs +0 -151
  171. package/dist/easing.cjs.map +0 -1
  172. package/dist/easing.d.ts +0 -46
  173. package/dist/easing.mjs +0 -151
  174. package/dist/easing.mjs.map +0 -1
  175. package/dist/emitter.cjs +0 -94
  176. package/dist/emitter.cjs.map +0 -1
  177. package/dist/emitter.d.ts +0 -68
  178. package/dist/emitter.mjs +0 -94
  179. package/dist/emitter.mjs.map +0 -1
  180. package/dist/enum.cjs +0 -58
  181. package/dist/enum.cjs.map +0 -1
  182. package/dist/enum.d.ts +0 -68
  183. package/dist/enum.mjs +0 -58
  184. package/dist/enum.mjs.map +0 -1
  185. package/dist/env.cjs +0 -28
  186. package/dist/env.cjs.map +0 -1
  187. package/dist/env.mjs +0 -28
  188. package/dist/env.mjs.map +0 -1
  189. package/dist/error.cjs +0 -12
  190. package/dist/error.cjs.map +0 -1
  191. package/dist/error.mjs +0 -12
  192. package/dist/error.mjs.map +0 -1
  193. package/dist/exception.cjs +0 -22
  194. package/dist/exception.cjs.map +0 -1
  195. package/dist/exception.d.ts +0 -31
  196. package/dist/exception.mjs +0 -22
  197. package/dist/exception.mjs.map +0 -1
  198. package/dist/fn.cjs +0 -76
  199. package/dist/fn.cjs.map +0 -1
  200. package/dist/fn.d.ts +0 -102
  201. package/dist/fn.mjs +0 -76
  202. package/dist/fn.mjs.map +0 -1
  203. package/dist/index.cjs +0 -5
  204. package/dist/index.cjs.map +0 -1
  205. package/dist/index.d.ts +0 -1
  206. package/dist/index.mjs +0 -5
  207. package/dist/index.mjs.map +0 -1
  208. package/dist/merge.cjs +0 -87
  209. package/dist/merge.cjs.map +0 -1
  210. package/dist/merge.mjs +0 -88
  211. package/dist/merge.mjs.map +0 -1
  212. package/dist/number.cjs +0 -11
  213. package/dist/number.cjs.map +0 -1
  214. package/dist/number.d.ts +0 -137
  215. package/dist/number.mjs +0 -11
  216. package/dist/number.mjs.map +0 -1
  217. package/dist/object/get-set.d.ts +0 -111
  218. package/dist/object/is.d.ts +0 -32
  219. package/dist/object/merge.d.ts +0 -72
  220. package/dist/object.cjs +0 -130
  221. package/dist/object.cjs.map +0 -1
  222. package/dist/object.mjs +0 -130
  223. package/dist/object.mjs.map +0 -1
  224. package/dist/path.cjs +0 -77
  225. package/dist/path.cjs.map +0 -1
  226. package/dist/path.d.ts +0 -82
  227. package/dist/path.mjs +0 -77
  228. package/dist/path.mjs.map +0 -1
  229. package/dist/promise.cjs +0 -62
  230. package/dist/promise.cjs.map +0 -1
  231. package/dist/promise.mjs +0 -62
  232. package/dist/promise.mjs.map +0 -1
  233. package/dist/qs.cjs +0 -47
  234. package/dist/qs.cjs.map +0 -1
  235. package/dist/qs.mjs +0 -47
  236. package/dist/qs.mjs.map +0 -1
  237. package/dist/regexp.cjs +0 -66
  238. package/dist/regexp.cjs.map +0 -1
  239. package/dist/regexp.d.ts +0 -65
  240. package/dist/regexp.mjs +0 -66
  241. package/dist/regexp.mjs.map +0 -1
  242. package/dist/string.cjs +0 -16
  243. package/dist/string.cjs.map +0 -1
  244. package/dist/string.d.ts +0 -80
  245. package/dist/string.mjs +0 -16
  246. package/dist/string.mjs.map +0 -1
  247. package/dist/string2.cjs +0 -147
  248. package/dist/string2.cjs.map +0 -1
  249. package/dist/string2.mjs +0 -148
  250. package/dist/string2.mjs.map +0 -1
  251. package/dist/time/from.d.ts +0 -14
  252. package/dist/time/to.d.ts +0 -38
  253. package/dist/time.cjs +0 -82
  254. package/dist/time.cjs.map +0 -1
  255. package/dist/time.mjs +0 -82
  256. package/dist/time.mjs.map +0 -1
  257. package/dist/timer.cjs +0 -119
  258. package/dist/timer.cjs.map +0 -1
  259. package/dist/timer.d.ts +0 -96
  260. package/dist/timer.mjs.map +0 -1
  261. package/dist/tree.cjs +0 -125
  262. package/dist/tree.cjs.map +0 -1
  263. package/dist/tree.mjs +0 -125
  264. package/dist/tree.mjs.map +0 -1
  265. package/dist/type.cjs +0 -78
  266. package/dist/type.cjs.map +0 -1
  267. package/dist/type.mjs +0 -78
  268. package/dist/type.mjs.map +0 -1
  269. package/dist/types.cjs +0 -2
  270. package/dist/types.cjs.map +0 -1
  271. package/dist/types.mjs +0 -2
  272. package/dist/types.mjs.map +0 -1
  273. package/dist/unique.cjs +0 -46
  274. package/dist/unique.cjs.map +0 -1
  275. package/dist/unique.d.ts +0 -22
  276. package/dist/unique.mjs +0 -46
  277. package/dist/unique.mjs.map +0 -1
  278. package/dist/url.cjs +0 -37
  279. package/dist/url.cjs.map +0 -1
  280. package/dist/url.d.ts +0 -53
  281. package/dist/url.mjs +0 -37
  282. package/dist/url.mjs.map +0 -1
  283. package/dist/version.cjs +0 -33
  284. package/dist/version.cjs.map +0 -1
  285. package/dist/version.d.ts +0 -32
  286. package/dist/version.mjs +0 -33
  287. package/dist/version.mjs.map +0 -1
  288. /package/{dist/color.d.ts → src/color.ts} +0 -0
  289. /package/{dist/date.d.ts → src/date.ts} +0 -0
  290. /package/{dist/dict.d.ts → src/dict.ts} +0 -0
  291. /package/{dist/object.d.ts → src/object.ts} +0 -0
  292. /package/{dist/time.d.ts → src/time.ts} +0 -0
package/dist/time.cjs DELETED
@@ -1,82 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const _const = require("./const.cjs");
4
- const type = require("./type.cjs");
5
- const rules = [
6
- ["years", _const.DATE_YEAR_MS],
7
- ["months", _const.DATE_MONTH_MS],
8
- ["days", _const.DATE_DAY_MS],
9
- ["hours", _const.DATE_HOUR_MS],
10
- ["minutes", _const.DATE_MINUTE_MS],
11
- ["seconds", _const.DATE_SECOND_MS]
12
- ];
13
- function timeFrom(duration) {
14
- const td = type.isString(duration) ? timeParse(duration) : duration;
15
- return rules.reduce((acc, [key, time]) => acc + (td[key] || 0) * time, 0);
16
- }
17
- const durationMatchRules = [
18
- [/(\d+)y/i, "years"],
19
- [/(\d+)M/, "months"],
20
- [/(\d+)d/i, "days"],
21
- [/(\d+)h/i, "hours"],
22
- [/(\d+)m/, "minutes"],
23
- [/(\d+)s/, "seconds"]
24
- ];
25
- function timeParse(duration) {
26
- const result = {};
27
- for (const [regex, key] of durationMatchRules) {
28
- const match = duration.match(regex);
29
- if (match) result[key] = Number(match[1]);
30
- else result[key] = 0;
31
- }
32
- return result;
33
- }
34
- function _timeAbsolute(timeMs, maxPoint) {
35
- const minPoint = "S";
36
- const defines = [
37
- ["D", "days", _const.DATE_DAY_MS],
38
- ["h", "hours", _const.DATE_HOUR_MS],
39
- ["m", "minutes", _const.DATE_MINUTE_MS],
40
- ["s", "seconds", _const.DATE_SECOND_MS],
41
- ["S", "milliseconds", 1]
42
- ];
43
- const minIndex = defines.findIndex((item) => item[0] === maxPoint);
44
- const maxIndex = defines.findIndex((item) => item[0] === minPoint);
45
- let timeMsFinal = timeMs;
46
- const dao = {
47
- years: 0,
48
- months: 0,
49
- days: 0,
50
- hours: 0,
51
- minutes: 0,
52
- seconds: 0,
53
- milliseconds: 0
54
- };
55
- for (let i = minIndex; i <= maxIndex; i++) {
56
- const mode = defines[i];
57
- const base = mode[2];
58
- const value = Math.floor(timeMsFinal / base);
59
- timeMsFinal = timeMsFinal - value * base;
60
- dao[mode[1]] = value;
61
- }
62
- return dao;
63
- }
64
- function timeToDays(timeMs) {
65
- return _timeAbsolute(timeMs, "D");
66
- }
67
- function timeToHours(timeMs) {
68
- return _timeAbsolute(timeMs, "h");
69
- }
70
- function timeToMinutes(timeMs) {
71
- return _timeAbsolute(timeMs, "m");
72
- }
73
- function timeToSeconds(timeMs) {
74
- return _timeAbsolute(timeMs, "s");
75
- }
76
- exports.timeFrom = timeFrom;
77
- exports.timeParse = timeParse;
78
- exports.timeToDays = timeToDays;
79
- exports.timeToHours = timeToHours;
80
- exports.timeToMinutes = timeToMinutes;
81
- exports.timeToSeconds = timeToSeconds;
82
- //# sourceMappingURL=time.cjs.map
package/dist/time.cjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"time.cjs","sources":["../src/time/from.ts","../src/time/to.ts"],"sourcesContent":["// @rer https://day.js.org/docs/en/durations/creating\n\nimport { DATE_DAY_MS, DATE_HOUR_MS, DATE_MINUTE_MS, DATE_MONTH_MS, DATE_SECOND_MS, DATE_YEAR_MS } from '@/date';\nimport { isString } from '@/type';\nimport type { TTimeDuration } from './to';\n\n/**\n * 时间转换规则数组\n * @type {Array<[RegExp, (match: RegExpMatchArray) => number]>}\n * @property {RegExp} 0 - 匹配时间单位正则表达式\n * @property {function} 1 - 将匹配结果转换为毫秒数的函数\n */\nconst rules: [key: keyof TTimeDuration, time: number][] = [\n ['years', DATE_YEAR_MS],\n ['months', DATE_MONTH_MS],\n ['days', DATE_DAY_MS],\n ['hours', DATE_HOUR_MS],\n ['minutes', DATE_MINUTE_MS],\n ['seconds', DATE_SECOND_MS],\n];\n\n/**\n * 将时间持续时间字符串或对象转换为毫秒数\n *\n * @param duration - 可以是时间持续时间字符串(如 '1d2h')或 TTimeDuration 对象\n * @returns 计算得到的总毫秒数\n */\nexport function timeFrom(duration: string | TTimeDuration) {\n const td = isString(duration) ? timeParse(duration) : duration;\n return rules.reduce((acc, [key, time]) => acc + (td[key] || 0) * time, 0);\n}\n\nconst durationMatchRules: [RegExp, key: keyof TTimeDuration][] = [\n [/(\\d+)y/i, 'years'],\n [/(\\d+)M/, 'months'],\n [/(\\d+)d/i, 'days'],\n [/(\\d+)h/i, 'hours'],\n [/(\\d+)m/, 'minutes'],\n [/(\\d+)s/, 'seconds'],\n];\n\n/**\n * 将时长字符串解析为时间对象\n * @param duration - 时长字符串(例如 \"1h30m\")\n * @returns 包含解析后时间单位的对象(小时、分钟等)\n */\nexport function timeParse(duration: string) {\n const result = {} as TTimeDuration;\n\n for (const [regex, key] of durationMatchRules) {\n const match = duration.match(regex);\n if (match) result[key] = Number(match[1]);\n else result[key] = 0;\n }\n\n return result;\n}\n","import { DATE_DAY_MS, DATE_HOUR_MS, DATE_MINUTE_MS, DATE_SECOND_MS } from '../date';\n\nexport type TTimeDuration = {\n years: number;\n months: number;\n /** 天数 */\n days: number;\n /** 小时数 */\n hours: number;\n /** 分钟数 */\n minutes: number;\n /** 秒数 */\n seconds: number;\n /** 毫秒数 */\n milliseconds: number;\n};\n\ntype _TTimeParsePoint = 'D' | 'h' | 'm' | 's' | 'S';\n\n/**\n * 解析时间毫秒数为绝对时间对象\n * @param timeMs 时间毫秒数\n * @param maxPoint 最大时间单位(决定分解的起始单位)\n * @returns 包含时间单位分解结果的对象\n * @example\n * ```typescript\n * // 默认以天为最大单位分解\n * timeInDay(123456789);\n * // { days: 1, hours: 10, minutes: 17, seconds: 36, milliseconds: 789 }\n *\n * // 指定最大单位为分钟,分解到分钟及以下单位\n * timeInMinute(123456789);\n * // { days: 0, hours: 0, minutes: 2057, seconds: 36, milliseconds: 789 }\n * ```\n */\nfunction _timeAbsolute(timeMs: number, maxPoint: _TTimeParsePoint): TTimeDuration {\n const minPoint: _TTimeParsePoint = 'S';\n\n const defines: [point: _TTimeParsePoint, key: keyof TTimeDuration, base: number][] = [\n ['D', 'days', DATE_DAY_MS],\n ['h', 'hours', DATE_HOUR_MS],\n ['m', 'minutes', DATE_MINUTE_MS],\n ['s', 'seconds', DATE_SECOND_MS],\n ['S', 'milliseconds', 1],\n ] as const;\n\n const minIndex = defines.findIndex((item) => item[0] === maxPoint);\n const maxIndex = defines.findIndex((item) => item[0] === minPoint);\n\n let timeMsFinal = timeMs;\n const dao: TTimeDuration = {\n years: 0,\n months: 0,\n days: 0,\n hours: 0,\n minutes: 0,\n seconds: 0,\n milliseconds: 0,\n };\n\n for (let i = minIndex; i <= maxIndex; i++) {\n const mode = defines[i];\n const base = mode[2];\n const value = Math.floor(timeMsFinal / base);\n timeMsFinal = timeMsFinal - value * base;\n dao[mode[1]] = value;\n }\n\n return dao;\n}\n\n/**\n * 将时间毫秒数解析为以天为最大单位的绝对时间对象\n * @param timeMs 时间毫秒数\n * @returns 包含天/小时/分钟/秒/毫秒分解结果的对象\n */\nexport function timeToDays(timeMs: number) {\n return _timeAbsolute(timeMs, 'D');\n}\n\n/**\n * 将时间毫秒数解析为以小时为最大单位的绝对时间对象\n * @param timeMs 时间毫秒数\n * @returns 包含小时/分钟/秒/毫秒分解结果的对象\n */\nexport function timeToHours(timeMs: number) {\n return _timeAbsolute(timeMs, 'h');\n}\n\n/**\n * 将时间毫秒数解析为以分钟为最大单位的绝对时间对象\n * @param timeMs 时间毫秒数\n * @returns 包含分钟/秒/毫秒分解结果的对象\n */\nexport function timeToMinutes(timeMs: number) {\n return _timeAbsolute(timeMs, 'm');\n}\n\n/**\n * 将时间毫秒数解析为以秒为最大单位的绝对时间对象\n * @param timeMs 时间毫秒数\n * @returns 包含秒/毫秒分解结果的对象\n */\nexport function timeToSeconds(timeMs: number) {\n return _timeAbsolute(timeMs, 's');\n}\n"],"names":["DATE_YEAR_MS","DATE_MONTH_MS","DATE_DAY_MS","DATE_HOUR_MS","DATE_MINUTE_MS","DATE_SECOND_MS","isString"],"mappings":";;;;AAYA,MAAM,QAAoD;AAAA,EACxD,CAAC,SAASA,OAAAA,YAAY;AAAA,EACtB,CAAC,UAAUC,OAAAA,aAAa;AAAA,EACxB,CAAC,QAAQC,OAAAA,WAAW;AAAA,EACpB,CAAC,SAASC,OAAAA,YAAY;AAAA,EACtB,CAAC,WAAWC,OAAAA,cAAc;AAAA,EAC1B,CAAC,WAAWC,OAAc,cAAA;AAC5B;AAQO,SAAS,SAAS,UAAkC;AACzD,QAAM,KAAKC,KAAAA,SAAS,QAAQ,IAAI,UAAU,QAAQ,IAAI;AACtD,SAAO,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,MAAM,OAAO,GAAG,GAAG,KAAK,KAAK,MAAM,CAAC;AAC1E;AAEA,MAAM,qBAA2D;AAAA,EAC/D,CAAC,WAAW,OAAO;AAAA,EACnB,CAAC,UAAU,QAAQ;AAAA,EACnB,CAAC,WAAW,MAAM;AAAA,EAClB,CAAC,WAAW,OAAO;AAAA,EACnB,CAAC,UAAU,SAAS;AAAA,EACpB,CAAC,UAAU,SAAS;AACtB;AAOO,SAAS,UAAU,UAAkB;AAC1C,QAAM,SAAS,CAAC;AAEhB,aAAW,CAAC,OAAO,GAAG,KAAK,oBAAoB;AACvC,UAAA,QAAQ,SAAS,MAAM,KAAK;AAClC,QAAI,MAAc,QAAA,GAAG,IAAI,OAAO,MAAM,CAAC,CAAC;AAAA,QACnC,QAAO,GAAG,IAAI;AAAA,EAAA;AAGd,SAAA;AACT;ACrBA,SAAS,cAAc,QAAgB,UAA2C;AAChF,QAAM,WAA6B;AAEnC,QAAM,UAA+E;AAAA,IACnF,CAAC,KAAK,QAAQJ,kBAAW;AAAA,IACzB,CAAC,KAAK,SAASC,mBAAY;AAAA,IAC3B,CAAC,KAAK,WAAWC,qBAAc;AAAA,IAC/B,CAAC,KAAK,WAAWC,qBAAc;AAAA,IAC/B,CAAC,KAAK,gBAAgB,CAAC;AAAA,EACzB;AAEM,QAAA,WAAW,QAAQ,UAAU,CAAC,SAAS,KAAK,CAAC,MAAM,QAAQ;AAC3D,QAAA,WAAW,QAAQ,UAAU,CAAC,SAAS,KAAK,CAAC,MAAM,QAAQ;AAEjE,MAAI,cAAc;AAClB,QAAM,MAAqB;AAAA,IACzB,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,IACT,SAAS;AAAA,IACT,cAAc;AAAA,EAChB;AAEA,WAAS,IAAI,UAAU,KAAK,UAAU,KAAK;AACnC,UAAA,OAAO,QAAQ,CAAC;AAChB,UAAA,OAAO,KAAK,CAAC;AACnB,UAAM,QAAQ,KAAK,MAAM,cAAc,IAAI;AAC3C,kBAAc,cAAc,QAAQ;AAChC,QAAA,KAAK,CAAC,CAAC,IAAI;AAAA,EAAA;AAGV,SAAA;AACT;AAOO,SAAS,WAAW,QAAgB;AAClC,SAAA,cAAc,QAAQ,GAAG;AAClC;AAOO,SAAS,YAAY,QAAgB;AACnC,SAAA,cAAc,QAAQ,GAAG;AAClC;AAOO,SAAS,cAAc,QAAgB;AACrC,SAAA,cAAc,QAAQ,GAAG;AAClC;AAOO,SAAS,cAAc,QAAgB;AACrC,SAAA,cAAc,QAAQ,GAAG;AAClC;;;;;;;"}
package/dist/time.mjs DELETED
@@ -1,82 +0,0 @@
1
- import { D as DATE_YEAR_MS, a as DATE_MONTH_MS, b as DATE_DAY_MS, c as DATE_HOUR_MS, d as DATE_MINUTE_MS, e as DATE_SECOND_MS } from "./const.mjs";
2
- import { isString } from "./type.mjs";
3
- const rules = [
4
- ["years", DATE_YEAR_MS],
5
- ["months", DATE_MONTH_MS],
6
- ["days", DATE_DAY_MS],
7
- ["hours", DATE_HOUR_MS],
8
- ["minutes", DATE_MINUTE_MS],
9
- ["seconds", DATE_SECOND_MS]
10
- ];
11
- function timeFrom(duration) {
12
- const td = isString(duration) ? timeParse(duration) : duration;
13
- return rules.reduce((acc, [key, time]) => acc + (td[key] || 0) * time, 0);
14
- }
15
- const durationMatchRules = [
16
- [/(\d+)y/i, "years"],
17
- [/(\d+)M/, "months"],
18
- [/(\d+)d/i, "days"],
19
- [/(\d+)h/i, "hours"],
20
- [/(\d+)m/, "minutes"],
21
- [/(\d+)s/, "seconds"]
22
- ];
23
- function timeParse(duration) {
24
- const result = {};
25
- for (const [regex, key] of durationMatchRules) {
26
- const match = duration.match(regex);
27
- if (match) result[key] = Number(match[1]);
28
- else result[key] = 0;
29
- }
30
- return result;
31
- }
32
- function _timeAbsolute(timeMs, maxPoint) {
33
- const minPoint = "S";
34
- const defines = [
35
- ["D", "days", DATE_DAY_MS],
36
- ["h", "hours", DATE_HOUR_MS],
37
- ["m", "minutes", DATE_MINUTE_MS],
38
- ["s", "seconds", DATE_SECOND_MS],
39
- ["S", "milliseconds", 1]
40
- ];
41
- const minIndex = defines.findIndex((item) => item[0] === maxPoint);
42
- const maxIndex = defines.findIndex((item) => item[0] === minPoint);
43
- let timeMsFinal = timeMs;
44
- const dao = {
45
- years: 0,
46
- months: 0,
47
- days: 0,
48
- hours: 0,
49
- minutes: 0,
50
- seconds: 0,
51
- milliseconds: 0
52
- };
53
- for (let i = minIndex; i <= maxIndex; i++) {
54
- const mode = defines[i];
55
- const base = mode[2];
56
- const value = Math.floor(timeMsFinal / base);
57
- timeMsFinal = timeMsFinal - value * base;
58
- dao[mode[1]] = value;
59
- }
60
- return dao;
61
- }
62
- function timeToDays(timeMs) {
63
- return _timeAbsolute(timeMs, "D");
64
- }
65
- function timeToHours(timeMs) {
66
- return _timeAbsolute(timeMs, "h");
67
- }
68
- function timeToMinutes(timeMs) {
69
- return _timeAbsolute(timeMs, "m");
70
- }
71
- function timeToSeconds(timeMs) {
72
- return _timeAbsolute(timeMs, "s");
73
- }
74
- export {
75
- timeFrom,
76
- timeParse,
77
- timeToDays,
78
- timeToHours,
79
- timeToMinutes,
80
- timeToSeconds
81
- };
82
- //# sourceMappingURL=time.mjs.map
package/dist/time.mjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"time.mjs","sources":["../src/time/from.ts","../src/time/to.ts"],"sourcesContent":["// @rer https://day.js.org/docs/en/durations/creating\n\nimport { DATE_DAY_MS, DATE_HOUR_MS, DATE_MINUTE_MS, DATE_MONTH_MS, DATE_SECOND_MS, DATE_YEAR_MS } from '@/date';\nimport { isString } from '@/type';\nimport type { TTimeDuration } from './to';\n\n/**\n * 时间转换规则数组\n * @type {Array<[RegExp, (match: RegExpMatchArray) => number]>}\n * @property {RegExp} 0 - 匹配时间单位正则表达式\n * @property {function} 1 - 将匹配结果转换为毫秒数的函数\n */\nconst rules: [key: keyof TTimeDuration, time: number][] = [\n ['years', DATE_YEAR_MS],\n ['months', DATE_MONTH_MS],\n ['days', DATE_DAY_MS],\n ['hours', DATE_HOUR_MS],\n ['minutes', DATE_MINUTE_MS],\n ['seconds', DATE_SECOND_MS],\n];\n\n/**\n * 将时间持续时间字符串或对象转换为毫秒数\n *\n * @param duration - 可以是时间持续时间字符串(如 '1d2h')或 TTimeDuration 对象\n * @returns 计算得到的总毫秒数\n */\nexport function timeFrom(duration: string | TTimeDuration) {\n const td = isString(duration) ? timeParse(duration) : duration;\n return rules.reduce((acc, [key, time]) => acc + (td[key] || 0) * time, 0);\n}\n\nconst durationMatchRules: [RegExp, key: keyof TTimeDuration][] = [\n [/(\\d+)y/i, 'years'],\n [/(\\d+)M/, 'months'],\n [/(\\d+)d/i, 'days'],\n [/(\\d+)h/i, 'hours'],\n [/(\\d+)m/, 'minutes'],\n [/(\\d+)s/, 'seconds'],\n];\n\n/**\n * 将时长字符串解析为时间对象\n * @param duration - 时长字符串(例如 \"1h30m\")\n * @returns 包含解析后时间单位的对象(小时、分钟等)\n */\nexport function timeParse(duration: string) {\n const result = {} as TTimeDuration;\n\n for (const [regex, key] of durationMatchRules) {\n const match = duration.match(regex);\n if (match) result[key] = Number(match[1]);\n else result[key] = 0;\n }\n\n return result;\n}\n","import { DATE_DAY_MS, DATE_HOUR_MS, DATE_MINUTE_MS, DATE_SECOND_MS } from '../date';\n\nexport type TTimeDuration = {\n years: number;\n months: number;\n /** 天数 */\n days: number;\n /** 小时数 */\n hours: number;\n /** 分钟数 */\n minutes: number;\n /** 秒数 */\n seconds: number;\n /** 毫秒数 */\n milliseconds: number;\n};\n\ntype _TTimeParsePoint = 'D' | 'h' | 'm' | 's' | 'S';\n\n/**\n * 解析时间毫秒数为绝对时间对象\n * @param timeMs 时间毫秒数\n * @param maxPoint 最大时间单位(决定分解的起始单位)\n * @returns 包含时间单位分解结果的对象\n * @example\n * ```typescript\n * // 默认以天为最大单位分解\n * timeInDay(123456789);\n * // { days: 1, hours: 10, minutes: 17, seconds: 36, milliseconds: 789 }\n *\n * // 指定最大单位为分钟,分解到分钟及以下单位\n * timeInMinute(123456789);\n * // { days: 0, hours: 0, minutes: 2057, seconds: 36, milliseconds: 789 }\n * ```\n */\nfunction _timeAbsolute(timeMs: number, maxPoint: _TTimeParsePoint): TTimeDuration {\n const minPoint: _TTimeParsePoint = 'S';\n\n const defines: [point: _TTimeParsePoint, key: keyof TTimeDuration, base: number][] = [\n ['D', 'days', DATE_DAY_MS],\n ['h', 'hours', DATE_HOUR_MS],\n ['m', 'minutes', DATE_MINUTE_MS],\n ['s', 'seconds', DATE_SECOND_MS],\n ['S', 'milliseconds', 1],\n ] as const;\n\n const minIndex = defines.findIndex((item) => item[0] === maxPoint);\n const maxIndex = defines.findIndex((item) => item[0] === minPoint);\n\n let timeMsFinal = timeMs;\n const dao: TTimeDuration = {\n years: 0,\n months: 0,\n days: 0,\n hours: 0,\n minutes: 0,\n seconds: 0,\n milliseconds: 0,\n };\n\n for (let i = minIndex; i <= maxIndex; i++) {\n const mode = defines[i];\n const base = mode[2];\n const value = Math.floor(timeMsFinal / base);\n timeMsFinal = timeMsFinal - value * base;\n dao[mode[1]] = value;\n }\n\n return dao;\n}\n\n/**\n * 将时间毫秒数解析为以天为最大单位的绝对时间对象\n * @param timeMs 时间毫秒数\n * @returns 包含天/小时/分钟/秒/毫秒分解结果的对象\n */\nexport function timeToDays(timeMs: number) {\n return _timeAbsolute(timeMs, 'D');\n}\n\n/**\n * 将时间毫秒数解析为以小时为最大单位的绝对时间对象\n * @param timeMs 时间毫秒数\n * @returns 包含小时/分钟/秒/毫秒分解结果的对象\n */\nexport function timeToHours(timeMs: number) {\n return _timeAbsolute(timeMs, 'h');\n}\n\n/**\n * 将时间毫秒数解析为以分钟为最大单位的绝对时间对象\n * @param timeMs 时间毫秒数\n * @returns 包含分钟/秒/毫秒分解结果的对象\n */\nexport function timeToMinutes(timeMs: number) {\n return _timeAbsolute(timeMs, 'm');\n}\n\n/**\n * 将时间毫秒数解析为以秒为最大单位的绝对时间对象\n * @param timeMs 时间毫秒数\n * @returns 包含秒/毫秒分解结果的对象\n */\nexport function timeToSeconds(timeMs: number) {\n return _timeAbsolute(timeMs, 's');\n}\n"],"names":[],"mappings":";;AAYA,MAAM,QAAoD;AAAA,EACxD,CAAC,SAAS,YAAY;AAAA,EACtB,CAAC,UAAU,aAAa;AAAA,EACxB,CAAC,QAAQ,WAAW;AAAA,EACpB,CAAC,SAAS,YAAY;AAAA,EACtB,CAAC,WAAW,cAAc;AAAA,EAC1B,CAAC,WAAW,cAAc;AAC5B;AAQO,SAAS,SAAS,UAAkC;AACzD,QAAM,KAAK,SAAS,QAAQ,IAAI,UAAU,QAAQ,IAAI;AACtD,SAAO,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,MAAM,OAAO,GAAG,GAAG,KAAK,KAAK,MAAM,CAAC;AAC1E;AAEA,MAAM,qBAA2D;AAAA,EAC/D,CAAC,WAAW,OAAO;AAAA,EACnB,CAAC,UAAU,QAAQ;AAAA,EACnB,CAAC,WAAW,MAAM;AAAA,EAClB,CAAC,WAAW,OAAO;AAAA,EACnB,CAAC,UAAU,SAAS;AAAA,EACpB,CAAC,UAAU,SAAS;AACtB;AAOO,SAAS,UAAU,UAAkB;AAC1C,QAAM,SAAS,CAAC;AAEhB,aAAW,CAAC,OAAO,GAAG,KAAK,oBAAoB;AACvC,UAAA,QAAQ,SAAS,MAAM,KAAK;AAClC,QAAI,MAAc,QAAA,GAAG,IAAI,OAAO,MAAM,CAAC,CAAC;AAAA,QACnC,QAAO,GAAG,IAAI;AAAA,EAAA;AAGd,SAAA;AACT;ACrBA,SAAS,cAAc,QAAgB,UAA2C;AAChF,QAAM,WAA6B;AAEnC,QAAM,UAA+E;AAAA,IACnF,CAAC,KAAK,QAAQ,WAAW;AAAA,IACzB,CAAC,KAAK,SAAS,YAAY;AAAA,IAC3B,CAAC,KAAK,WAAW,cAAc;AAAA,IAC/B,CAAC,KAAK,WAAW,cAAc;AAAA,IAC/B,CAAC,KAAK,gBAAgB,CAAC;AAAA,EACzB;AAEM,QAAA,WAAW,QAAQ,UAAU,CAAC,SAAS,KAAK,CAAC,MAAM,QAAQ;AAC3D,QAAA,WAAW,QAAQ,UAAU,CAAC,SAAS,KAAK,CAAC,MAAM,QAAQ;AAEjE,MAAI,cAAc;AAClB,QAAM,MAAqB;AAAA,IACzB,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,IACT,SAAS;AAAA,IACT,cAAc;AAAA,EAChB;AAEA,WAAS,IAAI,UAAU,KAAK,UAAU,KAAK;AACnC,UAAA,OAAO,QAAQ,CAAC;AAChB,UAAA,OAAO,KAAK,CAAC;AACnB,UAAM,QAAQ,KAAK,MAAM,cAAc,IAAI;AAC3C,kBAAc,cAAc,QAAQ;AAChC,QAAA,KAAK,CAAC,CAAC,IAAI;AAAA,EAAA;AAGV,SAAA;AACT;AAOO,SAAS,WAAW,QAAgB;AAClC,SAAA,cAAc,QAAQ,GAAG;AAClC;AAOO,SAAS,YAAY,QAAgB;AACnC,SAAA,cAAc,QAAQ,GAAG;AAClC;AAOO,SAAS,cAAc,QAAgB;AACrC,SAAA,cAAc,QAAQ,GAAG;AAClC;AAOO,SAAS,cAAc,QAAgB;AACrC,SAAA,cAAc,QAAQ,GAAG;AAClC;"}
package/dist/timer.cjs DELETED
@@ -1,119 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const STATUS_READY = 0;
4
- const STATUS_START = 1;
5
- const STATUS_PAUSE = 2;
6
- const STATUS_STOP = 3;
7
- function makeInterval(nextTime, effect) {
8
- let startAt = 0;
9
- let lastAt = 0;
10
- let stopAt = 0;
11
- let pauseAt = 0;
12
- let resumeAt = 0;
13
- let times = 0;
14
- let status = STATUS_READY;
15
- let runningTime = 0;
16
- const execute = () => {
17
- if (status >= STATUS_PAUSE) return;
18
- const now = Date.now();
19
- const intervalTime = lastAt > 0 ? now - lastAt : 0;
20
- runningTime += intervalTime;
21
- lastAt = now;
22
- const state = {
23
- times: ++times,
24
- startAt,
25
- stopAt,
26
- pauseAt,
27
- resumeAt,
28
- currentAt: now,
29
- elapsedTime: startAt > 0 ? now - startAt : 0,
30
- runningTime,
31
- intervalTime
32
- };
33
- if (effect.length === 2) {
34
- effect(state, () => {
35
- nextTime(execute);
36
- });
37
- } else {
38
- effect(state);
39
- nextTime(execute);
40
- }
41
- };
42
- const canStart = () => status === STATUS_READY;
43
- const start = () => {
44
- if (!canStart()) return;
45
- status = STATUS_START;
46
- startAt = Date.now();
47
- execute();
48
- };
49
- const canStop = () => status === STATUS_START;
50
- const stop = () => {
51
- if (!canStop()) return;
52
- status = STATUS_STOP;
53
- stopAt = Date.now();
54
- };
55
- const canPause = () => status === STATUS_START;
56
- const pause = () => {
57
- if (!canPause()) return;
58
- status = STATUS_PAUSE;
59
- pauseAt = Date.now();
60
- };
61
- const canResume = () => status === STATUS_PAUSE;
62
- const resume = () => {
63
- if (!canResume()) return;
64
- status = STATUS_START;
65
- resumeAt = Date.now();
66
- lastAt = resumeAt;
67
- execute();
68
- };
69
- return {
70
- canStart,
71
- canStop,
72
- canPause,
73
- canResume,
74
- start,
75
- stop,
76
- pause,
77
- resume,
78
- execute
79
- };
80
- }
81
- function timeInterval(callback, interval, options) {
82
- let timeId;
83
- const { canStart, canStop, canPause, canResume, start, stop, pause, resume, execute } = makeInterval((call) => {
84
- timeId = setTimeout(call, interval);
85
- }, callback);
86
- return {
87
- start() {
88
- if (!canStart()) return;
89
- if (options == null ? void 0 : options.leading) {
90
- start();
91
- } else {
92
- timeId = setTimeout(start, interval);
93
- }
94
- },
95
- stop() {
96
- if (!canStop()) return;
97
- if (options == null ? void 0 : options.trailing) execute();
98
- clearTimeout(timeId);
99
- stop();
100
- },
101
- pause() {
102
- if (!canPause()) return;
103
- if (options == null ? void 0 : options.trailing) execute();
104
- clearTimeout(timeId);
105
- pause();
106
- },
107
- resume(immediate) {
108
- if (!canResume()) return;
109
- if (immediate || (options == null ? void 0 : options.leading)) {
110
- resume();
111
- } else {
112
- timeId = setTimeout(resume, interval);
113
- }
114
- }
115
- };
116
- }
117
- exports.makeInterval = makeInterval;
118
- exports.timeInterval = timeInterval;
119
- //# sourceMappingURL=timer.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"timer.cjs","sources":["../src/timer.ts"],"sourcesContent":["/**\n * 定时器状态接口\n */\nexport type TTimerState = {\n /**\n * 执行次数\n */\n times: number;\n /**\n * 开始时间戳\n */\n startAt: number;\n /**\n * 停止时间戳\n */\n stopAt: number;\n /**\n * 暂停时间戳\n */\n pauseAt: number;\n /**\n * 恢复时间戳\n */\n resumeAt: number;\n /**\n * 当前时间戳\n */\n currentAt: number;\n /**\n * 总耗时(包括暂停时间)\n */\n elapsedTime: number;\n /**\n * 实际运行时间(不包括暂停时间)\n */\n runningTime: number;\n /**\n * 当前间隔时间\n */\n intervalTime: number;\n};\n\nexport type TTimerHandler = {\n /**\n * 开始\n */\n start: () => void;\n /**\n * 暂停\n */\n pause: () => void;\n /**\n * 恢复\n */\n resume: (immediate?: boolean) => void;\n /**\n * 停止\n */\n stop: () => void;\n};\n\nconst STATUS_READY = 0;\nconst STATUS_START = 1;\nconst STATUS_PAUSE = 2;\nconst STATUS_STOP = 3;\n\n/**\n * 创建间隔定时器核心函数\n *\n * @param nextTime - 用于安排下一次执行的函数\n * @param effect - 每次执行的回调函数,接收定时器状态和可选的next函数\n * @returns 返回包含控制方法的对象\n */\nexport function makeInterval(\n nextTime: (call: () => void) => void,\n effect: (timer: TTimerState, next?: () => void) => unknown,\n) {\n let startAt = 0;\n let lastAt = 0;\n let stopAt = 0;\n let pauseAt = 0;\n let resumeAt = 0;\n let times = 0;\n let status = STATUS_READY;\n let runningTime = 0;\n\n const execute = () => {\n if (status >= STATUS_PAUSE) return;\n\n const now = Date.now();\n const intervalTime = lastAt > 0 ? now - lastAt : 0;\n runningTime += intervalTime;\n lastAt = now;\n const state: TTimerState = {\n times: ++times,\n startAt,\n stopAt,\n pauseAt,\n resumeAt,\n currentAt: now,\n elapsedTime: startAt > 0 ? now - startAt : 0,\n runningTime,\n intervalTime,\n };\n\n if (effect.length === 2) {\n effect(state, () => {\n nextTime(execute);\n });\n } else {\n effect(state);\n nextTime(execute);\n }\n };\n\n const canStart = () => status === STATUS_READY;\n const start = () => {\n if (!canStart()) return;\n status = STATUS_START;\n startAt = Date.now();\n execute();\n };\n\n const canStop = () => status === STATUS_START;\n const stop = () => {\n if (!canStop()) return;\n status = STATUS_STOP;\n stopAt = Date.now();\n };\n\n const canPause = () => status === STATUS_START;\n const pause = () => {\n if (!canPause()) return;\n status = STATUS_PAUSE;\n pauseAt = Date.now();\n };\n\n const canResume = () => status === STATUS_PAUSE;\n const resume = () => {\n if (!canResume()) return;\n status = STATUS_START;\n resumeAt = Date.now();\n lastAt = resumeAt;\n execute();\n };\n\n return {\n canStart,\n canStop,\n canPause,\n canResume,\n start,\n stop,\n pause,\n resume,\n execute,\n };\n}\n\nexport type TTimerOptions = {\n /**\n * 是否在定时器开始时立即执行回调\n */\n leading?: boolean;\n /**\n * 是否在定时器停止时执行最后一次回调\n */\n trailing?: boolean;\n};\n\n/**\n * 创建一个基于 `setTimeout` 的间隔定时器\n *\n * @param callback - 每次间隔执行的回调函数,接收定时器状态和可选的 `next` 函数\n * @param interval - 间隔时间,单位为毫秒\n * @param options - 配置选项\n * @returns {TTimerHandler}\n */\nexport function timeInterval(\n callback: (state: TTimerState, next?: () => void) => unknown,\n interval: number,\n options?: TTimerOptions,\n): TTimerHandler {\n let timeId: number | NodeJS.Timeout;\n const { canStart, canStop, canPause, canResume, start, stop, pause, resume, execute } = makeInterval((call) => {\n timeId = setTimeout(call, interval);\n }, callback);\n\n return {\n start() {\n if (!canStart()) return;\n\n if (options?.leading) {\n start();\n } else {\n timeId = setTimeout(start, interval);\n }\n },\n\n stop() {\n if (!canStop()) return;\n if (options?.trailing) execute();\n\n clearTimeout(timeId);\n stop();\n },\n\n pause() {\n if (!canPause()) return;\n if (options?.trailing) execute();\n\n clearTimeout(timeId);\n pause();\n },\n\n resume(immediate?: boolean) {\n if (!canResume()) return;\n\n if (immediate || options?.leading) {\n resume();\n } else {\n timeId = setTimeout(resume, interval);\n }\n },\n };\n}\n"],"names":[],"mappings":";;AA6DA,MAAM,eAAe;AACrB,MAAM,eAAe;AACrB,MAAM,eAAe;AACrB,MAAM,cAAc;AASJ,SAAA,aACd,UACA,QACA;AACA,MAAI,UAAU;AACd,MAAI,SAAS;AACb,MAAI,SAAS;AACb,MAAI,UAAU;AACd,MAAI,WAAW;AACf,MAAI,QAAQ;AACZ,MAAI,SAAS;AACb,MAAI,cAAc;AAElB,QAAM,UAAU,MAAM;AACpB,QAAI,UAAU,aAAc;AAEtB,UAAA,MAAM,KAAK,IAAI;AACrB,UAAM,eAAe,SAAS,IAAI,MAAM,SAAS;AAClC,mBAAA;AACN,aAAA;AACT,UAAM,QAAqB;AAAA,MACzB,OAAO,EAAE;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,aAAa,UAAU,IAAI,MAAM,UAAU;AAAA,MAC3C;AAAA,MACA;AAAA,IACF;AAEI,QAAA,OAAO,WAAW,GAAG;AACvB,aAAO,OAAO,MAAM;AAClB,iBAAS,OAAO;AAAA,MAAA,CACjB;AAAA,IAAA,OACI;AACL,aAAO,KAAK;AACZ,eAAS,OAAO;AAAA,IAAA;AAAA,EAEpB;AAEM,QAAA,WAAW,MAAM,WAAW;AAClC,QAAM,QAAQ,MAAM;AACd,QAAA,CAAC,WAAY;AACR,aAAA;AACT,cAAU,KAAK,IAAI;AACX,YAAA;AAAA,EACV;AAEM,QAAA,UAAU,MAAM,WAAW;AACjC,QAAM,OAAO,MAAM;AACb,QAAA,CAAC,UAAW;AACP,aAAA;AACT,aAAS,KAAK,IAAI;AAAA,EACpB;AAEM,QAAA,WAAW,MAAM,WAAW;AAClC,QAAM,QAAQ,MAAM;AACd,QAAA,CAAC,WAAY;AACR,aAAA;AACT,cAAU,KAAK,IAAI;AAAA,EACrB;AAEM,QAAA,YAAY,MAAM,WAAW;AACnC,QAAM,SAAS,MAAM;AACf,QAAA,CAAC,YAAa;AACT,aAAA;AACT,eAAW,KAAK,IAAI;AACX,aAAA;AACD,YAAA;AAAA,EACV;AAEO,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAqBgB,SAAA,aACd,UACA,UACA,SACe;AACX,MAAA;AACJ,QAAM,EAAE,UAAU,SAAS,UAAU,WAAW,OAAO,MAAM,OAAO,QAAQ,QAAY,IAAA,aAAa,CAAC,SAAS;AACpG,aAAA,WAAW,MAAM,QAAQ;AAAA,KACjC,QAAQ;AAEJ,SAAA;AAAA,IACL,QAAQ;AACF,UAAA,CAAC,WAAY;AAEjB,UAAI,mCAAS,SAAS;AACd,cAAA;AAAA,MAAA,OACD;AACI,iBAAA,WAAW,OAAO,QAAQ;AAAA,MAAA;AAAA,IAEvC;AAAA,IAEA,OAAO;AACD,UAAA,CAAC,UAAW;AACZ,UAAA,mCAAS,SAAkB,SAAA;AAE/B,mBAAa,MAAM;AACd,WAAA;AAAA,IACP;AAAA,IAEA,QAAQ;AACF,UAAA,CAAC,WAAY;AACb,UAAA,mCAAS,SAAkB,SAAA;AAE/B,mBAAa,MAAM;AACb,YAAA;AAAA,IACR;AAAA,IAEA,OAAO,WAAqB;AACtB,UAAA,CAAC,YAAa;AAEd,UAAA,cAAa,mCAAS,UAAS;AAC1B,eAAA;AAAA,MAAA,OACF;AACI,iBAAA,WAAW,QAAQ,QAAQ;AAAA,MAAA;AAAA,IACtC;AAAA,EAEJ;AACF;;;"}
package/dist/timer.d.ts DELETED
@@ -1,96 +0,0 @@
1
- /**
2
- * 定时器状态接口
3
- */
4
- export type TTimerState = {
5
- /**
6
- * 执行次数
7
- */
8
- times: number;
9
- /**
10
- * 开始时间戳
11
- */
12
- startAt: number;
13
- /**
14
- * 停止时间戳
15
- */
16
- stopAt: number;
17
- /**
18
- * 暂停时间戳
19
- */
20
- pauseAt: number;
21
- /**
22
- * 恢复时间戳
23
- */
24
- resumeAt: number;
25
- /**
26
- * 当前时间戳
27
- */
28
- currentAt: number;
29
- /**
30
- * 总耗时(包括暂停时间)
31
- */
32
- elapsedTime: number;
33
- /**
34
- * 实际运行时间(不包括暂停时间)
35
- */
36
- runningTime: number;
37
- /**
38
- * 当前间隔时间
39
- */
40
- intervalTime: number;
41
- };
42
- export type TTimerHandler = {
43
- /**
44
- * 开始
45
- */
46
- start: () => void;
47
- /**
48
- * 暂停
49
- */
50
- pause: () => void;
51
- /**
52
- * 恢复
53
- */
54
- resume: (immediate?: boolean) => void;
55
- /**
56
- * 停止
57
- */
58
- stop: () => void;
59
- };
60
- /**
61
- * 创建间隔定时器核心函数
62
- *
63
- * @param nextTime - 用于安排下一次执行的函数
64
- * @param effect - 每次执行的回调函数,接收定时器状态和可选的next函数
65
- * @returns 返回包含控制方法的对象
66
- */
67
- export declare function makeInterval(nextTime: (call: () => void) => void, effect: (timer: TTimerState, next?: () => void) => unknown): {
68
- canStart: () => boolean;
69
- canStop: () => boolean;
70
- canPause: () => boolean;
71
- canResume: () => boolean;
72
- start: () => void;
73
- stop: () => void;
74
- pause: () => void;
75
- resume: () => void;
76
- execute: () => void;
77
- };
78
- export type TTimerOptions = {
79
- /**
80
- * 是否在定时器开始时立即执行回调
81
- */
82
- leading?: boolean;
83
- /**
84
- * 是否在定时器停止时执行最后一次回调
85
- */
86
- trailing?: boolean;
87
- };
88
- /**
89
- * 创建一个基于 `setTimeout` 的间隔定时器
90
- *
91
- * @param callback - 每次间隔执行的回调函数,接收定时器状态和可选的 `next` 函数
92
- * @param interval - 间隔时间,单位为毫秒
93
- * @param options - 配置选项
94
- * @returns {TTimerHandler}
95
- */
96
- export declare function timeInterval(callback: (state: TTimerState, next?: () => void) => unknown, interval: number, options?: TTimerOptions): TTimerHandler;
@@ -1 +0,0 @@
1
- {"version":3,"file":"timer.mjs","sources":["../src/timer.ts"],"sourcesContent":["/**\n * 定时器状态接口\n */\nexport type TTimerState = {\n /**\n * 执行次数\n */\n times: number;\n /**\n * 开始时间戳\n */\n startAt: number;\n /**\n * 停止时间戳\n */\n stopAt: number;\n /**\n * 暂停时间戳\n */\n pauseAt: number;\n /**\n * 恢复时间戳\n */\n resumeAt: number;\n /**\n * 当前时间戳\n */\n currentAt: number;\n /**\n * 总耗时(包括暂停时间)\n */\n elapsedTime: number;\n /**\n * 实际运行时间(不包括暂停时间)\n */\n runningTime: number;\n /**\n * 当前间隔时间\n */\n intervalTime: number;\n};\n\nexport type TTimerHandler = {\n /**\n * 开始\n */\n start: () => void;\n /**\n * 暂停\n */\n pause: () => void;\n /**\n * 恢复\n */\n resume: (immediate?: boolean) => void;\n /**\n * 停止\n */\n stop: () => void;\n};\n\nconst STATUS_READY = 0;\nconst STATUS_START = 1;\nconst STATUS_PAUSE = 2;\nconst STATUS_STOP = 3;\n\n/**\n * 创建间隔定时器核心函数\n *\n * @param nextTime - 用于安排下一次执行的函数\n * @param effect - 每次执行的回调函数,接收定时器状态和可选的next函数\n * @returns 返回包含控制方法的对象\n */\nexport function makeInterval(\n nextTime: (call: () => void) => void,\n effect: (timer: TTimerState, next?: () => void) => unknown,\n) {\n let startAt = 0;\n let lastAt = 0;\n let stopAt = 0;\n let pauseAt = 0;\n let resumeAt = 0;\n let times = 0;\n let status = STATUS_READY;\n let runningTime = 0;\n\n const execute = () => {\n if (status >= STATUS_PAUSE) return;\n\n const now = Date.now();\n const intervalTime = lastAt > 0 ? now - lastAt : 0;\n runningTime += intervalTime;\n lastAt = now;\n const state: TTimerState = {\n times: ++times,\n startAt,\n stopAt,\n pauseAt,\n resumeAt,\n currentAt: now,\n elapsedTime: startAt > 0 ? now - startAt : 0,\n runningTime,\n intervalTime,\n };\n\n if (effect.length === 2) {\n effect(state, () => {\n nextTime(execute);\n });\n } else {\n effect(state);\n nextTime(execute);\n }\n };\n\n const canStart = () => status === STATUS_READY;\n const start = () => {\n if (!canStart()) return;\n status = STATUS_START;\n startAt = Date.now();\n execute();\n };\n\n const canStop = () => status === STATUS_START;\n const stop = () => {\n if (!canStop()) return;\n status = STATUS_STOP;\n stopAt = Date.now();\n };\n\n const canPause = () => status === STATUS_START;\n const pause = () => {\n if (!canPause()) return;\n status = STATUS_PAUSE;\n pauseAt = Date.now();\n };\n\n const canResume = () => status === STATUS_PAUSE;\n const resume = () => {\n if (!canResume()) return;\n status = STATUS_START;\n resumeAt = Date.now();\n lastAt = resumeAt;\n execute();\n };\n\n return {\n canStart,\n canStop,\n canPause,\n canResume,\n start,\n stop,\n pause,\n resume,\n execute,\n };\n}\n\nexport type TTimerOptions = {\n /**\n * 是否在定时器开始时立即执行回调\n */\n leading?: boolean;\n /**\n * 是否在定时器停止时执行最后一次回调\n */\n trailing?: boolean;\n};\n\n/**\n * 创建一个基于 `setTimeout` 的间隔定时器\n *\n * @param callback - 每次间隔执行的回调函数,接收定时器状态和可选的 `next` 函数\n * @param interval - 间隔时间,单位为毫秒\n * @param options - 配置选项\n * @returns {TTimerHandler}\n */\nexport function timeInterval(\n callback: (state: TTimerState, next?: () => void) => unknown,\n interval: number,\n options?: TTimerOptions,\n): TTimerHandler {\n let timeId: number | NodeJS.Timeout;\n const { canStart, canStop, canPause, canResume, start, stop, pause, resume, execute } = makeInterval((call) => {\n timeId = setTimeout(call, interval);\n }, callback);\n\n return {\n start() {\n if (!canStart()) return;\n\n if (options?.leading) {\n start();\n } else {\n timeId = setTimeout(start, interval);\n }\n },\n\n stop() {\n if (!canStop()) return;\n if (options?.trailing) execute();\n\n clearTimeout(timeId);\n stop();\n },\n\n pause() {\n if (!canPause()) return;\n if (options?.trailing) execute();\n\n clearTimeout(timeId);\n pause();\n },\n\n resume(immediate?: boolean) {\n if (!canResume()) return;\n\n if (immediate || options?.leading) {\n resume();\n } else {\n timeId = setTimeout(resume, interval);\n }\n },\n };\n}\n"],"names":[],"mappings":"AA6DA,MAAM,eAAe;AACrB,MAAM,eAAe;AACrB,MAAM,eAAe;AACrB,MAAM,cAAc;AASJ,SAAA,aACd,UACA,QACA;AACA,MAAI,UAAU;AACd,MAAI,SAAS;AACb,MAAI,SAAS;AACb,MAAI,UAAU;AACd,MAAI,WAAW;AACf,MAAI,QAAQ;AACZ,MAAI,SAAS;AACb,MAAI,cAAc;AAElB,QAAM,UAAU,MAAM;AACpB,QAAI,UAAU,aAAc;AAEtB,UAAA,MAAM,KAAK,IAAI;AACrB,UAAM,eAAe,SAAS,IAAI,MAAM,SAAS;AAClC,mBAAA;AACN,aAAA;AACT,UAAM,QAAqB;AAAA,MACzB,OAAO,EAAE;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,aAAa,UAAU,IAAI,MAAM,UAAU;AAAA,MAC3C;AAAA,MACA;AAAA,IACF;AAEI,QAAA,OAAO,WAAW,GAAG;AACvB,aAAO,OAAO,MAAM;AAClB,iBAAS,OAAO;AAAA,MAAA,CACjB;AAAA,IAAA,OACI;AACL,aAAO,KAAK;AACZ,eAAS,OAAO;AAAA,IAAA;AAAA,EAEpB;AAEM,QAAA,WAAW,MAAM,WAAW;AAClC,QAAM,QAAQ,MAAM;AACd,QAAA,CAAC,WAAY;AACR,aAAA;AACT,cAAU,KAAK,IAAI;AACX,YAAA;AAAA,EACV;AAEM,QAAA,UAAU,MAAM,WAAW;AACjC,QAAM,OAAO,MAAM;AACb,QAAA,CAAC,UAAW;AACP,aAAA;AACT,aAAS,KAAK,IAAI;AAAA,EACpB;AAEM,QAAA,WAAW,MAAM,WAAW;AAClC,QAAM,QAAQ,MAAM;AACd,QAAA,CAAC,WAAY;AACR,aAAA;AACT,cAAU,KAAK,IAAI;AAAA,EACrB;AAEM,QAAA,YAAY,MAAM,WAAW;AACnC,QAAM,SAAS,MAAM;AACf,QAAA,CAAC,YAAa;AACT,aAAA;AACT,eAAW,KAAK,IAAI;AACX,aAAA;AACD,YAAA;AAAA,EACV;AAEO,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAqBgB,SAAA,aACd,UACA,UACA,SACe;AACX,MAAA;AACJ,QAAM,EAAE,UAAU,SAAS,UAAU,WAAW,OAAO,MAAM,OAAO,QAAQ,QAAY,IAAA,aAAa,CAAC,SAAS;AACpG,aAAA,WAAW,MAAM,QAAQ;AAAA,KACjC,QAAQ;AAEJ,SAAA;AAAA,IACL,QAAQ;AACF,UAAA,CAAC,WAAY;AAEjB,UAAI,mCAAS,SAAS;AACd,cAAA;AAAA,MAAA,OACD;AACI,iBAAA,WAAW,OAAO,QAAQ;AAAA,MAAA;AAAA,IAEvC;AAAA,IAEA,OAAO;AACD,UAAA,CAAC,UAAW;AACZ,UAAA,mCAAS,SAAkB,SAAA;AAE/B,mBAAa,MAAM;AACd,WAAA;AAAA,IACP;AAAA,IAEA,QAAQ;AACF,UAAA,CAAC,WAAY;AACb,UAAA,mCAAS,SAAkB,SAAA;AAE/B,mBAAa,MAAM;AACb,YAAA;AAAA,IACR;AAAA,IAEA,OAAO,WAAqB;AACtB,UAAA,CAAC,YAAa;AAEd,UAAA,cAAa,mCAAS,UAAS;AAC1B,eAAA;AAAA,MAAA,OACF;AACI,iBAAA,WAAW,QAAQ,QAAQ;AAAA,MAAA;AAAA,IACtC;AAAA,EAEJ;AACF;"}
package/dist/tree.cjs DELETED
@@ -1,125 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const array = require("./array.cjs");
4
- const type = require("./type.cjs");
5
- function treeEach(treeList, iterator, breadthFist = false) {
6
- const treeInfoList = [];
7
- let returnFalse = false;
8
- const iterate = (info) => {
9
- if (iterator(info) === false) {
10
- returnFalse = true;
11
- return false;
12
- }
13
- };
14
- const next = (info, walk2) => {
15
- const { item, level, parent, path } = info;
16
- const { children } = item;
17
- if (type.isArray(children)) {
18
- returnFalse = walk2({
19
- ...info,
20
- parent: item,
21
- list: children,
22
- level: level + 1
23
- }) === false;
24
- }
25
- };
26
- const walk = (walker) => {
27
- const { list, level, parent, path } = walker;
28
- const path2 = [...path];
29
- while (parent !== null && path2.length > 0 && path2[path2.length - 1] !== parent) {
30
- path2.pop();
31
- }
32
- array.arrayEach(list, (item, index) => {
33
- if (returnFalse) return false;
34
- const info = {
35
- ...walker,
36
- item,
37
- index,
38
- path: [...path2, item]
39
- };
40
- if (breadthFist) {
41
- treeInfoList.push(info);
42
- } else {
43
- iterate(info);
44
- if (returnFalse) return false;
45
- next(info, walk);
46
- }
47
- });
48
- if (breadthFist) {
49
- while (!returnFalse) {
50
- const info = treeInfoList.shift();
51
- if (!info) break;
52
- iterate(info);
53
- if (returnFalse) break;
54
- next(info, walk);
55
- }
56
- }
57
- return !returnFalse;
58
- };
59
- walk({
60
- list: treeList,
61
- level: 1,
62
- parent: null,
63
- path: []
64
- });
65
- }
66
- function treeFind(treeList, predicate, breadthFist = false) {
67
- let found;
68
- treeEach(
69
- treeList,
70
- (info) => {
71
- if (predicate(info)) {
72
- found = info;
73
- return false;
74
- }
75
- },
76
- breadthFist
77
- );
78
- return found;
79
- }
80
- function deepFlat(deepList, flatten, breadthFist = false) {
81
- const list2 = [];
82
- treeEach(
83
- deepList,
84
- (info) => {
85
- list2.push(flatten(info));
86
- },
87
- breadthFist
88
- );
89
- return list2;
90
- }
91
- function treeFrom(list, options) {
92
- const keyMap = /* @__PURE__ */ new Map();
93
- const freeSet = /* @__PURE__ */ new Set();
94
- const roots = [];
95
- const assign = (info, isFirst = false) => {
96
- const { selfKey, parentKey, item, index } = info;
97
- if (type.isNullish(parentKey)) {
98
- roots.push(item);
99
- } else {
100
- const parent = keyMap.get(parentKey);
101
- if (type.isUndefined(parent)) {
102
- if (isFirst) freeSet.add(info);
103
- } else {
104
- options.appendChild(parent, info);
105
- }
106
- }
107
- };
108
- array.arrayEach(list, (item, index) => {
109
- const selfKey = options.getSelfKey(item, index);
110
- const parentKey = options.getParentKey(item, index);
111
- if (type.isNullish(selfKey)) return;
112
- const info = { selfKey, parentKey, item, index };
113
- keyMap.set(selfKey, info);
114
- assign(info, true);
115
- });
116
- for (const info of freeSet.values()) {
117
- assign(info);
118
- }
119
- return roots;
120
- }
121
- exports.deepFlat = deepFlat;
122
- exports.treeEach = treeEach;
123
- exports.treeFind = treeFind;
124
- exports.treeFrom = treeFrom;
125
- //# sourceMappingURL=tree.cjs.map
package/dist/tree.cjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"tree.cjs","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 TTreeItem = AnyObject & {\n /**\n * 子节点列表。\n */\n children?: TTreeItem[];\n};\n\n/**\n * 表示深度遍历中的节点列表。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TTreeList<I extends TTreeItem> = I[];\n\n/**\n * 表示深度遍历中的遍历器状态。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TTreeWalker<I extends TTreeItem> = {\n /**\n * 当前层级的节点列表。\n */\n list: TTreeList<I>;\n\n /**\n * 当前节点的父节点,如果为根节点则为 `null`。\n */\n parent: I | null;\n\n /**\n * 当前节点的层级,从 1 开始计数。\n */\n level: number;\n\n /**\n * 从根节点到当前节点的路径。\n */\n path: TTreeList<I>;\n};\n\n/**\n * 表示深度遍历中的节点信息。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n */\nexport type TTreeInfo<I extends TTreeItem> = TTreeWalker<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 TTreeItem> = (info: TTreeInfo<I>) => false | unknown;\n\n/**\n * 深度遍历的异步迭代器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param info - 当前节点的信息。\n * @returns 如果返回 `false`,则提前终止遍历。\n */\nexport type TreeEachIteratorAsync<I extends TTreeItem> = (info: TTreeInfo<I>) => Promise<boolean | unknown>;\n\n/**\n * 深度遍历的同步遍历器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param walker - 遍历器状态。\n * @returns 遍历结果。\n */\nexport type TreeWalk<I extends TTreeItem> = (walker: TTreeWalker<I>) => unknown;\n\n/**\n * 深度遍历的异步遍历器函数类型。\n *\n * @template I - 节点对象的类型,必须继承自 `TreeItem`。\n * @param walker - 遍历器状态。\n * @returns 异步遍历结果。\n */\nexport type TreeWalkAsync<I extends TTreeItem> = (walker: TTreeWalker<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 TTreeItem = TTreeItem>(\n treeList: TTreeList<I>,\n iterator: TreeEachIterator<I>,\n breadthFist = false,\n): void {\n const treeInfoList: TTreeInfo<I>[] = [];\n let returnFalse = false;\n\n const iterate = (info: TTreeInfo<I>) => {\n if (iterator(info) === false) {\n returnFalse = true;\n return false;\n }\n };\n\n const next = (info: TTreeInfo<I>, walk: TreeWalk<I>) => {\n const { item, level, parent, path } = info;\n const { children } = item;\n\n if (isArray(children)) {\n returnFalse =\n walk({\n ...info,\n parent: item,\n list: children as TTreeList<I>,\n level: level + 1,\n }) === false;\n }\n };\n\n const walk: TreeWalk<I> = (walker) => {\n const { list, level, 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: TTreeInfo<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 TTreeItem>(\n treeList: TTreeList<I>,\n predicate: (info: TTreeInfo<I>) => boolean,\n breadthFist = false,\n): TTreeInfo<I> | undefined {\n let found: TTreeInfo<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 {TTreeList<I>} deepList - 要扁平化的深度嵌套树形结构。\n * @param {(info: TTreeInfo<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 TTreeItem, T>(\n deepList: TTreeList<I>,\n flatten: (info: TTreeInfo<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 TTreeFromOptions<I extends TTreeItem> = {\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 {TTreeFromOptions<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 TTreeItem>(list: I[], options: TTreeFromOptions<I>): TTreeList<I> | undefined {\n const keyMap = new Map<unknown, FromItemInfo<I>>();\n const freeSet = new Set<FromItemInfo<I>>();\n const roots: TTreeList<I> = [];\n\n // 分配节点\n const assign = (info: FromItemInfo<I>, isFirst = false) => {\n const { selfKey, parentKey, item, index } = 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"],"names":["walk","isArray","arrayEach","isNullish","isUndefined"],"mappings":";;;;AA0HO,SAAS,SACd,UACA,UACA,cAAc,OACR;AACN,QAAM,eAA+B,CAAC;AACtC,MAAI,cAAc;AAEZ,QAAA,UAAU,CAAC,SAAuB;AAClC,QAAA,SAAS,IAAI,MAAM,OAAO;AACd,oBAAA;AACP,aAAA;AAAA,IAAA;AAAA,EAEX;AAEM,QAAA,OAAO,CAAC,MAAoBA,UAAsB;AACtD,UAAM,EAAE,MAAM,OAAO,QAAQ,KAAS,IAAA;AAChC,UAAA,EAAE,aAAa;AAEjB,QAAAC,KAAAA,QAAQ,QAAQ,GAAG;AACrB,oBACED,MAAK;AAAA,QACH,GAAG;AAAA,QACH,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,MAChB,CAAA,MAAM;AAAA,IAAA;AAAA,EAEb;AAEM,QAAA,OAAoB,CAAC,WAAW;AACpC,UAAM,EAAE,MAAM,OAAO,QAAQ,KAAS,IAAA;AAEhC,UAAA,QAAQ,CAAC,GAAG,IAAI;AACf,WAAA,WAAW,QAAQ,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,CAAC,MAAM,QAAQ;AAChF,YAAM,IAAI;AAAA,IAAA;AAGFE,UAAAA,UAAA,MAAM,CAAC,MAAM,UAAU;AAC/B,UAAI,YAAoB,QAAA;AAExB,YAAM,OAAqB;AAAA,QACzB,GAAG;AAAA,QACH;AAAA,QACA;AAAA,QACA,MAAM,CAAC,GAAG,OAAO,IAAI;AAAA,MACvB;AAGA,UAAI,aAAa;AACf,qBAAa,KAAK,IAAI;AAAA,MAAA,OAGnB;AACH,gBAAQ,IAAI;AACZ,YAAI,YAAoB,QAAA;AACxB,aAAK,MAAM,IAAI;AAAA,MAAA;AAAA,IACjB,CACD;AAED,QAAI,aAAa;AACf,aAAO,CAAC,aAAa;AACb,cAAA,OAAO,aAAa,MAAM;AAChC,YAAI,CAAC,KAAM;AAEX,gBAAQ,IAAI;AACZ,YAAI,YAAa;AAGjB,aAAK,MAAM,IAAI;AAAA,MAAA;AAAA,IACjB;AAGF,WAAO,CAAC;AAAA,EACV;AAEK,OAAA;AAAA,IACH,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM,CAAA;AAAA,EAAC,CACR;AACH;AA6BO,SAAS,SACd,UACA,WACA,cAAc,OACY;AACtB,MAAA;AAEJ;AAAA,IACE;AAAA,IACA,CAAC,SAAS;AACJ,UAAA,UAAU,IAAI,GAAG;AACX,gBAAA;AACD,eAAA;AAAA,MAAA;AAAA,IAEX;AAAA,IACA;AAAA,EACF;AAEO,SAAA;AACT;AAsBO,SAAS,SACd,UACA,SACA,cAAc,OACT;AACL,QAAM,QAAa,CAAC;AAEpB;AAAA,IACE;AAAA,IACA,CAAC,SAAS;AACF,YAAA,KAAK,QAAQ,IAAI,CAAC;AAAA,IAC1B;AAAA,IACA;AAAA,EACF;AAEO,SAAA;AACT;AAuDgB,SAAA,SAA8B,MAAW,SAAwD;AACzG,QAAA,6BAAa,IAA8B;AAC3C,QAAA,8BAAc,IAAqB;AACzC,QAAM,QAAsB,CAAC;AAG7B,QAAM,SAAS,CAAC,MAAuB,UAAU,UAAU;AACzD,UAAM,EAAE,SAAS,WAAW,MAAM,MAAU,IAAA;AAGxC,QAAAC,KAAAA,UAAU,SAAS,GAAG;AACxB,YAAM,KAAK,IAAI;AAAA,IAAA,OAGZ;AACG,YAAA,SAAS,OAAO,IAAI,SAAS;AAG/B,UAAAC,KAAAA,YAAY,MAAM,GAAG;AAEnB,YAAA,QAAiB,SAAA,IAAI,IAAI;AAAA,MAAA,OAG1B;AACK,gBAAA,YAAY,QAAQ,IAAI;AAAA,MAAA;AAAA,IAClC;AAAA,EAEJ;AAGUF,QAAAA,UAAA,MAAM,CAAC,MAAM,UAAU;AAC/B,UAAM,UAAU,QAAQ,WAAW,MAAM,KAAK;AAC9C,UAAM,YAAY,QAAQ,aAAa,MAAM,KAAK;AAE9C,QAAAC,KAAAA,UAAU,OAAO,EAAG;AAExB,UAAM,OAAO,EAAE,SAAS,WAAW,MAAM,MAAM;AACxC,WAAA,IAAI,SAAS,IAAI;AAExB,WAAO,MAAM,IAAI;AAAA,EAAA,CAClB;AAGU,aAAA,QAAQ,QAAQ,UAAU;AACnC,WAAO,IAAI;AAAA,EAAA;AAGN,SAAA;AACT;;;;;"}