diff --git a/packages/client/README.md b/packages/client/README.md index 4e9c9aad8..c1a98ec2a 100644 --- a/packages/client/README.md +++ b/packages/client/README.md @@ -13,8 +13,8 @@
-
-
+
+
diff --git a/packages/client/src/client/open-feature-client.ts b/packages/client/src/client/open-feature-client.ts
index 20442e7de..fb22f5780 100644
--- a/packages/client/src/client/open-feature-client.ts
+++ b/packages/client/src/client/open-feature-client.ts
@@ -1,5 +1,3 @@
-import { Client } from './client';
-import { Provider } from '../provider';
import {
ClientMetadata,
ErrorCode,
@@ -20,8 +18,10 @@ import {
SafeLogger,
StandardResolutionReasons,
} from '@openfeature/shared';
-import { OpenFeature } from '../open-feature';
import { FlagEvaluationOptions } from '../evaluation';
+import { OpenFeature } from '../open-feature';
+import { Provider } from '../provider';
+import { Client } from './client';
type OpenFeatureClientOptions = {
name?: string;
@@ -56,7 +56,7 @@ export class OpenFeatureClient implements Client {
if (eventType === ProviderEvents.Ready && providerReady) {
// run immediately, we're ready.
try {
- handler({ clientName: this.metadata.name });
+ handler({ clientName: this.metadata.name, providerName: this._provider.metadata.name });
} catch (err) {
this._logger?.error('Error running event handler:', err);
}
diff --git a/packages/client/test/client.spec.ts b/packages/client/test/client.spec.ts
index ac8e3c96c..fb9d1fc1e 100644
--- a/packages/client/test/client.spec.ts
+++ b/packages/client/test/client.spec.ts
@@ -1,16 +1,16 @@
import {
Client,
- Provider,
ErrorCode,
EvaluationDetails,
- JsonValue,
+ FlagNotFoundError,
JsonArray,
JsonObject,
+ JsonValue,
+ OpenFeature,
+ OpenFeatureClient,
+ Provider,
ResolutionDetails,
StandardResolutionReasons,
- FlagNotFoundError,
- OpenFeatureClient,
- OpenFeature,
} from '../src';
const BOOLEAN_VALUE = true;
@@ -46,7 +46,6 @@ const MOCK_PROVIDER: Provider = {
metadata: {
name: 'mock',
},
-
events: undefined,
hooks: [],
initialize(): Promise
-
-
+
+
diff --git a/packages/server/src/client/open-feature-client.ts b/packages/server/src/client/open-feature-client.ts
index e6331a121..9e2d4ef24 100644
--- a/packages/server/src/client/open-feature-client.ts
+++ b/packages/server/src/client/open-feature-client.ts
@@ -6,23 +6,23 @@ import {
EventHandler,
FlagValue,
FlagValueType,
+ Hook,
HookContext,
+ InternalEventEmitter,
JsonValue,
Logger,
+ ManageContext,
OpenFeatureError,
- InternalEventEmitter,
ProviderEvents,
- ProviderStatus,
ResolutionDetails,
- StandardResolutionReasons,
SafeLogger,
- Hook,
- ManageContext,
+ StandardResolutionReasons,
+ statusMatchesEvent
} from '@openfeature/shared';
+import { FlagEvaluationOptions } from '../evaluation';
import { OpenFeature } from '../open-feature';
-import { Client } from './client';
import { Provider } from '../provider';
-import { FlagEvaluationOptions } from '../evaluation';
+import { Client } from './client';
type OpenFeatureClientOptions = {
name?: string;
@@ -56,12 +56,12 @@ export class OpenFeatureClient implements Client, ManageContext (eventType: T, handler: EventHandler {
// fetch the most recent event emitters, some may have been added during init
this.getAssociatedEventEmitters(clientName).forEach((emitter) => {
- emitter?.emit(ProviderEvents.Ready, { clientName });
+ emitter?.emit(ProviderEvents.Ready, { clientName, providerName });
});
- this._events?.emit(ProviderEvents.Ready, { clientName });
+ this._events?.emit(ProviderEvents.Ready, { clientName, providerName });
})
?.catch((error) => {
this.getAssociatedEventEmitters(clientName).forEach((emitter) => {
- emitter?.emit(ProviderEvents.Error, { clientName, message: error.message });
+ emitter?.emit(ProviderEvents.Error, { clientName, providerName, message: error.message });
});
- this._events?.emit(ProviderEvents.Error, { clientName, message: error.message });
+ this._events?.emit(ProviderEvents.Error, { clientName, providerName, message: error.message });
});
} else {
emitters.forEach((emitter) => {
- emitter?.emit(ProviderEvents.Ready, { clientName });
+ emitter?.emit(ProviderEvents.Ready, { clientName, providerName });
});
- this._events?.emit(ProviderEvents.Ready, { clientName });
+ this._events?.emit(ProviderEvents.Ready, { clientName, providerName });
}
if (clientName) {
@@ -208,7 +224,7 @@ export abstract class OpenFeatureCommonAPI (ProviderEvents).forEach((eventType) =>
clientProvider.events?.addHandler(eventType, async (details) => {
- newEmitter.emit(eventType, { ...details, clientName: name });
+ newEmitter.emit(eventType, { ...details, clientName: name, providerName: clientProvider.metadata.name });
})
);
@@ -248,9 +264,9 @@ export abstract class OpenFeatureCommonAPI ) => {
// on each event type, fire the associated handlers
emitters.forEach((emitter) => {
- emitter?.emit(eventType, { ...details, clientName });
+ emitter?.emit(eventType, { ...details, clientName, providerName: newProvider.metadata.name });
});
- this._events.emit(eventType, { ...details, clientName });
+ this._events.emit(eventType, { ...details, clientName, providerName: newProvider.metadata.name });
};
return [eventType, handler];
diff --git a/packages/shared/src/provider/provider.ts b/packages/shared/src/provider/provider.ts
index df42ec33e..e67b78c3d 100644
--- a/packages/shared/src/provider/provider.ts
+++ b/packages/shared/src/provider/provider.ts
@@ -1,7 +1,6 @@
-import { OpenFeatureEventEmitter } from '../events';
-import { Metadata } from '../types';
import { EvaluationContext } from '../evaluation';
-import { Paradigm } from '../types';
+import { OpenFeatureEventEmitter } from '../events';
+import { Metadata, Paradigm } from '../types';
/**
* The state of the provider.
@@ -21,6 +20,11 @@ export enum ProviderStatus {
* The provider is in an error state and unable to evaluate flags.
*/
ERROR = 'ERROR',
+
+ /**
+ * The provider's cached state is no longer valid and may not be up-to-date with the source of truth.
+ */
+ STALE = 'STALE',
}
/**