@flowgram.ai/command 0.1.0-alpha.2

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,284 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __decorateClass = (decorators, target, key, kind) => {
4
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
+ if (decorator = decorators[i])
7
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
+ if (kind && result) __defProp(target, key, result);
9
+ return result;
10
+ };
11
+
12
+ // src/command.ts
13
+ import { injectable, multiInject, optional } from "inversify";
14
+ import { Disposable, DisposableCollection, Emitter } from "@flowgram.ai/utils";
15
+ var Command;
16
+ ((Command2) => {
17
+ let Default;
18
+ ((Default2) => {
19
+ Default2["ZOOM_IN"] = "ZOOM_IN";
20
+ Default2["ZOOM_OUT"] = "ZOOM_OUT";
21
+ Default2["DELETE"] = "DELETE";
22
+ Default2["COPY"] = "COPY";
23
+ Default2["PASTE"] = "PASTE";
24
+ Default2["UNDO"] = "UNDO";
25
+ Default2["REDO"] = "REDO";
26
+ Default2["VIEW_CLOSE_ALL_WIDGET"] = "view.closeAllWidget";
27
+ Default2["VIEW_CLOSE_CURRENT_WIDGET"] = "view.closeCurrentWidget";
28
+ Default2["VIEW_REOPEN_LAST_WIDGET"] = "view.reopenLastWidget";
29
+ Default2["VIEW_CLOSE_OTHER_WIDGET"] = "view.closeOtherWidget";
30
+ Default2["VIEW_CLOSE_BOTTOM_PANEL"] = "view.closeBottomPannel";
31
+ Default2["VIEW_OPEN_NEXT_TAB"] = "view.openNextTab";
32
+ Default2["VIEW_OEPN_LAST_TAB"] = "view.openLastTab";
33
+ Default2["VIEW_FULL_SCREEN"] = "view.fullScreen";
34
+ Default2["VIEW_SAVING_WIDGET_CLOSE_CONFIRM"] = "view.savingWidgetCloseConfirm";
35
+ Default2["VIEW_SHORTCUTS"] = "view.shortcuts";
36
+ Default2["VIEW_PREFERENCES"] = "view.preferences";
37
+ Default2["VIEW_LOG"] = "view.log";
38
+ Default2["VIEW_PROBLEMS"] = "view.problems";
39
+ })(Default = Command2.Default || (Command2.Default = {}));
40
+ function is(arg) {
41
+ return !!arg && arg === Object(arg) && "id" in arg;
42
+ }
43
+ Command2.is = is;
44
+ })(Command || (Command = {}));
45
+ var CommandContribution = Symbol("CommandContribution");
46
+ var CommandExecuting;
47
+ ((CommandExecuting2) => {
48
+ function findSimple(arrs, newCmd) {
49
+ for (const item of arrs.values()) {
50
+ if (item.id === newCmd.id && item.args.length === newCmd.args.length && item.args.every((arg, index) => newCmd[index] === arg)) {
51
+ return item;
52
+ }
53
+ }
54
+ }
55
+ CommandExecuting2.findSimple = findSimple;
56
+ })(CommandExecuting || (CommandExecuting = {}));
57
+ var CommandRegistryFactory = "CommandRegistryFactory";
58
+ var CommandRegistry = class {
59
+ constructor() {
60
+ this._handlers = {};
61
+ this._commands = {};
62
+ this._commandExecutings = /* @__PURE__ */ new Set();
63
+ this.toUnregisterCommands = /* @__PURE__ */ new Map();
64
+ this.onDidExecuteCommandEmitter = new Emitter();
65
+ this.onDidExecuteCommand = this.onDidExecuteCommandEmitter.event;
66
+ this.onWillExecuteCommandEmitter = new Emitter();
67
+ this.onWillExecuteCommand = this.onWillExecuteCommandEmitter.event;
68
+ }
69
+ init() {
70
+ for (const contrib of this.contributions) {
71
+ contrib.registerCommands(this);
72
+ }
73
+ }
74
+ /**
75
+ * 当前所有 command
76
+ */
77
+ get commands() {
78
+ const commands = [];
79
+ for (const id of this.commandIds) {
80
+ const cmd = this.getCommand(id);
81
+ if (cmd) {
82
+ commands.push(cmd);
83
+ }
84
+ }
85
+ return commands;
86
+ }
87
+ /**
88
+ * 当前所有 commandid
89
+ */
90
+ get commandIds() {
91
+ return Object.keys(this._commands);
92
+ }
93
+ registerCommand(commandOrId, handler) {
94
+ const command = typeof commandOrId === "string" ? { id: commandOrId } : commandOrId;
95
+ if (this._commands[command.id]) {
96
+ console.warn(`A command ${command.id} is already registered.`);
97
+ return Disposable.NULL;
98
+ }
99
+ const toDispose = new DisposableCollection(this.doRegisterCommand(command));
100
+ if (handler) {
101
+ toDispose.push(this.registerHandler(command.id, handler));
102
+ }
103
+ this.toUnregisterCommands.set(command.id, toDispose);
104
+ toDispose.push(Disposable.create(() => this.toUnregisterCommands.delete(command.id)));
105
+ return toDispose;
106
+ }
107
+ unregisterCommand(commandOrId) {
108
+ const id = Command.is(commandOrId) ? commandOrId.id : commandOrId;
109
+ const toUnregister = this.toUnregisterCommands.get(id);
110
+ if (toUnregister) {
111
+ toUnregister.dispose();
112
+ }
113
+ }
114
+ /**
115
+ * 注册 handler
116
+ */
117
+ registerHandler(commandId, handler) {
118
+ let handlers = this._handlers[commandId];
119
+ if (!handlers) {
120
+ this._handlers[commandId] = handlers = [];
121
+ }
122
+ handlers.unshift(handler);
123
+ return {
124
+ dispose: () => {
125
+ const idx = handlers.indexOf(handler);
126
+ if (idx >= 0) {
127
+ handlers.splice(idx, 1);
128
+ }
129
+ }
130
+ };
131
+ }
132
+ /**
133
+ * 预留 contextMenu 用,该 handler 是否可见
134
+ */
135
+ isVisible(command, ...args) {
136
+ return typeof this.getVisibleHandler(command, ...args) !== "undefined";
137
+ }
138
+ /**
139
+ * command 是否可用
140
+ */
141
+ isEnabled(command, ...args) {
142
+ return typeof this.getActiveHandler(command, ...args) !== "undefined";
143
+ }
144
+ /**
145
+ * 预留 contextMenu 用,该 handler 是否可以触发
146
+ */
147
+ isToggled(command, ...args) {
148
+ return typeof this.getToggledHandler(command, ...args) !== "undefined";
149
+ }
150
+ /**
151
+ * 执行 command,会先判断是否可以执行,不会重复执行
152
+ */
153
+ async executeCommand(commandId, ...args) {
154
+ const handler = this.getActiveHandler(commandId, ...args);
155
+ const execInfo = { id: commandId, args };
156
+ const simpleExecInfo = CommandExecuting.findSimple(this._commandExecutings, execInfo);
157
+ if (simpleExecInfo) {
158
+ return execInfo.promise;
159
+ }
160
+ if (handler) {
161
+ try {
162
+ this._commandExecutings.add(execInfo);
163
+ this.onWillExecuteCommandEmitter.fire({ commandId, args });
164
+ const promise = handler.execute(...args);
165
+ execInfo.promise = promise;
166
+ const result = await promise;
167
+ this.onDidExecuteCommandEmitter.fire({ commandId, args });
168
+ return result;
169
+ } finally {
170
+ this._commandExecutings.delete(execInfo);
171
+ }
172
+ }
173
+ }
174
+ getVisibleHandler(commandId, ...args) {
175
+ const handlers = this._handlers[commandId];
176
+ if (handlers) {
177
+ for (const handler of handlers) {
178
+ try {
179
+ if (!handler.isVisible || handler.isVisible(...args)) {
180
+ return handler;
181
+ }
182
+ } catch (error) {
183
+ console.error(error);
184
+ }
185
+ }
186
+ }
187
+ return void 0;
188
+ }
189
+ getActiveHandler(commandId, ...args) {
190
+ const handlers = this._handlers[commandId];
191
+ if (handlers) {
192
+ for (const handler of handlers) {
193
+ try {
194
+ if (!handler.isEnabled || handler.isEnabled(...args)) {
195
+ return handler;
196
+ }
197
+ } catch (error) {
198
+ console.error(error);
199
+ }
200
+ }
201
+ }
202
+ return void 0;
203
+ }
204
+ /**
205
+ * 获取 command 对应的所有 handler
206
+ */
207
+ getAllHandlers(commandId) {
208
+ const handlers = this._handlers[commandId];
209
+ return handlers ? handlers.slice() : [];
210
+ }
211
+ getToggledHandler(commandId, ...args) {
212
+ const handlers = this._handlers[commandId];
213
+ if (handlers) {
214
+ for (const handler of handlers) {
215
+ try {
216
+ if (handler.isToggled && handler.isToggled(...args)) {
217
+ return handler;
218
+ }
219
+ } catch (error) {
220
+ console.error(error);
221
+ }
222
+ }
223
+ }
224
+ return void 0;
225
+ }
226
+ /**
227
+ * 获取 command
228
+ */
229
+ getCommand(id) {
230
+ return this._commands[id];
231
+ }
232
+ doRegisterCommand(command) {
233
+ this._commands[command.id] = command;
234
+ return {
235
+ dispose: () => {
236
+ delete this._commands[command.id];
237
+ }
238
+ };
239
+ }
240
+ /**
241
+ * 更新 command
242
+ */
243
+ updateCommand(id, command) {
244
+ if (this._commands[id]) {
245
+ this._commands[id] = {
246
+ ...this._commands[id],
247
+ ...command
248
+ };
249
+ }
250
+ }
251
+ dispose() {
252
+ this.onWillExecuteCommandEmitter.dispose();
253
+ this.onDidExecuteCommandEmitter.dispose();
254
+ }
255
+ };
256
+ __decorateClass([
257
+ multiInject(CommandContribution),
258
+ optional()
259
+ ], CommandRegistry.prototype, "contributions", 2);
260
+ CommandRegistry = __decorateClass([
261
+ injectable()
262
+ ], CommandRegistry);
263
+
264
+ // src/command-service.ts
265
+ var CommandService = Symbol("CommandService");
266
+
267
+ // src/command-container-module.ts
268
+ import { ContainerModule } from "inversify";
269
+ import { bindContributionProvider } from "@flowgram.ai/utils";
270
+ var CommandContainerModule = new ContainerModule((bind) => {
271
+ bindContributionProvider(bind, CommandContribution);
272
+ bind(CommandRegistry).toSelf().inSingletonScope();
273
+ bind(CommandService).toService(CommandRegistry);
274
+ bind(CommandRegistryFactory).toFactory((ctx) => () => ctx.container.get(CommandRegistry));
275
+ });
276
+ export {
277
+ Command,
278
+ CommandContainerModule,
279
+ CommandContribution,
280
+ CommandRegistry,
281
+ CommandRegistryFactory,
282
+ CommandService
283
+ };
284
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/command.ts","../../src/command-service.ts","../../src/command-container-module.ts"],"sourcesContent":["import { injectable, multiInject, optional } from 'inversify';\nimport { Disposable, DisposableCollection, Emitter } from '@flowgram.ai/utils';\n\nimport { type CommandService } from './command-service';\n\nexport interface Command {\n /**\n * id,唯一 key\n */\n id: string;\n /**\n * 展示用 label\n */\n label?: string;\n /**\n * 在一些明确的场景下,部分只展示简短的 label 即可\n */\n shortLabel?: string;\n\n /**\n * 展示用 command icon\n */\n icon?: string | React.ReactNode | ((props: any) => React.ReactNode);\n /**\n * 暂不使用\n */\n category?: string;\n}\nexport namespace Command {\n export enum Default {\n ZOOM_IN = 'ZOOM_IN',\n ZOOM_OUT = 'ZOOM_OUT',\n DELETE = 'DELETE',\n COPY = 'COPY',\n PASTE = 'PASTE',\n UNDO = 'UNDO',\n REDO = 'REDO',\n VIEW_CLOSE_ALL_WIDGET = 'view.closeAllWidget',\n VIEW_CLOSE_CURRENT_WIDGET = 'view.closeCurrentWidget',\n VIEW_REOPEN_LAST_WIDGET = 'view.reopenLastWidget',\n VIEW_CLOSE_OTHER_WIDGET = 'view.closeOtherWidget',\n VIEW_CLOSE_BOTTOM_PANEL = 'view.closeBottomPannel',\n VIEW_OPEN_NEXT_TAB = 'view.openNextTab',\n VIEW_OEPN_LAST_TAB = 'view.openLastTab',\n VIEW_FULL_SCREEN = 'view.fullScreen',\n VIEW_SAVING_WIDGET_CLOSE_CONFIRM = 'view.savingWidgetCloseConfirm',\n VIEW_SHORTCUTS = 'view.shortcuts',\n VIEW_PREFERENCES = 'view.preferences',\n VIEW_LOG = 'view.log',\n VIEW_PROBLEMS = 'view.problems',\n }\n\n /**\n * 判断是否是 command\n */\n export function is(arg: Command | any): arg is Command {\n return !!arg && arg === Object(arg) && 'id' in arg;\n }\n}\n\nexport interface CommandHandler {\n /**\n * handler 执行函数\n */\n execute(...args: any[]): any;\n\n /**\n * 该 handler 是否可以执行\n */\n isEnabled?(...args: any[]): boolean;\n\n /**\n * 预留 contextMenu 用,该 handler 是否可见\n */\n isVisible?(...args: any[]): boolean;\n\n /**\n * 预留 contextMenu 用,该 handler 是否可以触发\n */\n isToggled?(...args: any[]): boolean;\n}\n\nexport interface CommandEvent {\n /**\n * commandId\n */\n commandId: string;\n /**\n * 参数\n */\n args: any[];\n}\nexport const CommandContribution = Symbol('CommandContribution');\n\nexport interface CommandContribution {\n /**\n * 注册 command\n */\n registerCommands(commands: CommandService): void;\n}\n\n/**\n * 当前正在运行的 command\n */\ninterface CommandExecuting {\n /**\n * commandid\n */\n id: string;\n /**\n * 参数\n */\n args: any[];\n /**\n * 正在进行的 promise\n */\n promise?: Promise<any>;\n}\n\nnamespace CommandExecuting {\n /**\n * 获取正在运行的 command 单个实例\n */\n export function findSimple(\n arrs: Set<CommandExecuting>,\n newCmd: CommandExecuting,\n ): CommandExecuting | undefined {\n for (const item of arrs.values()) {\n if (\n item.id === newCmd.id &&\n item.args.length === newCmd.args.length &&\n item.args.every((arg, index) => (newCmd as any)[index] === arg)\n ) {\n return item;\n }\n }\n }\n}\n\nexport const CommandRegistryFactory = 'CommandRegistryFactory';\n\n@injectable()\nexport class CommandRegistry implements CommandService {\n protected readonly _handlers: { [id: string]: CommandHandler[] } = {};\n\n protected readonly _commands: { [id: string]: Command } = {};\n\n protected readonly _commandExecutings = new Set<CommandExecuting>();\n\n protected readonly toUnregisterCommands = new Map<string, Disposable>();\n\n protected readonly onDidExecuteCommandEmitter = new Emitter<CommandEvent>();\n\n readonly onDidExecuteCommand = this.onDidExecuteCommandEmitter.event;\n\n protected readonly onWillExecuteCommandEmitter = new Emitter<CommandEvent>();\n\n readonly onWillExecuteCommand = this.onWillExecuteCommandEmitter.event;\n\n @multiInject(CommandContribution)\n @optional()\n protected readonly contributions: CommandContribution[];\n\n init() {\n for (const contrib of this.contributions) {\n contrib.registerCommands(this);\n }\n }\n\n /**\n * 当前所有 command\n */\n get commands(): Command[] {\n const commands: Command[] = [];\n for (const id of this.commandIds) {\n const cmd = this.getCommand(id);\n if (cmd) {\n commands.push(cmd);\n }\n }\n return commands;\n }\n\n /**\n * 当前所有 commandid\n */\n get commandIds(): string[] {\n return Object.keys(this._commands);\n }\n\n /**\n * registerCommand\n */\n registerCommand(id: string, handler?: CommandHandler): Disposable;\n\n registerCommand(command: Command, handler?: CommandHandler): Disposable;\n\n registerCommand(commandOrId: string | Command, handler?: CommandHandler): Disposable {\n const command: Command = typeof commandOrId === 'string' ? { id: commandOrId } : commandOrId;\n\n if (this._commands[command.id]) {\n console.warn(`A command ${command.id} is already registered.`);\n return Disposable.NULL;\n }\n const toDispose = new DisposableCollection(this.doRegisterCommand(command));\n if (handler) {\n toDispose.push(this.registerHandler(command.id, handler));\n }\n this.toUnregisterCommands.set(command.id, toDispose);\n toDispose.push(Disposable.create(() => this.toUnregisterCommands.delete(command.id)));\n return toDispose;\n }\n\n /**\n * unregisterCommand\n */\n unregisterCommand(command: Command): void;\n\n unregisterCommand(id: string): void;\n\n unregisterCommand(commandOrId: Command | string): void {\n const id = Command.is(commandOrId) ? commandOrId.id : commandOrId;\n const toUnregister = this.toUnregisterCommands.get(id);\n if (toUnregister) {\n toUnregister.dispose();\n }\n }\n\n /**\n * 注册 handler\n */\n registerHandler(commandId: string, handler: CommandHandler): Disposable {\n let handlers = this._handlers[commandId];\n if (!handlers) {\n this._handlers[commandId] = handlers = [];\n }\n handlers.unshift(handler);\n return {\n dispose: () => {\n const idx = handlers.indexOf(handler);\n if (idx >= 0) {\n handlers.splice(idx, 1);\n }\n },\n };\n }\n\n /**\n * 预留 contextMenu 用,该 handler 是否可见\n */\n isVisible(command: string, ...args: any[]): boolean {\n return typeof this.getVisibleHandler(command, ...args) !== 'undefined';\n }\n\n /**\n * command 是否可用\n */\n isEnabled(command: string, ...args: any[]): boolean {\n return typeof this.getActiveHandler(command, ...args) !== 'undefined';\n }\n\n /**\n * 预留 contextMenu 用,该 handler 是否可以触发\n */\n isToggled(command: string, ...args: any[]): boolean {\n return typeof this.getToggledHandler(command, ...args) !== 'undefined';\n }\n\n /**\n * 执行 command,会先判断是否可以执行,不会重复执行\n */\n async executeCommand<T>(commandId: string, ...args: any[]): Promise<T | undefined> {\n const handler = this.getActiveHandler(commandId, ...args);\n const execInfo: CommandExecuting = { id: commandId, args };\n const simpleExecInfo = CommandExecuting.findSimple(this._commandExecutings, execInfo);\n if (simpleExecInfo) {\n return execInfo.promise;\n }\n if (handler) {\n try {\n this._commandExecutings.add(execInfo);\n this.onWillExecuteCommandEmitter.fire({ commandId, args });\n const promise = handler.execute(...args);\n execInfo.promise = promise;\n const result = await promise;\n this.onDidExecuteCommandEmitter.fire({ commandId, args });\n return result;\n } finally {\n this._commandExecutings.delete(execInfo);\n }\n }\n }\n\n getVisibleHandler(commandId: string, ...args: any[]): CommandHandler | undefined {\n const handlers = this._handlers[commandId];\n if (handlers) {\n for (const handler of handlers) {\n try {\n if (!handler.isVisible || handler.isVisible(...args)) {\n return handler;\n }\n } catch (error) {\n console.error(error);\n }\n }\n }\n return undefined;\n }\n\n getActiveHandler(commandId: string, ...args: any[]): CommandHandler | undefined {\n const handlers = this._handlers[commandId];\n if (handlers) {\n for (const handler of handlers) {\n try {\n if (!handler.isEnabled || handler.isEnabled(...args)) {\n return handler;\n }\n } catch (error) {\n console.error(error);\n }\n }\n }\n return undefined;\n }\n\n /**\n * 获取 command 对应的所有 handler\n */\n getAllHandlers(commandId: string): CommandHandler[] {\n const handlers = this._handlers[commandId];\n return handlers ? handlers.slice() : [];\n }\n\n getToggledHandler(commandId: string, ...args: any[]): CommandHandler | undefined {\n const handlers = this._handlers[commandId];\n if (handlers) {\n for (const handler of handlers) {\n try {\n if (handler.isToggled && handler.isToggled(...args)) {\n return handler;\n }\n } catch (error) {\n console.error(error);\n }\n }\n }\n return undefined;\n }\n\n /**\n * 获取 command\n */\n getCommand(id: string): Command | undefined {\n return this._commands[id];\n }\n\n protected doRegisterCommand(command: Command): Disposable {\n this._commands[command.id] = command;\n return {\n dispose: () => {\n delete this._commands[command.id];\n },\n };\n }\n\n /**\n * 更新 command\n */\n public updateCommand(id: string, command: Partial<Omit<Command, 'id'>>) {\n if (this._commands[id]) {\n this._commands[id] = {\n ...this._commands[id],\n ...command,\n };\n }\n }\n\n dispose() {\n this.onWillExecuteCommandEmitter.dispose();\n this.onDidExecuteCommandEmitter.dispose();\n }\n}\n","import { type Disposable, type Event } from '@flowgram.ai/utils';\n\nimport { type CommandEvent } from './command';\n\nexport const CommandService = Symbol('CommandService');\n\n/**\n * command service 执行接口\n */\nexport interface CommandService extends Disposable {\n /**\n * command 事件执行前触发事件\n */\n readonly onWillExecuteCommand: Event<CommandEvent>;\n /**\n * command 事件执行完成后触发\n */\n readonly onDidExecuteCommand: Event<CommandEvent>;\n\n /**\n * 执行 command\n */\n executeCommand<T>(command: string, ...args: any[]): Promise<T | undefined>;\n}\n","import { ContainerModule } from 'inversify';\nimport { bindContributionProvider } from '@flowgram.ai/utils';\n\nimport { CommandService } from './command-service';\nimport { CommandRegistry, CommandRegistryFactory, CommandContribution } from './command';\n\nexport const CommandContainerModule = new ContainerModule(bind => {\n bindContributionProvider(bind, CommandContribution);\n bind(CommandRegistry).toSelf().inSingletonScope();\n bind(CommandService).toService(CommandRegistry);\n bind(CommandRegistryFactory).toFactory(ctx => () => ctx.container.get(CommandRegistry));\n});\n"],"mappings":"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","names":["Command","Default","CommandExecuting"]}
@@ -0,0 +1,207 @@
1
+ import * as _flowgram_ai_utils from '@flowgram.ai/utils';
2
+ import { Disposable, Event, Emitter } from '@flowgram.ai/utils';
3
+ import { ContainerModule } from 'inversify';
4
+
5
+ declare const CommandService: unique symbol;
6
+ /**
7
+ * command service 执行接口
8
+ */
9
+ interface CommandService extends Disposable {
10
+ /**
11
+ * command 事件执行前触发事件
12
+ */
13
+ readonly onWillExecuteCommand: Event<CommandEvent>;
14
+ /**
15
+ * command 事件执行完成后触发
16
+ */
17
+ readonly onDidExecuteCommand: Event<CommandEvent>;
18
+ /**
19
+ * 执行 command
20
+ */
21
+ executeCommand<T>(command: string, ...args: any[]): Promise<T | undefined>;
22
+ }
23
+
24
+ interface Command {
25
+ /**
26
+ * id,唯一 key
27
+ */
28
+ id: string;
29
+ /**
30
+ * 展示用 label
31
+ */
32
+ label?: string;
33
+ /**
34
+ * 在一些明确的场景下,部分只展示简短的 label 即可
35
+ */
36
+ shortLabel?: string;
37
+ /**
38
+ * 展示用 command icon
39
+ */
40
+ icon?: string | React.ReactNode | ((props: any) => React.ReactNode);
41
+ /**
42
+ * 暂不使用
43
+ */
44
+ category?: string;
45
+ }
46
+ declare namespace Command {
47
+ enum Default {
48
+ ZOOM_IN = "ZOOM_IN",
49
+ ZOOM_OUT = "ZOOM_OUT",
50
+ DELETE = "DELETE",
51
+ COPY = "COPY",
52
+ PASTE = "PASTE",
53
+ UNDO = "UNDO",
54
+ REDO = "REDO",
55
+ VIEW_CLOSE_ALL_WIDGET = "view.closeAllWidget",
56
+ VIEW_CLOSE_CURRENT_WIDGET = "view.closeCurrentWidget",
57
+ VIEW_REOPEN_LAST_WIDGET = "view.reopenLastWidget",
58
+ VIEW_CLOSE_OTHER_WIDGET = "view.closeOtherWidget",
59
+ VIEW_CLOSE_BOTTOM_PANEL = "view.closeBottomPannel",
60
+ VIEW_OPEN_NEXT_TAB = "view.openNextTab",
61
+ VIEW_OEPN_LAST_TAB = "view.openLastTab",
62
+ VIEW_FULL_SCREEN = "view.fullScreen",
63
+ VIEW_SAVING_WIDGET_CLOSE_CONFIRM = "view.savingWidgetCloseConfirm",
64
+ VIEW_SHORTCUTS = "view.shortcuts",
65
+ VIEW_PREFERENCES = "view.preferences",
66
+ VIEW_LOG = "view.log",
67
+ VIEW_PROBLEMS = "view.problems"
68
+ }
69
+ /**
70
+ * 判断是否是 command
71
+ */
72
+ function is(arg: Command | any): arg is Command;
73
+ }
74
+ interface CommandHandler {
75
+ /**
76
+ * handler 执行函数
77
+ */
78
+ execute(...args: any[]): any;
79
+ /**
80
+ * 该 handler 是否可以执行
81
+ */
82
+ isEnabled?(...args: any[]): boolean;
83
+ /**
84
+ * 预留 contextMenu 用,该 handler 是否可见
85
+ */
86
+ isVisible?(...args: any[]): boolean;
87
+ /**
88
+ * 预留 contextMenu 用,该 handler 是否可以触发
89
+ */
90
+ isToggled?(...args: any[]): boolean;
91
+ }
92
+ interface CommandEvent {
93
+ /**
94
+ * commandId
95
+ */
96
+ commandId: string;
97
+ /**
98
+ * 参数
99
+ */
100
+ args: any[];
101
+ }
102
+ declare const CommandContribution: unique symbol;
103
+ interface CommandContribution {
104
+ /**
105
+ * 注册 command
106
+ */
107
+ registerCommands(commands: CommandService): void;
108
+ }
109
+ /**
110
+ * 当前正在运行的 command
111
+ */
112
+ interface CommandExecuting {
113
+ /**
114
+ * commandid
115
+ */
116
+ id: string;
117
+ /**
118
+ * 参数
119
+ */
120
+ args: any[];
121
+ /**
122
+ * 正在进行的 promise
123
+ */
124
+ promise?: Promise<any>;
125
+ }
126
+ declare namespace CommandExecuting {
127
+ /**
128
+ * 获取正在运行的 command 单个实例
129
+ */
130
+ function findSimple(arrs: Set<CommandExecuting>, newCmd: CommandExecuting): CommandExecuting | undefined;
131
+ }
132
+ declare const CommandRegistryFactory = "CommandRegistryFactory";
133
+ declare class CommandRegistry implements CommandService {
134
+ protected readonly _handlers: {
135
+ [id: string]: CommandHandler[];
136
+ };
137
+ protected readonly _commands: {
138
+ [id: string]: Command;
139
+ };
140
+ protected readonly _commandExecutings: Set<CommandExecuting>;
141
+ protected readonly toUnregisterCommands: Map<string, Disposable>;
142
+ protected readonly onDidExecuteCommandEmitter: Emitter<CommandEvent>;
143
+ readonly onDidExecuteCommand: _flowgram_ai_utils.Event<CommandEvent>;
144
+ protected readonly onWillExecuteCommandEmitter: Emitter<CommandEvent>;
145
+ readonly onWillExecuteCommand: _flowgram_ai_utils.Event<CommandEvent>;
146
+ protected readonly contributions: CommandContribution[];
147
+ init(): void;
148
+ /**
149
+ * 当前所有 command
150
+ */
151
+ get commands(): Command[];
152
+ /**
153
+ * 当前所有 commandid
154
+ */
155
+ get commandIds(): string[];
156
+ /**
157
+ * registerCommand
158
+ */
159
+ registerCommand(id: string, handler?: CommandHandler): Disposable;
160
+ registerCommand(command: Command, handler?: CommandHandler): Disposable;
161
+ /**
162
+ * unregisterCommand
163
+ */
164
+ unregisterCommand(command: Command): void;
165
+ unregisterCommand(id: string): void;
166
+ /**
167
+ * 注册 handler
168
+ */
169
+ registerHandler(commandId: string, handler: CommandHandler): Disposable;
170
+ /**
171
+ * 预留 contextMenu 用,该 handler 是否可见
172
+ */
173
+ isVisible(command: string, ...args: any[]): boolean;
174
+ /**
175
+ * command 是否可用
176
+ */
177
+ isEnabled(command: string, ...args: any[]): boolean;
178
+ /**
179
+ * 预留 contextMenu 用,该 handler 是否可以触发
180
+ */
181
+ isToggled(command: string, ...args: any[]): boolean;
182
+ /**
183
+ * 执行 command,会先判断是否可以执行,不会重复执行
184
+ */
185
+ executeCommand<T>(commandId: string, ...args: any[]): Promise<T | undefined>;
186
+ getVisibleHandler(commandId: string, ...args: any[]): CommandHandler | undefined;
187
+ getActiveHandler(commandId: string, ...args: any[]): CommandHandler | undefined;
188
+ /**
189
+ * 获取 command 对应的所有 handler
190
+ */
191
+ getAllHandlers(commandId: string): CommandHandler[];
192
+ getToggledHandler(commandId: string, ...args: any[]): CommandHandler | undefined;
193
+ /**
194
+ * 获取 command
195
+ */
196
+ getCommand(id: string): Command | undefined;
197
+ protected doRegisterCommand(command: Command): Disposable;
198
+ /**
199
+ * 更新 command
200
+ */
201
+ updateCommand(id: string, command: Partial<Omit<Command, 'id'>>): void;
202
+ dispose(): void;
203
+ }
204
+
205
+ declare const CommandContainerModule: ContainerModule;
206
+
207
+ export { Command, CommandContainerModule, CommandContribution, type CommandHandler, CommandRegistry, CommandRegistryFactory, CommandService };
@@ -0,0 +1,207 @@
1
+ import * as _flowgram_ai_utils from '@flowgram.ai/utils';
2
+ import { Disposable, Event, Emitter } from '@flowgram.ai/utils';
3
+ import { ContainerModule } from 'inversify';
4
+
5
+ declare const CommandService: unique symbol;
6
+ /**
7
+ * command service 执行接口
8
+ */
9
+ interface CommandService extends Disposable {
10
+ /**
11
+ * command 事件执行前触发事件
12
+ */
13
+ readonly onWillExecuteCommand: Event<CommandEvent>;
14
+ /**
15
+ * command 事件执行完成后触发
16
+ */
17
+ readonly onDidExecuteCommand: Event<CommandEvent>;
18
+ /**
19
+ * 执行 command
20
+ */
21
+ executeCommand<T>(command: string, ...args: any[]): Promise<T | undefined>;
22
+ }
23
+
24
+ interface Command {
25
+ /**
26
+ * id,唯一 key
27
+ */
28
+ id: string;
29
+ /**
30
+ * 展示用 label
31
+ */
32
+ label?: string;
33
+ /**
34
+ * 在一些明确的场景下,部分只展示简短的 label 即可
35
+ */
36
+ shortLabel?: string;
37
+ /**
38
+ * 展示用 command icon
39
+ */
40
+ icon?: string | React.ReactNode | ((props: any) => React.ReactNode);
41
+ /**
42
+ * 暂不使用
43
+ */
44
+ category?: string;
45
+ }
46
+ declare namespace Command {
47
+ enum Default {
48
+ ZOOM_IN = "ZOOM_IN",
49
+ ZOOM_OUT = "ZOOM_OUT",
50
+ DELETE = "DELETE",
51
+ COPY = "COPY",
52
+ PASTE = "PASTE",
53
+ UNDO = "UNDO",
54
+ REDO = "REDO",
55
+ VIEW_CLOSE_ALL_WIDGET = "view.closeAllWidget",
56
+ VIEW_CLOSE_CURRENT_WIDGET = "view.closeCurrentWidget",
57
+ VIEW_REOPEN_LAST_WIDGET = "view.reopenLastWidget",
58
+ VIEW_CLOSE_OTHER_WIDGET = "view.closeOtherWidget",
59
+ VIEW_CLOSE_BOTTOM_PANEL = "view.closeBottomPannel",
60
+ VIEW_OPEN_NEXT_TAB = "view.openNextTab",
61
+ VIEW_OEPN_LAST_TAB = "view.openLastTab",
62
+ VIEW_FULL_SCREEN = "view.fullScreen",
63
+ VIEW_SAVING_WIDGET_CLOSE_CONFIRM = "view.savingWidgetCloseConfirm",
64
+ VIEW_SHORTCUTS = "view.shortcuts",
65
+ VIEW_PREFERENCES = "view.preferences",
66
+ VIEW_LOG = "view.log",
67
+ VIEW_PROBLEMS = "view.problems"
68
+ }
69
+ /**
70
+ * 判断是否是 command
71
+ */
72
+ function is(arg: Command | any): arg is Command;
73
+ }
74
+ interface CommandHandler {
75
+ /**
76
+ * handler 执行函数
77
+ */
78
+ execute(...args: any[]): any;
79
+ /**
80
+ * 该 handler 是否可以执行
81
+ */
82
+ isEnabled?(...args: any[]): boolean;
83
+ /**
84
+ * 预留 contextMenu 用,该 handler 是否可见
85
+ */
86
+ isVisible?(...args: any[]): boolean;
87
+ /**
88
+ * 预留 contextMenu 用,该 handler 是否可以触发
89
+ */
90
+ isToggled?(...args: any[]): boolean;
91
+ }
92
+ interface CommandEvent {
93
+ /**
94
+ * commandId
95
+ */
96
+ commandId: string;
97
+ /**
98
+ * 参数
99
+ */
100
+ args: any[];
101
+ }
102
+ declare const CommandContribution: unique symbol;
103
+ interface CommandContribution {
104
+ /**
105
+ * 注册 command
106
+ */
107
+ registerCommands(commands: CommandService): void;
108
+ }
109
+ /**
110
+ * 当前正在运行的 command
111
+ */
112
+ interface CommandExecuting {
113
+ /**
114
+ * commandid
115
+ */
116
+ id: string;
117
+ /**
118
+ * 参数
119
+ */
120
+ args: any[];
121
+ /**
122
+ * 正在进行的 promise
123
+ */
124
+ promise?: Promise<any>;
125
+ }
126
+ declare namespace CommandExecuting {
127
+ /**
128
+ * 获取正在运行的 command 单个实例
129
+ */
130
+ function findSimple(arrs: Set<CommandExecuting>, newCmd: CommandExecuting): CommandExecuting | undefined;
131
+ }
132
+ declare const CommandRegistryFactory = "CommandRegistryFactory";
133
+ declare class CommandRegistry implements CommandService {
134
+ protected readonly _handlers: {
135
+ [id: string]: CommandHandler[];
136
+ };
137
+ protected readonly _commands: {
138
+ [id: string]: Command;
139
+ };
140
+ protected readonly _commandExecutings: Set<CommandExecuting>;
141
+ protected readonly toUnregisterCommands: Map<string, Disposable>;
142
+ protected readonly onDidExecuteCommandEmitter: Emitter<CommandEvent>;
143
+ readonly onDidExecuteCommand: _flowgram_ai_utils.Event<CommandEvent>;
144
+ protected readonly onWillExecuteCommandEmitter: Emitter<CommandEvent>;
145
+ readonly onWillExecuteCommand: _flowgram_ai_utils.Event<CommandEvent>;
146
+ protected readonly contributions: CommandContribution[];
147
+ init(): void;
148
+ /**
149
+ * 当前所有 command
150
+ */
151
+ get commands(): Command[];
152
+ /**
153
+ * 当前所有 commandid
154
+ */
155
+ get commandIds(): string[];
156
+ /**
157
+ * registerCommand
158
+ */
159
+ registerCommand(id: string, handler?: CommandHandler): Disposable;
160
+ registerCommand(command: Command, handler?: CommandHandler): Disposable;
161
+ /**
162
+ * unregisterCommand
163
+ */
164
+ unregisterCommand(command: Command): void;
165
+ unregisterCommand(id: string): void;
166
+ /**
167
+ * 注册 handler
168
+ */
169
+ registerHandler(commandId: string, handler: CommandHandler): Disposable;
170
+ /**
171
+ * 预留 contextMenu 用,该 handler 是否可见
172
+ */
173
+ isVisible(command: string, ...args: any[]): boolean;
174
+ /**
175
+ * command 是否可用
176
+ */
177
+ isEnabled(command: string, ...args: any[]): boolean;
178
+ /**
179
+ * 预留 contextMenu 用,该 handler 是否可以触发
180
+ */
181
+ isToggled(command: string, ...args: any[]): boolean;
182
+ /**
183
+ * 执行 command,会先判断是否可以执行,不会重复执行
184
+ */
185
+ executeCommand<T>(commandId: string, ...args: any[]): Promise<T | undefined>;
186
+ getVisibleHandler(commandId: string, ...args: any[]): CommandHandler | undefined;
187
+ getActiveHandler(commandId: string, ...args: any[]): CommandHandler | undefined;
188
+ /**
189
+ * 获取 command 对应的所有 handler
190
+ */
191
+ getAllHandlers(commandId: string): CommandHandler[];
192
+ getToggledHandler(commandId: string, ...args: any[]): CommandHandler | undefined;
193
+ /**
194
+ * 获取 command
195
+ */
196
+ getCommand(id: string): Command | undefined;
197
+ protected doRegisterCommand(command: Command): Disposable;
198
+ /**
199
+ * 更新 command
200
+ */
201
+ updateCommand(id: string, command: Partial<Omit<Command, 'id'>>): void;
202
+ dispose(): void;
203
+ }
204
+
205
+ declare const CommandContainerModule: ContainerModule;
206
+
207
+ export { Command, CommandContainerModule, CommandContribution, type CommandHandler, CommandRegistry, CommandRegistryFactory, CommandService };
package/dist/index.js ADDED
@@ -0,0 +1,313 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var __decorateClass = (decorators, target, key, kind) => {
20
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
21
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
22
+ if (decorator = decorators[i])
23
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
24
+ if (kind && result) __defProp(target, key, result);
25
+ return result;
26
+ };
27
+
28
+ // src/index.ts
29
+ var src_exports = {};
30
+ __export(src_exports, {
31
+ Command: () => Command,
32
+ CommandContainerModule: () => CommandContainerModule,
33
+ CommandContribution: () => CommandContribution,
34
+ CommandRegistry: () => CommandRegistry,
35
+ CommandRegistryFactory: () => CommandRegistryFactory,
36
+ CommandService: () => CommandService
37
+ });
38
+ module.exports = __toCommonJS(src_exports);
39
+
40
+ // src/command.ts
41
+ var import_inversify = require("inversify");
42
+ var import_utils = require("@flowgram.ai/utils");
43
+ var Command;
44
+ ((Command2) => {
45
+ let Default;
46
+ ((Default2) => {
47
+ Default2["ZOOM_IN"] = "ZOOM_IN";
48
+ Default2["ZOOM_OUT"] = "ZOOM_OUT";
49
+ Default2["DELETE"] = "DELETE";
50
+ Default2["COPY"] = "COPY";
51
+ Default2["PASTE"] = "PASTE";
52
+ Default2["UNDO"] = "UNDO";
53
+ Default2["REDO"] = "REDO";
54
+ Default2["VIEW_CLOSE_ALL_WIDGET"] = "view.closeAllWidget";
55
+ Default2["VIEW_CLOSE_CURRENT_WIDGET"] = "view.closeCurrentWidget";
56
+ Default2["VIEW_REOPEN_LAST_WIDGET"] = "view.reopenLastWidget";
57
+ Default2["VIEW_CLOSE_OTHER_WIDGET"] = "view.closeOtherWidget";
58
+ Default2["VIEW_CLOSE_BOTTOM_PANEL"] = "view.closeBottomPannel";
59
+ Default2["VIEW_OPEN_NEXT_TAB"] = "view.openNextTab";
60
+ Default2["VIEW_OEPN_LAST_TAB"] = "view.openLastTab";
61
+ Default2["VIEW_FULL_SCREEN"] = "view.fullScreen";
62
+ Default2["VIEW_SAVING_WIDGET_CLOSE_CONFIRM"] = "view.savingWidgetCloseConfirm";
63
+ Default2["VIEW_SHORTCUTS"] = "view.shortcuts";
64
+ Default2["VIEW_PREFERENCES"] = "view.preferences";
65
+ Default2["VIEW_LOG"] = "view.log";
66
+ Default2["VIEW_PROBLEMS"] = "view.problems";
67
+ })(Default = Command2.Default || (Command2.Default = {}));
68
+ function is(arg) {
69
+ return !!arg && arg === Object(arg) && "id" in arg;
70
+ }
71
+ Command2.is = is;
72
+ })(Command || (Command = {}));
73
+ var CommandContribution = Symbol("CommandContribution");
74
+ var CommandExecuting;
75
+ ((CommandExecuting2) => {
76
+ function findSimple(arrs, newCmd) {
77
+ for (const item of arrs.values()) {
78
+ if (item.id === newCmd.id && item.args.length === newCmd.args.length && item.args.every((arg, index) => newCmd[index] === arg)) {
79
+ return item;
80
+ }
81
+ }
82
+ }
83
+ CommandExecuting2.findSimple = findSimple;
84
+ })(CommandExecuting || (CommandExecuting = {}));
85
+ var CommandRegistryFactory = "CommandRegistryFactory";
86
+ var CommandRegistry = class {
87
+ constructor() {
88
+ this._handlers = {};
89
+ this._commands = {};
90
+ this._commandExecutings = /* @__PURE__ */ new Set();
91
+ this.toUnregisterCommands = /* @__PURE__ */ new Map();
92
+ this.onDidExecuteCommandEmitter = new import_utils.Emitter();
93
+ this.onDidExecuteCommand = this.onDidExecuteCommandEmitter.event;
94
+ this.onWillExecuteCommandEmitter = new import_utils.Emitter();
95
+ this.onWillExecuteCommand = this.onWillExecuteCommandEmitter.event;
96
+ }
97
+ init() {
98
+ for (const contrib of this.contributions) {
99
+ contrib.registerCommands(this);
100
+ }
101
+ }
102
+ /**
103
+ * 当前所有 command
104
+ */
105
+ get commands() {
106
+ const commands = [];
107
+ for (const id of this.commandIds) {
108
+ const cmd = this.getCommand(id);
109
+ if (cmd) {
110
+ commands.push(cmd);
111
+ }
112
+ }
113
+ return commands;
114
+ }
115
+ /**
116
+ * 当前所有 commandid
117
+ */
118
+ get commandIds() {
119
+ return Object.keys(this._commands);
120
+ }
121
+ registerCommand(commandOrId, handler) {
122
+ const command = typeof commandOrId === "string" ? { id: commandOrId } : commandOrId;
123
+ if (this._commands[command.id]) {
124
+ console.warn(`A command ${command.id} is already registered.`);
125
+ return import_utils.Disposable.NULL;
126
+ }
127
+ const toDispose = new import_utils.DisposableCollection(this.doRegisterCommand(command));
128
+ if (handler) {
129
+ toDispose.push(this.registerHandler(command.id, handler));
130
+ }
131
+ this.toUnregisterCommands.set(command.id, toDispose);
132
+ toDispose.push(import_utils.Disposable.create(() => this.toUnregisterCommands.delete(command.id)));
133
+ return toDispose;
134
+ }
135
+ unregisterCommand(commandOrId) {
136
+ const id = Command.is(commandOrId) ? commandOrId.id : commandOrId;
137
+ const toUnregister = this.toUnregisterCommands.get(id);
138
+ if (toUnregister) {
139
+ toUnregister.dispose();
140
+ }
141
+ }
142
+ /**
143
+ * 注册 handler
144
+ */
145
+ registerHandler(commandId, handler) {
146
+ let handlers = this._handlers[commandId];
147
+ if (!handlers) {
148
+ this._handlers[commandId] = handlers = [];
149
+ }
150
+ handlers.unshift(handler);
151
+ return {
152
+ dispose: () => {
153
+ const idx = handlers.indexOf(handler);
154
+ if (idx >= 0) {
155
+ handlers.splice(idx, 1);
156
+ }
157
+ }
158
+ };
159
+ }
160
+ /**
161
+ * 预留 contextMenu 用,该 handler 是否可见
162
+ */
163
+ isVisible(command, ...args) {
164
+ return typeof this.getVisibleHandler(command, ...args) !== "undefined";
165
+ }
166
+ /**
167
+ * command 是否可用
168
+ */
169
+ isEnabled(command, ...args) {
170
+ return typeof this.getActiveHandler(command, ...args) !== "undefined";
171
+ }
172
+ /**
173
+ * 预留 contextMenu 用,该 handler 是否可以触发
174
+ */
175
+ isToggled(command, ...args) {
176
+ return typeof this.getToggledHandler(command, ...args) !== "undefined";
177
+ }
178
+ /**
179
+ * 执行 command,会先判断是否可以执行,不会重复执行
180
+ */
181
+ async executeCommand(commandId, ...args) {
182
+ const handler = this.getActiveHandler(commandId, ...args);
183
+ const execInfo = { id: commandId, args };
184
+ const simpleExecInfo = CommandExecuting.findSimple(this._commandExecutings, execInfo);
185
+ if (simpleExecInfo) {
186
+ return execInfo.promise;
187
+ }
188
+ if (handler) {
189
+ try {
190
+ this._commandExecutings.add(execInfo);
191
+ this.onWillExecuteCommandEmitter.fire({ commandId, args });
192
+ const promise = handler.execute(...args);
193
+ execInfo.promise = promise;
194
+ const result = await promise;
195
+ this.onDidExecuteCommandEmitter.fire({ commandId, args });
196
+ return result;
197
+ } finally {
198
+ this._commandExecutings.delete(execInfo);
199
+ }
200
+ }
201
+ }
202
+ getVisibleHandler(commandId, ...args) {
203
+ const handlers = this._handlers[commandId];
204
+ if (handlers) {
205
+ for (const handler of handlers) {
206
+ try {
207
+ if (!handler.isVisible || handler.isVisible(...args)) {
208
+ return handler;
209
+ }
210
+ } catch (error) {
211
+ console.error(error);
212
+ }
213
+ }
214
+ }
215
+ return void 0;
216
+ }
217
+ getActiveHandler(commandId, ...args) {
218
+ const handlers = this._handlers[commandId];
219
+ if (handlers) {
220
+ for (const handler of handlers) {
221
+ try {
222
+ if (!handler.isEnabled || handler.isEnabled(...args)) {
223
+ return handler;
224
+ }
225
+ } catch (error) {
226
+ console.error(error);
227
+ }
228
+ }
229
+ }
230
+ return void 0;
231
+ }
232
+ /**
233
+ * 获取 command 对应的所有 handler
234
+ */
235
+ getAllHandlers(commandId) {
236
+ const handlers = this._handlers[commandId];
237
+ return handlers ? handlers.slice() : [];
238
+ }
239
+ getToggledHandler(commandId, ...args) {
240
+ const handlers = this._handlers[commandId];
241
+ if (handlers) {
242
+ for (const handler of handlers) {
243
+ try {
244
+ if (handler.isToggled && handler.isToggled(...args)) {
245
+ return handler;
246
+ }
247
+ } catch (error) {
248
+ console.error(error);
249
+ }
250
+ }
251
+ }
252
+ return void 0;
253
+ }
254
+ /**
255
+ * 获取 command
256
+ */
257
+ getCommand(id) {
258
+ return this._commands[id];
259
+ }
260
+ doRegisterCommand(command) {
261
+ this._commands[command.id] = command;
262
+ return {
263
+ dispose: () => {
264
+ delete this._commands[command.id];
265
+ }
266
+ };
267
+ }
268
+ /**
269
+ * 更新 command
270
+ */
271
+ updateCommand(id, command) {
272
+ if (this._commands[id]) {
273
+ this._commands[id] = {
274
+ ...this._commands[id],
275
+ ...command
276
+ };
277
+ }
278
+ }
279
+ dispose() {
280
+ this.onWillExecuteCommandEmitter.dispose();
281
+ this.onDidExecuteCommandEmitter.dispose();
282
+ }
283
+ };
284
+ __decorateClass([
285
+ (0, import_inversify.multiInject)(CommandContribution),
286
+ (0, import_inversify.optional)()
287
+ ], CommandRegistry.prototype, "contributions", 2);
288
+ CommandRegistry = __decorateClass([
289
+ (0, import_inversify.injectable)()
290
+ ], CommandRegistry);
291
+
292
+ // src/command-service.ts
293
+ var CommandService = Symbol("CommandService");
294
+
295
+ // src/command-container-module.ts
296
+ var import_inversify2 = require("inversify");
297
+ var import_utils2 = require("@flowgram.ai/utils");
298
+ var CommandContainerModule = new import_inversify2.ContainerModule((bind) => {
299
+ (0, import_utils2.bindContributionProvider)(bind, CommandContribution);
300
+ bind(CommandRegistry).toSelf().inSingletonScope();
301
+ bind(CommandService).toService(CommandRegistry);
302
+ bind(CommandRegistryFactory).toFactory((ctx) => () => ctx.container.get(CommandRegistry));
303
+ });
304
+ // Annotate the CommonJS export names for ESM import in node:
305
+ 0 && (module.exports = {
306
+ Command,
307
+ CommandContainerModule,
308
+ CommandContribution,
309
+ CommandRegistry,
310
+ CommandRegistryFactory,
311
+ CommandService
312
+ });
313
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/command.ts","../src/command-service.ts","../src/command-container-module.ts"],"sourcesContent":["export {\n CommandContribution,\n type CommandHandler,\n CommandRegistry,\n Command,\n CommandRegistryFactory,\n} from './command';\nexport { CommandService } from './command-service';\nexport { CommandContainerModule } from './command-container-module';\n","import { injectable, multiInject, optional } from 'inversify';\nimport { Disposable, DisposableCollection, Emitter } from '@flowgram.ai/utils';\n\nimport { type CommandService } from './command-service';\n\nexport interface Command {\n /**\n * id,唯一 key\n */\n id: string;\n /**\n * 展示用 label\n */\n label?: string;\n /**\n * 在一些明确的场景下,部分只展示简短的 label 即可\n */\n shortLabel?: string;\n\n /**\n * 展示用 command icon\n */\n icon?: string | React.ReactNode | ((props: any) => React.ReactNode);\n /**\n * 暂不使用\n */\n category?: string;\n}\nexport namespace Command {\n export enum Default {\n ZOOM_IN = 'ZOOM_IN',\n ZOOM_OUT = 'ZOOM_OUT',\n DELETE = 'DELETE',\n COPY = 'COPY',\n PASTE = 'PASTE',\n UNDO = 'UNDO',\n REDO = 'REDO',\n VIEW_CLOSE_ALL_WIDGET = 'view.closeAllWidget',\n VIEW_CLOSE_CURRENT_WIDGET = 'view.closeCurrentWidget',\n VIEW_REOPEN_LAST_WIDGET = 'view.reopenLastWidget',\n VIEW_CLOSE_OTHER_WIDGET = 'view.closeOtherWidget',\n VIEW_CLOSE_BOTTOM_PANEL = 'view.closeBottomPannel',\n VIEW_OPEN_NEXT_TAB = 'view.openNextTab',\n VIEW_OEPN_LAST_TAB = 'view.openLastTab',\n VIEW_FULL_SCREEN = 'view.fullScreen',\n VIEW_SAVING_WIDGET_CLOSE_CONFIRM = 'view.savingWidgetCloseConfirm',\n VIEW_SHORTCUTS = 'view.shortcuts',\n VIEW_PREFERENCES = 'view.preferences',\n VIEW_LOG = 'view.log',\n VIEW_PROBLEMS = 'view.problems',\n }\n\n /**\n * 判断是否是 command\n */\n export function is(arg: Command | any): arg is Command {\n return !!arg && arg === Object(arg) && 'id' in arg;\n }\n}\n\nexport interface CommandHandler {\n /**\n * handler 执行函数\n */\n execute(...args: any[]): any;\n\n /**\n * 该 handler 是否可以执行\n */\n isEnabled?(...args: any[]): boolean;\n\n /**\n * 预留 contextMenu 用,该 handler 是否可见\n */\n isVisible?(...args: any[]): boolean;\n\n /**\n * 预留 contextMenu 用,该 handler 是否可以触发\n */\n isToggled?(...args: any[]): boolean;\n}\n\nexport interface CommandEvent {\n /**\n * commandId\n */\n commandId: string;\n /**\n * 参数\n */\n args: any[];\n}\nexport const CommandContribution = Symbol('CommandContribution');\n\nexport interface CommandContribution {\n /**\n * 注册 command\n */\n registerCommands(commands: CommandService): void;\n}\n\n/**\n * 当前正在运行的 command\n */\ninterface CommandExecuting {\n /**\n * commandid\n */\n id: string;\n /**\n * 参数\n */\n args: any[];\n /**\n * 正在进行的 promise\n */\n promise?: Promise<any>;\n}\n\nnamespace CommandExecuting {\n /**\n * 获取正在运行的 command 单个实例\n */\n export function findSimple(\n arrs: Set<CommandExecuting>,\n newCmd: CommandExecuting,\n ): CommandExecuting | undefined {\n for (const item of arrs.values()) {\n if (\n item.id === newCmd.id &&\n item.args.length === newCmd.args.length &&\n item.args.every((arg, index) => (newCmd as any)[index] === arg)\n ) {\n return item;\n }\n }\n }\n}\n\nexport const CommandRegistryFactory = 'CommandRegistryFactory';\n\n@injectable()\nexport class CommandRegistry implements CommandService {\n protected readonly _handlers: { [id: string]: CommandHandler[] } = {};\n\n protected readonly _commands: { [id: string]: Command } = {};\n\n protected readonly _commandExecutings = new Set<CommandExecuting>();\n\n protected readonly toUnregisterCommands = new Map<string, Disposable>();\n\n protected readonly onDidExecuteCommandEmitter = new Emitter<CommandEvent>();\n\n readonly onDidExecuteCommand = this.onDidExecuteCommandEmitter.event;\n\n protected readonly onWillExecuteCommandEmitter = new Emitter<CommandEvent>();\n\n readonly onWillExecuteCommand = this.onWillExecuteCommandEmitter.event;\n\n @multiInject(CommandContribution)\n @optional()\n protected readonly contributions: CommandContribution[];\n\n init() {\n for (const contrib of this.contributions) {\n contrib.registerCommands(this);\n }\n }\n\n /**\n * 当前所有 command\n */\n get commands(): Command[] {\n const commands: Command[] = [];\n for (const id of this.commandIds) {\n const cmd = this.getCommand(id);\n if (cmd) {\n commands.push(cmd);\n }\n }\n return commands;\n }\n\n /**\n * 当前所有 commandid\n */\n get commandIds(): string[] {\n return Object.keys(this._commands);\n }\n\n /**\n * registerCommand\n */\n registerCommand(id: string, handler?: CommandHandler): Disposable;\n\n registerCommand(command: Command, handler?: CommandHandler): Disposable;\n\n registerCommand(commandOrId: string | Command, handler?: CommandHandler): Disposable {\n const command: Command = typeof commandOrId === 'string' ? { id: commandOrId } : commandOrId;\n\n if (this._commands[command.id]) {\n console.warn(`A command ${command.id} is already registered.`);\n return Disposable.NULL;\n }\n const toDispose = new DisposableCollection(this.doRegisterCommand(command));\n if (handler) {\n toDispose.push(this.registerHandler(command.id, handler));\n }\n this.toUnregisterCommands.set(command.id, toDispose);\n toDispose.push(Disposable.create(() => this.toUnregisterCommands.delete(command.id)));\n return toDispose;\n }\n\n /**\n * unregisterCommand\n */\n unregisterCommand(command: Command): void;\n\n unregisterCommand(id: string): void;\n\n unregisterCommand(commandOrId: Command | string): void {\n const id = Command.is(commandOrId) ? commandOrId.id : commandOrId;\n const toUnregister = this.toUnregisterCommands.get(id);\n if (toUnregister) {\n toUnregister.dispose();\n }\n }\n\n /**\n * 注册 handler\n */\n registerHandler(commandId: string, handler: CommandHandler): Disposable {\n let handlers = this._handlers[commandId];\n if (!handlers) {\n this._handlers[commandId] = handlers = [];\n }\n handlers.unshift(handler);\n return {\n dispose: () => {\n const idx = handlers.indexOf(handler);\n if (idx >= 0) {\n handlers.splice(idx, 1);\n }\n },\n };\n }\n\n /**\n * 预留 contextMenu 用,该 handler 是否可见\n */\n isVisible(command: string, ...args: any[]): boolean {\n return typeof this.getVisibleHandler(command, ...args) !== 'undefined';\n }\n\n /**\n * command 是否可用\n */\n isEnabled(command: string, ...args: any[]): boolean {\n return typeof this.getActiveHandler(command, ...args) !== 'undefined';\n }\n\n /**\n * 预留 contextMenu 用,该 handler 是否可以触发\n */\n isToggled(command: string, ...args: any[]): boolean {\n return typeof this.getToggledHandler(command, ...args) !== 'undefined';\n }\n\n /**\n * 执行 command,会先判断是否可以执行,不会重复执行\n */\n async executeCommand<T>(commandId: string, ...args: any[]): Promise<T | undefined> {\n const handler = this.getActiveHandler(commandId, ...args);\n const execInfo: CommandExecuting = { id: commandId, args };\n const simpleExecInfo = CommandExecuting.findSimple(this._commandExecutings, execInfo);\n if (simpleExecInfo) {\n return execInfo.promise;\n }\n if (handler) {\n try {\n this._commandExecutings.add(execInfo);\n this.onWillExecuteCommandEmitter.fire({ commandId, args });\n const promise = handler.execute(...args);\n execInfo.promise = promise;\n const result = await promise;\n this.onDidExecuteCommandEmitter.fire({ commandId, args });\n return result;\n } finally {\n this._commandExecutings.delete(execInfo);\n }\n }\n }\n\n getVisibleHandler(commandId: string, ...args: any[]): CommandHandler | undefined {\n const handlers = this._handlers[commandId];\n if (handlers) {\n for (const handler of handlers) {\n try {\n if (!handler.isVisible || handler.isVisible(...args)) {\n return handler;\n }\n } catch (error) {\n console.error(error);\n }\n }\n }\n return undefined;\n }\n\n getActiveHandler(commandId: string, ...args: any[]): CommandHandler | undefined {\n const handlers = this._handlers[commandId];\n if (handlers) {\n for (const handler of handlers) {\n try {\n if (!handler.isEnabled || handler.isEnabled(...args)) {\n return handler;\n }\n } catch (error) {\n console.error(error);\n }\n }\n }\n return undefined;\n }\n\n /**\n * 获取 command 对应的所有 handler\n */\n getAllHandlers(commandId: string): CommandHandler[] {\n const handlers = this._handlers[commandId];\n return handlers ? handlers.slice() : [];\n }\n\n getToggledHandler(commandId: string, ...args: any[]): CommandHandler | undefined {\n const handlers = this._handlers[commandId];\n if (handlers) {\n for (const handler of handlers) {\n try {\n if (handler.isToggled && handler.isToggled(...args)) {\n return handler;\n }\n } catch (error) {\n console.error(error);\n }\n }\n }\n return undefined;\n }\n\n /**\n * 获取 command\n */\n getCommand(id: string): Command | undefined {\n return this._commands[id];\n }\n\n protected doRegisterCommand(command: Command): Disposable {\n this._commands[command.id] = command;\n return {\n dispose: () => {\n delete this._commands[command.id];\n },\n };\n }\n\n /**\n * 更新 command\n */\n public updateCommand(id: string, command: Partial<Omit<Command, 'id'>>) {\n if (this._commands[id]) {\n this._commands[id] = {\n ...this._commands[id],\n ...command,\n };\n }\n }\n\n dispose() {\n this.onWillExecuteCommandEmitter.dispose();\n this.onDidExecuteCommandEmitter.dispose();\n }\n}\n","import { type Disposable, type Event } from '@flowgram.ai/utils';\n\nimport { type CommandEvent } from './command';\n\nexport const CommandService = Symbol('CommandService');\n\n/**\n * command service 执行接口\n */\nexport interface CommandService extends Disposable {\n /**\n * command 事件执行前触发事件\n */\n readonly onWillExecuteCommand: Event<CommandEvent>;\n /**\n * command 事件执行完成后触发\n */\n readonly onDidExecuteCommand: Event<CommandEvent>;\n\n /**\n * 执行 command\n */\n executeCommand<T>(command: string, ...args: any[]): Promise<T | undefined>;\n}\n","import { ContainerModule } from 'inversify';\nimport { bindContributionProvider } from '@flowgram.ai/utils';\n\nimport { CommandService } from './command-service';\nimport { CommandRegistry, CommandRegistryFactory, CommandContribution } from './command';\n\nexport const CommandContainerModule = new ContainerModule(bind => {\n bindContributionProvider(bind, CommandContribution);\n bind(CommandRegistry).toSelf().inSingletonScope();\n bind(CommandService).toService(CommandRegistry);\n bind(CommandRegistryFactory).toFactory(ctx => () => ctx.container.get(CommandRegistry));\n});\n"],"mappings":"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","names":["Command","Default","CommandExecuting","import_inversify","import_utils"]}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@flowgram.ai/command",
3
+ "version": "0.1.0-alpha.2",
4
+ "homepage": "https://flowgram.ai/",
5
+ "repository": "https://github.com/bytedance/flowgram.ai",
6
+ "license": "MIT",
7
+ "exports": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/esm/index.js",
10
+ "require": "./dist/index.js"
11
+ },
12
+ "main": "./dist/index.js",
13
+ "module": "./dist/esm/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "dependencies": {
19
+ "inversify": "^6.0.1",
20
+ "reflect-metadata": "~0.2.2",
21
+ "@flowgram.ai/utils": "0.1.0-alpha.2"
22
+ },
23
+ "devDependencies": {
24
+ "@types/lodash": "^4.14.137",
25
+ "@types/node": "^18",
26
+ "@types/react": "^18",
27
+ "@types/react-dom": "^18",
28
+ "@vitest/coverage-v8": "^0.32.0",
29
+ "eslint": "^8.54.0",
30
+ "jsdom": "^22.1.0",
31
+ "tsup": "^8.0.1",
32
+ "typescript": "^5.0.4",
33
+ "vitest": "^0.34.6",
34
+ "@flowgram.ai/eslint-config": "0.1.0-alpha.2",
35
+ "@flowgram.ai/ts-config": "0.1.0-alpha.2"
36
+ },
37
+ "peerDependencies": {
38
+ "react": ">=17",
39
+ "react-dom": ">=17"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public",
43
+ "registry": "https://registry.npmjs.org/"
44
+ },
45
+ "scripts": {
46
+ "build": "npm run build:fast -- --dts-resolve",
47
+ "build:fast": "tsup src/index.ts --format cjs,esm --sourcemap --legacy-output",
48
+ "build:watch": "npm run build:fast -- --dts-resolve",
49
+ "clean": "rimraf dist",
50
+ "ts-check": "tsc --noEmit",
51
+ "watch": "npm run build:fast -- --dts-resolve --watch --ignore-watch dist"
52
+ }
53
+ }