1.4.5 • Published 5 months ago

@chendf/data-compare v1.4.5

Weekly downloads
-
License
ISC
Repository
github
Last release
5 months ago

data-compare

data-compare是一个对比数据之间差异的一个轻量级库,类似于简化版本的git对比。

功能

通过diff算法对比出两个版本数据或三个版本数据之间的属性差异与状态。(新增/删除/修改/交换位置/冲突)。 通过diff算法对比出两个数据之间的属性差异。是否有属性删除/新增/修改之类的。 可以手动转换为对比节点(compareTree)也可以通过parse方法自动转换,自动转换可以手动配置转换结构。

三个版本数据对比

  • 三个版本
    • 当前版本
    • 基础版本
    • 其他版本

  • 差异获取
    • 当前版本与基础版本对比得到一个差异状态树(currentDiff)。
    • 其他版本与基础版本对比得到一个差异状态树(otherDiff)。
    • currentDiff 与 otherDiff 对比得到最终的一个差异树。

注意:只有三个版本对比才会出现冲突状态。冲突是指当前版本与其他版本都修改了同一个属性则会导致冲突。

数据对比的结构

// 必须要的属性
export type CompareDataAttr = { id?: number, name?: string }

export type CompareData = CompareDataAttr & Obj

export interface CompareTree<T extends CompareDataAttr = CompareData> extends Obj {
    // 树节点id
    id: number
    // 树节点名称 也可以通过配置更改 config
    name?: string
    // 需要对比的数据
    compareData: Partial<T> & CompareDataAttr
    // 源数据
    target?: T
    // 状态
    status: AttrCompareStatus
    // 当前节点的位置更换信息
    changeInfo?: ChangeCompareInfo
    // 子节点的位置跟换信息
    childrenChangeInfo?: ChildrenChangeCompareInfo
    // 子节点
    children: CompareTree<T>[]
    // 父节点
    parent?: CompareTree<T>
    // 当前节点id与另一个对比数id的映射
    mappingId?: number
    // 是否对比更换位置状态
    diffChange?: boolean
}

methods

createCompareNode: 创建一个对比节点

  • createCompareNode (data: CreateCompareTreeProps, parent?: CompareTree, isClone = false): CompareTree
  • @param data 原始数据。
  • @param parent 父节点。
  • @param isClone 是否为clone节点,clone节点不会触发 beforeCreateCompareNode 钩子
  • @returns 返回创建成功后的节点
import { createCompareNode } from '@chendf/data-compare'
const data = {
    id: 1,
    name: '名称'
}
const compareTree = createCompareNode({compareData: data, target: data})
// 返回一个树节点

speedCreateCompareNode: 快速创建一个对比节点

  • speedCreateCompareNode (data: T, parent?: CompareTree): CompareTree
  • @param data 原始数据
  • @param parent 父节点
  • @returns 返回创建成功后的节点
import { speedCreateCompareNode } from '@chendf/data-compare'
const data = {
    id: 1,
    name: '名称'
}
const compareTree = speedCreateCompareNode(data)
// 返回一个树节点

diffCompareTree: 对比两个对比树节点之间的差异 (两个重载)

  • diffCompareTree(origin: CompareTree[], target: CompareTree[], parent?: CompareTree): CompareTree[]
  • diffCompareTree(origin: CompareTree, target: CompareTree, parent?: CompareTree): CompareTree[]
  • @param origin 原始数据,该方法是会修改原始数据的
  • @param target 对比的数据
  • @param parent 父节点数据
  • @returns 对比后的数据
import { speedCreateCompareNode, diffCompareTree } from '@chendf/data-compare'
const data = {
    id: 1,
    name: '名称'
}
const compareTree1 = speedCreateCompareNode(data)
const data2 = {
    id: 1,
    name: '名称2'
}
const compareTree2 = speedCreateCompareNode(data2)
diffCompareTree(compareTree1, compareTree2)

// return
[
    {
        id: 1,
        name: "名称",
        compareData: {
            id: 1,
            name: "名称"
        },
        target: {
            id: 1,
            name: "名称"
        },
        status: {
            type: "update",
            path: "",
            attrStatus: {
                name: {
                    type: "update",
                    path: "name",
                    oldValue: "名称2"
                }
            }
        },
        children: []
    }
]

diffStatus: 对比两个差异树节点状态,并且设置冲突状态。如果两边都有修改那么当前节点就为冲突状态,也可通过钩子手动调整

  • diffStatus(current: CompareTree[], online: CompareTree[], currentParent?: CompareTree, onlineParent?: CompareTree): void
  • diffStatus(current: CompareTree, online: CompareTree, currentParent?: CompareTree, onlineParent?: CompareTree): void
  • @param current 当前版本数据
  • @param online 线上版本数据
  • @param currentParent 当前版本父节点
  • @param onlineParent 线上版本父节点
import { speedCreateCompareNode, diffCompareTree, diffStatus } from '@chendf/data-compare'
const current = {
    id: 1,
    name: '名称1',
    test: 1,
    update: 1
}
const currentTree = speedCreateCompareNode(current)
const base = {
    id: 1,
    name: '名称',
    test: 1,
    update: 2
}
const baseTree = speedCreateCompareNode(base)
const online = {
    id: 1,
    name: '名称2',
    test: 1,
    update: 2
}
const onlineTree = speedCreateCompareNode(online)
const currentBase = diffCompareTree(currentTree, baseTree)
const onlineBase = diffCompareTree(onlineTree, baseTree)
// 对比状态
diffStatus(currentBase, onlineBase)

// currentBase
[
    {
        "id": 1,
        "name": "名称1",
        "compareData": {
            "id": 1,
            "name": "名称1",
            "test": 1,
            "update": 1
        },
        "target": {
            "id": 1,
            "name": "名称1",
            "test": 1,
            "update": 1
        },
        "status": {
            "type": "conflict",
            "path": "",
            "attrStatus": {
                "name": {
                    "type": "conflict",
                    "path": "name",
                    "oldValue": "名称"
                },
                "update": {
                    "type": "update",
                    "path": "update",
                    "oldValue": 2
                }
            }
        },
        "children": [],
        "mappingId": 3
    }
]

// onlineBase
[
    {
        "id": 3,
        "name": "名称2",
        "compareData": {
            "id": 1,
            "name": "名称2",
            "test": 1,
            "update": 2
        },
        "target": {
            "id": 1,
            "name": "名称2",
            "test": 1,
            "update": 2
        },
        "status": {
            "type": "conflict",
            "path": "",
            "attrStatus": {
                "name": {
                    "type": "conflict",
                    "path": "name",
                    "oldValue": "名称"
                }
            }
        },
        "children": [],
        "mappingId": 1
    }
]

speedDiffStatus: 快速对比三个数据之间的差异

  • speedDiffStatus (current: T, online: T, base: T): SpeedDiffStatusType
  • @param current 当前版本
  • @param online 线上版本
  • @param base 基础版本
import { speedDiffStatus } from '@chendf/data-compare'
const current = {
    id: 1,
    name: '名称1',
    test: 1,
    update: 1
}
const base = {
    id: 1,
    name: '名称',
    test: 1,
    update: 2
}
const online = {
    id: 1,
    name: '名称2',
    test: 1,
    update: 2
}
this.speedDiffStatus(current, online, base)
// 结果与 diffStatus 结果一致

diffAttr: 对比两个对象之间的差异,能展示出每个对象节点的差异,并且有存储对应的路径与旧值

  • diffAttr (origin: unknown, target: unknown, pathStacks: string[] = []): AttrCompareStatus
  • @param origin 当前版本数据。
  • @param target 其他版本数据。
  • @param pathStacks 可选参数,为当前对比的节点的key路径。
import { diffAttr } from '@chendf/data-compare'
const diffResult = diffAttr({ a: 2, b: 2, d: 1 }, { a: 1, b: 2, c: 3 })

// 返回结果
{
    type: "update",
    path: "",
    attrStatus: {
        a: {
            type: "update",
            path: "a",
            oldValue: 1
        },
        d: {
            type: "create",
            path: "d"
        },
        c: {
            type: "delete",
            path: "c"
        }
    }
}

shallowDiffAttr: 对比两个对象之间的差异,返回对象的第一层结果差异,如果无差异则返回 undefined,并且有存储对应的路径与旧值

  • shallowDiffAttr (origin: unknown, target: unknown, pathStacks: string[] = []): UndefinedAble
  • @param origin 当前版本数据。
  • @param target 其他版本数据。
  • @param pathStacks 可选参数,为当前对比的节点的key路径。
import { shallowDiffAttr } from '@chendf/data-compare'
const diffResult = shallowDiffAttr({ a: 2, b: 2, d: 1 }, { a: 1, b: 2, c: 3 })

// 返回结果
{
    "a": {
        "type": "update",
        "newValue": 2,
        "oldValue": 1
    },
    "d": {
        "type": "create",
        "newValue": 1,
        "oldValue": undefined
    },
    "c": {
        "type": "delete",
        "newValue": undefined,
        "oldValue": 3
    }
}

updateConfig: 修改配置

  • updateConfig(config: Partial)
  • config:
    • childrenKey?: string // 解析为子节点的key
    • someKey?: string // 对比的key
    • nameKey?: string // 展示的name

parse: 将数据自动解析为对比节点 (如果想要自动解析按照自己数据格式解析,可以修改配置信息)

  • parse(data: T, parent?: CompareTree): CompareTree
  • parse(data: T[], parent?: CompareTree): CompareTree[]
import { parse } from '@chendf/data-compare'
const data = {
    id: 1,
    name: '名称2',
    test: 1,
    update: 2
}
const compareTree = parse(data) // 结果与直接调用 speedCreateCompareNode 一致 (不修改配置的情况下)

钩子函数 所有的钩子都存储在 cycle 对象上

钩子函数是指在对比期间调用的一些方法,可以让你定制化对比。

beforeCreateCompareNode: 创建对比节点之前调用

  • callback:
    • @param compareTree 根据当前源创建的节点数据
import { cycle } from '@chendf/data-compare'
cycle.beforeCreateCompareNode(compareTree => {
    // 如果想要对数据进行修改,只需要处理data即可
    compareTree.name = 'update' // example
})

beforeCompare: 在diffCompareTree每个节点之前调用

  • callback(origin: CompareTree[], target: CompareTree[], parent?: CompareTree)
    • @param origin 当前数据
    • @param target 对比的数据
    • @param parent 父节点

afterCompare: 在diffCompareTree每个节点之后调用

  • callback(origin: CompareTree[], target: CompareTree[], parent?: CompareTree)
    • @param origin 当前数据
    • @param target 对比的数据
    • @param parent 父节点

beforeDiffStatus: 在diffStatus当前父节点下的每个直属子节点之前调用

  • callback(current: CompareTree[], online: CompareTree[], currentParent?: CompareTree, onlineParent?: CompareTree)
    • @param current 当前数据
    • @param online 对比的数据
    • @param currentParent current父节点
    • @param onlineParent online父节点

afterDiffStatus: 在diffStatus当前父节点下的每个直属子节点之后调用

  • callback(current: CompareTree[], online: CompareTree[], currentParent?: CompareTree, onlineParent?: CompareTree)
    • @param current 当前数据
    • @param online 对比的数据
    • @param currentParent current父节点
    • @param onlineParent online父节点

afterCompareStatus: 在diffStatus中每个节点对比之后会调用。包括克隆的节点也会调用改钩子

  • callback(current: CompareTree, online: CompareTree)
    • @param current 当前数据
    • @param online 对比的数据

beforeCloneCompareTree: 对比中有些数据是被删除的,为了维护另一边对应的数据结构,需要手动克隆一份节点数据,改钩子在克隆之前会调用,clone之后会调用 afterCompareStatus

  • callback(cloneTree: CompareTree, statusType: CompareStatusEnum, parent?: CompareTree, isOnline?: boolean)
    • @param cloneTree 需要克隆的数据
    • @param statusType clone的状态
    • @param parent 当前克隆节点的父节点
    • @param isOnline 克隆的是当前数据还是对比数据, true为克隆的对比数据

parse钩子 parse钩子不会解析每个节点的时候都调用,如果需要解析每个节点都做处理,请使用 beforeCreateCompareNode

beforeParse: 解析节点之前调用

  • callback 参数为 parse 方法调用的参数

afterParse: 解析节点之后调用

  • callback(data: T | T[], newNode: CompareTree, parent?: CompareTree)
    • @param data 原始数据
    • @param newNode 生成的节点数据
    • _@param parent 父

全局钩子函数

注意:全局钩子函数有且只能有一个

  • useBeforeSameValue: 在对比两个值是否相等之前掉用,可以修改两个值是否相等。返回 true 代表两个值 相等,返回 false 代表两个值 不相等
    • callback(callback: (originSameValue: ISameValue, newSameValue: ISameValue, originValue: any, newValue: any)
      • ISameValue: { key: string / 当前对比的 key */ , value: any / 当前对比的 value */ }
      • @param originSameValue 旧数据
      • @param newSameValue 新数据
      • @param originValue 旧原始数据 (即 diff 的 origin)
      • @param newValue 新原始数据 (即 diff 的 target)
1.4.5

5 months ago

1.4.4

5 months ago

1.4.3

5 months ago

1.4.2

2 years ago

1.4.1

2 years ago

1.4.0

2 years ago

1.3.15

2 years ago

1.3.14

2 years ago

1.3.13

2 years ago

1.3.4

2 years ago

1.3.3

2 years ago

1.3.0

2 years ago

1.2.0

2 years ago

1.1.18

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago