ライブコーディングアプリ「Casto」ができるまで

Casto」(きゃすと)をリリースしました。

アプリの使い方などは以下の紹介記事が詳しいです。

ひとことで言うと「リアルタイムで更新できるgist」(by @hideack)です。

きっかけ

41日前の会話。

結局「ペアプロ」は課題が多く、「ライブコーディング」のアプリとして発表しました。

ブラウザからファイルの更新を検知できるのか

肝になるのは「ローカルのエディタ(VimとかXcode)からの変更を、ブラウザで検知できるのか」という所だけど、ちょっと調べるとFile APIでできそうだということが分かりました。

javascript - Check if file has changed using HTML5 File API - Stack Overflow

この回答のサンプルをそのままMeteorにアップロードしてみたのがこちら。 ファイルを保存したタイミングで画面が更新できています。

ファイルの変更箇所を検知できるか

これはFile APIを単純に使うだけでは実現できなそうでした。

ファイルのどの部分が更新されたのかわからないと、編集中の位置を閲覧者が探さないといけない。数行のスクリプトならともかく数百行あるファイルを共有するときには致命的に使いにくくなりそう。

最初は「変更箇所をマークする記法をあらかじめ決めておいて、エディタでそれを入力してもらって目印にする」という方式を考えていたのですが、社内の開発者に相談したところ、@hikalin8686が、「変更前のテキストを保存しておいてDiffをとればいいのでは」というアイディアを出してくれて、その方法で実装しました。

変更した行がハイライトされています。

Diffは以下のライブラリで実現できました。

kpdecker/jsdiff

ブラウザ内でエディタをどう実装するか

Aceを使いました。すごいですねAce。超便利。

Castoではシンタックスの判定にファイルの拡張子を使いますが、拡張子からAce内のModeに変換するプログラムもAceのものを流用できました。

ace/lib/ace/ext/modelist.js at master · ajaxorg/ace

サーバーサイド - UI層

今回はRendrを使ってみました。

Rendrについては、

Rendr入門(1): Node.js + Backbone.jsでサーバ & クライアントを構築する”Rendr”の紹介

この記事で知って使いたいなあと思っていたけど、正直よく理解してなかったので、がんばってMongoDB / MySQLなどのバックエンド接続も含めてRendrで実装しようとしていました。

Rendr徒然 - 日記

そんなときにこの記事を読んで「Rendrらしい」アーキテクチャへの理解が進みました。

一般的なSPA (「Reder徒然」からの引用)

client             server
==========         ==============

+---------+  HTTP  +------------+
| Browser |<======>| API server |
+---------+        +------------+

一般的なSPAや、Web APIを使ったiOS/Androidアプリもこの形に近くなると思います(REMPもこの作りです)。

Rendrを使ったSPA (「Reder徒然」からの引用)

client             server
==========         ======================================

UI層                                       サービス層
===================================        ==============

+---------+  HTTP  +--------------+  HTTP  +------------+
| Browser |<======>| Rendr server |<======>| API server |
+---------+        +--------------+        +------------+

ビューに関係する「UI層」内はサーバー・クライアント問わずJavaScript / Backbone.jsで統一されるため、テンプレートやバリデートの使い回しがしやすくなります。

またSPAでは、バルクAPI(複数のAPIをまとめたAPI)がない場合、初回表示で複数のAPIを叩くことになって表示が重くなりがちです。 Rendrでは初回表示はUI層内のサーバーでテンプレートを組み立てて描画するのでこの問題はありません(少なくともクライアント側では)。

Rendrについては基本的な動作以外はまだ理解できてない部分が多いので、バージョンアップ含めて追いかけていこうと思います。

サーバーサイド - サービス層

Padrino製のStoryboards APIにあいのりする形で、@hideackがCasto用のAPIを構築しました。

デプロイ

こちらを参照。

Rendrで作られたnode.jsアプリをminaでデプロイする - テノニッキ (@hideack 's diary)

これから

イシューを淡々とこなします。Firefox対応がわりと重めですね。 対応しました。