@cloudcome/utils-core 1.2.0 → 1.2.2

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 (51) hide show
  1. package/README.md +18 -0
  2. package/dist/async.cjs.map +1 -1
  3. package/dist/async.d.ts +3 -3
  4. package/dist/async.mjs.map +1 -1
  5. package/dist/cache.cjs.map +1 -1
  6. package/dist/cache.d.ts +14 -14
  7. package/dist/cache.mjs.map +1 -1
  8. package/dist/core.cjs.map +1 -1
  9. package/dist/core.mjs.map +1 -1
  10. package/dist/date/core.d.ts +4 -4
  11. package/dist/date/days.d.ts +3 -3
  12. package/dist/date/is.d.ts +7 -7
  13. package/dist/date/relative.d.ts +10 -10
  14. package/dist/date/start-end.d.ts +13 -13
  15. package/dist/date/timezone.d.ts +2 -2
  16. package/dist/date/weeks.d.ts +4 -4
  17. package/dist/date.cjs.map +1 -1
  18. package/dist/date.mjs.map +1 -1
  19. package/dist/enum.cjs +1 -1
  20. package/dist/enum.cjs.map +1 -1
  21. package/dist/enum.d.ts +1 -1
  22. package/dist/enum.mjs +1 -1
  23. package/dist/enum.mjs.map +1 -1
  24. package/dist/fn.cjs.map +1 -1
  25. package/dist/fn.d.ts +4 -4
  26. package/dist/fn.mjs.map +1 -1
  27. package/dist/index.cjs +1 -1
  28. package/dist/index.mjs +1 -1
  29. package/dist/merge.cjs.map +1 -1
  30. package/dist/merge.mjs.map +1 -1
  31. package/dist/object/get-set.d.ts +14 -14
  32. package/dist/object/merge.d.ts +1 -1
  33. package/dist/object.cjs.map +1 -1
  34. package/dist/object.mjs.map +1 -1
  35. package/dist/time/from.d.ts +4 -4
  36. package/dist/time/to.d.ts +5 -5
  37. package/dist/time.cjs.map +1 -1
  38. package/dist/time.mjs.map +1 -1
  39. package/dist/timer.cjs.map +1 -1
  40. package/dist/timer.d.ts +6 -6
  41. package/dist/timer.mjs.map +1 -1
  42. package/dist/tree.cjs.map +1 -1
  43. package/dist/tree.d.ts +19 -19
  44. package/dist/tree.mjs.map +1 -1
  45. package/dist/url.cjs.map +1 -1
  46. package/dist/url.d.ts +6 -6
  47. package/dist/url.mjs.map +1 -1
  48. package/dist/version.cjs.map +1 -1
  49. package/dist/version.d.ts +2 -2
  50. package/dist/version.mjs.map +1 -1
  51. package/package.json +1 -1
@@ -1 +1 @@
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;;;"}
1
+ {"version":3,"file":"timer.cjs","sources":["../src/timer.ts"],"sourcesContent":["/**\n * 定时器状态接口\n */\nexport type TimerState = {\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 TimerHandler = {\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: TimerState, 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: TimerState = {\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 TimerOptions = {\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 {TimerHandler}\n */\nexport function timeInterval(\n callback: (state: TimerState, next?: () => void) => unknown,\n interval: number,\n options?: TimerOptions,\n): TimerHandler {\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,QAAoB;AAAA,MACxB,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,SACc;AACV,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 CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 定时器状态接口
3
3
  */
4
- export type TTimerState = {
4
+ export type TimerState = {
5
5
  /**
6
6
  * 执行次数
7
7
  */
@@ -39,7 +39,7 @@ export type TTimerState = {
39
39
  */
40
40
  intervalTime: number;
41
41
  };
42
- export type TTimerHandler = {
42
+ export type TimerHandler = {
43
43
  /**
44
44
  * 开始
45
45
  */
@@ -64,7 +64,7 @@ export type TTimerHandler = {
64
64
  * @param effect - 每次执行的回调函数,接收定时器状态和可选的next函数
65
65
  * @returns 返回包含控制方法的对象
66
66
  */
67
- export declare function makeInterval(nextTime: (call: () => void) => void, effect: (timer: TTimerState, next?: () => void) => unknown): {
67
+ export declare function makeInterval(nextTime: (call: () => void) => void, effect: (timer: TimerState, next?: () => void) => unknown): {
68
68
  canStart: () => boolean;
69
69
  canStop: () => boolean;
70
70
  canPause: () => boolean;
@@ -75,7 +75,7 @@ export declare function makeInterval(nextTime: (call: () => void) => void, effec
75
75
  resume: () => void;
76
76
  execute: () => void;
77
77
  };
78
- export type TTimerOptions = {
78
+ export type TimerOptions = {
79
79
  /**
80
80
  * 是否在定时器开始时立即执行回调
81
81
  */
@@ -91,6 +91,6 @@ export type TTimerOptions = {
91
91
  * @param callback - 每次间隔执行的回调函数,接收定时器状态和可选的 `next` 函数
92
92
  * @param interval - 间隔时间,单位为毫秒
93
93
  * @param options - 配置选项
94
- * @returns {TTimerHandler}
94
+ * @returns {TimerHandler}
95
95
  */
96
- export declare function timeInterval(callback: (state: TTimerState, next?: () => void) => unknown, interval: number, options?: TTimerOptions): TTimerHandler;
96
+ export declare function timeInterval(callback: (state: TimerState, next?: () => void) => unknown, interval: number, options?: TimerOptions): TimerHandler;
@@ -1 +1 @@
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;"}
1
+ {"version":3,"file":"timer.mjs","sources":["../src/timer.ts"],"sourcesContent":["/**\n * 定时器状态接口\n */\nexport type TimerState = {\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 TimerHandler = {\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: TimerState, 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: TimerState = {\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 TimerOptions = {\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 {TimerHandler}\n */\nexport function timeInterval(\n callback: (state: TimerState, next?: () => void) => unknown,\n interval: number,\n options?: TimerOptions,\n): TimerHandler {\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,QAAoB;AAAA,MACxB,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,SACc;AACV,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.map CHANGED
@@ -1 +1 @@
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;;;;;"}
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 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, 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 TreeList<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: 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 { 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":"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"}
package/dist/tree.d.ts CHANGED
@@ -2,28 +2,28 @@ import { AnyObject } from './types';
2
2
  /**
3
3
  * 表示深度遍历中的节点对象,包含子节点列表。
4
4
  */
5
- export type TTreeItem = AnyObject & {
5
+ export type TreeItem = AnyObject & {
6
6
  /**
7
7
  * 子节点列表。
8
8
  */
9
- children?: TTreeItem[];
9
+ children?: TreeItem[];
10
10
  };
11
11
  /**
12
12
  * 表示深度遍历中的节点列表。
13
13
  *
14
14
  * @template I - 节点对象的类型,必须继承自 `TreeItem`。
15
15
  */
16
- export type TTreeList<I extends TTreeItem> = I[];
16
+ export type TreeList<I extends TreeItem> = I[];
17
17
  /**
18
18
  * 表示深度遍历中的遍历器状态。
19
19
  *
20
20
  * @template I - 节点对象的类型,必须继承自 `TreeItem`。
21
21
  */
22
- export type TTreeWalker<I extends TTreeItem> = {
22
+ export type TreeWalker<I extends TreeItem> = {
23
23
  /**
24
24
  * 当前层级的节点列表。
25
25
  */
26
- list: TTreeList<I>;
26
+ list: TreeList<I>;
27
27
  /**
28
28
  * 当前节点的父节点,如果为根节点则为 `null`。
29
29
  */
@@ -35,14 +35,14 @@ export type TTreeWalker<I extends TTreeItem> = {
35
35
  /**
36
36
  * 从根节点到当前节点的路径。
37
37
  */
38
- path: TTreeList<I>;
38
+ path: TreeList<I>;
39
39
  };
40
40
  /**
41
41
  * 表示深度遍历中的节点信息。
42
42
  *
43
43
  * @template I - 节点对象的类型,必须继承自 `TreeItem`。
44
44
  */
45
- export type TTreeInfo<I extends TTreeItem> = TTreeWalker<I> & {
45
+ export type TreeInfo<I extends TreeItem> = TreeWalker<I> & {
46
46
  /**
47
47
  * 当前节点。
48
48
  */
@@ -59,7 +59,7 @@ export type TTreeInfo<I extends TTreeItem> = TTreeWalker<I> & {
59
59
  * @param info - 当前节点的信息。
60
60
  * @returns 如果返回 `false`,则提前终止遍历。
61
61
  */
62
- export type TreeEachIterator<I extends TTreeItem> = (info: TTreeInfo<I>) => false | unknown;
62
+ export type TreeEachIterator<I extends TreeItem> = (info: TreeInfo<I>) => false | unknown;
63
63
  /**
64
64
  * 深度遍历的异步迭代器函数类型。
65
65
  *
@@ -67,7 +67,7 @@ export type TreeEachIterator<I extends TTreeItem> = (info: TTreeInfo<I>) => fals
67
67
  * @param info - 当前节点的信息。
68
68
  * @returns 如果返回 `false`,则提前终止遍历。
69
69
  */
70
- export type TreeEachIteratorAsync<I extends TTreeItem> = (info: TTreeInfo<I>) => Promise<boolean | unknown>;
70
+ export type TreeEachIteratorAsync<I extends TreeItem> = (info: TreeInfo<I>) => Promise<boolean | unknown>;
71
71
  /**
72
72
  * 深度遍历的同步遍历器函数类型。
73
73
  *
@@ -75,7 +75,7 @@ export type TreeEachIteratorAsync<I extends TTreeItem> = (info: TTreeInfo<I>) =>
75
75
  * @param walker - 遍历器状态。
76
76
  * @returns 遍历结果。
77
77
  */
78
- export type TreeWalk<I extends TTreeItem> = (walker: TTreeWalker<I>) => unknown;
78
+ export type TreeWalk<I extends TreeItem> = (walker: TreeWalker<I>) => unknown;
79
79
  /**
80
80
  * 深度遍历的异步遍历器函数类型。
81
81
  *
@@ -83,7 +83,7 @@ export type TreeWalk<I extends TTreeItem> = (walker: TTreeWalker<I>) => unknown;
83
83
  * @param walker - 遍历器状态。
84
84
  * @returns 异步遍历结果。
85
85
  */
86
- export type TreeWalkAsync<I extends TTreeItem> = (walker: TTreeWalker<I>) => Promise<unknown>;
86
+ export type TreeWalkAsync<I extends TreeItem> = (walker: TreeWalker<I>) => Promise<unknown>;
87
87
  /**
88
88
  * 深度遍历数组中的每个元素,并对每个元素执行提供的回调函数。
89
89
  *
@@ -105,7 +105,7 @@ export type TreeWalkAsync<I extends TTreeItem> = (walker: TTreeWalker<I>) => Pro
105
105
  * });
106
106
  * ```
107
107
  */
108
- export declare function treeEach<I extends TTreeItem = TTreeItem>(treeList: TTreeList<I>, iterator: TreeEachIterator<I>, breadthFist?: boolean): void;
108
+ export declare function treeEach<I extends TreeItem = TreeItem>(treeList: TreeList<I>, iterator: TreeEachIterator<I>, breadthFist?: boolean): void;
109
109
  /**
110
110
  * 在深度数组中查找满足条件的第一个节点信息。
111
111
  *
@@ -133,14 +133,14 @@ export declare function treeEach<I extends TTreeItem = TTreeItem>(treeList: TTre
133
133
  * // }
134
134
  * ```
135
135
  */
136
- export declare function treeFind<I extends TTreeItem>(treeList: TTreeList<I>, predicate: (info: TTreeInfo<I>) => boolean, breadthFist?: boolean): TTreeInfo<I> | undefined;
136
+ export declare function treeFind<I extends TreeItem>(treeList: TreeList<I>, predicate: (info: TreeInfo<I>) => boolean, breadthFist?: boolean): TreeInfo<I> | undefined;
137
137
  /**
138
138
  * 将深度嵌套的树形结构扁平化为一维数组,并对每个节点执行指定的转换函数。
139
139
  *
140
140
  * @template I - 树节点的类型,必须继承自 `TreeItem`。
141
141
  * @template T - 转换后的数据类型。
142
- * @param {TTreeList<I>} deepList - 要扁平化的深度嵌套树形结构。
143
- * @param {(info: TTreeInfo<I>) => T} flatten - 对每个节点执行的转换函数,返回转换后的数据。
142
+ * @param {TreeList<I>} deepList - 要扁平化的深度嵌套树形结构。
143
+ * @param {(info: TreeInfo<I>) => T} flatten - 对每个节点执行的转换函数,返回转换后的数据。
144
144
  * @param {boolean} [breadthFist=false] - 是否使用广度优先遍历,默认为 `false`(深度优先)。
145
145
  * @returns {T[]} - 转换后的一维数组。
146
146
  * @example
@@ -154,14 +154,14 @@ export declare function treeFind<I extends TTreeItem>(treeList: TTreeList<I>, pr
154
154
  * console.log(flattened); // [1, 2, 3, 4]
155
155
  * ```
156
156
  */
157
- export declare function deepFlat<I extends TTreeItem, T>(deepList: TTreeList<I>, flatten: (info: TTreeInfo<I>) => T, breadthFist?: boolean): T[];
157
+ export declare function deepFlat<I extends TreeItem, T>(deepList: TreeList<I>, flatten: (info: TreeInfo<I>) => T, breadthFist?: boolean): T[];
158
158
  type FromItemInfo<I> = {
159
159
  selfKey: unknown;
160
160
  parentKey: unknown;
161
161
  item: I;
162
162
  index: number;
163
163
  };
164
- export type TTreeFromOptions<I extends TTreeItem> = {
164
+ export type TreeFromOptions<I extends TreeItem> = {
165
165
  getSelfKey: (item: I, index: number) => unknown;
166
166
  getParentKey: (item: I, index: number) => unknown;
167
167
  appendChild: (parentInfo: FromItemInfo<I>, info: FromItemInfo<I>) => unknown;
@@ -171,7 +171,7 @@ export type TTreeFromOptions<I extends TTreeItem> = {
171
171
  *
172
172
  * @template I - 节点对象的类型,必须继承自 `AnyObject`。
173
173
  * @param {I[]} list - 扁平化的节点列表。
174
- * @param {TTreeFromOptions<I>} options - 构建树形结构的配置选项。
174
+ * @param {TreeFromOptions<I>} options - 构建树形结构的配置选项。
175
175
  * @param {function} options.getSelfKey - 获取节点自身唯一标识的函数。
176
176
  * @param {function} options.getParentKey - 获取节点父节点唯一标识的函数。
177
177
  * @param {function} options.appendChild - 将子节点添加到父节点的函数。
@@ -206,5 +206,5 @@ export type TTreeFromOptions<I extends TTreeItem> = {
206
206
  * // }
207
207
  * ```
208
208
  */
209
- export declare function treeFrom<I extends TTreeItem>(list: I[], options: TTreeFromOptions<I>): TTreeList<I> | undefined;
209
+ export declare function treeFrom<I extends TreeItem>(list: I[], options: TreeFromOptions<I>): TreeList<I> | undefined;
210
210
  export {};
package/dist/tree.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tree.mjs","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"],"mappings":"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"}
1
+ {"version":3,"file":"tree.mjs","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, 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 TreeList<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: 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 { 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"],"mappings":"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"}
package/dist/url.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"url.cjs","sources":["../src/url.ts"],"sourcesContent":["/**\n * 表示解析后的 URL 组件。\n */\nexport type TURLMeta = {\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): TURLMeta {\n let result: URL | null = null;\n\n try {\n // 添加 globalThis 是便于对接外部环境 URL 的自行实现\n // 例如在 uni-app、微信小程序等运行环境。\n result = new globalThis.URL(url);\n } catch (e) {\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 * 将 URLInfo 对象转换回 URL 字符串。\n * @param url - 需要转换的 URLInfo 对象。\n * @returns 转换后的 URL 字符串。\n */\nexport function urlStringify(url: TURLMeta) {\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"],"names":[],"mappings":";;AA+CO,SAAS,SAAS,KAAuB;AAC9C,MAAI,SAAqB;AAErB,MAAA;AAGO,aAAA,IAAI,WAAW,IAAI,GAAG;AAAA,WACxB,GAAG;AAAA,EAAA;AAIN,QAAA,YAAW,iCAAQ,aAAY;AAC/B,QAAA,QAAO,iCAAQ,SAAQ;AAEtB,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAU,iCAAQ,aAAY;AAAA,IAC9B,OAAM,iCAAQ,SAAQ;AAAA,IACtB,WAAU,iCAAQ,aAAY;AAAA,IAC9B,SAAQ,iCAAQ,WAAU;AAAA,IAC1B,OAAM,iCAAQ,SAAQ;AAAA,IACtB,WAAU,iCAAQ,aAAY;AAAA,IAC9B,WAAU,iCAAQ,aAAY;AAAA,EAChC;AACF;AAOO,SAAS,aAAa,KAAe;AACpC,QAAA,EAAE,UAAU,UAAU,MAAM,UAAU,QAAQ,MAAM,UAAU,SAAA,IAAa;AAC1E,SAAA;AAAA,IACL,WAAW,GAAG,QAAQ,OAAO;AAAA,IAC7B,YAAY,WAAW,GAAG,QAAQ,IAAI,QAAQ,MAAM;AAAA,IACpD;AAAA,IACA,OAAO,IAAI,IAAI,KAAK;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,EAEC,EAAA,OAAO,OAAO,EACd,KAAK,EAAE;AACZ;;;"}
1
+ {"version":3,"file":"url.cjs","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 (e) {\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"],"names":[],"mappings":";;AA+CO,SAAS,SAAS,KAAsB;AAC7C,MAAI,SAAqB;AAErB,MAAA;AAGO,aAAA,IAAI,WAAW,IAAI,GAAG;AAAA,WACxB,GAAG;AAAA,EAAA;AAIN,QAAA,YAAW,iCAAQ,aAAY;AAC/B,QAAA,QAAO,iCAAQ,SAAQ;AAEtB,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAU,iCAAQ,aAAY;AAAA,IAC9B,OAAM,iCAAQ,SAAQ;AAAA,IACtB,WAAU,iCAAQ,aAAY;AAAA,IAC9B,SAAQ,iCAAQ,WAAU;AAAA,IAC1B,OAAM,iCAAQ,SAAQ;AAAA,IACtB,WAAU,iCAAQ,aAAY;AAAA,IAC9B,WAAU,iCAAQ,aAAY;AAAA,EAChC;AACF;AAOO,SAAS,aAAa,KAAc;AACnC,QAAA,EAAE,UAAU,UAAU,MAAM,UAAU,QAAQ,MAAM,UAAU,SAAA,IAAa;AAC1E,SAAA;AAAA,IACL,WAAW,GAAG,QAAQ,OAAO;AAAA,IAC7B,YAAY,WAAW,GAAG,QAAQ,IAAI,QAAQ,MAAM;AAAA,IACpD;AAAA,IACA,OAAO,IAAI,IAAI,KAAK;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,EAEC,EAAA,OAAO,OAAO,EACd,KAAK,EAAE;AACZ;;;"}
package/dist/url.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
- * 表示解析后的 URL 组件。
2
+ * URL 元信息
3
3
  */
4
- export type TURLMeta = {
4
+ export type UrlMeta = {
5
5
  /**
6
6
  * 协议部分,包含冒号,例如 "https:"。
7
7
  */
@@ -44,10 +44,10 @@ export type TURLMeta = {
44
44
  * @param url - 需要解析的 URL 字符串。
45
45
  * @returns 包含解析后 URL 组件的对象。
46
46
  */
47
- export declare function urlParse(url: string): TURLMeta;
47
+ export declare function urlParse(url: string): UrlMeta;
48
48
  /**
49
- * 将 URLInfo 对象转换回 URL 字符串。
50
- * @param url - 需要转换的 URLInfo 对象。
49
+ * 将 UrlMeta 对象转换回 URL 字符串。
50
+ * @param url - 需要转换的 UrlMeta 对象。
51
51
  * @returns 转换后的 URL 字符串。
52
52
  */
53
- export declare function urlStringify(url: TURLMeta): string;
53
+ export declare function urlStringify(url: UrlMeta): string;
package/dist/url.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"url.mjs","sources":["../src/url.ts"],"sourcesContent":["/**\n * 表示解析后的 URL 组件。\n */\nexport type TURLMeta = {\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): TURLMeta {\n let result: URL | null = null;\n\n try {\n // 添加 globalThis 是便于对接外部环境 URL 的自行实现\n // 例如在 uni-app、微信小程序等运行环境。\n result = new globalThis.URL(url);\n } catch (e) {\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 * 将 URLInfo 对象转换回 URL 字符串。\n * @param url - 需要转换的 URLInfo 对象。\n * @returns 转换后的 URL 字符串。\n */\nexport function urlStringify(url: TURLMeta) {\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"],"names":[],"mappings":"AA+CO,SAAS,SAAS,KAAuB;AAC9C,MAAI,SAAqB;AAErB,MAAA;AAGO,aAAA,IAAI,WAAW,IAAI,GAAG;AAAA,WACxB,GAAG;AAAA,EAAA;AAIN,QAAA,YAAW,iCAAQ,aAAY;AAC/B,QAAA,QAAO,iCAAQ,SAAQ;AAEtB,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAU,iCAAQ,aAAY;AAAA,IAC9B,OAAM,iCAAQ,SAAQ;AAAA,IACtB,WAAU,iCAAQ,aAAY;AAAA,IAC9B,SAAQ,iCAAQ,WAAU;AAAA,IAC1B,OAAM,iCAAQ,SAAQ;AAAA,IACtB,WAAU,iCAAQ,aAAY;AAAA,IAC9B,WAAU,iCAAQ,aAAY;AAAA,EAChC;AACF;AAOO,SAAS,aAAa,KAAe;AACpC,QAAA,EAAE,UAAU,UAAU,MAAM,UAAU,QAAQ,MAAM,UAAU,SAAA,IAAa;AAC1E,SAAA;AAAA,IACL,WAAW,GAAG,QAAQ,OAAO;AAAA,IAC7B,YAAY,WAAW,GAAG,QAAQ,IAAI,QAAQ,MAAM;AAAA,IACpD;AAAA,IACA,OAAO,IAAI,IAAI,KAAK;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,EAEC,EAAA,OAAO,OAAO,EACd,KAAK,EAAE;AACZ;"}
1
+ {"version":3,"file":"url.mjs","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 (e) {\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"],"names":[],"mappings":"AA+CO,SAAS,SAAS,KAAsB;AAC7C,MAAI,SAAqB;AAErB,MAAA;AAGO,aAAA,IAAI,WAAW,IAAI,GAAG;AAAA,WACxB,GAAG;AAAA,EAAA;AAIN,QAAA,YAAW,iCAAQ,aAAY;AAC/B,QAAA,QAAO,iCAAQ,SAAQ;AAEtB,SAAA;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAU,iCAAQ,aAAY;AAAA,IAC9B,OAAM,iCAAQ,SAAQ;AAAA,IACtB,WAAU,iCAAQ,aAAY;AAAA,IAC9B,SAAQ,iCAAQ,WAAU;AAAA,IAC1B,OAAM,iCAAQ,SAAQ;AAAA,IACtB,WAAU,iCAAQ,aAAY;AAAA,IAC9B,WAAU,iCAAQ,aAAY;AAAA,EAChC;AACF;AAOO,SAAS,aAAa,KAAc;AACnC,QAAA,EAAE,UAAU,UAAU,MAAM,UAAU,QAAQ,MAAM,UAAU,SAAA,IAAa;AAC1E,SAAA;AAAA,IACL,WAAW,GAAG,QAAQ,OAAO;AAAA,IAC7B,YAAY,WAAW,GAAG,QAAQ,IAAI,QAAQ,MAAM;AAAA,IACpD;AAAA,IACA,OAAO,IAAI,IAAI,KAAK;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,EAEC,EAAA,OAAO,OAAO,EACd,KAAK,EAAE;AACZ;"}
@@ -1 +1 @@
1
- {"version":3,"file":"version.cjs","sources":["../src/version.ts"],"sourcesContent":["import { isUndefined } from './type';\n\n/**\n * 表示包含主版本号、次版本号和修订号的对象\n */\nexport type TVersionObject = {\n /**\n * 主版本号,当有不兼容的API修改时递增\n */\n major: number;\n /**\n * 次版本号,当有向下兼容的功能新增时递增\n */\n minor: number;\n /**\n * 修订号,当有向下兼容的问题修正时递增\n */\n patch: number;\n};\n\n/**\n * 将数字转换为安全的数值,如果输入为NaN则返回0\n * @param n - 要转换的数字\n * @returns 安全的数字(如果输入为NaN则返回0)\n */\nfunction internal_numerical(n?: number) {\n return Number.isNaN(n) || isUndefined(n) ? 0 : n;\n}\n\n/**\n * 将语义化版本号字符串解析为VersionObject对象\n * @param version - 要解析的版本号字符串 (例如 \"1.2.3\")\n * @returns 包含主版本号、次版本号和修订号的对象\n * @throws 如果版本号字符串格式无效将抛出错误\n */\nexport function versionParse(version: string): TVersionObject {\n const [major, minor, patch] = version.split('.').map(Number);\n return {\n major: internal_numerical(major),\n minor: internal_numerical(minor),\n patch: internal_numerical(patch),\n };\n}\n\n/**\n * 比较两个语义化版本号字符串\n * @param version1 - 要比较的第一个版本号字符串\n * @param version2 - 要比较的第二个版本号字符串\n * @returns 如果version1较大返回1,version2较大返回-1,相等返回0\n * @throws 如果任一版本号字符串格式无效将抛出错误\n */\nexport function versionCompare(version1: string, version2: string): number {\n const vo1 = versionParse(version1);\n const vo2 = versionParse(version2);\n const order: (keyof TVersionObject)[] = ['major', 'minor', 'patch'];\n\n for (const key of order) {\n const n1 = vo1[key];\n const n2 = vo2[key];\n\n if (n1 > n2) {\n return 1;\n }\n\n if (n1 < n2) {\n return -1;\n }\n }\n\n return 0;\n}\n"],"names":["isUndefined"],"mappings":";;;AAyBA,SAAS,mBAAmB,GAAY;AACtC,SAAO,OAAO,MAAM,CAAC,KAAKA,KAAAA,YAAY,CAAC,IAAI,IAAI;AACjD;AAQO,SAAS,aAAa,SAAiC;AACtD,QAAA,CAAC,OAAO,OAAO,KAAK,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,MAAM;AACpD,SAAA;AAAA,IACL,OAAO,mBAAmB,KAAK;AAAA,IAC/B,OAAO,mBAAmB,KAAK;AAAA,IAC/B,OAAO,mBAAmB,KAAK;AAAA,EACjC;AACF;AASgB,SAAA,eAAe,UAAkB,UAA0B;AACnE,QAAA,MAAM,aAAa,QAAQ;AAC3B,QAAA,MAAM,aAAa,QAAQ;AACjC,QAAM,QAAkC,CAAC,SAAS,SAAS,OAAO;AAElE,aAAW,OAAO,OAAO;AACjB,UAAA,KAAK,IAAI,GAAG;AACZ,UAAA,KAAK,IAAI,GAAG;AAElB,QAAI,KAAK,IAAI;AACJ,aAAA;AAAA,IAAA;AAGT,QAAI,KAAK,IAAI;AACJ,aAAA;AAAA,IAAA;AAAA,EACT;AAGK,SAAA;AACT;;;"}
1
+ {"version":3,"file":"version.cjs","sources":["../src/version.ts"],"sourcesContent":["import { isUndefined } from './type';\n\n/**\n * 表示包含主版本号、次版本号和修订号的对象\n */\nexport type VersionObject = {\n /**\n * 主版本号,当有不兼容的API修改时递增\n */\n major: number;\n /**\n * 次版本号,当有向下兼容的功能新增时递增\n */\n minor: number;\n /**\n * 修订号,当有向下兼容的问题修正时递增\n */\n patch: number;\n};\n\n/**\n * 将数字转换为安全的数值,如果输入为NaN则返回0\n * @param n - 要转换的数字\n * @returns 安全的数字(如果输入为NaN则返回0)\n */\nfunction internal_numerical(n?: number) {\n return Number.isNaN(n) || isUndefined(n) ? 0 : n;\n}\n\n/**\n * 将语义化版本号字符串解析为VersionObject对象\n * @param version - 要解析的版本号字符串 (例如 \"1.2.3\")\n * @returns 包含主版本号、次版本号和修订号的对象\n * @throws 如果版本号字符串格式无效将抛出错误\n */\nexport function versionParse(version: string): VersionObject {\n const [major, minor, patch] = version.split('.').map(Number);\n return {\n major: internal_numerical(major),\n minor: internal_numerical(minor),\n patch: internal_numerical(patch),\n };\n}\n\n/**\n * 比较两个语义化版本号字符串\n * @param version1 - 要比较的第一个版本号字符串\n * @param version2 - 要比较的第二个版本号字符串\n * @returns 如果version1较大返回1,version2较大返回-1,相等返回0\n * @throws 如果任一版本号字符串格式无效将抛出错误\n */\nexport function versionCompare(version1: string, version2: string): number {\n const vo1 = versionParse(version1);\n const vo2 = versionParse(version2);\n const order: (keyof VersionObject)[] = ['major', 'minor', 'patch'];\n\n for (const key of order) {\n const n1 = vo1[key];\n const n2 = vo2[key];\n\n if (n1 > n2) {\n return 1;\n }\n\n if (n1 < n2) {\n return -1;\n }\n }\n\n return 0;\n}\n"],"names":["isUndefined"],"mappings":";;;AAyBA,SAAS,mBAAmB,GAAY;AACtC,SAAO,OAAO,MAAM,CAAC,KAAKA,KAAAA,YAAY,CAAC,IAAI,IAAI;AACjD;AAQO,SAAS,aAAa,SAAgC;AACrD,QAAA,CAAC,OAAO,OAAO,KAAK,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,MAAM;AACpD,SAAA;AAAA,IACL,OAAO,mBAAmB,KAAK;AAAA,IAC/B,OAAO,mBAAmB,KAAK;AAAA,IAC/B,OAAO,mBAAmB,KAAK;AAAA,EACjC;AACF;AASgB,SAAA,eAAe,UAAkB,UAA0B;AACnE,QAAA,MAAM,aAAa,QAAQ;AAC3B,QAAA,MAAM,aAAa,QAAQ;AACjC,QAAM,QAAiC,CAAC,SAAS,SAAS,OAAO;AAEjE,aAAW,OAAO,OAAO;AACjB,UAAA,KAAK,IAAI,GAAG;AACZ,UAAA,KAAK,IAAI,GAAG;AAElB,QAAI,KAAK,IAAI;AACJ,aAAA;AAAA,IAAA;AAGT,QAAI,KAAK,IAAI;AACJ,aAAA;AAAA,IAAA;AAAA,EACT;AAGK,SAAA;AACT;;;"}
package/dist/version.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 表示包含主版本号、次版本号和修订号的对象
3
3
  */
4
- export type TVersionObject = {
4
+ export type VersionObject = {
5
5
  /**
6
6
  * 主版本号,当有不兼容的API修改时递增
7
7
  */
@@ -21,7 +21,7 @@ export type TVersionObject = {
21
21
  * @returns 包含主版本号、次版本号和修订号的对象
22
22
  * @throws 如果版本号字符串格式无效将抛出错误
23
23
  */
24
- export declare function versionParse(version: string): TVersionObject;
24
+ export declare function versionParse(version: string): VersionObject;
25
25
  /**
26
26
  * 比较两个语义化版本号字符串
27
27
  * @param version1 - 要比较的第一个版本号字符串
@@ -1 +1 @@
1
- {"version":3,"file":"version.mjs","sources":["../src/version.ts"],"sourcesContent":["import { isUndefined } from './type';\n\n/**\n * 表示包含主版本号、次版本号和修订号的对象\n */\nexport type TVersionObject = {\n /**\n * 主版本号,当有不兼容的API修改时递增\n */\n major: number;\n /**\n * 次版本号,当有向下兼容的功能新增时递增\n */\n minor: number;\n /**\n * 修订号,当有向下兼容的问题修正时递增\n */\n patch: number;\n};\n\n/**\n * 将数字转换为安全的数值,如果输入为NaN则返回0\n * @param n - 要转换的数字\n * @returns 安全的数字(如果输入为NaN则返回0)\n */\nfunction internal_numerical(n?: number) {\n return Number.isNaN(n) || isUndefined(n) ? 0 : n;\n}\n\n/**\n * 将语义化版本号字符串解析为VersionObject对象\n * @param version - 要解析的版本号字符串 (例如 \"1.2.3\")\n * @returns 包含主版本号、次版本号和修订号的对象\n * @throws 如果版本号字符串格式无效将抛出错误\n */\nexport function versionParse(version: string): TVersionObject {\n const [major, minor, patch] = version.split('.').map(Number);\n return {\n major: internal_numerical(major),\n minor: internal_numerical(minor),\n patch: internal_numerical(patch),\n };\n}\n\n/**\n * 比较两个语义化版本号字符串\n * @param version1 - 要比较的第一个版本号字符串\n * @param version2 - 要比较的第二个版本号字符串\n * @returns 如果version1较大返回1,version2较大返回-1,相等返回0\n * @throws 如果任一版本号字符串格式无效将抛出错误\n */\nexport function versionCompare(version1: string, version2: string): number {\n const vo1 = versionParse(version1);\n const vo2 = versionParse(version2);\n const order: (keyof TVersionObject)[] = ['major', 'minor', 'patch'];\n\n for (const key of order) {\n const n1 = vo1[key];\n const n2 = vo2[key];\n\n if (n1 > n2) {\n return 1;\n }\n\n if (n1 < n2) {\n return -1;\n }\n }\n\n return 0;\n}\n"],"names":[],"mappings":";AAyBA,SAAS,mBAAmB,GAAY;AACtC,SAAO,OAAO,MAAM,CAAC,KAAK,YAAY,CAAC,IAAI,IAAI;AACjD;AAQO,SAAS,aAAa,SAAiC;AACtD,QAAA,CAAC,OAAO,OAAO,KAAK,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,MAAM;AACpD,SAAA;AAAA,IACL,OAAO,mBAAmB,KAAK;AAAA,IAC/B,OAAO,mBAAmB,KAAK;AAAA,IAC/B,OAAO,mBAAmB,KAAK;AAAA,EACjC;AACF;AASgB,SAAA,eAAe,UAAkB,UAA0B;AACnE,QAAA,MAAM,aAAa,QAAQ;AAC3B,QAAA,MAAM,aAAa,QAAQ;AACjC,QAAM,QAAkC,CAAC,SAAS,SAAS,OAAO;AAElE,aAAW,OAAO,OAAO;AACjB,UAAA,KAAK,IAAI,GAAG;AACZ,UAAA,KAAK,IAAI,GAAG;AAElB,QAAI,KAAK,IAAI;AACJ,aAAA;AAAA,IAAA;AAGT,QAAI,KAAK,IAAI;AACJ,aAAA;AAAA,IAAA;AAAA,EACT;AAGK,SAAA;AACT;"}
1
+ {"version":3,"file":"version.mjs","sources":["../src/version.ts"],"sourcesContent":["import { isUndefined } from './type';\n\n/**\n * 表示包含主版本号、次版本号和修订号的对象\n */\nexport type VersionObject = {\n /**\n * 主版本号,当有不兼容的API修改时递增\n */\n major: number;\n /**\n * 次版本号,当有向下兼容的功能新增时递增\n */\n minor: number;\n /**\n * 修订号,当有向下兼容的问题修正时递增\n */\n patch: number;\n};\n\n/**\n * 将数字转换为安全的数值,如果输入为NaN则返回0\n * @param n - 要转换的数字\n * @returns 安全的数字(如果输入为NaN则返回0)\n */\nfunction internal_numerical(n?: number) {\n return Number.isNaN(n) || isUndefined(n) ? 0 : n;\n}\n\n/**\n * 将语义化版本号字符串解析为VersionObject对象\n * @param version - 要解析的版本号字符串 (例如 \"1.2.3\")\n * @returns 包含主版本号、次版本号和修订号的对象\n * @throws 如果版本号字符串格式无效将抛出错误\n */\nexport function versionParse(version: string): VersionObject {\n const [major, minor, patch] = version.split('.').map(Number);\n return {\n major: internal_numerical(major),\n minor: internal_numerical(minor),\n patch: internal_numerical(patch),\n };\n}\n\n/**\n * 比较两个语义化版本号字符串\n * @param version1 - 要比较的第一个版本号字符串\n * @param version2 - 要比较的第二个版本号字符串\n * @returns 如果version1较大返回1,version2较大返回-1,相等返回0\n * @throws 如果任一版本号字符串格式无效将抛出错误\n */\nexport function versionCompare(version1: string, version2: string): number {\n const vo1 = versionParse(version1);\n const vo2 = versionParse(version2);\n const order: (keyof VersionObject)[] = ['major', 'minor', 'patch'];\n\n for (const key of order) {\n const n1 = vo1[key];\n const n2 = vo2[key];\n\n if (n1 > n2) {\n return 1;\n }\n\n if (n1 < n2) {\n return -1;\n }\n }\n\n return 0;\n}\n"],"names":[],"mappings":";AAyBA,SAAS,mBAAmB,GAAY;AACtC,SAAO,OAAO,MAAM,CAAC,KAAK,YAAY,CAAC,IAAI,IAAI;AACjD;AAQO,SAAS,aAAa,SAAgC;AACrD,QAAA,CAAC,OAAO,OAAO,KAAK,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,MAAM;AACpD,SAAA;AAAA,IACL,OAAO,mBAAmB,KAAK;AAAA,IAC/B,OAAO,mBAAmB,KAAK;AAAA,IAC/B,OAAO,mBAAmB,KAAK;AAAA,EACjC;AACF;AASgB,SAAA,eAAe,UAAkB,UAA0B;AACnE,QAAA,MAAM,aAAa,QAAQ;AAC3B,QAAA,MAAM,aAAa,QAAQ;AACjC,QAAM,QAAiC,CAAC,SAAS,SAAS,OAAO;AAEjE,aAAW,OAAO,OAAO;AACjB,UAAA,KAAK,IAAI,GAAG;AACZ,UAAA,KAAK,IAAI,GAAG;AAElB,QAAI,KAAK,IAAI;AACJ,aAAA;AAAA,IAAA;AAGT,QAAI,KAAK,IAAI;AACJ,aAAA;AAAA,IAAA;AAAA,EACT;AAGK,SAAA;AACT;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudcome/utils-core",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "cloudcome core utils",
5
5
  "engines": {
6
6
  "node": ">=22"