@tmagic/editor 1.5.3 → 1.5.4

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 (36) hide show
  1. package/dist/tmagic-editor.js +454 -446
  2. package/dist/tmagic-editor.umd.cjs +453 -445
  3. package/package.json +7 -7
  4. package/src/components/CodeBlockEditor.vue +3 -3
  5. package/src/components/CodeParams.vue +2 -2
  6. package/src/components/ContentMenu.vue +13 -13
  7. package/src/components/FloatingBox.vue +9 -9
  8. package/src/components/Resizer.vue +2 -2
  9. package/src/components/ScrollBar.vue +6 -7
  10. package/src/components/ScrollViewer.vue +6 -6
  11. package/src/components/SplitView.vue +2 -2
  12. package/src/fields/DataSourceInput.vue +3 -3
  13. package/src/fields/DataSourceMethods.vue +4 -4
  14. package/src/hooks/use-code-block-edit.ts +5 -5
  15. package/src/initService.ts +104 -66
  16. package/src/layouts/CodeEditor.vue +6 -6
  17. package/src/layouts/Framework.vue +5 -5
  18. package/src/layouts/NavMenu.vue +6 -3
  19. package/src/layouts/page-bar/PageBar.vue +13 -13
  20. package/src/layouts/page-bar/PageBarScrollContainer.vue +12 -11
  21. package/src/layouts/props-panel/FormPanel.vue +6 -6
  22. package/src/layouts/props-panel/PropsPanel.vue +4 -2
  23. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +3 -3
  24. package/src/layouts/sidebar/layer/LayerMenu.vue +2 -2
  25. package/src/layouts/sidebar/layer/LayerPanel.vue +5 -4
  26. package/src/layouts/sidebar/layer/use-click.ts +4 -6
  27. package/src/layouts/workspace/viewer/NodeListMenu.vue +5 -5
  28. package/src/layouts/workspace/viewer/Stage.vue +13 -13
  29. package/src/layouts/workspace/viewer/StageOverlay.vue +2 -2
  30. package/src/layouts/workspace/viewer/ViewerMenu.vue +3 -3
  31. package/src/services/componentList.ts +2 -2
  32. package/src/services/dep.ts +8 -2
  33. package/src/services/stageOverlay.ts +2 -2
  34. package/src/services/ui.ts +2 -2
  35. package/src/utils/idle-task.ts +26 -10
  36. package/types/index.d.ts +7 -60
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.5.3",
2
+ "version": "1.5.4",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -58,11 +58,11 @@
58
58
  "moveable": "^0.53.0",
59
59
  "serialize-javascript": "^6.0.0",
60
60
  "sortablejs": "^1.15.2",
61
- "@tmagic/design": "1.5.3",
62
- "@tmagic/form": "1.5.3",
63
- "@tmagic/table": "1.5.3",
64
- "@tmagic/stage": "1.5.3",
65
- "@tmagic/utils": "1.5.3"
61
+ "@tmagic/design": "1.5.4",
62
+ "@tmagic/stage": "1.5.4",
63
+ "@tmagic/form": "1.5.4",
64
+ "@tmagic/table": "1.5.4",
65
+ "@tmagic/utils": "1.5.4"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@types/events": "^3.0.0",
@@ -83,7 +83,7 @@
83
83
  "monaco-editor": "^0.48.0",
84
84
  "typescript": "*",
85
85
  "vue": ">=3.5.0",
86
- "@tmagic/core": "1.5.3"
86
+ "@tmagic/core": "1.5.4"
87
87
  },
88
88
  "peerDependenciesMeta": {
89
89
  "typescript": {
@@ -104,14 +104,14 @@ const { height: codeBlockEditorHeight } = useEditorContentHeight();
104
104
  const difVisible = ref(false);
105
105
  const { rect: windowRect } = useWindowRect();
106
106
 
107
- const magicVsEditor = useTemplateRef<InstanceType<typeof CodeEditor>>('magicVsEditor');
107
+ const magicVsEditorRef = useTemplateRef<InstanceType<typeof CodeEditor>>('magicVsEditor');
108
108
 
109
109
  const diffChange = () => {
110
- if (!magicVsEditor.value || !formBox.value?.form) {
110
+ if (!magicVsEditorRef.value || !formBox.value?.form) {
111
111
  return;
112
112
  }
113
113
 
114
- formBox.value.form.values.content = magicVsEditor.value.getEditorValue();
114
+ formBox.value.form.values.content = magicVsEditorRef.value.getEditorValue();
115
115
 
116
116
  difVisible.value = false;
117
117
  };
@@ -32,7 +32,7 @@ const props = defineProps<{
32
32
 
33
33
  const emit = defineEmits(['change']);
34
34
 
35
- const form = useTemplateRef<InstanceType<typeof MForm>>('form');
35
+ const formRef = useTemplateRef<InstanceType<typeof MForm>>('form');
36
36
 
37
37
  const getFormConfig = (items: FormConfig = []) => [
38
38
  {
@@ -61,7 +61,7 @@ const codeParamsConfig = computed(() =>
61
61
  */
62
62
  const onParamsChangeHandler = async (v: FormValue, eventData: ContainerChangeEventData) => {
63
63
  try {
64
- const value = await form.value?.submitForm(true);
64
+ const value = await formRef.value?.submitForm(true);
65
65
  emit('change', value, eventData);
66
66
  } catch (e) {
67
67
  error(e);
@@ -69,9 +69,9 @@ const emit = defineEmits<{
69
69
  mouseenter: [];
70
70
  }>();
71
71
 
72
- const menu = useTemplateRef<HTMLDivElement>('menu');
73
- const buttons = useTemplateRef<InstanceType<typeof ToolButton>[]>('buttons');
74
- const subMenu = useTemplateRef<any>('subMenu');
72
+ const menuEl = useTemplateRef<HTMLDivElement>('menu');
73
+ const buttonRefs = useTemplateRef<InstanceType<typeof ToolButton>[]>('buttons');
74
+ const subMenuRef = useTemplateRef<any>('subMenu');
75
75
  const visible = ref(false);
76
76
  const subMenuData = ref<(MenuButton | MenuComponent)[]>([]);
77
77
  const zIndex = useZIndex();
@@ -88,13 +88,13 @@ const menuStyle = computed(() => ({
88
88
  zIndex: curZIndex.value,
89
89
  }));
90
90
 
91
- const contains = (el: HTMLElement) => menu.value?.contains(el) || subMenu.value?.contains(el);
91
+ const contains = (el: HTMLElement) => menuEl.value?.contains(el) || subMenuRef.value?.contains(el);
92
92
 
93
93
  const hide = () => {
94
94
  if (!visible.value) return;
95
95
 
96
96
  visible.value = false;
97
- subMenu.value?.hide();
97
+ subMenuRef.value?.hide();
98
98
 
99
99
  emit('hide');
100
100
  };
@@ -121,7 +121,7 @@ const outsideClickHideHandler = (e: MouseEvent) => {
121
121
  };
122
122
 
123
123
  const setPosition = (e: { clientY: number; clientX: number }) => {
124
- const menuHeight = menu.value?.clientHeight || 0;
124
+ const menuHeight = menuEl.value?.clientHeight || 0;
125
125
 
126
126
  let top = e.clientY;
127
127
  if (menuHeight + e.clientY > document.body.clientHeight) {
@@ -158,15 +158,15 @@ const showSubMenu = (item: MenuButton | MenuComponent, index: number) => {
158
158
  return;
159
159
  }
160
160
 
161
- if (menu.value) {
161
+ if (menuEl.value) {
162
162
  // 将子菜单放置在按钮右侧,与按钮齐平
163
- let y = menu.value.offsetTop;
164
- if (buttons.value?.[index].$el) {
165
- const rect = buttons.value?.[index].$el.getBoundingClientRect();
163
+ let y = menuEl.value.offsetTop;
164
+ if (buttonRefs.value?.[index].$el) {
165
+ const rect = buttonRefs.value?.[index].$el.getBoundingClientRect();
166
166
  y = rect.top;
167
167
  }
168
- subMenu.value?.show({
169
- clientX: menu.value.offsetLeft + menu.value.clientWidth - 2,
168
+ subMenuRef.value?.show({
169
+ clientX: menuEl.value.offsetLeft + menuEl.value.clientWidth - 2,
170
170
  clientY: y,
171
171
  });
172
172
  }
@@ -190,7 +190,7 @@ onBeforeUnmount(() => {
190
190
  });
191
191
 
192
192
  defineExpose({
193
- menu,
193
+ menu: menuEl,
194
194
  menuPosition,
195
195
  hide,
196
196
  show,
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <Teleport to="body" v-if="visible">
3
3
  <div ref="target" class="m-editor-float-box" :style="{ ...style, zIndex: curZIndex }" @mousedown="nextZIndex">
4
- <div ref="titleEl" class="m-editor-float-box-title">
4
+ <div ref="title" class="m-editor-float-box-title">
5
5
  <slot name="title">
6
6
  <span>{{ title }}</span>
7
7
  </slot>
@@ -47,8 +47,8 @@ const props = withDefaults(
47
47
  },
48
48
  );
49
49
 
50
- const target = useTemplateRef<HTMLDivElement>('target');
51
- const titleEl = useTemplateRef<HTMLDivElement>('titleEl');
50
+ const targetEl = useTemplateRef<HTMLDivElement>('target');
51
+ const titleEl = useTemplateRef<HTMLDivElement>('title');
52
52
 
53
53
  const zIndex = useZIndex();
54
54
  const curZIndex = ref<number>(0);
@@ -59,8 +59,8 @@ const bodyHeight = computed(() => {
59
59
  return height.value - titleHeight.value;
60
60
  }
61
61
 
62
- if (target.value) {
63
- return target.value.clientHeight - titleHeight.value;
62
+ if (targetEl.value) {
63
+ return targetEl.value.clientHeight - titleHeight.value;
64
64
  }
65
65
 
66
66
  return 'auto';
@@ -87,7 +87,7 @@ let moveable: VanillaMoveable | null = null;
87
87
  const initMoveable = () => {
88
88
  moveable = new VanillaMoveable(globalThis.document.body, {
89
89
  className: 'm-editor-floating-box-moveable',
90
- target: target.value,
90
+ target: targetEl.value,
91
91
  draggable: true,
92
92
  resizable: true,
93
93
  edge: true,
@@ -126,7 +126,7 @@ watch(
126
126
  await nextTick();
127
127
  curZIndex.value = zIndex.nextZIndex();
128
128
 
129
- const targetRect = target.value?.getBoundingClientRect();
129
+ const targetRect = targetEl.value?.getBoundingClientRect();
130
130
  if (targetRect) {
131
131
  width.value = targetRect.width;
132
132
  height.value = targetRect.height;
@@ -168,11 +168,11 @@ const nextZIndex = () => {
168
168
  curZIndex.value = zIndex.nextZIndex();
169
169
  };
170
170
 
171
- provide('parentFloating', target);
171
+ provide('parentFloating', targetEl);
172
172
 
173
173
  defineExpose({
174
174
  bodyHeight,
175
- target,
175
+ target: targetEl,
176
176
  titleEl,
177
177
  });
178
178
  </script>
@@ -18,6 +18,6 @@ const emit = defineEmits<{
18
18
  change: [e: OnDrag];
19
19
  }>();
20
20
 
21
- const target = useTemplateRef<HTMLSpanElement>('target');
22
- const { isDragging } = useGetSo(target, emit);
21
+ const targetEl = useTemplateRef<HTMLSpanElement>('target');
22
+ const { isDragging } = useGetSo(targetEl, emit);
23
23
  </script>
@@ -21,8 +21,8 @@ const props = defineProps<{
21
21
 
22
22
  const emit = defineEmits(['scroll']);
23
23
 
24
- const bar = useTemplateRef<HTMLDivElement>('bar');
25
- const thumb = useTemplateRef<HTMLDivElement>('thumb');
24
+ const barEl = useTemplateRef<HTMLDivElement>('bar');
25
+ const thumbEl = useTemplateRef<HTMLDivElement>('thumb');
26
26
 
27
27
  const thumbSize = computed(() => props.size * (props.size / props.scrollSize));
28
28
  const thumbPos = computed(() => (props.pos / props.scrollSize) * props.size);
@@ -35,9 +35,8 @@ const thumbStyle = computed(() => ({
35
35
  let gesto: Gesto;
36
36
 
37
37
  onMounted(() => {
38
- if (!thumb.value) return;
39
- const thumbEl = thumb.value;
40
- gesto = new Gesto(thumbEl, {
38
+ if (!thumbEl.value) return;
39
+ gesto = new Gesto(thumbEl.value, {
41
40
  container: window,
42
41
  });
43
42
 
@@ -50,12 +49,12 @@ onMounted(() => {
50
49
  scrollBy(getDelta(e));
51
50
  });
52
51
 
53
- bar.value?.addEventListener('wheel', wheelHandler, false);
52
+ barEl.value?.addEventListener('wheel', wheelHandler, false);
54
53
  });
55
54
 
56
55
  onBeforeUnmount(() => {
57
56
  if (gesto) gesto.off();
58
- bar.value?.removeEventListener('wheel', wheelHandler, false);
57
+ barEl.value?.removeEventListener('wheel', wheelHandler, false);
59
58
  });
60
59
 
61
60
  const wheelHandler = (e: WheelEvent) => {
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="m-editor-scroll-viewer-container" ref="container">
3
- <div ref="el" :style="style">
3
+ <div ref="target" :style="style">
4
4
  <slot></slot>
5
5
  </div>
6
6
 
@@ -63,8 +63,8 @@ const props = withDefaults(
63
63
  },
64
64
  );
65
65
 
66
- const container = useTemplateRef<HTMLDivElement>('container');
67
- const el = useTemplateRef<HTMLDivElement>('el');
66
+ const containerEl = useTemplateRef<HTMLDivElement>('container');
67
+ const el = useTemplateRef<HTMLDivElement>('target');
68
68
  const style = computed(
69
69
  () => `
70
70
  width: ${isNumber(`${props.width}`) ? `${props.width}px` : props.width};
@@ -80,9 +80,9 @@ const scrollHeight = ref(0);
80
80
  let scrollViewer: ScrollViewer;
81
81
 
82
82
  onMounted(() => {
83
- if (!container.value || !el.value) return;
83
+ if (!containerEl.value || !el.value) return;
84
84
  scrollViewer = new ScrollViewer({
85
- container: container.value,
85
+ container: containerEl.value,
86
86
  target: el.value,
87
87
  zoom: props.zoom,
88
88
  correctionScrollSize: props.correctionScrollSize,
@@ -123,6 +123,6 @@ const hScrollHandler = (delta: number) => {
123
123
  };
124
124
 
125
125
  defineExpose({
126
- container,
126
+ container: containerEl,
127
127
  });
128
128
  </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div ref="el" class="m-editor-layout" :style="`min-width: ${props.minCenter + props.minLeft + props.minRight}px`">
2
+ <div ref="target" class="m-editor-layout" :style="`min-width: ${props.minCenter + props.minLeft + props.minRight}px`">
3
3
  <template v-if="hasLeft && $slots.left">
4
4
  <div class="m-editor-layout-left" :class="leftClass" :style="`width: ${left}px`">
5
5
  <slot name="left"></slot>
@@ -51,7 +51,7 @@ const props = withDefaults(
51
51
  },
52
52
  );
53
53
 
54
- const el = useTemplateRef<HTMLElement>('el');
54
+ const el = useTemplateRef<HTMLElement>('target');
55
55
 
56
56
  const hasLeft = computed(() => typeof props.left !== 'undefined');
57
57
  const hasRight = computed(() => typeof props.right !== 'undefined');
@@ -83,12 +83,12 @@ const emit = defineEmits<{
83
83
 
84
84
  const { dataSourceService } = inject<Services>('services') || {};
85
85
 
86
- const autocomplete = useTemplateRef<InstanceType<typeof TMagicAutocomplete>>('autocomplete');
86
+ const autocompleteRef = useTemplateRef<InstanceType<typeof TMagicAutocomplete>>('autocomplete');
87
87
  const isFocused = ref(false);
88
88
  const state = ref('');
89
89
  const displayState = ref<{ value: string; type: 'var' | 'text' }[]>([]);
90
90
 
91
- const input = computed<HTMLInputElement>(() => autocomplete.value?.inputRef?.input);
91
+ const input = computed<HTMLInputElement>(() => autocompleteRef.value?.inputRef?.input);
92
92
  const dataSources = computed(() => dataSourceService?.get('dataSources') || []);
93
93
 
94
94
  const setDisplayState = () => {
@@ -112,7 +112,7 @@ const mouseupHandler = async () => {
112
112
 
113
113
  isFocused.value = true;
114
114
  await nextTick();
115
- autocomplete.value?.focus();
115
+ autocompleteRef.value?.focus();
116
116
 
117
117
  if (focusOffset && input.value) {
118
118
  input.value.setSelectionRange(anchorOffset, focusOffset);
@@ -51,7 +51,7 @@ const props = withDefaults(
51
51
  const emit = defineEmits(['change']);
52
52
 
53
53
  const codeConfig = ref<CodeBlockContent>();
54
- const codeBlockEditor = useTemplateRef<InstanceType<typeof CodeBlockEditor>>('codeBlockEditor');
54
+ const codeBlockEditorRef = useTemplateRef<InstanceType<typeof CodeBlockEditor>>('codeBlockEditor');
55
55
 
56
56
  let editIndex = -1;
57
57
 
@@ -94,7 +94,7 @@ const methodColumns: ColumnConfig[] = [
94
94
  editIndex = index;
95
95
 
96
96
  nextTick(() => {
97
- codeBlockEditor.value?.show();
97
+ codeBlockEditorRef.value?.show();
98
98
  });
99
99
  },
100
100
  },
@@ -121,7 +121,7 @@ const createCodeHandler = () => {
121
121
  editIndex = -1;
122
122
 
123
123
  nextTick(() => {
124
- codeBlockEditor.value?.show();
124
+ codeBlockEditorRef.value?.show();
125
125
  });
126
126
  };
127
127
 
@@ -157,6 +157,6 @@ const submitCodeHandler = (value: CodeBlockContent, data: ContainerChangeEventDa
157
157
  editIndex = -1;
158
158
  codeConfig.value = void 0;
159
159
 
160
- codeBlockEditor.value?.hide();
160
+ codeBlockEditorRef.value?.hide();
161
161
  };
162
162
  </script>
@@ -10,7 +10,7 @@ import type { CodeBlockService } from '@editor/services/codeBlock';
10
10
  export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
11
11
  const codeConfig = ref<CodeBlockContent>();
12
12
  const codeId = ref<string>();
13
- const codeBlockEditor = useTemplateRef<InstanceType<typeof CodeBlockEditor>>('codeBlockEditor');
13
+ const codeBlockEditorRef = useTemplateRef<InstanceType<typeof CodeBlockEditor>>('codeBlockEditor');
14
14
 
15
15
  // 新增代码块
16
16
  const createCodeBlock = async () => {
@@ -29,7 +29,7 @@ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
29
29
 
30
30
  await nextTick();
31
31
 
32
- codeBlockEditor.value?.show();
32
+ codeBlockEditorRef.value?.show();
33
33
  };
34
34
 
35
35
  // 编辑代码块
@@ -54,7 +54,7 @@ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
54
54
  codeId.value = id;
55
55
 
56
56
  await nextTick();
57
- codeBlockEditor.value?.show();
57
+ codeBlockEditorRef.value?.show();
58
58
  };
59
59
 
60
60
  // 删除代码块
@@ -67,13 +67,13 @@ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
67
67
 
68
68
  await codeBlockService?.setCodeDslById(codeId.value, values);
69
69
 
70
- codeBlockEditor.value?.hide();
70
+ codeBlockEditorRef.value?.hide();
71
71
  };
72
72
 
73
73
  return {
74
74
  codeId,
75
75
  codeConfig,
76
- codeBlockEditor,
76
+ codeBlockEditor: codeBlockEditorRef,
77
77
 
78
78
  createCodeBlock,
79
79
  editCode,
@@ -1,6 +1,7 @@
1
1
  import { computed, onBeforeUnmount, reactive, toRaw, watch } from 'vue';
2
2
  import { cloneDeep } from 'lodash-es';
3
3
 
4
+ import type TMagicCore from '@tmagic/core';
4
5
  import type {
5
6
  CodeBlockContent,
6
7
  DataSourceSchema,
@@ -263,67 +264,46 @@ export const initServiceEvents = (
263
264
 
264
265
  if (!node) return;
265
266
 
266
- collectIdle([node], true).then(() => {
267
- afterUpdateNodes([node]);
268
- });
267
+ collectIdle([node], true);
268
+ updateStage([node]);
269
269
  });
270
270
  });
271
271
 
272
- const getApp = () => stage.value?.renderer?.runtime?.getApp?.();
273
-
274
- const updateDataSourceSchema = (nodes: MNode[], deep: boolean) => {
275
- const root = editorService.get('root');
276
- const app = getApp();
277
-
278
- if (root && app?.dsl) {
279
- app.dsl.dataSourceDeps = root.dataSourceDeps;
280
- app.dsl.dataSourceCondDeps = root.dataSourceCondDeps;
281
- app.dsl.dataSources = root.dataSources;
272
+ const getApp = () => {
273
+ const renderer = stage.value?.renderer;
274
+ if (!renderer) {
275
+ return undefined;
282
276
  }
283
277
 
284
- if (root?.dataSources) {
285
- getApp()?.dataSourceManager?.updateSchema(root.dataSources);
278
+ if (renderer.runtime) {
279
+ return renderer.runtime.getApp?.();
286
280
  }
287
281
 
288
- if (!root || !stage.value) return;
282
+ return new Promise<TMagicCore | undefined>((resolve) => {
283
+ const timeout = globalThis.setTimeout(() => {
284
+ resolve(undefined);
285
+ }, 10000);
289
286
 
290
- const allNodes: MNode[] = [];
291
-
292
- if (deep) {
293
- nodes.forEach((node) => {
294
- traverseNode<MNode>(node, (node) => {
295
- if (!allNodes.includes(node)) {
296
- allNodes.push(node);
297
- }
298
- });
299
- });
300
- } else {
301
- allNodes.push(...nodes);
302
- }
303
-
304
- const deps = Object.values(root.dataSourceDeps || {});
305
- deps.forEach((dep) => {
306
- Object.keys(dep).forEach((id) => {
307
- const node = allNodes.find((node) => node.id === id);
308
- node &&
309
- stage.value?.update({
310
- config: cloneDeep(node),
311
- parentId: editorService.getParentById(node.id)?.id,
312
- root: cloneDeep(root),
313
- });
287
+ renderer.on('runtime-ready', () => {
288
+ if (timeout) {
289
+ globalThis.clearTimeout(timeout);
290
+ }
291
+ resolve(renderer.runtime?.getApp?.());
314
292
  });
315
293
  });
316
294
  };
317
295
 
318
- const afterUpdateNodes = (nodes: MNode[]) => {
296
+ const updateDataSourceSchema = async () => {
319
297
  const root = editorService.get('root');
320
- if (!root) return;
321
- for (const node of nodes) {
322
- stage.value?.update({
323
- config: cloneDeep(node),
324
- parentId: editorService.getParentById(node.id)?.id,
325
- root: cloneDeep(root),
326
- });
298
+ const app = await getApp();
299
+
300
+ if (root && app?.dsl) {
301
+ app.dsl.dataSourceDeps = root.dataSourceDeps;
302
+ app.dsl.dataSources = root.dataSources;
303
+ }
304
+
305
+ if (root?.dataSources) {
306
+ app?.dataSourceManager?.updateSchema(root.dataSources);
327
307
  }
328
308
  };
329
309
 
@@ -360,18 +340,72 @@ export const initServiceEvents = (
360
340
  }
361
341
  };
362
342
 
363
- const depCollectedHandler = () => {
343
+ /**
344
+ * 修改dsl后会执行依赖收集并调用此方法
345
+ * 所以这个方法是会被执行两次,当时updateStage应当时一次,所以通过inDeps参数来区分调用时机
346
+ * inDeps为true是则更新依赖收集到的节点,否则则更新没有依赖的节点
347
+ * @param nodes 需要更新的节点
348
+ * @param inDeps 是否依赖收集完成事件中执行的
349
+ * @returns
350
+ */
351
+ const updateStage = (nodes: MNode[], inDeps = false) => {
364
352
  const root = editorService.get('root');
365
353
  if (!root) return;
366
- const app = getApp();
354
+
355
+ const update = (node: MNode) =>
356
+ stage.value?.update({
357
+ config: cloneDeep(node),
358
+ parentId: editorService.getParentById(node.id)?.id,
359
+ root: cloneDeep(root),
360
+ });
361
+
362
+ nodes.forEach((node) => {
363
+ const inDepsNodeId: Id[] = [];
364
+ const deps = Object.values(root.dataSourceDeps || {});
365
+ deps.forEach((dep) => {
366
+ Object.keys(dep).forEach((id) => {
367
+ inDepsNodeId.push(id);
368
+ });
369
+ });
370
+
371
+ if (inDeps) {
372
+ if (inDepsNodeId.includes(node.id)) {
373
+ update(node);
374
+ }
375
+ } else {
376
+ if (!inDepsNodeId.includes(node.id)) {
377
+ update(node);
378
+ }
379
+ }
380
+ });
381
+ };
382
+
383
+ const dsDepCollectedHandler = async (nodes: MNode[], deep: boolean) => {
384
+ const root = editorService.get('root');
385
+ if (!root) return;
386
+ const app = await getApp();
367
387
  if (app?.dsl) {
368
388
  app.dsl.dataSourceDeps = root.dataSourceDeps;
369
389
  }
390
+ if (deep) {
391
+ nodes.forEach((node) => {
392
+ traverseNode<MNode>(
393
+ node,
394
+ (node) => {
395
+ updateStage([node], true);
396
+ },
397
+ [],
398
+ true,
399
+ );
400
+ });
401
+ } else {
402
+ updateStage(nodes, true);
403
+ }
370
404
  };
371
405
 
372
406
  depService.on('add-target', targetAddHandler);
373
407
  depService.on('remove-target', targetRemoveHandler);
374
- depService.on('collected', depCollectedHandler);
408
+ depService.on('ds-collected', dsDepCollectedHandler);
375
409
 
376
410
  const initDataSourceDepTarget = (ds: DataSourceSchema) => {
377
411
  depService.addTarget(createDataSourceTarget(ds, reactive({})));
@@ -396,9 +430,9 @@ export const initServiceEvents = (
396
430
 
397
431
  // 新增节点,收集依赖
398
432
  const nodeAddHandler = (nodes: MNode[]) => {
399
- collectIdle(nodes, true).then(() => {
400
- afterUpdateNodes(nodes);
401
- });
433
+ collectIdle(nodes, true);
434
+
435
+ updateStage(nodes);
402
436
  };
403
437
 
404
438
  // 节点更新,收集依赖
@@ -430,11 +464,10 @@ export const initServiceEvents = (
430
464
  });
431
465
 
432
466
  if (needRecollectNodes.length) {
433
- collectIdle(needRecollectNodes, true).then(() => {
434
- afterUpdateNodes(needRecollectNodes);
435
- });
467
+ collectIdle(needRecollectNodes, true);
468
+ updateStage(needRecollectNodes);
436
469
  } else if (normalNodes.length) {
437
- afterUpdateNodes(normalNodes);
470
+ updateStage(normalNodes);
438
471
  }
439
472
  };
440
473
 
@@ -446,7 +479,7 @@ export const initServiceEvents = (
446
479
  // 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖
447
480
  const historyChangeHandler = (page: MPage | MPageFragment) => {
448
481
  collectIdle([page], true).then(() => {
449
- updateDataSourceSchema([page], true);
482
+ updateDataSourceSchema();
450
483
  });
451
484
  };
452
485
 
@@ -472,12 +505,16 @@ export const initServiceEvents = (
472
505
  codeBlockService.on('addOrUpdate', codeBlockAddOrUpdateHandler);
473
506
  codeBlockService.on('remove', codeBlockRemoveHandler);
474
507
 
475
- const dataSourceAddHandler = (config: DataSourceSchema) => {
508
+ const dataSourceAddHandler = async (config: DataSourceSchema) => {
476
509
  initDataSourceDepTarget(config);
477
- getApp()?.dataSourceManager?.addDataSource(config);
510
+ const app = await getApp();
511
+ app?.dataSourceManager?.addDataSource(config);
478
512
  };
479
513
 
480
- const dataSourceUpdateHandler = (config: DataSourceSchema, { changeRecords }: { changeRecords: ChangeRecord[] }) => {
514
+ const dataSourceUpdateHandler = async (
515
+ config: DataSourceSchema,
516
+ { changeRecords }: { changeRecords: ChangeRecord[] },
517
+ ) => {
481
518
  let needRecollectDep = false;
482
519
  for (const changeRecord of changeRecords) {
483
520
  if (!changeRecord.propPath) {
@@ -506,11 +543,12 @@ export const initServiceEvents = (
506
543
  initDataSourceDepTarget(config);
507
544
 
508
545
  collectIdle(root.items, true).then(() => {
509
- updateDataSourceSchema(root?.items || [], true);
546
+ updateDataSourceSchema();
510
547
  });
511
548
  }
512
549
  } else if (root?.dataSources) {
513
- getApp()?.dataSourceManager?.updateSchema(root.dataSources);
550
+ const app = await getApp();
551
+ app?.dataSourceManager?.updateSchema(root.dataSources);
514
552
  }
515
553
  };
516
554
 
@@ -525,7 +563,7 @@ export const initServiceEvents = (
525
563
  const nodeIds = Object.keys(root?.dataSourceDeps?.[id] || {});
526
564
  const nodes = getNodes(nodeIds, root?.items);
527
565
  collectIdle(nodes, false).then(() => {
528
- updateDataSourceSchema(nodes, false);
566
+ updateDataSourceSchema();
529
567
  });
530
568
 
531
569
  removeDataSourceTarget(id);
@@ -538,7 +576,7 @@ export const initServiceEvents = (
538
576
  onBeforeUnmount(() => {
539
577
  depService.off('add-target', targetAddHandler);
540
578
  depService.off('remove-target', targetRemoveHandler);
541
- depService.off('collected', depCollectedHandler);
579
+ depService.off('ds-collected', dsDepCollectedHandler);
542
580
 
543
581
  editorService.off('history-change', historyChangeHandler);
544
582
  editorService.off('root-change', rootChangeHandler);