@d-matrix/utils 1.21.1 → 1.23.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.
@@ -0,0 +1 @@
1
+ export * as tree from './tree';
@@ -0,0 +1 @@
1
+ export * as tree from './tree';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 计算指定层级的节点数量
3
+ * @param root tree data 对象
4
+ * @param depth 需要计算节点数量的层级
5
+ * @param childrenKey 子节点key
6
+ * @returns 节点数量
7
+ */
8
+ export declare const nodeCountAtDepth: <T extends Record<string, any>>(root: T, depth: number, childrenKey?: string) => number;
9
+ /**
10
+ * 找到符合条件的节点
11
+ * @param tree tree data 数组
12
+ * @param predicate 对每个节点执行的函数, 如果返回true, 则返回该节点
13
+ * @param childrenKey 子节点key
14
+ * @returns 找到的节点
15
+ */
16
+ export declare const findNode: <T extends Record<string, any>>(tree: T[], predicate: (node: T) => boolean, childrenKey?: string) => T | null;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * 计算指定层级的节点数量
3
+ * @param root tree data 对象
4
+ * @param depth 需要计算节点数量的层级
5
+ * @param childrenKey 子节点key
6
+ * @returns 节点数量
7
+ */
8
+ export const nodeCountAtDepth = (root, depth, childrenKey = 'children') => {
9
+ const depths = { 0: 1 };
10
+ (function recurTree(node, level) {
11
+ var _a;
12
+ level++;
13
+ const children = (_a = node[childrenKey]) !== null && _a !== void 0 ? _a : [];
14
+ if (depths[level] === undefined) {
15
+ depths[level] = children.length;
16
+ }
17
+ else {
18
+ depths[level] += children.length;
19
+ }
20
+ if (level + 1 > depth)
21
+ return;
22
+ for (let i = 0; i < children.length; i++) {
23
+ recurTree(children[i], level);
24
+ }
25
+ })(root, 0);
26
+ return depths[depth];
27
+ };
28
+ /**
29
+ * 找到符合条件的节点
30
+ * @param tree tree data 数组
31
+ * @param predicate 对每个节点执行的函数, 如果返回true, 则返回该节点
32
+ * @param childrenKey 子节点key
33
+ * @returns 找到的节点
34
+ */
35
+ export const findNode = (tree, predicate, childrenKey = 'children') => {
36
+ const list = [...tree];
37
+ for (const node of list) {
38
+ if (predicate(node))
39
+ return node;
40
+ Array.isArray(node[childrenKey]) && list.push(...node[childrenKey]);
41
+ }
42
+ return null;
43
+ };
package/dist/array.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export declare function moveMutable<T>(array: T[], fromIndex: number, toIndex: number): void;
2
2
  export declare function moveImmutable<T>(array: T[], fromIndex: number, toIndex: number): T[];
3
3
  export declare function moveToStart<T>(array: T[], predicate: (item: T) => boolean): T[];
4
+ export declare const moveMulti: <T extends unknown>(arr: T[], indexes: number[], start: number) => T[];
package/dist/array.js CHANGED
@@ -19,3 +19,15 @@ export function moveToStart(array, predicate) {
19
19
  moveMutable(newArray, index, 0);
20
20
  return newArray;
21
21
  }
22
+ const removeSymbol = Symbol('Placeholder for removed element');
23
+ export const moveMulti = (arr, indexes, start) => {
24
+ const cloned = arr.slice();
25
+ for (let i = 0; i < cloned.length; i++) {
26
+ if (indexes.includes(i)) {
27
+ cloned[i] = removeSymbol;
28
+ }
29
+ }
30
+ const els = arr.filter((__, i) => indexes.includes(i));
31
+ cloned.splice(start, 0, ...els);
32
+ return cloned.filter((v) => v !== removeSymbol);
33
+ };
package/dist/index.d.ts CHANGED
@@ -12,3 +12,4 @@ export * as decimal from './decimal';
12
12
  export * as object from './object';
13
13
  export * as echarts from './echarts';
14
14
  export * as array from './array';
15
+ export * as number from './number';
package/dist/index.js CHANGED
@@ -12,3 +12,4 @@ export * as decimal from './decimal';
12
12
  export * as object from './object';
13
13
  export * as echarts from './echarts';
14
14
  export * as array from './array';
15
+ export * as number from './number';
@@ -0,0 +1,2 @@
1
+ /** 返回[min, max]之间的随机整数 */
2
+ export declare function randomInt(min: number, max: number): number;
package/dist/number.js ADDED
@@ -0,0 +1,4 @@
1
+ /** 返回[min, max]之间的随机整数 */
2
+ export function randomInt(min, max) {
3
+ return Math.floor(Math.random() * (max - min + 1) + min);
4
+ }
package/dist/object.d.ts CHANGED
@@ -4,3 +4,10 @@ export declare const ZeroValues: ({} | null | undefined)[];
4
4
  * 默认的零值是:undefined、null、空字符串, NaN, [], {}
5
5
  */
6
6
  export declare const removeZeroValueKeys: <T extends Record<string, any>>(obj: T, zeroValues?: ({} | null | undefined)[]) => T;
7
+ /**
8
+ * 返回tuple,而不是string[]
9
+ * const obj = { a: 1, b: '2' };
10
+ * Object.keys(obj) => string[]
11
+ * typedKeys({ a: 1, b: '2' }) => ('a' | 'b')[]
12
+ */
13
+ export declare const typedKeys: <T extends object>(obj: T) => (keyof T)[];
package/dist/object.js CHANGED
@@ -19,3 +19,10 @@ export const removeZeroValueKeys = (obj, zeroValues = ZeroValues) => {
19
19
  }
20
20
  return r;
21
21
  };
22
+ /**
23
+ * 返回tuple,而不是string[]
24
+ * const obj = { a: 1, b: '2' };
25
+ * Object.keys(obj) => string[]
26
+ * typedKeys({ a: 1, b: '2' }) => ('a' | 'b')[]
27
+ */
28
+ export const typedKeys = Object.keys;
@@ -1,3 +1,9 @@
1
1
  import type { ForwardRefExoticComponent, NamedExoticComponent, ComponentPropsWithoutRef, ComponentPropsWithRef, RefAttributes, ElementType } from 'react';
2
2
  export declare type ComponentRef<T extends ElementType> = T extends NamedExoticComponent<ComponentPropsWithoutRef<T> & RefAttributes<infer Method>> ? Method : ComponentPropsWithRef<T> extends RefAttributes<infer Method> ? Method : never;
3
3
  export declare type InferRef<T> = T extends ForwardRefExoticComponent<infer Ref> ? Ref extends React.RefAttributes<infer RefElement> ? RefElement : never : never;
4
+ declare type ReactRefComponent<Props extends {
5
+ ref?: React.Ref<any> | string;
6
+ }> = (props: Props) => React.ReactNode;
7
+ declare type ExtractRefAttributesRef<T> = T extends React.RefAttributes<infer P> ? P : never;
8
+ export declare type GetRef<T extends ReactRefComponent<any> | React.Component<any>> = T extends React.Component<any> ? T : T extends React.ComponentType<infer P> ? ExtractRefAttributesRef<P> : never;
9
+ export {};
package/dist/types.d.ts CHANGED
@@ -15,3 +15,7 @@ export declare type NonFunctionPropertyNames<T> = {
15
15
  }[keyof T];
16
16
  /** 获取对象中key的值,返回由这些值组成的union type */
17
17
  export declare type ValueOf<T> = T[keyof T];
18
+ /** 指定属性变为必选 */
19
+ export declare type WithRequired<T, K extends keyof T> = T & {
20
+ [P in K]-?: T[P];
21
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@d-matrix/utils",
3
3
  "sideEffects": false,
4
- "version": "1.21.1",
4
+ "version": "1.23.0",
5
5
  "description": "A dozen of utils for Front-End Development",
6
6
  "main": "dist/index.js",
7
7
  "scripts": {
package/readme.md CHANGED
@@ -20,6 +20,7 @@ A dozen of utils for Front-End Development
20
20
  - [decimal](#decimal)
21
21
  - [object](#object)
22
22
  - [array](#array)
23
+ - [number](#number)
23
24
  - [echarts](#echarts)
24
25
 
25
26
  ### clipboard
@@ -339,11 +340,55 @@ const map = {
339
340
  type T0 = ValueOf<typeof map>; // '0m' | '1m' | '2m' | '3m' | '4m' | '5m' | '6m'
340
341
  ```
341
342
 
343
+ - `WithRequired<T, K extends keyof T>`
344
+
345
+ 指定属性变为必选
346
+
347
+ ```ts
348
+ type Input = {
349
+ a: number;
350
+ b?: string;
351
+ };
352
+ type Output = WithRequired<Input, 'b'> // { a: number; b: string }
353
+ ```
354
+
342
355
  ### algorithm
343
356
 
344
- - `moveMulti<T extends unknown>(arr: T[], indexes: number[], start: number): T[]`
357
+ - `function nodeCountAtDepth(root: Record<string, any>, depth: number, childrenKey: string = 'children'): number;`
345
358
 
346
- 移动多个元素到数组中指定的位置,用法,见[测试用例](tests/algorithm.cy.ts)
359
+ 计算指定层级的节点数量
360
+
361
+ ```ts
362
+ const root = {
363
+ id: 1,
364
+ children: [
365
+ { id: 2, children: [{ id: 21 }, { id: 22 }, { id: 23 }] },
366
+ { id: 3, children: [{ id: 31 }, { id: 32 }, { id: 33 }] },
367
+ ],
368
+ };
369
+ expect(tree.nodeCountAtDepth(root, 0)).to.be.equal(1);
370
+ expect(tree.nodeCountAtDepth(root, 1)).to.be.equal(2);
371
+ expect(tree.nodeCountAtDepth(root, 2)).to.be.equal(6);
372
+ ```
373
+
374
+ - `const findNode = <T extends Record<string, any>>(tree: T[], predicate: (node: T) => boolean, childrenKey = 'children'): T | null`
375
+
376
+ 找到符合条件的节点
377
+
378
+ ```ts
379
+ const root = {
380
+ id: 1,
381
+ children: [
382
+ { id: 2, children: [{ id: 21 }, { id: 22 }, { id: 23 }] },
383
+ { id: 3, children: [{ id: 31 }, { id: 32 }, { id: 33 }] },
384
+ ],
385
+ };
386
+ const actual = tree.findNode([root], (node) => node.id === 3);
387
+ expect(actual).to.be.deep.equal(root.children[1]);
388
+
389
+ const actual2 = tree.findNode([root], (node) => node.id === 33);
390
+ expect(actual2).to.be.deep.equal(root.children[1].children[2]);
391
+ ```
347
392
 
348
393
  ### file
349
394
 
@@ -485,6 +530,16 @@ removeZeroValueKeys({ a: '', b: 'abc', c: undefined, d: null, e: NaN, f: -1, g:
485
530
  // { b: 'abc', f: -1 }
486
531
  ```
487
532
 
533
+ - `typedKeys(obj: T): Array<keyof T>`
534
+
535
+ 返回`tuple`,而不是`string[]`
536
+
537
+ ```ts
538
+ const obj = { a: 1, b: '2' };
539
+ Object.keys(obj) // string[]
540
+ object.typedKeys({ a: 1, b: '2' }) // ('a' | 'b')[]
541
+ ```
542
+
488
543
  ## array
489
544
 
490
545
  - `moveImmutable<T>(array: T[], fromIndex: number, toIndex: number): T[]`
@@ -522,6 +577,16 @@ const newList = array.moveToStart(list, (item) => item.id === 4);
522
577
  // [{ id: 4 }, { id: 1 }, { id: 2 }, { id: 3 }, { id: 5 }]
523
578
  ```
524
579
 
580
+ - `moveMulti<T extends unknown>(arr: T[], indexes: number[], start: number): T[]`
581
+
582
+ 移动多个元素到数组中指定的位置,用法,见[测试用例](tests/algorithm.cy.ts)
583
+
584
+ ## number
585
+
586
+ - `randomInt(min: number, max: number): number`
587
+
588
+ 返回`min`, `max`之间的随机整数
589
+
525
590
  ## echarts
526
591
 
527
592
  - `mergeOption(defaults: EChartsOption, overrides: EChartsOption, option?: deepmerge.Options): EChartsOption`
@@ -543,13 +608,13 @@ deep merge Echarts配置,用法见[测试用例](./tests//echarts/echarts.cy.t
543
608
  运行全部组件测试
544
609
 
545
610
  ```bash
546
- npm run cy:run -- --component
611
+ npm run cy:component:all
547
612
  ```
548
613
 
549
614
  运行单个组件测试
550
615
 
551
616
  ```bash
552
- npm run cy:run -- --component --spec tests/date.cy.ts
617
+ npm run cy:component -- tests/date.cy.ts
553
618
  ```
554
619
 
555
620
  运行E2E测试
@@ -1 +0,0 @@
1
- export declare const moveMulti: <T extends unknown>(arr: T[], indexes: number[], start: number) => T[];
package/dist/algorithm.js DELETED
@@ -1,12 +0,0 @@
1
- const removeSymbol = Symbol('Placeholder for removed element');
2
- export const moveMulti = (arr, indexes, start) => {
3
- const cloned = arr.slice();
4
- for (let i = 0; i < cloned.length; i++) {
5
- if (indexes.includes(i)) {
6
- cloned[i] = removeSymbol;
7
- }
8
- }
9
- const els = arr.filter((__, i) => indexes.includes(i));
10
- cloned.splice(start, 0, ...els);
11
- return cloned.filter((v) => v !== removeSymbol);
12
- };