mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-09-19 21:06:06 +08:00
feat(editor): dsl初始化时收集依赖使用worker
This commit is contained in:
parent
9252822c58
commit
179b797c5c
@ -278,9 +278,7 @@ export const initServiceEvents = (
|
||||
});
|
||||
};
|
||||
|
||||
const collectIdle = (nodes: MComponent[], deep: boolean, type?: DepTargetType) =>
|
||||
Promise.all(
|
||||
nodes.map((node) => {
|
||||
const getPageIdByNode = (node: MComponent) => {
|
||||
let pageId: Id | undefined;
|
||||
|
||||
if (isPage(node)) {
|
||||
@ -289,9 +287,12 @@ export const initServiceEvents = (
|
||||
const info = editorService.getNodeInfo(node.id);
|
||||
pageId = info.page?.id;
|
||||
}
|
||||
return depService.collectIdle([node], { pageId }, deep, type);
|
||||
}),
|
||||
);
|
||||
|
||||
return pageId;
|
||||
};
|
||||
|
||||
const collectIdle = (nodes: MComponent[], deep: boolean, type?: DepTargetType) =>
|
||||
Promise.all(nodes.map((node) => depService.collectIdle([node], { pageId: getPageIdByNode(node) }, deep, type)));
|
||||
|
||||
watch(
|
||||
() => editorService.get('stage'),
|
||||
@ -338,7 +339,8 @@ export const initServiceEvents = (
|
||||
|
||||
if (Array.isArray(value.items)) {
|
||||
depService.clearIdleTasks();
|
||||
collectIdle(value.items, true).then(() => {
|
||||
|
||||
(typeof Worker === 'undefined' ? collectIdle(value.items, true) : depService.collectByWorker(value)).then(() => {
|
||||
updateStageNodes(value.items);
|
||||
});
|
||||
} else {
|
||||
@ -629,16 +631,12 @@ export const initServiceEvents = (
|
||||
root.dataSourceDeps = {};
|
||||
}
|
||||
root.dataSourceDeps[target.id] = target.deps;
|
||||
}
|
||||
|
||||
if (target.type === DepTargetType.DATA_SOURCE_COND) {
|
||||
} else if (target.type === DepTargetType.DATA_SOURCE_COND) {
|
||||
if (!root.dataSourceCondDeps) {
|
||||
root.dataSourceCondDeps = {};
|
||||
}
|
||||
root.dataSourceCondDeps[target.id] = target.deps;
|
||||
}
|
||||
|
||||
if (target.type === DepTargetType.DATA_SOURCE_METHOD) {
|
||||
} else if (target.type === DepTargetType.DATA_SOURCE_METHOD) {
|
||||
if (!root.dataSourceMethodDeps) {
|
||||
root.dataSourceMethodDeps = {};
|
||||
}
|
||||
|
@ -17,12 +17,14 @@
|
||||
*/
|
||||
import { reactive, shallowReactive } from 'vue';
|
||||
import { throttle } from 'lodash-es';
|
||||
import serialize from 'serialize-javascript';
|
||||
|
||||
import type { DepExtendedData, Id, MNode, Target, TargetNode } from '@tmagic/core';
|
||||
import { DepTargetType, Watcher } from '@tmagic/core';
|
||||
import type { DepData, DepExtendedData, Id, MApp, MNode, Target, TargetNode } from '@tmagic/core';
|
||||
import { DepTargetType, traverseTarget, Watcher } from '@tmagic/core';
|
||||
import { isPage } from '@tmagic/utils';
|
||||
|
||||
import { IdleTask } from '@editor/utils/idle-task';
|
||||
import { IdleTask } from '@editor/utils/dep/idle-task';
|
||||
import Work from '@editor/utils/dep/worker.ts?worker&inline';
|
||||
|
||||
import BaseService from './BaseService';
|
||||
|
||||
@ -50,6 +52,8 @@ class Dep extends BaseService {
|
||||
|
||||
private watcher = new Watcher({ initialTargets: reactive({}) });
|
||||
|
||||
private waitingWorker?: Promise<void>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@ -114,7 +118,11 @@ class Dep extends BaseService {
|
||||
this.emit('ds-collected', nodes, deep);
|
||||
}
|
||||
|
||||
public collectIdle(nodes: MNode[], depExtendedData: DepExtendedData = {}, deep = false, type?: DepTargetType) {
|
||||
public async collectIdle(nodes: MNode[], depExtendedData: DepExtendedData = {}, deep = false, type?: DepTargetType) {
|
||||
if (this.waitingWorker) {
|
||||
await this.waitingWorker;
|
||||
}
|
||||
|
||||
this.set('collecting', true);
|
||||
let startTask = false;
|
||||
this.watcher.collectByCallback(nodes, type, ({ node, target }) => {
|
||||
@ -141,6 +149,48 @@ class Dep extends BaseService {
|
||||
});
|
||||
}
|
||||
|
||||
public collectByWorker(dsl: MApp) {
|
||||
this.set('collecting', true);
|
||||
|
||||
const { promise, resolve: waitingResolve } = Promise.withResolvers<void>();
|
||||
|
||||
this.waitingWorker = promise;
|
||||
|
||||
return new Promise<Record<string, Record<string, DepData>>>((resolve) => {
|
||||
const worker = new Work();
|
||||
worker.postMessage({
|
||||
dsl: serialize(dsl),
|
||||
});
|
||||
worker.onmessage = (e) => {
|
||||
resolve(e.data);
|
||||
};
|
||||
worker.onerror = () => {
|
||||
resolve({});
|
||||
};
|
||||
}).then((depsData) => {
|
||||
traverseTarget(this.watcher.getTargetsList(), (target) => {
|
||||
if (depsData[target.type]?.[target.id]) {
|
||||
target.deps = reactive(depsData[target.type][target.id]);
|
||||
|
||||
if (target.type === DepTargetType.DATA_SOURCE && dsl.dataSourceDeps) {
|
||||
dsl.dataSourceDeps[target.id] = target.deps;
|
||||
} else if (target.type === DepTargetType.DATA_SOURCE_COND && dsl.dataSourceCondDeps) {
|
||||
dsl.dataSourceCondDeps[target.id] = target.deps;
|
||||
} else if (target.type === DepTargetType.DATA_SOURCE_METHOD) {
|
||||
dsl.dataSourceMethodDeps[target.id] = target.deps;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.set('collecting', false);
|
||||
this.emit('collected', dsl.items, true);
|
||||
this.emit('ds-collected', dsl.items, true);
|
||||
waitingResolve();
|
||||
|
||||
return depsData;
|
||||
});
|
||||
}
|
||||
|
||||
public collectNode(node: MNode, target: Target, depExtendedData: DepExtendedData = {}, deep = false) {
|
||||
// 先删除原有依赖,重新收集
|
||||
if (isPage(node)) {
|
||||
|
63
packages/editor/src/utils/dep/worker.ts
Normal file
63
packages/editor/src/utils/dep/worker.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import {
|
||||
createCodeBlockTarget,
|
||||
createDataSourceCondTarget,
|
||||
createDataSourceMethodTarget,
|
||||
createDataSourceTarget,
|
||||
type DepData,
|
||||
DepTargetType,
|
||||
type Id,
|
||||
type MApp,
|
||||
traverseTarget,
|
||||
Watcher,
|
||||
} from '@tmagic/core';
|
||||
|
||||
import { error } from '../logger';
|
||||
|
||||
onmessage = (e) => {
|
||||
const watcher = new Watcher({ initialTargets: {} });
|
||||
|
||||
const { dsl } = e.data;
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line no-eval
|
||||
const mApp: MApp = eval(`(${dsl})`);
|
||||
|
||||
if (!mApp) {
|
||||
postMessage({});
|
||||
}
|
||||
|
||||
if (mApp.codeBlocks) {
|
||||
for (const [id, code] of Object.entries(mApp.codeBlocks)) {
|
||||
watcher.addTarget(createCodeBlockTarget(id, code));
|
||||
}
|
||||
}
|
||||
|
||||
if (mApp.dataSources) {
|
||||
for (const ds of mApp.dataSources) {
|
||||
watcher.addTarget(createDataSourceTarget(ds, {}));
|
||||
watcher.addTarget(createDataSourceMethodTarget(ds, {}));
|
||||
watcher.addTarget(createDataSourceCondTarget(ds, {}));
|
||||
}
|
||||
}
|
||||
|
||||
watcher.collectByCallback(mApp.items, undefined, ({ node, target }) => {
|
||||
watcher.collectItem(node, target, { pageId: node.id }, true);
|
||||
});
|
||||
|
||||
const data: Record<string, Record<Id, DepData>> = {
|
||||
[DepTargetType.DATA_SOURCE]: {},
|
||||
[DepTargetType.DATA_SOURCE_METHOD]: {},
|
||||
[DepTargetType.DATA_SOURCE_COND]: {},
|
||||
[DepTargetType.CODE_BLOCK]: {},
|
||||
};
|
||||
|
||||
traverseTarget(watcher.getTargetsList(), (target) => {
|
||||
data[target.type][target.id] = target.deps;
|
||||
});
|
||||
|
||||
postMessage(data);
|
||||
} catch (e: any) {
|
||||
error(e);
|
||||
postMessage({});
|
||||
}
|
||||
};
|
@ -22,7 +22,7 @@ export * from './logger';
|
||||
export * from './editor';
|
||||
export * from './operator';
|
||||
export * from './data-source';
|
||||
export * from './idle-task';
|
||||
export * from './dep/idle-task';
|
||||
export * from './scroll-viewer';
|
||||
export * from './tree';
|
||||
export * from './undo-redo';
|
||||
|
Loading…
x
Reference in New Issue
Block a user