webStorage を便利に使う angularJS用モジュールを作った

- 2015/12/22 追記
    - [stegomaさんの記事](http://qiita.com/stegoma/items/843fc29156c6a2de4fee) によると、[v0.3.8](https://github.com/gsklee/ngStorage/tree/0.3.8) から ngStorage でも prefix を設定出来るようになったようです。車輪の再発明する前にプルリクを投げましょう… orz  
以下は [v0.3.0](https://github.com/gsklee/ngStorage/tree/0.3.0) を元にした記事（と思われる。記事の投稿時期的に。）

# 以下本編

- 概要
    - angularJS での開発で webStorage 操作のために ngStorage モジュールを利用
    - 若干問題アリ。wrapping してみたけど作りなおしたほうが早そう
    - amoStorage 作った
    - bower install amoStorage でインスコできるようにした

# ngStorage の使い方
こんな感じ

```coffeescript
app = angular.module "someApp", ["ngStorage"]
app.controller "SomeCtrl", ["$localStorage", ($localStorage) ->
  $localStorage["key"] = "value"
  $localStorage["obj"] =
    hoge: "fuga"
    fizz: "buzz"
]
```

内部で定期的に `localStorage` と同期をとっている模様（→ https://github.com/gsklee/ngStorage/blob/0.3.0/ngStorage.js#L67 ）

# 問題アリ

- `webStorage` の実体はただの `kvs` で、`Object` の類は全部 `JSON parse` されてから格納される。
- アクセス制御の単位は `scheme + host + port` つまり、同じドメインなら同じ `webStorage` を共有する
- 今回のプロジェクトでは、ひとつのドメインで複数のサービスを運営する可能性があり、別サイトで同じように `angularJS` と `ngStorage` を使うことになるかもしれない。
- `key` の衝突を避けるには、`prefix` を付ける必要がある
- `ngStorage` は勝手に `ngStorage-` という `prefix` を付けてくれる
- `$localStorage` には `$reset` とかいうバルスメソッドが存在し、`ngStorage-` の付いたデータを無慈悲に消去する。
- →つまり、今回のプロジェクトでいくら `prefix` などを付けようとも、ずっと未来の全然違うプロジェクトで同じドメインで同じ `angularJS` で同じ `ngStorage` を使い、ムスカみたいなプログラマがドヤ顔で `$reset` を使っちゃったら全然関係ない今回のプロジェクトのデータがある日突然消えてしまう


- とここまで妄想してみたものの実際これはさほど問題ではない。
    - webStorage の中身は develooper tool などでユーザーが簡単に操作出来る（→ https://pic.twitter.com/07Xzkr5Wjy ）
    - 消えて困るようなデータはそもそも webStorage に置くべきではない
    - $reset という関数の使い方がわからない人は使わないし、わかる人はそれが得策でないこともわかるのでは

それにしても `ngStorage` はデータの有効期限を指定出来なかったり、デフォルトで付く `ngStorage-` が変えられなかったりと何かと不便だ。

# amoStorage 作りました
主な昨日は次の通り

- prefix の自由なカスタマイズ
    - アプリケーションごと（ `appName` ）、
    - リビジョンごと（ `revision` ）、
    - アプリ内の使用する場所ごと（ `prefix` ）、に prefix を付けられる
    - デフォルトは key の前に `appName/revision/prefix/` が付く
- 古いリビジョンの自動削除機能
    - リビジョン番号を更新することで、それ以外のリビジョンに紐付いたキーを掃除してくれる
- データごとに有効期限を設定できる
    - `storage.set key, value, expired_sec` で秒単位で指定可能
    - セッションなどを管理するときに便利

使い方：

```coffeescript
app = angular.module "someApp", ["amo.webStorage"]

app.config ["amoStorageManagerProvider", (provider) ->
  provider.appName = "someApp" # アプリ名
  provider.revision = "2"      # revision 番号
  provider.separator = "/"     # someApp/2/... というprefix が付く。
  # prefix をカスタマイズしたい場合は次の関数を書き換える。
  provider.keyGeneratorFactory = (appName, revision, separator, prefix) ->
    _prefix = "#{appName}[#{revision}][prefix/"
    _suffix = "]"
    return (key) -> "#{_prefix}#{key}#{_suffix}"
]

app.controller "SomeCtrl", ["amoStorageManager", (manager) ->
  storage = manager.getLocalStorage("SomeCtrl") # keyGeneratorFactory の prefix に "SomeCtrl" が渡される

  key = "key"
  value = "value"
  expired_sec = 10
  storage.set key, value, expired_sec
  # ↑ "someApp[2][SomeCtrl/key]#" というキーで値が保存される
  # 最後の # だけは内部的につけている記号で、ユーザーが使用しているキーと内部で管理用に使っているキーとを識別するためのもの。

  setTimeout((->
    v = storage.get key # expired_sec を過ぎたため null が返る
  ), 11000)
]
```

# bower 使ってインスコ
bower パッケージ↓

```shell-session
bower install amoStorage
```

ソース↓
https://github.com/amo12937/amoStorage

git clone 〜 grunt test まで

```shell-session
git clone git@github.com:amo12937/amoStorage.git
npm install
bower install
grunt test
```

README.md はそのうち書きます。