dexie / Dexie.js

A Minimalistic Wrapper for IndexedDB
https://dexie.org
Apache License 2.0
11.53k stars 642 forks source link

Dexie.Observable - timeline for moving out of beta #884

Open aecreations opened 5 years ago

aecreations commented 5 years ago

I am using Dexie in my Firefox add-on, Clippings. I'm also using Dexie.Observable, but when I recently submitted a new version of my Firefox add-on, it was rejected because Dexie.Observable is in beta, and the Mozilla Add-ons editors apparently won't accept add-ons that use beta versions of third-party libraries.

I see that the latest release of Dexie.Observable is 1.0.0-beta.5. When is Dexie.Observable planned to be moved out of beta status?

dfahlander commented 5 years ago

The plan is to rewrite it from scratch. There are no planned timelines.

demonking commented 3 years ago

what are the plans here after about 2 years?

dfahlander commented 3 years ago

As there is a built-in observability framework in the latest versions of dexie which is way more robust and performant than Dexie.Observable as it doesn't need to track changes persistently, the plan is to advertise the use of liveQuery(), and possibly some upcoming lower-level alternatives based on the same built-in framework.

Today you can use liveQuery() if you npm install dexie@next and you can also subscribe to Dexie.on('txcommitted', changeParts => {...}) if you need a lower level alternative. This event will probably be renamed and moved to a custom DOM event and liveQuery() may be moved out from dexie to its own package, as is already done with the react hook that is built on top of it [useLiveQuery()](https://dexie.org/docs/dexie-react-hooks/useLiveQuery()) (see PR #1244). Except from that, the API's are stable to use.

The new observability framwork triggers an event once a certain query would become affected by a mutation. The user is responsible of re-querying to see the new data (in the lower-level case where you just listen to Dexie.on('txcommitted'). If you however, use the high level api liveQuery() the framework will compute whether your query needs to be re-executed or not and you don't need to think about interpreting the event data (see sample below).

To install:

npm i dexie@next

Usage examples:

import Dexie, { liveQuery } from 'dexie';

const db = new Dexie('observableStuff');
db.version(1).stores({
  items: 'id, date, productId',
  products: 'id, price, name'
});

// Subscribe to changes:

const observable = liveQuery(
  // Provide a callback that queries your database(s) and returns a promise:
  async () => {
    const thisMorning = new Date().setHours(0);
    const todaysItems = await db.table('items')
      .where('date')
      .above(thisMorning)
      .toArray();

    // Join with product name and price
    return await Promise.all(
      todaysItems.map(async item => {
        const product = await db.table('products').get(item.productId);
        return {
          ...item,
          price: product.price,
          name: product.name
        };
      })
    );
);

const subscription = observable.subscribe(
   items => console.log(items);
);

// Now, whenever a mutation happens that would affect any of the queries
// in the above callback, it will be reexecuted and return the updated data.

// For example, this mutation:
db.table('products').update(77, { price: 2195 }) 
// ...will trigger re-execution only if you have a recent item with productId: 77

// And this mutation:
db.table('items').delete(4)
// ...will trigger re-execution only if you have a recent item with id 4.

So far, dexie docs only covers the react hook [useLiveQuery()](https://dexie.org/docs/dexie-react-hooks/useLiveQuery()) and not yet the plain liveQuery() as the latter may be moved to its own package. This is also the reason dexie 3.2 is still considered beta. We don't want to change API's once it is released as stable. But building your app on it is rather risk free as it will be a piece of cake to import it differently when it goes stable.

Different Use Cases

liveQuery() [useLiveQuery()](https://dexie.org/docs/dexie-react-hooks/useLiveQuery()) are designed for app developers and GUI framworks to gain reactivity. But if the purpose of observability is sync, you will need to track changes somehow, similarly to how Dexie.Observable does it. Today, we're putting all efforts on that into dexie-cloud-addon which is a new and better Dexie.Syncable with a more batteries-included solution and a defined protocol for syncing. Mutation tracking can be done as a middleware similar to how it is implemented in dexie-cloud-addon if you need to do it for your own case. We might break out parts of dexie-cloud-addon in future to make it easier to reuse and to built your own sync client. But the focus now is getting dexie cloud out and make it stable.