@ls-stack/utils 1.0.0 → 1.2.0

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.
@@ -24,7 +24,7 @@ type SortOrder = 'desc' | 'asc';
24
24
  *
25
25
  * Sort by `ascending` order by default
26
26
  *
27
- * Use `Infinity` as as wildcard to absulute max and min values
27
+ * Use `Infinity` as as wildcard to absolute max and min values
28
28
  *
29
29
  * @example
30
30
  * const items = [1, 3, 2, 4];
@@ -37,14 +37,15 @@ type SortOrder = 'desc' | 'asc';
37
37
  * // return a array to sort by multiple values
38
38
  * const sortedItems = sortBy(items, (item) => [item.a, item.b]);
39
39
  **/
40
- declare function sortBy<T>(arr: T[], sortByValue: (item: T) => (number | string)[] | number | string, { order }?: {
40
+ declare function sortBy<T>(arr: T[], sortByValue: (item: T) => (number | string)[] | number | string, props?: {
41
41
  order?: SortOrder | SortOrder[];
42
- }): T[];
42
+ } | SortOrder | SortOrder[]): T[];
43
43
  declare function arrayWithPrev<T>(array: T[]): [current: T, prev: T | null][];
44
44
  declare function arrayWithPrevAndIndex<T>(array: T[]): {
45
45
  item: T;
46
46
  prev: T | null;
47
47
  index: number;
48
48
  }[];
49
+ declare function isInArray<T, const U extends T>(value: T, oneOf: readonly U[]): value is U;
49
50
 
50
- export { type FilterAndMapReturn, arrayWithPrev, arrayWithPrevAndIndex, filterAndMap, sortBy };
51
+ export { type FilterAndMapReturn, arrayWithPrev, arrayWithPrevAndIndex, filterAndMap, isInArray, sortBy };
@@ -2,12 +2,14 @@ import {
2
2
  arrayWithPrev,
3
3
  arrayWithPrevAndIndex,
4
4
  filterAndMap,
5
+ isInArray,
5
6
  sortBy
6
- } from "./chunk-5SB253CL.js";
7
+ } from "./chunk-W7X6NSGR.js";
7
8
  export {
8
9
  arrayWithPrev,
9
10
  arrayWithPrevAndIndex,
10
11
  filterAndMap,
12
+ isInArray,
11
13
  sortBy
12
14
  };
13
15
  //# sourceMappingURL=arrayUtils.js.map
@@ -11,7 +11,8 @@ function filterAndMap(array, mapFilter) {
11
11
  }
12
12
  return result;
13
13
  }
14
- function sortBy(arr, sortByValue, { order = "asc" } = {}) {
14
+ function sortBy(arr, sortByValue, props = "asc") {
15
+ const order = Array.isArray(props) || typeof props === "string" ? props : props.order ?? "asc";
15
16
  return [...arr].sort((a, b) => {
16
17
  const _aPriority = sortByValue(a);
17
18
  const _bPriority = sortByValue(b);
@@ -44,11 +45,20 @@ function arrayWithPrevAndIndex(array) {
44
45
  index: i
45
46
  }));
46
47
  }
48
+ function isInArray(value, oneOf) {
49
+ for (let i = 0; i < oneOf.length; i++) {
50
+ if (oneOf[i] === value) {
51
+ return true;
52
+ }
53
+ }
54
+ return false;
55
+ }
47
56
 
48
57
  export {
49
58
  filterAndMap,
50
59
  sortBy,
51
60
  arrayWithPrev,
52
- arrayWithPrevAndIndex
61
+ arrayWithPrevAndIndex,
62
+ isInArray
53
63
  };
54
- //# sourceMappingURL=chunk-5SB253CL.js.map
64
+ //# sourceMappingURL=chunk-W7X6NSGR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/arrayUtils.ts"],"sourcesContent":["/**\n * allow to filter and map with better typing ergonomics\n *\n * In the `mapFilter` function return `false` to reject the item, or any other\n * value to map it.\n *\n * @example\n * // Filter reject and turn value into `value mapped`\n * const items = ['value', 'value', 'reject', 'reject'];\n *\n * const mappedItems = filterAndMap(items, (item) =>\n * item === 'reject'\n * ? false\n * : `${item} mapped`,\n * );\n *\n * mappedItems; // ['value mapped', 'value mapped']\n */\nexport function filterAndMap<T, R>(\n array: IterableIterator<T> | readonly T[],\n mapFilter: (item: T, index: number) => false | R,\n): R[] {\n const result: R[] = [];\n\n let i = -1;\n for (const item of array) {\n i += 1;\n const filterResult = mapFilter(item, i);\n\n if (filterResult !== false) {\n result.push(filterResult);\n }\n }\n\n return result;\n}\n\nexport type FilterAndMapReturn<T> = false | T;\n\ntype SortOrder = 'desc' | 'asc';\n\n/**\n * Sort an array based on a value\n *\n * Sort by `ascending` order by default\n *\n * Use `Infinity` as as wildcard to absolute max and min values\n *\n * @example\n * const items = [1, 3, 2, 4];\n *\n * const sortedItems = sortBy(items, (item) => item);\n * // [1, 2, 3, 4]\n *\n * const items2 = [{ a: 1, b: 2 }, { a: 2, b: 1 }, { a: 1, b: 1}]\n *\n * // return a array to sort by multiple values\n * const sortedItems = sortBy(items, (item) => [item.a, item.b]);\n **/\nexport function sortBy<T>(\n arr: T[],\n sortByValue: (item: T) => (number | string)[] | number | string,\n props: { order?: SortOrder | SortOrder[] } | SortOrder | SortOrder[] = 'asc',\n) {\n const order =\n Array.isArray(props) || typeof props === 'string' ?\n props\n : props.order ?? 'asc';\n\n return [...arr].sort((a, b) => {\n const _aPriority = sortByValue(a);\n const _bPriority = sortByValue(b);\n\n const aPriority = Array.isArray(_aPriority) ? _aPriority : [_aPriority];\n const bPriority = Array.isArray(_bPriority) ? _bPriority : [_bPriority];\n\n for (let i = 0; i < aPriority.length; i++) {\n const levelOrder: SortOrder =\n typeof order === 'string' ? order : order[i] ?? 'asc';\n\n const aP = aPriority[i] ?? 0;\n const bP = bPriority[i] ?? 0;\n\n if (aP === bP) {\n continue;\n }\n\n if (bP === Infinity || aP === -Infinity || aP < bP) {\n return levelOrder === 'asc' ? -1 : 1;\n }\n\n if (aP === Infinity || bP === -Infinity || aP > bP) {\n return levelOrder === 'asc' ? 1 : -1;\n }\n }\n\n return 0;\n });\n}\n\nexport function arrayWithPrev<T>(array: T[]): [current: T, prev: T | null][] {\n return array.map((item, i) => [item, array[i - 1] ?? null]);\n}\n\nexport function arrayWithPrevAndIndex<T>(\n array: T[],\n): { item: T; prev: T | null; index: number }[] {\n return array.map((item, i) => ({\n item,\n prev: array[i - 1] ?? null,\n index: i,\n }));\n}\n\nexport function isInArray<T, const U extends T>(\n value: T,\n oneOf: readonly U[],\n): value is U {\n for (let i = 0; i < oneOf.length; i++) {\n if (oneOf[i] === value) {\n return true;\n }\n }\n\n return false;\n}\n"],"mappings":";AAkBO,SAAS,aACd,OACA,WACK;AACL,QAAM,SAAc,CAAC;AAErB,MAAI,IAAI;AACR,aAAW,QAAQ,OAAO;AACxB,SAAK;AACL,UAAM,eAAe,UAAU,MAAM,CAAC;AAEtC,QAAI,iBAAiB,OAAO;AAC1B,aAAO,KAAK,YAAY;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO;AACT;AAwBO,SAAS,OACd,KACA,aACA,QAAuE,OACvE;AACA,QAAM,QACJ,MAAM,QAAQ,KAAK,KAAK,OAAO,UAAU,WACvC,QACA,MAAM,SAAS;AAEnB,SAAO,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM;AAC7B,UAAM,aAAa,YAAY,CAAC;AAChC,UAAM,aAAa,YAAY,CAAC;AAEhC,UAAM,YAAY,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,UAAU;AACtE,UAAM,YAAY,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,UAAU;AAEtE,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,YAAM,aACJ,OAAO,UAAU,WAAW,QAAQ,MAAM,CAAC,KAAK;AAElD,YAAM,KAAK,UAAU,CAAC,KAAK;AAC3B,YAAM,KAAK,UAAU,CAAC,KAAK;AAE3B,UAAI,OAAO,IAAI;AACb;AAAA,MACF;AAEA,UAAI,OAAO,YAAY,OAAO,aAAa,KAAK,IAAI;AAClD,eAAO,eAAe,QAAQ,KAAK;AAAA,MACrC;AAEA,UAAI,OAAO,YAAY,OAAO,aAAa,KAAK,IAAI;AAClD,eAAO,eAAe,QAAQ,IAAI;AAAA,MACpC;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAEO,SAAS,cAAiB,OAA4C;AAC3E,SAAO,MAAM,IAAI,CAAC,MAAM,MAAM,CAAC,MAAM,MAAM,IAAI,CAAC,KAAK,IAAI,CAAC;AAC5D;AAEO,SAAS,sBACd,OAC8C;AAC9C,SAAO,MAAM,IAAI,CAAC,MAAM,OAAO;AAAA,IAC7B;AAAA,IACA,MAAM,MAAM,IAAI,CAAC,KAAK;AAAA,IACtB,OAAO;AAAA,EACT,EAAE;AACJ;AAEO,SAAS,UACd,OACA,OACY;AACZ,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,QAAI,MAAM,CAAC,MAAM,OAAO;AACtB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,45 @@
1
+ type DebounceOptions = {
2
+ /**
3
+ * @see _.leading
4
+ */
5
+ leading?: boolean;
6
+ /**
7
+ * @see _.maxWait
8
+ */
9
+ maxWait?: number;
10
+ /**
11
+ * @see _.trailing
12
+ */
13
+ trailing?: boolean;
14
+ };
15
+ interface DebouncedFunc<T extends (...args: any[]) => void> {
16
+ /**
17
+ * Call the original function, but applying the debounce rules.
18
+ *
19
+ * If the debounced function can be run immediately, this calls it and returns its return
20
+ * value.
21
+ *
22
+ * Otherwise, it returns the return value of the last invocation, or undefined if the debounced
23
+ * function was not invoked yet.
24
+ */
25
+ (...args: Parameters<T>): ReturnType<T> | undefined;
26
+ /**
27
+ * Throw away any pending invocation of the debounced function.
28
+ */
29
+ cancel: () => void;
30
+ /**
31
+ * If there is a pending invocation of the debounced function, invoke it immediately and return
32
+ * its return value.
33
+ *
34
+ * Otherwise, return the value from the last invocation, or undefined if the debounced function
35
+ * was never invoked.
36
+ */
37
+ flush: () => ReturnType<T> | undefined;
38
+ }
39
+ declare function debounce<T extends (...args: any[]) => void>(func: T, wait: number, options?: DebounceOptions): DebouncedFunc<T>;
40
+ declare function isDebouncedFn<T extends (...args: any[]) => void>(fn: T): fn is T & {
41
+ cancel: () => void;
42
+ flush: () => ReturnType<T> | undefined;
43
+ };
44
+
45
+ export { type DebounceOptions, type DebouncedFunc, debounce, isDebouncedFn };
@@ -0,0 +1,100 @@
1
+ // src/debounce.ts
2
+ function debounce(func, wait, options) {
3
+ let lastArgs;
4
+ let lastThis;
5
+ let maxWait;
6
+ let result;
7
+ let timerId;
8
+ let lastCallTime;
9
+ let lastInvokeTime = 0;
10
+ let leading = false;
11
+ let maxing = false;
12
+ let trailing = true;
13
+ if (options) {
14
+ leading = !!options.leading;
15
+ maxing = "maxWait" in options;
16
+ maxWait = maxing ? Math.max(options.maxWait || 0, wait) : maxWait;
17
+ trailing = "trailing" in options ? !!options.trailing : trailing;
18
+ }
19
+ function invokeFunc(time) {
20
+ const args = lastArgs;
21
+ const thisArg = lastThis;
22
+ lastArgs = lastThis = void 0;
23
+ lastInvokeTime = time;
24
+ result = func.apply(thisArg, args);
25
+ return result;
26
+ }
27
+ function leadingEdge(time) {
28
+ lastInvokeTime = time;
29
+ timerId = setTimeout(timerExpired, wait);
30
+ return leading ? invokeFunc(time) : result;
31
+ }
32
+ function remainingWait(time) {
33
+ const timeSinceLastCall = time - (lastCallTime ?? 0);
34
+ const timeSinceLastInvoke = time - lastInvokeTime;
35
+ const timeWaiting = wait - timeSinceLastCall;
36
+ return maxing ? Math.min(timeWaiting, (maxWait ?? 0) - timeSinceLastInvoke) : timeWaiting;
37
+ }
38
+ function shouldInvoke(time) {
39
+ const timeSinceLastCall = time - (lastCallTime ?? 0);
40
+ const timeSinceLastInvoke = time - lastInvokeTime;
41
+ return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= (maxWait ?? 0);
42
+ }
43
+ function timerExpired() {
44
+ const time = Date.now();
45
+ if (shouldInvoke(time)) {
46
+ return trailingEdge(time);
47
+ }
48
+ timerId = setTimeout(timerExpired, remainingWait(time));
49
+ }
50
+ function trailingEdge(time) {
51
+ timerId = void 0;
52
+ if (trailing && lastArgs) {
53
+ return invokeFunc(time);
54
+ }
55
+ lastArgs = lastThis = void 0;
56
+ return result;
57
+ }
58
+ function cancel() {
59
+ if (timerId !== void 0) {
60
+ clearTimeout(timerId);
61
+ }
62
+ lastInvokeTime = 0;
63
+ lastArgs = lastCallTime = lastThis = timerId = void 0;
64
+ }
65
+ function flush() {
66
+ return timerId === void 0 ? result : trailingEdge(Date.now());
67
+ }
68
+ function debounced() {
69
+ const time = Date.now();
70
+ const isInvoking = shouldInvoke(time);
71
+ lastArgs = arguments;
72
+ lastThis = this;
73
+ lastCallTime = time;
74
+ if (isInvoking) {
75
+ if (timerId === void 0) {
76
+ return leadingEdge(lastCallTime);
77
+ }
78
+ if (maxing) {
79
+ clearTimeout(timerId);
80
+ timerId = setTimeout(timerExpired, wait);
81
+ return invokeFunc(lastCallTime);
82
+ }
83
+ }
84
+ if (timerId === void 0) {
85
+ timerId = setTimeout(timerExpired, wait);
86
+ }
87
+ return result;
88
+ }
89
+ debounced.cancel = cancel;
90
+ debounced.flush = flush;
91
+ return debounced;
92
+ }
93
+ function isDebouncedFn(fn) {
94
+ return typeof fn === "function" && "cancel" in fn && "flush" in fn;
95
+ }
96
+ export {
97
+ debounce,
98
+ isDebouncedFn
99
+ };
100
+ //# sourceMappingURL=debounce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/debounce.ts"],"sourcesContent":["export type DebounceOptions = {\n /**\n * @see _.leading\n */\n leading?: boolean;\n /**\n * @see _.maxWait\n */\n maxWait?: number;\n /**\n * @see _.trailing\n */\n trailing?: boolean;\n};\n\nexport interface DebouncedFunc<T extends (...args: any[]) => void> {\n /**\n * Call the original function, but applying the debounce rules.\n *\n * If the debounced function can be run immediately, this calls it and returns its return\n * value.\n *\n * Otherwise, it returns the return value of the last invocation, or undefined if the debounced\n * function was not invoked yet.\n */\n (...args: Parameters<T>): ReturnType<T> | undefined;\n\n /**\n * Throw away any pending invocation of the debounced function.\n */\n cancel: () => void;\n\n /**\n * If there is a pending invocation of the debounced function, invoke it immediately and return\n * its return value.\n *\n * Otherwise, return the value from the last invocation, or undefined if the debounced function\n * was never invoked.\n */\n flush: () => ReturnType<T> | undefined;\n}\n\n// forked from lodash/debounce\nexport function debounce<T extends (...args: any[]) => void>(\n func: T,\n wait: number,\n options?: DebounceOptions,\n): DebouncedFunc<T> {\n let lastArgs: IArguments | undefined;\n let lastThis: undefined;\n let maxWait: number | undefined;\n let result: any;\n let timerId: NodeJS.Timeout | undefined;\n let lastCallTime: number | undefined;\n let lastInvokeTime = 0;\n let leading = false;\n let maxing = false;\n let trailing = true;\n\n if (options) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? Math.max(options.maxWait || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time: number) {\n const args = lastArgs;\n const thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n result = func.apply(thisArg, args as any);\n return result;\n }\n\n function leadingEdge(time: number) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time: number) {\n const timeSinceLastCall = time - (lastCallTime ?? 0);\n const timeSinceLastInvoke = time - lastInvokeTime;\n const timeWaiting = wait - timeSinceLastCall;\n\n return maxing ?\n Math.min(timeWaiting, (maxWait ?? 0) - timeSinceLastInvoke)\n : timeWaiting;\n }\n\n function shouldInvoke(time: number) {\n const timeSinceLastCall = time - (lastCallTime ?? 0);\n const timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (\n lastCallTime === undefined ||\n timeSinceLastCall >= wait ||\n timeSinceLastCall < 0 ||\n (maxing && timeSinceLastInvoke >= (maxWait ?? 0))\n );\n }\n\n function timerExpired() {\n const time = Date.now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time: number) {\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(Date.now());\n }\n\n function debounced(this: any) {\n const time = Date.now();\n const isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n // eslint-disable-next-line @typescript-eslint/no-this-alias -- this is a forked code, so a refactor is not worth it\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n clearTimeout(timerId);\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n\n return debounced;\n}\n\nexport function isDebouncedFn<T extends (...args: any[]) => void>(\n fn: T,\n): fn is T & {\n cancel: () => void;\n flush: () => ReturnType<T> | undefined;\n} {\n return typeof fn === 'function' && 'cancel' in fn && 'flush' in fn;\n}\n"],"mappings":";AA2CO,SAAS,SACd,MACA,MACA,SACkB;AAClB,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI,iBAAiB;AACrB,MAAI,UAAU;AACd,MAAI,SAAS;AACb,MAAI,WAAW;AAEf,MAAI,SAAS;AACX,cAAU,CAAC,CAAC,QAAQ;AACpB,aAAS,aAAa;AACtB,cAAU,SAAS,KAAK,IAAI,QAAQ,WAAW,GAAG,IAAI,IAAI;AAC1D,eAAW,cAAc,UAAU,CAAC,CAAC,QAAQ,WAAW;AAAA,EAC1D;AAEA,WAAS,WAAW,MAAc;AAChC,UAAM,OAAO;AACb,UAAM,UAAU;AAEhB,eAAW,WAAW;AACtB,qBAAiB;AAEjB,aAAS,KAAK,MAAM,SAAS,IAAW;AACxC,WAAO;AAAA,EACT;AAEA,WAAS,YAAY,MAAc;AAEjC,qBAAiB;AAEjB,cAAU,WAAW,cAAc,IAAI;AAEvC,WAAO,UAAU,WAAW,IAAI,IAAI;AAAA,EACtC;AAEA,WAAS,cAAc,MAAc;AACnC,UAAM,oBAAoB,QAAQ,gBAAgB;AAClD,UAAM,sBAAsB,OAAO;AACnC,UAAM,cAAc,OAAO;AAE3B,WAAO,SACH,KAAK,IAAI,cAAc,WAAW,KAAK,mBAAmB,IAC1D;AAAA,EACN;AAEA,WAAS,aAAa,MAAc;AAClC,UAAM,oBAAoB,QAAQ,gBAAgB;AAClD,UAAM,sBAAsB,OAAO;AAKnC,WACE,iBAAiB,UACjB,qBAAqB,QACrB,oBAAoB,KACnB,UAAU,wBAAwB,WAAW;AAAA,EAElD;AAEA,WAAS,eAAe;AACtB,UAAM,OAAO,KAAK,IAAI;AACtB,QAAI,aAAa,IAAI,GAAG;AACtB,aAAO,aAAa,IAAI;AAAA,IAC1B;AAEA,cAAU,WAAW,cAAc,cAAc,IAAI,CAAC;AAAA,EACxD;AAEA,WAAS,aAAa,MAAc;AAClC,cAAU;AAIV,QAAI,YAAY,UAAU;AACxB,aAAO,WAAW,IAAI;AAAA,IACxB;AACA,eAAW,WAAW;AACtB,WAAO;AAAA,EACT;AAEA,WAAS,SAAS;AAChB,QAAI,YAAY,QAAW;AACzB,mBAAa,OAAO;AAAA,IACtB;AACA,qBAAiB;AACjB,eAAW,eAAe,WAAW,UAAU;AAAA,EACjD;AAEA,WAAS,QAAQ;AACf,WAAO,YAAY,SAAY,SAAS,aAAa,KAAK,IAAI,CAAC;AAAA,EACjE;AAEA,WAAS,YAAqB;AAC5B,UAAM,OAAO,KAAK,IAAI;AACtB,UAAM,aAAa,aAAa,IAAI;AAEpC,eAAW;AAEX,eAAW;AACX,mBAAe;AAEf,QAAI,YAAY;AACd,UAAI,YAAY,QAAW;AACzB,eAAO,YAAY,YAAY;AAAA,MACjC;AACA,UAAI,QAAQ;AAEV,qBAAa,OAAO;AACpB,kBAAU,WAAW,cAAc,IAAI;AACvC,eAAO,WAAW,YAAY;AAAA,MAChC;AAAA,IACF;AACA,QAAI,YAAY,QAAW;AACzB,gBAAU,WAAW,cAAc,IAAI;AAAA,IACzC;AACA,WAAO;AAAA,EACT;AACA,YAAU,SAAS;AACnB,YAAU,QAAQ;AAElB,SAAO;AACT;AAEO,SAAS,cACd,IAIA;AACA,SAAO,OAAO,OAAO,cAAc,YAAY,MAAM,WAAW;AAClE;","names":[]}
package/dist/main.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  ///<reference path="consoleFmt.d.ts" />
5
5
  ///<reference path="conversions.d.ts" />
6
6
  ///<reference path="createThrottleController.d.ts" />
7
+ ///<reference path="debounce.d.ts" />
7
8
  ///<reference path="dedent.d.ts" />
8
9
  ///<reference path="deepEqual.d.ts" />
9
10
  ///<reference path="enhancedMap.d.ts" />
@@ -1,10 +1,10 @@
1
- import {
2
- sleep
3
- } from "./chunk-HLFWWIDK.js";
4
1
  import {
5
2
  Result,
6
3
  normalizeError
7
4
  } from "./chunk-HYFUWQ2E.js";
5
+ import {
6
+ sleep
7
+ } from "./chunk-HLFWWIDK.js";
8
8
  import "./chunk-4DRNU53E.js";
9
9
  import {
10
10
  invariant,
package/dist/testUtils.js CHANGED
@@ -1,3 +1,6 @@
1
+ import {
2
+ deepEqual
3
+ } from "./chunk-JZUOIOMU.js";
1
4
  import {
2
5
  clampMin
3
6
  } from "./chunk-J66LUDLH.js";
@@ -8,13 +11,10 @@ import {
8
11
  import {
9
12
  arrayWithPrevAndIndex,
10
13
  filterAndMap
11
- } from "./chunk-5SB253CL.js";
14
+ } from "./chunk-W7X6NSGR.js";
12
15
  import {
13
16
  isObject
14
17
  } from "./chunk-JT3EBBCA.js";
15
- import {
16
- deepEqual
17
- } from "./chunk-JZUOIOMU.js";
18
18
 
19
19
  // src/testUtils.ts
20
20
  function createLoggerStore({
@@ -1,5 +1,15 @@
1
1
  import { NonPartial } from './typingUtils.js';
2
2
 
3
3
  declare function asNonPartial<T extends Record<string, unknown>>(obj: T): NonPartial<T>;
4
+ /** a wrapper to Object.entries with a better typing inference */
5
+ declare function typedObjectEntries<T extends Record<string, unknown>>(obj: T): NonNullable<{
6
+ [K in keyof T]: [K, T[K]];
7
+ }[keyof T]>[];
8
+ /** a wrapper to Object.keys with a better typing inference */
9
+ declare function typedObjectKeys<T extends Record<string, unknown>>(obj: T): (keyof T)[];
10
+ /** a safe way to cast types, use to substitute the `as Type` */
11
+ declare function asType<T = unknown>(value: T): T;
12
+ /** narrow a string to a union of strings */
13
+ declare function narrowStringToUnion<const T extends string>(key: string | undefined | null, union: T[]): T | undefined;
4
14
 
5
- export { asNonPartial };
15
+ export { asNonPartial, asType, narrowStringToUnion, typedObjectEntries, typedObjectKeys };
@@ -2,7 +2,26 @@
2
2
  function asNonPartial(obj) {
3
3
  return obj;
4
4
  }
5
+ function typedObjectEntries(obj) {
6
+ return Object.entries(obj);
7
+ }
8
+ function typedObjectKeys(obj) {
9
+ return Object.keys(obj);
10
+ }
11
+ function asType(value) {
12
+ return value;
13
+ }
14
+ function narrowStringToUnion(key, union) {
15
+ if (key && union.includes(key)) {
16
+ return key;
17
+ }
18
+ return void 0;
19
+ }
5
20
  export {
6
- asNonPartial
21
+ asNonPartial,
22
+ asType,
23
+ narrowStringToUnion,
24
+ typedObjectEntries,
25
+ typedObjectKeys
7
26
  };
8
27
  //# sourceMappingURL=typingFnUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/typingFnUtils.ts"],"sourcesContent":["import { NonPartial } from './typingUtils';\n\nexport function asNonPartial<T extends Record<string, unknown>>(\n obj: T,\n): NonPartial<T> {\n return obj;\n}\n"],"mappings":";AAEO,SAAS,aACd,KACe;AACf,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/typingFnUtils.ts"],"sourcesContent":["import { NonPartial } from './typingUtils';\n\nexport function asNonPartial<T extends Record<string, unknown>>(\n obj: T,\n): NonPartial<T> {\n return obj;\n}\n\n/** a wrapper to Object.entries with a better typing inference */\nexport function typedObjectEntries<T extends Record<string, unknown>>(\n obj: T,\n): NonNullable<\n {\n [K in keyof T]: [K, T[K]];\n }[keyof T]\n>[] {\n return Object.entries(obj) as any;\n}\n\n/** a wrapper to Object.keys with a better typing inference */\nexport function typedObjectKeys<T extends Record<string, unknown>>(\n obj: T,\n): (keyof T)[] {\n return Object.keys(obj) as any;\n}\n\n/** a safe way to cast types, use to substitute the `as Type` */\nexport function asType<T = unknown>(value: T): T {\n return value;\n}\n\n/** narrow a string to a union of strings */\nexport function narrowStringToUnion<const T extends string>(\n key: string | undefined | null,\n union: T[],\n): T | undefined {\n if (key && union.includes(key as T)) {\n return key as T;\n }\n\n return undefined;\n}\n"],"mappings":";AAEO,SAAS,aACd,KACe;AACf,SAAO;AACT;AAGO,SAAS,mBACd,KAKE;AACF,SAAO,OAAO,QAAQ,GAAG;AAC3B;AAGO,SAAS,gBACd,KACa;AACb,SAAO,OAAO,KAAK,GAAG;AACxB;AAGO,SAAS,OAAoB,OAAa;AAC/C,SAAO;AACT;AAGO,SAAS,oBACd,KACA,OACe;AACf,MAAI,OAAO,MAAM,SAAS,GAAQ,GAAG;AACnC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ls-stack/utils",
3
3
  "description": "Typescript utils",
4
- "version": "1.0.0",
4
+ "version": "1.2.0",
5
5
  "license": "MIT",
6
6
  "files": [
7
7
  "dist"
@@ -40,6 +40,10 @@
40
40
  "import": "./dist/createThrottleController.js",
41
41
  "types": "./dist/createThrottleController.d.ts"
42
42
  },
43
+ "./debounce": {
44
+ "import": "./dist/debounce.js",
45
+ "types": "./dist/debounce.d.ts"
46
+ },
43
47
  "./dedent": {
44
48
  "import": "./dist/dedent.js",
45
49
  "types": "./dist/dedent.d.ts"
@@ -159,6 +163,9 @@
159
163
  "createThrottleController": [
160
164
  "./dist/createThrottleController.d.ts"
161
165
  ],
166
+ "debounce": [
167
+ "./dist/debounce.d.ts"
168
+ ],
162
169
  "dedent": [
163
170
  "./dist/dedent.d.ts"
164
171
  ],
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/arrayUtils.ts"],"sourcesContent":["/**\n * allow to filter and map with better typing ergonomics\n *\n * In the `mapFilter` function return `false` to reject the item, or any other\n * value to map it.\n *\n * @example\n * // Filter reject and turn value into `value mapped`\n * const items = ['value', 'value', 'reject', 'reject'];\n *\n * const mappedItems = filterAndMap(items, (item) =>\n * item === 'reject'\n * ? false\n * : `${item} mapped`,\n * );\n *\n * mappedItems; // ['value mapped', 'value mapped']\n */\nexport function filterAndMap<T, R>(\n array: IterableIterator<T> | readonly T[],\n mapFilter: (item: T, index: number) => false | R,\n): R[] {\n const result: R[] = [];\n\n let i = -1;\n for (const item of array) {\n i += 1;\n const filterResult = mapFilter(item, i);\n\n if (filterResult !== false) {\n result.push(filterResult);\n }\n }\n\n return result;\n}\n\nexport type FilterAndMapReturn<T> = false | T;\n\ntype SortOrder = 'desc' | 'asc';\n\n/**\n * Sort an array based on a value\n *\n * Sort by `ascending` order by default\n *\n * Use `Infinity` as as wildcard to absulute max and min values\n *\n * @example\n * const items = [1, 3, 2, 4];\n *\n * const sortedItems = sortBy(items, (item) => item);\n * // [1, 2, 3, 4]\n *\n * const items2 = [{ a: 1, b: 2 }, { a: 2, b: 1 }, { a: 1, b: 1}]\n *\n * // return a array to sort by multiple values\n * const sortedItems = sortBy(items, (item) => [item.a, item.b]);\n **/\nexport function sortBy<T>(\n arr: T[],\n sortByValue: (item: T) => (number | string)[] | number | string,\n { order = 'asc' }: { order?: SortOrder | SortOrder[] } = {},\n) {\n return [...arr].sort((a, b) => {\n const _aPriority = sortByValue(a);\n const _bPriority = sortByValue(b);\n\n const aPriority = Array.isArray(_aPriority) ? _aPriority : [_aPriority];\n const bPriority = Array.isArray(_bPriority) ? _bPriority : [_bPriority];\n\n for (let i = 0; i < aPriority.length; i++) {\n const levelOrder: SortOrder =\n typeof order === 'string' ? order : order[i] ?? 'asc';\n\n const aP = aPriority[i] ?? 0;\n const bP = bPriority[i] ?? 0;\n\n if (aP === bP) {\n continue;\n }\n\n if (bP === Infinity || aP === -Infinity || aP < bP) {\n return levelOrder === 'asc' ? -1 : 1;\n }\n\n if (aP === Infinity || bP === -Infinity || aP > bP) {\n return levelOrder === 'asc' ? 1 : -1;\n }\n }\n\n return 0;\n });\n}\n\nexport function arrayWithPrev<T>(array: T[]): [current: T, prev: T | null][] {\n return array.map((item, i) => [item, array[i - 1] ?? null]);\n}\n\nexport function arrayWithPrevAndIndex<T>(\n array: T[],\n): { item: T; prev: T | null; index: number }[] {\n return array.map((item, i) => ({\n item,\n prev: array[i - 1] ?? null,\n index: i,\n }));\n}\n"],"mappings":";AAkBO,SAAS,aACd,OACA,WACK;AACL,QAAM,SAAc,CAAC;AAErB,MAAI,IAAI;AACR,aAAW,QAAQ,OAAO;AACxB,SAAK;AACL,UAAM,eAAe,UAAU,MAAM,CAAC;AAEtC,QAAI,iBAAiB,OAAO;AAC1B,aAAO,KAAK,YAAY;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO;AACT;AAwBO,SAAS,OACd,KACA,aACA,EAAE,QAAQ,MAAM,IAAyC,CAAC,GAC1D;AACA,SAAO,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM;AAC7B,UAAM,aAAa,YAAY,CAAC;AAChC,UAAM,aAAa,YAAY,CAAC;AAEhC,UAAM,YAAY,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,UAAU;AACtE,UAAM,YAAY,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,UAAU;AAEtE,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,YAAM,aACJ,OAAO,UAAU,WAAW,QAAQ,MAAM,CAAC,KAAK;AAElD,YAAM,KAAK,UAAU,CAAC,KAAK;AAC3B,YAAM,KAAK,UAAU,CAAC,KAAK;AAE3B,UAAI,OAAO,IAAI;AACb;AAAA,MACF;AAEA,UAAI,OAAO,YAAY,OAAO,aAAa,KAAK,IAAI;AAClD,eAAO,eAAe,QAAQ,KAAK;AAAA,MACrC;AAEA,UAAI,OAAO,YAAY,OAAO,aAAa,KAAK,IAAI;AAClD,eAAO,eAAe,QAAQ,IAAI;AAAA,MACpC;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAEO,SAAS,cAAiB,OAA4C;AAC3E,SAAO,MAAM,IAAI,CAAC,MAAM,MAAM,CAAC,MAAM,MAAM,IAAI,CAAC,KAAK,IAAI,CAAC;AAC5D;AAEO,SAAS,sBACd,OAC8C;AAC9C,SAAO,MAAM,IAAI,CAAC,MAAM,OAAO;AAAA,IAC7B;AAAA,IACA,MAAM,MAAM,IAAI,CAAC,KAAK;AAAA,IACtB,OAAO;AAAA,EACT,EAAE;AACJ;","names":[]}