@knotx/core 0.0.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.
- package/LICENSE +21 -0
- package/dist/index.cjs +418 -0
- package/dist/index.d.cts +307 -0
- package/dist/index.d.mts +307 -0
- package/dist/index.d.ts +307 -0
- package/dist/index.mjs +400 -0
- package/dist/utils.cjs +16 -0
- package/dist/utils.d.cts +1 -0
- package/dist/utils.d.mts +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.mjs +1 -0
- package/package.json +54 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { DataOperationPipe, DataOperation, DataManager } from '@knotx/data';
|
|
2
|
+
import { BehaviorSubject } from 'rxjs';
|
|
3
|
+
import { Container as Container$1, PluginDefinition as PluginDefinition$1, NodeData as NodeData$1, EdgeData as EdgeData$1, IEngineRuntime as IEngineRuntime$1, RenderType as RenderType$1, LayerComponent as LayerComponent$1, IPlugin as IPlugin$1, Layer as Layer$1, NodeRenderType as NodeRenderType$1, EdgeRenderType as EdgeRenderType$1, PluginData as PluginData$1, InteractionPriority as InteractionPriority$1 } from '@knotx/core';
|
|
4
|
+
export * from '@knotx/utils';
|
|
5
|
+
|
|
6
|
+
type HorizontalAlignment = 'left' | 'right';
|
|
7
|
+
type VerticalAlignment = 'top' | 'bottom';
|
|
8
|
+
interface NodePosition {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
}
|
|
12
|
+
interface NodeMeasured {
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
}
|
|
16
|
+
interface NodeData<TData = any> {
|
|
17
|
+
id: string;
|
|
18
|
+
type?: string;
|
|
19
|
+
position: NodePosition;
|
|
20
|
+
measured?: NodeMeasured;
|
|
21
|
+
data: TData;
|
|
22
|
+
}
|
|
23
|
+
interface NodeProps<T = any> {
|
|
24
|
+
node: NodeData<T>;
|
|
25
|
+
}
|
|
26
|
+
interface EdgeData<TData = any> {
|
|
27
|
+
id: string;
|
|
28
|
+
source: string;
|
|
29
|
+
target: string;
|
|
30
|
+
type?: string;
|
|
31
|
+
data?: TData;
|
|
32
|
+
}
|
|
33
|
+
interface EdgeProps<T = any> {
|
|
34
|
+
edge: T;
|
|
35
|
+
sourceX: number;
|
|
36
|
+
sourceY: number;
|
|
37
|
+
targetX: number;
|
|
38
|
+
targetY: number;
|
|
39
|
+
}
|
|
40
|
+
interface Container {
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
}
|
|
44
|
+
type Position = 'top' | 'right' | 'bottom' | 'left';
|
|
45
|
+
type RenderType = (...args: any[]) => any;
|
|
46
|
+
type NodeRenderType<TD extends Record<string, any> = any, TR = any> = (props: NodeProps<TD>) => TR;
|
|
47
|
+
type EdgeRenderType<TD extends Record<string, any> = any, TR = any> = (props: EdgeProps<TD>) => TR;
|
|
48
|
+
declare enum Layer {
|
|
49
|
+
Canvas = 0,
|
|
50
|
+
Background = 4,
|
|
51
|
+
Edges = 16,
|
|
52
|
+
Nodes = 64,
|
|
53
|
+
Foreground = 256
|
|
54
|
+
}
|
|
55
|
+
interface LayerComponent<TRenderType> {
|
|
56
|
+
plugin: string;
|
|
57
|
+
name: string;
|
|
58
|
+
layer: Layer;
|
|
59
|
+
render: TRenderType;
|
|
60
|
+
/**
|
|
61
|
+
* 层级偏移量
|
|
62
|
+
* @default 0
|
|
63
|
+
* (layer >> 1, layer << 1]
|
|
64
|
+
*/
|
|
65
|
+
offset?: number;
|
|
66
|
+
}
|
|
67
|
+
interface IPlugin<TPluginName extends string = string, TRenderType extends RenderType = RenderType> {
|
|
68
|
+
name: TPluginName;
|
|
69
|
+
pluginId: string;
|
|
70
|
+
onInit?: () => void;
|
|
71
|
+
onDestroy?: () => void;
|
|
72
|
+
render?: (...args: Parameters<TRenderType>) => ReturnType<TRenderType>;
|
|
73
|
+
}
|
|
74
|
+
declare abstract class BasePlugin<TPluginName extends string = string, TRenderType extends RenderType = RenderType> implements IPlugin<TPluginName, TRenderType> {
|
|
75
|
+
abstract name: TPluginName;
|
|
76
|
+
private static _instanceId;
|
|
77
|
+
private _instanceId;
|
|
78
|
+
get pluginId(): string;
|
|
79
|
+
}
|
|
80
|
+
type PluginFactory<TPluginName extends string = string, TRenderType extends RenderType = RenderType> = () => IPlugin<TPluginName, TRenderType>;
|
|
81
|
+
type PluginDefinition<TPluginName extends string = string, TRenderType extends RenderType = RenderType> = (typeof BasePlugin<TPluginName, TRenderType>) | IPlugin<TPluginName, TRenderType> | PluginFactory<TPluginName, TRenderType> | PluginWithOptions<any>;
|
|
82
|
+
type PluginWithOptions<T extends abstract new (...args: any) => any> = [
|
|
83
|
+
T,
|
|
84
|
+
...ConstructorParameters<T>
|
|
85
|
+
];
|
|
86
|
+
/**
|
|
87
|
+
* plugin data host
|
|
88
|
+
* @example
|
|
89
|
+
* `declare module '@knotx/core' {
|
|
90
|
+
* interface PluginData {
|
|
91
|
+
* pluginName: {
|
|
92
|
+
* property: any
|
|
93
|
+
* }
|
|
94
|
+
* }
|
|
95
|
+
* }`
|
|
96
|
+
*/
|
|
97
|
+
interface PluginData {
|
|
98
|
+
}
|
|
99
|
+
type NodeOperationPipe<T = any> = DataOperationPipe<NodeData<T>>;
|
|
100
|
+
type EdgeOperationPipe<T = any> = DataOperationPipe<EdgeData<T>>;
|
|
101
|
+
type NodeOperation<T = any> = DataOperation<NodeData<T>>;
|
|
102
|
+
type EdgeOperation<T = any> = DataOperation<EdgeData<T>>;
|
|
103
|
+
type NodeOperatorFunction<T = any, Args extends any[] = any[]> = (...args: Args) => NodeOperation<T>[];
|
|
104
|
+
type EdgeOperatorFunction<T = any, Args extends any[] = any[]> = (...args: Args) => EdgeOperation<T>[];
|
|
105
|
+
interface IEngineRuntime {
|
|
106
|
+
render?: {
|
|
107
|
+
getValue: <T, R = T>(value: BehaviorSubject<T> | T, options: {
|
|
108
|
+
paths: string[];
|
|
109
|
+
selector?: (value: T, context?: any) => R;
|
|
110
|
+
context?: any;
|
|
111
|
+
}) => T | R;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* 用户交互优先级定义
|
|
117
|
+
* 数值越大优先级越高
|
|
118
|
+
*/
|
|
119
|
+
declare enum InteractionPriority {
|
|
120
|
+
/** 文本输入框激活状态(输入中需独占) */
|
|
121
|
+
InputActive = 2000,
|
|
122
|
+
/** 实体连接拖拽 */
|
|
123
|
+
EntityConnectDrag = 1930,
|
|
124
|
+
/** 实体测量拖拽 */
|
|
125
|
+
EntityMeasureDrag = 1920,
|
|
126
|
+
/** 实体位置拖拽 */
|
|
127
|
+
EntityPositionDrag = 1910,
|
|
128
|
+
/** 连续操作:拖拽、缩放等进行中的动作 */
|
|
129
|
+
ContinuousDrag = 1900,
|
|
130
|
+
/** 右键菜单/上下文操作 */
|
|
131
|
+
ContextMenu = 1800,
|
|
132
|
+
/** 键盘快捷键(如 Delete/Ctrl+C) */
|
|
133
|
+
KeyboardShortcut = 1700,
|
|
134
|
+
/** 单击选中元素 */
|
|
135
|
+
ClickSelection = 1600,
|
|
136
|
+
/** 双击编辑元素 */
|
|
137
|
+
DoubleClickEdit = 1500,
|
|
138
|
+
/** 框选(多选)操作 */
|
|
139
|
+
MarqueeSelection = 1300,
|
|
140
|
+
/** 套索选择(Lasso Select) */
|
|
141
|
+
LassoSelection = 1250,
|
|
142
|
+
/** 长按操作(长按菜单/工具) */
|
|
143
|
+
LongPress = 1100,
|
|
144
|
+
/** 悬停提示(Hover Tooltip) */
|
|
145
|
+
HoverTooltip = 1000,
|
|
146
|
+
/** 画布平移(空格拖拽或手势) */
|
|
147
|
+
CanvasPan = 900,
|
|
148
|
+
/** 画布缩放(滚轮或双指) */
|
|
149
|
+
CanvasZoom = 800,
|
|
150
|
+
/** 多指手势(如三指滑动) */
|
|
151
|
+
MultiTouchGesture = 700
|
|
152
|
+
}
|
|
153
|
+
interface Interaction {
|
|
154
|
+
pluginId: string;
|
|
155
|
+
type: string;
|
|
156
|
+
priority: InteractionPriority;
|
|
157
|
+
active?: boolean;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 交互管理器
|
|
161
|
+
*/
|
|
162
|
+
declare class InteractionManager {
|
|
163
|
+
private interactions;
|
|
164
|
+
/**
|
|
165
|
+
* 获取当前活动的交互
|
|
166
|
+
*/
|
|
167
|
+
get activeInteraction(): Interaction | undefined;
|
|
168
|
+
/**
|
|
169
|
+
* 检查是否可以交互
|
|
170
|
+
* @param pluginId 插件ID
|
|
171
|
+
* @param type 交互类型
|
|
172
|
+
* @param autoStartPriority 自动启动优先级
|
|
173
|
+
* @returns 是否可以交互
|
|
174
|
+
*/
|
|
175
|
+
canInteract(pluginId: string, type: string, autoStartPriority?: InteractionPriority): boolean;
|
|
176
|
+
/**
|
|
177
|
+
* 启动交互
|
|
178
|
+
* @param pluginId 插件ID
|
|
179
|
+
* @param type 交互类型
|
|
180
|
+
* @param priority 优先级
|
|
181
|
+
* @returns 取消交互的函数
|
|
182
|
+
*/
|
|
183
|
+
startInteraction(pluginId: string, type: string, priority: InteractionPriority): () => void;
|
|
184
|
+
/**
|
|
185
|
+
* 结束交互
|
|
186
|
+
* @param pluginId 插件ID
|
|
187
|
+
* @param type 交互类型
|
|
188
|
+
*/
|
|
189
|
+
endInteraction(pluginId: string, type: string): void;
|
|
190
|
+
private updateActive;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
interface EngineOptions {
|
|
194
|
+
container: Container$1;
|
|
195
|
+
plugins?: PluginDefinition$1[];
|
|
196
|
+
nodes?: NodeData$1[];
|
|
197
|
+
edges?: EdgeData$1[];
|
|
198
|
+
runtime?: IEngineRuntime$1;
|
|
199
|
+
}
|
|
200
|
+
declare class Engine<TRenderType extends RenderType$1 = RenderType$1> {
|
|
201
|
+
readonly runtime: IEngineRuntime$1;
|
|
202
|
+
readonly interactionManager: InteractionManager;
|
|
203
|
+
readonly nodesManager: DataManager<NodeData$1>;
|
|
204
|
+
readonly edgesManager: DataManager<EdgeData$1>;
|
|
205
|
+
private container$;
|
|
206
|
+
private nodes$;
|
|
207
|
+
private edges$;
|
|
208
|
+
private layers$;
|
|
209
|
+
private plugins$;
|
|
210
|
+
private nodeRenderers$;
|
|
211
|
+
private edgeRenderers$;
|
|
212
|
+
private _pluginDataContainer;
|
|
213
|
+
get container(): Container$1;
|
|
214
|
+
set container(value: Container$1);
|
|
215
|
+
get nodes(): NodeData$1<any>[];
|
|
216
|
+
get edges(): EdgeData$1<any>[];
|
|
217
|
+
get layers(): Map<number, LayerComponent$1<TRenderType>[]>;
|
|
218
|
+
get plugins(): IPlugin$1<string, TRenderType>[];
|
|
219
|
+
constructor(options: EngineOptions);
|
|
220
|
+
private init;
|
|
221
|
+
private calculateEffectiveLayer;
|
|
222
|
+
getLayerComponents(layer: Layer$1): LayerComponent$1<TRenderType>[];
|
|
223
|
+
addNodePipe(pipe: DataOperationPipe<NodeData$1>): void;
|
|
224
|
+
addEdgePipe(pipe: DataOperationPipe<EdgeData$1>): void;
|
|
225
|
+
dispatchNodeOperation(operation: DataOperation<NodeData$1>): void;
|
|
226
|
+
dispatchEdgeOperation(operation: DataOperation<EdgeData$1>): void;
|
|
227
|
+
getNode(id: string): NodeData$1 | undefined;
|
|
228
|
+
getNodeDraft(id: string): NodeData$1 | undefined;
|
|
229
|
+
getNodes(): NodeData$1[];
|
|
230
|
+
getNodeRenderer(type: string): NodeRenderType$1 | undefined;
|
|
231
|
+
getEdge(id: string): EdgeData$1 | undefined;
|
|
232
|
+
getEdgeDraft(id: string): EdgeData$1 | undefined;
|
|
233
|
+
getEdges(): EdgeData$1[];
|
|
234
|
+
getEdgeRenderer(type: string): EdgeRenderType$1 | undefined;
|
|
235
|
+
registerPluginData<T extends keyof PluginData$1, TP extends keyof PluginData$1[T]>(pluginName: T, property: TP, data: BehaviorSubject<PluginData$1[T][TP]>): void;
|
|
236
|
+
registerNodeRenderer(type: string, renderer: NodeRenderType$1): void;
|
|
237
|
+
registerEdgeRenderer(type: string, renderer: EdgeRenderType$1): void;
|
|
238
|
+
canInteract(pluginId: string, type: string, autoStartPriority?: InteractionPriority$1): boolean;
|
|
239
|
+
startInteraction(pluginId: string, type: string, priority: InteractionPriority$1): void;
|
|
240
|
+
endInteraction(pluginId: string, type: string): void;
|
|
241
|
+
destroy(): void;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
declare function getLayerRenders<TRenderType extends RenderType$1 = RenderType$1>(plugin: IPlugin$1<string, TRenderType>): LayerComponent$1<TRenderType>[];
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Runtime 类
|
|
248
|
+
* 用于管理上下文和值处理
|
|
249
|
+
*/
|
|
250
|
+
declare class Runtime {
|
|
251
|
+
/**
|
|
252
|
+
* 当前上下文
|
|
253
|
+
*/
|
|
254
|
+
currentContext: {
|
|
255
|
+
type: any;
|
|
256
|
+
value: any;
|
|
257
|
+
} | undefined;
|
|
258
|
+
/**
|
|
259
|
+
* 在上下文中运行函数
|
|
260
|
+
* @param type 上下文类型
|
|
261
|
+
* @param handler 处理函数
|
|
262
|
+
* @param contextValue 上下文值
|
|
263
|
+
* @returns 处理函数的返回值
|
|
264
|
+
*/
|
|
265
|
+
runInContext<T>(type: any, handler: () => T, contextValue?: any): T;
|
|
266
|
+
/**
|
|
267
|
+
* 值处理器
|
|
268
|
+
*/
|
|
269
|
+
getValue<T>(engine: Engine<any>, options: {
|
|
270
|
+
paths: any[];
|
|
271
|
+
matcher?: (engine: Engine<any>) => BehaviorSubject<any>;
|
|
272
|
+
selector?: (value: T, context?: any) => any;
|
|
273
|
+
}): any;
|
|
274
|
+
/**
|
|
275
|
+
* 获取 Runtime 实例
|
|
276
|
+
* @returns Runtime 实例
|
|
277
|
+
*/
|
|
278
|
+
private static instance;
|
|
279
|
+
static getInstance(): Runtime;
|
|
280
|
+
/**
|
|
281
|
+
* 默认值处理器
|
|
282
|
+
*/
|
|
283
|
+
static DEFAULT_VALUE_HANDLER: <T>(value: BehaviorSubject<T> | T, { selector, context }: {
|
|
284
|
+
paths: string[];
|
|
285
|
+
selector?: (value: T, context?: any) => any;
|
|
286
|
+
context?: any;
|
|
287
|
+
}) => any;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* 在 render 上下文执行 hook 函数
|
|
292
|
+
* 函数中被读取的值会被转换为对应 runtime render 的响应式数据
|
|
293
|
+
* @param hook
|
|
294
|
+
*/
|
|
295
|
+
declare function use<T>(hook: () => T): T;
|
|
296
|
+
/**
|
|
297
|
+
* 在 render 上下文执行 hook 函数,context 作为 inject selector 的上下文
|
|
298
|
+
* 函数中被读取的值会被转换为对应 runtime render 的响应式数据
|
|
299
|
+
* @param hook
|
|
300
|
+
* @param context
|
|
301
|
+
*/
|
|
302
|
+
declare function use<T, TContext>(hook: () => {
|
|
303
|
+
__contextRef__: T;
|
|
304
|
+
__contextValue__: TContext;
|
|
305
|
+
}, context: TContext): T;
|
|
306
|
+
|
|
307
|
+
export { BasePlugin, type Container, type EdgeData, type EdgeOperation, type EdgeOperationPipe, type EdgeOperatorFunction, type EdgeProps, type EdgeRenderType, Engine, type EngineOptions, type HorizontalAlignment, type IEngineRuntime, type IPlugin, type Interaction, InteractionManager, InteractionPriority, Layer, type LayerComponent, type NodeData, type NodeMeasured, type NodeOperation, type NodeOperationPipe, type NodeOperatorFunction, type NodePosition, type NodeProps, type NodeRenderType, type PluginData, type PluginDefinition, type PluginFactory, type PluginWithOptions, type Position, type RenderType, Runtime, type VerticalAlignment, getLayerRenders, use };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import { Layer as Layer$1, BasePlugin as BasePlugin$1 } from '@knotx/core';
|
|
2
|
+
import { DataManager } from '@knotx/data';
|
|
3
|
+
import { set, get } from 'lodash-es';
|
|
4
|
+
import { BehaviorSubject, identity } from 'rxjs';
|
|
5
|
+
import { getSymbol } from '@knotx/utils';
|
|
6
|
+
export * from '@knotx/utils';
|
|
7
|
+
|
|
8
|
+
var __defProp$4 = Object.defineProperty;
|
|
9
|
+
var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
10
|
+
var __publicField$3 = (obj, key, value) => __defNormalProp$4(obj, key + "" , value);
|
|
11
|
+
var Layer = /* @__PURE__ */ ((Layer2) => {
|
|
12
|
+
Layer2[Layer2["Canvas"] = 0] = "Canvas";
|
|
13
|
+
Layer2[Layer2["Background"] = 4] = "Background";
|
|
14
|
+
Layer2[Layer2["Edges"] = 16] = "Edges";
|
|
15
|
+
Layer2[Layer2["Nodes"] = 64] = "Nodes";
|
|
16
|
+
Layer2[Layer2["Foreground"] = 256] = "Foreground";
|
|
17
|
+
return Layer2;
|
|
18
|
+
})(Layer || {});
|
|
19
|
+
const _BasePlugin = class _BasePlugin {
|
|
20
|
+
constructor() {
|
|
21
|
+
__publicField$3(this, "_instanceId", _BasePlugin._instanceId++);
|
|
22
|
+
}
|
|
23
|
+
get pluginId() {
|
|
24
|
+
return `${this.name}:${this._instanceId}`;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
__publicField$3(_BasePlugin, "_instanceId", 0);
|
|
28
|
+
let BasePlugin = _BasePlugin;
|
|
29
|
+
|
|
30
|
+
var __defProp$3 = Object.defineProperty;
|
|
31
|
+
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
32
|
+
var __publicField$2 = (obj, key, value) => __defNormalProp$3(obj, key + "" , value);
|
|
33
|
+
var InteractionPriority = /* @__PURE__ */ ((InteractionPriority2) => {
|
|
34
|
+
InteractionPriority2[InteractionPriority2["InputActive"] = 2e3] = "InputActive";
|
|
35
|
+
InteractionPriority2[InteractionPriority2["EntityConnectDrag"] = 1930] = "EntityConnectDrag";
|
|
36
|
+
InteractionPriority2[InteractionPriority2["EntityMeasureDrag"] = 1920] = "EntityMeasureDrag";
|
|
37
|
+
InteractionPriority2[InteractionPriority2["EntityPositionDrag"] = 1910] = "EntityPositionDrag";
|
|
38
|
+
InteractionPriority2[InteractionPriority2["ContinuousDrag"] = 1900] = "ContinuousDrag";
|
|
39
|
+
InteractionPriority2[InteractionPriority2["ContextMenu"] = 1800] = "ContextMenu";
|
|
40
|
+
InteractionPriority2[InteractionPriority2["KeyboardShortcut"] = 1700] = "KeyboardShortcut";
|
|
41
|
+
InteractionPriority2[InteractionPriority2["ClickSelection"] = 1600] = "ClickSelection";
|
|
42
|
+
InteractionPriority2[InteractionPriority2["DoubleClickEdit"] = 1500] = "DoubleClickEdit";
|
|
43
|
+
InteractionPriority2[InteractionPriority2["MarqueeSelection"] = 1300] = "MarqueeSelection";
|
|
44
|
+
InteractionPriority2[InteractionPriority2["LassoSelection"] = 1250] = "LassoSelection";
|
|
45
|
+
InteractionPriority2[InteractionPriority2["LongPress"] = 1100] = "LongPress";
|
|
46
|
+
InteractionPriority2[InteractionPriority2["HoverTooltip"] = 1e3] = "HoverTooltip";
|
|
47
|
+
InteractionPriority2[InteractionPriority2["CanvasPan"] = 900] = "CanvasPan";
|
|
48
|
+
InteractionPriority2[InteractionPriority2["CanvasZoom"] = 800] = "CanvasZoom";
|
|
49
|
+
InteractionPriority2[InteractionPriority2["MultiTouchGesture"] = 700] = "MultiTouchGesture";
|
|
50
|
+
return InteractionPriority2;
|
|
51
|
+
})(InteractionPriority || {});
|
|
52
|
+
class InteractionManager {
|
|
53
|
+
constructor() {
|
|
54
|
+
__publicField$2(this, "interactions", /* @__PURE__ */ new Map());
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* 获取当前活动的交互
|
|
58
|
+
*/
|
|
59
|
+
get activeInteraction() {
|
|
60
|
+
return Array.from(this.interactions.values()).find((interaction) => interaction.active);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 检查是否可以交互
|
|
64
|
+
* @param pluginId 插件ID
|
|
65
|
+
* @param type 交互类型
|
|
66
|
+
* @param autoStartPriority 自动启动优先级
|
|
67
|
+
* @returns 是否可以交互
|
|
68
|
+
*/
|
|
69
|
+
canInteract(pluginId, type, autoStartPriority) {
|
|
70
|
+
var _a, _b;
|
|
71
|
+
const interaction = this.interactions.get(pluginId + type);
|
|
72
|
+
if (!interaction && autoStartPriority) {
|
|
73
|
+
this.startInteraction(pluginId, type, autoStartPriority);
|
|
74
|
+
}
|
|
75
|
+
return (_b = (_a = this.interactions.get(pluginId + type)) == null ? void 0 : _a.active) != null ? _b : false;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 启动交互
|
|
79
|
+
* @param pluginId 插件ID
|
|
80
|
+
* @param type 交互类型
|
|
81
|
+
* @param priority 优先级
|
|
82
|
+
* @returns 取消交互的函数
|
|
83
|
+
*/
|
|
84
|
+
startInteraction(pluginId, type, priority) {
|
|
85
|
+
this.interactions.set(pluginId + type, { pluginId, type, priority });
|
|
86
|
+
this.updateActive();
|
|
87
|
+
return () => {
|
|
88
|
+
this.endInteraction(pluginId, type);
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* 结束交互
|
|
93
|
+
* @param pluginId 插件ID
|
|
94
|
+
* @param type 交互类型
|
|
95
|
+
*/
|
|
96
|
+
endInteraction(pluginId, type) {
|
|
97
|
+
this.interactions.delete(pluginId + type);
|
|
98
|
+
this.updateActive();
|
|
99
|
+
}
|
|
100
|
+
updateActive() {
|
|
101
|
+
const activeInteraction = Array.from(this.interactions.values()).reduce((acc, interaction) => {
|
|
102
|
+
if (acc) {
|
|
103
|
+
return interaction.priority >= acc.priority ? interaction : acc;
|
|
104
|
+
}
|
|
105
|
+
return interaction;
|
|
106
|
+
}, null);
|
|
107
|
+
this.interactions.values().forEach((interaction) => {
|
|
108
|
+
interaction.active = interaction === activeInteraction;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
var __defProp$2 = Object.defineProperty;
|
|
114
|
+
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
115
|
+
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
116
|
+
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
117
|
+
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
118
|
+
var __spreadValues$1 = (a, b) => {
|
|
119
|
+
for (var prop in b || (b = {}))
|
|
120
|
+
if (__hasOwnProp$1.call(b, prop))
|
|
121
|
+
__defNormalProp$2(a, prop, b[prop]);
|
|
122
|
+
if (__getOwnPropSymbols$1)
|
|
123
|
+
for (var prop of __getOwnPropSymbols$1(b)) {
|
|
124
|
+
if (__propIsEnum$1.call(b, prop))
|
|
125
|
+
__defNormalProp$2(a, prop, b[prop]);
|
|
126
|
+
}
|
|
127
|
+
return a;
|
|
128
|
+
};
|
|
129
|
+
function getLayerRenders(plugin) {
|
|
130
|
+
var _a;
|
|
131
|
+
const components = [];
|
|
132
|
+
let isRenderConsumed = false;
|
|
133
|
+
for (const [name, layer] of Object.entries((_a = Reflect.get(plugin, getSymbol("layer"))) != null ? _a : {})) {
|
|
134
|
+
components.push(__spreadValues$1({
|
|
135
|
+
plugin: plugin.name,
|
|
136
|
+
name: `${plugin.name}:${name}`,
|
|
137
|
+
render: Reflect.get(plugin, name).bind(plugin)
|
|
138
|
+
}, layer));
|
|
139
|
+
if (name === "render") {
|
|
140
|
+
isRenderConsumed = true;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (!isRenderConsumed && plugin.render) {
|
|
144
|
+
components.push({
|
|
145
|
+
plugin: plugin.name,
|
|
146
|
+
name: `${plugin.name}:render`,
|
|
147
|
+
layer: Layer$1.Foreground,
|
|
148
|
+
render: plugin.render.bind(plugin)
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return components;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
var __defProp$1 = Object.defineProperty;
|
|
155
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
156
|
+
var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
157
|
+
class Engine {
|
|
158
|
+
constructor(options) {
|
|
159
|
+
__publicField$1(this, "runtime");
|
|
160
|
+
__publicField$1(this, "interactionManager", new InteractionManager());
|
|
161
|
+
__publicField$1(this, "nodesManager");
|
|
162
|
+
__publicField$1(this, "edgesManager");
|
|
163
|
+
__publicField$1(this, "container$", new BehaviorSubject(null));
|
|
164
|
+
__publicField$1(this, "nodes$", new BehaviorSubject([]));
|
|
165
|
+
__publicField$1(this, "edges$", new BehaviorSubject([]));
|
|
166
|
+
__publicField$1(this, "layers$", new BehaviorSubject(/* @__PURE__ */ new Map()));
|
|
167
|
+
__publicField$1(this, "plugins$", new BehaviorSubject([]));
|
|
168
|
+
__publicField$1(this, "nodeRenderers$", new BehaviorSubject(/* @__PURE__ */ new Map()));
|
|
169
|
+
__publicField$1(this, "edgeRenderers$", new BehaviorSubject(/* @__PURE__ */ new Map()));
|
|
170
|
+
__publicField$1(this, "_pluginDataContainer", {});
|
|
171
|
+
var _a;
|
|
172
|
+
this.runtime = (_a = options.runtime) != null ? _a : {};
|
|
173
|
+
this.container$.next(options.container);
|
|
174
|
+
this.nodesManager = new DataManager("nodes");
|
|
175
|
+
this.edgesManager = new DataManager("edges");
|
|
176
|
+
this.nodesManager.getDataList$().subscribe(this.nodes$);
|
|
177
|
+
this.edgesManager.getDataList$().subscribe(this.edges$);
|
|
178
|
+
this.init(options);
|
|
179
|
+
}
|
|
180
|
+
get container() {
|
|
181
|
+
return this.container$.value;
|
|
182
|
+
}
|
|
183
|
+
set container(value) {
|
|
184
|
+
this.container$.next(value);
|
|
185
|
+
}
|
|
186
|
+
get nodes() {
|
|
187
|
+
return this.nodes$.value;
|
|
188
|
+
}
|
|
189
|
+
get edges() {
|
|
190
|
+
return this.edges$.value;
|
|
191
|
+
}
|
|
192
|
+
get layers() {
|
|
193
|
+
return this.layers$.value;
|
|
194
|
+
}
|
|
195
|
+
get plugins() {
|
|
196
|
+
return this.plugins$.value;
|
|
197
|
+
}
|
|
198
|
+
init(options) {
|
|
199
|
+
const { plugins = [], nodes = [], edges = [] } = options;
|
|
200
|
+
for (const def of plugins) {
|
|
201
|
+
let plugin;
|
|
202
|
+
if (Array.isArray(def)) {
|
|
203
|
+
plugin = new def[0](...def.slice(1));
|
|
204
|
+
} else if (typeof def === "function") {
|
|
205
|
+
if (Object.is(Reflect.getPrototypeOf(def), BasePlugin$1)) {
|
|
206
|
+
plugin = new def();
|
|
207
|
+
} else {
|
|
208
|
+
plugin = def();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (plugin) {
|
|
212
|
+
if (this._pluginDataContainer[plugin.name]) {
|
|
213
|
+
console.warn(`Plugin ${plugin.name} already registered, please check the plugin definition`);
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
this._pluginDataContainer[plugin.name] = {};
|
|
217
|
+
const engineSymbol = getSymbol("engine");
|
|
218
|
+
if (!Reflect.has(plugin, engineSymbol)) {
|
|
219
|
+
Reflect.set(plugin, engineSymbol, new BehaviorSubject(null));
|
|
220
|
+
}
|
|
221
|
+
Reflect.get(plugin, engineSymbol).next(this);
|
|
222
|
+
const currentPlugins = this.plugins$.value || [];
|
|
223
|
+
this.plugins$.next([...currentPlugins, plugin]);
|
|
224
|
+
const currentLayers = this.layers$.value;
|
|
225
|
+
getLayerRenders(plugin).forEach((component) => {
|
|
226
|
+
const effectiveLayer = this.calculateEffectiveLayer(component.layer, component.offset);
|
|
227
|
+
const layerComponents = currentLayers.get(effectiveLayer) || [];
|
|
228
|
+
currentLayers.set(effectiveLayer, [...layerComponents, component]);
|
|
229
|
+
});
|
|
230
|
+
this.layers$.next(currentLayers);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
this.plugins$.complete();
|
|
234
|
+
this.plugins$.value.forEach((plugin) => {
|
|
235
|
+
var _a;
|
|
236
|
+
return (_a = plugin.onInit) == null ? void 0 : _a.call(plugin);
|
|
237
|
+
});
|
|
238
|
+
this.nodesManager.init(nodes);
|
|
239
|
+
this.edgesManager.init(edges);
|
|
240
|
+
}
|
|
241
|
+
calculateEffectiveLayer(layer, offset) {
|
|
242
|
+
if (offset === void 0)
|
|
243
|
+
return layer;
|
|
244
|
+
return Math.max((layer >> 1) + 1, Math.min(layer << 1, layer + offset));
|
|
245
|
+
}
|
|
246
|
+
getLayerComponents(layer) {
|
|
247
|
+
return this.layers$.value.get(layer) || [];
|
|
248
|
+
}
|
|
249
|
+
addNodePipe(pipe) {
|
|
250
|
+
this.nodesManager.addDataOperationPipe(pipe);
|
|
251
|
+
}
|
|
252
|
+
addEdgePipe(pipe) {
|
|
253
|
+
this.edgesManager.addDataOperationPipe(pipe);
|
|
254
|
+
}
|
|
255
|
+
dispatchNodeOperation(operation) {
|
|
256
|
+
this.nodesManager.dispatch(operation);
|
|
257
|
+
}
|
|
258
|
+
dispatchEdgeOperation(operation) {
|
|
259
|
+
this.edgesManager.dispatch(operation);
|
|
260
|
+
}
|
|
261
|
+
getNode(id) {
|
|
262
|
+
return this.nodesManager.getData(id);
|
|
263
|
+
}
|
|
264
|
+
getNodeDraft(id) {
|
|
265
|
+
return this.nodesManager.getCurrentDraftData(id);
|
|
266
|
+
}
|
|
267
|
+
getNodes() {
|
|
268
|
+
return this.nodesManager.getDataList();
|
|
269
|
+
}
|
|
270
|
+
getNodeRenderer(type) {
|
|
271
|
+
return this.nodeRenderers$.value.get(type);
|
|
272
|
+
}
|
|
273
|
+
getEdge(id) {
|
|
274
|
+
return this.edgesManager.getData(id);
|
|
275
|
+
}
|
|
276
|
+
getEdgeDraft(id) {
|
|
277
|
+
return this.edgesManager.getCurrentDraftData(id);
|
|
278
|
+
}
|
|
279
|
+
getEdges() {
|
|
280
|
+
return this.edgesManager.getDataList();
|
|
281
|
+
}
|
|
282
|
+
getEdgeRenderer(type) {
|
|
283
|
+
return this.edgeRenderers$.value.get(type);
|
|
284
|
+
}
|
|
285
|
+
registerPluginData(pluginName, property, data) {
|
|
286
|
+
set(this, ["_pluginDataContainer", pluginName, property], data);
|
|
287
|
+
}
|
|
288
|
+
registerNodeRenderer(type, renderer) {
|
|
289
|
+
const nodeRenderers = this.nodeRenderers$.value;
|
|
290
|
+
nodeRenderers.set(type, renderer);
|
|
291
|
+
this.nodeRenderers$.next(nodeRenderers);
|
|
292
|
+
}
|
|
293
|
+
registerEdgeRenderer(type, renderer) {
|
|
294
|
+
const edgeRenderers = this.edgeRenderers$.value;
|
|
295
|
+
edgeRenderers.set(type, renderer);
|
|
296
|
+
this.edgeRenderers$.next(edgeRenderers);
|
|
297
|
+
}
|
|
298
|
+
canInteract(pluginId, type, autoStartPriority) {
|
|
299
|
+
return this.interactionManager.canInteract(pluginId, type, autoStartPriority);
|
|
300
|
+
}
|
|
301
|
+
startInteraction(pluginId, type, priority) {
|
|
302
|
+
this.interactionManager.startInteraction(pluginId, type, priority);
|
|
303
|
+
}
|
|
304
|
+
endInteraction(pluginId, type) {
|
|
305
|
+
this.interactionManager.endInteraction(pluginId, type);
|
|
306
|
+
}
|
|
307
|
+
destroy() {
|
|
308
|
+
this.plugins$.value.forEach((plugin) => {
|
|
309
|
+
var _a;
|
|
310
|
+
(_a = plugin.onDestroy) == null ? void 0 : _a.call(plugin);
|
|
311
|
+
});
|
|
312
|
+
this.plugins$.next([]);
|
|
313
|
+
this.container$.complete();
|
|
314
|
+
this.layers$.complete();
|
|
315
|
+
this.nodes$.complete();
|
|
316
|
+
this.edges$.complete();
|
|
317
|
+
this.nodeRenderers$.complete();
|
|
318
|
+
this.edgeRenderers$.complete();
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
var __defProp = Object.defineProperty;
|
|
323
|
+
var __defProps = Object.defineProperties;
|
|
324
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
325
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
326
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
327
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
328
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
329
|
+
var __spreadValues = (a, b) => {
|
|
330
|
+
for (var prop in b || (b = {}))
|
|
331
|
+
if (__hasOwnProp.call(b, prop))
|
|
332
|
+
__defNormalProp(a, prop, b[prop]);
|
|
333
|
+
if (__getOwnPropSymbols)
|
|
334
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
335
|
+
if (__propIsEnum.call(b, prop))
|
|
336
|
+
__defNormalProp(a, prop, b[prop]);
|
|
337
|
+
}
|
|
338
|
+
return a;
|
|
339
|
+
};
|
|
340
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
341
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
342
|
+
const _Runtime = class _Runtime {
|
|
343
|
+
constructor() {
|
|
344
|
+
/**
|
|
345
|
+
* 当前上下文
|
|
346
|
+
*/
|
|
347
|
+
__publicField(this, "currentContext");
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* 在上下文中运行函数
|
|
351
|
+
* @param type 上下文类型
|
|
352
|
+
* @param handler 处理函数
|
|
353
|
+
* @param contextValue 上下文值
|
|
354
|
+
* @returns 处理函数的返回值
|
|
355
|
+
*/
|
|
356
|
+
runInContext(type, handler, contextValue) {
|
|
357
|
+
this.currentContext = {
|
|
358
|
+
type,
|
|
359
|
+
value: contextValue
|
|
360
|
+
};
|
|
361
|
+
const result = handler();
|
|
362
|
+
this.currentContext = void 0;
|
|
363
|
+
return result;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* 值处理器
|
|
367
|
+
*/
|
|
368
|
+
getValue(engine, options) {
|
|
369
|
+
var _a, _b;
|
|
370
|
+
const { type: context, value: contextValue } = this.currentContext || {};
|
|
371
|
+
const getValue = ((_a = engine.runtime[context]) == null ? void 0 : _a.getValue) || _Runtime.DEFAULT_VALUE_HANDLER;
|
|
372
|
+
const value = getValue(
|
|
373
|
+
((_b = options.matcher) == null ? void 0 : _b.call(options, engine)) || get(engine, options.paths),
|
|
374
|
+
__spreadProps(__spreadValues({}, options), { context: contextValue })
|
|
375
|
+
);
|
|
376
|
+
return value;
|
|
377
|
+
}
|
|
378
|
+
static getInstance() {
|
|
379
|
+
if (!this.instance) {
|
|
380
|
+
this.instance = new _Runtime();
|
|
381
|
+
}
|
|
382
|
+
return this.instance;
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
/**
|
|
386
|
+
* 获取 Runtime 实例
|
|
387
|
+
* @returns Runtime 实例
|
|
388
|
+
*/
|
|
389
|
+
__publicField(_Runtime, "instance");
|
|
390
|
+
/**
|
|
391
|
+
* 默认值处理器
|
|
392
|
+
*/
|
|
393
|
+
__publicField(_Runtime, "DEFAULT_VALUE_HANDLER", (value, { selector = identity, context }) => selector(value instanceof BehaviorSubject ? value.value : value, context));
|
|
394
|
+
let Runtime = _Runtime;
|
|
395
|
+
|
|
396
|
+
function use(hook, context) {
|
|
397
|
+
return Runtime.getInstance().runInContext("render", hook, context);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
export { BasePlugin, Engine, InteractionManager, InteractionPriority, Layer, Runtime, getLayerRenders, use };
|