@tmagic/editor 1.8.0-beta.1 → 1.8.0-beta.11

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.
Files changed (232) hide show
  1. package/dist/es/Editor.vue_vue_type_script_setup_true_lang.js +31 -5
  2. package/dist/es/components/CodeBlockEditor.vue_vue_type_script_setup_true_lang.js +21 -113
  3. package/dist/es/components/CodeParams.vue_vue_type_script_setup_true_lang.js +7 -1
  4. package/dist/es/components/CompareForm.js +5 -0
  5. package/dist/es/components/CompareForm.vue_vue_type_script_setup_true_lang.js +196 -0
  6. package/dist/es/components/ContentMenu.vue_vue_type_script_setup_true_lang.js +1 -1
  7. package/dist/es/components/FloatingBox.vue_vue_type_script_setup_true_lang.js +2 -2
  8. package/dist/es/components/Icon.vue_vue_type_script_setup_true_lang.js +1 -1
  9. package/dist/es/components/Resizer.vue_vue_type_script_setup_true_lang.js +1 -1
  10. package/dist/es/components/ScrollBar.vue_vue_type_script_setup_true_lang.js +1 -1
  11. package/dist/es/components/ScrollViewer.vue_vue_type_script_setup_true_lang.js +1 -1
  12. package/dist/es/components/SearchInput.vue_vue_type_script_setup_true_lang.js +1 -1
  13. package/dist/es/components/SplitView.vue_vue_type_script_setup_true_lang.js +1 -1
  14. package/dist/es/components/ToolButton.vue_vue_type_script_setup_true_lang.js +7 -7
  15. package/dist/es/components/Tree.vue_vue_type_script_setup_true_lang.js +1 -1
  16. package/dist/es/components/TreeNode.vue_vue_type_script_setup_true_lang.js +1 -1
  17. package/dist/es/editorProps.js +2 -0
  18. package/dist/es/fields/Code.vue_vue_type_script_setup_true_lang.js +20 -4
  19. package/dist/es/fields/CodeLink.vue_vue_type_script_setup_true_lang.js +3 -6
  20. package/dist/es/fields/CodeSelect.vue_vue_type_script_setup_true_lang.js +19 -3
  21. package/dist/es/fields/CodeSelectCol.vue_vue_type_script_setup_true_lang.js +42 -8
  22. package/dist/es/fields/CondOpSelect.vue_vue_type_script_setup_true_lang.js +1 -1
  23. package/dist/es/fields/DataSourceFieldSelect/FieldSelect.vue_vue_type_script_setup_true_lang.js +14 -6
  24. package/dist/es/fields/DataSourceFieldSelect/Index.vue_vue_type_script_setup_true_lang.js +3 -3
  25. package/dist/es/fields/DataSourceFields.vue_vue_type_script_setup_true_lang.js +41 -16
  26. package/dist/es/fields/DataSourceInput.vue_vue_type_script_setup_true_lang.js +2 -2
  27. package/dist/es/fields/DataSourceMethodSelect.vue_vue_type_script_setup_true_name_true_lang.js +9 -5
  28. package/dist/es/fields/DataSourceMethods.vue_vue_type_script_setup_true_lang.js +40 -19
  29. package/dist/es/fields/DataSourceMocks.vue_vue_type_script_setup_true_lang.js +17 -9
  30. package/dist/es/fields/DataSourceSelect.vue_vue_type_script_setup_true_lang.js +4 -2
  31. package/dist/es/fields/DisplayConds.vue_vue_type_script_setup_true_lang.js +1 -1
  32. package/dist/es/fields/EventSelect.vue_vue_type_script_setup_true_lang.js +59 -12
  33. package/dist/es/fields/KeyValue.vue_vue_type_script_setup_true_lang.js +12 -7
  34. package/dist/es/fields/PageFragmentSelect.vue_vue_type_script_setup_true_lang.js +1 -1
  35. package/dist/es/fields/StyleSetter/Index.vue_vue_type_script_setup_true_lang.js +1 -1
  36. package/dist/es/fields/StyleSetter/components/BackgroundPosition.vue_vue_type_script_setup_true_lang.js +1 -1
  37. package/dist/es/fields/StyleSetter/components/Border.vue_vue_type_script_setup_true_lang.js +28 -6
  38. package/dist/es/fields/StyleSetter/components/Box.vue_vue_type_script_setup_true_lang.js +1 -1
  39. package/dist/es/fields/StyleSetter/icons/background-repeat/NoRepeat.js +1 -1
  40. package/dist/es/fields/StyleSetter/icons/background-repeat/Repeat.js +1 -1
  41. package/dist/es/fields/StyleSetter/icons/background-repeat/RepeatX.js +1 -1
  42. package/dist/es/fields/StyleSetter/icons/background-repeat/RepeatY.js +1 -1
  43. package/dist/es/fields/StyleSetter/icons/display/Block.js +1 -1
  44. package/dist/es/fields/StyleSetter/icons/display/Flex.js +1 -1
  45. package/dist/es/fields/StyleSetter/icons/display/Inline.js +1 -1
  46. package/dist/es/fields/StyleSetter/icons/display/InlineBlock.js +1 -1
  47. package/dist/es/fields/StyleSetter/icons/display/None.js +1 -1
  48. package/dist/es/fields/StyleSetter/icons/flex-direction/Column.js +1 -1
  49. package/dist/es/fields/StyleSetter/icons/flex-direction/ColumnReverse.js +1 -1
  50. package/dist/es/fields/StyleSetter/icons/flex-direction/Row.js +1 -1
  51. package/dist/es/fields/StyleSetter/icons/flex-direction/RowReverse.js +1 -1
  52. package/dist/es/fields/StyleSetter/icons/justify-content/Center.js +1 -1
  53. package/dist/es/fields/StyleSetter/icons/justify-content/FlexEnd.js +1 -1
  54. package/dist/es/fields/StyleSetter/icons/justify-content/FlexStart.js +1 -1
  55. package/dist/es/fields/StyleSetter/icons/justify-content/SpaceAround.js +1 -1
  56. package/dist/es/fields/StyleSetter/icons/justify-content/SpaceBetween.js +1 -1
  57. package/dist/es/fields/StyleSetter/icons/text-align/Center.js +1 -1
  58. package/dist/es/fields/StyleSetter/icons/text-align/Left.js +1 -1
  59. package/dist/es/fields/StyleSetter/icons/text-align/Right.js +1 -1
  60. package/dist/es/fields/StyleSetter/pro/Background.vue_vue_type_script_setup_true_lang.js +1 -1
  61. package/dist/es/fields/StyleSetter/pro/Border.vue_vue_type_script_setup_true_lang.js +1 -1
  62. package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +1 -1
  63. package/dist/es/fields/StyleSetter/pro/Layout.vue_vue_type_script_setup_true_lang.js +1 -1
  64. package/dist/es/fields/StyleSetter/pro/Position.vue_vue_type_script_setup_true_lang.js +1 -1
  65. package/dist/es/fields/StyleSetter/pro/Transform.vue_vue_type_script_setup_true_lang.js +1 -1
  66. package/dist/es/fields/UISelect.vue_vue_type_script_setup_true_lang.js +9 -6
  67. package/dist/es/hooks/use-code-block-edit.js +7 -4
  68. package/dist/es/hooks/use-data-source-edit.js +5 -2
  69. package/dist/es/hooks/use-stage.js +22 -10
  70. package/dist/es/icons/CenterIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  71. package/dist/es/icons/CodeIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  72. package/dist/es/icons/FolderMinusIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  73. package/dist/es/index.js +14 -3
  74. package/dist/es/initService.js +7 -7
  75. package/dist/es/layouts/AddPageBox.vue_vue_type_script_setup_true_lang.js +1 -1
  76. package/dist/es/layouts/CodeEditor.vue_vue_type_script_setup_true_lang.js +7 -6
  77. package/dist/es/layouts/Framework.vue_vue_type_script_setup_true_lang.js +14 -9
  78. package/dist/es/layouts/NavMenu.vue_vue_type_script_setup_true_lang.js +12 -4
  79. package/dist/es/layouts/NavMenuColumn.vue_vue_type_script_setup_true_lang.js +1 -1
  80. package/dist/es/layouts/history-list/Bucket.js +5 -0
  81. package/dist/es/layouts/history-list/Bucket.vue_vue_type_script_setup_true_lang.js +71 -0
  82. package/dist/es/layouts/history-list/BucketTab.js +5 -0
  83. package/dist/es/layouts/history-list/BucketTab.vue_vue_type_script_setup_true_lang.js +62 -0
  84. package/dist/es/layouts/history-list/GroupRow.js +5 -0
  85. package/dist/es/layouts/history-list/GroupRow.vue_vue_type_script_setup_true_lang.js +269 -0
  86. package/dist/es/layouts/history-list/HistoryDiffDialog.js +5 -0
  87. package/dist/es/layouts/history-list/HistoryDiffDialog.vue_vue_type_script_setup_true_lang.js +294 -0
  88. package/dist/es/layouts/history-list/HistoryListPanel.js +5 -0
  89. package/dist/es/layouts/history-list/HistoryListPanel.vue_vue_type_script_setup_true_lang.js +327 -0
  90. package/dist/es/layouts/history-list/InitialRow.js +5 -0
  91. package/dist/es/layouts/history-list/InitialRow.vue_vue_type_script_setup_true_lang.js +83 -0
  92. package/dist/es/layouts/history-list/PageTab.js +5 -0
  93. package/dist/es/layouts/history-list/PageTab.vue_vue_type_script_setup_true_lang.js +95 -0
  94. package/dist/es/layouts/history-list/composables.js +184 -0
  95. package/dist/es/layouts/history-list/useHistoryList.js +56 -0
  96. package/dist/es/layouts/history-list/useHistoryRevert.js +313 -0
  97. package/dist/es/layouts/page-bar/AddButton.vue_vue_type_script_setup_true_lang.js +1 -1
  98. package/dist/es/layouts/page-bar/PageBar.vue_vue_type_script_setup_true_lang.js +5 -3
  99. package/dist/es/layouts/page-bar/PageBarScrollContainer.vue_vue_type_script_setup_true_lang.js +1 -1
  100. package/dist/es/layouts/page-bar/PageList.vue_vue_type_script_setup_true_lang.js +1 -1
  101. package/dist/es/layouts/page-bar/Search.vue_vue_type_script_setup_true_lang.js +2 -2
  102. package/dist/es/layouts/props-panel/FormPanel.vue_vue_type_script_setup_true_lang.js +1 -1
  103. package/dist/es/layouts/props-panel/PropsPanel.vue_vue_type_script_setup_true_lang.js +6 -2
  104. package/dist/es/layouts/sidebar/ComponentListPanel.vue_vue_type_script_setup_true_lang.js +2 -2
  105. package/dist/es/layouts/sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +8 -4
  106. package/dist/es/layouts/sidebar/code-block/CodeBlockList.vue_vue_type_script_setup_true_lang.js +4 -4
  107. package/dist/es/layouts/sidebar/code-block/CodeBlockListPanel.vue_vue_type_script_setup_true_lang.js +2 -2
  108. package/dist/es/layouts/sidebar/code-block/useContentMenu.js +1 -1
  109. package/dist/es/layouts/sidebar/data-source/DataSourceAddButton.vue_vue_type_script_setup_true_lang.js +1 -1
  110. package/dist/es/layouts/sidebar/data-source/DataSourceConfigPanel.vue_vue_type_script_setup_true_lang.js +19 -6
  111. package/dist/es/layouts/sidebar/data-source/DataSourceList.vue_vue_type_script_setup_true_lang.js +1 -1
  112. package/dist/es/layouts/sidebar/data-source/DataSourceListPanel.vue_vue_type_script_setup_true_lang.js +25 -3
  113. package/dist/es/layouts/sidebar/data-source/useContentMenu.js +1 -1
  114. package/dist/es/layouts/sidebar/layer/LayerMenu.vue_vue_type_script_setup_true_lang.js +6 -6
  115. package/dist/es/layouts/sidebar/layer/LayerNodeTool.vue_vue_type_script_setup_true_lang.js +2 -2
  116. package/dist/es/layouts/sidebar/layer/LayerPanel.vue_vue_type_script_setup_true_lang.js +1 -1
  117. package/dist/es/layouts/sidebar/layer/use-node-status.js +1 -1
  118. package/dist/es/layouts/workspace/Breadcrumb.vue_vue_type_script_setup_true_lang.js +1 -1
  119. package/dist/es/layouts/workspace/Workspace.vue_vue_type_script_setup_true_lang.js +1 -1
  120. package/dist/es/layouts/workspace/viewer/NodeListMenu.vue_vue_type_script_setup_true_lang.js +1 -1
  121. package/dist/es/layouts/workspace/viewer/Stage.vue_vue_type_script_setup_true_lang.js +2 -2
  122. package/dist/es/layouts/workspace/viewer/StageOverlay.vue_vue_type_script_setup_true_lang.js +1 -1
  123. package/dist/es/layouts/workspace/viewer/ViewerMenu.vue_vue_type_script_setup_true_lang.js +9 -9
  124. package/dist/es/services/BaseService.js +31 -68
  125. package/dist/es/services/codeBlock.js +286 -8
  126. package/dist/es/services/componentList.js +2 -2
  127. package/dist/es/services/dataSource.js +287 -8
  128. package/dist/es/services/dep.js +21 -9
  129. package/dist/es/services/editor.js +655 -194
  130. package/dist/es/services/events.js +2 -2
  131. package/dist/es/services/history.js +390 -47
  132. package/dist/es/services/keybinding.js +5 -5
  133. package/dist/es/services/props.js +8 -8
  134. package/dist/es/services/stageOverlay.js +2 -2
  135. package/dist/es/services/storage.js +2 -2
  136. package/dist/es/services/ui.js +5 -2
  137. package/dist/es/style.css +456 -8
  138. package/dist/es/utils/code-block.js +122 -0
  139. package/dist/es/utils/content-menu.js +19 -12
  140. package/dist/es/utils/data-source/index.js +2 -0
  141. package/dist/es/utils/dep/worker.js +1 -1
  142. package/dist/es/utils/editor.js +105 -51
  143. package/dist/es/utils/history.js +220 -0
  144. package/dist/es/utils/indexed-db.js +86 -0
  145. package/dist/es/utils/undo-redo.js +80 -1
  146. package/dist/style.css +456 -8
  147. package/dist/tmagic-editor.umd.cjs +11149 -6646
  148. package/package.json +8 -8
  149. package/src/Editor.vue +25 -1
  150. package/src/components/CodeBlockEditor.vue +20 -109
  151. package/src/components/CodeParams.vue +6 -0
  152. package/src/components/CompareForm.vue +277 -0
  153. package/src/components/ToolButton.vue +2 -2
  154. package/src/editorProps.ts +9 -0
  155. package/src/fields/Code.vue +19 -3
  156. package/src/fields/CodeLink.vue +2 -5
  157. package/src/fields/CodeSelect.vue +17 -1
  158. package/src/fields/CodeSelectCol.vue +37 -3
  159. package/src/fields/DataSourceFieldSelect/FieldSelect.vue +23 -3
  160. package/src/fields/DataSourceFieldSelect/Index.vue +2 -2
  161. package/src/fields/DataSourceFields.vue +48 -10
  162. package/src/fields/DataSourceInput.vue +3 -3
  163. package/src/fields/DataSourceMethodSelect.vue +12 -4
  164. package/src/fields/DataSourceMethods.vue +55 -24
  165. package/src/fields/DataSourceMocks.vue +13 -3
  166. package/src/fields/DataSourceSelect.vue +4 -1
  167. package/src/fields/EventSelect.vue +57 -8
  168. package/src/fields/KeyValue.vue +17 -4
  169. package/src/fields/StyleSetter/components/Border.vue +15 -6
  170. package/src/fields/UISelect.vue +5 -2
  171. package/src/hooks/use-code-block-edit.ts +9 -5
  172. package/src/hooks/use-data-source-edit.ts +2 -2
  173. package/src/hooks/use-stage.ts +26 -9
  174. package/src/index.ts +8 -0
  175. package/src/initService.ts +1 -1
  176. package/src/layouts/CodeEditor.vue +17 -5
  177. package/src/layouts/Framework.vue +11 -6
  178. package/src/layouts/NavMenu.vue +12 -3
  179. package/src/layouts/history-list/Bucket.vue +91 -0
  180. package/src/layouts/history-list/BucketTab.vue +72 -0
  181. package/src/layouts/history-list/GroupRow.vue +304 -0
  182. package/src/layouts/history-list/HistoryDiffDialog.vue +281 -0
  183. package/src/layouts/history-list/HistoryListPanel.vue +367 -0
  184. package/src/layouts/history-list/InitialRow.vue +71 -0
  185. package/src/layouts/history-list/PageTab.vue +118 -0
  186. package/src/layouts/history-list/composables.ts +309 -0
  187. package/src/layouts/history-list/useHistoryList.ts +60 -0
  188. package/src/layouts/history-list/useHistoryRevert.ts +421 -0
  189. package/src/layouts/page-bar/PageBar.vue +4 -2
  190. package/src/layouts/props-panel/PropsPanel.vue +5 -1
  191. package/src/layouts/sidebar/ComponentListPanel.vue +9 -5
  192. package/src/layouts/sidebar/Sidebar.vue +8 -3
  193. package/src/layouts/sidebar/code-block/CodeBlockList.vue +5 -5
  194. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +1 -1
  195. package/src/layouts/sidebar/code-block/useContentMenu.ts +1 -1
  196. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +31 -2
  197. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +27 -2
  198. package/src/layouts/sidebar/data-source/useContentMenu.ts +1 -1
  199. package/src/layouts/sidebar/layer/LayerMenu.vue +19 -11
  200. package/src/layouts/sidebar/layer/LayerNodeTool.vue +7 -4
  201. package/src/layouts/sidebar/layer/use-node-status.ts +9 -6
  202. package/src/layouts/workspace/viewer/Stage.vue +1 -1
  203. package/src/layouts/workspace/viewer/ViewerMenu.vue +8 -8
  204. package/src/services/BaseService.ts +35 -86
  205. package/src/services/codeBlock.ts +361 -5
  206. package/src/services/dataSource.ts +336 -6
  207. package/src/services/dep.ts +32 -9
  208. package/src/services/editor.ts +834 -194
  209. package/src/services/history.ts +509 -49
  210. package/src/services/keybinding.ts +3 -3
  211. package/src/services/props.ts +2 -2
  212. package/src/services/ui.ts +7 -0
  213. package/src/theme/history-list-panel.scss +557 -0
  214. package/src/theme/page-bar.scss +0 -4
  215. package/src/theme/props-panel.scss +3 -3
  216. package/src/theme/style-setter/border.scss +4 -1
  217. package/src/theme/theme.scss +1 -0
  218. package/src/type.ts +613 -31
  219. package/src/utils/code-block.ts +150 -0
  220. package/src/utils/content-menu.ts +25 -13
  221. package/src/utils/data-source/index.ts +2 -0
  222. package/src/utils/dep/worker.ts +5 -3
  223. package/src/utils/editor.ts +166 -60
  224. package/src/utils/history.ts +286 -0
  225. package/src/utils/index.ts +3 -0
  226. package/src/utils/indexed-db.ts +122 -0
  227. package/src/utils/undo-redo.ts +111 -0
  228. package/types/index.d.ts +3197 -896
  229. package/dist/es/utils/compose.js +0 -44
  230. package/dist/es/utils/editor-history.js +0 -100
  231. package/src/utils/compose.ts +0 -52
  232. package/src/utils/editor-history.ts +0 -138
package/src/type.ts CHANGED
@@ -16,14 +16,24 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import type { Component } from 'vue';
19
+ import type { AppContext, Component } from 'vue';
20
20
  import type EventEmitter from 'events';
21
21
  import type * as Monaco from 'monaco-editor';
22
22
  import type { default as Sortable, Options, SortableEvent } from 'sortablejs';
23
23
  import type { PascalCasedProperties, Writable } from 'type-fest';
24
24
 
25
- import type { CodeBlockContent, CodeBlockDSL, Id, MApp, MContainer, MNode, MPage, MPageFragment } from '@tmagic/core';
26
- import type { ChangeRecord, FormConfig, TableColumnConfig, TypeFunction } from '@tmagic/form';
25
+ import type {
26
+ CodeBlockContent,
27
+ CodeBlockDSL,
28
+ DataSourceSchema,
29
+ Id,
30
+ MApp,
31
+ MContainer,
32
+ MNode,
33
+ MPage,
34
+ MPageFragment,
35
+ } from '@tmagic/core';
36
+ import type { ChangeRecord, FormConfig, FormState, TableColumnConfig, TypeFunction } from '@tmagic/form';
27
37
  import type StageCore from '@tmagic/stage';
28
38
  import type {
29
39
  CanDropIn,
@@ -46,7 +56,7 @@ import type { PropsService } from './services/props';
46
56
  import type { StageOverlayService } from './services/stageOverlay';
47
57
  import type { StorageService } from './services/storage';
48
58
  import type { UiService } from './services/ui';
49
- import type { UndoRedo } from './utils/undo-redo';
59
+ import type { SerializedUndoRedo, UndoRedo } from './utils/undo-redo';
50
60
 
51
61
  export type EditorSlots = FrameworkSlots &
52
62
  WorkspaceSlots &
@@ -138,7 +148,7 @@ export interface EditorInstallOptions {
138
148
  customCreateMonacoDiffEditor: (
139
149
  monaco: typeof import('monaco-editor'),
140
150
  codeEditorEl: HTMLElement,
141
- options: Monaco.editor.IStandaloneEditorConstructionOptions & { editorCustomType?: string },
151
+ options: Monaco.editor.IStandaloneDiffEditorConstructionOptions & { editorCustomType?: string },
142
152
  ) => Promise<Monaco.editor.IStandaloneDiffEditor> | Monaco.editor.IStandaloneDiffEditor;
143
153
  [key: string]: any;
144
154
  }
@@ -189,6 +199,11 @@ export interface StageOptions {
189
199
  */
190
200
  alwaysMultiSelect?: boolean;
191
201
  disabledRule?: boolean;
202
+ /**
203
+ * 禁用「非点击画布选中组件时(如从图层树、面包屑等外部选中),对选中区域做高亮闪烁提示」,
204
+ * 默认 false(即默认开启闪烁)
205
+ */
206
+ disabledFlashTip?: boolean;
192
207
  zoom?: number;
193
208
  /** 画布双击前的钩子函数,返回 false 则阻止默认的双击行为 */
194
209
  beforeDblclick?: (event: MouseEvent) => Promise<boolean | void> | boolean | void;
@@ -297,6 +312,8 @@ export interface UiState {
297
312
  hideSlideBar: boolean;
298
313
  /** 侧边栏面板配置 */
299
314
  sideBarItems: SideComponent[];
315
+ /** 当前激活的侧边栏面板 */
316
+ sideBarActiveTabName: string;
300
317
 
301
318
  // navMenu 的宽高
302
319
  navMenuRect: {
@@ -318,6 +335,7 @@ export interface EditorNodeInfo {
318
335
  node: MNode | null;
319
336
  parent: MContainer | null;
320
337
  page: MPage | MPageFragment | null;
338
+ path: MNode[];
321
339
  }
322
340
  // #endregion EditorNodeInfo
323
341
 
@@ -375,6 +393,9 @@ export interface MenuButton {
375
393
  items?: MenuButton[];
376
394
  /** 唯一标识,用于高亮 */
377
395
  id?: string | number;
396
+ buttonProps?: {
397
+ type?: string;
398
+ };
378
399
  }
379
400
  // #endregion MenuButton
380
401
 
@@ -407,6 +428,7 @@ export interface MenuComponent {
407
428
  * 'rule': 显示隐藏标尺
408
429
  * 'scale-to-original': 缩放到实际大小
409
430
  * 'scale-to-fit': 缩放以适应
431
+ * 'history-list': 历史记录面板(按 页面 / 数据源 / 代码块 三个 tab 展示,相邻同目标修改自动合并)
410
432
  */
411
433
  // #region MenuItem
412
434
  export type MenuItem =
@@ -421,6 +443,7 @@ export type MenuItem =
421
443
  | 'rule'
422
444
  | 'scale-to-original'
423
445
  | 'scale-to-fit'
446
+ | 'history-list'
424
447
  | MenuButton
425
448
  | MenuComponent
426
449
  | string;
@@ -463,6 +486,63 @@ export interface SideComponent extends MenuComponent {
463
486
  }
464
487
  // #endregion SideComponent
465
488
 
489
+ // #region HistoryListExtraTab
490
+ /**
491
+ * 历史记录面板(HistoryListPanel)的自定义扩展 tab。
492
+ *
493
+ * 业务方可通过 Editor 的 `historyListExtraTabs` 注入额外的历史记录 tab,
494
+ * 例如某个自定义模块维护自己的操作历史时,可以在历史记录面板中增加一个
495
+ * 独立的 tab 来展示与回滚。内置的「页面 / 数据源 / 代码块」三个 tab 之后
496
+ * 会依次追加这些扩展 tab。
497
+ */
498
+ export interface HistoryListExtraTab {
499
+ /** tab 唯一标识,作为 TMagicTabs 的 name */
500
+ name: string;
501
+ /** tab 显示文案,支持传入函数以展示动态内容(如记录数量) */
502
+ label: string | (() => string);
503
+ /** tab 内容区渲染的组件(Vue 组件或字符串标签) */
504
+ component: any;
505
+ /** 传入内容组件的 props */
506
+ props?: Record<string, any>;
507
+ /** 内容组件的事件监听 */
508
+ listeners?: Record<string, (..._args: any[]) => any>;
509
+ }
510
+ // #endregion HistoryListExtraTab
511
+
512
+ // #region CompareForm
513
+ /**
514
+ * 对比表单(CompareForm)的对比类型:
515
+ * - node: 节点组件,按 `type` 从 propsService 获取属性表单配置
516
+ * - data-source: 数据源,按 `type`(base/http/...) 从 dataSourceService 获取数据源表单配置
517
+ * - code-block: 数据源代码块,使用内置的代码块表单配置
518
+ */
519
+ export type CompareCategory = 'node' | 'data-source' | 'code-block' | string;
520
+
521
+ /**
522
+ * 自定义 `loadConfig` 时回传的上下文,聚合了组件当前的对比入参,
523
+ * 方便调用方在外部按需拼装 FormConfig。
524
+ */
525
+ export interface CompareFormLoadConfigContext {
526
+ /** 对比类型,见 CompareCategory */
527
+ category: string;
528
+ /** 节点 / 数据源类型 */
529
+ type?: string;
530
+ /** 数据源代码块场景下的数据源类型 */
531
+ dataSourceType?: string;
532
+ /**
533
+ * 内置的默认 FormConfig 加载逻辑(按 `category` 从 propsService / dataSourceService /
534
+ * 代码块工具取配置)。自定义 `loadConfig` 可调用它复用默认结果,再做二次加工。
535
+ */
536
+ defaultLoadConfig: () => Promise<FormConfig>;
537
+ }
538
+
539
+ /**
540
+ * 自定义 FormConfig 加载逻辑。传入后将接管内置的按 `category` 取配置逻辑,
541
+ * 可通过 `ctx.defaultLoadConfig()` 复用默认结果再做二次加工。
542
+ */
543
+ export type CompareFormLoadConfig = (ctx: CompareFormLoadConfigContext) => FormConfig | Promise<FormConfig>;
544
+ // #endregion CompareForm
545
+
466
546
  // #region SideItemKey
467
547
  export enum SideItemKey {
468
548
  COMPONENT_LIST = 'component-list',
@@ -606,38 +686,328 @@ export interface CodeParamStatement {
606
686
  }
607
687
 
608
688
  // #region HistoryOpType
609
- export type HistoryOpType = 'add' | 'remove' | 'update';
689
+ /**
690
+ * 历史记录操作类型:
691
+ * - `add` / `remove` / `update`:普通可撤销/重做的节点变更;
692
+ * - `initial`:页面「未修改的初始状态」基线(设置 root 时生成),作为页面栈 index 0 的固定底线 step。
693
+ * 该 step 不可被撤销/回滚(cursor 不会低于它),仅用于历史面板底部的初始行展示。
694
+ */
695
+ export type HistoryOpType = 'add' | 'remove' | 'update' | 'initial';
610
696
  // #endregion HistoryOpType
611
697
 
612
- // #region StepValue
613
- export interface StepValue {
614
- /** 页面信息 */
698
+ // #region HistoryOpSource
699
+ /**
700
+ * 历史记录的「操作途径」——标记本次变更由哪条交互入口触发,仅用于历史面板展示 / 业务埋点,
701
+ * 不影响 undo/redo 行为。缺省(未传)时 UI 视为「未知」。
702
+ *
703
+ * - `stage`:画布(拖拽 / 缩放 / 排序等舞台直接操作)
704
+ * - `tree`:树形面板(图层 / 数据源 / 代码块等树形结构里的拖拽 / 菜单操作)
705
+ * - `component-panel`:组件面板(左侧组件列表点击 / 拖拽新增组件)
706
+ * - `props`:配置面板表单(属性表单字段编辑)
707
+ * - `code`:源码编辑器(配置面板「源码」面板里直接编辑 JSON/代码后保存)
708
+ * - `stage-contextmenu`:画布右键菜单(舞台上节点的右键上下文菜单)
709
+ * - `tree-contextmenu`:树面板右键菜单(图层 / 数据源 / 代码块等树形列表上的右键上下文菜单)
710
+ * - `toolbar`:工具栏菜单(顶部导航工具栏按钮)
711
+ * - `shortcut`:键盘快捷键
712
+ * - `rollback`:历史回滚(历史面板里对某条历史「回滚」,反向应用为一条新记录,类 git revert)
713
+ * - `api`:代码 / 接口调用(程序化触发)
714
+ * - `ai`:AI 生成 / 智能助手触发的变更
715
+ * - `unknown`:未知来源
716
+ *
717
+ * 通过 `(string & {})` 允许业务侧扩展自定义途径字符串,同时保留内置值的自动补全。
718
+ */
719
+ export type HistoryOpSource =
720
+ | 'initial'
721
+ | 'stage'
722
+ | 'tree'
723
+ | 'component-panel'
724
+ | 'props'
725
+ | 'code'
726
+ | 'root-code'
727
+ | 'stage-contextmenu'
728
+ | 'tree-contextmenu'
729
+ | 'toolbar'
730
+ | 'shortcut'
731
+ | 'rollback'
732
+ | 'api'
733
+ | 'ai'
734
+ // 同步
735
+ | 'sync'
736
+ | 'unknown'
737
+ | (string & {});
738
+ // #endregion HistoryOpSource
739
+
740
+ // #region DslOpWithHistoryIdsResult
741
+ /** *AndGetHistoryId 系列方法返回值:原操作结果 + 本次写入历史记录的 uuid 列表(未入栈时为 `[]`)。 */
742
+ export type DslOpWithHistoryIdsResult<T> = {
743
+ result: T;
744
+ historyIds: string[];
745
+ };
746
+ // #endregion DslOpWithHistoryIdsResult
747
+
748
+ // #region StepDiffItem
749
+ /**
750
+ * 单条变更的 diff 描述,统一表达「页面节点 / 代码块 / 数据源」的变化内容,
751
+ * 被 {@link StepValue} / {@link CodeBlockStepValue} / {@link DataSourceStepValue} 的 `diff` 复用。
752
+ *
753
+ * 按 `opType` 区分携带的字段:
754
+ * - `add`:仅 `newSchema`(页面节点还带 `parentId` / `index`);
755
+ * - `remove`:仅 `oldSchema`(页面节点还带 `parentId` / `index`);
756
+ * - `update`:`oldSchema` + `newSchema`,并可带 `changeRecords` 做局部更新。
757
+ *
758
+ * 泛型 `T` 为变化内容的快照类型:页面节点为 `MNode`,代码块为 `CodeBlockContent`,数据源为 `DataSourceSchema`。
759
+ */
760
+ export interface StepDiffItem<T = unknown> {
761
+ /** 变更后的内容快照。`opType` 为 `add` / `update` 时有,`remove` 时无。 */
762
+ newSchema?: T;
763
+ /** 变更前的内容快照。`opType` 为 `remove` / `update` 时有,`add` 时无。 */
764
+ oldSchema?: T;
765
+ /** 父节点 id。仅页面节点有(数据源 / 代码块没有父节点)。 */
766
+ parentId?: Id;
767
+ /** 在父节点 items 数组中的索引。仅页面节点有(数据源 / 代码块无需排序)。 */
768
+ index?: number;
769
+ /**
770
+ * form 端 propPath/value 变更列表,仅 `opType` 为 `update` 时有;
771
+ * 撤销/重做时若有则按 propPath 局部更新,缺省才退化为整内容替换。
772
+ */
773
+ changeRecords?: ChangeRecord[];
774
+ }
775
+ // #endregion StepDiffItem
776
+
777
+ // #region BaseStepValue
778
+ /**
779
+ * 历史记录条目公共字段,被 {@link StepValue} / {@link CodeBlockStepValue} / {@link DataSourceStepValue} 复用。
780
+ *
781
+ * 泛型 `T` 为 `diff` 中变化内容的快照类型(页面节点 `MNode` / 代码块 `CodeBlockContent` / 数据源 `DataSourceSchema`)。
782
+ */
783
+ export interface BaseStepValue<T = unknown, U extends Record<string, any> = {}> {
784
+ /**
785
+ * 历史记录唯一标识(uuid)。入栈时自动写入(若调用方未指定),
786
+ * 用于精确定位 / 引用某一条历史记录(如 revert、埋点、跨端同步等)。
787
+ * 注意与 `data.id`(关联的页面 / 代码块 / 数据源 id)区分。
788
+ */
789
+ uuid: string;
790
+ /**
791
+ * 关联目标信息:`id` 为关联的页面 / 代码块 / 数据源等资源 id(也是历史栈的分组 key),
792
+ * `name` 为展示名。所有历史类型统一携带。
793
+ */
615
794
  data: { name: string; id: Id };
795
+ /** 操作类型:新增 / 删除 / 更新(三类历史记录统一携带)。 */
616
796
  opType: HistoryOpType;
617
- /** 操作前选中的节点 ID,用于撤销后恢复选择状态 */
618
- selectedBefore: Id[];
619
- /** 操作后选中的节点 ID,用于重做后恢复选择状态 */
620
- selectedAfter: Id[];
621
- modifiedNodeIds: Map<Id, Id>;
622
- /** opType 'add': 新增的节点 */
623
- nodes?: MNode[];
624
- /** opType 'add': 父节点 ID */
625
- parentId?: Id;
626
- /** opType 'add': 每个新增节点在父节点 items 中的索引 */
627
- indexMap?: Record<string, number>;
628
- /** opType 'remove': 被删除的节点及其位置信息 */
629
- removedItems?: { node: MNode; parentId: Id; index: number }[];
630
- /** opType 'update': 变更前后的节点快照 */
631
- updatedItems?: { oldNode: MNode; newNode: MNode }[];
797
+ /**
798
+ * 本次变更的内容(统一 diff 表达),每项见 {@link StepDiffItem}。
799
+ * 页面节点(add/remove 多节点、update 多节点)会有多项,代码块 / 数据源通常只有一项。
800
+ */
801
+ diff: StepDiffItem<T>[];
802
+ /**
803
+ * 调用方可选传入的人类可读描述(如「调整按钮颜色」),用于历史面板展示。
804
+ * 不影响 undo/redo 行为;缺省时面板会根据节点 / propPath 自动生成描述。
805
+ */
806
+ historyDescription?: string;
807
+ /**
808
+ * 操作途径:标记本次变更由哪条交互入口触发,取值见 {@link HistoryOpSource}
809
+ * (画布 / 树面板 / 组件面板 / 配置面板 / 源码编辑器 / 右键菜单 / 工具栏 / 快捷键 / 回滚 / 接口 等)。
810
+ * 仅用于历史面板展示与业务埋点,不影响 undo/redo 行为;缺省时面板视为「未知」。
811
+ */
812
+ source?: HistoryOpSource;
813
+ /**
814
+ * 入栈时间戳(毫秒)。入栈时自动写入(若调用方未指定),仅用于历史面板展示。
815
+ */
816
+ timestamp?: number;
817
+ /**
818
+ * 是否为「已保存」记录:DSL 落库(如保存到后端 / 本地)时由 historyService.markSaved 标记。
819
+ * 同一栈内任意时刻最多只有一条记录为 true;从 IndexedDB 恢复时游标会被定位到最近一条已保存记录之后。
820
+ */
821
+ saved?: boolean;
822
+ /**
823
+ * 是否为「整体设置 root」(set root)产生的记录(由 {@link Editor.pushRootDiffHistory} 写入)。
824
+ * 用于「连续 set root 合并」:当某页栈最新一条已是 root 记录时,下一条 set root 会替换它而非新增,
825
+ * 避免源码反复保存 / 外部重设 DSL 时堆积多条 root 记录。
826
+ */
827
+ rootStep?: boolean;
828
+ /** 操作人 */
829
+ operator?: string;
830
+ /** 扩展信息 */
831
+ extra?: U;
832
+ }
833
+ // #endregion BaseStepValue
834
+
835
+ // #region StepExtra
836
+ /**
837
+ * 历史记录的扩展上下文({@link BaseStepValue.extra})。
838
+ * 内置字段供 `page` 类型在撤销 / 重做时恢复选区与受影响节点;扩展类型可自由附加其它键。
839
+ */
840
+ export interface StepExtra {
841
+ /** 操作前选中的节点 ID,用于撤销后恢复选择状态(page 类型) */
842
+ selectedBefore?: Id[];
843
+ /** 操作后选中的节点 ID,用于重做后恢复选择状态(page 类型) */
844
+ selectedAfter?: Id[];
845
+ /** 本次操作涉及的节点 id 集合(page 类型) */
846
+ modifiedNodeIds?: Map<Id, Id>;
847
+ [key: string]: any;
632
848
  }
849
+ // #endregion StepExtra
850
+
851
+ // #region StepValue
852
+ /**
853
+ * 页面节点历史记录条目(`diff` 内容为 {@link MNode})。结构已与代码块 / 数据源统一收敛到
854
+ * {@link BaseStepValue}:关联 id 见 `data.id`,选区等上下文见 `extra`。
855
+ */
856
+ export type StepValue = BaseStepValue<MNode, StepExtra>;
633
857
  // #endregion StepValue
634
858
 
859
+ // #region CodeBlockStepValue
860
+ /**
861
+ * 代码块历史记录条目(`diff` 内容为 {@link CodeBlockContent}),按 `data.id`(codeBlock.id)
862
+ * 分组保存到 historyState.steps.codeBlock。结构与 {@link StepValue} / {@link DataSourceStepValue}
863
+ * 一致,仅 `diff` 快照类型不同。
864
+ */
865
+ export type CodeBlockStepValue = BaseStepValue<CodeBlockContent>;
866
+ // #endregion CodeBlockStepValue
867
+
868
+ // #region DataSourceStepValue
869
+ /**
870
+ * 数据源历史记录条目(`diff` 内容为 {@link DataSourceSchema}),按 `data.id`(dataSource.id)
871
+ * 分组保存到 historyState.steps.dataSource。结构与 {@link StepValue} / {@link CodeBlockStepValue}
872
+ * 一致,仅 `diff` 快照类型不同。
873
+ */
874
+ export type DataSourceStepValue = BaseStepValue<DataSourceSchema>;
875
+ // #endregion DataSourceStepValue
876
+
877
+ // #region HistorySteps
878
+ /**
879
+ * 历史记录类型标识:内置 `page` / `codeBlock` / `dataSource`,并允许业务扩展自定义类型。
880
+ * `(string & {})` 保留对内置字面量的智能提示,同时不限制扩展取值。
881
+ */
882
+ export type HistoryStepType = 'page' | 'codeBlock' | 'dataSource' | (string & {});
883
+
884
+ /**
885
+ * 全部历史栈的统一容器,按「类型 -> id -> UndoRedo 栈」两级分组。
886
+ *
887
+ * - `page`:页面历史栈,按 page.id 分组(每页一份 UndoRedo);
888
+ * - `codeBlock`:代码块历史栈,按 codeBlock.id 分组;
889
+ * - `dataSource`:数据源历史栈,按 dataSource.id 分组;
890
+ * - 其余键:业务通过 {@link HistoryService.registerStepType} 注册的自定义历史类型。
891
+ *
892
+ * 所有类型(含扩展类型)一视同仁:均按 id 独立分栈、独立 undo/redo,且都可通过
893
+ * {@link HistoryService.setMarker} 在 index 0 种入 `initial` 基线(撤销 / 回滚不会越过该基线)。
894
+ */
895
+ export interface HistorySteps {
896
+ page: Record<Id, UndoRedo<StepValue>>;
897
+ codeBlock: Record<Id, UndoRedo<CodeBlockStepValue>>;
898
+ dataSource: Record<Id, UndoRedo<DataSourceStepValue>>;
899
+ /** 扩展历史类型:按 id 分组的 UndoRedo 栈。 */
900
+ [stepType: string]: Record<Id, UndoRedo<any>>;
901
+ }
902
+ // #endregion HistorySteps
903
+
635
904
  export interface HistoryState {
636
- pageId?: Id;
637
- pageSteps: Record<Id, UndoRedo<StepValue>>;
638
- canRedo: boolean;
639
- canUndo: boolean;
905
+ /**
906
+ * 全部历史栈的统一容器(页面 / 代码块 / 数据源 / 扩展类型),见 {@link HistorySteps}。
907
+ * 各类型互不影响,支持按 id 独立 undo/redo;是否可撤销 / 重做改用 {@link HistoryService.canUndo} /
908
+ * {@link HistoryService.canRedo}(按 stepType + id 查询)替代旧的全局 canUndo / canRedo 字段。
909
+ */
910
+ steps: HistorySteps;
911
+ /**
912
+ * 各历史类型的展示名称,用于历史面板({@link HistorySteps} 的 tab / 分组标题等)。
913
+ * 内置 `page` / `codeBlock` / `dataSource` 有默认中文名(页面 / 代码块 / 数据源),
914
+ * 扩展类型可通过 {@link HistoryService.registerStepType} 的 `name` 选项或
915
+ * {@link HistoryService.setStepName} 登记;读取请用 {@link HistoryService.getStepName}。
916
+ */
917
+ stepNames: Record<string, string>;
918
+ }
919
+
920
+ // #region PersistedHistoryState
921
+ /**
922
+ * 历史记录的可持久化快照。由 historyService.saveToIndexedDB 写入 IndexedDB,
923
+ * 再由 historyService.restoreFromIndexedDB 读出并重建各 UndoRedo 栈。
924
+ */
925
+ export interface PersistedHistoryState {
926
+ /** 快照结构版本号,便于后续兼容升级。 */
927
+ version: number;
928
+ /**
929
+ * 全部历史栈的序列化快照,按「类型 -> id」两级分组,与 {@link HistorySteps} 对应。
930
+ * 内置 `page` / `codeBlock` / `dataSource`,并包含业务注册的扩展类型。
931
+ */
932
+ steps: {
933
+ page: Record<Id, SerializedUndoRedo<StepValue>>;
934
+ codeBlock: Record<Id, SerializedUndoRedo<CodeBlockStepValue>>;
935
+ dataSource: Record<Id, SerializedUndoRedo<DataSourceStepValue>>;
936
+ [stepType: string]: Record<Id, SerializedUndoRedo<any>>;
937
+ };
938
+ /** 保存时间戳(毫秒)。 */
939
+ savedAt: number;
940
+ }
941
+ // #endregion PersistedHistoryState
942
+
943
+ // #region HistoryPersistOptions
944
+ /** historyService 持久化相关 API 的可选配置。 */
945
+ export interface HistoryPersistOptions {
946
+ /** IndexedDB 数据库名,默认 `tmagic-editor`(最终库名会拼上当前 DSL app id)。 */
947
+ dbName?: string;
948
+ /** objectStore 名,默认 `history`。 */
949
+ storeName?: string;
950
+ /** 记录 key,用于区分不同活动页 / 项目,默认 `default`。 */
951
+ key?: IDBValidKey;
952
+ /**
953
+ * 显式指定用于库名隔离的 DSL app id。
954
+ * 缺省时回退到当前 editorService 的 `root.id`;在「先恢复历史再 set root」场景下 root 尚未设置,
955
+ * 需由调用方(如从待加载 DSL 取 id)显式传入,否则会读 / 写到未按 app 隔离的默认库。
956
+ */
957
+ appId?: Id;
958
+ }
959
+ // #endregion HistoryPersistOptions
960
+
961
+ // #region HistoryListEntry
962
+ /**
963
+ * 历史面板用:当前页面的一条历史步骤(包含位置和是否已应用)。
964
+ */
965
+ export interface HistoryStepEntry<T> {
966
+ /** 步骤内容 */
967
+ step: T;
968
+ /** 在所属栈中的索引(0 为最早) */
969
+ index: number;
970
+ /** 是否处于"已应用"段(即位于栈游标之前)。撤销后变为 false。 */
971
+ applied: boolean;
972
+ /** 是否为当前所在的步骤(栈中最近一次已应用的那一步,即 index === cursor - 1)。 */
973
+ isCurrent?: boolean;
974
+ }
975
+
976
+ /**
977
+ * 历史面板分组(页面 / 数据源 / 代码块 / 扩展类型统一结构)。
978
+ *
979
+ * 把指定历史栈的步骤列表按"目标"做相邻合并:
980
+ * - 连续修改同一目标(单实体 update,targetId 一致)的多步合并成一组,组内可展开查看每步;
981
+ * - add / remove / 多实体 update 始终独立成组(无法明确归属单一目标);
982
+ * - targetId 为 undefined 表示"无明确目标",不参与合并。
983
+ *
984
+ * 各类型仅 `kind` 与 step 快照类型不同,统一由泛型描述:
985
+ * - 页面:`HistoryGroup<StepValue>`,`kind: 'page'`,`id` 为 pageId,`targetId` 为被改节点 id;
986
+ * - 数据源:`HistoryGroup<DataSourceStepValue>`,`kind: 'data-source'`,`id` 为 dataSource.id;
987
+ * - 代码块:`HistoryGroup<CodeBlockStepValue>`,`kind: 'code-block'`,`id` 为 codeBlock.id。
988
+ */
989
+ export interface HistoryGroup<T extends BaseStepValue = BaseStepValue> {
990
+ /** 历史类型标识:page / code-block / data-source(扩展类型同理)。 */
991
+ kind: string;
992
+ /** 所属栈 id(page 为 pageId,代码块 / 数据源为对应资源 id)。 */
993
+ id: Id;
994
+ /** 该分组的操作类型。 */
995
+ opType: HistoryOpType;
996
+ /**
997
+ * 合并的目标 id:仅"单实体 update"有值,并按此与相邻同 id 的 update 合并。
998
+ * undefined 表示该分组不可被合并(add / remove / 多实体 update)。
999
+ */
1000
+ targetId?: Id;
1001
+ /** 目标可读名(取最后一步快照的 name/type/id)。 */
1002
+ targetName?: string;
1003
+ /** 组内所有步骤,按时间正序。 */
1004
+ steps: { step: T; index: number; applied: boolean; isCurrent?: boolean }[];
1005
+ /** 组内最后一步是否已应用。 */
1006
+ applied: boolean;
1007
+ /** 是否为当前所在的分组(包含栈中最近一次已应用步骤的那一组)。 */
1008
+ isCurrent?: boolean;
640
1009
  }
1010
+ // #endregion HistoryListEntry
641
1011
 
642
1012
  export enum KeyBindingCommand {
643
1013
  /** 复制 */
@@ -801,6 +1171,8 @@ export type SyncHookPlugin<
801
1171
 
802
1172
  export interface EventBusEvent {
803
1173
  'edit-data-source': [id: string];
1174
+ 'edit-data-source-method': [id: string, methodName: string];
1175
+ 'edit-data-source-field': [id: string, fieldPath: string[]];
804
1176
  'remove-data-source': [id: string];
805
1177
  'edit-code': [id: string];
806
1178
  }
@@ -834,7 +1206,11 @@ export type CustomContentMenuFunction = (
834
1206
  ) => (MenuButton | MenuComponent)[];
835
1207
 
836
1208
  export interface EditorEvents {
837
- 'root-change': [value: StoreState['root'], preValue?: StoreState['root']];
1209
+ 'root-change': [
1210
+ value: StoreState['root'],
1211
+ preValue?: StoreState['root'],
1212
+ options?: { historySource?: HistoryOpSource },
1213
+ ];
838
1214
  select: [node: MNode | null];
839
1215
  add: [nodes: MNode[]];
840
1216
  remove: [nodes: MNode[]];
@@ -842,6 +1218,54 @@ export interface EditorEvents {
842
1218
  'move-layer': [offset: number | LayerOffset];
843
1219
  'drag-to': [data: { targetIndex: number; configs: MNode | MNode[]; targetParent: MContainer }];
844
1220
  'history-change': [data: MPage | MPageFragment];
1221
+ /**
1222
+ * DSL 发生变更后统一触发,免去分别监听 add / remove / update / move-layer / drag-to。
1223
+ * 回调参数为 {@link EditorChangeEvent},按 `type` 区分操作类型并携带各自的操作内容(payload)
1224
+ * 以及变更所在的当前 page(可能为 null)。撤销 / 重做内部同样会经由
1225
+ * add / remove / update 触发本事件;如需区分「用户操作」与「撤销重做」请配合 `history-change`。
1226
+ */
1227
+ change: [event: EditorChangeEvent];
1228
+ }
1229
+
1230
+ // #region EditorChangeEvent
1231
+ /** `change` 事件中单个变更项:变更的 node 及其所属的 page(可能为 null)。 */
1232
+ export interface EditorChangeItem {
1233
+ node: MNode;
1234
+ page: StoreState['page'];
1235
+ }
1236
+
1237
+ /** `update` 类型变更项:node 为前后快照及 form 端变更记录,page 为其所属页面。 */
1238
+ export interface EditorUpdateChangeItem {
1239
+ node: { newNode: MNode; oldNode: MNode; changeRecords?: ChangeRecord[] };
1240
+ page: StoreState['page'];
1241
+ }
1242
+
1243
+ /**
1244
+ * {@link EditorEvents.change} 的回调参数:以 `type` 区分操作类型,并携带对应的操作内容。
1245
+ * `data` 为本次变更的节点列表,每项包含 node 及其所属的 page(可能为 null);
1246
+ * `move-layer` 额外带层级偏移 `offset`,`drag-to` 额外带目标位置 `targetIndex` / `targetParent`。
1247
+ */
1248
+ export type EditorChangeEvent =
1249
+ | { type: 'add'; data: EditorChangeItem[] }
1250
+ | { type: 'remove'; data: EditorChangeItem[] }
1251
+ | { type: 'update'; data: EditorUpdateChangeItem[] }
1252
+ | { type: 'move-layer'; data: EditorChangeItem[]; offset: number | LayerOffset }
1253
+ | { type: 'drag-to'; data: EditorChangeItem[]; targetIndex: number; targetParent: MContainer };
1254
+ // #endregion EditorChangeEvent
1255
+
1256
+ export interface HistoryEvents {
1257
+ change: [
1258
+ state: BaseStepValue | StepValue | CodeBlockStepValue | DataSourceStepValue,
1259
+ stepType: HistoryStepType,
1260
+ id: Id,
1261
+ ];
1262
+ 'code-block-history-change': [id: Id, state: CodeBlockStepValue];
1263
+ 'data-source-history-change': [id: Id, state: DataSourceStepValue];
1264
+ 'restore-from-indexed-db': [snapshot: PersistedHistoryState | null];
1265
+ 'save-to-indexed-db': [snapshot: PersistedHistoryState];
1266
+ 'mark-saved': [{ kind: HistoryStepType; id?: Id }];
1267
+ clear: [{ id: Id; stepType: HistoryStepType }];
1268
+ 'marker-change': [{ id: Id; marker: StepValue; stepType: HistoryStepType }];
845
1269
  }
846
1270
 
847
1271
  export const canUsePluginMethods = {
@@ -874,12 +1298,170 @@ export const canUsePluginMethods = {
874
1298
 
875
1299
  export type AsyncMethodName = Writable<(typeof canUsePluginMethods)['async']>;
876
1300
 
1301
+ // #region HistoryOpOptions
1302
+ /**
1303
+ * 历史记录写入相关的通用配置(codeBlock / dataSource / editor 共用)
1304
+ * - doNotPushHistory: 操作完成后是否不要将本次操作压入历史栈(撤销/重做记录),默认 false
1305
+ * - historyDescription: 入栈时附带的人类可读描述,用于历史面板展示;不影响 undo/redo 行为,缺省时面板会自动生成描述
1306
+ * - historySource: 操作途径,取值见 {@link HistoryOpSource}(画布 / 树面板 / 组件面板 / 配置面板 / 源码编辑器 / 右键菜单 / 工具栏 / 快捷键 / 回滚 / 接口 等),用于历史面板展示与埋点;不影响 undo/redo 行为
1307
+ */
1308
+ export interface HistoryOpOptions {
1309
+ doNotPushHistory?: boolean;
1310
+ historyDescription?: string;
1311
+ historySource?: HistoryOpSource;
1312
+ }
1313
+ // #endregion HistoryOpOptions
1314
+
1315
+ // #region HistoryOpOptionsWithChangeRecords
1316
+ /**
1317
+ * 在 HistoryOpOptions 基础上携带 form 端 propPath/value 变更记录,
1318
+ * 用于历史记录的精细化撤销/重做(按 propPath 局部 patch)。
1319
+ */
1320
+ export interface HistoryOpOptionsWithChangeRecords extends HistoryOpOptions {
1321
+ changeRecords?: ChangeRecord[];
1322
+ }
1323
+ // #endregion HistoryOpOptionsWithChangeRecords
1324
+
1325
+ // #region DslOpOptions
877
1326
  /**
878
1327
  * DSL 修改类操作的通用配置
879
1328
  * - doNotSelect: 操作后是否不要自动触发选中(不调用 this.select / this.multiSelect / stage.select / stage.multiSelect)
880
1329
  * - doNotSwitchPage: 操作若会引发当前页面切换(如新增 / 删除 / 跨页移动),是否跳过这次切换
881
1330
  */
882
- export type DslOpOptions = {
1331
+ export interface DslOpOptions extends HistoryOpOptions {
883
1332
  doNotSelect?: boolean;
884
1333
  doNotSwitchPage?: boolean;
885
- };
1334
+ }
1335
+ // #endregion DslOpOptions
1336
+
1337
+ /** 差异对话框的入参 */
1338
+ export interface DiffDialogPayload {
1339
+ /** 表单类别 */
1340
+ category?: CompareCategory;
1341
+ /** 节点类型 / 数据源类型 */
1342
+ type?: string;
1343
+ /** 代码块场景下的数据源类型 */
1344
+ dataSourceType?: string;
1345
+ /** 该 step 修改前的值(oldNode / oldSchema / oldContent) */
1346
+ lastValue: Record<string, any>;
1347
+ /** 该 step 修改后的值(newNode / newSchema / newContent) */
1348
+ value: Record<string, any>;
1349
+ /** 当前编辑器中实际的最新值;不传或为 null 时禁用「与当前对比」 */
1350
+ currentValue?: Record<string, any> | null;
1351
+ /** 用于标题展示的目标名称 */
1352
+ targetLabel?: string;
1353
+ /** 用于标题展示的目标 id */
1354
+ id?: string | number;
1355
+ /**
1356
+ * 指定打开时的初始对比模式:
1357
+ * - before:该步骤修改前 vs 修改后
1358
+ * - current:该步骤修改后 vs 当前最新值
1359
+ * 不传时按是否存在「修改后的值」/「当前值」自动推断。
1360
+ * 若指定的模式当前不可用(对应数据缺失),将回退到自动推断结果。
1361
+ */
1362
+ mode?: 'before' | 'current';
1363
+ }
1364
+
1365
+ /**
1366
+ * 一组「描述 + 可操作性」的判定函数集合。页面 / 数据源 / 代码块及业务自定义历史
1367
+ * 各自实现一份,作为整体注入,避免把 describe* / isStep* 拆成多个独立 props 反复透传。
1368
+ */
1369
+ export interface HistoryRowDescriptor<T extends BaseStepValue = BaseStepValue> {
1370
+ /**
1371
+ * 组级描述文案生成器,接收一个 group,返回展示文本。
1372
+ * 不传时回退到对组内最后一步调用 {@link describeStep}(适用于不做相邻合并、每组恒为单步的历史,如数据源/代码块)。
1373
+ */
1374
+ describeGroup?: (_group: any) => string;
1375
+ /** 单步描述文案生成器,接收一个 step,返回展示文本(合并组展开后的子步列表用)。 */
1376
+ describeStep: (_step: T) => string;
1377
+ /** 判断某个 step 是否可查看差异(前后值都存在)。不传则一律不展示差异入口。 */
1378
+ isStepDiffable?: (_step: T) => boolean;
1379
+ /** 判断某个 step 是否支持回滚(如更新需带 changeRecords)。不传则已应用即可回滚。 */
1380
+ isStepRevertable?: (_step: T) => boolean;
1381
+ }
1382
+
1383
+ /**
1384
+ * 通用 bucket(数据源 / 代码块 / 业务自定义历史)的整体渲染配置。
1385
+ * 把原先散落在 Bucket / BucketTab 上的 title / prefix / describe* / isStep* / showInitial / gotoEnabled
1386
+ * 收敛成一个对象作为单一 prop 传递,调用方一次配齐、组件内部按需读取。
1387
+ */
1388
+ export interface HistoryBucketConfig<T extends BaseStepValue = BaseStepValue> extends HistoryRowDescriptor<T> {
1389
+ /** bucket 头部标题,例如 "数据源" / "代码块"。 */
1390
+ title: string;
1391
+ /** 子项 key 的命名空间前缀(`ds` 数据源 / `cb` 代码块 / 业务自定义如 `mod`)。 */
1392
+ prefix: string;
1393
+ /** 是否展示底部「回到初始状态」入口,默认 true。无 undo cursor 语义的自定义历史可传 false。 */
1394
+ showInitial?: boolean;
1395
+ /** 是否支持「跳转到该记录」(goto),默认 true。 */
1396
+ gotoEnabled?: boolean;
1397
+ /** 是否展示顶部「清空」按钮,默认 true。无需提供清空能力的自定义历史可传 false。 */
1398
+ showClear?: boolean;
1399
+ }
1400
+
1401
+ export interface UseHistoryRevertOptions {
1402
+ /**
1403
+ * 父级应用上下文,用于让动态挂载的「差异确认弹窗」继承全局组件 / 指令 / provide / 插件
1404
+ * (Element Plus、@tmagic/form 字段组件等)。未显式传入时,会自动取调用方所在组件的 appContext
1405
+ * (`getCurrentInstance()?.appContext`)。业务方若在组件 setup 之外调用,需手动传入(如 `editorApp._context`)。
1406
+ */
1407
+ appContext?: AppContext | null;
1408
+ /**
1409
+ * 透传给差异确认弹窗的 `extendState`(即 Editor 的 `extendFormState`),
1410
+ * 使对比表单中依赖业务上下文的 `display` / `disabled` 等 filterFunction 正常工作。
1411
+ */
1412
+ extendState?: (_state: FormState) => Record<string, any> | Promise<Record<string, any>>;
1413
+ /**
1414
+ * 返回 PropsPanel 主属性表单(FormPanel -> MForm)的 formState。
1415
+ * 仅页面历史「查看差异 / 回滚确认」场景会使用该 formState 覆盖 CompareForm 中同名扩展字段,
1416
+ * 以保证两处 filterFunction 读取到一致的运行态上下文。
1417
+ */
1418
+ getPropsPanelFormState?: () => FormState | undefined;
1419
+ /**
1420
+ * 内置页面 / 数据源 / 代码块的差异 / 回滚确认弹窗默认宽度(透传给 TMagicDialog 的 `width`),
1421
+ * 如 `'1200px'` / `'80%'`。缺省时使用弹窗内置默认宽度(900px)。
1422
+ * 业务自有历史(`viewDiff` / `confirmAndRevert`)可在调用时通过各自入参的 `width` 单独覆盖。
1423
+ */
1424
+ dialogWidth?: string;
1425
+ }
1426
+
1427
+ /**
1428
+ * 业务自有历史(如管理台「模块」)做差异对比时所需的额外渲染入参。
1429
+ * 内置的页面 / 数据源 / 代码块按 `category` 自动取表单配置,无需传这些;
1430
+ * 业务自有类别可通过 `loadConfig` 注入自定义表单配置加载逻辑。
1431
+ */
1432
+ export interface CustomDiffFormOptions {
1433
+ /**
1434
+ * 自定义差异表单配置加载逻辑(如「模块」按 c_type 重建表单配置),
1435
+ * 透传给弹窗内部的 CompareForm;缺省时按 `category` 走内置加载。
1436
+ */
1437
+ loadConfig?: CompareFormLoadConfig;
1438
+ /** 需要走 self diff 的字段类型(如模块的 mod-cond)。 */
1439
+ selfDiffFieldTypes?: string[];
1440
+ /**
1441
+ * 可选:外部提供的 formState(通常来自 PropsPanel 主表单),
1442
+ * 对比弹窗会用它覆盖 CompareForm 中同名扩展字段,避免上下文不一致。
1443
+ */
1444
+ compareFormState?: FormState;
1445
+ /**
1446
+ * 差异 / 确认回滚弹窗宽度(透传给 HistoryDiffDialog 的 TMagicDialog `width`),
1447
+ * 如 `'1200px'` / `'80%'`。缺省时使用弹窗内置默认宽度(900px)。
1448
+ */
1449
+ width?: string;
1450
+ }
1451
+
1452
+ /**
1453
+ * 业务自有历史复用「单步回滚」交互({@link useHistoryRevert} 的 `confirmAndRevert`)的入参。
1454
+ * 与内置页面 / 数据源 / 代码块回滚共用「目标校验 → 差异/二次确认弹窗 → 反向回滚」流程,
1455
+ * 业务方只需提供:差异弹窗入参(可选)、表单配置加载(可选)、实际回滚执行函数。
1456
+ */
1457
+ export interface ConfirmAndRevertOptions<T = unknown> extends CustomDiffFormOptions {
1458
+ /**
1459
+ * 差异确认弹窗入参;可对比的步骤(单实体 update)传入后弹差异确认弹窗,
1460
+ * 传 null / 省略则退化为普通二次确认框(add / remove / 不可对比)。
1461
+ */
1462
+ diffPayload?: DiffDialogPayload | null;
1463
+ /** 回滚前置校验:返回 true 表示目标数据已删除等不可回滚,给出统一提示并中止。 */
1464
+ isTargetMissing?: () => boolean;
1465
+ /** 用户确认后执行的实际回滚逻辑。 */
1466
+ revert: () => T | Promise<T>;
1467
+ }