@flowgram.ai/free-history-plugin 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.
package/dist/index.js ADDED
@@ -0,0 +1,794 @@
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 __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var __decorateClass = (decorators, target, key, kind) => {
21
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
22
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
23
+ if (decorator = decorators[i])
24
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
25
+ if (kind && result) __defProp(target, key, result);
26
+ return result;
27
+ };
28
+
29
+ // src/index.ts
30
+ var src_exports = {};
31
+ __export(src_exports, {
32
+ FreeHistoryConfig: () => FreeHistoryConfig,
33
+ FreeHistoryRegisters: () => FreeHistoryRegisters,
34
+ FreeOperationType: () => FreeOperationType,
35
+ createFreeHistoryPlugin: () => createFreeHistoryPlugin,
36
+ useUndoRedo: () => useUndoRedo
37
+ });
38
+ module.exports = __toCommonJS(src_exports);
39
+
40
+ // src/create-free-history-plugin.ts
41
+ var import_core4 = require("@flowgram.ai/core");
42
+ var import_history5 = require("@flowgram.ai/history");
43
+
44
+ // src/history-entity-manager.ts
45
+ var import_lodash = require("lodash");
46
+ var import_inversify = require("inversify");
47
+ var import_utils = require("@flowgram.ai/utils");
48
+ var HistoryEntityManager = class {
49
+ constructor() {
50
+ this._entityDataValues = /* @__PURE__ */ new Map();
51
+ this._toDispose = new import_utils.DisposableCollection();
52
+ }
53
+ addEntityData(entityData) {
54
+ this._entityDataValues.set(entityData, (0, import_lodash.cloneDeep)(entityData.toJSON()));
55
+ this._toDispose.push(
56
+ entityData.onWillChange((event) => {
57
+ const value = event.toJSON();
58
+ const oldValue = this._entityDataValues.get(entityData);
59
+ if ((0, import_lodash.isEqual)(value, oldValue)) {
60
+ return;
61
+ }
62
+ this._entityDataValues.set(entityData, (0, import_lodash.cloneDeep)(value));
63
+ })
64
+ );
65
+ }
66
+ getValue(entityData) {
67
+ return this._entityDataValues.get(entityData);
68
+ }
69
+ setValue(entityData, value) {
70
+ return this._entityDataValues.set(entityData, value);
71
+ }
72
+ dispose() {
73
+ this._entityDataValues.clear();
74
+ this._toDispose.dispose();
75
+ }
76
+ };
77
+ HistoryEntityManager = __decorateClass([
78
+ (0, import_inversify.injectable)()
79
+ ], HistoryEntityManager);
80
+
81
+ // src/handlers/drag-nodes-handler.ts
82
+ var import_inversify2 = require("inversify");
83
+ var import_core = require("@flowgram.ai/core");
84
+ var import_history = require("@flowgram.ai/history");
85
+
86
+ // src/types.ts
87
+ var FreeOperationType = /* @__PURE__ */ ((FreeOperationType2) => {
88
+ FreeOperationType2["addLine"] = "addLine";
89
+ FreeOperationType2["deleteLine"] = "deleteLine";
90
+ FreeOperationType2["moveNode"] = "moveNode";
91
+ FreeOperationType2["addNode"] = "addNode";
92
+ FreeOperationType2["deleteNode"] = "deleteNode";
93
+ FreeOperationType2["changeNodeData"] = "changeNodeData";
94
+ FreeOperationType2["resetLayout"] = "resetLayout";
95
+ FreeOperationType2["dragNodes"] = "dragNodes";
96
+ return FreeOperationType2;
97
+ })(FreeOperationType || {});
98
+
99
+ // src/handlers/drag-nodes-handler.ts
100
+ var DragNodesHandler = class {
101
+ handle(event) {
102
+ if (event.type === "onDragEnd" && !event.altKey) {
103
+ this._dragNode(event);
104
+ }
105
+ }
106
+ _dragNode(event) {
107
+ this._historyService.pushOperation(
108
+ {
109
+ type: "dragNodes" /* dragNodes */,
110
+ value: {
111
+ ids: event.nodes.map((node) => node.id),
112
+ value: event.nodes.map((node) => {
113
+ const { x, y } = node.getData(import_core.TransformData).position;
114
+ return {
115
+ x,
116
+ y
117
+ };
118
+ }),
119
+ oldValue: event.startPositions
120
+ }
121
+ },
122
+ { noApply: true }
123
+ );
124
+ }
125
+ };
126
+ __decorateClass([
127
+ (0, import_inversify2.inject)(import_history.HistoryService)
128
+ ], DragNodesHandler.prototype, "_historyService", 2);
129
+ DragNodesHandler = __decorateClass([
130
+ (0, import_inversify2.injectable)()
131
+ ], DragNodesHandler);
132
+
133
+ // src/handlers/change-node-data-handler.ts
134
+ var import_lodash2 = require("lodash");
135
+ var import_inversify4 = require("inversify");
136
+ var import_form_core = require("@flowgram.ai/form-core");
137
+ var import_free_layout_core = require("@flowgram.ai/free-layout-core");
138
+ var import_history2 = require("@flowgram.ai/history");
139
+
140
+ // src/free-history-config.ts
141
+ var import_inversify3 = require("inversify");
142
+ var FreeHistoryConfig = class {
143
+ constructor() {
144
+ this.enable = false;
145
+ this.nodeToJSON = (node) => node.toJSON();
146
+ this.getNodeLabelById = (id) => id;
147
+ this.getNodeLabel = (node) => node.id;
148
+ this.getBlockLabel = (node) => node.id;
149
+ this.getNodeURI = (id) => `node:${id}`;
150
+ this.getLineURI = (id) => `line:${id}`;
151
+ }
152
+ init(ctx, options) {
153
+ this.enable = !!options?.enable;
154
+ if (options.nodeToJSON) {
155
+ this.nodeToJSON = options.nodeToJSON(ctx);
156
+ }
157
+ if (options.getNodeLabelById) {
158
+ this.getNodeLabelById = options.getNodeLabelById(ctx);
159
+ }
160
+ if (options.getNodeLabel) {
161
+ this.getNodeLabel = options.getNodeLabel(ctx);
162
+ }
163
+ if (options.getBlockLabel) {
164
+ this.getBlockLabel = options.getBlockLabel(ctx);
165
+ }
166
+ if (options.getNodeURI) {
167
+ this.getNodeURI = options.getNodeURI(ctx);
168
+ }
169
+ if (options.getLineURI) {
170
+ this.getLineURI = options.getLineURI(ctx);
171
+ }
172
+ }
173
+ };
174
+ FreeHistoryConfig = __decorateClass([
175
+ (0, import_inversify3.injectable)()
176
+ ], FreeHistoryConfig);
177
+
178
+ // src/handlers/change-node-data-handler.ts
179
+ var ChangeNodeDataHandler = class {
180
+ handle(event) {
181
+ const { path, value, initialized, node } = event;
182
+ const formData = node.getData(import_form_core.FlowNodeFormData);
183
+ const oldValue = this._entityManager.getValue(formData);
184
+ const propPath = path.split("/").filter(Boolean).join(".");
185
+ const propOldValue = propPath ? (0, import_lodash2.get)(oldValue, propPath) : oldValue;
186
+ if ((0, import_lodash2.isEqual)(value, propOldValue)) {
187
+ return;
188
+ }
189
+ if (initialized) {
190
+ let operationPath = path;
191
+ let operationValue = (0, import_lodash2.cloneDeep)(value);
192
+ let operationOldValue = propOldValue;
193
+ if (path !== "/") {
194
+ const clonedOldValue = (0, import_lodash2.cloneDeep)(oldValue);
195
+ (0, import_lodash2.set)(clonedOldValue, propPath, value);
196
+ operationPath = path.split("/").filter(Boolean)[0];
197
+ operationValue = (0, import_lodash2.get)(clonedOldValue, operationPath);
198
+ operationOldValue = (0, import_lodash2.get)(oldValue, operationPath);
199
+ }
200
+ this._historyService.pushOperation(
201
+ {
202
+ type: "changeNodeData" /* changeNodeData */,
203
+ value: {
204
+ id: node.id,
205
+ path: operationPath,
206
+ value: operationValue,
207
+ oldValue: operationOldValue
208
+ },
209
+ uri: this._config.getNodeURI(node.id)
210
+ },
211
+ { noApply: true }
212
+ );
213
+ }
214
+ if (propPath) {
215
+ (0, import_lodash2.set)(oldValue, propPath, (0, import_lodash2.cloneDeep)(value));
216
+ } else {
217
+ this._entityManager.setValue(formData, (0, import_lodash2.cloneDeep)(value));
218
+ }
219
+ }
220
+ };
221
+ __decorateClass([
222
+ (0, import_inversify4.inject)(import_history2.HistoryService)
223
+ ], ChangeNodeDataHandler.prototype, "_historyService", 2);
224
+ __decorateClass([
225
+ (0, import_inversify4.inject)(import_free_layout_core.WorkflowDocument)
226
+ ], ChangeNodeDataHandler.prototype, "document", 2);
227
+ __decorateClass([
228
+ (0, import_inversify4.inject)(HistoryEntityManager)
229
+ ], ChangeNodeDataHandler.prototype, "_entityManager", 2);
230
+ __decorateClass([
231
+ (0, import_inversify4.inject)(FreeHistoryConfig)
232
+ ], ChangeNodeDataHandler.prototype, "_config", 2);
233
+ ChangeNodeDataHandler = __decorateClass([
234
+ (0, import_inversify4.injectable)()
235
+ ], ChangeNodeDataHandler);
236
+
237
+ // src/handlers/change-content-handler.ts
238
+ var import_inversify5 = require("inversify");
239
+ var import_history3 = require("@flowgram.ai/history");
240
+
241
+ // src/changes/delete-node-change.ts
242
+ var import_free_layout_core2 = require("@flowgram.ai/free-layout-core");
243
+ var deleteNodeChange = {
244
+ type: import_free_layout_core2.WorkflowContentChangeType.DELETE_NODE,
245
+ toOperation: async (event, ctx) => {
246
+ const config = ctx.get(FreeHistoryConfig);
247
+ const document = ctx.get(import_free_layout_core2.WorkflowDocument);
248
+ const node = event.entity;
249
+ const json = await document.toNodeJSON(node);
250
+ const parentID = node.parent?.id;
251
+ await (0, import_free_layout_core2.delay)(0);
252
+ return {
253
+ type: "deleteNode" /* deleteNode */,
254
+ value: {
255
+ node: json,
256
+ parentID
257
+ },
258
+ uri: config.getNodeURI(node.id)
259
+ };
260
+ }
261
+ };
262
+
263
+ // src/changes/delete-line-change.ts
264
+ var import_free_layout_core3 = require("@flowgram.ai/free-layout-core");
265
+ var deleteLineChange = {
266
+ type: import_free_layout_core3.WorkflowContentChangeType.DELETE_LINE,
267
+ toOperation: (event, ctx) => {
268
+ const config = ctx.get(FreeHistoryConfig);
269
+ const line = event.entity;
270
+ const value = {
271
+ from: line.info.from,
272
+ to: line.info.to || "",
273
+ fromPort: line.info.fromPort || "",
274
+ toPort: line.info.toPort || "",
275
+ id: line.id
276
+ };
277
+ return {
278
+ type: "deleteLine" /* deleteLine */,
279
+ value,
280
+ uri: config.getNodeURI(line.id)
281
+ };
282
+ }
283
+ };
284
+
285
+ // src/changes/add-node-change.ts
286
+ var import_free_layout_core4 = require("@flowgram.ai/free-layout-core");
287
+ var import_free_layout_core5 = require("@flowgram.ai/free-layout-core");
288
+ var addNodeChange = {
289
+ type: import_free_layout_core5.WorkflowContentChangeType.ADD_NODE,
290
+ toOperation: async (event, ctx) => {
291
+ const config = ctx.get(FreeHistoryConfig);
292
+ const document = ctx.get(import_free_layout_core4.WorkflowDocument);
293
+ const node = event.entity;
294
+ const parentID = node.parent?.id;
295
+ await (0, import_free_layout_core4.delay)(10);
296
+ const json = await document.toNodeJSON(node);
297
+ return {
298
+ type: "addNode" /* addNode */,
299
+ value: {
300
+ node: json,
301
+ parentID
302
+ },
303
+ uri: config.getNodeURI(node.id)
304
+ };
305
+ }
306
+ };
307
+
308
+ // src/changes/add-line-change.ts
309
+ var import_free_layout_core6 = require("@flowgram.ai/free-layout-core");
310
+ var addLineChange = {
311
+ type: import_free_layout_core6.WorkflowContentChangeType.ADD_LINE,
312
+ toOperation: (event, ctx) => {
313
+ const config = ctx.get(FreeHistoryConfig);
314
+ const line = event.entity;
315
+ const value = {
316
+ from: line.info.from,
317
+ to: line.info.to || "",
318
+ fromPort: line.info.fromPort || "",
319
+ toPort: line.info.toPort || "",
320
+ id: line.id
321
+ };
322
+ return {
323
+ type: "addLine" /* addLine */,
324
+ value,
325
+ uri: config.getLineURI(line.id)
326
+ };
327
+ }
328
+ };
329
+
330
+ // src/changes/index.ts
331
+ var changes_default = [addLineChange, deleteLineChange, addNodeChange, deleteNodeChange];
332
+
333
+ // src/handlers/change-content-handler.ts
334
+ var ChangeContentHandler = class {
335
+ async handle(event, ctx) {
336
+ if (!this._historyService.undoRedoService.canPush()) {
337
+ return;
338
+ }
339
+ const change = changes_default.find((c) => c.type === event.type);
340
+ if (!change) {
341
+ return;
342
+ }
343
+ const operation = await change.toOperation(event, ctx);
344
+ if (!operation) {
345
+ return;
346
+ }
347
+ this._historyService.pushOperation(operation, { noApply: true });
348
+ }
349
+ };
350
+ __decorateClass([
351
+ (0, import_inversify5.inject)(import_history3.HistoryService)
352
+ ], ChangeContentHandler.prototype, "_historyService", 2);
353
+ ChangeContentHandler = __decorateClass([
354
+ (0, import_inversify5.injectable)()
355
+ ], ChangeContentHandler);
356
+
357
+ // src/free-history-registers.ts
358
+ var import_inversify6 = require("inversify");
359
+
360
+ // src/operation-metas/reset-layout.ts
361
+ var import_free_layout_core7 = require("@flowgram.ai/free-layout-core");
362
+
363
+ // src/operation-metas/base.ts
364
+ var baseOperationMeta = {
365
+ shouldMerge: (_op, prev, element) => {
366
+ if (!prev) {
367
+ return false;
368
+ }
369
+ if (
370
+ // 合并500ms内的操作, 如删除节点会联动删除线条
371
+ Date.now() - element.getTimestamp() < 500
372
+ ) {
373
+ return true;
374
+ }
375
+ return false;
376
+ }
377
+ };
378
+
379
+ // src/operation-metas/reset-layout.ts
380
+ var resetLayoutOperationMeta = {
381
+ ...baseOperationMeta,
382
+ type: "resetLayout" /* resetLayout */,
383
+ inverse: (op) => ({
384
+ ...op,
385
+ value: {
386
+ ...op.value,
387
+ value: op.value.oldValue,
388
+ oldValue: op.value.value
389
+ }
390
+ }),
391
+ apply: async (operation, ctx) => {
392
+ const reset = ctx.get(import_free_layout_core7.WorkflowResetLayoutService);
393
+ await reset.layoutToPositions(operation.value.ids, operation.value.value);
394
+ },
395
+ shouldMerge: () => false
396
+ };
397
+
398
+ // src/operation-metas/drag-nodes.ts
399
+ var import_document = require("@flowgram.ai/document");
400
+ var import_core2 = require("@flowgram.ai/core");
401
+ var import_free_layout_core8 = require("@flowgram.ai/free-layout-core");
402
+ var dragNodesOperationMeta = {
403
+ ...baseOperationMeta,
404
+ type: "dragNodes" /* dragNodes */,
405
+ inverse: (op) => ({
406
+ ...op,
407
+ value: {
408
+ ...op.value,
409
+ value: op.value.oldValue,
410
+ oldValue: op.value.value
411
+ }
412
+ }),
413
+ apply: (operation, ctx) => {
414
+ operation.value.ids.forEach((id, index) => {
415
+ const document = ctx.get(import_free_layout_core8.WorkflowDocument);
416
+ const node = document.getNode(id);
417
+ if (!node) {
418
+ return;
419
+ }
420
+ const transform = node.getData(import_core2.TransformData);
421
+ const point = operation.value.value[index];
422
+ transform.update({
423
+ position: {
424
+ x: point.x,
425
+ y: point.y
426
+ }
427
+ });
428
+ if (node.collapsedChildren?.length > 0) {
429
+ node.collapsedChildren.forEach((childNode) => {
430
+ const childNodeTransformData = childNode.getData(import_document.FlowNodeTransformData);
431
+ childNodeTransformData.fireChange();
432
+ });
433
+ }
434
+ });
435
+ },
436
+ shouldMerge: () => false
437
+ };
438
+
439
+ // src/operation-metas/delete-node.ts
440
+ var import_free_layout_core9 = require("@flowgram.ai/free-layout-core");
441
+ var deleteNodeOperationMeta = {
442
+ ...baseOperationMeta,
443
+ type: "deleteNode" /* deleteNode */,
444
+ inverse: (op) => ({
445
+ ...op,
446
+ type: "addNode" /* addNode */
447
+ }),
448
+ apply: (operation, ctx) => {
449
+ const document = ctx.get(import_free_layout_core9.WorkflowDocument);
450
+ const node = document.getNode(operation.value.node.id);
451
+ if (node) {
452
+ node.dispose();
453
+ }
454
+ },
455
+ getLabel: (op, ctx) => {
456
+ const config = ctx.get(FreeHistoryConfig);
457
+ return `Delete Node ${config.getNodeLabel(op.value.node)}`;
458
+ },
459
+ getDescription: (op, ctx) => {
460
+ const config = ctx.get(FreeHistoryConfig);
461
+ let desc = `Delete Node ${config.getNodeLabel(op.value.node)}`;
462
+ if (op.value.node.meta?.position) {
463
+ desc += ` at ${op.value.node.meta.position.x},${op.value.node.meta.position.y}`;
464
+ }
465
+ return desc;
466
+ }
467
+ };
468
+
469
+ // src/operation-metas/delete-line.ts
470
+ var import_free_layout_core10 = require("@flowgram.ai/free-layout-core");
471
+ var deleteLineOperationMeta = {
472
+ ...baseOperationMeta,
473
+ type: "deleteLine" /* deleteLine */,
474
+ inverse: (op) => ({
475
+ ...op,
476
+ type: "addLine" /* addLine */
477
+ }),
478
+ apply: (operation, ctx) => {
479
+ const document = ctx.get(import_free_layout_core10.WorkflowDocument);
480
+ document.removeNode(operation.value.id);
481
+ },
482
+ getLabel: (op, ctx) => "Delete Line",
483
+ getDescription: (op, ctx) => {
484
+ const config = ctx.get(FreeHistoryConfig);
485
+ const { value } = op;
486
+ if (!value.from || !value.to) {
487
+ return "Delete Line";
488
+ }
489
+ const fromName = config.getNodeLabelById(value.from);
490
+ const toName = config.getNodeLabelById(value.to);
491
+ return `Delete Line from ${fromName} to ${toName}`;
492
+ }
493
+ };
494
+
495
+ // src/operation-metas/change-node-data.ts
496
+ var import_form_core2 = require("@flowgram.ai/form-core");
497
+ var import_free_layout_core11 = require("@flowgram.ai/free-layout-core");
498
+ var changeNodeDataOperationMeta = {
499
+ ...baseOperationMeta,
500
+ type: "changeNodeData" /* changeNodeData */,
501
+ inverse: (op) => ({
502
+ ...op,
503
+ value: {
504
+ ...op.value,
505
+ value: op.value.oldValue,
506
+ oldValue: op.value.value
507
+ }
508
+ }),
509
+ apply: (operation, ctx) => {
510
+ const document = ctx.get(import_free_layout_core11.WorkflowDocument);
511
+ const node = document.getNode(operation.value.id);
512
+ if (!node) {
513
+ return;
514
+ }
515
+ const formData = node.getData(import_form_core2.FlowNodeFormData);
516
+ if (!formData) {
517
+ return;
518
+ }
519
+ let { path } = operation.value;
520
+ if (path.endsWith("/") && path !== "/") {
521
+ path = path.slice(0, -1);
522
+ }
523
+ if (!path.startsWith("/")) {
524
+ path = `/${path}`;
525
+ }
526
+ const formItem = formData.formModel.getFormItemByPath(path);
527
+ if (!formItem) {
528
+ return;
529
+ }
530
+ formItem.value = operation.value.value;
531
+ },
532
+ shouldMerge: (op, prev, element) => {
533
+ if (!prev) {
534
+ return false;
535
+ }
536
+ if (Date.now() - element.getTimestamp() < 500) {
537
+ if (op.type === prev.type && // 相同类型
538
+ op.value.id === prev.value.id && // 相同节点
539
+ op.value?.path === prev.value?.path) {
540
+ return {
541
+ type: op.type,
542
+ value: {
543
+ ...op.value,
544
+ value: op.value.value,
545
+ oldValue: prev.value.oldValue
546
+ }
547
+ };
548
+ }
549
+ return true;
550
+ }
551
+ return false;
552
+ }
553
+ };
554
+
555
+ // src/operation-metas/add-node.ts
556
+ var import_lodash3 = require("lodash");
557
+ var import_free_layout_core12 = require("@flowgram.ai/free-layout-core");
558
+ var addNodeOperationMeta = {
559
+ ...baseOperationMeta,
560
+ type: "addNode" /* addNode */,
561
+ inverse: (op) => ({
562
+ ...op,
563
+ type: "deleteNode" /* deleteNode */
564
+ }),
565
+ apply: async (operation, ctx) => {
566
+ const document = ctx.get(import_free_layout_core12.WorkflowDocument);
567
+ await document.createWorkflowNode(
568
+ (0, import_lodash3.cloneDeep)(operation.value.node),
569
+ false,
570
+ operation.value.parentID
571
+ );
572
+ },
573
+ getLabel: (op, ctx) => {
574
+ const config = ctx.get(FreeHistoryConfig);
575
+ return `Create Node ${config.getNodeLabel(op.value.node)}`;
576
+ },
577
+ getDescription: (op, ctx) => {
578
+ const config = ctx.get(FreeHistoryConfig);
579
+ let desc = `Create Node ${config.getNodeLabel(op.value.node)}`;
580
+ if (op.value.node.meta?.position) {
581
+ desc += ` at ${op.value.node.meta.position.x},${op.value.node.meta.position.y}`;
582
+ }
583
+ return desc;
584
+ }
585
+ };
586
+
587
+ // src/operation-metas/add-line.ts
588
+ var import_free_layout_core13 = require("@flowgram.ai/free-layout-core");
589
+ var addLineOperationMeta = {
590
+ ...baseOperationMeta,
591
+ type: "addLine" /* addLine */,
592
+ inverse: (op) => ({
593
+ ...op,
594
+ type: "deleteLine" /* deleteLine */
595
+ }),
596
+ apply: (operation, ctx) => {
597
+ const linesManager = ctx.get(import_free_layout_core13.WorkflowLinesManager);
598
+ linesManager.createLine({
599
+ ...operation.value,
600
+ key: operation.value.id
601
+ });
602
+ },
603
+ getLabel: (op, ctx) => "Create Line",
604
+ getDescription: (op, ctx) => {
605
+ const config = ctx.get(FreeHistoryConfig);
606
+ const { value } = op;
607
+ if (!value.from || !value.to) {
608
+ return "Create Line";
609
+ }
610
+ const fromName = config.getNodeLabelById(value.from);
611
+ const toName = config.getNodeLabelById(value.to);
612
+ return `Create Line from ${fromName} to ${toName}`;
613
+ }
614
+ };
615
+
616
+ // src/operation-metas/index.ts
617
+ var operationMetas = [
618
+ addLineOperationMeta,
619
+ deleteLineOperationMeta,
620
+ addNodeOperationMeta,
621
+ deleteNodeOperationMeta,
622
+ changeNodeDataOperationMeta,
623
+ resetLayoutOperationMeta,
624
+ dragNodesOperationMeta
625
+ ];
626
+
627
+ // src/free-history-registers.ts
628
+ var FreeHistoryRegisters = class {
629
+ registerOperationMeta(operationRegistry) {
630
+ operationMetas.forEach((operationMeta) => {
631
+ operationRegistry.registerOperationMeta(operationMeta);
632
+ });
633
+ }
634
+ };
635
+ FreeHistoryRegisters = __decorateClass([
636
+ (0, import_inversify6.injectable)()
637
+ ], FreeHistoryRegisters);
638
+
639
+ // src/free-history-manager.ts
640
+ var import_lodash4 = require("lodash");
641
+ var import_inversify7 = require("inversify");
642
+ var import_utils2 = require("@flowgram.ai/utils");
643
+ var import_history4 = require("@flowgram.ai/history");
644
+ var import_free_layout_core14 = require("@flowgram.ai/free-layout-core");
645
+ var import_form_core3 = require("@flowgram.ai/form-core");
646
+ var import_form_core4 = require("@flowgram.ai/form-core");
647
+ var import_core3 = require("@flowgram.ai/core");
648
+ var FreeHistoryManager = class {
649
+ constructor() {
650
+ this._toDispose = new import_utils2.DisposableCollection();
651
+ }
652
+ onInit(ctx, opts) {
653
+ const document = ctx.get(import_free_layout_core14.WorkflowDocument);
654
+ const historyService = ctx.get(import_history4.HistoryService);
655
+ const dragService = ctx.get(import_free_layout_core14.WorkflowDragService);
656
+ const resetLayoutService = ctx.get(import_free_layout_core14.WorkflowResetLayoutService);
657
+ if (opts?.limit) {
658
+ historyService.limit(opts.limit);
659
+ }
660
+ historyService.context.source = ctx;
661
+ this._toDispose.pushAll([
662
+ dragService.onNodesDrag(async (event) => {
663
+ if (event.type !== "onDragEnd") {
664
+ return;
665
+ }
666
+ this._dragNodesHandler.handle(event);
667
+ }),
668
+ document.onNodeCreate(({ node, data }) => {
669
+ const positionData = node.getData(import_core3.PositionData);
670
+ if (positionData) {
671
+ this._entityManager.addEntityData(positionData);
672
+ }
673
+ }),
674
+ this._formManager.onFormModelWillInit(({ model, data }) => {
675
+ const node = model.flowNodeEntity;
676
+ const formData = node.getData(import_form_core3.FlowNodeFormData);
677
+ if (formData) {
678
+ this._entityManager.setValue(formData, (0, import_lodash4.cloneDeep)(data));
679
+ this._toDispose.push(
680
+ formData.onDetailChange((event) => {
681
+ this._changeNodeDataHandler.handle({
682
+ ...event,
683
+ node
684
+ });
685
+ })
686
+ );
687
+ }
688
+ }),
689
+ document.onContentChange(async (event) => {
690
+ await this._changeContentHandler.handle(event, ctx);
691
+ }),
692
+ document.onReload((_event) => {
693
+ historyService.clear();
694
+ }),
695
+ resetLayoutService.onResetLayout((event) => {
696
+ historyService.pushOperation(
697
+ {
698
+ type: "resetLayout" /* resetLayout */,
699
+ value: {
700
+ ids: event.nodeIds,
701
+ value: event.positionMap,
702
+ oldValue: event.oldPositionMap
703
+ }
704
+ },
705
+ { noApply: true }
706
+ );
707
+ })
708
+ ]);
709
+ }
710
+ dispose() {
711
+ this._entityManager.dispose();
712
+ this._toDispose.dispose();
713
+ }
714
+ };
715
+ __decorateClass([
716
+ (0, import_inversify7.inject)(DragNodesHandler)
717
+ ], FreeHistoryManager.prototype, "_dragNodesHandler", 2);
718
+ __decorateClass([
719
+ (0, import_inversify7.inject)(ChangeNodeDataHandler)
720
+ ], FreeHistoryManager.prototype, "_changeNodeDataHandler", 2);
721
+ __decorateClass([
722
+ (0, import_inversify7.inject)(ChangeContentHandler)
723
+ ], FreeHistoryManager.prototype, "_changeContentHandler", 2);
724
+ __decorateClass([
725
+ (0, import_inversify7.inject)(HistoryEntityManager)
726
+ ], FreeHistoryManager.prototype, "_entityManager", 2);
727
+ __decorateClass([
728
+ (0, import_inversify7.inject)(import_form_core4.FormManager)
729
+ ], FreeHistoryManager.prototype, "_formManager", 2);
730
+ FreeHistoryManager = __decorateClass([
731
+ (0, import_inversify7.injectable)()
732
+ ], FreeHistoryManager);
733
+
734
+ // src/create-free-history-plugin.ts
735
+ var createFreeHistoryPlugin = (0, import_core4.definePluginCreator)({
736
+ onBind: ({ bind }) => {
737
+ (0, import_core4.bindContributions)(bind, FreeHistoryRegisters, [import_history5.OperationContribution]);
738
+ bind(FreeHistoryConfig).toSelf().inSingletonScope();
739
+ bind(FreeHistoryManager).toSelf().inSingletonScope();
740
+ bind(HistoryEntityManager).toSelf().inSingletonScope();
741
+ bind(DragNodesHandler).toSelf().inSingletonScope();
742
+ bind(ChangeNodeDataHandler).toSelf().inSingletonScope();
743
+ bind(ChangeContentHandler).toSelf().inSingletonScope();
744
+ },
745
+ onInit(ctx, opts) {
746
+ ctx.get(FreeHistoryConfig).init(ctx, opts);
747
+ if (!opts.enable) {
748
+ return;
749
+ }
750
+ ctx.get(FreeHistoryManager).onInit(ctx, opts);
751
+ },
752
+ onDispose(ctx) {
753
+ ctx.get(HistoryEntityManager).dispose();
754
+ },
755
+ containerModules: [import_history5.HistoryContainerModule]
756
+ });
757
+
758
+ // src/index.ts
759
+ __reExport(src_exports, require("@flowgram.ai/history"), module.exports);
760
+
761
+ // src/hooks/use-undo-redo.tsx
762
+ var import_react = require("react");
763
+ var import_core5 = require("@flowgram.ai/core");
764
+ var import_history6 = require("@flowgram.ai/history");
765
+ function useUndoRedo() {
766
+ const historyService = (0, import_core5.useService)(import_history6.HistoryService);
767
+ const [canUndo, setCanUndo] = (0, import_react.useState)(false);
768
+ const [canRedo, setCanRedo] = (0, import_react.useState)(false);
769
+ (0, import_react.useEffect)(() => {
770
+ const toDispose = historyService.undoRedoService.onChange(() => {
771
+ setCanUndo(historyService.canUndo());
772
+ setCanRedo(historyService.canRedo());
773
+ });
774
+ return () => {
775
+ toDispose.dispose();
776
+ };
777
+ }, []);
778
+ return {
779
+ canUndo,
780
+ canRedo,
781
+ undo: () => historyService.undo(),
782
+ redo: () => historyService.redo()
783
+ };
784
+ }
785
+ // Annotate the CommonJS export names for ESM import in node:
786
+ 0 && (module.exports = {
787
+ FreeHistoryConfig,
788
+ FreeHistoryRegisters,
789
+ FreeOperationType,
790
+ createFreeHistoryPlugin,
791
+ useUndoRedo,
792
+ ...require("@flowgram.ai/history")
793
+ });
794
+ //# sourceMappingURL=index.js.map