@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
package/src/easing.ts DELETED
@@ -1,166 +0,0 @@
1
- /**
2
- * https://github.com/gre/bezier-easing
3
- * BezierEasing - use bezier curve for transition easing function
4
- * by Gaëtan Renaudeau 2014 - 2015 – MIT License
5
- */
6
-
7
- // These values are established by empiricism with tests (tradeoff: performance VS precision)
8
- const NEWTON_ITERATIONS = 4;
9
- const NEWTON_MIN_SLOPE = 0.001;
10
- const SUBDIVISION_PRECISION = 0.0000001;
11
- const SUBDIVISION_MAX_ITERATIONS = 10;
12
-
13
- const kSplineTableSize = 11;
14
- const kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
15
-
16
- const float32ArraySupported = typeof Float32Array === 'function';
17
-
18
- function A(aA1: number, aA2: number) {
19
- return 1.0 - 3.0 * aA2 + 3.0 * aA1;
20
- }
21
- function B(aA1: number, aA2: number) {
22
- return 3.0 * aA2 - 6.0 * aA1;
23
- }
24
- function C(aA1: number) {
25
- return 3.0 * aA1;
26
- }
27
-
28
- // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
29
- function calcBezier(aT: number, aA1: number, aA2: number) {
30
- return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
31
- }
32
-
33
- // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
34
- function getSlope(aT: number, aA1: number, aA2: number) {
35
- return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
36
- }
37
-
38
- function binarySubdivide(aX: number, aA: number, aB: number, mX1: number, mX2: number) {
39
- let currentX: number;
40
- let currentT: number;
41
- let i = 0;
42
- let aBFinal = aB;
43
- let aAFinal = aA;
44
-
45
- do {
46
- currentT = aAFinal + (aBFinal - aAFinal) / 2.0;
47
- currentX = calcBezier(currentT, mX1, mX2) - aX;
48
- if (currentX > 0.0) {
49
- aBFinal = currentT;
50
- } else {
51
- aAFinal = currentT;
52
- }
53
- } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
54
- return currentT;
55
- }
56
-
57
- function newtonRaphsonIterate(aX: number, aGuessT: number, mX1: number, mX2: number) {
58
- let aGuessTFinal = aGuessT;
59
- for (let i = 0; i < NEWTON_ITERATIONS; ++i) {
60
- const currentSlope = getSlope(aGuessTFinal, mX1, mX2);
61
- if (currentSlope === 0.0) {
62
- return aGuessTFinal;
63
- }
64
- const currentX = calcBezier(aGuessTFinal, mX1, mX2) - aX;
65
- aGuessTFinal -= currentX / currentSlope;
66
- }
67
- return aGuessTFinal;
68
- }
69
-
70
- function LinearEasing(x: number) {
71
- return x;
72
- }
73
-
74
- /**
75
- * 创建一个基于贝塞尔曲线的缓动函数。
76
- *
77
- * @param x1 - 贝塞尔曲线的第一个控制点的 X 坐标,必须在 [0, 1] 范围内。
78
- * @param y1 - 贝塞尔曲线的第一个控制点的 Y 坐标,必须在 [0, 1] 范围内。
79
- * @param x2 - 贝塞尔曲线的第二个控制点的 X 坐标,必须在 [0, 1] 范围内。
80
- * @param y2 - 贝塞尔曲线的第二个控制点的 Y 坐标,必须在 [0, 1] 范围内。
81
- * @returns 返回一个缓动函数,该函数接受一个参数 x(范围在 0 到 1 之间),并返回相应的缓动值。
82
- * @throws 如果 mX1 或 mX2 不在 [0, 1] 范围内,则抛出错误。
83
- */
84
- export function createEasingFn(x1: number, y1: number, x2: number, y2: number) {
85
- if (!(0 <= x1 && x1 <= 1 && 0 <= x2 && x2 <= 1)) {
86
- throw new Error('bezier x values must be in [0, 1] range');
87
- }
88
-
89
- if (x1 === y1 && x2 === y2) {
90
- return LinearEasing;
91
- }
92
-
93
- // Precompute samples table
94
- const sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
95
- for (let i = 0; i < kSplineTableSize; ++i) {
96
- sampleValues[i] = calcBezier(i * kSampleStepSize, x1, x2);
97
- }
98
-
99
- function getTForX(aX: number) {
100
- let intervalStart = 0.0;
101
- let currentSample = 1;
102
- const lastSample = kSplineTableSize - 1;
103
-
104
- for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
105
- intervalStart += kSampleStepSize;
106
- }
107
- --currentSample;
108
-
109
- // Interpolate to provide an initial guess for t
110
- const dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
111
- const guessForT = intervalStart + dist * kSampleStepSize;
112
- const initialSlope = getSlope(guessForT, x1, x2);
113
-
114
- if (initialSlope >= NEWTON_MIN_SLOPE) {
115
- return newtonRaphsonIterate(aX, guessForT, x1, x2);
116
- }
117
-
118
- if (initialSlope === 0.0) {
119
- return guessForT;
120
- }
121
-
122
- return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, x1, x2);
123
- }
124
-
125
- /**
126
- * 贝塞尔曲线方程
127
- * @param x {number} 0~1
128
- */
129
- return function easingFunc(x: number) {
130
- // Because JavaScript number are imprecise, we should guarantee the extremes are right.
131
- if (x === 0 || x === 1) {
132
- return x;
133
- }
134
-
135
- return calcBezier(getTForX(x), y1, y2);
136
- };
137
- }
138
-
139
- export const easingEase = createEasingFn(0.25, 0.1, 0.25, 1);
140
- export const easingLinear = createEasingFn(0, 0, 1, 1);
141
- export const easingSnap = createEasingFn(0, 1, 0.5, 1);
142
- export const easingIn = createEasingFn(0.42, 0, 1, 1);
143
- export const easingOut = createEasingFn(0, 0, 0.58, 1);
144
- export const easingInOut = createEasingFn(0.42, 0, 0.58, 1);
145
- export const easingInQuad = createEasingFn(0.55, 0.085, 0.68, 0.53);
146
- export const easingInCubic = createEasingFn(0.55, 0.055, 0.675, 0.19);
147
- export const easingInQuart = createEasingFn(0.895, 0.03, 0.685, 0.22);
148
- export const easingInQuint = createEasingFn(0.755, 0.05, 0.855, 0.06);
149
- export const easingInSine = createEasingFn(0.47, 0, 0.745, 0.715);
150
- export const easingInExpo = createEasingFn(0.95, 0.05, 0.795, 0.035);
151
- export const easingInCirc = createEasingFn(0.6, 0.04, 0.98, 0.335);
152
- export const easingInBack = createEasingFn(0.6, -0.28, 0.735, 0.045);
153
- export const easingOutQuad = createEasingFn(0.25, 0.46, 0.45, 0.94);
154
- export const easingOutCubic = createEasingFn(0.215, 0.61, 0.355, 1);
155
- export const easingOutQuart = createEasingFn(0.165, 0.84, 0.44, 1);
156
- export const easingOutQuint = createEasingFn(0.23, 1, 0.32, 1);
157
- export const easingOutSine = createEasingFn(0.39, 0.575, 0.565, 1);
158
- export const easingOutExpo = createEasingFn(0.19, 1, 0.22, 1);
159
- export const easingOutCirc = createEasingFn(0.075, 0.82, 0.165, 1);
160
- export const easingOutBack = createEasingFn(0.175, 0.885, 0.32, 1.275);
161
- export const easingInOutQuart = createEasingFn(0.77, 0, 0.175, 1);
162
- export const easingInOutQuint = createEasingFn(0.86, 0, 0.07, 1);
163
- export const easingInOutSine = createEasingFn(0.445, 0.05, 0.55, 0.95);
164
- export const easingInOutExpo = createEasingFn(1, 0, 0, 1);
165
- export const easingInOutCirc = createEasingFn(0.785, 0.135, 0.15, 0.86);
166
- export const easingInOutBack = createEasingFn(0.68, -0.55, 0.265, 1.55);
package/src/emitter.ts DELETED
@@ -1,117 +0,0 @@
1
- import type { AnyFunction, AnyObject } from './types';
2
-
3
- /**
4
- * 事件类型映射,key 为事件名称,value 为事件参数类型数组
5
- */
6
- export type EmitterMap = Record<string, unknown[]>;
7
-
8
- /**
9
- * 事件监听器函数类型
10
- * @template E - EmitterMap 类型
11
- * @template K - 事件名称类型
12
- */
13
- export type EmitterListener<E extends EmitterMap, K extends keyof E> = (...payloads: E[K]) => false | unknown;
14
-
15
- /**
16
- * 事件发射器类,用于管理事件监听和触发
17
- * @template E - 事件类型映射
18
- *
19
- * @example
20
- * type MyEvents = {
21
- * 'click': [x: number, y: number];
22
- * 'change': [value: string];
23
- * };
24
- *
25
- * const emitter = new Emitter<MyEvents>();
26
- * emitter.on('click', (x, y) => {
27
- * console.log(`Clicked at (${x}, ${y})`);
28
- * });
29
- * emitter.emit('click', 10, 20);
30
- */
31
- export class Emitter<E extends EmitterMap> {
32
- #events: Map<keyof E, Set<AnyFunction>> = new Map();
33
-
34
- /**
35
- * 注册事件监听器
36
- * @param event - 要监听的事件名称
37
- * @param listener - 事件监听器函数
38
- * @example
39
- * emitter.on('click', (x, y) => {
40
- * console.log(`Clicked at (${x}, ${y})`);
41
- * });
42
- */
43
- on<K extends keyof E>(event: K, listener: EmitterListener<E, K>) {
44
- const listeners = this.#events.get(event);
45
- if (listeners) {
46
- listeners.add(listener);
47
- } else {
48
- this.#events.set(event, new Set([listener]));
49
- }
50
- }
51
-
52
- /**
53
- * 移除事件监听器,有三种使用方式:
54
- * 1. 移除特定事件的特定监听器
55
- * 2. 移除特定事件的所有监听器
56
- * 3. 移除所有事件的所有监听器
57
- * @param event - 要移除的事件名称(可选)
58
- * @param listener - 要移除的监听器函数(可选)
59
- * @example
60
- * // 移除特定事件的特定监听器
61
- * emitter.off('click', clickHandler);
62
- *
63
- * // 移除特定事件的所有监听器
64
- * emitter.off('click');
65
- *
66
- * // 移除所有事件的所有监听器
67
- * emitter.off();
68
- */
69
- off<K extends keyof E>(event?: K, listener?: EmitterListener<E, K>) {
70
- if (event && listener) {
71
- this.#offListener(event, listener);
72
- } else if (event) {
73
- this.#offEvent(event);
74
- } else {
75
- this.#offAll();
76
- }
77
- }
78
-
79
- #offAll() {
80
- this.#events.clear();
81
- }
82
-
83
- #offEvent<K extends keyof E>(event: K) {
84
- this.#events.delete(event);
85
- }
86
-
87
- #offListener<K extends keyof E>(event: K, listener: EmitterListener<E, K>) {
88
- const listeners = this.#events.get(event);
89
-
90
- if (listeners) {
91
- listeners.delete(listener);
92
- }
93
- }
94
-
95
- /**
96
- * 触发指定事件,调用所有注册的监听器
97
- * @param event - 要触发的事件名称
98
- * @param payloads - 传递给监听器的参数
99
- * @remarks
100
- * 监听器会按照注册的顺序依次执行,如果某个监听器返回 false,
101
- * 则后续监听器将不会被执行
102
- * @example
103
- * emitter.emit('click', 10, 20);
104
- */
105
- emit<K extends keyof E>(event: K, ...payloads: Parameters<EmitterListener<E, K>>) {
106
- const listeners = this.#events.get(event) as Set<EmitterListener<E, K>> | undefined;
107
-
108
- if (!listeners) return;
109
-
110
- // 避免在 emit、on 的过程中改变 listeners 从而影响本次 emit
111
- for (const listener of [...listeners]) {
112
- if (listener(...payloads) === false) {
113
- break;
114
- }
115
- }
116
- }
117
- }
package/src/enum.ts DELETED
@@ -1,171 +0,0 @@
1
- import type { AnyObject, MergeIntersection, UnionToIntersection, UnionToTuple } from './types';
2
-
3
- export type EnumKey = string;
4
- export type EnumValue = number | string;
5
- export type EnumMetaAppend = {
6
- key?: string;
7
- value?: string | number;
8
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
9
- [key: string]: any;
10
- };
11
- export type EnumMeta<A extends EnumMetaAppend> = A & {
12
- value: EnumValue;
13
- };
14
- export type EnumDescription<A extends EnumMetaAppend> = Record<EnumKey, EnumMeta<A>>;
15
-
16
- const enumError = Symbol('enumKeyError');
17
-
18
- type _StartWithDollarSign<T extends string> = T extends `$${infer R}` ? R : never;
19
-
20
- type _CheckDefinition<O extends AnyObject> = {
21
- // [K in keyof O & string]: K extends Capitalize<K> ? O[K] : `错误:枚举键名 ${K} 必须大写字母开头`;
22
- [K in keyof O & string]: K extends Capitalize<K>
23
- ? K extends `$${infer R}`
24
- ? O[K] & { [enumError]: `错误:枚举键名 ${K} 不能以 $ 符号开头` }
25
- : O[K]
26
- : O[K] & { [enumError]: `错误:枚举键名 ${K} 必须以大写字母开头` };
27
- };
28
-
29
- type _ToOriginDefProp<T extends AnyObject> = {
30
- [K in keyof T as `$${K & string}`]: MergeIntersection<T[K] & { readonly key: K }>;
31
- };
32
-
33
- type _KVRecord<T> = T extends Record<string, AnyObject>
34
- ? {
35
- readonly [K in keyof T]: T[K]['value'];
36
- }
37
- : never;
38
-
39
- type _VKRecord<T> = T extends Record<string, AnyObject>
40
- ? MergeIntersection<
41
- UnionToIntersection<
42
- {
43
- [K in keyof T]: {
44
- [P in keyof T[K] as P extends 'value' ? T[K][P] & (string | number) : never]: K;
45
- };
46
- }[keyof T]
47
- >
48
- >
49
- : never;
50
-
51
- export type EnumExpose<A extends EnumMetaAppend, E extends EnumDescription<A>> = _ToOriginDefProp<E> &
52
- _KVRecord<E> & {
53
- readonly definition: E;
54
- readonly descriptions: MergeIntersection<A & { key: keyof E }>[];
55
- readonly keys: UnionToTuple<keyof E>;
56
- readonly length: UnionToTuple<keyof E>['length'];
57
- readonly values: UnionToTuple<E[keyof E]['value']>;
58
- readonly kvRecord: _KVRecord<E>;
59
- readonly vkRecord: _VKRecord<E>;
60
- toKeyRecord: <P extends keyof A>(prop: P) => Record<keyof E, A[P]>;
61
- toValueRecord: <P extends keyof A>(prop: P) => Record<E[keyof E]['value'], A[P]>;
62
- };
63
-
64
- /**
65
- * 定义一个枚举类型,如果需要类型提示,需要使用 declareEnum 函数定义枚举。
66
- * @template A - 枚举元数据附加类型,扩展自 EnumMetaAppend
67
- * @template E - 枚举描述类型,键为枚举键名,值为枚举元数据
68
- * @param {_CheckDefinition<E>} definition - 枚举定义对象
69
- * @returns {EnumExpose<A, E>} 返回枚举的完整暴露对象
70
- * @example
71
- * ```typescript
72
- * const Status = defineEnum({
73
- * Pending: { value: 0, label: '待处理' },
74
- * Approved: { value: 1, label: '已批准' }
75
- * });
76
- * ```
77
- *
78
- * @property {E} definition - 原始枚举定义对象
79
- * @property {Array<MergeIntersection<A & { key: keyof E }>>} descriptions - 枚举项的完整描述数组
80
- * @property {UnionToTuple<keyof E>} keys - 枚举键名的元组
81
- * @property {"UnionToTuple<keyof E>[\"length\"]"} length - 枚举项的数量
82
- * @property {UnionToTuple<E[keyof E]["value"]>} values - 枚举值的元组
83
- * @property {Record<keyof E, E[keyof E]["value"]>} kvRecord - 键到值的映射记录
84
- * @property {Record<E[keyof E]["value"], E[keyof E]>} vkRecord - 值到键的映射记录
85
- * @property {function} toKeyRecord - 根据属性名创建键到属性值的映射记录
86
- * @property {function} toValueRecord - 根据属性名创建值到属性值的映射记录
87
- */
88
- function defineEnum<A extends EnumMetaAppend, const E extends EnumDescription<A>>(
89
- definition: _CheckDefinition<E>,
90
- ): EnumExpose<A, E> {
91
- const keys = Object.keys(definition);
92
-
93
- return {
94
- ...[...Object.entries(definition)].reduce((acc, [key, dfn]) => {
95
- if (key[0].toUpperCase() !== key[0]) {
96
- throw new Error(`错误:枚举键名 ${key} 必须以大写字母开头`);
97
- }
98
-
99
- if (key.startsWith('$')) {
100
- throw new Error(`错误:枚举键名 ${key} 不能以 $ 符号开头`);
101
- }
102
-
103
- // @ts-ignore
104
- acc[key] = dfn.value;
105
- // @ts-ignore
106
- acc[`$${key}`] = { key, ...dfn };
107
- return acc;
108
- }, {}),
109
- definition,
110
- descriptions: keys.map((key) => ({
111
- key,
112
- ...definition[key],
113
- })),
114
- keys,
115
- length: keys.length,
116
- values: keys.map((key) => definition[key as keyof E].value),
117
- kvRecord: keys.reduce((acc, key) => {
118
- // @ts-ignore
119
- acc[key] = definition[key].value;
120
- return acc;
121
- }, {}),
122
- vkRecord: keys.reduce((acc, key) => {
123
- // @ts-ignore
124
- acc[definition[key].value] = key;
125
- return acc;
126
- }, {}),
127
- toKeyRecord<P extends keyof A>(prop: P) {
128
- return keys.reduce((acc, key) => {
129
- // @ts-ignore
130
- acc[key] = definition[key][prop];
131
- return acc;
132
- }, {});
133
- },
134
- toValueRecord<P extends keyof A>(prop: P) {
135
- return keys.reduce(
136
- (acc, key) => {
137
- // @ts-ignore
138
- acc[definition[key].value] = definition[key][prop];
139
- return acc;
140
- },
141
- {} as Record<E[keyof E]['value'], A[P]>,
142
- );
143
- },
144
- } as unknown as EnumExpose<A, E>;
145
- }
146
-
147
- /**
148
- * 声明一个枚举工厂函数
149
- * @template A - 枚举元数据附加类型,扩展自 EnumMetaAppend
150
- * @returns {Object} 返回包含 define 方法的对象
151
- *
152
- * @property {function} define - 定义枚举的函数
153
- * @template E - 枚举描述类型
154
- * @param {_CheckDefinition<E>} definition - 枚举定义对象
155
- * @returns {EnumExpose<A, E>} 返回枚举的完整暴露对象
156
- * @example
157
- * ```typescript
158
- * const createStatusEnum = declareEnum<{ label: string }>();
159
- * const Status = createStatusEnum.define({
160
- * Pending: { value: 0, label: '待处理' },
161
- * Approved: { value: 1, label: '已批准' }
162
- * });
163
- * ```
164
- */
165
- export function declareEnum<A extends EnumMetaAppend>() {
166
- return {
167
- define<const E extends EnumDescription<A>>(definition: _CheckDefinition<E>): EnumExpose<A, E> {
168
- return defineEnum(definition);
169
- },
170
- };
171
- }
package/src/exception.ts DELETED
@@ -1,68 +0,0 @@
1
- import { objectDefaults } from './object';
2
- import type { AnyObject } from './types';
3
-
4
- /**
5
- * 构建异常选项
6
- */
7
- export type BuildExceptionOptions = {
8
- /**
9
- * 自定义错误消息格式函数
10
- * @param name 错误名称
11
- * @param message 原始错误消息
12
- * @returns 格式化后的错误消息
13
- * @example
14
- * (name, message) => `${name}::${message}`
15
- */
16
- format?: (name: string, message: string) => string;
17
- };
18
-
19
- /**
20
- * 默认的异常构建选项
21
- */
22
- const defaults: BuildExceptionOptions = {
23
- /**
24
- * 默认消息格式函数
25
- * @default (name, message) => `[${name}] ${message}`
26
- */
27
- format: (name, message) => `[${name}] ${message}`,
28
- };
29
-
30
- /**
31
- * 构建自定义异常类
32
- * @template T 额外属性的类型
33
- * @param name 异常类名称
34
- * @param options 构建选项
35
- * @returns 自定义异常类
36
- * @example
37
- * const MyException = buildException<{ code: number }>('MyException');
38
- * const err = new MyException('error', { code: 404 });
39
- *
40
- * @example
41
- * const SimpleException = buildException('SimpleException');
42
- * const err = new SimpleException('error', undefined);
43
- */
44
- export function buildException<T = void>(name: string, options?: BuildExceptionOptions) {
45
- const { format } = objectDefaults(options || {}, defaults) as Required<BuildExceptionOptions>;
46
-
47
- return class extends Error {
48
- constructor(message: string, extra: T) {
49
- super(format(name, message));
50
- this.name = name;
51
- Object.assign(this, extra);
52
- }
53
- } as unknown as {
54
- new (message: string, extra: T): Error & T;
55
- };
56
- }
57
-
58
- // const MyException = buildException<{ foo: string; bar: number }>('MyException: ');
59
- // const myException = new MyException('bar', { foo: '1', bar: 1 });
60
- // myException.foo;
61
- // myException.bar;
62
- // myException.name;
63
- // myException.message;
64
- // myException.stack;
65
- // myException.cause;
66
-
67
- // const MyException2 = buildException('MyException2: ');
68
- // const myException2 = new MyException2('bar');