|
|
|
|
@ -238,38 +238,40 @@ actor ApiCallCollection<T: SyncedStorable>: SomeCallCollection { |
|
|
|
|
fileprivate func _call(method: HTTPMethod, instance: T? = nil) async throws -> ApiCall<T>? { |
|
|
|
|
|
|
|
|
|
if let instance { |
|
|
|
|
return try await self._callForInstance(method, instance: instance) |
|
|
|
|
return try await self._callForInstance(instance, method: method) |
|
|
|
|
} else { |
|
|
|
|
if self.items.contains(where: { $0.method == .get }) { |
|
|
|
|
return nil |
|
|
|
|
} else { |
|
|
|
|
return try self._createCall(.get) |
|
|
|
|
return try self._createGetCall() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _callForInstance(_ method: HTTPMethod, instance: T) async throws -> ApiCall<T>? { |
|
|
|
|
fileprivate func _callForInstance(_ instance: T, method: HTTPMethod, transactionId: String? = nil) async throws -> ApiCall<T> { |
|
|
|
|
|
|
|
|
|
// cleanup |
|
|
|
|
let existingCalls = self.items.filter { $0.dataId == instance.stringId } |
|
|
|
|
self._deleteCalls(existingCalls) |
|
|
|
|
|
|
|
|
|
if let existingCall = self.items.first(where: { $0.dataId == instance.stringId }) { |
|
|
|
|
switch method { |
|
|
|
|
case .delete: |
|
|
|
|
self.deleteById(existingCall.id) // delete the existing call as we don't need it |
|
|
|
|
if existingCall.method == HTTPMethod.post { |
|
|
|
|
return nil // if the post has not been done, we can just stop here |
|
|
|
|
} else { |
|
|
|
|
return try self._createCall(method, instance: instance) // otherwise it's a put and we want to send the delete |
|
|
|
|
} |
|
|
|
|
default: // here we should only trying to PUT, so we update the existing POST/PUT with the instance new values |
|
|
|
|
existingCall.body = try instance.jsonString() |
|
|
|
|
return existingCall |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
return try self._createCall(method, instance: instance) |
|
|
|
|
// create |
|
|
|
|
let call = try self._createCall(method, instance: instance, transactionId: transactionId) |
|
|
|
|
self._prepareCall(apiCall: call) |
|
|
|
|
return call |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _deleteCalls(_ calls: [ApiCall<T>]) { |
|
|
|
|
for call in calls { |
|
|
|
|
self.deleteById(call.id) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _createGetCall() throws -> ApiCall<T> { |
|
|
|
|
return try self._createCall(.get, instance: nil) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Creates an API call for the Storable [instance] and an HTTP [method] |
|
|
|
|
fileprivate func _createCall(_ method: HTTPMethod, instance: T? = nil, transactionId: String? = nil) throws -> ApiCall<T> { |
|
|
|
|
fileprivate func _createCall(_ method: HTTPMethod, instance: T?, transactionId: String? = nil) throws -> ApiCall<T> { |
|
|
|
|
if let instance { |
|
|
|
|
let jsonString = try instance.jsonString() |
|
|
|
|
return ApiCall(method: method, dataId: instance.stringId, body: jsonString, transactionId: transactionId) |
|
|
|
|
@ -302,31 +304,34 @@ actor ApiCallCollection<T: SyncedStorable>: SomeCallCollection { |
|
|
|
|
var apiCalls: [ApiCall<T>] = [] |
|
|
|
|
let transactionId = Store.randomId() |
|
|
|
|
for insert in batch.inserts { |
|
|
|
|
let call = try self._createCall(.post, instance: insert, transactionId: transactionId) |
|
|
|
|
self._prepareCall(apiCall: call) |
|
|
|
|
let call = try await self._callForInstance(insert, method: .post, transactionId: transactionId) |
|
|
|
|
apiCalls.append(call) |
|
|
|
|
} |
|
|
|
|
for update in batch.updates { |
|
|
|
|
let call = try self._createCall(.put, instance: update, transactionId: transactionId) |
|
|
|
|
self._prepareCall(apiCall: call) |
|
|
|
|
let call = try await self._callForInstance(update, method: .put, transactionId: transactionId) |
|
|
|
|
apiCalls.append(call) |
|
|
|
|
} |
|
|
|
|
for delete in batch.deletes { |
|
|
|
|
let call = try self._createCall(.delete, instance: delete, transactionId: transactionId) |
|
|
|
|
self._prepareCall(apiCall: call) |
|
|
|
|
let call = try await self._callForInstance(delete, method: .delete, transactionId: transactionId) |
|
|
|
|
apiCalls.append(call) |
|
|
|
|
} |
|
|
|
|
return try await self._executeApiCalls(apiCalls) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Initiates the process of sending the data with the server |
|
|
|
|
fileprivate func _sendServerRequest<V: Decodable>(_ method: HTTPMethod, instance: T? = nil) async throws -> V? { |
|
|
|
|
if let apiCall = try await self._call(method: method, instance: instance) { |
|
|
|
|
return try await self._prepareAndSendCall(apiCall) |
|
|
|
|
} else { |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// /// Initiates the process of sending the data with the server |
|
|
|
|
//<<<<<<< HEAD |
|
|
|
|
// fileprivate func _sendServerRequest<V: Decodable>(_ method: HTTPMethod, instance: T? = nil) async throws -> V? { |
|
|
|
|
// if let apiCall = try await self._call(method: method, instance: instance) { |
|
|
|
|
// return try await self._prepareAndSendCall(apiCall) |
|
|
|
|
//======= |
|
|
|
|
// fileprivate func _synchronize<V: Decodable>(_ instance: T, method: HTTPMethod) async throws -> V? { |
|
|
|
|
// if let apiCall = try await self._callForInstance(instance, method: method) { |
|
|
|
|
// return try await self._executeApiCall(apiCall) |
|
|
|
|
//>>>>>>> main |
|
|
|
|
// } else { |
|
|
|
|
// return nil |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
fileprivate func _prepareAndSendCall<V: Decodable>(_ apiCall: ApiCall<T>) async throws -> V? { |
|
|
|
|
self._prepareCall(apiCall: apiCall) |
|
|
|
|
|