Skip to content

Self-hosted LiveSync 1.0に先立って

皆さんお元気ですか。きみのぶです。
Self-hosted LiveSync 1.0に先立って、筆を執らねばと思い、記事を書いています。
真面目に話さないと、と思ったところがちょっと堅苦しくなってますが、最後までお付き合いいただければと思います。
前回の三部作はどうなってるんだ、とお思いの皆様、大丈夫です。ちゃんと書きます。

1.0へ向けた大きな見直しの発端は、Community Directory Reviewで多くの問題を指摘されたことでした。もう本当に、めちゃくちゃに悪い点数です。

PARTICULARLY BAD SCORE

これまでは、サブモジュールが検査対象にならないことへの対応として生成した型定義をリポジトリへ含めたり、CLIのためにESLintの除外を追加したりしていました。いずれも、その時点ではビルドやreviewを成立させるための現実的な回避策でした。とはいえ、それらが積み重なるにつれて、構造上の問題を解決するのではなくかえって見えにくくしていたことに気付きました。

今回の変更がめちゃくちゃに大きいのは、私が今後こういうリリースをしていく、という意味ではありません。むしろ、これまで先送りしてきた問題が多すぎたのだと思ってます。よく、本質的に難しいと述べたりもしていましたが、あまり褒められた態度ではないと真剣に反省しています。みなさんにこの複雑さを受け入れる負担を押しつけていたな、と。実際にテストを行ってみて「ああ、全然ダメかもしれない」と何度も思いましたし。トラブルシューティングに関しては全面的に書き換えました(嘘じゃないか、と指摘されましたし)。

そうなんです、今回、調査やリグレッションテストの作成や実際の修正には、AIをかなり広範囲に使用しています。検証も修正もさせています。OpenAIのご厚意により、Codex for Open Sourceをこのプロジェクトで試す機会をいただいたためです。 ただし、AIの出力そのものを品質の根拠にはしていなくて。変更の判断、レビュー、公開の責任は、これまでどおり私が負っています(少なくとも、そのつもりです)。コミット歴を敢えて残してありますが、変更権限や公開操作を明確に区切り、単体テスト、統合テスト、実際のObsidianを使ったE2E、そして実機での確認を組み合わせながら進めてきました。(ちなみに、具体的な指示に興味がある方は、私のdotfilesをご参照ください)。
AIを使っていて心強いのは、見落とした前提や過去の判断を、何度でも調べ直せることです。先ほども触れましたが、その過程で、多数の文書の不備、分かりにくい設定導線、古い回避策、そして実装と説明の食い違いが見つかりました。本当に、これはひどかったと思ってます。

再利用性についても、大きく見直しました。

livesync-commonlib のIssue #1を開いたのは、2022年のちょうど同じ時期でした。当時の英文を読み直すと、成長したなと感じます。その後も何度か、npm packageとして公開しないのかという質問をいただきましたが、当時の私は「グローバルに公開するにはニッチすぎる」と考えていました。しかし、利用するプロジェクトや用途が増えるにつれ、妥当性を欠いているんでは……? と思い始めていました。とはいえ、すぐに着手できる問題でもなく。結果として非常に腰の重い作業になってしまいましたが、Self-hosted LiveSync 1.0を機に、ようやく4年越しでCommonlibをnpm packageとして公開できました。

Self-hosted LiveSyncや関連プロジェクトのビルドが難しかった原因はいくつもありますが、Commonlibをサブモジュールとして扱い、境界を越えて内部ファイルを利用していたことは、その中でも割とデカめの問題でした。今回、その境界を明確にし、翻訳カタログもSelf-hosted LiveSync側で管理する形に改めた事により、安定性も上がりましたし、独立性も高まりました。あと、いくつか構造を逆転させているため、翻訳への貢献もLiveSync側の一つのリポジトリで受け付けられるようになりました(新しいメッセージの追加は別です)。これで、Pull Requestが複数の場所へ散らばりにくくなると期待しています。

もう一つの大きな変更がFancy Kitです。

私はSelf-hosted LiveSyncのほかにも TagFolderDifferential ZIP Backup など、いくつかのObsidian plug-inを開発しています。それぞれに似たUI、dialogue、テスト補助、及びObsidianとの接続処理があり、同じようなCommunity Directory Reviewの指摘を受けていました。
これも最初は個別に対応していましたが、結局個別に直し続けるだけでは同じ問題を繰り返すのでは……? と思い至りまして。。今回、併せて、再利用可能な境界を持つものをFancy Kitとして整理し、それぞれ npm package として公開しました。すべてを共通化したのではなく、複数の plug-in で責任範囲を説明でき、テストできる部分に絞っています。結果として、皆さんにも活用してもらえるんじゃないかな、なんて、これも期待しています。このFancy Kitの最大の存在意義は、ただ単に戦闘証明済という事なんですけど。

そうそう。自動テストも大幅に増えました。

少し前から、Self-hosted LiveSyncには本物のObsidianを起動してセッションを検証するE2Eテストがありました。既存のObsidianを自動テストするツールだけでは、このplug-inを入れ替えたり、再起動させたり、複数Vaultで同期させる、といったあまりにニッチな用途にうまく合わず、コツコツ書いていたのです。今回はこれも、継続的に実行できるテスト基盤として整理しました。がっつり活用してみると、少しどころか、たくさん機能は足りませんでしたし。今回はCouchDBだけではなく、ほかの同期方法(Object Storage、P2P)とか、Setup URIなどのシナリオに沿ったテスト、それと、ちょっと前から課題になっていた競合解決等。あとは、よく話題に挙がっていたHidden File Sync等も自動化できる範囲で検証しています。そうそう。スクリーンショットなんかも撮れるようにしていて、これからドキュメントを作っています。副次的なもので、スクリーンショットがあれば、私もあとから確認がやりやすかった、というのもあります。

とはいえもちろん、テストが多ければよいというものではありませんし、テスト自体もコストがかかります。今後は、各テストが何を保証しているのかをハッキリさせつつ、役割を失ったものや、現実には起こらない状態だけを検証するものを整理していく必要があります。今回は、とにかく検証を行うために、非常に過剰に書いてあると私も思ってますから。なので、過剰に構えないでください。(本当に、ちょっとやりすぎたとは思っています。)

今回の作業によって、長く残っていた技術的負債のかなりの部分を返せたと思います。もちろんまだまだ問題は残っているでしょう。しかし、今後の変更を、もう少し小さく、理解しやすく、検証しやすくするための土台はできました。破壊的な変更も、これまでより減らしていきます。

現在Pull Requestを送ってくださっている皆さんには、ソースの読み直しや、場合によっては対応の調整をお願いすることになると思います。せっかくの貢献を長くお待たせしてしまい、申し訳ありません。

これからも、皆さんからのIssue、Pull Request、翻訳、検証、及びフィードバックをお待ちしています。

Updated at: