Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DemoCore/Sources/DemoCore/Features/ScreenMachines.swift
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ public final class TaskFormSheetMachine {

_Concurrency.Task {
do {
let payload = try DemoSyncPayload(dictionary: requestBody)
let payload = try SyncJSON(dictionary: requestBody)
switch mode {
case .create(let projectID):
try await syncEngine.createTask(body: payload, projectID: projectID)
Expand Down
27 changes: 14 additions & 13 deletions DemoCore/Sources/DemoCore/Networking/DemoAPI.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import DemoBackend
import Foundation
import SwiftSync

public typealias DemoSeedData = DemoBackend.DemoSeedData
public typealias DemoServerSimulator = DemoBackend.DemoServerSimulator
Expand Down Expand Up @@ -83,67 +84,67 @@ public final class FakeDemoAPIClient {
}
}

public func getProjects() async throws -> [DemoSyncPayload] {
public func getProjects() async throws -> [SyncJSON] {
try await networkGate(endpoint: "GET /projects")
return try backend.getProjectsPayload().map(Self.makePayload)
}

public func getProjectTasks(projectID: String) async throws -> [DemoSyncPayload] {
public func getProjectTasks(projectID: String) async throws -> [SyncJSON] {
try await networkGate(endpoint: "GET /projects/{id}/tasks")
return try backend.getProjectTasksPayload(projectID: projectID).map(Self.makePayload)
}

public func getUsers() async throws -> [DemoSyncPayload] {
public func getUsers() async throws -> [SyncJSON] {
try await networkGate(endpoint: "GET /users")
return try backend.getUsersPayload().map(Self.makePayload)
}

public func getTaskDetail(taskID: String) async throws -> DemoSyncPayload? {
public func getTaskDetail(taskID: String) async throws -> SyncJSON? {
try await networkGate(endpoint: "GET /tasks/{id}")
guard let payload = try backend.getTaskDetailPayload(publicID: taskID) else { return nil }
return try Self.makePayload(payload)
}

public func getTaskStateOptions() async throws -> [DemoSyncPayload] {
public func getTaskStateOptions() async throws -> [SyncJSON] {
try await networkGate(endpoint: "GET /task-state-options")
return try backend.getTaskStateOptionsPayload().map(Self.makePayload)
}

public func patchTaskState(taskID: String, state: String) async throws -> DemoSyncPayload? {
public func patchTaskState(taskID: String, state: String) async throws -> SyncJSON? {
try await networkGate(endpoint: "PATCH /tasks/{id} (state)")
guard let payload = try backend.patchTaskState(publicID: taskID, state: state) else { return nil }
return try Self.makePayload(payload)
}

public func patchTaskAssignee(taskID: String, assigneeID: String?) async throws -> DemoSyncPayload? {
public func patchTaskAssignee(taskID: String, assigneeID: String?) async throws -> SyncJSON? {
try await networkGate(endpoint: "PATCH /tasks/{id} (assignee_id)")
guard let payload = try backend.patchTaskAssignee(publicID: taskID, assigneeID: assigneeID) else { return nil }
return try Self.makePayload(payload)
}

public func replaceTaskReviewers(taskID: String, reviewerIDs: [String]) async throws -> DemoSyncPayload? {
public func replaceTaskReviewers(taskID: String, reviewerIDs: [String]) async throws -> SyncJSON? {
try await networkGate(endpoint: "PUT /tasks/{id}/reviewers")
guard let payload = try backend.replaceTaskReviewers(publicID: taskID, reviewerIDs: reviewerIDs) else {
return nil
}
return try Self.makePayload(payload)
}

public func replaceTaskWatchers(taskID: String, watcherIDs: [String]) async throws -> DemoSyncPayload? {
public func replaceTaskWatchers(taskID: String, watcherIDs: [String]) async throws -> SyncJSON? {
try await networkGate(endpoint: "PUT /tasks/{id}/watchers")
guard let payload = try backend.replaceTaskWatchers(publicID: taskID, watcherIDs: watcherIDs) else {
return nil
}
return try Self.makePayload(payload)
}

public func createTask(body: DemoSyncPayload) async throws -> DemoSyncPayload {
public func createTask(body: SyncJSON) async throws -> SyncJSON {
try await networkGate(endpoint: "POST /tasks")
let created = try backend.createTask(body: body.toSyncPayloadDictionary())
return try Self.makePayload(created)
}

public func updateTask(taskID: String, body: DemoSyncPayload) async throws -> DemoSyncPayload? {
public func updateTask(taskID: String, body: SyncJSON) async throws -> SyncJSON? {
try await networkGate(endpoint: "PUT /tasks/{id}")
let updated = try backend.updateTask(publicID: taskID, body: body.toSyncPayloadDictionary())
return try Self.makePayload(updated)
Expand Down Expand Up @@ -203,9 +204,9 @@ public final class FakeDemoAPIClient {
try await _Concurrency.Task.sleep(nanoseconds: (baseDelayMS + jitter + mutationExtra) * 1_000_000)
}

private static func makePayload(_ dictionary: [String: Any]) throws -> DemoSyncPayload {
private static func makePayload(_ dictionary: [String: Any]) throws -> SyncJSON {
do {
return try DemoSyncPayload(dictionary: dictionary)
return try SyncJSON(dictionary: dictionary)
} catch {
throw DemoAPIError.invalidPayload(error.localizedDescription)
}
Expand Down
120 changes: 0 additions & 120 deletions DemoCore/Sources/DemoCore/Networking/DemoSyncPayload.swift

This file was deleted.

12 changes: 6 additions & 6 deletions DemoCore/Sources/DemoCore/Sync/DemoSyncEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public final class DemoSyncEngine {
}
}

public func createTask(body: DemoSyncPayload, projectID: String) async throws {
public func createTask(body: SyncJSON, projectID: String) async throws {
if isOffline {
guard let project = try project(withID: projectID) else {
throw SyncTaskDetailError.missingProject(projectID)
Expand All @@ -107,7 +107,7 @@ public final class DemoSyncEngine {
}
}

public func updateTask(taskID: String, projectID: String?, body: DemoSyncPayload) async throws {
public func updateTask(taskID: String, projectID: String?, body: SyncJSON) async throws {
// A row the server doesn't have yet (offline-created, or a rejected insert) can't be PUT — it
// must be (re)sent as an upsert. Apply locally so it stays a pending change; online, push it.
let neverSynced = isNeverPushed(taskID)
Expand Down Expand Up @@ -275,7 +275,7 @@ public final class DemoSyncEngine {
// hard-deleted row when a delete loses) and treat the row as resolved, not a failure.
if let server = result["server"] as? [String: Any] {
try? await syncContainer.sync(
item: DemoSyncPayload(dictionary: server), as: Task.self)
item: SyncJSON(dictionary: server), as: Task.self)
}
case ("upsert", "applied"), ("delete", "applied"):
break
Expand Down Expand Up @@ -305,7 +305,7 @@ public final class DemoSyncEngine {
/// Apply a payload to the local store as a *local* edit (default author), so it's tracked as a
/// pending change — unlike `syncContainer.sync(item:)`, which stamps writes as inbound (pulled).
/// Reuses the `@Syncable`-generated `make`/`apply`, so no field mapping is duplicated here.
private func applyLocalTask(_ body: DemoSyncPayload, project: Project? = nil) throws {
private func applyLocalTask(_ body: SyncJSON, project: Project? = nil) throws {
let values = body.toSyncPayloadDictionary()
let payload = SyncPayload(values: values, keyStyle: syncContainer.keyStyle)
let context = syncContainer.mainContext
Expand Down Expand Up @@ -449,7 +449,7 @@ public final class DemoSyncEngine {
try await syncItemsIfPresent(in: payload, taskID: taskID)
}

private func syncTaskDetailItem(_ payload: DemoSyncPayload) async throws {
private func syncTaskDetailItem(_ payload: SyncJSON) async throws {
guard let projectID = payload.string("project_id"), !projectID.isEmpty else {
throw SyncTaskDetailError.missingProjectID
}
Expand Down Expand Up @@ -491,7 +491,7 @@ public final class DemoSyncEngine {
).first
}

private func syncItemsIfPresent(in payload: DemoSyncPayload, taskID: String) async throws {
private func syncItemsIfPresent(in payload: SyncJSON, taskID: String) async throws {
guard let itemPayload = payload.objectArray("items") else { return }
guard let resolvedTask = try task(withID: taskID) else { return }
nonisolated(unsafe) let task = resolvedTask
Expand Down
Loading