Skip to content

Commit

Permalink
Prevent remote-change events in RealtimeSyncOff mode (#176)
Browse files Browse the repository at this point in the history
* Prevent remote-change events in RealtimeSyncOff mode

* Fix lint error

* remove outdated test cases
  • Loading branch information
humdrum authored May 29, 2024
1 parent d32e035 commit 58f5114
Show file tree
Hide file tree
Showing 2 changed files with 1 addition and 133 deletions.
2 changes: 1 addition & 1 deletion Sources/Core/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ public actor Client {

// NOTE(chacha912, hackerwins): If syncLoop already executed with
// PushPull, ignore the response when the syncMode is PushOnly.
if responsePack.hasChanges(), attachment.syncMode == .realtimePushOnly {
if responsePack.hasChanges() && (attachment.syncMode == .realtimePushOnly || attachment.syncMode == .realtimeSyncOff) {
return doc
}

Expand Down
132 changes: 0 additions & 132 deletions Tests/Integration/PresenceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -717,138 +717,6 @@ final class PresenceSubscribeTests: XCTestCase {
try await c3.deactivate()
}

func test_presence_my_presence_remains_after_update() async throws {
let c1 = Client(rpcAddress)
let c2 = Client(rpcAddress)
try await c1.activate()
try await c2.activate()

let docKey = "\(Date().description)-\(self.description)".toDocKey

let doc1 = Document(key: docKey)
try await c1.attach(doc1)
let doc2 = Document(key: docKey)
try await c2.attach(doc2)

let startPath = [0, 1]
let endPath = [0, 3]

try await doc1.update { root, presence in
root.tree = JSONTree(initialRoot: JSONTreeElementNode(type: "doc", children: [
JSONTreeElementNode(type: "node", children: [
JSONTreeTextNode(value: "Hello")
])]))

let range = try (root.tree as? JSONTree)?.pathRangeToPosRange((startPath, endPath))

presence.set(["start": range!.0, "end": range!.1])
}

var myPresence = await doc1.getMyPresence()

var start: CRDTTreePosStruct = self.decodeDictionary(myPresence!["start"])!
var end: CRDTTreePosStruct = self.decodeDictionary(myPresence!["end"])!

var converted = try await(doc1.getRoot().tree as? JSONTree)?.posRangeToPathRange((start, end))

XCTAssertEqual(converted!.0, startPath)
XCTAssertEqual(converted!.1, endPath)

try await doc1.update { root, _ in
try (root.tree as? JSONTree)?.editByPath([0, 0], [0, 0], JSONTreeTextNode(value: "A"))
}

myPresence = await doc1.getMyPresence()

start = self.decodeDictionary(myPresence!["start"])!
end = self.decodeDictionary(myPresence!["end"])!

converted = try await(doc1.getRoot().tree as? JSONTree)?.posRangeToPathRange((start, end))

XCTAssertEqual(converted!.0, [0, 2])
XCTAssertEqual(converted!.1, [0, 4])

try await c1.deactivate()
try await c2.deactivate()
}

func test_presence_updated_when_someone_edits() async throws {
let c1 = Client(rpcAddress)
let c2 = Client(rpcAddress)
try await c1.activate()
try await c2.activate()
let c1ID = await c1.id!

let docKey = "\(Date().description)-\(self.description)".toDocKey

let doc1 = Document(key: docKey)
try await c1.attach(doc1, [:], .realtimeSyncOff)
let doc2 = Document(key: docKey)
try await c2.attach(doc2, [:], .realtimeSyncOff)

let startPath = [1, 0, 0, 2]
let endPath = [1, 0, 0, 3]

try await doc1.update { root, presence in
root.tree = JSONTree(initialRoot:
JSONTreeElementNode(type: "doc", children: [
JSONTreeElementNode(type: "Title", children: [
JSONTreeElementNode(type: "unit", children: [
JSONTreeElementNode(type: "paragraph", children: [
JSONTreeElementNode(type: "node")])])]),
JSONTreeElementNode(type: "text-1", children: [
JSONTreeElementNode(type: "paragraph", children: [
JSONTreeElementNode(type: "node", children: [
JSONTreeTextNode(value: "H"),
JSONTreeTextNode(value: "e"),
JSONTreeTextNode(value: "l"),
JSONTreeTextNode(value: "l"),
JSONTreeTextNode(value: "o")
])
])
])
])
)

let range = try (root.tree as? JSONTree)?.pathRangeToPosRange((startPath, endPath))

presence.set(["start": range!.0, "end": range!.1])
}

try await c1.sync()
try await c2.sync()

var myPresence = await doc2.getPresence(c1ID)

var start: CRDTTreePosStruct = self.decodeDictionary(myPresence!["start"])!
var end: CRDTTreePosStruct = self.decodeDictionary(myPresence!["end"])!

var converted = try await(doc1.getRoot().tree as? JSONTree)?.posRangeToPathRange((start, end))

XCTAssertEqual(converted!.0, startPath)
XCTAssertEqual(converted!.1, endPath)

try await doc1.update { root, _ in
try (root.tree as? JSONTree)?.editByPath([1, 0, 0, 1], [1, 0, 0, 1], JSONTreeTextNode(value: "ABC"))
}

try await c1.sync()
try await c2.sync()

myPresence = await doc2.getPresence(c1ID)

start = self.decodeDictionary(myPresence!["start"])!
end = self.decodeDictionary(myPresence!["end"])!

converted = try await(doc1.getRoot().tree as? JSONTree)?.posRangeToPathRange((start, end))

XCTAssertEqual(converted!.0, [1, 0, 0, 5])
XCTAssertEqual(converted!.1, [1, 0, 0, 6])

try await c1.deactivate()
try await c2.deactivate()
}

private func decodeDictionary(_ dictionary: Any?) -> CRDTTreePosStruct? {
guard let dictionary = dictionary as? [String: Any],
let data = try? JSONSerialization.data(withJSONObject: dictionary, options: [])
Expand Down

0 comments on commit 58f5114

Please sign in to comment.