@react-fabric/utilities 1.0.0-beta.8 → 1.0.1
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/dist/cjs/css/boundingBox.js +72 -0
- package/dist/cjs/css/cn.js +39 -0
- package/dist/cjs/css/imageColorset.js +96 -0
- package/dist/cjs/data/countries.js +98 -0
- package/dist/cjs/{_fileType.js → data/fileType.js} +37 -19
- package/dist/cjs/data/format.js +136 -0
- package/dist/cjs/helpers/debounce.js +63 -0
- package/dist/cjs/{useLogger.js → helpers/getLogger.js} +96 -96
- package/dist/cjs/helpers/lonlat.js +99 -0
- package/dist/cjs/index.js +99 -76
- package/dist/cjs/lists/dedupe.js +54 -0
- package/dist/cjs/lists/flatten.js +66 -0
- package/dist/cjs/{_getByPath.js → lists/getByPath.js} +58 -37
- package/dist/cjs/lists/groupBy.js +49 -0
- package/dist/cjs/matchers/compare.js +70 -0
- package/dist/cjs/matchers/isEmpty.js +34 -0
- package/dist/cjs/matchers/isEqual.js +82 -0
- package/dist/cjs/matchers/nullChecks.js +61 -0
- package/dist/cjs/matchers/typeChecks.js +127 -0
- package/dist/cjs/strings/ascii.js +105 -0
- package/dist/cjs/strings/hash.js +75 -0
- package/dist/cjs/strings/interpolate.js +47 -0
- package/dist/cjs/strings/matchString.js +54 -0
- package/dist/cjs/strings/template.js +48 -0
- package/dist/cjs/strings/tokenize.js +83 -0
- package/dist/cjs/utils/mergeRefs.js +56 -0
- package/dist/esm/css/boundingBox.js +71 -0
- package/dist/esm/css/cn.js +39 -0
- package/dist/esm/css/imageColorset.js +96 -0
- package/dist/esm/data/countries.js +98 -0
- package/dist/esm/{_fileType.js → data/fileType.js} +37 -19
- package/dist/esm/data/format.js +138 -0
- package/dist/esm/helpers/debounce.js +63 -0
- package/dist/esm/{useLogger.js → helpers/getLogger.js} +96 -96
- package/dist/esm/helpers/lonlat.js +97 -0
- package/dist/esm/index.js +54 -36
- package/dist/esm/lists/dedupe.js +54 -0
- package/dist/esm/lists/flatten.js +65 -0
- package/dist/esm/{_getByPath.js → lists/getByPath.js} +50 -29
- package/dist/esm/lists/groupBy.js +49 -0
- package/dist/esm/matchers/compare.js +70 -0
- package/dist/esm/matchers/isEmpty.js +34 -0
- package/dist/esm/matchers/isEqual.js +82 -0
- package/dist/esm/matchers/nullChecks.js +58 -0
- package/dist/esm/matchers/typeChecks.js +119 -0
- package/dist/esm/strings/ascii.js +105 -0
- package/dist/esm/strings/hash.js +73 -0
- package/dist/esm/strings/interpolate.js +47 -0
- package/dist/esm/strings/matchString.js +54 -0
- package/dist/esm/strings/template.js +48 -0
- package/dist/esm/strings/tokenize.js +82 -0
- package/dist/esm/utils/mergeRefs.js +56 -0
- package/dist/types/css/boundingBox.d.ts +46 -0
- package/dist/types/css/cn.d.ts +26 -0
- package/dist/types/css/imageColorset.d.ts +37 -0
- package/dist/types/data/countries.d.ts +136 -0
- package/dist/types/{_fileType.d.ts → data/fileType.d.ts} +41 -1
- package/dist/types/data/format.d.ts +122 -0
- package/dist/types/helpers/debounce.d.ts +38 -0
- package/dist/types/helpers/getLogger.d.ts +49 -0
- package/dist/types/helpers/lonlat.d.ts +48 -0
- package/dist/types/index.d.ts +54 -20
- package/dist/types/lists/dedupe.d.ts +36 -0
- package/dist/types/lists/flatten.d.ts +47 -0
- package/dist/types/lists/getByPath.d.ts +45 -0
- package/dist/types/lists/groupBy.d.ts +36 -0
- package/dist/types/matchers/compare.d.ts +38 -0
- package/dist/types/matchers/isEmpty.d.ts +38 -0
- package/dist/types/matchers/isEqual.d.ts +39 -0
- package/dist/types/matchers/nullChecks.d.ts +43 -0
- package/dist/types/matchers/typeChecks.d.ts +107 -0
- package/dist/types/strings/ascii.d.ts +34 -0
- package/dist/types/strings/hash.d.ts +46 -0
- package/dist/types/strings/interpolate.d.ts +34 -0
- package/dist/types/strings/matchString.d.ts +41 -0
- package/dist/types/strings/template.d.ts +35 -0
- package/dist/types/strings/tokenize.d.ts +44 -0
- package/dist/types/utils/mergeRefs.d.ts +36 -0
- package/package.json +13 -11
- package/src/css/boundingBox.ts +80 -0
- package/src/css/cn.ts +32 -0
- package/src/css/imageColorset.ts +97 -0
- package/src/data/countries.ts +126 -0
- package/src/{_fileType.ts → data/fileType.ts} +72 -89
- package/src/data/format.ts +192 -0
- package/src/helpers/debounce.ts +49 -0
- package/src/{useLogger.ts → helpers/getLogger.ts} +52 -101
- package/src/helpers/lonlat.ts +124 -0
- package/src/index.ts +57 -37
- package/src/lists/dedupe.ts +46 -0
- package/src/lists/flatten.ts +56 -0
- package/src/lists/getByPath.ts +122 -0
- package/src/lists/groupBy.ts +47 -0
- package/src/matchers/compare.ts +64 -0
- package/src/matchers/isEmpty.ts +54 -0
- package/src/matchers/isEqual.ts +71 -0
- package/src/matchers/nullChecks.ts +55 -0
- package/src/matchers/typeChecks.ts +146 -0
- package/src/strings/ascii.ts +100 -0
- package/src/strings/hash.ts +68 -0
- package/src/strings/interpolate.ts +42 -0
- package/src/strings/matchString.ts +49 -0
- package/src/strings/template.ts +43 -0
- package/src/strings/tokenize.ts +77 -0
- package/src/utils/mergeRefs.ts +47 -0
- package/src/{yup.ts → utils/yup.ts} +3 -3
- package/dist/cjs/_ascii.js +0 -76
- package/dist/cjs/_boundingBox.js +0 -59
- package/dist/cjs/_countries.js +0 -2805
- package/dist/cjs/_debounce.js +0 -53
- package/dist/cjs/_dedupe.js +0 -63
- package/dist/cjs/_fetch.js +0 -128
- package/dist/cjs/_format.js +0 -118
- package/dist/cjs/_hash.js +0 -67
- package/dist/cjs/_interpolate.js +0 -47
- package/dist/cjs/_isEqual.js +0 -108
- package/dist/cjs/_isType.js +0 -98
- package/dist/cjs/_mergeRefs.js +0 -40
- package/dist/cjs/_tokenize.js +0 -67
- package/dist/cjs/getImageColorset.js +0 -70
- package/dist/esm/_ascii.js +0 -76
- package/dist/esm/_boundingBox.js +0 -58
- package/dist/esm/_countries.js +0 -2805
- package/dist/esm/_debounce.js +0 -53
- package/dist/esm/_dedupe.js +0 -60
- package/dist/esm/_fetch.js +0 -128
- package/dist/esm/_format.js +0 -120
- package/dist/esm/_hash.js +0 -65
- package/dist/esm/_interpolate.js +0 -46
- package/dist/esm/_isEqual.js +0 -106
- package/dist/esm/_isType.js +0 -85
- package/dist/esm/_mergeRefs.js +0 -40
- package/dist/esm/_tokenize.js +0 -66
- package/dist/esm/getImageColorset.js +0 -70
- package/dist/types/_ascii.d.ts +0 -5
- package/dist/types/_boundingBox.d.ts +0 -10
- package/dist/types/_countries.d.ts +0 -85
- package/dist/types/_debounce.d.ts +0 -8
- package/dist/types/_dedupe.d.ts +0 -4
- package/dist/types/_fetch.d.ts +0 -23
- package/dist/types/_format.d.ts +0 -27
- package/dist/types/_getByPath.d.ts +0 -10
- package/dist/types/_hash.d.ts +0 -16
- package/dist/types/_interpolate.d.ts +0 -6
- package/dist/types/_isEqual.d.ts +0 -15
- package/dist/types/_isType.d.ts +0 -14
- package/dist/types/_mergeRefs.d.ts +0 -1
- package/dist/types/_tokenize.d.ts +0 -8
- package/dist/types/getImageColorset.d.ts +0 -1
- package/dist/types/useLogger.d.ts +0 -25
- package/src/_ascii.ts +0 -93
- package/src/_boundingBox.ts +0 -72
- package/src/_countries.ts +0 -3046
- package/src/_debounce.ts +0 -42
- package/src/_dedupe.ts +0 -56
- package/src/_fetch.ts +0 -109
- package/src/_format.ts +0 -141
- package/src/_getByPath.ts +0 -108
- package/src/_hash.ts +0 -62
- package/src/_interpolate.ts +0 -42
- package/src/_isEqual.ts +0 -102
- package/src/_isType.ts +0 -105
- package/src/_mergeRefs.ts +0 -33
- package/src/_tokenize.ts +0 -69
- package/src/getImageColorset.ts +0 -81
- /package/dist/cjs/{yup.js → utils/yup.js} +0 -0
- /package/dist/esm/{yup.js → utils/yup.js} +0 -0
- /package/dist/types/{yup.d.ts → utils/yup.d.ts} +0 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Fabric
|
|
3
|
+
* @version 1.0.0
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright 2024 Adarsh Pastakia
|
|
6
|
+
*
|
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
* furnished to do so, subject to the following conditions:
|
|
13
|
+
*
|
|
14
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
* copies or substantial portions of the Software.
|
|
16
|
+
*
|
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
* SOFTWARE.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { differenceInDays, format as dtformat, parseISO } from "date-fns";
|
|
27
|
+
import { parsePhoneNumberFromString, type CountryCode } from "libphonenumber-js";
|
|
28
|
+
import numeral from "numeral";
|
|
29
|
+
import Countries from "../data/countries";
|
|
30
|
+
import { isEmpty } from "../matchers/isEmpty";
|
|
31
|
+
import { isNil } from "../matchers/nullChecks";
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Format utility functions for various data types.
|
|
35
|
+
* This namespace provides methods to format phone numbers, numbers, bytes, percentages, dates, and durations.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
export namespace Format {
|
|
39
|
+
function getPhone(value: string, country: string) {
|
|
40
|
+
const phone = value.match(/^[0+]/) != null ? value.replace(/^00/, "+") : `+${value}`;
|
|
41
|
+
const number = parsePhoneNumberFromString(phone, country as CountryCode);
|
|
42
|
+
/* istanbul ignore next */
|
|
43
|
+
return (
|
|
44
|
+
number ?? {
|
|
45
|
+
country: "",
|
|
46
|
+
formatInternational: () => value,
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function numberFormat(number?: string | number, format = "0,0[.]00a") {
|
|
52
|
+
if (isNil(number)) {
|
|
53
|
+
return "";
|
|
54
|
+
}
|
|
55
|
+
const prefix = `${number}`.startsWith("+") ? "+" : "";
|
|
56
|
+
return prefix + numeral(number).format(format);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function makeDuration(value: number, fmt = "HH:mm:ss.SSS") {
|
|
60
|
+
if (!isNaN(value)) {
|
|
61
|
+
const days = differenceInDays(value, 0);
|
|
62
|
+
const prefix = days > 0 ? `${days}d:` : "";
|
|
63
|
+
let time = dtformat(parseISO(new Date(value).toISOString().replace("Z", "")), fmt);
|
|
64
|
+
if (!prefix) time = time.replace(/^00:/, "");
|
|
65
|
+
return `${prefix}${time}`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Format phone number with country flag or emoji.
|
|
71
|
+
* It takes a phone number string, a country code, and a boolean to indicate whether to use CSS classes for flags.
|
|
72
|
+
* If the phone number is empty, less than 6 characters, or does not match the regex for valid phone numbers,
|
|
73
|
+
* it returns the original value.
|
|
74
|
+
* If the phone number is valid, it formats the phone number using `libphonenumber-js` and returns it with the country flag or emoji.
|
|
75
|
+
* The country flag is represented as a CSS class, and the emoji is obtained from the `Countries` module.
|
|
76
|
+
*
|
|
77
|
+
* @param {string} value - The phone number to format.
|
|
78
|
+
* @param {string} country - The country code to use for formatting.
|
|
79
|
+
* @param {boolean} useCss - Whether to use CSS classes for flags.
|
|
80
|
+
* @returns {string} The formatted phone number with country flag or emoji.
|
|
81
|
+
*/
|
|
82
|
+
export function phone(value?: string, country = "AE", useCss = false) {
|
|
83
|
+
if (isEmpty(value) || value.length < 6 || !/^[\d+\s\-()]+$/.test(value)) return value;
|
|
84
|
+
const phone = getPhone(value, country);
|
|
85
|
+
/* istanbul ignore next */
|
|
86
|
+
return `${useCss ? `<span class="iconify-color circle-flags--${phone.country}"></span>` : Countries.emoji(phone.country ?? "")} ${phone.formatInternational()}`;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Format number using `numeral`.
|
|
90
|
+
* It takes a number or string and a format string, and returns the formatted number.
|
|
91
|
+
* If the number is undefined or null, it returns an empty string.
|
|
92
|
+
* If the number starts with a '+', it retains the '+' sign in the formatted output.
|
|
93
|
+
* This function is useful for displaying numbers in a human-readable format,
|
|
94
|
+
* such as for financial data, statistics, or any numerical representation.
|
|
95
|
+
*
|
|
96
|
+
* @param {string | number} number - number or string to format
|
|
97
|
+
* @param {string} [format] - optional format string, defaults to "0,0[.]00a"
|
|
98
|
+
* @returns {string} formatted number
|
|
99
|
+
*/
|
|
100
|
+
export function number(number?: string | number, format?: string) {
|
|
101
|
+
return numberFormat(number, format);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Format bytes using `numeral`.
|
|
105
|
+
* It takes a number or string and returns the formatted bytes.
|
|
106
|
+
* If the number is undefined or null, it returns an empty string.
|
|
107
|
+
* If the number starts with a '+', it retains the '+' sign in the formatted output.
|
|
108
|
+
* This function is useful for displaying file sizes or data transfer amounts in a human-readable format.
|
|
109
|
+
*
|
|
110
|
+
* @param {string | number} number - number or string to format
|
|
111
|
+
* @returns {string} formatted bytes
|
|
112
|
+
*/
|
|
113
|
+
export function bytes(number?: string | number) {
|
|
114
|
+
return numberFormat(number, "0,0[.]00b");
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Format percentage using `numeral`.
|
|
118
|
+
* It takes a number or string and returns the formatted percentage.
|
|
119
|
+
* If the number is undefined or null, it returns an empty string.
|
|
120
|
+
* If the number starts with a '+', it retains the '+' sign in the formatted output.
|
|
121
|
+
*
|
|
122
|
+
* @param {string | number} number - number or string to format
|
|
123
|
+
* @returns {string} formatted percentage
|
|
124
|
+
*/
|
|
125
|
+
export function percent(number?: string | number) {
|
|
126
|
+
return numberFormat(number, "0,0[.]00%");
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Format date using `date-fns`.
|
|
130
|
+
* It takes a date (as a Date object, string, or number) and a format string.
|
|
131
|
+
* If the date is undefined or null, it returns an empty string.
|
|
132
|
+
* If the date is a valid date, it formats it using the provided format string.
|
|
133
|
+
* Format defaults to "d-M-y" if not provided.
|
|
134
|
+
*
|
|
135
|
+
* @param {date | string | number} date - Date object, string, or number to format
|
|
136
|
+
* @typedef {string} format - Optional format string, defaults to "d-M-y"
|
|
137
|
+
* @returns {string} - Formatted date string
|
|
138
|
+
*/
|
|
139
|
+
export function date(date?: Date | string | number, format = "d-M-y") {
|
|
140
|
+
return date ? dtformat(new Date(date), format) : "";
|
|
141
|
+
}
|
|
142
|
+
/** ***************** format time duration from total seconds/milliseconds *******************/
|
|
143
|
+
/**
|
|
144
|
+
* Format time duration with milliseconds
|
|
145
|
+
* This function takes a number or string representing a duration in seconds or milliseconds,
|
|
146
|
+
* and returns a formatted string in the format "HH:mm:ss.SSS".
|
|
147
|
+
* If the input is undefined or null, it returns "00:00.000".
|
|
148
|
+
* If the input is Infinity, it returns "∞".
|
|
149
|
+
* The function also accepts an optional boolean parameter `isFraction` to indicate whether the input is in seconds (true) or milliseconds (false).
|
|
150
|
+
* If `isFraction` is true, the input is multiplied by 1000 to convert seconds to milliseconds.
|
|
151
|
+
* The function uses the `makeDuration` helper function to format the duration.
|
|
152
|
+
*
|
|
153
|
+
* @param {string | number} number - The duration to format, can be a string or number.
|
|
154
|
+
* @param {boolean} isFraction - Optional parameter to indicate if the input is in seconds (true) or milliseconds (false).
|
|
155
|
+
* @returns {string} - The formatted duration string.
|
|
156
|
+
*/
|
|
157
|
+
export function duration(number?: string | number, isFraction?: boolean) {
|
|
158
|
+
if (isNil(number)) {
|
|
159
|
+
return "00:00.000";
|
|
160
|
+
}
|
|
161
|
+
if (number === Infinity) {
|
|
162
|
+
return "∞";
|
|
163
|
+
}
|
|
164
|
+
const value = parseFloat(`${number}`) * (isFraction ? 1000 : 1);
|
|
165
|
+
return makeDuration(value) ?? "00:00.000";
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Format time duration in seconds
|
|
169
|
+
* This function takes a number or string representing a duration in seconds,
|
|
170
|
+
* and returns a formatted string in the format "HH:mm:ss".
|
|
171
|
+
* If the input is undefined or null, it returns "00:00".
|
|
172
|
+
* If the input is Infinity, it returns "∞".
|
|
173
|
+
* The function also accepts an optional boolean parameter `isFraction` to indicate whether the input is in seconds (true) or milliseconds (false).
|
|
174
|
+
* If `isFraction` is true, the input is multiplied by 1000 to convert seconds to milliseconds.
|
|
175
|
+
* The function uses the `makeDuration` helper function to format the duration.
|
|
176
|
+
* This function is useful for displaying durations in a human-readable format, such as for timers or elapsed time.
|
|
177
|
+
*
|
|
178
|
+
* @param {string | number} number - The duration to format, can be a string or number.
|
|
179
|
+
* @param {boolean} isFraction - Optional parameter to indicate if the input is in seconds (true) or milliseconds (false).
|
|
180
|
+
* @returns {string} - The formatted duration string.
|
|
181
|
+
*/
|
|
182
|
+
export function durationSeconds(number?: string | number, isFraction?: boolean) {
|
|
183
|
+
if (isNil(number)) {
|
|
184
|
+
return "00:00";
|
|
185
|
+
}
|
|
186
|
+
if (number === Infinity) {
|
|
187
|
+
return "∞";
|
|
188
|
+
}
|
|
189
|
+
const value = parseFloat(`${number}`) * (isFraction ? 1000 : 1);
|
|
190
|
+
return makeDuration(value, "HH:mm:ss") ?? "00:00";
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Fabric
|
|
3
|
+
* @version 1.0.0
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright 2024 Adarsh Pastakia
|
|
6
|
+
*
|
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
* furnished to do so, subject to the following conditions:
|
|
13
|
+
*
|
|
14
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
* copies or substantial portions of the Software.
|
|
16
|
+
*
|
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
* SOFTWARE.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/* istanbul ignore file */
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Debounce function to limit the rate at which a function can fire.
|
|
30
|
+
* It will delay the execution of the function until after a specified timeout
|
|
31
|
+
* has elapsed since the last time the function was invoked.
|
|
32
|
+
*
|
|
33
|
+
* @param fn - The function to debounce.
|
|
34
|
+
* @param timeout - The number of milliseconds to wait before invoking the function.
|
|
35
|
+
* @returns A debounced version of the function that can be called with any arguments.
|
|
36
|
+
* The debounced function also has a `cancel` method to clear the timeout.
|
|
37
|
+
*/
|
|
38
|
+
export function debounce(fn: (...rest: AnyObject[]) => unknown, timeout = 500) {
|
|
39
|
+
/** ***************** create debounce timer id using callback hash *******************/
|
|
40
|
+
let _timer: number;
|
|
41
|
+
|
|
42
|
+
/** ***************** return debounced function *******************/
|
|
43
|
+
const cb = (...args: AnyObject[]) => {
|
|
44
|
+
clearTimeout(_timer);
|
|
45
|
+
if (typeof window !== "undefined") _timer = window.setTimeout(() => fn?.(...(args as unknown[])), timeout);
|
|
46
|
+
};
|
|
47
|
+
cb.cancel = () => clearTimeout(_timer);
|
|
48
|
+
return cb;
|
|
49
|
+
}
|
|
@@ -1,24 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
2
|
* React Fabric
|
|
3
|
-
* @version
|
|
4
|
-
*
|
|
3
|
+
* @version 1.0.0
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright 2024 Adarsh Pastakia
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
7
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
* in the Software without restriction, including without limitation the rights
|
|
10
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
* furnished to do so, subject to the following conditions:
|
|
8
13
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
12
|
-
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
13
|
-
* subject to the following conditions:
|
|
14
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
* copies or substantial portions of the Software.
|
|
14
16
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
17
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
* SOFTWARE.
|
|
22
24
|
*/
|
|
23
25
|
|
|
24
26
|
interface LogDetail {
|
|
@@ -28,12 +30,12 @@ interface LogDetail {
|
|
|
28
30
|
totalTime?: number;
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
OFF,
|
|
33
|
-
WARNING,
|
|
34
|
-
INFO,
|
|
35
|
-
DEBUG,
|
|
36
|
-
}
|
|
33
|
+
const LOG_LEVEL = {
|
|
34
|
+
OFF: 0,
|
|
35
|
+
WARNING: 1,
|
|
36
|
+
INFO: 2,
|
|
37
|
+
DEBUG: 3,
|
|
38
|
+
};
|
|
37
39
|
|
|
38
40
|
/* istanbul ignore file */
|
|
39
41
|
|
|
@@ -51,71 +53,38 @@ const NODE = {
|
|
|
51
53
|
logLevel() {
|
|
52
54
|
return (
|
|
53
55
|
// @ts-expect-error ignore
|
|
54
|
-
global.LOG_LEVEL ??
|
|
55
|
-
(process.env.NODE_ENV !== "production"
|
|
56
|
-
? LOG_LEVEL.DEBUG
|
|
57
|
-
: LOG_LEVEL.WARNING)
|
|
56
|
+
(global.LOG_LEVEL as unknown as number) ?? (process.env.NODE_ENV !== "production" ? LOG_LEVEL.DEBUG : LOG_LEVEL.WARNING)
|
|
58
57
|
);
|
|
59
58
|
},
|
|
60
59
|
|
|
61
|
-
makeLog(
|
|
62
|
-
level: string,
|
|
63
|
-
{ process, module, duration, totalTime }: LogDetail = {},
|
|
64
|
-
) {
|
|
60
|
+
makeLog(level: string, { process, module, duration, totalTime }: LogDetail = {}) {
|
|
65
61
|
const ret = [];
|
|
66
62
|
if (process) ret.push(`${this.PROCESS}Process: ${process}${this.RESET}`);
|
|
67
63
|
if (module) ret.push(`${this.PROCESS}Module: ${module}${this.RESET}`);
|
|
68
|
-
if (duration)
|
|
69
|
-
|
|
70
|
-
if (module)
|
|
71
|
-
ret.push(`${this.DURATION}TotalTime: ${totalTime}${this.RESET}`);
|
|
64
|
+
if (duration) ret.push(`${this.DURATION}Duration: ${duration}${this.RESET}`);
|
|
65
|
+
if (module) ret.push(`${this.DURATION}TotalTime: ${totalTime}${this.RESET}`);
|
|
72
66
|
|
|
73
|
-
return [
|
|
74
|
-
`[${this.TIME}${new Date().toISOString()}${this.RESET}] ${level}`,
|
|
75
|
-
ret.join(" "),
|
|
76
|
-
]
|
|
77
|
-
.filter(Boolean)
|
|
78
|
-
.join("\n");
|
|
67
|
+
return [`[${this.TIME}${new Date().toISOString()}${this.RESET}] ${level}`, ret.join(" ")].filter(Boolean).join("\n");
|
|
79
68
|
},
|
|
80
69
|
|
|
81
70
|
log(msg: string, opts: LogDetail, ...rest: unknown[]) {
|
|
82
71
|
if (+this.logLevel() < LOG_LEVEL.DEBUG) return;
|
|
83
|
-
console.log(
|
|
84
|
-
this.makeLog(`${this.LOG}LOG${this.RESET}`, opts),
|
|
85
|
-
`\n${msg}\n`,
|
|
86
|
-
...rest,
|
|
87
|
-
);
|
|
72
|
+
console.log(this.makeLog(`${this.LOG}LOG${this.RESET}`, opts), `\n${msg}\n`, ...rest);
|
|
88
73
|
},
|
|
89
74
|
debug(msg: string, opts: LogDetail, ...rest: unknown[]) {
|
|
90
75
|
if (+this.logLevel() < LOG_LEVEL.DEBUG) return;
|
|
91
|
-
console.debug(
|
|
92
|
-
this.makeLog(`${this.DEBUG}DEBUG${this.RESET}`, opts),
|
|
93
|
-
`\n${msg}\n`,
|
|
94
|
-
...rest,
|
|
95
|
-
);
|
|
76
|
+
console.debug(this.makeLog(`${this.DEBUG}DEBUG${this.RESET}`, opts), `\n${msg}\n`, ...rest);
|
|
96
77
|
},
|
|
97
78
|
info(msg: string, opts: LogDetail, ...rest: unknown[]) {
|
|
98
79
|
if (+this.logLevel() < LOG_LEVEL.INFO) return;
|
|
99
|
-
console.info(
|
|
100
|
-
this.makeLog(`${this.INFO}INFO${this.RESET}`, opts),
|
|
101
|
-
`\n${msg}\n`,
|
|
102
|
-
...rest,
|
|
103
|
-
);
|
|
80
|
+
console.info(this.makeLog(`${this.INFO}INFO${this.RESET}`, opts), `\n${msg}\n`, ...rest);
|
|
104
81
|
},
|
|
105
82
|
error(msg: string, opts: LogDetail, ...rest: unknown[]) {
|
|
106
|
-
console.error(
|
|
107
|
-
this.makeLog(`${this.ERROR}ERROR${this.RESET}`, opts),
|
|
108
|
-
`\n${msg}\n`,
|
|
109
|
-
...rest,
|
|
110
|
-
);
|
|
83
|
+
console.error(this.makeLog(`${this.ERROR}ERROR${this.RESET}`, opts), `\n${msg}\n`, ...rest);
|
|
111
84
|
},
|
|
112
85
|
warning(msg: string, opts: LogDetail, ...rest: unknown[]) {
|
|
113
86
|
if (+this.logLevel() < LOG_LEVEL.WARNING) return;
|
|
114
|
-
console.warn(
|
|
115
|
-
this.makeLog(`${this.WARNING}WARNING${this.RESET}`, opts),
|
|
116
|
-
`\n${msg}\n`,
|
|
117
|
-
...rest,
|
|
118
|
-
);
|
|
87
|
+
console.warn(this.makeLog(`${this.WARNING}WARNING${this.RESET}`, opts), `\n${msg}\n`, ...rest);
|
|
119
88
|
},
|
|
120
89
|
};
|
|
121
90
|
|
|
@@ -132,23 +101,14 @@ const BROWSER = {
|
|
|
132
101
|
logLevel() {
|
|
133
102
|
return (
|
|
134
103
|
// @ts-expect-error ignore
|
|
135
|
-
(typeof window !== "undefined" ? window.LOG_LEVEL : undefined) ??
|
|
136
|
-
(process.env.NODE_ENV !== "production"
|
|
137
|
-
? LOG_LEVEL.DEBUG
|
|
138
|
-
: LOG_LEVEL.WARNING)
|
|
104
|
+
(typeof window !== "undefined" ? (window.LOG_LEVEL as number) : undefined) ??
|
|
105
|
+
(process.env.NODE_ENV !== "production" ? LOG_LEVEL.DEBUG : LOG_LEVEL.WARNING)
|
|
139
106
|
);
|
|
140
107
|
},
|
|
141
108
|
|
|
142
|
-
makeLog(
|
|
143
|
-
level: string,
|
|
144
|
-
color: string,
|
|
145
|
-
{ process, module, duration, totalTime }: LogDetail = {},
|
|
146
|
-
) {
|
|
109
|
+
makeLog(level: string, color: string, { process, module, duration, totalTime }: LogDetail = {}) {
|
|
147
110
|
const ret = [];
|
|
148
|
-
const colors = [
|
|
149
|
-
`color:${this.TIME};font-weight:bold;`,
|
|
150
|
-
`color:${color};font-weight:bold;`,
|
|
151
|
-
];
|
|
111
|
+
const colors = [`color:${this.TIME};font-weight:bold;`, `color:${color};font-weight:bold;`];
|
|
152
112
|
if (module) ret.push(`%cModule: ${module}`);
|
|
153
113
|
if (process) ret.push(`%cProcess: ${process}`);
|
|
154
114
|
if (duration) ret.push(`%cDuration: ${duration}`);
|
|
@@ -158,12 +118,7 @@ const BROWSER = {
|
|
|
158
118
|
if (duration) colors.push(`color:${this.DURATION}`);
|
|
159
119
|
if (module) colors.push(`color:${this.DURATION}`);
|
|
160
120
|
|
|
161
|
-
return [
|
|
162
|
-
[`%c[${new Date().toISOString()}] ${level}`, ret.join(" ")]
|
|
163
|
-
.filter(Boolean)
|
|
164
|
-
.join("\n"),
|
|
165
|
-
colors,
|
|
166
|
-
];
|
|
121
|
+
return [[`%c[${new Date().toISOString()}] ${level}`, ret.join(" ")].filter(Boolean).join("\n"), colors];
|
|
167
122
|
},
|
|
168
123
|
|
|
169
124
|
log(msg: string, opts: LogDetail, ...rest: unknown[]) {
|
|
@@ -198,9 +153,9 @@ const logger = () => {
|
|
|
198
153
|
};
|
|
199
154
|
|
|
200
155
|
/**
|
|
201
|
-
*
|
|
156
|
+
* Returns a logger object with log/debug/info/error/warning methods, adapted for Node or browser. Optionally takes a module name.
|
|
202
157
|
*/
|
|
203
|
-
export const
|
|
158
|
+
export const getLogger = (mod?: string) => ({
|
|
204
159
|
timer(process: string) {
|
|
205
160
|
const startTime = new Date().getTime();
|
|
206
161
|
let nextTime = new Date().getTime();
|
|
@@ -278,27 +233,23 @@ export const useLogger = (mod?: string) => ({
|
|
|
278
233
|
};
|
|
279
234
|
},
|
|
280
235
|
|
|
281
|
-
log(msg: string,
|
|
282
|
-
logger()?.log(msg, opts, ...rest);
|
|
236
|
+
log(msg: string, opts: LogDetail, ...rest: unknown[]) {
|
|
237
|
+
logger()?.log(msg, { module: mod, ...opts }, ...rest);
|
|
283
238
|
},
|
|
284
239
|
|
|
285
|
-
debug(msg: string,
|
|
286
|
-
logger()?.debug(msg, opts, ...rest);
|
|
240
|
+
debug(msg: string, opts: LogDetail, ...rest: unknown[]) {
|
|
241
|
+
logger()?.debug(msg, { module: mod, ...opts }, ...rest);
|
|
287
242
|
},
|
|
288
243
|
|
|
289
|
-
info(msg: string,
|
|
290
|
-
logger()?.info(msg, opts, ...rest);
|
|
244
|
+
info(msg: string, opts: LogDetail, ...rest: unknown[]) {
|
|
245
|
+
logger()?.info(msg, { module: mod, ...opts }, ...rest);
|
|
291
246
|
},
|
|
292
247
|
|
|
293
|
-
error(msg: string,
|
|
294
|
-
logger()?.error(msg, opts, ...rest);
|
|
248
|
+
error(msg: string, opts: LogDetail, ...rest: unknown[]) {
|
|
249
|
+
logger()?.error(msg, { module: mod, ...opts }, ...rest);
|
|
295
250
|
},
|
|
296
251
|
|
|
297
|
-
warning(
|
|
298
|
-
msg:
|
|
299
|
-
{ module = mod, ...opts }: LogDetail,
|
|
300
|
-
...rest: unknown[]
|
|
301
|
-
) {
|
|
302
|
-
logger()?.warning(msg, opts, ...rest);
|
|
252
|
+
warning(msg: string, opts: LogDetail, ...rest: unknown[]) {
|
|
253
|
+
logger()?.warning(msg, { module: mod, ...opts }, ...rest);
|
|
303
254
|
},
|
|
304
255
|
});
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* React Fabric
|
|
3
|
+
* @version: 1.0.0
|
|
4
|
+
*
|
|
5
|
+
*
|
|
6
|
+
* The MIT License (MIT)
|
|
7
|
+
* Copyright (c) 2025 Adarsh Pastakia
|
|
8
|
+
*
|
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
|
10
|
+
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
11
|
+
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
12
|
+
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
13
|
+
* subject to the following conditions:
|
|
14
|
+
*
|
|
15
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
16
|
+
* portions of the Software.
|
|
17
|
+
*
|
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
19
|
+
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
20
|
+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
+
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { isEmpty } from "../matchers/isEmpty";
|
|
25
|
+
import { isArray, isObject, isString } from "../matchers/typeChecks";
|
|
26
|
+
|
|
27
|
+
export type LngLatLike =
|
|
28
|
+
| {
|
|
29
|
+
lng: number;
|
|
30
|
+
lat: number;
|
|
31
|
+
}
|
|
32
|
+
| {
|
|
33
|
+
lon: number;
|
|
34
|
+
lat: number;
|
|
35
|
+
}
|
|
36
|
+
| {
|
|
37
|
+
longitude: number;
|
|
38
|
+
latitude: number;
|
|
39
|
+
}
|
|
40
|
+
| [lon: number | string, lat: number | string]
|
|
41
|
+
| [lon: number | string, lat: number | string, z: number | string]
|
|
42
|
+
| string;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Convert a decimal degree coordinate to Degrees, Minutes, Seconds (DMS) format.
|
|
46
|
+
* Takes a single coordinate value and returns a formatted string with direction
|
|
47
|
+
* indicators (N/S for latitude, E/W for longitude).
|
|
48
|
+
*
|
|
49
|
+
* @param {number} coord - The decimal degree coordinate to convert.
|
|
50
|
+
* @param {boolean} [isLat=false] - Whether this is a latitude coordinate (affects direction suffix).
|
|
51
|
+
* @returns {string} A string in the format `"degrees˚minutes'seconds" Direction` (e.g., `"40˚42'51.36"N"`).
|
|
52
|
+
*/
|
|
53
|
+
function convertToDMS(coord: number, isLat = false) {
|
|
54
|
+
const degree = Math.floor(Math.abs(coord));
|
|
55
|
+
const hour = (Math.abs(coord) - degree) * 60;
|
|
56
|
+
const minute = (hour - Math.floor(hour)) * 60;
|
|
57
|
+
|
|
58
|
+
return `${degree}˚${Math.floor(hour)}'${minute.toFixed(2)}"${coord < 0 ? (isLat ? "S" : "W") : isLat ? "N" : "E"}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Convert various formats of longitude and latitude to a tuple of [lon, lat].
|
|
63
|
+
* This function supports:
|
|
64
|
+
* - Arrays with two or three elements (e.g., [lon, lat] or [lon, lat, alt])
|
|
65
|
+
* - Objects with properties `lng`, `lat`, `lon`, or `longitude` and `latitude`
|
|
66
|
+
* - Strings in the format "lat,lon"
|
|
67
|
+
* The function will return a tuple of numbers [lon, lat].
|
|
68
|
+
*
|
|
69
|
+
* @param {LngLatLike} lonLat - The input longitude and latitude in various formats.
|
|
70
|
+
* @returns { [lon: number, lat: number] } A tuple of [lon, lat] where lon and lat are numbers.
|
|
71
|
+
* @throws Error if the input is not a valid format.
|
|
72
|
+
*/
|
|
73
|
+
export function convertToLonLat(lonLat: LngLatLike): [lon: number, lat: number] {
|
|
74
|
+
if (isEmpty(lonLat)) {
|
|
75
|
+
throw Error("Invalid geo coordinates");
|
|
76
|
+
}
|
|
77
|
+
if ((isArray(lonLat) && lonLat.length === 2) || (isArray(lonLat) && lonLat.length === 3)) {
|
|
78
|
+
return [Number(lonLat[0]), Number(lonLat[1])];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (isObject(lonLat)) {
|
|
82
|
+
if ("longitude" in lonLat) {
|
|
83
|
+
return [lonLat.longitude, lonLat.latitude];
|
|
84
|
+
}
|
|
85
|
+
return ["lon" in lonLat ? lonLat.lon : lonLat.lng, lonLat.lat];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (isString(lonLat)) {
|
|
89
|
+
const [lat, lon] = lonLat.split(",");
|
|
90
|
+
if (!isNaN(+lat) && !isNaN(+lon)) return [+lon, +lat];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
throw Error("Invalid geo coordinates");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function getLatitudeLongitude(lonLat: LngLatLike): { latitude: number; longitude: number } {
|
|
97
|
+
const [lon, lat] = convertToLonLat(lonLat);
|
|
98
|
+
return { latitude: lat, longitude: lon };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Convert a latitude and longitude to a human-readable text format.
|
|
103
|
+
* This function takes a latitude and longitude in various formats and
|
|
104
|
+
* returns a string in the format "degrees˚minutes'seconds" with direction (N/S, E/W).
|
|
105
|
+
*
|
|
106
|
+
* This function supports:
|
|
107
|
+
*
|
|
108
|
+
* - Objects with properties `lng`, `lat`, `lon`, or `longitude` and `latitude`
|
|
109
|
+
* - Arrays with two or three elements (e.g., [lon, lat] or [lon, lat, alt])
|
|
110
|
+
* - Strings in the format "lat,lon"
|
|
111
|
+
*
|
|
112
|
+
* @param {LngLatLike} latlon - The latitude and longitude in various formats.
|
|
113
|
+
* @returns {string} A string representation of the location in DMS format.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```jsx
|
|
117
|
+
* const location = getLocationAsText({ lat: 40.7128, lng: -74.0060 });
|
|
118
|
+
* console.log(location); // "40˚42'51.36"N, 74˚0'21.60"W"
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
export function getLocationAsText(latlon: LngLatLike) {
|
|
122
|
+
const [lon, lat] = convertToLonLat(latlon);
|
|
123
|
+
return `${convertToDMS(lat, true)}, ${convertToDMS(lon)}`;
|
|
124
|
+
}
|