@flowgram.ai/history-node-plugin 0.1.0-alpha.10
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/esm/index.js +135 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.d.mts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +159 -0
- package/dist/index.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,135 @@
|
|
|
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/create-history-node-plugin.ts
|
|
13
|
+
import { FlowDocument as FlowDocument2 } from "@flowgram.ai/document";
|
|
14
|
+
import { bindContributions, definePluginCreator } from "@flowgram.ai/core";
|
|
15
|
+
import { HistoryContainerModule, HistoryService, OperationContribution } from "@flowgram.ai/history";
|
|
16
|
+
|
|
17
|
+
// src/utils/index.ts
|
|
18
|
+
import { get } from "lodash";
|
|
19
|
+
import { isFormModelV2 } from "@flowgram.ai/node";
|
|
20
|
+
import { FlowNodeFormData } from "@flowgram.ai/form-core";
|
|
21
|
+
function getFormModelV2(node) {
|
|
22
|
+
if (!node) {
|
|
23
|
+
return void 0;
|
|
24
|
+
}
|
|
25
|
+
const formModel = node?.getData(FlowNodeFormData)?.getFormModel();
|
|
26
|
+
if (!formModel || !isFormModelV2(formModel)) {
|
|
27
|
+
return void 0;
|
|
28
|
+
}
|
|
29
|
+
return formModel;
|
|
30
|
+
}
|
|
31
|
+
function shouldChangeFormValuesMerge(op, prev, element) {
|
|
32
|
+
if (!prev) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (Date.now() - element.getTimestamp() < 500) {
|
|
36
|
+
if (op.type === prev.type && // 相同类型
|
|
37
|
+
op.value?.id === prev.value?.id && // 相同节点
|
|
38
|
+
op.value?.path === prev.value?.path) {
|
|
39
|
+
return {
|
|
40
|
+
type: op.type,
|
|
41
|
+
value: {
|
|
42
|
+
...op.value,
|
|
43
|
+
value: op.value?.value,
|
|
44
|
+
oldValue: prev.value?.oldValue
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
function attachFormValuesChange(formModel, node, historyService) {
|
|
53
|
+
formModel.onFormValuesChange((event) => {
|
|
54
|
+
historyService.pushOperation(
|
|
55
|
+
{
|
|
56
|
+
type: "changeFormValues" /* changeFormValues */,
|
|
57
|
+
value: {
|
|
58
|
+
id: node.id,
|
|
59
|
+
path: event.name,
|
|
60
|
+
value: event.name ? get(event.values, event.name) : event.values,
|
|
61
|
+
oldValue: event.name ? get(event.prevValues, event.name) : event.prevValues
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{ noApply: true }
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/history-node-registers.ts
|
|
70
|
+
import { injectable } from "inversify";
|
|
71
|
+
|
|
72
|
+
// src/operation-metas/change-form-values.ts
|
|
73
|
+
import { FlowDocument } from "@flowgram.ai/document";
|
|
74
|
+
var changeFormValueOperationMeta = {
|
|
75
|
+
type: "changeFormValues" /* changeFormValues */,
|
|
76
|
+
inverse: (op) => ({
|
|
77
|
+
...op,
|
|
78
|
+
value: {
|
|
79
|
+
...op.value,
|
|
80
|
+
value: op.value.oldValue,
|
|
81
|
+
oldValue: op.value.value
|
|
82
|
+
}
|
|
83
|
+
}),
|
|
84
|
+
apply: ({ value: { value, path, id } }, ctx) => {
|
|
85
|
+
const document = ctx.get(FlowDocument);
|
|
86
|
+
const formModel = getFormModelV2(document.getNode(id));
|
|
87
|
+
if (!formModel) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (!path) {
|
|
91
|
+
formModel.updateFormValues(value);
|
|
92
|
+
} else {
|
|
93
|
+
formModel.setValueIn(path, value);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
shouldMerge: shouldChangeFormValuesMerge
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// src/operation-metas/index.ts
|
|
100
|
+
var operationMetas = [changeFormValueOperationMeta];
|
|
101
|
+
|
|
102
|
+
// src/history-node-registers.ts
|
|
103
|
+
var HistoryNodeRegisters = class {
|
|
104
|
+
registerOperationMeta(operationRegistry) {
|
|
105
|
+
operationMetas.forEach((operationMeta) => {
|
|
106
|
+
operationRegistry.registerOperationMeta(operationMeta);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
HistoryNodeRegisters = __decorateClass([
|
|
111
|
+
injectable()
|
|
112
|
+
], HistoryNodeRegisters);
|
|
113
|
+
|
|
114
|
+
// src/create-history-node-plugin.ts
|
|
115
|
+
var createHistoryNodePlugin = definePluginCreator({
|
|
116
|
+
onBind: ({ bind }) => {
|
|
117
|
+
bindContributions(bind, HistoryNodeRegisters, [OperationContribution]);
|
|
118
|
+
},
|
|
119
|
+
onInit: (ctx, _opts) => {
|
|
120
|
+
const document = ctx.get(FlowDocument2);
|
|
121
|
+
const historyService = ctx.get(HistoryService);
|
|
122
|
+
document.onNodeCreate(({ node }) => {
|
|
123
|
+
const formModel = getFormModelV2(node);
|
|
124
|
+
if (!formModel) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
attachFormValuesChange(formModel, node, historyService);
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
containerModules: [HistoryContainerModule]
|
|
131
|
+
});
|
|
132
|
+
export {
|
|
133
|
+
createHistoryNodePlugin
|
|
134
|
+
};
|
|
135
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/create-history-node-plugin.ts","../../src/utils/index.ts","../../src/history-node-registers.ts","../../src/operation-metas/change-form-values.ts","../../src/operation-metas/index.ts"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowDocument } from '@flowgram.ai/document';\nimport { bindContributions, definePluginCreator } from '@flowgram.ai/core';\nimport { HistoryContainerModule, HistoryService, OperationContribution } from '@flowgram.ai/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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { get } from 'lodash';\nimport { FormModelV2, isFormModelV2 } from '@flowgram.ai/node';\nimport { HistoryService, Operation } from '@flowgram.ai/history';\nimport { StackOperation } from '@flowgram.ai/history';\nimport { FlowNodeFormData } from '@flowgram.ai/form-core';\nimport { FlowNodeEntity } from '@flowgram.ai/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 { injectable } from 'inversify';\nimport { type OperationContribution, type OperationRegistry } from '@flowgram.ai/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 { type OperationMeta } from '@flowgram.ai/history';\nimport { FlowDocument } from '@flowgram.ai/document';\nimport { type PluginContext } from '@flowgram.ai/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.ai/history';\n\nimport { changeFormValueOperationMeta } from './change-form-values';\n\nexport const operationMetas: OperationMeta[] = [changeFormValueOperationMeta];\n"],"mappings":"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","names":["FlowDocument","FlowDocument"]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as _flowgram_ai_core from '@flowgram.ai/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_ai_core.PluginCreator<unknown>;
|
|
11
|
+
|
|
12
|
+
export { createHistoryNodePlugin };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as _flowgram_ai_core from '@flowgram.ai/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_ai_core.PluginCreator<unknown>;
|
|
11
|
+
|
|
12
|
+
export { createHistoryNodePlugin };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
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
|
+
createHistoryNodePlugin: () => createHistoryNodePlugin
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(src_exports);
|
|
34
|
+
|
|
35
|
+
// src/create-history-node-plugin.ts
|
|
36
|
+
var import_document2 = require("@flowgram.ai/document");
|
|
37
|
+
var import_core = require("@flowgram.ai/core");
|
|
38
|
+
var import_history = require("@flowgram.ai/history");
|
|
39
|
+
|
|
40
|
+
// src/utils/index.ts
|
|
41
|
+
var import_lodash = require("lodash");
|
|
42
|
+
var import_node = require("@flowgram.ai/node");
|
|
43
|
+
var import_form_core = require("@flowgram.ai/form-core");
|
|
44
|
+
function getFormModelV2(node) {
|
|
45
|
+
if (!node) {
|
|
46
|
+
return void 0;
|
|
47
|
+
}
|
|
48
|
+
const formModel = node?.getData(import_form_core.FlowNodeFormData)?.getFormModel();
|
|
49
|
+
if (!formModel || !(0, import_node.isFormModelV2)(formModel)) {
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
return formModel;
|
|
53
|
+
}
|
|
54
|
+
function shouldChangeFormValuesMerge(op, prev, element) {
|
|
55
|
+
if (!prev) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
if (Date.now() - element.getTimestamp() < 500) {
|
|
59
|
+
if (op.type === prev.type && // 相同类型
|
|
60
|
+
op.value?.id === prev.value?.id && // 相同节点
|
|
61
|
+
op.value?.path === prev.value?.path) {
|
|
62
|
+
return {
|
|
63
|
+
type: op.type,
|
|
64
|
+
value: {
|
|
65
|
+
...op.value,
|
|
66
|
+
value: op.value?.value,
|
|
67
|
+
oldValue: prev.value?.oldValue
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
function attachFormValuesChange(formModel, node, historyService) {
|
|
76
|
+
formModel.onFormValuesChange((event) => {
|
|
77
|
+
historyService.pushOperation(
|
|
78
|
+
{
|
|
79
|
+
type: "changeFormValues" /* changeFormValues */,
|
|
80
|
+
value: {
|
|
81
|
+
id: node.id,
|
|
82
|
+
path: event.name,
|
|
83
|
+
value: event.name ? (0, import_lodash.get)(event.values, event.name) : event.values,
|
|
84
|
+
oldValue: event.name ? (0, import_lodash.get)(event.prevValues, event.name) : event.prevValues
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
{ noApply: true }
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/history-node-registers.ts
|
|
93
|
+
var import_inversify = require("inversify");
|
|
94
|
+
|
|
95
|
+
// src/operation-metas/change-form-values.ts
|
|
96
|
+
var import_document = require("@flowgram.ai/document");
|
|
97
|
+
var changeFormValueOperationMeta = {
|
|
98
|
+
type: "changeFormValues" /* changeFormValues */,
|
|
99
|
+
inverse: (op) => ({
|
|
100
|
+
...op,
|
|
101
|
+
value: {
|
|
102
|
+
...op.value,
|
|
103
|
+
value: op.value.oldValue,
|
|
104
|
+
oldValue: op.value.value
|
|
105
|
+
}
|
|
106
|
+
}),
|
|
107
|
+
apply: ({ value: { value, path, id } }, ctx) => {
|
|
108
|
+
const document = ctx.get(import_document.FlowDocument);
|
|
109
|
+
const formModel = getFormModelV2(document.getNode(id));
|
|
110
|
+
if (!formModel) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (!path) {
|
|
114
|
+
formModel.updateFormValues(value);
|
|
115
|
+
} else {
|
|
116
|
+
formModel.setValueIn(path, value);
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
shouldMerge: shouldChangeFormValuesMerge
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// src/operation-metas/index.ts
|
|
123
|
+
var operationMetas = [changeFormValueOperationMeta];
|
|
124
|
+
|
|
125
|
+
// src/history-node-registers.ts
|
|
126
|
+
var HistoryNodeRegisters = class {
|
|
127
|
+
registerOperationMeta(operationRegistry) {
|
|
128
|
+
operationMetas.forEach((operationMeta) => {
|
|
129
|
+
operationRegistry.registerOperationMeta(operationMeta);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
HistoryNodeRegisters = __decorateClass([
|
|
134
|
+
(0, import_inversify.injectable)()
|
|
135
|
+
], HistoryNodeRegisters);
|
|
136
|
+
|
|
137
|
+
// src/create-history-node-plugin.ts
|
|
138
|
+
var createHistoryNodePlugin = (0, import_core.definePluginCreator)({
|
|
139
|
+
onBind: ({ bind }) => {
|
|
140
|
+
(0, import_core.bindContributions)(bind, HistoryNodeRegisters, [import_history.OperationContribution]);
|
|
141
|
+
},
|
|
142
|
+
onInit: (ctx, _opts) => {
|
|
143
|
+
const document = ctx.get(import_document2.FlowDocument);
|
|
144
|
+
const historyService = ctx.get(import_history.HistoryService);
|
|
145
|
+
document.onNodeCreate(({ node }) => {
|
|
146
|
+
const formModel = getFormModelV2(node);
|
|
147
|
+
if (!formModel) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
attachFormValuesChange(formModel, node, historyService);
|
|
151
|
+
});
|
|
152
|
+
},
|
|
153
|
+
containerModules: [import_history.HistoryContainerModule]
|
|
154
|
+
});
|
|
155
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
156
|
+
0 && (module.exports = {
|
|
157
|
+
createHistoryNodePlugin
|
|
158
|
+
});
|
|
159
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/create-history-node-plugin.ts","../src/utils/index.ts","../src/history-node-registers.ts","../src/operation-metas/change-form-values.ts","../src/operation-metas/index.ts"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nexport * from './create-history-node-plugin';\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FlowDocument } from '@flowgram.ai/document';\nimport { bindContributions, definePluginCreator } from '@flowgram.ai/core';\nimport { HistoryContainerModule, HistoryService, OperationContribution } from '@flowgram.ai/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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { get } from 'lodash';\nimport { FormModelV2, isFormModelV2 } from '@flowgram.ai/node';\nimport { HistoryService, Operation } from '@flowgram.ai/history';\nimport { StackOperation } from '@flowgram.ai/history';\nimport { FlowNodeFormData } from '@flowgram.ai/form-core';\nimport { FlowNodeEntity } from '@flowgram.ai/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 { injectable } from 'inversify';\nimport { type OperationContribution, type OperationRegistry } from '@flowgram.ai/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 { type OperationMeta } from '@flowgram.ai/history';\nimport { FlowDocument } from '@flowgram.ai/document';\nimport { type PluginContext } from '@flowgram.ai/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.ai/history';\n\nimport { changeFormValueOperationMeta } from './change-form-values';\n\nexport const operationMetas: OperationMeta[] = [changeFormValueOperationMeta];\n"],"mappings":"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","names":["import_document"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flowgram.ai/history-node-plugin",
|
|
3
|
+
"version": "0.1.0-alpha.10",
|
|
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
|
+
"lodash": "^4.17.21",
|
|
22
|
+
"@flowgram.ai/core": "0.1.0-alpha.10",
|
|
23
|
+
"@flowgram.ai/document": "0.1.0-alpha.10",
|
|
24
|
+
"@flowgram.ai/form": "0.1.0-alpha.10",
|
|
25
|
+
"@flowgram.ai/form-core": "0.1.0-alpha.10",
|
|
26
|
+
"@flowgram.ai/node": "0.1.0-alpha.10",
|
|
27
|
+
"@flowgram.ai/history": "0.1.0-alpha.10",
|
|
28
|
+
"@flowgram.ai/utils": "0.1.0-alpha.10"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/bezier-js": "4.1.3",
|
|
32
|
+
"@types/lodash": "^4.14.137",
|
|
33
|
+
"@types/react": "^18",
|
|
34
|
+
"@types/react-dom": "^18",
|
|
35
|
+
"@types/styled-components": "^5",
|
|
36
|
+
"@vitest/coverage-v8": "^0.32.0",
|
|
37
|
+
"eslint": "^8.54.0",
|
|
38
|
+
"react": "^18",
|
|
39
|
+
"react-dom": "^18",
|
|
40
|
+
"styled-components": "^5",
|
|
41
|
+
"tsup": "^8.0.1",
|
|
42
|
+
"typescript": "^5.0.4",
|
|
43
|
+
"vitest": "^0.34.6",
|
|
44
|
+
"@flowgram.ai/eslint-config": "0.1.0-alpha.10",
|
|
45
|
+
"@flowgram.ai/ts-config": "0.1.0-alpha.10"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"react": ">=16.8",
|
|
49
|
+
"react-dom": ">=16.8",
|
|
50
|
+
"styled-components": ">=4"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public",
|
|
54
|
+
"registry": "https://registry.npmjs.org/"
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "npm run build:fast -- --dts-resolve",
|
|
58
|
+
"build:fast": "tsup src/index.ts --format cjs,esm --sourcemap --legacy-output",
|
|
59
|
+
"build:watch": "npm run build:fast -- --dts-resolve",
|
|
60
|
+
"clean": "rimraf dist",
|
|
61
|
+
"test": "vitest run",
|
|
62
|
+
"test:cov": "vitest run --coverage",
|
|
63
|
+
"ts-check": "tsc --noEmit",
|
|
64
|
+
"watch": "npm run build:fast -- --dts-resolve --watch --ignore-watch dist"
|
|
65
|
+
}
|
|
66
|
+
}
|