Skip to content

Commit

Permalink
added some more functions
Browse files Browse the repository at this point in the history
  • Loading branch information
irzhywau committed Feb 26, 2022
1 parent ac078f1 commit 849fb4e
Show file tree
Hide file tree
Showing 16 changed files with 363 additions and 15 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# OpenZhy Utilities #

Utilities for typescript frontend development
Utilities for typescript frontend development

## Installation ##
`npm i -S @open-zhy/utils`
OR
`yarn add @open-zhy/utils`
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@open-zhy/utils",
"version": "0.1.0",
"version": "0.1.1",
"description": "Utilities for typescript frontend development",
"keywords": [
"utilities"
Expand Down
21 changes: 21 additions & 0 deletions src/array.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
/**
* Find intersections of 2 array
*
* @param arr1
* @param arr2
* @returns Array of all values that share both arrays
*/
export const arrayIntersect = <T extends unknown>(
arr1: T[],
arr2: T[]
) => arr1.filter((a1: T) => arr2.includes(a1));

/**
* Remove an item from array by its index
*
* @param source
* @param index
* @returns
*/
export const removeByIndex = <T>(source: Array<T>, index: number): Array<T> => {
const temp: Array<T> = [...source];
temp.splice(index, 1);

return temp;
};
File renamed without changes.
35 changes: 33 additions & 2 deletions src/async.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
import type { RetryOptions } from 'src/types'
export interface RetryOptions {
/**
* Number of attempts to process when function execution fails
*/
retries?: number;

/**
* Interval between 2 attempts
*/
interval?: number;
backoffFactor?: number;
}

/**
* Make a pause in an async context
*
* @param duration
* @returns
*/
export const wait = (duration: number) => new Promise((resolve) => setTimeout(resolve, duration));

const defaultRetryOptions = {
Expand All @@ -20,6 +37,13 @@ const onlyDefined = (values: Record<string, any>): Record<string, any> => Object
}, {}
);

/**
* Implementing a basic retrial flow
*
* @param fn
* @param o
* @returns
*/
export const retry = <T extends unknown>(
fn: () => Promise<T>,
o?: RetryOptions
Expand All @@ -45,7 +69,14 @@ export const retry = <T extends unknown>(
});
});

export const promiseAllStepN = <T extends unknown>(n: number, list: any[]) => {
/**
* Execute in parallel a set of batch function
*
* @param n
* @param list
* @returns
*/
export const promiseAllStepN = <T extends unknown>(n: number, list: any[]): Promise<T[]> => {
if (list.length === 0) {
return Promise.resolve([]);
}
Expand Down
21 changes: 21 additions & 0 deletions src/bytesToSize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Convert a bytes number to human readable value
*
* @param bytes
* @param decimals
* @returns
*/
const bytesToSize = (bytes: number, decimals = 2): string => {
if (bytes === 0) {
return '0 Bytes';
}

const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));

return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
};

export default bytesToSize;
6 changes: 5 additions & 1 deletion src/device.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
// eslint-disable-next-line max-len
/**
* Test whether the browser is on mobile
*
* @returns
*/
export const isMobile = (): boolean => /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Mobile/i.test(navigator.userAgent);
6 changes: 6 additions & 0 deletions src/email.ts
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
/**
* Check whether a string is a valid email
*
* @param email `
* @returns
*/
export const isValidEmail = (email: string) => (/^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/ig).test(email);
39 changes: 37 additions & 2 deletions src/formatNumber.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,63 @@
import replace from 'lodash.replace';
import numeral from 'numeral';

// ----------------------------------------------------------------------

/**
* Format a number to currency
*
* @param number
* @returns
*/
export function fCurrency(number: number) {
return numeral(number).format(Number.isInteger(number) ? '$0,0' : '$0,0.00');
}

/**
* Format a number to percent
*
* @param number
* @returns
*/
export function fPercent(number: number) {
return numeral(number / 100).format('0.0%');
}

/**
* Enforce number formatting
*
* @param number
* @returns
*/
export function fNumber(number: number) {
return numeral(number).format();
}

/**
* Shorten a number
*
* @param number
* @returns
*/
export function fShortenNumber(number: number) {
return replace(numeral(number).format('0.00a'), '.00', '');
}

/**
* Format number
*
* @param number
* @returns
*/
export function fData(number: number) {
return numeral(number).format('0.0 b');
}

/**
* Make user-friendly number like 1.3K, 3.6M
*
* @param num
* @param digits
* @returns
*/
export const nFormat = (num: number, digits = 0): string => {
if (num <= 1) {
return num.toFixed(digits);
Expand Down
2 changes: 0 additions & 2 deletions src/formatTime.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { format, formatDistanceToNow } from 'date-fns';

// ----------------------------------------------------------------------

declare type DateType = string | number | Date;

export function fDate(date: DateType) {
Expand Down
16 changes: 15 additions & 1 deletion src/images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ export const defaultCliperFactory = (...CANVAS_SIZE: number[]) => (
);
};

/**
* Clip avatar to square
*
* @param file
* @param sz
* @returns
*/
export const clipAvatar = (file: File, sz: number) => new Promise<{data: string; image: HTMLImageElement}>(
(resolve) => {
const cliper = defaultCliperFactory(sz);
Expand All @@ -52,6 +59,13 @@ export const clipAvatar = (file: File, sz: number) => new Promise<{data: string;
}
);

/**
* Clip cover image to a rectangle
*
* @param file
* @param sz
* @returns
*/
export const clipCover = (file: File, sz: number[]) => new Promise<{data: string; image: HTMLImageElement}>(
(resolve) => {
const r0 = sz[0] / (sz[1] || sz[0]);
Expand Down Expand Up @@ -85,7 +99,7 @@ export const clipCover = (file: File, sz: number[]) => new Promise<{data: string

const data = await cliper(img, x, y, ...size);

return resolve({ image: img, data });
return resolve({ data, image: img });
};
}
);
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
export * from './async';
export * from './array';
export * from './bytesToSize';
export * from './formatNumber';
export * from './formatTime';
export * from './images';
export * from './email';
export * from './storage';
export * from './device';
export * from './waitable';
16 changes: 11 additions & 5 deletions src/md5.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
/* eslint-disable */
/**
* MD5 (Message-Digest Algorithm)
* http://www.webtoolkit.info/
* */

* Calculate md5 value of a string
* --------------------------------------------------
*
* MD5 (Message-Digest Algorithm)
* http://www.webtoolkit.info/
*
* --------------------------------------------------
*
* @param strValue
* @returns
*/
export function md5(strValue: string) {
function RotateLeft(lValue: number, iShiftBits: number) {
return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
Expand Down
13 changes: 13 additions & 0 deletions src/storage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import merge from 'lodash.merge';

/**
* Load a json value from localstorage
*
* @param key
* @param defaultValue
* @returns
*/
export const loadJsonValue = <T extends Record<string, unknown>>(key: string, defaultValue?: T): T => {
const textJson = localStorage.getItem(key);
if (!textJson) {
Expand All @@ -13,6 +20,12 @@ export const loadJsonValue = <T extends Record<string, unknown>>(key: string, de
}
};

/**
* Save a json data into localstorage
*
* @param key
* @param value
*/
export const storeJsonValue = <T extends Record<string, unknown>>(key: string, value: T) => {
localStorage.setItem(key, JSON.stringify(value));
};
62 changes: 62 additions & 0 deletions src/string.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Create a random string that can be used as Id
*
* @param factor
* @returns
*/
export const generateId = (factor: number = 16): string => {
const arr = new Uint8Array(factor);
window.crypto.getRandomValues(arr);
return Array.from(arr, (v) => v.toString(16).padStart(2, '0')).join('');
};

/**
* Capitablize a string
*
* @param text
* @returns
*/
export const capitalize = (text: string): string => {
if ((text || '').length === 0) {
return '';
}

return text[0].toUpperCase() + text.substring(1);
};

/**
* Truncate a string
*
* @param str
* @param num
* @returns
*/
export const truncate = (str: string, num: number = 100): string => {
// If the length of str is less than or equal to num
// just return str--don't truncate it.
if (str.length <= num) {
return str;
}

// Return str truncated with '...' concatenated to the end of str.
return `${str.slice(0, num)}...`;
};

/**
* Simplified text parser
*
* @param originalText
* @param config
* @returns
*/
export const textParser = (originalText: string, config: any[] = []): { [key: string]: string } => {
const result: { [key: string]: string } = {};

let rest: string = originalText;
config.forEach(({ key, search }: { key: string; search: string }) => {
result[key] = rest.split(search).pop();
rest = rest.replace(result[key], '').replace(search, '');
});

return result;
};
Loading

0 comments on commit 849fb4e

Please sign in to comment.