@tmagic/editor 1.5.3 → 1.5.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.
Files changed (36) hide show
  1. package/dist/tmagic-editor.js +601 -565
  2. package/dist/tmagic-editor.umd.cjs +600 -564
  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 +289 -220
  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 +10 -4
  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
@@ -1,13 +1,14 @@
1
- import { computed, onBeforeUnmount, reactive, toRaw, watch } from 'vue';
1
+ import { 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,
7
8
  EventOption,
8
9
  Id,
9
10
  MApp,
10
- MNode,
11
+ MComponent,
11
12
  MPage,
12
13
  MPageFragment,
13
14
  } from '@tmagic/core';
@@ -21,7 +22,7 @@ import {
21
22
  Target,
22
23
  } from '@tmagic/core';
23
24
  import { ChangeRecord } from '@tmagic/form';
24
- import { getNodes, isPage, isValueIncludeDataSource, traverseNode } from '@tmagic/utils';
25
+ import { getNodes, isPage, isValueIncludeDataSource } from '@tmagic/utils';
25
26
 
26
27
  import PropsPanel from './layouts/PropsPanel.vue';
27
28
  import { isIncludeDataSource } from './utils/editor';
@@ -105,11 +106,12 @@ export const initServiceState = (
105
106
  const eventsList: Record<string, EventOption[]> = {};
106
107
  const methodsList: Record<string, EventOption[]> = {};
107
108
 
108
- eventMethodList &&
109
- Object.keys(eventMethodList).forEach((type: string) => {
109
+ if (eventMethodList) {
110
+ for (const type of Object.keys(eventMethodList)) {
110
111
  eventsList[type] = eventMethodList[type].events;
111
112
  methodsList[type] = eventMethodList[type].methods;
112
- });
113
+ }
114
+ }
113
115
 
114
116
  eventsService.setEvents(eventsList);
115
117
  eventsService.setMethods(methodsList);
@@ -122,10 +124,13 @@ export const initServiceState = (
122
124
  watch(
123
125
  () => props.datasourceConfigs,
124
126
  (configs) => {
125
- configs &&
126
- Object.entries(configs).forEach(([key, value]) => {
127
- dataSourceService.setFormConfig(key, value);
128
- });
127
+ if (!configs) {
128
+ return;
129
+ }
130
+
131
+ for (const [key, value] of Object.entries(configs)) {
132
+ dataSourceService.setFormConfig(key, value);
133
+ }
129
134
  },
130
135
  {
131
136
  immediate: true,
@@ -135,10 +140,13 @@ export const initServiceState = (
135
140
  watch(
136
141
  () => props.datasourceValues,
137
142
  (values) => {
138
- values &&
139
- Object.entries(values).forEach(([key, value]) => {
140
- dataSourceService.setFormValue(key, value);
141
- });
143
+ if (!values) {
144
+ return;
145
+ }
146
+
147
+ for (const [key, value] of Object.entries(values)) {
148
+ dataSourceService.setFormValue(key, value);
149
+ }
142
150
  },
143
151
  {
144
152
  immediate: true,
@@ -151,18 +159,20 @@ export const initServiceState = (
151
159
  const eventsList: Record<string, EventOption[]> = {};
152
160
  const methodsList: Record<string, EventOption[]> = {};
153
161
 
154
- eventMethodList &&
155
- Object.keys(eventMethodList).forEach((type: string) => {
162
+ if (eventMethodList) {
163
+ for (const type of Object.keys(eventMethodList)) {
156
164
  eventsList[type] = eventMethodList[type].events;
157
165
  methodsList[type] = eventMethodList[type].methods;
158
- });
166
+ }
167
+ }
159
168
 
160
- Object.entries(eventsList).forEach(([key, value]) => {
169
+ for (const [key, value] of Object.entries(eventsList)) {
161
170
  dataSourceService.setFormEvent(key, value);
162
- });
163
- Object.entries(methodsList).forEach(([key, value]) => {
171
+ }
172
+
173
+ for (const [key, value] of Object.entries(methodsList)) {
164
174
  dataSourceService.setFormMethod(key, value);
165
- });
175
+ }
166
176
  },
167
177
  {
168
178
  immediate: true,
@@ -202,184 +212,75 @@ export const initServiceEvents = (
202
212
  ((event: 'update:modelValue', value: MApp | null) => void),
203
213
  { editorService, codeBlockService, dataSourceService, depService }: Services,
204
214
  ) => {
205
- const rootChangeHandler = async (value: MApp | null, preValue?: MApp | null) => {
206
- if (!value) return;
207
-
208
- value.codeBlocks = value.codeBlocks || {};
209
- value.dataSources = value.dataSources || [];
210
-
211
- codeBlockService.setCodeDsl(value.codeBlocks);
212
- dataSourceService.set('dataSources', value.dataSources);
213
-
214
- depService.removeTargets(DepTargetType.CODE_BLOCK);
215
-
216
- Object.entries(value.codeBlocks).forEach(([id, code]) => {
217
- depService.addTarget(createCodeBlockTarget(id, code));
218
- });
219
-
220
- dataSourceService.get('dataSources').forEach((ds) => {
221
- initDataSourceDepTarget(ds);
222
- });
223
-
224
- if (Array.isArray(value.items)) {
225
- depService.clearIdleTasks();
226
- collectIdle(value.items, true);
227
- } else {
228
- depService.clear();
229
- delete value.dataSourceDeps;
230
- delete value.dataSourceCondDeps;
215
+ const getTMagicApp = () => {
216
+ const renderer = editorService.get('stage')?.renderer;
217
+ if (!renderer) {
218
+ return undefined;
231
219
  }
232
220
 
233
- const nodeId = editorService.get('node')?.id || props.defaultSelected;
234
- let node;
235
- if (nodeId) {
236
- node = editorService.getNodeById(nodeId);
221
+ if (renderer.runtime) {
222
+ return renderer.runtime.getApp?.();
237
223
  }
238
224
 
239
- if (node && node !== value) {
240
- await editorService.select(node.id);
241
- } else if (value.items?.length) {
242
- await editorService.select(value.items[0]);
243
- } else if (value.id) {
244
- editorService.set('nodes', [value]);
245
- editorService.set('parent', null);
246
- editorService.set('page', null);
247
- }
248
-
249
- if (toRaw(value) !== toRaw(preValue)) {
250
- emit('update:modelValue', value);
251
- }
252
- };
253
-
254
- const stage = computed(() => editorService.get('stage'));
255
-
256
- watch(stage, (stage) => {
257
- if (!stage) {
258
- return;
259
- }
260
-
261
- stage.on('rerender', () => {
262
- const node = editorService.get('node');
263
-
264
- if (!node) return;
265
-
266
- collectIdle([node], true).then(() => {
267
- afterUpdateNodes([node]);
268
- });
269
- });
270
- });
225
+ return new Promise<TMagicCore | undefined>((resolve) => {
226
+ // 设置 10s 超时
227
+ const timeout = globalThis.setTimeout(() => {
228
+ resolve(undefined);
229
+ }, 10000);
271
230
 
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;
282
- }
283
-
284
- if (root?.dataSources) {
285
- getApp()?.dataSourceManager?.updateSchema(root.dataSources);
286
- }
287
-
288
- if (!root || !stage.value) return;
289
-
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
- });
231
+ renderer.on('runtime-ready', () => {
232
+ if (timeout) {
233
+ globalThis.clearTimeout(timeout);
234
+ }
235
+ resolve(renderer.runtime?.getApp?.());
314
236
  });
315
237
  });
316
238
  };
317
239
 
318
- const afterUpdateNodes = (nodes: MNode[]) => {
319
- const root = editorService.get('root');
320
- if (!root) return;
240
+ const updateStageNodes = (nodes: MComponent[]) => {
321
241
  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
- });
242
+ updateStageNode(node);
327
243
  }
328
244
  };
329
245
 
330
- const targetAddHandler = (target: Target) => {
246
+ const updateStageNode = (node: MComponent) => {
331
247
  const root = editorService.get('root');
332
248
  if (!root) return;
333
249
 
334
- if (target.type === DepTargetType.DATA_SOURCE) {
335
- if (!root.dataSourceDeps) {
336
- root.dataSourceDeps = {};
337
- }
338
- root.dataSourceDeps[target.id] = target.deps;
339
- }
340
-
341
- if (target.type === DepTargetType.DATA_SOURCE_COND) {
342
- if (!root.dataSourceCondDeps) {
343
- root.dataSourceCondDeps = {};
344
- }
345
- root.dataSourceCondDeps[target.id] = target.deps;
346
- }
250
+ return editorService.get('stage')?.update({
251
+ config: cloneDeep(node),
252
+ parentId: editorService.getParentById(node.id)?.id,
253
+ root: cloneDeep(root),
254
+ });
347
255
  };
348
256
 
349
- const targetRemoveHandler = (id: string | number) => {
257
+ const updateDataSourceSchema = async () => {
350
258
  const root = editorService.get('root');
259
+ const app = await getTMagicApp();
351
260
 
352
- if (!root) return;
261
+ if (!app || !root) {
262
+ return;
263
+ }
353
264
 
354
- if (root.dataSourceDeps) {
355
- delete root.dataSourceDeps[id];
265
+ if (app.dsl) {
266
+ app.dsl.dataSources = root.dataSources;
356
267
  }
357
268
 
358
- if (root.dataSourceCondDeps) {
359
- delete root.dataSourceCondDeps[id];
269
+ if (root.dataSources) {
270
+ app.dataSourceManager?.updateSchema(root.dataSources);
360
271
  }
361
272
  };
362
273
 
363
- const depCollectedHandler = () => {
274
+ const dsDepCollectedHandler = async () => {
364
275
  const root = editorService.get('root');
365
- if (!root) return;
366
- const app = getApp();
367
- if (app?.dsl) {
276
+ const app = await getTMagicApp();
277
+
278
+ if (root && app?.dsl) {
368
279
  app.dsl.dataSourceDeps = root.dataSourceDeps;
369
280
  }
370
281
  };
371
282
 
372
- depService.on('add-target', targetAddHandler);
373
- depService.on('remove-target', targetRemoveHandler);
374
- depService.on('collected', depCollectedHandler);
375
-
376
- const initDataSourceDepTarget = (ds: DataSourceSchema) => {
377
- depService.addTarget(createDataSourceTarget(ds, reactive({})));
378
- depService.addTarget(createDataSourceMethodTarget(ds, reactive({})));
379
- depService.addTarget(createDataSourceCondTarget(ds, reactive({})));
380
- };
381
-
382
- const collectIdle = (nodes: MNode[], deep: boolean) =>
283
+ const collectIdle = (nodes: MComponent[], deep: boolean, type?: DepTargetType) =>
383
284
  Promise.all(
384
285
  nodes.map((node) => {
385
286
  let pageId: Id | undefined;
@@ -390,64 +291,163 @@ export const initServiceEvents = (
390
291
  const info = editorService.getNodeInfo(node.id);
391
292
  pageId = info.page?.id;
392
293
  }
393
- return depService.collectIdle([node], { pageId }, deep);
294
+ return depService.collectIdle([node], { pageId }, deep, type);
394
295
  }),
395
296
  );
396
297
 
298
+ watch(
299
+ () => editorService.get('stage'),
300
+ (stage) => {
301
+ if (!stage) {
302
+ return;
303
+ }
304
+
305
+ stage.on('rerender', async () => {
306
+ const node = editorService.get('node');
307
+
308
+ if (!node) return;
309
+
310
+ await collectIdle([node], true, DepTargetType.DATA_SOURCE);
311
+ updateStageNode(node);
312
+ });
313
+ },
314
+ );
315
+
316
+ const initDataSourceDepTarget = (ds: DataSourceSchema) => {
317
+ depService.addTarget(createDataSourceTarget(ds, reactive({})));
318
+ depService.addTarget(createDataSourceMethodTarget(ds, reactive({})));
319
+ depService.addTarget(createDataSourceCondTarget(ds, reactive({})));
320
+ };
321
+
322
+ const rootChangeHandler = async (value: MApp | null, preValue?: MApp | null) => {
323
+ if (!value) return;
324
+
325
+ value.codeBlocks = value.codeBlocks || {};
326
+ value.dataSources = value.dataSources || [];
327
+
328
+ codeBlockService.setCodeDsl(value.codeBlocks);
329
+ dataSourceService.set('dataSources', value.dataSources);
330
+
331
+ depService.removeTargets(DepTargetType.CODE_BLOCK);
332
+
333
+ for (const [id, code] of Object.entries(value.codeBlocks)) {
334
+ depService.addTarget(createCodeBlockTarget(id, code));
335
+ }
336
+
337
+ for (const ds of dataSourceService.get('dataSources')) {
338
+ initDataSourceDepTarget(ds);
339
+ }
340
+
341
+ if (Array.isArray(value.items)) {
342
+ depService.clearIdleTasks();
343
+ collectIdle(value.items, true).then(() => {
344
+ updateStageNodes(value.items);
345
+ });
346
+ } else {
347
+ depService.clear();
348
+ delete value.dataSourceDeps;
349
+ delete value.dataSourceCondDeps;
350
+ }
351
+
352
+ const nodeId = editorService.get('node')?.id || props.defaultSelected;
353
+ let node;
354
+ if (nodeId) {
355
+ node = editorService.getNodeById(nodeId);
356
+ }
357
+
358
+ if (node && node !== value) {
359
+ await editorService.select(node.id);
360
+ } else if (value.items?.length) {
361
+ await editorService.select(value.items[0]);
362
+ } else if (value.id) {
363
+ editorService.set('nodes', [value]);
364
+ editorService.set('parent', null);
365
+ editorService.set('page', null);
366
+ }
367
+
368
+ if (toRaw(value) !== toRaw(preValue)) {
369
+ emit('update:modelValue', value);
370
+ }
371
+ };
372
+
397
373
  // 新增节点,收集依赖
398
- const nodeAddHandler = (nodes: MNode[]) => {
399
- collectIdle(nodes, true).then(() => {
400
- afterUpdateNodes(nodes);
401
- });
374
+ const nodeAddHandler = async (nodes: MComponent[]) => {
375
+ await collectIdle(nodes, true);
376
+
377
+ updateStageNodes(nodes);
402
378
  };
403
379
 
404
380
  // 节点更新,收集依赖
405
381
  // 仅当修改到数据源相关的才收集
406
- const nodeUpdateHandler = (data: { newNode: MNode; oldNode: MNode; changeRecords?: ChangeRecord[] }[]) => {
407
- const needRecollectNodes: MNode[] = [];
408
- const normalNodes: MNode[] = [];
409
- data.forEach(({ newNode, oldNode, changeRecords }) => {
382
+ const nodeUpdateHandler = async (
383
+ data: { newNode: MComponent; oldNode: MComponent; changeRecords?: ChangeRecord[] }[],
384
+ ) => {
385
+ const needRecollectNodes: MComponent[] = [];
386
+ const normalNodes: MComponent[] = [];
387
+ for (const { newNode, oldNode, changeRecords } of data) {
410
388
  if (changeRecords?.length) {
411
- for (const record of changeRecords) {
389
+ // eslint-disable-next-line no-restricted-syntax
390
+ forChangeRecords: for (const record of changeRecords) {
391
+ if (!record.propPath) {
392
+ needRecollectNodes.push(newNode);
393
+ break forChangeRecords;
394
+ }
395
+
412
396
  // NODE_CONDS_KEY为显示条件key
413
397
  if (
414
- !record.propPath ||
415
398
  new RegExp(`${NODE_CONDS_KEY}.(\\d)+.cond`).test(record.propPath) ||
416
399
  new RegExp(`${NODE_CONDS_KEY}.(\\d)+.cond.(\\d)+.value`).test(record.propPath) ||
417
400
  record.propPath === NODE_CONDS_KEY ||
418
401
  isValueIncludeDataSource(record.value)
419
402
  ) {
420
403
  needRecollectNodes.push(newNode);
421
- } else {
422
- normalNodes.push(newNode);
404
+ break forChangeRecords;
405
+ }
406
+
407
+ // 修改的key在收集的依赖中,则需要触发重新收集
408
+ for (const target of Object.values(depService.getTargets(DepTargetType.DATA_SOURCE))) {
409
+ if (!target.deps[newNode.id]) {
410
+ continue;
411
+ }
412
+ if (target.deps[newNode.id].keys.includes(record.propPath)) {
413
+ needRecollectNodes.push(newNode);
414
+ break forChangeRecords;
415
+ }
423
416
  }
417
+
418
+ normalNodes.push(newNode);
424
419
  }
425
420
  } else if (isIncludeDataSource(newNode, oldNode)) {
426
421
  needRecollectNodes.push(newNode);
427
422
  } else {
428
423
  normalNodes.push(newNode);
429
424
  }
430
- });
425
+ }
431
426
 
432
427
  if (needRecollectNodes.length) {
433
- collectIdle(needRecollectNodes, true).then(() => {
434
- afterUpdateNodes(needRecollectNodes);
435
- });
436
- } else if (normalNodes.length) {
437
- afterUpdateNodes(normalNodes);
428
+ // 有数据源依赖,需要等依赖重新收集完才更新stage
429
+ await collectIdle(needRecollectNodes, true, DepTargetType.DATA_SOURCE);
430
+ await collectIdle(needRecollectNodes, true, DepTargetType.DATA_SOURCE_COND);
431
+ updateStageNodes(needRecollectNodes);
432
+ } else {
433
+ updateStageNodes(normalNodes);
434
+ // 在上面判断是否需要收集数据源依赖中已经更新stage
435
+ Promise.all([
436
+ collectIdle(normalNodes, true, DepTargetType.CODE_BLOCK),
437
+ collectIdle(normalNodes, true, DepTargetType.DATA_SOURCE_METHOD),
438
+ ]);
438
439
  }
439
440
  };
440
441
 
441
442
  // 节点删除,清除对齐的依赖收集
442
- const nodeRemoveHandler = (nodes: MNode[]) => {
443
+ const nodeRemoveHandler = (nodes: MComponent[]) => {
443
444
  depService.clear(nodes);
444
445
  };
445
446
 
446
447
  // 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖
447
- const historyChangeHandler = (page: MPage | MPageFragment) => {
448
- collectIdle([page], true).then(() => {
449
- updateDataSourceSchema([page], true);
450
- });
448
+ const historyChangeHandler = async (page: MPage | MPageFragment) => {
449
+ await collectIdle([page], true);
450
+ updateStageNode(page);
451
451
  };
452
452
 
453
453
  editorService.on('history-change', historyChangeHandler);
@@ -456,42 +456,39 @@ export const initServiceEvents = (
456
456
  editorService.on('remove', nodeRemoveHandler);
457
457
  editorService.on('update', nodeUpdateHandler);
458
458
 
459
- const codeBlockAddOrUpdateHandler = (id: Id, codeBlock: CodeBlockContent) => {
460
- if (depService.hasTarget(id, DepTargetType.CODE_BLOCK)) {
461
- depService.getTarget(id, DepTargetType.CODE_BLOCK)!.name = codeBlock.name;
462
- return;
463
- }
464
-
465
- depService.addTarget(createCodeBlockTarget(id, codeBlock));
466
- };
467
-
468
- const codeBlockRemoveHandler = (id: Id) => {
469
- depService.removeTarget(id, DepTargetType.CODE_BLOCK);
470
- };
471
-
472
- codeBlockService.on('addOrUpdate', codeBlockAddOrUpdateHandler);
473
- codeBlockService.on('remove', codeBlockRemoveHandler);
474
-
475
- const dataSourceAddHandler = (config: DataSourceSchema) => {
459
+ const dataSourceAddHandler = async (config: DataSourceSchema) => {
476
460
  initDataSourceDepTarget(config);
477
- getApp()?.dataSourceManager?.addDataSource(config);
461
+ const app = await getTMagicApp();
462
+ app?.dataSourceManager?.addDataSource(config);
478
463
  };
479
464
 
480
- const dataSourceUpdateHandler = (config: DataSourceSchema, { changeRecords }: { changeRecords: ChangeRecord[] }) => {
465
+ const dataSourceUpdateHandler = async (
466
+ config: DataSourceSchema,
467
+ { changeRecords }: { changeRecords: ChangeRecord[] },
468
+ ) => {
481
469
  let needRecollectDep = false;
470
+ let isModifyField = false;
471
+ let isModifyMock = false;
472
+ let isModifyMethod = false;
482
473
  for (const changeRecord of changeRecords) {
483
474
  if (!changeRecord.propPath) {
484
475
  continue;
485
476
  }
486
477
 
487
- needRecollectDep =
478
+ isModifyField =
488
479
  changeRecord.propPath === 'fields' ||
489
- changeRecord.propPath === 'methods' ||
490
480
  /fields.(\d)+.name/.test(changeRecord.propPath) ||
491
- /fields.(\d)+$/.test(changeRecord.propPath) ||
481
+ /fields.(\d)+$/.test(changeRecord.propPath);
482
+
483
+ isModifyMock = changeRecord.propPath === 'mocks';
484
+
485
+ isModifyMethod =
486
+ changeRecord.propPath === 'methods' ||
492
487
  /methods.(\d)+.name/.test(changeRecord.propPath) ||
493
488
  /methods.(\d)+$/.test(changeRecord.propPath);
494
489
 
490
+ needRecollectDep = isModifyField || isModifyMock || isModifyMethod;
491
+
495
492
  if (needRecollectDep) {
496
493
  break;
497
494
  }
@@ -505,12 +502,25 @@ export const initServiceEvents = (
505
502
  removeDataSourceTarget(config.id);
506
503
  initDataSourceDepTarget(config);
507
504
 
508
- collectIdle(root.items, true).then(() => {
509
- updateDataSourceSchema(root?.items || [], true);
505
+ let collectIdlePromises: Promise<void[]>[] = [];
506
+ if (isModifyField) {
507
+ collectIdlePromises = [
508
+ collectIdle(root.items, true, DepTargetType.DATA_SOURCE),
509
+ collectIdle(root.items, true, DepTargetType.DATA_SOURCE_COND),
510
+ ];
511
+ } else if (isModifyMock) {
512
+ collectIdlePromises = [collectIdle(root.items, true, DepTargetType.DATA_SOURCE)];
513
+ } else if (isModifyMethod) {
514
+ collectIdlePromises = [collectIdle(root.items, true, DepTargetType.DATA_SOURCE_METHOD)];
515
+ }
516
+ Promise.all(collectIdlePromises).then(() => {
517
+ updateDataSourceSchema();
518
+ updateStageNodes(root.items);
510
519
  });
511
520
  }
512
521
  } else if (root?.dataSources) {
513
- getApp()?.dataSourceManager?.updateSchema(root.dataSources);
522
+ const app = await getTMagicApp();
523
+ app?.dataSourceManager?.updateSchema(root.dataSources);
514
524
  }
515
525
  };
516
526
 
@@ -524,8 +534,14 @@ export const initServiceEvents = (
524
534
  const root = editorService.get('root');
525
535
  const nodeIds = Object.keys(root?.dataSourceDeps?.[id] || {});
526
536
  const nodes = getNodes(nodeIds, root?.items);
527
- collectIdle(nodes, false).then(() => {
528
- updateDataSourceSchema(nodes, false);
537
+
538
+ Promise.all([
539
+ collectIdle(nodes, false, DepTargetType.DATA_SOURCE),
540
+ collectIdle(nodes, false, DepTargetType.DATA_SOURCE_COND),
541
+ collectIdle(nodes, false, DepTargetType.DATA_SOURCE_METHOD),
542
+ ]).then(() => {
543
+ updateDataSourceSchema();
544
+ updateStageNodes(nodes);
529
545
  });
530
546
 
531
547
  removeDataSourceTarget(id);
@@ -535,10 +551,63 @@ export const initServiceEvents = (
535
551
  dataSourceService.on('update', dataSourceUpdateHandler);
536
552
  dataSourceService.on('remove', dataSourceRemoveHandler);
537
553
 
554
+ const codeBlockAddOrUpdateHandler = (id: Id, codeBlock: CodeBlockContent) => {
555
+ if (depService.hasTarget(id, DepTargetType.CODE_BLOCK)) {
556
+ depService.getTarget(id, DepTargetType.CODE_BLOCK)!.name = codeBlock.name;
557
+ return;
558
+ }
559
+
560
+ depService.addTarget(createCodeBlockTarget(id, codeBlock));
561
+ };
562
+
563
+ const codeBlockRemoveHandler = (id: Id) => {
564
+ depService.removeTarget(id, DepTargetType.CODE_BLOCK);
565
+ };
566
+
567
+ codeBlockService.on('addOrUpdate', codeBlockAddOrUpdateHandler);
568
+ codeBlockService.on('remove', codeBlockRemoveHandler);
569
+
570
+ const targetAddHandler = (target: Target) => {
571
+ const root = editorService.get('root');
572
+ if (!root) return;
573
+
574
+ if (target.type === DepTargetType.DATA_SOURCE) {
575
+ if (!root.dataSourceDeps) {
576
+ root.dataSourceDeps = {};
577
+ }
578
+ root.dataSourceDeps[target.id] = target.deps;
579
+ }
580
+
581
+ if (target.type === DepTargetType.DATA_SOURCE_COND) {
582
+ if (!root.dataSourceCondDeps) {
583
+ root.dataSourceCondDeps = {};
584
+ }
585
+ root.dataSourceCondDeps[target.id] = target.deps;
586
+ }
587
+ };
588
+
589
+ const targetRemoveHandler = (id: string | number) => {
590
+ const root = editorService.get('root');
591
+
592
+ if (!root) return;
593
+
594
+ if (root.dataSourceDeps) {
595
+ delete root.dataSourceDeps[id];
596
+ }
597
+
598
+ if (root.dataSourceCondDeps) {
599
+ delete root.dataSourceCondDeps[id];
600
+ }
601
+ };
602
+
603
+ depService.on('add-target', targetAddHandler);
604
+ depService.on('remove-target', targetRemoveHandler);
605
+ depService.on('ds-collected', dsDepCollectedHandler);
606
+
538
607
  onBeforeUnmount(() => {
539
608
  depService.off('add-target', targetAddHandler);
540
609
  depService.off('remove-target', targetRemoveHandler);
541
- depService.off('collected', depCollectedHandler);
610
+ depService.off('ds-collected', dsDepCollectedHandler);
542
611
 
543
612
  editorService.off('history-change', historyChangeHandler);
544
613
  editorService.off('root-change', rootChangeHandler);