@tmagic/editor 1.8.0-beta.4 → 1.8.0-beta.5
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/es/components/CompareForm.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/ToolButton.vue_vue_type_script_setup_true_lang.js +6 -6
- package/dist/es/index.js +6 -3
- package/dist/es/initService.js +1 -1
- package/dist/es/layouts/Framework.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/history-list/Bucket.vue_vue_type_script_setup_true_lang.js +19 -55
- package/dist/es/layouts/history-list/BucketTab.vue_vue_type_script_setup_true_lang.js +22 -39
- package/dist/es/layouts/history-list/GroupRow.vue_vue_type_script_setup_true_lang.js +149 -103
- package/dist/es/layouts/history-list/HistoryDiffDialog.vue_vue_type_script_setup_true_lang.js +32 -8
- package/dist/es/layouts/history-list/HistoryListPanel.vue_vue_type_script_setup_true_lang.js +333 -211
- package/dist/es/layouts/history-list/InitialRow.vue_vue_type_script_setup_true_lang.js +28 -7
- package/dist/es/layouts/history-list/PageTab.vue_vue_type_script_setup_true_lang.js +47 -60
- package/dist/es/layouts/history-list/composables.js +73 -32
- package/dist/es/layouts/page-bar/PageBar.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/es/layouts/sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +5 -1
- package/dist/es/services/codeBlock.js +85 -37
- package/dist/es/services/dataSource.js +62 -26
- package/dist/es/services/editor.js +243 -100
- package/dist/es/services/history.js +270 -206
- package/dist/es/services/ui.js +3 -0
- package/dist/es/style.css +49 -6
- package/dist/es/utils/editor.js +35 -1
- package/dist/es/utils/history.js +223 -0
- package/dist/es/utils/indexed-db.js +86 -0
- package/dist/es/utils/undo-redo.js +60 -1
- package/dist/style.css +49 -6
- package/dist/tmagic-editor.umd.cjs +1799 -905
- package/package.json +7 -7
- package/src/components/CompareForm.vue +3 -1
- package/src/components/ToolButton.vue +2 -2
- package/src/index.ts +1 -0
- package/src/initService.ts +1 -1
- package/src/layouts/Framework.vue +1 -1
- package/src/layouts/history-list/Bucket.vue +34 -71
- package/src/layouts/history-list/BucketTab.vue +46 -54
- package/src/layouts/history-list/GroupRow.vue +146 -111
- package/src/layouts/history-list/HistoryDiffDialog.vue +94 -68
- package/src/layouts/history-list/HistoryListPanel.vue +296 -113
- package/src/layouts/history-list/InitialRow.vue +25 -9
- package/src/layouts/history-list/PageTab.vue +57 -51
- package/src/layouts/history-list/composables.ts +157 -36
- package/src/layouts/page-bar/PageBar.vue +4 -2
- package/src/layouts/sidebar/Sidebar.vue +6 -1
- package/src/services/codeBlock.ts +107 -37
- package/src/services/dataSource.ts +89 -40
- package/src/services/editor.ts +370 -134
- package/src/services/history.ts +305 -203
- package/src/services/ui.ts +7 -0
- package/src/theme/history-list-panel.scss +72 -5
- package/src/theme/page-bar.scss +0 -4
- package/src/type.ts +167 -63
- package/src/utils/editor.ts +41 -1
- package/src/utils/history.ts +298 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/indexed-db.ts +122 -0
- package/src/utils/undo-redo.ts +88 -0
- package/types/index.d.ts +783 -291
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { CODE_DRAFT_STORAGE_KEY } from "../type.js";
|
|
2
2
|
import BaseService from "./BaseService.js";
|
|
3
|
-
import history_default from "./history.js";
|
|
4
3
|
import { getEditorConfig } from "../utils/config.js";
|
|
4
|
+
import { describeRevertStep } from "../utils/history.js";
|
|
5
|
+
import history_default from "./history.js";
|
|
5
6
|
import storage_default, { Protocol } from "./storage.js";
|
|
6
7
|
import { COPY_CODE_STORAGE_KEY } from "../utils/editor.js";
|
|
7
8
|
import editor_default from "./editor.js";
|
|
@@ -20,17 +21,6 @@ var canUsePluginMethods = {
|
|
|
20
21
|
],
|
|
21
22
|
sync: ["setCodeDslByIdSync"]
|
|
22
23
|
};
|
|
23
|
-
/**
|
|
24
|
-
* 「回滚」生成的新 step 简短描述。仅 service 层使用。
|
|
25
|
-
*/
|
|
26
|
-
var describeRevertCodeBlockStep = (step) => {
|
|
27
|
-
const { oldContent, newContent, changeRecords, id } = step;
|
|
28
|
-
if (oldContent === null && newContent) return `撤回新增 ${newContent.name || newContent.id || id}`;
|
|
29
|
-
if (oldContent && newContent === null) return `还原已删除的 ${oldContent.name || oldContent.id || id}`;
|
|
30
|
-
const name = newContent?.name || oldContent?.name || `${id}`;
|
|
31
|
-
const propPath = changeRecords?.[0]?.propPath;
|
|
32
|
-
return propPath ? `还原 ${name} · ${propPath}` : `还原 ${name}`;
|
|
33
|
-
};
|
|
34
24
|
var CodeBlock = class extends BaseService {
|
|
35
25
|
state = reactive({
|
|
36
26
|
codeDsl: null,
|
|
@@ -39,6 +29,16 @@ var CodeBlock = class extends BaseService {
|
|
|
39
29
|
undeletableList: [],
|
|
40
30
|
paramsColConfig: void 0
|
|
41
31
|
});
|
|
32
|
+
/**
|
|
33
|
+
* 最近一次写入历史栈的代码块历史记录 uuid(单条写入场景:新增 / 更新)。
|
|
34
|
+
* 供 setCodeDslById(Sync)AndGetHistoryId 取回,普通方法不读取它。
|
|
35
|
+
*/
|
|
36
|
+
lastPushedHistoryId = null;
|
|
37
|
+
/**
|
|
38
|
+
* deleteCodeDslByIds 一次删除多个代码块时,按写入顺序收集的历史记录 uuid 列表。
|
|
39
|
+
* 在 deleteCodeDslByIds 入口处重置,供 deleteCodeDslByIdsAndGetHistoryId 取回。
|
|
40
|
+
*/
|
|
41
|
+
lastDeletedHistoryIds = [];
|
|
42
42
|
constructor() {
|
|
43
43
|
super([...canUsePluginMethods.async.map((methodName) => ({
|
|
44
44
|
name: methodName,
|
|
@@ -121,13 +121,13 @@ var CodeBlock = class extends BaseService {
|
|
|
121
121
|
...codeConfigProcessed
|
|
122
122
|
};
|
|
123
123
|
const newContent = cloneDeep$1(codeDsl[id]);
|
|
124
|
-
if (!doNotPushHistory) history_default.pushCodeBlock(id, {
|
|
124
|
+
if (!doNotPushHistory) this.lastPushedHistoryId = history_default.pushCodeBlock(id, {
|
|
125
125
|
oldContent,
|
|
126
126
|
newContent,
|
|
127
127
|
changeRecords,
|
|
128
128
|
historyDescription,
|
|
129
129
|
source: historySource
|
|
130
|
-
});
|
|
130
|
+
})?.uuid ?? null;
|
|
131
131
|
this.emit("addOrUpdate", id, codeDsl[id]);
|
|
132
132
|
}
|
|
133
133
|
/**
|
|
@@ -210,18 +210,50 @@ var CodeBlock = class extends BaseService {
|
|
|
210
210
|
async deleteCodeDslByIds(codeIds, { doNotPushHistory = false, historyDescription, historySource } = {}) {
|
|
211
211
|
const currentDsl = await this.getCodeDsl();
|
|
212
212
|
if (!currentDsl) return;
|
|
213
|
+
this.lastDeletedHistoryIds = [];
|
|
213
214
|
codeIds.forEach((id) => {
|
|
214
215
|
const oldContent = currentDsl[id] ? cloneDeep$1(currentDsl[id]) : null;
|
|
215
216
|
delete currentDsl[id];
|
|
216
|
-
if (oldContent && !doNotPushHistory)
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
217
|
+
if (oldContent && !doNotPushHistory) {
|
|
218
|
+
const uuid = history_default.pushCodeBlock(id, {
|
|
219
|
+
oldContent,
|
|
220
|
+
newContent: null,
|
|
221
|
+
historyDescription,
|
|
222
|
+
source: historySource
|
|
223
|
+
})?.uuid;
|
|
224
|
+
if (uuid) this.lastDeletedHistoryIds.push(uuid);
|
|
225
|
+
}
|
|
222
226
|
this.emit("remove", id);
|
|
223
227
|
});
|
|
224
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* 下列 *AndGetHistoryId 方法与对应的写入方法行为完全一致,
|
|
231
|
+
* 唯一区别是返回值为本次写入历史栈的历史记录 uuid({@link CodeBlockStepValue.uuid}),
|
|
232
|
+
* 可用于精确引用 / 定位该条历史记录(埋点、revert、跨端同步等)。
|
|
233
|
+
*
|
|
234
|
+
* 当本次操作未写入历史(doNotPushHistory 为 true、或无对应记录)时:单条写入返回 null,批量删除返回空数组。
|
|
235
|
+
*/
|
|
236
|
+
/** 等价于 {@link setCodeDslById},但返回本次写入历史记录的 uuid(未入栈时返回 null)。 */
|
|
237
|
+
async setCodeDslByIdAndGetHistoryId(id, codeConfig, options = {}) {
|
|
238
|
+
this.lastPushedHistoryId = null;
|
|
239
|
+
await this.setCodeDslById(id, codeConfig, options);
|
|
240
|
+
return this.lastPushedHistoryId;
|
|
241
|
+
}
|
|
242
|
+
/** 等价于 {@link setCodeDslByIdSync},但返回本次写入历史记录的 uuid(未入栈时返回 null)。 */
|
|
243
|
+
setCodeDslByIdSyncAndGetHistoryId(id, codeConfig, force = true, options = {}) {
|
|
244
|
+
this.lastPushedHistoryId = null;
|
|
245
|
+
this.setCodeDslByIdSync(id, codeConfig, force, options);
|
|
246
|
+
return this.lastPushedHistoryId;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* 等价于 {@link deleteCodeDslByIds},但返回本次写入的全部历史记录 uuid(按删除顺序)。
|
|
250
|
+
* 一次删除多个代码块会产生多条历史记录,因此返回数组;未写入任何历史时返回空数组。
|
|
251
|
+
*/
|
|
252
|
+
async deleteCodeDslByIdsAndGetHistoryId(codeIds, options = {}) {
|
|
253
|
+
this.lastDeletedHistoryIds = [];
|
|
254
|
+
await this.deleteCodeDslByIds(codeIds, options);
|
|
255
|
+
return [...this.lastDeletedHistoryIds];
|
|
256
|
+
}
|
|
225
257
|
setParamsColConfig(config) {
|
|
226
258
|
this.state.paramsColConfig = config;
|
|
227
259
|
}
|
|
@@ -297,11 +329,25 @@ var CodeBlock = class extends BaseService {
|
|
|
297
329
|
async revert(id, index) {
|
|
298
330
|
const entry = history_default.getCodeBlockStepList(id)[index];
|
|
299
331
|
if (!entry?.applied) return null;
|
|
300
|
-
|
|
301
|
-
|
|
332
|
+
const { oldSchema, newSchema, changeRecords } = entry.step.diff?.[0] ?? {};
|
|
333
|
+
if (oldSchema && newSchema && !changeRecords?.length) return null;
|
|
334
|
+
const description = `回滚 #${index + 1}: ${describeRevertStep(entry.step.id, entry.step.diff?.[0], (s) => s.name)}`;
|
|
302
335
|
return await this.applyRevertStep(entry.step, description);
|
|
303
336
|
}
|
|
304
337
|
/**
|
|
338
|
+
* 通过历史记录 uuid 回滚某条代码块历史步骤,语义同 {@link revert},
|
|
339
|
+
* 仅无需调用方再传 codeBlockId 与 index:内部会按 uuid({@link CodeBlockStepValue.uuid})
|
|
340
|
+
* 在全部代码块栈中定位对应步骤后再回滚。
|
|
341
|
+
*
|
|
342
|
+
* @param uuid 目标历史记录的 uuid,通常由 {@link setCodeDslByIdAndGetHistoryId} 等方法返回
|
|
343
|
+
* @returns 反向后产生的新 step;找不到对应 uuid / 未应用时返回 null
|
|
344
|
+
*/
|
|
345
|
+
async revertById(uuid) {
|
|
346
|
+
const location = history_default.findCodeBlockStepLocationByUuid(uuid);
|
|
347
|
+
if (!location) return null;
|
|
348
|
+
return await this.revert(location.id, location.index);
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
305
351
|
* 生成代码块唯一id
|
|
306
352
|
* @returns {Id} 代码块唯一id
|
|
307
353
|
*/
|
|
@@ -366,22 +412,23 @@ var CodeBlock = class extends BaseService {
|
|
|
366
412
|
* 差异仅在于通过公开的 setCodeDslByIdSync / deleteCodeDslByIds 触发 push。
|
|
367
413
|
*/
|
|
368
414
|
async applyRevertStep(step, historyDescription) {
|
|
369
|
-
const { id
|
|
370
|
-
|
|
415
|
+
const { id } = step;
|
|
416
|
+
const { oldSchema, newSchema, changeRecords } = step.diff?.[0] ?? {};
|
|
417
|
+
if (!oldSchema && newSchema) {
|
|
371
418
|
await this.deleteCodeDslByIds([id], {
|
|
372
419
|
historyDescription,
|
|
373
420
|
historySource: "rollback"
|
|
374
421
|
});
|
|
375
422
|
return history_default.getCodeBlockStepList(id).slice(-1)[0]?.step ?? null;
|
|
376
423
|
}
|
|
377
|
-
if (
|
|
378
|
-
this.setCodeDslByIdSync(id, cloneDeep$1(
|
|
424
|
+
if (oldSchema && !newSchema) {
|
|
425
|
+
this.setCodeDslByIdSync(id, cloneDeep$1(oldSchema), true, {
|
|
379
426
|
historyDescription,
|
|
380
427
|
historySource: "rollback"
|
|
381
428
|
});
|
|
382
429
|
return history_default.getCodeBlockStepList(id).slice(-1)[0]?.step ?? null;
|
|
383
430
|
}
|
|
384
|
-
if (!
|
|
431
|
+
if (!oldSchema || !newSchema) return null;
|
|
385
432
|
if (changeRecords?.length) {
|
|
386
433
|
const current = this.getCodeContentById(id);
|
|
387
434
|
if (!current) return null;
|
|
@@ -392,17 +439,17 @@ var CodeBlock = class extends BaseService {
|
|
|
392
439
|
fallbackToFullReplace = true;
|
|
393
440
|
break;
|
|
394
441
|
}
|
|
395
|
-
const value = cloneDeep$1(getValueByKeyPath(record.propPath,
|
|
442
|
+
const value = cloneDeep$1(getValueByKeyPath(record.propPath, oldSchema));
|
|
396
443
|
setValueByKeyPath(record.propPath, value, patched);
|
|
397
444
|
}
|
|
398
|
-
this.setCodeDslByIdSync(id, fallbackToFullReplace ? cloneDeep$1(
|
|
445
|
+
this.setCodeDslByIdSync(id, fallbackToFullReplace ? cloneDeep$1(oldSchema) : patched, true, {
|
|
399
446
|
changeRecords,
|
|
400
447
|
historyDescription,
|
|
401
448
|
historySource: "rollback"
|
|
402
449
|
});
|
|
403
450
|
return history_default.getCodeBlockStepList(id).slice(-1)[0]?.step ?? null;
|
|
404
451
|
}
|
|
405
|
-
this.setCodeDslByIdSync(id, cloneDeep$1(
|
|
452
|
+
this.setCodeDslByIdSync(id, cloneDeep$1(oldSchema), true, {
|
|
406
453
|
historyDescription,
|
|
407
454
|
historySource: "rollback"
|
|
408
455
|
});
|
|
@@ -423,19 +470,20 @@ var CodeBlock = class extends BaseService {
|
|
|
423
470
|
* @param reverse true=撤销,false=重做
|
|
424
471
|
*/
|
|
425
472
|
async applyHistoryStep(step, reverse) {
|
|
426
|
-
const { id
|
|
427
|
-
|
|
473
|
+
const { id } = step;
|
|
474
|
+
const { oldSchema, newSchema, changeRecords } = step.diff?.[0] ?? {};
|
|
475
|
+
if (!oldSchema && newSchema) {
|
|
428
476
|
if (reverse) await this.deleteCodeDslByIds([id], { doNotPushHistory: true });
|
|
429
|
-
else this.setCodeDslByIdSync(id, cloneDeep$1(
|
|
477
|
+
else this.setCodeDslByIdSync(id, cloneDeep$1(newSchema), true, { doNotPushHistory: true });
|
|
430
478
|
return;
|
|
431
479
|
}
|
|
432
|
-
if (
|
|
433
|
-
if (reverse) this.setCodeDslByIdSync(id, cloneDeep$1(
|
|
480
|
+
if (oldSchema && !newSchema) {
|
|
481
|
+
if (reverse) this.setCodeDslByIdSync(id, cloneDeep$1(oldSchema), true, { doNotPushHistory: true });
|
|
434
482
|
else await this.deleteCodeDslByIds([id], { doNotPushHistory: true });
|
|
435
483
|
return;
|
|
436
484
|
}
|
|
437
|
-
if (!
|
|
438
|
-
const sourceForValues = reverse ?
|
|
485
|
+
if (!oldSchema || !newSchema) return;
|
|
486
|
+
const sourceForValues = reverse ? oldSchema : newSchema;
|
|
439
487
|
if (changeRecords?.length) {
|
|
440
488
|
const current = this.getCodeContentById(id);
|
|
441
489
|
if (!current) return;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import BaseService from "./BaseService.js";
|
|
2
|
+
import { describeRevertStep } from "../utils/history.js";
|
|
2
3
|
import history_default from "./history.js";
|
|
3
4
|
import storage_default, { Protocol } from "./storage.js";
|
|
4
5
|
import { COPY_DS_STORAGE_KEY } from "../utils/editor.js";
|
|
@@ -26,18 +27,6 @@ var canUsePluginMethods = {
|
|
|
26
27
|
"createId"
|
|
27
28
|
]
|
|
28
29
|
};
|
|
29
|
-
/**
|
|
30
|
-
* 「回滚」生成的新 step 简短描述。
|
|
31
|
-
* 仅在 service 层使用,避免依赖 UI 层 composables。
|
|
32
|
-
*/
|
|
33
|
-
var describeRevertDataSourceStep = (step) => {
|
|
34
|
-
const { oldSchema, newSchema, changeRecords, id } = step;
|
|
35
|
-
if (oldSchema === null && newSchema) return `撤回新增 ${newSchema.title || newSchema.id || id}`;
|
|
36
|
-
if (oldSchema && newSchema === null) return `还原已删除的 ${oldSchema.title || oldSchema.id || id}`;
|
|
37
|
-
const title = newSchema?.title || oldSchema?.title || `${id}`;
|
|
38
|
-
const propPath = changeRecords?.[0]?.propPath;
|
|
39
|
-
return propPath ? `还原 ${title} · ${propPath}` : `还原 ${title}`;
|
|
40
|
-
};
|
|
41
30
|
var DataSource = class extends BaseService {
|
|
42
31
|
state = reactive({
|
|
43
32
|
datasourceTypeList: [],
|
|
@@ -48,6 +37,12 @@ var DataSource = class extends BaseService {
|
|
|
48
37
|
events: {},
|
|
49
38
|
methods: {}
|
|
50
39
|
});
|
|
40
|
+
/**
|
|
41
|
+
* 最近一次写入历史栈的数据源历史记录 uuid。
|
|
42
|
+
* 供 *AndGetHistoryId 系列方法在调用 add / update / remove 后取回本次产生的历史记录 id;
|
|
43
|
+
* 普通方法不读取它,调用前由 *AndGetHistoryId 重置为 null。
|
|
44
|
+
*/
|
|
45
|
+
lastPushedHistoryId = null;
|
|
51
46
|
constructor() {
|
|
52
47
|
super(canUsePluginMethods.sync.map((methodName) => ({
|
|
53
48
|
name: methodName,
|
|
@@ -97,12 +92,12 @@ var DataSource = class extends BaseService {
|
|
|
97
92
|
id: config.id && !this.getDataSourceById(config.id) ? config.id : this.createId()
|
|
98
93
|
};
|
|
99
94
|
this.get("dataSources").push(newConfig);
|
|
100
|
-
if (!doNotPushHistory) history_default.pushDataSource(newConfig.id, {
|
|
95
|
+
if (!doNotPushHistory) this.lastPushedHistoryId = history_default.pushDataSource(newConfig.id, {
|
|
101
96
|
oldSchema: null,
|
|
102
97
|
newSchema: newConfig,
|
|
103
98
|
historyDescription,
|
|
104
99
|
source: historySource
|
|
105
|
-
});
|
|
100
|
+
})?.uuid ?? null;
|
|
106
101
|
this.emit("add", newConfig);
|
|
107
102
|
return newConfig;
|
|
108
103
|
}
|
|
@@ -120,13 +115,13 @@ var DataSource = class extends BaseService {
|
|
|
120
115
|
const oldConfig = dataSources[index];
|
|
121
116
|
const newConfig = cloneDeep$1(config);
|
|
122
117
|
dataSources[index] = newConfig;
|
|
123
|
-
if (!doNotPushHistory) history_default.pushDataSource(newConfig.id, {
|
|
118
|
+
if (!doNotPushHistory) this.lastPushedHistoryId = history_default.pushDataSource(newConfig.id, {
|
|
124
119
|
oldSchema: oldConfig ? cloneDeep$1(oldConfig) : null,
|
|
125
120
|
newSchema: newConfig,
|
|
126
121
|
changeRecords,
|
|
127
122
|
historyDescription,
|
|
128
123
|
source: historySource
|
|
129
|
-
});
|
|
124
|
+
})?.uuid ?? null;
|
|
130
125
|
this.emit("update", newConfig, {
|
|
131
126
|
oldConfig,
|
|
132
127
|
changeRecords
|
|
@@ -145,15 +140,40 @@ var DataSource = class extends BaseService {
|
|
|
145
140
|
const index = dataSources.findIndex((ds) => ds.id === id);
|
|
146
141
|
const oldConfig = index !== -1 ? dataSources[index] : null;
|
|
147
142
|
dataSources.splice(index, 1);
|
|
148
|
-
if (oldConfig && !doNotPushHistory) history_default.pushDataSource(id, {
|
|
143
|
+
if (oldConfig && !doNotPushHistory) this.lastPushedHistoryId = history_default.pushDataSource(id, {
|
|
149
144
|
oldSchema: cloneDeep$1(oldConfig),
|
|
150
145
|
newSchema: null,
|
|
151
146
|
historyDescription,
|
|
152
147
|
source: historySource
|
|
153
|
-
});
|
|
148
|
+
})?.uuid ?? null;
|
|
154
149
|
this.emit("remove", id);
|
|
155
150
|
}
|
|
156
151
|
/**
|
|
152
|
+
* 下列 *AndGetHistoryId 方法与对应的 add / update / remove 行为完全一致,
|
|
153
|
+
* 唯一区别是返回值为本次写入历史栈的历史记录 uuid({@link DataSourceStepValue.uuid}),
|
|
154
|
+
* 而非数据源配置。可用于精确引用 / 定位该条历史记录(埋点、revert、跨端同步等)。
|
|
155
|
+
*
|
|
156
|
+
* 当本次操作未写入历史(doNotPushHistory 为 true、或无对应记录)时返回 null。
|
|
157
|
+
*/
|
|
158
|
+
/** 等价于 {@link add},但返回本次写入历史记录的 uuid(未入栈时返回 null)。 */
|
|
159
|
+
addAndGetHistoryId(config, options = {}) {
|
|
160
|
+
this.lastPushedHistoryId = null;
|
|
161
|
+
this.add(config, options);
|
|
162
|
+
return this.lastPushedHistoryId;
|
|
163
|
+
}
|
|
164
|
+
/** 等价于 {@link update},但返回本次写入历史记录的 uuid(未入栈时返回 null)。 */
|
|
165
|
+
updateAndGetHistoryId(config, options = {}) {
|
|
166
|
+
this.lastPushedHistoryId = null;
|
|
167
|
+
this.update(config, options);
|
|
168
|
+
return this.lastPushedHistoryId;
|
|
169
|
+
}
|
|
170
|
+
/** 等价于 {@link remove},但返回本次写入历史记录的 uuid(未入栈时返回 null)。 */
|
|
171
|
+
removeAndGetHistoryId(id, options = {}) {
|
|
172
|
+
this.lastPushedHistoryId = null;
|
|
173
|
+
this.remove(id, options);
|
|
174
|
+
return this.lastPushedHistoryId;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
157
177
|
* 撤销指定数据源的最近一次变更。
|
|
158
178
|
*
|
|
159
179
|
* 内部走 add / update / remove,因此会自动触发 dataSourceService 的事件,
|
|
@@ -221,10 +241,24 @@ var DataSource = class extends BaseService {
|
|
|
221
241
|
revert(id, index) {
|
|
222
242
|
const entry = history_default.getDataSourceStepList(id)[index];
|
|
223
243
|
if (!entry?.applied) return null;
|
|
224
|
-
|
|
225
|
-
|
|
244
|
+
const { oldSchema, newSchema, changeRecords } = entry.step.diff?.[0] ?? {};
|
|
245
|
+
if (oldSchema && newSchema && !changeRecords?.length) return null;
|
|
246
|
+
const description = `回滚 #${index + 1}: ${describeRevertStep(entry.step.id, entry.step.diff?.[0], (s) => s.title)}`;
|
|
226
247
|
return this.applyRevertStep(entry.step, description);
|
|
227
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* 通过历史记录 uuid 回滚某条数据源历史步骤,语义同 {@link revert},
|
|
251
|
+
* 仅无需调用方再传 dataSourceId 与 index:内部会按 uuid({@link DataSourceStepValue.uuid})
|
|
252
|
+
* 在全部数据源栈中定位对应步骤后再回滚。
|
|
253
|
+
*
|
|
254
|
+
* @param uuid 目标历史记录的 uuid,通常由 {@link addAndGetHistoryId} 等方法返回
|
|
255
|
+
* @returns 反向后产生的新 step;找不到对应 uuid / 未应用时返回 null
|
|
256
|
+
*/
|
|
257
|
+
revertById(uuid) {
|
|
258
|
+
const location = history_default.findDataSourceStepLocationByUuid(uuid);
|
|
259
|
+
if (!location) return null;
|
|
260
|
+
return this.revert(location.id, location.index);
|
|
261
|
+
}
|
|
228
262
|
createId() {
|
|
229
263
|
return `ds_${guid()}`;
|
|
230
264
|
}
|
|
@@ -283,15 +317,16 @@ var DataSource = class extends BaseService {
|
|
|
283
317
|
* 同构,差异仅在于走对应的公共 add / update / remove 而不是带 doNotPushHistory 的版本。
|
|
284
318
|
*/
|
|
285
319
|
applyRevertStep(step, historyDescription) {
|
|
286
|
-
const { id
|
|
287
|
-
|
|
320
|
+
const { id } = step;
|
|
321
|
+
const { oldSchema, newSchema, changeRecords } = step.diff?.[0] ?? {};
|
|
322
|
+
if (!oldSchema && newSchema) {
|
|
288
323
|
this.remove(`${id}`, {
|
|
289
324
|
historyDescription,
|
|
290
325
|
historySource: "rollback"
|
|
291
326
|
});
|
|
292
327
|
return history_default.getDataSourceStepList(id).slice(-1)[0]?.step ?? null;
|
|
293
328
|
}
|
|
294
|
-
if (oldSchema && newSchema
|
|
329
|
+
if (oldSchema && !newSchema) {
|
|
295
330
|
this.add(cloneDeep$1(oldSchema), {
|
|
296
331
|
historyDescription,
|
|
297
332
|
historySource: "rollback"
|
|
@@ -340,13 +375,14 @@ var DataSource = class extends BaseService {
|
|
|
340
375
|
* @param reverse true=撤销,false=重做
|
|
341
376
|
*/
|
|
342
377
|
applyHistoryStep(step, reverse) {
|
|
343
|
-
const { id
|
|
344
|
-
|
|
378
|
+
const { id } = step;
|
|
379
|
+
const { oldSchema, newSchema, changeRecords } = step.diff?.[0] ?? {};
|
|
380
|
+
if (!oldSchema && newSchema) {
|
|
345
381
|
if (reverse) this.remove(`${id}`, { doNotPushHistory: true });
|
|
346
382
|
else this.add(cloneDeep$1(newSchema), { doNotPushHistory: true });
|
|
347
383
|
return;
|
|
348
384
|
}
|
|
349
|
-
if (oldSchema && newSchema
|
|
385
|
+
if (oldSchema && !newSchema) {
|
|
350
386
|
if (reverse) this.add(cloneDeep$1(oldSchema), { doNotPushHistory: true });
|
|
351
387
|
else this.remove(`${id}`, { doNotPushHistory: true });
|
|
352
388
|
return;
|