foreslash 0.2.4 → 0.3.1

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.
package/lib/index.d.ts CHANGED
@@ -169,7 +169,7 @@ type RetryOption = {
169
169
  * ```js
170
170
  * // 基本用法, 默认重试 3 次, 每次失败后会立即重新调用
171
171
  * const res = await retry(() => fetch(url, params))
172
- * // 重试 10 次
172
+ * // 重试 10 次, 最多会调用传入的函数 10
173
173
  * const res = await retry(() => fetch(url, params), { times: 10 })
174
174
  * // 延迟模式, 每次失败后会等待 1 秒再重新调用
175
175
  * const res = await retry(() => fetch(url, params), { delay: 1000 })
@@ -196,8 +196,7 @@ declare function retry<T>(asyncFunction: RetryFunction<T>, option?: RetryOption)
196
196
  */
197
197
  declare function sleep(time?: number): Promise<unknown>;
198
198
 
199
- type TryitResultType<Res, Err> = [undefined, Res] | [Err, undefined];
200
- type TryitResult<Res, Err extends Error> = Res extends Promise<infer R> ? Promise<TryitResultType<R, Err>> : TryitResultType<Res, Err>;
199
+ type TryitResult<Res, Err> = [undefined, Res] | [Err, undefined];
201
200
  /**
202
201
  * 将一个函数处理为 `error-first` 的函数
203
202
  * @param fn 需要处理的函数, 可以是异步函数
@@ -207,11 +206,6 @@ type TryitResult<Res, Err extends Error> = Res extends Promise<infer R> ? Promis
207
206
  * 如果出现异常则 `result` 为 `undefined`, `error` 是原函数抛出的错误
208
207
  * @example
209
208
  * ```js
210
- * // Sync Function
211
- * const normalFn = () => { return 1 }
212
- * const errorFn = () => { throw new Error('1') }
213
- * tryit(normalFn)() // [undefined, 1]
214
- * tryit(errorFn)() // [Error('1'), undefined]
215
209
  * // Async Function
216
210
  * const normalAsyncFn = () => { return Promise.resolve(1) }
217
211
  * const errorAsyncFn = () => { return Promise.reject('1') }
@@ -220,6 +214,24 @@ type TryitResult<Res, Err extends Error> = Res extends Promise<infer R> ? Promis
220
214
  * ```
221
215
  * @version 0.2.0
222
216
  */
217
+ declare function tryit<Args extends any[], Res, Err extends Error>(fn: (...args: Args) => Promise<Res>): (...args: Args) => Promise<TryitResult<Res, Err>>;
218
+ /**
219
+ * 将一个函数处理为 `error-first` 的函数
220
+ * @param fn 需要处理的函数, 可以是异步函数
221
+ * @returns 处理过的函数, 调用后返回一个 `error-first` 的元组 `[error, result]`;\
222
+ * 如果原函数是异步函数, 则返回值会是 `Promise<[error, result]>`;\
223
+ * 如果运行正常则 `result` 是原函数的返回值, `error` 为 `undefined`;\
224
+ * 如果出现异常则 `result` 为 `undefined`, `error` 是原函数抛出的错误
225
+ * @example
226
+ * ```js
227
+ * // Sync Function
228
+ * const normalFn = () => { return 1 }
229
+ * const errorFn = () => { throw new Error('1') }
230
+ * tryit(normalFn)() // [undefined, 1]
231
+ * tryit(errorFn)() // [Error('1'), undefined]
232
+ * ```
233
+ * @version 0.2.0
234
+ */
223
235
  declare function tryit<Args extends any[], Res, Err extends Error>(fn: (...args: Args) => Res): (...args: Args) => TryitResult<Res, Err>;
224
236
 
225
237
  interface PromiseLikeConstructor {
@@ -308,6 +320,19 @@ declare function isArrayLike(value: unknown): value is ArrayLike<any>;
308
320
  */
309
321
  declare function isBigInt(value: unknown): value is bigint;
310
322
 
323
+ /**
324
+ * 类型守卫,判断给定的值是否为 `Blob` 对象
325
+ * @param value 要判断的值
326
+ * @example
327
+ * ```js
328
+ * isBlob(new Blob()) // true
329
+ * isBlob(new ArrayBuffer(8)) // false
330
+ * isBlob([1, 2, 3]) // false
331
+ * ```
332
+ * @version 0.3.0
333
+ */
334
+ declare function isBlob(value: any): value is Blob;
335
+
311
336
  /**
312
337
  * 类型守卫,判断给定的值是否为布尔类型
313
338
  * @param value 要判断的值
@@ -1153,6 +1178,18 @@ declare function titleCase(str: string, options?: {
1153
1178
  keepNumber?: boolean;
1154
1179
  }): string;
1155
1180
 
1181
+ /**
1182
+ * 将字符串的首字母大写
1183
+ * @param str 字符串
1184
+ * @returns 首字母大写后的字符串
1185
+ * @example
1186
+ * ```js
1187
+ * capitalize('hello world') // 'Hello world'
1188
+ * ```
1189
+ * @version 0.3.0
1190
+ */
1191
+ declare function capitalize(str: string): string;
1192
+
1156
1193
  type VarCase = {
1157
1194
  code: string;
1158
1195
  /** 是否为全大写 */
@@ -1239,6 +1276,74 @@ declare function caseKebab(str: string, keepLetterCase?: boolean, keepNumber?: b
1239
1276
  */
1240
1277
  declare function caseSnake(str: string, keepLetterCase?: boolean, keepNumber?: boolean): string;
1241
1278
 
1279
+ /**
1280
+ * 给一个多行的字符串清除缩进效果
1281
+ * @param str 需要处理的字符串
1282
+ * @param count 缩进数量, 默认为 `2`
1283
+ * @param indentStr 缩进字符串, 默认为 ` `(一个空格)
1284
+ * @returns 处理过的字符串
1285
+ * @example
1286
+ * ```js
1287
+ * dedent(` a\n b\n c`) // `a\nb\n c`
1288
+ * dedent(`*a\n**b\n****c`, 3, '*') // `a\nb\n*c`
1289
+ * ```
1290
+ * @version 0.3.1
1291
+ */
1292
+ declare function dedent(str: string, count?: number | null, indentStr?: string): string;
1293
+ /**
1294
+ * 给一个多行的字符串清除缩进效果
1295
+ * @param str 需要处理的字符串
1296
+ * @param option 缩进效果配置
1297
+ * - `count` 缩进数量, 默认为 `2`
1298
+ * - `indentStr` 缩进字符串, 默认为 ` `(一个空格)
1299
+ * @returns 处理过的字符串
1300
+ * @example
1301
+ * ```js
1302
+ * dedent(` a\n b\n c`) // `a\nb\n c`
1303
+ * dedent(`*a\n**b\n****c`, { count: 3, indentStr: '*' }) // `a\nb\n*c`
1304
+ * ```
1305
+ * @version 0.3.1
1306
+ */
1307
+ declare function dedent(str: string, option?: {
1308
+ count?: number;
1309
+ indentStr?: string;
1310
+ }): string;
1311
+
1312
+ /**
1313
+ * 给一个多行的字符串添加缩进效果
1314
+ * @param str 需要处理的字符串
1315
+ * @param count 缩进数量, 默认为 `2`
1316
+ * @param indentStr 缩进字符串, 默认为 ` `(一个空格)
1317
+ * @returns 处理过的字符串
1318
+ * @example
1319
+ * ```js
1320
+ * indent(`a\nb\n c`) // ` a\n b\n c`
1321
+ * indent(`a\nb\n c`, 1, '*') // `*a\n*b\n* c`
1322
+ * ```
1323
+ * @version 0.3.1
1324
+ */
1325
+ declare function indent(str: string, count?: number | null, indentStr?: string): string;
1326
+ /**
1327
+ * 给一个多行的字符串添加缩进效果
1328
+ * @param str 需要处理的字符串
1329
+ * @param option 缩进效果配置
1330
+ * - `count` 缩进数量, 默认为 `2`
1331
+ * - `indentStr` 缩进字符串, 默认为 ` `(一个空格)
1332
+ * - `ignoreEmptyLine` 是否忽略空行, 默认为是
1333
+ * @returns 处理过的字符串
1334
+ * @example
1335
+ * ```js
1336
+ * indent(`a\nb\n c`) // ` a\n b\n c`
1337
+ * indent(`a\nb\n c`, { count: 1, indentStr: '*' }) // `*a\n*b\n* c`
1338
+ * ```
1339
+ * @version 0.3.1
1340
+ */
1341
+ declare function indent(str: string, option?: {
1342
+ count?: number;
1343
+ indentStr?: string;
1344
+ ignoreEmptyLine?: boolean;
1345
+ }): string;
1346
+
1242
1347
  /**
1243
1348
  * 分割单词, 适用于分割、转换变量名的场景
1244
1349
  * - 任何非英文字母、数字的字符均会视为分割符
@@ -1253,6 +1358,18 @@ declare function caseSnake(str: string, keepLetterCase?: boolean, keepNumber?: b
1253
1358
  */
1254
1359
  declare function splitWords(str: string): string[];
1255
1360
 
1361
+ /**
1362
+ * 将字符串的首字母小写
1363
+ * @param str 字符串
1364
+ * @returns 首字母小写后的字符串
1365
+ * @example
1366
+ * ```js
1367
+ * uncapitalize('Hello world') // 'hello world'
1368
+ * ```
1369
+ * @version 0.3.0
1370
+ */
1371
+ declare function uncapitalize(str: string): string;
1372
+
1256
1373
  /**
1257
1374
  * 调用`Object.prototype.toString`获取对象类型名称
1258
1375
  * @param value 要判断的类型
@@ -1490,6 +1607,130 @@ type CloneOptions = {
1490
1607
  */
1491
1608
  declare function deepClone<T>(obj: T, options?: Partial<CloneOptions>, map?: Map<any, any>): T;
1492
1609
 
1610
+ /**
1611
+ * 合并策略, 可以是 `'keep'` `'override'` `'merge'` 或者一个方法
1612
+ * - `'keep'` 表示保留原值
1613
+ * - `'override'` 表示覆盖为新值
1614
+ * - 如果是自定义合并方法, 那么你的方法接收的第一个参数是需要合并的值以及其路径
1615
+ * - `{ target: 原值; source: 新值; path: 路径数组; unhandledValue: 如果无法处理则返回这个 }`
1616
+ */
1617
+ type MergeStrategy = 'keep' | 'override' | MergeStrategyFunction;
1618
+ type MergeStrategyFunction<T = any, S = any, Res = any> = (param: {
1619
+ target: T;
1620
+ source: S;
1621
+ path: (string | symbol)[];
1622
+ unhandledValue: any;
1623
+ map: Map<any, any>;
1624
+ typeStrategy: MergeTypeStrategy;
1625
+ /** 深拷贝, 直接传值即可, 参数已经预设好了 */
1626
+ cloner: <T>(obj: T) => T;
1627
+ /** 深合并, 直接传值即可, 参数已经预设好了 */
1628
+ merger: (target: any, source: any, path: (string | symbol)[]) => any;
1629
+ }) => Res;
1630
+ /** 所有内部识别的值类型 */
1631
+ type BaseMargeType = 'Number' | 'String' | 'Boolean' | 'Symbol' | 'BigInt' | 'Null' | 'Undefined' | 'Object' | 'Array' | 'Set' | 'Map' | 'FormData' | 'Date' | 'RegExp' | 'Promise' | 'Function' | 'Generator' | 'Iterator' | 'ArrayBuffer' | 'Buffer' | 'DataView' | 'Blob' | 'File' | 'TypedArray' | 'WeakSet' | 'WeakMap' | 'WeakRef' | 'Error';
1632
+ /** 来源对象上的值类型, 不会有 `'Empty'` */
1633
+ type SourceMergeType = BaseMargeType | 'Any';
1634
+ /** 目标对象上的值类型, 如果某个字段目标上没有而来源上有, 那么就为 `"Empty"` */
1635
+ type TargetMergeType = BaseMargeType | 'Empty' | 'Any';
1636
+ /** 合并类型, 其中来源对象上不会有 `'Empty'` */
1637
+ type MergeType = `${SourceMergeType}2${TargetMergeType}`;
1638
+ /** 根据目标对象类型和来源对象类型获取合并策略 */
1639
+ type MergeTypeStrategy = {
1640
+ [mergeType in MergeType]?: MergeStrategy;
1641
+ };
1642
+ type MergeEmptyPlaceholder = A.x & {
1643
+ '@@merge/placeholder': true;
1644
+ };
1645
+ /** `deepMerge` 深合并的空值占位符 */
1646
+ declare const $$Empty: Readonly<{
1647
+ '@@merge/placeholder': true;
1648
+ }>;
1649
+ /**
1650
+ * 判断给定的参数是否为 `deepMerge` 深合并的空值占位符
1651
+ * @param arg 需要判定的参数
1652
+ * @returns 是否为空值占位符
1653
+ */
1654
+ declare function isMergeEmptyPlaceholder(arg: any): arg is MergeEmptyPlaceholder;
1655
+
1656
+ /** `deepMerge` 深合并方法的配置参数 */
1657
+ type MergeOption = {
1658
+ /** 针对不同的类型设置不同的合并方法 */
1659
+ typeStrategy?: Partial<MergeTypeStrategy>;
1660
+ /** `deepMerge` 内部使用 `deepClone` 拷贝对象之类的值 */
1661
+ cloneOptions?: CloneOptions;
1662
+ };
1663
+
1664
+ /**
1665
+ * 深合并, 作为基底的对象称为目标对象(target), 往之合并内容的对象称为来源对象(source)
1666
+ * - 不能处理循环引用等特殊场景
1667
+ * - 满足基本的合并功能, 以下行为是其默认行为
1668
+ * - 普通对象、FormData 这类对象会递归合并
1669
+ * - 数组会以拼接的方式合并
1670
+ * - `{ a: [1, 2] }` 和 `{ a: [3, 4] }` 会合并为 `{ a: [1, 2, 3, 4] }`
1671
+ * - Set、Map 会直接合并, 其中 Map 合并时来源对象会覆盖目标对象相同 Key 的值
1672
+ * - Set 和 Map 视为不同类型, 会用来源对象的值覆盖
1673
+ * - Set 和数组会互相合并
1674
+ * - `{ a: [1, 2] }` 和 `{ a: Set([3, 4]) }` 会合并为 `{ a: [1, 2, 3, 4] }`
1675
+ * - `{ a: Set([1, 2]) }` 和 `{ a: [3, 4] }` 会合并为 `{ a: Set([1, 2, 3, 4]) }`
1676
+ * - 来源对象的基本类型值不会覆盖对象
1677
+ * - 来源对象的空值(null、undefined)不会覆盖其他类型的值
1678
+ * - 来源对象的非空值会覆盖目标对象的空值(目标对象不存在某个键时也视为空值)
1679
+ * - 其他情况: 不同类型、原始类型、其他不能合并/拼接的值会以来源对象的为准作覆盖
1680
+ * - 可以根据类型配置不同的策略, 策略可以是 `"keep"` `"override"` 或者一个方法
1681
+ * - `"keep"` 保留目标对象的值
1682
+ * - `"override"` 保留来源对象的值
1683
+ * - 传入方法:
1684
+ * - 类型 `(param: { target: any; source: any; path: (string | symbol)[]; unhandledValue: any; map: Map<any, any> }) => any`
1685
+ * - `target` 当前目标对象上这个位置的值
1686
+ * - `source` 当前来源对象上这个位置的值
1687
+ * - `path` 当前处理的值在对象上的位置
1688
+ * - `map` 用于处理循环引用等情况的 Map 对象
1689
+ * - `unhandledValue` 将这个值返回, 可以跳过处理, 交给兜底逻辑
1690
+ * - 返回值: 合并后的对象
1691
+ * - 合并类型: 一个字符串 `${来源对象值类型}2${目标对象值类型}`, 常见类型见下
1692
+ * - 基本类型 `"Number"` `"String"` `"Boolean"` `"Symbol"` `"BigInt"` `"Null"` `"Undefined"`
1693
+ * - 常见对象 `"Object"` `"Array"` `"Set"` `"Map"` `"FormData"` `"Date"` `"RegExp"` `"Promise"`
1694
+ * - 函数 `"Function"`
1695
+ * - 这些均视为函数 `"AsyncFunction"` `"GeneratorFunction"`, 不能拿来用
1696
+ * - 生成器函数运行后得到生成器 `"Generator"`
1697
+ * - 迭代器 `"Iterator"`
1698
+ * - 这些均视为迭代器, 不能拿来用
1699
+ * - `"String Iterator"` `"Array Iterator"` `"RegExp String Iterator"`
1700
+ * - `"Map Iterator"` `"Set Iterator"` `"Segmenter String Iterator"`
1701
+ * - `"Iterator Helper"`
1702
+ * - 二进制流&文件 `"ArrayBuffer"` `"Buffer"` `"DataView"` `"Blob"` `"File"`
1703
+ * - 类型数组 `"TypedArray"`
1704
+ * - 这些均视为类型数组, 不能拿来用
1705
+ * - `"Int8Array"` `"Int16Array"` `"Int32Array"`
1706
+ * - `"Uint8Array"` `"Uint8ClampedArray"` `"Uint16Array"` `"Uint32Array"`
1707
+ * - `"Float32Array"` `"Float64Array"`
1708
+ * - `"BigInt64Array"` `"BigUint64Array"`
1709
+ * - 弱引用 `"WeakSet"` `"WeakMap"` `"WeakRef"`
1710
+ * - 报错信息 `"Error"`
1711
+ * - 任意类型的错误视为报错信息
1712
+ * - 其他类型 `"Any"` 表示所有类型(用于兜底), 空类型 `"Empty"` 表示目标对象上没有这个键
1713
+ * - `"Empty"` 不会出现在来源对象上, 因此只会有 `"Any2Empty"`, 而不会有 `"Empty2Any"`
1714
+ * - 策略优先级是:
1715
+ * - 精确指定优先级最高: 如 `"Object2Object"` 优先于 `"Object2Any"`
1716
+ * - 来源对象精确指定优先级高: 如 `"Object2Any"` 优先于 `"Any2Object"`
1717
+ * - 空类型 `"Empty"` 视为精确指定
1718
+ * @param target 目标对象
1719
+ * @param source 来源对象, 往目标对象合并内容
1720
+ * @param option 配置
1721
+ * - `option.typeStrategy`: 针对不同的类型设置不同的合并方法
1722
+ * - `option.cloneOptions`: `deepMerge` 内部使用 `deepClone` 拷贝对象之类的值
1723
+ * @example
1724
+ * ```js
1725
+ * const obj1 = { arr: [1, 2], obj: { a: [1], b: { c: 2 } }, p: '1' }
1726
+ * const obj2 = { arr: [3], obj: { a: [2], b: { c: 4, d: 3 } }, p: '2' }
1727
+ * const obj3 = deepMerge(obj1, obj2)
1728
+ * obj3 // { arr: [1, 2, 3], obj: { a: [1, 2], b: { c: 4, d: 3 } }, p: '2' }
1729
+ * ```
1730
+ * @version 0.3.0
1731
+ */
1732
+ declare function deepMerge<Target, Source, Result = Target & Source>(target: Target, source: Source, option?: MergeOption): Result;
1733
+
1493
1734
  /**
1494
1735
  * 快速深拷贝
1495
1736
  * - 功能较为齐全, 相对 `deepClone` 而言运行更快
@@ -1549,7 +1790,15 @@ declare function isEmpty(value: unknown): boolean;
1549
1790
  * - `getKey` 自定义 key 的生成规则, 默认使用内部方法生成 key
1550
1791
  * - `ttl` 缓存的过期时间, 单位毫秒, 为 0 表示不过期, 默认不过期
1551
1792
  * - `count` 缓存最大使用次数, 为 0 表示不限次数, 默认不限次数
1552
- * @returns
1793
+ * @returns 记忆化的函数, 输入相同参数再次调用时会直接返回之前的结果而不会调用原函数
1794
+ * @example
1795
+ * ```js
1796
+ * // 计算斐波那契数列
1797
+ * const fib = memo(function (n) {
1798
+ * if (n < 2) return n
1799
+ * return fib(n - 1) + fib(n - 2)
1800
+ * })
1801
+ * ```
1553
1802
  */
1554
1803
  declare function memo<TArgs extends any[], TRes>(fn: (...args: TArgs) => TRes, options?: {
1555
1804
  getKey?: (...args: TArgs) => string | number;
@@ -1737,4 +1986,5 @@ declare function throttle<T extends any[]>(fn: (...args: T) => any, delay: numbe
1737
1986
  reset: () => void;
1738
1987
  };
1739
1988
 
1740
- export { type CloneOptions, type CustomCloner, type RangeOptions, type TypedArray, _, acceptableFileName, acceptableFileType, camelCase, caseCamel, caseConvert, caseKebab, casePascal, caseSnake, clamp, compose, _curryMore as curry, debounce, deepClone, defer, fastClone, getAcceptableExtByMIME, getAcceptableMIMEByExt, getGlobalThis, getTag, isArray, isArrayBuffer, isArrayLike, isBigInt, isBigInt64Array, isBigUint64Array, isBoolean, isBuffer, isDataView, isDate, isEmpty, isFile, isFloat32Array, isFloat64Array, isFormData, isFunction, isInt16Array, isInt32Array, isInt8Array, isInteger, isIterable, isMap, isNil, isNull, isNumber, isObject, isPlaceholder, isPrimitive, isPromise, isPromiseLike, isRegExp, isSet, isString, isSymbol, isTypedArray, isUint16Array, isUint32Array, isUint8Array, isUint8ClampedArray, isUndefined, isWeakMap, isWeakSet, isWrapperBigInt, isWrapperBoolean, isWrapperNumber, isWrapperObject, isWrapperString, isWrapperSymbol, kebabCase, memo, noop, not, parallel, pascalCase, pass, passWith, pipe, randomBase32String, randomChoice, randomHexString, randomInt, randomIntFloor, randomString, range, remove, retry, shuffle, sleep, snakeCase, splitWords, throttle, titleCase, tryit, ulid, uuidNil, uuidV4, withResolvers };
1989
+ export { $$Empty, _, acceptableFileName, acceptableFileType, camelCase, capitalize, caseCamel, caseConvert, caseKebab, casePascal, caseSnake, clamp, compose, _curryMore as curry, debounce, dedent, deepClone, deepMerge, defer, fastClone, getAcceptableExtByMIME, getAcceptableMIMEByExt, getGlobalThis, getTag, indent, isArray, isArrayBuffer, isArrayLike, isBigInt, isBigInt64Array, isBigUint64Array, isBlob, isBoolean, isBuffer, isDataView, isDate, isEmpty, isFile, isFloat32Array, isFloat64Array, isFormData, isFunction, isInt16Array, isInt32Array, isInt8Array, isInteger, isIterable, isMap, isMergeEmptyPlaceholder, isNil, isNull, isNumber, isObject, isPlaceholder, isPrimitive, isPromise, isPromiseLike, isRegExp, isSet, isString, isSymbol, isTypedArray, isUint16Array, isUint32Array, isUint8Array, isUint8ClampedArray, isUndefined, isWeakMap, isWeakSet, isWrapperBigInt, isWrapperBoolean, isWrapperNumber, isWrapperObject, isWrapperString, isWrapperSymbol, kebabCase, memo, noop, not, parallel, pascalCase, pass, passWith, pipe, randomBase32String, randomChoice, randomHexString, randomInt, randomIntFloor, randomString, range, remove, retry, shuffle, sleep, snakeCase, splitWords, throttle, titleCase, tryit, ulid, uncapitalize, uuidNil, uuidV4, withResolvers };
1990
+ export type { BaseMargeType, CloneOptions, CustomCloner, MergeOption, MergeStrategy, MergeStrategyFunction, MergeType, MergeTypeStrategy, RangeOptions, SourceMergeType, TargetMergeType, TypedArray };