Orbit 通向 v1.0 的长期方案:从 Runtime 代码到兼容性网络

规划主题: Orbit 1.0 — Stable Floating Interaction Platform
起点: v0.4 的 Runtime Hardening 与 Contract Alpha
规划日期: 2026-08-16

一、长期目标:v1.0 不是“大版本”,而是“可被依赖的承诺”

Orbit 的长期价值不能建立在 Music、Clock 或未来某一个 Widget 的功能稀缺性上。单个悬浮工具会被替代,单套拖拽与 Dock 代码也会被复刻。Orbit 真正可能形成不可替代性的路径,是让站点主题、Widget 作者与用户都开始依赖同一种悬浮交互兼容性

因此,v1.0 不应理解为“功能足够多”或“文档足够完整”,而应理解为:Orbit 已经能稳定地承诺一个跨主题、跨 Widget、跨版本的 Runtime Contract,并有真实的独立采用者证明该 Contract 值得依赖。

Orbit 1.0 的产品不是一批官方悬浮组件,而是一种让任何静态站功能获得一致空间、手势、生命周期、可访问性与用户偏好能力的开放运行时。

这一表述并不意味着 Orbit 要做成大型平台或云服务。相反,Orbit 的竞争力应来自轻量、可复制、可自托管、无框架与 local-first;这些特征与现有静态站定位一致。1 2 但“轻量”不能等于“只是一份好代码”。v1.0 必须让外部作者不用理解内部实现,也愿意把自己的 Widget 面向 Orbit 构建。

二、不可替代性的正确模型

Orbit 不应该试图通过封闭数据、专有账户或功能堆叠制造替代成本。那既偏离静态站与开源工具的气质,也会使产品与成熟 SaaS 正面竞争。更适合 Orbit 的模式是:开放协议 + 兼容实现 + 可移植用户连续性 + 生态验证

不可替代性来源 它解决的问题 Orbit 中的具体体现 不应误解为
稳定 Contract Widget 作者无需为每个主题重写横切交互。 一次面向 Orbit 的实现,获得挂载、拖拽、停靠、显隐、销毁、Launcher、Profile。 一个内部 registerHost 函数。
主题兼容性 站点维护者无需逐一手工协调 Widget。 主题只接入 Runtime 与 Manifest,多个 Widget 可统一运行。 官方只提供一个 Demo 主题。
用户连续性 用户的位置、可见性、偏好不因 Widget 更新而丢失。 local-first Profile、导入/导出、schema 迁移。 把用户数据锁在私有服务。
互操作网络 替换 Runtime 会破坏已有 Widget/主题兼容性。 独立 Widget、主题与工具都采用同一 Contract。 GitHub Star 或官方 Widget 数量。
可信治理 使用者敢于在自己的站点上长期依赖。 SemVer、兼容矩阵、弃用策略、安全边界与透明发布。 一次性发布 1.0 标签。

要注意:开源协议不会让 Orbit 的源码不可复制,但会让“重建所有兼容性、文档、测试、示例、用户 Profile 迁移与社区习惯”变得没有意义。真正的护城河不是锁定,而是被采用后形成的协调成本。如果到 1.0 前没有独立采用者,Orbit 仍可以是优秀库,但不应自称为平台。

三、v1.0 的产品边界

Orbit 需要坚定地做一个页面级微交互 Runtime,而不是逐步吞噬静态站的内容层、账号层、编辑层或 AI 层。边界越清楚,Contract 越稳定,第三方才越容易相信其长期方向。

Orbit 1.0 负责 Orbit 1.0 不负责
Widget 的挂载、生命周期、显隐、位置、停靠、空间协调和恢复。 内容管理、文章编辑、站内搜索、评论、推荐系统。
Pointer/keyboard/reduced-motion 等跨 Widget 交互约定。 Widget 的业务逻辑、业务数据模型和后端服务。
Launcher、可访问性基线、Profile 导入导出与错误隔离。 用户账号、强制云同步、广告、追踪与市场交易。
Widget/主题/Manifest 的兼容性与版本协商。 规定所有 Widget 必须使用同一视觉语言。
对静态 HTML、Hexo 等低构建依赖环境的友好接入。 成为 React/Vue/Next 等框架的通用应用平台。

这意味着,Reader、Music、Clock、站点状态等任何后续功能都只能是对 Contract 的证明,而不能倒逼 Core 为某一个业务做硬编码。当前 Runtime 已经开始避免在 Core 中写死业务 DOM id,这一原则应在 1.0 中成为硬性规则。3

四、通向 1.0 的阶段路线

版本号不是日历承诺。每个阶段只有在前一阶段的证据充分时才进入下一阶段。建议将路线分成 v0.4、v0.5、v0.6、v0.7–0.9、v1.0 RC 与 v1.0 六个阶段;若证据不足,应延长验证,不要用功能清单替代成熟度。

阶段 核心目的 对外状态 进入下一阶段的证据
v0.4 加固生命周期,发布 Contract Alpha 与 Profile Alpha。 实验性、仅建议试用。 三个异质 Widget 跑通同一 Contract;Music/Clock 重挂载无资源泄漏。
v0.5 把 Alpha 用于真实主题与外部作者试验。 Public Beta。 至少 2 个非核心维护的 Widget 或主题接入;发现并修复 Contract 缺口。
v0.6 收敛 Contract,定义 Manifest 与兼容性工具。 Candidate API。 Contract 变更明显下降;Widget 可由独立仓库发布与安装。
v0.7–0.9 兼容性、迁移、性能、安全和治理打磨。 Release Candidate 预备期。 至少一个完整升级周期无破坏性事故;跨浏览器/主题矩阵稳定。
v1.0 RC API freeze、生态回归与迁移演练。 除 P0/P1 问题外不再改 Contract。 独立采用者确认升级无阻;安全与可访问性门禁通过。
v1.0 发布稳定承诺与兼容政策。 Stable。 满足所有 1.0 发布门槛,而非仅完成开发任务。

4.1 v0.4:证明“Contract 可以存在”

v0.4 负责清理地基:Music 的资源回收、Clock 的 Contract 迁移、Reference Widget、Profile Alpha、DOM 集成测试与统一 CI。它不试图解决生态问题,只解决“Orbit 自己是否有资格要求别人依赖它”。具体方案见《Orbit v0.4 方案》。

4.2 v0.5:证明“外部人可以使用 Contract”

v0.5 的主任务不是增加官方 Widget,而是引入外部视角。至少选择两个与核心仓库不同的维护边界:一个 Widget 作者、一个主题维护者;最好两者都不参与 Runtime 内部开发。应让他们按公开文档完成接入,然后将他们遇到的阻碍记录为 Contract Issue,而不是由核心作者用私有知识绕过。

v0.5 可以提供以下最小分发形态:一个 Runtime 包、一个 Widget manifest、一个独立 Widget 包,以及一个主题适配示例。对静态站用户仍应保留复制 dist/ 的零构建接入;包管理器是可选便利层,不可成为唯一路径。

v0.5 的成功问题: 一个来自独立仓库的 Widget 能否不复制 GestureSnapLauncher、位置持久化或 DOM 清理代码,在两个不同主题中工作?如果答案是否定的,不应进入 API freeze。

4.3 v0.6:从“API 集合”成为“互操作协议”

v0.6 应冻结 Manifest 的基本形态,并建立兼容性协商。Runtime 与 Widget 不应只靠“能 import 就运行”,而应明确说明所要求的 Contract 版本、能力、样式资产和可选权限。Manifest 必须足够小,避免重演复杂前端插件平台的包管理问题。

1
2
3
4
5
6
7
8
9
{
"id": "org.example.status",
"name": "Example Status",
"orbit": { "contract": "^0.6.0" },
"entry": "./dist/widget.js",
"styles": ["./dist/widget.css"],
"capabilities": ["drag", "dock", "profile", "portal"],
"permissions": ["local-profile"]
}
v0.6 规范组成 目的 稳定性要求
Widget Manifest 声明 entry、样式、Contract 版本、能力与权限。 进入 Candidate,字段采用可扩展/可忽略策略。
WidgetDefinition 定义 mount/destroy/visibility/metadata。 以生命周期语义为核心,避免业务字段膨胀。
Runtime Service API 提供 layout、gesture、profile、portal、a11y。 错误、取消、资源所有权要有明确语义。
Profile Schema 允许用户导入导出和 Widget 状态隔离。 提供 schema version 与 migration hook。
Theme Adapter 约束主题如何加载 Runtime、Manifest、样式。 保持静态文件接入,不假设框架或后端。
Compatibility Report 在构建/运行前说明可否组合。 对不兼容版本给出可理解错误,而非静默失败。

此阶段还应发布一个小型开发工具,例如 orbit validate 或纯浏览器诊断面板,用于验证 Manifest、识别重复 id、缺失样式、未释放 portal 和 Contract 不匹配。工具的价值不在“更炫”,而在于让第三方接入成本可见、可诊断。

4.4 v0.7–0.9:证明“生态可以安全地演进”

v0.7–0.9 的工作重点是耐久性,不是扩张速度。需要完成三类验证:一是兼容性,二是性能与可访问性,三是治理与升级。

兼容性方面,应至少维护两个主题/部署形态、三个独立业务形态的 Widget,并让其中至少一个 Widget 经过一次非破坏性升级。性能方面,要在移动端验证多个 Widget 并存、低端设备拖拽、长列表/portal 和 reduced-motion;现有项目对 rAF 合并、backdrop-filter 与几何正确性已有意识,但应从文档原则走向可复现的基准和回归门禁。4

治理方面,需要建立公开的变更流程:Alpha 可以快速变化;Beta 需要迁移指南;Candidate 仅修复;Stable 采用 SemVer、支持窗口与弃用周期。所有 breaking change 必须同时提供旧 Contract adapter 或明确的 codemod/迁移指南。v1.0 不应让早期 Widget 作者在一次小版本升级后被迫重写。

五、1.0 的技术架构标准

v1.0 不要求最复杂的实现,但要求每一种副作用都有清楚所有者、每一种跨 Widget 交互都有清楚仲裁者、每一个扩展点都有错误边界。

5.1 Core 的稳定职责

Core 子系统 1.0 承诺 典型失败时的行为
Registry 校验 id、版本与 capability;维护实例目录。 拒绝冲突定义,并向诊断面板报告。
Lifecycle 统一清理 listener、timer、rAF、observer、media 等副作用。 一个 cleanup 出错不阻断其他清理,错误以 widgetError 事件报告。
Visibility 区分 hide 与 destroy,维护 aria-hidden 与 portal 可见性。 无 Root 时不无限重试;销毁状态不得被意外复活。
Space Coordinator 处理位置、碰撞策略、停靠和 viewport 变化。 根据 capability 降级,不强迫所有 Widget 可拖拽。
Gesture Router 拥有 pointer session 与快捷键冲突策略。 冲突时遵循优先级并保证 cancel 可达。
Launcher 从 Metadata 渲染 Widget 列表,并保持键盘与焦点可访问。 单个 Widget 元数据损坏不得导致 Launcher 崩溃。
Profile Store 命名空间状态、schema 升级、导入/导出。 忽略不认识/损坏的条目,不丢弃其他 Widget 状态。
Diagnostics 汇总版本、实例、泄漏提示、兼容性状态。 默认只读,不影响生产体验。

5.2 Widget 的稳定权利与责任

Widget 作者有权要求 Runtime 提供声明过的服务;也有责任遵守资源、DOM、状态与安全边界。这个对称关系应写入 1.0 Contract,而不是分散在示例注释中。

Widget 权利 Widget 责任
获取隔离的 Profile 命名空间和可移植状态。 不读取、修改其他 Widget 的 Profile。
请求受控 portal 以渲染 body 级 UI。 通过 Runtime 声明 portal,销毁时不留下节点或全局监听。
使用统一 gesture/layout 服务。 不自行注册与 Runtime 冲突的全局 pointer 流。
在 Launcher 展示 label、图标与可见性。 元数据必须安全文本化;不得依赖 Core 的内置 id。
通过事件与其他 Widget 协作。 只使用版本化、文档化事件;不得直接调用其他 Host 私有 API。

5.3 安全与隐私底线

Orbit 的开放扩展会引入比第一方 Widget 更大的输入边界。1.0 应禁止 Core 直接把外部 Widget 的 id、label 或元数据写进 innerHTML;应采取 DOM API、文本转义和 URL 协议校验。Widget 样式隔离在 1.0 可以先通过命名空间约定和文档实现,不必急于引入 Shadow DOM;但必须避免默认全局 selector 破坏主题。

Profile 默认仅保存在用户浏览器。任何未来同步能力必须是可选、显式同意、可导出和可删除的独立服务,不能成为 Runtime 的隐式网络行为。对于像 Music 一样依赖外部 API 的 Widget,Manifest 至少应声明网络能力,并在文档中给出 CSP、connect-srcmedia-src 说明。5

六、生态策略:先验证“被采用”,再追求“规模”

Orbit 最需要的不是大量官方组件,而是少量可信的独立采用。第一批生态不应追求市场,而应追求异质性与可复现性。

参与者 他们为什么会采用 Orbit Orbit 必须提供的交换价值 首批验证方式
静态站主题作者 不想为每个插件维护拖拽、移动端、z-index、可访问性。 一个稳定的 Theme Adapter 与统一入口。 在两个不同风格主题中加载同一 Widget。
Widget 作者 不想重复做生命周期、空间与管理面板。 Contract、Services、样板、诊断和版本兼容。 独立仓库发布一个非核心 Widget。
站点维护者 想组合工具而不让页面变乱。 Launcher、冲突管理、Profile 与可复制配置。 从 manifest 安装/移除多个 Widget。
终端用户 想保留自己的位置、可见性和微交互偏好。 local-first、低打扰、可恢复、可迁移。 导出 Profile 后在另一兼容站点/主题导入。

首批 Widget 的选择应围绕 Contract 的压力测试,而非热度。建议至少包含:一个带媒体/异步状态的 Widget(Music)、一个极轻量周期更新 Widget(Clock)、一个含 portal 或列表的 Widget,以及一个由外部作者实现的、与上述业务无关的 Widget。这样才能验证 Runtime 是否真的通用。

同样,主题适配需要两个不同约束:例如一个传统 Hexo 主题和一个纯静态 HTML/Cloudflare Pages 部署。若 Orbit 只能在自己的 Demo 样式和 DOM 结构中顺利运行,它就还不是通用 Runtime。

七、版本与治理政策

v1.0 的可依赖性不只取决于代码,还取决于使用者能否预测变化。应在 1.0 前公布以下政策,并实际执行至少一个 Beta → RC 的升级周期。

政策 1.0 承诺
语义化版本 Core Contract 的破坏性变化只出现在 Major;新增可选能力进入 Minor。
Contract 生命周期 experimentalbetastable 三阶段;每项能力均标记稳定性。
弃用期 Stable API 在至少一个 Minor 版本内给出 warning、文档迁移和可用替代。
兼容窗口 Runtime 明确支持哪些 Widget Contract 范围;不兼容必须可诊断。
安全修复 P0/P1 漏洞或资源泄漏优先 patch;公开说明影响范围与修复版本。
变更治理 影响 Contract 的 Proposal 必须有动机、替代方案、迁移和测试计划。
生态沟通 Changelog 区分 Runtime、Contract、Widget、Theme Adapter 与文档变化。

MIT 许可与开放开发仍然可以保持。真正需要治理的不是贡献权限,而是 Contract 的稳定性:不要让每个为 Music 手感而做的内部变化,意外成为所有第三方 Widget 的破坏性变化。

八、衡量进展的指标

Orbit 不应以“新增组件数”作为长期北极星。它要证明的,是部署者、Widget 作者和用户对同一 Runtime 的依赖正在增强。建议同时观察领先指标与结果指标。

类别 指标 为什么重要
Contract 可用性 从空模板到首个 Widget 可运行的步骤数与失败点。 衡量第三方接入摩擦,而不是核心作者熟练度。
复用深度 Widget 业务代码中未重复实现的 Runtime 横切能力数量。 验证 Contract 是否真正节省了拖拽、显隐、清理等样板。
生命周期可靠性 多次 destroy/remount 后监听、DOM、portal、media 的残留数。 这是第三方敢否依赖 Runtime 的基础。
生态独立性 非核心维护者的 Widget/主题数量及持续兼容版本数。 区分官方示例与真实采用。
用户连续性 Profile 导出/导入成功率、schema 迁移成功率。 证明 Orbit 开始承载可移植偏好,而非单页装饰。
升级信任 Minor 升级中无迁移失败的第三方 Widget 比例。 证明治理与兼容政策可执行。
体验质量 交互冲突、可访问性缺陷、移动端回归的 issue 数。 防止生态扩张破坏 Orbit 的低打扰哲学。

这些指标不一定全部公开,但它们应服务于一个判断:是否有人在没有核心作者介入的前提下,成功安装、开发、升级并维护 Orbit Widget。

九、v1.0 的 Go / No-Go 门槛

v1.0 最重要的纪律,是宁可继续发布 0.x,也不要用版本号掩盖未经验证的稳定性。以下门槛应作为发布清单而非愿景。

Go:可以发布 v1.0 的条件

维度 必须满足的条件
生命周期 所有参考 Widget 都通过自动化 mount/hide/destroy/remount/portal 清理测试;无已知 P0/P1 泄漏。
Contract WidgetDefinition、Runtime Services、Manifest、Profile Schema 已至少经过一个完整 Beta 升级周期。
外部采用 至少 2 个非核心维护的 Widget/主题组合,在不同主题或部署形态中持续可用。
兼容性 有公开兼容矩阵、诊断工具与一次成功的无破坏升级案例。
文档 新 Widget 作者可只凭公开文档完成接入;所有链接、示例、npm 包文件和迁移指南通过自动校验。
可访问性 Launcher、键盘操作、焦点恢复、reduced motion 和高对比基本场景有自动/人工回归。
安全与隐私 动态元数据安全渲染;Profile local-first;网络能力与 CSP 边界文档化。
治理 SemVer、弃用、支持窗口与变更 Proposal 流程已发布并试运行。

No-Go:应继续停留在 0.x 的信号

若 Contract 仍频繁因第一方 Widget 的临时需求而改变;若 Music/Clock 之外的 Widget 需要复制内部私有模块;若第三方主题接入需要核心作者手工调试;若 destroy/remount 仍可能残留监听;或若唯一采用者仍是 Orbit 自己的 Demo,那么 v1.0 都尚未到来。此时继续发布 0.6、0.7 或 0.9 是负责任的做法,而不是失败。

十、结论:让 Orbit 值得被替代之前先值得被依赖

Orbit 的目标不应该是让任何人“无法替代”它的代码;开源世界中那既不现实也不必要。更值得追求的状态是:Widget 作者、主题维护者和用户都发现,离开 Orbit 会失去一组已经验证过的兼容性、连续性与交互质量,于是没有足够理由去替换它

这条路径从 v0.4 的生命周期和 Contract Alpha 开始,但不在 v0.4 结束。v0.5 需要外部人使用,v0.6 需要协议收敛,v0.7–0.9 需要在真实升级中证明耐久,v1.0 才能对稳定性作出承诺。届时 Music、Clock 与其他 Widget 仍然重要,但它们的重要性不在“本身不可替代”,而在于它们共同证明:Orbit 已经成为静态站悬浮交互的可靠兼容层。

参考资料