Skip to content

Commit e15df6a

Browse files
Copilotpubkey
andauthored
docs: Document RxDocument immutability and lifetime behavior in rx-document.md (#7929)
* Initial plan * docs: add RxDocument lifetime and immutability section to rx-document.md Co-authored-by: pubkey <8926560+pubkey@users.noreply.github.com> * docs: move Document Lifetime and Immutability section after isRxDocument Co-authored-by: pubkey <8926560+pubkey@users.noreply.github.com> * docs: add link to conflicts page in Document Lifetime and Immutability section Co-authored-by: pubkey <8926560+pubkey@users.noreply.github.com> * docs: remove introductory line from Document Lifetime section Co-authored-by: pubkey <8926560+pubkey@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pubkey <8926560+pubkey@users.noreply.github.com>
1 parent 48a0141 commit e15df6a

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

docs-src/docs/rx-document.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,6 @@ const latestDoc = myDocument.getLatest();
173173
console.log(docAfterEdit === latestDoc); // > true
174174
```
175175

176-
177-
178176
### Observe $
179177
Calling this will return an [RxJS Observable](https://rxjs.dev/guide/observable) which emits the current newest state of the RxDocument.
180178

@@ -297,3 +295,31 @@ Returns true if the given object is an instance of RxDocument. Returns false if
297295
```js
298296
const is = isRxDocument(myObj);
299297
```
298+
299+
## Document Lifetime and Immutability
300+
301+
**RxDocument instances are immutable.** Each instance represents a snapshot of the document at the time it was fetched or last written. Modifying a document does not update existing instances of it - it creates a new `RxDocument` instance with the updated data. The old instance retains its original data.
302+
303+
```js
304+
const doc = await myCollection.findOne('foobar').exec();
305+
console.log(doc.age); // 10
306+
307+
await doc.incrementalPatch({ age: 20 });
308+
309+
// The original instance still has the old data
310+
console.log(doc.age); // 10
311+
312+
// Use getLatest() to get the updated state
313+
console.log(doc.getLatest().age); // 20
314+
```
315+
316+
**RxDB de-duplicates document instances.** When the same document is fetched multiple times without any writes in between, RxDB returns the same instance to save memory. Once a write occurs, subsequent fetches return a new instance reflecting the updated state.
317+
318+
**Calling non-incremental write methods on an outdated instance throws a `CONFLICT` error.** If you hold a reference to a document and another operation modifies that document in the meantime, calling `.patch()`, `.update()`, or `.modify()` on the outdated instance will fail with a conflict error. See [Transactions, Conflicts and Revisions](./transactions-conflicts-revisions.md) for details on how RxDB handles conflicts.
319+
320+
To avoid this, either:
321+
- Use the [incremental methods](#prevent-conflicts-with-the-incremental-methods) (`incrementalPatch`, `incrementalModify`, `incrementalUpdate`) which always fetch the latest state before applying changes.
322+
- Call `getLatest()` to get the current state before writing.
323+
- Re-query the collection to get a fresh document.
324+
325+
**How long to keep a reference to an `RxDocument`.** Treat an `RxDocument` like plain JSON data - it is a snapshot valid at the time of retrieval. RxDB manages query result caching internally via [event-reduce](./rx-query.md), so you do not need to cache documents yourself. For components that display document data and need live updates, subscribe to the document's `$` observable instead of holding a static reference.

0 commit comments

Comments
 (0)