Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
dd51e2c
test: make waitAssert fail on timeout
mtonko-flx Sep 2, 2026
272e392
feat(events)!: add reconciling and context-changed provider events
mtonko-flx Sep 2, 2026
4821cb0
feat: add ProviderStatusTracker
mtonko-flx Sep 2, 2026
c340708
fix(logging): bridge NSLog's argument through NSString
mtonko-flx Sep 2, 2026
e12d9fa
feat!: make providers own their status
mtonko-flx Sep 2, 2026
1fb943d
refactor(multiprovider)!: aggregate status through a tracker
mtonko-flx Sep 2, 2026
36cfc2e
docs: document provider-owned status
mtonko-flx Sep 2, 2026
b821ac5
fix: order the tracker's reconciliation bookkeeping under one lock
mtonko-flx Sep 2, 2026
9a933c7
fix(api)!: commit, publish and retire a provider registration together
mtonko-flx Sep 2, 2026
b5d1746
fix(multiprovider)!: reconcile through the tracker instead of hand-ro…
mtonko-flx Sep 2, 2026
39bff1a
test: pin the provider lifecycle and tracker race contracts
mtonko-flx Sep 2, 2026
c219146
docs: record the reconciliation and not-ready aggregation behaviour
mtonko-flx Sep 2, 2026
6863b60
fix: never conclude readiness from reconciling a not-ready provider
mtonko-flx Sep 2, 2026
43273ce
test: drop the unsound stateless-event race assertion
mtonko-flx Sep 2, 2026
e7cf24d
fix(api)!: keep a re-registered provider's registration and retire of…
mtonko-flx Sep 2, 2026
02f00ca
fix(multiprovider): collect a child's cancellation instead of abandon…
mtonko-flx Sep 3, 2026
64c2735
refactor: trim comments to the density the rest of the repository keeps
mtonko-flx Sep 3, 2026
9036e87
test: signal the tracker handover instead of polling a list the colle…
mtonko-flx Sep 3, 2026
fb63dfa
fix(multiprovider): resolve a reconciliation a child started on its o…
mtonko-flx Sep 3, 2026
213b08a
fix(api): leave a re-registered provider alone when its retirement ru…
mtonko-flx Sep 3, 2026
e7a0e51
style: opt in to the experimental coroutines API the reconciling test…
mtonko-flx Sep 3, 2026
d241ca1
docs: record that reporting unreadiness is the provider's job
mtonko-flx Sep 3, 2026
f54dfd6
Merge remote-tracking branch 'origin/main' into feat/first-party-prov…
mtonko-flx Sep 3, 2026
f50b144
fix(multiprovider): log a child provider's swallowed lifecycle failure
mtonko-flx Sep 3, 2026
dd594f2
fix(api): dispatch a new provider's initialize before a racing setEva…
mtonko-flx Sep 3, 2026
5b6037c
fix(test): make AutoHealingProvider's ready flag visible across threads
mtonko-flx Sep 3, 2026
f268828
test: release the blocking shutdown latch in a finally block
mtonko-flx Sep 3, 2026
81c9bba
docs: drop an unresolvable KDoc link that fails the dokka build
mtonko-flx Sep 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 39 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ coroutineScope.launch(Dispatchers.Default) {

Asynchronous API that doesn't wait is also available. It's useful when you want to set a provider and continue with other tasks.

However, flag evaluations are only possible after the provider is Ready.
However, flag evaluations are only meaningful after the provider is Ready. The SDK does not gate them on the status: an evaluation made earlier reaches the provider, which reports its own unreadiness with a `PROVIDER_NOT_READY` or `PROVIDER_FATAL` error code, and the client returns the default value.

```kotlin
OpenFeatureAPI.setProvider(MyProvider()) // can pass a dispatcher here
Expand Down Expand Up @@ -356,9 +356,9 @@ Support for domains is currently in development.
### Eventing

Events from the Provider allow the SDK to react to state changes in the provider or underlying flag management system, such as flag definition changes, provider readiness, or error conditions.
Events are optional which mean that not all Providers will emit them and it is not a must have. Some providers support additional events, such as `PROVIDER_CONFIGURATION_CHANGED`.
A provider reports every status transition as an event — that is how the SDK knows a provider is ready, stale or in error — and some providers report additional events, such as `PROVIDER_CONFIGURATION_CHANGED`.

Please refer to the documentation of the provider you're using to see what events are supported.
Please refer to the documentation of the provider you're using to see what additional events are supported.

Example usage:
```kotlin
Expand Down Expand Up @@ -415,8 +415,31 @@ in an Android app.
To develop a provider, you need to create a new project and include the OpenFeature SDK as a dependency.
You’ll then need to write the provider by implementing the `FeatureProvider` interface exported by the OpenFeature SDK.

#### Status ownership

A provider is responsible for its own `status`. The SDK reads it but never sets it, so you must keep it
consistent with the events you emit, and it must be thread-safe because the SDK reads it from flag
evaluation paths on any thread.

The easiest way to satisfy both requirements is to delegate to `ProviderStatusTracker`, which derives
`status` from the events you send it and replays the current status to new subscribers. Emit at least
one non-not-ready event before `initialize` returns, otherwise the provider stays `NotReady`:
throwing does not set a status.

Refusing an evaluation made before the provider is ready is the provider's job too, per requirement
2.2.7: return or throw with error code `PROVIDER_NOT_READY`, or `PROVIDER_FATAL` where the failure is
irrecoverable, and the client returns the default value.

#### Example implementation

```kotlin
class NewProvider(override val hooks: List<Hook<*>>, override val metadata: ProviderMetadata) : FeatureProvider {
private val statusTracker = ProviderStatusTracker()

override val status: OpenFeatureStatus get() = statusTracker.status

override fun observe(): Flow<OpenFeatureProviderEvents> = statusTracker.observe()

override fun getBooleanEvaluation(
key: String,
defaultValue: Boolean,
Expand Down Expand Up @@ -466,11 +489,21 @@ class NewProvider(override val hooks: List<Hook<*>>, override val metadata: Prov
}

override suspend fun initialize(initialContext: EvaluationContext?) {
// add context-aware provider initialization
// add context-aware provider initialization, then report the outcome
statusTracker.send(OpenFeatureProviderEvents.ProviderReady())
}

override suspend fun onContextSet(oldContext: EvaluationContext?, newContext: EvaluationContext) {
// add necessary changes on context change
override suspend fun onContextSet(
oldContext: EvaluationContext?,
newContext: EvaluationContext
) = statusTracker.reconciling {
// add necessary changes on context change; reconciling reports the transitions around this,
// and collapses overlapping invocations into a single reported outcome
}

override fun shutdown() {
// release resources, and return to NotReady in case this provider is registered again
statusTracker.reset()
}

override fun track(
Expand All @@ -481,9 +514,6 @@ class NewProvider(override val hooks: List<Hook<*>>, override val metadata: Prov
// Optionally track an event
}

override fun observe(): Flow<OpenFeatureProviderEvents> {
// Optionally return a `Flow` of OpenFeatureProviderEvents
}
}
```

Expand Down
8 changes: 5 additions & 3 deletions docs/multiprovider/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,21 @@ Children are evaluated in the order provided. Put the most authoritative or fast

### Events and status aggregation

`MultiProvider` listens to child provider events and emits a single, aggregate status via `OpenFeatureAPI.statusFlow`. Per the OpenFeature specification: a child stays `NOT_READY` until it emits `PROVIDER_READY`, `PROVIDER_ERROR`, or `PROVIDER_STALE` (or only `PROVIDER_CONFIGURATION_CHANGED`, which does not change readiness). The highest-precedence status among children wins:
`MultiProvider` owns a `ProviderStatusTracker` like any other provider, and reports a single aggregate status through it. A child stays `NOT_READY` until it reports `PROVIDER_READY`, `PROVIDER_ERROR` or `PROVIDER_STALE`; `PROVIDER_CONFIGURATION_CHANGED` carries no status and does not change readiness.

Aggregation is `Strategy.status(providers)`, which you can override. The default reports the most severe child status, which is the order the specification's [Multi-Provider appendix](https://openfeature.dev/specification/appendix-a/#status-and-event-handling) defines:

1. Fatal
2. NotReady
3. Error
4. Reconciling / Stale
5. Ready

`ProviderConfigurationChanged` is re-emitted as-is. When the aggregate status changes due to a child event, the original triggering event is also emitted.
An aggregate transition carries the `EventDetails` of the child event that triggered it.

### Context propagation

When the evaluation context changes, `MultiProvider` calls `onContextSet` on all child providers concurrently. Aggregate status transitions to Reconciling and then back to Ready (or Error) in line with SDK behavior.
When the evaluation context changes, `MultiProvider` reconciles through its `ProviderStatusTracker`: `PROVIDER_RECONCILING` is reported once even across overlapping context sets, `onContextSet` is called on all child providers concurrently, and only the last invocation to terminate reports an outcome.

### Provider metadata

Expand Down
59 changes: 53 additions & 6 deletions kotlin-sdk/api/android/kotlin-sdk.api
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,16 @@ public abstract interface class dev/openfeature/kotlin/sdk/FeatureProvider {
public abstract fun getLongEvaluation (Ljava/lang/String;JLdev/openfeature/kotlin/sdk/EvaluationContext;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public abstract fun getMetadata ()Ldev/openfeature/kotlin/sdk/ProviderMetadata;
public abstract fun getObjectEvaluation (Ljava/lang/String;Ldev/openfeature/kotlin/sdk/Value;Ldev/openfeature/kotlin/sdk/EvaluationContext;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public abstract fun getStatus ()Ldev/openfeature/kotlin/sdk/OpenFeatureStatus;
public abstract fun getStringEvaluation (Ljava/lang/String;Ljava/lang/String;Ldev/openfeature/kotlin/sdk/EvaluationContext;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public abstract fun initialize (Ldev/openfeature/kotlin/sdk/EvaluationContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun observe ()Lkotlinx/coroutines/flow/Flow;
public abstract fun observe ()Lkotlinx/coroutines/flow/Flow;
public abstract fun onContextSet (Ldev/openfeature/kotlin/sdk/EvaluationContext;Ldev/openfeature/kotlin/sdk/EvaluationContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public abstract fun shutdown ()V
public fun track (Ljava/lang/String;Ldev/openfeature/kotlin/sdk/EvaluationContext;Ldev/openfeature/kotlin/sdk/TrackingEventDetails;)V
}

public final class dev/openfeature/kotlin/sdk/FeatureProvider$DefaultImpls {
public static fun observe (Ldev/openfeature/kotlin/sdk/FeatureProvider;)Lkotlinx/coroutines/flow/Flow;
public static fun track (Ldev/openfeature/kotlin/sdk/FeatureProvider;Ljava/lang/String;Ldev/openfeature/kotlin/sdk/EvaluationContext;Ldev/openfeature/kotlin/sdk/TrackingEventDetails;)V
}

Expand Down Expand Up @@ -252,6 +252,7 @@ public class dev/openfeature/kotlin/sdk/NoOpProvider : dev/openfeature/kotlin/sd
public fun getLongEvaluation (Ljava/lang/String;JLdev/openfeature/kotlin/sdk/EvaluationContext;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public fun getMetadata ()Ldev/openfeature/kotlin/sdk/ProviderMetadata;
public fun getObjectEvaluation (Ljava/lang/String;Ldev/openfeature/kotlin/sdk/Value;Ldev/openfeature/kotlin/sdk/EvaluationContext;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public fun getStatus ()Ldev/openfeature/kotlin/sdk/OpenFeatureStatus;
public fun getStringEvaluation (Ljava/lang/String;Ljava/lang/String;Ldev/openfeature/kotlin/sdk/EvaluationContext;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public fun initialize (Ldev/openfeature/kotlin/sdk/EvaluationContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun observe ()Lkotlinx/coroutines/flow/Flow;
Expand Down Expand Up @@ -287,11 +288,10 @@ public class dev/openfeature/kotlin/sdk/OpenFeatureAPIInstance {
public final fun getHooks ()Ljava/util/List;
public final fun getProvider ()Ldev/openfeature/kotlin/sdk/FeatureProvider;
public final fun getProviderMetadata ()Ldev/openfeature/kotlin/sdk/ProviderMetadata;
public final fun getProvidersFlow ()Lkotlinx/coroutines/flow/MutableStateFlow;
public final fun getStatus ()Ldev/openfeature/kotlin/sdk/OpenFeatureStatus;
public final fun getStatusFlow ()Lkotlinx/coroutines/flow/Flow;
public final fun setEvaluationContext (Ldev/openfeature/kotlin/sdk/EvaluationContext;Lkotlinx/coroutines/CoroutineDispatcher;)V
public static synthetic fun setEvaluationContext$default (Ldev/openfeature/kotlin/sdk/OpenFeatureAPIInstance;Ldev/openfeature/kotlin/sdk/EvaluationContext;Lkotlinx/coroutines/CoroutineDispatcher;ILjava/lang/Object;)V
public final fun observe ()Lkotlinx/coroutines/flow/Flow;
public final fun setEvaluationContext (Ldev/openfeature/kotlin/sdk/EvaluationContext;)V
public final fun setEvaluationContextAndWait (Ldev/openfeature/kotlin/sdk/EvaluationContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun setProvider (Ldev/openfeature/kotlin/sdk/FeatureProvider;Lkotlinx/coroutines/CoroutineDispatcher;Ldev/openfeature/kotlin/sdk/EvaluationContext;)V
public static synthetic fun setProvider$default (Ldev/openfeature/kotlin/sdk/OpenFeatureAPIInstance;Ldev/openfeature/kotlin/sdk/FeatureProvider;Lkotlinx/coroutines/CoroutineDispatcher;Ldev/openfeature/kotlin/sdk/EvaluationContext;ILjava/lang/Object;)V
Expand Down Expand Up @@ -354,12 +354,16 @@ public abstract interface class dev/openfeature/kotlin/sdk/OpenFeatureStatus {

public final class dev/openfeature/kotlin/sdk/OpenFeatureStatus$Error : dev/openfeature/kotlin/sdk/OpenFeatureStatus {
public fun <init> (Ldev/openfeature/kotlin/sdk/exceptions/OpenFeatureError;)V
public fun equals (Ljava/lang/Object;)Z
public final fun getError ()Ldev/openfeature/kotlin/sdk/exceptions/OpenFeatureError;
public fun hashCode ()I
}

public final class dev/openfeature/kotlin/sdk/OpenFeatureStatus$Fatal : dev/openfeature/kotlin/sdk/OpenFeatureStatus {
public fun <init> (Ldev/openfeature/kotlin/sdk/exceptions/OpenFeatureError;)V
public fun equals (Ljava/lang/Object;)Z
public final fun getError ()Ldev/openfeature/kotlin/sdk/exceptions/OpenFeatureError;
public fun hashCode ()I
}

public final class dev/openfeature/kotlin/sdk/OpenFeatureStatus$NotReady : dev/openfeature/kotlin/sdk/OpenFeatureStatus {
Expand Down Expand Up @@ -409,6 +413,15 @@ public final class dev/openfeature/kotlin/sdk/ProviderMetadata$DefaultImpls {
public static fun getOriginalMetadata (Ldev/openfeature/kotlin/sdk/ProviderMetadata;)Ljava/util/Map;
}

public final class dev/openfeature/kotlin/sdk/ProviderStatusTracker {
public fun <init> ()V
public final fun getStatus ()Ldev/openfeature/kotlin/sdk/OpenFeatureStatus;
public final fun observe ()Lkotlinx/coroutines/flow/Flow;
public final fun reconciling (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun reset ()V
public final fun send (Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents;)V
}

public final class dev/openfeature/kotlin/sdk/Reason : java/lang/Enum {
public static final field CACHED Ldev/openfeature/kotlin/sdk/Reason;
public static final field DEFAULT Ldev/openfeature/kotlin/sdk/Reason;
Expand Down Expand Up @@ -724,6 +737,19 @@ public final class dev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$P
public fun toString ()Ljava/lang/String;
}

public final class dev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$ProviderContextChanged : dev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents {
public fun <init> ()V
public fun <init> (Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;)V
public synthetic fun <init> (Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;
public final fun copy (Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;)Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$ProviderContextChanged;
public static synthetic fun copy$default (Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$ProviderContextChanged;Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;ILjava/lang/Object;)Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$ProviderContextChanged;
public fun equals (Ljava/lang/Object;)Z
public fun getEventDetails ()Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class dev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$ProviderError : dev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents {
public fun <init> ()V
public fun <init> (Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;)V
Expand All @@ -750,6 +776,19 @@ public final class dev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$P
public fun toString ()Ljava/lang/String;
}

public final class dev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$ProviderReconciling : dev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents {
public fun <init> ()V
public fun <init> (Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;)V
public synthetic fun <init> (Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;
public final fun copy (Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;)Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$ProviderReconciling;
public static synthetic fun copy$default (Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$ProviderReconciling;Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;ILjava/lang/Object;)Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$ProviderReconciling;
public fun equals (Ljava/lang/Object;)Z
public fun getEventDetails ()Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class dev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$ProviderStale : dev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents {
public fun <init> ()V
public fun <init> (Ldev/openfeature/kotlin/sdk/events/OpenFeatureProviderEvents$EventDetails;)V
Expand Down Expand Up @@ -913,11 +952,13 @@ public final class dev/openfeature/kotlin/sdk/logging/NoOpLogger : dev/openfeatu
public final class dev/openfeature/kotlin/sdk/multiprovider/FirstMatchStrategy : dev/openfeature/kotlin/sdk/multiprovider/MultiProvider$Strategy {
public fun <init> ()V
public fun evaluate (Ljava/util/List;Ljava/lang/String;Ljava/lang/Object;Ldev/openfeature/kotlin/sdk/EvaluationContext;Lkotlin/jvm/functions/Function4;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public fun status (Ljava/util/List;)Ldev/openfeature/kotlin/sdk/OpenFeatureStatus;
}

public final class dev/openfeature/kotlin/sdk/multiprovider/FirstSuccessfulStrategy : dev/openfeature/kotlin/sdk/multiprovider/MultiProvider$Strategy {
public fun <init> ()V
public fun evaluate (Ljava/util/List;Ljava/lang/String;Ljava/lang/Object;Ldev/openfeature/kotlin/sdk/EvaluationContext;Lkotlin/jvm/functions/Function4;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public fun status (Ljava/util/List;)Ldev/openfeature/kotlin/sdk/OpenFeatureStatus;
}

public final class dev/openfeature/kotlin/sdk/multiprovider/MultiProvider : dev/openfeature/kotlin/sdk/FeatureProvider {
Expand All @@ -931,7 +972,7 @@ public final class dev/openfeature/kotlin/sdk/multiprovider/MultiProvider : dev/
public fun getLongEvaluation (Ljava/lang/String;JLdev/openfeature/kotlin/sdk/EvaluationContext;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public fun getMetadata ()Ldev/openfeature/kotlin/sdk/ProviderMetadata;
public fun getObjectEvaluation (Ljava/lang/String;Ldev/openfeature/kotlin/sdk/Value;Ldev/openfeature/kotlin/sdk/EvaluationContext;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public final fun getStatusFlow ()Lkotlinx/coroutines/flow/StateFlow;
public fun getStatus ()Ldev/openfeature/kotlin/sdk/OpenFeatureStatus;
public fun getStringEvaluation (Ljava/lang/String;Ljava/lang/String;Ldev/openfeature/kotlin/sdk/EvaluationContext;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public fun initialize (Ldev/openfeature/kotlin/sdk/EvaluationContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun observe ()Lkotlinx/coroutines/flow/Flow;
Expand All @@ -950,6 +991,7 @@ public final class dev/openfeature/kotlin/sdk/multiprovider/MultiProvider$ChildF
public fun getMetadata ()Ldev/openfeature/kotlin/sdk/ProviderMetadata;
public final fun getName ()Ljava/lang/String;
public fun getObjectEvaluation (Ljava/lang/String;Ldev/openfeature/kotlin/sdk/Value;Ldev/openfeature/kotlin/sdk/EvaluationContext;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public fun getStatus ()Ldev/openfeature/kotlin/sdk/OpenFeatureStatus;
public fun getStringEvaluation (Ljava/lang/String;Ljava/lang/String;Ldev/openfeature/kotlin/sdk/EvaluationContext;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public fun initialize (Ldev/openfeature/kotlin/sdk/EvaluationContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun observe ()Lkotlinx/coroutines/flow/Flow;
Expand All @@ -963,5 +1005,10 @@ public final class dev/openfeature/kotlin/sdk/multiprovider/MultiProvider$Compan

public abstract interface class dev/openfeature/kotlin/sdk/multiprovider/MultiProvider$Strategy {
public abstract fun evaluate (Ljava/util/List;Ljava/lang/String;Ljava/lang/Object;Ldev/openfeature/kotlin/sdk/EvaluationContext;Lkotlin/jvm/functions/Function4;)Ldev/openfeature/kotlin/sdk/ProviderEvaluation;
public fun status (Ljava/util/List;)Ldev/openfeature/kotlin/sdk/OpenFeatureStatus;
}

public final class dev/openfeature/kotlin/sdk/multiprovider/MultiProvider$Strategy$DefaultImpls {
public static fun status (Ldev/openfeature/kotlin/sdk/multiprovider/MultiProvider$Strategy;Ljava/util/List;)Ldev/openfeature/kotlin/sdk/OpenFeatureStatus;
}

Loading
Loading