a-js-tools 1.0.13-beta.5 → 2.0.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 (57) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +1 -1
  3. package/cjs/array/difference.js +51 -0
  4. package/cjs/array/index.js +154 -0
  5. package/cjs/array/intersection.js +45 -0
  6. package/cjs/array/symmetricDifference.js +51 -0
  7. package/cjs/array/union.js +65 -0
  8. package/cjs/className.js +58 -0
  9. package/cjs/getRandomNumber.js +76 -0
  10. package/cjs/getRandomString.js +126 -0
  11. package/cjs/index.js +38 -0
  12. package/cjs/isNode.js +27 -0
  13. package/cjs/object/createConstructor.js +58 -0
  14. package/cjs/performance.js +124 -0
  15. package/cjs/regexp/autoEscapedRegExp.js +48 -0
  16. package/cjs/regexp/escapeRegExp.js +24 -0
  17. package/cjs/regexp/parse.js +32 -0
  18. package/cjs/sleep.js +38 -0
  19. package/es/array/difference.js +49 -0
  20. package/es/array/index.js +148 -0
  21. package/es/array/intersection.js +43 -0
  22. package/es/array/symmetricDifference.js +49 -0
  23. package/es/array/union.js +63 -0
  24. package/es/className.js +55 -0
  25. package/es/getRandomNumber.js +73 -0
  26. package/es/getRandomString.js +124 -0
  27. package/es/index.js +14 -0
  28. package/es/isNode.js +24 -0
  29. package/es/object/createConstructor.js +55 -0
  30. package/es/performance.js +121 -0
  31. package/es/regexp/autoEscapedRegExp.js +46 -0
  32. package/es/regexp/escapeRegExp.js +22 -0
  33. package/es/regexp/parse.js +30 -0
  34. package/es/sleep.js +36 -0
  35. package/es/src/index.d.ts +11 -0
  36. package/es/src/object/index.d.ts +2 -0
  37. package/package.json +91 -25
  38. package/index.cjs.js +0 -898
  39. package/index.d.ts +0 -9
  40. package/src/index.d.ts +0 -3
  41. /package/{src → es/src}/array/difference.d.ts +0 -0
  42. /package/{src → es/src}/array/index.d.ts +0 -0
  43. /package/{src → es/src}/array/intersection.d.ts +0 -0
  44. /package/{src → es/src}/array/symmetricDifference.d.ts +0 -0
  45. /package/{src → es/src}/array/union.d.ts +0 -0
  46. /package/{src → es/src}/className.d.ts +0 -0
  47. /package/{src → es/src}/getRandomNumber.d.ts +0 -0
  48. /package/{src → es/src}/getRandomString.d.ts +0 -0
  49. /package/{src → es/src}/isNode.d.ts +0 -0
  50. /package/{src → es/src}/object/createConstructor.d.ts +0 -0
  51. /package/{src → es/src}/performance.d.ts +0 -0
  52. /package/{src → es/src}/regexp/autoEscapedRegExp.d.ts +0 -0
  53. /package/{src → es/src}/regexp/escapeRegExp.d.ts +0 -0
  54. /package/{src → es/src}/regexp/index.d.ts +0 -0
  55. /package/{src → es/src}/regexp/parse.d.ts +0 -0
  56. /package/{src → es/src}/regexp/types.d.ts +0 -0
  57. /package/{src → es/src}/sleep.d.ts +0 -0
@@ -0,0 +1,63 @@
1
+ import { isEmptyArray, isArray } from 'a-type-of-js';
2
+
3
+ /**
4
+ *
5
+ * 数组的并集
6
+ *
7
+ * <span style="color:#f36;">请注意,参数有不为数组时直接抛出 TypeError</span>
8
+ * @param arrays - 多个数组
9
+ * @returns 联合后的数组
10
+ *
11
+ *
12
+ * @example
13
+ *
14
+ * ```ts
15
+ * import { union } from 'a-js-tools';
16
+ *
17
+ * const log = console.log;
18
+ *
19
+ * // []
20
+ * log(union());
21
+ *
22
+ * // [1, 2, 3]
23
+ * log(union([1, 2, 3]));
24
+ *
25
+ * // TypeError
26
+ * log(union([1, 2, 3], 'i'));
27
+ * log(union([1, 2, 3], undefined));
28
+ * log(union([1, 2, 3], null));
29
+ * log(union([1, 2, 3], 4));
30
+ * log(union([1, 2, 3], {}));
31
+ * log(union([1, 2, 3], false));
32
+ *
33
+ * // [1, 2, 3, 4, 6]
34
+ * log(union([1, 2, 3], [2, 4, 6]));
35
+ *
36
+ * // [1, 2, 3, 4, 6]
37
+ * log(union([1, 2, 3], [2, 4, 6], [1, 2, 3]));
38
+ *
39
+ * // [1, 2, 3, 4, 6]
40
+ * log(union([1, 2, 3], [2, 4, 6], [1, 2, 3], [1, 2, 3]));
41
+ * ```
42
+ *
43
+ */
44
+ function union(...arrays) {
45
+ if (isEmptyArray(arrays)) {
46
+ return [];
47
+ }
48
+ if (arrays.some(i => !isArray(i))) {
49
+ throw new TypeError('参数必须都是数组形式的元素');
50
+ }
51
+ if (arrays.length === 1) {
52
+ return [...arrays[0]];
53
+ }
54
+ const resultSet = new Set();
55
+ for (const array of arrays) {
56
+ for (const item of array) {
57
+ resultSet.add(item);
58
+ }
59
+ }
60
+ return Array.from(resultSet);
61
+ }
62
+
63
+ export { union };
@@ -0,0 +1,55 @@
1
+ /**
2
+ * 驼峰命名与连字符命名法的互换
3
+ *
4
+ * @packageDocumentation
5
+ * @module @a-js-tools/class-name
6
+ * @license MIT
7
+ */
8
+ /**
9
+ *
10
+ * 连字符连接转化为小/大驼峰命名法
11
+ *
12
+ * @param str 待转化文本
13
+ * @param dividingType 连字符,缺省值为 "-"
14
+ * @param initial 是否转换第一个字符。默认值为 false (小驼峰类型)
15
+ * @returns 驼峰命名法字符串(e.g. “helloWorld”)
16
+ *
17
+ */
18
+ function toLowerCamelCase(
19
+ /** 待转化文本 */
20
+ str,
21
+ /** 连字符,缺省值为 "-" */
22
+ dividingType = '-',
23
+ /** 是否转换第一个字符。默认值为 false (小驼峰类型) */
24
+ initial = false) {
25
+ let result = str;
26
+ /**
27
+ * 匹配规则
28
+ *
29
+ * - 匹配到分隔符,将分隔符后面的字符转化为大写
30
+ */
31
+ const template = /[\\]|[\^]|[?]|[-]|[.]|[(]|[)]|[|]|[[]\[\]]|[{]|[}]|[+]|[*]|[$]/;
32
+ /** 转化首字符 */
33
+ const toTransform = (_str, _dividingType) => _str.replace(new RegExp(`${template.test(_dividingType) ? `\\${_dividingType}` : _dividingType}([a-zA-Z])`, 'g'), (match, p1) => p1.toUpperCase());
34
+ // 多分隔符转化
35
+ dividingType
36
+ .split('')
37
+ .forEach((item) => (result = toTransform(result, item)));
38
+ return initial
39
+ ? result.replace(/^./, (match) => match.toUpperCase())
40
+ : result;
41
+ }
42
+ /**
43
+ * 驼峰命名法转化为连字符连接
44
+ *
45
+ * @param str 待转化文本
46
+ * @param dividingType 分割符
47
+ * @returns 分割符转化的文本 (e.g. 'hello-world')
48
+ *
49
+ */
50
+ function toSplitCase(str, dividingType = '-') {
51
+ const result = str.replace(/[A-Z]/g, (match) => dividingType.concat(match.toLowerCase()));
52
+ return result.startsWith(dividingType) ? result.substring(1) : result;
53
+ }
54
+
55
+ export { toLowerCamelCase, toSplitCase };
@@ -0,0 +1,73 @@
1
+ import { isNaN, isNumber } from 'a-type-of-js';
2
+
3
+ /**
4
+ * 过去随机数
5
+ *
6
+ * @packageDocumentation
7
+ * @module @a-js-tools/get-random-number
8
+ * @license MIT
9
+ */
10
+ /**
11
+ *
12
+ * 获取一个随机的整数类型
13
+ *
14
+ * 您可以传入两个参数并获取它们之间的任意数字,返回值<span style="color:#ff0;">*会包含端值*</span>
15
+ *
16
+ * 如果只传递一个参数,则如果提供的值为负数,则得到一个小于(或大于)该数字的整数
17
+ *
18
+ * @param max 较大值 ,不允许为`NaN`
19
+ * @param min 较小值,不允许为 `NaN`
20
+ * @returns 任意的整数
21
+ */
22
+ function getRandomInt(max = 1, min = 0) {
23
+ // 判断是否为 NaN 或 不是数字
24
+ if (!isFinite(max) ||
25
+ !isFinite(min) ||
26
+ isNaN(max) ||
27
+ isNaN(min) ||
28
+ !isNumber(max) ||
29
+ !isNumber(min)) {
30
+ throw new TypeError('getRandomInt: max or min is NaN or is not a number');
31
+ }
32
+ /** 获取最小值 */
33
+ let _min = Math.ceil(Number(min)),
34
+ /** 获取最大值 */
35
+ _max = Math.floor(Number(max));
36
+ // 两值相等时,直接返回最大值
37
+ if (_max === _min)
38
+ return _max;
39
+ // 两值交换
40
+ if (_min > _max)
41
+ [_max, _min] = [_min, _max];
42
+ return Math.round(Math.random() * (_max - _min) + _min);
43
+ }
44
+ /**
45
+ *
46
+ * 获取任意的浮点数
47
+ *
48
+ * 您可以传入两个参数并获取它们之间的任意数字
49
+ *
50
+ * 如果只传入一个参数,则如果提供的值为负数,则获取小于(或大于)该数字的浮点数
51
+ *
52
+ * @param max 较大数,缺省值为 1
53
+ * @param min 较小值,缺省值为 0
54
+ * @returns 任意的浮点数
55
+ */
56
+ function getRandomFloat(max = 1, min = 0) {
57
+ // 判断是否为 NaN 或 不是数字
58
+ if (!isFinite(max) ||
59
+ !isFinite(min) ||
60
+ isNaN(max) ||
61
+ isNaN(min) ||
62
+ !isNumber(max) ||
63
+ !isNumber(min)) {
64
+ throw new TypeError('getRandomInt: max or min is NaN or is not a number');
65
+ }
66
+ if (max == min)
67
+ max++;
68
+ if (min > max)
69
+ [max, min] = [min, max];
70
+ return Math.random() * (max - min) + min;
71
+ }
72
+
73
+ export { getRandomFloat, getRandomInt };
@@ -0,0 +1,124 @@
1
+ import { isPlainObject, isNumber, isNaN, isUndefined } from 'a-type-of-js';
2
+ import { ObjectAssign } from './object/createConstructor.js';
3
+ import { getRandomInt } from './getRandomNumber.js';
4
+
5
+ /**
6
+ * 获取随机字符串
7
+ *
8
+ * @packageDocumentation
9
+ * @module @a-js-tools/get-random-string
10
+ * @license MIT
11
+ */
12
+ /**
13
+ *
14
+ * 获取简单的随机字符串
15
+ *
16
+ * @param options - 字符串长度
17
+ * @returns - 随机字符串
18
+ *
19
+ *
20
+ */
21
+ function getRandomString(options) {
22
+ // 验证输入参数
23
+ if (
24
+ // 参数类型错误
25
+ (!isPlainObject(options) && !isNumber(options)) ||
26
+ // 参数为 NaN
27
+ (isNumber(options) && isNaN(options)) ||
28
+ // 参数为数字时为无穷大
29
+ (isNumber(options) && !isFinite(options)) ||
30
+ // 参数为数字时为非整数
31
+ (isNumber(options) && !Number.isInteger(options)) ||
32
+ // 参数为数字时为负数
33
+ (isNumber(options) && Number.isInteger(options) && options < 1) ||
34
+ // 参数为数值然而却小于 1
35
+ (isNumber(options) && options < 1) ||
36
+ // 参数为对象但是 length 属性非数值
37
+ (isPlainObject(options) &&
38
+ (!isNumber(options.length) ||
39
+ options.length < 1 ||
40
+ !Number.isInteger(options.length))))
41
+ throw new TypeError('参数类型错误 ❌ (getRandomString)');
42
+ const initOptions = {
43
+ length: 32,
44
+ chars: 'abcdefghijklmnopqrstuvwxyz',
45
+ chars2: '0123456789',
46
+ chars3: '!@#$%^&*()_+~`|}{[]:;?><,./-=',
47
+ type: 'string',
48
+ includeUppercaseLetters: false,
49
+ includeNumbers: false,
50
+ includeSpecial: false,
51
+ };
52
+ /// 生成 UUID
53
+ if (initOptions.type === 'uuid')
54
+ return crypto.randomUUID();
55
+ // 验证输入参数
56
+ if (isNumber(options) && Number.isInteger(options) && options > 0)
57
+ ObjectAssign(initOptions, { length: options });
58
+ if (isPlainObject(options)) {
59
+ ObjectAssign(initOptions, options);
60
+ initOptions.length = initOptions.length < 1 ? 32 : initOptions.length;
61
+ }
62
+ /** 生成随机字符串 */
63
+ const templateCharsArr = initOptions.chars.split('');
64
+ // 添加大写字母
65
+ if (initOptions.includeUppercaseLetters)
66
+ interleaveString(templateCharsArr, initOptions.chars.toUpperCase());
67
+ // 添加数字
68
+ if (initOptions.includeNumbers)
69
+ interleaveString(templateCharsArr, initOptions.chars2);
70
+ // 添加特殊字符
71
+ if (initOptions.includeSpecial)
72
+ interleaveString(templateCharsArr, initOptions.chars3);
73
+ /** 结果字符串 */
74
+ let result = '';
75
+ /** 混淆后的字符串 */
76
+ const str = templateCharsArr.join('');
77
+ /** 混淆后字符长度 */
78
+ const strLen = str.length;
79
+ if (globalThis && globalThis.crypto && globalThis.crypto.getRandomValues) {
80
+ // 使用密码学安全的随机数生成器
81
+ const bytes = globalThis.crypto.getRandomValues(new Uint8Array(initOptions.length));
82
+ /** 获取最后的 chars 数据 */
83
+ // 循环遍历
84
+ bytes.forEach(byte => (result += str[byte % strLen]));
85
+ }
86
+ else {
87
+ for (let i = 0; i < initOptions.length; i++)
88
+ result += str[getRandomInt(strLen - 1)];
89
+ }
90
+ /**
91
+ *
92
+ * 字符串交叉函数
93
+ *
94
+ * 非线形串交叉,对相交叉
95
+ *
96
+ * @param str1 - 字符串1
97
+ * @param str2 - 字符串2
98
+ * @returns - 交叉后的字符串
99
+ * @example
100
+ * ```ts
101
+ * interleaveString('abc', '123') // 'a1b2c3'
102
+ * ```
103
+ */
104
+ function interleaveString(str1, str2) {
105
+ const str1Length = str1.length, str2Length = str2.length;
106
+ const maxLength = Math.max(str1Length, str2Length);
107
+ for (let i = 0; i < maxLength; i++) {
108
+ if (i < str1Length && !isUndefined(str2[i])) {
109
+ str1[i] += str2[i];
110
+ }
111
+ else if (i < str2Length) {
112
+ str1[i] = str2[i];
113
+ }
114
+ }
115
+ }
116
+ /// 结果字符串不包含字符
117
+ if (!/[a-zA-Z]/.test(result))
118
+ return String.fromCharCode(getRandomInt(97, 122)).concat(result.slice(1));
119
+ while (!/^[a-zA-Z]$/.test(result[0]))
120
+ result = result.slice(1) + result[0];
121
+ return result;
122
+ }
123
+
124
+ export { getRandomString };
package/es/index.js ADDED
@@ -0,0 +1,14 @@
1
+ export { toLowerCamelCase, toSplitCase } from './className.js';
2
+ export { ObjectAssign, createConstructor } from './object/createConstructor.js';
3
+ export { getRandomFloat, getRandomInt } from './getRandomNumber.js';
4
+ export { getRandomString } from './getRandomString.js';
5
+ export { debounce, throttle } from './performance.js';
6
+ export { escapeRegExp } from './regexp/escapeRegExp.js';
7
+ export { autoEscapedRegExp } from './regexp/autoEscapedRegExp.js';
8
+ export { isBrowser, isNode } from './isNode.js';
9
+ export { enArr } from './array/index.js';
10
+ export { sleep } from './sleep.js';
11
+ export { intersection } from './array/intersection.js';
12
+ export { union } from './array/union.js';
13
+ export { difference } from './array/difference.js';
14
+ export { symmetricDifference } from './array/symmetricDifference.js';
package/es/isNode.js ADDED
@@ -0,0 +1,24 @@
1
+ import { isUndefined } from 'a-type-of-js';
2
+
3
+ /**
4
+ *
5
+ * 判断当前环境是否为 node 环境
6
+ *
7
+ */
8
+ function isNode() {
9
+ return !isUndefined((globalThis &&
10
+ globalThis.process &&
11
+ globalThis.process.versions &&
12
+ globalThis.process.versions.node) ||
13
+ undefined);
14
+ }
15
+ /**
16
+ *
17
+ * 是否为浏览器环境
18
+ *
19
+ */
20
+ function isBrowser() {
21
+ return !isNode();
22
+ }
23
+
24
+ export { isBrowser, isNode };
@@ -0,0 +1,55 @@
1
+ /**
2
+ *
3
+ * 构建一个 Constructor 构造函数
4
+ *
5
+ * 接收一个构造函数,然后返回 TS 能识别的构造函数自身
6
+ *
7
+ * 函数本身并没有执行任何逻辑,仅是简单的返回了实参自身
8
+ *
9
+ * 而经过该函数的包装,构造函数成了能够被 TS 识别为可用 new 实例的构造函数
10
+ *
11
+ * @param constructor - 传入一个构造函数
12
+ * @returns 返回传入的构造函数
13
+ *
14
+ * ```ts
15
+ * import { createConstructor } from "a-js-tools";
16
+ *
17
+ * type Tom = {
18
+ * a: number
19
+ * }
20
+ *
21
+ * function _Tom (this: TomType): Tom {
22
+ * this.a = 1;
23
+ *
24
+ * return this;
25
+ * }
26
+ *
27
+ * // 逻辑上没有错,但是会造成 ts 显示
28
+ * // 其目标缺少构造签名的 "new" 表达式隐式具有 "any" 类型。ts(7009)
29
+ * const a = new _Tom();
30
+ *
31
+ * const tomConstructor = createConstructor(_tom);
32
+ *
33
+ * const b = new tomConstructor(); // 这时就不会显示错误
34
+ *
35
+ * ```
36
+ *
37
+ */
38
+ function createConstructor(constructor) {
39
+ constructor.prototype.apply = Function.apply;
40
+ constructor.prototype.bind = Function.bind;
41
+ constructor.prototype.call = Function.call;
42
+ constructor.prototype.length = Function.length;
43
+ // constructor.prototype.arguments = Function.arguments;
44
+ constructor.prototype.name = Function.name;
45
+ constructor.prototype.toString = Function.toString;
46
+ return constructor;
47
+ }
48
+ /** 对象的 assign 用法 */
49
+ function ObjectAssign(target, bar) {
50
+ const keys = Object.keys(bar);
51
+ keys.forEach(key => (target[key] = bar[key]));
52
+ return target;
53
+ }
54
+
55
+ export { ObjectAssign, createConstructor };
@@ -0,0 +1,121 @@
1
+ import { isUndefined, isNull } from 'a-type-of-js';
2
+ import { isFunction } from 'a-type-of-js/isFunction';
3
+ import { isNumber } from 'a-type-of-js/isNumber';
4
+
5
+ /**
6
+ * 防抖和节流
7
+ *
8
+ * @packageDocumentation
9
+ * @module @a-js-tools/performance
10
+ * @license MIT
11
+ */
12
+ /**
13
+ *
14
+ * 防抖
15
+ *
16
+ * @param callback 回调函数
17
+ * @param options 延迟时间(毫秒),默认 200 (ms) 或包含 this 的配置
18
+ * @returns 返回的闭包函数
19
+ * @example
20
+ *
21
+ * ```ts
22
+ * const debounce = (callback: Function, delay = 300) => {
23
+ * let timer: any = null
24
+ * return (...args: any[]) => {
25
+ * clearTimeout(timer)
26
+ * }
27
+ * }
28
+ *
29
+ */
30
+ function debounce(callback, options = 200) {
31
+ if (!isFunction(callback))
32
+ throw new TypeError('callback must be a function');
33
+ if (isNumber(options))
34
+ options = {
35
+ delay: options,
36
+ this: null,
37
+ };
38
+ if (isUndefined(options.delay) ||
39
+ !isFinite(options.delay) ||
40
+ options.delay < 0)
41
+ // 强制转换非数值
42
+ options.delay = 200;
43
+ /** 定时器返回的 id */
44
+ let timeoutId;
45
+ const clear = () => {
46
+ if (timeoutId) {
47
+ clearTimeout(timeoutId);
48
+ timeoutId = undefined;
49
+ }
50
+ };
51
+ const result = (...args) => {
52
+ clear();
53
+ timeoutId = setTimeout(() => {
54
+ try {
55
+ const _this = options && options.this ? options.this : null;
56
+ // 由于 Reflect.apply 并不能在 ES5 中使用,所以我们并不能保证能执行成功
57
+ callback.apply(_this, args);
58
+ // Reflect.apply(callback, options?.this ?? null, args);
59
+ }
60
+ catch (error) {
61
+ console.log('Debounce callback throw an error', error);
62
+ }
63
+ }, Math.max(options.delay || 5, 5));
64
+ };
65
+ result.cancel = () => clear();
66
+ return result;
67
+ }
68
+ /**
69
+ * 节流
70
+ *
71
+ * @param callback 回调函数
72
+ * @param options 延迟时间(毫秒),默认 200 (ms) 或设置 this
73
+ * @returns 返回的闭包函数
74
+ */
75
+ function throttle(callback, options = 200) {
76
+ if (!isFunction(callback))
77
+ throw new TypeError('callback must be a function');
78
+ if (isNumber(options))
79
+ options = {
80
+ delay: options,
81
+ this: null,
82
+ };
83
+ if (isUndefined(options.delay) ||
84
+ !isFinite(options.delay) ||
85
+ options.delay < 0)
86
+ // 强制转换非数值
87
+ options.delay = 200;
88
+ /** 延迟控制插销 */
89
+ let inThrottle = false;
90
+ /** 延迟控制 */
91
+ let timeoutId = null;
92
+ const delay = options && options.delay ? options.delay : 5;
93
+ const throttled = (...args) => {
94
+ if (inThrottle)
95
+ return;
96
+ try {
97
+ const _this = options && options.this ? options.this : null;
98
+ callback.apply(_this, args);
99
+ }
100
+ catch (error) {
101
+ console.error('Throttle 执行回调抛出问题', error);
102
+ }
103
+ inThrottle = true;
104
+ if (!isNull(timeoutId))
105
+ clearTimeout(timeoutId);
106
+ timeoutId = setTimeout(() => {
107
+ inThrottle = false;
108
+ timeoutId = null;
109
+ }, Math.max(delay, 5));
110
+ };
111
+ throttled.cancel = () => {
112
+ if (!isNull(timeoutId)) {
113
+ clearTimeout(timeoutId);
114
+ }
115
+ inThrottle = false;
116
+ timeoutId = null;
117
+ };
118
+ return throttled;
119
+ }
120
+
121
+ export { debounce, throttle };
@@ -0,0 +1,46 @@
1
+ import { isString, isUndefined } from 'a-type-of-js';
2
+ import { escapeRegExp } from './escapeRegExp.js';
3
+ import { parse } from './parse.js';
4
+
5
+ /**
6
+ *
7
+ * ## 适用于简单的文本字符串自动转化为简单模式正则表达式
8
+ *
9
+ * *若字符串包含且需保留字符类、组、反向引用、量词等时,该方法可能不适用*
10
+ *
11
+ * @param pattern 待转化的文本字符串
12
+ * @param options 转化选项。 为文本字符串时,默认为正则表达式的标志,还可指定是否匹配开头或结尾
13
+ * @returns 正则表达式
14
+ * @example
15
+ *
16
+ * ```ts
17
+ * import { autoEscapedRegExp } from 'a-regexp';
18
+ *
19
+ * autoEscapedRegExp('abc'); // => /abc/
20
+ * autoEscapedRegExp('abc', 'gim'); // => /abc/gim
21
+ * autoEscapedRegExp('abc', { flags: 'g', start: true }); // => /^abc/g
22
+ * autoEscapedRegExp('abc', { flags: 'g', end: true }); // => /abc$/g
23
+ * autoEscapedRegExp('abc', { start: true, end: true }); // => /^abc$/
24
+ *
25
+ * // 转化特殊字符类、组、反向引用、量词等
26
+ * // 无法保留匹配规则
27
+ * autoEscapedRegExp('a-zA-Z0-9'); // => /a-zA-Z0-9/
28
+ * autoEscapedRegExp('a-zA-Z0-9', 'g'); // => /a-zA-Z0-9/g
29
+ * autoEscapedRegExp('[a-zA-Z0-9]'); // => /\[a-zA-Z0-9\]/
30
+ * autoEscapedRegExp('^[a-zA-Z0-9]+$'); // => /\^\[a-zA-Z0-9\]\$/
31
+ *
32
+ * ```
33
+ *
34
+ */
35
+ function autoEscapedRegExp(pattern, options) {
36
+ if (!isString(pattern))
37
+ throw new TypeError('pattern must be a 字符串');
38
+ pattern = escapeRegExp(pattern);
39
+ /** 简单转化 */
40
+ if (isUndefined(options))
41
+ return new RegExp(pattern);
42
+ options = parse(options);
43
+ return new RegExp(`${options.start ? '^' : ''}${pattern}${options.end ? '$' : ''}`, options.flags);
44
+ }
45
+
46
+ export { autoEscapedRegExp };
@@ -0,0 +1,22 @@
1
+ /**
2
+ *
3
+ * 将一个字符串转化为符合正则要求的字符串
4
+ *
5
+ * @param str 需要转义的字符串
6
+ * @requires escapeRegExp 转化后字符串
7
+ * @example
8
+ *
9
+ * ```ts
10
+ * import { escapeRegExp } from 'a-js-tools';
11
+ *
12
+ * escapeRegExp('a.b.c'); // 'a\\.b\\.c'
13
+ * escapeRegExp('a\\.b\\.c'); // 'a\\\\.b\\\\.c'
14
+ * escapeRegExp('[a-z]'); // '\\[a-z\\]'
15
+ * escapeRegExp('^abc$'); // '\\^abc\\$'
16
+ * ```
17
+ */
18
+ function escapeRegExp(str) {
19
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
20
+ }
21
+
22
+ export { escapeRegExp };
@@ -0,0 +1,30 @@
1
+ import { isString, isNull } from 'a-type-of-js';
2
+
3
+ /**
4
+ *
5
+ * 解析 options
6
+ *
7
+ */
8
+ function parse(options) {
9
+ // 处理 options
10
+ if (isString(options)) {
11
+ options = {
12
+ flags: options,
13
+ };
14
+ }
15
+ // 处理 flags
16
+ if (!isString(options.flags))
17
+ options.flags = '';
18
+ else {
19
+ // 需求是保留字符串中的某一部分,使用
20
+ const regexp = /[migsuy]/g;
21
+ const matchResult = options.flags.match(regexp);
22
+ if (isNull(matchResult))
23
+ options.flags = '';
24
+ else
25
+ options.flags = [...new Set(matchResult)].join('');
26
+ }
27
+ return options;
28
+ }
29
+
30
+ export { parse };
package/es/sleep.js ADDED
@@ -0,0 +1,36 @@
1
+ import { isZero } from 'a-type-of-js/isNumber';
2
+
3
+ /**
4
+ *
5
+ * ## 线程休息
6
+ *
7
+ * 但从调用到执行完毕总是与期望的时间并不相吻合,除非执行是线型的(也不保证时间的严格性)
8
+ *
9
+ * - 宏任务:整体代码、setTimeout、DOM 事件回调、requestAnimationFrame、setImmediate、setInterval、I/O操作、UI渲染等
10
+ * - 微任务:Promise的then/catch/finally、process.nextTick(Node.js)、MutationObserver、queueMicrotask(显示添加微任务)等
11
+ *
12
+ * <span style="color:#ff0;">*Node.js中的process.nextTick优先级高于其他微任务*</span>
13
+ *
14
+ * @param delay 睡觉时长(机器时间,毫秒为单位)
15
+ * @returns 🈳
16
+ * @example
17
+ *
18
+ * ```ts
19
+ * import { sleep } from 'a-js-tools';
20
+ *
21
+ * console.log(Date.now()); // 1748058118471
22
+ * await sleep(1000);
23
+ * console.log(Date.now()); // 1748058119473
24
+ *
25
+ * ```
26
+ *
27
+ */
28
+ async function sleep(delay = 1000) {
29
+ if (!isFinite(delay) || delay < 0)
30
+ throw new TypeError('delay 应该是一个正常的数值');
31
+ if (isZero(delay))
32
+ return Promise.resolve();
33
+ return new Promise(resolve => setTimeout(resolve, delay));
34
+ }
35
+
36
+ export { sleep };
@@ -0,0 +1,11 @@
1
+ export { toLowerCamelCase, toSplitCase } from './className';
2
+ export type { CreateConstructor } from './object/createConstructor';
3
+ export { createConstructor, ObjectAssign } from './object/createConstructor';
4
+ export { getRandomFloat, getRandomInt } from './getRandomNumber';
5
+ export { getRandomString } from './getRandomString';
6
+ export { throttle, debounce } from './performance';
7
+ export type { DebounceAndThrottleReturnType, debounce_throttle_options, } from './performance';
8
+ export { escapeRegExp, autoEscapedRegExp } from './regexp';
9
+ export { isBrowser, isNode } from './isNode';
10
+ export { intersection, enArr, union, difference, symmetricDifference, } from './array';
11
+ export { sleep } from './sleep';
@@ -0,0 +1,2 @@
1
+ export type { CreateConstructor } from './createConstructor';
2
+ export { createConstructor } from './createConstructor';