mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-09-20 05:29:58 +08:00
feat(editor): dsl初始化时收集依赖使用worker
This commit is contained in:
parent
9252822c58
commit
179b797c5c
@ -278,20 +278,21 @@ export const initServiceEvents = (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const collectIdle = (nodes: MComponent[], deep: boolean, type?: DepTargetType) =>
|
const getPageIdByNode = (node: MComponent) => {
|
||||||
Promise.all(
|
let pageId: Id | undefined;
|
||||||
nodes.map((node) => {
|
|
||||||
let pageId: Id | undefined;
|
|
||||||
|
|
||||||
if (isPage(node)) {
|
if (isPage(node)) {
|
||||||
pageId = node.id;
|
pageId = node.id;
|
||||||
} else {
|
} else {
|
||||||
const info = editorService.getNodeInfo(node.id);
|
const info = editorService.getNodeInfo(node.id);
|
||||||
pageId = info.page?.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(
|
watch(
|
||||||
() => editorService.get('stage'),
|
() => editorService.get('stage'),
|
||||||
@ -338,7 +339,8 @@ export const initServiceEvents = (
|
|||||||
|
|
||||||
if (Array.isArray(value.items)) {
|
if (Array.isArray(value.items)) {
|
||||||
depService.clearIdleTasks();
|
depService.clearIdleTasks();
|
||||||
collectIdle(value.items, true).then(() => {
|
|
||||||
|
(typeof Worker === 'undefined' ? collectIdle(value.items, true) : depService.collectByWorker(value)).then(() => {
|
||||||
updateStageNodes(value.items);
|
updateStageNodes(value.items);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -629,16 +631,12 @@ export const initServiceEvents = (
|
|||||||
root.dataSourceDeps = {};
|
root.dataSourceDeps = {};
|
||||||
}
|
}
|
||||||
root.dataSourceDeps[target.id] = target.deps;
|
root.dataSourceDeps[target.id] = target.deps;
|
||||||
}
|
} else if (target.type === DepTargetType.DATA_SOURCE_COND) {
|
||||||
|
|
||||||
if (target.type === DepTargetType.DATA_SOURCE_COND) {
|
|
||||||
if (!root.dataSourceCondDeps) {
|
if (!root.dataSourceCondDeps) {
|
||||||
root.dataSourceCondDeps = {};
|
root.dataSourceCondDeps = {};
|
||||||
}
|
}
|
||||||
root.dataSourceCondDeps[target.id] = target.deps;
|
root.dataSourceCondDeps[target.id] = target.deps;
|
||||||
}
|
} else if (target.type === DepTargetType.DATA_SOURCE_METHOD) {
|
||||||
|
|
||||||
if (target.type === DepTargetType.DATA_SOURCE_METHOD) {
|
|
||||||
if (!root.dataSourceMethodDeps) {
|
if (!root.dataSourceMethodDeps) {
|
||||||
root.dataSourceMethodDeps = {};
|
root.dataSourceMethodDeps = {};
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,14 @@
|
|||||||
*/
|
*/
|
||||||
import { reactive, shallowReactive } from 'vue';
|
import { reactive, shallowReactive } from 'vue';
|
||||||
import { throttle } from 'lodash-es';
|
import { throttle } from 'lodash-es';
|
||||||
|
import serialize from 'serialize-javascript';
|
||||||
|
|
||||||
import type { DepExtendedData, Id, MNode, Target, TargetNode } from '@tmagic/core';
|
import type { DepData, DepExtendedData, Id, MApp, MNode, Target, TargetNode } from '@tmagic/core';
|
||||||
import { DepTargetType, Watcher } from '@tmagic/core';
|
import { DepTargetType, traverseTarget, Watcher } from '@tmagic/core';
|
||||||
import { isPage } from '@tmagic/utils';
|
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';
|
import BaseService from './BaseService';
|
||||||
|
|
||||||
@ -50,6 +52,8 @@ class Dep extends BaseService {
|
|||||||
|
|
||||||
private watcher = new Watcher({ initialTargets: reactive({}) });
|
private watcher = new Watcher({ initialTargets: reactive({}) });
|
||||||
|
|
||||||
|
private waitingWorker?: Promise<void>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -114,7 +118,11 @@ class Dep extends BaseService {
|
|||||||
this.emit('ds-collected', nodes, deep);
|
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);
|
this.set('collecting', true);
|
||||||
let startTask = false;
|
let startTask = false;
|
||||||
this.watcher.collectByCallback(nodes, type, ({ node, target }) => {
|
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) {
|
public collectNode(node: MNode, target: Target, depExtendedData: DepExtendedData = {}, deep = false) {
|
||||||
// 先删除原有依赖,重新收集
|
// 先删除原有依赖,重新收集
|
||||||
if (isPage(node)) {
|
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 './editor';
|
||||||
export * from './operator';
|
export * from './operator';
|
||||||
export * from './data-source';
|
export * from './data-source';
|
||||||
export * from './idle-task';
|
export * from './dep/idle-task';
|
||||||
export * from './scroll-viewer';
|
export * from './scroll-viewer';
|
||||||
export * from './tree';
|
export * from './tree';
|
||||||
export * from './undo-redo';
|
export * from './undo-redo';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user