danholibraryjs 1.11.0 → 2.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.
Files changed (210) hide show
  1. package/README.md +0 -1
  2. package/_package.github-release.json +6 -0
  3. package/_package.npm-release.json +6 -0
  4. package/dist/Classes/DanhoLogger.d.ts +23 -0
  5. package/dist/Classes/DanhoLogger.js +65 -0
  6. package/dist/Classes/Events/Event.d.ts +66 -66
  7. package/dist/Classes/Events/Event.js +114 -114
  8. package/dist/Classes/Events/EventCollection.d.ts +57 -57
  9. package/dist/Classes/Events/EventCollection.js +109 -109
  10. package/dist/Classes/Events/EventEmitter.d.ts +74 -74
  11. package/dist/Classes/Events/EventEmitter.js +97 -97
  12. package/dist/Classes/Events/index.d.ts +3 -3
  13. package/dist/Classes/Events/index.js +19 -19
  14. package/dist/Classes/Time/Date.d.ts +148 -147
  15. package/dist/Classes/Time/Date.js +241 -238
  16. package/dist/Classes/Time/Time.d.ts +66 -65
  17. package/dist/Classes/Time/Time.js +120 -117
  18. package/dist/Classes/Time/TimeProperties.d.ts +3 -3
  19. package/dist/Classes/Time/TimeProperties.js +2 -2
  20. package/dist/Classes/Time/TimeSpan.d.ts +123 -123
  21. package/dist/Classes/Time/TimeSpan.js +179 -179
  22. package/dist/Classes/Time/index.d.ts +4 -4
  23. package/dist/Classes/Time/index.js +20 -20
  24. package/dist/Classes/index.d.ts +4 -3
  25. package/dist/Classes/index.js +20 -19
  26. package/dist/Classes/store.d.ts +75 -75
  27. package/dist/Classes/store.js +84 -84
  28. package/dist/Extensions/Array/array.extension.d.ts +42 -0
  29. package/dist/Extensions/Array/array.extension.js +57 -0
  30. package/dist/Extensions/Array/crud.extension.d.ts +24 -0
  31. package/dist/Extensions/Array/crud.extension.js +28 -0
  32. package/dist/Extensions/Array/index.d.ts +6 -0
  33. package/dist/Extensions/Array/index.js +22 -0
  34. package/dist/Extensions/Array/loop.extension.d.ts +18 -0
  35. package/dist/Extensions/Array/loop.extension.js +23 -0
  36. package/dist/Extensions/Array/random.extension.d.ts +23 -0
  37. package/dist/Extensions/Array/random.extension.js +35 -0
  38. package/dist/Extensions/Array/sort.extension.d.ts +27 -0
  39. package/dist/Extensions/Array/sort.extension.js +31 -0
  40. package/dist/Extensions/Array/string.extension.d.ts +13 -0
  41. package/dist/Extensions/Array/string.extension.js +14 -0
  42. package/dist/Extensions/Function.d.ts +29 -14
  43. package/dist/Extensions/Function.js +23 -10
  44. package/dist/Extensions/Map.d.ts +54 -54
  45. package/dist/Extensions/Map.js +42 -42
  46. package/dist/Extensions/Number.d.ts +13 -0
  47. package/dist/Extensions/Number.js +40 -0
  48. package/dist/Extensions/Object/arrays.extension.d.ts +17 -0
  49. package/dist/Extensions/Object/arrays.extension.js +13 -0
  50. package/dist/Extensions/Object/booleans.extension.d.ts +18 -0
  51. package/dist/Extensions/Object/booleans.extension.js +37 -0
  52. package/dist/Extensions/Object/extracts.extension.d.ts +38 -0
  53. package/dist/Extensions/Object/extracts.extension.js +72 -0
  54. package/dist/Extensions/Object/index.d.ts +4 -49
  55. package/dist/Extensions/Object/index.js +20 -38
  56. package/dist/Extensions/Object/properties.d.ts +28 -28
  57. package/dist/Extensions/Object/properties.extension.d.ts +33 -0
  58. package/dist/Extensions/Object/properties.extension.js +21 -0
  59. package/dist/Extensions/Object/properties.js +20 -20
  60. package/dist/Extensions/String/case.extension.d.ts +12 -0
  61. package/dist/Extensions/String/case.extension.js +55 -0
  62. package/dist/Extensions/String/index.d.ts +1 -0
  63. package/dist/{Functions → Extensions/String}/index.js +17 -21
  64. package/dist/Extensions/index.d.ts +6 -17
  65. package/dist/Extensions/index.js +22 -30
  66. package/dist/Interfaces/ElementOptions.d.ts +15 -15
  67. package/dist/Interfaces/ElementOptions.js +2 -2
  68. package/dist/Interfaces/IReplacement.d.ts +12 -12
  69. package/dist/Interfaces/IReplacement.js +2 -2
  70. package/dist/Interfaces/index.d.ts +2 -2
  71. package/dist/Interfaces/index.js +18 -18
  72. package/dist/Types/Able.d.ts +16 -0
  73. package/dist/Types/Able.js +2 -0
  74. package/dist/Types/Array.d.ts +6 -0
  75. package/dist/Types/Array.js +2 -0
  76. package/dist/Types/BetterTypes.d.ts +9 -9
  77. package/dist/Types/BetterTypes.js +2 -2
  78. package/dist/Types/C#.d.ts +8 -0
  79. package/dist/Types/C#.js +2 -0
  80. package/dist/Types/Date.d.ts +6 -6
  81. package/dist/Types/Date.js +2 -2
  82. package/dist/Types/Events.d.ts +10 -10
  83. package/dist/Types/Events.js +2 -2
  84. package/dist/Types/Function.d.ts +5 -0
  85. package/dist/Types/Function.js +2 -0
  86. package/dist/Types/Object.d.ts +4 -0
  87. package/dist/Types/Object.js +2 -0
  88. package/dist/Types/PropertiesWith.d.ts +34 -13
  89. package/dist/Types/PropertiesWith.js +2 -2
  90. package/dist/Types/String.d.ts +1 -0
  91. package/dist/Types/String.js +2 -0
  92. package/dist/Types/TransformTypes.d.ts +22 -16
  93. package/dist/Types/TransformTypes.js +2 -2
  94. package/dist/Types/index.d.ts +24 -65
  95. package/dist/Types/index.js +27 -21
  96. package/dist/Utils/{ApiUtil → ApiUtils}/ApiTypes.d.ts +15 -15
  97. package/dist/Utils/{ApiUtil → ApiUtils}/ApiTypes.js +15 -15
  98. package/dist/Utils/{ApiUtil → ApiUtils}/RequestUtil.d.ts +19 -19
  99. package/dist/Utils/{ApiUtil → ApiUtils}/RequestUtil.js +73 -73
  100. package/dist/Utils/{ApiUtil → ApiUtils}/index.d.ts +20 -20
  101. package/dist/Utils/{ApiUtil → ApiUtils}/index.js +33 -33
  102. package/dist/Utils/ColorUtils.d.ts +11 -0
  103. package/dist/Utils/ColorUtils.js +93 -0
  104. package/dist/Utils/{FormUtil.d.ts → FormUtils.d.ts} +6 -6
  105. package/dist/Utils/{FormUtil.js → FormUtils.js} +35 -35
  106. package/dist/Utils/NumberUtils.d.ts +1 -0
  107. package/dist/Utils/NumberUtils.js +7 -0
  108. package/dist/Utils/PatcherUtils.d.ts +6 -0
  109. package/dist/Utils/PatcherUtils.js +80 -0
  110. package/dist/Utils/StringUtils.d.ts +3 -0
  111. package/dist/Utils/StringUtils.js +47 -0
  112. package/dist/Utils/TimeUtils/debounce.util.d.ts +22 -0
  113. package/dist/Utils/TimeUtils/debounce.util.js +78 -0
  114. package/dist/Utils/TimeUtils/functions.util.d.ts +4 -0
  115. package/dist/Utils/TimeUtils/functions.util.js +21 -0
  116. package/dist/Utils/TimeUtils/index.d.ts +15 -0
  117. package/dist/Utils/TimeUtils/index.js +34 -0
  118. package/dist/Utils/TimeUtils/throttle.util.d.ts +15 -0
  119. package/dist/Utils/TimeUtils/throttle.util.js +43 -0
  120. package/dist/Utils/index.d.ts +7 -2
  121. package/dist/Utils/index.js +23 -18
  122. package/dist/index.d.ts +4 -5
  123. package/dist/index.js +20 -21
  124. package/docs/Classes.md +78 -3
  125. package/docs/Extensions.md +219 -78
  126. package/docs/Types.md +202 -58
  127. package/docs/index.md +0 -1
  128. package/package.json +4 -2
  129. package/src/Classes/DanhoLogger.ts +78 -0
  130. package/src/Classes/Events/Event.ts +96 -96
  131. package/src/Classes/Events/EventCollection.ts +90 -90
  132. package/src/Classes/Events/EventEmitter.ts +68 -68
  133. package/src/Classes/Time/Date.ts +219 -216
  134. package/src/Classes/Time/Time.ts +109 -104
  135. package/src/Classes/Time/TimeSpan.ts +171 -171
  136. package/src/Classes/index.ts +1 -0
  137. package/src/Classes/store.ts +22 -22
  138. package/src/Extensions/Array/array.extension.ts +103 -0
  139. package/src/Extensions/Array/crud.extension.ts +46 -0
  140. package/src/Extensions/Array/index.ts +6 -0
  141. package/src/Extensions/Array/loop.extension.ts +38 -0
  142. package/src/Extensions/Array/random.extension.ts +56 -0
  143. package/src/Extensions/Array/sort.extension.ts +52 -0
  144. package/src/Extensions/Array/string.extension.ts +22 -0
  145. package/src/Extensions/Function.ts +37 -10
  146. package/src/Extensions/Map.ts +56 -56
  147. package/src/Extensions/Number.ts +50 -0
  148. package/src/Extensions/Object/arrays.extension.ts +27 -0
  149. package/src/Extensions/Object/booleans.extension.ts +46 -0
  150. package/src/Extensions/Object/extracts.extension.ts +102 -0
  151. package/src/Extensions/Object/index.ts +4 -82
  152. package/src/Extensions/Object/properties.extension.ts +59 -0
  153. package/src/Extensions/Object/properties.ts +36 -36
  154. package/src/Extensions/String/case.extension.ts +95 -0
  155. package/src/Extensions/String/index.ts +1 -0
  156. package/src/Extensions/index.ts +3 -21
  157. package/src/Interfaces/ElementOptions.ts +7 -7
  158. package/src/Interfaces/IReplacement.ts +2 -2
  159. package/src/Types/Able.ts +22 -0
  160. package/src/Types/Array.ts +7 -0
  161. package/src/Types/C#.ts +9 -0
  162. package/src/Types/Date.ts +1 -1
  163. package/src/Types/Events.ts +12 -12
  164. package/src/Types/Function.ts +10 -0
  165. package/src/Types/Object.ts +4 -0
  166. package/src/Types/PropertiesWith.ts +35 -4
  167. package/src/Types/String.ts +1 -0
  168. package/src/Types/TransformTypes.ts +21 -13
  169. package/src/Types/index.ts +7 -69
  170. package/src/Utils/{ApiUtil → ApiUtils}/ApiTypes.ts +2 -1
  171. package/src/Utils/{ApiUtil → ApiUtils}/index.ts +1 -1
  172. package/src/Utils/ColorUtils.ts +102 -0
  173. package/src/Utils/{FormUtil.ts → FormUtils.ts} +2 -2
  174. package/src/Utils/NumberUtils.ts +3 -0
  175. package/src/Utils/PatcherUtils.ts +111 -0
  176. package/src/Utils/StringUtils.ts +44 -0
  177. package/src/Utils/TimeUtils/debounce.util.ts +85 -0
  178. package/src/Utils/TimeUtils/functions.util.ts +18 -0
  179. package/src/Utils/TimeUtils/index.ts +9 -0
  180. package/src/Utils/TimeUtils/throttle.util.ts +44 -0
  181. package/src/Utils/index.ts +8 -2
  182. package/src/index.ts +0 -1
  183. package/dist/Extensions/Array.d.ts +0 -52
  184. package/dist/Extensions/Array.js +0 -51
  185. package/dist/Extensions/Document.d.ts +0 -27
  186. package/dist/Extensions/Document.js +0 -32
  187. package/dist/Extensions/String.d.ts +0 -36
  188. package/dist/Extensions/String.js +0 -25
  189. package/dist/Functions/CopyToClipboard.d.ts +0 -7
  190. package/dist/Functions/CopyToClipboard.js +0 -15
  191. package/dist/Functions/GetCSSProperty.d.ts +0 -15
  192. package/dist/Functions/GetCSSProperty.js +0 -26
  193. package/dist/Functions/GetNestedProperty.d.ts +0 -9
  194. package/dist/Functions/GetNestedProperty.js +0 -23
  195. package/dist/Functions/HTMLEvent.d.ts +0 -11
  196. package/dist/Functions/HTMLEvent.js +0 -14
  197. package/dist/Functions/SetNavigationSelected.d.ts +0 -9
  198. package/dist/Functions/SetNavigationSelected.js +0 -25
  199. package/dist/Functions/index.d.ts +0 -5
  200. package/docs/Functions.md +0 -61
  201. package/src/Extensions/Array.ts +0 -95
  202. package/src/Extensions/Document.ts +0 -58
  203. package/src/Extensions/String.ts +0 -54
  204. package/src/Functions/CopyToClipboard.ts +0 -10
  205. package/src/Functions/GetCSSProperty.ts +0 -27
  206. package/src/Functions/GetNestedProperty.ts +0 -29
  207. package/src/Functions/HTMLEvent.ts +0 -13
  208. package/src/Functions/SetNavigationSelected.ts +0 -19
  209. package/src/Functions/index.ts +0 -5
  210. /package/src/Utils/{ApiUtil → ApiUtils}/RequestUtil.ts +0 -0
@@ -2,13 +2,44 @@
2
2
  * Filters all properties from From that has the return type of Type
3
3
  */
4
4
  export type PropertiesWith<Type, From> = {
5
- [Key in keyof From as From[Key] extends Type ? Key : never]: From[Key]
6
- }
5
+ [Key in keyof From as From[Key] extends Type ? Key : never]: From[Key]
6
+ };
7
7
  export default PropertiesWith;
8
8
 
9
9
  /**
10
10
  * Fitlers all properties from From that don't have the return type of Type
11
11
  */
12
12
  export type PropertiesWithout<Type, From> = {
13
- [Key in keyof From as From[Key] extends Type ? never : Key]: From[Key]
14
- }
13
+ [Key in keyof From as From[Key] extends Type ? never : Key]: From[Key]
14
+ };
15
+
16
+ /**
17
+ * GetRepeatedKeys<[
18
+ * { username: string, password: string },
19
+ * { username: number, email: string },
20
+ * ]> // { username: string | number }
21
+ */
22
+ export type GetRepeatedKeys<Types extends Array<any>> = (
23
+ Types extends [infer First, infer Second, ...infer Rest]
24
+ ? First extends object
25
+ ? Second extends object
26
+ ? {
27
+ [Key in Extract<keyof First, keyof Second>]: First[Key] | Second[Key]
28
+ } & GetRepeatedKeys<Rest>
29
+ : {}
30
+ : {}
31
+ : {}
32
+ );
33
+
34
+ /**
35
+ * Situation: Model = Character | Artifact | Domain
36
+ * Type must include generic type T, which is the Model type
37
+ * Type must also include generic type TProps, which is the properties of the Model type. Selected properties of TProps must extract the types of Model whose properties has been selected.
38
+ *
39
+ * Example:
40
+ * type Model = Character | Artifact | Domain
41
+ * Properties<Model, 'name' | 'rarity'>
42
+ *
43
+ * Result: Character | Artifact, because only Character and Artifact have 'name' and 'rarity' properties
44
+ */
45
+ export type ModelWithProps<T, TProps extends (keyof T | string)> = T extends Record<TProps, any> ? T : never;
@@ -0,0 +1 @@
1
+ export type Autocomplete<T> = T | (string & {});
@@ -2,27 +2,35 @@
2
2
  * Converts Start types to Switch types in From type
3
3
  */
4
4
  export type TransformType<From, Start, Switch> = {
5
- [Key in keyof From]: From[Key] extends Start ? Switch : From[Key]
6
- }
5
+ [Key in keyof From]: From[Key] extends Start ? Switch : From[Key]
6
+ };
7
7
 
8
8
  /**
9
9
  * Returns object with properties matching BaseType with types of NewType
10
10
  */
11
- export type TransformTypes<From, BaseType, NewType> = Record<keyof {
12
- [Key in keyof From as From[Key] extends BaseType ? Key : never]: Key
13
- }, NewType>
11
+ export type TransformTypes<From, BaseType, NewType> = Record<keyof {
12
+ [Key in keyof From as From[Key] extends BaseType ? Key : never]: Key
13
+ }, NewType>;
14
14
 
15
15
  //Returns From with properties switched from BaseType to NewType
16
16
  // export type TransformTypes<From, BaseType, NewType> = TransformType<From, BaseType[keyof BaseType], NewType>;
17
17
 
18
18
  export type Json<T> = {
19
- [Key in keyof T]: T[Key] extends object
20
- ? Json<T[Key]>
21
- : T[Key] extends Array<infer U>
22
- ? Array<Json<U>>
23
- : T[Key] extends number | string | boolean | null
24
- ? T[Key]
25
- : string
26
- }
19
+ [Key in keyof T]: T[Key] extends object
20
+ ? Json<T[Key]>
21
+ : T[Key] extends Array<infer U>
22
+ ? Array<Json<U>>
23
+ : T[Key] extends number | string | boolean | null
24
+ ? T[Key]
25
+ : string
26
+ };
27
+
28
+
29
+ /**
30
+ * Type's properties are ReturnType
31
+ */
32
+ export type AllPropsAre<ReturnType> = {
33
+ [key: string]: ReturnType;
34
+ };
27
35
 
28
36
  export default TransformTypes;
@@ -1,46 +1,14 @@
1
+ export * from './Able';
2
+ export * from './Array';
1
3
  export * from './BetterTypes';
4
+ export * from './C#';
2
5
  export * from './Date';
3
6
  export * from './Events';
7
+ export * from './Function';
4
8
  export * from './TransformTypes';
9
+ export * from './Object';
5
10
  export * from './PropertiesWith';
6
-
7
- /**
8
- * Item is single or multiple
9
- */
10
- export type Arrayable<T> = T | Array<T>;
11
-
12
- /**
13
- * Item is function or T
14
- */
15
- export type Functionable<T> = T | (() => T);
16
-
17
- /**
18
- * Item is Promise<T> or T
19
- */
20
- export type Promisable<T> = T | Promise<T>;
21
-
22
- /**
23
- * Item is T or null
24
- */
25
- export type Nullable<T> = T | null;
26
-
27
- /**
28
- * Item cannot be null or undefined
29
- */
30
- export type NonNullable<T> =
31
- T extends null ? never :
32
- T extends undefined ? never :
33
- T;
34
-
35
- /**
36
- * C# Guid representation
37
- */
38
- export type Guid = string;
39
-
40
- /**
41
- * C# TimeSpan representation from JSON
42
- */
43
- export type TimeSpanType = string;
11
+ export * from './String';
44
12
 
45
13
  /**
46
14
  * Used for HTMLElement.append in ElementOptions, Document.createProperElement.
@@ -51,39 +19,9 @@ export type TimeSpanType = string;
51
19
  */
52
20
  export type IElement = HTMLElement | string;
53
21
 
54
- /**
55
- * Return types of T
56
- */
57
- export type ValueOf<T> = T[keyof T];
58
-
59
- /**
60
- * Type's properties are ReturnType
61
- */
62
- export type AllPropsAre<ReturnType> = {
63
- [key: string]: ReturnType
64
- }
65
-
66
22
  /**
67
23
  * string or RegExp.. pretty self-explanatory
68
24
  */
69
25
  export type StringRegex = string | RegExp;
70
26
 
71
- export type If<Boolean extends boolean, True, False> = Boolean extends true ? True : False;
72
-
73
- /**
74
- * GetRepeatedKeys<[
75
- * { username: string, password: string },
76
- * { username: number, email: string },
77
- * ]> // { username: string | number }
78
- */
79
- export type GetRepeatedKeys<Types extends Array<any>> = (
80
- Types extends [infer First, infer Second, ...infer Rest]
81
- ? First extends object
82
- ? Second extends object
83
- ? {
84
- [Key in Extract<keyof First, keyof Second>]: First[Key] | Second[Key]
85
- } & GetRepeatedKeys<Rest>
86
- : {}
87
- : {}
88
- : {}
89
- );
27
+ export type If<Boolean extends boolean, True, False> = Boolean extends true ? True : False;
@@ -1,4 +1,4 @@
1
- // An ApiEndpoint paramter can be either a string or undefined
1
+ // An ApiEndpoint parameter can be either a string or undefined
2
2
  export type TParam = string | undefined;
3
3
 
4
4
  // All possible HTTP methods
@@ -6,6 +6,7 @@ export type HttpMethods =
6
6
  | 'GET'
7
7
  | 'POST'
8
8
  | 'PUT'
9
+ | 'PATCH'
9
10
  | 'DELETE';
10
11
 
11
12
  // Options for the Request function
@@ -1,7 +1,7 @@
1
1
  import { ApiUtilOptions, RequestOptions } from "./ApiTypes";
2
2
  import { Request } from "./RequestUtil";
3
3
 
4
- export class ApiUtil<ApiEndpoints extends string> {
4
+ export class ApiUtils<ApiEndpoints extends string> {
5
5
  protected __baseEndpointDev: string;
6
6
  protected __baseEndpoint?: string;
7
7
  protected __log: boolean;
@@ -0,0 +1,102 @@
1
+ export type RGB = [number, number, number];
2
+ export type Hex = `#${string}`;
3
+ export type ColorType = 'hex' | 'rgb' | 'hsl';
4
+
5
+
6
+ export function convert(value: RGB, to: Exclude<ColorType, 'rgb'>): string;
7
+ export function convert(value: string, from: Exclude<ColorType, 'rgb'>, to: 'rgb'): RGB;
8
+ export function convert(value: string | RGB, fromOrTo: ColorType, to?: ColorType): string | RGB {
9
+ const from = typeof value === 'string' ? fromOrTo : 'rgb';
10
+ const target = typeof value === 'string' ? to : fromOrTo;
11
+
12
+ if (from === target) return value as string;
13
+
14
+ switch (from) {
15
+ case 'hsl': {
16
+ switch (target) {
17
+ case 'hex': return hslToHex(value as string);
18
+ case 'rgb': return hexToRgb(hslToHex(value as string)) as RGB;
19
+ }
20
+ }
21
+ case 'rgb': {
22
+ switch (target) {
23
+ case 'hex': return hslToHex(rgbToHsl(value as RGB))
24
+ case 'hsl': return rgbToHsl(value as RGB);
25
+ }
26
+ }
27
+ case 'hex': {
28
+ switch (target) {
29
+ case 'rgb': return hexToRgb(value as Hex) as RGB;
30
+ case 'hsl': return rgbToHsl(hexToRgb(value as Hex));
31
+ }
32
+ }
33
+ default: return value;
34
+ }
35
+ }
36
+
37
+ export function generateRandomColor(): Hex {
38
+ return `#${Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0')}`;
39
+ }
40
+
41
+ export const ColorUtils = {
42
+ convert,
43
+ generateRandomColor
44
+ };
45
+
46
+ export default ColorUtils;
47
+
48
+ function hslToHex(value?: string): Hex {
49
+ if (!value) return "#000000";
50
+
51
+ const match = value.match(/hsl\((\d+), (\d+)%, (\d+)%\)/);
52
+ if (!match) return value as Hex;
53
+
54
+ let [_, h, s, l] = match.map(Number);
55
+ l /= 100;
56
+ const a = s * Math.min(l, 1 - l) / 100;
57
+ const format = (value: number) => {
58
+ const k = (value + h / 30) % 12;
59
+ const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
60
+ return Math.round(255 * color).toString(16).padStart(2, '0');
61
+ };
62
+ return `#${format(0)}${format(8)}${format(4)}`;
63
+ }
64
+
65
+ function hexToRgb(hex: Hex): RGB {
66
+ if (!hex) return [0, 0, 0];
67
+
68
+ const match = hex.match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
69
+ if (!match) return [0, 0, 0];
70
+
71
+ let colorString = match[0];
72
+
73
+ if (match[0].length === 3) colorString = colorString.split('').map(char => char + char).join('');
74
+
75
+ const integer = parseInt(colorString, 16);
76
+ const r = (integer >> 16) & 0xFF;
77
+ const g = (integer >> 8) & 0xFF;
78
+ const b = integer & 0xFF;
79
+
80
+ return [r, g, b];
81
+ }
82
+
83
+ function rgbToHsl(rgb: RGB): string {
84
+ let [r, g, b] = rgb.map(x => x / 255);
85
+ const max = Math.max(r, g, b), min = Math.min(r, g, b);
86
+ let h = 0, s = 0, l = (max + min) / 2;
87
+
88
+ if (max !== min) {
89
+ const d = max - min;
90
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
91
+
92
+ switch (max) {
93
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
94
+ case g: h = (b - r) / d + 2; break;
95
+ case b: h = (r - g) / d + 4; break;
96
+ }
97
+
98
+ h /= 6;
99
+ }
100
+
101
+ return `hsl(${Math.round(h * 360)}, ${Math.round(s * 100)}%, ${Math.round(l * 100)}%)`;
102
+ }
@@ -15,14 +15,14 @@ export function serializeForm<T extends object>(form: HTMLFormElement, log = fal
15
15
 
16
16
  const name = element.getAttribute('name');
17
17
  if (!name) {
18
- console.error('[DanhoLibraryRJS] [FormUtil]: name attribute is required', { element });
18
+ console.error('[DanhoLibraryJS] [FormUtil]: name attribute is required', { element });
19
19
  throw new Error('name attribute is required');
20
20
  }
21
21
 
22
22
  const value = element.value;
23
23
  if (value === null) console.warn(`${name}.value returned null`, { element });
24
24
 
25
- if (log) console.log(`[DanhoLibraryRJS] [FormUtil]`, { name, value });
25
+ if (log) console.log(`[DanhoLibraryJS] [FormUtil]`, { name, value });
26
26
  acc[name] = /^\d$/.test(value) ? parseInt(value) : value;
27
27
  }
28
28
 
@@ -0,0 +1,3 @@
1
+ export function between(min: number, max: number): number {
2
+ return Math.floor(Math.random() * (max - min + 1)) + min;
3
+ }
@@ -0,0 +1,111 @@
1
+ type PatchEvent = 'before' | 'instead' | 'after';
2
+ type PatcherReplacement<TTarget extends object, TProperty extends keyof TTarget, TPatchEvent extends PatchEvent> = (
3
+ TPatchEvent extends 'before'
4
+ ? TTarget[TProperty] extends (...args: infer TArgs) => any
5
+ ? (...args: TArgs) => TArgs | void
6
+ : (current: TTarget[TProperty], update: TTarget[TProperty]) => TTarget[TProperty] | void
7
+ : TPatchEvent extends 'instead'
8
+ ? TTarget[TProperty] extends (...args: infer TArgs) => infer TReturn
9
+ ? (...args: TArgs) => TReturn
10
+ : (current: TTarget[TProperty], update: TTarget[TProperty]) => TTarget[TProperty]
11
+ : TTarget[TProperty] extends (...args: infer TArgs) => any
12
+ ? (...args: TArgs) => void
13
+ : (previous: TTarget[TProperty], updated: TTarget[TProperty]) => void
14
+ )
15
+
16
+ type Patch = {
17
+ event: PatchEvent;
18
+ replacement: any;
19
+ original: any;
20
+ unpatch: () => void;
21
+ }
22
+ const PATCHES = new Map<object, Map<string | symbol | number, Array<Patch>>>();
23
+
24
+ export function patch<
25
+ TTarget extends object,
26
+ TProperty extends keyof TTarget,
27
+ TPatchEvent extends PatchEvent,
28
+ TPatchReplacement extends PatcherReplacement<TTarget, TProperty, TPatchEvent>
29
+ >(target: TTarget, property: TProperty, event: TPatchEvent, replacement: TPatchReplacement) {
30
+ if (!target || !property || !replacement) return;
31
+ else if (!(property in target)) throw Error(`Property "${String(property)}" does not exist on target`);
32
+
33
+ const original = target[property];
34
+ if (!PATCHES.has(target)) PATCHES.set(target, new Map());
35
+ const targetPatches = PATCHES.get(target)!;
36
+
37
+ if (!targetPatches.has(property)) targetPatches.set(property, []);
38
+
39
+ const unpatch = (() => {
40
+ if (typeof original === 'function') {
41
+ switch (event) {
42
+ case 'before': {
43
+ target[property] = function (...args: any[]) {
44
+ const updatedArgs = (replacement as any).apply(target, args);
45
+ return (original as any).apply(target, updatedArgs || args);
46
+ } as TTarget[TProperty];
47
+ break;
48
+ }
49
+ case 'instead': {
50
+ target[property] = function (...args: any[]) {
51
+ return (replacement as any).apply(target, args);
52
+ } as TTarget[TProperty];
53
+ break;
54
+ }
55
+ case 'after': {
56
+ target[property] = function (...args: any[]) {
57
+ const result = (original as any).apply(target, args);
58
+ (replacement as any).apply(target, args);
59
+ return result;
60
+ } as TTarget[TProperty];
61
+ break;
62
+ }
63
+ }
64
+
65
+ return () => target[property] = original;
66
+ } else {
67
+ let currentValue = target[property];
68
+ const propertyDescriptor = Object.getOwnPropertyDescriptor(target, property);
69
+
70
+ const valuePatch = (update?: TTarget[TProperty]) => {
71
+ update ??= currentValue;
72
+ const result = event !== 'after' ? (replacement as any)(currentValue, update) || currentValue : currentValue;
73
+
74
+ if (event === 'after') (replacement as any)(currentValue, update);
75
+
76
+ return result;
77
+ }
78
+
79
+ Object.defineProperty(target, property, {
80
+ get: () => valuePatch(),
81
+ set: valuePatch,
82
+ });
83
+
84
+ return () => Object.defineProperty(target, property, propertyDescriptor!);
85
+ }
86
+ })();
87
+
88
+ targetPatches.get(property)!.push({ event, replacement, original, unpatch });
89
+ return unpatch;
90
+ }
91
+
92
+ export function unpatch<
93
+ TTarget extends object,
94
+ TProperty extends keyof TTarget
95
+ >(target: TTarget, property: TProperty) {
96
+ const targetPatches = PATCHES.get(target);
97
+ if (!targetPatches?.has(property)) return;
98
+
99
+ targetPatches.get(property)!.forEach(patch => patch.unpatch());
100
+ targetPatches.delete(property);
101
+ }
102
+
103
+ export function unpatchAll() {
104
+ PATCHES.forEach(properties => {
105
+ properties.forEach(patches => {
106
+ patches.forEach(patch => patch.unpatch());
107
+ });
108
+ });
109
+
110
+ PATCHES.clear();
111
+ }
@@ -0,0 +1,44 @@
1
+ export function classNames(...args: Array<any>): string {
2
+ return args.reduce((acc, arg) => {
3
+ if (!arg) return acc;
4
+
5
+ switch (typeof arg) {
6
+ case 'string': {
7
+ acc += arg;
8
+ break;
9
+ }
10
+ case 'object': {
11
+ if (Array.isArray(arg)) {
12
+ acc += classNames(...arg);
13
+ break;
14
+ } else {
15
+ acc += Object.entries(arg).reduce((objAcc, [key, value]) => objAcc + (value ? key : ''), '');
16
+ break;
17
+ }
18
+ }
19
+ default: {
20
+ acc += `${arg}`;
21
+ break;
22
+ }
23
+ }
24
+
25
+ return acc + ' ';
26
+ }, '').trim();
27
+ }
28
+
29
+ export function randomId(length = 16): string {
30
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
31
+ return Array.from({ length }, () => characters.charAt(Math.floor(Math.random() * characters.length))).join('');
32
+ }
33
+
34
+ export function pluralize(countable: number | ArrayLike<any> | Map<any, any>, singular: string, plural?: string): string {
35
+ const count = (
36
+ typeof countable === 'number' ? countable
37
+ : countable instanceof Map ? countable.size
38
+ : countable.length
39
+ );
40
+
41
+ if (count === 1) return singular;
42
+ if (plural) return plural;
43
+ return `${singular}s`;
44
+ }
@@ -0,0 +1,85 @@
1
+ const DebounceManager = {
2
+ timers: new Map<string, number>(),
3
+ abortListeners: new Map<string, () => void>(),
4
+ };
5
+
6
+ /**
7
+ * Delay running the callback until delay milliseconds have passed without the function being called again.
8
+ * If the function is called again before the delay has passed, the timer resets.
9
+ *
10
+ * @param debounceId A unique identifier for the debounce instance. Call with the same ID to reset the timer.
11
+ * @param callback The callback to run after the delay has passed without the function being called again
12
+ * @param delay The delay in milliseconds to wait before running the callback after the last call
13
+ * @param signal Optional AbortSignal to cancel the debounced operation
14
+ * @returns A promise that resolves to the result of the callback when it is eventually called, or rejects if aborted
15
+ */
16
+ export function debounce<T>(debounceId: string, callback: () => T, delay: number, signal?: AbortSignal) {
17
+ const { timers, abortListeners } = DebounceManager;
18
+
19
+ // Clean up existing debounce with the same ID
20
+ if (timers.has(debounceId)) {
21
+ clearTimeout(timers.get(debounceId));
22
+ timers.delete(debounceId);
23
+
24
+ const existingListener = abortListeners.get(debounceId);
25
+ if (existingListener && signal) {
26
+ signal.removeEventListener('abort', existingListener);
27
+ }
28
+ abortListeners.delete(debounceId);
29
+ }
30
+
31
+ const promise = new Promise<T>((resolve, reject) => {
32
+ // Check if already aborted
33
+ if (signal?.aborted) {
34
+ const error = new DOMException('Debounce aborted', 'AbortError');
35
+ reject(error);
36
+ return;
37
+ }
38
+
39
+ const timeoutId = setTimeout(() => {
40
+ timers.delete(debounceId);
41
+ abortListeners.delete(debounceId);
42
+
43
+ try {
44
+ resolve(callback());
45
+ } catch (error) {
46
+ reject(error);
47
+ }
48
+ }, delay);
49
+
50
+ timers.set(debounceId, timeoutId);
51
+
52
+ // Set up abort listener
53
+ if (signal) {
54
+ const abortListener = () => {
55
+ clearTimeout(timeoutId);
56
+ timers.delete(debounceId);
57
+ abortListeners.delete(debounceId);
58
+
59
+ const error = new DOMException('Debounce aborted', 'AbortError');
60
+ reject(error);
61
+ };
62
+
63
+ signal.addEventListener('abort', abortListener, { once: true });
64
+ abortListeners.set(debounceId, abortListener);
65
+ }
66
+ });
67
+
68
+ return promise;
69
+ }
70
+
71
+ /**
72
+ * Wrap a callback in a debounce, allowing it to be called multiple times, but only run after the delay has passed without it being called again
73
+ * @param callback The callback to run after the delay has passed without the function being called again
74
+ * @param delay The delay in milliseconds to wait before running the callback after the last call
75
+ * @returns An object containing the debounced function, an AbortController to cancel operations, and the abort method for convenience
76
+ */
77
+ export function wrapInDebounce<T>(callback: (...args: T[]) => void, delay: number) {
78
+ const controller = new AbortController();
79
+
80
+ return {
81
+ debounced: (...args: T[]) => debounce(Symbol().toString(), () => callback(...args), delay, controller.signal),
82
+ controller,
83
+ abort: () => controller.abort(),
84
+ };
85
+ }
@@ -0,0 +1,18 @@
1
+ export function wait<T>(time: number): Promise<void>;
2
+ export function wait<T>(callback: (...args: any[]) => T, time: number): Promise<T>;
3
+ export function wait<T>(callbackOrTime: ((...args: any[]) => T) | number, time?: number) {
4
+ const callback = typeof callbackOrTime === 'function' ? callbackOrTime : (() => undefined);
5
+ time ??= callbackOrTime as number;
6
+
7
+ return new Promise<T>((resolve, reject) => {
8
+ try { setTimeout(() => resolve(callback() as T), time); }
9
+ catch (err) { reject(err); }
10
+ });
11
+ }
12
+
13
+ export function getUnixTime(date: Date | string): number;
14
+ export function getUnixTime(timestamp: number): number;
15
+ export function getUnixTime(arg: Date | string | number): number {
16
+ const timestamp = typeof arg === 'number' ? arg : new Date(arg).getTime();
17
+ return Math.floor(timestamp / 1000);
18
+ }
@@ -0,0 +1,9 @@
1
+ import * as Debounce from './debounce.util';
2
+ import * as Functions from './functions.util';
3
+ import * as Throttle from './throttle.util';
4
+
5
+ export const TimeUtils = {
6
+ ...Functions,
7
+ ...Debounce,
8
+ ...Throttle,
9
+ };
@@ -0,0 +1,44 @@
1
+ const ThrottleManager = {
2
+ cooldowns: new Map<string, boolean>(),
3
+ results: new Map<string, any>(),
4
+ };
5
+
6
+ /**
7
+ * Allow callback to be run once every cooldown period, regardless of calls
8
+ * @param callback The callback to run
9
+ * @param cooldown The delay to wait before allowing the callback to be called again
10
+ * @returns A throttled version of the callback
11
+ */
12
+ export function throttle<T>(throttleId: string, callback: () => T, cooldown: number) {
13
+ const { cooldowns, results } = ThrottleManager;
14
+
15
+ const isCooldown = cooldowns.get(throttleId) ?? false;
16
+ if (isCooldown) return results.get(throttleId) as T;
17
+
18
+ const result = callback();
19
+
20
+ setTimeout(() => {
21
+ cooldowns.delete(throttleId);
22
+ results.delete(throttleId);
23
+ }, cooldown);
24
+
25
+ cooldowns.set(throttleId, true);
26
+ results.set(throttleId, result);
27
+
28
+ return result;
29
+ }
30
+
31
+ /**
32
+ * Wrap a callback in a throttle, allowing it to be called multiple times, but only run once every cooldown period
33
+ * @param callback The callback to run
34
+ * @param cooldown The delay to wait before allowing the callback to be called again
35
+ * @returns A throttled version of the callback that can be called multiple times, but will only run once every cooldown period
36
+ */
37
+ export function wrapInThrottle<T>(callback: (...args: T[]) => void, cooldown: number) {
38
+ const throttleId = Symbol().toString();
39
+ return (...args: T[]) => throttle(throttleId, () => callback(...args), cooldown);
40
+ }
41
+
42
+ export function isThrottleOnCooldown(throttleId: string) {
43
+ return ThrottleManager.cooldowns.get(throttleId) ?? false;
44
+ }
@@ -1,2 +1,8 @@
1
- export * from './ApiUtil';
2
- export * from './FormUtil';
1
+ export * from './ApiUtils';
2
+ export * from './TimeUtils';
3
+
4
+ export * from './ColorUtils';
5
+ export * from './FormUtils';
6
+ export * from './NumberUtils';
7
+ export * from './PatcherUtils';
8
+ export * from './StringUtils';
package/src/index.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './Classes';
2
2
  export * from './Extensions';
3
- export * from './Functions';
4
3
  export * from './Interfaces';
5
4
  export * from './Types';