@superutils/core 1.0.4 → 1.0.6

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/README.md CHANGED
@@ -222,7 +222,7 @@ search(data, { query: { age: 28, name: 've' } })
222
222
  // [4, { age: 28, name: 'Dave' }],
223
223
  // ])
224
224
 
225
- // Fuzzy search accross all properties
225
+ // Search across all properties
226
226
  search(data, { query: 'li' })
227
227
  search(data, { query: /li/i }) // Using regular expression
228
228
  // Result:
@@ -255,7 +255,7 @@ search(data, {
255
255
  age: /(2[5-9])|(3[0-5])/, // match ages 25-35
256
256
  name: /ali|ob|ve/i,
257
257
  },
258
- // transform the property values (or item itself when in fuzzy search mode)
258
+ // transform the property values (or item itself when searching all properties in global search mode using `query: string | RegExp`)
259
259
  transform: (item, value, property) => {
260
260
  // exclude items by returning undefined or emptry string
261
261
  if (item.age < 18) return ''
package/dist/index.d.ts CHANGED
@@ -27,7 +27,7 @@ type Curry<TData, TParams extends unknown[]> = <TArgs extends unknown[]>(...args
27
27
  /**
28
28
  * Deferred function config
29
29
  */
30
- interface DeferredConfig<ThisArg = unknown> {
30
+ interface DeferredOptions<ThisArg = unknown> {
31
31
  leading?: boolean | 'global';
32
32
  onError?: (err: unknown) => ValueOrPromise<unknown>;
33
33
  thisArg?: ThisArg;
@@ -283,7 +283,7 @@ type CurriedArgs<TArgs extends unknown[], TArgsIsFinite extends boolean, TFunc e
283
283
  *
284
284
  */
285
285
  declare const deferred: {
286
- <TArgs extends unknown[], ThisArg>(callback: (this: ThisArg, ...args: TArgs) => ValueOrPromise<unknown>, delay?: number, config?: DeferredConfig<ThisArg>): (...args: TArgs) => void;
286
+ <TArgs extends unknown[], ThisArg>(callback: (this: ThisArg, ...args: TArgs) => ValueOrPromise<unknown>, delay?: number, config?: DeferredOptions<ThisArg>): (...args: TArgs) => void;
287
287
  defaults: {
288
288
  /**
289
289
  * Set the default value of argument `leading` for the `deferred` function.
@@ -400,7 +400,7 @@ declare const isArrLike: (x: any) => x is typeof x extends (infer Value)[] ? Val
400
400
  * Check if value is convertible to an array by using `Array.from(x)` even if it comes from a different realm
401
401
  * (eg: iframe, iframes, worker contexts, node vm contexts, browser extensions).
402
402
  *
403
- * Caution: much slower than {@link isArrLike()} due to use of `Object.prototype.toString.call()`
403
+ * Caution: much slower than {@link isArrLike} due to use of `Object.prototype.toString.call()`
404
404
  */
405
405
  declare const isArrLikeSafe: <T = unknown, MapKey = unknown>(x: unknown) => x is Set<T> | Map<MapKey, T> | T[];
406
406
  /** Check if all values in the array are unique */
@@ -644,7 +644,7 @@ declare const is: {
644
644
  declare function noop(): void;
645
645
  declare function noopAsync(): Promise<void>;
646
646
 
647
- type ThrottleConfig<ThisArg = unknown> = {
647
+ type ThrottleOptions<ThisArg = unknown> = {
648
648
  onError?: (err: unknown) => ValueOrPromise<unknown>;
649
649
  thisArg?: ThisArg;
650
650
  trailing?: boolean;
@@ -662,7 +662,7 @@ type ThrottleConfig<ThisArg = unknown> = {
662
662
  * @param config.trailing (optional) whether to enable trailing edge execution. Default: `true`
663
663
  */
664
664
  declare const throttled: {
665
- <TArgs extends unknown[], ThisArg>(callback: (this: ThisArg, ...args: TArgs) => ValueOrPromise<unknown>, delay?: number, config?: ThrottleConfig<ThisArg>): (...args: TArgs) => void;
665
+ <TArgs extends unknown[], ThisArg>(callback: (this: ThisArg, ...args: TArgs) => ValueOrPromise<unknown>, delay?: number, config?: ThrottleOptions<ThisArg>): (...args: TArgs) => void;
666
666
  /**
667
667
  * Set the default values
668
668
  * This change is applicable application-wide and only applies to any new invocation of `throttle()`.
@@ -712,25 +712,34 @@ declare const objClean: <T extends Record<PropertyKey, unknown>, Key extends key
712
712
  * Deep-copy an object to another object
713
713
  *
714
714
  * @param input input object
715
+ * @param _output (optional) output object
715
716
  * @param ignoreKeys (optional) input peroperties to be ignored. Prevents output's property to be overriden.
716
717
  *
717
718
  * For child object properties use "." (dot) separated path.
718
719
  *
719
720
  * Eg: `"child.grandchild1"` where input is `{ child: { grandchild1: 1, grandchild2: 2 }}`
720
721
  *
721
- * @param output (optional) output object
722
- * @param override (optional) whether to allow override output (if provided) properties.
722
+ * @param override (optional) whether to allow override output properties.
723
+ * This will only be used if `output` object is provided and has own property.
723
724
  * Accepted values:
724
- * `true`: input property will override output property
725
- * `false`: no overriding if output contains the property. Even if the property value is `undefined`.
726
- * `"empty"`: only allow overriding output property if it's value is empty by using {@link isEmpty}.
725
+ * - `true`: input property will override output property
726
+ * - `false`: no overriding if output contains the property. Even if the property value is `undefined`.
727
+ * - `"empty"`: only allow overriding output property if it's value is empty by using {@link isEmpty}.
728
+ * - `function`: decide whether to override on a per property basis.
729
+ *
730
+ * Function Arguments:
731
+ * 1. key: current property name/key
732
+ * 2. outputValue: `output` property value
733
+ * 3. inputValue: `input` property value
727
734
  *
728
735
  * Default: `false`
729
736
  *
737
+ * @param reverse (optional) whether to reverse sort object properties. Default: `false`
738
+ *
730
739
  *
731
740
  * @returns copied and/or merged object
732
741
  */
733
- declare const objCopy: <Key extends string | symbol, T extends Record<Key, unknown>, IgnoredKey extends Key | string>(input: T, output?: Record<PropertyKey, unknown>, ignoreKeys?: IgnoredKey[] | Set<IgnoredKey>, override?: boolean | "empty", recursive?: boolean) => Record<PropertyKey, unknown>;
742
+ declare const objCopy: <Key extends PropertyKey, InValue, OutValue, IgnoredKey extends Key | string>(input: Record<Key, InValue>, output?: Record<PropertyKey, OutValue>, ignoreKeys?: IgnoredKey[] | Set<IgnoredKey>, override?: boolean | "empty" | ((key: Key, outputValue: OutValue, inputValue: InValue) => boolean), recursive?: boolean) => Record<PropertyKey, unknown>;
734
743
 
735
744
  /**
736
745
  * Creates an object from an array of keys and a corresponding array of values.
@@ -760,6 +769,15 @@ declare const objCopy: <Key extends string | symbol, T extends Record<Key, unkno
760
769
  */
761
770
  declare const objCreate: <V, K extends PropertyKey, RV, RK extends PropertyKey, Result extends Record<K | RK, V | RV>>(keys?: K[], values?: V[], result?: Result) => Result;
762
771
 
772
+ /**
773
+ * Checks if all the supplied keys exist in an object
774
+ *
775
+ * @param input
776
+ * @param keys
777
+ * @param equireValue (optional) whether each property should have some value.
778
+ */
779
+ declare function objHasKeys(input?: object | unknown[], keys?: PropertyKey[], requireValue?: boolean): boolean;
780
+
763
781
  /**
764
782
  * Get object property names/keys
765
783
  *
@@ -837,10 +855,11 @@ declare const objWithoutKeys: (input: unknown, keys: string[], output?: Record<P
837
855
  declare const arrReadOnly: <T>(arr: T[], config?: Omit<ReadOnlyConfig<T[]>, "revoke">) => T[];
838
856
 
839
857
  /**
858
+ * @ignore exclude from documentation
840
859
  * Helper class for creating read-only arrays.
841
860
  *
842
861
  * Caution: This class can by itself only make the array partially read-only.
843
- * Use {@link arrReadOnly()} instead.
862
+ * Use {@link arrReadOnly} instead.
844
863
  */
845
864
  declare class ReadOnlyArrayHelper<T> extends Array<T> {
846
865
  readonly config: Omit<ReadOnlyConfig<T[]>, 'revoke'>;
@@ -852,16 +871,6 @@ declare class ReadOnlyArrayHelper<T> extends Array<T> {
852
871
  shift: () => T;
853
872
  splice: (..._ignoredArgs: unknown[]) => never[];
854
873
  unshift: (..._ignoredArgs: T[]) => number;
855
- reduce: {
856
- (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
857
- (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
858
- <U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
859
- };
860
- reduceRight: {
861
- (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
862
- (callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
863
- <U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
864
- };
865
874
  }
866
875
 
867
876
  /**
@@ -905,9 +914,9 @@ declare const arrReverse: <T = unknown>(arr: T[], reverse?: boolean, newArray?:
905
914
  * const map = arrToMap(arr, (item: Item) => item.key, 1) // Map<number, Item>
906
915
  * ```
907
916
  */
917
+ declare function arrToMap<T extends unknown[], FlatDepth extends number = 0, MapItem = FlatArray<T, FlatDepth>, KeyProp extends keyof MapItem = keyof MapItem>(arr: T, key: KeyProp, flatDepth?: FlatDepth): Map<MapItem[KeyProp], MapItem>;
908
918
  declare function arrToMap<T extends unknown[], FlatDepth extends number = 0>(arr: T, flatDepth?: FlatDepth): Map<number, FlatArray<T, FlatDepth>>;
909
919
  declare function arrToMap<T extends unknown[], FlatDepth extends number = 0, MapItem = FlatArray<T, FlatDepth>, MapKey = unknown>(arr: T, key: (item: MapItem, index: number, flatArr: MapItem[]) => MapKey, flatDepth?: FlatDepth): Map<MapKey, MapItem>;
910
- declare function arrToMap<T extends unknown[], FlatDepth extends number = 0, MapItem = FlatArray<T, FlatDepth>, KeyProp extends keyof MapItem = keyof MapItem>(arr: T, key: KeyProp, flatDepth?: FlatDepth): Map<MapItem[KeyProp], MapItem>;
911
920
 
912
921
  /**
913
922
  * @function arrUnique
@@ -957,7 +966,7 @@ type SortOptions = {
957
966
  undefinedFirst?: boolean;
958
967
  };
959
968
  /** Search criteria for searcheing iterables */
960
- type SearchOptions<K, V, AsMap extends boolean = false> = {
969
+ type SearchOptions<K, V, MatchExact extends boolean = false, AsMap extends boolean = false> = {
961
970
  /** Whethere to return the result as a map (`true`) or array (`false`). Default: `true` */
962
971
  asMap?: AsMap;
963
972
  /** case-insensitive search for strings. Default: `false` */
@@ -965,21 +974,33 @@ type SearchOptions<K, V, AsMap extends boolean = false> = {
965
974
  /** limit number of results. Default: `Infinity` */
966
975
  limit?: number;
967
976
  /** partial match for values. Default: `false` */
968
- matchExact?: boolean;
977
+ matchExact?: MatchExact;
969
978
  /** match all supplied key-value pairs. Default: `false` */
970
979
  matchAll?: boolean;
971
980
  /** key-value pairs */
972
- query: Record<string, unknown> | string | RegExp;
981
+ query: Record<PropertyKey, unknown> | RegExp | string;
982
+ /** If `true`, the results are sorted by relevance (match index). Default: `false` */
983
+ ranked?: boolean;
973
984
  /** Map to store results in. Default: `new Map()` */
974
985
  result?: Map<K, V>;
975
- /** Callback to convert item/item-property to string */
976
- transform?: (
986
+ /**
987
+ * Boolean or Callback to prepare item or individual property for search by converting to string.
988
+ *
989
+ * - `true`: value will be stringified
990
+ * - `false`: value will not be stringified when `matchExact = true`
991
+ * - `function`: transformed value will be used to search
992
+ *
993
+ * Returning "empty" (`undefined | null | [] | '' | ...`) value will ignore the item/property.
994
+ *
995
+ * Default: `true`
996
+ */
997
+ transform?: boolean | ((
977
998
  /** List item */
978
999
  item: V,
979
- /** Item property value or `undefined` for fuzzy search. */
1000
+ /** Item property value or `undefined` for global search across all properties. */
980
1001
  value?: V[keyof V],
981
- /** Item property key provided by query or `undefined` for fuzzy search. */
982
- key?: keyof V) => string | undefined;
1002
+ /** Item property key provided by query or `undefined` for global search across all properties. */
1003
+ key?: keyof V) => MatchExact extends true ? unknown : string | undefined);
983
1004
  };
984
1005
 
985
1006
  /**
@@ -987,6 +1008,12 @@ type SearchOptions<K, V, AsMap extends boolean = false> = {
987
1008
  *
988
1009
  * @param data
989
1010
  * @param predicate callback function to filter values
1011
+ * Parameters:
1012
+ * 1. `item`: current item
1013
+ * 2. `key`: index/key
1014
+ * 3. `data`: value provided in the first argument (`data`)
1015
+ * @param limit (optional) limit number of results
1016
+ * @param arArray
990
1017
  *
991
1018
  * @returns new Map with filtered items
992
1019
  *
@@ -1007,7 +1034,7 @@ type SearchOptions<K, V, AsMap extends boolean = false> = {
1007
1034
  * // }
1008
1035
  * ```
1009
1036
  */
1010
- declare const filter: <K, V, AsArray extends boolean = false, Result = AsArray extends true ? V[] : Map<K, V>>(data: IterableList<K, V>, predicate: (value: V, key: K, data: IterableList<K, V>) => boolean, limit?: number, asArray?: AsArray, result?: Map<K, V>) => Result;
1037
+ declare const filter: <K, V, AsArray extends boolean = false, Result = AsArray extends true ? V[] : Map<K, V>>(data: IterableList<K, V>, predicate: (item: V, key: K, data: IterableList<K, V>) => boolean, limit?: number, asArray?: AsArray, result?: Map<K, V>) => Result;
1011
1038
 
1012
1039
  /**
1013
1040
  * Finds a first item matching criteria in an {@link IterableList}.
@@ -1070,8 +1097,8 @@ declare const getValues: <K, V>(data: IterableList<K, V>) => V[];
1070
1097
  declare const reverse: <K, V, T extends IterableList<K, V>>(data: T, reverse?: boolean, newInstance?: boolean) => V[] | [K, V][] | Map<K, V> | Set<V> | (T & Record<"clear", unknown>);
1071
1098
 
1072
1099
  /**
1073
- * A versatile utility for searching through an iterable list (e.g., Array, Map, Set) of objects.
1074
- * It supports both a simple "fuzzy" search with a string query across all properties and a
1100
+ * A versatile utility for searching through an iterable list (Array, Map, or Set) of objects.
1101
+ * It supports both a global search (using a string or RegExp) across all properties of an item, and a
1075
1102
  * detailed, field-specific search using a query object.
1076
1103
  *
1077
1104
  * @param data The list of objects to search within. Compatible types include:
@@ -1082,6 +1109,8 @@ declare const reverse: <K, V, T extends IterableList<K, V>>(data: T, reverse?: b
1082
1109
  * - `HTMLCollection` (in DOM environments): should accompany `options.transform()`
1083
1110
  * @param options The search criteria.
1084
1111
  * @param options.query The search query. Can be a string to search all fields, or an object for field-specific
1112
+ * @param options.ranked (optional) If `true`, the results are sorted by relevance (match index). Default: `false`.
1113
+ *
1085
1114
  * searches (e.g., `{ name: 'John', city: 'New York' }`).
1086
1115
  * @param options.asMap (optional) If `true`, returns a `Map`. If `false`, returns an `Array`. Default: `true`.
1087
1116
  * @param options.ignoreCase (optional) If `true`, performs a case-insensitive search for strings. Default: `true`.
@@ -1116,19 +1145,23 @@ declare const reverse: <K, V, T extends IterableList<K, V>>(data: T, reverse?: b
1116
1145
  * ```
1117
1146
  */
1118
1147
  declare const search: {
1119
- <K, V, AsMap extends boolean = true, Result = AsMap extends true ? Map<K, V> : V[]>(data: IterableList<K, V>, options: SearchOptions<K, V, AsMap>): Result;
1120
- defaultOptions: Pick<Required<SearchOptions<unknown, unknown, true>>, "matchAll" | "limit" | "asMap" | "ignoreCase" | "matchExact">;
1148
+ <K, V, MatchExact extends boolean = false, AsMap extends boolean = true, Result = AsMap extends true ? Map<K, V> : V[]>(data: IterableList<K, V>, options: SearchOptions<K, V, MatchExact, AsMap>): Result;
1149
+ defaultOptions: Pick<Required<SearchOptions<unknown, unknown, false, true>>, "matchAll" | "limit" | "asMap" | "ignoreCase" | "ranked" | "transform">;
1121
1150
  };
1122
- /** Utility for use with {@link search()} function */
1123
- declare function matchItemOrProp<K, V>(// extends Record<string, unknown>
1124
- { query, ignoreCase, matchExact, transform, }: Pick<SearchOptions<K, V, boolean>, 'transform' | 'query' | 'ignoreCase' | 'matchExact'>, item: V, propertyName?: string): boolean;
1151
+ /**
1152
+ * Utility for use with {@link search} function
1153
+ *
1154
+ * @returns match index (`-1` means didn't match)
1155
+ */
1156
+ declare function matchObjOrProp<K, V>(// extends Record<string, unknown>
1157
+ { query, ignoreCase, matchExact, transform, }: Pick<SearchOptions<K, V, boolean>, 'transform' | 'query' | 'ignoreCase' | 'matchExact'>, item: V, propertyName?: string): number;
1125
1158
 
1126
- type SliceMapCallback<Data, Value, Key> = (item: Value, key: Key, data: Data) => Value;
1159
+ type SliceMapTransform<Data, Value, Key> = (item: Value, key: Key, data: Data) => Value;
1127
1160
  type SliceMapOptions<Data, Value, Key, AsMap extends boolean = false> = {
1128
1161
  /** Whether to return the result as a Map (preserving original keys) or an Array */
1129
1162
  asMap?: AsMap;
1130
- /** callback to transform each item */
1131
- transform?: SliceMapCallback<Data, Value, Key>;
1163
+ /** Callback to transform each item from the selected range */
1164
+ transform?: SliceMapTransform<Data, Value, Key>;
1132
1165
  /** End index (exclusive). Default: `undefined` (end of the list) */
1133
1166
  end?: number;
1134
1167
  /** Whether to exclude item if value is `undefined | null` */
@@ -1140,9 +1173,14 @@ type SliceMapOptions<Data, Value, Key, AsMap extends boolean = false> = {
1140
1173
  * Slice an iterable list and map the values into an Array/Map
1141
1174
  *
1142
1175
  * @param data Array, Map, Set...
1143
- * @param start Default: `0`
1144
- * @param end (optional) last index - exclusive. Default: index of the last item
1145
- * @param callback to be executed on each item within the set range.
1176
+ * @param options One of the following is required to create a new list:
1177
+ * 1. A callback function {@link SliceMapTransform} to transform all items.
1178
+ * 2. Advanced options {@link SliceMapOptions}.
1179
+ * @param options.asMap (optional) whether return a Map or Array.
1180
+ * @param options.end (optional) End index (exclusive). Default: `undefined` (end of the list)
1181
+ * @param options.ignoreEmpty (optional) Whether to exclude item if value is `undefined | null`
1182
+ * @param options.start (optional) Default: `0`
1183
+ * @param options.transform (optional)
1146
1184
  *
1147
1185
  * If callback throws error or returnes `undefined`, the item will be ignored.
1148
1186
  *
@@ -1153,7 +1191,7 @@ type SliceMapOptions<Data, Value, Key, AsMap extends boolean = false> = {
1153
1191
  *
1154
1192
  * @returns Array/Map
1155
1193
  */
1156
- declare const sliceMap: <Data extends IterableList, Key = Data extends IterableList<infer Key_1, unknown> ? Key_1 : never, Value = Data extends IterableList<unknown, infer Value_1> ? Value_1 : never, AsMap extends boolean = false>(data: Data, options?: SliceMapOptions<Data, Value, Key, AsMap> | SliceMapCallback<Data, Value, Key>) => AsMap extends false ? Value[] : Map<Key, Value>;
1194
+ declare const sliceMap: <Data extends IterableList, Key = Data extends IterableList<infer Key_1, unknown> ? Key_1 : never, Value = Data extends IterableList<unknown, infer Value_1> ? Value_1 : never, AsMap extends boolean = false, Result = AsMap extends false ? Value[] : Map<Key, Value>>(data: Data, options?: SliceMapOptions<Data, Value, Key, AsMap> | SliceMapTransform<Data, Value, Key>) => Result;
1157
1195
 
1158
1196
  type EntryComparator<K, V> = (a: [K, V], b: [K, V]) => number;
1159
1197
  type ArrayComparator<V> = (a: V, b: V) => number;
@@ -1267,6 +1305,13 @@ declare const mapJoin: <K, V>(...inputs: (Map<K, V> | [K, V][])[]) => Map<K, V>;
1267
1305
  */
1268
1306
  declare const randomInt: (min?: number, max?: number) => number;
1269
1307
 
1308
+ /** Describes a number type with negative values only */
1309
+ type NegativeNumber<N extends number = number> = `${N}` extends `-${string}` ? N : never;
1310
+ /** Describes a number type with positive values excluding `0` */
1311
+ type PositiveNumber<N extends number = number> = `${N}` extends `-${string}` | '0' ? never : N;
1312
+ /** Describes a number type with positive values and `0` */
1313
+ type PositiveNumberWithZero<N extends number = number> = `${N}` extends `-${string}` ? never : N;
1314
+
1270
1315
  /**
1271
1316
  * Clears clutter from strings
1272
1317
  *
@@ -1319,4 +1364,14 @@ declare const EMAIL_REGEX: RegExp;
1319
1364
  declare const HEX_REGEX: RegExp;
1320
1365
  declare const HASH_REGEX: RegExp;
1321
1366
 
1322
- export { type ArrayComparator, type AsyncFn, type CreateTuple, type CurriedArgs, type Curry, type DeferredConfig, type DropFirst, type DropFirstN, type DropLast, EMAIL_REGEX, type EntryComparator, type FindOptions, HASH_REGEX, HEX_REGEX, type IfPromiseAddValue, type IsFiniteTuple, type IsOptional, type IterableList, type KeepFirst, type KeepFirstN, type KeepOptionals, type KeepRequired, type MakeOptional, type MinLength, type OptionalIf, type ReadOnlyAllowAddFn, ReadOnlyArrayHelper, type ReadOnlyConfig, type SearchOptions, type Slice, type SliceMapCallback, type SliceMapOptions, type SortOptions, type ThrottleConfig, type TimeoutId, type TupleMaxLength, type TupleWithAlt, type ValueOrFunc, type ValueOrPromise, arrReadOnly, arrReverse, arrToMap, arrUnique, asAny, clearClutter, copyToClipboard, curry, debounce, deferred, fallbackIfFails, filter, find, forceCast, getEntries, getKeys, getSize, getUrlParam, getValues, is, isArr, isArr2D, isArrLike, isArrLikeSafe, isArrObj, isArrUnique, isAsyncFn, isBool, isDate, isDateValid, isDefined, isEmpty, isEmptySafe, isEnvBrowser, isEnvNode, isEnvTouchable, isError, isFn, isInteger, isMap, isMapObj, isNumber, isObj, isPositiveInteger, isPositiveNumber, isPromise, isRegExp, isSet, isStr, isSymbol, isUint8Arr, isUrl, isUrlValid, mapJoin, matchItemOrProp, noop, noopAsync, objClean, objCopy, objCreate, objKeys, objReadOnly, objSetProp, objSetPropUndefined, objSort, objWithoutKeys, randomInt, reverse, search, sliceMap, sort, throttled, toDatetimeLocal };
1367
+ /**
1368
+ * Convert comma separated strings to array
1369
+ *
1370
+ * @param value value to convert
1371
+ * @param seperator (optional) only used when value is a string. Default: `","`
1372
+ *
1373
+ * @returns Array
1374
+ */
1375
+ declare const strToArr: (value: unknown, seperator?: string) => string[];
1376
+
1377
+ export { type ArrayComparator, type AsyncFn, type CreateTuple, type CurriedArgs, type Curry, type DeferredOptions, type DropFirst, type DropFirstN, type DropLast, EMAIL_REGEX, type EntryComparator, type FindOptions, HASH_REGEX, HEX_REGEX, type IfPromiseAddValue, type IsFiniteTuple, type IsOptional, type IterableList, type KeepFirst, type KeepFirstN, type KeepOptionals, type KeepRequired, type MakeOptional, type MinLength, type NegativeNumber, type OptionalIf, type PositiveNumber, type PositiveNumberWithZero, type ReadOnlyAllowAddFn, ReadOnlyArrayHelper, type ReadOnlyConfig, type SearchOptions, type Slice, type SliceMapOptions, type SliceMapTransform, type SortOptions, type ThrottleOptions, type TimeoutId, type TupleMaxLength, type TupleWithAlt, type ValueOrFunc, type ValueOrPromise, arrReadOnly, arrReverse, arrToMap, arrUnique, asAny, clearClutter, copyToClipboard, curry, debounce, deferred, fallbackIfFails, filter, find, forceCast, getEntries, getKeys, getSize, getUrlParam, getValues, is, isArr, isArr2D, isArrLike, isArrLikeSafe, isArrObj, isArrUnique, isAsyncFn, isBool, isDate, isDateValid, isDefined, isEmpty, isEmptySafe, isEnvBrowser, isEnvNode, isEnvTouchable, isError, isFn, isInteger, isMap, isMapObj, isNumber, isObj, isPositiveInteger, isPositiveNumber, isPromise, isRegExp, isSet, isStr, isSymbol, isUint8Arr, isUrl, isUrlValid, mapJoin, matchObjOrProp, noop, noopAsync, objClean, objCopy, objCreate, objHasKeys, objKeys, objReadOnly, objSetProp, objSetPropUndefined, objSort, objWithoutKeys, randomInt, reverse, search, sliceMap, sort, strToArr, throttled, toDatetimeLocal };
package/dist/index.js CHANGED
@@ -195,15 +195,12 @@ var is = {
195
195
  // src/fallbackIfFails.ts
196
196
  var fallbackIfFails = (target, args, fallbackValue) => {
197
197
  let result;
198
- let asPromise = false;
199
198
  try {
200
199
  result = !isFn(target) ? target : target(...isFn(args) ? args() : args);
201
200
  if (!isPromise(result)) return result;
202
- asPromise = true;
203
201
  return result.catch((err) => getAltValCb(err, fallbackValue));
204
202
  } catch (error) {
205
- result = getAltValCb(error, fallbackValue);
206
- return asPromise && !isPromise(result) ? Promise.resolve(result) : result;
203
+ return getAltValCb(error, fallbackValue);
207
204
  }
208
205
  };
209
206
  var fallbackIfFails_default = fallbackIfFails;
@@ -298,7 +295,7 @@ var objClean = (obj, keys, ignoreIfNotExist = true) => {
298
295
  const result = {};
299
296
  if (!isObj(obj) || !isArr(keys)) return result;
300
297
  const uniqKeys = arrUnique(
301
- keys.map((x) => isStr(x) ? `${x}`.split(".")[0] : x)
298
+ keys.map((x) => String(x).split(".")[0])
302
299
  ).sort();
303
300
  for (const key of uniqKeys) {
304
301
  if (ignoreIfNotExist && !obj.hasOwnProperty(key)) continue;
@@ -338,8 +335,8 @@ var objKeys_default = objKeys;
338
335
  // src/obj/objCopy.ts
339
336
  var clone = (value, fallback = "null") => JSON.parse(fallbackIfFails_default(JSON.stringify, [value], fallback));
340
337
  var objCopy = (input, output, ignoreKeys, override = false, recursive = true) => {
341
- if (!isObj(output)) output = {};
342
- if (!isObj(input)) return output;
338
+ const _output = isObj(output) ? output : {};
339
+ if (!isObj(input)) return _output;
343
340
  const _ignoreKeys = new Set(ignoreKeys != null ? ignoreKeys : []);
344
341
  const inKeys = objKeys_default(input, true, true).filter(
345
342
  (x) => !_ignoreKeys.has(x)
@@ -347,14 +344,14 @@ var objCopy = (input, output, ignoreKeys, override = false, recursive = true) =>
347
344
  for (const _key of inKeys) {
348
345
  const key = _key;
349
346
  const value = input[key];
350
- const skip = output.hasOwnProperty(key) && (!override || override === "empty" && !isEmpty(output[key]));
347
+ const skip = _output.hasOwnProperty(key) && (override === "empty" ? !isEmpty(_output[key]) : isFn(override) ? !override(key, _output[key], value) : true);
351
348
  if (skip) continue;
352
349
  const isPrimitive = [void 0, null, Infinity, NaN].includes(asAny(value)) || !isObj(value, false);
353
350
  if (isPrimitive) {
354
- output[key] = value;
351
+ _output[key] = value;
355
352
  continue;
356
353
  }
357
- output[key] = (() => {
354
+ _output[key] = (() => {
358
355
  switch (Object.getPrototypeOf(value)) {
359
356
  case Array.prototype:
360
357
  return clone(value, "[]");
@@ -384,19 +381,19 @@ var objCopy = (input, output, ignoreKeys, override = false, recursive = true) =>
384
381
  }
385
382
  if (isSymbol(key) || !recursive) return clone(value);
386
383
  const ignoreChildKeys = [..._ignoreKeys].map(
387
- (x) => !isSymbol(x) && x.startsWith(key.concat(".")) && x.split(key.concat("."))[1]
384
+ (x) => String(x).startsWith(String(key).concat(".")) && String(x).split(String(key).concat("."))[1]
388
385
  ).filter(Boolean);
389
386
  if (!ignoreChildKeys.length) return clone(value);
390
387
  return objCopy(
391
388
  value,
392
- output[key],
389
+ _output[key],
393
390
  ignoreChildKeys,
394
391
  override,
395
392
  recursive
396
393
  );
397
394
  })();
398
395
  }
399
- return output;
396
+ return _output;
400
397
  };
401
398
 
402
399
  // src/obj/objCreate.ts
@@ -409,6 +406,16 @@ var objCreate = (keys = [], values = [], result) => {
409
406
  return result;
410
407
  };
411
408
 
409
+ // src/obj/objHasKeys.ts
410
+ function objHasKeys(input = {}, keys = [], requireValue = false) {
411
+ if (!isObj(input) || !isArr(keys)) return false;
412
+ for (const key of keys) {
413
+ if (!input.hasOwnProperty(key)) return false;
414
+ if (requireValue && isEmpty(input[key])) return false;
415
+ }
416
+ return true;
417
+ }
418
+
412
419
  // src/obj/objReadOnly.ts
413
420
  var objReadOnly = (obj, config) => {
414
421
  if (!isObj(obj, false)) obj = {};
@@ -501,10 +508,10 @@ var ReadOnlyArrayHelper = class extends Array {
501
508
  this.shift = () => this.ignoreOrThrow(this[0]);
502
509
  this.splice = (..._ignoredArgs) => this.ignoreOrThrow([]);
503
510
  this.unshift = (..._ignoredArgs) => this.ignoreOrThrow(this.length);
504
- // fromAsync = super.fromAsync
505
- this.reduce = super.reduce;
506
- this.reduceRight = super.reduceRight;
507
511
  }
512
+ // fromAsync = super.fromAsync
513
+ // reduce = super.reduce
514
+ // reduceRight = super.reduceRight
508
515
  };
509
516
 
510
517
  // src/arr/arrReverse.ts
@@ -532,9 +539,10 @@ function arrToMap(arr, key, flatDepth = 0) {
532
539
  var arrUnique = (arr, flatDepth = 0) => !isArr(arr) ? [] : Array.from(new Set(arr.flat(flatDepth)));
533
540
 
534
541
  // src/iterable/filter.ts
535
- var filter = (data, predicate, limit = Infinity, asArray = false, result = /* @__PURE__ */ new Map()) => {
542
+ var filter = (data, predicate, limit, asArray, result) => {
536
543
  var _a;
537
544
  if (!isMap(result)) result = /* @__PURE__ */ new Map();
545
+ if (!isPositiveInteger(limit)) limit = Infinity;
538
546
  for (const [key, item] of ((_a = data == null ? void 0 : data.entries) == null ? void 0 : _a.call(data)) || []) {
539
547
  if (result.size >= limit) break;
540
548
  fallbackIfFails_default(predicate != null ? predicate : item, [item, key, data], false) && result.set(key, item);
@@ -571,11 +579,23 @@ var search = (data, options) => {
571
579
  const result = isMap(options == null ? void 0 : options.result) ? options.result : /* @__PURE__ */ new Map();
572
580
  const asMap = (_a = options == null ? void 0 : options.asMap) != null ? _a : search.defaultOptions.asMap;
573
581
  if (ignore) return asMap ? result : getValues_default(result);
574
- options = objCopy(search.defaultOptions, options, [], "empty");
575
- const { ignoreCase, limit = Infinity, matchAll, matchExact } = options;
582
+ options = objCopy(
583
+ search.defaultOptions,
584
+ options,
585
+ [],
586
+ "empty"
587
+ // override `option` property with default value when "empty" (undefined, null, '',....)
588
+ );
589
+ const {
590
+ ignoreCase,
591
+ limit = Infinity,
592
+ matchAll,
593
+ matchExact,
594
+ ranked
595
+ } = options;
576
596
  let { query } = options;
577
597
  const qIsStr = isStr(query);
578
- const qIsRegExp = !qIsStr && isRegExp(query);
598
+ const qIsRegExp = isRegExp(query);
579
599
  const qKeys = fallbackIfFails_default(Object.keys, [query], []);
580
600
  if (ignoreCase && !matchExact && !qIsRegExp) {
581
601
  query = qIsStr ? query.toLowerCase() : objCreate(
@@ -586,15 +606,45 @@ var search = (data, options) => {
586
606
  );
587
607
  }
588
608
  options.query = query;
589
- const entries = data.entries();
590
- for (const [dataKey, dataValue] of entries) {
591
- if (result.size >= limit) break;
592
- const matched = qIsStr || qIsRegExp ? matchItemOrProp(options, dataValue, void 0) : qKeys[matchAll ? "every" : "some"](
593
- (key) => matchItemOrProp(options, dataValue, key)
594
- // search specific properties
595
- );
596
- if (!matched) continue;
597
- result.set(dataKey, dataValue);
609
+ if (!ranked) {
610
+ for (const [dataKey, dataValue] of data.entries()) {
611
+ if (result.size >= limit) break;
612
+ const matched = qIsStr || qIsRegExp ? (
613
+ // global search across all properties
614
+ matchObjOrProp(options, dataValue, void 0) >= 0
615
+ ) : (
616
+ // field-specific search
617
+ qKeys[matchAll ? "every" : "some"](
618
+ (key) => matchObjOrProp(options, dataValue, key) >= 0
619
+ )
620
+ );
621
+ if (!matched) continue;
622
+ result.set(dataKey, dataValue);
623
+ }
624
+ } else {
625
+ const preRankedResults = [];
626
+ for (const [dataKey, dataValue] of data.entries()) {
627
+ let matchIndex = -1;
628
+ if (qIsStr || qIsRegExp) {
629
+ matchIndex = matchObjOrProp(options, dataValue, void 0);
630
+ matchIndex >= 0 && preRankedResults.push([matchIndex, dataKey, dataValue]);
631
+ continue;
632
+ }
633
+ const indexes = [];
634
+ const match = qKeys[matchAll ? "every" : "some"](
635
+ // field-specific search
636
+ (key) => {
637
+ const index = matchObjOrProp(options, dataValue, key);
638
+ indexes.push(index);
639
+ return index >= 0;
640
+ }
641
+ );
642
+ if (!match) continue;
643
+ matchIndex = // eslint-disable-next-line @typescript-eslint/prefer-find
644
+ indexes.sort((a, b) => a - b).filter((n) => n !== -1)[0];
645
+ matchIndex >= 0 && preRankedResults.push([matchIndex, dataKey, dataValue]);
646
+ }
647
+ preRankedResults.sort((a, b) => a[0] - b[0]).slice(0, limit).forEach(([_, key, value]) => result.set(key, value));
598
648
  }
599
649
  return asMap ? result : getValues_default(result);
600
650
  };
@@ -603,37 +653,37 @@ search.defaultOptions = {
603
653
  ignoreCase: true,
604
654
  limit: Infinity,
605
655
  matchAll: false,
606
- matchExact: false
656
+ ranked: false,
657
+ transform: true
607
658
  };
608
- function matchItemOrProp({
659
+ function matchObjOrProp({
609
660
  query,
610
661
  ignoreCase,
611
662
  matchExact,
612
- transform
663
+ transform = true
613
664
  }, item, propertyName) {
614
665
  var _a, _b;
615
- const fuzzy = isStr(query) || isRegExp(query) || propertyName === void 0;
616
- const keyword = fuzzy ? query : query[propertyName];
617
- const propVal = fuzzy || !isObj(item) ? item : item[propertyName];
618
- let value = fallbackIfFails_default(
619
- () => {
620
- var _a2;
621
- return isFn(transform) ? transform(
622
- item,
623
- fuzzy ? void 0 : propVal,
624
- propertyName
625
- ) : isObj(propVal, false) ? JSON.stringify(
626
- isArrLike(propVal) ? [...propVal.values()] : Object.values(propVal)
627
- ) : (_a2 = propVal == null ? void 0 : propVal.toString) == null ? void 0 : _a2.call(propVal);
628
- },
666
+ const global = isStr(query) || isRegExp(query) || propertyName === void 0;
667
+ const keyword = global ? query : query[propertyName];
668
+ const propVal = global || !isObj(item) ? item : item[propertyName];
669
+ const value = fallbackIfFails_default(
670
+ () => isFn(transform) ? transform(
671
+ item,
672
+ global ? void 0 : propVal,
673
+ propertyName
674
+ ) : matchExact && transform === false ? propVal : isObj(propVal, false) ? JSON.stringify(
675
+ isArrLike(propVal) ? [...propVal.values()] : Object.values(propVal)
676
+ ) : String(propVal != null ? propVal : ""),
629
677
  [],
630
678
  ""
631
679
  );
632
- if (!(value == null ? void 0 : value.trim())) return false;
633
- if (isRegExp(keyword)) return keyword.test(`${value}`);
634
- if (ignoreCase && !matchExact) value = value.toLowerCase();
635
- if (value === keyword) return true;
636
- return !matchExact && `${value}`.includes((_b = (_a = keyword == null ? void 0 : keyword.toString) == null ? void 0 : _a.call(keyword)) != null ? _b : "");
680
+ if (value === keyword) return 0;
681
+ if (matchExact) return -1;
682
+ let valueStr = String(value);
683
+ if (!valueStr.trim()) return -1;
684
+ if (isRegExp(keyword)) return (_b = (_a = valueStr.match(keyword)) == null ? void 0 : _a.index) != null ? _b : -1;
685
+ if (ignoreCase) valueStr = valueStr.toLowerCase();
686
+ return valueStr.indexOf(String(keyword));
637
687
  }
638
688
  var search_default = search;
639
689
 
@@ -669,9 +719,13 @@ var reverse = (data, reverse2 = true, newInstance = false) => {
669
719
  if (!dataType) return [];
670
720
  const arr = dataType === 1 ? !newInstance ? data : [...data] : dataType === 2 ? [...data.entries()] : [...data.values()];
671
721
  if (reverse2) arr.reverse();
672
- if (dataType === 1) return arr;
673
- if (newInstance || !("clear" in data && isFn(data.clear))) {
674
- return dataType === 2 ? new Map(arr) : dataType === 3 && new Set(arr) || [];
722
+ switch (dataType) {
723
+ case 1:
724
+ return arr;
725
+ case 2:
726
+ case 3:
727
+ if (newInstance || !("clear" in data && isFn(data.clear)))
728
+ return dataType === 2 ? new Map(arr) : new Set(arr);
675
729
  }
676
730
  (_a = data == null ? void 0 : data.clear) == null ? void 0 : _a.call(data);
677
731
  for (const item of arr)
@@ -782,7 +836,7 @@ var copyToClipboard = (str) => fallbackIfFails(
782
836
  () => navigator.clipboard.writeText(str).then(() => 1),
783
837
  [],
784
838
  // If clipboard API is not available or fails, use the fallback method
785
- () => Promise.resolve(copyLegacy(str))
839
+ () => Promise.resolve(copyLegacy(str) ? 2 : 0)
786
840
  );
787
841
  var copyLegacy = (str) => fallbackIfFails(
788
842
  () => {
@@ -795,11 +849,11 @@ var copyLegacy = (str) => fallbackIfFails(
795
849
  el.select();
796
850
  const success = document.execCommand("copy");
797
851
  document.body.removeChild(el);
798
- return success ? 2 : 0;
852
+ return success;
799
853
  },
800
854
  [],
801
- 0
802
- // On error, resolve with 0
855
+ false
856
+ // On error, return false
803
857
  );
804
858
 
805
859
  // src/str/getUrlParam.ts
@@ -851,6 +905,9 @@ var EMAIL_REGEX = new RegExp(
851
905
  );
852
906
  var HEX_REGEX = /^0x[0-9a-f]+$/i;
853
907
  var HASH_REGEX = /^0x[0-9a-f]{64}$/i;
908
+
909
+ // src/str/strToArr.ts
910
+ var strToArr = (value, seperator = ",") => typeof value === "string" && value.split(seperator).filter(Boolean) || [];
854
911
  export {
855
912
  EMAIL_REGEX,
856
913
  HASH_REGEX,
@@ -910,12 +967,13 @@ export {
910
967
  isUrl,
911
968
  isUrlValid,
912
969
  mapJoin,
913
- matchItemOrProp,
970
+ matchObjOrProp,
914
971
  noop,
915
972
  noopAsync,
916
973
  objClean,
917
974
  objCopy,
918
975
  objCreate,
976
+ objHasKeys,
919
977
  objKeys,
920
978
  objReadOnly,
921
979
  objSetProp,
@@ -927,6 +985,7 @@ export {
927
985
  search,
928
986
  sliceMap,
929
987
  sort,
988
+ strToArr,
930
989
  throttled,
931
990
  toDatetimeLocal
932
991
  };
package/package.json CHANGED
@@ -36,10 +36,11 @@
36
36
  "_watch": "tsc -p tsconfig.json --watch",
37
37
  "build": "tsup src/index.ts --format esm --dts --clean --config ../../tsup.config.js",
38
38
  "dev": "npm run build -- --watch",
39
- "test": "cd ../../ && npm run test promise"
39
+ "start": "npm run build -- --watch",
40
+ "test": "cd ../../ && npm run test core"
40
41
  },
41
42
  "sideEffects": false,
42
43
  "type": "module",
43
44
  "types": "dist/index.d.ts",
44
- "version": "1.0.4"
45
+ "version": "1.0.6"
45
46
  }