主题
公开面一览
库对外只有下面这些名字。一部分是纯函数(上一段的输出就是下一段的输入),一部分是两个状态口(建注册表、落介质)。
运行时导出(@ggn/draw)
| 模块 | 导出 |
|---|---|
| contract | DrawDocumentSchema、parseDocument |
| diagnostic | diagnostic、ok、err |
| geometry | rectUnion、rectContains、pointOnSide、polylineD、midpoint |
| measure | estimateTextMeasurer、estimateCharWidth、labelLines、labelAnchor、measureLabel、FALLBACK_FONT_SIZE、FALLBACK_LINE_HEIGHT |
| theme | resolveTheme、resolveToken、DEFAULT_TOKENS、DEFAULT_TYPOGRAPHY |
| registry | createRegistry、defaultAnchor |
| registry · 内置原语 | builtinRegistry、createBuiltinRegistry、rectShape、ellipseShape、pathShape、textShape、groupShape、BUILTIN_SHAPE_TYPES、BUILTIN_MARKER_TYPES |
| layout | layoutDocument、layeredEngine、defaultEngine、gridEngine、explicitEngine、engineByName、orthogonalRouter、avoidingRouter、straightRouter、borderPoint、endpointPoint、DEFAULT_SPACING、CONTAINER_PADDING |
| scene | diffScene、ROOT_KEY |
| build | buildScene |
| host | renderToSvg |
| handle | createDrawHandle |
派生入口(@ggn/draw/dom)
| 入口 | 导出 |
|---|---|
@ggn/draw/dom | createDomHost |
类型导出
| 模块 | 类型 |
|---|---|
| contract | DrawDocument、DrawNode、DrawEdge、EndpointRef、Label、LayoutIntent、Port、StyleDecl |
| diagnostic | Diagnostic、DiagnosticCode、Result |
| geometry | Point、Size、Rect、Side、Route、RoutingKind |
| measure | TextMeasurer、TextStyle、Typography |
| theme | ThemeInput、ResolvedTheme、TokenValue |
| registry | DrawRegistry、ShapeSpec、ShapeEntry、ShapeMetrics、EdgeSpec、MarkerSpec、ShapeRenderCtx、EdgeRenderCtx、SceneSink、ChildOptions、MeasureFn |
| registry · 内置原语 | BuiltinShapeType、BuiltinMarkerType |
| layout | LayoutOptions、LayoutResult、LayoutEngine、LayoutEngineInput、LayoutEngineOutput、Router、RouterInput、RouterOutput |
| scene | Scene、SceneNode、SceneGroup、SceneRect、SceneEllipse、ScenePath、SceneText、ScenePatch、NodeProps、Style、Paint、LinearGradientPaint、DotsPatternPaint、GradientStop、TextAnchor |
| build | BuildOptions |
| host | DrawHost、RenderToSvgOptions |
| handle | DrawHandle、DrawHandleOptions |
统一返回模型
ts
type Result<T> =
| { ok: true; value: T; diagnostics: Diagnostic[] }
| { ok: false; diagnostics: Diagnostic[] };四条硬规则:
- 所有可能失败的阶段统一
Result<T>:parseDocument/resolveTheme/layoutDocument/buildScene。 ok: false只表示产不出可用值:contract 结构非法、layout 缺几何、build 入参不自洽。ok: true也带diagnostics:成功不代表零警告。- 调用方传错类型是编程错误(TS 编译期拦),运行期不做防御、不进
Result。
不做的 API
| 不做 | 为什么 |
|---|---|
renderToSvg(document) 一步到位 | 四段混一起,中间结果拿不到,无法单独测 |
导出 flattenScene | Scene 已可递归遍历;公开统一展开顺序会把内部实现细节变成契约 |
EdgeSpec.route | 路由是 layout 的事,不是边类型的事;要按类型分派就注入 Router |
withMiddleware(host, mw) | 场景在进 host 前已物化,没有绘制流可包;改写写成 Scene → Scene 纯函数 |
move patch | 顺序是文档的确定函数;结构性重排退化成 remove + create 仍然正确 |
DrawDocument.theme | 主题是呈现策略;写在文档里同一份数据就没法换主题 |
| 可改的全局注册表 | builtinRegistry 是模块级只读样板 base:要扩展就 createRegistry({ base: builtinRegistry }),handle 创建时也会浅拷贝成快照 |
诊断码
| code | 产生处 | 触发 |
|---|---|---|
SCHEMA_INVALID | contract | zod 结构校验失败(未知字段除外) |
UNKNOWN_FIELD | contract | zod unrecognized_keys |
DANGLING_REFERENCE | contract | 边端点 / children 引用了不存在的节点 |
UNKNOWN_PORT | contract | 边端点引用了节点上未声明的 port |
PARENT_CYCLE / MULTIPLE_PARENTS | contract | children 成环 / 多父 |
PIN_DANGLING | contract | layout.pins 指向不存在的 node |
PROPS_INVALID | theme / layout | 排版量或形状 props 非法;用默认值 |
UNKNOWN_SHAPE / UNKNOWN_EDGE / UNKNOWN_MARKER | build | type 未注册 |
UNKNOWN_TOKEN | build | 样式引用了 tokens 里没有的名字;退回到更早一层的同名字段(最外层 = 内置默认画法) |
LAYOUT_FAILED | layout / build | 引擎没给出某个节点的坐标、路由缺失 |
FALLBACK_USED | build | 形状 / 边 / marker 未注册时的回落标记 |