@polyv/utils 1.6.0 → 2.0.0-beta.2

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 (56) hide show
  1. package/README.md +34 -19
  2. package/dist/cjs/boolean.d.ts +45 -0
  3. package/dist/cjs/boolean.js +1 -0
  4. package/dist/cjs/countdown.d.ts +97 -0
  5. package/dist/cjs/countdown.js +1 -0
  6. package/dist/cjs/date.d.ts +44 -0
  7. package/dist/cjs/date.js +1 -0
  8. package/dist/cjs/json.d.ts +43 -0
  9. package/dist/cjs/json.js +1 -0
  10. package/dist/cjs/net.d.ts +32 -0
  11. package/dist/cjs/net.js +1 -0
  12. package/dist/cjs/string.d.ts +94 -0
  13. package/dist/cjs/string.js +1 -0
  14. package/dist/cjs/validate.d.ts +26 -0
  15. package/dist/cjs/validate.js +1 -0
  16. package/dist/es/boolean.d.ts +45 -0
  17. package/dist/es/boolean.js +1 -0
  18. package/dist/es/countdown.d.ts +97 -0
  19. package/dist/es/countdown.js +1 -0
  20. package/dist/es/date.d.ts +44 -0
  21. package/dist/es/date.js +1 -0
  22. package/dist/es/json.d.ts +43 -0
  23. package/dist/es/json.js +1 -0
  24. package/dist/es/net.d.ts +32 -0
  25. package/dist/es/net.js +1 -0
  26. package/dist/es/string.d.ts +94 -0
  27. package/dist/es/string.js +1 -0
  28. package/dist/es/validate.d.ts +26 -0
  29. package/dist/es/validate.js +1 -0
  30. package/package.json +29 -24
  31. package/dist/boolean.js +0 -1
  32. package/dist/browser.js +0 -1
  33. package/dist/cookie.js +0 -1
  34. package/dist/countdown.js +0 -1
  35. package/dist/date.js +0 -1
  36. package/dist/lang.js +0 -1
  37. package/dist/net.js +0 -1
  38. package/dist/polling.js +0 -1
  39. package/dist/querystring.js +0 -1
  40. package/dist/storage.js +0 -1
  41. package/dist/string.js +0 -1
  42. package/dist/validate.js +0 -1
  43. package/src/boolean.js +0 -67
  44. package/src/browser.js +0 -113
  45. package/src/cookie.js +0 -115
  46. package/src/countdown.js +0 -91
  47. package/src/date.js +0 -92
  48. package/src/internal/core.js +0 -59
  49. package/src/internal/timeunit.js +0 -63
  50. package/src/lang.js +0 -121
  51. package/src/net.js +0 -54
  52. package/src/polling.js +0 -142
  53. package/src/querystring.js +0 -121
  54. package/src/storage.js +0 -106
  55. package/src/string.js +0 -190
  56. package/src/validate.js +0 -42
package/src/countdown.js DELETED
@@ -1,91 +0,0 @@
1
- /**
2
- * 本模块提供倒数功能。
3
- * @module countdown
4
- */
5
-
6
- const computes = [
7
- { divisor: 24 * 60 * 60 * 1000, unit: 'days' },
8
- { divisor: 60 * 60 * 1000, unit: 'hours' },
9
- { divisor: 60 * 1000, unit: 'minutes' },
10
- { divisor: 1000, unit: 'seconds' }
11
- ];
12
-
13
- /**
14
- * 倒计时回调函数。
15
- * @callback countdownCallback
16
- * @memberof module:countdown.Countdown
17
- * @param {Object} rest 剩余的时间。
18
- * @param {number} rest.days 剩余天数。
19
- * @param {number} rest.hours 剩余小时数。
20
- * @param {number} rest.minutes 剩余分钟数。
21
- * @param {number} rest.seconds 剩余秒数。
22
- * @param {boolean} rest.totalMsecs 剩余的总毫秒数。
23
- */
24
- /**
25
- * 倒计时类。
26
- * @memberof module:countdown
27
- * @class
28
- * @name Countdown
29
- * @author luoliquan
30
- * @param {number} secs 总秒数。
31
- * @param {countdownCallback} [cb] 回调函数。
32
- * @example
33
- * const countdown = new Countdown(60, (rest) => {
34
- * console.dir(rest);
35
- * });
36
- * countdown.start();
37
- */
38
- export default class Countdown {
39
- constructor(secs, cb) {
40
- secs = parseInt(secs);
41
- if (isNaN(secs)) { throw new Error('Total seconds must be a number'); }
42
- this._secs = secs * 1000; // 倒计时毫秒数
43
- this._cb = typeof cb === 'function' ? cb : function() {}; // 倒计时回调函数
44
- }
45
-
46
- _exec() {
47
- if (!this._startTime) { return; }
48
-
49
- let value = Math.max(0, this._secs - (Date.now() - this._startTime));
50
- if (value > 0 && !this._stopped) {
51
- setTimeout(() => { this._exec(); }, 1000);
52
- }
53
-
54
- if (value >= 0) {
55
- const rest = {
56
- totalMsecs: value
57
- };
58
- computes.forEach((item, i) => {
59
- rest[item.unit] = value / item.divisor;
60
- if (i === computes.length - 1) {
61
- rest[item.unit] = Math.round(rest[item.unit]);
62
- } else {
63
- rest[item.unit] = Math.floor(rest[item.unit]);
64
- value = value % item.divisor;
65
- }
66
- });
67
- this._cb(rest);
68
- }
69
- }
70
-
71
- /**
72
- * 开始倒计时。
73
- * @method
74
- * @memberof module:countdown.Countdown.prototype
75
- */
76
- start() {
77
- if (this.secs <= 0) { return; }
78
- this._startTime = Date.now();
79
- this._exec();
80
- }
81
-
82
- /**
83
- * 停止倒计时。
84
- * @method
85
- * @memberof module:countdown.Countdown.prototype
86
- */
87
- stop() {
88
- if (this._timerId) { clearTimeout(this._timerId); }
89
- this._stopped = true;
90
- }
91
- }
package/src/date.js DELETED
@@ -1,92 +0,0 @@
1
- /**
2
- * 本模块提供日期处理相关方法。
3
- * @module date
4
- */
5
-
6
- import { extend } from './lang';
7
-
8
- // 保证日期相关函数的操作对象为日期类型
9
- export function ensureDate(date) {
10
- if (typeof date !== 'object') { date = new Date(date); }
11
- return date;
12
- }
13
-
14
- /**
15
- * 格式化日期。
16
- * @author luoliquan
17
- * @param {(Date|number)} date 日期对象或时间戳(毫秒)。
18
- * @param {string} formation 格式。
19
- * @return {string} 格式化结果。
20
- * @example
21
- * formatDate(new Date(2018, 9, 8, 8, 50, 56), 'YYYY-MM-DD hh:mm:ss'); // '2018-10-08 08:50:56'
22
- */
23
- export function formatDate(date, formation) {
24
- date = ensureDate(date);
25
-
26
- const values = {
27
- Y: date.getFullYear(),
28
- M: date.getMonth() + 1,
29
- D: date.getDate(),
30
- h: date.getHours(),
31
- m: date.getMinutes(),
32
- s: date.getSeconds()
33
- };
34
-
35
- return formation.replace(/([YMDhms])\1*/g, (match) => {
36
- let result = values[match[0]];
37
- if (match.length > 1 && result.toString().length !== match.length) {
38
- result = ((new Array(match.length)).join('0') + result).slice(-match.length);
39
- }
40
- return result;
41
- });
42
- }
43
-
44
- /**
45
- * 把秒数格式化成「时:分:秒」格式。
46
- * @author luoliquan
47
- * @param {number} secs 秒数。
48
- * @param {Object} [options] 格式化配置。
49
- * @param {number} [options.segments=2] 段数,2 或者 3。
50
- * 为 2 时,如果小时为 0,则格式化样式为「分:秒」。
51
- * @param {number} [options.digits=2] 每一段数字的最小位数,不足位数时补 0。
52
- * @return {string} 格式化结果。
53
- * @example
54
- * formatSeconds(3682); // '01:01:22'
55
- * formatSeconds(82); // '01:22'
56
- * formatSeconds(82, { segments: 3 }); // '00:01:22'
57
- * formatSeconds(3682, { digits: 1 }); // '1:1:22'
58
- */
59
- export function formatSeconds(secs, options) {
60
- secs = Number(secs);
61
- if (isNaN(secs) || secs < 0) {
62
- throw new Error('"secs" must be a positive integer');
63
- }
64
-
65
- // 参数合法性校验
66
- options = extend({}, options);
67
- options.segments = parseInt(options.segments);
68
- // 位数最小为 1
69
- options.digits = Math.max(1, parseInt(options.digits) || 2);
70
- // 段数只能为 2 或者 3
71
- if ([2, 3].indexOf(options.segments) === -1) {
72
- options.segments = 2;
73
- }
74
-
75
- // 需要补多少个 0
76
- const zeros = (new Array(options.digits + 1).join('0'));
77
-
78
- const result = [
79
- 60 * 60,
80
- 60,
81
- 1
82
- ].map((num) => {
83
- const subResult = Math.floor(secs / num);
84
- const len = subResult.toString().length;
85
- secs = secs % num;
86
- return (zeros + subResult).slice(-Math.max(len, options.digits));
87
- });
88
-
89
- if (options.segments < 3 && !Number(result[0])) { result.shift(); }
90
-
91
- return result.join(':');
92
- }
@@ -1,59 +0,0 @@
1
- /**
2
- * @module internal-core
3
- * @ignore
4
- */
5
-
6
- // ESLint 不推荐直接使用 obj.hasOwnProperty
7
- const hasOwnProperty = Object.prototype.hasOwnProperty;
8
- /**
9
- * 检查指定对象是否具有某个 own property。
10
- * @function
11
- * @name hasOwnProp
12
- * @author luoliquan
13
- * @param {Any} obj 指定对象。
14
- * @param {string} prop 属性名。
15
- * @return {boolean} 指定对象是否具有某个 own property。
16
- */
17
- export function hasOwnProp(obj, prop) {
18
- return hasOwnProperty.call(obj, prop);
19
- }
20
-
21
- // 单个源扩展
22
- export function extendSingle(target, src) {
23
- if (src != null) {
24
- let key, value;
25
- for (key in src) {
26
- value = src[key];
27
- if (key === '__proto__' || target === value) { continue; }
28
- if (hasOwnProp(src, key)) { target[key] = value; }
29
- }
30
- }
31
- }
32
-
33
-
34
- const toString = Object.prototype.toString;
35
-
36
- // 是否 Object 类型
37
- export function isObject(value) {
38
- return toString.call(value) === '[object Object]';
39
- }
40
-
41
- // 是否 Date 类型
42
- export function isDate(value) {
43
- return toString.call(value) === '[object Date]';
44
- }
45
-
46
-
47
- /**
48
- * 全局对象,浏览器环境下为 window,Node 环境下为 global。
49
- * @type {Object}
50
- */
51
- let theGlobal;
52
- if (typeof window !== 'undefined') {
53
- theGlobal = window;
54
- } else if (typeof global !== 'undefined') {
55
- theGlobal = global;
56
- } else {
57
- theGlobal = null;
58
- }
59
- export { theGlobal };
@@ -1,63 +0,0 @@
1
- /**
2
- * @module
3
- * @ignore
4
- */
5
-
6
- import { hasOwnProp } from './core';
7
-
8
- // 时间单位
9
- const timeUnits = {
10
- SEC: 1000,
11
- MIN: 60 * 1000,
12
- HOUR: 60 * 60 * 1000,
13
- DAY: 24 * 60 * 60 * 1000,
14
- MONTH: 30 * 24 * 60 * 60 * 1000,
15
- YEAR: 365 * 24 * 60 * 60 * 1000
16
- };
17
-
18
- /**
19
- * 把带单位的时间跨度转换为毫秒表示。
20
- * @author luoliquan
21
- * @param {(number|string)} timespan 时间跨度。为数字时表示毫秒,为字符串时支持以下格式(%表示数字):
22
- * %secs;
23
- * %mins;
24
- * %hours;
25
- * %days;
26
- * %months;
27
- * %years。
28
- * @return {number} 时间跨度的毫秒表示。
29
- */
30
- export function parse(timespan) {
31
- // str为数字,直接返回
32
- if (typeof timespan === 'number') { return timespan; }
33
- if (!isNaN(timespan)) { return Number(timespan); }
34
-
35
- const num = parseFloat(timespan);
36
- if (isNaN(num)) {
37
- throw new Error('Invalid timespan string');
38
- }
39
-
40
- const unit = timespan.split(num)[1]
41
- .trim()
42
- .toUpperCase()
43
- .replace(/S$/, ''); // 移除复数时的s
44
-
45
- if (hasOwnProp(timeUnits, unit)) {
46
- return num * timeUnits[unit];
47
- } else {
48
- throw new Error('Invalid time unit "' + unit + '"');
49
- }
50
- }
51
-
52
- /**
53
- * 以指定日期对象的毫秒表示加上指定时间跨度的毫秒表示,生成新的日期对象。
54
- * @author luoliquan
55
- * @param {(Date|number)} date 指定日期对象或日期的毫秒表示。
56
- * @param {(number|string)} timespan 时间跨度,为数字时表示毫秒,为字符串时支持的格式同 parse。
57
- * @return {Date} 表示相加结果的日期对象。
58
- */
59
- export function addToDate(date, timespan) {
60
- return new Date(
61
- (typeof date === 'number' ? date : date.getTime()) + parse(timespan)
62
- );
63
- }
package/src/lang.js DELETED
@@ -1,121 +0,0 @@
1
- /**
2
- * 本模块提供基础方法。
3
- * @module lang
4
- */
5
-
6
- import { extendSingle, hasOwnProp, isObject } from './internal/core';
7
-
8
- /**
9
- * 检查指定对象是否具有某个 own property(ESLint 不推荐直接使用 obj.hasOwnProperty)。
10
- * @author luoliquan
11
- * @name hasOwnProp
12
- * @function
13
- * @static
14
- * @param {Any} obj 指定对象。
15
- * @param {string} prop 属性名。
16
- * @return {boolean} 指定对象是否具有某个 own property。
17
- */
18
- export { hasOwnProp };
19
-
20
- /**
21
- * 检查指定对象是否为类数组结构。
22
- * @author luoliquan
23
- * @param {Any} obj 指定对象。
24
- * @return {boolean} 检查指定对象是否为类数组结构。
25
- * @example
26
- * isArrayLike([]); // true
27
- * isArrayLike(document.getElementsByTagName('body')); // true
28
- * isArrayLike({}); // false
29
- */
30
- export function isArrayLike(obj) {
31
- return obj != null &&
32
- typeof obj !== 'function' &&
33
- typeof obj.length === 'number' &&
34
- obj.length >= 0 &&
35
- obj.length % 1 === 0; // 不是小数
36
- }
37
-
38
- /**
39
- * 检查指定值是否为空数据。以下情况会判断为空数据:
40
- * null 或者 undefined;
41
- * 数组结构,但长度为 0;
42
- * 空字符串或仅包含空白字符的字符串;
43
- * 没有 own property 的纯对象。
44
- * @author luoliquan
45
- * @param {Any} value 指定值。
46
- * @return {boolean} 指定值是否为空数据。
47
- * @example
48
- * isEmptyData(null); // true
49
- * isEmptyData([]); // true
50
- * isEmptyData(''); // true
51
- * isEmptyData({}); // true
52
- * isEmptyData({ a: 1 }); // false
53
- * isEmptyData([1]); // false
54
- */
55
- export function isEmptyData(value) {
56
- if (value == null) { return true; }
57
- if (typeof value === 'string') {
58
- return value.trim() === '';
59
- } else if (Array.isArray(value)) {
60
- return !value.length;
61
- } else if (isObject(value)) {
62
- for (const key in value) {
63
- if (hasOwnProp(value, key)) { return false; }
64
- }
65
- return true;
66
- }
67
- return false;
68
- }
69
-
70
- /**
71
- * 把源对象的属性(own property)扩展到目标对象(同 Object.assign)。
72
- * @author luoliquan
73
- * @param {Any} target 目标对象。
74
- * @param {...Any} [source] 源对象。若有同名属性,则后者覆盖前者。
75
- * @return {Any} 目标对象。
76
- */
77
- export function extend(target) {
78
- if (target == null) {
79
- throw new Error('The target argument cannot be null or undefined');
80
- }
81
-
82
- const len = arguments.length;
83
- let i = 0;
84
- while (++i < len) {
85
- extendSingle(target, arguments[i]);
86
- }
87
- return target;
88
- }
89
-
90
- /**
91
- * 深度克隆指定对象(仅限 JSON 支持的数据类型)。
92
- * @author liumin
93
- * @param {Any} obj 指定对象。
94
- * @return {Any} 克隆结果。
95
- * @example
96
- * cloneJSON({ a: 1, b: 2 }); // { a: 1, b: 2 }
97
- */
98
- export function cloneJSON(obj) {
99
- if (obj == null) { return obj; }
100
- return JSON.parse(JSON.stringify(obj));
101
- }
102
-
103
- /**
104
- * 尝试把指定字符串解析为 JSON 对象。
105
- * @author luoliquan
106
- * @param {string} str 指定字符串。
107
- * @param {Function} [onError] 解析出错时执行的函数。
108
- * @return {Any} 解析结果,解析失败时返回 undefined。
109
- * @example
110
- * tryParseJSON('ss&&**'); // undefined
111
- * tryParseJSON('{"a": 1}'); // { a: 1 }
112
- */
113
- export function tryParseJSON(str, onError) {
114
- let result;
115
- try {
116
- result = JSON.parse(str);
117
- } catch (e) {
118
- if (onError) { onError(e); }
119
- }
120
- return result;
121
- }
package/src/net.js DELETED
@@ -1,54 +0,0 @@
1
- /**
2
- * 本模块提供网络协议相关方法。
3
- * @module net
4
- */
5
-
6
- // 匹配协议
7
- const reProtocol = /^(?:([a-z]+):)?\/{2,3}/i;
8
-
9
- /**
10
- * 检查目标字符串是否以特定 URL 协议开头。
11
- * @author luoliquan
12
- * @param {string} str 目标字符串。
13
- * @param {Array} [protocols] 特定协议(不含冒号和斜杠),不指定时表示允许任何协议。
14
- * @return {boolean} 目标字符串是否以特定 URL 协议开头。
15
- * @example
16
- * startsWithProtocol('//abc.com'); // true
17
- * startsWithProtocol('https://abc.com'); // true
18
- * startsWithProtocol('file:///Users/'); // true
19
- * startsWithProtocol('abc.com'); // false
20
- * startsWithProtocol('http://abc.com', ['http', 'https']); // true
21
- * startsWithProtocol('ftp://abc.com', ['http', 'https']); // false
22
- */
23
- export function startsWithProtocol(str, protocols) {
24
- const result = reProtocol.test(str);
25
- if (result && protocols) {
26
- const protocol = (RegExp.$1 || '').toLowerCase();
27
- for (let i = protocols.length - 1; i >= 0; i--) {
28
- if (protocol === protocols[i].toLowerCase()) {
29
- return true;
30
- }
31
- }
32
- return false;
33
- }
34
- return result;
35
- }
36
-
37
- /**
38
- * 替换目标字符串中的 URL 协议。如果字符串中不包含协议,则加上协议。
39
- * @author luoliquan
40
- * @param {string} url 目标字符串。
41
- * @param {string} protocol 协议。
42
- * @return {string} 替换结果。
43
- * @example
44
- * changeProtocol('abc.com', 'https'); // 'https://abc.com'
45
- * changeProtocol('http://abc.com', 'https'); // 'https://abc.com'
46
- */
47
- export function changeProtocol(url, protocol) {
48
- if (!reProtocol.test(protocol)) {
49
- protocol += '://';
50
- }
51
- return startsWithProtocol(url) ?
52
- url.replace(reProtocol, protocol) :
53
- protocol + url;
54
- }
package/src/polling.js DELETED
@@ -1,142 +0,0 @@
1
- /**
2
- * 本模块提供轮询功能。
3
- * @module polling
4
- */
5
-
6
- import { theGlobal } from './internal/core';
7
- import { extend } from './lang';
8
-
9
- /**
10
- * 轮询类。
11
- * @memberof module:polling
12
- * @class
13
- * @name Polling
14
- * @constructor
15
- * @param {Function} executor 执行函数,返回值为 Promise(带有 then 方法)时会进行异步处理。
16
- * @param {Object} [options] 其他选项。
17
- * @param {number} [options.interval=1000] 轮询间隔(毫秒)。
18
- * @param {boolean} [options.breakOnError=false] 执行函数有异常(包括 Promise 的拒绝状态)时是否中断轮询。
19
- * @example
20
- * const polling = new Polling(() => {
21
- * return new Promise((resolve) => {
22
- * setTimeout(() => {
23
- * console.log('executed');
24
- * resolve();
25
- * }, 1000);
26
- * });
27
- * }, {
28
- * interval: 2000
29
- * });
30
- * polling.start();
31
- */
32
- export default class Polling {
33
- constructor(executor, options) {
34
- // 执行函数
35
- this._executor = executor;
36
- // 其他选项
37
- this._options = extend({
38
- interval: 1000,
39
- breakOnError: false
40
- }, options);
41
- // 轮询计时器 id
42
- this._timerId = null;
43
- // 轮询是否已开始
44
- this._started = false;
45
- // 是否正在运行执行函数(针对异步情况)
46
- this._isExecuting = false;
47
- // 是否要在当前轮询之后马上运行执行函数
48
- this._shouldImmediate = false;
49
- }
50
-
51
- // 执行轮询函数
52
- _exec() {
53
- let result;
54
- try {
55
- result = this._executor.call(theGlobal);
56
- } catch (e) {
57
- if (this._options.breakOnError) {
58
- this.stop();
59
- }
60
- }
61
-
62
- if (result && typeof result.then === 'function') {
63
- // 异步情况,在 Promise 回调中继续下一次轮询
64
- this._isExecuting = true;
65
- result.then(() => {
66
- this._isExecuting = false;
67
- this._next();
68
- }, () => {
69
- this._isExecuting = false;
70
- if (this._options.breakOnError) {
71
- this.stop();
72
- } else {
73
- this._next();
74
- }
75
- });
76
-
77
- } else {
78
- // 同步情况,直接执行下一次轮询
79
- this._next();
80
- }
81
- }
82
-
83
- // 下一次轮询
84
- _next() {
85
- if (this._shouldImmediate) {
86
- // 外部调用了 execImmediately,马上执行
87
- this._exec();
88
-
89
- } else if (this._started) {
90
- // 进入下一次轮询
91
- this._timerId = setTimeout(() => {
92
- this._exec();
93
- }, this._options.interval);
94
- }
95
- }
96
-
97
- /**
98
- * 在当前轮询结束后马上执行一次执行函数。
99
- * @method
100
- * @memberof module:polling.Polling.prototype
101
- */
102
- execImmediately() {
103
- // 阻止下次轮询
104
- this._clearTimeout();
105
-
106
- if (this._isExecuting) {
107
- // 如果当前轮询还在运行中,先记录下来,待结束后再执行
108
- this._shouldImmediate = true;
109
- } else {
110
- // 下一次轮询还没开始,直接运行执行函数
111
- this._exec();
112
- }
113
- }
114
-
115
- /**
116
- * 启动轮询。
117
- * @method
118
- * @memberof module:polling.Polling.prototype
119
- */
120
- start() {
121
- this._started = true;
122
- this._exec();
123
- }
124
-
125
- /**
126
- * 停止轮询。
127
- * @method
128
- * @memberof module:polling.Polling.prototype
129
- */
130
- stop() {
131
- this._clearTimeout();
132
- this._started = false;
133
- }
134
-
135
- // 清理计时器
136
- _clearTimeout() {
137
- if (this._timerId) {
138
- clearTimeout(this._timerId);
139
- this._timerId = null;
140
- }
141
- }
142
- }