@leexi/shared 0.3.9 → 0.4.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.
Files changed (64) hide show
  1. package/README.md +198 -43
  2. package/dist/eslint/base.eslint.config.d.ts +3 -1277
  3. package/dist/eslint/base.eslint.config.mjs +6 -3
  4. package/dist/eslint/vue.eslint.config.d.ts +3 -1307
  5. package/dist/eslint/vue.eslint.config.mjs +2 -1
  6. package/dist/module.json +2 -2
  7. package/dist/runtime/utils/array/castArray.d.ts +1 -0
  8. package/dist/runtime/utils/array/castArray.js +3 -0
  9. package/dist/runtime/utils/array/groupBy.d.ts +1 -0
  10. package/dist/runtime/utils/array/groupBy.js +9 -0
  11. package/dist/runtime/utils/array/index.d.ts +11 -0
  12. package/dist/runtime/utils/array/index.js +11 -0
  13. package/dist/runtime/utils/array/joinBy.d.ts +1 -0
  14. package/dist/runtime/utils/array/joinBy.js +9 -0
  15. package/dist/runtime/utils/array/partition.d.ts +1 -0
  16. package/dist/runtime/utils/array/partition.js +4 -0
  17. package/dist/runtime/utils/array/removeRecord.d.ts +1 -0
  18. package/dist/runtime/utils/array/removeRecord.js +3 -0
  19. package/dist/runtime/utils/array/replaceRecord.d.ts +1 -0
  20. package/dist/runtime/utils/array/replaceRecord.js +3 -0
  21. package/dist/runtime/utils/array/sortBy.d.ts +2 -0
  22. package/dist/runtime/utils/array/sortBy.js +40 -0
  23. package/dist/runtime/utils/array/sum.d.ts +1 -0
  24. package/dist/runtime/utils/array/sum.js +1 -0
  25. package/dist/runtime/utils/array/sumBy.d.ts +1 -0
  26. package/dist/runtime/utils/array/sumBy.js +3 -0
  27. package/dist/runtime/utils/array/uniq.d.ts +1 -0
  28. package/dist/runtime/utils/array/uniq.js +1 -0
  29. package/dist/runtime/utils/array/uniqBy.d.ts +1 -0
  30. package/dist/runtime/utils/array/uniqBy.js +8 -0
  31. package/dist/runtime/utils/function/debounce.d.ts +1 -0
  32. package/dist/runtime/utils/function/debounce.js +6 -0
  33. package/dist/runtime/utils/function/index.d.ts +1 -0
  34. package/dist/runtime/utils/function/index.js +1 -0
  35. package/dist/runtime/utils/index.d.ts +4 -0
  36. package/dist/runtime/utils/index.js +4 -0
  37. package/dist/runtime/utils/number/index.d.ts +1 -0
  38. package/dist/runtime/utils/number/index.js +1 -0
  39. package/dist/runtime/utils/number/toPadStart.d.ts +1 -0
  40. package/dist/runtime/utils/number/toPadStart.js +3 -0
  41. package/dist/runtime/utils/promise/index.d.ts +3 -0
  42. package/dist/runtime/utils/promise/index.js +3 -0
  43. package/dist/runtime/utils/promise/singleFlight.d.ts +1 -0
  44. package/dist/runtime/utils/promise/singleFlight.js +32 -0
  45. package/dist/runtime/utils/promise/sleep.d.ts +1 -0
  46. package/dist/runtime/utils/promise/sleep.js +1 -0
  47. package/dist/runtime/utils/promise/throttle.d.ts +1 -0
  48. package/dist/runtime/utils/promise/throttle.js +32 -0
  49. package/dist/runtime/utils/records/get.d.ts +1 -0
  50. package/dist/runtime/utils/records/get.js +5 -0
  51. package/dist/runtime/utils/records/index.d.ts +2 -0
  52. package/dist/runtime/utils/records/index.js +2 -0
  53. package/dist/runtime/utils/records/merge.d.ts +1 -0
  54. package/dist/runtime/utils/records/merge.js +16 -0
  55. package/dist/runtime/utils/records/set.js +4 -2
  56. package/dist/runtime/utils/strings/index.d.ts +3 -0
  57. package/dist/runtime/utils/strings/index.js +3 -0
  58. package/dist/runtime/utils/strings/strContains.d.ts +1 -0
  59. package/dist/runtime/utils/strings/strContains.js +18 -0
  60. package/dist/runtime/utils/strings/truncate.d.ts +1 -0
  61. package/dist/runtime/utils/strings/truncate.js +5 -0
  62. package/dist/runtime/utils/strings/urlify.d.ts +1 -0
  63. package/dist/runtime/utils/strings/urlify.js +1 -0
  64. package/package.json +10 -9
@@ -2,7 +2,7 @@ import tailwind from "eslint-plugin-tailwindcss";
2
2
  import tseslint from "typescript-eslint";
3
3
  import vue from "eslint-plugin-vue";
4
4
  import base from "./base.eslint.config.mjs";
5
- export default [
5
+ const config = [
6
6
  ...base,
7
7
  ...tailwind.configs["flat/recommended"],
8
8
  ...vue.configs["flat/recommended"],
@@ -45,3 +45,4 @@ export default [
45
45
  ]
46
46
  }
47
47
  ];
48
+ export default config;
package/dist/module.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "configKey": "leexi",
3
3
  "name": "@leexi/shared",
4
- "version": "0.3.9",
4
+ "version": "0.4.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
- "unbuild": "3.6.0"
7
+ "unbuild": "3.6.1"
8
8
  }
9
9
  }
@@ -0,0 +1 @@
1
+ export function castArray(value: any): any[];
@@ -0,0 +1,3 @@
1
+ import { deepDup } from '../index.js';
2
+
3
+ export const castArray = value => Array.isArray(value) ? deepDup(value) : [value];
@@ -0,0 +1 @@
1
+ export function groupBy(records: any, pathOrCallback: any): any;
@@ -0,0 +1,9 @@
1
+ import { get } from '../index.js';
2
+
3
+ export const groupBy = (records, pathOrCallback) => records.reduce((groupedRecords, currentRecord) => {
4
+ const key = typeof pathOrCallback === 'string' ? get(currentRecord, pathOrCallback) : pathOrCallback(currentRecord);
5
+ groupedRecords[key] ||= [];
6
+ groupedRecords[key].push(currentRecord);
7
+
8
+ return groupedRecords;
9
+ }, {});
@@ -0,0 +1,11 @@
1
+ export { castArray } from "./castArray.js";
2
+ export { groupBy } from "./groupBy.js";
3
+ export { joinBy } from "./joinBy.js";
4
+ export { partition } from "./partition.js";
5
+ export { removeRecord } from "./removeRecord.js";
6
+ export { replaceRecord } from "./replaceRecord.js";
7
+ export { sortBy } from "./sortBy.js";
8
+ export { sum } from "./sum.js";
9
+ export { sumBy } from "./sumBy.js";
10
+ export { uniq } from "./uniq.js";
11
+ export { uniqBy } from "./uniqBy.js";
@@ -0,0 +1,11 @@
1
+ export { castArray } from './castArray.js';
2
+ export { groupBy } from './groupBy.js';
3
+ export { joinBy } from './joinBy.js';
4
+ export { partition } from './partition.js';
5
+ export { removeRecord } from './removeRecord.js';
6
+ export { replaceRecord } from './replaceRecord.js';
7
+ export { sortBy } from './sortBy.js';
8
+ export { sum } from './sum.js';
9
+ export { sumBy } from './sumBy.js';
10
+ export { uniq } from './uniq.js';
11
+ export { uniqBy } from './uniqBy.js';
@@ -0,0 +1 @@
1
+ export function joinBy(records: any, attr: any): any[];
@@ -0,0 +1,9 @@
1
+ export const joinBy = (records, attr) => {
2
+ const filteredRecords = {};
3
+ records.forEach(record => {
4
+ const key = record[attr];
5
+ return filteredRecords[key] = { ...filteredRecords[key], ...record };
6
+ });
7
+
8
+ return Object.values(filteredRecords);
9
+ };
@@ -0,0 +1 @@
1
+ export function partition(items: any, callback: any): any;
@@ -0,0 +1,4 @@
1
+ export const partition = (items, callback) => items.reduce(([truthy, falsy], currentItem) => {
2
+ (callback(currentItem) ? truthy : falsy).push(currentItem);
3
+ return [truthy, falsy];
4
+ }, [[], []]);
@@ -0,0 +1 @@
1
+ export function removeRecord(records: any, removedRecord: any, removeBy?: string): any;
@@ -0,0 +1,3 @@
1
+ export const removeRecord = (records, removedRecord, removeBy = 'uuid') => (
2
+ records.filter(record => record[removeBy] !== removedRecord[removeBy])
3
+ );
@@ -0,0 +1 @@
1
+ export function replaceRecord(records: any, replacement: any, replaceBy?: string): any;
@@ -0,0 +1,3 @@
1
+ export const replaceRecord = (records, replacement, replaceBy = 'uuid') => (
2
+ records.map(record => record[replaceBy] === replacement[replaceBy] ? replacement : record)
3
+ );
@@ -0,0 +1,2 @@
1
+ import type { FilteredAttrs, Primitive } from '~/types';
2
+ export declare const sortBy: <T, C extends (_: T) => Primitive, K extends Extract<FilteredAttrs<T, Primitive>, string>>(items: T[], attrsOrCallbacks: C | K | `-${K}` | (C | K | `-${K}`)[]) => T[];
@@ -0,0 +1,40 @@
1
+ import { deepDup } from "~/src/runtime/utils";
2
+ export const sortBy = (items, attrsOrCallbacks) => {
3
+ const directions = [];
4
+ if (!Array.isArray(attrsOrCallbacks)) {
5
+ attrsOrCallbacks = [attrsOrCallbacks];
6
+ }
7
+ const formattedAttrsOrCallbacks = attrsOrCallbacks.map((attrOrCallback, index) => {
8
+ if (typeof attrOrCallback === "string" && attrOrCallback[0] === "-") {
9
+ directions[index] = -1;
10
+ return attrOrCallback.slice(1);
11
+ } else {
12
+ directions[index] = 1;
13
+ return attrOrCallback;
14
+ }
15
+ });
16
+ const getValue = (item, index) => {
17
+ const attrOrCallback = formattedAttrsOrCallbacks[index];
18
+ if (typeof attrOrCallback === "string") {
19
+ return item[attrOrCallback];
20
+ } else if (typeof attrOrCallback === "function") {
21
+ return attrOrCallback(item);
22
+ } else {
23
+ return 0;
24
+ }
25
+ };
26
+ return deepDup(items).sort((a, b) => {
27
+ for (let i = 0; i < formattedAttrsOrCallbacks.length; i++) {
28
+ const aValue = getValue(a, i);
29
+ const bValue = getValue(b, i);
30
+ if (typeof aValue === "string" && typeof bValue === "string" && aValue.localeCompare(bValue) !== 0) {
31
+ return aValue.localeCompare(bValue) > 0 ? directions[i] : -directions[i];
32
+ } else if (typeof aValue === "number" && typeof bValue === "number" && aValue !== bValue) {
33
+ return (aValue - bValue) * directions[i];
34
+ } else if (typeof aValue === "boolean" && aValue !== bValue) {
35
+ return aValue ? directions[i] : -directions[i];
36
+ }
37
+ }
38
+ return 0;
39
+ });
40
+ };
@@ -0,0 +1 @@
1
+ export function sum(numbers: any): any;
@@ -0,0 +1 @@
1
+ export const sum = numbers => numbers.reduce((a, b) => a + b, 0);
@@ -0,0 +1 @@
1
+ export function sumBy(records: any, attr: any): any;
@@ -0,0 +1,3 @@
1
+ import { sum } from '../index.js';
2
+
3
+ export const sumBy = (records, attr) => sum(records.map(record => record[attr]));
@@ -0,0 +1 @@
1
+ export function uniq(values: any): any[];
@@ -0,0 +1 @@
1
+ export const uniq = values => [...new Set(values || [])];
@@ -0,0 +1 @@
1
+ export function uniqBy(records: any, attrOrCallback: any): any[];
@@ -0,0 +1,8 @@
1
+ export const uniqBy = (records, attrOrCallback) => {
2
+ const mapData = records.map(record => {
3
+ const key = typeof attrOrCallback === 'string' ? record[attrOrCallback] : attrOrCallback(record);
4
+ return [key, record];
5
+ });
6
+
7
+ return [...new Map(mapData).values()];
8
+ };
@@ -0,0 +1 @@
1
+ export function debounce(callback: any, timeout?: number): void;
@@ -0,0 +1,6 @@
1
+ let timer;
2
+
3
+ export const debounce = (callback, timeout = 300) => {
4
+ clearTimeout(timer);
5
+ timer = setTimeout(callback, timeout);
6
+ };
@@ -0,0 +1 @@
1
+ export { debounce } from "./debounce.js";
@@ -0,0 +1 @@
1
+ export { debounce } from './debounce.js';
@@ -1,3 +1,7 @@
1
+ export * from './array/index.js';
2
+ export * from './function/index.js';
3
+ export * from './number/index.js';
1
4
  export * from './objects/index.js';
5
+ export * from './promise/index.js';
2
6
  export * from './records/index.js';
3
7
  export * from './strings/index.js';
@@ -1,3 +1,7 @@
1
+ export * from "./array/index.js";
2
+ export * from "./function/index.js";
3
+ export * from "./number/index.js";
1
4
  export * from "./objects/index.js";
5
+ export * from "./promise/index.js";
2
6
  export * from "./records/index.js";
3
7
  export * from "./strings/index.js";
@@ -0,0 +1 @@
1
+ export { toPadStart } from "./toPadStart.js";
@@ -0,0 +1 @@
1
+ export { toPadStart } from './toPadStart.js';
@@ -0,0 +1 @@
1
+ export function toPadStart(value: any, maxLength?: number, fillString?: string): string;
@@ -0,0 +1,3 @@
1
+ export const toPadStart = (value, maxLength = 2, fillString = '0') => (
2
+ Math.floor(value).toString().padStart(maxLength, fillString)
3
+ );
@@ -0,0 +1,3 @@
1
+ export { singleFlight } from "./singleFlight.js";
2
+ export { sleep } from "./sleep.js";
3
+ export { throttle } from "./throttle.js";
@@ -0,0 +1,3 @@
1
+ export { singleFlight } from './singleFlight.js';
2
+ export { sleep } from './sleep.js';
3
+ export { throttle } from './throttle.js';
@@ -0,0 +1 @@
1
+ export function singleFlight(key: string, request: () => Promise<any>): Promise<any>;
@@ -0,0 +1,32 @@
1
+ const cachedPromise = {};
2
+
3
+ /**
4
+ * Ensures that a given asynchronous `request` function, identified by a `key`,
5
+ * is executed only once, even if called multiple times concurrently. Subsequent
6
+ * calls with the same key will return the same Promise as the initial call,
7
+ * preventing redundant operations.
8
+ *
9
+ * The cached Promise for a specific key is cleared once the request
10
+ * (either successfully or with an error) has completed. This allows
11
+ * for subsequent calls with the same key to trigger a new request.
12
+ *
13
+ * @param {string} key - A unique identifier for the request.
14
+ * @param {function(): Promise<any>} request - An asynchronous function that
15
+ * returns a Promise. This function will be executed only if there is
16
+ * no ongoing request for the given `key`.
17
+ * @returns {Promise<any>} A Promise that resolves with the result of the
18
+ * `request` function, or rejects with its error. All concurrent calls
19
+ * for the same `key` will receive this same Promise.
20
+ */
21
+ export const singleFlight = (key, request) => {
22
+ if (!cachedPromise[key]) {
23
+ cachedPromise[key] = new Promise((resolve, reject) => {
24
+ request()
25
+ .then(response => { resolve(response); })
26
+ .catch(error => { reject(error); })
27
+ .finally(() => { cachedPromise[key] = null; });
28
+ });
29
+ }
30
+
31
+ return cachedPromise[key];
32
+ };
@@ -0,0 +1 @@
1
+ export function sleep(msDuration: any): Promise<any>;
@@ -0,0 +1 @@
1
+ export const sleep = msDuration => new Promise(resolve => setTimeout(resolve, msDuration));
@@ -0,0 +1 @@
1
+ export function throttle(promises: any, max: any, abortController?: AbortController): Promise<(AbortController | (() => Promise<any[]>))[]>;
@@ -0,0 +1,32 @@
1
+ export const throttle = async (promises, max, abortController = new AbortController()) => {
2
+ const handlePromises = async () => {
3
+ const queue = new Set();
4
+ const results = [];
5
+
6
+ for (const promise of promises) {
7
+ if (abortController.signal.aborted) {
8
+ await Promise.all(queue); // Wait for the promises in the queue to finish
9
+ throw new Error('Aborted');
10
+ }
11
+
12
+ const p = promise().then(response => {
13
+ queue.delete(p);
14
+ return response;
15
+ });
16
+
17
+ queue.add(p);
18
+ results.push(p);
19
+
20
+ if (queue.size >= max) { await Promise.race(queue); }
21
+ }
22
+
23
+ abortController.signal.addEventListener('abort', async () => {
24
+ await Promise.all(queue); // Wait for the promises in the queue to finish
25
+ queue.forEach(p => p.abort());
26
+ });
27
+
28
+ return Promise.all(results);
29
+ };
30
+
31
+ return [handlePromises, abortController];
32
+ };
@@ -0,0 +1 @@
1
+ export function get(record: any, path: any): any;
@@ -0,0 +1,5 @@
1
+ export const get = (record, path) => {
2
+ let value = record;
3
+ path.split('.').forEach(key => value = value?.[key]);
4
+ return value;
5
+ };
@@ -1,3 +1,5 @@
1
+ export { get } from './get.js';
2
+ export { merge } from './merge.js';
1
3
  export { omit } from './omit.js';
2
4
  export { pick } from './pick.js';
3
5
  export { set } from './set.js';
@@ -1,3 +1,5 @@
1
+ export { get } from "./get.js";
2
+ export { merge } from "./merge.js";
1
3
  export { omit } from "./omit.js";
2
4
  export { pick } from "./pick.js";
3
5
  export { set } from "./set.js";
@@ -0,0 +1 @@
1
+ export function merge(record: any, defaults: any): any;
@@ -0,0 +1,16 @@
1
+ import { deepDup } from '../index.js';
2
+
3
+ export const merge = (record, defaults) => {
4
+ const dup = deepDup(record || {});
5
+ Object.entries(defaults || {}).forEach(([key, value]) => {
6
+ const isObject = value && typeof value === 'object' && !Array.isArray(value);
7
+
8
+ if (isObject) {
9
+ dup[key] = merge(dup[key], value);
10
+ } else if (dup[key] == null) {
11
+ dup[key] = value;
12
+ }
13
+ });
14
+
15
+ return dup;
16
+ };
@@ -1,5 +1,7 @@
1
1
  export const set = (record, path, value) => {
2
- const [key, ...rest] = path;
3
- Object.assign(record, { ...record, [key]: rest.length ? set(record[key] ?? {}, rest, value) : value });
2
+ if (path.length) {
3
+ const [key, ...rest] = path;
4
+ Object.assign(record, { ...record, [key]: rest.length ? set(record[key] ?? {}, rest, value) : value });
5
+ }
4
6
  return record;
5
7
  };
@@ -2,3 +2,6 @@ export { camelcase } from './camelcase.js';
2
2
  export { capitalize } from './capitalize.js';
3
3
  export { kebabcase } from './kebabcase.js';
4
4
  export { snakecase } from './snakecase.js';
5
+ export { strContains } from './strContains.js';
6
+ export { truncate } from './truncate.js';
7
+ export { urlify } from './urlify.js';
@@ -2,3 +2,6 @@ export { camelcase } from "./camelcase.js";
2
2
  export { capitalize } from "./capitalize.js";
3
3
  export { kebabcase } from "./kebabcase.js";
4
4
  export { snakecase } from "./snakecase.js";
5
+ export { strContains } from "./strContains.js";
6
+ export { truncate } from "./truncate.js";
7
+ export { urlify } from "./urlify.js";
@@ -0,0 +1 @@
1
+ export function strContains(value: any, query: any, options?: {}): any;
@@ -0,0 +1,18 @@
1
+ export const strContains = (value, query, options = {}) => {
2
+ const deaccent = string => string.normalize('NFD').replace(/\p{Diacritic}/gu, '');
3
+
4
+ value ||= '';
5
+ query ||= '';
6
+
7
+ if (!options.caseSensitive) {
8
+ value = value.toLowerCase();
9
+ query = query.toLowerCase();
10
+ }
11
+
12
+ if (!options.accentSensitive) {
13
+ value = deaccent(value);
14
+ query = deaccent(query);
15
+ }
16
+
17
+ return value.includes(query);
18
+ };
@@ -0,0 +1 @@
1
+ export function truncate(value: any, precision: any, overflow?: string): any;
@@ -0,0 +1,5 @@
1
+ export const truncate = (value, precision, overflow = '...') => {
2
+ if (typeof value !== 'string') { return value; }
3
+
4
+ return value.length > precision ? `${value.slice(0, precision)}${overflow}` : value;
5
+ };
@@ -0,0 +1 @@
1
+ export function urlify(endpoint: any, params: any): string;
@@ -0,0 +1 @@
1
+ export const urlify = (endpoint, params) => `${endpoint}?${new URLSearchParams(params).toString()}`;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "license": "UNLICENSED",
3
3
  "name": "@leexi/shared",
4
4
  "type": "module",
5
- "version": "0.3.9",
5
+ "version": "0.4.0",
6
6
  "exports": {
7
7
  "./composables": {
8
8
  "import": "./dist/runtime/composables/index.js",
@@ -46,24 +46,25 @@
46
46
  "tsc": "vue-tsc --noEmit"
47
47
  },
48
48
  "dependencies": {
49
- "@stylistic/eslint-plugin": "^5.2.2",
49
+ "@stylistic/eslint-plugin": "^5.2.3",
50
50
  "@types/eslint-plugin-tailwindcss": "^3.17.0",
51
- "eslint": "^9.32.0",
51
+ "eslint": "^9.34.0",
52
+ "eslint-plugin-sort-keys-plus": "^1.5.0",
52
53
  "eslint-plugin-tailwindcss": "^3.18.2",
53
54
  "eslint-plugin-vue": "^10.4.0",
54
- "globals": "^16.2.0",
55
- "typescript": "^5.8.3",
56
- "typescript-eslint": "^8.38.0",
55
+ "globals": "^16.3.0",
56
+ "typescript": "^5.9.2",
57
+ "typescript-eslint": "^8.41.0",
57
58
  "vue-eslint-parser": "^10.2.0"
58
59
  },
59
60
  "devDependencies": {
60
61
  "@nuxt/module-builder": "^1.0.2",
61
62
  "@nuxt/test-utils": "^3.19.2",
62
- "@types/node": "^22.16.0",
63
+ "@types/node": "<23.0.0",
63
64
  "happy-dom": "^18.0.1",
64
- "nuxt": "^3.17.6",
65
+ "nuxt": "^4.0.3",
65
66
  "tailwindcss": "<4.0.0",
66
67
  "vitest": "^3.2.4",
67
- "vue-tsc": "^3.0.4"
68
+ "vue-tsc": "^3.0.6"
68
69
  }
69
70
  }