anti scroll

ブラウザと小説の新しい関係を模索する

RxJSとvirtual-domで、拡張可能なreactiveアプリケーションを作るリアクティブ・アダプター - inga

inga(因果)は、軽量で拡張可能なリアクティブ・アダプターです。RxJSとvirtual-domを使っています。

github.com

よくあるTodo-MVCは100行ぐらいです。

inga/todo-mvc.js

特徴

  • 軽量なこと。全ソース合わせても100行ちょっとしかないです。
  • プラグインで拡張可能です。
  • 副作用の処理をthunkで扱うストリームがデフォルトで付いているので、大抵のイベント処理はこれで済みます。

簡単なサンプル

例えばクリックする度にカウンタが増える、みたいなのは次のようになります。

var Inga = require("inga");

Inga.define({
  domRoot:"#app",
  dataSource:new Inga.ActionStateStream({
    initialState:{clickCount:0}
  }),
  virtualView:function(ctx){
    return h("button", {
      "ev-click":function(ev){
        ctx.action.emitUpdater(function(state){
          state.clickCount++;
        });
      }
    }, ctx.state.clickCount);
  }
});

プラグインを使ったサンプル

例えばinga/plugins/scroll-posを組み込むと、こんな感じでレンダリング・コンテキストの状態オブジェクトにscrollPosが合成されます。

var Inga = require("inga");

Inga.define({
  domRoot:"#app",
  dataSource:new Inga.ActionStateStream({
    initialState:{scrollPos:{x:0, y:0}},
    // plugin 'scroll-pos' combines 'scrollPos' to status object.
    plugins:[
      {module:require("inga/plugins/scroll-pos"), options:{combine:true}}
    ]
  }),
  virtualView:function(ctx){
    return h("div", [
      h("p", "x = " + ctx.state.scrollPos.x),
      h("p", "y = " + ctx.state.scrollPos.y)
    ]);
  }
});

自前のストリームを合成するサンプル

デフォルトのストリームに、自分で作ったストリームを組み込む場合は次のようにcombineアクションを定義します。

var Rx = require("rx");
var Inga = require("inga");

Inga.define({
  domRoot:"#app",
  dataSource:new Inga.ActionStateStream({
    initialState:{width:window.innerWidth},
    actions:{
      // extend default stream by your own source.
      combine:function(initial_state, upstream$){
        var width$ = new Rx.Observable.fromEvent(window, "resize")
          .debounce(250)
          .map(function(event){
          return window.innerWidth
        })
        .startWith(window.innerWidth);

        return upstream$.combineLatest(width$, function(state, width){
          state.width = width;
          return state;
        });
      }
    }
  }),
  virtualView:function(ctx){
    return h("p", "current window width = " + ctx.state.width);
  }
});

その他

ライセンスはMITです。