@knotx/data
v0.5.7
Published
Data for Knotx
Readme
@knotx/data
一个基于 RxJS 的响应式数据管理库,提供强大的数据操作和双向关系管理功能。
📦 安装
npm install @knotx/datayarn add @knotx/datapnpm add @knotx/data🔧 基本概述
@knotx/data 是 Knotx 生态系统的核心数据管理包,提供两个主要的数据管理工具:
- DataManager: 用于管理数据的增删改查操作,支持草稿模式、批量操作、版本控制等高级功能
- DualRelation: 用于管理父子节点之间的双向关系,支持层级管理、循环引用检测等功能
🚀 快速开始
import { DataManager, DualRelation } from '@knotx/data'
// 创建数据管理器
const dataManager = new DataManager('my-data')
// 创建双向关系管理器
const relation = new DualRelation<string, string>()📚 API 文档
DataManager
类型定义
interface IData {
id: string
}
// DataManager 类的类型定义
interface DataManager<TData extends IData = IData, TTag extends string = any> {
// 数据管理器的方法和属性
}构造函数
const dataManager = new DataManager<MyData>('my-tag')参数:
tag: 数据管理器的标识符
核心方法
init(initialDataList?: TData[]): void
初始化数据管理器,设置初始数据列表。
interface User {
id: string
name: string
age: number
}
const userManager = new DataManager<User>('users')
userManager.init([
{ id: '1', name: 'Alice', age: 25 },
{ id: '2', name: 'Bob', age: 30 }
])getDataList$(): Observable<TData[]>
获取数据列表的响应式流。
userManager.getDataList$().subscribe((users) => {
console.log('用户列表更新:', users)
})getDataList(): TData[]
获取当前数据列表。
const users = userManager.getDataList()
console.log('当前用户:', users)getData$(id: string, equal?: (a?: TData, b?: TData) => boolean): Observable<TData | undefined>
获取指定ID数据的响应式流。
userManager.getData$('1').subscribe((user) => {
console.log('用户1数据:', user)
})getData(id: string): TData | undefined
获取指定ID的数据。
const user = userManager.getData('1')
console.log('用户1:', user)dispatch(operation: DataOperation<TData>): void
分发数据操作。
// 添加用户
userManager.dispatch({
type: 'add',
data: { id: '3', name: 'Charlie', age: 28 }
})
// 更新用户
userManager.dispatch({
type: 'update',
id: '1',
data: { age: 26 }
})
// 删除用户
userManager.dispatch({
type: 'remove',
id: '2'
})
// 批量操作
userManager.dispatch({
type: 'batch',
operations: [
{ type: 'add', data: { id: '4', name: 'David', age: 35 } },
{ type: 'update', id: '3', data: { age: 29 } }
]
})草稿模式
草稿模式允许你在不影响主数据的情况下进行数据操作。
dispatch 草稿操作
// 开始草稿
userManager.dispatch({
type: 'startDraft',
draftId: 'my-draft'
})
// 在草稿中操作
userManager.dispatch({
type: 'draftOperation',
draftId: 'my-draft',
operation: {
type: 'add',
data: { id: '5', name: 'Eve', age: 24 }
}
})
// 提交草稿
userManager.dispatch({
type: 'commitDraft',
draftId: 'my-draft'
})
// 或者丢弃草稿
userManager.dispatch({
type: 'discardDraft',
draftId: 'my-draft'
})getDraftDataList(draftId: string): TData[] | undefined
获取草稿中的数据列表。
const draftUsers = userManager.getDraftDataList('my-draft')getDraftData(draftId: string, dataId: string): TData | undefined
获取草稿中的特定数据。
const draftUser = userManager.getDraftData('my-draft', '5')dryRun(operation: DataOperation<TData>): Map<string, TData>
模拟执行操作,返回结果但不实际修改数据。
const result = userManager.dryRun({
type: 'commitDraft',
draftId: 'my-draft'
})版本控制
DataManager 提供版本控制功能,跟踪数据变更。
// 监听版本变更
userManager.patchVersion$.subscribe((version) => {
console.log('补丁版本:', version)
})
userManager.mapVersion$.subscribe((version) => {
console.log('映射版本:', version)
})
// 获取当前版本
console.log('当前版本:', userManager.version)操作管道
操作管道允许你在数据操作的不同阶段插入自定义逻辑。
interface DataOperationPipe<T extends IData = IData> {
transform?: (operations$: Subject<DataOperation<T>>) => OperatorFunction<DataOperation<T>, DataOperation<T>>
preOperation?: (operations$: Subject<DataOperation<T>>) => OperatorFunction<DataOperation<T>, DataOperation<T>>
postOperation?: (operations$: Subject<DataOperation<T>>) => OperatorFunction<
{ dataMap: Map<string, T>, operations: DataOperation<T>[] },
{ dataMap: Map<string, T>, operations: DataOperation<T>[] }
>
}
// 添加操作管道
const removePipe = userManager.addDataOperationPipe({
preOperation: () => tap((operation) => {
console.log('执行操作前:', operation)
}),
postOperation: () => tap(({ dataMap, operations }) => {
console.log('执行操作后:', { dataMap, operations })
})
})
// 移除管道
removePipe()DualRelation
类型定义
// DualRelation 类的类型定义
interface DualRelation<P, C> {
// 双向关系的方法和属性
}泛型参数:
P: 父节点类型C: 子节点类型
构造函数
interface DualRelationOptions {
allowEmptyParent?: boolean // 是否允许父节点没有子节点
historyDepth?: number // 历史变更记录的最大数量
}
const relation = new DualRelation<string, string>({
allowEmptyParent: true,
historyDepth: 50
})核心方法
add(parent: P, child: C): void
添加父子关系。
// 创建文件系统关系
const fileSystem = new DualRelation<string, string>()
fileSystem.add('root', 'folder1')
fileSystem.add('root', 'folder2')
fileSystem.add('folder1', 'file1.txt')
fileSystem.add('folder1', 'file2.txt')
fileSystem.add('folder2', 'file3.txt')removeChild(child: C): boolean
移除子节点及其父关系。
const removed = fileSystem.removeChild('file1.txt')
console.log('是否成功移除:', removed)removeParent(parent: P): boolean
移除父节点及其所有子关系。
const removed = fileSystem.removeParent('folder1')
console.log('是否成功移除:', removed)getChildren(parent: P): Set<C>
获取父节点的所有子节点。
const children = fileSystem.getChildren('root')
console.log('root的子节点:', Array.from(children))getParent(child: C): P | undefined
获取子节点的父节点。
const parent = fileSystem.getParent('file1.txt')
console.log('file1.txt的父节点:', parent)getRootParent(node: C): P | C | null
获取节点的根父节点。
const rootParent = fileSystem.getRootParent('file1.txt')
console.log('file1.txt的根父节点:', rootParent)hasRelation(parent: P, child: C): boolean
检查是否存在父子关系。
const exists = fileSystem.hasRelation('folder1', 'file1.txt')
console.log('关系是否存在:', exists)hasCircularReference(): boolean
检查是否存在循环引用。
const hasCircular = fileSystem.hasCircularReference()
console.log('是否存在循环引用:', hasCircular)addSafe(parent: P, child: C): boolean
安全地添加关系,会检查循环引用。
const added = fileSystem.addSafe('file1.txt', 'root') // 会失败,因为会产生循环引用
console.log('是否成功添加:', added)层级管理
getNodeLevel(node: P | C): number
获取节点的层级。
const level = fileSystem.getNodeLevel('file1.txt')
console.log('file1.txt的层级:', level)getDescendants(parent: P, includeSelf?: boolean): Set<C>
获取父节点的所有后代。
const descendants = fileSystem.getDescendants('root', true)
console.log('root的所有后代:', Array.from(descendants))批量操作
// 开始批量操作
fileSystem.beginBatch()
// 执行多个操作
fileSystem.add('root', 'folder3')
fileSystem.add('folder3', 'file4.txt')
fileSystem.add('folder3', 'file5.txt')
// 提交批量操作
const hasChanges = fileSystem.commitBatch()
console.log('是否有变更:', hasChanges)
// 或者使用便捷方法
const hasChanges2 = fileSystem.batch(() => {
fileSystem.add('root', 'folder4')
fileSystem.add('folder4', 'file6.txt')
})变更历史
// 监听版本变更
fileSystem.version.subscribe((version) => {
console.log('版本:', version)
})
// 获取变更历史
const history = fileSystem.changeHistory
console.log('变更历史:', history)工具方法
// 获取所有父节点
const allParents = fileSystem.getAllParents()
// 获取所有子节点
const allChildren = fileSystem.getAllChildren()
// 获取关系数量
const count = fileSystem.size()
// 清空所有关系
fileSystem.clear()📁 目录结构
packages/data/
├── src/
│ ├── index.ts # 主要导出文件
│ ├── data-manager.ts # DataManager 类和相关接口
│ └── dual-relation.ts # DualRelation 类和相关接口
├── dist/ # 编译输出目录
├── package.json # 包配置文件
├── README.md # 中文文档
├── README.en.md # 英文文档
├── CHANGELOG.md # 变更日志
├── build.config.ts # 构建配置
├── eslint.config.mjs # ESLint 配置
└── tsconfig.json # TypeScript 配置源代码结构
index.ts: 主要的导出文件,导出 DataManager 和 DualRelationdata-manager.ts: 包含 DataManager 类的完整实现,提供数据管理功能dual-relation.ts: 包含 DualRelation 类的完整实现,提供双向关系管理功能
🔗 相关链接
📄 许可证
MIT License - 详见 LICENSE 文件。
🤝 贡献
欢迎贡献代码!请查看 CONTRIBUTING.md 了解详细信息。
