Feature/editor optimization (#251)

* refactor: 编辑器/运行时架构拆分与构建系统升级

* feat(core): 层级系统重构与UI变换矩阵修复

* refactor: 移除 ecs-components 聚合包并修复跨包组件查找问题

* fix(physics): 修复跨包组件类引用问题

* feat: 统一运行时架构与浏览器运行支持

* feat(asset): 实现浏览器运行时资产加载系统

* fix: 修复文档、CodeQL安全问题和CI类型检查错误

* fix: 修复文档、CodeQL安全问题和CI类型检查错误

* fix: 修复文档、CodeQL安全问题、CI类型检查和测试错误

* test: 补齐核心模块测试用例,修复CI构建配置

* fix: 修复测试用例中的类型错误和断言问题

* fix: 修复 turbo build:npm 任务的依赖顺序问题

* fix: 修复 CI 构建错误并优化构建性能
This commit is contained in:
YHH
2025-12-01 22:28:51 +08:00
committed by GitHub
parent 189714c727
commit b42a7b4e43
468 changed files with 18301 additions and 9075 deletions

View File

@@ -2,24 +2,24 @@
"name": "@esengine/asset-system",
"version": "1.0.0",
"description": "Asset management system for ES Engine",
"type": "module",
"main": "dist/index.js",
"module": "dist/index.mjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"files": [
"dist"
],
"scripts": {
"build": "rollup -c",
"build:npm": "npm run build",
"build": "tsup",
"build:watch": "tsup --watch",
"clean": "rimraf dist",
"type-check": "npx tsc --noEmit"
"type-check": "tsc --noEmit"
},
"keywords": [
"ecs",
@@ -29,16 +29,11 @@
],
"author": "yhh",
"license": "MIT",
"peerDependencies": {
"@esengine/ecs-framework": "^2.0.0"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^28.0.3",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-typescript": "^11.1.6",
"@esengine/ecs-framework": "workspace:*",
"@esengine/build-config": "workspace:*",
"rimraf": "^5.0.0",
"rollup": "^4.42.0",
"rollup-plugin-dts": "^6.2.1",
"tsup": "^8.0.0",
"typescript": "^5.8.3"
},
"publishConfig": {

View File

@@ -1,49 +0,0 @@
import typescript from '@rollup/plugin-typescript';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import dts from 'rollup-plugin-dts';
const external = ['@esengine/ecs-framework'];
export default [
// ESM and CJS builds
{
input: 'src/index.ts',
output: [
{
file: 'dist/index.js',
format: 'cjs',
sourcemap: true,
exports: 'named'
},
{
file: 'dist/index.mjs',
format: 'es',
sourcemap: true
}
],
external,
plugins: [
resolve({
preferBuiltins: false,
browser: true
}),
commonjs(),
typescript({
tsconfig: './tsconfig.json',
declaration: false,
declarationMap: false
})
]
},
// Type definitions
{
input: 'src/index.ts',
output: {
file: 'dist/index.d.ts',
format: 'es'
},
external,
plugins: [dts()]
}
];

View File

@@ -0,0 +1,22 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "ES2020",
"moduleResolution": "bundler",
"lib": ["ES2020", "DOM"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"declarationMap": true,
"resolveJsonModule": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}

View File

@@ -0,0 +1,7 @@
import { defineConfig } from 'tsup';
import { runtimeOnlyPreset } from '../build-config/src/presets/plugin-tsup';
export default defineConfig({
...runtimeOnlyPreset(),
tsconfig: 'tsconfig.build.json'
});

View File

@@ -0,0 +1,46 @@
{
"name": "@esengine/audio",
"version": "1.0.0",
"description": "ECS-based audio system",
"esengine": {
"plugin": true,
"pluginExport": "AudioPlugin",
"category": "audio",
"isEnginePlugin": true
},
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"files": [
"dist"
],
"scripts": {
"build": "tsup",
"build:watch": "tsup --watch",
"type-check": "tsc --noEmit",
"clean": "rimraf dist"
},
"devDependencies": {
"@esengine/ecs-framework": "workspace:*",
"@esengine/engine-core": "workspace:*",
"@esengine/build-config": "workspace:*",
"rimraf": "^5.0.5",
"tsup": "^8.0.0",
"typescript": "^5.3.3"
},
"keywords": [
"ecs",
"audio",
"sound",
"music"
],
"author": "yhh",
"license": "MIT"
}

View File

@@ -0,0 +1,24 @@
import type { ComponentRegistry as ComponentRegistryType } from '@esengine/ecs-framework';
import type { IRuntimeModule, IPlugin, PluginDescriptor } from '@esengine/engine-core';
import { AudioSourceComponent } from './AudioSourceComponent';
class AudioRuntimeModule implements IRuntimeModule {
registerComponents(registry: typeof ComponentRegistryType): void {
registry.register(AudioSourceComponent);
}
}
const descriptor: PluginDescriptor = {
id: '@esengine/audio',
name: 'Audio',
version: '1.0.0',
description: '音频组件',
category: 'audio',
enabledByDefault: true,
isEnginePlugin: true
};
export const AudioPlugin: IPlugin = {
descriptor,
runtimeModule: new AudioRuntimeModule()
};

View File

@@ -0,0 +1,43 @@
import { Component, ECSComponent, Serializable, Serialize, Property } from '@esengine/ecs-framework';
@ECSComponent('AudioSource')
@Serializable({ version: 1, typeId: 'AudioSource' })
export class AudioSourceComponent extends Component {
@Serialize()
@Property({ type: 'asset', label: 'Audio Clip', assetType: 'audio' })
clip: string = '';
/** 范围 [0, 1] */
@Serialize()
@Property({ type: 'number', label: 'Volume', min: 0, max: 1, step: 0.01 })
volume: number = 1;
@Serialize()
@Property({ type: 'number', label: 'Pitch', min: 0.1, max: 3, step: 0.1 })
pitch: number = 1;
@Serialize()
@Property({ type: 'boolean', label: 'Loop' })
loop: boolean = false;
@Serialize()
@Property({ type: 'boolean', label: 'Play On Awake' })
playOnAwake: boolean = false;
@Serialize()
@Property({ type: 'boolean', label: 'Mute' })
mute: boolean = false;
/** 0 = 2D, 1 = 3D */
@Serialize()
@Property({ type: 'number', label: 'Spatial Blend', min: 0, max: 1, step: 0.1 })
spatialBlend: number = 0;
@Serialize()
@Property({ type: 'number', label: 'Min Distance' })
minDistance: number = 1;
@Serialize()
@Property({ type: 'number', label: 'Max Distance' })
maxDistance: number = 500;
}

View File

@@ -0,0 +1,2 @@
export { AudioSourceComponent } from './AudioSourceComponent';
export { AudioPlugin } from './AudioPlugin';

View File

@@ -0,0 +1,12 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"composite": false,
"declaration": true,
"declarationMap": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}

View File

@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"],
"references": [
{ "path": "../core" }
]
}

View File

@@ -0,0 +1,7 @@
import { defineConfig } from 'tsup';
import { runtimeOnlyPreset } from '../build-config/src/presets/plugin-tsup';
export default defineConfig({
...runtimeOnlyPreset(),
tsconfig: 'tsconfig.build.json'
});

View File

@@ -0,0 +1,49 @@
{
"name": "@esengine/behavior-tree-editor",
"version": "1.0.0",
"description": "Editor support for @esengine/behavior-tree - visual editor, inspectors, and tools",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"files": [
"dist"
],
"scripts": {
"build": "tsup",
"build:watch": "tsup --watch",
"type-check": "tsc --noEmit",
"clean": "rimraf dist"
},
"dependencies": {
"@esengine/behavior-tree": "workspace:*"
},
"devDependencies": {
"@esengine/ecs-framework": "workspace:*",
"@esengine/engine-core": "workspace:*",
"@esengine/editor-core": "workspace:*",
"@esengine/editor-runtime": "workspace:*",
"@esengine/node-editor": "workspace:*",
"@esengine/build-config": "workspace:*",
"lucide-react": "^0.545.0",
"react": "^18.3.1",
"zustand": "^5.0.8",
"@types/react": "^18.3.12",
"rimraf": "^5.0.5",
"tsup": "^8.0.0",
"typescript": "^5.3.3"
},
"keywords": [
"ecs",
"behavior-tree",
"editor"
],
"author": "",
"license": "MIT"
}

View File

@@ -21,18 +21,16 @@ export const descriptor: PluginDescriptor = {
{
name: 'BehaviorTreeRuntime',
type: 'runtime',
loadingPhase: 'default',
entry: './src/index.ts'
loadingPhase: 'default'
},
{
name: 'BehaviorTreeEditor',
type: 'editor',
loadingPhase: 'default',
entry: './src/editor/index.ts'
loadingPhase: 'default'
}
],
dependencies: [
{ id: '@esengine/core', version: '>=1.0.0' }
{ id: '@esengine/engine-core', version: '>=1.0.0', optional: true }
],
icon: 'GitBranch'
};

View File

@@ -1,4 +1,4 @@
import { GlobalBlackboardConfig, BlackboardValueType, BlackboardVariable } from '../../..';
import { type GlobalBlackboardConfig, BlackboardValueType, type BlackboardVariable } from '@esengine/behavior-tree';
import { createLogger } from '@esengine/ecs-framework';
const logger = createLogger('GlobalBlackboardService');

View File

@@ -1,7 +1,7 @@
import { createStore } from '@esengine/editor-runtime';
const create = createStore;
import { NodeTemplates, NodeTemplate } from '../../..';
import { NodeTemplates, type NodeTemplate } from '@esengine/behavior-tree';
import { BehaviorTree } from '../../domain/models/BehaviorTree';
import { Node } from '../../domain/models/Node';
import { Connection, ConnectionType } from '../../domain/models/Connection';

View File

@@ -1,4 +1,4 @@
import { NodeTemplate } from '../../..';
import type { NodeTemplate } from '@esengine/behavior-tree';
import { Node } from '../../domain/models/Node';
import { Position } from '../../domain/value-objects/Position';
import { INodeFactory } from '../../domain/interfaces/INodeFactory';

View File

@@ -10,7 +10,7 @@ import {
createLogger,
} from '@esengine/editor-runtime';
import { GlobalBlackboardTypeGenerator } from '../generators/GlobalBlackboardTypeGenerator';
import { EditorFormatConverter, BehaviorTreeAssetSerializer } from '../..';
import { EditorFormatConverter, BehaviorTreeAssetSerializer } from '@esengine/behavior-tree';
import { useBehaviorTreeDataStore } from '../application/state/BehaviorTreeDataStore';
const { File, FolderTree, FolderOpen } = Icons;

View File

@@ -1,5 +1,5 @@
import { React, useEffect, useMemo, useRef, useState, useCallback } from '@esengine/editor-runtime';
import { NodeTemplate, BlackboardValueType } from '../..';
import { BlackboardValueType, type NodeTemplate } from '@esengine/behavior-tree';
import { useBehaviorTreeDataStore, BehaviorTreeNode, ROOT_NODE_ID } from '../stores';
import { useUIStore } from '../stores';
import { showToast as notificationShowToast } from '../services/NotificationService';

View File

@@ -1,6 +1,6 @@
import { React, useRef, useEffect, useState, useMemo, Icons } from '@esengine/editor-runtime';
import type { LucideIcon } from '@esengine/editor-runtime';
import { NodeTemplate } from '../../..';
import type { NodeTemplate } from '@esengine/behavior-tree';
import { NodeFactory } from '../../infrastructure/factories/NodeFactory';
const { Search, X, ChevronDown, ChevronRight } = Icons;

View File

@@ -1,6 +1,6 @@
import { React, Icons } from '@esengine/editor-runtime';
import type { LucideIcon } from '@esengine/editor-runtime';
import { PropertyDefinition } from '../../..';
import type { PropertyDefinition } from '@esengine/behavior-tree';
import { Node as BehaviorTreeNodeType } from '../../domain/models/Node';
import { Connection } from '../../domain/models/Connection';

View File

@@ -1,4 +1,4 @@
import { NodeTemplate, NodeType } from '../..';
import { NodeType, type NodeTemplate } from '@esengine/behavior-tree';
import { Icons } from '@esengine/editor-runtime';
import type { LucideIcon } from '@esengine/editor-runtime';

View File

@@ -1,6 +1,6 @@
import { Node } from '../models/Node';
import { Position } from '../value-objects/Position';
import { NodeTemplate } from '../../..';
import type { NodeTemplate } from '@esengine/behavior-tree';
export const ROOT_NODE_ID = 'root-node';

View File

@@ -1,4 +1,4 @@
import { NodeTemplate } from '../../..';
import type { NodeTemplate } from '@esengine/behavior-tree';
import { Node } from '../models/Node';
import { Position } from '../value-objects';

View File

@@ -1,4 +1,4 @@
import { NodeTemplate } from '../../..';
import type { NodeTemplate } from '@esengine/behavior-tree';
import { Position, NodeType } from '../value-objects';
import { ValidationError } from '../errors';

View File

@@ -1,4 +1,4 @@
import { GlobalBlackboardConfig, BlackboardValueType } from '../..';
import { BlackboardValueType, type GlobalBlackboardConfig } from '@esengine/behavior-tree';
/**
*

View File

@@ -1,5 +1,5 @@
import { useState, type RefObject, React, createLogger } from '@esengine/editor-runtime';
import { NodeTemplate, NodeType } from '../..';
import { NodeType, type NodeTemplate } from '@esengine/behavior-tree';
import { Position } from '../domain/value-objects/Position';
import { useNodeOperations } from './useNodeOperations';

View File

@@ -1,5 +1,5 @@
import { useCallback, useMemo, CommandManager } from '@esengine/editor-runtime';
import { NodeTemplate } from '../..';
import type { NodeTemplate } from '@esengine/behavior-tree';
import { Position } from '../domain/value-objects/Position';
import { INodeFactory } from '../domain/interfaces/INodeFactory';
import { TreeStateAdapter } from '../application/state/BehaviorTreeDataStore';

View File

@@ -1,6 +1,6 @@
import { type RefObject, React } from '@esengine/editor-runtime';
import { BehaviorTreeNode, Connection, ROOT_NODE_ID, useUIStore } from '../stores';
import { PropertyDefinition } from '../..';
import type { PropertyDefinition } from '@esengine/behavior-tree';
import { useConnectionOperations } from './useConnectionOperations';
interface UsePortConnectionParams {

View File

@@ -1,5 +1,5 @@
import { useState, type RefObject } from '@esengine/editor-runtime';
import { NodeTemplate } from '../..';
import type { NodeTemplate } from '@esengine/behavior-tree';
import { BehaviorTreeNode, Connection, useBehaviorTreeDataStore } from '../stores';
import { Node } from '../domain/models/Node';
import { Position } from '../domain/value-objects/Position';

View File

@@ -4,7 +4,7 @@
*/
import type { ServiceContainer } from '@esengine/ecs-framework';
import { TransformComponent } from '@esengine/ecs-components';
import { TransformComponent } from '@esengine/engine-core';
import {
type IEditorModuleLoader,
type IPluginLoader,
@@ -20,6 +20,7 @@ import {
MessageHub,
IMessageHub,
FileActionRegistry,
IFileActionRegistry,
IDialogService,
IFileSystemService,
type IDialog,
@@ -28,8 +29,8 @@ import {
PluginAPI,
} from '@esengine/editor-runtime';
// Runtime imports (relative paths since we're in the same package)
import { BehaviorTreeRuntimeComponent } from '../execution/BehaviorTreeRuntimeComponent';
// Runtime imports from @esengine/behavior-tree package
import { BehaviorTreeRuntimeComponent, BehaviorTreeRuntimeModule } from '@esengine/behavior-tree';
// Editor components and services
import { BehaviorTreeService } from './services/BehaviorTreeService';
@@ -41,9 +42,8 @@ import { useBehaviorTreeDataStore } from './stores';
import { createRootNode } from './domain/constants/RootNode';
import { PluginContext } from './PluginContext';
// Import descriptor from local file, runtime module from main module
// Import descriptor from local file
import { descriptor } from './BehaviorTreePlugin';
import { BehaviorTreeRuntimeModule } from '../BehaviorTreeRuntimeModule';
// 导入编辑器 CSS 样式(会被 vite 自动处理并注入到 DOM
// Import editor CSS styles (automatically handled and injected by vite)
@@ -86,7 +86,7 @@ export class BehaviorTreeEditorModule implements IEditorModuleLoader {
private registerAssetCreationMappings(services: ServiceContainer): void {
try {
const fileActionRegistry = services.resolve(FileActionRegistry);
const fileActionRegistry = services.resolve<FileActionRegistry>(IFileActionRegistry);
if (fileActionRegistry) {
fileActionRegistry.registerAssetCreationMapping({
extension: '.btree',

Some files were not shown because too many files have changed in this diff Show More