@@ -11,6 +11,8 @@ import com.posthog.server.internal.PostHogMemoryQueue
1111import com.posthog.server.internal.PostHogServerContext
1212import java.net.Proxy
1313
14+ internal typealias NullaryCallback = () -> Unit
15+
1416/* *
1517 * The SDK Config
1618 */
@@ -106,6 +108,31 @@ public open class PostHogConfig constructor(
106108 * Defaults to 1000
107109 */
108110 public var featureFlagCalledCacheSize : Int = DEFAULT_FEATURE_FLAG_CALLED_CACHE_SIZE ,
111+ /* *
112+ * Enable local evaluation of feature flags
113+ * When enabled, the SDK periodically fetches flag definitions and evaluates flags locally
114+ * without making API calls for each flag check. Falls back to API if evaluation is inconclusive.
115+ * Requires personalApiKey to be set.
116+ * Defaults to false
117+ */
118+ public var enableLocalEvaluation : Boolean = false ,
119+ /* *
120+ * Personal API key for local evaluation
121+ * Required when enableLocalEvaluation is true.
122+ * Get your personal API key from PostHog -> Settings -> User -> Personal API Keys
123+ * Defaults to null
124+ */
125+ public var personalApiKey : String? = null ,
126+ /* *
127+ * Interval in seconds for polling feature flag definitions for local evaluation
128+ * Defaults to 30 seconds
129+ */
130+ public var pollIntervalSeconds : Int = DEFAULT_POLL_INTERVAL_SECONDS ,
131+ /* *
132+ * Callback when local evaluation is ready
133+ */
134+ public var onLocalEvaluationReady : NullaryCallback ? = null
135+
109136) {
110137 private val beforeSendCallbacks = mutableListOf<PostHogBeforeSend >()
111138 private val integrations = mutableListOf<PostHogIntegration >()
@@ -145,6 +172,10 @@ public open class PostHogConfig constructor(
145172 api,
146173 cacheMaxAgeMs = featureFlagCacheMaxAgeMs,
147174 cacheMaxSize = featureFlagCacheSize,
175+ enableLocalEvaluation = enableLocalEvaluation,
176+ personalApiKey = personalApiKey,
177+ pollIntervalSeconds = pollIntervalSeconds,
178+ onLocalEvaluationReady = onLocalEvaluationReady,
148179 )
149180 },
150181 queueProvider = { config, api, endpoint, _, executor ->
@@ -181,6 +212,7 @@ public open class PostHogConfig constructor(
181212 public const val DEFAULT_FEATURE_FLAG_CACHE_SIZE : Int = 1000
182213 public const val DEFAULT_FEATURE_FLAG_CACHE_MAX_AGE_MS : Int = 5 * 60 * 1000 // 5 minutes
183214 public const val DEFAULT_FEATURE_FLAG_CALLED_CACHE_SIZE : Int = 1000
215+ public const val DEFAULT_POLL_INTERVAL_SECONDS : Int = 30
184216
185217 @JvmStatic
186218 public fun builder (apiKey : String ): Builder = Builder (apiKey)
@@ -202,39 +234,64 @@ public open class PostHogConfig constructor(
202234 private var featureFlagCacheSize: Int = DEFAULT_FEATURE_FLAG_CACHE_SIZE
203235 private var featureFlagCacheMaxAgeMs: Int = DEFAULT_FEATURE_FLAG_CACHE_MAX_AGE_MS
204236 private var featureFlagCalledCacheSize: Int = DEFAULT_FEATURE_FLAG_CALLED_CACHE_SIZE
237+ private var enableLocalEvaluation: Boolean = false
238+ private var personalApiKey: String? = null
239+ private var pollIntervalSeconds: Int = DEFAULT_POLL_INTERVAL_SECONDS
240+ private var onLocalEvaluationReady: NullaryCallback ? = null
205241
206242 public fun host (host : String ): Builder = apply { this .host = host }
207243
208244 public fun debug (debug : Boolean ): Builder = apply { this .debug = debug }
209245
210- public fun sendFeatureFlagEvent (sendFeatureFlagEvent : Boolean ): Builder = apply { this .sendFeatureFlagEvent = sendFeatureFlagEvent }
246+ public fun sendFeatureFlagEvent (sendFeatureFlagEvent : Boolean ): Builder =
247+ apply { this .sendFeatureFlagEvent = sendFeatureFlagEvent }
211248
212- public fun preloadFeatureFlags (preloadFeatureFlags : Boolean ): Builder = apply { this .preloadFeatureFlags = preloadFeatureFlags }
249+ public fun preloadFeatureFlags (preloadFeatureFlags : Boolean ): Builder =
250+ apply { this .preloadFeatureFlags = preloadFeatureFlags }
213251
214- public fun remoteConfig (remoteConfig : Boolean ): Builder = apply { this .remoteConfig = remoteConfig }
252+ public fun remoteConfig (remoteConfig : Boolean ): Builder =
253+ apply { this .remoteConfig = remoteConfig }
215254
216255 public fun flushAt (flushAt : Int ): Builder = apply { this .flushAt = flushAt }
217256
218- public fun maxQueueSize (maxQueueSize : Int ): Builder = apply { this .maxQueueSize = maxQueueSize }
257+ public fun maxQueueSize (maxQueueSize : Int ): Builder =
258+ apply { this .maxQueueSize = maxQueueSize }
219259
220- public fun maxBatchSize (maxBatchSize : Int ): Builder = apply { this .maxBatchSize = maxBatchSize }
260+ public fun maxBatchSize (maxBatchSize : Int ): Builder =
261+ apply { this .maxBatchSize = maxBatchSize }
221262
222- public fun flushIntervalSeconds (flushIntervalSeconds : Int ): Builder = apply { this .flushIntervalSeconds = flushIntervalSeconds }
263+ public fun flushIntervalSeconds (flushIntervalSeconds : Int ): Builder =
264+ apply { this .flushIntervalSeconds = flushIntervalSeconds }
223265
224- public fun encryption (encryption : PostHogEncryption ? ): Builder = apply { this .encryption = encryption }
266+ public fun encryption (encryption : PostHogEncryption ? ): Builder =
267+ apply { this .encryption = encryption }
225268
226- public fun onFeatureFlags (onFeatureFlags : PostHogOnFeatureFlags ? ): Builder = apply { this .onFeatureFlags = onFeatureFlags }
269+ public fun onFeatureFlags (onFeatureFlags : PostHogOnFeatureFlags ? ): Builder =
270+ apply { this .onFeatureFlags = onFeatureFlags }
227271
228272 public fun proxy (proxy : Proxy ? ): Builder = apply { this .proxy = proxy }
229273
230- public fun featureFlagCacheSize (featureFlagCacheSize : Int ): Builder = apply { this .featureFlagCacheSize = featureFlagCacheSize }
274+ public fun featureFlagCacheSize (featureFlagCacheSize : Int ): Builder =
275+ apply { this .featureFlagCacheSize = featureFlagCacheSize }
231276
232277 public fun featureFlagCacheMaxAgeMs (featureFlagCacheMaxAgeMs : Int ): Builder =
233278 apply { this .featureFlagCacheMaxAgeMs = featureFlagCacheMaxAgeMs }
234279
235280 public fun featureFlagCalledCacheSize (featureFlagCalledCacheSize : Int ): Builder =
236281 apply { this .featureFlagCalledCacheSize = featureFlagCalledCacheSize }
237282
283+ public fun localEvaluation (enableLocalEvaluation : Boolean ): Builder =
284+ apply { this .enableLocalEvaluation = enableLocalEvaluation }
285+
286+ public fun personalApiKey (personalApiKey : String? ): Builder =
287+ apply { this .personalApiKey = personalApiKey }
288+
289+ public fun pollIntervalSeconds (pollIntervalSeconds : Int ): Builder =
290+ apply { this .pollIntervalSeconds = pollIntervalSeconds }
291+
292+ public fun onLocalEvaluationReady (onLocalEvaluationReady : NullaryCallback ? ): Builder =
293+ apply { this .onLocalEvaluationReady = onLocalEvaluationReady }
294+
238295 public fun build (): PostHogConfig =
239296 PostHogConfig (
240297 apiKey = apiKey,
@@ -253,6 +310,10 @@ public open class PostHogConfig constructor(
253310 featureFlagCacheSize = featureFlagCacheSize,
254311 featureFlagCacheMaxAgeMs = featureFlagCacheMaxAgeMs,
255312 featureFlagCalledCacheSize = featureFlagCalledCacheSize,
313+ enableLocalEvaluation = enableLocalEvaluation,
314+ personalApiKey = personalApiKey,
315+ pollIntervalSeconds = pollIntervalSeconds,
316+ onLocalEvaluationReady = onLocalEvaluationReady,
256317 )
257318 }
258319}
0 commit comments