Appearance
Plugin Architecture
面向插件作者与架构维护者的正式插件接口说明。
1. 公共口径
当前对外推荐入口是 plugin families:
ObjectTypePluginUIContributionPluginWorkflowServicePlugin
插件作者不应再把旧兼容契约当成公共 SDK。文档、示例和包根导出已经统一按 plugin families 表达。
2. 两个正交维度
装载层
corebuiltinoptional
能力族
objectuiworkflow
装载层决定插件在什么层进入编辑器,能力族决定它扩展什么。
3. 当前 live 支持矩阵
| 家族 | 当前 public 入口 | live 状态 | 备注 |
|---|---|---|---|
| object | ObjectTypePlugin.descriptors + createRuntime(ctx) | 已 live | descriptors 进入 registry;controllers 进入当前 object plane |
| ui | toolbar / contextMenu / selectionBar / shortcuts / commands | 已 live | 这些能力会进入当前 shell 与 command runtime |
| ui 扩展区 | leftDock / slots | 已 live | 组件 ID 通过 MolEditor.uiComponents 解析;toolbar 六个 slot 也已按当前 layout model 直接进入当前 shell |
| workflow | WorkflowServicePlugin | 已 live | workflow registry 已成为宿主覆盖与扩展边界;layout / persistence / share / clipboard / upload 由 kernel 主路径直接消费,import / export 由 shell 与 workflow helper 查询 registry;optional 层可覆盖 builtin 默认服务 |
4. 当前主路径已是 direct activation
当前 package 入口、文档叙事与 kernel 主装载路径都已经完成正式切换与 direct activation。对外 public 插件契约已经收口到 plugin families;旧 EditorPlugin / PluginContext 不再作为 public API 暴露,但内核内部仍通过 registryBridge 把 kernel 状态适配为 PluginActivateContext。
当前仍然成立的事实是:
- core / builtin 主路径已经切到 direct plugins
usePluginRegistry.ts的主装载路径已经 direct-only,只理解 plugin familiesObjectTypePlugin.createRuntime(ctx)当前已统一吃PluginActivateContext,稳定 live integration 入口为ctx.store、ctx.workflow、ctx.scene、ctx.viewport与ctx.molecule- 稳定读写面已经收口:读取优先走
ctx.store、ctx.workflow、ctx.scene.getLayer()、ctx.viewport.snapshot();molecule live integration 走ctx.molecule;写入优先走ctx.beginTransaction() - object controller 已参与当前 scene sync / viewport transform 主路径,但统一触发与 fallback 协调仍在
useScene/useEditor一侧
因此,准确表述应该是:
- public surface:已经完成正式切换
- kernel 主路径:已经 direct activation
- package boundary:plugin families 已成为唯一 public 契约;内部仍保留
registryBridge适配层来隔离 kernel 实现细节,后续主要是继续收口内部耦合
4.1 molecule 特化边界
Molio 是一个主打分子编辑能力、深度依赖 RDKit 的画板内核,因此 molecule 不应被当作必须彻底抹平的历史包袱。
当前应保留的特化边界是:
- RDKit 相关 chemistry 处理
molDataStore与分子级 snapshot / transform 语义- 分子 scene build 与 molecule-specific actions
当前应持续收口的,不是这些核心特化本身,而是它们向通用层的外溢:
- selection service 中的 molecule 特判
- history / selection snapshot 的 mixed-mode 痕迹
- workflow helper 与 shell 条件判断对 molecule 实现细节的依赖
5. ObjectTypePlugin
5.1 结构
ObjectTypePlugin 当前由两部分构成:
descriptorscreateRuntime(ctx)
descriptor 负责定义 kind 与对象级生命周期;runtime 负责把该对象接进当前 object controller live path。
5.2 最小样板
ts
import { ref } from 'vue'
import type {
ObjectControllerRuntime,
ObjectDescriptor,
ObjectTypePlugin,
} from '@shangchien/molio'
type NotePayload = {
kind: 'host:note'
text: string
}
const descriptor: ObjectDescriptor<NotePayload> = {
id: 'host:note',
kind: 'host:note',
family: 'leaf',
title: 'Host Note',
schemaVersion: 1,
}
export const noteObjectPlugin: ObjectTypePlugin = {
manifest: {
id: 'host:note.object',
name: 'Host Note Object',
version: '1.0.0',
},
descriptors: [descriptor],
createRuntime() {
const selectedIds = ref(new Set<string>())
const controller: ObjectControllerRuntime = {
key: 'host:note',
descriptor,
actions: {},
selectedIds,
hitObject: () => null,
isSelected: id => selectedIds.value.has(id),
selectObject: id => {
selectedIds.value = id ? new Set([id]) : new Set()
},
clearSelection: () => {
selectedIds.value = new Set()
},
getSelectedObject: () => null,
beginDrag: () => false,
updateDrag: () => {},
endDrag: () => {},
cancelDrag: () => {},
}
return { controllers: [controller] }
},
}6. UIContributionPlugin
6.1 当前 live 子集
当前 direct UI family 已能接入:
- toolbar
- context menu
- selection bar
- leftDock
- shortcuts
- commands
- slots
leftDock.panelComponent 与 slots.component 当前都通过 MolEditor 的 uiComponents 映射解析。渲染出的组件会收到两个 prop:editor 和 contribution。
6.2 toolbar layout model
当前 shell 主路径已经直接按 toolbar layout model 渲染六个 slot:
| slot | 当前屏幕区域 |
|---|---|
center-actions | 顶部左侧主操作区 |
top-utility | 顶部右侧工具区 |
left-tools | 左侧工具区 |
right-actions | 右侧动作区 |
left-secondary | 底部左侧次级工具区 |
bottom-status | 底部右侧状态/视口区 |
6.3 icon 使用约定
当前壳层直接消费 SVG 字符串,因此 iconKey 在 live path 中应传入 SVG 字符串,而不是逻辑 key。后续若引入统一 icon registry,再收紧这一点。
6.4 最小样板
ts
import { EDITOR_COMMANDS, type UIContributionPlugin } from '@shangchien/molio'
export const hostUiPlugin: UIContributionPlugin = {
manifest: {
id: 'host:ui.viewport',
name: 'Host Viewport Actions',
version: '1.0.0',
},
toolbar: [
{
id: 'host:ui.viewport.autofit',
slot: 'top-utility',
label: '重置视图',
commandId: EDITOR_COMMANDS.viewAutofit,
},
],
}7. WorkflowServicePlugin
当前 workflow family 已经能注册并进入当前 runtime:
uploadlayoutpersistenceshareclipboardimportersexporters
当前更准确的边界是:
layout、persistence、share、clipboard、upload由 kernel 主路径直接读取 workflow registryimporters、exporters通过 workflow registry 注册,再由 shell 或 workflow helper 在需要时查询调用- builtin 层提供默认实现,宿主可在 optional 层覆盖
8. 当前要避免的误解
- “只要写了 descriptor,对象就已经能编辑”是错的。descriptor 需要配合
createRuntime(ctx)才能进入当前 object live path。 - toolbar shell 已直接按当前 layout model 渲染,统一 selection context 也已覆盖 molecule / text / image / connector。
- “public API 已完成正式切换” 不代表内部适配层已经不存在;
registryBridge仍是当前 kernel 内部把实现细节隔离在 public plugin 契约之外的边界。 - molecule 保留 RDKit /
molDataStore/ 分子 scene build 特化是合理的;真正需要继续治理的是这些特化向通用服务层的外溢。 - object plugin 仍应优先消费稳定 activate context,而不是把新的内核闭包能力继续暴露成 ad-hoc 服务。