Skip to content

Commit a5d1050

Browse files
committed
docs: update README
1 parent 03a1a51 commit a5d1050

File tree

6 files changed

+302
-153
lines changed

6 files changed

+302
-153
lines changed

README.md

Lines changed: 138 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,23 @@
1616
- [General info](#general-info)
1717
- [Technologies](#technologies)
1818
- [Install](#install)
19-
- [Usage](#usage)
19+
- [Usage (NgModule)](#usage-ngmodule)
2020
- [In your `AppModule`](#in-your-appmodule)
2121
- [In your `FeatureModule`](#in-your-featuremodule)
2222
- [In your `FeatureService`](#in-your-featureservice)
23+
- [Usage (Standalone)](#usage-standalone)
24+
- [In your `main.ts`](#in-your-maints)
25+
- [In your `Component`](#in-your-component)
26+
- [Using `sginals` \& `signalStore` from `@ngrx/signals`](#using-sginals--signalstore-from-ngrxsignals)
2327
- [Features](#features)
24-
- [Diagrams](#diagrams)
2528
- [Status](#status)
2629
- [Inspiration](#inspiration)
2730
- [Notes](#notes)
2831
- [Contact](#contact)
2932

3033
## General info
3134

32-
If you don't want to setup RxDB manually in your next Angular project - just import `NgxRxdbModule`
35+
If you don't want to setup RxDB manually in your next Angular project - just import `NgxRxdbModule` or go with `provideRxDatabase` and `provideRxCollection` if standalone component is your choice.
3336

3437
## Technologies
3538

@@ -41,28 +44,28 @@ If you don't want to setup RxDB manually in your next Angular project - just imp
4144

4245
`npm install @ngx-odm/rxdb`
4346

44-
## Usage
47+
## Usage (NgModule)
4548

4649
### In your `AppModule`
4750

4851
```typescript
52+
import { NgxRxdbModule } from '@ngx-odm/rxdb';
53+
import { getRxDatabaseCreator } from '@ngx-odm/rxdb/config';
54+
4955
@NgModule({
5056
imports: [
5157
// ... other imports
52-
// ...
53-
NgxRxdbModule.forRoot({
54-
// optional, NgxRxdbConfig extends RxDatabaseCreator, will be merged with default config
55-
name: 'ngx', // <- name (required, 'ngx')
56-
adapter: 'idb', // <- storage-adapter (required, default: 'idb')
57-
password: '123456789', // <- password (optional)
58+
NgxRxdbModule.forRoot(getRxDatabaseCreator({
59+
name: 'demo', // <- name (required, 'ngx')
60+
storage: getRxStorageDexie(), // <- storage (not required, 'dexie')
61+
localDocuments: true,
5862
multiInstance: true, // <- multiInstance (optional, default: true)
59-
queryChangeDetection: false, // <- queryChangeDetection (optional, default: false)
63+
ignoreDuplicate: false,
6064
options: {
61-
// NgxRxdb options (optional)
62-
schemas: [...CollectionConfigs], // array of NgxRxdbCollectionConfig (optional)
65+
storageType: 'dexie|memory', // <- storageType (optional, use if you want defaults provided automatically)
6366
dumpPath: 'assets/dump.json', // path to datbase dump file (optional)
6467
},
65-
}),
68+
})),
6669
],
6770
providers: [],
6871
bootstrap: [AppComponent],
@@ -76,17 +79,20 @@ export class AppModule {}
7679
> https://rxdb.info/rx-schema.html
7780
7881
```typescript
82+
import type { RxCollectionCreatorExtended } from '@ngx-odm/rxdb/config';
7983
// create or import your schema
8084
const todoSchema: RxSchema = require('../../../assets/data/todo.schema.json');
8185
// create config
82-
// NgxRxdbCollectionConfig extends RxCollectionCreator
83-
const todoCollectionConfig: NgxRxdbCollectionConfig = {
86+
const todoCollectionConfig: RxCollectionCreatorExtended = {
8487
name: 'todo', // <- name (required)
85-
schema: todoSchema, // <- name (required)
86-
statics: {}, // <- collection methods (optional)
87-
methods: {}, // <- instance-methods methods (optional)
88+
schema: todoSchema, // <- schema (not required, see below)
89+
localDocuments: true,
8890
options: {
8991
initialDocs: [], // docs to be imported into empty collection (optional)
92+
schemaUrl: 'assets/data/todo.schema.json', // load schema from remote url (optional)
93+
replicationStateFactory: collection => {
94+
// provide replication state (optional)
95+
},
9096
},
9197
};
9298

@@ -95,83 +101,157 @@ const todoCollectionConfig: NgxRxdbCollectionConfig = {
95101
// ... other imports
96102
NgxRxdbModule.forFeature(todoCollectionConfig),
97103
],
98-
// declarations
99-
// providers
100104
})
101-
export class TodosModule {}
105+
export class TodosModule {
106+
constructor(
107+
@Inject(NgxRxdbCollectionService) private collectionService: NgxRxdbCollection<Todo>
108+
) {
109+
this.collectionService.sync(); // INFO: collection is ready
110+
}
111+
}
102112
```
103113

104114
### In your `FeatureService`
105115

106116
```typescript
107117
@Injectable()
108118
export class TodosService {
119+
private collectionService: NgxRxdbCollection<Todo> = inject<NgxRxdbCollection<Todo>>(NgxRxdbCollectionService);
109120
// store & get filter as property of a `local` document
110121
filter$ = this.collectionService
111122
.getLocal('local', 'filterValue')
112123
.pipe(startWith('ALL'), distinctUntilChanged());
113-
// get count of documents in collection as observable (use fast calculation with static colection method)
124+
// get count of documents in collection as observable
114125
count$ = this.collectionService.count();
115126

116-
constructor(private collectionService: NgxRxdbCollectionService<Todo>) {}
117-
// get documents from collection as observable using `RxQuery` mango-queries
118-
selectTodos(): Observable<Todo[]> {
119-
return this.filter$.pipe(
120-
switchMap(filterValue => {
121-
const queryObj = {
122-
selector: {
123-
createdAt: {
124-
$gt: null,
125-
},
126-
completed: filterValue === 'COMPLETED',
127-
},
128-
sort: [{ createdAt: 'desc' } as any],
129-
};
130-
return this.collectionService.docs(queryObj);
131-
})
132-
);
133-
}
127+
// get documents from collection as observable
128+
// optionally using `RxQuery` mango-queries
129+
todos$: Observable<Todo[]> = this.collectionService.docs();
134130

135131
// add new document
136132
add(name: string): void {
137133
const payload: Todo = { guid: uuid(), name, done: false, dateCreated: Date.now() };
138134
this.collectionService.insert(payload);
139135
}
140136

141-
// update prop od existing document
137+
// update property of single document
142138
toggle(guid: string, done: boolean): void {
143-
this.collectionService.update(guid, { done });
139+
this.collectionService.set(guid, { done });
144140
}
145141

146-
// use `bulk` to delete all dcouments by qeury
147-
removeDoneTodos(): void {
148-
const rulesObject = { done: { $eq: true } };
149-
this.collectionService.removeBulkBy(rulesObject);
142+
// update many documents with partial data by query
143+
toggleAllTodos(completed: boolean) {
144+
this.collectionService.updateBulk(
145+
{ selector: { completed: { $eq: !completed } } },
146+
{ completed }
147+
);
148+
}
149+
150+
// remove many dcouments by qeury
151+
removeCompletedTodos(): void {
152+
cthis.collectionService.removeBulk({ selector: { completed: true } });
150153
}
151154
// ...
152155
}
153156
```
154157

155-
## Features
158+
## Usage (Standalone)
156159

157-
By using this module you can
160+
### In your `main.ts`
158161

159-
- Automatically initialize db with settings, optionally provide db dumb to pre-fill with collections & documents
160-
- Automatically initialize RxCollection for each _lazy-loaded Feature module_ with config
161-
- Work straight with `db.collection` or via _NgxRxdbCollectionService_ wrapper with some helper methods
162+
```typescript
163+
import { provideRxDatabase } from '@ngx-odm/rxdb';
164+
import { getRxDatabaseCreator } from '@ngx-odm/rxdb/config';
165+
166+
export const appConfig: ApplicationConfig = {
167+
providers: [
168+
// ... other providers
169+
provideRxDatabase(
170+
getRxDatabaseCreator({
171+
name: 'demo',
172+
localDocuments: true,
173+
multiInstance: true,
174+
ignoreDuplicate: false,
175+
storage: getRxStorageDexie()
176+
})
177+
),
178+
],
179+
};
162180

163-
To-do list:
181+
bootstrapApplication(AppComponent, appConfig).catch(err => console.error(err));
182+
```
164183

165-
- Enable sync
166-
- ...
184+
### In your `Component`
167185

168-
## Diagrams
186+
```typescript
187+
import { provideRxCollection } from '@ngx-odm/rxdb';
188+
189+
@Component({
190+
standalone: true,
191+
// ...
192+
providers: [provideRxCollection(config)]
193+
})
194+
export class StandaloneComponent {
195+
readonly todoCollection = inject(NgxRxdbCollectionService<Todo>);
196+
}
197+
```
198+
199+
### Using `sginals` & `signalStore` from `@ngrx/signals`
200+
201+
```typescript
202+
import { signalStore } from '@ngrx/signals';
203+
import { withEntities } from '@ngrx/signals/entities';
204+
import { withCollectionService } from '@ngx-odm/rxdb/signals';
205+
import { withDevtools } from '@angular-architects/ngrx-toolkit';
206+
207+
export const TodoStore = signalStore(
208+
{ providedIn: 'root' },
209+
withDevtools('todo'),
210+
withEntities<Todo>(),
211+
// INFO: an instance of RxCollection will be provided by this
212+
withCollectionService<Todo, TodosFilter, RxCollectionCreatorExtended>({
213+
filter: 'ALL' as TodosFilter,
214+
collectionConfig: TodosCollectionConfig,
215+
}),
216+
...
217+
);
218+
219+
@Component({
220+
standalone: true,
221+
// ...
222+
providers: [TodoStore],
223+
})
224+
export class StandaloneComponent {
225+
readonly todoStore = inject(TodoStore);
226+
227+
constructor() {
228+
effect(() => {
229+
const { filter, entities } = this.todoStore;
230+
});
231+
}
232+
}
233+
```
234+
235+
## Features
236+
237+
By using this module you can simplify your work with RxDB in Angular application:
238+
239+
- Automatically initialize db with settings
240+
- optionally provide db dumb to pre-fill collections
241+
- optionally provide array of initial documents to pre-fill collection
242+
- optionally provide remote location for schema and fetch it automatically before create collection (e.g. to maintain single source of truth for schema)
243+
- optionally provide syncronization with remote db (CouchDB, Kinto etc.) as DB options
244+
- Automatically initialize RxCollection for each _lazy-loaded Feature module / standalone component_ with config
245+
- Work with documents via _NgxRxdbCollectionService_ with unified methods instead of using _RxCollection_ directly (though you still have access to _RxCollection_ and _RxDatabase_ instance)
246+
- Work with signals and entities with `@ngrx/signals` and `@ngrx/entity` (optionally _zoneless_) (see [example](examples/standalone/src/app/todos/todos.store.ts))
247+
248+
<!-- ## Diagrams
169249
170250
![NgxRxdbModule Initialization UML](examples/uml.NgxRxdbModule.png)
171251
NgxRxdbModule Initialization UML
172252
173253
![NgxRxdbService Sequence UML](examples/uml.NgxRxdbService.png)
174-
NgxRxdbModule Initialization UML
254+
NgxRxdbModule Initialization UML -->
175255

176256
## Status
177257

@@ -184,26 +264,10 @@ Project inspired by
184264
- [rxdb-angular2-example](https://github.com/pubkey/rxdb/blob/master/examples/angular2/README.md#rxdb-angular2-example)
185265
- [Angular NgRx Material Starter](https://tomastrajan.github.io/angular-ngrx-material-starter#/examples/todos)
186266
- _The Angular Library Series_ from [Angular In Depth](https://blog.angularindepth.com/)
267+
- [NgRx Toolkit](https://github.com/angular-architects/ngrx-toolkit/blob/main/libs/ngrx-toolkit/src/lib/with-data-service.ts) - inspired by Manfred Steyer and created singnals tool by analogy of `withDataService` from [Angular Architects](https://angulararchitects.io/)
187268

188269
## Notes
189270

190-
- example on how to trigger a query on signal change. e.g. filter todos using DB query and not in memory
191-
so `fetch` then must be triggered every time
192-
193-
```
194-
toObservable(filter)
195-
.pipe(
196-
switchMap(filterValue => {
197-
if (filterValue === 'COMPLETED') {
198-
query.selector = { completed: { $eq: true } };
199-
} else if (filterValue === 'ACTIVE') {
200-
query.selector = { completed: { $eq: false } };
201-
}
202-
return find(query);
203-
}),
204-
takeUntilDestroyed(this)
205-
).subscribe();
206-
```
207271

208272
## Contact
209273

examples/demo/src/app/todos/services/todos.service.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,7 @@ export class TodosService {
109109
}
110110

111111
removeCompletedTodos(): void {
112-
const rulesObject = { selector: { completed: true } };
113-
this.collectionService.removeBulk(rulesObject);
112+
this.collectionService.removeBulk({ selector: { completed: true } });
114113
this.filterTodos('ALL');
115114
}
116115

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"name": "ngx-odm",
44
"version": "0.0.0-dev",
55
"private": false,
6-
"description": "Angular ODMs for NoSql DBs like RxDB, Kinto",
6+
"description": "Angular 10+ wrapper (module or standalone) for RxDB - A realtime Database for the Web",
77
"keywords": [
88
"angular",
99
"rxjs",

packages/rxdb/CHANGELOG.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22

33
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
44

5-
# [5.0.0](https://github.com/voznik/ngx-odm/compare/v4.0.0...v5.0.0) (2024-01-08)
6-
7-
8-
95
# [4.0.0](https://github.com/voznik/ngx-odm/compare/v3.0.0...v4.0.0) (2023-11-02)
106

117
# [3.0.0](https://github.com/voznik/ngx-odm/compare/v3.0.0-dev.0...v3.0.0) (2023-10-18)

0 commit comments

Comments
 (0)