Show HN: YAOS – Obsidian 的一键部署、实时同步引擎
1 分•作者: kavinsood•5 个月前
嗨 HN,
我是一位 Obsidian 的重度用户。
最近我厌倦了两种常见的同步方案的权衡:
1. 基于文件的同步(iCloud/Dropbox/Syncthing),让你等待更改传播,或者给你一个“冲突副本”。
2. 自托管设置(如 CouchDB),需要操作虚拟机和 Docker 化的数据库来同步 Markdown 文件。
所以我构建了 <i>YAOS</i>:一个本地优先、实时的 Obsidian 同步引擎。
自托管 OSS 应该有更好的用户体验。
你可以一键将后端部署到你自己的 Cloudflare 账户。它完全符合 Cloudflare 的免费套餐(对于普通的个人使用,每月花费 0 美元),并且完全不需要终端交互、SSH 和 env 文件。
你可以立即试用:<a href="https://github.com/kavinsood/yaos" rel="nofollow">https://github.com/kavinsood/yaos</a>
<i>它在幕后是如何工作的:</i>
* 文本同步使用 Yjs CRDTs。它同步实时的按键和光标,而不是将库视为一堆稍后要推送的文件。
* 每个库映射到一个 Cloudflare Durable Object,为你提供一个低延迟、单线程的边缘协调器。
* 后端在 DO 的 SQLite 存储之上使用分块的 Checkpoint + Delta-Journal MVCC 存储引擎。
* 附件通过 R2 单独同步(这是可选的——文本同步在没有它的情况下也能正常工作)。
这个项目中最难的部分是将 Obsidian 的同步 UI 和嘈杂的 OS 文件监视器与内存中的 CRDT 图连接起来。我不得不构建一个尾随边缘快照排水器,将快速的 IO 突发(如运行查找和全部替换)合并成原子 CRDT 事务,以防止无限的写入循环。
目前的设计为每个库保留一个单体 CRDT。这对于普通的个人笔记来说很好,但有一个硬内存上限(大约 50MB 的原始文本)。我选择了这种权衡,因为我更关心快速、可靠的实时人体工程学,而不是无限制的企业规模。
我还在 GitHub 上写了关于棘手部分的工程笔记(例如,处理离线文件夹重命名冲突,而不会恢复已删除的文件)。
在过去的三个星期里,我一直在进行残酷的 QA 检查,以强化移动设备重新连接、IndexedDB 配额失败和离线分裂脑目录重命名。
我很乐意收到关于架构、代码或我所做的权衡的反馈。我会在帖子中回答问题!
查看原文
Hey HN,<p>I'm a heavy Obsidian user.<p>I recently got tired of the two usual sync tradeoffs:<p>1. File-based sync (iCloud/Dropbox/Syncthing) that leaves you waiting for changes to propagate, or hands you a "conflicted copy."
2. Self-hosted setups (like CouchDB) that need touching VMs and dockerized databases to sync markdown.<p>So I built <i>YAOS</i>: a local-first, real-time sync engine for Obsidian.<p>Self-hosting OSS should have better UX.<p>You can deploy the backend to your own Cloudflare account in one click. It fits comfortably in Cloudflare's free tier (costing $0/month for normal personal use), and requires absolutely no terminal interaction, no SSH, and no env files.<p>You can try it out right now: <a href="https://github.com/kavinsood/yaos" rel="nofollow">https://github.com/kavinsood/yaos</a><p><i>How it works under the hood:</i><p>- Text sync uses Yjs CRDTs. It syncs real-time keystrokes and cursors rather than treating the vault as a pile of files to push around later.
- Each vault maps to a Cloudflare Durable Object, giving you a low-latency, single-threaded coordinator at the edge.
- The backend uses a chunked Checkpoint + Delta-Journal MVCC storage engine on top of the DO's SQLite storage.
- Attachments sync separately via R2 (which is optional—text sync works fine without it).<p>The hardest part of this project was bridging Obsidian's synchronous UI and noisy OS file-watchers with the in-memory CRDT graph. I had to build a trailing-edge snapshot drain that coalesces rapid-fire IO bursts (like running a find-and-replace-all) into atomic CRDT transactions to prevent infinite write-loops.<p>The current design keeps a monolithic CRDT per vault. This is great for normal personal notes, but has a hard memory ceiling (~50MB of raw text). I chose this tradeoff because I cared more about fast, boringly reliable real-time ergonomics than unbounded enterprise scale.<p>I also wrote up engineering notes on the tricky parts (like handling offline folder rename collisions without resurrecting dead files) on GitHub.<p>I've spent the last three weeks doing brutal QA passes to harden mobile reconnects, IndexedDB quota failures, and offline split-brain directory renames.<p>I'd love feedback on the architecture, the code, or the trade-offs I made. I'll be hanging out in the thread to answer questions!