# RxDB 11 - WebWorker Support & More

> RxDB 11.0 brings Worker-based storage for multi-core performance gains. Explore the major changes and migrate seamlessly to harness new speeds.

# 11.0.0

The last major release was only about [6 month ago](./10.0.0.md). But to further improve RxDB, it was necessary to make some more breaking changes and release the next major version.
In the last version `10.0.0` the storage layer was abstracted in a way to make it possible to not only use PouchDB as storage, but instead we can use different storage engines like the one based on [LokiJS](../rx-storage-lokijs.md) or any custom implementation of the `RxStorage` interface.

In the new version `11.0.0` the focus is on making it possible to put the RxStorage into a **WebWorker** to take CPU load from the main process into the worker's process. This can improve the perceived performance of your application, especially when you have to handle many documents or when you need the main process CPU cycles to manage the DOM with your frontend framework.

## Worker plugin

Performance was always something RxDB had a struggle with. Not because RxDB itself is slow, but because the underlying storage engine (mostly PouchDB) or [IndexedDB is slow](../slow-indexeddb.md). This never was a problem for 'normal' applications that have to store some documents. But on big applications with much data, there was a bottleneck.

With the Worker plugin, you can move the `RxStorage` out of the main JavaScript process. This makes it pretty easy to utilize more than one CPU core and speed up your application.

```ts
// worker.ts
import { wrappedRxStorage } from 'rxdb/plugins/worker';
import { getRxStorageLoki } from 'rxdb/plugins/storage-lokijs';
wrappedRxStorage({
    storage: getRxStorageLoki()
});
```

```ts
// main process
import { createRxDatabase } from 'rxdb/plugins/core';
import { getRxStorageWorker } from 'rxdb/plugins/worker';
const database = await createRxDatabase({
    name: 'mydatabase',
    storage: getRxStorageWorker(
        {
            workerInput: 'path/to/worker.js'
        }
    )
});
```

The whole documentation about the worker plugin can be found [here](../rx-storage-worker.md).

## Transpile `async`/`await` to promises instead of generators

The RxDB source-code is transpiled from TypeScript to es5/es6 JavaScript code via babel.
In the past we transpiled the `async` and `await` keywords with the babel plugin `plugin-transform-async-to-generator`.
Now we use the [babel-plugin-transform-async-to-promises](https://github.com/rpetrich/babel-plugin-transform-async-to-promises) plugin instead.
It transpiles `async`/`await` into native `Promise`s instead of using JavaScript generators. This has shown to decrease build size by about 10% and also improves the performance.

## Removed deprecated `received` methods

In the past there was a typo in all getters and methods that are called `received`.
This was renamed to `received` and all mistyped methods have been deprecated.
We now removed all deprecated methods, so you have to use the correctly spelled methods instead.
[See #3392](https://github.com/pubkey/rxdb/pull/3392)

## All internal events are handled as bulks

All events that are generated from writing to the storage instance are now handled in bulks instead of each event for its own. This has shown to save performance when the events are send over a data layer like a `WebWorker` or the `BroadcastChannel`. This change only affects you if you have created custom RxDB plugins.

## RxStorage interface changes

To make the RxStorage abstraction compatible with Webworkers, we had to do some changes. These will only affect you if you use a custom RxStorage implementation.

- The non async functions `prepareQuery`, `getSortComparator` and `getQueryMatcher` have been moved out of `RxStorageInstance` into the `statics` property of `RxStorage`. This makes it possible to split the code when using the worker plugin. You only need to load the static methods at the main process, and the whole storage engine is only loaded inside of the worker.
- All data communication with the RxStorage now happens only via plain JSON objects. Instead of returning a JavaScript `Map` or `Set`, only [JSON datatypes](https://www.w3schools.com/js/js_json_datatypes.asp) are allowed. This makes it easier to properly serialize the data when transferring it over to or from a WebWorker.
- Events that are created from a write operation, must be emitted **before** the write operation resolves. This ensures that RxDB always knows about all events before it runs another operation. So when you do an insert and a query directly after the insert, the query will return the correct results.
- The meta data `digest` and `length` of attachments is now created by RxDB, not by the RxStorage. [#3548](https://github.com/pubkey/rxdb/issues/3548)
- Added the statics `hashKey` property to identify the used hash function.

## Removed the `no-validate` plugin.

In the past, RxDB required you to add one schema validation plugin. For production, it was useful to not have any schema validation for better performance and a smaller build size. For that, the `no-validate` plugin could be added which was just a dummy plugin that did no do any validation. To remove this unnecessary complexity, RxDB no longer requires you to add a validation plugin. Therefore the no-validate plugin is now removed as it is no longer needed.

## Other changes

- The LokiJS RxStorage no longer uses the `IdleQueue` to determine if the database is idle. Because LokiJS is in-memory, we can just wait for CPU idleness via [requestIdleCallback()](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback)
- Bugfix: Do not throw an error when database is destroyed while a GraphQL replication is running.
- Compound primary key migration throws "Value of primary key(s) cannot be changed" [#3546](https://github.com/pubkey/rxdb/pull/3546)
- Allow `_id` as primaryKey [#3562](https://github.com/pubkey/rxdb/pull/3562) Thanks [@SuperKirik](https://github.com/SuperKirik)
- LokiJS: Remote operations do never resolve when remote instance was leader and died.

## Migration from `10.x.x`

The migration should be pretty easy. Nothing in the datalayer has been changed, so you can use the stored data of v10 together with the new v11 RxDB.

## 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 had 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.
- Improve the documentation. In the last user survey many users told me that the documentation is not good enough. But I reviewed the docs and could not find clear flaws. The problem is that I am way to deep into RxDB so that I am not able to understand which documentation a newcomer to the project needs. Likely I assume too much knowledge or focus writing about the wrong parts.
- Update the [example projects](https://github.com/pubkey/rxdb/tree/master/examples) many of them are outdated and need updates.

## Discuss!

Please [discuss here](https://github.com/pubkey/rxdb/issues/3555).
