Orbit 通向 v1.0 的长期方案:从 Runtime 代码到兼容性网络
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 能否不复制 Gesture、Snap、Launcher、位置持久化或 DOM 清理代码,在两个不同主题中工作?如果答案是否定的,不应进入 API freeze。
4.3 v0.6:从“API 集合”成为“互操作协议”
v0.6 应冻结 Manifest 的基本形态,并建立兼容性协商。Runtime 与 Widget 不应只靠“能 import 就运行”,而应明确说明所要求的 Contract 版本、能力、样式资产和可选权限。Manifest 必须足够小,避免重演复杂前端插件平台的包管理问题。
1 | { |
| 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-src 与 media-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 生命周期 | experimental → beta → stable 三阶段;每项能力均标记稳定性。 |
| 弃用期 | 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 已经成为静态站悬浮交互的可靠兼容层。




