magic-utils-yonava 1.0.2 → 1.0.4

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 (115) hide show
  1. package/dist/clone.d.ts +9 -0
  2. package/dist/clone.js +15 -0
  3. package/dist/clone.test.d.ts +1 -0
  4. package/dist/clone.test.js +42 -0
  5. package/dist/colors.d.ts +522 -0
  6. package/{src/colors.ts → dist/colors.js} +224 -274
  7. package/dist/ctx/index.d.ts +10 -0
  8. package/dist/ctx/index.js +19 -0
  9. package/dist/debounce.d.ts +9 -0
  10. package/{src/debounce.ts → dist/debounce.js} +6 -6
  11. package/dist/debugging.d.ts +2 -0
  12. package/dist/debugging.js +21 -0
  13. package/dist/deepDelta/delta.test.d.ts +1 -0
  14. package/dist/deepDelta/delta.test.js +114 -0
  15. package/dist/deepDelta/index.d.ts +8 -0
  16. package/dist/deepDelta/index.js +40 -0
  17. package/dist/deepMerge.d.ts +16 -0
  18. package/dist/deepMerge.js +32 -0
  19. package/dist/deepMerge.test.d.ts +1 -0
  20. package/dist/deepMerge.test.js +68 -0
  21. package/dist/fps.d.ts +6 -0
  22. package/dist/fps.js +51 -0
  23. package/dist/fracDecConverter/index.d.ts +9 -0
  24. package/dist/fracDecConverter/index.js +34 -0
  25. package/dist/hashing.d.ts +2 -0
  26. package/dist/hashing.js +7 -0
  27. package/dist/id.d.ts +5 -0
  28. package/dist/index.d.ts +1 -0
  29. package/dist/index.js +1 -0
  30. package/dist/localStorage.d.ts +37 -0
  31. package/dist/localStorage.js +22 -0
  32. package/dist/math.d.ts +60 -0
  33. package/{src/math.ts → dist/math.js} +28 -32
  34. package/dist/math.test.d.ts +1 -0
  35. package/dist/math.test.js +42 -0
  36. package/{src/maybeGetter/index.ts → dist/maybeGetter/index.d.ts} +3 -18
  37. package/dist/maybeGetter/index.js +15 -0
  38. package/dist/mouse.d.ts +8 -0
  39. package/{src/mouse.ts → dist/mouse.js} +4 -4
  40. package/dist/random.d.ts +19 -0
  41. package/dist/random.js +21 -0
  42. package/dist/sets.d.ts +8 -0
  43. package/{src/sets.ts → dist/sets.js} +2 -2
  44. package/dist/string.d.ts +21 -0
  45. package/{src/string.ts → dist/string.js} +11 -11
  46. package/dist/string.test.d.ts +1 -0
  47. package/dist/string.test.js +14 -0
  48. package/{src/types.ts → dist/types.d.ts} +13 -38
  49. package/dist/types.js +1 -0
  50. package/dist/utils/clone.d.ts +9 -0
  51. package/dist/utils/clone.js +15 -0
  52. package/dist/utils/clone.test.d.ts +1 -0
  53. package/dist/utils/clone.test.js +42 -0
  54. package/dist/utils/colors.d.ts +522 -0
  55. package/dist/utils/colors.js +517 -0
  56. package/dist/utils/ctx/index.d.ts +10 -0
  57. package/dist/utils/ctx/index.js +19 -0
  58. package/dist/utils/debounce.d.ts +9 -0
  59. package/dist/utils/debounce.js +15 -0
  60. package/dist/utils/debugging.d.ts +2 -0
  61. package/dist/utils/debugging.js +21 -0
  62. package/dist/utils/deepDelta/delta.test.d.ts +1 -0
  63. package/dist/utils/deepDelta/delta.test.js +114 -0
  64. package/dist/utils/deepDelta/index.d.ts +8 -0
  65. package/dist/utils/deepDelta/index.js +40 -0
  66. package/dist/utils/deepMerge.d.ts +16 -0
  67. package/dist/utils/deepMerge.js +32 -0
  68. package/dist/utils/deepMerge.test.d.ts +1 -0
  69. package/dist/utils/deepMerge.test.js +68 -0
  70. package/dist/utils/fps.d.ts +6 -0
  71. package/dist/utils/fps.js +51 -0
  72. package/dist/utils/fracDecConverter/index.d.ts +9 -0
  73. package/dist/utils/fracDecConverter/index.js +34 -0
  74. package/dist/utils/hashing.d.ts +2 -0
  75. package/dist/utils/hashing.js +7 -0
  76. package/dist/utils/id.d.ts +5 -0
  77. package/dist/utils/id.js +5 -0
  78. package/dist/utils/localStorage.d.ts +37 -0
  79. package/dist/utils/localStorage.js +22 -0
  80. package/dist/utils/math.d.ts +60 -0
  81. package/dist/utils/math.js +89 -0
  82. package/dist/utils/math.test.d.ts +1 -0
  83. package/dist/utils/math.test.js +42 -0
  84. package/dist/utils/maybeGetter/index.d.ts +26 -0
  85. package/dist/utils/maybeGetter/index.js +15 -0
  86. package/dist/utils/mouse.d.ts +8 -0
  87. package/dist/utils/mouse.js +8 -0
  88. package/dist/utils/random.d.ts +19 -0
  89. package/dist/utils/random.js +21 -0
  90. package/dist/utils/sets.d.ts +8 -0
  91. package/dist/utils/sets.js +10 -0
  92. package/dist/utils/string.d.ts +21 -0
  93. package/dist/utils/string.js +31 -0
  94. package/dist/utils/string.test.d.ts +1 -0
  95. package/dist/utils/string.test.js +14 -0
  96. package/dist/utils/types.d.ts +54 -0
  97. package/dist/utils/types.js +1 -0
  98. package/package.json +4 -1
  99. package/src/clone.test.ts +0 -47
  100. package/src/clone.ts +0 -15
  101. package/src/ctx/index.ts +0 -20
  102. package/src/debugging.ts +0 -23
  103. package/src/deepDelta/delta.test.ts +0 -129
  104. package/src/deepDelta/index.ts +0 -48
  105. package/src/deepMerge.test.ts +0 -89
  106. package/src/deepMerge.ts +0 -37
  107. package/src/fps.ts +0 -64
  108. package/src/fracDecConverter/index.ts +0 -36
  109. package/src/hashing.ts +0 -9
  110. package/src/localStorage.ts +0 -49
  111. package/src/math.test.ts +0 -57
  112. package/src/random.ts +0 -27
  113. package/src/string.test.ts +0 -17
  114. package/tsconfig.json +0 -20
  115. /package/{src/id.ts → dist/id.js} +0 -0
@@ -3,7 +3,6 @@
3
3
  * {@link} https://en.wikipedia.org/wiki/Golden_ratio
4
4
  */
5
5
  export const GOLDEN_RATIO = 1.618;
6
-
7
6
  /**
8
7
  * rounds a number to the nearest multiple of another number
9
8
  *
@@ -14,10 +13,9 @@ export const GOLDEN_RATIO = 1.618;
14
13
  * roundToNearest5(13) // 15
15
14
  * roundToNearest5(12) // 10
16
15
  */
17
- export const roundToNearestN = (nearest: number) => (n: number) => {
18
- return Math.round(n / nearest) * nearest;
16
+ export const roundToNearestN = (nearest) => (n) => {
17
+ return Math.round(n / nearest) * nearest;
19
18
  };
20
-
21
19
  /**
22
20
  * get the prime factors of a number
23
21
  *
@@ -26,22 +24,20 @@ export const roundToNearestN = (nearest: number) => (n: number) => {
26
24
  * @example getPrimeFactors(12) // [2, 2, 3]
27
25
  * getPrimeFactors(15) // [3, 5]
28
26
  */
29
- export const getPrimeFactors = (num: number) => {
30
- const factors: number[] = [];
31
- let divisor = 2;
32
-
33
- while (num >= 2) {
34
- if (num % divisor === 0) {
35
- factors.push(divisor);
36
- num = num / divisor;
37
- } else {
38
- divisor++;
27
+ export const getPrimeFactors = (num) => {
28
+ const factors = [];
29
+ let divisor = 2;
30
+ while (num >= 2) {
31
+ if (num % divisor === 0) {
32
+ factors.push(divisor);
33
+ num = num / divisor;
34
+ }
35
+ else {
36
+ divisor++;
37
+ }
39
38
  }
40
- }
41
-
42
- return factors;
39
+ return factors;
43
40
  };
44
-
45
41
  /**
46
42
  * get the lowest prime factor of a number
47
43
  *
@@ -51,11 +47,11 @@ export const getPrimeFactors = (num: number) => {
51
47
  * lowestPrimeFactor(12) // 12 = 2 * 2 * 3, min(2, 2, 3) = 2
52
48
  * lowestPrimeFactor(15) // 15 = 3 * 5, min(3, 5) = 3
53
49
  */
54
- export const lowestPrimeFactor = (num: number) => {
55
- if (num === 1) return 1; // 1 has no prime factors
56
- return Math.min(...getPrimeFactors(num));
50
+ export const lowestPrimeFactor = (num) => {
51
+ if (num === 1)
52
+ return 1; // 1 has no prime factors
53
+ return Math.min(...getPrimeFactors(num));
57
54
  };
58
-
59
55
  /**
60
56
  * get the greatest common divisor of two numbers.
61
57
  * {@link} https://en.wikipedia.org/wiki/Euclidean_algorithm
@@ -67,18 +63,17 @@ export const lowestPrimeFactor = (num: number) => {
67
63
  * @example gcd(12, 15) // 3
68
64
  * gcd(12, 18) // 6
69
65
  */
70
- export const gcd = (a: number, b: number): number => {
71
- if (b === 0) return a;
72
- return gcd(b, a % b);
66
+ export const gcd = (a, b) => {
67
+ if (b === 0)
68
+ return a;
69
+ return gcd(b, a % b);
73
70
  };
74
-
75
71
  /**
76
72
  * check if two numbers are within a certain tolerance of each other
77
73
  */
78
- export const within = (tolerance: number) => (a: number, b: number) => {
79
- return Math.abs(a - b) <= tolerance;
74
+ export const within = (tolerance) => (a, b) => {
75
+ return Math.abs(a - b) <= tolerance;
80
76
  };
81
-
82
77
  /**
83
78
  * get the average of an array of numbers
84
79
  *
@@ -87,7 +82,8 @@ export const within = (tolerance: number) => (a: number, b: number) => {
87
82
  * @example average([1, 2, 3]) // 2
88
83
  * average([1, 2, 3, 4]) // 2.5
89
84
  */
90
- export const average = (arr: number[]) => {
91
- if (arr.length === 0) return 0;
92
- return arr.reduce((acc, val) => acc + val, 0) / arr.length;
85
+ export const average = (arr) => {
86
+ if (arr.length === 0)
87
+ return 0;
88
+ return arr.reduce((acc, val) => acc + val, 0) / arr.length;
93
89
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import { average, gcd, getPrimeFactors, lowestPrimeFactor, roundToNearestN, } from './math';
3
+ describe('roundToNearestN', () => {
4
+ test('rounds a number to the nearest multiple of n', () => {
5
+ const roundToNearest5 = roundToNearestN(5);
6
+ expect(roundToNearest5(13)).toBe(15);
7
+ expect(roundToNearest5(12)).toBe(10);
8
+ });
9
+ });
10
+ describe('getPrimeFactors', () => {
11
+ test('returns the prime factors of a number', () => {
12
+ expect(getPrimeFactors(12)).toEqual([2, 2, 3]);
13
+ expect(getPrimeFactors(15)).toEqual([3, 5]);
14
+ });
15
+ test('edge case: 1', () => {
16
+ expect(getPrimeFactors(1)).toEqual([]);
17
+ });
18
+ });
19
+ describe('lowestPrimeFactor', () => {
20
+ test('returns the lowest prime factor of a number', () => {
21
+ expect(lowestPrimeFactor(12)).toBe(2);
22
+ expect(lowestPrimeFactor(15)).toBe(3);
23
+ });
24
+ test('edge case: 1', () => {
25
+ expect(lowestPrimeFactor(1)).toBe(1);
26
+ });
27
+ });
28
+ describe('gcd', () => {
29
+ test('returns the greatest common divisor of two numbers', () => {
30
+ expect(gcd(12, 15)).toBe(3);
31
+ expect(gcd(12, 18)).toBe(6);
32
+ });
33
+ });
34
+ describe('average', () => {
35
+ test('returns the average of a list of numbers', () => {
36
+ expect(average([1, 2, 3, 4, 5])).toBe(3);
37
+ expect(average([1, 2, 3, 4, 5, 6])).toBe(3.5);
38
+ });
39
+ test('edge case: empty list', () => {
40
+ expect(average([])).toBe(0);
41
+ });
42
+ });
@@ -1,5 +1,4 @@
1
1
  import type { RemoveAnyArray } from '../types';
2
-
3
2
  /**
4
3
  * taking some data that may be a plain value or a function that returns that value
5
4
  *
@@ -7,20 +6,14 @@ import type { RemoveAnyArray } from '../types';
7
6
  * @template K - the type of the arguments necessary in order to resolve the value
8
7
  */
9
8
  export type MaybeGetter<T, K extends any[] = []> = T | ((...arg: K) => T);
10
-
11
9
  /**
12
10
  * the value of a MaybeGetter
13
11
  */
14
- export type UnwrapMaybeGetter<T> =
15
- T extends MaybeGetter<infer U, infer _> ? U : T;
16
-
12
+ export type UnwrapMaybeGetter<T> = T extends MaybeGetter<infer U, infer _> ? U : T;
17
13
  /**
18
14
  * the parameters of a MaybeGetter
19
15
  */
20
- export type MaybeGetterParams<T> = RemoveAnyArray<
21
- T extends MaybeGetter<infer _, infer K> ? K : []
22
- >;
23
-
16
+ export type MaybeGetterParams<T> = RemoveAnyArray<T extends MaybeGetter<infer _, infer K> ? K : []>;
24
17
  /**
25
18
  * unwraps a MaybeGetter into a value of type T.
26
19
  *
@@ -30,12 +23,4 @@ export type MaybeGetterParams<T> = RemoveAnyArray<
30
23
  * @example getValue(5) // 5
31
24
  * getValue(() => 5) // 5
32
25
  */
33
- export const getValue = <T, K extends any[]>(
34
- value: MaybeGetter<T, K>,
35
- ...args: K
36
- ) => {
37
- if (typeof value === 'function') {
38
- return (value as (...args: K) => T)(...args);
39
- }
40
- return value;
41
- };
26
+ export declare const getValue: <T, K extends any[]>(value: MaybeGetter<T, K>, ...args: K) => T;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * unwraps a MaybeGetter into a value of type T.
3
+ *
4
+ * @param value - the value to unwrap
5
+ * @param args - the arguments to pass to the getter if the value is a getter
6
+ * @returns T, which is UnwrapMaybeGetter<MaybeGetter<T, K>>
7
+ * @example getValue(5) // 5
8
+ * getValue(() => 5) // 5
9
+ */
10
+ export const getValue = (value, ...args) => {
11
+ if (typeof value === 'function') {
12
+ return value(...args);
13
+ }
14
+ return value;
15
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
3
+ */
4
+ export declare const MOUSE_BUTTONS: {
5
+ readonly left: 0;
6
+ readonly middle: 1;
7
+ readonly right: 2;
8
+ };
@@ -2,7 +2,7 @@
2
2
  * https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
3
3
  */
4
4
  export const MOUSE_BUTTONS = {
5
- left: 0,
6
- middle: 1,
7
- right: 2,
8
- } as const;
5
+ left: 0,
6
+ middle: 1,
7
+ right: 2,
8
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * given two numbers, this function returns a random number between them (inclusive)
3
+ *
4
+ * @param min - the lowest number
5
+ * @param max - the highest number
6
+ * @returns a random number between min and max
7
+ */
8
+ export declare const getRandomInRange: (min: number, max: number) => number;
9
+ export declare const getRandomPointOnCanvas: (canvas: HTMLCanvasElement, buffer?: number) => {
10
+ x: number;
11
+ y: number;
12
+ };
13
+ /**
14
+ * get a random element from an array
15
+ *
16
+ * @param array
17
+ * @returns random element from given array
18
+ */
19
+ export declare const getRandomElement: <T>(array: ArrayLike<T>) => T;
package/dist/random.js ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * given two numbers, this function returns a random number between them (inclusive)
3
+ *
4
+ * @param min - the lowest number
5
+ * @param max - the highest number
6
+ * @returns a random number between min and max
7
+ */
8
+ export const getRandomInRange = (min, max) => Math.round(Math.random() * (max - min) + min);
9
+ export const getRandomPointOnCanvas = (canvas, buffer = 50) => ({
10
+ x: getRandomInRange(buffer, canvas.width - buffer),
11
+ y: getRandomInRange(buffer, canvas.height - buffer),
12
+ });
13
+ /**
14
+ * get a random element from an array
15
+ *
16
+ * @param array
17
+ * @returns random element from given array
18
+ */
19
+ export const getRandomElement = (array) => {
20
+ return array[Math.floor(Math.random() * array.length)];
21
+ };
package/dist/sets.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * combine an array of sets into a single set
3
+ *
4
+ * @param sets array of sets
5
+ * @returns a single set containing all elements from the input sets
6
+ * @example mergeSetArrayIntoSet([new Set([1, 2]), new Set([2, 3])]) // Set(1, 2, 3)
7
+ */
8
+ export declare const mergeSetArrayIntoSet: <T>(sets: Set<T>[]) => Set<T>;
@@ -5,6 +5,6 @@
5
5
  * @returns a single set containing all elements from the input sets
6
6
  * @example mergeSetArrayIntoSet([new Set([1, 2]), new Set([2, 3])]) // Set(1, 2, 3)
7
7
  */
8
- export const mergeSetArrayIntoSet = <T>(sets: Set<T>[]) => {
9
- return sets.reduce((acc, set) => new Set([...acc, ...set]), new Set<T>());
8
+ export const mergeSetArrayIntoSet = (sets) => {
9
+ return sets.reduce((acc, set) => new Set([...acc, ...set]), new Set());
10
10
  };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * makes the first letter of a string uppercase
3
+ *
4
+ * @param str - the string to capitalize
5
+ * @returns the capitalized string
6
+ * @example capitalize('hello') // 'Hello'
7
+ */
8
+ export declare const capitalize: (str: string) => string;
9
+ /**
10
+ * turns a camelCase string into a title case string
11
+ *
12
+ * @param str - the string to convert
13
+ * @returns the title case string
14
+ * @example camelCaseToTitleCase('camelCase') // 'Camel Case'
15
+ */
16
+ export declare const camelCaseToTitleCase: (str: string) => string;
17
+ /**
18
+ * turns an array of strings into a comma separated list with 'and' before the last item
19
+ * @example toCommaList(['a', 'b', 'c']) // 'a, b and c'
20
+ */
21
+ export declare const getCommaList: (arr: string[]) => string;
@@ -5,9 +5,7 @@
5
5
  * @returns the capitalized string
6
6
  * @example capitalize('hello') // 'Hello'
7
7
  */
8
- export const capitalize = (str: string) =>
9
- str.charAt(0).toUpperCase() + str.slice(1);
10
-
8
+ export const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
11
9
  /**
12
10
  * turns a camelCase string into a title case string
13
11
  *
@@ -15,17 +13,19 @@ export const capitalize = (str: string) =>
15
13
  * @returns the title case string
16
14
  * @example camelCaseToTitleCase('camelCase') // 'Camel Case'
17
15
  */
18
- export const camelCaseToTitleCase = (str: string) => {
19
- const result = str.replace(/([A-Z])/g, ' $1');
20
- return capitalize(result);
16
+ export const camelCaseToTitleCase = (str) => {
17
+ const result = str.replace(/([A-Z])/g, ' $1');
18
+ return capitalize(result);
21
19
  };
22
20
  /**
23
21
  * turns an array of strings into a comma separated list with 'and' before the last item
24
22
  * @example toCommaList(['a', 'b', 'c']) // 'a, b and c'
25
23
  */
26
- export const getCommaList = (arr: string[]) => {
27
- if (arr.length === 0) return '';
28
- if (arr.length === 1) return arr[0];
29
- const last = arr.pop();
30
- return arr.join(', ') + ' and ' + last;
24
+ export const getCommaList = (arr) => {
25
+ if (arr.length === 0)
26
+ return '';
27
+ if (arr.length === 1)
28
+ return arr[0];
29
+ const last = arr.pop();
30
+ return arr.join(', ') + ' and ' + last;
31
31
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,14 @@
1
+ import { describe, expect, test } from 'vitest';
2
+ import { camelCaseToTitleCase, capitalize } from './string';
3
+ describe('capitalize', () => {
4
+ test('capitalizes the first letter of a string', () => {
5
+ expect(capitalize('hello')).toBe('Hello');
6
+ expect(capitalize('this is one string')).toBe('This is one string');
7
+ });
8
+ });
9
+ describe('camelCaseToTitleCase', () => {
10
+ test('converts camelCase to title case', () => {
11
+ expect(camelCaseToTitleCase('camelCase')).toBe('Camel Case');
12
+ expect(camelCaseToTitleCase('thisIsOneString')).toBe('This Is One String');
13
+ });
14
+ });
@@ -1,71 +1,45 @@
1
1
  import type { Prettify, UnionToIntersection } from 'ts-essentials';
2
-
3
2
  /**
4
3
  * makes only certain keys K in an object T optional
5
4
  * @example
6
5
  * type T = PartiallyPartial<{ a: number, b: string }, 'a'> // { a?: number, b: string }
7
6
  */
8
- export type PartiallyPartial<T, K extends keyof T> = Prettify<
9
- Omit<T, K> & Partial<Pick<T, K>>
10
- >;
11
-
7
+ export type PartiallyPartial<T, K extends keyof T> = Prettify<Omit<T, K> & Partial<Pick<T, K>>>;
12
8
  /**
13
9
  * makes only certain keys K in an object T required
14
10
  * @example
15
11
  * type T = PartiallyRequired<{ a?: number, b?: string }, 'a'> // { a: number, b?: string }
16
12
  */
17
- export type PartiallyRequired<T, K extends keyof T> = Prettify<
18
- Omit<T, K> & Required<Pick<T, K>>
19
- >;
20
-
13
+ export type PartiallyRequired<T, K extends keyof T> = Prettify<Omit<T, K> & Required<Pick<T, K>>>;
21
14
  /**
22
15
  * takes `any[]` out of a union of arrays
23
16
  * @example RemoveAnyArray<number[] | any[]> // number[]
24
17
  */
25
- export type RemoveAnyArray<T extends unknown[]> = Exclude<
26
- T,
27
- ['!!!-@-NOT-A-TYPE-@-!!!'][]
28
- >;
29
-
30
- // HTML mouse and keyboard event types
31
-
18
+ export type RemoveAnyArray<T extends unknown[]> = Exclude<T, [
19
+ '!!!-@-NOT-A-TYPE-@-!!!'
20
+ ][]>;
32
21
  type EventNames = keyof HTMLElementEventMap;
33
-
34
22
  type FilterEventNames<T> = {
35
- [K in EventNames]: HTMLElementEventMap[K] extends T ? K : never;
23
+ [K in EventNames]: HTMLElementEventMap[K] extends T ? K : never;
36
24
  }[EventNames];
37
-
38
25
  type MouseEventNames = FilterEventNames<MouseEvent>;
39
26
  type KeyboardEventNames = FilterEventNames<KeyboardEvent>;
40
-
41
27
  type EventMap<T extends EventNames, E> = Record<T, (ev: E) => void>;
42
-
43
28
  export type MouseEventMap = EventMap<MouseEventNames, MouseEvent>;
44
29
  export type KeyboardEventMap = EventMap<KeyboardEventNames, KeyboardEvent>;
45
-
46
30
  export type MouseEventEntries = [
47
- keyof MouseEventMap,
48
- (ev: MouseEvent) => void,
31
+ keyof MouseEventMap,
32
+ (ev: MouseEvent) => void
49
33
  ][];
50
34
  export type KeyboardEventEntries = [
51
- keyof KeyboardEventMap,
52
- (ev: KeyboardEvent) => void,
35
+ keyof KeyboardEventMap,
36
+ (ev: KeyboardEvent) => void
53
37
  ][];
54
-
55
38
  export type TimeoutHandler = ReturnType<typeof setTimeout>;
56
39
  export type IntervalHandler = ReturnType<typeof setInterval>;
57
-
58
- type LastOf<U> =
59
- UnionToIntersection<U extends any ? () => U : never> extends () => infer R
60
- ? R
61
- : never;
62
-
40
+ type LastOf<U> = UnionToIntersection<U extends any ? () => U : never> extends () => infer R ? R : never;
63
41
  type Push<T extends any[], V> = [...T, V];
64
-
65
- type UnionToTuple<T, L = LastOf<T>> = [T] extends [never]
66
- ? []
67
- : Push<UnionToTuple<Exclude<T, L>>, L>;
68
-
42
+ type UnionToTuple<T, L = LastOf<T>> = [T] extends [never] ? [] : Push<UnionToTuple<Exclude<T, L>>, L>;
69
43
  /**
70
44
  * turns the keys of an object into a tuple
71
45
  *
@@ -77,3 +51,4 @@ type UnionToTuple<T, L = LastOf<T>> = [T] extends [never]
77
51
  * // ["name", "age", "id"]
78
52
  */
79
53
  export type ObjectKeysToTuple<T extends object> = UnionToTuple<keyof T>;
54
+ export {};
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * clones an object while preserving the references of non-primitive values
3
+ *
4
+ * @param obj - the object to clone
5
+ * @returns the cloned object
6
+ */
7
+ export declare const clone: (obj: Record<any, any>) => {
8
+ [x: string]: any;
9
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * clones an object while preserving the references of non-primitive values
3
+ *
4
+ * @param obj - the object to clone
5
+ * @returns the cloned object
6
+ */
7
+ export const clone = (obj) => {
8
+ const cloned = { ...obj };
9
+ for (const key in cloned) {
10
+ if (typeof cloned[key] === 'object') {
11
+ cloned[key] = clone(cloned[key]);
12
+ }
13
+ }
14
+ return cloned;
15
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
1
+ import { expect, test } from "vitest";
2
+ import { clone } from "./clone";
3
+ import { delta } from "./deepDelta";
4
+ test("works on basic objects", () => {
5
+ const obj = { a: 1, b: 2 };
6
+ const cloned = clone(obj);
7
+ expect(cloned).not.toBe(obj);
8
+ expect(cloned).toEqual(obj);
9
+ });
10
+ test("works on nested objects", () => {
11
+ const obj = { a: { b: 1 } };
12
+ const cloned = clone(obj);
13
+ expect(cloned).not.toBe(obj);
14
+ expect(cloned).toEqual(obj);
15
+ });
16
+ test("works by preserving nested references", () => {
17
+ const objWithRef = { a: { b: () => { } }, c: { d: 1 } };
18
+ const cloned = clone(objWithRef);
19
+ objWithRef.c = {};
20
+ expect(cloned.a.b).toBe(objWithRef.a.b);
21
+ expect(cloned.c).toEqual({ d: 1 });
22
+ });
23
+ test("works with deep delta", () => {
24
+ const nodeSize = (node) => node.size;
25
+ const nodeBorderWidth = (node) => node.borderWidth;
26
+ const storedTheme = clone({
27
+ nodeSize,
28
+ nodeBorderWidth,
29
+ nodeBorderColor: "#000",
30
+ edgeWidth: 1,
31
+ edgeColor: "#123",
32
+ });
33
+ const incomingTheme = {
34
+ nodeSize,
35
+ nodeBorderWidth,
36
+ nodeBorderColor: "#000",
37
+ edgeWidth: 1,
38
+ edgeColor: "#123",
39
+ };
40
+ const diff = delta(storedTheme, incomingTheme);
41
+ expect(diff).toEqual(null);
42
+ });