@flowgram-vue/history-node-plugin 0.2.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 ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
4
+ Copyright (c) 2026 Crayon
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/dist/index.cjs ADDED
@@ -0,0 +1,127 @@
1
+ 'use strict';
2
+
3
+ var document = require('@flowgram-vue/document');
4
+ var core = require('@flowgram-vue/core');
5
+ var history = require('@flowgram-vue/history');
6
+ var lodashEs = require('lodash-es');
7
+ var node = require('@flowgram-vue/node');
8
+ var formCore = require('@flowgram-vue/form-core');
9
+ var inversify = require('inversify');
10
+
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __decorateClass = (decorators, target, key, kind) => {
13
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
14
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
15
+ if (decorator = decorators[i])
16
+ result = (decorator(result)) || result;
17
+ return result;
18
+ };
19
+ function getFormModelV2(node$1) {
20
+ if (!node$1) {
21
+ return void 0;
22
+ }
23
+ const formModel = node$1?.getData(formCore.FlowNodeFormData)?.getFormModel();
24
+ if (!formModel || !node.isFormModelV2(formModel)) {
25
+ return void 0;
26
+ }
27
+ return formModel;
28
+ }
29
+ function shouldChangeFormValuesMerge(op, prev, element) {
30
+ if (!prev) {
31
+ return false;
32
+ }
33
+ if (Date.now() - element.getTimestamp() < 500) {
34
+ if (op.type === prev.type && // 相同类型
35
+ op.value?.id === prev.value?.id && // 相同节点
36
+ op.value?.path === prev.value?.path) {
37
+ return {
38
+ type: op.type,
39
+ value: {
40
+ ...op.value,
41
+ value: op.value?.value,
42
+ oldValue: prev.value?.oldValue
43
+ }
44
+ };
45
+ }
46
+ return true;
47
+ }
48
+ return false;
49
+ }
50
+ function attachFormValuesChange(formModel, node, historyService) {
51
+ formModel.onFormValuesChange((event) => {
52
+ historyService.pushOperation(
53
+ {
54
+ type: "changeFormValues" /* changeFormValues */,
55
+ value: {
56
+ id: node.id,
57
+ path: event.name,
58
+ value: event.name ? lodashEs.get(event.values, event.name) : event.values,
59
+ oldValue: event.name ? lodashEs.get(event.prevValues, event.name) : event.prevValues
60
+ }
61
+ },
62
+ { noApply: true }
63
+ );
64
+ });
65
+ }
66
+ var changeFormValueOperationMeta = {
67
+ type: "changeFormValues" /* changeFormValues */,
68
+ inverse: (op) => ({
69
+ ...op,
70
+ value: {
71
+ ...op.value,
72
+ value: op.value.oldValue,
73
+ oldValue: op.value.value
74
+ }
75
+ }),
76
+ apply: ({ value: { value, path, id } }, ctx) => {
77
+ const document$1 = ctx.get(document.FlowDocument);
78
+ const formModel = getFormModelV2(document$1.getNode(id));
79
+ if (!formModel) {
80
+ return;
81
+ }
82
+ if (!path) {
83
+ formModel.updateFormValues(value);
84
+ } else {
85
+ formModel.setValueIn(path, value);
86
+ }
87
+ },
88
+ shouldMerge: shouldChangeFormValuesMerge
89
+ };
90
+
91
+ // src/operation-metas/index.ts
92
+ var operationMetas = [changeFormValueOperationMeta];
93
+
94
+ // src/history-node-registers.ts
95
+ var HistoryNodeRegisters = class {
96
+ registerOperationMeta(operationRegistry) {
97
+ operationMetas.forEach((operationMeta) => {
98
+ operationRegistry.registerOperationMeta(operationMeta);
99
+ });
100
+ }
101
+ };
102
+ HistoryNodeRegisters = __decorateClass([
103
+ inversify.injectable()
104
+ ], HistoryNodeRegisters);
105
+
106
+ // src/create-history-node-plugin.ts
107
+ var createHistoryNodePlugin = core.definePluginCreator({
108
+ onBind: ({ bind }) => {
109
+ core.bindContributions(bind, HistoryNodeRegisters, [history.OperationContribution]);
110
+ },
111
+ onInit: (ctx, _opts) => {
112
+ const document$1 = ctx.get(document.FlowDocument);
113
+ const historyService = ctx.get(history.HistoryService);
114
+ document$1.onNodeCreate(({ node }) => {
115
+ const formModel = getFormModelV2(node);
116
+ if (!formModel) {
117
+ return;
118
+ }
119
+ attachFormValuesChange(formModel, node, historyService);
120
+ });
121
+ },
122
+ containerModules: [history.HistoryContainerModule]
123
+ });
124
+
125
+ exports.createHistoryNodePlugin = createHistoryNodePlugin;
126
+ //# sourceMappingURL=index.cjs.map
127
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/index.ts","../src/operation-metas/change-form-values.ts","../src/operation-metas/index.ts","../src/history-node-registers.ts","../src/create-history-node-plugin.ts"],"names":["node","FlowNodeFormData","isFormModelV2","get","document","FlowDocument","injectable","definePluginCreator","bindContributions","OperationContribution","HistoryService","HistoryContainerModule"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { get } from 'lodash-es';\nimport { FormModelV2, isFormModelV2 } from '@flowgram-vue/node';\nimport { HistoryService, Operation } from '@flowgram-vue/history';\nimport { StackOperation } from '@flowgram-vue/history';\nimport { FlowNodeFormData } from '@flowgram-vue/form-core';\nimport { FlowNodeEntity } from '@flowgram-vue/document';\n\nimport { ChangeFormValuesOperationValue, NodeOperationType } from '../types';\n\n/**\n * 获取v2版本的formModel\n * @param node 节点\n * @returns\n */\nexport function getFormModelV2(node: FlowNodeEntity | undefined): FormModelV2 | undefined {\n if (!node) {\n return undefined;\n }\n\n const formModel = node?.getData(FlowNodeFormData)?.getFormModel<FormModelV2>();\n\n if (!formModel || !isFormModelV2(formModel)) {\n return undefined;\n }\n\n return formModel;\n}\n\n/**\n * 表单合并策略\n * @param op 操作\n * @param prev 上一个操作\n * @param element 操作栈元素\n * @returns\n */\nexport function shouldChangeFormValuesMerge(\n op: Operation<ChangeFormValuesOperationValue | undefined>,\n prev: Operation<ChangeFormValuesOperationValue | undefined>,\n element: StackOperation\n) {\n if (!prev) {\n return false;\n }\n\n if (Date.now() - element.getTimestamp() < 500) {\n if (\n op.type === prev.type && // 相同类型\n op.value?.id === prev.value?.id && // 相同节点\n op.value?.path === prev.value?.path // 相同路径\n ) {\n return {\n type: op.type,\n value: {\n ...op.value,\n value: op.value?.value,\n oldValue: prev.value?.oldValue,\n },\n };\n }\n return true;\n }\n return false;\n}\n\n/**\n * 监听表单值变化\n * @param formModel 表单模型\n * @param node 节点\n * @param historyService 历史服务\n */\nexport function attachFormValuesChange(\n formModel: FormModelV2,\n node: FlowNodeEntity,\n historyService: HistoryService\n) {\n formModel.onFormValuesChange((event) => {\n historyService.pushOperation(\n {\n type: NodeOperationType.changeFormValues,\n value: {\n id: node.id,\n path: event.name,\n value: event.name ? get(event.values, event.name) : event.values,\n oldValue: event.name ? get(event.prevValues, event.name) : event.prevValues,\n },\n },\n { noApply: true }\n );\n });\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { type OperationMeta } from '@flowgram-vue/history';\nimport { FlowDocument } from '@flowgram-vue/document';\nimport { type PluginContext } from '@flowgram-vue/core';\n\nimport { getFormModelV2, shouldChangeFormValuesMerge } from '../utils';\nimport { ChangeFormValuesOperationValue, NodeOperationType } from '../types';\n\n/**\n * 表单修改操作\n */\nexport const changeFormValueOperationMeta: OperationMeta<\n ChangeFormValuesOperationValue,\n PluginContext,\n void\n> = {\n type: NodeOperationType.changeFormValues,\n inverse: (op) => ({\n ...op,\n value: {\n ...op.value,\n value: op.value.oldValue,\n oldValue: op.value.value,\n },\n }),\n apply: ({ value: { value, path, id } }, ctx: PluginContext) => {\n const document = ctx.get<FlowDocument>(FlowDocument);\n const formModel = getFormModelV2(document.getNode(id));\n\n if (!formModel) {\n return;\n }\n if (!path) {\n formModel.updateFormValues(value);\n } else {\n formModel.setValueIn(path, value);\n }\n },\n shouldMerge: shouldChangeFormValuesMerge as OperationMeta['shouldMerge'],\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { OperationMeta } from '@flowgram-vue/history';\n\nimport { changeFormValueOperationMeta } from './change-form-values';\n\nexport const operationMetas: OperationMeta[] = [changeFormValueOperationMeta];\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { injectable } from 'inversify';\nimport { type OperationContribution, type OperationRegistry } from '@flowgram-vue/history';\n\nimport { operationMetas } from './operation-metas';\n\n/**\n * 表单历史操作\n */\n@injectable()\nexport class HistoryNodeRegisters implements OperationContribution {\n registerOperationMeta(operationRegistry: OperationRegistry): void {\n operationMetas.forEach(operationMeta => {\n operationRegistry.registerOperationMeta(operationMeta);\n });\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowDocument } from '@flowgram-vue/document';\nimport { bindContributions, definePluginCreator } from '@flowgram-vue/core';\nimport { HistoryContainerModule, HistoryService, OperationContribution } from '@flowgram-vue/history';\n\nimport { attachFormValuesChange, getFormModelV2 } from './utils';\nimport { HistoryNodeRegisters } from './history-node-registers';\n\n/**\n * 表单历史插件\n */\nexport const createHistoryNodePlugin = definePluginCreator({\n onBind: ({ bind }) => {\n bindContributions(bind, HistoryNodeRegisters, [OperationContribution]);\n },\n onInit: (ctx, _opts) => {\n const document = ctx.get<FlowDocument>(FlowDocument);\n const historyService = ctx.get<HistoryService>(HistoryService);\n\n document.onNodeCreate(({ node }) => {\n const formModel = getFormModelV2(node);\n\n if (!formModel) {\n return;\n }\n\n attachFormValuesChange(formModel, node, historyService);\n });\n },\n containerModules: [HistoryContainerModule],\n});\n"]}
@@ -0,0 +1,12 @@
1
+ import * as _flowgram_vue_core from '@flowgram-vue/core';
2
+
3
+ /**
4
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
5
+ * SPDX-License-Identifier: MIT
6
+ */
7
+ /**
8
+ * 表单历史插件
9
+ */
10
+ declare const createHistoryNodePlugin: _flowgram_vue_core.PluginCreator<unknown>;
11
+
12
+ export { createHistoryNodePlugin };
package/dist/index.js ADDED
@@ -0,0 +1,125 @@
1
+ import { FlowDocument } from '@flowgram-vue/document';
2
+ import { definePluginCreator, bindContributions } from '@flowgram-vue/core';
3
+ import { HistoryContainerModule, HistoryService, OperationContribution } from '@flowgram-vue/history';
4
+ import { get } from 'lodash-es';
5
+ import { isFormModelV2 } from '@flowgram-vue/node';
6
+ import { FlowNodeFormData } from '@flowgram-vue/form-core';
7
+ import { injectable } from 'inversify';
8
+
9
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
+ var __decorateClass = (decorators, target, key, kind) => {
11
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
12
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
13
+ if (decorator = decorators[i])
14
+ result = (decorator(result)) || result;
15
+ return result;
16
+ };
17
+ function getFormModelV2(node) {
18
+ if (!node) {
19
+ return void 0;
20
+ }
21
+ const formModel = node?.getData(FlowNodeFormData)?.getFormModel();
22
+ if (!formModel || !isFormModelV2(formModel)) {
23
+ return void 0;
24
+ }
25
+ return formModel;
26
+ }
27
+ function shouldChangeFormValuesMerge(op, prev, element) {
28
+ if (!prev) {
29
+ return false;
30
+ }
31
+ if (Date.now() - element.getTimestamp() < 500) {
32
+ if (op.type === prev.type && // 相同类型
33
+ op.value?.id === prev.value?.id && // 相同节点
34
+ op.value?.path === prev.value?.path) {
35
+ return {
36
+ type: op.type,
37
+ value: {
38
+ ...op.value,
39
+ value: op.value?.value,
40
+ oldValue: prev.value?.oldValue
41
+ }
42
+ };
43
+ }
44
+ return true;
45
+ }
46
+ return false;
47
+ }
48
+ function attachFormValuesChange(formModel, node, historyService) {
49
+ formModel.onFormValuesChange((event) => {
50
+ historyService.pushOperation(
51
+ {
52
+ type: "changeFormValues" /* changeFormValues */,
53
+ value: {
54
+ id: node.id,
55
+ path: event.name,
56
+ value: event.name ? get(event.values, event.name) : event.values,
57
+ oldValue: event.name ? get(event.prevValues, event.name) : event.prevValues
58
+ }
59
+ },
60
+ { noApply: true }
61
+ );
62
+ });
63
+ }
64
+ var changeFormValueOperationMeta = {
65
+ type: "changeFormValues" /* changeFormValues */,
66
+ inverse: (op) => ({
67
+ ...op,
68
+ value: {
69
+ ...op.value,
70
+ value: op.value.oldValue,
71
+ oldValue: op.value.value
72
+ }
73
+ }),
74
+ apply: ({ value: { value, path, id } }, ctx) => {
75
+ const document = ctx.get(FlowDocument);
76
+ const formModel = getFormModelV2(document.getNode(id));
77
+ if (!formModel) {
78
+ return;
79
+ }
80
+ if (!path) {
81
+ formModel.updateFormValues(value);
82
+ } else {
83
+ formModel.setValueIn(path, value);
84
+ }
85
+ },
86
+ shouldMerge: shouldChangeFormValuesMerge
87
+ };
88
+
89
+ // src/operation-metas/index.ts
90
+ var operationMetas = [changeFormValueOperationMeta];
91
+
92
+ // src/history-node-registers.ts
93
+ var HistoryNodeRegisters = class {
94
+ registerOperationMeta(operationRegistry) {
95
+ operationMetas.forEach((operationMeta) => {
96
+ operationRegistry.registerOperationMeta(operationMeta);
97
+ });
98
+ }
99
+ };
100
+ HistoryNodeRegisters = __decorateClass([
101
+ injectable()
102
+ ], HistoryNodeRegisters);
103
+
104
+ // src/create-history-node-plugin.ts
105
+ var createHistoryNodePlugin = definePluginCreator({
106
+ onBind: ({ bind }) => {
107
+ bindContributions(bind, HistoryNodeRegisters, [OperationContribution]);
108
+ },
109
+ onInit: (ctx, _opts) => {
110
+ const document = ctx.get(FlowDocument);
111
+ const historyService = ctx.get(HistoryService);
112
+ document.onNodeCreate(({ node }) => {
113
+ const formModel = getFormModelV2(node);
114
+ if (!formModel) {
115
+ return;
116
+ }
117
+ attachFormValuesChange(formModel, node, historyService);
118
+ });
119
+ },
120
+ containerModules: [HistoryContainerModule]
121
+ });
122
+
123
+ export { createHistoryNodePlugin };
124
+ //# sourceMappingURL=index.js.map
125
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/index.ts","../src/operation-metas/change-form-values.ts","../src/operation-metas/index.ts","../src/history-node-registers.ts","../src/create-history-node-plugin.ts"],"names":["FlowDocument"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { get } from 'lodash-es';\nimport { FormModelV2, isFormModelV2 } from '@flowgram-vue/node';\nimport { HistoryService, Operation } from '@flowgram-vue/history';\nimport { StackOperation } from '@flowgram-vue/history';\nimport { FlowNodeFormData } from '@flowgram-vue/form-core';\nimport { FlowNodeEntity } from '@flowgram-vue/document';\n\nimport { ChangeFormValuesOperationValue, NodeOperationType } from '../types';\n\n/**\n * 获取v2版本的formModel\n * @param node 节点\n * @returns\n */\nexport function getFormModelV2(node: FlowNodeEntity | undefined): FormModelV2 | undefined {\n if (!node) {\n return undefined;\n }\n\n const formModel = node?.getData(FlowNodeFormData)?.getFormModel<FormModelV2>();\n\n if (!formModel || !isFormModelV2(formModel)) {\n return undefined;\n }\n\n return formModel;\n}\n\n/**\n * 表单合并策略\n * @param op 操作\n * @param prev 上一个操作\n * @param element 操作栈元素\n * @returns\n */\nexport function shouldChangeFormValuesMerge(\n op: Operation<ChangeFormValuesOperationValue | undefined>,\n prev: Operation<ChangeFormValuesOperationValue | undefined>,\n element: StackOperation\n) {\n if (!prev) {\n return false;\n }\n\n if (Date.now() - element.getTimestamp() < 500) {\n if (\n op.type === prev.type && // 相同类型\n op.value?.id === prev.value?.id && // 相同节点\n op.value?.path === prev.value?.path // 相同路径\n ) {\n return {\n type: op.type,\n value: {\n ...op.value,\n value: op.value?.value,\n oldValue: prev.value?.oldValue,\n },\n };\n }\n return true;\n }\n return false;\n}\n\n/**\n * 监听表单值变化\n * @param formModel 表单模型\n * @param node 节点\n * @param historyService 历史服务\n */\nexport function attachFormValuesChange(\n formModel: FormModelV2,\n node: FlowNodeEntity,\n historyService: HistoryService\n) {\n formModel.onFormValuesChange((event) => {\n historyService.pushOperation(\n {\n type: NodeOperationType.changeFormValues,\n value: {\n id: node.id,\n path: event.name,\n value: event.name ? get(event.values, event.name) : event.values,\n oldValue: event.name ? get(event.prevValues, event.name) : event.prevValues,\n },\n },\n { noApply: true }\n );\n });\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { type OperationMeta } from '@flowgram-vue/history';\nimport { FlowDocument } from '@flowgram-vue/document';\nimport { type PluginContext } from '@flowgram-vue/core';\n\nimport { getFormModelV2, shouldChangeFormValuesMerge } from '../utils';\nimport { ChangeFormValuesOperationValue, NodeOperationType } from '../types';\n\n/**\n * 表单修改操作\n */\nexport const changeFormValueOperationMeta: OperationMeta<\n ChangeFormValuesOperationValue,\n PluginContext,\n void\n> = {\n type: NodeOperationType.changeFormValues,\n inverse: (op) => ({\n ...op,\n value: {\n ...op.value,\n value: op.value.oldValue,\n oldValue: op.value.value,\n },\n }),\n apply: ({ value: { value, path, id } }, ctx: PluginContext) => {\n const document = ctx.get<FlowDocument>(FlowDocument);\n const formModel = getFormModelV2(document.getNode(id));\n\n if (!formModel) {\n return;\n }\n if (!path) {\n formModel.updateFormValues(value);\n } else {\n formModel.setValueIn(path, value);\n }\n },\n shouldMerge: shouldChangeFormValuesMerge as OperationMeta['shouldMerge'],\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { OperationMeta } from '@flowgram-vue/history';\n\nimport { changeFormValueOperationMeta } from './change-form-values';\n\nexport const operationMetas: OperationMeta[] = [changeFormValueOperationMeta];\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { injectable } from 'inversify';\nimport { type OperationContribution, type OperationRegistry } from '@flowgram-vue/history';\n\nimport { operationMetas } from './operation-metas';\n\n/**\n * 表单历史操作\n */\n@injectable()\nexport class HistoryNodeRegisters implements OperationContribution {\n registerOperationMeta(operationRegistry: OperationRegistry): void {\n operationMetas.forEach(operationMeta => {\n operationRegistry.registerOperationMeta(operationMeta);\n });\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowDocument } from '@flowgram-vue/document';\nimport { bindContributions, definePluginCreator } from '@flowgram-vue/core';\nimport { HistoryContainerModule, HistoryService, OperationContribution } from '@flowgram-vue/history';\n\nimport { attachFormValuesChange, getFormModelV2 } from './utils';\nimport { HistoryNodeRegisters } from './history-node-registers';\n\n/**\n * 表单历史插件\n */\nexport const createHistoryNodePlugin = definePluginCreator({\n onBind: ({ bind }) => {\n bindContributions(bind, HistoryNodeRegisters, [OperationContribution]);\n },\n onInit: (ctx, _opts) => {\n const document = ctx.get<FlowDocument>(FlowDocument);\n const historyService = ctx.get<HistoryService>(HistoryService);\n\n document.onNodeCreate(({ node }) => {\n const formModel = getFormModelV2(node);\n\n if (!formModel) {\n return;\n }\n\n attachFormValuesChange(formModel, node, historyService);\n });\n },\n containerModules: [HistoryContainerModule],\n});\n"]}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@flowgram-vue/history-node-plugin",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "homepage": "https://flowgram.ai/",
6
+ "repository": "https://github.com/Crayon-hua/flowgram-vue",
7
+ "license": "MIT",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.cjs"
13
+ }
14
+ },
15
+ "main": "./dist/index.cjs",
16
+ "module": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "files": [
19
+ "src",
20
+ "dist"
21
+ ],
22
+ "dependencies": {
23
+ "inversify": "^6.0.1",
24
+ "lodash-es": "^4.17.21",
25
+ "reflect-metadata": "~0.2.2",
26
+ "@flowgram-vue/document": "0.2.0",
27
+ "@flowgram-vue/core": "0.2.0",
28
+ "@flowgram-vue/history": "0.2.0",
29
+ "@flowgram-vue/node": "0.2.0",
30
+ "@flowgram-vue/form": "0.2.0",
31
+ "@flowgram-vue/form-core": "0.2.0"
32
+ },
33
+ "devDependencies": {
34
+ "@types/lodash-es": "^4.17.12",
35
+ "@types/node": "^20",
36
+ "@vitejs/plugin-vue": "^6.0.1",
37
+ "@vitest/coverage-v8": "^3.2.4",
38
+ "eslint": "^9.0.0",
39
+ "jsdom": "^26.1.0",
40
+ "typescript": "^5.8.3",
41
+ "vitest": "^3.2.4",
42
+ "vue": "^3.5.18",
43
+ "@flowgram-vue/eslint-config": "0.2.0",
44
+ "@flowgram-vue/ts-config": "0.2.0",
45
+ "@flowgram-vue/build-config": "0.2.0"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public",
49
+ "registry": "https://registry.npmjs.org/"
50
+ },
51
+ "scripts": {
52
+ "build": "flowgram-build",
53
+ "test": "vitest run",
54
+ "test:cov": "vitest run --coverage",
55
+ "lint": "eslint .",
56
+ "ts-check": "tsc --noEmit",
57
+ "type-check": "tsc --noEmit",
58
+ "build:fast": "flowgram-build --fast",
59
+ "build:watch": "flowgram-build --watch"
60
+ }
61
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { FlowDocument } from '@flowgram-vue/document';
7
+ import { bindContributions, definePluginCreator } from '@flowgram-vue/core';
8
+ import { HistoryContainerModule, HistoryService, OperationContribution } from '@flowgram-vue/history';
9
+
10
+ import { attachFormValuesChange, getFormModelV2 } from './utils';
11
+ import { HistoryNodeRegisters } from './history-node-registers';
12
+
13
+ /**
14
+ * 表单历史插件
15
+ */
16
+ export const createHistoryNodePlugin = definePluginCreator({
17
+ onBind: ({ bind }) => {
18
+ bindContributions(bind, HistoryNodeRegisters, [OperationContribution]);
19
+ },
20
+ onInit: (ctx, _opts) => {
21
+ const document = ctx.get<FlowDocument>(FlowDocument);
22
+ const historyService = ctx.get<HistoryService>(HistoryService);
23
+
24
+ document.onNodeCreate(({ node }) => {
25
+ const formModel = getFormModelV2(node);
26
+
27
+ if (!formModel) {
28
+ return;
29
+ }
30
+
31
+ attachFormValuesChange(formModel, node, historyService);
32
+ });
33
+ },
34
+ containerModules: [HistoryContainerModule],
35
+ });
package/src/env.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ declare module '*.vue' {
7
+ import type { DefineComponent } from 'vue';
8
+ const component: DefineComponent<object, object, unknown>;
9
+ export default component;
10
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { injectable } from 'inversify';
7
+ import { type OperationContribution, type OperationRegistry } from '@flowgram-vue/history';
8
+
9
+ import { operationMetas } from './operation-metas';
10
+
11
+ /**
12
+ * 表单历史操作
13
+ */
14
+ @injectable()
15
+ export class HistoryNodeRegisters implements OperationContribution {
16
+ registerOperationMeta(operationRegistry: OperationRegistry): void {
17
+ operationMetas.forEach(operationMeta => {
18
+ operationRegistry.registerOperationMeta(operationMeta);
19
+ });
20
+ }
21
+ }
package/src/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export * from './create-history-node-plugin';
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { type OperationMeta } from '@flowgram-vue/history';
7
+ import { FlowDocument } from '@flowgram-vue/document';
8
+ import { type PluginContext } from '@flowgram-vue/core';
9
+
10
+ import { getFormModelV2, shouldChangeFormValuesMerge } from '../utils';
11
+ import { ChangeFormValuesOperationValue, NodeOperationType } from '../types';
12
+
13
+ /**
14
+ * 表单修改操作
15
+ */
16
+ export const changeFormValueOperationMeta: OperationMeta<
17
+ ChangeFormValuesOperationValue,
18
+ PluginContext,
19
+ void
20
+ > = {
21
+ type: NodeOperationType.changeFormValues,
22
+ inverse: (op) => ({
23
+ ...op,
24
+ value: {
25
+ ...op.value,
26
+ value: op.value.oldValue,
27
+ oldValue: op.value.value,
28
+ },
29
+ }),
30
+ apply: ({ value: { value, path, id } }, ctx: PluginContext) => {
31
+ const document = ctx.get<FlowDocument>(FlowDocument);
32
+ const formModel = getFormModelV2(document.getNode(id));
33
+
34
+ if (!formModel) {
35
+ return;
36
+ }
37
+ if (!path) {
38
+ formModel.updateFormValues(value);
39
+ } else {
40
+ formModel.setValueIn(path, value);
41
+ }
42
+ },
43
+ shouldMerge: shouldChangeFormValuesMerge as OperationMeta['shouldMerge'],
44
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { OperationMeta } from '@flowgram-vue/history';
7
+
8
+ import { changeFormValueOperationMeta } from './change-form-values';
9
+
10
+ export const operationMetas: OperationMeta[] = [changeFormValueOperationMeta];
package/src/types.ts ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export enum NodeOperationType {
7
+ changeFormValues = 'changeFormValues',
8
+ }
9
+
10
+ export interface ChangeFormValuesOperationValue {
11
+ id: string;
12
+ path: string;
13
+ value: unknown;
14
+ oldValue: unknown;
15
+ }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { get } from 'lodash-es';
7
+ import { FormModelV2, isFormModelV2 } from '@flowgram-vue/node';
8
+ import { HistoryService, Operation } from '@flowgram-vue/history';
9
+ import { StackOperation } from '@flowgram-vue/history';
10
+ import { FlowNodeFormData } from '@flowgram-vue/form-core';
11
+ import { FlowNodeEntity } from '@flowgram-vue/document';
12
+
13
+ import { ChangeFormValuesOperationValue, NodeOperationType } from '../types';
14
+
15
+ /**
16
+ * 获取v2版本的formModel
17
+ * @param node 节点
18
+ * @returns
19
+ */
20
+ export function getFormModelV2(node: FlowNodeEntity | undefined): FormModelV2 | undefined {
21
+ if (!node) {
22
+ return undefined;
23
+ }
24
+
25
+ const formModel = node?.getData(FlowNodeFormData)?.getFormModel<FormModelV2>();
26
+
27
+ if (!formModel || !isFormModelV2(formModel)) {
28
+ return undefined;
29
+ }
30
+
31
+ return formModel;
32
+ }
33
+
34
+ /**
35
+ * 表单合并策略
36
+ * @param op 操作
37
+ * @param prev 上一个操作
38
+ * @param element 操作栈元素
39
+ * @returns
40
+ */
41
+ export function shouldChangeFormValuesMerge(
42
+ op: Operation<ChangeFormValuesOperationValue | undefined>,
43
+ prev: Operation<ChangeFormValuesOperationValue | undefined>,
44
+ element: StackOperation
45
+ ) {
46
+ if (!prev) {
47
+ return false;
48
+ }
49
+
50
+ if (Date.now() - element.getTimestamp() < 500) {
51
+ if (
52
+ op.type === prev.type && // 相同类型
53
+ op.value?.id === prev.value?.id && // 相同节点
54
+ op.value?.path === prev.value?.path // 相同路径
55
+ ) {
56
+ return {
57
+ type: op.type,
58
+ value: {
59
+ ...op.value,
60
+ value: op.value?.value,
61
+ oldValue: prev.value?.oldValue,
62
+ },
63
+ };
64
+ }
65
+ return true;
66
+ }
67
+ return false;
68
+ }
69
+
70
+ /**
71
+ * 监听表单值变化
72
+ * @param formModel 表单模型
73
+ * @param node 节点
74
+ * @param historyService 历史服务
75
+ */
76
+ export function attachFormValuesChange(
77
+ formModel: FormModelV2,
78
+ node: FlowNodeEntity,
79
+ historyService: HistoryService
80
+ ) {
81
+ formModel.onFormValuesChange((event) => {
82
+ historyService.pushOperation(
83
+ {
84
+ type: NodeOperationType.changeFormValues,
85
+ value: {
86
+ id: node.id,
87
+ path: event.name,
88
+ value: event.name ? get(event.values, event.name) : event.values,
89
+ oldValue: event.name ? get(event.prevValues, event.name) : event.prevValues,
90
+ },
91
+ },
92
+ { noApply: true }
93
+ );
94
+ });
95
+ }