Help us understand the problem. What is going on with this article?

IndexedDbをActiveRecord+Promiseっぽく扱えてJSONSchemaでバリデーションできてnodeでもオンメモリで動いてくORMみたいな何か作ってみた

More than 5 years have passed since last update.

タイトル盛りすぎた。 mizchi/stone-skin です。 npm install stone-skin で入るんでbrowserifyと一緒に使ってください。

命名は、時間があったらFF14やるんだけどなという気持ちを込めて。(ナイトだけLv50にしてから1年以上触ってない)

この前紹介したArdaと一緒で、本番環境でドッグフーディングしつつ開発したので、使い物になるはず。今さっきドキュメント書いてv0.1.0にしたので紹介。

サンプルコード

非同期APIはPromiseを返すので、この前書いた
JavaScript - Babelのasync/await試してみた(+中の処理をちょっと追ってみた) - Qiita のasync/awaitを使いつつ紹介。

import "babel/polyfill";
import StoneSkin from '../with-tv4';

class ItemStore extends StoneSkin.IndexedDb {
  storeName: 'Item';
  schema: {
    properties: {
      title: {
        type: 'string'
      }
    }
  }
}

let itemStore = new ItemStore();
(async () => {
  await itemStore.ready;
  await itemStore.save({title: 'foo', _id: 'xxx'});
  let item = await itemStore.find('xxx');
  console.log(item);
  let items = await itemStore.all();
  console.log(items);
})();

_id だけ予約語。find(), save({..}), all(), select(i => bool) っていうそれっぽいAPIで永続化されたIndexedDbを扱える。

MemoryDbっていうクラスを継承しても全く同じAPIになるが、永続化はされない。扱ってる時はどっちか気にしなくてよい。

save時に渡したインスタンスは、JSONSchemaでバリデーションされる。
TypeScript用の型定義も用意した https://github.com/mizchi/stone-skin/blob/master/stone-skin.d.ts のだけど、TypeScriptの抜け道がいくらでもある型チェックより保存時のインスタンスのバリデーションの方が安心できそうだったので、実行時バリデーションを大事にした。型情報は補完用。

他にも StoneSkin.utils.setupWithMigrate(version) っていうスキーマバージョンが変わった時のマイグレーションヘルパとかある。というか必要に迫られて作った。

他は mizchi/stone-skin の README や examples を見てください。

作った動機

近年、JavaScriptアプリの多機能化により、ブラウザストレージを適切に扱う必要性が増してきた。うんぬん。

似たようなライブラリとして Dexie.js - Minimalistic IndexedDB WrappermWater/minimongo がある。

弊社某アプリの開発でminimongo使ってたんだけどmongo部分がどんどんいらなくなってきて、結局モンゴクエリでwhereするの面倒くさくなってきた。どうせJSから扱うんだし、カーソル処理+filter関数だけでどうにかできるはず、という直感はあった。ついでに適切にバッチ処理にフォールバック出来るようにするとパフォーマンスあがるはずで、薄いラッパーの上でそういうの作りたかった。作った。

で、最初jensarps/IDBWrapperをみてたんだけど、Promise化ぐらいならいけるやろと思い mizchi/idb-wrapper-promisify を書き(これのテストをPromise用に書き換えて通すのが面倒だった)、その上にActiveRecord風のAPIを被せた。

永続化ストレージ、簡単に扱うよりも固く扱えるようにするのが動機として強いんだけど、とはいえある程度簡単じゃないとモチベーション下がる。素のIndexedDbは妙にローレベルで最適化難しく、StoneSkinはまだパフォーマンス的な最適化は施してないがそれが出来る余地を残してある。

お試しください。

plaid
CXプラットフォーム「KARTE」の開発・運営、EC特化型メディア「Shopping Tribe」の企画・運営、CX特化型メディア「XD(クロスディー)」の企画・運営
https://plaid.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした