# RxDB 14.0 - Major Changes & New Features

> Discover RxDB 14.0, a major release packed with API changes, improved performance, and streamlined storage, ensuring faster data operations than ever.

# 14.0.0

The release [14.0.0](https://rxdb.info/releases/14.0.0.html) 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](https://github.com/pubkey/rxdb/blob/master/CHANGELOG.md).

## Removing deprecated features

The PouchDB RxStorage was deprecated in 13 and has now finally been removed, see [here](../rx-storage-pouchdb.md).
Also the old `replication-couchdb` plugin was removed. Instead we had the `replication-couchdb-new` plugin which was now renamed to `replication-couchdb`.

## API changes

### RxDocument objects are now immutable

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.

### Refactor `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.

```ts
const results = await myRxCollection.findByIds(['foo', 'bar']).exec();
const results$ = await myRxCollection.findByIds(['foo', 'bar']).$;
```

### Rename to RxDocument update/modify functions

Related issue [#4180](https://github.com/pubkey/rxdb/issues/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`):
- RENAME `atomicUpdate()` to `incrementalModify()`
- RENAME `atomicPatch()` to `incrementalPatch()`
- RENAME `atomicUpsert()` to `incrementalUpsert()`
- ADD `RxDocument().incrementalUpdate()`
- ADD `RxDocument.incrementalRemove()`
- ADD non-incremental `RxDocument` methods `patch()` and `modify()`

### Replication is started with a pure function

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:

```ts
import { replicateCouchDB } from 'rxdb/plugins/replication-couchdb';
const replicationState = replicateCouchDB({ /* ... */ });
```

### Storage plugins are prefixed with `storage-`

For better naming, all storage plugins have been prefixed with `storage-` so the imports have been changed:

```ts
// Instead of 
import { getRxStorageDexie } from 'rxdb/plugins/dexie';
// it is now
import { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';
```

### Encryption plugin was renamed to `encryption-crypto-js`

To make it possible to have alternative encryption plugins, the `encryption` plugin was renamed to `encryption-crypto-js`.

```ts
// Instead of 
import { wrappedKeyEncryptionStorage } from 'rxdb/plugins/encryption';
// it is now
import { wrappedKeyEncryptionCryptoJsStorage } from 'rxdb/plugins/encryption-crypto-js';
```

### Rewrite the `worker` plugin

In the past, the [worker plugin](../rx-storage-worker.html) was based on the [threads](https://www.npmjs.com/package/threads) library. It was completely rewritten and uses the plain JavaScript API together with the [remote storage plugin](../rx-storage-remote.md). **BUT** notice that the worker plugin has moved into the [RxDB Premium 👑](/premium/) package.

## Performance improvements

### Do not use hash for revisions

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:
- Hashing in JavaScript is slow, not running hashes on insert improves performance by about 33%
- When 2 clients do the exact same write to the document, it is not clear from comparing the document states because they will have the exact same hash which makes some conflict resolution strategies impossible to implement.

Instead we now use just use the RxDatabase.token together with the revision height.

### Batch up incremental operations 

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.

### Improved tree shaking

Many changes have been made to improve [tree shakability](https://webpack.js.org/guides/tree-shaking/) of RxDB which results in smaller bundle sizes and a faster application startup.

### Refactor the document cache

The whole RxDocument cache was refactored. It now runs based on the [WeakRef API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef) 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](https://caniuse.com/?search=weakref) so RxDB will no longer run on ie11.

### No longer transpile some modern JavaScript features

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:
  - [async/await](https://caniuse.com/async-functions)
  - [Arrow functions](https://caniuse.com/arrow-functions)
  - [for...of](https://caniuse.com/?search=for...of)
  - [shorthand properties](https://caniuse.com/mdn-javascript_operators_object_initializer_shorthand_property_names)
  - [Spread operator](https://caniuse.com/?search=spread%20operator)
  - [destructuring](https://caniuse.com/?search=destructuring)
  - [default parameters](https://caniuse.com/?search=default%20parameters)
  - [object spread](https://caniuse.com/?search=Object%20spread)

All these optimizations together reduced the [test-bundle](https://github.com/pubkey/rxdb/blob/master/config/bundle-size.js) size from `74148` bytes down to `36007` bytes.

## Other changes
- ADD `push/pull.initialCheckpoint` to start a replication from a given checkpoint.
- The following plugins are out of beta mode:
  - [RxStorage Sharding](../rx-storage-sharding.md)
  - [RxStorage Remote](../rx-storage-remote.md)
  - [RxStorage FoundationDB](../rx-storage-foundationdb.md)
  - [New Replication CouchDB](../replication-couchdb.md)
  - [Cleanup Plugin](../cleanup.md)

## Bugfixes
- CHANGE (memory RxStorage) do not clean up database state on closing of the storage, only on `remove()`.
- FIX CouchDB replication: Use correct default fetch method.
- FIX schema hashing should respect the sort order [#4005](https://github.com/pubkey/rxdb/pull/4005)
- FIX replication does not provide a `._rev` to the storage write when a conflict is resolved.
- FIX(remote storage) ensure caching works properly even on parallel create-calls
- FIX(replication) Composite Primary Keys broken on replicated collections [#4190](https://github.com/pubkey/rxdb/pull/4190)
- FIX(sqlite) $in Query not working SQLite [#4278](https://github.com/pubkey/rxdb/issues/4278)
- FIX CouchDB push is throwing error because of missing revision [#4299](https://github.com/pubkey/rxdb/pull/4299)
- ADD dev-mode shows a `console.warn()` to ensure people do not use it in production.
- Remove the usage of `Buffer`. We now use `Blob` everywhere.
- FIX import of socket.io [#4307](https://github.com/pubkey/rxdb/pull/4307)
- FIX Id length limit reached with composite key [#4315](https://github.com/pubkey/rxdb/issues/4315)
- FIX `$regex` query not working on remote storage.
- FIX SQLite must store attachments data as Blob instead of base64 string to reduce the database size.
- FIX CouchDB replication conflict handling
- CHANGE Encryption plugin was renamed to `encryption-crypto-js`
- FIX replication state meta data must also be encrypted.

## Migration from 13.x.x to 14.0.0

The 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](../migration-storage.md).

## You can help!

There are many things that can be done by **you** to improve RxDB:

- Check the [BACKLOG](https://github.com/pubkey/rxdb/blob/master/orga/BACKLOG.md) for features that would be great to have.
- Check the [breaking backlog](https://github.com/pubkey/rxdb/blob/master/orga/before-next-major.md) for breaking changes that must be implemented in the future but where I did not have the time yet.
- Check the [todos](https://github.com/pubkey/rxdb/search?q=todo) in the code. There are many small improvements that can be done for performance and build size.
- Review the code and add tests. I am only a single human with a laptop. My code is not perfect and much small improvements can be done when people review the code and help me to clarify undefined behaviors.
- Update the [example projects](https://github.com/pubkey/rxdb/tree/master/examples) many of them are outdated and need updates.
