@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/dist/async.cjs ADDED
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ var __typeError = (msg) => {
3
+ throw TypeError(msg);
4
+ };
5
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
6
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
7
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
8
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
9
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
10
+ var __privateWrapper = (obj, member, setter, getter) => ({
11
+ set _(value) {
12
+ __privateSet(obj, member, value, setter);
13
+ },
14
+ get _() {
15
+ return __privateGet(obj, member, getter);
16
+ }
17
+ });
18
+ var _tasks, _length, _AsyncQueue_instances, add_fn, addAndRun_fn, _startResolved, _startRejected, _startResults, _startPwr, _startLength, _running, run_fn, _stopResolved, _stopRejected, _stopLength, _stopResults, _stopPwr;
19
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
20
+ const fn = require("./fn.cjs");
21
+ class AsyncQueue {
22
+ /**
23
+ * 创建一个异步任务队列
24
+ * @param asyncFns - 要执行的异步函数数组
25
+ * @param options - 队列配置选项
26
+ */
27
+ constructor(asyncFns, options) {
28
+ __privateAdd(this, _AsyncQueue_instances);
29
+ __privateAdd(this, _tasks, []);
30
+ __privateAdd(this, _length, 0);
31
+ __privateAdd(this, _startResolved, 0);
32
+ __privateAdd(this, _startRejected, 0);
33
+ __privateAdd(this, _startResults, []);
34
+ __privateAdd(this, _startPwr, null);
35
+ __privateAdd(this, _startLength, 0);
36
+ __privateAdd(this, _running, 0);
37
+ __privateAdd(this, _stopResolved, 0);
38
+ __privateAdd(this, _stopRejected, 0);
39
+ __privateAdd(this, _stopLength, -1);
40
+ __privateAdd(this, _stopResults, []);
41
+ __privateAdd(this, _stopPwr, null);
42
+ this.options = options;
43
+ asyncFns.forEach((afn, idx) => {
44
+ __privateMethod(this, _AsyncQueue_instances, add_fn).call(this, "push", afn);
45
+ });
46
+ }
47
+ get length() {
48
+ return __privateGet(this, _length);
49
+ }
50
+ get limit() {
51
+ var _a;
52
+ return ((_a = this.options) == null ? void 0 : _a.limit) || 0;
53
+ }
54
+ async push(afn) {
55
+ return __privateMethod(this, _AsyncQueue_instances, addAndRun_fn).call(this, "push", afn);
56
+ }
57
+ async unshift(afn) {
58
+ return __privateMethod(this, _AsyncQueue_instances, addAndRun_fn).call(this, "unshift", afn);
59
+ }
60
+ get startSettled() {
61
+ return __privateGet(this, _startResolved) === __privateGet(this, _startLength) || __privateGet(this, _startRejected) > 0;
62
+ }
63
+ /**
64
+ * 启动队列中的任务执行
65
+ * @returns 返回一个 Promise,在所有启动任务完成后解析为结果数组
66
+ */
67
+ async start() {
68
+ if (__privateGet(this, _startPwr)) return __privateGet(this, _startPwr).promise;
69
+ __privateSet(this, _startLength, __privateGet(this, _length));
70
+ __privateSet(this, _startPwr, Promise.withResolvers());
71
+ if (__privateGet(this, _startLength) === 0) {
72
+ __privateGet(this, _startPwr).resolve([]);
73
+ } else {
74
+ __privateMethod(this, _AsyncQueue_instances, run_fn).call(this);
75
+ }
76
+ return __privateGet(this, _startPwr).promise;
77
+ }
78
+ get stopSettled() {
79
+ return __privateGet(this, _stopResolved) === __privateGet(this, _stopLength) || __privateGet(this, _stopRejected) > 0;
80
+ }
81
+ /**
82
+ * 终止队列中的任务执行,终止队列后不再可以追加异步任务
83
+ * @returns 返回一个 Promise,在所有启动任务完成后解析为结果数组
84
+ */
85
+ async stop() {
86
+ if (__privateGet(this, _stopPwr)) {
87
+ return __privateGet(this, _stopPwr).promise;
88
+ }
89
+ __privateSet(this, _stopLength, __privateGet(this, _length));
90
+ __privateSet(this, _stopPwr, Promise.withResolvers());
91
+ if (__privateGet(this, _stopLength) === 0) {
92
+ __privateGet(this, _stopPwr).resolve([]);
93
+ } else {
94
+ __privateMethod(this, _AsyncQueue_instances, run_fn).call(this);
95
+ }
96
+ return __privateGet(this, _stopPwr).promise;
97
+ }
98
+ }
99
+ _tasks = new WeakMap();
100
+ _length = new WeakMap();
101
+ _AsyncQueue_instances = new WeakSet();
102
+ add_fn = function(method, afn, pwr) {
103
+ __privateGet(this, _tasks)[method]({
104
+ idx: __privateWrapper(this, _length)._++,
105
+ afn,
106
+ pwr
107
+ });
108
+ };
109
+ addAndRun_fn = function(method, afn) {
110
+ if (__privateGet(this, _stopLength) >= 0) {
111
+ throw new Error("异步队列已被终止,无法添加新的任务");
112
+ }
113
+ const pwr = Promise.withResolvers();
114
+ __privateMethod(this, _AsyncQueue_instances, add_fn).call(this, method, afn, pwr);
115
+ if (__privateGet(this, _startPwr) && __privateGet(this, _running) === 0) {
116
+ __privateMethod(this, _AsyncQueue_instances, run_fn).call(this);
117
+ }
118
+ return pwr.promise;
119
+ };
120
+ _startResolved = new WeakMap();
121
+ _startRejected = new WeakMap();
122
+ _startResults = new WeakMap();
123
+ _startPwr = new WeakMap();
124
+ _startLength = new WeakMap();
125
+ _running = new WeakMap();
126
+ run_fn = function() {
127
+ while (this.limit === 0 || __privateGet(this, _running) < this.limit) {
128
+ const task = __privateGet(this, _tasks).shift();
129
+ if (!task) break;
130
+ __privateWrapper(this, _running)._++;
131
+ task.afn().then((result) => {
132
+ var _a, _b, _c;
133
+ __privateWrapper(this, _running)._--;
134
+ (_a = task.pwr) == null ? void 0 : _a.resolve(result);
135
+ if (task.idx < __privateGet(this, _startLength)) {
136
+ __privateGet(this, _startResults)[task.idx] = result;
137
+ __privateWrapper(this, _startResolved)._++;
138
+ }
139
+ if (__privateGet(this, _startResolved) === __privateGet(this, _startLength)) {
140
+ (_b = __privateGet(this, _startPwr)) == null ? void 0 : _b.resolve(__privateGet(this, _startResults));
141
+ }
142
+ __privateGet(this, _stopResults)[task.idx] = result;
143
+ __privateWrapper(this, _stopResolved)._++;
144
+ if (__privateGet(this, _stopResolved) === __privateGet(this, _stopLength)) {
145
+ (_c = __privateGet(this, _stopPwr)) == null ? void 0 : _c.resolve(__privateGet(this, _stopResults));
146
+ } else {
147
+ __privateMethod(this, _AsyncQueue_instances, run_fn).call(this);
148
+ }
149
+ }).catch((reason) => {
150
+ var _a, _b, _c;
151
+ __privateWrapper(this, _running)._--;
152
+ (_a = task.pwr) == null ? void 0 : _a.reject(reason);
153
+ if (task.idx < __privateGet(this, _startLength)) {
154
+ __privateWrapper(this, _startRejected)._++;
155
+ (_b = __privateGet(this, _startPwr)) == null ? void 0 : _b.reject(reason);
156
+ }
157
+ if (__privateGet(this, _stopLength) > 0) {
158
+ __privateWrapper(this, _stopRejected)._++;
159
+ (_c = __privateGet(this, _stopPwr)) == null ? void 0 : _c.reject(reason);
160
+ }
161
+ });
162
+ }
163
+ };
164
+ _stopResolved = new WeakMap();
165
+ _stopRejected = new WeakMap();
166
+ _stopLength = new WeakMap();
167
+ _stopResults = new WeakMap();
168
+ _stopPwr = new WeakMap();
169
+ function asyncLimit(asyncFns, limit) {
170
+ const aq = new AsyncQueue(asyncFns, { limit });
171
+ return aq.start();
172
+ }
173
+ function asyncShared(af, options) {
174
+ let executedPromise;
175
+ let executing = false;
176
+ let executingInputs;
177
+ let executedTime = 0;
178
+ const _sharedAf = async (from, ...inputs) => {
179
+ var _a;
180
+ executingInputs = inputs;
181
+ if (executing && executedPromise) {
182
+ return executedPromise;
183
+ }
184
+ if (executedPromise && Date.now() - executedTime < ((options == null ? void 0 : options.maxAge) || 0)) {
185
+ return executedPromise;
186
+ }
187
+ executing = true;
188
+ (_a = options == null ? void 0 : options.onExecute) == null ? void 0 : _a.call(options, ...executingInputs);
189
+ executedPromise = af(...executingInputs);
190
+ executingInputs = void 0;
191
+ executedPromise.then((res) => {
192
+ var _a2;
193
+ (_a2 = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a2.call(options, res);
194
+ }).catch((err) => {
195
+ var _a2;
196
+ (_a2 = options == null ? void 0 : options.onError) == null ? void 0 : _a2.call(options, err);
197
+ }).finally(() => {
198
+ var _a2;
199
+ executing = false;
200
+ executedTime = Date.now();
201
+ (_a2 = options == null ? void 0 : options.onFinally) == null ? void 0 : _a2.call(options);
202
+ if (executingInputs && (options == null ? void 0 : options.trailing)) {
203
+ _sharedAf("trailing", ...executingInputs);
204
+ }
205
+ });
206
+ return executedPromise;
207
+ };
208
+ return function sharedAf(...inputs) {
209
+ var _a;
210
+ (_a = options == null ? void 0 : options.onTrigger) == null ? void 0 : _a.call(options, ...inputs);
211
+ const p = _sharedAf("trigger", ...inputs);
212
+ p.catch(fn.fnNoop);
213
+ return p;
214
+ };
215
+ }
216
+ exports.AsyncQueue = AsyncQueue;
217
+ exports.asyncLimit = asyncLimit;
218
+ exports.asyncShared = asyncShared;
219
+ //# sourceMappingURL=async.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async.cjs","sources":["../src/async.ts"],"sourcesContent":["import { fnNoop } from './fn';\nimport type { AnyArray, AnyAsyncFunction } from './types';\n\n/**\n * 表示异步任务的类型\n * @template T - 任务返回值的类型\n */\ntype AsyncTask<T> = {\n /** 任务索引 */\n idx: number;\n /** 异步任务函数 */\n afn: () => Promise<T>;\n /** Promise 的解析器对象 */\n pwr?: PromiseWithResolvers<T>;\n};\n\n/**\n * 异步任务队列的配置选项\n */\nexport type TAsyncQueueOptions = {\n /**\n * 并发限制数,0 表示无限制\n * @default 0\n */\n limit?: number;\n};\n\n/**\n * 异步任务队列,用于管理和控制异步任务的执行\n * @template T - 任务返回值的类型\n */\nexport class AsyncQueue<T> {\n #tasks: AsyncTask<T>[] = [];\n #length = 0;\n\n /**\n * 创建一个异步任务队列\n * @param asyncFns - 要执行的异步函数数组\n * @param options - 队列配置选项\n */\n constructor(\n asyncFns: Array<() => Promise<T>>,\n readonly options?: TAsyncQueueOptions,\n ) {\n asyncFns.forEach((afn, idx) => {\n this.#add('push', afn);\n });\n }\n\n get length() {\n return this.#length;\n }\n\n get limit() {\n return this.options?.limit || 0;\n }\n\n #add(method: 'unshift' | 'push', afn: () => Promise<T>, pwr?: PromiseWithResolvers<T>) {\n this.#tasks[method]({\n idx: this.#length++,\n afn: afn,\n pwr: pwr,\n });\n }\n\n #addAndRun(method: 'unshift' | 'push', afn: () => Promise<T>) {\n // 明确终止了\n if (this.#stopLength >= 0) {\n throw new Error('异步队列已被终止,无法添加新的任务');\n }\n\n const pwr = Promise.withResolvers<T>();\n this.#add(method, afn, pwr);\n\n if (this.#startPwr && this.#running === 0) {\n this.#run();\n }\n\n return pwr.promise;\n }\n\n async push(afn: () => Promise<T>) {\n return this.#addAndRun('push', afn);\n }\n\n async unshift(afn: () => Promise<T>) {\n return this.#addAndRun('unshift', afn);\n }\n\n #startResolved = 0;\n #startRejected = 0;\n get startSettled() {\n return this.#startResolved === this.#startLength || this.#startRejected > 0;\n }\n\n #startResults: T[] = [];\n #startPwr: PromiseWithResolvers<T[]> | null = null;\n #startLength = 0;\n\n /**\n * 启动队列中的任务执行\n * @returns 返回一个 Promise,在所有启动任务完成后解析为结果数组\n */\n async start(): Promise<T[]> {\n if (this.#startPwr) return this.#startPwr.promise;\n\n // 固化启动时长度,便于判断 start 异步结果\n this.#startLength = this.#length;\n this.#startPwr = Promise.withResolvers<T[]>();\n\n if (this.#startLength === 0) {\n this.#startPwr.resolve([]);\n } else {\n this.#run();\n }\n\n return this.#startPwr.promise;\n }\n\n #running = 0;\n #run() {\n while (this.limit === 0 || this.#running < this.limit) {\n const task = this.#tasks.shift();\n\n // 无任务可执行\n if (!task) break;\n\n this.#running++;\n\n task\n .afn()\n .then((result) => {\n this.#running--;\n task.pwr?.resolve(result);\n\n // 属于启动任务\n if (task.idx < this.#startLength) {\n this.#startResults[task.idx] = result;\n this.#startResolved++;\n }\n\n // 所有启动任务都已执行完毕\n if (this.#startResolved === this.#startLength) {\n this.#startPwr?.resolve(this.#startResults);\n }\n\n this.#stopResults[task.idx] = result;\n this.#stopResolved++;\n\n // 所有停止任务都已执行完毕\n if (this.#stopResolved === this.#stopLength) {\n this.#stopPwr?.resolve(this.#stopResults);\n } else {\n this.#run();\n }\n })\n .catch((reason) => {\n this.#running--;\n task.pwr?.reject(reason);\n\n // 属于启动任务\n if (task.idx < this.#startLength) {\n this.#startRejected++;\n this.#startPwr?.reject(reason);\n }\n\n // 属于停止任务\n if (this.#stopLength > 0) {\n this.#stopRejected++;\n this.#stopPwr?.reject(reason);\n }\n });\n }\n }\n #stopResolved = 0;\n #stopRejected = 0;\n get stopSettled() {\n return this.#stopResolved === this.#stopLength || this.#stopRejected > 0;\n }\n\n #stopLength = -1;\n #stopResults: T[] = [];\n\n #stopPwr?: PromiseWithResolvers<T[]> | null = null;\n\n /**\n * 终止队列中的任务执行,终止队列后不再可以追加异步任务\n * @returns 返回一个 Promise,在所有启动任务完成后解析为结果数组\n */\n async stop() {\n if (this.#stopPwr) {\n return this.#stopPwr.promise;\n }\n\n this.#stopLength = this.#length;\n this.#stopPwr = Promise.withResolvers<T[]>();\n\n if (this.#stopLength === 0) {\n this.#stopPwr.resolve([]);\n } else {\n this.#run();\n }\n\n return this.#stopPwr.promise;\n }\n}\n\n/**\n * 使用给定的并发限制执行异步函数\n *\n * 此函数的目的是控制一组异步函数的并发执行数量,通过创建一个AsyncQueue实例来管理这些异步函数的执行\n * 它确保在任何给定时间只有最多`limit`数量的异步函数被执行,以避免潜在的性能问题或资源竞争\n *\n * @param asyncFns 一个包含异步函数的数组,每个异步函数都不需要参数,并返回一个Promise\n * @param limit 并发限制的数量,表示同时执行的异步函数的最大数量,0 表示不限制\n * @returns 返回一个Promise,当所有异步函数都执行完毕后,该Promise将被解析\n */\nexport function asyncLimit<T>(asyncFns: Array<() => Promise<T>>, limit: number) {\n const aq = new AsyncQueue<T>(asyncFns, { limit });\n return aq.start();\n}\n\n/**\n * 异步共享函数的配置选项\n */\nexport type AsyncSharedOptions<I extends AnyArray, O> = {\n /**\n * 是否在调用结束后再执行(只在运行期间有再次调用时才会生效)\n * @type {boolean}\n * @default false\n * @example\n * const sharedFn = asyncShared(fetchData, { trailing: true });\n * // 如果在 fetchData 执行期间多次调用 sharedFn,则会在 fetchData 结束后再次执行\n */\n trailing?: boolean;\n\n /**\n * 缓存结果的最大有效期(毫秒)\n * @type {number}\n * @example\n * const sharedFn = asyncShared(fetchData, { maxAge: 1000 });\n * // 在 1 秒内调用 sharedFn 会直接返回缓存结果\n */\n maxAge?: number;\n\n /**\n * 在调用共享函数时触发的回调函数\n * @param inputs - 传递给共享函数的参数\n * @example\n * const options: AsyncSharedOptions<typeof fetchData> = {\n * onTrigger: (...args) => console.log('Calling with:', args)\n * };\n */\n onTrigger?: (...inputs: I) => unknown;\n\n /**\n * 在执行异步函数时触发的回调函数\n * @param args - 传递给异步函数的参数\n * @example\n * const options: AsyncSharedOptions<typeof fetchData> = {\n * onExecute: (...args) => console.log('Executing with:', args)\n * };\n */\n onExecute?: (...args: I) => unknown;\n\n /**\n * 在异步函数成功执行后触发的回调函数\n * @param output - 异步函数的返回结果\n * @example\n * const options: AsyncSharedOptions<typeof fetchData> = {\n * onSuccess: (result) => console.log('Success:', result)\n * };\n */\n onSuccess?: (output: O) => unknown;\n\n /**\n * 在异步函数执行失败时触发的回调函数\n * @param error - 异步函数抛出的错误\n * @example\n * const options: AsyncSharedOptions<typeof fetchData> = {\n * onError: (error) => console.error('Error:', error)\n * };\n */\n onError?: (error: unknown) => unknown;\n\n /**\n * 在异步函数执行完成(无论成功或失败)时触发的回调函数\n * @example\n * const options: AsyncSharedOptions<typeof fetchData> = {\n * onFinally: () => console.log('Execution completed')\n * };\n */\n onFinally?: () => unknown;\n};\n\n/**\n * 创建一个共享执行结果的异步函数\n * @template F - 异步函数类型\n * @param {F} af - 要共享的异步函数\n * @param {AsyncSharedOptions} [options] - 配置选项\n * @returns {F} 返回一个新的异步函数,该函数会共享执行结果\n * @example\n * const fetchData = async (id) => {\n * // 模拟异步操作\n * return await fetch(`/api/data/${id}`);\n * };\n *\n * const sharedFetch = asyncShared(fetchData, { maxAge: 1000 });\n *\n * // 多次调用会共享同一个请求\n * const result1 = await sharedFetch(1);\n * const result2 = await sharedFetch(1); // 上次请求完成后 1000ms 内直接返回缓存结果\n */\nexport function asyncShared<I extends AnyArray, O>(\n af: (...inputs: I) => Promise<O>,\n options?: AsyncSharedOptions<I, O>,\n) {\n let executedPromise: Promise<O> | undefined;\n let executing = false;\n let executingInputs: I | undefined;\n let executedTime = 0;\n\n const _sharedAf = async (from: 'trigger' | 'trailing', ...inputs: I) => {\n executingInputs = inputs;\n\n // 如果正在运行,则复用运行结果\n if (executing && executedPromise) {\n return executedPromise;\n }\n\n // 如果已运行结束空闲时,判断是否在等待时间内\n if (executedPromise && Date.now() - executedTime < (options?.maxAge || 0)) {\n return executedPromise;\n }\n\n // 否则直接执行\n executing = true;\n options?.onExecute?.(...executingInputs);\n executedPromise = af(...executingInputs);\n executingInputs = undefined;\n executedPromise\n .then((res) => {\n options?.onSuccess?.(res);\n })\n .catch((err) => {\n options?.onError?.(err);\n })\n .finally(() => {\n executing = false;\n executedTime = Date.now();\n options?.onFinally?.();\n\n // 执行期间多次调用,则重新执行\n if (executingInputs && options?.trailing) {\n _sharedAf('trailing', ...executingInputs);\n }\n });\n\n return executedPromise;\n };\n\n return function sharedAf(...inputs: I): Promise<O> {\n options?.onTrigger?.(...inputs);\n const p = _sharedAf('trigger', ...inputs);\n // 必须捕获错误,否则单测错误边界时会抛错\n p.catch(fnNoop);\n return p;\n };\n}\n\n// const af1 = asyncShared(async () => {\n// return 1;\n// });\n// const n = await af1();\n\n// const af2 = asyncShared(async (a: number) => {\n// return a + 1;\n// });\n// const n2 = await af2(2);\n"],"names":["_a","fnNoop"],"mappings":"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"}
@@ -0,0 +1,137 @@
1
+ import { AnyArray } from './types';
2
+ /**
3
+ * 异步任务队列的配置选项
4
+ */
5
+ export type TAsyncQueueOptions = {
6
+ /**
7
+ * 并发限制数,0 表示无限制
8
+ * @default 0
9
+ */
10
+ limit?: number;
11
+ };
12
+ /**
13
+ * 异步任务队列,用于管理和控制异步任务的执行
14
+ * @template T - 任务返回值的类型
15
+ */
16
+ export declare class AsyncQueue<T> {
17
+ #private;
18
+ readonly options?: TAsyncQueueOptions | undefined;
19
+ /**
20
+ * 创建一个异步任务队列
21
+ * @param asyncFns - 要执行的异步函数数组
22
+ * @param options - 队列配置选项
23
+ */
24
+ constructor(asyncFns: Array<() => Promise<T>>, options?: TAsyncQueueOptions | undefined);
25
+ get length(): number;
26
+ get limit(): number;
27
+ push(afn: () => Promise<T>): Promise<T>;
28
+ unshift(afn: () => Promise<T>): Promise<T>;
29
+ get startSettled(): boolean;
30
+ /**
31
+ * 启动队列中的任务执行
32
+ * @returns 返回一个 Promise,在所有启动任务完成后解析为结果数组
33
+ */
34
+ start(): Promise<T[]>;
35
+ get stopSettled(): boolean;
36
+ /**
37
+ * 终止队列中的任务执行,终止队列后不再可以追加异步任务
38
+ * @returns 返回一个 Promise,在所有启动任务完成后解析为结果数组
39
+ */
40
+ stop(): Promise<T[]>;
41
+ }
42
+ /**
43
+ * 使用给定的并发限制执行异步函数
44
+ *
45
+ * 此函数的目的是控制一组异步函数的并发执行数量,通过创建一个AsyncQueue实例来管理这些异步函数的执行
46
+ * 它确保在任何给定时间只有最多`limit`数量的异步函数被执行,以避免潜在的性能问题或资源竞争
47
+ *
48
+ * @param asyncFns 一个包含异步函数的数组,每个异步函数都不需要参数,并返回一个Promise
49
+ * @param limit 并发限制的数量,表示同时执行的异步函数的最大数量,0 表示不限制
50
+ * @returns 返回一个Promise,当所有异步函数都执行完毕后,该Promise将被解析
51
+ */
52
+ export declare function asyncLimit<T>(asyncFns: Array<() => Promise<T>>, limit: number): Promise<T[]>;
53
+ /**
54
+ * 异步共享函数的配置选项
55
+ */
56
+ export type AsyncSharedOptions<I extends AnyArray, O> = {
57
+ /**
58
+ * 是否在调用结束后再执行(只在运行期间有再次调用时才会生效)
59
+ * @type {boolean}
60
+ * @default false
61
+ * @example
62
+ * const sharedFn = asyncShared(fetchData, { trailing: true });
63
+ * // 如果在 fetchData 执行期间多次调用 sharedFn,则会在 fetchData 结束后再次执行
64
+ */
65
+ trailing?: boolean;
66
+ /**
67
+ * 缓存结果的最大有效期(毫秒)
68
+ * @type {number}
69
+ * @example
70
+ * const sharedFn = asyncShared(fetchData, { maxAge: 1000 });
71
+ * // 在 1 秒内调用 sharedFn 会直接返回缓存结果
72
+ */
73
+ maxAge?: number;
74
+ /**
75
+ * 在调用共享函数时触发的回调函数
76
+ * @param inputs - 传递给共享函数的参数
77
+ * @example
78
+ * const options: AsyncSharedOptions<typeof fetchData> = {
79
+ * onTrigger: (...args) => console.log('Calling with:', args)
80
+ * };
81
+ */
82
+ onTrigger?: (...inputs: I) => unknown;
83
+ /**
84
+ * 在执行异步函数时触发的回调函数
85
+ * @param args - 传递给异步函数的参数
86
+ * @example
87
+ * const options: AsyncSharedOptions<typeof fetchData> = {
88
+ * onExecute: (...args) => console.log('Executing with:', args)
89
+ * };
90
+ */
91
+ onExecute?: (...args: I) => unknown;
92
+ /**
93
+ * 在异步函数成功执行后触发的回调函数
94
+ * @param output - 异步函数的返回结果
95
+ * @example
96
+ * const options: AsyncSharedOptions<typeof fetchData> = {
97
+ * onSuccess: (result) => console.log('Success:', result)
98
+ * };
99
+ */
100
+ onSuccess?: (output: O) => unknown;
101
+ /**
102
+ * 在异步函数执行失败时触发的回调函数
103
+ * @param error - 异步函数抛出的错误
104
+ * @example
105
+ * const options: AsyncSharedOptions<typeof fetchData> = {
106
+ * onError: (error) => console.error('Error:', error)
107
+ * };
108
+ */
109
+ onError?: (error: unknown) => unknown;
110
+ /**
111
+ * 在异步函数执行完成(无论成功或失败)时触发的回调函数
112
+ * @example
113
+ * const options: AsyncSharedOptions<typeof fetchData> = {
114
+ * onFinally: () => console.log('Execution completed')
115
+ * };
116
+ */
117
+ onFinally?: () => unknown;
118
+ };
119
+ /**
120
+ * 创建一个共享执行结果的异步函数
121
+ * @template F - 异步函数类型
122
+ * @param {F} af - 要共享的异步函数
123
+ * @param {AsyncSharedOptions} [options] - 配置选项
124
+ * @returns {F} 返回一个新的异步函数,该函数会共享执行结果
125
+ * @example
126
+ * const fetchData = async (id) => {
127
+ * // 模拟异步操作
128
+ * return await fetch(`/api/data/${id}`);
129
+ * };
130
+ *
131
+ * const sharedFetch = asyncShared(fetchData, { maxAge: 1000 });
132
+ *
133
+ * // 多次调用会共享同一个请求
134
+ * const result1 = await sharedFetch(1);
135
+ * const result2 = await sharedFetch(1); // 上次请求完成后 1000ms 内直接返回缓存结果
136
+ */
137
+ export declare function asyncShared<I extends AnyArray, O>(af: (...inputs: I) => Promise<O>, options?: AsyncSharedOptions<I, O>): (...inputs: I) => Promise<O>;
package/dist/async.mjs ADDED
@@ -0,0 +1,219 @@
1
+ var __typeError = (msg) => {
2
+ throw TypeError(msg);
3
+ };
4
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
5
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
8
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
9
+ var __privateWrapper = (obj, member, setter, getter) => ({
10
+ set _(value) {
11
+ __privateSet(obj, member, value, setter);
12
+ },
13
+ get _() {
14
+ return __privateGet(obj, member, getter);
15
+ }
16
+ });
17
+ var _tasks, _length, _AsyncQueue_instances, add_fn, addAndRun_fn, _startResolved, _startRejected, _startResults, _startPwr, _startLength, _running, run_fn, _stopResolved, _stopRejected, _stopLength, _stopResults, _stopPwr;
18
+ import { fnNoop } from "./fn.mjs";
19
+ class AsyncQueue {
20
+ /**
21
+ * 创建一个异步任务队列
22
+ * @param asyncFns - 要执行的异步函数数组
23
+ * @param options - 队列配置选项
24
+ */
25
+ constructor(asyncFns, options) {
26
+ __privateAdd(this, _AsyncQueue_instances);
27
+ __privateAdd(this, _tasks, []);
28
+ __privateAdd(this, _length, 0);
29
+ __privateAdd(this, _startResolved, 0);
30
+ __privateAdd(this, _startRejected, 0);
31
+ __privateAdd(this, _startResults, []);
32
+ __privateAdd(this, _startPwr, null);
33
+ __privateAdd(this, _startLength, 0);
34
+ __privateAdd(this, _running, 0);
35
+ __privateAdd(this, _stopResolved, 0);
36
+ __privateAdd(this, _stopRejected, 0);
37
+ __privateAdd(this, _stopLength, -1);
38
+ __privateAdd(this, _stopResults, []);
39
+ __privateAdd(this, _stopPwr, null);
40
+ this.options = options;
41
+ asyncFns.forEach((afn, idx) => {
42
+ __privateMethod(this, _AsyncQueue_instances, add_fn).call(this, "push", afn);
43
+ });
44
+ }
45
+ get length() {
46
+ return __privateGet(this, _length);
47
+ }
48
+ get limit() {
49
+ var _a;
50
+ return ((_a = this.options) == null ? void 0 : _a.limit) || 0;
51
+ }
52
+ async push(afn) {
53
+ return __privateMethod(this, _AsyncQueue_instances, addAndRun_fn).call(this, "push", afn);
54
+ }
55
+ async unshift(afn) {
56
+ return __privateMethod(this, _AsyncQueue_instances, addAndRun_fn).call(this, "unshift", afn);
57
+ }
58
+ get startSettled() {
59
+ return __privateGet(this, _startResolved) === __privateGet(this, _startLength) || __privateGet(this, _startRejected) > 0;
60
+ }
61
+ /**
62
+ * 启动队列中的任务执行
63
+ * @returns 返回一个 Promise,在所有启动任务完成后解析为结果数组
64
+ */
65
+ async start() {
66
+ if (__privateGet(this, _startPwr)) return __privateGet(this, _startPwr).promise;
67
+ __privateSet(this, _startLength, __privateGet(this, _length));
68
+ __privateSet(this, _startPwr, Promise.withResolvers());
69
+ if (__privateGet(this, _startLength) === 0) {
70
+ __privateGet(this, _startPwr).resolve([]);
71
+ } else {
72
+ __privateMethod(this, _AsyncQueue_instances, run_fn).call(this);
73
+ }
74
+ return __privateGet(this, _startPwr).promise;
75
+ }
76
+ get stopSettled() {
77
+ return __privateGet(this, _stopResolved) === __privateGet(this, _stopLength) || __privateGet(this, _stopRejected) > 0;
78
+ }
79
+ /**
80
+ * 终止队列中的任务执行,终止队列后不再可以追加异步任务
81
+ * @returns 返回一个 Promise,在所有启动任务完成后解析为结果数组
82
+ */
83
+ async stop() {
84
+ if (__privateGet(this, _stopPwr)) {
85
+ return __privateGet(this, _stopPwr).promise;
86
+ }
87
+ __privateSet(this, _stopLength, __privateGet(this, _length));
88
+ __privateSet(this, _stopPwr, Promise.withResolvers());
89
+ if (__privateGet(this, _stopLength) === 0) {
90
+ __privateGet(this, _stopPwr).resolve([]);
91
+ } else {
92
+ __privateMethod(this, _AsyncQueue_instances, run_fn).call(this);
93
+ }
94
+ return __privateGet(this, _stopPwr).promise;
95
+ }
96
+ }
97
+ _tasks = new WeakMap();
98
+ _length = new WeakMap();
99
+ _AsyncQueue_instances = new WeakSet();
100
+ add_fn = function(method, afn, pwr) {
101
+ __privateGet(this, _tasks)[method]({
102
+ idx: __privateWrapper(this, _length)._++,
103
+ afn,
104
+ pwr
105
+ });
106
+ };
107
+ addAndRun_fn = function(method, afn) {
108
+ if (__privateGet(this, _stopLength) >= 0) {
109
+ throw new Error("异步队列已被终止,无法添加新的任务");
110
+ }
111
+ const pwr = Promise.withResolvers();
112
+ __privateMethod(this, _AsyncQueue_instances, add_fn).call(this, method, afn, pwr);
113
+ if (__privateGet(this, _startPwr) && __privateGet(this, _running) === 0) {
114
+ __privateMethod(this, _AsyncQueue_instances, run_fn).call(this);
115
+ }
116
+ return pwr.promise;
117
+ };
118
+ _startResolved = new WeakMap();
119
+ _startRejected = new WeakMap();
120
+ _startResults = new WeakMap();
121
+ _startPwr = new WeakMap();
122
+ _startLength = new WeakMap();
123
+ _running = new WeakMap();
124
+ run_fn = function() {
125
+ while (this.limit === 0 || __privateGet(this, _running) < this.limit) {
126
+ const task = __privateGet(this, _tasks).shift();
127
+ if (!task) break;
128
+ __privateWrapper(this, _running)._++;
129
+ task.afn().then((result) => {
130
+ var _a, _b, _c;
131
+ __privateWrapper(this, _running)._--;
132
+ (_a = task.pwr) == null ? void 0 : _a.resolve(result);
133
+ if (task.idx < __privateGet(this, _startLength)) {
134
+ __privateGet(this, _startResults)[task.idx] = result;
135
+ __privateWrapper(this, _startResolved)._++;
136
+ }
137
+ if (__privateGet(this, _startResolved) === __privateGet(this, _startLength)) {
138
+ (_b = __privateGet(this, _startPwr)) == null ? void 0 : _b.resolve(__privateGet(this, _startResults));
139
+ }
140
+ __privateGet(this, _stopResults)[task.idx] = result;
141
+ __privateWrapper(this, _stopResolved)._++;
142
+ if (__privateGet(this, _stopResolved) === __privateGet(this, _stopLength)) {
143
+ (_c = __privateGet(this, _stopPwr)) == null ? void 0 : _c.resolve(__privateGet(this, _stopResults));
144
+ } else {
145
+ __privateMethod(this, _AsyncQueue_instances, run_fn).call(this);
146
+ }
147
+ }).catch((reason) => {
148
+ var _a, _b, _c;
149
+ __privateWrapper(this, _running)._--;
150
+ (_a = task.pwr) == null ? void 0 : _a.reject(reason);
151
+ if (task.idx < __privateGet(this, _startLength)) {
152
+ __privateWrapper(this, _startRejected)._++;
153
+ (_b = __privateGet(this, _startPwr)) == null ? void 0 : _b.reject(reason);
154
+ }
155
+ if (__privateGet(this, _stopLength) > 0) {
156
+ __privateWrapper(this, _stopRejected)._++;
157
+ (_c = __privateGet(this, _stopPwr)) == null ? void 0 : _c.reject(reason);
158
+ }
159
+ });
160
+ }
161
+ };
162
+ _stopResolved = new WeakMap();
163
+ _stopRejected = new WeakMap();
164
+ _stopLength = new WeakMap();
165
+ _stopResults = new WeakMap();
166
+ _stopPwr = new WeakMap();
167
+ function asyncLimit(asyncFns, limit) {
168
+ const aq = new AsyncQueue(asyncFns, { limit });
169
+ return aq.start();
170
+ }
171
+ function asyncShared(af, options) {
172
+ let executedPromise;
173
+ let executing = false;
174
+ let executingInputs;
175
+ let executedTime = 0;
176
+ const _sharedAf = async (from, ...inputs) => {
177
+ var _a;
178
+ executingInputs = inputs;
179
+ if (executing && executedPromise) {
180
+ return executedPromise;
181
+ }
182
+ if (executedPromise && Date.now() - executedTime < ((options == null ? void 0 : options.maxAge) || 0)) {
183
+ return executedPromise;
184
+ }
185
+ executing = true;
186
+ (_a = options == null ? void 0 : options.onExecute) == null ? void 0 : _a.call(options, ...executingInputs);
187
+ executedPromise = af(...executingInputs);
188
+ executingInputs = void 0;
189
+ executedPromise.then((res) => {
190
+ var _a2;
191
+ (_a2 = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a2.call(options, res);
192
+ }).catch((err) => {
193
+ var _a2;
194
+ (_a2 = options == null ? void 0 : options.onError) == null ? void 0 : _a2.call(options, err);
195
+ }).finally(() => {
196
+ var _a2;
197
+ executing = false;
198
+ executedTime = Date.now();
199
+ (_a2 = options == null ? void 0 : options.onFinally) == null ? void 0 : _a2.call(options);
200
+ if (executingInputs && (options == null ? void 0 : options.trailing)) {
201
+ _sharedAf("trailing", ...executingInputs);
202
+ }
203
+ });
204
+ return executedPromise;
205
+ };
206
+ return function sharedAf(...inputs) {
207
+ var _a;
208
+ (_a = options == null ? void 0 : options.onTrigger) == null ? void 0 : _a.call(options, ...inputs);
209
+ const p = _sharedAf("trigger", ...inputs);
210
+ p.catch(fnNoop);
211
+ return p;
212
+ };
213
+ }
214
+ export {
215
+ AsyncQueue,
216
+ asyncLimit,
217
+ asyncShared
218
+ };
219
+ //# sourceMappingURL=async.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async.mjs","sources":["../src/async.ts"],"sourcesContent":["import { fnNoop } from './fn';\nimport type { AnyArray, AnyAsyncFunction } from './types';\n\n/**\n * 表示异步任务的类型\n * @template T - 任务返回值的类型\n */\ntype AsyncTask<T> = {\n /** 任务索引 */\n idx: number;\n /** 异步任务函数 */\n afn: () => Promise<T>;\n /** Promise 的解析器对象 */\n pwr?: PromiseWithResolvers<T>;\n};\n\n/**\n * 异步任务队列的配置选项\n */\nexport type TAsyncQueueOptions = {\n /**\n * 并发限制数,0 表示无限制\n * @default 0\n */\n limit?: number;\n};\n\n/**\n * 异步任务队列,用于管理和控制异步任务的执行\n * @template T - 任务返回值的类型\n */\nexport class AsyncQueue<T> {\n #tasks: AsyncTask<T>[] = [];\n #length = 0;\n\n /**\n * 创建一个异步任务队列\n * @param asyncFns - 要执行的异步函数数组\n * @param options - 队列配置选项\n */\n constructor(\n asyncFns: Array<() => Promise<T>>,\n readonly options?: TAsyncQueueOptions,\n ) {\n asyncFns.forEach((afn, idx) => {\n this.#add('push', afn);\n });\n }\n\n get length() {\n return this.#length;\n }\n\n get limit() {\n return this.options?.limit || 0;\n }\n\n #add(method: 'unshift' | 'push', afn: () => Promise<T>, pwr?: PromiseWithResolvers<T>) {\n this.#tasks[method]({\n idx: this.#length++,\n afn: afn,\n pwr: pwr,\n });\n }\n\n #addAndRun(method: 'unshift' | 'push', afn: () => Promise<T>) {\n // 明确终止了\n if (this.#stopLength >= 0) {\n throw new Error('异步队列已被终止,无法添加新的任务');\n }\n\n const pwr = Promise.withResolvers<T>();\n this.#add(method, afn, pwr);\n\n if (this.#startPwr && this.#running === 0) {\n this.#run();\n }\n\n return pwr.promise;\n }\n\n async push(afn: () => Promise<T>) {\n return this.#addAndRun('push', afn);\n }\n\n async unshift(afn: () => Promise<T>) {\n return this.#addAndRun('unshift', afn);\n }\n\n #startResolved = 0;\n #startRejected = 0;\n get startSettled() {\n return this.#startResolved === this.#startLength || this.#startRejected > 0;\n }\n\n #startResults: T[] = [];\n #startPwr: PromiseWithResolvers<T[]> | null = null;\n #startLength = 0;\n\n /**\n * 启动队列中的任务执行\n * @returns 返回一个 Promise,在所有启动任务完成后解析为结果数组\n */\n async start(): Promise<T[]> {\n if (this.#startPwr) return this.#startPwr.promise;\n\n // 固化启动时长度,便于判断 start 异步结果\n this.#startLength = this.#length;\n this.#startPwr = Promise.withResolvers<T[]>();\n\n if (this.#startLength === 0) {\n this.#startPwr.resolve([]);\n } else {\n this.#run();\n }\n\n return this.#startPwr.promise;\n }\n\n #running = 0;\n #run() {\n while (this.limit === 0 || this.#running < this.limit) {\n const task = this.#tasks.shift();\n\n // 无任务可执行\n if (!task) break;\n\n this.#running++;\n\n task\n .afn()\n .then((result) => {\n this.#running--;\n task.pwr?.resolve(result);\n\n // 属于启动任务\n if (task.idx < this.#startLength) {\n this.#startResults[task.idx] = result;\n this.#startResolved++;\n }\n\n // 所有启动任务都已执行完毕\n if (this.#startResolved === this.#startLength) {\n this.#startPwr?.resolve(this.#startResults);\n }\n\n this.#stopResults[task.idx] = result;\n this.#stopResolved++;\n\n // 所有停止任务都已执行完毕\n if (this.#stopResolved === this.#stopLength) {\n this.#stopPwr?.resolve(this.#stopResults);\n } else {\n this.#run();\n }\n })\n .catch((reason) => {\n this.#running--;\n task.pwr?.reject(reason);\n\n // 属于启动任务\n if (task.idx < this.#startLength) {\n this.#startRejected++;\n this.#startPwr?.reject(reason);\n }\n\n // 属于停止任务\n if (this.#stopLength > 0) {\n this.#stopRejected++;\n this.#stopPwr?.reject(reason);\n }\n });\n }\n }\n #stopResolved = 0;\n #stopRejected = 0;\n get stopSettled() {\n return this.#stopResolved === this.#stopLength || this.#stopRejected > 0;\n }\n\n #stopLength = -1;\n #stopResults: T[] = [];\n\n #stopPwr?: PromiseWithResolvers<T[]> | null = null;\n\n /**\n * 终止队列中的任务执行,终止队列后不再可以追加异步任务\n * @returns 返回一个 Promise,在所有启动任务完成后解析为结果数组\n */\n async stop() {\n if (this.#stopPwr) {\n return this.#stopPwr.promise;\n }\n\n this.#stopLength = this.#length;\n this.#stopPwr = Promise.withResolvers<T[]>();\n\n if (this.#stopLength === 0) {\n this.#stopPwr.resolve([]);\n } else {\n this.#run();\n }\n\n return this.#stopPwr.promise;\n }\n}\n\n/**\n * 使用给定的并发限制执行异步函数\n *\n * 此函数的目的是控制一组异步函数的并发执行数量,通过创建一个AsyncQueue实例来管理这些异步函数的执行\n * 它确保在任何给定时间只有最多`limit`数量的异步函数被执行,以避免潜在的性能问题或资源竞争\n *\n * @param asyncFns 一个包含异步函数的数组,每个异步函数都不需要参数,并返回一个Promise\n * @param limit 并发限制的数量,表示同时执行的异步函数的最大数量,0 表示不限制\n * @returns 返回一个Promise,当所有异步函数都执行完毕后,该Promise将被解析\n */\nexport function asyncLimit<T>(asyncFns: Array<() => Promise<T>>, limit: number) {\n const aq = new AsyncQueue<T>(asyncFns, { limit });\n return aq.start();\n}\n\n/**\n * 异步共享函数的配置选项\n */\nexport type AsyncSharedOptions<I extends AnyArray, O> = {\n /**\n * 是否在调用结束后再执行(只在运行期间有再次调用时才会生效)\n * @type {boolean}\n * @default false\n * @example\n * const sharedFn = asyncShared(fetchData, { trailing: true });\n * // 如果在 fetchData 执行期间多次调用 sharedFn,则会在 fetchData 结束后再次执行\n */\n trailing?: boolean;\n\n /**\n * 缓存结果的最大有效期(毫秒)\n * @type {number}\n * @example\n * const sharedFn = asyncShared(fetchData, { maxAge: 1000 });\n * // 在 1 秒内调用 sharedFn 会直接返回缓存结果\n */\n maxAge?: number;\n\n /**\n * 在调用共享函数时触发的回调函数\n * @param inputs - 传递给共享函数的参数\n * @example\n * const options: AsyncSharedOptions<typeof fetchData> = {\n * onTrigger: (...args) => console.log('Calling with:', args)\n * };\n */\n onTrigger?: (...inputs: I) => unknown;\n\n /**\n * 在执行异步函数时触发的回调函数\n * @param args - 传递给异步函数的参数\n * @example\n * const options: AsyncSharedOptions<typeof fetchData> = {\n * onExecute: (...args) => console.log('Executing with:', args)\n * };\n */\n onExecute?: (...args: I) => unknown;\n\n /**\n * 在异步函数成功执行后触发的回调函数\n * @param output - 异步函数的返回结果\n * @example\n * const options: AsyncSharedOptions<typeof fetchData> = {\n * onSuccess: (result) => console.log('Success:', result)\n * };\n */\n onSuccess?: (output: O) => unknown;\n\n /**\n * 在异步函数执行失败时触发的回调函数\n * @param error - 异步函数抛出的错误\n * @example\n * const options: AsyncSharedOptions<typeof fetchData> = {\n * onError: (error) => console.error('Error:', error)\n * };\n */\n onError?: (error: unknown) => unknown;\n\n /**\n * 在异步函数执行完成(无论成功或失败)时触发的回调函数\n * @example\n * const options: AsyncSharedOptions<typeof fetchData> = {\n * onFinally: () => console.log('Execution completed')\n * };\n */\n onFinally?: () => unknown;\n};\n\n/**\n * 创建一个共享执行结果的异步函数\n * @template F - 异步函数类型\n * @param {F} af - 要共享的异步函数\n * @param {AsyncSharedOptions} [options] - 配置选项\n * @returns {F} 返回一个新的异步函数,该函数会共享执行结果\n * @example\n * const fetchData = async (id) => {\n * // 模拟异步操作\n * return await fetch(`/api/data/${id}`);\n * };\n *\n * const sharedFetch = asyncShared(fetchData, { maxAge: 1000 });\n *\n * // 多次调用会共享同一个请求\n * const result1 = await sharedFetch(1);\n * const result2 = await sharedFetch(1); // 上次请求完成后 1000ms 内直接返回缓存结果\n */\nexport function asyncShared<I extends AnyArray, O>(\n af: (...inputs: I) => Promise<O>,\n options?: AsyncSharedOptions<I, O>,\n) {\n let executedPromise: Promise<O> | undefined;\n let executing = false;\n let executingInputs: I | undefined;\n let executedTime = 0;\n\n const _sharedAf = async (from: 'trigger' | 'trailing', ...inputs: I) => {\n executingInputs = inputs;\n\n // 如果正在运行,则复用运行结果\n if (executing && executedPromise) {\n return executedPromise;\n }\n\n // 如果已运行结束空闲时,判断是否在等待时间内\n if (executedPromise && Date.now() - executedTime < (options?.maxAge || 0)) {\n return executedPromise;\n }\n\n // 否则直接执行\n executing = true;\n options?.onExecute?.(...executingInputs);\n executedPromise = af(...executingInputs);\n executingInputs = undefined;\n executedPromise\n .then((res) => {\n options?.onSuccess?.(res);\n })\n .catch((err) => {\n options?.onError?.(err);\n })\n .finally(() => {\n executing = false;\n executedTime = Date.now();\n options?.onFinally?.();\n\n // 执行期间多次调用,则重新执行\n if (executingInputs && options?.trailing) {\n _sharedAf('trailing', ...executingInputs);\n }\n });\n\n return executedPromise;\n };\n\n return function sharedAf(...inputs: I): Promise<O> {\n options?.onTrigger?.(...inputs);\n const p = _sharedAf('trigger', ...inputs);\n // 必须捕获错误,否则单测错误边界时会抛错\n p.catch(fnNoop);\n return p;\n };\n}\n\n// const af1 = asyncShared(async () => {\n// return 1;\n// });\n// const n = await af1();\n\n// const af2 = asyncShared(async (a: number) => {\n// return a + 1;\n// });\n// const n2 = await af2(2);\n"],"names":["_a"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ function base64toBlob(base64) {
4
+ const byteString = atob(base64.split(",")[1]);
5
+ const mimeString = base64.split(",")[0].split(":")[1].split(";")[0];
6
+ const ab = new ArrayBuffer(byteString.length);
7
+ const ua = new Uint8Array(ab);
8
+ for (let i = 0; i < byteString.length; i++) {
9
+ ua[i] = byteString.charCodeAt(i);
10
+ }
11
+ return new Blob([ab], {
12
+ type: mimeString
13
+ });
14
+ }
15
+ exports.base64toBlob = base64toBlob;
16
+ //# sourceMappingURL=base64.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base64.cjs","sources":["../src/base64.ts"],"sourcesContent":["/**\n * base64 转换为 Blob 实例\n * @ref http://stackoverflow.com/q/18253378\n * @param base64 {String} base64 编码\n * @returns {Blob}\n */\nexport function base64toBlob(base64: string): Blob {\n const byteString = atob(base64.split(',')[1]);\n const mimeString = base64.split(',')[0].split(':')[1].split(';')[0];\n const ab = new ArrayBuffer(byteString.length);\n const ua = new Uint8Array(ab);\n\n for (let i = 0; i < byteString.length; i++) {\n ua[i] = byteString.charCodeAt(i);\n }\n\n return new Blob([ab], {\n type: mimeString,\n });\n}\n"],"names":[],"mappings":";;AAMO,SAAS,aAAa,QAAsB;AACjD,QAAM,aAAa,KAAK,OAAO,MAAM,GAAG,EAAE,CAAC,CAAC;AAC5C,QAAM,aAAa,OAAO,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;AAClE,QAAM,KAAK,IAAI,YAAY,WAAW,MAAM;AACtC,QAAA,KAAK,IAAI,WAAW,EAAE;AAE5B,WAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,OAAG,CAAC,IAAI,WAAW,WAAW,CAAC;AAAA,EAAA;AAGjC,SAAO,IAAI,KAAK,CAAC,EAAE,GAAG;AAAA,IACpB,MAAM;AAAA,EAAA,CACP;AACH;;"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * base64 转换为 Blob 实例
3
+ * @ref http://stackoverflow.com/q/18253378
4
+ * @param base64 {String} base64 编码
5
+ * @returns {Blob}
6
+ */
7
+ export declare function base64toBlob(base64: string): Blob;