@pawover/kit 0.0.0-alpha.1

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 (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/enums/index.js +20 -0
  4. package/dist/hooks/react/index.js +5 -0
  5. package/dist/hooks/react/useCreation.js +11 -0
  6. package/dist/hooks/react/useLatest.js +6 -0
  7. package/dist/hooks/react/useMount.js +29 -0
  8. package/dist/hooks/react/useResponsive.js +59 -0
  9. package/dist/hooks/react/useUnmount.js +17 -0
  10. package/dist/index.js +2 -0
  11. package/dist/types/enums/index.d.ts +20 -0
  12. package/dist/types/hooks/react/index.d.ts +5 -0
  13. package/dist/types/hooks/react/useCreation.d.ts +2 -0
  14. package/dist/types/hooks/react/useLatest.d.ts +1 -0
  15. package/dist/types/hooks/react/useMount.d.ts +11 -0
  16. package/dist/types/hooks/react/useResponsive.d.ts +16 -0
  17. package/dist/types/hooks/react/useUnmount.d.ts +6 -0
  18. package/dist/types/index.d.ts +2 -0
  19. package/dist/types/utils/array.d.ts +76 -0
  20. package/dist/types/utils/index.d.ts +6 -0
  21. package/dist/types/utils/object.d.ts +53 -0
  22. package/dist/types/utils/string.d.ts +13 -0
  23. package/dist/types/utils/to.d.ts +5 -0
  24. package/dist/types/utils/tree/index.d.ts +6 -0
  25. package/dist/types/utils/tree/rowsToTree.d.ts +10 -0
  26. package/dist/types/utils/tree/treeFilter.d.ts +6 -0
  27. package/dist/types/utils/tree/treeFind.d.ts +8 -0
  28. package/dist/types/utils/tree/treeForEach.d.ts +5 -0
  29. package/dist/types/utils/tree/treeMap.d.ts +6 -0
  30. package/dist/types/utils/tree/treeToRows.d.ts +9 -0
  31. package/dist/types/utils/tree/types.d.ts +24 -0
  32. package/dist/types/utils/typeof.d.ts +29 -0
  33. package/dist/utils/array.js +196 -0
  34. package/dist/utils/index.js +6 -0
  35. package/dist/utils/object.js +138 -0
  36. package/dist/utils/string.js +70 -0
  37. package/dist/utils/to.js +16 -0
  38. package/dist/utils/tree/index.js +6 -0
  39. package/dist/utils/tree/rowsToTree.js +35 -0
  40. package/dist/utils/tree/treeFilter.js +92 -0
  41. package/dist/utils/tree/treeFind.js +82 -0
  42. package/dist/utils/tree/treeForEach.js +60 -0
  43. package/dist/utils/tree/treeMap.js +79 -0
  44. package/dist/utils/tree/treeToRows.js +13 -0
  45. package/dist/utils/tree/types.js +10 -0
  46. package/dist/utils/typeof.js +114 -0
  47. package/package.json +90 -0
@@ -0,0 +1,60 @@
1
+ import { isArray } from "../typeof";
2
+ import { getFinalChildrenKey } from "./types";
3
+ const strategies = { pre: preImpl, post: postImpl, breadth: breadthImpl };
4
+ // 前置遍历
5
+ function preImpl(row, callback, options) {
6
+ callback(row, options);
7
+ const finalChildrenKey = getFinalChildrenKey(row, options, options);
8
+ const children = row[finalChildrenKey];
9
+ if (isArray(children)) {
10
+ const nextLevelOptions = { ...options, parents: [...options.parents, row], depth: options.depth + 1 };
11
+ for (const child of children) {
12
+ preImpl(child, callback, nextLevelOptions);
13
+ }
14
+ }
15
+ }
16
+ // 后置遍历
17
+ function postImpl(row, callback, options) {
18
+ const finalChildrenKey = getFinalChildrenKey(row, options, options);
19
+ const children = row[finalChildrenKey];
20
+ if (isArray(children)) {
21
+ const nextLevelOptions = { ...options, parents: [...options.parents, row], depth: options.depth + 1 };
22
+ for (const child of children) {
23
+ postImpl(child, callback, nextLevelOptions);
24
+ }
25
+ }
26
+ callback(row, options);
27
+ }
28
+ // 广度优先遍历
29
+ function breadthImpl(row, callback, options) {
30
+ const queue = [{ queueRow: row, queueOptions: options }];
31
+ const runQueue = () => {
32
+ if (queue.length === 0) {
33
+ return;
34
+ }
35
+ const { queueRow, queueOptions } = queue.shift();
36
+ const finalChildrenKey = getFinalChildrenKey(queueRow, queueOptions, queueOptions);
37
+ const children = queueRow[finalChildrenKey];
38
+ if (isArray(children)) {
39
+ const nextLevelOptions = { ...queueOptions, parents: [...queueOptions.parents, queueRow], depth: queueOptions.depth + 1 };
40
+ const subQueueItems = children.map((queueRow) => ({ queueRow, queueOptions: nextLevelOptions }));
41
+ queue.push(...subQueueItems);
42
+ }
43
+ callback(queueRow, queueOptions);
44
+ runQueue();
45
+ };
46
+ runQueue();
47
+ }
48
+ export function treeForEach(tree, callback, options = {}) {
49
+ const { childrenKey = "children", strategy = "pre", getChildrenKey } = options;
50
+ const traversalMethod = strategies[strategy];
51
+ const innerOptions = { childrenKey: childrenKey, depth: 0, parents: [], getChildrenKey };
52
+ if (isArray(tree)) {
53
+ for (const row of tree) {
54
+ traversalMethod(row, callback, innerOptions);
55
+ }
56
+ }
57
+ else {
58
+ traversalMethod(tree, callback, innerOptions);
59
+ }
60
+ }
@@ -0,0 +1,79 @@
1
+ import { arrayLast } from "../array";
2
+ import { isArray } from "../typeof";
3
+ import { getFinalChildrenKey } from "./types";
4
+ const strategies = { pre: preImpl, post: postImpl, breadth: breadthImpl };
5
+ // 前置遍历
6
+ function preImpl(row, callback, options) {
7
+ const finalChildrenKey = getFinalChildrenKey(row, options, options);
8
+ const result = callback(row, options);
9
+ const children = row[finalChildrenKey];
10
+ let newChildren;
11
+ if (isArray(children)) {
12
+ const nextLevelOptions = { ...options, parents: [...options.parents, row], depth: options.depth + 1 };
13
+ newChildren = children.map((c) => preImpl(c, callback, nextLevelOptions));
14
+ }
15
+ return { ...result, [finalChildrenKey]: newChildren };
16
+ }
17
+ // 子节点优先遍历
18
+ function postImpl(row, callback, options) {
19
+ const finalChildrenKey = getFinalChildrenKey(row, options, options);
20
+ const children = row[finalChildrenKey];
21
+ let newChildren;
22
+ if (isArray(children)) {
23
+ const nextLevelOptions = { ...options, parents: [...options.parents, row], depth: options.depth + 1 };
24
+ newChildren = children.map((c) => postImpl(c, callback, nextLevelOptions));
25
+ }
26
+ const result = callback(row, options);
27
+ return { ...result, [finalChildrenKey]: newChildren };
28
+ }
29
+ // 广度优先遍历
30
+ function breadthImpl(row, callback, options) {
31
+ const queue = [{ queueRow: row, queueOptions: options }];
32
+ const cache = new WeakMap();
33
+ const childrenKeyCache = new WeakMap();
34
+ let result;
35
+ const runQueue = () => {
36
+ if (queue.length === 0) {
37
+ return result;
38
+ }
39
+ const { queueRow, queueOptions } = queue.shift();
40
+ const finalChildrenKey = getFinalChildrenKey(queueRow, queueOptions, queueOptions);
41
+ const children = queueRow[finalChildrenKey];
42
+ if (isArray(children)) {
43
+ const nextLevelOptions = { ...queueOptions, parents: [...queueOptions.parents, queueRow], depth: queueOptions.depth + 1 };
44
+ const subQueueItems = children.map((queueRow) => ({ queueRow, queueOptions: nextLevelOptions }));
45
+ queue.push(...subQueueItems);
46
+ }
47
+ const res = callback(queueRow, queueOptions);
48
+ cache.set(queueRow, res);
49
+ childrenKeyCache.set(queueRow, finalChildrenKey);
50
+ // breadth 模式的子节点一定晚于父节点执行,所以可以在cache中找到父节点的生成物
51
+ const parent = arrayLast(queueOptions.parents);
52
+ if (parent) {
53
+ const newParent = cache.get(parent);
54
+ const parentChildrenKey = childrenKeyCache.get(parent);
55
+ if (newParent && parentChildrenKey) {
56
+ if (newParent[parentChildrenKey]) {
57
+ newParent[parentChildrenKey].push(res);
58
+ }
59
+ else {
60
+ newParent[parentChildrenKey] = [res];
61
+ }
62
+ }
63
+ }
64
+ // 这棵树的顶点
65
+ if (queueOptions.depth === 0) {
66
+ result = res;
67
+ }
68
+ return runQueue();
69
+ };
70
+ return runQueue();
71
+ }
72
+ export function treeMap(tree, callback, options = {}) {
73
+ const { childrenKey = "children", strategy = "pre", getChildrenKey } = options;
74
+ const traversalMethod = strategies[strategy];
75
+ const innerOptions = { childrenKey: childrenKey, depth: 0, parents: [], getChildrenKey };
76
+ return isArray(tree)
77
+ ? tree.map((row) => traversalMethod(row, callback, innerOptions))
78
+ : traversalMethod(tree, callback, innerOptions);
79
+ }
@@ -0,0 +1,13 @@
1
+ import { treeForEach } from "./treeForEach";
2
+ /**
3
+ * 树结构 转 行结构
4
+ */
5
+ export function treeToRows(tree, options = {}) {
6
+ const { childrenKey = "children" } = options;
7
+ const result = [];
8
+ if (!tree) {
9
+ return result;
10
+ }
11
+ treeForEach(tree, (t) => result.push({ ...t, [childrenKey]: undefined }), options);
12
+ return result;
13
+ }
@@ -0,0 +1,10 @@
1
+ import { isFunction } from "../typeof";
2
+ export function getFinalChildrenKey(tree, meta, options) {
3
+ if (isFunction(options.getChildrenKey)) {
4
+ const dynamicChildrenKey = options.getChildrenKey(tree, meta);
5
+ if (dynamicChildrenKey && dynamicChildrenKey !== null) {
6
+ return dynamicChildrenKey;
7
+ }
8
+ }
9
+ return options.childrenKey;
10
+ }
@@ -0,0 +1,114 @@
1
+ const prototypes = {
2
+ string: "[object String]",
3
+ number: "[object Number]",
4
+ boolean: "[object Boolean]",
5
+ object: "[object Object]",
6
+ array: "[object Array]",
7
+ bigInt: "[object BigInt]",
8
+ symbol: "[object Symbol]",
9
+ function: "[object Function]",
10
+ generatorFunction: "[object GeneratorFunction]",
11
+ asyncFunction: "[object AsyncFunction]",
12
+ promise: "[object Promise]",
13
+ null: "[object Null]",
14
+ undefined: "[object Undefined]",
15
+ date: "[object Date]",
16
+ regExp: "[object RegExp]",
17
+ error: "[object Error]",
18
+ file: "[object File]",
19
+ map: "[object Map]",
20
+ weakMap: "[object WeakMap]",
21
+ set: "[object Set]",
22
+ weakSet: "[object WeakSet]",
23
+ window: "[object Window]",
24
+ webSocket: "[object WebSocket]",
25
+ URLSearchParams: "[object URLSearchParams]",
26
+ };
27
+ function resolvePrototypeString(value) {
28
+ return Object.prototype.toString.call(value);
29
+ }
30
+ export function isString(value) {
31
+ return resolvePrototypeString(value) === prototypes.string;
32
+ }
33
+ export function isNumber(value) {
34
+ return resolvePrototypeString(value) === prototypes.number;
35
+ }
36
+ export function isBoolean(value) {
37
+ return resolvePrototypeString(value) === prototypes.boolean;
38
+ }
39
+ export function isObject(value) {
40
+ return resolvePrototypeString(value) === prototypes.object;
41
+ }
42
+ export function isArray(value) {
43
+ return resolvePrototypeString(value) === prototypes.array;
44
+ }
45
+ export function isBigInt(value) {
46
+ return resolvePrototypeString(value) === prototypes.bigInt;
47
+ }
48
+ export function isSymbol(value) {
49
+ return resolvePrototypeString(value) === prototypes.symbol;
50
+ }
51
+ export function isFunction(value) {
52
+ const prototypeList = [prototypes.function, prototypes.generatorFunction, prototypes.asyncFunction];
53
+ return prototypeList.includes(resolvePrototypeString(value));
54
+ }
55
+ export function isGeneratorFunction(value) {
56
+ return resolvePrototypeString(value) === prototypes.generatorFunction;
57
+ }
58
+ export function isAsyncFunction(value) {
59
+ return resolvePrototypeString(value) === prototypes.asyncFunction;
60
+ }
61
+ export function isPromise(value) {
62
+ return resolvePrototypeString(value) === prototypes.promise;
63
+ }
64
+ export function isPromiseLike(value) {
65
+ return isPromise(value) || (isObject(value) && isFunction(value["then"]));
66
+ }
67
+ export function isNull(value) {
68
+ return resolvePrototypeString(value) === prototypes.null;
69
+ }
70
+ export function isUndefined(value) {
71
+ return resolvePrototypeString(value) === prototypes.undefined;
72
+ }
73
+ export function isDate(value) {
74
+ return resolvePrototypeString(value) === prototypes.date;
75
+ }
76
+ export function isRegExp(value) {
77
+ return resolvePrototypeString(value) === prototypes.regExp;
78
+ }
79
+ export function isError(value) {
80
+ return resolvePrototypeString(value) === prototypes.error;
81
+ }
82
+ export function isFile(value) {
83
+ return resolvePrototypeString(value) === prototypes.file;
84
+ }
85
+ export function isMap(value) {
86
+ return resolvePrototypeString(value) === prototypes.map;
87
+ }
88
+ export function isWeakMap(value) {
89
+ return resolvePrototypeString(value) === prototypes.weakMap;
90
+ }
91
+ export function isSet(value) {
92
+ return resolvePrototypeString(value) === prototypes.set;
93
+ }
94
+ export function isWeakSet(value) {
95
+ return resolvePrototypeString(value) === prototypes.weakSet;
96
+ }
97
+ export function isWindow(value) {
98
+ return resolvePrototypeString(value) === prototypes.window;
99
+ }
100
+ export function isWebSocket(value) {
101
+ return resolvePrototypeString(value) === prototypes.webSocket;
102
+ }
103
+ export function isURLSearchParams(value) {
104
+ return resolvePrototypeString(value) === prototypes.URLSearchParams;
105
+ }
106
+ export function isClass(value) {
107
+ return resolvePrototypeString(value).startsWith("class ");
108
+ }
109
+ export function isInteger(value) {
110
+ return Number.isInteger(value);
111
+ }
112
+ export function isIterable(value) {
113
+ return isObject(value) && Symbol.iterator in value;
114
+ }
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "@pawover/kit",
3
+ "author": "pawover<pawover@outlook.com>",
4
+ "description": "pawover's kit",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "version": "0.0.0-alpha.1",
8
+ "packageManager": "pnpm@10.20.0",
9
+ "engines": {
10
+ "node": ">=22.20.0"
11
+ },
12
+ "keywords": [
13
+ "pawover",
14
+ "pawover-kit"
15
+ ],
16
+ "homepage": "https://github.com/pawover/pawover-kit#readme",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/pawover/pawover-kit.git"
20
+ },
21
+ "main": "./dist/index.js",
22
+ "module": "./dist/index.js",
23
+ "types": "dist/types/index.d.ts",
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/types/index.d.ts",
30
+ "import": "./dist/index.js",
31
+ "default": "./dist/index.js"
32
+ },
33
+ "./*": {
34
+ "types": "./dist/types/*.d.ts",
35
+ "import": "./dist/*.js",
36
+ "default": "./dist/*.js"
37
+ }
38
+ },
39
+ "scripts": {
40
+ "build": "tsc",
41
+ "public": "pnpm build && npm publish --access public",
42
+ "check": "pnpm check:types & pnpm check:eslint & pnpm check:format",
43
+ "check:types": "tsc --noEmit",
44
+ "check:eslint": "eslint --fix \"**/*.{js,cjs,mjs,ts,cts,mts,jsx,tsx,vue}\" --cache-location=eslint.cache.json --cache",
45
+ "check:format": "prettier --write \"**/*.{html,json}\" !.vscode/settings.json --cache-location=prettier.cache.json --cache",
46
+ "check:pack": "attw --pack .",
47
+ "clean": "pnpm clean:cache & pnpm clean:lib & pnpm clean:output",
48
+ "clean:cache": "rimraf -g **/*.cache.json **/auto-*.json **/auto-*.d.ts",
49
+ "clean:lib": "rimraf -g **/node_modules",
50
+ "clean:output": "rimraf dist",
51
+ "lib:up": "taze -I -r --exclude pnpm"
52
+ },
53
+ "devDependencies": {
54
+ "@pawover/eslint-rules": "0.0.0-alpha.3",
55
+ "@pawover/types": "0.0.0-alpha.6",
56
+ "@stylistic/eslint-plugin": "^5.5.0",
57
+ "@types/node": "^24.10.1",
58
+ "@types/react": "^19.2.4",
59
+ "ahooks": "^3.9.6",
60
+ "eslint": "^9.39.1",
61
+ "eslint-plugin-antfu": "^3.1.1",
62
+ "globals": "^16.5.0",
63
+ "prettier": "^3.6.2",
64
+ "radashi": "^12.7.0",
65
+ "react": "^19.2.0",
66
+ "rimraf": "^6.1.0",
67
+ "taze": "^19.9.0",
68
+ "type-fest": "^5.2.0",
69
+ "typescript": "^5.9.3",
70
+ "typescript-eslint": "^8.46.4",
71
+ "vue": "^3.5.24"
72
+ },
73
+ "peerDependencies": {
74
+ "ahooks": ">=3.9.6",
75
+ "radashi": ">=12.7.0",
76
+ "react": ">=19.2.0",
77
+ "vue": ">=3.5.24"
78
+ },
79
+ "peerDependenciesMeta": {
80
+ "ahooks": {
81
+ "optional": true
82
+ },
83
+ "react": {
84
+ "optional": true
85
+ },
86
+ "vue": {
87
+ "optional": true
88
+ }
89
+ }
90
+ }