公开 API
@dopejs/pingo 的导出即公开契约。内部包(@dopejs/pingo-host 等)不承诺稳定性,
迁移扫描器会阻止业务直接依赖它们。
快照即契约
公开面被固化在 benchmarks/api/facade.v1.d.ts 中,任何签名变化都必须显式更新该快照并经过审阅,
pnpm api:check 在漂移时失败。
根与宿主
createHostedCanvasRoot(canvas, options?): Promise<HostedCanvasRoot>
createCanvasRoot(context, core, options?): PingoRoot // 主线程 M1 路径
initializeWasm(input?): Promise<void>
createWasmCore(width, height, input?): Promise<CoreClient>
initializeWasm 让业务把 WASM 初始化纳入自己的启动或路由 loading。它在当前
JavaScript realm 内是幂等的:并发与后续调用共享第一次成功的初始化,失败不会被缓存,
可以重试;第一次调用决定自托管 input。Worker 是独立 realm,默认仍由 Host 在 Worker
中完成初始化。createWasmCore 会复用同一 realm 中已经完成或正在进行的初始化。
HostedCanvasRoot 方法:
| 方法 | 说明 |
|---|---|
render(node) |
提交一帧组件树 |
close() |
关闭 root、Worker 与 Core |
mode |
实际传输路径:sab / post-message / main-thread |
beginScroll / scrollBy / endScroll / cancelScroll |
直接操纵滚动 |
setScrollVelocity(target, x, y) |
由 Core 渲染时钟持续按逻辑像素/秒滚动;0, 0 停止 |
setReducedMotion(value) |
实时覆盖 Core animation 的 reduced-motion 策略 |
focusEditable / blurEditable |
激活或结束原生编辑会话 |
updateEditingGeometry |
手动提供 IME 几何(通常自动完成) |
transportMetrics() / inputTransportMetrics() |
mutation/input 传输与背压快照 |
mediaMetrics() |
媒体绑定、copy、掉帧、释放与在途帧快照 |
paintedText() |
最近一帧实际画出的文本,按绘制顺序 |
常用选项:onFrame、onHostError、onMediaMetrics、onEditTransaction、
onEventTransaction、onSemantics、onPaintedText、onNonPassiveRegions、transport、
rasterCache、accessibility、nativeTextInputMode。
元素与 JSX
createElement(type, props, key?): PingoElement
Fragment
主机元素:container、text、scroll、virtualList、editableText。
类型:CommonProps、ContainerProps、TextProps、ScrollProps、VirtualListProps、
EditableTextProps、EditableInputMode、Color、EdgeInsets、NodeHandle、Ref、
PingoNode、FunctionComponent。
M6 新增保持旧 intrinsic 兼容的基础组件:
View(props: ViewProps)
Text(props: TextProps)
Image(props: ImageProps)
Input(props: InputProps)
UnstyledTextArea(props: UnstyledTextAreaProps)
它们接受既有 direct props 与 style/className,分别映射到 container、text、image
和共享的 editableText 原语。View.virtual.axis 显式选择 "x" | "y" 主轴;ref 使用
ViewHandle,可调用 scrollTo、scrollBy、setScrollVelocity 与 capture,旧 root 滚动
方法继续兼容。
已发布的 TextArea 仍是带边框、padding
与 rows 布局的 widget,为避免 0.x 静默破坏暂不改名;无装饰基础组件因此使用
UnstyledTextArea 兼容别名。
JSX 运行时通过 @dopejs/pingo/jsx-runtime 与 @dopejs/pingo/jsx-dev-runtime 提供。
样式能力(M6)
createStyleSheet(cssOrObject, options?): PingoStyleSheet
compileStyleSheet(cssOrObject, options?): StyleSheetCompilation
supportsStyle(property, value): boolean
styleCapabilities(): StyleCapabilities
CSS_SUBSET_VERSION: string
createStyleSheet 编译同节点 class/compound-class selector、shorthand、cascade 与
computed-value 元数据;失败时抛出带结构化 diagnostics 的 StyleSheetCompileError。
compileStyleSheet 是不抛异常的对应入口。完整支持矩阵见生成的 CSS subset 表。
styleCapabilities().engineReady 为 true,每个属性的 engineSupport 为 m6-core。
root.styleMetrics() 暴露累计 resolution/cache hit/diagnostic/interaction variant 计数;
滚动热路径不进入 Shell resolver。输入变化时仍使用完整 resolver 保证结果可差分验证。
三个独立回滚选项为 styleResolverEnabled、foundationComponentsEnabled 与
interactionStylesEnabled;关闭后旧 direct props、intrinsic、事件与 virtualList 仍可工作。
SCSS / Less 构建期预处理
SCSS/Less 不进入 facade 或浏览器运行时。需要生成 pingo stylesheet 的 Vite 应用安装
@dopejs/pingo-style-preprocess,并启用独立的 Node-only 插件:
// vite.config.ts
import { pingoStylePreprocess } from "@dopejs/pingo-style-preprocess/vite";
import { defineConfig } from "vite";
export default defineConfig({ plugins: [pingoStylePreprocess()] });
然后用显式 query 区分 pingo stylesheet 与普通 DOM CSS:
/// <reference types="@dopejs/pingo-style-preprocess/client" />
import buttonSheet from "./button.scss?pingo-style"; // PingoStyleSheet,不注入 DOM
import "./site.less"; // 普通 Vite DOM CSS
?pingo-style 在构建期完成 Sass/Less 编译、依赖边界检查、source-map 诊断和 pingo CSS
subset 校验;partial/import 会加入 Vite watch graph。Node API 还提供
compileScssString、compileLessString 与 compilePingoStyleFile。完整约束和回滚方式见
SCSS / Less 支持设计。
Core 动画(M7)
CommonProps.transition 接受单条或每属性一条 TransitionSpec;animation 接受
KeyframeAnimationSpec,首期属性严格限于 opacity 与六元素 affine transform。支持
delay、duration、CSS easing/cubic-bezier/steps、iteration、direction、fill 与 playState;
暂停/恢复保持逻辑进度,retarget 从当前 presentation value 继续。Host 默认跟随
prefers-reduced-motion 的实时变化,也可用 reducedMotion 初值和
root.setReducedMotion() 覆盖。
coreAnimationEnabled: false 是独立回滚开关:Shell 仍提交 durable 最终值,但不定义
animation resource。它不回退 ABI;旧 Core 必须通过正常 ABI 协商拒绝 ABI 15。
CSS 文本中的 transition-* / animation-* longhand 尚未加入 subset;M7 公开的是结构化、
类型安全的组件属性,Core 始终不解析 CSS。
Video(M8)
Video(props: VideoProps): PingoElement
detectMediaCapabilities(): MediaCapabilities
VideoProps 提供 src、poster、autoPlay、loop、muted、crossOrigin、preload,
以及 onPlay、onPause、onEnded、onLoadedMetadata、onTimeUpdate、onError。
ref 的 VideoHandle 提供 play()、pause() 与 seek(seconds)。尺寸与
style.objectFit/objectPosition 由 Core 计算,HTMLVideoElement、解码与 audio 始终留在 Host。
主线程使用 html-media 零 copy 路径;Worker 优先使用 transferable VideoFrame,不可用时
使用 ImageBitmap copy。路径通过媒体帧的 FrameReport.mediaPath 观测,资源与背压通过
root.mediaMetrics() / onMediaMetrics 观测。每个 Video 最多一帧传输在途,突发帧丢旧保新;
解绑、替换和关闭 root 会清理浏览器资源。videoEnabled: false 是独立回滚开关。
响应式与 hooks
(signal, computed, effect, batch, untracked);
(useState, useSignal, useMemo, useCallback, useRef, useEffect);
(createContext, useContext); // Provider 作为元素类型:<ctx.Provider value={...}>
类型:Signal、ReadonlySignal、RefObject、Unsubscribe、PingoContext、ContextProvider。
useContext 沿组件 owner 链读最近 Provider;Provider value 变化只重渲染订阅的消费者,
并穿透 memo(signal 失效路径)。用 hooks 的组件必须经 createElement/JSX 使用,
直接函数调用没有组件作用域。
编辑
TextEditingController;
useTextEditingController(options);
类型:EditTransaction、EditingGeometry、EditingSelection、NativeTextInputMode。
Widgets
TextField(props): PingoNode
TextArea(props): PingoNode
Pressable(props): PingoNode
Button(props): PingoNode
Pressable 与 Button 只组合 View/Text 和既有事件/语义,不引入 Core control kind。
语义镜像为 button 提供 Enter keydown 与 Space keyup 默认激活;disabled 同时移除事件、
焦点顺序和原生语义激活。
无障碍
SemanticTreeMirror
getByRole(root, role, { name? }): HTMLElement
queryAllByRole(root, role, { name? }): HTMLElement[]
类型:SemanticNode、SemanticMirrorNode、SemanticTreeMirrorOptions。
渲染侧的对照断言用 onPaintedText / paintedText():语义树说节点是什么,它说这一帧
实际画出了什么。类型:PaintedTextRecord、PaintedTextSnapshot。见
无障碍与可测试性。
字体
createFont(options): PingoFont
loadFont(source, options?): Promise<PingoFont>
支持 TTF / OTF / TTC / WOFF / WOFF2(WOFF2 解码器按需动态加载)。
类型:PingoFontSource、PingoFontOptions、PingoFontLoadOptions、
PingoFontLoadError、PingoFontLoadErrorCode、Woff2Decoder。
发布与诊断
ENGINE_VERSION: string
ENGINE_ABI_VERSION: number
engineIdentity(): { version, abiVersion }
verifyWasmIntegrity(bytes, manifest): Promise<void>
WasmIntegrityError 在自托管 WASM 与构建 manifest 不一致时抛出。见诊断。
迁移边界
@dopejs/pingo-compat 是独立的边界包,提供 mountCompatPage 做按页面灰度与回退。
详见迁移指南。