(Translated by https://www.hiragana.jp/)
GitHub - teambition/ReactiveDB: Reactive ORM for Lovefield
Skip to content

teambition/ReactiveDB

Repository files navigation

CircleCI Coverage Status Dependency Status devDependencies Status Greenkeeper badge

ReactiveDB

いち个 Reactive 风格てき前端ぜんたん ORM。もとLovefield あずか RxJS

Features

  • 响应しき查询

    支持しじ以 Observable てき形式けいしきかえしかい响应しきすうすえ

  • かずすえ一致いっちせい

    所有しょゆうてき执行过程こと务性てきざいぐういた环境异常时(indexDB 异常,浏览げんせい,隐私しき导致てきこうのうせいかけしつとう) 也不かい产生脏数すえ

  • かずすえ持久じきゅう

    だい量的りょうてきすうすえ场景,极端如单页应よう间断运行几个がつてきじょう况下,かい造成ぞうせいないそんうらない用量ようりょう过多。所有しょゆうてきすうすえ持久じきゅうざい本地ほんじそん储而ないそんちゅう支持しじ丰富てきすうすえ换页配置はいち[WIP]。

  • debug tools

    Lovefield debug tool for Chrome

Documents

Scenarios

ざい单页实时せい应用てき场景抽象ちゅうしょうざい前端ぜんたん维护すうすえ以及其关联的すうすえてき变更てき逻辑

こう虑下めんてき场景,ざい一个单页前端应用中,需要じゅよう展示てんじ A,B, C, D よん个列ひょう:

其中れつひょう A 展示てんじ所有しょゆう ownerId 为 user1 てき Item :

[
  {
    "_id": 1,
    "name": "item 1",
    "ownerId": "user1",
    "creatorId": "user2",
    "created": "2016-01-31T16:00:00.000Z",
    "owner": {
      "_id": "user1",
      "name": "user1 name"
    },
    "creator": {
      "_id": "user2",
      "name": "user2 name"
    }
  },
  {
    "_id": 3,
    "name": "item 1",
    "ownerId": "user1",
    "creatorId": "user3",
    "created": "2016-05-03T16:00:00.000Z",
    "owner": {
      "_id": "user1",
      "name": "user1 name"
    },
    "creator": {
      "_id": "user3",
      "name": "user3 name"
    }
  }
  ...
]

れつひょう B 展示てんじ所有しょゆう creatorId 为 user2 てき Item:

[
  {
    "_id": 1,
    "name": "item 1",
    "ownerId": "user1",
    "creatorId": "user2",
    "created": "2016-01-31T16:00:00.000Z",
    "owner": {
      "_id": "user1",
      "name": "user1 name"
    },
    "creator": {
      "_id": "user2",
      "name": "user2 name"
    }
  },
  {
    "_id": 2,
    "name": "item 1",
    "ownerId": "user2",
    "creatorId": "user3",
    "created": "2016-04-20T16:00:00.000Z",
    "owner": {
      "_id": "user2",
      "name": "user2 name"
    },
    "creator": {
      "_id": "user3",
      "name": "user3 name"
    }
  }
  ...
]

れつひょう C 展示てんじ所有しょゆう created 时间为 2016ねん3がつ1にち 以后てき Item:

[
  {
    "_id": 2,
    "name": "item 1",
    "ownerId": "user2",
    "creatorId": "user3",
    "created": "2016-04-20T16:00:00.000Z",
    "owner": {
      "_id": "user2",
      "name": "user2 name"
    },
    "creator": {
      "_id": "user3",
      "name": "user3 name"
    }
  },
  {
    "_id": 3,
    "name": "item 1",
    "ownerId": "user1",
    "creatorId": "user3",
    "created": "2016-05-03T16:00:00.000Z",
    "owner": {
      "_id": "user1",
      "name": "user1 name"
    },
    "creator": {
      "_id": "user3",
      "name": "user3 name"
    }
  }
]

れつひょう D 展示てんじ所有しょゆうてきよう户信いき:

[
  {
    "_id": "user1",
    "name": "user1 name",
    "avatarUrl": "user1 avatarUrl",
    "birthday": "user1 birthday"
  },
  {
    "_id": "user2",
    "name": "user2 name",
    "avatarUrl": "user2 avatarUrl",
    "birthday": "user2 birthday"
  },
  {
    "_id": "user3",
    "name": "user3 name",
    "avatarUrl": "user3 avatarUrl",
    "birthday": "user3 birthday"
  }
]

这四个列表的数据分别从四个 API 获取。ざいだい多数たすう单页应用てき构中,すうすえ层会缓存这几个接こうてきすうすえ,避免じゅう复请もとめ。而在实时せいてき单页应用ちゅう,这些すうすえてき更新こうしん通常つうじょう需要じゅようどおりWebSocket とう手段しゅだん进行更新こうしんすえ缓存策略さくりゃくてき不同ふどう(单例そん储/どういち ID そん储多份数すえ),则有不同ふどうてき更新こうしん方式ほうしきただし这个过程一般いっぱん 业务且难以抽象ちゅうしょう てき

如单一引用存储数据时, 上面うわつら场景ちゅうれつ举到てきすうすえただかいそん储为:

{
  item1, item2, item3,
  user1, user2, user3
}

ざい这种缓存策略さくりゃく,一个数据变更后,はた变更きさきてき结果通知つうちいた所属しょぞくてき集合しゅうごういちけん非常ひじょうあさ烦的事情じじょうかり设现ざいわが们的应用おさむいたいちじょう socket 消息しょうそく:

{
  "change:item1": {
    "ownerId": "user3"
  }
}

按照业务需求わが们应该将 item1ListA ちゅううつりじょざい这种缓存策略さくりゃくちゅう,如果使用しようてき pub/sub てき模型もけい进行通知つうち(Backbone 类),则会导致すうすえ层外てきだい码不とく进行大量たいりょうてき计算,とまてき filter 一个变更是否满足某个列表的需求。这种じゅう复的过程是非ぜひつね难以维护,业务,且难以抽象ちゅうしょうてき。 而按あきら ReactiveDB てき设计理念りねん所有しょゆうてきすうすえみやこ有可ゆか选的响应しきそくにんなにあずかこれしょう关的变动都会とかい让数すえくだり更新こうしん最新さいしんてき值:

伪代码如:

/**
 * @param tableName
 * @param queryOptions
 * @return QueryToken<T>
 **/
database.get<ItemSchema>('Item', {
  where: {
    ownerId: 'user1'
  },
  fields: [
    '_id', 'name', 'ownerId',
    {
      owner: ['_id', 'name']
    }
  ]
})
  .changes()
  .subscribe(items => {
    console.log(items)
  })

使用しよう ReactiveDB てきじょう况下,无论 Item 本身ほんみてき变更还是あずかこれ关联てき User 变更,都会とかい生新せいしんてき items 值。 さら复杂てきListC:

/**
 * @param tableName
 * @param queryOptions
 * @return QueryToken<T>
 **/
database.get<ItemSchema>('Item', {
  where: {
    created: {
      // $gte means great than and equal
      // さら操作そうささん见详细的使用しようぶん
      '$gte': new Date(2016, 3, 1).valueOf()
    }
  },
  fields: [
    '_id', 'name', 'ownerId',
    {
      owner: ['_id', 'name']
    }
  ]
})
  .changes()
  .subscribe(items => {
    console.log(items)
  })