docs/releases/14.0.0.html
On this page
The release 14.0.0 is used for major refactorings and API changes. The replication or the storage layer have only been touched marginally.
Notice that only the major changes are listed here. All minor changes can be found in the changelog.
The PouchDB RxStorage was deprecated in 13 and has now finally been removed, see here. Also the old replication-couchdb plugin was removed. Instead we had the replication-couchdb-new plugin which was now renamed to replication-couchdb.
At the previous version of RxDB, RxDocuments mutate themself when they receive ChangeEvents from the database. For example when you have a document where name = 'foo' and some update changes the state to name = 'bar' in the database, then the previous JavaScript object changed its own property to the have doc.name === 'bar'. This feature was great when you use a RxDocument with some change-detection like in angular or vue templates. You can use document properties directly in the template and all updates will be reflected in the view, without having to use observables or subscriptions.
However this behavior is also confusing many times. When the state in the database is changed, it is not clear at which exact point of time the objects attribute changes. Also the self mutating behavior created some problem with vue- and react-devtools because of how they clone objects.
In RxDB v14, all RxDocuments are immutable. When you subscribe to a query and the same document is returned in the results, this will always be a new JavaScript object.
Also RxDocument.$ now emits RxDocument instances instead of the plain document data.
findByIds()In the past, the functions findByIds and findByIds$ directly returned the result set. This was confusing, instead they now return a RxQuery object that works exactly like any other database query.
const results = await myRxCollection.findByIds(['foo', 'bar']).exec();
const results$ = await myRxCollection.findByIds(['foo', 'bar']).$;
Related issue #4180.
In the past the naming of the document mutation methods is confusing. For example update() works completely different to atomicUpdate() and so on. The naming of all functions was unified and all methods do now have an incremental and a non-incremental version (previously known as atomic):
atomicUpdate() to incrementalModify()atomicPatch() to incrementalPatch()atomicUpsert() to incrementalUpsert()RxDocument().incrementalUpdate()RxDocument.incrementalRemove()RxDocument methods patch() and modify()In the past, to start a replication, the replication plugin was added to RxDB and a method on the RxCollection was called like myRxCollection.syncGraphQL(). This caused many problems with tree shaking bailouts and having the correct typings. So instead of having class method on the RxCollection, the replications are now started like:
import { replicateCouchDB } from 'rxdb/plugins/replication-couchdb';
const replicationState = replicateCouchDB({ /* ... */ });
storage-For better naming, all storage plugins have been prefixed with storage- so the imports have been changed:
// Instead of
import { getRxStorageDexie } from 'rxdb/plugins/dexie';
// it is now
import { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';
encryption-crypto-jsTo make it possible to have alternative encryption plugins, the encryption plugin was renamed to encryption-crypto-js.
// Instead of
import { wrappedKeyEncryptionStorage } from 'rxdb/plugins/encryption';
// it is now
import {
wrappedKeyEncryptionCryptoJsStorage
} from 'rxdb/plugins/encryption-crypto-js';
worker pluginIn the past, the worker plugin was based on the threads library. It was completely rewritten and uses the plain JavaScript API together with the remote storage plugin. BUT notice that the worker plugin has moved into the RxDB Premium 👑 package.
In the past, the _rev field of a RxDocument data was filled with a hash of the documents data. This was not the best solution because:
Instead we now use just use the RxDatabase.token together with the revision height.
When making multiple writes to different (or the same) document, in the past RxDB made one write call to the storage. When doing fast writes, like when you writhe the current mouse position to a document, the writes could have queued up to the point where the users recognizes performance lag. In RxDB v14, pending document updates are batched up into single storage writes for better performance.
Many changes have been made to improve tree shakability of RxDB which results in smaller bundle sizes and a faster application startup.
The whole RxDocument cache was refactored. It now runs based on the WeakRef API and automatically cleans up cached documents that are no longer referenced. This reduces the use memory and makes RxDB more suitable for being used in Node.js on the server side.
Notice that the WeakRef API is only featured in modern browsers so RxDB will no longer run on ie11.
To reduce the bundle size and improve performance, the following JavaScript features will no longer be transpiled because they are natively supported in modern browsers anyway:
All these optimizations together reduced the test-bundle size from 74148 bytes down to 36007 bytes.
push/pull.initialCheckpoint to start a replication from a given checkpoint.remove().._rev to the storage write when a conflict is resolved.console.warn() to ensure people do not use it in production.Buffer. We now use Blob everywhere.$regex query not working on remote storage.encryption-crypto-jsThe way RxDB hashes and normalizes a schema has changed. To migrate stored data between the RxDB versions, therefore you have to increase your schema version by 1 and add a migration strategy.
For some storages, the stored data of the previous RxDB versions is not compatible with RxDB 14.0.0. So if you want to keep that data, you have to migrate it in a way. For most use cases you might want to just drop the data from the client and re-sync it again from the backend. To keep the data locally, you might want to use the storage migration plugin.
There are many things that can be done by you to improve RxDB: