@superutils/core 1.0.5 → 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 +2 -2
- package/dist/index.d.ts +34 -16
- package/dist/index.js +78 -35
- package/package.json +1 -1
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
|
-
//
|
|
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
|
|
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
|
@@ -966,7 +966,7 @@ type SortOptions = {
|
|
|
966
966
|
undefinedFirst?: boolean;
|
|
967
967
|
};
|
|
968
968
|
/** Search criteria for searcheing iterables */
|
|
969
|
-
type SearchOptions<K, V, AsMap extends boolean = false> = {
|
|
969
|
+
type SearchOptions<K, V, MatchExact extends boolean = false, AsMap extends boolean = false> = {
|
|
970
970
|
/** Whethere to return the result as a map (`true`) or array (`false`). Default: `true` */
|
|
971
971
|
asMap?: AsMap;
|
|
972
972
|
/** case-insensitive search for strings. Default: `false` */
|
|
@@ -974,21 +974,33 @@ type SearchOptions<K, V, AsMap extends boolean = false> = {
|
|
|
974
974
|
/** limit number of results. Default: `Infinity` */
|
|
975
975
|
limit?: number;
|
|
976
976
|
/** partial match for values. Default: `false` */
|
|
977
|
-
matchExact?:
|
|
977
|
+
matchExact?: MatchExact;
|
|
978
978
|
/** match all supplied key-value pairs. Default: `false` */
|
|
979
979
|
matchAll?: boolean;
|
|
980
980
|
/** key-value pairs */
|
|
981
|
-
query: Record<
|
|
981
|
+
query: Record<PropertyKey, unknown> | RegExp | string;
|
|
982
|
+
/** If `true`, the results are sorted by relevance (match index). Default: `false` */
|
|
983
|
+
ranked?: boolean;
|
|
982
984
|
/** Map to store results in. Default: `new Map()` */
|
|
983
985
|
result?: Map<K, V>;
|
|
984
|
-
/**
|
|
985
|
-
|
|
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 | ((
|
|
986
998
|
/** List item */
|
|
987
999
|
item: V,
|
|
988
|
-
/** Item property value or `undefined` for
|
|
1000
|
+
/** Item property value or `undefined` for global search across all properties. */
|
|
989
1001
|
value?: V[keyof V],
|
|
990
|
-
/** Item property key provided by query or `undefined` for
|
|
991
|
-
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);
|
|
992
1004
|
};
|
|
993
1005
|
|
|
994
1006
|
/**
|
|
@@ -1085,8 +1097,8 @@ declare const getValues: <K, V>(data: IterableList<K, V>) => V[];
|
|
|
1085
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>);
|
|
1086
1098
|
|
|
1087
1099
|
/**
|
|
1088
|
-
* A versatile utility for searching through an iterable list (
|
|
1089
|
-
* It supports both 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
|
|
1090
1102
|
* detailed, field-specific search using a query object.
|
|
1091
1103
|
*
|
|
1092
1104
|
* @param data The list of objects to search within. Compatible types include:
|
|
@@ -1097,6 +1109,8 @@ declare const reverse: <K, V, T extends IterableList<K, V>>(data: T, reverse?: b
|
|
|
1097
1109
|
* - `HTMLCollection` (in DOM environments): should accompany `options.transform()`
|
|
1098
1110
|
* @param options The search criteria.
|
|
1099
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
|
+
*
|
|
1100
1114
|
* searches (e.g., `{ name: 'John', city: 'New York' }`).
|
|
1101
1115
|
* @param options.asMap (optional) If `true`, returns a `Map`. If `false`, returns an `Array`. Default: `true`.
|
|
1102
1116
|
* @param options.ignoreCase (optional) If `true`, performs a case-insensitive search for strings. Default: `true`.
|
|
@@ -1131,12 +1145,16 @@ declare const reverse: <K, V, T extends IterableList<K, V>>(data: T, reverse?: b
|
|
|
1131
1145
|
* ```
|
|
1132
1146
|
*/
|
|
1133
1147
|
declare const search: {
|
|
1134
|
-
<K, V, AsMap extends boolean = true, Result = AsMap extends true ? Map<K, V> : V[]>(data: IterableList<K, V>, options: SearchOptions<K, V, AsMap>): Result;
|
|
1135
|
-
defaultOptions: Pick<Required<SearchOptions<unknown, unknown, true>>, "matchAll" | "limit" | "asMap" | "ignoreCase" | "
|
|
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">;
|
|
1136
1150
|
};
|
|
1137
|
-
/**
|
|
1138
|
-
|
|
1139
|
-
|
|
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;
|
|
1140
1158
|
|
|
1141
1159
|
type SliceMapTransform<Data, Value, Key> = (item: Value, key: Key, data: Data) => Value;
|
|
1142
1160
|
type SliceMapOptions<Data, Value, Key, AsMap extends boolean = false> = {
|
|
@@ -1356,4 +1374,4 @@ declare const HASH_REGEX: RegExp;
|
|
|
1356
1374
|
*/
|
|
1357
1375
|
declare const strToArr: (value: unknown, seperator?: string) => string[];
|
|
1358
1376
|
|
|
1359
|
-
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,
|
|
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
|
@@ -579,11 +579,23 @@ var search = (data, options) => {
|
|
|
579
579
|
const result = isMap(options == null ? void 0 : options.result) ? options.result : /* @__PURE__ */ new Map();
|
|
580
580
|
const asMap = (_a = options == null ? void 0 : options.asMap) != null ? _a : search.defaultOptions.asMap;
|
|
581
581
|
if (ignore) return asMap ? result : getValues_default(result);
|
|
582
|
-
options = objCopy(
|
|
583
|
-
|
|
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;
|
|
584
596
|
let { query } = options;
|
|
585
597
|
const qIsStr = isStr(query);
|
|
586
|
-
const qIsRegExp =
|
|
598
|
+
const qIsRegExp = isRegExp(query);
|
|
587
599
|
const qKeys = fallbackIfFails_default(Object.keys, [query], []);
|
|
588
600
|
if (ignoreCase && !matchExact && !qIsRegExp) {
|
|
589
601
|
query = qIsStr ? query.toLowerCase() : objCreate(
|
|
@@ -594,15 +606,45 @@ var search = (data, options) => {
|
|
|
594
606
|
);
|
|
595
607
|
}
|
|
596
608
|
options.query = query;
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
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));
|
|
606
648
|
}
|
|
607
649
|
return asMap ? result : getValues_default(result);
|
|
608
650
|
};
|
|
@@ -611,36 +653,37 @@ search.defaultOptions = {
|
|
|
611
653
|
ignoreCase: true,
|
|
612
654
|
limit: Infinity,
|
|
613
655
|
matchAll: false,
|
|
614
|
-
|
|
656
|
+
ranked: false,
|
|
657
|
+
transform: true
|
|
615
658
|
};
|
|
616
|
-
function
|
|
659
|
+
function matchObjOrProp({
|
|
617
660
|
query,
|
|
618
661
|
ignoreCase,
|
|
619
662
|
matchExact,
|
|
620
|
-
transform
|
|
663
|
+
transform = true
|
|
621
664
|
}, item, propertyName) {
|
|
622
|
-
|
|
623
|
-
const
|
|
624
|
-
const
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
)
|
|
633
|
-
|
|
634
|
-
) : (_a = propVal == null ? void 0 : propVal.toString) == null ? void 0 : _a.call(propVal);
|
|
635
|
-
},
|
|
665
|
+
var _a, _b;
|
|
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 : ""),
|
|
636
677
|
[],
|
|
637
678
|
""
|
|
638
679
|
);
|
|
639
|
-
if (
|
|
640
|
-
if (
|
|
641
|
-
|
|
642
|
-
if (
|
|
643
|
-
return
|
|
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));
|
|
644
687
|
}
|
|
645
688
|
var search_default = search;
|
|
646
689
|
|
|
@@ -924,7 +967,7 @@ export {
|
|
|
924
967
|
isUrl,
|
|
925
968
|
isUrlValid,
|
|
926
969
|
mapJoin,
|
|
927
|
-
|
|
970
|
+
matchObjOrProp,
|
|
928
971
|
noop,
|
|
929
972
|
noopAsync,
|
|
930
973
|
objClean,
|
package/package.json
CHANGED