Skip to content

2026年のSelf-hosted LiveSync (v1.0~) ​

みなさんこんにちは。きみのぶです。

さて、前回必ず3部作を書くと言っていましたが、私の異常な多忙により、ずーっとのびのびになっておりました。なので、第2部・第3部合わせた記事って感じですね。

と言うことで、一旦仕切りなおすべく、Self-hosted LiveSyncの、1.0での大躍進をガンガン紹介していきたいと思います。

コアの分離とcommonlibの共通化 ​

今まで、Self-hosted LiveSync(と、関連ツール)は、commonlibをサブリポジトリとして読み込んでいました。このメンテ、僕が、Self-hosted LiveSyncについてやる分にはめちゃくちゃ簡単だったんですが、それ以外の場合ーーつまり、コントリビューションを頂いたりするときーーに超大変だったんです。(あともちろん、livesync-bridgeなんかが遅れがちとかもありました)。特にcommonlibの方にタグなんかも付けてなかったので、どこからどう直ってるかとかもわかりにくかったですし、再利用性を考えているようで、あんまり全然考えられていませんでした。

ということで、これをちゃんと切り出して、npmに登録しました。Self-hosted LiveSyncのコンパチ系を作るときは、皆さんぜひ使ってください。

翻訳リソースなんかも最初はcommonlibに入れてたんですが、これもなんか微妙だったので、Self-hosted LiveSync側に移すように変更したりで、今はかなりみなさんの貢献を受け付けやすくなっています[1]。

CLIとかの強化 ​

Issueでも要望を受けていた、Self-hosted LiveSyncのファイルを取り出したりなんかするツール、これ、前々回で書いたようなモジュール構造の変更などをやってると、なんかいけそうな感じになってきたんです。おりしもOSSメンテナとしてCopilotを使わせてもらえるようになったりで、この辺もガリガリと再設計をして、結局いわゆるHexagonal Architectureとして落ち着きつつ、実装できました。なんというか、叡智というのはあるんですね。ほんと。

CLIができると、実はテストもグッと品質を上げることができました。というのも、コアロジックは本物な上、コマンドラインからテストできるので、結構な問題をこの過程でつぶしました。シェルスクリプトで間に合ったというのも大きいです。今はDenoベースのテストになってますけど。

実のところ、CLIは私は常用というほど使ってはいないのですが、いざというときに使えるので、やはり実装してよかったな、と思ってます。(プルリクエストで、デフォルトモードとしてDaemonモードを採用してほしいというのがあり、へぇ、と思ったぐらいです)。

P2P同期のExperimental卒業 ​

共通化などを行ったことによって、P2P同期もかなり堅牢になりまして。というのも、なんとCLIからもできるようになったんです。その結果、これもポロポロと不備が発見され……修正されました。

その過程で、UIも操作しづらいなぁということで書き直されてかなり使いやすくなって。そのおかげで、今や立派な同期経路になっています。Diag的に接続できないかったコネクション数がわかるなどの微妙な改善も行われています。

加えて、そこまでやっても、コネクションが確立しないケースがあるんだな、とようやく認識しまして[2]…オプションとしてTURNサーバを使う機能、そしてCloudflareのRealtime APIを呼んでTURNサーバを使う機能を実装しています。

なので、今の Self-hosted LiveSyncは割としっかりした Serverless LiveSync にもなります(厳密にいえばServerはありますけどね)。

Q: Cloudflareええんか? ​

めっちゃ悩みました。Self-hostedちゃうやんけ、と。

まぁ、いうてIBM Cloudant[3]だってSelf-hostedではない、と言われればそうですし……とか言い訳をいろいろ考えまして……。

ただ、超悩んだ結果、Self-hosted LiveSyncに関しては下記の指針でこういうモジュールを含めることにしました。

  1. 完全にオプショナルな事
  2. メンテちゃんとすること
  3. サードパーティーに依存するよ、と書くこと

なので、上記の条件に一致する場合は、PRもらえればちゃんと読みます。TURNサーバのように、原理的にWebRTCの中身を見ないものであれば、より気持ちが楽ですね。

複数接続の保持 ​

Self-hosted LiveSyncは、実は'単一のサーバ'を想定していません。サーバは任意のタイミングで切り替えられるようになっています。これは、Object Storage同期なども同じで、基本的には、フットワーク軽めにこの辺りを変えられるようにしています。とはいえ、UIとしてはそんな風になっていませんでした[4]。

そこで、v1.0.0からは、複数の接続を保持して、切り替えられるようにしています。新しいサーバを立てたら、そっちを設定して、ちゃんと同期できてから前のサーバを落とす、みたいなことが可能になりました。

この関連で、切り替えたときにtweakが不一致だと非常に面倒なので、tweakの自動更新なんかも実装してます。tweakの警告、めちゃくちゃ評判悪かったですからね。

UI周りの改修・オンボーディングの改善 ​

これもまぁ、本当にひどかったので、いろいろ直しました。'オンボーディングがわかりづらすぎる'。これ、いわゆる知識の呪いにかかっていることが本当にありありとわかりました。(というのも、AIに読ませて、少しわかりにくいですが、こういう機能ですみたいな忖度のこもったコメントを頂いたので……)。

要らない選択肢とかもそもそも減らしましたし、モーダルダイアログとかも減りました(消えないNoticeで出ます)。

この辺りから、AIをかなり活用して対応してます。

競合解決の堅牢化 ​

これは本当に、ここできっちり固められてよかったなって思ってます。v1.0.0からしばらくは何度も修正してますが、ちゃんと言語化したから直せたよな、とか思うレベルです。たとえば、Self-hosted LiveSyncはConflictを不正な状態ではなく、一級市民として扱う、とか。

結構な言語化をしたので、いっそ、と JOSS形式で超真面目に設計思想も書きました。お時間があったら読んでみてください。

あと、研究者の方……Self-hosted LiveSyncを研究に使ってたらCiteしてください……そしてできればご一報ください。ZenodoのDOIは10.5281/zenodo.22065456です。


  1. というのも、翻訳PRが本体のリポジトリ側だけで受け付けられるようになったんです。 ↩︎

  2. 僕はこういうケースはあっさりTailscaleに入れて解決してました。 ↩︎

  3. 名指ししている製品はこれだけのはず。Object StorageとかBucketとか歯に何か挟まったような物言いをしているのは意図的です。 ↩︎

  4. 唯一、P2P同期だけが、ほかの同期方法と同時に使える接続でした。 ↩︎

Updated at: