@cloudcome/utils-core 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. package/dist/array.cjs +129 -0
  2. package/dist/array.cjs.map +1 -0
  3. package/dist/array.d.ts +171 -0
  4. package/dist/array.mjs +129 -0
  5. package/dist/array.mjs.map +1 -0
  6. package/dist/async.cjs +219 -0
  7. package/dist/async.cjs.map +1 -0
  8. package/dist/async.d.ts +137 -0
  9. package/dist/async.mjs +219 -0
  10. package/dist/async.mjs.map +1 -0
  11. package/dist/base64.cjs +16 -0
  12. package/dist/base64.cjs.map +1 -0
  13. package/dist/base64.d.ts +7 -0
  14. package/dist/base64.mjs +16 -0
  15. package/dist/base64.mjs.map +1 -0
  16. package/dist/cache.cjs +79 -0
  17. package/dist/cache.cjs.map +1 -0
  18. package/dist/cache.d.ts +90 -0
  19. package/dist/cache.mjs +79 -0
  20. package/dist/cache.mjs.map +1 -0
  21. package/{src/color/contrast.ts → dist/color/contrast.d.ts} +2 -12
  22. package/dist/color/distance.d.ts +8 -0
  23. package/dist/color/helpers.d.ts +2 -0
  24. package/dist/color/hex-hsl.d.ts +3 -0
  25. package/{src/color/hex-hsv.ts → dist/color/hex-hsv.d.ts} +3 -11
  26. package/{src/color/hex-hwb.ts → dist/color/hex-hwb.d.ts} +3 -11
  27. package/dist/color/hex-rgb.d.ts +18 -0
  28. package/{src/color/hsl-lighten.ts → dist/color/hsl-lighten.d.ts} +2 -7
  29. package/{src/color/hsv-brighten.ts → dist/color/hsv-brighten.d.ts} +2 -7
  30. package/{src/color/luminance.ts → dist/color/luminance.d.ts} +2 -9
  31. package/{src/color/mix.ts → dist/color/mix.d.ts} +2 -10
  32. package/dist/color/rgb-hsl.d.ts +23 -0
  33. package/{src/color/rgb-hsv.ts → dist/color/rgb-hsv.d.ts} +3 -30
  34. package/dist/color/rgb-hwb.d.ts +29 -0
  35. package/{src/color/rgb-lab.ts → dist/color/rgb-lab.d.ts} +3 -11
  36. package/dist/color/rgb-whiter.d.ts +12 -0
  37. package/dist/color/rgb-xyz.d.ts +22 -0
  38. package/{src/color/types.ts → dist/color/types.d.ts} +30 -12
  39. package/{src/color/xyz-lab.ts → dist/color/xyz-lab.d.ts} +3 -32
  40. package/dist/color.cjs +250 -0
  41. package/dist/color.cjs.map +1 -0
  42. package/dist/color.mjs +250 -0
  43. package/dist/color.mjs.map +1 -0
  44. package/dist/const.cjs +14 -0
  45. package/dist/const.cjs.map +1 -0
  46. package/dist/const.mjs +15 -0
  47. package/dist/const.mjs.map +1 -0
  48. package/dist/core.cjs +250 -0
  49. package/dist/core.cjs.map +1 -0
  50. package/dist/core.mjs +251 -0
  51. package/dist/core.mjs.map +1 -0
  52. package/dist/crypto/md5.d.mts +1 -0
  53. package/dist/crypto/sha1.d.mts +1 -0
  54. package/dist/crypto/sha256.d.mts +1 -0
  55. package/dist/crypto/sha512.d.mts +1 -0
  56. package/dist/crypto.cjs +812 -0
  57. package/dist/crypto.cjs.map +1 -0
  58. package/{src/crypto.ts → dist/crypto.d.ts} +4 -20
  59. package/dist/crypto.mjs +812 -0
  60. package/dist/crypto.mjs.map +1 -0
  61. package/dist/date/const.d.ts +6 -0
  62. package/dist/date/core.d.ts +52 -0
  63. package/dist/date/days.d.ts +23 -0
  64. package/{src/date/is.ts → dist/date/is.d.ts} +8 -102
  65. package/dist/date/relative.d.ts +44 -0
  66. package/dist/date/start-end.d.ts +73 -0
  67. package/dist/date/timezone.d.ts +67 -0
  68. package/dist/date/weeks.d.ts +72 -0
  69. package/dist/date.cjs +239 -0
  70. package/dist/date.cjs.map +1 -0
  71. package/dist/date.mjs +241 -0
  72. package/dist/date.mjs.map +1 -0
  73. package/dist/dict.cjs +2 -0
  74. package/dist/dict.cjs.map +1 -0
  75. package/dist/dict.mjs +2 -0
  76. package/dist/dict.mjs.map +1 -0
  77. package/dist/each.cjs +18 -0
  78. package/dist/each.cjs.map +1 -0
  79. package/dist/each.mjs +19 -0
  80. package/dist/each.mjs.map +1 -0
  81. package/dist/easing.cjs +151 -0
  82. package/dist/easing.cjs.map +1 -0
  83. package/dist/easing.d.ts +46 -0
  84. package/dist/easing.mjs +151 -0
  85. package/dist/easing.mjs.map +1 -0
  86. package/dist/emitter.cjs +94 -0
  87. package/dist/emitter.cjs.map +1 -0
  88. package/dist/emitter.d.ts +68 -0
  89. package/dist/emitter.mjs +94 -0
  90. package/dist/emitter.mjs.map +1 -0
  91. package/dist/enum.cjs +58 -0
  92. package/dist/enum.cjs.map +1 -0
  93. package/dist/enum.d.ts +68 -0
  94. package/dist/enum.mjs +58 -0
  95. package/dist/enum.mjs.map +1 -0
  96. package/dist/env.cjs +28 -0
  97. package/dist/env.cjs.map +1 -0
  98. package/{src/env.ts → dist/env.d.ts} +6 -30
  99. package/dist/env.mjs +28 -0
  100. package/dist/env.mjs.map +1 -0
  101. package/dist/error.cjs +12 -0
  102. package/dist/error.cjs.map +1 -0
  103. package/{src/error.ts → dist/error.d.ts} +3 -12
  104. package/dist/error.mjs +12 -0
  105. package/dist/error.mjs.map +1 -0
  106. package/dist/exception.cjs +22 -0
  107. package/dist/exception.cjs.map +1 -0
  108. package/dist/exception.d.ts +31 -0
  109. package/dist/exception.mjs +22 -0
  110. package/dist/exception.mjs.map +1 -0
  111. package/dist/fn.cjs +76 -0
  112. package/dist/fn.cjs.map +1 -0
  113. package/dist/fn.d.ts +102 -0
  114. package/dist/fn.mjs +76 -0
  115. package/dist/fn.mjs.map +1 -0
  116. package/dist/index.cjs +5 -0
  117. package/dist/index.cjs.map +1 -0
  118. package/dist/index.d.ts +1 -0
  119. package/dist/index.mjs +5 -0
  120. package/dist/index.mjs.map +1 -0
  121. package/dist/merge.cjs +87 -0
  122. package/dist/merge.cjs.map +1 -0
  123. package/dist/merge.mjs +88 -0
  124. package/dist/merge.mjs.map +1 -0
  125. package/dist/number.cjs +14 -0
  126. package/dist/number.cjs.map +1 -0
  127. package/dist/number.d.ts +153 -0
  128. package/dist/number.mjs +14 -0
  129. package/dist/number.mjs.map +1 -0
  130. package/{src/object/each.ts → dist/object/each.d.ts} +3 -23
  131. package/dist/object/get-set.d.ts +111 -0
  132. package/dist/object/is.d.ts +32 -0
  133. package/dist/object/merge.d.ts +72 -0
  134. package/{src/object/process.ts → dist/object/process.d.ts} +4 -38
  135. package/dist/object.cjs +130 -0
  136. package/dist/object.cjs.map +1 -0
  137. package/dist/object.mjs +130 -0
  138. package/dist/object.mjs.map +1 -0
  139. package/dist/path.cjs +77 -0
  140. package/dist/path.cjs.map +1 -0
  141. package/dist/path.d.ts +82 -0
  142. package/dist/path.mjs +77 -0
  143. package/dist/path.mjs.map +1 -0
  144. package/dist/promise.cjs +62 -0
  145. package/dist/promise.cjs.map +1 -0
  146. package/{src/promise.ts → dist/promise.d.ts} +6 -67
  147. package/dist/promise.mjs +62 -0
  148. package/dist/promise.mjs.map +1 -0
  149. package/dist/qs.cjs +47 -0
  150. package/dist/qs.cjs.map +1 -0
  151. package/{src/qs.ts → dist/qs.d.ts} +3 -60
  152. package/dist/qs.mjs +47 -0
  153. package/dist/qs.mjs.map +1 -0
  154. package/dist/regexp.cjs +66 -0
  155. package/dist/regexp.cjs.map +1 -0
  156. package/dist/regexp.d.ts +65 -0
  157. package/dist/regexp.mjs +66 -0
  158. package/dist/regexp.mjs.map +1 -0
  159. package/dist/string.cjs +16 -0
  160. package/dist/string.cjs.map +1 -0
  161. package/dist/string.d.ts +80 -0
  162. package/dist/string.mjs +16 -0
  163. package/dist/string.mjs.map +1 -0
  164. package/dist/string2.cjs +157 -0
  165. package/dist/string2.cjs.map +1 -0
  166. package/dist/string2.mjs +158 -0
  167. package/dist/string2.mjs.map +1 -0
  168. package/dist/time/from.d.ts +14 -0
  169. package/dist/time/to.d.ts +38 -0
  170. package/dist/time.cjs +82 -0
  171. package/dist/time.cjs.map +1 -0
  172. package/dist/time.mjs +82 -0
  173. package/dist/time.mjs.map +1 -0
  174. package/dist/timer.cjs +119 -0
  175. package/dist/timer.cjs.map +1 -0
  176. package/dist/timer.d.ts +96 -0
  177. package/{src/timer.ts → dist/timer.mjs} +17 -124
  178. package/dist/timer.mjs.map +1 -0
  179. package/dist/tree.cjs +125 -0
  180. package/dist/tree.cjs.map +1 -0
  181. package/{src/tree.ts → dist/tree.d.ts} +41 -225
  182. package/dist/tree.mjs +125 -0
  183. package/dist/tree.mjs.map +1 -0
  184. package/dist/type.cjs +78 -0
  185. package/dist/type.cjs.map +1 -0
  186. package/{src/type.ts → dist/type.d.ts} +20 -96
  187. package/dist/type.mjs +78 -0
  188. package/dist/type.mjs.map +1 -0
  189. package/dist/types.cjs +2 -0
  190. package/dist/types.cjs.map +1 -0
  191. package/{src/types.ts → dist/types.d.ts} +12 -33
  192. package/dist/types.mjs +2 -0
  193. package/dist/types.mjs.map +1 -0
  194. package/dist/unique.cjs +46 -0
  195. package/dist/unique.cjs.map +1 -0
  196. package/dist/unique.d.ts +22 -0
  197. package/dist/unique.mjs +46 -0
  198. package/dist/unique.mjs.map +1 -0
  199. package/dist/url.cjs +37 -0
  200. package/dist/url.cjs.map +1 -0
  201. package/dist/url.d.ts +53 -0
  202. package/dist/url.mjs +37 -0
  203. package/dist/url.mjs.map +1 -0
  204. package/dist/version.cjs +33 -0
  205. package/dist/version.cjs.map +1 -0
  206. package/dist/version.d.ts +32 -0
  207. package/dist/version.mjs +33 -0
  208. package/dist/version.mjs.map +1 -0
  209. package/package.json +8 -2
  210. package/CHANGELOG.md +0 -52
  211. package/src/array.ts +0 -312
  212. package/src/async.ts +0 -379
  213. package/src/base64.ts +0 -20
  214. package/src/cache.ts +0 -146
  215. package/src/color/distance.ts +0 -28
  216. package/src/color/helpers.ts +0 -23
  217. package/src/color/hex-hsl.ts +0 -11
  218. package/src/color/hex-rgb.ts +0 -39
  219. package/src/color/rgb-hsl.ts +0 -53
  220. package/src/color/rgb-hwb.ts +0 -56
  221. package/src/color/rgb-whiter.ts +0 -22
  222. package/src/color/rgb-xyz.ts +0 -62
  223. package/src/crypto/md5.mjs +0 -357
  224. package/src/crypto/sha1.mjs +0 -300
  225. package/src/crypto/sha256.mjs +0 -310
  226. package/src/crypto/sha512.mjs +0 -459
  227. package/src/date/const.ts +0 -6
  228. package/src/date/core.ts +0 -162
  229. package/src/date/days.ts +0 -51
  230. package/src/date/relative.ts +0 -92
  231. package/src/date/start-end.ts +0 -246
  232. package/src/date/timezone.ts +0 -220
  233. package/src/date/weeks.ts +0 -100
  234. package/src/dts/global.d.ts +0 -27
  235. package/src/easing.ts +0 -166
  236. package/src/emitter.ts +0 -117
  237. package/src/enum.ts +0 -171
  238. package/src/exception.ts +0 -68
  239. package/src/fn.ts +0 -197
  240. package/src/index.ts +0 -1
  241. package/src/number.ts +0 -236
  242. package/src/object/get-set.ts +0 -273
  243. package/src/object/is.ts +0 -128
  244. package/src/object/merge.ts +0 -180
  245. package/src/path.ts +0 -188
  246. package/src/regexp.ts +0 -156
  247. package/src/string.ts +0 -146
  248. package/src/time/from.ts +0 -57
  249. package/src/time/to.ts +0 -106
  250. package/src/unique.ts +0 -77
  251. package/src/url.ts +0 -93
  252. package/src/version.ts +0 -71
  253. package/test/array.test.ts +0 -332
  254. package/test/async-real.test.ts +0 -39
  255. package/test/async.test.ts +0 -375
  256. package/test/base64.test.ts +0 -32
  257. package/test/cache.test.ts +0 -83
  258. package/test/color.test.ts +0 -163
  259. package/test/crypto.test.ts +0 -34
  260. package/test/date-tz.test.ts +0 -206
  261. package/test/date.test.ts +0 -353
  262. package/test/easing.test.ts +0 -33
  263. package/test/emitter.test.ts +0 -71
  264. package/test/enum.test.ts +0 -113
  265. package/test/env.test.ts +0 -69
  266. package/test/error.test.ts +0 -58
  267. package/test/exception.test.ts +0 -43
  268. package/test/fn.test.ts +0 -263
  269. package/test/helpers.ts +0 -23
  270. package/test/index.test.ts +0 -6
  271. package/test/number.test.ts +0 -213
  272. package/test/object.test.ts +0 -309
  273. package/test/path.test.ts +0 -156
  274. package/test/promise.test.ts +0 -199
  275. package/test/qs.test.ts +0 -79
  276. package/test/regexp.test.ts +0 -97
  277. package/test/string.test.ts +0 -150
  278. package/test/time.test.ts +0 -214
  279. package/test/timer.test.ts +0 -114
  280. package/test/tree.test.ts +0 -348
  281. package/test/type.test.ts +0 -226
  282. package/test/unique.test.ts +0 -71
  283. package/test/url.test.ts +0 -136
  284. package/test/version.test.ts +0 -52
  285. package/tsconfig.json +0 -31
  286. package/vite.config.mts +0 -114
  287. /package/{src/color.ts → dist/color.d.ts} +0 -0
  288. /package/{src/date.ts → dist/date.d.ts} +0 -0
  289. /package/{src/dict.ts → dist/dict.d.ts} +0 -0
  290. /package/{src/object.ts → dist/object.d.ts} +0 -0
  291. /package/{src/time.ts → dist/time.d.ts} +0 -0
@@ -0,0 +1,31 @@
1
+ /**
2
+ * 构建异常选项
3
+ */
4
+ export type BuildExceptionOptions = {
5
+ /**
6
+ * 自定义错误消息格式函数
7
+ * @param name 错误名称
8
+ * @param message 原始错误消息
9
+ * @returns 格式化后的错误消息
10
+ * @example
11
+ * (name, message) => `${name}::${message}`
12
+ */
13
+ format?: (name: string, message: string) => string;
14
+ };
15
+ /**
16
+ * 构建自定义异常类
17
+ * @template T 额外属性的类型
18
+ * @param name 异常类名称
19
+ * @param options 构建选项
20
+ * @returns 自定义异常类
21
+ * @example
22
+ * const MyException = buildException<{ code: number }>('MyException');
23
+ * const err = new MyException('error', { code: 404 });
24
+ *
25
+ * @example
26
+ * const SimpleException = buildException('SimpleException');
27
+ * const err = new SimpleException('error', undefined);
28
+ */
29
+ export declare function buildException<T = void>(name: string, options?: BuildExceptionOptions): {
30
+ new (message: string, extra: T): Error & T;
31
+ };
@@ -0,0 +1,22 @@
1
+ import { o as objectDefaults } from "./merge.mjs";
2
+ const defaults = {
3
+ /**
4
+ * 默认消息格式函数
5
+ * @default (name, message) => `[${name}] ${message}`
6
+ */
7
+ format: (name, message) => `[${name}] ${message}`
8
+ };
9
+ function buildException(name, options) {
10
+ const { format } = objectDefaults(options || {}, defaults);
11
+ return class extends Error {
12
+ constructor(message, extra) {
13
+ super(format(name, message));
14
+ this.name = name;
15
+ Object.assign(this, extra);
16
+ }
17
+ };
18
+ }
19
+ export {
20
+ buildException
21
+ };
22
+ //# sourceMappingURL=exception.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exception.mjs","sources":["../src/exception.ts"],"sourcesContent":["import { objectDefaults } from './object';\nimport type { AnyObject } from './types';\n\n/**\n * 构建异常选项\n */\nexport type BuildExceptionOptions = {\n /**\n * 自定义错误消息格式函数\n * @param name 错误名称\n * @param message 原始错误消息\n * @returns 格式化后的错误消息\n * @example\n * (name, message) => `${name}::${message}`\n */\n format?: (name: string, message: string) => string;\n};\n\n/**\n * 默认的异常构建选项\n */\nconst defaults: BuildExceptionOptions = {\n /**\n * 默认消息格式函数\n * @default (name, message) => `[${name}] ${message}`\n */\n format: (name, message) => `[${name}] ${message}`,\n};\n\n/**\n * 构建自定义异常类\n * @template T 额外属性的类型\n * @param name 异常类名称\n * @param options 构建选项\n * @returns 自定义异常类\n * @example\n * const MyException = buildException<{ code: number }>('MyException');\n * const err = new MyException('error', { code: 404 });\n *\n * @example\n * const SimpleException = buildException('SimpleException');\n * const err = new SimpleException('error', undefined);\n */\nexport function buildException<T = void>(name: string, options?: BuildExceptionOptions) {\n const { format } = objectDefaults(options || {}, defaults) as Required<BuildExceptionOptions>;\n\n return class extends Error {\n constructor(message: string, extra: T) {\n super(format(name, message));\n this.name = name;\n Object.assign(this, extra);\n }\n } as unknown as {\n new (message: string, extra: T): Error & T;\n };\n}\n\n// const MyException = buildException<{ foo: string; bar: number }>('MyException: ');\n// const myException = new MyException('bar', { foo: '1', bar: 1 });\n// myException.foo;\n// myException.bar;\n// myException.name;\n// myException.message;\n// myException.stack;\n// myException.cause;\n\n// const MyException2 = buildException('MyException2: ');\n// const myException2 = new MyException2('bar');\n"],"names":[],"mappings":";AAqBA,MAAM,WAAkC;AAAA;AAAA;AAAA;AAAA;AAAA,EAKtC,QAAQ,CAAC,MAAM,YAAY,IAAI,IAAI,KAAK,OAAO;AACjD;AAgBgB,SAAA,eAAyB,MAAc,SAAiC;AACtF,QAAM,EAAE,OAAO,IAAI,eAAe,WAAW,CAAA,GAAI,QAAQ;AAEzD,SAAO,cAAc,MAAM;AAAA,IACzB,YAAY,SAAiB,OAAU;AAC/B,YAAA,OAAO,MAAM,OAAO,CAAC;AAC3B,WAAK,OAAO;AACL,aAAA,OAAO,MAAM,KAAK;AAAA,IAAA;AAAA,EAE7B;AAGF;"}
package/dist/fn.cjs ADDED
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const type = require("./type.cjs");
4
+ function fnNoop() {
5
+ }
6
+ function fnDebounce(fn, wait) {
7
+ const options = type.isNumber(wait) ? { wait } : wait;
8
+ let canceled = false;
9
+ let timer;
10
+ let leading = false;
11
+ const debounced = function(...args) {
12
+ if (canceled) return;
13
+ if (options.leading && !leading) {
14
+ leading = true;
15
+ fn.apply(this, args);
16
+ return;
17
+ }
18
+ clearTimeout(timer);
19
+ timer = setTimeout(() => {
20
+ if (canceled) return;
21
+ fn.apply(this, args);
22
+ }, options.wait);
23
+ };
24
+ debounced.cancel = () => {
25
+ clearTimeout(timer);
26
+ canceled = true;
27
+ };
28
+ return debounced;
29
+ }
30
+ function fnThrottle(fn, wait) {
31
+ const options = type.isNumber(wait) ? { wait } : wait;
32
+ const waitFinal = options.wait;
33
+ let lastTime = 0;
34
+ let canceled = false;
35
+ let timer;
36
+ const throttled = function(...args) {
37
+ if (canceled) return;
38
+ const now = Date.now();
39
+ if (options.leading && lastTime === 0) {
40
+ lastTime = now;
41
+ fn.apply(this, args);
42
+ } else if (lastTime > 0 && now - lastTime >= waitFinal) {
43
+ lastTime = now;
44
+ fn.apply(this, args);
45
+ } else if (lastTime === 0) {
46
+ lastTime = now;
47
+ }
48
+ if (options.trailing) {
49
+ clearTimeout(timer);
50
+ timer = setTimeout(() => {
51
+ fn.apply(this, args);
52
+ }, waitFinal);
53
+ }
54
+ };
55
+ throttled.cancel = () => {
56
+ canceled = true;
57
+ clearTimeout(timer);
58
+ };
59
+ return throttled;
60
+ }
61
+ function fnOnce(fn) {
62
+ let called = false;
63
+ let result;
64
+ return function(...args) {
65
+ if (!called) {
66
+ called = true;
67
+ result = fn.apply(this, args);
68
+ }
69
+ return result;
70
+ };
71
+ }
72
+ exports.fnDebounce = fnDebounce;
73
+ exports.fnNoop = fnNoop;
74
+ exports.fnOnce = fnOnce;
75
+ exports.fnThrottle = fnThrottle;
76
+ //# sourceMappingURL=fn.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fn.cjs","sources":["../src/fn.ts"],"sourcesContent":["import { isNumber } from './type';\nimport type { AnyFunction } from './types';\n\n/**\n * 一个空操作函数,不执行任何操作。\n *\n * @example\n * ```typescript\n * fnNoop(); // 不执行任何操作\n * ```\n */\nexport function fnNoop() {\n //\n}\n\n/**\n * 防抖函数的配置选项。\n */\nexport type TDebounceOptions = {\n /**\n * 等待时间(毫秒)。\n */\n wait: number;\n /**\n * 是否在等待开始时立即执行一次\n * @default false\n */\n leading?: boolean;\n};\n\n/**\n * 创建一个防抖函数,该函数会在指定的等待时间后执行,如果在等待时间内再次调用,则重新计时。\n *\n * @param fn - 需要防抖的函数。\n * @param wait - 等待时间(毫秒)或包含 `wait` 和 `leading` 选项的对象。\n * @returns 返回一个防抖函数,该函数具有 `cancel` 方法,用于取消防抖操作。\n *\n * @example\n * ```typescript\n * const debouncedFn = fnDebounce(() => {\n * console.log('Debounced!');\n * }, 100);\n *\n * debouncedFn(); // 不会立即执行\n * debouncedFn(); // 重新计时\n * debouncedFn.cancel(); // 取消防抖操作\n * ```\n */\nexport function fnDebounce<F extends AnyFunction>(fn: F, wait: number | TDebounceOptions) {\n const options: TDebounceOptions = isNumber(wait) ? { wait } : wait;\n let canceled = false;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n let timer: any;\n let leading = false;\n\n const debounced = function (this: unknown, ...args: Parameters<F>) {\n if (canceled) return;\n\n // 第一次执行\n if (options.leading && !leading) {\n leading = true;\n fn.apply(this, args);\n return;\n }\n\n // 最后一次执行\n clearTimeout(timer);\n timer = setTimeout(() => {\n if (canceled) return;\n\n fn.apply(this, args);\n }, options.wait);\n };\n\n debounced.cancel = () => {\n clearTimeout(timer);\n canceled = true;\n };\n\n return debounced;\n}\n\nexport type TThrottleOptions = {\n /**\n * 等待时间(毫秒)。\n */\n wait: number;\n\n /**\n * 是否在第一次调用时立即执行\n * @default false\n */\n leading?: boolean;\n\n /**\n * 是否在调用结束后等待一段时间再执行\n * @default false\n */\n trailing?: boolean;\n};\n\n/**\n * 创建一个节流函数,该函数会在指定的等待时间内最多执行一次,如果在等待时间内再次调用,则忽略后续调用。\n *\n * @param fn - 需要节流的函数。\n * @param wait - 等待时间(毫秒)或包含 `wait`、`leading` 和 `trailing` 选项的对象。\n * @returns 返回一个节流函数,该函数具有 `cancel` 方法,用于取消节流操作。\n *\n * @example\n * ```typescript\n * const throttledFn = fnThrottle(() => {\n * console.log('Throttled!');\n * }, 100);\n *\n * throttledFn(); // 立即执行\n * throttledFn(); // 忽略\n * throttledFn.cancel(); // 取消节流操作\n * ```\n */\nexport function fnThrottle<F extends AnyFunction>(fn: F, wait: number | TThrottleOptions) {\n const options = isNumber(wait) ? { wait } : wait;\n const waitFinal = options.wait;\n let lastTime = 0;\n let canceled = false;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n let timer: any;\n\n const throttled = function (this: unknown, ...args: Parameters<F>) {\n if (canceled) return;\n\n const now = Date.now();\n\n // 第一次执行\n if (options.leading && lastTime === 0) {\n lastTime = now;\n fn.apply(this, args);\n }\n\n // 中间控频执行\n else if (lastTime > 0 && now - lastTime >= waitFinal) {\n lastTime = now;\n fn.apply(this, args);\n }\n\n // 首次计时\n else if (lastTime === 0) {\n lastTime = now;\n }\n\n // 最后一次执行\n if (options.trailing) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n fn.apply(this, args);\n }, waitFinal);\n }\n };\n\n throttled.cancel = () => {\n canceled = true;\n clearTimeout(timer);\n };\n\n return throttled;\n}\n\n/**\n * 创建一个只执行一次的函数,无论调用多少次,实际执行的函数体也只会执行一次。\n *\n * @param fn - 需要只执行一次的函数。\n * @returns 返回一个只执行一次的函数,该函数在第一次调用后会缓存结果并返回缓存的结果。\n *\n * @example\n * ```typescript\n * const onceFn = fnOnce(() => {\n * console.log('This will be logged only once.');\n * return 42;\n * });\n *\n * console.log(onceFn()); // 输出: This will be logged only once. 42\n * console.log(onceFn()); // 输出: 42\n * ```\n */\nexport function fnOnce<F extends AnyFunction>(fn: F) {\n let called = false;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n let result: any;\n\n return function (this: unknown, ...args: Parameters<F>) {\n if (!called) {\n called = true;\n result = fn.apply(this, args);\n }\n\n return result;\n };\n}\n"],"names":["isNumber"],"mappings":";;;AAWO,SAAS,SAAS;AAEzB;AAmCgB,SAAA,WAAkC,IAAO,MAAiC;AACxF,QAAM,UAA4BA,KAAAA,SAAS,IAAI,IAAI,EAAE,KAAS,IAAA;AAC9D,MAAI,WAAW;AAEX,MAAA;AACJ,MAAI,UAAU;AAER,QAAA,YAAY,YAA4B,MAAqB;AACjE,QAAI,SAAU;AAGV,QAAA,QAAQ,WAAW,CAAC,SAAS;AACrB,gBAAA;AACP,SAAA,MAAM,MAAM,IAAI;AACnB;AAAA,IAAA;AAIF,iBAAa,KAAK;AAClB,YAAQ,WAAW,MAAM;AACvB,UAAI,SAAU;AAEX,SAAA,MAAM,MAAM,IAAI;AAAA,IAAA,GAClB,QAAQ,IAAI;AAAA,EACjB;AAEA,YAAU,SAAS,MAAM;AACvB,iBAAa,KAAK;AACP,eAAA;AAAA,EACb;AAEO,SAAA;AACT;AAuCgB,SAAA,WAAkC,IAAO,MAAiC;AACxF,QAAM,UAAUA,KAAAA,SAAS,IAAI,IAAI,EAAE,KAAS,IAAA;AAC5C,QAAM,YAAY,QAAQ;AAC1B,MAAI,WAAW;AACf,MAAI,WAAW;AAEX,MAAA;AAEE,QAAA,YAAY,YAA4B,MAAqB;AACjE,QAAI,SAAU;AAER,UAAA,MAAM,KAAK,IAAI;AAGjB,QAAA,QAAQ,WAAW,aAAa,GAAG;AAC1B,iBAAA;AACR,SAAA,MAAM,MAAM,IAAI;AAAA,IAIZ,WAAA,WAAW,KAAK,MAAM,YAAY,WAAW;AACzC,iBAAA;AACR,SAAA,MAAM,MAAM,IAAI;AAAA,IAAA,WAIZ,aAAa,GAAG;AACZ,iBAAA;AAAA,IAAA;AAIb,QAAI,QAAQ,UAAU;AACpB,mBAAa,KAAK;AAClB,cAAQ,WAAW,MAAM;AACpB,WAAA,MAAM,MAAM,IAAI;AAAA,SAClB,SAAS;AAAA,IAAA;AAAA,EAEhB;AAEA,YAAU,SAAS,MAAM;AACZ,eAAA;AACX,iBAAa,KAAK;AAAA,EACpB;AAEO,SAAA;AACT;AAmBO,SAAS,OAA8B,IAAO;AACnD,MAAI,SAAS;AAET,MAAA;AAEJ,SAAO,YAA4B,MAAqB;AACtD,QAAI,CAAC,QAAQ;AACF,eAAA;AACA,eAAA,GAAG,MAAM,MAAM,IAAI;AAAA,IAAA;AAGvB,WAAA;AAAA,EACT;AACF;;;;;"}
package/dist/fn.d.ts ADDED
@@ -0,0 +1,102 @@
1
+ import { AnyFunction } from './types';
2
+ /**
3
+ * 一个空操作函数,不执行任何操作。
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * fnNoop(); // 不执行任何操作
8
+ * ```
9
+ */
10
+ export declare function fnNoop(): void;
11
+ /**
12
+ * 防抖函数的配置选项。
13
+ */
14
+ export type TDebounceOptions = {
15
+ /**
16
+ * 等待时间(毫秒)。
17
+ */
18
+ wait: number;
19
+ /**
20
+ * 是否在等待开始时立即执行一次
21
+ * @default false
22
+ */
23
+ leading?: boolean;
24
+ };
25
+ /**
26
+ * 创建一个防抖函数,该函数会在指定的等待时间后执行,如果在等待时间内再次调用,则重新计时。
27
+ *
28
+ * @param fn - 需要防抖的函数。
29
+ * @param wait - 等待时间(毫秒)或包含 `wait` 和 `leading` 选项的对象。
30
+ * @returns 返回一个防抖函数,该函数具有 `cancel` 方法,用于取消防抖操作。
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const debouncedFn = fnDebounce(() => {
35
+ * console.log('Debounced!');
36
+ * }, 100);
37
+ *
38
+ * debouncedFn(); // 不会立即执行
39
+ * debouncedFn(); // 重新计时
40
+ * debouncedFn.cancel(); // 取消防抖操作
41
+ * ```
42
+ */
43
+ export declare function fnDebounce<F extends AnyFunction>(fn: F, wait: number | TDebounceOptions): {
44
+ (this: unknown, ...args: Parameters<F>): void;
45
+ cancel(): void;
46
+ };
47
+ export type TThrottleOptions = {
48
+ /**
49
+ * 等待时间(毫秒)。
50
+ */
51
+ wait: number;
52
+ /**
53
+ * 是否在第一次调用时立即执行
54
+ * @default false
55
+ */
56
+ leading?: boolean;
57
+ /**
58
+ * 是否在调用结束后等待一段时间再执行
59
+ * @default false
60
+ */
61
+ trailing?: boolean;
62
+ };
63
+ /**
64
+ * 创建一个节流函数,该函数会在指定的等待时间内最多执行一次,如果在等待时间内再次调用,则忽略后续调用。
65
+ *
66
+ * @param fn - 需要节流的函数。
67
+ * @param wait - 等待时间(毫秒)或包含 `wait`、`leading` 和 `trailing` 选项的对象。
68
+ * @returns 返回一个节流函数,该函数具有 `cancel` 方法,用于取消节流操作。
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * const throttledFn = fnThrottle(() => {
73
+ * console.log('Throttled!');
74
+ * }, 100);
75
+ *
76
+ * throttledFn(); // 立即执行
77
+ * throttledFn(); // 忽略
78
+ * throttledFn.cancel(); // 取消节流操作
79
+ * ```
80
+ */
81
+ export declare function fnThrottle<F extends AnyFunction>(fn: F, wait: number | TThrottleOptions): {
82
+ (this: unknown, ...args: Parameters<F>): void;
83
+ cancel(): void;
84
+ };
85
+ /**
86
+ * 创建一个只执行一次的函数,无论调用多少次,实际执行的函数体也只会执行一次。
87
+ *
88
+ * @param fn - 需要只执行一次的函数。
89
+ * @returns 返回一个只执行一次的函数,该函数在第一次调用后会缓存结果并返回缓存的结果。
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * const onceFn = fnOnce(() => {
94
+ * console.log('This will be logged only once.');
95
+ * return 42;
96
+ * });
97
+ *
98
+ * console.log(onceFn()); // 输出: This will be logged only once. 42
99
+ * console.log(onceFn()); // 输出: 42
100
+ * ```
101
+ */
102
+ export declare function fnOnce<F extends AnyFunction>(fn: F): (this: unknown, ...args: Parameters<F>) => any;
package/dist/fn.mjs ADDED
@@ -0,0 +1,76 @@
1
+ import { isNumber } from "./type.mjs";
2
+ function fnNoop() {
3
+ }
4
+ function fnDebounce(fn, wait) {
5
+ const options = isNumber(wait) ? { wait } : wait;
6
+ let canceled = false;
7
+ let timer;
8
+ let leading = false;
9
+ const debounced = function(...args) {
10
+ if (canceled) return;
11
+ if (options.leading && !leading) {
12
+ leading = true;
13
+ fn.apply(this, args);
14
+ return;
15
+ }
16
+ clearTimeout(timer);
17
+ timer = setTimeout(() => {
18
+ if (canceled) return;
19
+ fn.apply(this, args);
20
+ }, options.wait);
21
+ };
22
+ debounced.cancel = () => {
23
+ clearTimeout(timer);
24
+ canceled = true;
25
+ };
26
+ return debounced;
27
+ }
28
+ function fnThrottle(fn, wait) {
29
+ const options = isNumber(wait) ? { wait } : wait;
30
+ const waitFinal = options.wait;
31
+ let lastTime = 0;
32
+ let canceled = false;
33
+ let timer;
34
+ const throttled = function(...args) {
35
+ if (canceled) return;
36
+ const now = Date.now();
37
+ if (options.leading && lastTime === 0) {
38
+ lastTime = now;
39
+ fn.apply(this, args);
40
+ } else if (lastTime > 0 && now - lastTime >= waitFinal) {
41
+ lastTime = now;
42
+ fn.apply(this, args);
43
+ } else if (lastTime === 0) {
44
+ lastTime = now;
45
+ }
46
+ if (options.trailing) {
47
+ clearTimeout(timer);
48
+ timer = setTimeout(() => {
49
+ fn.apply(this, args);
50
+ }, waitFinal);
51
+ }
52
+ };
53
+ throttled.cancel = () => {
54
+ canceled = true;
55
+ clearTimeout(timer);
56
+ };
57
+ return throttled;
58
+ }
59
+ function fnOnce(fn) {
60
+ let called = false;
61
+ let result;
62
+ return function(...args) {
63
+ if (!called) {
64
+ called = true;
65
+ result = fn.apply(this, args);
66
+ }
67
+ return result;
68
+ };
69
+ }
70
+ export {
71
+ fnDebounce,
72
+ fnNoop,
73
+ fnOnce,
74
+ fnThrottle
75
+ };
76
+ //# sourceMappingURL=fn.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fn.mjs","sources":["../src/fn.ts"],"sourcesContent":["import { isNumber } from './type';\nimport type { AnyFunction } from './types';\n\n/**\n * 一个空操作函数,不执行任何操作。\n *\n * @example\n * ```typescript\n * fnNoop(); // 不执行任何操作\n * ```\n */\nexport function fnNoop() {\n //\n}\n\n/**\n * 防抖函数的配置选项。\n */\nexport type TDebounceOptions = {\n /**\n * 等待时间(毫秒)。\n */\n wait: number;\n /**\n * 是否在等待开始时立即执行一次\n * @default false\n */\n leading?: boolean;\n};\n\n/**\n * 创建一个防抖函数,该函数会在指定的等待时间后执行,如果在等待时间内再次调用,则重新计时。\n *\n * @param fn - 需要防抖的函数。\n * @param wait - 等待时间(毫秒)或包含 `wait` 和 `leading` 选项的对象。\n * @returns 返回一个防抖函数,该函数具有 `cancel` 方法,用于取消防抖操作。\n *\n * @example\n * ```typescript\n * const debouncedFn = fnDebounce(() => {\n * console.log('Debounced!');\n * }, 100);\n *\n * debouncedFn(); // 不会立即执行\n * debouncedFn(); // 重新计时\n * debouncedFn.cancel(); // 取消防抖操作\n * ```\n */\nexport function fnDebounce<F extends AnyFunction>(fn: F, wait: number | TDebounceOptions) {\n const options: TDebounceOptions = isNumber(wait) ? { wait } : wait;\n let canceled = false;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n let timer: any;\n let leading = false;\n\n const debounced = function (this: unknown, ...args: Parameters<F>) {\n if (canceled) return;\n\n // 第一次执行\n if (options.leading && !leading) {\n leading = true;\n fn.apply(this, args);\n return;\n }\n\n // 最后一次执行\n clearTimeout(timer);\n timer = setTimeout(() => {\n if (canceled) return;\n\n fn.apply(this, args);\n }, options.wait);\n };\n\n debounced.cancel = () => {\n clearTimeout(timer);\n canceled = true;\n };\n\n return debounced;\n}\n\nexport type TThrottleOptions = {\n /**\n * 等待时间(毫秒)。\n */\n wait: number;\n\n /**\n * 是否在第一次调用时立即执行\n * @default false\n */\n leading?: boolean;\n\n /**\n * 是否在调用结束后等待一段时间再执行\n * @default false\n */\n trailing?: boolean;\n};\n\n/**\n * 创建一个节流函数,该函数会在指定的等待时间内最多执行一次,如果在等待时间内再次调用,则忽略后续调用。\n *\n * @param fn - 需要节流的函数。\n * @param wait - 等待时间(毫秒)或包含 `wait`、`leading` 和 `trailing` 选项的对象。\n * @returns 返回一个节流函数,该函数具有 `cancel` 方法,用于取消节流操作。\n *\n * @example\n * ```typescript\n * const throttledFn = fnThrottle(() => {\n * console.log('Throttled!');\n * }, 100);\n *\n * throttledFn(); // 立即执行\n * throttledFn(); // 忽略\n * throttledFn.cancel(); // 取消节流操作\n * ```\n */\nexport function fnThrottle<F extends AnyFunction>(fn: F, wait: number | TThrottleOptions) {\n const options = isNumber(wait) ? { wait } : wait;\n const waitFinal = options.wait;\n let lastTime = 0;\n let canceled = false;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n let timer: any;\n\n const throttled = function (this: unknown, ...args: Parameters<F>) {\n if (canceled) return;\n\n const now = Date.now();\n\n // 第一次执行\n if (options.leading && lastTime === 0) {\n lastTime = now;\n fn.apply(this, args);\n }\n\n // 中间控频执行\n else if (lastTime > 0 && now - lastTime >= waitFinal) {\n lastTime = now;\n fn.apply(this, args);\n }\n\n // 首次计时\n else if (lastTime === 0) {\n lastTime = now;\n }\n\n // 最后一次执行\n if (options.trailing) {\n clearTimeout(timer);\n timer = setTimeout(() => {\n fn.apply(this, args);\n }, waitFinal);\n }\n };\n\n throttled.cancel = () => {\n canceled = true;\n clearTimeout(timer);\n };\n\n return throttled;\n}\n\n/**\n * 创建一个只执行一次的函数,无论调用多少次,实际执行的函数体也只会执行一次。\n *\n * @param fn - 需要只执行一次的函数。\n * @returns 返回一个只执行一次的函数,该函数在第一次调用后会缓存结果并返回缓存的结果。\n *\n * @example\n * ```typescript\n * const onceFn = fnOnce(() => {\n * console.log('This will be logged only once.');\n * return 42;\n * });\n *\n * console.log(onceFn()); // 输出: This will be logged only once. 42\n * console.log(onceFn()); // 输出: 42\n * ```\n */\nexport function fnOnce<F extends AnyFunction>(fn: F) {\n let called = false;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n let result: any;\n\n return function (this: unknown, ...args: Parameters<F>) {\n if (!called) {\n called = true;\n result = fn.apply(this, args);\n }\n\n return result;\n };\n}\n"],"names":[],"mappings":";AAWO,SAAS,SAAS;AAEzB;AAmCgB,SAAA,WAAkC,IAAO,MAAiC;AACxF,QAAM,UAA4B,SAAS,IAAI,IAAI,EAAE,KAAS,IAAA;AAC9D,MAAI,WAAW;AAEX,MAAA;AACJ,MAAI,UAAU;AAER,QAAA,YAAY,YAA4B,MAAqB;AACjE,QAAI,SAAU;AAGV,QAAA,QAAQ,WAAW,CAAC,SAAS;AACrB,gBAAA;AACP,SAAA,MAAM,MAAM,IAAI;AACnB;AAAA,IAAA;AAIF,iBAAa,KAAK;AAClB,YAAQ,WAAW,MAAM;AACvB,UAAI,SAAU;AAEX,SAAA,MAAM,MAAM,IAAI;AAAA,IAAA,GAClB,QAAQ,IAAI;AAAA,EACjB;AAEA,YAAU,SAAS,MAAM;AACvB,iBAAa,KAAK;AACP,eAAA;AAAA,EACb;AAEO,SAAA;AACT;AAuCgB,SAAA,WAAkC,IAAO,MAAiC;AACxF,QAAM,UAAU,SAAS,IAAI,IAAI,EAAE,KAAS,IAAA;AAC5C,QAAM,YAAY,QAAQ;AAC1B,MAAI,WAAW;AACf,MAAI,WAAW;AAEX,MAAA;AAEE,QAAA,YAAY,YAA4B,MAAqB;AACjE,QAAI,SAAU;AAER,UAAA,MAAM,KAAK,IAAI;AAGjB,QAAA,QAAQ,WAAW,aAAa,GAAG;AAC1B,iBAAA;AACR,SAAA,MAAM,MAAM,IAAI;AAAA,IAIZ,WAAA,WAAW,KAAK,MAAM,YAAY,WAAW;AACzC,iBAAA;AACR,SAAA,MAAM,MAAM,IAAI;AAAA,IAAA,WAIZ,aAAa,GAAG;AACZ,iBAAA;AAAA,IAAA;AAIb,QAAI,QAAQ,UAAU;AACpB,mBAAa,KAAK;AAClB,cAAQ,WAAW,MAAM;AACpB,WAAA,MAAM,MAAM,IAAI;AAAA,SAClB,SAAS;AAAA,IAAA;AAAA,EAEhB;AAEA,YAAU,SAAS,MAAM;AACZ,eAAA;AACX,iBAAa,KAAK;AAAA,EACpB;AAEO,SAAA;AACT;AAmBO,SAAS,OAA8B,IAAO;AACnD,MAAI,SAAS;AAET,MAAA;AAEJ,SAAO,YAA4B,MAAqB;AACtD,QAAI,CAAC,QAAQ;AACF,eAAA;AACA,eAAA,GAAG,MAAM,MAAM,IAAI;AAAA,IAAA;AAGvB,WAAA;AAAA,EACT;AACF;"}
package/dist/index.cjs ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const VERSION = "1.1.1";
4
+ exports.VERSION = VERSION;
5
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["export const VERSION = PKG_VERSION;\n"],"names":[],"mappings":";;AAAO,MAAM,UAAU;;"}
@@ -0,0 +1 @@
1
+ export declare const VERSION: string;
package/dist/index.mjs ADDED
@@ -0,0 +1,5 @@
1
+ const VERSION = "1.1.1";
2
+ export {
3
+ VERSION
4
+ };
5
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["export const VERSION = PKG_VERSION;\n"],"names":[],"mappings":"AAAO,MAAM,UAAU;"}
package/dist/merge.cjs ADDED
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ const type = require("./type.cjs");
3
+ const each = require("./each.cjs");
4
+ function _objectMerge(mergeRule, target, ...sources) {
5
+ const seen = /* @__PURE__ */ new WeakMap();
6
+ const { assign, next } = mergeRule;
7
+ const align = (target2, source) => {
8
+ const targetType = type.typeIs(target2);
9
+ const sourceType = type.typeIs(source);
10
+ if (targetType === sourceType) {
11
+ return target2;
12
+ }
13
+ return sourceType === "array" ? [] : {};
14
+ };
15
+ const each$1 = (source, iterator) => {
16
+ if (type.isObject(source)) {
17
+ each.objectEach(source, iterator);
18
+ } else {
19
+ source.forEach(iterator);
20
+ }
21
+ };
22
+ const merge = (target2, source) => {
23
+ if (seen.has(source)) {
24
+ return seen.get(source);
25
+ }
26
+ const merged = align(target2, source);
27
+ seen.set(source, merged);
28
+ each$1(source, (value, key) => {
29
+ if (!next({ target: merged, source, key })) {
30
+ return;
31
+ }
32
+ if (type.isObject(value) || type.isArray(value)) {
33
+ merged[key] = assign({
34
+ target: merged,
35
+ source,
36
+ key,
37
+ // @ts-expect-error
38
+ merge: () => merge(merged[key], value)
39
+ });
40
+ } else {
41
+ merged[key] = assign({
42
+ target: merged,
43
+ source,
44
+ key,
45
+ merge: () => value
46
+ });
47
+ }
48
+ });
49
+ return merged;
50
+ };
51
+ let returnTarget = target;
52
+ for (const source of sources) {
53
+ returnTarget = merge(target, source);
54
+ }
55
+ return returnTarget;
56
+ }
57
+ function objectMerge(target, ...sources) {
58
+ return _objectMerge(
59
+ {
60
+ next() {
61
+ return true;
62
+ },
63
+ assign({ merge }) {
64
+ return merge();
65
+ }
66
+ },
67
+ target,
68
+ ...sources
69
+ );
70
+ }
71
+ function objectDefaults(target, defaults) {
72
+ return _objectMerge(
73
+ {
74
+ next({ target: target2, source, key }) {
75
+ return target2[key] === void 0 || type.isObject(target2[key]) || type.isArray(target2[key]);
76
+ },
77
+ assign({ merge }) {
78
+ return merge();
79
+ }
80
+ },
81
+ target,
82
+ defaults
83
+ );
84
+ }
85
+ exports.objectDefaults = objectDefaults;
86
+ exports.objectMerge = objectMerge;
87
+ //# sourceMappingURL=merge.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.cjs","sources":["../src/object/merge.ts"],"sourcesContent":["import { isArray, isObject, typeIs } from '@/type';\nimport type { AnyArray, AnyObject } from '@/types';\nimport { objectEach } from './each';\n\nexport type TObjectMergeRule = {\n /**\n * 处理冲突\n * @param target - 目标对象\n * @param source - 源对象\n * @param key - 键名\n * @returns 返回 true 表示继续处理,否则返回 false\n */\n next: (info: {\n target: AnyObject | AnyArray;\n source: AnyObject | AnyArray;\n key: string | number;\n }) => boolean;\n\n /**\n * 处理赋值\n * @param target - 目标对象\n * @param source - 源对象\n * @param key - 键名\n * @returns 返回处理后的值\n */\n assign: (info: {\n target: AnyObject | AnyArray;\n source: AnyObject | AnyArray;\n key: string | number;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n merge: () => any;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n }) => any;\n};\n\nfunction _objectMerge(mergeRule: TObjectMergeRule, target: AnyObject | AnyArray, ...sources: (AnyObject | AnyArray)[]) {\n const seen = new WeakMap<AnyObject | AnyArray, AnyObject | AnyArray>();\n const { assign, next } = mergeRule;\n const align = (target: AnyObject | AnyArray, source: AnyObject | AnyArray) => {\n const targetType = typeIs(target);\n const sourceType = typeIs(source);\n\n if (targetType === sourceType) {\n return target;\n }\n\n return sourceType === 'array' ? [] : {};\n };\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n const each = (source: AnyObject | AnyArray, iterator: (val: any, key: string | number) => void) => {\n if (isObject(source)) {\n objectEach(source, iterator);\n } else {\n source.forEach(iterator);\n }\n };\n\n const merge = (target: AnyObject | AnyArray, source: AnyObject | AnyArray): AnyObject | AnyArray => {\n // 如果循环引用了,则直接返回目标对象\n if (seen.has(source)) {\n // biome-ignore lint/style/noNonNullAssertion: <explanation>\n return seen.get(source)!;\n }\n\n // 对齐目标对象和源对象\n const merged = align(target, source);\n\n // 存储循环引用\n seen.set(source, merged);\n\n // 遍历源对象\n each(source, (value, key) => {\n if (!next({ target: merged, source, key })) {\n return;\n }\n\n if (isObject(value) || isArray(value)) {\n // @ts-expect-error\n merged[key] = assign({\n target: merged,\n source,\n key,\n // @ts-expect-error\n merge: () => merge(merged[key], value),\n });\n } else {\n // @ts-expect-error\n merged[key] = assign({\n target: merged,\n source,\n key,\n merge: () => value,\n });\n }\n });\n\n return merged;\n };\n\n let returnTarget = target;\n\n for (const source of sources) {\n returnTarget = merge(target, source);\n }\n\n return returnTarget;\n}\n\n/**\n * 合并多个对象或数组。如果遇到循环引用,则直接返回目标对象。\n *\n * @param target - 目标对象或数组。\n * @param sources - 要合并的源对象或数组。\n * @returns 合并后的对象或数组。\n *\n * @example\n * ```typescript\n * const obj1 = { a: 1, b: { x: 10 } };\n * const obj2 = { b: { y: 20 }, c: 3 };\n * const merged = objectMerge(obj1, obj2);\n * console.log(merged); // { a: 1, b: { x: 10, y: 20 }, c: 3 }\n * ```\n */\nexport function objectMerge(target: AnyObject | AnyArray, ...sources: (AnyObject | AnyArray)[]) {\n return _objectMerge(\n {\n next() {\n return true;\n },\n assign({ merge }) {\n return merge();\n },\n },\n target,\n ...sources,\n );\n}\n\n/**\n * 为对象设置默认值。如果目标对象中的属性为 `undefined`,则使用默认对象中的属性值。\n * 支持多个默认对象,优先级从左到右依次降低。\n * 如果目标对象中的属性已经是对象或数组,则递归地设置默认值。\n *\n * @param target - 目标对象或数组。\n * @param defaults - 默认对象或数组。\n * @returns 合并后的对象或数组。\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: undefined };\n * const defaults = { a: 4, b: 2, c: 3 };\n * const result = objectDefaults(obj, defaults);\n * console.log(result); // { a: 1, b: 2, c: 3 }\n *\n * const obj2 = { a: 1, b: 2 };\n * const defaults2 = { a: 5, b: 3, c: 4 };\n * const result2 = objectDefaults(obj2, defaults2);\n * console.log(result2); // { a: 1, b: 2, c: 4 }\n *\n * const obj3 = { a: { x: 1 }, b: undefined };\n * const defaults3 = { a: { x: 4, z: 3 }, b: { y: 2 } };\n * const result3 = objectDefaults(obj3, defaults3);\n * console.log(result3); // { a: { x: 1, z: 3 }, b: { y: 2 } }\n * ```\n */\nexport function objectDefaults<T extends AnyObject | AnyArray>(target: T, defaults: T): T {\n return _objectMerge(\n {\n next({ target, source, key }) {\n // @ts-expect-error\n return target[key] === undefined || isObject(target[key]) || isArray(target[key]);\n },\n assign({ merge }) {\n return merge();\n },\n },\n target,\n defaults,\n ) as T;\n}\n"],"names":["target","typeIs","each","isObject","objectEach","isArray"],"mappings":";;;AAmCA,SAAS,aAAa,WAA6B,WAAiC,SAAmC;AAC/G,QAAA,2BAAW,QAAoD;AAC/D,QAAA,EAAE,QAAQ,KAAA,IAAS;AACnB,QAAA,QAAQ,CAACA,SAA8B,WAAiC;AACtE,UAAA,aAAaC,YAAOD,OAAM;AAC1B,UAAA,aAAaC,YAAO,MAAM;AAEhC,QAAI,eAAe,YAAY;AACtBD,aAAAA;AAAAA,IAAA;AAGT,WAAO,eAAe,UAAU,CAAA,IAAK,CAAC;AAAA,EACxC;AAEM,QAAAE,SAAO,CAAC,QAA8B,aAAuD;AAC7F,QAAAC,KAAAA,SAAS,MAAM,GAAG;AACpBC,WAAA,WAAW,QAAQ,QAAQ;AAAA,IAAA,OACtB;AACL,aAAO,QAAQ,QAAQ;AAAA,IAAA;AAAA,EAE3B;AAEM,QAAA,QAAQ,CAACJ,SAA8B,WAAuD;AAE9F,QAAA,KAAK,IAAI,MAAM,GAAG;AAEb,aAAA,KAAK,IAAI,MAAM;AAAA,IAAA;AAIlB,UAAA,SAAS,MAAMA,SAAQ,MAAM;AAG9B,SAAA,IAAI,QAAQ,MAAM;AAGlBE,WAAA,QAAQ,CAAC,OAAO,QAAQ;AACvB,UAAA,CAAC,KAAK,EAAE,QAAQ,QAAQ,QAAQ,IAAA,CAAK,GAAG;AAC1C;AAAA,MAAA;AAGF,UAAIC,KAAS,SAAA,KAAK,KAAKE,KAAA,QAAQ,KAAK,GAAG;AAE9B,eAAA,GAAG,IAAI,OAAO;AAAA,UACnB,QAAQ;AAAA,UACR;AAAA,UACA;AAAA;AAAA,UAEA,OAAO,MAAM,MAAM,OAAO,GAAG,GAAG,KAAK;AAAA,QAAA,CACtC;AAAA,MAAA,OACI;AAEE,eAAA,GAAG,IAAI,OAAO;AAAA,UACnB,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,UACA,OAAO,MAAM;AAAA,QAAA,CACd;AAAA,MAAA;AAAA,IACH,CACD;AAEM,WAAA;AAAA,EACT;AAEA,MAAI,eAAe;AAEnB,aAAW,UAAU,SAAS;AACb,mBAAA,MAAM,QAAQ,MAAM;AAAA,EAAA;AAG9B,SAAA;AACT;AAiBgB,SAAA,YAAY,WAAiC,SAAmC;AACvF,SAAA;AAAA,IACL;AAAA,MACE,OAAO;AACE,eAAA;AAAA,MACT;AAAA,MACA,OAAO,EAAE,SAAS;AAChB,eAAO,MAAM;AAAA,MAAA;AAAA,IAEjB;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AACF;AA6BgB,SAAA,eAA+C,QAAW,UAAgB;AACjF,SAAA;AAAA,IACL;AAAA,MACE,KAAK,EAAE,QAAAL,SAAQ,QAAQ,OAAO;AAE5B,eAAOA,QAAO,GAAG,MAAM,UAAaG,KAAAA,SAASH,QAAO,GAAG,CAAC,KAAKK,KAAAA,QAAQL,QAAO,GAAG,CAAC;AAAA,MAClF;AAAA,MACA,OAAO,EAAE,SAAS;AAChB,eAAO,MAAM;AAAA,MAAA;AAAA,IAEjB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;"}
package/dist/merge.mjs ADDED
@@ -0,0 +1,88 @@
1
+ import { typeIs, isObject, isArray } from "./type.mjs";
2
+ import { o as objectEach } from "./each.mjs";
3
+ function _objectMerge(mergeRule, target, ...sources) {
4
+ const seen = /* @__PURE__ */ new WeakMap();
5
+ const { assign, next } = mergeRule;
6
+ const align = (target2, source) => {
7
+ const targetType = typeIs(target2);
8
+ const sourceType = typeIs(source);
9
+ if (targetType === sourceType) {
10
+ return target2;
11
+ }
12
+ return sourceType === "array" ? [] : {};
13
+ };
14
+ const each = (source, iterator) => {
15
+ if (isObject(source)) {
16
+ objectEach(source, iterator);
17
+ } else {
18
+ source.forEach(iterator);
19
+ }
20
+ };
21
+ const merge = (target2, source) => {
22
+ if (seen.has(source)) {
23
+ return seen.get(source);
24
+ }
25
+ const merged = align(target2, source);
26
+ seen.set(source, merged);
27
+ each(source, (value, key) => {
28
+ if (!next({ target: merged, source, key })) {
29
+ return;
30
+ }
31
+ if (isObject(value) || isArray(value)) {
32
+ merged[key] = assign({
33
+ target: merged,
34
+ source,
35
+ key,
36
+ // @ts-expect-error
37
+ merge: () => merge(merged[key], value)
38
+ });
39
+ } else {
40
+ merged[key] = assign({
41
+ target: merged,
42
+ source,
43
+ key,
44
+ merge: () => value
45
+ });
46
+ }
47
+ });
48
+ return merged;
49
+ };
50
+ let returnTarget = target;
51
+ for (const source of sources) {
52
+ returnTarget = merge(target, source);
53
+ }
54
+ return returnTarget;
55
+ }
56
+ function objectMerge(target, ...sources) {
57
+ return _objectMerge(
58
+ {
59
+ next() {
60
+ return true;
61
+ },
62
+ assign({ merge }) {
63
+ return merge();
64
+ }
65
+ },
66
+ target,
67
+ ...sources
68
+ );
69
+ }
70
+ function objectDefaults(target, defaults) {
71
+ return _objectMerge(
72
+ {
73
+ next({ target: target2, source, key }) {
74
+ return target2[key] === void 0 || isObject(target2[key]) || isArray(target2[key]);
75
+ },
76
+ assign({ merge }) {
77
+ return merge();
78
+ }
79
+ },
80
+ target,
81
+ defaults
82
+ );
83
+ }
84
+ export {
85
+ objectMerge as a,
86
+ objectDefaults as o
87
+ };
88
+ //# sourceMappingURL=merge.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.mjs","sources":["../src/object/merge.ts"],"sourcesContent":["import { isArray, isObject, typeIs } from '@/type';\nimport type { AnyArray, AnyObject } from '@/types';\nimport { objectEach } from './each';\n\nexport type TObjectMergeRule = {\n /**\n * 处理冲突\n * @param target - 目标对象\n * @param source - 源对象\n * @param key - 键名\n * @returns 返回 true 表示继续处理,否则返回 false\n */\n next: (info: {\n target: AnyObject | AnyArray;\n source: AnyObject | AnyArray;\n key: string | number;\n }) => boolean;\n\n /**\n * 处理赋值\n * @param target - 目标对象\n * @param source - 源对象\n * @param key - 键名\n * @returns 返回处理后的值\n */\n assign: (info: {\n target: AnyObject | AnyArray;\n source: AnyObject | AnyArray;\n key: string | number;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n merge: () => any;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n }) => any;\n};\n\nfunction _objectMerge(mergeRule: TObjectMergeRule, target: AnyObject | AnyArray, ...sources: (AnyObject | AnyArray)[]) {\n const seen = new WeakMap<AnyObject | AnyArray, AnyObject | AnyArray>();\n const { assign, next } = mergeRule;\n const align = (target: AnyObject | AnyArray, source: AnyObject | AnyArray) => {\n const targetType = typeIs(target);\n const sourceType = typeIs(source);\n\n if (targetType === sourceType) {\n return target;\n }\n\n return sourceType === 'array' ? [] : {};\n };\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n const each = (source: AnyObject | AnyArray, iterator: (val: any, key: string | number) => void) => {\n if (isObject(source)) {\n objectEach(source, iterator);\n } else {\n source.forEach(iterator);\n }\n };\n\n const merge = (target: AnyObject | AnyArray, source: AnyObject | AnyArray): AnyObject | AnyArray => {\n // 如果循环引用了,则直接返回目标对象\n if (seen.has(source)) {\n // biome-ignore lint/style/noNonNullAssertion: <explanation>\n return seen.get(source)!;\n }\n\n // 对齐目标对象和源对象\n const merged = align(target, source);\n\n // 存储循环引用\n seen.set(source, merged);\n\n // 遍历源对象\n each(source, (value, key) => {\n if (!next({ target: merged, source, key })) {\n return;\n }\n\n if (isObject(value) || isArray(value)) {\n // @ts-expect-error\n merged[key] = assign({\n target: merged,\n source,\n key,\n // @ts-expect-error\n merge: () => merge(merged[key], value),\n });\n } else {\n // @ts-expect-error\n merged[key] = assign({\n target: merged,\n source,\n key,\n merge: () => value,\n });\n }\n });\n\n return merged;\n };\n\n let returnTarget = target;\n\n for (const source of sources) {\n returnTarget = merge(target, source);\n }\n\n return returnTarget;\n}\n\n/**\n * 合并多个对象或数组。如果遇到循环引用,则直接返回目标对象。\n *\n * @param target - 目标对象或数组。\n * @param sources - 要合并的源对象或数组。\n * @returns 合并后的对象或数组。\n *\n * @example\n * ```typescript\n * const obj1 = { a: 1, b: { x: 10 } };\n * const obj2 = { b: { y: 20 }, c: 3 };\n * const merged = objectMerge(obj1, obj2);\n * console.log(merged); // { a: 1, b: { x: 10, y: 20 }, c: 3 }\n * ```\n */\nexport function objectMerge(target: AnyObject | AnyArray, ...sources: (AnyObject | AnyArray)[]) {\n return _objectMerge(\n {\n next() {\n return true;\n },\n assign({ merge }) {\n return merge();\n },\n },\n target,\n ...sources,\n );\n}\n\n/**\n * 为对象设置默认值。如果目标对象中的属性为 `undefined`,则使用默认对象中的属性值。\n * 支持多个默认对象,优先级从左到右依次降低。\n * 如果目标对象中的属性已经是对象或数组,则递归地设置默认值。\n *\n * @param target - 目标对象或数组。\n * @param defaults - 默认对象或数组。\n * @returns 合并后的对象或数组。\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: undefined };\n * const defaults = { a: 4, b: 2, c: 3 };\n * const result = objectDefaults(obj, defaults);\n * console.log(result); // { a: 1, b: 2, c: 3 }\n *\n * const obj2 = { a: 1, b: 2 };\n * const defaults2 = { a: 5, b: 3, c: 4 };\n * const result2 = objectDefaults(obj2, defaults2);\n * console.log(result2); // { a: 1, b: 2, c: 4 }\n *\n * const obj3 = { a: { x: 1 }, b: undefined };\n * const defaults3 = { a: { x: 4, z: 3 }, b: { y: 2 } };\n * const result3 = objectDefaults(obj3, defaults3);\n * console.log(result3); // { a: { x: 1, z: 3 }, b: { y: 2 } }\n * ```\n */\nexport function objectDefaults<T extends AnyObject | AnyArray>(target: T, defaults: T): T {\n return _objectMerge(\n {\n next({ target, source, key }) {\n // @ts-expect-error\n return target[key] === undefined || isObject(target[key]) || isArray(target[key]);\n },\n assign({ merge }) {\n return merge();\n },\n },\n target,\n defaults,\n ) as T;\n}\n"],"names":["target"],"mappings":";;AAmCA,SAAS,aAAa,WAA6B,WAAiC,SAAmC;AAC/G,QAAA,2BAAW,QAAoD;AAC/D,QAAA,EAAE,QAAQ,KAAA,IAAS;AACnB,QAAA,QAAQ,CAACA,SAA8B,WAAiC;AACtE,UAAA,aAAa,OAAOA,OAAM;AAC1B,UAAA,aAAa,OAAO,MAAM;AAEhC,QAAI,eAAe,YAAY;AACtBA,aAAAA;AAAAA,IAAA;AAGT,WAAO,eAAe,UAAU,CAAA,IAAK,CAAC;AAAA,EACxC;AAEM,QAAA,OAAO,CAAC,QAA8B,aAAuD;AAC7F,QAAA,SAAS,MAAM,GAAG;AACpB,iBAAW,QAAQ,QAAQ;AAAA,IAAA,OACtB;AACL,aAAO,QAAQ,QAAQ;AAAA,IAAA;AAAA,EAE3B;AAEM,QAAA,QAAQ,CAACA,SAA8B,WAAuD;AAE9F,QAAA,KAAK,IAAI,MAAM,GAAG;AAEb,aAAA,KAAK,IAAI,MAAM;AAAA,IAAA;AAIlB,UAAA,SAAS,MAAMA,SAAQ,MAAM;AAG9B,SAAA,IAAI,QAAQ,MAAM;AAGlB,SAAA,QAAQ,CAAC,OAAO,QAAQ;AACvB,UAAA,CAAC,KAAK,EAAE,QAAQ,QAAQ,QAAQ,IAAA,CAAK,GAAG;AAC1C;AAAA,MAAA;AAGF,UAAI,SAAS,KAAK,KAAK,QAAQ,KAAK,GAAG;AAE9B,eAAA,GAAG,IAAI,OAAO;AAAA,UACnB,QAAQ;AAAA,UACR;AAAA,UACA;AAAA;AAAA,UAEA,OAAO,MAAM,MAAM,OAAO,GAAG,GAAG,KAAK;AAAA,QAAA,CACtC;AAAA,MAAA,OACI;AAEE,eAAA,GAAG,IAAI,OAAO;AAAA,UACnB,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,UACA,OAAO,MAAM;AAAA,QAAA,CACd;AAAA,MAAA;AAAA,IACH,CACD;AAEM,WAAA;AAAA,EACT;AAEA,MAAI,eAAe;AAEnB,aAAW,UAAU,SAAS;AACb,mBAAA,MAAM,QAAQ,MAAM;AAAA,EAAA;AAG9B,SAAA;AACT;AAiBgB,SAAA,YAAY,WAAiC,SAAmC;AACvF,SAAA;AAAA,IACL;AAAA,MACE,OAAO;AACE,eAAA;AAAA,MACT;AAAA,MACA,OAAO,EAAE,SAAS;AAChB,eAAO,MAAM;AAAA,MAAA;AAAA,IAEjB;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AACF;AA6BgB,SAAA,eAA+C,QAAW,UAAgB;AACjF,SAAA;AAAA,IACL;AAAA,MACE,KAAK,EAAE,QAAAA,SAAQ,QAAQ,OAAO;AAE5B,eAAOA,QAAO,GAAG,MAAM,UAAa,SAASA,QAAO,GAAG,CAAC,KAAK,QAAQA,QAAO,GAAG,CAAC;AAAA,MAClF;AAAA,MACA,OAAO,EAAE,SAAS;AAChB,eAAO,MAAM;AAAA,MAAA;AAAA,IAEjB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ require("./merge.cjs");
4
+ const number = require("./string2.cjs");
5
+ require("./type.cjs");
6
+ exports.fileSizeAbbr = number.fileSizeAbbr;
7
+ exports.numberAbbr = number.numberAbbr;
8
+ exports.numberClamp = number.numberClamp;
9
+ exports.numberConvert = number.numberConvert;
10
+ exports.numberFixed = number.numberFixed;
11
+ exports.numberFormat = number.numberFormat;
12
+ exports.numberUnit = number.numberUnit;
13
+ exports.randomNumber = number.randomNumber;
14
+ //# sourceMappingURL=number.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}