Provide a custom trace transport
Inject delivery for tests or another durable destination.
The built-in HTTP transport is automatic. To use another destination, implement
LedgeTransport.upload(_:) and inject it when creating the client.
import Foundation
import LedgeKit
actor MemoryTransport: LedgeTransport {
private(set) var payloads: [Data] = []
func upload(_ upload: LedgeUpload) async throws {
payloads.append(try Data(contentsOf: upload.payloadURL))
}
}
func makeTestClient(directory: URL, transport: MemoryTransport) throws -> LedgeClient {
try LedgeClient(serviceName: "test-app", transport: transport, localDirectory: directory)
}LedgeUpload exposes id: UUID and payloadURL: URL. The file contains the complete
encoded envelope. Read its bytes before returning: successful upload permits the
outbox to delete it. Serialization and wire-model types are internal to the SDK.
In-memory acceptance is useful in a test. A production transport must return only after its destination durably accepts the payload. Preserve the upload ID when forwarding to an idempotent receiver.
Implement LedgeTransportFailure.isRetryable on errors that distinguish permanent
rejection from temporary failure. Unclassified errors remain retryable. The built-in
transport sends a bearer write key, content type, and trace ID idempotency header;
schemaVersion lives only in the JSON body.