|  | 
| 1 |  | -# RavenDB client for Node.js | 
|  | 1 | +# RavenDB Client for Node.js | 
| 2 | 2 | 
 | 
| 3 |  | -[](https://travis-ci.org/ravendb/ravendb-nodejs-client) [](https://snyk.io/test/github/ravendb/ravendb-nodejs-client) | 
| 4 |  | - | 
| 5 |  | -## Changelog | 
|  | 3 | +[](https://nodei.co/npm/ravendb/) | 
| 6 | 4 | 
 | 
| 7 |  | -### 4.0.3 - 2018-10-01 | 
| 8 |  | -Added support for the following features: | 
| 9 |  | -- [Streaming](#streaming) | 
| 10 |  | -- More like this | 
| 11 |  | -- [Suggestions](#suggestions) | 
| 12 |  | -- [Revisions](#revisions) | 
| 13 |  | -- [Advanced patching](#advanced-patching) | 
|  | 5 | +[](https://travis-ci.org/ravendb/ravendb-nodejs-client) [](https://snyk.io/test/github/ravendb/ravendb-nodejs-client) | 
| 14 | 6 | 
 | 
| 15 |  | -### 4.0.2 - 2018-09-14 | 
| 16 |  | -Added support for the following features: | 
| 17 |  | -- [Attachments](#attachments) | 
| 18 |  | -- [Bulk Insert](#bulk-insert) | 
| 19 |  | -- [Changes API](#changes-api) | 
| 20 | 7 | 
 | 
| 21 | 8 | ## Installation | 
| 22 | 9 | 
 | 
| 23 | 10 | ```bash | 
| 24 | 11 | npm install --save ravendb | 
| 25 | 12 | ``` | 
| 26 | 13 | 
 | 
|  | 14 | +## Releases and Changelog - [click here](https://github.com/ravendb/ravendb-nodejs-client/releases) | 
|  | 15 | + | 
| 27 | 16 | ## Getting started | 
| 28 | 17 | 
 | 
| 29 | 18 | 1. Require `DocumentStore` class from package | 
| @@ -747,14 +736,67 @@ session.advanced.patch("users/1", "underAge", false); | 
| 747 | 736 | 
 | 
| 748 | 737 | await session.saveChanges(); | 
| 749 | 738 | ``` | 
|  | 739 | +### Subscriptions | 
|  | 740 | +```javascript | 
|  | 741 | +// create a subscription | 
|  | 742 | +const subscriptionName = await store.subscriptions.create({ | 
|  | 743 | +    query: "from users where age >= 30" | 
|  | 744 | +}); | 
|  | 745 | + | 
|  | 746 | +// get subscription worker for your subscription | 
|  | 747 | +const subscription = store.subscriptions.getSubscriptionWorker({ subscriptionName }); | 
|  | 748 | + | 
|  | 749 | +subscription.on("error", err => { | 
|  | 750 | +    // handle errors | 
|  | 751 | +}); | 
|  | 752 | + | 
|  | 753 | +subscription.on("batch", (batch, callback) => { | 
|  | 754 | +    try { | 
|  | 755 | +        // do batch processing on batch.items | 
|  | 756 | +        // batch.items: | 
|  | 757 | +        // [ Item { | 
|  | 758 | +        //     changeVector: 'A:2-r6nkF5nZtUKhcPEk6/LL+Q', | 
|  | 759 | +        //     id: 'users/1-A', | 
|  | 760 | +        //     rawResult: | 
|  | 761 | +        //      { name: 'John', | 
|  | 762 | +        //        age: 30, | 
|  | 763 | +        //        registeredAt: '2017-11-11T00:00:00.0000000', | 
|  | 764 | +        //        kids: [Array], | 
|  | 765 | +        //        '@metadata': [Object], | 
|  | 766 | +        //        id: 'users/1-A' }, | 
|  | 767 | +        //     rawMetadata: | 
|  | 768 | +        //      { '@collection': 'Users', | 
|  | 769 | +        //        '@nested-object-types': [Object], | 
|  | 770 | +        //        'Raven-Node-Type': 'User', | 
|  | 771 | +        //        '@change-vector': 'A:2-r6nkF5nZtUKhcPEk6/LL+Q', | 
|  | 772 | +        //        '@id': 'users/1-A', | 
|  | 773 | +        //        '@last-modified': '2018-10-18T11:15:51.4882011Z' }, | 
|  | 774 | +        //     exceptionMessage: undefined } ] | 
|  | 775 | +        // ... | 
|  | 776 | + | 
|  | 777 | +        // call the callback, once you're done | 
|  | 778 | +        callback(); | 
|  | 779 | +    } catch(err) { | 
|  | 780 | +        // if processing fails for a particular batch | 
|  | 781 | +        // pass the error to the callback | 
|  | 782 | +        callback(err); | 
|  | 783 | +    } | 
|  | 784 | +}); | 
|  | 785 | +``` | 
| 750 | 786 | 
 | 
| 751 | 787 | ## Using object literals for entities | 
| 752 | 788 | 
 | 
| 753 |  | -In order to comfortably use object literals as entities set function getting collection name based on the content of the object - `store.conventions.findCollectionNameForObjectLiteral()`. This needs to be done *before* an `initialize()` call on `DocumentStore` instance. If you fail to do so, your entites will land up in *@empty* collection having an *UUID* for an ID. E.g. | 
|  | 789 | +In order to comfortably use object literals as entities set the function getting collection name based on the content of the object - `store.conventions.findCollectionNameForObjectLiteral()`.  | 
|  | 790 | + | 
| 754 | 791 | ```javascript | 
|  | 792 | +const store = new DocumentStore(urls, database); | 
| 755 | 793 | store.conventions.findCollectionNameForObjectLiteral = entity => entity["collection"]; | 
|  | 794 | +// ... | 
|  | 795 | +store.initialize(); | 
| 756 | 796 | ``` | 
| 757 | 797 | 
 | 
|  | 798 | +This needs to be done *before* an `initialize()` call on `DocumentStore` instance. If you fail to do so, your entites will land up in *@empty* collection having an *UUID* for an ID. E.g. | 
|  | 799 | + | 
| 758 | 800 | ## Using classes for entities | 
| 759 | 801 | 
 | 
| 760 | 802 | 1. Define your model as class. Attributes should be just public properties: | 
|  | 
0 commit comments