a-js-tools 1.0.5 → 2.0.0-alpha.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.
- package/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/array/difference.cjs +2 -2
- package/src/array/difference.mjs +2 -2
- package/src/array/intersection.cjs +1 -1
- package/src/array/intersection.mjs +1 -1
- package/src/array/symmetricDifference.cjs +6 -3
- package/src/array/symmetricDifference.mjs +6 -3
- package/src/array/union.cjs +8 -4
- package/src/array/union.mjs +8 -4
- package/src/className.cjs +3 -3
- package/src/className.mjs +3 -3
- package/src/getRandomString.cjs +17 -9
- package/src/getRandomString.mjs +17 -9
- package/src/performance.cjs +34 -28
- package/src/performance.d.ts +11 -9
- package/src/performance.mjs +35 -29
- package/src/regexp/autoEscapedRegExp.cjs +4 -2
- package/src/regexp/autoEscapedRegExp.mjs +4 -2
- package/src/regexp/parse.cjs +6 -3
- package/src/regexp/parse.mjs +6 -3
package/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CreateConstructor, createConstructor } from 'src/object/createConstructor';
|
|
2
2
|
export { toLowerCamelCase, toSplitCase, getRandomFloat, getRandomInt, getRandomString, } from './src/index';
|
|
3
3
|
export { throttle, debounce } from './src/performance';
|
|
4
|
-
export type { DebounceAndThrottleReturnType } from './src/performance';
|
|
4
|
+
export type { DebounceAndThrottleReturnType, debounce_throttle_options, } from './src/performance';
|
|
5
5
|
export { escapeRegExp, autoEscapedRegExp } from './src/regexp';
|
|
6
6
|
export { isBrowser, isNode } from './src/isNode';
|
|
7
7
|
export { intersection, enArr, union, difference, symmetricDifference, } from './src/array/';
|
package/package.json
CHANGED
package/src/array/difference.cjs
CHANGED
|
@@ -34,9 +34,9 @@ var aTypeOfJs = require('a-type-of-js');
|
|
|
34
34
|
*
|
|
35
35
|
*/
|
|
36
36
|
function difference(a, b) {
|
|
37
|
-
if (
|
|
37
|
+
if ([a, b].some(e => !aTypeOfJs.isArray(e)))
|
|
38
38
|
throw new TypeError('参数需为数组');
|
|
39
|
-
if (
|
|
39
|
+
if ([a, b].some(e => aTypeOfJs.isEmptyArray(e)))
|
|
40
40
|
return a;
|
|
41
41
|
/** 获取两个数组中长度较小的 */
|
|
42
42
|
// 参数有顺序要求
|
package/src/array/difference.mjs
CHANGED
|
@@ -32,9 +32,9 @@ import { isArray, isEmptyArray } from 'a-type-of-js';
|
|
|
32
32
|
*
|
|
33
33
|
*/
|
|
34
34
|
function difference(a, b) {
|
|
35
|
-
if (
|
|
35
|
+
if ([a, b].some(e => !isArray(e)))
|
|
36
36
|
throw new TypeError('参数需为数组');
|
|
37
|
-
if (
|
|
37
|
+
if ([a, b].some(e => isEmptyArray(e)))
|
|
38
38
|
return a;
|
|
39
39
|
/** 获取两个数组中长度较小的 */
|
|
40
40
|
// 参数有顺序要求
|
|
@@ -27,7 +27,7 @@ function intersection(a, b) {
|
|
|
27
27
|
if (!aTypeOfJs.isArray(a) || !aTypeOfJs.isArray(b))
|
|
28
28
|
throw new TypeError('参数必须是数组类型数据');
|
|
29
29
|
// 任意数组为空,则返回空数组
|
|
30
|
-
if (
|
|
30
|
+
if ([a, b].some(e => aTypeOfJs.isEmptyArray(e)))
|
|
31
31
|
return [];
|
|
32
32
|
/**
|
|
33
33
|
* 在实际运算中, new Set() 的 开销为 O(n) ,filter 的开销也为 O(n)
|
|
@@ -25,7 +25,7 @@ function intersection(a, b) {
|
|
|
25
25
|
if (!isArray(a) || !isArray(b))
|
|
26
26
|
throw new TypeError('参数必须是数组类型数据');
|
|
27
27
|
// 任意数组为空,则返回空数组
|
|
28
|
-
if (
|
|
28
|
+
if ([a, b].some(e => isEmptyArray(e)))
|
|
29
29
|
return [];
|
|
30
30
|
/**
|
|
31
31
|
* 在实际运算中, new Set() 的 开销为 O(n) ,filter 的开销也为 O(n)
|
|
@@ -36,12 +36,15 @@ var difference = require('./difference.cjs');
|
|
|
36
36
|
*
|
|
37
37
|
*/
|
|
38
38
|
function symmetricDifference(a, b) {
|
|
39
|
-
if (!aTypeOfJs.isArray(a) || !aTypeOfJs.isArray(b))
|
|
39
|
+
if (!aTypeOfJs.isArray(a) || !aTypeOfJs.isArray(b)) {
|
|
40
40
|
throw new TypeError('参数必须是数组');
|
|
41
|
-
|
|
41
|
+
}
|
|
42
|
+
if (aTypeOfJs.isEmptyArray(a)) {
|
|
42
43
|
return [...b];
|
|
43
|
-
|
|
44
|
+
}
|
|
45
|
+
if (aTypeOfJs.isEmptyArray(b)) {
|
|
44
46
|
return [...a];
|
|
47
|
+
}
|
|
45
48
|
return [...difference.difference(a, b), ...difference.difference(b, a)];
|
|
46
49
|
}
|
|
47
50
|
|
|
@@ -34,12 +34,15 @@ import { difference } from './difference.mjs';
|
|
|
34
34
|
*
|
|
35
35
|
*/
|
|
36
36
|
function symmetricDifference(a, b) {
|
|
37
|
-
if (!isArray(a) || !isArray(b))
|
|
37
|
+
if (!isArray(a) || !isArray(b)) {
|
|
38
38
|
throw new TypeError('参数必须是数组');
|
|
39
|
-
|
|
39
|
+
}
|
|
40
|
+
if (isEmptyArray(a)) {
|
|
40
41
|
return [...b];
|
|
41
|
-
|
|
42
|
+
}
|
|
43
|
+
if (isEmptyArray(b)) {
|
|
42
44
|
return [...a];
|
|
45
|
+
}
|
|
43
46
|
return [...difference(a, b), ...difference(b, a)];
|
|
44
47
|
}
|
|
45
48
|
|
package/src/array/union.cjs
CHANGED
|
@@ -44,16 +44,20 @@ var aTypeOfJs = require('a-type-of-js');
|
|
|
44
44
|
*
|
|
45
45
|
*/
|
|
46
46
|
function union(...arrays) {
|
|
47
|
-
if (aTypeOfJs.isEmptyArray(arrays))
|
|
47
|
+
if (aTypeOfJs.isEmptyArray(arrays)) {
|
|
48
48
|
return [];
|
|
49
|
-
|
|
49
|
+
}
|
|
50
|
+
if (arrays.some(i => !aTypeOfJs.isArray(i))) {
|
|
50
51
|
throw new TypeError('参数必须都是数组形式的元素');
|
|
51
|
-
|
|
52
|
+
}
|
|
53
|
+
if (arrays.length === 1) {
|
|
52
54
|
return [...arrays[0]];
|
|
55
|
+
}
|
|
53
56
|
const resultSet = new Set();
|
|
54
57
|
for (const array of arrays) {
|
|
55
|
-
for (const item of array)
|
|
58
|
+
for (const item of array) {
|
|
56
59
|
resultSet.add(item);
|
|
60
|
+
}
|
|
57
61
|
}
|
|
58
62
|
return Array.from(resultSet);
|
|
59
63
|
}
|
package/src/array/union.mjs
CHANGED
|
@@ -42,16 +42,20 @@ import { isEmptyArray, isArray } from 'a-type-of-js';
|
|
|
42
42
|
*
|
|
43
43
|
*/
|
|
44
44
|
function union(...arrays) {
|
|
45
|
-
if (isEmptyArray(arrays))
|
|
45
|
+
if (isEmptyArray(arrays)) {
|
|
46
46
|
return [];
|
|
47
|
-
|
|
47
|
+
}
|
|
48
|
+
if (arrays.some(i => !isArray(i))) {
|
|
48
49
|
throw new TypeError('参数必须都是数组形式的元素');
|
|
49
|
-
|
|
50
|
+
}
|
|
51
|
+
if (arrays.length === 1) {
|
|
50
52
|
return [...arrays[0]];
|
|
53
|
+
}
|
|
51
54
|
const resultSet = new Set();
|
|
52
55
|
for (const array of arrays) {
|
|
53
|
-
for (const item of array)
|
|
56
|
+
for (const item of array) {
|
|
54
57
|
resultSet.add(item);
|
|
58
|
+
}
|
|
55
59
|
}
|
|
56
60
|
return Array.from(resultSet);
|
|
57
61
|
}
|
package/src/className.cjs
CHANGED
|
@@ -34,9 +34,9 @@ initial = false) {
|
|
|
34
34
|
/** 转化首字符 */
|
|
35
35
|
const toTransform = (_str, _dividingType) => _str.replace(new RegExp(`${template.test(_dividingType) ? `\\${_dividingType}` : _dividingType}([a-zA-Z])`, 'g'), (match, p1) => p1.toUpperCase());
|
|
36
36
|
// 多分隔符转化
|
|
37
|
-
dividingType
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
dividingType.split('').forEach((item) => {
|
|
38
|
+
result = toTransform(result, item);
|
|
39
|
+
});
|
|
40
40
|
return initial
|
|
41
41
|
? result.replace(/^./, (match) => match.toUpperCase())
|
|
42
42
|
: result;
|
package/src/className.mjs
CHANGED
|
@@ -32,9 +32,9 @@ initial = false) {
|
|
|
32
32
|
/** 转化首字符 */
|
|
33
33
|
const toTransform = (_str, _dividingType) => _str.replace(new RegExp(`${template.test(_dividingType) ? `\\${_dividingType}` : _dividingType}([a-zA-Z])`, 'g'), (match, p1) => p1.toUpperCase());
|
|
34
34
|
// 多分隔符转化
|
|
35
|
-
dividingType
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
dividingType.split('').forEach((item) => {
|
|
36
|
+
result = toTransform(result, item);
|
|
37
|
+
});
|
|
38
38
|
return initial
|
|
39
39
|
? result.replace(/^./, (match) => match.toUpperCase())
|
|
40
40
|
: result;
|
package/src/getRandomString.cjs
CHANGED
|
@@ -38,8 +38,9 @@ function getRandomString(options) {
|
|
|
38
38
|
(aTypeOfJs.isPlainObject(options) &&
|
|
39
39
|
(!aTypeOfJs.isNumber(options.length) ||
|
|
40
40
|
options.length < 1 ||
|
|
41
|
-
!Number.isInteger(options.length))))
|
|
41
|
+
!Number.isInteger(options.length)))) {
|
|
42
42
|
throw new TypeError('参数类型错误 ❌ (getRandomString)');
|
|
43
|
+
}
|
|
43
44
|
const initOptions = {
|
|
44
45
|
length: 32,
|
|
45
46
|
chars: 'abcdefghijklmnopqrstuvwxyz',
|
|
@@ -51,11 +52,13 @@ function getRandomString(options) {
|
|
|
51
52
|
includeSpecial: false,
|
|
52
53
|
};
|
|
53
54
|
/// 生成 UUID
|
|
54
|
-
if (initOptions.type === 'uuid')
|
|
55
|
+
if (initOptions.type === 'uuid') {
|
|
55
56
|
return crypto.randomUUID();
|
|
56
|
-
|
|
57
|
-
if (aTypeOfJs.isNumber(options) && Number.isInteger(options) && options > 0)
|
|
57
|
+
}
|
|
58
|
+
if (aTypeOfJs.isNumber(options) && Number.isInteger(options) && options > 0) {
|
|
59
|
+
// 验证输入参数
|
|
58
60
|
Object.assign(initOptions, { length: options });
|
|
61
|
+
}
|
|
59
62
|
if (aTypeOfJs.isPlainObject(options)) {
|
|
60
63
|
Object.assign(initOptions, options);
|
|
61
64
|
initOptions.length = initOptions.length < 1 ? 32 : initOptions.length;
|
|
@@ -63,14 +66,17 @@ function getRandomString(options) {
|
|
|
63
66
|
/** 生成随机字符串 */
|
|
64
67
|
const templateCharsArr = initOptions.chars.split('');
|
|
65
68
|
// 添加大写字母
|
|
66
|
-
if (initOptions.includeUppercaseLetters)
|
|
69
|
+
if (initOptions.includeUppercaseLetters) {
|
|
67
70
|
interleaveString(templateCharsArr, initOptions.chars.toUpperCase());
|
|
71
|
+
}
|
|
68
72
|
// 添加数字
|
|
69
|
-
if (initOptions.includeNumbers)
|
|
73
|
+
if (initOptions.includeNumbers) {
|
|
70
74
|
interleaveString(templateCharsArr, initOptions.chars2);
|
|
75
|
+
}
|
|
71
76
|
// 添加特殊字符
|
|
72
|
-
if (initOptions.includeSpecial)
|
|
77
|
+
if (initOptions.includeSpecial) {
|
|
73
78
|
interleaveString(templateCharsArr, initOptions.chars3);
|
|
79
|
+
}
|
|
74
80
|
// 使用密码学安全的随机数生成器
|
|
75
81
|
const bytes = isNode.isBrowser() && window.crypto
|
|
76
82
|
? window.crypto.getRandomValues(new Uint8Array(initOptions.length))
|
|
@@ -98,10 +104,12 @@ function getRandomString(options) {
|
|
|
98
104
|
const str1Length = str1.length, str2Length = str2.length;
|
|
99
105
|
const maxLength = Math.max(str1Length, str2Length);
|
|
100
106
|
for (let i = 0; i < maxLength; i++) {
|
|
101
|
-
if (i < str1Length && !aTypeOfJs.isUndefined(str2[i]))
|
|
107
|
+
if (i < str1Length && !aTypeOfJs.isUndefined(str2[i])) {
|
|
102
108
|
str1[i] += str2[i];
|
|
103
|
-
|
|
109
|
+
}
|
|
110
|
+
else if (i < str2Length) {
|
|
104
111
|
str1[i] = str2[i];
|
|
112
|
+
}
|
|
105
113
|
}
|
|
106
114
|
}
|
|
107
115
|
return result;
|
package/src/getRandomString.mjs
CHANGED
|
@@ -36,8 +36,9 @@ function getRandomString(options) {
|
|
|
36
36
|
(isPlainObject(options) &&
|
|
37
37
|
(!isNumber(options.length) ||
|
|
38
38
|
options.length < 1 ||
|
|
39
|
-
!Number.isInteger(options.length))))
|
|
39
|
+
!Number.isInteger(options.length)))) {
|
|
40
40
|
throw new TypeError('参数类型错误 ❌ (getRandomString)');
|
|
41
|
+
}
|
|
41
42
|
const initOptions = {
|
|
42
43
|
length: 32,
|
|
43
44
|
chars: 'abcdefghijklmnopqrstuvwxyz',
|
|
@@ -49,11 +50,13 @@ function getRandomString(options) {
|
|
|
49
50
|
includeSpecial: false,
|
|
50
51
|
};
|
|
51
52
|
/// 生成 UUID
|
|
52
|
-
if (initOptions.type === 'uuid')
|
|
53
|
+
if (initOptions.type === 'uuid') {
|
|
53
54
|
return crypto.randomUUID();
|
|
54
|
-
|
|
55
|
-
if (isNumber(options) && Number.isInteger(options) && options > 0)
|
|
55
|
+
}
|
|
56
|
+
if (isNumber(options) && Number.isInteger(options) && options > 0) {
|
|
57
|
+
// 验证输入参数
|
|
56
58
|
Object.assign(initOptions, { length: options });
|
|
59
|
+
}
|
|
57
60
|
if (isPlainObject(options)) {
|
|
58
61
|
Object.assign(initOptions, options);
|
|
59
62
|
initOptions.length = initOptions.length < 1 ? 32 : initOptions.length;
|
|
@@ -61,14 +64,17 @@ function getRandomString(options) {
|
|
|
61
64
|
/** 生成随机字符串 */
|
|
62
65
|
const templateCharsArr = initOptions.chars.split('');
|
|
63
66
|
// 添加大写字母
|
|
64
|
-
if (initOptions.includeUppercaseLetters)
|
|
67
|
+
if (initOptions.includeUppercaseLetters) {
|
|
65
68
|
interleaveString(templateCharsArr, initOptions.chars.toUpperCase());
|
|
69
|
+
}
|
|
66
70
|
// 添加数字
|
|
67
|
-
if (initOptions.includeNumbers)
|
|
71
|
+
if (initOptions.includeNumbers) {
|
|
68
72
|
interleaveString(templateCharsArr, initOptions.chars2);
|
|
73
|
+
}
|
|
69
74
|
// 添加特殊字符
|
|
70
|
-
if (initOptions.includeSpecial)
|
|
75
|
+
if (initOptions.includeSpecial) {
|
|
71
76
|
interleaveString(templateCharsArr, initOptions.chars3);
|
|
77
|
+
}
|
|
72
78
|
// 使用密码学安全的随机数生成器
|
|
73
79
|
const bytes = isBrowser() && window.crypto
|
|
74
80
|
? window.crypto.getRandomValues(new Uint8Array(initOptions.length))
|
|
@@ -96,10 +102,12 @@ function getRandomString(options) {
|
|
|
96
102
|
const str1Length = str1.length, str2Length = str2.length;
|
|
97
103
|
const maxLength = Math.max(str1Length, str2Length);
|
|
98
104
|
for (let i = 0; i < maxLength; i++) {
|
|
99
|
-
if (i < str1Length && !isUndefined(str2[i]))
|
|
105
|
+
if (i < str1Length && !isUndefined(str2[i])) {
|
|
100
106
|
str1[i] += str2[i];
|
|
101
|
-
|
|
107
|
+
}
|
|
108
|
+
else if (i < str2Length) {
|
|
102
109
|
str1[i] = str2[i];
|
|
110
|
+
}
|
|
103
111
|
}
|
|
104
112
|
}
|
|
105
113
|
return result;
|
package/src/performance.cjs
CHANGED
|
@@ -13,8 +13,7 @@ var aTypeOfJs = require('a-type-of-js');
|
|
|
13
13
|
*
|
|
14
14
|
* 防抖
|
|
15
15
|
*
|
|
16
|
-
* @param
|
|
17
|
-
* @param options 延迟时间(毫秒),默认 200 (ms) 或包含 this 的配置
|
|
16
|
+
* @param options 使用参数
|
|
18
17
|
* @returns 返回的闭包函数
|
|
19
18
|
* @example
|
|
20
19
|
*
|
|
@@ -27,17 +26,19 @@ var aTypeOfJs = require('a-type-of-js');
|
|
|
27
26
|
* }
|
|
28
27
|
*
|
|
29
28
|
*/
|
|
30
|
-
function debounce(
|
|
31
|
-
if (
|
|
32
|
-
throw new TypeError('callback must be a function');
|
|
33
|
-
if (aTypeOfJs.isNumber(options))
|
|
29
|
+
function debounce(options) {
|
|
30
|
+
if (aTypeOfJs.isFunction(options)) {
|
|
34
31
|
options = {
|
|
35
|
-
|
|
32
|
+
callback: options,
|
|
33
|
+
delay: 200,
|
|
36
34
|
this: null,
|
|
37
35
|
};
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
}
|
|
37
|
+
if (!aTypeOfJs.isPlainObject(options) || !aTypeOfJs.isFunction(options.callback))
|
|
38
|
+
throw new TypeError('参数类型有误');
|
|
39
|
+
if (aTypeOfJs.isUndefined(options.delay))
|
|
40
|
+
options.delay = 200;
|
|
41
|
+
if (!isFinite(options.delay) || options.delay < 0)
|
|
41
42
|
// 强制转换非数值
|
|
42
43
|
options.delay = 200;
|
|
43
44
|
/** 定时器返回的 id */
|
|
@@ -52,34 +53,37 @@ function debounce(callback, options = 200) {
|
|
|
52
53
|
clear();
|
|
53
54
|
timeoutId = setTimeout(() => {
|
|
54
55
|
try {
|
|
55
|
-
Reflect.apply(callback, options
|
|
56
|
+
Reflect.apply(options.callback, options.this ?? null, args);
|
|
56
57
|
}
|
|
57
58
|
catch (error) {
|
|
58
59
|
console.log('Debounce callback throw an error', error);
|
|
59
60
|
}
|
|
60
|
-
}, Math.max(options
|
|
61
|
+
}, Math.max(options.delay ?? 5, 5));
|
|
62
|
+
};
|
|
63
|
+
result.cancel = () => {
|
|
64
|
+
clear();
|
|
61
65
|
};
|
|
62
|
-
result.cancel = () => clear();
|
|
63
66
|
return result;
|
|
64
67
|
}
|
|
65
68
|
/**
|
|
66
69
|
* 节流
|
|
67
70
|
*
|
|
68
|
-
* @param
|
|
69
|
-
* @param options 延迟时间(毫秒),默认 200 (ms) 或设置 this
|
|
71
|
+
* @param options 使用的参数值
|
|
70
72
|
* @returns 返回的闭包函数
|
|
71
73
|
*/
|
|
72
|
-
function throttle(
|
|
73
|
-
if (
|
|
74
|
-
throw new TypeError('callback must be a function');
|
|
75
|
-
if (aTypeOfJs.isNumber(options))
|
|
74
|
+
function throttle(options) {
|
|
75
|
+
if (aTypeOfJs.isFunction(options)) {
|
|
76
76
|
options = {
|
|
77
|
-
|
|
77
|
+
callback: options,
|
|
78
|
+
delay: 200,
|
|
78
79
|
this: null,
|
|
79
80
|
};
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
}
|
|
82
|
+
if (!aTypeOfJs.isPlainObject(options) || !aTypeOfJs.isFunction(options.callback))
|
|
83
|
+
throw new TypeError('参数类型有误');
|
|
84
|
+
if (aTypeOfJs.isUndefined(options.delay))
|
|
85
|
+
options.delay = 200;
|
|
86
|
+
if (!isFinite(options.delay) || options.delay < 0)
|
|
83
87
|
// 强制转换非数值
|
|
84
88
|
options.delay = 200;
|
|
85
89
|
/** 延迟控制插销 */
|
|
@@ -90,22 +94,24 @@ function throttle(callback, options = 200) {
|
|
|
90
94
|
if (inThrottle)
|
|
91
95
|
return;
|
|
92
96
|
try {
|
|
93
|
-
Reflect.apply(callback, options
|
|
97
|
+
Reflect.apply(options.callback, options.this ?? null, args);
|
|
94
98
|
}
|
|
95
99
|
catch (error) {
|
|
96
|
-
console.error('Throttle
|
|
100
|
+
console.error('Throttle callback throw an error', error);
|
|
97
101
|
}
|
|
98
102
|
inThrottle = true;
|
|
99
|
-
if (!aTypeOfJs.isNull(timeoutId))
|
|
103
|
+
if (!aTypeOfJs.isNull(timeoutId)) {
|
|
100
104
|
clearTimeout(timeoutId);
|
|
105
|
+
}
|
|
101
106
|
timeoutId = setTimeout(() => {
|
|
102
107
|
inThrottle = false;
|
|
103
108
|
timeoutId = null;
|
|
104
|
-
}, Math.max(options
|
|
109
|
+
}, Math.max(options.delay ?? 5, 5));
|
|
105
110
|
};
|
|
106
111
|
throttled.cancel = () => {
|
|
107
|
-
if (!aTypeOfJs.isNull(timeoutId))
|
|
112
|
+
if (!aTypeOfJs.isNull(timeoutId)) {
|
|
108
113
|
clearTimeout(timeoutId);
|
|
114
|
+
}
|
|
109
115
|
inThrottle = false;
|
|
110
116
|
timeoutId = null;
|
|
111
117
|
};
|
package/src/performance.d.ts
CHANGED
|
@@ -15,17 +15,20 @@ export interface DebounceAndThrottleReturnType<F extends Callback> {
|
|
|
15
15
|
(...args: Parameters<F>): void;
|
|
16
16
|
cancel(): void;
|
|
17
17
|
}
|
|
18
|
-
/**
|
|
19
|
-
export type debounce_throttle_options = {
|
|
18
|
+
/** 参数类型 */
|
|
19
|
+
export type debounce_throttle_options<T extends (...args: unknown[]) => void> = T | {
|
|
20
|
+
/** 回调函数 */
|
|
21
|
+
callback: T;
|
|
22
|
+
/** 使用的延迟时间,缺省值为 200ms */
|
|
20
23
|
delay?: number;
|
|
24
|
+
/** 使用的 this */
|
|
21
25
|
this?: null | unknown;
|
|
22
|
-
}
|
|
26
|
+
};
|
|
23
27
|
/**
|
|
24
28
|
*
|
|
25
29
|
* 防抖
|
|
26
30
|
*
|
|
27
|
-
* @param
|
|
28
|
-
* @param options 延迟时间(毫秒),默认 200 (ms) 或包含 this 的配置
|
|
31
|
+
* @param options 使用参数
|
|
29
32
|
* @returns 返回的闭包函数
|
|
30
33
|
* @example
|
|
31
34
|
*
|
|
@@ -38,13 +41,12 @@ export type debounce_throttle_options = {
|
|
|
38
41
|
* }
|
|
39
42
|
*
|
|
40
43
|
*/
|
|
41
|
-
export declare function debounce<F extends (...args: unknown[]) => void>(
|
|
44
|
+
export declare function debounce<F extends (...args: unknown[]) => void>(options: debounce_throttle_options<F>): DebounceAndThrottleReturnType<F>;
|
|
42
45
|
/**
|
|
43
46
|
* 节流
|
|
44
47
|
*
|
|
45
|
-
* @param
|
|
46
|
-
* @param options 延迟时间(毫秒),默认 200 (ms) 或设置 this
|
|
48
|
+
* @param options 使用的参数值
|
|
47
49
|
* @returns 返回的闭包函数
|
|
48
50
|
*/
|
|
49
|
-
export declare function throttle<F extends (...args: unknown[]) => void>(
|
|
51
|
+
export declare function throttle<F extends (...args: unknown[]) => void>(options: debounce_throttle_options<F>): DebounceAndThrottleReturnType<F>;
|
|
50
52
|
export {};
|
package/src/performance.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isFunction,
|
|
1
|
+
import { isFunction, isPlainObject, isUndefined, isNull } from 'a-type-of-js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 防抖和节流
|
|
@@ -11,8 +11,7 @@ import { isFunction, isNumber, isUndefined, isNull } from 'a-type-of-js';
|
|
|
11
11
|
*
|
|
12
12
|
* 防抖
|
|
13
13
|
*
|
|
14
|
-
* @param
|
|
15
|
-
* @param options 延迟时间(毫秒),默认 200 (ms) 或包含 this 的配置
|
|
14
|
+
* @param options 使用参数
|
|
16
15
|
* @returns 返回的闭包函数
|
|
17
16
|
* @example
|
|
18
17
|
*
|
|
@@ -25,17 +24,19 @@ import { isFunction, isNumber, isUndefined, isNull } from 'a-type-of-js';
|
|
|
25
24
|
* }
|
|
26
25
|
*
|
|
27
26
|
*/
|
|
28
|
-
function debounce(
|
|
29
|
-
if (
|
|
30
|
-
throw new TypeError('callback must be a function');
|
|
31
|
-
if (isNumber(options))
|
|
27
|
+
function debounce(options) {
|
|
28
|
+
if (isFunction(options)) {
|
|
32
29
|
options = {
|
|
33
|
-
|
|
30
|
+
callback: options,
|
|
31
|
+
delay: 200,
|
|
34
32
|
this: null,
|
|
35
33
|
};
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
}
|
|
35
|
+
if (!isPlainObject(options) || !isFunction(options.callback))
|
|
36
|
+
throw new TypeError('参数类型有误');
|
|
37
|
+
if (isUndefined(options.delay))
|
|
38
|
+
options.delay = 200;
|
|
39
|
+
if (!isFinite(options.delay) || options.delay < 0)
|
|
39
40
|
// 强制转换非数值
|
|
40
41
|
options.delay = 200;
|
|
41
42
|
/** 定时器返回的 id */
|
|
@@ -50,34 +51,37 @@ function debounce(callback, options = 200) {
|
|
|
50
51
|
clear();
|
|
51
52
|
timeoutId = setTimeout(() => {
|
|
52
53
|
try {
|
|
53
|
-
Reflect.apply(callback, options
|
|
54
|
+
Reflect.apply(options.callback, options.this ?? null, args);
|
|
54
55
|
}
|
|
55
56
|
catch (error) {
|
|
56
57
|
console.log('Debounce callback throw an error', error);
|
|
57
58
|
}
|
|
58
|
-
}, Math.max(options
|
|
59
|
+
}, Math.max(options.delay ?? 5, 5));
|
|
60
|
+
};
|
|
61
|
+
result.cancel = () => {
|
|
62
|
+
clear();
|
|
59
63
|
};
|
|
60
|
-
result.cancel = () => clear();
|
|
61
64
|
return result;
|
|
62
65
|
}
|
|
63
66
|
/**
|
|
64
67
|
* 节流
|
|
65
68
|
*
|
|
66
|
-
* @param
|
|
67
|
-
* @param options 延迟时间(毫秒),默认 200 (ms) 或设置 this
|
|
69
|
+
* @param options 使用的参数值
|
|
68
70
|
* @returns 返回的闭包函数
|
|
69
71
|
*/
|
|
70
|
-
function throttle(
|
|
71
|
-
if (
|
|
72
|
-
throw new TypeError('callback must be a function');
|
|
73
|
-
if (isNumber(options))
|
|
72
|
+
function throttle(options) {
|
|
73
|
+
if (isFunction(options)) {
|
|
74
74
|
options = {
|
|
75
|
-
|
|
75
|
+
callback: options,
|
|
76
|
+
delay: 200,
|
|
76
77
|
this: null,
|
|
77
78
|
};
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
}
|
|
80
|
+
if (!isPlainObject(options) || !isFunction(options.callback))
|
|
81
|
+
throw new TypeError('参数类型有误');
|
|
82
|
+
if (isUndefined(options.delay))
|
|
83
|
+
options.delay = 200;
|
|
84
|
+
if (!isFinite(options.delay) || options.delay < 0)
|
|
81
85
|
// 强制转换非数值
|
|
82
86
|
options.delay = 200;
|
|
83
87
|
/** 延迟控制插销 */
|
|
@@ -88,22 +92,24 @@ function throttle(callback, options = 200) {
|
|
|
88
92
|
if (inThrottle)
|
|
89
93
|
return;
|
|
90
94
|
try {
|
|
91
|
-
Reflect.apply(callback, options
|
|
95
|
+
Reflect.apply(options.callback, options.this ?? null, args);
|
|
92
96
|
}
|
|
93
97
|
catch (error) {
|
|
94
|
-
console.error('Throttle
|
|
98
|
+
console.error('Throttle callback throw an error', error);
|
|
95
99
|
}
|
|
96
100
|
inThrottle = true;
|
|
97
|
-
if (!isNull(timeoutId))
|
|
101
|
+
if (!isNull(timeoutId)) {
|
|
98
102
|
clearTimeout(timeoutId);
|
|
103
|
+
}
|
|
99
104
|
timeoutId = setTimeout(() => {
|
|
100
105
|
inThrottle = false;
|
|
101
106
|
timeoutId = null;
|
|
102
|
-
}, Math.max(options
|
|
107
|
+
}, Math.max(options.delay ?? 5, 5));
|
|
103
108
|
};
|
|
104
109
|
throttled.cancel = () => {
|
|
105
|
-
if (!isNull(timeoutId))
|
|
110
|
+
if (!isNull(timeoutId)) {
|
|
106
111
|
clearTimeout(timeoutId);
|
|
112
|
+
}
|
|
107
113
|
inThrottle = false;
|
|
108
114
|
timeoutId = null;
|
|
109
115
|
};
|
|
@@ -35,12 +35,14 @@ var parse = require('./parse.cjs');
|
|
|
35
35
|
*
|
|
36
36
|
*/
|
|
37
37
|
function autoEscapedRegExp(pattern, options) {
|
|
38
|
-
if (!aTypeOfJs.isString(pattern))
|
|
38
|
+
if (!aTypeOfJs.isString(pattern)) {
|
|
39
39
|
throw new TypeError('pattern must be a 字符串');
|
|
40
|
+
}
|
|
40
41
|
pattern = escapeRegExp.escapeRegExp(pattern);
|
|
41
42
|
/** 简单转化 */
|
|
42
|
-
if (aTypeOfJs.isUndefined(options))
|
|
43
|
+
if (aTypeOfJs.isUndefined(options)) {
|
|
43
44
|
return new RegExp(pattern);
|
|
45
|
+
}
|
|
44
46
|
options = parse.parse(options);
|
|
45
47
|
return new RegExp(`${options.start ? '^' : ''}${pattern}${options.end ? '$' : ''}`, options.flags);
|
|
46
48
|
}
|
|
@@ -33,12 +33,14 @@ import { parse } from './parse.mjs';
|
|
|
33
33
|
*
|
|
34
34
|
*/
|
|
35
35
|
function autoEscapedRegExp(pattern, options) {
|
|
36
|
-
if (!isString(pattern))
|
|
36
|
+
if (!isString(pattern)) {
|
|
37
37
|
throw new TypeError('pattern must be a 字符串');
|
|
38
|
+
}
|
|
38
39
|
pattern = escapeRegExp(pattern);
|
|
39
40
|
/** 简单转化 */
|
|
40
|
-
if (isUndefined(options))
|
|
41
|
+
if (isUndefined(options)) {
|
|
41
42
|
return new RegExp(pattern);
|
|
43
|
+
}
|
|
42
44
|
options = parse(options);
|
|
43
45
|
return new RegExp(`${options.start ? '^' : ''}${pattern}${options.end ? '$' : ''}`, options.flags);
|
|
44
46
|
}
|
package/src/regexp/parse.cjs
CHANGED
|
@@ -15,16 +15,19 @@ function parse(options) {
|
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
// 处理 flags
|
|
18
|
-
if (!aTypeOfJs.isString(options.flags))
|
|
18
|
+
if (!aTypeOfJs.isString(options.flags)) {
|
|
19
19
|
options.flags = '';
|
|
20
|
+
}
|
|
20
21
|
else {
|
|
21
22
|
// 需求是保留字符串中的某一部分,使用
|
|
22
23
|
const regexp = /[migsuy]/g;
|
|
23
24
|
const matchResult = options.flags.match(regexp);
|
|
24
|
-
if (aTypeOfJs.isNull(matchResult))
|
|
25
|
+
if (aTypeOfJs.isNull(matchResult)) {
|
|
25
26
|
options.flags = '';
|
|
26
|
-
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
27
29
|
options.flags = [...new Set(matchResult)].join('');
|
|
30
|
+
}
|
|
28
31
|
}
|
|
29
32
|
return options;
|
|
30
33
|
}
|
package/src/regexp/parse.mjs
CHANGED
|
@@ -13,16 +13,19 @@ function parse(options) {
|
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
// 处理 flags
|
|
16
|
-
if (!isString(options.flags))
|
|
16
|
+
if (!isString(options.flags)) {
|
|
17
17
|
options.flags = '';
|
|
18
|
+
}
|
|
18
19
|
else {
|
|
19
20
|
// 需求是保留字符串中的某一部分,使用
|
|
20
21
|
const regexp = /[migsuy]/g;
|
|
21
22
|
const matchResult = options.flags.match(regexp);
|
|
22
|
-
if (isNull(matchResult))
|
|
23
|
+
if (isNull(matchResult)) {
|
|
23
24
|
options.flags = '';
|
|
24
|
-
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
25
27
|
options.flags = [...new Set(matchResult)].join('');
|
|
28
|
+
}
|
|
26
29
|
}
|
|
27
30
|
return options;
|
|
28
31
|
}
|