zek 19.0.13 → 19.0.16

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/fesm2022/zek.mjs CHANGED
@@ -92,6 +92,28 @@ class ArrayHelper {
92
92
  }
93
93
  return result;
94
94
  }
95
+ /**
96
+ * Returns a new array with duplicates removed based on a specific key or selector.
97
+ * @param array The source array.
98
+ * @param keySelector A function that returns the value to compare by.
99
+ */
100
+ static distinctBy(array, keySelector) {
101
+ // Guard clause for null/undefined or empty arrays
102
+ if (!array || array.length === 0) {
103
+ return [];
104
+ }
105
+ const seen = new Set();
106
+ const result = [];
107
+ // Using a for...of loop is often cleaner than standard for loop in modern JS
108
+ for (const item of array) {
109
+ const key = keySelector(item);
110
+ if (!seen.has(key)) {
111
+ seen.add(key);
112
+ result.push(item);
113
+ }
114
+ }
115
+ return result;
116
+ }
95
117
  static filterByKey(filterValue, key, array) {
96
118
  if (typeof filterValue === 'undefined' || filterValue == null || (typeof key === 'string' && key.length === 0))
97
119
  return array;
@@ -1033,25 +1055,69 @@ class ObjectHelper {
1033
1055
  return target;
1034
1056
  }
1035
1057
  static deepCopy(value) {
1058
+ // 1. Guard clause: if value is null or not an object, return it.
1059
+ // (This handles primitives and breaks recursion)
1036
1060
  if (!this.isObject(value))
1037
1061
  return value;
1038
- let output = {};
1062
+ // 2. Handle Arrays
1039
1063
  if (Array.isArray(value)) {
1040
- output = value.map(x => this.deepCopy(x));
1041
- }
1042
- else {
1043
- Object.keys(value).forEach((key) => {
1044
- const v = value[key];
1045
- if (this.isObject(v)) {
1046
- output[key] = this.deepCopy(v);
1047
- }
1048
- else {
1049
- Object.assign(output, { [key]: v });
1050
- }
1051
- });
1064
+ return value.map(x => this.deepCopy(x));
1065
+ }
1066
+ // 3. Handle Objects
1067
+ const output = {};
1068
+ for (const key of Object.keys(value)) {
1069
+ const v = value[key];
1070
+ if (this.isObject(v)) {
1071
+ output[key] = this.deepCopy(v);
1072
+ }
1073
+ else {
1074
+ Object.assign(output, { [key]: v });
1075
+ }
1052
1076
  }
1053
1077
  return output;
1054
1078
  }
1079
+ static deepEquals(a, b) {
1080
+ // 1. Strict equality for primitives
1081
+ if (a === b)
1082
+ return true;
1083
+ // 2. If one is null/undefined or types differ → not equal
1084
+ if (a == null || b == null || typeof a !== typeof b)
1085
+ return false;
1086
+ // 3. Date comparison
1087
+ if (a instanceof Date && b instanceof Date) {
1088
+ return a.getTime() === b.getTime();
1089
+ }
1090
+ // 4. Arrays
1091
+ if (Array.isArray(a)) {
1092
+ if (!Array.isArray(b))
1093
+ return false;
1094
+ if (a.length !== b.length)
1095
+ return false;
1096
+ for (let i = 0; i < a.length; i++) {
1097
+ if (!this.deepEquals(a[i], b[i]))
1098
+ return false;
1099
+ }
1100
+ return true;
1101
+ }
1102
+ // 5. Objects
1103
+ if (this.isObject(a)) {
1104
+ if (!this.isObject(b))
1105
+ return false;
1106
+ const keysA = Object.keys(a);
1107
+ const keysB = Object.keys(b);
1108
+ if (keysA.length !== keysB.length)
1109
+ return false;
1110
+ for (const key of keysA) {
1111
+ if (!keysB.includes(key))
1112
+ return false;
1113
+ if (!this.deepEquals(a[key], b[key]))
1114
+ return false;
1115
+ }
1116
+ return true;
1117
+ }
1118
+ // 6. Fallback
1119
+ return false;
1120
+ }
1055
1121
  }
1056
1122
 
1057
1123
  class FilterHelper {
@@ -2815,6 +2881,12 @@ class IdName {
2815
2881
  }
2816
2882
  class IdNameChecked extends IdName {
2817
2883
  checked;
2884
+ constructor(init) {
2885
+ super();
2886
+ if (init) {
2887
+ Object.assign(this, init);
2888
+ }
2889
+ }
2818
2890
  }
2819
2891
 
2820
2892
  class KeyPair {