lovefield は google 製のIndexedDBのSQL風ラッパー。
indexeddb を使うライブラリは大抵node環境で動かないのだが、fake-indexeddb でモックすることでインメモリDBとしてテスト環境で動かすことができた。少なくとも、公式のチュートリアルの範囲では。
以下動いたコード。
// mock indexeddb
global.self = global;
global.indexedDB = require("fake-indexeddb");
// Get started
const lf = require("lovefield");
const schemaBuilder = lf.schema.create("todo", 1);
schemaBuilder
.createTable("Item")
.addColumn("id", lf.Type.INTEGER)
.addColumn("description", lf.Type.STRING)
.addColumn("deadline", lf.Type.DATE_TIME)
.addColumn("done", lf.Type.BOOLEAN)
.addPrimaryKey(["id"])
.addIndex("idxDeadline", ["deadline"], false, lf.Order.DESC);
(async () => {
const db = await schemaBuilder.connect();
// Get the schema representation of table Item.
// All schema-related APIs are synchronous.
const item = db.getSchema().table("Item");
// Creates a row. Lovefield does not accept plain objects as row.
// Use the createRow() API provided in table schema to create a row.
const row = item.createRow({
"id": 1,
"description": "Get a cup of coffee",
"deadline": new Date(),
"done": false
});
// INSERT OR REPLACE INTO Item VALUES row;
// The exec() method returns a Promise.
await db.insertOrReplace().into(item).values([row]).exec();
// When reached here, Lovefield guarantees previous INSERT OR REPLACE
// has been committed with its implicit transaction.
// SELECT * FROM Item WHERE Item.done = false;
// Return another Promise by calling this SELECT query's exec() method.
const results = await db.select().from(item).where(item.done.eq(false)).exec();
results.forEach((row) => {
// Use column name to directly dereference the columns from a row.
// console.log(row.description, "before", row.deadline);
console.log("item:", row);
});
})();
動機
現状のIndexedDBが使いづらい理由にドメイン層に近い部分で使うのにNodeでユニットテストできない点があると思っていて、これでその不満が解決できればだいぶ複雑なIsomorphicなアプリが作りやすくなる。
fake-indexeddb がどれぐらい信用できるかは、
It passes the W3C IndexedDB test suite (a feat that all browsers except Chrome fail) plus a couple hundred more tests just to be sure. It also works well enough to run fairly complex IndexedDB-based software.
とのことなんで、そもそも非同期のイベントくる順番がぶっ壊れてる Safari の実装よりマシじゃないでしょうか。