Formula Authoring
RenderFormulaAuthoringEditor是在现有RenderCodeEditor之上的领域中立组合组件。它展示Formula编译分析和显式snapshot只读预览,不解释Medical或Report作用域,也不保存或写回业务文档。
Package边界
应用分别从两个入口导入UI与Engine:
import {
RenderFormulaAuthoringEditor,
createFormulaEngineAuthoringProvider,
} from 'ds-ui'
import {
compileFormula,
computeSourceHash,
getCheckedFormulaEnvelope,
getFormulaAnalysis,
normalizeEnvironment,
standardLibraryCatalog,
structuredHash,
} from '@ds-ui/formula-engine'
ds-ui根入口不重新导出Formula Engine,也没有对它的静态runtime依赖。只有创建真实provider的应用bundle才包含Engine。
Engine-backed Provider
const provider = createFormulaEngineAuthoringProvider({
engine: {
compileFormula,
computeSourceHash,
structuredHash,
normalizeEnvironment,
getCheckedFormulaEnvelope,
getFormulaAnalysis,
},
createCompileRequest: request => binding.createCompileRequest(
request.source,
request.anchor,
),
getEnvironment: request => request.environment,
getCatalog: request => binding.getAuthoringCatalog(
request.anchor,
standardLibraryCatalog.functions,
),
standardLibraryProfile: 'common-v1',
})
Provider提供:
- Engine compile diagnostics,并保留
code、args和UTF-16 offsetspan; - result type/shape、ordered dependency、selected function/overload和cost upper bound;
- symbol/function completion;
- escaped/qualified identifier replacement span;
- symbol/function Hover和function Signature Help;
- Formula semantic tokens;
- 只移除行尾空白的默认format策略,或宿主注入的领域中立formatter。
getCatalog()必须返回本次snapshot的完整symbol/function catalog。使用静态standardLibraryCatalog.functions时,应设置standardLibraryProfile,provider会过滤当前profile不可用的函数。
缓存键包含catalogSnapshotKey、source hash、normalized environment hash和完整compile request hash。catalog snapshot变化后,旧结果不会继续展示。
编辑器与Analysis
const authoring = new RenderFormulaAuthoringEditor({
value: '=SUM(scores)+amount*factor',
provider,
languageContext: {
catalogSnapshotKey: 'catalog-v42',
anchor: formulaOwnerAnchor,
},
onAnalysisChange: analysis => {
console.log(analysis?.summary)
},
})
组件复用CodeEditor的IME、clipboard、undo/redo、diagnostics、completion、Hover和Signature Help。Analysis区域显示当前catalog key、result、dependencies、functions和cost,不写回source或领域对象。
显式只读Preview
没有evaluation snapshot时组件不会求值。宿主必须同时提供snapshot identity和opaque snapshot:
authoring.setEvaluationSnapshot({
evaluationSnapshotKey: 'values-v18',
snapshot: immutableEvaluationSnapshot,
})
await authoring.refreshPreview()
Provider可选实现preview(request),返回:
value:Scalar或Array的type、shape、orientation和display cells;error:Formula value error;failed:execution/host/snapshot failure;- 可选metrics。
request.signal在source、catalog、evaluation snapshot变化或组件销毁时终止;provider应尽快停止本地或远程求值。
Preview是no-write调用。响应必须回显同一catalogSnapshotKey与evaluationSnapshotKey,任一不匹配都会fail closed。
Preview预算
默认硬上限:
{
"maxCells": 200,
"maxTextLength": 512
}
normalizeFormulaAuthoringPreviewLimits()会把宿主请求限制在硬上限内;normalizeFormulaAuthoringPreview()会再次截断provider响应,设置truncated,并避免在UTF-16 surrogate pair中间截断文本。
组合组件的文本区域最多直接展示12个cell。即使归一化结果保留更多cell,UI也会明确显示presentation truncation;完整的预算内脱离副本仍可从preview读取。
状态与调试
debugState()返回:
- catalog/evaluation snapshot key;
- analysis状态:
loading、invalid、ready; - preview状态:
unavailable、loading、value、error、failed; - dependency/function数量;
- 可见preview cell数量和truncated状态。
- 实际展示的preview cell数量。
边界
- Formula Engine仍是headless package;
- catalog和snapshot由调用方Binding构造;
RenderFormulaAuthoringEditor不读取Medical Element或Report dataset;- 不根据source猜旧expression语言;
- 不执行保存、writeback、print或export;
- 不把preview结果当作跨端canonical oracle。
底层CodeEditor接口、offset映射与交互行为见CodeEditor。