Swift Customization
Keep provider, trusted actor and tenant, request policy, App Audit Sink, and optional telemetry in the
application composition root. Generated queries and mutations receive only context. Do not add a
second data-service argument or allow federation payloads to replace governance resources.
GeneratedRuntimeModule.module is a passive manifest. Install it during runtime assembly, then use
context.ensureSchema(GeneratedRuntimeModule.module) only at an explicit startup or administrative
boundary. Passing only module.entities bypasses module-owned root and constant bootstrap behavior.
Module installation, request handling, health checks, and telemetry setup must not alter the
production schema implicitly.
RuntimeTelemetry is no-op by default. If OpenTelemetry is enabled, the application owns exporters, processors, flush, and shutdown. Telemetry failure must not change a business result, and sampling must never suppress the App Audit Sink.
Worked Example: Trusted Runtime Composition
public enum RuntimeCustomizationError: Error {
case missingTrustedTenant
case resourceBusy
}
public struct RuntimeComposition {
public let context: UserContext
public let dataService: SQLiteDataService
public let module: RuntimeModule
}
public func configuredRuntime(
databasePath: String,
module: RuntimeModule,
requestPolicy: RequestPolicy,
trustedTenant: String,
appAuditSink: any AuditSink,
telemetry: any RuntimeTelemetry = NoopRuntimeTelemetry()
) throws -> RuntimeComposition {
guard !trustedTenant.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
else { throw RuntimeCustomizationError.missingTrustedTenant }
let service = try SQLiteDataService(path: databasePath)
let context = UserContext(
actor: "teaql-application",
trustedTenant: trustedTenant,
queryExecutor: service,
mutationExecutor: service,
requestPolicy: requestPolicy,
auditSink: appAuditSink,
runtimeTelemetry: telemetry)
return RuntimeComposition(context: context, dataService: service, module: module)
}
public func readiness(_ runtime: RuntimeComposition) async throws {
guard let tenant = runtime.context.trustedTenant, !tenant.isEmpty
else { throw RuntimeCustomizationError.missingTrustedTenant }
try await runtime.context.ensureSchema(runtime.module)
}
The general Swift RequestPolicy hook applies to queries. Enforce Mutation
tenant authorization at the application/provider/TFP boundary as well.
Runtime infrastructure
Swift provides injectable LocalCache/LocalCache.shared and
LocalLock/LocalLock.shared; both are process-local. The caller supplies a
stable UUID owner to tryLock and unlock. TeaQL currently claims no Swift
Remote Cache, Remote Lock, Nacos, or Consul adapter. See
Cache, Lock, and Cloud Runtime Infrastructure
for TTL, lease, readiness, and telemetry rules.
Worked Example: Local Cache and Lock
Keep one stable owner UUID for the scope that owns the lock:
let cache = LocalCache.shared
let locks = LocalLock.shared
let lockOwner = UUID()
func currencyView(
context: UserContext,
tenant: String,
code: String
) async throws -> CurrencyView {
let cacheKey = "\(tenant):currency:\(code)"
if let value: CurrencyView = cache.get(cacheKey) { return value }
let lockKey = "\(tenant):currency-refresh:\(code)"
guard locks.tryLock(lockKey, owner: lockOwner, timeoutMillis: 250, expireMillis: 5_000)
else { throw RuntimeCustomizationError.resourceBusy }
defer { locks.unlock(lockKey, owner: lockOwner) }
if let value: CurrencyView = cache.get(cacheKey) { return value }
let value = try await loadAuthorizedCurrencyView(context, code)
cache.put(cacheKey, value: value, timeToLiveInSeconds: 300)
return value
}
RuntimeCustomizationError.resourceBusy is an application error case to add;
it is not generated by TeaQL. Remove the cache entry after the corresponding
audited Mutation commits.