3 min read

Misora 開発ノート Part.5

Claude Code を利用して静的サイトとして WebRTC SFU Sora さえあれば利用できるミーティングツールを開発している。プロダクト名は Misora (み空色) 。

今までのまとめはこちら

全くコードは書いていない。テストコード以外も少しずつ見るようにしている。CLAUDE.md をしっかり書いて、指示は複雑なタスクになりそうな場合は、かなり詳細に指示してる。E2E テストとコンポーネントテストはかなりしっかりレビューしている。

せっかくなのでメモを定期的に書いている。

統計機能

ミーティングツールによくある「このルームって誰が参加して、どんな状況だったのだろう」というのをクライアント側で実現する仕組みを DuckDB-Wasm (OPFS) を利用する事で実現することにした。

/stats にアクセスするといいままでの統計情報がみれるようにした

中身は至ってシンプルでミーティング中に Sora のシグナリング通知を DuckDB-Wasm (OPFS) に突っ込んでおき、それを /stats で表示するという仕組み。

グラフライブラリはいったん Claude Code にお任せして chart.jsreact-chartjs-2 を採用した。

Web Locks API

DuckDB-Wasm (OPFS) を使うときの最大の課題が「複数ページから DuckDB-Wasm を利用しようとすると破綻する」というもので、これは仕様上仕方が無い。

解決する方法は現状ほぼない。本来は SharedWorker を利用する事で、複数ページから安全に DucKDB-Wasm (OPFS) を利用できるようにしたいのだが、DuckDB-Wasm 自体が Worker を利用しているため、Worker の中で Shared Worker として動かすことができない。

となると「あるページで DuckDB-Wasm を利用している時は、他のページでは利用できなくする」という戦略をとるしかない。

ここで登場するのが Web Locks API だ。その名の通りロックを取る API で、ブラウザのタブを落としたり更新したりするとちゃんとロックを外してくれるナイスな API 。

これにより統計ページやミーティングページで DuckDB-Wasm 利用時はロックをとり続けるという仕組みで無理矢理 DuckDB-Wasm を触るタブを一つに保証している。

実際に片方でロックを取って、タブを落としてロックが外れてもう片方で表示される

この方法が良いかどうかは正直わからないが、現時点で複数ページで DuckDB-Wasm を触る可能性がある場合は、回避策がほぼないので致し方ない。ちなみにかなり安定して動いているので、よしとする。デッドロックも基本おきていない。ページ読み込み時に定期的にロックが外れているかを見続ける仕組みにしているが、まぁ大丈夫だろう。

OPFS に保存した DuckDB ファイルのパージ

これがまぁまぁやっかいで、データベースの構造を変えたりしたときにパージする必要がある。マイグレーションなんてめんどくさいのでやらない。

丁寧に削除する必要がある。

一応モーダルを簡単に付けた

packege.json

グラフ関連が増えた。chart.js / react-chartjs-2 これが良いかはまだ判断していない。できれば軽量な react 向けのライブラリを使いたい。

  "dependencies": {
    "@duckdb/duckdb-wasm": "1.29.1-dev261.0",
    "chart.js": "4.5.0",
    "jose": "6.0.11",
    "react": "19.1.0",
    "react-chartjs-2": "5.3.0",
    "react-dom": "19.1.0",
    "react-router-dom": "7.6.3",
    "sora-js-sdk": "2025.2.0-canary.1",
    "zustand": "5.0.6"
  },

サイズ

グラフやら DuckDB-Wasm の Wasm やそれを使う Worker で容量ががっつりふえたが、これは必要になるときまで読み込まないみたいな仕組みを追加予定。

全員が毎回これを読み込むべきかも検討する。

vite v7.0.2 building for production...
✓ 346 modules transformed.

dist/index.html                                        0.45 kB │ gzip:     0.29 kB
dist/assets/duckdb-browser-eh.worker-B6HdX64c.js     751.49 kB
dist/assets/duckdb-eh-BdKO50rA.wasm               33,454.60 kB │ gzip: 7,337.00 kB
dist/assets/index-BD3WDMj7.css                        36.94 kB │ gzip:     7.37 kB
dist/assets/index-B2Wj3a8-.js                        821.11 kB │ gzip:   238.60 kB

ここまでのコード量

1 行も自分では書いてない。統計ページを増やしたのと、それに伴いコンポーネントテストや E2E テストが増えたので、まぁ妥当な増加量という印象。

今後

統計機能はそもそも全員に必要かどうかがわからないので、どうするかを考える。まずはミーティング参加者全員は無理矢理統計情報を取って貰う事にする。ライブ機能ページでは収集しない。

ライブ機能、統計機能と実現したかった機能があっさりできたので、これらをより安定化させて、バグを取ったり挙動をどうするかを検討していきたい。

ミュート通知機能と挙手機能は優先度下げる。

ただ、視聴者側で受信する映像の画質を選択できる仕組みは追加したい。そもそも Sora 自体に自動で画質を切り替える仕組みを用意する予定なので、そちらが来れば色々素敵な感じになりそう。

雑感

Web Locks API を試すとき、かなり試してみたが、とても良い感触だった。Playwright によりコンテキストを同一にすることでロック状態を気軽に再現出来るのも良い。

また DuckDB-Wasm のコード自体を Claude Code に調べてもらい、DuckDB-Wasm (OPFS) での制限を明確にしてしてもらったのも良かった。やはり調査が圧倒的に優秀なのは便利すぎる。

とにかくトライアルアンドエラーを繰り返し続けるためのテストは本当に重要という印象。