🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@danep/utils

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@danep/utils - npm Package Compare versions

Comparing version
1.0.0
to
1.1.0
+23
.eslintrc.cjs
module.exports = {
root: true,
parserOptions: {
sourceType: 'module'
},
env: {
browser: true,
node: true,
es6: true
},
globals: {
it: 'readonly',
expect: 'readonly',
describe: 'readonly'
},
extends: 'standard',
rules: {
indent: ['error', 2],
'linebreak-style': ['error', 'unix'],
quotes: ['error', 'single'],
semi: ['error', 'always']
}
};
import { getValue } from './type.js';
function createCache () {
let cache = null;
return {
get () { return cache; },
set (val) {
cache = val;
return cache;
}
};
}
/**
* @description 传入 promise 的创建函数, 返回一个包装函数, 用于缓存 promise 的值, 默认存储在 returnFn.cache
* @param {function} fn function: promise
* @param {function} cache.get 存储媒介
* @param {function} cache.set 存储媒介
* @returns {function} function: promise
*/
export function promiseCache (fn, cache = createCache()) {
promiseCacheWrap.cache = cache;
function promiseCacheWrap () {
const arg = arguments;
const cacheVal = cache.get(...arg);
if (cacheVal) return Promise.resolve(cacheVal);
else {
return Promise.resolve(
cache.set(
fn(...arg).catch(error => {
cache.set(null);
return Promise.reject(error);
}),
...arg
)
);
}
};
return promiseCacheWrap;
}
/**
* @description 传入 promise 的创建函数, 返回一个包装函数, 额外返回一个取消 promise 的函数
* @param {function} fn function: promise
* @return {function } function: [promise, cancel: function]
*/
export function promiseCancel (fn) {
return function promiseCancelWrap () {
let cancelReject;
const cancelPromise = new Promise((resolve, reject) => {
cancelReject = reject;
});
function cancel (error) {
return cancelReject(error);
}
return [
Promise.race([cancelPromise, fn(...arguments)]),
cancel
];
};
}
/**
* @description 传入 promise 的创建函数, 返回一个包装函数, 会自动取消上一个函数中创建的 promise
* @param {function} fn function: promise
* @return {function} function: promise
*/
export function promiseAutoCancel (fn, error) {
const wrapFn = promiseCancel(fn);
let prevCancel = null;
return function wrapCancel () {
if (prevCancel) prevCancel(getValue(error));
const [promise, cancel] = wrapFn(...arguments);
prevCancel = cancel;
return promise;
};
}
import {
promiseCache,
promiseCancel,
promiseAutoCancel
} from './promise.js';
import { beforeEach, jest } from '@jest/globals';
let promiseCreator;
let fetch;
let resolveFaker;
const param = 'Test';
beforeEach(() => {
const _fetch = jest.fn();
const _resolveFaker = jest.fn();
fetch = _fetch;
resolveFaker = _resolveFaker;
promiseCreator = (param) => new Promise(
(resolve) => {
_fetch(param);
setTimeout(
() => {
_resolveFaker(param);
resolve(param);
},
20
);
}
);
});
describe('promiseCache 测试', () => {
let promiseCacheWrap;
beforeEach(() => {
promiseCacheWrap = promiseCache(promiseCreator);
});
it('首次调用', async () => {
expect(fetch).toHaveBeenCalledTimes(0);
expect(resolveFaker).toHaveBeenCalledTimes(0);
await expect(promiseCacheWrap(param)).resolves.toBe(param);
expect(fetch).toHaveBeenCalledTimes(1);
expect(resolveFaker).toHaveBeenCalledTimes(1);
});
it('获取数据失败', async () => {
expect(fetch).toHaveBeenCalledTimes(0);
expect(resolveFaker).toHaveBeenCalledTimes(0);
let cancel;
const promiseCancelWrap = promiseCancel(promiseCreator);
promiseCacheWrap = promiseCache((...arg) => {
const promiseCancelWrapReturns = promiseCancelWrap(...arg);
cancel = promiseCancelWrapReturns[1];
return promiseCancelWrapReturns[0];
});
setTimeout(() => {
cancel('error');
}, 10);
await expect(promiseCacheWrap(param)).rejects.toBe('error');
expect(fetch).toHaveBeenCalledTimes(1);
expect(resolveFaker).toHaveBeenCalledTimes(0);
});
it('读取缓存', async () => {
expect(fetch).toHaveBeenCalledTimes(0);
expect(resolveFaker).toHaveBeenCalledTimes(0);
const first = promiseCacheWrap(param);
const second = promiseCacheWrap(param);
await expect(first).resolves.toBe(param);
await expect(second).resolves.toBe(param);
expect(first).toBe(second);
expect(fetch).toHaveBeenCalledTimes(1);
expect(resolveFaker).toHaveBeenCalledTimes(1);
const third = promiseCacheWrap(param);
await expect(third).resolves.toBe(param);
expect(third).toBe(second);
expect(fetch).toHaveBeenCalledTimes(1);
expect(resolveFaker).toHaveBeenCalledTimes(1);
});
it('删除缓存', async () => {
expect(fetch).toHaveBeenCalledTimes(0);
expect(resolveFaker).toHaveBeenCalledTimes(0);
await expect(promiseCacheWrap(param)).resolves.toBe(param);
expect(fetch).toHaveBeenCalledTimes(1);
expect(resolveFaker).toHaveBeenCalledTimes(1);
promiseCacheWrap.cache.set(null);
await expect(promiseCacheWrap(param)).resolves.toBe(param);
expect(fetch).toHaveBeenCalledTimes(2);
expect(resolveFaker).toHaveBeenCalledTimes(2);
});
it('自定义cache', async () => {
function createCache () {
let cache = {};
return {
get (id) { return cache[id]; },
set (val, id) {
if (!val && !id) cache = {};
else cache[id] = val;
return val;
}
};
}
promiseCacheWrap = promiseCache(promiseCreator, createCache());
await expect(promiseCacheWrap(1)).resolves.toBe(1);
expect(fetch).toHaveBeenCalledTimes(1);
expect(resolveFaker).toHaveBeenCalledTimes(1);
await expect(promiseCacheWrap(2)).resolves.toBe(2);
expect(fetch).toHaveBeenCalledTimes(2);
expect(resolveFaker).toHaveBeenCalledTimes(2);
await expect(promiseCacheWrap(1)).resolves.toBe(1);
expect(fetch).toHaveBeenCalledTimes(2);
expect(resolveFaker).toHaveBeenCalledTimes(2);
promiseCacheWrap.cache.set(null, 1);
await expect(promiseCacheWrap(1)).resolves.toBe(1);
expect(fetch).toHaveBeenCalledTimes(3);
expect(resolveFaker).toHaveBeenCalledTimes(3);
});
});
describe('promiseCancel 测试', () => {
let promiseCreatorWrap,
promiseCreatorWrapReturns;
beforeEach(() => {
promiseCreatorWrap = promiseCancel(promiseCreator);
promiseCreatorWrapReturns = promiseCreatorWrap(param);
});
it('return 数据结构', () => {
expect(fetch).toHaveBeenCalledTimes(1);
expect(promiseCreatorWrap).toBeInstanceOf(Function);
expect(promiseCreatorWrapReturns).toBeInstanceOf(Array);
expect(promiseCreatorWrapReturns[0]).toBeInstanceOf(Promise);
expect(promiseCreatorWrapReturns[1]).toBeInstanceOf(Function);
});
it('取消', async () => {
const error = 'Cancel';
setTimeout(() => {
promiseCreatorWrapReturns[1](error);
}, 10);
await expect(promiseCreatorWrapReturns[0]).rejects.toBe(error);
expect(resolveFaker).not.toHaveBeenCalled();
});
it('不取消', async () => {
await expect(promiseCreatorWrapReturns[0]).resolves.toBe(param);
});
});
describe('promiseAutoCancel 测试', () => {
const error = 'Cancel';
let promiseAutoCancelWrap;
beforeEach(() => {
promiseAutoCancelWrap = promiseAutoCancel(promiseCreator, error);
});
it('调用一次', async () => {
expect(resolveFaker).toHaveBeenCalledTimes(0);
expect(fetch).toHaveBeenCalledTimes(0);
await expect(promiseAutoCancelWrap(param)).resolves.toBe(param);
expect(resolveFaker).toHaveBeenCalledTimes(1);
expect(fetch).toHaveBeenCalledTimes(1);
});
it('在首次结束后再次调用', async () => {
expect(resolveFaker).toHaveBeenCalledTimes(0);
expect(fetch).toHaveBeenCalledTimes(0);
await expect(promiseAutoCancelWrap(param)).resolves.toBe(param);
expect(resolveFaker).toHaveBeenCalledTimes(1);
expect(fetch).toHaveBeenCalledTimes(1);
await expect(promiseAutoCancelWrap(param)).resolves.toBe(param);
expect(resolveFaker).toHaveBeenCalledTimes(2);
expect(fetch).toHaveBeenCalledTimes(2);
});
it('在首次结束前再次调用', async () => {
expect(resolveFaker).toHaveBeenCalledTimes(0);
expect(fetch).toHaveBeenCalledTimes(0);
const first = promiseAutoCancelWrap(param);
expect(fetch).toHaveBeenCalledTimes(1);
const second = promiseAutoCancelWrap(param);
await expect(first).rejects.toBe(error);
expect(resolveFaker).toHaveBeenCalledTimes(0);
expect(fetch).toHaveBeenCalledTimes(2);
await expect(second).resolves.toBe(param);
expect(resolveFaker).toHaveBeenCalledTimes(2);
expect(fetch).toHaveBeenCalledTimes(2);
});
});
/**
* @description 是否是有长度的数组
* @param {any} val any
* @returns {boolean} boolean
*/
export function isValidArray (val) {
return Array.isArray(val) && val.length !== 0;
}
/**
* @description 如果参数是参数,返回函数的返回值,否则返回参数
* @param {any} valOrFn any
* @returns {any}
*/
export function getValue (valOrFn) {
return typeof valOrFn === 'function' ? valOrFn() : valOrFn;
}
/**
* @description 是否是 promise
* @param {any} val any
* @returns {boolean} boolean
*/
export function isPromise (val) {
return (
val !== undefined &&
val !== null &&
typeof val.then === 'function' &&
typeof val.catch === 'function'
);
}
import {
isValidArray,
getValue,
isPromise
} from './type.js';
describe('isValidArray 测试', () => {
it('非数组', () => {
expect(isValidArray(null)).toBe(false);
expect(isValidArray(undefined)).toBe(false);
expect(isValidArray(1)).toBe(false);
expect(isValidArray('')).toBe(false);
});
it('空数组', () => {
expect(isValidArray([])).toBe(false);
});
it('数组', () => {
expect(isValidArray([1])).toBe(true);
expect(isValidArray(new Array(6))).toBe(true);
});
});
describe('getValue 测试', () => {
it('数值', () => {
expect(getValue(null)).toBe(null);
expect(getValue(undefined)).toBe(undefined);
expect(getValue(1)).toBe(1);
expect(getValue('')).toBe('');
});
it('函数', () => {
expect(getValue(() => null)).toBe(null);
expect(getValue(() => undefined)).toBe(undefined);
expect(getValue(() => 1)).toBe(1);
expect(getValue(() => '')).toBe('');
});
});
describe('isPromise 测试', () => {
it('非 Promise', () => {
expect(isPromise(null)).toBe(false);
expect(isPromise(undefined)).toBe(false);
expect(isPromise(NaN)).toBe(false);
expect(isPromise(1)).toBe(false);
expect(isPromise('')).toBe(false);
});
it('类 Promise', () => {
expect(isPromise({ then: () => {} })).toBe(false);
expect(isPromise({ catch: () => {} })).toBe(false);
expect(isPromise({ then: () => {}, catch: () => {} })).toBe(true);
});
it('Promise', () => {
expect(isPromise(new Promise(() => {}))).toBe(true);
expect(isPromise(Promise.resolve())).toBe(true);
});
});
+17
-10

@@ -1,12 +0,19 @@

export default {
transform: {},
collectCoverage: true,
coverageThreshold: {
global: {
branches: 100,
functions: 100,
lines: 100,
statements: 100
import path from 'path';
export default () => {
const file = process.argv.find(arg => /\.test\.js$/.test(arg));
return {
rootDir: './',
transform: {},
collectCoverage: true,
collectCoverageFrom: file ? [path.relative('./', file.replace(/\.test\.js$/, '.js'))] : null,
coverageThreshold: {
global: {
branches: 100,
functions: 100,
lines: 100,
statements: 100
}
}
}
};
};
{
"name": "@danep/utils",
"version": "1.0.0",
"version": "1.1.0",
"description": "简单的工具库",
"type": "module",
"main": "index.js",
"main": "./src/index.js",
"exports": "./src/index.js",
"scripts": {
"test": "node --experimental-vm-modules node_modules/.bin/jest"
"test": "node --experimental-vm-modules node_modules/.bin/jest",
"eslint": "eslint src/*.js --fix"
},

@@ -14,4 +15,26 @@ "author": "autumnLeaves0",

"devDependencies": {
"jest": "^26.6.3"
"eslint": "^7.17.0",
"eslint-config-standard": "^16.0.2",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"husky": "^4.3.7",
"jest": "^26.6.3",
"lint-staged": "^10.5.3"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"src/**/*.test.js": [
"eslint --fix",
"npm run test"
],
"src/**/*!(*.test).js": [
"eslint --fix",
"npm run test -- --findRelatedTests"
]
}
}

@@ -1,16 +0,16 @@

export function dateFormat(date, fmt) {
var o = {
"Y+": date.getFullYear(), //年
"M+": date.getMonth() + 1, //月份
"D+": date.getDate(), //日
"h+": date.getHours(), //小时
"m+": date.getMinutes(), //分
"s+": date.getSeconds(), //秒
"q+": Math.floor((date.getMonth() + 3) / 3), //季度
"x+": date.getMilliseconds() //毫秒
export function dateFormat (date, fmt) {
const o = {
'Y+': date.getFullYear(), // 年
'M+': date.getMonth() + 1, // 月份
'D+': date.getDate(), // 日
'h+': date.getHours(), // 小时
'm+': date.getMinutes(), // 分
's+': date.getSeconds(), // 秒
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
'x+': date.getMilliseconds() // 毫秒
};
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, ("" + o[k]).padStart(RegExp.$1.length, 0));
for (const k in o) {
if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, ('' + o[k]).padStart(RegExp.$1.length, 0));
}
return fmt;
}
}

@@ -5,3 +5,3 @@ import { dateFormat } from './dateFormat.js';

it('YYYY年MM月DD日 hh点mm分ss秒xxx 季度q', () => {
var str = dateFormat(new Date('2000/3/5 12:13:4:800'), 'YYYY年MM月DD日 hh点mm分ss秒xxx 季度q')
const str = dateFormat(new Date('2000/3/5 12:13:4:800'), 'YYYY年MM月DD日 hh点mm分ss秒xxx 季度q');
expect(str).toBe('2000年03月05日 12点13分04秒800 季度1');

@@ -11,5 +11,5 @@ });

it('Y年M月D日 h点m分s秒x ', () => {
var str = dateFormat(new Date('2000/3/5 12:13:4:800'), 'Y年M月D日 h点m分s秒x')
const str = dateFormat(new Date('2000/3/5 12:13:4:800'), 'Y年M月D日 h点m分s秒x');
expect(str).toBe('2000年3月5日 12点13分4秒800');
});
})
});

@@ -1,2 +0,4 @@

export { dateFormat } from './dateFormat.js'
export { urlParse } from './urlParse.js'
export * from './dateFormat.js';
export * from './urlParse.js';
export * from './type.js';
export * from './promise.js';

@@ -1,10 +0,11 @@

export function urlParse(url) {
if (/^https?:\/\/[^?]+\??([^#]*)/.test(url)){ url = RegExp.$1 || ''
console.log( url, RegExp.$1,RegExp.$2,RegExp.$3)}
var reg = /([^&=?]+)=?([^&=?]*?)(&|$|#.*)/g
var o = {}
export function urlParse (url) {
if (/^https?:\/\/[^?]+\??([^#]*)/.test(url)) {
url = RegExp.$1 || '';
}
const reg = /([^&=?]+)=?([^&=?]*?)(&|$|#.*)/g;
const o = {};
while (reg.test(url)) {
o[RegExp.$1] = decodeURIComponent(RegExp.$2) || 'true'
o[RegExp.$1] = decodeURIComponent(RegExp.$2) || 'true';
}
return o;
}
}

@@ -5,18 +5,17 @@ import { urlParse } from './urlParse.js';

it('普通解析', () => {
var o = urlParse('www.baidu.com?a=1&b=2&c=3#hash')
let o = urlParse('www.baidu.com?a=1&b=2&c=3#hash');
expect(o).toEqual({ a: '1', b: '2', c: '3' });
var o = urlParse('?a=1&b=2&c=3#hash')
o = urlParse('?a=1&b=2&c=3#hash');
expect(o).toEqual({ a: '1', b: '2', c: '3' });
var o = urlParse('a=1&b=2&c=3#hash')
o = urlParse('a=1&b=2&c=3#hash');
expect(o).toEqual({ a: '1', b: '2', c: '3' });
var o = urlParse('http://www.baidu.com')
o = urlParse('http://www.baidu.com');
expect(o).toEqual({});
});
it('参数解码', () => {
var o = urlParse('www.baidu.com?a=%E5%93%88')
const o = urlParse('www.baidu.com?a=%E5%93%88');
expect(o).toEqual({ a: '哈' });

@@ -26,5 +25,5 @@ });

it('空字符串解析成true', () => {
var o = urlParse('www.baidu.com?a&b=&c=3')
const o = urlParse('www.baidu.com?a&b=&c=3');
expect(o).toEqual({ a: 'true', b: 'true', c: '3' });
});
})
});