@planet-matrix/mobius-model 0.4.0 → 0.6.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 (179) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +134 -21
  3. package/dist/index.js +45 -4
  4. package/dist/index.js.map +186 -11
  5. package/oxlint.config.ts +6 -0
  6. package/package.json +16 -10
  7. package/src/abort/README.md +92 -0
  8. package/src/abort/abort-manager.ts +278 -0
  9. package/src/abort/abort-signal-listener-manager.ts +81 -0
  10. package/src/abort/index.ts +2 -0
  11. package/src/basic/README.md +69 -117
  12. package/src/basic/enhance.ts +10 -0
  13. package/src/basic/function.ts +81 -62
  14. package/src/basic/index.ts +2 -0
  15. package/src/basic/is.ts +152 -71
  16. package/src/basic/object.ts +82 -0
  17. package/src/basic/promise.ts +29 -8
  18. package/src/basic/string.ts +2 -33
  19. package/src/color/README.md +105 -0
  20. package/src/color/index.ts +3 -0
  21. package/src/color/internal.ts +42 -0
  22. package/src/color/rgb/analyze.ts +236 -0
  23. package/src/color/rgb/construct.ts +130 -0
  24. package/src/color/rgb/convert.ts +227 -0
  25. package/src/color/rgb/derive.ts +303 -0
  26. package/src/color/rgb/index.ts +6 -0
  27. package/src/color/rgb/internal.ts +208 -0
  28. package/src/color/rgb/parse.ts +302 -0
  29. package/src/color/rgb/serialize.ts +144 -0
  30. package/src/color/types.ts +57 -0
  31. package/src/color/xyz/analyze.ts +80 -0
  32. package/src/color/xyz/construct.ts +19 -0
  33. package/src/color/xyz/convert.ts +71 -0
  34. package/src/color/xyz/index.ts +3 -0
  35. package/src/color/xyz/internal.ts +23 -0
  36. package/src/css/README.md +93 -0
  37. package/src/css/class.ts +559 -0
  38. package/src/css/index.ts +1 -0
  39. package/src/encoding/README.md +92 -0
  40. package/src/encoding/base64.ts +107 -0
  41. package/src/encoding/index.ts +1 -0
  42. package/src/environment/README.md +97 -0
  43. package/src/environment/basic.ts +26 -0
  44. package/src/environment/device.ts +311 -0
  45. package/src/environment/feature.ts +285 -0
  46. package/src/environment/geo.ts +337 -0
  47. package/src/environment/index.ts +7 -0
  48. package/src/environment/runtime.ts +400 -0
  49. package/src/environment/snapshot.ts +60 -0
  50. package/src/environment/variable.ts +239 -0
  51. package/src/event/README.md +90 -0
  52. package/src/event/class-event-proxy.ts +228 -0
  53. package/src/event/common.ts +19 -0
  54. package/src/event/event-manager.ts +203 -0
  55. package/src/event/index.ts +4 -0
  56. package/src/event/instance-event-proxy.ts +186 -0
  57. package/src/event/internal.ts +24 -0
  58. package/src/exception/README.md +96 -0
  59. package/src/exception/browser.ts +219 -0
  60. package/src/exception/index.ts +4 -0
  61. package/src/exception/nodejs.ts +169 -0
  62. package/src/exception/normalize.ts +106 -0
  63. package/src/exception/types.ts +99 -0
  64. package/src/identifier/README.md +92 -0
  65. package/src/identifier/id.ts +119 -0
  66. package/src/identifier/index.ts +2 -0
  67. package/src/identifier/uuid.ts +187 -0
  68. package/src/index.ts +18 -1
  69. package/src/log/README.md +79 -0
  70. package/src/log/index.ts +5 -0
  71. package/src/log/log-emitter.ts +72 -0
  72. package/src/log/log-record.ts +10 -0
  73. package/src/log/log-scheduler.ts +74 -0
  74. package/src/log/log-type.ts +8 -0
  75. package/src/log/logger.ts +543 -0
  76. package/src/orchestration/README.md +89 -0
  77. package/src/orchestration/coordination/barrier.ts +214 -0
  78. package/src/orchestration/coordination/count-down-latch.ts +215 -0
  79. package/src/orchestration/coordination/errors.ts +98 -0
  80. package/src/orchestration/coordination/index.ts +16 -0
  81. package/src/orchestration/coordination/internal/wait-constraints.ts +95 -0
  82. package/src/orchestration/coordination/internal/wait-queue.ts +109 -0
  83. package/src/orchestration/coordination/keyed-lock.ts +168 -0
  84. package/src/orchestration/coordination/mutex.ts +257 -0
  85. package/src/orchestration/coordination/permit.ts +127 -0
  86. package/src/orchestration/coordination/read-write-lock.ts +444 -0
  87. package/src/orchestration/coordination/semaphore.ts +280 -0
  88. package/src/orchestration/index.ts +1 -0
  89. package/src/random/README.md +78 -0
  90. package/src/random/index.ts +1 -0
  91. package/src/random/string.ts +35 -0
  92. package/src/reactor/README.md +4 -0
  93. package/src/reactor/reactor-core/primitive.ts +9 -9
  94. package/src/reactor/reactor-core/reactive-system.ts +5 -5
  95. package/src/singleton/README.md +79 -0
  96. package/src/singleton/factory.ts +55 -0
  97. package/src/singleton/index.ts +2 -0
  98. package/src/singleton/manager.ts +204 -0
  99. package/src/storage/README.md +107 -0
  100. package/src/storage/index.ts +1 -0
  101. package/src/storage/table.ts +449 -0
  102. package/src/timer/README.md +86 -0
  103. package/src/timer/expiration/expiration-manager.ts +594 -0
  104. package/src/timer/expiration/index.ts +3 -0
  105. package/src/timer/expiration/min-heap.ts +208 -0
  106. package/src/timer/expiration/remaining-manager.ts +241 -0
  107. package/src/timer/index.ts +1 -0
  108. package/src/type/README.md +54 -307
  109. package/src/type/class.ts +2 -2
  110. package/src/type/index.ts +14 -14
  111. package/src/type/is.ts +265 -2
  112. package/src/type/object.ts +37 -0
  113. package/src/type/string.ts +7 -2
  114. package/src/type/tuple.ts +6 -6
  115. package/src/type/union.ts +16 -0
  116. package/src/web/README.md +77 -0
  117. package/src/web/capture.ts +35 -0
  118. package/src/web/clipboard.ts +97 -0
  119. package/src/web/dom.ts +117 -0
  120. package/src/web/download.ts +16 -0
  121. package/src/web/event.ts +46 -0
  122. package/src/web/index.ts +10 -0
  123. package/src/web/local-storage.ts +113 -0
  124. package/src/web/location.ts +28 -0
  125. package/src/web/permission.ts +172 -0
  126. package/src/web/script-loader.ts +432 -0
  127. package/tests/unit/abort/abort-manager.spec.ts +225 -0
  128. package/tests/unit/abort/abort-signal-listener-manager.spec.ts +62 -0
  129. package/tests/unit/basic/array.spec.ts +1 -1
  130. package/tests/unit/basic/object.spec.ts +32 -1
  131. package/tests/unit/basic/stream.spec.ts +1 -1
  132. package/tests/unit/basic/string.spec.ts +0 -9
  133. package/tests/unit/color/rgb/analyze.spec.ts +110 -0
  134. package/tests/unit/color/rgb/construct.spec.ts +56 -0
  135. package/tests/unit/color/rgb/convert.spec.ts +60 -0
  136. package/tests/unit/color/rgb/derive.spec.ts +103 -0
  137. package/tests/unit/color/rgb/parse.spec.ts +66 -0
  138. package/tests/unit/color/rgb/serialize.spec.ts +46 -0
  139. package/tests/unit/color/xyz/analyze.spec.ts +33 -0
  140. package/tests/unit/color/xyz/construct.spec.ts +10 -0
  141. package/tests/unit/color/xyz/convert.spec.ts +18 -0
  142. package/tests/unit/css/class.spec.ts +157 -0
  143. package/tests/unit/encoding/base64.spec.ts +40 -0
  144. package/tests/unit/environment/basic.spec.ts +20 -0
  145. package/tests/unit/environment/device.spec.ts +146 -0
  146. package/tests/unit/environment/feature.spec.ts +388 -0
  147. package/tests/unit/environment/geo.spec.ts +111 -0
  148. package/tests/unit/environment/runtime.spec.ts +364 -0
  149. package/tests/unit/environment/snapshot.spec.ts +4 -0
  150. package/tests/unit/environment/variable.spec.ts +190 -0
  151. package/tests/unit/event/class-event-proxy.spec.ts +225 -0
  152. package/tests/unit/event/event-manager.spec.ts +246 -0
  153. package/tests/unit/event/instance-event-proxy.spec.ts +187 -0
  154. package/tests/unit/exception/browser.spec.ts +213 -0
  155. package/tests/unit/exception/nodejs.spec.ts +144 -0
  156. package/tests/unit/exception/normalize.spec.ts +57 -0
  157. package/tests/unit/identifier/id.spec.ts +71 -0
  158. package/tests/unit/identifier/uuid.spec.ts +85 -0
  159. package/tests/unit/log/log-emitter.spec.ts +33 -0
  160. package/tests/unit/log/log-scheduler.spec.ts +40 -0
  161. package/tests/unit/log/log-type.spec.ts +7 -0
  162. package/tests/unit/log/logger.spec.ts +222 -0
  163. package/tests/unit/orchestration/coordination/barrier.spec.ts +96 -0
  164. package/tests/unit/orchestration/coordination/count-down-latch.spec.ts +63 -0
  165. package/tests/unit/orchestration/coordination/errors.spec.ts +29 -0
  166. package/tests/unit/orchestration/coordination/keyed-lock.spec.ts +109 -0
  167. package/tests/unit/orchestration/coordination/mutex.spec.ts +132 -0
  168. package/tests/unit/orchestration/coordination/permit.spec.ts +43 -0
  169. package/tests/unit/orchestration/coordination/read-write-lock.spec.ts +154 -0
  170. package/tests/unit/orchestration/coordination/semaphore.spec.ts +135 -0
  171. package/tests/unit/random/string.spec.ts +11 -0
  172. package/tests/unit/reactor/alien-signals-effect.spec.ts +11 -10
  173. package/tests/unit/reactor/preact-signal.spec.ts +1 -2
  174. package/tests/unit/singleton/singleton.spec.ts +49 -0
  175. package/tests/unit/storage/table.spec.ts +620 -0
  176. package/tests/unit/timer/expiration/expiration-manager.spec.ts +464 -0
  177. package/tests/unit/timer/expiration/min-heap.spec.ts +71 -0
  178. package/tests/unit/timer/expiration/remaining-manager.spec.ts +234 -0
  179. package/.oxlintrc.json +0 -5
package/src/basic/is.ts CHANGED
@@ -13,81 +13,140 @@ import type {
13
13
 
14
14
  /**
15
15
  * 进行类型检测的常用手段包括:
16
- * - typeof: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
16
+ * - typeof: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
17
17
  * https://tc39.es/ecma262/#sec-typeof-operator
18
- * - instanceof: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof
19
- * - toString: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
18
+ * - instanceof: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof
19
+ * - toString: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
20
20
  *
21
- * - `typeof` operator can operate on non-exist variable.
21
+ * 检测可能不存在的变量:
22
+ * - typeof value === "undefined"
23
+ * - globalThis.value === undefined
22
24
  */
23
25
 
24
26
  /**
25
- *
27
+ * 判断目标值是否为原始值(primitive)。
26
28
  */
27
29
  export const isPrimitive = (target: unknown): target is Primitive => {
28
30
  return isString(target) || isNumber(target) || isBoolean(target) || isBigInt(target) || isSymbol(target) || isNull(target) || isUndefined(target)
29
31
  }
32
+
33
+ /**
34
+ * 判断目标值是否为非原始值(non-primitive)。
35
+ */
30
36
  export const isNonPrimitive = (target: unknown): target is NonPrimitive => {
31
37
  return isPrimitive(target) === false
32
38
  }
39
+
40
+ /**
41
+ * 判断目标值是否为字符串。
42
+ */
33
43
  export const isString = (target: unknown): target is string => {
34
44
  return Object.prototype.toString.call(target) === "[object String]"
35
45
  }
46
+
47
+ /**
48
+ * 判断目标值是否为数字。
49
+ */
36
50
  export const isNumber = (target: unknown): target is number => {
37
51
  return Object.prototype.toString.call(target) === "[object Number]" && isNaN(Number.parseFloat(String(target)))
38
52
  }
53
+
54
+ /**
55
+ * 判断目标值是否为 `NaN`。
56
+ */
39
57
  export const isNaN = (target: unknown): boolean => {
40
58
  return Number.isNaN(target)
41
59
  }
60
+
61
+ /**
62
+ * 判断目标值是否为有限数字。
63
+ */
42
64
  export const isFiniteNumber = (target: unknown): target is number => {
43
65
  return isNumber(target) && Number.isFinite(target)
44
66
  }
67
+
68
+ /**
69
+ * 判断目标值是否为无限数字。
70
+ */
45
71
  export const isInfiniteNumber = (target: unknown): target is number => {
46
72
  return isNumber(target) && !Number.isFinite(target)
47
73
  }
74
+
75
+ /**
76
+ * 判断目标值是否为布尔值。
77
+ */
48
78
  export const isBoolean = (target: unknown): target is boolean => {
49
79
  return Object.prototype.toString.call(target) === "[object Boolean]"
50
80
  }
81
+
82
+ /**
83
+ * 判断目标值是否为 `true`。
84
+ */
51
85
  export const isTrue = (target: unknown): target is true => {
52
86
  return isBoolean(target) && target === true
53
87
  }
88
+
89
+ /**
90
+ * 判断目标值是否为 `false`。
91
+ */
54
92
  export const isFalse = (target: unknown): target is false => {
55
93
  return isBoolean(target) && target === false
56
94
  }
95
+
96
+ /**
97
+ * 判断目标值是否为大整数(BigInt)。
98
+ */
57
99
  export const isBigInt = (target: unknown): target is bigint => {
58
100
  return Object.prototype.toString.call(target) === "[object BigInt]"
59
101
  }
102
+
103
+ /**
104
+ * 判断目标值是否为符号(Symbol)。
105
+ */
60
106
  export const isSymbol = (target: unknown): target is symbol => {
61
107
  return Object.prototype.toString.call(target) === "[object Symbol]"
62
108
  }
109
+
110
+ /**
111
+ * 判断目标值是否为 `null`。
112
+ */
63
113
  export const isNull = (target: unknown): target is null => {
64
114
  return Object.prototype.toString.call((target)) === "[object Null]"
65
115
  }
116
+
117
+ /**
118
+ * 判断目标值是否为 `undefined`。
119
+ */
66
120
  export const isUndefined = (target: unknown): target is undefined => {
67
121
  return Object.prototype.toString.call(target) === "[object Undefined]"
68
122
  }
69
123
  /**
124
+ * 判断目标值是否不是 `undefined`。
125
+ *
70
126
  * @see {@link https://stackoverflow.com/a/52097700}
71
127
  */
72
128
  export const isDefined = <T>(target: T | undefined): target is T => {
73
129
  return isUndefined(target) === false
74
130
  }
131
+
132
+ /**
133
+ * 判断目标值是否为 `null` 或 `undefined`。
134
+ */
75
135
  export const isNil = (target: unknown): target is (null | undefined) => {
76
136
  return target === null || target === undefined
77
137
  }
78
138
 
79
139
  /**
80
- * Predicate whether the target is an Object, use `instanceof` operator to check.
140
+ * 使用 `instanceof` 判断目标值是否为对象。
81
141
  *
82
142
  * @see {@link isGeneralObject}, {@link isPlainObject}
83
143
  */
84
144
  // oxlint-disable-next-line no-wrapper-object-types
85
145
  export const isObject = (target: unknown): target is Object => {
86
- // oxlint-disable-next-line no-instanceof-builtins
87
146
  return target instanceof Object
88
147
  }
89
148
  /**
90
- * Predicate whether the target is a general object, use `typeof` operator to check.
149
+ * 使用 `typeof` 判断目标值是否为广义对象。
91
150
  *
92
151
  * A general object is an object that is:
93
152
  * - not `null`, not a `function`, not a `primitive`.
@@ -97,17 +156,12 @@ export const isObject = (target: unknown): target is Object => {
97
156
  *
98
157
  * @example
99
158
  * ```
100
- * typeof null // => 'object'
101
- * typeof [] // => 'object'
102
- * typeof {} // => 'object'
103
- * typeof { a: 1 } // => 'object'
104
- * typeof (new Map()) // => 'object'
105
- * typeof (new WeakMap()) // => 'object'
106
- * typeof (new Set()) // => 'object'
107
- * typeof (new WeakSet()) // => 'object'
108
- * typeof (new Date()) // => 'object'
109
- * typeof window // => 'object'
110
- * typeof document // => 'object'
159
+ * // Expect: true
160
+ * const example1 = isGeneralObject([])
161
+ * // Expect: true
162
+ * const example2 = isGeneralObject(new Map())
163
+ * // Expect: false
164
+ * const example3 = isGeneralObject(null)
111
165
  * ```
112
166
  *
113
167
  * @see {@link isObject}, {@link isPlainObject}
@@ -141,88 +195,151 @@ export const isPlainObject = (target: unknown): target is PlainObject => {
141
195
  const proto = Object.getPrototypeOf(target)
142
196
  return proto === Object.prototype || proto === null
143
197
  }
198
+
199
+ /**
200
+ * 判断目标值是否为空普通对象。
201
+ */
144
202
  export const isEmptyPlainObject = (target: unknown): target is PlainObject => {
145
203
  return isPlainObject(target) && Reflect.ownKeys(target).length === 0
146
204
  }
147
205
 
206
+ /**
207
+ * 判断目标值是否为数组。
208
+ */
148
209
  export function isArray<T>(target: T[]): target is T[]
149
210
  export function isArray<T>(target: unknown): target is T[]
150
211
  export function isArray<T>(target: unknown): target is T[] {
151
212
  return Array.isArray(target)
152
213
  }
214
+
215
+ /**
216
+ * 判断目标值是否为空数组。
217
+ */
153
218
  export const isEmptyArray = (target: unknown): target is [] => {
154
219
  return isArray(target) && target.length === 0
155
220
  }
156
221
 
222
+ /**
223
+ * 判断目标值是否为类数组对象(array-like)。
224
+ */
157
225
  export function isArrayLike<T>(target: ArrayLike<T>): target is ArrayLike<T>
158
226
  export function isArrayLike<T>(target: unknown): target is ArrayLike<T>
159
227
  export function isArrayLike<T>(target: unknown): target is ArrayLike<T> {
160
228
  return isGeneralObject(target) && ("length" in target) && isNumber(target.length)
161
229
  }
162
230
 
231
+ /**
232
+ * 判断目标值是否为 `Map`。
233
+ */
163
234
  export function isMap<K, V>(target: Map<K, V>): target is Map<K, V>
164
235
  export function isMap<K, V>(target: unknown): target is Map<K, V>
165
236
  export function isMap<K, V>(target: unknown): target is Map<K, V> {
166
237
  return Object.prototype.toString.call(target) === "[object Map]"
167
238
  }
168
239
 
240
+ /**
241
+ * 判断目标值是否为 `WeakMap`。
242
+ */
169
243
  export function isWeakMap<K extends object, V>(target: WeakMap<K, V>): target is WeakMap<K, V>
170
244
  export function isWeakMap<K extends object, V>(target: unknown): target is WeakMap<K, V>
171
245
  export function isWeakMap<K extends object, V>(target: unknown): target is WeakMap<K, V> {
172
246
  return Object.prototype.toString.call(target) === "[object WeakMap]"
173
247
  }
174
248
 
249
+ /**
250
+ * 判断目标值是否为 `Set`。
251
+ */
175
252
  export function isSet<T>(target: Set<T>): target is Set<T>
176
253
  export function isSet<T>(target: unknown): target is Set<T>
177
254
  export function isSet<T>(target: unknown): target is Set<T> {
178
255
  return Object.prototype.toString.call(target) === "[object Set]"
179
256
  }
180
257
 
258
+ /**
259
+ * 判断目标值是否为 `WeakSet`。
260
+ */
181
261
  export function isWeakSet<T extends object>(target: WeakSet<T>): target is WeakSet<T>
182
262
  export function isWeakSet<T extends object>(target: unknown): target is WeakSet<T>
183
263
  export function isWeakSet<T extends object>(target: unknown): target is WeakSet<T> {
184
264
  return Object.prototype.toString.call(target) === "[object WeakSet]"
185
265
  }
186
266
 
267
+ /**
268
+ * 判断目标值是否为 `Date`。
269
+ */
187
270
  export const isDate = (target: unknown): target is Date => {
188
271
  return Object.prototype.toString.call(target) === "[object Date]"
189
272
  }
190
273
 
274
+ /**
275
+ * 判断目标值是否为 `RegExp`。
276
+ */
191
277
  export const isRegExp = (target: unknown): target is RegExp => {
192
278
  return Object.prototype.toString.call(target) === "[object RegExp]"
193
279
  }
194
280
 
281
+ /**
282
+ * 判断目标值是否为 `Error`。
283
+ */
195
284
  export const isError = (target: unknown): target is Error => {
196
285
  return Object.prototype.toString.call(target) === "[object Error]"
197
286
  }
198
287
 
288
+ /**
289
+ * 判断目标值是否为 `Promise`。
290
+ */
199
291
  export function isPromise<T>(target: Promise<T>): target is Promise<T>
200
292
  export function isPromise<T>(target: unknown): target is Promise<T>
201
293
  export function isPromise<T>(target: unknown): target is Promise<T> {
202
294
  return Object.prototype.toString.call(target) === "[object Promise]"
203
295
  }
204
296
 
297
+ /**
298
+ * 判断目标值是否为任意函数。
299
+ */
205
300
  // oxlint-disable-next-line no-unsafe-function-type
206
301
  export const isFunction = (target: unknown): target is Function => {
207
302
  return typeof target === "function"
208
303
  }
304
+
305
+ /**
306
+ * 判断目标值是否为任意同步或异步函数类型。
307
+ */
209
308
  export const isAnyFunction = (target: unknown): target is AnyFunction => {
210
309
  return isFunction(target)
211
310
  }
311
+
312
+ /**
313
+ * 判断目标值是否为同步函数。
314
+ */
212
315
  export const isSyncFunction = (target: unknown): target is AnySyncFunction => {
213
316
  return Object.prototype.toString.call(target) === "[object Function]"
214
317
  }
318
+
319
+ /**
320
+ * 判断目标值是否为异步函数。
321
+ */
215
322
  export const isAsyncFunction = (target: unknown): target is AnyAsyncFunction => {
216
323
  return Object.prototype.toString.call(target) === "[object AsyncFunction]"
217
324
  }
325
+
326
+ /**
327
+ * 判断目标值是否为生成器函数。
328
+ */
218
329
  export const isGeneratorFunction = (target: unknown): target is AnyGeneratorFunction => {
219
330
  return Object.prototype.toString.call((target)) === "[object GeneratorFunction]"
220
331
  }
332
+
333
+ /**
334
+ * 判断目标值是否为异步生成器函数。
335
+ */
221
336
  export const isAsyncGeneratorFunction = (target: unknown): target is AnyAsyncGeneratorFunction => {
222
337
  return Object.prototype.toString.call(target) === "[object AsyncGeneratorFunction]"
223
338
  }
224
339
 
225
340
  /**
341
+ * 判断目标值是否实现可迭代协议(iterable protocol)。
342
+ *
226
343
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol}
227
344
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator}
228
345
  */
@@ -233,6 +350,8 @@ export function isIterable<T>(target: unknown): target is Iterable<T> {
233
350
  return isGeneralObject(target) && typeof (target as any)[Symbol.iterator] === "function"
234
351
  }
235
352
  /**
353
+ * 判断目标值是否实现异步可迭代协议。
354
+ *
236
355
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator}
237
356
  */
238
357
  export function isAsyncIterable<T>(target: AsyncIterable<T>): target is AsyncIterable<T>
@@ -242,6 +361,8 @@ export function isAsyncIterable<T>(target: unknown): target is AsyncIterable<T>
242
361
  return isGeneralObject(target) && typeof (target as any)[Symbol.asyncIterator] === "function"
243
362
  }
244
363
  /**
364
+ * 判断目标值是否实现迭代器协议(iterator protocol)。
365
+ *
245
366
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterator_protocol}
246
367
  */
247
368
  export function isIterator<T, TReturn = unknown, TNext = undefined>(target: Iterator<T, TReturn, TNext>): target is Iterator<T, TReturn, TNext>
@@ -250,71 +371,31 @@ export function isIterator<T, TReturn = unknown, TNext = undefined>(target: unkn
250
371
  // oxlint-disable-next-line no-unsafe-type-assertion no-unsafe-member-access
251
372
  return isGeneralObject(target) && typeof (target as any).next === "function"
252
373
  }
374
+
375
+ /**
376
+ * 判断目标值是否实现异步迭代器协议。
377
+ */
253
378
  export function isAsyncIterator<T, TReturn = unknown, TNext = undefined>(target: AsyncIterator<T, TReturn, TNext>): target is AsyncIterator<T, TReturn, TNext>
254
379
  export function isAsyncIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is AsyncIterator<T, TReturn, TNext>
255
380
  export function isAsyncIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is AsyncIterator<T, TReturn, TNext> {
256
381
  // oxlint-disable-next-line no-unsafe-type-assertion no-unsafe-member-access
257
382
  return isGeneralObject(target) && typeof (target as any).next === "function"
258
383
  }
384
+
385
+ /**
386
+ * 判断目标值是否同时满足可迭代对象与迭代器的条件。
387
+ */
259
388
  export function isIterableIterator<T, TReturn = unknown, TNext = undefined>(target: IterableIterator<T>): target is IterableIterator<T, TReturn, TNext>
260
389
  export function isIterableIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is IterableIterator<T, TReturn, TNext>
261
390
  export function isIterableIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is IterableIterator<T> {
262
391
  return isIterator<T, TReturn, TNext>(target) && isIterable<T>(target)
263
392
  }
393
+
394
+ /**
395
+ * 判断目标值是否同时满足异步可迭代对象与异步迭代器的条件。
396
+ */
264
397
  export function isAsyncIterableIterator<T, TReturn = unknown, TNext = undefined>(target: AsyncIterableIterator<T>): target is AsyncIterableIterator<T, TReturn, TNext>
265
398
  export function isAsyncIterableIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is AsyncIterableIterator<T, TReturn, TNext>
266
399
  export function isAsyncIterableIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is AsyncIterableIterator<T> {
267
400
  return isAsyncIterator<T, TReturn, TNext>(target) && isAsyncIterable<T>(target)
268
401
  }
269
-
270
- /**
271
- * Check `target` and `Window` is both defined
272
- * before use the `instanceof` operator to check `target` is instanceof `Window`.
273
- */
274
- export const isWindow = (target: unknown): target is Window => {
275
- return isGeneralObject(target) && isDefined(Window) && target instanceof Window
276
- }
277
- /**
278
- * Check `target` and `Element` is both defined
279
- * before use the `instanceof` operator to check `target` is instanceof `Element`.
280
- */
281
- export const isElement = (target: unknown): target is Element => {
282
- return isGeneralObject(target) && isDefined(Element) && target instanceof Element
283
- }
284
- /**
285
- * Check `target` and `Node` is both defined
286
- * before use the `instanceof` operator to check `target` is instanceof `Node`.
287
- */
288
- export const isNode = (target: unknown): target is Node => {
289
- return isGeneralObject(target) && isDefined(Node) && target instanceof Node
290
- }
291
- /**
292
- * Check `target` and `HTMLElement` is both defined
293
- * before use the `instanceof` operator to check `target` is instanceof `HTMLElement`.
294
- */
295
- export const isHTMLElement = (target: unknown): target is HTMLElement => {
296
- return isGeneralObject(target) && isDefined(HTMLElement) && target instanceof HTMLElement
297
- }
298
- /**
299
- * Check `target` and `HTMLCollection` is both defined
300
- * before use the `instanceof` operator to check `target` is instanceof `HTMLCollection`.
301
- */
302
- export const isHTMLCollection = (target: unknown): target is HTMLCollection => {
303
- return isGeneralObject(target) && isDefined(HTMLCollection) && target instanceof HTMLCollection
304
- }
305
- /**
306
- * Check `target` and `Document` is both defined
307
- * before use the `instanceof` operator to check `target` is instanceof `Document`.
308
- */
309
- export const isDocument = (target: unknown): target is Document => {
310
- return isGeneralObject(target) && isDefined(Document) && target instanceof Document
311
- }
312
- /**
313
- * Check `target` and `EventTarget` is both defined
314
- * before use the `instanceof` operator to check `target` is instanceof `EventTarget`.
315
- *
316
- * @see {@link https://developer.mozilla.org/zh-CN/docs/Web/API/Event}
317
- */
318
- export const isEventTarget = (target: unknown): target is EventTarget => {
319
- return isGeneralObject(target) && isDefined(EventTarget) && target instanceof EventTarget
320
- }
@@ -1,4 +1,5 @@
1
1
  import type { AnyRecord } from "../type/index.ts"
2
+ import { isDate } from "./is.ts"
2
3
 
3
4
  /**
4
5
  * Return a new object that includes only the specified keys from the source object.
@@ -56,3 +57,84 @@ export const excludeFields = <T extends AnyRecord, K extends keyof T>(
56
57
  // oxlint-disable-next-line no-unsafe-type-assertion
57
58
  return newObject as Omit<T, K> // 使用Omit类型确保返回的类型反映了被排除的键
58
59
  }
60
+
61
+ /**
62
+ * Convert all Date fields in an object to number.
63
+ *
64
+ * @example
65
+ * ```before
66
+ * type Obj = {
67
+ * createdAt: Date,
68
+ * }
69
+ * ```
70
+ * ```after
71
+ * type Obj = {
72
+ * createdAt: number,
73
+ * }
74
+ * ```
75
+ *
76
+ * @example
77
+ * ```before
78
+ * type Obj = {
79
+ * createdAt: Date | undefined,
80
+ * }
81
+ * ```
82
+ * ```after
83
+ * type Obj = {
84
+ * createdAt: number | undefined,
85
+ * }
86
+ * ```
87
+ *
88
+ * @example
89
+ * ```before
90
+ * type Obj = {
91
+ * createdAt: Date | null,
92
+ * }
93
+ * ```
94
+ * ```after
95
+ * type Obj = {
96
+ * createdAt: number | null,
97
+ * }
98
+ * ```
99
+ */
100
+ export type ObjectDateFieldsToNumber<O extends object> = {
101
+ [K in keyof O]: O[K] extends Date
102
+ ? number
103
+ : (
104
+ O[K] extends Date | undefined
105
+ ? number | undefined
106
+ :
107
+ (O[K] extends Date | null
108
+ ? number | null
109
+ : (
110
+ O[K] extends object
111
+ ? ObjectDateFieldsToNumber<O[K]>
112
+ : O[K]
113
+ )
114
+ )
115
+ )
116
+ }
117
+ /**
118
+ * Convert all Date fields in an object to number.
119
+ *
120
+ * @example
121
+ * ```
122
+ * const obj = { createdAt: new Date() };
123
+ * const result = objectDateFieldsToNumber(obj);
124
+ * // Expect: { createdAt: 1712345678901 }
125
+ * ```
126
+ */
127
+ export const objectDateFieldsToNumber = <O extends Record<string | number | symbol, unknown>>(
128
+ obj: O
129
+ ): ObjectDateFieldsToNumber<O> => {
130
+ // oxlint-disable-next-line guard-for-in
131
+ for (const key in obj) {
132
+ const value = obj[key];
133
+ if (isDate(value)) {
134
+ // oxlint-disable-next-line no-unsafe-type-assertion
135
+ obj[key] = value.getTime() as O[Extract<keyof O, string>]
136
+ }
137
+ }
138
+ // oxlint-disable-next-line no-unsafe-type-assertion
139
+ return obj as ObjectDateFieldsToNumber<O>
140
+ }
@@ -56,32 +56,43 @@ export const promiseFinally = async <V>(
56
56
  }
57
57
 
58
58
  const INTERNAL_PROMISE_FAIL_RESULT_TYPE: symbol = Symbol("fail")
59
+
60
+ /**
61
+ * 表示标准化的 Promise 失败结果。
62
+ */
59
63
  export interface PromiseFailResult {
60
64
  __type__: typeof INTERNAL_PROMISE_FAIL_RESULT_TYPE
61
65
  reason: unknown
62
66
  }
67
+
68
+ /**
69
+ * 表示带原始下标信息的 Promise 失败结果。
70
+ */
63
71
  export interface PromiseIndexedFailResult extends PromiseFailResult {
64
72
  index: number
65
73
  }
74
+
75
+ /**
76
+ * 根据拒因构造标准化的 Promise 失败结果。
77
+ */
66
78
  export const promiseConstructFailResult = (reason: unknown): PromiseFailResult => {
67
79
  return { __type__: INTERNAL_PROMISE_FAIL_RESULT_TYPE, reason }
68
80
  }
69
81
  /**
70
- * Predicate whether the target is a promise fail result.
82
+ * 判断目标值是否为标准化的 Promise 失败结果。
71
83
  */
72
84
  export const isPromiseFailResult = (target: unknown): target is PromiseFailResult => {
73
85
  return isPlainObject(target) && target["__type__"] === INTERNAL_PROMISE_FAIL_RESULT_TYPE
74
86
  }
75
87
  /**
76
- * Designed to use as `onrejected` callback of `Promise.catch`
77
- * to return a standard `PromiseFailResult`.
88
+ * 用作 `Promise.catch` `onrejected` 回调,并返回标准化失败结果。
78
89
  */
79
90
  export const promiseCatchToFailResult = (reason: unknown): PromiseFailResult => {
80
91
  return { __type__: INTERNAL_PROMISE_FAIL_RESULT_TYPE, reason }
81
92
  }
82
93
 
83
94
  /**
84
- * Giving an array, filter non-`PromiseFailResult` items.
95
+ * 从结果数组中过滤出非 `PromiseFailResult` 项。
85
96
  */
86
97
  export const promiseFilterSuccessResults = <V>(
87
98
  results: Array<V | PromiseFailResult>,
@@ -93,8 +104,7 @@ export const promiseFilterSuccessResults = <V>(
93
104
  return filtered as V[]
94
105
  }
95
106
  /**
96
- * Giving a array, filter `PromiseFailResult` items, with extra `index` property
97
- * which indicate the index of the item in the original array.
107
+ * 从结果数组中过滤出失败项,并补充其原始下标。
98
108
  */
99
109
  export const promiseFilterFailResults = <V>(
100
110
  results: Array<V | PromiseFailResult>,
@@ -125,8 +135,12 @@ type PromiseQueueFirstPromiseMaker<T, S = unknown> = (context: PromiseQueueFirst
125
135
  type PromiseQueueRestPromiseMaker<T, S = unknown> = (context: PromiseQueueRestPromiseMakerContext<T, S>) => Promise<T>
126
136
  type PromiseQueuePromiseMakers<T, S = unknown> = [
127
137
  PromiseQueueFirstPromiseMaker<T, S>,
128
- ...PromiseQueueRestPromiseMaker<T, S>[]
138
+ ...Array<PromiseQueueRestPromiseMaker<T, S>>
129
139
  ]
140
+
141
+ /**
142
+ * `promiseQueue` 的配置项。
143
+ */
130
144
  export interface PromiseQueueOptions {
131
145
  /**
132
146
  * @default 0
@@ -204,6 +218,10 @@ interface PromiseRetryRestPromiseMakerContext<T, S = unknown> {
204
218
  type PromiseRetryPromiseMaker<T, S = unknown> = (
205
219
  context: PromiseRetryFirstPromiseMakerContext<S> | PromiseRetryRestPromiseMakerContext<T, S>
206
220
  ) => Promise<T>
221
+
222
+ /**
223
+ * `promiseRetryWhile` 与 `promiseRetryUntil` 的配置项。
224
+ */
207
225
  export interface PromiseRetryOptions {
208
226
  /**
209
227
  * @default 0
@@ -387,6 +405,10 @@ interface PromiseForeverRestPromiseMakerContext<T, S = unknown> {
387
405
  type PromiseForeverPromiseMaker<T, S = unknown> = (
388
406
  context: PromiseForeverFirstPromiseMakerContext<S> | PromiseForeverRestPromiseMakerContext<T, S>
389
407
  ) => Promise<T>
408
+
409
+ /**
410
+ * `promiseForever` 的配置项。
411
+ */
390
412
  export interface PromiseForeverOptions {
391
413
  /**
392
414
  * @default 0
@@ -441,7 +463,6 @@ export const promiseForever = <T, S = unknown>(
441
463
  context: PromiseForeverFirstPromiseMakerContext<S> | PromiseForeverRestPromiseMakerContext<T, S>
442
464
  ): void => {
443
465
  void promiseMaker(context)
444
- // oxlint-disable-next-line prefer-await-to-callbacks
445
466
  .catch((error: unknown) => {
446
467
  const failedResult = promiseCatchToFailResult(error)
447
468
  if (onRejected !== undefined) {
@@ -1,34 +1,3 @@
1
- const internalRandomPacket: Record<number, string[]> = {}
2
- /**
3
- * Generate a random string with a fixed length and optional character set.
4
- *
5
- * @example
6
- * ```
7
- * // Expect: 8
8
- * const example1 = stringRandom(8).length
9
- * // Expect: true
10
- * const example2 = stringRandom(4, "ab").split("").every(char => char === "a" || char === "b")
11
- * ```
12
- */
13
- export const stringRandom = (length: number, chars?: string | undefined): string => {
14
- let result = ""
15
- const preparedChars = chars ?? "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
16
-
17
- Array.from({ length }).forEach(() => {
18
- result = result + preparedChars[Math.floor(Math.random() * preparedChars.length)]!
19
- })
20
-
21
- internalRandomPacket[length] = internalRandomPacket[length] ?? []
22
- const packet = internalRandomPacket[length]
23
- if (packet.includes(result)) {
24
- return stringRandom(length, preparedChars)
25
- }
26
- else {
27
- packet.push(result)
28
- return result
29
- }
30
- }
31
-
32
1
  /**
33
2
  * Convert a camelCase string into kebab-case.
34
3
  *
@@ -177,8 +146,8 @@ export const stringSliceByUnits = (text: string, start: number, end: number): st
177
146
 
178
147
  export interface StringSplitOptions {
179
148
  input: string
180
- chunkSize: number
181
- chunkOverlap: number
149
+ chunkSize?: number | undefined
150
+ chunkOverlap?: number | undefined
182
151
  }
183
152
 
184
153
  /**