@knotx/core 0.4.12 → 0.4.14

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 (3) hide show
  1. package/README.en.md +738 -0
  2. package/README.md +738 -0
  3. package/package.json +6 -6
package/README.md ADDED
@@ -0,0 +1,738 @@
1
+ # @knotx/core
2
+
3
+ [English](./README.en.md) | **中文**
4
+
5
+ ---
6
+
7
+ ## 📦 安装
8
+
9
+ ```bash
10
+ npm install @knotx/core
11
+ ```
12
+
13
+ ```bash
14
+ yarn add @knotx/core
15
+ ```
16
+
17
+ ```bash
18
+ pnpm add @knotx/core
19
+ ```
20
+
21
+ ## 📖 概述
22
+
23
+ `@knotx/core` 是 Knotx 图形编辑器的核心包,提供了构建可视化图形编辑器所需的基础架构。它包含引擎管理、插件系统、交互管理、元素操作、层级渲染等核心功能,为开发者提供了强大而灵活的图形编辑能力。
24
+
25
+ ## 🚀 快速开始
26
+
27
+ ```typescript
28
+ import { Engine } from '@knotx/core'
29
+
30
+ // 创建引擎实例
31
+ const engine = new Engine({
32
+ container: { width: 800, height: 600, direction: 'horizontal' },
33
+ nodes: [
34
+ { id: '1', position: { x: 100, y: 100 }, data: { label: 'Node 1' } },
35
+ { id: '2', position: { x: 300, y: 200 }, data: { label: 'Node 2' } }
36
+ ],
37
+ edges: [
38
+ { id: 'e1', source: '1', target: '2', data: {} }
39
+ ]
40
+ })
41
+
42
+ // 获取节点
43
+ const nodes = engine.getNodes()
44
+ console.log(nodes)
45
+ ```
46
+
47
+ ## 📚 完整 API 文档
48
+
49
+ ### 🔧 核心类
50
+
51
+ #### Engine 类
52
+
53
+ 引擎是 Knotx 的核心,负责管理整个图形编辑器的状态和行为。
54
+
55
+ ```typescript
56
+ // Engine 类的类型定义
57
+ interface Engine<TRenderType extends RenderType = RenderType, TNode extends IRecord = IRecord, TEdge extends IRecord = IRecord> {
58
+ // 引擎的方法和属性
59
+ }
60
+ ```
61
+
62
+ **属性:**
63
+ - `runtime: IEngineRuntime` - 运行时配置
64
+ - `interaction: InteractionManager` - 交互管理器
65
+ - `nodesManager: DataManager<Node<TNode>>` - 节点数据管理器
66
+ - `edgesManager: DataManager<Edge<TEdge>>` - 边数据管理器
67
+ - `container: Container` - 容器配置
68
+ - `nodes: Node<TNode>[]` - 节点数组
69
+ - `edges: Edge<TEdge>[]` - 边数组
70
+ - `layers: Map<number, LayerComponent<TRenderType>[]>` - 层级组件映射
71
+ - `plugins: IPlugin[]` - 插件数组
72
+
73
+ **方法:**
74
+ - `getNodes(): Node<TNode>[]` - 获取所有节点
75
+ - `getEdges(): Edge<TEdge>[]` - 获取所有边
76
+ - `getNode({ id }): Node<TNode> | undefined` - 根据 ID 获取节点
77
+ - `getEdge({ id }): Edge<TEdge> | undefined` - 根据 ID 获取边
78
+ - `getNodeDraft({ id }): Node<TNode> | undefined` - 获取节点草稿
79
+ - `getEdgeDraft({ id }): Edge<TEdge> | undefined` - 获取边草稿
80
+ - `getPlugin<TPlugin>({ pluginName }): TPlugin | undefined` - 获取插件
81
+ - `getNodeRenderer(type: string): NodeRenderType | undefined` - 获取节点渲染器
82
+ - `getEdgeRenderer(type: string): EdgeRender | undefined` - 获取边渲染器
83
+ - `getLayerComponents(layer: Layer): LayerComponent<TRenderType>[]` - 获取层级组件
84
+ - `addNodePipe(pipe: DataOperationPipe<Node<TNode>>)` - 添加节点操作管道
85
+ - `addEdgePipe(pipe: DataOperationPipe<Edge<TEdge>>)` - 添加边操作管道
86
+ - `dispatchNodeOperation(operation: DataOperation<Node<TNode>>)` - 派发节点操作
87
+ - `dispatchEdgeOperation(operation: DataOperation<Edge<TEdge>>)` - 派发边操作
88
+ - `registerNodeRenderer(type: string, renderer: NodeRenderType): () => void` - 注册节点渲染器
89
+ - `registerEdgeRenderer(type: string, renderer: EdgeRenderType, config: Required<EdgeConfig>): () => void` - 注册边渲染器
90
+ - `registerPluginData<T, TP>(pluginName: T, property: TP, data: BehaviorSubject<PluginData[T][TP]>): void` - 注册插件数据
91
+ - `subscribePluginData<T, TP>(pluginName: T, property: TP, observer: (value: PluginData[T][TP]) => void): Subscription | null` - 订阅插件数据
92
+ - `registerPluginTool<T, TP>(pluginName: T, property: TP, data: { description: string; parameters: Schema; func: PluginTools[T][TP] }): void` - 注册插件工具
93
+ - `resetPluginData<T>(pluginName: T): void` - 重置插件数据
94
+ - `resetPluginTool<T>(pluginName: T): void` - 重置插件工具
95
+ - `changePluginConfig({ pluginName, config }): void` - 更改插件配置
96
+ - `callTool: CallToolMethod` - 调用工具方法
97
+ - `listPlugins(): IPluginInfo[]` - 列出所有插件
98
+ - `listPluginTools({ pluginName }): IToolInfo[]` - 列出插件工具
99
+ - `listEngineTools(): IToolInfo[]` - 列出引擎工具
100
+ - `destroy()` - 销毁引擎
101
+
102
+ #### BasePlugin 类
103
+
104
+ 插件基类,提供插件开发的基础功能。
105
+
106
+ ```typescript
107
+ // BasePlugin 抽象类的类型定义
108
+ abstract class BasePlugin<TPluginName extends string = string, TPluginConfig extends IRecord | undefined = undefined, TRenderType extends RenderType = RenderType> {
109
+ // 插件的抽象方法和属性
110
+ }
111
+ ```
112
+
113
+ **属性:**
114
+ - `abstract name: TPluginName` - 插件名称
115
+ - `pluginId: string` - 插件唯一ID
116
+ - `protected subscriptions: (SubscriptionLike | (() => void))[]` - 订阅集合
117
+ - `protected callTool: Engine['callTool']` - 调用工具方法
118
+
119
+ **方法:**
120
+ - `onInit?(config: TPluginConfig): void` - 初始化回调
121
+ - `onConfigChange?(config: TPluginConfig): void` - 配置变更回调
122
+ - `onDestroy?(): void` - 销毁回调
123
+
124
+ #### InteractionManager 类
125
+
126
+ 交互管理器,负责管理用户交互的优先级和状态。
127
+
128
+ ```typescript
129
+ // InteractionManager 类的类型定义
130
+ class InteractionManager {
131
+ // 交互管理器的方法和属性
132
+ }
133
+ ```
134
+
135
+ **属性:**
136
+ - `active: Interaction | undefined` - 当前活动交互
137
+
138
+ **方法:**
139
+ - `canInteract(priority: InteractionPriority): boolean` - 检查是否可以交互
140
+ - `start(pluginId: string, type: string, priority: InteractionPriority): () => void` - 开始交互
141
+ - `end(pluginId: string, type: string): void` - 结束交互
142
+
143
+ #### Runtime 类
144
+
145
+ 运行时管理器,处理上下文执行和值处理。
146
+
147
+ ```typescript
148
+ // Runtime 类的类型定义
149
+ class Runtime {
150
+ // 运行时的方法和属性
151
+ }
152
+ ```
153
+
154
+ **属性:**
155
+ - `currentContext: { type: any; value: any } | undefined` - 当前上下文
156
+
157
+ **方法:**
158
+ - `runInContext<T>(type: any, handler: () => T, contextValue?: any): T` - 在上下文中运行
159
+ - `getValue<T>(engine: Engine<any>, options: { paths: any[]; matcher?: (engine: Engine<any>) => BehaviorSubject<any>; selector?: (value: T, context?: any) => any }): any` - 获取值
160
+ - `static getInstance(): Runtime` - 获取单例实例
161
+ - `static DEFAULT_VALUE_HANDLER: <T>(value: BehaviorSubject<T> | T, options: { paths: string[]; selector?: (value: T, context?: any) => any; context?: any }) => T` - 默认值处理器
162
+
163
+ #### DataManager 类
164
+
165
+ 数据管理器,管理数据的增删改查和版本控制。
166
+
167
+ ```typescript
168
+ // DataManager 类的类型定义
169
+ class DataManager<TData extends IData = IData, TTag extends string = any> {
170
+ // 数据管理器的方法和属性
171
+ }
172
+ ```
173
+
174
+ **属性:**
175
+ - `readonly tag: TTag` - 标签
176
+ - `readonly dataMap$: BehaviorSubject<Map<string, TData>>` - 数据映射
177
+ - `readonly patchVersion$: BehaviorSubject<number>` - 补丁版本
178
+ - `readonly mapVersion$: BehaviorSubject<number>` - 映射版本
179
+ - `version: number` - 版本号
180
+
181
+ **方法:**
182
+ - `init(initialDataList: TData[]): void` - 初始化
183
+ - `getDataList$(): Observable<TData[]>` - 获取数据列表流
184
+ - `getDataList(): TData[]` - 获取数据列表
185
+ - `getData(id: string): TData | undefined` - 获取数据
186
+ - `getOperations$(): Observable<DataOperation<TData>>` - 获取操作流
187
+ - `dispatch(operation: DataOperation<TData>): void` - 派发操作
188
+ - `getDraftDataList(draftId: string): TData[] | undefined` - 获取草稿数据列表
189
+
190
+ #### DualRelation 类
191
+
192
+ 双向关系管理器,管理父子节点关系。
193
+
194
+ ```typescript
195
+ // DualRelation 类的类型定义
196
+ class DualRelation<P, C> {
197
+ // 双向关系管理器的方法和属性
198
+ }
199
+ ```
200
+
201
+ **属性:**
202
+ - `version: BehaviorSubject<number>` - 版本号
203
+
204
+ **方法:**
205
+ - `addRelation(parent: P, child: C): void` - 添加关系
206
+ - `removeRelation(parent: P, child: C): void` - 删除关系
207
+ - `getChildren(parent: P): C[]` - 获取子节点
208
+ - `getParent(child: C): P | undefined` - 获取父节点
209
+ - `clear(): void` - 清空关系
210
+
211
+ #### Element 接口和 DOMElement 类
212
+
213
+ 元素抽象,提供跨平台的元素操作接口。
214
+
215
+ ```typescript
216
+ interface Element {
217
+ classList: ElementClassList
218
+ attribute: ElementAttribute
219
+ uniqSelector: string | undefined
220
+ getRect: () => ElementRect
221
+ addEventListener: EventListenerDefinition
222
+ removeEventListener: EventListenerDefinition
223
+ query: (selector: string) => Element | null
224
+ queryAll: (selector: string) => Element[]
225
+ }
226
+
227
+ class DOMElement implements Element {
228
+ constructor(readonly dom: HTMLElement) {}
229
+ static fromDOM(dom: HTMLElement): DOMElement
230
+ }
231
+ ```
232
+
233
+ ### 🎭 类型定义
234
+
235
+ #### 基础类型
236
+ ```typescript
237
+ type HorizontalAlignment = 'left' | 'right'
238
+ type VerticalAlignment = 'top' | 'bottom'
239
+ type Direction = 'horizontal' | 'vertical'
240
+ type IRecord = Record<string, any>
241
+ type Position = VerticalAlignment | HorizontalAlignment | `${HorizontalAlignment}-${VerticalAlignment}` | 'center'
242
+ type RenderType = (...args: any[]) => any
243
+ ```
244
+
245
+ #### 节点相关类型
246
+ ```typescript
247
+ interface NodePosition {
248
+ x: number
249
+ y: number
250
+ }
251
+
252
+ interface NodeMeasured {
253
+ width: number
254
+ height: number
255
+ }
256
+
257
+ interface Node<TData extends IRecord = IRecord> {
258
+ id: string
259
+ type?: string
260
+ position: NodePosition
261
+ measured?: NodeMeasured
262
+ data: TData
263
+ }
264
+
265
+ interface NodeProps<TData extends IRecord = IRecord> {
266
+ node: Node<TData>
267
+ renderVersion?: number
268
+ }
269
+
270
+ type NodeRenderType<TD extends IRecord = any, TR = any> = (props: NodeProps<TD>) => TR
271
+ type NodeOperation<T extends IRecord = any> = DataOperation<Node<T>>
272
+ type NodeOperationPipe<T extends IRecord = any> = DataOperationPipe<Node<T>>
273
+ type NodeOperatorFunction<T extends IRecord = any, TArgs extends any[] = any[]> = (...args: TArgs) => NodeOperation<T>[]
274
+ ```
275
+
276
+ #### 边相关类型
277
+ ```typescript
278
+ interface EdgeConfig {
279
+ sourcePosition?: Position
280
+ targetPosition?: Position
281
+ sourceYOffset?: string | number
282
+ sourceXOffset?: string | number
283
+ targetYOffset?: string | number
284
+ targetXOffset?: string | number
285
+ }
286
+
287
+ interface Edge<TData extends IRecord = IRecord> extends EdgeConfig {
288
+ id: string
289
+ source: string
290
+ target: string
291
+ type?: string
292
+ data?: TData
293
+ }
294
+
295
+ interface EdgeProps<TData extends IRecord = IRecord> {
296
+ edge: Edge<TData>
297
+ sourceX: number
298
+ sourceY: number
299
+ targetX: number
300
+ targetY: number
301
+ renderVersion?: number
302
+ }
303
+
304
+ type EdgeRenderType<TD extends IRecord = any, TR = any> = (props: EdgeProps<TD>) => TR
305
+
306
+ interface EdgeRender<TD extends IRecord = any, TR = any> {
307
+ renderer: EdgeRenderType<TD, TR>
308
+ config: Required<EdgeConfig>
309
+ }
310
+
311
+ type EdgeOperation<T extends IRecord = any> = DataOperation<Edge<T>>
312
+ type EdgeOperationPipe<T extends IRecord = any> = DataOperationPipe<Edge<T>>
313
+ type EdgeOperatorFunction<T extends IRecord = any, TArgs extends any[] = any[]> = (...args: TArgs) => EdgeOperation<T>[]
314
+ ```
315
+
316
+ #### 容器类型
317
+ ```typescript
318
+ interface Container {
319
+ width: number
320
+ height: number
321
+ direction: Direction
322
+ }
323
+ ```
324
+
325
+ #### 层级类型
326
+ ```typescript
327
+ enum Layer {
328
+ Canvas = 0,
329
+ Background = 4,
330
+ Edges = 16,
331
+ Nodes = 64,
332
+ Foreground = 256,
333
+ }
334
+
335
+ interface LayerComponent<TRenderType> {
336
+ plugin: string
337
+ name: string
338
+ layer: Layer
339
+ render: TRenderType
340
+ offset?: number
341
+ }
342
+ ```
343
+
344
+ #### 插件类型
345
+ ```typescript
346
+ interface IPlugin<TPluginName extends string = string, TPluginConfig extends IRecord | undefined = any> {
347
+ name: TPluginName
348
+ pluginId: string
349
+ description?: string
350
+ onInit?: (config: TPluginConfig) => void
351
+ onConfigChange?: (config: TPluginConfig) => void
352
+ onDestroy?: () => void
353
+ }
354
+
355
+ type Plugin<TName extends string = string, TConfig extends IRecord | undefined = any, TRenderType extends RenderType = RenderType> = new (__: TConfig) => BasePlugin<TName, TConfig, TRenderType>
356
+
357
+ interface PluginData {} // 模块扩展接口
358
+ interface PluginTools {} // 模块扩展接口
359
+ interface EngineTools {} // 模块扩展接口
360
+
361
+ interface IPluginInfo {
362
+ name: string
363
+ description?: string
364
+ }
365
+
366
+ interface IToolInfo {
367
+ type: 'function'
368
+ name: string
369
+ description: string
370
+ parameters: Schema
371
+ }
372
+ ```
373
+
374
+ #### 数据操作类型
375
+ ```typescript
376
+ interface IData {
377
+ id: string
378
+ }
379
+
380
+ interface DataAddOperation<T extends IData = IData> {
381
+ type: 'add'
382
+ data: T
383
+ }
384
+
385
+ interface DataRemoveOperation<_T extends IData = IData> {
386
+ type: 'remove'
387
+ id: string
388
+ }
389
+
390
+ interface DataUpdateOperation<T extends IData = IData> {
391
+ type: 'update'
392
+ id: string
393
+ data: T
394
+ }
395
+
396
+ interface DataBatchOperation<T extends IData = IData> {
397
+ type: 'batch'
398
+ operations: DataOperation<T>[]
399
+ isInit?: boolean
400
+ }
401
+
402
+ interface DataStartDraftOperation<T extends IData = IData> {
403
+ type: 'startDraft'
404
+ draftId: string
405
+ data: T
406
+ }
407
+
408
+ interface DataCommitDraftOperation<T extends IData = IData> {
409
+ type: 'commitDraft'
410
+ draftId: string
411
+ data: T
412
+ }
413
+
414
+ interface DataDiscardDraftOperation<T extends IData = IData> {
415
+ type: 'discardDraft'
416
+ draftId: string
417
+ }
418
+
419
+ interface DataDraftOperation<T extends IData = IData> {
420
+ type: 'draft'
421
+ draftId: string
422
+ operation: DataOperation<T>
423
+ }
424
+
425
+ type DataOperation<T extends IData = IData> = DataAddOperation<T> | DataRemoveOperation<T> | DataUpdateOperation<T> | DataBatchOperation<T> | DataStartDraftOperation<T> | DataCommitDraftOperation<T> | DataDiscardDraftOperation<T> | DataDraftOperation<T>
426
+
427
+ interface DataOperationPipe<T extends IData = IData> {
428
+ transform?: (operations$: Subject<DataOperation<T>>) => OperatorFunction<DataOperation<T>, DataOperation<T>>
429
+ preOperation?: (operations$: Subject<DataOperation<T>>) => OperatorFunction<DataOperation<T>, DataOperation<T>>
430
+ postOperation?: (operations$: Subject<DataOperation<T>>) => OperatorFunction<{ dataMap: Map<string, T>, operations: DataOperation<T>[] }, { dataMap: Map<string, T>, operations: DataOperation<T>[] }>
431
+ }
432
+ ```
433
+
434
+ #### 交互类型
435
+ ```typescript
436
+ enum InteractionPriority {
437
+ InputActive = 2000,
438
+ EntityConnectDrag = 1930,
439
+ EntityMeasureDrag = 1920,
440
+ EntityPositionDrag = 1910,
441
+ ContinuousDrag = 1900,
442
+ ContextMenu = 1800,
443
+ KeyboardShortcut = 1700,
444
+ ClickSelection = 1600,
445
+ DoubleClickEdit = 1500,
446
+ MarqueeSelection = 1300,
447
+ LassoSelection = 1250,
448
+ LongPress = 1100,
449
+ HoverTooltip = 1000,
450
+ CanvasPan = 900,
451
+ CanvasZoom = 800,
452
+ CanvasContextMenu = 700,
453
+ CanvasClick = 600,
454
+ MultiTouchGesture = 500,
455
+ }
456
+
457
+ interface Interaction {
458
+ pluginId: string
459
+ type: string
460
+ priority: InteractionPriority
461
+ active?: boolean
462
+ }
463
+ ```
464
+
465
+ #### 元素类型
466
+ ```typescript
467
+ interface ElementClassList {
468
+ toString: () => string
469
+ add: (...tokens: string[]) => void
470
+ contains: (token: string) => boolean
471
+ remove: (...tokens: string[]) => void
472
+ }
473
+
474
+ interface ElementAttribute {
475
+ get: (name: string) => string | null
476
+ set: (name: string, value: string) => void
477
+ remove: (name: string) => void
478
+ }
479
+
480
+ interface ElementRect {
481
+ height: number
482
+ width: number
483
+ x: number
484
+ y: number
485
+ }
486
+
487
+ interface EventListenerDefinition<E = any> {
488
+ (type: string, listener: ((evt: E) => void) | EventListenerObject<E>, options?: boolean | AddEventListenerOptions): void
489
+ }
490
+ ```
491
+
492
+ #### 引擎类型
493
+ ```typescript
494
+ interface EngineOptions<TNode extends IRecord = IRecord, TEdge extends IRecord = IRecord> {
495
+ container: Container
496
+ plugins?: Plugin[]
497
+ pluginConfig?: IRecord
498
+ nodes?: Node<TNode>[]
499
+ edges?: Edge<TEdge>[]
500
+ runtime?: IEngineRuntime
501
+ }
502
+
503
+ interface IEngineRuntime {
504
+ render?: {
505
+ getValue: <T, R = T>(value: BehaviorSubject<T> | T, options: {
506
+ paths: string[]
507
+ selector?: (value: T, context?: any) => R
508
+ context?: any
509
+ }) => T | R
510
+ }
511
+ }
512
+
513
+ interface CallToolMethod {
514
+ <T extends keyof PluginTools, TP extends keyof PluginTools[T]>(pluginName: Extract<T, keyof PluginTools>, toolName: Extract<TP, keyof PluginTools[T]>, ...args: Parameters<PluginTools[T][TP]>): ReturnType<PluginTools[T][TP]>
515
+ <T extends keyof EngineTools>(engineToolName: Extract<T, keyof EngineTools>, ...args: Parameters<EngineTools[T]>): ReturnType<EngineTools[T]>
516
+ }
517
+ ```
518
+
519
+ ### 🛠️ 工具函数
520
+
521
+ #### 钩子函数
522
+ ```typescript
523
+ function use<T>(hook: () => T): T
524
+ function use<T, TContext>(hook: () => { __contextRef__: T, __contextValue__: TContext }, context: TContext): T
525
+ ```
526
+
527
+ #### 层级函数
528
+ ```typescript
529
+ function getLayerRenders<TRenderType extends RenderType = RenderType>(plugin: IPlugin): LayerComponent<TRenderType>[]
530
+ ```
531
+
532
+ #### 工具函数(来自 @knotx/utils)
533
+ ```typescript
534
+ // BEM 样式类名工具
535
+ function bem(block: string, element?: string, modifier?: string, prefix?: string): string
536
+ function addBemModifier(className: string, modifier: string): string
537
+
538
+ // 唯一 ID 生成
539
+ function generateId(): string
540
+
541
+ // 符号工具
542
+ function getSymbol<TName extends string>(name: TName): symbol & { __knotx__?: TName }
543
+
544
+ // 数据操作工具
545
+ function isInitOperation<T extends IData>(operation: DataOperation<T>): operation is DataInitBatchOperation<T>
546
+ function isDraftOperation<T extends IData>(operation: DataOperation<T>): operation is Extract<DataOperation<T>, { draftId: string }>
547
+ function isEmptyBatchOperation<T extends IData>(operation: DataOperation<T>): operation is DataEmptyBatchOperation<T>
548
+ function flattenOperations<T extends IData>(operations: DataOperation<T>[]): DataOperation<T>[]
549
+ function emptyOperation<T extends IData>(): DataEmptyBatchOperation<T>
550
+ function buildDiffOperation<T extends IData>(previousDataMap: Map<string, T>, dataMap: Map<string, T>, compare?: (a: T | undefined, b: T | undefined) => boolean): DataBatchOperation<T>
551
+ ```
552
+
553
+ ### 📘 使用示例
554
+
555
+ #### 基本使用
556
+ ```typescript
557
+ import { Engine } from '@knotx/core'
558
+
559
+ // 创建引擎
560
+ const engine = new Engine({
561
+ container: { width: 800, height: 600, direction: 'horizontal' },
562
+ nodes: [
563
+ { id: '1', position: { x: 100, y: 100 }, data: { label: 'Node 1' } }
564
+ ],
565
+ edges: []
566
+ })
567
+
568
+ // 获取数据
569
+ const nodes = engine.getNodes()
570
+ const node = engine.getNode({ id: '1' })
571
+ ```
572
+
573
+ #### 插件开发
574
+ ```typescript
575
+ import { BasePlugin, Layer } from '@knotx/core'
576
+
577
+ class MyPlugin extends BasePlugin<'my-plugin', { theme: string }> {
578
+ name = 'my-plugin' as const
579
+
580
+ onInit(config: { theme: string }) {
581
+ // 插件初始化逻辑
582
+ }
583
+ }
584
+ ```
585
+
586
+ #### 数据操作
587
+ ```typescript
588
+ import { DataManager } from '@knotx/core'
589
+
590
+ const dataManager = new DataManager<Node>('nodes')
591
+ dataManager.init([
592
+ { id: '1', position: { x: 0, y: 0 }, data: {} }
593
+ ])
594
+
595
+ // 添加数据
596
+ dataManager.dispatch({
597
+ type: 'add',
598
+ data: { id: '2', position: { x: 100, y: 100 }, data: {} }
599
+ })
600
+ ```
601
+
602
+ #### 交互管理
603
+ ```typescript
604
+ import { InteractionManager, InteractionPriority } from '@knotx/core'
605
+
606
+ const interaction = new InteractionManager()
607
+ const cancel = interaction.start('plugin-id', 'drag', InteractionPriority.EntityPositionDrag)
608
+
609
+ // 检查是否可以交互
610
+ if (interaction.canInteract(InteractionPriority.ClickSelection)) {
611
+ // 执行交互逻辑
612
+ }
613
+
614
+ // 取消交互
615
+ cancel()
616
+ ```
617
+
618
+ ## 🗂️ 文件目录结构
619
+
620
+ ```
621
+ packages/core/
622
+ ├── src/
623
+ │ ├── index.ts # 主导出文件
624
+ │ ├── definition.ts # 类型定义和接口
625
+ │ ├── engine.ts # 核心引擎实现
626
+ │ ├── element.ts # 元素抽象层
627
+ │ ├── plugin.ts # 插件基类
628
+ │ ├── interaction.ts # 交互管理器
629
+ │ ├── runtime.ts # 运行时管理
630
+ │ ├── layer.tsx # 层级渲染
631
+ │ ├── use.ts # 钩子函数
632
+ │ ├── data.ts # 数据管理(重新导出)
633
+ │ └── utils.ts # 工具函数(重新导出)
634
+ ├── dist/ # 构建输出目录
635
+ ├── package.json # 包配置文件
636
+ ├── tsconfig.json # TypeScript 配置
637
+ ├── build.config.ts # 构建配置
638
+ └── README.md # 项目文档
639
+ ```
640
+
641
+ ## 🔧 高级用法
642
+
643
+ ### 自定义插件开发
644
+
645
+ ```typescript
646
+ import type { LayerComponent } from '@knotx/core'
647
+
648
+ import { BasePlugin, Layer } from '@knotx/core'
649
+
650
+ class CustomPlugin extends BasePlugin<'custom', { theme: string }> {
651
+ name = 'custom' as const
652
+
653
+ // 声明插件数据
654
+ declare pluginData: {
655
+ selectedNodes: string[]
656
+ highlightColor: string
657
+ }
658
+
659
+ // 声明插件工具
660
+ declare pluginTools: {
661
+ selectNode: (nodeId: string) => void
662
+ clearSelection: () => void
663
+ }
664
+
665
+ onInit(config: { theme: string }) {
666
+ // 注册插件数据
667
+ this.engine.registerPluginData('custom', 'selectedNodes', new BehaviorSubject([]))
668
+ this.engine.registerPluginData('custom', 'highlightColor', new BehaviorSubject('#blue'))
669
+
670
+ // 注册插件工具
671
+ this.engine.registerPluginTool('custom', 'selectNode', {
672
+ description: '选择节点',
673
+ parameters: { type: 'string' },
674
+ func: (nodeId: string) => {
675
+ // 实现选择逻辑
676
+ console.log('Selecting node:', nodeId)
677
+ }
678
+ })
679
+
680
+ // 注册层级组件
681
+ this.engine.registerLayerComponent({
682
+ plugin: this.name,
683
+ name: 'selection-layer',
684
+ layer: Layer.Foreground,
685
+ render: this.renderSelection.bind(this)
686
+ })
687
+ }
688
+
689
+ renderSelection() {
690
+ return '<div class="selection-overlay">Selection Layer</div>'
691
+ }
692
+ }
693
+ ```
694
+
695
+ ### 数据操作管道
696
+
697
+ ```typescript
698
+ import type { EdgeOperation, NodeOperation } from '@knotx/core'
699
+
700
+ // 节点操作管道
701
+ engine.addNodePipe((operations: NodeOperation[]) => {
702
+ return operations.map((op) => {
703
+ if (op.type === 'update') {
704
+ // 在更新前验证数据
705
+ if (!validateNodeData(op.data)) {
706
+ throw new Error('Invalid node data')
707
+ }
708
+ }
709
+ return op
710
+ })
711
+ })
712
+
713
+ // 边操作管道
714
+ engine.addEdgePipe((operations: EdgeOperation[]) => {
715
+ return operations.filter((op) => {
716
+ // 过滤无效的边操作
717
+ return op.source !== op.target
718
+ })
719
+ })
720
+ ```
721
+
722
+ ---
723
+
724
+ ## 📄 开源协议
725
+
726
+ 本项目采用 [MIT License](../../LICENSE) 开源协议。
727
+
728
+ ---
729
+
730
+ ## 🔗 相关链接
731
+
732
+ - [项目主页](https://github.com/boenfu/knotx)
733
+ - [问题反馈](https://github.com/boenfu/knotx/issues)
734
+ - [贡献指南](../../CONTRIBUTING.md)
735
+
736
+ ---
737
+
738
+ Made with ❤️ by the Knotx team