From 9548e39d62af88870f5f846da14ba141183f7b4a Mon Sep 17 00:00:00 2001 From: Jesse Grosjean Date: Sun, 21 Jul 2024 12:49:12 -0400 Subject: [PATCH] Document object did change (#195) * Change objectDidChange public API to AnyPublisher * Add example and note that objectWillChange and objectDidChange are always paired to documentation --- Sources/Automerge/Document.swift | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/Sources/Automerge/Document.swift b/Sources/Automerge/Document.swift index 2ac06a36..f5e02208 100644 --- a/Sources/Automerge/Document.swift +++ b/Sources/Automerge/Document.swift @@ -27,13 +27,30 @@ public final class Document: @unchecked Sendable { try work() } #endif - + #if canImport(Combine) - /// A publisher that sends a signal after the document is updated. + private let objectDidChangeSubject: PassthroughSubject<(), Never> = .init() + + /// A publisher that emits after the document has changed. + /// + /// This publisher and ``objectWillChange()`` are always paired. Unlike that + /// publisher, this one fires after the document update is complete, allowing you to + /// read any changed values. /// - /// You can use the signal from this publisher to read the and record ``Document/heads()`` - /// to get the state indicator of the document after the change is complete. - public let objectDidChange: PassthroughSubject = .init() + /// An example that uses this publisher to observe granular patch changes: + /// + /// ```swift + /// var observedHeads = doc.heads() + /// doc.objectDidChange.sink { + /// let changes = doc.difference(since: observedHeads) + /// observedHeads = doc.heads() + /// if !changes.isEmpty { + /// processChanges(changes) + /// } + /// }.store(in: &cancellables) + public lazy var objectDidChange: AnyPublisher<(), Never> = { + objectDidChangeSubject.eraseToAnyPublisher() + }() #endif var reportingLogLevel: LogVerbosity @@ -1272,7 +1289,7 @@ extension Document: ObservableObject { } fileprivate func sendObjectDidChange() { - objectDidChange.send() + objectDidChangeSubject.send() } } #else