Skip to content

Commit e369f1f

Browse files
authored
chore: kickoff release
2 parents 30728eb + 9f8e690 commit e369f1f

File tree

4 files changed

+89
-40
lines changed

4 files changed

+89
-40
lines changed

AmplifyPlugins/DataStore/Sources/AWSDataStorePlugin/Sync/SubscriptionSync/ReconcileAndLocalSave/RemoteSyncReconciler.swift

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,41 @@ struct RemoteSyncReconciler {
3333
}
3434
}
3535

36-
3736
/// Reconciles the incoming `remoteModels` against the local metadata to get the disposition
3837
///
38+
/// GroupBy the remoteModels by model identifier and apply only the latest version of the remoteModel
39+
///
3940
/// - Parameters:
4041
/// - remoteModels: models retrieved from the remote store
4142
/// - localMetadatas: metadata retrieved from the local store
4243
/// - Returns: disposition of models to apply locally
43-
static func getDispositions(_ remoteModels: [RemoteModel],
44-
localMetadatas: [LocalMetadata]) -> [Disposition] {
45-
guard !remoteModels.isEmpty else {
44+
static func getDispositions(
45+
_ remoteModels: [RemoteModel],
46+
localMetadatas: [LocalMetadata]
47+
) -> [Disposition] {
48+
let remoteModelsGroupByIdentifier = remoteModels.reduce([String: [RemoteModel]]()) {
49+
$0.merging([
50+
$1.model.identifier: ($0[$1.model.identifier] ?? []) + [$1]
51+
], uniquingKeysWith: { $1 })
52+
}
53+
54+
let optimizedRemoteModels = remoteModelsGroupByIdentifier.values.compactMap {
55+
$0.sorted(by: { $0.syncMetadata.version > $1.syncMetadata.version }).first
56+
}
57+
58+
guard !optimizedRemoteModels.isEmpty else {
4659
return []
4760
}
48-
61+
4962
guard !localMetadatas.isEmpty else {
50-
return remoteModels.compactMap { getDisposition($0, localMetadata: nil) }
63+
return optimizedRemoteModels.compactMap { getDisposition($0, localMetadata: nil) }
5164
}
52-
53-
let metadataBymodelId = localMetadatas.reduce(into: [:]) { $0[$1.modelId] = $1 }
54-
let dispositions = remoteModels.compactMap { getDisposition($0, localMetadata: metadataBymodelId[$0.model.identifier]) }
55-
65+
66+
let metadataByModelId = localMetadatas.reduce(into: [:]) { $0[$1.modelId] = $1 }
67+
let dispositions = optimizedRemoteModels.compactMap {
68+
getDisposition($0, localMetadata: metadataByModelId[$0.model.identifier])
69+
}
70+
5671
return dispositions
5772
}
5873

AmplifyPlugins/DataStore/Tests/AWSDataStorePluginTests/Sync/SubscriptionSync/RemoteSyncReconcilerTests.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,33 @@ class RemoteSyncReconcilerTests: XCTestCase {
179179
}
180180
waitForExpectations(timeout: 1)
181181
}
182+
183+
func testGetDispositions_emptyLocal_singleModelAddedAndDeleted() {
184+
let sameId = UUID().uuidString
185+
186+
let remoteModels = [
187+
makeRemoteModel(modelId: sameId, deleted: false, version: 1),
188+
makeRemoteModel(modelId: sameId, deleted: true, version: 2)
189+
]
190+
191+
let dispositions = RemoteSyncReconciler.getDispositions(remoteModels, localMetadatas: [])
192+
193+
XCTAssertTrue(dispositions.isEmpty)
194+
}
195+
196+
func testGetDispositions_emptyLocal_oneModelAdded_SecondModelAddedAndDeleted() {
197+
let sameId = UUID().uuidString
198+
199+
let remoteModels = [
200+
makeRemoteModel(deleted: false, version: 1),
201+
makeRemoteModel(modelId: sameId, deleted: false, version: 1),
202+
makeRemoteModel(modelId: sameId, deleted: true, version: 2)
203+
]
204+
205+
let dispositions = RemoteSyncReconciler.getDispositions(remoteModels, localMetadatas: [])
206+
207+
XCTAssertTrue(dispositions.count == 1)
208+
}
182209

183210
// MARK: - Utilities
184211

AmplifyPlugins/Predictions/AWSPredictionsPlugin/Liveness/Service/FaceLivenessSession.swift

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ public final class FaceLivenessSession: LivenessService {
1717
let baseURL: URL
1818
var serverEventListeners: [LivenessEventKind.Server: (FaceLivenessSession.SessionConfiguration) -> Void] = [:]
1919
var onComplete: (ServerDisconnection) -> Void = { _ in }
20+
21+
private let livenessServiceDispatchQueue = DispatchQueue(
22+
label: "com.amazon.aws.amplify.liveness.service",
23+
target: .global()
24+
)
2025

2126
init(
2227
websocket: WebSocketSession,
@@ -77,36 +82,38 @@ public final class FaceLivenessSession: LivenessService {
7782

7883
public func send<T>(
7984
_ event: LivenessEvent<T>,
80-
eventDate: () -> Date = Date.init
85+
eventDate: @escaping () -> Date = Date.init
8186
) {
82-
let encodedPayload = eventStreamEncoder.encode(
83-
payload: event.payload,
84-
headers: [
85-
":content-type": .string("application/json"),
86-
":event-type": .string(event.eventTypeHeader),
87-
":message-type": .string("event")
88-
]
89-
)
90-
91-
let eventDate = eventDate()
92-
93-
let signedPayload = signer.signWithPreviousSignature(
94-
payload: encodedPayload,
95-
dateHeader: (key: ":date", value: eventDate)
96-
)
97-
98-
let encodedEvent = eventStreamEncoder.encode(
99-
payload: encodedPayload,
100-
headers: [
101-
":date": .timestamp(eventDate),
102-
":chunk-signature": .data(signedPayload)
103-
]
104-
)
105-
106-
websocket.send(
107-
message: .data(encodedEvent),
108-
onError: { _ in }
109-
)
87+
livenessServiceDispatchQueue.async {
88+
let encodedPayload = self.eventStreamEncoder.encode(
89+
payload: event.payload,
90+
headers: [
91+
":content-type": .string("application/json"),
92+
":event-type": .string(event.eventTypeHeader),
93+
":message-type": .string("event")
94+
]
95+
)
96+
97+
let eventDate = eventDate()
98+
99+
let signedPayload = self.signer.signWithPreviousSignature(
100+
payload: encodedPayload,
101+
dateHeader: (key: ":date", value: eventDate)
102+
)
103+
104+
let encodedEvent = self.eventStreamEncoder.encode(
105+
payload: encodedPayload,
106+
headers: [
107+
":date": .timestamp(eventDate),
108+
":chunk-signature": .data(signedPayload)
109+
]
110+
)
111+
112+
self.websocket.send(
113+
message: .data(encodedEvent),
114+
onError: { _ in }
115+
)
116+
}
110117
}
111118

112119
private func fallbackDecoding(_ message: EventStream.Message) -> Bool {

AmplifyPlugins/Predictions/AWSPredictionsPlugin/Liveness/Service/FaceLivenessSessionRepresentable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import Amplify
1212
public protocol LivenessService {
1313
func send<T>(
1414
_ event: LivenessEvent<T>,
15-
eventDate: () -> Date
15+
eventDate: @escaping () -> Date
1616
)
1717

1818
var onServiceException: (FaceLivenessSessionError) -> Void { get set }

0 commit comments

Comments
 (0)