[sub-spm-optional-products] Add LCECryptoKit and LCFeatureControl as optional sub-SPM products

LCEssentials installs standalone; each sub target-depends on it so linking a
sub's product always pulls LCEssentials in too, without the consumer having to
declare it separately.

- LCECryptoKit: internalized from the remote LCECryptoKitBinary git dependency
  (embedded token URL removed) into a local binaryTarget vendoring
  Frameworks/LCECryptoKit.xcframework. LCECryptoKitManager moved out of
  LCEssentials core into its own LCECryptoKitManager target/product; the
  no-op fallback for when the binary wasn't linked is gone (breaking change
  for existing consumers, see decisions/2026-09-15-sub-spm-optional-products.md).
- LCFeatureControl: new product wrapping Atomenta's Feature Control API
  (flag evaluation with TTL cache + safe-degrade fallback to defaults,
  notifications inbox, batched exposure telemetry). 45 new tests.
This commit is contained in:
Daniel Arantes Loverde
2026-09-16 09:23:57 -03:00
parent d067791930
commit 2ba487a6e8
47 changed files with 4264 additions and 113 deletions

View File

@@ -0,0 +1,33 @@
import Foundation
/// Wiring for one Atomenta Feature Control module deployment.
public struct FeatureControlConfiguration: Sendable {
public var baseURL: String
public var evaluatePath: String
public var notificationsPath: String
public var telemetryPath: String
public var environment: String
public var auth: any FeatureControlAuthorizing
/// In-memory cache TTL. FC-060 §5 recommends 3060s client-side.
public var cacheTTL: TimeInterval
/// FC-060 §5 recommends 1.53s at the BFF; same budget applies here.
public var requestTimeout: TimeInterval
public init(baseURL: String,
environment: String,
auth: any FeatureControlAuthorizing,
evaluatePath: String = "/api/feature-control/evaluate",
notificationsPath: String = "/api/feature-control/notifications",
telemetryPath: String = "/api/feature-control/telemetry/exposure",
cacheTTL: TimeInterval = 45,
requestTimeout: TimeInterval = 3) {
self.baseURL = baseURL
self.environment = environment
self.auth = auth
self.evaluatePath = evaluatePath
self.notificationsPath = notificationsPath
self.telemetryPath = telemetryPath
self.cacheTTL = cacheTTL
self.requestTimeout = requestTimeout
}
}