Documentation Index
Fetch the complete documentation index at: https://docs.myme.so/llms.txt
Use this file to discover all available pages before exploring further.
Conflict handling
See Errors — version_conflict for the enriched 409 payload and Conflicts for the resolution model. The Swift SDK exposes the three modes asClientConfiguration.conflictStrategy and UpdateOptions.conflict.
.auto (default), .manual (throws ConflictError with current, ancestor, conflictingFields, clientPatch, mergePolicy), and .callback are the three modes.
.auto is policy-aware. The SDK reads the type’s merge_policy directly from the 409 response and resolves each conflicting field per its strategy. last_writer_wins fields take the server’s value; keep_both_copies fields spawn a sibling item of the same type, tagged conflicted-copy, populated from the client’s in-flight values for the keep-both fields and the server’s current values for the rest. The original item retains the server’s winning state for the conflicted keep-both fields; non-keep-both client changes apply normally.
The SyncEngine.events stream emits .conflictAutoMerged(payload:) whenever a replay auto-merge fires:
conflictedCopyId != nil — the user’s in-flight edit was preserved as a sibling rather than discarded.
In synced mode the chosen conflict strategy is captured with the queued mutation so it applies on replay against any 409 the server returns. The .callback resolver closure can’t be queued (closures aren’t Codable); on replay, .callback degrades to .auto.
Errors
Errors are subclasses of a baseMarfaError. Pattern-match on the subclass:
MarfaError.code is a String, not an enum. Branch on the subclass where one exists; fall through to MarfaError and inspect code for anything else. Error codes are stable strings ("version_conflict", "rate_limited") — branch on them, not on the message.NotFoundError, ValidationError, UnauthorizedError, ForbiddenError, ConflictError, NetworkError, ResponseDecodingError, LocalModeUnsupportedError.
Testing
MarfaSDKTestSupport ships as a separate product alongside MarfaSDK and provides scaffolding for unit tests:
MockTransport— stub for theTransportprotocol. Queue responses, assert on captured requests.InMemoryKeychain— in-memorySecureStoragesubstitute. SPM test binaries run unsigned and can’t reach the real Keychain.MarfaSDKTest.makeInMemoryClient()— pure-localMarfaClientbacked by an in-memoryModelContainer. Drop-in replacement forMarfaClient.local(path:)in test setups; sidesteps the cross-test container issues that show up when sharing a file-backed store across cases in the same process.
MarfaSDKTestSupport as a dependency on your test target only. The product is non-semver-stable across SDK minor versions and is not intended for production code.
The Transport protocol is public. MockTransport exists primarily for mocking the network in unit tests; the production MarfaClient init always instantiates URLSessionTransport. The protocol includes rawUpload(method:path:body:contentType:query:onBytesSent:) — the progress-aware upload hook that forwards URLSessionTaskDelegate.didSendBodyData — so stubs exercising byte-progress code paths (e.g. against BlobUploadProgressQuery) can drive those callbacks deterministically from a mock.
Concurrency model
MarfaClientisSendable— safe to pass across actors.- Namespace methods are
async throwsand don’t require caller isolation. LocalStore,MutationQueue,SyncEngine,ConnectionStateManagerare Swift actors. Shared state is actor-isolated; callers never synchronise manually.MarfaStoreand query classes are@MainActor @Observable— observe them directly from SwiftUI views.- The whole package builds under Swift 6 strict concurrency with zero
@unchecked Sendableleaks in the public surface.